diff options
| author | Mark Brown <[email protected]> | 2015-10-12 18:09:27 +0100 | 
|---|---|---|
| committer | Mark Brown <[email protected]> | 2015-10-12 18:09:27 +0100 | 
| commit | 79828b4fa835f73cdaf4bffa48696abdcbea9d02 (patch) | |
| tree | 5e0fa7156acb75ba603022bc807df8f2fedb97a8 /drivers/net/ethernet/intel/e1000e/netdev.c | |
| parent | 721b51fcf91898299d96f4b72cb9434cda29dce6 (diff) | |
| parent | 8c1a9d6323abf0fb1e5dad96cf3f1c783505ea5a (diff) | |
Merge remote-tracking branch 'asoc/fix/rt5645' into asoc-fix-rt5645
Diffstat (limited to 'drivers/net/ethernet/intel/e1000e/netdev.c')
| -rw-r--r-- | drivers/net/ethernet/intel/e1000e/netdev.c | 89 | 
1 files changed, 64 insertions, 25 deletions
diff --git a/drivers/net/ethernet/intel/e1000e/netdev.c b/drivers/net/ethernet/intel/e1000e/netdev.c index 89d788d8f263..faf4b3f3d0b5 100644 --- a/drivers/net/ethernet/intel/e1000e/netdev.c +++ b/drivers/net/ethernet/intel/e1000e/netdev.c @@ -48,7 +48,7 @@  #define DRV_EXTRAVERSION "-k" -#define DRV_VERSION "3.2.5" DRV_EXTRAVERSION +#define DRV_VERSION "3.2.6" DRV_EXTRAVERSION  char e1000e_driver_name[] = "e1000e";  const char e1000e_driver_version[] = DRV_VERSION; @@ -1737,12 +1737,6 @@ static void e1000_clean_rx_ring(struct e1000_ring *rx_ring)  	rx_ring->next_to_clean = 0;  	rx_ring->next_to_use = 0;  	adapter->flags2 &= ~FLAG2_IS_DISCARDING; - -	writel(0, rx_ring->head); -	if (adapter->flags2 & FLAG2_PCIM2PCI_ARBITER_WA) -		e1000e_update_rdt_wa(rx_ring, 0); -	else -		writel(0, rx_ring->tail);  }  static void e1000e_downshift_workaround(struct work_struct *work) @@ -2447,12 +2441,6 @@ static void e1000_clean_tx_ring(struct e1000_ring *tx_ring)  	tx_ring->next_to_use = 0;  	tx_ring->next_to_clean = 0; - -	writel(0, tx_ring->head); -	if (adapter->flags2 & FLAG2_PCIM2PCI_ARBITER_WA) -		e1000e_update_tdt_wa(tx_ring, 0); -	else -		writel(0, tx_ring->tail);  }  /** @@ -2954,6 +2942,12 @@ static void e1000_configure_tx(struct e1000_adapter *adapter)  	tx_ring->head = adapter->hw.hw_addr + E1000_TDH(0);  	tx_ring->tail = adapter->hw.hw_addr + E1000_TDT(0); +	writel(0, tx_ring->head); +	if (adapter->flags2 & FLAG2_PCIM2PCI_ARBITER_WA) +		e1000e_update_tdt_wa(tx_ring, 0); +	else +		writel(0, tx_ring->tail); +  	/* Set the Tx Interrupt Delay register */  	ew32(TIDV, adapter->tx_int_delay);  	/* Tx irq moderation */ @@ -3275,6 +3269,12 @@ static void e1000_configure_rx(struct e1000_adapter *adapter)  	rx_ring->head = adapter->hw.hw_addr + E1000_RDH(0);  	rx_ring->tail = adapter->hw.hw_addr + E1000_RDT(0); +	writel(0, rx_ring->head); +	if (adapter->flags2 & FLAG2_PCIM2PCI_ARBITER_WA) +		e1000e_update_rdt_wa(rx_ring, 0); +	else +		writel(0, rx_ring->tail); +  	/* Enable Receive Checksum Offload for TCP and UDP */  	rxcsum = er32(RXCSUM);  	if (adapter->netdev->features & NETIF_F_RXCSUM) @@ -4280,18 +4280,29 @@ static cycle_t e1000e_cyclecounter_read(const struct cyclecounter *cc)  	struct e1000_adapter *adapter = container_of(cc, struct e1000_adapter,  						     cc);  	struct e1000_hw *hw = &adapter->hw; +	u32 systimel_1, systimel_2, systimeh;  	cycle_t systim, systim_next; -	/* SYSTIMH latching upon SYSTIML read does not work well. To fix that -	 * we don't want to allow overflow of SYSTIML and a change to SYSTIMH -	 * to occur between reads, so if we read a vale close to overflow, we -	 * wait for overflow to occur and read both registers when its safe. +	/* SYSTIMH latching upon SYSTIML read does not work well. +	 * This means that if SYSTIML overflows after we read it but before +	 * we read SYSTIMH, the value of SYSTIMH has been incremented and we +	 * will experience a huge non linear increment in the systime value +	 * to fix that we test for overflow and if true, we re-read systime.  	 */ -	u32 systim_overflow_latch_fix = 0x3FFFFFFF; - -	do { -		systim = (cycle_t)er32(SYSTIML); -	} while (systim > systim_overflow_latch_fix); -	systim |= (cycle_t)er32(SYSTIMH) << 32; +	systimel_1 = er32(SYSTIML); +	systimeh = er32(SYSTIMH); +	systimel_2 = er32(SYSTIML); +	/* Check for overflow. If there was no overflow, use the values */ +	if (systimel_1 < systimel_2) { +		systim = (cycle_t)systimel_1; +		systim |= (cycle_t)systimeh << 32; +	} else { +		/* There was an overflow, read again SYSTIMH, and use +		 * systimel_2 +		 */ +		systimeh = er32(SYSTIMH); +		systim = (cycle_t)systimel_2; +		systim |= (cycle_t)systimeh << 32; +	}  	if ((hw->mac.type == e1000_82574) || (hw->mac.type == e1000_82583)) {  		u64 incvalue, time_delta, rem, temp; @@ -4588,6 +4599,7 @@ static int e1000_open(struct net_device *netdev)  	return 0;  err_req_irq: +	pm_qos_remove_request(&adapter->pm_qos_req);  	e1000e_release_hw_control(adapter);  	e1000_power_down_phy(adapter);  	e1000e_free_rx_resources(adapter->rx_ring); @@ -6316,6 +6328,33 @@ static int __e1000_shutdown(struct pci_dev *pdev, bool runtime)  			return retval;  	} +	/* Ensure that the appropriate bits are set in LPI_CTRL +	 * for EEE in Sx +	 */ +	if ((hw->phy.type >= e1000_phy_i217) && +	    adapter->eee_advert && hw->dev_spec.ich8lan.eee_lp_ability) { +		u16 lpi_ctrl = 0; + +		retval = hw->phy.ops.acquire(hw); +		if (!retval) { +			retval = e1e_rphy_locked(hw, I82579_LPI_CTRL, +						 &lpi_ctrl); +			if (!retval) { +				if (adapter->eee_advert & +				    hw->dev_spec.ich8lan.eee_lp_ability & +				    I82579_EEE_100_SUPPORTED) +					lpi_ctrl |= I82579_LPI_CTRL_100_ENABLE; +				if (adapter->eee_advert & +				    hw->dev_spec.ich8lan.eee_lp_ability & +				    I82579_EEE_1000_SUPPORTED) +					lpi_ctrl |= I82579_LPI_CTRL_1000_ENABLE; + +				retval = e1e_wphy_locked(hw, I82579_LPI_CTRL, +							 lpi_ctrl); +			} +		} +		hw->phy.ops.release(hw); +	}  	/* Release control of h/w to f/w.  If f/w is AMT enabled, this  	 * would have already happened in close and is redundant. @@ -6465,7 +6504,7 @@ static int __e1000_resume(struct pci_dev *pdev)  	if (adapter->flags2 & FLAG2_DISABLE_ASPM_L1)  		aspm_disable_flag |= PCIE_LINK_STATE_L1;  	if (aspm_disable_flag) -		e1000e_disable_aspm_locked(pdev, aspm_disable_flag); +		e1000e_disable_aspm(pdev, aspm_disable_flag);  	pci_set_master(pdev); @@ -6743,7 +6782,7 @@ static pci_ers_result_t e1000_io_slot_reset(struct pci_dev *pdev)  	if (adapter->flags2 & FLAG2_DISABLE_ASPM_L1)  		aspm_disable_flag |= PCIE_LINK_STATE_L1;  	if (aspm_disable_flag) -		e1000e_disable_aspm(pdev, aspm_disable_flag); +		e1000e_disable_aspm_locked(pdev, aspm_disable_flag);  	err = pci_enable_device_mem(pdev);  	if (err) {  |