Skip to content

Commit

Permalink
igc: Add NVM support
Browse files Browse the repository at this point in the history
Add code for NVM support and get MAC address, complete probe
method.

Signed-off-by: Sasha Neftin <[email protected]>
Signed-off-by: Alexander Duyck <[email protected]>
Tested-by: Aaron Brown <[email protected]>
Signed-off-by: Jeff Kirsher <[email protected]>
  • Loading branch information
aneftin authored and Jeff Kirsher committed Oct 17, 2018
1 parent c0071c7 commit ab40561
Show file tree
Hide file tree
Showing 13 changed files with 949 additions and 3 deletions.
2 changes: 1 addition & 1 deletion drivers/net/ethernet/intel/igc/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -7,4 +7,4 @@

obj-$(CONFIG_IGC) += igc.o

igc-objs := igc_main.o igc_mac.o igc_i225.o igc_base.o
igc-objs := igc_main.o igc_mac.o igc_i225.o igc_base.o igc_nvm.o
6 changes: 6 additions & 0 deletions drivers/net/ethernet/intel/igc/igc.h
Original file line number Diff line number Diff line change
Expand Up @@ -131,6 +131,10 @@ enum igc_tx_flags {
IGC_TX_FLAGS_CSUM = 0x20,
};

enum igc_boards {
board_base,
};

/* The largest size we can write to the descriptor is 65535. In order to
* maintain a power of two alignment we have to limit ourselves to 32K.
*/
Expand Down Expand Up @@ -342,6 +346,8 @@ struct igc_adapter {
spinlock_t nfc_lock;

struct igc_mac_addr *mac_table;

struct igc_info ei;
};

/* igc_desc_unused - calculate if we have unused descriptors */
Expand Down
109 changes: 109 additions & 0 deletions drivers/net/ethernet/intel/igc/igc_base.c
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,22 @@ static s32 igc_set_pcie_completion_timeout(struct igc_hw *hw)
return ret_val;
}

/**
* igc_check_for_link_base - Check for link
* @hw: pointer to the HW structure
*
* If sgmii is enabled, then use the pcs register to determine link, otherwise
* use the generic interface for determining link.
*/
static s32 igc_check_for_link_base(struct igc_hw *hw)
{
s32 ret_val = 0;

ret_val = igc_check_for_copper_link(hw);

return ret_val;
}

/**
* igc_reset_hw_base - Reset hardware
* @hw: pointer to the HW structure
Expand Down Expand Up @@ -107,12 +123,51 @@ static s32 igc_reset_hw_base(struct igc_hw *hw)
return ret_val;
}

/**
* igc_init_nvm_params_base - Init NVM func ptrs.
* @hw: pointer to the HW structure
*/
static s32 igc_init_nvm_params_base(struct igc_hw *hw)
{
struct igc_nvm_info *nvm = &hw->nvm;
u32 eecd = rd32(IGC_EECD);
u16 size;

size = (u16)((eecd & IGC_EECD_SIZE_EX_MASK) >>
IGC_EECD_SIZE_EX_SHIFT);

/* Added to a constant, "size" becomes the left-shift value
* for setting word_size.
*/
size += NVM_WORD_SIZE_BASE_SHIFT;

/* Just in case size is out of range, cap it to the largest
* EEPROM size supported
*/
if (size > 15)
size = 15;

nvm->word_size = BIT(size);
nvm->opcode_bits = 8;
nvm->delay_usec = 1;

nvm->page_size = eecd & IGC_EECD_ADDR_BITS ? 32 : 8;
nvm->address_bits = eecd & IGC_EECD_ADDR_BITS ?
16 : 8;

if (nvm->word_size == BIT(15))
nvm->page_size = 128;

return 0;
}

/**
* igc_init_mac_params_base - Init MAC func ptrs.
* @hw: pointer to the HW structure
*/
static s32 igc_init_mac_params_base(struct igc_hw *hw)
{
struct igc_dev_spec_base *dev_spec = &hw->dev_spec._base;
struct igc_mac_info *mac = &hw->mac;

/* Set mta register count */
Expand All @@ -125,6 +180,10 @@ static s32 igc_init_mac_params_base(struct igc_hw *hw)
mac->ops.acquire_swfw_sync = igc_acquire_swfw_sync_i225;
mac->ops.release_swfw_sync = igc_release_swfw_sync_i225;

/* Allow a single clear of the SW semaphore on I225 */
if (mac->type == igc_i225)
dev_spec->clear_semaphore_once = true;

return 0;
}

Expand All @@ -142,10 +201,43 @@ static s32 igc_get_invariants_base(struct igc_hw *hw)
if (ret_val)
goto out;

/* NVM initialization */
ret_val = igc_init_nvm_params_base(hw);
switch (hw->mac.type) {
case igc_i225:
ret_val = igc_init_nvm_params_i225(hw);
break;
default:
break;
}

if (ret_val)
goto out;

out:
return ret_val;
}

/**
* igc_get_link_up_info_base - Get link speed/duplex info
* @hw: pointer to the HW structure
* @speed: stores the current speed
* @duplex: stores the current duplex
*
* This is a wrapper function, if using the serial gigabit media independent
* interface, use PCS to retrieve the link speed and duplex information.
* Otherwise, use the generic function to get the link speed and duplex info.
*/
static s32 igc_get_link_up_info_base(struct igc_hw *hw, u16 *speed,
u16 *duplex)
{
s32 ret_val;

ret_val = igc_get_speed_and_duplex_copper(hw, speed, duplex);

return ret_val;
}

/**
* igc_init_hw_base - Initialize hardware
* @hw: pointer to the HW structure
Expand Down Expand Up @@ -184,6 +276,19 @@ static s32 igc_init_hw_base(struct igc_hw *hw)
return ret_val;
}

/**
* igc_read_mac_addr_base - Read device MAC address
* @hw: pointer to the HW structure
*/
static s32 igc_read_mac_addr_base(struct igc_hw *hw)
{
s32 ret_val = 0;

ret_val = igc_read_mac_addr(hw);

return ret_val;
}

/**
* igc_rx_fifo_flush_base - Clean rx fifo after Rx enable
* @hw: pointer to the HW structure
Expand Down Expand Up @@ -262,6 +367,10 @@ void igc_rx_fifo_flush_base(struct igc_hw *hw)

static struct igc_mac_operations igc_mac_ops_base = {
.init_hw = igc_init_hw_base,
.check_for_link = igc_check_for_link_base,
.rar_set = igc_rar_set,
.read_mac_addr = igc_read_mac_addr_base,
.get_speed_and_duplex = igc_get_link_up_info_base,
};

const struct igc_info igc_base_info = {
Expand Down
52 changes: 52 additions & 0 deletions drivers/net/ethernet/intel/igc/igc_defines.h
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,8 @@
*/
#define IGC_RAH_AV 0x80000000 /* Receive descriptor valid */
#define IGC_RAH_POOL_1 0x00040000
#define IGC_RAL_MAC_ADDR_LEN 4
#define IGC_RAH_MAC_ADDR_LEN 2

/* Error Codes */
#define IGC_SUCCESS 0
Expand All @@ -57,9 +59,51 @@
#define IGC_SWSM_SMBI 0x00000001 /* Driver Semaphore bit */
#define IGC_SWSM_SWESMBI 0x00000002 /* FW Semaphore bit */

/* SWFW_SYNC Definitions */
#define IGC_SWFW_EEP_SM 0x1
#define IGC_SWFW_PHY0_SM 0x2

/* NVM Control */
/* Number of milliseconds for NVM auto read done after MAC reset. */
#define AUTO_READ_DONE_TIMEOUT 10
#define IGC_EECD_AUTO_RD 0x00000200 /* NVM Auto Read done */
#define IGC_EECD_REQ 0x00000040 /* NVM Access Request */
#define IGC_EECD_GNT 0x00000080 /* NVM Access Grant */
/* NVM Addressing bits based on type 0=small, 1=large */
#define IGC_EECD_ADDR_BITS 0x00000400
#define IGC_NVM_GRANT_ATTEMPTS 1000 /* NVM # attempts to gain grant */
#define IGC_EECD_SIZE_EX_MASK 0x00007800 /* NVM Size */
#define IGC_EECD_SIZE_EX_SHIFT 11
#define IGC_EECD_FLUPD_I225 0x00800000 /* Update FLASH */
#define IGC_EECD_FLUDONE_I225 0x04000000 /* Update FLASH done*/
#define IGC_EECD_FLASH_DETECTED_I225 0x00080000 /* FLASH detected */
#define IGC_FLUDONE_ATTEMPTS 20000
#define IGC_EERD_EEWR_MAX_COUNT 512 /* buffered EEPROM words rw */

/* Offset to data in NVM read/write registers */
#define IGC_NVM_RW_REG_DATA 16
#define IGC_NVM_RW_REG_DONE 2 /* Offset to READ/WRITE done bit */
#define IGC_NVM_RW_REG_START 1 /* Start operation */
#define IGC_NVM_RW_ADDR_SHIFT 2 /* Shift to the address bits */
#define IGC_NVM_POLL_READ 0 /* Flag for polling for read complete */

/* NVM Word Offsets */
#define NVM_CHECKSUM_REG 0x003F

/* For checksumming, the sum of all words in the NVM should equal 0xBABA. */
#define NVM_SUM 0xBABA

#define NVM_PBA_OFFSET_0 8
#define NVM_PBA_OFFSET_1 9
#define NVM_RESERVED_WORD 0xFFFF
#define NVM_PBA_PTR_GUARD 0xFAFA
#define NVM_WORD_SIZE_BASE_SHIFT 6

/* Collision related configuration parameters */
#define IGC_COLLISION_THRESHOLD 15
#define IGC_CT_SHIFT 4
#define IGC_COLLISION_DISTANCE 63
#define IGC_COLD_SHIFT 12

/* Device Status */
#define IGC_STATUS_FD 0x00000001 /* Full duplex.0=half,1=full */
Expand All @@ -70,6 +114,14 @@
#define IGC_STATUS_TXOFF 0x00000010 /* transmission paused */
#define IGC_STATUS_SPEED_100 0x00000040 /* Speed 100Mb/s */
#define IGC_STATUS_SPEED_1000 0x00000080 /* Speed 1000Mb/s */
#define IGC_STATUS_SPEED_2500 0x00400000 /* Speed 2.5Gb/s */

#define SPEED_10 10
#define SPEED_100 100
#define SPEED_1000 1000
#define SPEED_2500 2500
#define HALF_DUPLEX 1
#define FULL_DUPLEX 2

/* Interrupt Cause Read */
#define IGC_ICR_TXDW BIT(0) /* Transmit desc written back */
Expand Down
3 changes: 3 additions & 0 deletions drivers/net/ethernet/intel/igc/igc_hw.h
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
#include "igc_regs.h"
#include "igc_defines.h"
#include "igc_mac.h"
#include "igc_nvm.h"
#include "igc_i225.h"
#include "igc_base.h"

Expand Down Expand Up @@ -56,6 +57,8 @@ struct igc_info {
struct igc_nvm_operations *nvm_ops;
};

extern const struct igc_info igc_base_info;

struct igc_mac_info {
struct igc_mac_operations ops;

Expand Down
Loading

0 comments on commit ab40561

Please sign in to comment.