e1000e i219 fix unit hang on reset and runtime D3
Subsystems (2)
PATCH v2 1/1 e1000e i219 fix unit hang on reset and runtime D3
From: Yanir Lubetkin <[email protected]>
unit hang may occur if multiple descriptors are available in the rings during reset or runtime suspend. This state can be detected by testing the PCI config space register FEXTNVM7 bit 8 (0x100 mask). if this bit is on, and there are pending descriptors in one of the rings, we must flush them prior to reset. same goes for entering runtime suspend.
--- drivers/net/ethernet/intel/e1000e/ich8lan.h | 2 + drivers/net/ethernet/intel/e1000e/netdev.c | 94 +++++++++++++++++++++++++++++ drivers/net/ethernet/intel/e1000e/regs.h | 1 + 3 files changed, 97 insertions(+)
drivers/net/ethernet/intel/e1000e/ich8lan.h +2 -0
@@ -101,6 +101,8 @@#define E1000_FEXTNVM7_DISABLE_SMB_PERST 0x00000020 +#define E1000_FEXTNVM11_DISABLE_MULR_FIX 0x00002000 +#define K1_ENTRY_LATENCY 0#define K1_MIN_TIME 1#define NVM_SIZE_MULTIPLIER 4096/*multiplier for NVMS field */
drivers/net/ethernet/intel/e1000e/netdev.c +94 -0
106 lines not on this page · raw message
drivers/net/ethernet/intel/e1000e/regs.h +1 -0
@@ -38,6 +38,7 @@#define E1000_FEXTNVM4 0x00024/* Future Extended NVM 4 - RW */ #define E1000_FEXTNVM6 0x00010/* Future Extended NVM 6 - RW */ #define E1000_FEXTNVM7 0x000E4/* Future Extended NVM 7 - RW */ +#define E1000_FEXTNVM11 0x5BBC/* Future Extended NVM 11 - RW */ #define E1000_PCIEANACFG 0x00F18/* PCIE Analog Config */ #define E1000_FCT 0x00030/* Flow Control Type - RW */ #define E1000_VET 0x00038/* VLAN Ether Type - RW */
Signature · 9 lines
1.9.3 --------------------------------------------------------------------- Intel Israel (74) Limited This e-mail and any attachments may contain confidential material for the sole use of the intended recipient(s). Any review or distribution by others is strictly prohibited. If you are not the intended recipient, please contact the sender and delete all copies.
PATCH v2 1/1 e1000e i219 fix unit hang on reset and runtime D3
Quoted 54 lines · Yanir Lubetkin
From: Yanir Lubetkin <[email protected]>
unit hang may occur if multiple descriptors are available in the rings during reset or runtime suspend. This state can be detected by testing the PCI config space register FEXTNVM7 bit 8 (
0x100mask). if this bit is on, and there are pending descriptors in one of the rings, we must flush them prior to reset. same goes for entering runtime suspend.Signed-off-by Yanir Lubetkin <[email protected]>--- drivers/net/ethernet/intel/e1000e/ich8lan.h | 2 + drivers/net/ethernet/intel/e1000e/netdev.c | 94 +++++++++++++++++++++++++++++ drivers/net/ethernet/intel/e1000e/regs.h | 1 + 3 files changed, 97 insertions(+)drivers/net/ethernet/intel/e1000e/ich8lan.h +2
-0@@ -101,6 +101,8 @@#define E1000_FEXTNVM7_DISABLE_SMB_PERST 0x00000020 +#define E1000_FEXTNVM11_DISABLE_MULR_FIX 0x00002000 +#define K1_ENTRY_LATENCY 0#define K1_MIN_TIME 1#define NVM_SIZE_MULTIPLIER 4096/*multiplier for NVMS field */ drivers/net/ethernet/intel/e1000e/netdev.c +18
-0@@ -3788,6 +3788,98 @@ static void e1000_power_down_phy(struct e1000_adapter *adapter) }/** +* e1000_flush_tx_ring - remove all descriptors from the tx_ring +* +* force the hardware to read all the descriptors and discard them +* we put a descriptor with the ring itself as its data. reading +* the descriptor contents is performing a read on all the ring entries and +* causes a ring flush +*/ +static void e1000_flush_tx_ring (struct e1000_adapter *adapter) +{ +struct e1000_hw *hw = &adapter->hw; +struct e1000_ring *tx_ring = adapter->tx_ring; +struct e1000_tx_desc *tx_desc =NULL ; +u32 txd_lower =E1000_TXD_CMD_IFCS ; +u32 tctl, tdbal, tdbah; +int next_to_use; +u16 size =512 ; + + tctl =er32 (TCTL );
drivers/net/ethernet/intel/e1000e/netdev.c static void e1000_power_down_phy(struct e1000_adapter *adapter) · line 3818
Quoted 10 lines
drivers/net/ethernet/intel/e1000e/netdev.c +10
-0+ew32 (TCTL , tctl |E1000_TCTL_EN ); + tdbal =er32 (TDBAL (0 )); + tdbah =er32 (TDBAH (0 )); + next_to_use = tx_ring->next_to_use; + tx_desc =E1000_TX_DESC (*tx_ring, next_to_use); + tx_desc->buffer_addr =cpu_to_le64 (((u64 )tdbah <<32 ) | tdbal); + tx_desc->lower.data =cpu_to_le32 (txd_lower | size); + tx_desc->upper.data =0 ; +/* in case other processors access the descriptor ring */ +dma_wmb ();
You had it right the first time. It should be wmb(), but the comment is wrong. It is supposed to be there to guarantee the descriptor write is complete before notifying the device of new descriptors.
- Alex