diff options
Diffstat (limited to 'drivers/net/ethernet/intel/ixgbe/ixgbe_main.c')
| -rw-r--r-- | drivers/net/ethernet/intel/ixgbe/ixgbe_main.c | 157 | 
1 files changed, 83 insertions, 74 deletions
diff --git a/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c b/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c index 79f4a26ea6c..6225f880a3f 100644 --- a/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c +++ b/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c @@ -63,7 +63,7 @@ char ixgbe_default_device_descr[] =  static char ixgbe_default_device_descr[] =  			      "Intel(R) 10 Gigabit Network Connection";  #endif -#define DRV_VERSION "3.11.33-k" +#define DRV_VERSION "3.13.10-k"  const char ixgbe_driver_version[] = DRV_VERSION;  static const char ixgbe_copyright[] =  				"Copyright (c) 1999-2013 Intel Corporation."; @@ -149,6 +149,52 @@ MODULE_DESCRIPTION("Intel(R) 10 Gigabit PCI Express Network Driver");  MODULE_LICENSE("GPL");  MODULE_VERSION(DRV_VERSION); +static int ixgbe_read_pci_cfg_word_parent(struct ixgbe_adapter *adapter, +					  u32 reg, u16 *value) +{ +	int pos = 0; +	struct pci_dev *parent_dev; +	struct pci_bus *parent_bus; + +	parent_bus = adapter->pdev->bus->parent; +	if (!parent_bus) +		return -1; + +	parent_dev = parent_bus->self; +	if (!parent_dev) +		return -1; + +	pos = pci_find_capability(parent_dev, PCI_CAP_ID_EXP); +	if (!pos) +		return -1; + +	pci_read_config_word(parent_dev, pos + reg, value); +	return 0; +} + +static s32 ixgbe_get_parent_bus_info(struct ixgbe_adapter *adapter) +{ +	struct ixgbe_hw *hw = &adapter->hw; +	u16 link_status = 0; +	int err; + +	hw->bus.type = ixgbe_bus_type_pci_express; + +	/* Get the negotiated link width and speed from PCI config space of the +	 * parent, as this device is behind a switch +	 */ +	err = ixgbe_read_pci_cfg_word_parent(adapter, 18, &link_status); + +	/* assume caller will handle error case */ +	if (err) +		return err; + +	hw->bus.width = ixgbe_convert_bus_width(link_status); +	hw->bus.speed = ixgbe_convert_bus_speed(link_status); + +	return 0; +} +  static void ixgbe_service_event_schedule(struct ixgbe_adapter *adapter)  {  	if (!test_bit(__IXGBE_DOWN, &adapter->state) && @@ -1337,7 +1383,7 @@ static unsigned int ixgbe_get_headlen(unsigned char *data,  			return hdr.network - data;  		/* record next protocol if header is present */ -		if (!hdr.ipv4->frag_off) +		if (!(hdr.ipv4->frag_off & htons(IP_OFFSET)))  			nexthdr = hdr.ipv4->protocol;  	} else if (protocol == __constant_htons(ETH_P_IPV6)) {  		if ((hdr.network - data) > (max_len - sizeof(struct ipv6hdr))) @@ -1442,10 +1488,10 @@ static void ixgbe_process_skb_fields(struct ixgbe_ring *rx_ring,  	ixgbe_ptp_rx_hwtstamp(rx_ring, rx_desc, skb); -	if ((dev->features & NETIF_F_HW_VLAN_RX) && +	if ((dev->features & NETIF_F_HW_VLAN_CTAG_RX) &&  	    ixgbe_test_staterr(rx_desc, IXGBE_RXD_STAT_VP)) {  		u16 vid = le16_to_cpu(rx_desc->wb.upper.vlan); -		__vlan_hwaccel_put_tag(skb, vid); +		__vlan_hwaccel_put_tag(skb, htons(ETH_P_8021Q), vid);  	}  	skb_record_rx_queue(skb, rx_ring->queue_index); @@ -3421,7 +3467,8 @@ static void ixgbe_configure_rx(struct ixgbe_adapter *adapter)  	hw->mac.ops.enable_rx_dma(hw, rxctrl);  } -static int ixgbe_vlan_rx_add_vid(struct net_device *netdev, u16 vid) +static int ixgbe_vlan_rx_add_vid(struct net_device *netdev, +				 __be16 proto, u16 vid)  {  	struct ixgbe_adapter *adapter = netdev_priv(netdev);  	struct ixgbe_hw *hw = &adapter->hw; @@ -3433,7 +3480,8 @@ static int ixgbe_vlan_rx_add_vid(struct net_device *netdev, u16 vid)  	return 0;  } -static int ixgbe_vlan_rx_kill_vid(struct net_device *netdev, u16 vid) +static int ixgbe_vlan_rx_kill_vid(struct net_device *netdev, +				  __be16 proto, u16 vid)  {  	struct ixgbe_adapter *adapter = netdev_priv(netdev);  	struct ixgbe_hw *hw = &adapter->hw; @@ -3538,10 +3586,10 @@ static void ixgbe_restore_vlan(struct ixgbe_adapter *adapter)  {  	u16 vid; -	ixgbe_vlan_rx_add_vid(adapter->netdev, 0); +	ixgbe_vlan_rx_add_vid(adapter->netdev, htons(ETH_P_8021Q), 0);  	for_each_set_bit(vid, adapter->active_vlans, VLAN_N_VID) -		ixgbe_vlan_rx_add_vid(adapter->netdev, vid); +		ixgbe_vlan_rx_add_vid(adapter->netdev, htons(ETH_P_8021Q), vid);  }  /** @@ -3676,7 +3724,7 @@ void ixgbe_set_rx_mode(struct net_device *netdev)  	IXGBE_WRITE_REG(hw, IXGBE_FCTRL, fctrl); -	if (netdev->features & NETIF_F_HW_VLAN_RX) +	if (netdev->features & NETIF_F_HW_VLAN_CTAG_RX)  		ixgbe_vlan_strip_enable(adapter);  	else  		ixgbe_vlan_strip_disable(adapter); @@ -5077,14 +5125,14 @@ static int __ixgbe_shutdown(struct pci_dev *pdev, bool *enable_wake)  	netif_device_detach(netdev); +	rtnl_lock();  	if (netif_running(netdev)) { -		rtnl_lock();  		ixgbe_down(adapter);  		ixgbe_free_irq(adapter);  		ixgbe_free_all_tx_resources(adapter);  		ixgbe_free_all_rx_resources(adapter); -		rtnl_unlock();  	} +	rtnl_unlock();  	ixgbe_clear_interrupt_scheme(adapter); @@ -6425,9 +6473,7 @@ netdev_tx_t ixgbe_xmit_frame_ring(struct sk_buff *skb,  	struct ixgbe_tx_buffer *first;  	int tso;  	u32 tx_flags = 0; -#if PAGE_SIZE > IXGBE_MAX_DATA_PER_TXD  	unsigned short f; -#endif  	u16 count = TXD_USE_COUNT(skb_headlen(skb));  	__be16 protocol = skb->protocol;  	u8 hdr_len = 0; @@ -6439,12 +6485,9 @@ netdev_tx_t ixgbe_xmit_frame_ring(struct sk_buff *skb,  	 *       + 1 desc for context descriptor,  	 * otherwise try next time  	 */ -#if PAGE_SIZE > IXGBE_MAX_DATA_PER_TXD  	for (f = 0; f < skb_shinfo(skb)->nr_frags; f++)  		count += TXD_USE_COUNT(skb_shinfo(skb)->frags[f].size); -#else -	count += skb_shinfo(skb)->nr_frags; -#endif +  	if (ixgbe_maybe_stop_tx(tx_ring, count + 3)) {  		tx_ring->tx_stats.tx_busy++;  		return NETDEV_TX_BUSY; @@ -6983,7 +7026,7 @@ static int ixgbe_set_features(struct net_device *netdev,  		break;  	} -	if (features & NETIF_F_HW_VLAN_RX) +	if (features & NETIF_F_HW_VLAN_CTAG_RX)  		ixgbe_vlan_strip_enable(adapter);  	else  		ixgbe_vlan_strip_disable(adapter); @@ -7007,7 +7050,7 @@ static int ixgbe_ndo_fdb_add(struct ndmsg *ndm, struct nlattr *tb[],  	int err;  	if (!(adapter->flags & IXGBE_FLAG_SRIOV_ENABLED)) -		return -EOPNOTSUPP; +		return ndo_dflt_fdb_add(ndm, tb, dev, addr, flags);  	/* Hardware does not support aging addresses so if a  	 * ndm_state is given only allow permanent addresses @@ -7038,44 +7081,6 @@ static int ixgbe_ndo_fdb_add(struct ndmsg *ndm, struct nlattr *tb[],  	return err;  } -static int ixgbe_ndo_fdb_del(struct ndmsg *ndm, struct nlattr *tb[], -			     struct net_device *dev, -			     const unsigned char *addr) -{ -	struct ixgbe_adapter *adapter = netdev_priv(dev); -	int err = -EOPNOTSUPP; - -	if (ndm->ndm_state & NUD_PERMANENT) { -		pr_info("%s: FDB only supports static addresses\n", -			ixgbe_driver_name); -		return -EINVAL; -	} - -	if (adapter->flags & IXGBE_FLAG_SRIOV_ENABLED) { -		if (is_unicast_ether_addr(addr)) -			err = dev_uc_del(dev, addr); -		else if (is_multicast_ether_addr(addr)) -			err = dev_mc_del(dev, addr); -		else -			err = -EINVAL; -	} - -	return err; -} - -static int ixgbe_ndo_fdb_dump(struct sk_buff *skb, -			      struct netlink_callback *cb, -			      struct net_device *dev, -			      int idx) -{ -	struct ixgbe_adapter *adapter = netdev_priv(dev); - -	if (adapter->flags & IXGBE_FLAG_SRIOV_ENABLED) -		idx = ndo_dflt_fdb_dump(skb, cb, dev, idx); - -	return idx; -} -  static int ixgbe_ndo_bridge_setlink(struct net_device *dev,  				    struct nlmsghdr *nlh)  { @@ -7171,8 +7176,6 @@ static const struct net_device_ops ixgbe_netdev_ops = {  	.ndo_set_features = ixgbe_set_features,  	.ndo_fix_features = ixgbe_fix_features,  	.ndo_fdb_add		= ixgbe_ndo_fdb_add, -	.ndo_fdb_del		= ixgbe_ndo_fdb_del, -	.ndo_fdb_dump		= ixgbe_ndo_fdb_dump,  	.ndo_bridge_setlink	= ixgbe_ndo_bridge_setlink,  	.ndo_bridge_getlink	= ixgbe_ndo_bridge_getlink,  }; @@ -7205,6 +7208,7 @@ int ixgbe_wol_supported(struct ixgbe_adapter *adapter, u16 device_id,  		case IXGBE_SUBDEV_ID_82599_SFP:  		case IXGBE_SUBDEV_ID_82599_RNDC:  		case IXGBE_SUBDEV_ID_82599_ECNA_DP: +		case IXGBE_SUBDEV_ID_82599_LOM_SFP:  			is_wol_supported = 1;  			break;  		} @@ -7369,6 +7373,10 @@ static int ixgbe_probe(struct pci_dev *pdev, const struct pci_device_id *ent)  	if (err)  		goto err_sw_init; +	/* Cache if MNG FW is up so we don't have to read the REG later */ +	if (hw->mac.ops.mng_fw_enabled) +		hw->mng_fw_enabled = hw->mac.ops.mng_fw_enabled(hw); +  	/* Make it possible the adapter to be woken up via WOL */  	switch (adapter->hw.mac.type) {  	case ixgbe_mac_82599EB: @@ -7425,9 +7433,9 @@ skip_sriov:  	netdev->features = NETIF_F_SG |  			   NETIF_F_IP_CSUM |  			   NETIF_F_IPV6_CSUM | -			   NETIF_F_HW_VLAN_TX | -			   NETIF_F_HW_VLAN_RX | -			   NETIF_F_HW_VLAN_FILTER | +			   NETIF_F_HW_VLAN_CTAG_TX | +			   NETIF_F_HW_VLAN_CTAG_RX | +			   NETIF_F_HW_VLAN_CTAG_FILTER |  			   NETIF_F_TSO |  			   NETIF_F_TSO6 |  			   NETIF_F_RXHASH | @@ -7521,7 +7529,9 @@ skip_sriov:  	/* WOL not supported for all devices */  	adapter->wol = 0;  	hw->eeprom.ops.read(hw, 0x2c, &adapter->eeprom_cap); -	if (ixgbe_wol_supported(adapter, pdev->device, pdev->subsystem_device)) +	hw->wol_supported = ixgbe_wol_supported(adapter, pdev->device, +						pdev->subsystem_device); +	if (hw->wol_supported)  		adapter->wol = IXGBE_WUFC_MAG;  	device_set_wakeup_enable(&adapter->pdev->dev, adapter->wol); @@ -7532,10 +7542,13 @@ skip_sriov:  	/* pick up the PCI bus settings for reporting later */  	hw->mac.ops.get_bus_info(hw); +	if (hw->device_id == IXGBE_DEV_ID_82599_SFP_SF_QP) +		ixgbe_get_parent_bus_info(adapter);  	/* print bus type/speed/width info */  	e_dev_info("(PCI Express:%s:%s) %pM\n", -		   (hw->bus.speed == ixgbe_bus_speed_5000 ? "5.0GT/s" : +		   (hw->bus.speed == ixgbe_bus_speed_8000 ? "8.0GT/s" : +		    hw->bus.speed == ixgbe_bus_speed_5000 ? "5.0GT/s" :  		    hw->bus.speed == ixgbe_bus_speed_2500 ? "2.5GT/s" :  		    "Unknown"),  		   (hw->bus.width == ixgbe_bus_width_pcie_x8 ? "Width x8" : @@ -7615,9 +7628,13 @@ skip_sriov:  		e_err(probe, "failed to allocate sysfs resources\n");  #endif /* CONFIG_IXGBE_HWMON */ -#ifdef CONFIG_DEBUG_FS  	ixgbe_dbg_adapter_init(adapter); -#endif /* CONFIG_DEBUG_FS */ + +	/* Need link setup for MNG FW, else wait for IXGBE_UP */ +	if (hw->mng_fw_enabled && hw->mac.ops.setup_link) +		hw->mac.ops.setup_link(hw, +			IXGBE_LINK_SPEED_10GB_FULL | IXGBE_LINK_SPEED_1GB_FULL, +			true);  	return 0; @@ -7653,9 +7670,7 @@ static void ixgbe_remove(struct pci_dev *pdev)  	struct ixgbe_adapter *adapter = pci_get_drvdata(pdev);  	struct net_device *netdev = adapter->netdev; -#ifdef CONFIG_DEBUG_FS  	ixgbe_dbg_adapter_exit(adapter); -#endif /*CONFIG_DEBUG_FS */  	set_bit(__IXGBE_DOWN, &adapter->state);  	cancel_work_sync(&adapter->service_task); @@ -7918,15 +7933,11 @@ static int __init ixgbe_init_module(void)  	pr_info("%s - version %s\n", ixgbe_driver_string, ixgbe_driver_version);  	pr_info("%s\n", ixgbe_copyright); -#ifdef CONFIG_DEBUG_FS  	ixgbe_dbg_init(); -#endif /* CONFIG_DEBUG_FS */  	ret = pci_register_driver(&ixgbe_driver);  	if (ret) { -#ifdef CONFIG_DEBUG_FS  		ixgbe_dbg_exit(); -#endif /* CONFIG_DEBUG_FS */  		return ret;  	} @@ -7952,9 +7963,7 @@ static void __exit ixgbe_exit_module(void)  #endif  	pci_unregister_driver(&ixgbe_driver); -#ifdef CONFIG_DEBUG_FS  	ixgbe_dbg_exit(); -#endif /* CONFIG_DEBUG_FS */  	rcu_barrier(); /* Wait for completion of call_rcu()'s */  }  |