diff options
Diffstat (limited to 'drivers/net/e1000e/netdev.c')
-rw-r--r-- | drivers/net/e1000e/netdev.c | 171 |
1 files changed, 77 insertions, 94 deletions
diff --git a/drivers/net/e1000e/netdev.c b/drivers/net/e1000e/netdev.c index 3310c3d477d..4353ad56cf1 100644 --- a/drivers/net/e1000e/netdev.c +++ b/drivers/net/e1000e/netdev.c @@ -31,6 +31,7 @@ #include <linux/module.h> #include <linux/types.h> #include <linux/init.h> +#include <linux/interrupt.h> #include <linux/pci.h> #include <linux/vmalloc.h> #include <linux/pagemap.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.3.16" DRV_EXTRAVERSION char e1000e_driver_name[] = "e1000e"; const char e1000e_driver_version[] = DRV_VERSION; @@ -522,7 +523,7 @@ static void e1000_rx_checksum(struct e1000_adapter *adapter, u32 status_err, * @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 +544,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++; @@ -588,7 +589,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 +615,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 +641,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++; @@ -691,7 +693,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 +714,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 +725,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; @@ -887,7 +889,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 +902,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 +1232,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 +1247,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 +1414,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 +1427,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; @@ -3104,7 +3109,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 +3352,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) @@ -3413,17 +3419,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 +3838,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 +3851,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; @@ -5154,21 +5133,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 +5177,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 +5257,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 +5323,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 +5408,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 */ |