diff options
Diffstat (limited to 'drivers/net/ethernet/intel')
| -rw-r--r-- | drivers/net/ethernet/intel/e1000e/ethtool.c | 13 | ||||
| -rw-r--r-- | drivers/net/ethernet/intel/e1000e/ich8lan.c | 71 | ||||
| -rw-r--r-- | drivers/net/ethernet/intel/e1000e/ich8lan.h | 2 | ||||
| -rw-r--r-- | drivers/net/ethernet/intel/e1000e/netdev.c | 82 | ||||
| -rw-r--r-- | drivers/net/ethernet/intel/e1000e/regs.h | 1 | ||||
| -rw-r--r-- | drivers/net/ethernet/intel/igb/e1000_82575.c | 11 | ||||
| -rw-r--r-- | drivers/net/ethernet/intel/igb/igb.h | 2 | ||||
| -rw-r--r-- | drivers/net/ethernet/intel/igb/igb_hwmon.c | 14 | ||||
| -rw-r--r-- | drivers/net/ethernet/intel/igb/igb_main.c | 76 | 
9 files changed, 132 insertions, 140 deletions
diff --git a/drivers/net/ethernet/intel/e1000e/ethtool.c b/drivers/net/ethernet/intel/e1000e/ethtool.c index 2c1813737f6..f91a8f3f9d4 100644 --- a/drivers/net/ethernet/intel/e1000e/ethtool.c +++ b/drivers/net/ethernet/intel/e1000e/ethtool.c @@ -36,6 +36,7 @@  #include <linux/delay.h>  #include <linux/vmalloc.h>  #include <linux/mdio.h> +#include <linux/pm_runtime.h>  #include "e1000.h" @@ -2229,7 +2230,19 @@ static int e1000e_get_ts_info(struct net_device *netdev,  	return 0;  } +static int e1000e_ethtool_begin(struct net_device *netdev) +{ +	return pm_runtime_get_sync(netdev->dev.parent); +} + +static void e1000e_ethtool_complete(struct net_device *netdev) +{ +	pm_runtime_put_sync(netdev->dev.parent); +} +  static const struct ethtool_ops e1000_ethtool_ops = { +	.begin			= e1000e_ethtool_begin, +	.complete		= e1000e_ethtool_complete,  	.get_settings		= e1000_get_settings,  	.set_settings		= e1000_set_settings,  	.get_drvinfo		= e1000_get_drvinfo, diff --git a/drivers/net/ethernet/intel/e1000e/ich8lan.c b/drivers/net/ethernet/intel/e1000e/ich8lan.c index dff7bff8b8e..121a865c7fb 100644 --- a/drivers/net/ethernet/intel/e1000e/ich8lan.c +++ b/drivers/net/ethernet/intel/e1000e/ich8lan.c @@ -782,6 +782,59 @@ release:  }  /** + *  e1000_k1_workaround_lpt_lp - K1 workaround on Lynxpoint-LP + *  @hw:   pointer to the HW structure + *  @link: link up bool flag + * + *  When K1 is enabled for 1Gbps, the MAC can miss 2 DMA completion indications + *  preventing further DMA write requests.  Workaround the issue by disabling + *  the de-assertion of the clock request when in 1Gpbs mode. + **/ +static s32 e1000_k1_workaround_lpt_lp(struct e1000_hw *hw, bool link) +{ +	u32 fextnvm6 = er32(FEXTNVM6); +	s32 ret_val = 0; + +	if (link && (er32(STATUS) & E1000_STATUS_SPEED_1000)) { +		u16 kmrn_reg; + +		ret_val = hw->phy.ops.acquire(hw); +		if (ret_val) +			return ret_val; + +		ret_val = +		    e1000e_read_kmrn_reg_locked(hw, E1000_KMRNCTRLSTA_K1_CONFIG, +						&kmrn_reg); +		if (ret_val) +			goto release; + +		ret_val = +		    e1000e_write_kmrn_reg_locked(hw, +						 E1000_KMRNCTRLSTA_K1_CONFIG, +						 kmrn_reg & +						 ~E1000_KMRNCTRLSTA_K1_ENABLE); +		if (ret_val) +			goto release; + +		usleep_range(10, 20); + +		ew32(FEXTNVM6, fextnvm6 | E1000_FEXTNVM6_REQ_PLL_CLK); + +		ret_val = +		    e1000e_write_kmrn_reg_locked(hw, +						 E1000_KMRNCTRLSTA_K1_CONFIG, +						 kmrn_reg); +release: +		hw->phy.ops.release(hw); +	} else { +		/* clear FEXTNVM6 bit 8 on link down or 10/100 */ +		ew32(FEXTNVM6, fextnvm6 & ~E1000_FEXTNVM6_REQ_PLL_CLK); +	} + +	return ret_val; +} + +/**   *  e1000_check_for_copper_link_ich8lan - Check for link (Copper)   *  @hw: pointer to the HW structure   * @@ -818,6 +871,14 @@ static s32 e1000_check_for_copper_link_ich8lan(struct e1000_hw *hw)  			return ret_val;  	} +	/* Work-around I218 hang issue */ +	if ((hw->adapter->pdev->device == E1000_DEV_ID_PCH_LPTLP_I218_LM) || +	    (hw->adapter->pdev->device == E1000_DEV_ID_PCH_LPTLP_I218_V)) { +		ret_val = e1000_k1_workaround_lpt_lp(hw, link); +		if (ret_val) +			return ret_val; +	} +  	/* Clear link partner's EEE ability */  	hw->dev_spec.ich8lan.eee_lp_ability = 0; @@ -3954,8 +4015,16 @@ void e1000_suspend_workarounds_ich8lan(struct e1000_hw *hw)  	phy_ctrl = er32(PHY_CTRL);  	phy_ctrl |= E1000_PHY_CTRL_GBE_DISABLE; +  	if (hw->phy.type == e1000_phy_i217) { -		u16 phy_reg; +		u16 phy_reg, device_id = hw->adapter->pdev->device; + +		if ((device_id == E1000_DEV_ID_PCH_LPTLP_I218_LM) || +		    (device_id == E1000_DEV_ID_PCH_LPTLP_I218_V)) { +			u32 fextnvm6 = er32(FEXTNVM6); + +			ew32(FEXTNVM6, fextnvm6 & ~E1000_FEXTNVM6_REQ_PLL_CLK); +		}  		ret_val = hw->phy.ops.acquire(hw);  		if (ret_val) diff --git a/drivers/net/ethernet/intel/e1000e/ich8lan.h b/drivers/net/ethernet/intel/e1000e/ich8lan.h index b6d3174d7d2..8bf4655c2e1 100644 --- a/drivers/net/ethernet/intel/e1000e/ich8lan.h +++ b/drivers/net/ethernet/intel/e1000e/ich8lan.h @@ -92,6 +92,8 @@  #define E1000_FEXTNVM4_BEACON_DURATION_8USEC	0x7  #define E1000_FEXTNVM4_BEACON_DURATION_16USEC	0x3 +#define E1000_FEXTNVM6_REQ_PLL_CLK	0x00000100 +  #define PCIE_ICH8_SNOOP_ALL	PCIE_NO_SNOOP_ALL  #define E1000_ICH_RAR_ENTRIES	7 diff --git a/drivers/net/ethernet/intel/e1000e/netdev.c b/drivers/net/ethernet/intel/e1000e/netdev.c index a177b8b65c4..948b86ffa4f 100644 --- a/drivers/net/ethernet/intel/e1000e/netdev.c +++ b/drivers/net/ethernet/intel/e1000e/netdev.c @@ -4303,6 +4303,7 @@ static int e1000_open(struct net_device *netdev)  	netif_start_queue(netdev);  	adapter->idle_check = true; +	hw->mac.get_link_status = true;  	pm_runtime_put(&pdev->dev);  	/* fire a link status change interrupt to start the watchdog */ @@ -4662,6 +4663,7 @@ static void e1000_phy_read_status(struct e1000_adapter *adapter)  	    (adapter->hw.phy.media_type == e1000_media_type_copper)) {  		int ret_val; +		pm_runtime_get_sync(&adapter->pdev->dev);  		ret_val = e1e_rphy(hw, MII_BMCR, &phy->bmcr);  		ret_val |= e1e_rphy(hw, MII_BMSR, &phy->bmsr);  		ret_val |= e1e_rphy(hw, MII_ADVERTISE, &phy->advertise); @@ -4672,6 +4674,7 @@ static void e1000_phy_read_status(struct e1000_adapter *adapter)  		ret_val |= e1e_rphy(hw, MII_ESTATUS, &phy->estatus);  		if (ret_val)  			e_warn("Error reading PHY register\n"); +		pm_runtime_put_sync(&adapter->pdev->dev);  	} else {  		/* Do not read PHY registers if link is not up  		 * Set values to typical power-on defaults @@ -5887,8 +5890,7 @@ release:  	return retval;  } -static int __e1000_shutdown(struct pci_dev *pdev, bool *enable_wake, -			    bool runtime) +static int __e1000_shutdown(struct pci_dev *pdev, bool runtime)  {  	struct net_device *netdev = pci_get_drvdata(pdev);  	struct e1000_adapter *adapter = netdev_priv(netdev); @@ -5912,10 +5914,6 @@ static int __e1000_shutdown(struct pci_dev *pdev, bool *enable_wake,  	}  	e1000e_reset_interrupt_capability(adapter); -	retval = pci_save_state(pdev); -	if (retval) -		return retval; -  	status = er32(STATUS);  	if (status & E1000_STATUS_LU)  		wufc &= ~E1000_WUFC_LNKC; @@ -5971,13 +5969,6 @@ static int __e1000_shutdown(struct pci_dev *pdev, bool *enable_wake,  		ew32(WUFC, 0);  	} -	*enable_wake = !!wufc; - -	/* make sure adapter isn't asleep if manageability is enabled */ -	if ((adapter->flags & FLAG_MNG_PT_ENABLED) || -	    (hw->mac.ops.check_mng_mode(hw))) -		*enable_wake = true; -  	if (adapter->hw.phy.type == e1000_phy_igp_3)  		e1000e_igp3_phy_powerdown_workaround_ich8lan(&adapter->hw); @@ -5986,27 +5977,7 @@ static int __e1000_shutdown(struct pci_dev *pdev, bool *enable_wake,  	 */  	e1000e_release_hw_control(adapter); -	pci_disable_device(pdev); - -	return 0; -} - -static void e1000_power_off(struct pci_dev *pdev, bool sleep, bool wake) -{ -	if (sleep && wake) { -		pci_prepare_to_sleep(pdev); -		return; -	} - -	pci_wake_from_d3(pdev, wake); -	pci_set_power_state(pdev, PCI_D3hot); -} - -static void e1000_complete_shutdown(struct pci_dev *pdev, bool sleep, -                                    bool wake) -{ -	struct net_device *netdev = pci_get_drvdata(pdev); -	struct e1000_adapter *adapter = netdev_priv(netdev); +	pci_clear_master(pdev);  	/* The pci-e switch on some quad port adapters will report a  	 * correctable error when the MAC transitions from D0 to D3.  To @@ -6021,12 +5992,13 @@ static void e1000_complete_shutdown(struct pci_dev *pdev, bool sleep,  		pcie_capability_write_word(us_dev, PCI_EXP_DEVCTL,  					   (devctl & ~PCI_EXP_DEVCTL_CERE)); -		e1000_power_off(pdev, sleep, wake); +		pci_save_state(pdev); +		pci_prepare_to_sleep(pdev);  		pcie_capability_write_word(us_dev, PCI_EXP_DEVCTL, devctl); -	} else { -		e1000_power_off(pdev, sleep, wake);  	} + +	return 0;  }  #ifdef CONFIG_PCIEASPM @@ -6084,9 +6056,7 @@ static int __e1000_resume(struct pci_dev *pdev)  	if (aspm_disable_flag)  		e1000e_disable_aspm(pdev, aspm_disable_flag); -	pci_set_power_state(pdev, PCI_D0); -	pci_restore_state(pdev); -	pci_save_state(pdev); +	pci_set_master(pdev);  	e1000e_set_interrupt_capability(adapter);  	if (netif_running(netdev)) { @@ -6152,14 +6122,8 @@ static int __e1000_resume(struct pci_dev *pdev)  static int e1000_suspend(struct device *dev)  {  	struct pci_dev *pdev = to_pci_dev(dev); -	int retval; -	bool wake; - -	retval = __e1000_shutdown(pdev, &wake, false); -	if (!retval) -		e1000_complete_shutdown(pdev, true, wake); -	return retval; +	return __e1000_shutdown(pdev, false);  }  static int e1000_resume(struct device *dev) @@ -6182,13 +6146,10 @@ static int e1000_runtime_suspend(struct device *dev)  	struct net_device *netdev = pci_get_drvdata(pdev);  	struct e1000_adapter *adapter = netdev_priv(netdev); -	if (e1000e_pm_ready(adapter)) { -		bool wake; - -		__e1000_shutdown(pdev, &wake, true); -	} +	if (!e1000e_pm_ready(adapter)) +		return 0; -	return 0; +	return __e1000_shutdown(pdev, true);  }  static int e1000_idle(struct device *dev) @@ -6226,12 +6187,7 @@ static int e1000_runtime_resume(struct device *dev)  static void e1000_shutdown(struct pci_dev *pdev)  { -	bool wake = false; - -	__e1000_shutdown(pdev, &wake, false); - -	if (system_state == SYSTEM_POWER_OFF) -		e1000_complete_shutdown(pdev, false, wake); +	__e1000_shutdown(pdev, false);  }  #ifdef CONFIG_NET_POLL_CONTROLLER @@ -6352,9 +6308,9 @@ static pci_ers_result_t e1000_io_slot_reset(struct pci_dev *pdev)  			"Cannot re-enable PCI device after reset.\n");  		result = PCI_ERS_RESULT_DISCONNECT;  	} else { -		pci_set_master(pdev);  		pdev->state_saved = true;  		pci_restore_state(pdev); +		pci_set_master(pdev);  		pci_enable_wake(pdev, PCI_D3hot, 0);  		pci_enable_wake(pdev, PCI_D3cold, 0); @@ -6783,7 +6739,11 @@ static int e1000_probe(struct pci_dev *pdev, const struct pci_device_id *ent)  	/* initialize the wol settings based on the eeprom settings */  	adapter->wol = adapter->eeprom_wol; -	device_set_wakeup_enable(&adapter->pdev->dev, adapter->wol); + +	/* make sure adapter isn't asleep if manageability is enabled */ +	if (adapter->wol || (adapter->flags & FLAG_MNG_PT_ENABLED) || +	    (hw->mac.ops.check_mng_mode(hw))) +		device_wakeup_enable(&pdev->dev);  	/* save off EEPROM version number */  	e1000_read_nvm(&adapter->hw, 5, 1, &adapter->eeprom_vers); diff --git a/drivers/net/ethernet/intel/e1000e/regs.h b/drivers/net/ethernet/intel/e1000e/regs.h index 794fe149766..a7e6a3e3725 100644 --- a/drivers/net/ethernet/intel/e1000e/regs.h +++ b/drivers/net/ethernet/intel/e1000e/regs.h @@ -42,6 +42,7 @@  #define E1000_FEXTNVM	0x00028	/* Future Extended NVM - RW */  #define E1000_FEXTNVM3	0x0003C	/* Future Extended NVM 3 - RW */  #define E1000_FEXTNVM4	0x00024	/* Future Extended NVM 4 - RW */ +#define E1000_FEXTNVM6	0x00010	/* Future Extended NVM 6 - RW */  #define E1000_FEXTNVM7	0x000E4	/* Future Extended NVM 7 - RW */  #define E1000_FCT	0x00030	/* Flow Control Type - RW */  #define E1000_VET	0x00038	/* VLAN Ether Type - RW */ diff --git a/drivers/net/ethernet/intel/igb/e1000_82575.c b/drivers/net/ethernet/intel/igb/e1000_82575.c index 84e7e0909de..b64542acfa3 100644 --- a/drivers/net/ethernet/intel/igb/e1000_82575.c +++ b/drivers/net/ethernet/intel/igb/e1000_82575.c @@ -1361,11 +1361,16 @@ static s32 igb_setup_copper_link_82575(struct e1000_hw *hw)  	switch (hw->phy.type) {  	case e1000_phy_i210:  	case e1000_phy_m88: -		if (hw->phy.id == I347AT4_E_PHY_ID || -		    hw->phy.id == M88E1112_E_PHY_ID) +		switch (hw->phy.id) { +		case I347AT4_E_PHY_ID: +		case M88E1112_E_PHY_ID: +		case I210_I_PHY_ID:  			ret_val = igb_copper_link_setup_m88_gen2(hw); -		else +			break; +		default:  			ret_val = igb_copper_link_setup_m88(hw); +			break; +		}  		break;  	case e1000_phy_igp_3:  		ret_val = igb_copper_link_setup_igp(hw); diff --git a/drivers/net/ethernet/intel/igb/igb.h b/drivers/net/ethernet/intel/igb/igb.h index d27edbc6392..25151401c2a 100644 --- a/drivers/net/ethernet/intel/igb/igb.h +++ b/drivers/net/ethernet/intel/igb/igb.h @@ -447,7 +447,7 @@ struct igb_adapter {  #endif  	struct i2c_algo_bit_data i2c_algo;  	struct i2c_adapter i2c_adap; -	struct igb_i2c_client_list *i2c_clients; +	struct i2c_client *i2c_client;  };  #define IGB_FLAG_HAS_MSI		(1 << 0) diff --git a/drivers/net/ethernet/intel/igb/igb_hwmon.c b/drivers/net/ethernet/intel/igb/igb_hwmon.c index 0a9b073d0b0..4623502054d 100644 --- a/drivers/net/ethernet/intel/igb/igb_hwmon.c +++ b/drivers/net/ethernet/intel/igb/igb_hwmon.c @@ -39,6 +39,10 @@  #include <linux/pci.h>  #ifdef CONFIG_IGB_HWMON +struct i2c_board_info i350_sensor_info = { +	I2C_BOARD_INFO("i350bb", (0Xf8 >> 1)), +}; +  /* hwmon callback functions */  static ssize_t igb_hwmon_show_location(struct device *dev,  					 struct device_attribute *attr, @@ -188,6 +192,7 @@ int igb_sysfs_init(struct igb_adapter *adapter)  	unsigned int i;  	int n_attrs;  	int rc = 0; +	struct i2c_client *client = NULL;  	/* If this method isn't defined we don't support thermals */  	if (adapter->hw.mac.ops.init_thermal_sensor_thresh == NULL) @@ -198,6 +203,15 @@ int igb_sysfs_init(struct igb_adapter *adapter)  		if (rc)  			goto exit; +	/* init i2c_client */ +	client = i2c_new_device(&adapter->i2c_adap, &i350_sensor_info); +	if (client == NULL) { +		dev_info(&adapter->pdev->dev, +			"Failed to create new i2c device..\n"); +		goto exit; +	} +	adapter->i2c_client = client; +  	/* Allocation space for max attributes  	 * max num sensors * values (loc, temp, max, caution)  	 */ diff --git a/drivers/net/ethernet/intel/igb/igb_main.c b/drivers/net/ethernet/intel/igb/igb_main.c index ed79a1c53b5..4dbd62968c7 100644 --- a/drivers/net/ethernet/intel/igb/igb_main.c +++ b/drivers/net/ethernet/intel/igb/igb_main.c @@ -1923,10 +1923,6 @@ void igb_set_fw_version(struct igb_adapter *adapter)  	return;  } -static const struct i2c_board_info i350_sensor_info = { -	I2C_BOARD_INFO("i350bb", 0Xf8), -}; -  /*  igb_init_i2c - Init I2C interface   *  @adapter: pointer to adapter structure   * @@ -6227,13 +6223,6 @@ static struct sk_buff *igb_build_rx_buffer(struct igb_ring *rx_ring,  	/* If we spanned a buffer we have a huge mess so test for it */  	BUG_ON(unlikely(!igb_test_staterr(rx_desc, E1000_RXD_STAT_EOP))); -	/* Guarantee this function can be used by verifying buffer sizes */ -	BUILD_BUG_ON(SKB_WITH_OVERHEAD(IGB_RX_BUFSZ) < (NET_SKB_PAD + -							NET_IP_ALIGN + -							IGB_TS_HDR_LEN + -							ETH_FRAME_LEN + -							ETH_FCS_LEN)); -  	rx_buffer = &rx_ring->rx_buffer_info[rx_ring->next_to_clean];  	page = rx_buffer->page;  	prefetchw(page); @@ -7724,67 +7713,6 @@ static void igb_init_dmac(struct igb_adapter *adapter, u32 pba)  	}  } -static DEFINE_SPINLOCK(i2c_clients_lock); - -/*  igb_get_i2c_client - returns matching client - *  in adapters's client list. - *  @adapter: adapter struct - *  @dev_addr: device address of i2c needed. - */ -static struct i2c_client * -igb_get_i2c_client(struct igb_adapter *adapter, u8 dev_addr) -{ -	ulong flags; -	struct igb_i2c_client_list *client_list; -	struct i2c_client *client = NULL; -	struct i2c_board_info client_info = { -		I2C_BOARD_INFO("igb", 0x00), -	}; - -	spin_lock_irqsave(&i2c_clients_lock, flags); -	client_list = adapter->i2c_clients; - -	/* See if we already have an i2c_client */ -	while (client_list) { -		if (client_list->client->addr == (dev_addr >> 1)) { -			client = client_list->client; -			goto exit; -		} else { -			client_list = client_list->next; -		} -	} - -	/* no client_list found, create a new one */ -	client_list = kzalloc(sizeof(*client_list), GFP_ATOMIC); -	if (client_list == NULL) -		goto exit; - -	/* dev_addr passed to us is left-shifted by 1 bit -	 * i2c_new_device call expects it to be flush to the right. -	 */ -	client_info.addr = dev_addr >> 1; -	client_info.platform_data = adapter; -	client_list->client = i2c_new_device(&adapter->i2c_adap, &client_info); -	if (client_list->client == NULL) { -		dev_info(&adapter->pdev->dev, -			"Failed to create new i2c device..\n"); -		goto err_no_client; -	} - -	/* insert new client at head of list */ -	client_list->next = adapter->i2c_clients; -	adapter->i2c_clients = client_list; - -	client = client_list->client; -	goto exit; - -err_no_client: -	kfree(client_list); -exit: -	spin_unlock_irqrestore(&i2c_clients_lock, flags); -	return client; -} -  /*  igb_read_i2c_byte - Reads 8 bit word over I2C   *  @hw: pointer to hardware structure   *  @byte_offset: byte offset to read @@ -7798,7 +7726,7 @@ s32 igb_read_i2c_byte(struct e1000_hw *hw, u8 byte_offset,  				u8 dev_addr, u8 *data)  {  	struct igb_adapter *adapter = container_of(hw, struct igb_adapter, hw); -	struct i2c_client *this_client = igb_get_i2c_client(adapter, dev_addr); +	struct i2c_client *this_client = adapter->i2c_client;  	s32 status;  	u16 swfw_mask = 0; @@ -7835,7 +7763,7 @@ s32 igb_write_i2c_byte(struct e1000_hw *hw, u8 byte_offset,  				 u8 dev_addr, u8 data)  {  	struct igb_adapter *adapter = container_of(hw, struct igb_adapter, hw); -	struct i2c_client *this_client = igb_get_i2c_client(adapter, dev_addr); +	struct i2c_client *this_client = adapter->i2c_client;  	s32 status;  	u16 swfw_mask = E1000_SWFW_PHY0_SM;  |