从最常见的修改mac address 说起:
section 1: 读mac address
/* Only the MAC addr is required to be present in the iNVM */
switch (offset) {
case NVM_MAC_ADDR:
ret_val = igb_read_invm_word_i210(hw, (u8)offset, &data[0]);
ret_val |= igb_read_invm_word_i210(hw, (u8)offset+1,
&data[1]);
ret_val |= igb_read_invm_word_i210(hw, (u8)offset+2,
&data[2]);
if (ret_val)
hw_dbg("MAC Addr not found in iNVM\n");
break;
mac address 是放在eeprom 最开始的位置:
/* NVM Word Offsets */
#define NVM_COMPAT 0x0003
#define NVM_ID_LED_SETTINGS 0x0004 /* SERDES output amplitude */
#define NVM_VERSION 0x0005
#define NVM_INIT_CONTROL2_REG 0x000F
#define NVM_INIT_CONTROL3_PORT_B 0x0014
#define NVM_INIT_CONTROL3_PORT_A 0x0024
#define NVM_ALT_MAC_ADDR_PTR 0x0037
#define NVM_CHECKSUM_REG 0x003F
#define NVM_COMPATIBILITY_REG_3 0x0003
#define NVM_COMPATIBILITY_BIT_MASK 0x8000
#define NVM_MAC_ADDR 0x0000
#define NVM_SUB_DEV_ID 0x000B
#define NVM_SUB_VEN_ID 0x000C
#define NVM_DEV_ID 0x000D
#define NVM_VEN_ID 0x000E
#define NVM_INIT_CTRL_2 0x000F
#define NVM_INIT_CTRL_4 0x0013
#define NVM_LED_1_CFG 0x001C
#define NVM_LED_0_2_CFG 0x001F
#define NVM_ETRACK_WORD 0x0042
#define NVM_ETRACK_HIWORD 0x0043
#define NVM_COMB_VER_OFF 0x0083
#define NVM_COMB_VER_PTR 0x003d
/**
* igb_set_mac - Change the Ethernet Address of the NIC
* @netdev: network interface device structure
* @p: pointer to an address structure
*
* Returns 0 on success, negative on failure
**/
static int igb_set_mac(struct net_device *netdev, void *p)
{
struct igb_adapter *adapter = netdev_priv(netdev);
struct e1000_hw *hw = &adapter->hw;
struct sockaddr *addr = p;
if (!is_valid_ether_addr(addr->sa_data))
return -EADDRNOTAVAIL;
memcpy(netdev->dev_addr, addr->sa_data, netdev->addr_len);
memcpy(hw->mac.addr, addr->sa_data, netdev->addr_len);
/* set the correct pool for the new PF MAC address in entry 0 */
igb_rar_set_qsel(adapter, hw->mac.addr, 0,
adapter->vfs_allocated_count);
return 0;
}
在最开始,我们的检测这块网卡的flash是否存在:
/**
* igb_get_flash_presence_i210 - Check if flash device is detected.
* @hw: pointer to the HW structure
*
**/
bool igb_get_flash_presence_i210(struct e1000_hw *hw)
{
u32 eec = 0;
bool ret_val = false;
eec = rd32(E1000_EECD);
if (eec & E1000_EECD_FLASH_DETECTED_I210)
ret_val = true;
return ret_val;
}
rd32定义在 e1000_regs.h里面
#define rd32(reg) (igb_rd32(hw, reg))
u32 igb_rd32(struct e1000_hw *hw, u32 reg);
其函数实现在igb_main.c
u32 igb_rd32(struct e1000_hw *hw, u32 reg)
{
struct igb_adapter *igb = container_of(hw, struct igb_adapter, hw);
u8 __iomem *hw_addr = ACCESS_ONCE(hw->hw_addr);
u32 value = 0;
if (E1000_REMOVED(hw_addr))
return ~value;
value = readl(&hw_addr[reg]);
/* reads should not return all F's */
if (!(~value) && (!reg || !(~readl(hw_addr)))) {
struct net_device *netdev = igb->netdev;
hw->hw_addr = NULL;
netif_device_detach(netdev);
netdev_err(netdev, "PCIe link lost, device now detached\n");
}
return value;
}
如何通过pcd 配置空间读到mac address ?
那我们就来到9.3.11