diff options
Diffstat (limited to 'drivers/net/e1000e/netdev.c')
-rw-r--r-- | drivers/net/e1000e/netdev.c | 258 |
1 files changed, 158 insertions, 100 deletions
diff --git a/drivers/net/e1000e/netdev.c b/drivers/net/e1000e/netdev.c index 3310c3d477d..2198e615f24 100644 --- a/drivers/net/e1000e/netdev.c +++ b/drivers/net/e1000e/netdev.c @@ -36,6 +36,7 @@ #include <linux/pagemap.h> #include <linux/delay.h> #include <linux/netdevice.h> +#include <linux/interrupt.h> #include <linux/tcp.h> #include <linux/ipv6.h> #include <linux/slab.h> @@ -53,9 +54,9 @@ #include "e1000.h" -#define DRV_EXTRAVERSION "-k2" +#define DRV_EXTRAVERSION "-k" -#define DRV_VERSION "1.3.10" DRV_EXTRAVERSION +#define DRV_VERSION "1.4.4" DRV_EXTRAVERSION char e1000e_driver_name[] = "e1000e"; const char e1000e_driver_version[] = DRV_VERSION; @@ -518,11 +519,68 @@ static void e1000_rx_checksum(struct e1000_adapter *adapter, u32 status_err, } /** + * 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 **/ static void e1000_alloc_rx_buffers(struct e1000_adapter *adapter, - int cleaned_count) + int cleaned_count, gfp_t gfp) { struct net_device *netdev = adapter->netdev; struct pci_dev *pdev = adapter->pdev; @@ -543,7 +601,7 @@ static void e1000_alloc_rx_buffers(struct e1000_adapter *adapter, goto map_skb; } - skb = netdev_alloc_skb_ip_align(netdev, bufsz); + skb = __netdev_alloc_skb_ip_align(netdev, bufsz, gfp); if (!skb) { /* Better luck next round */ adapter->alloc_rx_buff_failed++; @@ -572,7 +630,10 @@ map_skb: * such as IA-64). */ wmb(); - writel(i, adapter->hw.hw_addr + rx_ring->tail); + if (adapter->flags2 & FLAG2_PCIM2PCI_ARBITER_WA) + e1000e_update_rdt_wa(adapter, i); + else + writel(i, adapter->hw.hw_addr + rx_ring->tail); } i++; if (i == rx_ring->count) @@ -588,7 +649,7 @@ map_skb: * @adapter: address of board private structure **/ static void e1000_alloc_rx_buffers_ps(struct e1000_adapter *adapter, - int cleaned_count) + int cleaned_count, gfp_t gfp) { struct net_device *netdev = adapter->netdev; struct pci_dev *pdev = adapter->pdev; @@ -614,7 +675,7 @@ static void e1000_alloc_rx_buffers_ps(struct e1000_adapter *adapter, continue; } if (!ps_page->page) { - ps_page->page = alloc_page(GFP_ATOMIC); + ps_page->page = alloc_page(gfp); if (!ps_page->page) { adapter->alloc_rx_buff_failed++; goto no_buffers; @@ -640,8 +701,9 @@ static void e1000_alloc_rx_buffers_ps(struct e1000_adapter *adapter, cpu_to_le64(ps_page->dma); } - skb = netdev_alloc_skb_ip_align(netdev, - adapter->rx_ps_bsize0); + skb = __netdev_alloc_skb_ip_align(netdev, + adapter->rx_ps_bsize0, + gfp); if (!skb) { adapter->alloc_rx_buff_failed++; @@ -671,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++; @@ -691,7 +757,7 @@ no_buffers: **/ static void e1000_alloc_jumbo_rx_buffers(struct e1000_adapter *adapter, - int cleaned_count) + int cleaned_count, gfp_t gfp) { struct net_device *netdev = adapter->netdev; struct pci_dev *pdev = adapter->pdev; @@ -712,7 +778,7 @@ static void e1000_alloc_jumbo_rx_buffers(struct e1000_adapter *adapter, goto check_page; } - skb = netdev_alloc_skb_ip_align(netdev, bufsz); + skb = __netdev_alloc_skb_ip_align(netdev, bufsz, gfp); if (unlikely(!skb)) { /* Better luck next round */ adapter->alloc_rx_buff_failed++; @@ -723,7 +789,7 @@ static void e1000_alloc_jumbo_rx_buffers(struct e1000_adapter *adapter, check_page: /* allocate a new page if necessary */ if (!buffer_info->page) { - buffer_info->page = alloc_page(GFP_ATOMIC); + buffer_info->page = alloc_page(gfp); if (unlikely(!buffer_info->page)) { adapter->alloc_rx_buff_failed++; break; @@ -754,7 +820,10 @@ check_page: * applicable for weak-ordered memory model archs, * such as IA-64). */ wmb(); - writel(i, adapter->hw.hw_addr + rx_ring->tail); + if (adapter->flags2 & FLAG2_PCIM2PCI_ARBITER_WA) + e1000e_update_rdt_wa(adapter, i); + else + writel(i, adapter->hw.hw_addr + rx_ring->tail); } } @@ -887,7 +956,8 @@ next_desc: /* return some buffers to hardware, one at a time is too slow */ if (cleaned_count >= E1000_RX_BUFFER_WRITE) { - adapter->alloc_rx_buf(adapter, cleaned_count); + adapter->alloc_rx_buf(adapter, cleaned_count, + GFP_ATOMIC); cleaned_count = 0; } @@ -899,7 +969,7 @@ next_desc: cleaned_count = e1000_desc_unused(rx_ring); if (cleaned_count) - adapter->alloc_rx_buf(adapter, cleaned_count); + adapter->alloc_rx_buf(adapter, cleaned_count, GFP_ATOMIC); adapter->total_rx_bytes += total_rx_bytes; adapter->total_rx_packets += total_rx_packets; @@ -1229,7 +1299,8 @@ next_desc: /* return some buffers to hardware, one at a time is too slow */ if (cleaned_count >= E1000_RX_BUFFER_WRITE) { - adapter->alloc_rx_buf(adapter, cleaned_count); + adapter->alloc_rx_buf(adapter, cleaned_count, + GFP_ATOMIC); cleaned_count = 0; } @@ -1243,7 +1314,7 @@ next_desc: cleaned_count = e1000_desc_unused(rx_ring); if (cleaned_count) - adapter->alloc_rx_buf(adapter, cleaned_count); + adapter->alloc_rx_buf(adapter, cleaned_count, GFP_ATOMIC); adapter->total_rx_bytes += total_rx_bytes; adapter->total_rx_packets += total_rx_packets; @@ -1410,7 +1481,8 @@ next_desc: /* return some buffers to hardware, one at a time is too slow */ if (unlikely(cleaned_count >= E1000_RX_BUFFER_WRITE)) { - adapter->alloc_rx_buf(adapter, cleaned_count); + adapter->alloc_rx_buf(adapter, cleaned_count, + GFP_ATOMIC); cleaned_count = 0; } @@ -1422,7 +1494,7 @@ next_desc: cleaned_count = e1000_desc_unused(rx_ring); if (cleaned_count) - adapter->alloc_rx_buf(adapter, cleaned_count); + adapter->alloc_rx_buf(adapter, cleaned_count, GFP_ATOMIC); adapter->total_rx_bytes += total_rx_bytes; adapter->total_rx_packets += total_rx_packets; @@ -2910,7 +2982,8 @@ static void e1000_configure_rx(struct e1000_adapter *adapter) /* disable receives while setting up the descriptors */ rctl = er32(RCTL); - ew32(RCTL, rctl & ~E1000_RCTL_EN); + if (!(adapter->flags2 & FLAG2_NO_DISABLE_RX)) + ew32(RCTL, rctl & ~E1000_RCTL_EN); e1e_flush(); usleep_range(10000, 20000); @@ -3104,7 +3177,8 @@ static void e1000_configure(struct e1000_adapter *adapter) e1000_configure_tx(adapter); e1000_setup_rctl(adapter); e1000_configure_rx(adapter); - adapter->alloc_rx_buf(adapter, e1000_desc_unused(adapter->rx_ring)); + adapter->alloc_rx_buf(adapter, e1000_desc_unused(adapter->rx_ring), + GFP_KERNEL); } /** @@ -3346,7 +3420,7 @@ int e1000e_up(struct e1000_adapter *adapter) e1000_configure_msix(adapter); e1000_irq_enable(adapter); - netif_wake_queue(adapter->netdev); + netif_start_queue(adapter->netdev); /* fire a link change interrupt to start the watchdog */ if (adapter->msix_entries) @@ -3388,7 +3462,8 @@ void e1000e_down(struct e1000_adapter *adapter) /* disable receives in the hardware */ rctl = er32(RCTL); - ew32(RCTL, rctl & ~E1000_RCTL_EN); + if (!(adapter->flags2 & FLAG2_NO_DISABLE_RX)) + ew32(RCTL, rctl & ~E1000_RCTL_EN); /* flush and sleep below */ netif_stop_queue(netdev); @@ -3397,6 +3472,7 @@ void e1000e_down(struct e1000_adapter *adapter) tctl = er32(TCTL); tctl &= ~E1000_TCTL_EN; ew32(TCTL, tctl); + /* flush both disables and wait for them to finish */ e1e_flush(); usleep_range(10000, 20000); @@ -3413,17 +3489,16 @@ void e1000e_down(struct e1000_adapter *adapter) e1000e_update_stats(adapter); spin_unlock(&adapter->stats64_lock); + e1000e_flush_descriptors(adapter); + e1000_clean_tx_ring(adapter); + e1000_clean_rx_ring(adapter); + adapter->link_speed = 0; adapter->link_duplex = 0; if (!pci_channel_offline(adapter->pdev)) e1000e_reset(adapter); - e1000e_flush_descriptors(adapter); - - e1000_clean_tx_ring(adapter); - e1000_clean_rx_ring(adapter); - /* * TODO: for power management, we could drop the link and * pci_disable_device here. @@ -3833,6 +3908,8 @@ static void e1000_update_phy_info(unsigned long data) /** * e1000e_update_phy_stats - Update the PHY statistics counters * @adapter: board private structure + * + * Read/clear the upper 16-bit PHY registers and read/accumulate lower **/ static void e1000e_update_phy_stats(struct e1000_adapter *adapter) { @@ -3844,89 +3921,61 @@ static void e1000e_update_phy_stats(struct e1000_adapter *adapter) if (ret_val) return; - hw->phy.addr = 1; - -#define HV_PHY_STATS_PAGE 778 /* * A page set is expensive so check if already on desired page. * If not, set to the page with the PHY status registers. */ + hw->phy.addr = 1; ret_val = e1000e_read_phy_reg_mdic(hw, IGP01E1000_PHY_PAGE_SELECT, &phy_data); if (ret_val) goto release; - if (phy_data != (HV_PHY_STATS_PAGE << IGP_PAGE_SHIFT)) { - ret_val = e1000e_write_phy_reg_mdic(hw, - IGP01E1000_PHY_PAGE_SELECT, - (HV_PHY_STATS_PAGE << - IGP_PAGE_SHIFT)); + if (phy_data != (HV_STATS_PAGE << IGP_PAGE_SHIFT)) { + ret_val = hw->phy.ops.set_page(hw, + HV_STATS_PAGE << IGP_PAGE_SHIFT); if (ret_val) goto release; } - /* Read/clear the upper 16-bit registers and read/accumulate lower */ - /* Single Collision Count */ - e1000e_read_phy_reg_mdic(hw, HV_SCC_UPPER & MAX_PHY_REG_ADDRESS, - &phy_data); - ret_val = e1000e_read_phy_reg_mdic(hw, - HV_SCC_LOWER & MAX_PHY_REG_ADDRESS, - &phy_data); + hw->phy.ops.read_reg_page(hw, HV_SCC_UPPER, &phy_data); + ret_val = hw->phy.ops.read_reg_page(hw, HV_SCC_LOWER, &phy_data); if (!ret_val) adapter->stats.scc += phy_data; /* Excessive Collision Count */ - e1000e_read_phy_reg_mdic(hw, HV_ECOL_UPPER & MAX_PHY_REG_ADDRESS, - &phy_data); - ret_val = e1000e_read_phy_reg_mdic(hw, - HV_ECOL_LOWER & MAX_PHY_REG_ADDRESS, - &phy_data); + hw->phy.ops.read_reg_page(hw, HV_ECOL_UPPER, &phy_data); + ret_val = hw->phy.ops.read_reg_page(hw, HV_ECOL_LOWER, &phy_data); if (!ret_val) adapter->stats.ecol += phy_data; /* Multiple Collision Count */ - e1000e_read_phy_reg_mdic(hw, HV_MCC_UPPER & MAX_PHY_REG_ADDRESS, - &phy_data); - ret_val = e1000e_read_phy_reg_mdic(hw, - HV_MCC_LOWER & MAX_PHY_REG_ADDRESS, - &phy_data); + hw->phy.ops.read_reg_page(hw, HV_MCC_UPPER, &phy_data); + ret_val = hw->phy.ops.read_reg_page(hw, HV_MCC_LOWER, &phy_data); if (!ret_val) adapter->stats.mcc += phy_data; /* Late Collision Count */ - e1000e_read_phy_reg_mdic(hw, HV_LATECOL_UPPER & MAX_PHY_REG_ADDRESS, - &phy_data); - ret_val = e1000e_read_phy_reg_mdic(hw, - HV_LATECOL_LOWER & - MAX_PHY_REG_ADDRESS, - &phy_data); + hw->phy.ops.read_reg_page(hw, HV_LATECOL_UPPER, &phy_data); + ret_val = hw->phy.ops.read_reg_page(hw, HV_LATECOL_LOWER, &phy_data); if (!ret_val) adapter->stats.latecol += phy_data; /* Collision Count - also used for adaptive IFS */ - e1000e_read_phy_reg_mdic(hw, HV_COLC_UPPER & MAX_PHY_REG_ADDRESS, - &phy_data); - ret_val = e1000e_read_phy_reg_mdic(hw, - HV_COLC_LOWER & MAX_PHY_REG_ADDRESS, - &phy_data); + hw->phy.ops.read_reg_page(hw, HV_COLC_UPPER, &phy_data); + ret_val = hw->phy.ops.read_reg_page(hw, HV_COLC_LOWER, &phy_data); if (!ret_val) hw->mac.collision_delta = phy_data; /* Defer Count */ - e1000e_read_phy_reg_mdic(hw, HV_DC_UPPER & MAX_PHY_REG_ADDRESS, - &phy_data); - ret_val = e1000e_read_phy_reg_mdic(hw, - HV_DC_LOWER & MAX_PHY_REG_ADDRESS, - &phy_data); + hw->phy.ops.read_reg_page(hw, HV_DC_UPPER, &phy_data); + ret_val = hw->phy.ops.read_reg_page(hw, HV_DC_LOWER, &phy_data); if (!ret_val) adapter->stats.dc += phy_data; /* Transmit with no CRS */ - e1000e_read_phy_reg_mdic(hw, HV_TNCRS_UPPER & MAX_PHY_REG_ADDRESS, - &phy_data); - ret_val = e1000e_read_phy_reg_mdic(hw, - HV_TNCRS_LOWER & MAX_PHY_REG_ADDRESS, - &phy_data); + hw->phy.ops.read_reg_page(hw, HV_TNCRS_UPPER, &phy_data); + ret_val = hw->phy.ops.read_reg_page(hw, HV_TNCRS_LOWER, &phy_data); if (!ret_val) adapter->stats.tncrs += phy_data; @@ -4707,7 +4756,12 @@ static void e1000_tx_queue(struct e1000_adapter *adapter, wmb(); tx_ring->next_to_use = i; - writel(i, adapter->hw.hw_addr + tx_ring->tail); + + 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 @@ -5154,21 +5208,34 @@ static int e1000_init_phy_wakeup(struct e1000_adapter *adapter, u32 wufc) { struct e1000_hw *hw = &adapter->hw; u32 i, mac_reg; - u16 phy_reg; + u16 phy_reg, wuc_enable; int retval = 0; /* copy MAC RARs to PHY RARs */ e1000_copy_rx_addrs_to_phy_ich8lan(hw); - /* copy MAC MTA to PHY MTA */ + retval = hw->phy.ops.acquire(hw); + if (retval) { + e_err("Could not acquire PHY\n"); + return retval; + } + + /* Enable access to wakeup registers on and set page to BM_WUC_PAGE */ + retval = e1000_enable_phy_wakeup_reg_access_bm(hw, &wuc_enable); + if (retval) + goto out; + + /* copy MAC MTA to PHY MTA - only needed for pchlan */ for (i = 0; i < adapter->hw.mac.mta_reg_count; i++) { mac_reg = E1000_READ_REG_ARRAY(hw, E1000_MTA, i); - e1e_wphy(hw, BM_MTA(i), (u16)(mac_reg & 0xFFFF)); - e1e_wphy(hw, BM_MTA(i) + 1, (u16)((mac_reg >> 16) & 0xFFFF)); + hw->phy.ops.write_reg_page(hw, BM_MTA(i), + (u16)(mac_reg & 0xFFFF)); + hw->phy.ops.write_reg_page(hw, BM_MTA(i) + 1, + (u16)((mac_reg >> 16) & 0xFFFF)); } /* configure PHY Rx Control register */ - e1e_rphy(&adapter->hw, BM_RCTL, &phy_reg); + hw->phy.ops.read_reg_page(&adapter->hw, BM_RCTL, &phy_reg); mac_reg = er32(RCTL); if (mac_reg & E1000_RCTL_UPE) phy_reg |= BM_RCTL_UPE; @@ -5185,31 +5252,19 @@ static int e1000_init_phy_wakeup(struct e1000_adapter *adapter, u32 wufc) mac_reg = er32(CTRL); if (mac_reg & E1000_CTRL_RFCE) phy_reg |= BM_RCTL_RFCE; - e1e_wphy(&adapter->hw, BM_RCTL, phy_reg); + hw->phy.ops.write_reg_page(&adapter->hw, BM_RCTL, phy_reg); /* enable PHY wakeup in MAC register */ ew32(WUFC, wufc); ew32(WUC, E1000_WUC_PHY_WAKE | E1000_WUC_PME_EN); /* configure and enable PHY wakeup in PHY registers */ - e1e_wphy(&adapter->hw, BM_WUFC, wufc); - e1e_wphy(&adapter->hw, BM_WUC, E1000_WUC_PME_EN); + hw->phy.ops.write_reg_page(&adapter->hw, BM_WUFC, wufc); + hw->phy.ops.write_reg_page(&adapter->hw, BM_WUC, E1000_WUC_PME_EN); /* activate PHY wakeup */ - retval = hw->phy.ops.acquire(hw); - if (retval) { - e_err("Could not acquire PHY\n"); - return retval; - } - e1000e_write_phy_reg_mdic(hw, IGP01E1000_PHY_PAGE_SELECT, - (BM_WUC_ENABLE_PAGE << IGP_PAGE_SHIFT)); - retval = e1000e_read_phy_reg_mdic(hw, BM_WUC_ENABLE_REG, &phy_reg); - if (retval) { - e_err("Could not read PHY page 769\n"); - goto out; - } - phy_reg |= BM_WUC_ENABLE_BIT | BM_WUC_HOST_WU_BIT; - retval = e1000e_write_phy_reg_mdic(hw, BM_WUC_ENABLE_REG, phy_reg); + wuc_enable |= BM_WUC_ENABLE_BIT | BM_WUC_HOST_WU_BIT; + retval = e1000_disable_phy_wakeup_reg_access_bm(hw, &wuc_enable); if (retval) e_err("Could not set PHY Host Wakeup bit\n"); out: @@ -5277,7 +5332,7 @@ static int __e1000_shutdown(struct pci_dev *pdev, bool *enable_wake, } if (adapter->flags & FLAG_IS_ICH) - e1000e_disable_gig_wol_ich8lan(&adapter->hw); + e1000_suspend_workarounds_ich8lan(&adapter->hw); /* Allow time for pending master requests to run */ e1000e_disable_pcie_master(&adapter->hw); @@ -5343,7 +5398,7 @@ static void e1000_complete_shutdown(struct pci_dev *pdev, bool sleep, */ if (adapter->flags & FLAG_IS_QUAD_PORT) { struct pci_dev *us_dev = pdev->bus->self; - int pos = pci_find_capability(us_dev, PCI_CAP_ID_EXP); + int pos = pci_pcie_cap(us_dev); u16 devctl; pci_read_config_word(us_dev, pos + PCI_EXP_DEVCTL, &devctl); @@ -5428,6 +5483,9 @@ static int __e1000_resume(struct pci_dev *pdev) return err; } + if (hw->mac.type == e1000_pch2lan) + e1000_resume_workarounds_pchlan(&adapter->hw); + e1000e_power_up_phy(adapter); /* report the system wakeup cause from S3/S4 */ |