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 3310c3d477d7..4353ad56cf16 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 */  |