diff options
Diffstat (limited to 'drivers/net/ethernet/intel/ice')
| -rw-r--r-- | drivers/net/ethernet/intel/ice/ice.h | 4 | ||||
| -rw-r--r-- | drivers/net/ethernet/intel/ice/ice_common.c | 3 | ||||
| -rw-r--r-- | drivers/net/ethernet/intel/ice/ice_ethtool.c | 7 | ||||
| -rw-r--r-- | drivers/net/ethernet/intel/ice/ice_hw_autogen.h | 2 | ||||
| -rw-r--r-- | drivers/net/ethernet/intel/ice/ice_lib.c | 3 | ||||
| -rw-r--r-- | drivers/net/ethernet/intel/ice/ice_main.c | 86 | ||||
| -rw-r--r-- | drivers/net/ethernet/intel/ice/ice_switch.c | 12 | ||||
| -rw-r--r-- | drivers/net/ethernet/intel/ice/ice_switch.h | 2 | ||||
| -rw-r--r-- | drivers/net/ethernet/intel/ice/ice_txrx.c | 11 | ||||
| -rw-r--r-- | drivers/net/ethernet/intel/ice/ice_txrx.h | 17 | ||||
| -rw-r--r-- | drivers/net/ethernet/intel/ice/ice_type.h | 2 | ||||
| -rw-r--r-- | drivers/net/ethernet/intel/ice/ice_virtchnl_pf.c | 4 | 
12 files changed, 101 insertions, 52 deletions
| diff --git a/drivers/net/ethernet/intel/ice/ice.h b/drivers/net/ethernet/intel/ice/ice.h index 4c4b5717a627..b8548370f1c7 100644 --- a/drivers/net/ethernet/intel/ice/ice.h +++ b/drivers/net/ethernet/intel/ice/ice.h @@ -76,6 +76,8 @@ extern const char ice_drv_ver[];  #define ICE_MIN_INTR_PER_VF		(ICE_MIN_QS_PER_VF + 1)  #define ICE_DFLT_INTR_PER_VF		(ICE_DFLT_QS_PER_VF + 1) +#define ICE_MAX_RESET_WAIT		20 +  #define ICE_VSIQF_HKEY_ARRAY_SIZE	((VSIQF_HKEY_MAX_INDEX + 1) *	4)  #define ICE_DFLT_NETIF_M (NETIF_MSG_DRV | NETIF_MSG_PROBE | NETIF_MSG_LINK) @@ -189,7 +191,6 @@ struct ice_vsi {  	u64 tx_linearize;  	DECLARE_BITMAP(state, __ICE_STATE_NBITS);  	DECLARE_BITMAP(flags, ICE_VSI_FLAG_NBITS); -	unsigned long active_vlans[BITS_TO_LONGS(VLAN_N_VID)];  	unsigned int current_netdev_flags;  	u32 tx_restart;  	u32 tx_busy; @@ -369,5 +370,6 @@ int ice_set_rss(struct ice_vsi *vsi, u8 *seed, u8 *lut, u16 lut_size);  int ice_get_rss(struct ice_vsi *vsi, u8 *seed, u8 *lut, u16 lut_size);  void ice_fill_rss_lut(u8 *lut, u16 rss_table_size, u16 rss_size);  void ice_print_link_msg(struct ice_vsi *vsi, bool isup); +void ice_napi_del(struct ice_vsi *vsi);  #endif /* _ICE_H_ */ diff --git a/drivers/net/ethernet/intel/ice/ice_common.c b/drivers/net/ethernet/intel/ice/ice_common.c index 8cd6a2401fd9..554fd707a6d6 100644 --- a/drivers/net/ethernet/intel/ice/ice_common.c +++ b/drivers/net/ethernet/intel/ice/ice_common.c @@ -811,6 +811,9 @@ void ice_deinit_hw(struct ice_hw *hw)  	/* Attempt to disable FW logging before shutting down control queues */  	ice_cfg_fw_log(hw, false);  	ice_shutdown_all_ctrlq(hw); + +	/* Clear VSI contexts if not already cleared */ +	ice_clear_all_vsi_ctx(hw);  }  /** diff --git a/drivers/net/ethernet/intel/ice/ice_ethtool.c b/drivers/net/ethernet/intel/ice/ice_ethtool.c index 96923580f2a6..648acdb4c644 100644 --- a/drivers/net/ethernet/intel/ice/ice_ethtool.c +++ b/drivers/net/ethernet/intel/ice/ice_ethtool.c @@ -1517,10 +1517,15 @@ ice_set_pauseparam(struct net_device *netdev, struct ethtool_pauseparam *pause)  	}  	if (!test_bit(__ICE_DOWN, pf->state)) { -		/* Give it a little more time to try to come back */ +		/* Give it a little more time to try to come back. If still +		 * down, restart autoneg link or reinitialize the interface. +		 */  		msleep(75);  		if (!test_bit(__ICE_DOWN, pf->state))  			return ice_nway_reset(netdev); + +		ice_down(vsi); +		ice_up(vsi);  	}  	return err; diff --git a/drivers/net/ethernet/intel/ice/ice_hw_autogen.h b/drivers/net/ethernet/intel/ice/ice_hw_autogen.h index 5fdea6ec7675..596b9fb1c510 100644 --- a/drivers/net/ethernet/intel/ice/ice_hw_autogen.h +++ b/drivers/net/ethernet/intel/ice/ice_hw_autogen.h @@ -242,6 +242,8 @@  #define GLNVM_ULD				0x000B6008  #define GLNVM_ULD_CORER_DONE_M			BIT(3)  #define GLNVM_ULD_GLOBR_DONE_M			BIT(4) +#define GLPCI_CNF2				0x000BE004 +#define GLPCI_CNF2_CACHELINE_SIZE_M		BIT(1)  #define PF_FUNC_RID				0x0009E880  #define PF_FUNC_RID_FUNC_NUM_S			0  #define PF_FUNC_RID_FUNC_NUM_M			ICE_M(0x7, 0) diff --git a/drivers/net/ethernet/intel/ice/ice_lib.c b/drivers/net/ethernet/intel/ice/ice_lib.c index 5bacad01f0c9..1041fa2a7767 100644 --- a/drivers/net/ethernet/intel/ice/ice_lib.c +++ b/drivers/net/ethernet/intel/ice/ice_lib.c @@ -1997,7 +1997,7 @@ int ice_cfg_vlan_pruning(struct ice_vsi *vsi, bool ena)  	status = ice_update_vsi(&vsi->back->hw, vsi->idx, ctxt, NULL);  	if (status) {  		netdev_err(vsi->netdev, "%sabling VLAN pruning on VSI handle: %d, VSI HW ID: %d failed, err = %d, aq_err = %d\n", -			   ena ? "Ena" : "Dis", vsi->idx, vsi->vsi_num, status, +			   ena ? "En" : "Dis", vsi->idx, vsi->vsi_num, status,  			   vsi->back->hw.adminq.sq_last_status);  		goto err_out;  	} @@ -2458,6 +2458,7 @@ int ice_vsi_release(struct ice_vsi *vsi)  	 * on this wq  	 */  	if (vsi->netdev && !ice_is_reset_in_progress(pf->state)) { +		ice_napi_del(vsi);  		unregister_netdev(vsi->netdev);  		free_netdev(vsi->netdev);  		vsi->netdev = NULL; diff --git a/drivers/net/ethernet/intel/ice/ice_main.c b/drivers/net/ethernet/intel/ice/ice_main.c index 05993451147a..333312a1d595 100644 --- a/drivers/net/ethernet/intel/ice/ice_main.c +++ b/drivers/net/ethernet/intel/ice/ice_main.c @@ -1465,7 +1465,7 @@ skip_req_irq:   * ice_napi_del - Remove NAPI handler for the VSI   * @vsi: VSI for which NAPI handler is to be removed   */ -static void ice_napi_del(struct ice_vsi *vsi) +void ice_napi_del(struct ice_vsi *vsi)  {  	int v_idx; @@ -1622,7 +1622,6 @@ static int ice_vlan_rx_add_vid(struct net_device *netdev,  {  	struct ice_netdev_priv *np = netdev_priv(netdev);  	struct ice_vsi *vsi = np->vsi; -	int ret;  	if (vid >= VLAN_N_VID) {  		netdev_err(netdev, "VLAN id requested %d is out of range %d\n", @@ -1635,7 +1634,8 @@ static int ice_vlan_rx_add_vid(struct net_device *netdev,  	/* Enable VLAN pruning when VLAN 0 is added */  	if (unlikely(!vid)) { -		ret = ice_cfg_vlan_pruning(vsi, true); +		int ret = ice_cfg_vlan_pruning(vsi, true); +  		if (ret)  			return ret;  	} @@ -1644,12 +1644,7 @@ static int ice_vlan_rx_add_vid(struct net_device *netdev,  	 * needed to continue allowing all untagged packets since VLAN prune  	 * list is applied to all packets by the switch  	 */ -	ret = ice_vsi_add_vlan(vsi, vid); - -	if (!ret) -		set_bit(vid, vsi->active_vlans); - -	return ret; +	return ice_vsi_add_vlan(vsi, vid);  }  /** @@ -1677,8 +1672,6 @@ static int ice_vlan_rx_kill_vid(struct net_device *netdev,  	if (status)  		return status; -	clear_bit(vid, vsi->active_vlans); -  	/* Disable VLAN pruning when VLAN 0 is removed */  	if (unlikely(!vid))  		status = ice_cfg_vlan_pruning(vsi, false); @@ -2002,6 +1995,22 @@ static int ice_init_interrupt_scheme(struct ice_pf *pf)  }  /** + * ice_verify_cacheline_size - verify driver's assumption of 64 Byte cache lines + * @pf: pointer to the PF structure + * + * There is no error returned here because the driver should be able to handle + * 128 Byte cache lines, so we only print a warning in case issues are seen, + * specifically with Tx. + */ +static void ice_verify_cacheline_size(struct ice_pf *pf) +{ +	if (rd32(&pf->hw, GLPCI_CNF2) & GLPCI_CNF2_CACHELINE_SIZE_M) +		dev_warn(&pf->pdev->dev, +			 "%d Byte cache line assumption is invalid, driver may have Tx timeouts!\n", +			 ICE_CACHE_LINE_BYTES); +} + +/**   * ice_probe - Device initialization routine   * @pdev: PCI device information struct   * @ent: entry in ice_pci_tbl @@ -2151,6 +2160,8 @@ static int ice_probe(struct pci_dev *pdev,  	/* since everything is good, start the service timer */  	mod_timer(&pf->serv_tmr, round_jiffies(jiffies + pf->serv_tmr_period)); +	ice_verify_cacheline_size(pf); +  	return 0;  err_alloc_sw_unroll: @@ -2182,6 +2193,12 @@ static void ice_remove(struct pci_dev *pdev)  	if (!pf)  		return; +	for (i = 0; i < ICE_MAX_RESET_WAIT; i++) { +		if (!ice_is_reset_in_progress(pf->state)) +			break; +		msleep(100); +	} +  	set_bit(__ICE_DOWN, pf->state);  	ice_service_task_stop(pf); @@ -2510,31 +2527,6 @@ static int ice_vsi_vlan_setup(struct ice_vsi *vsi)  }  /** - * ice_restore_vlan - Reinstate VLANs when vsi/netdev comes back up - * @vsi: the VSI being brought back up - */ -static int ice_restore_vlan(struct ice_vsi *vsi) -{ -	int err; -	u16 vid; - -	if (!vsi->netdev) -		return -EINVAL; - -	err = ice_vsi_vlan_setup(vsi); -	if (err) -		return err; - -	for_each_set_bit(vid, vsi->active_vlans, VLAN_N_VID) { -		err = ice_vlan_rx_add_vid(vsi->netdev, htons(ETH_P_8021Q), vid); -		if (err) -			break; -	} - -	return err; -} - -/**   * ice_vsi_cfg - Setup the VSI   * @vsi: the VSI being configured   * @@ -2546,7 +2538,9 @@ static int ice_vsi_cfg(struct ice_vsi *vsi)  	if (vsi->netdev) {  		ice_set_rx_mode(vsi->netdev); -		err = ice_restore_vlan(vsi); + +		err = ice_vsi_vlan_setup(vsi); +  		if (err)  			return err;  	} @@ -3296,7 +3290,7 @@ static void ice_rebuild(struct ice_pf *pf)  	struct device *dev = &pf->pdev->dev;  	struct ice_hw *hw = &pf->hw;  	enum ice_status ret; -	int err; +	int err, i;  	if (test_bit(__ICE_DOWN, pf->state))  		goto clear_recovery; @@ -3370,6 +3364,22 @@ static void ice_rebuild(struct ice_pf *pf)  	}  	ice_reset_all_vfs(pf, true); + +	for (i = 0; i < pf->num_alloc_vsi; i++) { +		bool link_up; + +		if (!pf->vsi[i] || pf->vsi[i]->type != ICE_VSI_PF) +			continue; +		ice_get_link_status(pf->vsi[i]->port_info, &link_up); +		if (link_up) { +			netif_carrier_on(pf->vsi[i]->netdev); +			netif_tx_wake_all_queues(pf->vsi[i]->netdev); +		} else { +			netif_carrier_off(pf->vsi[i]->netdev); +			netif_tx_stop_all_queues(pf->vsi[i]->netdev); +		} +	} +  	/* if we get here, reset flow is successful */  	clear_bit(__ICE_RESET_FAILED, pf->state);  	return; diff --git a/drivers/net/ethernet/intel/ice/ice_switch.c b/drivers/net/ethernet/intel/ice/ice_switch.c index 33403f39f1b3..40c9c6558956 100644 --- a/drivers/net/ethernet/intel/ice/ice_switch.c +++ b/drivers/net/ethernet/intel/ice/ice_switch.c @@ -348,6 +348,18 @@ static void ice_clear_vsi_ctx(struct ice_hw *hw, u16 vsi_handle)  }  /** + * ice_clear_all_vsi_ctx - clear all the VSI context entries + * @hw: pointer to the hw struct + */ +void ice_clear_all_vsi_ctx(struct ice_hw *hw) +{ +	u16 i; + +	for (i = 0; i < ICE_MAX_VSI; i++) +		ice_clear_vsi_ctx(hw, i); +} + +/**   * ice_add_vsi - add VSI context to the hardware and VSI handle list   * @hw: pointer to the hw struct   * @vsi_handle: unique VSI handle provided by drivers diff --git a/drivers/net/ethernet/intel/ice/ice_switch.h b/drivers/net/ethernet/intel/ice/ice_switch.h index b88d96a1ef69..d5ef0bd58bf9 100644 --- a/drivers/net/ethernet/intel/ice/ice_switch.h +++ b/drivers/net/ethernet/intel/ice/ice_switch.h @@ -190,6 +190,8 @@ ice_update_vsi(struct ice_hw *hw, u16 vsi_handle, struct ice_vsi_ctx *vsi_ctx,  	       struct ice_sq_cd *cd);  bool ice_is_vsi_valid(struct ice_hw *hw, u16 vsi_handle);  struct ice_vsi_ctx *ice_get_vsi_ctx(struct ice_hw *hw, u16 vsi_handle); +void ice_clear_all_vsi_ctx(struct ice_hw *hw); +/* Switch config */  enum ice_status ice_get_initial_sw_cfg(struct ice_hw *hw);  /* Switch/bridge related commands */ diff --git a/drivers/net/ethernet/intel/ice/ice_txrx.c b/drivers/net/ethernet/intel/ice/ice_txrx.c index 5dae968d853e..fe5bbabbb41e 100644 --- a/drivers/net/ethernet/intel/ice/ice_txrx.c +++ b/drivers/net/ethernet/intel/ice/ice_txrx.c @@ -1520,7 +1520,7 @@ int ice_tso(struct ice_tx_buf *first, struct ice_tx_offload_params *off)  	/* update gso_segs and bytecount */  	first->gso_segs = skb_shinfo(skb)->gso_segs; -	first->bytecount = (first->gso_segs - 1) * off->header_len; +	first->bytecount += (first->gso_segs - 1) * off->header_len;  	cd_tso_len = skb->len - off->header_len;  	cd_mss = skb_shinfo(skb)->gso_size; @@ -1556,15 +1556,15 @@ int ice_tso(struct ice_tx_buf *first, struct ice_tx_offload_params *off)   * magnitude greater than our largest possible GSO size.   *   * This would then be implemented as: - *     return (((size >> 12) * 85) >> 8) + 1; + *     return (((size >> 12) * 85) >> 8) + ICE_DESCS_FOR_SKB_DATA_PTR;   *   * Since multiplication and division are commutative, we can reorder   * operations into: - *     return ((size * 85) >> 20) + 1; + *     return ((size * 85) >> 20) + ICE_DESCS_FOR_SKB_DATA_PTR;   */  static unsigned int ice_txd_use_count(unsigned int size)  { -	return ((size * 85) >> 20) + 1; +	return ((size * 85) >> 20) + ICE_DESCS_FOR_SKB_DATA_PTR;  }  /** @@ -1706,7 +1706,8 @@ ice_xmit_frame_ring(struct sk_buff *skb, struct ice_ring *tx_ring)  	 *       + 1 desc for context descriptor,  	 * otherwise try next time  	 */ -	if (ice_maybe_stop_tx(tx_ring, count + 4 + 1)) { +	if (ice_maybe_stop_tx(tx_ring, count + ICE_DESCS_PER_CACHE_LINE + +			      ICE_DESCS_FOR_CTX_DESC)) {  		tx_ring->tx_stats.tx_busy++;  		return NETDEV_TX_BUSY;  	} diff --git a/drivers/net/ethernet/intel/ice/ice_txrx.h b/drivers/net/ethernet/intel/ice/ice_txrx.h index 1d0f58bd389b..75d0eaf6c9dd 100644 --- a/drivers/net/ethernet/intel/ice/ice_txrx.h +++ b/drivers/net/ethernet/intel/ice/ice_txrx.h @@ -22,8 +22,21 @@  #define ICE_RX_BUF_WRITE	16	/* Must be power of 2 */  #define ICE_MAX_TXQ_PER_TXQG	128 -/* Tx Descriptors needed, worst case */ -#define DESC_NEEDED (MAX_SKB_FRAGS + 4) +/* We are assuming that the cache line is always 64 Bytes here for ice. + * In order to make sure that is a correct assumption there is a check in probe + * to print a warning if the read from GLPCI_CNF2 tells us that the cache line + * size is 128 bytes. We do it this way because we do not want to read the + * GLPCI_CNF2 register or a variable containing the value on every pass through + * the Tx path. + */ +#define ICE_CACHE_LINE_BYTES		64 +#define ICE_DESCS_PER_CACHE_LINE	(ICE_CACHE_LINE_BYTES / \ +					 sizeof(struct ice_tx_desc)) +#define ICE_DESCS_FOR_CTX_DESC		1 +#define ICE_DESCS_FOR_SKB_DATA_PTR	1 +/* Tx descriptors needed, worst case */ +#define DESC_NEEDED (MAX_SKB_FRAGS + ICE_DESCS_FOR_CTX_DESC + \ +		     ICE_DESCS_PER_CACHE_LINE + ICE_DESCS_FOR_SKB_DATA_PTR)  #define ICE_DESC_UNUSED(R)	\  	((((R)->next_to_clean > (R)->next_to_use) ? 0 : (R)->count) + \  	(R)->next_to_clean - (R)->next_to_use - 1) diff --git a/drivers/net/ethernet/intel/ice/ice_type.h b/drivers/net/ethernet/intel/ice/ice_type.h index 12f9432abf11..f4dbc81c1988 100644 --- a/drivers/net/ethernet/intel/ice/ice_type.h +++ b/drivers/net/ethernet/intel/ice/ice_type.h @@ -92,12 +92,12 @@ struct ice_link_status {  	u64 phy_type_low;  	u16 max_frame_size;  	u16 link_speed; +	u16 req_speeds;  	u8 lse_ena;	/* Link Status Event notification */  	u8 link_info;  	u8 an_info;  	u8 ext_info;  	u8 pacing; -	u8 req_speeds;  	/* Refer to #define from module_type[ICE_MODULE_TYPE_TOTAL_BYTE] of  	 * ice_aqc_get_phy_caps structure  	 */ diff --git a/drivers/net/ethernet/intel/ice/ice_virtchnl_pf.c b/drivers/net/ethernet/intel/ice/ice_virtchnl_pf.c index 45f10f8f01dc..e71065f9d391 100644 --- a/drivers/net/ethernet/intel/ice/ice_virtchnl_pf.c +++ b/drivers/net/ethernet/intel/ice/ice_virtchnl_pf.c @@ -348,7 +348,7 @@ static int ice_vsi_set_pvid(struct ice_vsi *vsi, u16 vid)  	struct ice_vsi_ctx ctxt = { 0 };  	enum ice_status status; -	ctxt.info.vlan_flags = ICE_AQ_VSI_VLAN_MODE_TAGGED | +	ctxt.info.vlan_flags = ICE_AQ_VSI_VLAN_MODE_UNTAGGED |  			       ICE_AQ_VSI_PVLAN_INSERT_PVID |  			       ICE_AQ_VSI_VLAN_EMOD_STR;  	ctxt.info.pvid = cpu_to_le16(vid); @@ -2171,7 +2171,6 @@ static int ice_vc_process_vlan_msg(struct ice_vf *vf, u8 *msg, bool add_v)  			if (!ice_vsi_add_vlan(vsi, vid)) {  				vf->num_vlan++; -				set_bit(vid, vsi->active_vlans);  				/* Enable VLAN pruning when VLAN 0 is added */  				if (unlikely(!vid)) @@ -2190,7 +2189,6 @@ static int ice_vc_process_vlan_msg(struct ice_vf *vf, u8 *msg, bool add_v)  			 */  			if (!ice_vsi_kill_vlan(vsi, vid)) {  				vf->num_vlan--; -				clear_bit(vid, vsi->active_vlans);  				/* Disable VLAN pruning when removing VLAN 0 */  				if (unlikely(!vid)) | 
