diff options
| author | Dmitry Torokhov <[email protected]> | 2023-08-30 16:06:38 -0700 | 
|---|---|---|
| committer | Dmitry Torokhov <[email protected]> | 2023-08-30 16:06:38 -0700 | 
| commit | 1ac731c529cd4d6adbce134754b51ff7d822b145 (patch) | |
| tree | 143ab3f35ca5f3b69f583c84e6964b17139c2ec1 /drivers/net/ethernet/intel | |
| parent | 07b4c950f27bef0362dc6ad7ee713aab61d58149 (diff) | |
| parent | 54116d442e001e1b6bd482122043b1870998a1f3 (diff) | |
Merge branch 'next' into for-linus
Prepare input updates for 6.6 merge window.
Diffstat (limited to 'drivers/net/ethernet/intel')
77 files changed, 1162 insertions, 7365 deletions
diff --git a/drivers/net/ethernet/intel/Kconfig b/drivers/net/ethernet/intel/Kconfig index c18c3b373846..9bc0a9519899 100644 --- a/drivers/net/ethernet/intel/Kconfig +++ b/drivers/net/ethernet/intel/Kconfig @@ -139,23 +139,6 @@ config IGBVF  	  To compile this driver as a module, choose M here. The module  	  will be called igbvf. -config IXGB -	tristate "Intel(R) PRO/10GbE support" -	depends on PCI -	help -	  This driver supports Intel(R) PRO/10GbE family of adapters for -	  PCI-X type cards. For PCI-E type cards, use the "ixgbe" driver -	  instead. For more information on how to identify your adapter, go -	  to the Adapter & Driver ID Guide that can be located at: - -	  <http://support.intel.com> - -	  More specific information on configuring the driver is in -	  <file:Documentation/networking/device_drivers/ethernet/intel/ixgb.rst>. - -	  To compile this driver as a module, choose M here. The module -	  will be called ixgb. -  config IXGBE  	tristate "Intel(R) 10GbE PCI Express adapters support"  	depends on PCI diff --git a/drivers/net/ethernet/intel/Makefile b/drivers/net/ethernet/intel/Makefile index 3075290063f6..d80d04132073 100644 --- a/drivers/net/ethernet/intel/Makefile +++ b/drivers/net/ethernet/intel/Makefile @@ -12,7 +12,6 @@ obj-$(CONFIG_IGBVF) += igbvf/  obj-$(CONFIG_IXGBE) += ixgbe/  obj-$(CONFIG_IXGBEVF) += ixgbevf/  obj-$(CONFIG_I40E) += i40e/ -obj-$(CONFIG_IXGB) += ixgb/  obj-$(CONFIG_IAVF) += iavf/  obj-$(CONFIG_FM10K) += fm10k/  obj-$(CONFIG_ICE) += ice/ diff --git a/drivers/net/ethernet/intel/e1000e/netdev.c b/drivers/net/ethernet/intel/e1000e/netdev.c index e1eb1de88bf9..bd7ef59b1f2e 100644 --- a/drivers/net/ethernet/intel/e1000e/netdev.c +++ b/drivers/net/ethernet/intel/e1000e/netdev.c @@ -23,7 +23,6 @@  #include <linux/smp.h>  #include <linux/pm_qos.h>  #include <linux/pm_runtime.h> -#include <linux/aer.h>  #include <linux/prefetch.h>  #include <linux/suspend.h> @@ -5288,31 +5287,6 @@ static void e1000_watchdog_task(struct work_struct *work)  				ew32(TARC(0), tarc0);  			} -			/* disable TSO for pcie and 10/100 speeds, to avoid -			 * some hardware issues -			 */ -			if (!(adapter->flags & FLAG_TSO_FORCE)) { -				switch (adapter->link_speed) { -				case SPEED_10: -				case SPEED_100: -					e_info("10/100 speed: disabling TSO\n"); -					netdev->features &= ~NETIF_F_TSO; -					netdev->features &= ~NETIF_F_TSO6; -					break; -				case SPEED_1000: -					netdev->features |= NETIF_F_TSO; -					netdev->features |= NETIF_F_TSO6; -					break; -				default: -					/* oops */ -					break; -				} -				if (hw->mac.type == e1000_pch_spt) { -					netdev->features &= ~NETIF_F_TSO; -					netdev->features &= ~NETIF_F_TSO6; -				} -			} -  			/* enable transmits in the hardware, need to do this  			 * after setting TARC(0)  			 */ @@ -7526,6 +7500,32 @@ static int e1000_probe(struct pci_dev *pdev, const struct pci_device_id *ent)  			    NETIF_F_RXCSUM |  			    NETIF_F_HW_CSUM); +	/* disable TSO for pcie and 10/100 speeds to avoid +	 * some hardware issues and for i219 to fix transfer +	 * speed being capped at 60% +	 */ +	if (!(adapter->flags & FLAG_TSO_FORCE)) { +		switch (adapter->link_speed) { +		case SPEED_10: +		case SPEED_100: +			e_info("10/100 speed: disabling TSO\n"); +			netdev->features &= ~NETIF_F_TSO; +			netdev->features &= ~NETIF_F_TSO6; +			break; +		case SPEED_1000: +			netdev->features |= NETIF_F_TSO; +			netdev->features |= NETIF_F_TSO6; +			break; +		default: +			/* oops */ +			break; +		} +		if (hw->mac.type == e1000_pch_spt) { +			netdev->features &= ~NETIF_F_TSO; +			netdev->features &= ~NETIF_F_TSO6; +		} +	} +  	/* Set user-changeable features (subset of all device features) */  	netdev->hw_features = netdev->features;  	netdev->hw_features |= NETIF_F_RXFCS; diff --git a/drivers/net/ethernet/intel/fm10k/fm10k_pci.c b/drivers/net/ethernet/intel/fm10k/fm10k_pci.c index 027d721feb18..d748b98274e7 100644 --- a/drivers/net/ethernet/intel/fm10k/fm10k_pci.c +++ b/drivers/net/ethernet/intel/fm10k/fm10k_pci.c @@ -3,7 +3,6 @@  #include <linux/module.h>  #include <linux/interrupt.h> -#include <linux/aer.h>  #include "fm10k.h" diff --git a/drivers/net/ethernet/intel/i40e/i40e.h b/drivers/net/ethernet/intel/i40e/i40e.h index 60ce4d15d82a..6e310a539467 100644 --- a/drivers/net/ethernet/intel/i40e/i40e.h +++ b/drivers/net/ethernet/intel/i40e/i40e.h @@ -10,7 +10,6 @@  #include <linux/errno.h>  #include <linux/module.h>  #include <linux/pci.h> -#include <linux/aer.h>  #include <linux/netdevice.h>  #include <linux/ioport.h>  #include <linux/iommu.h> diff --git a/drivers/net/ethernet/intel/i40e/i40e_diag.c b/drivers/net/ethernet/intel/i40e/i40e_diag.c index 5b3519c6e362..97fe1787a8f4 100644 --- a/drivers/net/ethernet/intel/i40e/i40e_diag.c +++ b/drivers/net/ethernet/intel/i40e/i40e_diag.c @@ -44,7 +44,7 @@ static int i40e_diag_reg_pattern_test(struct i40e_hw *hw,  	return 0;  } -struct i40e_diag_reg_test_info i40e_reg_list[] = { +const struct i40e_diag_reg_test_info i40e_reg_list[] = {  	/* offset               mask         elements   stride */  	{I40E_QTX_CTL(0),       0x0000FFBF, 1,  		I40E_QTX_CTL(1) - I40E_QTX_CTL(0)}, @@ -78,27 +78,28 @@ int i40e_diag_reg_test(struct i40e_hw *hw)  {  	int ret_code = 0;  	u32 reg, mask; +	u32 elements;  	u32 i, j;  	for (i = 0; i40e_reg_list[i].offset != 0 &&  					     !ret_code; i++) { +		elements = i40e_reg_list[i].elements;  		/* set actual reg range for dynamically allocated resources */  		if (i40e_reg_list[i].offset == I40E_QTX_CTL(0) &&  		    hw->func_caps.num_tx_qp != 0) -			i40e_reg_list[i].elements = hw->func_caps.num_tx_qp; +			elements = hw->func_caps.num_tx_qp;  		if ((i40e_reg_list[i].offset == I40E_PFINT_ITRN(0, 0) ||  		     i40e_reg_list[i].offset == I40E_PFINT_ITRN(1, 0) ||  		     i40e_reg_list[i].offset == I40E_PFINT_ITRN(2, 0) ||  		     i40e_reg_list[i].offset == I40E_QINT_TQCTL(0) ||  		     i40e_reg_list[i].offset == I40E_QINT_RQCTL(0)) &&  		    hw->func_caps.num_msix_vectors != 0) -			i40e_reg_list[i].elements = -				hw->func_caps.num_msix_vectors - 1; +			elements = hw->func_caps.num_msix_vectors - 1;  		/* test register access */  		mask = i40e_reg_list[i].mask; -		for (j = 0; j < i40e_reg_list[i].elements && !ret_code; j++) { +		for (j = 0; j < elements && !ret_code; j++) {  			reg = i40e_reg_list[i].offset +  			      (j * i40e_reg_list[i].stride);  			ret_code = i40e_diag_reg_pattern_test(hw, reg, mask); diff --git a/drivers/net/ethernet/intel/i40e/i40e_diag.h b/drivers/net/ethernet/intel/i40e/i40e_diag.h index e641035c7297..c3ce5f35211f 100644 --- a/drivers/net/ethernet/intel/i40e/i40e_diag.h +++ b/drivers/net/ethernet/intel/i40e/i40e_diag.h @@ -20,7 +20,7 @@ struct i40e_diag_reg_test_info {  	u32 stride;	/* bytes between each element */  }; -extern struct i40e_diag_reg_test_info i40e_reg_list[]; +extern const struct i40e_diag_reg_test_info i40e_reg_list[];  int i40e_diag_reg_test(struct i40e_hw *hw);  int i40e_diag_eeprom_test(struct i40e_hw *hw); diff --git a/drivers/net/ethernet/intel/i40e/i40e_ethtool.c b/drivers/net/ethernet/intel/i40e/i40e_ethtool.c index 4934ff58332c..afc4fa8c66af 100644 --- a/drivers/net/ethernet/intel/i40e/i40e_ethtool.c +++ b/drivers/net/ethernet/intel/i40e/i40e_ethtool.c @@ -5402,6 +5402,13 @@ flags_complete:  		return -EOPNOTSUPP;  	} +	if ((changed_flags & I40E_FLAG_LEGACY_RX) && +	    I40E_2K_TOO_SMALL_WITH_PADDING) { +		dev_warn(&pf->pdev->dev, +			 "2k Rx buffer is too small to fit standard MTU and skb_shared_info\n"); +		return -EOPNOTSUPP; +	} +  	if ((changed_flags & new_flags &  	     I40E_FLAG_LINK_DOWN_ON_CLOSE_ENABLED) &&  	    (new_flags & I40E_FLAG_MFP_ENABLED)) diff --git a/drivers/net/ethernet/intel/i40e/i40e_main.c b/drivers/net/ethernet/intel/i40e/i40e_main.c index 467001db5070..b847bd105b16 100644 --- a/drivers/net/ethernet/intel/i40e/i40e_main.c +++ b/drivers/net/ethernet/intel/i40e/i40e_main.c @@ -2896,15 +2896,35 @@ static void i40e_sync_filters_subtask(struct i40e_pf *pf)  }  /** - * i40e_max_xdp_frame_size - returns the maximum allowed frame size for XDP + * i40e_calculate_vsi_rx_buf_len - Calculates buffer length + * + * @vsi: VSI to calculate rx_buf_len from + */ +static u16 i40e_calculate_vsi_rx_buf_len(struct i40e_vsi *vsi) +{ +	if (!vsi->netdev || (vsi->back->flags & I40E_FLAG_LEGACY_RX)) +		return SKB_WITH_OVERHEAD(I40E_RXBUFFER_2048); + +	return PAGE_SIZE < 8192 ? I40E_RXBUFFER_3072 : I40E_RXBUFFER_2048; +} + +/** + * i40e_max_vsi_frame_size - returns the maximum allowed frame size for VSI   * @vsi: the vsi + * @xdp_prog: XDP program   **/ -static int i40e_max_xdp_frame_size(struct i40e_vsi *vsi) +static int i40e_max_vsi_frame_size(struct i40e_vsi *vsi, +				   struct bpf_prog *xdp_prog)  { -	if (PAGE_SIZE >= 8192 || (vsi->back->flags & I40E_FLAG_LEGACY_RX)) -		return I40E_RXBUFFER_2048; +	u16 rx_buf_len = i40e_calculate_vsi_rx_buf_len(vsi); +	u16 chain_len; + +	if (xdp_prog && !xdp_prog->aux->xdp_has_frags) +		chain_len = 1;  	else -		return I40E_RXBUFFER_3072; +		chain_len = I40E_MAX_CHAINED_RX_BUFFERS; + +	return min_t(u16, rx_buf_len * chain_len, I40E_MAX_RXBUFFER);  }  /** @@ -2919,12 +2939,13 @@ static int i40e_change_mtu(struct net_device *netdev, int new_mtu)  	struct i40e_netdev_priv *np = netdev_priv(netdev);  	struct i40e_vsi *vsi = np->vsi;  	struct i40e_pf *pf = vsi->back; +	int frame_size; -	if (i40e_enabled_xdp_vsi(vsi)) { -		int frame_size = new_mtu + I40E_PACKET_HDR_PAD; - -		if (frame_size > i40e_max_xdp_frame_size(vsi)) -			return -EINVAL; +	frame_size = i40e_max_vsi_frame_size(vsi, vsi->xdp_prog); +	if (new_mtu > frame_size - I40E_PACKET_HDR_PAD) { +		netdev_err(netdev, "Error changing mtu to %d, Max is %d\n", +			   new_mtu, frame_size - I40E_PACKET_HDR_PAD); +		return -EINVAL;  	}  	netdev_dbg(netdev, "changing MTU from %d to %d\n", @@ -3595,6 +3616,8 @@ static int i40e_configure_rx_ring(struct i40e_ring *ring)  		}  	} +	xdp_init_buff(&ring->xdp, i40e_rx_pg_size(ring) / 2, &ring->xdp_rxq); +  	rx_ctx.dbuff = DIV_ROUND_UP(ring->rx_buf_len,  				    BIT_ULL(I40E_RXQ_CTX_DBUFF_SHIFT)); @@ -3640,10 +3663,16 @@ static int i40e_configure_rx_ring(struct i40e_ring *ring)  	}  	/* configure Rx buffer alignment */ -	if (!vsi->netdev || (vsi->back->flags & I40E_FLAG_LEGACY_RX)) +	if (!vsi->netdev || (vsi->back->flags & I40E_FLAG_LEGACY_RX)) { +		if (I40E_2K_TOO_SMALL_WITH_PADDING) { +			dev_info(&vsi->back->pdev->dev, +				 "2k Rx buffer is too small to fit standard MTU and skb_shared_info\n"); +			return -EOPNOTSUPP; +		}  		clear_ring_build_skb_enabled(ring); -	else +	} else {  		set_ring_build_skb_enabled(ring); +	}  	ring->rx_offset = i40e_rx_offset(ring); @@ -3694,24 +3723,6 @@ static int i40e_vsi_configure_tx(struct i40e_vsi *vsi)  }  /** - * i40e_calculate_vsi_rx_buf_len - Calculates buffer length - * - * @vsi: VSI to calculate rx_buf_len from - */ -static u16 i40e_calculate_vsi_rx_buf_len(struct i40e_vsi *vsi) -{ -	if (!vsi->netdev || (vsi->back->flags & I40E_FLAG_LEGACY_RX)) -		return I40E_RXBUFFER_2048; - -#if (PAGE_SIZE < 8192) -	if (!I40E_2K_TOO_SMALL_WITH_PADDING && vsi->netdev->mtu <= ETH_DATA_LEN) -		return I40E_RXBUFFER_1536 - NET_IP_ALIGN; -#endif - -	return PAGE_SIZE < 8192 ? I40E_RXBUFFER_3072 : I40E_RXBUFFER_2048; -} - -/**   * i40e_vsi_configure_rx - Configure the VSI for Rx   * @vsi: the VSI being configured   * @@ -3722,13 +3733,15 @@ static int i40e_vsi_configure_rx(struct i40e_vsi *vsi)  	int err = 0;  	u16 i; -	vsi->max_frame = I40E_MAX_RXBUFFER; +	vsi->max_frame = i40e_max_vsi_frame_size(vsi, vsi->xdp_prog);  	vsi->rx_buf_len = i40e_calculate_vsi_rx_buf_len(vsi);  #if (PAGE_SIZE < 8192)  	if (vsi->netdev && !I40E_2K_TOO_SMALL_WITH_PADDING && -	    vsi->netdev->mtu <= ETH_DATA_LEN) -		vsi->max_frame = I40E_RXBUFFER_1536 - NET_IP_ALIGN; +	    vsi->netdev->mtu <= ETH_DATA_LEN) { +		vsi->rx_buf_len = I40E_RXBUFFER_1536 - NET_IP_ALIGN; +		vsi->max_frame = vsi->rx_buf_len; +	}  #endif  	/* set up individual rings */ @@ -11059,8 +11072,11 @@ static void i40e_rebuild(struct i40e_pf *pf, bool reinit, bool lock_acquired)  					     pf->hw.aq.asq_last_status));  	}  	/* reinit the misc interrupt */ -	if (pf->flags & I40E_FLAG_MSIX_ENABLED) +	if (pf->flags & I40E_FLAG_MSIX_ENABLED) {  		ret = i40e_setup_misc_vector(pf); +		if (ret) +			goto end_unlock; +	}  	/* Add a filter to drop all Flow control frames from any VSI from being  	 * transmitted. By doing so we stop a malicious VF from sending out @@ -13316,15 +13332,15 @@ out_err:  static int i40e_xdp_setup(struct i40e_vsi *vsi, struct bpf_prog *prog,  			  struct netlink_ext_ack *extack)  { -	int frame_size = vsi->netdev->mtu + ETH_HLEN + ETH_FCS_LEN + VLAN_HLEN; +	int frame_size = i40e_max_vsi_frame_size(vsi, prog);  	struct i40e_pf *pf = vsi->back;  	struct bpf_prog *old_prog;  	bool need_reset;  	int i;  	/* Don't allow frames that span over multiple buffers */ -	if (frame_size > i40e_calculate_vsi_rx_buf_len(vsi)) { -		NL_SET_ERR_MSG_MOD(extack, "MTU too large to enable XDP"); +	if (vsi->netdev->mtu > frame_size - I40E_PACKET_HDR_PAD) { +		NL_SET_ERR_MSG_MOD(extack, "MTU too large for linear frames and XDP prog does not support frags");  		return -EINVAL;  	} @@ -13810,7 +13826,8 @@ static int i40e_config_netdev(struct i40e_vsi *vsi)  		netdev->xdp_features = NETDEV_XDP_ACT_BASIC |  				       NETDEV_XDP_ACT_REDIRECT | -				       NETDEV_XDP_ACT_XSK_ZEROCOPY; +				       NETDEV_XDP_ACT_XSK_ZEROCOPY | +				       NETDEV_XDP_ACT_RX_SG;  	} else {  		/* Relate the VSI_VMDQ name to the VSI_MAIN name. Note that we  		 * are still limited by IFNAMSIZ, but we're adding 'v%d\0' to @@ -14133,15 +14150,15 @@ static int i40e_add_vsi(struct i40e_vsi *vsi)  		vsi->id = ctxt.vsi_number;  	} -	vsi->active_filters = 0; -	clear_bit(__I40E_VSI_OVERFLOW_PROMISC, vsi->state);  	spin_lock_bh(&vsi->mac_filter_hash_lock); +	vsi->active_filters = 0;  	/* If macvlan filters already exist, force them to get loaded */  	hash_for_each_safe(vsi->mac_filter_hash, bkt, h, f, hlist) {  		f->state = I40E_FILTER_NEW;  		f_count++;  	}  	spin_unlock_bh(&vsi->mac_filter_hash_lock); +	clear_bit(__I40E_VSI_OVERFLOW_PROMISC, vsi->state);  	if (f_count) {  		vsi->flags |= I40E_VSI_FLAG_FILTER_CHANGED; @@ -15525,6 +15542,7 @@ static int i40e_init_recovery_mode(struct i40e_pf *pf, struct i40e_hw *hw)  	int err;  	int v_idx; +	pci_set_drvdata(pf->pdev, pf);  	pci_save_state(pf->pdev);  	/* set up periodic task facility */ diff --git a/drivers/net/ethernet/intel/i40e/i40e_trace.h b/drivers/net/ethernet/intel/i40e/i40e_trace.h index 79d587ad5409..33b4e30f5e00 100644 --- a/drivers/net/ethernet/intel/i40e/i40e_trace.h +++ b/drivers/net/ethernet/intel/i40e/i40e_trace.h @@ -162,45 +162,45 @@ DECLARE_EVENT_CLASS(  	TP_PROTO(struct i40e_ring *ring,  		 union i40e_16byte_rx_desc *desc, -		 struct sk_buff *skb), +		 struct xdp_buff *xdp), -	TP_ARGS(ring, desc, skb), +	TP_ARGS(ring, desc, xdp),  	TP_STRUCT__entry(  		__field(void*, ring)  		__field(void*, desc) -		__field(void*, skb) +		__field(void*, xdp)  		__string(devname, ring->netdev->name)  	),  	TP_fast_assign(  		__entry->ring = ring;  		__entry->desc = desc; -		__entry->skb = skb; +		__entry->xdp = xdp;  		__assign_str(devname, ring->netdev->name);  	),  	TP_printk( -		"netdev: %s ring: %p desc: %p skb %p", +		"netdev: %s ring: %p desc: %p xdp %p",  		__get_str(devname), __entry->ring, -		__entry->desc, __entry->skb) +		__entry->desc, __entry->xdp)  );  DEFINE_EVENT(  	i40e_rx_template, i40e_clean_rx_irq,  	TP_PROTO(struct i40e_ring *ring,  		 union i40e_16byte_rx_desc *desc, -		 struct sk_buff *skb), +		 struct xdp_buff *xdp), -	TP_ARGS(ring, desc, skb)); +	TP_ARGS(ring, desc, xdp));  DEFINE_EVENT(  	i40e_rx_template, i40e_clean_rx_irq_rx,  	TP_PROTO(struct i40e_ring *ring,  		 union i40e_16byte_rx_desc *desc, -		 struct sk_buff *skb), +		 struct xdp_buff *xdp), -	TP_ARGS(ring, desc, skb)); +	TP_ARGS(ring, desc, xdp));  DECLARE_EVENT_CLASS(  	i40e_xmit_template, diff --git a/drivers/net/ethernet/intel/i40e/i40e_txrx.c b/drivers/net/ethernet/intel/i40e/i40e_txrx.c index 924f972b91fa..8b8bf4880faa 100644 --- a/drivers/net/ethernet/intel/i40e/i40e_txrx.c +++ b/drivers/net/ethernet/intel/i40e/i40e_txrx.c @@ -171,10 +171,10 @@ static char *i40e_create_dummy_packet(u8 *dummy_packet, bool ipv4, u8 l4proto,  				      struct i40e_fdir_filter *data)  {  	bool is_vlan = !!data->vlan_tag; -	struct vlan_hdr vlan; -	struct ipv6hdr ipv6; -	struct ethhdr eth; -	struct iphdr ip; +	struct vlan_hdr vlan = {}; +	struct ipv6hdr ipv6 = {}; +	struct ethhdr eth = {}; +	struct iphdr ip = {};  	u8 *tmp;  	if (ipv4) { @@ -1477,9 +1477,6 @@ void i40e_clean_rx_ring(struct i40e_ring *rx_ring)  	if (!rx_ring->rx_bi)  		return; -	dev_kfree_skb(rx_ring->skb); -	rx_ring->skb = NULL; -  	if (rx_ring->xsk_pool) {  		i40e_xsk_clean_rx_ring(rx_ring);  		goto skip_free; @@ -1524,6 +1521,7 @@ skip_free:  	rx_ring->next_to_alloc = 0;  	rx_ring->next_to_clean = 0; +	rx_ring->next_to_process = 0;  	rx_ring->next_to_use = 0;  } @@ -1576,6 +1574,7 @@ int i40e_setup_rx_descriptors(struct i40e_ring *rx_ring)  	rx_ring->next_to_alloc = 0;  	rx_ring->next_to_clean = 0; +	rx_ring->next_to_process = 0;  	rx_ring->next_to_use = 0;  	/* XDP RX-queue info only needed for RX rings exposed to XDP */ @@ -1617,21 +1616,19 @@ void i40e_release_rx_desc(struct i40e_ring *rx_ring, u32 val)  	writel(val, rx_ring->tail);  } +#if (PAGE_SIZE >= 8192)  static unsigned int i40e_rx_frame_truesize(struct i40e_ring *rx_ring,  					   unsigned int size)  {  	unsigned int truesize; -#if (PAGE_SIZE < 8192) -	truesize = i40e_rx_pg_size(rx_ring) / 2; /* Must be power-of-2 */ -#else  	truesize = rx_ring->rx_offset ?  		SKB_DATA_ALIGN(size + rx_ring->rx_offset) +  		SKB_DATA_ALIGN(sizeof(struct skb_shared_info)) :  		SKB_DATA_ALIGN(size); -#endif  	return truesize;  } +#endif  /**   * i40e_alloc_mapped_page - recycle or make a new page @@ -1970,7 +1967,6 @@ static bool i40e_cleanup_headers(struct i40e_ring *rx_ring, struct sk_buff *skb,   * i40e_can_reuse_rx_page - Determine if page can be reused for another Rx   * @rx_buffer: buffer containing the page   * @rx_stats: rx stats structure for the rx ring - * @rx_buffer_pgcnt: buffer page refcount pre xdp_do_redirect() call   *   * If page is reusable, we have a green light for calling i40e_reuse_rx_page,   * which will assign the current buffer to the buffer that next_to_alloc is @@ -1981,8 +1977,7 @@ static bool i40e_cleanup_headers(struct i40e_ring *rx_ring, struct sk_buff *skb,   * or busy if it could not be reused.   */  static bool i40e_can_reuse_rx_page(struct i40e_rx_buffer *rx_buffer, -				   struct i40e_rx_queue_stats *rx_stats, -				   int rx_buffer_pgcnt) +				   struct i40e_rx_queue_stats *rx_stats)  {  	unsigned int pagecnt_bias = rx_buffer->pagecnt_bias;  	struct page *page = rx_buffer->page; @@ -1995,7 +1990,7 @@ static bool i40e_can_reuse_rx_page(struct i40e_rx_buffer *rx_buffer,  #if (PAGE_SIZE < 8192)  	/* if we are only owner of page we can reuse it */ -	if (unlikely((rx_buffer_pgcnt - pagecnt_bias) > 1)) { +	if (unlikely((rx_buffer->page_count - pagecnt_bias) > 1)) {  		rx_stats->page_busy_count++;  		return false;  	} @@ -2021,33 +2016,14 @@ static bool i40e_can_reuse_rx_page(struct i40e_rx_buffer *rx_buffer,  }  /** - * i40e_add_rx_frag - Add contents of Rx buffer to sk_buff - * @rx_ring: rx descriptor ring to transact packets on - * @rx_buffer: buffer containing page to add - * @skb: sk_buff to place the data into - * @size: packet length from rx_desc - * - * This function will add the data contained in rx_buffer->page to the skb. - * It will just attach the page as a frag to the skb. - * - * The function will then update the page offset. + * i40e_rx_buffer_flip - adjusted rx_buffer to point to an unused region + * @rx_buffer: Rx buffer to adjust + * @truesize: Size of adjustment   **/ -static void i40e_add_rx_frag(struct i40e_ring *rx_ring, -			     struct i40e_rx_buffer *rx_buffer, -			     struct sk_buff *skb, -			     unsigned int size) +static void i40e_rx_buffer_flip(struct i40e_rx_buffer *rx_buffer, +				unsigned int truesize)  {  #if (PAGE_SIZE < 8192) -	unsigned int truesize = i40e_rx_pg_size(rx_ring) / 2; -#else -	unsigned int truesize = SKB_DATA_ALIGN(size + rx_ring->rx_offset); -#endif - -	skb_add_rx_frag(skb, skb_shinfo(skb)->nr_frags, rx_buffer->page, -			rx_buffer->page_offset, size, truesize); - -	/* page is being used so we must update the page offset */ -#if (PAGE_SIZE < 8192)  	rx_buffer->page_offset ^= truesize;  #else  	rx_buffer->page_offset += truesize; @@ -2058,19 +2034,17 @@ static void i40e_add_rx_frag(struct i40e_ring *rx_ring,   * i40e_get_rx_buffer - Fetch Rx buffer and synchronize data for use   * @rx_ring: rx descriptor ring to transact packets on   * @size: size of buffer to add to skb - * @rx_buffer_pgcnt: buffer page refcount   *   * This function will pull an Rx buffer from the ring and synchronize it   * for use by the CPU.   */  static struct i40e_rx_buffer *i40e_get_rx_buffer(struct i40e_ring *rx_ring, -						 const unsigned int size, -						 int *rx_buffer_pgcnt) +						 const unsigned int size)  {  	struct i40e_rx_buffer *rx_buffer; -	rx_buffer = i40e_rx_bi(rx_ring, rx_ring->next_to_clean); -	*rx_buffer_pgcnt = +	rx_buffer = i40e_rx_bi(rx_ring, rx_ring->next_to_process); +	rx_buffer->page_count =  #if (PAGE_SIZE < 8192)  		page_count(rx_buffer->page);  #else @@ -2092,25 +2066,82 @@ static struct i40e_rx_buffer *i40e_get_rx_buffer(struct i40e_ring *rx_ring,  }  /** - * i40e_construct_skb - Allocate skb and populate it + * i40e_put_rx_buffer - Clean up used buffer and either recycle or free   * @rx_ring: rx descriptor ring to transact packets on   * @rx_buffer: rx buffer to pull data from + * + * This function will clean up the contents of the rx_buffer.  It will + * either recycle the buffer or unmap it and free the associated resources. + */ +static void i40e_put_rx_buffer(struct i40e_ring *rx_ring, +			       struct i40e_rx_buffer *rx_buffer) +{ +	if (i40e_can_reuse_rx_page(rx_buffer, &rx_ring->rx_stats)) { +		/* hand second half of page back to the ring */ +		i40e_reuse_rx_page(rx_ring, rx_buffer); +	} else { +		/* we are not reusing the buffer so unmap it */ +		dma_unmap_page_attrs(rx_ring->dev, rx_buffer->dma, +				     i40e_rx_pg_size(rx_ring), +				     DMA_FROM_DEVICE, I40E_RX_DMA_ATTR); +		__page_frag_cache_drain(rx_buffer->page, +					rx_buffer->pagecnt_bias); +		/* clear contents of buffer_info */ +		rx_buffer->page = NULL; +	} +} + +/** + * i40e_process_rx_buffs- Processing of buffers post XDP prog or on error + * @rx_ring: Rx descriptor ring to transact packets on + * @xdp_res: Result of the XDP program + * @xdp: xdp_buff pointing to the data + **/ +static void i40e_process_rx_buffs(struct i40e_ring *rx_ring, int xdp_res, +				  struct xdp_buff *xdp) +{ +	u32 next = rx_ring->next_to_clean; +	struct i40e_rx_buffer *rx_buffer; + +	xdp->flags = 0; + +	while (1) { +		rx_buffer = i40e_rx_bi(rx_ring, next); +		if (++next == rx_ring->count) +			next = 0; + +		if (!rx_buffer->page) +			continue; + +		if (xdp_res == I40E_XDP_CONSUMED) +			rx_buffer->pagecnt_bias++; +		else +			i40e_rx_buffer_flip(rx_buffer, xdp->frame_sz); + +		/* EOP buffer will be put in i40e_clean_rx_irq() */ +		if (next == rx_ring->next_to_process) +			return; + +		i40e_put_rx_buffer(rx_ring, rx_buffer); +	} +} + +/** + * i40e_construct_skb - Allocate skb and populate it + * @rx_ring: rx descriptor ring to transact packets on   * @xdp: xdp_buff pointing to the data + * @nr_frags: number of buffers for the packet   *   * This function allocates an skb.  It then populates it with the page   * data from the current receive descriptor, taking care to set up the   * skb correctly.   */  static struct sk_buff *i40e_construct_skb(struct i40e_ring *rx_ring, -					  struct i40e_rx_buffer *rx_buffer, -					  struct xdp_buff *xdp) +					  struct xdp_buff *xdp, +					  u32 nr_frags)  {  	unsigned int size = xdp->data_end - xdp->data; -#if (PAGE_SIZE < 8192) -	unsigned int truesize = i40e_rx_pg_size(rx_ring) / 2; -#else -	unsigned int truesize = SKB_DATA_ALIGN(size); -#endif +	struct i40e_rx_buffer *rx_buffer;  	unsigned int headlen;  	struct sk_buff *skb; @@ -2150,48 +2181,60 @@ static struct sk_buff *i40e_construct_skb(struct i40e_ring *rx_ring,  	memcpy(__skb_put(skb, headlen), xdp->data,  	       ALIGN(headlen, sizeof(long))); +	rx_buffer = i40e_rx_bi(rx_ring, rx_ring->next_to_clean);  	/* update all of the pointers */  	size -= headlen;  	if (size) { +		if (unlikely(nr_frags >= MAX_SKB_FRAGS)) { +			dev_kfree_skb(skb); +			return NULL; +		}  		skb_add_rx_frag(skb, 0, rx_buffer->page,  				rx_buffer->page_offset + headlen, -				size, truesize); - +				size, xdp->frame_sz);  		/* buffer is used by skb, update page_offset */ -#if (PAGE_SIZE < 8192) -		rx_buffer->page_offset ^= truesize; -#else -		rx_buffer->page_offset += truesize; -#endif +		i40e_rx_buffer_flip(rx_buffer, xdp->frame_sz);  	} else {  		/* buffer is unused, reset bias back to rx_buffer */  		rx_buffer->pagecnt_bias++;  	} +	if (unlikely(xdp_buff_has_frags(xdp))) { +		struct skb_shared_info *sinfo, *skinfo = skb_shinfo(skb); + +		sinfo = xdp_get_shared_info_from_buff(xdp); +		memcpy(&skinfo->frags[skinfo->nr_frags], &sinfo->frags[0], +		       sizeof(skb_frag_t) * nr_frags); + +		xdp_update_skb_shared_info(skb, skinfo->nr_frags + nr_frags, +					   sinfo->xdp_frags_size, +					   nr_frags * xdp->frame_sz, +					   xdp_buff_is_frag_pfmemalloc(xdp)); + +		/* First buffer has already been processed, so bump ntc */ +		if (++rx_ring->next_to_clean == rx_ring->count) +			rx_ring->next_to_clean = 0; + +		i40e_process_rx_buffs(rx_ring, I40E_XDP_PASS, xdp); +	} +  	return skb;  }  /**   * i40e_build_skb - Build skb around an existing buffer   * @rx_ring: Rx descriptor ring to transact packets on - * @rx_buffer: Rx buffer to pull data from   * @xdp: xdp_buff pointing to the data + * @nr_frags: number of buffers for the packet   *   * This function builds an skb around an existing Rx buffer, taking care   * to set up the skb correctly and avoid any memcpy overhead.   */  static struct sk_buff *i40e_build_skb(struct i40e_ring *rx_ring, -				      struct i40e_rx_buffer *rx_buffer, -				      struct xdp_buff *xdp) +				      struct xdp_buff *xdp, +				      u32 nr_frags)  {  	unsigned int metasize = xdp->data - xdp->data_meta; -#if (PAGE_SIZE < 8192) -	unsigned int truesize = i40e_rx_pg_size(rx_ring) / 2; -#else -	unsigned int truesize = SKB_DATA_ALIGN(sizeof(struct skb_shared_info)) + -				SKB_DATA_ALIGN(xdp->data_end - -					       xdp->data_hard_start); -#endif  	struct sk_buff *skb;  	/* Prefetch first cache line of first page. If xdp->data_meta @@ -2202,7 +2245,7 @@ static struct sk_buff *i40e_build_skb(struct i40e_ring *rx_ring,  	net_prefetch(xdp->data_meta);  	/* build an skb around the page buffer */ -	skb = napi_build_skb(xdp->data_hard_start, truesize); +	skb = napi_build_skb(xdp->data_hard_start, xdp->frame_sz);  	if (unlikely(!skb))  		return NULL; @@ -2212,42 +2255,25 @@ static struct sk_buff *i40e_build_skb(struct i40e_ring *rx_ring,  	if (metasize)  		skb_metadata_set(skb, metasize); -	/* buffer is used by skb, update page_offset */ -#if (PAGE_SIZE < 8192) -	rx_buffer->page_offset ^= truesize; -#else -	rx_buffer->page_offset += truesize; -#endif +	if (unlikely(xdp_buff_has_frags(xdp))) { +		struct skb_shared_info *sinfo; -	return skb; -} +		sinfo = xdp_get_shared_info_from_buff(xdp); +		xdp_update_skb_shared_info(skb, nr_frags, +					   sinfo->xdp_frags_size, +					   nr_frags * xdp->frame_sz, +					   xdp_buff_is_frag_pfmemalloc(xdp)); -/** - * i40e_put_rx_buffer - Clean up used buffer and either recycle or free - * @rx_ring: rx descriptor ring to transact packets on - * @rx_buffer: rx buffer to pull data from - * @rx_buffer_pgcnt: rx buffer page refcount pre xdp_do_redirect() call - * - * This function will clean up the contents of the rx_buffer.  It will - * either recycle the buffer or unmap it and free the associated resources. - */ -static void i40e_put_rx_buffer(struct i40e_ring *rx_ring, -			       struct i40e_rx_buffer *rx_buffer, -			       int rx_buffer_pgcnt) -{ -	if (i40e_can_reuse_rx_page(rx_buffer, &rx_ring->rx_stats, rx_buffer_pgcnt)) { -		/* hand second half of page back to the ring */ -		i40e_reuse_rx_page(rx_ring, rx_buffer); +		i40e_process_rx_buffs(rx_ring, I40E_XDP_PASS, xdp);  	} else { -		/* we are not reusing the buffer so unmap it */ -		dma_unmap_page_attrs(rx_ring->dev, rx_buffer->dma, -				     i40e_rx_pg_size(rx_ring), -				     DMA_FROM_DEVICE, I40E_RX_DMA_ATTR); -		__page_frag_cache_drain(rx_buffer->page, -					rx_buffer->pagecnt_bias); -		/* clear contents of buffer_info */ -		rx_buffer->page = NULL; +		struct i40e_rx_buffer *rx_buffer; + +		rx_buffer = i40e_rx_bi(rx_ring, rx_ring->next_to_clean); +		/* buffer is used by skb, update page_offset */ +		i40e_rx_buffer_flip(rx_buffer, xdp->frame_sz);  	} + +	return skb;  }  /** @@ -2333,25 +2359,6 @@ xdp_out:  }  /** - * i40e_rx_buffer_flip - adjusted rx_buffer to point to an unused region - * @rx_ring: Rx ring - * @rx_buffer: Rx buffer to adjust - * @size: Size of adjustment - **/ -static void i40e_rx_buffer_flip(struct i40e_ring *rx_ring, -				struct i40e_rx_buffer *rx_buffer, -				unsigned int size) -{ -	unsigned int truesize = i40e_rx_frame_truesize(rx_ring, size); - -#if (PAGE_SIZE < 8192) -	rx_buffer->page_offset ^= truesize; -#else -	rx_buffer->page_offset += truesize; -#endif -} - -/**   * i40e_xdp_ring_update_tail - Updates the XDP Tx ring tail register   * @xdp_ring: XDP Tx ring   * @@ -2409,16 +2416,65 @@ void i40e_finalize_xdp_rx(struct i40e_ring *rx_ring, unsigned int xdp_res)  }  /** - * i40e_inc_ntc: Advance the next_to_clean index + * i40e_inc_ntp: Advance the next_to_process index   * @rx_ring: Rx ring   **/ -static void i40e_inc_ntc(struct i40e_ring *rx_ring) +static void i40e_inc_ntp(struct i40e_ring *rx_ring) +{ +	u32 ntp = rx_ring->next_to_process + 1; + +	ntp = (ntp < rx_ring->count) ? ntp : 0; +	rx_ring->next_to_process = ntp; +	prefetch(I40E_RX_DESC(rx_ring, ntp)); +} + +/** + * i40e_add_xdp_frag: Add a frag to xdp_buff + * @xdp: xdp_buff pointing to the data + * @nr_frags: return number of buffers for the packet + * @rx_buffer: rx_buffer holding data of the current frag + * @size: size of data of current frag + */ +static int i40e_add_xdp_frag(struct xdp_buff *xdp, u32 *nr_frags, +			     struct i40e_rx_buffer *rx_buffer, u32 size)  { -	u32 ntc = rx_ring->next_to_clean + 1; +	struct skb_shared_info *sinfo = xdp_get_shared_info_from_buff(xdp); + +	if (!xdp_buff_has_frags(xdp)) { +		sinfo->nr_frags = 0; +		sinfo->xdp_frags_size = 0; +		xdp_buff_set_frags_flag(xdp); +	} else if (unlikely(sinfo->nr_frags >= MAX_SKB_FRAGS)) { +		/* Overflowing packet: All frags need to be dropped */ +		return -ENOMEM; +	} + +	__skb_fill_page_desc_noacc(sinfo, sinfo->nr_frags++, rx_buffer->page, +				   rx_buffer->page_offset, size); + +	sinfo->xdp_frags_size += size; -	ntc = (ntc < rx_ring->count) ? ntc : 0; -	rx_ring->next_to_clean = ntc; -	prefetch(I40E_RX_DESC(rx_ring, ntc)); +	if (page_is_pfmemalloc(rx_buffer->page)) +		xdp_buff_set_frag_pfmemalloc(xdp); +	*nr_frags = sinfo->nr_frags; + +	return 0; +} + +/** + * i40e_consume_xdp_buff - Consume all the buffers of the packet and update ntc + * @rx_ring: rx descriptor ring to transact packets on + * @xdp: xdp_buff pointing to the data + * @rx_buffer: rx_buffer of eop desc + */ +static void i40e_consume_xdp_buff(struct i40e_ring *rx_ring, +				  struct xdp_buff *xdp, +				  struct i40e_rx_buffer *rx_buffer) +{ +	i40e_process_rx_buffs(rx_ring, I40E_XDP_CONSUMED, xdp); +	i40e_put_rx_buffer(rx_ring, rx_buffer); +	rx_ring->next_to_clean = rx_ring->next_to_process; +	xdp->data = NULL;  }  /** @@ -2437,38 +2493,36 @@ static void i40e_inc_ntc(struct i40e_ring *rx_ring)  static int i40e_clean_rx_irq(struct i40e_ring *rx_ring, int budget,  			     unsigned int *rx_cleaned)  { -	unsigned int total_rx_bytes = 0, total_rx_packets = 0, frame_sz = 0; +	unsigned int total_rx_bytes = 0, total_rx_packets = 0;  	u16 cleaned_count = I40E_DESC_UNUSED(rx_ring); +	u16 clean_threshold = rx_ring->count / 2;  	unsigned int offset = rx_ring->rx_offset; -	struct sk_buff *skb = rx_ring->skb; +	struct xdp_buff *xdp = &rx_ring->xdp;  	unsigned int xdp_xmit = 0;  	struct bpf_prog *xdp_prog;  	bool failure = false; -	struct xdp_buff xdp;  	int xdp_res = 0; -#if (PAGE_SIZE < 8192) -	frame_sz = i40e_rx_frame_truesize(rx_ring, 0); -#endif -	xdp_init_buff(&xdp, frame_sz, &rx_ring->xdp_rxq); -  	xdp_prog = READ_ONCE(rx_ring->xdp_prog);  	while (likely(total_rx_packets < (unsigned int)budget)) { +		u16 ntp = rx_ring->next_to_process;  		struct i40e_rx_buffer *rx_buffer;  		union i40e_rx_desc *rx_desc; -		int rx_buffer_pgcnt; +		struct sk_buff *skb;  		unsigned int size; +		u32 nfrags = 0; +		bool neop;  		u64 qword;  		/* return some buffers to hardware, one at a time is too slow */ -		if (cleaned_count >= I40E_RX_BUFFER_WRITE) { +		if (cleaned_count >= clean_threshold) {  			failure = failure ||  				  i40e_alloc_rx_buffers(rx_ring, cleaned_count);  			cleaned_count = 0;  		} -		rx_desc = I40E_RX_DESC(rx_ring, rx_ring->next_to_clean); +		rx_desc = I40E_RX_DESC(rx_ring, ntp);  		/* status_error_len will always be zero for unused descriptors  		 * because it's cleared in cleanup, and overlaps with hdr_addr @@ -2487,8 +2541,8 @@ static int i40e_clean_rx_irq(struct i40e_ring *rx_ring, int budget,  			i40e_clean_programming_status(rx_ring,  						      rx_desc->raw.qword[0],  						      qword); -			rx_buffer = i40e_rx_bi(rx_ring, rx_ring->next_to_clean); -			i40e_inc_ntc(rx_ring); +			rx_buffer = i40e_rx_bi(rx_ring, ntp); +			i40e_inc_ntp(rx_ring);  			i40e_reuse_rx_page(rx_ring, rx_buffer);  			cleaned_count++;  			continue; @@ -2499,76 +2553,84 @@ static int i40e_clean_rx_irq(struct i40e_ring *rx_ring, int budget,  		if (!size)  			break; -		i40e_trace(clean_rx_irq, rx_ring, rx_desc, skb); -		rx_buffer = i40e_get_rx_buffer(rx_ring, size, &rx_buffer_pgcnt); - +		i40e_trace(clean_rx_irq, rx_ring, rx_desc, xdp);  		/* retrieve a buffer from the ring */ -		if (!skb) { +		rx_buffer = i40e_get_rx_buffer(rx_ring, size); + +		neop = i40e_is_non_eop(rx_ring, rx_desc); +		i40e_inc_ntp(rx_ring); + +		if (!xdp->data) {  			unsigned char *hard_start;  			hard_start = page_address(rx_buffer->page) +  				     rx_buffer->page_offset - offset; -			xdp_prepare_buff(&xdp, hard_start, offset, size, true); -			xdp_buff_clear_frags_flag(&xdp); +			xdp_prepare_buff(xdp, hard_start, offset, size, true);  #if (PAGE_SIZE > 4096)  			/* At larger PAGE_SIZE, frame_sz depend on len size */ -			xdp.frame_sz = i40e_rx_frame_truesize(rx_ring, size); +			xdp->frame_sz = i40e_rx_frame_truesize(rx_ring, size);  #endif -			xdp_res = i40e_run_xdp(rx_ring, &xdp, xdp_prog); +		} else if (i40e_add_xdp_frag(xdp, &nfrags, rx_buffer, size) && +			   !neop) { +			/* Overflowing packet: Drop all frags on EOP */ +			i40e_consume_xdp_buff(rx_ring, xdp, rx_buffer); +			break;  		} +		if (neop) +			continue; + +		xdp_res = i40e_run_xdp(rx_ring, xdp, xdp_prog); +  		if (xdp_res) { -			if (xdp_res & (I40E_XDP_TX | I40E_XDP_REDIR)) { -				xdp_xmit |= xdp_res; -				i40e_rx_buffer_flip(rx_ring, rx_buffer, size); +			xdp_xmit |= xdp_res & (I40E_XDP_TX | I40E_XDP_REDIR); + +			if (unlikely(xdp_buff_has_frags(xdp))) { +				i40e_process_rx_buffs(rx_ring, xdp_res, xdp); +				size = xdp_get_buff_len(xdp); +			} else if (xdp_res & (I40E_XDP_TX | I40E_XDP_REDIR)) { +				i40e_rx_buffer_flip(rx_buffer, xdp->frame_sz);  			} else {  				rx_buffer->pagecnt_bias++;  			}  			total_rx_bytes += size; -			total_rx_packets++; -		} else if (skb) { -			i40e_add_rx_frag(rx_ring, rx_buffer, skb, size); -		} else if (ring_uses_build_skb(rx_ring)) { -			skb = i40e_build_skb(rx_ring, rx_buffer, &xdp);  		} else { -			skb = i40e_construct_skb(rx_ring, rx_buffer, &xdp); -		} +			if (ring_uses_build_skb(rx_ring)) +				skb = i40e_build_skb(rx_ring, xdp, nfrags); +			else +				skb = i40e_construct_skb(rx_ring, xdp, nfrags); + +			/* drop if we failed to retrieve a buffer */ +			if (!skb) { +				rx_ring->rx_stats.alloc_buff_failed++; +				i40e_consume_xdp_buff(rx_ring, xdp, rx_buffer); +				break; +			} -		/* exit if we failed to retrieve a buffer */ -		if (!xdp_res && !skb) { -			rx_ring->rx_stats.alloc_buff_failed++; -			rx_buffer->pagecnt_bias++; -			break; -		} +			if (i40e_cleanup_headers(rx_ring, skb, rx_desc)) +				goto process_next; -		i40e_put_rx_buffer(rx_ring, rx_buffer, rx_buffer_pgcnt); -		cleaned_count++; +			/* probably a little skewed due to removing CRC */ +			total_rx_bytes += skb->len; -		i40e_inc_ntc(rx_ring); -		if (i40e_is_non_eop(rx_ring, rx_desc)) -			continue; +			/* populate checksum, VLAN, and protocol */ +			i40e_process_skb_fields(rx_ring, rx_desc, skb); -		if (xdp_res || i40e_cleanup_headers(rx_ring, skb, rx_desc)) { -			skb = NULL; -			continue; +			i40e_trace(clean_rx_irq_rx, rx_ring, rx_desc, xdp); +			napi_gro_receive(&rx_ring->q_vector->napi, skb);  		} -		/* probably a little skewed due to removing CRC */ -		total_rx_bytes += skb->len; - -		/* populate checksum, VLAN, and protocol */ -		i40e_process_skb_fields(rx_ring, rx_desc, skb); - -		i40e_trace(clean_rx_irq_rx, rx_ring, rx_desc, skb); -		napi_gro_receive(&rx_ring->q_vector->napi, skb); -		skb = NULL; -  		/* update budget accounting */  		total_rx_packets++; +process_next: +		cleaned_count += nfrags + 1; +		i40e_put_rx_buffer(rx_ring, rx_buffer); +		rx_ring->next_to_clean = rx_ring->next_to_process; + +		xdp->data = NULL;  	}  	i40e_finalize_xdp_rx(rx_ring, xdp_xmit); -	rx_ring->skb = skb;  	i40e_update_rx_stats(rx_ring, total_rx_bytes, total_rx_packets); @@ -3001,7 +3063,7 @@ static inline int i40e_tx_prepare_vlan_flags(struct sk_buff *skb,  			rc = skb_cow_head(skb, 0);  			if (rc < 0)  				return rc; -			vhdr = (struct vlan_ethhdr *)skb->data; +			vhdr = skb_vlan_eth_hdr(skb);  			vhdr->h_vlan_TCI = htons(tx_flags >>  						 I40E_TX_FLAGS_VLAN_SHIFT);  		} else { diff --git a/drivers/net/ethernet/intel/i40e/i40e_txrx.h b/drivers/net/ethernet/intel/i40e/i40e_txrx.h index 768290dc6f48..8c3d24012c54 100644 --- a/drivers/net/ethernet/intel/i40e/i40e_txrx.h +++ b/drivers/net/ethernet/intel/i40e/i40e_txrx.h @@ -277,6 +277,7 @@ struct i40e_rx_buffer {  	struct page *page;  	__u32 page_offset;  	__u16 pagecnt_bias; +	__u32 page_count;  };  struct i40e_queue_stats { @@ -336,6 +337,17 @@ struct i40e_ring {  	u8 dcb_tc;			/* Traffic class of ring */  	u8 __iomem *tail; +	/* Storing xdp_buff on ring helps in saving the state of partially built +	 * packet when i40e_clean_rx_ring_irq() must return before it sees EOP +	 * and to resume packet building for this ring in the next call to +	 * i40e_clean_rx_ring_irq(). +	 */ +	struct xdp_buff xdp; + +	/* Next descriptor to be processed; next_to_clean is updated only on +	 * processing EOP descriptor +	 */ +	u16 next_to_process;  	/* high bit set means dynamic, use accessor routines to read/write.  	 * hardware only supports 2us resolution for the ITR registers.  	 * these values always store the USER setting, and must be converted @@ -380,14 +392,6 @@ struct i40e_ring {  	struct rcu_head rcu;		/* to avoid race on free */  	u16 next_to_alloc; -	struct sk_buff *skb;		/* When i40e_clean_rx_ring_irq() must -					 * return before it sees the EOP for -					 * the current packet, we save that skb -					 * here and resume receiving this -					 * packet the next time -					 * i40e_clean_rx_ring_irq() is called -					 * for this ring. -					 */  	struct i40e_channel *ch;  	u16 rx_offset; diff --git a/drivers/net/ethernet/intel/i40e/i40e_virtchnl_pf.c b/drivers/net/ethernet/intel/i40e/i40e_virtchnl_pf.c index 8a4587585acd..be59ba3774e1 100644 --- a/drivers/net/ethernet/intel/i40e/i40e_virtchnl_pf.c +++ b/drivers/net/ethernet/intel/i40e/i40e_virtchnl_pf.c @@ -2915,6 +2915,72 @@ static inline int i40e_check_vf_permission(struct i40e_vf *vf,  }  /** + * i40e_vc_ether_addr_type - get type of virtchnl_ether_addr + * @vc_ether_addr: used to extract the type + **/ +static u8 +i40e_vc_ether_addr_type(struct virtchnl_ether_addr *vc_ether_addr) +{ +	return vc_ether_addr->type & VIRTCHNL_ETHER_ADDR_TYPE_MASK; +} + +/** + * i40e_is_vc_addr_legacy + * @vc_ether_addr: VIRTCHNL structure that contains MAC and type + * + * check if the MAC address is from an older VF + **/ +static bool +i40e_is_vc_addr_legacy(struct virtchnl_ether_addr *vc_ether_addr) +{ +	return i40e_vc_ether_addr_type(vc_ether_addr) == +		VIRTCHNL_ETHER_ADDR_LEGACY; +} + +/** + * i40e_is_vc_addr_primary + * @vc_ether_addr: VIRTCHNL structure that contains MAC and type + * + * check if the MAC address is the VF's primary MAC + * This function should only be called when the MAC address in + * virtchnl_ether_addr is a valid unicast MAC + **/ +static bool +i40e_is_vc_addr_primary(struct virtchnl_ether_addr *vc_ether_addr) +{ +	return i40e_vc_ether_addr_type(vc_ether_addr) == +		VIRTCHNL_ETHER_ADDR_PRIMARY; +} + +/** + * i40e_update_vf_mac_addr + * @vf: VF to update + * @vc_ether_addr: structure from VIRTCHNL with MAC to add + * + * update the VF's cached hardware MAC if allowed + **/ +static void +i40e_update_vf_mac_addr(struct i40e_vf *vf, +			struct virtchnl_ether_addr *vc_ether_addr) +{ +	u8 *mac_addr = vc_ether_addr->addr; + +	if (!is_valid_ether_addr(mac_addr)) +		return; + +	/* If request to add MAC filter is a primary request update its default +	 * MAC address with the requested one. If it is a legacy request then +	 * check if current default is empty if so update the default MAC +	 */ +	if (i40e_is_vc_addr_primary(vc_ether_addr)) { +		ether_addr_copy(vf->default_lan_addr.addr, mac_addr); +	} else if (i40e_is_vc_addr_legacy(vc_ether_addr)) { +		if (is_zero_ether_addr(vf->default_lan_addr.addr)) +			ether_addr_copy(vf->default_lan_addr.addr, mac_addr); +	} +} + +/**   * i40e_vc_add_mac_addr_msg   * @vf: pointer to the VF info   * @msg: pointer to the msg buffer @@ -2965,11 +3031,8 @@ static int i40e_vc_add_mac_addr_msg(struct i40e_vf *vf, u8 *msg)  				spin_unlock_bh(&vsi->mac_filter_hash_lock);  				goto error_param;  			} -			if (is_valid_ether_addr(al->list[i].addr) && -			    is_zero_ether_addr(vf->default_lan_addr.addr)) -				ether_addr_copy(vf->default_lan_addr.addr, -						al->list[i].addr);  		} +		i40e_update_vf_mac_addr(vf, &al->list[i]);  	}  	spin_unlock_bh(&vsi->mac_filter_hash_lock); @@ -3032,6 +3095,9 @@ static int i40e_vc_del_mac_addr_msg(struct i40e_vf *vf, u8 *msg)  	spin_unlock_bh(&vsi->mac_filter_hash_lock); +	if (was_unimac_deleted) +		eth_zero_addr(vf->default_lan_addr.addr); +  	/* program the updated filter list */  	ret = i40e_sync_vsi_filters(vsi);  	if (ret) diff --git a/drivers/net/ethernet/intel/iavf/iavf.h b/drivers/net/ethernet/intel/iavf/iavf.h index 232bc61d9eee..39d0fe76a38f 100644 --- a/drivers/net/ethernet/intel/iavf/iavf.h +++ b/drivers/net/ethernet/intel/iavf/iavf.h @@ -6,7 +6,6 @@  #include <linux/module.h>  #include <linux/pci.h> -#include <linux/aer.h>  #include <linux/netdevice.h>  #include <linux/vmalloc.h>  #include <linux/interrupt.h> @@ -59,8 +58,6 @@ enum iavf_vsi_state_t {  struct iavf_vsi {  	struct iavf_adapter *back;  	struct net_device *netdev; -	unsigned long active_cvlans[BITS_TO_LONGS(VLAN_N_VID)]; -	unsigned long active_svlans[BITS_TO_LONGS(VLAN_N_VID)];  	u16 seid;  	u16 id;  	DECLARE_BITMAP(state, __IAVF_VSI_STATE_SIZE__); @@ -158,15 +155,20 @@ struct iavf_vlan {  	u16 tpid;  }; +enum iavf_vlan_state_t { +	IAVF_VLAN_INVALID, +	IAVF_VLAN_ADD,		/* filter needs to be added */ +	IAVF_VLAN_IS_NEW,	/* filter is new, wait for PF answer */ +	IAVF_VLAN_ACTIVE,	/* filter is accepted by PF */ +	IAVF_VLAN_DISABLE,	/* filter needs to be deleted by PF, then marked INACTIVE */ +	IAVF_VLAN_INACTIVE,	/* filter is inactive, we are in IFF_DOWN */ +	IAVF_VLAN_REMOVE,	/* filter needs to be removed from list */ +}; +  struct iavf_vlan_filter {  	struct list_head list;  	struct iavf_vlan vlan; -	struct { -		u8 is_new_vlan:1;	/* filter is new, wait for PF answer */ -		u8 remove:1;		/* filter needs to be removed */ -		u8 add:1;		/* filter needs to be added */ -		u8 padding:5; -	}; +	enum iavf_vlan_state_t state;  };  #define IAVF_MAX_TRAFFIC_CLASS	4 @@ -258,6 +260,7 @@ struct iavf_adapter {  	wait_queue_head_t vc_waitqueue;  	struct iavf_q_vector *q_vectors;  	struct list_head vlan_filter_list; +	int num_vlan_filters;  	struct list_head mac_filter_list;  	struct mutex crit_lock;  	struct mutex client_lock; @@ -522,7 +525,7 @@ void iavf_set_ethtool_ops(struct net_device *netdev);  void iavf_update_stats(struct iavf_adapter *adapter);  void iavf_reset_interrupt_capability(struct iavf_adapter *adapter);  int iavf_init_interrupt_scheme(struct iavf_adapter *adapter); -void iavf_irq_enable_queues(struct iavf_adapter *adapter, u32 mask); +void iavf_irq_enable_queues(struct iavf_adapter *adapter);  void iavf_free_all_tx_resources(struct iavf_adapter *adapter);  void iavf_free_all_rx_resources(struct iavf_adapter *adapter); diff --git a/drivers/net/ethernet/intel/iavf/iavf_common.c b/drivers/net/ethernet/intel/iavf/iavf_common.c index 16c490965b61..dd11dbbd5551 100644 --- a/drivers/net/ethernet/intel/iavf/iavf_common.c +++ b/drivers/net/ethernet/intel/iavf/iavf_common.c @@ -661,7 +661,7 @@ struct iavf_rx_ptype_decoded iavf_ptype_lookup[BIT(8)] = {  	/* Non Tunneled IPv6 */  	IAVF_PTT(88, IP, IPV6, FRG, NONE, NONE, NOF, NONE, PAY3),  	IAVF_PTT(89, IP, IPV6, NOF, NONE, NONE, NOF, NONE, PAY3), -	IAVF_PTT(90, IP, IPV6, NOF, NONE, NONE, NOF, UDP,  PAY3), +	IAVF_PTT(90, IP, IPV6, NOF, NONE, NONE, NOF, UDP,  PAY4),  	IAVF_PTT_UNUSED_ENTRY(91),  	IAVF_PTT(92, IP, IPV6, NOF, NONE, NONE, NOF, TCP,  PAY4),  	IAVF_PTT(93, IP, IPV6, NOF, NONE, NONE, NOF, SCTP, PAY4), diff --git a/drivers/net/ethernet/intel/iavf/iavf_main.c b/drivers/net/ethernet/intel/iavf/iavf_main.c index 3273aeb8fa67..4a66873882d1 100644 --- a/drivers/net/ethernet/intel/iavf/iavf_main.c +++ b/drivers/net/ethernet/intel/iavf/iavf_main.c @@ -359,21 +359,18 @@ static void iavf_irq_disable(struct iavf_adapter *adapter)  }  /** - * iavf_irq_enable_queues - Enable interrupt for specified queues + * iavf_irq_enable_queues - Enable interrupt for all queues   * @adapter: board private structure - * @mask: bitmap of queues to enable   **/ -void iavf_irq_enable_queues(struct iavf_adapter *adapter, u32 mask) +void iavf_irq_enable_queues(struct iavf_adapter *adapter)  {  	struct iavf_hw *hw = &adapter->hw;  	int i;  	for (i = 1; i < adapter->num_msix_vectors; i++) { -		if (mask & BIT(i - 1)) { -			wr32(hw, IAVF_VFINT_DYN_CTLN1(i - 1), -			     IAVF_VFINT_DYN_CTLN1_INTENA_MASK | -			     IAVF_VFINT_DYN_CTLN1_ITR_INDX_MASK); -		} +		wr32(hw, IAVF_VFINT_DYN_CTLN1(i - 1), +		     IAVF_VFINT_DYN_CTLN1_INTENA_MASK | +		     IAVF_VFINT_DYN_CTLN1_ITR_INDX_MASK);  	}  } @@ -387,7 +384,7 @@ void iavf_irq_enable(struct iavf_adapter *adapter, bool flush)  	struct iavf_hw *hw = &adapter->hw;  	iavf_misc_irq_enable(adapter); -	iavf_irq_enable_queues(adapter, ~0); +	iavf_irq_enable_queues(adapter);  	if (flush)  		iavf_flush(hw); @@ -791,7 +788,8 @@ iavf_vlan_filter *iavf_add_vlan(struct iavf_adapter *adapter,  		f->vlan = vlan;  		list_add_tail(&f->list, &adapter->vlan_filter_list); -		f->add = true; +		f->state = IAVF_VLAN_ADD; +		adapter->num_vlan_filters++;  		adapter->aq_required |= IAVF_FLAG_AQ_ADD_VLAN_FILTER;  	} @@ -813,7 +811,7 @@ static void iavf_del_vlan(struct iavf_adapter *adapter, struct iavf_vlan vlan)  	f = iavf_find_vlan(adapter, vlan);  	if (f) { -		f->remove = true; +		f->state = IAVF_VLAN_REMOVE;  		adapter->aq_required |= IAVF_FLAG_AQ_DEL_VLAN_FILTER;  	} @@ -828,14 +826,18 @@ static void iavf_del_vlan(struct iavf_adapter *adapter, struct iavf_vlan vlan)   **/  static void iavf_restore_filters(struct iavf_adapter *adapter)  { -	u16 vid; +	struct iavf_vlan_filter *f;  	/* re-add all VLAN filters */ -	for_each_set_bit(vid, adapter->vsi.active_cvlans, VLAN_N_VID) -		iavf_add_vlan(adapter, IAVF_VLAN(vid, ETH_P_8021Q)); +	spin_lock_bh(&adapter->mac_vlan_list_lock); + +	list_for_each_entry(f, &adapter->vlan_filter_list, list) { +		if (f->state == IAVF_VLAN_INACTIVE) +			f->state = IAVF_VLAN_ADD; +	} -	for_each_set_bit(vid, adapter->vsi.active_svlans, VLAN_N_VID) -		iavf_add_vlan(adapter, IAVF_VLAN(vid, ETH_P_8021AD)); +	spin_unlock_bh(&adapter->mac_vlan_list_lock); +	adapter->aq_required |= IAVF_FLAG_AQ_ADD_VLAN_FILTER;  }  /** @@ -844,8 +846,7 @@ static void iavf_restore_filters(struct iavf_adapter *adapter)   */  u16 iavf_get_num_vlans_added(struct iavf_adapter *adapter)  { -	return bitmap_weight(adapter->vsi.active_cvlans, VLAN_N_VID) + -		bitmap_weight(adapter->vsi.active_svlans, VLAN_N_VID); +	return adapter->num_vlan_filters;  }  /** @@ -893,6 +894,10 @@ static int iavf_vlan_rx_add_vid(struct net_device *netdev,  {  	struct iavf_adapter *adapter = netdev_priv(netdev); +	/* Do not track VLAN 0 filter, always added by the PF on VF init */ +	if (!vid) +		return 0; +  	if (!VLAN_FILTERING_ALLOWED(adapter))  		return -EIO; @@ -919,12 +924,11 @@ static int iavf_vlan_rx_kill_vid(struct net_device *netdev,  {  	struct iavf_adapter *adapter = netdev_priv(netdev); -	iavf_del_vlan(adapter, IAVF_VLAN(vid, be16_to_cpu(proto))); -	if (proto == cpu_to_be16(ETH_P_8021Q)) -		clear_bit(vid, adapter->vsi.active_cvlans); -	else -		clear_bit(vid, adapter->vsi.active_svlans); +	/* We do not track VLAN 0 filter */ +	if (!vid) +		return 0; +	iavf_del_vlan(adapter, IAVF_VLAN(vid, be16_to_cpu(proto)));  	return 0;  } @@ -1285,16 +1289,11 @@ static void iavf_clear_mac_vlan_filters(struct iavf_adapter *adapter)  		}  	} -	/* remove all VLAN filters */ +	/* disable all VLAN filters */  	list_for_each_entry_safe(vlf, vlftmp, &adapter->vlan_filter_list, -				 list) { -		if (vlf->add) { -			list_del(&vlf->list); -			kfree(vlf); -		} else { -			vlf->remove = true; -		} -	} +				 list) +		vlf->state = IAVF_VLAN_DISABLE; +  	spin_unlock_bh(&adapter->mac_vlan_list_lock);  } @@ -2906,6 +2905,7 @@ static void iavf_disable_vf(struct iavf_adapter *adapter)  		list_del(&fv->list);  		kfree(fv);  	} +	adapter->num_vlan_filters = 0;  	spin_unlock_bh(&adapter->mac_vlan_list_lock); @@ -3123,9 +3123,6 @@ continue_reset:  	adapter->aq_required |= IAVF_FLAG_AQ_ADD_CLOUD_FILTER;  	iavf_misc_irq_enable(adapter); -	bitmap_clear(adapter->vsi.active_cvlans, 0, VLAN_N_VID); -	bitmap_clear(adapter->vsi.active_svlans, 0, VLAN_N_VID); -  	mod_delayed_work(adapter->wq, &adapter->watchdog_task, 2);  	/* We were running when the reset started, so we need to restore some @@ -5066,6 +5063,11 @@ static void iavf_remove(struct pci_dev *pdev)  			mutex_unlock(&adapter->crit_lock);  			break;  		} +		/* Simply return if we already went through iavf_shutdown */ +		if (adapter->state == __IAVF_REMOVE) { +			mutex_unlock(&adapter->crit_lock); +			return; +		}  		mutex_unlock(&adapter->crit_lock);  		usleep_range(500, 1000); diff --git a/drivers/net/ethernet/intel/iavf/iavf_register.h b/drivers/net/ethernet/intel/iavf/iavf_register.h index bf793332fc9d..a19e88898a0b 100644 --- a/drivers/net/ethernet/intel/iavf/iavf_register.h +++ b/drivers/net/ethernet/intel/iavf/iavf_register.h @@ -40,7 +40,7 @@  #define IAVF_VFINT_DYN_CTL01_INTENA_MASK IAVF_MASK(0x1, IAVF_VFINT_DYN_CTL01_INTENA_SHIFT)  #define IAVF_VFINT_DYN_CTL01_ITR_INDX_SHIFT 3  #define IAVF_VFINT_DYN_CTL01_ITR_INDX_MASK IAVF_MASK(0x3, IAVF_VFINT_DYN_CTL01_ITR_INDX_SHIFT) -#define IAVF_VFINT_DYN_CTLN1(_INTVF) (0x00003800 + ((_INTVF) * 4)) /* _i=0...15 */ /* Reset: VFR */ +#define IAVF_VFINT_DYN_CTLN1(_INTVF) (0x00003800 + ((_INTVF) * 4)) /* _i=0...63 */ /* Reset: VFR */  #define IAVF_VFINT_DYN_CTLN1_INTENA_SHIFT 0  #define IAVF_VFINT_DYN_CTLN1_INTENA_MASK IAVF_MASK(0x1, IAVF_VFINT_DYN_CTLN1_INTENA_SHIFT)  #define IAVF_VFINT_DYN_CTLN1_SWINT_TRIG_SHIFT 2 diff --git a/drivers/net/ethernet/intel/iavf/iavf_txrx.c b/drivers/net/ethernet/intel/iavf/iavf_txrx.c index 18b6a702a1d6..e989feda133c 100644 --- a/drivers/net/ethernet/intel/iavf/iavf_txrx.c +++ b/drivers/net/ethernet/intel/iavf/iavf_txrx.c @@ -1096,7 +1096,7 @@ static inline void iavf_rx_hash(struct iavf_ring *ring,  		cpu_to_le64((u64)IAVF_RX_DESC_FLTSTAT_RSS_HASH <<  			    IAVF_RX_DESC_STATUS_FLTSTAT_SHIFT); -	if (ring->netdev->features & NETIF_F_RXHASH) +	if (!(ring->netdev->features & NETIF_F_RXHASH))  		return;  	if ((rx_desc->wb.qword1.status_error_len & rss_mask) == rss_mask) { diff --git a/drivers/net/ethernet/intel/iavf/iavf_virtchnl.c b/drivers/net/ethernet/intel/iavf/iavf_virtchnl.c index 6d23338604bb..7c0578b5457b 100644 --- a/drivers/net/ethernet/intel/iavf/iavf_virtchnl.c +++ b/drivers/net/ethernet/intel/iavf/iavf_virtchnl.c @@ -642,16 +642,10 @@ static void iavf_vlan_add_reject(struct iavf_adapter *adapter)  	spin_lock_bh(&adapter->mac_vlan_list_lock);  	list_for_each_entry_safe(f, ftmp, &adapter->vlan_filter_list, list) { -		if (f->is_new_vlan) { -			if (f->vlan.tpid == ETH_P_8021Q) -				clear_bit(f->vlan.vid, -					  adapter->vsi.active_cvlans); -			else -				clear_bit(f->vlan.vid, -					  adapter->vsi.active_svlans); - +		if (f->state == IAVF_VLAN_IS_NEW) {  			list_del(&f->list);  			kfree(f); +			adapter->num_vlan_filters--;  		}  	}  	spin_unlock_bh(&adapter->mac_vlan_list_lock); @@ -679,7 +673,7 @@ void iavf_add_vlans(struct iavf_adapter *adapter)  	spin_lock_bh(&adapter->mac_vlan_list_lock);  	list_for_each_entry(f, &adapter->vlan_filter_list, list) { -		if (f->add) +		if (f->state == IAVF_VLAN_ADD)  			count++;  	}  	if (!count || !VLAN_FILTERING_ALLOWED(adapter)) { @@ -710,11 +704,10 @@ void iavf_add_vlans(struct iavf_adapter *adapter)  		vvfl->vsi_id = adapter->vsi_res->vsi_id;  		vvfl->num_elements = count;  		list_for_each_entry(f, &adapter->vlan_filter_list, list) { -			if (f->add) { +			if (f->state == IAVF_VLAN_ADD) {  				vvfl->vlan_id[i] = f->vlan.vid;  				i++; -				f->add = false; -				f->is_new_vlan = true; +				f->state = IAVF_VLAN_IS_NEW;  				if (i == count)  					break;  			} @@ -760,7 +753,7 @@ void iavf_add_vlans(struct iavf_adapter *adapter)  		vvfl_v2->vport_id = adapter->vsi_res->vsi_id;  		vvfl_v2->num_elements = count;  		list_for_each_entry(f, &adapter->vlan_filter_list, list) { -			if (f->add) { +			if (f->state == IAVF_VLAN_ADD) {  				struct virtchnl_vlan_supported_caps *filtering_support =  					&adapter->vlan_v2_caps.filtering.filtering_support;  				struct virtchnl_vlan *vlan; @@ -778,8 +771,7 @@ void iavf_add_vlans(struct iavf_adapter *adapter)  				vlan->tpid = f->vlan.tpid;  				i++; -				f->add = false; -				f->is_new_vlan = true; +				f->state = IAVF_VLAN_IS_NEW;  			}  		} @@ -822,10 +814,16 @@ void iavf_del_vlans(struct iavf_adapter *adapter)  		 * filters marked for removal to enable bailing out before  		 * sending a virtchnl message  		 */ -		if (f->remove && !VLAN_FILTERING_ALLOWED(adapter)) { +		if (f->state == IAVF_VLAN_REMOVE && +		    !VLAN_FILTERING_ALLOWED(adapter)) {  			list_del(&f->list);  			kfree(f); -		} else if (f->remove) { +			adapter->num_vlan_filters--; +		} else if (f->state == IAVF_VLAN_DISABLE && +		    !VLAN_FILTERING_ALLOWED(adapter)) { +			f->state = IAVF_VLAN_INACTIVE; +		} else if (f->state == IAVF_VLAN_REMOVE || +			   f->state == IAVF_VLAN_DISABLE) {  			count++;  		}  	} @@ -857,11 +855,18 @@ void iavf_del_vlans(struct iavf_adapter *adapter)  		vvfl->vsi_id = adapter->vsi_res->vsi_id;  		vvfl->num_elements = count;  		list_for_each_entry_safe(f, ftmp, &adapter->vlan_filter_list, list) { -			if (f->remove) { +			if (f->state == IAVF_VLAN_DISABLE) {  				vvfl->vlan_id[i] = f->vlan.vid; +				f->state = IAVF_VLAN_INACTIVE;  				i++; +				if (i == count) +					break; +			} else if (f->state == IAVF_VLAN_REMOVE) { +				vvfl->vlan_id[i] = f->vlan.vid;  				list_del(&f->list);  				kfree(f); +				adapter->num_vlan_filters--; +				i++;  				if (i == count)  					break;  			} @@ -901,7 +906,8 @@ void iavf_del_vlans(struct iavf_adapter *adapter)  		vvfl_v2->vport_id = adapter->vsi_res->vsi_id;  		vvfl_v2->num_elements = count;  		list_for_each_entry_safe(f, ftmp, &adapter->vlan_filter_list, list) { -			if (f->remove) { +			if (f->state == IAVF_VLAN_DISABLE || +			    f->state == IAVF_VLAN_REMOVE) {  				struct virtchnl_vlan_supported_caps *filtering_support =  					&adapter->vlan_v2_caps.filtering.filtering_support;  				struct virtchnl_vlan *vlan; @@ -915,8 +921,13 @@ void iavf_del_vlans(struct iavf_adapter *adapter)  				vlan->tci = f->vlan.vid;  				vlan->tpid = f->vlan.tpid; -				list_del(&f->list); -				kfree(f); +				if (f->state == IAVF_VLAN_DISABLE) { +					f->state = IAVF_VLAN_INACTIVE; +				} else { +					list_del(&f->list); +					kfree(f); +					adapter->num_vlan_filters--; +				}  				i++;  				if (i == count)  					break; @@ -2192,7 +2203,7 @@ void iavf_virtchnl_completion(struct iavf_adapter *adapter,  				list_for_each_entry(vlf,  						    &adapter->vlan_filter_list,  						    list) -					vlf->add = true; +					vlf->state = IAVF_VLAN_ADD;  				adapter->aq_required |=  					IAVF_FLAG_AQ_ADD_VLAN_FILTER; @@ -2227,11 +2238,6 @@ void iavf_virtchnl_completion(struct iavf_adapter *adapter,  		iavf_process_config(adapter);  		adapter->flags |= IAVF_FLAG_SETUP_NETDEV_FEATURES; -		/* Request VLAN offload settings */ -		if (VLAN_V2_ALLOWED(adapter)) -			iavf_set_vlan_offload_features(adapter, 0, -						       netdev->features); -  		iavf_set_queue_vlan_tag_loc(adapter);  		was_mac_changed = !ether_addr_equal(netdev->dev_addr, @@ -2260,7 +2266,7 @@ void iavf_virtchnl_completion(struct iavf_adapter *adapter,  				list_for_each_entry(vlf,  						    &adapter->vlan_filter_list,  						    list) -					vlf->add = true; +					vlf->state = IAVF_VLAN_ADD;  				aq_required |= IAVF_FLAG_AQ_ADD_VLAN_FILTER;  			} @@ -2444,17 +2450,8 @@ void iavf_virtchnl_completion(struct iavf_adapter *adapter,  		spin_lock_bh(&adapter->mac_vlan_list_lock);  		list_for_each_entry(f, &adapter->vlan_filter_list, list) { -			if (f->is_new_vlan) { -				f->is_new_vlan = false; -				if (!f->vlan.vid) -					continue; -				if (f->vlan.tpid == ETH_P_8021Q) -					set_bit(f->vlan.vid, -						adapter->vsi.active_cvlans); -				else -					set_bit(f->vlan.vid, -						adapter->vsi.active_svlans); -			} +			if (f->state == IAVF_VLAN_IS_NEW) +				f->state = IAVF_VLAN_ACTIVE;  		}  		spin_unlock_bh(&adapter->mac_vlan_list_lock);  		} diff --git a/drivers/net/ethernet/intel/ice/ice.h b/drivers/net/ethernet/intel/ice/ice.h index b0e29e342401..aa32111afd6e 100644 --- a/drivers/net/ethernet/intel/ice/ice.h +++ b/drivers/net/ethernet/intel/ice/ice.h @@ -20,7 +20,6 @@  #include <linux/pci.h>  #include <linux/workqueue.h>  #include <linux/wait.h> -#include <linux/aer.h>  #include <linux/interrupt.h>  #include <linux/ethtool.h>  #include <linux/timer.h> @@ -509,6 +508,7 @@ enum ice_pf_flags {  	ICE_FLAG_VF_VLAN_PRUNING,  	ICE_FLAG_LINK_LENIENT_MODE_ENA,  	ICE_FLAG_PLUG_AUX_DEV, +	ICE_FLAG_UNPLUG_AUX_DEV,  	ICE_FLAG_MTU_CHANGED,  	ICE_FLAG_GNSS,			/* GNSS successfully initialized */  	ICE_PF_FLAGS_NBITS		/* must be last */ @@ -955,16 +955,11 @@ static inline void ice_set_rdma_cap(struct ice_pf *pf)   */  static inline void ice_clear_rdma_cap(struct ice_pf *pf)  { -	/* We can directly unplug aux device here only if the flag bit -	 * ICE_FLAG_PLUG_AUX_DEV is not set because ice_unplug_aux_dev() -	 * could race with ice_plug_aux_dev() called from -	 * ice_service_task(). In this case we only clear that bit now and -	 * aux device will be unplugged later once ice_plug_aux_device() -	 * called from ice_service_task() finishes (see ice_service_task()). +	/* defer unplug to service task to avoid RTNL lock and +	 * clear PLUG bit so that pending plugs don't interfere  	 */ -	if (!test_and_clear_bit(ICE_FLAG_PLUG_AUX_DEV, pf->flags)) -		ice_unplug_aux_dev(pf); - +	clear_bit(ICE_FLAG_PLUG_AUX_DEV, pf->flags); +	set_bit(ICE_FLAG_UNPLUG_AUX_DEV, pf->flags);  	clear_bit(ICE_FLAG_RDMA_ENA, pf->flags);  }  #endif /* _ICE_H_ */ diff --git a/drivers/net/ethernet/intel/ice/ice_common.c b/drivers/net/ethernet/intel/ice/ice_common.c index c2fda4fa4188..eb2dc0983776 100644 --- a/drivers/net/ethernet/intel/ice/ice_common.c +++ b/drivers/net/ethernet/intel/ice/ice_common.c @@ -1619,7 +1619,6 @@ ice_sq_send_cmd_retry(struct ice_hw *hw, struct ice_ctl_q_info *cq,  {  	struct ice_aq_desc desc_cpy;  	bool is_cmd_for_retry; -	u8 *buf_cpy = NULL;  	u8 idx = 0;  	u16 opcode;  	int status; @@ -1629,11 +1628,8 @@ ice_sq_send_cmd_retry(struct ice_hw *hw, struct ice_ctl_q_info *cq,  	memset(&desc_cpy, 0, sizeof(desc_cpy));  	if (is_cmd_for_retry) { -		if (buf) { -			buf_cpy = kzalloc(buf_size, GFP_KERNEL); -			if (!buf_cpy) -				return -ENOMEM; -		} +		/* All retryable cmds are direct, without buf. */ +		WARN_ON(buf);  		memcpy(&desc_cpy, desc, sizeof(desc_cpy));  	} @@ -1645,17 +1641,12 @@ ice_sq_send_cmd_retry(struct ice_hw *hw, struct ice_ctl_q_info *cq,  		    hw->adminq.sq_last_status != ICE_AQ_RC_EBUSY)  			break; -		if (buf_cpy) -			memcpy(buf, buf_cpy, buf_size); -  		memcpy(desc, &desc_cpy, sizeof(desc_cpy)); -		mdelay(ICE_SQ_SEND_DELAY_TIME_MS); +		msleep(ICE_SQ_SEND_DELAY_TIME_MS);  	} while (++idx < ICE_SQ_SEND_MAX_EXECUTE); -	kfree(buf_cpy); -  	return status;  } @@ -1992,19 +1983,19 @@ ice_acquire_res_exit:   */  void ice_release_res(struct ice_hw *hw, enum ice_aq_res_ids res)  { -	u32 total_delay = 0; +	unsigned long timeout;  	int status; -	status = ice_aq_release_res(hw, res, 0, NULL); -  	/* there are some rare cases when trying to release the resource  	 * results in an admin queue timeout, so handle them correctly  	 */ -	while ((status == -EIO) && (total_delay < hw->adminq.sq_cmd_timeout)) { -		mdelay(1); +	timeout = jiffies + 10 * ICE_CTL_Q_SQ_CMD_TIMEOUT; +	do {  		status = ice_aq_release_res(hw, res, 0, NULL); -		total_delay++; -	} +		if (status != -EIO) +			break; +		usleep_range(1000, 2000); +	} while (time_before(jiffies, timeout));  }  /** @@ -5169,7 +5160,7 @@ ice_aq_read_i2c(struct ice_hw *hw, struct ice_aqc_link_topo_addr topo_addr,   */  int  ice_aq_write_i2c(struct ice_hw *hw, struct ice_aqc_link_topo_addr topo_addr, -		 u16 bus_addr, __le16 addr, u8 params, u8 *data, +		 u16 bus_addr, __le16 addr, u8 params, const u8 *data,  		 struct ice_sq_cd *cd)  {  	struct ice_aq_desc desc = { 0 }; diff --git a/drivers/net/ethernet/intel/ice/ice_common.h b/drivers/net/ethernet/intel/ice/ice_common.h index 8ba5f935a092..81961a7d6598 100644 --- a/drivers/net/ethernet/intel/ice/ice_common.h +++ b/drivers/net/ethernet/intel/ice/ice_common.h @@ -229,7 +229,7 @@ ice_aq_read_i2c(struct ice_hw *hw, struct ice_aqc_link_topo_addr topo_addr,  		struct ice_sq_cd *cd);  int  ice_aq_write_i2c(struct ice_hw *hw, struct ice_aqc_link_topo_addr topo_addr, -		 u16 bus_addr, __le16 addr, u8 params, u8 *data, +		 u16 bus_addr, __le16 addr, u8 params, const u8 *data,  		 struct ice_sq_cd *cd);  bool ice_fw_supports_report_dflt_cfg(struct ice_hw *hw);  #endif /* _ICE_COMMON_H_ */ diff --git a/drivers/net/ethernet/intel/ice/ice_controlq.c b/drivers/net/ethernet/intel/ice/ice_controlq.c index 6bcfee295991..d2faf1baad2f 100644 --- a/drivers/net/ethernet/intel/ice/ice_controlq.c +++ b/drivers/net/ethernet/intel/ice/ice_controlq.c @@ -637,9 +637,6 @@ static int ice_init_ctrlq(struct ice_hw *hw, enum ice_ctl_q q_type)  		return -EIO;  	} -	/* setup SQ command write back timeout */ -	cq->sq_cmd_timeout = ICE_CTL_Q_SQ_CMD_TIMEOUT; -  	/* allocate the ATQ */  	ret_code = ice_init_sq(hw, cq);  	if (ret_code) @@ -967,7 +964,7 @@ ice_sq_send_cmd(struct ice_hw *hw, struct ice_ctl_q_info *cq,  	struct ice_aq_desc *desc_on_ring;  	bool cmd_completed = false;  	struct ice_sq_cd *details; -	u32 total_delay = 0; +	unsigned long timeout;  	int status = 0;  	u16 retval = 0;  	u32 val = 0; @@ -1060,13 +1057,14 @@ ice_sq_send_cmd(struct ice_hw *hw, struct ice_ctl_q_info *cq,  		cq->sq.next_to_use = 0;  	wr32(hw, cq->sq.tail, cq->sq.next_to_use); +	timeout = jiffies + ICE_CTL_Q_SQ_CMD_TIMEOUT;  	do {  		if (ice_sq_done(hw, cq))  			break; -		udelay(ICE_CTL_Q_SQ_CMD_USEC); -		total_delay++; -	} while (total_delay < cq->sq_cmd_timeout); +		usleep_range(ICE_CTL_Q_SQ_CMD_USEC, +			     ICE_CTL_Q_SQ_CMD_USEC * 3 / 2); +	} while (time_before(jiffies, timeout));  	/* if ready, copy the desc back to temp */  	if (ice_sq_done(hw, cq)) { diff --git a/drivers/net/ethernet/intel/ice/ice_controlq.h b/drivers/net/ethernet/intel/ice/ice_controlq.h index c07e9cc9fc6e..950b7f4a7a05 100644 --- a/drivers/net/ethernet/intel/ice/ice_controlq.h +++ b/drivers/net/ethernet/intel/ice/ice_controlq.h @@ -34,7 +34,7 @@ enum ice_ctl_q {  };  /* Control Queue timeout settings - max delay 1s */ -#define ICE_CTL_Q_SQ_CMD_TIMEOUT	10000 /* Count 10000 times */ +#define ICE_CTL_Q_SQ_CMD_TIMEOUT	HZ    /* Wait max 1s */  #define ICE_CTL_Q_SQ_CMD_USEC		100   /* Check every 100usec */  #define ICE_CTL_Q_ADMIN_INIT_TIMEOUT	10    /* Count 10 times */  #define ICE_CTL_Q_ADMIN_INIT_MSEC	100   /* Check every 100msec */ @@ -87,7 +87,6 @@ struct ice_ctl_q_info {  	enum ice_ctl_q qtype;  	struct ice_ctl_q_ring rq;	/* receive queue */  	struct ice_ctl_q_ring sq;	/* send queue */ -	u32 sq_cmd_timeout;		/* send queue cmd write back timeout */  	u16 num_rq_entries;		/* receive queue depth */  	u16 num_sq_entries;		/* send queue depth */  	u16 rq_buf_size;		/* receive queue buffer size */ diff --git a/drivers/net/ethernet/intel/ice/ice_dcb_lib.c b/drivers/net/ethernet/intel/ice/ice_dcb_lib.c index c6d4926f0fcf..850db8e0e6b0 100644 --- a/drivers/net/ethernet/intel/ice/ice_dcb_lib.c +++ b/drivers/net/ethernet/intel/ice/ice_dcb_lib.c @@ -932,10 +932,9 @@ ice_tx_prepare_vlan_flags_dcb(struct ice_tx_ring *tx_ring,  	if ((first->tx_flags & ICE_TX_FLAGS_HW_VLAN ||  	     first->tx_flags & ICE_TX_FLAGS_HW_OUTER_SINGLE_VLAN) ||  	    skb->priority != TC_PRIO_CONTROL) { -		first->tx_flags &= ~ICE_TX_FLAGS_VLAN_PR_M; +		first->vid &= ~VLAN_PRIO_MASK;  		/* Mask the lower 3 bits to set the 802.1p priority */ -		first->tx_flags |= (skb->priority & 0x7) << -				   ICE_TX_FLAGS_VLAN_PR_S; +		first->vid |= (skb->priority << VLAN_PRIO_SHIFT) & VLAN_PRIO_MASK;  		/* if this is not already set it means a VLAN 0 + priority needs  		 * to be offloaded  		 */ diff --git a/drivers/net/ethernet/intel/ice/ice_devlink.c b/drivers/net/ethernet/intel/ice/ice_devlink.c index 05f216af8c81..bc44cc220818 100644 --- a/drivers/net/ethernet/intel/ice/ice_devlink.c +++ b/drivers/net/ethernet/intel/ice/ice_devlink.c @@ -1254,7 +1254,6 @@ static const struct devlink_ops ice_devlink_ops = {  	.supported_flash_update_params = DEVLINK_SUPPORT_FLASH_UPDATE_OVERWRITE_MASK,  	.reload_actions = BIT(DEVLINK_RELOAD_ACTION_DRIVER_REINIT) |  			  BIT(DEVLINK_RELOAD_ACTION_FW_ACTIVATE), -	/* The ice driver currently does not support driver reinit */  	.reload_down = ice_devlink_reload_down,  	.reload_up = ice_devlink_reload_up,  	.port_split = ice_devlink_port_split, diff --git a/drivers/net/ethernet/intel/ice/ice_gnss.c b/drivers/net/ethernet/intel/ice/ice_gnss.c index 8dec748bb53a..75c9de675f20 100644 --- a/drivers/net/ethernet/intel/ice/ice_gnss.c +++ b/drivers/net/ethernet/intel/ice/ice_gnss.c @@ -16,8 +16,8 @@   * * number of bytes written - success   * * negative - error code   */ -static unsigned int -ice_gnss_do_write(struct ice_pf *pf, unsigned char *buf, unsigned int size) +static int +ice_gnss_do_write(struct ice_pf *pf, const unsigned char *buf, unsigned int size)  {  	struct ice_aqc_link_topo_addr link_topo;  	struct ice_hw *hw = &pf->hw; @@ -72,39 +72,7 @@ err_out:  	dev_err(ice_pf_to_dev(pf), "GNSS failed to write, offset=%u, size=%u, err=%d\n",  		offset, size, err); -	return offset; -} - -/** - * ice_gnss_write_pending - Write all pending data to internal GNSS - * @work: GNSS write work structure - */ -static void ice_gnss_write_pending(struct kthread_work *work) -{ -	struct gnss_serial *gnss = container_of(work, struct gnss_serial, -						write_work); -	struct ice_pf *pf = gnss->back; - -	if (!pf) -		return; - -	if (!test_bit(ICE_FLAG_GNSS, pf->flags)) -		return; - -	if (!list_empty(&gnss->queue)) { -		struct gnss_write_buf *write_buf = NULL; -		unsigned int bytes; - -		write_buf = list_first_entry(&gnss->queue, -					     struct gnss_write_buf, queue); - -		bytes = ice_gnss_do_write(pf, write_buf->buf, write_buf->size); -		dev_dbg(ice_pf_to_dev(pf), "%u bytes written to GNSS\n", bytes); - -		list_del(&write_buf->queue); -		kfree(write_buf->buf); -		kfree(write_buf); -	} +	return err;  }  /** @@ -117,6 +85,7 @@ static void ice_gnss_read(struct kthread_work *work)  {  	struct gnss_serial *gnss = container_of(work, struct gnss_serial,  						read_work.work); +	unsigned long delay = ICE_GNSS_POLL_DATA_DELAY_TIME;  	unsigned int i, bytes_read, data_len, count;  	struct ice_aqc_link_topo_addr link_topo;  	struct ice_pf *pf; @@ -127,20 +96,10 @@ static void ice_gnss_read(struct kthread_work *work)  	int err = 0;  	pf = gnss->back; -	if (!pf) { -		err = -EFAULT; -		goto exit; -	} - -	if (!test_bit(ICE_FLAG_GNSS, pf->flags)) +	if (!pf || !test_bit(ICE_FLAG_GNSS, pf->flags))  		return;  	hw = &pf->hw; -	buf = (char *)get_zeroed_page(GFP_KERNEL); -	if (!buf) { -		err = -ENOMEM; -		goto exit; -	}  	memset(&link_topo, 0, sizeof(struct ice_aqc_link_topo_addr));  	link_topo.topo_params.index = ICE_E810T_GNSS_I2C_BUS; @@ -151,25 +110,24 @@ static void ice_gnss_read(struct kthread_work *work)  	i2c_params = ICE_GNSS_UBX_DATA_LEN_WIDTH |  		     ICE_AQC_I2C_USE_REPEATED_START; -	/* Read data length in a loop, when it's not 0 the data is ready */ -	for (i = 0; i < ICE_MAX_UBX_READ_TRIES; i++) { -		err = ice_aq_read_i2c(hw, link_topo, ICE_GNSS_UBX_I2C_BUS_ADDR, -				      cpu_to_le16(ICE_GNSS_UBX_DATA_LEN_H), -				      i2c_params, (u8 *)&data_len_b, NULL); -		if (err) -			goto exit_buf; +	err = ice_aq_read_i2c(hw, link_topo, ICE_GNSS_UBX_I2C_BUS_ADDR, +			      cpu_to_le16(ICE_GNSS_UBX_DATA_LEN_H), +			      i2c_params, (u8 *)&data_len_b, NULL); +	if (err) +		goto requeue; -		data_len = be16_to_cpu(data_len_b); -		if (data_len != 0 && data_len != U16_MAX) -			break; +	data_len = be16_to_cpu(data_len_b); +	if (data_len == 0 || data_len == U16_MAX) +		goto requeue; -		mdelay(10); -	} +	/* The u-blox has data_len bytes for us to read */  	data_len = min_t(typeof(data_len), data_len, PAGE_SIZE); -	if (!data_len) { + +	buf = (char *)get_zeroed_page(GFP_KERNEL); +	if (!buf) {  		err = -ENOMEM; -		goto exit_buf; +		goto requeue;  	}  	/* Read received data */ @@ -183,7 +141,7 @@ static void ice_gnss_read(struct kthread_work *work)  				      cpu_to_le16(ICE_GNSS_UBX_EMPTY_DATA),  				      bytes_read, &buf[i], NULL);  		if (err) -			goto exit_buf; +			goto free_buf;  	}  	count = gnss_insert_raw(pf->gnss_dev, buf, i); @@ -191,11 +149,11 @@ static void ice_gnss_read(struct kthread_work *work)  		dev_warn(ice_pf_to_dev(pf),  			 "gnss_insert_raw ret=%d size=%d\n",  			 count, i); -exit_buf: +	delay = ICE_GNSS_TIMER_DELAY_TIME; +free_buf:  	free_page((unsigned long)buf); -	kthread_queue_delayed_work(gnss->kworker, &gnss->read_work, -				   ICE_GNSS_TIMER_DELAY_TIME); -exit: +requeue: +	kthread_queue_delayed_work(gnss->kworker, &gnss->read_work, delay);  	if (err)  		dev_dbg(ice_pf_to_dev(pf), "GNSS failed to read err=%d\n", err);  } @@ -224,8 +182,6 @@ static struct gnss_serial *ice_gnss_struct_init(struct ice_pf *pf)  	pf->gnss_serial = gnss;  	kthread_init_delayed_work(&gnss->read_work, ice_gnss_read); -	INIT_LIST_HEAD(&gnss->queue); -	kthread_init_work(&gnss->write_work, ice_gnss_write_pending);  	kworker = kthread_create_worker(0, "ice-gnss-%s", dev_name(dev));  	if (IS_ERR(kworker)) {  		kfree(gnss); @@ -285,7 +241,6 @@ static void ice_gnss_close(struct gnss_device *gdev)  	if (!gnss)  		return; -	kthread_cancel_work_sync(&gnss->write_work);  	kthread_cancel_delayed_work_sync(&gnss->read_work);  } @@ -304,10 +259,7 @@ ice_gnss_write(struct gnss_device *gdev, const unsigned char *buf,  	       size_t count)  {  	struct ice_pf *pf = gnss_get_drvdata(gdev); -	struct gnss_write_buf *write_buf;  	struct gnss_serial *gnss; -	unsigned char *cmd_buf; -	int err = count;  	/* We cannot write a single byte using our I2C implementation. */  	if (count <= 1 || count > ICE_GNSS_TTY_WRITE_BUF) @@ -323,24 +275,7 @@ ice_gnss_write(struct gnss_device *gdev, const unsigned char *buf,  	if (!gnss)  		return -ENODEV; -	cmd_buf = kcalloc(count, sizeof(*buf), GFP_KERNEL); -	if (!cmd_buf) -		return -ENOMEM; - -	memcpy(cmd_buf, buf, count); -	write_buf = kzalloc(sizeof(*write_buf), GFP_KERNEL); -	if (!write_buf) { -		kfree(cmd_buf); -		return -ENOMEM; -	} - -	write_buf->buf = cmd_buf; -	write_buf->size = count; -	INIT_LIST_HEAD(&write_buf->queue); -	list_add_tail(&write_buf->queue, &gnss->queue); -	kthread_queue_work(gnss->kworker, &gnss->write_work); - -	return err; +	return ice_gnss_do_write(pf, buf, count);  }  static const struct gnss_operations ice_gnss_ops = { @@ -436,7 +371,6 @@ void ice_gnss_exit(struct ice_pf *pf)  	if (pf->gnss_serial) {  		struct gnss_serial *gnss = pf->gnss_serial; -		kthread_cancel_work_sync(&gnss->write_work);  		kthread_cancel_delayed_work_sync(&gnss->read_work);  		kthread_destroy_worker(gnss->kworker);  		gnss->kworker = NULL; diff --git a/drivers/net/ethernet/intel/ice/ice_gnss.h b/drivers/net/ethernet/intel/ice/ice_gnss.h index 4d49e5b0b4b8..75e567ad7059 100644 --- a/drivers/net/ethernet/intel/ice/ice_gnss.h +++ b/drivers/net/ethernet/intel/ice/ice_gnss.h @@ -5,6 +5,7 @@  #define _ICE_GNSS_H_  #define ICE_E810T_GNSS_I2C_BUS		0x2 +#define ICE_GNSS_POLL_DATA_DELAY_TIME	(HZ / 50) /* poll every 20 ms */  #define ICE_GNSS_TIMER_DELAY_TIME	(HZ / 10) /* 0.1 second per message */  #define ICE_GNSS_TTY_WRITE_BUF		250  #define ICE_MAX_I2C_DATA_SIZE		FIELD_MAX(ICE_AQC_I2C_DATA_SIZE_M) @@ -20,29 +21,17 @@   * passed as I2C addr parameter.   */  #define ICE_GNSS_UBX_WRITE_BYTES	(ICE_MAX_I2C_WRITE_BYTES + 1) -#define ICE_MAX_UBX_READ_TRIES		255 -#define ICE_MAX_UBX_ACK_READ_TRIES	4095 - -struct gnss_write_buf { -	struct list_head queue; -	unsigned int size; -	unsigned char *buf; -};  /**   * struct gnss_serial - data used to initialize GNSS TTY port   * @back: back pointer to PF   * @kworker: kwork thread for handling periodic work   * @read_work: read_work function for handling GNSS reads - * @write_work: write_work function for handling GNSS writes - * @queue: write buffers queue   */  struct gnss_serial {  	struct ice_pf *back;  	struct kthread_worker *kworker;  	struct kthread_delayed_work read_work; -	struct kthread_work write_work; -	struct list_head queue;  };  #if IS_ENABLED(CONFIG_GNSS) diff --git a/drivers/net/ethernet/intel/ice/ice_lib.c b/drivers/net/ethernet/intel/ice/ice_lib.c index 0f52ea38b6f3..11ae0e41f518 100644 --- a/drivers/net/ethernet/intel/ice/ice_lib.c +++ b/drivers/net/ethernet/intel/ice/ice_lib.c @@ -291,6 +291,7 @@ static void ice_vsi_delete_from_hw(struct ice_vsi *vsi)  	struct ice_vsi_ctx *ctxt;  	int status; +	ice_fltr_remove_all(vsi);  	ctxt = kzalloc(sizeof(*ctxt), GFP_KERNEL);  	if (!ctxt)  		return; @@ -2744,6 +2745,8 @@ ice_vsi_cfg_def(struct ice_vsi *vsi, struct ice_vsi_cfg_params *params)  			goto unroll_vector_base;  		ice_vsi_map_rings_to_vectors(vsi); +		vsi->stat_offsets_loaded = false; +  		if (ice_is_xdp_ena_vsi(vsi)) {  			ret = ice_vsi_determine_xdp_res(vsi);  			if (ret) @@ -2792,6 +2795,9 @@ ice_vsi_cfg_def(struct ice_vsi *vsi, struct ice_vsi_cfg_params *params)  		ret = ice_vsi_alloc_ring_stats(vsi);  		if (ret)  			goto unroll_vector_base; + +		vsi->stat_offsets_loaded = false; +  		/* Do not exit if configuring RSS had an issue, at least  		 * receive traffic on first queue. Hence no need to capture  		 * return value @@ -2892,7 +2898,6 @@ void ice_vsi_decfg(struct ice_vsi *vsi)  	    !test_bit(ICE_FLAG_FW_LLDP_AGENT, pf->flags))  		ice_cfg_sw_lldp(vsi, false, false); -	ice_fltr_remove_all(vsi);  	ice_rm_vsi_lan_cfg(vsi->port_info, vsi->idx);  	err = ice_rm_vsi_rdma_cfg(vsi->port_info, vsi->idx);  	if (err) diff --git a/drivers/net/ethernet/intel/ice/ice_main.c b/drivers/net/ethernet/intel/ice/ice_main.c index 567694bf098b..42c318ceff61 100644 --- a/drivers/net/ethernet/intel/ice/ice_main.c +++ b/drivers/net/ethernet/intel/ice/ice_main.c @@ -1393,6 +1393,8 @@ static void ice_aq_cancel_waiting_tasks(struct ice_pf *pf)  	wake_up(&pf->aq_wait_queue);  } +#define ICE_MBX_OVERFLOW_WATERMARK 64 +  /**   * __ice_clean_ctrlq - helper function to clean controlq rings   * @pf: ptr to struct ice_pf @@ -1483,6 +1485,7 @@ static int __ice_clean_ctrlq(struct ice_pf *pf, enum ice_ctl_q q_type)  		return 0;  	do { +		struct ice_mbx_data data = {};  		u16 opcode;  		int ret; @@ -1509,8 +1512,12 @@ static int __ice_clean_ctrlq(struct ice_pf *pf, enum ice_ctl_q q_type)  			ice_vf_lan_overflow_event(pf, &event);  			break;  		case ice_mbx_opc_send_msg_to_pf: -			if (!ice_is_malicious_vf(pf, &event, i, pending)) -				ice_vc_process_vf_msg(pf, &event); +			data.num_msg_proc = i; +			data.num_pending_arq = pending; +			data.max_num_msgs_mbx = hw->mailboxq.num_rq_entries; +			data.async_watermark_val = ICE_MBX_OVERFLOW_WATERMARK; + +			ice_vc_process_vf_msg(pf, &event, &data);  			break;  		case ice_aqc_opc_fw_logging:  			ice_output_fw_log(hw, &event.desc, event.msg_buf); @@ -2316,18 +2323,15 @@ static void ice_service_task(struct work_struct *work)  		}  	} -	if (test_bit(ICE_FLAG_PLUG_AUX_DEV, pf->flags)) { -		/* Plug aux device per request */ -		ice_plug_aux_dev(pf); +	/* unplug aux dev per request, if an unplug request came in +	 * while processing a plug request, this will handle it +	 */ +	if (test_and_clear_bit(ICE_FLAG_UNPLUG_AUX_DEV, pf->flags)) +		ice_unplug_aux_dev(pf); -		/* Mark plugging as done but check whether unplug was -		 * requested during ice_plug_aux_dev() call -		 * (e.g. from ice_clear_rdma_cap()) and if so then -		 * plug aux device. -		 */ -		if (!test_and_clear_bit(ICE_FLAG_PLUG_AUX_DEV, pf->flags)) -			ice_unplug_aux_dev(pf); -	} +	/* Plug aux device per request */ +	if (test_and_clear_bit(ICE_FLAG_PLUG_AUX_DEV, pf->flags)) +		ice_plug_aux_dev(pf);  	if (test_and_clear_bit(ICE_FLAG_MTU_CHANGED, pf->flags)) {  		struct iidc_event *event; @@ -3891,6 +3895,7 @@ static int ice_init_pf(struct ice_pf *pf)  	mutex_init(&pf->vfs.table_lock);  	hash_init(pf->vfs.table); +	ice_mbx_init_snapshot(&pf->hw);  	return 0;  } @@ -4644,6 +4649,12 @@ static int ice_start_eth(struct ice_vsi *vsi)  	return err;  } +static void ice_stop_eth(struct ice_vsi *vsi) +{ +	ice_fltr_remove_all(vsi); +	ice_vsi_close(vsi); +} +  static int ice_init_eth(struct ice_pf *pf)  {  	struct ice_vsi *vsi = ice_get_main_vsi(pf); @@ -4791,9 +4802,13 @@ err_init_pf:  static void ice_deinit_dev(struct ice_pf *pf)  {  	ice_free_irq_msix_misc(pf); -	ice_clear_interrupt_scheme(pf);  	ice_deinit_pf(pf);  	ice_deinit_hw(&pf->hw); + +	/* Service task is already stopped, so call reset directly. */ +	ice_reset(&pf->hw, ICE_RESET_PFR); +	pci_wait_for_pending_transaction(pf->pdev); +	ice_clear_interrupt_scheme(pf);  }  static void ice_init_features(struct ice_pf *pf) @@ -5083,10 +5098,6 @@ int ice_load(struct ice_pf *pf)  	struct ice_vsi *vsi;  	int err; -	err = ice_reset(&pf->hw, ICE_RESET_PFR); -	if (err) -		return err; -  	err = ice_init_dev(pf);  	if (err)  		return err; @@ -5132,7 +5143,7 @@ void ice_unload(struct ice_pf *pf)  {  	ice_deinit_features(pf);  	ice_deinit_rdma(pf); -	ice_vsi_close(ice_get_main_vsi(pf)); +	ice_stop_eth(ice_get_main_vsi(pf));  	ice_vsi_decfg(ice_get_main_vsi(pf));  	ice_deinit_dev(pf);  } @@ -5343,12 +5354,6 @@ static void ice_remove(struct pci_dev *pdev)  	ice_setup_mc_magic_wake(pf);  	ice_set_wake(pf); -	/* Issue a PFR as part of the prescribed driver unload flow.  Do not -	 * do it via ice_schedule_reset() since there is no need to rebuild -	 * and the service task is already stopped. -	 */ -	ice_reset(&pf->hw, ICE_RESET_PFR); -	pci_wait_for_pending_transaction(pdev);  	pci_disable_device(pdev);  } @@ -7045,6 +7050,10 @@ int ice_down(struct ice_vsi *vsi)  	ice_for_each_txq(vsi, i)  		ice_clean_tx_ring(vsi->tx_rings[i]); +	if (ice_is_xdp_ena_vsi(vsi)) +		ice_for_each_xdp_txq(vsi, i) +			ice_clean_tx_ring(vsi->xdp_rings[i]); +  	ice_for_each_rxq(vsi, i)  		ice_clean_rx_ring(vsi->rx_rings[i]); diff --git a/drivers/net/ethernet/intel/ice/ice_sched.c b/drivers/net/ethernet/intel/ice/ice_sched.c index 4eca8d195ef0..b7682de0ae05 100644 --- a/drivers/net/ethernet/intel/ice/ice_sched.c +++ b/drivers/net/ethernet/intel/ice/ice_sched.c @@ -2788,7 +2788,7 @@ static int  ice_sched_assoc_vsi_to_agg(struct ice_port_info *pi, u32 agg_id,  			   u16 vsi_handle, unsigned long *tc_bitmap)  { -	struct ice_sched_agg_vsi_info *agg_vsi_info, *old_agg_vsi_info = NULL; +	struct ice_sched_agg_vsi_info *agg_vsi_info, *iter, *old_agg_vsi_info = NULL;  	struct ice_sched_agg_info *agg_info, *old_agg_info;  	struct ice_hw *hw = pi->hw;  	int status = 0; @@ -2806,11 +2806,13 @@ ice_sched_assoc_vsi_to_agg(struct ice_port_info *pi, u32 agg_id,  	if (old_agg_info && old_agg_info != agg_info) {  		struct ice_sched_agg_vsi_info *vtmp; -		list_for_each_entry_safe(old_agg_vsi_info, vtmp, +		list_for_each_entry_safe(iter, vtmp,  					 &old_agg_info->agg_vsi_list,  					 list_entry) -			if (old_agg_vsi_info->vsi_handle == vsi_handle) +			if (iter->vsi_handle == vsi_handle) { +				old_agg_vsi_info = iter;  				break; +			}  	}  	/* check if entry already exist */ diff --git a/drivers/net/ethernet/intel/ice/ice_sriov.c b/drivers/net/ethernet/intel/ice/ice_sriov.c index 96a64c25e2ef..588ad8696756 100644 --- a/drivers/net/ethernet/intel/ice/ice_sriov.c +++ b/drivers/net/ethernet/intel/ice/ice_sriov.c @@ -204,10 +204,7 @@ void ice_free_vfs(struct ice_pf *pf)  		}  		/* clear malicious info since the VF is getting released */ -		if (ice_mbx_clear_malvf(&hw->mbx_snapshot, pf->vfs.malvfs, -					ICE_MAX_SRIOV_VFS, vf->vf_id)) -			dev_dbg(dev, "failed to clear malicious VF state for VF %u\n", -				vf->vf_id); +		list_del(&vf->mbx_info.list_entry);  		mutex_unlock(&vf->cfg_lock);  	} @@ -1017,7 +1014,6 @@ int ice_sriov_configure(struct pci_dev *pdev, int num_vfs)  	if (!num_vfs) {  		if (!pci_vfs_assigned(pdev)) {  			ice_free_vfs(pf); -			ice_mbx_deinit_snapshot(&pf->hw);  			if (pf->lag)  				ice_enable_lag(pf->lag);  			return 0; @@ -1027,16 +1023,10 @@ int ice_sriov_configure(struct pci_dev *pdev, int num_vfs)  		return -EBUSY;  	} -	err = ice_mbx_init_snapshot(&pf->hw, num_vfs); +	err = ice_pci_sriov_ena(pf, num_vfs);  	if (err)  		return err; -	err = ice_pci_sriov_ena(pf, num_vfs); -	if (err) { -		ice_mbx_deinit_snapshot(&pf->hw); -		return err; -	} -  	if (pf->lag)  		ice_disable_lag(pf->lag);  	return num_vfs; @@ -1181,7 +1171,7 @@ int ice_set_vf_spoofchk(struct net_device *netdev, int vf_id, bool ena)  	if (!vf)  		return -EINVAL; -	ret = ice_check_vf_ready_for_cfg(vf); +	ret = ice_check_vf_ready_for_reset(vf);  	if (ret)  		goto out_put_vf; @@ -1296,7 +1286,7 @@ int ice_set_vf_mac(struct net_device *netdev, int vf_id, u8 *mac)  		goto out_put_vf;  	} -	ret = ice_check_vf_ready_for_cfg(vf); +	ret = ice_check_vf_ready_for_reset(vf);  	if (ret)  		goto out_put_vf; @@ -1341,16 +1331,16 @@ int ice_set_vf_trust(struct net_device *netdev, int vf_id, bool trusted)  	struct ice_vf *vf;  	int ret; +	vf = ice_get_vf_by_id(pf, vf_id); +	if (!vf) +		return -EINVAL; +  	if (ice_is_eswitch_mode_switchdev(pf)) {  		dev_info(ice_pf_to_dev(pf), "Trusted VF is forbidden in switchdev mode\n");  		return -EOPNOTSUPP;  	} -	vf = ice_get_vf_by_id(pf, vf_id); -	if (!vf) -		return -EINVAL; - -	ret = ice_check_vf_ready_for_cfg(vf); +	ret = ice_check_vf_ready_for_reset(vf);  	if (ret)  		goto out_put_vf; @@ -1663,7 +1653,7 @@ ice_set_vf_port_vlan(struct net_device *netdev, int vf_id, u16 vlan_id, u8 qos,  	if (!vf)  		return -EINVAL; -	ret = ice_check_vf_ready_for_cfg(vf); +	ret = ice_check_vf_ready_for_reset(vf);  	if (ret)  		goto out_put_vf; @@ -1787,66 +1777,3 @@ void ice_restore_all_vfs_msi_state(struct pci_dev *pdev)  		}  	}  } - -/** - * ice_is_malicious_vf - helper function to detect a malicious VF - * @pf: ptr to struct ice_pf - * @event: pointer to the AQ event - * @num_msg_proc: the number of messages processed so far - * @num_msg_pending: the number of messages peinding in admin queue - */ -bool -ice_is_malicious_vf(struct ice_pf *pf, struct ice_rq_event_info *event, -		    u16 num_msg_proc, u16 num_msg_pending) -{ -	s16 vf_id = le16_to_cpu(event->desc.retval); -	struct device *dev = ice_pf_to_dev(pf); -	struct ice_mbx_data mbxdata; -	bool malvf = false; -	struct ice_vf *vf; -	int status; - -	vf = ice_get_vf_by_id(pf, vf_id); -	if (!vf) -		return false; - -	if (test_bit(ICE_VF_STATE_DIS, vf->vf_states)) -		goto out_put_vf; - -	mbxdata.num_msg_proc = num_msg_proc; -	mbxdata.num_pending_arq = num_msg_pending; -	mbxdata.max_num_msgs_mbx = pf->hw.mailboxq.num_rq_entries; -#define ICE_MBX_OVERFLOW_WATERMARK 64 -	mbxdata.async_watermark_val = ICE_MBX_OVERFLOW_WATERMARK; - -	/* check to see if we have a malicious VF */ -	status = ice_mbx_vf_state_handler(&pf->hw, &mbxdata, vf_id, &malvf); -	if (status) -		goto out_put_vf; - -	if (malvf) { -		bool report_vf = false; - -		/* if the VF is malicious and we haven't let the user -		 * know about it, then let them know now -		 */ -		status = ice_mbx_report_malvf(&pf->hw, pf->vfs.malvfs, -					      ICE_MAX_SRIOV_VFS, vf_id, -					      &report_vf); -		if (status) -			dev_dbg(dev, "Error reporting malicious VF\n"); - -		if (report_vf) { -			struct ice_vsi *pf_vsi = ice_get_main_vsi(pf); - -			if (pf_vsi) -				dev_warn(dev, "VF MAC %pM on PF MAC %pM is generating asynchronous messages and may be overflowing the PF message queue. Please see the Adapter User Guide for more information\n", -					 &vf->dev_lan_addr[0], -					 pf_vsi->netdev->dev_addr); -		} -	} - -out_put_vf: -	ice_put_vf(vf); -	return malvf; -} diff --git a/drivers/net/ethernet/intel/ice/ice_sriov.h b/drivers/net/ethernet/intel/ice/ice_sriov.h index 955ab810a198..346cb2666f3a 100644 --- a/drivers/net/ethernet/intel/ice/ice_sriov.h +++ b/drivers/net/ethernet/intel/ice/ice_sriov.h @@ -33,11 +33,7 @@ int  ice_get_vf_cfg(struct net_device *netdev, int vf_id, struct ifla_vf_info *ivi);  void ice_free_vfs(struct ice_pf *pf); -void ice_vc_process_vf_msg(struct ice_pf *pf, struct ice_rq_event_info *event);  void ice_restore_all_vfs_msi_state(struct pci_dev *pdev); -bool -ice_is_malicious_vf(struct ice_pf *pf, struct ice_rq_event_info *event, -		    u16 num_msg_proc, u16 num_msg_pending);  int  ice_set_vf_port_vlan(struct net_device *netdev, int vf_id, u16 vlan_id, u8 qos, @@ -68,22 +64,11 @@ ice_vc_validate_pattern(struct ice_vf *vf, struct virtchnl_proto_hdrs *proto);  static inline void ice_process_vflr_event(struct ice_pf *pf) { }  static inline void ice_free_vfs(struct ice_pf *pf) { }  static inline -void ice_vc_process_vf_msg(struct ice_pf *pf, struct ice_rq_event_info *event) { } -static inline  void ice_vf_lan_overflow_event(struct ice_pf *pf, struct ice_rq_event_info *event) { }  static inline void ice_print_vfs_mdd_events(struct ice_pf *pf) { }  static inline void ice_print_vf_rx_mdd_event(struct ice_vf *vf) { }  static inline void ice_restore_all_vfs_msi_state(struct pci_dev *pdev) { } -static inline bool -ice_is_malicious_vf(struct ice_pf __always_unused *pf, -		    struct ice_rq_event_info __always_unused *event, -		    u16 __always_unused num_msg_proc, -		    u16 __always_unused num_msg_pending) -{ -	return false; -} -  static inline int  ice_sriov_configure(struct pci_dev __always_unused *pdev,  		    int __always_unused num_vfs) diff --git a/drivers/net/ethernet/intel/ice/ice_switch.c b/drivers/net/ethernet/intel/ice/ice_switch.c index 61f844d22512..46b36851af46 100644 --- a/drivers/net/ethernet/intel/ice/ice_switch.c +++ b/drivers/net/ethernet/intel/ice/ice_switch.c @@ -1780,18 +1780,36 @@ ice_update_vsi(struct ice_hw *hw, u16 vsi_handle, struct ice_vsi_ctx *vsi_ctx,  int  ice_cfg_rdma_fltr(struct ice_hw *hw, u16 vsi_handle, bool enable)  { -	struct ice_vsi_ctx *ctx; +	struct ice_vsi_ctx *ctx, *cached_ctx; +	int status; + +	cached_ctx = ice_get_vsi_ctx(hw, vsi_handle); +	if (!cached_ctx) +		return -ENOENT; -	ctx = ice_get_vsi_ctx(hw, vsi_handle); +	ctx = kzalloc(sizeof(*ctx), GFP_KERNEL);  	if (!ctx) -		return -EIO; +		return -ENOMEM; + +	ctx->info.q_opt_rss = cached_ctx->info.q_opt_rss; +	ctx->info.q_opt_tc = cached_ctx->info.q_opt_tc; +	ctx->info.q_opt_flags = cached_ctx->info.q_opt_flags; + +	ctx->info.valid_sections = cpu_to_le16(ICE_AQ_VSI_PROP_Q_OPT_VALID);  	if (enable)  		ctx->info.q_opt_flags |= ICE_AQ_VSI_Q_OPT_PE_FLTR_EN;  	else  		ctx->info.q_opt_flags &= ~ICE_AQ_VSI_Q_OPT_PE_FLTR_EN; -	return ice_update_vsi(hw, vsi_handle, ctx, NULL); +	status = ice_update_vsi(hw, vsi_handle, ctx, NULL); +	if (!status) { +		cached_ctx->info.q_opt_flags = ctx->info.q_opt_flags; +		cached_ctx->info.valid_sections |= ctx->info.valid_sections; +	} + +	kfree(ctx); +	return status;  }  /** diff --git a/drivers/net/ethernet/intel/ice/ice_tc_lib.c b/drivers/net/ethernet/intel/ice/ice_tc_lib.c index 76f29a5bf8d7..d1a31f236d26 100644 --- a/drivers/net/ethernet/intel/ice/ice_tc_lib.c +++ b/drivers/net/ethernet/intel/ice/ice_tc_lib.c @@ -693,17 +693,18 @@ ice_eswitch_add_tc_fltr(struct ice_vsi *vsi, struct ice_tc_flower_fltr *fltr)  	 * results into order of switch rule evaluation.  	 */  	rule_info.priority = 7; +	rule_info.flags_info.act_valid = true;  	if (fltr->direction == ICE_ESWITCH_FLTR_INGRESS) {  		rule_info.sw_act.flag |= ICE_FLTR_RX;  		rule_info.sw_act.src = hw->pf_id;  		rule_info.rx = true; +		rule_info.flags_info.act = ICE_SINGLE_ACT_LB_ENABLE;  	} else {  		rule_info.sw_act.flag |= ICE_FLTR_TX;  		rule_info.sw_act.src = vsi->idx;  		rule_info.rx = false;  		rule_info.flags_info.act = ICE_SINGLE_ACT_LAN_ENABLE; -		rule_info.flags_info.act_valid = true;  	}  	/* specify the cookie as filter_rule_id */ diff --git a/drivers/net/ethernet/intel/ice/ice_txrx.c b/drivers/net/ethernet/intel/ice/ice_txrx.c index dfd22862e926..52d0a126eb61 100644 --- a/drivers/net/ethernet/intel/ice/ice_txrx.c +++ b/drivers/net/ethernet/intel/ice/ice_txrx.c @@ -938,6 +938,7 @@ ice_reuse_rx_page(struct ice_rx_ring *rx_ring, struct ice_rx_buf *old_buf)   * ice_get_rx_buf - Fetch Rx buffer and synchronize data for use   * @rx_ring: Rx descriptor ring to transact packets on   * @size: size of buffer to add to skb + * @ntc: index of next to clean element   *   * This function will pull an Rx buffer from the ring and synchronize it   * for use by the CPU. @@ -1026,7 +1027,6 @@ ice_build_skb(struct ice_rx_ring *rx_ring, struct xdp_buff *xdp)  /**   * ice_construct_skb - Allocate skb and populate it   * @rx_ring: Rx descriptor ring to transact packets on - * @rx_buf: Rx buffer to pull data from   * @xdp: xdp_buff pointing to the data   *   * This function allocates an skb. It then populates it with the page @@ -1152,11 +1152,11 @@ int ice_clean_rx_irq(struct ice_rx_ring *rx_ring, int budget)  	unsigned int total_rx_bytes = 0, total_rx_pkts = 0;  	unsigned int offset = rx_ring->rx_offset;  	struct xdp_buff *xdp = &rx_ring->xdp; +	u32 cached_ntc = rx_ring->first_desc;  	struct ice_tx_ring *xdp_ring = NULL;  	struct bpf_prog *xdp_prog = NULL;  	u32 ntc = rx_ring->next_to_clean;  	u32 cnt = rx_ring->count; -	u32 cached_ntc = ntc;  	u32 xdp_xmit = 0;  	u32 cached_ntu;  	bool failure; @@ -1210,6 +1210,7 @@ int ice_clean_rx_irq(struct ice_rx_ring *rx_ring, int budget)  				ice_vc_fdir_irq_handler(ctrl_vsi, rx_desc);  			if (++ntc == cnt)  				ntc = 0; +			rx_ring->first_desc = ntc;  			continue;  		} @@ -1663,8 +1664,7 @@ ice_tx_map(struct ice_tx_ring *tx_ring, struct ice_tx_buf *first,  	if (first->tx_flags & ICE_TX_FLAGS_HW_VLAN) {  		td_cmd |= (u64)ICE_TX_DESC_CMD_IL2TAG1; -		td_tag = (first->tx_flags & ICE_TX_FLAGS_VLAN_M) >> -			  ICE_TX_FLAGS_VLAN_S; +		td_tag = first->vid;  	}  	dma = dma_map_single(tx_ring->dev, skb->data, size, DMA_TO_DEVICE); @@ -1997,7 +1997,7 @@ ice_tx_prepare_vlan_flags(struct ice_tx_ring *tx_ring, struct ice_tx_buf *first)  	 * VLAN offloads exclusively so we only care about the VLAN ID here  	 */  	if (skb_vlan_tag_present(skb)) { -		first->tx_flags |= skb_vlan_tag_get(skb) << ICE_TX_FLAGS_VLAN_S; +		first->vid = skb_vlan_tag_get(skb);  		if (tx_ring->flags & ICE_TX_FLAGS_RING_VLAN_L2TAG2)  			first->tx_flags |= ICE_TX_FLAGS_HW_OUTER_SINGLE_VLAN;  		else @@ -2387,8 +2387,7 @@ ice_xmit_frame_ring(struct sk_buff *skb, struct ice_tx_ring *tx_ring)  		offload.cd_qw1 |= (u64)(ICE_TX_DESC_DTYPE_CTX |  					(ICE_TX_CTX_DESC_IL2TAG2 <<  					ICE_TXD_CTX_QW1_CMD_S)); -		offload.cd_l2tag2 = (first->tx_flags & ICE_TX_FLAGS_VLAN_M) >> -			ICE_TX_FLAGS_VLAN_S; +		offload.cd_l2tag2 = first->vid;  	}  	/* set up TSO offload */ diff --git a/drivers/net/ethernet/intel/ice/ice_txrx.h b/drivers/net/ethernet/intel/ice/ice_txrx.h index fff0efe28373..166413fc33f4 100644 --- a/drivers/net/ethernet/intel/ice/ice_txrx.h +++ b/drivers/net/ethernet/intel/ice/ice_txrx.h @@ -127,10 +127,6 @@ static inline int ice_skb_pad(void)  #define ICE_TX_FLAGS_IPV6	BIT(6)  #define ICE_TX_FLAGS_TUNNEL	BIT(7)  #define ICE_TX_FLAGS_HW_OUTER_SINGLE_VLAN	BIT(8) -#define ICE_TX_FLAGS_VLAN_M	0xffff0000 -#define ICE_TX_FLAGS_VLAN_PR_M	0xe0000000 -#define ICE_TX_FLAGS_VLAN_PR_S	29 -#define ICE_TX_FLAGS_VLAN_S	16  #define ICE_XDP_PASS		0  #define ICE_XDP_CONSUMED	BIT(0) @@ -182,8 +178,9 @@ struct ice_tx_buf {  		unsigned int gso_segs;  		unsigned int nr_frags;	/* used for mbuf XDP */  	}; -	u32 type:16;			/* &ice_tx_buf_type */ -	u32 tx_flags:16; +	u32 tx_flags:12; +	u32 type:4;			/* &ice_tx_buf_type */ +	u32 vid:16;  	DEFINE_DMA_UNMAP_LEN(len);  	DEFINE_DMA_UNMAP_ADDR(dma);  }; diff --git a/drivers/net/ethernet/intel/ice/ice_txrx_lib.c b/drivers/net/ethernet/intel/ice/ice_txrx_lib.c index 7bc5aa340c7d..c8322fb6f2b3 100644 --- a/drivers/net/ethernet/intel/ice/ice_txrx_lib.c +++ b/drivers/net/ethernet/intel/ice/ice_txrx_lib.c @@ -438,6 +438,7 @@ busy:   * ice_finalize_xdp_rx - Bump XDP Tx tail and/or flush redirect map   * @xdp_ring: XDP ring   * @xdp_res: Result of the receive batch + * @first_idx: index to write from caller   *   * This function bumps XDP Tx tail and/or flush redirect map, and   * should be called when a batch of packets has been processed in the diff --git a/drivers/net/ethernet/intel/ice/ice_type.h b/drivers/net/ethernet/intel/ice/ice_type.h index e3f622cad425..a09556e57803 100644 --- a/drivers/net/ethernet/intel/ice/ice_type.h +++ b/drivers/net/ethernet/intel/ice/ice_type.h @@ -784,14 +784,15 @@ struct ice_mbx_snap_buffer_data {  	u16 max_num_msgs_mbx;  }; -/* Structure to track messages sent by VFs on mailbox: - * 1. vf_cntr: a counter array of VFs to track the number of - * asynchronous messages sent by each VF - * 2. vfcntr_len: number of entries in VF counter array +/* Structure used to track a single VF's messages on the mailbox: + * 1. list_entry: linked list entry node + * 2. msg_count: the number of asynchronous messages sent by this VF + * 3. malicious: whether this VF has been detected as malicious before   */ -struct ice_mbx_vf_counter { -	u32 *vf_cntr; -	u32 vfcntr_len; +struct ice_mbx_vf_info { +	struct list_head list_entry; +	u32 msg_count; +	u8 malicious : 1;  };  /* Structure to hold data relevant to the captured static snapshot @@ -799,7 +800,7 @@ struct ice_mbx_vf_counter {   */  struct ice_mbx_snapshot {  	struct ice_mbx_snap_buffer_data mbx_buf; -	struct ice_mbx_vf_counter mbx_vf; +	struct list_head mbx_vf;  };  /* Structure to hold data to be used for capturing or updating a diff --git a/drivers/net/ethernet/intel/ice/ice_vf_lib.c b/drivers/net/ethernet/intel/ice/ice_vf_lib.c index 0e57bd1b85fd..bf74a2f3a4f8 100644 --- a/drivers/net/ethernet/intel/ice/ice_vf_lib.c +++ b/drivers/net/ethernet/intel/ice/ice_vf_lib.c @@ -186,6 +186,25 @@ int ice_check_vf_ready_for_cfg(struct ice_vf *vf)  }  /** + * ice_check_vf_ready_for_reset - check if VF is ready to be reset + * @vf: VF to check if it's ready to be reset + * + * The purpose of this function is to ensure that the VF is not in reset, + * disabled, and is both initialized and active, thus enabling us to safely + * initialize another reset. + */ +int ice_check_vf_ready_for_reset(struct ice_vf *vf) +{ +	int ret; + +	ret = ice_check_vf_ready_for_cfg(vf); +	if (!ret && !test_bit(ICE_VF_STATE_ACTIVE, vf->vf_states)) +		ret = -EAGAIN; + +	return ret; +} + +/**   * ice_trigger_vf_reset - Reset a VF on HW   * @vf: pointer to the VF structure   * @is_vflr: true if VFLR was issued, false if not @@ -496,10 +515,7 @@ void ice_reset_all_vfs(struct ice_pf *pf)  	/* clear all malicious info if the VFs are getting reset */  	ice_for_each_vf(pf, bkt, vf) -		if (ice_mbx_clear_malvf(&hw->mbx_snapshot, pf->vfs.malvfs, -					ICE_MAX_SRIOV_VFS, vf->vf_id)) -			dev_dbg(dev, "failed to clear malicious VF state for VF %u\n", -				vf->vf_id); +		ice_mbx_clear_malvf(&vf->mbx_info);  	/* If VFs have been disabled, there is no need to reset */  	if (test_and_set_bit(ICE_VF_DIS, pf->state)) { @@ -601,12 +617,10 @@ int ice_reset_vf(struct ice_vf *vf, u32 flags)  	struct ice_pf *pf = vf->pf;  	struct ice_vsi *vsi;  	struct device *dev; -	struct ice_hw *hw;  	int err = 0;  	bool rsd;  	dev = ice_pf_to_dev(pf); -	hw = &pf->hw;  	if (flags & ICE_VF_RESET_NOTIFY)  		ice_notify_vf_reset(vf); @@ -705,10 +719,7 @@ int ice_reset_vf(struct ice_vf *vf, u32 flags)  	ice_eswitch_replay_vf_mac_rule(vf);  	/* if the VF has been reset allow it to come up again */ -	if (ice_mbx_clear_malvf(&hw->mbx_snapshot, pf->vfs.malvfs, -				ICE_MAX_SRIOV_VFS, vf->vf_id)) -		dev_dbg(dev, "failed to clear malicious VF state for VF %u\n", -			vf->vf_id); +	ice_mbx_clear_malvf(&vf->mbx_info);  out_unlock:  	if (flags & ICE_VF_RESET_LOCK) @@ -764,6 +775,9 @@ void ice_initialize_vf_entry(struct ice_vf *vf)  	ice_vf_ctrl_invalidate_vsi(vf);  	ice_vf_fdir_init(vf); +	/* Initialize mailbox info for this VF */ +	ice_mbx_init_vf_info(&pf->hw, &vf->mbx_info); +  	mutex_init(&vf->cfg_lock);  } diff --git a/drivers/net/ethernet/intel/ice/ice_vf_lib.h b/drivers/net/ethernet/intel/ice/ice_vf_lib.h index ef30f05b5d02..a38ef00a3679 100644 --- a/drivers/net/ethernet/intel/ice/ice_vf_lib.h +++ b/drivers/net/ethernet/intel/ice/ice_vf_lib.h @@ -74,7 +74,6 @@ struct ice_vfs {  	u16 num_qps_per;		/* number of queue pairs per VF */  	u16 num_msix_per;		/* number of MSI-X vectors per VF */  	unsigned long last_printed_mdd_jiffies;	/* MDD message rate limit */ -	DECLARE_BITMAP(malvfs, ICE_MAX_SRIOV_VFS); /* malicious VF indicator */  };  /* VF information structure */ @@ -105,6 +104,7 @@ struct ice_vf {  	DECLARE_BITMAP(rxq_ena, ICE_MAX_RSS_QS_PER_VF);  	struct ice_vlan port_vlan_info;	/* Port VLAN ID, QoS, and TPID */  	struct virtchnl_vlan_caps vlan_v2_caps; +	struct ice_mbx_vf_info mbx_info;  	u8 pf_set_mac:1;		/* VF MAC address set by VMM admin */  	u8 trusted:1;  	u8 spoofchk:1; @@ -215,6 +215,7 @@ u16 ice_get_num_vfs(struct ice_pf *pf);  struct ice_vsi *ice_get_vf_vsi(struct ice_vf *vf);  bool ice_is_vf_disabled(struct ice_vf *vf);  int ice_check_vf_ready_for_cfg(struct ice_vf *vf); +int ice_check_vf_ready_for_reset(struct ice_vf *vf);  void ice_set_vf_state_dis(struct ice_vf *vf);  bool ice_is_any_vf_in_unicast_promisc(struct ice_pf *pf);  void diff --git a/drivers/net/ethernet/intel/ice/ice_vf_mbx.c b/drivers/net/ethernet/intel/ice/ice_vf_mbx.c index f56fa94ff3d0..40cb4ba0789c 100644 --- a/drivers/net/ethernet/intel/ice/ice_vf_mbx.c +++ b/drivers/net/ethernet/intel/ice/ice_vf_mbx.c @@ -93,36 +93,31 @@ u32 ice_conv_link_speed_to_virtchnl(bool adv_link_support, u16 link_speed)   *   * 2. When the caller starts processing its mailbox queue in response to an   * interrupt, the structure ice_mbx_snapshot is expected to be cleared before - * the algorithm can be run for the first time for that interrupt. This can be - * done via ice_mbx_reset_snapshot(). + * the algorithm can be run for the first time for that interrupt. This + * requires calling ice_mbx_reset_snapshot() as well as calling + * ice_mbx_reset_vf_info() for each VF tracking structure.   *   * 3. For every message read by the caller from the MBX Queue, the caller must   * call the detection algorithm's entry function ice_mbx_vf_state_handler().   * Before every call to ice_mbx_vf_state_handler() the struct ice_mbx_data is   * filled as it is required to be passed to the algorithm.   * - * 4. Every time a message is read from the MBX queue, a VFId is received which - * is passed to the state handler. The boolean output is_malvf of the state - * handler ice_mbx_vf_state_handler() serves as an indicator to the caller - * whether this VF is malicious or not. + * 4. Every time a message is read from the MBX queue, a tracking structure + * for the VF must be passed to the state handler. The boolean output + * report_malvf from ice_mbx_vf_state_handler() serves as an indicator to the + * caller whether it must report this VF as malicious or not.   *   * 5. When a VF is identified to be malicious, the caller can send a message - * to the system administrator. The caller can invoke ice_mbx_report_malvf() - * to help determine if a malicious VF is to be reported or not. This function - * requires the caller to maintain a global bitmap to track all malicious VFs - * and pass that to ice_mbx_report_malvf() along with the VFID which was identified - * to be malicious by ice_mbx_vf_state_handler(). + * to the system administrator.   * - * 6. The global bitmap maintained by PF can be cleared completely if PF is in - * reset or the bit corresponding to a VF can be cleared if that VF is in reset. - * When a VF is shut down and brought back up, we assume that the new VF - * brought up is not malicious and hence report it if found malicious. + * 6. The PF is responsible for maintaining the struct ice_mbx_vf_info + * structure for each VF. The PF should clear the VF tracking structure if the + * VF is reset. When a VF is shut down and brought back up, we will then + * assume that the new VF is not malicious and may report it again if we + * detect it again.   *   * 7. The function ice_mbx_reset_snapshot() is called to reset the information   * in ice_mbx_snapshot for every new mailbox interrupt handled. - * - * 8. The memory allocated for variables in ice_mbx_snapshot is de-allocated - * when driver is unloaded.   */  #define ICE_RQ_DATA_MASK(rq_data) ((rq_data) & PF_MBX_ARQH_ARQH_M)  /* Using the highest value for an unsigned 16-bit value 0xFFFF to indicate that @@ -131,6 +126,25 @@ u32 ice_conv_link_speed_to_virtchnl(bool adv_link_support, u16 link_speed)  #define ICE_IGNORE_MAX_MSG_CNT	0xFFFF  /** + * ice_mbx_reset_snapshot - Reset mailbox snapshot structure + * @snap: pointer to the mailbox snapshot + */ +static void ice_mbx_reset_snapshot(struct ice_mbx_snapshot *snap) +{ +	struct ice_mbx_vf_info *vf_info; + +	/* Clear mbx_buf in the mailbox snaphot structure and setting the +	 * mailbox snapshot state to a new capture. +	 */ +	memset(&snap->mbx_buf, 0, sizeof(snap->mbx_buf)); +	snap->mbx_buf.state = ICE_MAL_VF_DETECT_STATE_NEW_SNAPSHOT; + +	/* Reset message counts for all VFs to zero */ +	list_for_each_entry(vf_info, &snap->mbx_vf, list_entry) +		vf_info->msg_count = 0; +} + +/**   * ice_mbx_traverse - Pass through mailbox snapshot   * @hw: pointer to the HW struct   * @new_state: new algorithm state @@ -171,7 +185,7 @@ ice_mbx_traverse(struct ice_hw *hw,  /**   * ice_mbx_detect_malvf - Detect malicious VF in snapshot   * @hw: pointer to the HW struct - * @vf_id: relative virtual function ID + * @vf_info: mailbox tracking structure for a VF   * @new_state: new algorithm state   * @is_malvf: boolean output to indicate if VF is malicious   * @@ -180,19 +194,14 @@ ice_mbx_traverse(struct ice_hw *hw,   * the permissible number of messages to send.   */  static int -ice_mbx_detect_malvf(struct ice_hw *hw, u16 vf_id, +ice_mbx_detect_malvf(struct ice_hw *hw, struct ice_mbx_vf_info *vf_info,  		     enum ice_mbx_snapshot_state *new_state,  		     bool *is_malvf)  { -	struct ice_mbx_snapshot *snap = &hw->mbx_snapshot; - -	if (vf_id >= snap->mbx_vf.vfcntr_len) -		return -EIO; - -	/* increment the message count in the VF array */ -	snap->mbx_vf.vf_cntr[vf_id]++; +	/* increment the message count for this VF */ +	vf_info->msg_count++; -	if (snap->mbx_vf.vf_cntr[vf_id] >= ICE_ASYNC_VF_MSG_THRESHOLD) +	if (vf_info->msg_count >= ICE_ASYNC_VF_MSG_THRESHOLD)  		*is_malvf = true;  	/* continue to iterate through the mailbox snapshot */ @@ -202,35 +211,11 @@ ice_mbx_detect_malvf(struct ice_hw *hw, u16 vf_id,  }  /** - * ice_mbx_reset_snapshot - Reset mailbox snapshot structure - * @snap: pointer to mailbox snapshot structure in the ice_hw struct - * - * Reset the mailbox snapshot structure and clear VF counter array. - */ -static void ice_mbx_reset_snapshot(struct ice_mbx_snapshot *snap) -{ -	u32 vfcntr_len; - -	if (!snap || !snap->mbx_vf.vf_cntr) -		return; - -	/* Clear VF counters. */ -	vfcntr_len = snap->mbx_vf.vfcntr_len; -	if (vfcntr_len) -		memset(snap->mbx_vf.vf_cntr, 0, -		       (vfcntr_len * sizeof(*snap->mbx_vf.vf_cntr))); - -	/* Reset mailbox snapshot for a new capture. */ -	memset(&snap->mbx_buf, 0, sizeof(snap->mbx_buf)); -	snap->mbx_buf.state = ICE_MAL_VF_DETECT_STATE_NEW_SNAPSHOT; -} - -/**   * ice_mbx_vf_state_handler - Handle states of the overflow algorithm   * @hw: pointer to the HW struct   * @mbx_data: pointer to structure containing mailbox data - * @vf_id: relative virtual function (VF) ID - * @is_malvf: boolean output to indicate if VF is malicious + * @vf_info: mailbox tracking structure for the VF in question + * @report_malvf: boolean output to indicate whether VF should be reported   *   * The function serves as an entry point for the malicious VF   * detection algorithm by handling the different states and state @@ -249,24 +234,24 @@ static void ice_mbx_reset_snapshot(struct ice_mbx_snapshot *snap)   * the static snapshot and look for a malicious VF.   */  int -ice_mbx_vf_state_handler(struct ice_hw *hw, -			 struct ice_mbx_data *mbx_data, u16 vf_id, -			 bool *is_malvf) +ice_mbx_vf_state_handler(struct ice_hw *hw, struct ice_mbx_data *mbx_data, +			 struct ice_mbx_vf_info *vf_info, bool *report_malvf)  {  	struct ice_mbx_snapshot *snap = &hw->mbx_snapshot;  	struct ice_mbx_snap_buffer_data *snap_buf;  	struct ice_ctl_q_info *cq = &hw->mailboxq;  	enum ice_mbx_snapshot_state new_state; +	bool is_malvf = false;  	int status = 0; -	if (!is_malvf || !mbx_data) +	if (!report_malvf || !mbx_data || !vf_info)  		return -EINVAL; +	*report_malvf = false; +  	/* When entering the mailbox state machine assume that the VF  	 * is not malicious until detected.  	 */ -	*is_malvf = false; -  	 /* Checking if max messages allowed to be processed while servicing current  	  * interrupt is not less than the defined AVF message threshold.  	  */ @@ -315,7 +300,7 @@ ice_mbx_vf_state_handler(struct ice_hw *hw,  		if (snap_buf->num_pending_arq >=  		    mbx_data->async_watermark_val) {  			new_state = ICE_MAL_VF_DETECT_STATE_DETECT; -			status = ice_mbx_detect_malvf(hw, vf_id, &new_state, is_malvf); +			status = ice_mbx_detect_malvf(hw, vf_info, &new_state, &is_malvf);  		} else {  			new_state = ICE_MAL_VF_DETECT_STATE_TRAVERSE;  			ice_mbx_traverse(hw, &new_state); @@ -329,7 +314,7 @@ ice_mbx_vf_state_handler(struct ice_hw *hw,  	case ICE_MAL_VF_DETECT_STATE_DETECT:  		new_state = ICE_MAL_VF_DETECT_STATE_DETECT; -		status = ice_mbx_detect_malvf(hw, vf_id, &new_state, is_malvf); +		status = ice_mbx_detect_malvf(hw, vf_info, &new_state, &is_malvf);  		break;  	default: @@ -339,145 +324,57 @@ ice_mbx_vf_state_handler(struct ice_hw *hw,  	snap_buf->state = new_state; -	return status; -} - -/** - * ice_mbx_report_malvf - Track and note malicious VF - * @hw: pointer to the HW struct - * @all_malvfs: all malicious VFs tracked by PF - * @bitmap_len: length of bitmap in bits - * @vf_id: relative virtual function ID of the malicious VF - * @report_malvf: boolean to indicate if malicious VF must be reported - * - * This function will update a bitmap that keeps track of the malicious - * VFs attached to the PF. A malicious VF must be reported only once if - * discovered between VF resets or loading so the function checks - * the input vf_id against the bitmap to verify if the VF has been - * detected in any previous mailbox iterations. - */ -int -ice_mbx_report_malvf(struct ice_hw *hw, unsigned long *all_malvfs, -		     u16 bitmap_len, u16 vf_id, bool *report_malvf) -{ -	if (!all_malvfs || !report_malvf) -		return -EINVAL; - -	*report_malvf = false; - -	if (bitmap_len < hw->mbx_snapshot.mbx_vf.vfcntr_len) -		return -EINVAL; - -	if (vf_id >= bitmap_len) -		return -EIO; - -	/* If the vf_id is found in the bitmap set bit and boolean to true */ -	if (!test_and_set_bit(vf_id, all_malvfs)) +	/* Only report VFs as malicious the first time we detect it */ +	if (is_malvf && !vf_info->malicious) { +		vf_info->malicious = 1;  		*report_malvf = true; +	} -	return 0; +	return status;  }  /** - * ice_mbx_clear_malvf - Clear VF bitmap and counter for VF ID - * @snap: pointer to the mailbox snapshot structure - * @all_malvfs: all malicious VFs tracked by PF - * @bitmap_len: length of bitmap in bits - * @vf_id: relative virtual function ID of the malicious VF + * ice_mbx_clear_malvf - Clear VF mailbox info + * @vf_info: the mailbox tracking structure for a VF   * - * In case of a VF reset, this function can be called to clear - * the bit corresponding to the VF ID in the bitmap tracking all - * malicious VFs attached to the PF. The function also clears the - * VF counter array at the index of the VF ID. This is to ensure - * that the new VF loaded is not considered malicious before going - * through the overflow detection algorithm. + * In case of a VF reset, this function shall be called to clear the VF's + * current mailbox tracking state.   */ -int -ice_mbx_clear_malvf(struct ice_mbx_snapshot *snap, unsigned long *all_malvfs, -		    u16 bitmap_len, u16 vf_id) +void ice_mbx_clear_malvf(struct ice_mbx_vf_info *vf_info)  { -	if (!snap || !all_malvfs) -		return -EINVAL; - -	if (bitmap_len < snap->mbx_vf.vfcntr_len) -		return -EINVAL; - -	/* Ensure VF ID value is not larger than bitmap or VF counter length */ -	if (vf_id >= bitmap_len || vf_id >= snap->mbx_vf.vfcntr_len) -		return -EIO; - -	/* Clear VF ID bit in the bitmap tracking malicious VFs attached to PF */ -	clear_bit(vf_id, all_malvfs); - -	/* Clear the VF counter in the mailbox snapshot structure for that VF ID. -	 * This is to ensure that if a VF is unloaded and a new one brought back -	 * up with the same VF ID for a snapshot currently in traversal or detect -	 * state the counter for that VF ID does not increment on top of existing -	 * values in the mailbox overflow detection algorithm. -	 */ -	snap->mbx_vf.vf_cntr[vf_id] = 0; - -	return 0; +	vf_info->malicious = 0; +	vf_info->msg_count = 0;  }  /** - * ice_mbx_init_snapshot - Initialize mailbox snapshot structure + * ice_mbx_init_vf_info - Initialize a new VF mailbox tracking info   * @hw: pointer to the hardware structure - * @vf_count: number of VFs allocated on a PF + * @vf_info: the mailbox tracking info structure for a VF   * - * Clear the mailbox snapshot structure and allocate memory - * for the VF counter array based on the number of VFs allocated - * on that PF. + * Initialize a VF mailbox tracking info structure and insert it into the + * snapshot list.   * - * Assumption: This function will assume ice_get_caps() has already been - * called to ensure that the vf_count can be compared against the number - * of VFs supported as defined in the functional capabilities of the device. + * If you remove the VF, you must also delete the associated VF info structure + * from the linked list.   */ -int ice_mbx_init_snapshot(struct ice_hw *hw, u16 vf_count) +void ice_mbx_init_vf_info(struct ice_hw *hw, struct ice_mbx_vf_info *vf_info)  {  	struct ice_mbx_snapshot *snap = &hw->mbx_snapshot; -	/* Ensure that the number of VFs allocated is non-zero and -	 * is not greater than the number of supported VFs defined in -	 * the functional capabilities of the PF. -	 */ -	if (!vf_count || vf_count > hw->func_caps.num_allocd_vfs) -		return -EINVAL; - -	snap->mbx_vf.vf_cntr = devm_kcalloc(ice_hw_to_dev(hw), vf_count, -					    sizeof(*snap->mbx_vf.vf_cntr), -					    GFP_KERNEL); -	if (!snap->mbx_vf.vf_cntr) -		return -ENOMEM; - -	/* Setting the VF counter length to the number of allocated -	 * VFs for given PF's functional capabilities. -	 */ -	snap->mbx_vf.vfcntr_len = vf_count; - -	/* Clear mbx_buf in the mailbox snaphot structure and setting the -	 * mailbox snapshot state to a new capture. -	 */ -	memset(&snap->mbx_buf, 0, sizeof(snap->mbx_buf)); -	snap->mbx_buf.state = ICE_MAL_VF_DETECT_STATE_NEW_SNAPSHOT; - -	return 0; +	ice_mbx_clear_malvf(vf_info); +	list_add(&vf_info->list_entry, &snap->mbx_vf);  }  /** - * ice_mbx_deinit_snapshot - Free mailbox snapshot structure + * ice_mbx_init_snapshot - Initialize mailbox snapshot data   * @hw: pointer to the hardware structure   * - * Clear the mailbox snapshot structure and free the VF counter array. + * Clear the mailbox snapshot structure and initialize the VF mailbox list.   */ -void ice_mbx_deinit_snapshot(struct ice_hw *hw) +void ice_mbx_init_snapshot(struct ice_hw *hw)  {  	struct ice_mbx_snapshot *snap = &hw->mbx_snapshot; -	/* Free VF counter array and reset VF counter length */ -	devm_kfree(ice_hw_to_dev(hw), snap->mbx_vf.vf_cntr); -	snap->mbx_vf.vfcntr_len = 0; - -	/* Clear mbx_buf in the mailbox snaphot structure */ -	memset(&snap->mbx_buf, 0, sizeof(snap->mbx_buf)); +	INIT_LIST_HEAD(&snap->mbx_vf); +	ice_mbx_reset_snapshot(snap);  } diff --git a/drivers/net/ethernet/intel/ice/ice_vf_mbx.h b/drivers/net/ethernet/intel/ice/ice_vf_mbx.h index 582716e6d5f9..44bc030d17e0 100644 --- a/drivers/net/ethernet/intel/ice/ice_vf_mbx.h +++ b/drivers/net/ethernet/intel/ice/ice_vf_mbx.h @@ -21,15 +21,10 @@ ice_aq_send_msg_to_vf(struct ice_hw *hw, u16 vfid, u32 v_opcode, u32 v_retval,  u32 ice_conv_link_speed_to_virtchnl(bool adv_link_support, u16 link_speed);  int  ice_mbx_vf_state_handler(struct ice_hw *hw, struct ice_mbx_data *mbx_data, -			 u16 vf_id, bool *is_mal_vf); -int -ice_mbx_clear_malvf(struct ice_mbx_snapshot *snap, unsigned long *all_malvfs, -		    u16 bitmap_len, u16 vf_id); -int ice_mbx_init_snapshot(struct ice_hw *hw, u16 vf_count); -void ice_mbx_deinit_snapshot(struct ice_hw *hw); -int -ice_mbx_report_malvf(struct ice_hw *hw, unsigned long *all_malvfs, -		     u16 bitmap_len, u16 vf_id, bool *report_malvf); +			 struct ice_mbx_vf_info *vf_info, bool *report_malvf); +void ice_mbx_clear_malvf(struct ice_mbx_vf_info *vf_info); +void ice_mbx_init_vf_info(struct ice_hw *hw, struct ice_mbx_vf_info *vf_info); +void ice_mbx_init_snapshot(struct ice_hw *hw);  #else /* CONFIG_PCI_IOV */  static inline int  ice_aq_send_msg_to_vf(struct ice_hw __always_unused *hw, @@ -48,5 +43,9 @@ ice_conv_link_speed_to_virtchnl(bool __always_unused adv_link_support,  	return 0;  } +static inline void ice_mbx_init_snapshot(struct ice_hw *hw) +{ +} +  #endif /* CONFIG_PCI_IOV */  #endif /* _ICE_VF_MBX_H_ */ diff --git a/drivers/net/ethernet/intel/ice/ice_virtchnl.c b/drivers/net/ethernet/intel/ice/ice_virtchnl.c index e24e3f5017ca..f4a524f80b11 100644 --- a/drivers/net/ethernet/intel/ice/ice_virtchnl.c +++ b/drivers/net/ethernet/intel/ice/ice_virtchnl.c @@ -3834,14 +3834,57 @@ void ice_virtchnl_set_repr_ops(struct ice_vf *vf)  }  /** + * ice_is_malicious_vf - check if this vf might be overflowing mailbox + * @vf: the VF to check + * @mbxdata: data about the state of the mailbox + * + * Detect if a given VF might be malicious and attempting to overflow the PF + * mailbox. If so, log a warning message and ignore this event. + */ +static bool +ice_is_malicious_vf(struct ice_vf *vf, struct ice_mbx_data *mbxdata) +{ +	bool report_malvf = false; +	struct device *dev; +	struct ice_pf *pf; +	int status; + +	pf = vf->pf; +	dev = ice_pf_to_dev(pf); + +	if (test_bit(ICE_VF_STATE_DIS, vf->vf_states)) +		return vf->mbx_info.malicious; + +	/* check to see if we have a newly malicious VF */ +	status = ice_mbx_vf_state_handler(&pf->hw, mbxdata, &vf->mbx_info, +					  &report_malvf); +	if (status) +		dev_warn_ratelimited(dev, "Unable to check status of mailbox overflow for VF %u MAC %pM, status %d\n", +				     vf->vf_id, vf->dev_lan_addr, status); + +	if (report_malvf) { +		struct ice_vsi *pf_vsi = ice_get_main_vsi(pf); +		u8 zero_addr[ETH_ALEN] = {}; + +		dev_warn(dev, "VF MAC %pM on PF MAC %pM is generating asynchronous messages and may be overflowing the PF message queue. Please see the Adapter User Guide for more information\n", +			 vf->dev_lan_addr, +			 pf_vsi ? pf_vsi->netdev->dev_addr : zero_addr); +	} + +	return vf->mbx_info.malicious; +} + +/**   * ice_vc_process_vf_msg - Process request from VF   * @pf: pointer to the PF structure   * @event: pointer to the AQ event + * @mbxdata: information used to detect VF attempting mailbox overflow   *   * called from the common asq/arq handler to   * process request from VF   */ -void ice_vc_process_vf_msg(struct ice_pf *pf, struct ice_rq_event_info *event) +void ice_vc_process_vf_msg(struct ice_pf *pf, struct ice_rq_event_info *event, +			   struct ice_mbx_data *mbxdata)  {  	u32 v_opcode = le32_to_cpu(event->desc.cookie_high);  	s16 vf_id = le16_to_cpu(event->desc.retval); @@ -3863,6 +3906,10 @@ void ice_vc_process_vf_msg(struct ice_pf *pf, struct ice_rq_event_info *event)  	mutex_lock(&vf->cfg_lock); +	/* Check if the VF is trying to overflow the mailbox */ +	if (ice_is_malicious_vf(vf, mbxdata)) +		goto finish; +  	/* Check if VF is disabled. */  	if (test_bit(ICE_VF_STATE_DIS, vf->vf_states)) {  		err = -EPERM; @@ -3908,6 +3955,7 @@ error_handler:  		ice_vc_notify_vf_link_state(vf);  		break;  	case VIRTCHNL_OP_RESET_VF: +		clear_bit(ICE_VF_STATE_ACTIVE, vf->vf_states);  		ops->reset_vf(vf);  		break;  	case VIRTCHNL_OP_ADD_ETH_ADDR: diff --git a/drivers/net/ethernet/intel/ice/ice_virtchnl.h b/drivers/net/ethernet/intel/ice/ice_virtchnl.h index b454654d7b0c..cd747718de73 100644 --- a/drivers/net/ethernet/intel/ice/ice_virtchnl.h +++ b/drivers/net/ethernet/intel/ice/ice_virtchnl.h @@ -63,6 +63,8 @@ int  ice_vc_send_msg_to_vf(struct ice_vf *vf, u32 v_opcode,  		      enum virtchnl_status_code v_retval, u8 *msg, u16 msglen);  bool ice_vc_isvalid_vsi_id(struct ice_vf *vf, u16 vsi_id); +void ice_vc_process_vf_msg(struct ice_pf *pf, struct ice_rq_event_info *event, +			   struct ice_mbx_data *mbxdata);  #else /* CONFIG_PCI_IOV */  static inline void ice_virtchnl_set_dflt_ops(struct ice_vf *vf) { }  static inline void ice_virtchnl_set_repr_ops(struct ice_vf *vf) { } @@ -81,6 +83,12 @@ static inline bool ice_vc_isvalid_vsi_id(struct ice_vf *vf, u16 vsi_id)  {  	return false;  } + +static inline void +ice_vc_process_vf_msg(struct ice_pf *pf, struct ice_rq_event_info *event, +		      struct ice_mbx_data *mbxdata) +{ +}  #endif /* !CONFIG_PCI_IOV */  #endif /* _ICE_VIRTCHNL_H_ */ diff --git a/drivers/net/ethernet/intel/ice/ice_virtchnl_fdir.c b/drivers/net/ethernet/intel/ice/ice_virtchnl_fdir.c index e6ef6b303222..daa6a1e894cf 100644 --- a/drivers/net/ethernet/intel/ice/ice_virtchnl_fdir.c +++ b/drivers/net/ethernet/intel/ice/ice_virtchnl_fdir.c @@ -542,6 +542,87 @@ static void ice_vc_fdir_rem_prof_all(struct ice_vf *vf)  }  /** + * ice_vc_fdir_reset_cnt_all - reset all FDIR counters for this VF FDIR + * @fdir: pointer to the VF FDIR structure + */ +static void ice_vc_fdir_reset_cnt_all(struct ice_vf_fdir *fdir) +{ +	enum ice_fltr_ptype flow; + +	for (flow = ICE_FLTR_PTYPE_NONF_NONE; +	     flow < ICE_FLTR_PTYPE_MAX; flow++) { +		fdir->fdir_fltr_cnt[flow][0] = 0; +		fdir->fdir_fltr_cnt[flow][1] = 0; +	} +} + +/** + * ice_vc_fdir_has_prof_conflict + * @vf: pointer to the VF structure + * @conf: FDIR configuration for each filter + * + * Check if @conf has conflicting profile with existing profiles + * + * Return: true on success, and false on error. + */ +static bool +ice_vc_fdir_has_prof_conflict(struct ice_vf *vf, +			      struct virtchnl_fdir_fltr_conf *conf) +{ +	struct ice_fdir_fltr *desc; + +	list_for_each_entry(desc, &vf->fdir.fdir_rule_list, fltr_node) { +		struct virtchnl_fdir_fltr_conf *existing_conf; +		enum ice_fltr_ptype flow_type_a, flow_type_b; +		struct ice_fdir_fltr *a, *b; + +		existing_conf = to_fltr_conf_from_desc(desc); +		a = &existing_conf->input; +		b = &conf->input; +		flow_type_a = a->flow_type; +		flow_type_b = b->flow_type; + +		/* No need to compare two rules with different tunnel types or +		 * with the same protocol type. +		 */ +		if (existing_conf->ttype != conf->ttype || +		    flow_type_a == flow_type_b) +			continue; + +		switch (flow_type_a) { +		case ICE_FLTR_PTYPE_NONF_IPV4_UDP: +		case ICE_FLTR_PTYPE_NONF_IPV4_TCP: +		case ICE_FLTR_PTYPE_NONF_IPV4_SCTP: +			if (flow_type_b == ICE_FLTR_PTYPE_NONF_IPV4_OTHER) +				return true; +			break; +		case ICE_FLTR_PTYPE_NONF_IPV4_OTHER: +			if (flow_type_b == ICE_FLTR_PTYPE_NONF_IPV4_UDP || +			    flow_type_b == ICE_FLTR_PTYPE_NONF_IPV4_TCP || +			    flow_type_b == ICE_FLTR_PTYPE_NONF_IPV4_SCTP) +				return true; +			break; +		case ICE_FLTR_PTYPE_NONF_IPV6_UDP: +		case ICE_FLTR_PTYPE_NONF_IPV6_TCP: +		case ICE_FLTR_PTYPE_NONF_IPV6_SCTP: +			if (flow_type_b == ICE_FLTR_PTYPE_NONF_IPV6_OTHER) +				return true; +			break; +		case ICE_FLTR_PTYPE_NONF_IPV6_OTHER: +			if (flow_type_b == ICE_FLTR_PTYPE_NONF_IPV6_UDP || +			    flow_type_b == ICE_FLTR_PTYPE_NONF_IPV6_TCP || +			    flow_type_b == ICE_FLTR_PTYPE_NONF_IPV6_SCTP) +				return true; +			break; +		default: +			break; +		} +	} + +	return false; +} + +/**   * ice_vc_fdir_write_flow_prof   * @vf: pointer to the VF structure   * @flow: filter flow type @@ -677,6 +758,13 @@ ice_vc_fdir_config_input_set(struct ice_vf *vf, struct virtchnl_fdir_add *fltr,  	enum ice_fltr_ptype flow;  	int ret; +	ret = ice_vc_fdir_has_prof_conflict(vf, conf); +	if (ret) { +		dev_dbg(dev, "Found flow profile conflict for VF %d\n", +			vf->vf_id); +		return ret; +	} +  	flow = input->flow_type;  	ret = ice_vc_fdir_alloc_prof(vf, flow);  	if (ret) { @@ -1798,7 +1886,7 @@ int ice_vc_add_fdir_fltr(struct ice_vf *vf, u8 *msg)  		v_ret = VIRTCHNL_STATUS_SUCCESS;  		stat->status = VIRTCHNL_FDIR_FAILURE_RULE_NORESOURCE;  		dev_dbg(dev, "VF %d: set FDIR context failed\n", vf->vf_id); -		goto err_free_conf; +		goto err_rem_entry;  	}  	ret = ice_vc_fdir_write_fltr(vf, conf, true, is_tun); @@ -1807,15 +1895,16 @@ int ice_vc_add_fdir_fltr(struct ice_vf *vf, u8 *msg)  		stat->status = VIRTCHNL_FDIR_FAILURE_RULE_NORESOURCE;  		dev_err(dev, "VF %d: writing FDIR rule failed, ret:%d\n",  			vf->vf_id, ret); -		goto err_rem_entry; +		goto err_clr_irq;  	}  exit:  	kfree(stat);  	return ret; -err_rem_entry: +err_clr_irq:  	ice_vc_fdir_clear_irq_ctx(vf); +err_rem_entry:  	ice_vc_fdir_remove_entry(vf, conf, conf->flow_id);  err_free_conf:  	devm_kfree(dev, conf); @@ -1924,6 +2013,7 @@ void ice_vf_fdir_init(struct ice_vf *vf)  	spin_lock_init(&fdir->ctx_lock);  	fdir->ctx_irq.flags = 0;  	fdir->ctx_done.flags = 0; +	ice_vc_fdir_reset_cnt_all(fdir);  }  /** diff --git a/drivers/net/ethernet/intel/ice/ice_xsk.c b/drivers/net/ethernet/intel/ice/ice_xsk.c index 31565bbafa22..d1e489da7363 100644 --- a/drivers/net/ethernet/intel/ice/ice_xsk.c +++ b/drivers/net/ethernet/intel/ice/ice_xsk.c @@ -184,8 +184,6 @@ static int ice_qp_dis(struct ice_vsi *vsi, u16 q_idx)  	}  	netif_tx_stop_queue(netdev_get_tx_queue(vsi->netdev, q_idx)); -	ice_qvec_dis_irq(vsi, rx_ring, q_vector); -  	ice_fill_txq_meta(vsi, tx_ring, &txq_meta);  	err = ice_vsi_stop_tx_ring(vsi, ICE_NO_RESET, 0, tx_ring, &txq_meta);  	if (err) @@ -200,10 +198,11 @@ static int ice_qp_dis(struct ice_vsi *vsi, u16 q_idx)  		if (err)  			return err;  	} +	ice_qvec_dis_irq(vsi, rx_ring, q_vector); +  	err = ice_vsi_ctrl_one_rx_ring(vsi, false, q_idx, true);  	if (err)  		return err; -	ice_clean_rx_ring(rx_ring);  	ice_qvec_toggle_napi(vsi, q_vector, false);  	ice_qp_clean_rings(vsi, q_idx); diff --git a/drivers/net/ethernet/intel/igb/e1000_mac.c b/drivers/net/ethernet/intel/igb/e1000_mac.c index 205d577bdbba..caf91c6f52b4 100644 --- a/drivers/net/ethernet/intel/igb/e1000_mac.c +++ b/drivers/net/ethernet/intel/igb/e1000_mac.c @@ -426,7 +426,7 @@ void igb_mta_set(struct e1000_hw *hw, u32 hash_value)  static u32 igb_hash_mc_addr(struct e1000_hw *hw, u8 *mc_addr)  {  	u32 hash_value, hash_mask; -	u8 bit_shift = 0; +	u8 bit_shift = 1;  	/* Register count multiplied by bits per register */  	hash_mask = (hw->mac.mta_reg_count * 32) - 1; @@ -434,7 +434,7 @@ static u32 igb_hash_mc_addr(struct e1000_hw *hw, u8 *mc_addr)  	/* For a mc_filter_type of 0, bit_shift is the number of left-shifts  	 * where 0xFF would still fall within the hash mask.  	 */ -	while (hash_mask >> bit_shift != 0xFF) +	while (hash_mask >> bit_shift != 0xFF && bit_shift < 4)  		bit_shift++;  	/* The portion of the address that is used for the hash table diff --git a/drivers/net/ethernet/intel/igb/igb_ethtool.c b/drivers/net/ethernet/intel/igb/igb_ethtool.c index 7d60da1b7bf4..319ed601eaa1 100644 --- a/drivers/net/ethernet/intel/igb/igb_ethtool.c +++ b/drivers/net/ethernet/intel/igb/igb_ethtool.c @@ -822,6 +822,8 @@ static int igb_set_eeprom(struct net_device *netdev,  		 */  		ret_val = hw->nvm.ops.read(hw, last_word, 1,  				   &eeprom_buff[last_word - first_word]); +		if (ret_val) +			goto out;  	}  	/* Device's eeprom is always little-endian, word addressable */ @@ -841,6 +843,7 @@ static int igb_set_eeprom(struct net_device *netdev,  		hw->nvm.ops.update(hw);  	igb_set_fw_version(adapter); +out:  	kfree(eeprom_buff);  	return ret_val;  } diff --git a/drivers/net/ethernet/intel/igb/igb_main.c b/drivers/net/ethernet/intel/igb/igb_main.c index 03bc1e8af575..bb3db387d49c 100644 --- a/drivers/net/ethernet/intel/igb/igb_main.c +++ b/drivers/net/ethernet/intel/igb/igb_main.c @@ -28,7 +28,6 @@  #include <linux/tcp.h>  #include <linux/sctp.h>  #include <linux/if_ether.h> -#include <linux/aer.h>  #include <linux/prefetch.h>  #include <linux/bpf.h>  #include <linux/bpf_trace.h> @@ -109,6 +108,7 @@ static void igb_free_all_rx_resources(struct igb_adapter *);  static void igb_setup_mrqc(struct igb_adapter *);  static int igb_probe(struct pci_dev *, const struct pci_device_id *);  static void igb_remove(struct pci_dev *pdev); +static void igb_init_queue_configuration(struct igb_adapter *adapter);  static int igb_sw_init(struct igb_adapter *);  int igb_open(struct net_device *);  int igb_close(struct net_device *); @@ -175,9 +175,7 @@ static void igb_nfc_filter_restore(struct igb_adapter *adapter);  #ifdef CONFIG_PCI_IOV  static int igb_vf_configure(struct igb_adapter *adapter, int vf); -static int igb_pci_enable_sriov(struct pci_dev *dev, int num_vfs); -static int igb_disable_sriov(struct pci_dev *dev); -static int igb_pci_disable_sriov(struct pci_dev *dev); +static int igb_disable_sriov(struct pci_dev *dev, bool reinit);  #endif  static int igb_suspend(struct device *); @@ -3665,7 +3663,7 @@ err_sw_init:  	kfree(adapter->shadow_vfta);  	igb_clear_interrupt_scheme(adapter);  #ifdef CONFIG_PCI_IOV -	igb_disable_sriov(pdev); +	igb_disable_sriov(pdev, false);  #endif  	pci_iounmap(pdev, adapter->io_addr);  err_ioremap: @@ -3679,7 +3677,38 @@ err_dma:  }  #ifdef CONFIG_PCI_IOV -static int igb_disable_sriov(struct pci_dev *pdev) +static int igb_sriov_reinit(struct pci_dev *dev) +{ +	struct net_device *netdev = pci_get_drvdata(dev); +	struct igb_adapter *adapter = netdev_priv(netdev); +	struct pci_dev *pdev = adapter->pdev; + +	rtnl_lock(); + +	if (netif_running(netdev)) +		igb_close(netdev); +	else +		igb_reset(adapter); + +	igb_clear_interrupt_scheme(adapter); + +	igb_init_queue_configuration(adapter); + +	if (igb_init_interrupt_scheme(adapter, true)) { +		rtnl_unlock(); +		dev_err(&pdev->dev, "Unable to allocate memory for queues\n"); +		return -ENOMEM; +	} + +	if (netif_running(netdev)) +		igb_open(netdev); + +	rtnl_unlock(); + +	return 0; +} + +static int igb_disable_sriov(struct pci_dev *pdev, bool reinit)  {  	struct net_device *netdev = pci_get_drvdata(pdev);  	struct igb_adapter *adapter = netdev_priv(netdev); @@ -3713,10 +3742,10 @@ static int igb_disable_sriov(struct pci_dev *pdev)  		adapter->flags |= IGB_FLAG_DMAC;  	} -	return 0; +	return reinit ? igb_sriov_reinit(pdev) : 0;  } -static int igb_enable_sriov(struct pci_dev *pdev, int num_vfs) +static int igb_enable_sriov(struct pci_dev *pdev, int num_vfs, bool reinit)  {  	struct net_device *netdev = pci_get_drvdata(pdev);  	struct igb_adapter *adapter = netdev_priv(netdev); @@ -3781,12 +3810,6 @@ static int igb_enable_sriov(struct pci_dev *pdev, int num_vfs)  			"Unable to allocate memory for VF MAC filter list\n");  	} -	/* only call pci_enable_sriov() if no VFs are allocated already */ -	if (!old_vfs) { -		err = pci_enable_sriov(pdev, adapter->vfs_allocated_count); -		if (err) -			goto err_out; -	}  	dev_info(&pdev->dev, "%d VFs allocated\n",  		 adapter->vfs_allocated_count);  	for (i = 0; i < adapter->vfs_allocated_count; i++) @@ -3794,6 +3817,17 @@ static int igb_enable_sriov(struct pci_dev *pdev, int num_vfs)  	/* DMA Coalescing is not supported in IOV mode. */  	adapter->flags &= ~IGB_FLAG_DMAC; + +	if (reinit) { +		err = igb_sriov_reinit(pdev); +		if (err) +			goto err_out; +	} + +	/* only call pci_enable_sriov() if no VFs are allocated already */ +	if (!old_vfs) +		err = pci_enable_sriov(pdev, adapter->vfs_allocated_count); +  	goto out;  err_out: @@ -3863,9 +3897,7 @@ static void igb_remove(struct pci_dev *pdev)  	igb_release_hw_control(adapter);  #ifdef CONFIG_PCI_IOV -	rtnl_lock(); -	igb_disable_sriov(pdev); -	rtnl_unlock(); +	igb_disable_sriov(pdev, false);  #endif  	unregister_netdev(netdev); @@ -3911,7 +3943,7 @@ static void igb_probe_vfs(struct igb_adapter *adapter)  	igb_reset_interrupt_capability(adapter);  	pci_sriov_set_totalvfs(pdev, 7); -	igb_enable_sriov(pdev, max_vfs); +	igb_enable_sriov(pdev, max_vfs, false);  #endif /* CONFIG_PCI_IOV */  } @@ -6915,6 +6947,7 @@ static void igb_extts(struct igb_adapter *adapter, int tsintr_tt)  	struct e1000_hw *hw = &adapter->hw;  	struct ptp_clock_event event;  	struct timespec64 ts; +	unsigned long flags;  	if (pin < 0 || pin >= IGB_N_SDP)  		return; @@ -6922,9 +6955,12 @@ static void igb_extts(struct igb_adapter *adapter, int tsintr_tt)  	if (hw->mac.type == e1000_82580 ||  	    hw->mac.type == e1000_i354 ||  	    hw->mac.type == e1000_i350) { -		s64 ns = rd32(auxstmpl); +		u64 ns = rd32(auxstmpl); -		ns += ((s64)(rd32(auxstmph) & 0xFF)) << 32; +		ns += ((u64)(rd32(auxstmph) & 0xFF)) << 32; +		spin_lock_irqsave(&adapter->tmreg_lock, flags); +		ns = timecounter_cyc2time(&adapter->tc, ns); +		spin_unlock_irqrestore(&adapter->tmreg_lock, flags);  		ts = ns_to_timespec64(ns);  	} else {  		ts.tv_nsec = rd32(auxstmpl); @@ -9520,71 +9556,17 @@ static void igb_shutdown(struct pci_dev *pdev)  	}  } -#ifdef CONFIG_PCI_IOV -static int igb_sriov_reinit(struct pci_dev *dev) -{ -	struct net_device *netdev = pci_get_drvdata(dev); -	struct igb_adapter *adapter = netdev_priv(netdev); -	struct pci_dev *pdev = adapter->pdev; - -	rtnl_lock(); - -	if (netif_running(netdev)) -		igb_close(netdev); -	else -		igb_reset(adapter); - -	igb_clear_interrupt_scheme(adapter); - -	igb_init_queue_configuration(adapter); - -	if (igb_init_interrupt_scheme(adapter, true)) { -		rtnl_unlock(); -		dev_err(&pdev->dev, "Unable to allocate memory for queues\n"); -		return -ENOMEM; -	} - -	if (netif_running(netdev)) -		igb_open(netdev); - -	rtnl_unlock(); - -	return 0; -} - -static int igb_pci_disable_sriov(struct pci_dev *dev) -{ -	int err = igb_disable_sriov(dev); - -	if (!err) -		err = igb_sriov_reinit(dev); - -	return err; -} - -static int igb_pci_enable_sriov(struct pci_dev *dev, int num_vfs) -{ -	int err = igb_enable_sriov(dev, num_vfs); - -	if (err) -		goto out; - -	err = igb_sriov_reinit(dev); -	if (!err) -		return num_vfs; - -out: -	return err; -} - -#endif  static int igb_pci_sriov_configure(struct pci_dev *dev, int num_vfs)  {  #ifdef CONFIG_PCI_IOV -	if (num_vfs == 0) -		return igb_pci_disable_sriov(dev); -	else -		return igb_pci_enable_sriov(dev, num_vfs); +	int err; + +	if (num_vfs == 0) { +		return igb_disable_sriov(dev, true); +	} else { +		err = igb_enable_sriov(dev, num_vfs, true); +		return err ? err : num_vfs; +	}  #endif  	return 0;  } diff --git a/drivers/net/ethernet/intel/igb/igb_ptp.c b/drivers/net/ethernet/intel/igb/igb_ptp.c index 6f471b91f562..405886ee5261 100644 --- a/drivers/net/ethernet/intel/igb/igb_ptp.c +++ b/drivers/net/ethernet/intel/igb/igb_ptp.c @@ -67,6 +67,7 @@  #define INCVALUE_82576_MASK		GENMASK(E1000_TIMINCA_16NS_SHIFT - 1, 0)  #define INCVALUE_82576			(16u << IGB_82576_TSYNC_SHIFT)  #define IGB_NBITS_82580			40 +#define IGB_82580_BASE_PERIOD		0x800000000  static void igb_ptp_tx_hwtstamp(struct igb_adapter *adapter);  static void igb_ptp_sdp_init(struct igb_adapter *adapter); @@ -209,17 +210,11 @@ static int igb_ptp_adjfine_82580(struct ptp_clock_info *ptp, long scaled_ppm)  	struct igb_adapter *igb = container_of(ptp, struct igb_adapter,  					       ptp_caps);  	struct e1000_hw *hw = &igb->hw; -	int neg_adj = 0; +	bool neg_adj;  	u64 rate;  	u32 inca; -	if (scaled_ppm < 0) { -		neg_adj = 1; -		scaled_ppm = -scaled_ppm; -	} -	rate = scaled_ppm; -	rate <<= 13; -	rate = div_u64(rate, 15625); +	neg_adj = diff_by_scaled_ppm(IGB_82580_BASE_PERIOD, scaled_ppm, &rate);  	inca = rate & INCVALUE_MASK;  	if (neg_adj) diff --git a/drivers/net/ethernet/intel/igbvf/netdev.c b/drivers/net/ethernet/intel/igbvf/netdev.c index 3a32809510fc..7ff2752dd763 100644 --- a/drivers/net/ethernet/intel/igbvf/netdev.c +++ b/drivers/net/ethernet/intel/igbvf/netdev.c @@ -1074,7 +1074,7 @@ static int igbvf_request_msix(struct igbvf_adapter *adapter)  			  igbvf_intr_msix_rx, 0, adapter->rx_ring->name,  			  netdev);  	if (err) -		goto out; +		goto free_irq_tx;  	adapter->rx_ring->itr_register = E1000_EITR(vector);  	adapter->rx_ring->itr_val = adapter->current_itr; @@ -1083,10 +1083,14 @@ static int igbvf_request_msix(struct igbvf_adapter *adapter)  	err = request_irq(adapter->msix_entries[vector].vector,  			  igbvf_msix_other, 0, netdev->name, netdev);  	if (err) -		goto out; +		goto free_irq_rx;  	igbvf_configure_msix(adapter);  	return 0; +free_irq_rx: +	free_irq(adapter->msix_entries[--vector].vector, netdev); +free_irq_tx: +	free_irq(adapter->msix_entries[--vector].vector, netdev);  out:  	return err;  } @@ -2589,6 +2593,33 @@ static void igbvf_io_resume(struct pci_dev *pdev)  	netif_device_attach(netdev);  } +/** + * igbvf_io_prepare - prepare device driver for PCI reset + * @pdev: PCI device information struct + */ +static void igbvf_io_prepare(struct pci_dev *pdev) +{ +	struct net_device *netdev = pci_get_drvdata(pdev); +	struct igbvf_adapter *adapter = netdev_priv(netdev); + +	while (test_and_set_bit(__IGBVF_RESETTING, &adapter->state)) +		usleep_range(1000, 2000); +	igbvf_down(adapter); +} + +/** + * igbvf_io_reset_done - PCI reset done, device driver reset can begin + * @pdev: PCI device information struct + */ +static void igbvf_io_reset_done(struct pci_dev *pdev) +{ +	struct net_device *netdev = pci_get_drvdata(pdev); +	struct igbvf_adapter *adapter = netdev_priv(netdev); + +	igbvf_up(adapter); +	clear_bit(__IGBVF_RESETTING, &adapter->state); +} +  static void igbvf_print_device_info(struct igbvf_adapter *adapter)  {  	struct e1000_hw *hw = &adapter->hw; @@ -2916,6 +2947,8 @@ static const struct pci_error_handlers igbvf_err_handler = {  	.error_detected = igbvf_io_error_detected,  	.slot_reset = igbvf_io_slot_reset,  	.resume = igbvf_io_resume, +	.reset_prepare = igbvf_io_prepare, +	.reset_done = igbvf_io_reset_done,  };  static const struct pci_device_id igbvf_pci_tbl[] = { diff --git a/drivers/net/ethernet/intel/igbvf/vf.c b/drivers/net/ethernet/intel/igbvf/vf.c index b8ba3f94c363..a47a2e3e548c 100644 --- a/drivers/net/ethernet/intel/igbvf/vf.c +++ b/drivers/net/ethernet/intel/igbvf/vf.c @@ -1,6 +1,8 @@  // SPDX-License-Identifier: GPL-2.0  /* Copyright(c) 2009 - 2018 Intel Corporation. */ +#include <linux/etherdevice.h> +  #include "vf.h"  static s32 e1000_check_for_link_vf(struct e1000_hw *hw); @@ -131,11 +133,16 @@ static s32 e1000_reset_hw_vf(struct e1000_hw *hw)  		/* set our "perm_addr" based on info provided by PF */  		ret_val = mbx->ops.read_posted(hw, msgbuf, 3);  		if (!ret_val) { -			if (msgbuf[0] == (E1000_VF_RESET | -					  E1000_VT_MSGTYPE_ACK)) +			switch (msgbuf[0]) { +			case E1000_VF_RESET | E1000_VT_MSGTYPE_ACK:  				memcpy(hw->mac.perm_addr, addr, ETH_ALEN); -			else +				break; +			case E1000_VF_RESET | E1000_VT_MSGTYPE_NACK: +				eth_zero_addr(hw->mac.perm_addr); +				break; +			default:  				ret_val = -E1000_ERR_MAC_INIT; +			}  		}  	} diff --git a/drivers/net/ethernet/intel/igc/igc.h b/drivers/net/ethernet/intel/igc/igc.h index df3e26c0cf01..34aebf00a512 100644 --- a/drivers/net/ethernet/intel/igc/igc.h +++ b/drivers/net/ethernet/intel/igc/igc.h @@ -99,6 +99,7 @@ struct igc_ring {  	u32 start_time;  	u32 end_time; +	u32 max_sdu;  	/* CBS parameters */  	bool cbs_enable;                /* indicates if CBS is enabled */ @@ -185,6 +186,7 @@ struct igc_adapter {  	ktime_t base_time;  	ktime_t cycle_time;  	bool qbv_enable; +	u32 qbv_config_change_errors;  	/* OS defined structs */  	struct pci_dev *pdev; @@ -292,8 +294,6 @@ extern char igc_driver_name[];  #define IGC_FLAG_PTP			BIT(8)  #define IGC_FLAG_WOL_SUPPORTED		BIT(8)  #define IGC_FLAG_NEED_LINK_UPDATE	BIT(9) -#define IGC_FLAG_MEDIA_RESET		BIT(10) -#define IGC_FLAG_MAS_ENABLE		BIT(12)  #define IGC_FLAG_HAS_MSIX		BIT(13)  #define IGC_FLAG_EEE			BIT(14)  #define IGC_FLAG_VLAN_PROMISC		BIT(15) diff --git a/drivers/net/ethernet/intel/igc/igc_base.h b/drivers/net/ethernet/intel/igc/igc_base.h index 7a992befca24..9f3827eda157 100644 --- a/drivers/net/ethernet/intel/igc/igc_base.h +++ b/drivers/net/ethernet/intel/igc/igc_base.h @@ -87,8 +87,13 @@ union igc_adv_rx_desc {  #define IGC_RXDCTL_SWFLUSH		0x04000000 /* Receive Software Flush */  /* SRRCTL bit definitions */ -#define IGC_SRRCTL_BSIZEPKT_SHIFT		10 /* Shift _right_ */ -#define IGC_SRRCTL_BSIZEHDRSIZE_SHIFT		2  /* Shift _left_ */ -#define IGC_SRRCTL_DESCTYPE_ADV_ONEBUF	0x02000000 +#define IGC_SRRCTL_BSIZEPKT_MASK	GENMASK(6, 0) +#define IGC_SRRCTL_BSIZEPKT(x)		FIELD_PREP(IGC_SRRCTL_BSIZEPKT_MASK, \ +					(x) / 1024) /* in 1 KB resolution */ +#define IGC_SRRCTL_BSIZEHDR_MASK	GENMASK(13, 8) +#define IGC_SRRCTL_BSIZEHDR(x)		FIELD_PREP(IGC_SRRCTL_BSIZEHDR_MASK, \ +					(x) / 64) /* in 64 bytes resolution */ +#define IGC_SRRCTL_DESCTYPE_MASK	GENMASK(27, 25) +#define IGC_SRRCTL_DESCTYPE_ADV_ONEBUF	FIELD_PREP(IGC_SRRCTL_DESCTYPE_MASK, 1)  #endif /* _IGC_BASE_H */ diff --git a/drivers/net/ethernet/intel/igc/igc_defines.h b/drivers/net/ethernet/intel/igc/igc_defines.h index 9dec3563ce3a..44a507029946 100644 --- a/drivers/net/ethernet/intel/igc/igc_defines.h +++ b/drivers/net/ethernet/intel/igc/igc_defines.h @@ -662,9 +662,6 @@   */  #define IGC_TW_SYSTEM_100_MASK		0x0000FF00  #define IGC_TW_SYSTEM_100_SHIFT		8 -#define IGC_DMACR_DMAC_EN		0x80000000 /* Enable DMA Coalescing */ -#define IGC_DMACR_DMACTHR_MASK		0x00FF0000 -#define IGC_DMACR_DMACTHR_SHIFT		16  /* Reg val to set scale to 1024 nsec */  #define IGC_LTRMINV_SCALE_1024		2  /* Reg val to set scale to 32768 nsec */ diff --git a/drivers/net/ethernet/intel/igc/igc_ethtool.c b/drivers/net/ethernet/intel/igc/igc_ethtool.c index 5a26a7805ef8..0e2cb00622d1 100644 --- a/drivers/net/ethernet/intel/igc/igc_ethtool.c +++ b/drivers/net/ethernet/intel/igc/igc_ethtool.c @@ -67,6 +67,7 @@ static const struct igc_stats igc_gstrings_stats[] = {  	IGC_STAT("rx_hwtstamp_cleared", rx_hwtstamp_cleared),  	IGC_STAT("tx_lpi_counter", stats.tlpic),  	IGC_STAT("rx_lpi_counter", stats.rlpic), +	IGC_STAT("qbv_config_change_errors", qbv_config_change_errors),  };  #define IGC_NETDEV_STAT(_net_stat) { \ diff --git a/drivers/net/ethernet/intel/igc/igc_hw.h b/drivers/net/ethernet/intel/igc/igc_hw.h index 88680e3d613d..e1c572e0d4ef 100644 --- a/drivers/net/ethernet/intel/igc/igc_hw.h +++ b/drivers/net/ethernet/intel/igc/igc_hw.h @@ -273,6 +273,7 @@ struct igc_hw_stats {  	u64 o2bspc;  	u64 b2ospc;  	u64 b2ogprc; +	u64 txdrop;  };  struct net_device *igc_get_hw_dev(struct igc_hw *hw); diff --git a/drivers/net/ethernet/intel/igc/igc_i225.c b/drivers/net/ethernet/intel/igc/igc_i225.c index 59d5c467ea6e..17546a035ab1 100644 --- a/drivers/net/ethernet/intel/igc/igc_i225.c +++ b/drivers/net/ethernet/intel/igc/igc_i225.c @@ -593,20 +593,11 @@ s32 igc_set_ltr_i225(struct igc_hw *hw, bool link)  		size = rd32(IGC_RXPBS) &  		       IGC_RXPBS_SIZE_I225_MASK; -		/* Calculations vary based on DMAC settings. */ -		if (rd32(IGC_DMACR) & IGC_DMACR_DMAC_EN) { -			size -= (rd32(IGC_DMACR) & -				 IGC_DMACR_DMACTHR_MASK) >> -				 IGC_DMACR_DMACTHR_SHIFT; -			/* Convert size to bits. */ -			size *= 1024 * 8; -		} else { -			/* Convert size to bytes, subtract the MTU, and then -			 * convert the size to bits. -			 */ -			size *= 1024; -			size *= 8; -		} +		/* Convert size to bytes, subtract the MTU, and then +		 * convert the size to bits. +		 */ +		size *= 1024; +		size *= 8;  		if (size < 0) {  			hw_dbg("Invalid effective Rx buffer size %d\n", diff --git a/drivers/net/ethernet/intel/igc/igc_main.c b/drivers/net/ethernet/intel/igc/igc_main.c index 2928a6c73692..fa764190f270 100644 --- a/drivers/net/ethernet/intel/igc/igc_main.c +++ b/drivers/net/ethernet/intel/igc/igc_main.c @@ -4,7 +4,6 @@  #include <linux/module.h>  #include <linux/types.h>  #include <linux/if_vlan.h> -#include <linux/aer.h>  #include <linux/tcp.h>  #include <linux/udp.h>  #include <linux/ip.h> @@ -255,6 +254,13 @@ static void igc_clean_tx_ring(struct igc_ring *tx_ring)  	/* reset BQL for queue */  	netdev_tx_reset_queue(txring_txq(tx_ring)); +	/* Zero out the buffer ring */ +	memset(tx_ring->tx_buffer_info, 0, +	       sizeof(*tx_ring->tx_buffer_info) * tx_ring->count); + +	/* Zero out the descriptor ring */ +	memset(tx_ring->desc, 0, tx_ring->size); +  	/* reset next_to_use and next_to_clean */  	tx_ring->next_to_use = 0;  	tx_ring->next_to_clean = 0; @@ -268,7 +274,7 @@ static void igc_clean_tx_ring(struct igc_ring *tx_ring)   */  void igc_free_tx_resources(struct igc_ring *tx_ring)  { -	igc_clean_tx_ring(tx_ring); +	igc_disable_tx_ring(tx_ring);  	vfree(tx_ring->tx_buffer_info);  	tx_ring->tx_buffer_info = NULL; @@ -641,8 +647,11 @@ static void igc_configure_rx_ring(struct igc_adapter *adapter,  	else  		buf_size = IGC_RXBUFFER_2048; -	srrctl = IGC_RX_HDR_LEN << IGC_SRRCTL_BSIZEHDRSIZE_SHIFT; -	srrctl |= buf_size >> IGC_SRRCTL_BSIZEPKT_SHIFT; +	srrctl = rd32(IGC_SRRCTL(reg_idx)); +	srrctl &= ~(IGC_SRRCTL_BSIZEPKT_MASK | IGC_SRRCTL_BSIZEHDR_MASK | +		    IGC_SRRCTL_DESCTYPE_MASK); +	srrctl |= IGC_SRRCTL_BSIZEHDR(IGC_RX_HDR_LEN); +	srrctl |= IGC_SRRCTL_BSIZEPKT(buf_size);  	srrctl |= IGC_SRRCTL_DESCTYPE_ADV_ONEBUF;  	wr32(IGC_SRRCTL(reg_idx), srrctl); @@ -1501,6 +1510,7 @@ static int igc_tso(struct igc_ring *tx_ring,  static netdev_tx_t igc_xmit_frame_ring(struct sk_buff *skb,  				       struct igc_ring *tx_ring)  { +	struct igc_adapter *adapter = netdev_priv(tx_ring->netdev);  	bool first_flag = false, insert_empty = false;  	u16 count = TXD_USE_COUNT(skb_headlen(skb));  	__be16 protocol = vlan_get_protocol(skb); @@ -1563,9 +1573,19 @@ done:  	first->bytecount = skb->len;  	first->gso_segs = 1; -	if (unlikely(skb_shinfo(skb)->tx_flags & SKBTX_HW_TSTAMP)) { -		struct igc_adapter *adapter = netdev_priv(tx_ring->netdev); +	if (tx_ring->max_sdu > 0) { +		u32 max_sdu = 0; + +		max_sdu = tx_ring->max_sdu + +			  (skb_vlan_tagged(first->skb) ? VLAN_HLEN : 0); + +		if (first->bytecount > max_sdu) { +			adapter->stats.txdrop++; +			goto out_drop; +		} +	} +	if (unlikely(skb_shinfo(skb)->tx_flags & SKBTX_HW_TSTAMP)) {  		/* FIXME: add support for retrieving timestamps from  		 * the other timer registers before skipping the  		 * timestamping request. @@ -4920,7 +4940,8 @@ void igc_update_stats(struct igc_adapter *adapter)  	net_stats->tx_window_errors = adapter->stats.latecol;  	net_stats->tx_carrier_errors = adapter->stats.tncrs; -	/* Tx Dropped needs to be maintained elsewhere */ +	/* Tx Dropped */ +	net_stats->tx_dropped = adapter->stats.txdrop;  	/* Management Stats */  	adapter->stats.mgptc += rd32(IGC_MGTPTC); @@ -5566,25 +5587,8 @@ no_wait:  				mod_timer(&adapter->phy_info_timer,  					  round_jiffies(jiffies + 2 * HZ)); -			/* link is down, time to check for alternate media */ -			if (adapter->flags & IGC_FLAG_MAS_ENABLE) { -				if (adapter->flags & IGC_FLAG_MEDIA_RESET) { -					schedule_work(&adapter->reset_task); -					/* return immediately */ -					return; -				} -			}  			pm_schedule_suspend(netdev->dev.parent,  					    MSEC_PER_SEC * 5); - -		/* also check for alternate media here */ -		} else if (!netif_carrier_ok(netdev) && -			   (adapter->flags & IGC_FLAG_MAS_ENABLE)) { -			if (adapter->flags & IGC_FLAG_MEDIA_RESET) { -				schedule_work(&adapter->reset_task); -				/* return immediately */ -				return; -			}  		}  	} @@ -6010,18 +6014,18 @@ static bool validate_schedule(struct igc_adapter *adapter,  		if (e->command != TC_TAPRIO_CMD_SET_GATES)  			return false; -		for (i = 0; i < adapter->num_tx_queues; i++) { -			if (e->gate_mask & BIT(i)) +		for (i = 0; i < adapter->num_tx_queues; i++) +			if (e->gate_mask & BIT(i)) {  				queue_uses[i]++; -			/* There are limitations: A single queue cannot be -			 * opened and closed multiple times per cycle unless the -			 * gate stays open. Check for it. -			 */ -			if (queue_uses[i] > 1 && -			    !(prev->gate_mask & BIT(i))) -				return false; -		} +				/* There are limitations: A single queue cannot +				 * be opened and closed multiple times per cycle +				 * unless the gate stays open. Check for it. +				 */ +				if (queue_uses[i] > 1 && +				    !(prev->gate_mask & BIT(i))) +					return false; +			}  	}  	return true; @@ -6049,12 +6053,14 @@ static int igc_tsn_clear_schedule(struct igc_adapter *adapter)  	adapter->base_time = 0;  	adapter->cycle_time = NSEC_PER_SEC; +	adapter->qbv_config_change_errors = 0;  	for (i = 0; i < adapter->num_tx_queues; i++) {  		struct igc_ring *ring = adapter->tx_ring[i];  		ring->start_time = 0;  		ring->end_time = NSEC_PER_SEC; +		ring->max_sdu = 0;  	}  	return 0; @@ -6138,6 +6144,16 @@ static int igc_save_qbv_schedule(struct igc_adapter *adapter,  		}  	} +	for (i = 0; i < adapter->num_tx_queues; i++) { +		struct igc_ring *ring = adapter->tx_ring[i]; +		struct net_device *dev = adapter->netdev; + +		if (qopt->max_sdu[i]) +			ring->max_sdu = qopt->max_sdu[i] + dev->hard_header_len; +		else +			ring->max_sdu = 0; +	} +  	return 0;  } @@ -6236,8 +6252,10 @@ static int igc_tc_query_caps(struct igc_adapter *adapter,  		caps->broken_mqprio = true; -		if (hw->mac.type == igc_i225) +		if (hw->mac.type == igc_i225) { +			caps->supports_queue_max_sdu = true;  			caps->gate_mask_per_txq = true; +		}  		return 0;  	} @@ -6712,6 +6730,9 @@ static void igc_remove(struct pci_dev *pdev)  	igc_ptp_stop(adapter); +	pci_disable_ptm(pdev); +	pci_clear_master(pdev); +  	set_bit(__IGC_DOWN, &adapter->state);  	del_timer_sync(&adapter->watchdog_timer); diff --git a/drivers/net/ethernet/intel/igc/igc_regs.h b/drivers/net/ethernet/intel/igc/igc_regs.h index 01c86d36856d..dba5a5759b1c 100644 --- a/drivers/net/ethernet/intel/igc/igc_regs.h +++ b/drivers/net/ethernet/intel/igc/igc_regs.h @@ -292,7 +292,6 @@  /* LTR registers */  #define IGC_LTRC	0x01A0 /* Latency Tolerance Reporting Control */ -#define IGC_DMACR	0x02508 /* DMA Coalescing Control Register */  #define IGC_LTRMINV	0x5BB0 /* LTR Minimum Value */  #define IGC_LTRMAXV	0x5BB4 /* LTR Maximum Value */ diff --git a/drivers/net/ethernet/intel/igc/igc_tsn.c b/drivers/net/ethernet/intel/igc/igc_tsn.c index a386c8d61dbf..94a2b0dfb54d 100644 --- a/drivers/net/ethernet/intel/igc/igc_tsn.c +++ b/drivers/net/ethernet/intel/igc/igc_tsn.c @@ -114,6 +114,7 @@ static int igc_tsn_disable_offload(struct igc_adapter *adapter)  static int igc_tsn_enable_offload(struct igc_adapter *adapter)  {  	struct igc_hw *hw = &adapter->hw; +	bool tsn_mode_reconfig = false;  	u32 tqavctrl, baset_l, baset_h;  	u32 sec, nsec, cycle;  	ktime_t base_time, systim; @@ -226,6 +227,10 @@ skip_cbs:  	}  	tqavctrl = rd32(IGC_TQAVCTRL) & ~IGC_TQAVCTRL_FUTSCDDIS; + +	if (tqavctrl & IGC_TQAVCTRL_TRANSMIT_MODE_TSN) +		tsn_mode_reconfig = true; +  	tqavctrl |= IGC_TQAVCTRL_TRANSMIT_MODE_TSN | IGC_TQAVCTRL_ENHANCED_QAV;  	cycle = adapter->cycle_time; @@ -239,6 +244,13 @@ skip_cbs:  		s64 n = div64_s64(ktime_sub_ns(systim, base_time), cycle);  		base_time = ktime_add_ns(base_time, (n + 1) * cycle); + +		/* Increase the counter if scheduling into the past while +		 * Gate Control List (GCL) is running. +		 */ +		if ((rd32(IGC_BASET_H) || rd32(IGC_BASET_L)) && +		    tsn_mode_reconfig) +			adapter->qbv_config_change_errors++;  	} else {  		/* According to datasheet section 7.5.2.9.3.3, FutScdDis bit  		 * has to be configured before the cycle time and base time. diff --git a/drivers/net/ethernet/intel/ixgb/Makefile b/drivers/net/ethernet/intel/ixgb/Makefile deleted file mode 100644 index 2433e9300a33..000000000000 --- a/drivers/net/ethernet/intel/ixgb/Makefile +++ /dev/null @@ -1,9 +0,0 @@ -# SPDX-License-Identifier: GPL-2.0 -# Copyright(c) 1999 - 2008 Intel Corporation. -# -# Makefile for the Intel(R) PRO/10GbE ethernet driver -# - -obj-$(CONFIG_IXGB) += ixgb.o - -ixgb-objs := ixgb_main.o ixgb_hw.o ixgb_ee.o ixgb_ethtool.o ixgb_param.o diff --git a/drivers/net/ethernet/intel/ixgb/ixgb.h b/drivers/net/ethernet/intel/ixgb/ixgb.h deleted file mode 100644 index 81ac39576803..000000000000 --- a/drivers/net/ethernet/intel/ixgb/ixgb.h +++ /dev/null @@ -1,179 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0 */ -/* Copyright(c) 1999 - 2008 Intel Corporation. */ - -#ifndef _IXGB_H_ -#define _IXGB_H_ - -#include <linux/stddef.h> -#include <linux/module.h> -#include <linux/types.h> -#include <asm/byteorder.h> -#include <linux/mm.h> -#include <linux/errno.h> -#include <linux/ioport.h> -#include <linux/pci.h> -#include <linux/kernel.h> -#include <linux/netdevice.h> -#include <linux/etherdevice.h> -#include <linux/skbuff.h> -#include <linux/delay.h> -#include <linux/timer.h> -#include <linux/slab.h> -#include <linux/vmalloc.h> -#include <linux/interrupt.h> -#include <linux/string.h> -#include <linux/pagemap.h> -#include <linux/dma-mapping.h> -#include <linux/bitops.h> -#include <asm/io.h> -#include <asm/irq.h> -#include <linux/capability.h> -#include <linux/in.h> -#include <linux/ip.h> -#include <linux/tcp.h> -#include <linux/udp.h> -#include <net/pkt_sched.h> -#include <linux/list.h> -#include <linux/reboot.h> -#include <net/checksum.h> - -#include <linux/ethtool.h> -#include <linux/if_vlan.h> - -#define BAR_0		0 -#define BAR_1		1 - -struct ixgb_adapter; -#include "ixgb_hw.h" -#include "ixgb_ee.h" -#include "ixgb_ids.h" - -/* TX/RX descriptor defines */ -#define DEFAULT_TXD      256 -#define MAX_TXD         4096 -#define MIN_TXD           64 - -/* hardware cannot reliably support more than 512 descriptors owned by - * hardware descriptor cache otherwise an unreliable ring under heavy - * receive load may result */ -#define DEFAULT_RXD      512 -#define MAX_RXD          512 -#define MIN_RXD           64 - -/* Supported Rx Buffer Sizes */ -#define IXGB_RXBUFFER_2048  2048 -#define IXGB_RXBUFFER_4096  4096 -#define IXGB_RXBUFFER_8192  8192 -#define IXGB_RXBUFFER_16384 16384 - -/* How many Rx Buffers do we bundle into one write to the hardware ? */ -#define IXGB_RX_BUFFER_WRITE	8	/* Must be power of 2 */ - -/* wrapper around a pointer to a socket buffer, - * so a DMA handle can be stored along with the buffer */ -struct ixgb_buffer { -	struct sk_buff *skb; -	dma_addr_t dma; -	unsigned long time_stamp; -	u16 length; -	u16 next_to_watch; -	u16 mapped_as_page; -}; - -struct ixgb_desc_ring { -	/* pointer to the descriptor ring memory */ -	void *desc; -	/* physical address of the descriptor ring */ -	dma_addr_t dma; -	/* length of descriptor ring in bytes */ -	unsigned int size; -	/* number of descriptors in the ring */ -	unsigned int count; -	/* next descriptor to associate a buffer with */ -	unsigned int next_to_use; -	/* next descriptor to check for DD status bit */ -	unsigned int next_to_clean; -	/* array of buffer information structs */ -	struct ixgb_buffer *buffer_info; -}; - -#define IXGB_DESC_UNUSED(R) \ -	((((R)->next_to_clean > (R)->next_to_use) ? 0 : (R)->count) + \ -	(R)->next_to_clean - (R)->next_to_use - 1) - -#define IXGB_GET_DESC(R, i, type)	(&(((struct type *)((R).desc))[i])) -#define IXGB_RX_DESC(R, i)		IXGB_GET_DESC(R, i, ixgb_rx_desc) -#define IXGB_TX_DESC(R, i)		IXGB_GET_DESC(R, i, ixgb_tx_desc) -#define IXGB_CONTEXT_DESC(R, i)	IXGB_GET_DESC(R, i, ixgb_context_desc) - -/* board specific private data structure */ - -struct ixgb_adapter { -	struct timer_list watchdog_timer; -	unsigned long active_vlans[BITS_TO_LONGS(VLAN_N_VID)]; -	u32 bd_number; -	u32 rx_buffer_len; -	u32 part_num; -	u16 link_speed; -	u16 link_duplex; -	struct work_struct tx_timeout_task; - -	/* TX */ -	struct ixgb_desc_ring tx_ring ____cacheline_aligned_in_smp; -	unsigned int restart_queue; -	unsigned long timeo_start; -	u32 tx_cmd_type; -	u64 hw_csum_tx_good; -	u64 hw_csum_tx_error; -	u32 tx_int_delay; -	u32 tx_timeout_count; -	bool tx_int_delay_enable; -	bool detect_tx_hung; - -	/* RX */ -	struct ixgb_desc_ring rx_ring; -	u64 hw_csum_rx_error; -	u64 hw_csum_rx_good; -	u32 rx_int_delay; -	bool rx_csum; - -	/* OS defined structs */ -	struct napi_struct napi; -	struct net_device *netdev; -	struct pci_dev *pdev; - -	/* structs defined in ixgb_hw.h */ -	struct ixgb_hw hw; -	u16 msg_enable; -	struct ixgb_hw_stats stats; -	u32 alloc_rx_buff_failed; -	bool have_msi; -	unsigned long flags; -}; - -enum ixgb_state_t { -	/* TBD -	__IXGB_TESTING, -	__IXGB_RESETTING, -	*/ -	__IXGB_DOWN -}; - -/* Exported from other modules */ -void ixgb_check_options(struct ixgb_adapter *adapter); -void ixgb_set_ethtool_ops(struct net_device *netdev); -extern char ixgb_driver_name[]; - -void ixgb_set_speed_duplex(struct net_device *netdev); - -int ixgb_up(struct ixgb_adapter *adapter); -void ixgb_down(struct ixgb_adapter *adapter, bool kill_watchdog); -void ixgb_reset(struct ixgb_adapter *adapter); -int ixgb_setup_rx_resources(struct ixgb_adapter *adapter); -int ixgb_setup_tx_resources(struct ixgb_adapter *adapter); -void ixgb_free_rx_resources(struct ixgb_adapter *adapter); -void ixgb_free_tx_resources(struct ixgb_adapter *adapter); -void ixgb_update_stats(struct ixgb_adapter *adapter); - - -#endif /* _IXGB_H_ */ diff --git a/drivers/net/ethernet/intel/ixgb/ixgb_ee.c b/drivers/net/ethernet/intel/ixgb/ixgb_ee.c deleted file mode 100644 index 129286fc1634..000000000000 --- a/drivers/net/ethernet/intel/ixgb/ixgb_ee.c +++ /dev/null @@ -1,580 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0 -/* Copyright(c) 1999 - 2008 Intel Corporation. */ - -#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt - -#include "ixgb_hw.h" -#include "ixgb_ee.h" -/* Local prototypes */ -static u16 ixgb_shift_in_bits(struct ixgb_hw *hw); - -static void ixgb_shift_out_bits(struct ixgb_hw *hw, -				u16 data, -				u16 count); -static void ixgb_standby_eeprom(struct ixgb_hw *hw); - -static bool ixgb_wait_eeprom_command(struct ixgb_hw *hw); - -static void ixgb_cleanup_eeprom(struct ixgb_hw *hw); - -/****************************************************************************** - * Raises the EEPROM's clock input. - * - * hw - Struct containing variables accessed by shared code - * eecd_reg - EECD's current value - *****************************************************************************/ -static void -ixgb_raise_clock(struct ixgb_hw *hw, -		  u32 *eecd_reg) -{ -	/* Raise the clock input to the EEPROM (by setting the SK bit), and then -	 *  wait 50 microseconds. -	 */ -	*eecd_reg = *eecd_reg | IXGB_EECD_SK; -	IXGB_WRITE_REG(hw, EECD, *eecd_reg); -	IXGB_WRITE_FLUSH(hw); -	udelay(50); -} - -/****************************************************************************** - * Lowers the EEPROM's clock input. - * - * hw - Struct containing variables accessed by shared code - * eecd_reg - EECD's current value - *****************************************************************************/ -static void -ixgb_lower_clock(struct ixgb_hw *hw, -		  u32 *eecd_reg) -{ -	/* Lower the clock input to the EEPROM (by clearing the SK bit), and then -	 * wait 50 microseconds. -	 */ -	*eecd_reg = *eecd_reg & ~IXGB_EECD_SK; -	IXGB_WRITE_REG(hw, EECD, *eecd_reg); -	IXGB_WRITE_FLUSH(hw); -	udelay(50); -} - -/****************************************************************************** - * Shift data bits out to the EEPROM. - * - * hw - Struct containing variables accessed by shared code - * data - data to send to the EEPROM - * count - number of bits to shift out - *****************************************************************************/ -static void -ixgb_shift_out_bits(struct ixgb_hw *hw, -					 u16 data, -					 u16 count) -{ -	u32 eecd_reg; -	u32 mask; - -	/* We need to shift "count" bits out to the EEPROM. So, value in the -	 * "data" parameter will be shifted out to the EEPROM one bit at a time. -	 * In order to do this, "data" must be broken down into bits. -	 */ -	mask = 0x01 << (count - 1); -	eecd_reg = IXGB_READ_REG(hw, EECD); -	eecd_reg &= ~(IXGB_EECD_DO | IXGB_EECD_DI); -	do { -		/* A "1" is shifted out to the EEPROM by setting bit "DI" to a "1", -		 * and then raising and then lowering the clock (the SK bit controls -		 * the clock input to the EEPROM).  A "0" is shifted out to the EEPROM -		 * by setting "DI" to "0" and then raising and then lowering the clock. -		 */ -		eecd_reg &= ~IXGB_EECD_DI; - -		if (data & mask) -			eecd_reg |= IXGB_EECD_DI; - -		IXGB_WRITE_REG(hw, EECD, eecd_reg); -		IXGB_WRITE_FLUSH(hw); - -		udelay(50); - -		ixgb_raise_clock(hw, &eecd_reg); -		ixgb_lower_clock(hw, &eecd_reg); - -		mask = mask >> 1; - -	} while (mask); - -	/* We leave the "DI" bit set to "0" when we leave this routine. */ -	eecd_reg &= ~IXGB_EECD_DI; -	IXGB_WRITE_REG(hw, EECD, eecd_reg); -} - -/****************************************************************************** - * Shift data bits in from the EEPROM - * - * hw - Struct containing variables accessed by shared code - *****************************************************************************/ -static u16 -ixgb_shift_in_bits(struct ixgb_hw *hw) -{ -	u32 eecd_reg; -	u32 i; -	u16 data; - -	/* In order to read a register from the EEPROM, we need to shift 16 bits -	 * in from the EEPROM. Bits are "shifted in" by raising the clock input to -	 * the EEPROM (setting the SK bit), and then reading the value of the "DO" -	 * bit.  During this "shifting in" process the "DI" bit should always be -	 * clear.. -	 */ - -	eecd_reg = IXGB_READ_REG(hw, EECD); - -	eecd_reg &= ~(IXGB_EECD_DO | IXGB_EECD_DI); -	data = 0; - -	for (i = 0; i < 16; i++) { -		data = data << 1; -		ixgb_raise_clock(hw, &eecd_reg); - -		eecd_reg = IXGB_READ_REG(hw, EECD); - -		eecd_reg &= ~(IXGB_EECD_DI); -		if (eecd_reg & IXGB_EECD_DO) -			data |= 1; - -		ixgb_lower_clock(hw, &eecd_reg); -	} - -	return data; -} - -/****************************************************************************** - * Prepares EEPROM for access - * - * hw - Struct containing variables accessed by shared code - * - * Lowers EEPROM clock. Clears input pin. Sets the chip select pin. This - * function should be called before issuing a command to the EEPROM. - *****************************************************************************/ -static void -ixgb_setup_eeprom(struct ixgb_hw *hw) -{ -	u32 eecd_reg; - -	eecd_reg = IXGB_READ_REG(hw, EECD); - -	/*  Clear SK and DI  */ -	eecd_reg &= ~(IXGB_EECD_SK | IXGB_EECD_DI); -	IXGB_WRITE_REG(hw, EECD, eecd_reg); - -	/*  Set CS  */ -	eecd_reg |= IXGB_EECD_CS; -	IXGB_WRITE_REG(hw, EECD, eecd_reg); -} - -/****************************************************************************** - * Returns EEPROM to a "standby" state - * - * hw - Struct containing variables accessed by shared code - *****************************************************************************/ -static void -ixgb_standby_eeprom(struct ixgb_hw *hw) -{ -	u32 eecd_reg; - -	eecd_reg = IXGB_READ_REG(hw, EECD); - -	/*  Deselect EEPROM  */ -	eecd_reg &= ~(IXGB_EECD_CS | IXGB_EECD_SK); -	IXGB_WRITE_REG(hw, EECD, eecd_reg); -	IXGB_WRITE_FLUSH(hw); -	udelay(50); - -	/*  Clock high  */ -	eecd_reg |= IXGB_EECD_SK; -	IXGB_WRITE_REG(hw, EECD, eecd_reg); -	IXGB_WRITE_FLUSH(hw); -	udelay(50); - -	/*  Select EEPROM  */ -	eecd_reg |= IXGB_EECD_CS; -	IXGB_WRITE_REG(hw, EECD, eecd_reg); -	IXGB_WRITE_FLUSH(hw); -	udelay(50); - -	/*  Clock low  */ -	eecd_reg &= ~IXGB_EECD_SK; -	IXGB_WRITE_REG(hw, EECD, eecd_reg); -	IXGB_WRITE_FLUSH(hw); -	udelay(50); -} - -/****************************************************************************** - * Raises then lowers the EEPROM's clock pin - * - * hw - Struct containing variables accessed by shared code - *****************************************************************************/ -static void -ixgb_clock_eeprom(struct ixgb_hw *hw) -{ -	u32 eecd_reg; - -	eecd_reg = IXGB_READ_REG(hw, EECD); - -	/*  Rising edge of clock  */ -	eecd_reg |= IXGB_EECD_SK; -	IXGB_WRITE_REG(hw, EECD, eecd_reg); -	IXGB_WRITE_FLUSH(hw); -	udelay(50); - -	/*  Falling edge of clock  */ -	eecd_reg &= ~IXGB_EECD_SK; -	IXGB_WRITE_REG(hw, EECD, eecd_reg); -	IXGB_WRITE_FLUSH(hw); -	udelay(50); -} - -/****************************************************************************** - * Terminates a command by lowering the EEPROM's chip select pin - * - * hw - Struct containing variables accessed by shared code - *****************************************************************************/ -static void -ixgb_cleanup_eeprom(struct ixgb_hw *hw) -{ -	u32 eecd_reg; - -	eecd_reg = IXGB_READ_REG(hw, EECD); - -	eecd_reg &= ~(IXGB_EECD_CS | IXGB_EECD_DI); - -	IXGB_WRITE_REG(hw, EECD, eecd_reg); - -	ixgb_clock_eeprom(hw); -} - -/****************************************************************************** - * Waits for the EEPROM to finish the current command. - * - * hw - Struct containing variables accessed by shared code - * - * The command is done when the EEPROM's data out pin goes high. - * - * Returns: - *      true: EEPROM data pin is high before timeout. - *      false:  Time expired. - *****************************************************************************/ -static bool -ixgb_wait_eeprom_command(struct ixgb_hw *hw) -{ -	u32 eecd_reg; -	u32 i; - -	/* Toggle the CS line.  This in effect tells to EEPROM to actually execute -	 * the command in question. -	 */ -	ixgb_standby_eeprom(hw); - -	/* Now read DO repeatedly until is high (equal to '1').  The EEPROM will -	 * signal that the command has been completed by raising the DO signal. -	 * If DO does not go high in 10 milliseconds, then error out. -	 */ -	for (i = 0; i < 200; i++) { -		eecd_reg = IXGB_READ_REG(hw, EECD); - -		if (eecd_reg & IXGB_EECD_DO) -			return true; - -		udelay(50); -	} -	ASSERT(0); -	return false; -} - -/****************************************************************************** - * Verifies that the EEPROM has a valid checksum - * - * hw - Struct containing variables accessed by shared code - * - * Reads the first 64 16 bit words of the EEPROM and sums the values read. - * If the sum of the 64 16 bit words is 0xBABA, the EEPROM's checksum is - * valid. - * - * Returns: - *  true: Checksum is valid - *  false: Checksum is not valid. - *****************************************************************************/ -bool -ixgb_validate_eeprom_checksum(struct ixgb_hw *hw) -{ -	u16 checksum = 0; -	u16 i; - -	for (i = 0; i < (EEPROM_CHECKSUM_REG + 1); i++) -		checksum += ixgb_read_eeprom(hw, i); - -	if (checksum == (u16) EEPROM_SUM) -		return true; -	else -		return false; -} - -/****************************************************************************** - * Calculates the EEPROM checksum and writes it to the EEPROM - * - * hw - Struct containing variables accessed by shared code - * - * Sums the first 63 16 bit words of the EEPROM. Subtracts the sum from 0xBABA. - * Writes the difference to word offset 63 of the EEPROM. - *****************************************************************************/ -void -ixgb_update_eeprom_checksum(struct ixgb_hw *hw) -{ -	u16 checksum = 0; -	u16 i; - -	for (i = 0; i < EEPROM_CHECKSUM_REG; i++) -		checksum += ixgb_read_eeprom(hw, i); - -	checksum = (u16) EEPROM_SUM - checksum; - -	ixgb_write_eeprom(hw, EEPROM_CHECKSUM_REG, checksum); -} - -/****************************************************************************** - * Writes a 16 bit word to a given offset in the EEPROM. - * - * hw - Struct containing variables accessed by shared code - * reg - offset within the EEPROM to be written to - * data - 16 bit word to be written to the EEPROM - * - * If ixgb_update_eeprom_checksum is not called after this function, the - * EEPROM will most likely contain an invalid checksum. - * - *****************************************************************************/ -void -ixgb_write_eeprom(struct ixgb_hw *hw, u16 offset, u16 data) -{ -	struct ixgb_ee_map_type *ee_map = (struct ixgb_ee_map_type *)hw->eeprom; - -	/* Prepare the EEPROM for writing */ -	ixgb_setup_eeprom(hw); - -	/*  Send the 9-bit EWEN (write enable) command to the EEPROM (5-bit opcode -	 *  plus 4-bit dummy).  This puts the EEPROM into write/erase mode. -	 */ -	ixgb_shift_out_bits(hw, EEPROM_EWEN_OPCODE, 5); -	ixgb_shift_out_bits(hw, 0, 4); - -	/*  Prepare the EEPROM  */ -	ixgb_standby_eeprom(hw); - -	/*  Send the Write command (3-bit opcode + 6-bit addr)  */ -	ixgb_shift_out_bits(hw, EEPROM_WRITE_OPCODE, 3); -	ixgb_shift_out_bits(hw, offset, 6); - -	/*  Send the data  */ -	ixgb_shift_out_bits(hw, data, 16); - -	ixgb_wait_eeprom_command(hw); - -	/*  Recover from write  */ -	ixgb_standby_eeprom(hw); - -	/* Send the 9-bit EWDS (write disable) command to the EEPROM (5-bit -	 * opcode plus 4-bit dummy).  This takes the EEPROM out of write/erase -	 * mode. -	 */ -	ixgb_shift_out_bits(hw, EEPROM_EWDS_OPCODE, 5); -	ixgb_shift_out_bits(hw, 0, 4); - -	/*  Done with writing  */ -	ixgb_cleanup_eeprom(hw); - -	/* clear the init_ctrl_reg_1 to signify that the cache is invalidated */ -	ee_map->init_ctrl_reg_1 = cpu_to_le16(EEPROM_ICW1_SIGNATURE_CLEAR); -} - -/****************************************************************************** - * Reads a 16 bit word from the EEPROM. - * - * hw - Struct containing variables accessed by shared code - * offset - offset of 16 bit word in the EEPROM to read - * - * Returns: - *  The 16-bit value read from the eeprom - *****************************************************************************/ -u16 -ixgb_read_eeprom(struct ixgb_hw *hw, -		  u16 offset) -{ -	u16 data; - -	/*  Prepare the EEPROM for reading  */ -	ixgb_setup_eeprom(hw); - -	/*  Send the READ command (opcode + addr)  */ -	ixgb_shift_out_bits(hw, EEPROM_READ_OPCODE, 3); -	/* -	 * We have a 64 word EEPROM, there are 6 address bits -	 */ -	ixgb_shift_out_bits(hw, offset, 6); - -	/*  Read the data  */ -	data = ixgb_shift_in_bits(hw); - -	/*  End this read operation  */ -	ixgb_standby_eeprom(hw); - -	return data; -} - -/****************************************************************************** - * Reads eeprom and stores data in shared structure. - * Validates eeprom checksum and eeprom signature. - * - * hw - Struct containing variables accessed by shared code - * - * Returns: - *      true: if eeprom read is successful - *      false: otherwise. - *****************************************************************************/ -bool -ixgb_get_eeprom_data(struct ixgb_hw *hw) -{ -	u16 i; -	u16 checksum = 0; -	struct ixgb_ee_map_type *ee_map; - -	ENTER(); - -	ee_map = (struct ixgb_ee_map_type *)hw->eeprom; - -	pr_debug("Reading eeprom data\n"); -	for (i = 0; i < IXGB_EEPROM_SIZE ; i++) { -		u16 ee_data; -		ee_data = ixgb_read_eeprom(hw, i); -		checksum += ee_data; -		hw->eeprom[i] = cpu_to_le16(ee_data); -	} - -	if (checksum != (u16) EEPROM_SUM) { -		pr_debug("Checksum invalid\n"); -		/* clear the init_ctrl_reg_1 to signify that the cache is -		 * invalidated */ -		ee_map->init_ctrl_reg_1 = cpu_to_le16(EEPROM_ICW1_SIGNATURE_CLEAR); -		return false; -	} - -	if ((ee_map->init_ctrl_reg_1 & cpu_to_le16(EEPROM_ICW1_SIGNATURE_MASK)) -		 != cpu_to_le16(EEPROM_ICW1_SIGNATURE_VALID)) { -		pr_debug("Signature invalid\n"); -		return false; -	} - -	return true; -} - -/****************************************************************************** - * Local function to check if the eeprom signature is good - * If the eeprom signature is good, calls ixgb)get_eeprom_data. - * - * hw - Struct containing variables accessed by shared code - * - * Returns: - *      true: eeprom signature was good and the eeprom read was successful - *      false: otherwise. - ******************************************************************************/ -static bool -ixgb_check_and_get_eeprom_data (struct ixgb_hw* hw) -{ -	struct ixgb_ee_map_type *ee_map = (struct ixgb_ee_map_type *)hw->eeprom; - -	if ((ee_map->init_ctrl_reg_1 & cpu_to_le16(EEPROM_ICW1_SIGNATURE_MASK)) -	    == cpu_to_le16(EEPROM_ICW1_SIGNATURE_VALID)) { -		return true; -	} else { -		return ixgb_get_eeprom_data(hw); -	} -} - -/****************************************************************************** - * return a word from the eeprom - * - * hw - Struct containing variables accessed by shared code - * index - Offset of eeprom word - * - * Returns: - *          Word at indexed offset in eeprom, if valid, 0 otherwise. - ******************************************************************************/ -__le16 -ixgb_get_eeprom_word(struct ixgb_hw *hw, u16 index) -{ - -	if (index < IXGB_EEPROM_SIZE && ixgb_check_and_get_eeprom_data(hw)) -		return hw->eeprom[index]; - -	return 0; -} - -/****************************************************************************** - * return the mac address from EEPROM - * - * hw       - Struct containing variables accessed by shared code - * mac_addr - Ethernet Address if EEPROM contents are valid, 0 otherwise - * - * Returns: None. - ******************************************************************************/ -void -ixgb_get_ee_mac_addr(struct ixgb_hw *hw, -			u8 *mac_addr) -{ -	int i; -	struct ixgb_ee_map_type *ee_map = (struct ixgb_ee_map_type *)hw->eeprom; - -	ENTER(); - -	if (ixgb_check_and_get_eeprom_data(hw)) { -		for (i = 0; i < ETH_ALEN; i++) { -			mac_addr[i] = ee_map->mac_addr[i]; -		} -		pr_debug("eeprom mac address = %pM\n", mac_addr); -	} -} - - -/****************************************************************************** - * return the Printed Board Assembly number from EEPROM - * - * hw - Struct containing variables accessed by shared code - * - * Returns: - *          PBA number if EEPROM contents are valid, 0 otherwise - ******************************************************************************/ -u32 -ixgb_get_ee_pba_number(struct ixgb_hw *hw) -{ -	if (ixgb_check_and_get_eeprom_data(hw)) -		return le16_to_cpu(hw->eeprom[EEPROM_PBA_1_2_REG]) -			| (le16_to_cpu(hw->eeprom[EEPROM_PBA_3_4_REG])<<16); - -	return 0; -} - - -/****************************************************************************** - * return the Device Id from EEPROM - * - * hw - Struct containing variables accessed by shared code - * - * Returns: - *          Device Id if EEPROM contents are valid, 0 otherwise - ******************************************************************************/ -u16 -ixgb_get_ee_device_id(struct ixgb_hw *hw) -{ -	struct ixgb_ee_map_type *ee_map = (struct ixgb_ee_map_type *)hw->eeprom; - -	if (ixgb_check_and_get_eeprom_data(hw)) -		return le16_to_cpu(ee_map->device_id); - -	return 0; -} - diff --git a/drivers/net/ethernet/intel/ixgb/ixgb_ee.h b/drivers/net/ethernet/intel/ixgb/ixgb_ee.h deleted file mode 100644 index 3ee0a09e5d0a..000000000000 --- a/drivers/net/ethernet/intel/ixgb/ixgb_ee.h +++ /dev/null @@ -1,79 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0 */ -/* Copyright(c) 1999 - 2008 Intel Corporation. */ - -#ifndef _IXGB_EE_H_ -#define _IXGB_EE_H_ - -#define IXGB_EEPROM_SIZE    64	/* Size in words */ - -/* EEPROM Commands */ -#define EEPROM_READ_OPCODE  0x6	/* EEPROM read opcode */ -#define EEPROM_WRITE_OPCODE 0x5	/* EEPROM write opcode */ -#define EEPROM_ERASE_OPCODE 0x7	/* EEPROM erase opcode */ -#define EEPROM_EWEN_OPCODE  0x13	/* EEPROM erase/write enable */ -#define EEPROM_EWDS_OPCODE  0x10	/* EEPROM erase/write disable */ - -/* EEPROM MAP (Word Offsets) */ -#define EEPROM_IA_1_2_REG        0x0000 -#define EEPROM_IA_3_4_REG        0x0001 -#define EEPROM_IA_5_6_REG        0x0002 -#define EEPROM_COMPATIBILITY_REG 0x0003 -#define EEPROM_PBA_1_2_REG       0x0008 -#define EEPROM_PBA_3_4_REG       0x0009 -#define EEPROM_INIT_CONTROL1_REG 0x000A -#define EEPROM_SUBSYS_ID_REG     0x000B -#define EEPROM_SUBVEND_ID_REG    0x000C -#define EEPROM_DEVICE_ID_REG     0x000D -#define EEPROM_VENDOR_ID_REG     0x000E -#define EEPROM_INIT_CONTROL2_REG 0x000F -#define EEPROM_SWDPINS_REG       0x0020 -#define EEPROM_CIRCUIT_CTRL_REG  0x0021 -#define EEPROM_D0_D3_POWER_REG   0x0022 -#define EEPROM_FLASH_VERSION     0x0032 -#define EEPROM_CHECKSUM_REG      0x003F - -/* Mask bits for fields in Word 0x0a of the EEPROM */ - -#define EEPROM_ICW1_SIGNATURE_MASK  0xC000 -#define EEPROM_ICW1_SIGNATURE_VALID 0x4000 -#define EEPROM_ICW1_SIGNATURE_CLEAR 0x0000 - -/* For checksumming, the sum of all words in the EEPROM should equal 0xBABA. */ -#define EEPROM_SUM 0xBABA - -/* EEPROM Map Sizes (Byte Counts) */ -#define PBA_SIZE 4 - -/* EEPROM Map defines (WORD OFFSETS)*/ - -/* EEPROM structure */ -struct ixgb_ee_map_type { -	u8 mac_addr[ETH_ALEN]; -	__le16 compatibility; -	__le16 reserved1[4]; -	__le32 pba_number; -	__le16 init_ctrl_reg_1; -	__le16 subsystem_id; -	__le16 subvendor_id; -	__le16 device_id; -	__le16 vendor_id; -	__le16 init_ctrl_reg_2; -	__le16 oem_reserved[16]; -	__le16 swdpins_reg; -	__le16 circuit_ctrl_reg; -	u8 d3_power; -	u8 d0_power; -	__le16 reserved2[28]; -	__le16 checksum; -}; - -/* EEPROM Functions */ -u16 ixgb_read_eeprom(struct ixgb_hw *hw, u16 reg); - -bool ixgb_validate_eeprom_checksum(struct ixgb_hw *hw); - -void ixgb_update_eeprom_checksum(struct ixgb_hw *hw); - -void ixgb_write_eeprom(struct ixgb_hw *hw, u16 reg, u16 data); - -#endif				/* IXGB_EE_H */ diff --git a/drivers/net/ethernet/intel/ixgb/ixgb_ethtool.c b/drivers/net/ethernet/intel/ixgb/ixgb_ethtool.c deleted file mode 100644 index efa980514944..000000000000 --- a/drivers/net/ethernet/intel/ixgb/ixgb_ethtool.c +++ /dev/null @@ -1,642 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0 -/* Copyright(c) 1999 - 2008 Intel Corporation. */ - -/* ethtool support for ixgb */ - -#include "ixgb.h" - -#include <linux/uaccess.h> - -#define IXGB_ALL_RAR_ENTRIES 16 - -enum {NETDEV_STATS, IXGB_STATS}; - -struct ixgb_stats { -	char stat_string[ETH_GSTRING_LEN]; -	int type; -	int sizeof_stat; -	int stat_offset; -}; - -#define IXGB_STAT(m)		IXGB_STATS, \ -				sizeof_field(struct ixgb_adapter, m), \ -				offsetof(struct ixgb_adapter, m) -#define IXGB_NETDEV_STAT(m)	NETDEV_STATS, \ -				sizeof_field(struct net_device, m), \ -				offsetof(struct net_device, m) - -static struct ixgb_stats ixgb_gstrings_stats[] = { -	{"rx_packets", IXGB_NETDEV_STAT(stats.rx_packets)}, -	{"tx_packets", IXGB_NETDEV_STAT(stats.tx_packets)}, -	{"rx_bytes", IXGB_NETDEV_STAT(stats.rx_bytes)}, -	{"tx_bytes", IXGB_NETDEV_STAT(stats.tx_bytes)}, -	{"rx_errors", IXGB_NETDEV_STAT(stats.rx_errors)}, -	{"tx_errors", IXGB_NETDEV_STAT(stats.tx_errors)}, -	{"rx_dropped", IXGB_NETDEV_STAT(stats.rx_dropped)}, -	{"tx_dropped", IXGB_NETDEV_STAT(stats.tx_dropped)}, -	{"multicast", IXGB_NETDEV_STAT(stats.multicast)}, -	{"collisions", IXGB_NETDEV_STAT(stats.collisions)}, - -/*	{ "rx_length_errors", IXGB_NETDEV_STAT(stats.rx_length_errors) },	*/ -	{"rx_over_errors", IXGB_NETDEV_STAT(stats.rx_over_errors)}, -	{"rx_crc_errors", IXGB_NETDEV_STAT(stats.rx_crc_errors)}, -	{"rx_frame_errors", IXGB_NETDEV_STAT(stats.rx_frame_errors)}, -	{"rx_no_buffer_count", IXGB_STAT(stats.rnbc)}, -	{"rx_fifo_errors", IXGB_NETDEV_STAT(stats.rx_fifo_errors)}, -	{"rx_missed_errors", IXGB_NETDEV_STAT(stats.rx_missed_errors)}, -	{"tx_aborted_errors", IXGB_NETDEV_STAT(stats.tx_aborted_errors)}, -	{"tx_carrier_errors", IXGB_NETDEV_STAT(stats.tx_carrier_errors)}, -	{"tx_fifo_errors", IXGB_NETDEV_STAT(stats.tx_fifo_errors)}, -	{"tx_heartbeat_errors", IXGB_NETDEV_STAT(stats.tx_heartbeat_errors)}, -	{"tx_window_errors", IXGB_NETDEV_STAT(stats.tx_window_errors)}, -	{"tx_deferred_ok", IXGB_STAT(stats.dc)}, -	{"tx_timeout_count", IXGB_STAT(tx_timeout_count) }, -	{"tx_restart_queue", IXGB_STAT(restart_queue) }, -	{"rx_long_length_errors", IXGB_STAT(stats.roc)}, -	{"rx_short_length_errors", IXGB_STAT(stats.ruc)}, -	{"tx_tcp_seg_good", IXGB_STAT(stats.tsctc)}, -	{"tx_tcp_seg_failed", IXGB_STAT(stats.tsctfc)}, -	{"rx_flow_control_xon", IXGB_STAT(stats.xonrxc)}, -	{"rx_flow_control_xoff", IXGB_STAT(stats.xoffrxc)}, -	{"tx_flow_control_xon", IXGB_STAT(stats.xontxc)}, -	{"tx_flow_control_xoff", IXGB_STAT(stats.xofftxc)}, -	{"rx_csum_offload_good", IXGB_STAT(hw_csum_rx_good)}, -	{"rx_csum_offload_errors", IXGB_STAT(hw_csum_rx_error)}, -	{"tx_csum_offload_good", IXGB_STAT(hw_csum_tx_good)}, -	{"tx_csum_offload_errors", IXGB_STAT(hw_csum_tx_error)} -}; - -#define IXGB_STATS_LEN	ARRAY_SIZE(ixgb_gstrings_stats) - -static int -ixgb_get_link_ksettings(struct net_device *netdev, -			struct ethtool_link_ksettings *cmd) -{ -	struct ixgb_adapter *adapter = netdev_priv(netdev); - -	ethtool_link_ksettings_zero_link_mode(cmd, supported); -	ethtool_link_ksettings_add_link_mode(cmd, supported, 10000baseT_Full); -	ethtool_link_ksettings_add_link_mode(cmd, supported, FIBRE); - -	ethtool_link_ksettings_zero_link_mode(cmd, advertising); -	ethtool_link_ksettings_add_link_mode(cmd, advertising, 10000baseT_Full); -	ethtool_link_ksettings_add_link_mode(cmd, advertising, FIBRE); - -	cmd->base.port = PORT_FIBRE; - -	if (netif_carrier_ok(adapter->netdev)) { -		cmd->base.speed = SPEED_10000; -		cmd->base.duplex = DUPLEX_FULL; -	} else { -		cmd->base.speed = SPEED_UNKNOWN; -		cmd->base.duplex = DUPLEX_UNKNOWN; -	} - -	cmd->base.autoneg = AUTONEG_DISABLE; -	return 0; -} - -void ixgb_set_speed_duplex(struct net_device *netdev) -{ -	struct ixgb_adapter *adapter = netdev_priv(netdev); -	/* be optimistic about our link, since we were up before */ -	adapter->link_speed = 10000; -	adapter->link_duplex = FULL_DUPLEX; -	netif_carrier_on(netdev); -	netif_wake_queue(netdev); -} - -static int -ixgb_set_link_ksettings(struct net_device *netdev, -			const struct ethtool_link_ksettings *cmd) -{ -	struct ixgb_adapter *adapter = netdev_priv(netdev); -	u32 speed = cmd->base.speed; - -	if (cmd->base.autoneg == AUTONEG_ENABLE || -	    (speed + cmd->base.duplex != SPEED_10000 + DUPLEX_FULL)) -		return -EINVAL; - -	if (netif_running(adapter->netdev)) { -		ixgb_down(adapter, true); -		ixgb_reset(adapter); -		ixgb_up(adapter); -		ixgb_set_speed_duplex(netdev); -	} else -		ixgb_reset(adapter); - -	return 0; -} - -static void -ixgb_get_pauseparam(struct net_device *netdev, -			 struct ethtool_pauseparam *pause) -{ -	struct ixgb_adapter *adapter = netdev_priv(netdev); -	struct ixgb_hw *hw = &adapter->hw; - -	pause->autoneg = AUTONEG_DISABLE; - -	if (hw->fc.type == ixgb_fc_rx_pause) -		pause->rx_pause = 1; -	else if (hw->fc.type == ixgb_fc_tx_pause) -		pause->tx_pause = 1; -	else if (hw->fc.type == ixgb_fc_full) { -		pause->rx_pause = 1; -		pause->tx_pause = 1; -	} -} - -static int -ixgb_set_pauseparam(struct net_device *netdev, -			 struct ethtool_pauseparam *pause) -{ -	struct ixgb_adapter *adapter = netdev_priv(netdev); -	struct ixgb_hw *hw = &adapter->hw; - -	if (pause->autoneg == AUTONEG_ENABLE) -		return -EINVAL; - -	if (pause->rx_pause && pause->tx_pause) -		hw->fc.type = ixgb_fc_full; -	else if (pause->rx_pause && !pause->tx_pause) -		hw->fc.type = ixgb_fc_rx_pause; -	else if (!pause->rx_pause && pause->tx_pause) -		hw->fc.type = ixgb_fc_tx_pause; -	else if (!pause->rx_pause && !pause->tx_pause) -		hw->fc.type = ixgb_fc_none; - -	if (netif_running(adapter->netdev)) { -		ixgb_down(adapter, true); -		ixgb_up(adapter); -		ixgb_set_speed_duplex(netdev); -	} else -		ixgb_reset(adapter); - -	return 0; -} - -static u32 -ixgb_get_msglevel(struct net_device *netdev) -{ -	struct ixgb_adapter *adapter = netdev_priv(netdev); -	return adapter->msg_enable; -} - -static void -ixgb_set_msglevel(struct net_device *netdev, u32 data) -{ -	struct ixgb_adapter *adapter = netdev_priv(netdev); -	adapter->msg_enable = data; -} -#define IXGB_GET_STAT(_A_, _R_) _A_->stats._R_ - -static int -ixgb_get_regs_len(struct net_device *netdev) -{ -#define IXGB_REG_DUMP_LEN  136*sizeof(u32) -	return IXGB_REG_DUMP_LEN; -} - -static void -ixgb_get_regs(struct net_device *netdev, -		   struct ethtool_regs *regs, void *p) -{ -	struct ixgb_adapter *adapter = netdev_priv(netdev); -	struct ixgb_hw *hw = &adapter->hw; -	u32 *reg = p; -	u32 *reg_start = reg; -	u8 i; - -	/* the 1 (one) below indicates an attempt at versioning, if the -	 * interface in ethtool or the driver changes, this 1 should be -	 * incremented */ -	regs->version = (1<<24) | hw->revision_id << 16 | hw->device_id; - -	/* General Registers */ -	*reg++ = IXGB_READ_REG(hw, CTRL0);	/*   0 */ -	*reg++ = IXGB_READ_REG(hw, CTRL1);	/*   1 */ -	*reg++ = IXGB_READ_REG(hw, STATUS);	/*   2 */ -	*reg++ = IXGB_READ_REG(hw, EECD);	/*   3 */ -	*reg++ = IXGB_READ_REG(hw, MFS);	/*   4 */ - -	/* Interrupt */ -	*reg++ = IXGB_READ_REG(hw, ICR);	/*   5 */ -	*reg++ = IXGB_READ_REG(hw, ICS);	/*   6 */ -	*reg++ = IXGB_READ_REG(hw, IMS);	/*   7 */ -	*reg++ = IXGB_READ_REG(hw, IMC);	/*   8 */ - -	/* Receive */ -	*reg++ = IXGB_READ_REG(hw, RCTL);	/*   9 */ -	*reg++ = IXGB_READ_REG(hw, FCRTL);	/*  10 */ -	*reg++ = IXGB_READ_REG(hw, FCRTH);	/*  11 */ -	*reg++ = IXGB_READ_REG(hw, RDBAL);	/*  12 */ -	*reg++ = IXGB_READ_REG(hw, RDBAH);	/*  13 */ -	*reg++ = IXGB_READ_REG(hw, RDLEN);	/*  14 */ -	*reg++ = IXGB_READ_REG(hw, RDH);	/*  15 */ -	*reg++ = IXGB_READ_REG(hw, RDT);	/*  16 */ -	*reg++ = IXGB_READ_REG(hw, RDTR);	/*  17 */ -	*reg++ = IXGB_READ_REG(hw, RXDCTL);	/*  18 */ -	*reg++ = IXGB_READ_REG(hw, RAIDC);	/*  19 */ -	*reg++ = IXGB_READ_REG(hw, RXCSUM);	/*  20 */ - -	/* there are 16 RAR entries in hardware, we only use 3 */ -	for (i = 0; i < IXGB_ALL_RAR_ENTRIES; i++) { -		*reg++ = IXGB_READ_REG_ARRAY(hw, RAL, (i << 1)); /*21,...,51 */ -		*reg++ = IXGB_READ_REG_ARRAY(hw, RAH, (i << 1)); /*22,...,52 */ -	} - -	/* Transmit */ -	*reg++ = IXGB_READ_REG(hw, TCTL);	/*  53 */ -	*reg++ = IXGB_READ_REG(hw, TDBAL);	/*  54 */ -	*reg++ = IXGB_READ_REG(hw, TDBAH);	/*  55 */ -	*reg++ = IXGB_READ_REG(hw, TDLEN);	/*  56 */ -	*reg++ = IXGB_READ_REG(hw, TDH);	/*  57 */ -	*reg++ = IXGB_READ_REG(hw, TDT);	/*  58 */ -	*reg++ = IXGB_READ_REG(hw, TIDV);	/*  59 */ -	*reg++ = IXGB_READ_REG(hw, TXDCTL);	/*  60 */ -	*reg++ = IXGB_READ_REG(hw, TSPMT);	/*  61 */ -	*reg++ = IXGB_READ_REG(hw, PAP);	/*  62 */ - -	/* Physical */ -	*reg++ = IXGB_READ_REG(hw, PCSC1);	/*  63 */ -	*reg++ = IXGB_READ_REG(hw, PCSC2);	/*  64 */ -	*reg++ = IXGB_READ_REG(hw, PCSS1);	/*  65 */ -	*reg++ = IXGB_READ_REG(hw, PCSS2);	/*  66 */ -	*reg++ = IXGB_READ_REG(hw, XPCSS);	/*  67 */ -	*reg++ = IXGB_READ_REG(hw, UCCR);	/*  68 */ -	*reg++ = IXGB_READ_REG(hw, XPCSTC);	/*  69 */ -	*reg++ = IXGB_READ_REG(hw, MACA);	/*  70 */ -	*reg++ = IXGB_READ_REG(hw, APAE);	/*  71 */ -	*reg++ = IXGB_READ_REG(hw, ARD);	/*  72 */ -	*reg++ = IXGB_READ_REG(hw, AIS);	/*  73 */ -	*reg++ = IXGB_READ_REG(hw, MSCA);	/*  74 */ -	*reg++ = IXGB_READ_REG(hw, MSRWD);	/*  75 */ - -	/* Statistics */ -	*reg++ = IXGB_GET_STAT(adapter, tprl);	/*  76 */ -	*reg++ = IXGB_GET_STAT(adapter, tprh);	/*  77 */ -	*reg++ = IXGB_GET_STAT(adapter, gprcl);	/*  78 */ -	*reg++ = IXGB_GET_STAT(adapter, gprch);	/*  79 */ -	*reg++ = IXGB_GET_STAT(adapter, bprcl);	/*  80 */ -	*reg++ = IXGB_GET_STAT(adapter, bprch);	/*  81 */ -	*reg++ = IXGB_GET_STAT(adapter, mprcl);	/*  82 */ -	*reg++ = IXGB_GET_STAT(adapter, mprch);	/*  83 */ -	*reg++ = IXGB_GET_STAT(adapter, uprcl);	/*  84 */ -	*reg++ = IXGB_GET_STAT(adapter, uprch);	/*  85 */ -	*reg++ = IXGB_GET_STAT(adapter, vprcl);	/*  86 */ -	*reg++ = IXGB_GET_STAT(adapter, vprch);	/*  87 */ -	*reg++ = IXGB_GET_STAT(adapter, jprcl);	/*  88 */ -	*reg++ = IXGB_GET_STAT(adapter, jprch);	/*  89 */ -	*reg++ = IXGB_GET_STAT(adapter, gorcl);	/*  90 */ -	*reg++ = IXGB_GET_STAT(adapter, gorch);	/*  91 */ -	*reg++ = IXGB_GET_STAT(adapter, torl);	/*  92 */ -	*reg++ = IXGB_GET_STAT(adapter, torh);	/*  93 */ -	*reg++ = IXGB_GET_STAT(adapter, rnbc);	/*  94 */ -	*reg++ = IXGB_GET_STAT(adapter, ruc);	/*  95 */ -	*reg++ = IXGB_GET_STAT(adapter, roc);	/*  96 */ -	*reg++ = IXGB_GET_STAT(adapter, rlec);	/*  97 */ -	*reg++ = IXGB_GET_STAT(adapter, crcerrs);	/*  98 */ -	*reg++ = IXGB_GET_STAT(adapter, icbc);	/*  99 */ -	*reg++ = IXGB_GET_STAT(adapter, ecbc);	/* 100 */ -	*reg++ = IXGB_GET_STAT(adapter, mpc);	/* 101 */ -	*reg++ = IXGB_GET_STAT(adapter, tptl);	/* 102 */ -	*reg++ = IXGB_GET_STAT(adapter, tpth);	/* 103 */ -	*reg++ = IXGB_GET_STAT(adapter, gptcl);	/* 104 */ -	*reg++ = IXGB_GET_STAT(adapter, gptch);	/* 105 */ -	*reg++ = IXGB_GET_STAT(adapter, bptcl);	/* 106 */ -	*reg++ = IXGB_GET_STAT(adapter, bptch);	/* 107 */ -	*reg++ = IXGB_GET_STAT(adapter, mptcl);	/* 108 */ -	*reg++ = IXGB_GET_STAT(adapter, mptch);	/* 109 */ -	*reg++ = IXGB_GET_STAT(adapter, uptcl);	/* 110 */ -	*reg++ = IXGB_GET_STAT(adapter, uptch);	/* 111 */ -	*reg++ = IXGB_GET_STAT(adapter, vptcl);	/* 112 */ -	*reg++ = IXGB_GET_STAT(adapter, vptch);	/* 113 */ -	*reg++ = IXGB_GET_STAT(adapter, jptcl);	/* 114 */ -	*reg++ = IXGB_GET_STAT(adapter, jptch);	/* 115 */ -	*reg++ = IXGB_GET_STAT(adapter, gotcl);	/* 116 */ -	*reg++ = IXGB_GET_STAT(adapter, gotch);	/* 117 */ -	*reg++ = IXGB_GET_STAT(adapter, totl);	/* 118 */ -	*reg++ = IXGB_GET_STAT(adapter, toth);	/* 119 */ -	*reg++ = IXGB_GET_STAT(adapter, dc);	/* 120 */ -	*reg++ = IXGB_GET_STAT(adapter, plt64c);	/* 121 */ -	*reg++ = IXGB_GET_STAT(adapter, tsctc);	/* 122 */ -	*reg++ = IXGB_GET_STAT(adapter, tsctfc);	/* 123 */ -	*reg++ = IXGB_GET_STAT(adapter, ibic);	/* 124 */ -	*reg++ = IXGB_GET_STAT(adapter, rfc);	/* 125 */ -	*reg++ = IXGB_GET_STAT(adapter, lfc);	/* 126 */ -	*reg++ = IXGB_GET_STAT(adapter, pfrc);	/* 127 */ -	*reg++ = IXGB_GET_STAT(adapter, pftc);	/* 128 */ -	*reg++ = IXGB_GET_STAT(adapter, mcfrc);	/* 129 */ -	*reg++ = IXGB_GET_STAT(adapter, mcftc);	/* 130 */ -	*reg++ = IXGB_GET_STAT(adapter, xonrxc);	/* 131 */ -	*reg++ = IXGB_GET_STAT(adapter, xontxc);	/* 132 */ -	*reg++ = IXGB_GET_STAT(adapter, xoffrxc);	/* 133 */ -	*reg++ = IXGB_GET_STAT(adapter, xofftxc);	/* 134 */ -	*reg++ = IXGB_GET_STAT(adapter, rjc);	/* 135 */ - -	regs->len = (reg - reg_start) * sizeof(u32); -} - -static int -ixgb_get_eeprom_len(struct net_device *netdev) -{ -	/* return size in bytes */ -	return IXGB_EEPROM_SIZE << 1; -} - -static int -ixgb_get_eeprom(struct net_device *netdev, -		  struct ethtool_eeprom *eeprom, u8 *bytes) -{ -	struct ixgb_adapter *adapter = netdev_priv(netdev); -	struct ixgb_hw *hw = &adapter->hw; -	__le16 *eeprom_buff; -	int i, max_len, first_word, last_word; -	int ret_val = 0; - -	if (eeprom->len == 0) { -		ret_val = -EINVAL; -		goto geeprom_error; -	} - -	eeprom->magic = hw->vendor_id | (hw->device_id << 16); - -	max_len = ixgb_get_eeprom_len(netdev); - -	if (eeprom->offset > eeprom->offset + eeprom->len) { -		ret_val = -EINVAL; -		goto geeprom_error; -	} - -	if ((eeprom->offset + eeprom->len) > max_len) -		eeprom->len = (max_len - eeprom->offset); - -	first_word = eeprom->offset >> 1; -	last_word = (eeprom->offset + eeprom->len - 1) >> 1; - -	eeprom_buff = kmalloc_array(last_word - first_word + 1, -				    sizeof(__le16), -				    GFP_KERNEL); -	if (!eeprom_buff) -		return -ENOMEM; - -	/* note the eeprom was good because the driver loaded */ -	for (i = 0; i <= (last_word - first_word); i++) -		eeprom_buff[i] = ixgb_get_eeprom_word(hw, (first_word + i)); - -	memcpy(bytes, (u8 *)eeprom_buff + (eeprom->offset & 1), eeprom->len); -	kfree(eeprom_buff); - -geeprom_error: -	return ret_val; -} - -static int -ixgb_set_eeprom(struct net_device *netdev, -		  struct ethtool_eeprom *eeprom, u8 *bytes) -{ -	struct ixgb_adapter *adapter = netdev_priv(netdev); -	struct ixgb_hw *hw = &adapter->hw; -	u16 *eeprom_buff; -	void *ptr; -	int max_len, first_word, last_word; -	u16 i; - -	if (eeprom->len == 0) -		return -EINVAL; - -	if (eeprom->magic != (hw->vendor_id | (hw->device_id << 16))) -		return -EFAULT; - -	max_len = ixgb_get_eeprom_len(netdev); - -	if (eeprom->offset > eeprom->offset + eeprom->len) -		return -EINVAL; - -	if ((eeprom->offset + eeprom->len) > max_len) -		eeprom->len = (max_len - eeprom->offset); - -	first_word = eeprom->offset >> 1; -	last_word = (eeprom->offset + eeprom->len - 1) >> 1; -	eeprom_buff = kmalloc(max_len, GFP_KERNEL); -	if (!eeprom_buff) -		return -ENOMEM; - -	ptr = (void *)eeprom_buff; - -	if (eeprom->offset & 1) { -		/* need read/modify/write of first changed EEPROM word */ -		/* only the second byte of the word is being modified */ -		eeprom_buff[0] = ixgb_read_eeprom(hw, first_word); -		ptr++; -	} -	if ((eeprom->offset + eeprom->len) & 1) { -		/* need read/modify/write of last changed EEPROM word */ -		/* only the first byte of the word is being modified */ -		eeprom_buff[last_word - first_word] -			= ixgb_read_eeprom(hw, last_word); -	} - -	memcpy(ptr, bytes, eeprom->len); -	for (i = 0; i <= (last_word - first_word); i++) -		ixgb_write_eeprom(hw, first_word + i, eeprom_buff[i]); - -	/* Update the checksum over the first part of the EEPROM if needed */ -	if (first_word <= EEPROM_CHECKSUM_REG) -		ixgb_update_eeprom_checksum(hw); - -	kfree(eeprom_buff); -	return 0; -} - -static void -ixgb_get_drvinfo(struct net_device *netdev, -		   struct ethtool_drvinfo *drvinfo) -{ -	struct ixgb_adapter *adapter = netdev_priv(netdev); - -	strscpy(drvinfo->driver,  ixgb_driver_name, -		sizeof(drvinfo->driver)); -	strscpy(drvinfo->bus_info, pci_name(adapter->pdev), -		sizeof(drvinfo->bus_info)); -} - -static void -ixgb_get_ringparam(struct net_device *netdev, -		   struct ethtool_ringparam *ring, -		   struct kernel_ethtool_ringparam *kernel_ring, -		   struct netlink_ext_ack *extack) -{ -	struct ixgb_adapter *adapter = netdev_priv(netdev); -	struct ixgb_desc_ring *txdr = &adapter->tx_ring; -	struct ixgb_desc_ring *rxdr = &adapter->rx_ring; - -	ring->rx_max_pending = MAX_RXD; -	ring->tx_max_pending = MAX_TXD; -	ring->rx_pending = rxdr->count; -	ring->tx_pending = txdr->count; -} - -static int -ixgb_set_ringparam(struct net_device *netdev, -		   struct ethtool_ringparam *ring, -		   struct kernel_ethtool_ringparam *kernel_ring, -		   struct netlink_ext_ack *extack) -{ -	struct ixgb_adapter *adapter = netdev_priv(netdev); -	struct ixgb_desc_ring *txdr = &adapter->tx_ring; -	struct ixgb_desc_ring *rxdr = &adapter->rx_ring; -	struct ixgb_desc_ring tx_old, tx_new, rx_old, rx_new; -	int err; - -	tx_old = adapter->tx_ring; -	rx_old = adapter->rx_ring; - -	if ((ring->rx_mini_pending) || (ring->rx_jumbo_pending)) -		return -EINVAL; - -	if (netif_running(adapter->netdev)) -		ixgb_down(adapter, true); - -	rxdr->count = max(ring->rx_pending,(u32)MIN_RXD); -	rxdr->count = min(rxdr->count,(u32)MAX_RXD); -	rxdr->count = ALIGN(rxdr->count, IXGB_REQ_RX_DESCRIPTOR_MULTIPLE); - -	txdr->count = max(ring->tx_pending,(u32)MIN_TXD); -	txdr->count = min(txdr->count,(u32)MAX_TXD); -	txdr->count = ALIGN(txdr->count, IXGB_REQ_TX_DESCRIPTOR_MULTIPLE); - -	if (netif_running(adapter->netdev)) { -		/* Try to get new resources before deleting old */ -		if ((err = ixgb_setup_rx_resources(adapter))) -			goto err_setup_rx; -		if ((err = ixgb_setup_tx_resources(adapter))) -			goto err_setup_tx; - -		/* save the new, restore the old in order to free it, -		 * then restore the new back again */ - -		rx_new = adapter->rx_ring; -		tx_new = adapter->tx_ring; -		adapter->rx_ring = rx_old; -		adapter->tx_ring = tx_old; -		ixgb_free_rx_resources(adapter); -		ixgb_free_tx_resources(adapter); -		adapter->rx_ring = rx_new; -		adapter->tx_ring = tx_new; -		if ((err = ixgb_up(adapter))) -			return err; -		ixgb_set_speed_duplex(netdev); -	} - -	return 0; -err_setup_tx: -	ixgb_free_rx_resources(adapter); -err_setup_rx: -	adapter->rx_ring = rx_old; -	adapter->tx_ring = tx_old; -	ixgb_up(adapter); -	return err; -} - -static int -ixgb_set_phys_id(struct net_device *netdev, enum ethtool_phys_id_state state) -{ -	struct ixgb_adapter *adapter = netdev_priv(netdev); - -	switch (state) { -	case ETHTOOL_ID_ACTIVE: -		return 2; - -	case ETHTOOL_ID_ON: -		ixgb_led_on(&adapter->hw); -		break; - -	case ETHTOOL_ID_OFF: -	case ETHTOOL_ID_INACTIVE: -		ixgb_led_off(&adapter->hw); -	} - -	return 0; -} - -static int -ixgb_get_sset_count(struct net_device *netdev, int sset) -{ -	switch (sset) { -	case ETH_SS_STATS: -		return IXGB_STATS_LEN; -	default: -		return -EOPNOTSUPP; -	} -} - -static void -ixgb_get_ethtool_stats(struct net_device *netdev, -		struct ethtool_stats *stats, u64 *data) -{ -	struct ixgb_adapter *adapter = netdev_priv(netdev); -	int i; -	char *p = NULL; - -	ixgb_update_stats(adapter); -	for (i = 0; i < IXGB_STATS_LEN; i++) { -		switch (ixgb_gstrings_stats[i].type) { -		case NETDEV_STATS: -			p = (char *) netdev + -					ixgb_gstrings_stats[i].stat_offset; -			break; -		case IXGB_STATS: -			p = (char *) adapter + -					ixgb_gstrings_stats[i].stat_offset; -			break; -		} - -		data[i] = (ixgb_gstrings_stats[i].sizeof_stat == -			sizeof(u64)) ? *(u64 *)p : *(u32 *)p; -	} -} - -static void -ixgb_get_strings(struct net_device *netdev, u32 stringset, u8 *data) -{ -	int i; - -	switch(stringset) { -	case ETH_SS_STATS: -		for (i = 0; i < IXGB_STATS_LEN; i++) { -			memcpy(data + i * ETH_GSTRING_LEN, -			ixgb_gstrings_stats[i].stat_string, -			ETH_GSTRING_LEN); -		} -		break; -	} -} - -static const struct ethtool_ops ixgb_ethtool_ops = { -	.get_drvinfo = ixgb_get_drvinfo, -	.get_regs_len = ixgb_get_regs_len, -	.get_regs = ixgb_get_regs, -	.get_link = ethtool_op_get_link, -	.get_eeprom_len = ixgb_get_eeprom_len, -	.get_eeprom = ixgb_get_eeprom, -	.set_eeprom = ixgb_set_eeprom, -	.get_ringparam = ixgb_get_ringparam, -	.set_ringparam = ixgb_set_ringparam, -	.get_pauseparam	= ixgb_get_pauseparam, -	.set_pauseparam	= ixgb_set_pauseparam, -	.get_msglevel = ixgb_get_msglevel, -	.set_msglevel = ixgb_set_msglevel, -	.get_strings = ixgb_get_strings, -	.set_phys_id = ixgb_set_phys_id, -	.get_sset_count = ixgb_get_sset_count, -	.get_ethtool_stats = ixgb_get_ethtool_stats, -	.get_link_ksettings = ixgb_get_link_ksettings, -	.set_link_ksettings = ixgb_set_link_ksettings, -}; - -void ixgb_set_ethtool_ops(struct net_device *netdev) -{ -	netdev->ethtool_ops = &ixgb_ethtool_ops; -} diff --git a/drivers/net/ethernet/intel/ixgb/ixgb_hw.c b/drivers/net/ethernet/intel/ixgb/ixgb_hw.c deleted file mode 100644 index 98bd3267b99b..000000000000 --- a/drivers/net/ethernet/intel/ixgb/ixgb_hw.c +++ /dev/null @@ -1,1229 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0 -/* Copyright(c) 1999 - 2008 Intel Corporation. */ - -/* ixgb_hw.c - * Shared functions for accessing and configuring the adapter - */ - -#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt - -#include <linux/pci_ids.h> -#include "ixgb_hw.h" -#include "ixgb_ids.h" - -#include <linux/etherdevice.h> - -/*  Local function prototypes */ - -static u32 ixgb_hash_mc_addr(struct ixgb_hw *hw, u8 * mc_addr); - -static void ixgb_mta_set(struct ixgb_hw *hw, u32 hash_value); - -static void ixgb_get_bus_info(struct ixgb_hw *hw); - -static bool ixgb_link_reset(struct ixgb_hw *hw); - -static void ixgb_optics_reset(struct ixgb_hw *hw); - -static void ixgb_optics_reset_bcm(struct ixgb_hw *hw); - -static ixgb_phy_type ixgb_identify_phy(struct ixgb_hw *hw); - -static void ixgb_clear_hw_cntrs(struct ixgb_hw *hw); - -static void ixgb_clear_vfta(struct ixgb_hw *hw); - -static void ixgb_init_rx_addrs(struct ixgb_hw *hw); - -static u16 ixgb_read_phy_reg(struct ixgb_hw *hw, -				  u32 reg_address, -				  u32 phy_address, -				  u32 device_type); - -static bool ixgb_setup_fc(struct ixgb_hw *hw); - -static bool mac_addr_valid(u8 *mac_addr); - -static u32 ixgb_mac_reset(struct ixgb_hw *hw) -{ -	u32 ctrl_reg; - -	ctrl_reg =  IXGB_CTRL0_RST | -				IXGB_CTRL0_SDP3_DIR |   /* All pins are Output=1 */ -				IXGB_CTRL0_SDP2_DIR | -				IXGB_CTRL0_SDP1_DIR | -				IXGB_CTRL0_SDP0_DIR | -				IXGB_CTRL0_SDP3	 |   /* Initial value 1101   */ -				IXGB_CTRL0_SDP2	 | -				IXGB_CTRL0_SDP0; - -#ifdef HP_ZX1 -	/* Workaround for 82597EX reset errata */ -	IXGB_WRITE_REG_IO(hw, CTRL0, ctrl_reg); -#else -	IXGB_WRITE_REG(hw, CTRL0, ctrl_reg); -#endif - -	/* Delay a few ms just to allow the reset to complete */ -	msleep(IXGB_DELAY_AFTER_RESET); -	ctrl_reg = IXGB_READ_REG(hw, CTRL0); -#ifdef DBG -	/* Make sure the self-clearing global reset bit did self clear */ -	ASSERT(!(ctrl_reg & IXGB_CTRL0_RST)); -#endif - -	if (hw->subsystem_vendor_id == PCI_VENDOR_ID_SUN) { -		ctrl_reg =  /* Enable interrupt from XFP and SerDes */ -			   IXGB_CTRL1_GPI0_EN | -			   IXGB_CTRL1_SDP6_DIR | -			   IXGB_CTRL1_SDP7_DIR | -			   IXGB_CTRL1_SDP6 | -			   IXGB_CTRL1_SDP7; -		IXGB_WRITE_REG(hw, CTRL1, ctrl_reg); -		ixgb_optics_reset_bcm(hw); -	} - -	if (hw->phy_type == ixgb_phy_type_txn17401) -		ixgb_optics_reset(hw); - -	return ctrl_reg; -} - -/****************************************************************************** - * Reset the transmit and receive units; mask and clear all interrupts. - * - * hw - Struct containing variables accessed by shared code - *****************************************************************************/ -bool -ixgb_adapter_stop(struct ixgb_hw *hw) -{ -	u32 ctrl_reg; - -	ENTER(); - -	/* If we are stopped or resetting exit gracefully and wait to be -	 * started again before accessing the hardware. -	 */ -	if (hw->adapter_stopped) { -		pr_debug("Exiting because the adapter is already stopped!!!\n"); -		return false; -	} - -	/* Set the Adapter Stopped flag so other driver functions stop -	 * touching the Hardware. -	 */ -	hw->adapter_stopped = true; - -	/* Clear interrupt mask to stop board from generating interrupts */ -	pr_debug("Masking off all interrupts\n"); -	IXGB_WRITE_REG(hw, IMC, 0xFFFFFFFF); - -	/* Disable the Transmit and Receive units.  Then delay to allow -	 * any pending transactions to complete before we hit the MAC with -	 * the global reset. -	 */ -	IXGB_WRITE_REG(hw, RCTL, IXGB_READ_REG(hw, RCTL) & ~IXGB_RCTL_RXEN); -	IXGB_WRITE_REG(hw, TCTL, IXGB_READ_REG(hw, TCTL) & ~IXGB_TCTL_TXEN); -	IXGB_WRITE_FLUSH(hw); -	msleep(IXGB_DELAY_BEFORE_RESET); - -	/* Issue a global reset to the MAC.  This will reset the chip's -	 * transmit, receive, DMA, and link units.  It will not effect -	 * the current PCI configuration.  The global reset bit is self- -	 * clearing, and should clear within a microsecond. -	 */ -	pr_debug("Issuing a global reset to MAC\n"); - -	ctrl_reg = ixgb_mac_reset(hw); - -	/* Clear interrupt mask to stop board from generating interrupts */ -	pr_debug("Masking off all interrupts\n"); -	IXGB_WRITE_REG(hw, IMC, 0xffffffff); - -	/* Clear any pending interrupt events. */ -	IXGB_READ_REG(hw, ICR); - -	return ctrl_reg & IXGB_CTRL0_RST; -} - - -/****************************************************************************** - * Identifies the vendor of the optics module on the adapter.  The SR adapters - * support two different types of XPAK optics, so it is necessary to determine - * which optics are present before applying any optics-specific workarounds. - * - * hw - Struct containing variables accessed by shared code. - * - * Returns: the vendor of the XPAK optics module. - *****************************************************************************/ -static ixgb_xpak_vendor -ixgb_identify_xpak_vendor(struct ixgb_hw *hw) -{ -	u32 i; -	u16 vendor_name[5]; -	ixgb_xpak_vendor xpak_vendor; - -	ENTER(); - -	/* Read the first few bytes of the vendor string from the XPAK NVR -	 * registers.  These are standard XENPAK/XPAK registers, so all XPAK -	 * devices should implement them. */ -	for (i = 0; i < 5; i++) { -		vendor_name[i] = ixgb_read_phy_reg(hw, -						   MDIO_PMA_PMD_XPAK_VENDOR_NAME -						   + i, IXGB_PHY_ADDRESS, -						   MDIO_MMD_PMAPMD); -	} - -	/* Determine the actual vendor */ -	if (vendor_name[0] == 'I' && -	    vendor_name[1] == 'N' && -	    vendor_name[2] == 'T' && -	    vendor_name[3] == 'E' && vendor_name[4] == 'L') { -		xpak_vendor = ixgb_xpak_vendor_intel; -	} else { -		xpak_vendor = ixgb_xpak_vendor_infineon; -	} - -	return xpak_vendor; -} - -/****************************************************************************** - * Determine the physical layer module on the adapter. - * - * hw - Struct containing variables accessed by shared code.  The device_id - *      field must be (correctly) populated before calling this routine. - * - * Returns: the phy type of the adapter. - *****************************************************************************/ -static ixgb_phy_type -ixgb_identify_phy(struct ixgb_hw *hw) -{ -	ixgb_phy_type phy_type; -	ixgb_xpak_vendor xpak_vendor; - -	ENTER(); - -	/* Infer the transceiver/phy type from the device id */ -	switch (hw->device_id) { -	case IXGB_DEVICE_ID_82597EX: -		pr_debug("Identified TXN17401 optics\n"); -		phy_type = ixgb_phy_type_txn17401; -		break; - -	case IXGB_DEVICE_ID_82597EX_SR: -		/* The SR adapters carry two different types of XPAK optics -		 * modules; read the vendor identifier to determine the exact -		 * type of optics. */ -		xpak_vendor = ixgb_identify_xpak_vendor(hw); -		if (xpak_vendor == ixgb_xpak_vendor_intel) { -			pr_debug("Identified TXN17201 optics\n"); -			phy_type = ixgb_phy_type_txn17201; -		} else { -			pr_debug("Identified G6005 optics\n"); -			phy_type = ixgb_phy_type_g6005; -		} -		break; -	case IXGB_DEVICE_ID_82597EX_LR: -		pr_debug("Identified G6104 optics\n"); -		phy_type = ixgb_phy_type_g6104; -		break; -	case IXGB_DEVICE_ID_82597EX_CX4: -		pr_debug("Identified CX4\n"); -		xpak_vendor = ixgb_identify_xpak_vendor(hw); -		if (xpak_vendor == ixgb_xpak_vendor_intel) { -			pr_debug("Identified TXN17201 optics\n"); -			phy_type = ixgb_phy_type_txn17201; -		} else { -			pr_debug("Identified G6005 optics\n"); -			phy_type = ixgb_phy_type_g6005; -		} -		break; -	default: -		pr_debug("Unknown physical layer module\n"); -		phy_type = ixgb_phy_type_unknown; -		break; -	} - -	/* update phy type for sun specific board */ -	if (hw->subsystem_vendor_id == PCI_VENDOR_ID_SUN) -		phy_type = ixgb_phy_type_bcm; - -	return phy_type; -} - -/****************************************************************************** - * Performs basic configuration of the adapter. - * - * hw - Struct containing variables accessed by shared code - * - * Resets the controller. - * Reads and validates the EEPROM. - * Initializes the receive address registers. - * Initializes the multicast table. - * Clears all on-chip counters. - * Calls routine to setup flow control settings. - * Leaves the transmit and receive units disabled and uninitialized. - * - * Returns: - *      true if successful, - *      false if unrecoverable problems were encountered. - *****************************************************************************/ -bool -ixgb_init_hw(struct ixgb_hw *hw) -{ -	u32 i; -	bool status; - -	ENTER(); - -	/* Issue a global reset to the MAC.  This will reset the chip's -	 * transmit, receive, DMA, and link units.  It will not effect -	 * the current PCI configuration.  The global reset bit is self- -	 * clearing, and should clear within a microsecond. -	 */ -	pr_debug("Issuing a global reset to MAC\n"); - -	ixgb_mac_reset(hw); - -	pr_debug("Issuing an EE reset to MAC\n"); -#ifdef HP_ZX1 -	/* Workaround for 82597EX reset errata */ -	IXGB_WRITE_REG_IO(hw, CTRL1, IXGB_CTRL1_EE_RST); -#else -	IXGB_WRITE_REG(hw, CTRL1, IXGB_CTRL1_EE_RST); -#endif - -	/* Delay a few ms just to allow the reset to complete */ -	msleep(IXGB_DELAY_AFTER_EE_RESET); - -	if (!ixgb_get_eeprom_data(hw)) -		return false; - -	/* Use the device id to determine the type of phy/transceiver. */ -	hw->device_id = ixgb_get_ee_device_id(hw); -	hw->phy_type = ixgb_identify_phy(hw); - -	/* Setup the receive addresses. -	 * Receive Address Registers (RARs 0 - 15). -	 */ -	ixgb_init_rx_addrs(hw); - -	/* -	 * Check that a valid MAC address has been set. -	 * If it is not valid, we fail hardware init. -	 */ -	if (!mac_addr_valid(hw->curr_mac_addr)) { -		pr_debug("MAC address invalid after ixgb_init_rx_addrs\n"); -		return(false); -	} - -	/* tell the routines in this file they can access hardware again */ -	hw->adapter_stopped = false; - -	/* Fill in the bus_info structure */ -	ixgb_get_bus_info(hw); - -	/* Zero out the Multicast HASH table */ -	pr_debug("Zeroing the MTA\n"); -	for (i = 0; i < IXGB_MC_TBL_SIZE; i++) -		IXGB_WRITE_REG_ARRAY(hw, MTA, i, 0); - -	/* Zero out the VLAN Filter Table Array */ -	ixgb_clear_vfta(hw); - -	/* Zero all of the hardware counters */ -	ixgb_clear_hw_cntrs(hw); - -	/* Call a subroutine to setup flow control. */ -	status = ixgb_setup_fc(hw); - -	/* 82597EX errata: Call check-for-link in case lane deskew is locked */ -	ixgb_check_for_link(hw); - -	return status; -} - -/****************************************************************************** - * Initializes receive address filters. - * - * hw - Struct containing variables accessed by shared code - * - * Places the MAC address in receive address register 0 and clears the rest - * of the receive address registers. Clears the multicast table. Assumes - * the receiver is in reset when the routine is called. - *****************************************************************************/ -static void -ixgb_init_rx_addrs(struct ixgb_hw *hw) -{ -	u32 i; - -	ENTER(); - -	/* -	 * If the current mac address is valid, assume it is a software override -	 * to the permanent address. -	 * Otherwise, use the permanent address from the eeprom. -	 */ -	if (!mac_addr_valid(hw->curr_mac_addr)) { - -		/* Get the MAC address from the eeprom for later reference */ -		ixgb_get_ee_mac_addr(hw, hw->curr_mac_addr); - -		pr_debug("Keeping Permanent MAC Addr = %pM\n", -			 hw->curr_mac_addr); -	} else { - -		/* Setup the receive address. */ -		pr_debug("Overriding MAC Address in RAR[0]\n"); -		pr_debug("New MAC Addr = %pM\n", hw->curr_mac_addr); - -		ixgb_rar_set(hw, hw->curr_mac_addr, 0); -	} - -	/* Zero out the other 15 receive addresses. */ -	pr_debug("Clearing RAR[1-15]\n"); -	for (i = 1; i < IXGB_RAR_ENTRIES; i++) { -		/* Write high reg first to disable the AV bit first */ -		IXGB_WRITE_REG_ARRAY(hw, RA, ((i << 1) + 1), 0); -		IXGB_WRITE_REG_ARRAY(hw, RA, (i << 1), 0); -	} -} - -/****************************************************************************** - * Updates the MAC's list of multicast addresses. - * - * hw - Struct containing variables accessed by shared code - * mc_addr_list - the list of new multicast addresses - * mc_addr_count - number of addresses - * pad - number of bytes between addresses in the list - * - * The given list replaces any existing list. Clears the last 15 receive - * address registers and the multicast table. Uses receive address registers - * for the first 15 multicast addresses, and hashes the rest into the - * multicast table. - *****************************************************************************/ -void -ixgb_mc_addr_list_update(struct ixgb_hw *hw, -			  u8 *mc_addr_list, -			  u32 mc_addr_count, -			  u32 pad) -{ -	u32 hash_value; -	u32 i; -	u32 rar_used_count = 1;		/* RAR[0] is used for our MAC address */ -	u8 *mca; - -	ENTER(); - -	/* Set the new number of MC addresses that we are being requested to use. */ -	hw->num_mc_addrs = mc_addr_count; - -	/* Clear RAR[1-15] */ -	pr_debug("Clearing RAR[1-15]\n"); -	for (i = rar_used_count; i < IXGB_RAR_ENTRIES; i++) { -		IXGB_WRITE_REG_ARRAY(hw, RA, (i << 1), 0); -		IXGB_WRITE_REG_ARRAY(hw, RA, ((i << 1) + 1), 0); -	} - -	/* Clear the MTA */ -	pr_debug("Clearing MTA\n"); -	for (i = 0; i < IXGB_MC_TBL_SIZE; i++) -		IXGB_WRITE_REG_ARRAY(hw, MTA, i, 0); - -	/* Add the new addresses */ -	mca = mc_addr_list; -	for (i = 0; i < mc_addr_count; i++) { -		pr_debug("Adding the multicast addresses:\n"); -		pr_debug("MC Addr #%d = %pM\n", i, mca); - -		/* Place this multicast address in the RAR if there is room, * -		 * else put it in the MTA -		 */ -		if (rar_used_count < IXGB_RAR_ENTRIES) { -			ixgb_rar_set(hw, mca, rar_used_count); -			pr_debug("Added a multicast address to RAR[%d]\n", i); -			rar_used_count++; -		} else { -			hash_value = ixgb_hash_mc_addr(hw, mca); - -			pr_debug("Hash value = 0x%03X\n", hash_value); - -			ixgb_mta_set(hw, hash_value); -		} - -		mca += ETH_ALEN + pad; -	} - -	pr_debug("MC Update Complete\n"); -} - -/****************************************************************************** - * Hashes an address to determine its location in the multicast table - * - * hw - Struct containing variables accessed by shared code - * mc_addr - the multicast address to hash - * - * Returns: - *      The hash value - *****************************************************************************/ -static u32 -ixgb_hash_mc_addr(struct ixgb_hw *hw, -		   u8 *mc_addr) -{ -	u32 hash_value = 0; - -	ENTER(); - -	/* The portion of the address that is used for the hash table is -	 * determined by the mc_filter_type setting. -	 */ -	switch (hw->mc_filter_type) { -		/* [0] [1] [2] [3] [4] [5] -		 * 01  AA  00  12  34  56 -		 * LSB                 MSB - According to H/W docs */ -	case 0: -		/* [47:36] i.e. 0x563 for above example address */ -		hash_value = -		    ((mc_addr[4] >> 4) | (((u16) mc_addr[5]) << 4)); -		break; -	case 1:		/* [46:35] i.e. 0xAC6 for above example address */ -		hash_value = -		    ((mc_addr[4] >> 3) | (((u16) mc_addr[5]) << 5)); -		break; -	case 2:		/* [45:34] i.e. 0x5D8 for above example address */ -		hash_value = -		    ((mc_addr[4] >> 2) | (((u16) mc_addr[5]) << 6)); -		break; -	case 3:		/* [43:32] i.e. 0x634 for above example address */ -		hash_value = ((mc_addr[4]) | (((u16) mc_addr[5]) << 8)); -		break; -	default: -		/* Invalid mc_filter_type, what should we do? */ -		pr_debug("MC filter type param set incorrectly\n"); -		ASSERT(0); -		break; -	} - -	hash_value &= 0xFFF; -	return hash_value; -} - -/****************************************************************************** - * Sets the bit in the multicast table corresponding to the hash value. - * - * hw - Struct containing variables accessed by shared code - * hash_value - Multicast address hash value - *****************************************************************************/ -static void -ixgb_mta_set(struct ixgb_hw *hw, -		  u32 hash_value) -{ -	u32 hash_bit, hash_reg; -	u32 mta_reg; - -	/* The MTA is a register array of 128 32-bit registers. -	 * It is treated like an array of 4096 bits.  We want to set -	 * bit BitArray[hash_value]. So we figure out what register -	 * the bit is in, read it, OR in the new bit, then write -	 * back the new value.  The register is determined by the -	 * upper 7 bits of the hash value and the bit within that -	 * register are determined by the lower 5 bits of the value. -	 */ -	hash_reg = (hash_value >> 5) & 0x7F; -	hash_bit = hash_value & 0x1F; - -	mta_reg = IXGB_READ_REG_ARRAY(hw, MTA, hash_reg); - -	mta_reg |= (1 << hash_bit); - -	IXGB_WRITE_REG_ARRAY(hw, MTA, hash_reg, mta_reg); -} - -/****************************************************************************** - * Puts an ethernet address into a receive address register. - * - * hw - Struct containing variables accessed by shared code - * addr - Address to put into receive address register - * index - Receive address register to write - *****************************************************************************/ -void -ixgb_rar_set(struct ixgb_hw *hw, -		  const u8 *addr, -		  u32 index) -{ -	u32 rar_low, rar_high; - -	ENTER(); - -	/* HW expects these in little endian so we reverse the byte order -	 * from network order (big endian) to little endian -	 */ -	rar_low = ((u32) addr[0] | -		   ((u32)addr[1] << 8) | -		   ((u32)addr[2] << 16) | -		   ((u32)addr[3] << 24)); - -	rar_high = ((u32) addr[4] | -			((u32)addr[5] << 8) | -			IXGB_RAH_AV); - -	IXGB_WRITE_REG_ARRAY(hw, RA, (index << 1), rar_low); -	IXGB_WRITE_REG_ARRAY(hw, RA, ((index << 1) + 1), rar_high); -} - -/****************************************************************************** - * Writes a value to the specified offset in the VLAN filter table. - * - * hw - Struct containing variables accessed by shared code - * offset - Offset in VLAN filter table to write - * value - Value to write into VLAN filter table - *****************************************************************************/ -void -ixgb_write_vfta(struct ixgb_hw *hw, -		 u32 offset, -		 u32 value) -{ -	IXGB_WRITE_REG_ARRAY(hw, VFTA, offset, value); -} - -/****************************************************************************** - * Clears the VLAN filter table - * - * hw - Struct containing variables accessed by shared code - *****************************************************************************/ -static void -ixgb_clear_vfta(struct ixgb_hw *hw) -{ -	u32 offset; - -	for (offset = 0; offset < IXGB_VLAN_FILTER_TBL_SIZE; offset++) -		IXGB_WRITE_REG_ARRAY(hw, VFTA, offset, 0); -} - -/****************************************************************************** - * Configures the flow control settings based on SW configuration. - * - * hw - Struct containing variables accessed by shared code - *****************************************************************************/ - -static bool -ixgb_setup_fc(struct ixgb_hw *hw) -{ -	u32 ctrl_reg; -	u32 pap_reg = 0;   /* by default, assume no pause time */ -	bool status = true; - -	ENTER(); - -	/* Get the current control reg 0 settings */ -	ctrl_reg = IXGB_READ_REG(hw, CTRL0); - -	/* Clear the Receive Pause Enable and Transmit Pause Enable bits */ -	ctrl_reg &= ~(IXGB_CTRL0_RPE | IXGB_CTRL0_TPE); - -	/* The possible values of the "flow_control" parameter are: -	 *      0:  Flow control is completely disabled -	 *      1:  Rx flow control is enabled (we can receive pause frames -	 *          but not send pause frames). -	 *      2:  Tx flow control is enabled (we can send pause frames -	 *          but we do not support receiving pause frames). -	 *      3:  Both Rx and TX flow control (symmetric) are enabled. -	 *  other:  Invalid. -	 */ -	switch (hw->fc.type) { -	case ixgb_fc_none:	/* 0 */ -		/* Set CMDC bit to disable Rx Flow control */ -		ctrl_reg |= (IXGB_CTRL0_CMDC); -		break; -	case ixgb_fc_rx_pause:	/* 1 */ -		/* RX Flow control is enabled, and TX Flow control is -		 * disabled. -		 */ -		ctrl_reg |= (IXGB_CTRL0_RPE); -		break; -	case ixgb_fc_tx_pause:	/* 2 */ -		/* TX Flow control is enabled, and RX Flow control is -		 * disabled, by a software over-ride. -		 */ -		ctrl_reg |= (IXGB_CTRL0_TPE); -		pap_reg = hw->fc.pause_time; -		break; -	case ixgb_fc_full:	/* 3 */ -		/* Flow control (both RX and TX) is enabled by a software -		 * over-ride. -		 */ -		ctrl_reg |= (IXGB_CTRL0_RPE | IXGB_CTRL0_TPE); -		pap_reg = hw->fc.pause_time; -		break; -	default: -		/* We should never get here.  The value should be 0-3. */ -		pr_debug("Flow control param set incorrectly\n"); -		ASSERT(0); -		break; -	} - -	/* Write the new settings */ -	IXGB_WRITE_REG(hw, CTRL0, ctrl_reg); - -	if (pap_reg != 0) -		IXGB_WRITE_REG(hw, PAP, pap_reg); - -	/* Set the flow control receive threshold registers.  Normally, -	 * these registers will be set to a default threshold that may be -	 * adjusted later by the driver's runtime code.  However, if the -	 * ability to transmit pause frames in not enabled, then these -	 * registers will be set to 0. -	 */ -	if (!(hw->fc.type & ixgb_fc_tx_pause)) { -		IXGB_WRITE_REG(hw, FCRTL, 0); -		IXGB_WRITE_REG(hw, FCRTH, 0); -	} else { -	   /* We need to set up the Receive Threshold high and low water -	    * marks as well as (optionally) enabling the transmission of XON -	    * frames. */ -		if (hw->fc.send_xon) { -			IXGB_WRITE_REG(hw, FCRTL, -				(hw->fc.low_water | IXGB_FCRTL_XONE)); -		} else { -			IXGB_WRITE_REG(hw, FCRTL, hw->fc.low_water); -		} -		IXGB_WRITE_REG(hw, FCRTH, hw->fc.high_water); -	} -	return status; -} - -/****************************************************************************** - * Reads a word from a device over the Management Data Interface (MDI) bus. - * This interface is used to manage Physical layer devices. - * - * hw          - Struct containing variables accessed by hw code - * reg_address - Offset of device register being read. - * phy_address - Address of device on MDI. - * - * Returns:  Data word (16 bits) from MDI device. - * - * The 82597EX has support for several MDI access methods.  This routine - * uses the new protocol MDI Single Command and Address Operation. - * This requires that first an address cycle command is sent, followed by a - * read command. - *****************************************************************************/ -static u16 -ixgb_read_phy_reg(struct ixgb_hw *hw, -		u32 reg_address, -		u32 phy_address, -		u32 device_type) -{ -	u32 i; -	u32 data; -	u32 command = 0; - -	ASSERT(reg_address <= IXGB_MAX_PHY_REG_ADDRESS); -	ASSERT(phy_address <= IXGB_MAX_PHY_ADDRESS); -	ASSERT(device_type <= IXGB_MAX_PHY_DEV_TYPE); - -	/* Setup and write the address cycle command */ -	command = ((reg_address << IXGB_MSCA_NP_ADDR_SHIFT) | -		   (device_type << IXGB_MSCA_DEV_TYPE_SHIFT) | -		   (phy_address << IXGB_MSCA_PHY_ADDR_SHIFT) | -		   (IXGB_MSCA_ADDR_CYCLE | IXGB_MSCA_MDI_COMMAND)); - -	IXGB_WRITE_REG(hw, MSCA, command); - -    /************************************************************** -    ** Check every 10 usec to see if the address cycle completed -    ** The COMMAND bit will clear when the operation is complete. -    ** This may take as long as 64 usecs (we'll wait 100 usecs max) -    ** from the CPU Write to the Ready bit assertion. -    **************************************************************/ - -	for (i = 0; i < 10; i++) -	{ -		udelay(10); - -		command = IXGB_READ_REG(hw, MSCA); - -		if ((command & IXGB_MSCA_MDI_COMMAND) == 0) -			break; -	} - -	ASSERT((command & IXGB_MSCA_MDI_COMMAND) == 0); - -	/* Address cycle complete, setup and write the read command */ -	command = ((reg_address << IXGB_MSCA_NP_ADDR_SHIFT) | -		   (device_type << IXGB_MSCA_DEV_TYPE_SHIFT) | -		   (phy_address << IXGB_MSCA_PHY_ADDR_SHIFT) | -		   (IXGB_MSCA_READ | IXGB_MSCA_MDI_COMMAND)); - -	IXGB_WRITE_REG(hw, MSCA, command); - -    /************************************************************** -    ** Check every 10 usec to see if the read command completed -    ** The COMMAND bit will clear when the operation is complete. -    ** The read may take as long as 64 usecs (we'll wait 100 usecs max) -    ** from the CPU Write to the Ready bit assertion. -    **************************************************************/ - -	for (i = 0; i < 10; i++) -	{ -		udelay(10); - -		command = IXGB_READ_REG(hw, MSCA); - -		if ((command & IXGB_MSCA_MDI_COMMAND) == 0) -			break; -	} - -	ASSERT((command & IXGB_MSCA_MDI_COMMAND) == 0); - -	/* Operation is complete, get the data from the MDIO Read/Write Data -	 * register and return. -	 */ -	data = IXGB_READ_REG(hw, MSRWD); -	data >>= IXGB_MSRWD_READ_DATA_SHIFT; -	return((u16) data); -} - -/****************************************************************************** - * Writes a word to a device over the Management Data Interface (MDI) bus. - * This interface is used to manage Physical layer devices. - * - * hw          - Struct containing variables accessed by hw code - * reg_address - Offset of device register being read. - * phy_address - Address of device on MDI. - * device_type - Also known as the Device ID or DID. - * data        - 16-bit value to be written - * - * Returns:  void. - * - * The 82597EX has support for several MDI access methods.  This routine - * uses the new protocol MDI Single Command and Address Operation. - * This requires that first an address cycle command is sent, followed by a - * write command. - *****************************************************************************/ -static void -ixgb_write_phy_reg(struct ixgb_hw *hw, -			u32 reg_address, -			u32 phy_address, -			u32 device_type, -			u16 data) -{ -	u32 i; -	u32 command = 0; - -	ASSERT(reg_address <= IXGB_MAX_PHY_REG_ADDRESS); -	ASSERT(phy_address <= IXGB_MAX_PHY_ADDRESS); -	ASSERT(device_type <= IXGB_MAX_PHY_DEV_TYPE); - -	/* Put the data in the MDIO Read/Write Data register */ -	IXGB_WRITE_REG(hw, MSRWD, (u32)data); - -	/* Setup and write the address cycle command */ -	command = ((reg_address << IXGB_MSCA_NP_ADDR_SHIFT)  | -			   (device_type << IXGB_MSCA_DEV_TYPE_SHIFT) | -			   (phy_address << IXGB_MSCA_PHY_ADDR_SHIFT) | -			   (IXGB_MSCA_ADDR_CYCLE | IXGB_MSCA_MDI_COMMAND)); - -	IXGB_WRITE_REG(hw, MSCA, command); - -	/************************************************************** -	** Check every 10 usec to see if the address cycle completed -	** The COMMAND bit will clear when the operation is complete. -	** This may take as long as 64 usecs (we'll wait 100 usecs max) -	** from the CPU Write to the Ready bit assertion. -	**************************************************************/ - -	for (i = 0; i < 10; i++) -	{ -		udelay(10); - -		command = IXGB_READ_REG(hw, MSCA); - -		if ((command & IXGB_MSCA_MDI_COMMAND) == 0) -			break; -	} - -	ASSERT((command & IXGB_MSCA_MDI_COMMAND) == 0); - -	/* Address cycle complete, setup and write the write command */ -	command = ((reg_address << IXGB_MSCA_NP_ADDR_SHIFT)  | -			   (device_type << IXGB_MSCA_DEV_TYPE_SHIFT) | -			   (phy_address << IXGB_MSCA_PHY_ADDR_SHIFT) | -			   (IXGB_MSCA_WRITE | IXGB_MSCA_MDI_COMMAND)); - -	IXGB_WRITE_REG(hw, MSCA, command); - -	/************************************************************** -	** Check every 10 usec to see if the read command completed -	** The COMMAND bit will clear when the operation is complete. -	** The write may take as long as 64 usecs (we'll wait 100 usecs max) -	** from the CPU Write to the Ready bit assertion. -	**************************************************************/ - -	for (i = 0; i < 10; i++) -	{ -		udelay(10); - -		command = IXGB_READ_REG(hw, MSCA); - -		if ((command & IXGB_MSCA_MDI_COMMAND) == 0) -			break; -	} - -	ASSERT((command & IXGB_MSCA_MDI_COMMAND) == 0); - -	/* Operation is complete, return. */ -} - -/****************************************************************************** - * Checks to see if the link status of the hardware has changed. - * - * hw - Struct containing variables accessed by hw code - * - * Called by any function that needs to check the link status of the adapter. - *****************************************************************************/ -void -ixgb_check_for_link(struct ixgb_hw *hw) -{ -	u32 status_reg; -	u32 xpcss_reg; - -	ENTER(); - -	xpcss_reg = IXGB_READ_REG(hw, XPCSS); -	status_reg = IXGB_READ_REG(hw, STATUS); - -	if ((xpcss_reg & IXGB_XPCSS_ALIGN_STATUS) && -	    (status_reg & IXGB_STATUS_LU)) { -		hw->link_up = true; -	} else if (!(xpcss_reg & IXGB_XPCSS_ALIGN_STATUS) && -		   (status_reg & IXGB_STATUS_LU)) { -		pr_debug("XPCSS Not Aligned while Status:LU is set\n"); -		hw->link_up = ixgb_link_reset(hw); -	} else { -		/* -		 * 82597EX errata.  Since the lane deskew problem may prevent -		 * link, reset the link before reporting link down. -		 */ -		hw->link_up = ixgb_link_reset(hw); -	} -	/*  Anything else for 10 Gig?? */ -} - -/****************************************************************************** - * Check for a bad link condition that may have occurred. - * The indication is that the RFC / LFC registers may be incrementing - * continually.  A full adapter reset is required to recover. - * - * hw - Struct containing variables accessed by hw code - * - * Called by any function that needs to check the link status of the adapter. - *****************************************************************************/ -bool ixgb_check_for_bad_link(struct ixgb_hw *hw) -{ -	u32 newLFC, newRFC; -	bool bad_link_returncode = false; - -	if (hw->phy_type == ixgb_phy_type_txn17401) { -		newLFC = IXGB_READ_REG(hw, LFC); -		newRFC = IXGB_READ_REG(hw, RFC); -		if ((hw->lastLFC + 250 < newLFC) -		    || (hw->lastRFC + 250 < newRFC)) { -			pr_debug("BAD LINK! too many LFC/RFC since last check\n"); -			bad_link_returncode = true; -		} -		hw->lastLFC = newLFC; -		hw->lastRFC = newRFC; -	} - -	return bad_link_returncode; -} - -/****************************************************************************** - * Clears all hardware statistics counters. - * - * hw - Struct containing variables accessed by shared code - *****************************************************************************/ -static void -ixgb_clear_hw_cntrs(struct ixgb_hw *hw) -{ -	ENTER(); - -	/* if we are stopped or resetting exit gracefully */ -	if (hw->adapter_stopped) { -		pr_debug("Exiting because the adapter is stopped!!!\n"); -		return; -	} - -	IXGB_READ_REG(hw, TPRL); -	IXGB_READ_REG(hw, TPRH); -	IXGB_READ_REG(hw, GPRCL); -	IXGB_READ_REG(hw, GPRCH); -	IXGB_READ_REG(hw, BPRCL); -	IXGB_READ_REG(hw, BPRCH); -	IXGB_READ_REG(hw, MPRCL); -	IXGB_READ_REG(hw, MPRCH); -	IXGB_READ_REG(hw, UPRCL); -	IXGB_READ_REG(hw, UPRCH); -	IXGB_READ_REG(hw, VPRCL); -	IXGB_READ_REG(hw, VPRCH); -	IXGB_READ_REG(hw, JPRCL); -	IXGB_READ_REG(hw, JPRCH); -	IXGB_READ_REG(hw, GORCL); -	IXGB_READ_REG(hw, GORCH); -	IXGB_READ_REG(hw, TORL); -	IXGB_READ_REG(hw, TORH); -	IXGB_READ_REG(hw, RNBC); -	IXGB_READ_REG(hw, RUC); -	IXGB_READ_REG(hw, ROC); -	IXGB_READ_REG(hw, RLEC); -	IXGB_READ_REG(hw, CRCERRS); -	IXGB_READ_REG(hw, ICBC); -	IXGB_READ_REG(hw, ECBC); -	IXGB_READ_REG(hw, MPC); -	IXGB_READ_REG(hw, TPTL); -	IXGB_READ_REG(hw, TPTH); -	IXGB_READ_REG(hw, GPTCL); -	IXGB_READ_REG(hw, GPTCH); -	IXGB_READ_REG(hw, BPTCL); -	IXGB_READ_REG(hw, BPTCH); -	IXGB_READ_REG(hw, MPTCL); -	IXGB_READ_REG(hw, MPTCH); -	IXGB_READ_REG(hw, UPTCL); -	IXGB_READ_REG(hw, UPTCH); -	IXGB_READ_REG(hw, VPTCL); -	IXGB_READ_REG(hw, VPTCH); -	IXGB_READ_REG(hw, JPTCL); -	IXGB_READ_REG(hw, JPTCH); -	IXGB_READ_REG(hw, GOTCL); -	IXGB_READ_REG(hw, GOTCH); -	IXGB_READ_REG(hw, TOTL); -	IXGB_READ_REG(hw, TOTH); -	IXGB_READ_REG(hw, DC); -	IXGB_READ_REG(hw, PLT64C); -	IXGB_READ_REG(hw, TSCTC); -	IXGB_READ_REG(hw, TSCTFC); -	IXGB_READ_REG(hw, IBIC); -	IXGB_READ_REG(hw, RFC); -	IXGB_READ_REG(hw, LFC); -	IXGB_READ_REG(hw, PFRC); -	IXGB_READ_REG(hw, PFTC); -	IXGB_READ_REG(hw, MCFRC); -	IXGB_READ_REG(hw, MCFTC); -	IXGB_READ_REG(hw, XONRXC); -	IXGB_READ_REG(hw, XONTXC); -	IXGB_READ_REG(hw, XOFFRXC); -	IXGB_READ_REG(hw, XOFFTXC); -	IXGB_READ_REG(hw, RJC); -} - -/****************************************************************************** - * Turns on the software controllable LED - * - * hw - Struct containing variables accessed by shared code - *****************************************************************************/ -void -ixgb_led_on(struct ixgb_hw *hw) -{ -	u32 ctrl0_reg = IXGB_READ_REG(hw, CTRL0); - -	/* To turn on the LED, clear software-definable pin 0 (SDP0). */ -	ctrl0_reg &= ~IXGB_CTRL0_SDP0; -	IXGB_WRITE_REG(hw, CTRL0, ctrl0_reg); -} - -/****************************************************************************** - * Turns off the software controllable LED - * - * hw - Struct containing variables accessed by shared code - *****************************************************************************/ -void -ixgb_led_off(struct ixgb_hw *hw) -{ -	u32 ctrl0_reg = IXGB_READ_REG(hw, CTRL0); - -	/* To turn off the LED, set software-definable pin 0 (SDP0). */ -	ctrl0_reg |= IXGB_CTRL0_SDP0; -	IXGB_WRITE_REG(hw, CTRL0, ctrl0_reg); -} - -/****************************************************************************** - * Gets the current PCI bus type, speed, and width of the hardware - * - * hw - Struct containing variables accessed by shared code - *****************************************************************************/ -static void -ixgb_get_bus_info(struct ixgb_hw *hw) -{ -	u32 status_reg; - -	status_reg = IXGB_READ_REG(hw, STATUS); - -	hw->bus.type = (status_reg & IXGB_STATUS_PCIX_MODE) ? -		ixgb_bus_type_pcix : ixgb_bus_type_pci; - -	if (hw->bus.type == ixgb_bus_type_pci) { -		hw->bus.speed = (status_reg & IXGB_STATUS_PCI_SPD) ? -			ixgb_bus_speed_66 : ixgb_bus_speed_33; -	} else { -		switch (status_reg & IXGB_STATUS_PCIX_SPD_MASK) { -		case IXGB_STATUS_PCIX_SPD_66: -			hw->bus.speed = ixgb_bus_speed_66; -			break; -		case IXGB_STATUS_PCIX_SPD_100: -			hw->bus.speed = ixgb_bus_speed_100; -			break; -		case IXGB_STATUS_PCIX_SPD_133: -			hw->bus.speed = ixgb_bus_speed_133; -			break; -		default: -			hw->bus.speed = ixgb_bus_speed_reserved; -			break; -		} -	} - -	hw->bus.width = (status_reg & IXGB_STATUS_BUS64) ? -		ixgb_bus_width_64 : ixgb_bus_width_32; -} - -/****************************************************************************** - * Tests a MAC address to ensure it is a valid Individual Address - * - * mac_addr - pointer to MAC address. - * - *****************************************************************************/ -static bool -mac_addr_valid(u8 *mac_addr) -{ -	bool is_valid = true; -	ENTER(); - -	/* Make sure it is not a multicast address */ -	if (is_multicast_ether_addr(mac_addr)) { -		pr_debug("MAC address is multicast\n"); -		is_valid = false; -	} -	/* Not a broadcast address */ -	else if (is_broadcast_ether_addr(mac_addr)) { -		pr_debug("MAC address is broadcast\n"); -		is_valid = false; -	} -	/* Reject the zero address */ -	else if (is_zero_ether_addr(mac_addr)) { -		pr_debug("MAC address is all zeros\n"); -		is_valid = false; -	} -	return is_valid; -} - -/****************************************************************************** - * Resets the 10GbE link.  Waits the settle time and returns the state of - * the link. - * - * hw - Struct containing variables accessed by shared code - *****************************************************************************/ -static bool -ixgb_link_reset(struct ixgb_hw *hw) -{ -	bool link_status = false; -	u8 wait_retries = MAX_RESET_ITERATIONS; -	u8 lrst_retries = MAX_RESET_ITERATIONS; - -	do { -		/* Reset the link */ -		IXGB_WRITE_REG(hw, CTRL0, -			       IXGB_READ_REG(hw, CTRL0) | IXGB_CTRL0_LRST); - -		/* Wait for link-up and lane re-alignment */ -		do { -			udelay(IXGB_DELAY_USECS_AFTER_LINK_RESET); -			link_status = -			    ((IXGB_READ_REG(hw, STATUS) & IXGB_STATUS_LU) -			     && (IXGB_READ_REG(hw, XPCSS) & -				 IXGB_XPCSS_ALIGN_STATUS)) ? true : false; -		} while (!link_status && --wait_retries); - -	} while (!link_status && --lrst_retries); - -	return link_status; -} - -/****************************************************************************** - * Resets the 10GbE optics module. - * - * hw - Struct containing variables accessed by shared code - *****************************************************************************/ -static void -ixgb_optics_reset(struct ixgb_hw *hw) -{ -	if (hw->phy_type == ixgb_phy_type_txn17401) { -		ixgb_write_phy_reg(hw, -				   MDIO_CTRL1, -				   IXGB_PHY_ADDRESS, -				   MDIO_MMD_PMAPMD, -				   MDIO_CTRL1_RESET); - -		ixgb_read_phy_reg(hw, MDIO_CTRL1, IXGB_PHY_ADDRESS, MDIO_MMD_PMAPMD); -	} -} - -/****************************************************************************** - * Resets the 10GbE optics module for Sun variant NIC. - * - * hw - Struct containing variables accessed by shared code - *****************************************************************************/ - -#define   IXGB_BCM8704_USER_PMD_TX_CTRL_REG         0xC803 -#define   IXGB_BCM8704_USER_PMD_TX_CTRL_REG_VAL     0x0164 -#define   IXGB_BCM8704_USER_CTRL_REG                0xC800 -#define   IXGB_BCM8704_USER_CTRL_REG_VAL            0x7FBF -#define   IXGB_BCM8704_USER_DEV3_ADDR               0x0003 -#define   IXGB_SUN_PHY_ADDRESS                      0x0000 -#define   IXGB_SUN_PHY_RESET_DELAY                     305 - -static void -ixgb_optics_reset_bcm(struct ixgb_hw *hw) -{ -	u32 ctrl = IXGB_READ_REG(hw, CTRL0); -	ctrl &= ~IXGB_CTRL0_SDP2; -	ctrl |= IXGB_CTRL0_SDP3; -	IXGB_WRITE_REG(hw, CTRL0, ctrl); -	IXGB_WRITE_FLUSH(hw); - -	/* SerDes needs extra delay */ -	msleep(IXGB_SUN_PHY_RESET_DELAY); - -	/* Broadcom 7408L configuration */ -	/* Reference clock config */ -	ixgb_write_phy_reg(hw, -			   IXGB_BCM8704_USER_PMD_TX_CTRL_REG, -			   IXGB_SUN_PHY_ADDRESS, -			   IXGB_BCM8704_USER_DEV3_ADDR, -			   IXGB_BCM8704_USER_PMD_TX_CTRL_REG_VAL); -	/*  we must read the registers twice */ -	ixgb_read_phy_reg(hw, -			  IXGB_BCM8704_USER_PMD_TX_CTRL_REG, -			  IXGB_SUN_PHY_ADDRESS, -			  IXGB_BCM8704_USER_DEV3_ADDR); -	ixgb_read_phy_reg(hw, -			  IXGB_BCM8704_USER_PMD_TX_CTRL_REG, -			  IXGB_SUN_PHY_ADDRESS, -			  IXGB_BCM8704_USER_DEV3_ADDR); - -	ixgb_write_phy_reg(hw, -			   IXGB_BCM8704_USER_CTRL_REG, -			   IXGB_SUN_PHY_ADDRESS, -			   IXGB_BCM8704_USER_DEV3_ADDR, -			   IXGB_BCM8704_USER_CTRL_REG_VAL); -	ixgb_read_phy_reg(hw, -			  IXGB_BCM8704_USER_CTRL_REG, -			  IXGB_SUN_PHY_ADDRESS, -			  IXGB_BCM8704_USER_DEV3_ADDR); -	ixgb_read_phy_reg(hw, -			  IXGB_BCM8704_USER_CTRL_REG, -			  IXGB_SUN_PHY_ADDRESS, -			  IXGB_BCM8704_USER_DEV3_ADDR); - -	/* SerDes needs extra delay */ -	msleep(IXGB_SUN_PHY_RESET_DELAY); -} diff --git a/drivers/net/ethernet/intel/ixgb/ixgb_hw.h b/drivers/net/ethernet/intel/ixgb/ixgb_hw.h deleted file mode 100644 index 70bcff5fb3db..000000000000 --- a/drivers/net/ethernet/intel/ixgb/ixgb_hw.h +++ /dev/null @@ -1,767 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0 */ -/* Copyright(c) 1999 - 2008 Intel Corporation. */ - -#ifndef _IXGB_HW_H_ -#define _IXGB_HW_H_ - -#include <linux/mdio.h> - -#include "ixgb_osdep.h" - -/* Enums */ -typedef enum { -	ixgb_mac_unknown = 0, -	ixgb_82597, -	ixgb_num_macs -} ixgb_mac_type; - -/* Types of physical layer modules */ -typedef enum { -	ixgb_phy_type_unknown = 0, -	ixgb_phy_type_g6005,	/* 850nm, MM fiber, XPAK transceiver */ -	ixgb_phy_type_g6104,	/* 1310nm, SM fiber, XPAK transceiver */ -	ixgb_phy_type_txn17201,	/* 850nm, MM fiber, XPAK transceiver */ -	ixgb_phy_type_txn17401,	/* 1310nm, SM fiber, XENPAK transceiver */ -	ixgb_phy_type_bcm	/* SUN specific board */ -} ixgb_phy_type; - -/* XPAK transceiver vendors, for the SR adapters */ -typedef enum { -	ixgb_xpak_vendor_intel, -	ixgb_xpak_vendor_infineon -} ixgb_xpak_vendor; - -/* Media Types */ -typedef enum { -	ixgb_media_type_unknown = 0, -	ixgb_media_type_fiber = 1, -	ixgb_media_type_copper = 2, -	ixgb_num_media_types -} ixgb_media_type; - -/* Flow Control Settings */ -typedef enum { -	ixgb_fc_none = 0, -	ixgb_fc_rx_pause = 1, -	ixgb_fc_tx_pause = 2, -	ixgb_fc_full = 3, -	ixgb_fc_default = 0xFF -} ixgb_fc_type; - -/* PCI bus types */ -typedef enum { -	ixgb_bus_type_unknown = 0, -	ixgb_bus_type_pci, -	ixgb_bus_type_pcix -} ixgb_bus_type; - -/* PCI bus speeds */ -typedef enum { -	ixgb_bus_speed_unknown = 0, -	ixgb_bus_speed_33, -	ixgb_bus_speed_66, -	ixgb_bus_speed_100, -	ixgb_bus_speed_133, -	ixgb_bus_speed_reserved -} ixgb_bus_speed; - -/* PCI bus widths */ -typedef enum { -	ixgb_bus_width_unknown = 0, -	ixgb_bus_width_32, -	ixgb_bus_width_64 -} ixgb_bus_width; - -#define IXGB_EEPROM_SIZE    64	/* Size in words */ - -#define SPEED_10000  10000 -#define FULL_DUPLEX  2 - -#define MIN_NUMBER_OF_DESCRIPTORS       8 -#define MAX_NUMBER_OF_DESCRIPTORS  0xFFF8	/* 13 bits in RDLEN/TDLEN, 128B aligned     */ - -#define IXGB_DELAY_BEFORE_RESET        10	/* allow 10ms after idling rx/tx units      */ -#define IXGB_DELAY_AFTER_RESET          1	/* allow 1ms after the reset                */ -#define IXGB_DELAY_AFTER_EE_RESET      10	/* allow 10ms after the EEPROM reset        */ - -#define IXGB_DELAY_USECS_AFTER_LINK_RESET    13	/* allow 13 microseconds after the reset    */ -					   /* NOTE: this is MICROSECONDS               */ -#define MAX_RESET_ITERATIONS            8	/* number of iterations to get things right */ - -/* General Registers */ -#define IXGB_CTRL0   0x00000	/* Device Control Register 0 - RW */ -#define IXGB_CTRL1   0x00008	/* Device Control Register 1 - RW */ -#define IXGB_STATUS  0x00010	/* Device Status Register - RO */ -#define IXGB_EECD    0x00018	/* EEPROM/Flash Control/Data Register - RW */ -#define IXGB_MFS     0x00020	/* Maximum Frame Size - RW */ - -/* Interrupt */ -#define IXGB_ICR     0x00080	/* Interrupt Cause Read - R/clr */ -#define IXGB_ICS     0x00088	/* Interrupt Cause Set - RW */ -#define IXGB_IMS     0x00090	/* Interrupt Mask Set/Read - RW */ -#define IXGB_IMC     0x00098	/* Interrupt Mask Clear - WO */ - -/* Receive */ -#define IXGB_RCTL    0x00100	/* RX Control - RW */ -#define IXGB_FCRTL   0x00108	/* Flow Control Receive Threshold Low - RW */ -#define IXGB_FCRTH   0x00110	/* Flow Control Receive Threshold High - RW */ -#define IXGB_RDBAL   0x00118	/* RX Descriptor Base Low - RW */ -#define IXGB_RDBAH   0x0011C	/* RX Descriptor Base High - RW */ -#define IXGB_RDLEN   0x00120	/* RX Descriptor Length - RW */ -#define IXGB_RDH     0x00128	/* RX Descriptor Head - RW */ -#define IXGB_RDT     0x00130	/* RX Descriptor Tail - RW */ -#define IXGB_RDTR    0x00138	/* RX Delay Timer Ring - RW */ -#define IXGB_RXDCTL  0x00140	/* Receive Descriptor Control - RW */ -#define IXGB_RAIDC   0x00148	/* Receive Adaptive Interrupt Delay Control - RW */ -#define IXGB_RXCSUM  0x00158	/* Receive Checksum Control - RW */ -#define IXGB_RA      0x00180	/* Receive Address Array Base - RW */ -#define IXGB_RAL     0x00180	/* Receive Address Low [0:15] - RW */ -#define IXGB_RAH     0x00184	/* Receive Address High [0:15] - RW */ -#define IXGB_MTA     0x00200	/* Multicast Table Array [0:127] - RW */ -#define IXGB_VFTA    0x00400	/* VLAN Filter Table Array [0:127] - RW */ -#define IXGB_REQ_RX_DESCRIPTOR_MULTIPLE 8 - -/* Transmit */ -#define IXGB_TCTL    0x00600	/* TX Control - RW */ -#define IXGB_TDBAL   0x00608	/* TX Descriptor Base Low - RW */ -#define IXGB_TDBAH   0x0060C	/* TX Descriptor Base High - RW */ -#define IXGB_TDLEN   0x00610	/* TX Descriptor Length - RW */ -#define IXGB_TDH     0x00618	/* TX Descriptor Head - RW */ -#define IXGB_TDT     0x00620	/* TX Descriptor Tail - RW */ -#define IXGB_TIDV    0x00628	/* TX Interrupt Delay Value - RW */ -#define IXGB_TXDCTL  0x00630	/* Transmit Descriptor Control - RW */ -#define IXGB_TSPMT   0x00638	/* TCP Segmentation PAD & Min Threshold - RW */ -#define IXGB_PAP     0x00640	/* Pause and Pace - RW */ -#define IXGB_REQ_TX_DESCRIPTOR_MULTIPLE 8 - -/* Physical */ -#define IXGB_PCSC1   0x00700	/* PCS Control 1 - RW */ -#define IXGB_PCSC2   0x00708	/* PCS Control 2 - RW */ -#define IXGB_PCSS1   0x00710	/* PCS Status 1 - RO */ -#define IXGB_PCSS2   0x00718	/* PCS Status 2 - RO */ -#define IXGB_XPCSS   0x00720	/* 10GBASE-X PCS Status (or XGXS Lane Status) - RO */ -#define IXGB_UCCR    0x00728	/* Unilink Circuit Control Register */ -#define IXGB_XPCSTC  0x00730	/* 10GBASE-X PCS Test Control */ -#define IXGB_MACA    0x00738	/* MDI Autoscan Command and Address - RW */ -#define IXGB_APAE    0x00740	/* Autoscan PHY Address Enable - RW */ -#define IXGB_ARD     0x00748	/* Autoscan Read Data - RO */ -#define IXGB_AIS     0x00750	/* Autoscan Interrupt Status - RO */ -#define IXGB_MSCA    0x00758	/* MDI Single Command and Address - RW */ -#define IXGB_MSRWD   0x00760	/* MDI Single Read and Write Data - RW, RO */ - -/* Wake-up */ -#define IXGB_WUFC    0x00808	/* Wake Up Filter Control - RW */ -#define IXGB_WUS     0x00810	/* Wake Up Status - RO */ -#define IXGB_FFLT    0x01000	/* Flexible Filter Length Table - RW */ -#define IXGB_FFMT    0x01020	/* Flexible Filter Mask Table - RW */ -#define IXGB_FTVT    0x01420	/* Flexible Filter Value Table - RW */ - -/* Statistics */ -#define IXGB_TPRL    0x02000	/* Total Packets Received (Low) */ -#define IXGB_TPRH    0x02004	/* Total Packets Received (High) */ -#define IXGB_GPRCL   0x02008	/* Good Packets Received Count (Low) */ -#define IXGB_GPRCH   0x0200C	/* Good Packets Received Count (High) */ -#define IXGB_BPRCL   0x02010	/* Broadcast Packets Received Count (Low) */ -#define IXGB_BPRCH   0x02014	/* Broadcast Packets Received Count (High) */ -#define IXGB_MPRCL   0x02018	/* Multicast Packets Received Count (Low) */ -#define IXGB_MPRCH   0x0201C	/* Multicast Packets Received Count (High) */ -#define IXGB_UPRCL   0x02020	/* Unicast Packets Received Count (Low) */ -#define IXGB_UPRCH   0x02024	/* Unicast Packets Received Count (High) */ -#define IXGB_VPRCL   0x02028	/* VLAN Packets Received Count (Low) */ -#define IXGB_VPRCH   0x0202C	/* VLAN Packets Received Count (High) */ -#define IXGB_JPRCL   0x02030	/* Jumbo Packets Received Count (Low) */ -#define IXGB_JPRCH   0x02034	/* Jumbo Packets Received Count (High) */ -#define IXGB_GORCL   0x02038	/* Good Octets Received Count (Low) */ -#define IXGB_GORCH   0x0203C	/* Good Octets Received Count (High) */ -#define IXGB_TORL    0x02040	/* Total Octets Received (Low) */ -#define IXGB_TORH    0x02044	/* Total Octets Received (High) */ -#define IXGB_RNBC    0x02048	/* Receive No Buffers Count */ -#define IXGB_RUC     0x02050	/* Receive Undersize Count */ -#define IXGB_ROC     0x02058	/* Receive Oversize Count */ -#define IXGB_RLEC    0x02060	/* Receive Length Error Count */ -#define IXGB_CRCERRS 0x02068	/* CRC Error Count */ -#define IXGB_ICBC    0x02070	/* Illegal control byte in mid-packet Count */ -#define IXGB_ECBC    0x02078	/* Error Control byte in mid-packet Count */ -#define IXGB_MPC     0x02080	/* Missed Packets Count */ -#define IXGB_TPTL    0x02100	/* Total Packets Transmitted (Low) */ -#define IXGB_TPTH    0x02104	/* Total Packets Transmitted (High) */ -#define IXGB_GPTCL   0x02108	/* Good Packets Transmitted Count (Low) */ -#define IXGB_GPTCH   0x0210C	/* Good Packets Transmitted Count (High) */ -#define IXGB_BPTCL   0x02110	/* Broadcast Packets Transmitted Count (Low) */ -#define IXGB_BPTCH   0x02114	/* Broadcast Packets Transmitted Count (High) */ -#define IXGB_MPTCL   0x02118	/* Multicast Packets Transmitted Count (Low) */ -#define IXGB_MPTCH   0x0211C	/* Multicast Packets Transmitted Count (High) */ -#define IXGB_UPTCL   0x02120	/* Unicast Packets Transmitted Count (Low) */ -#define IXGB_UPTCH   0x02124	/* Unicast Packets Transmitted Count (High) */ -#define IXGB_VPTCL   0x02128	/* VLAN Packets Transmitted Count (Low) */ -#define IXGB_VPTCH   0x0212C	/* VLAN Packets Transmitted Count (High) */ -#define IXGB_JPTCL   0x02130	/* Jumbo Packets Transmitted Count (Low) */ -#define IXGB_JPTCH   0x02134	/* Jumbo Packets Transmitted Count (High) */ -#define IXGB_GOTCL   0x02138	/* Good Octets Transmitted Count (Low) */ -#define IXGB_GOTCH   0x0213C	/* Good Octets Transmitted Count (High) */ -#define IXGB_TOTL    0x02140	/* Total Octets Transmitted Count (Low) */ -#define IXGB_TOTH    0x02144	/* Total Octets Transmitted Count (High) */ -#define IXGB_DC      0x02148	/* Defer Count */ -#define IXGB_PLT64C  0x02150	/* Packet Transmitted was less than 64 bytes Count */ -#define IXGB_TSCTC   0x02170	/* TCP Segmentation Context Transmitted Count */ -#define IXGB_TSCTFC  0x02178	/* TCP Segmentation Context Tx Fail Count */ -#define IXGB_IBIC    0x02180	/* Illegal byte during Idle stream count */ -#define IXGB_RFC     0x02188	/* Remote Fault Count */ -#define IXGB_LFC     0x02190	/* Local Fault Count */ -#define IXGB_PFRC    0x02198	/* Pause Frame Receive Count */ -#define IXGB_PFTC    0x021A0	/* Pause Frame Transmit Count */ -#define IXGB_MCFRC   0x021A8	/* MAC Control Frames (non-Pause) Received Count */ -#define IXGB_MCFTC   0x021B0	/* MAC Control Frames (non-Pause) Transmitted Count */ -#define IXGB_XONRXC  0x021B8	/* XON Received Count */ -#define IXGB_XONTXC  0x021C0	/* XON Transmitted Count */ -#define IXGB_XOFFRXC 0x021C8	/* XOFF Received Count */ -#define IXGB_XOFFTXC 0x021D0	/* XOFF Transmitted Count */ -#define IXGB_RJC     0x021D8	/* Receive Jabber Count */ - -/* CTRL0 Bit Masks */ -#define IXGB_CTRL0_LRST     0x00000008 -#define IXGB_CTRL0_JFE      0x00000010 -#define IXGB_CTRL0_XLE      0x00000020 -#define IXGB_CTRL0_MDCS     0x00000040 -#define IXGB_CTRL0_CMDC     0x00000080 -#define IXGB_CTRL0_SDP0     0x00040000 -#define IXGB_CTRL0_SDP1     0x00080000 -#define IXGB_CTRL0_SDP2     0x00100000 -#define IXGB_CTRL0_SDP3     0x00200000 -#define IXGB_CTRL0_SDP0_DIR 0x00400000 -#define IXGB_CTRL0_SDP1_DIR 0x00800000 -#define IXGB_CTRL0_SDP2_DIR 0x01000000 -#define IXGB_CTRL0_SDP3_DIR 0x02000000 -#define IXGB_CTRL0_RST      0x04000000 -#define IXGB_CTRL0_RPE      0x08000000 -#define IXGB_CTRL0_TPE      0x10000000 -#define IXGB_CTRL0_VME      0x40000000 - -/* CTRL1 Bit Masks */ -#define IXGB_CTRL1_GPI0_EN     0x00000001 -#define IXGB_CTRL1_GPI1_EN     0x00000002 -#define IXGB_CTRL1_GPI2_EN     0x00000004 -#define IXGB_CTRL1_GPI3_EN     0x00000008 -#define IXGB_CTRL1_SDP4        0x00000010 -#define IXGB_CTRL1_SDP5        0x00000020 -#define IXGB_CTRL1_SDP6        0x00000040 -#define IXGB_CTRL1_SDP7        0x00000080 -#define IXGB_CTRL1_SDP4_DIR    0x00000100 -#define IXGB_CTRL1_SDP5_DIR    0x00000200 -#define IXGB_CTRL1_SDP6_DIR    0x00000400 -#define IXGB_CTRL1_SDP7_DIR    0x00000800 -#define IXGB_CTRL1_EE_RST      0x00002000 -#define IXGB_CTRL1_RO_DIS      0x00020000 -#define IXGB_CTRL1_PCIXHM_MASK 0x00C00000 -#define IXGB_CTRL1_PCIXHM_1_2  0x00000000 -#define IXGB_CTRL1_PCIXHM_5_8  0x00400000 -#define IXGB_CTRL1_PCIXHM_3_4  0x00800000 -#define IXGB_CTRL1_PCIXHM_7_8  0x00C00000 - -/* STATUS Bit Masks */ -#define IXGB_STATUS_LU            0x00000002 -#define IXGB_STATUS_AIP           0x00000004 -#define IXGB_STATUS_TXOFF         0x00000010 -#define IXGB_STATUS_XAUIME        0x00000020 -#define IXGB_STATUS_RES           0x00000040 -#define IXGB_STATUS_RIS           0x00000080 -#define IXGB_STATUS_RIE           0x00000100 -#define IXGB_STATUS_RLF           0x00000200 -#define IXGB_STATUS_RRF           0x00000400 -#define IXGB_STATUS_PCI_SPD       0x00000800 -#define IXGB_STATUS_BUS64         0x00001000 -#define IXGB_STATUS_PCIX_MODE     0x00002000 -#define IXGB_STATUS_PCIX_SPD_MASK 0x0000C000 -#define IXGB_STATUS_PCIX_SPD_66   0x00000000 -#define IXGB_STATUS_PCIX_SPD_100  0x00004000 -#define IXGB_STATUS_PCIX_SPD_133  0x00008000 -#define IXGB_STATUS_REV_ID_MASK   0x000F0000 -#define IXGB_STATUS_REV_ID_SHIFT  16 - -/* EECD Bit Masks */ -#define IXGB_EECD_SK       0x00000001 -#define IXGB_EECD_CS       0x00000002 -#define IXGB_EECD_DI       0x00000004 -#define IXGB_EECD_DO       0x00000008 -#define IXGB_EECD_FWE_MASK 0x00000030 -#define IXGB_EECD_FWE_DIS  0x00000010 -#define IXGB_EECD_FWE_EN   0x00000020 - -/* MFS */ -#define IXGB_MFS_SHIFT 16 - -/* Interrupt Register Bit Masks (used for ICR, ICS, IMS, and IMC) */ -#define IXGB_INT_TXDW     0x00000001 -#define IXGB_INT_TXQE     0x00000002 -#define IXGB_INT_LSC      0x00000004 -#define IXGB_INT_RXSEQ    0x00000008 -#define IXGB_INT_RXDMT0   0x00000010 -#define IXGB_INT_RXO      0x00000040 -#define IXGB_INT_RXT0     0x00000080 -#define IXGB_INT_AUTOSCAN 0x00000200 -#define IXGB_INT_GPI0     0x00000800 -#define IXGB_INT_GPI1     0x00001000 -#define IXGB_INT_GPI2     0x00002000 -#define IXGB_INT_GPI3     0x00004000 - -/* RCTL Bit Masks */ -#define IXGB_RCTL_RXEN        0x00000002 -#define IXGB_RCTL_SBP         0x00000004 -#define IXGB_RCTL_UPE         0x00000008 -#define IXGB_RCTL_MPE         0x00000010 -#define IXGB_RCTL_RDMTS_MASK  0x00000300 -#define IXGB_RCTL_RDMTS_1_2   0x00000000 -#define IXGB_RCTL_RDMTS_1_4   0x00000100 -#define IXGB_RCTL_RDMTS_1_8   0x00000200 -#define IXGB_RCTL_MO_MASK     0x00003000 -#define IXGB_RCTL_MO_47_36    0x00000000 -#define IXGB_RCTL_MO_46_35    0x00001000 -#define IXGB_RCTL_MO_45_34    0x00002000 -#define IXGB_RCTL_MO_43_32    0x00003000 -#define IXGB_RCTL_MO_SHIFT    12 -#define IXGB_RCTL_BAM         0x00008000 -#define IXGB_RCTL_BSIZE_MASK  0x00030000 -#define IXGB_RCTL_BSIZE_2048  0x00000000 -#define IXGB_RCTL_BSIZE_4096  0x00010000 -#define IXGB_RCTL_BSIZE_8192  0x00020000 -#define IXGB_RCTL_BSIZE_16384 0x00030000 -#define IXGB_RCTL_VFE         0x00040000 -#define IXGB_RCTL_CFIEN       0x00080000 -#define IXGB_RCTL_CFI         0x00100000 -#define IXGB_RCTL_RPDA_MASK   0x00600000 -#define IXGB_RCTL_RPDA_MC_MAC 0x00000000 -#define IXGB_RCTL_MC_ONLY     0x00400000 -#define IXGB_RCTL_CFF         0x00800000 -#define IXGB_RCTL_SECRC       0x04000000 -#define IXGB_RDT_FPDB         0x80000000 - -#define IXGB_RCTL_IDLE_RX_UNIT 0 - -/* FCRTL Bit Masks */ -#define IXGB_FCRTL_XONE       0x80000000 - -/* RXDCTL Bit Masks */ -#define IXGB_RXDCTL_PTHRESH_MASK  0x000001FF -#define IXGB_RXDCTL_PTHRESH_SHIFT 0 -#define IXGB_RXDCTL_HTHRESH_MASK  0x0003FE00 -#define IXGB_RXDCTL_HTHRESH_SHIFT 9 -#define IXGB_RXDCTL_WTHRESH_MASK  0x07FC0000 -#define IXGB_RXDCTL_WTHRESH_SHIFT 18 - -/* RAIDC Bit Masks */ -#define IXGB_RAIDC_HIGHTHRS_MASK 0x0000003F -#define IXGB_RAIDC_DELAY_MASK    0x000FF800 -#define IXGB_RAIDC_DELAY_SHIFT   11 -#define IXGB_RAIDC_POLL_MASK     0x1FF00000 -#define IXGB_RAIDC_POLL_SHIFT    20 -#define IXGB_RAIDC_RXT_GATE      0x40000000 -#define IXGB_RAIDC_EN            0x80000000 - -#define IXGB_RAIDC_POLL_1000_INTERRUPTS_PER_SECOND      1220 -#define IXGB_RAIDC_POLL_5000_INTERRUPTS_PER_SECOND      244 -#define IXGB_RAIDC_POLL_10000_INTERRUPTS_PER_SECOND     122 -#define IXGB_RAIDC_POLL_20000_INTERRUPTS_PER_SECOND     61 - -/* RXCSUM Bit Masks */ -#define IXGB_RXCSUM_IPOFL 0x00000100 -#define IXGB_RXCSUM_TUOFL 0x00000200 - -/* RAH Bit Masks */ -#define IXGB_RAH_ASEL_MASK 0x00030000 -#define IXGB_RAH_ASEL_DEST 0x00000000 -#define IXGB_RAH_ASEL_SRC  0x00010000 -#define IXGB_RAH_AV        0x80000000 - -/* TCTL Bit Masks */ -#define IXGB_TCTL_TCE  0x00000001 -#define IXGB_TCTL_TXEN 0x00000002 -#define IXGB_TCTL_TPDE 0x00000004 - -#define IXGB_TCTL_IDLE_TX_UNIT  0 - -/* TXDCTL Bit Masks */ -#define IXGB_TXDCTL_PTHRESH_MASK  0x0000007F -#define IXGB_TXDCTL_HTHRESH_MASK  0x00007F00 -#define IXGB_TXDCTL_HTHRESH_SHIFT 8 -#define IXGB_TXDCTL_WTHRESH_MASK  0x007F0000 -#define IXGB_TXDCTL_WTHRESH_SHIFT 16 - -/* TSPMT Bit Masks */ -#define IXGB_TSPMT_TSMT_MASK   0x0000FFFF -#define IXGB_TSPMT_TSPBP_MASK  0xFFFF0000 -#define IXGB_TSPMT_TSPBP_SHIFT 16 - -/* PAP Bit Masks */ -#define IXGB_PAP_TXPC_MASK 0x0000FFFF -#define IXGB_PAP_TXPV_MASK 0x000F0000 -#define IXGB_PAP_TXPV_10G  0x00000000 -#define IXGB_PAP_TXPV_1G   0x00010000 -#define IXGB_PAP_TXPV_2G   0x00020000 -#define IXGB_PAP_TXPV_3G   0x00030000 -#define IXGB_PAP_TXPV_4G   0x00040000 -#define IXGB_PAP_TXPV_5G   0x00050000 -#define IXGB_PAP_TXPV_6G   0x00060000 -#define IXGB_PAP_TXPV_7G   0x00070000 -#define IXGB_PAP_TXPV_8G   0x00080000 -#define IXGB_PAP_TXPV_9G   0x00090000 -#define IXGB_PAP_TXPV_WAN  0x000F0000 - -/* PCSC1 Bit Masks */ -#define IXGB_PCSC1_LOOPBACK 0x00004000 - -/* PCSC2 Bit Masks */ -#define IXGB_PCSC2_PCS_TYPE_MASK  0x00000003 -#define IXGB_PCSC2_PCS_TYPE_10GBX 0x00000001 - -/* PCSS1 Bit Masks */ -#define IXGB_PCSS1_LOCAL_FAULT    0x00000080 -#define IXGB_PCSS1_RX_LINK_STATUS 0x00000004 - -/* PCSS2 Bit Masks */ -#define IXGB_PCSS2_DEV_PRES_MASK 0x0000C000 -#define IXGB_PCSS2_DEV_PRES      0x00004000 -#define IXGB_PCSS2_TX_LF         0x00000800 -#define IXGB_PCSS2_RX_LF         0x00000400 -#define IXGB_PCSS2_10GBW         0x00000004 -#define IXGB_PCSS2_10GBX         0x00000002 -#define IXGB_PCSS2_10GBR         0x00000001 - -/* XPCSS Bit Masks */ -#define IXGB_XPCSS_ALIGN_STATUS 0x00001000 -#define IXGB_XPCSS_PATTERN_TEST 0x00000800 -#define IXGB_XPCSS_LANE_3_SYNC  0x00000008 -#define IXGB_XPCSS_LANE_2_SYNC  0x00000004 -#define IXGB_XPCSS_LANE_1_SYNC  0x00000002 -#define IXGB_XPCSS_LANE_0_SYNC  0x00000001 - -/* XPCSTC Bit Masks */ -#define IXGB_XPCSTC_BERT_TRIG       0x00200000 -#define IXGB_XPCSTC_BERT_SST        0x00100000 -#define IXGB_XPCSTC_BERT_PSZ_MASK   0x000C0000 -#define IXGB_XPCSTC_BERT_PSZ_SHIFT  17 -#define IXGB_XPCSTC_BERT_PSZ_INF    0x00000003 -#define IXGB_XPCSTC_BERT_PSZ_68     0x00000001 -#define IXGB_XPCSTC_BERT_PSZ_1028   0x00000000 - -/* MSCA bit Masks */ -/* New Protocol Address */ -#define IXGB_MSCA_NP_ADDR_MASK      0x0000FFFF -#define IXGB_MSCA_NP_ADDR_SHIFT     0 -/* Either Device Type or Register Address,depending on ST_CODE */ -#define IXGB_MSCA_DEV_TYPE_MASK     0x001F0000 -#define IXGB_MSCA_DEV_TYPE_SHIFT    16 -#define IXGB_MSCA_PHY_ADDR_MASK     0x03E00000 -#define IXGB_MSCA_PHY_ADDR_SHIFT    21 -#define IXGB_MSCA_OP_CODE_MASK      0x0C000000 -/* OP_CODE == 00, Address cycle, New Protocol           */ -/* OP_CODE == 01, Write operation                       */ -/* OP_CODE == 10, Read operation                        */ -/* OP_CODE == 11, Read, auto increment, New Protocol    */ -#define IXGB_MSCA_ADDR_CYCLE        0x00000000 -#define IXGB_MSCA_WRITE             0x04000000 -#define IXGB_MSCA_READ              0x08000000 -#define IXGB_MSCA_READ_AUTOINC      0x0C000000 -#define IXGB_MSCA_OP_CODE_SHIFT     26 -#define IXGB_MSCA_ST_CODE_MASK      0x30000000 -/* ST_CODE == 00, New Protocol  */ -/* ST_CODE == 01, Old Protocol  */ -#define IXGB_MSCA_NEW_PROTOCOL      0x00000000 -#define IXGB_MSCA_OLD_PROTOCOL      0x10000000 -#define IXGB_MSCA_ST_CODE_SHIFT     28 -/* Initiate command, self-clearing when command completes */ -#define IXGB_MSCA_MDI_COMMAND       0x40000000 -/*MDI In Progress Enable. */ -#define IXGB_MSCA_MDI_IN_PROG_EN    0x80000000 - -/* MSRWD bit masks */ -#define IXGB_MSRWD_WRITE_DATA_MASK  0x0000FFFF -#define IXGB_MSRWD_WRITE_DATA_SHIFT 0 -#define IXGB_MSRWD_READ_DATA_MASK   0xFFFF0000 -#define IXGB_MSRWD_READ_DATA_SHIFT  16 - -/* Definitions for the optics devices on the MDIO bus. */ -#define IXGB_PHY_ADDRESS             0x0	/* Single PHY, multiple "Devices" */ - -#define MDIO_PMA_PMD_XPAK_VENDOR_NAME       0x803A	/* XPAK/XENPAK devices only */ - -/* Vendor-specific MDIO registers */ -#define G6XXX_PMA_PMD_VS1                   0xC001	/* Vendor-specific register */ -#define G6XXX_XGXS_XAUI_VS2                 0x18	/* Vendor-specific register */ - -#define G6XXX_PMA_PMD_VS1_PLL_RESET         0x80 -#define G6XXX_PMA_PMD_VS1_REMOVE_PLL_RESET  0x00 -#define G6XXX_XGXS_XAUI_VS2_INPUT_MASK      0x0F	/* XAUI lanes synchronized */ - -/* Layout of a single receive descriptor.  The controller assumes that this - * structure is packed into 16 bytes, which is a safe assumption with most - * compilers.  However, some compilers may insert padding between the fields, - * in which case the structure must be packed in some compiler-specific - * manner. */ -struct ixgb_rx_desc { -	__le64 buff_addr; -	__le16 length; -	__le16 reserved; -	u8 status; -	u8 errors; -	__le16 special; -}; - -#define IXGB_RX_DESC_STATUS_DD    0x01 -#define IXGB_RX_DESC_STATUS_EOP   0x02 -#define IXGB_RX_DESC_STATUS_IXSM  0x04 -#define IXGB_RX_DESC_STATUS_VP    0x08 -#define IXGB_RX_DESC_STATUS_TCPCS 0x20 -#define IXGB_RX_DESC_STATUS_IPCS  0x40 -#define IXGB_RX_DESC_STATUS_PIF   0x80 - -#define IXGB_RX_DESC_ERRORS_CE   0x01 -#define IXGB_RX_DESC_ERRORS_SE   0x02 -#define IXGB_RX_DESC_ERRORS_P    0x08 -#define IXGB_RX_DESC_ERRORS_TCPE 0x20 -#define IXGB_RX_DESC_ERRORS_IPE  0x40 -#define IXGB_RX_DESC_ERRORS_RXE  0x80 - -#define IXGB_RX_DESC_SPECIAL_VLAN_MASK  0x0FFF	/* VLAN ID is in lower 12 bits */ -#define IXGB_RX_DESC_SPECIAL_PRI_MASK   0xE000	/* Priority is in upper 3 bits */ -#define IXGB_RX_DESC_SPECIAL_PRI_SHIFT  0x000D	/* Priority is in upper 3 of 16 */ - -/* Layout of a single transmit descriptor.  The controller assumes that this - * structure is packed into 16 bytes, which is a safe assumption with most - * compilers.  However, some compilers may insert padding between the fields, - * in which case the structure must be packed in some compiler-specific - * manner. */ -struct ixgb_tx_desc { -	__le64 buff_addr; -	__le32 cmd_type_len; -	u8 status; -	u8 popts; -	__le16 vlan; -}; - -#define IXGB_TX_DESC_LENGTH_MASK    0x000FFFFF -#define IXGB_TX_DESC_TYPE_MASK      0x00F00000 -#define IXGB_TX_DESC_TYPE_SHIFT     20 -#define IXGB_TX_DESC_CMD_MASK       0xFF000000 -#define IXGB_TX_DESC_CMD_SHIFT      24 -#define IXGB_TX_DESC_CMD_EOP        0x01000000 -#define IXGB_TX_DESC_CMD_TSE        0x04000000 -#define IXGB_TX_DESC_CMD_RS         0x08000000 -#define IXGB_TX_DESC_CMD_VLE        0x40000000 -#define IXGB_TX_DESC_CMD_IDE        0x80000000 - -#define IXGB_TX_DESC_TYPE           0x00100000 - -#define IXGB_TX_DESC_STATUS_DD  0x01 - -#define IXGB_TX_DESC_POPTS_IXSM 0x01 -#define IXGB_TX_DESC_POPTS_TXSM 0x02 -#define IXGB_TX_DESC_SPECIAL_PRI_SHIFT  IXGB_RX_DESC_SPECIAL_PRI_SHIFT	/* Priority is in upper 3 of 16 */ - -struct ixgb_context_desc { -	u8 ipcss; -	u8 ipcso; -	__le16 ipcse; -	u8 tucss; -	u8 tucso; -	__le16 tucse; -	__le32 cmd_type_len; -	u8 status; -	u8 hdr_len; -	__le16 mss; -}; - -#define IXGB_CONTEXT_DESC_CMD_TCP 0x01000000 -#define IXGB_CONTEXT_DESC_CMD_IP  0x02000000 -#define IXGB_CONTEXT_DESC_CMD_TSE 0x04000000 -#define IXGB_CONTEXT_DESC_CMD_RS  0x08000000 -#define IXGB_CONTEXT_DESC_CMD_IDE 0x80000000 - -#define IXGB_CONTEXT_DESC_TYPE 0x00000000 - -#define IXGB_CONTEXT_DESC_STATUS_DD 0x01 - -/* Filters */ -#define IXGB_MC_TBL_SIZE          128	/* Multicast Filter Table (4096 bits) */ -#define IXGB_VLAN_FILTER_TBL_SIZE 128	/* VLAN Filter Table (4096 bits) */ -#define IXGB_RAR_ENTRIES		  3	/* Number of entries in Rx Address array */ - -#define IXGB_MEMORY_REGISTER_BASE_ADDRESS   0 -#define ENET_HEADER_SIZE			14 -#define ENET_FCS_LENGTH			 4 -#define IXGB_MAX_NUM_MULTICAST_ADDRESSES	128 -#define IXGB_MIN_ENET_FRAME_SIZE_WITHOUT_FCS	60 -#define IXGB_MAX_ENET_FRAME_SIZE_WITHOUT_FCS	1514 -#define IXGB_MAX_JUMBO_FRAME_SIZE		0x3F00 - -/* Phy Addresses */ -#define IXGB_OPTICAL_PHY_ADDR 0x0	/* Optical Module phy address */ -#define IXGB_XAUII_PHY_ADDR   0x1	/* Xauii transceiver phy address */ -#define IXGB_DIAG_PHY_ADDR    0x1F	/* Diagnostic Device phy address */ - -/* This structure takes a 64k flash and maps it for identification commands */ -struct ixgb_flash_buffer { -	u8 manufacturer_id; -	u8 device_id; -	u8 filler1[0x2AA8]; -	u8 cmd2; -	u8 filler2[0x2AAA]; -	u8 cmd1; -	u8 filler3[0xAAAA]; -}; - -/* Flow control parameters */ -struct ixgb_fc { -	u32 high_water;	/* Flow Control High-water          */ -	u32 low_water;	/* Flow Control Low-water           */ -	u16 pause_time;	/* Flow Control Pause timer         */ -	bool send_xon;		/* Flow control send XON            */ -	ixgb_fc_type type;	/* Type of flow control             */ -}; - -/* The historical defaults for the flow control values are given below. */ -#define FC_DEFAULT_HI_THRESH        (0x8000)	/* 32KB */ -#define FC_DEFAULT_LO_THRESH        (0x4000)	/* 16KB */ -#define FC_DEFAULT_TX_TIMER         (0x100)	/* ~130 us */ - -/* Phy definitions */ -#define IXGB_MAX_PHY_REG_ADDRESS    0xFFFF -#define IXGB_MAX_PHY_ADDRESS        31 -#define IXGB_MAX_PHY_DEV_TYPE       31 - -/* Bus parameters */ -struct ixgb_bus { -	ixgb_bus_speed speed; -	ixgb_bus_width width; -	ixgb_bus_type type; -}; - -struct ixgb_hw { -	u8 __iomem *hw_addr;/* Base Address of the hardware     */ -	void *back;		/* Pointer to OS-dependent struct   */ -	struct ixgb_fc fc;	/* Flow control parameters          */ -	struct ixgb_bus bus;	/* Bus parameters                   */ -	u32 phy_id;	/* Phy Identifier                   */ -	u32 phy_addr;	/* XGMII address of Phy             */ -	ixgb_mac_type mac_type;	/* Identifier for MAC controller    */ -	ixgb_phy_type phy_type;	/* Transceiver/phy identifier       */ -	u32 max_frame_size;	/* Maximum frame size supported     */ -	u32 mc_filter_type;	/* Multicast filter hash type       */ -	u32 num_mc_addrs;	/* Number of current Multicast addrs */ -	u8 curr_mac_addr[ETH_ALEN];	/* Individual address currently programmed in MAC */ -	u32 num_tx_desc;	/* Number of Transmit descriptors   */ -	u32 num_rx_desc;	/* Number of Receive descriptors    */ -	u32 rx_buffer_size;	/* Size of Receive buffer           */ -	bool link_up;		/* true if link is valid            */ -	bool adapter_stopped;	/* State of adapter                 */ -	u16 device_id;	/* device id from PCI configuration space */ -	u16 vendor_id;	/* vendor id from PCI configuration space */ -	u8 revision_id;	/* revision id from PCI configuration space */ -	u16 subsystem_vendor_id;	/* subsystem vendor id from PCI configuration space */ -	u16 subsystem_id;	/* subsystem id from PCI configuration space */ -	u32 bar0;		/* Base Address registers           */ -	u32 bar1; -	u32 bar2; -	u32 bar3; -	u16 pci_cmd_word;	/* PCI command register id from PCI configuration space */ -	__le16 eeprom[IXGB_EEPROM_SIZE];	/* EEPROM contents read at init time  */ -	unsigned long io_base;	/* Our I/O mapped location */ -	u32 lastLFC; -	u32 lastRFC; -}; - -/* Statistics reported by the hardware */ -struct ixgb_hw_stats { -	u64 tprl; -	u64 tprh; -	u64 gprcl; -	u64 gprch; -	u64 bprcl; -	u64 bprch; -	u64 mprcl; -	u64 mprch; -	u64 uprcl; -	u64 uprch; -	u64 vprcl; -	u64 vprch; -	u64 jprcl; -	u64 jprch; -	u64 gorcl; -	u64 gorch; -	u64 torl; -	u64 torh; -	u64 rnbc; -	u64 ruc; -	u64 roc; -	u64 rlec; -	u64 crcerrs; -	u64 icbc; -	u64 ecbc; -	u64 mpc; -	u64 tptl; -	u64 tpth; -	u64 gptcl; -	u64 gptch; -	u64 bptcl; -	u64 bptch; -	u64 mptcl; -	u64 mptch; -	u64 uptcl; -	u64 uptch; -	u64 vptcl; -	u64 vptch; -	u64 jptcl; -	u64 jptch; -	u64 gotcl; -	u64 gotch; -	u64 totl; -	u64 toth; -	u64 dc; -	u64 plt64c; -	u64 tsctc; -	u64 tsctfc; -	u64 ibic; -	u64 rfc; -	u64 lfc; -	u64 pfrc; -	u64 pftc; -	u64 mcfrc; -	u64 mcftc; -	u64 xonrxc; -	u64 xontxc; -	u64 xoffrxc; -	u64 xofftxc; -	u64 rjc; -}; - -/* Function Prototypes */ -bool ixgb_adapter_stop(struct ixgb_hw *hw); -bool ixgb_init_hw(struct ixgb_hw *hw); -bool ixgb_adapter_start(struct ixgb_hw *hw); -void ixgb_check_for_link(struct ixgb_hw *hw); -bool ixgb_check_for_bad_link(struct ixgb_hw *hw); - -void ixgb_rar_set(struct ixgb_hw *hw, const u8 *addr, u32 index); - -/* Filters (multicast, vlan, receive) */ -void ixgb_mc_addr_list_update(struct ixgb_hw *hw, u8 *mc_addr_list, -			      u32 mc_addr_count, u32 pad); - -/* Vfta functions */ -void ixgb_write_vfta(struct ixgb_hw *hw, u32 offset, u32 value); - -/* Access functions to eeprom data */ -void ixgb_get_ee_mac_addr(struct ixgb_hw *hw, u8 *mac_addr); -u32 ixgb_get_ee_pba_number(struct ixgb_hw *hw); -u16 ixgb_get_ee_device_id(struct ixgb_hw *hw); -bool ixgb_get_eeprom_data(struct ixgb_hw *hw); -__le16 ixgb_get_eeprom_word(struct ixgb_hw *hw, u16 index); - -/* Everything else */ -void ixgb_led_on(struct ixgb_hw *hw); -void ixgb_led_off(struct ixgb_hw *hw); -void ixgb_write_pci_cfg(struct ixgb_hw *hw, -			 u32 reg, -			 u16 * value); - - -#endif /* _IXGB_HW_H_ */ diff --git a/drivers/net/ethernet/intel/ixgb/ixgb_ids.h b/drivers/net/ethernet/intel/ixgb/ixgb_ids.h deleted file mode 100644 index 9695b8215f01..000000000000 --- a/drivers/net/ethernet/intel/ixgb/ixgb_ids.h +++ /dev/null @@ -1,23 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0 */ -/* Copyright(c) 1999 - 2008 Intel Corporation. */ - -#ifndef _IXGB_IDS_H_ -#define _IXGB_IDS_H_ - -/********************************************************************** -** The Device and Vendor IDs for 10 Gigabit MACs -**********************************************************************/ - -#define IXGB_DEVICE_ID_82597EX      0x1048 -#define IXGB_DEVICE_ID_82597EX_SR   0x1A48 -#define IXGB_DEVICE_ID_82597EX_LR   0x1B48 -#define IXGB_SUBDEVICE_ID_A11F      0xA11F -#define IXGB_SUBDEVICE_ID_A01F      0xA01F - -#define IXGB_DEVICE_ID_82597EX_CX4   0x109E -#define IXGB_SUBDEVICE_ID_A00C  0xA00C -#define IXGB_SUBDEVICE_ID_A01C  0xA01C -#define IXGB_SUBDEVICE_ID_7036  0x7036 - -#endif /* #ifndef _IXGB_IDS_H_ */ -/* End of File */ diff --git a/drivers/net/ethernet/intel/ixgb/ixgb_main.c b/drivers/net/ethernet/intel/ixgb/ixgb_main.c deleted file mode 100644 index b4d47e7a76c8..000000000000 --- a/drivers/net/ethernet/intel/ixgb/ixgb_main.c +++ /dev/null @@ -1,2285 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0 -/* Copyright(c) 1999 - 2008 Intel Corporation. */ - -#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt - -#include <linux/prefetch.h> -#include "ixgb.h" - -char ixgb_driver_name[] = "ixgb"; -static char ixgb_driver_string[] = "Intel(R) PRO/10GbE Network Driver"; - -static const char ixgb_copyright[] = "Copyright (c) 1999-2008 Intel Corporation."; - -#define IXGB_CB_LENGTH 256 -static unsigned int copybreak __read_mostly = IXGB_CB_LENGTH; -module_param(copybreak, uint, 0644); -MODULE_PARM_DESC(copybreak, -	"Maximum size of packet that is copied to a new buffer on receive"); - -/* ixgb_pci_tbl - PCI Device ID Table - * - * Wildcard entries (PCI_ANY_ID) should come last - * Last entry must be all 0s - * - * { Vendor ID, Device ID, SubVendor ID, SubDevice ID, - *   Class, Class Mask, private data (not used) } - */ -static const struct pci_device_id ixgb_pci_tbl[] = { -	{PCI_VENDOR_ID_INTEL, IXGB_DEVICE_ID_82597EX, -	 PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, -	{PCI_VENDOR_ID_INTEL, IXGB_DEVICE_ID_82597EX_CX4, -	 PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, -	{PCI_VENDOR_ID_INTEL, IXGB_DEVICE_ID_82597EX_SR, -	 PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, -	{PCI_VENDOR_ID_INTEL, IXGB_DEVICE_ID_82597EX_LR, -	 PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, - -	/* required last entry */ -	{0,} -}; - -MODULE_DEVICE_TABLE(pci, ixgb_pci_tbl); - -/* Local Function Prototypes */ -static int ixgb_init_module(void); -static void ixgb_exit_module(void); -static int ixgb_probe(struct pci_dev *pdev, const struct pci_device_id *ent); -static void ixgb_remove(struct pci_dev *pdev); -static int ixgb_sw_init(struct ixgb_adapter *adapter); -static int ixgb_open(struct net_device *netdev); -static int ixgb_close(struct net_device *netdev); -static void ixgb_configure_tx(struct ixgb_adapter *adapter); -static void ixgb_configure_rx(struct ixgb_adapter *adapter); -static void ixgb_setup_rctl(struct ixgb_adapter *adapter); -static void ixgb_clean_tx_ring(struct ixgb_adapter *adapter); -static void ixgb_clean_rx_ring(struct ixgb_adapter *adapter); -static void ixgb_set_multi(struct net_device *netdev); -static void ixgb_watchdog(struct timer_list *t); -static netdev_tx_t ixgb_xmit_frame(struct sk_buff *skb, -				   struct net_device *netdev); -static int ixgb_change_mtu(struct net_device *netdev, int new_mtu); -static int ixgb_set_mac(struct net_device *netdev, void *p); -static irqreturn_t ixgb_intr(int irq, void *data); -static bool ixgb_clean_tx_irq(struct ixgb_adapter *adapter); - -static int ixgb_clean(struct napi_struct *, int); -static bool ixgb_clean_rx_irq(struct ixgb_adapter *, int *, int); -static void ixgb_alloc_rx_buffers(struct ixgb_adapter *, int); - -static void ixgb_tx_timeout(struct net_device *dev, unsigned int txqueue); -static void ixgb_tx_timeout_task(struct work_struct *work); - -static void ixgb_vlan_strip_enable(struct ixgb_adapter *adapter); -static void ixgb_vlan_strip_disable(struct ixgb_adapter *adapter); -static int ixgb_vlan_rx_add_vid(struct net_device *netdev, -				__be16 proto, u16 vid); -static int ixgb_vlan_rx_kill_vid(struct net_device *netdev, -				 __be16 proto, u16 vid); -static void ixgb_restore_vlan(struct ixgb_adapter *adapter); - -static pci_ers_result_t ixgb_io_error_detected (struct pci_dev *pdev, -                             pci_channel_state_t state); -static pci_ers_result_t ixgb_io_slot_reset (struct pci_dev *pdev); -static void ixgb_io_resume (struct pci_dev *pdev); - -static const struct pci_error_handlers ixgb_err_handler = { -	.error_detected = ixgb_io_error_detected, -	.slot_reset = ixgb_io_slot_reset, -	.resume = ixgb_io_resume, -}; - -static struct pci_driver ixgb_driver = { -	.name     = ixgb_driver_name, -	.id_table = ixgb_pci_tbl, -	.probe    = ixgb_probe, -	.remove   = ixgb_remove, -	.err_handler = &ixgb_err_handler -}; - -MODULE_AUTHOR("Intel Corporation, <[email protected]>"); -MODULE_DESCRIPTION("Intel(R) PRO/10GbE Network Driver"); -MODULE_LICENSE("GPL v2"); - -#define DEFAULT_MSG_ENABLE (NETIF_MSG_DRV|NETIF_MSG_PROBE|NETIF_MSG_LINK) -static int debug = -1; -module_param(debug, int, 0); -MODULE_PARM_DESC(debug, "Debug level (0=none,...,16=all)"); - -/** - * ixgb_init_module - Driver Registration Routine - * - * ixgb_init_module is the first routine called when the driver is - * loaded. All it does is register with the PCI subsystem. - **/ - -static int __init -ixgb_init_module(void) -{ -	pr_info("%s\n", ixgb_driver_string); -	pr_info("%s\n", ixgb_copyright); - -	return pci_register_driver(&ixgb_driver); -} - -module_init(ixgb_init_module); - -/** - * ixgb_exit_module - Driver Exit Cleanup Routine - * - * ixgb_exit_module is called just before the driver is removed - * from memory. - **/ - -static void __exit -ixgb_exit_module(void) -{ -	pci_unregister_driver(&ixgb_driver); -} - -module_exit(ixgb_exit_module); - -/** - * ixgb_irq_disable - Mask off interrupt generation on the NIC - * @adapter: board private structure - **/ - -static void -ixgb_irq_disable(struct ixgb_adapter *adapter) -{ -	IXGB_WRITE_REG(&adapter->hw, IMC, ~0); -	IXGB_WRITE_FLUSH(&adapter->hw); -	synchronize_irq(adapter->pdev->irq); -} - -/** - * ixgb_irq_enable - Enable default interrupt generation settings - * @adapter: board private structure - **/ - -static void -ixgb_irq_enable(struct ixgb_adapter *adapter) -{ -	u32 val = IXGB_INT_RXT0 | IXGB_INT_RXDMT0 | -		  IXGB_INT_TXDW | IXGB_INT_LSC; -	if (adapter->hw.subsystem_vendor_id == PCI_VENDOR_ID_SUN) -		val |= IXGB_INT_GPI0; -	IXGB_WRITE_REG(&adapter->hw, IMS, val); -	IXGB_WRITE_FLUSH(&adapter->hw); -} - -int -ixgb_up(struct ixgb_adapter *adapter) -{ -	struct net_device *netdev = adapter->netdev; -	int err, irq_flags = IRQF_SHARED; -	int max_frame = netdev->mtu + ENET_HEADER_SIZE + ENET_FCS_LENGTH; -	struct ixgb_hw *hw = &adapter->hw; - -	/* hardware has been reset, we need to reload some things */ - -	ixgb_rar_set(hw, netdev->dev_addr, 0); -	ixgb_set_multi(netdev); - -	ixgb_restore_vlan(adapter); - -	ixgb_configure_tx(adapter); -	ixgb_setup_rctl(adapter); -	ixgb_configure_rx(adapter); -	ixgb_alloc_rx_buffers(adapter, IXGB_DESC_UNUSED(&adapter->rx_ring)); - -	/* disable interrupts and get the hardware into a known state */ -	IXGB_WRITE_REG(&adapter->hw, IMC, 0xffffffff); - -	/* only enable MSI if bus is in PCI-X mode */ -	if (IXGB_READ_REG(&adapter->hw, STATUS) & IXGB_STATUS_PCIX_MODE) { -		err = pci_enable_msi(adapter->pdev); -		if (!err) { -			adapter->have_msi = true; -			irq_flags = 0; -		} -		/* proceed to try to request regular interrupt */ -	} - -	err = request_irq(adapter->pdev->irq, ixgb_intr, irq_flags, -	                  netdev->name, netdev); -	if (err) { -		if (adapter->have_msi) -			pci_disable_msi(adapter->pdev); -		netif_err(adapter, probe, adapter->netdev, -			  "Unable to allocate interrupt Error: %d\n", err); -		return err; -	} - -	if ((hw->max_frame_size != max_frame) || -		(hw->max_frame_size != -		(IXGB_READ_REG(hw, MFS) >> IXGB_MFS_SHIFT))) { - -		hw->max_frame_size = max_frame; - -		IXGB_WRITE_REG(hw, MFS, hw->max_frame_size << IXGB_MFS_SHIFT); - -		if (hw->max_frame_size > -		   IXGB_MAX_ENET_FRAME_SIZE_WITHOUT_FCS + ENET_FCS_LENGTH) { -			u32 ctrl0 = IXGB_READ_REG(hw, CTRL0); - -			if (!(ctrl0 & IXGB_CTRL0_JFE)) { -				ctrl0 |= IXGB_CTRL0_JFE; -				IXGB_WRITE_REG(hw, CTRL0, ctrl0); -			} -		} -	} - -	clear_bit(__IXGB_DOWN, &adapter->flags); - -	napi_enable(&adapter->napi); -	ixgb_irq_enable(adapter); - -	netif_wake_queue(netdev); - -	mod_timer(&adapter->watchdog_timer, jiffies); - -	return 0; -} - -void -ixgb_down(struct ixgb_adapter *adapter, bool kill_watchdog) -{ -	struct net_device *netdev = adapter->netdev; - -	/* prevent the interrupt handler from restarting watchdog */ -	set_bit(__IXGB_DOWN, &adapter->flags); - -	netif_carrier_off(netdev); - -	napi_disable(&adapter->napi); -	/* waiting for NAPI to complete can re-enable interrupts */ -	ixgb_irq_disable(adapter); -	free_irq(adapter->pdev->irq, netdev); - -	if (adapter->have_msi) -		pci_disable_msi(adapter->pdev); - -	if (kill_watchdog) -		del_timer_sync(&adapter->watchdog_timer); - -	adapter->link_speed = 0; -	adapter->link_duplex = 0; -	netif_stop_queue(netdev); - -	ixgb_reset(adapter); -	ixgb_clean_tx_ring(adapter); -	ixgb_clean_rx_ring(adapter); -} - -void -ixgb_reset(struct ixgb_adapter *adapter) -{ -	struct ixgb_hw *hw = &adapter->hw; - -	ixgb_adapter_stop(hw); -	if (!ixgb_init_hw(hw)) -		netif_err(adapter, probe, adapter->netdev, "ixgb_init_hw failed\n"); - -	/* restore frame size information */ -	IXGB_WRITE_REG(hw, MFS, hw->max_frame_size << IXGB_MFS_SHIFT); -	if (hw->max_frame_size > -	    IXGB_MAX_ENET_FRAME_SIZE_WITHOUT_FCS + ENET_FCS_LENGTH) { -		u32 ctrl0 = IXGB_READ_REG(hw, CTRL0); -		if (!(ctrl0 & IXGB_CTRL0_JFE)) { -			ctrl0 |= IXGB_CTRL0_JFE; -			IXGB_WRITE_REG(hw, CTRL0, ctrl0); -		} -	} -} - -static netdev_features_t -ixgb_fix_features(struct net_device *netdev, netdev_features_t features) -{ -	/* -	 * Tx VLAN insertion does not work per HW design when Rx stripping is -	 * disabled. -	 */ -	if (!(features & NETIF_F_HW_VLAN_CTAG_RX)) -		features &= ~NETIF_F_HW_VLAN_CTAG_TX; - -	return features; -} - -static int -ixgb_set_features(struct net_device *netdev, netdev_features_t features) -{ -	struct ixgb_adapter *adapter = netdev_priv(netdev); -	netdev_features_t changed = features ^ netdev->features; - -	if (!(changed & (NETIF_F_RXCSUM|NETIF_F_HW_VLAN_CTAG_RX))) -		return 0; - -	adapter->rx_csum = !!(features & NETIF_F_RXCSUM); - -	if (netif_running(netdev)) { -		ixgb_down(adapter, true); -		ixgb_up(adapter); -		ixgb_set_speed_duplex(netdev); -	} else -		ixgb_reset(adapter); - -	return 0; -} - - -static const struct net_device_ops ixgb_netdev_ops = { -	.ndo_open 		= ixgb_open, -	.ndo_stop		= ixgb_close, -	.ndo_start_xmit		= ixgb_xmit_frame, -	.ndo_set_rx_mode	= ixgb_set_multi, -	.ndo_validate_addr	= eth_validate_addr, -	.ndo_set_mac_address	= ixgb_set_mac, -	.ndo_change_mtu		= ixgb_change_mtu, -	.ndo_tx_timeout		= ixgb_tx_timeout, -	.ndo_vlan_rx_add_vid	= ixgb_vlan_rx_add_vid, -	.ndo_vlan_rx_kill_vid	= ixgb_vlan_rx_kill_vid, -	.ndo_fix_features       = ixgb_fix_features, -	.ndo_set_features       = ixgb_set_features, -}; - -/** - * ixgb_probe - Device Initialization Routine - * @pdev: PCI device information struct - * @ent: entry in ixgb_pci_tbl - * - * Returns 0 on success, negative on failure - * - * ixgb_probe initializes an adapter identified by a pci_dev structure. - * The OS initialization, configuring of the adapter private structure, - * and a hardware reset occur. - **/ - -static int -ixgb_probe(struct pci_dev *pdev, const struct pci_device_id *ent) -{ -	struct net_device *netdev = NULL; -	struct ixgb_adapter *adapter; -	static int cards_found = 0; -	u8 addr[ETH_ALEN]; -	int i; -	int err; - -	err = pci_enable_device(pdev); -	if (err) -		return err; - -	err = dma_set_mask_and_coherent(&pdev->dev, DMA_BIT_MASK(64)); -	if (err) { -		pr_err("No usable DMA configuration, aborting\n"); -		goto err_dma_mask; -	} - -	err = pci_request_regions(pdev, ixgb_driver_name); -	if (err) -		goto err_request_regions; - -	pci_set_master(pdev); - -	netdev = alloc_etherdev(sizeof(struct ixgb_adapter)); -	if (!netdev) { -		err = -ENOMEM; -		goto err_alloc_etherdev; -	} - -	SET_NETDEV_DEV(netdev, &pdev->dev); - -	pci_set_drvdata(pdev, netdev); -	adapter = netdev_priv(netdev); -	adapter->netdev = netdev; -	adapter->pdev = pdev; -	adapter->hw.back = adapter; -	adapter->msg_enable = netif_msg_init(debug, DEFAULT_MSG_ENABLE); - -	adapter->hw.hw_addr = pci_ioremap_bar(pdev, BAR_0); -	if (!adapter->hw.hw_addr) { -		err = -EIO; -		goto err_ioremap; -	} - -	for (i = BAR_1; i < PCI_STD_NUM_BARS; i++) { -		if (pci_resource_len(pdev, i) == 0) -			continue; -		if (pci_resource_flags(pdev, i) & IORESOURCE_IO) { -			adapter->hw.io_base = pci_resource_start(pdev, i); -			break; -		} -	} - -	netdev->netdev_ops = &ixgb_netdev_ops; -	ixgb_set_ethtool_ops(netdev); -	netdev->watchdog_timeo = 5 * HZ; -	netif_napi_add(netdev, &adapter->napi, ixgb_clean); - -	strncpy(netdev->name, pci_name(pdev), sizeof(netdev->name) - 1); - -	adapter->bd_number = cards_found; -	adapter->link_speed = 0; -	adapter->link_duplex = 0; - -	/* setup the private structure */ - -	err = ixgb_sw_init(adapter); -	if (err) -		goto err_sw_init; - -	netdev->hw_features = NETIF_F_SG | -			   NETIF_F_TSO | -			   NETIF_F_HW_CSUM | -			   NETIF_F_HW_VLAN_CTAG_TX | -			   NETIF_F_HW_VLAN_CTAG_RX; -	netdev->features = netdev->hw_features | -			   NETIF_F_HW_VLAN_CTAG_FILTER; -	netdev->hw_features |= NETIF_F_RXCSUM; - -	netdev->features |= NETIF_F_HIGHDMA; -	netdev->vlan_features |= NETIF_F_HIGHDMA; - -	/* MTU range: 68 - 16114 */ -	netdev->min_mtu = ETH_MIN_MTU; -	netdev->max_mtu = IXGB_MAX_JUMBO_FRAME_SIZE - ETH_HLEN; - -	/* make sure the EEPROM is good */ - -	if (!ixgb_validate_eeprom_checksum(&adapter->hw)) { -		netif_err(adapter, probe, adapter->netdev, -			  "The EEPROM Checksum Is Not Valid\n"); -		err = -EIO; -		goto err_eeprom; -	} - -	ixgb_get_ee_mac_addr(&adapter->hw, addr); -	eth_hw_addr_set(netdev, addr); - -	if (!is_valid_ether_addr(netdev->dev_addr)) { -		netif_err(adapter, probe, adapter->netdev, "Invalid MAC Address\n"); -		err = -EIO; -		goto err_eeprom; -	} - -	adapter->part_num = ixgb_get_ee_pba_number(&adapter->hw); - -	timer_setup(&adapter->watchdog_timer, ixgb_watchdog, 0); - -	INIT_WORK(&adapter->tx_timeout_task, ixgb_tx_timeout_task); - -	strcpy(netdev->name, "eth%d"); -	err = register_netdev(netdev); -	if (err) -		goto err_register; - -	/* carrier off reporting is important to ethtool even BEFORE open */ -	netif_carrier_off(netdev); - -	netif_info(adapter, probe, adapter->netdev, -		   "Intel(R) PRO/10GbE Network Connection\n"); -	ixgb_check_options(adapter); -	/* reset the hardware with the new settings */ - -	ixgb_reset(adapter); - -	cards_found++; -	return 0; - -err_register: -err_sw_init: -err_eeprom: -	iounmap(adapter->hw.hw_addr); -err_ioremap: -	free_netdev(netdev); -err_alloc_etherdev: -	pci_release_regions(pdev); -err_request_regions: -err_dma_mask: -	pci_disable_device(pdev); -	return err; -} - -/** - * ixgb_remove - Device Removal Routine - * @pdev: PCI device information struct - * - * ixgb_remove is called by the PCI subsystem to alert the driver - * that it should release a PCI device.  The could be caused by a - * Hot-Plug event, or because the driver is going to be removed from - * memory. - **/ - -static void -ixgb_remove(struct pci_dev *pdev) -{ -	struct net_device *netdev = pci_get_drvdata(pdev); -	struct ixgb_adapter *adapter = netdev_priv(netdev); - -	cancel_work_sync(&adapter->tx_timeout_task); - -	unregister_netdev(netdev); - -	iounmap(adapter->hw.hw_addr); -	pci_release_regions(pdev); - -	free_netdev(netdev); -	pci_disable_device(pdev); -} - -/** - * ixgb_sw_init - Initialize general software structures (struct ixgb_adapter) - * @adapter: board private structure to initialize - * - * ixgb_sw_init initializes the Adapter private data structure. - * Fields are initialized based on PCI device information and - * OS network device settings (MTU size). - **/ - -static int -ixgb_sw_init(struct ixgb_adapter *adapter) -{ -	struct ixgb_hw *hw = &adapter->hw; -	struct net_device *netdev = adapter->netdev; -	struct pci_dev *pdev = adapter->pdev; - -	/* PCI config space info */ - -	hw->vendor_id = pdev->vendor; -	hw->device_id = pdev->device; -	hw->subsystem_vendor_id = pdev->subsystem_vendor; -	hw->subsystem_id = pdev->subsystem_device; - -	hw->max_frame_size = netdev->mtu + ENET_HEADER_SIZE + ENET_FCS_LENGTH; -	adapter->rx_buffer_len = hw->max_frame_size + 8; /* + 8 for errata */ - -	if ((hw->device_id == IXGB_DEVICE_ID_82597EX) || -	    (hw->device_id == IXGB_DEVICE_ID_82597EX_CX4) || -	    (hw->device_id == IXGB_DEVICE_ID_82597EX_LR) || -	    (hw->device_id == IXGB_DEVICE_ID_82597EX_SR)) -		hw->mac_type = ixgb_82597; -	else { -		/* should never have loaded on this device */ -		netif_err(adapter, probe, adapter->netdev, "unsupported device id\n"); -	} - -	/* enable flow control to be programmed */ -	hw->fc.send_xon = 1; - -	set_bit(__IXGB_DOWN, &adapter->flags); -	return 0; -} - -/** - * ixgb_open - Called when a network interface is made active - * @netdev: network interface device structure - * - * Returns 0 on success, negative value on failure - * - * The open entry point is called when a network interface is made - * active by the system (IFF_UP).  At this point all resources needed - * for transmit and receive operations are allocated, the interrupt - * handler is registered with the OS, the watchdog timer is started, - * and the stack is notified that the interface is ready. - **/ - -static int -ixgb_open(struct net_device *netdev) -{ -	struct ixgb_adapter *adapter = netdev_priv(netdev); -	int err; - -	/* allocate transmit descriptors */ -	err = ixgb_setup_tx_resources(adapter); -	if (err) -		goto err_setup_tx; - -	netif_carrier_off(netdev); - -	/* allocate receive descriptors */ - -	err = ixgb_setup_rx_resources(adapter); -	if (err) -		goto err_setup_rx; - -	err = ixgb_up(adapter); -	if (err) -		goto err_up; - -	netif_start_queue(netdev); - -	return 0; - -err_up: -	ixgb_free_rx_resources(adapter); -err_setup_rx: -	ixgb_free_tx_resources(adapter); -err_setup_tx: -	ixgb_reset(adapter); - -	return err; -} - -/** - * ixgb_close - Disables a network interface - * @netdev: network interface device structure - * - * Returns 0, this is not allowed to fail - * - * The close entry point is called when an interface is de-activated - * by the OS.  The hardware is still under the drivers control, but - * needs to be disabled.  A global MAC reset is issued to stop the - * hardware, and all transmit and receive resources are freed. - **/ - -static int -ixgb_close(struct net_device *netdev) -{ -	struct ixgb_adapter *adapter = netdev_priv(netdev); - -	ixgb_down(adapter, true); - -	ixgb_free_tx_resources(adapter); -	ixgb_free_rx_resources(adapter); - -	return 0; -} - -/** - * ixgb_setup_tx_resources - allocate Tx resources (Descriptors) - * @adapter: board private structure - * - * Return 0 on success, negative on failure - **/ - -int -ixgb_setup_tx_resources(struct ixgb_adapter *adapter) -{ -	struct ixgb_desc_ring *txdr = &adapter->tx_ring; -	struct pci_dev *pdev = adapter->pdev; -	int size; - -	size = sizeof(struct ixgb_buffer) * txdr->count; -	txdr->buffer_info = vzalloc(size); -	if (!txdr->buffer_info) -		return -ENOMEM; - -	/* round up to nearest 4K */ - -	txdr->size = txdr->count * sizeof(struct ixgb_tx_desc); -	txdr->size = ALIGN(txdr->size, 4096); - -	txdr->desc = dma_alloc_coherent(&pdev->dev, txdr->size, &txdr->dma, -					GFP_KERNEL); -	if (!txdr->desc) { -		vfree(txdr->buffer_info); -		return -ENOMEM; -	} - -	txdr->next_to_use = 0; -	txdr->next_to_clean = 0; - -	return 0; -} - -/** - * ixgb_configure_tx - Configure 82597 Transmit Unit after Reset. - * @adapter: board private structure - * - * Configure the Tx unit of the MAC after a reset. - **/ - -static void -ixgb_configure_tx(struct ixgb_adapter *adapter) -{ -	u64 tdba = adapter->tx_ring.dma; -	u32 tdlen = adapter->tx_ring.count * sizeof(struct ixgb_tx_desc); -	u32 tctl; -	struct ixgb_hw *hw = &adapter->hw; - -	/* Setup the Base and Length of the Tx Descriptor Ring -	 * tx_ring.dma can be either a 32 or 64 bit value -	 */ - -	IXGB_WRITE_REG(hw, TDBAL, (tdba & 0x00000000ffffffffULL)); -	IXGB_WRITE_REG(hw, TDBAH, (tdba >> 32)); - -	IXGB_WRITE_REG(hw, TDLEN, tdlen); - -	/* Setup the HW Tx Head and Tail descriptor pointers */ - -	IXGB_WRITE_REG(hw, TDH, 0); -	IXGB_WRITE_REG(hw, TDT, 0); - -	/* don't set up txdctl, it induces performance problems if configured -	 * incorrectly */ -	/* Set the Tx Interrupt Delay register */ - -	IXGB_WRITE_REG(hw, TIDV, adapter->tx_int_delay); - -	/* Program the Transmit Control Register */ - -	tctl = IXGB_TCTL_TCE | IXGB_TCTL_TXEN | IXGB_TCTL_TPDE; -	IXGB_WRITE_REG(hw, TCTL, tctl); - -	/* Setup Transmit Descriptor Settings for this adapter */ -	adapter->tx_cmd_type = -		IXGB_TX_DESC_TYPE | -		(adapter->tx_int_delay_enable ? IXGB_TX_DESC_CMD_IDE : 0); -} - -/** - * ixgb_setup_rx_resources - allocate Rx resources (Descriptors) - * @adapter: board private structure - * - * Returns 0 on success, negative on failure - **/ - -int -ixgb_setup_rx_resources(struct ixgb_adapter *adapter) -{ -	struct ixgb_desc_ring *rxdr = &adapter->rx_ring; -	struct pci_dev *pdev = adapter->pdev; -	int size; - -	size = sizeof(struct ixgb_buffer) * rxdr->count; -	rxdr->buffer_info = vzalloc(size); -	if (!rxdr->buffer_info) -		return -ENOMEM; - -	/* Round up to nearest 4K */ - -	rxdr->size = rxdr->count * sizeof(struct ixgb_rx_desc); -	rxdr->size = ALIGN(rxdr->size, 4096); - -	rxdr->desc = dma_alloc_coherent(&pdev->dev, rxdr->size, &rxdr->dma, -					GFP_KERNEL); - -	if (!rxdr->desc) { -		vfree(rxdr->buffer_info); -		return -ENOMEM; -	} - -	rxdr->next_to_clean = 0; -	rxdr->next_to_use = 0; - -	return 0; -} - -/** - * ixgb_setup_rctl - configure the receive control register - * @adapter: Board private structure - **/ - -static void -ixgb_setup_rctl(struct ixgb_adapter *adapter) -{ -	u32 rctl; - -	rctl = IXGB_READ_REG(&adapter->hw, RCTL); - -	rctl &= ~(3 << IXGB_RCTL_MO_SHIFT); - -	rctl |= -		IXGB_RCTL_BAM | IXGB_RCTL_RDMTS_1_2 | -		IXGB_RCTL_RXEN | IXGB_RCTL_CFF | -		(adapter->hw.mc_filter_type << IXGB_RCTL_MO_SHIFT); - -	rctl |= IXGB_RCTL_SECRC; - -	if (adapter->rx_buffer_len <= IXGB_RXBUFFER_2048) -		rctl |= IXGB_RCTL_BSIZE_2048; -	else if (adapter->rx_buffer_len <= IXGB_RXBUFFER_4096) -		rctl |= IXGB_RCTL_BSIZE_4096; -	else if (adapter->rx_buffer_len <= IXGB_RXBUFFER_8192) -		rctl |= IXGB_RCTL_BSIZE_8192; -	else if (adapter->rx_buffer_len <= IXGB_RXBUFFER_16384) -		rctl |= IXGB_RCTL_BSIZE_16384; - -	IXGB_WRITE_REG(&adapter->hw, RCTL, rctl); -} - -/** - * ixgb_configure_rx - Configure 82597 Receive Unit after Reset. - * @adapter: board private structure - * - * Configure the Rx unit of the MAC after a reset. - **/ - -static void -ixgb_configure_rx(struct ixgb_adapter *adapter) -{ -	u64 rdba = adapter->rx_ring.dma; -	u32 rdlen = adapter->rx_ring.count * sizeof(struct ixgb_rx_desc); -	struct ixgb_hw *hw = &adapter->hw; -	u32 rctl; -	u32 rxcsum; - -	/* make sure receives are disabled while setting up the descriptors */ - -	rctl = IXGB_READ_REG(hw, RCTL); -	IXGB_WRITE_REG(hw, RCTL, rctl & ~IXGB_RCTL_RXEN); - -	/* set the Receive Delay Timer Register */ - -	IXGB_WRITE_REG(hw, RDTR, adapter->rx_int_delay); - -	/* Setup the Base and Length of the Rx Descriptor Ring */ - -	IXGB_WRITE_REG(hw, RDBAL, (rdba & 0x00000000ffffffffULL)); -	IXGB_WRITE_REG(hw, RDBAH, (rdba >> 32)); - -	IXGB_WRITE_REG(hw, RDLEN, rdlen); - -	/* Setup the HW Rx Head and Tail Descriptor Pointers */ -	IXGB_WRITE_REG(hw, RDH, 0); -	IXGB_WRITE_REG(hw, RDT, 0); - -	/* due to the hardware errata with RXDCTL, we are unable to use any of -	 * the performance enhancing features of it without causing other -	 * subtle bugs, some of the bugs could include receive length -	 * corruption at high data rates (WTHRESH > 0) and/or receive -	 * descriptor ring irregularites (particularly in hardware cache) */ -	IXGB_WRITE_REG(hw, RXDCTL, 0); - -	/* Enable Receive Checksum Offload for TCP and UDP */ -	if (adapter->rx_csum) { -		rxcsum = IXGB_READ_REG(hw, RXCSUM); -		rxcsum |= IXGB_RXCSUM_TUOFL; -		IXGB_WRITE_REG(hw, RXCSUM, rxcsum); -	} - -	/* Enable Receives */ - -	IXGB_WRITE_REG(hw, RCTL, rctl); -} - -/** - * ixgb_free_tx_resources - Free Tx Resources - * @adapter: board private structure - * - * Free all transmit software resources - **/ - -void -ixgb_free_tx_resources(struct ixgb_adapter *adapter) -{ -	struct pci_dev *pdev = adapter->pdev; - -	ixgb_clean_tx_ring(adapter); - -	vfree(adapter->tx_ring.buffer_info); -	adapter->tx_ring.buffer_info = NULL; - -	dma_free_coherent(&pdev->dev, adapter->tx_ring.size, -			  adapter->tx_ring.desc, adapter->tx_ring.dma); - -	adapter->tx_ring.desc = NULL; -} - -static void -ixgb_unmap_and_free_tx_resource(struct ixgb_adapter *adapter, -                                struct ixgb_buffer *buffer_info) -{ -	if (buffer_info->dma) { -		if (buffer_info->mapped_as_page) -			dma_unmap_page(&adapter->pdev->dev, buffer_info->dma, -				       buffer_info->length, DMA_TO_DEVICE); -		else -			dma_unmap_single(&adapter->pdev->dev, buffer_info->dma, -					 buffer_info->length, DMA_TO_DEVICE); -		buffer_info->dma = 0; -	} - -	if (buffer_info->skb) { -		dev_kfree_skb_any(buffer_info->skb); -		buffer_info->skb = NULL; -	} -	buffer_info->time_stamp = 0; -	/* these fields must always be initialized in tx -	 * buffer_info->length = 0; -	 * buffer_info->next_to_watch = 0; */ -} - -/** - * ixgb_clean_tx_ring - Free Tx Buffers - * @adapter: board private structure - **/ - -static void -ixgb_clean_tx_ring(struct ixgb_adapter *adapter) -{ -	struct ixgb_desc_ring *tx_ring = &adapter->tx_ring; -	struct ixgb_buffer *buffer_info; -	unsigned long size; -	unsigned int i; - -	/* Free all the Tx ring sk_buffs */ - -	for (i = 0; i < tx_ring->count; i++) { -		buffer_info = &tx_ring->buffer_info[i]; -		ixgb_unmap_and_free_tx_resource(adapter, buffer_info); -	} - -	size = sizeof(struct ixgb_buffer) * tx_ring->count; -	memset(tx_ring->buffer_info, 0, size); - -	/* Zero out the descriptor ring */ - -	memset(tx_ring->desc, 0, tx_ring->size); - -	tx_ring->next_to_use = 0; -	tx_ring->next_to_clean = 0; - -	IXGB_WRITE_REG(&adapter->hw, TDH, 0); -	IXGB_WRITE_REG(&adapter->hw, TDT, 0); -} - -/** - * ixgb_free_rx_resources - Free Rx Resources - * @adapter: board private structure - * - * Free all receive software resources - **/ - -void -ixgb_free_rx_resources(struct ixgb_adapter *adapter) -{ -	struct ixgb_desc_ring *rx_ring = &adapter->rx_ring; -	struct pci_dev *pdev = adapter->pdev; - -	ixgb_clean_rx_ring(adapter); - -	vfree(rx_ring->buffer_info); -	rx_ring->buffer_info = NULL; - -	dma_free_coherent(&pdev->dev, rx_ring->size, rx_ring->desc, -			  rx_ring->dma); - -	rx_ring->desc = NULL; -} - -/** - * ixgb_clean_rx_ring - Free Rx Buffers - * @adapter: board private structure - **/ - -static void -ixgb_clean_rx_ring(struct ixgb_adapter *adapter) -{ -	struct ixgb_desc_ring *rx_ring = &adapter->rx_ring; -	struct ixgb_buffer *buffer_info; -	struct pci_dev *pdev = adapter->pdev; -	unsigned long size; -	unsigned int i; - -	/* Free all the Rx ring sk_buffs */ - -	for (i = 0; i < rx_ring->count; i++) { -		buffer_info = &rx_ring->buffer_info[i]; -		if (buffer_info->dma) { -			dma_unmap_single(&pdev->dev, -					 buffer_info->dma, -					 buffer_info->length, -					 DMA_FROM_DEVICE); -			buffer_info->dma = 0; -			buffer_info->length = 0; -		} - -		if (buffer_info->skb) { -			dev_kfree_skb(buffer_info->skb); -			buffer_info->skb = NULL; -		} -	} - -	size = sizeof(struct ixgb_buffer) * rx_ring->count; -	memset(rx_ring->buffer_info, 0, size); - -	/* Zero out the descriptor ring */ - -	memset(rx_ring->desc, 0, rx_ring->size); - -	rx_ring->next_to_clean = 0; -	rx_ring->next_to_use = 0; - -	IXGB_WRITE_REG(&adapter->hw, RDH, 0); -	IXGB_WRITE_REG(&adapter->hw, RDT, 0); -} - -/** - * ixgb_set_mac - Change the Ethernet Address of the NIC - * @netdev: network interface device structure - * @p: pointer to an address structure - * - * Returns 0 on success, negative on failure - **/ - -static int -ixgb_set_mac(struct net_device *netdev, void *p) -{ -	struct ixgb_adapter *adapter = netdev_priv(netdev); -	struct sockaddr *addr = p; - -	if (!is_valid_ether_addr(addr->sa_data)) -		return -EADDRNOTAVAIL; - -	eth_hw_addr_set(netdev, addr->sa_data); - -	ixgb_rar_set(&adapter->hw, addr->sa_data, 0); - -	return 0; -} - -/** - * ixgb_set_multi - Multicast and Promiscuous mode set - * @netdev: network interface device structure - * - * The set_multi entry point is called whenever the multicast address - * list or the network interface flags are updated.  This routine is - * responsible for configuring the hardware for proper multicast, - * promiscuous mode, and all-multi behavior. - **/ - -static void -ixgb_set_multi(struct net_device *netdev) -{ -	struct ixgb_adapter *adapter = netdev_priv(netdev); -	struct ixgb_hw *hw = &adapter->hw; -	struct netdev_hw_addr *ha; -	u32 rctl; - -	/* Check for Promiscuous and All Multicast modes */ - -	rctl = IXGB_READ_REG(hw, RCTL); - -	if (netdev->flags & IFF_PROMISC) { -		rctl |= (IXGB_RCTL_UPE | IXGB_RCTL_MPE); -		/* disable VLAN filtering */ -		rctl &= ~IXGB_RCTL_CFIEN; -		rctl &= ~IXGB_RCTL_VFE; -	} else { -		if (netdev->flags & IFF_ALLMULTI) { -			rctl |= IXGB_RCTL_MPE; -			rctl &= ~IXGB_RCTL_UPE; -		} else { -			rctl &= ~(IXGB_RCTL_UPE | IXGB_RCTL_MPE); -		} -		/* enable VLAN filtering */ -		rctl |= IXGB_RCTL_VFE; -		rctl &= ~IXGB_RCTL_CFIEN; -	} - -	if (netdev_mc_count(netdev) > IXGB_MAX_NUM_MULTICAST_ADDRESSES) { -		rctl |= IXGB_RCTL_MPE; -		IXGB_WRITE_REG(hw, RCTL, rctl); -	} else { -		u8 *mta = kmalloc_array(ETH_ALEN, -				        IXGB_MAX_NUM_MULTICAST_ADDRESSES, -				        GFP_ATOMIC); -		u8 *addr; -		if (!mta) -			goto alloc_failed; - -		IXGB_WRITE_REG(hw, RCTL, rctl); - -		addr = mta; -		netdev_for_each_mc_addr(ha, netdev) { -			memcpy(addr, ha->addr, ETH_ALEN); -			addr += ETH_ALEN; -		} - -		ixgb_mc_addr_list_update(hw, mta, netdev_mc_count(netdev), 0); -		kfree(mta); -	} - -alloc_failed: -	if (netdev->features & NETIF_F_HW_VLAN_CTAG_RX) -		ixgb_vlan_strip_enable(adapter); -	else -		ixgb_vlan_strip_disable(adapter); - -} - -/** - * ixgb_watchdog - Timer Call-back - * @t: pointer to timer_list containing our private info pointer - **/ - -static void -ixgb_watchdog(struct timer_list *t) -{ -	struct ixgb_adapter *adapter = from_timer(adapter, t, watchdog_timer); -	struct net_device *netdev = adapter->netdev; -	struct ixgb_desc_ring *txdr = &adapter->tx_ring; - -	ixgb_check_for_link(&adapter->hw); - -	if (ixgb_check_for_bad_link(&adapter->hw)) { -		/* force the reset path */ -		netif_stop_queue(netdev); -	} - -	if (adapter->hw.link_up) { -		if (!netif_carrier_ok(netdev)) { -			netdev_info(netdev, -				    "NIC Link is Up 10 Gbps Full Duplex, Flow Control: %s\n", -				    (adapter->hw.fc.type == ixgb_fc_full) ? -				    "RX/TX" : -				    (adapter->hw.fc.type == ixgb_fc_rx_pause) ? -				     "RX" : -				    (adapter->hw.fc.type == ixgb_fc_tx_pause) ? -				    "TX" : "None"); -			adapter->link_speed = 10000; -			adapter->link_duplex = FULL_DUPLEX; -			netif_carrier_on(netdev); -		} -	} else { -		if (netif_carrier_ok(netdev)) { -			adapter->link_speed = 0; -			adapter->link_duplex = 0; -			netdev_info(netdev, "NIC Link is Down\n"); -			netif_carrier_off(netdev); -		} -	} - -	ixgb_update_stats(adapter); - -	if (!netif_carrier_ok(netdev)) { -		if (IXGB_DESC_UNUSED(txdr) + 1 < txdr->count) { -			/* We've lost link, so the controller stops DMA, -			 * but we've got queued Tx work that's never going -			 * to get done, so reset controller to flush Tx. -			 * (Do the reset outside of interrupt context). */ -			schedule_work(&adapter->tx_timeout_task); -			/* return immediately since reset is imminent */ -			return; -		} -	} - -	/* Force detection of hung controller every watchdog period */ -	adapter->detect_tx_hung = true; - -	/* generate an interrupt to force clean up of any stragglers */ -	IXGB_WRITE_REG(&adapter->hw, ICS, IXGB_INT_TXDW); - -	/* Reset the timer */ -	mod_timer(&adapter->watchdog_timer, jiffies + 2 * HZ); -} - -#define IXGB_TX_FLAGS_CSUM		0x00000001 -#define IXGB_TX_FLAGS_VLAN		0x00000002 -#define IXGB_TX_FLAGS_TSO		0x00000004 - -static int -ixgb_tso(struct ixgb_adapter *adapter, struct sk_buff *skb) -{ -	struct ixgb_context_desc *context_desc; -	unsigned int i; -	u8 ipcss, ipcso, tucss, tucso, hdr_len; -	u16 ipcse, tucse, mss; - -	if (likely(skb_is_gso(skb))) { -		struct ixgb_buffer *buffer_info; -		struct iphdr *iph; -		int err; - -		err = skb_cow_head(skb, 0); -		if (err < 0) -			return err; - -		hdr_len = skb_tcp_all_headers(skb); -		mss = skb_shinfo(skb)->gso_size; -		iph = ip_hdr(skb); -		iph->tot_len = 0; -		iph->check = 0; -		tcp_hdr(skb)->check = ~csum_tcpudp_magic(iph->saddr, -							 iph->daddr, 0, -							 IPPROTO_TCP, 0); -		ipcss = skb_network_offset(skb); -		ipcso = (void *)&(iph->check) - (void *)skb->data; -		ipcse = skb_transport_offset(skb) - 1; -		tucss = skb_transport_offset(skb); -		tucso = (void *)&(tcp_hdr(skb)->check) - (void *)skb->data; -		tucse = 0; - -		i = adapter->tx_ring.next_to_use; -		context_desc = IXGB_CONTEXT_DESC(adapter->tx_ring, i); -		buffer_info = &adapter->tx_ring.buffer_info[i]; -		WARN_ON(buffer_info->dma != 0); - -		context_desc->ipcss = ipcss; -		context_desc->ipcso = ipcso; -		context_desc->ipcse = cpu_to_le16(ipcse); -		context_desc->tucss = tucss; -		context_desc->tucso = tucso; -		context_desc->tucse = cpu_to_le16(tucse); -		context_desc->mss = cpu_to_le16(mss); -		context_desc->hdr_len = hdr_len; -		context_desc->status = 0; -		context_desc->cmd_type_len = cpu_to_le32( -						  IXGB_CONTEXT_DESC_TYPE -						| IXGB_CONTEXT_DESC_CMD_TSE -						| IXGB_CONTEXT_DESC_CMD_IP -						| IXGB_CONTEXT_DESC_CMD_TCP -						| IXGB_CONTEXT_DESC_CMD_IDE -						| (skb->len - (hdr_len))); - - -		if (++i == adapter->tx_ring.count) i = 0; -		adapter->tx_ring.next_to_use = i; - -		return 1; -	} - -	return 0; -} - -static bool -ixgb_tx_csum(struct ixgb_adapter *adapter, struct sk_buff *skb) -{ -	struct ixgb_context_desc *context_desc; -	unsigned int i; -	u8 css, cso; - -	if (likely(skb->ip_summed == CHECKSUM_PARTIAL)) { -		struct ixgb_buffer *buffer_info; -		css = skb_checksum_start_offset(skb); -		cso = css + skb->csum_offset; - -		i = adapter->tx_ring.next_to_use; -		context_desc = IXGB_CONTEXT_DESC(adapter->tx_ring, i); -		buffer_info = &adapter->tx_ring.buffer_info[i]; -		WARN_ON(buffer_info->dma != 0); - -		context_desc->tucss = css; -		context_desc->tucso = cso; -		context_desc->tucse = 0; -		/* zero out any previously existing data in one instruction */ -		*(u32 *)&(context_desc->ipcss) = 0; -		context_desc->status = 0; -		context_desc->hdr_len = 0; -		context_desc->mss = 0; -		context_desc->cmd_type_len = -			cpu_to_le32(IXGB_CONTEXT_DESC_TYPE -				    | IXGB_TX_DESC_CMD_IDE); - -		if (++i == adapter->tx_ring.count) i = 0; -		adapter->tx_ring.next_to_use = i; - -		return true; -	} - -	return false; -} - -#define IXGB_MAX_TXD_PWR	14 -#define IXGB_MAX_DATA_PER_TXD	(1<<IXGB_MAX_TXD_PWR) - -static int -ixgb_tx_map(struct ixgb_adapter *adapter, struct sk_buff *skb, -	    unsigned int first) -{ -	struct ixgb_desc_ring *tx_ring = &adapter->tx_ring; -	struct pci_dev *pdev = adapter->pdev; -	struct ixgb_buffer *buffer_info; -	int len = skb_headlen(skb); -	unsigned int offset = 0, size, count = 0, i; -	unsigned int mss = skb_shinfo(skb)->gso_size; -	unsigned int nr_frags = skb_shinfo(skb)->nr_frags; -	unsigned int f; - -	i = tx_ring->next_to_use; - -	while (len) { -		buffer_info = &tx_ring->buffer_info[i]; -		size = min(len, IXGB_MAX_DATA_PER_TXD); -		/* Workaround for premature desc write-backs -		 * in TSO mode.  Append 4-byte sentinel desc */ -		if (unlikely(mss && !nr_frags && size == len && size > 8)) -			size -= 4; - -		buffer_info->length = size; -		WARN_ON(buffer_info->dma != 0); -		buffer_info->time_stamp = jiffies; -		buffer_info->mapped_as_page = false; -		buffer_info->dma = dma_map_single(&pdev->dev, -						  skb->data + offset, -						  size, DMA_TO_DEVICE); -		if (dma_mapping_error(&pdev->dev, buffer_info->dma)) -			goto dma_error; -		buffer_info->next_to_watch = 0; - -		len -= size; -		offset += size; -		count++; -		if (len) { -			i++; -			if (i == tx_ring->count) -				i = 0; -		} -	} - -	for (f = 0; f < nr_frags; f++) { -		const skb_frag_t *frag = &skb_shinfo(skb)->frags[f]; -		len = skb_frag_size(frag); -		offset = 0; - -		while (len) { -			i++; -			if (i == tx_ring->count) -				i = 0; - -			buffer_info = &tx_ring->buffer_info[i]; -			size = min(len, IXGB_MAX_DATA_PER_TXD); - -			/* Workaround for premature desc write-backs -			 * in TSO mode.  Append 4-byte sentinel desc */ -			if (unlikely(mss && (f == (nr_frags - 1)) -				     && size == len && size > 8)) -				size -= 4; - -			buffer_info->length = size; -			buffer_info->time_stamp = jiffies; -			buffer_info->mapped_as_page = true; -			buffer_info->dma = -				skb_frag_dma_map(&pdev->dev, frag, offset, size, -						 DMA_TO_DEVICE); -			if (dma_mapping_error(&pdev->dev, buffer_info->dma)) -				goto dma_error; -			buffer_info->next_to_watch = 0; - -			len -= size; -			offset += size; -			count++; -		} -	} -	tx_ring->buffer_info[i].skb = skb; -	tx_ring->buffer_info[first].next_to_watch = i; - -	return count; - -dma_error: -	dev_err(&pdev->dev, "TX DMA map failed\n"); -	buffer_info->dma = 0; -	if (count) -		count--; - -	while (count--) { -		if (i==0) -			i += tx_ring->count; -		i--; -		buffer_info = &tx_ring->buffer_info[i]; -		ixgb_unmap_and_free_tx_resource(adapter, buffer_info); -	} - -	return 0; -} - -static void -ixgb_tx_queue(struct ixgb_adapter *adapter, int count, int vlan_id,int tx_flags) -{ -	struct ixgb_desc_ring *tx_ring = &adapter->tx_ring; -	struct ixgb_tx_desc *tx_desc = NULL; -	struct ixgb_buffer *buffer_info; -	u32 cmd_type_len = adapter->tx_cmd_type; -	u8 status = 0; -	u8 popts = 0; -	unsigned int i; - -	if (tx_flags & IXGB_TX_FLAGS_TSO) { -		cmd_type_len |= IXGB_TX_DESC_CMD_TSE; -		popts |= (IXGB_TX_DESC_POPTS_IXSM | IXGB_TX_DESC_POPTS_TXSM); -	} - -	if (tx_flags & IXGB_TX_FLAGS_CSUM) -		popts |= IXGB_TX_DESC_POPTS_TXSM; - -	if (tx_flags & IXGB_TX_FLAGS_VLAN) -		cmd_type_len |= IXGB_TX_DESC_CMD_VLE; - -	i = tx_ring->next_to_use; - -	while (count--) { -		buffer_info = &tx_ring->buffer_info[i]; -		tx_desc = IXGB_TX_DESC(*tx_ring, i); -		tx_desc->buff_addr = cpu_to_le64(buffer_info->dma); -		tx_desc->cmd_type_len = -			cpu_to_le32(cmd_type_len | buffer_info->length); -		tx_desc->status = status; -		tx_desc->popts = popts; -		tx_desc->vlan = cpu_to_le16(vlan_id); - -		if (++i == tx_ring->count) i = 0; -	} - -	tx_desc->cmd_type_len |= -		cpu_to_le32(IXGB_TX_DESC_CMD_EOP | IXGB_TX_DESC_CMD_RS); - -	/* Force memory writes to complete before letting h/w -	 * know there are new descriptors to fetch.  (Only -	 * applicable for weak-ordered memory model archs, -	 * such as IA-64). */ -	wmb(); - -	tx_ring->next_to_use = i; -	IXGB_WRITE_REG(&adapter->hw, TDT, i); -} - -static int __ixgb_maybe_stop_tx(struct net_device *netdev, int size) -{ -	struct ixgb_adapter *adapter = netdev_priv(netdev); -	struct ixgb_desc_ring *tx_ring = &adapter->tx_ring; - -	netif_stop_queue(netdev); -	/* Herbert's original patch had: -	 *  smp_mb__after_netif_stop_queue(); -	 * but since that doesn't exist yet, just open code it. */ -	smp_mb(); - -	/* We need to check again in a case another CPU has just -	 * made room available. */ -	if (likely(IXGB_DESC_UNUSED(tx_ring) < size)) -		return -EBUSY; - -	/* A reprieve! */ -	netif_start_queue(netdev); -	++adapter->restart_queue; -	return 0; -} - -static int ixgb_maybe_stop_tx(struct net_device *netdev, -                              struct ixgb_desc_ring *tx_ring, int size) -{ -	if (likely(IXGB_DESC_UNUSED(tx_ring) >= size)) -		return 0; -	return __ixgb_maybe_stop_tx(netdev, size); -} - - -/* Tx Descriptors needed, worst case */ -#define TXD_USE_COUNT(S) (((S) >> IXGB_MAX_TXD_PWR) + \ -			 (((S) & (IXGB_MAX_DATA_PER_TXD - 1)) ? 1 : 0)) -#define DESC_NEEDED TXD_USE_COUNT(IXGB_MAX_DATA_PER_TXD) /* skb->date */ + \ -	MAX_SKB_FRAGS * TXD_USE_COUNT(PAGE_SIZE) + 1 /* for context */ \ -	+ 1 /* one more needed for sentinel TSO workaround */ - -static netdev_tx_t -ixgb_xmit_frame(struct sk_buff *skb, struct net_device *netdev) -{ -	struct ixgb_adapter *adapter = netdev_priv(netdev); -	unsigned int first; -	unsigned int tx_flags = 0; -	int vlan_id = 0; -	int count = 0; -	int tso; - -	if (test_bit(__IXGB_DOWN, &adapter->flags)) { -		dev_kfree_skb_any(skb); -		return NETDEV_TX_OK; -	} - -	if (skb->len <= 0) { -		dev_kfree_skb_any(skb); -		return NETDEV_TX_OK; -	} - -	if (unlikely(ixgb_maybe_stop_tx(netdev, &adapter->tx_ring, -                     DESC_NEEDED))) -		return NETDEV_TX_BUSY; - -	if (skb_vlan_tag_present(skb)) { -		tx_flags |= IXGB_TX_FLAGS_VLAN; -		vlan_id = skb_vlan_tag_get(skb); -	} - -	first = adapter->tx_ring.next_to_use; - -	tso = ixgb_tso(adapter, skb); -	if (tso < 0) { -		dev_kfree_skb_any(skb); -		return NETDEV_TX_OK; -	} - -	if (likely(tso)) -		tx_flags |= IXGB_TX_FLAGS_TSO; -	else if (ixgb_tx_csum(adapter, skb)) -		tx_flags |= IXGB_TX_FLAGS_CSUM; - -	count = ixgb_tx_map(adapter, skb, first); - -	if (count) { -		ixgb_tx_queue(adapter, count, vlan_id, tx_flags); -		/* Make sure there is space in the ring for the next send. */ -		ixgb_maybe_stop_tx(netdev, &adapter->tx_ring, DESC_NEEDED); - -	} else { -		dev_kfree_skb_any(skb); -		adapter->tx_ring.buffer_info[first].time_stamp = 0; -		adapter->tx_ring.next_to_use = first; -	} - -	return NETDEV_TX_OK; -} - -/** - * ixgb_tx_timeout - Respond to a Tx Hang - * @netdev: network interface device structure - * @txqueue: queue hanging (unused) - **/ - -static void -ixgb_tx_timeout(struct net_device *netdev, unsigned int __always_unused txqueue) -{ -	struct ixgb_adapter *adapter = netdev_priv(netdev); - -	/* Do the reset outside of interrupt context */ -	schedule_work(&adapter->tx_timeout_task); -} - -static void -ixgb_tx_timeout_task(struct work_struct *work) -{ -	struct ixgb_adapter *adapter = -		container_of(work, struct ixgb_adapter, tx_timeout_task); - -	adapter->tx_timeout_count++; -	ixgb_down(adapter, true); -	ixgb_up(adapter); -} - -/** - * ixgb_change_mtu - Change the Maximum Transfer Unit - * @netdev: network interface device structure - * @new_mtu: new value for maximum frame size - * - * Returns 0 on success, negative on failure - **/ - -static int -ixgb_change_mtu(struct net_device *netdev, int new_mtu) -{ -	struct ixgb_adapter *adapter = netdev_priv(netdev); -	int max_frame = new_mtu + ENET_HEADER_SIZE + ENET_FCS_LENGTH; - -	if (netif_running(netdev)) -		ixgb_down(adapter, true); - -	adapter->rx_buffer_len = max_frame + 8; /* + 8 for errata */ - -	netdev->mtu = new_mtu; - -	if (netif_running(netdev)) -		ixgb_up(adapter); - -	return 0; -} - -/** - * ixgb_update_stats - Update the board statistics counters. - * @adapter: board private structure - **/ - -void -ixgb_update_stats(struct ixgb_adapter *adapter) -{ -	struct net_device *netdev = adapter->netdev; -	struct pci_dev *pdev = adapter->pdev; - -	/* Prevent stats update while adapter is being reset */ -	if (pci_channel_offline(pdev)) -		return; - -	if ((netdev->flags & IFF_PROMISC) || (netdev->flags & IFF_ALLMULTI) || -	   (netdev_mc_count(netdev) > IXGB_MAX_NUM_MULTICAST_ADDRESSES)) { -		u64 multi = IXGB_READ_REG(&adapter->hw, MPRCL); -		u32 bcast_l = IXGB_READ_REG(&adapter->hw, BPRCL); -		u32 bcast_h = IXGB_READ_REG(&adapter->hw, BPRCH); -		u64 bcast = ((u64)bcast_h << 32) | bcast_l; - -		multi |= ((u64)IXGB_READ_REG(&adapter->hw, MPRCH) << 32); -		/* fix up multicast stats by removing broadcasts */ -		if (multi >= bcast) -			multi -= bcast; - -		adapter->stats.mprcl += (multi & 0xFFFFFFFF); -		adapter->stats.mprch += (multi >> 32); -		adapter->stats.bprcl += bcast_l; -		adapter->stats.bprch += bcast_h; -	} else { -		adapter->stats.mprcl += IXGB_READ_REG(&adapter->hw, MPRCL); -		adapter->stats.mprch += IXGB_READ_REG(&adapter->hw, MPRCH); -		adapter->stats.bprcl += IXGB_READ_REG(&adapter->hw, BPRCL); -		adapter->stats.bprch += IXGB_READ_REG(&adapter->hw, BPRCH); -	} -	adapter->stats.tprl += IXGB_READ_REG(&adapter->hw, TPRL); -	adapter->stats.tprh += IXGB_READ_REG(&adapter->hw, TPRH); -	adapter->stats.gprcl += IXGB_READ_REG(&adapter->hw, GPRCL); -	adapter->stats.gprch += IXGB_READ_REG(&adapter->hw, GPRCH); -	adapter->stats.uprcl += IXGB_READ_REG(&adapter->hw, UPRCL); -	adapter->stats.uprch += IXGB_READ_REG(&adapter->hw, UPRCH); -	adapter->stats.vprcl += IXGB_READ_REG(&adapter->hw, VPRCL); -	adapter->stats.vprch += IXGB_READ_REG(&adapter->hw, VPRCH); -	adapter->stats.jprcl += IXGB_READ_REG(&adapter->hw, JPRCL); -	adapter->stats.jprch += IXGB_READ_REG(&adapter->hw, JPRCH); -	adapter->stats.gorcl += IXGB_READ_REG(&adapter->hw, GORCL); -	adapter->stats.gorch += IXGB_READ_REG(&adapter->hw, GORCH); -	adapter->stats.torl += IXGB_READ_REG(&adapter->hw, TORL); -	adapter->stats.torh += IXGB_READ_REG(&adapter->hw, TORH); -	adapter->stats.rnbc += IXGB_READ_REG(&adapter->hw, RNBC); -	adapter->stats.ruc += IXGB_READ_REG(&adapter->hw, RUC); -	adapter->stats.roc += IXGB_READ_REG(&adapter->hw, ROC); -	adapter->stats.rlec += IXGB_READ_REG(&adapter->hw, RLEC); -	adapter->stats.crcerrs += IXGB_READ_REG(&adapter->hw, CRCERRS); -	adapter->stats.icbc += IXGB_READ_REG(&adapter->hw, ICBC); -	adapter->stats.ecbc += IXGB_READ_REG(&adapter->hw, ECBC); -	adapter->stats.mpc += IXGB_READ_REG(&adapter->hw, MPC); -	adapter->stats.tptl += IXGB_READ_REG(&adapter->hw, TPTL); -	adapter->stats.tpth += IXGB_READ_REG(&adapter->hw, TPTH); -	adapter->stats.gptcl += IXGB_READ_REG(&adapter->hw, GPTCL); -	adapter->stats.gptch += IXGB_READ_REG(&adapter->hw, GPTCH); -	adapter->stats.bptcl += IXGB_READ_REG(&adapter->hw, BPTCL); -	adapter->stats.bptch += IXGB_READ_REG(&adapter->hw, BPTCH); -	adapter->stats.mptcl += IXGB_READ_REG(&adapter->hw, MPTCL); -	adapter->stats.mptch += IXGB_READ_REG(&adapter->hw, MPTCH); -	adapter->stats.uptcl += IXGB_READ_REG(&adapter->hw, UPTCL); -	adapter->stats.uptch += IXGB_READ_REG(&adapter->hw, UPTCH); -	adapter->stats.vptcl += IXGB_READ_REG(&adapter->hw, VPTCL); -	adapter->stats.vptch += IXGB_READ_REG(&adapter->hw, VPTCH); -	adapter->stats.jptcl += IXGB_READ_REG(&adapter->hw, JPTCL); -	adapter->stats.jptch += IXGB_READ_REG(&adapter->hw, JPTCH); -	adapter->stats.gotcl += IXGB_READ_REG(&adapter->hw, GOTCL); -	adapter->stats.gotch += IXGB_READ_REG(&adapter->hw, GOTCH); -	adapter->stats.totl += IXGB_READ_REG(&adapter->hw, TOTL); -	adapter->stats.toth += IXGB_READ_REG(&adapter->hw, TOTH); -	adapter->stats.dc += IXGB_READ_REG(&adapter->hw, DC); -	adapter->stats.plt64c += IXGB_READ_REG(&adapter->hw, PLT64C); -	adapter->stats.tsctc += IXGB_READ_REG(&adapter->hw, TSCTC); -	adapter->stats.tsctfc += IXGB_READ_REG(&adapter->hw, TSCTFC); -	adapter->stats.ibic += IXGB_READ_REG(&adapter->hw, IBIC); -	adapter->stats.rfc += IXGB_READ_REG(&adapter->hw, RFC); -	adapter->stats.lfc += IXGB_READ_REG(&adapter->hw, LFC); -	adapter->stats.pfrc += IXGB_READ_REG(&adapter->hw, PFRC); -	adapter->stats.pftc += IXGB_READ_REG(&adapter->hw, PFTC); -	adapter->stats.mcfrc += IXGB_READ_REG(&adapter->hw, MCFRC); -	adapter->stats.mcftc += IXGB_READ_REG(&adapter->hw, MCFTC); -	adapter->stats.xonrxc += IXGB_READ_REG(&adapter->hw, XONRXC); -	adapter->stats.xontxc += IXGB_READ_REG(&adapter->hw, XONTXC); -	adapter->stats.xoffrxc += IXGB_READ_REG(&adapter->hw, XOFFRXC); -	adapter->stats.xofftxc += IXGB_READ_REG(&adapter->hw, XOFFTXC); -	adapter->stats.rjc += IXGB_READ_REG(&adapter->hw, RJC); - -	/* Fill out the OS statistics structure */ - -	netdev->stats.rx_packets = adapter->stats.gprcl; -	netdev->stats.tx_packets = adapter->stats.gptcl; -	netdev->stats.rx_bytes = adapter->stats.gorcl; -	netdev->stats.tx_bytes = adapter->stats.gotcl; -	netdev->stats.multicast = adapter->stats.mprcl; -	netdev->stats.collisions = 0; - -	/* ignore RLEC as it reports errors for padded (<64bytes) frames -	 * with a length in the type/len field */ -	netdev->stats.rx_errors = -	    /* adapter->stats.rnbc + */ adapter->stats.crcerrs + -	    adapter->stats.ruc + -	    adapter->stats.roc /*+ adapter->stats.rlec */  + -	    adapter->stats.icbc + -	    adapter->stats.ecbc + adapter->stats.mpc; - -	/* see above -	 * netdev->stats.rx_length_errors = adapter->stats.rlec; -	 */ - -	netdev->stats.rx_crc_errors = adapter->stats.crcerrs; -	netdev->stats.rx_fifo_errors = adapter->stats.mpc; -	netdev->stats.rx_missed_errors = adapter->stats.mpc; -	netdev->stats.rx_over_errors = adapter->stats.mpc; - -	netdev->stats.tx_errors = 0; -	netdev->stats.rx_frame_errors = 0; -	netdev->stats.tx_aborted_errors = 0; -	netdev->stats.tx_carrier_errors = 0; -	netdev->stats.tx_fifo_errors = 0; -	netdev->stats.tx_heartbeat_errors = 0; -	netdev->stats.tx_window_errors = 0; -} - -/** - * ixgb_intr - Interrupt Handler - * @irq: interrupt number - * @data: pointer to a network interface device structure - **/ - -static irqreturn_t -ixgb_intr(int irq, void *data) -{ -	struct net_device *netdev = data; -	struct ixgb_adapter *adapter = netdev_priv(netdev); -	struct ixgb_hw *hw = &adapter->hw; -	u32 icr = IXGB_READ_REG(hw, ICR); - -	if (unlikely(!icr)) -		return IRQ_NONE;  /* Not our interrupt */ - -	if (unlikely(icr & (IXGB_INT_RXSEQ | IXGB_INT_LSC))) -		if (!test_bit(__IXGB_DOWN, &adapter->flags)) -			mod_timer(&adapter->watchdog_timer, jiffies); - -	if (napi_schedule_prep(&adapter->napi)) { - -		/* Disable interrupts and register for poll. The flush -		  of the posted write is intentionally left out. -		*/ - -		IXGB_WRITE_REG(&adapter->hw, IMC, ~0); -		__napi_schedule(&adapter->napi); -	} -	return IRQ_HANDLED; -} - -/** - * ixgb_clean - NAPI Rx polling callback - * @napi: napi struct pointer - * @budget: max number of receives to clean - **/ - -static int -ixgb_clean(struct napi_struct *napi, int budget) -{ -	struct ixgb_adapter *adapter = container_of(napi, struct ixgb_adapter, napi); -	int work_done = 0; - -	ixgb_clean_tx_irq(adapter); -	ixgb_clean_rx_irq(adapter, &work_done, budget); - -	/* If budget not fully consumed, exit the polling mode */ -	if (work_done < budget) { -		napi_complete_done(napi, work_done); -		if (!test_bit(__IXGB_DOWN, &adapter->flags)) -			ixgb_irq_enable(adapter); -	} - -	return work_done; -} - -/** - * ixgb_clean_tx_irq - Reclaim resources after transmit completes - * @adapter: board private structure - **/ - -static bool -ixgb_clean_tx_irq(struct ixgb_adapter *adapter) -{ -	struct ixgb_desc_ring *tx_ring = &adapter->tx_ring; -	struct net_device *netdev = adapter->netdev; -	struct ixgb_tx_desc *tx_desc, *eop_desc; -	struct ixgb_buffer *buffer_info; -	unsigned int i, eop; -	bool cleaned = false; - -	i = tx_ring->next_to_clean; -	eop = tx_ring->buffer_info[i].next_to_watch; -	eop_desc = IXGB_TX_DESC(*tx_ring, eop); - -	while (eop_desc->status & IXGB_TX_DESC_STATUS_DD) { - -		rmb(); /* read buffer_info after eop_desc */ -		for (cleaned = false; !cleaned; ) { -			tx_desc = IXGB_TX_DESC(*tx_ring, i); -			buffer_info = &tx_ring->buffer_info[i]; - -			if (tx_desc->popts & -			   (IXGB_TX_DESC_POPTS_TXSM | -			    IXGB_TX_DESC_POPTS_IXSM)) -				adapter->hw_csum_tx_good++; - -			ixgb_unmap_and_free_tx_resource(adapter, buffer_info); - -			*(u32 *)&(tx_desc->status) = 0; - -			cleaned = (i == eop); -			if (++i == tx_ring->count) i = 0; -		} - -		eop = tx_ring->buffer_info[i].next_to_watch; -		eop_desc = IXGB_TX_DESC(*tx_ring, eop); -	} - -	tx_ring->next_to_clean = i; - -	if (unlikely(cleaned && netif_carrier_ok(netdev) && -		     IXGB_DESC_UNUSED(tx_ring) >= DESC_NEEDED)) { -		/* Make sure that anybody stopping the queue after this -		 * sees the new next_to_clean. */ -		smp_mb(); - -		if (netif_queue_stopped(netdev) && -		    !(test_bit(__IXGB_DOWN, &adapter->flags))) { -			netif_wake_queue(netdev); -			++adapter->restart_queue; -		} -	} - -	if (adapter->detect_tx_hung) { -		/* detect a transmit hang in hardware, this serializes the -		 * check with the clearing of time_stamp and movement of i */ -		adapter->detect_tx_hung = false; -		if (tx_ring->buffer_info[eop].time_stamp && -		   time_after(jiffies, tx_ring->buffer_info[eop].time_stamp + HZ) -		   && !(IXGB_READ_REG(&adapter->hw, STATUS) & -		        IXGB_STATUS_TXOFF)) { -			/* detected Tx unit hang */ -			netif_err(adapter, drv, adapter->netdev, -				  "Detected Tx Unit Hang\n" -				  "  TDH                  <%x>\n" -				  "  TDT                  <%x>\n" -				  "  next_to_use          <%x>\n" -				  "  next_to_clean        <%x>\n" -				  "buffer_info[next_to_clean]\n" -				  "  time_stamp           <%lx>\n" -				  "  next_to_watch        <%x>\n" -				  "  jiffies              <%lx>\n" -				  "  next_to_watch.status <%x>\n", -				  IXGB_READ_REG(&adapter->hw, TDH), -				  IXGB_READ_REG(&adapter->hw, TDT), -				  tx_ring->next_to_use, -				  tx_ring->next_to_clean, -				  tx_ring->buffer_info[eop].time_stamp, -				  eop, -				  jiffies, -				  eop_desc->status); -			netif_stop_queue(netdev); -		} -	} - -	return cleaned; -} - -/** - * ixgb_rx_checksum - Receive Checksum Offload for 82597. - * @adapter: board private structure - * @rx_desc: receive descriptor - * @skb: socket buffer with received data - **/ - -static void -ixgb_rx_checksum(struct ixgb_adapter *adapter, -                 struct ixgb_rx_desc *rx_desc, -                 struct sk_buff *skb) -{ -	/* Ignore Checksum bit is set OR -	 * TCP Checksum has not been calculated -	 */ -	if ((rx_desc->status & IXGB_RX_DESC_STATUS_IXSM) || -	   (!(rx_desc->status & IXGB_RX_DESC_STATUS_TCPCS))) { -		skb_checksum_none_assert(skb); -		return; -	} - -	/* At this point we know the hardware did the TCP checksum */ -	/* now look at the TCP checksum error bit */ -	if (rx_desc->errors & IXGB_RX_DESC_ERRORS_TCPE) { -		/* let the stack verify checksum errors */ -		skb_checksum_none_assert(skb); -		adapter->hw_csum_rx_error++; -	} else { -		/* TCP checksum is good */ -		skb->ip_summed = CHECKSUM_UNNECESSARY; -		adapter->hw_csum_rx_good++; -	} -} - -/* - * this should improve performance for small packets with large amounts - * of reassembly being done in the stack - */ -static void ixgb_check_copybreak(struct napi_struct *napi, -				 struct ixgb_buffer *buffer_info, -				 u32 length, struct sk_buff **skb) -{ -	struct sk_buff *new_skb; - -	if (length > copybreak) -		return; - -	new_skb = napi_alloc_skb(napi, length); -	if (!new_skb) -		return; - -	skb_copy_to_linear_data_offset(new_skb, -NET_IP_ALIGN, -				       (*skb)->data - NET_IP_ALIGN, -				       length + NET_IP_ALIGN); -	/* save the skb in buffer_info as good */ -	buffer_info->skb = *skb; -	*skb = new_skb; -} - -/** - * ixgb_clean_rx_irq - Send received data up the network stack, - * @adapter: board private structure - * @work_done: output pointer to amount of packets cleaned - * @work_to_do: how much work we can complete - **/ - -static bool -ixgb_clean_rx_irq(struct ixgb_adapter *adapter, int *work_done, int work_to_do) -{ -	struct ixgb_desc_ring *rx_ring = &adapter->rx_ring; -	struct net_device *netdev = adapter->netdev; -	struct pci_dev *pdev = adapter->pdev; -	struct ixgb_rx_desc *rx_desc, *next_rxd; -	struct ixgb_buffer *buffer_info, *next_buffer, *next2_buffer; -	u32 length; -	unsigned int i, j; -	int cleaned_count = 0; -	bool cleaned = false; - -	i = rx_ring->next_to_clean; -	rx_desc = IXGB_RX_DESC(*rx_ring, i); -	buffer_info = &rx_ring->buffer_info[i]; - -	while (rx_desc->status & IXGB_RX_DESC_STATUS_DD) { -		struct sk_buff *skb; -		u8 status; - -		if (*work_done >= work_to_do) -			break; - -		(*work_done)++; -		rmb();	/* read descriptor and rx_buffer_info after status DD */ -		status = rx_desc->status; -		skb = buffer_info->skb; -		buffer_info->skb = NULL; - -		prefetch(skb->data - NET_IP_ALIGN); - -		if (++i == rx_ring->count) -			i = 0; -		next_rxd = IXGB_RX_DESC(*rx_ring, i); -		prefetch(next_rxd); - -		j = i + 1; -		if (j == rx_ring->count) -			j = 0; -		next2_buffer = &rx_ring->buffer_info[j]; -		prefetch(next2_buffer); - -		next_buffer = &rx_ring->buffer_info[i]; - -		cleaned = true; -		cleaned_count++; - -		dma_unmap_single(&pdev->dev, -				 buffer_info->dma, -				 buffer_info->length, -				 DMA_FROM_DEVICE); -		buffer_info->dma = 0; - -		length = le16_to_cpu(rx_desc->length); -		rx_desc->length = 0; - -		if (unlikely(!(status & IXGB_RX_DESC_STATUS_EOP))) { - -			/* All receives must fit into a single buffer */ - -			pr_debug("Receive packet consumed multiple buffers length<%x>\n", -				 length); - -			dev_kfree_skb_irq(skb); -			goto rxdesc_done; -		} - -		if (unlikely(rx_desc->errors & -		    (IXGB_RX_DESC_ERRORS_CE | IXGB_RX_DESC_ERRORS_SE | -		     IXGB_RX_DESC_ERRORS_P | IXGB_RX_DESC_ERRORS_RXE))) { -			dev_kfree_skb_irq(skb); -			goto rxdesc_done; -		} - -		ixgb_check_copybreak(&adapter->napi, buffer_info, length, &skb); - -		/* Good Receive */ -		skb_put(skb, length); - -		/* Receive Checksum Offload */ -		ixgb_rx_checksum(adapter, rx_desc, skb); - -		skb->protocol = eth_type_trans(skb, netdev); -		if (status & IXGB_RX_DESC_STATUS_VP) -			__vlan_hwaccel_put_tag(skb, htons(ETH_P_8021Q), -				       le16_to_cpu(rx_desc->special)); - -		netif_receive_skb(skb); - -rxdesc_done: -		/* clean up descriptor, might be written over by hw */ -		rx_desc->status = 0; - -		/* return some buffers to hardware, one at a time is too slow */ -		if (unlikely(cleaned_count >= IXGB_RX_BUFFER_WRITE)) { -			ixgb_alloc_rx_buffers(adapter, cleaned_count); -			cleaned_count = 0; -		} - -		/* use prefetched values */ -		rx_desc = next_rxd; -		buffer_info = next_buffer; -	} - -	rx_ring->next_to_clean = i; - -	cleaned_count = IXGB_DESC_UNUSED(rx_ring); -	if (cleaned_count) -		ixgb_alloc_rx_buffers(adapter, cleaned_count); - -	return cleaned; -} - -/** - * ixgb_alloc_rx_buffers - Replace used receive buffers - * @adapter: address of board private structure - * @cleaned_count: how many buffers to allocate - **/ - -static void -ixgb_alloc_rx_buffers(struct ixgb_adapter *adapter, int cleaned_count) -{ -	struct ixgb_desc_ring *rx_ring = &adapter->rx_ring; -	struct net_device *netdev = adapter->netdev; -	struct pci_dev *pdev = adapter->pdev; -	struct ixgb_rx_desc *rx_desc; -	struct ixgb_buffer *buffer_info; -	struct sk_buff *skb; -	unsigned int i; -	long cleancount; - -	i = rx_ring->next_to_use; -	buffer_info = &rx_ring->buffer_info[i]; -	cleancount = IXGB_DESC_UNUSED(rx_ring); - - -	/* leave three descriptors unused */ -	while (--cleancount > 2 && cleaned_count--) { -		/* recycle! its good for you */ -		skb = buffer_info->skb; -		if (skb) { -			skb_trim(skb, 0); -			goto map_skb; -		} - -		skb = netdev_alloc_skb_ip_align(netdev, adapter->rx_buffer_len); -		if (unlikely(!skb)) { -			/* Better luck next round */ -			adapter->alloc_rx_buff_failed++; -			break; -		} - -		buffer_info->skb = skb; -		buffer_info->length = adapter->rx_buffer_len; -map_skb: -		buffer_info->dma = dma_map_single(&pdev->dev, -		                                  skb->data, -		                                  adapter->rx_buffer_len, -						  DMA_FROM_DEVICE); -		if (dma_mapping_error(&pdev->dev, buffer_info->dma)) { -			adapter->alloc_rx_buff_failed++; -			break; -		} - -		rx_desc = IXGB_RX_DESC(*rx_ring, i); -		rx_desc->buff_addr = cpu_to_le64(buffer_info->dma); -		/* guarantee DD bit not set now before h/w gets descriptor -		 * this is the rest of the workaround for h/w double -		 * writeback. */ -		rx_desc->status = 0; - - -		if (++i == rx_ring->count) -			i = 0; -		buffer_info = &rx_ring->buffer_info[i]; -	} - -	if (likely(rx_ring->next_to_use != i)) { -		rx_ring->next_to_use = i; -		if (unlikely(i-- == 0)) -			i = (rx_ring->count - 1); - -		/* Force memory writes to complete before letting h/w -		 * know there are new descriptors to fetch.  (Only -		 * applicable for weak-ordered memory model archs, such -		 * as IA-64). */ -		wmb(); -		IXGB_WRITE_REG(&adapter->hw, RDT, i); -	} -} - -static void -ixgb_vlan_strip_enable(struct ixgb_adapter *adapter) -{ -	u32 ctrl; - -	/* enable VLAN tag insert/strip */ -	ctrl = IXGB_READ_REG(&adapter->hw, CTRL0); -	ctrl |= IXGB_CTRL0_VME; -	IXGB_WRITE_REG(&adapter->hw, CTRL0, ctrl); -} - -static void -ixgb_vlan_strip_disable(struct ixgb_adapter *adapter) -{ -	u32 ctrl; - -	/* disable VLAN tag insert/strip */ -	ctrl = IXGB_READ_REG(&adapter->hw, CTRL0); -	ctrl &= ~IXGB_CTRL0_VME; -	IXGB_WRITE_REG(&adapter->hw, CTRL0, ctrl); -} - -static int -ixgb_vlan_rx_add_vid(struct net_device *netdev, __be16 proto, u16 vid) -{ -	struct ixgb_adapter *adapter = netdev_priv(netdev); -	u32 vfta, index; - -	/* add VID to filter table */ - -	index = (vid >> 5) & 0x7F; -	vfta = IXGB_READ_REG_ARRAY(&adapter->hw, VFTA, index); -	vfta |= (1 << (vid & 0x1F)); -	ixgb_write_vfta(&adapter->hw, index, vfta); -	set_bit(vid, adapter->active_vlans); - -	return 0; -} - -static int -ixgb_vlan_rx_kill_vid(struct net_device *netdev, __be16 proto, u16 vid) -{ -	struct ixgb_adapter *adapter = netdev_priv(netdev); -	u32 vfta, index; - -	/* remove VID from filter table */ - -	index = (vid >> 5) & 0x7F; -	vfta = IXGB_READ_REG_ARRAY(&adapter->hw, VFTA, index); -	vfta &= ~(1 << (vid & 0x1F)); -	ixgb_write_vfta(&adapter->hw, index, vfta); -	clear_bit(vid, adapter->active_vlans); - -	return 0; -} - -static void -ixgb_restore_vlan(struct ixgb_adapter *adapter) -{ -	u16 vid; - -	for_each_set_bit(vid, adapter->active_vlans, VLAN_N_VID) -		ixgb_vlan_rx_add_vid(adapter->netdev, htons(ETH_P_8021Q), vid); -} - -/** - * ixgb_io_error_detected - called when PCI error is detected - * @pdev:    pointer to pci device with error - * @state:   pci channel state after error - * - * This callback is called by the PCI subsystem whenever - * a PCI bus error is detected. - */ -static pci_ers_result_t ixgb_io_error_detected(struct pci_dev *pdev, -                                               pci_channel_state_t state) -{ -	struct net_device *netdev = pci_get_drvdata(pdev); -	struct ixgb_adapter *adapter = netdev_priv(netdev); - -	netif_device_detach(netdev); - -	if (state == pci_channel_io_perm_failure) -		return PCI_ERS_RESULT_DISCONNECT; - -	if (netif_running(netdev)) -		ixgb_down(adapter, true); - -	pci_disable_device(pdev); - -	/* Request a slot reset. */ -	return PCI_ERS_RESULT_NEED_RESET; -} - -/** - * ixgb_io_slot_reset - called after the pci bus has been reset. - * @pdev: pointer to pci device with error - * - * This callback is called after the PCI bus has been reset. - * Basically, this tries to restart the card from scratch. - * This is a shortened version of the device probe/discovery code, - * it resembles the first-half of the ixgb_probe() routine. - */ -static pci_ers_result_t ixgb_io_slot_reset(struct pci_dev *pdev) -{ -	struct net_device *netdev = pci_get_drvdata(pdev); -	struct ixgb_adapter *adapter = netdev_priv(netdev); -	u8 addr[ETH_ALEN]; - -	if (pci_enable_device(pdev)) { -		netif_err(adapter, probe, adapter->netdev, -			  "Cannot re-enable PCI device after reset\n"); -		return PCI_ERS_RESULT_DISCONNECT; -	} - -	/* Perform card reset only on one instance of the card */ -	if (0 != PCI_FUNC (pdev->devfn)) -		return PCI_ERS_RESULT_RECOVERED; - -	pci_set_master(pdev); - -	netif_carrier_off(netdev); -	netif_stop_queue(netdev); -	ixgb_reset(adapter); - -	/* Make sure the EEPROM is good */ -	if (!ixgb_validate_eeprom_checksum(&adapter->hw)) { -		netif_err(adapter, probe, adapter->netdev, -			  "After reset, the EEPROM checksum is not valid\n"); -		return PCI_ERS_RESULT_DISCONNECT; -	} -	ixgb_get_ee_mac_addr(&adapter->hw, addr); -	eth_hw_addr_set(netdev, addr); -	memcpy(netdev->perm_addr, netdev->dev_addr, netdev->addr_len); - -	if (!is_valid_ether_addr(netdev->perm_addr)) { -		netif_err(adapter, probe, adapter->netdev, -			  "After reset, invalid MAC address\n"); -		return PCI_ERS_RESULT_DISCONNECT; -	} - -	return PCI_ERS_RESULT_RECOVERED; -} - -/** - * ixgb_io_resume - called when its OK to resume normal operations - * @pdev: pointer to pci device with error - * - * The error recovery driver tells us that its OK to resume - * normal operation. Implementation resembles the second-half - * of the ixgb_probe() routine. - */ -static void ixgb_io_resume(struct pci_dev *pdev) -{ -	struct net_device *netdev = pci_get_drvdata(pdev); -	struct ixgb_adapter *adapter = netdev_priv(netdev); - -	pci_set_master(pdev); - -	if (netif_running(netdev)) { -		if (ixgb_up(adapter)) { -			pr_err("can't bring device back up after reset\n"); -			return; -		} -	} - -	netif_device_attach(netdev); -	mod_timer(&adapter->watchdog_timer, jiffies); -} - -/* ixgb_main.c */ diff --git a/drivers/net/ethernet/intel/ixgb/ixgb_osdep.h b/drivers/net/ethernet/intel/ixgb/ixgb_osdep.h deleted file mode 100644 index 7bd54efa698d..000000000000 --- a/drivers/net/ethernet/intel/ixgb/ixgb_osdep.h +++ /dev/null @@ -1,39 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0 */ -/* Copyright(c) 1999 - 2008 Intel Corporation. */ - -/* glue for the OS independent part of ixgb - * includes register access macros - */ - -#ifndef _IXGB_OSDEP_H_ -#define _IXGB_OSDEP_H_ - -#include <linux/types.h> -#include <linux/delay.h> -#include <asm/io.h> -#include <linux/interrupt.h> -#include <linux/sched.h> -#include <linux/if_ether.h> - -#undef ASSERT -#define ASSERT(x)	BUG_ON(!(x)) - -#define ENTER() pr_debug("%s\n", __func__); - -#define IXGB_WRITE_REG(a, reg, value) ( \ -	writel((value), ((a)->hw_addr + IXGB_##reg))) - -#define IXGB_READ_REG(a, reg) ( \ -	readl((a)->hw_addr + IXGB_##reg)) - -#define IXGB_WRITE_REG_ARRAY(a, reg, offset, value) ( \ -	writel((value), ((a)->hw_addr + IXGB_##reg + ((offset) << 2)))) - -#define IXGB_READ_REG_ARRAY(a, reg, offset) ( \ -	readl((a)->hw_addr + IXGB_##reg + ((offset) << 2))) - -#define IXGB_WRITE_FLUSH(a) IXGB_READ_REG(a, STATUS) - -#define IXGB_MEMCPY memcpy - -#endif /* _IXGB_OSDEP_H_ */ diff --git a/drivers/net/ethernet/intel/ixgb/ixgb_param.c b/drivers/net/ethernet/intel/ixgb/ixgb_param.c deleted file mode 100644 index d40f96250691..000000000000 --- a/drivers/net/ethernet/intel/ixgb/ixgb_param.c +++ /dev/null @@ -1,442 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0 -/* Copyright(c) 1999 - 2008 Intel Corporation. */ - -#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt - -#include "ixgb.h" - -/* This is the only thing that needs to be changed to adjust the - * maximum number of ports that the driver can manage. - */ - -#define IXGB_MAX_NIC 8 - -#define OPTION_UNSET	-1 -#define OPTION_DISABLED 0 -#define OPTION_ENABLED  1 - -/* All parameters are treated the same, as an integer array of values. - * This macro just reduces the need to repeat the same declaration code - * over and over (plus this helps to avoid typo bugs). - */ - -#define IXGB_PARAM_INIT { [0 ... IXGB_MAX_NIC] = OPTION_UNSET } -#define IXGB_PARAM(X, desc)					\ -	static int X[IXGB_MAX_NIC+1]		\ -		= IXGB_PARAM_INIT;				\ -	static unsigned int num_##X = 0;			\ -	module_param_array_named(X, X, int, &num_##X, 0);	\ -	MODULE_PARM_DESC(X, desc); - -/* Transmit Descriptor Count - * - * Valid Range: 64-4096 - * - * Default Value: 256 - */ - -IXGB_PARAM(TxDescriptors, "Number of transmit descriptors"); - -/* Receive Descriptor Count - * - * Valid Range: 64-4096 - * - * Default Value: 1024 - */ - -IXGB_PARAM(RxDescriptors, "Number of receive descriptors"); - -/* User Specified Flow Control Override - * - * Valid Range: 0-3 - *  - 0 - No Flow Control - *  - 1 - Rx only, respond to PAUSE frames but do not generate them - *  - 2 - Tx only, generate PAUSE frames but ignore them on receive - *  - 3 - Full Flow Control Support - * - * Default Value: 2 - Tx only (silicon bug avoidance) - */ - -IXGB_PARAM(FlowControl, "Flow Control setting"); - -/* XsumRX - Receive Checksum Offload Enable/Disable - * - * Valid Range: 0, 1 - *  - 0 - disables all checksum offload - *  - 1 - enables receive IP/TCP/UDP checksum offload - *        on 82597 based NICs - * - * Default Value: 1 - */ - -IXGB_PARAM(XsumRX, "Disable or enable Receive Checksum offload"); - -/* Transmit Interrupt Delay in units of 0.8192 microseconds - * - * Valid Range: 0-65535 - * - * Default Value: 32 - */ - -IXGB_PARAM(TxIntDelay, "Transmit Interrupt Delay"); - -/* Receive Interrupt Delay in units of 0.8192 microseconds - * - * Valid Range: 0-65535 - * - * Default Value: 72 - */ - -IXGB_PARAM(RxIntDelay, "Receive Interrupt Delay"); - -/* Receive Flow control high threshold (when we send a pause frame) - * (FCRTH) - * - * Valid Range: 1,536 - 262,136 (0x600 - 0x3FFF8, 8 byte granularity) - * - * Default Value: 196,608 (0x30000) - */ - -IXGB_PARAM(RxFCHighThresh, "Receive Flow Control High Threshold"); - -/* Receive Flow control low threshold (when we send a resume frame) - * (FCRTL) - * - * Valid Range: 64 - 262,136 (0x40 - 0x3FFF8, 8 byte granularity) - *              must be less than high threshold by at least 8 bytes - * - * Default Value:  163,840 (0x28000) - */ - -IXGB_PARAM(RxFCLowThresh, "Receive Flow Control Low Threshold"); - -/* Flow control request timeout (how long to pause the link partner's tx) - * (PAP 15:0) - * - * Valid Range: 1 - 65535 - * - * Default Value:  65535 (0xffff) (we'll send an xon if we recover) - */ - -IXGB_PARAM(FCReqTimeout, "Flow Control Request Timeout"); - -/* Interrupt Delay Enable - * - * Valid Range: 0, 1 - * - *  - 0 - disables transmit interrupt delay - *  - 1 - enables transmmit interrupt delay - * - * Default Value: 1 - */ - -IXGB_PARAM(IntDelayEnable, "Transmit Interrupt Delay Enable"); - - -#define DEFAULT_TIDV	   		     32 -#define MAX_TIDV			 0xFFFF -#define MIN_TIDV			      0 - -#define DEFAULT_RDTR		   	     72 -#define MAX_RDTR			 0xFFFF -#define MIN_RDTR			      0 - -#define DEFAULT_FCRTL	  		0x28000 -#define DEFAULT_FCRTH			0x30000 -#define MIN_FCRTL			      0 -#define MAX_FCRTL			0x3FFE8 -#define MIN_FCRTH			      8 -#define MAX_FCRTH			0x3FFF0 - -#define MIN_FCPAUSE			      1 -#define MAX_FCPAUSE			 0xffff -#define DEFAULT_FCPAUSE		  	 0xFFFF /* this may be too long */ - -struct ixgb_option { -	enum { enable_option, range_option, list_option } type; -	const char *name; -	const char *err; -	int def; -	union { -		struct {	/* range_option info */ -			int min; -			int max; -		} r; -		struct {	/* list_option info */ -			int nr; -			const struct ixgb_opt_list { -				int i; -				const char *str; -			} *p; -		} l; -	} arg; -}; - -static int -ixgb_validate_option(unsigned int *value, const struct ixgb_option *opt) -{ -	if (*value == OPTION_UNSET) { -		*value = opt->def; -		return 0; -	} - -	switch (opt->type) { -	case enable_option: -		switch (*value) { -		case OPTION_ENABLED: -			pr_info("%s Enabled\n", opt->name); -			return 0; -		case OPTION_DISABLED: -			pr_info("%s Disabled\n", opt->name); -			return 0; -		} -		break; -	case range_option: -		if (*value >= opt->arg.r.min && *value <= opt->arg.r.max) { -			pr_info("%s set to %i\n", opt->name, *value); -			return 0; -		} -		break; -	case list_option: { -		int i; -		const struct ixgb_opt_list *ent; - -		for (i = 0; i < opt->arg.l.nr; i++) { -			ent = &opt->arg.l.p[i]; -			if (*value == ent->i) { -				if (ent->str[0] != '\0') -					pr_info("%s\n", ent->str); -				return 0; -			} -		} -	} -		break; -	default: -		BUG(); -	} - -	pr_info("Invalid %s specified (%i) %s\n", opt->name, *value, opt->err); -	*value = opt->def; -	return -1; -} - -/** - * ixgb_check_options - Range Checking for Command Line Parameters - * @adapter: board private structure - * - * This routine checks all command line parameters for valid user - * input.  If an invalid value is given, or if no user specified - * value exists, a default value is used.  The final value is stored - * in a variable in the adapter structure. - **/ - -void -ixgb_check_options(struct ixgb_adapter *adapter) -{ -	int bd = adapter->bd_number; -	if (bd >= IXGB_MAX_NIC) { -		pr_notice("Warning: no configuration for board #%i\n", bd); -		pr_notice("Using defaults for all values\n"); -	} - -	{ /* Transmit Descriptor Count */ -		static const struct ixgb_option opt = { -			.type = range_option, -			.name = "Transmit Descriptors", -			.err  = "using default of " __MODULE_STRING(DEFAULT_TXD), -			.def  = DEFAULT_TXD, -			.arg  = { .r = { .min = MIN_TXD, -					 .max = MAX_TXD}} -		}; -		struct ixgb_desc_ring *tx_ring = &adapter->tx_ring; - -		if (num_TxDescriptors > bd) { -			tx_ring->count = TxDescriptors[bd]; -			ixgb_validate_option(&tx_ring->count, &opt); -		} else { -			tx_ring->count = opt.def; -		} -		tx_ring->count = ALIGN(tx_ring->count, IXGB_REQ_TX_DESCRIPTOR_MULTIPLE); -	} -	{ /* Receive Descriptor Count */ -		static const struct ixgb_option opt = { -			.type = range_option, -			.name = "Receive Descriptors", -			.err  = "using default of " __MODULE_STRING(DEFAULT_RXD), -			.def  = DEFAULT_RXD, -			.arg  = { .r = { .min = MIN_RXD, -					 .max = MAX_RXD}} -		}; -		struct ixgb_desc_ring *rx_ring = &adapter->rx_ring; - -		if (num_RxDescriptors > bd) { -			rx_ring->count = RxDescriptors[bd]; -			ixgb_validate_option(&rx_ring->count, &opt); -		} else { -			rx_ring->count = opt.def; -		} -		rx_ring->count = ALIGN(rx_ring->count, IXGB_REQ_RX_DESCRIPTOR_MULTIPLE); -	} -	{ /* Receive Checksum Offload Enable */ -		static const struct ixgb_option opt = { -			.type = enable_option, -			.name = "Receive Checksum Offload", -			.err  = "defaulting to Enabled", -			.def  = OPTION_ENABLED -		}; - -		if (num_XsumRX > bd) { -			unsigned int rx_csum = XsumRX[bd]; -			ixgb_validate_option(&rx_csum, &opt); -			adapter->rx_csum = rx_csum; -		} else { -			adapter->rx_csum = opt.def; -		} -	} -	{ /* Flow Control */ - -		static const struct ixgb_opt_list fc_list[] = { -		       { ixgb_fc_none, "Flow Control Disabled" }, -		       { ixgb_fc_rx_pause, "Flow Control Receive Only" }, -		       { ixgb_fc_tx_pause, "Flow Control Transmit Only" }, -		       { ixgb_fc_full, "Flow Control Enabled" }, -		       { ixgb_fc_default, "Flow Control Hardware Default" } -		}; - -		static const struct ixgb_option opt = { -			.type = list_option, -			.name = "Flow Control", -			.err  = "reading default settings from EEPROM", -			.def  = ixgb_fc_tx_pause, -			.arg  = { .l = { .nr = ARRAY_SIZE(fc_list), -					 .p = fc_list }} -		}; - -		if (num_FlowControl > bd) { -			unsigned int fc = FlowControl[bd]; -			ixgb_validate_option(&fc, &opt); -			adapter->hw.fc.type = fc; -		} else { -			adapter->hw.fc.type = opt.def; -		} -	} -	{ /* Receive Flow Control High Threshold */ -		static const struct ixgb_option opt = { -			.type = range_option, -			.name = "Rx Flow Control High Threshold", -			.err  = "using default of " __MODULE_STRING(DEFAULT_FCRTH), -			.def  = DEFAULT_FCRTH, -			.arg  = { .r = { .min = MIN_FCRTH, -					 .max = MAX_FCRTH}} -		}; - -		if (num_RxFCHighThresh > bd) { -			adapter->hw.fc.high_water = RxFCHighThresh[bd]; -			ixgb_validate_option(&adapter->hw.fc.high_water, &opt); -		} else { -			adapter->hw.fc.high_water = opt.def; -		} -		if (!(adapter->hw.fc.type & ixgb_fc_tx_pause) ) -			pr_info("Ignoring RxFCHighThresh when no RxFC\n"); -	} -	{ /* Receive Flow Control Low Threshold */ -		static const struct ixgb_option opt = { -			.type = range_option, -			.name = "Rx Flow Control Low Threshold", -			.err  = "using default of " __MODULE_STRING(DEFAULT_FCRTL), -			.def  = DEFAULT_FCRTL, -			.arg  = { .r = { .min = MIN_FCRTL, -					 .max = MAX_FCRTL}} -		}; - -		if (num_RxFCLowThresh > bd) { -			adapter->hw.fc.low_water = RxFCLowThresh[bd]; -			ixgb_validate_option(&adapter->hw.fc.low_water, &opt); -		} else { -			adapter->hw.fc.low_water = opt.def; -		} -		if (!(adapter->hw.fc.type & ixgb_fc_tx_pause) ) -			pr_info("Ignoring RxFCLowThresh when no RxFC\n"); -	} -	{ /* Flow Control Pause Time Request*/ -		static const struct ixgb_option opt = { -			.type = range_option, -			.name = "Flow Control Pause Time Request", -			.err  = "using default of "__MODULE_STRING(DEFAULT_FCPAUSE), -			.def  = DEFAULT_FCPAUSE, -			.arg = { .r = { .min = MIN_FCPAUSE, -					.max = MAX_FCPAUSE}} -		}; - -		if (num_FCReqTimeout > bd) { -			unsigned int pause_time = FCReqTimeout[bd]; -			ixgb_validate_option(&pause_time, &opt); -			adapter->hw.fc.pause_time = pause_time; -		} else { -			adapter->hw.fc.pause_time = opt.def; -		} -		if (!(adapter->hw.fc.type & ixgb_fc_tx_pause) ) -			pr_info("Ignoring FCReqTimeout when no RxFC\n"); -	} -	/* high low and spacing check for rx flow control thresholds */ -	if (adapter->hw.fc.type & ixgb_fc_tx_pause) { -		/* high must be greater than low */ -		if (adapter->hw.fc.high_water < (adapter->hw.fc.low_water + 8)) { -			/* set defaults */ -			pr_info("RxFCHighThresh must be >= (RxFCLowThresh + 8), Using Defaults\n"); -			adapter->hw.fc.high_water = DEFAULT_FCRTH; -			adapter->hw.fc.low_water  = DEFAULT_FCRTL; -		} -	} -	{ /* Receive Interrupt Delay */ -		static const struct ixgb_option opt = { -			.type = range_option, -			.name = "Receive Interrupt Delay", -			.err  = "using default of " __MODULE_STRING(DEFAULT_RDTR), -			.def  = DEFAULT_RDTR, -			.arg  = { .r = { .min = MIN_RDTR, -					 .max = MAX_RDTR}} -		}; - -		if (num_RxIntDelay > bd) { -			adapter->rx_int_delay = RxIntDelay[bd]; -			ixgb_validate_option(&adapter->rx_int_delay, &opt); -		} else { -			adapter->rx_int_delay = opt.def; -		} -	} -	{ /* Transmit Interrupt Delay */ -		static const struct ixgb_option opt = { -			.type = range_option, -			.name = "Transmit Interrupt Delay", -			.err  = "using default of " __MODULE_STRING(DEFAULT_TIDV), -			.def  = DEFAULT_TIDV, -			.arg  = { .r = { .min = MIN_TIDV, -					 .max = MAX_TIDV}} -		}; - -		if (num_TxIntDelay > bd) { -			adapter->tx_int_delay = TxIntDelay[bd]; -			ixgb_validate_option(&adapter->tx_int_delay, &opt); -		} else { -			adapter->tx_int_delay = opt.def; -		} -	} - -	{ /* Transmit Interrupt Delay Enable */ -		static const struct ixgb_option opt = { -			.type = enable_option, -			.name = "Tx Interrupt Delay Enable", -			.err  = "defaulting to Enabled", -			.def  = OPTION_ENABLED -		}; - -		if (num_IntDelayEnable > bd) { -			unsigned int ide = IntDelayEnable[bd]; -			ixgb_validate_option(&ide, &opt); -			adapter->tx_int_delay_enable = ide; -		} else { -			adapter->tx_int_delay_enable = opt.def; -		} -	} -} diff --git a/drivers/net/ethernet/intel/ixgbe/ixgbe.h b/drivers/net/ethernet/intel/ixgbe/ixgbe.h index 8736ca4b2628..63d4e32df029 100644 --- a/drivers/net/ethernet/intel/ixgbe/ixgbe.h +++ b/drivers/net/ethernet/intel/ixgbe/ixgbe.h @@ -9,7 +9,6 @@  #include <linux/pci.h>  #include <linux/netdevice.h>  #include <linux/cpumask.h> -#include <linux/aer.h>  #include <linux/if_vlan.h>  #include <linux/jiffies.h>  #include <linux/phy.h> diff --git a/drivers/net/ethernet/intel/ixgbe/ixgbe_ethtool.c b/drivers/net/ethernet/intel/ixgbe/ixgbe_ethtool.c index 6cfc9dc16537..0bbad4a5cc2f 100644 --- a/drivers/net/ethernet/intel/ixgbe/ixgbe_ethtool.c +++ b/drivers/net/ethernet/intel/ixgbe/ixgbe_ethtool.c @@ -2665,6 +2665,14 @@ static int ixgbe_get_rss_hash_opts(struct ixgbe_adapter *adapter,  	return 0;  } +static int ixgbe_rss_indir_tbl_max(struct ixgbe_adapter *adapter) +{ +	if (adapter->hw.mac.type < ixgbe_mac_X550) +		return 16; +	else +		return 64; +} +  static int ixgbe_get_rxnfc(struct net_device *dev, struct ethtool_rxnfc *cmd,  			   u32 *rule_locs)  { @@ -2673,7 +2681,8 @@ static int ixgbe_get_rxnfc(struct net_device *dev, struct ethtool_rxnfc *cmd,  	switch (cmd->cmd) {  	case ETHTOOL_GRXRINGS: -		cmd->data = adapter->num_rx_queues; +		cmd->data = min_t(int, adapter->num_rx_queues, +				  ixgbe_rss_indir_tbl_max(adapter));  		ret = 0;  		break;  	case ETHTOOL_GRXCLSRLCNT: @@ -3075,14 +3084,6 @@ static int ixgbe_set_rxnfc(struct net_device *dev, struct ethtool_rxnfc *cmd)  	return ret;  } -static int ixgbe_rss_indir_tbl_max(struct ixgbe_adapter *adapter) -{ -	if (adapter->hw.mac.type < ixgbe_mac_X550) -		return 16; -	else -		return 64; -} -  static u32 ixgbe_get_rxfh_key_size(struct net_device *netdev)  {  	return IXGBE_RSS_KEY_SIZE; @@ -3131,8 +3132,8 @@ static int ixgbe_set_rxfh(struct net_device *netdev, const u32 *indir,  	int i;  	u32 reta_entries = ixgbe_rss_indir_tbl_entries(adapter); -	if (hfunc) -		return -EINVAL; +	if (hfunc != ETH_RSS_HASH_NO_CHANGE && hfunc != ETH_RSS_HASH_TOP) +		return -EOPNOTSUPP;  	/* Fill out the redirection table */  	if (indir) { diff --git a/drivers/net/ethernet/intel/ixgbe/ixgbe_lib.c b/drivers/net/ethernet/intel/ixgbe/ixgbe_lib.c index f8156fe4b1dc..0ee943db3dc9 100644 --- a/drivers/net/ethernet/intel/ixgbe/ixgbe_lib.c +++ b/drivers/net/ethernet/intel/ixgbe/ixgbe_lib.c @@ -1035,9 +1035,6 @@ static void ixgbe_free_q_vector(struct ixgbe_adapter *adapter, int v_idx)  	adapter->q_vector[v_idx] = NULL;  	__netif_napi_del(&q_vector->napi); -	if (static_key_enabled(&ixgbe_xdp_locking_key)) -		static_branch_dec(&ixgbe_xdp_locking_key); -  	/*  	 * after a call to __netif_napi_del() napi may still be used and  	 * ixgbe_get_stats64() might access the rings on this vector, diff --git a/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c b/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c index 773c35fecace..1726297f2e0d 100644 --- a/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c +++ b/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c @@ -36,6 +36,7 @@  #include <net/tc_act/tc_mirred.h>  #include <net/vxlan.h>  #include <net/mpls.h> +#include <net/netdev_queues.h>  #include <net/xdp_sock_drv.h>  #include <net/xfrm.h> @@ -1119,6 +1120,7 @@ static bool ixgbe_clean_tx_irq(struct ixgbe_q_vector *q_vector,  	unsigned int total_bytes = 0, total_packets = 0, total_ipsec = 0;  	unsigned int budget = q_vector->tx.work_limit;  	unsigned int i = tx_ring->next_to_clean; +	struct netdev_queue *txq;  	if (test_bit(__IXGBE_DOWN, &adapter->state))  		return true; @@ -1249,24 +1251,14 @@ static bool ixgbe_clean_tx_irq(struct ixgbe_q_vector *q_vector,  	if (ring_is_xdp(tx_ring))  		return !!budget; -	netdev_tx_completed_queue(txring_txq(tx_ring), -				  total_packets, total_bytes); -  #define TX_WAKE_THRESHOLD (DESC_NEEDED * 2) -	if (unlikely(total_packets && netif_carrier_ok(tx_ring->netdev) && -		     (ixgbe_desc_unused(tx_ring) >= TX_WAKE_THRESHOLD))) { -		/* Make sure that anybody stopping the queue after this -		 * sees the new next_to_clean. -		 */ -		smp_mb(); -		if (__netif_subqueue_stopped(tx_ring->netdev, -					     tx_ring->queue_index) -		    && !test_bit(__IXGBE_DOWN, &adapter->state)) { -			netif_wake_subqueue(tx_ring->netdev, -					    tx_ring->queue_index); -			++tx_ring->tx_stats.restart_queue; -		} -	} +	txq = netdev_get_tx_queue(tx_ring->netdev, tx_ring->queue_index); +	if (!__netif_txq_completed_wake(txq, total_packets, total_bytes, +					ixgbe_desc_unused(tx_ring), +					TX_WAKE_THRESHOLD, +					!netif_carrier_ok(tx_ring->netdev) || +					test_bit(__IXGBE_DOWN, &adapter->state))) +		++tx_ring->tx_stats.restart_queue;  	return !!budget;  } @@ -6495,6 +6487,10 @@ static int ixgbe_sw_init(struct ixgbe_adapter *adapter,  	set_bit(0, adapter->fwd_bitmask);  	set_bit(__IXGBE_DOWN, &adapter->state); +	/* enable locking for XDP_TX if we have more CPUs than queues */ +	if (nr_cpu_ids > IXGBE_MAX_XDP_QS) +		static_branch_enable(&ixgbe_xdp_locking_key); +  	return 0;  } @@ -8270,22 +8266,10 @@ static void ixgbe_tx_olinfo_status(union ixgbe_adv_tx_desc *tx_desc,  static int __ixgbe_maybe_stop_tx(struct ixgbe_ring *tx_ring, u16 size)  { -	netif_stop_subqueue(tx_ring->netdev, tx_ring->queue_index); - -	/* Herbert's original patch had: -	 *  smp_mb__after_netif_stop_queue(); -	 * but since that doesn't exist yet, just open code it. -	 */ -	smp_mb(); - -	/* We need to check again in a case another CPU has just -	 * made room available. -	 */ -	if (likely(ixgbe_desc_unused(tx_ring) < size)) +	if (!netif_subqueue_try_stop(tx_ring->netdev, tx_ring->queue_index, +				     ixgbe_desc_unused(tx_ring), size))  		return -EBUSY; -	/* A reprieve! - use start_queue because it doesn't call schedule */ -	netif_start_subqueue(tx_ring->netdev, tx_ring->queue_index);  	++tx_ring->tx_stats.restart_queue;  	return 0;  } @@ -8818,7 +8802,7 @@ netdev_tx_t ixgbe_xmit_frame_ring(struct sk_buff *skb,  			if (skb_cow_head(skb, 0))  				goto out_drop; -			vhdr = (struct vlan_ethhdr *)skb->data; +			vhdr = skb_vlan_eth_hdr(skb);  			vhdr->h_vlan_TCI = htons(tx_flags >>  						 IXGBE_TX_FLAGS_VLAN_SHIFT);  		} else { @@ -10290,8 +10274,6 @@ static int ixgbe_xdp_setup(struct net_device *dev, struct bpf_prog *prog)  	 */  	if (nr_cpu_ids > IXGBE_MAX_XDP_QS * 2)  		return -ENOMEM; -	else if (nr_cpu_ids > IXGBE_MAX_XDP_QS) -		static_branch_inc(&ixgbe_xdp_locking_key);  	old_prog = xchg(&adapter->xdp_prog, prog);  	need_reset = (!!prog != !!old_prog);  |