igb 0000:02:00.2 xxxxx: PCIe link lost, device now detached
读取到的 hw_addr 为全 F 时,会报错:“PCIe link lost, device now detached”。
/* 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)))) { // value 如果全 F 会报错
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;
}
读 mac 地址方法:内部寄存器和内存可以通过 基地值寄存器(BAR0 或 BAR0/1)+ 偏移量 的方法进行访问。这里通过函数 readl 实现 hw_addr 的读取。
函数 readl 的实现:
/*
readl() 从内存映射的 I/O 空间读取数据,readl 从 I/O 读取 32 位数据 ( 4 字节 )。
变量 :addr 是 I/O 地址。
返回值 : 从 I/O 空间读取的数值。
*/
#include
unsigned char readl (unsigned int addr )
/*
定义
*/
#define readl(addr) __le32_to_cpu(__raw_readl(addr))
#ifndef __raw_readl
static inline u32 __raw_readl(const volatile void __iomem *addr)
{
return *(const volatile u32 __force *) addr;
}
#endif
检测网卡的flash是否存在时会调用 igb_rd32:
/**
* 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);