linux i210 网卡驱动解读

从最常见的修改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



你可能感兴趣的:(Linux源码剖析)