Merge branch 'drivers_6.4.0' into 'stable-1.6'

Add e1000e and igb for 6.4

Closes #180

See merge request etherlab.org/ethercat!169
This commit is contained in:
Florian Pose 2025-06-23 10:50:41 +02:00
commit ced654cb3e
90 changed files with 117029 additions and 3 deletions

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,70 @@
/* SPDX-License-Identifier: GPL-2.0 */
/* Copyright(c) 1999 - 2018 Intel Corporation. */
#ifndef _E1000E_80003ES2LAN_H_
#define _E1000E_80003ES2LAN_H_
#define E1000_KMRNCTRLSTA_OFFSET_FIFO_CTRL 0x00
#define E1000_KMRNCTRLSTA_OFFSET_INB_CTRL 0x02
#define E1000_KMRNCTRLSTA_OFFSET_HD_CTRL 0x10
#define E1000_KMRNCTRLSTA_OFFSET_MAC2PHY_OPMODE 0x1F
#define E1000_KMRNCTRLSTA_FIFO_CTRL_RX_BYPASS 0x0008
#define E1000_KMRNCTRLSTA_FIFO_CTRL_TX_BYPASS 0x0800
#define E1000_KMRNCTRLSTA_INB_CTRL_DIS_PADDING 0x0010
#define E1000_KMRNCTRLSTA_HD_CTRL_10_100_DEFAULT 0x0004
#define E1000_KMRNCTRLSTA_HD_CTRL_1000_DEFAULT 0x0000
#define E1000_KMRNCTRLSTA_OPMODE_E_IDLE 0x2000
#define E1000_KMRNCTRLSTA_OPMODE_MASK 0x000C
#define E1000_KMRNCTRLSTA_OPMODE_INBAND_MDIO 0x0004
#define E1000_TCTL_EXT_GCEX_MASK 0x000FFC00 /* Gig Carry Extend Padding */
#define DEFAULT_TCTL_EXT_GCEX_80003ES2LAN 0x00010000
#define DEFAULT_TIPG_IPGT_1000_80003ES2LAN 0x8
#define DEFAULT_TIPG_IPGT_10_100_80003ES2LAN 0x9
/* GG82563 PHY Specific Status Register (Page 0, Register 16 */
#define GG82563_PSCR_POLARITY_REVERSAL_DISABLE 0x0002 /* 1=Reversal Dis */
#define GG82563_PSCR_CROSSOVER_MODE_MASK 0x0060
#define GG82563_PSCR_CROSSOVER_MODE_MDI 0x0000 /* 00=Manual MDI */
#define GG82563_PSCR_CROSSOVER_MODE_MDIX 0x0020 /* 01=Manual MDIX */
#define GG82563_PSCR_CROSSOVER_MODE_AUTO 0x0060 /* 11=Auto crossover */
/* PHY Specific Control Register 2 (Page 0, Register 26) */
#define GG82563_PSCR2_REVERSE_AUTO_NEG 0x2000 /* 1=Reverse Auto-Neg */
/* MAC Specific Control Register (Page 2, Register 21) */
/* Tx clock speed for Link Down and 1000BASE-T for the following speeds */
#define GG82563_MSCR_TX_CLK_MASK 0x0007
#define GG82563_MSCR_TX_CLK_10MBPS_2_5 0x0004
#define GG82563_MSCR_TX_CLK_100MBPS_25 0x0005
#define GG82563_MSCR_TX_CLK_1000MBPS_25 0x0007
#define GG82563_MSCR_ASSERT_CRS_ON_TX 0x0010 /* 1=Assert */
/* DSP Distance Register (Page 5, Register 26)
* 0 = <50M
* 1 = 50-80M
* 2 = 80-100M
* 3 = 110-140M
* 4 = >140M
*/
#define GG82563_DSPD_CABLE_LENGTH 0x0007
/* Kumeran Mode Control Register (Page 193, Register 16) */
#define GG82563_KMCR_PASS_FALSE_CARRIER 0x0800
/* Max number of times Kumeran read/write should be validated */
#define GG82563_MAX_KMRN_RETRY 0x5
/* Power Management Control Register (Page 193, Register 20) */
/* 1=Enable SERDES Electrical Idle */
#define GG82563_PMCR_ENABLE_ELECTRICAL_IDLE 0x0001
/* In-Band Control Register (Page 194, Register 18) */
#define GG82563_ICR_DIS_PADDING 0x0010 /* Disable Padding */
#endif

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,70 @@
/* SPDX-License-Identifier: GPL-2.0 */
/* Copyright(c) 1999 - 2018 Intel Corporation. */
#ifndef _E1000E_80003ES2LAN_H_
#define _E1000E_80003ES2LAN_H_
#define E1000_KMRNCTRLSTA_OFFSET_FIFO_CTRL 0x00
#define E1000_KMRNCTRLSTA_OFFSET_INB_CTRL 0x02
#define E1000_KMRNCTRLSTA_OFFSET_HD_CTRL 0x10
#define E1000_KMRNCTRLSTA_OFFSET_MAC2PHY_OPMODE 0x1F
#define E1000_KMRNCTRLSTA_FIFO_CTRL_RX_BYPASS 0x0008
#define E1000_KMRNCTRLSTA_FIFO_CTRL_TX_BYPASS 0x0800
#define E1000_KMRNCTRLSTA_INB_CTRL_DIS_PADDING 0x0010
#define E1000_KMRNCTRLSTA_HD_CTRL_10_100_DEFAULT 0x0004
#define E1000_KMRNCTRLSTA_HD_CTRL_1000_DEFAULT 0x0000
#define E1000_KMRNCTRLSTA_OPMODE_E_IDLE 0x2000
#define E1000_KMRNCTRLSTA_OPMODE_MASK 0x000C
#define E1000_KMRNCTRLSTA_OPMODE_INBAND_MDIO 0x0004
#define E1000_TCTL_EXT_GCEX_MASK 0x000FFC00 /* Gig Carry Extend Padding */
#define DEFAULT_TCTL_EXT_GCEX_80003ES2LAN 0x00010000
#define DEFAULT_TIPG_IPGT_1000_80003ES2LAN 0x8
#define DEFAULT_TIPG_IPGT_10_100_80003ES2LAN 0x9
/* GG82563 PHY Specific Status Register (Page 0, Register 16 */
#define GG82563_PSCR_POLARITY_REVERSAL_DISABLE 0x0002 /* 1=Reversal Dis */
#define GG82563_PSCR_CROSSOVER_MODE_MASK 0x0060
#define GG82563_PSCR_CROSSOVER_MODE_MDI 0x0000 /* 00=Manual MDI */
#define GG82563_PSCR_CROSSOVER_MODE_MDIX 0x0020 /* 01=Manual MDIX */
#define GG82563_PSCR_CROSSOVER_MODE_AUTO 0x0060 /* 11=Auto crossover */
/* PHY Specific Control Register 2 (Page 0, Register 26) */
#define GG82563_PSCR2_REVERSE_AUTO_NEG 0x2000 /* 1=Reverse Auto-Neg */
/* MAC Specific Control Register (Page 2, Register 21) */
/* Tx clock speed for Link Down and 1000BASE-T for the following speeds */
#define GG82563_MSCR_TX_CLK_MASK 0x0007
#define GG82563_MSCR_TX_CLK_10MBPS_2_5 0x0004
#define GG82563_MSCR_TX_CLK_100MBPS_25 0x0005
#define GG82563_MSCR_TX_CLK_1000MBPS_25 0x0007
#define GG82563_MSCR_ASSERT_CRS_ON_TX 0x0010 /* 1=Assert */
/* DSP Distance Register (Page 5, Register 26)
* 0 = <50M
* 1 = 50-80M
* 2 = 80-100M
* 3 = 110-140M
* 4 = >140M
*/
#define GG82563_DSPD_CABLE_LENGTH 0x0007
/* Kumeran Mode Control Register (Page 193, Register 16) */
#define GG82563_KMCR_PASS_FALSE_CARRIER 0x0800
/* Max number of times Kumeran read/write should be validated */
#define GG82563_MAX_KMRN_RETRY 0x5
/* Power Management Control Register (Page 193, Register 20) */
/* 1=Enable SERDES Electrical Idle */
#define GG82563_PMCR_ENABLE_ELECTRICAL_IDLE 0x0001
/* In-Band Control Register (Page 194, Register 18) */
#define GG82563_ICR_DIS_PADDING 0x0010 /* Disable Padding */
#endif

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,35 @@
/* SPDX-License-Identifier: GPL-2.0 */
/* Copyright(c) 1999 - 2018 Intel Corporation. */
#ifndef _E1000E_82571_H_
#define _E1000E_82571_H_
#define ID_LED_RESERVED_F746 0xF746
#define ID_LED_DEFAULT_82573 ((ID_LED_DEF1_DEF2 << 12) | \
(ID_LED_OFF1_ON2 << 8) | \
(ID_LED_DEF1_DEF2 << 4) | \
(ID_LED_DEF1_DEF2))
#define E1000_GCR_L1_ACT_WITHOUT_L0S_RX 0x08000000
#define AN_RETRY_COUNT 5 /* Autoneg Retry Count value */
/* Intr Throttling - RW */
#define E1000_EITR_82574(_n) (0x000E8 + (0x4 * (_n)))
#define E1000_EIAC_82574 0x000DC /* Ext. Interrupt Auto Clear - RW */
#define E1000_EIAC_MASK_82574 0x01F00000
#define E1000_IVAR_INT_ALLOC_VALID 0x8
/* Manageability Operation Mode mask */
#define E1000_NVM_INIT_CTRL2_MNGM 0x6000
#define E1000_BASE1000T_STATUS 10
#define E1000_IDLE_ERROR_COUNT_MASK 0xFF
#define E1000_RECEIVE_ERROR_COUNTER 21
#define E1000_RECEIVE_ERROR_MAX 0xFFFF
bool e1000_check_phy_82574(struct e1000_hw *hw);
bool e1000e_get_laa_state_82571(struct e1000_hw *hw);
void e1000e_set_laa_state_82571(struct e1000_hw *hw, bool state);
#endif

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,35 @@
/* SPDX-License-Identifier: GPL-2.0 */
/* Copyright(c) 1999 - 2018 Intel Corporation. */
#ifndef _E1000E_82571_H_
#define _E1000E_82571_H_
#define ID_LED_RESERVED_F746 0xF746
#define ID_LED_DEFAULT_82573 ((ID_LED_DEF1_DEF2 << 12) | \
(ID_LED_OFF1_ON2 << 8) | \
(ID_LED_DEF1_DEF2 << 4) | \
(ID_LED_DEF1_DEF2))
#define E1000_GCR_L1_ACT_WITHOUT_L0S_RX 0x08000000
#define AN_RETRY_COUNT 5 /* Autoneg Retry Count value */
/* Intr Throttling - RW */
#define E1000_EITR_82574(_n) (0x000E8 + (0x4 * (_n)))
#define E1000_EIAC_82574 0x000DC /* Ext. Interrupt Auto Clear - RW */
#define E1000_EIAC_MASK_82574 0x01F00000
#define E1000_IVAR_INT_ALLOC_VALID 0x8
/* Manageability Operation Mode mask */
#define E1000_NVM_INIT_CTRL2_MNGM 0x6000
#define E1000_BASE1000T_STATUS 10
#define E1000_IDLE_ERROR_COUNT_MASK 0xFF
#define E1000_RECEIVE_ERROR_COUNTER 21
#define E1000_RECEIVE_ERROR_MAX 0xFFFF
bool e1000_check_phy_82574(struct e1000_hw *hw);
bool e1000e_get_laa_state_82571(struct e1000_hw *hw);
void e1000e_set_laa_state_82571(struct e1000_hw *hw, bool state);
#endif

View File

@ -24,7 +24,7 @@
#-----------------------------------------------------------------------------
src := @abs_srcdir@
ccflags-y := -I@abs_top_builddir@
ccflags-y := -I@abs_top_builddir@ -I@abs_srcdir@
TOPDIR := $(src)/../..
@ -72,7 +72,7 @@ ifeq (@ENABLE_E1000E@,1)
CFLAGS_netdev-@KERNEL_E1000E@-ethercat.o = -DREV=$(REV)
ifeq (@ENABLE_DRIVER_RESOURCE_VERIFYING@,1)
ccflags-y := -DEC_ENABLE_DRIVER_RESOURCE_VERIFYING
ccflags-y += -DEC_ENABLE_DRIVER_RESOURCE_VERIFYING
endif
endif

View File

@ -562,6 +562,52 @@ EXTRA_DIST = \
regs-5.4-orig.h \
regs-6.1-ethercat.h \
regs-6.1-orig.h \
80003es2lan-6.4-ethercat.c \
80003es2lan-6.4-orig.c \
80003es2lan-6.4-ethercat.h \
80003es2lan-6.4-orig.h \
82571-6.4-ethercat.c \
82571-6.4-orig.c \
82571-6.4-ethercat.h \
82571-6.4-orig.h \
defines-6.4-ethercat.h \
defines-6.4-orig.h \
e1000e_trace-6.4-ethercat.h \
e1000e_trace-6.4-orig.h \
e1000-6.4-ethercat.h \
e1000-6.4-orig.h \
ethtool-6.4-ethercat.c \
ethtool-6.4-orig.c \
hw-6.4-ethercat.h \
hw-6.4-orig.h \
ich8lan-6.4-ethercat.c \
ich8lan-6.4-orig.c \
ich8lan-6.4-ethercat.h \
ich8lan-6.4-orig.h \
mac-6.4-ethercat.c \
mac-6.4-orig.c \
mac-6.4-ethercat.h \
mac-6.4-orig.h \
manage-6.4-ethercat.c \
manage-6.4-orig.c \
manage-6.4-ethercat.h \
manage-6.4-orig.h \
netdev-6.4-ethercat.c \
netdev-6.4-orig.c \
nvm-6.4-ethercat.c \
nvm-6.4-orig.c \
nvm-6.4-ethercat.h \
nvm-6.4-orig.h \
param-6.4-ethercat.c \
param-6.4-orig.c \
phy-6.4-ethercat.c \
phy-6.4-orig.c \
phy-6.4-ethercat.h \
phy-6.4-orig.h \
ptp-6.4-ethercat.c \
ptp-6.4-orig.c \
regs-6.4-ethercat.h \
regs-6.4-orig.h \
update.sh
#-----------------------------------------------------------------------------

View File

@ -0,0 +1,811 @@
/* SPDX-License-Identifier: GPL-2.0 */
/* Copyright(c) 1999 - 2018 Intel Corporation. */
#ifndef _E1000_DEFINES_H_
#define _E1000_DEFINES_H_
/* Number of Transmit and Receive Descriptors must be a multiple of 8 */
#define REQ_TX_DESCRIPTOR_MULTIPLE 8
#define REQ_RX_DESCRIPTOR_MULTIPLE 8
/* Definitions for power management and wakeup registers */
/* Wake Up Control */
#define E1000_WUC_APME 0x00000001 /* APM Enable */
#define E1000_WUC_PME_EN 0x00000002 /* PME Enable */
#define E1000_WUC_PME_STATUS 0x00000004 /* PME Status */
#define E1000_WUC_APMPME 0x00000008 /* Assert PME on APM Wakeup */
#define E1000_WUC_PHY_WAKE 0x00000100 /* if PHY supports wakeup */
/* Wake Up Filter Control */
#define E1000_WUFC_LNKC 0x00000001 /* Link Status Change Wakeup Enable */
#define E1000_WUFC_MAG 0x00000002 /* Magic Packet Wakeup Enable */
#define E1000_WUFC_EX 0x00000004 /* Directed Exact Wakeup Enable */
#define E1000_WUFC_MC 0x00000008 /* Directed Multicast Wakeup Enable */
#define E1000_WUFC_BC 0x00000010 /* Broadcast Wakeup Enable */
#define E1000_WUFC_ARP 0x00000020 /* ARP Request Packet Wakeup Enable */
/* Wake Up Status */
#define E1000_WUS_LNKC E1000_WUFC_LNKC
#define E1000_WUS_MAG E1000_WUFC_MAG
#define E1000_WUS_EX E1000_WUFC_EX
#define E1000_WUS_MC E1000_WUFC_MC
#define E1000_WUS_BC E1000_WUFC_BC
/* Extended Device Control */
#define E1000_CTRL_EXT_LPCD 0x00000004 /* LCD Power Cycle Done */
#define E1000_CTRL_EXT_SDP3_DATA 0x00000080 /* Value of SW Definable Pin 3 */
#define E1000_CTRL_EXT_FORCE_SMBUS 0x00000800 /* Force SMBus mode */
#define E1000_CTRL_EXT_EE_RST 0x00002000 /* Reinitialize from EEPROM */
#define E1000_CTRL_EXT_SPD_BYPS 0x00008000 /* Speed Select Bypass */
#define E1000_CTRL_EXT_RO_DIS 0x00020000 /* Relaxed Ordering disable */
#define E1000_CTRL_EXT_DMA_DYN_CLK_EN 0x00080000 /* DMA Dynamic Clock Gating */
#define E1000_CTRL_EXT_LINK_MODE_MASK 0x00C00000
#define E1000_CTRL_EXT_LINK_MODE_PCIE_SERDES 0x00C00000
#define E1000_CTRL_EXT_EIAME 0x01000000
#define E1000_CTRL_EXT_DRV_LOAD 0x10000000 /* Driver loaded bit for FW */
#define E1000_CTRL_EXT_IAME 0x08000000 /* Int ACK Auto-mask */
#define E1000_CTRL_EXT_PBA_CLR 0x80000000 /* PBA Clear */
#define E1000_CTRL_EXT_LSECCK 0x00001000
#define E1000_CTRL_EXT_PHYPDEN 0x00100000
/* Receive Descriptor bit definitions */
#define E1000_RXD_STAT_DD 0x01 /* Descriptor Done */
#define E1000_RXD_STAT_EOP 0x02 /* End of Packet */
#define E1000_RXD_STAT_IXSM 0x04 /* Ignore checksum */
#define E1000_RXD_STAT_VP 0x08 /* IEEE VLAN Packet */
#define E1000_RXD_STAT_UDPCS 0x10 /* UDP xsum calculated */
#define E1000_RXD_STAT_TCPCS 0x20 /* TCP xsum calculated */
#define E1000_RXD_ERR_CE 0x01 /* CRC Error */
#define E1000_RXD_ERR_SE 0x02 /* Symbol Error */
#define E1000_RXD_ERR_SEQ 0x04 /* Sequence Error */
#define E1000_RXD_ERR_CXE 0x10 /* Carrier Extension Error */
#define E1000_RXD_ERR_TCPE 0x20 /* TCP/UDP Checksum Error */
#define E1000_RXD_ERR_IPE 0x40 /* IP Checksum Error */
#define E1000_RXD_ERR_RXE 0x80 /* Rx Data Error */
#define E1000_RXD_SPC_VLAN_MASK 0x0FFF /* VLAN ID is in lower 12 bits */
#define E1000_RXDEXT_STATERR_TST 0x00000100 /* Time Stamp taken */
#define E1000_RXDEXT_STATERR_CE 0x01000000
#define E1000_RXDEXT_STATERR_SE 0x02000000
#define E1000_RXDEXT_STATERR_SEQ 0x04000000
#define E1000_RXDEXT_STATERR_CXE 0x10000000
#define E1000_RXDEXT_STATERR_RXE 0x80000000
/* mask to determine if packets should be dropped due to frame errors */
#define E1000_RXD_ERR_FRAME_ERR_MASK ( \
E1000_RXD_ERR_CE | \
E1000_RXD_ERR_SE | \
E1000_RXD_ERR_SEQ | \
E1000_RXD_ERR_CXE | \
E1000_RXD_ERR_RXE)
/* Same mask, but for extended and packet split descriptors */
#define E1000_RXDEXT_ERR_FRAME_ERR_MASK ( \
E1000_RXDEXT_STATERR_CE | \
E1000_RXDEXT_STATERR_SE | \
E1000_RXDEXT_STATERR_SEQ | \
E1000_RXDEXT_STATERR_CXE | \
E1000_RXDEXT_STATERR_RXE)
#define E1000_MRQC_RSS_FIELD_MASK 0xFFFF0000
#define E1000_MRQC_RSS_FIELD_IPV4_TCP 0x00010000
#define E1000_MRQC_RSS_FIELD_IPV4 0x00020000
#define E1000_MRQC_RSS_FIELD_IPV6_TCP_EX 0x00040000
#define E1000_MRQC_RSS_FIELD_IPV6 0x00100000
#define E1000_MRQC_RSS_FIELD_IPV6_TCP 0x00200000
#define E1000_RXDPS_HDRSTAT_HDRSP 0x00008000
/* Management Control */
#define E1000_MANC_SMBUS_EN 0x00000001 /* SMBus Enabled - RO */
#define E1000_MANC_ASF_EN 0x00000002 /* ASF Enabled - RO */
#define E1000_MANC_ARP_EN 0x00002000 /* Enable ARP Request Filtering */
#define E1000_MANC_RCV_TCO_EN 0x00020000 /* Receive TCO Packets Enabled */
#define E1000_MANC_BLK_PHY_RST_ON_IDE 0x00040000 /* Block phy resets */
/* Enable MAC address filtering */
#define E1000_MANC_EN_MAC_ADDR_FILTER 0x00100000
/* Enable MNG packets to host memory */
#define E1000_MANC_EN_MNG2HOST 0x00200000
#define E1000_MANC2H_PORT_623 0x00000020 /* Port 0x26f */
#define E1000_MANC2H_PORT_664 0x00000040 /* Port 0x298 */
#define E1000_MDEF_PORT_623 0x00000800 /* Port 0x26f */
#define E1000_MDEF_PORT_664 0x00000400 /* Port 0x298 */
/* Receive Control */
#define E1000_RCTL_EN 0x00000002 /* enable */
#define E1000_RCTL_SBP 0x00000004 /* store bad packet */
#define E1000_RCTL_UPE 0x00000008 /* unicast promiscuous enable */
#define E1000_RCTL_MPE 0x00000010 /* multicast promiscuous enab */
#define E1000_RCTL_LPE 0x00000020 /* long packet enable */
#define E1000_RCTL_LBM_NO 0x00000000 /* no loopback mode */
#define E1000_RCTL_LBM_MAC 0x00000040 /* MAC loopback mode */
#define E1000_RCTL_LBM_TCVR 0x000000C0 /* tcvr loopback mode */
#define E1000_RCTL_DTYP_PS 0x00000400 /* Packet Split descriptor */
#define E1000_RCTL_RDMTS_HALF 0x00000000 /* Rx desc min threshold size */
#define E1000_RCTL_RDMTS_HEX 0x00010000
#define E1000_RCTL_MO_SHIFT 12 /* multicast offset shift */
#define E1000_RCTL_MO_3 0x00003000 /* multicast offset 15:4 */
#define E1000_RCTL_BAM 0x00008000 /* broadcast enable */
/* these buffer sizes are valid if E1000_RCTL_BSEX is 0 */
#define E1000_RCTL_SZ_2048 0x00000000 /* Rx buffer size 2048 */
#define E1000_RCTL_SZ_1024 0x00010000 /* Rx buffer size 1024 */
#define E1000_RCTL_SZ_512 0x00020000 /* Rx buffer size 512 */
#define E1000_RCTL_SZ_256 0x00030000 /* Rx buffer size 256 */
/* these buffer sizes are valid if E1000_RCTL_BSEX is 1 */
#define E1000_RCTL_SZ_16384 0x00010000 /* Rx buffer size 16384 */
#define E1000_RCTL_SZ_8192 0x00020000 /* Rx buffer size 8192 */
#define E1000_RCTL_SZ_4096 0x00030000 /* Rx buffer size 4096 */
#define E1000_RCTL_VFE 0x00040000 /* vlan filter enable */
#define E1000_RCTL_CFIEN 0x00080000 /* canonical form enable */
#define E1000_RCTL_CFI 0x00100000 /* canonical form indicator */
#define E1000_RCTL_DPF 0x00400000 /* Discard Pause Frames */
#define E1000_RCTL_PMCF 0x00800000 /* pass MAC control frames */
#define E1000_RCTL_BSEX 0x02000000 /* Buffer size extension */
#define E1000_RCTL_SECRC 0x04000000 /* Strip Ethernet CRC */
/* Use byte values for the following shift parameters
* Usage:
* psrctl |= (((ROUNDUP(value0, 128) >> E1000_PSRCTL_BSIZE0_SHIFT) &
* E1000_PSRCTL_BSIZE0_MASK) |
* ((ROUNDUP(value1, 1024) >> E1000_PSRCTL_BSIZE1_SHIFT) &
* E1000_PSRCTL_BSIZE1_MASK) |
* ((ROUNDUP(value2, 1024) << E1000_PSRCTL_BSIZE2_SHIFT) &
* E1000_PSRCTL_BSIZE2_MASK) |
* ((ROUNDUP(value3, 1024) << E1000_PSRCTL_BSIZE3_SHIFT) |;
* E1000_PSRCTL_BSIZE3_MASK))
* where value0 = [128..16256], default=256
* value1 = [1024..64512], default=4096
* value2 = [0..64512], default=4096
* value3 = [0..64512], default=0
*/
#define E1000_PSRCTL_BSIZE0_MASK 0x0000007F
#define E1000_PSRCTL_BSIZE1_MASK 0x00003F00
#define E1000_PSRCTL_BSIZE2_MASK 0x003F0000
#define E1000_PSRCTL_BSIZE3_MASK 0x3F000000
#define E1000_PSRCTL_BSIZE0_SHIFT 7 /* Shift _right_ 7 */
#define E1000_PSRCTL_BSIZE1_SHIFT 2 /* Shift _right_ 2 */
#define E1000_PSRCTL_BSIZE2_SHIFT 6 /* Shift _left_ 6 */
#define E1000_PSRCTL_BSIZE3_SHIFT 14 /* Shift _left_ 14 */
/* SWFW_SYNC Definitions */
#define E1000_SWFW_EEP_SM 0x1
#define E1000_SWFW_PHY0_SM 0x2
#define E1000_SWFW_PHY1_SM 0x4
#define E1000_SWFW_CSR_SM 0x8
/* Device Control */
#define E1000_CTRL_FD 0x00000001 /* Full duplex.0=half; 1=full */
#define E1000_CTRL_GIO_MASTER_DISABLE 0x00000004 /*Blocks new Master requests */
#define E1000_CTRL_LRST 0x00000008 /* Link reset. 0=normal,1=reset */
#define E1000_CTRL_ASDE 0x00000020 /* Auto-speed detect enable */
#define E1000_CTRL_SLU 0x00000040 /* Set link up (Force Link) */
#define E1000_CTRL_ILOS 0x00000080 /* Invert Loss-Of Signal */
#define E1000_CTRL_SPD_SEL 0x00000300 /* Speed Select Mask */
#define E1000_CTRL_SPD_10 0x00000000 /* Force 10Mb */
#define E1000_CTRL_SPD_100 0x00000100 /* Force 100Mb */
#define E1000_CTRL_SPD_1000 0x00000200 /* Force 1Gb */
#define E1000_CTRL_FRCSPD 0x00000800 /* Force Speed */
#define E1000_CTRL_FRCDPX 0x00001000 /* Force Duplex */
#define E1000_CTRL_LANPHYPC_OVERRIDE 0x00010000 /* SW control of LANPHYPC */
#define E1000_CTRL_LANPHYPC_VALUE 0x00020000 /* SW value of LANPHYPC */
#define E1000_CTRL_MEHE 0x00080000 /* Memory Error Handling Enable */
#define E1000_CTRL_SWDPIN0 0x00040000 /* SWDPIN 0 value */
#define E1000_CTRL_SWDPIN1 0x00080000 /* SWDPIN 1 value */
#define E1000_CTRL_ADVD3WUC 0x00100000 /* D3 WUC */
#define E1000_CTRL_EN_PHY_PWR_MGMT 0x00200000 /* PHY PM enable */
#define E1000_CTRL_SWDPIO0 0x00400000 /* SWDPIN 0 Input or output */
#define E1000_CTRL_RST 0x04000000 /* Global reset */
#define E1000_CTRL_RFCE 0x08000000 /* Receive Flow Control enable */
#define E1000_CTRL_TFCE 0x10000000 /* Transmit flow control enable */
#define E1000_CTRL_VME 0x40000000 /* IEEE VLAN mode enable */
#define E1000_CTRL_PHY_RST 0x80000000 /* PHY Reset */
#define E1000_PCS_LCTL_FORCE_FCTRL 0x80
#define E1000_PCS_LSTS_AN_COMPLETE 0x10000
/* Device Status */
#define E1000_STATUS_FD 0x00000001 /* Full duplex.0=half,1=full */
#define E1000_STATUS_LU 0x00000002 /* Link up.0=no,1=link */
#define E1000_STATUS_FUNC_MASK 0x0000000C /* PCI Function Mask */
#define E1000_STATUS_FUNC_SHIFT 2
#define E1000_STATUS_FUNC_1 0x00000004 /* Function 1 */
#define E1000_STATUS_TXOFF 0x00000010 /* transmission paused */
#define E1000_STATUS_SPEED_MASK 0x000000C0
#define E1000_STATUS_SPEED_10 0x00000000 /* Speed 10Mb/s */
#define E1000_STATUS_SPEED_100 0x00000040 /* Speed 100Mb/s */
#define E1000_STATUS_SPEED_1000 0x00000080 /* Speed 1000Mb/s */
#define E1000_STATUS_LAN_INIT_DONE 0x00000200 /* Lan Init Completion by NVM */
#define E1000_STATUS_PHYRA 0x00000400 /* PHY Reset Asserted */
#define E1000_STATUS_GIO_MASTER_ENABLE 0x00080000 /* Master Req status */
/* PCIm function state */
#define E1000_STATUS_PCIM_STATE 0x40000000
#define HALF_DUPLEX 1
#define FULL_DUPLEX 2
#define ADVERTISE_10_HALF 0x0001
#define ADVERTISE_10_FULL 0x0002
#define ADVERTISE_100_HALF 0x0004
#define ADVERTISE_100_FULL 0x0008
#define ADVERTISE_1000_HALF 0x0010 /* Not used, just FYI */
#define ADVERTISE_1000_FULL 0x0020
/* 1000/H is not supported, nor spec-compliant. */
#define E1000_ALL_SPEED_DUPLEX ( \
ADVERTISE_10_HALF | ADVERTISE_10_FULL | ADVERTISE_100_HALF | \
ADVERTISE_100_FULL | ADVERTISE_1000_FULL)
#define E1000_ALL_NOT_GIG ( \
ADVERTISE_10_HALF | ADVERTISE_10_FULL | ADVERTISE_100_HALF | \
ADVERTISE_100_FULL)
#define E1000_ALL_100_SPEED (ADVERTISE_100_HALF | ADVERTISE_100_FULL)
#define E1000_ALL_10_SPEED (ADVERTISE_10_HALF | ADVERTISE_10_FULL)
#define E1000_ALL_HALF_DUPLEX (ADVERTISE_10_HALF | ADVERTISE_100_HALF)
#define AUTONEG_ADVERTISE_SPEED_DEFAULT E1000_ALL_SPEED_DUPLEX
/* LED Control */
#define E1000_PHY_LED0_MODE_MASK 0x00000007
#define E1000_PHY_LED0_IVRT 0x00000008
#define E1000_PHY_LED0_MASK 0x0000001F
#define E1000_LEDCTL_LED0_MODE_MASK 0x0000000F
#define E1000_LEDCTL_LED0_MODE_SHIFT 0
#define E1000_LEDCTL_LED0_IVRT 0x00000040
#define E1000_LEDCTL_LED0_BLINK 0x00000080
#define E1000_LEDCTL_MODE_LINK_UP 0x2
#define E1000_LEDCTL_MODE_LED_ON 0xE
#define E1000_LEDCTL_MODE_LED_OFF 0xF
/* Transmit Descriptor bit definitions */
#define E1000_TXD_DTYP_D 0x00100000 /* Data Descriptor */
#define E1000_TXD_POPTS_IXSM 0x01 /* Insert IP checksum */
#define E1000_TXD_POPTS_TXSM 0x02 /* Insert TCP/UDP checksum */
#define E1000_TXD_CMD_EOP 0x01000000 /* End of Packet */
#define E1000_TXD_CMD_IFCS 0x02000000 /* Insert FCS (Ethernet CRC) */
#define E1000_TXD_CMD_IC 0x04000000 /* Insert Checksum */
#define E1000_TXD_CMD_RS 0x08000000 /* Report Status */
#define E1000_TXD_CMD_RPS 0x10000000 /* Report Packet Sent */
#define E1000_TXD_CMD_DEXT 0x20000000 /* Descriptor extension (0 = legacy) */
#define E1000_TXD_CMD_VLE 0x40000000 /* Add VLAN tag */
#define E1000_TXD_CMD_IDE 0x80000000 /* Enable Tidv register */
#define E1000_TXD_STAT_DD 0x00000001 /* Descriptor Done */
#define E1000_TXD_STAT_EC 0x00000002 /* Excess Collisions */
#define E1000_TXD_STAT_LC 0x00000004 /* Late Collisions */
#define E1000_TXD_STAT_TU 0x00000008 /* Transmit underrun */
#define E1000_TXD_CMD_TCP 0x01000000 /* TCP packet */
#define E1000_TXD_CMD_IP 0x02000000 /* IP packet */
#define E1000_TXD_CMD_TSE 0x04000000 /* TCP Seg enable */
#define E1000_TXD_STAT_TC 0x00000004 /* Tx Underrun */
#define E1000_TXD_EXTCMD_TSTAMP 0x00000010 /* IEEE1588 Timestamp packet */
/* Transmit Control */
#define E1000_TCTL_EN 0x00000002 /* enable Tx */
#define E1000_TCTL_PSP 0x00000008 /* pad short packets */
#define E1000_TCTL_CT 0x00000ff0 /* collision threshold */
#define E1000_TCTL_COLD 0x003ff000 /* collision distance */
#define E1000_TCTL_RTLC 0x01000000 /* Re-transmit on late collision */
#define E1000_TCTL_MULR 0x10000000 /* Multiple request support */
/* SerDes Control */
#define E1000_SCTL_DISABLE_SERDES_LOOPBACK 0x0400
#define E1000_SCTL_ENABLE_SERDES_LOOPBACK 0x0410
/* Receive Checksum Control */
#define E1000_RXCSUM_TUOFL 0x00000200 /* TCP / UDP checksum offload */
#define E1000_RXCSUM_IPPCSE 0x00001000 /* IP payload checksum enable */
#define E1000_RXCSUM_PCSD 0x00002000 /* packet checksum disabled */
/* Header split receive */
#define E1000_RFCTL_NFSW_DIS 0x00000040
#define E1000_RFCTL_NFSR_DIS 0x00000080
#define E1000_RFCTL_ACK_DIS 0x00001000
#define E1000_RFCTL_EXTEN 0x00008000
#define E1000_RFCTL_IPV6_EX_DIS 0x00010000
#define E1000_RFCTL_NEW_IPV6_EXT_DIS 0x00020000
/* Collision related configuration parameters */
#define E1000_COLLISION_THRESHOLD 15
#define E1000_CT_SHIFT 4
#define E1000_COLLISION_DISTANCE 63
#define E1000_COLD_SHIFT 12
/* Default values for the transmit IPG register */
#define DEFAULT_82543_TIPG_IPGT_COPPER 8
#define E1000_TIPG_IPGT_MASK 0x000003FF
#define DEFAULT_82543_TIPG_IPGR1 8
#define E1000_TIPG_IPGR1_SHIFT 10
#define DEFAULT_82543_TIPG_IPGR2 6
#define DEFAULT_80003ES2LAN_TIPG_IPGR2 7
#define E1000_TIPG_IPGR2_SHIFT 20
#define MAX_JUMBO_FRAME_SIZE 0x3F00
#define E1000_TX_PTR_GAP 0x1F
/* Extended Configuration Control and Size */
#define E1000_EXTCNF_CTRL_MDIO_SW_OWNERSHIP 0x00000020
#define E1000_EXTCNF_CTRL_LCD_WRITE_ENABLE 0x00000001
#define E1000_EXTCNF_CTRL_OEM_WRITE_ENABLE 0x00000008
#define E1000_EXTCNF_CTRL_SWFLAG 0x00000020
#define E1000_EXTCNF_CTRL_GATE_PHY_CFG 0x00000080
#define E1000_EXTCNF_SIZE_EXT_PCIE_LENGTH_MASK 0x00FF0000
#define E1000_EXTCNF_SIZE_EXT_PCIE_LENGTH_SHIFT 16
#define E1000_EXTCNF_CTRL_EXT_CNF_POINTER_MASK 0x0FFF0000
#define E1000_EXTCNF_CTRL_EXT_CNF_POINTER_SHIFT 16
#define E1000_PHY_CTRL_D0A_LPLU 0x00000002
#define E1000_PHY_CTRL_NOND0A_LPLU 0x00000004
#define E1000_PHY_CTRL_NOND0A_GBE_DISABLE 0x00000008
#define E1000_PHY_CTRL_GBE_DISABLE 0x00000040
#define E1000_KABGTXD_BGSQLBIAS 0x00050000
/* Low Power IDLE Control */
#define E1000_LPIC_LPIET_SHIFT 24 /* Low Power Idle Entry Time */
/* PBA constants */
#define E1000_PBA_8K 0x0008 /* 8KB */
#define E1000_PBA_16K 0x0010 /* 16KB */
#define E1000_PBA_RXA_MASK 0xFFFF
#define E1000_PBS_16K E1000_PBA_16K
/* Uncorrectable/correctable ECC Error counts and enable bits */
#define E1000_PBECCSTS_CORR_ERR_CNT_MASK 0x000000FF
#define E1000_PBECCSTS_UNCORR_ERR_CNT_MASK 0x0000FF00
#define E1000_PBECCSTS_UNCORR_ERR_CNT_SHIFT 8
#define E1000_PBECCSTS_ECC_ENABLE 0x00010000
#define IFS_MAX 80
#define IFS_MIN 40
#define IFS_RATIO 4
#define IFS_STEP 10
#define MIN_NUM_XMITS 1000
/* SW Semaphore Register */
#define E1000_SWSM_SMBI 0x00000001 /* Driver Semaphore bit */
#define E1000_SWSM_SWESMBI 0x00000002 /* FW Semaphore bit */
#define E1000_SWSM_DRV_LOAD 0x00000008 /* Driver Loaded Bit */
#define E1000_SWSM2_LOCK 0x00000002 /* Secondary driver semaphore bit */
/* Interrupt Cause Read */
#define E1000_ICR_TXDW 0x00000001 /* Transmit desc written back */
#define E1000_ICR_LSC 0x00000004 /* Link Status Change */
#define E1000_ICR_RXSEQ 0x00000008 /* Rx sequence error */
#define E1000_ICR_RXDMT0 0x00000010 /* Rx desc min. threshold (0) */
#define E1000_ICR_RXO 0x00000040 /* Receiver Overrun */
#define E1000_ICR_RXT0 0x00000080 /* Rx timer intr (ring 0) */
#define E1000_ICR_MDAC 0x00000200 /* MDIO Access Complete */
#define E1000_ICR_SRPD 0x00010000 /* Small Receive Packet Detected */
#define E1000_ICR_ACK 0x00020000 /* Receive ACK Frame Detected */
#define E1000_ICR_MNG 0x00040000 /* Manageability Event Detected */
#define E1000_ICR_ECCER 0x00400000 /* Uncorrectable ECC Error */
/* If this bit asserted, the driver should claim the interrupt */
#define E1000_ICR_INT_ASSERTED 0x80000000
#define E1000_ICR_RXQ0 0x00100000 /* Rx Queue 0 Interrupt */
#define E1000_ICR_RXQ1 0x00200000 /* Rx Queue 1 Interrupt */
#define E1000_ICR_TXQ0 0x00400000 /* Tx Queue 0 Interrupt */
#define E1000_ICR_TXQ1 0x00800000 /* Tx Queue 1 Interrupt */
#define E1000_ICR_OTHER 0x01000000 /* Other Interrupt */
/* PBA ECC Register */
#define E1000_PBA_ECC_COUNTER_MASK 0xFFF00000 /* ECC counter mask */
#define E1000_PBA_ECC_COUNTER_SHIFT 20 /* ECC counter shift value */
#define E1000_PBA_ECC_CORR_EN 0x00000001 /* ECC correction enable */
#define E1000_PBA_ECC_STAT_CLR 0x00000002 /* Clear ECC error counter */
#define E1000_PBA_ECC_INT_EN 0x00000004 /* Enable ICR bit 5 for ECC */
/* This defines the bits that are set in the Interrupt Mask
* Set/Read Register. Each bit is documented below:
* o RXT0 = Receiver Timer Interrupt (ring 0)
* o TXDW = Transmit Descriptor Written Back
* o RXDMT0 = Receive Descriptor Minimum Threshold hit (ring 0)
* o RXSEQ = Receive Sequence Error
* o LSC = Link Status Change
*/
#define IMS_ENABLE_MASK ( \
E1000_IMS_RXT0 | \
E1000_IMS_TXDW | \
E1000_IMS_RXDMT0 | \
E1000_IMS_RXSEQ | \
E1000_IMS_LSC)
/* These are all of the events related to the OTHER interrupt.
*/
#define IMS_OTHER_MASK ( \
E1000_IMS_LSC | \
E1000_IMS_RXO | \
E1000_IMS_MDAC | \
E1000_IMS_SRPD | \
E1000_IMS_ACK | \
E1000_IMS_MNG)
/* Interrupt Mask Set */
#define E1000_IMS_TXDW E1000_ICR_TXDW /* Transmit desc written back */
#define E1000_IMS_LSC E1000_ICR_LSC /* Link Status Change */
#define E1000_IMS_RXSEQ E1000_ICR_RXSEQ /* Rx sequence error */
#define E1000_IMS_RXDMT0 E1000_ICR_RXDMT0 /* Rx desc min. threshold */
#define E1000_IMS_RXO E1000_ICR_RXO /* Receiver Overrun */
#define E1000_IMS_RXT0 E1000_ICR_RXT0 /* Rx timer intr */
#define E1000_IMS_MDAC E1000_ICR_MDAC /* MDIO Access Complete */
#define E1000_IMS_SRPD E1000_ICR_SRPD /* Small Receive Packet */
#define E1000_IMS_ACK E1000_ICR_ACK /* Receive ACK Frame Detected */
#define E1000_IMS_MNG E1000_ICR_MNG /* Manageability Event */
#define E1000_IMS_ECCER E1000_ICR_ECCER /* Uncorrectable ECC Error */
#define E1000_IMS_RXQ0 E1000_ICR_RXQ0 /* Rx Queue 0 Interrupt */
#define E1000_IMS_RXQ1 E1000_ICR_RXQ1 /* Rx Queue 1 Interrupt */
#define E1000_IMS_TXQ0 E1000_ICR_TXQ0 /* Tx Queue 0 Interrupt */
#define E1000_IMS_TXQ1 E1000_ICR_TXQ1 /* Tx Queue 1 Interrupt */
#define E1000_IMS_OTHER E1000_ICR_OTHER /* Other Interrupt */
/* Interrupt Cause Set */
#define E1000_ICS_LSC E1000_ICR_LSC /* Link Status Change */
#define E1000_ICS_RXSEQ E1000_ICR_RXSEQ /* Rx sequence error */
#define E1000_ICS_RXDMT0 E1000_ICR_RXDMT0 /* Rx desc min. threshold */
#define E1000_ICS_OTHER E1000_ICR_OTHER /* Other Interrupt */
/* Transmit Descriptor Control */
#define E1000_TXDCTL_PTHRESH 0x0000003F /* TXDCTL Prefetch Threshold */
#define E1000_TXDCTL_HTHRESH 0x00003F00 /* TXDCTL Host Threshold */
#define E1000_TXDCTL_WTHRESH 0x003F0000 /* TXDCTL Writeback Threshold */
#define E1000_TXDCTL_GRAN 0x01000000 /* TXDCTL Granularity */
#define E1000_TXDCTL_FULL_TX_DESC_WB 0x01010000 /* GRAN=1, WTHRESH=1 */
#define E1000_TXDCTL_MAX_TX_DESC_PREFETCH 0x0100001F /* GRAN=1, PTHRESH=31 */
/* Enable the counting of desc. still to be processed. */
#define E1000_TXDCTL_COUNT_DESC 0x00400000
/* Flow Control Constants */
#define FLOW_CONTROL_ADDRESS_LOW 0x00C28001
#define FLOW_CONTROL_ADDRESS_HIGH 0x00000100
#define FLOW_CONTROL_TYPE 0x8808
/* 802.1q VLAN Packet Size */
#define E1000_VLAN_FILTER_TBL_SIZE 128 /* VLAN Filter Table (4096 bits) */
/* Receive Address
* Number of high/low register pairs in the RAR. The RAR (Receive Address
* Registers) holds the directed and multicast addresses that we monitor.
* Technically, we have 16 spots. However, we reserve one of these spots
* (RAR[15]) for our directed address used by controllers with
* manageability enabled, allowing us room for 15 multicast addresses.
*/
#define E1000_RAR_ENTRIES 15
#define E1000_RAH_AV 0x80000000 /* Receive descriptor valid */
#define E1000_RAL_MAC_ADDR_LEN 4
#define E1000_RAH_MAC_ADDR_LEN 2
/* Error Codes */
#define E1000_ERR_NVM 1
#define E1000_ERR_PHY 2
#define E1000_ERR_CONFIG 3
#define E1000_ERR_PARAM 4
#define E1000_ERR_MAC_INIT 5
#define E1000_ERR_PHY_TYPE 6
#define E1000_ERR_RESET 9
#define E1000_ERR_MASTER_REQUESTS_PENDING 10
#define E1000_ERR_HOST_INTERFACE_COMMAND 11
#define E1000_BLK_PHY_RESET 12
#define E1000_ERR_SWFW_SYNC 13
#define E1000_NOT_IMPLEMENTED 14
#define E1000_ERR_INVALID_ARGUMENT 16
#define E1000_ERR_NO_SPACE 17
#define E1000_ERR_NVM_PBA_SECTION 18
/* Loop limit on how long we wait for auto-negotiation to complete */
#define FIBER_LINK_UP_LIMIT 50
#define COPPER_LINK_UP_LIMIT 10
#define PHY_AUTO_NEG_LIMIT 45
#define PHY_FORCE_LIMIT 20
/* Number of 100 microseconds we wait for PCI Express master disable */
#define MASTER_DISABLE_TIMEOUT 800
/* Number of milliseconds we wait for PHY configuration done after MAC reset */
#define PHY_CFG_TIMEOUT 100
/* Number of 2 milliseconds we wait for acquiring MDIO ownership. */
#define MDIO_OWNERSHIP_TIMEOUT 10
/* Number of milliseconds for NVM auto read done after MAC reset. */
#define AUTO_READ_DONE_TIMEOUT 10
/* Flow Control */
#define E1000_FCRTH_RTH 0x0000FFF8 /* Mask Bits[15:3] for RTH */
#define E1000_FCRTL_RTL 0x0000FFF8 /* Mask Bits[15:3] for RTL */
#define E1000_FCRTL_XONE 0x80000000 /* Enable XON frame transmission */
/* Transmit Configuration Word */
#define E1000_TXCW_FD 0x00000020 /* TXCW full duplex */
#define E1000_TXCW_PAUSE 0x00000080 /* TXCW sym pause request */
#define E1000_TXCW_ASM_DIR 0x00000100 /* TXCW astm pause direction */
#define E1000_TXCW_PAUSE_MASK 0x00000180 /* TXCW pause request mask */
#define E1000_TXCW_ANE 0x80000000 /* Auto-neg enable */
/* Receive Configuration Word */
#define E1000_RXCW_CW 0x0000ffff /* RxConfigWord mask */
#define E1000_RXCW_IV 0x08000000 /* Receive config invalid */
#define E1000_RXCW_C 0x20000000 /* Receive config */
#define E1000_RXCW_SYNCH 0x40000000 /* Receive config synch */
/* HH Time Sync */
#define E1000_TSYNCTXCTL_MAX_ALLOWED_DLY_MASK 0x0000F000 /* max delay */
#define E1000_TSYNCTXCTL_SYNC_COMP 0x40000000 /* sync complete */
#define E1000_TSYNCTXCTL_START_SYNC 0x80000000 /* initiate sync */
#define E1000_TSYNCTXCTL_VALID 0x00000001 /* Tx timestamp valid */
#define E1000_TSYNCTXCTL_ENABLED 0x00000010 /* enable Tx timestamping */
#define E1000_TSYNCRXCTL_VALID 0x00000001 /* Rx timestamp valid */
#define E1000_TSYNCRXCTL_TYPE_MASK 0x0000000E /* Rx type mask */
#define E1000_TSYNCRXCTL_TYPE_L2_V2 0x00
#define E1000_TSYNCRXCTL_TYPE_L4_V1 0x02
#define E1000_TSYNCRXCTL_TYPE_L2_L4_V2 0x04
#define E1000_TSYNCRXCTL_TYPE_ALL 0x08
#define E1000_TSYNCRXCTL_TYPE_EVENT_V2 0x0A
#define E1000_TSYNCRXCTL_ENABLED 0x00000010 /* enable Rx timestamping */
#define E1000_TSYNCRXCTL_SYSCFI 0x00000020 /* Sys clock frequency */
#define E1000_RXMTRL_PTP_V1_SYNC_MESSAGE 0x00000000
#define E1000_RXMTRL_PTP_V1_DELAY_REQ_MESSAGE 0x00010000
#define E1000_RXMTRL_PTP_V2_SYNC_MESSAGE 0x00000000
#define E1000_RXMTRL_PTP_V2_DELAY_REQ_MESSAGE 0x01000000
#define E1000_TIMINCA_INCPERIOD_SHIFT 24
#define E1000_TIMINCA_INCVALUE_MASK 0x00FFFFFF
/* PCI Express Control */
#define E1000_GCR_RXD_NO_SNOOP 0x00000001
#define E1000_GCR_RXDSCW_NO_SNOOP 0x00000002
#define E1000_GCR_RXDSCR_NO_SNOOP 0x00000004
#define E1000_GCR_TXD_NO_SNOOP 0x00000008
#define E1000_GCR_TXDSCW_NO_SNOOP 0x00000010
#define E1000_GCR_TXDSCR_NO_SNOOP 0x00000020
#define PCIE_NO_SNOOP_ALL (E1000_GCR_RXD_NO_SNOOP | \
E1000_GCR_RXDSCW_NO_SNOOP | \
E1000_GCR_RXDSCR_NO_SNOOP | \
E1000_GCR_TXD_NO_SNOOP | \
E1000_GCR_TXDSCW_NO_SNOOP | \
E1000_GCR_TXDSCR_NO_SNOOP)
/* NVM Control */
#define E1000_EECD_SK 0x00000001 /* NVM Clock */
#define E1000_EECD_CS 0x00000002 /* NVM Chip Select */
#define E1000_EECD_DI 0x00000004 /* NVM Data In */
#define E1000_EECD_DO 0x00000008 /* NVM Data Out */
#define E1000_EECD_REQ 0x00000040 /* NVM Access Request */
#define E1000_EECD_GNT 0x00000080 /* NVM Access Grant */
#define E1000_EECD_PRES 0x00000100 /* NVM Present */
#define E1000_EECD_SIZE 0x00000200 /* NVM Size (0=64 word 1=256 word) */
/* NVM Addressing bits based on type (0-small, 1-large) */
#define E1000_EECD_ADDR_BITS 0x00000400
#define E1000_NVM_GRANT_ATTEMPTS 1000 /* NVM # attempts to gain grant */
#define E1000_EECD_AUTO_RD 0x00000200 /* NVM Auto Read done */
#define E1000_EECD_SIZE_EX_MASK 0x00007800 /* NVM Size */
#define E1000_EECD_SIZE_EX_SHIFT 11
#define E1000_EECD_FLUPD 0x00080000 /* Update FLASH */
#define E1000_EECD_AUPDEN 0x00100000 /* Enable Autonomous FLASH update */
#define E1000_EECD_SEC1VAL 0x00400000 /* Sector One Valid */
#define E1000_EECD_SEC1VAL_VALID_MASK (E1000_EECD_AUTO_RD | E1000_EECD_PRES)
#define E1000_NVM_RW_REG_DATA 16 /* Offset to data in NVM r/w regs */
#define E1000_NVM_RW_REG_DONE 2 /* Offset to READ/WRITE done bit */
#define E1000_NVM_RW_REG_START 1 /* Start operation */
#define E1000_NVM_RW_ADDR_SHIFT 2 /* Shift to the address bits */
#define E1000_NVM_POLL_WRITE 1 /* Flag for polling write complete */
#define E1000_NVM_POLL_READ 0 /* Flag for polling read complete */
#define E1000_FLASH_UPDATES 2000
/* NVM Word Offsets */
#define NVM_COMPAT 0x0003
#define NVM_ID_LED_SETTINGS 0x0004
#define NVM_FUTURE_INIT_WORD1 0x0019
#define NVM_COMPAT_VALID_CSUM 0x0001
#define NVM_FUTURE_INIT_WORD1_VALID_CSUM 0x0040
#define NVM_INIT_CONTROL2_REG 0x000F
#define NVM_INIT_CONTROL3_PORT_B 0x0014
#define NVM_INIT_3GIO_3 0x001A
#define NVM_INIT_CONTROL3_PORT_A 0x0024
#define NVM_CFG 0x0012
#define NVM_ALT_MAC_ADDR_PTR 0x0037
#define NVM_CHECKSUM_REG 0x003F
#define E1000_NVM_CFG_DONE_PORT_0 0x40000 /* MNG config cycle done */
#define E1000_NVM_CFG_DONE_PORT_1 0x80000 /* ...for second port */
/* Mask bits for fields in Word 0x0f of the NVM */
#define NVM_WORD0F_PAUSE_MASK 0x3000
#define NVM_WORD0F_PAUSE 0x1000
#define NVM_WORD0F_ASM_DIR 0x2000
/* Mask bits for fields in Word 0x1a of the NVM */
#define NVM_WORD1A_ASPM_MASK 0x000C
/* Mask bits for fields in Word 0x03 of the EEPROM */
#define NVM_COMPAT_LOM 0x0800
/* length of string needed to store PBA number */
#define E1000_PBANUM_LENGTH 11
/* For checksumming, the sum of all words in the NVM should equal 0xBABA. */
#define NVM_SUM 0xBABA
/* PBA (printed board assembly) number words */
#define NVM_PBA_OFFSET_0 8
#define NVM_PBA_OFFSET_1 9
#define NVM_PBA_PTR_GUARD 0xFAFA
#define NVM_WORD_SIZE_BASE_SHIFT 6
/* NVM Commands - SPI */
#define NVM_MAX_RETRY_SPI 5000 /* Max wait of 5ms, for RDY signal */
#define NVM_READ_OPCODE_SPI 0x03 /* NVM read opcode */
#define NVM_WRITE_OPCODE_SPI 0x02 /* NVM write opcode */
#define NVM_A8_OPCODE_SPI 0x08 /* opcode bit-3 = address bit-8 */
#define NVM_WREN_OPCODE_SPI 0x06 /* NVM set Write Enable latch */
#define NVM_RDSR_OPCODE_SPI 0x05 /* NVM read Status register */
/* SPI NVM Status Register */
#define NVM_STATUS_RDY_SPI 0x01
/* Word definitions for ID LED Settings */
#define ID_LED_RESERVED_0000 0x0000
#define ID_LED_RESERVED_FFFF 0xFFFF
#define ID_LED_DEFAULT ((ID_LED_OFF1_ON2 << 12) | \
(ID_LED_OFF1_OFF2 << 8) | \
(ID_LED_DEF1_DEF2 << 4) | \
(ID_LED_DEF1_DEF2))
#define ID_LED_DEF1_DEF2 0x1
#define ID_LED_DEF1_ON2 0x2
#define ID_LED_DEF1_OFF2 0x3
#define ID_LED_ON1_DEF2 0x4
#define ID_LED_ON1_ON2 0x5
#define ID_LED_ON1_OFF2 0x6
#define ID_LED_OFF1_DEF2 0x7
#define ID_LED_OFF1_ON2 0x8
#define ID_LED_OFF1_OFF2 0x9
#define IGP_ACTIVITY_LED_MASK 0xFFFFF0FF
#define IGP_ACTIVITY_LED_ENABLE 0x0300
#define IGP_LED3_MODE 0x07000000
/* PCI/PCI-X/PCI-EX Config space */
#define PCI_HEADER_TYPE_REGISTER 0x0E
#define PCIE_LINK_STATUS 0x12
#define PCI_HEADER_TYPE_MULTIFUNC 0x80
#define PCIE_LINK_WIDTH_MASK 0x3F0
#define PCIE_LINK_WIDTH_SHIFT 4
#define PHY_REVISION_MASK 0xFFFFFFF0
#define MAX_PHY_REG_ADDRESS 0x1F /* 5 bit address bus (0-0x1F) */
#define MAX_PHY_MULTI_PAGE_REG 0xF
/* Bit definitions for valid PHY IDs.
* I = Integrated
* E = External
*/
#define M88E1000_E_PHY_ID 0x01410C50
#define M88E1000_I_PHY_ID 0x01410C30
#define M88E1011_I_PHY_ID 0x01410C20
#define IGP01E1000_I_PHY_ID 0x02A80380
#define M88E1111_I_PHY_ID 0x01410CC0
#define GG82563_E_PHY_ID 0x01410CA0
#define IGP03E1000_E_PHY_ID 0x02A80390
#define IFE_E_PHY_ID 0x02A80330
#define IFE_PLUS_E_PHY_ID 0x02A80320
#define IFE_C_E_PHY_ID 0x02A80310
#define BME1000_E_PHY_ID 0x01410CB0
#define BME1000_E_PHY_ID_R2 0x01410CB1
#define I82577_E_PHY_ID 0x01540050
#define I82578_E_PHY_ID 0x004DD040
#define I82579_E_PHY_ID 0x01540090
#define I217_E_PHY_ID 0x015400A0
/* M88E1000 Specific Registers */
#define M88E1000_PHY_SPEC_CTRL 0x10 /* PHY Specific Control Register */
#define M88E1000_PHY_SPEC_STATUS 0x11 /* PHY Specific Status Register */
#define M88E1000_EXT_PHY_SPEC_CTRL 0x14 /* Extended PHY Specific Control */
#define M88E1000_PHY_PAGE_SELECT 0x1D /* Reg 29 for page number setting */
#define M88E1000_PHY_GEN_CONTROL 0x1E /* Its meaning depends on reg 29 */
/* M88E1000 PHY Specific Control Register */
#define M88E1000_PSCR_POLARITY_REVERSAL 0x0002 /* 1=Polarity Reversal enabled */
#define M88E1000_PSCR_MDI_MANUAL_MODE 0x0000 /* MDI Crossover Mode bits 6:5 */
/* Manual MDI configuration */
#define M88E1000_PSCR_MDIX_MANUAL_MODE 0x0020 /* Manual MDIX configuration */
/* 1000BASE-T: Auto crossover, 100BASE-TX/10BASE-T: MDI Mode */
#define M88E1000_PSCR_AUTO_X_1000T 0x0040
/* Auto crossover enabled all speeds */
#define M88E1000_PSCR_AUTO_X_MODE 0x0060
#define M88E1000_PSCR_ASSERT_CRS_ON_TX 0x0800 /* 1=Assert CRS on Transmit */
/* M88E1000 PHY Specific Status Register */
#define M88E1000_PSSR_REV_POLARITY 0x0002 /* 1=Polarity reversed */
#define M88E1000_PSSR_DOWNSHIFT 0x0020 /* 1=Downshifted */
#define M88E1000_PSSR_MDIX 0x0040 /* 1=MDIX; 0=MDI */
/* 0=<50M; 1=50-80M; 2=80-110M; 3=110-140M; 4=>140M */
#define M88E1000_PSSR_CABLE_LENGTH 0x0380
#define M88E1000_PSSR_SPEED 0xC000 /* Speed, bits 14:15 */
#define M88E1000_PSSR_1000MBS 0x8000 /* 10=1000Mbs */
#define M88E1000_PSSR_CABLE_LENGTH_SHIFT 7
/* Number of times we will attempt to autonegotiate before downshifting if we
* are the master
*/
#define M88E1000_EPSCR_MASTER_DOWNSHIFT_MASK 0x0C00
#define M88E1000_EPSCR_MASTER_DOWNSHIFT_1X 0x0000
/* Number of times we will attempt to autonegotiate before downshifting if we
* are the slave
*/
#define M88E1000_EPSCR_SLAVE_DOWNSHIFT_MASK 0x0300
#define M88E1000_EPSCR_SLAVE_DOWNSHIFT_1X 0x0100
#define M88E1000_EPSCR_TX_CLK_25 0x0070 /* 25 MHz TX_CLK */
/* M88EC018 Rev 2 specific DownShift settings */
#define M88EC018_EPSCR_DOWNSHIFT_COUNTER_MASK 0x0E00
#define M88EC018_EPSCR_DOWNSHIFT_COUNTER_5X 0x0800
#define I82578_EPSCR_DOWNSHIFT_ENABLE 0x0020
#define I82578_EPSCR_DOWNSHIFT_COUNTER_MASK 0x001C
/* BME1000 PHY Specific Control Register */
#define BME1000_PSCR_ENABLE_DOWNSHIFT 0x0800 /* 1 = enable downshift */
/* Bits...
* 15-5: page
* 4-0: register offset
*/
#define GG82563_PAGE_SHIFT 5
#define GG82563_REG(page, reg) \
(((page) << GG82563_PAGE_SHIFT) | ((reg) & MAX_PHY_REG_ADDRESS))
#define GG82563_MIN_ALT_REG 30
/* GG82563 Specific Registers */
#define GG82563_PHY_SPEC_CTRL \
GG82563_REG(0, 16) /* PHY Specific Control */
#define GG82563_PHY_PAGE_SELECT \
GG82563_REG(0, 22) /* Page Select */
#define GG82563_PHY_SPEC_CTRL_2 \
GG82563_REG(0, 26) /* PHY Specific Control 2 */
#define GG82563_PHY_PAGE_SELECT_ALT \
GG82563_REG(0, 29) /* Alternate Page Select */
#define GG82563_PHY_MAC_SPEC_CTRL \
GG82563_REG(2, 21) /* MAC Specific Control Register */
#define GG82563_PHY_DSP_DISTANCE \
GG82563_REG(5, 26) /* DSP Distance */
/* Page 193 - Port Control Registers */
#define GG82563_PHY_KMRN_MODE_CTRL \
GG82563_REG(193, 16) /* Kumeran Mode Control */
#define GG82563_PHY_PWR_MGMT_CTRL \
GG82563_REG(193, 20) /* Power Management Control */
/* Page 194 - KMRN Registers */
#define GG82563_PHY_INBAND_CTRL \
GG82563_REG(194, 18) /* Inband Control */
/* MDI Control */
#define E1000_MDIC_REG_MASK 0x001F0000
#define E1000_MDIC_REG_SHIFT 16
#define E1000_MDIC_PHY_SHIFT 21
#define E1000_MDIC_OP_WRITE 0x04000000
#define E1000_MDIC_OP_READ 0x08000000
#define E1000_MDIC_READY 0x10000000
#define E1000_MDIC_ERROR 0x40000000
/* SerDes Control */
#define E1000_GEN_POLL_TIMEOUT 640
#endif /* _E1000_DEFINES_H_ */

View File

@ -0,0 +1,811 @@
/* SPDX-License-Identifier: GPL-2.0 */
/* Copyright(c) 1999 - 2018 Intel Corporation. */
#ifndef _E1000_DEFINES_H_
#define _E1000_DEFINES_H_
/* Number of Transmit and Receive Descriptors must be a multiple of 8 */
#define REQ_TX_DESCRIPTOR_MULTIPLE 8
#define REQ_RX_DESCRIPTOR_MULTIPLE 8
/* Definitions for power management and wakeup registers */
/* Wake Up Control */
#define E1000_WUC_APME 0x00000001 /* APM Enable */
#define E1000_WUC_PME_EN 0x00000002 /* PME Enable */
#define E1000_WUC_PME_STATUS 0x00000004 /* PME Status */
#define E1000_WUC_APMPME 0x00000008 /* Assert PME on APM Wakeup */
#define E1000_WUC_PHY_WAKE 0x00000100 /* if PHY supports wakeup */
/* Wake Up Filter Control */
#define E1000_WUFC_LNKC 0x00000001 /* Link Status Change Wakeup Enable */
#define E1000_WUFC_MAG 0x00000002 /* Magic Packet Wakeup Enable */
#define E1000_WUFC_EX 0x00000004 /* Directed Exact Wakeup Enable */
#define E1000_WUFC_MC 0x00000008 /* Directed Multicast Wakeup Enable */
#define E1000_WUFC_BC 0x00000010 /* Broadcast Wakeup Enable */
#define E1000_WUFC_ARP 0x00000020 /* ARP Request Packet Wakeup Enable */
/* Wake Up Status */
#define E1000_WUS_LNKC E1000_WUFC_LNKC
#define E1000_WUS_MAG E1000_WUFC_MAG
#define E1000_WUS_EX E1000_WUFC_EX
#define E1000_WUS_MC E1000_WUFC_MC
#define E1000_WUS_BC E1000_WUFC_BC
/* Extended Device Control */
#define E1000_CTRL_EXT_LPCD 0x00000004 /* LCD Power Cycle Done */
#define E1000_CTRL_EXT_SDP3_DATA 0x00000080 /* Value of SW Definable Pin 3 */
#define E1000_CTRL_EXT_FORCE_SMBUS 0x00000800 /* Force SMBus mode */
#define E1000_CTRL_EXT_EE_RST 0x00002000 /* Reinitialize from EEPROM */
#define E1000_CTRL_EXT_SPD_BYPS 0x00008000 /* Speed Select Bypass */
#define E1000_CTRL_EXT_RO_DIS 0x00020000 /* Relaxed Ordering disable */
#define E1000_CTRL_EXT_DMA_DYN_CLK_EN 0x00080000 /* DMA Dynamic Clock Gating */
#define E1000_CTRL_EXT_LINK_MODE_MASK 0x00C00000
#define E1000_CTRL_EXT_LINK_MODE_PCIE_SERDES 0x00C00000
#define E1000_CTRL_EXT_EIAME 0x01000000
#define E1000_CTRL_EXT_DRV_LOAD 0x10000000 /* Driver loaded bit for FW */
#define E1000_CTRL_EXT_IAME 0x08000000 /* Int ACK Auto-mask */
#define E1000_CTRL_EXT_PBA_CLR 0x80000000 /* PBA Clear */
#define E1000_CTRL_EXT_LSECCK 0x00001000
#define E1000_CTRL_EXT_PHYPDEN 0x00100000
/* Receive Descriptor bit definitions */
#define E1000_RXD_STAT_DD 0x01 /* Descriptor Done */
#define E1000_RXD_STAT_EOP 0x02 /* End of Packet */
#define E1000_RXD_STAT_IXSM 0x04 /* Ignore checksum */
#define E1000_RXD_STAT_VP 0x08 /* IEEE VLAN Packet */
#define E1000_RXD_STAT_UDPCS 0x10 /* UDP xsum calculated */
#define E1000_RXD_STAT_TCPCS 0x20 /* TCP xsum calculated */
#define E1000_RXD_ERR_CE 0x01 /* CRC Error */
#define E1000_RXD_ERR_SE 0x02 /* Symbol Error */
#define E1000_RXD_ERR_SEQ 0x04 /* Sequence Error */
#define E1000_RXD_ERR_CXE 0x10 /* Carrier Extension Error */
#define E1000_RXD_ERR_TCPE 0x20 /* TCP/UDP Checksum Error */
#define E1000_RXD_ERR_IPE 0x40 /* IP Checksum Error */
#define E1000_RXD_ERR_RXE 0x80 /* Rx Data Error */
#define E1000_RXD_SPC_VLAN_MASK 0x0FFF /* VLAN ID is in lower 12 bits */
#define E1000_RXDEXT_STATERR_TST 0x00000100 /* Time Stamp taken */
#define E1000_RXDEXT_STATERR_CE 0x01000000
#define E1000_RXDEXT_STATERR_SE 0x02000000
#define E1000_RXDEXT_STATERR_SEQ 0x04000000
#define E1000_RXDEXT_STATERR_CXE 0x10000000
#define E1000_RXDEXT_STATERR_RXE 0x80000000
/* mask to determine if packets should be dropped due to frame errors */
#define E1000_RXD_ERR_FRAME_ERR_MASK ( \
E1000_RXD_ERR_CE | \
E1000_RXD_ERR_SE | \
E1000_RXD_ERR_SEQ | \
E1000_RXD_ERR_CXE | \
E1000_RXD_ERR_RXE)
/* Same mask, but for extended and packet split descriptors */
#define E1000_RXDEXT_ERR_FRAME_ERR_MASK ( \
E1000_RXDEXT_STATERR_CE | \
E1000_RXDEXT_STATERR_SE | \
E1000_RXDEXT_STATERR_SEQ | \
E1000_RXDEXT_STATERR_CXE | \
E1000_RXDEXT_STATERR_RXE)
#define E1000_MRQC_RSS_FIELD_MASK 0xFFFF0000
#define E1000_MRQC_RSS_FIELD_IPV4_TCP 0x00010000
#define E1000_MRQC_RSS_FIELD_IPV4 0x00020000
#define E1000_MRQC_RSS_FIELD_IPV6_TCP_EX 0x00040000
#define E1000_MRQC_RSS_FIELD_IPV6 0x00100000
#define E1000_MRQC_RSS_FIELD_IPV6_TCP 0x00200000
#define E1000_RXDPS_HDRSTAT_HDRSP 0x00008000
/* Management Control */
#define E1000_MANC_SMBUS_EN 0x00000001 /* SMBus Enabled - RO */
#define E1000_MANC_ASF_EN 0x00000002 /* ASF Enabled - RO */
#define E1000_MANC_ARP_EN 0x00002000 /* Enable ARP Request Filtering */
#define E1000_MANC_RCV_TCO_EN 0x00020000 /* Receive TCO Packets Enabled */
#define E1000_MANC_BLK_PHY_RST_ON_IDE 0x00040000 /* Block phy resets */
/* Enable MAC address filtering */
#define E1000_MANC_EN_MAC_ADDR_FILTER 0x00100000
/* Enable MNG packets to host memory */
#define E1000_MANC_EN_MNG2HOST 0x00200000
#define E1000_MANC2H_PORT_623 0x00000020 /* Port 0x26f */
#define E1000_MANC2H_PORT_664 0x00000040 /* Port 0x298 */
#define E1000_MDEF_PORT_623 0x00000800 /* Port 0x26f */
#define E1000_MDEF_PORT_664 0x00000400 /* Port 0x298 */
/* Receive Control */
#define E1000_RCTL_EN 0x00000002 /* enable */
#define E1000_RCTL_SBP 0x00000004 /* store bad packet */
#define E1000_RCTL_UPE 0x00000008 /* unicast promiscuous enable */
#define E1000_RCTL_MPE 0x00000010 /* multicast promiscuous enab */
#define E1000_RCTL_LPE 0x00000020 /* long packet enable */
#define E1000_RCTL_LBM_NO 0x00000000 /* no loopback mode */
#define E1000_RCTL_LBM_MAC 0x00000040 /* MAC loopback mode */
#define E1000_RCTL_LBM_TCVR 0x000000C0 /* tcvr loopback mode */
#define E1000_RCTL_DTYP_PS 0x00000400 /* Packet Split descriptor */
#define E1000_RCTL_RDMTS_HALF 0x00000000 /* Rx desc min threshold size */
#define E1000_RCTL_RDMTS_HEX 0x00010000
#define E1000_RCTL_MO_SHIFT 12 /* multicast offset shift */
#define E1000_RCTL_MO_3 0x00003000 /* multicast offset 15:4 */
#define E1000_RCTL_BAM 0x00008000 /* broadcast enable */
/* these buffer sizes are valid if E1000_RCTL_BSEX is 0 */
#define E1000_RCTL_SZ_2048 0x00000000 /* Rx buffer size 2048 */
#define E1000_RCTL_SZ_1024 0x00010000 /* Rx buffer size 1024 */
#define E1000_RCTL_SZ_512 0x00020000 /* Rx buffer size 512 */
#define E1000_RCTL_SZ_256 0x00030000 /* Rx buffer size 256 */
/* these buffer sizes are valid if E1000_RCTL_BSEX is 1 */
#define E1000_RCTL_SZ_16384 0x00010000 /* Rx buffer size 16384 */
#define E1000_RCTL_SZ_8192 0x00020000 /* Rx buffer size 8192 */
#define E1000_RCTL_SZ_4096 0x00030000 /* Rx buffer size 4096 */
#define E1000_RCTL_VFE 0x00040000 /* vlan filter enable */
#define E1000_RCTL_CFIEN 0x00080000 /* canonical form enable */
#define E1000_RCTL_CFI 0x00100000 /* canonical form indicator */
#define E1000_RCTL_DPF 0x00400000 /* Discard Pause Frames */
#define E1000_RCTL_PMCF 0x00800000 /* pass MAC control frames */
#define E1000_RCTL_BSEX 0x02000000 /* Buffer size extension */
#define E1000_RCTL_SECRC 0x04000000 /* Strip Ethernet CRC */
/* Use byte values for the following shift parameters
* Usage:
* psrctl |= (((ROUNDUP(value0, 128) >> E1000_PSRCTL_BSIZE0_SHIFT) &
* E1000_PSRCTL_BSIZE0_MASK) |
* ((ROUNDUP(value1, 1024) >> E1000_PSRCTL_BSIZE1_SHIFT) &
* E1000_PSRCTL_BSIZE1_MASK) |
* ((ROUNDUP(value2, 1024) << E1000_PSRCTL_BSIZE2_SHIFT) &
* E1000_PSRCTL_BSIZE2_MASK) |
* ((ROUNDUP(value3, 1024) << E1000_PSRCTL_BSIZE3_SHIFT) |;
* E1000_PSRCTL_BSIZE3_MASK))
* where value0 = [128..16256], default=256
* value1 = [1024..64512], default=4096
* value2 = [0..64512], default=4096
* value3 = [0..64512], default=0
*/
#define E1000_PSRCTL_BSIZE0_MASK 0x0000007F
#define E1000_PSRCTL_BSIZE1_MASK 0x00003F00
#define E1000_PSRCTL_BSIZE2_MASK 0x003F0000
#define E1000_PSRCTL_BSIZE3_MASK 0x3F000000
#define E1000_PSRCTL_BSIZE0_SHIFT 7 /* Shift _right_ 7 */
#define E1000_PSRCTL_BSIZE1_SHIFT 2 /* Shift _right_ 2 */
#define E1000_PSRCTL_BSIZE2_SHIFT 6 /* Shift _left_ 6 */
#define E1000_PSRCTL_BSIZE3_SHIFT 14 /* Shift _left_ 14 */
/* SWFW_SYNC Definitions */
#define E1000_SWFW_EEP_SM 0x1
#define E1000_SWFW_PHY0_SM 0x2
#define E1000_SWFW_PHY1_SM 0x4
#define E1000_SWFW_CSR_SM 0x8
/* Device Control */
#define E1000_CTRL_FD 0x00000001 /* Full duplex.0=half; 1=full */
#define E1000_CTRL_GIO_MASTER_DISABLE 0x00000004 /*Blocks new Master requests */
#define E1000_CTRL_LRST 0x00000008 /* Link reset. 0=normal,1=reset */
#define E1000_CTRL_ASDE 0x00000020 /* Auto-speed detect enable */
#define E1000_CTRL_SLU 0x00000040 /* Set link up (Force Link) */
#define E1000_CTRL_ILOS 0x00000080 /* Invert Loss-Of Signal */
#define E1000_CTRL_SPD_SEL 0x00000300 /* Speed Select Mask */
#define E1000_CTRL_SPD_10 0x00000000 /* Force 10Mb */
#define E1000_CTRL_SPD_100 0x00000100 /* Force 100Mb */
#define E1000_CTRL_SPD_1000 0x00000200 /* Force 1Gb */
#define E1000_CTRL_FRCSPD 0x00000800 /* Force Speed */
#define E1000_CTRL_FRCDPX 0x00001000 /* Force Duplex */
#define E1000_CTRL_LANPHYPC_OVERRIDE 0x00010000 /* SW control of LANPHYPC */
#define E1000_CTRL_LANPHYPC_VALUE 0x00020000 /* SW value of LANPHYPC */
#define E1000_CTRL_MEHE 0x00080000 /* Memory Error Handling Enable */
#define E1000_CTRL_SWDPIN0 0x00040000 /* SWDPIN 0 value */
#define E1000_CTRL_SWDPIN1 0x00080000 /* SWDPIN 1 value */
#define E1000_CTRL_ADVD3WUC 0x00100000 /* D3 WUC */
#define E1000_CTRL_EN_PHY_PWR_MGMT 0x00200000 /* PHY PM enable */
#define E1000_CTRL_SWDPIO0 0x00400000 /* SWDPIN 0 Input or output */
#define E1000_CTRL_RST 0x04000000 /* Global reset */
#define E1000_CTRL_RFCE 0x08000000 /* Receive Flow Control enable */
#define E1000_CTRL_TFCE 0x10000000 /* Transmit flow control enable */
#define E1000_CTRL_VME 0x40000000 /* IEEE VLAN mode enable */
#define E1000_CTRL_PHY_RST 0x80000000 /* PHY Reset */
#define E1000_PCS_LCTL_FORCE_FCTRL 0x80
#define E1000_PCS_LSTS_AN_COMPLETE 0x10000
/* Device Status */
#define E1000_STATUS_FD 0x00000001 /* Full duplex.0=half,1=full */
#define E1000_STATUS_LU 0x00000002 /* Link up.0=no,1=link */
#define E1000_STATUS_FUNC_MASK 0x0000000C /* PCI Function Mask */
#define E1000_STATUS_FUNC_SHIFT 2
#define E1000_STATUS_FUNC_1 0x00000004 /* Function 1 */
#define E1000_STATUS_TXOFF 0x00000010 /* transmission paused */
#define E1000_STATUS_SPEED_MASK 0x000000C0
#define E1000_STATUS_SPEED_10 0x00000000 /* Speed 10Mb/s */
#define E1000_STATUS_SPEED_100 0x00000040 /* Speed 100Mb/s */
#define E1000_STATUS_SPEED_1000 0x00000080 /* Speed 1000Mb/s */
#define E1000_STATUS_LAN_INIT_DONE 0x00000200 /* Lan Init Completion by NVM */
#define E1000_STATUS_PHYRA 0x00000400 /* PHY Reset Asserted */
#define E1000_STATUS_GIO_MASTER_ENABLE 0x00080000 /* Master Req status */
/* PCIm function state */
#define E1000_STATUS_PCIM_STATE 0x40000000
#define HALF_DUPLEX 1
#define FULL_DUPLEX 2
#define ADVERTISE_10_HALF 0x0001
#define ADVERTISE_10_FULL 0x0002
#define ADVERTISE_100_HALF 0x0004
#define ADVERTISE_100_FULL 0x0008
#define ADVERTISE_1000_HALF 0x0010 /* Not used, just FYI */
#define ADVERTISE_1000_FULL 0x0020
/* 1000/H is not supported, nor spec-compliant. */
#define E1000_ALL_SPEED_DUPLEX ( \
ADVERTISE_10_HALF | ADVERTISE_10_FULL | ADVERTISE_100_HALF | \
ADVERTISE_100_FULL | ADVERTISE_1000_FULL)
#define E1000_ALL_NOT_GIG ( \
ADVERTISE_10_HALF | ADVERTISE_10_FULL | ADVERTISE_100_HALF | \
ADVERTISE_100_FULL)
#define E1000_ALL_100_SPEED (ADVERTISE_100_HALF | ADVERTISE_100_FULL)
#define E1000_ALL_10_SPEED (ADVERTISE_10_HALF | ADVERTISE_10_FULL)
#define E1000_ALL_HALF_DUPLEX (ADVERTISE_10_HALF | ADVERTISE_100_HALF)
#define AUTONEG_ADVERTISE_SPEED_DEFAULT E1000_ALL_SPEED_DUPLEX
/* LED Control */
#define E1000_PHY_LED0_MODE_MASK 0x00000007
#define E1000_PHY_LED0_IVRT 0x00000008
#define E1000_PHY_LED0_MASK 0x0000001F
#define E1000_LEDCTL_LED0_MODE_MASK 0x0000000F
#define E1000_LEDCTL_LED0_MODE_SHIFT 0
#define E1000_LEDCTL_LED0_IVRT 0x00000040
#define E1000_LEDCTL_LED0_BLINK 0x00000080
#define E1000_LEDCTL_MODE_LINK_UP 0x2
#define E1000_LEDCTL_MODE_LED_ON 0xE
#define E1000_LEDCTL_MODE_LED_OFF 0xF
/* Transmit Descriptor bit definitions */
#define E1000_TXD_DTYP_D 0x00100000 /* Data Descriptor */
#define E1000_TXD_POPTS_IXSM 0x01 /* Insert IP checksum */
#define E1000_TXD_POPTS_TXSM 0x02 /* Insert TCP/UDP checksum */
#define E1000_TXD_CMD_EOP 0x01000000 /* End of Packet */
#define E1000_TXD_CMD_IFCS 0x02000000 /* Insert FCS (Ethernet CRC) */
#define E1000_TXD_CMD_IC 0x04000000 /* Insert Checksum */
#define E1000_TXD_CMD_RS 0x08000000 /* Report Status */
#define E1000_TXD_CMD_RPS 0x10000000 /* Report Packet Sent */
#define E1000_TXD_CMD_DEXT 0x20000000 /* Descriptor extension (0 = legacy) */
#define E1000_TXD_CMD_VLE 0x40000000 /* Add VLAN tag */
#define E1000_TXD_CMD_IDE 0x80000000 /* Enable Tidv register */
#define E1000_TXD_STAT_DD 0x00000001 /* Descriptor Done */
#define E1000_TXD_STAT_EC 0x00000002 /* Excess Collisions */
#define E1000_TXD_STAT_LC 0x00000004 /* Late Collisions */
#define E1000_TXD_STAT_TU 0x00000008 /* Transmit underrun */
#define E1000_TXD_CMD_TCP 0x01000000 /* TCP packet */
#define E1000_TXD_CMD_IP 0x02000000 /* IP packet */
#define E1000_TXD_CMD_TSE 0x04000000 /* TCP Seg enable */
#define E1000_TXD_STAT_TC 0x00000004 /* Tx Underrun */
#define E1000_TXD_EXTCMD_TSTAMP 0x00000010 /* IEEE1588 Timestamp packet */
/* Transmit Control */
#define E1000_TCTL_EN 0x00000002 /* enable Tx */
#define E1000_TCTL_PSP 0x00000008 /* pad short packets */
#define E1000_TCTL_CT 0x00000ff0 /* collision threshold */
#define E1000_TCTL_COLD 0x003ff000 /* collision distance */
#define E1000_TCTL_RTLC 0x01000000 /* Re-transmit on late collision */
#define E1000_TCTL_MULR 0x10000000 /* Multiple request support */
/* SerDes Control */
#define E1000_SCTL_DISABLE_SERDES_LOOPBACK 0x0400
#define E1000_SCTL_ENABLE_SERDES_LOOPBACK 0x0410
/* Receive Checksum Control */
#define E1000_RXCSUM_TUOFL 0x00000200 /* TCP / UDP checksum offload */
#define E1000_RXCSUM_IPPCSE 0x00001000 /* IP payload checksum enable */
#define E1000_RXCSUM_PCSD 0x00002000 /* packet checksum disabled */
/* Header split receive */
#define E1000_RFCTL_NFSW_DIS 0x00000040
#define E1000_RFCTL_NFSR_DIS 0x00000080
#define E1000_RFCTL_ACK_DIS 0x00001000
#define E1000_RFCTL_EXTEN 0x00008000
#define E1000_RFCTL_IPV6_EX_DIS 0x00010000
#define E1000_RFCTL_NEW_IPV6_EXT_DIS 0x00020000
/* Collision related configuration parameters */
#define E1000_COLLISION_THRESHOLD 15
#define E1000_CT_SHIFT 4
#define E1000_COLLISION_DISTANCE 63
#define E1000_COLD_SHIFT 12
/* Default values for the transmit IPG register */
#define DEFAULT_82543_TIPG_IPGT_COPPER 8
#define E1000_TIPG_IPGT_MASK 0x000003FF
#define DEFAULT_82543_TIPG_IPGR1 8
#define E1000_TIPG_IPGR1_SHIFT 10
#define DEFAULT_82543_TIPG_IPGR2 6
#define DEFAULT_80003ES2LAN_TIPG_IPGR2 7
#define E1000_TIPG_IPGR2_SHIFT 20
#define MAX_JUMBO_FRAME_SIZE 0x3F00
#define E1000_TX_PTR_GAP 0x1F
/* Extended Configuration Control and Size */
#define E1000_EXTCNF_CTRL_MDIO_SW_OWNERSHIP 0x00000020
#define E1000_EXTCNF_CTRL_LCD_WRITE_ENABLE 0x00000001
#define E1000_EXTCNF_CTRL_OEM_WRITE_ENABLE 0x00000008
#define E1000_EXTCNF_CTRL_SWFLAG 0x00000020
#define E1000_EXTCNF_CTRL_GATE_PHY_CFG 0x00000080
#define E1000_EXTCNF_SIZE_EXT_PCIE_LENGTH_MASK 0x00FF0000
#define E1000_EXTCNF_SIZE_EXT_PCIE_LENGTH_SHIFT 16
#define E1000_EXTCNF_CTRL_EXT_CNF_POINTER_MASK 0x0FFF0000
#define E1000_EXTCNF_CTRL_EXT_CNF_POINTER_SHIFT 16
#define E1000_PHY_CTRL_D0A_LPLU 0x00000002
#define E1000_PHY_CTRL_NOND0A_LPLU 0x00000004
#define E1000_PHY_CTRL_NOND0A_GBE_DISABLE 0x00000008
#define E1000_PHY_CTRL_GBE_DISABLE 0x00000040
#define E1000_KABGTXD_BGSQLBIAS 0x00050000
/* Low Power IDLE Control */
#define E1000_LPIC_LPIET_SHIFT 24 /* Low Power Idle Entry Time */
/* PBA constants */
#define E1000_PBA_8K 0x0008 /* 8KB */
#define E1000_PBA_16K 0x0010 /* 16KB */
#define E1000_PBA_RXA_MASK 0xFFFF
#define E1000_PBS_16K E1000_PBA_16K
/* Uncorrectable/correctable ECC Error counts and enable bits */
#define E1000_PBECCSTS_CORR_ERR_CNT_MASK 0x000000FF
#define E1000_PBECCSTS_UNCORR_ERR_CNT_MASK 0x0000FF00
#define E1000_PBECCSTS_UNCORR_ERR_CNT_SHIFT 8
#define E1000_PBECCSTS_ECC_ENABLE 0x00010000
#define IFS_MAX 80
#define IFS_MIN 40
#define IFS_RATIO 4
#define IFS_STEP 10
#define MIN_NUM_XMITS 1000
/* SW Semaphore Register */
#define E1000_SWSM_SMBI 0x00000001 /* Driver Semaphore bit */
#define E1000_SWSM_SWESMBI 0x00000002 /* FW Semaphore bit */
#define E1000_SWSM_DRV_LOAD 0x00000008 /* Driver Loaded Bit */
#define E1000_SWSM2_LOCK 0x00000002 /* Secondary driver semaphore bit */
/* Interrupt Cause Read */
#define E1000_ICR_TXDW 0x00000001 /* Transmit desc written back */
#define E1000_ICR_LSC 0x00000004 /* Link Status Change */
#define E1000_ICR_RXSEQ 0x00000008 /* Rx sequence error */
#define E1000_ICR_RXDMT0 0x00000010 /* Rx desc min. threshold (0) */
#define E1000_ICR_RXO 0x00000040 /* Receiver Overrun */
#define E1000_ICR_RXT0 0x00000080 /* Rx timer intr (ring 0) */
#define E1000_ICR_MDAC 0x00000200 /* MDIO Access Complete */
#define E1000_ICR_SRPD 0x00010000 /* Small Receive Packet Detected */
#define E1000_ICR_ACK 0x00020000 /* Receive ACK Frame Detected */
#define E1000_ICR_MNG 0x00040000 /* Manageability Event Detected */
#define E1000_ICR_ECCER 0x00400000 /* Uncorrectable ECC Error */
/* If this bit asserted, the driver should claim the interrupt */
#define E1000_ICR_INT_ASSERTED 0x80000000
#define E1000_ICR_RXQ0 0x00100000 /* Rx Queue 0 Interrupt */
#define E1000_ICR_RXQ1 0x00200000 /* Rx Queue 1 Interrupt */
#define E1000_ICR_TXQ0 0x00400000 /* Tx Queue 0 Interrupt */
#define E1000_ICR_TXQ1 0x00800000 /* Tx Queue 1 Interrupt */
#define E1000_ICR_OTHER 0x01000000 /* Other Interrupt */
/* PBA ECC Register */
#define E1000_PBA_ECC_COUNTER_MASK 0xFFF00000 /* ECC counter mask */
#define E1000_PBA_ECC_COUNTER_SHIFT 20 /* ECC counter shift value */
#define E1000_PBA_ECC_CORR_EN 0x00000001 /* ECC correction enable */
#define E1000_PBA_ECC_STAT_CLR 0x00000002 /* Clear ECC error counter */
#define E1000_PBA_ECC_INT_EN 0x00000004 /* Enable ICR bit 5 for ECC */
/* This defines the bits that are set in the Interrupt Mask
* Set/Read Register. Each bit is documented below:
* o RXT0 = Receiver Timer Interrupt (ring 0)
* o TXDW = Transmit Descriptor Written Back
* o RXDMT0 = Receive Descriptor Minimum Threshold hit (ring 0)
* o RXSEQ = Receive Sequence Error
* o LSC = Link Status Change
*/
#define IMS_ENABLE_MASK ( \
E1000_IMS_RXT0 | \
E1000_IMS_TXDW | \
E1000_IMS_RXDMT0 | \
E1000_IMS_RXSEQ | \
E1000_IMS_LSC)
/* These are all of the events related to the OTHER interrupt.
*/
#define IMS_OTHER_MASK ( \
E1000_IMS_LSC | \
E1000_IMS_RXO | \
E1000_IMS_MDAC | \
E1000_IMS_SRPD | \
E1000_IMS_ACK | \
E1000_IMS_MNG)
/* Interrupt Mask Set */
#define E1000_IMS_TXDW E1000_ICR_TXDW /* Transmit desc written back */
#define E1000_IMS_LSC E1000_ICR_LSC /* Link Status Change */
#define E1000_IMS_RXSEQ E1000_ICR_RXSEQ /* Rx sequence error */
#define E1000_IMS_RXDMT0 E1000_ICR_RXDMT0 /* Rx desc min. threshold */
#define E1000_IMS_RXO E1000_ICR_RXO /* Receiver Overrun */
#define E1000_IMS_RXT0 E1000_ICR_RXT0 /* Rx timer intr */
#define E1000_IMS_MDAC E1000_ICR_MDAC /* MDIO Access Complete */
#define E1000_IMS_SRPD E1000_ICR_SRPD /* Small Receive Packet */
#define E1000_IMS_ACK E1000_ICR_ACK /* Receive ACK Frame Detected */
#define E1000_IMS_MNG E1000_ICR_MNG /* Manageability Event */
#define E1000_IMS_ECCER E1000_ICR_ECCER /* Uncorrectable ECC Error */
#define E1000_IMS_RXQ0 E1000_ICR_RXQ0 /* Rx Queue 0 Interrupt */
#define E1000_IMS_RXQ1 E1000_ICR_RXQ1 /* Rx Queue 1 Interrupt */
#define E1000_IMS_TXQ0 E1000_ICR_TXQ0 /* Tx Queue 0 Interrupt */
#define E1000_IMS_TXQ1 E1000_ICR_TXQ1 /* Tx Queue 1 Interrupt */
#define E1000_IMS_OTHER E1000_ICR_OTHER /* Other Interrupt */
/* Interrupt Cause Set */
#define E1000_ICS_LSC E1000_ICR_LSC /* Link Status Change */
#define E1000_ICS_RXSEQ E1000_ICR_RXSEQ /* Rx sequence error */
#define E1000_ICS_RXDMT0 E1000_ICR_RXDMT0 /* Rx desc min. threshold */
#define E1000_ICS_OTHER E1000_ICR_OTHER /* Other Interrupt */
/* Transmit Descriptor Control */
#define E1000_TXDCTL_PTHRESH 0x0000003F /* TXDCTL Prefetch Threshold */
#define E1000_TXDCTL_HTHRESH 0x00003F00 /* TXDCTL Host Threshold */
#define E1000_TXDCTL_WTHRESH 0x003F0000 /* TXDCTL Writeback Threshold */
#define E1000_TXDCTL_GRAN 0x01000000 /* TXDCTL Granularity */
#define E1000_TXDCTL_FULL_TX_DESC_WB 0x01010000 /* GRAN=1, WTHRESH=1 */
#define E1000_TXDCTL_MAX_TX_DESC_PREFETCH 0x0100001F /* GRAN=1, PTHRESH=31 */
/* Enable the counting of desc. still to be processed. */
#define E1000_TXDCTL_COUNT_DESC 0x00400000
/* Flow Control Constants */
#define FLOW_CONTROL_ADDRESS_LOW 0x00C28001
#define FLOW_CONTROL_ADDRESS_HIGH 0x00000100
#define FLOW_CONTROL_TYPE 0x8808
/* 802.1q VLAN Packet Size */
#define E1000_VLAN_FILTER_TBL_SIZE 128 /* VLAN Filter Table (4096 bits) */
/* Receive Address
* Number of high/low register pairs in the RAR. The RAR (Receive Address
* Registers) holds the directed and multicast addresses that we monitor.
* Technically, we have 16 spots. However, we reserve one of these spots
* (RAR[15]) for our directed address used by controllers with
* manageability enabled, allowing us room for 15 multicast addresses.
*/
#define E1000_RAR_ENTRIES 15
#define E1000_RAH_AV 0x80000000 /* Receive descriptor valid */
#define E1000_RAL_MAC_ADDR_LEN 4
#define E1000_RAH_MAC_ADDR_LEN 2
/* Error Codes */
#define E1000_ERR_NVM 1
#define E1000_ERR_PHY 2
#define E1000_ERR_CONFIG 3
#define E1000_ERR_PARAM 4
#define E1000_ERR_MAC_INIT 5
#define E1000_ERR_PHY_TYPE 6
#define E1000_ERR_RESET 9
#define E1000_ERR_MASTER_REQUESTS_PENDING 10
#define E1000_ERR_HOST_INTERFACE_COMMAND 11
#define E1000_BLK_PHY_RESET 12
#define E1000_ERR_SWFW_SYNC 13
#define E1000_NOT_IMPLEMENTED 14
#define E1000_ERR_INVALID_ARGUMENT 16
#define E1000_ERR_NO_SPACE 17
#define E1000_ERR_NVM_PBA_SECTION 18
/* Loop limit on how long we wait for auto-negotiation to complete */
#define FIBER_LINK_UP_LIMIT 50
#define COPPER_LINK_UP_LIMIT 10
#define PHY_AUTO_NEG_LIMIT 45
#define PHY_FORCE_LIMIT 20
/* Number of 100 microseconds we wait for PCI Express master disable */
#define MASTER_DISABLE_TIMEOUT 800
/* Number of milliseconds we wait for PHY configuration done after MAC reset */
#define PHY_CFG_TIMEOUT 100
/* Number of 2 milliseconds we wait for acquiring MDIO ownership. */
#define MDIO_OWNERSHIP_TIMEOUT 10
/* Number of milliseconds for NVM auto read done after MAC reset. */
#define AUTO_READ_DONE_TIMEOUT 10
/* Flow Control */
#define E1000_FCRTH_RTH 0x0000FFF8 /* Mask Bits[15:3] for RTH */
#define E1000_FCRTL_RTL 0x0000FFF8 /* Mask Bits[15:3] for RTL */
#define E1000_FCRTL_XONE 0x80000000 /* Enable XON frame transmission */
/* Transmit Configuration Word */
#define E1000_TXCW_FD 0x00000020 /* TXCW full duplex */
#define E1000_TXCW_PAUSE 0x00000080 /* TXCW sym pause request */
#define E1000_TXCW_ASM_DIR 0x00000100 /* TXCW astm pause direction */
#define E1000_TXCW_PAUSE_MASK 0x00000180 /* TXCW pause request mask */
#define E1000_TXCW_ANE 0x80000000 /* Auto-neg enable */
/* Receive Configuration Word */
#define E1000_RXCW_CW 0x0000ffff /* RxConfigWord mask */
#define E1000_RXCW_IV 0x08000000 /* Receive config invalid */
#define E1000_RXCW_C 0x20000000 /* Receive config */
#define E1000_RXCW_SYNCH 0x40000000 /* Receive config synch */
/* HH Time Sync */
#define E1000_TSYNCTXCTL_MAX_ALLOWED_DLY_MASK 0x0000F000 /* max delay */
#define E1000_TSYNCTXCTL_SYNC_COMP 0x40000000 /* sync complete */
#define E1000_TSYNCTXCTL_START_SYNC 0x80000000 /* initiate sync */
#define E1000_TSYNCTXCTL_VALID 0x00000001 /* Tx timestamp valid */
#define E1000_TSYNCTXCTL_ENABLED 0x00000010 /* enable Tx timestamping */
#define E1000_TSYNCRXCTL_VALID 0x00000001 /* Rx timestamp valid */
#define E1000_TSYNCRXCTL_TYPE_MASK 0x0000000E /* Rx type mask */
#define E1000_TSYNCRXCTL_TYPE_L2_V2 0x00
#define E1000_TSYNCRXCTL_TYPE_L4_V1 0x02
#define E1000_TSYNCRXCTL_TYPE_L2_L4_V2 0x04
#define E1000_TSYNCRXCTL_TYPE_ALL 0x08
#define E1000_TSYNCRXCTL_TYPE_EVENT_V2 0x0A
#define E1000_TSYNCRXCTL_ENABLED 0x00000010 /* enable Rx timestamping */
#define E1000_TSYNCRXCTL_SYSCFI 0x00000020 /* Sys clock frequency */
#define E1000_RXMTRL_PTP_V1_SYNC_MESSAGE 0x00000000
#define E1000_RXMTRL_PTP_V1_DELAY_REQ_MESSAGE 0x00010000
#define E1000_RXMTRL_PTP_V2_SYNC_MESSAGE 0x00000000
#define E1000_RXMTRL_PTP_V2_DELAY_REQ_MESSAGE 0x01000000
#define E1000_TIMINCA_INCPERIOD_SHIFT 24
#define E1000_TIMINCA_INCVALUE_MASK 0x00FFFFFF
/* PCI Express Control */
#define E1000_GCR_RXD_NO_SNOOP 0x00000001
#define E1000_GCR_RXDSCW_NO_SNOOP 0x00000002
#define E1000_GCR_RXDSCR_NO_SNOOP 0x00000004
#define E1000_GCR_TXD_NO_SNOOP 0x00000008
#define E1000_GCR_TXDSCW_NO_SNOOP 0x00000010
#define E1000_GCR_TXDSCR_NO_SNOOP 0x00000020
#define PCIE_NO_SNOOP_ALL (E1000_GCR_RXD_NO_SNOOP | \
E1000_GCR_RXDSCW_NO_SNOOP | \
E1000_GCR_RXDSCR_NO_SNOOP | \
E1000_GCR_TXD_NO_SNOOP | \
E1000_GCR_TXDSCW_NO_SNOOP | \
E1000_GCR_TXDSCR_NO_SNOOP)
/* NVM Control */
#define E1000_EECD_SK 0x00000001 /* NVM Clock */
#define E1000_EECD_CS 0x00000002 /* NVM Chip Select */
#define E1000_EECD_DI 0x00000004 /* NVM Data In */
#define E1000_EECD_DO 0x00000008 /* NVM Data Out */
#define E1000_EECD_REQ 0x00000040 /* NVM Access Request */
#define E1000_EECD_GNT 0x00000080 /* NVM Access Grant */
#define E1000_EECD_PRES 0x00000100 /* NVM Present */
#define E1000_EECD_SIZE 0x00000200 /* NVM Size (0=64 word 1=256 word) */
/* NVM Addressing bits based on type (0-small, 1-large) */
#define E1000_EECD_ADDR_BITS 0x00000400
#define E1000_NVM_GRANT_ATTEMPTS 1000 /* NVM # attempts to gain grant */
#define E1000_EECD_AUTO_RD 0x00000200 /* NVM Auto Read done */
#define E1000_EECD_SIZE_EX_MASK 0x00007800 /* NVM Size */
#define E1000_EECD_SIZE_EX_SHIFT 11
#define E1000_EECD_FLUPD 0x00080000 /* Update FLASH */
#define E1000_EECD_AUPDEN 0x00100000 /* Enable Autonomous FLASH update */
#define E1000_EECD_SEC1VAL 0x00400000 /* Sector One Valid */
#define E1000_EECD_SEC1VAL_VALID_MASK (E1000_EECD_AUTO_RD | E1000_EECD_PRES)
#define E1000_NVM_RW_REG_DATA 16 /* Offset to data in NVM r/w regs */
#define E1000_NVM_RW_REG_DONE 2 /* Offset to READ/WRITE done bit */
#define E1000_NVM_RW_REG_START 1 /* Start operation */
#define E1000_NVM_RW_ADDR_SHIFT 2 /* Shift to the address bits */
#define E1000_NVM_POLL_WRITE 1 /* Flag for polling write complete */
#define E1000_NVM_POLL_READ 0 /* Flag for polling read complete */
#define E1000_FLASH_UPDATES 2000
/* NVM Word Offsets */
#define NVM_COMPAT 0x0003
#define NVM_ID_LED_SETTINGS 0x0004
#define NVM_FUTURE_INIT_WORD1 0x0019
#define NVM_COMPAT_VALID_CSUM 0x0001
#define NVM_FUTURE_INIT_WORD1_VALID_CSUM 0x0040
#define NVM_INIT_CONTROL2_REG 0x000F
#define NVM_INIT_CONTROL3_PORT_B 0x0014
#define NVM_INIT_3GIO_3 0x001A
#define NVM_INIT_CONTROL3_PORT_A 0x0024
#define NVM_CFG 0x0012
#define NVM_ALT_MAC_ADDR_PTR 0x0037
#define NVM_CHECKSUM_REG 0x003F
#define E1000_NVM_CFG_DONE_PORT_0 0x40000 /* MNG config cycle done */
#define E1000_NVM_CFG_DONE_PORT_1 0x80000 /* ...for second port */
/* Mask bits for fields in Word 0x0f of the NVM */
#define NVM_WORD0F_PAUSE_MASK 0x3000
#define NVM_WORD0F_PAUSE 0x1000
#define NVM_WORD0F_ASM_DIR 0x2000
/* Mask bits for fields in Word 0x1a of the NVM */
#define NVM_WORD1A_ASPM_MASK 0x000C
/* Mask bits for fields in Word 0x03 of the EEPROM */
#define NVM_COMPAT_LOM 0x0800
/* length of string needed to store PBA number */
#define E1000_PBANUM_LENGTH 11
/* For checksumming, the sum of all words in the NVM should equal 0xBABA. */
#define NVM_SUM 0xBABA
/* PBA (printed board assembly) number words */
#define NVM_PBA_OFFSET_0 8
#define NVM_PBA_OFFSET_1 9
#define NVM_PBA_PTR_GUARD 0xFAFA
#define NVM_WORD_SIZE_BASE_SHIFT 6
/* NVM Commands - SPI */
#define NVM_MAX_RETRY_SPI 5000 /* Max wait of 5ms, for RDY signal */
#define NVM_READ_OPCODE_SPI 0x03 /* NVM read opcode */
#define NVM_WRITE_OPCODE_SPI 0x02 /* NVM write opcode */
#define NVM_A8_OPCODE_SPI 0x08 /* opcode bit-3 = address bit-8 */
#define NVM_WREN_OPCODE_SPI 0x06 /* NVM set Write Enable latch */
#define NVM_RDSR_OPCODE_SPI 0x05 /* NVM read Status register */
/* SPI NVM Status Register */
#define NVM_STATUS_RDY_SPI 0x01
/* Word definitions for ID LED Settings */
#define ID_LED_RESERVED_0000 0x0000
#define ID_LED_RESERVED_FFFF 0xFFFF
#define ID_LED_DEFAULT ((ID_LED_OFF1_ON2 << 12) | \
(ID_LED_OFF1_OFF2 << 8) | \
(ID_LED_DEF1_DEF2 << 4) | \
(ID_LED_DEF1_DEF2))
#define ID_LED_DEF1_DEF2 0x1
#define ID_LED_DEF1_ON2 0x2
#define ID_LED_DEF1_OFF2 0x3
#define ID_LED_ON1_DEF2 0x4
#define ID_LED_ON1_ON2 0x5
#define ID_LED_ON1_OFF2 0x6
#define ID_LED_OFF1_DEF2 0x7
#define ID_LED_OFF1_ON2 0x8
#define ID_LED_OFF1_OFF2 0x9
#define IGP_ACTIVITY_LED_MASK 0xFFFFF0FF
#define IGP_ACTIVITY_LED_ENABLE 0x0300
#define IGP_LED3_MODE 0x07000000
/* PCI/PCI-X/PCI-EX Config space */
#define PCI_HEADER_TYPE_REGISTER 0x0E
#define PCIE_LINK_STATUS 0x12
#define PCI_HEADER_TYPE_MULTIFUNC 0x80
#define PCIE_LINK_WIDTH_MASK 0x3F0
#define PCIE_LINK_WIDTH_SHIFT 4
#define PHY_REVISION_MASK 0xFFFFFFF0
#define MAX_PHY_REG_ADDRESS 0x1F /* 5 bit address bus (0-0x1F) */
#define MAX_PHY_MULTI_PAGE_REG 0xF
/* Bit definitions for valid PHY IDs.
* I = Integrated
* E = External
*/
#define M88E1000_E_PHY_ID 0x01410C50
#define M88E1000_I_PHY_ID 0x01410C30
#define M88E1011_I_PHY_ID 0x01410C20
#define IGP01E1000_I_PHY_ID 0x02A80380
#define M88E1111_I_PHY_ID 0x01410CC0
#define GG82563_E_PHY_ID 0x01410CA0
#define IGP03E1000_E_PHY_ID 0x02A80390
#define IFE_E_PHY_ID 0x02A80330
#define IFE_PLUS_E_PHY_ID 0x02A80320
#define IFE_C_E_PHY_ID 0x02A80310
#define BME1000_E_PHY_ID 0x01410CB0
#define BME1000_E_PHY_ID_R2 0x01410CB1
#define I82577_E_PHY_ID 0x01540050
#define I82578_E_PHY_ID 0x004DD040
#define I82579_E_PHY_ID 0x01540090
#define I217_E_PHY_ID 0x015400A0
/* M88E1000 Specific Registers */
#define M88E1000_PHY_SPEC_CTRL 0x10 /* PHY Specific Control Register */
#define M88E1000_PHY_SPEC_STATUS 0x11 /* PHY Specific Status Register */
#define M88E1000_EXT_PHY_SPEC_CTRL 0x14 /* Extended PHY Specific Control */
#define M88E1000_PHY_PAGE_SELECT 0x1D /* Reg 29 for page number setting */
#define M88E1000_PHY_GEN_CONTROL 0x1E /* Its meaning depends on reg 29 */
/* M88E1000 PHY Specific Control Register */
#define M88E1000_PSCR_POLARITY_REVERSAL 0x0002 /* 1=Polarity Reversal enabled */
#define M88E1000_PSCR_MDI_MANUAL_MODE 0x0000 /* MDI Crossover Mode bits 6:5 */
/* Manual MDI configuration */
#define M88E1000_PSCR_MDIX_MANUAL_MODE 0x0020 /* Manual MDIX configuration */
/* 1000BASE-T: Auto crossover, 100BASE-TX/10BASE-T: MDI Mode */
#define M88E1000_PSCR_AUTO_X_1000T 0x0040
/* Auto crossover enabled all speeds */
#define M88E1000_PSCR_AUTO_X_MODE 0x0060
#define M88E1000_PSCR_ASSERT_CRS_ON_TX 0x0800 /* 1=Assert CRS on Transmit */
/* M88E1000 PHY Specific Status Register */
#define M88E1000_PSSR_REV_POLARITY 0x0002 /* 1=Polarity reversed */
#define M88E1000_PSSR_DOWNSHIFT 0x0020 /* 1=Downshifted */
#define M88E1000_PSSR_MDIX 0x0040 /* 1=MDIX; 0=MDI */
/* 0=<50M; 1=50-80M; 2=80-110M; 3=110-140M; 4=>140M */
#define M88E1000_PSSR_CABLE_LENGTH 0x0380
#define M88E1000_PSSR_SPEED 0xC000 /* Speed, bits 14:15 */
#define M88E1000_PSSR_1000MBS 0x8000 /* 10=1000Mbs */
#define M88E1000_PSSR_CABLE_LENGTH_SHIFT 7
/* Number of times we will attempt to autonegotiate before downshifting if we
* are the master
*/
#define M88E1000_EPSCR_MASTER_DOWNSHIFT_MASK 0x0C00
#define M88E1000_EPSCR_MASTER_DOWNSHIFT_1X 0x0000
/* Number of times we will attempt to autonegotiate before downshifting if we
* are the slave
*/
#define M88E1000_EPSCR_SLAVE_DOWNSHIFT_MASK 0x0300
#define M88E1000_EPSCR_SLAVE_DOWNSHIFT_1X 0x0100
#define M88E1000_EPSCR_TX_CLK_25 0x0070 /* 25 MHz TX_CLK */
/* M88EC018 Rev 2 specific DownShift settings */
#define M88EC018_EPSCR_DOWNSHIFT_COUNTER_MASK 0x0E00
#define M88EC018_EPSCR_DOWNSHIFT_COUNTER_5X 0x0800
#define I82578_EPSCR_DOWNSHIFT_ENABLE 0x0020
#define I82578_EPSCR_DOWNSHIFT_COUNTER_MASK 0x001C
/* BME1000 PHY Specific Control Register */
#define BME1000_PSCR_ENABLE_DOWNSHIFT 0x0800 /* 1 = enable downshift */
/* Bits...
* 15-5: page
* 4-0: register offset
*/
#define GG82563_PAGE_SHIFT 5
#define GG82563_REG(page, reg) \
(((page) << GG82563_PAGE_SHIFT) | ((reg) & MAX_PHY_REG_ADDRESS))
#define GG82563_MIN_ALT_REG 30
/* GG82563 Specific Registers */
#define GG82563_PHY_SPEC_CTRL \
GG82563_REG(0, 16) /* PHY Specific Control */
#define GG82563_PHY_PAGE_SELECT \
GG82563_REG(0, 22) /* Page Select */
#define GG82563_PHY_SPEC_CTRL_2 \
GG82563_REG(0, 26) /* PHY Specific Control 2 */
#define GG82563_PHY_PAGE_SELECT_ALT \
GG82563_REG(0, 29) /* Alternate Page Select */
#define GG82563_PHY_MAC_SPEC_CTRL \
GG82563_REG(2, 21) /* MAC Specific Control Register */
#define GG82563_PHY_DSP_DISTANCE \
GG82563_REG(5, 26) /* DSP Distance */
/* Page 193 - Port Control Registers */
#define GG82563_PHY_KMRN_MODE_CTRL \
GG82563_REG(193, 16) /* Kumeran Mode Control */
#define GG82563_PHY_PWR_MGMT_CTRL \
GG82563_REG(193, 20) /* Power Management Control */
/* Page 194 - KMRN Registers */
#define GG82563_PHY_INBAND_CTRL \
GG82563_REG(194, 18) /* Inband Control */
/* MDI Control */
#define E1000_MDIC_REG_MASK 0x001F0000
#define E1000_MDIC_REG_SHIFT 16
#define E1000_MDIC_PHY_SHIFT 21
#define E1000_MDIC_OP_WRITE 0x04000000
#define E1000_MDIC_OP_READ 0x08000000
#define E1000_MDIC_READY 0x10000000
#define E1000_MDIC_ERROR 0x40000000
/* SerDes Control */
#define E1000_GEN_POLL_TIMEOUT 640
#endif /* _E1000_DEFINES_H_ */

View File

@ -0,0 +1,616 @@
/* SPDX-License-Identifier: GPL-2.0 */
/* Copyright(c) 1999 - 2018 Intel Corporation. */
/* Linux PRO/1000 Ethernet Driver main header file */
#ifndef _E1000_H_
#define _E1000_H_
#include <linux/bitops.h>
#include <linux/types.h>
#include <linux/timer.h>
#include <linux/workqueue.h>
#include <linux/io.h>
#include <linux/netdevice.h>
#include <linux/pci.h>
#include <linux/crc32.h>
#include <linux/if_vlan.h>
#include <linux/timecounter.h>
#include <linux/net_tstamp.h>
#include <linux/ptp_clock_kernel.h>
#include <linux/ptp_classify.h>
#include <linux/mii.h>
#include <linux/mdio.h>
#include <linux/mutex.h>
#include <linux/pm_qos.h>
#include <linux/irq_work.h>
#include "hw-6.4-ethercat.h"
/* EtherCAT header file */
#include "../ecdev.h"
struct e1000_info;
#define e_dbg(format, arg...) \
netdev_dbg(hw->adapter->netdev, format, ## arg)
#define e_err(format, arg...) \
netdev_err(adapter->netdev, format, ## arg)
#define e_info(format, arg...) \
netdev_info(adapter->netdev, format, ## arg)
#define e_warn(format, arg...) \
netdev_warn(adapter->netdev, format, ## arg)
#define e_notice(format, arg...) \
netdev_notice(adapter->netdev, format, ## arg)
/* Interrupt modes, as used by the IntMode parameter */
#define E1000E_INT_MODE_LEGACY 0
#define E1000E_INT_MODE_MSI 1
#define E1000E_INT_MODE_MSIX 2
/* Tx/Rx descriptor defines */
#define E1000_DEFAULT_TXD 256
#define E1000_MAX_TXD 4096
#define E1000_MIN_TXD 64
#define E1000_DEFAULT_RXD 256
#define E1000_MAX_RXD 4096
#define E1000_MIN_RXD 64
#define E1000_MIN_ITR_USECS 10 /* 100000 irq/sec */
#define E1000_MAX_ITR_USECS 10000 /* 100 irq/sec */
#define E1000_FC_PAUSE_TIME 0x0680 /* 858 usec */
/* How many Tx Descriptors do we need to call netif_wake_queue ? */
/* How many Rx Buffers do we bundle into one write to the hardware ? */
#define E1000_RX_BUFFER_WRITE 16 /* Must be power of 2 */
#define AUTO_ALL_MODES 0
#define E1000_EEPROM_APME 0x0400
#define E1000_MNG_VLAN_NONE (-1)
#define DEFAULT_JUMBO 9234
/* Time to wait before putting the device into D3 if there's no link (in ms). */
#define LINK_TIMEOUT 100
/* Count for polling __E1000_RESET condition every 10-20msec.
* Experimentation has shown the reset can take approximately 210msec.
*/
#define E1000_CHECK_RESET_COUNT 25
#define PCICFG_DESC_RING_STATUS 0xe4
#define FLUSH_DESC_REQUIRED 0x100
/* in the case of WTHRESH, it appears at least the 82571/2 hardware
* writes back 4 descriptors when WTHRESH=5, and 3 descriptors when
* WTHRESH=4, so a setting of 5 gives the most efficient bus
* utilization but to avoid possible Tx stalls, set it to 1
*/
#define E1000_TXDCTL_DMA_BURST_ENABLE \
(E1000_TXDCTL_GRAN | /* set descriptor granularity */ \
E1000_TXDCTL_COUNT_DESC | \
(1u << 16) | /* wthresh must be +1 more than desired */\
(1u << 8) | /* hthresh */ \
0x1f) /* pthresh */
#define E1000_RXDCTL_DMA_BURST_ENABLE \
(0x01000000 | /* set descriptor granularity */ \
(4u << 16) | /* set writeback threshold */ \
(4u << 8) | /* set prefetch threshold */ \
0x20) /* set hthresh */
#define E1000_TIDV_FPD BIT(31)
#define E1000_RDTR_FPD BIT(31)
enum e1000_boards {
board_82571,
board_82572,
board_82573,
board_82574,
board_82583,
board_80003es2lan,
board_ich8lan,
board_ich9lan,
board_ich10lan,
board_pchlan,
board_pch2lan,
board_pch_lpt,
board_pch_spt,
board_pch_cnp,
board_pch_tgp,
board_pch_adp,
board_pch_mtp
};
struct e1000_ps_page {
struct page *page;
u64 dma; /* must be u64 - written to hw */
};
/* wrappers around a pointer to a socket buffer,
* so a DMA handle can be stored along with the buffer
*/
struct e1000_buffer {
dma_addr_t dma;
struct sk_buff *skb;
union {
/* Tx */
struct {
unsigned long time_stamp;
u16 length;
u16 next_to_watch;
unsigned int segs;
unsigned int bytecount;
u16 mapped_as_page;
};
/* Rx */
struct {
/* arrays of page information for packet split */
struct e1000_ps_page *ps_pages;
struct page *page;
};
};
};
struct e1000_ring {
struct e1000_adapter *adapter; /* back pointer to adapter */
void *desc; /* pointer to ring memory */
dma_addr_t dma; /* phys address of ring */
unsigned int size; /* length of ring in bytes */
unsigned int count; /* number of desc. in ring */
u16 next_to_use;
u16 next_to_clean;
void __iomem *head;
void __iomem *tail;
/* array of buffer information structs */
struct e1000_buffer *buffer_info;
char name[IFNAMSIZ + 5];
u32 ims_val;
u32 itr_val;
void __iomem *itr_register;
int set_itr;
struct sk_buff *rx_skb_top;
};
/* PHY register snapshot values */
struct e1000_phy_regs {
u16 bmcr; /* basic mode control register */
u16 bmsr; /* basic mode status register */
u16 advertise; /* auto-negotiation advertisement */
u16 lpa; /* link partner ability register */
u16 expansion; /* auto-negotiation expansion reg */
u16 ctrl1000; /* 1000BASE-T control register */
u16 stat1000; /* 1000BASE-T status register */
u16 estatus; /* extended status register */
};
/* board specific private data structure */
struct e1000_adapter {
struct timer_list watchdog_timer;
struct timer_list phy_info_timer;
struct timer_list blink_timer;
struct work_struct reset_task;
struct work_struct watchdog_task;
const struct e1000_info *ei;
unsigned long active_vlans[BITS_TO_LONGS(VLAN_N_VID)];
u32 bd_number;
u32 rx_buffer_len;
u16 mng_vlan_id;
u16 link_speed;
u16 link_duplex;
u16 eeprom_vers;
/* track device up/down/testing state */
unsigned long state;
/* Interrupt Throttle Rate */
u32 itr;
u32 itr_setting;
u16 tx_itr;
u16 rx_itr;
/* Tx - one ring per active queue */
struct e1000_ring *tx_ring ____cacheline_aligned_in_smp;
u32 tx_fifo_limit;
struct napi_struct napi;
unsigned int uncorr_errors; /* uncorrectable ECC errors */
unsigned int corr_errors; /* correctable ECC errors */
unsigned int restart_queue;
u32 txd_cmd;
bool detect_tx_hung;
bool tx_hang_recheck;
u8 tx_timeout_factor;
u32 tx_int_delay;
u32 tx_abs_int_delay;
unsigned int total_tx_bytes;
unsigned int total_tx_packets;
unsigned int total_rx_bytes;
unsigned int total_rx_packets;
/* Tx stats */
u64 tpt_old;
u64 colc_old;
u32 gotc;
u64 gotc_old;
u32 tx_timeout_count;
u32 tx_fifo_head;
u32 tx_head_addr;
u32 tx_fifo_size;
u32 tx_dma_failed;
u32 tx_hwtstamp_timeouts;
u32 tx_hwtstamp_skipped;
/* Rx */
bool (*clean_rx)(struct e1000_ring *ring, int *work_done,
int work_to_do) ____cacheline_aligned_in_smp;
void (*alloc_rx_buf)(struct e1000_ring *ring, int cleaned_count,
gfp_t gfp);
struct e1000_ring *rx_ring;
u32 rx_int_delay;
u32 rx_abs_int_delay;
/* Rx stats */
u64 hw_csum_err;
u64 hw_csum_good;
u64 rx_hdr_split;
u32 gorc;
u64 gorc_old;
u32 alloc_rx_buff_failed;
u32 rx_dma_failed;
u32 rx_hwtstamp_cleared;
unsigned int rx_ps_pages;
u16 rx_ps_bsize0;
u32 max_frame_size;
u32 min_frame_size;
/* OS defined structs */
struct net_device *netdev;
struct pci_dev *pdev;
/* structs defined in e1000_hw.h */
struct e1000_hw hw;
spinlock_t stats64_lock; /* protects statistics counters */
struct e1000_hw_stats stats;
struct e1000_phy_info phy_info;
struct e1000_phy_stats phy_stats;
/* Snapshot of PHY registers */
struct e1000_phy_regs phy_regs;
struct e1000_ring test_tx_ring;
struct e1000_ring test_rx_ring;
u32 test_icr;
u32 msg_enable;
unsigned int num_vectors;
struct msix_entry *msix_entries;
int int_mode;
u32 eiac_mask;
u32 eeprom_wol;
u32 wol;
u32 pba;
u32 max_hw_frame_size;
bool fc_autoneg;
unsigned int flags;
unsigned int flags2;
struct work_struct downshift_task;
struct work_struct update_phy_task;
struct work_struct print_hang_task;
int phy_hang_count;
u16 tx_ring_count;
u16 rx_ring_count;
struct hwtstamp_config hwtstamp_config;
struct delayed_work systim_overflow_work;
struct sk_buff *tx_hwtstamp_skb;
unsigned long tx_hwtstamp_start;
struct work_struct tx_hwtstamp_work;
spinlock_t systim_lock; /* protects SYSTIML/H regsters */
struct cyclecounter cc;
struct timecounter tc;
struct ptp_clock *ptp_clock;
struct ptp_clock_info ptp_clock_info;
struct pm_qos_request pm_qos_req;
long ptp_delta;
u16 eee_advert;
/* EtherCAT device variables */
ec_device_t *ecdev_;
unsigned long ec_watchdog_jiffies;
struct irq_work watchdog_kicker;
bool ecdev_initialized;
};
static inline ec_device_t *get_ecdev(struct e1000_adapter *adapter)
{
#ifdef EC_ENABLE_DRIVER_RESOURCE_VERIFYING
WARN_ON(!adapter->ecdev_initialized);
#endif
return adapter->ecdev_;
}
struct e1000_info {
enum e1000_mac_type mac;
unsigned int flags;
unsigned int flags2;
u32 pba;
u32 max_hw_frame_size;
s32 (*get_variants)(struct e1000_adapter *);
const struct e1000_mac_operations *mac_ops;
const struct e1000_phy_operations *phy_ops;
const struct e1000_nvm_operations *nvm_ops;
};
s32 e1000e_get_base_timinca(struct e1000_adapter *adapter, u32 *timinca);
/* The system time is maintained by a 64-bit counter comprised of the 32-bit
* SYSTIMH and SYSTIML registers. How the counter increments (and therefore
* its resolution) is based on the contents of the TIMINCA register - it
* increments every incperiod (bits 31:24) clock ticks by incvalue (bits 23:0).
* For the best accuracy, the incperiod should be as small as possible. The
* incvalue is scaled by a factor as large as possible (while still fitting
* in bits 23:0) so that relatively small clock corrections can be made.
*
* As a result, a shift of INCVALUE_SHIFT_n is used to fit a value of
* INCVALUE_n into the TIMINCA register allowing 32+8+(24-INCVALUE_SHIFT_n)
* bits to count nanoseconds leaving the rest for fractional nonseconds.
*/
#define INCVALUE_96MHZ 125
#define INCVALUE_SHIFT_96MHZ 17
#define INCPERIOD_SHIFT_96MHZ 2
#define INCPERIOD_96MHZ (12 >> INCPERIOD_SHIFT_96MHZ)
#define INCVALUE_25MHZ 40
#define INCVALUE_SHIFT_25MHZ 18
#define INCPERIOD_25MHZ 1
#define INCVALUE_24MHZ 125
#define INCVALUE_SHIFT_24MHZ 14
#define INCPERIOD_24MHZ 3
#define INCVALUE_38400KHZ 26
#define INCVALUE_SHIFT_38400KHZ 19
#define INCPERIOD_38400KHZ 1
/* Another drawback of scaling the incvalue by a large factor is the
* 64-bit SYSTIM register overflows more quickly. This is dealt with
* by simply reading the clock before it overflows.
*
* Clock ns bits Overflows after
* ~~~~~~ ~~~~~~~ ~~~~~~~~~~~~~~~
* 96MHz 47-bit 2^(47-INCPERIOD_SHIFT_96MHz) / 10^9 / 3600 = 9.77 hrs
* 25MHz 46-bit 2^46 / 10^9 / 3600 = 19.55 hours
*/
#define E1000_SYSTIM_OVERFLOW_PERIOD (HZ * 60 * 60 * 4)
#define E1000_MAX_82574_SYSTIM_REREADS 50
#define E1000_82574_SYSTIM_EPSILON (1ULL << 35ULL)
/* hardware capability, feature, and workaround flags */
#define FLAG_HAS_AMT BIT(0)
#define FLAG_HAS_FLASH BIT(1)
#define FLAG_HAS_HW_VLAN_FILTER BIT(2)
#define FLAG_HAS_WOL BIT(3)
/* reserved BIT(4) */
#define FLAG_HAS_CTRLEXT_ON_LOAD BIT(5)
#define FLAG_HAS_SWSM_ON_LOAD BIT(6)
#define FLAG_HAS_JUMBO_FRAMES BIT(7)
#define FLAG_READ_ONLY_NVM BIT(8)
#define FLAG_IS_ICH BIT(9)
#define FLAG_HAS_MSIX BIT(10)
#define FLAG_HAS_SMART_POWER_DOWN BIT(11)
#define FLAG_IS_QUAD_PORT_A BIT(12)
#define FLAG_IS_QUAD_PORT BIT(13)
#define FLAG_HAS_HW_TIMESTAMP BIT(14)
#define FLAG_APME_IN_WUC BIT(15)
#define FLAG_APME_IN_CTRL3 BIT(16)
#define FLAG_APME_CHECK_PORT_B BIT(17)
#define FLAG_DISABLE_FC_PAUSE_TIME BIT(18)
#define FLAG_NO_WAKE_UCAST BIT(19)
#define FLAG_MNG_PT_ENABLED BIT(20)
#define FLAG_RESET_OVERWRITES_LAA BIT(21)
#define FLAG_TARC_SPEED_MODE_BIT BIT(22)
#define FLAG_TARC_SET_BIT_ZERO BIT(23)
#define FLAG_RX_NEEDS_RESTART BIT(24)
#define FLAG_LSC_GIG_SPEED_DROP BIT(25)
#define FLAG_SMART_POWER_DOWN BIT(26)
#define FLAG_MSI_ENABLED BIT(27)
/* reserved BIT(28) */
#define FLAG_TSO_FORCE BIT(29)
#define FLAG_RESTART_NOW BIT(30)
#define FLAG_MSI_TEST_FAILED BIT(31)
#define FLAG2_CRC_STRIPPING BIT(0)
#define FLAG2_HAS_PHY_WAKEUP BIT(1)
#define FLAG2_IS_DISCARDING BIT(2)
#define FLAG2_DISABLE_ASPM_L1 BIT(3)
#define FLAG2_HAS_PHY_STATS BIT(4)
#define FLAG2_HAS_EEE BIT(5)
#define FLAG2_DMA_BURST BIT(6)
#define FLAG2_DISABLE_ASPM_L0S BIT(7)
#define FLAG2_DISABLE_AIM BIT(8)
#define FLAG2_CHECK_PHY_HANG BIT(9)
#define FLAG2_NO_DISABLE_RX BIT(10)
#define FLAG2_PCIM2PCI_ARBITER_WA BIT(11)
#define FLAG2_DFLT_CRC_STRIPPING BIT(12)
#define FLAG2_CHECK_RX_HWTSTAMP BIT(13)
#define FLAG2_CHECK_SYSTIM_OVERFLOW BIT(14)
#define FLAG2_ENABLE_S0IX_FLOWS BIT(15)
#define E1000_RX_DESC_PS(R, i) \
(&(((union e1000_rx_desc_packet_split *)((R).desc))[i]))
#define E1000_RX_DESC_EXT(R, i) \
(&(((union e1000_rx_desc_extended *)((R).desc))[i]))
#define E1000_GET_DESC(R, i, type) (&(((struct type *)((R).desc))[i]))
#define E1000_TX_DESC(R, i) E1000_GET_DESC(R, i, e1000_tx_desc)
#define E1000_CONTEXT_DESC(R, i) E1000_GET_DESC(R, i, e1000_context_desc)
enum e1000_state_t {
__E1000_TESTING,
__E1000_RESETTING,
__E1000_ACCESS_SHARED_RESOURCE,
__E1000_DOWN
};
enum latency_range {
lowest_latency = 0,
low_latency = 1,
bulk_latency = 2,
latency_invalid = 255
};
extern char e1000e_driver_name[];
void e1000e_check_options(struct e1000_adapter *adapter);
void e1000e_set_ethtool_ops(struct net_device *netdev);
int e1000e_open(struct net_device *netdev);
int e1000e_close(struct net_device *netdev);
void e1000e_up(struct e1000_adapter *adapter);
void e1000e_down(struct e1000_adapter *adapter, bool reset);
void e1000e_reinit_locked(struct e1000_adapter *adapter);
void e1000e_reset(struct e1000_adapter *adapter);
void e1000e_power_up_phy(struct e1000_adapter *adapter);
int e1000e_setup_rx_resources(struct e1000_ring *ring);
int e1000e_setup_tx_resources(struct e1000_ring *ring);
void e1000e_free_rx_resources(struct e1000_ring *ring);
void e1000e_free_tx_resources(struct e1000_ring *ring);
void e1000e_get_stats64(struct net_device *netdev,
struct rtnl_link_stats64 *stats);
void e1000e_set_interrupt_capability(struct e1000_adapter *adapter);
void e1000e_reset_interrupt_capability(struct e1000_adapter *adapter);
void e1000e_get_hw_control(struct e1000_adapter *adapter);
void e1000e_release_hw_control(struct e1000_adapter *adapter);
void e1000e_write_itr(struct e1000_adapter *adapter, u32 itr);
extern unsigned int copybreak;
extern const struct e1000_info e1000_82571_info;
extern const struct e1000_info e1000_82572_info;
extern const struct e1000_info e1000_82573_info;
extern const struct e1000_info e1000_82574_info;
extern const struct e1000_info e1000_82583_info;
extern const struct e1000_info e1000_ich8_info;
extern const struct e1000_info e1000_ich9_info;
extern const struct e1000_info e1000_ich10_info;
extern const struct e1000_info e1000_pch_info;
extern const struct e1000_info e1000_pch2_info;
extern const struct e1000_info e1000_pch_lpt_info;
extern const struct e1000_info e1000_pch_spt_info;
extern const struct e1000_info e1000_pch_cnp_info;
extern const struct e1000_info e1000_pch_tgp_info;
extern const struct e1000_info e1000_pch_adp_info;
extern const struct e1000_info e1000_pch_mtp_info;
extern const struct e1000_info e1000_es2_info;
void e1000e_ptp_init(struct e1000_adapter *adapter);
void e1000e_ptp_remove(struct e1000_adapter *adapter);
u64 e1000e_read_systim(struct e1000_adapter *adapter,
struct ptp_system_timestamp *sts);
static inline s32 e1000_phy_hw_reset(struct e1000_hw *hw)
{
return hw->phy.ops.reset(hw);
}
static inline s32 e1e_rphy(struct e1000_hw *hw, u32 offset, u16 *data)
{
return hw->phy.ops.read_reg(hw, offset, data);
}
static inline s32 e1e_rphy_locked(struct e1000_hw *hw, u32 offset, u16 *data)
{
return hw->phy.ops.read_reg_locked(hw, offset, data);
}
static inline s32 e1e_wphy(struct e1000_hw *hw, u32 offset, u16 data)
{
return hw->phy.ops.write_reg(hw, offset, data);
}
static inline s32 e1e_wphy_locked(struct e1000_hw *hw, u32 offset, u16 data)
{
return hw->phy.ops.write_reg_locked(hw, offset, data);
}
void e1000e_reload_nvm_generic(struct e1000_hw *hw);
static inline s32 e1000e_read_mac_addr(struct e1000_hw *hw)
{
if (hw->mac.ops.read_mac_addr)
return hw->mac.ops.read_mac_addr(hw);
return e1000_read_mac_addr_generic(hw);
}
static inline s32 e1000_validate_nvm_checksum(struct e1000_hw *hw)
{
return hw->nvm.ops.validate(hw);
}
static inline s32 e1000e_update_nvm_checksum(struct e1000_hw *hw)
{
return hw->nvm.ops.update(hw);
}
static inline s32 e1000_read_nvm(struct e1000_hw *hw, u16 offset, u16 words,
u16 *data)
{
return hw->nvm.ops.read(hw, offset, words, data);
}
static inline s32 e1000_write_nvm(struct e1000_hw *hw, u16 offset, u16 words,
u16 *data)
{
return hw->nvm.ops.write(hw, offset, words, data);
}
static inline s32 e1000_get_phy_info(struct e1000_hw *hw)
{
return hw->phy.ops.get_info(hw);
}
static inline u32 __er32(struct e1000_hw *hw, unsigned long reg)
{
return readl(hw->hw_addr + reg);
}
#define er32(reg) __er32(hw, E1000_##reg)
void __ew32(struct e1000_hw *hw, unsigned long reg, u32 val);
#define ew32(reg, val) __ew32(hw, E1000_##reg, (val))
#define e1e_flush() er32(STATUS)
#define E1000_WRITE_REG_ARRAY(a, reg, offset, value) \
(__ew32((a), (reg + ((offset) << 2)), (value)))
#define E1000_READ_REG_ARRAY(a, reg, offset) \
(readl((a)->hw_addr + reg + ((offset) << 2)))
#endif /* _E1000_H_ */

View File

@ -0,0 +1,598 @@
/* SPDX-License-Identifier: GPL-2.0 */
/* Copyright(c) 1999 - 2018 Intel Corporation. */
/* Linux PRO/1000 Ethernet Driver main header file */
#ifndef _E1000_H_
#define _E1000_H_
#include <linux/bitops.h>
#include <linux/types.h>
#include <linux/timer.h>
#include <linux/workqueue.h>
#include <linux/io.h>
#include <linux/netdevice.h>
#include <linux/pci.h>
#include <linux/crc32.h>
#include <linux/if_vlan.h>
#include <linux/timecounter.h>
#include <linux/net_tstamp.h>
#include <linux/ptp_clock_kernel.h>
#include <linux/ptp_classify.h>
#include <linux/mii.h>
#include <linux/mdio.h>
#include <linux/mutex.h>
#include <linux/pm_qos.h>
#include "hw.h"
struct e1000_info;
#define e_dbg(format, arg...) \
netdev_dbg(hw->adapter->netdev, format, ## arg)
#define e_err(format, arg...) \
netdev_err(adapter->netdev, format, ## arg)
#define e_info(format, arg...) \
netdev_info(adapter->netdev, format, ## arg)
#define e_warn(format, arg...) \
netdev_warn(adapter->netdev, format, ## arg)
#define e_notice(format, arg...) \
netdev_notice(adapter->netdev, format, ## arg)
/* Interrupt modes, as used by the IntMode parameter */
#define E1000E_INT_MODE_LEGACY 0
#define E1000E_INT_MODE_MSI 1
#define E1000E_INT_MODE_MSIX 2
/* Tx/Rx descriptor defines */
#define E1000_DEFAULT_TXD 256
#define E1000_MAX_TXD 4096
#define E1000_MIN_TXD 64
#define E1000_DEFAULT_RXD 256
#define E1000_MAX_RXD 4096
#define E1000_MIN_RXD 64
#define E1000_MIN_ITR_USECS 10 /* 100000 irq/sec */
#define E1000_MAX_ITR_USECS 10000 /* 100 irq/sec */
#define E1000_FC_PAUSE_TIME 0x0680 /* 858 usec */
/* How many Tx Descriptors do we need to call netif_wake_queue ? */
/* How many Rx Buffers do we bundle into one write to the hardware ? */
#define E1000_RX_BUFFER_WRITE 16 /* Must be power of 2 */
#define AUTO_ALL_MODES 0
#define E1000_EEPROM_APME 0x0400
#define E1000_MNG_VLAN_NONE (-1)
#define DEFAULT_JUMBO 9234
/* Time to wait before putting the device into D3 if there's no link (in ms). */
#define LINK_TIMEOUT 100
/* Count for polling __E1000_RESET condition every 10-20msec.
* Experimentation has shown the reset can take approximately 210msec.
*/
#define E1000_CHECK_RESET_COUNT 25
#define PCICFG_DESC_RING_STATUS 0xe4
#define FLUSH_DESC_REQUIRED 0x100
/* in the case of WTHRESH, it appears at least the 82571/2 hardware
* writes back 4 descriptors when WTHRESH=5, and 3 descriptors when
* WTHRESH=4, so a setting of 5 gives the most efficient bus
* utilization but to avoid possible Tx stalls, set it to 1
*/
#define E1000_TXDCTL_DMA_BURST_ENABLE \
(E1000_TXDCTL_GRAN | /* set descriptor granularity */ \
E1000_TXDCTL_COUNT_DESC | \
(1u << 16) | /* wthresh must be +1 more than desired */\
(1u << 8) | /* hthresh */ \
0x1f) /* pthresh */
#define E1000_RXDCTL_DMA_BURST_ENABLE \
(0x01000000 | /* set descriptor granularity */ \
(4u << 16) | /* set writeback threshold */ \
(4u << 8) | /* set prefetch threshold */ \
0x20) /* set hthresh */
#define E1000_TIDV_FPD BIT(31)
#define E1000_RDTR_FPD BIT(31)
enum e1000_boards {
board_82571,
board_82572,
board_82573,
board_82574,
board_82583,
board_80003es2lan,
board_ich8lan,
board_ich9lan,
board_ich10lan,
board_pchlan,
board_pch2lan,
board_pch_lpt,
board_pch_spt,
board_pch_cnp,
board_pch_tgp,
board_pch_adp,
board_pch_mtp
};
struct e1000_ps_page {
struct page *page;
u64 dma; /* must be u64 - written to hw */
};
/* wrappers around a pointer to a socket buffer,
* so a DMA handle can be stored along with the buffer
*/
struct e1000_buffer {
dma_addr_t dma;
struct sk_buff *skb;
union {
/* Tx */
struct {
unsigned long time_stamp;
u16 length;
u16 next_to_watch;
unsigned int segs;
unsigned int bytecount;
u16 mapped_as_page;
};
/* Rx */
struct {
/* arrays of page information for packet split */
struct e1000_ps_page *ps_pages;
struct page *page;
};
};
};
struct e1000_ring {
struct e1000_adapter *adapter; /* back pointer to adapter */
void *desc; /* pointer to ring memory */
dma_addr_t dma; /* phys address of ring */
unsigned int size; /* length of ring in bytes */
unsigned int count; /* number of desc. in ring */
u16 next_to_use;
u16 next_to_clean;
void __iomem *head;
void __iomem *tail;
/* array of buffer information structs */
struct e1000_buffer *buffer_info;
char name[IFNAMSIZ + 5];
u32 ims_val;
u32 itr_val;
void __iomem *itr_register;
int set_itr;
struct sk_buff *rx_skb_top;
};
/* PHY register snapshot values */
struct e1000_phy_regs {
u16 bmcr; /* basic mode control register */
u16 bmsr; /* basic mode status register */
u16 advertise; /* auto-negotiation advertisement */
u16 lpa; /* link partner ability register */
u16 expansion; /* auto-negotiation expansion reg */
u16 ctrl1000; /* 1000BASE-T control register */
u16 stat1000; /* 1000BASE-T status register */
u16 estatus; /* extended status register */
};
/* board specific private data structure */
struct e1000_adapter {
struct timer_list watchdog_timer;
struct timer_list phy_info_timer;
struct timer_list blink_timer;
struct work_struct reset_task;
struct work_struct watchdog_task;
const struct e1000_info *ei;
unsigned long active_vlans[BITS_TO_LONGS(VLAN_N_VID)];
u32 bd_number;
u32 rx_buffer_len;
u16 mng_vlan_id;
u16 link_speed;
u16 link_duplex;
u16 eeprom_vers;
/* track device up/down/testing state */
unsigned long state;
/* Interrupt Throttle Rate */
u32 itr;
u32 itr_setting;
u16 tx_itr;
u16 rx_itr;
/* Tx - one ring per active queue */
struct e1000_ring *tx_ring ____cacheline_aligned_in_smp;
u32 tx_fifo_limit;
struct napi_struct napi;
unsigned int uncorr_errors; /* uncorrectable ECC errors */
unsigned int corr_errors; /* correctable ECC errors */
unsigned int restart_queue;
u32 txd_cmd;
bool detect_tx_hung;
bool tx_hang_recheck;
u8 tx_timeout_factor;
u32 tx_int_delay;
u32 tx_abs_int_delay;
unsigned int total_tx_bytes;
unsigned int total_tx_packets;
unsigned int total_rx_bytes;
unsigned int total_rx_packets;
/* Tx stats */
u64 tpt_old;
u64 colc_old;
u32 gotc;
u64 gotc_old;
u32 tx_timeout_count;
u32 tx_fifo_head;
u32 tx_head_addr;
u32 tx_fifo_size;
u32 tx_dma_failed;
u32 tx_hwtstamp_timeouts;
u32 tx_hwtstamp_skipped;
/* Rx */
bool (*clean_rx)(struct e1000_ring *ring, int *work_done,
int work_to_do) ____cacheline_aligned_in_smp;
void (*alloc_rx_buf)(struct e1000_ring *ring, int cleaned_count,
gfp_t gfp);
struct e1000_ring *rx_ring;
u32 rx_int_delay;
u32 rx_abs_int_delay;
/* Rx stats */
u64 hw_csum_err;
u64 hw_csum_good;
u64 rx_hdr_split;
u32 gorc;
u64 gorc_old;
u32 alloc_rx_buff_failed;
u32 rx_dma_failed;
u32 rx_hwtstamp_cleared;
unsigned int rx_ps_pages;
u16 rx_ps_bsize0;
u32 max_frame_size;
u32 min_frame_size;
/* OS defined structs */
struct net_device *netdev;
struct pci_dev *pdev;
/* structs defined in e1000_hw.h */
struct e1000_hw hw;
spinlock_t stats64_lock; /* protects statistics counters */
struct e1000_hw_stats stats;
struct e1000_phy_info phy_info;
struct e1000_phy_stats phy_stats;
/* Snapshot of PHY registers */
struct e1000_phy_regs phy_regs;
struct e1000_ring test_tx_ring;
struct e1000_ring test_rx_ring;
u32 test_icr;
u32 msg_enable;
unsigned int num_vectors;
struct msix_entry *msix_entries;
int int_mode;
u32 eiac_mask;
u32 eeprom_wol;
u32 wol;
u32 pba;
u32 max_hw_frame_size;
bool fc_autoneg;
unsigned int flags;
unsigned int flags2;
struct work_struct downshift_task;
struct work_struct update_phy_task;
struct work_struct print_hang_task;
int phy_hang_count;
u16 tx_ring_count;
u16 rx_ring_count;
struct hwtstamp_config hwtstamp_config;
struct delayed_work systim_overflow_work;
struct sk_buff *tx_hwtstamp_skb;
unsigned long tx_hwtstamp_start;
struct work_struct tx_hwtstamp_work;
spinlock_t systim_lock; /* protects SYSTIML/H regsters */
struct cyclecounter cc;
struct timecounter tc;
struct ptp_clock *ptp_clock;
struct ptp_clock_info ptp_clock_info;
struct pm_qos_request pm_qos_req;
long ptp_delta;
u16 eee_advert;
};
struct e1000_info {
enum e1000_mac_type mac;
unsigned int flags;
unsigned int flags2;
u32 pba;
u32 max_hw_frame_size;
s32 (*get_variants)(struct e1000_adapter *);
const struct e1000_mac_operations *mac_ops;
const struct e1000_phy_operations *phy_ops;
const struct e1000_nvm_operations *nvm_ops;
};
s32 e1000e_get_base_timinca(struct e1000_adapter *adapter, u32 *timinca);
/* The system time is maintained by a 64-bit counter comprised of the 32-bit
* SYSTIMH and SYSTIML registers. How the counter increments (and therefore
* its resolution) is based on the contents of the TIMINCA register - it
* increments every incperiod (bits 31:24) clock ticks by incvalue (bits 23:0).
* For the best accuracy, the incperiod should be as small as possible. The
* incvalue is scaled by a factor as large as possible (while still fitting
* in bits 23:0) so that relatively small clock corrections can be made.
*
* As a result, a shift of INCVALUE_SHIFT_n is used to fit a value of
* INCVALUE_n into the TIMINCA register allowing 32+8+(24-INCVALUE_SHIFT_n)
* bits to count nanoseconds leaving the rest for fractional nonseconds.
*/
#define INCVALUE_96MHZ 125
#define INCVALUE_SHIFT_96MHZ 17
#define INCPERIOD_SHIFT_96MHZ 2
#define INCPERIOD_96MHZ (12 >> INCPERIOD_SHIFT_96MHZ)
#define INCVALUE_25MHZ 40
#define INCVALUE_SHIFT_25MHZ 18
#define INCPERIOD_25MHZ 1
#define INCVALUE_24MHZ 125
#define INCVALUE_SHIFT_24MHZ 14
#define INCPERIOD_24MHZ 3
#define INCVALUE_38400KHZ 26
#define INCVALUE_SHIFT_38400KHZ 19
#define INCPERIOD_38400KHZ 1
/* Another drawback of scaling the incvalue by a large factor is the
* 64-bit SYSTIM register overflows more quickly. This is dealt with
* by simply reading the clock before it overflows.
*
* Clock ns bits Overflows after
* ~~~~~~ ~~~~~~~ ~~~~~~~~~~~~~~~
* 96MHz 47-bit 2^(47-INCPERIOD_SHIFT_96MHz) / 10^9 / 3600 = 9.77 hrs
* 25MHz 46-bit 2^46 / 10^9 / 3600 = 19.55 hours
*/
#define E1000_SYSTIM_OVERFLOW_PERIOD (HZ * 60 * 60 * 4)
#define E1000_MAX_82574_SYSTIM_REREADS 50
#define E1000_82574_SYSTIM_EPSILON (1ULL << 35ULL)
/* hardware capability, feature, and workaround flags */
#define FLAG_HAS_AMT BIT(0)
#define FLAG_HAS_FLASH BIT(1)
#define FLAG_HAS_HW_VLAN_FILTER BIT(2)
#define FLAG_HAS_WOL BIT(3)
/* reserved BIT(4) */
#define FLAG_HAS_CTRLEXT_ON_LOAD BIT(5)
#define FLAG_HAS_SWSM_ON_LOAD BIT(6)
#define FLAG_HAS_JUMBO_FRAMES BIT(7)
#define FLAG_READ_ONLY_NVM BIT(8)
#define FLAG_IS_ICH BIT(9)
#define FLAG_HAS_MSIX BIT(10)
#define FLAG_HAS_SMART_POWER_DOWN BIT(11)
#define FLAG_IS_QUAD_PORT_A BIT(12)
#define FLAG_IS_QUAD_PORT BIT(13)
#define FLAG_HAS_HW_TIMESTAMP BIT(14)
#define FLAG_APME_IN_WUC BIT(15)
#define FLAG_APME_IN_CTRL3 BIT(16)
#define FLAG_APME_CHECK_PORT_B BIT(17)
#define FLAG_DISABLE_FC_PAUSE_TIME BIT(18)
#define FLAG_NO_WAKE_UCAST BIT(19)
#define FLAG_MNG_PT_ENABLED BIT(20)
#define FLAG_RESET_OVERWRITES_LAA BIT(21)
#define FLAG_TARC_SPEED_MODE_BIT BIT(22)
#define FLAG_TARC_SET_BIT_ZERO BIT(23)
#define FLAG_RX_NEEDS_RESTART BIT(24)
#define FLAG_LSC_GIG_SPEED_DROP BIT(25)
#define FLAG_SMART_POWER_DOWN BIT(26)
#define FLAG_MSI_ENABLED BIT(27)
/* reserved BIT(28) */
#define FLAG_TSO_FORCE BIT(29)
#define FLAG_RESTART_NOW BIT(30)
#define FLAG_MSI_TEST_FAILED BIT(31)
#define FLAG2_CRC_STRIPPING BIT(0)
#define FLAG2_HAS_PHY_WAKEUP BIT(1)
#define FLAG2_IS_DISCARDING BIT(2)
#define FLAG2_DISABLE_ASPM_L1 BIT(3)
#define FLAG2_HAS_PHY_STATS BIT(4)
#define FLAG2_HAS_EEE BIT(5)
#define FLAG2_DMA_BURST BIT(6)
#define FLAG2_DISABLE_ASPM_L0S BIT(7)
#define FLAG2_DISABLE_AIM BIT(8)
#define FLAG2_CHECK_PHY_HANG BIT(9)
#define FLAG2_NO_DISABLE_RX BIT(10)
#define FLAG2_PCIM2PCI_ARBITER_WA BIT(11)
#define FLAG2_DFLT_CRC_STRIPPING BIT(12)
#define FLAG2_CHECK_RX_HWTSTAMP BIT(13)
#define FLAG2_CHECK_SYSTIM_OVERFLOW BIT(14)
#define FLAG2_ENABLE_S0IX_FLOWS BIT(15)
#define E1000_RX_DESC_PS(R, i) \
(&(((union e1000_rx_desc_packet_split *)((R).desc))[i]))
#define E1000_RX_DESC_EXT(R, i) \
(&(((union e1000_rx_desc_extended *)((R).desc))[i]))
#define E1000_GET_DESC(R, i, type) (&(((struct type *)((R).desc))[i]))
#define E1000_TX_DESC(R, i) E1000_GET_DESC(R, i, e1000_tx_desc)
#define E1000_CONTEXT_DESC(R, i) E1000_GET_DESC(R, i, e1000_context_desc)
enum e1000_state_t {
__E1000_TESTING,
__E1000_RESETTING,
__E1000_ACCESS_SHARED_RESOURCE,
__E1000_DOWN
};
enum latency_range {
lowest_latency = 0,
low_latency = 1,
bulk_latency = 2,
latency_invalid = 255
};
extern char e1000e_driver_name[];
void e1000e_check_options(struct e1000_adapter *adapter);
void e1000e_set_ethtool_ops(struct net_device *netdev);
int e1000e_open(struct net_device *netdev);
int e1000e_close(struct net_device *netdev);
void e1000e_up(struct e1000_adapter *adapter);
void e1000e_down(struct e1000_adapter *adapter, bool reset);
void e1000e_reinit_locked(struct e1000_adapter *adapter);
void e1000e_reset(struct e1000_adapter *adapter);
void e1000e_power_up_phy(struct e1000_adapter *adapter);
int e1000e_setup_rx_resources(struct e1000_ring *ring);
int e1000e_setup_tx_resources(struct e1000_ring *ring);
void e1000e_free_rx_resources(struct e1000_ring *ring);
void e1000e_free_tx_resources(struct e1000_ring *ring);
void e1000e_get_stats64(struct net_device *netdev,
struct rtnl_link_stats64 *stats);
void e1000e_set_interrupt_capability(struct e1000_adapter *adapter);
void e1000e_reset_interrupt_capability(struct e1000_adapter *adapter);
void e1000e_get_hw_control(struct e1000_adapter *adapter);
void e1000e_release_hw_control(struct e1000_adapter *adapter);
void e1000e_write_itr(struct e1000_adapter *adapter, u32 itr);
extern unsigned int copybreak;
extern const struct e1000_info e1000_82571_info;
extern const struct e1000_info e1000_82572_info;
extern const struct e1000_info e1000_82573_info;
extern const struct e1000_info e1000_82574_info;
extern const struct e1000_info e1000_82583_info;
extern const struct e1000_info e1000_ich8_info;
extern const struct e1000_info e1000_ich9_info;
extern const struct e1000_info e1000_ich10_info;
extern const struct e1000_info e1000_pch_info;
extern const struct e1000_info e1000_pch2_info;
extern const struct e1000_info e1000_pch_lpt_info;
extern const struct e1000_info e1000_pch_spt_info;
extern const struct e1000_info e1000_pch_cnp_info;
extern const struct e1000_info e1000_pch_tgp_info;
extern const struct e1000_info e1000_pch_adp_info;
extern const struct e1000_info e1000_pch_mtp_info;
extern const struct e1000_info e1000_es2_info;
void e1000e_ptp_init(struct e1000_adapter *adapter);
void e1000e_ptp_remove(struct e1000_adapter *adapter);
u64 e1000e_read_systim(struct e1000_adapter *adapter,
struct ptp_system_timestamp *sts);
static inline s32 e1000_phy_hw_reset(struct e1000_hw *hw)
{
return hw->phy.ops.reset(hw);
}
static inline s32 e1e_rphy(struct e1000_hw *hw, u32 offset, u16 *data)
{
return hw->phy.ops.read_reg(hw, offset, data);
}
static inline s32 e1e_rphy_locked(struct e1000_hw *hw, u32 offset, u16 *data)
{
return hw->phy.ops.read_reg_locked(hw, offset, data);
}
static inline s32 e1e_wphy(struct e1000_hw *hw, u32 offset, u16 data)
{
return hw->phy.ops.write_reg(hw, offset, data);
}
static inline s32 e1e_wphy_locked(struct e1000_hw *hw, u32 offset, u16 data)
{
return hw->phy.ops.write_reg_locked(hw, offset, data);
}
void e1000e_reload_nvm_generic(struct e1000_hw *hw);
static inline s32 e1000e_read_mac_addr(struct e1000_hw *hw)
{
if (hw->mac.ops.read_mac_addr)
return hw->mac.ops.read_mac_addr(hw);
return e1000_read_mac_addr_generic(hw);
}
static inline s32 e1000_validate_nvm_checksum(struct e1000_hw *hw)
{
return hw->nvm.ops.validate(hw);
}
static inline s32 e1000e_update_nvm_checksum(struct e1000_hw *hw)
{
return hw->nvm.ops.update(hw);
}
static inline s32 e1000_read_nvm(struct e1000_hw *hw, u16 offset, u16 words,
u16 *data)
{
return hw->nvm.ops.read(hw, offset, words, data);
}
static inline s32 e1000_write_nvm(struct e1000_hw *hw, u16 offset, u16 words,
u16 *data)
{
return hw->nvm.ops.write(hw, offset, words, data);
}
static inline s32 e1000_get_phy_info(struct e1000_hw *hw)
{
return hw->phy.ops.get_info(hw);
}
static inline u32 __er32(struct e1000_hw *hw, unsigned long reg)
{
return readl(hw->hw_addr + reg);
}
#define er32(reg) __er32(hw, E1000_##reg)
void __ew32(struct e1000_hw *hw, unsigned long reg, u32 val);
#define ew32(reg, val) __ew32(hw, E1000_##reg, (val))
#define e1e_flush() er32(STATUS)
#define E1000_WRITE_REG_ARRAY(a, reg, offset, value) \
(__ew32((a), (reg + ((offset) << 2)), (value)))
#define E1000_READ_REG_ARRAY(a, reg, offset) \
(readl((a)->hw_addr + reg + ((offset) << 2)))
#endif /* _E1000_H_ */

View File

@ -0,0 +1,42 @@
/* SPDX-License-Identifier: GPL-2.0 */
/* Copyright(c) 2022, Intel Corporation. */
/* Modeled on trace-events-sample.h */
/* The trace subsystem name for e1000e will be "e1000e_trace".
*
* This file is named e1000e_trace.h.
*
* Since this include file's name is different from the trace
* subsystem name, we'll have to define TRACE_INCLUDE_FILE at the end
* of this file.
*/
#undef TRACE_SYSTEM
#define TRACE_SYSTEM e1000e_trace
#if !defined(_TRACE_E1000E_TRACE_H) || defined(TRACE_HEADER_MULTI_READ)
#define _TRACE_E1000E_TRACE_H
#include <linux/tracepoint.h>
TRACE_EVENT(e1000e_trace_mac_register,
TP_PROTO(uint32_t reg),
TP_ARGS(reg),
TP_STRUCT__entry(__field(uint32_t, reg)),
TP_fast_assign(__entry->reg = reg;),
TP_printk("event: TraceHub e1000e mac register: 0x%08x",
__entry->reg)
);
#endif
/* This must be outside ifdef _E1000E_TRACE_H */
/* This trace include file is not located in the .../include/trace
* with the kernel tracepoint definitions, because we're a loadable
* module.
*/
#undef TRACE_INCLUDE_PATH
#define TRACE_INCLUDE_PATH .
#undef TRACE_INCLUDE_FILE
#define TRACE_INCLUDE_FILE e1000e_trace-6.4-ethercat
#include <trace/define_trace.h>

View File

@ -0,0 +1,42 @@
/* SPDX-License-Identifier: GPL-2.0 */
/* Copyright(c) 2022, Intel Corporation. */
/* Modeled on trace-events-sample.h */
/* The trace subsystem name for e1000e will be "e1000e_trace".
*
* This file is named e1000e_trace.h.
*
* Since this include file's name is different from the trace
* subsystem name, we'll have to define TRACE_INCLUDE_FILE at the end
* of this file.
*/
#undef TRACE_SYSTEM
#define TRACE_SYSTEM e1000e_trace
#if !defined(_TRACE_E1000E_TRACE_H) || defined(TRACE_HEADER_MULTI_READ)
#define _TRACE_E1000E_TRACE_H
#include <linux/tracepoint.h>
TRACE_EVENT(e1000e_trace_mac_register,
TP_PROTO(uint32_t reg),
TP_ARGS(reg),
TP_STRUCT__entry(__field(uint32_t, reg)),
TP_fast_assign(__entry->reg = reg;),
TP_printk("event: TraceHub e1000e mac register: 0x%08x",
__entry->reg)
);
#endif
/* This must be outside ifdef _E1000E_TRACE_H */
/* This trace include file is not located in the .../include/trace
* with the kernel tracepoint definitions, because we're a loadable
* module.
*/
#undef TRACE_INCLUDE_PATH
#define TRACE_INCLUDE_PATH .
#undef TRACE_INCLUDE_FILE
#define TRACE_INCLUDE_FILE e1000e_trace
#include <trace/define_trace.h>

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,735 @@
/* SPDX-License-Identifier: GPL-2.0 */
/* Copyright(c) 1999 - 2018 Intel Corporation. */
#ifndef _E1000E_HW_H_
#define _E1000E_HW_H_
#include "regs-6.4-ethercat.h"
#include "defines-6.4-ethercat.h"
struct e1000_hw;
#define E1000_DEV_ID_82571EB_COPPER 0x105E
#define E1000_DEV_ID_82571EB_FIBER 0x105F
#define E1000_DEV_ID_82571EB_SERDES 0x1060
#define E1000_DEV_ID_82571EB_QUAD_COPPER 0x10A4
#define E1000_DEV_ID_82571PT_QUAD_COPPER 0x10D5
#define E1000_DEV_ID_82571EB_QUAD_FIBER 0x10A5
#define E1000_DEV_ID_82571EB_QUAD_COPPER_LP 0x10BC
#define E1000_DEV_ID_82571EB_SERDES_DUAL 0x10D9
#define E1000_DEV_ID_82571EB_SERDES_QUAD 0x10DA
#define E1000_DEV_ID_82572EI_COPPER 0x107D
#define E1000_DEV_ID_82572EI_FIBER 0x107E
#define E1000_DEV_ID_82572EI_SERDES 0x107F
#define E1000_DEV_ID_82572EI 0x10B9
#define E1000_DEV_ID_82573E 0x108B
#define E1000_DEV_ID_82573E_IAMT 0x108C
#define E1000_DEV_ID_82573L 0x109A
#define E1000_DEV_ID_82574L 0x10D3
#define E1000_DEV_ID_82574LA 0x10F6
#define E1000_DEV_ID_82583V 0x150C
#define E1000_DEV_ID_80003ES2LAN_COPPER_DPT 0x1096
#define E1000_DEV_ID_80003ES2LAN_SERDES_DPT 0x1098
#define E1000_DEV_ID_80003ES2LAN_COPPER_SPT 0x10BA
#define E1000_DEV_ID_80003ES2LAN_SERDES_SPT 0x10BB
#define E1000_DEV_ID_ICH8_82567V_3 0x1501
#define E1000_DEV_ID_ICH8_IGP_M_AMT 0x1049
#define E1000_DEV_ID_ICH8_IGP_AMT 0x104A
#define E1000_DEV_ID_ICH8_IGP_C 0x104B
#define E1000_DEV_ID_ICH8_IFE 0x104C
#define E1000_DEV_ID_ICH8_IFE_GT 0x10C4
#define E1000_DEV_ID_ICH8_IFE_G 0x10C5
#define E1000_DEV_ID_ICH8_IGP_M 0x104D
#define E1000_DEV_ID_ICH9_IGP_AMT 0x10BD
#define E1000_DEV_ID_ICH9_BM 0x10E5
#define E1000_DEV_ID_ICH9_IGP_M_AMT 0x10F5
#define E1000_DEV_ID_ICH9_IGP_M 0x10BF
#define E1000_DEV_ID_ICH9_IGP_M_V 0x10CB
#define E1000_DEV_ID_ICH9_IGP_C 0x294C
#define E1000_DEV_ID_ICH9_IFE 0x10C0
#define E1000_DEV_ID_ICH9_IFE_GT 0x10C3
#define E1000_DEV_ID_ICH9_IFE_G 0x10C2
#define E1000_DEV_ID_ICH10_R_BM_LM 0x10CC
#define E1000_DEV_ID_ICH10_R_BM_LF 0x10CD
#define E1000_DEV_ID_ICH10_R_BM_V 0x10CE
#define E1000_DEV_ID_ICH10_D_BM_LM 0x10DE
#define E1000_DEV_ID_ICH10_D_BM_LF 0x10DF
#define E1000_DEV_ID_ICH10_D_BM_V 0x1525
#define E1000_DEV_ID_PCH_M_HV_LM 0x10EA
#define E1000_DEV_ID_PCH_M_HV_LC 0x10EB
#define E1000_DEV_ID_PCH_D_HV_DM 0x10EF
#define E1000_DEV_ID_PCH_D_HV_DC 0x10F0
#define E1000_DEV_ID_PCH2_LV_LM 0x1502
#define E1000_DEV_ID_PCH2_LV_V 0x1503
#define E1000_DEV_ID_PCH_LPT_I217_LM 0x153A
#define E1000_DEV_ID_PCH_LPT_I217_V 0x153B
#define E1000_DEV_ID_PCH_LPTLP_I218_LM 0x155A
#define E1000_DEV_ID_PCH_LPTLP_I218_V 0x1559
#define E1000_DEV_ID_PCH_I218_LM2 0x15A0
#define E1000_DEV_ID_PCH_I218_V2 0x15A1
#define E1000_DEV_ID_PCH_I218_LM3 0x15A2 /* Wildcat Point PCH */
#define E1000_DEV_ID_PCH_I218_V3 0x15A3 /* Wildcat Point PCH */
#define E1000_DEV_ID_PCH_SPT_I219_LM 0x156F /* SPT PCH */
#define E1000_DEV_ID_PCH_SPT_I219_V 0x1570 /* SPT PCH */
#define E1000_DEV_ID_PCH_SPT_I219_LM2 0x15B7 /* SPT-H PCH */
#define E1000_DEV_ID_PCH_SPT_I219_V2 0x15B8 /* SPT-H PCH */
#define E1000_DEV_ID_PCH_LBG_I219_LM3 0x15B9 /* LBG PCH */
#define E1000_DEV_ID_PCH_SPT_I219_LM4 0x15D7
#define E1000_DEV_ID_PCH_SPT_I219_V4 0x15D8
#define E1000_DEV_ID_PCH_SPT_I219_LM5 0x15E3
#define E1000_DEV_ID_PCH_SPT_I219_V5 0x15D6
#define E1000_DEV_ID_PCH_CNP_I219_LM6 0x15BD
#define E1000_DEV_ID_PCH_CNP_I219_V6 0x15BE
#define E1000_DEV_ID_PCH_CNP_I219_LM7 0x15BB
#define E1000_DEV_ID_PCH_CNP_I219_V7 0x15BC
#define E1000_DEV_ID_PCH_ICP_I219_LM8 0x15DF
#define E1000_DEV_ID_PCH_ICP_I219_V8 0x15E0
#define E1000_DEV_ID_PCH_ICP_I219_LM9 0x15E1
#define E1000_DEV_ID_PCH_ICP_I219_V9 0x15E2
#define E1000_DEV_ID_PCH_CMP_I219_LM10 0x0D4E
#define E1000_DEV_ID_PCH_CMP_I219_V10 0x0D4F
#define E1000_DEV_ID_PCH_CMP_I219_LM11 0x0D4C
#define E1000_DEV_ID_PCH_CMP_I219_V11 0x0D4D
#define E1000_DEV_ID_PCH_CMP_I219_LM12 0x0D53
#define E1000_DEV_ID_PCH_CMP_I219_V12 0x0D55
#define E1000_DEV_ID_PCH_TGP_I219_LM13 0x15FB
#define E1000_DEV_ID_PCH_TGP_I219_V13 0x15FC
#define E1000_DEV_ID_PCH_TGP_I219_LM14 0x15F9
#define E1000_DEV_ID_PCH_TGP_I219_V14 0x15FA
#define E1000_DEV_ID_PCH_TGP_I219_LM15 0x15F4
#define E1000_DEV_ID_PCH_TGP_I219_V15 0x15F5
#define E1000_DEV_ID_PCH_RPL_I219_LM23 0x0DC5
#define E1000_DEV_ID_PCH_RPL_I219_V23 0x0DC6
#define E1000_DEV_ID_PCH_ADP_I219_LM16 0x1A1E
#define E1000_DEV_ID_PCH_ADP_I219_V16 0x1A1F
#define E1000_DEV_ID_PCH_ADP_I219_LM17 0x1A1C
#define E1000_DEV_ID_PCH_ADP_I219_V17 0x1A1D
#define E1000_DEV_ID_PCH_RPL_I219_LM22 0x0DC7
#define E1000_DEV_ID_PCH_RPL_I219_V22 0x0DC8
#define E1000_DEV_ID_PCH_MTP_I219_LM18 0x550A
#define E1000_DEV_ID_PCH_MTP_I219_V18 0x550B
#define E1000_DEV_ID_PCH_MTP_I219_LM19 0x550C
#define E1000_DEV_ID_PCH_MTP_I219_V19 0x550D
#define E1000_DEV_ID_PCH_LNP_I219_LM20 0x550E
#define E1000_DEV_ID_PCH_LNP_I219_V20 0x550F
#define E1000_DEV_ID_PCH_LNP_I219_LM21 0x5510
#define E1000_DEV_ID_PCH_LNP_I219_V21 0x5511
#define E1000_DEV_ID_PCH_ARL_I219_LM24 0x57A0
#define E1000_DEV_ID_PCH_ARL_I219_V24 0x57A1
#define E1000_DEV_ID_PCH_PTP_I219_LM25 0x57B3
#define E1000_DEV_ID_PCH_PTP_I219_V25 0x57B4
#define E1000_DEV_ID_PCH_PTP_I219_LM26 0x57B5
#define E1000_DEV_ID_PCH_PTP_I219_V26 0x57B6
#define E1000_DEV_ID_PCH_PTP_I219_LM27 0x57B7
#define E1000_DEV_ID_PCH_PTP_I219_V27 0x57B8
#define E1000_REVISION_4 4
#define E1000_FUNC_1 1
#define E1000_ALT_MAC_ADDRESS_OFFSET_LAN0 0
#define E1000_ALT_MAC_ADDRESS_OFFSET_LAN1 3
enum e1000_mac_type {
e1000_82571,
e1000_82572,
e1000_82573,
e1000_82574,
e1000_82583,
e1000_80003es2lan,
e1000_ich8lan,
e1000_ich9lan,
e1000_ich10lan,
e1000_pchlan,
e1000_pch2lan,
e1000_pch_lpt,
e1000_pch_spt,
e1000_pch_cnp,
e1000_pch_tgp,
e1000_pch_adp,
e1000_pch_mtp,
e1000_pch_lnp,
e1000_pch_ptp,
};
enum e1000_media_type {
e1000_media_type_unknown = 0,
e1000_media_type_copper = 1,
e1000_media_type_fiber = 2,
e1000_media_type_internal_serdes = 3,
e1000_num_media_types
};
enum e1000_nvm_type {
e1000_nvm_unknown = 0,
e1000_nvm_none,
e1000_nvm_eeprom_spi,
e1000_nvm_flash_hw,
e1000_nvm_flash_sw
};
enum e1000_nvm_override {
e1000_nvm_override_none = 0,
e1000_nvm_override_spi_small,
e1000_nvm_override_spi_large
};
enum e1000_phy_type {
e1000_phy_unknown = 0,
e1000_phy_none,
e1000_phy_m88,
e1000_phy_igp,
e1000_phy_igp_2,
e1000_phy_gg82563,
e1000_phy_igp_3,
e1000_phy_ife,
e1000_phy_bm,
e1000_phy_82578,
e1000_phy_82577,
e1000_phy_82579,
e1000_phy_i217,
};
enum e1000_bus_width {
e1000_bus_width_unknown = 0,
e1000_bus_width_pcie_x1,
e1000_bus_width_pcie_x2,
e1000_bus_width_pcie_x4 = 4,
e1000_bus_width_pcie_x8 = 8,
e1000_bus_width_32,
e1000_bus_width_64,
e1000_bus_width_reserved
};
enum e1000_1000t_rx_status {
e1000_1000t_rx_status_not_ok = 0,
e1000_1000t_rx_status_ok,
e1000_1000t_rx_status_undefined = 0xFF
};
enum e1000_rev_polarity {
e1000_rev_polarity_normal = 0,
e1000_rev_polarity_reversed,
e1000_rev_polarity_undefined = 0xFF
};
enum e1000_fc_mode {
e1000_fc_none = 0,
e1000_fc_rx_pause,
e1000_fc_tx_pause,
e1000_fc_full,
e1000_fc_default = 0xFF
};
enum e1000_ms_type {
e1000_ms_hw_default = 0,
e1000_ms_force_master,
e1000_ms_force_slave,
e1000_ms_auto
};
enum e1000_smart_speed {
e1000_smart_speed_default = 0,
e1000_smart_speed_on,
e1000_smart_speed_off
};
enum e1000_serdes_link_state {
e1000_serdes_link_down = 0,
e1000_serdes_link_autoneg_progress,
e1000_serdes_link_autoneg_complete,
e1000_serdes_link_forced_up
};
/* Receive Descriptor - Extended */
union e1000_rx_desc_extended {
struct {
__le64 buffer_addr;
__le64 reserved;
} read;
struct {
struct {
__le32 mrq; /* Multiple Rx Queues */
union {
__le32 rss; /* RSS Hash */
struct {
__le16 ip_id; /* IP id */
__le16 csum; /* Packet Checksum */
} csum_ip;
} hi_dword;
} lower;
struct {
__le32 status_error; /* ext status/error */
__le16 length;
__le16 vlan; /* VLAN tag */
} upper;
} wb; /* writeback */
};
#define MAX_PS_BUFFERS 4
/* Number of packet split data buffers (not including the header buffer) */
#define PS_PAGE_BUFFERS (MAX_PS_BUFFERS - 1)
/* Receive Descriptor - Packet Split */
union e1000_rx_desc_packet_split {
struct {
/* one buffer for protocol header(s), three data buffers */
__le64 buffer_addr[MAX_PS_BUFFERS];
} read;
struct {
struct {
__le32 mrq; /* Multiple Rx Queues */
union {
__le32 rss; /* RSS Hash */
struct {
__le16 ip_id; /* IP id */
__le16 csum; /* Packet Checksum */
} csum_ip;
} hi_dword;
} lower;
struct {
__le32 status_error; /* ext status/error */
__le16 length0; /* length of buffer 0 */
__le16 vlan; /* VLAN tag */
} middle;
struct {
__le16 header_status;
/* length of buffers 1-3 */
__le16 length[PS_PAGE_BUFFERS];
} upper;
__le64 reserved;
} wb; /* writeback */
};
/* Transmit Descriptor */
struct e1000_tx_desc {
__le64 buffer_addr; /* Address of the descriptor's data buffer */
union {
__le32 data;
struct {
__le16 length; /* Data buffer length */
u8 cso; /* Checksum offset */
u8 cmd; /* Descriptor control */
} flags;
} lower;
union {
__le32 data;
struct {
u8 status; /* Descriptor status */
u8 css; /* Checksum start */
__le16 special;
} fields;
} upper;
};
/* Offload Context Descriptor */
struct e1000_context_desc {
union {
__le32 ip_config;
struct {
u8 ipcss; /* IP checksum start */
u8 ipcso; /* IP checksum offset */
__le16 ipcse; /* IP checksum end */
} ip_fields;
} lower_setup;
union {
__le32 tcp_config;
struct {
u8 tucss; /* TCP checksum start */
u8 tucso; /* TCP checksum offset */
__le16 tucse; /* TCP checksum end */
} tcp_fields;
} upper_setup;
__le32 cmd_and_length;
union {
__le32 data;
struct {
u8 status; /* Descriptor status */
u8 hdr_len; /* Header length */
__le16 mss; /* Maximum segment size */
} fields;
} tcp_seg_setup;
};
/* Offload data descriptor */
struct e1000_data_desc {
__le64 buffer_addr; /* Address of the descriptor's buffer address */
union {
__le32 data;
struct {
__le16 length; /* Data buffer length */
u8 typ_len_ext;
u8 cmd;
} flags;
} lower;
union {
__le32 data;
struct {
u8 status; /* Descriptor status */
u8 popts; /* Packet Options */
__le16 special;
} fields;
} upper;
};
/* Statistics counters collected by the MAC */
struct e1000_hw_stats {
u64 crcerrs;
u64 algnerrc;
u64 symerrs;
u64 rxerrc;
u64 mpc;
u64 scc;
u64 ecol;
u64 mcc;
u64 latecol;
u64 colc;
u64 dc;
u64 tncrs;
u64 sec;
u64 cexterr;
u64 rlec;
u64 xonrxc;
u64 xontxc;
u64 xoffrxc;
u64 xofftxc;
u64 fcruc;
u64 prc64;
u64 prc127;
u64 prc255;
u64 prc511;
u64 prc1023;
u64 prc1522;
u64 gprc;
u64 bprc;
u64 mprc;
u64 gptc;
u64 gorc;
u64 gotc;
u64 rnbc;
u64 ruc;
u64 rfc;
u64 roc;
u64 rjc;
u64 mgprc;
u64 mgpdc;
u64 mgptc;
u64 tor;
u64 tot;
u64 tpr;
u64 tpt;
u64 ptc64;
u64 ptc127;
u64 ptc255;
u64 ptc511;
u64 ptc1023;
u64 ptc1522;
u64 mptc;
u64 bptc;
u64 tsctc;
u64 tsctfc;
u64 iac;
u64 icrxptc;
u64 icrxatc;
u64 ictxptc;
u64 ictxatc;
u64 ictxqec;
u64 ictxqmtc;
u64 icrxdmtc;
u64 icrxoc;
};
struct e1000_phy_stats {
u32 idle_errors;
u32 receive_errors;
};
struct e1000_host_mng_dhcp_cookie {
u32 signature;
u8 status;
u8 reserved0;
u16 vlan_id;
u32 reserved1;
u16 reserved2;
u8 reserved3;
u8 checksum;
};
/* Host Interface "Rev 1" */
struct e1000_host_command_header {
u8 command_id;
u8 command_length;
u8 command_options;
u8 checksum;
};
#define E1000_HI_MAX_DATA_LENGTH 252
struct e1000_host_command_info {
struct e1000_host_command_header command_header;
u8 command_data[E1000_HI_MAX_DATA_LENGTH];
};
/* Host Interface "Rev 2" */
struct e1000_host_mng_command_header {
u8 command_id;
u8 checksum;
u16 reserved1;
u16 reserved2;
u16 command_length;
};
#define E1000_HI_MAX_MNG_DATA_LENGTH 0x6F8
struct e1000_host_mng_command_info {
struct e1000_host_mng_command_header command_header;
u8 command_data[E1000_HI_MAX_MNG_DATA_LENGTH];
};
#include "mac-6.4-ethercat.h"
#include "phy-6.4-ethercat.h"
#include "nvm-6.4-ethercat.h"
#include "manage-6.4-ethercat.h"
/* Function pointers for the MAC. */
struct e1000_mac_operations {
s32 (*id_led_init)(struct e1000_hw *);
s32 (*blink_led)(struct e1000_hw *);
bool (*check_mng_mode)(struct e1000_hw *);
s32 (*check_for_link)(struct e1000_hw *);
s32 (*cleanup_led)(struct e1000_hw *);
void (*clear_hw_cntrs)(struct e1000_hw *);
void (*clear_vfta)(struct e1000_hw *);
s32 (*get_bus_info)(struct e1000_hw *);
void (*set_lan_id)(struct e1000_hw *);
s32 (*get_link_up_info)(struct e1000_hw *, u16 *, u16 *);
s32 (*led_on)(struct e1000_hw *);
s32 (*led_off)(struct e1000_hw *);
void (*update_mc_addr_list)(struct e1000_hw *, u8 *, u32);
s32 (*reset_hw)(struct e1000_hw *);
s32 (*init_hw)(struct e1000_hw *);
s32 (*setup_link)(struct e1000_hw *);
s32 (*setup_physical_interface)(struct e1000_hw *);
s32 (*setup_led)(struct e1000_hw *);
void (*write_vfta)(struct e1000_hw *, u32, u32);
void (*config_collision_dist)(struct e1000_hw *);
int (*rar_set)(struct e1000_hw *, u8 *, u32);
s32 (*read_mac_addr)(struct e1000_hw *);
u32 (*rar_get_count)(struct e1000_hw *);
};
/* When to use various PHY register access functions:
*
* Func Caller
* Function Does Does When to use
* ~~~~~~~~~~~~ ~~~~~ ~~~~~~ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
* X_reg L,P,A n/a for simple PHY reg accesses
* X_reg_locked P,A L for multiple accesses of different regs
* on different pages
* X_reg_page A L,P for multiple accesses of different regs
* on the same page
*
* Where X=[read|write], L=locking, P=sets page, A=register access
*
*/
struct e1000_phy_operations {
s32 (*acquire)(struct e1000_hw *);
s32 (*cfg_on_link_up)(struct e1000_hw *);
s32 (*check_polarity)(struct e1000_hw *);
s32 (*check_reset_block)(struct e1000_hw *);
s32 (*commit)(struct e1000_hw *);
s32 (*force_speed_duplex)(struct e1000_hw *);
s32 (*get_cfg_done)(struct e1000_hw *hw);
s32 (*get_cable_length)(struct e1000_hw *);
s32 (*get_info)(struct e1000_hw *);
s32 (*set_page)(struct e1000_hw *, u16);
s32 (*read_reg)(struct e1000_hw *, u32, u16 *);
s32 (*read_reg_locked)(struct e1000_hw *, u32, u16 *);
s32 (*read_reg_page)(struct e1000_hw *, u32, u16 *);
void (*release)(struct e1000_hw *);
s32 (*reset)(struct e1000_hw *);
s32 (*set_d0_lplu_state)(struct e1000_hw *, bool);
s32 (*set_d3_lplu_state)(struct e1000_hw *, bool);
s32 (*write_reg)(struct e1000_hw *, u32, u16);
s32 (*write_reg_locked)(struct e1000_hw *, u32, u16);
s32 (*write_reg_page)(struct e1000_hw *, u32, u16);
void (*power_up)(struct e1000_hw *);
void (*power_down)(struct e1000_hw *);
};
/* Function pointers for the NVM. */
struct e1000_nvm_operations {
s32 (*acquire)(struct e1000_hw *);
s32 (*read)(struct e1000_hw *, u16, u16, u16 *);
void (*release)(struct e1000_hw *);
void (*reload)(struct e1000_hw *);
s32 (*update)(struct e1000_hw *);
s32 (*valid_led_default)(struct e1000_hw *, u16 *);
s32 (*validate)(struct e1000_hw *);
s32 (*write)(struct e1000_hw *, u16, u16, u16 *);
};
struct e1000_mac_info {
struct e1000_mac_operations ops;
u8 addr[ETH_ALEN];
u8 perm_addr[ETH_ALEN];
enum e1000_mac_type type;
u32 collision_delta;
u32 ledctl_default;
u32 ledctl_mode1;
u32 ledctl_mode2;
u32 mc_filter_type;
u32 tx_packet_delta;
u32 txcw;
u16 current_ifs_val;
u16 ifs_max_val;
u16 ifs_min_val;
u16 ifs_ratio;
u16 ifs_step_size;
u16 mta_reg_count;
/* Maximum size of the MTA register table in all supported adapters */
#define MAX_MTA_REG 128
u32 mta_shadow[MAX_MTA_REG];
u16 rar_entry_count;
u8 forced_speed_duplex;
bool adaptive_ifs;
bool has_fwsm;
bool arc_subsystem_valid;
bool autoneg;
bool autoneg_failed;
bool get_link_status;
bool in_ifs_mode;
bool serdes_has_link;
bool tx_pkt_filtering;
enum e1000_serdes_link_state serdes_link_state;
};
struct e1000_phy_info {
struct e1000_phy_operations ops;
enum e1000_phy_type type;
enum e1000_1000t_rx_status local_rx;
enum e1000_1000t_rx_status remote_rx;
enum e1000_ms_type ms_type;
enum e1000_ms_type original_ms_type;
enum e1000_rev_polarity cable_polarity;
enum e1000_smart_speed smart_speed;
u32 addr;
u32 id;
u32 reset_delay_us; /* in usec */
u32 revision;
enum e1000_media_type media_type;
u16 autoneg_advertised;
u16 autoneg_mask;
u16 cable_length;
u16 max_cable_length;
u16 min_cable_length;
u8 mdix;
bool disable_polarity_correction;
bool is_mdix;
bool polarity_correction;
bool speed_downgraded;
bool autoneg_wait_to_complete;
};
struct e1000_nvm_info {
struct e1000_nvm_operations ops;
enum e1000_nvm_type type;
enum e1000_nvm_override override;
u32 flash_bank_size;
u32 flash_base_addr;
u16 word_size;
u16 delay_usec;
u16 address_bits;
u16 opcode_bits;
u16 page_size;
};
struct e1000_bus_info {
enum e1000_bus_width width;
u16 func;
};
struct e1000_fc_info {
u32 high_water; /* Flow control high-water mark */
u32 low_water; /* Flow control low-water mark */
u16 pause_time; /* Flow control pause timer */
u16 refresh_time; /* Flow control refresh timer */
bool send_xon; /* Flow control send XON */
bool strict_ieee; /* Strict IEEE mode */
enum e1000_fc_mode current_mode; /* FC mode in effect */
enum e1000_fc_mode requested_mode; /* FC mode requested by caller */
};
struct e1000_dev_spec_82571 {
bool laa_is_present;
u32 smb_counter;
};
struct e1000_dev_spec_80003es2lan {
bool mdic_wa_enable;
};
struct e1000_shadow_ram {
u16 value;
bool modified;
};
#define E1000_ICH8_SHADOW_RAM_WORDS 2048
/* I218 PHY Ultra Low Power (ULP) states */
enum e1000_ulp_state {
e1000_ulp_state_unknown,
e1000_ulp_state_off,
e1000_ulp_state_on,
};
struct e1000_dev_spec_ich8lan {
bool kmrn_lock_loss_workaround_enabled;
struct e1000_shadow_ram shadow_ram[E1000_ICH8_SHADOW_RAM_WORDS];
bool nvm_k1_enabled;
bool eee_disable;
u16 eee_lp_ability;
enum e1000_ulp_state ulp_state;
};
struct e1000_hw {
struct e1000_adapter *adapter;
void __iomem *hw_addr;
void __iomem *flash_address;
struct e1000_mac_info mac;
struct e1000_fc_info fc;
struct e1000_phy_info phy;
struct e1000_nvm_info nvm;
struct e1000_bus_info bus;
struct e1000_host_mng_dhcp_cookie mng_cookie;
union {
struct e1000_dev_spec_82571 e82571;
struct e1000_dev_spec_80003es2lan e80003es2lan;
struct e1000_dev_spec_ich8lan ich8lan;
} dev_spec;
};
#include "82571-6.4-ethercat.h"
#include "80003es2lan-6.4-ethercat.h"
#include "ich8lan-6.4-ethercat.h"
#endif /* _E1000E_HW_H_ */

View File

@ -0,0 +1,735 @@
/* SPDX-License-Identifier: GPL-2.0 */
/* Copyright(c) 1999 - 2018 Intel Corporation. */
#ifndef _E1000E_HW_H_
#define _E1000E_HW_H_
#include "regs.h"
#include "defines.h"
struct e1000_hw;
#define E1000_DEV_ID_82571EB_COPPER 0x105E
#define E1000_DEV_ID_82571EB_FIBER 0x105F
#define E1000_DEV_ID_82571EB_SERDES 0x1060
#define E1000_DEV_ID_82571EB_QUAD_COPPER 0x10A4
#define E1000_DEV_ID_82571PT_QUAD_COPPER 0x10D5
#define E1000_DEV_ID_82571EB_QUAD_FIBER 0x10A5
#define E1000_DEV_ID_82571EB_QUAD_COPPER_LP 0x10BC
#define E1000_DEV_ID_82571EB_SERDES_DUAL 0x10D9
#define E1000_DEV_ID_82571EB_SERDES_QUAD 0x10DA
#define E1000_DEV_ID_82572EI_COPPER 0x107D
#define E1000_DEV_ID_82572EI_FIBER 0x107E
#define E1000_DEV_ID_82572EI_SERDES 0x107F
#define E1000_DEV_ID_82572EI 0x10B9
#define E1000_DEV_ID_82573E 0x108B
#define E1000_DEV_ID_82573E_IAMT 0x108C
#define E1000_DEV_ID_82573L 0x109A
#define E1000_DEV_ID_82574L 0x10D3
#define E1000_DEV_ID_82574LA 0x10F6
#define E1000_DEV_ID_82583V 0x150C
#define E1000_DEV_ID_80003ES2LAN_COPPER_DPT 0x1096
#define E1000_DEV_ID_80003ES2LAN_SERDES_DPT 0x1098
#define E1000_DEV_ID_80003ES2LAN_COPPER_SPT 0x10BA
#define E1000_DEV_ID_80003ES2LAN_SERDES_SPT 0x10BB
#define E1000_DEV_ID_ICH8_82567V_3 0x1501
#define E1000_DEV_ID_ICH8_IGP_M_AMT 0x1049
#define E1000_DEV_ID_ICH8_IGP_AMT 0x104A
#define E1000_DEV_ID_ICH8_IGP_C 0x104B
#define E1000_DEV_ID_ICH8_IFE 0x104C
#define E1000_DEV_ID_ICH8_IFE_GT 0x10C4
#define E1000_DEV_ID_ICH8_IFE_G 0x10C5
#define E1000_DEV_ID_ICH8_IGP_M 0x104D
#define E1000_DEV_ID_ICH9_IGP_AMT 0x10BD
#define E1000_DEV_ID_ICH9_BM 0x10E5
#define E1000_DEV_ID_ICH9_IGP_M_AMT 0x10F5
#define E1000_DEV_ID_ICH9_IGP_M 0x10BF
#define E1000_DEV_ID_ICH9_IGP_M_V 0x10CB
#define E1000_DEV_ID_ICH9_IGP_C 0x294C
#define E1000_DEV_ID_ICH9_IFE 0x10C0
#define E1000_DEV_ID_ICH9_IFE_GT 0x10C3
#define E1000_DEV_ID_ICH9_IFE_G 0x10C2
#define E1000_DEV_ID_ICH10_R_BM_LM 0x10CC
#define E1000_DEV_ID_ICH10_R_BM_LF 0x10CD
#define E1000_DEV_ID_ICH10_R_BM_V 0x10CE
#define E1000_DEV_ID_ICH10_D_BM_LM 0x10DE
#define E1000_DEV_ID_ICH10_D_BM_LF 0x10DF
#define E1000_DEV_ID_ICH10_D_BM_V 0x1525
#define E1000_DEV_ID_PCH_M_HV_LM 0x10EA
#define E1000_DEV_ID_PCH_M_HV_LC 0x10EB
#define E1000_DEV_ID_PCH_D_HV_DM 0x10EF
#define E1000_DEV_ID_PCH_D_HV_DC 0x10F0
#define E1000_DEV_ID_PCH2_LV_LM 0x1502
#define E1000_DEV_ID_PCH2_LV_V 0x1503
#define E1000_DEV_ID_PCH_LPT_I217_LM 0x153A
#define E1000_DEV_ID_PCH_LPT_I217_V 0x153B
#define E1000_DEV_ID_PCH_LPTLP_I218_LM 0x155A
#define E1000_DEV_ID_PCH_LPTLP_I218_V 0x1559
#define E1000_DEV_ID_PCH_I218_LM2 0x15A0
#define E1000_DEV_ID_PCH_I218_V2 0x15A1
#define E1000_DEV_ID_PCH_I218_LM3 0x15A2 /* Wildcat Point PCH */
#define E1000_DEV_ID_PCH_I218_V3 0x15A3 /* Wildcat Point PCH */
#define E1000_DEV_ID_PCH_SPT_I219_LM 0x156F /* SPT PCH */
#define E1000_DEV_ID_PCH_SPT_I219_V 0x1570 /* SPT PCH */
#define E1000_DEV_ID_PCH_SPT_I219_LM2 0x15B7 /* SPT-H PCH */
#define E1000_DEV_ID_PCH_SPT_I219_V2 0x15B8 /* SPT-H PCH */
#define E1000_DEV_ID_PCH_LBG_I219_LM3 0x15B9 /* LBG PCH */
#define E1000_DEV_ID_PCH_SPT_I219_LM4 0x15D7
#define E1000_DEV_ID_PCH_SPT_I219_V4 0x15D8
#define E1000_DEV_ID_PCH_SPT_I219_LM5 0x15E3
#define E1000_DEV_ID_PCH_SPT_I219_V5 0x15D6
#define E1000_DEV_ID_PCH_CNP_I219_LM6 0x15BD
#define E1000_DEV_ID_PCH_CNP_I219_V6 0x15BE
#define E1000_DEV_ID_PCH_CNP_I219_LM7 0x15BB
#define E1000_DEV_ID_PCH_CNP_I219_V7 0x15BC
#define E1000_DEV_ID_PCH_ICP_I219_LM8 0x15DF
#define E1000_DEV_ID_PCH_ICP_I219_V8 0x15E0
#define E1000_DEV_ID_PCH_ICP_I219_LM9 0x15E1
#define E1000_DEV_ID_PCH_ICP_I219_V9 0x15E2
#define E1000_DEV_ID_PCH_CMP_I219_LM10 0x0D4E
#define E1000_DEV_ID_PCH_CMP_I219_V10 0x0D4F
#define E1000_DEV_ID_PCH_CMP_I219_LM11 0x0D4C
#define E1000_DEV_ID_PCH_CMP_I219_V11 0x0D4D
#define E1000_DEV_ID_PCH_CMP_I219_LM12 0x0D53
#define E1000_DEV_ID_PCH_CMP_I219_V12 0x0D55
#define E1000_DEV_ID_PCH_TGP_I219_LM13 0x15FB
#define E1000_DEV_ID_PCH_TGP_I219_V13 0x15FC
#define E1000_DEV_ID_PCH_TGP_I219_LM14 0x15F9
#define E1000_DEV_ID_PCH_TGP_I219_V14 0x15FA
#define E1000_DEV_ID_PCH_TGP_I219_LM15 0x15F4
#define E1000_DEV_ID_PCH_TGP_I219_V15 0x15F5
#define E1000_DEV_ID_PCH_RPL_I219_LM23 0x0DC5
#define E1000_DEV_ID_PCH_RPL_I219_V23 0x0DC6
#define E1000_DEV_ID_PCH_ADP_I219_LM16 0x1A1E
#define E1000_DEV_ID_PCH_ADP_I219_V16 0x1A1F
#define E1000_DEV_ID_PCH_ADP_I219_LM17 0x1A1C
#define E1000_DEV_ID_PCH_ADP_I219_V17 0x1A1D
#define E1000_DEV_ID_PCH_RPL_I219_LM22 0x0DC7
#define E1000_DEV_ID_PCH_RPL_I219_V22 0x0DC8
#define E1000_DEV_ID_PCH_MTP_I219_LM18 0x550A
#define E1000_DEV_ID_PCH_MTP_I219_V18 0x550B
#define E1000_DEV_ID_PCH_MTP_I219_LM19 0x550C
#define E1000_DEV_ID_PCH_MTP_I219_V19 0x550D
#define E1000_DEV_ID_PCH_LNP_I219_LM20 0x550E
#define E1000_DEV_ID_PCH_LNP_I219_V20 0x550F
#define E1000_DEV_ID_PCH_LNP_I219_LM21 0x5510
#define E1000_DEV_ID_PCH_LNP_I219_V21 0x5511
#define E1000_DEV_ID_PCH_ARL_I219_LM24 0x57A0
#define E1000_DEV_ID_PCH_ARL_I219_V24 0x57A1
#define E1000_DEV_ID_PCH_PTP_I219_LM25 0x57B3
#define E1000_DEV_ID_PCH_PTP_I219_V25 0x57B4
#define E1000_DEV_ID_PCH_PTP_I219_LM26 0x57B5
#define E1000_DEV_ID_PCH_PTP_I219_V26 0x57B6
#define E1000_DEV_ID_PCH_PTP_I219_LM27 0x57B7
#define E1000_DEV_ID_PCH_PTP_I219_V27 0x57B8
#define E1000_REVISION_4 4
#define E1000_FUNC_1 1
#define E1000_ALT_MAC_ADDRESS_OFFSET_LAN0 0
#define E1000_ALT_MAC_ADDRESS_OFFSET_LAN1 3
enum e1000_mac_type {
e1000_82571,
e1000_82572,
e1000_82573,
e1000_82574,
e1000_82583,
e1000_80003es2lan,
e1000_ich8lan,
e1000_ich9lan,
e1000_ich10lan,
e1000_pchlan,
e1000_pch2lan,
e1000_pch_lpt,
e1000_pch_spt,
e1000_pch_cnp,
e1000_pch_tgp,
e1000_pch_adp,
e1000_pch_mtp,
e1000_pch_lnp,
e1000_pch_ptp,
};
enum e1000_media_type {
e1000_media_type_unknown = 0,
e1000_media_type_copper = 1,
e1000_media_type_fiber = 2,
e1000_media_type_internal_serdes = 3,
e1000_num_media_types
};
enum e1000_nvm_type {
e1000_nvm_unknown = 0,
e1000_nvm_none,
e1000_nvm_eeprom_spi,
e1000_nvm_flash_hw,
e1000_nvm_flash_sw
};
enum e1000_nvm_override {
e1000_nvm_override_none = 0,
e1000_nvm_override_spi_small,
e1000_nvm_override_spi_large
};
enum e1000_phy_type {
e1000_phy_unknown = 0,
e1000_phy_none,
e1000_phy_m88,
e1000_phy_igp,
e1000_phy_igp_2,
e1000_phy_gg82563,
e1000_phy_igp_3,
e1000_phy_ife,
e1000_phy_bm,
e1000_phy_82578,
e1000_phy_82577,
e1000_phy_82579,
e1000_phy_i217,
};
enum e1000_bus_width {
e1000_bus_width_unknown = 0,
e1000_bus_width_pcie_x1,
e1000_bus_width_pcie_x2,
e1000_bus_width_pcie_x4 = 4,
e1000_bus_width_pcie_x8 = 8,
e1000_bus_width_32,
e1000_bus_width_64,
e1000_bus_width_reserved
};
enum e1000_1000t_rx_status {
e1000_1000t_rx_status_not_ok = 0,
e1000_1000t_rx_status_ok,
e1000_1000t_rx_status_undefined = 0xFF
};
enum e1000_rev_polarity {
e1000_rev_polarity_normal = 0,
e1000_rev_polarity_reversed,
e1000_rev_polarity_undefined = 0xFF
};
enum e1000_fc_mode {
e1000_fc_none = 0,
e1000_fc_rx_pause,
e1000_fc_tx_pause,
e1000_fc_full,
e1000_fc_default = 0xFF
};
enum e1000_ms_type {
e1000_ms_hw_default = 0,
e1000_ms_force_master,
e1000_ms_force_slave,
e1000_ms_auto
};
enum e1000_smart_speed {
e1000_smart_speed_default = 0,
e1000_smart_speed_on,
e1000_smart_speed_off
};
enum e1000_serdes_link_state {
e1000_serdes_link_down = 0,
e1000_serdes_link_autoneg_progress,
e1000_serdes_link_autoneg_complete,
e1000_serdes_link_forced_up
};
/* Receive Descriptor - Extended */
union e1000_rx_desc_extended {
struct {
__le64 buffer_addr;
__le64 reserved;
} read;
struct {
struct {
__le32 mrq; /* Multiple Rx Queues */
union {
__le32 rss; /* RSS Hash */
struct {
__le16 ip_id; /* IP id */
__le16 csum; /* Packet Checksum */
} csum_ip;
} hi_dword;
} lower;
struct {
__le32 status_error; /* ext status/error */
__le16 length;
__le16 vlan; /* VLAN tag */
} upper;
} wb; /* writeback */
};
#define MAX_PS_BUFFERS 4
/* Number of packet split data buffers (not including the header buffer) */
#define PS_PAGE_BUFFERS (MAX_PS_BUFFERS - 1)
/* Receive Descriptor - Packet Split */
union e1000_rx_desc_packet_split {
struct {
/* one buffer for protocol header(s), three data buffers */
__le64 buffer_addr[MAX_PS_BUFFERS];
} read;
struct {
struct {
__le32 mrq; /* Multiple Rx Queues */
union {
__le32 rss; /* RSS Hash */
struct {
__le16 ip_id; /* IP id */
__le16 csum; /* Packet Checksum */
} csum_ip;
} hi_dword;
} lower;
struct {
__le32 status_error; /* ext status/error */
__le16 length0; /* length of buffer 0 */
__le16 vlan; /* VLAN tag */
} middle;
struct {
__le16 header_status;
/* length of buffers 1-3 */
__le16 length[PS_PAGE_BUFFERS];
} upper;
__le64 reserved;
} wb; /* writeback */
};
/* Transmit Descriptor */
struct e1000_tx_desc {
__le64 buffer_addr; /* Address of the descriptor's data buffer */
union {
__le32 data;
struct {
__le16 length; /* Data buffer length */
u8 cso; /* Checksum offset */
u8 cmd; /* Descriptor control */
} flags;
} lower;
union {
__le32 data;
struct {
u8 status; /* Descriptor status */
u8 css; /* Checksum start */
__le16 special;
} fields;
} upper;
};
/* Offload Context Descriptor */
struct e1000_context_desc {
union {
__le32 ip_config;
struct {
u8 ipcss; /* IP checksum start */
u8 ipcso; /* IP checksum offset */
__le16 ipcse; /* IP checksum end */
} ip_fields;
} lower_setup;
union {
__le32 tcp_config;
struct {
u8 tucss; /* TCP checksum start */
u8 tucso; /* TCP checksum offset */
__le16 tucse; /* TCP checksum end */
} tcp_fields;
} upper_setup;
__le32 cmd_and_length;
union {
__le32 data;
struct {
u8 status; /* Descriptor status */
u8 hdr_len; /* Header length */
__le16 mss; /* Maximum segment size */
} fields;
} tcp_seg_setup;
};
/* Offload data descriptor */
struct e1000_data_desc {
__le64 buffer_addr; /* Address of the descriptor's buffer address */
union {
__le32 data;
struct {
__le16 length; /* Data buffer length */
u8 typ_len_ext;
u8 cmd;
} flags;
} lower;
union {
__le32 data;
struct {
u8 status; /* Descriptor status */
u8 popts; /* Packet Options */
__le16 special;
} fields;
} upper;
};
/* Statistics counters collected by the MAC */
struct e1000_hw_stats {
u64 crcerrs;
u64 algnerrc;
u64 symerrs;
u64 rxerrc;
u64 mpc;
u64 scc;
u64 ecol;
u64 mcc;
u64 latecol;
u64 colc;
u64 dc;
u64 tncrs;
u64 sec;
u64 cexterr;
u64 rlec;
u64 xonrxc;
u64 xontxc;
u64 xoffrxc;
u64 xofftxc;
u64 fcruc;
u64 prc64;
u64 prc127;
u64 prc255;
u64 prc511;
u64 prc1023;
u64 prc1522;
u64 gprc;
u64 bprc;
u64 mprc;
u64 gptc;
u64 gorc;
u64 gotc;
u64 rnbc;
u64 ruc;
u64 rfc;
u64 roc;
u64 rjc;
u64 mgprc;
u64 mgpdc;
u64 mgptc;
u64 tor;
u64 tot;
u64 tpr;
u64 tpt;
u64 ptc64;
u64 ptc127;
u64 ptc255;
u64 ptc511;
u64 ptc1023;
u64 ptc1522;
u64 mptc;
u64 bptc;
u64 tsctc;
u64 tsctfc;
u64 iac;
u64 icrxptc;
u64 icrxatc;
u64 ictxptc;
u64 ictxatc;
u64 ictxqec;
u64 ictxqmtc;
u64 icrxdmtc;
u64 icrxoc;
};
struct e1000_phy_stats {
u32 idle_errors;
u32 receive_errors;
};
struct e1000_host_mng_dhcp_cookie {
u32 signature;
u8 status;
u8 reserved0;
u16 vlan_id;
u32 reserved1;
u16 reserved2;
u8 reserved3;
u8 checksum;
};
/* Host Interface "Rev 1" */
struct e1000_host_command_header {
u8 command_id;
u8 command_length;
u8 command_options;
u8 checksum;
};
#define E1000_HI_MAX_DATA_LENGTH 252
struct e1000_host_command_info {
struct e1000_host_command_header command_header;
u8 command_data[E1000_HI_MAX_DATA_LENGTH];
};
/* Host Interface "Rev 2" */
struct e1000_host_mng_command_header {
u8 command_id;
u8 checksum;
u16 reserved1;
u16 reserved2;
u16 command_length;
};
#define E1000_HI_MAX_MNG_DATA_LENGTH 0x6F8
struct e1000_host_mng_command_info {
struct e1000_host_mng_command_header command_header;
u8 command_data[E1000_HI_MAX_MNG_DATA_LENGTH];
};
#include "mac.h"
#include "phy.h"
#include "nvm.h"
#include "manage.h"
/* Function pointers for the MAC. */
struct e1000_mac_operations {
s32 (*id_led_init)(struct e1000_hw *);
s32 (*blink_led)(struct e1000_hw *);
bool (*check_mng_mode)(struct e1000_hw *);
s32 (*check_for_link)(struct e1000_hw *);
s32 (*cleanup_led)(struct e1000_hw *);
void (*clear_hw_cntrs)(struct e1000_hw *);
void (*clear_vfta)(struct e1000_hw *);
s32 (*get_bus_info)(struct e1000_hw *);
void (*set_lan_id)(struct e1000_hw *);
s32 (*get_link_up_info)(struct e1000_hw *, u16 *, u16 *);
s32 (*led_on)(struct e1000_hw *);
s32 (*led_off)(struct e1000_hw *);
void (*update_mc_addr_list)(struct e1000_hw *, u8 *, u32);
s32 (*reset_hw)(struct e1000_hw *);
s32 (*init_hw)(struct e1000_hw *);
s32 (*setup_link)(struct e1000_hw *);
s32 (*setup_physical_interface)(struct e1000_hw *);
s32 (*setup_led)(struct e1000_hw *);
void (*write_vfta)(struct e1000_hw *, u32, u32);
void (*config_collision_dist)(struct e1000_hw *);
int (*rar_set)(struct e1000_hw *, u8 *, u32);
s32 (*read_mac_addr)(struct e1000_hw *);
u32 (*rar_get_count)(struct e1000_hw *);
};
/* When to use various PHY register access functions:
*
* Func Caller
* Function Does Does When to use
* ~~~~~~~~~~~~ ~~~~~ ~~~~~~ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
* X_reg L,P,A n/a for simple PHY reg accesses
* X_reg_locked P,A L for multiple accesses of different regs
* on different pages
* X_reg_page A L,P for multiple accesses of different regs
* on the same page
*
* Where X=[read|write], L=locking, P=sets page, A=register access
*
*/
struct e1000_phy_operations {
s32 (*acquire)(struct e1000_hw *);
s32 (*cfg_on_link_up)(struct e1000_hw *);
s32 (*check_polarity)(struct e1000_hw *);
s32 (*check_reset_block)(struct e1000_hw *);
s32 (*commit)(struct e1000_hw *);
s32 (*force_speed_duplex)(struct e1000_hw *);
s32 (*get_cfg_done)(struct e1000_hw *hw);
s32 (*get_cable_length)(struct e1000_hw *);
s32 (*get_info)(struct e1000_hw *);
s32 (*set_page)(struct e1000_hw *, u16);
s32 (*read_reg)(struct e1000_hw *, u32, u16 *);
s32 (*read_reg_locked)(struct e1000_hw *, u32, u16 *);
s32 (*read_reg_page)(struct e1000_hw *, u32, u16 *);
void (*release)(struct e1000_hw *);
s32 (*reset)(struct e1000_hw *);
s32 (*set_d0_lplu_state)(struct e1000_hw *, bool);
s32 (*set_d3_lplu_state)(struct e1000_hw *, bool);
s32 (*write_reg)(struct e1000_hw *, u32, u16);
s32 (*write_reg_locked)(struct e1000_hw *, u32, u16);
s32 (*write_reg_page)(struct e1000_hw *, u32, u16);
void (*power_up)(struct e1000_hw *);
void (*power_down)(struct e1000_hw *);
};
/* Function pointers for the NVM. */
struct e1000_nvm_operations {
s32 (*acquire)(struct e1000_hw *);
s32 (*read)(struct e1000_hw *, u16, u16, u16 *);
void (*release)(struct e1000_hw *);
void (*reload)(struct e1000_hw *);
s32 (*update)(struct e1000_hw *);
s32 (*valid_led_default)(struct e1000_hw *, u16 *);
s32 (*validate)(struct e1000_hw *);
s32 (*write)(struct e1000_hw *, u16, u16, u16 *);
};
struct e1000_mac_info {
struct e1000_mac_operations ops;
u8 addr[ETH_ALEN];
u8 perm_addr[ETH_ALEN];
enum e1000_mac_type type;
u32 collision_delta;
u32 ledctl_default;
u32 ledctl_mode1;
u32 ledctl_mode2;
u32 mc_filter_type;
u32 tx_packet_delta;
u32 txcw;
u16 current_ifs_val;
u16 ifs_max_val;
u16 ifs_min_val;
u16 ifs_ratio;
u16 ifs_step_size;
u16 mta_reg_count;
/* Maximum size of the MTA register table in all supported adapters */
#define MAX_MTA_REG 128
u32 mta_shadow[MAX_MTA_REG];
u16 rar_entry_count;
u8 forced_speed_duplex;
bool adaptive_ifs;
bool has_fwsm;
bool arc_subsystem_valid;
bool autoneg;
bool autoneg_failed;
bool get_link_status;
bool in_ifs_mode;
bool serdes_has_link;
bool tx_pkt_filtering;
enum e1000_serdes_link_state serdes_link_state;
};
struct e1000_phy_info {
struct e1000_phy_operations ops;
enum e1000_phy_type type;
enum e1000_1000t_rx_status local_rx;
enum e1000_1000t_rx_status remote_rx;
enum e1000_ms_type ms_type;
enum e1000_ms_type original_ms_type;
enum e1000_rev_polarity cable_polarity;
enum e1000_smart_speed smart_speed;
u32 addr;
u32 id;
u32 reset_delay_us; /* in usec */
u32 revision;
enum e1000_media_type media_type;
u16 autoneg_advertised;
u16 autoneg_mask;
u16 cable_length;
u16 max_cable_length;
u16 min_cable_length;
u8 mdix;
bool disable_polarity_correction;
bool is_mdix;
bool polarity_correction;
bool speed_downgraded;
bool autoneg_wait_to_complete;
};
struct e1000_nvm_info {
struct e1000_nvm_operations ops;
enum e1000_nvm_type type;
enum e1000_nvm_override override;
u32 flash_bank_size;
u32 flash_base_addr;
u16 word_size;
u16 delay_usec;
u16 address_bits;
u16 opcode_bits;
u16 page_size;
};
struct e1000_bus_info {
enum e1000_bus_width width;
u16 func;
};
struct e1000_fc_info {
u32 high_water; /* Flow control high-water mark */
u32 low_water; /* Flow control low-water mark */
u16 pause_time; /* Flow control pause timer */
u16 refresh_time; /* Flow control refresh timer */
bool send_xon; /* Flow control send XON */
bool strict_ieee; /* Strict IEEE mode */
enum e1000_fc_mode current_mode; /* FC mode in effect */
enum e1000_fc_mode requested_mode; /* FC mode requested by caller */
};
struct e1000_dev_spec_82571 {
bool laa_is_present;
u32 smb_counter;
};
struct e1000_dev_spec_80003es2lan {
bool mdic_wa_enable;
};
struct e1000_shadow_ram {
u16 value;
bool modified;
};
#define E1000_ICH8_SHADOW_RAM_WORDS 2048
/* I218 PHY Ultra Low Power (ULP) states */
enum e1000_ulp_state {
e1000_ulp_state_unknown,
e1000_ulp_state_off,
e1000_ulp_state_on,
};
struct e1000_dev_spec_ich8lan {
bool kmrn_lock_loss_workaround_enabled;
struct e1000_shadow_ram shadow_ram[E1000_ICH8_SHADOW_RAM_WORDS];
bool nvm_k1_enabled;
bool eee_disable;
u16 eee_lp_ability;
enum e1000_ulp_state ulp_state;
};
struct e1000_hw {
struct e1000_adapter *adapter;
void __iomem *hw_addr;
void __iomem *flash_address;
struct e1000_mac_info mac;
struct e1000_fc_info fc;
struct e1000_phy_info phy;
struct e1000_nvm_info nvm;
struct e1000_bus_info bus;
struct e1000_host_mng_dhcp_cookie mng_cookie;
union {
struct e1000_dev_spec_82571 e82571;
struct e1000_dev_spec_80003es2lan e80003es2lan;
struct e1000_dev_spec_ich8lan ich8lan;
} dev_spec;
};
#include "82571.h"
#include "80003es2lan.h"
#include "ich8lan.h"
#endif /* _E1000E_HW_H_ */

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,309 @@
/* SPDX-License-Identifier: GPL-2.0 */
/* Copyright(c) 1999 - 2018 Intel Corporation. */
#ifndef _E1000E_ICH8LAN_H_
#define _E1000E_ICH8LAN_H_
#define ICH_FLASH_GFPREG 0x0000
#define ICH_FLASH_HSFSTS 0x0004
#define ICH_FLASH_HSFCTL 0x0006
#define ICH_FLASH_FADDR 0x0008
#define ICH_FLASH_FDATA0 0x0010
#define ICH_FLASH_PR0 0x0074
/* Requires up to 10 seconds when MNG might be accessing part. */
#define ICH_FLASH_READ_COMMAND_TIMEOUT 10000000
#define ICH_FLASH_WRITE_COMMAND_TIMEOUT 10000000
#define ICH_FLASH_ERASE_COMMAND_TIMEOUT 10000000
#define ICH_FLASH_LINEAR_ADDR_MASK 0x00FFFFFF
#define ICH_FLASH_CYCLE_REPEAT_COUNT 10
#define ICH_CYCLE_READ 0
#define ICH_CYCLE_WRITE 2
#define ICH_CYCLE_ERASE 3
#define FLASH_GFPREG_BASE_MASK 0x1FFF
#define FLASH_SECTOR_ADDR_SHIFT 12
#define ICH_FLASH_SEG_SIZE_256 256
#define ICH_FLASH_SEG_SIZE_4K 4096
#define ICH_FLASH_SEG_SIZE_8K 8192
#define ICH_FLASH_SEG_SIZE_64K 65536
#define E1000_ICH_FWSM_RSPCIPHY 0x00000040 /* Reset PHY on PCI Reset */
/* FW established a valid mode */
#define E1000_ICH_FWSM_FW_VALID 0x00008000
#define E1000_ICH_FWSM_PCIM2PCI 0x01000000 /* ME PCIm-to-PCI active */
#define E1000_ICH_FWSM_PCIM2PCI_COUNT 2000
#define E1000_ICH_MNG_IAMT_MODE 0x2
#define E1000_FWSM_WLOCK_MAC_MASK 0x0380
#define E1000_FWSM_WLOCK_MAC_SHIFT 7
#define E1000_FWSM_ULP_CFG_DONE 0x00000400 /* Low power cfg done */
#define E1000_EXFWSM_DPG_EXIT_DONE 0x00000001
/* Shared Receive Address Registers */
#define E1000_SHRAL_PCH_LPT(_i) (0x05408 + ((_i) * 8))
#define E1000_SHRAH_PCH_LPT(_i) (0x0540C + ((_i) * 8))
#define E1000_H2ME 0x05B50 /* Host to ME */
#define E1000_H2ME_START_DPG 0x00000001 /* indicate the ME of DPG */
#define E1000_H2ME_EXIT_DPG 0x00000002 /* indicate the ME exit DPG */
#define E1000_H2ME_ULP 0x00000800 /* ULP Indication Bit */
#define E1000_H2ME_ENFORCE_SETTINGS 0x00001000 /* Enforce Settings */
#define ID_LED_DEFAULT_ICH8LAN ((ID_LED_DEF1_DEF2 << 12) | \
(ID_LED_OFF1_OFF2 << 8) | \
(ID_LED_OFF1_ON2 << 4) | \
(ID_LED_DEF1_DEF2))
#define E1000_ICH_NVM_SIG_WORD 0x13u
#define E1000_ICH_NVM_SIG_MASK 0xC000u
#define E1000_ICH_NVM_VALID_SIG_MASK 0xC0u
#define E1000_ICH_NVM_SIG_VALUE 0x80u
#define E1000_ICH8_LAN_INIT_TIMEOUT 1500
/* FEXT register bit definition */
#define E1000_FEXT_PHY_CABLE_DISCONNECTED 0x00000004
#define E1000_FEXTNVM_SW_CONFIG 1
#define E1000_FEXTNVM_SW_CONFIG_ICH8M (1 << 27) /* different on ICH8M */
#define E1000_FEXTNVM3_PHY_CFG_COUNTER_MASK 0x0C000000
#define E1000_FEXTNVM3_PHY_CFG_COUNTER_50MSEC 0x08000000
#define E1000_FEXTNVM4_BEACON_DURATION_MASK 0x7
#define E1000_FEXTNVM4_BEACON_DURATION_8USEC 0x7
#define E1000_FEXTNVM4_BEACON_DURATION_16USEC 0x3
#define E1000_FEXTNVM6_REQ_PLL_CLK 0x00000100
#define E1000_FEXTNVM6_ENABLE_K1_ENTRY_CONDITION 0x00000200
#define E1000_FEXTNVM6_K1_OFF_ENABLE 0x80000000
/* bit for disabling packet buffer read */
#define E1000_FEXTNVM7_DISABLE_PB_READ 0x00040000
#define E1000_FEXTNVM7_SIDE_CLK_UNGATE 0x00000004
#define E1000_FEXTNVM7_DISABLE_SMB_PERST 0x00000020
#define E1000_FEXTNVM9_IOSFSB_CLKGATE_DIS 0x00000800
#define E1000_FEXTNVM9_IOSFSB_CLKREQ_DIS 0x00001000
#define E1000_FEXTNVM11_DISABLE_PB_READ 0x00000200
#define E1000_FEXTNVM11_DISABLE_MULR_FIX 0x00002000
/* bit24: RXDCTL thresholds granularity: 0 - cache lines, 1 - descriptors */
#define E1000_RXDCTL_THRESH_UNIT_DESC 0x01000000
#define K1_ENTRY_LATENCY 0
#define K1_MIN_TIME 1
#define NVM_SIZE_MULTIPLIER 4096 /*multiplier for NVMS field */
#define E1000_FLASH_BASE_ADDR 0xE000 /*offset of NVM access regs */
#define E1000_CTRL_EXT_NVMVS 0x3 /*NVM valid sector */
#define E1000_TARC0_CB_MULTIQ_3_REQ 0x30000000
#define E1000_TARC0_CB_MULTIQ_2_REQ 0x20000000
#define PCIE_ICH8_SNOOP_ALL PCIE_NO_SNOOP_ALL
#define E1000_ICH_RAR_ENTRIES 7
#define E1000_PCH2_RAR_ENTRIES 5 /* RAR[0], SHRA[0-3] */
#define E1000_PCH_LPT_RAR_ENTRIES 12 /* RAR[0], SHRA[0-10] */
#define PHY_PAGE_SHIFT 5
#define PHY_REG(page, reg) (((page) << PHY_PAGE_SHIFT) | \
((reg) & MAX_PHY_REG_ADDRESS))
#define IGP3_KMRN_DIAG PHY_REG(770, 19) /* KMRN Diagnostic */
#define IGP3_VR_CTRL PHY_REG(776, 18) /* Voltage Regulator Control */
#define IGP3_KMRN_DIAG_PCS_LOCK_LOSS 0x0002
#define IGP3_VR_CTRL_DEV_POWERDOWN_MODE_MASK 0x0300
#define IGP3_VR_CTRL_MODE_SHUTDOWN 0x0200
/* PHY Wakeup Registers and defines */
#define BM_PORT_GEN_CFG PHY_REG(BM_PORT_CTRL_PAGE, 17)
#define BM_RCTL PHY_REG(BM_WUC_PAGE, 0)
#define BM_WUC PHY_REG(BM_WUC_PAGE, 1)
#define BM_WUFC PHY_REG(BM_WUC_PAGE, 2)
#define BM_WUS PHY_REG(BM_WUC_PAGE, 3)
#define BM_RAR_L(_i) (BM_PHY_REG(BM_WUC_PAGE, 16 + ((_i) << 2)))
#define BM_RAR_M(_i) (BM_PHY_REG(BM_WUC_PAGE, 17 + ((_i) << 2)))
#define BM_RAR_H(_i) (BM_PHY_REG(BM_WUC_PAGE, 18 + ((_i) << 2)))
#define BM_RAR_CTRL(_i) (BM_PHY_REG(BM_WUC_PAGE, 19 + ((_i) << 2)))
#define BM_MTA(_i) (BM_PHY_REG(BM_WUC_PAGE, 128 + ((_i) << 1)))
#define BM_RCTL_UPE 0x0001 /* Unicast Promiscuous Mode */
#define BM_RCTL_MPE 0x0002 /* Multicast Promiscuous Mode */
#define BM_RCTL_MO_SHIFT 3 /* Multicast Offset Shift */
#define BM_RCTL_MO_MASK (3 << 3) /* Multicast Offset Mask */
#define BM_RCTL_BAM 0x0020 /* Broadcast Accept Mode */
#define BM_RCTL_PMCF 0x0040 /* Pass MAC Control Frames */
#define BM_RCTL_RFCE 0x0080 /* Rx Flow Control Enable */
#define HV_LED_CONFIG PHY_REG(768, 30) /* LED Configuration */
#define HV_MUX_DATA_CTRL PHY_REG(776, 16)
#define HV_MUX_DATA_CTRL_GEN_TO_MAC 0x0400
#define HV_MUX_DATA_CTRL_FORCE_SPEED 0x0004
#define HV_STATS_PAGE 778
/* Half-duplex collision counts */
#define HV_SCC_UPPER PHY_REG(HV_STATS_PAGE, 16) /* Single Collision */
#define HV_SCC_LOWER PHY_REG(HV_STATS_PAGE, 17)
#define HV_ECOL_UPPER PHY_REG(HV_STATS_PAGE, 18) /* Excessive Coll. */
#define HV_ECOL_LOWER PHY_REG(HV_STATS_PAGE, 19)
#define HV_MCC_UPPER PHY_REG(HV_STATS_PAGE, 20) /* Multiple Collision */
#define HV_MCC_LOWER PHY_REG(HV_STATS_PAGE, 21)
#define HV_LATECOL_UPPER PHY_REG(HV_STATS_PAGE, 23) /* Late Collision */
#define HV_LATECOL_LOWER PHY_REG(HV_STATS_PAGE, 24)
#define HV_COLC_UPPER PHY_REG(HV_STATS_PAGE, 25) /* Collision */
#define HV_COLC_LOWER PHY_REG(HV_STATS_PAGE, 26)
#define HV_DC_UPPER PHY_REG(HV_STATS_PAGE, 27) /* Defer Count */
#define HV_DC_LOWER PHY_REG(HV_STATS_PAGE, 28)
#define HV_TNCRS_UPPER PHY_REG(HV_STATS_PAGE, 29) /* Tx with no CRS */
#define HV_TNCRS_LOWER PHY_REG(HV_STATS_PAGE, 30)
#define E1000_FCRTV_PCH 0x05F40 /* PCH Flow Control Refresh Timer Value */
#define E1000_NVM_K1_CONFIG 0x1B /* NVM K1 Config Word */
#define E1000_NVM_K1_ENABLE 0x1 /* NVM Enable K1 bit */
/* SMBus Control Phy Register */
#define CV_SMB_CTRL PHY_REG(769, 23)
#define CV_SMB_CTRL_FORCE_SMBUS 0x0001
/* I218 Ultra Low Power Configuration 1 Register */
#define I218_ULP_CONFIG1 PHY_REG(779, 16)
#define I218_ULP_CONFIG1_START 0x0001 /* Start auto ULP config */
#define I218_ULP_CONFIG1_IND 0x0004 /* Pwr up from ULP indication */
#define I218_ULP_CONFIG1_STICKY_ULP 0x0010 /* Set sticky ULP mode */
#define I218_ULP_CONFIG1_INBAND_EXIT 0x0020 /* Inband on ULP exit */
#define I218_ULP_CONFIG1_WOL_HOST 0x0040 /* WoL Host on ULP exit */
#define I218_ULP_CONFIG1_RESET_TO_SMBUS 0x0100 /* Reset to SMBus mode */
/* enable ULP even if when phy powered down via lanphypc */
#define I218_ULP_CONFIG1_EN_ULP_LANPHYPC 0x0400
/* disable clear of sticky ULP on PERST */
#define I218_ULP_CONFIG1_DIS_CLR_STICKY_ON_PERST 0x0800
#define I218_ULP_CONFIG1_DISABLE_SMB_PERST 0x1000 /* Disable on PERST# */
/* SMBus Address Phy Register */
#define HV_SMB_ADDR PHY_REG(768, 26)
#define HV_SMB_ADDR_MASK 0x007F
#define HV_SMB_ADDR_PEC_EN 0x0200
#define HV_SMB_ADDR_VALID 0x0080
#define HV_SMB_ADDR_FREQ_MASK 0x1100
#define HV_SMB_ADDR_FREQ_LOW_SHIFT 8
#define HV_SMB_ADDR_FREQ_HIGH_SHIFT 12
/* Strapping Option Register - RO */
#define E1000_STRAP 0x0000C
#define E1000_STRAP_SMBUS_ADDRESS_MASK 0x00FE0000
#define E1000_STRAP_SMBUS_ADDRESS_SHIFT 17
#define E1000_STRAP_SMT_FREQ_MASK 0x00003000
#define E1000_STRAP_SMT_FREQ_SHIFT 12
/* OEM Bits Phy Register */
#define HV_OEM_BITS PHY_REG(768, 25)
#define HV_OEM_BITS_LPLU 0x0004 /* Low Power Link Up */
#define HV_OEM_BITS_GBE_DIS 0x0040 /* Gigabit Disable */
#define HV_OEM_BITS_RESTART_AN 0x0400 /* Restart Auto-negotiation */
/* KMRN Mode Control */
#define HV_KMRN_MODE_CTRL PHY_REG(769, 16)
#define HV_KMRN_MDIO_SLOW 0x0400
/* KMRN FIFO Control and Status */
#define HV_KMRN_FIFO_CTRLSTA PHY_REG(770, 16)
#define HV_KMRN_FIFO_CTRLSTA_PREAMBLE_MASK 0x7000
#define HV_KMRN_FIFO_CTRLSTA_PREAMBLE_SHIFT 12
/* PHY Power Management Control */
#define HV_PM_CTRL PHY_REG(770, 17)
#define HV_PM_CTRL_K1_CLK_REQ 0x200
#define HV_PM_CTRL_K1_ENABLE 0x4000
#define I217_PLL_CLOCK_GATE_REG PHY_REG(772, 28)
#define I217_PLL_CLOCK_GATE_MASK 0x07FF
#define SW_FLAG_TIMEOUT 1000 /* SW Semaphore flag timeout in ms */
/* Inband Control */
#define I217_INBAND_CTRL PHY_REG(770, 18)
#define I217_INBAND_CTRL_LINK_STAT_TX_TIMEOUT_MASK 0x3F00
#define I217_INBAND_CTRL_LINK_STAT_TX_TIMEOUT_SHIFT 8
/* Low Power Idle GPIO Control */
#define I217_LPI_GPIO_CTRL PHY_REG(772, 18)
#define I217_LPI_GPIO_CTRL_AUTO_EN_LPI 0x0800
/* PHY Low Power Idle Control */
#define I82579_LPI_CTRL PHY_REG(772, 20)
#define I82579_LPI_CTRL_100_ENABLE 0x2000
#define I82579_LPI_CTRL_1000_ENABLE 0x4000
#define I82579_LPI_CTRL_ENABLE_MASK 0x6000
#define I82579_LPI_CTRL_FORCE_PLL_LOCK_COUNT 0x80
/* Extended Management Interface (EMI) Registers */
#define I82579_EMI_ADDR 0x10
#define I82579_EMI_DATA 0x11
#define I82579_LPI_UPDATE_TIMER 0x4805 /* in 40ns units + 40 ns base value */
#define I82579_MSE_THRESHOLD 0x084F /* 82579 Mean Square Error Threshold */
#define I82577_MSE_THRESHOLD 0x0887 /* 82577 Mean Square Error Threshold */
#define I82579_MSE_LINK_DOWN 0x2411 /* MSE count before dropping link */
#define I82579_RX_CONFIG 0x3412 /* Receive configuration */
#define I82579_LPI_PLL_SHUT 0x4412 /* LPI PLL Shut Enable */
#define I82579_EEE_PCS_STATUS 0x182E /* IEEE MMD Register 3.1 >> 8 */
#define I82579_EEE_CAPABILITY 0x0410 /* IEEE MMD Register 3.20 */
#define I82579_EEE_ADVERTISEMENT 0x040E /* IEEE MMD Register 7.60 */
#define I82579_EEE_LP_ABILITY 0x040F /* IEEE MMD Register 7.61 */
#define I82579_EEE_100_SUPPORTED (1 << 1) /* 100BaseTx EEE */
#define I82579_EEE_1000_SUPPORTED (1 << 2) /* 1000BaseTx EEE */
#define I82579_LPI_100_PLL_SHUT (1 << 2) /* 100M LPI PLL Shut Enabled */
#define I217_EEE_PCS_STATUS 0x9401 /* IEEE MMD Register 3.1 */
#define I217_EEE_CAPABILITY 0x8000 /* IEEE MMD Register 3.20 */
#define I217_EEE_ADVERTISEMENT 0x8001 /* IEEE MMD Register 7.60 */
#define I217_EEE_LP_ABILITY 0x8002 /* IEEE MMD Register 7.61 */
#define I217_RX_CONFIG 0xB20C /* Receive configuration */
#define E1000_EEE_RX_LPI_RCVD 0x0400 /* Tx LP idle received */
#define E1000_EEE_TX_LPI_RCVD 0x0800 /* Rx LP idle received */
/* Intel Rapid Start Technology Support */
#define I217_PROXY_CTRL BM_PHY_REG(BM_WUC_PAGE, 70)
#define I217_PROXY_CTRL_AUTO_DISABLE 0x0080
#define I217_SxCTRL PHY_REG(BM_PORT_CTRL_PAGE, 28)
#define I217_SxCTRL_ENABLE_LPI_RESET 0x1000
#define I217_CGFREG PHY_REG(772, 29)
#define I217_CGFREG_ENABLE_MTA_RESET 0x0002
#define I217_MEMPWR PHY_REG(772, 26)
#define I217_MEMPWR_DISABLE_SMB_RELEASE 0x0010
/* Receive Address Initial CRC Calculation */
#define E1000_PCH_RAICC(_n) (0x05F50 + ((_n) * 4))
/* Latency Tolerance Reporting */
#define E1000_LTRV 0x000F8
#define E1000_LTRV_VALUE_MASK 0x000003FF
#define E1000_LTRV_SCALE_MAX 5
#define E1000_LTRV_SCALE_FACTOR 5
#define E1000_LTRV_SCALE_SHIFT 10
#define E1000_LTRV_SCALE_MASK 0x00001C00
#define E1000_LTRV_REQ_SHIFT 15
#define E1000_LTRV_NOSNOOP_SHIFT 16
#define E1000_LTRV_SEND (1 << 30)
/* Proprietary Latency Tolerance Reporting PCI Capability */
#define E1000_PCI_LTR_CAP_LPT 0xA8
/* Don't gate wake DMA clock */
#define E1000_FFLT_DBG_DONT_GATE_WAKE_DMA_CLK 0x1000
void e1000e_write_protect_nvm_ich8lan(struct e1000_hw *hw);
void e1000e_set_kmrn_lock_loss_workaround_ich8lan(struct e1000_hw *hw,
bool state);
void e1000e_igp3_phy_powerdown_workaround_ich8lan(struct e1000_hw *hw);
void e1000e_gig_downshift_workaround_ich8lan(struct e1000_hw *hw);
void e1000_suspend_workarounds_ich8lan(struct e1000_hw *hw);
void e1000_resume_workarounds_pchlan(struct e1000_hw *hw);
s32 e1000_configure_k1_ich8lan(struct e1000_hw *hw, bool k1_enable);
void e1000_copy_rx_addrs_to_phy_ich8lan(struct e1000_hw *hw);
s32 e1000_lv_jumbo_workaround_ich8lan(struct e1000_hw *hw, bool enable);
s32 e1000_read_emi_reg_locked(struct e1000_hw *hw, u16 addr, u16 *data);
s32 e1000_write_emi_reg_locked(struct e1000_hw *hw, u16 addr, u16 data);
s32 e1000_set_eee_pchlan(struct e1000_hw *hw);
s32 e1000_enable_ulp_lpt_lp(struct e1000_hw *hw, bool to_sx);
#endif /* _E1000E_ICH8LAN_H_ */

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,309 @@
/* SPDX-License-Identifier: GPL-2.0 */
/* Copyright(c) 1999 - 2018 Intel Corporation. */
#ifndef _E1000E_ICH8LAN_H_
#define _E1000E_ICH8LAN_H_
#define ICH_FLASH_GFPREG 0x0000
#define ICH_FLASH_HSFSTS 0x0004
#define ICH_FLASH_HSFCTL 0x0006
#define ICH_FLASH_FADDR 0x0008
#define ICH_FLASH_FDATA0 0x0010
#define ICH_FLASH_PR0 0x0074
/* Requires up to 10 seconds when MNG might be accessing part. */
#define ICH_FLASH_READ_COMMAND_TIMEOUT 10000000
#define ICH_FLASH_WRITE_COMMAND_TIMEOUT 10000000
#define ICH_FLASH_ERASE_COMMAND_TIMEOUT 10000000
#define ICH_FLASH_LINEAR_ADDR_MASK 0x00FFFFFF
#define ICH_FLASH_CYCLE_REPEAT_COUNT 10
#define ICH_CYCLE_READ 0
#define ICH_CYCLE_WRITE 2
#define ICH_CYCLE_ERASE 3
#define FLASH_GFPREG_BASE_MASK 0x1FFF
#define FLASH_SECTOR_ADDR_SHIFT 12
#define ICH_FLASH_SEG_SIZE_256 256
#define ICH_FLASH_SEG_SIZE_4K 4096
#define ICH_FLASH_SEG_SIZE_8K 8192
#define ICH_FLASH_SEG_SIZE_64K 65536
#define E1000_ICH_FWSM_RSPCIPHY 0x00000040 /* Reset PHY on PCI Reset */
/* FW established a valid mode */
#define E1000_ICH_FWSM_FW_VALID 0x00008000
#define E1000_ICH_FWSM_PCIM2PCI 0x01000000 /* ME PCIm-to-PCI active */
#define E1000_ICH_FWSM_PCIM2PCI_COUNT 2000
#define E1000_ICH_MNG_IAMT_MODE 0x2
#define E1000_FWSM_WLOCK_MAC_MASK 0x0380
#define E1000_FWSM_WLOCK_MAC_SHIFT 7
#define E1000_FWSM_ULP_CFG_DONE 0x00000400 /* Low power cfg done */
#define E1000_EXFWSM_DPG_EXIT_DONE 0x00000001
/* Shared Receive Address Registers */
#define E1000_SHRAL_PCH_LPT(_i) (0x05408 + ((_i) * 8))
#define E1000_SHRAH_PCH_LPT(_i) (0x0540C + ((_i) * 8))
#define E1000_H2ME 0x05B50 /* Host to ME */
#define E1000_H2ME_START_DPG 0x00000001 /* indicate the ME of DPG */
#define E1000_H2ME_EXIT_DPG 0x00000002 /* indicate the ME exit DPG */
#define E1000_H2ME_ULP 0x00000800 /* ULP Indication Bit */
#define E1000_H2ME_ENFORCE_SETTINGS 0x00001000 /* Enforce Settings */
#define ID_LED_DEFAULT_ICH8LAN ((ID_LED_DEF1_DEF2 << 12) | \
(ID_LED_OFF1_OFF2 << 8) | \
(ID_LED_OFF1_ON2 << 4) | \
(ID_LED_DEF1_DEF2))
#define E1000_ICH_NVM_SIG_WORD 0x13u
#define E1000_ICH_NVM_SIG_MASK 0xC000u
#define E1000_ICH_NVM_VALID_SIG_MASK 0xC0u
#define E1000_ICH_NVM_SIG_VALUE 0x80u
#define E1000_ICH8_LAN_INIT_TIMEOUT 1500
/* FEXT register bit definition */
#define E1000_FEXT_PHY_CABLE_DISCONNECTED 0x00000004
#define E1000_FEXTNVM_SW_CONFIG 1
#define E1000_FEXTNVM_SW_CONFIG_ICH8M (1 << 27) /* different on ICH8M */
#define E1000_FEXTNVM3_PHY_CFG_COUNTER_MASK 0x0C000000
#define E1000_FEXTNVM3_PHY_CFG_COUNTER_50MSEC 0x08000000
#define E1000_FEXTNVM4_BEACON_DURATION_MASK 0x7
#define E1000_FEXTNVM4_BEACON_DURATION_8USEC 0x7
#define E1000_FEXTNVM4_BEACON_DURATION_16USEC 0x3
#define E1000_FEXTNVM6_REQ_PLL_CLK 0x00000100
#define E1000_FEXTNVM6_ENABLE_K1_ENTRY_CONDITION 0x00000200
#define E1000_FEXTNVM6_K1_OFF_ENABLE 0x80000000
/* bit for disabling packet buffer read */
#define E1000_FEXTNVM7_DISABLE_PB_READ 0x00040000
#define E1000_FEXTNVM7_SIDE_CLK_UNGATE 0x00000004
#define E1000_FEXTNVM7_DISABLE_SMB_PERST 0x00000020
#define E1000_FEXTNVM9_IOSFSB_CLKGATE_DIS 0x00000800
#define E1000_FEXTNVM9_IOSFSB_CLKREQ_DIS 0x00001000
#define E1000_FEXTNVM11_DISABLE_PB_READ 0x00000200
#define E1000_FEXTNVM11_DISABLE_MULR_FIX 0x00002000
/* bit24: RXDCTL thresholds granularity: 0 - cache lines, 1 - descriptors */
#define E1000_RXDCTL_THRESH_UNIT_DESC 0x01000000
#define K1_ENTRY_LATENCY 0
#define K1_MIN_TIME 1
#define NVM_SIZE_MULTIPLIER 4096 /*multiplier for NVMS field */
#define E1000_FLASH_BASE_ADDR 0xE000 /*offset of NVM access regs */
#define E1000_CTRL_EXT_NVMVS 0x3 /*NVM valid sector */
#define E1000_TARC0_CB_MULTIQ_3_REQ 0x30000000
#define E1000_TARC0_CB_MULTIQ_2_REQ 0x20000000
#define PCIE_ICH8_SNOOP_ALL PCIE_NO_SNOOP_ALL
#define E1000_ICH_RAR_ENTRIES 7
#define E1000_PCH2_RAR_ENTRIES 5 /* RAR[0], SHRA[0-3] */
#define E1000_PCH_LPT_RAR_ENTRIES 12 /* RAR[0], SHRA[0-10] */
#define PHY_PAGE_SHIFT 5
#define PHY_REG(page, reg) (((page) << PHY_PAGE_SHIFT) | \
((reg) & MAX_PHY_REG_ADDRESS))
#define IGP3_KMRN_DIAG PHY_REG(770, 19) /* KMRN Diagnostic */
#define IGP3_VR_CTRL PHY_REG(776, 18) /* Voltage Regulator Control */
#define IGP3_KMRN_DIAG_PCS_LOCK_LOSS 0x0002
#define IGP3_VR_CTRL_DEV_POWERDOWN_MODE_MASK 0x0300
#define IGP3_VR_CTRL_MODE_SHUTDOWN 0x0200
/* PHY Wakeup Registers and defines */
#define BM_PORT_GEN_CFG PHY_REG(BM_PORT_CTRL_PAGE, 17)
#define BM_RCTL PHY_REG(BM_WUC_PAGE, 0)
#define BM_WUC PHY_REG(BM_WUC_PAGE, 1)
#define BM_WUFC PHY_REG(BM_WUC_PAGE, 2)
#define BM_WUS PHY_REG(BM_WUC_PAGE, 3)
#define BM_RAR_L(_i) (BM_PHY_REG(BM_WUC_PAGE, 16 + ((_i) << 2)))
#define BM_RAR_M(_i) (BM_PHY_REG(BM_WUC_PAGE, 17 + ((_i) << 2)))
#define BM_RAR_H(_i) (BM_PHY_REG(BM_WUC_PAGE, 18 + ((_i) << 2)))
#define BM_RAR_CTRL(_i) (BM_PHY_REG(BM_WUC_PAGE, 19 + ((_i) << 2)))
#define BM_MTA(_i) (BM_PHY_REG(BM_WUC_PAGE, 128 + ((_i) << 1)))
#define BM_RCTL_UPE 0x0001 /* Unicast Promiscuous Mode */
#define BM_RCTL_MPE 0x0002 /* Multicast Promiscuous Mode */
#define BM_RCTL_MO_SHIFT 3 /* Multicast Offset Shift */
#define BM_RCTL_MO_MASK (3 << 3) /* Multicast Offset Mask */
#define BM_RCTL_BAM 0x0020 /* Broadcast Accept Mode */
#define BM_RCTL_PMCF 0x0040 /* Pass MAC Control Frames */
#define BM_RCTL_RFCE 0x0080 /* Rx Flow Control Enable */
#define HV_LED_CONFIG PHY_REG(768, 30) /* LED Configuration */
#define HV_MUX_DATA_CTRL PHY_REG(776, 16)
#define HV_MUX_DATA_CTRL_GEN_TO_MAC 0x0400
#define HV_MUX_DATA_CTRL_FORCE_SPEED 0x0004
#define HV_STATS_PAGE 778
/* Half-duplex collision counts */
#define HV_SCC_UPPER PHY_REG(HV_STATS_PAGE, 16) /* Single Collision */
#define HV_SCC_LOWER PHY_REG(HV_STATS_PAGE, 17)
#define HV_ECOL_UPPER PHY_REG(HV_STATS_PAGE, 18) /* Excessive Coll. */
#define HV_ECOL_LOWER PHY_REG(HV_STATS_PAGE, 19)
#define HV_MCC_UPPER PHY_REG(HV_STATS_PAGE, 20) /* Multiple Collision */
#define HV_MCC_LOWER PHY_REG(HV_STATS_PAGE, 21)
#define HV_LATECOL_UPPER PHY_REG(HV_STATS_PAGE, 23) /* Late Collision */
#define HV_LATECOL_LOWER PHY_REG(HV_STATS_PAGE, 24)
#define HV_COLC_UPPER PHY_REG(HV_STATS_PAGE, 25) /* Collision */
#define HV_COLC_LOWER PHY_REG(HV_STATS_PAGE, 26)
#define HV_DC_UPPER PHY_REG(HV_STATS_PAGE, 27) /* Defer Count */
#define HV_DC_LOWER PHY_REG(HV_STATS_PAGE, 28)
#define HV_TNCRS_UPPER PHY_REG(HV_STATS_PAGE, 29) /* Tx with no CRS */
#define HV_TNCRS_LOWER PHY_REG(HV_STATS_PAGE, 30)
#define E1000_FCRTV_PCH 0x05F40 /* PCH Flow Control Refresh Timer Value */
#define E1000_NVM_K1_CONFIG 0x1B /* NVM K1 Config Word */
#define E1000_NVM_K1_ENABLE 0x1 /* NVM Enable K1 bit */
/* SMBus Control Phy Register */
#define CV_SMB_CTRL PHY_REG(769, 23)
#define CV_SMB_CTRL_FORCE_SMBUS 0x0001
/* I218 Ultra Low Power Configuration 1 Register */
#define I218_ULP_CONFIG1 PHY_REG(779, 16)
#define I218_ULP_CONFIG1_START 0x0001 /* Start auto ULP config */
#define I218_ULP_CONFIG1_IND 0x0004 /* Pwr up from ULP indication */
#define I218_ULP_CONFIG1_STICKY_ULP 0x0010 /* Set sticky ULP mode */
#define I218_ULP_CONFIG1_INBAND_EXIT 0x0020 /* Inband on ULP exit */
#define I218_ULP_CONFIG1_WOL_HOST 0x0040 /* WoL Host on ULP exit */
#define I218_ULP_CONFIG1_RESET_TO_SMBUS 0x0100 /* Reset to SMBus mode */
/* enable ULP even if when phy powered down via lanphypc */
#define I218_ULP_CONFIG1_EN_ULP_LANPHYPC 0x0400
/* disable clear of sticky ULP on PERST */
#define I218_ULP_CONFIG1_DIS_CLR_STICKY_ON_PERST 0x0800
#define I218_ULP_CONFIG1_DISABLE_SMB_PERST 0x1000 /* Disable on PERST# */
/* SMBus Address Phy Register */
#define HV_SMB_ADDR PHY_REG(768, 26)
#define HV_SMB_ADDR_MASK 0x007F
#define HV_SMB_ADDR_PEC_EN 0x0200
#define HV_SMB_ADDR_VALID 0x0080
#define HV_SMB_ADDR_FREQ_MASK 0x1100
#define HV_SMB_ADDR_FREQ_LOW_SHIFT 8
#define HV_SMB_ADDR_FREQ_HIGH_SHIFT 12
/* Strapping Option Register - RO */
#define E1000_STRAP 0x0000C
#define E1000_STRAP_SMBUS_ADDRESS_MASK 0x00FE0000
#define E1000_STRAP_SMBUS_ADDRESS_SHIFT 17
#define E1000_STRAP_SMT_FREQ_MASK 0x00003000
#define E1000_STRAP_SMT_FREQ_SHIFT 12
/* OEM Bits Phy Register */
#define HV_OEM_BITS PHY_REG(768, 25)
#define HV_OEM_BITS_LPLU 0x0004 /* Low Power Link Up */
#define HV_OEM_BITS_GBE_DIS 0x0040 /* Gigabit Disable */
#define HV_OEM_BITS_RESTART_AN 0x0400 /* Restart Auto-negotiation */
/* KMRN Mode Control */
#define HV_KMRN_MODE_CTRL PHY_REG(769, 16)
#define HV_KMRN_MDIO_SLOW 0x0400
/* KMRN FIFO Control and Status */
#define HV_KMRN_FIFO_CTRLSTA PHY_REG(770, 16)
#define HV_KMRN_FIFO_CTRLSTA_PREAMBLE_MASK 0x7000
#define HV_KMRN_FIFO_CTRLSTA_PREAMBLE_SHIFT 12
/* PHY Power Management Control */
#define HV_PM_CTRL PHY_REG(770, 17)
#define HV_PM_CTRL_K1_CLK_REQ 0x200
#define HV_PM_CTRL_K1_ENABLE 0x4000
#define I217_PLL_CLOCK_GATE_REG PHY_REG(772, 28)
#define I217_PLL_CLOCK_GATE_MASK 0x07FF
#define SW_FLAG_TIMEOUT 1000 /* SW Semaphore flag timeout in ms */
/* Inband Control */
#define I217_INBAND_CTRL PHY_REG(770, 18)
#define I217_INBAND_CTRL_LINK_STAT_TX_TIMEOUT_MASK 0x3F00
#define I217_INBAND_CTRL_LINK_STAT_TX_TIMEOUT_SHIFT 8
/* Low Power Idle GPIO Control */
#define I217_LPI_GPIO_CTRL PHY_REG(772, 18)
#define I217_LPI_GPIO_CTRL_AUTO_EN_LPI 0x0800
/* PHY Low Power Idle Control */
#define I82579_LPI_CTRL PHY_REG(772, 20)
#define I82579_LPI_CTRL_100_ENABLE 0x2000
#define I82579_LPI_CTRL_1000_ENABLE 0x4000
#define I82579_LPI_CTRL_ENABLE_MASK 0x6000
#define I82579_LPI_CTRL_FORCE_PLL_LOCK_COUNT 0x80
/* Extended Management Interface (EMI) Registers */
#define I82579_EMI_ADDR 0x10
#define I82579_EMI_DATA 0x11
#define I82579_LPI_UPDATE_TIMER 0x4805 /* in 40ns units + 40 ns base value */
#define I82579_MSE_THRESHOLD 0x084F /* 82579 Mean Square Error Threshold */
#define I82577_MSE_THRESHOLD 0x0887 /* 82577 Mean Square Error Threshold */
#define I82579_MSE_LINK_DOWN 0x2411 /* MSE count before dropping link */
#define I82579_RX_CONFIG 0x3412 /* Receive configuration */
#define I82579_LPI_PLL_SHUT 0x4412 /* LPI PLL Shut Enable */
#define I82579_EEE_PCS_STATUS 0x182E /* IEEE MMD Register 3.1 >> 8 */
#define I82579_EEE_CAPABILITY 0x0410 /* IEEE MMD Register 3.20 */
#define I82579_EEE_ADVERTISEMENT 0x040E /* IEEE MMD Register 7.60 */
#define I82579_EEE_LP_ABILITY 0x040F /* IEEE MMD Register 7.61 */
#define I82579_EEE_100_SUPPORTED (1 << 1) /* 100BaseTx EEE */
#define I82579_EEE_1000_SUPPORTED (1 << 2) /* 1000BaseTx EEE */
#define I82579_LPI_100_PLL_SHUT (1 << 2) /* 100M LPI PLL Shut Enabled */
#define I217_EEE_PCS_STATUS 0x9401 /* IEEE MMD Register 3.1 */
#define I217_EEE_CAPABILITY 0x8000 /* IEEE MMD Register 3.20 */
#define I217_EEE_ADVERTISEMENT 0x8001 /* IEEE MMD Register 7.60 */
#define I217_EEE_LP_ABILITY 0x8002 /* IEEE MMD Register 7.61 */
#define I217_RX_CONFIG 0xB20C /* Receive configuration */
#define E1000_EEE_RX_LPI_RCVD 0x0400 /* Tx LP idle received */
#define E1000_EEE_TX_LPI_RCVD 0x0800 /* Rx LP idle received */
/* Intel Rapid Start Technology Support */
#define I217_PROXY_CTRL BM_PHY_REG(BM_WUC_PAGE, 70)
#define I217_PROXY_CTRL_AUTO_DISABLE 0x0080
#define I217_SxCTRL PHY_REG(BM_PORT_CTRL_PAGE, 28)
#define I217_SxCTRL_ENABLE_LPI_RESET 0x1000
#define I217_CGFREG PHY_REG(772, 29)
#define I217_CGFREG_ENABLE_MTA_RESET 0x0002
#define I217_MEMPWR PHY_REG(772, 26)
#define I217_MEMPWR_DISABLE_SMB_RELEASE 0x0010
/* Receive Address Initial CRC Calculation */
#define E1000_PCH_RAICC(_n) (0x05F50 + ((_n) * 4))
/* Latency Tolerance Reporting */
#define E1000_LTRV 0x000F8
#define E1000_LTRV_VALUE_MASK 0x000003FF
#define E1000_LTRV_SCALE_MAX 5
#define E1000_LTRV_SCALE_FACTOR 5
#define E1000_LTRV_SCALE_SHIFT 10
#define E1000_LTRV_SCALE_MASK 0x00001C00
#define E1000_LTRV_REQ_SHIFT 15
#define E1000_LTRV_NOSNOOP_SHIFT 16
#define E1000_LTRV_SEND (1 << 30)
/* Proprietary Latency Tolerance Reporting PCI Capability */
#define E1000_PCI_LTR_CAP_LPT 0xA8
/* Don't gate wake DMA clock */
#define E1000_FFLT_DBG_DONT_GATE_WAKE_DMA_CLK 0x1000
void e1000e_write_protect_nvm_ich8lan(struct e1000_hw *hw);
void e1000e_set_kmrn_lock_loss_workaround_ich8lan(struct e1000_hw *hw,
bool state);
void e1000e_igp3_phy_powerdown_workaround_ich8lan(struct e1000_hw *hw);
void e1000e_gig_downshift_workaround_ich8lan(struct e1000_hw *hw);
void e1000_suspend_workarounds_ich8lan(struct e1000_hw *hw);
void e1000_resume_workarounds_pchlan(struct e1000_hw *hw);
s32 e1000_configure_k1_ich8lan(struct e1000_hw *hw, bool k1_enable);
void e1000_copy_rx_addrs_to_phy_ich8lan(struct e1000_hw *hw);
s32 e1000_lv_jumbo_workaround_ich8lan(struct e1000_hw *hw, bool enable);
s32 e1000_read_emi_reg_locked(struct e1000_hw *hw, u16 addr, u16 *data);
s32 e1000_write_emi_reg_locked(struct e1000_hw *hw, u16 addr, u16 data);
s32 e1000_set_eee_pchlan(struct e1000_hw *hw);
s32 e1000_enable_ulp_lpt_lp(struct e1000_hw *hw, bool to_sx);
#endif /* _E1000E_ICH8LAN_H_ */

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,50 @@
/* SPDX-License-Identifier: GPL-2.0 */
/* Copyright(c) 1999 - 2018 Intel Corporation. */
#ifndef _E1000E_MAC_H_
#define _E1000E_MAC_H_
s32 e1000e_blink_led_generic(struct e1000_hw *hw);
s32 e1000e_check_for_copper_link(struct e1000_hw *hw);
s32 e1000e_check_for_fiber_link(struct e1000_hw *hw);
s32 e1000e_check_for_serdes_link(struct e1000_hw *hw);
s32 e1000e_cleanup_led_generic(struct e1000_hw *hw);
s32 e1000e_config_fc_after_link_up(struct e1000_hw *hw);
s32 e1000e_disable_pcie_master(struct e1000_hw *hw);
s32 e1000e_force_mac_fc(struct e1000_hw *hw);
s32 e1000e_get_auto_rd_done(struct e1000_hw *hw);
s32 e1000e_get_bus_info_pcie(struct e1000_hw *hw);
void e1000_set_lan_id_single_port(struct e1000_hw *hw);
s32 e1000e_get_hw_semaphore(struct e1000_hw *hw);
s32 e1000e_get_speed_and_duplex_copper(struct e1000_hw *hw, u16 *speed,
u16 *duplex);
s32 e1000e_get_speed_and_duplex_fiber_serdes(struct e1000_hw *hw,
u16 *speed, u16 *duplex);
s32 e1000e_id_led_init_generic(struct e1000_hw *hw);
s32 e1000e_led_on_generic(struct e1000_hw *hw);
s32 e1000e_led_off_generic(struct e1000_hw *hw);
void e1000e_update_mc_addr_list_generic(struct e1000_hw *hw,
u8 *mc_addr_list, u32 mc_addr_count);
s32 e1000e_set_fc_watermarks(struct e1000_hw *hw);
s32 e1000e_setup_fiber_serdes_link(struct e1000_hw *hw);
s32 e1000e_setup_led_generic(struct e1000_hw *hw);
s32 e1000e_setup_link_generic(struct e1000_hw *hw);
s32 e1000e_validate_mdi_setting_generic(struct e1000_hw *hw);
s32 e1000e_validate_mdi_setting_crossover_generic(struct e1000_hw *hw);
void e1000e_clear_hw_cntrs_base(struct e1000_hw *hw);
void e1000_clear_vfta_generic(struct e1000_hw *hw);
void e1000e_init_rx_addrs(struct e1000_hw *hw, u16 rar_count);
void e1000e_put_hw_semaphore(struct e1000_hw *hw);
s32 e1000_check_alt_mac_addr_generic(struct e1000_hw *hw);
void e1000e_reset_adaptive(struct e1000_hw *hw);
void e1000e_set_pcie_no_snoop(struct e1000_hw *hw, u32 no_snoop);
void e1000e_update_adaptive(struct e1000_hw *hw);
void e1000_write_vfta_generic(struct e1000_hw *hw, u32 offset, u32 value);
void e1000_set_lan_id_multi_port_pcie(struct e1000_hw *hw);
u32 e1000e_rar_get_count_generic(struct e1000_hw *hw);
int e1000e_rar_set_generic(struct e1000_hw *hw, u8 *addr, u32 index);
void e1000e_config_collision_dist_generic(struct e1000_hw *hw);
#endif

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,50 @@
/* SPDX-License-Identifier: GPL-2.0 */
/* Copyright(c) 1999 - 2018 Intel Corporation. */
#ifndef _E1000E_MAC_H_
#define _E1000E_MAC_H_
s32 e1000e_blink_led_generic(struct e1000_hw *hw);
s32 e1000e_check_for_copper_link(struct e1000_hw *hw);
s32 e1000e_check_for_fiber_link(struct e1000_hw *hw);
s32 e1000e_check_for_serdes_link(struct e1000_hw *hw);
s32 e1000e_cleanup_led_generic(struct e1000_hw *hw);
s32 e1000e_config_fc_after_link_up(struct e1000_hw *hw);
s32 e1000e_disable_pcie_master(struct e1000_hw *hw);
s32 e1000e_force_mac_fc(struct e1000_hw *hw);
s32 e1000e_get_auto_rd_done(struct e1000_hw *hw);
s32 e1000e_get_bus_info_pcie(struct e1000_hw *hw);
void e1000_set_lan_id_single_port(struct e1000_hw *hw);
s32 e1000e_get_hw_semaphore(struct e1000_hw *hw);
s32 e1000e_get_speed_and_duplex_copper(struct e1000_hw *hw, u16 *speed,
u16 *duplex);
s32 e1000e_get_speed_and_duplex_fiber_serdes(struct e1000_hw *hw,
u16 *speed, u16 *duplex);
s32 e1000e_id_led_init_generic(struct e1000_hw *hw);
s32 e1000e_led_on_generic(struct e1000_hw *hw);
s32 e1000e_led_off_generic(struct e1000_hw *hw);
void e1000e_update_mc_addr_list_generic(struct e1000_hw *hw,
u8 *mc_addr_list, u32 mc_addr_count);
s32 e1000e_set_fc_watermarks(struct e1000_hw *hw);
s32 e1000e_setup_fiber_serdes_link(struct e1000_hw *hw);
s32 e1000e_setup_led_generic(struct e1000_hw *hw);
s32 e1000e_setup_link_generic(struct e1000_hw *hw);
s32 e1000e_validate_mdi_setting_generic(struct e1000_hw *hw);
s32 e1000e_validate_mdi_setting_crossover_generic(struct e1000_hw *hw);
void e1000e_clear_hw_cntrs_base(struct e1000_hw *hw);
void e1000_clear_vfta_generic(struct e1000_hw *hw);
void e1000e_init_rx_addrs(struct e1000_hw *hw, u16 rar_count);
void e1000e_put_hw_semaphore(struct e1000_hw *hw);
s32 e1000_check_alt_mac_addr_generic(struct e1000_hw *hw);
void e1000e_reset_adaptive(struct e1000_hw *hw);
void e1000e_set_pcie_no_snoop(struct e1000_hw *hw, u32 no_snoop);
void e1000e_update_adaptive(struct e1000_hw *hw);
void e1000_write_vfta_generic(struct e1000_hw *hw, u32 offset, u32 value);
void e1000_set_lan_id_multi_port_pcie(struct e1000_hw *hw);
u32 e1000e_rar_get_count_generic(struct e1000_hw *hw);
int e1000e_rar_set_generic(struct e1000_hw *hw, u8 *addr, u32 index);
void e1000e_config_collision_dist_generic(struct e1000_hw *hw);
#endif

View File

@ -0,0 +1,329 @@
// SPDX-License-Identifier: GPL-2.0
/* Copyright(c) 1999 - 2018 Intel Corporation. */
#include "e1000-6.4-ethercat.h"
/**
* e1000_calculate_checksum - Calculate checksum for buffer
* @buffer: pointer to EEPROM
* @length: size of EEPROM to calculate a checksum for
*
* Calculates the checksum for some buffer on a specified length. The
* checksum calculated is returned.
**/
static u8 e1000_calculate_checksum(u8 *buffer, u32 length)
{
u32 i;
u8 sum = 0;
if (!buffer)
return 0;
for (i = 0; i < length; i++)
sum += buffer[i];
return (u8)(0 - sum);
}
/**
* e1000_mng_enable_host_if - Checks host interface is enabled
* @hw: pointer to the HW structure
*
* Returns 0 upon success, else -E1000_ERR_HOST_INTERFACE_COMMAND
*
* This function checks whether the HOST IF is enabled for command operation
* and also checks whether the previous command is completed. It busy waits
* in case of previous command is not completed.
**/
static s32 e1000_mng_enable_host_if(struct e1000_hw *hw)
{
u32 hicr;
u8 i;
if (!hw->mac.arc_subsystem_valid) {
e_dbg("ARC subsystem not valid.\n");
return -E1000_ERR_HOST_INTERFACE_COMMAND;
}
/* Check that the host interface is enabled. */
hicr = er32(HICR);
if (!(hicr & E1000_HICR_EN)) {
e_dbg("E1000_HOST_EN bit disabled.\n");
return -E1000_ERR_HOST_INTERFACE_COMMAND;
}
/* check the previous command is completed */
for (i = 0; i < E1000_MNG_DHCP_COMMAND_TIMEOUT; i++) {
hicr = er32(HICR);
if (!(hicr & E1000_HICR_C))
break;
mdelay(1);
}
if (i == E1000_MNG_DHCP_COMMAND_TIMEOUT) {
e_dbg("Previous command timeout failed.\n");
return -E1000_ERR_HOST_INTERFACE_COMMAND;
}
return 0;
}
/**
* e1000e_check_mng_mode_generic - Generic check management mode
* @hw: pointer to the HW structure
*
* Reads the firmware semaphore register and returns true (>0) if
* manageability is enabled, else false (0).
**/
bool e1000e_check_mng_mode_generic(struct e1000_hw *hw)
{
u32 fwsm = er32(FWSM);
return (fwsm & E1000_FWSM_MODE_MASK) ==
(E1000_MNG_IAMT_MODE << E1000_FWSM_MODE_SHIFT);
}
/**
* e1000e_enable_tx_pkt_filtering - Enable packet filtering on Tx
* @hw: pointer to the HW structure
*
* Enables packet filtering on transmit packets if manageability is enabled
* and host interface is enabled.
**/
bool e1000e_enable_tx_pkt_filtering(struct e1000_hw *hw)
{
struct e1000_host_mng_dhcp_cookie *hdr = &hw->mng_cookie;
u32 *buffer = (u32 *)&hw->mng_cookie;
u32 offset;
s32 ret_val, hdr_csum, csum;
u8 i, len;
hw->mac.tx_pkt_filtering = true;
/* No manageability, no filtering */
if (!hw->mac.ops.check_mng_mode(hw)) {
hw->mac.tx_pkt_filtering = false;
return hw->mac.tx_pkt_filtering;
}
/* If we can't read from the host interface for whatever
* reason, disable filtering.
*/
ret_val = e1000_mng_enable_host_if(hw);
if (ret_val) {
hw->mac.tx_pkt_filtering = false;
return hw->mac.tx_pkt_filtering;
}
/* Read in the header. Length and offset are in dwords. */
len = E1000_MNG_DHCP_COOKIE_LENGTH >> 2;
offset = E1000_MNG_DHCP_COOKIE_OFFSET >> 2;
for (i = 0; i < len; i++)
*(buffer + i) = E1000_READ_REG_ARRAY(hw, E1000_HOST_IF,
offset + i);
hdr_csum = hdr->checksum;
hdr->checksum = 0;
csum = e1000_calculate_checksum((u8 *)hdr,
E1000_MNG_DHCP_COOKIE_LENGTH);
/* If either the checksums or signature don't match, then
* the cookie area isn't considered valid, in which case we
* take the safe route of assuming Tx filtering is enabled.
*/
if ((hdr_csum != csum) || (hdr->signature != E1000_IAMT_SIGNATURE)) {
hw->mac.tx_pkt_filtering = true;
return hw->mac.tx_pkt_filtering;
}
/* Cookie area is valid, make the final check for filtering. */
if (!(hdr->status & E1000_MNG_DHCP_COOKIE_STATUS_PARSING))
hw->mac.tx_pkt_filtering = false;
return hw->mac.tx_pkt_filtering;
}
/**
* e1000_mng_write_cmd_header - Writes manageability command header
* @hw: pointer to the HW structure
* @hdr: pointer to the host interface command header
*
* Writes the command header after does the checksum calculation.
**/
static s32 e1000_mng_write_cmd_header(struct e1000_hw *hw,
struct e1000_host_mng_command_header *hdr)
{
u16 i, length = sizeof(struct e1000_host_mng_command_header);
/* Write the whole command header structure with new checksum. */
hdr->checksum = e1000_calculate_checksum((u8 *)hdr, length);
length >>= 2;
/* Write the relevant command block into the ram area. */
for (i = 0; i < length; i++) {
E1000_WRITE_REG_ARRAY(hw, E1000_HOST_IF, i, *((u32 *)hdr + i));
e1e_flush();
}
return 0;
}
/**
* e1000_mng_host_if_write - Write to the manageability host interface
* @hw: pointer to the HW structure
* @buffer: pointer to the host interface buffer
* @length: size of the buffer
* @offset: location in the buffer to write to
* @sum: sum of the data (not checksum)
*
* This function writes the buffer content at the offset given on the host if.
* It also does alignment considerations to do the writes in most efficient
* way. Also fills up the sum of the buffer in *buffer parameter.
**/
static s32 e1000_mng_host_if_write(struct e1000_hw *hw, u8 *buffer,
u16 length, u16 offset, u8 *sum)
{
u8 *tmp;
u8 *bufptr = buffer;
u32 data = 0;
u16 remaining, i, j, prev_bytes;
/* sum = only sum of the data and it is not checksum */
if (length == 0 || offset + length > E1000_HI_MAX_MNG_DATA_LENGTH)
return -E1000_ERR_PARAM;
tmp = (u8 *)&data;
prev_bytes = offset & 0x3;
offset >>= 2;
if (prev_bytes) {
data = E1000_READ_REG_ARRAY(hw, E1000_HOST_IF, offset);
for (j = prev_bytes; j < sizeof(u32); j++) {
*(tmp + j) = *bufptr++;
*sum += *(tmp + j);
}
E1000_WRITE_REG_ARRAY(hw, E1000_HOST_IF, offset, data);
length -= j - prev_bytes;
offset++;
}
remaining = length & 0x3;
length -= remaining;
/* Calculate length in DWORDs */
length >>= 2;
/* The device driver writes the relevant command block into the
* ram area.
*/
for (i = 0; i < length; i++) {
for (j = 0; j < sizeof(u32); j++) {
*(tmp + j) = *bufptr++;
*sum += *(tmp + j);
}
E1000_WRITE_REG_ARRAY(hw, E1000_HOST_IF, offset + i, data);
}
if (remaining) {
for (j = 0; j < sizeof(u32); j++) {
if (j < remaining)
*(tmp + j) = *bufptr++;
else
*(tmp + j) = 0;
*sum += *(tmp + j);
}
E1000_WRITE_REG_ARRAY(hw, E1000_HOST_IF, offset + i, data);
}
return 0;
}
/**
* e1000e_mng_write_dhcp_info - Writes DHCP info to host interface
* @hw: pointer to the HW structure
* @buffer: pointer to the host interface
* @length: size of the buffer
*
* Writes the DHCP information to the host interface.
**/
s32 e1000e_mng_write_dhcp_info(struct e1000_hw *hw, u8 *buffer, u16 length)
{
struct e1000_host_mng_command_header hdr;
s32 ret_val;
u32 hicr;
hdr.command_id = E1000_MNG_DHCP_TX_PAYLOAD_CMD;
hdr.command_length = length;
hdr.reserved1 = 0;
hdr.reserved2 = 0;
hdr.checksum = 0;
/* Enable the host interface */
ret_val = e1000_mng_enable_host_if(hw);
if (ret_val)
return ret_val;
/* Populate the host interface with the contents of "buffer". */
ret_val = e1000_mng_host_if_write(hw, buffer, length,
sizeof(hdr), &(hdr.checksum));
if (ret_val)
return ret_val;
/* Write the manageability command header */
ret_val = e1000_mng_write_cmd_header(hw, &hdr);
if (ret_val)
return ret_val;
/* Tell the ARC a new command is pending. */
hicr = er32(HICR);
ew32(HICR, hicr | E1000_HICR_C);
return 0;
}
/**
* e1000e_enable_mng_pass_thru - Check if management passthrough is needed
* @hw: pointer to the HW structure
*
* Verifies the hardware needs to leave interface enabled so that frames can
* be directed to and from the management interface.
**/
bool e1000e_enable_mng_pass_thru(struct e1000_hw *hw)
{
u32 manc;
u32 fwsm, factps;
manc = er32(MANC);
if (!(manc & E1000_MANC_RCV_TCO_EN))
return false;
if (hw->mac.has_fwsm) {
fwsm = er32(FWSM);
factps = er32(FACTPS);
if (!(factps & E1000_FACTPS_MNGCG) &&
((fwsm & E1000_FWSM_MODE_MASK) ==
(e1000_mng_mode_pt << E1000_FWSM_MODE_SHIFT)))
return true;
} else if ((hw->mac.type == e1000_82574) ||
(hw->mac.type == e1000_82583)) {
u16 data;
s32 ret_val;
factps = er32(FACTPS);
ret_val = e1000_read_nvm(hw, NVM_INIT_CONTROL2_REG, 1, &data);
if (ret_val)
return false;
if (!(factps & E1000_FACTPS_MNGCG) &&
((data & E1000_NVM_INIT_CTRL2_MNGM) ==
(e1000_mng_mode_pt << 13)))
return true;
} else if ((manc & E1000_MANC_SMBUS_EN) &&
!(manc & E1000_MANC_ASF_EN)) {
return true;
}
return false;
}

View File

@ -0,0 +1,47 @@
/* SPDX-License-Identifier: GPL-2.0 */
/* Copyright(c) 1999 - 2018 Intel Corporation. */
#ifndef _E1000E_MANAGE_H_
#define _E1000E_MANAGE_H_
bool e1000e_check_mng_mode_generic(struct e1000_hw *hw);
bool e1000e_enable_tx_pkt_filtering(struct e1000_hw *hw);
s32 e1000e_mng_write_dhcp_info(struct e1000_hw *hw, u8 *buffer, u16 length);
bool e1000e_enable_mng_pass_thru(struct e1000_hw *hw);
enum e1000_mng_mode {
e1000_mng_mode_none = 0,
e1000_mng_mode_asf,
e1000_mng_mode_pt,
e1000_mng_mode_ipmi,
e1000_mng_mode_host_if_only
};
#define E1000_FACTPS_MNGCG 0x20000000
#define E1000_FWSM_MODE_MASK 0xE
#define E1000_FWSM_MODE_SHIFT 1
#define E1000_MNG_IAMT_MODE 0x3
#define E1000_MNG_DHCP_COOKIE_LENGTH 0x10
#define E1000_MNG_DHCP_COOKIE_OFFSET 0x6F0
#define E1000_MNG_DHCP_COMMAND_TIMEOUT 10
#define E1000_MNG_DHCP_TX_PAYLOAD_CMD 64
#define E1000_MNG_DHCP_COOKIE_STATUS_PARSING 0x1
#define E1000_MNG_DHCP_COOKIE_STATUS_VLAN 0x2
#define E1000_VFTA_ENTRY_SHIFT 5
#define E1000_VFTA_ENTRY_MASK 0x7F
#define E1000_VFTA_ENTRY_BIT_SHIFT_MASK 0x1F
#define E1000_HICR_EN 0x01 /* Enable bit - RO */
/* Driver sets this bit when done to put command in RAM */
#define E1000_HICR_C 0x02
#define E1000_HICR_SV 0x04 /* Status Validity */
#define E1000_HICR_FW_RESET_ENABLE 0x40
#define E1000_HICR_FW_RESET 0x80
/* Intel(R) Active Management Technology signature */
#define E1000_IAMT_SIGNATURE 0x544D4149
#endif

View File

@ -0,0 +1,329 @@
// SPDX-License-Identifier: GPL-2.0
/* Copyright(c) 1999 - 2018 Intel Corporation. */
#include "e1000.h"
/**
* e1000_calculate_checksum - Calculate checksum for buffer
* @buffer: pointer to EEPROM
* @length: size of EEPROM to calculate a checksum for
*
* Calculates the checksum for some buffer on a specified length. The
* checksum calculated is returned.
**/
static u8 e1000_calculate_checksum(u8 *buffer, u32 length)
{
u32 i;
u8 sum = 0;
if (!buffer)
return 0;
for (i = 0; i < length; i++)
sum += buffer[i];
return (u8)(0 - sum);
}
/**
* e1000_mng_enable_host_if - Checks host interface is enabled
* @hw: pointer to the HW structure
*
* Returns 0 upon success, else -E1000_ERR_HOST_INTERFACE_COMMAND
*
* This function checks whether the HOST IF is enabled for command operation
* and also checks whether the previous command is completed. It busy waits
* in case of previous command is not completed.
**/
static s32 e1000_mng_enable_host_if(struct e1000_hw *hw)
{
u32 hicr;
u8 i;
if (!hw->mac.arc_subsystem_valid) {
e_dbg("ARC subsystem not valid.\n");
return -E1000_ERR_HOST_INTERFACE_COMMAND;
}
/* Check that the host interface is enabled. */
hicr = er32(HICR);
if (!(hicr & E1000_HICR_EN)) {
e_dbg("E1000_HOST_EN bit disabled.\n");
return -E1000_ERR_HOST_INTERFACE_COMMAND;
}
/* check the previous command is completed */
for (i = 0; i < E1000_MNG_DHCP_COMMAND_TIMEOUT; i++) {
hicr = er32(HICR);
if (!(hicr & E1000_HICR_C))
break;
mdelay(1);
}
if (i == E1000_MNG_DHCP_COMMAND_TIMEOUT) {
e_dbg("Previous command timeout failed.\n");
return -E1000_ERR_HOST_INTERFACE_COMMAND;
}
return 0;
}
/**
* e1000e_check_mng_mode_generic - Generic check management mode
* @hw: pointer to the HW structure
*
* Reads the firmware semaphore register and returns true (>0) if
* manageability is enabled, else false (0).
**/
bool e1000e_check_mng_mode_generic(struct e1000_hw *hw)
{
u32 fwsm = er32(FWSM);
return (fwsm & E1000_FWSM_MODE_MASK) ==
(E1000_MNG_IAMT_MODE << E1000_FWSM_MODE_SHIFT);
}
/**
* e1000e_enable_tx_pkt_filtering - Enable packet filtering on Tx
* @hw: pointer to the HW structure
*
* Enables packet filtering on transmit packets if manageability is enabled
* and host interface is enabled.
**/
bool e1000e_enable_tx_pkt_filtering(struct e1000_hw *hw)
{
struct e1000_host_mng_dhcp_cookie *hdr = &hw->mng_cookie;
u32 *buffer = (u32 *)&hw->mng_cookie;
u32 offset;
s32 ret_val, hdr_csum, csum;
u8 i, len;
hw->mac.tx_pkt_filtering = true;
/* No manageability, no filtering */
if (!hw->mac.ops.check_mng_mode(hw)) {
hw->mac.tx_pkt_filtering = false;
return hw->mac.tx_pkt_filtering;
}
/* If we can't read from the host interface for whatever
* reason, disable filtering.
*/
ret_val = e1000_mng_enable_host_if(hw);
if (ret_val) {
hw->mac.tx_pkt_filtering = false;
return hw->mac.tx_pkt_filtering;
}
/* Read in the header. Length and offset are in dwords. */
len = E1000_MNG_DHCP_COOKIE_LENGTH >> 2;
offset = E1000_MNG_DHCP_COOKIE_OFFSET >> 2;
for (i = 0; i < len; i++)
*(buffer + i) = E1000_READ_REG_ARRAY(hw, E1000_HOST_IF,
offset + i);
hdr_csum = hdr->checksum;
hdr->checksum = 0;
csum = e1000_calculate_checksum((u8 *)hdr,
E1000_MNG_DHCP_COOKIE_LENGTH);
/* If either the checksums or signature don't match, then
* the cookie area isn't considered valid, in which case we
* take the safe route of assuming Tx filtering is enabled.
*/
if ((hdr_csum != csum) || (hdr->signature != E1000_IAMT_SIGNATURE)) {
hw->mac.tx_pkt_filtering = true;
return hw->mac.tx_pkt_filtering;
}
/* Cookie area is valid, make the final check for filtering. */
if (!(hdr->status & E1000_MNG_DHCP_COOKIE_STATUS_PARSING))
hw->mac.tx_pkt_filtering = false;
return hw->mac.tx_pkt_filtering;
}
/**
* e1000_mng_write_cmd_header - Writes manageability command header
* @hw: pointer to the HW structure
* @hdr: pointer to the host interface command header
*
* Writes the command header after does the checksum calculation.
**/
static s32 e1000_mng_write_cmd_header(struct e1000_hw *hw,
struct e1000_host_mng_command_header *hdr)
{
u16 i, length = sizeof(struct e1000_host_mng_command_header);
/* Write the whole command header structure with new checksum. */
hdr->checksum = e1000_calculate_checksum((u8 *)hdr, length);
length >>= 2;
/* Write the relevant command block into the ram area. */
for (i = 0; i < length; i++) {
E1000_WRITE_REG_ARRAY(hw, E1000_HOST_IF, i, *((u32 *)hdr + i));
e1e_flush();
}
return 0;
}
/**
* e1000_mng_host_if_write - Write to the manageability host interface
* @hw: pointer to the HW structure
* @buffer: pointer to the host interface buffer
* @length: size of the buffer
* @offset: location in the buffer to write to
* @sum: sum of the data (not checksum)
*
* This function writes the buffer content at the offset given on the host if.
* It also does alignment considerations to do the writes in most efficient
* way. Also fills up the sum of the buffer in *buffer parameter.
**/
static s32 e1000_mng_host_if_write(struct e1000_hw *hw, u8 *buffer,
u16 length, u16 offset, u8 *sum)
{
u8 *tmp;
u8 *bufptr = buffer;
u32 data = 0;
u16 remaining, i, j, prev_bytes;
/* sum = only sum of the data and it is not checksum */
if (length == 0 || offset + length > E1000_HI_MAX_MNG_DATA_LENGTH)
return -E1000_ERR_PARAM;
tmp = (u8 *)&data;
prev_bytes = offset & 0x3;
offset >>= 2;
if (prev_bytes) {
data = E1000_READ_REG_ARRAY(hw, E1000_HOST_IF, offset);
for (j = prev_bytes; j < sizeof(u32); j++) {
*(tmp + j) = *bufptr++;
*sum += *(tmp + j);
}
E1000_WRITE_REG_ARRAY(hw, E1000_HOST_IF, offset, data);
length -= j - prev_bytes;
offset++;
}
remaining = length & 0x3;
length -= remaining;
/* Calculate length in DWORDs */
length >>= 2;
/* The device driver writes the relevant command block into the
* ram area.
*/
for (i = 0; i < length; i++) {
for (j = 0; j < sizeof(u32); j++) {
*(tmp + j) = *bufptr++;
*sum += *(tmp + j);
}
E1000_WRITE_REG_ARRAY(hw, E1000_HOST_IF, offset + i, data);
}
if (remaining) {
for (j = 0; j < sizeof(u32); j++) {
if (j < remaining)
*(tmp + j) = *bufptr++;
else
*(tmp + j) = 0;
*sum += *(tmp + j);
}
E1000_WRITE_REG_ARRAY(hw, E1000_HOST_IF, offset + i, data);
}
return 0;
}
/**
* e1000e_mng_write_dhcp_info - Writes DHCP info to host interface
* @hw: pointer to the HW structure
* @buffer: pointer to the host interface
* @length: size of the buffer
*
* Writes the DHCP information to the host interface.
**/
s32 e1000e_mng_write_dhcp_info(struct e1000_hw *hw, u8 *buffer, u16 length)
{
struct e1000_host_mng_command_header hdr;
s32 ret_val;
u32 hicr;
hdr.command_id = E1000_MNG_DHCP_TX_PAYLOAD_CMD;
hdr.command_length = length;
hdr.reserved1 = 0;
hdr.reserved2 = 0;
hdr.checksum = 0;
/* Enable the host interface */
ret_val = e1000_mng_enable_host_if(hw);
if (ret_val)
return ret_val;
/* Populate the host interface with the contents of "buffer". */
ret_val = e1000_mng_host_if_write(hw, buffer, length,
sizeof(hdr), &(hdr.checksum));
if (ret_val)
return ret_val;
/* Write the manageability command header */
ret_val = e1000_mng_write_cmd_header(hw, &hdr);
if (ret_val)
return ret_val;
/* Tell the ARC a new command is pending. */
hicr = er32(HICR);
ew32(HICR, hicr | E1000_HICR_C);
return 0;
}
/**
* e1000e_enable_mng_pass_thru - Check if management passthrough is needed
* @hw: pointer to the HW structure
*
* Verifies the hardware needs to leave interface enabled so that frames can
* be directed to and from the management interface.
**/
bool e1000e_enable_mng_pass_thru(struct e1000_hw *hw)
{
u32 manc;
u32 fwsm, factps;
manc = er32(MANC);
if (!(manc & E1000_MANC_RCV_TCO_EN))
return false;
if (hw->mac.has_fwsm) {
fwsm = er32(FWSM);
factps = er32(FACTPS);
if (!(factps & E1000_FACTPS_MNGCG) &&
((fwsm & E1000_FWSM_MODE_MASK) ==
(e1000_mng_mode_pt << E1000_FWSM_MODE_SHIFT)))
return true;
} else if ((hw->mac.type == e1000_82574) ||
(hw->mac.type == e1000_82583)) {
u16 data;
s32 ret_val;
factps = er32(FACTPS);
ret_val = e1000_read_nvm(hw, NVM_INIT_CONTROL2_REG, 1, &data);
if (ret_val)
return false;
if (!(factps & E1000_FACTPS_MNGCG) &&
((data & E1000_NVM_INIT_CTRL2_MNGM) ==
(e1000_mng_mode_pt << 13)))
return true;
} else if ((manc & E1000_MANC_SMBUS_EN) &&
!(manc & E1000_MANC_ASF_EN)) {
return true;
}
return false;
}

View File

@ -0,0 +1,47 @@
/* SPDX-License-Identifier: GPL-2.0 */
/* Copyright(c) 1999 - 2018 Intel Corporation. */
#ifndef _E1000E_MANAGE_H_
#define _E1000E_MANAGE_H_
bool e1000e_check_mng_mode_generic(struct e1000_hw *hw);
bool e1000e_enable_tx_pkt_filtering(struct e1000_hw *hw);
s32 e1000e_mng_write_dhcp_info(struct e1000_hw *hw, u8 *buffer, u16 length);
bool e1000e_enable_mng_pass_thru(struct e1000_hw *hw);
enum e1000_mng_mode {
e1000_mng_mode_none = 0,
e1000_mng_mode_asf,
e1000_mng_mode_pt,
e1000_mng_mode_ipmi,
e1000_mng_mode_host_if_only
};
#define E1000_FACTPS_MNGCG 0x20000000
#define E1000_FWSM_MODE_MASK 0xE
#define E1000_FWSM_MODE_SHIFT 1
#define E1000_MNG_IAMT_MODE 0x3
#define E1000_MNG_DHCP_COOKIE_LENGTH 0x10
#define E1000_MNG_DHCP_COOKIE_OFFSET 0x6F0
#define E1000_MNG_DHCP_COMMAND_TIMEOUT 10
#define E1000_MNG_DHCP_TX_PAYLOAD_CMD 64
#define E1000_MNG_DHCP_COOKIE_STATUS_PARSING 0x1
#define E1000_MNG_DHCP_COOKIE_STATUS_VLAN 0x2
#define E1000_VFTA_ENTRY_SHIFT 5
#define E1000_VFTA_ENTRY_MASK 0x7F
#define E1000_VFTA_ENTRY_BIT_SHIFT_MASK 0x1F
#define E1000_HICR_EN 0x01 /* Enable bit - RO */
/* Driver sets this bit when done to put command in RAM */
#define E1000_HICR_C 0x02
#define E1000_HICR_SV 0x04 /* Status Validity */
#define E1000_HICR_FW_RESET_ENABLE 0x40
#define E1000_HICR_FW_RESET 0x80
/* Intel(R) Active Management Technology signature */
#define E1000_IAMT_SIGNATURE 0x544D4149
#endif

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,615 @@
// SPDX-License-Identifier: GPL-2.0
/* Copyright(c) 1999 - 2018 Intel Corporation. */
#include "e1000-6.4-ethercat.h"
/**
* e1000_raise_eec_clk - Raise EEPROM clock
* @hw: pointer to the HW structure
* @eecd: pointer to the EEPROM
*
* Enable/Raise the EEPROM clock bit.
**/
static void e1000_raise_eec_clk(struct e1000_hw *hw, u32 *eecd)
{
*eecd = *eecd | E1000_EECD_SK;
ew32(EECD, *eecd);
e1e_flush();
udelay(hw->nvm.delay_usec);
}
/**
* e1000_lower_eec_clk - Lower EEPROM clock
* @hw: pointer to the HW structure
* @eecd: pointer to the EEPROM
*
* Clear/Lower the EEPROM clock bit.
**/
static void e1000_lower_eec_clk(struct e1000_hw *hw, u32 *eecd)
{
*eecd = *eecd & ~E1000_EECD_SK;
ew32(EECD, *eecd);
e1e_flush();
udelay(hw->nvm.delay_usec);
}
/**
* e1000_shift_out_eec_bits - Shift data bits our to the EEPROM
* @hw: pointer to the HW structure
* @data: data to send to the EEPROM
* @count: number of bits to shift out
*
* We need to shift 'count' bits out to the EEPROM. So, the value in the
* "data" parameter will be shifted out to the EEPROM one bit at a time.
* In order to do this, "data" must be broken down into bits.
**/
static void e1000_shift_out_eec_bits(struct e1000_hw *hw, u16 data, u16 count)
{
struct e1000_nvm_info *nvm = &hw->nvm;
u32 eecd = er32(EECD);
u32 mask;
mask = BIT(count - 1);
if (nvm->type == e1000_nvm_eeprom_spi)
eecd |= E1000_EECD_DO;
do {
eecd &= ~E1000_EECD_DI;
if (data & mask)
eecd |= E1000_EECD_DI;
ew32(EECD, eecd);
e1e_flush();
udelay(nvm->delay_usec);
e1000_raise_eec_clk(hw, &eecd);
e1000_lower_eec_clk(hw, &eecd);
mask >>= 1;
} while (mask);
eecd &= ~E1000_EECD_DI;
ew32(EECD, eecd);
}
/**
* e1000_shift_in_eec_bits - Shift data bits in from the EEPROM
* @hw: pointer to the HW structure
* @count: number of bits to shift in
*
* In order to read a register from the EEPROM, we need to shift 'count' bits
* in from the EEPROM. Bits are "shifted in" by raising the clock input to
* the EEPROM (setting the SK bit), and then reading the value of the data out
* "DO" bit. During this "shifting in" process the data in "DI" bit should
* always be clear.
**/
static u16 e1000_shift_in_eec_bits(struct e1000_hw *hw, u16 count)
{
u32 eecd;
u32 i;
u16 data;
eecd = er32(EECD);
eecd &= ~(E1000_EECD_DO | E1000_EECD_DI);
data = 0;
for (i = 0; i < count; i++) {
data <<= 1;
e1000_raise_eec_clk(hw, &eecd);
eecd = er32(EECD);
eecd &= ~E1000_EECD_DI;
if (eecd & E1000_EECD_DO)
data |= 1;
e1000_lower_eec_clk(hw, &eecd);
}
return data;
}
/**
* e1000e_poll_eerd_eewr_done - Poll for EEPROM read/write completion
* @hw: pointer to the HW structure
* @ee_reg: EEPROM flag for polling
*
* Polls the EEPROM status bit for either read or write completion based
* upon the value of 'ee_reg'.
**/
s32 e1000e_poll_eerd_eewr_done(struct e1000_hw *hw, int ee_reg)
{
u32 attempts = 100000;
u32 i, reg = 0;
for (i = 0; i < attempts; i++) {
if (ee_reg == E1000_NVM_POLL_READ)
reg = er32(EERD);
else
reg = er32(EEWR);
if (reg & E1000_NVM_RW_REG_DONE)
return 0;
udelay(5);
}
return -E1000_ERR_NVM;
}
/**
* e1000e_acquire_nvm - Generic request for access to EEPROM
* @hw: pointer to the HW structure
*
* Set the EEPROM access request bit and wait for EEPROM access grant bit.
* Return successful if access grant bit set, else clear the request for
* EEPROM access and return -E1000_ERR_NVM (-1).
**/
s32 e1000e_acquire_nvm(struct e1000_hw *hw)
{
u32 eecd = er32(EECD);
s32 timeout = E1000_NVM_GRANT_ATTEMPTS;
ew32(EECD, eecd | E1000_EECD_REQ);
eecd = er32(EECD);
while (timeout) {
if (eecd & E1000_EECD_GNT)
break;
udelay(5);
eecd = er32(EECD);
timeout--;
}
if (!timeout) {
eecd &= ~E1000_EECD_REQ;
ew32(EECD, eecd);
e_dbg("Could not acquire NVM grant\n");
return -E1000_ERR_NVM;
}
return 0;
}
/**
* e1000_standby_nvm - Return EEPROM to standby state
* @hw: pointer to the HW structure
*
* Return the EEPROM to a standby state.
**/
static void e1000_standby_nvm(struct e1000_hw *hw)
{
struct e1000_nvm_info *nvm = &hw->nvm;
u32 eecd = er32(EECD);
if (nvm->type == e1000_nvm_eeprom_spi) {
/* Toggle CS to flush commands */
eecd |= E1000_EECD_CS;
ew32(EECD, eecd);
e1e_flush();
udelay(nvm->delay_usec);
eecd &= ~E1000_EECD_CS;
ew32(EECD, eecd);
e1e_flush();
udelay(nvm->delay_usec);
}
}
/**
* e1000_stop_nvm - Terminate EEPROM command
* @hw: pointer to the HW structure
*
* Terminates the current command by inverting the EEPROM's chip select pin.
**/
static void e1000_stop_nvm(struct e1000_hw *hw)
{
u32 eecd;
eecd = er32(EECD);
if (hw->nvm.type == e1000_nvm_eeprom_spi) {
/* Pull CS high */
eecd |= E1000_EECD_CS;
e1000_lower_eec_clk(hw, &eecd);
}
}
/**
* e1000e_release_nvm - Release exclusive access to EEPROM
* @hw: pointer to the HW structure
*
* Stop any current commands to the EEPROM and clear the EEPROM request bit.
**/
void e1000e_release_nvm(struct e1000_hw *hw)
{
u32 eecd;
e1000_stop_nvm(hw);
eecd = er32(EECD);
eecd &= ~E1000_EECD_REQ;
ew32(EECD, eecd);
}
/**
* e1000_ready_nvm_eeprom - Prepares EEPROM for read/write
* @hw: pointer to the HW structure
*
* Setups the EEPROM for reading and writing.
**/
static s32 e1000_ready_nvm_eeprom(struct e1000_hw *hw)
{
struct e1000_nvm_info *nvm = &hw->nvm;
u32 eecd = er32(EECD);
u8 spi_stat_reg;
if (nvm->type == e1000_nvm_eeprom_spi) {
u16 timeout = NVM_MAX_RETRY_SPI;
/* Clear SK and CS */
eecd &= ~(E1000_EECD_CS | E1000_EECD_SK);
ew32(EECD, eecd);
e1e_flush();
udelay(1);
/* Read "Status Register" repeatedly until the LSB is cleared.
* The EEPROM will signal that the command has been completed
* by clearing bit 0 of the internal status register. If it's
* not cleared within 'timeout', then error out.
*/
while (timeout) {
e1000_shift_out_eec_bits(hw, NVM_RDSR_OPCODE_SPI,
hw->nvm.opcode_bits);
spi_stat_reg = (u8)e1000_shift_in_eec_bits(hw, 8);
if (!(spi_stat_reg & NVM_STATUS_RDY_SPI))
break;
udelay(5);
e1000_standby_nvm(hw);
timeout--;
}
if (!timeout) {
e_dbg("SPI NVM Status error\n");
return -E1000_ERR_NVM;
}
}
return 0;
}
/**
* e1000e_read_nvm_eerd - Reads EEPROM using EERD register
* @hw: pointer to the HW structure
* @offset: offset of word in the EEPROM to read
* @words: number of words to read
* @data: word read from the EEPROM
*
* Reads a 16 bit word from the EEPROM using the EERD register.
**/
s32 e1000e_read_nvm_eerd(struct e1000_hw *hw, u16 offset, u16 words, u16 *data)
{
struct e1000_nvm_info *nvm = &hw->nvm;
u32 i, eerd = 0;
s32 ret_val = 0;
/* A check for invalid values: offset too large, too many words,
* too many words for the offset, and not enough words.
*/
if ((offset >= nvm->word_size) || (words > (nvm->word_size - offset)) ||
(words == 0)) {
e_dbg("nvm parameter(s) out of bounds\n");
return -E1000_ERR_NVM;
}
for (i = 0; i < words; i++) {
eerd = ((offset + i) << E1000_NVM_RW_ADDR_SHIFT) +
E1000_NVM_RW_REG_START;
ew32(EERD, eerd);
ret_val = e1000e_poll_eerd_eewr_done(hw, E1000_NVM_POLL_READ);
if (ret_val) {
e_dbg("NVM read error: %d\n", ret_val);
break;
}
data[i] = (er32(EERD) >> E1000_NVM_RW_REG_DATA);
}
return ret_val;
}
/**
* e1000e_write_nvm_spi - Write to EEPROM using SPI
* @hw: pointer to the HW structure
* @offset: offset within the EEPROM to be written to
* @words: number of words to write
* @data: 16 bit word(s) to be written to the EEPROM
*
* Writes data to EEPROM at offset using SPI interface.
*
* If e1000e_update_nvm_checksum is not called after this function , the
* EEPROM will most likely contain an invalid checksum.
**/
s32 e1000e_write_nvm_spi(struct e1000_hw *hw, u16 offset, u16 words, u16 *data)
{
struct e1000_nvm_info *nvm = &hw->nvm;
s32 ret_val = -E1000_ERR_NVM;
u16 widx = 0;
/* A check for invalid values: offset too large, too many words,
* and not enough words.
*/
if ((offset >= nvm->word_size) || (words > (nvm->word_size - offset)) ||
(words == 0)) {
e_dbg("nvm parameter(s) out of bounds\n");
return -E1000_ERR_NVM;
}
while (widx < words) {
u8 write_opcode = NVM_WRITE_OPCODE_SPI;
ret_val = nvm->ops.acquire(hw);
if (ret_val)
return ret_val;
ret_val = e1000_ready_nvm_eeprom(hw);
if (ret_val) {
nvm->ops.release(hw);
return ret_val;
}
e1000_standby_nvm(hw);
/* Send the WRITE ENABLE command (8 bit opcode) */
e1000_shift_out_eec_bits(hw, NVM_WREN_OPCODE_SPI,
nvm->opcode_bits);
e1000_standby_nvm(hw);
/* Some SPI eeproms use the 8th address bit embedded in the
* opcode
*/
if ((nvm->address_bits == 8) && (offset >= 128))
write_opcode |= NVM_A8_OPCODE_SPI;
/* Send the Write command (8-bit opcode + addr) */
e1000_shift_out_eec_bits(hw, write_opcode, nvm->opcode_bits);
e1000_shift_out_eec_bits(hw, (u16)((offset + widx) * 2),
nvm->address_bits);
/* Loop to allow for up to whole page write of eeprom */
while (widx < words) {
u16 word_out = data[widx];
word_out = (word_out >> 8) | (word_out << 8);
e1000_shift_out_eec_bits(hw, word_out, 16);
widx++;
if ((((offset + widx) * 2) % nvm->page_size) == 0) {
e1000_standby_nvm(hw);
break;
}
}
usleep_range(10000, 11000);
nvm->ops.release(hw);
}
return ret_val;
}
/**
* e1000_read_pba_string_generic - Read device part number
* @hw: pointer to the HW structure
* @pba_num: pointer to device part number
* @pba_num_size: size of part number buffer
*
* Reads the product board assembly (PBA) number from the EEPROM and stores
* the value in pba_num.
**/
s32 e1000_read_pba_string_generic(struct e1000_hw *hw, u8 *pba_num,
u32 pba_num_size)
{
s32 ret_val;
u16 nvm_data;
u16 pba_ptr;
u16 offset;
u16 length;
if (pba_num == NULL) {
e_dbg("PBA string buffer was null\n");
return -E1000_ERR_INVALID_ARGUMENT;
}
ret_val = e1000_read_nvm(hw, NVM_PBA_OFFSET_0, 1, &nvm_data);
if (ret_val) {
e_dbg("NVM Read Error\n");
return ret_val;
}
ret_val = e1000_read_nvm(hw, NVM_PBA_OFFSET_1, 1, &pba_ptr);
if (ret_val) {
e_dbg("NVM Read Error\n");
return ret_val;
}
/* if nvm_data is not ptr guard the PBA must be in legacy format which
* means pba_ptr is actually our second data word for the PBA number
* and we can decode it into an ascii string
*/
if (nvm_data != NVM_PBA_PTR_GUARD) {
e_dbg("NVM PBA number is not stored as string\n");
/* make sure callers buffer is big enough to store the PBA */
if (pba_num_size < E1000_PBANUM_LENGTH) {
e_dbg("PBA string buffer too small\n");
return E1000_ERR_NO_SPACE;
}
/* extract hex string from data and pba_ptr */
pba_num[0] = (nvm_data >> 12) & 0xF;
pba_num[1] = (nvm_data >> 8) & 0xF;
pba_num[2] = (nvm_data >> 4) & 0xF;
pba_num[3] = nvm_data & 0xF;
pba_num[4] = (pba_ptr >> 12) & 0xF;
pba_num[5] = (pba_ptr >> 8) & 0xF;
pba_num[6] = '-';
pba_num[7] = 0;
pba_num[8] = (pba_ptr >> 4) & 0xF;
pba_num[9] = pba_ptr & 0xF;
/* put a null character on the end of our string */
pba_num[10] = '\0';
/* switch all the data but the '-' to hex char */
for (offset = 0; offset < 10; offset++) {
if (pba_num[offset] < 0xA)
pba_num[offset] += '0';
else if (pba_num[offset] < 0x10)
pba_num[offset] += 'A' - 0xA;
}
return 0;
}
ret_val = e1000_read_nvm(hw, pba_ptr, 1, &length);
if (ret_val) {
e_dbg("NVM Read Error\n");
return ret_val;
}
if (length == 0xFFFF || length == 0) {
e_dbg("NVM PBA number section invalid length\n");
return -E1000_ERR_NVM_PBA_SECTION;
}
/* check if pba_num buffer is big enough */
if (pba_num_size < (((u32)length * 2) - 1)) {
e_dbg("PBA string buffer too small\n");
return -E1000_ERR_NO_SPACE;
}
/* trim pba length from start of string */
pba_ptr++;
length--;
for (offset = 0; offset < length; offset++) {
ret_val = e1000_read_nvm(hw, pba_ptr + offset, 1, &nvm_data);
if (ret_val) {
e_dbg("NVM Read Error\n");
return ret_val;
}
pba_num[offset * 2] = (u8)(nvm_data >> 8);
pba_num[(offset * 2) + 1] = (u8)(nvm_data & 0xFF);
}
pba_num[offset * 2] = '\0';
return 0;
}
/**
* e1000_read_mac_addr_generic - Read device MAC address
* @hw: pointer to the HW structure
*
* Reads the device MAC address from the EEPROM and stores the value.
* Since devices with two ports use the same EEPROM, we increment the
* last bit in the MAC address for the second port.
**/
s32 e1000_read_mac_addr_generic(struct e1000_hw *hw)
{
u32 rar_high;
u32 rar_low;
u16 i;
rar_high = er32(RAH(0));
rar_low = er32(RAL(0));
for (i = 0; i < E1000_RAL_MAC_ADDR_LEN; i++)
hw->mac.perm_addr[i] = (u8)(rar_low >> (i * 8));
for (i = 0; i < E1000_RAH_MAC_ADDR_LEN; i++)
hw->mac.perm_addr[i + 4] = (u8)(rar_high >> (i * 8));
for (i = 0; i < ETH_ALEN; i++)
hw->mac.addr[i] = hw->mac.perm_addr[i];
return 0;
}
/**
* e1000e_validate_nvm_checksum_generic - Validate EEPROM checksum
* @hw: pointer to the HW structure
*
* Calculates the EEPROM checksum by reading/adding each word of the EEPROM
* and then verifies that the sum of the EEPROM is equal to 0xBABA.
**/
s32 e1000e_validate_nvm_checksum_generic(struct e1000_hw *hw)
{
s32 ret_val;
u16 checksum = 0;
u16 i, nvm_data;
for (i = 0; i < (NVM_CHECKSUM_REG + 1); i++) {
ret_val = e1000_read_nvm(hw, i, 1, &nvm_data);
if (ret_val) {
e_dbg("NVM Read Error\n");
return ret_val;
}
checksum += nvm_data;
}
if (checksum != (u16)NVM_SUM) {
e_dbg("NVM Checksum Invalid\n");
return -E1000_ERR_NVM;
}
return 0;
}
/**
* e1000e_update_nvm_checksum_generic - Update EEPROM checksum
* @hw: pointer to the HW structure
*
* Updates the EEPROM checksum by reading/adding each word of the EEPROM
* up to the checksum. Then calculates the EEPROM checksum and writes the
* value to the EEPROM.
**/
s32 e1000e_update_nvm_checksum_generic(struct e1000_hw *hw)
{
s32 ret_val;
u16 checksum = 0;
u16 i, nvm_data;
for (i = 0; i < NVM_CHECKSUM_REG; i++) {
ret_val = e1000_read_nvm(hw, i, 1, &nvm_data);
if (ret_val) {
e_dbg("NVM Read Error while updating checksum.\n");
return ret_val;
}
checksum += nvm_data;
}
checksum = (u16)NVM_SUM - checksum;
ret_val = e1000_write_nvm(hw, NVM_CHECKSUM_REG, 1, &checksum);
if (ret_val)
e_dbg("NVM Write Error while updating checksum.\n");
return ret_val;
}
/**
* e1000e_reload_nvm_generic - Reloads EEPROM
* @hw: pointer to the HW structure
*
* Reloads the EEPROM by setting the "Reinitialize from EEPROM" bit in the
* extended control register.
**/
void e1000e_reload_nvm_generic(struct e1000_hw *hw)
{
u32 ctrl_ext;
usleep_range(10, 20);
ctrl_ext = er32(CTRL_EXT);
ctrl_ext |= E1000_CTRL_EXT_EE_RST;
ew32(CTRL_EXT, ctrl_ext);
e1e_flush();
}

View File

@ -0,0 +1,22 @@
/* SPDX-License-Identifier: GPL-2.0 */
/* Copyright(c) 1999 - 2018 Intel Corporation. */
#ifndef _E1000E_NVM_H_
#define _E1000E_NVM_H_
s32 e1000e_acquire_nvm(struct e1000_hw *hw);
s32 e1000e_poll_eerd_eewr_done(struct e1000_hw *hw, int ee_reg);
s32 e1000_read_mac_addr_generic(struct e1000_hw *hw);
s32 e1000_read_pba_string_generic(struct e1000_hw *hw, u8 *pba_num,
u32 pba_num_size);
s32 e1000e_read_nvm_eerd(struct e1000_hw *hw, u16 offset, u16 words, u16 *data);
s32 e1000e_valid_led_default(struct e1000_hw *hw, u16 *data);
s32 e1000e_validate_nvm_checksum_generic(struct e1000_hw *hw);
s32 e1000e_write_nvm_spi(struct e1000_hw *hw, u16 offset, u16 words, u16 *data);
s32 e1000e_update_nvm_checksum_generic(struct e1000_hw *hw);
void e1000e_release_nvm(struct e1000_hw *hw);
#define E1000_STM_OPCODE 0xDB00
#endif

View File

@ -0,0 +1,615 @@
// SPDX-License-Identifier: GPL-2.0
/* Copyright(c) 1999 - 2018 Intel Corporation. */
#include "e1000.h"
/**
* e1000_raise_eec_clk - Raise EEPROM clock
* @hw: pointer to the HW structure
* @eecd: pointer to the EEPROM
*
* Enable/Raise the EEPROM clock bit.
**/
static void e1000_raise_eec_clk(struct e1000_hw *hw, u32 *eecd)
{
*eecd = *eecd | E1000_EECD_SK;
ew32(EECD, *eecd);
e1e_flush();
udelay(hw->nvm.delay_usec);
}
/**
* e1000_lower_eec_clk - Lower EEPROM clock
* @hw: pointer to the HW structure
* @eecd: pointer to the EEPROM
*
* Clear/Lower the EEPROM clock bit.
**/
static void e1000_lower_eec_clk(struct e1000_hw *hw, u32 *eecd)
{
*eecd = *eecd & ~E1000_EECD_SK;
ew32(EECD, *eecd);
e1e_flush();
udelay(hw->nvm.delay_usec);
}
/**
* e1000_shift_out_eec_bits - Shift data bits our to the EEPROM
* @hw: pointer to the HW structure
* @data: data to send to the EEPROM
* @count: number of bits to shift out
*
* We need to shift 'count' bits out to the EEPROM. So, the value in the
* "data" parameter will be shifted out to the EEPROM one bit at a time.
* In order to do this, "data" must be broken down into bits.
**/
static void e1000_shift_out_eec_bits(struct e1000_hw *hw, u16 data, u16 count)
{
struct e1000_nvm_info *nvm = &hw->nvm;
u32 eecd = er32(EECD);
u32 mask;
mask = BIT(count - 1);
if (nvm->type == e1000_nvm_eeprom_spi)
eecd |= E1000_EECD_DO;
do {
eecd &= ~E1000_EECD_DI;
if (data & mask)
eecd |= E1000_EECD_DI;
ew32(EECD, eecd);
e1e_flush();
udelay(nvm->delay_usec);
e1000_raise_eec_clk(hw, &eecd);
e1000_lower_eec_clk(hw, &eecd);
mask >>= 1;
} while (mask);
eecd &= ~E1000_EECD_DI;
ew32(EECD, eecd);
}
/**
* e1000_shift_in_eec_bits - Shift data bits in from the EEPROM
* @hw: pointer to the HW structure
* @count: number of bits to shift in
*
* In order to read a register from the EEPROM, we need to shift 'count' bits
* in from the EEPROM. Bits are "shifted in" by raising the clock input to
* the EEPROM (setting the SK bit), and then reading the value of the data out
* "DO" bit. During this "shifting in" process the data in "DI" bit should
* always be clear.
**/
static u16 e1000_shift_in_eec_bits(struct e1000_hw *hw, u16 count)
{
u32 eecd;
u32 i;
u16 data;
eecd = er32(EECD);
eecd &= ~(E1000_EECD_DO | E1000_EECD_DI);
data = 0;
for (i = 0; i < count; i++) {
data <<= 1;
e1000_raise_eec_clk(hw, &eecd);
eecd = er32(EECD);
eecd &= ~E1000_EECD_DI;
if (eecd & E1000_EECD_DO)
data |= 1;
e1000_lower_eec_clk(hw, &eecd);
}
return data;
}
/**
* e1000e_poll_eerd_eewr_done - Poll for EEPROM read/write completion
* @hw: pointer to the HW structure
* @ee_reg: EEPROM flag for polling
*
* Polls the EEPROM status bit for either read or write completion based
* upon the value of 'ee_reg'.
**/
s32 e1000e_poll_eerd_eewr_done(struct e1000_hw *hw, int ee_reg)
{
u32 attempts = 100000;
u32 i, reg = 0;
for (i = 0; i < attempts; i++) {
if (ee_reg == E1000_NVM_POLL_READ)
reg = er32(EERD);
else
reg = er32(EEWR);
if (reg & E1000_NVM_RW_REG_DONE)
return 0;
udelay(5);
}
return -E1000_ERR_NVM;
}
/**
* e1000e_acquire_nvm - Generic request for access to EEPROM
* @hw: pointer to the HW structure
*
* Set the EEPROM access request bit and wait for EEPROM access grant bit.
* Return successful if access grant bit set, else clear the request for
* EEPROM access and return -E1000_ERR_NVM (-1).
**/
s32 e1000e_acquire_nvm(struct e1000_hw *hw)
{
u32 eecd = er32(EECD);
s32 timeout = E1000_NVM_GRANT_ATTEMPTS;
ew32(EECD, eecd | E1000_EECD_REQ);
eecd = er32(EECD);
while (timeout) {
if (eecd & E1000_EECD_GNT)
break;
udelay(5);
eecd = er32(EECD);
timeout--;
}
if (!timeout) {
eecd &= ~E1000_EECD_REQ;
ew32(EECD, eecd);
e_dbg("Could not acquire NVM grant\n");
return -E1000_ERR_NVM;
}
return 0;
}
/**
* e1000_standby_nvm - Return EEPROM to standby state
* @hw: pointer to the HW structure
*
* Return the EEPROM to a standby state.
**/
static void e1000_standby_nvm(struct e1000_hw *hw)
{
struct e1000_nvm_info *nvm = &hw->nvm;
u32 eecd = er32(EECD);
if (nvm->type == e1000_nvm_eeprom_spi) {
/* Toggle CS to flush commands */
eecd |= E1000_EECD_CS;
ew32(EECD, eecd);
e1e_flush();
udelay(nvm->delay_usec);
eecd &= ~E1000_EECD_CS;
ew32(EECD, eecd);
e1e_flush();
udelay(nvm->delay_usec);
}
}
/**
* e1000_stop_nvm - Terminate EEPROM command
* @hw: pointer to the HW structure
*
* Terminates the current command by inverting the EEPROM's chip select pin.
**/
static void e1000_stop_nvm(struct e1000_hw *hw)
{
u32 eecd;
eecd = er32(EECD);
if (hw->nvm.type == e1000_nvm_eeprom_spi) {
/* Pull CS high */
eecd |= E1000_EECD_CS;
e1000_lower_eec_clk(hw, &eecd);
}
}
/**
* e1000e_release_nvm - Release exclusive access to EEPROM
* @hw: pointer to the HW structure
*
* Stop any current commands to the EEPROM and clear the EEPROM request bit.
**/
void e1000e_release_nvm(struct e1000_hw *hw)
{
u32 eecd;
e1000_stop_nvm(hw);
eecd = er32(EECD);
eecd &= ~E1000_EECD_REQ;
ew32(EECD, eecd);
}
/**
* e1000_ready_nvm_eeprom - Prepares EEPROM for read/write
* @hw: pointer to the HW structure
*
* Setups the EEPROM for reading and writing.
**/
static s32 e1000_ready_nvm_eeprom(struct e1000_hw *hw)
{
struct e1000_nvm_info *nvm = &hw->nvm;
u32 eecd = er32(EECD);
u8 spi_stat_reg;
if (nvm->type == e1000_nvm_eeprom_spi) {
u16 timeout = NVM_MAX_RETRY_SPI;
/* Clear SK and CS */
eecd &= ~(E1000_EECD_CS | E1000_EECD_SK);
ew32(EECD, eecd);
e1e_flush();
udelay(1);
/* Read "Status Register" repeatedly until the LSB is cleared.
* The EEPROM will signal that the command has been completed
* by clearing bit 0 of the internal status register. If it's
* not cleared within 'timeout', then error out.
*/
while (timeout) {
e1000_shift_out_eec_bits(hw, NVM_RDSR_OPCODE_SPI,
hw->nvm.opcode_bits);
spi_stat_reg = (u8)e1000_shift_in_eec_bits(hw, 8);
if (!(spi_stat_reg & NVM_STATUS_RDY_SPI))
break;
udelay(5);
e1000_standby_nvm(hw);
timeout--;
}
if (!timeout) {
e_dbg("SPI NVM Status error\n");
return -E1000_ERR_NVM;
}
}
return 0;
}
/**
* e1000e_read_nvm_eerd - Reads EEPROM using EERD register
* @hw: pointer to the HW structure
* @offset: offset of word in the EEPROM to read
* @words: number of words to read
* @data: word read from the EEPROM
*
* Reads a 16 bit word from the EEPROM using the EERD register.
**/
s32 e1000e_read_nvm_eerd(struct e1000_hw *hw, u16 offset, u16 words, u16 *data)
{
struct e1000_nvm_info *nvm = &hw->nvm;
u32 i, eerd = 0;
s32 ret_val = 0;
/* A check for invalid values: offset too large, too many words,
* too many words for the offset, and not enough words.
*/
if ((offset >= nvm->word_size) || (words > (nvm->word_size - offset)) ||
(words == 0)) {
e_dbg("nvm parameter(s) out of bounds\n");
return -E1000_ERR_NVM;
}
for (i = 0; i < words; i++) {
eerd = ((offset + i) << E1000_NVM_RW_ADDR_SHIFT) +
E1000_NVM_RW_REG_START;
ew32(EERD, eerd);
ret_val = e1000e_poll_eerd_eewr_done(hw, E1000_NVM_POLL_READ);
if (ret_val) {
e_dbg("NVM read error: %d\n", ret_val);
break;
}
data[i] = (er32(EERD) >> E1000_NVM_RW_REG_DATA);
}
return ret_val;
}
/**
* e1000e_write_nvm_spi - Write to EEPROM using SPI
* @hw: pointer to the HW structure
* @offset: offset within the EEPROM to be written to
* @words: number of words to write
* @data: 16 bit word(s) to be written to the EEPROM
*
* Writes data to EEPROM at offset using SPI interface.
*
* If e1000e_update_nvm_checksum is not called after this function , the
* EEPROM will most likely contain an invalid checksum.
**/
s32 e1000e_write_nvm_spi(struct e1000_hw *hw, u16 offset, u16 words, u16 *data)
{
struct e1000_nvm_info *nvm = &hw->nvm;
s32 ret_val = -E1000_ERR_NVM;
u16 widx = 0;
/* A check for invalid values: offset too large, too many words,
* and not enough words.
*/
if ((offset >= nvm->word_size) || (words > (nvm->word_size - offset)) ||
(words == 0)) {
e_dbg("nvm parameter(s) out of bounds\n");
return -E1000_ERR_NVM;
}
while (widx < words) {
u8 write_opcode = NVM_WRITE_OPCODE_SPI;
ret_val = nvm->ops.acquire(hw);
if (ret_val)
return ret_val;
ret_val = e1000_ready_nvm_eeprom(hw);
if (ret_val) {
nvm->ops.release(hw);
return ret_val;
}
e1000_standby_nvm(hw);
/* Send the WRITE ENABLE command (8 bit opcode) */
e1000_shift_out_eec_bits(hw, NVM_WREN_OPCODE_SPI,
nvm->opcode_bits);
e1000_standby_nvm(hw);
/* Some SPI eeproms use the 8th address bit embedded in the
* opcode
*/
if ((nvm->address_bits == 8) && (offset >= 128))
write_opcode |= NVM_A8_OPCODE_SPI;
/* Send the Write command (8-bit opcode + addr) */
e1000_shift_out_eec_bits(hw, write_opcode, nvm->opcode_bits);
e1000_shift_out_eec_bits(hw, (u16)((offset + widx) * 2),
nvm->address_bits);
/* Loop to allow for up to whole page write of eeprom */
while (widx < words) {
u16 word_out = data[widx];
word_out = (word_out >> 8) | (word_out << 8);
e1000_shift_out_eec_bits(hw, word_out, 16);
widx++;
if ((((offset + widx) * 2) % nvm->page_size) == 0) {
e1000_standby_nvm(hw);
break;
}
}
usleep_range(10000, 11000);
nvm->ops.release(hw);
}
return ret_val;
}
/**
* e1000_read_pba_string_generic - Read device part number
* @hw: pointer to the HW structure
* @pba_num: pointer to device part number
* @pba_num_size: size of part number buffer
*
* Reads the product board assembly (PBA) number from the EEPROM and stores
* the value in pba_num.
**/
s32 e1000_read_pba_string_generic(struct e1000_hw *hw, u8 *pba_num,
u32 pba_num_size)
{
s32 ret_val;
u16 nvm_data;
u16 pba_ptr;
u16 offset;
u16 length;
if (pba_num == NULL) {
e_dbg("PBA string buffer was null\n");
return -E1000_ERR_INVALID_ARGUMENT;
}
ret_val = e1000_read_nvm(hw, NVM_PBA_OFFSET_0, 1, &nvm_data);
if (ret_val) {
e_dbg("NVM Read Error\n");
return ret_val;
}
ret_val = e1000_read_nvm(hw, NVM_PBA_OFFSET_1, 1, &pba_ptr);
if (ret_val) {
e_dbg("NVM Read Error\n");
return ret_val;
}
/* if nvm_data is not ptr guard the PBA must be in legacy format which
* means pba_ptr is actually our second data word for the PBA number
* and we can decode it into an ascii string
*/
if (nvm_data != NVM_PBA_PTR_GUARD) {
e_dbg("NVM PBA number is not stored as string\n");
/* make sure callers buffer is big enough to store the PBA */
if (pba_num_size < E1000_PBANUM_LENGTH) {
e_dbg("PBA string buffer too small\n");
return E1000_ERR_NO_SPACE;
}
/* extract hex string from data and pba_ptr */
pba_num[0] = (nvm_data >> 12) & 0xF;
pba_num[1] = (nvm_data >> 8) & 0xF;
pba_num[2] = (nvm_data >> 4) & 0xF;
pba_num[3] = nvm_data & 0xF;
pba_num[4] = (pba_ptr >> 12) & 0xF;
pba_num[5] = (pba_ptr >> 8) & 0xF;
pba_num[6] = '-';
pba_num[7] = 0;
pba_num[8] = (pba_ptr >> 4) & 0xF;
pba_num[9] = pba_ptr & 0xF;
/* put a null character on the end of our string */
pba_num[10] = '\0';
/* switch all the data but the '-' to hex char */
for (offset = 0; offset < 10; offset++) {
if (pba_num[offset] < 0xA)
pba_num[offset] += '0';
else if (pba_num[offset] < 0x10)
pba_num[offset] += 'A' - 0xA;
}
return 0;
}
ret_val = e1000_read_nvm(hw, pba_ptr, 1, &length);
if (ret_val) {
e_dbg("NVM Read Error\n");
return ret_val;
}
if (length == 0xFFFF || length == 0) {
e_dbg("NVM PBA number section invalid length\n");
return -E1000_ERR_NVM_PBA_SECTION;
}
/* check if pba_num buffer is big enough */
if (pba_num_size < (((u32)length * 2) - 1)) {
e_dbg("PBA string buffer too small\n");
return -E1000_ERR_NO_SPACE;
}
/* trim pba length from start of string */
pba_ptr++;
length--;
for (offset = 0; offset < length; offset++) {
ret_val = e1000_read_nvm(hw, pba_ptr + offset, 1, &nvm_data);
if (ret_val) {
e_dbg("NVM Read Error\n");
return ret_val;
}
pba_num[offset * 2] = (u8)(nvm_data >> 8);
pba_num[(offset * 2) + 1] = (u8)(nvm_data & 0xFF);
}
pba_num[offset * 2] = '\0';
return 0;
}
/**
* e1000_read_mac_addr_generic - Read device MAC address
* @hw: pointer to the HW structure
*
* Reads the device MAC address from the EEPROM and stores the value.
* Since devices with two ports use the same EEPROM, we increment the
* last bit in the MAC address for the second port.
**/
s32 e1000_read_mac_addr_generic(struct e1000_hw *hw)
{
u32 rar_high;
u32 rar_low;
u16 i;
rar_high = er32(RAH(0));
rar_low = er32(RAL(0));
for (i = 0; i < E1000_RAL_MAC_ADDR_LEN; i++)
hw->mac.perm_addr[i] = (u8)(rar_low >> (i * 8));
for (i = 0; i < E1000_RAH_MAC_ADDR_LEN; i++)
hw->mac.perm_addr[i + 4] = (u8)(rar_high >> (i * 8));
for (i = 0; i < ETH_ALEN; i++)
hw->mac.addr[i] = hw->mac.perm_addr[i];
return 0;
}
/**
* e1000e_validate_nvm_checksum_generic - Validate EEPROM checksum
* @hw: pointer to the HW structure
*
* Calculates the EEPROM checksum by reading/adding each word of the EEPROM
* and then verifies that the sum of the EEPROM is equal to 0xBABA.
**/
s32 e1000e_validate_nvm_checksum_generic(struct e1000_hw *hw)
{
s32 ret_val;
u16 checksum = 0;
u16 i, nvm_data;
for (i = 0; i < (NVM_CHECKSUM_REG + 1); i++) {
ret_val = e1000_read_nvm(hw, i, 1, &nvm_data);
if (ret_val) {
e_dbg("NVM Read Error\n");
return ret_val;
}
checksum += nvm_data;
}
if (checksum != (u16)NVM_SUM) {
e_dbg("NVM Checksum Invalid\n");
return -E1000_ERR_NVM;
}
return 0;
}
/**
* e1000e_update_nvm_checksum_generic - Update EEPROM checksum
* @hw: pointer to the HW structure
*
* Updates the EEPROM checksum by reading/adding each word of the EEPROM
* up to the checksum. Then calculates the EEPROM checksum and writes the
* value to the EEPROM.
**/
s32 e1000e_update_nvm_checksum_generic(struct e1000_hw *hw)
{
s32 ret_val;
u16 checksum = 0;
u16 i, nvm_data;
for (i = 0; i < NVM_CHECKSUM_REG; i++) {
ret_val = e1000_read_nvm(hw, i, 1, &nvm_data);
if (ret_val) {
e_dbg("NVM Read Error while updating checksum.\n");
return ret_val;
}
checksum += nvm_data;
}
checksum = (u16)NVM_SUM - checksum;
ret_val = e1000_write_nvm(hw, NVM_CHECKSUM_REG, 1, &checksum);
if (ret_val)
e_dbg("NVM Write Error while updating checksum.\n");
return ret_val;
}
/**
* e1000e_reload_nvm_generic - Reloads EEPROM
* @hw: pointer to the HW structure
*
* Reloads the EEPROM by setting the "Reinitialize from EEPROM" bit in the
* extended control register.
**/
void e1000e_reload_nvm_generic(struct e1000_hw *hw)
{
u32 ctrl_ext;
usleep_range(10, 20);
ctrl_ext = er32(CTRL_EXT);
ctrl_ext |= E1000_CTRL_EXT_EE_RST;
ew32(CTRL_EXT, ctrl_ext);
e1e_flush();
}

View File

@ -0,0 +1,22 @@
/* SPDX-License-Identifier: GPL-2.0 */
/* Copyright(c) 1999 - 2018 Intel Corporation. */
#ifndef _E1000E_NVM_H_
#define _E1000E_NVM_H_
s32 e1000e_acquire_nvm(struct e1000_hw *hw);
s32 e1000e_poll_eerd_eewr_done(struct e1000_hw *hw, int ee_reg);
s32 e1000_read_mac_addr_generic(struct e1000_hw *hw);
s32 e1000_read_pba_string_generic(struct e1000_hw *hw, u8 *pba_num,
u32 pba_num_size);
s32 e1000e_read_nvm_eerd(struct e1000_hw *hw, u16 offset, u16 words, u16 *data);
s32 e1000e_valid_led_default(struct e1000_hw *hw, u16 *data);
s32 e1000e_validate_nvm_checksum_generic(struct e1000_hw *hw);
s32 e1000e_write_nvm_spi(struct e1000_hw *hw, u16 offset, u16 words, u16 *data);
s32 e1000e_update_nvm_checksum_generic(struct e1000_hw *hw);
void e1000e_release_nvm(struct e1000_hw *hw);
#define E1000_STM_OPCODE 0xDB00
#endif

View File

@ -0,0 +1,527 @@
// SPDX-License-Identifier: GPL-2.0
/* Copyright(c) 1999 - 2018 Intel Corporation. */
#include <linux/netdevice.h>
#include <linux/module.h>
#include <linux/pci.h>
#include "e1000-6.4-ethercat.h"
/* This is the only thing that needs to be changed to adjust the
* maximum number of ports that the driver can manage.
*/
#define E1000_MAX_NIC 32
#define OPTION_UNSET -1
#define OPTION_DISABLED 0
#define OPTION_ENABLED 1
#define COPYBREAK_DEFAULT 256
unsigned int copybreak = COPYBREAK_DEFAULT;
module_param(copybreak, uint, 0644);
MODULE_PARM_DESC(copybreak,
"Maximum size of packet that is copied to a new buffer on receive");
/* All parameters are treated the same, as an integer array of values.
* This macro just reduces the need to repeat the same declaration code
* over and over (plus this helps to avoid typo bugs).
*/
#define E1000_PARAM_INIT { [0 ... E1000_MAX_NIC] = OPTION_UNSET }
#define E1000_PARAM(X, desc) \
static int X[E1000_MAX_NIC+1] = E1000_PARAM_INIT; \
static unsigned int num_##X; \
module_param_array_named(X, X, int, &num_##X, 0); \
MODULE_PARM_DESC(X, desc);
/* Transmit Interrupt Delay in units of 1.024 microseconds
* Tx interrupt delay needs to typically be set to something non-zero
*
* Valid Range: 0-65535
*/
E1000_PARAM(TxIntDelay, "Transmit Interrupt Delay");
#define DEFAULT_TIDV 8
#define MAX_TXDELAY 0xFFFF
#define MIN_TXDELAY 0
/* Transmit Absolute Interrupt Delay in units of 1.024 microseconds
*
* Valid Range: 0-65535
*/
E1000_PARAM(TxAbsIntDelay, "Transmit Absolute Interrupt Delay");
#define DEFAULT_TADV 32
#define MAX_TXABSDELAY 0xFFFF
#define MIN_TXABSDELAY 0
/* Receive Interrupt Delay in units of 1.024 microseconds
* hardware will likely hang if you set this to anything but zero.
*
* Burst variant is used as default if device has FLAG2_DMA_BURST.
*
* Valid Range: 0-65535
*/
E1000_PARAM(RxIntDelay, "Receive Interrupt Delay");
#define DEFAULT_RDTR 0
#define BURST_RDTR 0x20
#define MAX_RXDELAY 0xFFFF
#define MIN_RXDELAY 0
/* Receive Absolute Interrupt Delay in units of 1.024 microseconds
*
* Burst variant is used as default if device has FLAG2_DMA_BURST.
*
* Valid Range: 0-65535
*/
E1000_PARAM(RxAbsIntDelay, "Receive Absolute Interrupt Delay");
#define DEFAULT_RADV 8
#define BURST_RADV 0x20
#define MAX_RXABSDELAY 0xFFFF
#define MIN_RXABSDELAY 0
/* Interrupt Throttle Rate (interrupts/sec)
*
* Valid Range: 100-100000 or one of: 0=off, 1=dynamic, 3=dynamic conservative
*/
E1000_PARAM(InterruptThrottleRate, "Interrupt Throttling Rate");
#define DEFAULT_ITR 3
#define MAX_ITR 100000
#define MIN_ITR 100
/* IntMode (Interrupt Mode)
*
* Valid Range: varies depending on kernel configuration & hardware support
*
* legacy=0, MSI=1, MSI-X=2
*
* When MSI/MSI-X support is enabled in kernel-
* Default Value: 2 (MSI-X) when supported by hardware, 1 (MSI) otherwise
* When MSI/MSI-X support is not enabled in kernel-
* Default Value: 0 (legacy)
*
* When a mode is specified that is not allowed/supported, it will be
* demoted to the most advanced interrupt mode available.
*/
E1000_PARAM(IntMode, "Interrupt Mode");
/* Enable Smart Power Down of the PHY
*
* Valid Range: 0, 1
*
* Default Value: 0 (disabled)
*/
E1000_PARAM(SmartPowerDownEnable, "Enable PHY smart power down");
/* Enable Kumeran Lock Loss workaround
*
* Valid Range: 0, 1
*
* Default Value: 1 (enabled)
*/
E1000_PARAM(KumeranLockLoss, "Enable Kumeran lock loss workaround");
/* Write Protect NVM
*
* Valid Range: 0, 1
*
* Default Value: 1 (enabled)
*/
E1000_PARAM(WriteProtectNVM,
"Write-protect NVM [WARNING: disabling this can lead to corrupted NVM]");
/* Enable CRC Stripping
*
* Valid Range: 0, 1
*
* Default Value: 1 (enabled)
*/
E1000_PARAM(CrcStripping,
"Enable CRC Stripping, disable if your BMC needs the CRC");
struct e1000_option {
enum { enable_option, range_option, list_option } type;
const char *name;
const char *err;
int def;
union {
/* range_option info */
struct {
int min;
int max;
} r;
/* list_option info */
struct {
int nr;
struct e1000_opt_list {
int i;
char *str;
} *p;
} l;
} arg;
};
static int e1000_validate_option(unsigned int *value,
const struct e1000_option *opt,
struct e1000_adapter *adapter)
{
if (*value == OPTION_UNSET) {
*value = opt->def;
return 0;
}
switch (opt->type) {
case enable_option:
switch (*value) {
case OPTION_ENABLED:
dev_info(&adapter->pdev->dev, "%s Enabled\n",
opt->name);
return 0;
case OPTION_DISABLED:
dev_info(&adapter->pdev->dev, "%s Disabled\n",
opt->name);
return 0;
}
break;
case range_option:
if (*value >= opt->arg.r.min && *value <= opt->arg.r.max) {
dev_info(&adapter->pdev->dev, "%s set to %i\n",
opt->name, *value);
return 0;
}
break;
case list_option: {
int i;
struct e1000_opt_list *ent;
for (i = 0; i < opt->arg.l.nr; i++) {
ent = &opt->arg.l.p[i];
if (*value == ent->i) {
if (ent->str[0] != '\0')
dev_info(&adapter->pdev->dev, "%s\n",
ent->str);
return 0;
}
}
}
break;
default:
BUG();
}
dev_info(&adapter->pdev->dev, "Invalid %s value specified (%i) %s\n",
opt->name, *value, opt->err);
*value = opt->def;
return -1;
}
/**
* e1000e_check_options - Range Checking for Command Line Parameters
* @adapter: board private structure
*
* This routine checks all command line parameters for valid user
* input. If an invalid value is given, or if no user specified
* value exists, a default value is used. The final value is stored
* in a variable in the adapter structure.
**/
void e1000e_check_options(struct e1000_adapter *adapter)
{
struct e1000_hw *hw = &adapter->hw;
int bd = adapter->bd_number;
if (bd >= E1000_MAX_NIC) {
dev_notice(&adapter->pdev->dev,
"Warning: no configuration for board #%i\n", bd);
dev_notice(&adapter->pdev->dev,
"Using defaults for all values\n");
}
/* Transmit Interrupt Delay */
{
static const struct e1000_option opt = {
.type = range_option,
.name = "Transmit Interrupt Delay",
.err = "using default of "
__MODULE_STRING(DEFAULT_TIDV),
.def = DEFAULT_TIDV,
.arg = { .r = { .min = MIN_TXDELAY,
.max = MAX_TXDELAY } }
};
if (num_TxIntDelay > bd) {
adapter->tx_int_delay = TxIntDelay[bd];
e1000_validate_option(&adapter->tx_int_delay, &opt,
adapter);
} else {
adapter->tx_int_delay = opt.def;
}
}
/* Transmit Absolute Interrupt Delay */
{
static const struct e1000_option opt = {
.type = range_option,
.name = "Transmit Absolute Interrupt Delay",
.err = "using default of "
__MODULE_STRING(DEFAULT_TADV),
.def = DEFAULT_TADV,
.arg = { .r = { .min = MIN_TXABSDELAY,
.max = MAX_TXABSDELAY } }
};
if (num_TxAbsIntDelay > bd) {
adapter->tx_abs_int_delay = TxAbsIntDelay[bd];
e1000_validate_option(&adapter->tx_abs_int_delay, &opt,
adapter);
} else {
adapter->tx_abs_int_delay = opt.def;
}
}
/* Receive Interrupt Delay */
{
static struct e1000_option opt = {
.type = range_option,
.name = "Receive Interrupt Delay",
.err = "using default of "
__MODULE_STRING(DEFAULT_RDTR),
.def = DEFAULT_RDTR,
.arg = { .r = { .min = MIN_RXDELAY,
.max = MAX_RXDELAY } }
};
if (adapter->flags2 & FLAG2_DMA_BURST)
opt.def = BURST_RDTR;
if (num_RxIntDelay > bd) {
adapter->rx_int_delay = RxIntDelay[bd];
e1000_validate_option(&adapter->rx_int_delay, &opt,
adapter);
} else {
adapter->rx_int_delay = opt.def;
}
}
/* Receive Absolute Interrupt Delay */
{
static struct e1000_option opt = {
.type = range_option,
.name = "Receive Absolute Interrupt Delay",
.err = "using default of "
__MODULE_STRING(DEFAULT_RADV),
.def = DEFAULT_RADV,
.arg = { .r = { .min = MIN_RXABSDELAY,
.max = MAX_RXABSDELAY } }
};
if (adapter->flags2 & FLAG2_DMA_BURST)
opt.def = BURST_RADV;
if (num_RxAbsIntDelay > bd) {
adapter->rx_abs_int_delay = RxAbsIntDelay[bd];
e1000_validate_option(&adapter->rx_abs_int_delay, &opt,
adapter);
} else {
adapter->rx_abs_int_delay = opt.def;
}
}
/* Interrupt Throttling Rate */
{
static const struct e1000_option opt = {
.type = range_option,
.name = "Interrupt Throttling Rate (ints/sec)",
.err = "using default of "
__MODULE_STRING(DEFAULT_ITR),
.def = DEFAULT_ITR,
.arg = { .r = { .min = MIN_ITR,
.max = MAX_ITR } }
};
if (num_InterruptThrottleRate > bd) {
adapter->itr = InterruptThrottleRate[bd];
/* Make sure a message is printed for non-special
* values. And in case of an invalid option, display
* warning, use default and go through itr/itr_setting
* adjustment logic below
*/
if ((adapter->itr > 4) &&
e1000_validate_option(&adapter->itr, &opt, adapter))
adapter->itr = opt.def;
} else {
/* If no option specified, use default value and go
* through the logic below to adjust itr/itr_setting
*/
adapter->itr = opt.def;
/* Make sure a message is printed for non-special
* default values
*/
if (adapter->itr > 4)
dev_info(&adapter->pdev->dev,
"%s set to default %d\n", opt.name,
adapter->itr);
}
adapter->itr_setting = adapter->itr;
switch (adapter->itr) {
case 0:
dev_info(&adapter->pdev->dev, "%s turned off\n",
opt.name);
break;
case 1:
dev_info(&adapter->pdev->dev,
"%s set to dynamic mode\n", opt.name);
adapter->itr = 20000;
break;
case 2:
dev_info(&adapter->pdev->dev,
"%s Invalid mode - setting default\n",
opt.name);
adapter->itr_setting = opt.def;
fallthrough;
case 3:
dev_info(&adapter->pdev->dev,
"%s set to dynamic conservative mode\n",
opt.name);
adapter->itr = 20000;
break;
case 4:
dev_info(&adapter->pdev->dev,
"%s set to simplified (2000-8000 ints) mode\n",
opt.name);
break;
default:
/* Save the setting, because the dynamic bits
* change itr.
*
* Clear the lower two bits because
* they are used as control.
*/
adapter->itr_setting &= ~3;
break;
}
}
/* Interrupt Mode */
{
static struct e1000_option opt = {
.type = range_option,
.name = "Interrupt Mode",
#ifndef CONFIG_PCI_MSI
.err = "defaulting to 0 (legacy)",
.def = E1000E_INT_MODE_LEGACY,
.arg = { .r = { .min = 0,
.max = 0 } }
#endif
};
#ifdef CONFIG_PCI_MSI
if (adapter->flags & FLAG_HAS_MSIX) {
opt.err = kstrdup("defaulting to 2 (MSI-X)",
GFP_KERNEL);
opt.def = E1000E_INT_MODE_MSIX;
opt.arg.r.max = E1000E_INT_MODE_MSIX;
} else {
opt.err = kstrdup("defaulting to 1 (MSI)", GFP_KERNEL);
opt.def = E1000E_INT_MODE_MSI;
opt.arg.r.max = E1000E_INT_MODE_MSI;
}
if (!opt.err) {
dev_err(&adapter->pdev->dev,
"Failed to allocate memory\n");
return;
}
#endif
if (num_IntMode > bd) {
unsigned int int_mode = IntMode[bd];
e1000_validate_option(&int_mode, &opt, adapter);
adapter->int_mode = int_mode;
} else {
adapter->int_mode = opt.def;
}
#ifdef CONFIG_PCI_MSI
kfree(opt.err);
#endif
}
/* Smart Power Down */
{
static const struct e1000_option opt = {
.type = enable_option,
.name = "PHY Smart Power Down",
.err = "defaulting to Disabled",
.def = OPTION_DISABLED
};
if (num_SmartPowerDownEnable > bd) {
unsigned int spd = SmartPowerDownEnable[bd];
e1000_validate_option(&spd, &opt, adapter);
if ((adapter->flags & FLAG_HAS_SMART_POWER_DOWN) && spd)
adapter->flags |= FLAG_SMART_POWER_DOWN;
}
}
/* CRC Stripping */
{
static const struct e1000_option opt = {
.type = enable_option,
.name = "CRC Stripping",
.err = "defaulting to Enabled",
.def = OPTION_ENABLED
};
if (num_CrcStripping > bd) {
unsigned int crc_stripping = CrcStripping[bd];
e1000_validate_option(&crc_stripping, &opt, adapter);
if (crc_stripping == OPTION_ENABLED) {
adapter->flags2 |= FLAG2_CRC_STRIPPING;
adapter->flags2 |= FLAG2_DFLT_CRC_STRIPPING;
}
} else {
adapter->flags2 |= FLAG2_CRC_STRIPPING;
adapter->flags2 |= FLAG2_DFLT_CRC_STRIPPING;
}
}
/* Kumeran Lock Loss Workaround */
{
static const struct e1000_option opt = {
.type = enable_option,
.name = "Kumeran Lock Loss Workaround",
.err = "defaulting to Enabled",
.def = OPTION_ENABLED
};
bool enabled = opt.def;
if (num_KumeranLockLoss > bd) {
unsigned int kmrn_lock_loss = KumeranLockLoss[bd];
e1000_validate_option(&kmrn_lock_loss, &opt, adapter);
enabled = kmrn_lock_loss;
}
if (hw->mac.type == e1000_ich8lan)
e1000e_set_kmrn_lock_loss_workaround_ich8lan(hw,
enabled);
}
/* Write-protect NVM */
{
static const struct e1000_option opt = {
.type = enable_option,
.name = "Write-protect NVM",
.err = "defaulting to Enabled",
.def = OPTION_ENABLED
};
if (adapter->flags & FLAG_IS_ICH) {
if (num_WriteProtectNVM > bd) {
unsigned int write_protect_nvm =
WriteProtectNVM[bd];
e1000_validate_option(&write_protect_nvm, &opt,
adapter);
if (write_protect_nvm)
adapter->flags |= FLAG_READ_ONLY_NVM;
} else {
if (opt.def)
adapter->flags |= FLAG_READ_ONLY_NVM;
}
}
}
}

View File

@ -0,0 +1,527 @@
// SPDX-License-Identifier: GPL-2.0
/* Copyright(c) 1999 - 2018 Intel Corporation. */
#include <linux/netdevice.h>
#include <linux/module.h>
#include <linux/pci.h>
#include "e1000.h"
/* This is the only thing that needs to be changed to adjust the
* maximum number of ports that the driver can manage.
*/
#define E1000_MAX_NIC 32
#define OPTION_UNSET -1
#define OPTION_DISABLED 0
#define OPTION_ENABLED 1
#define COPYBREAK_DEFAULT 256
unsigned int copybreak = COPYBREAK_DEFAULT;
module_param(copybreak, uint, 0644);
MODULE_PARM_DESC(copybreak,
"Maximum size of packet that is copied to a new buffer on receive");
/* All parameters are treated the same, as an integer array of values.
* This macro just reduces the need to repeat the same declaration code
* over and over (plus this helps to avoid typo bugs).
*/
#define E1000_PARAM_INIT { [0 ... E1000_MAX_NIC] = OPTION_UNSET }
#define E1000_PARAM(X, desc) \
static int X[E1000_MAX_NIC+1] = E1000_PARAM_INIT; \
static unsigned int num_##X; \
module_param_array_named(X, X, int, &num_##X, 0); \
MODULE_PARM_DESC(X, desc);
/* Transmit Interrupt Delay in units of 1.024 microseconds
* Tx interrupt delay needs to typically be set to something non-zero
*
* Valid Range: 0-65535
*/
E1000_PARAM(TxIntDelay, "Transmit Interrupt Delay");
#define DEFAULT_TIDV 8
#define MAX_TXDELAY 0xFFFF
#define MIN_TXDELAY 0
/* Transmit Absolute Interrupt Delay in units of 1.024 microseconds
*
* Valid Range: 0-65535
*/
E1000_PARAM(TxAbsIntDelay, "Transmit Absolute Interrupt Delay");
#define DEFAULT_TADV 32
#define MAX_TXABSDELAY 0xFFFF
#define MIN_TXABSDELAY 0
/* Receive Interrupt Delay in units of 1.024 microseconds
* hardware will likely hang if you set this to anything but zero.
*
* Burst variant is used as default if device has FLAG2_DMA_BURST.
*
* Valid Range: 0-65535
*/
E1000_PARAM(RxIntDelay, "Receive Interrupt Delay");
#define DEFAULT_RDTR 0
#define BURST_RDTR 0x20
#define MAX_RXDELAY 0xFFFF
#define MIN_RXDELAY 0
/* Receive Absolute Interrupt Delay in units of 1.024 microseconds
*
* Burst variant is used as default if device has FLAG2_DMA_BURST.
*
* Valid Range: 0-65535
*/
E1000_PARAM(RxAbsIntDelay, "Receive Absolute Interrupt Delay");
#define DEFAULT_RADV 8
#define BURST_RADV 0x20
#define MAX_RXABSDELAY 0xFFFF
#define MIN_RXABSDELAY 0
/* Interrupt Throttle Rate (interrupts/sec)
*
* Valid Range: 100-100000 or one of: 0=off, 1=dynamic, 3=dynamic conservative
*/
E1000_PARAM(InterruptThrottleRate, "Interrupt Throttling Rate");
#define DEFAULT_ITR 3
#define MAX_ITR 100000
#define MIN_ITR 100
/* IntMode (Interrupt Mode)
*
* Valid Range: varies depending on kernel configuration & hardware support
*
* legacy=0, MSI=1, MSI-X=2
*
* When MSI/MSI-X support is enabled in kernel-
* Default Value: 2 (MSI-X) when supported by hardware, 1 (MSI) otherwise
* When MSI/MSI-X support is not enabled in kernel-
* Default Value: 0 (legacy)
*
* When a mode is specified that is not allowed/supported, it will be
* demoted to the most advanced interrupt mode available.
*/
E1000_PARAM(IntMode, "Interrupt Mode");
/* Enable Smart Power Down of the PHY
*
* Valid Range: 0, 1
*
* Default Value: 0 (disabled)
*/
E1000_PARAM(SmartPowerDownEnable, "Enable PHY smart power down");
/* Enable Kumeran Lock Loss workaround
*
* Valid Range: 0, 1
*
* Default Value: 1 (enabled)
*/
E1000_PARAM(KumeranLockLoss, "Enable Kumeran lock loss workaround");
/* Write Protect NVM
*
* Valid Range: 0, 1
*
* Default Value: 1 (enabled)
*/
E1000_PARAM(WriteProtectNVM,
"Write-protect NVM [WARNING: disabling this can lead to corrupted NVM]");
/* Enable CRC Stripping
*
* Valid Range: 0, 1
*
* Default Value: 1 (enabled)
*/
E1000_PARAM(CrcStripping,
"Enable CRC Stripping, disable if your BMC needs the CRC");
struct e1000_option {
enum { enable_option, range_option, list_option } type;
const char *name;
const char *err;
int def;
union {
/* range_option info */
struct {
int min;
int max;
} r;
/* list_option info */
struct {
int nr;
struct e1000_opt_list {
int i;
char *str;
} *p;
} l;
} arg;
};
static int e1000_validate_option(unsigned int *value,
const struct e1000_option *opt,
struct e1000_adapter *adapter)
{
if (*value == OPTION_UNSET) {
*value = opt->def;
return 0;
}
switch (opt->type) {
case enable_option:
switch (*value) {
case OPTION_ENABLED:
dev_info(&adapter->pdev->dev, "%s Enabled\n",
opt->name);
return 0;
case OPTION_DISABLED:
dev_info(&adapter->pdev->dev, "%s Disabled\n",
opt->name);
return 0;
}
break;
case range_option:
if (*value >= opt->arg.r.min && *value <= opt->arg.r.max) {
dev_info(&adapter->pdev->dev, "%s set to %i\n",
opt->name, *value);
return 0;
}
break;
case list_option: {
int i;
struct e1000_opt_list *ent;
for (i = 0; i < opt->arg.l.nr; i++) {
ent = &opt->arg.l.p[i];
if (*value == ent->i) {
if (ent->str[0] != '\0')
dev_info(&adapter->pdev->dev, "%s\n",
ent->str);
return 0;
}
}
}
break;
default:
BUG();
}
dev_info(&adapter->pdev->dev, "Invalid %s value specified (%i) %s\n",
opt->name, *value, opt->err);
*value = opt->def;
return -1;
}
/**
* e1000e_check_options - Range Checking for Command Line Parameters
* @adapter: board private structure
*
* This routine checks all command line parameters for valid user
* input. If an invalid value is given, or if no user specified
* value exists, a default value is used. The final value is stored
* in a variable in the adapter structure.
**/
void e1000e_check_options(struct e1000_adapter *adapter)
{
struct e1000_hw *hw = &adapter->hw;
int bd = adapter->bd_number;
if (bd >= E1000_MAX_NIC) {
dev_notice(&adapter->pdev->dev,
"Warning: no configuration for board #%i\n", bd);
dev_notice(&adapter->pdev->dev,
"Using defaults for all values\n");
}
/* Transmit Interrupt Delay */
{
static const struct e1000_option opt = {
.type = range_option,
.name = "Transmit Interrupt Delay",
.err = "using default of "
__MODULE_STRING(DEFAULT_TIDV),
.def = DEFAULT_TIDV,
.arg = { .r = { .min = MIN_TXDELAY,
.max = MAX_TXDELAY } }
};
if (num_TxIntDelay > bd) {
adapter->tx_int_delay = TxIntDelay[bd];
e1000_validate_option(&adapter->tx_int_delay, &opt,
adapter);
} else {
adapter->tx_int_delay = opt.def;
}
}
/* Transmit Absolute Interrupt Delay */
{
static const struct e1000_option opt = {
.type = range_option,
.name = "Transmit Absolute Interrupt Delay",
.err = "using default of "
__MODULE_STRING(DEFAULT_TADV),
.def = DEFAULT_TADV,
.arg = { .r = { .min = MIN_TXABSDELAY,
.max = MAX_TXABSDELAY } }
};
if (num_TxAbsIntDelay > bd) {
adapter->tx_abs_int_delay = TxAbsIntDelay[bd];
e1000_validate_option(&adapter->tx_abs_int_delay, &opt,
adapter);
} else {
adapter->tx_abs_int_delay = opt.def;
}
}
/* Receive Interrupt Delay */
{
static struct e1000_option opt = {
.type = range_option,
.name = "Receive Interrupt Delay",
.err = "using default of "
__MODULE_STRING(DEFAULT_RDTR),
.def = DEFAULT_RDTR,
.arg = { .r = { .min = MIN_RXDELAY,
.max = MAX_RXDELAY } }
};
if (adapter->flags2 & FLAG2_DMA_BURST)
opt.def = BURST_RDTR;
if (num_RxIntDelay > bd) {
adapter->rx_int_delay = RxIntDelay[bd];
e1000_validate_option(&adapter->rx_int_delay, &opt,
adapter);
} else {
adapter->rx_int_delay = opt.def;
}
}
/* Receive Absolute Interrupt Delay */
{
static struct e1000_option opt = {
.type = range_option,
.name = "Receive Absolute Interrupt Delay",
.err = "using default of "
__MODULE_STRING(DEFAULT_RADV),
.def = DEFAULT_RADV,
.arg = { .r = { .min = MIN_RXABSDELAY,
.max = MAX_RXABSDELAY } }
};
if (adapter->flags2 & FLAG2_DMA_BURST)
opt.def = BURST_RADV;
if (num_RxAbsIntDelay > bd) {
adapter->rx_abs_int_delay = RxAbsIntDelay[bd];
e1000_validate_option(&adapter->rx_abs_int_delay, &opt,
adapter);
} else {
adapter->rx_abs_int_delay = opt.def;
}
}
/* Interrupt Throttling Rate */
{
static const struct e1000_option opt = {
.type = range_option,
.name = "Interrupt Throttling Rate (ints/sec)",
.err = "using default of "
__MODULE_STRING(DEFAULT_ITR),
.def = DEFAULT_ITR,
.arg = { .r = { .min = MIN_ITR,
.max = MAX_ITR } }
};
if (num_InterruptThrottleRate > bd) {
adapter->itr = InterruptThrottleRate[bd];
/* Make sure a message is printed for non-special
* values. And in case of an invalid option, display
* warning, use default and go through itr/itr_setting
* adjustment logic below
*/
if ((adapter->itr > 4) &&
e1000_validate_option(&adapter->itr, &opt, adapter))
adapter->itr = opt.def;
} else {
/* If no option specified, use default value and go
* through the logic below to adjust itr/itr_setting
*/
adapter->itr = opt.def;
/* Make sure a message is printed for non-special
* default values
*/
if (adapter->itr > 4)
dev_info(&adapter->pdev->dev,
"%s set to default %d\n", opt.name,
adapter->itr);
}
adapter->itr_setting = adapter->itr;
switch (adapter->itr) {
case 0:
dev_info(&adapter->pdev->dev, "%s turned off\n",
opt.name);
break;
case 1:
dev_info(&adapter->pdev->dev,
"%s set to dynamic mode\n", opt.name);
adapter->itr = 20000;
break;
case 2:
dev_info(&adapter->pdev->dev,
"%s Invalid mode - setting default\n",
opt.name);
adapter->itr_setting = opt.def;
fallthrough;
case 3:
dev_info(&adapter->pdev->dev,
"%s set to dynamic conservative mode\n",
opt.name);
adapter->itr = 20000;
break;
case 4:
dev_info(&adapter->pdev->dev,
"%s set to simplified (2000-8000 ints) mode\n",
opt.name);
break;
default:
/* Save the setting, because the dynamic bits
* change itr.
*
* Clear the lower two bits because
* they are used as control.
*/
adapter->itr_setting &= ~3;
break;
}
}
/* Interrupt Mode */
{
static struct e1000_option opt = {
.type = range_option,
.name = "Interrupt Mode",
#ifndef CONFIG_PCI_MSI
.err = "defaulting to 0 (legacy)",
.def = E1000E_INT_MODE_LEGACY,
.arg = { .r = { .min = 0,
.max = 0 } }
#endif
};
#ifdef CONFIG_PCI_MSI
if (adapter->flags & FLAG_HAS_MSIX) {
opt.err = kstrdup("defaulting to 2 (MSI-X)",
GFP_KERNEL);
opt.def = E1000E_INT_MODE_MSIX;
opt.arg.r.max = E1000E_INT_MODE_MSIX;
} else {
opt.err = kstrdup("defaulting to 1 (MSI)", GFP_KERNEL);
opt.def = E1000E_INT_MODE_MSI;
opt.arg.r.max = E1000E_INT_MODE_MSI;
}
if (!opt.err) {
dev_err(&adapter->pdev->dev,
"Failed to allocate memory\n");
return;
}
#endif
if (num_IntMode > bd) {
unsigned int int_mode = IntMode[bd];
e1000_validate_option(&int_mode, &opt, adapter);
adapter->int_mode = int_mode;
} else {
adapter->int_mode = opt.def;
}
#ifdef CONFIG_PCI_MSI
kfree(opt.err);
#endif
}
/* Smart Power Down */
{
static const struct e1000_option opt = {
.type = enable_option,
.name = "PHY Smart Power Down",
.err = "defaulting to Disabled",
.def = OPTION_DISABLED
};
if (num_SmartPowerDownEnable > bd) {
unsigned int spd = SmartPowerDownEnable[bd];
e1000_validate_option(&spd, &opt, adapter);
if ((adapter->flags & FLAG_HAS_SMART_POWER_DOWN) && spd)
adapter->flags |= FLAG_SMART_POWER_DOWN;
}
}
/* CRC Stripping */
{
static const struct e1000_option opt = {
.type = enable_option,
.name = "CRC Stripping",
.err = "defaulting to Enabled",
.def = OPTION_ENABLED
};
if (num_CrcStripping > bd) {
unsigned int crc_stripping = CrcStripping[bd];
e1000_validate_option(&crc_stripping, &opt, adapter);
if (crc_stripping == OPTION_ENABLED) {
adapter->flags2 |= FLAG2_CRC_STRIPPING;
adapter->flags2 |= FLAG2_DFLT_CRC_STRIPPING;
}
} else {
adapter->flags2 |= FLAG2_CRC_STRIPPING;
adapter->flags2 |= FLAG2_DFLT_CRC_STRIPPING;
}
}
/* Kumeran Lock Loss Workaround */
{
static const struct e1000_option opt = {
.type = enable_option,
.name = "Kumeran Lock Loss Workaround",
.err = "defaulting to Enabled",
.def = OPTION_ENABLED
};
bool enabled = opt.def;
if (num_KumeranLockLoss > bd) {
unsigned int kmrn_lock_loss = KumeranLockLoss[bd];
e1000_validate_option(&kmrn_lock_loss, &opt, adapter);
enabled = kmrn_lock_loss;
}
if (hw->mac.type == e1000_ich8lan)
e1000e_set_kmrn_lock_loss_workaround_ich8lan(hw,
enabled);
}
/* Write-protect NVM */
{
static const struct e1000_option opt = {
.type = enable_option,
.name = "Write-protect NVM",
.err = "defaulting to Enabled",
.def = OPTION_ENABLED
};
if (adapter->flags & FLAG_IS_ICH) {
if (num_WriteProtectNVM > bd) {
unsigned int write_protect_nvm =
WriteProtectNVM[bd];
e1000_validate_option(&write_protect_nvm, &opt,
adapter);
if (write_protect_nvm)
adapter->flags |= FLAG_READ_ONLY_NVM;
} else {
if (opt.def)
adapter->flags |= FLAG_READ_ONLY_NVM;
}
}
}
}

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,218 @@
/* SPDX-License-Identifier: GPL-2.0 */
/* Copyright(c) 1999 - 2018 Intel Corporation. */
#ifndef _E1000E_PHY_H_
#define _E1000E_PHY_H_
s32 e1000e_check_downshift(struct e1000_hw *hw);
s32 e1000_check_polarity_m88(struct e1000_hw *hw);
s32 e1000_check_polarity_igp(struct e1000_hw *hw);
s32 e1000_check_polarity_ife(struct e1000_hw *hw);
s32 e1000e_check_reset_block_generic(struct e1000_hw *hw);
s32 e1000e_copper_link_setup_igp(struct e1000_hw *hw);
s32 e1000e_copper_link_setup_m88(struct e1000_hw *hw);
s32 e1000e_phy_force_speed_duplex_igp(struct e1000_hw *hw);
s32 e1000e_phy_force_speed_duplex_m88(struct e1000_hw *hw);
s32 e1000_phy_force_speed_duplex_ife(struct e1000_hw *hw);
s32 e1000e_get_cable_length_m88(struct e1000_hw *hw);
s32 e1000e_get_cable_length_igp_2(struct e1000_hw *hw);
s32 e1000e_get_cfg_done_generic(struct e1000_hw *hw);
s32 e1000e_get_phy_id(struct e1000_hw *hw);
s32 e1000e_get_phy_info_igp(struct e1000_hw *hw);
s32 e1000e_get_phy_info_m88(struct e1000_hw *hw);
s32 e1000_get_phy_info_ife(struct e1000_hw *hw);
s32 e1000e_phy_sw_reset(struct e1000_hw *hw);
void e1000e_phy_force_speed_duplex_setup(struct e1000_hw *hw, u16 *phy_ctrl);
s32 e1000e_phy_hw_reset_generic(struct e1000_hw *hw);
s32 e1000e_phy_reset_dsp(struct e1000_hw *hw);
s32 e1000e_read_kmrn_reg(struct e1000_hw *hw, u32 offset, u16 *data);
s32 e1000e_read_kmrn_reg_locked(struct e1000_hw *hw, u32 offset, u16 *data);
s32 e1000_set_page_igp(struct e1000_hw *hw, u16 page);
s32 e1000e_read_phy_reg_igp(struct e1000_hw *hw, u32 offset, u16 *data);
s32 e1000e_read_phy_reg_igp_locked(struct e1000_hw *hw, u32 offset, u16 *data);
s32 e1000e_read_phy_reg_m88(struct e1000_hw *hw, u32 offset, u16 *data);
s32 e1000e_set_d3_lplu_state(struct e1000_hw *hw, bool active);
s32 e1000e_setup_copper_link(struct e1000_hw *hw);
s32 e1000e_write_kmrn_reg(struct e1000_hw *hw, u32 offset, u16 data);
s32 e1000e_write_kmrn_reg_locked(struct e1000_hw *hw, u32 offset, u16 data);
s32 e1000e_write_phy_reg_igp(struct e1000_hw *hw, u32 offset, u16 data);
s32 e1000e_write_phy_reg_igp_locked(struct e1000_hw *hw, u32 offset, u16 data);
s32 e1000e_write_phy_reg_m88(struct e1000_hw *hw, u32 offset, u16 data);
s32 e1000e_phy_has_link_generic(struct e1000_hw *hw, u32 iterations,
u32 usec_interval, bool *success);
s32 e1000e_phy_init_script_igp3(struct e1000_hw *hw);
enum e1000_phy_type e1000e_get_phy_type_from_id(u32 phy_id);
s32 e1000e_determine_phy_address(struct e1000_hw *hw);
s32 e1000e_write_phy_reg_bm(struct e1000_hw *hw, u32 offset, u16 data);
s32 e1000e_read_phy_reg_bm(struct e1000_hw *hw, u32 offset, u16 *data);
s32 e1000_enable_phy_wakeup_reg_access_bm(struct e1000_hw *hw, u16 *phy_reg);
s32 e1000_disable_phy_wakeup_reg_access_bm(struct e1000_hw *hw, u16 *phy_reg);
s32 e1000e_read_phy_reg_bm2(struct e1000_hw *hw, u32 offset, u16 *data);
s32 e1000e_write_phy_reg_bm2(struct e1000_hw *hw, u32 offset, u16 data);
void e1000_power_up_phy_copper(struct e1000_hw *hw);
void e1000_power_down_phy_copper(struct e1000_hw *hw);
s32 e1000e_read_phy_reg_mdic(struct e1000_hw *hw, u32 offset, u16 *data);
s32 e1000e_write_phy_reg_mdic(struct e1000_hw *hw, u32 offset, u16 data);
s32 e1000_read_phy_reg_hv(struct e1000_hw *hw, u32 offset, u16 *data);
s32 e1000_read_phy_reg_hv_locked(struct e1000_hw *hw, u32 offset, u16 *data);
s32 e1000_read_phy_reg_page_hv(struct e1000_hw *hw, u32 offset, u16 *data);
s32 e1000_write_phy_reg_hv(struct e1000_hw *hw, u32 offset, u16 data);
s32 e1000_write_phy_reg_hv_locked(struct e1000_hw *hw, u32 offset, u16 data);
s32 e1000_write_phy_reg_page_hv(struct e1000_hw *hw, u32 offset, u16 data);
s32 e1000_link_stall_workaround_hv(struct e1000_hw *hw);
s32 e1000_copper_link_setup_82577(struct e1000_hw *hw);
s32 e1000_check_polarity_82577(struct e1000_hw *hw);
s32 e1000_get_phy_info_82577(struct e1000_hw *hw);
s32 e1000_phy_force_speed_duplex_82577(struct e1000_hw *hw);
s32 e1000_get_cable_length_82577(struct e1000_hw *hw);
#define E1000_MAX_PHY_ADDR 8
/* IGP01E1000 Specific Registers */
#define IGP01E1000_PHY_PORT_CONFIG 0x10 /* Port Config */
#define IGP01E1000_PHY_PORT_STATUS 0x11 /* Status */
#define IGP01E1000_PHY_PORT_CTRL 0x12 /* Control */
#define IGP01E1000_PHY_LINK_HEALTH 0x13 /* PHY Link Health */
#define IGP02E1000_PHY_POWER_MGMT 0x19 /* Power Management */
#define IGP01E1000_PHY_PAGE_SELECT 0x1F /* Page Select */
#define BM_PHY_PAGE_SELECT 22 /* Page Select for BM */
#define IGP_PAGE_SHIFT 5
#define PHY_REG_MASK 0x1F
/* BM/HV Specific Registers */
#define BM_PORT_CTRL_PAGE 769
#define BM_WUC_PAGE 800
#define BM_WUC_ADDRESS_OPCODE 0x11
#define BM_WUC_DATA_OPCODE 0x12
#define BM_WUC_ENABLE_PAGE BM_PORT_CTRL_PAGE
#define BM_WUC_ENABLE_REG 17
#define BM_WUC_ENABLE_BIT BIT(2)
#define BM_WUC_HOST_WU_BIT BIT(4)
#define BM_WUC_ME_WU_BIT BIT(5)
#define PHY_UPPER_SHIFT 21
#define BM_PHY_REG(page, reg) \
(((reg) & MAX_PHY_REG_ADDRESS) |\
(((page) & 0xFFFF) << PHY_PAGE_SHIFT) |\
(((reg) & ~MAX_PHY_REG_ADDRESS) << (PHY_UPPER_SHIFT - PHY_PAGE_SHIFT)))
#define BM_PHY_REG_PAGE(offset) \
((u16)(((offset) >> PHY_PAGE_SHIFT) & 0xFFFF))
#define BM_PHY_REG_NUM(offset) \
((u16)(((offset) & MAX_PHY_REG_ADDRESS) |\
(((offset) >> (PHY_UPPER_SHIFT - PHY_PAGE_SHIFT)) &\
~MAX_PHY_REG_ADDRESS)))
#define HV_INTC_FC_PAGE_START 768
#define I82578_ADDR_REG 29
#define I82577_ADDR_REG 16
#define I82577_CFG_REG 22
#define I82577_CFG_ASSERT_CRS_ON_TX BIT(15)
#define I82577_CFG_ENABLE_DOWNSHIFT (3u << 10) /* auto downshift */
#define I82577_CTRL_REG 23
/* 82577 specific PHY registers */
#define I82577_PHY_CTRL_2 18
#define I82577_PHY_LBK_CTRL 19
#define I82577_PHY_STATUS_2 26
#define I82577_PHY_DIAG_STATUS 31
/* I82577 PHY Status 2 */
#define I82577_PHY_STATUS2_REV_POLARITY 0x0400
#define I82577_PHY_STATUS2_MDIX 0x0800
#define I82577_PHY_STATUS2_SPEED_MASK 0x0300
#define I82577_PHY_STATUS2_SPEED_1000MBPS 0x0200
/* I82577 PHY Control 2 */
#define I82577_PHY_CTRL2_MANUAL_MDIX 0x0200
#define I82577_PHY_CTRL2_AUTO_MDI_MDIX 0x0400
#define I82577_PHY_CTRL2_MDIX_CFG_MASK 0x0600
/* I82577 PHY Diagnostics Status */
#define I82577_DSTATUS_CABLE_LENGTH 0x03FC
#define I82577_DSTATUS_CABLE_LENGTH_SHIFT 2
/* BM PHY Copper Specific Control 1 */
#define BM_CS_CTRL1 16
/* BM PHY Copper Specific Status */
#define BM_CS_STATUS 17
#define BM_CS_STATUS_LINK_UP 0x0400
#define BM_CS_STATUS_RESOLVED 0x0800
#define BM_CS_STATUS_SPEED_MASK 0xC000
#define BM_CS_STATUS_SPEED_1000 0x8000
/* 82577 Mobile Phy Status Register */
#define HV_M_STATUS 26
#define HV_M_STATUS_AUTONEG_COMPLETE 0x1000
#define HV_M_STATUS_SPEED_MASK 0x0300
#define HV_M_STATUS_SPEED_1000 0x0200
#define HV_M_STATUS_SPEED_100 0x0100
#define HV_M_STATUS_LINK_UP 0x0040
#define IGP01E1000_PHY_PCS_INIT_REG 0x00B4
#define IGP01E1000_PHY_POLARITY_MASK 0x0078
#define IGP01E1000_PSCR_AUTO_MDIX 0x1000
#define IGP01E1000_PSCR_FORCE_MDI_MDIX 0x2000 /* 0=MDI, 1=MDIX */
#define IGP01E1000_PSCFR_SMART_SPEED 0x0080
#define IGP02E1000_PM_SPD 0x0001 /* Smart Power Down */
#define IGP02E1000_PM_D0_LPLU 0x0002 /* For D0a states */
#define IGP02E1000_PM_D3_LPLU 0x0004 /* For all other states */
#define IGP01E1000_PLHR_SS_DOWNGRADE 0x8000
#define IGP01E1000_PSSR_POLARITY_REVERSED 0x0002
#define IGP01E1000_PSSR_MDIX 0x0800
#define IGP01E1000_PSSR_SPEED_MASK 0xC000
#define IGP01E1000_PSSR_SPEED_1000MBPS 0xC000
#define IGP02E1000_PHY_CHANNEL_NUM 4
#define IGP02E1000_PHY_AGC_A 0x11B1
#define IGP02E1000_PHY_AGC_B 0x12B1
#define IGP02E1000_PHY_AGC_C 0x14B1
#define IGP02E1000_PHY_AGC_D 0x18B1
#define IGP02E1000_AGC_LENGTH_SHIFT 9 /* Course=15:13, Fine=12:9 */
#define IGP02E1000_AGC_LENGTH_MASK 0x7F
#define IGP02E1000_AGC_RANGE 15
#define E1000_CABLE_LENGTH_UNDEFINED 0xFF
#define E1000_KMRNCTRLSTA_OFFSET 0x001F0000
#define E1000_KMRNCTRLSTA_OFFSET_SHIFT 16
#define E1000_KMRNCTRLSTA_REN 0x00200000
#define E1000_KMRNCTRLSTA_CTRL_OFFSET 0x1 /* Kumeran Control */
#define E1000_KMRNCTRLSTA_DIAG_OFFSET 0x3 /* Kumeran Diagnostic */
#define E1000_KMRNCTRLSTA_TIMEOUTS 0x4 /* Kumeran Timeouts */
#define E1000_KMRNCTRLSTA_INBAND_PARAM 0x9 /* Kumeran InBand Parameters */
#define E1000_KMRNCTRLSTA_IBIST_DISABLE 0x0200 /* Kumeran IBIST Disable */
#define E1000_KMRNCTRLSTA_DIAG_NELPBK 0x1000 /* Nearend Loopback mode */
#define E1000_KMRNCTRLSTA_K1_CONFIG 0x7
#define E1000_KMRNCTRLSTA_K1_ENABLE 0x0002 /* enable K1 */
#define E1000_KMRNCTRLSTA_HD_CTRL 0x10 /* Kumeran HD Control */
#define IFE_PHY_EXTENDED_STATUS_CONTROL 0x10
#define IFE_PHY_SPECIAL_CONTROL 0x11 /* 100BaseTx PHY Special Ctrl */
#define IFE_PHY_SPECIAL_CONTROL_LED 0x1B /* PHY Special and LED Ctrl */
#define IFE_PHY_MDIX_CONTROL 0x1C /* MDI/MDI-X Control */
/* IFE PHY Extended Status Control */
#define IFE_PESC_POLARITY_REVERSED 0x0100
/* IFE PHY Special Control */
#define IFE_PSC_AUTO_POLARITY_DISABLE 0x0010
#define IFE_PSC_FORCE_POLARITY 0x0020
/* IFE PHY Special Control and LED Control */
#define IFE_PSCL_PROBE_MODE 0x0020
#define IFE_PSCL_PROBE_LEDS_OFF 0x0006 /* Force LEDs 0 and 2 off */
#define IFE_PSCL_PROBE_LEDS_ON 0x0007 /* Force LEDs 0 and 2 on */
/* IFE PHY MDIX Control */
#define IFE_PMC_MDIX_STATUS 0x0020 /* 1=MDI-X, 0=MDI */
#define IFE_PMC_FORCE_MDIX 0x0040 /* 1=force MDI-X, 0=force MDI */
#define IFE_PMC_AUTO_MDIX 0x0080 /* 1=enable auto, 0=disable */
#endif

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,218 @@
/* SPDX-License-Identifier: GPL-2.0 */
/* Copyright(c) 1999 - 2018 Intel Corporation. */
#ifndef _E1000E_PHY_H_
#define _E1000E_PHY_H_
s32 e1000e_check_downshift(struct e1000_hw *hw);
s32 e1000_check_polarity_m88(struct e1000_hw *hw);
s32 e1000_check_polarity_igp(struct e1000_hw *hw);
s32 e1000_check_polarity_ife(struct e1000_hw *hw);
s32 e1000e_check_reset_block_generic(struct e1000_hw *hw);
s32 e1000e_copper_link_setup_igp(struct e1000_hw *hw);
s32 e1000e_copper_link_setup_m88(struct e1000_hw *hw);
s32 e1000e_phy_force_speed_duplex_igp(struct e1000_hw *hw);
s32 e1000e_phy_force_speed_duplex_m88(struct e1000_hw *hw);
s32 e1000_phy_force_speed_duplex_ife(struct e1000_hw *hw);
s32 e1000e_get_cable_length_m88(struct e1000_hw *hw);
s32 e1000e_get_cable_length_igp_2(struct e1000_hw *hw);
s32 e1000e_get_cfg_done_generic(struct e1000_hw *hw);
s32 e1000e_get_phy_id(struct e1000_hw *hw);
s32 e1000e_get_phy_info_igp(struct e1000_hw *hw);
s32 e1000e_get_phy_info_m88(struct e1000_hw *hw);
s32 e1000_get_phy_info_ife(struct e1000_hw *hw);
s32 e1000e_phy_sw_reset(struct e1000_hw *hw);
void e1000e_phy_force_speed_duplex_setup(struct e1000_hw *hw, u16 *phy_ctrl);
s32 e1000e_phy_hw_reset_generic(struct e1000_hw *hw);
s32 e1000e_phy_reset_dsp(struct e1000_hw *hw);
s32 e1000e_read_kmrn_reg(struct e1000_hw *hw, u32 offset, u16 *data);
s32 e1000e_read_kmrn_reg_locked(struct e1000_hw *hw, u32 offset, u16 *data);
s32 e1000_set_page_igp(struct e1000_hw *hw, u16 page);
s32 e1000e_read_phy_reg_igp(struct e1000_hw *hw, u32 offset, u16 *data);
s32 e1000e_read_phy_reg_igp_locked(struct e1000_hw *hw, u32 offset, u16 *data);
s32 e1000e_read_phy_reg_m88(struct e1000_hw *hw, u32 offset, u16 *data);
s32 e1000e_set_d3_lplu_state(struct e1000_hw *hw, bool active);
s32 e1000e_setup_copper_link(struct e1000_hw *hw);
s32 e1000e_write_kmrn_reg(struct e1000_hw *hw, u32 offset, u16 data);
s32 e1000e_write_kmrn_reg_locked(struct e1000_hw *hw, u32 offset, u16 data);
s32 e1000e_write_phy_reg_igp(struct e1000_hw *hw, u32 offset, u16 data);
s32 e1000e_write_phy_reg_igp_locked(struct e1000_hw *hw, u32 offset, u16 data);
s32 e1000e_write_phy_reg_m88(struct e1000_hw *hw, u32 offset, u16 data);
s32 e1000e_phy_has_link_generic(struct e1000_hw *hw, u32 iterations,
u32 usec_interval, bool *success);
s32 e1000e_phy_init_script_igp3(struct e1000_hw *hw);
enum e1000_phy_type e1000e_get_phy_type_from_id(u32 phy_id);
s32 e1000e_determine_phy_address(struct e1000_hw *hw);
s32 e1000e_write_phy_reg_bm(struct e1000_hw *hw, u32 offset, u16 data);
s32 e1000e_read_phy_reg_bm(struct e1000_hw *hw, u32 offset, u16 *data);
s32 e1000_enable_phy_wakeup_reg_access_bm(struct e1000_hw *hw, u16 *phy_reg);
s32 e1000_disable_phy_wakeup_reg_access_bm(struct e1000_hw *hw, u16 *phy_reg);
s32 e1000e_read_phy_reg_bm2(struct e1000_hw *hw, u32 offset, u16 *data);
s32 e1000e_write_phy_reg_bm2(struct e1000_hw *hw, u32 offset, u16 data);
void e1000_power_up_phy_copper(struct e1000_hw *hw);
void e1000_power_down_phy_copper(struct e1000_hw *hw);
s32 e1000e_read_phy_reg_mdic(struct e1000_hw *hw, u32 offset, u16 *data);
s32 e1000e_write_phy_reg_mdic(struct e1000_hw *hw, u32 offset, u16 data);
s32 e1000_read_phy_reg_hv(struct e1000_hw *hw, u32 offset, u16 *data);
s32 e1000_read_phy_reg_hv_locked(struct e1000_hw *hw, u32 offset, u16 *data);
s32 e1000_read_phy_reg_page_hv(struct e1000_hw *hw, u32 offset, u16 *data);
s32 e1000_write_phy_reg_hv(struct e1000_hw *hw, u32 offset, u16 data);
s32 e1000_write_phy_reg_hv_locked(struct e1000_hw *hw, u32 offset, u16 data);
s32 e1000_write_phy_reg_page_hv(struct e1000_hw *hw, u32 offset, u16 data);
s32 e1000_link_stall_workaround_hv(struct e1000_hw *hw);
s32 e1000_copper_link_setup_82577(struct e1000_hw *hw);
s32 e1000_check_polarity_82577(struct e1000_hw *hw);
s32 e1000_get_phy_info_82577(struct e1000_hw *hw);
s32 e1000_phy_force_speed_duplex_82577(struct e1000_hw *hw);
s32 e1000_get_cable_length_82577(struct e1000_hw *hw);
#define E1000_MAX_PHY_ADDR 8
/* IGP01E1000 Specific Registers */
#define IGP01E1000_PHY_PORT_CONFIG 0x10 /* Port Config */
#define IGP01E1000_PHY_PORT_STATUS 0x11 /* Status */
#define IGP01E1000_PHY_PORT_CTRL 0x12 /* Control */
#define IGP01E1000_PHY_LINK_HEALTH 0x13 /* PHY Link Health */
#define IGP02E1000_PHY_POWER_MGMT 0x19 /* Power Management */
#define IGP01E1000_PHY_PAGE_SELECT 0x1F /* Page Select */
#define BM_PHY_PAGE_SELECT 22 /* Page Select for BM */
#define IGP_PAGE_SHIFT 5
#define PHY_REG_MASK 0x1F
/* BM/HV Specific Registers */
#define BM_PORT_CTRL_PAGE 769
#define BM_WUC_PAGE 800
#define BM_WUC_ADDRESS_OPCODE 0x11
#define BM_WUC_DATA_OPCODE 0x12
#define BM_WUC_ENABLE_PAGE BM_PORT_CTRL_PAGE
#define BM_WUC_ENABLE_REG 17
#define BM_WUC_ENABLE_BIT BIT(2)
#define BM_WUC_HOST_WU_BIT BIT(4)
#define BM_WUC_ME_WU_BIT BIT(5)
#define PHY_UPPER_SHIFT 21
#define BM_PHY_REG(page, reg) \
(((reg) & MAX_PHY_REG_ADDRESS) |\
(((page) & 0xFFFF) << PHY_PAGE_SHIFT) |\
(((reg) & ~MAX_PHY_REG_ADDRESS) << (PHY_UPPER_SHIFT - PHY_PAGE_SHIFT)))
#define BM_PHY_REG_PAGE(offset) \
((u16)(((offset) >> PHY_PAGE_SHIFT) & 0xFFFF))
#define BM_PHY_REG_NUM(offset) \
((u16)(((offset) & MAX_PHY_REG_ADDRESS) |\
(((offset) >> (PHY_UPPER_SHIFT - PHY_PAGE_SHIFT)) &\
~MAX_PHY_REG_ADDRESS)))
#define HV_INTC_FC_PAGE_START 768
#define I82578_ADDR_REG 29
#define I82577_ADDR_REG 16
#define I82577_CFG_REG 22
#define I82577_CFG_ASSERT_CRS_ON_TX BIT(15)
#define I82577_CFG_ENABLE_DOWNSHIFT (3u << 10) /* auto downshift */
#define I82577_CTRL_REG 23
/* 82577 specific PHY registers */
#define I82577_PHY_CTRL_2 18
#define I82577_PHY_LBK_CTRL 19
#define I82577_PHY_STATUS_2 26
#define I82577_PHY_DIAG_STATUS 31
/* I82577 PHY Status 2 */
#define I82577_PHY_STATUS2_REV_POLARITY 0x0400
#define I82577_PHY_STATUS2_MDIX 0x0800
#define I82577_PHY_STATUS2_SPEED_MASK 0x0300
#define I82577_PHY_STATUS2_SPEED_1000MBPS 0x0200
/* I82577 PHY Control 2 */
#define I82577_PHY_CTRL2_MANUAL_MDIX 0x0200
#define I82577_PHY_CTRL2_AUTO_MDI_MDIX 0x0400
#define I82577_PHY_CTRL2_MDIX_CFG_MASK 0x0600
/* I82577 PHY Diagnostics Status */
#define I82577_DSTATUS_CABLE_LENGTH 0x03FC
#define I82577_DSTATUS_CABLE_LENGTH_SHIFT 2
/* BM PHY Copper Specific Control 1 */
#define BM_CS_CTRL1 16
/* BM PHY Copper Specific Status */
#define BM_CS_STATUS 17
#define BM_CS_STATUS_LINK_UP 0x0400
#define BM_CS_STATUS_RESOLVED 0x0800
#define BM_CS_STATUS_SPEED_MASK 0xC000
#define BM_CS_STATUS_SPEED_1000 0x8000
/* 82577 Mobile Phy Status Register */
#define HV_M_STATUS 26
#define HV_M_STATUS_AUTONEG_COMPLETE 0x1000
#define HV_M_STATUS_SPEED_MASK 0x0300
#define HV_M_STATUS_SPEED_1000 0x0200
#define HV_M_STATUS_SPEED_100 0x0100
#define HV_M_STATUS_LINK_UP 0x0040
#define IGP01E1000_PHY_PCS_INIT_REG 0x00B4
#define IGP01E1000_PHY_POLARITY_MASK 0x0078
#define IGP01E1000_PSCR_AUTO_MDIX 0x1000
#define IGP01E1000_PSCR_FORCE_MDI_MDIX 0x2000 /* 0=MDI, 1=MDIX */
#define IGP01E1000_PSCFR_SMART_SPEED 0x0080
#define IGP02E1000_PM_SPD 0x0001 /* Smart Power Down */
#define IGP02E1000_PM_D0_LPLU 0x0002 /* For D0a states */
#define IGP02E1000_PM_D3_LPLU 0x0004 /* For all other states */
#define IGP01E1000_PLHR_SS_DOWNGRADE 0x8000
#define IGP01E1000_PSSR_POLARITY_REVERSED 0x0002
#define IGP01E1000_PSSR_MDIX 0x0800
#define IGP01E1000_PSSR_SPEED_MASK 0xC000
#define IGP01E1000_PSSR_SPEED_1000MBPS 0xC000
#define IGP02E1000_PHY_CHANNEL_NUM 4
#define IGP02E1000_PHY_AGC_A 0x11B1
#define IGP02E1000_PHY_AGC_B 0x12B1
#define IGP02E1000_PHY_AGC_C 0x14B1
#define IGP02E1000_PHY_AGC_D 0x18B1
#define IGP02E1000_AGC_LENGTH_SHIFT 9 /* Course=15:13, Fine=12:9 */
#define IGP02E1000_AGC_LENGTH_MASK 0x7F
#define IGP02E1000_AGC_RANGE 15
#define E1000_CABLE_LENGTH_UNDEFINED 0xFF
#define E1000_KMRNCTRLSTA_OFFSET 0x001F0000
#define E1000_KMRNCTRLSTA_OFFSET_SHIFT 16
#define E1000_KMRNCTRLSTA_REN 0x00200000
#define E1000_KMRNCTRLSTA_CTRL_OFFSET 0x1 /* Kumeran Control */
#define E1000_KMRNCTRLSTA_DIAG_OFFSET 0x3 /* Kumeran Diagnostic */
#define E1000_KMRNCTRLSTA_TIMEOUTS 0x4 /* Kumeran Timeouts */
#define E1000_KMRNCTRLSTA_INBAND_PARAM 0x9 /* Kumeran InBand Parameters */
#define E1000_KMRNCTRLSTA_IBIST_DISABLE 0x0200 /* Kumeran IBIST Disable */
#define E1000_KMRNCTRLSTA_DIAG_NELPBK 0x1000 /* Nearend Loopback mode */
#define E1000_KMRNCTRLSTA_K1_CONFIG 0x7
#define E1000_KMRNCTRLSTA_K1_ENABLE 0x0002 /* enable K1 */
#define E1000_KMRNCTRLSTA_HD_CTRL 0x10 /* Kumeran HD Control */
#define IFE_PHY_EXTENDED_STATUS_CONTROL 0x10
#define IFE_PHY_SPECIAL_CONTROL 0x11 /* 100BaseTx PHY Special Ctrl */
#define IFE_PHY_SPECIAL_CONTROL_LED 0x1B /* PHY Special and LED Ctrl */
#define IFE_PHY_MDIX_CONTROL 0x1C /* MDI/MDI-X Control */
/* IFE PHY Extended Status Control */
#define IFE_PESC_POLARITY_REVERSED 0x0100
/* IFE PHY Special Control */
#define IFE_PSC_AUTO_POLARITY_DISABLE 0x0010
#define IFE_PSC_FORCE_POLARITY 0x0020
/* IFE PHY Special Control and LED Control */
#define IFE_PSCL_PROBE_MODE 0x0020
#define IFE_PSCL_PROBE_LEDS_OFF 0x0006 /* Force LEDs 0 and 2 off */
#define IFE_PSCL_PROBE_LEDS_ON 0x0007 /* Force LEDs 0 and 2 on */
/* IFE PHY MDIX Control */
#define IFE_PMC_MDIX_STATUS 0x0020 /* 1=MDI-X, 0=MDI */
#define IFE_PMC_FORCE_MDIX 0x0040 /* 1=force MDI-X, 0=force MDI */
#define IFE_PMC_AUTO_MDIX 0x0080 /* 1=enable auto, 0=disable */
#endif

View File

@ -0,0 +1,346 @@
// SPDX-License-Identifier: GPL-2.0
/* Copyright(c) 1999 - 2018 Intel Corporation. */
/* PTP 1588 Hardware Clock (PHC)
* Derived from PTP Hardware Clock driver for Intel 82576 and 82580 (igb)
* Copyright (C) 2011 Richard Cochran <richardcochran@gmail.com>
*/
#include "e1000-6.4-ethercat.h"
#ifdef CONFIG_E1000E_HWTS
#include <linux/clocksource.h>
#include <linux/ktime.h>
#include <asm/tsc.h>
#endif
/**
* e1000e_phc_adjfine - adjust the frequency of the hardware clock
* @ptp: ptp clock structure
* @delta: Desired frequency chance in scaled parts per million
*
* Adjust the frequency of the PHC cycle counter by the indicated delta from
* the base frequency.
*
* Scaled parts per million is ppm but with a 16 bit binary fractional field.
**/
static int e1000e_phc_adjfine(struct ptp_clock_info *ptp, long delta)
{
struct e1000_adapter *adapter = container_of(ptp, struct e1000_adapter,
ptp_clock_info);
struct e1000_hw *hw = &adapter->hw;
unsigned long flags;
u64 incvalue;
u32 timinca;
s32 ret_val;
/* Get the System Time Register SYSTIM base frequency */
ret_val = e1000e_get_base_timinca(adapter, &timinca);
if (ret_val)
return ret_val;
spin_lock_irqsave(&adapter->systim_lock, flags);
incvalue = timinca & E1000_TIMINCA_INCVALUE_MASK;
incvalue = adjust_by_scaled_ppm(incvalue, delta);
timinca &= ~E1000_TIMINCA_INCVALUE_MASK;
timinca |= incvalue;
ew32(TIMINCA, timinca);
adapter->ptp_delta = delta;
spin_unlock_irqrestore(&adapter->systim_lock, flags);
return 0;
}
/**
* e1000e_phc_adjtime - Shift the time of the hardware clock
* @ptp: ptp clock structure
* @delta: Desired change in nanoseconds
*
* Adjust the timer by resetting the timecounter structure.
**/
static int e1000e_phc_adjtime(struct ptp_clock_info *ptp, s64 delta)
{
struct e1000_adapter *adapter = container_of(ptp, struct e1000_adapter,
ptp_clock_info);
unsigned long flags;
spin_lock_irqsave(&adapter->systim_lock, flags);
timecounter_adjtime(&adapter->tc, delta);
spin_unlock_irqrestore(&adapter->systim_lock, flags);
return 0;
}
#ifdef CONFIG_E1000E_HWTS
#define MAX_HW_WAIT_COUNT (3)
/**
* e1000e_phc_get_syncdevicetime - Callback given to timekeeping code reads system/device registers
* @device: current device time
* @system: system counter value read synchronously with device time
* @ctx: context provided by timekeeping code
*
* Read device and system (ART) clock simultaneously and return the corrected
* clock values in ns.
**/
static int e1000e_phc_get_syncdevicetime(ktime_t *device,
struct system_counterval_t *system,
void *ctx)
{
struct e1000_adapter *adapter = (struct e1000_adapter *)ctx;
struct e1000_hw *hw = &adapter->hw;
unsigned long flags;
int i;
u32 tsync_ctrl;
u64 dev_cycles;
u64 sys_cycles;
tsync_ctrl = er32(TSYNCTXCTL);
tsync_ctrl |= E1000_TSYNCTXCTL_START_SYNC |
E1000_TSYNCTXCTL_MAX_ALLOWED_DLY_MASK;
ew32(TSYNCTXCTL, tsync_ctrl);
for (i = 0; i < MAX_HW_WAIT_COUNT; ++i) {
udelay(1);
tsync_ctrl = er32(TSYNCTXCTL);
if (tsync_ctrl & E1000_TSYNCTXCTL_SYNC_COMP)
break;
}
if (i == MAX_HW_WAIT_COUNT)
return -ETIMEDOUT;
dev_cycles = er32(SYSSTMPH);
dev_cycles <<= 32;
dev_cycles |= er32(SYSSTMPL);
spin_lock_irqsave(&adapter->systim_lock, flags);
*device = ns_to_ktime(timecounter_cyc2time(&adapter->tc, dev_cycles));
spin_unlock_irqrestore(&adapter->systim_lock, flags);
sys_cycles = er32(PLTSTMPH);
sys_cycles <<= 32;
sys_cycles |= er32(PLTSTMPL);
*system = convert_art_to_tsc(sys_cycles);
return 0;
}
/**
* e1000e_phc_getcrosststamp - Reads the current system/device cross timestamp
* @ptp: ptp clock structure
* @xtstamp: structure containing timestamp
*
* Read device and system (ART) clock simultaneously and return the scaled
* clock values in ns.
**/
static int e1000e_phc_getcrosststamp(struct ptp_clock_info *ptp,
struct system_device_crosststamp *xtstamp)
{
struct e1000_adapter *adapter = container_of(ptp, struct e1000_adapter,
ptp_clock_info);
return get_device_system_crosststamp(e1000e_phc_get_syncdevicetime,
adapter, NULL, xtstamp);
}
#endif/*CONFIG_E1000E_HWTS*/
/**
* e1000e_phc_gettimex - Reads the current time from the hardware clock and
* system clock
* @ptp: ptp clock structure
* @ts: timespec structure to hold the current PHC time
* @sts: structure to hold the current system time
*
* Read the timecounter and return the correct value in ns after converting
* it into a struct timespec.
**/
static int e1000e_phc_gettimex(struct ptp_clock_info *ptp,
struct timespec64 *ts,
struct ptp_system_timestamp *sts)
{
struct e1000_adapter *adapter = container_of(ptp, struct e1000_adapter,
ptp_clock_info);
unsigned long flags;
u64 cycles, ns;
spin_lock_irqsave(&adapter->systim_lock, flags);
/* NOTE: Non-monotonic SYSTIM readings may be returned */
cycles = e1000e_read_systim(adapter, sts);
ns = timecounter_cyc2time(&adapter->tc, cycles);
spin_unlock_irqrestore(&adapter->systim_lock, flags);
*ts = ns_to_timespec64(ns);
return 0;
}
/**
* e1000e_phc_settime - Set the current time on the hardware clock
* @ptp: ptp clock structure
* @ts: timespec containing the new time for the cycle counter
*
* Reset the timecounter to use a new base value instead of the kernel
* wall timer value.
**/
static int e1000e_phc_settime(struct ptp_clock_info *ptp,
const struct timespec64 *ts)
{
struct e1000_adapter *adapter = container_of(ptp, struct e1000_adapter,
ptp_clock_info);
unsigned long flags;
u64 ns;
ns = timespec64_to_ns(ts);
/* reset the timecounter */
spin_lock_irqsave(&adapter->systim_lock, flags);
timecounter_init(&adapter->tc, &adapter->cc, ns);
spin_unlock_irqrestore(&adapter->systim_lock, flags);
return 0;
}
/**
* e1000e_phc_enable - enable or disable an ancillary feature
* @ptp: ptp clock structure
* @request: Desired resource to enable or disable
* @on: Caller passes one to enable or zero to disable
*
* Enable (or disable) ancillary features of the PHC subsystem.
* Currently, no ancillary features are supported.
**/
static int e1000e_phc_enable(struct ptp_clock_info __always_unused *ptp,
struct ptp_clock_request __always_unused *request,
int __always_unused on)
{
return -EOPNOTSUPP;
}
static void e1000e_systim_overflow_work(struct work_struct *work)
{
struct e1000_adapter *adapter = container_of(work, struct e1000_adapter,
systim_overflow_work.work);
struct e1000_hw *hw = &adapter->hw;
struct timespec64 ts;
u64 ns;
/* Update the timecounter */
ns = timecounter_read(&adapter->tc);
ts = ns_to_timespec64(ns);
e_dbg("SYSTIM overflow check at %lld.%09lu\n",
(long long) ts.tv_sec, ts.tv_nsec);
schedule_delayed_work(&adapter->systim_overflow_work,
E1000_SYSTIM_OVERFLOW_PERIOD);
}
static const struct ptp_clock_info e1000e_ptp_clock_info = {
.owner = THIS_MODULE,
.n_alarm = 0,
.n_ext_ts = 0,
.n_per_out = 0,
.n_pins = 0,
.pps = 0,
.adjfine = e1000e_phc_adjfine,
.adjtime = e1000e_phc_adjtime,
.gettimex64 = e1000e_phc_gettimex,
.settime64 = e1000e_phc_settime,
.enable = e1000e_phc_enable,
};
/**
* e1000e_ptp_init - initialize PTP for devices which support it
* @adapter: board private structure
*
* This function performs the required steps for enabling PTP support.
* If PTP support has already been loaded it simply calls the cyclecounter
* init routine and exits.
**/
void e1000e_ptp_init(struct e1000_adapter *adapter)
{
struct e1000_hw *hw = &adapter->hw;
adapter->ptp_clock = NULL;
if (!(adapter->flags & FLAG_HAS_HW_TIMESTAMP))
return;
adapter->ptp_clock_info = e1000e_ptp_clock_info;
snprintf(adapter->ptp_clock_info.name,
sizeof(adapter->ptp_clock_info.name), "%pm",
adapter->netdev->perm_addr);
switch (hw->mac.type) {
case e1000_pch2lan:
case e1000_pch_lpt:
case e1000_pch_spt:
case e1000_pch_cnp:
case e1000_pch_tgp:
case e1000_pch_adp:
case e1000_pch_mtp:
case e1000_pch_lnp:
case e1000_pch_ptp:
if ((hw->mac.type < e1000_pch_lpt) ||
(er32(TSYNCRXCTL) & E1000_TSYNCRXCTL_SYSCFI)) {
adapter->ptp_clock_info.max_adj = 24000000 - 1;
break;
}
fallthrough;
case e1000_82574:
case e1000_82583:
adapter->ptp_clock_info.max_adj = 600000000 - 1;
break;
default:
break;
}
#ifdef CONFIG_E1000E_HWTS
/* CPU must have ART and GBe must be from Sunrise Point or greater */
if (hw->mac.type >= e1000_pch_spt && boot_cpu_has(X86_FEATURE_ART))
adapter->ptp_clock_info.getcrosststamp =
e1000e_phc_getcrosststamp;
#endif/*CONFIG_E1000E_HWTS*/
INIT_DELAYED_WORK(&adapter->systim_overflow_work,
e1000e_systim_overflow_work);
schedule_delayed_work(&adapter->systim_overflow_work,
E1000_SYSTIM_OVERFLOW_PERIOD);
adapter->ptp_clock = ptp_clock_register(&adapter->ptp_clock_info,
&adapter->pdev->dev);
if (IS_ERR(adapter->ptp_clock)) {
adapter->ptp_clock = NULL;
e_err("ptp_clock_register failed\n");
} else if (adapter->ptp_clock) {
e_info("registered PHC clock\n");
}
}
/**
* e1000e_ptp_remove - disable PTP device and stop the overflow check
* @adapter: board private structure
*
* Stop the PTP support, and cancel the delayed work.
**/
void e1000e_ptp_remove(struct e1000_adapter *adapter)
{
if (!(adapter->flags & FLAG_HAS_HW_TIMESTAMP))
return;
cancel_delayed_work_sync(&adapter->systim_overflow_work);
if (adapter->ptp_clock) {
ptp_clock_unregister(adapter->ptp_clock);
adapter->ptp_clock = NULL;
e_info("removed PHC\n");
}
}

View File

@ -0,0 +1,346 @@
// SPDX-License-Identifier: GPL-2.0
/* Copyright(c) 1999 - 2018 Intel Corporation. */
/* PTP 1588 Hardware Clock (PHC)
* Derived from PTP Hardware Clock driver for Intel 82576 and 82580 (igb)
* Copyright (C) 2011 Richard Cochran <richardcochran@gmail.com>
*/
#include "e1000.h"
#ifdef CONFIG_E1000E_HWTS
#include <linux/clocksource.h>
#include <linux/ktime.h>
#include <asm/tsc.h>
#endif
/**
* e1000e_phc_adjfine - adjust the frequency of the hardware clock
* @ptp: ptp clock structure
* @delta: Desired frequency chance in scaled parts per million
*
* Adjust the frequency of the PHC cycle counter by the indicated delta from
* the base frequency.
*
* Scaled parts per million is ppm but with a 16 bit binary fractional field.
**/
static int e1000e_phc_adjfine(struct ptp_clock_info *ptp, long delta)
{
struct e1000_adapter *adapter = container_of(ptp, struct e1000_adapter,
ptp_clock_info);
struct e1000_hw *hw = &adapter->hw;
unsigned long flags;
u64 incvalue;
u32 timinca;
s32 ret_val;
/* Get the System Time Register SYSTIM base frequency */
ret_val = e1000e_get_base_timinca(adapter, &timinca);
if (ret_val)
return ret_val;
spin_lock_irqsave(&adapter->systim_lock, flags);
incvalue = timinca & E1000_TIMINCA_INCVALUE_MASK;
incvalue = adjust_by_scaled_ppm(incvalue, delta);
timinca &= ~E1000_TIMINCA_INCVALUE_MASK;
timinca |= incvalue;
ew32(TIMINCA, timinca);
adapter->ptp_delta = delta;
spin_unlock_irqrestore(&adapter->systim_lock, flags);
return 0;
}
/**
* e1000e_phc_adjtime - Shift the time of the hardware clock
* @ptp: ptp clock structure
* @delta: Desired change in nanoseconds
*
* Adjust the timer by resetting the timecounter structure.
**/
static int e1000e_phc_adjtime(struct ptp_clock_info *ptp, s64 delta)
{
struct e1000_adapter *adapter = container_of(ptp, struct e1000_adapter,
ptp_clock_info);
unsigned long flags;
spin_lock_irqsave(&adapter->systim_lock, flags);
timecounter_adjtime(&adapter->tc, delta);
spin_unlock_irqrestore(&adapter->systim_lock, flags);
return 0;
}
#ifdef CONFIG_E1000E_HWTS
#define MAX_HW_WAIT_COUNT (3)
/**
* e1000e_phc_get_syncdevicetime - Callback given to timekeeping code reads system/device registers
* @device: current device time
* @system: system counter value read synchronously with device time
* @ctx: context provided by timekeeping code
*
* Read device and system (ART) clock simultaneously and return the corrected
* clock values in ns.
**/
static int e1000e_phc_get_syncdevicetime(ktime_t *device,
struct system_counterval_t *system,
void *ctx)
{
struct e1000_adapter *adapter = (struct e1000_adapter *)ctx;
struct e1000_hw *hw = &adapter->hw;
unsigned long flags;
int i;
u32 tsync_ctrl;
u64 dev_cycles;
u64 sys_cycles;
tsync_ctrl = er32(TSYNCTXCTL);
tsync_ctrl |= E1000_TSYNCTXCTL_START_SYNC |
E1000_TSYNCTXCTL_MAX_ALLOWED_DLY_MASK;
ew32(TSYNCTXCTL, tsync_ctrl);
for (i = 0; i < MAX_HW_WAIT_COUNT; ++i) {
udelay(1);
tsync_ctrl = er32(TSYNCTXCTL);
if (tsync_ctrl & E1000_TSYNCTXCTL_SYNC_COMP)
break;
}
if (i == MAX_HW_WAIT_COUNT)
return -ETIMEDOUT;
dev_cycles = er32(SYSSTMPH);
dev_cycles <<= 32;
dev_cycles |= er32(SYSSTMPL);
spin_lock_irqsave(&adapter->systim_lock, flags);
*device = ns_to_ktime(timecounter_cyc2time(&adapter->tc, dev_cycles));
spin_unlock_irqrestore(&adapter->systim_lock, flags);
sys_cycles = er32(PLTSTMPH);
sys_cycles <<= 32;
sys_cycles |= er32(PLTSTMPL);
*system = convert_art_to_tsc(sys_cycles);
return 0;
}
/**
* e1000e_phc_getcrosststamp - Reads the current system/device cross timestamp
* @ptp: ptp clock structure
* @xtstamp: structure containing timestamp
*
* Read device and system (ART) clock simultaneously and return the scaled
* clock values in ns.
**/
static int e1000e_phc_getcrosststamp(struct ptp_clock_info *ptp,
struct system_device_crosststamp *xtstamp)
{
struct e1000_adapter *adapter = container_of(ptp, struct e1000_adapter,
ptp_clock_info);
return get_device_system_crosststamp(e1000e_phc_get_syncdevicetime,
adapter, NULL, xtstamp);
}
#endif/*CONFIG_E1000E_HWTS*/
/**
* e1000e_phc_gettimex - Reads the current time from the hardware clock and
* system clock
* @ptp: ptp clock structure
* @ts: timespec structure to hold the current PHC time
* @sts: structure to hold the current system time
*
* Read the timecounter and return the correct value in ns after converting
* it into a struct timespec.
**/
static int e1000e_phc_gettimex(struct ptp_clock_info *ptp,
struct timespec64 *ts,
struct ptp_system_timestamp *sts)
{
struct e1000_adapter *adapter = container_of(ptp, struct e1000_adapter,
ptp_clock_info);
unsigned long flags;
u64 cycles, ns;
spin_lock_irqsave(&adapter->systim_lock, flags);
/* NOTE: Non-monotonic SYSTIM readings may be returned */
cycles = e1000e_read_systim(adapter, sts);
ns = timecounter_cyc2time(&adapter->tc, cycles);
spin_unlock_irqrestore(&adapter->systim_lock, flags);
*ts = ns_to_timespec64(ns);
return 0;
}
/**
* e1000e_phc_settime - Set the current time on the hardware clock
* @ptp: ptp clock structure
* @ts: timespec containing the new time for the cycle counter
*
* Reset the timecounter to use a new base value instead of the kernel
* wall timer value.
**/
static int e1000e_phc_settime(struct ptp_clock_info *ptp,
const struct timespec64 *ts)
{
struct e1000_adapter *adapter = container_of(ptp, struct e1000_adapter,
ptp_clock_info);
unsigned long flags;
u64 ns;
ns = timespec64_to_ns(ts);
/* reset the timecounter */
spin_lock_irqsave(&adapter->systim_lock, flags);
timecounter_init(&adapter->tc, &adapter->cc, ns);
spin_unlock_irqrestore(&adapter->systim_lock, flags);
return 0;
}
/**
* e1000e_phc_enable - enable or disable an ancillary feature
* @ptp: ptp clock structure
* @request: Desired resource to enable or disable
* @on: Caller passes one to enable or zero to disable
*
* Enable (or disable) ancillary features of the PHC subsystem.
* Currently, no ancillary features are supported.
**/
static int e1000e_phc_enable(struct ptp_clock_info __always_unused *ptp,
struct ptp_clock_request __always_unused *request,
int __always_unused on)
{
return -EOPNOTSUPP;
}
static void e1000e_systim_overflow_work(struct work_struct *work)
{
struct e1000_adapter *adapter = container_of(work, struct e1000_adapter,
systim_overflow_work.work);
struct e1000_hw *hw = &adapter->hw;
struct timespec64 ts;
u64 ns;
/* Update the timecounter */
ns = timecounter_read(&adapter->tc);
ts = ns_to_timespec64(ns);
e_dbg("SYSTIM overflow check at %lld.%09lu\n",
(long long) ts.tv_sec, ts.tv_nsec);
schedule_delayed_work(&adapter->systim_overflow_work,
E1000_SYSTIM_OVERFLOW_PERIOD);
}
static const struct ptp_clock_info e1000e_ptp_clock_info = {
.owner = THIS_MODULE,
.n_alarm = 0,
.n_ext_ts = 0,
.n_per_out = 0,
.n_pins = 0,
.pps = 0,
.adjfine = e1000e_phc_adjfine,
.adjtime = e1000e_phc_adjtime,
.gettimex64 = e1000e_phc_gettimex,
.settime64 = e1000e_phc_settime,
.enable = e1000e_phc_enable,
};
/**
* e1000e_ptp_init - initialize PTP for devices which support it
* @adapter: board private structure
*
* This function performs the required steps for enabling PTP support.
* If PTP support has already been loaded it simply calls the cyclecounter
* init routine and exits.
**/
void e1000e_ptp_init(struct e1000_adapter *adapter)
{
struct e1000_hw *hw = &adapter->hw;
adapter->ptp_clock = NULL;
if (!(adapter->flags & FLAG_HAS_HW_TIMESTAMP))
return;
adapter->ptp_clock_info = e1000e_ptp_clock_info;
snprintf(adapter->ptp_clock_info.name,
sizeof(adapter->ptp_clock_info.name), "%pm",
adapter->netdev->perm_addr);
switch (hw->mac.type) {
case e1000_pch2lan:
case e1000_pch_lpt:
case e1000_pch_spt:
case e1000_pch_cnp:
case e1000_pch_tgp:
case e1000_pch_adp:
case e1000_pch_mtp:
case e1000_pch_lnp:
case e1000_pch_ptp:
if ((hw->mac.type < e1000_pch_lpt) ||
(er32(TSYNCRXCTL) & E1000_TSYNCRXCTL_SYSCFI)) {
adapter->ptp_clock_info.max_adj = 24000000 - 1;
break;
}
fallthrough;
case e1000_82574:
case e1000_82583:
adapter->ptp_clock_info.max_adj = 600000000 - 1;
break;
default:
break;
}
#ifdef CONFIG_E1000E_HWTS
/* CPU must have ART and GBe must be from Sunrise Point or greater */
if (hw->mac.type >= e1000_pch_spt && boot_cpu_has(X86_FEATURE_ART))
adapter->ptp_clock_info.getcrosststamp =
e1000e_phc_getcrosststamp;
#endif/*CONFIG_E1000E_HWTS*/
INIT_DELAYED_WORK(&adapter->systim_overflow_work,
e1000e_systim_overflow_work);
schedule_delayed_work(&adapter->systim_overflow_work,
E1000_SYSTIM_OVERFLOW_PERIOD);
adapter->ptp_clock = ptp_clock_register(&adapter->ptp_clock_info,
&adapter->pdev->dev);
if (IS_ERR(adapter->ptp_clock)) {
adapter->ptp_clock = NULL;
e_err("ptp_clock_register failed\n");
} else if (adapter->ptp_clock) {
e_info("registered PHC clock\n");
}
}
/**
* e1000e_ptp_remove - disable PTP device and stop the overflow check
* @adapter: board private structure
*
* Stop the PTP support, and cancel the delayed work.
**/
void e1000e_ptp_remove(struct e1000_adapter *adapter)
{
if (!(adapter->flags & FLAG_HAS_HW_TIMESTAMP))
return;
cancel_delayed_work_sync(&adapter->systim_overflow_work);
if (adapter->ptp_clock) {
ptp_clock_unregister(adapter->ptp_clock);
adapter->ptp_clock = NULL;
e_info("removed PHC\n");
}
}

View File

@ -0,0 +1,245 @@
/* SPDX-License-Identifier: GPL-2.0 */
/* Copyright(c) 1999 - 2018 Intel Corporation. */
#ifndef _E1000E_REGS_H_
#define _E1000E_REGS_H_
#define E1000_CTRL 0x00000 /* Device Control - RW */
#define E1000_STATUS 0x00008 /* Device Status - RO */
#define E1000_EECD 0x00010 /* EEPROM/Flash Control - RW */
#define E1000_EERD 0x00014 /* EEPROM Read - RW */
#define E1000_CTRL_EXT 0x00018 /* Extended Device Control - RW */
#define E1000_FLA 0x0001C /* Flash Access - RW */
#define E1000_MDIC 0x00020 /* MDI Control - RW */
#define E1000_SCTL 0x00024 /* SerDes Control - RW */
#define E1000_FCAL 0x00028 /* Flow Control Address Low - RW */
#define E1000_FCAH 0x0002C /* Flow Control Address High -RW */
#define E1000_FEXT 0x0002C /* Future Extended - RW */
#define E1000_FEXTNVM 0x00028 /* Future Extended NVM - RW */
#define E1000_FEXTNVM3 0x0003C /* Future Extended NVM 3 - RW */
#define E1000_FEXTNVM4 0x00024 /* Future Extended NVM 4 - RW */
#define E1000_FEXTNVM5 0x00014 /* Future Extended NVM 5 - RW */
#define E1000_FEXTNVM6 0x00010 /* Future Extended NVM 6 - RW */
#define E1000_FEXTNVM7 0x000E4 /* Future Extended NVM 7 - RW */
#define E1000_FEXTNVM8 0x5BB0 /* Future Extended NVM 8 - RW */
#define E1000_FEXTNVM9 0x5BB4 /* Future Extended NVM 9 - RW */
#define E1000_FEXTNVM11 0x5BBC /* Future Extended NVM 11 - RW */
#define E1000_FEXTNVM12 0x5BC0 /* Future Extended NVM 12 - RW */
#define E1000_PCIEANACFG 0x00F18 /* PCIE Analog Config */
#define E1000_DPGFR 0x00FAC /* Dynamic Power Gate Force Control Register */
#define E1000_FCT 0x00030 /* Flow Control Type - RW */
#define E1000_VET 0x00038 /* VLAN Ether Type - RW */
#define E1000_ICR 0x000C0 /* Interrupt Cause Read - R/clr */
#define E1000_ITR 0x000C4 /* Interrupt Throttling Rate - RW */
#define E1000_ICS 0x000C8 /* Interrupt Cause Set - WO */
#define E1000_IMS 0x000D0 /* Interrupt Mask Set - RW */
#define E1000_IMC 0x000D8 /* Interrupt Mask Clear - WO */
#define E1000_IAM 0x000E0 /* Interrupt Acknowledge Auto Mask */
#define E1000_IVAR 0x000E4 /* Interrupt Vector Allocation Register - RW */
#define E1000_SVCR 0x000F0
#define E1000_SVT 0x000F4
#define E1000_LPIC 0x000FC /* Low Power IDLE control */
#define E1000_RCTL 0x00100 /* Rx Control - RW */
#define E1000_FCTTV 0x00170 /* Flow Control Transmit Timer Value - RW */
#define E1000_TXCW 0x00178 /* Tx Configuration Word - RW */
#define E1000_RXCW 0x00180 /* Rx Configuration Word - RO */
#define E1000_PBA_ECC 0x01100 /* PBA ECC Register */
#define E1000_TCTL 0x00400 /* Tx Control - RW */
#define E1000_TCTL_EXT 0x00404 /* Extended Tx Control - RW */
#define E1000_TIPG 0x00410 /* Tx Inter-packet gap -RW */
#define E1000_AIT 0x00458 /* Adaptive Interframe Spacing Throttle - RW */
#define E1000_LEDCTL 0x00E00 /* LED Control - RW */
#define E1000_EXTCNF_CTRL 0x00F00 /* Extended Configuration Control */
#define E1000_EXTCNF_SIZE 0x00F08 /* Extended Configuration Size */
#define E1000_PHY_CTRL 0x00F10 /* PHY Control Register in CSR */
#define E1000_POEMB E1000_PHY_CTRL /* PHY OEM Bits */
#define E1000_PBA 0x01000 /* Packet Buffer Allocation - RW */
#define E1000_PBS 0x01008 /* Packet Buffer Size */
#define E1000_PBECCSTS 0x0100C /* Packet Buffer ECC Status - RW */
#define E1000_IOSFPC 0x00F28 /* TX corrupted data */
#define E1000_EEMNGCTL 0x01010 /* MNG EEprom Control */
#define E1000_EEWR 0x0102C /* EEPROM Write Register - RW */
#define E1000_FLOP 0x0103C /* FLASH Opcode Register */
#define E1000_ERT 0x02008 /* Early Rx Threshold - RW */
#define E1000_FCRTL 0x02160 /* Flow Control Receive Threshold Low - RW */
#define E1000_FCRTH 0x02168 /* Flow Control Receive Threshold High - RW */
#define E1000_PSRCTL 0x02170 /* Packet Split Receive Control - RW */
#define E1000_RDFH 0x02410 /* Rx Data FIFO Head - RW */
#define E1000_RDFT 0x02418 /* Rx Data FIFO Tail - RW */
#define E1000_RDFHS 0x02420 /* Rx Data FIFO Head Saved - RW */
#define E1000_RDFTS 0x02428 /* Rx Data FIFO Tail Saved - RW */
#define E1000_RDFPC 0x02430 /* Rx Data FIFO Packet Count - RW */
/* Split and Replication Rx Control - RW */
#define E1000_RDTR 0x02820 /* Rx Delay Timer - RW */
#define E1000_RADV 0x0282C /* Rx Interrupt Absolute Delay Timer - RW */
/* Convenience macros
*
* Note: "_n" is the queue number of the register to be written to.
*
* Example usage:
* E1000_RDBAL_REG(current_rx_queue)
*/
#define E1000_RDBAL(_n) ((_n) < 4 ? (0x02800 + ((_n) * 0x100)) : \
(0x0C000 + ((_n) * 0x40)))
#define E1000_RDBAH(_n) ((_n) < 4 ? (0x02804 + ((_n) * 0x100)) : \
(0x0C004 + ((_n) * 0x40)))
#define E1000_RDLEN(_n) ((_n) < 4 ? (0x02808 + ((_n) * 0x100)) : \
(0x0C008 + ((_n) * 0x40)))
#define E1000_RDH(_n) ((_n) < 4 ? (0x02810 + ((_n) * 0x100)) : \
(0x0C010 + ((_n) * 0x40)))
#define E1000_RDT(_n) ((_n) < 4 ? (0x02818 + ((_n) * 0x100)) : \
(0x0C018 + ((_n) * 0x40)))
#define E1000_RXDCTL(_n) ((_n) < 4 ? (0x02828 + ((_n) * 0x100)) : \
(0x0C028 + ((_n) * 0x40)))
#define E1000_TDBAL(_n) ((_n) < 4 ? (0x03800 + ((_n) * 0x100)) : \
(0x0E000 + ((_n) * 0x40)))
#define E1000_TDBAH(_n) ((_n) < 4 ? (0x03804 + ((_n) * 0x100)) : \
(0x0E004 + ((_n) * 0x40)))
#define E1000_TDLEN(_n) ((_n) < 4 ? (0x03808 + ((_n) * 0x100)) : \
(0x0E008 + ((_n) * 0x40)))
#define E1000_TDH(_n) ((_n) < 4 ? (0x03810 + ((_n) * 0x100)) : \
(0x0E010 + ((_n) * 0x40)))
#define E1000_TDT(_n) ((_n) < 4 ? (0x03818 + ((_n) * 0x100)) : \
(0x0E018 + ((_n) * 0x40)))
#define E1000_TXDCTL(_n) ((_n) < 4 ? (0x03828 + ((_n) * 0x100)) : \
(0x0E028 + ((_n) * 0x40)))
#define E1000_TARC(_n) (0x03840 + ((_n) * 0x100))
#define E1000_KABGTXD 0x03004 /* AFE Band Gap Transmit Ref Data */
#define E1000_RAL(_i) (((_i) <= 15) ? (0x05400 + ((_i) * 8)) : \
(0x054E0 + ((_i - 16) * 8)))
#define E1000_RAH(_i) (((_i) <= 15) ? (0x05404 + ((_i) * 8)) : \
(0x054E4 + ((_i - 16) * 8)))
#define E1000_SHRAL(_i) (0x05438 + ((_i) * 8))
#define E1000_SHRAH(_i) (0x0543C + ((_i) * 8))
#define E1000_TDFH 0x03410 /* Tx Data FIFO Head - RW */
#define E1000_TDFT 0x03418 /* Tx Data FIFO Tail - RW */
#define E1000_TDFHS 0x03420 /* Tx Data FIFO Head Saved - RW */
#define E1000_TDFTS 0x03428 /* Tx Data FIFO Tail Saved - RW */
#define E1000_TDFPC 0x03430 /* Tx Data FIFO Packet Count - RW */
#define E1000_TIDV 0x03820 /* Tx Interrupt Delay Value - RW */
#define E1000_TADV 0x0382C /* Tx Interrupt Absolute Delay Val - RW */
#define E1000_CRCERRS 0x04000 /* CRC Error Count - R/clr */
#define E1000_ALGNERRC 0x04004 /* Alignment Error Count - R/clr */
#define E1000_SYMERRS 0x04008 /* Symbol Error Count - R/clr */
#define E1000_RXERRC 0x0400C /* Receive Error Count - R/clr */
#define E1000_MPC 0x04010 /* Missed Packet Count - R/clr */
#define E1000_SCC 0x04014 /* Single Collision Count - R/clr */
#define E1000_ECOL 0x04018 /* Excessive Collision Count - R/clr */
#define E1000_MCC 0x0401C /* Multiple Collision Count - R/clr */
#define E1000_LATECOL 0x04020 /* Late Collision Count - R/clr */
#define E1000_COLC 0x04028 /* Collision Count - R/clr */
#define E1000_DC 0x04030 /* Defer Count - R/clr */
#define E1000_TNCRS 0x04034 /* Tx-No CRS - R/clr */
#define E1000_SEC 0x04038 /* Sequence Error Count - R/clr */
#define E1000_CEXTERR 0x0403C /* Carrier Extension Error Count - R/clr */
#define E1000_RLEC 0x04040 /* Receive Length Error Count - R/clr */
#define E1000_XONRXC 0x04048 /* XON Rx Count - R/clr */
#define E1000_XONTXC 0x0404C /* XON Tx Count - R/clr */
#define E1000_XOFFRXC 0x04050 /* XOFF Rx Count - R/clr */
#define E1000_XOFFTXC 0x04054 /* XOFF Tx Count - R/clr */
#define E1000_FCRUC 0x04058 /* Flow Control Rx Unsupported Count- R/clr */
#define E1000_PRC64 0x0405C /* Packets Rx (64 bytes) - R/clr */
#define E1000_PRC127 0x04060 /* Packets Rx (65-127 bytes) - R/clr */
#define E1000_PRC255 0x04064 /* Packets Rx (128-255 bytes) - R/clr */
#define E1000_PRC511 0x04068 /* Packets Rx (255-511 bytes) - R/clr */
#define E1000_PRC1023 0x0406C /* Packets Rx (512-1023 bytes) - R/clr */
#define E1000_PRC1522 0x04070 /* Packets Rx (1024-1522 bytes) - R/clr */
#define E1000_GPRC 0x04074 /* Good Packets Rx Count - R/clr */
#define E1000_BPRC 0x04078 /* Broadcast Packets Rx Count - R/clr */
#define E1000_MPRC 0x0407C /* Multicast Packets Rx Count - R/clr */
#define E1000_GPTC 0x04080 /* Good Packets Tx Count - R/clr */
#define E1000_GORCL 0x04088 /* Good Octets Rx Count Low - R/clr */
#define E1000_GORCH 0x0408C /* Good Octets Rx Count High - R/clr */
#define E1000_GOTCL 0x04090 /* Good Octets Tx Count Low - R/clr */
#define E1000_GOTCH 0x04094 /* Good Octets Tx Count High - R/clr */
#define E1000_RNBC 0x040A0 /* Rx No Buffers Count - R/clr */
#define E1000_RUC 0x040A4 /* Rx Undersize Count - R/clr */
#define E1000_RFC 0x040A8 /* Rx Fragment Count - R/clr */
#define E1000_ROC 0x040AC /* Rx Oversize Count - R/clr */
#define E1000_RJC 0x040B0 /* Rx Jabber Count - R/clr */
#define E1000_MGTPRC 0x040B4 /* Management Packets Rx Count - R/clr */
#define E1000_MGTPDC 0x040B8 /* Management Packets Dropped Count - R/clr */
#define E1000_MGTPTC 0x040BC /* Management Packets Tx Count - R/clr */
#define E1000_TORL 0x040C0 /* Total Octets Rx Low - R/clr */
#define E1000_TORH 0x040C4 /* Total Octets Rx High - R/clr */
#define E1000_TOTL 0x040C8 /* Total Octets Tx Low - R/clr */
#define E1000_TOTH 0x040CC /* Total Octets Tx High - R/clr */
#define E1000_TPR 0x040D0 /* Total Packets Rx - R/clr */
#define E1000_TPT 0x040D4 /* Total Packets Tx - R/clr */
#define E1000_PTC64 0x040D8 /* Packets Tx (64 bytes) - R/clr */
#define E1000_PTC127 0x040DC /* Packets Tx (65-127 bytes) - R/clr */
#define E1000_PTC255 0x040E0 /* Packets Tx (128-255 bytes) - R/clr */
#define E1000_PTC511 0x040E4 /* Packets Tx (256-511 bytes) - R/clr */
#define E1000_PTC1023 0x040E8 /* Packets Tx (512-1023 bytes) - R/clr */
#define E1000_PTC1522 0x040EC /* Packets Tx (1024-1522 Bytes) - R/clr */
#define E1000_MPTC 0x040F0 /* Multicast Packets Tx Count - R/clr */
#define E1000_BPTC 0x040F4 /* Broadcast Packets Tx Count - R/clr */
#define E1000_TSCTC 0x040F8 /* TCP Segmentation Context Tx - R/clr */
#define E1000_TSCTFC 0x040FC /* TCP Segmentation Context Tx Fail - R/clr */
#define E1000_IAC 0x04100 /* Interrupt Assertion Count */
#define E1000_ICRXPTC 0x04104 /* Interrupt Cause Rx Pkt Timer Expire Count */
#define E1000_ICRXATC 0x04108 /* Interrupt Cause Rx Abs Timer Expire Count */
#define E1000_ICTXPTC 0x0410C /* Interrupt Cause Tx Pkt Timer Expire Count */
#define E1000_ICTXATC 0x04110 /* Interrupt Cause Tx Abs Timer Expire Count */
#define E1000_ICTXQEC 0x04118 /* Interrupt Cause Tx Queue Empty Count */
#define E1000_ICTXQMTC 0x0411C /* Interrupt Cause Tx Queue Min Thresh Count */
#define E1000_ICRXDMTC 0x04120 /* Interrupt Cause Rx Desc Min Thresh Count */
#define E1000_ICRXOC 0x04124 /* Interrupt Cause Receiver Overrun Count */
#define E1000_CRC_OFFSET 0x05F50 /* CRC Offset register */
#define E1000_PCS_LCTL 0x04208 /* PCS Link Control - RW */
#define E1000_PCS_LSTAT 0x0420C /* PCS Link Status - RO */
#define E1000_PCS_ANADV 0x04218 /* AN advertisement - RW */
#define E1000_PCS_LPAB 0x0421C /* Link Partner Ability - RW */
#define E1000_RXCSUM 0x05000 /* Rx Checksum Control - RW */
#define E1000_RFCTL 0x05008 /* Receive Filter Control */
#define E1000_MTA 0x05200 /* Multicast Table Array - RW Array */
#define E1000_RA 0x05400 /* Receive Address - RW Array */
#define E1000_VFTA 0x05600 /* VLAN Filter Table Array - RW Array */
#define E1000_WUC 0x05800 /* Wakeup Control - RW */
#define E1000_WUFC 0x05808 /* Wakeup Filter Control - RW */
#define E1000_WUS 0x05810 /* Wakeup Status - RO */
#define E1000_MANC 0x05820 /* Management Control - RW */
#define E1000_FFLT 0x05F00 /* Flexible Filter Length Table - RW Array */
#define E1000_HOST_IF 0x08800 /* Host Interface */
#define E1000_KMRNCTRLSTA 0x00034 /* MAC-PHY interface - RW */
#define E1000_MANC2H 0x05860 /* Management Control To Host - RW */
/* Management Decision Filters */
#define E1000_MDEF(_n) (0x05890 + (4 * (_n)))
#define E1000_SW_FW_SYNC 0x05B5C /* SW-FW Synchronization - RW */
#define E1000_GCR 0x05B00 /* PCI-Ex Control */
#define E1000_GCR2 0x05B64 /* PCI-Ex Control #2 */
#define E1000_FACTPS 0x05B30 /* Function Active and Power State to MNG */
#define E1000_SWSM 0x05B50 /* SW Semaphore */
#define E1000_FWSM 0x05B54 /* FW Semaphore */
#define E1000_EXFWSM 0x05B58 /* Extended FW Semaphore */
/* Driver-only SW semaphore (not used by BOOT agents) */
#define E1000_SWSM2 0x05B58
#define E1000_FFLT_DBG 0x05F04 /* Debug Register */
#define E1000_HICR 0x08F00 /* Host Interface Control */
/* RSS registers */
#define E1000_MRQC 0x05818 /* Multiple Receive Control - RW */
#define E1000_RETA(_i) (0x05C00 + ((_i) * 4)) /* Redirection Table - RW */
#define E1000_RSSRK(_i) (0x05C80 + ((_i) * 4)) /* RSS Random Key - RW */
#define E1000_TSYNCRXCTL 0x0B620 /* Rx Time Sync Control register - RW */
#define E1000_TSYNCTXCTL 0x0B614 /* Tx Time Sync Control register - RW */
#define E1000_RXSTMPL 0x0B624 /* Rx timestamp Low - RO */
#define E1000_RXSTMPH 0x0B628 /* Rx timestamp High - RO */
#define E1000_TXSTMPL 0x0B618 /* Tx timestamp value Low - RO */
#define E1000_TXSTMPH 0x0B61C /* Tx timestamp value High - RO */
#define E1000_SYSTIML 0x0B600 /* System time register Low - RO */
#define E1000_SYSTIMH 0x0B604 /* System time register High - RO */
#define E1000_TIMINCA 0x0B608 /* Increment attributes register - RW */
#define E1000_SYSSTMPL 0x0B648 /* HH Timesync system stamp low register */
#define E1000_SYSSTMPH 0x0B64C /* HH Timesync system stamp hi register */
#define E1000_PLTSTMPL 0x0B640 /* HH Timesync platform stamp low register */
#define E1000_PLTSTMPH 0x0B644 /* HH Timesync platform stamp hi register */
#define E1000_RXMTRL 0x0B634 /* Time sync Rx EtherType and Msg Type - RW */
#define E1000_RXUDP 0x0B638 /* Time Sync Rx UDP Port - RW */
/* PHY registers */
#define I82579_DFT_CTRL PHY_REG(769, 20)
#endif

View File

@ -0,0 +1,245 @@
/* SPDX-License-Identifier: GPL-2.0 */
/* Copyright(c) 1999 - 2018 Intel Corporation. */
#ifndef _E1000E_REGS_H_
#define _E1000E_REGS_H_
#define E1000_CTRL 0x00000 /* Device Control - RW */
#define E1000_STATUS 0x00008 /* Device Status - RO */
#define E1000_EECD 0x00010 /* EEPROM/Flash Control - RW */
#define E1000_EERD 0x00014 /* EEPROM Read - RW */
#define E1000_CTRL_EXT 0x00018 /* Extended Device Control - RW */
#define E1000_FLA 0x0001C /* Flash Access - RW */
#define E1000_MDIC 0x00020 /* MDI Control - RW */
#define E1000_SCTL 0x00024 /* SerDes Control - RW */
#define E1000_FCAL 0x00028 /* Flow Control Address Low - RW */
#define E1000_FCAH 0x0002C /* Flow Control Address High -RW */
#define E1000_FEXT 0x0002C /* Future Extended - RW */
#define E1000_FEXTNVM 0x00028 /* Future Extended NVM - RW */
#define E1000_FEXTNVM3 0x0003C /* Future Extended NVM 3 - RW */
#define E1000_FEXTNVM4 0x00024 /* Future Extended NVM 4 - RW */
#define E1000_FEXTNVM5 0x00014 /* Future Extended NVM 5 - RW */
#define E1000_FEXTNVM6 0x00010 /* Future Extended NVM 6 - RW */
#define E1000_FEXTNVM7 0x000E4 /* Future Extended NVM 7 - RW */
#define E1000_FEXTNVM8 0x5BB0 /* Future Extended NVM 8 - RW */
#define E1000_FEXTNVM9 0x5BB4 /* Future Extended NVM 9 - RW */
#define E1000_FEXTNVM11 0x5BBC /* Future Extended NVM 11 - RW */
#define E1000_FEXTNVM12 0x5BC0 /* Future Extended NVM 12 - RW */
#define E1000_PCIEANACFG 0x00F18 /* PCIE Analog Config */
#define E1000_DPGFR 0x00FAC /* Dynamic Power Gate Force Control Register */
#define E1000_FCT 0x00030 /* Flow Control Type - RW */
#define E1000_VET 0x00038 /* VLAN Ether Type - RW */
#define E1000_ICR 0x000C0 /* Interrupt Cause Read - R/clr */
#define E1000_ITR 0x000C4 /* Interrupt Throttling Rate - RW */
#define E1000_ICS 0x000C8 /* Interrupt Cause Set - WO */
#define E1000_IMS 0x000D0 /* Interrupt Mask Set - RW */
#define E1000_IMC 0x000D8 /* Interrupt Mask Clear - WO */
#define E1000_IAM 0x000E0 /* Interrupt Acknowledge Auto Mask */
#define E1000_IVAR 0x000E4 /* Interrupt Vector Allocation Register - RW */
#define E1000_SVCR 0x000F0
#define E1000_SVT 0x000F4
#define E1000_LPIC 0x000FC /* Low Power IDLE control */
#define E1000_RCTL 0x00100 /* Rx Control - RW */
#define E1000_FCTTV 0x00170 /* Flow Control Transmit Timer Value - RW */
#define E1000_TXCW 0x00178 /* Tx Configuration Word - RW */
#define E1000_RXCW 0x00180 /* Rx Configuration Word - RO */
#define E1000_PBA_ECC 0x01100 /* PBA ECC Register */
#define E1000_TCTL 0x00400 /* Tx Control - RW */
#define E1000_TCTL_EXT 0x00404 /* Extended Tx Control - RW */
#define E1000_TIPG 0x00410 /* Tx Inter-packet gap -RW */
#define E1000_AIT 0x00458 /* Adaptive Interframe Spacing Throttle - RW */
#define E1000_LEDCTL 0x00E00 /* LED Control - RW */
#define E1000_EXTCNF_CTRL 0x00F00 /* Extended Configuration Control */
#define E1000_EXTCNF_SIZE 0x00F08 /* Extended Configuration Size */
#define E1000_PHY_CTRL 0x00F10 /* PHY Control Register in CSR */
#define E1000_POEMB E1000_PHY_CTRL /* PHY OEM Bits */
#define E1000_PBA 0x01000 /* Packet Buffer Allocation - RW */
#define E1000_PBS 0x01008 /* Packet Buffer Size */
#define E1000_PBECCSTS 0x0100C /* Packet Buffer ECC Status - RW */
#define E1000_IOSFPC 0x00F28 /* TX corrupted data */
#define E1000_EEMNGCTL 0x01010 /* MNG EEprom Control */
#define E1000_EEWR 0x0102C /* EEPROM Write Register - RW */
#define E1000_FLOP 0x0103C /* FLASH Opcode Register */
#define E1000_ERT 0x02008 /* Early Rx Threshold - RW */
#define E1000_FCRTL 0x02160 /* Flow Control Receive Threshold Low - RW */
#define E1000_FCRTH 0x02168 /* Flow Control Receive Threshold High - RW */
#define E1000_PSRCTL 0x02170 /* Packet Split Receive Control - RW */
#define E1000_RDFH 0x02410 /* Rx Data FIFO Head - RW */
#define E1000_RDFT 0x02418 /* Rx Data FIFO Tail - RW */
#define E1000_RDFHS 0x02420 /* Rx Data FIFO Head Saved - RW */
#define E1000_RDFTS 0x02428 /* Rx Data FIFO Tail Saved - RW */
#define E1000_RDFPC 0x02430 /* Rx Data FIFO Packet Count - RW */
/* Split and Replication Rx Control - RW */
#define E1000_RDTR 0x02820 /* Rx Delay Timer - RW */
#define E1000_RADV 0x0282C /* Rx Interrupt Absolute Delay Timer - RW */
/* Convenience macros
*
* Note: "_n" is the queue number of the register to be written to.
*
* Example usage:
* E1000_RDBAL_REG(current_rx_queue)
*/
#define E1000_RDBAL(_n) ((_n) < 4 ? (0x02800 + ((_n) * 0x100)) : \
(0x0C000 + ((_n) * 0x40)))
#define E1000_RDBAH(_n) ((_n) < 4 ? (0x02804 + ((_n) * 0x100)) : \
(0x0C004 + ((_n) * 0x40)))
#define E1000_RDLEN(_n) ((_n) < 4 ? (0x02808 + ((_n) * 0x100)) : \
(0x0C008 + ((_n) * 0x40)))
#define E1000_RDH(_n) ((_n) < 4 ? (0x02810 + ((_n) * 0x100)) : \
(0x0C010 + ((_n) * 0x40)))
#define E1000_RDT(_n) ((_n) < 4 ? (0x02818 + ((_n) * 0x100)) : \
(0x0C018 + ((_n) * 0x40)))
#define E1000_RXDCTL(_n) ((_n) < 4 ? (0x02828 + ((_n) * 0x100)) : \
(0x0C028 + ((_n) * 0x40)))
#define E1000_TDBAL(_n) ((_n) < 4 ? (0x03800 + ((_n) * 0x100)) : \
(0x0E000 + ((_n) * 0x40)))
#define E1000_TDBAH(_n) ((_n) < 4 ? (0x03804 + ((_n) * 0x100)) : \
(0x0E004 + ((_n) * 0x40)))
#define E1000_TDLEN(_n) ((_n) < 4 ? (0x03808 + ((_n) * 0x100)) : \
(0x0E008 + ((_n) * 0x40)))
#define E1000_TDH(_n) ((_n) < 4 ? (0x03810 + ((_n) * 0x100)) : \
(0x0E010 + ((_n) * 0x40)))
#define E1000_TDT(_n) ((_n) < 4 ? (0x03818 + ((_n) * 0x100)) : \
(0x0E018 + ((_n) * 0x40)))
#define E1000_TXDCTL(_n) ((_n) < 4 ? (0x03828 + ((_n) * 0x100)) : \
(0x0E028 + ((_n) * 0x40)))
#define E1000_TARC(_n) (0x03840 + ((_n) * 0x100))
#define E1000_KABGTXD 0x03004 /* AFE Band Gap Transmit Ref Data */
#define E1000_RAL(_i) (((_i) <= 15) ? (0x05400 + ((_i) * 8)) : \
(0x054E0 + ((_i - 16) * 8)))
#define E1000_RAH(_i) (((_i) <= 15) ? (0x05404 + ((_i) * 8)) : \
(0x054E4 + ((_i - 16) * 8)))
#define E1000_SHRAL(_i) (0x05438 + ((_i) * 8))
#define E1000_SHRAH(_i) (0x0543C + ((_i) * 8))
#define E1000_TDFH 0x03410 /* Tx Data FIFO Head - RW */
#define E1000_TDFT 0x03418 /* Tx Data FIFO Tail - RW */
#define E1000_TDFHS 0x03420 /* Tx Data FIFO Head Saved - RW */
#define E1000_TDFTS 0x03428 /* Tx Data FIFO Tail Saved - RW */
#define E1000_TDFPC 0x03430 /* Tx Data FIFO Packet Count - RW */
#define E1000_TIDV 0x03820 /* Tx Interrupt Delay Value - RW */
#define E1000_TADV 0x0382C /* Tx Interrupt Absolute Delay Val - RW */
#define E1000_CRCERRS 0x04000 /* CRC Error Count - R/clr */
#define E1000_ALGNERRC 0x04004 /* Alignment Error Count - R/clr */
#define E1000_SYMERRS 0x04008 /* Symbol Error Count - R/clr */
#define E1000_RXERRC 0x0400C /* Receive Error Count - R/clr */
#define E1000_MPC 0x04010 /* Missed Packet Count - R/clr */
#define E1000_SCC 0x04014 /* Single Collision Count - R/clr */
#define E1000_ECOL 0x04018 /* Excessive Collision Count - R/clr */
#define E1000_MCC 0x0401C /* Multiple Collision Count - R/clr */
#define E1000_LATECOL 0x04020 /* Late Collision Count - R/clr */
#define E1000_COLC 0x04028 /* Collision Count - R/clr */
#define E1000_DC 0x04030 /* Defer Count - R/clr */
#define E1000_TNCRS 0x04034 /* Tx-No CRS - R/clr */
#define E1000_SEC 0x04038 /* Sequence Error Count - R/clr */
#define E1000_CEXTERR 0x0403C /* Carrier Extension Error Count - R/clr */
#define E1000_RLEC 0x04040 /* Receive Length Error Count - R/clr */
#define E1000_XONRXC 0x04048 /* XON Rx Count - R/clr */
#define E1000_XONTXC 0x0404C /* XON Tx Count - R/clr */
#define E1000_XOFFRXC 0x04050 /* XOFF Rx Count - R/clr */
#define E1000_XOFFTXC 0x04054 /* XOFF Tx Count - R/clr */
#define E1000_FCRUC 0x04058 /* Flow Control Rx Unsupported Count- R/clr */
#define E1000_PRC64 0x0405C /* Packets Rx (64 bytes) - R/clr */
#define E1000_PRC127 0x04060 /* Packets Rx (65-127 bytes) - R/clr */
#define E1000_PRC255 0x04064 /* Packets Rx (128-255 bytes) - R/clr */
#define E1000_PRC511 0x04068 /* Packets Rx (255-511 bytes) - R/clr */
#define E1000_PRC1023 0x0406C /* Packets Rx (512-1023 bytes) - R/clr */
#define E1000_PRC1522 0x04070 /* Packets Rx (1024-1522 bytes) - R/clr */
#define E1000_GPRC 0x04074 /* Good Packets Rx Count - R/clr */
#define E1000_BPRC 0x04078 /* Broadcast Packets Rx Count - R/clr */
#define E1000_MPRC 0x0407C /* Multicast Packets Rx Count - R/clr */
#define E1000_GPTC 0x04080 /* Good Packets Tx Count - R/clr */
#define E1000_GORCL 0x04088 /* Good Octets Rx Count Low - R/clr */
#define E1000_GORCH 0x0408C /* Good Octets Rx Count High - R/clr */
#define E1000_GOTCL 0x04090 /* Good Octets Tx Count Low - R/clr */
#define E1000_GOTCH 0x04094 /* Good Octets Tx Count High - R/clr */
#define E1000_RNBC 0x040A0 /* Rx No Buffers Count - R/clr */
#define E1000_RUC 0x040A4 /* Rx Undersize Count - R/clr */
#define E1000_RFC 0x040A8 /* Rx Fragment Count - R/clr */
#define E1000_ROC 0x040AC /* Rx Oversize Count - R/clr */
#define E1000_RJC 0x040B0 /* Rx Jabber Count - R/clr */
#define E1000_MGTPRC 0x040B4 /* Management Packets Rx Count - R/clr */
#define E1000_MGTPDC 0x040B8 /* Management Packets Dropped Count - R/clr */
#define E1000_MGTPTC 0x040BC /* Management Packets Tx Count - R/clr */
#define E1000_TORL 0x040C0 /* Total Octets Rx Low - R/clr */
#define E1000_TORH 0x040C4 /* Total Octets Rx High - R/clr */
#define E1000_TOTL 0x040C8 /* Total Octets Tx Low - R/clr */
#define E1000_TOTH 0x040CC /* Total Octets Tx High - R/clr */
#define E1000_TPR 0x040D0 /* Total Packets Rx - R/clr */
#define E1000_TPT 0x040D4 /* Total Packets Tx - R/clr */
#define E1000_PTC64 0x040D8 /* Packets Tx (64 bytes) - R/clr */
#define E1000_PTC127 0x040DC /* Packets Tx (65-127 bytes) - R/clr */
#define E1000_PTC255 0x040E0 /* Packets Tx (128-255 bytes) - R/clr */
#define E1000_PTC511 0x040E4 /* Packets Tx (256-511 bytes) - R/clr */
#define E1000_PTC1023 0x040E8 /* Packets Tx (512-1023 bytes) - R/clr */
#define E1000_PTC1522 0x040EC /* Packets Tx (1024-1522 Bytes) - R/clr */
#define E1000_MPTC 0x040F0 /* Multicast Packets Tx Count - R/clr */
#define E1000_BPTC 0x040F4 /* Broadcast Packets Tx Count - R/clr */
#define E1000_TSCTC 0x040F8 /* TCP Segmentation Context Tx - R/clr */
#define E1000_TSCTFC 0x040FC /* TCP Segmentation Context Tx Fail - R/clr */
#define E1000_IAC 0x04100 /* Interrupt Assertion Count */
#define E1000_ICRXPTC 0x04104 /* Interrupt Cause Rx Pkt Timer Expire Count */
#define E1000_ICRXATC 0x04108 /* Interrupt Cause Rx Abs Timer Expire Count */
#define E1000_ICTXPTC 0x0410C /* Interrupt Cause Tx Pkt Timer Expire Count */
#define E1000_ICTXATC 0x04110 /* Interrupt Cause Tx Abs Timer Expire Count */
#define E1000_ICTXQEC 0x04118 /* Interrupt Cause Tx Queue Empty Count */
#define E1000_ICTXQMTC 0x0411C /* Interrupt Cause Tx Queue Min Thresh Count */
#define E1000_ICRXDMTC 0x04120 /* Interrupt Cause Rx Desc Min Thresh Count */
#define E1000_ICRXOC 0x04124 /* Interrupt Cause Receiver Overrun Count */
#define E1000_CRC_OFFSET 0x05F50 /* CRC Offset register */
#define E1000_PCS_LCTL 0x04208 /* PCS Link Control - RW */
#define E1000_PCS_LSTAT 0x0420C /* PCS Link Status - RO */
#define E1000_PCS_ANADV 0x04218 /* AN advertisement - RW */
#define E1000_PCS_LPAB 0x0421C /* Link Partner Ability - RW */
#define E1000_RXCSUM 0x05000 /* Rx Checksum Control - RW */
#define E1000_RFCTL 0x05008 /* Receive Filter Control */
#define E1000_MTA 0x05200 /* Multicast Table Array - RW Array */
#define E1000_RA 0x05400 /* Receive Address - RW Array */
#define E1000_VFTA 0x05600 /* VLAN Filter Table Array - RW Array */
#define E1000_WUC 0x05800 /* Wakeup Control - RW */
#define E1000_WUFC 0x05808 /* Wakeup Filter Control - RW */
#define E1000_WUS 0x05810 /* Wakeup Status - RO */
#define E1000_MANC 0x05820 /* Management Control - RW */
#define E1000_FFLT 0x05F00 /* Flexible Filter Length Table - RW Array */
#define E1000_HOST_IF 0x08800 /* Host Interface */
#define E1000_KMRNCTRLSTA 0x00034 /* MAC-PHY interface - RW */
#define E1000_MANC2H 0x05860 /* Management Control To Host - RW */
/* Management Decision Filters */
#define E1000_MDEF(_n) (0x05890 + (4 * (_n)))
#define E1000_SW_FW_SYNC 0x05B5C /* SW-FW Synchronization - RW */
#define E1000_GCR 0x05B00 /* PCI-Ex Control */
#define E1000_GCR2 0x05B64 /* PCI-Ex Control #2 */
#define E1000_FACTPS 0x05B30 /* Function Active and Power State to MNG */
#define E1000_SWSM 0x05B50 /* SW Semaphore */
#define E1000_FWSM 0x05B54 /* FW Semaphore */
#define E1000_EXFWSM 0x05B58 /* Extended FW Semaphore */
/* Driver-only SW semaphore (not used by BOOT agents) */
#define E1000_SWSM2 0x05B58
#define E1000_FFLT_DBG 0x05F04 /* Debug Register */
#define E1000_HICR 0x08F00 /* Host Interface Control */
/* RSS registers */
#define E1000_MRQC 0x05818 /* Multiple Receive Control - RW */
#define E1000_RETA(_i) (0x05C00 + ((_i) * 4)) /* Redirection Table - RW */
#define E1000_RSSRK(_i) (0x05C80 + ((_i) * 4)) /* RSS Random Key - RW */
#define E1000_TSYNCRXCTL 0x0B620 /* Rx Time Sync Control register - RW */
#define E1000_TSYNCTXCTL 0x0B614 /* Tx Time Sync Control register - RW */
#define E1000_RXSTMPL 0x0B624 /* Rx timestamp Low - RO */
#define E1000_RXSTMPH 0x0B628 /* Rx timestamp High - RO */
#define E1000_TXSTMPL 0x0B618 /* Tx timestamp value Low - RO */
#define E1000_TXSTMPH 0x0B61C /* Tx timestamp value High - RO */
#define E1000_SYSTIML 0x0B600 /* System time register Low - RO */
#define E1000_SYSTIMH 0x0B604 /* System time register High - RO */
#define E1000_TIMINCA 0x0B608 /* Increment attributes register - RW */
#define E1000_SYSSTMPL 0x0B648 /* HH Timesync system stamp low register */
#define E1000_SYSSTMPH 0x0B64C /* HH Timesync system stamp hi register */
#define E1000_PLTSTMPL 0x0B640 /* HH Timesync platform stamp low register */
#define E1000_PLTSTMPH 0x0B644 /* HH Timesync platform stamp hi register */
#define E1000_RXMTRL 0x0B634 /* Time sync Rx EtherType and Msg Type - RW */
#define E1000_RXUDP 0x0B638 /* Time Sync Rx UDP Port - RW */
/* PHY registers */
#define I82579_DFT_CTRL PHY_REG(769, 20)
#endif

View File

@ -23,6 +23,7 @@ for f in $KERNELDIR/drivers/net/ethernet/intel/e1000e/*.[ch]; do
ep=${b/\./-$PREVER-ethercat.}
diff -u $op $ep | patch -p1 $e
sed -i s/$PREVER-ethercat.h/$KERNELVER-ethercat.h/ $e
sed -i s/trace-$PREVER-ethercat/trace-$KERNELVER-ethercat/ $e
git add $o $e
echo -e "\t$e \\\\\n\t$o \\\\" >> Makefile.am
done

View File

@ -50,6 +50,10 @@ EXTRA_DIST = \
e1000_82575-6.1-ethercat.h \
e1000_82575-6.1-orig.c \
e1000_82575-6.1-orig.h \
e1000_82575-6.4-ethercat.c \
e1000_82575-6.4-ethercat.h \
e1000_82575-6.4-orig.c \
e1000_82575-6.4-orig.h \
e1000_defines-3.18-ethercat.h \
e1000_defines-3.18-orig.h \
e1000_defines-4.19-ethercat.h \
@ -64,6 +68,8 @@ EXTRA_DIST = \
e1000_defines-5.15-orig.h \
e1000_defines-6.1-ethercat.h \
e1000_defines-6.1-orig.h \
e1000_defines-6.4-ethercat.h \
e1000_defines-6.4-orig.h \
e1000_hw-3.18-ethercat.h \
e1000_hw-3.18-orig.h \
e1000_hw-4.19-ethercat.h \
@ -78,6 +84,8 @@ EXTRA_DIST = \
e1000_hw-5.15-orig.h \
e1000_hw-6.1-ethercat.h \
e1000_hw-6.1-orig.h \
e1000_hw-6.4-ethercat.h \
e1000_hw-6.4-orig.h \
e1000_i210-3.18-ethercat.c \
e1000_i210-3.18-ethercat.h \
e1000_i210-3.18-orig.c \
@ -106,6 +114,10 @@ EXTRA_DIST = \
e1000_i210-6.1-ethercat.h \
e1000_i210-6.1-orig.c \
e1000_i210-6.1-orig.h \
e1000_i210-6.4-ethercat.c \
e1000_i210-6.4-ethercat.h \
e1000_i210-6.4-orig.c \
e1000_i210-6.4-orig.h \
e1000_mac-3.18-ethercat.c \
e1000_mac-3.18-ethercat.h \
e1000_mac-3.18-orig.c \
@ -134,6 +146,10 @@ EXTRA_DIST = \
e1000_mac-6.1-ethercat.h \
e1000_mac-6.1-orig.c \
e1000_mac-6.1-orig.h \
e1000_mac-6.4-ethercat.c \
e1000_mac-6.4-ethercat.h \
e1000_mac-6.4-orig.c \
e1000_mac-6.4-orig.h \
e1000_mbx-3.18-ethercat.c \
e1000_mbx-3.18-ethercat.h \
e1000_mbx-3.18-orig.c \
@ -162,6 +178,10 @@ EXTRA_DIST = \
e1000_mbx-6.1-ethercat.h \
e1000_mbx-6.1-orig.c \
e1000_mbx-6.1-orig.h \
e1000_mbx-6.4-ethercat.c \
e1000_mbx-6.4-ethercat.h \
e1000_mbx-6.4-orig.c \
e1000_mbx-6.4-orig.h \
e1000_nvm-3.18-ethercat.c \
e1000_nvm-3.18-ethercat.h \
e1000_nvm-3.18-orig.c \
@ -190,6 +210,10 @@ EXTRA_DIST = \
e1000_nvm-6.1-ethercat.h \
e1000_nvm-6.1-orig.c \
e1000_nvm-6.1-orig.h \
e1000_nvm-6.4-ethercat.c \
e1000_nvm-6.4-ethercat.h \
e1000_nvm-6.4-orig.c \
e1000_nvm-6.4-orig.h \
e1000_phy-3.18-ethercat.c \
e1000_phy-3.18-ethercat.h \
e1000_phy-3.18-orig.c \
@ -217,7 +241,11 @@ EXTRA_DIST = \
e1000_phy-6.1-ethercat.c \
e1000_phy-6.1-ethercat.h \
e1000_phy-6.1-orig.c \
e1000_phy-6.1-orig.h \
e1000_phy-6.1-orig.c \
e1000_phy-6.4-ethercat.c \
e1000_phy-6.4-ethercat.h \
e1000_phy-6.4-orig.h \
e1000_phy-6.4-orig.h \
e1000_regs-3.18-ethercat.h \
e1000_regs-3.18-orig.h \
e1000_regs-4.19-ethercat.h \
@ -232,6 +260,8 @@ EXTRA_DIST = \
e1000_regs-5.15-orig.h \
e1000_regs-6.1-ethercat.h \
e1000_regs-6.1-orig.h \
e1000_regs-6.4-ethercat.h \
e1000_regs-6.4-orig.h \
igb-3.18-ethercat.h \
igb-3.18-orig.h \
igb-4.19-ethercat.h \
@ -246,6 +276,8 @@ EXTRA_DIST = \
igb-5.15-orig.h \
igb-6.1-ethercat.h \
igb-6.1-orig.h \
igb-6.4-ethercat.h \
igb-6.4-orig.h \
igb_ethtool-3.18-ethercat.c \
igb_ethtool-3.18-orig.c \
igb_ethtool-4.19-ethercat.c \
@ -274,6 +306,8 @@ EXTRA_DIST = \
igb_hwmon-5.15-orig.c \
igb_hwmon-6.1-ethercat.c \
igb_hwmon-6.1-orig.c \
igb_hwmon-6.4-ethercat.c \
igb_hwmon-6.4-orig.c \
igb_main-3.18-ethercat.c \
igb_main-3.18-orig.c \
igb_main-4.19-ethercat.c \
@ -288,6 +322,8 @@ EXTRA_DIST = \
igb_main-5.15-orig.c \
igb_main-6.1-ethercat.c \
igb_main-6.1-orig.c \
igb_main-6.4-ethercat.c \
igb_main-6.4-orig.c \
igb_ptp-3.18-ethercat.c \
igb_ptp-3.18-orig.c \
igb_ptp-4.19-ethercat.c \
@ -302,6 +338,8 @@ EXTRA_DIST = \
igb_ptp-5.15-orig.c \
igb_ptp-6.1-ethercat.c \
igb_ptp-6.1-orig.c \
igb_ptp-6.4-ethercat.c \
igb_ptp-6.4-orig.c \
update.sh
#------------------------------------------------------------------------------

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,265 @@
/* SPDX-License-Identifier: GPL-2.0 */
/* Copyright(c) 2007 - 2018 Intel Corporation. */
#ifndef _E1000_82575_H_
#define _E1000_82575_H_
void igb_shutdown_serdes_link_82575(struct e1000_hw *hw);
void igb_power_up_serdes_link_82575(struct e1000_hw *hw);
void igb_power_down_phy_copper_82575(struct e1000_hw *hw);
void igb_rx_fifo_flush_82575(struct e1000_hw *hw);
s32 igb_read_i2c_byte(struct e1000_hw *hw, u8 byte_offset, u8 dev_addr,
u8 *data);
s32 igb_write_i2c_byte(struct e1000_hw *hw, u8 byte_offset, u8 dev_addr,
u8 data);
#define ID_LED_DEFAULT_82575_SERDES ((ID_LED_DEF1_DEF2 << 12) | \
(ID_LED_DEF1_DEF2 << 8) | \
(ID_LED_DEF1_DEF2 << 4) | \
(ID_LED_OFF1_ON2))
#define E1000_RAR_ENTRIES_82575 16
#define E1000_RAR_ENTRIES_82576 24
#define E1000_RAR_ENTRIES_82580 24
#define E1000_RAR_ENTRIES_I350 32
#define E1000_SW_SYNCH_MB 0x00000100
#define E1000_STAT_DEV_RST_SET 0x00100000
#define E1000_CTRL_DEV_RST 0x20000000
/* SRRCTL bit definitions */
#define E1000_SRRCTL_BSIZEPKT_SHIFT 10 /* Shift _right_ */
#define E1000_SRRCTL_BSIZEHDRSIZE_SHIFT 2 /* Shift _left_ */
#define E1000_SRRCTL_DESCTYPE_ADV_ONEBUF 0x02000000
#define E1000_SRRCTL_DESCTYPE_HDR_SPLIT_ALWAYS 0x0A000000
#define E1000_SRRCTL_DROP_EN 0x80000000
#define E1000_SRRCTL_TIMESTAMP 0x40000000
#define E1000_MRQC_ENABLE_RSS_MQ 0x00000002
#define E1000_MRQC_ENABLE_VMDQ 0x00000003
#define E1000_MRQC_RSS_FIELD_IPV4_UDP 0x00400000
#define E1000_MRQC_ENABLE_VMDQ_RSS_MQ 0x00000005
#define E1000_MRQC_RSS_FIELD_IPV6_UDP 0x00800000
#define E1000_MRQC_RSS_FIELD_IPV6_UDP_EX 0x01000000
#define E1000_EICR_TX_QUEUE ( \
E1000_EICR_TX_QUEUE0 | \
E1000_EICR_TX_QUEUE1 | \
E1000_EICR_TX_QUEUE2 | \
E1000_EICR_TX_QUEUE3)
#define E1000_EICR_RX_QUEUE ( \
E1000_EICR_RX_QUEUE0 | \
E1000_EICR_RX_QUEUE1 | \
E1000_EICR_RX_QUEUE2 | \
E1000_EICR_RX_QUEUE3)
/* Immediate Interrupt Rx (A.K.A. Low Latency Interrupt) */
#define E1000_IMIREXT_SIZE_BP 0x00001000 /* Packet size bypass */
#define E1000_IMIREXT_CTRL_BP 0x00080000 /* Bypass check of ctrl bits */
/* Receive Descriptor - Advanced */
union e1000_adv_rx_desc {
struct {
__le64 pkt_addr; /* Packet buffer address */
__le64 hdr_addr; /* Header buffer address */
} read;
struct {
struct {
struct {
__le16 pkt_info; /* RSS type, Packet type */
__le16 hdr_info; /* Split Head, buf len */
} lo_dword;
union {
__le32 rss; /* RSS Hash */
struct {
__le16 ip_id; /* IP id */
__le16 csum; /* Packet Checksum */
} csum_ip;
} hi_dword;
} lower;
struct {
__le32 status_error; /* ext status/error */
__le16 length; /* Packet length */
__le16 vlan; /* VLAN tag */
} upper;
} wb; /* writeback */
};
#define E1000_RXDADV_HDRBUFLEN_MASK 0x7FE0
#define E1000_RXDADV_HDRBUFLEN_SHIFT 5
#define E1000_RXDADV_STAT_TS 0x10000 /* Pkt was time stamped */
#define E1000_RXDADV_STAT_TSIP 0x08000 /* timestamp in packet */
/* Transmit Descriptor - Advanced */
union e1000_adv_tx_desc {
struct {
__le64 buffer_addr; /* Address of descriptor's data buf */
__le32 cmd_type_len;
__le32 olinfo_status;
} read;
struct {
__le64 rsvd; /* Reserved */
__le32 nxtseq_seed;
__le32 status;
} wb;
};
/* Adv Transmit Descriptor Config Masks */
#define E1000_ADVTXD_MAC_TSTAMP 0x00080000 /* IEEE1588 Timestamp packet */
#define E1000_ADVTXD_DTYP_CTXT 0x00200000 /* Advanced Context Descriptor */
#define E1000_ADVTXD_DTYP_DATA 0x00300000 /* Advanced Data Descriptor */
#define E1000_ADVTXD_DCMD_EOP 0x01000000 /* End of Packet */
#define E1000_ADVTXD_DCMD_IFCS 0x02000000 /* Insert FCS (Ethernet CRC) */
#define E1000_ADVTXD_DCMD_RS 0x08000000 /* Report Status */
#define E1000_ADVTXD_DCMD_DEXT 0x20000000 /* Descriptor extension (1=Adv) */
#define E1000_ADVTXD_DCMD_VLE 0x40000000 /* VLAN pkt enable */
#define E1000_ADVTXD_DCMD_TSE 0x80000000 /* TCP Seg enable */
#define E1000_ADVTXD_PAYLEN_SHIFT 14 /* Adv desc PAYLEN shift */
/* Context descriptors */
struct e1000_adv_tx_context_desc {
__le32 vlan_macip_lens;
__le32 seqnum_seed;
__le32 type_tucmd_mlhl;
__le32 mss_l4len_idx;
};
#define E1000_ADVTXD_MACLEN_SHIFT 9 /* Adv ctxt desc mac len shift */
#define E1000_ADVTXD_TUCMD_L4T_UDP 0x00000000 /* L4 Packet TYPE of UDP */
#define E1000_ADVTXD_TUCMD_IPV4 0x00000400 /* IP Packet Type: 1=IPv4 */
#define E1000_ADVTXD_TUCMD_L4T_TCP 0x00000800 /* L4 Packet TYPE of TCP */
#define E1000_ADVTXD_TUCMD_L4T_SCTP 0x00001000 /* L4 packet TYPE of SCTP */
/* IPSec Encrypt Enable for ESP */
#define E1000_ADVTXD_L4LEN_SHIFT 8 /* Adv ctxt L4LEN shift */
#define E1000_ADVTXD_MSS_SHIFT 16 /* Adv ctxt MSS shift */
/* Adv ctxt IPSec SA IDX mask */
/* Adv ctxt IPSec ESP len mask */
/* Additional Transmit Descriptor Control definitions */
#define E1000_TXDCTL_QUEUE_ENABLE 0x02000000 /* Enable specific Tx Queue */
/* Tx Queue Arbitration Priority 0=low, 1=high */
/* Additional Receive Descriptor Control definitions */
#define E1000_RXDCTL_QUEUE_ENABLE 0x02000000 /* Enable specific Rx Queue */
/* Direct Cache Access (DCA) definitions */
#define E1000_DCA_CTRL_DCA_MODE_DISABLE 0x01 /* DCA Disable */
#define E1000_DCA_CTRL_DCA_MODE_CB2 0x02 /* DCA Mode CB2 */
#define E1000_DCA_RXCTRL_CPUID_MASK 0x0000001F /* Rx CPUID Mask */
#define E1000_DCA_RXCTRL_DESC_DCA_EN BIT(5) /* DCA Rx Desc enable */
#define E1000_DCA_RXCTRL_HEAD_DCA_EN BIT(6) /* DCA Rx Desc header enable */
#define E1000_DCA_RXCTRL_DATA_DCA_EN BIT(7) /* DCA Rx Desc payload enable */
#define E1000_DCA_RXCTRL_DESC_RRO_EN BIT(9) /* DCA Rx rd Desc Relax Order */
#define E1000_DCA_TXCTRL_CPUID_MASK 0x0000001F /* Tx CPUID Mask */
#define E1000_DCA_TXCTRL_DESC_DCA_EN BIT(5) /* DCA Tx Desc enable */
#define E1000_DCA_TXCTRL_DESC_RRO_EN BIT(9) /* Tx rd Desc Relax Order */
#define E1000_DCA_TXCTRL_TX_WB_RO_EN BIT(11) /* Tx Desc writeback RO bit */
#define E1000_DCA_TXCTRL_DATA_RRO_EN BIT(13) /* Tx rd data Relax Order */
/* Additional DCA related definitions, note change in position of CPUID */
#define E1000_DCA_TXCTRL_CPUID_MASK_82576 0xFF000000 /* Tx CPUID Mask */
#define E1000_DCA_RXCTRL_CPUID_MASK_82576 0xFF000000 /* Rx CPUID Mask */
#define E1000_DCA_TXCTRL_CPUID_SHIFT 24 /* Tx CPUID now in the last byte */
#define E1000_DCA_RXCTRL_CPUID_SHIFT 24 /* Rx CPUID now in the last byte */
/* ETQF register bit definitions */
#define E1000_ETQF_FILTER_ENABLE BIT(26)
#define E1000_ETQF_1588 BIT(30)
#define E1000_ETQF_IMM_INT BIT(29)
#define E1000_ETQF_QUEUE_ENABLE BIT(31)
#define E1000_ETQF_QUEUE_SHIFT 16
#define E1000_ETQF_QUEUE_MASK 0x00070000
#define E1000_ETQF_ETYPE_MASK 0x0000FFFF
/* FTQF register bit definitions */
#define E1000_FTQF_VF_BP 0x00008000
#define E1000_FTQF_1588_TIME_STAMP 0x08000000
#define E1000_FTQF_MASK 0xF0000000
#define E1000_FTQF_MASK_PROTO_BP 0x10000000
#define E1000_FTQF_MASK_SOURCE_PORT_BP 0x80000000
#define E1000_NVM_APME_82575 0x0400
#define MAX_NUM_VFS 8
#define E1000_DTXSWC_MAC_SPOOF_MASK 0x000000FF /* Per VF MAC spoof control */
#define E1000_DTXSWC_VLAN_SPOOF_MASK 0x0000FF00 /* Per VF VLAN spoof control */
#define E1000_DTXSWC_LLE_MASK 0x00FF0000 /* Per VF Local LB enables */
#define E1000_DTXSWC_VLAN_SPOOF_SHIFT 8
#define E1000_DTXSWC_VMDQ_LOOPBACK_EN BIT(31) /* global VF LB enable */
/* Easy defines for setting default pool, would normally be left a zero */
#define E1000_VT_CTL_DEFAULT_POOL_SHIFT 7
#define E1000_VT_CTL_DEFAULT_POOL_MASK (0x7 << E1000_VT_CTL_DEFAULT_POOL_SHIFT)
/* Other useful VMD_CTL register defines */
#define E1000_VT_CTL_IGNORE_MAC BIT(28)
#define E1000_VT_CTL_DISABLE_DEF_POOL BIT(29)
#define E1000_VT_CTL_VM_REPL_EN BIT(30)
/* Per VM Offload register setup */
#define E1000_VMOLR_RLPML_MASK 0x00003FFF /* Long Packet Maximum Length mask */
#define E1000_VMOLR_LPE 0x00010000 /* Accept Long packet */
#define E1000_VMOLR_RSSE 0x00020000 /* Enable RSS */
#define E1000_VMOLR_AUPE 0x01000000 /* Accept untagged packets */
#define E1000_VMOLR_ROMPE 0x02000000 /* Accept overflow multicast */
#define E1000_VMOLR_ROPE 0x04000000 /* Accept overflow unicast */
#define E1000_VMOLR_BAM 0x08000000 /* Accept Broadcast packets */
#define E1000_VMOLR_MPME 0x10000000 /* Multicast promiscuous mode */
#define E1000_VMOLR_STRVLAN 0x40000000 /* Vlan stripping enable */
#define E1000_VMOLR_STRCRC 0x80000000 /* CRC stripping enable */
#define E1000_DVMOLR_HIDEVLAN 0x20000000 /* Hide vlan enable */
#define E1000_DVMOLR_STRVLAN 0x40000000 /* Vlan stripping enable */
#define E1000_DVMOLR_STRCRC 0x80000000 /* CRC stripping enable */
#define E1000_VLVF_ARRAY_SIZE 32
#define E1000_VLVF_VLANID_MASK 0x00000FFF
#define E1000_VLVF_POOLSEL_SHIFT 12
#define E1000_VLVF_POOLSEL_MASK (0xFF << E1000_VLVF_POOLSEL_SHIFT)
#define E1000_VLVF_LVLAN 0x00100000
#define E1000_VLVF_VLANID_ENABLE 0x80000000
#define E1000_VMVIR_VLANA_DEFAULT 0x40000000 /* Always use default VLAN */
#define E1000_VMVIR_VLANA_NEVER 0x80000000 /* Never insert VLAN tag */
#define E1000_IOVCTL 0x05BBC
#define E1000_IOVCTL_REUSE_VFQ 0x00000001
#define E1000_RPLOLR_STRVLAN 0x40000000
#define E1000_RPLOLR_STRCRC 0x80000000
#define E1000_DTXCTL_8023LL 0x0004
#define E1000_DTXCTL_VLAN_ADDED 0x0008
#define E1000_DTXCTL_OOS_ENABLE 0x0010
#define E1000_DTXCTL_MDP_EN 0x0020
#define E1000_DTXCTL_SPOOF_INT 0x0040
#define E1000_EEPROM_PCS_AUTONEG_DISABLE_BIT BIT(14)
#define ALL_QUEUES 0xFFFF
/* RX packet buffer size defines */
#define E1000_RXPBS_SIZE_MASK_82576 0x0000007F
void igb_vmdq_set_anti_spoofing_pf(struct e1000_hw *, bool, int);
void igb_vmdq_set_loopback_pf(struct e1000_hw *, bool);
void igb_vmdq_set_replication_pf(struct e1000_hw *, bool);
u16 igb_rxpbs_adjust_82580(u32 data);
s32 igb_read_emi_reg(struct e1000_hw *, u16 addr, u16 *data);
s32 igb_set_eee_i350(struct e1000_hw *, bool adv1G, bool adv100M);
s32 igb_set_eee_i354(struct e1000_hw *, bool adv1G, bool adv100M);
s32 igb_get_eee_status_i354(struct e1000_hw *hw, bool *status);
#define E1000_I2C_THERMAL_SENSOR_ADDR 0xF8
#define E1000_EMC_INTERNAL_DATA 0x00
#define E1000_EMC_INTERNAL_THERM_LIMIT 0x20
#define E1000_EMC_DIODE1_DATA 0x01
#define E1000_EMC_DIODE1_THERM_LIMIT 0x19
#define E1000_EMC_DIODE2_DATA 0x23
#define E1000_EMC_DIODE2_THERM_LIMIT 0x1A
#define E1000_EMC_DIODE3_DATA 0x2A
#define E1000_EMC_DIODE3_THERM_LIMIT 0x30
#endif

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,265 @@
/* SPDX-License-Identifier: GPL-2.0 */
/* Copyright(c) 2007 - 2018 Intel Corporation. */
#ifndef _E1000_82575_H_
#define _E1000_82575_H_
void igb_shutdown_serdes_link_82575(struct e1000_hw *hw);
void igb_power_up_serdes_link_82575(struct e1000_hw *hw);
void igb_power_down_phy_copper_82575(struct e1000_hw *hw);
void igb_rx_fifo_flush_82575(struct e1000_hw *hw);
s32 igb_read_i2c_byte(struct e1000_hw *hw, u8 byte_offset, u8 dev_addr,
u8 *data);
s32 igb_write_i2c_byte(struct e1000_hw *hw, u8 byte_offset, u8 dev_addr,
u8 data);
#define ID_LED_DEFAULT_82575_SERDES ((ID_LED_DEF1_DEF2 << 12) | \
(ID_LED_DEF1_DEF2 << 8) | \
(ID_LED_DEF1_DEF2 << 4) | \
(ID_LED_OFF1_ON2))
#define E1000_RAR_ENTRIES_82575 16
#define E1000_RAR_ENTRIES_82576 24
#define E1000_RAR_ENTRIES_82580 24
#define E1000_RAR_ENTRIES_I350 32
#define E1000_SW_SYNCH_MB 0x00000100
#define E1000_STAT_DEV_RST_SET 0x00100000
#define E1000_CTRL_DEV_RST 0x20000000
/* SRRCTL bit definitions */
#define E1000_SRRCTL_BSIZEPKT_SHIFT 10 /* Shift _right_ */
#define E1000_SRRCTL_BSIZEHDRSIZE_SHIFT 2 /* Shift _left_ */
#define E1000_SRRCTL_DESCTYPE_ADV_ONEBUF 0x02000000
#define E1000_SRRCTL_DESCTYPE_HDR_SPLIT_ALWAYS 0x0A000000
#define E1000_SRRCTL_DROP_EN 0x80000000
#define E1000_SRRCTL_TIMESTAMP 0x40000000
#define E1000_MRQC_ENABLE_RSS_MQ 0x00000002
#define E1000_MRQC_ENABLE_VMDQ 0x00000003
#define E1000_MRQC_RSS_FIELD_IPV4_UDP 0x00400000
#define E1000_MRQC_ENABLE_VMDQ_RSS_MQ 0x00000005
#define E1000_MRQC_RSS_FIELD_IPV6_UDP 0x00800000
#define E1000_MRQC_RSS_FIELD_IPV6_UDP_EX 0x01000000
#define E1000_EICR_TX_QUEUE ( \
E1000_EICR_TX_QUEUE0 | \
E1000_EICR_TX_QUEUE1 | \
E1000_EICR_TX_QUEUE2 | \
E1000_EICR_TX_QUEUE3)
#define E1000_EICR_RX_QUEUE ( \
E1000_EICR_RX_QUEUE0 | \
E1000_EICR_RX_QUEUE1 | \
E1000_EICR_RX_QUEUE2 | \
E1000_EICR_RX_QUEUE3)
/* Immediate Interrupt Rx (A.K.A. Low Latency Interrupt) */
#define E1000_IMIREXT_SIZE_BP 0x00001000 /* Packet size bypass */
#define E1000_IMIREXT_CTRL_BP 0x00080000 /* Bypass check of ctrl bits */
/* Receive Descriptor - Advanced */
union e1000_adv_rx_desc {
struct {
__le64 pkt_addr; /* Packet buffer address */
__le64 hdr_addr; /* Header buffer address */
} read;
struct {
struct {
struct {
__le16 pkt_info; /* RSS type, Packet type */
__le16 hdr_info; /* Split Head, buf len */
} lo_dword;
union {
__le32 rss; /* RSS Hash */
struct {
__le16 ip_id; /* IP id */
__le16 csum; /* Packet Checksum */
} csum_ip;
} hi_dword;
} lower;
struct {
__le32 status_error; /* ext status/error */
__le16 length; /* Packet length */
__le16 vlan; /* VLAN tag */
} upper;
} wb; /* writeback */
};
#define E1000_RXDADV_HDRBUFLEN_MASK 0x7FE0
#define E1000_RXDADV_HDRBUFLEN_SHIFT 5
#define E1000_RXDADV_STAT_TS 0x10000 /* Pkt was time stamped */
#define E1000_RXDADV_STAT_TSIP 0x08000 /* timestamp in packet */
/* Transmit Descriptor - Advanced */
union e1000_adv_tx_desc {
struct {
__le64 buffer_addr; /* Address of descriptor's data buf */
__le32 cmd_type_len;
__le32 olinfo_status;
} read;
struct {
__le64 rsvd; /* Reserved */
__le32 nxtseq_seed;
__le32 status;
} wb;
};
/* Adv Transmit Descriptor Config Masks */
#define E1000_ADVTXD_MAC_TSTAMP 0x00080000 /* IEEE1588 Timestamp packet */
#define E1000_ADVTXD_DTYP_CTXT 0x00200000 /* Advanced Context Descriptor */
#define E1000_ADVTXD_DTYP_DATA 0x00300000 /* Advanced Data Descriptor */
#define E1000_ADVTXD_DCMD_EOP 0x01000000 /* End of Packet */
#define E1000_ADVTXD_DCMD_IFCS 0x02000000 /* Insert FCS (Ethernet CRC) */
#define E1000_ADVTXD_DCMD_RS 0x08000000 /* Report Status */
#define E1000_ADVTXD_DCMD_DEXT 0x20000000 /* Descriptor extension (1=Adv) */
#define E1000_ADVTXD_DCMD_VLE 0x40000000 /* VLAN pkt enable */
#define E1000_ADVTXD_DCMD_TSE 0x80000000 /* TCP Seg enable */
#define E1000_ADVTXD_PAYLEN_SHIFT 14 /* Adv desc PAYLEN shift */
/* Context descriptors */
struct e1000_adv_tx_context_desc {
__le32 vlan_macip_lens;
__le32 seqnum_seed;
__le32 type_tucmd_mlhl;
__le32 mss_l4len_idx;
};
#define E1000_ADVTXD_MACLEN_SHIFT 9 /* Adv ctxt desc mac len shift */
#define E1000_ADVTXD_TUCMD_L4T_UDP 0x00000000 /* L4 Packet TYPE of UDP */
#define E1000_ADVTXD_TUCMD_IPV4 0x00000400 /* IP Packet Type: 1=IPv4 */
#define E1000_ADVTXD_TUCMD_L4T_TCP 0x00000800 /* L4 Packet TYPE of TCP */
#define E1000_ADVTXD_TUCMD_L4T_SCTP 0x00001000 /* L4 packet TYPE of SCTP */
/* IPSec Encrypt Enable for ESP */
#define E1000_ADVTXD_L4LEN_SHIFT 8 /* Adv ctxt L4LEN shift */
#define E1000_ADVTXD_MSS_SHIFT 16 /* Adv ctxt MSS shift */
/* Adv ctxt IPSec SA IDX mask */
/* Adv ctxt IPSec ESP len mask */
/* Additional Transmit Descriptor Control definitions */
#define E1000_TXDCTL_QUEUE_ENABLE 0x02000000 /* Enable specific Tx Queue */
/* Tx Queue Arbitration Priority 0=low, 1=high */
/* Additional Receive Descriptor Control definitions */
#define E1000_RXDCTL_QUEUE_ENABLE 0x02000000 /* Enable specific Rx Queue */
/* Direct Cache Access (DCA) definitions */
#define E1000_DCA_CTRL_DCA_MODE_DISABLE 0x01 /* DCA Disable */
#define E1000_DCA_CTRL_DCA_MODE_CB2 0x02 /* DCA Mode CB2 */
#define E1000_DCA_RXCTRL_CPUID_MASK 0x0000001F /* Rx CPUID Mask */
#define E1000_DCA_RXCTRL_DESC_DCA_EN BIT(5) /* DCA Rx Desc enable */
#define E1000_DCA_RXCTRL_HEAD_DCA_EN BIT(6) /* DCA Rx Desc header enable */
#define E1000_DCA_RXCTRL_DATA_DCA_EN BIT(7) /* DCA Rx Desc payload enable */
#define E1000_DCA_RXCTRL_DESC_RRO_EN BIT(9) /* DCA Rx rd Desc Relax Order */
#define E1000_DCA_TXCTRL_CPUID_MASK 0x0000001F /* Tx CPUID Mask */
#define E1000_DCA_TXCTRL_DESC_DCA_EN BIT(5) /* DCA Tx Desc enable */
#define E1000_DCA_TXCTRL_DESC_RRO_EN BIT(9) /* Tx rd Desc Relax Order */
#define E1000_DCA_TXCTRL_TX_WB_RO_EN BIT(11) /* Tx Desc writeback RO bit */
#define E1000_DCA_TXCTRL_DATA_RRO_EN BIT(13) /* Tx rd data Relax Order */
/* Additional DCA related definitions, note change in position of CPUID */
#define E1000_DCA_TXCTRL_CPUID_MASK_82576 0xFF000000 /* Tx CPUID Mask */
#define E1000_DCA_RXCTRL_CPUID_MASK_82576 0xFF000000 /* Rx CPUID Mask */
#define E1000_DCA_TXCTRL_CPUID_SHIFT 24 /* Tx CPUID now in the last byte */
#define E1000_DCA_RXCTRL_CPUID_SHIFT 24 /* Rx CPUID now in the last byte */
/* ETQF register bit definitions */
#define E1000_ETQF_FILTER_ENABLE BIT(26)
#define E1000_ETQF_1588 BIT(30)
#define E1000_ETQF_IMM_INT BIT(29)
#define E1000_ETQF_QUEUE_ENABLE BIT(31)
#define E1000_ETQF_QUEUE_SHIFT 16
#define E1000_ETQF_QUEUE_MASK 0x00070000
#define E1000_ETQF_ETYPE_MASK 0x0000FFFF
/* FTQF register bit definitions */
#define E1000_FTQF_VF_BP 0x00008000
#define E1000_FTQF_1588_TIME_STAMP 0x08000000
#define E1000_FTQF_MASK 0xF0000000
#define E1000_FTQF_MASK_PROTO_BP 0x10000000
#define E1000_FTQF_MASK_SOURCE_PORT_BP 0x80000000
#define E1000_NVM_APME_82575 0x0400
#define MAX_NUM_VFS 8
#define E1000_DTXSWC_MAC_SPOOF_MASK 0x000000FF /* Per VF MAC spoof control */
#define E1000_DTXSWC_VLAN_SPOOF_MASK 0x0000FF00 /* Per VF VLAN spoof control */
#define E1000_DTXSWC_LLE_MASK 0x00FF0000 /* Per VF Local LB enables */
#define E1000_DTXSWC_VLAN_SPOOF_SHIFT 8
#define E1000_DTXSWC_VMDQ_LOOPBACK_EN BIT(31) /* global VF LB enable */
/* Easy defines for setting default pool, would normally be left a zero */
#define E1000_VT_CTL_DEFAULT_POOL_SHIFT 7
#define E1000_VT_CTL_DEFAULT_POOL_MASK (0x7 << E1000_VT_CTL_DEFAULT_POOL_SHIFT)
/* Other useful VMD_CTL register defines */
#define E1000_VT_CTL_IGNORE_MAC BIT(28)
#define E1000_VT_CTL_DISABLE_DEF_POOL BIT(29)
#define E1000_VT_CTL_VM_REPL_EN BIT(30)
/* Per VM Offload register setup */
#define E1000_VMOLR_RLPML_MASK 0x00003FFF /* Long Packet Maximum Length mask */
#define E1000_VMOLR_LPE 0x00010000 /* Accept Long packet */
#define E1000_VMOLR_RSSE 0x00020000 /* Enable RSS */
#define E1000_VMOLR_AUPE 0x01000000 /* Accept untagged packets */
#define E1000_VMOLR_ROMPE 0x02000000 /* Accept overflow multicast */
#define E1000_VMOLR_ROPE 0x04000000 /* Accept overflow unicast */
#define E1000_VMOLR_BAM 0x08000000 /* Accept Broadcast packets */
#define E1000_VMOLR_MPME 0x10000000 /* Multicast promiscuous mode */
#define E1000_VMOLR_STRVLAN 0x40000000 /* Vlan stripping enable */
#define E1000_VMOLR_STRCRC 0x80000000 /* CRC stripping enable */
#define E1000_DVMOLR_HIDEVLAN 0x20000000 /* Hide vlan enable */
#define E1000_DVMOLR_STRVLAN 0x40000000 /* Vlan stripping enable */
#define E1000_DVMOLR_STRCRC 0x80000000 /* CRC stripping enable */
#define E1000_VLVF_ARRAY_SIZE 32
#define E1000_VLVF_VLANID_MASK 0x00000FFF
#define E1000_VLVF_POOLSEL_SHIFT 12
#define E1000_VLVF_POOLSEL_MASK (0xFF << E1000_VLVF_POOLSEL_SHIFT)
#define E1000_VLVF_LVLAN 0x00100000
#define E1000_VLVF_VLANID_ENABLE 0x80000000
#define E1000_VMVIR_VLANA_DEFAULT 0x40000000 /* Always use default VLAN */
#define E1000_VMVIR_VLANA_NEVER 0x80000000 /* Never insert VLAN tag */
#define E1000_IOVCTL 0x05BBC
#define E1000_IOVCTL_REUSE_VFQ 0x00000001
#define E1000_RPLOLR_STRVLAN 0x40000000
#define E1000_RPLOLR_STRCRC 0x80000000
#define E1000_DTXCTL_8023LL 0x0004
#define E1000_DTXCTL_VLAN_ADDED 0x0008
#define E1000_DTXCTL_OOS_ENABLE 0x0010
#define E1000_DTXCTL_MDP_EN 0x0020
#define E1000_DTXCTL_SPOOF_INT 0x0040
#define E1000_EEPROM_PCS_AUTONEG_DISABLE_BIT BIT(14)
#define ALL_QUEUES 0xFFFF
/* RX packet buffer size defines */
#define E1000_RXPBS_SIZE_MASK_82576 0x0000007F
void igb_vmdq_set_anti_spoofing_pf(struct e1000_hw *, bool, int);
void igb_vmdq_set_loopback_pf(struct e1000_hw *, bool);
void igb_vmdq_set_replication_pf(struct e1000_hw *, bool);
u16 igb_rxpbs_adjust_82580(u32 data);
s32 igb_read_emi_reg(struct e1000_hw *, u16 addr, u16 *data);
s32 igb_set_eee_i350(struct e1000_hw *, bool adv1G, bool adv100M);
s32 igb_set_eee_i354(struct e1000_hw *, bool adv1G, bool adv100M);
s32 igb_get_eee_status_i354(struct e1000_hw *hw, bool *status);
#define E1000_I2C_THERMAL_SENSOR_ADDR 0xF8
#define E1000_EMC_INTERNAL_DATA 0x00
#define E1000_EMC_INTERNAL_THERM_LIMIT 0x20
#define E1000_EMC_DIODE1_DATA 0x01
#define E1000_EMC_DIODE1_THERM_LIMIT 0x19
#define E1000_EMC_DIODE2_DATA 0x23
#define E1000_EMC_DIODE2_THERM_LIMIT 0x1A
#define E1000_EMC_DIODE3_DATA 0x2A
#define E1000_EMC_DIODE3_THERM_LIMIT 0x30
#endif

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,554 @@
/* SPDX-License-Identifier: GPL-2.0 */
/* Copyright(c) 2007 - 2018 Intel Corporation. */
#ifndef _E1000_IGB_HW_H_
#define _E1000_IGB_HW_H_
#include <linux/types.h>
#include <linux/delay.h>
#include <linux/io.h>
#include <linux/netdevice.h>
#include "e1000_regs-6.1-ethercat.h"
#include "e1000_defines-6.1-ethercat.h"
struct e1000_hw;
#define E1000_DEV_ID_82576 0x10C9
#define E1000_DEV_ID_82576_FIBER 0x10E6
#define E1000_DEV_ID_82576_SERDES 0x10E7
#define E1000_DEV_ID_82576_QUAD_COPPER 0x10E8
#define E1000_DEV_ID_82576_QUAD_COPPER_ET2 0x1526
#define E1000_DEV_ID_82576_NS 0x150A
#define E1000_DEV_ID_82576_NS_SERDES 0x1518
#define E1000_DEV_ID_82576_SERDES_QUAD 0x150D
#define E1000_DEV_ID_82575EB_COPPER 0x10A7
#define E1000_DEV_ID_82575EB_FIBER_SERDES 0x10A9
#define E1000_DEV_ID_82575GB_QUAD_COPPER 0x10D6
#define E1000_DEV_ID_82580_COPPER 0x150E
#define E1000_DEV_ID_82580_FIBER 0x150F
#define E1000_DEV_ID_82580_SERDES 0x1510
#define E1000_DEV_ID_82580_SGMII 0x1511
#define E1000_DEV_ID_82580_COPPER_DUAL 0x1516
#define E1000_DEV_ID_82580_QUAD_FIBER 0x1527
#define E1000_DEV_ID_DH89XXCC_SGMII 0x0438
#define E1000_DEV_ID_DH89XXCC_SERDES 0x043A
#define E1000_DEV_ID_DH89XXCC_BACKPLANE 0x043C
#define E1000_DEV_ID_DH89XXCC_SFP 0x0440
#define E1000_DEV_ID_I350_COPPER 0x1521
#define E1000_DEV_ID_I350_FIBER 0x1522
#define E1000_DEV_ID_I350_SERDES 0x1523
#define E1000_DEV_ID_I350_SGMII 0x1524
#define E1000_DEV_ID_I210_COPPER 0x1533
#define E1000_DEV_ID_I210_FIBER 0x1536
#define E1000_DEV_ID_I210_SERDES 0x1537
#define E1000_DEV_ID_I210_SGMII 0x1538
#define E1000_DEV_ID_I210_COPPER_FLASHLESS 0x157B
#define E1000_DEV_ID_I210_SERDES_FLASHLESS 0x157C
#define E1000_DEV_ID_I211_COPPER 0x1539
#define E1000_DEV_ID_I354_BACKPLANE_1GBPS 0x1F40
#define E1000_DEV_ID_I354_SGMII 0x1F41
#define E1000_DEV_ID_I354_BACKPLANE_2_5GBPS 0x1F45
#define E1000_REVISION_2 2
#define E1000_REVISION_4 4
#define E1000_FUNC_0 0
#define E1000_FUNC_1 1
#define E1000_FUNC_2 2
#define E1000_FUNC_3 3
#define E1000_ALT_MAC_ADDRESS_OFFSET_LAN0 0
#define E1000_ALT_MAC_ADDRESS_OFFSET_LAN1 3
#define E1000_ALT_MAC_ADDRESS_OFFSET_LAN2 6
#define E1000_ALT_MAC_ADDRESS_OFFSET_LAN3 9
enum e1000_mac_type {
e1000_undefined = 0,
e1000_82575,
e1000_82576,
e1000_82580,
e1000_i350,
e1000_i354,
e1000_i210,
e1000_i211,
e1000_num_macs /* List is 1-based, so subtract 1 for true count. */
};
enum e1000_media_type {
e1000_media_type_unknown = 0,
e1000_media_type_copper = 1,
e1000_media_type_fiber = 2,
e1000_media_type_internal_serdes = 3,
e1000_num_media_types
};
enum e1000_nvm_type {
e1000_nvm_unknown = 0,
e1000_nvm_none,
e1000_nvm_eeprom_spi,
e1000_nvm_flash_hw,
e1000_nvm_invm,
e1000_nvm_flash_sw
};
enum e1000_nvm_override {
e1000_nvm_override_none = 0,
e1000_nvm_override_spi_small,
e1000_nvm_override_spi_large,
};
enum e1000_phy_type {
e1000_phy_unknown = 0,
e1000_phy_none,
e1000_phy_m88,
e1000_phy_igp,
e1000_phy_igp_2,
e1000_phy_gg82563,
e1000_phy_igp_3,
e1000_phy_ife,
e1000_phy_82580,
e1000_phy_i210,
e1000_phy_bcm54616,
};
enum e1000_bus_type {
e1000_bus_type_unknown = 0,
e1000_bus_type_pci,
e1000_bus_type_pcix,
e1000_bus_type_pci_express,
e1000_bus_type_reserved
};
enum e1000_bus_speed {
e1000_bus_speed_unknown = 0,
e1000_bus_speed_33,
e1000_bus_speed_66,
e1000_bus_speed_100,
e1000_bus_speed_120,
e1000_bus_speed_133,
e1000_bus_speed_2500,
e1000_bus_speed_5000,
e1000_bus_speed_reserved
};
enum e1000_bus_width {
e1000_bus_width_unknown = 0,
e1000_bus_width_pcie_x1,
e1000_bus_width_pcie_x2,
e1000_bus_width_pcie_x4 = 4,
e1000_bus_width_pcie_x8 = 8,
e1000_bus_width_32,
e1000_bus_width_64,
e1000_bus_width_reserved
};
enum e1000_1000t_rx_status {
e1000_1000t_rx_status_not_ok = 0,
e1000_1000t_rx_status_ok,
e1000_1000t_rx_status_undefined = 0xFF
};
enum e1000_rev_polarity {
e1000_rev_polarity_normal = 0,
e1000_rev_polarity_reversed,
e1000_rev_polarity_undefined = 0xFF
};
enum e1000_fc_mode {
e1000_fc_none = 0,
e1000_fc_rx_pause,
e1000_fc_tx_pause,
e1000_fc_full,
e1000_fc_default = 0xFF
};
/* Statistics counters collected by the MAC */
struct e1000_hw_stats {
u64 crcerrs;
u64 algnerrc;
u64 symerrs;
u64 rxerrc;
u64 mpc;
u64 scc;
u64 ecol;
u64 mcc;
u64 latecol;
u64 colc;
u64 dc;
u64 tncrs;
u64 sec;
u64 cexterr;
u64 rlec;
u64 xonrxc;
u64 xontxc;
u64 xoffrxc;
u64 xofftxc;
u64 fcruc;
u64 prc64;
u64 prc127;
u64 prc255;
u64 prc511;
u64 prc1023;
u64 prc1522;
u64 gprc;
u64 bprc;
u64 mprc;
u64 gptc;
u64 gorc;
u64 gotc;
u64 rnbc;
u64 ruc;
u64 rfc;
u64 roc;
u64 rjc;
u64 mgprc;
u64 mgpdc;
u64 mgptc;
u64 tor;
u64 tot;
u64 tpr;
u64 tpt;
u64 ptc64;
u64 ptc127;
u64 ptc255;
u64 ptc511;
u64 ptc1023;
u64 ptc1522;
u64 mptc;
u64 bptc;
u64 tsctc;
u64 tsctfc;
u64 iac;
u64 icrxptc;
u64 icrxatc;
u64 ictxptc;
u64 ictxatc;
u64 ictxqec;
u64 ictxqmtc;
u64 icrxdmtc;
u64 icrxoc;
u64 cbtmpc;
u64 htdpmc;
u64 cbrdpc;
u64 cbrmpc;
u64 rpthc;
u64 hgptc;
u64 htcbdpc;
u64 hgorc;
u64 hgotc;
u64 lenerrs;
u64 scvpc;
u64 hrmpc;
u64 doosync;
u64 o2bgptc;
u64 o2bspc;
u64 b2ospc;
u64 b2ogprc;
};
struct e1000_host_mng_dhcp_cookie {
u32 signature;
u8 status;
u8 reserved0;
u16 vlan_id;
u32 reserved1;
u16 reserved2;
u8 reserved3;
u8 checksum;
};
/* Host Interface "Rev 1" */
struct e1000_host_command_header {
u8 command_id;
u8 command_length;
u8 command_options;
u8 checksum;
};
#define E1000_HI_MAX_DATA_LENGTH 252
struct e1000_host_command_info {
struct e1000_host_command_header command_header;
u8 command_data[E1000_HI_MAX_DATA_LENGTH];
};
/* Host Interface "Rev 2" */
struct e1000_host_mng_command_header {
u8 command_id;
u8 checksum;
u16 reserved1;
u16 reserved2;
u16 command_length;
};
#define E1000_HI_MAX_MNG_DATA_LENGTH 0x6F8
struct e1000_host_mng_command_info {
struct e1000_host_mng_command_header command_header;
u8 command_data[E1000_HI_MAX_MNG_DATA_LENGTH];
};
#include "e1000_mac-6.1-ethercat.h"
#include "e1000_phy-6.1-ethercat.h"
#include "e1000_nvm-6.1-ethercat.h"
#include "e1000_mbx-6.1-ethercat.h"
struct e1000_mac_operations {
s32 (*check_for_link)(struct e1000_hw *);
s32 (*reset_hw)(struct e1000_hw *);
s32 (*init_hw)(struct e1000_hw *);
bool (*check_mng_mode)(struct e1000_hw *);
s32 (*setup_physical_interface)(struct e1000_hw *);
void (*rar_set)(struct e1000_hw *, u8 *, u32);
s32 (*read_mac_addr)(struct e1000_hw *);
s32 (*get_speed_and_duplex)(struct e1000_hw *, u16 *, u16 *);
s32 (*acquire_swfw_sync)(struct e1000_hw *, u16);
void (*release_swfw_sync)(struct e1000_hw *, u16);
#ifdef CONFIG_IGB_HWMON
s32 (*get_thermal_sensor_data)(struct e1000_hw *);
s32 (*init_thermal_sensor_thresh)(struct e1000_hw *);
#endif
void (*write_vfta)(struct e1000_hw *, u32, u32);
};
struct e1000_phy_operations {
s32 (*acquire)(struct e1000_hw *);
s32 (*check_polarity)(struct e1000_hw *);
s32 (*check_reset_block)(struct e1000_hw *);
s32 (*force_speed_duplex)(struct e1000_hw *);
s32 (*get_cfg_done)(struct e1000_hw *hw);
s32 (*get_cable_length)(struct e1000_hw *);
s32 (*get_phy_info)(struct e1000_hw *);
s32 (*read_reg)(struct e1000_hw *, u32, u16 *);
void (*release)(struct e1000_hw *);
s32 (*reset)(struct e1000_hw *);
s32 (*set_d0_lplu_state)(struct e1000_hw *, bool);
s32 (*set_d3_lplu_state)(struct e1000_hw *, bool);
s32 (*write_reg)(struct e1000_hw *, u32, u16);
s32 (*read_i2c_byte)(struct e1000_hw *, u8, u8, u8 *);
s32 (*write_i2c_byte)(struct e1000_hw *, u8, u8, u8);
};
struct e1000_nvm_operations {
s32 (*acquire)(struct e1000_hw *);
s32 (*read)(struct e1000_hw *, u16, u16, u16 *);
void (*release)(struct e1000_hw *);
s32 (*write)(struct e1000_hw *, u16, u16, u16 *);
s32 (*update)(struct e1000_hw *);
s32 (*validate)(struct e1000_hw *);
s32 (*valid_led_default)(struct e1000_hw *, u16 *);
};
#define E1000_MAX_SENSORS 3
struct e1000_thermal_diode_data {
u8 location;
u8 temp;
u8 caution_thresh;
u8 max_op_thresh;
};
struct e1000_thermal_sensor_data {
struct e1000_thermal_diode_data sensor[E1000_MAX_SENSORS];
};
struct e1000_info {
s32 (*get_invariants)(struct e1000_hw *);
struct e1000_mac_operations *mac_ops;
const struct e1000_phy_operations *phy_ops;
struct e1000_nvm_operations *nvm_ops;
};
extern const struct e1000_info e1000_82575_info;
struct e1000_mac_info {
struct e1000_mac_operations ops;
u8 addr[6];
u8 perm_addr[6];
enum e1000_mac_type type;
u32 ledctl_default;
u32 ledctl_mode1;
u32 ledctl_mode2;
u32 mc_filter_type;
u32 txcw;
u16 mta_reg_count;
u16 uta_reg_count;
/* Maximum size of the MTA register table in all supported adapters */
#define MAX_MTA_REG 128
u32 mta_shadow[MAX_MTA_REG];
u16 rar_entry_count;
u8 forced_speed_duplex;
bool adaptive_ifs;
bool arc_subsystem_valid;
bool asf_firmware_present;
bool autoneg;
bool autoneg_failed;
bool disable_hw_init_bits;
bool get_link_status;
bool ifs_params_forced;
bool in_ifs_mode;
bool report_tx_early;
bool serdes_has_link;
bool tx_pkt_filtering;
struct e1000_thermal_sensor_data thermal_sensor_data;
};
struct e1000_phy_info {
struct e1000_phy_operations ops;
enum e1000_phy_type type;
enum e1000_1000t_rx_status local_rx;
enum e1000_1000t_rx_status remote_rx;
enum e1000_ms_type ms_type;
enum e1000_ms_type original_ms_type;
enum e1000_rev_polarity cable_polarity;
enum e1000_smart_speed smart_speed;
u32 addr;
u32 id;
u32 reset_delay_us; /* in usec */
u32 revision;
enum e1000_media_type media_type;
u16 autoneg_advertised;
u16 autoneg_mask;
u16 cable_length;
u16 max_cable_length;
u16 min_cable_length;
u16 pair_length[4];
u8 mdix;
bool disable_polarity_correction;
bool is_mdix;
bool polarity_correction;
bool reset_disable;
bool speed_downgraded;
bool autoneg_wait_to_complete;
};
struct e1000_nvm_info {
struct e1000_nvm_operations ops;
enum e1000_nvm_type type;
enum e1000_nvm_override override;
u32 flash_bank_size;
u32 flash_base_addr;
u16 word_size;
u16 delay_usec;
u16 address_bits;
u16 opcode_bits;
u16 page_size;
};
struct e1000_bus_info {
enum e1000_bus_type type;
enum e1000_bus_speed speed;
enum e1000_bus_width width;
u32 snoop;
u16 func;
u16 pci_cmd_word;
};
struct e1000_fc_info {
u32 high_water; /* Flow control high-water mark */
u32 low_water; /* Flow control low-water mark */
u16 pause_time; /* Flow control pause timer */
bool send_xon; /* Flow control send XON */
bool strict_ieee; /* Strict IEEE mode */
enum e1000_fc_mode current_mode; /* Type of flow control */
enum e1000_fc_mode requested_mode;
};
struct e1000_mbx_operations {
s32 (*init_params)(struct e1000_hw *hw);
s32 (*read)(struct e1000_hw *hw, u32 *msg, u16 size, u16 mbx_id,
bool unlock);
s32 (*write)(struct e1000_hw *hw, u32 *msg, u16 size, u16 mbx_id);
s32 (*read_posted)(struct e1000_hw *hw, u32 *msg, u16 size, u16 mbx_id);
s32 (*write_posted)(struct e1000_hw *hw, u32 *msg, u16 size,
u16 mbx_id);
s32 (*check_for_msg)(struct e1000_hw *hw, u16 mbx_id);
s32 (*check_for_ack)(struct e1000_hw *hw, u16 mbx_id);
s32 (*check_for_rst)(struct e1000_hw *hw, u16 mbx_id);
s32 (*unlock)(struct e1000_hw *hw, u16 mbx_id);
};
struct e1000_mbx_stats {
u32 msgs_tx;
u32 msgs_rx;
u32 acks;
u32 reqs;
u32 rsts;
};
struct e1000_mbx_info {
struct e1000_mbx_operations ops;
struct e1000_mbx_stats stats;
u32 timeout;
u32 usec_delay;
u16 size;
};
struct e1000_dev_spec_82575 {
bool sgmii_active;
bool global_device_reset;
bool eee_disable;
bool clear_semaphore_once;
struct e1000_sfp_flags eth_flags;
bool module_plugged;
u8 media_port;
bool media_changed;
bool mas_capable;
};
struct e1000_hw {
void *back;
u8 __iomem *hw_addr;
u8 __iomem *flash_address;
unsigned long io_base;
struct e1000_mac_info mac;
struct e1000_fc_info fc;
struct e1000_phy_info phy;
struct e1000_nvm_info nvm;
struct e1000_bus_info bus;
struct e1000_mbx_info mbx;
struct e1000_host_mng_dhcp_cookie mng_cookie;
union {
struct e1000_dev_spec_82575 _82575;
} dev_spec;
u16 device_id;
u16 subsystem_vendor_id;
u16 subsystem_device_id;
u16 vendor_id;
u8 revision_id;
};
struct net_device *igb_get_hw_dev(struct e1000_hw *hw);
#define hw_dbg(format, arg...) \
netdev_dbg(igb_get_hw_dev(hw), format, ##arg)
/* These functions must be implemented by drivers */
s32 igb_read_pcie_cap_reg(struct e1000_hw *hw, u32 reg, u16 *value);
s32 igb_write_pcie_cap_reg(struct e1000_hw *hw, u32 reg, u16 *value);
void igb_read_pci_cfg(struct e1000_hw *hw, u32 reg, u16 *value);
void igb_write_pci_cfg(struct e1000_hw *hw, u32 reg, u16 *value);
#endif /* _E1000_IGB_HW_H_ */

View File

@ -0,0 +1,554 @@
/* SPDX-License-Identifier: GPL-2.0 */
/* Copyright(c) 2007 - 2018 Intel Corporation. */
#ifndef _E1000_IGB_HW_H_
#define _E1000_IGB_HW_H_
#include <linux/types.h>
#include <linux/delay.h>
#include <linux/io.h>
#include <linux/netdevice.h>
#include "e1000_regs.h"
#include "e1000_defines.h"
struct e1000_hw;
#define E1000_DEV_ID_82576 0x10C9
#define E1000_DEV_ID_82576_FIBER 0x10E6
#define E1000_DEV_ID_82576_SERDES 0x10E7
#define E1000_DEV_ID_82576_QUAD_COPPER 0x10E8
#define E1000_DEV_ID_82576_QUAD_COPPER_ET2 0x1526
#define E1000_DEV_ID_82576_NS 0x150A
#define E1000_DEV_ID_82576_NS_SERDES 0x1518
#define E1000_DEV_ID_82576_SERDES_QUAD 0x150D
#define E1000_DEV_ID_82575EB_COPPER 0x10A7
#define E1000_DEV_ID_82575EB_FIBER_SERDES 0x10A9
#define E1000_DEV_ID_82575GB_QUAD_COPPER 0x10D6
#define E1000_DEV_ID_82580_COPPER 0x150E
#define E1000_DEV_ID_82580_FIBER 0x150F
#define E1000_DEV_ID_82580_SERDES 0x1510
#define E1000_DEV_ID_82580_SGMII 0x1511
#define E1000_DEV_ID_82580_COPPER_DUAL 0x1516
#define E1000_DEV_ID_82580_QUAD_FIBER 0x1527
#define E1000_DEV_ID_DH89XXCC_SGMII 0x0438
#define E1000_DEV_ID_DH89XXCC_SERDES 0x043A
#define E1000_DEV_ID_DH89XXCC_BACKPLANE 0x043C
#define E1000_DEV_ID_DH89XXCC_SFP 0x0440
#define E1000_DEV_ID_I350_COPPER 0x1521
#define E1000_DEV_ID_I350_FIBER 0x1522
#define E1000_DEV_ID_I350_SERDES 0x1523
#define E1000_DEV_ID_I350_SGMII 0x1524
#define E1000_DEV_ID_I210_COPPER 0x1533
#define E1000_DEV_ID_I210_FIBER 0x1536
#define E1000_DEV_ID_I210_SERDES 0x1537
#define E1000_DEV_ID_I210_SGMII 0x1538
#define E1000_DEV_ID_I210_COPPER_FLASHLESS 0x157B
#define E1000_DEV_ID_I210_SERDES_FLASHLESS 0x157C
#define E1000_DEV_ID_I211_COPPER 0x1539
#define E1000_DEV_ID_I354_BACKPLANE_1GBPS 0x1F40
#define E1000_DEV_ID_I354_SGMII 0x1F41
#define E1000_DEV_ID_I354_BACKPLANE_2_5GBPS 0x1F45
#define E1000_REVISION_2 2
#define E1000_REVISION_4 4
#define E1000_FUNC_0 0
#define E1000_FUNC_1 1
#define E1000_FUNC_2 2
#define E1000_FUNC_3 3
#define E1000_ALT_MAC_ADDRESS_OFFSET_LAN0 0
#define E1000_ALT_MAC_ADDRESS_OFFSET_LAN1 3
#define E1000_ALT_MAC_ADDRESS_OFFSET_LAN2 6
#define E1000_ALT_MAC_ADDRESS_OFFSET_LAN3 9
enum e1000_mac_type {
e1000_undefined = 0,
e1000_82575,
e1000_82576,
e1000_82580,
e1000_i350,
e1000_i354,
e1000_i210,
e1000_i211,
e1000_num_macs /* List is 1-based, so subtract 1 for true count. */
};
enum e1000_media_type {
e1000_media_type_unknown = 0,
e1000_media_type_copper = 1,
e1000_media_type_fiber = 2,
e1000_media_type_internal_serdes = 3,
e1000_num_media_types
};
enum e1000_nvm_type {
e1000_nvm_unknown = 0,
e1000_nvm_none,
e1000_nvm_eeprom_spi,
e1000_nvm_flash_hw,
e1000_nvm_invm,
e1000_nvm_flash_sw
};
enum e1000_nvm_override {
e1000_nvm_override_none = 0,
e1000_nvm_override_spi_small,
e1000_nvm_override_spi_large,
};
enum e1000_phy_type {
e1000_phy_unknown = 0,
e1000_phy_none,
e1000_phy_m88,
e1000_phy_igp,
e1000_phy_igp_2,
e1000_phy_gg82563,
e1000_phy_igp_3,
e1000_phy_ife,
e1000_phy_82580,
e1000_phy_i210,
e1000_phy_bcm54616,
};
enum e1000_bus_type {
e1000_bus_type_unknown = 0,
e1000_bus_type_pci,
e1000_bus_type_pcix,
e1000_bus_type_pci_express,
e1000_bus_type_reserved
};
enum e1000_bus_speed {
e1000_bus_speed_unknown = 0,
e1000_bus_speed_33,
e1000_bus_speed_66,
e1000_bus_speed_100,
e1000_bus_speed_120,
e1000_bus_speed_133,
e1000_bus_speed_2500,
e1000_bus_speed_5000,
e1000_bus_speed_reserved
};
enum e1000_bus_width {
e1000_bus_width_unknown = 0,
e1000_bus_width_pcie_x1,
e1000_bus_width_pcie_x2,
e1000_bus_width_pcie_x4 = 4,
e1000_bus_width_pcie_x8 = 8,
e1000_bus_width_32,
e1000_bus_width_64,
e1000_bus_width_reserved
};
enum e1000_1000t_rx_status {
e1000_1000t_rx_status_not_ok = 0,
e1000_1000t_rx_status_ok,
e1000_1000t_rx_status_undefined = 0xFF
};
enum e1000_rev_polarity {
e1000_rev_polarity_normal = 0,
e1000_rev_polarity_reversed,
e1000_rev_polarity_undefined = 0xFF
};
enum e1000_fc_mode {
e1000_fc_none = 0,
e1000_fc_rx_pause,
e1000_fc_tx_pause,
e1000_fc_full,
e1000_fc_default = 0xFF
};
/* Statistics counters collected by the MAC */
struct e1000_hw_stats {
u64 crcerrs;
u64 algnerrc;
u64 symerrs;
u64 rxerrc;
u64 mpc;
u64 scc;
u64 ecol;
u64 mcc;
u64 latecol;
u64 colc;
u64 dc;
u64 tncrs;
u64 sec;
u64 cexterr;
u64 rlec;
u64 xonrxc;
u64 xontxc;
u64 xoffrxc;
u64 xofftxc;
u64 fcruc;
u64 prc64;
u64 prc127;
u64 prc255;
u64 prc511;
u64 prc1023;
u64 prc1522;
u64 gprc;
u64 bprc;
u64 mprc;
u64 gptc;
u64 gorc;
u64 gotc;
u64 rnbc;
u64 ruc;
u64 rfc;
u64 roc;
u64 rjc;
u64 mgprc;
u64 mgpdc;
u64 mgptc;
u64 tor;
u64 tot;
u64 tpr;
u64 tpt;
u64 ptc64;
u64 ptc127;
u64 ptc255;
u64 ptc511;
u64 ptc1023;
u64 ptc1522;
u64 mptc;
u64 bptc;
u64 tsctc;
u64 tsctfc;
u64 iac;
u64 icrxptc;
u64 icrxatc;
u64 ictxptc;
u64 ictxatc;
u64 ictxqec;
u64 ictxqmtc;
u64 icrxdmtc;
u64 icrxoc;
u64 cbtmpc;
u64 htdpmc;
u64 cbrdpc;
u64 cbrmpc;
u64 rpthc;
u64 hgptc;
u64 htcbdpc;
u64 hgorc;
u64 hgotc;
u64 lenerrs;
u64 scvpc;
u64 hrmpc;
u64 doosync;
u64 o2bgptc;
u64 o2bspc;
u64 b2ospc;
u64 b2ogprc;
};
struct e1000_host_mng_dhcp_cookie {
u32 signature;
u8 status;
u8 reserved0;
u16 vlan_id;
u32 reserved1;
u16 reserved2;
u8 reserved3;
u8 checksum;
};
/* Host Interface "Rev 1" */
struct e1000_host_command_header {
u8 command_id;
u8 command_length;
u8 command_options;
u8 checksum;
};
#define E1000_HI_MAX_DATA_LENGTH 252
struct e1000_host_command_info {
struct e1000_host_command_header command_header;
u8 command_data[E1000_HI_MAX_DATA_LENGTH];
};
/* Host Interface "Rev 2" */
struct e1000_host_mng_command_header {
u8 command_id;
u8 checksum;
u16 reserved1;
u16 reserved2;
u16 command_length;
};
#define E1000_HI_MAX_MNG_DATA_LENGTH 0x6F8
struct e1000_host_mng_command_info {
struct e1000_host_mng_command_header command_header;
u8 command_data[E1000_HI_MAX_MNG_DATA_LENGTH];
};
#include "e1000_mac.h"
#include "e1000_phy.h"
#include "e1000_nvm.h"
#include "e1000_mbx.h"
struct e1000_mac_operations {
s32 (*check_for_link)(struct e1000_hw *);
s32 (*reset_hw)(struct e1000_hw *);
s32 (*init_hw)(struct e1000_hw *);
bool (*check_mng_mode)(struct e1000_hw *);
s32 (*setup_physical_interface)(struct e1000_hw *);
void (*rar_set)(struct e1000_hw *, u8 *, u32);
s32 (*read_mac_addr)(struct e1000_hw *);
s32 (*get_speed_and_duplex)(struct e1000_hw *, u16 *, u16 *);
s32 (*acquire_swfw_sync)(struct e1000_hw *, u16);
void (*release_swfw_sync)(struct e1000_hw *, u16);
#ifdef CONFIG_IGB_HWMON
s32 (*get_thermal_sensor_data)(struct e1000_hw *);
s32 (*init_thermal_sensor_thresh)(struct e1000_hw *);
#endif
void (*write_vfta)(struct e1000_hw *, u32, u32);
};
struct e1000_phy_operations {
s32 (*acquire)(struct e1000_hw *);
s32 (*check_polarity)(struct e1000_hw *);
s32 (*check_reset_block)(struct e1000_hw *);
s32 (*force_speed_duplex)(struct e1000_hw *);
s32 (*get_cfg_done)(struct e1000_hw *hw);
s32 (*get_cable_length)(struct e1000_hw *);
s32 (*get_phy_info)(struct e1000_hw *);
s32 (*read_reg)(struct e1000_hw *, u32, u16 *);
void (*release)(struct e1000_hw *);
s32 (*reset)(struct e1000_hw *);
s32 (*set_d0_lplu_state)(struct e1000_hw *, bool);
s32 (*set_d3_lplu_state)(struct e1000_hw *, bool);
s32 (*write_reg)(struct e1000_hw *, u32, u16);
s32 (*read_i2c_byte)(struct e1000_hw *, u8, u8, u8 *);
s32 (*write_i2c_byte)(struct e1000_hw *, u8, u8, u8);
};
struct e1000_nvm_operations {
s32 (*acquire)(struct e1000_hw *);
s32 (*read)(struct e1000_hw *, u16, u16, u16 *);
void (*release)(struct e1000_hw *);
s32 (*write)(struct e1000_hw *, u16, u16, u16 *);
s32 (*update)(struct e1000_hw *);
s32 (*validate)(struct e1000_hw *);
s32 (*valid_led_default)(struct e1000_hw *, u16 *);
};
#define E1000_MAX_SENSORS 3
struct e1000_thermal_diode_data {
u8 location;
u8 temp;
u8 caution_thresh;
u8 max_op_thresh;
};
struct e1000_thermal_sensor_data {
struct e1000_thermal_diode_data sensor[E1000_MAX_SENSORS];
};
struct e1000_info {
s32 (*get_invariants)(struct e1000_hw *);
struct e1000_mac_operations *mac_ops;
const struct e1000_phy_operations *phy_ops;
struct e1000_nvm_operations *nvm_ops;
};
extern const struct e1000_info e1000_82575_info;
struct e1000_mac_info {
struct e1000_mac_operations ops;
u8 addr[6];
u8 perm_addr[6];
enum e1000_mac_type type;
u32 ledctl_default;
u32 ledctl_mode1;
u32 ledctl_mode2;
u32 mc_filter_type;
u32 txcw;
u16 mta_reg_count;
u16 uta_reg_count;
/* Maximum size of the MTA register table in all supported adapters */
#define MAX_MTA_REG 128
u32 mta_shadow[MAX_MTA_REG];
u16 rar_entry_count;
u8 forced_speed_duplex;
bool adaptive_ifs;
bool arc_subsystem_valid;
bool asf_firmware_present;
bool autoneg;
bool autoneg_failed;
bool disable_hw_init_bits;
bool get_link_status;
bool ifs_params_forced;
bool in_ifs_mode;
bool report_tx_early;
bool serdes_has_link;
bool tx_pkt_filtering;
struct e1000_thermal_sensor_data thermal_sensor_data;
};
struct e1000_phy_info {
struct e1000_phy_operations ops;
enum e1000_phy_type type;
enum e1000_1000t_rx_status local_rx;
enum e1000_1000t_rx_status remote_rx;
enum e1000_ms_type ms_type;
enum e1000_ms_type original_ms_type;
enum e1000_rev_polarity cable_polarity;
enum e1000_smart_speed smart_speed;
u32 addr;
u32 id;
u32 reset_delay_us; /* in usec */
u32 revision;
enum e1000_media_type media_type;
u16 autoneg_advertised;
u16 autoneg_mask;
u16 cable_length;
u16 max_cable_length;
u16 min_cable_length;
u16 pair_length[4];
u8 mdix;
bool disable_polarity_correction;
bool is_mdix;
bool polarity_correction;
bool reset_disable;
bool speed_downgraded;
bool autoneg_wait_to_complete;
};
struct e1000_nvm_info {
struct e1000_nvm_operations ops;
enum e1000_nvm_type type;
enum e1000_nvm_override override;
u32 flash_bank_size;
u32 flash_base_addr;
u16 word_size;
u16 delay_usec;
u16 address_bits;
u16 opcode_bits;
u16 page_size;
};
struct e1000_bus_info {
enum e1000_bus_type type;
enum e1000_bus_speed speed;
enum e1000_bus_width width;
u32 snoop;
u16 func;
u16 pci_cmd_word;
};
struct e1000_fc_info {
u32 high_water; /* Flow control high-water mark */
u32 low_water; /* Flow control low-water mark */
u16 pause_time; /* Flow control pause timer */
bool send_xon; /* Flow control send XON */
bool strict_ieee; /* Strict IEEE mode */
enum e1000_fc_mode current_mode; /* Type of flow control */
enum e1000_fc_mode requested_mode;
};
struct e1000_mbx_operations {
s32 (*init_params)(struct e1000_hw *hw);
s32 (*read)(struct e1000_hw *hw, u32 *msg, u16 size, u16 mbx_id,
bool unlock);
s32 (*write)(struct e1000_hw *hw, u32 *msg, u16 size, u16 mbx_id);
s32 (*read_posted)(struct e1000_hw *hw, u32 *msg, u16 size, u16 mbx_id);
s32 (*write_posted)(struct e1000_hw *hw, u32 *msg, u16 size,
u16 mbx_id);
s32 (*check_for_msg)(struct e1000_hw *hw, u16 mbx_id);
s32 (*check_for_ack)(struct e1000_hw *hw, u16 mbx_id);
s32 (*check_for_rst)(struct e1000_hw *hw, u16 mbx_id);
s32 (*unlock)(struct e1000_hw *hw, u16 mbx_id);
};
struct e1000_mbx_stats {
u32 msgs_tx;
u32 msgs_rx;
u32 acks;
u32 reqs;
u32 rsts;
};
struct e1000_mbx_info {
struct e1000_mbx_operations ops;
struct e1000_mbx_stats stats;
u32 timeout;
u32 usec_delay;
u16 size;
};
struct e1000_dev_spec_82575 {
bool sgmii_active;
bool global_device_reset;
bool eee_disable;
bool clear_semaphore_once;
struct e1000_sfp_flags eth_flags;
bool module_plugged;
u8 media_port;
bool media_changed;
bool mas_capable;
};
struct e1000_hw {
void *back;
u8 __iomem *hw_addr;
u8 __iomem *flash_address;
unsigned long io_base;
struct e1000_mac_info mac;
struct e1000_fc_info fc;
struct e1000_phy_info phy;
struct e1000_nvm_info nvm;
struct e1000_bus_info bus;
struct e1000_mbx_info mbx;
struct e1000_host_mng_dhcp_cookie mng_cookie;
union {
struct e1000_dev_spec_82575 _82575;
} dev_spec;
u16 device_id;
u16 subsystem_vendor_id;
u16 subsystem_device_id;
u16 vendor_id;
u8 revision_id;
};
struct net_device *igb_get_hw_dev(struct e1000_hw *hw);
#define hw_dbg(format, arg...) \
netdev_dbg(igb_get_hw_dev(hw), format, ##arg)
/* These functions must be implemented by drivers */
s32 igb_read_pcie_cap_reg(struct e1000_hw *hw, u32 reg, u16 *value);
s32 igb_write_pcie_cap_reg(struct e1000_hw *hw, u32 reg, u16 *value);
void igb_read_pci_cfg(struct e1000_hw *hw, u32 reg, u16 *value);
void igb_write_pci_cfg(struct e1000_hw *hw, u32 reg, u16 *value);
#endif /* _E1000_IGB_HW_H_ */

View File

@ -0,0 +1,911 @@
// SPDX-License-Identifier: GPL-2.0
/* Copyright(c) 2007 - 2018 Intel Corporation. */
/* e1000_i210
* e1000_i211
*/
#include <linux/types.h>
#include <linux/if_ether.h>
#include "e1000_hw-6.1-ethercat.h"
#include "e1000_i210-6.1-ethercat.h"
static s32 igb_update_flash_i210(struct e1000_hw *hw);
/**
* igb_get_hw_semaphore_i210 - Acquire hardware semaphore
* @hw: pointer to the HW structure
*
* Acquire the HW semaphore to access the PHY or NVM
*/
static s32 igb_get_hw_semaphore_i210(struct e1000_hw *hw)
{
u32 swsm;
s32 timeout = hw->nvm.word_size + 1;
s32 i = 0;
/* Get the SW semaphore */
while (i < timeout) {
swsm = rd32(E1000_SWSM);
if (!(swsm & E1000_SWSM_SMBI))
break;
udelay(50);
i++;
}
if (i == timeout) {
/* In rare circumstances, the SW semaphore may already be held
* unintentionally. Clear the semaphore once before giving up.
*/
if (hw->dev_spec._82575.clear_semaphore_once) {
hw->dev_spec._82575.clear_semaphore_once = false;
igb_put_hw_semaphore(hw);
for (i = 0; i < timeout; i++) {
swsm = rd32(E1000_SWSM);
if (!(swsm & E1000_SWSM_SMBI))
break;
udelay(50);
}
}
/* If we do not have the semaphore here, we have to give up. */
if (i == timeout) {
hw_dbg("Driver can't access device - SMBI bit is set.\n");
return -E1000_ERR_NVM;
}
}
/* Get the FW semaphore. */
for (i = 0; i < timeout; i++) {
swsm = rd32(E1000_SWSM);
wr32(E1000_SWSM, swsm | E1000_SWSM_SWESMBI);
/* Semaphore acquired if bit latched */
if (rd32(E1000_SWSM) & E1000_SWSM_SWESMBI)
break;
udelay(50);
}
if (i == timeout) {
/* Release semaphores */
igb_put_hw_semaphore(hw);
hw_dbg("Driver can't access the NVM\n");
return -E1000_ERR_NVM;
}
return 0;
}
/**
* igb_acquire_nvm_i210 - Request for access to EEPROM
* @hw: pointer to the HW structure
*
* Acquire the necessary semaphores for exclusive access to the EEPROM.
* Set the EEPROM access request bit and wait for EEPROM access grant bit.
* Return successful if access grant bit set, else clear the request for
* EEPROM access and return -E1000_ERR_NVM (-1).
**/
static s32 igb_acquire_nvm_i210(struct e1000_hw *hw)
{
return igb_acquire_swfw_sync_i210(hw, E1000_SWFW_EEP_SM);
}
/**
* igb_release_nvm_i210 - Release exclusive access to EEPROM
* @hw: pointer to the HW structure
*
* Stop any current commands to the EEPROM and clear the EEPROM request bit,
* then release the semaphores acquired.
**/
static void igb_release_nvm_i210(struct e1000_hw *hw)
{
igb_release_swfw_sync_i210(hw, E1000_SWFW_EEP_SM);
}
/**
* igb_acquire_swfw_sync_i210 - Acquire SW/FW semaphore
* @hw: pointer to the HW structure
* @mask: specifies which semaphore to acquire
*
* Acquire the SW/FW semaphore to access the PHY or NVM. The mask
* will also specify which port we're acquiring the lock for.
**/
s32 igb_acquire_swfw_sync_i210(struct e1000_hw *hw, u16 mask)
{
u32 swfw_sync;
u32 swmask = mask;
u32 fwmask = mask << 16;
s32 ret_val = 0;
s32 i = 0, timeout = 200; /* FIXME: find real value to use here */
while (i < timeout) {
if (igb_get_hw_semaphore_i210(hw)) {
ret_val = -E1000_ERR_SWFW_SYNC;
goto out;
}
swfw_sync = rd32(E1000_SW_FW_SYNC);
if (!(swfw_sync & (fwmask | swmask)))
break;
/* Firmware currently using resource (fwmask) */
igb_put_hw_semaphore(hw);
mdelay(5);
i++;
}
if (i == timeout) {
hw_dbg("Driver can't access resource, SW_FW_SYNC timeout.\n");
ret_val = -E1000_ERR_SWFW_SYNC;
goto out;
}
swfw_sync |= swmask;
wr32(E1000_SW_FW_SYNC, swfw_sync);
igb_put_hw_semaphore(hw);
out:
return ret_val;
}
/**
* igb_release_swfw_sync_i210 - Release SW/FW semaphore
* @hw: pointer to the HW structure
* @mask: specifies which semaphore to acquire
*
* Release the SW/FW semaphore used to access the PHY or NVM. The mask
* will also specify which port we're releasing the lock for.
**/
void igb_release_swfw_sync_i210(struct e1000_hw *hw, u16 mask)
{
u32 swfw_sync;
while (igb_get_hw_semaphore_i210(hw))
; /* Empty */
swfw_sync = rd32(E1000_SW_FW_SYNC);
swfw_sync &= ~mask;
wr32(E1000_SW_FW_SYNC, swfw_sync);
igb_put_hw_semaphore(hw);
}
/**
* igb_read_nvm_srrd_i210 - Reads Shadow Ram using EERD register
* @hw: pointer to the HW structure
* @offset: offset of word in the Shadow Ram to read
* @words: number of words to read
* @data: word read from the Shadow Ram
*
* Reads a 16 bit word from the Shadow Ram using the EERD register.
* Uses necessary synchronization semaphores.
**/
static s32 igb_read_nvm_srrd_i210(struct e1000_hw *hw, u16 offset, u16 words,
u16 *data)
{
s32 status = 0;
u16 i, count;
/* We cannot hold synchronization semaphores for too long,
* because of forceful takeover procedure. However it is more efficient
* to read in bursts than synchronizing access for each word.
*/
for (i = 0; i < words; i += E1000_EERD_EEWR_MAX_COUNT) {
count = (words - i) / E1000_EERD_EEWR_MAX_COUNT > 0 ?
E1000_EERD_EEWR_MAX_COUNT : (words - i);
if (!(hw->nvm.ops.acquire(hw))) {
status = igb_read_nvm_eerd(hw, offset, count,
data + i);
hw->nvm.ops.release(hw);
} else {
status = E1000_ERR_SWFW_SYNC;
}
if (status)
break;
}
return status;
}
/**
* igb_write_nvm_srwr - Write to Shadow Ram using EEWR
* @hw: pointer to the HW structure
* @offset: offset within the Shadow Ram to be written to
* @words: number of words to write
* @data: 16 bit word(s) to be written to the Shadow Ram
*
* Writes data to Shadow Ram at offset using EEWR register.
*
* If igb_update_nvm_checksum is not called after this function , the
* Shadow Ram will most likely contain an invalid checksum.
**/
static s32 igb_write_nvm_srwr(struct e1000_hw *hw, u16 offset, u16 words,
u16 *data)
{
struct e1000_nvm_info *nvm = &hw->nvm;
u32 i, k, eewr = 0;
u32 attempts = 100000;
s32 ret_val = 0;
/* A check for invalid values: offset too large, too many words,
* too many words for the offset, and not enough words.
*/
if ((offset >= nvm->word_size) || (words > (nvm->word_size - offset)) ||
(words == 0)) {
hw_dbg("nvm parameter(s) out of bounds\n");
ret_val = -E1000_ERR_NVM;
goto out;
}
for (i = 0; i < words; i++) {
eewr = ((offset+i) << E1000_NVM_RW_ADDR_SHIFT) |
(data[i] << E1000_NVM_RW_REG_DATA) |
E1000_NVM_RW_REG_START;
wr32(E1000_SRWR, eewr);
for (k = 0; k < attempts; k++) {
if (E1000_NVM_RW_REG_DONE &
rd32(E1000_SRWR)) {
ret_val = 0;
break;
}
udelay(5);
}
if (ret_val) {
hw_dbg("Shadow RAM write EEWR timed out\n");
break;
}
}
out:
return ret_val;
}
/**
* igb_write_nvm_srwr_i210 - Write to Shadow RAM using EEWR
* @hw: pointer to the HW structure
* @offset: offset within the Shadow RAM to be written to
* @words: number of words to write
* @data: 16 bit word(s) to be written to the Shadow RAM
*
* Writes data to Shadow RAM at offset using EEWR register.
*
* If e1000_update_nvm_checksum is not called after this function , the
* data will not be committed to FLASH and also Shadow RAM will most likely
* contain an invalid checksum.
*
* If error code is returned, data and Shadow RAM may be inconsistent - buffer
* partially written.
**/
static s32 igb_write_nvm_srwr_i210(struct e1000_hw *hw, u16 offset, u16 words,
u16 *data)
{
s32 status = 0;
u16 i, count;
/* We cannot hold synchronization semaphores for too long,
* because of forceful takeover procedure. However it is more efficient
* to write in bursts than synchronizing access for each word.
*/
for (i = 0; i < words; i += E1000_EERD_EEWR_MAX_COUNT) {
count = (words - i) / E1000_EERD_EEWR_MAX_COUNT > 0 ?
E1000_EERD_EEWR_MAX_COUNT : (words - i);
if (!(hw->nvm.ops.acquire(hw))) {
status = igb_write_nvm_srwr(hw, offset, count,
data + i);
hw->nvm.ops.release(hw);
} else {
status = E1000_ERR_SWFW_SYNC;
}
if (status)
break;
}
return status;
}
/**
* igb_read_invm_word_i210 - Reads OTP
* @hw: pointer to the HW structure
* @address: the word address (aka eeprom offset) to read
* @data: pointer to the data read
*
* Reads 16-bit words from the OTP. Return error when the word is not
* stored in OTP.
**/
static s32 igb_read_invm_word_i210(struct e1000_hw *hw, u8 address, u16 *data)
{
s32 status = -E1000_ERR_INVM_VALUE_NOT_FOUND;
u32 invm_dword;
u16 i;
u8 record_type, word_address;
for (i = 0; i < E1000_INVM_SIZE; i++) {
invm_dword = rd32(E1000_INVM_DATA_REG(i));
/* Get record type */
record_type = INVM_DWORD_TO_RECORD_TYPE(invm_dword);
if (record_type == E1000_INVM_UNINITIALIZED_STRUCTURE)
break;
if (record_type == E1000_INVM_CSR_AUTOLOAD_STRUCTURE)
i += E1000_INVM_CSR_AUTOLOAD_DATA_SIZE_IN_DWORDS;
if (record_type == E1000_INVM_RSA_KEY_SHA256_STRUCTURE)
i += E1000_INVM_RSA_KEY_SHA256_DATA_SIZE_IN_DWORDS;
if (record_type == E1000_INVM_WORD_AUTOLOAD_STRUCTURE) {
word_address = INVM_DWORD_TO_WORD_ADDRESS(invm_dword);
if (word_address == address) {
*data = INVM_DWORD_TO_WORD_DATA(invm_dword);
hw_dbg("Read INVM Word 0x%02x = %x\n",
address, *data);
status = 0;
break;
}
}
}
if (status)
hw_dbg("Requested word 0x%02x not found in OTP\n", address);
return status;
}
/**
* igb_read_invm_i210 - Read invm wrapper function for I210/I211
* @hw: pointer to the HW structure
* @offset: offset to read from
* @words: number of words to read (unused)
* @data: pointer to the data read
*
* Wrapper function to return data formerly found in the NVM.
**/
static s32 igb_read_invm_i210(struct e1000_hw *hw, u16 offset,
u16 __always_unused words, u16 *data)
{
s32 ret_val = 0;
/* 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;
case NVM_INIT_CTRL_2:
ret_val = igb_read_invm_word_i210(hw, (u8)offset, data);
if (ret_val) {
*data = NVM_INIT_CTRL_2_DEFAULT_I211;
ret_val = 0;
}
break;
case NVM_INIT_CTRL_4:
ret_val = igb_read_invm_word_i210(hw, (u8)offset, data);
if (ret_val) {
*data = NVM_INIT_CTRL_4_DEFAULT_I211;
ret_val = 0;
}
break;
case NVM_LED_1_CFG:
ret_val = igb_read_invm_word_i210(hw, (u8)offset, data);
if (ret_val) {
*data = NVM_LED_1_CFG_DEFAULT_I211;
ret_val = 0;
}
break;
case NVM_LED_0_2_CFG:
ret_val = igb_read_invm_word_i210(hw, (u8)offset, data);
if (ret_val) {
*data = NVM_LED_0_2_CFG_DEFAULT_I211;
ret_val = 0;
}
break;
case NVM_ID_LED_SETTINGS:
ret_val = igb_read_invm_word_i210(hw, (u8)offset, data);
if (ret_val) {
*data = ID_LED_RESERVED_FFFF;
ret_val = 0;
}
break;
case NVM_SUB_DEV_ID:
*data = hw->subsystem_device_id;
break;
case NVM_SUB_VEN_ID:
*data = hw->subsystem_vendor_id;
break;
case NVM_DEV_ID:
*data = hw->device_id;
break;
case NVM_VEN_ID:
*data = hw->vendor_id;
break;
default:
hw_dbg("NVM word 0x%02x is not mapped.\n", offset);
*data = NVM_RESERVED_WORD;
break;
}
return ret_val;
}
/**
* igb_read_invm_version - Reads iNVM version and image type
* @hw: pointer to the HW structure
* @invm_ver: version structure for the version read
*
* Reads iNVM version and image type.
**/
s32 igb_read_invm_version(struct e1000_hw *hw,
struct e1000_fw_version *invm_ver) {
u32 *record = NULL;
u32 *next_record = NULL;
u32 i = 0;
u32 invm_dword = 0;
u32 invm_blocks = E1000_INVM_SIZE - (E1000_INVM_ULT_BYTES_SIZE /
E1000_INVM_RECORD_SIZE_IN_BYTES);
u32 buffer[E1000_INVM_SIZE];
s32 status = -E1000_ERR_INVM_VALUE_NOT_FOUND;
u16 version = 0;
/* Read iNVM memory */
for (i = 0; i < E1000_INVM_SIZE; i++) {
invm_dword = rd32(E1000_INVM_DATA_REG(i));
buffer[i] = invm_dword;
}
/* Read version number */
for (i = 1; i < invm_blocks; i++) {
record = &buffer[invm_blocks - i];
next_record = &buffer[invm_blocks - i + 1];
/* Check if we have first version location used */
if ((i == 1) && ((*record & E1000_INVM_VER_FIELD_ONE) == 0)) {
version = 0;
status = 0;
break;
}
/* Check if we have second version location used */
else if ((i == 1) &&
((*record & E1000_INVM_VER_FIELD_TWO) == 0)) {
version = (*record & E1000_INVM_VER_FIELD_ONE) >> 3;
status = 0;
break;
}
/* Check if we have odd version location
* used and it is the last one used
*/
else if ((((*record & E1000_INVM_VER_FIELD_ONE) == 0) &&
((*record & 0x3) == 0)) || (((*record & 0x3) != 0) &&
(i != 1))) {
version = (*next_record & E1000_INVM_VER_FIELD_TWO)
>> 13;
status = 0;
break;
}
/* Check if we have even version location
* used and it is the last one used
*/
else if (((*record & E1000_INVM_VER_FIELD_TWO) == 0) &&
((*record & 0x3) == 0)) {
version = (*record & E1000_INVM_VER_FIELD_ONE) >> 3;
status = 0;
break;
}
}
if (!status) {
invm_ver->invm_major = (version & E1000_INVM_MAJOR_MASK)
>> E1000_INVM_MAJOR_SHIFT;
invm_ver->invm_minor = version & E1000_INVM_MINOR_MASK;
}
/* Read Image Type */
for (i = 1; i < invm_blocks; i++) {
record = &buffer[invm_blocks - i];
next_record = &buffer[invm_blocks - i + 1];
/* Check if we have image type in first location used */
if ((i == 1) && ((*record & E1000_INVM_IMGTYPE_FIELD) == 0)) {
invm_ver->invm_img_type = 0;
status = 0;
break;
}
/* Check if we have image type in first location used */
else if ((((*record & 0x3) == 0) &&
((*record & E1000_INVM_IMGTYPE_FIELD) == 0)) ||
((((*record & 0x3) != 0) && (i != 1)))) {
invm_ver->invm_img_type =
(*next_record & E1000_INVM_IMGTYPE_FIELD) >> 23;
status = 0;
break;
}
}
return status;
}
/**
* igb_validate_nvm_checksum_i210 - Validate EEPROM checksum
* @hw: pointer to the HW structure
*
* Calculates the EEPROM checksum by reading/adding each word of the EEPROM
* and then verifies that the sum of the EEPROM is equal to 0xBABA.
**/
static s32 igb_validate_nvm_checksum_i210(struct e1000_hw *hw)
{
s32 status = 0;
s32 (*read_op_ptr)(struct e1000_hw *, u16, u16, u16 *);
if (!(hw->nvm.ops.acquire(hw))) {
/* Replace the read function with semaphore grabbing with
* the one that skips this for a while.
* We have semaphore taken already here.
*/
read_op_ptr = hw->nvm.ops.read;
hw->nvm.ops.read = igb_read_nvm_eerd;
status = igb_validate_nvm_checksum(hw);
/* Revert original read operation. */
hw->nvm.ops.read = read_op_ptr;
hw->nvm.ops.release(hw);
} else {
status = E1000_ERR_SWFW_SYNC;
}
return status;
}
/**
* igb_update_nvm_checksum_i210 - Update EEPROM checksum
* @hw: pointer to the HW structure
*
* Updates the EEPROM checksum by reading/adding each word of the EEPROM
* up to the checksum. Then calculates the EEPROM checksum and writes the
* value to the EEPROM. Next commit EEPROM data onto the Flash.
**/
static s32 igb_update_nvm_checksum_i210(struct e1000_hw *hw)
{
s32 ret_val = 0;
u16 checksum = 0;
u16 i, nvm_data;
/* Read the first word from the EEPROM. If this times out or fails, do
* not continue or we could be in for a very long wait while every
* EEPROM read fails
*/
ret_val = igb_read_nvm_eerd(hw, 0, 1, &nvm_data);
if (ret_val) {
hw_dbg("EEPROM read failed\n");
goto out;
}
if (!(hw->nvm.ops.acquire(hw))) {
/* Do not use hw->nvm.ops.write, hw->nvm.ops.read
* because we do not want to take the synchronization
* semaphores twice here.
*/
for (i = 0; i < NVM_CHECKSUM_REG; i++) {
ret_val = igb_read_nvm_eerd(hw, i, 1, &nvm_data);
if (ret_val) {
hw->nvm.ops.release(hw);
hw_dbg("NVM Read Error while updating checksum.\n");
goto out;
}
checksum += nvm_data;
}
checksum = (u16) NVM_SUM - checksum;
ret_val = igb_write_nvm_srwr(hw, NVM_CHECKSUM_REG, 1,
&checksum);
if (ret_val) {
hw->nvm.ops.release(hw);
hw_dbg("NVM Write Error while updating checksum.\n");
goto out;
}
hw->nvm.ops.release(hw);
ret_val = igb_update_flash_i210(hw);
} else {
ret_val = -E1000_ERR_SWFW_SYNC;
}
out:
return ret_val;
}
/**
* igb_pool_flash_update_done_i210 - Pool FLUDONE status.
* @hw: pointer to the HW structure
*
**/
static s32 igb_pool_flash_update_done_i210(struct e1000_hw *hw)
{
s32 ret_val = -E1000_ERR_NVM;
u32 i, reg;
for (i = 0; i < E1000_FLUDONE_ATTEMPTS; i++) {
reg = rd32(E1000_EECD);
if (reg & E1000_EECD_FLUDONE_I210) {
ret_val = 0;
break;
}
udelay(5);
}
return ret_val;
}
/**
* 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;
}
/**
* igb_update_flash_i210 - Commit EEPROM to the flash
* @hw: pointer to the HW structure
*
**/
static s32 igb_update_flash_i210(struct e1000_hw *hw)
{
s32 ret_val = 0;
u32 flup;
ret_val = igb_pool_flash_update_done_i210(hw);
if (ret_val == -E1000_ERR_NVM) {
hw_dbg("Flash update time out\n");
goto out;
}
flup = rd32(E1000_EECD) | E1000_EECD_FLUPD_I210;
wr32(E1000_EECD, flup);
ret_val = igb_pool_flash_update_done_i210(hw);
if (ret_val)
hw_dbg("Flash update time out\n");
else
hw_dbg("Flash update complete\n");
out:
return ret_val;
}
/**
* igb_valid_led_default_i210 - Verify a valid default LED config
* @hw: pointer to the HW structure
* @data: pointer to the NVM (EEPROM)
*
* Read the EEPROM for the current default LED configuration. If the
* LED configuration is not valid, set to a valid LED configuration.
**/
s32 igb_valid_led_default_i210(struct e1000_hw *hw, u16 *data)
{
s32 ret_val;
ret_val = hw->nvm.ops.read(hw, NVM_ID_LED_SETTINGS, 1, data);
if (ret_val) {
hw_dbg("NVM Read Error\n");
goto out;
}
if (*data == ID_LED_RESERVED_0000 || *data == ID_LED_RESERVED_FFFF) {
switch (hw->phy.media_type) {
case e1000_media_type_internal_serdes:
*data = ID_LED_DEFAULT_I210_SERDES;
break;
case e1000_media_type_copper:
default:
*data = ID_LED_DEFAULT_I210;
break;
}
}
out:
return ret_val;
}
/**
* __igb_access_xmdio_reg - Read/write XMDIO register
* @hw: pointer to the HW structure
* @address: XMDIO address to program
* @dev_addr: device address to program
* @data: pointer to value to read/write from/to the XMDIO address
* @read: boolean flag to indicate read or write
**/
static s32 __igb_access_xmdio_reg(struct e1000_hw *hw, u16 address,
u8 dev_addr, u16 *data, bool read)
{
s32 ret_val = 0;
ret_val = hw->phy.ops.write_reg(hw, E1000_MMDAC, dev_addr);
if (ret_val)
return ret_val;
ret_val = hw->phy.ops.write_reg(hw, E1000_MMDAAD, address);
if (ret_val)
return ret_val;
ret_val = hw->phy.ops.write_reg(hw, E1000_MMDAC, E1000_MMDAC_FUNC_DATA |
dev_addr);
if (ret_val)
return ret_val;
if (read)
ret_val = hw->phy.ops.read_reg(hw, E1000_MMDAAD, data);
else
ret_val = hw->phy.ops.write_reg(hw, E1000_MMDAAD, *data);
if (ret_val)
return ret_val;
/* Recalibrate the device back to 0 */
ret_val = hw->phy.ops.write_reg(hw, E1000_MMDAC, 0);
if (ret_val)
return ret_val;
return ret_val;
}
/**
* igb_read_xmdio_reg - Read XMDIO register
* @hw: pointer to the HW structure
* @addr: XMDIO address to program
* @dev_addr: device address to program
* @data: value to be read from the EMI address
**/
s32 igb_read_xmdio_reg(struct e1000_hw *hw, u16 addr, u8 dev_addr, u16 *data)
{
return __igb_access_xmdio_reg(hw, addr, dev_addr, data, true);
}
/**
* igb_write_xmdio_reg - Write XMDIO register
* @hw: pointer to the HW structure
* @addr: XMDIO address to program
* @dev_addr: device address to program
* @data: value to be written to the XMDIO address
**/
s32 igb_write_xmdio_reg(struct e1000_hw *hw, u16 addr, u8 dev_addr, u16 data)
{
return __igb_access_xmdio_reg(hw, addr, dev_addr, &data, false);
}
/**
* igb_init_nvm_params_i210 - Init NVM func ptrs.
* @hw: pointer to the HW structure
**/
s32 igb_init_nvm_params_i210(struct e1000_hw *hw)
{
struct e1000_nvm_info *nvm = &hw->nvm;
nvm->ops.acquire = igb_acquire_nvm_i210;
nvm->ops.release = igb_release_nvm_i210;
nvm->ops.valid_led_default = igb_valid_led_default_i210;
/* NVM Function Pointers */
if (igb_get_flash_presence_i210(hw)) {
hw->nvm.type = e1000_nvm_flash_hw;
nvm->ops.read = igb_read_nvm_srrd_i210;
nvm->ops.write = igb_write_nvm_srwr_i210;
nvm->ops.validate = igb_validate_nvm_checksum_i210;
nvm->ops.update = igb_update_nvm_checksum_i210;
} else {
hw->nvm.type = e1000_nvm_invm;
nvm->ops.read = igb_read_invm_i210;
nvm->ops.write = NULL;
nvm->ops.validate = NULL;
nvm->ops.update = NULL;
}
return 0;
}
/**
* igb_pll_workaround_i210
* @hw: pointer to the HW structure
*
* Works around an errata in the PLL circuit where it occasionally
* provides the wrong clock frequency after power up.
**/
s32 igb_pll_workaround_i210(struct e1000_hw *hw)
{
s32 ret_val;
u32 wuc, mdicnfg, ctrl, ctrl_ext, reg_val;
u16 nvm_word, phy_word, pci_word, tmp_nvm;
int i;
/* Get and set needed register values */
wuc = rd32(E1000_WUC);
mdicnfg = rd32(E1000_MDICNFG);
reg_val = mdicnfg & ~E1000_MDICNFG_EXT_MDIO;
wr32(E1000_MDICNFG, reg_val);
/* Get data from NVM, or set default */
ret_val = igb_read_invm_word_i210(hw, E1000_INVM_AUTOLOAD,
&nvm_word);
if (ret_val)
nvm_word = E1000_INVM_DEFAULT_AL;
tmp_nvm = nvm_word | E1000_INVM_PLL_WO_VAL;
igb_write_phy_reg_82580(hw, I347AT4_PAGE_SELECT, E1000_PHY_PLL_FREQ_PAGE);
phy_word = E1000_PHY_PLL_UNCONF;
for (i = 0; i < E1000_MAX_PLL_TRIES; i++) {
/* check current state directly from internal PHY */
igb_read_phy_reg_82580(hw, E1000_PHY_PLL_FREQ_REG, &phy_word);
if ((phy_word & E1000_PHY_PLL_UNCONF)
!= E1000_PHY_PLL_UNCONF) {
ret_val = 0;
break;
} else {
ret_val = -E1000_ERR_PHY;
}
/* directly reset the internal PHY */
ctrl = rd32(E1000_CTRL);
wr32(E1000_CTRL, ctrl|E1000_CTRL_PHY_RST);
ctrl_ext = rd32(E1000_CTRL_EXT);
ctrl_ext |= (E1000_CTRL_EXT_PHYPDEN | E1000_CTRL_EXT_SDLPE);
wr32(E1000_CTRL_EXT, ctrl_ext);
wr32(E1000_WUC, 0);
reg_val = (E1000_INVM_AUTOLOAD << 4) | (tmp_nvm << 16);
wr32(E1000_EEARBC_I210, reg_val);
igb_read_pci_cfg(hw, E1000_PCI_PMCSR, &pci_word);
pci_word |= E1000_PCI_PMCSR_D3;
igb_write_pci_cfg(hw, E1000_PCI_PMCSR, &pci_word);
usleep_range(1000, 2000);
pci_word &= ~E1000_PCI_PMCSR_D3;
igb_write_pci_cfg(hw, E1000_PCI_PMCSR, &pci_word);
reg_val = (E1000_INVM_AUTOLOAD << 4) | (nvm_word << 16);
wr32(E1000_EEARBC_I210, reg_val);
/* restore WUC register */
wr32(E1000_WUC, wuc);
}
igb_write_phy_reg_82580(hw, I347AT4_PAGE_SELECT, 0);
/* restore MDICNFG setting */
wr32(E1000_MDICNFG, mdicnfg);
return ret_val;
}
/**
* igb_get_cfg_done_i210 - Read config done bit
* @hw: pointer to the HW structure
*
* Read the management control register for the config done bit for
* completion status. NOTE: silicon which is EEPROM-less will fail trying
* to read the config done bit, so an error is *ONLY* logged and returns
* 0. If we were to return with error, EEPROM-less silicon
* would not be able to be reset or change link.
**/
s32 igb_get_cfg_done_i210(struct e1000_hw *hw)
{
s32 timeout = PHY_CFG_TIMEOUT;
u32 mask = E1000_NVM_CFG_DONE_PORT_0;
while (timeout) {
if (rd32(E1000_EEMNGCTL_I210) & mask)
break;
usleep_range(1000, 2000);
timeout--;
}
if (!timeout)
hw_dbg("MNG configuration cycle has not completed.\n");
return 0;
}

View File

@ -0,0 +1,74 @@
/* SPDX-License-Identifier: GPL-2.0 */
/* Copyright(c) 2007 - 2018 Intel Corporation. */
#ifndef _E1000_I210_H_
#define _E1000_I210_H_
s32 igb_acquire_swfw_sync_i210(struct e1000_hw *hw, u16 mask);
void igb_release_swfw_sync_i210(struct e1000_hw *hw, u16 mask);
s32 igb_valid_led_default_i210(struct e1000_hw *hw, u16 *data);
s32 igb_read_invm_version(struct e1000_hw *hw,
struct e1000_fw_version *invm_ver);
s32 igb_read_xmdio_reg(struct e1000_hw *hw, u16 addr, u8 dev_addr, u16 *data);
s32 igb_write_xmdio_reg(struct e1000_hw *hw, u16 addr, u8 dev_addr, u16 data);
s32 igb_init_nvm_params_i210(struct e1000_hw *hw);
bool igb_get_flash_presence_i210(struct e1000_hw *hw);
s32 igb_pll_workaround_i210(struct e1000_hw *hw);
s32 igb_get_cfg_done_i210(struct e1000_hw *hw);
#define E1000_STM_OPCODE 0xDB00
#define E1000_EEPROM_FLASH_SIZE_WORD 0x11
#define INVM_DWORD_TO_RECORD_TYPE(invm_dword) \
(u8)((invm_dword) & 0x7)
#define INVM_DWORD_TO_WORD_ADDRESS(invm_dword) \
(u8)(((invm_dword) & 0x0000FE00) >> 9)
#define INVM_DWORD_TO_WORD_DATA(invm_dword) \
(u16)(((invm_dword) & 0xFFFF0000) >> 16)
enum E1000_INVM_STRUCTURE_TYPE {
E1000_INVM_UNINITIALIZED_STRUCTURE = 0x00,
E1000_INVM_WORD_AUTOLOAD_STRUCTURE = 0x01,
E1000_INVM_CSR_AUTOLOAD_STRUCTURE = 0x02,
E1000_INVM_PHY_REGISTER_AUTOLOAD_STRUCTURE = 0x03,
E1000_INVM_RSA_KEY_SHA256_STRUCTURE = 0x04,
E1000_INVM_INVALIDATED_STRUCTURE = 0x0F,
};
#define E1000_INVM_RSA_KEY_SHA256_DATA_SIZE_IN_DWORDS 8
#define E1000_INVM_CSR_AUTOLOAD_DATA_SIZE_IN_DWORDS 1
#define E1000_INVM_ULT_BYTES_SIZE 8
#define E1000_INVM_RECORD_SIZE_IN_BYTES 4
#define E1000_INVM_VER_FIELD_ONE 0x1FF8
#define E1000_INVM_VER_FIELD_TWO 0x7FE000
#define E1000_INVM_IMGTYPE_FIELD 0x1F800000
#define E1000_INVM_MAJOR_MASK 0x3F0
#define E1000_INVM_MINOR_MASK 0xF
#define E1000_INVM_MAJOR_SHIFT 4
#define ID_LED_DEFAULT_I210 ((ID_LED_OFF1_ON2 << 8) | \
(ID_LED_DEF1_DEF2 << 4) | \
(ID_LED_OFF1_OFF2))
#define ID_LED_DEFAULT_I210_SERDES ((ID_LED_DEF1_DEF2 << 8) | \
(ID_LED_DEF1_DEF2 << 4) | \
(ID_LED_OFF1_ON2))
/* NVM offset defaults for i211 device */
#define NVM_INIT_CTRL_2_DEFAULT_I211 0X7243
#define NVM_INIT_CTRL_4_DEFAULT_I211 0x00C1
#define NVM_LED_1_CFG_DEFAULT_I211 0x0184
#define NVM_LED_0_2_CFG_DEFAULT_I211 0x200C
/* PLL Defines */
#define E1000_PCI_PMCSR 0x44
#define E1000_PCI_PMCSR_D3 0x03
#define E1000_MAX_PLL_TRIES 5
#define E1000_PHY_PLL_UNCONF 0xFF
#define E1000_PHY_PLL_FREQ_PAGE 0xFC
#define E1000_PHY_PLL_FREQ_REG 0x000E
#define E1000_INVM_DEFAULT_AL 0x202F
#define E1000_INVM_AUTOLOAD 0x0A
#define E1000_INVM_PLL_WO_VAL 0x0010
#endif

View File

@ -0,0 +1,911 @@
// SPDX-License-Identifier: GPL-2.0
/* Copyright(c) 2007 - 2018 Intel Corporation. */
/* e1000_i210
* e1000_i211
*/
#include <linux/types.h>
#include <linux/if_ether.h>
#include "e1000_hw.h"
#include "e1000_i210.h"
static s32 igb_update_flash_i210(struct e1000_hw *hw);
/**
* igb_get_hw_semaphore_i210 - Acquire hardware semaphore
* @hw: pointer to the HW structure
*
* Acquire the HW semaphore to access the PHY or NVM
*/
static s32 igb_get_hw_semaphore_i210(struct e1000_hw *hw)
{
u32 swsm;
s32 timeout = hw->nvm.word_size + 1;
s32 i = 0;
/* Get the SW semaphore */
while (i < timeout) {
swsm = rd32(E1000_SWSM);
if (!(swsm & E1000_SWSM_SMBI))
break;
udelay(50);
i++;
}
if (i == timeout) {
/* In rare circumstances, the SW semaphore may already be held
* unintentionally. Clear the semaphore once before giving up.
*/
if (hw->dev_spec._82575.clear_semaphore_once) {
hw->dev_spec._82575.clear_semaphore_once = false;
igb_put_hw_semaphore(hw);
for (i = 0; i < timeout; i++) {
swsm = rd32(E1000_SWSM);
if (!(swsm & E1000_SWSM_SMBI))
break;
udelay(50);
}
}
/* If we do not have the semaphore here, we have to give up. */
if (i == timeout) {
hw_dbg("Driver can't access device - SMBI bit is set.\n");
return -E1000_ERR_NVM;
}
}
/* Get the FW semaphore. */
for (i = 0; i < timeout; i++) {
swsm = rd32(E1000_SWSM);
wr32(E1000_SWSM, swsm | E1000_SWSM_SWESMBI);
/* Semaphore acquired if bit latched */
if (rd32(E1000_SWSM) & E1000_SWSM_SWESMBI)
break;
udelay(50);
}
if (i == timeout) {
/* Release semaphores */
igb_put_hw_semaphore(hw);
hw_dbg("Driver can't access the NVM\n");
return -E1000_ERR_NVM;
}
return 0;
}
/**
* igb_acquire_nvm_i210 - Request for access to EEPROM
* @hw: pointer to the HW structure
*
* Acquire the necessary semaphores for exclusive access to the EEPROM.
* Set the EEPROM access request bit and wait for EEPROM access grant bit.
* Return successful if access grant bit set, else clear the request for
* EEPROM access and return -E1000_ERR_NVM (-1).
**/
static s32 igb_acquire_nvm_i210(struct e1000_hw *hw)
{
return igb_acquire_swfw_sync_i210(hw, E1000_SWFW_EEP_SM);
}
/**
* igb_release_nvm_i210 - Release exclusive access to EEPROM
* @hw: pointer to the HW structure
*
* Stop any current commands to the EEPROM and clear the EEPROM request bit,
* then release the semaphores acquired.
**/
static void igb_release_nvm_i210(struct e1000_hw *hw)
{
igb_release_swfw_sync_i210(hw, E1000_SWFW_EEP_SM);
}
/**
* igb_acquire_swfw_sync_i210 - Acquire SW/FW semaphore
* @hw: pointer to the HW structure
* @mask: specifies which semaphore to acquire
*
* Acquire the SW/FW semaphore to access the PHY or NVM. The mask
* will also specify which port we're acquiring the lock for.
**/
s32 igb_acquire_swfw_sync_i210(struct e1000_hw *hw, u16 mask)
{
u32 swfw_sync;
u32 swmask = mask;
u32 fwmask = mask << 16;
s32 ret_val = 0;
s32 i = 0, timeout = 200; /* FIXME: find real value to use here */
while (i < timeout) {
if (igb_get_hw_semaphore_i210(hw)) {
ret_val = -E1000_ERR_SWFW_SYNC;
goto out;
}
swfw_sync = rd32(E1000_SW_FW_SYNC);
if (!(swfw_sync & (fwmask | swmask)))
break;
/* Firmware currently using resource (fwmask) */
igb_put_hw_semaphore(hw);
mdelay(5);
i++;
}
if (i == timeout) {
hw_dbg("Driver can't access resource, SW_FW_SYNC timeout.\n");
ret_val = -E1000_ERR_SWFW_SYNC;
goto out;
}
swfw_sync |= swmask;
wr32(E1000_SW_FW_SYNC, swfw_sync);
igb_put_hw_semaphore(hw);
out:
return ret_val;
}
/**
* igb_release_swfw_sync_i210 - Release SW/FW semaphore
* @hw: pointer to the HW structure
* @mask: specifies which semaphore to acquire
*
* Release the SW/FW semaphore used to access the PHY or NVM. The mask
* will also specify which port we're releasing the lock for.
**/
void igb_release_swfw_sync_i210(struct e1000_hw *hw, u16 mask)
{
u32 swfw_sync;
while (igb_get_hw_semaphore_i210(hw))
; /* Empty */
swfw_sync = rd32(E1000_SW_FW_SYNC);
swfw_sync &= ~mask;
wr32(E1000_SW_FW_SYNC, swfw_sync);
igb_put_hw_semaphore(hw);
}
/**
* igb_read_nvm_srrd_i210 - Reads Shadow Ram using EERD register
* @hw: pointer to the HW structure
* @offset: offset of word in the Shadow Ram to read
* @words: number of words to read
* @data: word read from the Shadow Ram
*
* Reads a 16 bit word from the Shadow Ram using the EERD register.
* Uses necessary synchronization semaphores.
**/
static s32 igb_read_nvm_srrd_i210(struct e1000_hw *hw, u16 offset, u16 words,
u16 *data)
{
s32 status = 0;
u16 i, count;
/* We cannot hold synchronization semaphores for too long,
* because of forceful takeover procedure. However it is more efficient
* to read in bursts than synchronizing access for each word.
*/
for (i = 0; i < words; i += E1000_EERD_EEWR_MAX_COUNT) {
count = (words - i) / E1000_EERD_EEWR_MAX_COUNT > 0 ?
E1000_EERD_EEWR_MAX_COUNT : (words - i);
if (!(hw->nvm.ops.acquire(hw))) {
status = igb_read_nvm_eerd(hw, offset, count,
data + i);
hw->nvm.ops.release(hw);
} else {
status = E1000_ERR_SWFW_SYNC;
}
if (status)
break;
}
return status;
}
/**
* igb_write_nvm_srwr - Write to Shadow Ram using EEWR
* @hw: pointer to the HW structure
* @offset: offset within the Shadow Ram to be written to
* @words: number of words to write
* @data: 16 bit word(s) to be written to the Shadow Ram
*
* Writes data to Shadow Ram at offset using EEWR register.
*
* If igb_update_nvm_checksum is not called after this function , the
* Shadow Ram will most likely contain an invalid checksum.
**/
static s32 igb_write_nvm_srwr(struct e1000_hw *hw, u16 offset, u16 words,
u16 *data)
{
struct e1000_nvm_info *nvm = &hw->nvm;
u32 i, k, eewr = 0;
u32 attempts = 100000;
s32 ret_val = 0;
/* A check for invalid values: offset too large, too many words,
* too many words for the offset, and not enough words.
*/
if ((offset >= nvm->word_size) || (words > (nvm->word_size - offset)) ||
(words == 0)) {
hw_dbg("nvm parameter(s) out of bounds\n");
ret_val = -E1000_ERR_NVM;
goto out;
}
for (i = 0; i < words; i++) {
eewr = ((offset+i) << E1000_NVM_RW_ADDR_SHIFT) |
(data[i] << E1000_NVM_RW_REG_DATA) |
E1000_NVM_RW_REG_START;
wr32(E1000_SRWR, eewr);
for (k = 0; k < attempts; k++) {
if (E1000_NVM_RW_REG_DONE &
rd32(E1000_SRWR)) {
ret_val = 0;
break;
}
udelay(5);
}
if (ret_val) {
hw_dbg("Shadow RAM write EEWR timed out\n");
break;
}
}
out:
return ret_val;
}
/**
* igb_write_nvm_srwr_i210 - Write to Shadow RAM using EEWR
* @hw: pointer to the HW structure
* @offset: offset within the Shadow RAM to be written to
* @words: number of words to write
* @data: 16 bit word(s) to be written to the Shadow RAM
*
* Writes data to Shadow RAM at offset using EEWR register.
*
* If e1000_update_nvm_checksum is not called after this function , the
* data will not be committed to FLASH and also Shadow RAM will most likely
* contain an invalid checksum.
*
* If error code is returned, data and Shadow RAM may be inconsistent - buffer
* partially written.
**/
static s32 igb_write_nvm_srwr_i210(struct e1000_hw *hw, u16 offset, u16 words,
u16 *data)
{
s32 status = 0;
u16 i, count;
/* We cannot hold synchronization semaphores for too long,
* because of forceful takeover procedure. However it is more efficient
* to write in bursts than synchronizing access for each word.
*/
for (i = 0; i < words; i += E1000_EERD_EEWR_MAX_COUNT) {
count = (words - i) / E1000_EERD_EEWR_MAX_COUNT > 0 ?
E1000_EERD_EEWR_MAX_COUNT : (words - i);
if (!(hw->nvm.ops.acquire(hw))) {
status = igb_write_nvm_srwr(hw, offset, count,
data + i);
hw->nvm.ops.release(hw);
} else {
status = E1000_ERR_SWFW_SYNC;
}
if (status)
break;
}
return status;
}
/**
* igb_read_invm_word_i210 - Reads OTP
* @hw: pointer to the HW structure
* @address: the word address (aka eeprom offset) to read
* @data: pointer to the data read
*
* Reads 16-bit words from the OTP. Return error when the word is not
* stored in OTP.
**/
static s32 igb_read_invm_word_i210(struct e1000_hw *hw, u8 address, u16 *data)
{
s32 status = -E1000_ERR_INVM_VALUE_NOT_FOUND;
u32 invm_dword;
u16 i;
u8 record_type, word_address;
for (i = 0; i < E1000_INVM_SIZE; i++) {
invm_dword = rd32(E1000_INVM_DATA_REG(i));
/* Get record type */
record_type = INVM_DWORD_TO_RECORD_TYPE(invm_dword);
if (record_type == E1000_INVM_UNINITIALIZED_STRUCTURE)
break;
if (record_type == E1000_INVM_CSR_AUTOLOAD_STRUCTURE)
i += E1000_INVM_CSR_AUTOLOAD_DATA_SIZE_IN_DWORDS;
if (record_type == E1000_INVM_RSA_KEY_SHA256_STRUCTURE)
i += E1000_INVM_RSA_KEY_SHA256_DATA_SIZE_IN_DWORDS;
if (record_type == E1000_INVM_WORD_AUTOLOAD_STRUCTURE) {
word_address = INVM_DWORD_TO_WORD_ADDRESS(invm_dword);
if (word_address == address) {
*data = INVM_DWORD_TO_WORD_DATA(invm_dword);
hw_dbg("Read INVM Word 0x%02x = %x\n",
address, *data);
status = 0;
break;
}
}
}
if (status)
hw_dbg("Requested word 0x%02x not found in OTP\n", address);
return status;
}
/**
* igb_read_invm_i210 - Read invm wrapper function for I210/I211
* @hw: pointer to the HW structure
* @offset: offset to read from
* @words: number of words to read (unused)
* @data: pointer to the data read
*
* Wrapper function to return data formerly found in the NVM.
**/
static s32 igb_read_invm_i210(struct e1000_hw *hw, u16 offset,
u16 __always_unused words, u16 *data)
{
s32 ret_val = 0;
/* 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;
case NVM_INIT_CTRL_2:
ret_val = igb_read_invm_word_i210(hw, (u8)offset, data);
if (ret_val) {
*data = NVM_INIT_CTRL_2_DEFAULT_I211;
ret_val = 0;
}
break;
case NVM_INIT_CTRL_4:
ret_val = igb_read_invm_word_i210(hw, (u8)offset, data);
if (ret_val) {
*data = NVM_INIT_CTRL_4_DEFAULT_I211;
ret_val = 0;
}
break;
case NVM_LED_1_CFG:
ret_val = igb_read_invm_word_i210(hw, (u8)offset, data);
if (ret_val) {
*data = NVM_LED_1_CFG_DEFAULT_I211;
ret_val = 0;
}
break;
case NVM_LED_0_2_CFG:
ret_val = igb_read_invm_word_i210(hw, (u8)offset, data);
if (ret_val) {
*data = NVM_LED_0_2_CFG_DEFAULT_I211;
ret_val = 0;
}
break;
case NVM_ID_LED_SETTINGS:
ret_val = igb_read_invm_word_i210(hw, (u8)offset, data);
if (ret_val) {
*data = ID_LED_RESERVED_FFFF;
ret_val = 0;
}
break;
case NVM_SUB_DEV_ID:
*data = hw->subsystem_device_id;
break;
case NVM_SUB_VEN_ID:
*data = hw->subsystem_vendor_id;
break;
case NVM_DEV_ID:
*data = hw->device_id;
break;
case NVM_VEN_ID:
*data = hw->vendor_id;
break;
default:
hw_dbg("NVM word 0x%02x is not mapped.\n", offset);
*data = NVM_RESERVED_WORD;
break;
}
return ret_val;
}
/**
* igb_read_invm_version - Reads iNVM version and image type
* @hw: pointer to the HW structure
* @invm_ver: version structure for the version read
*
* Reads iNVM version and image type.
**/
s32 igb_read_invm_version(struct e1000_hw *hw,
struct e1000_fw_version *invm_ver) {
u32 *record = NULL;
u32 *next_record = NULL;
u32 i = 0;
u32 invm_dword = 0;
u32 invm_blocks = E1000_INVM_SIZE - (E1000_INVM_ULT_BYTES_SIZE /
E1000_INVM_RECORD_SIZE_IN_BYTES);
u32 buffer[E1000_INVM_SIZE];
s32 status = -E1000_ERR_INVM_VALUE_NOT_FOUND;
u16 version = 0;
/* Read iNVM memory */
for (i = 0; i < E1000_INVM_SIZE; i++) {
invm_dword = rd32(E1000_INVM_DATA_REG(i));
buffer[i] = invm_dword;
}
/* Read version number */
for (i = 1; i < invm_blocks; i++) {
record = &buffer[invm_blocks - i];
next_record = &buffer[invm_blocks - i + 1];
/* Check if we have first version location used */
if ((i == 1) && ((*record & E1000_INVM_VER_FIELD_ONE) == 0)) {
version = 0;
status = 0;
break;
}
/* Check if we have second version location used */
else if ((i == 1) &&
((*record & E1000_INVM_VER_FIELD_TWO) == 0)) {
version = (*record & E1000_INVM_VER_FIELD_ONE) >> 3;
status = 0;
break;
}
/* Check if we have odd version location
* used and it is the last one used
*/
else if ((((*record & E1000_INVM_VER_FIELD_ONE) == 0) &&
((*record & 0x3) == 0)) || (((*record & 0x3) != 0) &&
(i != 1))) {
version = (*next_record & E1000_INVM_VER_FIELD_TWO)
>> 13;
status = 0;
break;
}
/* Check if we have even version location
* used and it is the last one used
*/
else if (((*record & E1000_INVM_VER_FIELD_TWO) == 0) &&
((*record & 0x3) == 0)) {
version = (*record & E1000_INVM_VER_FIELD_ONE) >> 3;
status = 0;
break;
}
}
if (!status) {
invm_ver->invm_major = (version & E1000_INVM_MAJOR_MASK)
>> E1000_INVM_MAJOR_SHIFT;
invm_ver->invm_minor = version & E1000_INVM_MINOR_MASK;
}
/* Read Image Type */
for (i = 1; i < invm_blocks; i++) {
record = &buffer[invm_blocks - i];
next_record = &buffer[invm_blocks - i + 1];
/* Check if we have image type in first location used */
if ((i == 1) && ((*record & E1000_INVM_IMGTYPE_FIELD) == 0)) {
invm_ver->invm_img_type = 0;
status = 0;
break;
}
/* Check if we have image type in first location used */
else if ((((*record & 0x3) == 0) &&
((*record & E1000_INVM_IMGTYPE_FIELD) == 0)) ||
((((*record & 0x3) != 0) && (i != 1)))) {
invm_ver->invm_img_type =
(*next_record & E1000_INVM_IMGTYPE_FIELD) >> 23;
status = 0;
break;
}
}
return status;
}
/**
* igb_validate_nvm_checksum_i210 - Validate EEPROM checksum
* @hw: pointer to the HW structure
*
* Calculates the EEPROM checksum by reading/adding each word of the EEPROM
* and then verifies that the sum of the EEPROM is equal to 0xBABA.
**/
static s32 igb_validate_nvm_checksum_i210(struct e1000_hw *hw)
{
s32 status = 0;
s32 (*read_op_ptr)(struct e1000_hw *, u16, u16, u16 *);
if (!(hw->nvm.ops.acquire(hw))) {
/* Replace the read function with semaphore grabbing with
* the one that skips this for a while.
* We have semaphore taken already here.
*/
read_op_ptr = hw->nvm.ops.read;
hw->nvm.ops.read = igb_read_nvm_eerd;
status = igb_validate_nvm_checksum(hw);
/* Revert original read operation. */
hw->nvm.ops.read = read_op_ptr;
hw->nvm.ops.release(hw);
} else {
status = E1000_ERR_SWFW_SYNC;
}
return status;
}
/**
* igb_update_nvm_checksum_i210 - Update EEPROM checksum
* @hw: pointer to the HW structure
*
* Updates the EEPROM checksum by reading/adding each word of the EEPROM
* up to the checksum. Then calculates the EEPROM checksum and writes the
* value to the EEPROM. Next commit EEPROM data onto the Flash.
**/
static s32 igb_update_nvm_checksum_i210(struct e1000_hw *hw)
{
s32 ret_val = 0;
u16 checksum = 0;
u16 i, nvm_data;
/* Read the first word from the EEPROM. If this times out or fails, do
* not continue or we could be in for a very long wait while every
* EEPROM read fails
*/
ret_val = igb_read_nvm_eerd(hw, 0, 1, &nvm_data);
if (ret_val) {
hw_dbg("EEPROM read failed\n");
goto out;
}
if (!(hw->nvm.ops.acquire(hw))) {
/* Do not use hw->nvm.ops.write, hw->nvm.ops.read
* because we do not want to take the synchronization
* semaphores twice here.
*/
for (i = 0; i < NVM_CHECKSUM_REG; i++) {
ret_val = igb_read_nvm_eerd(hw, i, 1, &nvm_data);
if (ret_val) {
hw->nvm.ops.release(hw);
hw_dbg("NVM Read Error while updating checksum.\n");
goto out;
}
checksum += nvm_data;
}
checksum = (u16) NVM_SUM - checksum;
ret_val = igb_write_nvm_srwr(hw, NVM_CHECKSUM_REG, 1,
&checksum);
if (ret_val) {
hw->nvm.ops.release(hw);
hw_dbg("NVM Write Error while updating checksum.\n");
goto out;
}
hw->nvm.ops.release(hw);
ret_val = igb_update_flash_i210(hw);
} else {
ret_val = -E1000_ERR_SWFW_SYNC;
}
out:
return ret_val;
}
/**
* igb_pool_flash_update_done_i210 - Pool FLUDONE status.
* @hw: pointer to the HW structure
*
**/
static s32 igb_pool_flash_update_done_i210(struct e1000_hw *hw)
{
s32 ret_val = -E1000_ERR_NVM;
u32 i, reg;
for (i = 0; i < E1000_FLUDONE_ATTEMPTS; i++) {
reg = rd32(E1000_EECD);
if (reg & E1000_EECD_FLUDONE_I210) {
ret_val = 0;
break;
}
udelay(5);
}
return ret_val;
}
/**
* 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;
}
/**
* igb_update_flash_i210 - Commit EEPROM to the flash
* @hw: pointer to the HW structure
*
**/
static s32 igb_update_flash_i210(struct e1000_hw *hw)
{
s32 ret_val = 0;
u32 flup;
ret_val = igb_pool_flash_update_done_i210(hw);
if (ret_val == -E1000_ERR_NVM) {
hw_dbg("Flash update time out\n");
goto out;
}
flup = rd32(E1000_EECD) | E1000_EECD_FLUPD_I210;
wr32(E1000_EECD, flup);
ret_val = igb_pool_flash_update_done_i210(hw);
if (ret_val)
hw_dbg("Flash update time out\n");
else
hw_dbg("Flash update complete\n");
out:
return ret_val;
}
/**
* igb_valid_led_default_i210 - Verify a valid default LED config
* @hw: pointer to the HW structure
* @data: pointer to the NVM (EEPROM)
*
* Read the EEPROM for the current default LED configuration. If the
* LED configuration is not valid, set to a valid LED configuration.
**/
s32 igb_valid_led_default_i210(struct e1000_hw *hw, u16 *data)
{
s32 ret_val;
ret_val = hw->nvm.ops.read(hw, NVM_ID_LED_SETTINGS, 1, data);
if (ret_val) {
hw_dbg("NVM Read Error\n");
goto out;
}
if (*data == ID_LED_RESERVED_0000 || *data == ID_LED_RESERVED_FFFF) {
switch (hw->phy.media_type) {
case e1000_media_type_internal_serdes:
*data = ID_LED_DEFAULT_I210_SERDES;
break;
case e1000_media_type_copper:
default:
*data = ID_LED_DEFAULT_I210;
break;
}
}
out:
return ret_val;
}
/**
* __igb_access_xmdio_reg - Read/write XMDIO register
* @hw: pointer to the HW structure
* @address: XMDIO address to program
* @dev_addr: device address to program
* @data: pointer to value to read/write from/to the XMDIO address
* @read: boolean flag to indicate read or write
**/
static s32 __igb_access_xmdio_reg(struct e1000_hw *hw, u16 address,
u8 dev_addr, u16 *data, bool read)
{
s32 ret_val = 0;
ret_val = hw->phy.ops.write_reg(hw, E1000_MMDAC, dev_addr);
if (ret_val)
return ret_val;
ret_val = hw->phy.ops.write_reg(hw, E1000_MMDAAD, address);
if (ret_val)
return ret_val;
ret_val = hw->phy.ops.write_reg(hw, E1000_MMDAC, E1000_MMDAC_FUNC_DATA |
dev_addr);
if (ret_val)
return ret_val;
if (read)
ret_val = hw->phy.ops.read_reg(hw, E1000_MMDAAD, data);
else
ret_val = hw->phy.ops.write_reg(hw, E1000_MMDAAD, *data);
if (ret_val)
return ret_val;
/* Recalibrate the device back to 0 */
ret_val = hw->phy.ops.write_reg(hw, E1000_MMDAC, 0);
if (ret_val)
return ret_val;
return ret_val;
}
/**
* igb_read_xmdio_reg - Read XMDIO register
* @hw: pointer to the HW structure
* @addr: XMDIO address to program
* @dev_addr: device address to program
* @data: value to be read from the EMI address
**/
s32 igb_read_xmdio_reg(struct e1000_hw *hw, u16 addr, u8 dev_addr, u16 *data)
{
return __igb_access_xmdio_reg(hw, addr, dev_addr, data, true);
}
/**
* igb_write_xmdio_reg - Write XMDIO register
* @hw: pointer to the HW structure
* @addr: XMDIO address to program
* @dev_addr: device address to program
* @data: value to be written to the XMDIO address
**/
s32 igb_write_xmdio_reg(struct e1000_hw *hw, u16 addr, u8 dev_addr, u16 data)
{
return __igb_access_xmdio_reg(hw, addr, dev_addr, &data, false);
}
/**
* igb_init_nvm_params_i210 - Init NVM func ptrs.
* @hw: pointer to the HW structure
**/
s32 igb_init_nvm_params_i210(struct e1000_hw *hw)
{
struct e1000_nvm_info *nvm = &hw->nvm;
nvm->ops.acquire = igb_acquire_nvm_i210;
nvm->ops.release = igb_release_nvm_i210;
nvm->ops.valid_led_default = igb_valid_led_default_i210;
/* NVM Function Pointers */
if (igb_get_flash_presence_i210(hw)) {
hw->nvm.type = e1000_nvm_flash_hw;
nvm->ops.read = igb_read_nvm_srrd_i210;
nvm->ops.write = igb_write_nvm_srwr_i210;
nvm->ops.validate = igb_validate_nvm_checksum_i210;
nvm->ops.update = igb_update_nvm_checksum_i210;
} else {
hw->nvm.type = e1000_nvm_invm;
nvm->ops.read = igb_read_invm_i210;
nvm->ops.write = NULL;
nvm->ops.validate = NULL;
nvm->ops.update = NULL;
}
return 0;
}
/**
* igb_pll_workaround_i210
* @hw: pointer to the HW structure
*
* Works around an errata in the PLL circuit where it occasionally
* provides the wrong clock frequency after power up.
**/
s32 igb_pll_workaround_i210(struct e1000_hw *hw)
{
s32 ret_val;
u32 wuc, mdicnfg, ctrl, ctrl_ext, reg_val;
u16 nvm_word, phy_word, pci_word, tmp_nvm;
int i;
/* Get and set needed register values */
wuc = rd32(E1000_WUC);
mdicnfg = rd32(E1000_MDICNFG);
reg_val = mdicnfg & ~E1000_MDICNFG_EXT_MDIO;
wr32(E1000_MDICNFG, reg_val);
/* Get data from NVM, or set default */
ret_val = igb_read_invm_word_i210(hw, E1000_INVM_AUTOLOAD,
&nvm_word);
if (ret_val)
nvm_word = E1000_INVM_DEFAULT_AL;
tmp_nvm = nvm_word | E1000_INVM_PLL_WO_VAL;
igb_write_phy_reg_82580(hw, I347AT4_PAGE_SELECT, E1000_PHY_PLL_FREQ_PAGE);
phy_word = E1000_PHY_PLL_UNCONF;
for (i = 0; i < E1000_MAX_PLL_TRIES; i++) {
/* check current state directly from internal PHY */
igb_read_phy_reg_82580(hw, E1000_PHY_PLL_FREQ_REG, &phy_word);
if ((phy_word & E1000_PHY_PLL_UNCONF)
!= E1000_PHY_PLL_UNCONF) {
ret_val = 0;
break;
} else {
ret_val = -E1000_ERR_PHY;
}
/* directly reset the internal PHY */
ctrl = rd32(E1000_CTRL);
wr32(E1000_CTRL, ctrl|E1000_CTRL_PHY_RST);
ctrl_ext = rd32(E1000_CTRL_EXT);
ctrl_ext |= (E1000_CTRL_EXT_PHYPDEN | E1000_CTRL_EXT_SDLPE);
wr32(E1000_CTRL_EXT, ctrl_ext);
wr32(E1000_WUC, 0);
reg_val = (E1000_INVM_AUTOLOAD << 4) | (tmp_nvm << 16);
wr32(E1000_EEARBC_I210, reg_val);
igb_read_pci_cfg(hw, E1000_PCI_PMCSR, &pci_word);
pci_word |= E1000_PCI_PMCSR_D3;
igb_write_pci_cfg(hw, E1000_PCI_PMCSR, &pci_word);
usleep_range(1000, 2000);
pci_word &= ~E1000_PCI_PMCSR_D3;
igb_write_pci_cfg(hw, E1000_PCI_PMCSR, &pci_word);
reg_val = (E1000_INVM_AUTOLOAD << 4) | (nvm_word << 16);
wr32(E1000_EEARBC_I210, reg_val);
/* restore WUC register */
wr32(E1000_WUC, wuc);
}
igb_write_phy_reg_82580(hw, I347AT4_PAGE_SELECT, 0);
/* restore MDICNFG setting */
wr32(E1000_MDICNFG, mdicnfg);
return ret_val;
}
/**
* igb_get_cfg_done_i210 - Read config done bit
* @hw: pointer to the HW structure
*
* Read the management control register for the config done bit for
* completion status. NOTE: silicon which is EEPROM-less will fail trying
* to read the config done bit, so an error is *ONLY* logged and returns
* 0. If we were to return with error, EEPROM-less silicon
* would not be able to be reset or change link.
**/
s32 igb_get_cfg_done_i210(struct e1000_hw *hw)
{
s32 timeout = PHY_CFG_TIMEOUT;
u32 mask = E1000_NVM_CFG_DONE_PORT_0;
while (timeout) {
if (rd32(E1000_EEMNGCTL_I210) & mask)
break;
usleep_range(1000, 2000);
timeout--;
}
if (!timeout)
hw_dbg("MNG configuration cycle has not completed.\n");
return 0;
}

View File

@ -0,0 +1,74 @@
/* SPDX-License-Identifier: GPL-2.0 */
/* Copyright(c) 2007 - 2018 Intel Corporation. */
#ifndef _E1000_I210_H_
#define _E1000_I210_H_
s32 igb_acquire_swfw_sync_i210(struct e1000_hw *hw, u16 mask);
void igb_release_swfw_sync_i210(struct e1000_hw *hw, u16 mask);
s32 igb_valid_led_default_i210(struct e1000_hw *hw, u16 *data);
s32 igb_read_invm_version(struct e1000_hw *hw,
struct e1000_fw_version *invm_ver);
s32 igb_read_xmdio_reg(struct e1000_hw *hw, u16 addr, u8 dev_addr, u16 *data);
s32 igb_write_xmdio_reg(struct e1000_hw *hw, u16 addr, u8 dev_addr, u16 data);
s32 igb_init_nvm_params_i210(struct e1000_hw *hw);
bool igb_get_flash_presence_i210(struct e1000_hw *hw);
s32 igb_pll_workaround_i210(struct e1000_hw *hw);
s32 igb_get_cfg_done_i210(struct e1000_hw *hw);
#define E1000_STM_OPCODE 0xDB00
#define E1000_EEPROM_FLASH_SIZE_WORD 0x11
#define INVM_DWORD_TO_RECORD_TYPE(invm_dword) \
(u8)((invm_dword) & 0x7)
#define INVM_DWORD_TO_WORD_ADDRESS(invm_dword) \
(u8)(((invm_dword) & 0x0000FE00) >> 9)
#define INVM_DWORD_TO_WORD_DATA(invm_dword) \
(u16)(((invm_dword) & 0xFFFF0000) >> 16)
enum E1000_INVM_STRUCTURE_TYPE {
E1000_INVM_UNINITIALIZED_STRUCTURE = 0x00,
E1000_INVM_WORD_AUTOLOAD_STRUCTURE = 0x01,
E1000_INVM_CSR_AUTOLOAD_STRUCTURE = 0x02,
E1000_INVM_PHY_REGISTER_AUTOLOAD_STRUCTURE = 0x03,
E1000_INVM_RSA_KEY_SHA256_STRUCTURE = 0x04,
E1000_INVM_INVALIDATED_STRUCTURE = 0x0F,
};
#define E1000_INVM_RSA_KEY_SHA256_DATA_SIZE_IN_DWORDS 8
#define E1000_INVM_CSR_AUTOLOAD_DATA_SIZE_IN_DWORDS 1
#define E1000_INVM_ULT_BYTES_SIZE 8
#define E1000_INVM_RECORD_SIZE_IN_BYTES 4
#define E1000_INVM_VER_FIELD_ONE 0x1FF8
#define E1000_INVM_VER_FIELD_TWO 0x7FE000
#define E1000_INVM_IMGTYPE_FIELD 0x1F800000
#define E1000_INVM_MAJOR_MASK 0x3F0
#define E1000_INVM_MINOR_MASK 0xF
#define E1000_INVM_MAJOR_SHIFT 4
#define ID_LED_DEFAULT_I210 ((ID_LED_OFF1_ON2 << 8) | \
(ID_LED_DEF1_DEF2 << 4) | \
(ID_LED_OFF1_OFF2))
#define ID_LED_DEFAULT_I210_SERDES ((ID_LED_DEF1_DEF2 << 8) | \
(ID_LED_DEF1_DEF2 << 4) | \
(ID_LED_OFF1_ON2))
/* NVM offset defaults for i211 device */
#define NVM_INIT_CTRL_2_DEFAULT_I211 0X7243
#define NVM_INIT_CTRL_4_DEFAULT_I211 0x00C1
#define NVM_LED_1_CFG_DEFAULT_I211 0x0184
#define NVM_LED_0_2_CFG_DEFAULT_I211 0x200C
/* PLL Defines */
#define E1000_PCI_PMCSR 0x44
#define E1000_PCI_PMCSR_D3 0x03
#define E1000_MAX_PLL_TRIES 5
#define E1000_PHY_PLL_UNCONF 0xFF
#define E1000_PHY_PLL_FREQ_PAGE 0xFC
#define E1000_PHY_PLL_FREQ_REG 0x000E
#define E1000_INVM_DEFAULT_AL 0x202F
#define E1000_INVM_AUTOLOAD 0x0A
#define E1000_INVM_PLL_WO_VAL 0x0010
#endif

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,68 @@
/* SPDX-License-Identifier: GPL-2.0 */
/* Copyright(c) 2007 - 2018 Intel Corporation. */
#ifndef _E1000_MAC_H_
#define _E1000_MAC_H_
#include "e1000_hw-6.1-ethercat.h"
#include "e1000_phy-6.1-ethercat.h"
#include "e1000_nvm-6.1-ethercat.h"
#include "e1000_defines-6.1-ethercat.h"
#include "e1000_i210-6.1-ethercat.h"
/* Functions that should not be called directly from drivers but can be used
* by other files in this 'shared code'
*/
s32 igb_blink_led(struct e1000_hw *hw);
s32 igb_check_for_copper_link(struct e1000_hw *hw);
s32 igb_cleanup_led(struct e1000_hw *hw);
s32 igb_config_fc_after_link_up(struct e1000_hw *hw);
s32 igb_disable_pcie_master(struct e1000_hw *hw);
s32 igb_force_mac_fc(struct e1000_hw *hw);
s32 igb_get_auto_rd_done(struct e1000_hw *hw);
s32 igb_get_bus_info_pcie(struct e1000_hw *hw);
s32 igb_get_hw_semaphore(struct e1000_hw *hw);
s32 igb_get_speed_and_duplex_copper(struct e1000_hw *hw, u16 *speed,
u16 *duplex);
s32 igb_id_led_init(struct e1000_hw *hw);
s32 igb_led_off(struct e1000_hw *hw);
void igb_update_mc_addr_list(struct e1000_hw *hw,
u8 *mc_addr_list, u32 mc_addr_count);
s32 igb_setup_link(struct e1000_hw *hw);
s32 igb_validate_mdi_setting(struct e1000_hw *hw);
s32 igb_write_8bit_ctrl_reg(struct e1000_hw *hw, u32 reg,
u32 offset, u8 data);
void igb_clear_hw_cntrs_base(struct e1000_hw *hw);
void igb_clear_vfta(struct e1000_hw *hw);
void igb_write_vfta(struct e1000_hw *hw, u32 offset, u32 value);
s32 igb_vfta_set(struct e1000_hw *hw, u32 vid, u32 vind,
bool vlan_on, bool vlvf_bypass);
void igb_config_collision_dist(struct e1000_hw *hw);
void igb_init_rx_addrs(struct e1000_hw *hw, u16 rar_count);
void igb_mta_set(struct e1000_hw *hw, u32 hash_value);
void igb_put_hw_semaphore(struct e1000_hw *hw);
void igb_rar_set(struct e1000_hw *hw, u8 *addr, u32 index);
s32 igb_check_alt_mac_addr(struct e1000_hw *hw);
bool igb_enable_mng_pass_thru(struct e1000_hw *hw);
enum e1000_mng_mode {
e1000_mng_mode_none = 0,
e1000_mng_mode_asf,
e1000_mng_mode_pt,
e1000_mng_mode_ipmi,
e1000_mng_mode_host_if_only
};
#define E1000_FACTPS_MNGCG 0x20000000
#define E1000_FWSM_MODE_MASK 0xE
#define E1000_FWSM_MODE_SHIFT 1
#define E1000_MNG_DHCP_COOKIE_STATUS_VLAN 0x2
void e1000_init_function_pointers_82575(struct e1000_hw *hw);
#endif

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,68 @@
/* SPDX-License-Identifier: GPL-2.0 */
/* Copyright(c) 2007 - 2018 Intel Corporation. */
#ifndef _E1000_MAC_H_
#define _E1000_MAC_H_
#include "e1000_hw.h"
#include "e1000_phy.h"
#include "e1000_nvm.h"
#include "e1000_defines.h"
#include "e1000_i210.h"
/* Functions that should not be called directly from drivers but can be used
* by other files in this 'shared code'
*/
s32 igb_blink_led(struct e1000_hw *hw);
s32 igb_check_for_copper_link(struct e1000_hw *hw);
s32 igb_cleanup_led(struct e1000_hw *hw);
s32 igb_config_fc_after_link_up(struct e1000_hw *hw);
s32 igb_disable_pcie_master(struct e1000_hw *hw);
s32 igb_force_mac_fc(struct e1000_hw *hw);
s32 igb_get_auto_rd_done(struct e1000_hw *hw);
s32 igb_get_bus_info_pcie(struct e1000_hw *hw);
s32 igb_get_hw_semaphore(struct e1000_hw *hw);
s32 igb_get_speed_and_duplex_copper(struct e1000_hw *hw, u16 *speed,
u16 *duplex);
s32 igb_id_led_init(struct e1000_hw *hw);
s32 igb_led_off(struct e1000_hw *hw);
void igb_update_mc_addr_list(struct e1000_hw *hw,
u8 *mc_addr_list, u32 mc_addr_count);
s32 igb_setup_link(struct e1000_hw *hw);
s32 igb_validate_mdi_setting(struct e1000_hw *hw);
s32 igb_write_8bit_ctrl_reg(struct e1000_hw *hw, u32 reg,
u32 offset, u8 data);
void igb_clear_hw_cntrs_base(struct e1000_hw *hw);
void igb_clear_vfta(struct e1000_hw *hw);
void igb_write_vfta(struct e1000_hw *hw, u32 offset, u32 value);
s32 igb_vfta_set(struct e1000_hw *hw, u32 vid, u32 vind,
bool vlan_on, bool vlvf_bypass);
void igb_config_collision_dist(struct e1000_hw *hw);
void igb_init_rx_addrs(struct e1000_hw *hw, u16 rar_count);
void igb_mta_set(struct e1000_hw *hw, u32 hash_value);
void igb_put_hw_semaphore(struct e1000_hw *hw);
void igb_rar_set(struct e1000_hw *hw, u8 *addr, u32 index);
s32 igb_check_alt_mac_addr(struct e1000_hw *hw);
bool igb_enable_mng_pass_thru(struct e1000_hw *hw);
enum e1000_mng_mode {
e1000_mng_mode_none = 0,
e1000_mng_mode_asf,
e1000_mng_mode_pt,
e1000_mng_mode_ipmi,
e1000_mng_mode_host_if_only
};
#define E1000_FACTPS_MNGCG 0x20000000
#define E1000_FWSM_MODE_MASK 0xE
#define E1000_FWSM_MODE_SHIFT 1
#define E1000_MNG_DHCP_COOKIE_STATUS_VLAN 0x2
void e1000_init_function_pointers_82575(struct e1000_hw *hw);
#endif

View File

@ -0,0 +1,474 @@
// SPDX-License-Identifier: GPL-2.0
/* Copyright(c) 2007 - 2018 Intel Corporation. */
#include "e1000_mbx-6.1-ethercat.h"
/**
* igb_read_mbx - Reads a message from the mailbox
* @hw: pointer to the HW structure
* @msg: The message buffer
* @size: Length of buffer
* @mbx_id: id of mailbox to read
* @unlock: skip locking or not
*
* returns SUCCESS if it successfully read message from buffer
**/
s32 igb_read_mbx(struct e1000_hw *hw, u32 *msg, u16 size, u16 mbx_id,
bool unlock)
{
struct e1000_mbx_info *mbx = &hw->mbx;
s32 ret_val = -E1000_ERR_MBX;
/* limit read to size of mailbox */
if (size > mbx->size)
size = mbx->size;
if (mbx->ops.read)
ret_val = mbx->ops.read(hw, msg, size, mbx_id, unlock);
return ret_val;
}
/**
* igb_write_mbx - Write a message to the mailbox
* @hw: pointer to the HW structure
* @msg: The message buffer
* @size: Length of buffer
* @mbx_id: id of mailbox to write
*
* returns SUCCESS if it successfully copied message into the buffer
**/
s32 igb_write_mbx(struct e1000_hw *hw, u32 *msg, u16 size, u16 mbx_id)
{
struct e1000_mbx_info *mbx = &hw->mbx;
s32 ret_val = 0;
if (size > mbx->size)
ret_val = -E1000_ERR_MBX;
else if (mbx->ops.write)
ret_val = mbx->ops.write(hw, msg, size, mbx_id);
return ret_val;
}
/**
* igb_check_for_msg - checks to see if someone sent us mail
* @hw: pointer to the HW structure
* @mbx_id: id of mailbox to check
*
* returns SUCCESS if the Status bit was found or else ERR_MBX
**/
s32 igb_check_for_msg(struct e1000_hw *hw, u16 mbx_id)
{
struct e1000_mbx_info *mbx = &hw->mbx;
s32 ret_val = -E1000_ERR_MBX;
if (mbx->ops.check_for_msg)
ret_val = mbx->ops.check_for_msg(hw, mbx_id);
return ret_val;
}
/**
* igb_check_for_ack - checks to see if someone sent us ACK
* @hw: pointer to the HW structure
* @mbx_id: id of mailbox to check
*
* returns SUCCESS if the Status bit was found or else ERR_MBX
**/
s32 igb_check_for_ack(struct e1000_hw *hw, u16 mbx_id)
{
struct e1000_mbx_info *mbx = &hw->mbx;
s32 ret_val = -E1000_ERR_MBX;
if (mbx->ops.check_for_ack)
ret_val = mbx->ops.check_for_ack(hw, mbx_id);
return ret_val;
}
/**
* igb_check_for_rst - checks to see if other side has reset
* @hw: pointer to the HW structure
* @mbx_id: id of mailbox to check
*
* returns SUCCESS if the Status bit was found or else ERR_MBX
**/
s32 igb_check_for_rst(struct e1000_hw *hw, u16 mbx_id)
{
struct e1000_mbx_info *mbx = &hw->mbx;
s32 ret_val = -E1000_ERR_MBX;
if (mbx->ops.check_for_rst)
ret_val = mbx->ops.check_for_rst(hw, mbx_id);
return ret_val;
}
/**
* igb_unlock_mbx - unlock the mailbox
* @hw: pointer to the HW structure
* @mbx_id: id of mailbox to check
*
* returns SUCCESS if the mailbox was unlocked or else ERR_MBX
**/
s32 igb_unlock_mbx(struct e1000_hw *hw, u16 mbx_id)
{
struct e1000_mbx_info *mbx = &hw->mbx;
s32 ret_val = -E1000_ERR_MBX;
if (mbx->ops.unlock)
ret_val = mbx->ops.unlock(hw, mbx_id);
return ret_val;
}
/**
* igb_poll_for_msg - Wait for message notification
* @hw: pointer to the HW structure
* @mbx_id: id of mailbox to write
*
* returns SUCCESS if it successfully received a message notification
**/
static s32 igb_poll_for_msg(struct e1000_hw *hw, u16 mbx_id)
{
struct e1000_mbx_info *mbx = &hw->mbx;
int countdown = mbx->timeout;
if (!countdown || !mbx->ops.check_for_msg)
goto out;
while (countdown && mbx->ops.check_for_msg(hw, mbx_id)) {
countdown--;
if (!countdown)
break;
udelay(mbx->usec_delay);
}
/* if we failed, all future posted messages fail until reset */
if (!countdown)
mbx->timeout = 0;
out:
return countdown ? 0 : -E1000_ERR_MBX;
}
/**
* igb_poll_for_ack - Wait for message acknowledgement
* @hw: pointer to the HW structure
* @mbx_id: id of mailbox to write
*
* returns SUCCESS if it successfully received a message acknowledgement
**/
static s32 igb_poll_for_ack(struct e1000_hw *hw, u16 mbx_id)
{
struct e1000_mbx_info *mbx = &hw->mbx;
int countdown = mbx->timeout;
if (!countdown || !mbx->ops.check_for_ack)
goto out;
while (countdown && mbx->ops.check_for_ack(hw, mbx_id)) {
countdown--;
if (!countdown)
break;
udelay(mbx->usec_delay);
}
/* if we failed, all future posted messages fail until reset */
if (!countdown)
mbx->timeout = 0;
out:
return countdown ? 0 : -E1000_ERR_MBX;
}
/**
* igb_read_posted_mbx - Wait for message notification and receive message
* @hw: pointer to the HW structure
* @msg: The message buffer
* @size: Length of buffer
* @mbx_id: id of mailbox to write
*
* returns SUCCESS if it successfully received a message notification and
* copied it into the receive buffer.
**/
static s32 igb_read_posted_mbx(struct e1000_hw *hw, u32 *msg, u16 size,
u16 mbx_id)
{
struct e1000_mbx_info *mbx = &hw->mbx;
s32 ret_val = -E1000_ERR_MBX;
if (!mbx->ops.read)
goto out;
ret_val = igb_poll_for_msg(hw, mbx_id);
if (!ret_val)
ret_val = mbx->ops.read(hw, msg, size, mbx_id, true);
out:
return ret_val;
}
/**
* igb_write_posted_mbx - Write a message to the mailbox, wait for ack
* @hw: pointer to the HW structure
* @msg: The message buffer
* @size: Length of buffer
* @mbx_id: id of mailbox to write
*
* returns SUCCESS if it successfully copied message into the buffer and
* received an ack to that message within delay * timeout period
**/
static s32 igb_write_posted_mbx(struct e1000_hw *hw, u32 *msg, u16 size,
u16 mbx_id)
{
struct e1000_mbx_info *mbx = &hw->mbx;
s32 ret_val = -E1000_ERR_MBX;
/* exit if either we can't write or there isn't a defined timeout */
if (!mbx->ops.write || !mbx->timeout)
goto out;
/* send msg */
ret_val = mbx->ops.write(hw, msg, size, mbx_id);
/* if msg sent wait until we receive an ack */
if (!ret_val)
ret_val = igb_poll_for_ack(hw, mbx_id);
out:
return ret_val;
}
static s32 igb_check_for_bit_pf(struct e1000_hw *hw, u32 mask)
{
u32 mbvficr = rd32(E1000_MBVFICR);
s32 ret_val = -E1000_ERR_MBX;
if (mbvficr & mask) {
ret_val = 0;
wr32(E1000_MBVFICR, mask);
}
return ret_val;
}
/**
* igb_check_for_msg_pf - checks to see if the VF has sent mail
* @hw: pointer to the HW structure
* @vf_number: the VF index
*
* returns SUCCESS if the VF has set the Status bit or else ERR_MBX
**/
static s32 igb_check_for_msg_pf(struct e1000_hw *hw, u16 vf_number)
{
s32 ret_val = -E1000_ERR_MBX;
if (!igb_check_for_bit_pf(hw, E1000_MBVFICR_VFREQ_VF1 << vf_number)) {
ret_val = 0;
hw->mbx.stats.reqs++;
}
return ret_val;
}
/**
* igb_check_for_ack_pf - checks to see if the VF has ACKed
* @hw: pointer to the HW structure
* @vf_number: the VF index
*
* returns SUCCESS if the VF has set the Status bit or else ERR_MBX
**/
static s32 igb_check_for_ack_pf(struct e1000_hw *hw, u16 vf_number)
{
s32 ret_val = -E1000_ERR_MBX;
if (!igb_check_for_bit_pf(hw, E1000_MBVFICR_VFACK_VF1 << vf_number)) {
ret_val = 0;
hw->mbx.stats.acks++;
}
return ret_val;
}
/**
* igb_check_for_rst_pf - checks to see if the VF has reset
* @hw: pointer to the HW structure
* @vf_number: the VF index
*
* returns SUCCESS if the VF has set the Status bit or else ERR_MBX
**/
static s32 igb_check_for_rst_pf(struct e1000_hw *hw, u16 vf_number)
{
u32 vflre = rd32(E1000_VFLRE);
s32 ret_val = -E1000_ERR_MBX;
if (vflre & BIT(vf_number)) {
ret_val = 0;
wr32(E1000_VFLRE, BIT(vf_number));
hw->mbx.stats.rsts++;
}
return ret_val;
}
/**
* igb_obtain_mbx_lock_pf - obtain mailbox lock
* @hw: pointer to the HW structure
* @vf_number: the VF index
*
* return SUCCESS if we obtained the mailbox lock
**/
static s32 igb_obtain_mbx_lock_pf(struct e1000_hw *hw, u16 vf_number)
{
s32 ret_val = -E1000_ERR_MBX;
u32 p2v_mailbox;
int count = 10;
do {
/* Take ownership of the buffer */
wr32(E1000_P2VMAILBOX(vf_number), E1000_P2VMAILBOX_PFU);
/* reserve mailbox for vf use */
p2v_mailbox = rd32(E1000_P2VMAILBOX(vf_number));
if (p2v_mailbox & E1000_P2VMAILBOX_PFU) {
ret_val = 0;
break;
}
udelay(1000);
} while (count-- > 0);
return ret_val;
}
/**
* igb_release_mbx_lock_pf - release mailbox lock
* @hw: pointer to the HW structure
* @vf_number: the VF index
*
* return SUCCESS if we released the mailbox lock
**/
static s32 igb_release_mbx_lock_pf(struct e1000_hw *hw, u16 vf_number)
{
u32 p2v_mailbox;
/* drop PF lock of mailbox, if set */
p2v_mailbox = rd32(E1000_P2VMAILBOX(vf_number));
if (p2v_mailbox & E1000_P2VMAILBOX_PFU)
wr32(E1000_P2VMAILBOX(vf_number),
p2v_mailbox & ~E1000_P2VMAILBOX_PFU);
return 0;
}
/**
* igb_write_mbx_pf - Places a message in the mailbox
* @hw: pointer to the HW structure
* @msg: The message buffer
* @size: Length of buffer
* @vf_number: the VF index
*
* returns SUCCESS if it successfully copied message into the buffer
**/
static s32 igb_write_mbx_pf(struct e1000_hw *hw, u32 *msg, u16 size,
u16 vf_number)
{
s32 ret_val;
u16 i;
/* lock the mailbox to prevent pf/vf race condition */
ret_val = igb_obtain_mbx_lock_pf(hw, vf_number);
if (ret_val)
goto out_no_write;
/* flush msg and acks as we are overwriting the message buffer */
igb_check_for_msg_pf(hw, vf_number);
igb_check_for_ack_pf(hw, vf_number);
/* copy the caller specified message to the mailbox memory buffer */
for (i = 0; i < size; i++)
array_wr32(E1000_VMBMEM(vf_number), i, msg[i]);
/* Interrupt VF to tell it a message has been sent and release buffer*/
wr32(E1000_P2VMAILBOX(vf_number), E1000_P2VMAILBOX_STS);
/* update stats */
hw->mbx.stats.msgs_tx++;
out_no_write:
return ret_val;
}
/**
* igb_read_mbx_pf - Read a message from the mailbox
* @hw: pointer to the HW structure
* @msg: The message buffer
* @size: Length of buffer
* @vf_number: the VF index
* @unlock: unlock the mailbox when done?
*
* This function copies a message from the mailbox buffer to the caller's
* memory buffer. The presumption is that the caller knows that there was
* a message due to a VF request so no polling for message is needed.
**/
static s32 igb_read_mbx_pf(struct e1000_hw *hw, u32 *msg, u16 size,
u16 vf_number, bool unlock)
{
s32 ret_val;
u16 i;
/* lock the mailbox to prevent pf/vf race condition */
ret_val = igb_obtain_mbx_lock_pf(hw, vf_number);
if (ret_val)
goto out_no_read;
/* copy the message to the mailbox memory buffer */
for (i = 0; i < size; i++)
msg[i] = array_rd32(E1000_VMBMEM(vf_number), i);
/* Acknowledge the message and release mailbox lock (or not) */
if (unlock)
wr32(E1000_P2VMAILBOX(vf_number), E1000_P2VMAILBOX_ACK);
else
wr32(E1000_P2VMAILBOX(vf_number),
E1000_P2VMAILBOX_ACK | E1000_P2VMAILBOX_PFU);
/* update stats */
hw->mbx.stats.msgs_rx++;
out_no_read:
return ret_val;
}
/**
* igb_init_mbx_params_pf - set initial values for pf mailbox
* @hw: pointer to the HW structure
*
* Initializes the hw->mbx struct to correct values for pf mailbox
*/
s32 igb_init_mbx_params_pf(struct e1000_hw *hw)
{
struct e1000_mbx_info *mbx = &hw->mbx;
mbx->timeout = 0;
mbx->usec_delay = 0;
mbx->size = E1000_VFMAILBOX_SIZE;
mbx->ops.read = igb_read_mbx_pf;
mbx->ops.write = igb_write_mbx_pf;
mbx->ops.read_posted = igb_read_posted_mbx;
mbx->ops.write_posted = igb_write_posted_mbx;
mbx->ops.check_for_msg = igb_check_for_msg_pf;
mbx->ops.check_for_ack = igb_check_for_ack_pf;
mbx->ops.check_for_rst = igb_check_for_rst_pf;
mbx->ops.unlock = igb_release_mbx_lock_pf;
mbx->stats.msgs_tx = 0;
mbx->stats.msgs_rx = 0;
mbx->stats.reqs = 0;
mbx->stats.acks = 0;
mbx->stats.rsts = 0;
return 0;
}

View File

@ -0,0 +1,59 @@
/* SPDX-License-Identifier: GPL-2.0 */
/* Copyright(c) 2007 - 2018 Intel Corporation. */
#ifndef _E1000_MBX_H_
#define _E1000_MBX_H_
#include "e1000_hw-6.1-ethercat.h"
#define E1000_P2VMAILBOX_STS 0x00000001 /* Initiate message send to VF */
#define E1000_P2VMAILBOX_ACK 0x00000002 /* Ack message recv'd from VF */
#define E1000_P2VMAILBOX_VFU 0x00000004 /* VF owns the mailbox buffer */
#define E1000_P2VMAILBOX_PFU 0x00000008 /* PF owns the mailbox buffer */
#define E1000_P2VMAILBOX_RVFU 0x00000010 /* Reset VFU - used when VF stuck */
#define E1000_MBVFICR_VFREQ_MASK 0x000000FF /* bits for VF messages */
#define E1000_MBVFICR_VFREQ_VF1 0x00000001 /* bit for VF 1 message */
#define E1000_MBVFICR_VFACK_MASK 0x00FF0000 /* bits for VF acks */
#define E1000_MBVFICR_VFACK_VF1 0x00010000 /* bit for VF 1 ack */
#define E1000_VFMAILBOX_SIZE 16 /* 16 32 bit words - 64 bytes */
/* If it's a E1000_VF_* msg then it originates in the VF and is sent to the
* PF. The reverse is true if it is E1000_PF_*.
* Message ACK's are the value or'd with 0xF0000000
*/
/* Messages below or'd with this are the ACK */
#define E1000_VT_MSGTYPE_ACK 0x80000000
/* Messages below or'd with this are the NACK */
#define E1000_VT_MSGTYPE_NACK 0x40000000
/* Indicates that VF is still clear to send requests */
#define E1000_VT_MSGTYPE_CTS 0x20000000
#define E1000_VT_MSGINFO_SHIFT 16
/* bits 23:16 are used for exra info for certain messages */
#define E1000_VT_MSGINFO_MASK (0xFF << E1000_VT_MSGINFO_SHIFT)
#define E1000_VF_RESET 0x01 /* VF requests reset */
#define E1000_VF_SET_MAC_ADDR 0x02 /* VF requests to set MAC addr */
/* VF requests to clear all unicast MAC filters */
#define E1000_VF_MAC_FILTER_CLR (0x01 << E1000_VT_MSGINFO_SHIFT)
/* VF requests to add unicast MAC filter */
#define E1000_VF_MAC_FILTER_ADD (0x02 << E1000_VT_MSGINFO_SHIFT)
#define E1000_VF_SET_MULTICAST 0x03 /* VF requests to set MC addr */
#define E1000_VF_SET_VLAN 0x04 /* VF requests to set VLAN */
#define E1000_VF_SET_LPE 0x05 /* VF requests to set VMOLR.LPE */
#define E1000_VF_SET_PROMISC 0x06 /*VF requests to clear VMOLR.ROPE/MPME*/
#define E1000_VF_SET_PROMISC_MULTICAST (0x02 << E1000_VT_MSGINFO_SHIFT)
#define E1000_PF_CONTROL_MSG 0x0100 /* PF control message */
s32 igb_read_mbx(struct e1000_hw *hw, u32 *msg, u16 size, u16 mbx_id,
bool unlock);
s32 igb_write_mbx(struct e1000_hw *hw, u32 *msg, u16 size, u16 mbx_id);
s32 igb_check_for_msg(struct e1000_hw *hw, u16 mbx_id);
s32 igb_check_for_ack(struct e1000_hw *hw, u16 mbx_id);
s32 igb_check_for_rst(struct e1000_hw *hw, u16 mbx_id);
s32 igb_unlock_mbx(struct e1000_hw *hw, u16 mbx_id);
s32 igb_init_mbx_params_pf(struct e1000_hw *hw);
#endif /* _E1000_MBX_H_ */

View File

@ -0,0 +1,475 @@
// SPDX-License-Identifier: GPL-2.0
/* Copyright(c) 2007 - 2018 Intel Corporation. */
#include "e1000_mbx.h"
/**
* igb_read_mbx - Reads a message from the mailbox
* @hw: pointer to the HW structure
* @msg: The message buffer
* @size: Length of buffer
* @mbx_id: id of mailbox to read
* @unlock: skip locking or not
*
* returns SUCCESS if it successfully read message from buffer
**/
s32 igb_read_mbx(struct e1000_hw *hw, u32 *msg, u16 size, u16 mbx_id,
bool unlock)
{
struct e1000_mbx_info *mbx = &hw->mbx;
s32 ret_val = -E1000_ERR_MBX;
/* limit read to size of mailbox */
if (size > mbx->size)
size = mbx->size;
if (mbx->ops.read)
ret_val = mbx->ops.read(hw, msg, size, mbx_id, unlock);
return ret_val;
}
/**
* igb_write_mbx - Write a message to the mailbox
* @hw: pointer to the HW structure
* @msg: The message buffer
* @size: Length of buffer
* @mbx_id: id of mailbox to write
*
* returns SUCCESS if it successfully copied message into the buffer
**/
s32 igb_write_mbx(struct e1000_hw *hw, u32 *msg, u16 size, u16 mbx_id)
{
struct e1000_mbx_info *mbx = &hw->mbx;
s32 ret_val = 0;
if (size > mbx->size)
ret_val = -E1000_ERR_MBX;
else if (mbx->ops.write)
ret_val = mbx->ops.write(hw, msg, size, mbx_id);
return ret_val;
}
/**
* igb_check_for_msg - checks to see if someone sent us mail
* @hw: pointer to the HW structure
* @mbx_id: id of mailbox to check
*
* returns SUCCESS if the Status bit was found or else ERR_MBX
**/
s32 igb_check_for_msg(struct e1000_hw *hw, u16 mbx_id)
{
struct e1000_mbx_info *mbx = &hw->mbx;
s32 ret_val = -E1000_ERR_MBX;
if (mbx->ops.check_for_msg)
ret_val = mbx->ops.check_for_msg(hw, mbx_id);
return ret_val;
}
/**
* igb_check_for_ack - checks to see if someone sent us ACK
* @hw: pointer to the HW structure
* @mbx_id: id of mailbox to check
*
* returns SUCCESS if the Status bit was found or else ERR_MBX
**/
s32 igb_check_for_ack(struct e1000_hw *hw, u16 mbx_id)
{
struct e1000_mbx_info *mbx = &hw->mbx;
s32 ret_val = -E1000_ERR_MBX;
if (mbx->ops.check_for_ack)
ret_val = mbx->ops.check_for_ack(hw, mbx_id);
return ret_val;
}
/**
* igb_check_for_rst - checks to see if other side has reset
* @hw: pointer to the HW structure
* @mbx_id: id of mailbox to check
*
* returns SUCCESS if the Status bit was found or else ERR_MBX
**/
s32 igb_check_for_rst(struct e1000_hw *hw, u16 mbx_id)
{
struct e1000_mbx_info *mbx = &hw->mbx;
s32 ret_val = -E1000_ERR_MBX;
if (mbx->ops.check_for_rst)
ret_val = mbx->ops.check_for_rst(hw, mbx_id);
return ret_val;
}
/**
* igb_unlock_mbx - unlock the mailbox
* @hw: pointer to the HW structure
* @mbx_id: id of mailbox to check
*
* returns SUCCESS if the mailbox was unlocked or else ERR_MBX
**/
s32 igb_unlock_mbx(struct e1000_hw *hw, u16 mbx_id)
{
struct e1000_mbx_info *mbx = &hw->mbx;
s32 ret_val = -E1000_ERR_MBX;
if (mbx->ops.unlock)
ret_val = mbx->ops.unlock(hw, mbx_id);
return ret_val;
}
/**
* igb_poll_for_msg - Wait for message notification
* @hw: pointer to the HW structure
* @mbx_id: id of mailbox to write
*
* returns SUCCESS if it successfully received a message notification
**/
static s32 igb_poll_for_msg(struct e1000_hw *hw, u16 mbx_id)
{
struct e1000_mbx_info *mbx = &hw->mbx;
int countdown = mbx->timeout;
if (!countdown || !mbx->ops.check_for_msg)
goto out;
while (countdown && mbx->ops.check_for_msg(hw, mbx_id)) {
countdown--;
if (!countdown)
break;
udelay(mbx->usec_delay);
}
/* if we failed, all future posted messages fail until reset */
if (!countdown)
mbx->timeout = 0;
out:
return countdown ? 0 : -E1000_ERR_MBX;
}
/**
* igb_poll_for_ack - Wait for message acknowledgement
* @hw: pointer to the HW structure
* @mbx_id: id of mailbox to write
*
* returns SUCCESS if it successfully received a message acknowledgement
**/
static s32 igb_poll_for_ack(struct e1000_hw *hw, u16 mbx_id)
{
struct e1000_mbx_info *mbx = &hw->mbx;
int countdown = mbx->timeout;
if (!countdown || !mbx->ops.check_for_ack)
goto out;
while (countdown && mbx->ops.check_for_ack(hw, mbx_id)) {
countdown--;
if (!countdown)
break;
udelay(mbx->usec_delay);
}
/* if we failed, all future posted messages fail until reset */
if (!countdown)
mbx->timeout = 0;
out:
return countdown ? 0 : -E1000_ERR_MBX;
}
/**
* igb_read_posted_mbx - Wait for message notification and receive message
* @hw: pointer to the HW structure
* @msg: The message buffer
* @size: Length of buffer
* @mbx_id: id of mailbox to write
*
* returns SUCCESS if it successfully received a message notification and
* copied it into the receive buffer.
**/
static s32 igb_read_posted_mbx(struct e1000_hw *hw, u32 *msg, u16 size,
u16 mbx_id)
{
struct e1000_mbx_info *mbx = &hw->mbx;
s32 ret_val = -E1000_ERR_MBX;
if (!mbx->ops.read)
goto out;
ret_val = igb_poll_for_msg(hw, mbx_id);
if (!ret_val)
ret_val = mbx->ops.read(hw, msg, size, mbx_id, true);
out:
return ret_val;
}
/**
* igb_write_posted_mbx - Write a message to the mailbox, wait for ack
* @hw: pointer to the HW structure
* @msg: The message buffer
* @size: Length of buffer
* @mbx_id: id of mailbox to write
*
* returns SUCCESS if it successfully copied message into the buffer and
* received an ack to that message within delay * timeout period
**/
static s32 igb_write_posted_mbx(struct e1000_hw *hw, u32 *msg, u16 size,
u16 mbx_id)
{
struct e1000_mbx_info *mbx = &hw->mbx;
s32 ret_val = -E1000_ERR_MBX;
/* exit if either we can't write or there isn't a defined timeout */
if (!mbx->ops.write || !mbx->timeout)
goto out;
/* send msg */
ret_val = mbx->ops.write(hw, msg, size, mbx_id);
/* if msg sent wait until we receive an ack */
if (!ret_val)
ret_val = igb_poll_for_ack(hw, mbx_id);
out:
return ret_val;
}
static s32 igb_check_for_bit_pf(struct e1000_hw *hw, u32 mask)
{
u32 mbvficr = rd32(E1000_MBVFICR);
s32 ret_val = -E1000_ERR_MBX;
if (mbvficr & mask) {
ret_val = 0;
wr32(E1000_MBVFICR, mask);
}
return ret_val;
}
/**
* igb_check_for_msg_pf - checks to see if the VF has sent mail
* @hw: pointer to the HW structure
* @vf_number: the VF index
*
* returns SUCCESS if the VF has set the Status bit or else ERR_MBX
**/
static s32 igb_check_for_msg_pf(struct e1000_hw *hw, u16 vf_number)
{
s32 ret_val = -E1000_ERR_MBX;
if (!igb_check_for_bit_pf(hw, E1000_MBVFICR_VFREQ_VF1 << vf_number)) {
ret_val = 0;
hw->mbx.stats.reqs++;
}
return ret_val;
}
/**
* igb_check_for_ack_pf - checks to see if the VF has ACKed
* @hw: pointer to the HW structure
* @vf_number: the VF index
*
* returns SUCCESS if the VF has set the Status bit or else ERR_MBX
**/
static s32 igb_check_for_ack_pf(struct e1000_hw *hw, u16 vf_number)
{
s32 ret_val = -E1000_ERR_MBX;
if (!igb_check_for_bit_pf(hw, E1000_MBVFICR_VFACK_VF1 << vf_number)) {
ret_val = 0;
hw->mbx.stats.acks++;
}
return ret_val;
}
/**
* igb_check_for_rst_pf - checks to see if the VF has reset
* @hw: pointer to the HW structure
* @vf_number: the VF index
*
* returns SUCCESS if the VF has set the Status bit or else ERR_MBX
**/
static s32 igb_check_for_rst_pf(struct e1000_hw *hw, u16 vf_number)
{
u32 vflre = rd32(E1000_VFLRE);
s32 ret_val = -E1000_ERR_MBX;
if (vflre & BIT(vf_number)) {
ret_val = 0;
wr32(E1000_VFLRE, BIT(vf_number));
hw->mbx.stats.rsts++;
}
return ret_val;
}
/**
* igb_obtain_mbx_lock_pf - obtain mailbox lock
* @hw: pointer to the HW structure
* @vf_number: the VF index
*
* return SUCCESS if we obtained the mailbox lock
**/
static s32 igb_obtain_mbx_lock_pf(struct e1000_hw *hw, u16 vf_number)
{
s32 ret_val = -E1000_ERR_MBX;
u32 p2v_mailbox;
int count = 10;
do {
/* Take ownership of the buffer */
wr32(E1000_P2VMAILBOX(vf_number), E1000_P2VMAILBOX_PFU);
/* reserve mailbox for vf use */
p2v_mailbox = rd32(E1000_P2VMAILBOX(vf_number));
if (p2v_mailbox & E1000_P2VMAILBOX_PFU) {
ret_val = 0;
break;
}
udelay(1000);
} while (count-- > 0);
return ret_val;
}
/**
* igb_release_mbx_lock_pf - release mailbox lock
* @hw: pointer to the HW structure
* @vf_number: the VF index
*
* return SUCCESS if we released the mailbox lock
**/
static s32 igb_release_mbx_lock_pf(struct e1000_hw *hw, u16 vf_number)
{
u32 p2v_mailbox;
/* drop PF lock of mailbox, if set */
p2v_mailbox = rd32(E1000_P2VMAILBOX(vf_number));
if (p2v_mailbox & E1000_P2VMAILBOX_PFU)
wr32(E1000_P2VMAILBOX(vf_number),
p2v_mailbox & ~E1000_P2VMAILBOX_PFU);
return 0;
}
/**
* igb_write_mbx_pf - Places a message in the mailbox
* @hw: pointer to the HW structure
* @msg: The message buffer
* @size: Length of buffer
* @vf_number: the VF index
*
* returns SUCCESS if it successfully copied message into the buffer
**/
static s32 igb_write_mbx_pf(struct e1000_hw *hw, u32 *msg, u16 size,
u16 vf_number)
{
s32 ret_val;
u16 i;
/* lock the mailbox to prevent pf/vf race condition */
ret_val = igb_obtain_mbx_lock_pf(hw, vf_number);
if (ret_val)
goto out_no_write;
/* flush msg and acks as we are overwriting the message buffer */
igb_check_for_msg_pf(hw, vf_number);
igb_check_for_ack_pf(hw, vf_number);
/* copy the caller specified message to the mailbox memory buffer */
for (i = 0; i < size; i++)
array_wr32(E1000_VMBMEM(vf_number), i, msg[i]);
/* Interrupt VF to tell it a message has been sent and release buffer*/
wr32(E1000_P2VMAILBOX(vf_number), E1000_P2VMAILBOX_STS);
/* update stats */
hw->mbx.stats.msgs_tx++;
out_no_write:
return ret_val;
}
/**
* igb_read_mbx_pf - Read a message from the mailbox
* @hw: pointer to the HW structure
* @msg: The message buffer
* @size: Length of buffer
* @vf_number: the VF index
* @unlock: unlock the mailbox when done?
*
* This function copies a message from the mailbox buffer to the caller's
* memory buffer. The presumption is that the caller knows that there was
* a message due to a VF request so no polling for message is needed.
**/
static s32 igb_read_mbx_pf(struct e1000_hw *hw, u32 *msg, u16 size,
u16 vf_number, bool unlock)
{
s32 ret_val;
u16 i;
/* lock the mailbox to prevent pf/vf race condition */
ret_val = igb_obtain_mbx_lock_pf(hw, vf_number);
if (ret_val)
goto out_no_read;
/* copy the message to the mailbox memory buffer */
for (i = 0; i < size; i++)
msg[i] = array_rd32(E1000_VMBMEM(vf_number), i);
/* Acknowledge the message and release mailbox lock (or not) */
if (unlock)
wr32(E1000_P2VMAILBOX(vf_number), E1000_P2VMAILBOX_ACK);
else
wr32(E1000_P2VMAILBOX(vf_number),
E1000_P2VMAILBOX_ACK | E1000_P2VMAILBOX_PFU);
/* update stats */
hw->mbx.stats.msgs_rx++;
out_no_read:
return ret_val;
}
/**
* igb_init_mbx_params_pf - set initial values for pf mailbox
* @hw: pointer to the HW structure
*
* Initializes the hw->mbx struct to correct values for pf mailbox
*/
s32 igb_init_mbx_params_pf(struct e1000_hw *hw)
{
struct e1000_mbx_info *mbx = &hw->mbx;
mbx->timeout = 0;
mbx->usec_delay = 0;
mbx->size = E1000_VFMAILBOX_SIZE;
mbx->ops.read = igb_read_mbx_pf;
mbx->ops.write = igb_write_mbx_pf;
mbx->ops.read_posted = igb_read_posted_mbx;
mbx->ops.write_posted = igb_write_posted_mbx;
mbx->ops.check_for_msg = igb_check_for_msg_pf;
mbx->ops.check_for_ack = igb_check_for_ack_pf;
mbx->ops.check_for_rst = igb_check_for_rst_pf;
mbx->ops.unlock = igb_release_mbx_lock_pf;
mbx->stats.msgs_tx = 0;
mbx->stats.msgs_rx = 0;
mbx->stats.reqs = 0;
mbx->stats.acks = 0;
mbx->stats.rsts = 0;
return 0;
}

View File

@ -0,0 +1,59 @@
/* SPDX-License-Identifier: GPL-2.0 */
/* Copyright(c) 2007 - 2018 Intel Corporation. */
#ifndef _E1000_MBX_H_
#define _E1000_MBX_H_
#include "e1000_hw.h"
#define E1000_P2VMAILBOX_STS 0x00000001 /* Initiate message send to VF */
#define E1000_P2VMAILBOX_ACK 0x00000002 /* Ack message recv'd from VF */
#define E1000_P2VMAILBOX_VFU 0x00000004 /* VF owns the mailbox buffer */
#define E1000_P2VMAILBOX_PFU 0x00000008 /* PF owns the mailbox buffer */
#define E1000_P2VMAILBOX_RVFU 0x00000010 /* Reset VFU - used when VF stuck */
#define E1000_MBVFICR_VFREQ_MASK 0x000000FF /* bits for VF messages */
#define E1000_MBVFICR_VFREQ_VF1 0x00000001 /* bit for VF 1 message */
#define E1000_MBVFICR_VFACK_MASK 0x00FF0000 /* bits for VF acks */
#define E1000_MBVFICR_VFACK_VF1 0x00010000 /* bit for VF 1 ack */
#define E1000_VFMAILBOX_SIZE 16 /* 16 32 bit words - 64 bytes */
/* If it's a E1000_VF_* msg then it originates in the VF and is sent to the
* PF. The reverse is true if it is E1000_PF_*.
* Message ACK's are the value or'd with 0xF0000000
*/
/* Messages below or'd with this are the ACK */
#define E1000_VT_MSGTYPE_ACK 0x80000000
/* Messages below or'd with this are the NACK */
#define E1000_VT_MSGTYPE_NACK 0x40000000
/* Indicates that VF is still clear to send requests */
#define E1000_VT_MSGTYPE_CTS 0x20000000
#define E1000_VT_MSGINFO_SHIFT 16
/* bits 23:16 are used for exra info for certain messages */
#define E1000_VT_MSGINFO_MASK (0xFF << E1000_VT_MSGINFO_SHIFT)
#define E1000_VF_RESET 0x01 /* VF requests reset */
#define E1000_VF_SET_MAC_ADDR 0x02 /* VF requests to set MAC addr */
/* VF requests to clear all unicast MAC filters */
#define E1000_VF_MAC_FILTER_CLR (0x01 << E1000_VT_MSGINFO_SHIFT)
/* VF requests to add unicast MAC filter */
#define E1000_VF_MAC_FILTER_ADD (0x02 << E1000_VT_MSGINFO_SHIFT)
#define E1000_VF_SET_MULTICAST 0x03 /* VF requests to set MC addr */
#define E1000_VF_SET_VLAN 0x04 /* VF requests to set VLAN */
#define E1000_VF_SET_LPE 0x05 /* VF requests to set VMOLR.LPE */
#define E1000_VF_SET_PROMISC 0x06 /*VF requests to clear VMOLR.ROPE/MPME*/
#define E1000_VF_SET_PROMISC_MULTICAST (0x02 << E1000_VT_MSGINFO_SHIFT)
#define E1000_PF_CONTROL_MSG 0x0100 /* PF control message */
s32 igb_read_mbx(struct e1000_hw *hw, u32 *msg, u16 size, u16 mbx_id,
bool unlock);
s32 igb_write_mbx(struct e1000_hw *hw, u32 *msg, u16 size, u16 mbx_id);
s32 igb_check_for_msg(struct e1000_hw *hw, u16 mbx_id);
s32 igb_check_for_ack(struct e1000_hw *hw, u16 mbx_id);
s32 igb_check_for_rst(struct e1000_hw *hw, u16 mbx_id);
s32 igb_unlock_mbx(struct e1000_hw *hw, u16 mbx_id);
s32 igb_init_mbx_params_pf(struct e1000_hw *hw);
#endif /* _E1000_MBX_H_ */

View File

@ -0,0 +1,782 @@
// SPDX-License-Identifier: GPL-2.0
/* Copyright(c) 2007 - 2018 Intel Corporation. */
#include <linux/if_ether.h>
#include <linux/delay.h>
#include "e1000_mac-6.1-ethercat.h"
#include "e1000_nvm-6.1-ethercat.h"
/**
* igb_raise_eec_clk - Raise EEPROM clock
* @hw: pointer to the HW structure
* @eecd: pointer to the EEPROM
*
* Enable/Raise the EEPROM clock bit.
**/
static void igb_raise_eec_clk(struct e1000_hw *hw, u32 *eecd)
{
*eecd = *eecd | E1000_EECD_SK;
wr32(E1000_EECD, *eecd);
wrfl();
udelay(hw->nvm.delay_usec);
}
/**
* igb_lower_eec_clk - Lower EEPROM clock
* @hw: pointer to the HW structure
* @eecd: pointer to the EEPROM
*
* Clear/Lower the EEPROM clock bit.
**/
static void igb_lower_eec_clk(struct e1000_hw *hw, u32 *eecd)
{
*eecd = *eecd & ~E1000_EECD_SK;
wr32(E1000_EECD, *eecd);
wrfl();
udelay(hw->nvm.delay_usec);
}
/**
* igb_shift_out_eec_bits - Shift data bits our to the EEPROM
* @hw: pointer to the HW structure
* @data: data to send to the EEPROM
* @count: number of bits to shift out
*
* We need to shift 'count' bits out to the EEPROM. So, the value in the
* "data" parameter will be shifted out to the EEPROM one bit at a time.
* In order to do this, "data" must be broken down into bits.
**/
static void igb_shift_out_eec_bits(struct e1000_hw *hw, u16 data, u16 count)
{
struct e1000_nvm_info *nvm = &hw->nvm;
u32 eecd = rd32(E1000_EECD);
u32 mask;
mask = 1u << (count - 1);
if (nvm->type == e1000_nvm_eeprom_spi)
eecd |= E1000_EECD_DO;
do {
eecd &= ~E1000_EECD_DI;
if (data & mask)
eecd |= E1000_EECD_DI;
wr32(E1000_EECD, eecd);
wrfl();
udelay(nvm->delay_usec);
igb_raise_eec_clk(hw, &eecd);
igb_lower_eec_clk(hw, &eecd);
mask >>= 1;
} while (mask);
eecd &= ~E1000_EECD_DI;
wr32(E1000_EECD, eecd);
}
/**
* igb_shift_in_eec_bits - Shift data bits in from the EEPROM
* @hw: pointer to the HW structure
* @count: number of bits to shift in
*
* In order to read a register from the EEPROM, we need to shift 'count' bits
* in from the EEPROM. Bits are "shifted in" by raising the clock input to
* the EEPROM (setting the SK bit), and then reading the value of the data out
* "DO" bit. During this "shifting in" process the data in "DI" bit should
* always be clear.
**/
static u16 igb_shift_in_eec_bits(struct e1000_hw *hw, u16 count)
{
u32 eecd;
u32 i;
u16 data;
eecd = rd32(E1000_EECD);
eecd &= ~(E1000_EECD_DO | E1000_EECD_DI);
data = 0;
for (i = 0; i < count; i++) {
data <<= 1;
igb_raise_eec_clk(hw, &eecd);
eecd = rd32(E1000_EECD);
eecd &= ~E1000_EECD_DI;
if (eecd & E1000_EECD_DO)
data |= 1;
igb_lower_eec_clk(hw, &eecd);
}
return data;
}
/**
* igb_poll_eerd_eewr_done - Poll for EEPROM read/write completion
* @hw: pointer to the HW structure
* @ee_reg: EEPROM flag for polling
*
* Polls the EEPROM status bit for either read or write completion based
* upon the value of 'ee_reg'.
**/
static s32 igb_poll_eerd_eewr_done(struct e1000_hw *hw, int ee_reg)
{
u32 attempts = 100000;
u32 i, reg = 0;
s32 ret_val = -E1000_ERR_NVM;
for (i = 0; i < attempts; i++) {
if (ee_reg == E1000_NVM_POLL_READ)
reg = rd32(E1000_EERD);
else
reg = rd32(E1000_EEWR);
if (reg & E1000_NVM_RW_REG_DONE) {
ret_val = 0;
break;
}
udelay(5);
}
return ret_val;
}
/**
* igb_acquire_nvm - Generic request for access to EEPROM
* @hw: pointer to the HW structure
*
* Set the EEPROM access request bit and wait for EEPROM access grant bit.
* Return successful if access grant bit set, else clear the request for
* EEPROM access and return -E1000_ERR_NVM (-1).
**/
s32 igb_acquire_nvm(struct e1000_hw *hw)
{
u32 eecd = rd32(E1000_EECD);
s32 timeout = E1000_NVM_GRANT_ATTEMPTS;
s32 ret_val = 0;
wr32(E1000_EECD, eecd | E1000_EECD_REQ);
eecd = rd32(E1000_EECD);
while (timeout) {
if (eecd & E1000_EECD_GNT)
break;
udelay(5);
eecd = rd32(E1000_EECD);
timeout--;
}
if (!timeout) {
eecd &= ~E1000_EECD_REQ;
wr32(E1000_EECD, eecd);
hw_dbg("Could not acquire NVM grant\n");
ret_val = -E1000_ERR_NVM;
}
return ret_val;
}
/**
* igb_standby_nvm - Return EEPROM to standby state
* @hw: pointer to the HW structure
*
* Return the EEPROM to a standby state.
**/
static void igb_standby_nvm(struct e1000_hw *hw)
{
struct e1000_nvm_info *nvm = &hw->nvm;
u32 eecd = rd32(E1000_EECD);
if (nvm->type == e1000_nvm_eeprom_spi) {
/* Toggle CS to flush commands */
eecd |= E1000_EECD_CS;
wr32(E1000_EECD, eecd);
wrfl();
udelay(nvm->delay_usec);
eecd &= ~E1000_EECD_CS;
wr32(E1000_EECD, eecd);
wrfl();
udelay(nvm->delay_usec);
}
}
/**
* e1000_stop_nvm - Terminate EEPROM command
* @hw: pointer to the HW structure
*
* Terminates the current command by inverting the EEPROM's chip select pin.
**/
static void e1000_stop_nvm(struct e1000_hw *hw)
{
u32 eecd;
eecd = rd32(E1000_EECD);
if (hw->nvm.type == e1000_nvm_eeprom_spi) {
/* Pull CS high */
eecd |= E1000_EECD_CS;
igb_lower_eec_clk(hw, &eecd);
}
}
/**
* igb_release_nvm - Release exclusive access to EEPROM
* @hw: pointer to the HW structure
*
* Stop any current commands to the EEPROM and clear the EEPROM request bit.
**/
void igb_release_nvm(struct e1000_hw *hw)
{
u32 eecd;
e1000_stop_nvm(hw);
eecd = rd32(E1000_EECD);
eecd &= ~E1000_EECD_REQ;
wr32(E1000_EECD, eecd);
}
/**
* igb_ready_nvm_eeprom - Prepares EEPROM for read/write
* @hw: pointer to the HW structure
*
* Setups the EEPROM for reading and writing.
**/
static s32 igb_ready_nvm_eeprom(struct e1000_hw *hw)
{
struct e1000_nvm_info *nvm = &hw->nvm;
u32 eecd = rd32(E1000_EECD);
s32 ret_val = 0;
u16 timeout = 0;
u8 spi_stat_reg;
if (nvm->type == e1000_nvm_eeprom_spi) {
/* Clear SK and CS */
eecd &= ~(E1000_EECD_CS | E1000_EECD_SK);
wr32(E1000_EECD, eecd);
wrfl();
udelay(1);
timeout = NVM_MAX_RETRY_SPI;
/* Read "Status Register" repeatedly until the LSB is cleared.
* The EEPROM will signal that the command has been completed
* by clearing bit 0 of the internal status register. If it's
* not cleared within 'timeout', then error out.
*/
while (timeout) {
igb_shift_out_eec_bits(hw, NVM_RDSR_OPCODE_SPI,
hw->nvm.opcode_bits);
spi_stat_reg = (u8)igb_shift_in_eec_bits(hw, 8);
if (!(spi_stat_reg & NVM_STATUS_RDY_SPI))
break;
udelay(5);
igb_standby_nvm(hw);
timeout--;
}
if (!timeout) {
hw_dbg("SPI NVM Status error\n");
ret_val = -E1000_ERR_NVM;
goto out;
}
}
out:
return ret_val;
}
/**
* igb_read_nvm_spi - Read EEPROM's using SPI
* @hw: pointer to the HW structure
* @offset: offset of word in the EEPROM to read
* @words: number of words to read
* @data: word read from the EEPROM
*
* Reads a 16 bit word from the EEPROM.
**/
s32 igb_read_nvm_spi(struct e1000_hw *hw, u16 offset, u16 words, u16 *data)
{
struct e1000_nvm_info *nvm = &hw->nvm;
u32 i = 0;
s32 ret_val;
u16 word_in;
u8 read_opcode = NVM_READ_OPCODE_SPI;
/* A check for invalid values: offset too large, too many words,
* and not enough words.
*/
if ((offset >= nvm->word_size) || (words > (nvm->word_size - offset)) ||
(words == 0)) {
hw_dbg("nvm parameter(s) out of bounds\n");
ret_val = -E1000_ERR_NVM;
goto out;
}
ret_val = nvm->ops.acquire(hw);
if (ret_val)
goto out;
ret_val = igb_ready_nvm_eeprom(hw);
if (ret_val)
goto release;
igb_standby_nvm(hw);
if ((nvm->address_bits == 8) && (offset >= 128))
read_opcode |= NVM_A8_OPCODE_SPI;
/* Send the READ command (opcode + addr) */
igb_shift_out_eec_bits(hw, read_opcode, nvm->opcode_bits);
igb_shift_out_eec_bits(hw, (u16)(offset*2), nvm->address_bits);
/* Read the data. SPI NVMs increment the address with each byte
* read and will roll over if reading beyond the end. This allows
* us to read the whole NVM from any offset
*/
for (i = 0; i < words; i++) {
word_in = igb_shift_in_eec_bits(hw, 16);
data[i] = (word_in >> 8) | (word_in << 8);
}
release:
nvm->ops.release(hw);
out:
return ret_val;
}
/**
* igb_read_nvm_eerd - Reads EEPROM using EERD register
* @hw: pointer to the HW structure
* @offset: offset of word in the EEPROM to read
* @words: number of words to read
* @data: word read from the EEPROM
*
* Reads a 16 bit word from the EEPROM using the EERD register.
**/
s32 igb_read_nvm_eerd(struct e1000_hw *hw, u16 offset, u16 words, u16 *data)
{
struct e1000_nvm_info *nvm = &hw->nvm;
u32 i, eerd = 0;
s32 ret_val = 0;
/* A check for invalid values: offset too large, too many words,
* and not enough words.
*/
if ((offset >= nvm->word_size) || (words > (nvm->word_size - offset)) ||
(words == 0)) {
hw_dbg("nvm parameter(s) out of bounds\n");
ret_val = -E1000_ERR_NVM;
goto out;
}
for (i = 0; i < words; i++) {
eerd = ((offset+i) << E1000_NVM_RW_ADDR_SHIFT) +
E1000_NVM_RW_REG_START;
wr32(E1000_EERD, eerd);
ret_val = igb_poll_eerd_eewr_done(hw, E1000_NVM_POLL_READ);
if (ret_val)
break;
data[i] = (rd32(E1000_EERD) >>
E1000_NVM_RW_REG_DATA);
}
out:
return ret_val;
}
/**
* igb_write_nvm_spi - Write to EEPROM using SPI
* @hw: pointer to the HW structure
* @offset: offset within the EEPROM to be written to
* @words: number of words to write
* @data: 16 bit word(s) to be written to the EEPROM
*
* Writes data to EEPROM at offset using SPI interface.
*
* If e1000_update_nvm_checksum is not called after this function , the
* EEPROM will most likley contain an invalid checksum.
**/
s32 igb_write_nvm_spi(struct e1000_hw *hw, u16 offset, u16 words, u16 *data)
{
struct e1000_nvm_info *nvm = &hw->nvm;
s32 ret_val = -E1000_ERR_NVM;
u16 widx = 0;
/* A check for invalid values: offset too large, too many words,
* and not enough words.
*/
if ((offset >= nvm->word_size) || (words > (nvm->word_size - offset)) ||
(words == 0)) {
hw_dbg("nvm parameter(s) out of bounds\n");
return ret_val;
}
while (widx < words) {
u8 write_opcode = NVM_WRITE_OPCODE_SPI;
ret_val = nvm->ops.acquire(hw);
if (ret_val)
return ret_val;
ret_val = igb_ready_nvm_eeprom(hw);
if (ret_val) {
nvm->ops.release(hw);
return ret_val;
}
igb_standby_nvm(hw);
/* Send the WRITE ENABLE command (8 bit opcode) */
igb_shift_out_eec_bits(hw, NVM_WREN_OPCODE_SPI,
nvm->opcode_bits);
igb_standby_nvm(hw);
/* Some SPI eeproms use the 8th address bit embedded in the
* opcode
*/
if ((nvm->address_bits == 8) && (offset >= 128))
write_opcode |= NVM_A8_OPCODE_SPI;
/* Send the Write command (8-bit opcode + addr) */
igb_shift_out_eec_bits(hw, write_opcode, nvm->opcode_bits);
igb_shift_out_eec_bits(hw, (u16)((offset + widx) * 2),
nvm->address_bits);
/* Loop to allow for up to whole page write of eeprom */
while (widx < words) {
u16 word_out = data[widx];
word_out = (word_out >> 8) | (word_out << 8);
igb_shift_out_eec_bits(hw, word_out, 16);
widx++;
if ((((offset + widx) * 2) % nvm->page_size) == 0) {
igb_standby_nvm(hw);
break;
}
}
usleep_range(1000, 2000);
nvm->ops.release(hw);
}
return ret_val;
}
/**
* igb_read_part_string - Read device part number
* @hw: pointer to the HW structure
* @part_num: pointer to device part number
* @part_num_size: size of part number buffer
*
* Reads the product board assembly (PBA) number from the EEPROM and stores
* the value in part_num.
**/
s32 igb_read_part_string(struct e1000_hw *hw, u8 *part_num, u32 part_num_size)
{
s32 ret_val;
u16 nvm_data;
u16 pointer;
u16 offset;
u16 length;
if (part_num == NULL) {
hw_dbg("PBA string buffer was null\n");
ret_val = E1000_ERR_INVALID_ARGUMENT;
goto out;
}
ret_val = hw->nvm.ops.read(hw, NVM_PBA_OFFSET_0, 1, &nvm_data);
if (ret_val) {
hw_dbg("NVM Read Error\n");
goto out;
}
ret_val = hw->nvm.ops.read(hw, NVM_PBA_OFFSET_1, 1, &pointer);
if (ret_val) {
hw_dbg("NVM Read Error\n");
goto out;
}
/* if nvm_data is not ptr guard the PBA must be in legacy format which
* means pointer is actually our second data word for the PBA number
* and we can decode it into an ascii string
*/
if (nvm_data != NVM_PBA_PTR_GUARD) {
hw_dbg("NVM PBA number is not stored as string\n");
/* we will need 11 characters to store the PBA */
if (part_num_size < 11) {
hw_dbg("PBA string buffer too small\n");
return E1000_ERR_NO_SPACE;
}
/* extract hex string from data and pointer */
part_num[0] = (nvm_data >> 12) & 0xF;
part_num[1] = (nvm_data >> 8) & 0xF;
part_num[2] = (nvm_data >> 4) & 0xF;
part_num[3] = nvm_data & 0xF;
part_num[4] = (pointer >> 12) & 0xF;
part_num[5] = (pointer >> 8) & 0xF;
part_num[6] = '-';
part_num[7] = 0;
part_num[8] = (pointer >> 4) & 0xF;
part_num[9] = pointer & 0xF;
/* put a null character on the end of our string */
part_num[10] = '\0';
/* switch all the data but the '-' to hex char */
for (offset = 0; offset < 10; offset++) {
if (part_num[offset] < 0xA)
part_num[offset] += '0';
else if (part_num[offset] < 0x10)
part_num[offset] += 'A' - 0xA;
}
goto out;
}
ret_val = hw->nvm.ops.read(hw, pointer, 1, &length);
if (ret_val) {
hw_dbg("NVM Read Error\n");
goto out;
}
if (length == 0xFFFF || length == 0) {
hw_dbg("NVM PBA number section invalid length\n");
ret_val = E1000_ERR_NVM_PBA_SECTION;
goto out;
}
/* check if part_num buffer is big enough */
if (part_num_size < (((u32)length * 2) - 1)) {
hw_dbg("PBA string buffer too small\n");
ret_val = E1000_ERR_NO_SPACE;
goto out;
}
/* trim pba length from start of string */
pointer++;
length--;
for (offset = 0; offset < length; offset++) {
ret_val = hw->nvm.ops.read(hw, pointer + offset, 1, &nvm_data);
if (ret_val) {
hw_dbg("NVM Read Error\n");
goto out;
}
part_num[offset * 2] = (u8)(nvm_data >> 8);
part_num[(offset * 2) + 1] = (u8)(nvm_data & 0xFF);
}
part_num[offset * 2] = '\0';
out:
return ret_val;
}
/**
* igb_read_mac_addr - Read device MAC address
* @hw: pointer to the HW structure
*
* Reads the device MAC address from the EEPROM and stores the value.
* Since devices with two ports use the same EEPROM, we increment the
* last bit in the MAC address for the second port.
**/
s32 igb_read_mac_addr(struct e1000_hw *hw)
{
u32 rar_high;
u32 rar_low;
u16 i;
rar_high = rd32(E1000_RAH(0));
rar_low = rd32(E1000_RAL(0));
for (i = 0; i < E1000_RAL_MAC_ADDR_LEN; i++)
hw->mac.perm_addr[i] = (u8)(rar_low >> (i*8));
for (i = 0; i < E1000_RAH_MAC_ADDR_LEN; i++)
hw->mac.perm_addr[i+4] = (u8)(rar_high >> (i*8));
for (i = 0; i < ETH_ALEN; i++)
hw->mac.addr[i] = hw->mac.perm_addr[i];
return 0;
}
/**
* igb_validate_nvm_checksum - Validate EEPROM checksum
* @hw: pointer to the HW structure
*
* Calculates the EEPROM checksum by reading/adding each word of the EEPROM
* and then verifies that the sum of the EEPROM is equal to 0xBABA.
**/
s32 igb_validate_nvm_checksum(struct e1000_hw *hw)
{
s32 ret_val = 0;
u16 checksum = 0;
u16 i, nvm_data;
for (i = 0; i < (NVM_CHECKSUM_REG + 1); i++) {
ret_val = hw->nvm.ops.read(hw, i, 1, &nvm_data);
if (ret_val) {
hw_dbg("NVM Read Error\n");
goto out;
}
checksum += nvm_data;
}
if (checksum != (u16) NVM_SUM) {
hw_dbg("NVM Checksum Invalid\n");
ret_val = -E1000_ERR_NVM;
goto out;
}
out:
return ret_val;
}
/**
* igb_update_nvm_checksum - Update EEPROM checksum
* @hw: pointer to the HW structure
*
* Updates the EEPROM checksum by reading/adding each word of the EEPROM
* up to the checksum. Then calculates the EEPROM checksum and writes the
* value to the EEPROM.
**/
s32 igb_update_nvm_checksum(struct e1000_hw *hw)
{
s32 ret_val;
u16 checksum = 0;
u16 i, nvm_data;
for (i = 0; i < NVM_CHECKSUM_REG; i++) {
ret_val = hw->nvm.ops.read(hw, i, 1, &nvm_data);
if (ret_val) {
hw_dbg("NVM Read Error while updating checksum.\n");
goto out;
}
checksum += nvm_data;
}
checksum = (u16) NVM_SUM - checksum;
ret_val = hw->nvm.ops.write(hw, NVM_CHECKSUM_REG, 1, &checksum);
if (ret_val)
hw_dbg("NVM Write Error while updating checksum.\n");
out:
return ret_val;
}
/**
* igb_get_fw_version - Get firmware version information
* @hw: pointer to the HW structure
* @fw_vers: pointer to output structure
*
* unsupported MAC types will return all 0 version structure
**/
void igb_get_fw_version(struct e1000_hw *hw, struct e1000_fw_version *fw_vers)
{
u16 eeprom_verh, eeprom_verl, etrack_test, fw_version;
u8 q, hval, rem, result;
u16 comb_verh, comb_verl, comb_offset;
memset(fw_vers, 0, sizeof(struct e1000_fw_version));
/* basic eeprom version numbers and bits used vary by part and by tool
* used to create the nvm images. Check which data format we have.
*/
hw->nvm.ops.read(hw, NVM_ETRACK_HIWORD, 1, &etrack_test);
switch (hw->mac.type) {
case e1000_i211:
igb_read_invm_version(hw, fw_vers);
return;
case e1000_82575:
case e1000_82576:
case e1000_82580:
/* Use this format, unless EETRACK ID exists,
* then use alternate format
*/
if ((etrack_test & NVM_MAJOR_MASK) != NVM_ETRACK_VALID) {
hw->nvm.ops.read(hw, NVM_VERSION, 1, &fw_version);
fw_vers->eep_major = (fw_version & NVM_MAJOR_MASK)
>> NVM_MAJOR_SHIFT;
fw_vers->eep_minor = (fw_version & NVM_MINOR_MASK)
>> NVM_MINOR_SHIFT;
fw_vers->eep_build = (fw_version & NVM_IMAGE_ID_MASK);
goto etrack_id;
}
break;
case e1000_i210:
if (!(igb_get_flash_presence_i210(hw))) {
igb_read_invm_version(hw, fw_vers);
return;
}
fallthrough;
case e1000_i350:
/* find combo image version */
hw->nvm.ops.read(hw, NVM_COMB_VER_PTR, 1, &comb_offset);
if ((comb_offset != 0x0) &&
(comb_offset != NVM_VER_INVALID)) {
hw->nvm.ops.read(hw, (NVM_COMB_VER_OFF + comb_offset
+ 1), 1, &comb_verh);
hw->nvm.ops.read(hw, (NVM_COMB_VER_OFF + comb_offset),
1, &comb_verl);
/* get Option Rom version if it exists and is valid */
if ((comb_verh && comb_verl) &&
((comb_verh != NVM_VER_INVALID) &&
(comb_verl != NVM_VER_INVALID))) {
fw_vers->or_valid = true;
fw_vers->or_major =
comb_verl >> NVM_COMB_VER_SHFT;
fw_vers->or_build =
(comb_verl << NVM_COMB_VER_SHFT)
| (comb_verh >> NVM_COMB_VER_SHFT);
fw_vers->or_patch =
comb_verh & NVM_COMB_VER_MASK;
}
}
break;
default:
return;
}
hw->nvm.ops.read(hw, NVM_VERSION, 1, &fw_version);
fw_vers->eep_major = (fw_version & NVM_MAJOR_MASK)
>> NVM_MAJOR_SHIFT;
/* check for old style version format in newer images*/
if ((fw_version & NVM_NEW_DEC_MASK) == 0x0) {
eeprom_verl = (fw_version & NVM_COMB_VER_MASK);
} else {
eeprom_verl = (fw_version & NVM_MINOR_MASK)
>> NVM_MINOR_SHIFT;
}
/* Convert minor value to hex before assigning to output struct
* Val to be converted will not be higher than 99, per tool output
*/
q = eeprom_verl / NVM_HEX_CONV;
hval = q * NVM_HEX_TENS;
rem = eeprom_verl % NVM_HEX_CONV;
result = hval + rem;
fw_vers->eep_minor = result;
etrack_id:
if ((etrack_test & NVM_MAJOR_MASK) == NVM_ETRACK_VALID) {
hw->nvm.ops.read(hw, NVM_ETRACK_WORD, 1, &eeprom_verl);
hw->nvm.ops.read(hw, (NVM_ETRACK_WORD + 1), 1, &eeprom_verh);
fw_vers->etrack_id = (eeprom_verh << NVM_ETRACK_SHIFT)
| eeprom_verl;
}
}

View File

@ -0,0 +1,36 @@
/* SPDX-License-Identifier: GPL-2.0 */
/* Copyright(c) 2007 - 2018 Intel Corporation. */
#ifndef _E1000_NVM_H_
#define _E1000_NVM_H_
s32 igb_acquire_nvm(struct e1000_hw *hw);
void igb_release_nvm(struct e1000_hw *hw);
s32 igb_read_mac_addr(struct e1000_hw *hw);
s32 igb_read_part_num(struct e1000_hw *hw, u32 *part_num);
s32 igb_read_part_string(struct e1000_hw *hw, u8 *part_num,
u32 part_num_size);
s32 igb_read_nvm_eerd(struct e1000_hw *hw, u16 offset, u16 words, u16 *data);
s32 igb_read_nvm_spi(struct e1000_hw *hw, u16 offset, u16 words, u16 *data);
s32 igb_write_nvm_spi(struct e1000_hw *hw, u16 offset, u16 words, u16 *data);
s32 igb_validate_nvm_checksum(struct e1000_hw *hw);
s32 igb_update_nvm_checksum(struct e1000_hw *hw);
struct e1000_fw_version {
u32 etrack_id;
u16 eep_major;
u16 eep_minor;
u16 eep_build;
u8 invm_major;
u8 invm_minor;
u8 invm_img_type;
bool or_valid;
u16 or_major;
u16 or_build;
u16 or_patch;
};
void igb_get_fw_version(struct e1000_hw *hw, struct e1000_fw_version *fw_vers);
#endif

View File

@ -0,0 +1,782 @@
// SPDX-License-Identifier: GPL-2.0
/* Copyright(c) 2007 - 2018 Intel Corporation. */
#include <linux/if_ether.h>
#include <linux/delay.h>
#include "e1000_mac.h"
#include "e1000_nvm.h"
/**
* igb_raise_eec_clk - Raise EEPROM clock
* @hw: pointer to the HW structure
* @eecd: pointer to the EEPROM
*
* Enable/Raise the EEPROM clock bit.
**/
static void igb_raise_eec_clk(struct e1000_hw *hw, u32 *eecd)
{
*eecd = *eecd | E1000_EECD_SK;
wr32(E1000_EECD, *eecd);
wrfl();
udelay(hw->nvm.delay_usec);
}
/**
* igb_lower_eec_clk - Lower EEPROM clock
* @hw: pointer to the HW structure
* @eecd: pointer to the EEPROM
*
* Clear/Lower the EEPROM clock bit.
**/
static void igb_lower_eec_clk(struct e1000_hw *hw, u32 *eecd)
{
*eecd = *eecd & ~E1000_EECD_SK;
wr32(E1000_EECD, *eecd);
wrfl();
udelay(hw->nvm.delay_usec);
}
/**
* igb_shift_out_eec_bits - Shift data bits our to the EEPROM
* @hw: pointer to the HW structure
* @data: data to send to the EEPROM
* @count: number of bits to shift out
*
* We need to shift 'count' bits out to the EEPROM. So, the value in the
* "data" parameter will be shifted out to the EEPROM one bit at a time.
* In order to do this, "data" must be broken down into bits.
**/
static void igb_shift_out_eec_bits(struct e1000_hw *hw, u16 data, u16 count)
{
struct e1000_nvm_info *nvm = &hw->nvm;
u32 eecd = rd32(E1000_EECD);
u32 mask;
mask = 1u << (count - 1);
if (nvm->type == e1000_nvm_eeprom_spi)
eecd |= E1000_EECD_DO;
do {
eecd &= ~E1000_EECD_DI;
if (data & mask)
eecd |= E1000_EECD_DI;
wr32(E1000_EECD, eecd);
wrfl();
udelay(nvm->delay_usec);
igb_raise_eec_clk(hw, &eecd);
igb_lower_eec_clk(hw, &eecd);
mask >>= 1;
} while (mask);
eecd &= ~E1000_EECD_DI;
wr32(E1000_EECD, eecd);
}
/**
* igb_shift_in_eec_bits - Shift data bits in from the EEPROM
* @hw: pointer to the HW structure
* @count: number of bits to shift in
*
* In order to read a register from the EEPROM, we need to shift 'count' bits
* in from the EEPROM. Bits are "shifted in" by raising the clock input to
* the EEPROM (setting the SK bit), and then reading the value of the data out
* "DO" bit. During this "shifting in" process the data in "DI" bit should
* always be clear.
**/
static u16 igb_shift_in_eec_bits(struct e1000_hw *hw, u16 count)
{
u32 eecd;
u32 i;
u16 data;
eecd = rd32(E1000_EECD);
eecd &= ~(E1000_EECD_DO | E1000_EECD_DI);
data = 0;
for (i = 0; i < count; i++) {
data <<= 1;
igb_raise_eec_clk(hw, &eecd);
eecd = rd32(E1000_EECD);
eecd &= ~E1000_EECD_DI;
if (eecd & E1000_EECD_DO)
data |= 1;
igb_lower_eec_clk(hw, &eecd);
}
return data;
}
/**
* igb_poll_eerd_eewr_done - Poll for EEPROM read/write completion
* @hw: pointer to the HW structure
* @ee_reg: EEPROM flag for polling
*
* Polls the EEPROM status bit for either read or write completion based
* upon the value of 'ee_reg'.
**/
static s32 igb_poll_eerd_eewr_done(struct e1000_hw *hw, int ee_reg)
{
u32 attempts = 100000;
u32 i, reg = 0;
s32 ret_val = -E1000_ERR_NVM;
for (i = 0; i < attempts; i++) {
if (ee_reg == E1000_NVM_POLL_READ)
reg = rd32(E1000_EERD);
else
reg = rd32(E1000_EEWR);
if (reg & E1000_NVM_RW_REG_DONE) {
ret_val = 0;
break;
}
udelay(5);
}
return ret_val;
}
/**
* igb_acquire_nvm - Generic request for access to EEPROM
* @hw: pointer to the HW structure
*
* Set the EEPROM access request bit and wait for EEPROM access grant bit.
* Return successful if access grant bit set, else clear the request for
* EEPROM access and return -E1000_ERR_NVM (-1).
**/
s32 igb_acquire_nvm(struct e1000_hw *hw)
{
u32 eecd = rd32(E1000_EECD);
s32 timeout = E1000_NVM_GRANT_ATTEMPTS;
s32 ret_val = 0;
wr32(E1000_EECD, eecd | E1000_EECD_REQ);
eecd = rd32(E1000_EECD);
while (timeout) {
if (eecd & E1000_EECD_GNT)
break;
udelay(5);
eecd = rd32(E1000_EECD);
timeout--;
}
if (!timeout) {
eecd &= ~E1000_EECD_REQ;
wr32(E1000_EECD, eecd);
hw_dbg("Could not acquire NVM grant\n");
ret_val = -E1000_ERR_NVM;
}
return ret_val;
}
/**
* igb_standby_nvm - Return EEPROM to standby state
* @hw: pointer to the HW structure
*
* Return the EEPROM to a standby state.
**/
static void igb_standby_nvm(struct e1000_hw *hw)
{
struct e1000_nvm_info *nvm = &hw->nvm;
u32 eecd = rd32(E1000_EECD);
if (nvm->type == e1000_nvm_eeprom_spi) {
/* Toggle CS to flush commands */
eecd |= E1000_EECD_CS;
wr32(E1000_EECD, eecd);
wrfl();
udelay(nvm->delay_usec);
eecd &= ~E1000_EECD_CS;
wr32(E1000_EECD, eecd);
wrfl();
udelay(nvm->delay_usec);
}
}
/**
* e1000_stop_nvm - Terminate EEPROM command
* @hw: pointer to the HW structure
*
* Terminates the current command by inverting the EEPROM's chip select pin.
**/
static void e1000_stop_nvm(struct e1000_hw *hw)
{
u32 eecd;
eecd = rd32(E1000_EECD);
if (hw->nvm.type == e1000_nvm_eeprom_spi) {
/* Pull CS high */
eecd |= E1000_EECD_CS;
igb_lower_eec_clk(hw, &eecd);
}
}
/**
* igb_release_nvm - Release exclusive access to EEPROM
* @hw: pointer to the HW structure
*
* Stop any current commands to the EEPROM and clear the EEPROM request bit.
**/
void igb_release_nvm(struct e1000_hw *hw)
{
u32 eecd;
e1000_stop_nvm(hw);
eecd = rd32(E1000_EECD);
eecd &= ~E1000_EECD_REQ;
wr32(E1000_EECD, eecd);
}
/**
* igb_ready_nvm_eeprom - Prepares EEPROM for read/write
* @hw: pointer to the HW structure
*
* Setups the EEPROM for reading and writing.
**/
static s32 igb_ready_nvm_eeprom(struct e1000_hw *hw)
{
struct e1000_nvm_info *nvm = &hw->nvm;
u32 eecd = rd32(E1000_EECD);
s32 ret_val = 0;
u16 timeout = 0;
u8 spi_stat_reg;
if (nvm->type == e1000_nvm_eeprom_spi) {
/* Clear SK and CS */
eecd &= ~(E1000_EECD_CS | E1000_EECD_SK);
wr32(E1000_EECD, eecd);
wrfl();
udelay(1);
timeout = NVM_MAX_RETRY_SPI;
/* Read "Status Register" repeatedly until the LSB is cleared.
* The EEPROM will signal that the command has been completed
* by clearing bit 0 of the internal status register. If it's
* not cleared within 'timeout', then error out.
*/
while (timeout) {
igb_shift_out_eec_bits(hw, NVM_RDSR_OPCODE_SPI,
hw->nvm.opcode_bits);
spi_stat_reg = (u8)igb_shift_in_eec_bits(hw, 8);
if (!(spi_stat_reg & NVM_STATUS_RDY_SPI))
break;
udelay(5);
igb_standby_nvm(hw);
timeout--;
}
if (!timeout) {
hw_dbg("SPI NVM Status error\n");
ret_val = -E1000_ERR_NVM;
goto out;
}
}
out:
return ret_val;
}
/**
* igb_read_nvm_spi - Read EEPROM's using SPI
* @hw: pointer to the HW structure
* @offset: offset of word in the EEPROM to read
* @words: number of words to read
* @data: word read from the EEPROM
*
* Reads a 16 bit word from the EEPROM.
**/
s32 igb_read_nvm_spi(struct e1000_hw *hw, u16 offset, u16 words, u16 *data)
{
struct e1000_nvm_info *nvm = &hw->nvm;
u32 i = 0;
s32 ret_val;
u16 word_in;
u8 read_opcode = NVM_READ_OPCODE_SPI;
/* A check for invalid values: offset too large, too many words,
* and not enough words.
*/
if ((offset >= nvm->word_size) || (words > (nvm->word_size - offset)) ||
(words == 0)) {
hw_dbg("nvm parameter(s) out of bounds\n");
ret_val = -E1000_ERR_NVM;
goto out;
}
ret_val = nvm->ops.acquire(hw);
if (ret_val)
goto out;
ret_val = igb_ready_nvm_eeprom(hw);
if (ret_val)
goto release;
igb_standby_nvm(hw);
if ((nvm->address_bits == 8) && (offset >= 128))
read_opcode |= NVM_A8_OPCODE_SPI;
/* Send the READ command (opcode + addr) */
igb_shift_out_eec_bits(hw, read_opcode, nvm->opcode_bits);
igb_shift_out_eec_bits(hw, (u16)(offset*2), nvm->address_bits);
/* Read the data. SPI NVMs increment the address with each byte
* read and will roll over if reading beyond the end. This allows
* us to read the whole NVM from any offset
*/
for (i = 0; i < words; i++) {
word_in = igb_shift_in_eec_bits(hw, 16);
data[i] = (word_in >> 8) | (word_in << 8);
}
release:
nvm->ops.release(hw);
out:
return ret_val;
}
/**
* igb_read_nvm_eerd - Reads EEPROM using EERD register
* @hw: pointer to the HW structure
* @offset: offset of word in the EEPROM to read
* @words: number of words to read
* @data: word read from the EEPROM
*
* Reads a 16 bit word from the EEPROM using the EERD register.
**/
s32 igb_read_nvm_eerd(struct e1000_hw *hw, u16 offset, u16 words, u16 *data)
{
struct e1000_nvm_info *nvm = &hw->nvm;
u32 i, eerd = 0;
s32 ret_val = 0;
/* A check for invalid values: offset too large, too many words,
* and not enough words.
*/
if ((offset >= nvm->word_size) || (words > (nvm->word_size - offset)) ||
(words == 0)) {
hw_dbg("nvm parameter(s) out of bounds\n");
ret_val = -E1000_ERR_NVM;
goto out;
}
for (i = 0; i < words; i++) {
eerd = ((offset+i) << E1000_NVM_RW_ADDR_SHIFT) +
E1000_NVM_RW_REG_START;
wr32(E1000_EERD, eerd);
ret_val = igb_poll_eerd_eewr_done(hw, E1000_NVM_POLL_READ);
if (ret_val)
break;
data[i] = (rd32(E1000_EERD) >>
E1000_NVM_RW_REG_DATA);
}
out:
return ret_val;
}
/**
* igb_write_nvm_spi - Write to EEPROM using SPI
* @hw: pointer to the HW structure
* @offset: offset within the EEPROM to be written to
* @words: number of words to write
* @data: 16 bit word(s) to be written to the EEPROM
*
* Writes data to EEPROM at offset using SPI interface.
*
* If e1000_update_nvm_checksum is not called after this function , the
* EEPROM will most likley contain an invalid checksum.
**/
s32 igb_write_nvm_spi(struct e1000_hw *hw, u16 offset, u16 words, u16 *data)
{
struct e1000_nvm_info *nvm = &hw->nvm;
s32 ret_val = -E1000_ERR_NVM;
u16 widx = 0;
/* A check for invalid values: offset too large, too many words,
* and not enough words.
*/
if ((offset >= nvm->word_size) || (words > (nvm->word_size - offset)) ||
(words == 0)) {
hw_dbg("nvm parameter(s) out of bounds\n");
return ret_val;
}
while (widx < words) {
u8 write_opcode = NVM_WRITE_OPCODE_SPI;
ret_val = nvm->ops.acquire(hw);
if (ret_val)
return ret_val;
ret_val = igb_ready_nvm_eeprom(hw);
if (ret_val) {
nvm->ops.release(hw);
return ret_val;
}
igb_standby_nvm(hw);
/* Send the WRITE ENABLE command (8 bit opcode) */
igb_shift_out_eec_bits(hw, NVM_WREN_OPCODE_SPI,
nvm->opcode_bits);
igb_standby_nvm(hw);
/* Some SPI eeproms use the 8th address bit embedded in the
* opcode
*/
if ((nvm->address_bits == 8) && (offset >= 128))
write_opcode |= NVM_A8_OPCODE_SPI;
/* Send the Write command (8-bit opcode + addr) */
igb_shift_out_eec_bits(hw, write_opcode, nvm->opcode_bits);
igb_shift_out_eec_bits(hw, (u16)((offset + widx) * 2),
nvm->address_bits);
/* Loop to allow for up to whole page write of eeprom */
while (widx < words) {
u16 word_out = data[widx];
word_out = (word_out >> 8) | (word_out << 8);
igb_shift_out_eec_bits(hw, word_out, 16);
widx++;
if ((((offset + widx) * 2) % nvm->page_size) == 0) {
igb_standby_nvm(hw);
break;
}
}
usleep_range(1000, 2000);
nvm->ops.release(hw);
}
return ret_val;
}
/**
* igb_read_part_string - Read device part number
* @hw: pointer to the HW structure
* @part_num: pointer to device part number
* @part_num_size: size of part number buffer
*
* Reads the product board assembly (PBA) number from the EEPROM and stores
* the value in part_num.
**/
s32 igb_read_part_string(struct e1000_hw *hw, u8 *part_num, u32 part_num_size)
{
s32 ret_val;
u16 nvm_data;
u16 pointer;
u16 offset;
u16 length;
if (part_num == NULL) {
hw_dbg("PBA string buffer was null\n");
ret_val = E1000_ERR_INVALID_ARGUMENT;
goto out;
}
ret_val = hw->nvm.ops.read(hw, NVM_PBA_OFFSET_0, 1, &nvm_data);
if (ret_val) {
hw_dbg("NVM Read Error\n");
goto out;
}
ret_val = hw->nvm.ops.read(hw, NVM_PBA_OFFSET_1, 1, &pointer);
if (ret_val) {
hw_dbg("NVM Read Error\n");
goto out;
}
/* if nvm_data is not ptr guard the PBA must be in legacy format which
* means pointer is actually our second data word for the PBA number
* and we can decode it into an ascii string
*/
if (nvm_data != NVM_PBA_PTR_GUARD) {
hw_dbg("NVM PBA number is not stored as string\n");
/* we will need 11 characters to store the PBA */
if (part_num_size < 11) {
hw_dbg("PBA string buffer too small\n");
return E1000_ERR_NO_SPACE;
}
/* extract hex string from data and pointer */
part_num[0] = (nvm_data >> 12) & 0xF;
part_num[1] = (nvm_data >> 8) & 0xF;
part_num[2] = (nvm_data >> 4) & 0xF;
part_num[3] = nvm_data & 0xF;
part_num[4] = (pointer >> 12) & 0xF;
part_num[5] = (pointer >> 8) & 0xF;
part_num[6] = '-';
part_num[7] = 0;
part_num[8] = (pointer >> 4) & 0xF;
part_num[9] = pointer & 0xF;
/* put a null character on the end of our string */
part_num[10] = '\0';
/* switch all the data but the '-' to hex char */
for (offset = 0; offset < 10; offset++) {
if (part_num[offset] < 0xA)
part_num[offset] += '0';
else if (part_num[offset] < 0x10)
part_num[offset] += 'A' - 0xA;
}
goto out;
}
ret_val = hw->nvm.ops.read(hw, pointer, 1, &length);
if (ret_val) {
hw_dbg("NVM Read Error\n");
goto out;
}
if (length == 0xFFFF || length == 0) {
hw_dbg("NVM PBA number section invalid length\n");
ret_val = E1000_ERR_NVM_PBA_SECTION;
goto out;
}
/* check if part_num buffer is big enough */
if (part_num_size < (((u32)length * 2) - 1)) {
hw_dbg("PBA string buffer too small\n");
ret_val = E1000_ERR_NO_SPACE;
goto out;
}
/* trim pba length from start of string */
pointer++;
length--;
for (offset = 0; offset < length; offset++) {
ret_val = hw->nvm.ops.read(hw, pointer + offset, 1, &nvm_data);
if (ret_val) {
hw_dbg("NVM Read Error\n");
goto out;
}
part_num[offset * 2] = (u8)(nvm_data >> 8);
part_num[(offset * 2) + 1] = (u8)(nvm_data & 0xFF);
}
part_num[offset * 2] = '\0';
out:
return ret_val;
}
/**
* igb_read_mac_addr - Read device MAC address
* @hw: pointer to the HW structure
*
* Reads the device MAC address from the EEPROM and stores the value.
* Since devices with two ports use the same EEPROM, we increment the
* last bit in the MAC address for the second port.
**/
s32 igb_read_mac_addr(struct e1000_hw *hw)
{
u32 rar_high;
u32 rar_low;
u16 i;
rar_high = rd32(E1000_RAH(0));
rar_low = rd32(E1000_RAL(0));
for (i = 0; i < E1000_RAL_MAC_ADDR_LEN; i++)
hw->mac.perm_addr[i] = (u8)(rar_low >> (i*8));
for (i = 0; i < E1000_RAH_MAC_ADDR_LEN; i++)
hw->mac.perm_addr[i+4] = (u8)(rar_high >> (i*8));
for (i = 0; i < ETH_ALEN; i++)
hw->mac.addr[i] = hw->mac.perm_addr[i];
return 0;
}
/**
* igb_validate_nvm_checksum - Validate EEPROM checksum
* @hw: pointer to the HW structure
*
* Calculates the EEPROM checksum by reading/adding each word of the EEPROM
* and then verifies that the sum of the EEPROM is equal to 0xBABA.
**/
s32 igb_validate_nvm_checksum(struct e1000_hw *hw)
{
s32 ret_val = 0;
u16 checksum = 0;
u16 i, nvm_data;
for (i = 0; i < (NVM_CHECKSUM_REG + 1); i++) {
ret_val = hw->nvm.ops.read(hw, i, 1, &nvm_data);
if (ret_val) {
hw_dbg("NVM Read Error\n");
goto out;
}
checksum += nvm_data;
}
if (checksum != (u16) NVM_SUM) {
hw_dbg("NVM Checksum Invalid\n");
ret_val = -E1000_ERR_NVM;
goto out;
}
out:
return ret_val;
}
/**
* igb_update_nvm_checksum - Update EEPROM checksum
* @hw: pointer to the HW structure
*
* Updates the EEPROM checksum by reading/adding each word of the EEPROM
* up to the checksum. Then calculates the EEPROM checksum and writes the
* value to the EEPROM.
**/
s32 igb_update_nvm_checksum(struct e1000_hw *hw)
{
s32 ret_val;
u16 checksum = 0;
u16 i, nvm_data;
for (i = 0; i < NVM_CHECKSUM_REG; i++) {
ret_val = hw->nvm.ops.read(hw, i, 1, &nvm_data);
if (ret_val) {
hw_dbg("NVM Read Error while updating checksum.\n");
goto out;
}
checksum += nvm_data;
}
checksum = (u16) NVM_SUM - checksum;
ret_val = hw->nvm.ops.write(hw, NVM_CHECKSUM_REG, 1, &checksum);
if (ret_val)
hw_dbg("NVM Write Error while updating checksum.\n");
out:
return ret_val;
}
/**
* igb_get_fw_version - Get firmware version information
* @hw: pointer to the HW structure
* @fw_vers: pointer to output structure
*
* unsupported MAC types will return all 0 version structure
**/
void igb_get_fw_version(struct e1000_hw *hw, struct e1000_fw_version *fw_vers)
{
u16 eeprom_verh, eeprom_verl, etrack_test, fw_version;
u8 q, hval, rem, result;
u16 comb_verh, comb_verl, comb_offset;
memset(fw_vers, 0, sizeof(struct e1000_fw_version));
/* basic eeprom version numbers and bits used vary by part and by tool
* used to create the nvm images. Check which data format we have.
*/
hw->nvm.ops.read(hw, NVM_ETRACK_HIWORD, 1, &etrack_test);
switch (hw->mac.type) {
case e1000_i211:
igb_read_invm_version(hw, fw_vers);
return;
case e1000_82575:
case e1000_82576:
case e1000_82580:
/* Use this format, unless EETRACK ID exists,
* then use alternate format
*/
if ((etrack_test & NVM_MAJOR_MASK) != NVM_ETRACK_VALID) {
hw->nvm.ops.read(hw, NVM_VERSION, 1, &fw_version);
fw_vers->eep_major = (fw_version & NVM_MAJOR_MASK)
>> NVM_MAJOR_SHIFT;
fw_vers->eep_minor = (fw_version & NVM_MINOR_MASK)
>> NVM_MINOR_SHIFT;
fw_vers->eep_build = (fw_version & NVM_IMAGE_ID_MASK);
goto etrack_id;
}
break;
case e1000_i210:
if (!(igb_get_flash_presence_i210(hw))) {
igb_read_invm_version(hw, fw_vers);
return;
}
fallthrough;
case e1000_i350:
/* find combo image version */
hw->nvm.ops.read(hw, NVM_COMB_VER_PTR, 1, &comb_offset);
if ((comb_offset != 0x0) &&
(comb_offset != NVM_VER_INVALID)) {
hw->nvm.ops.read(hw, (NVM_COMB_VER_OFF + comb_offset
+ 1), 1, &comb_verh);
hw->nvm.ops.read(hw, (NVM_COMB_VER_OFF + comb_offset),
1, &comb_verl);
/* get Option Rom version if it exists and is valid */
if ((comb_verh && comb_verl) &&
((comb_verh != NVM_VER_INVALID) &&
(comb_verl != NVM_VER_INVALID))) {
fw_vers->or_valid = true;
fw_vers->or_major =
comb_verl >> NVM_COMB_VER_SHFT;
fw_vers->or_build =
(comb_verl << NVM_COMB_VER_SHFT)
| (comb_verh >> NVM_COMB_VER_SHFT);
fw_vers->or_patch =
comb_verh & NVM_COMB_VER_MASK;
}
}
break;
default:
return;
}
hw->nvm.ops.read(hw, NVM_VERSION, 1, &fw_version);
fw_vers->eep_major = (fw_version & NVM_MAJOR_MASK)
>> NVM_MAJOR_SHIFT;
/* check for old style version format in newer images*/
if ((fw_version & NVM_NEW_DEC_MASK) == 0x0) {
eeprom_verl = (fw_version & NVM_COMB_VER_MASK);
} else {
eeprom_verl = (fw_version & NVM_MINOR_MASK)
>> NVM_MINOR_SHIFT;
}
/* Convert minor value to hex before assigning to output struct
* Val to be converted will not be higher than 99, per tool output
*/
q = eeprom_verl / NVM_HEX_CONV;
hval = q * NVM_HEX_TENS;
rem = eeprom_verl % NVM_HEX_CONV;
result = hval + rem;
fw_vers->eep_minor = result;
etrack_id:
if ((etrack_test & NVM_MAJOR_MASK) == NVM_ETRACK_VALID) {
hw->nvm.ops.read(hw, NVM_ETRACK_WORD, 1, &eeprom_verl);
hw->nvm.ops.read(hw, (NVM_ETRACK_WORD + 1), 1, &eeprom_verh);
fw_vers->etrack_id = (eeprom_verh << NVM_ETRACK_SHIFT)
| eeprom_verl;
}
}

View File

@ -0,0 +1,36 @@
/* SPDX-License-Identifier: GPL-2.0 */
/* Copyright(c) 2007 - 2018 Intel Corporation. */
#ifndef _E1000_NVM_H_
#define _E1000_NVM_H_
s32 igb_acquire_nvm(struct e1000_hw *hw);
void igb_release_nvm(struct e1000_hw *hw);
s32 igb_read_mac_addr(struct e1000_hw *hw);
s32 igb_read_part_num(struct e1000_hw *hw, u32 *part_num);
s32 igb_read_part_string(struct e1000_hw *hw, u8 *part_num,
u32 part_num_size);
s32 igb_read_nvm_eerd(struct e1000_hw *hw, u16 offset, u16 words, u16 *data);
s32 igb_read_nvm_spi(struct e1000_hw *hw, u16 offset, u16 words, u16 *data);
s32 igb_write_nvm_spi(struct e1000_hw *hw, u16 offset, u16 words, u16 *data);
s32 igb_validate_nvm_checksum(struct e1000_hw *hw);
s32 igb_update_nvm_checksum(struct e1000_hw *hw);
struct e1000_fw_version {
u32 etrack_id;
u16 eep_major;
u16 eep_minor;
u16 eep_build;
u8 invm_major;
u8 invm_minor;
u8 invm_img_type;
bool or_valid;
u16 or_major;
u16 or_build;
u16 or_patch;
};
void igb_get_fw_version(struct e1000_hw *hw, struct e1000_fw_version *fw_vers);
#endif

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,145 @@
/* SPDX-License-Identifier: GPL-2.0 */
/* Copyright(c) 2007 - 2018 Intel Corporation. */
#ifndef _E1000_PHY_H_
#define _E1000_PHY_H_
enum e1000_ms_type {
e1000_ms_hw_default = 0,
e1000_ms_force_master,
e1000_ms_force_slave,
e1000_ms_auto
};
enum e1000_smart_speed {
e1000_smart_speed_default = 0,
e1000_smart_speed_on,
e1000_smart_speed_off
};
s32 igb_check_downshift(struct e1000_hw *hw);
s32 igb_check_reset_block(struct e1000_hw *hw);
s32 igb_copper_link_setup_igp(struct e1000_hw *hw);
s32 igb_copper_link_setup_m88(struct e1000_hw *hw);
s32 igb_copper_link_setup_m88_gen2(struct e1000_hw *hw);
s32 igb_phy_force_speed_duplex_igp(struct e1000_hw *hw);
s32 igb_phy_force_speed_duplex_m88(struct e1000_hw *hw);
s32 igb_get_cable_length_m88(struct e1000_hw *hw);
s32 igb_get_cable_length_m88_gen2(struct e1000_hw *hw);
s32 igb_get_cable_length_igp_2(struct e1000_hw *hw);
s32 igb_get_phy_id(struct e1000_hw *hw);
s32 igb_get_phy_info_igp(struct e1000_hw *hw);
s32 igb_get_phy_info_m88(struct e1000_hw *hw);
s32 igb_phy_sw_reset(struct e1000_hw *hw);
s32 igb_phy_hw_reset(struct e1000_hw *hw);
s32 igb_read_phy_reg_igp(struct e1000_hw *hw, u32 offset, u16 *data);
s32 igb_set_d3_lplu_state(struct e1000_hw *hw, bool active);
s32 igb_setup_copper_link(struct e1000_hw *hw);
s32 igb_write_phy_reg_igp(struct e1000_hw *hw, u32 offset, u16 data);
s32 igb_phy_has_link(struct e1000_hw *hw, u32 iterations,
u32 usec_interval, bool *success);
void igb_power_up_phy_copper(struct e1000_hw *hw);
void igb_power_down_phy_copper(struct e1000_hw *hw);
s32 igb_phy_init_script_igp3(struct e1000_hw *hw);
s32 igb_initialize_M88E1512_phy(struct e1000_hw *hw);
s32 igb_initialize_M88E1543_phy(struct e1000_hw *hw);
s32 igb_read_phy_reg_mdic(struct e1000_hw *hw, u32 offset, u16 *data);
s32 igb_write_phy_reg_mdic(struct e1000_hw *hw, u32 offset, u16 data);
s32 igb_read_phy_reg_i2c(struct e1000_hw *hw, u32 offset, u16 *data);
s32 igb_write_phy_reg_i2c(struct e1000_hw *hw, u32 offset, u16 data);
s32 igb_read_sfp_data_byte(struct e1000_hw *hw, u16 offset, u8 *data);
s32 igb_copper_link_setup_82580(struct e1000_hw *hw);
s32 igb_get_phy_info_82580(struct e1000_hw *hw);
s32 igb_phy_force_speed_duplex_82580(struct e1000_hw *hw);
s32 igb_get_cable_length_82580(struct e1000_hw *hw);
s32 igb_read_phy_reg_82580(struct e1000_hw *hw, u32 offset, u16 *data);
s32 igb_write_phy_reg_82580(struct e1000_hw *hw, u32 offset, u16 data);
s32 igb_check_polarity_m88(struct e1000_hw *hw);
/* IGP01E1000 Specific Registers */
#define IGP01E1000_PHY_PORT_CONFIG 0x10 /* Port Config */
#define IGP01E1000_PHY_PORT_STATUS 0x11 /* Status */
#define IGP01E1000_PHY_PORT_CTRL 0x12 /* Control */
#define IGP01E1000_PHY_LINK_HEALTH 0x13 /* PHY Link Health */
#define IGP02E1000_PHY_POWER_MGMT 0x19 /* Power Management */
#define IGP01E1000_PHY_PAGE_SELECT 0x1F /* Page Select */
#define IGP01E1000_PHY_PCS_INIT_REG 0x00B4
#define IGP01E1000_PHY_POLARITY_MASK 0x0078
#define IGP01E1000_PSCR_AUTO_MDIX 0x1000
#define IGP01E1000_PSCR_FORCE_MDI_MDIX 0x2000 /* 0=MDI, 1=MDIX */
#define IGP01E1000_PSCFR_SMART_SPEED 0x0080
#define I82580_ADDR_REG 16
#define I82580_CFG_REG 22
#define I82580_CFG_ASSERT_CRS_ON_TX BIT(15)
#define I82580_CFG_ENABLE_DOWNSHIFT (3u << 10) /* auto downshift 100/10 */
#define I82580_CTRL_REG 23
#define I82580_CTRL_DOWNSHIFT_MASK (7u << 10)
/* 82580 specific PHY registers */
#define I82580_PHY_CTRL_2 18
#define I82580_PHY_LBK_CTRL 19
#define I82580_PHY_STATUS_2 26
#define I82580_PHY_DIAG_STATUS 31
/* I82580 PHY Status 2 */
#define I82580_PHY_STATUS2_REV_POLARITY 0x0400
#define I82580_PHY_STATUS2_MDIX 0x0800
#define I82580_PHY_STATUS2_SPEED_MASK 0x0300
#define I82580_PHY_STATUS2_SPEED_1000MBPS 0x0200
#define I82580_PHY_STATUS2_SPEED_100MBPS 0x0100
/* I82580 PHY Control 2 */
#define I82580_PHY_CTRL2_MANUAL_MDIX 0x0200
#define I82580_PHY_CTRL2_AUTO_MDI_MDIX 0x0400
#define I82580_PHY_CTRL2_MDIX_CFG_MASK 0x0600
/* I82580 PHY Diagnostics Status */
#define I82580_DSTATUS_CABLE_LENGTH 0x03FC
#define I82580_DSTATUS_CABLE_LENGTH_SHIFT 2
/* 82580 PHY Power Management */
#define E1000_82580_PHY_POWER_MGMT 0xE14
#define E1000_82580_PM_SPD 0x0001 /* Smart Power Down */
#define E1000_82580_PM_D0_LPLU 0x0002 /* For D0a states */
#define E1000_82580_PM_D3_LPLU 0x0004 /* For all other states */
#define E1000_82580_PM_GO_LINKD 0x0020 /* Go Link Disconnect */
/* Enable flexible speed on link-up */
#define IGP02E1000_PM_D0_LPLU 0x0002 /* For D0a states */
#define IGP02E1000_PM_D3_LPLU 0x0004 /* For all other states */
#define IGP01E1000_PLHR_SS_DOWNGRADE 0x8000
#define IGP01E1000_PSSR_POLARITY_REVERSED 0x0002
#define IGP01E1000_PSSR_MDIX 0x0800
#define IGP01E1000_PSSR_SPEED_MASK 0xC000
#define IGP01E1000_PSSR_SPEED_1000MBPS 0xC000
#define IGP02E1000_PHY_CHANNEL_NUM 4
#define IGP02E1000_PHY_AGC_A 0x11B1
#define IGP02E1000_PHY_AGC_B 0x12B1
#define IGP02E1000_PHY_AGC_C 0x14B1
#define IGP02E1000_PHY_AGC_D 0x18B1
#define IGP02E1000_AGC_LENGTH_SHIFT 9 /* Course - 15:13, Fine - 12:9 */
#define IGP02E1000_AGC_LENGTH_MASK 0x7F
#define IGP02E1000_AGC_RANGE 15
#define E1000_CABLE_LENGTH_UNDEFINED 0xFF
/* SFP modules ID memory locations */
#define E1000_SFF_IDENTIFIER_OFFSET 0x00
#define E1000_SFF_IDENTIFIER_SFF 0x02
#define E1000_SFF_IDENTIFIER_SFP 0x03
#define E1000_SFF_ETH_FLAGS_OFFSET 0x06
/* Flags for SFP modules compatible with ETH up to 1Gb */
struct e1000_sfp_flags {
u8 e1000_base_sx:1;
u8 e1000_base_lx:1;
u8 e1000_base_cx:1;
u8 e1000_base_t:1;
u8 e100_base_lx:1;
u8 e100_base_fx:1;
u8 e10_base_bx10:1;
u8 e10_base_px:1;
};
#endif

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,145 @@
/* SPDX-License-Identifier: GPL-2.0 */
/* Copyright(c) 2007 - 2018 Intel Corporation. */
#ifndef _E1000_PHY_H_
#define _E1000_PHY_H_
enum e1000_ms_type {
e1000_ms_hw_default = 0,
e1000_ms_force_master,
e1000_ms_force_slave,
e1000_ms_auto
};
enum e1000_smart_speed {
e1000_smart_speed_default = 0,
e1000_smart_speed_on,
e1000_smart_speed_off
};
s32 igb_check_downshift(struct e1000_hw *hw);
s32 igb_check_reset_block(struct e1000_hw *hw);
s32 igb_copper_link_setup_igp(struct e1000_hw *hw);
s32 igb_copper_link_setup_m88(struct e1000_hw *hw);
s32 igb_copper_link_setup_m88_gen2(struct e1000_hw *hw);
s32 igb_phy_force_speed_duplex_igp(struct e1000_hw *hw);
s32 igb_phy_force_speed_duplex_m88(struct e1000_hw *hw);
s32 igb_get_cable_length_m88(struct e1000_hw *hw);
s32 igb_get_cable_length_m88_gen2(struct e1000_hw *hw);
s32 igb_get_cable_length_igp_2(struct e1000_hw *hw);
s32 igb_get_phy_id(struct e1000_hw *hw);
s32 igb_get_phy_info_igp(struct e1000_hw *hw);
s32 igb_get_phy_info_m88(struct e1000_hw *hw);
s32 igb_phy_sw_reset(struct e1000_hw *hw);
s32 igb_phy_hw_reset(struct e1000_hw *hw);
s32 igb_read_phy_reg_igp(struct e1000_hw *hw, u32 offset, u16 *data);
s32 igb_set_d3_lplu_state(struct e1000_hw *hw, bool active);
s32 igb_setup_copper_link(struct e1000_hw *hw);
s32 igb_write_phy_reg_igp(struct e1000_hw *hw, u32 offset, u16 data);
s32 igb_phy_has_link(struct e1000_hw *hw, u32 iterations,
u32 usec_interval, bool *success);
void igb_power_up_phy_copper(struct e1000_hw *hw);
void igb_power_down_phy_copper(struct e1000_hw *hw);
s32 igb_phy_init_script_igp3(struct e1000_hw *hw);
s32 igb_initialize_M88E1512_phy(struct e1000_hw *hw);
s32 igb_initialize_M88E1543_phy(struct e1000_hw *hw);
s32 igb_read_phy_reg_mdic(struct e1000_hw *hw, u32 offset, u16 *data);
s32 igb_write_phy_reg_mdic(struct e1000_hw *hw, u32 offset, u16 data);
s32 igb_read_phy_reg_i2c(struct e1000_hw *hw, u32 offset, u16 *data);
s32 igb_write_phy_reg_i2c(struct e1000_hw *hw, u32 offset, u16 data);
s32 igb_read_sfp_data_byte(struct e1000_hw *hw, u16 offset, u8 *data);
s32 igb_copper_link_setup_82580(struct e1000_hw *hw);
s32 igb_get_phy_info_82580(struct e1000_hw *hw);
s32 igb_phy_force_speed_duplex_82580(struct e1000_hw *hw);
s32 igb_get_cable_length_82580(struct e1000_hw *hw);
s32 igb_read_phy_reg_82580(struct e1000_hw *hw, u32 offset, u16 *data);
s32 igb_write_phy_reg_82580(struct e1000_hw *hw, u32 offset, u16 data);
s32 igb_check_polarity_m88(struct e1000_hw *hw);
/* IGP01E1000 Specific Registers */
#define IGP01E1000_PHY_PORT_CONFIG 0x10 /* Port Config */
#define IGP01E1000_PHY_PORT_STATUS 0x11 /* Status */
#define IGP01E1000_PHY_PORT_CTRL 0x12 /* Control */
#define IGP01E1000_PHY_LINK_HEALTH 0x13 /* PHY Link Health */
#define IGP02E1000_PHY_POWER_MGMT 0x19 /* Power Management */
#define IGP01E1000_PHY_PAGE_SELECT 0x1F /* Page Select */
#define IGP01E1000_PHY_PCS_INIT_REG 0x00B4
#define IGP01E1000_PHY_POLARITY_MASK 0x0078
#define IGP01E1000_PSCR_AUTO_MDIX 0x1000
#define IGP01E1000_PSCR_FORCE_MDI_MDIX 0x2000 /* 0=MDI, 1=MDIX */
#define IGP01E1000_PSCFR_SMART_SPEED 0x0080
#define I82580_ADDR_REG 16
#define I82580_CFG_REG 22
#define I82580_CFG_ASSERT_CRS_ON_TX BIT(15)
#define I82580_CFG_ENABLE_DOWNSHIFT (3u << 10) /* auto downshift 100/10 */
#define I82580_CTRL_REG 23
#define I82580_CTRL_DOWNSHIFT_MASK (7u << 10)
/* 82580 specific PHY registers */
#define I82580_PHY_CTRL_2 18
#define I82580_PHY_LBK_CTRL 19
#define I82580_PHY_STATUS_2 26
#define I82580_PHY_DIAG_STATUS 31
/* I82580 PHY Status 2 */
#define I82580_PHY_STATUS2_REV_POLARITY 0x0400
#define I82580_PHY_STATUS2_MDIX 0x0800
#define I82580_PHY_STATUS2_SPEED_MASK 0x0300
#define I82580_PHY_STATUS2_SPEED_1000MBPS 0x0200
#define I82580_PHY_STATUS2_SPEED_100MBPS 0x0100
/* I82580 PHY Control 2 */
#define I82580_PHY_CTRL2_MANUAL_MDIX 0x0200
#define I82580_PHY_CTRL2_AUTO_MDI_MDIX 0x0400
#define I82580_PHY_CTRL2_MDIX_CFG_MASK 0x0600
/* I82580 PHY Diagnostics Status */
#define I82580_DSTATUS_CABLE_LENGTH 0x03FC
#define I82580_DSTATUS_CABLE_LENGTH_SHIFT 2
/* 82580 PHY Power Management */
#define E1000_82580_PHY_POWER_MGMT 0xE14
#define E1000_82580_PM_SPD 0x0001 /* Smart Power Down */
#define E1000_82580_PM_D0_LPLU 0x0002 /* For D0a states */
#define E1000_82580_PM_D3_LPLU 0x0004 /* For all other states */
#define E1000_82580_PM_GO_LINKD 0x0020 /* Go Link Disconnect */
/* Enable flexible speed on link-up */
#define IGP02E1000_PM_D0_LPLU 0x0002 /* For D0a states */
#define IGP02E1000_PM_D3_LPLU 0x0004 /* For all other states */
#define IGP01E1000_PLHR_SS_DOWNGRADE 0x8000
#define IGP01E1000_PSSR_POLARITY_REVERSED 0x0002
#define IGP01E1000_PSSR_MDIX 0x0800
#define IGP01E1000_PSSR_SPEED_MASK 0xC000
#define IGP01E1000_PSSR_SPEED_1000MBPS 0xC000
#define IGP02E1000_PHY_CHANNEL_NUM 4
#define IGP02E1000_PHY_AGC_A 0x11B1
#define IGP02E1000_PHY_AGC_B 0x12B1
#define IGP02E1000_PHY_AGC_C 0x14B1
#define IGP02E1000_PHY_AGC_D 0x18B1
#define IGP02E1000_AGC_LENGTH_SHIFT 9 /* Course - 15:13, Fine - 12:9 */
#define IGP02E1000_AGC_LENGTH_MASK 0x7F
#define IGP02E1000_AGC_RANGE 15
#define E1000_CABLE_LENGTH_UNDEFINED 0xFF
/* SFP modules ID memory locations */
#define E1000_SFF_IDENTIFIER_OFFSET 0x00
#define E1000_SFF_IDENTIFIER_SFF 0x02
#define E1000_SFF_IDENTIFIER_SFP 0x03
#define E1000_SFF_ETH_FLAGS_OFFSET 0x06
/* Flags for SFP modules compatible with ETH up to 1Gb */
struct e1000_sfp_flags {
u8 e1000_base_sx:1;
u8 e1000_base_lx:1;
u8 e1000_base_cx:1;
u8 e1000_base_t:1;
u8 e100_base_lx:1;
u8 e100_base_fx:1;
u8 e10_base_bx10:1;
u8 e10_base_px:1;
};
#endif

View File

@ -0,0 +1,418 @@
/* SPDX-License-Identifier: GPL-2.0 */
/* Copyright(c) 2007 - 2018 Intel Corporation. */
#ifndef _E1000_REGS_H_
#define _E1000_REGS_H_
#define E1000_CTRL 0x00000 /* Device Control - RW */
#define E1000_STATUS 0x00008 /* Device Status - RO */
#define E1000_EECD 0x00010 /* EEPROM/Flash Control - RW */
#define E1000_EERD 0x00014 /* EEPROM Read - RW */
#define E1000_CTRL_EXT 0x00018 /* Extended Device Control - RW */
#define E1000_MDIC 0x00020 /* MDI Control - RW */
#define E1000_MDICNFG 0x00E04 /* MDI Config - RW */
#define E1000_SCTL 0x00024 /* SerDes Control - RW */
#define E1000_FCAL 0x00028 /* Flow Control Address Low - RW */
#define E1000_FCAH 0x0002C /* Flow Control Address High -RW */
#define E1000_FCT 0x00030 /* Flow Control Type - RW */
#define E1000_CONNSW 0x00034 /* Copper/Fiber switch control - RW */
#define E1000_VET 0x00038 /* VLAN Ether Type - RW */
#define E1000_TSSDP 0x0003C /* Time Sync SDP Configuration Register - RW */
#define E1000_ICR 0x000C0 /* Interrupt Cause Read - R/clr */
#define E1000_ITR 0x000C4 /* Interrupt Throttling Rate - RW */
#define E1000_ICS 0x000C8 /* Interrupt Cause Set - WO */
#define E1000_IMS 0x000D0 /* Interrupt Mask Set - RW */
#define E1000_IMC 0x000D8 /* Interrupt Mask Clear - WO */
#define E1000_IAM 0x000E0 /* Interrupt Acknowledge Auto Mask */
#define E1000_RCTL 0x00100 /* RX Control - RW */
#define E1000_FCTTV 0x00170 /* Flow Control Transmit Timer Value - RW */
#define E1000_TXCW 0x00178 /* TX Configuration Word - RW */
#define E1000_EICR 0x01580 /* Ext. Interrupt Cause Read - R/clr */
#define E1000_EITR(_n) (0x01680 + (0x4 * (_n)))
#define E1000_EICS 0x01520 /* Ext. Interrupt Cause Set - W0 */
#define E1000_EIMS 0x01524 /* Ext. Interrupt Mask Set/Read - RW */
#define E1000_EIMC 0x01528 /* Ext. Interrupt Mask Clear - WO */
#define E1000_EIAC 0x0152C /* Ext. Interrupt Auto Clear - RW */
#define E1000_EIAM 0x01530 /* Ext. Interrupt Ack Auto Clear Mask - RW */
#define E1000_GPIE 0x01514 /* General Purpose Interrupt Enable - RW */
#define E1000_IVAR0 0x01700 /* Interrupt Vector Allocation (array) - RW */
#define E1000_IVAR_MISC 0x01740 /* IVAR for "other" causes - RW */
#define E1000_TCTL 0x00400 /* TX Control - RW */
#define E1000_TCTL_EXT 0x00404 /* Extended TX Control - RW */
#define E1000_TIPG 0x00410 /* TX Inter-packet gap -RW */
#define E1000_AIT 0x00458 /* Adaptive Interframe Spacing Throttle - RW */
#define E1000_LEDCTL 0x00E00 /* LED Control - RW */
#define E1000_LEDMUX 0x08130 /* LED MUX Control */
#define E1000_PBA 0x01000 /* Packet Buffer Allocation - RW */
#define E1000_PBS 0x01008 /* Packet Buffer Size */
#define E1000_EEMNGCTL 0x01010 /* MNG EEprom Control */
#define E1000_EEMNGCTL_I210 0x12030 /* MNG EEprom Control */
#define E1000_EEARBC_I210 0x12024 /* EEPROM Auto Read Bus Control */
#define E1000_EEWR 0x0102C /* EEPROM Write Register - RW */
#define E1000_I2CCMD 0x01028 /* SFPI2C Command Register - RW */
#define E1000_FRTIMER 0x01048 /* Free Running Timer - RW */
#define E1000_TCPTIMER 0x0104C /* TCP Timer - RW */
#define E1000_FCRTL 0x02160 /* Flow Control Receive Threshold Low - RW */
#define E1000_FCRTH 0x02168 /* Flow Control Receive Threshold High - RW */
#define E1000_FCRTV 0x02460 /* Flow Control Refresh Timer Value - RW */
#define E1000_I2CPARAMS 0x0102C /* SFPI2C Parameters Register - RW */
#define E1000_I2CBB_EN 0x00000100 /* I2C - Bit Bang Enable */
#define E1000_I2C_CLK_OUT 0x00000200 /* I2C- Clock */
#define E1000_I2C_DATA_OUT 0x00000400 /* I2C- Data Out */
#define E1000_I2C_DATA_OE_N 0x00000800 /* I2C- Data Output Enable */
#define E1000_I2C_DATA_IN 0x00001000 /* I2C- Data In */
#define E1000_I2C_CLK_OE_N 0x00002000 /* I2C- Clock Output Enable */
#define E1000_I2C_CLK_IN 0x00004000 /* I2C- Clock In */
#define E1000_MPHY_ADDR_CTRL 0x0024 /* GbE MPHY Address Control */
#define E1000_MPHY_DATA 0x0E10 /* GBE MPHY Data */
#define E1000_MPHY_STAT 0x0E0C /* GBE MPHY Statistics */
/* IEEE 1588 TIMESYNCH */
#define E1000_TSYNCRXCTL 0x0B620 /* Rx Time Sync Control register - RW */
#define E1000_TSYNCTXCTL 0x0B614 /* Tx Time Sync Control register - RW */
#define E1000_TSYNCRXCFG 0x05F50 /* Time Sync Rx Configuration - RW */
#define E1000_RXSTMPL 0x0B624 /* Rx timestamp Low - RO */
#define E1000_RXSTMPH 0x0B628 /* Rx timestamp High - RO */
#define E1000_RXSATRL 0x0B62C /* Rx timestamp attribute low - RO */
#define E1000_RXSATRH 0x0B630 /* Rx timestamp attribute high - RO */
#define E1000_TXSTMPL 0x0B618 /* Tx timestamp value Low - RO */
#define E1000_TXSTMPH 0x0B61C /* Tx timestamp value High - RO */
#define E1000_SYSTIML 0x0B600 /* System time register Low - RO */
#define E1000_SYSTIMH 0x0B604 /* System time register High - RO */
#define E1000_TIMINCA 0x0B608 /* Increment attributes register - RW */
#define E1000_TSAUXC 0x0B640 /* Timesync Auxiliary Control register */
#define E1000_TRGTTIML0 0x0B644 /* Target Time Register 0 Low - RW */
#define E1000_TRGTTIMH0 0x0B648 /* Target Time Register 0 High - RW */
#define E1000_TRGTTIML1 0x0B64C /* Target Time Register 1 Low - RW */
#define E1000_TRGTTIMH1 0x0B650 /* Target Time Register 1 High - RW */
#define E1000_FREQOUT0 0x0B654 /* Frequency Out 0 Control Register - RW */
#define E1000_FREQOUT1 0x0B658 /* Frequency Out 1 Control Register - RW */
#define E1000_AUXSTMPL0 0x0B65C /* Auxiliary Time Stamp 0 Register Low - RO */
#define E1000_AUXSTMPH0 0x0B660 /* Auxiliary Time Stamp 0 Register High - RO */
#define E1000_AUXSTMPL1 0x0B664 /* Auxiliary Time Stamp 1 Register Low - RO */
#define E1000_AUXSTMPH1 0x0B668 /* Auxiliary Time Stamp 1 Register High - RO */
#define E1000_SYSTIMR 0x0B6F8 /* System time register Residue */
#define E1000_TSICR 0x0B66C /* Interrupt Cause Register */
#define E1000_TSIM 0x0B674 /* Interrupt Mask Register */
/* Filtering Registers */
#define E1000_SAQF(_n) (0x5980 + 4 * (_n))
#define E1000_DAQF(_n) (0x59A0 + 4 * (_n))
#define E1000_SPQF(_n) (0x59C0 + 4 * (_n))
#define E1000_FTQF(_n) (0x59E0 + 4 * (_n))
#define E1000_SAQF0 E1000_SAQF(0)
#define E1000_DAQF0 E1000_DAQF(0)
#define E1000_SPQF0 E1000_SPQF(0)
#define E1000_FTQF0 E1000_FTQF(0)
#define E1000_SYNQF(_n) (0x055FC + (4 * (_n))) /* SYN Packet Queue Fltr */
#define E1000_ETQF(_n) (0x05CB0 + (4 * (_n))) /* EType Queue Fltr */
#define E1000_RQDPC(_n) (0x0C030 + ((_n) * 0x40))
/* DMA Coalescing registers */
#define E1000_DMACR 0x02508 /* Control Register */
#define E1000_DMCTXTH 0x03550 /* Transmit Threshold */
#define E1000_DMCTLX 0x02514 /* Time to Lx Request */
#define E1000_DMCRTRH 0x05DD0 /* Receive Packet Rate Threshold */
#define E1000_DMCCNT 0x05DD4 /* Current Rx Count */
#define E1000_FCRTC 0x02170 /* Flow Control Rx high watermark */
/* TX Rate Limit Registers */
#define E1000_RTTDQSEL 0x3604 /* Tx Desc Plane Queue Select - WO */
#define E1000_RTTBCNRM 0x3690 /* Tx BCN Rate-scheduler MMW */
#define E1000_RTTBCNRC 0x36B0 /* Tx BCN Rate-Scheduler Config - WO */
/* Split and Replication RX Control - RW */
#define E1000_RXPBS 0x02404 /* Rx Packet Buffer Size - RW */
/* Thermal sensor configuration and status registers */
#define E1000_THMJT 0x08100 /* Junction Temperature */
#define E1000_THLOWTC 0x08104 /* Low Threshold Control */
#define E1000_THMIDTC 0x08108 /* Mid Threshold Control */
#define E1000_THHIGHTC 0x0810C /* High Threshold Control */
#define E1000_THSTAT 0x08110 /* Thermal Sensor Status */
/* Convenience macros
*
* Note: "_n" is the queue number of the register to be written to.
*
* Example usage:
* E1000_RDBAL_REG(current_rx_queue)
*/
#define E1000_RDBAL(_n) ((_n) < 4 ? (0x02800 + ((_n) * 0x100)) \
: (0x0C000 + ((_n) * 0x40)))
#define E1000_RDBAH(_n) ((_n) < 4 ? (0x02804 + ((_n) * 0x100)) \
: (0x0C004 + ((_n) * 0x40)))
#define E1000_RDLEN(_n) ((_n) < 4 ? (0x02808 + ((_n) * 0x100)) \
: (0x0C008 + ((_n) * 0x40)))
#define E1000_SRRCTL(_n) ((_n) < 4 ? (0x0280C + ((_n) * 0x100)) \
: (0x0C00C + ((_n) * 0x40)))
#define E1000_RDH(_n) ((_n) < 4 ? (0x02810 + ((_n) * 0x100)) \
: (0x0C010 + ((_n) * 0x40)))
#define E1000_RDT(_n) ((_n) < 4 ? (0x02818 + ((_n) * 0x100)) \
: (0x0C018 + ((_n) * 0x40)))
#define E1000_RXDCTL(_n) ((_n) < 4 ? (0x02828 + ((_n) * 0x100)) \
: (0x0C028 + ((_n) * 0x40)))
#define E1000_TDBAL(_n) ((_n) < 4 ? (0x03800 + ((_n) * 0x100)) \
: (0x0E000 + ((_n) * 0x40)))
#define E1000_TDBAH(_n) ((_n) < 4 ? (0x03804 + ((_n) * 0x100)) \
: (0x0E004 + ((_n) * 0x40)))
#define E1000_TDLEN(_n) ((_n) < 4 ? (0x03808 + ((_n) * 0x100)) \
: (0x0E008 + ((_n) * 0x40)))
#define E1000_TDH(_n) ((_n) < 4 ? (0x03810 + ((_n) * 0x100)) \
: (0x0E010 + ((_n) * 0x40)))
#define E1000_TDT(_n) ((_n) < 4 ? (0x03818 + ((_n) * 0x100)) \
: (0x0E018 + ((_n) * 0x40)))
#define E1000_TXDCTL(_n) ((_n) < 4 ? (0x03828 + ((_n) * 0x100)) \
: (0x0E028 + ((_n) * 0x40)))
#define E1000_RXCTL(_n) ((_n) < 4 ? (0x02814 + ((_n) * 0x100)) : \
(0x0C014 + ((_n) * 0x40)))
#define E1000_DCA_RXCTRL(_n) E1000_RXCTL(_n)
#define E1000_TXCTL(_n) ((_n) < 4 ? (0x03814 + ((_n) * 0x100)) : \
(0x0E014 + ((_n) * 0x40)))
#define E1000_DCA_TXCTRL(_n) E1000_TXCTL(_n)
#define E1000_TDWBAL(_n) ((_n) < 4 ? (0x03838 + ((_n) * 0x100)) \
: (0x0E038 + ((_n) * 0x40)))
#define E1000_TDWBAH(_n) ((_n) < 4 ? (0x0383C + ((_n) * 0x100)) \
: (0x0E03C + ((_n) * 0x40)))
#define E1000_RXPBS 0x02404 /* Rx Packet Buffer Size - RW */
#define E1000_TXPBS 0x03404 /* Tx Packet Buffer Size - RW */
#define E1000_TDFH 0x03410 /* TX Data FIFO Head - RW */
#define E1000_TDFT 0x03418 /* TX Data FIFO Tail - RW */
#define E1000_TDFHS 0x03420 /* TX Data FIFO Head Saved - RW */
#define E1000_TDFPC 0x03430 /* TX Data FIFO Packet Count - RW */
#define E1000_DTXCTL 0x03590 /* DMA TX Control - RW */
#define E1000_CRCERRS 0x04000 /* CRC Error Count - R/clr */
#define E1000_ALGNERRC 0x04004 /* Alignment Error Count - R/clr */
#define E1000_SYMERRS 0x04008 /* Symbol Error Count - R/clr */
#define E1000_RXERRC 0x0400C /* Receive Error Count - R/clr */
#define E1000_MPC 0x04010 /* Missed Packet Count - R/clr */
#define E1000_SCC 0x04014 /* Single Collision Count - R/clr */
#define E1000_ECOL 0x04018 /* Excessive Collision Count - R/clr */
#define E1000_MCC 0x0401C /* Multiple Collision Count - R/clr */
#define E1000_LATECOL 0x04020 /* Late Collision Count - R/clr */
#define E1000_COLC 0x04028 /* Collision Count - R/clr */
#define E1000_DC 0x04030 /* Defer Count - R/clr */
#define E1000_TNCRS 0x04034 /* TX-No CRS - R/clr */
#define E1000_SEC 0x04038 /* Sequence Error Count - R/clr */
#define E1000_CEXTERR 0x0403C /* Carrier Extension Error Count - R/clr */
#define E1000_RLEC 0x04040 /* Receive Length Error Count - R/clr */
#define E1000_XONRXC 0x04048 /* XON RX Count - R/clr */
#define E1000_XONTXC 0x0404C /* XON TX Count - R/clr */
#define E1000_XOFFRXC 0x04050 /* XOFF RX Count - R/clr */
#define E1000_XOFFTXC 0x04054 /* XOFF TX Count - R/clr */
#define E1000_FCRUC 0x04058 /* Flow Control RX Unsupported Count- R/clr */
#define E1000_PRC64 0x0405C /* Packets RX (64 bytes) - R/clr */
#define E1000_PRC127 0x04060 /* Packets RX (65-127 bytes) - R/clr */
#define E1000_PRC255 0x04064 /* Packets RX (128-255 bytes) - R/clr */
#define E1000_PRC511 0x04068 /* Packets RX (255-511 bytes) - R/clr */
#define E1000_PRC1023 0x0406C /* Packets RX (512-1023 bytes) - R/clr */
#define E1000_PRC1522 0x04070 /* Packets RX (1024-1522 bytes) - R/clr */
#define E1000_GPRC 0x04074 /* Good Packets RX Count - R/clr */
#define E1000_BPRC 0x04078 /* Broadcast Packets RX Count - R/clr */
#define E1000_MPRC 0x0407C /* Multicast Packets RX Count - R/clr */
#define E1000_GPTC 0x04080 /* Good Packets TX Count - R/clr */
#define E1000_GORCL 0x04088 /* Good Octets RX Count Low - R/clr */
#define E1000_GORCH 0x0408C /* Good Octets RX Count High - R/clr */
#define E1000_GOTCL 0x04090 /* Good Octets TX Count Low - R/clr */
#define E1000_GOTCH 0x04094 /* Good Octets TX Count High - R/clr */
#define E1000_RNBC 0x040A0 /* RX No Buffers Count - R/clr */
#define E1000_RUC 0x040A4 /* RX Undersize Count - R/clr */
#define E1000_RFC 0x040A8 /* RX Fragment Count - R/clr */
#define E1000_ROC 0x040AC /* RX Oversize Count - R/clr */
#define E1000_RJC 0x040B0 /* RX Jabber Count - R/clr */
#define E1000_MGTPRC 0x040B4 /* Management Packets RX Count - R/clr */
#define E1000_MGTPDC 0x040B8 /* Management Packets Dropped Count - R/clr */
#define E1000_MGTPTC 0x040BC /* Management Packets TX Count - R/clr */
#define E1000_TORL 0x040C0 /* Total Octets RX Low - R/clr */
#define E1000_TORH 0x040C4 /* Total Octets RX High - R/clr */
#define E1000_TOTL 0x040C8 /* Total Octets TX Low - R/clr */
#define E1000_TOTH 0x040CC /* Total Octets TX High - R/clr */
#define E1000_TPR 0x040D0 /* Total Packets RX - R/clr */
#define E1000_TPT 0x040D4 /* Total Packets TX - R/clr */
#define E1000_PTC64 0x040D8 /* Packets TX (64 bytes) - R/clr */
#define E1000_PTC127 0x040DC /* Packets TX (65-127 bytes) - R/clr */
#define E1000_PTC255 0x040E0 /* Packets TX (128-255 bytes) - R/clr */
#define E1000_PTC511 0x040E4 /* Packets TX (256-511 bytes) - R/clr */
#define E1000_PTC1023 0x040E8 /* Packets TX (512-1023 bytes) - R/clr */
#define E1000_PTC1522 0x040EC /* Packets TX (1024-1522 Bytes) - R/clr */
#define E1000_MPTC 0x040F0 /* Multicast Packets TX Count - R/clr */
#define E1000_BPTC 0x040F4 /* Broadcast Packets TX Count - R/clr */
#define E1000_TSCTC 0x040F8 /* TCP Segmentation Context TX - R/clr */
#define E1000_TSCTFC 0x040FC /* TCP Segmentation Context TX Fail - R/clr */
#define E1000_IAC 0x04100 /* Interrupt Assertion Count */
/* Interrupt Cause Rx Packet Timer Expire Count */
#define E1000_ICRXPTC 0x04104
/* Interrupt Cause Rx Absolute Timer Expire Count */
#define E1000_ICRXATC 0x04108
/* Interrupt Cause Tx Packet Timer Expire Count */
#define E1000_ICTXPTC 0x0410C
/* Interrupt Cause Tx Absolute Timer Expire Count */
#define E1000_ICTXATC 0x04110
/* Interrupt Cause Tx Queue Empty Count */
#define E1000_ICTXQEC 0x04118
/* Interrupt Cause Tx Queue Minimum Threshold Count */
#define E1000_ICTXQMTC 0x0411C
/* Interrupt Cause Rx Descriptor Minimum Threshold Count */
#define E1000_ICRXDMTC 0x04120
#define E1000_ICRXOC 0x04124 /* Interrupt Cause Receiver Overrun Count */
#define E1000_PCS_CFG0 0x04200 /* PCS Configuration 0 - RW */
#define E1000_PCS_LCTL 0x04208 /* PCS Link Control - RW */
#define E1000_PCS_LSTAT 0x0420C /* PCS Link Status - RO */
#define E1000_CBTMPC 0x0402C /* Circuit Breaker TX Packet Count */
#define E1000_HTDPMC 0x0403C /* Host Transmit Discarded Packets */
#define E1000_CBRMPC 0x040FC /* Circuit Breaker RX Packet Count */
#define E1000_RPTHC 0x04104 /* Rx Packets To Host */
#define E1000_HGPTC 0x04118 /* Host Good Packets TX Count */
#define E1000_HTCBDPC 0x04124 /* Host TX Circuit Breaker Dropped Count */
#define E1000_HGORCL 0x04128 /* Host Good Octets Received Count Low */
#define E1000_HGORCH 0x0412C /* Host Good Octets Received Count High */
#define E1000_HGOTCL 0x04130 /* Host Good Octets Transmit Count Low */
#define E1000_HGOTCH 0x04134 /* Host Good Octets Transmit Count High */
#define E1000_LENERRS 0x04138 /* Length Errors Count */
#define E1000_SCVPC 0x04228 /* SerDes/SGMII Code Violation Pkt Count */
#define E1000_PCS_ANADV 0x04218 /* AN advertisement - RW */
#define E1000_PCS_LPAB 0x0421C /* Link Partner Ability - RW */
#define E1000_PCS_NPTX 0x04220 /* AN Next Page Transmit - RW */
#define E1000_PCS_LPABNP 0x04224 /* Link Partner Ability Next Page - RW */
#define E1000_RXCSUM 0x05000 /* RX Checksum Control - RW */
#define E1000_RLPML 0x05004 /* RX Long Packet Max Length */
#define E1000_RFCTL 0x05008 /* Receive Filter Control*/
#define E1000_MTA 0x05200 /* Multicast Table Array - RW Array */
#define E1000_RA 0x05400 /* Receive Address - RW Array */
#define E1000_RA2 0x054E0 /* 2nd half of Rx address array - RW Array */
#define E1000_PSRTYPE(_i) (0x05480 + ((_i) * 4))
#define E1000_RAL(_i) (((_i) <= 15) ? (0x05400 + ((_i) * 8)) : \
(0x054E0 + ((_i - 16) * 8)))
#define E1000_RAH(_i) (((_i) <= 15) ? (0x05404 + ((_i) * 8)) : \
(0x054E4 + ((_i - 16) * 8)))
#define E1000_VLAPQF 0x055B0 /* VLAN Priority Queue Filter VLAPQF */
#define E1000_IP4AT_REG(_i) (0x05840 + ((_i) * 8))
#define E1000_IP6AT_REG(_i) (0x05880 + ((_i) * 4))
#define E1000_WUPM_REG(_i) (0x05A00 + ((_i) * 4))
#define E1000_FFMT_REG(_i) (0x09000 + ((_i) * 8))
#define E1000_FFVT_REG(_i) (0x09800 + ((_i) * 8))
#define E1000_FFLT_REG(_i) (0x05F00 + ((_i) * 8))
#define E1000_VFTA 0x05600 /* VLAN Filter Table Array - RW Array */
#define E1000_VT_CTL 0x0581C /* VMDq Control - RW */
#define E1000_WUC 0x05800 /* Wakeup Control - RW */
#define E1000_WUFC 0x05808 /* Wakeup Filter Control - RW */
#define E1000_WUS 0x05810 /* Wakeup Status - R/W1C */
#define E1000_MANC 0x05820 /* Management Control - RW */
#define E1000_IPAV 0x05838 /* IP Address Valid - RW */
#define E1000_WUPL 0x05900 /* Wakeup Packet Length - RW */
#define E1000_SW_FW_SYNC 0x05B5C /* Software-Firmware Synchronization - RW */
#define E1000_CCMCTL 0x05B48 /* CCM Control Register */
#define E1000_GIOCTL 0x05B44 /* GIO Analog Control Register */
#define E1000_SCCTL 0x05B4C /* PCIc PLL Configuration Register */
#define E1000_GCR 0x05B00 /* PCI-Ex Control */
#define E1000_FACTPS 0x05B30 /* Function Active and Power State to MNG */
#define E1000_SWSM 0x05B50 /* SW Semaphore */
#define E1000_FWSM 0x05B54 /* FW Semaphore */
#define E1000_DCA_CTRL 0x05B74 /* DCA Control - RW */
/* RSS registers */
#define E1000_MRQC 0x05818 /* Multiple Receive Control - RW */
#define E1000_IMIR(_i) (0x05A80 + ((_i) * 4)) /* Immediate Interrupt */
#define E1000_IMIREXT(_i) (0x05AA0 + ((_i) * 4)) /* Immediate Interrupt Ext*/
#define E1000_IMIRVP 0x05AC0 /* Immediate Interrupt RX VLAN Priority - RW */
/* MSI-X Allocation Register (_i) - RW */
#define E1000_MSIXBM(_i) (0x01600 + ((_i) * 4))
/* Redirection Table - RW Array */
#define E1000_RETA(_i) (0x05C00 + ((_i) * 4))
#define E1000_RSSRK(_i) (0x05C80 + ((_i) * 4)) /* RSS Random Key - RW Array */
/* VT Registers */
#define E1000_MBVFICR 0x00C80 /* Mailbox VF Cause - RWC */
#define E1000_MBVFIMR 0x00C84 /* Mailbox VF int Mask - RW */
#define E1000_VFLRE 0x00C88 /* VF Register Events - RWC */
#define E1000_VFRE 0x00C8C /* VF Receive Enables */
#define E1000_VFTE 0x00C90 /* VF Transmit Enables */
#define E1000_QDE 0x02408 /* Queue Drop Enable - RW */
#define E1000_DTXSWC 0x03500 /* DMA Tx Switch Control - RW */
#define E1000_WVBR 0x03554 /* VM Wrong Behavior - RWS */
#define E1000_RPLOLR 0x05AF0 /* Replication Offload - RW */
#define E1000_UTA 0x0A000 /* Unicast Table Array - RW */
#define E1000_IOVTCL 0x05BBC /* IOV Control Register */
#define E1000_TXSWC 0x05ACC /* Tx Switch Control */
#define E1000_LVMMC 0x03548 /* Last VM Misbehavior cause */
/* These act per VF so an array friendly macro is used */
#define E1000_P2VMAILBOX(_n) (0x00C00 + (4 * (_n)))
#define E1000_VMBMEM(_n) (0x00800 + (64 * (_n)))
#define E1000_VMOLR(_n) (0x05AD0 + (4 * (_n)))
#define E1000_DVMOLR(_n) (0x0C038 + (64 * (_n)))
#define E1000_VLVF(_n) (0x05D00 + (4 * (_n))) /* VLAN VM Filter */
#define E1000_VMVIR(_n) (0x03700 + (4 * (_n)))
struct e1000_hw;
u32 igb_rd32(struct e1000_hw *hw, u32 reg);
/* write operations, indexed using DWORDS */
#define wr32(reg, val) \
do { \
u8 __iomem *hw_addr = READ_ONCE((hw)->hw_addr); \
if (!E1000_REMOVED(hw_addr)) \
writel((val), &hw_addr[(reg)]); \
} while (0)
#define rd32(reg) (igb_rd32(hw, reg))
#define wrfl() ((void)rd32(E1000_STATUS))
#define array_wr32(reg, offset, value) \
wr32((reg) + ((offset) << 2), (value))
#define array_rd32(reg, offset) (igb_rd32(hw, reg + ((offset) << 2)))
/* DMA Coalescing registers */
#define E1000_PCIEMISC 0x05BB8 /* PCIE misc config register */
/* Energy Efficient Ethernet "EEE" register */
#define E1000_IPCNFG 0x0E38 /* Internal PHY Configuration */
#define E1000_EEER 0x0E30 /* Energy Efficient Ethernet */
#define E1000_EEE_SU 0X0E34 /* EEE Setup */
#define E1000_EMIADD 0x10 /* Extended Memory Indirect Address */
#define E1000_EMIDATA 0x11 /* Extended Memory Indirect Data */
#define E1000_MMDAC 13 /* MMD Access Control */
#define E1000_MMDAAD 14 /* MMD Access Address/Data */
/* Thermal Sensor Register */
#define E1000_THSTAT 0x08110 /* Thermal Sensor Status */
/* OS2BMC Registers */
#define E1000_B2OSPC 0x08FE0 /* BMC2OS packets sent by BMC */
#define E1000_B2OGPRC 0x04158 /* BMC2OS packets received by host */
#define E1000_O2BGPTC 0x08FE4 /* OS2BMC packets received by BMC */
#define E1000_O2BSPC 0x0415C /* OS2BMC packets transmitted by host */
#define E1000_SRWR 0x12018 /* Shadow Ram Write Register - RW */
#define E1000_I210_FLMNGCTL 0x12038
#define E1000_I210_FLMNGDATA 0x1203C
#define E1000_I210_FLMNGCNT 0x12040
#define E1000_I210_FLSWCTL 0x12048
#define E1000_I210_FLSWDATA 0x1204C
#define E1000_I210_FLSWCNT 0x12050
#define E1000_I210_FLA 0x1201C
#define E1000_I210_DTXMXPKTSZ 0x355C
#define E1000_I210_TXDCTL(_n) (0x0E028 + ((_n) * 0x40))
#define E1000_I210_TQAVCTRL 0x3570
#define E1000_I210_TQAVCC(_n) (0x3004 + ((_n) * 0x40))
#define E1000_I210_TQAVHC(_n) (0x300C + ((_n) * 0x40))
#define E1000_I210_RR2DCDELAY 0x5BF4
#define E1000_INVM_DATA_REG(_n) (0x12120 + 4*(_n))
#define E1000_INVM_SIZE 64 /* Number of INVM Data Registers */
#define E1000_REMOVED(h) unlikely(!(h))
#endif

View File

@ -0,0 +1,418 @@
/* SPDX-License-Identifier: GPL-2.0 */
/* Copyright(c) 2007 - 2018 Intel Corporation. */
#ifndef _E1000_REGS_H_
#define _E1000_REGS_H_
#define E1000_CTRL 0x00000 /* Device Control - RW */
#define E1000_STATUS 0x00008 /* Device Status - RO */
#define E1000_EECD 0x00010 /* EEPROM/Flash Control - RW */
#define E1000_EERD 0x00014 /* EEPROM Read - RW */
#define E1000_CTRL_EXT 0x00018 /* Extended Device Control - RW */
#define E1000_MDIC 0x00020 /* MDI Control - RW */
#define E1000_MDICNFG 0x00E04 /* MDI Config - RW */
#define E1000_SCTL 0x00024 /* SerDes Control - RW */
#define E1000_FCAL 0x00028 /* Flow Control Address Low - RW */
#define E1000_FCAH 0x0002C /* Flow Control Address High -RW */
#define E1000_FCT 0x00030 /* Flow Control Type - RW */
#define E1000_CONNSW 0x00034 /* Copper/Fiber switch control - RW */
#define E1000_VET 0x00038 /* VLAN Ether Type - RW */
#define E1000_TSSDP 0x0003C /* Time Sync SDP Configuration Register - RW */
#define E1000_ICR 0x000C0 /* Interrupt Cause Read - R/clr */
#define E1000_ITR 0x000C4 /* Interrupt Throttling Rate - RW */
#define E1000_ICS 0x000C8 /* Interrupt Cause Set - WO */
#define E1000_IMS 0x000D0 /* Interrupt Mask Set - RW */
#define E1000_IMC 0x000D8 /* Interrupt Mask Clear - WO */
#define E1000_IAM 0x000E0 /* Interrupt Acknowledge Auto Mask */
#define E1000_RCTL 0x00100 /* RX Control - RW */
#define E1000_FCTTV 0x00170 /* Flow Control Transmit Timer Value - RW */
#define E1000_TXCW 0x00178 /* TX Configuration Word - RW */
#define E1000_EICR 0x01580 /* Ext. Interrupt Cause Read - R/clr */
#define E1000_EITR(_n) (0x01680 + (0x4 * (_n)))
#define E1000_EICS 0x01520 /* Ext. Interrupt Cause Set - W0 */
#define E1000_EIMS 0x01524 /* Ext. Interrupt Mask Set/Read - RW */
#define E1000_EIMC 0x01528 /* Ext. Interrupt Mask Clear - WO */
#define E1000_EIAC 0x0152C /* Ext. Interrupt Auto Clear - RW */
#define E1000_EIAM 0x01530 /* Ext. Interrupt Ack Auto Clear Mask - RW */
#define E1000_GPIE 0x01514 /* General Purpose Interrupt Enable - RW */
#define E1000_IVAR0 0x01700 /* Interrupt Vector Allocation (array) - RW */
#define E1000_IVAR_MISC 0x01740 /* IVAR for "other" causes - RW */
#define E1000_TCTL 0x00400 /* TX Control - RW */
#define E1000_TCTL_EXT 0x00404 /* Extended TX Control - RW */
#define E1000_TIPG 0x00410 /* TX Inter-packet gap -RW */
#define E1000_AIT 0x00458 /* Adaptive Interframe Spacing Throttle - RW */
#define E1000_LEDCTL 0x00E00 /* LED Control - RW */
#define E1000_LEDMUX 0x08130 /* LED MUX Control */
#define E1000_PBA 0x01000 /* Packet Buffer Allocation - RW */
#define E1000_PBS 0x01008 /* Packet Buffer Size */
#define E1000_EEMNGCTL 0x01010 /* MNG EEprom Control */
#define E1000_EEMNGCTL_I210 0x12030 /* MNG EEprom Control */
#define E1000_EEARBC_I210 0x12024 /* EEPROM Auto Read Bus Control */
#define E1000_EEWR 0x0102C /* EEPROM Write Register - RW */
#define E1000_I2CCMD 0x01028 /* SFPI2C Command Register - RW */
#define E1000_FRTIMER 0x01048 /* Free Running Timer - RW */
#define E1000_TCPTIMER 0x0104C /* TCP Timer - RW */
#define E1000_FCRTL 0x02160 /* Flow Control Receive Threshold Low - RW */
#define E1000_FCRTH 0x02168 /* Flow Control Receive Threshold High - RW */
#define E1000_FCRTV 0x02460 /* Flow Control Refresh Timer Value - RW */
#define E1000_I2CPARAMS 0x0102C /* SFPI2C Parameters Register - RW */
#define E1000_I2CBB_EN 0x00000100 /* I2C - Bit Bang Enable */
#define E1000_I2C_CLK_OUT 0x00000200 /* I2C- Clock */
#define E1000_I2C_DATA_OUT 0x00000400 /* I2C- Data Out */
#define E1000_I2C_DATA_OE_N 0x00000800 /* I2C- Data Output Enable */
#define E1000_I2C_DATA_IN 0x00001000 /* I2C- Data In */
#define E1000_I2C_CLK_OE_N 0x00002000 /* I2C- Clock Output Enable */
#define E1000_I2C_CLK_IN 0x00004000 /* I2C- Clock In */
#define E1000_MPHY_ADDR_CTRL 0x0024 /* GbE MPHY Address Control */
#define E1000_MPHY_DATA 0x0E10 /* GBE MPHY Data */
#define E1000_MPHY_STAT 0x0E0C /* GBE MPHY Statistics */
/* IEEE 1588 TIMESYNCH */
#define E1000_TSYNCRXCTL 0x0B620 /* Rx Time Sync Control register - RW */
#define E1000_TSYNCTXCTL 0x0B614 /* Tx Time Sync Control register - RW */
#define E1000_TSYNCRXCFG 0x05F50 /* Time Sync Rx Configuration - RW */
#define E1000_RXSTMPL 0x0B624 /* Rx timestamp Low - RO */
#define E1000_RXSTMPH 0x0B628 /* Rx timestamp High - RO */
#define E1000_RXSATRL 0x0B62C /* Rx timestamp attribute low - RO */
#define E1000_RXSATRH 0x0B630 /* Rx timestamp attribute high - RO */
#define E1000_TXSTMPL 0x0B618 /* Tx timestamp value Low - RO */
#define E1000_TXSTMPH 0x0B61C /* Tx timestamp value High - RO */
#define E1000_SYSTIML 0x0B600 /* System time register Low - RO */
#define E1000_SYSTIMH 0x0B604 /* System time register High - RO */
#define E1000_TIMINCA 0x0B608 /* Increment attributes register - RW */
#define E1000_TSAUXC 0x0B640 /* Timesync Auxiliary Control register */
#define E1000_TRGTTIML0 0x0B644 /* Target Time Register 0 Low - RW */
#define E1000_TRGTTIMH0 0x0B648 /* Target Time Register 0 High - RW */
#define E1000_TRGTTIML1 0x0B64C /* Target Time Register 1 Low - RW */
#define E1000_TRGTTIMH1 0x0B650 /* Target Time Register 1 High - RW */
#define E1000_FREQOUT0 0x0B654 /* Frequency Out 0 Control Register - RW */
#define E1000_FREQOUT1 0x0B658 /* Frequency Out 1 Control Register - RW */
#define E1000_AUXSTMPL0 0x0B65C /* Auxiliary Time Stamp 0 Register Low - RO */
#define E1000_AUXSTMPH0 0x0B660 /* Auxiliary Time Stamp 0 Register High - RO */
#define E1000_AUXSTMPL1 0x0B664 /* Auxiliary Time Stamp 1 Register Low - RO */
#define E1000_AUXSTMPH1 0x0B668 /* Auxiliary Time Stamp 1 Register High - RO */
#define E1000_SYSTIMR 0x0B6F8 /* System time register Residue */
#define E1000_TSICR 0x0B66C /* Interrupt Cause Register */
#define E1000_TSIM 0x0B674 /* Interrupt Mask Register */
/* Filtering Registers */
#define E1000_SAQF(_n) (0x5980 + 4 * (_n))
#define E1000_DAQF(_n) (0x59A0 + 4 * (_n))
#define E1000_SPQF(_n) (0x59C0 + 4 * (_n))
#define E1000_FTQF(_n) (0x59E0 + 4 * (_n))
#define E1000_SAQF0 E1000_SAQF(0)
#define E1000_DAQF0 E1000_DAQF(0)
#define E1000_SPQF0 E1000_SPQF(0)
#define E1000_FTQF0 E1000_FTQF(0)
#define E1000_SYNQF(_n) (0x055FC + (4 * (_n))) /* SYN Packet Queue Fltr */
#define E1000_ETQF(_n) (0x05CB0 + (4 * (_n))) /* EType Queue Fltr */
#define E1000_RQDPC(_n) (0x0C030 + ((_n) * 0x40))
/* DMA Coalescing registers */
#define E1000_DMACR 0x02508 /* Control Register */
#define E1000_DMCTXTH 0x03550 /* Transmit Threshold */
#define E1000_DMCTLX 0x02514 /* Time to Lx Request */
#define E1000_DMCRTRH 0x05DD0 /* Receive Packet Rate Threshold */
#define E1000_DMCCNT 0x05DD4 /* Current Rx Count */
#define E1000_FCRTC 0x02170 /* Flow Control Rx high watermark */
/* TX Rate Limit Registers */
#define E1000_RTTDQSEL 0x3604 /* Tx Desc Plane Queue Select - WO */
#define E1000_RTTBCNRM 0x3690 /* Tx BCN Rate-scheduler MMW */
#define E1000_RTTBCNRC 0x36B0 /* Tx BCN Rate-Scheduler Config - WO */
/* Split and Replication RX Control - RW */
#define E1000_RXPBS 0x02404 /* Rx Packet Buffer Size - RW */
/* Thermal sensor configuration and status registers */
#define E1000_THMJT 0x08100 /* Junction Temperature */
#define E1000_THLOWTC 0x08104 /* Low Threshold Control */
#define E1000_THMIDTC 0x08108 /* Mid Threshold Control */
#define E1000_THHIGHTC 0x0810C /* High Threshold Control */
#define E1000_THSTAT 0x08110 /* Thermal Sensor Status */
/* Convenience macros
*
* Note: "_n" is the queue number of the register to be written to.
*
* Example usage:
* E1000_RDBAL_REG(current_rx_queue)
*/
#define E1000_RDBAL(_n) ((_n) < 4 ? (0x02800 + ((_n) * 0x100)) \
: (0x0C000 + ((_n) * 0x40)))
#define E1000_RDBAH(_n) ((_n) < 4 ? (0x02804 + ((_n) * 0x100)) \
: (0x0C004 + ((_n) * 0x40)))
#define E1000_RDLEN(_n) ((_n) < 4 ? (0x02808 + ((_n) * 0x100)) \
: (0x0C008 + ((_n) * 0x40)))
#define E1000_SRRCTL(_n) ((_n) < 4 ? (0x0280C + ((_n) * 0x100)) \
: (0x0C00C + ((_n) * 0x40)))
#define E1000_RDH(_n) ((_n) < 4 ? (0x02810 + ((_n) * 0x100)) \
: (0x0C010 + ((_n) * 0x40)))
#define E1000_RDT(_n) ((_n) < 4 ? (0x02818 + ((_n) * 0x100)) \
: (0x0C018 + ((_n) * 0x40)))
#define E1000_RXDCTL(_n) ((_n) < 4 ? (0x02828 + ((_n) * 0x100)) \
: (0x0C028 + ((_n) * 0x40)))
#define E1000_TDBAL(_n) ((_n) < 4 ? (0x03800 + ((_n) * 0x100)) \
: (0x0E000 + ((_n) * 0x40)))
#define E1000_TDBAH(_n) ((_n) < 4 ? (0x03804 + ((_n) * 0x100)) \
: (0x0E004 + ((_n) * 0x40)))
#define E1000_TDLEN(_n) ((_n) < 4 ? (0x03808 + ((_n) * 0x100)) \
: (0x0E008 + ((_n) * 0x40)))
#define E1000_TDH(_n) ((_n) < 4 ? (0x03810 + ((_n) * 0x100)) \
: (0x0E010 + ((_n) * 0x40)))
#define E1000_TDT(_n) ((_n) < 4 ? (0x03818 + ((_n) * 0x100)) \
: (0x0E018 + ((_n) * 0x40)))
#define E1000_TXDCTL(_n) ((_n) < 4 ? (0x03828 + ((_n) * 0x100)) \
: (0x0E028 + ((_n) * 0x40)))
#define E1000_RXCTL(_n) ((_n) < 4 ? (0x02814 + ((_n) * 0x100)) : \
(0x0C014 + ((_n) * 0x40)))
#define E1000_DCA_RXCTRL(_n) E1000_RXCTL(_n)
#define E1000_TXCTL(_n) ((_n) < 4 ? (0x03814 + ((_n) * 0x100)) : \
(0x0E014 + ((_n) * 0x40)))
#define E1000_DCA_TXCTRL(_n) E1000_TXCTL(_n)
#define E1000_TDWBAL(_n) ((_n) < 4 ? (0x03838 + ((_n) * 0x100)) \
: (0x0E038 + ((_n) * 0x40)))
#define E1000_TDWBAH(_n) ((_n) < 4 ? (0x0383C + ((_n) * 0x100)) \
: (0x0E03C + ((_n) * 0x40)))
#define E1000_RXPBS 0x02404 /* Rx Packet Buffer Size - RW */
#define E1000_TXPBS 0x03404 /* Tx Packet Buffer Size - RW */
#define E1000_TDFH 0x03410 /* TX Data FIFO Head - RW */
#define E1000_TDFT 0x03418 /* TX Data FIFO Tail - RW */
#define E1000_TDFHS 0x03420 /* TX Data FIFO Head Saved - RW */
#define E1000_TDFPC 0x03430 /* TX Data FIFO Packet Count - RW */
#define E1000_DTXCTL 0x03590 /* DMA TX Control - RW */
#define E1000_CRCERRS 0x04000 /* CRC Error Count - R/clr */
#define E1000_ALGNERRC 0x04004 /* Alignment Error Count - R/clr */
#define E1000_SYMERRS 0x04008 /* Symbol Error Count - R/clr */
#define E1000_RXERRC 0x0400C /* Receive Error Count - R/clr */
#define E1000_MPC 0x04010 /* Missed Packet Count - R/clr */
#define E1000_SCC 0x04014 /* Single Collision Count - R/clr */
#define E1000_ECOL 0x04018 /* Excessive Collision Count - R/clr */
#define E1000_MCC 0x0401C /* Multiple Collision Count - R/clr */
#define E1000_LATECOL 0x04020 /* Late Collision Count - R/clr */
#define E1000_COLC 0x04028 /* Collision Count - R/clr */
#define E1000_DC 0x04030 /* Defer Count - R/clr */
#define E1000_TNCRS 0x04034 /* TX-No CRS - R/clr */
#define E1000_SEC 0x04038 /* Sequence Error Count - R/clr */
#define E1000_CEXTERR 0x0403C /* Carrier Extension Error Count - R/clr */
#define E1000_RLEC 0x04040 /* Receive Length Error Count - R/clr */
#define E1000_XONRXC 0x04048 /* XON RX Count - R/clr */
#define E1000_XONTXC 0x0404C /* XON TX Count - R/clr */
#define E1000_XOFFRXC 0x04050 /* XOFF RX Count - R/clr */
#define E1000_XOFFTXC 0x04054 /* XOFF TX Count - R/clr */
#define E1000_FCRUC 0x04058 /* Flow Control RX Unsupported Count- R/clr */
#define E1000_PRC64 0x0405C /* Packets RX (64 bytes) - R/clr */
#define E1000_PRC127 0x04060 /* Packets RX (65-127 bytes) - R/clr */
#define E1000_PRC255 0x04064 /* Packets RX (128-255 bytes) - R/clr */
#define E1000_PRC511 0x04068 /* Packets RX (255-511 bytes) - R/clr */
#define E1000_PRC1023 0x0406C /* Packets RX (512-1023 bytes) - R/clr */
#define E1000_PRC1522 0x04070 /* Packets RX (1024-1522 bytes) - R/clr */
#define E1000_GPRC 0x04074 /* Good Packets RX Count - R/clr */
#define E1000_BPRC 0x04078 /* Broadcast Packets RX Count - R/clr */
#define E1000_MPRC 0x0407C /* Multicast Packets RX Count - R/clr */
#define E1000_GPTC 0x04080 /* Good Packets TX Count - R/clr */
#define E1000_GORCL 0x04088 /* Good Octets RX Count Low - R/clr */
#define E1000_GORCH 0x0408C /* Good Octets RX Count High - R/clr */
#define E1000_GOTCL 0x04090 /* Good Octets TX Count Low - R/clr */
#define E1000_GOTCH 0x04094 /* Good Octets TX Count High - R/clr */
#define E1000_RNBC 0x040A0 /* RX No Buffers Count - R/clr */
#define E1000_RUC 0x040A4 /* RX Undersize Count - R/clr */
#define E1000_RFC 0x040A8 /* RX Fragment Count - R/clr */
#define E1000_ROC 0x040AC /* RX Oversize Count - R/clr */
#define E1000_RJC 0x040B0 /* RX Jabber Count - R/clr */
#define E1000_MGTPRC 0x040B4 /* Management Packets RX Count - R/clr */
#define E1000_MGTPDC 0x040B8 /* Management Packets Dropped Count - R/clr */
#define E1000_MGTPTC 0x040BC /* Management Packets TX Count - R/clr */
#define E1000_TORL 0x040C0 /* Total Octets RX Low - R/clr */
#define E1000_TORH 0x040C4 /* Total Octets RX High - R/clr */
#define E1000_TOTL 0x040C8 /* Total Octets TX Low - R/clr */
#define E1000_TOTH 0x040CC /* Total Octets TX High - R/clr */
#define E1000_TPR 0x040D0 /* Total Packets RX - R/clr */
#define E1000_TPT 0x040D4 /* Total Packets TX - R/clr */
#define E1000_PTC64 0x040D8 /* Packets TX (64 bytes) - R/clr */
#define E1000_PTC127 0x040DC /* Packets TX (65-127 bytes) - R/clr */
#define E1000_PTC255 0x040E0 /* Packets TX (128-255 bytes) - R/clr */
#define E1000_PTC511 0x040E4 /* Packets TX (256-511 bytes) - R/clr */
#define E1000_PTC1023 0x040E8 /* Packets TX (512-1023 bytes) - R/clr */
#define E1000_PTC1522 0x040EC /* Packets TX (1024-1522 Bytes) - R/clr */
#define E1000_MPTC 0x040F0 /* Multicast Packets TX Count - R/clr */
#define E1000_BPTC 0x040F4 /* Broadcast Packets TX Count - R/clr */
#define E1000_TSCTC 0x040F8 /* TCP Segmentation Context TX - R/clr */
#define E1000_TSCTFC 0x040FC /* TCP Segmentation Context TX Fail - R/clr */
#define E1000_IAC 0x04100 /* Interrupt Assertion Count */
/* Interrupt Cause Rx Packet Timer Expire Count */
#define E1000_ICRXPTC 0x04104
/* Interrupt Cause Rx Absolute Timer Expire Count */
#define E1000_ICRXATC 0x04108
/* Interrupt Cause Tx Packet Timer Expire Count */
#define E1000_ICTXPTC 0x0410C
/* Interrupt Cause Tx Absolute Timer Expire Count */
#define E1000_ICTXATC 0x04110
/* Interrupt Cause Tx Queue Empty Count */
#define E1000_ICTXQEC 0x04118
/* Interrupt Cause Tx Queue Minimum Threshold Count */
#define E1000_ICTXQMTC 0x0411C
/* Interrupt Cause Rx Descriptor Minimum Threshold Count */
#define E1000_ICRXDMTC 0x04120
#define E1000_ICRXOC 0x04124 /* Interrupt Cause Receiver Overrun Count */
#define E1000_PCS_CFG0 0x04200 /* PCS Configuration 0 - RW */
#define E1000_PCS_LCTL 0x04208 /* PCS Link Control - RW */
#define E1000_PCS_LSTAT 0x0420C /* PCS Link Status - RO */
#define E1000_CBTMPC 0x0402C /* Circuit Breaker TX Packet Count */
#define E1000_HTDPMC 0x0403C /* Host Transmit Discarded Packets */
#define E1000_CBRMPC 0x040FC /* Circuit Breaker RX Packet Count */
#define E1000_RPTHC 0x04104 /* Rx Packets To Host */
#define E1000_HGPTC 0x04118 /* Host Good Packets TX Count */
#define E1000_HTCBDPC 0x04124 /* Host TX Circuit Breaker Dropped Count */
#define E1000_HGORCL 0x04128 /* Host Good Octets Received Count Low */
#define E1000_HGORCH 0x0412C /* Host Good Octets Received Count High */
#define E1000_HGOTCL 0x04130 /* Host Good Octets Transmit Count Low */
#define E1000_HGOTCH 0x04134 /* Host Good Octets Transmit Count High */
#define E1000_LENERRS 0x04138 /* Length Errors Count */
#define E1000_SCVPC 0x04228 /* SerDes/SGMII Code Violation Pkt Count */
#define E1000_PCS_ANADV 0x04218 /* AN advertisement - RW */
#define E1000_PCS_LPAB 0x0421C /* Link Partner Ability - RW */
#define E1000_PCS_NPTX 0x04220 /* AN Next Page Transmit - RW */
#define E1000_PCS_LPABNP 0x04224 /* Link Partner Ability Next Page - RW */
#define E1000_RXCSUM 0x05000 /* RX Checksum Control - RW */
#define E1000_RLPML 0x05004 /* RX Long Packet Max Length */
#define E1000_RFCTL 0x05008 /* Receive Filter Control*/
#define E1000_MTA 0x05200 /* Multicast Table Array - RW Array */
#define E1000_RA 0x05400 /* Receive Address - RW Array */
#define E1000_RA2 0x054E0 /* 2nd half of Rx address array - RW Array */
#define E1000_PSRTYPE(_i) (0x05480 + ((_i) * 4))
#define E1000_RAL(_i) (((_i) <= 15) ? (0x05400 + ((_i) * 8)) : \
(0x054E0 + ((_i - 16) * 8)))
#define E1000_RAH(_i) (((_i) <= 15) ? (0x05404 + ((_i) * 8)) : \
(0x054E4 + ((_i - 16) * 8)))
#define E1000_VLAPQF 0x055B0 /* VLAN Priority Queue Filter VLAPQF */
#define E1000_IP4AT_REG(_i) (0x05840 + ((_i) * 8))
#define E1000_IP6AT_REG(_i) (0x05880 + ((_i) * 4))
#define E1000_WUPM_REG(_i) (0x05A00 + ((_i) * 4))
#define E1000_FFMT_REG(_i) (0x09000 + ((_i) * 8))
#define E1000_FFVT_REG(_i) (0x09800 + ((_i) * 8))
#define E1000_FFLT_REG(_i) (0x05F00 + ((_i) * 8))
#define E1000_VFTA 0x05600 /* VLAN Filter Table Array - RW Array */
#define E1000_VT_CTL 0x0581C /* VMDq Control - RW */
#define E1000_WUC 0x05800 /* Wakeup Control - RW */
#define E1000_WUFC 0x05808 /* Wakeup Filter Control - RW */
#define E1000_WUS 0x05810 /* Wakeup Status - R/W1C */
#define E1000_MANC 0x05820 /* Management Control - RW */
#define E1000_IPAV 0x05838 /* IP Address Valid - RW */
#define E1000_WUPL 0x05900 /* Wakeup Packet Length - RW */
#define E1000_SW_FW_SYNC 0x05B5C /* Software-Firmware Synchronization - RW */
#define E1000_CCMCTL 0x05B48 /* CCM Control Register */
#define E1000_GIOCTL 0x05B44 /* GIO Analog Control Register */
#define E1000_SCCTL 0x05B4C /* PCIc PLL Configuration Register */
#define E1000_GCR 0x05B00 /* PCI-Ex Control */
#define E1000_FACTPS 0x05B30 /* Function Active and Power State to MNG */
#define E1000_SWSM 0x05B50 /* SW Semaphore */
#define E1000_FWSM 0x05B54 /* FW Semaphore */
#define E1000_DCA_CTRL 0x05B74 /* DCA Control - RW */
/* RSS registers */
#define E1000_MRQC 0x05818 /* Multiple Receive Control - RW */
#define E1000_IMIR(_i) (0x05A80 + ((_i) * 4)) /* Immediate Interrupt */
#define E1000_IMIREXT(_i) (0x05AA0 + ((_i) * 4)) /* Immediate Interrupt Ext*/
#define E1000_IMIRVP 0x05AC0 /* Immediate Interrupt RX VLAN Priority - RW */
/* MSI-X Allocation Register (_i) - RW */
#define E1000_MSIXBM(_i) (0x01600 + ((_i) * 4))
/* Redirection Table - RW Array */
#define E1000_RETA(_i) (0x05C00 + ((_i) * 4))
#define E1000_RSSRK(_i) (0x05C80 + ((_i) * 4)) /* RSS Random Key - RW Array */
/* VT Registers */
#define E1000_MBVFICR 0x00C80 /* Mailbox VF Cause - RWC */
#define E1000_MBVFIMR 0x00C84 /* Mailbox VF int Mask - RW */
#define E1000_VFLRE 0x00C88 /* VF Register Events - RWC */
#define E1000_VFRE 0x00C8C /* VF Receive Enables */
#define E1000_VFTE 0x00C90 /* VF Transmit Enables */
#define E1000_QDE 0x02408 /* Queue Drop Enable - RW */
#define E1000_DTXSWC 0x03500 /* DMA Tx Switch Control - RW */
#define E1000_WVBR 0x03554 /* VM Wrong Behavior - RWS */
#define E1000_RPLOLR 0x05AF0 /* Replication Offload - RW */
#define E1000_UTA 0x0A000 /* Unicast Table Array - RW */
#define E1000_IOVTCL 0x05BBC /* IOV Control Register */
#define E1000_TXSWC 0x05ACC /* Tx Switch Control */
#define E1000_LVMMC 0x03548 /* Last VM Misbehavior cause */
/* These act per VF so an array friendly macro is used */
#define E1000_P2VMAILBOX(_n) (0x00C00 + (4 * (_n)))
#define E1000_VMBMEM(_n) (0x00800 + (64 * (_n)))
#define E1000_VMOLR(_n) (0x05AD0 + (4 * (_n)))
#define E1000_DVMOLR(_n) (0x0C038 + (64 * (_n)))
#define E1000_VLVF(_n) (0x05D00 + (4 * (_n))) /* VLAN VM Filter */
#define E1000_VMVIR(_n) (0x03700 + (4 * (_n)))
struct e1000_hw;
u32 igb_rd32(struct e1000_hw *hw, u32 reg);
/* write operations, indexed using DWORDS */
#define wr32(reg, val) \
do { \
u8 __iomem *hw_addr = READ_ONCE((hw)->hw_addr); \
if (!E1000_REMOVED(hw_addr)) \
writel((val), &hw_addr[(reg)]); \
} while (0)
#define rd32(reg) (igb_rd32(hw, reg))
#define wrfl() ((void)rd32(E1000_STATUS))
#define array_wr32(reg, offset, value) \
wr32((reg) + ((offset) << 2), (value))
#define array_rd32(reg, offset) (igb_rd32(hw, reg + ((offset) << 2)))
/* DMA Coalescing registers */
#define E1000_PCIEMISC 0x05BB8 /* PCIE misc config register */
/* Energy Efficient Ethernet "EEE" register */
#define E1000_IPCNFG 0x0E38 /* Internal PHY Configuration */
#define E1000_EEER 0x0E30 /* Energy Efficient Ethernet */
#define E1000_EEE_SU 0X0E34 /* EEE Setup */
#define E1000_EMIADD 0x10 /* Extended Memory Indirect Address */
#define E1000_EMIDATA 0x11 /* Extended Memory Indirect Data */
#define E1000_MMDAC 13 /* MMD Access Control */
#define E1000_MMDAAD 14 /* MMD Access Address/Data */
/* Thermal Sensor Register */
#define E1000_THSTAT 0x08110 /* Thermal Sensor Status */
/* OS2BMC Registers */
#define E1000_B2OSPC 0x08FE0 /* BMC2OS packets sent by BMC */
#define E1000_B2OGPRC 0x04158 /* BMC2OS packets received by host */
#define E1000_O2BGPTC 0x08FE4 /* OS2BMC packets received by BMC */
#define E1000_O2BSPC 0x0415C /* OS2BMC packets transmitted by host */
#define E1000_SRWR 0x12018 /* Shadow Ram Write Register - RW */
#define E1000_I210_FLMNGCTL 0x12038
#define E1000_I210_FLMNGDATA 0x1203C
#define E1000_I210_FLMNGCNT 0x12040
#define E1000_I210_FLSWCTL 0x12048
#define E1000_I210_FLSWDATA 0x1204C
#define E1000_I210_FLSWCNT 0x12050
#define E1000_I210_FLA 0x1201C
#define E1000_I210_DTXMXPKTSZ 0x355C
#define E1000_I210_TXDCTL(_n) (0x0E028 + ((_n) * 0x40))
#define E1000_I210_TQAVCTRL 0x3570
#define E1000_I210_TQAVCC(_n) (0x3004 + ((_n) * 0x40))
#define E1000_I210_TQAVHC(_n) (0x300C + ((_n) * 0x40))
#define E1000_I210_RR2DCDELAY 0x5BF4
#define E1000_INVM_DATA_REG(_n) (0x12120 + 4*(_n))
#define E1000_INVM_SIZE 64 /* Number of INVM Data Registers */
#define E1000_REMOVED(h) unlikely(!(h))
#endif

View File

@ -0,0 +1,828 @@
/* SPDX-License-Identifier: GPL-2.0 */
/* Copyright(c) 2007 - 2018 Intel Corporation. */
/* Linux PRO/1000 Ethernet Driver main header file */
#ifndef _IGB_H_
#define _IGB_H_
#include "e1000_mac-6.1-ethercat.h"
#include "e1000_82575-6.1-ethercat.h"
#include <linux/timecounter.h>
#include <linux/net_tstamp.h>
#include <linux/ptp_clock_kernel.h>
#include <linux/bitops.h>
#include <linux/if_vlan.h>
#include <linux/i2c.h>
#include <linux/i2c-algo-bit.h>
#include <linux/irq_work.h>
#include <linux/pci.h>
#include <linux/mdio.h>
#include <net/xdp.h>
/* EtherCAT header file */
#include "../ecdev.h"
struct igb_adapter;
#define E1000_PCS_CFG_IGN_SD 1
/* Interrupt defines */
#define IGB_START_ITR 648 /* ~6000 ints/sec */
#define IGB_4K_ITR 980
#define IGB_20K_ITR 196
#define IGB_70K_ITR 56
/* TX/RX descriptor defines */
#define IGB_DEFAULT_TXD 256
#define IGB_DEFAULT_TX_WORK 128
#define IGB_MIN_TXD 80
#define IGB_MAX_TXD 4096
#define IGB_DEFAULT_RXD 256
#define IGB_MIN_RXD 80
#define IGB_MAX_RXD 4096
#define IGB_DEFAULT_ITR 3 /* dynamic */
#define IGB_MAX_ITR_USECS 10000
#define IGB_MIN_ITR_USECS 10
#define NON_Q_VECTORS 1
#define MAX_Q_VECTORS 8
#define MAX_MSIX_ENTRIES 10
/* Transmit and receive queues */
#define IGB_MAX_RX_QUEUES 8
#define IGB_MAX_RX_QUEUES_82575 4
#define IGB_MAX_RX_QUEUES_I211 2
#define IGB_MAX_TX_QUEUES 8
#define IGB_MAX_VF_MC_ENTRIES 30
#define IGB_MAX_VF_FUNCTIONS 8
#define IGB_MAX_VFTA_ENTRIES 128
#define IGB_82576_VF_DEV_ID 0x10CA
#define IGB_I350_VF_DEV_ID 0x1520
/* NVM version defines */
#define IGB_MAJOR_MASK 0xF000
#define IGB_MINOR_MASK 0x0FF0
#define IGB_BUILD_MASK 0x000F
#define IGB_COMB_VER_MASK 0x00FF
#define IGB_MAJOR_SHIFT 12
#define IGB_MINOR_SHIFT 4
#define IGB_COMB_VER_SHFT 8
#define IGB_NVM_VER_INVALID 0xFFFF
#define IGB_ETRACK_SHIFT 16
#define NVM_ETRACK_WORD 0x0042
#define NVM_COMB_VER_OFF 0x0083
#define NVM_COMB_VER_PTR 0x003d
/* Transmit and receive latency (for PTP timestamps) */
#define IGB_I210_TX_LATENCY_10 9542
#define IGB_I210_TX_LATENCY_100 1024
#define IGB_I210_TX_LATENCY_1000 178
#define IGB_I210_RX_LATENCY_10 20662
#define IGB_I210_RX_LATENCY_100 2213
#define IGB_I210_RX_LATENCY_1000 448
/* XDP */
#define IGB_XDP_PASS 0
#define IGB_XDP_CONSUMED BIT(0)
#define IGB_XDP_TX BIT(1)
#define IGB_XDP_REDIR BIT(2)
struct vf_data_storage {
unsigned char vf_mac_addresses[ETH_ALEN];
u16 vf_mc_hashes[IGB_MAX_VF_MC_ENTRIES];
u16 num_vf_mc_hashes;
u32 flags;
unsigned long last_nack;
u16 pf_vlan; /* When set, guest VLAN config not allowed. */
u16 pf_qos;
u16 tx_rate;
bool spoofchk_enabled;
bool trusted;
};
/* Number of unicast MAC filters reserved for the PF in the RAR registers */
#define IGB_PF_MAC_FILTERS_RESERVED 3
struct vf_mac_filter {
struct list_head l;
int vf;
bool free;
u8 vf_mac[ETH_ALEN];
};
#define IGB_VF_FLAG_CTS 0x00000001 /* VF is clear to send data */
#define IGB_VF_FLAG_UNI_PROMISC 0x00000002 /* VF has unicast promisc */
#define IGB_VF_FLAG_MULTI_PROMISC 0x00000004 /* VF has multicast promisc */
#define IGB_VF_FLAG_PF_SET_MAC 0x00000008 /* PF has set MAC address */
/* RX descriptor control thresholds.
* PTHRESH - MAC will consider prefetch if it has fewer than this number of
* descriptors available in its onboard memory.
* Setting this to 0 disables RX descriptor prefetch.
* HTHRESH - MAC will only prefetch if there are at least this many descriptors
* available in host memory.
* If PTHRESH is 0, this should also be 0.
* WTHRESH - RX descriptor writeback threshold - MAC will delay writing back
* descriptors until either it has this many to write back, or the
* ITR timer expires.
*/
#define IGB_RX_PTHRESH ((hw->mac.type == e1000_i354) ? 12 : 8)
#define IGB_RX_HTHRESH 8
#define IGB_TX_PTHRESH ((hw->mac.type == e1000_i354) ? 20 : 8)
#define IGB_TX_HTHRESH 1
#define IGB_RX_WTHRESH ((hw->mac.type == e1000_82576 && \
(adapter->flags & IGB_FLAG_HAS_MSIX)) ? 1 : 4)
#define IGB_TX_WTHRESH ((hw->mac.type == e1000_82576 && \
(adapter->flags & IGB_FLAG_HAS_MSIX)) ? 1 : 16)
/* this is the size past which hardware will drop packets when setting LPE=0 */
#define MAXIMUM_ETHERNET_VLAN_SIZE 1522
#define IGB_ETH_PKT_HDR_PAD (ETH_HLEN + ETH_FCS_LEN + (VLAN_HLEN * 2))
/* Supported Rx Buffer Sizes */
#define IGB_RXBUFFER_256 256
#define IGB_RXBUFFER_1536 1536
#define IGB_RXBUFFER_2048 2048
#define IGB_RXBUFFER_3072 3072
#define IGB_RX_HDR_LEN IGB_RXBUFFER_256
#define IGB_TS_HDR_LEN 16
/* Attempt to maximize the headroom available for incoming frames. We
* use a 2K buffer for receives and need 1536/1534 to store the data for
* the frame. This leaves us with 512 bytes of room. From that we need
* to deduct the space needed for the shared info and the padding needed
* to IP align the frame.
*
* Note: For cache line sizes 256 or larger this value is going to end
* up negative. In these cases we should fall back to the 3K
* buffers.
*/
#if (PAGE_SIZE < 8192)
#define IGB_MAX_FRAME_BUILD_SKB (IGB_RXBUFFER_1536 - NET_IP_ALIGN)
#define IGB_2K_TOO_SMALL_WITH_PADDING \
((NET_SKB_PAD + IGB_TS_HDR_LEN + IGB_RXBUFFER_1536) > SKB_WITH_OVERHEAD(IGB_RXBUFFER_2048))
static inline int igb_compute_pad(int rx_buf_len)
{
int page_size, pad_size;
page_size = ALIGN(rx_buf_len, PAGE_SIZE / 2);
pad_size = SKB_WITH_OVERHEAD(page_size) - rx_buf_len;
return pad_size;
}
static inline int igb_skb_pad(void)
{
int rx_buf_len;
/* If a 2K buffer cannot handle a standard Ethernet frame then
* optimize padding for a 3K buffer instead of a 1.5K buffer.
*
* For a 3K buffer we need to add enough padding to allow for
* tailroom due to NET_IP_ALIGN possibly shifting us out of
* cache-line alignment.
*/
if (IGB_2K_TOO_SMALL_WITH_PADDING)
rx_buf_len = IGB_RXBUFFER_3072 + SKB_DATA_ALIGN(NET_IP_ALIGN);
else
rx_buf_len = IGB_RXBUFFER_1536;
/* if needed make room for NET_IP_ALIGN */
rx_buf_len -= NET_IP_ALIGN;
return igb_compute_pad(rx_buf_len);
}
#define IGB_SKB_PAD igb_skb_pad()
#else
#define IGB_SKB_PAD (NET_SKB_PAD + NET_IP_ALIGN)
#endif
/* How many Rx Buffers do we bundle into one write to the hardware ? */
#define IGB_RX_BUFFER_WRITE 16 /* Must be power of 2 */
#define IGB_RX_DMA_ATTR \
(DMA_ATTR_SKIP_CPU_SYNC | DMA_ATTR_WEAK_ORDERING)
#define AUTO_ALL_MODES 0
#define IGB_EEPROM_APME 0x0400
#ifndef IGB_MASTER_SLAVE
/* Switch to override PHY master/slave setting */
#define IGB_MASTER_SLAVE e1000_ms_hw_default
#endif
#define IGB_MNG_VLAN_NONE -1
enum igb_tx_flags {
/* cmd_type flags */
IGB_TX_FLAGS_VLAN = 0x01,
IGB_TX_FLAGS_TSO = 0x02,
IGB_TX_FLAGS_TSTAMP = 0x04,
/* olinfo flags */
IGB_TX_FLAGS_IPV4 = 0x10,
IGB_TX_FLAGS_CSUM = 0x20,
};
/* VLAN info */
#define IGB_TX_FLAGS_VLAN_MASK 0xffff0000
#define IGB_TX_FLAGS_VLAN_SHIFT 16
/* 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.
*/
#define IGB_MAX_TXD_PWR 15
#define IGB_MAX_DATA_PER_TXD (1u << IGB_MAX_TXD_PWR)
/* Tx Descriptors needed, worst case */
#define TXD_USE_COUNT(S) DIV_ROUND_UP((S), IGB_MAX_DATA_PER_TXD)
#define DESC_NEEDED (MAX_SKB_FRAGS + 4)
/* EEPROM byte offsets */
#define IGB_SFF_8472_SWAP 0x5C
#define IGB_SFF_8472_COMP 0x5E
/* Bitmasks */
#define IGB_SFF_ADDRESSING_MODE 0x4
#define IGB_SFF_8472_UNSUP 0x00
/* TX resources are shared between XDP and netstack
* and we need to tag the buffer type to distinguish them
*/
enum igb_tx_buf_type {
IGB_TYPE_SKB = 0,
IGB_TYPE_XDP,
};
/* wrapper around a pointer to a socket buffer,
* so a DMA handle can be stored along with the buffer
*/
struct igb_tx_buffer {
union e1000_adv_tx_desc *next_to_watch;
unsigned long time_stamp;
enum igb_tx_buf_type type;
union {
struct sk_buff *skb;
struct xdp_frame *xdpf;
};
unsigned int bytecount;
u16 gso_segs;
__be16 protocol;
DEFINE_DMA_UNMAP_ADDR(dma);
DEFINE_DMA_UNMAP_LEN(len);
u32 tx_flags;
};
struct igb_rx_buffer {
dma_addr_t dma;
struct page *page;
#if (BITS_PER_LONG > 32) || (PAGE_SIZE >= 65536)
__u32 page_offset;
#else
__u16 page_offset;
#endif
__u16 pagecnt_bias;
};
struct igb_tx_queue_stats {
u64 packets;
u64 bytes;
u64 restart_queue;
u64 restart_queue2;
};
struct igb_rx_queue_stats {
u64 packets;
u64 bytes;
u64 drops;
u64 csum_err;
u64 alloc_failed;
};
struct igb_ring_container {
struct igb_ring *ring; /* pointer to linked list of rings */
unsigned int total_bytes; /* total bytes processed this int */
unsigned int total_packets; /* total packets processed this int */
u16 work_limit; /* total work allowed per interrupt */
u8 count; /* total number of rings in vector */
u8 itr; /* current ITR setting for ring */
};
struct igb_ring {
struct igb_q_vector *q_vector; /* backlink to q_vector */
struct net_device *netdev; /* back pointer to net_device */
struct bpf_prog *xdp_prog;
struct device *dev; /* device pointer for dma mapping */
union { /* array of buffer info structs */
struct igb_tx_buffer *tx_buffer_info;
struct igb_rx_buffer *rx_buffer_info;
};
void *desc; /* descriptor ring memory */
unsigned long flags; /* ring specific flags */
void __iomem *tail; /* pointer to ring tail register */
dma_addr_t dma; /* phys address of the ring */
unsigned int size; /* length of desc. ring in bytes */
u16 count; /* number of desc. in the ring */
u8 queue_index; /* logical index of the ring*/
u8 reg_idx; /* physical index of the ring */
bool launchtime_enable; /* true if LaunchTime is enabled */
bool cbs_enable; /* indicates if CBS is enabled */
s32 idleslope; /* idleSlope in kbps */
s32 sendslope; /* sendSlope in kbps */
s32 hicredit; /* hiCredit in bytes */
s32 locredit; /* loCredit in bytes */
/* everything past this point are written often */
u16 next_to_clean;
u16 next_to_use;
u16 next_to_alloc;
union {
/* TX */
struct {
struct igb_tx_queue_stats tx_stats;
struct u64_stats_sync tx_syncp;
struct u64_stats_sync tx_syncp2;
};
/* RX */
struct {
struct sk_buff *skb;
struct igb_rx_queue_stats rx_stats;
struct u64_stats_sync rx_syncp;
};
};
struct xdp_rxq_info xdp_rxq;
} ____cacheline_internodealigned_in_smp;
struct igb_q_vector {
struct igb_adapter *adapter; /* backlink */
int cpu; /* CPU for DCA */
u32 eims_value; /* EIMS mask value */
u16 itr_val;
u8 set_itr;
void __iomem *itr_register;
struct igb_ring_container rx, tx;
struct napi_struct napi;
struct rcu_head rcu; /* to avoid race with update stats on free */
char name[IFNAMSIZ + 9];
/* for dynamic allocation of rings associated with this q_vector */
struct igb_ring ring[] ____cacheline_internodealigned_in_smp;
};
enum e1000_ring_flags_t {
IGB_RING_FLAG_RX_3K_BUFFER,
IGB_RING_FLAG_RX_BUILD_SKB_ENABLED,
IGB_RING_FLAG_RX_SCTP_CSUM,
IGB_RING_FLAG_RX_LB_VLAN_BSWAP,
IGB_RING_FLAG_TX_CTX_IDX,
IGB_RING_FLAG_TX_DETECT_HANG
};
#define ring_uses_large_buffer(ring) \
test_bit(IGB_RING_FLAG_RX_3K_BUFFER, &(ring)->flags)
#define set_ring_uses_large_buffer(ring) \
set_bit(IGB_RING_FLAG_RX_3K_BUFFER, &(ring)->flags)
#define clear_ring_uses_large_buffer(ring) \
clear_bit(IGB_RING_FLAG_RX_3K_BUFFER, &(ring)->flags)
#define ring_uses_build_skb(ring) \
test_bit(IGB_RING_FLAG_RX_BUILD_SKB_ENABLED, &(ring)->flags)
#define set_ring_build_skb_enabled(ring) \
set_bit(IGB_RING_FLAG_RX_BUILD_SKB_ENABLED, &(ring)->flags)
#define clear_ring_build_skb_enabled(ring) \
clear_bit(IGB_RING_FLAG_RX_BUILD_SKB_ENABLED, &(ring)->flags)
static inline unsigned int igb_rx_bufsz(struct igb_ring *ring)
{
#if (PAGE_SIZE < 8192)
if (ring_uses_large_buffer(ring))
return IGB_RXBUFFER_3072;
if (ring_uses_build_skb(ring))
return IGB_MAX_FRAME_BUILD_SKB;
#endif
return IGB_RXBUFFER_2048;
}
static inline unsigned int igb_rx_pg_order(struct igb_ring *ring)
{
#if (PAGE_SIZE < 8192)
if (ring_uses_large_buffer(ring))
return 1;
#endif
return 0;
}
#define igb_rx_pg_size(_ring) (PAGE_SIZE << igb_rx_pg_order(_ring))
#define IGB_TXD_DCMD (E1000_ADVTXD_DCMD_EOP | E1000_ADVTXD_DCMD_RS)
#define IGB_RX_DESC(R, i) \
(&(((union e1000_adv_rx_desc *)((R)->desc))[i]))
#define IGB_TX_DESC(R, i) \
(&(((union e1000_adv_tx_desc *)((R)->desc))[i]))
#define IGB_TX_CTXTDESC(R, i) \
(&(((struct e1000_adv_tx_context_desc *)((R)->desc))[i]))
/* igb_test_staterr - tests bits within Rx descriptor status and error fields */
static inline __le32 igb_test_staterr(union e1000_adv_rx_desc *rx_desc,
const u32 stat_err_bits)
{
return rx_desc->wb.upper.status_error & cpu_to_le32(stat_err_bits);
}
/* igb_desc_unused - calculate if we have unused descriptors */
static inline int igb_desc_unused(struct igb_ring *ring)
{
if (ring->next_to_clean > ring->next_to_use)
return ring->next_to_clean - ring->next_to_use - 1;
return ring->count + ring->next_to_clean - ring->next_to_use - 1;
}
#ifdef CONFIG_IGB_HWMON
#define IGB_HWMON_TYPE_LOC 0
#define IGB_HWMON_TYPE_TEMP 1
#define IGB_HWMON_TYPE_CAUTION 2
#define IGB_HWMON_TYPE_MAX 3
struct hwmon_attr {
struct device_attribute dev_attr;
struct e1000_hw *hw;
struct e1000_thermal_diode_data *sensor;
char name[12];
};
struct hwmon_buff {
struct attribute_group group;
const struct attribute_group *groups[2];
struct attribute *attrs[E1000_MAX_SENSORS * 4 + 1];
struct hwmon_attr hwmon_list[E1000_MAX_SENSORS * 4];
unsigned int n_hwmon;
};
#endif
/* The number of L2 ether-type filter registers, Index 3 is reserved
* for PTP 1588 timestamp
*/
#define MAX_ETYPE_FILTER (4 - 1)
/* ETQF filter list: one static filter per filter consumer. This is
* to avoid filter collisions later. Add new filters here!!
*
* Current filters: Filter 3
*/
#define IGB_ETQF_FILTER_1588 3
#define IGB_N_EXTTS 2
#define IGB_N_PEROUT 2
#define IGB_N_SDP 4
#define IGB_RETA_SIZE 128
enum igb_filter_match_flags {
IGB_FILTER_FLAG_ETHER_TYPE = 0x1,
IGB_FILTER_FLAG_VLAN_TCI = 0x2,
IGB_FILTER_FLAG_SRC_MAC_ADDR = 0x4,
IGB_FILTER_FLAG_DST_MAC_ADDR = 0x8,
};
#define IGB_MAX_RXNFC_FILTERS 16
/* RX network flow classification data structure */
struct igb_nfc_input {
/* Byte layout in order, all values with MSB first:
* match_flags - 1 byte
* etype - 2 bytes
* vlan_tci - 2 bytes
*/
u8 match_flags;
__be16 etype;
__be16 vlan_tci;
u8 src_addr[ETH_ALEN];
u8 dst_addr[ETH_ALEN];
};
struct igb_nfc_filter {
struct hlist_node nfc_node;
struct igb_nfc_input filter;
unsigned long cookie;
u16 etype_reg_index;
u16 sw_idx;
u16 action;
};
struct igb_mac_addr {
u8 addr[ETH_ALEN];
u8 queue;
u8 state; /* bitmask */
};
#define IGB_MAC_STATE_DEFAULT 0x1
#define IGB_MAC_STATE_IN_USE 0x2
#define IGB_MAC_STATE_SRC_ADDR 0x4
#define IGB_MAC_STATE_QUEUE_STEERING 0x8
/* board specific private data structure */
struct igb_adapter {
unsigned long active_vlans[BITS_TO_LONGS(VLAN_N_VID)];
struct net_device *netdev;
struct bpf_prog *xdp_prog;
unsigned long state;
unsigned int flags;
unsigned int num_q_vectors;
struct msix_entry msix_entries[MAX_MSIX_ENTRIES];
/* Interrupt Throttle Rate */
u32 rx_itr_setting;
u32 tx_itr_setting;
u16 tx_itr;
u16 rx_itr;
/* TX */
u16 tx_work_limit;
u32 tx_timeout_count;
int num_tx_queues;
struct igb_ring *tx_ring[16];
/* RX */
int num_rx_queues;
struct igb_ring *rx_ring[16];
u32 max_frame_size;
u32 min_frame_size;
struct timer_list watchdog_timer;
struct timer_list phy_info_timer;
u16 mng_vlan_id;
u32 bd_number;
u32 wol;
u32 en_mng_pt;
u16 link_speed;
u16 link_duplex;
u8 __iomem *io_addr; /* Mainly for iounmap use */
struct work_struct reset_task;
struct work_struct watchdog_task;
bool fc_autoneg;
u8 tx_timeout_factor;
struct timer_list blink_timer;
unsigned long led_status;
/* OS defined structs */
struct pci_dev *pdev;
spinlock_t stats64_lock;
struct rtnl_link_stats64 stats64;
/* structs defined in e1000_hw.h */
struct e1000_hw hw;
struct e1000_hw_stats stats;
struct e1000_phy_info phy_info;
u32 test_icr;
struct igb_ring test_tx_ring;
struct igb_ring test_rx_ring;
int msg_enable;
struct igb_q_vector *q_vector[MAX_Q_VECTORS];
u32 eims_enable_mask;
u32 eims_other;
/* to not mess up cache alignment, always add to the bottom */
u16 tx_ring_count;
u16 rx_ring_count;
unsigned int vfs_allocated_count;
struct vf_data_storage *vf_data;
int vf_rate_link_speed;
u32 rss_queues;
u32 wvbr;
u32 *shadow_vfta;
struct ptp_clock *ptp_clock;
struct ptp_clock_info ptp_caps;
struct delayed_work ptp_overflow_work;
struct work_struct ptp_tx_work;
struct sk_buff *ptp_tx_skb;
struct hwtstamp_config tstamp_config;
unsigned long ptp_tx_start;
unsigned long last_rx_ptp_check;
unsigned long last_rx_timestamp;
unsigned int ptp_flags;
spinlock_t tmreg_lock;
struct cyclecounter cc;
struct timecounter tc;
u32 tx_hwtstamp_timeouts;
u32 tx_hwtstamp_skipped;
u32 rx_hwtstamp_cleared;
bool pps_sys_wrap_on;
struct ptp_pin_desc sdp_config[IGB_N_SDP];
struct {
struct timespec64 start;
struct timespec64 period;
} perout[IGB_N_PEROUT];
char fw_version[32];
#ifdef CONFIG_IGB_HWMON
struct hwmon_buff *igb_hwmon_buff;
bool ets;
#endif
struct i2c_algo_bit_data i2c_algo;
struct i2c_adapter i2c_adap;
struct i2c_client *i2c_client;
u32 rss_indir_tbl_init;
u8 rss_indir_tbl[IGB_RETA_SIZE];
unsigned long link_check_timeout;
int copper_tries;
struct e1000_info ei;
u16 eee_advert;
/* RX network flow classification support */
struct hlist_head nfc_filter_list;
struct hlist_head cls_flower_list;
unsigned int nfc_filter_count;
/* lock for RX network flow classification filter */
spinlock_t nfc_lock;
bool etype_bitmap[MAX_ETYPE_FILTER];
struct igb_mac_addr *mac_table;
struct vf_mac_filter vf_macs;
struct vf_mac_filter *vf_mac_list;
/* lock for VF resources */
spinlock_t vfs_lock;
/* EtherCAT device variables */
ec_device_t *ecdev_;
unsigned long ec_watchdog_jiffies;
struct irq_work ec_watchdog_kicker;
bool ecdev_initialized;
};
static inline ec_device_t *get_ecdev(struct igb_adapter *adapter)
{
#ifdef EC_ENABLE_DRIVER_RESOURCE_VERIFYING
WARN_ON(!adapter->ecdev_initialized);
#endif
return adapter->ecdev_;
}
/* flags controlling PTP/1588 function */
#define IGB_PTP_ENABLED BIT(0)
#define IGB_PTP_OVERFLOW_CHECK BIT(1)
#define IGB_FLAG_HAS_MSI BIT(0)
#define IGB_FLAG_DCA_ENABLED BIT(1)
#define IGB_FLAG_QUAD_PORT_A BIT(2)
#define IGB_FLAG_QUEUE_PAIRS BIT(3)
#define IGB_FLAG_DMAC BIT(4)
#define IGB_FLAG_RSS_FIELD_IPV4_UDP BIT(6)
#define IGB_FLAG_RSS_FIELD_IPV6_UDP BIT(7)
#define IGB_FLAG_WOL_SUPPORTED BIT(8)
#define IGB_FLAG_NEED_LINK_UPDATE BIT(9)
#define IGB_FLAG_MEDIA_RESET BIT(10)
#define IGB_FLAG_MAS_CAPABLE BIT(11)
#define IGB_FLAG_MAS_ENABLE BIT(12)
#define IGB_FLAG_HAS_MSIX BIT(13)
#define IGB_FLAG_EEE BIT(14)
#define IGB_FLAG_VLAN_PROMISC BIT(15)
#define IGB_FLAG_RX_LEGACY BIT(16)
#define IGB_FLAG_FQTSS BIT(17)
/* Media Auto Sense */
#define IGB_MAS_ENABLE_0 0X0001
#define IGB_MAS_ENABLE_1 0X0002
#define IGB_MAS_ENABLE_2 0X0004
#define IGB_MAS_ENABLE_3 0X0008
/* DMA Coalescing defines */
#define IGB_MIN_TXPBSIZE 20408
#define IGB_TX_BUF_4096 4096
#define IGB_DMCTLX_DCFLUSH_DIS 0x80000000 /* Disable DMA Coal Flush */
#define IGB_82576_TSYNC_SHIFT 19
enum e1000_state_t {
__IGB_TESTING,
__IGB_RESETTING,
__IGB_DOWN,
__IGB_PTP_TX_IN_PROGRESS,
};
enum igb_boards {
board_82575,
};
extern char igb_driver_name[];
int igb_xmit_xdp_ring(struct igb_adapter *adapter,
struct igb_ring *ring,
struct xdp_frame *xdpf);
int igb_open(struct net_device *netdev);
int igb_close(struct net_device *netdev);
int igb_up(struct igb_adapter *);
void igb_down(struct igb_adapter *);
void igb_reinit_locked(struct igb_adapter *);
void igb_reset(struct igb_adapter *);
int igb_reinit_queues(struct igb_adapter *);
void igb_write_rss_indir_tbl(struct igb_adapter *);
int igb_set_spd_dplx(struct igb_adapter *, u32, u8);
int igb_setup_tx_resources(struct igb_ring *);
int igb_setup_rx_resources(struct igb_ring *);
void igb_free_tx_resources(struct igb_ring *);
void igb_free_rx_resources(struct igb_ring *);
void igb_configure_tx_ring(struct igb_adapter *, struct igb_ring *);
void igb_configure_rx_ring(struct igb_adapter *, struct igb_ring *);
void igb_setup_tctl(struct igb_adapter *);
void igb_setup_rctl(struct igb_adapter *);
void igb_setup_srrctl(struct igb_adapter *, struct igb_ring *);
netdev_tx_t igb_xmit_frame_ring(struct sk_buff *, struct igb_ring *);
void igb_alloc_rx_buffers(struct igb_ring *, u16);
void igb_update_stats(struct igb_adapter *);
bool igb_has_link(struct igb_adapter *adapter);
void igb_set_ethtool_ops(struct net_device *);
void igb_power_up_link(struct igb_adapter *);
void igb_set_fw_version(struct igb_adapter *);
void igb_ptp_init(struct igb_adapter *adapter);
void igb_ptp_stop(struct igb_adapter *adapter);
void igb_ptp_reset(struct igb_adapter *adapter);
void igb_ptp_suspend(struct igb_adapter *adapter);
void igb_ptp_rx_hang(struct igb_adapter *adapter);
void igb_ptp_tx_hang(struct igb_adapter *adapter);
void igb_ptp_rx_rgtstamp(struct igb_q_vector *q_vector, struct sk_buff *skb);
int igb_ptp_rx_pktstamp(struct igb_q_vector *q_vector, void *va,
ktime_t *timestamp);
int igb_ptp_set_ts_config(struct net_device *netdev, struct ifreq *ifr);
int igb_ptp_get_ts_config(struct net_device *netdev, struct ifreq *ifr);
void igb_set_flag_queue_pairs(struct igb_adapter *, const u32);
unsigned int igb_get_max_rss_queues(struct igb_adapter *);
#ifdef CONFIG_IGB_HWMON
void igb_sysfs_exit(struct igb_adapter *adapter);
int igb_sysfs_init(struct igb_adapter *adapter);
#endif
static inline s32 igb_reset_phy(struct e1000_hw *hw)
{
if (hw->phy.ops.reset)
return hw->phy.ops.reset(hw);
return 0;
}
static inline s32 igb_read_phy_reg(struct e1000_hw *hw, u32 offset, u16 *data)
{
if (hw->phy.ops.read_reg)
return hw->phy.ops.read_reg(hw, offset, data);
return 0;
}
static inline s32 igb_write_phy_reg(struct e1000_hw *hw, u32 offset, u16 data)
{
if (hw->phy.ops.write_reg)
return hw->phy.ops.write_reg(hw, offset, data);
return 0;
}
static inline s32 igb_get_phy_info(struct e1000_hw *hw)
{
if (hw->phy.ops.get_phy_info)
return hw->phy.ops.get_phy_info(hw);
return 0;
}
static inline struct netdev_queue *txring_txq(const struct igb_ring *tx_ring)
{
return netdev_get_tx_queue(tx_ring->netdev, tx_ring->queue_index);
}
int igb_add_filter(struct igb_adapter *adapter,
struct igb_nfc_filter *input);
int igb_erase_filter(struct igb_adapter *adapter,
struct igb_nfc_filter *input);
int igb_add_mac_steering_filter(struct igb_adapter *adapter,
const u8 *addr, u8 queue, u8 flags);
int igb_del_mac_steering_filter(struct igb_adapter *adapter,
const u8 *addr, u8 queue, u8 flags);
#endif /* _IGB_H_ */

810
devices/igb/igb-6.4-orig.h Normal file
View File

@ -0,0 +1,810 @@
/* SPDX-License-Identifier: GPL-2.0 */
/* Copyright(c) 2007 - 2018 Intel Corporation. */
/* Linux PRO/1000 Ethernet Driver main header file */
#ifndef _IGB_H_
#define _IGB_H_
#include "e1000_mac.h"
#include "e1000_82575.h"
#include <linux/timecounter.h>
#include <linux/net_tstamp.h>
#include <linux/ptp_clock_kernel.h>
#include <linux/bitops.h>
#include <linux/if_vlan.h>
#include <linux/i2c.h>
#include <linux/i2c-algo-bit.h>
#include <linux/pci.h>
#include <linux/mdio.h>
#include <net/xdp.h>
struct igb_adapter;
#define E1000_PCS_CFG_IGN_SD 1
/* Interrupt defines */
#define IGB_START_ITR 648 /* ~6000 ints/sec */
#define IGB_4K_ITR 980
#define IGB_20K_ITR 196
#define IGB_70K_ITR 56
/* TX/RX descriptor defines */
#define IGB_DEFAULT_TXD 256
#define IGB_DEFAULT_TX_WORK 128
#define IGB_MIN_TXD 80
#define IGB_MAX_TXD 4096
#define IGB_DEFAULT_RXD 256
#define IGB_MIN_RXD 80
#define IGB_MAX_RXD 4096
#define IGB_DEFAULT_ITR 3 /* dynamic */
#define IGB_MAX_ITR_USECS 10000
#define IGB_MIN_ITR_USECS 10
#define NON_Q_VECTORS 1
#define MAX_Q_VECTORS 8
#define MAX_MSIX_ENTRIES 10
/* Transmit and receive queues */
#define IGB_MAX_RX_QUEUES 8
#define IGB_MAX_RX_QUEUES_82575 4
#define IGB_MAX_RX_QUEUES_I211 2
#define IGB_MAX_TX_QUEUES 8
#define IGB_MAX_VF_MC_ENTRIES 30
#define IGB_MAX_VF_FUNCTIONS 8
#define IGB_MAX_VFTA_ENTRIES 128
#define IGB_82576_VF_DEV_ID 0x10CA
#define IGB_I350_VF_DEV_ID 0x1520
/* NVM version defines */
#define IGB_MAJOR_MASK 0xF000
#define IGB_MINOR_MASK 0x0FF0
#define IGB_BUILD_MASK 0x000F
#define IGB_COMB_VER_MASK 0x00FF
#define IGB_MAJOR_SHIFT 12
#define IGB_MINOR_SHIFT 4
#define IGB_COMB_VER_SHFT 8
#define IGB_NVM_VER_INVALID 0xFFFF
#define IGB_ETRACK_SHIFT 16
#define NVM_ETRACK_WORD 0x0042
#define NVM_COMB_VER_OFF 0x0083
#define NVM_COMB_VER_PTR 0x003d
/* Transmit and receive latency (for PTP timestamps) */
#define IGB_I210_TX_LATENCY_10 9542
#define IGB_I210_TX_LATENCY_100 1024
#define IGB_I210_TX_LATENCY_1000 178
#define IGB_I210_RX_LATENCY_10 20662
#define IGB_I210_RX_LATENCY_100 2213
#define IGB_I210_RX_LATENCY_1000 448
/* XDP */
#define IGB_XDP_PASS 0
#define IGB_XDP_CONSUMED BIT(0)
#define IGB_XDP_TX BIT(1)
#define IGB_XDP_REDIR BIT(2)
struct vf_data_storage {
unsigned char vf_mac_addresses[ETH_ALEN];
u16 vf_mc_hashes[IGB_MAX_VF_MC_ENTRIES];
u16 num_vf_mc_hashes;
u32 flags;
unsigned long last_nack;
u16 pf_vlan; /* When set, guest VLAN config not allowed. */
u16 pf_qos;
u16 tx_rate;
bool spoofchk_enabled;
bool trusted;
};
/* Number of unicast MAC filters reserved for the PF in the RAR registers */
#define IGB_PF_MAC_FILTERS_RESERVED 3
struct vf_mac_filter {
struct list_head l;
int vf;
bool free;
u8 vf_mac[ETH_ALEN];
};
#define IGB_VF_FLAG_CTS 0x00000001 /* VF is clear to send data */
#define IGB_VF_FLAG_UNI_PROMISC 0x00000002 /* VF has unicast promisc */
#define IGB_VF_FLAG_MULTI_PROMISC 0x00000004 /* VF has multicast promisc */
#define IGB_VF_FLAG_PF_SET_MAC 0x00000008 /* PF has set MAC address */
/* RX descriptor control thresholds.
* PTHRESH - MAC will consider prefetch if it has fewer than this number of
* descriptors available in its onboard memory.
* Setting this to 0 disables RX descriptor prefetch.
* HTHRESH - MAC will only prefetch if there are at least this many descriptors
* available in host memory.
* If PTHRESH is 0, this should also be 0.
* WTHRESH - RX descriptor writeback threshold - MAC will delay writing back
* descriptors until either it has this many to write back, or the
* ITR timer expires.
*/
#define IGB_RX_PTHRESH ((hw->mac.type == e1000_i354) ? 12 : 8)
#define IGB_RX_HTHRESH 8
#define IGB_TX_PTHRESH ((hw->mac.type == e1000_i354) ? 20 : 8)
#define IGB_TX_HTHRESH 1
#define IGB_RX_WTHRESH ((hw->mac.type == e1000_82576 && \
(adapter->flags & IGB_FLAG_HAS_MSIX)) ? 1 : 4)
#define IGB_TX_WTHRESH ((hw->mac.type == e1000_82576 && \
(adapter->flags & IGB_FLAG_HAS_MSIX)) ? 1 : 16)
/* this is the size past which hardware will drop packets when setting LPE=0 */
#define MAXIMUM_ETHERNET_VLAN_SIZE 1522
#define IGB_ETH_PKT_HDR_PAD (ETH_HLEN + ETH_FCS_LEN + (VLAN_HLEN * 2))
/* Supported Rx Buffer Sizes */
#define IGB_RXBUFFER_256 256
#define IGB_RXBUFFER_1536 1536
#define IGB_RXBUFFER_2048 2048
#define IGB_RXBUFFER_3072 3072
#define IGB_RX_HDR_LEN IGB_RXBUFFER_256
#define IGB_TS_HDR_LEN 16
/* Attempt to maximize the headroom available for incoming frames. We
* use a 2K buffer for receives and need 1536/1534 to store the data for
* the frame. This leaves us with 512 bytes of room. From that we need
* to deduct the space needed for the shared info and the padding needed
* to IP align the frame.
*
* Note: For cache line sizes 256 or larger this value is going to end
* up negative. In these cases we should fall back to the 3K
* buffers.
*/
#if (PAGE_SIZE < 8192)
#define IGB_MAX_FRAME_BUILD_SKB (IGB_RXBUFFER_1536 - NET_IP_ALIGN)
#define IGB_2K_TOO_SMALL_WITH_PADDING \
((NET_SKB_PAD + IGB_TS_HDR_LEN + IGB_RXBUFFER_1536) > SKB_WITH_OVERHEAD(IGB_RXBUFFER_2048))
static inline int igb_compute_pad(int rx_buf_len)
{
int page_size, pad_size;
page_size = ALIGN(rx_buf_len, PAGE_SIZE / 2);
pad_size = SKB_WITH_OVERHEAD(page_size) - rx_buf_len;
return pad_size;
}
static inline int igb_skb_pad(void)
{
int rx_buf_len;
/* If a 2K buffer cannot handle a standard Ethernet frame then
* optimize padding for a 3K buffer instead of a 1.5K buffer.
*
* For a 3K buffer we need to add enough padding to allow for
* tailroom due to NET_IP_ALIGN possibly shifting us out of
* cache-line alignment.
*/
if (IGB_2K_TOO_SMALL_WITH_PADDING)
rx_buf_len = IGB_RXBUFFER_3072 + SKB_DATA_ALIGN(NET_IP_ALIGN);
else
rx_buf_len = IGB_RXBUFFER_1536;
/* if needed make room for NET_IP_ALIGN */
rx_buf_len -= NET_IP_ALIGN;
return igb_compute_pad(rx_buf_len);
}
#define IGB_SKB_PAD igb_skb_pad()
#else
#define IGB_SKB_PAD (NET_SKB_PAD + NET_IP_ALIGN)
#endif
/* How many Rx Buffers do we bundle into one write to the hardware ? */
#define IGB_RX_BUFFER_WRITE 16 /* Must be power of 2 */
#define IGB_RX_DMA_ATTR \
(DMA_ATTR_SKIP_CPU_SYNC | DMA_ATTR_WEAK_ORDERING)
#define AUTO_ALL_MODES 0
#define IGB_EEPROM_APME 0x0400
#ifndef IGB_MASTER_SLAVE
/* Switch to override PHY master/slave setting */
#define IGB_MASTER_SLAVE e1000_ms_hw_default
#endif
#define IGB_MNG_VLAN_NONE -1
enum igb_tx_flags {
/* cmd_type flags */
IGB_TX_FLAGS_VLAN = 0x01,
IGB_TX_FLAGS_TSO = 0x02,
IGB_TX_FLAGS_TSTAMP = 0x04,
/* olinfo flags */
IGB_TX_FLAGS_IPV4 = 0x10,
IGB_TX_FLAGS_CSUM = 0x20,
};
/* VLAN info */
#define IGB_TX_FLAGS_VLAN_MASK 0xffff0000
#define IGB_TX_FLAGS_VLAN_SHIFT 16
/* 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.
*/
#define IGB_MAX_TXD_PWR 15
#define IGB_MAX_DATA_PER_TXD (1u << IGB_MAX_TXD_PWR)
/* Tx Descriptors needed, worst case */
#define TXD_USE_COUNT(S) DIV_ROUND_UP((S), IGB_MAX_DATA_PER_TXD)
#define DESC_NEEDED (MAX_SKB_FRAGS + 4)
/* EEPROM byte offsets */
#define IGB_SFF_8472_SWAP 0x5C
#define IGB_SFF_8472_COMP 0x5E
/* Bitmasks */
#define IGB_SFF_ADDRESSING_MODE 0x4
#define IGB_SFF_8472_UNSUP 0x00
/* TX resources are shared between XDP and netstack
* and we need to tag the buffer type to distinguish them
*/
enum igb_tx_buf_type {
IGB_TYPE_SKB = 0,
IGB_TYPE_XDP,
};
/* wrapper around a pointer to a socket buffer,
* so a DMA handle can be stored along with the buffer
*/
struct igb_tx_buffer {
union e1000_adv_tx_desc *next_to_watch;
unsigned long time_stamp;
enum igb_tx_buf_type type;
union {
struct sk_buff *skb;
struct xdp_frame *xdpf;
};
unsigned int bytecount;
u16 gso_segs;
__be16 protocol;
DEFINE_DMA_UNMAP_ADDR(dma);
DEFINE_DMA_UNMAP_LEN(len);
u32 tx_flags;
};
struct igb_rx_buffer {
dma_addr_t dma;
struct page *page;
#if (BITS_PER_LONG > 32) || (PAGE_SIZE >= 65536)
__u32 page_offset;
#else
__u16 page_offset;
#endif
__u16 pagecnt_bias;
};
struct igb_tx_queue_stats {
u64 packets;
u64 bytes;
u64 restart_queue;
u64 restart_queue2;
};
struct igb_rx_queue_stats {
u64 packets;
u64 bytes;
u64 drops;
u64 csum_err;
u64 alloc_failed;
};
struct igb_ring_container {
struct igb_ring *ring; /* pointer to linked list of rings */
unsigned int total_bytes; /* total bytes processed this int */
unsigned int total_packets; /* total packets processed this int */
u16 work_limit; /* total work allowed per interrupt */
u8 count; /* total number of rings in vector */
u8 itr; /* current ITR setting for ring */
};
struct igb_ring {
struct igb_q_vector *q_vector; /* backlink to q_vector */
struct net_device *netdev; /* back pointer to net_device */
struct bpf_prog *xdp_prog;
struct device *dev; /* device pointer for dma mapping */
union { /* array of buffer info structs */
struct igb_tx_buffer *tx_buffer_info;
struct igb_rx_buffer *rx_buffer_info;
};
void *desc; /* descriptor ring memory */
unsigned long flags; /* ring specific flags */
void __iomem *tail; /* pointer to ring tail register */
dma_addr_t dma; /* phys address of the ring */
unsigned int size; /* length of desc. ring in bytes */
u16 count; /* number of desc. in the ring */
u8 queue_index; /* logical index of the ring*/
u8 reg_idx; /* physical index of the ring */
bool launchtime_enable; /* true if LaunchTime is enabled */
bool cbs_enable; /* indicates if CBS is enabled */
s32 idleslope; /* idleSlope in kbps */
s32 sendslope; /* sendSlope in kbps */
s32 hicredit; /* hiCredit in bytes */
s32 locredit; /* loCredit in bytes */
/* everything past this point are written often */
u16 next_to_clean;
u16 next_to_use;
u16 next_to_alloc;
union {
/* TX */
struct {
struct igb_tx_queue_stats tx_stats;
struct u64_stats_sync tx_syncp;
struct u64_stats_sync tx_syncp2;
};
/* RX */
struct {
struct sk_buff *skb;
struct igb_rx_queue_stats rx_stats;
struct u64_stats_sync rx_syncp;
};
};
struct xdp_rxq_info xdp_rxq;
} ____cacheline_internodealigned_in_smp;
struct igb_q_vector {
struct igb_adapter *adapter; /* backlink */
int cpu; /* CPU for DCA */
u32 eims_value; /* EIMS mask value */
u16 itr_val;
u8 set_itr;
void __iomem *itr_register;
struct igb_ring_container rx, tx;
struct napi_struct napi;
struct rcu_head rcu; /* to avoid race with update stats on free */
char name[IFNAMSIZ + 9];
/* for dynamic allocation of rings associated with this q_vector */
struct igb_ring ring[] ____cacheline_internodealigned_in_smp;
};
enum e1000_ring_flags_t {
IGB_RING_FLAG_RX_3K_BUFFER,
IGB_RING_FLAG_RX_BUILD_SKB_ENABLED,
IGB_RING_FLAG_RX_SCTP_CSUM,
IGB_RING_FLAG_RX_LB_VLAN_BSWAP,
IGB_RING_FLAG_TX_CTX_IDX,
IGB_RING_FLAG_TX_DETECT_HANG
};
#define ring_uses_large_buffer(ring) \
test_bit(IGB_RING_FLAG_RX_3K_BUFFER, &(ring)->flags)
#define set_ring_uses_large_buffer(ring) \
set_bit(IGB_RING_FLAG_RX_3K_BUFFER, &(ring)->flags)
#define clear_ring_uses_large_buffer(ring) \
clear_bit(IGB_RING_FLAG_RX_3K_BUFFER, &(ring)->flags)
#define ring_uses_build_skb(ring) \
test_bit(IGB_RING_FLAG_RX_BUILD_SKB_ENABLED, &(ring)->flags)
#define set_ring_build_skb_enabled(ring) \
set_bit(IGB_RING_FLAG_RX_BUILD_SKB_ENABLED, &(ring)->flags)
#define clear_ring_build_skb_enabled(ring) \
clear_bit(IGB_RING_FLAG_RX_BUILD_SKB_ENABLED, &(ring)->flags)
static inline unsigned int igb_rx_bufsz(struct igb_ring *ring)
{
#if (PAGE_SIZE < 8192)
if (ring_uses_large_buffer(ring))
return IGB_RXBUFFER_3072;
if (ring_uses_build_skb(ring))
return IGB_MAX_FRAME_BUILD_SKB;
#endif
return IGB_RXBUFFER_2048;
}
static inline unsigned int igb_rx_pg_order(struct igb_ring *ring)
{
#if (PAGE_SIZE < 8192)
if (ring_uses_large_buffer(ring))
return 1;
#endif
return 0;
}
#define igb_rx_pg_size(_ring) (PAGE_SIZE << igb_rx_pg_order(_ring))
#define IGB_TXD_DCMD (E1000_ADVTXD_DCMD_EOP | E1000_ADVTXD_DCMD_RS)
#define IGB_RX_DESC(R, i) \
(&(((union e1000_adv_rx_desc *)((R)->desc))[i]))
#define IGB_TX_DESC(R, i) \
(&(((union e1000_adv_tx_desc *)((R)->desc))[i]))
#define IGB_TX_CTXTDESC(R, i) \
(&(((struct e1000_adv_tx_context_desc *)((R)->desc))[i]))
/* igb_test_staterr - tests bits within Rx descriptor status and error fields */
static inline __le32 igb_test_staterr(union e1000_adv_rx_desc *rx_desc,
const u32 stat_err_bits)
{
return rx_desc->wb.upper.status_error & cpu_to_le32(stat_err_bits);
}
/* igb_desc_unused - calculate if we have unused descriptors */
static inline int igb_desc_unused(struct igb_ring *ring)
{
if (ring->next_to_clean > ring->next_to_use)
return ring->next_to_clean - ring->next_to_use - 1;
return ring->count + ring->next_to_clean - ring->next_to_use - 1;
}
#ifdef CONFIG_IGB_HWMON
#define IGB_HWMON_TYPE_LOC 0
#define IGB_HWMON_TYPE_TEMP 1
#define IGB_HWMON_TYPE_CAUTION 2
#define IGB_HWMON_TYPE_MAX 3
struct hwmon_attr {
struct device_attribute dev_attr;
struct e1000_hw *hw;
struct e1000_thermal_diode_data *sensor;
char name[12];
};
struct hwmon_buff {
struct attribute_group group;
const struct attribute_group *groups[2];
struct attribute *attrs[E1000_MAX_SENSORS * 4 + 1];
struct hwmon_attr hwmon_list[E1000_MAX_SENSORS * 4];
unsigned int n_hwmon;
};
#endif
/* The number of L2 ether-type filter registers, Index 3 is reserved
* for PTP 1588 timestamp
*/
#define MAX_ETYPE_FILTER (4 - 1)
/* ETQF filter list: one static filter per filter consumer. This is
* to avoid filter collisions later. Add new filters here!!
*
* Current filters: Filter 3
*/
#define IGB_ETQF_FILTER_1588 3
#define IGB_N_EXTTS 2
#define IGB_N_PEROUT 2
#define IGB_N_SDP 4
#define IGB_RETA_SIZE 128
enum igb_filter_match_flags {
IGB_FILTER_FLAG_ETHER_TYPE = 0x1,
IGB_FILTER_FLAG_VLAN_TCI = 0x2,
IGB_FILTER_FLAG_SRC_MAC_ADDR = 0x4,
IGB_FILTER_FLAG_DST_MAC_ADDR = 0x8,
};
#define IGB_MAX_RXNFC_FILTERS 16
/* RX network flow classification data structure */
struct igb_nfc_input {
/* Byte layout in order, all values with MSB first:
* match_flags - 1 byte
* etype - 2 bytes
* vlan_tci - 2 bytes
*/
u8 match_flags;
__be16 etype;
__be16 vlan_tci;
u8 src_addr[ETH_ALEN];
u8 dst_addr[ETH_ALEN];
};
struct igb_nfc_filter {
struct hlist_node nfc_node;
struct igb_nfc_input filter;
unsigned long cookie;
u16 etype_reg_index;
u16 sw_idx;
u16 action;
};
struct igb_mac_addr {
u8 addr[ETH_ALEN];
u8 queue;
u8 state; /* bitmask */
};
#define IGB_MAC_STATE_DEFAULT 0x1
#define IGB_MAC_STATE_IN_USE 0x2
#define IGB_MAC_STATE_SRC_ADDR 0x4
#define IGB_MAC_STATE_QUEUE_STEERING 0x8
/* board specific private data structure */
struct igb_adapter {
unsigned long active_vlans[BITS_TO_LONGS(VLAN_N_VID)];
struct net_device *netdev;
struct bpf_prog *xdp_prog;
unsigned long state;
unsigned int flags;
unsigned int num_q_vectors;
struct msix_entry msix_entries[MAX_MSIX_ENTRIES];
/* Interrupt Throttle Rate */
u32 rx_itr_setting;
u32 tx_itr_setting;
u16 tx_itr;
u16 rx_itr;
/* TX */
u16 tx_work_limit;
u32 tx_timeout_count;
int num_tx_queues;
struct igb_ring *tx_ring[16];
/* RX */
int num_rx_queues;
struct igb_ring *rx_ring[16];
u32 max_frame_size;
u32 min_frame_size;
struct timer_list watchdog_timer;
struct timer_list phy_info_timer;
u16 mng_vlan_id;
u32 bd_number;
u32 wol;
u32 en_mng_pt;
u16 link_speed;
u16 link_duplex;
u8 __iomem *io_addr; /* Mainly for iounmap use */
struct work_struct reset_task;
struct work_struct watchdog_task;
bool fc_autoneg;
u8 tx_timeout_factor;
struct timer_list blink_timer;
unsigned long led_status;
/* OS defined structs */
struct pci_dev *pdev;
spinlock_t stats64_lock;
struct rtnl_link_stats64 stats64;
/* structs defined in e1000_hw.h */
struct e1000_hw hw;
struct e1000_hw_stats stats;
struct e1000_phy_info phy_info;
u32 test_icr;
struct igb_ring test_tx_ring;
struct igb_ring test_rx_ring;
int msg_enable;
struct igb_q_vector *q_vector[MAX_Q_VECTORS];
u32 eims_enable_mask;
u32 eims_other;
/* to not mess up cache alignment, always add to the bottom */
u16 tx_ring_count;
u16 rx_ring_count;
unsigned int vfs_allocated_count;
struct vf_data_storage *vf_data;
int vf_rate_link_speed;
u32 rss_queues;
u32 wvbr;
u32 *shadow_vfta;
struct ptp_clock *ptp_clock;
struct ptp_clock_info ptp_caps;
struct delayed_work ptp_overflow_work;
struct work_struct ptp_tx_work;
struct sk_buff *ptp_tx_skb;
struct hwtstamp_config tstamp_config;
unsigned long ptp_tx_start;
unsigned long last_rx_ptp_check;
unsigned long last_rx_timestamp;
unsigned int ptp_flags;
spinlock_t tmreg_lock;
struct cyclecounter cc;
struct timecounter tc;
u32 tx_hwtstamp_timeouts;
u32 tx_hwtstamp_skipped;
u32 rx_hwtstamp_cleared;
bool pps_sys_wrap_on;
struct ptp_pin_desc sdp_config[IGB_N_SDP];
struct {
struct timespec64 start;
struct timespec64 period;
} perout[IGB_N_PEROUT];
char fw_version[32];
#ifdef CONFIG_IGB_HWMON
struct hwmon_buff *igb_hwmon_buff;
bool ets;
#endif
struct i2c_algo_bit_data i2c_algo;
struct i2c_adapter i2c_adap;
struct i2c_client *i2c_client;
u32 rss_indir_tbl_init;
u8 rss_indir_tbl[IGB_RETA_SIZE];
unsigned long link_check_timeout;
int copper_tries;
struct e1000_info ei;
u16 eee_advert;
/* RX network flow classification support */
struct hlist_head nfc_filter_list;
struct hlist_head cls_flower_list;
unsigned int nfc_filter_count;
/* lock for RX network flow classification filter */
spinlock_t nfc_lock;
bool etype_bitmap[MAX_ETYPE_FILTER];
struct igb_mac_addr *mac_table;
struct vf_mac_filter vf_macs;
struct vf_mac_filter *vf_mac_list;
/* lock for VF resources */
spinlock_t vfs_lock;
};
/* flags controlling PTP/1588 function */
#define IGB_PTP_ENABLED BIT(0)
#define IGB_PTP_OVERFLOW_CHECK BIT(1)
#define IGB_FLAG_HAS_MSI BIT(0)
#define IGB_FLAG_DCA_ENABLED BIT(1)
#define IGB_FLAG_QUAD_PORT_A BIT(2)
#define IGB_FLAG_QUEUE_PAIRS BIT(3)
#define IGB_FLAG_DMAC BIT(4)
#define IGB_FLAG_RSS_FIELD_IPV4_UDP BIT(6)
#define IGB_FLAG_RSS_FIELD_IPV6_UDP BIT(7)
#define IGB_FLAG_WOL_SUPPORTED BIT(8)
#define IGB_FLAG_NEED_LINK_UPDATE BIT(9)
#define IGB_FLAG_MEDIA_RESET BIT(10)
#define IGB_FLAG_MAS_CAPABLE BIT(11)
#define IGB_FLAG_MAS_ENABLE BIT(12)
#define IGB_FLAG_HAS_MSIX BIT(13)
#define IGB_FLAG_EEE BIT(14)
#define IGB_FLAG_VLAN_PROMISC BIT(15)
#define IGB_FLAG_RX_LEGACY BIT(16)
#define IGB_FLAG_FQTSS BIT(17)
/* Media Auto Sense */
#define IGB_MAS_ENABLE_0 0X0001
#define IGB_MAS_ENABLE_1 0X0002
#define IGB_MAS_ENABLE_2 0X0004
#define IGB_MAS_ENABLE_3 0X0008
/* DMA Coalescing defines */
#define IGB_MIN_TXPBSIZE 20408
#define IGB_TX_BUF_4096 4096
#define IGB_DMCTLX_DCFLUSH_DIS 0x80000000 /* Disable DMA Coal Flush */
#define IGB_82576_TSYNC_SHIFT 19
enum e1000_state_t {
__IGB_TESTING,
__IGB_RESETTING,
__IGB_DOWN,
__IGB_PTP_TX_IN_PROGRESS,
};
enum igb_boards {
board_82575,
};
extern char igb_driver_name[];
int igb_xmit_xdp_ring(struct igb_adapter *adapter,
struct igb_ring *ring,
struct xdp_frame *xdpf);
int igb_open(struct net_device *netdev);
int igb_close(struct net_device *netdev);
int igb_up(struct igb_adapter *);
void igb_down(struct igb_adapter *);
void igb_reinit_locked(struct igb_adapter *);
void igb_reset(struct igb_adapter *);
int igb_reinit_queues(struct igb_adapter *);
void igb_write_rss_indir_tbl(struct igb_adapter *);
int igb_set_spd_dplx(struct igb_adapter *, u32, u8);
int igb_setup_tx_resources(struct igb_ring *);
int igb_setup_rx_resources(struct igb_ring *);
void igb_free_tx_resources(struct igb_ring *);
void igb_free_rx_resources(struct igb_ring *);
void igb_configure_tx_ring(struct igb_adapter *, struct igb_ring *);
void igb_configure_rx_ring(struct igb_adapter *, struct igb_ring *);
void igb_setup_tctl(struct igb_adapter *);
void igb_setup_rctl(struct igb_adapter *);
void igb_setup_srrctl(struct igb_adapter *, struct igb_ring *);
netdev_tx_t igb_xmit_frame_ring(struct sk_buff *, struct igb_ring *);
void igb_alloc_rx_buffers(struct igb_ring *, u16);
void igb_update_stats(struct igb_adapter *);
bool igb_has_link(struct igb_adapter *adapter);
void igb_set_ethtool_ops(struct net_device *);
void igb_power_up_link(struct igb_adapter *);
void igb_set_fw_version(struct igb_adapter *);
void igb_ptp_init(struct igb_adapter *adapter);
void igb_ptp_stop(struct igb_adapter *adapter);
void igb_ptp_reset(struct igb_adapter *adapter);
void igb_ptp_suspend(struct igb_adapter *adapter);
void igb_ptp_rx_hang(struct igb_adapter *adapter);
void igb_ptp_tx_hang(struct igb_adapter *adapter);
void igb_ptp_rx_rgtstamp(struct igb_q_vector *q_vector, struct sk_buff *skb);
int igb_ptp_rx_pktstamp(struct igb_q_vector *q_vector, void *va,
ktime_t *timestamp);
int igb_ptp_set_ts_config(struct net_device *netdev, struct ifreq *ifr);
int igb_ptp_get_ts_config(struct net_device *netdev, struct ifreq *ifr);
void igb_set_flag_queue_pairs(struct igb_adapter *, const u32);
unsigned int igb_get_max_rss_queues(struct igb_adapter *);
#ifdef CONFIG_IGB_HWMON
void igb_sysfs_exit(struct igb_adapter *adapter);
int igb_sysfs_init(struct igb_adapter *adapter);
#endif
static inline s32 igb_reset_phy(struct e1000_hw *hw)
{
if (hw->phy.ops.reset)
return hw->phy.ops.reset(hw);
return 0;
}
static inline s32 igb_read_phy_reg(struct e1000_hw *hw, u32 offset, u16 *data)
{
if (hw->phy.ops.read_reg)
return hw->phy.ops.read_reg(hw, offset, data);
return 0;
}
static inline s32 igb_write_phy_reg(struct e1000_hw *hw, u32 offset, u16 data)
{
if (hw->phy.ops.write_reg)
return hw->phy.ops.write_reg(hw, offset, data);
return 0;
}
static inline s32 igb_get_phy_info(struct e1000_hw *hw)
{
if (hw->phy.ops.get_phy_info)
return hw->phy.ops.get_phy_info(hw);
return 0;
}
static inline struct netdev_queue *txring_txq(const struct igb_ring *tx_ring)
{
return netdev_get_tx_queue(tx_ring->netdev, tx_ring->queue_index);
}
int igb_add_filter(struct igb_adapter *adapter,
struct igb_nfc_filter *input);
int igb_erase_filter(struct igb_adapter *adapter,
struct igb_nfc_filter *input);
int igb_add_mac_steering_filter(struct igb_adapter *adapter,
const u8 *addr, u8 queue, u8 flags);
int igb_del_mac_steering_filter(struct igb_adapter *adapter,
const u8 *addr, u8 queue, u8 flags);
#endif /* _IGB_H_ */

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,229 @@
// SPDX-License-Identifier: GPL-2.0
/* Copyright(c) 2007 - 2018 Intel Corporation. */
#include "igb-6.1-ethercat.h"
#include "e1000_82575-6.1-ethercat.h"
#include "e1000_hw-6.1-ethercat.h"
#include <linux/module.h>
#include <linux/types.h>
#include <linux/sysfs.h>
#include <linux/kobject.h>
#include <linux/device.h>
#include <linux/netdevice.h>
#include <linux/hwmon.h>
#include <linux/pci.h>
#ifdef CONFIG_IGB_HWMON
static struct i2c_board_info i350_sensor_info = {
I2C_BOARD_INFO("i350bb", (0Xf8 >> 1)),
};
/* hwmon callback functions */
static ssize_t igb_hwmon_show_location(struct device *dev,
struct device_attribute *attr,
char *buf)
{
struct hwmon_attr *igb_attr = container_of(attr, struct hwmon_attr,
dev_attr);
return sprintf(buf, "loc%u\n",
igb_attr->sensor->location);
}
static ssize_t igb_hwmon_show_temp(struct device *dev,
struct device_attribute *attr,
char *buf)
{
struct hwmon_attr *igb_attr = container_of(attr, struct hwmon_attr,
dev_attr);
unsigned int value;
/* reset the temp field */
igb_attr->hw->mac.ops.get_thermal_sensor_data(igb_attr->hw);
value = igb_attr->sensor->temp;
/* display millidegree */
value *= 1000;
return sprintf(buf, "%u\n", value);
}
static ssize_t igb_hwmon_show_cautionthresh(struct device *dev,
struct device_attribute *attr,
char *buf)
{
struct hwmon_attr *igb_attr = container_of(attr, struct hwmon_attr,
dev_attr);
unsigned int value = igb_attr->sensor->caution_thresh;
/* display millidegree */
value *= 1000;
return sprintf(buf, "%u\n", value);
}
static ssize_t igb_hwmon_show_maxopthresh(struct device *dev,
struct device_attribute *attr,
char *buf)
{
struct hwmon_attr *igb_attr = container_of(attr, struct hwmon_attr,
dev_attr);
unsigned int value = igb_attr->sensor->max_op_thresh;
/* display millidegree */
value *= 1000;
return sprintf(buf, "%u\n", value);
}
/* igb_add_hwmon_attr - Create hwmon attr table for a hwmon sysfs file.
* @ adapter: pointer to the adapter structure
* @ offset: offset in the eeprom sensor data table
* @ type: type of sensor data to display
*
* For each file we want in hwmon's sysfs interface we need a device_attribute
* This is included in our hwmon_attr struct that contains the references to
* the data structures we need to get the data to display.
*/
static int igb_add_hwmon_attr(struct igb_adapter *adapter,
unsigned int offset, int type)
{
int rc;
unsigned int n_attr;
struct hwmon_attr *igb_attr;
n_attr = adapter->igb_hwmon_buff->n_hwmon;
igb_attr = &adapter->igb_hwmon_buff->hwmon_list[n_attr];
switch (type) {
case IGB_HWMON_TYPE_LOC:
igb_attr->dev_attr.show = igb_hwmon_show_location;
snprintf(igb_attr->name, sizeof(igb_attr->name),
"temp%u_label", offset + 1);
break;
case IGB_HWMON_TYPE_TEMP:
igb_attr->dev_attr.show = igb_hwmon_show_temp;
snprintf(igb_attr->name, sizeof(igb_attr->name),
"temp%u_input", offset + 1);
break;
case IGB_HWMON_TYPE_CAUTION:
igb_attr->dev_attr.show = igb_hwmon_show_cautionthresh;
snprintf(igb_attr->name, sizeof(igb_attr->name),
"temp%u_max", offset + 1);
break;
case IGB_HWMON_TYPE_MAX:
igb_attr->dev_attr.show = igb_hwmon_show_maxopthresh;
snprintf(igb_attr->name, sizeof(igb_attr->name),
"temp%u_crit", offset + 1);
break;
default:
rc = -EPERM;
return rc;
}
/* These always the same regardless of type */
igb_attr->sensor =
&adapter->hw.mac.thermal_sensor_data.sensor[offset];
igb_attr->hw = &adapter->hw;
igb_attr->dev_attr.store = NULL;
igb_attr->dev_attr.attr.mode = 0444;
igb_attr->dev_attr.attr.name = igb_attr->name;
sysfs_attr_init(&igb_attr->dev_attr.attr);
adapter->igb_hwmon_buff->attrs[n_attr] = &igb_attr->dev_attr.attr;
++adapter->igb_hwmon_buff->n_hwmon;
return 0;
}
static void igb_sysfs_del_adapter(struct igb_adapter *adapter)
{
}
/* called from igb_main.c */
void igb_sysfs_exit(struct igb_adapter *adapter)
{
igb_sysfs_del_adapter(adapter);
}
/* called from igb_main.c */
int igb_sysfs_init(struct igb_adapter *adapter)
{
struct hwmon_buff *igb_hwmon;
struct i2c_client *client;
struct device *hwmon_dev;
unsigned int i;
int rc = 0;
/* If this method isn't defined we don't support thermals */
if (adapter->hw.mac.ops.init_thermal_sensor_thresh == NULL)
goto exit;
/* Don't create thermal hwmon interface if no sensors present */
rc = (adapter->hw.mac.ops.init_thermal_sensor_thresh(&adapter->hw));
if (rc)
goto exit;
igb_hwmon = devm_kzalloc(&adapter->pdev->dev, sizeof(*igb_hwmon),
GFP_KERNEL);
if (!igb_hwmon) {
rc = -ENOMEM;
goto exit;
}
adapter->igb_hwmon_buff = igb_hwmon;
for (i = 0; i < E1000_MAX_SENSORS; i++) {
/* Only create hwmon sysfs entries for sensors that have
* meaningful data.
*/
if (adapter->hw.mac.thermal_sensor_data.sensor[i].location == 0)
continue;
/* Bail if any hwmon attr struct fails to initialize */
rc = igb_add_hwmon_attr(adapter, i, IGB_HWMON_TYPE_CAUTION);
if (rc)
goto exit;
rc = igb_add_hwmon_attr(adapter, i, IGB_HWMON_TYPE_LOC);
if (rc)
goto exit;
rc = igb_add_hwmon_attr(adapter, i, IGB_HWMON_TYPE_TEMP);
if (rc)
goto exit;
rc = igb_add_hwmon_attr(adapter, i, IGB_HWMON_TYPE_MAX);
if (rc)
goto exit;
}
/* init i2c_client */
client = i2c_new_client_device(&adapter->i2c_adap, &i350_sensor_info);
if (IS_ERR(client)) {
dev_info(&adapter->pdev->dev,
"Failed to create new i2c device.\n");
rc = PTR_ERR(client);
goto exit;
}
adapter->i2c_client = client;
igb_hwmon->groups[0] = &igb_hwmon->group;
igb_hwmon->group.attrs = igb_hwmon->attrs;
hwmon_dev = devm_hwmon_device_register_with_groups(&adapter->pdev->dev,
client->name,
igb_hwmon,
igb_hwmon->groups);
if (IS_ERR(hwmon_dev)) {
rc = PTR_ERR(hwmon_dev);
goto err;
}
goto exit;
err:
igb_sysfs_del_adapter(adapter);
exit:
return rc;
}
#endif

View File

@ -0,0 +1,229 @@
// SPDX-License-Identifier: GPL-2.0
/* Copyright(c) 2007 - 2018 Intel Corporation. */
#include "igb.h"
#include "e1000_82575.h"
#include "e1000_hw.h"
#include <linux/module.h>
#include <linux/types.h>
#include <linux/sysfs.h>
#include <linux/kobject.h>
#include <linux/device.h>
#include <linux/netdevice.h>
#include <linux/hwmon.h>
#include <linux/pci.h>
#ifdef CONFIG_IGB_HWMON
static struct i2c_board_info i350_sensor_info = {
I2C_BOARD_INFO("i350bb", (0Xf8 >> 1)),
};
/* hwmon callback functions */
static ssize_t igb_hwmon_show_location(struct device *dev,
struct device_attribute *attr,
char *buf)
{
struct hwmon_attr *igb_attr = container_of(attr, struct hwmon_attr,
dev_attr);
return sprintf(buf, "loc%u\n",
igb_attr->sensor->location);
}
static ssize_t igb_hwmon_show_temp(struct device *dev,
struct device_attribute *attr,
char *buf)
{
struct hwmon_attr *igb_attr = container_of(attr, struct hwmon_attr,
dev_attr);
unsigned int value;
/* reset the temp field */
igb_attr->hw->mac.ops.get_thermal_sensor_data(igb_attr->hw);
value = igb_attr->sensor->temp;
/* display millidegree */
value *= 1000;
return sprintf(buf, "%u\n", value);
}
static ssize_t igb_hwmon_show_cautionthresh(struct device *dev,
struct device_attribute *attr,
char *buf)
{
struct hwmon_attr *igb_attr = container_of(attr, struct hwmon_attr,
dev_attr);
unsigned int value = igb_attr->sensor->caution_thresh;
/* display millidegree */
value *= 1000;
return sprintf(buf, "%u\n", value);
}
static ssize_t igb_hwmon_show_maxopthresh(struct device *dev,
struct device_attribute *attr,
char *buf)
{
struct hwmon_attr *igb_attr = container_of(attr, struct hwmon_attr,
dev_attr);
unsigned int value = igb_attr->sensor->max_op_thresh;
/* display millidegree */
value *= 1000;
return sprintf(buf, "%u\n", value);
}
/* igb_add_hwmon_attr - Create hwmon attr table for a hwmon sysfs file.
* @ adapter: pointer to the adapter structure
* @ offset: offset in the eeprom sensor data table
* @ type: type of sensor data to display
*
* For each file we want in hwmon's sysfs interface we need a device_attribute
* This is included in our hwmon_attr struct that contains the references to
* the data structures we need to get the data to display.
*/
static int igb_add_hwmon_attr(struct igb_adapter *adapter,
unsigned int offset, int type)
{
int rc;
unsigned int n_attr;
struct hwmon_attr *igb_attr;
n_attr = adapter->igb_hwmon_buff->n_hwmon;
igb_attr = &adapter->igb_hwmon_buff->hwmon_list[n_attr];
switch (type) {
case IGB_HWMON_TYPE_LOC:
igb_attr->dev_attr.show = igb_hwmon_show_location;
snprintf(igb_attr->name, sizeof(igb_attr->name),
"temp%u_label", offset + 1);
break;
case IGB_HWMON_TYPE_TEMP:
igb_attr->dev_attr.show = igb_hwmon_show_temp;
snprintf(igb_attr->name, sizeof(igb_attr->name),
"temp%u_input", offset + 1);
break;
case IGB_HWMON_TYPE_CAUTION:
igb_attr->dev_attr.show = igb_hwmon_show_cautionthresh;
snprintf(igb_attr->name, sizeof(igb_attr->name),
"temp%u_max", offset + 1);
break;
case IGB_HWMON_TYPE_MAX:
igb_attr->dev_attr.show = igb_hwmon_show_maxopthresh;
snprintf(igb_attr->name, sizeof(igb_attr->name),
"temp%u_crit", offset + 1);
break;
default:
rc = -EPERM;
return rc;
}
/* These always the same regardless of type */
igb_attr->sensor =
&adapter->hw.mac.thermal_sensor_data.sensor[offset];
igb_attr->hw = &adapter->hw;
igb_attr->dev_attr.store = NULL;
igb_attr->dev_attr.attr.mode = 0444;
igb_attr->dev_attr.attr.name = igb_attr->name;
sysfs_attr_init(&igb_attr->dev_attr.attr);
adapter->igb_hwmon_buff->attrs[n_attr] = &igb_attr->dev_attr.attr;
++adapter->igb_hwmon_buff->n_hwmon;
return 0;
}
static void igb_sysfs_del_adapter(struct igb_adapter *adapter)
{
}
/* called from igb_main.c */
void igb_sysfs_exit(struct igb_adapter *adapter)
{
igb_sysfs_del_adapter(adapter);
}
/* called from igb_main.c */
int igb_sysfs_init(struct igb_adapter *adapter)
{
struct hwmon_buff *igb_hwmon;
struct i2c_client *client;
struct device *hwmon_dev;
unsigned int i;
int rc = 0;
/* If this method isn't defined we don't support thermals */
if (adapter->hw.mac.ops.init_thermal_sensor_thresh == NULL)
goto exit;
/* Don't create thermal hwmon interface if no sensors present */
rc = (adapter->hw.mac.ops.init_thermal_sensor_thresh(&adapter->hw));
if (rc)
goto exit;
igb_hwmon = devm_kzalloc(&adapter->pdev->dev, sizeof(*igb_hwmon),
GFP_KERNEL);
if (!igb_hwmon) {
rc = -ENOMEM;
goto exit;
}
adapter->igb_hwmon_buff = igb_hwmon;
for (i = 0; i < E1000_MAX_SENSORS; i++) {
/* Only create hwmon sysfs entries for sensors that have
* meaningful data.
*/
if (adapter->hw.mac.thermal_sensor_data.sensor[i].location == 0)
continue;
/* Bail if any hwmon attr struct fails to initialize */
rc = igb_add_hwmon_attr(adapter, i, IGB_HWMON_TYPE_CAUTION);
if (rc)
goto exit;
rc = igb_add_hwmon_attr(adapter, i, IGB_HWMON_TYPE_LOC);
if (rc)
goto exit;
rc = igb_add_hwmon_attr(adapter, i, IGB_HWMON_TYPE_TEMP);
if (rc)
goto exit;
rc = igb_add_hwmon_attr(adapter, i, IGB_HWMON_TYPE_MAX);
if (rc)
goto exit;
}
/* init i2c_client */
client = i2c_new_client_device(&adapter->i2c_adap, &i350_sensor_info);
if (IS_ERR(client)) {
dev_info(&adapter->pdev->dev,
"Failed to create new i2c device.\n");
rc = PTR_ERR(client);
goto exit;
}
adapter->i2c_client = client;
igb_hwmon->groups[0] = &igb_hwmon->group;
igb_hwmon->group.attrs = igb_hwmon->attrs;
hwmon_dev = devm_hwmon_device_register_with_groups(&adapter->pdev->dev,
client->name,
igb_hwmon,
igb_hwmon->groups);
if (IS_ERR(hwmon_dev)) {
rc = PTR_ERR(hwmon_dev);
goto err;
}
goto exit;
err:
igb_sysfs_del_adapter(adapter);
exit:
return rc;
}
#endif

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff