Loading drivers/net/e1000e/e1000.h +4 −0 Original line number Diff line number Diff line Loading @@ -155,6 +155,9 @@ struct e1000_info; #define HV_M_STATUS_SPEED_1000 0x0200 #define HV_M_STATUS_LINK_UP 0x0040 #define E1000_ICH_FWSM_PCIM2PCI 0x01000000 /* ME PCIm-to-PCI active */ #define E1000_ICH_FWSM_PCIM2PCI_COUNT 2000 /* Time to wait before putting the device into D3 if there's no link (in ms). */ #define LINK_TIMEOUT 100 Loading Loading @@ -454,6 +457,7 @@ struct e1000_info { #define FLAG2_DISABLE_AIM (1 << 8) #define FLAG2_CHECK_PHY_HANG (1 << 9) #define FLAG2_NO_DISABLE_RX (1 << 10) #define FLAG2_PCIM2PCI_ARBITER_WA (1 << 11) #define E1000_RX_DESC_PS(R, i) \ (&(((union e1000_rx_desc_packet_split *)((R).desc))[i])) Loading drivers/net/e1000e/ich8lan.c +52 −13 Original line number Diff line number Diff line Loading @@ -139,6 +139,7 @@ /* PHY Low Power Idle Control */ #define I82579_LPI_CTRL PHY_REG(772, 20) #define I82579_LPI_CTRL_ENABLE_MASK 0x6000 #define I82579_LPI_CTRL_FORCE_PLL_LOCK_COUNT 0x80 /* EMI Registers */ #define I82579_EMI_ADDR 0x10 Loading @@ -163,6 +164,11 @@ #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 /* ICH GbE Flash Hardware Sequencing Flash Status Register bit breakdown */ /* Offset 04h HSFSTS */ union ich8_hws_flash_status { Loading Loading @@ -657,6 +663,7 @@ static s32 e1000_check_for_copper_link_ich8lan(struct e1000_hw *hw) struct e1000_mac_info *mac = &hw->mac; s32 ret_val; bool link; u16 phy_reg; /* * We only want to go out to the PHY registers to see if Auto-Neg Loading Loading @@ -689,16 +696,35 @@ static s32 e1000_check_for_copper_link_ich8lan(struct e1000_hw *hw) mac->get_link_status = false; switch (hw->mac.type) { case e1000_pch2lan: ret_val = e1000_k1_workaround_lv(hw); if (ret_val) goto out; /* fall-thru */ case e1000_pchlan: if (hw->phy.type == e1000_phy_82578) { ret_val = e1000_link_stall_workaround_hv(hw); if (ret_val) goto out; } if (hw->mac.type == e1000_pch2lan) { ret_val = e1000_k1_workaround_lv(hw); if (ret_val) goto out; /* * Workaround for PCHx parts in half-duplex: * Set the number of preambles removed from the packet * when it is passed from the PHY to the MAC to prevent * the MAC from misinterpreting the packet type. */ e1e_rphy(hw, HV_KMRN_FIFO_CTRLSTA, &phy_reg); phy_reg &= ~HV_KMRN_FIFO_CTRLSTA_PREAMBLE_MASK; if ((er32(STATUS) & E1000_STATUS_FD) != E1000_STATUS_FD) phy_reg |= (1 << HV_KMRN_FIFO_CTRLSTA_PREAMBLE_SHIFT); e1e_wphy(hw, HV_KMRN_FIFO_CTRLSTA, phy_reg); break; default: break; } /* Loading Loading @@ -788,6 +814,11 @@ static s32 e1000_get_variants_ich8lan(struct e1000_adapter *adapter) (adapter->hw.phy.type == e1000_phy_igp_3)) adapter->flags |= FLAG_LSC_GIG_SPEED_DROP; /* Enable workaround for 82579 w/ ME enabled */ if ((adapter->hw.mac.type == e1000_pch2lan) && (er32(FWSM) & E1000_ICH_FWSM_FW_VALID)) adapter->flags2 |= FLAG2_PCIM2PCI_ARBITER_WA; /* Disable EEE by default until IEEE802.3az spec is finalized */ if (adapter->flags2 & FLAG2_HAS_EEE) adapter->hw.dev_spec.ich8lan.eee_disable = true; Loading Loading @@ -1355,7 +1386,7 @@ static s32 e1000_hv_phy_workarounds_ich8lan(struct e1000_hw *hw) return ret_val; /* Preamble tuning for SSC */ ret_val = e1e_wphy(hw, PHY_REG(770, 16), 0xA204); ret_val = e1e_wphy(hw, HV_KMRN_FIFO_CTRLSTA, 0xA204); if (ret_val) return ret_val; } Loading Loading @@ -1645,6 +1676,7 @@ static s32 e1000_k1_workaround_lv(struct e1000_hw *hw) s32 ret_val = 0; u16 status_reg = 0; u32 mac_reg; u16 phy_reg; if (hw->mac.type != e1000_pch2lan) goto out; Loading @@ -1659,12 +1691,19 @@ static s32 e1000_k1_workaround_lv(struct e1000_hw *hw) mac_reg = er32(FEXTNVM4); mac_reg &= ~E1000_FEXTNVM4_BEACON_DURATION_MASK; if (status_reg & HV_M_STATUS_SPEED_1000) ret_val = e1e_rphy(hw, I82579_LPI_CTRL, &phy_reg); if (ret_val) goto out; if (status_reg & HV_M_STATUS_SPEED_1000) { mac_reg |= E1000_FEXTNVM4_BEACON_DURATION_8USEC; else phy_reg &= ~I82579_LPI_CTRL_FORCE_PLL_LOCK_COUNT; } else { mac_reg |= E1000_FEXTNVM4_BEACON_DURATION_16USEC; phy_reg |= I82579_LPI_CTRL_FORCE_PLL_LOCK_COUNT; } ew32(FEXTNVM4, mac_reg); ret_val = e1e_wphy(hw, I82579_LPI_CTRL, phy_reg); } out: Loading drivers/net/e1000e/netdev.c +76 −4 Original line number Diff line number Diff line Loading @@ -518,6 +518,63 @@ static void e1000_rx_checksum(struct e1000_adapter *adapter, u32 status_err, adapter->hw_csum_good++; } /** * e1000e_update_tail_wa - helper function for e1000e_update_[rt]dt_wa() * @hw: pointer to the HW structure * @tail: address of tail descriptor register * @i: value to write to tail descriptor register * * When updating the tail register, the ME could be accessing Host CSR * registers at the same time. Normally, this is handled in h/w by an * arbiter but on some parts there is a bug that acknowledges Host accesses * later than it should which could result in the descriptor register to * have an incorrect value. Workaround this by checking the FWSM register * which has bit 24 set while ME is accessing Host CSR registers, wait * if it is set and try again a number of times. **/ static inline s32 e1000e_update_tail_wa(struct e1000_hw *hw, u8 __iomem * tail, unsigned int i) { unsigned int j = 0; while ((j++ < E1000_ICH_FWSM_PCIM2PCI_COUNT) && (er32(FWSM) & E1000_ICH_FWSM_PCIM2PCI)) udelay(50); writel(i, tail); if ((j == E1000_ICH_FWSM_PCIM2PCI_COUNT) && (i != readl(tail))) return E1000_ERR_SWFW_SYNC; return 0; } static void e1000e_update_rdt_wa(struct e1000_adapter *adapter, unsigned int i) { u8 __iomem *tail = (adapter->hw.hw_addr + adapter->rx_ring->tail); struct e1000_hw *hw = &adapter->hw; if (e1000e_update_tail_wa(hw, tail, i)) { u32 rctl = er32(RCTL); ew32(RCTL, rctl & ~E1000_RCTL_EN); e_err("ME firmware caused invalid RDT - resetting\n"); schedule_work(&adapter->reset_task); } } static void e1000e_update_tdt_wa(struct e1000_adapter *adapter, unsigned int i) { u8 __iomem *tail = (adapter->hw.hw_addr + adapter->tx_ring->tail); struct e1000_hw *hw = &adapter->hw; if (e1000e_update_tail_wa(hw, tail, i)) { u32 tctl = er32(TCTL); ew32(TCTL, tctl & ~E1000_TCTL_EN); e_err("ME firmware caused invalid TDT - resetting\n"); schedule_work(&adapter->reset_task); } } /** * e1000_alloc_rx_buffers - Replace used receive buffers; legacy & extended * @adapter: address of board private structure Loading Loading @@ -573,6 +630,9 @@ static void e1000_alloc_rx_buffers(struct e1000_adapter *adapter, * such as IA-64). */ wmb(); if (adapter->flags2 & FLAG2_PCIM2PCI_ARBITER_WA) e1000e_update_rdt_wa(adapter, i); else writel(i, adapter->hw.hw_addr + rx_ring->tail); } i++; Loading Loading @@ -673,7 +733,11 @@ static void e1000_alloc_rx_buffers_ps(struct e1000_adapter *adapter, * such as IA-64). */ wmb(); writel(i << 1, adapter->hw.hw_addr + rx_ring->tail); if (adapter->flags2 & FLAG2_PCIM2PCI_ARBITER_WA) e1000e_update_rdt_wa(adapter, i << 1); else writel(i << 1, adapter->hw.hw_addr + rx_ring->tail); } i++; Loading Loading @@ -756,6 +820,9 @@ static void e1000_alloc_jumbo_rx_buffers(struct e1000_adapter *adapter, * applicable for weak-ordered memory model archs, * such as IA-64). */ wmb(); if (adapter->flags2 & FLAG2_PCIM2PCI_ARBITER_WA) e1000e_update_rdt_wa(adapter, i); else writel(i, adapter->hw.hw_addr + rx_ring->tail); } } Loading Loading @@ -4689,7 +4756,12 @@ static void e1000_tx_queue(struct e1000_adapter *adapter, wmb(); tx_ring->next_to_use = i; if (adapter->flags2 & FLAG2_PCIM2PCI_ARBITER_WA) e1000e_update_tdt_wa(adapter, i); else writel(i, adapter->hw.hw_addr + tx_ring->tail); /* * we need this if more than one processor can write to our tail * at a time, it synchronizes IO on IA64/Altix systems Loading drivers/net/ixgbe/ixgbe_main.c +3 −1 Original line number Diff line number Diff line Loading @@ -1459,9 +1459,11 @@ static void ixgbe_clean_rx_irq(struct ixgbe_q_vector *q_vector, if (ixgbe_rx_is_fcoe(adapter, rx_desc)) { ddp_bytes = ixgbe_fcoe_ddp(adapter, rx_desc, skb, staterr); if (!ddp_bytes) if (!ddp_bytes) { dev_kfree_skb_any(skb); goto next_desc; } } #endif /* IXGBE_FCOE */ ixgbe_receive_skb(q_vector, skb, staterr, rx_ring, rx_desc); Loading Loading
drivers/net/e1000e/e1000.h +4 −0 Original line number Diff line number Diff line Loading @@ -155,6 +155,9 @@ struct e1000_info; #define HV_M_STATUS_SPEED_1000 0x0200 #define HV_M_STATUS_LINK_UP 0x0040 #define E1000_ICH_FWSM_PCIM2PCI 0x01000000 /* ME PCIm-to-PCI active */ #define E1000_ICH_FWSM_PCIM2PCI_COUNT 2000 /* Time to wait before putting the device into D3 if there's no link (in ms). */ #define LINK_TIMEOUT 100 Loading Loading @@ -454,6 +457,7 @@ struct e1000_info { #define FLAG2_DISABLE_AIM (1 << 8) #define FLAG2_CHECK_PHY_HANG (1 << 9) #define FLAG2_NO_DISABLE_RX (1 << 10) #define FLAG2_PCIM2PCI_ARBITER_WA (1 << 11) #define E1000_RX_DESC_PS(R, i) \ (&(((union e1000_rx_desc_packet_split *)((R).desc))[i])) Loading
drivers/net/e1000e/ich8lan.c +52 −13 Original line number Diff line number Diff line Loading @@ -139,6 +139,7 @@ /* PHY Low Power Idle Control */ #define I82579_LPI_CTRL PHY_REG(772, 20) #define I82579_LPI_CTRL_ENABLE_MASK 0x6000 #define I82579_LPI_CTRL_FORCE_PLL_LOCK_COUNT 0x80 /* EMI Registers */ #define I82579_EMI_ADDR 0x10 Loading @@ -163,6 +164,11 @@ #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 /* ICH GbE Flash Hardware Sequencing Flash Status Register bit breakdown */ /* Offset 04h HSFSTS */ union ich8_hws_flash_status { Loading Loading @@ -657,6 +663,7 @@ static s32 e1000_check_for_copper_link_ich8lan(struct e1000_hw *hw) struct e1000_mac_info *mac = &hw->mac; s32 ret_val; bool link; u16 phy_reg; /* * We only want to go out to the PHY registers to see if Auto-Neg Loading Loading @@ -689,16 +696,35 @@ static s32 e1000_check_for_copper_link_ich8lan(struct e1000_hw *hw) mac->get_link_status = false; switch (hw->mac.type) { case e1000_pch2lan: ret_val = e1000_k1_workaround_lv(hw); if (ret_val) goto out; /* fall-thru */ case e1000_pchlan: if (hw->phy.type == e1000_phy_82578) { ret_val = e1000_link_stall_workaround_hv(hw); if (ret_val) goto out; } if (hw->mac.type == e1000_pch2lan) { ret_val = e1000_k1_workaround_lv(hw); if (ret_val) goto out; /* * Workaround for PCHx parts in half-duplex: * Set the number of preambles removed from the packet * when it is passed from the PHY to the MAC to prevent * the MAC from misinterpreting the packet type. */ e1e_rphy(hw, HV_KMRN_FIFO_CTRLSTA, &phy_reg); phy_reg &= ~HV_KMRN_FIFO_CTRLSTA_PREAMBLE_MASK; if ((er32(STATUS) & E1000_STATUS_FD) != E1000_STATUS_FD) phy_reg |= (1 << HV_KMRN_FIFO_CTRLSTA_PREAMBLE_SHIFT); e1e_wphy(hw, HV_KMRN_FIFO_CTRLSTA, phy_reg); break; default: break; } /* Loading Loading @@ -788,6 +814,11 @@ static s32 e1000_get_variants_ich8lan(struct e1000_adapter *adapter) (adapter->hw.phy.type == e1000_phy_igp_3)) adapter->flags |= FLAG_LSC_GIG_SPEED_DROP; /* Enable workaround for 82579 w/ ME enabled */ if ((adapter->hw.mac.type == e1000_pch2lan) && (er32(FWSM) & E1000_ICH_FWSM_FW_VALID)) adapter->flags2 |= FLAG2_PCIM2PCI_ARBITER_WA; /* Disable EEE by default until IEEE802.3az spec is finalized */ if (adapter->flags2 & FLAG2_HAS_EEE) adapter->hw.dev_spec.ich8lan.eee_disable = true; Loading Loading @@ -1355,7 +1386,7 @@ static s32 e1000_hv_phy_workarounds_ich8lan(struct e1000_hw *hw) return ret_val; /* Preamble tuning for SSC */ ret_val = e1e_wphy(hw, PHY_REG(770, 16), 0xA204); ret_val = e1e_wphy(hw, HV_KMRN_FIFO_CTRLSTA, 0xA204); if (ret_val) return ret_val; } Loading Loading @@ -1645,6 +1676,7 @@ static s32 e1000_k1_workaround_lv(struct e1000_hw *hw) s32 ret_val = 0; u16 status_reg = 0; u32 mac_reg; u16 phy_reg; if (hw->mac.type != e1000_pch2lan) goto out; Loading @@ -1659,12 +1691,19 @@ static s32 e1000_k1_workaround_lv(struct e1000_hw *hw) mac_reg = er32(FEXTNVM4); mac_reg &= ~E1000_FEXTNVM4_BEACON_DURATION_MASK; if (status_reg & HV_M_STATUS_SPEED_1000) ret_val = e1e_rphy(hw, I82579_LPI_CTRL, &phy_reg); if (ret_val) goto out; if (status_reg & HV_M_STATUS_SPEED_1000) { mac_reg |= E1000_FEXTNVM4_BEACON_DURATION_8USEC; else phy_reg &= ~I82579_LPI_CTRL_FORCE_PLL_LOCK_COUNT; } else { mac_reg |= E1000_FEXTNVM4_BEACON_DURATION_16USEC; phy_reg |= I82579_LPI_CTRL_FORCE_PLL_LOCK_COUNT; } ew32(FEXTNVM4, mac_reg); ret_val = e1e_wphy(hw, I82579_LPI_CTRL, phy_reg); } out: Loading
drivers/net/e1000e/netdev.c +76 −4 Original line number Diff line number Diff line Loading @@ -518,6 +518,63 @@ static void e1000_rx_checksum(struct e1000_adapter *adapter, u32 status_err, adapter->hw_csum_good++; } /** * e1000e_update_tail_wa - helper function for e1000e_update_[rt]dt_wa() * @hw: pointer to the HW structure * @tail: address of tail descriptor register * @i: value to write to tail descriptor register * * When updating the tail register, the ME could be accessing Host CSR * registers at the same time. Normally, this is handled in h/w by an * arbiter but on some parts there is a bug that acknowledges Host accesses * later than it should which could result in the descriptor register to * have an incorrect value. Workaround this by checking the FWSM register * which has bit 24 set while ME is accessing Host CSR registers, wait * if it is set and try again a number of times. **/ static inline s32 e1000e_update_tail_wa(struct e1000_hw *hw, u8 __iomem * tail, unsigned int i) { unsigned int j = 0; while ((j++ < E1000_ICH_FWSM_PCIM2PCI_COUNT) && (er32(FWSM) & E1000_ICH_FWSM_PCIM2PCI)) udelay(50); writel(i, tail); if ((j == E1000_ICH_FWSM_PCIM2PCI_COUNT) && (i != readl(tail))) return E1000_ERR_SWFW_SYNC; return 0; } static void e1000e_update_rdt_wa(struct e1000_adapter *adapter, unsigned int i) { u8 __iomem *tail = (adapter->hw.hw_addr + adapter->rx_ring->tail); struct e1000_hw *hw = &adapter->hw; if (e1000e_update_tail_wa(hw, tail, i)) { u32 rctl = er32(RCTL); ew32(RCTL, rctl & ~E1000_RCTL_EN); e_err("ME firmware caused invalid RDT - resetting\n"); schedule_work(&adapter->reset_task); } } static void e1000e_update_tdt_wa(struct e1000_adapter *adapter, unsigned int i) { u8 __iomem *tail = (adapter->hw.hw_addr + adapter->tx_ring->tail); struct e1000_hw *hw = &adapter->hw; if (e1000e_update_tail_wa(hw, tail, i)) { u32 tctl = er32(TCTL); ew32(TCTL, tctl & ~E1000_TCTL_EN); e_err("ME firmware caused invalid TDT - resetting\n"); schedule_work(&adapter->reset_task); } } /** * e1000_alloc_rx_buffers - Replace used receive buffers; legacy & extended * @adapter: address of board private structure Loading Loading @@ -573,6 +630,9 @@ static void e1000_alloc_rx_buffers(struct e1000_adapter *adapter, * such as IA-64). */ wmb(); if (adapter->flags2 & FLAG2_PCIM2PCI_ARBITER_WA) e1000e_update_rdt_wa(adapter, i); else writel(i, adapter->hw.hw_addr + rx_ring->tail); } i++; Loading Loading @@ -673,7 +733,11 @@ static void e1000_alloc_rx_buffers_ps(struct e1000_adapter *adapter, * such as IA-64). */ wmb(); writel(i << 1, adapter->hw.hw_addr + rx_ring->tail); if (adapter->flags2 & FLAG2_PCIM2PCI_ARBITER_WA) e1000e_update_rdt_wa(adapter, i << 1); else writel(i << 1, adapter->hw.hw_addr + rx_ring->tail); } i++; Loading Loading @@ -756,6 +820,9 @@ static void e1000_alloc_jumbo_rx_buffers(struct e1000_adapter *adapter, * applicable for weak-ordered memory model archs, * such as IA-64). */ wmb(); if (adapter->flags2 & FLAG2_PCIM2PCI_ARBITER_WA) e1000e_update_rdt_wa(adapter, i); else writel(i, adapter->hw.hw_addr + rx_ring->tail); } } Loading Loading @@ -4689,7 +4756,12 @@ static void e1000_tx_queue(struct e1000_adapter *adapter, wmb(); tx_ring->next_to_use = i; if (adapter->flags2 & FLAG2_PCIM2PCI_ARBITER_WA) e1000e_update_tdt_wa(adapter, i); else writel(i, adapter->hw.hw_addr + tx_ring->tail); /* * we need this if more than one processor can write to our tail * at a time, it synchronizes IO on IA64/Altix systems Loading
drivers/net/ixgbe/ixgbe_main.c +3 −1 Original line number Diff line number Diff line Loading @@ -1459,9 +1459,11 @@ static void ixgbe_clean_rx_irq(struct ixgbe_q_vector *q_vector, if (ixgbe_rx_is_fcoe(adapter, rx_desc)) { ddp_bytes = ixgbe_fcoe_ddp(adapter, rx_desc, skb, staterr); if (!ddp_bytes) if (!ddp_bytes) { dev_kfree_skb_any(skb); goto next_desc; } } #endif /* IXGBE_FCOE */ ixgbe_receive_skb(q_vector, skb, staterr, rx_ring, rx_desc); Loading