Merge branch 'for-next/e1000'
This commit is contained in:
commit
f0a3a956b8
|
@ -10,7 +10,7 @@ obj-$(CONFIG_DRIVER_NET_CPSW) += cpsw.o
|
||||||
obj-$(CONFIG_DRIVER_NET_DAVINCI_EMAC) += davinci_emac.o
|
obj-$(CONFIG_DRIVER_NET_DAVINCI_EMAC) += davinci_emac.o
|
||||||
obj-$(CONFIG_DRIVER_NET_DESIGNWARE) += designware.o
|
obj-$(CONFIG_DRIVER_NET_DESIGNWARE) += designware.o
|
||||||
obj-$(CONFIG_DRIVER_NET_DM9K) += dm9k.o
|
obj-$(CONFIG_DRIVER_NET_DM9K) += dm9k.o
|
||||||
obj-$(CONFIG_DRIVER_NET_E1000) += e1000.o
|
obj-$(CONFIG_DRIVER_NET_E1000) += e1000/regio.o e1000/main.o e1000/eeprom.o
|
||||||
obj-$(CONFIG_DRIVER_NET_ENC28J60) += enc28j60.o
|
obj-$(CONFIG_DRIVER_NET_ENC28J60) += enc28j60.o
|
||||||
obj-$(CONFIG_DRIVER_NET_EP93XX) += ep93xx.o
|
obj-$(CONFIG_DRIVER_NET_EP93XX) += ep93xx.o
|
||||||
obj-$(CONFIG_DRIVER_NET_ETHOC) += ethoc.o
|
obj-$(CONFIG_DRIVER_NET_ETHOC) += ethoc.o
|
||||||
|
|
|
@ -16,6 +16,10 @@
|
||||||
* Structures, enums, and macros for the MAC
|
* Structures, enums, and macros for the MAC
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
#include <io.h>
|
||||||
|
#include <net.h>
|
||||||
|
#include <linux/mtd/mtd.h>
|
||||||
|
|
||||||
#ifndef _E1000_HW_H_
|
#ifndef _E1000_HW_H_
|
||||||
#define _E1000_HW_H_
|
#define _E1000_HW_H_
|
||||||
|
|
||||||
|
@ -25,18 +29,6 @@
|
||||||
#define DEBUGFUNC() do { } while (0)
|
#define DEBUGFUNC() do { } while (0)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* I/O wrapper functions */
|
|
||||||
#define E1000_WRITE_REG(a, reg, value) \
|
|
||||||
writel((value), ((a)->hw_addr + E1000_##reg))
|
|
||||||
#define E1000_READ_REG(a, reg) \
|
|
||||||
readl((a)->hw_addr + E1000_##reg)
|
|
||||||
#define E1000_WRITE_REG_ARRAY(a, reg, offset, value) \
|
|
||||||
writel((value), ((a)->hw_addr + E1000_##reg + ((offset) << 2)))
|
|
||||||
#define E1000_READ_REG_ARRAY(a, reg, offset) \
|
|
||||||
readl((a)->hw_addr + E1000_##reg + ((offset) << 2))
|
|
||||||
#define E1000_WRITE_FLUSH(a) \
|
|
||||||
do { E1000_READ_REG(a, STATUS); } while (0)
|
|
||||||
|
|
||||||
/* Enumerated types specific to the e1000 hardware */
|
/* Enumerated types specific to the e1000 hardware */
|
||||||
/* Media Access Controlers */
|
/* Media Access Controlers */
|
||||||
typedef enum {
|
typedef enum {
|
||||||
|
@ -398,6 +390,11 @@ struct e1000_tx_desc {
|
||||||
#define E1000_MC_TBL_SIZE 128 /* Multicast Filter Table (4096 bits) */
|
#define E1000_MC_TBL_SIZE 128 /* Multicast Filter Table (4096 bits) */
|
||||||
#define E1000_VLAN_FILTER_TBL_SIZE 128 /* VLAN Filter Table (4096 bits) */
|
#define E1000_VLAN_FILTER_TBL_SIZE 128 /* VLAN Filter Table (4096 bits) */
|
||||||
|
|
||||||
|
#define E1000_MIGHT_BE_REMAPPED 0x80000000 /* Flag indicating that on
|
||||||
|
some variants of the chip
|
||||||
|
register offset might be
|
||||||
|
different */
|
||||||
|
|
||||||
/* Register Set. (82543, 82544)
|
/* Register Set. (82543, 82544)
|
||||||
*
|
*
|
||||||
* Registers are defined to be 32 bits and should be accessed as 32 bit values.
|
* Registers are defined to be 32 bits and should be accessed as 32 bit values.
|
||||||
|
@ -413,9 +410,7 @@ struct e1000_tx_desc {
|
||||||
#define E1000_CTRL 0x00000 /* Device Control - RW */
|
#define E1000_CTRL 0x00000 /* Device Control - RW */
|
||||||
#define E1000_STATUS 0x00008 /* Device Status - RO */
|
#define E1000_STATUS 0x00008 /* Device Status - RO */
|
||||||
#define E1000_EECD 0x00010 /* EEPROM/Flash Control - RW */
|
#define E1000_EECD 0x00010 /* EEPROM/Flash Control - RW */
|
||||||
#define E1000_I210_EECD 0x12010 /* EEPROM/Flash Control - RW */
|
|
||||||
#define E1000_EERD 0x00014 /* EEPROM Read - RW */
|
#define E1000_EERD 0x00014 /* EEPROM Read - RW */
|
||||||
#define E1000_I210_EERD 0x12014 /* EEPROM Read - RW */
|
|
||||||
#define E1000_CTRL_EXT 0x00018 /* Extended Device Control - RW */
|
#define E1000_CTRL_EXT 0x00018 /* Extended Device Control - RW */
|
||||||
#define E1000_MDIC 0x00020 /* MDI Control - RW */
|
#define E1000_MDIC 0x00020 /* MDI Control - RW */
|
||||||
#define E1000_FCAL 0x00028 /* Flow Control Address Low - RW */
|
#define E1000_FCAL 0x00028 /* Flow Control Address Low - RW */
|
||||||
|
@ -440,21 +435,24 @@ struct e1000_tx_desc {
|
||||||
#define E1000_LEDCTL 0x00E00 /* LED Control - RW */
|
#define E1000_LEDCTL 0x00E00 /* LED Control - RW */
|
||||||
#define E1000_EXTCNF_CTRL 0x00F00 /* Extended Configuration Control */
|
#define E1000_EXTCNF_CTRL 0x00F00 /* Extended Configuration Control */
|
||||||
#define E1000_EXTCNF_SIZE 0x00F08 /* Extended Configuration Size */
|
#define E1000_EXTCNF_SIZE 0x00F08 /* Extended Configuration Size */
|
||||||
#define E1000_PHY_CTRL 0x00F10 /* PHY Control Register in CSR */
|
#define E1000_PHY_CTRL (E1000_MIGHT_BE_REMAPPED | 0x00F10) /* PHY Control Register in CSR */
|
||||||
#define E1000_I210_PHY_CTRL 0x00E14 /* PHY Control Register in CSR */
|
#define E1000_I210_PHY_CTRL 0x00E14 /* PHY Control Register in CSR */
|
||||||
#define FEXTNVM_SW_CONFIG 0x0001
|
#define FEXTNVM_SW_CONFIG 0x0001
|
||||||
#define E1000_PBA 0x01000 /* Packet Buffer Allocation - RW */
|
#define E1000_PBA 0x01000 /* Packet Buffer Allocation - RW */
|
||||||
#define E1000_PBS 0x01008 /* Packet Buffer Size */
|
#define E1000_PBS 0x01008 /* Packet Buffer Size */
|
||||||
#define E1000_EEMNGCTL 0x01010 /* MNG EEprom Control */
|
#define E1000_EEMNGCTL (E1000_MIGHT_BE_REMAPPED | 0x01010) /* MNG EEprom Control */
|
||||||
#define E1000_I210_EEMNGCTL 0x12030 /* MNG EEprom Control */
|
#define E1000_I210_EEMNGCTL 0x12030 /* MNG EEprom Control */
|
||||||
#define E1000_FLASH_UPDATES 1000
|
#define E1000_FLASH_UPDATES 1000
|
||||||
#define E1000_EEARBC 0x01024 /* EEPROM Auto Read Bus Control */
|
#define E1000_EEARBC 0x01024 /* EEPROM Auto Read Bus Control */
|
||||||
#define E1000_FLASHT 0x01028 /* FLASH Timer Register */
|
#define E1000_FLASHT 0x01028 /* FLASH Timer Register */
|
||||||
#define E1000_EEWR 0x0102C /* EEPROM Write Register - RW */
|
#define E1000_EEWR (E1000_MIGHT_BE_REMAPPED | 0x0102C) /* EEPROM Write Register - RW */
|
||||||
#define E1000_I210_EEWR 0x12018 /* EEPROM Write Register - RW */
|
#define E1000_I210_EEWR 0x12018 /* EEPROM Write Register - RW */
|
||||||
#define E1000_FLSWCTL 0x01030 /* FLASH control register */
|
#define E1000_FLSWCTL 0x01030 /* FLASH control register */
|
||||||
|
#define E1000_I210_FLSWCTL 0x12048 /* FLASH control register */
|
||||||
#define E1000_FLSWDATA 0x01034 /* FLASH data register */
|
#define E1000_FLSWDATA 0x01034 /* FLASH data register */
|
||||||
|
#define E1000_I210_FLSWDATA 0x1204C /* FLASH data register */
|
||||||
#define E1000_FLSWCNT 0x01038 /* FLASH Access Counter */
|
#define E1000_FLSWCNT 0x01038 /* FLASH Access Counter */
|
||||||
|
#define E1000_I210_FLSWCNT 0x12050 /* FLASH Access Counter */
|
||||||
#define E1000_FLOP 0x0103C /* FLASH Opcode Register */
|
#define E1000_FLOP 0x0103C /* FLASH Opcode Register */
|
||||||
#define E1000_ERT 0x02008 /* Early Rx Threshold - RW */
|
#define E1000_ERT 0x02008 /* Early Rx Threshold - RW */
|
||||||
#define E1000_FCRTL 0x02160 /* Flow Control Receive Threshold Low - RW */
|
#define E1000_FCRTL 0x02160 /* Flow Control Receive Threshold Low - RW */
|
||||||
|
@ -693,15 +691,20 @@ struct e1000_tx_desc {
|
||||||
#define E1000_82542_FFMT E1000_FFMT
|
#define E1000_82542_FFMT E1000_FFMT
|
||||||
#define E1000_82542_FFVT E1000_FFVT
|
#define E1000_82542_FFVT E1000_FFVT
|
||||||
|
|
||||||
|
struct e1000_hw;
|
||||||
|
|
||||||
struct e1000_eeprom_info {
|
struct e1000_eeprom_info {
|
||||||
e1000_eeprom_type type;
|
e1000_eeprom_type type;
|
||||||
uint16_t word_size;
|
size_t word_size;
|
||||||
uint16_t opcode_bits;
|
uint16_t opcode_bits;
|
||||||
uint16_t address_bits;
|
uint16_t address_bits;
|
||||||
uint16_t delay_usec;
|
uint16_t delay_usec;
|
||||||
uint16_t page_size;
|
|
||||||
bool use_eerd;
|
int32_t (*acquire) (struct e1000_hw *hw);
|
||||||
bool use_eewr;
|
void (*release) (struct e1000_hw *hw);
|
||||||
|
|
||||||
|
int32_t (*read) (struct e1000_hw *hw, uint16_t offset,
|
||||||
|
uint16_t words, uint16_t *data);
|
||||||
};
|
};
|
||||||
|
|
||||||
#define E1000_EEPROM_SWDPIN0 0x0001 /* SWDPIN 0 EEPROM Value */
|
#define E1000_EEPROM_SWDPIN0 0x0001 /* SWDPIN 0 EEPROM Value */
|
||||||
|
@ -802,9 +805,12 @@ struct e1000_eeprom_info {
|
||||||
#define E1000_EECD_SELSHAD 0x00020000 /* Select Shadow RAM */
|
#define E1000_EECD_SELSHAD 0x00020000 /* Select Shadow RAM */
|
||||||
#define E1000_EECD_INITSRAM 0x00040000 /* Initialize Shadow RAM */
|
#define E1000_EECD_INITSRAM 0x00040000 /* Initialize Shadow RAM */
|
||||||
#define E1000_EECD_FLUPD 0x00080000 /* Update FLASH */
|
#define E1000_EECD_FLUPD 0x00080000 /* Update FLASH */
|
||||||
|
#define E1000_EECD_I210_FLASH_DETECTED (1 << 19) /* FLASH detected */
|
||||||
#define E1000_EECD_AUPDEN 0x00100000 /* Enable Autonomous FLASH update */
|
#define E1000_EECD_AUPDEN 0x00100000 /* Enable Autonomous FLASH update */
|
||||||
#define E1000_EECD_SHADV 0x00200000 /* Shadow RAM Data Valid */
|
#define E1000_EECD_SHADV 0x00200000 /* Shadow RAM Data Valid */
|
||||||
#define E1000_EECD_SEC1VAL 0x00400000 /* Sector One Valid */
|
#define E1000_EECD_SEC1VAL 0x00400000 /* Sector One Valid */
|
||||||
|
#define E1000_EECD_I210_FLUPD (1 << 23)
|
||||||
|
#define E1000_EECD_I210_FLUDONE (1 << 26)
|
||||||
#define E1000_EECD_SECVAL_SHIFT 22
|
#define E1000_EECD_SECVAL_SHIFT 22
|
||||||
#define E1000_STM_OPCODE 0xDB00
|
#define E1000_STM_OPCODE 0xDB00
|
||||||
#define E1000_HICR_FW_RESET 0xC0
|
#define E1000_HICR_FW_RESET 0xC0
|
||||||
|
@ -1978,6 +1984,11 @@ struct e1000_eeprom_info {
|
||||||
#define ICH_FLASH_LINEAR_ADDR_MASK 0x00FFFFFF
|
#define ICH_FLASH_LINEAR_ADDR_MASK 0x00FFFFFF
|
||||||
|
|
||||||
#define E1000_SW_FW_SYNC 0x05B5C /* Software-Firmware Synchronization - RW */
|
#define E1000_SW_FW_SYNC 0x05B5C /* Software-Firmware Synchronization - RW */
|
||||||
|
#define E1000_PCIEMISC 0x05BB8
|
||||||
|
#define E1000_PCIEMISC_DMA_IDLE (1 << 9)
|
||||||
|
#define E1000_PCIEMISC_RESERVED_MASK (~(E1000_PCIEMISC_DMA_IDLE))
|
||||||
|
#define E1000_PCIEMISC_RESERVED_PATTERN1 0x8A
|
||||||
|
#define E1000_PCIEMISC_RESERVED_PATTERN2 (0x122 << 10)
|
||||||
|
|
||||||
/* SPI EEPROM Status Register */
|
/* SPI EEPROM Status Register */
|
||||||
#define EEPROM_STATUS_RDY_SPI 0x01
|
#define EEPROM_STATUS_RDY_SPI 0x01
|
||||||
|
@ -2090,4 +2101,117 @@ struct e1000_eeprom_info {
|
||||||
|
|
||||||
#define E1000_CTRL_EXT_INT_TIMER_CLR 0x20000000 /* Clear Interrupt timers
|
#define E1000_CTRL_EXT_INT_TIMER_CLR 0x20000000 /* Clear Interrupt timers
|
||||||
after IMS clear */
|
after IMS clear */
|
||||||
|
|
||||||
|
#define E1000_FLA 0x1201C
|
||||||
|
#define E1000_FLA_FL_SIZE_SHIFT 17
|
||||||
|
#define E1000_FLA_FL_SIZE_MASK (0b111 << E1000_FLA_FL_SIZE_SHIFT) /* EEprom Size */
|
||||||
|
#define E1000_FLA_FL_SIZE_2MB 0b101
|
||||||
|
#define E1000_FLA_FL_SIZE_4MB 0b110
|
||||||
|
#define E1000_FLA_FL_SIZE_8MB 0b111
|
||||||
|
|
||||||
|
|
||||||
|
#define E1000_FLSWCTL_ADDR(a) ((a) & 0x00FFFFFF)
|
||||||
|
#define E1000_FLSWCTL_CMD_READ 0b0000
|
||||||
|
#define E1000_FLSWCTL_CMD_WRITE 0b0001
|
||||||
|
#define E1000_FLSWCTL_CMD_ERASE_SECTOR 0b0010
|
||||||
|
#define E1000_FLSWCTL_CMD_ERASE_DEVICE 0b0011
|
||||||
|
#define E1000_FLSWCTL_CMD(c) ((0b1111 & (c)) << 24)
|
||||||
|
|
||||||
|
#define E1000_FLSWCTL_CMD_ADDR_MASK 0x0FFFFFFF
|
||||||
|
|
||||||
|
#define E1000_FLSWCTL_CMDV (1 << 28)
|
||||||
|
#define E1000_FLSWCTL_FLBUSY (1 << 29)
|
||||||
|
#define E1000_FLSWCTL_DONE (1 << 30)
|
||||||
|
#define E1000_FLSWCTL_GLDONE (1 << 31)
|
||||||
|
|
||||||
|
|
||||||
|
#define E1000_INVM_TEST(n) (0x122A0 + 4 * (n))
|
||||||
|
#define E1000_INVM_DATA_(n) (0x12120 + 4 * (n))
|
||||||
|
#if 0
|
||||||
|
#define E1000_INVM_DATA(n) E1000_INVM_TEST(n)
|
||||||
|
#else
|
||||||
|
#define E1000_INVM_DATA(n) E1000_INVM_DATA_(n)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#define E1000_INVM_LOCK(n) (0x12220 + 4 * (n))
|
||||||
|
#define E1000_INVM_LOCK_BIT (1 << 0)
|
||||||
|
|
||||||
|
#define E1000_INVM_PROTECT 0x12324
|
||||||
|
#define E1000_INVM_PROTECT_CODE (0xABACADA << 4)
|
||||||
|
#define E1000_INVM_PROTECT_BUSY (1 << 2)
|
||||||
|
#define E1000_INVM_PROTECT_WRITE_ERROR (1 << 1)
|
||||||
|
#define E1000_INVM_PROTECT_ALLOW_WRITE (1 << 0)
|
||||||
|
|
||||||
|
#define E1000_INVM_DATA_MAX_N 63
|
||||||
|
|
||||||
|
#define E1000_EEMNGCTL_CFG_DONE (1 << 18)
|
||||||
|
|
||||||
|
|
||||||
|
struct e1000_hw {
|
||||||
|
struct eth_device edev;
|
||||||
|
|
||||||
|
struct pci_dev *pdev;
|
||||||
|
struct device_d *dev;
|
||||||
|
|
||||||
|
void __iomem *hw_addr;
|
||||||
|
|
||||||
|
e1000_mac_type mac_type;
|
||||||
|
e1000_phy_type phy_type;
|
||||||
|
uint32_t txd_cmd;
|
||||||
|
e1000_media_type media_type;
|
||||||
|
e1000_fc_type fc;
|
||||||
|
struct e1000_eeprom_info eeprom;
|
||||||
|
|
||||||
|
struct {
|
||||||
|
struct cdev cdev;
|
||||||
|
struct device_d dev;
|
||||||
|
int line;
|
||||||
|
} invm;
|
||||||
|
|
||||||
|
struct mtd_info mtd;
|
||||||
|
|
||||||
|
uint32_t phy_id;
|
||||||
|
uint32_t phy_revision;
|
||||||
|
uint32_t original_fc;
|
||||||
|
uint32_t autoneg_failed;
|
||||||
|
uint16_t autoneg_advertised;
|
||||||
|
uint16_t pci_cmd_word;
|
||||||
|
uint16_t device_id;
|
||||||
|
uint16_t vendor_id;
|
||||||
|
uint8_t revision_id;
|
||||||
|
struct mii_bus miibus;
|
||||||
|
|
||||||
|
struct e1000_tx_desc *tx_base;
|
||||||
|
struct e1000_rx_desc *rx_base;
|
||||||
|
unsigned char *packet;
|
||||||
|
|
||||||
|
int tx_tail;
|
||||||
|
int rx_tail, rx_last;
|
||||||
|
};
|
||||||
|
|
||||||
|
void e1000_write_reg(struct e1000_hw *hw, uint32_t reg,
|
||||||
|
uint32_t value);
|
||||||
|
uint32_t e1000_read_reg(struct e1000_hw *hw, uint32_t reg);
|
||||||
|
uint32_t e1000_read_reg_array(struct e1000_hw *hw,
|
||||||
|
uint32_t base, uint32_t idx);
|
||||||
|
void e1000_write_reg_array(struct e1000_hw *hw, uint32_t base,
|
||||||
|
uint32_t idx, uint32_t value);
|
||||||
|
|
||||||
|
void e1000_write_flush(struct e1000_hw *hw);
|
||||||
|
|
||||||
|
int32_t e1000_init_eeprom_params(struct e1000_hw *hw);
|
||||||
|
int e1000_validate_eeprom_checksum(struct e1000_hw *hw);
|
||||||
|
int32_t e1000_read_eeprom(struct e1000_hw *hw, uint16_t offset,
|
||||||
|
uint16_t words,
|
||||||
|
uint16_t *data);
|
||||||
|
|
||||||
|
int32_t e1000_swfw_sync_acquire(struct e1000_hw *hw, uint16_t mask);
|
||||||
|
int32_t e1000_swfw_sync_release(struct e1000_hw *hw, uint16_t mask);
|
||||||
|
|
||||||
|
int e1000_poll_reg(struct e1000_hw *hw, uint32_t reg,
|
||||||
|
uint32_t mask, uint32_t value,
|
||||||
|
uint64_t timeout);
|
||||||
|
|
||||||
|
int e1000_register_eeprom(struct e1000_hw *hw);
|
||||||
|
|
||||||
#endif /* _E1000_HW_H_ */
|
#endif /* _E1000_HW_H_ */
|
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,70 @@
|
||||||
|
#include <common.h>
|
||||||
|
|
||||||
|
#include "e1000.h"
|
||||||
|
|
||||||
|
static uint32_t e1000_true_offset(struct e1000_hw *hw, uint32_t reg)
|
||||||
|
{
|
||||||
|
if (reg & E1000_MIGHT_BE_REMAPPED) {
|
||||||
|
reg &= ~E1000_MIGHT_BE_REMAPPED;
|
||||||
|
|
||||||
|
if (hw->mac_type == e1000_igb) {
|
||||||
|
switch (reg) {
|
||||||
|
case E1000_EEWR:
|
||||||
|
reg = E1000_I210_EEWR;
|
||||||
|
break;
|
||||||
|
case E1000_PHY_CTRL:
|
||||||
|
reg = E1000_I210_PHY_CTRL;
|
||||||
|
break;
|
||||||
|
case E1000_EEMNGCTL:
|
||||||
|
reg = E1000_I210_EEMNGCTL;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
return reg;
|
||||||
|
}
|
||||||
|
|
||||||
|
void e1000_write_reg(struct e1000_hw *hw, uint32_t reg, uint32_t value)
|
||||||
|
{
|
||||||
|
reg = e1000_true_offset(hw, reg);
|
||||||
|
writel(value, hw->hw_addr + reg);
|
||||||
|
}
|
||||||
|
|
||||||
|
uint32_t e1000_read_reg(struct e1000_hw *hw, uint32_t reg)
|
||||||
|
{
|
||||||
|
reg = e1000_true_offset(hw, reg);
|
||||||
|
return readl(hw->hw_addr + reg);
|
||||||
|
}
|
||||||
|
|
||||||
|
void e1000_write_reg_array(struct e1000_hw *hw, uint32_t base,
|
||||||
|
uint32_t idx, uint32_t value)
|
||||||
|
{
|
||||||
|
writel(value, hw->hw_addr + base + idx * sizeof(uint32_t));
|
||||||
|
}
|
||||||
|
|
||||||
|
uint32_t e1000_read_reg_array(struct e1000_hw *hw, uint32_t base, uint32_t idx)
|
||||||
|
{
|
||||||
|
return readl(hw->hw_addr + base + idx * sizeof(uint32_t));
|
||||||
|
}
|
||||||
|
|
||||||
|
void e1000_write_flush(struct e1000_hw *hw)
|
||||||
|
{
|
||||||
|
e1000_read_reg(hw, E1000_STATUS);
|
||||||
|
}
|
||||||
|
|
||||||
|
int e1000_poll_reg(struct e1000_hw *hw, uint32_t reg, uint32_t mask,
|
||||||
|
uint32_t value, uint64_t timeout)
|
||||||
|
{
|
||||||
|
const uint64_t start = get_time_ns();
|
||||||
|
|
||||||
|
do {
|
||||||
|
const uint32_t v = e1000_read_reg(hw, reg);
|
||||||
|
|
||||||
|
if ((v & mask) == value)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
} while (!is_timeout(start, timeout));
|
||||||
|
|
||||||
|
return -ETIMEDOUT;
|
||||||
|
}
|
Loading…
Reference in New Issue