diff options
Diffstat (limited to 'drivers/net/ethernet/intel/ice')
| -rw-r--r-- | drivers/net/ethernet/intel/ice/ice_main.c | 49 | ||||
| -rw-r--r-- | drivers/net/ethernet/intel/ice/ice_ptp.c | 2 | ||||
| -rw-r--r-- | drivers/net/ethernet/intel/ice/ice_ptp.h | 31 | ||||
| -rw-r--r-- | drivers/net/ethernet/intel/ice/ice_vf_lib.c | 5 | ||||
| -rw-r--r-- | drivers/net/ethernet/intel/ice/ice_virtchnl.c | 53 | 
5 files changed, 94 insertions, 46 deletions
diff --git a/drivers/net/ethernet/intel/ice/ice_main.c b/drivers/net/ethernet/intel/ice/ice_main.c index e1cae253412c..c1ac2f746714 100644 --- a/drivers/net/ethernet/intel/ice/ice_main.c +++ b/drivers/net/ethernet/intel/ice/ice_main.c @@ -5763,25 +5763,38 @@ static netdev_features_t  ice_fix_features(struct net_device *netdev, netdev_features_t features)  {  	struct ice_netdev_priv *np = netdev_priv(netdev); -	netdev_features_t supported_vlan_filtering; -	netdev_features_t requested_vlan_filtering; -	struct ice_vsi *vsi = np->vsi; - -	requested_vlan_filtering = features & NETIF_VLAN_FILTERING_FEATURES; - -	/* make sure supported_vlan_filtering works for both SVM and DVM */ -	supported_vlan_filtering = NETIF_F_HW_VLAN_CTAG_FILTER; -	if (ice_is_dvm_ena(&vsi->back->hw)) -		supported_vlan_filtering |= NETIF_F_HW_VLAN_STAG_FILTER; - -	if (requested_vlan_filtering && -	    requested_vlan_filtering != supported_vlan_filtering) { -		if (requested_vlan_filtering & NETIF_F_HW_VLAN_CTAG_FILTER) { -			netdev_warn(netdev, "cannot support requested VLAN filtering settings, enabling all supported VLAN filtering settings\n"); -			features |= supported_vlan_filtering; +	netdev_features_t req_vlan_fltr, cur_vlan_fltr; +	bool cur_ctag, cur_stag, req_ctag, req_stag; + +	cur_vlan_fltr = netdev->features & NETIF_VLAN_FILTERING_FEATURES; +	cur_ctag = cur_vlan_fltr & NETIF_F_HW_VLAN_CTAG_FILTER; +	cur_stag = cur_vlan_fltr & NETIF_F_HW_VLAN_STAG_FILTER; + +	req_vlan_fltr = features & NETIF_VLAN_FILTERING_FEATURES; +	req_ctag = req_vlan_fltr & NETIF_F_HW_VLAN_CTAG_FILTER; +	req_stag = req_vlan_fltr & NETIF_F_HW_VLAN_STAG_FILTER; + +	if (req_vlan_fltr != cur_vlan_fltr) { +		if (ice_is_dvm_ena(&np->vsi->back->hw)) { +			if (req_ctag && req_stag) { +				features |= NETIF_VLAN_FILTERING_FEATURES; +			} else if (!req_ctag && !req_stag) { +				features &= ~NETIF_VLAN_FILTERING_FEATURES; +			} else if ((!cur_ctag && req_ctag && !cur_stag) || +				   (!cur_stag && req_stag && !cur_ctag)) { +				features |= NETIF_VLAN_FILTERING_FEATURES; +				netdev_warn(netdev,  "802.1Q and 802.1ad VLAN filtering must be either both on or both off. VLAN filtering has been enabled for both types.\n"); +			} else if ((cur_ctag && !req_ctag && cur_stag) || +				   (cur_stag && !req_stag && cur_ctag)) { +				features &= ~NETIF_VLAN_FILTERING_FEATURES; +				netdev_warn(netdev,  "802.1Q and 802.1ad VLAN filtering must be either both on or both off. VLAN filtering has been disabled for both types.\n"); +			}  		} else { -			netdev_warn(netdev, "cannot support requested VLAN filtering settings, clearing all supported VLAN filtering settings\n"); -			features &= ~supported_vlan_filtering; +			if (req_vlan_fltr & NETIF_F_HW_VLAN_STAG_FILTER) +				netdev_warn(netdev, "cannot support requested 802.1ad filtering setting in SVM mode\n"); + +			if (req_vlan_fltr & NETIF_F_HW_VLAN_CTAG_FILTER) +				features |= NETIF_F_HW_VLAN_CTAG_FILTER;  		}  	} diff --git a/drivers/net/ethernet/intel/ice/ice_ptp.c b/drivers/net/ethernet/intel/ice/ice_ptp.c index 662947c882e8..ef9344ef0d8e 100644 --- a/drivers/net/ethernet/intel/ice/ice_ptp.c +++ b/drivers/net/ethernet/intel/ice/ice_ptp.c @@ -2271,7 +2271,7 @@ static int  ice_ptp_init_tx_e822(struct ice_pf *pf, struct ice_ptp_tx *tx, u8 port)  {  	tx->quad = port / ICE_PORTS_PER_QUAD; -	tx->quad_offset = tx->quad * INDEX_PER_PORT; +	tx->quad_offset = (port % ICE_PORTS_PER_QUAD) * INDEX_PER_PORT;  	tx->len = INDEX_PER_PORT;  	return ice_ptp_alloc_tx_tracker(tx); diff --git a/drivers/net/ethernet/intel/ice/ice_ptp.h b/drivers/net/ethernet/intel/ice/ice_ptp.h index afd048d69959..10e396abf130 100644 --- a/drivers/net/ethernet/intel/ice/ice_ptp.h +++ b/drivers/net/ethernet/intel/ice/ice_ptp.h @@ -49,6 +49,37 @@ struct ice_perout_channel {   * To allow multiple ports to access the shared register block independently,   * the blocks are split up so that indexes are assigned to each port based on   * hardware logical port number. + * + * The timestamp blocks are handled differently for E810- and E822-based + * devices. In E810 devices, each port has its own block of timestamps, while in + * E822 there is a need to logically break the block of registers into smaller + * chunks based on the port number to avoid collisions. + * + * Example for port 5 in E810: + *  +--------+--------+--------+--------+--------+--------+--------+--------+ + *  |register|register|register|register|register|register|register|register| + *  | block  | block  | block  | block  | block  | block  | block  | block  | + *  |  for   |  for   |  for   |  for   |  for   |  for   |  for   |  for   | + *  | port 0 | port 1 | port 2 | port 3 | port 4 | port 5 | port 6 | port 7 | + *  +--------+--------+--------+--------+--------+--------+--------+--------+ + *                                               ^^ + *                                               || + *                                               |---  quad offset is always 0 + *                                               ---- quad number + * + * Example for port 5 in E822: + * +-----------------------------+-----------------------------+ + * |  register block for quad 0  |  register block for quad 1  | + * |+------+------+------+------+|+------+------+------+------+| + * ||port 0|port 1|port 2|port 3|||port 0|port 1|port 2|port 3|| + * |+------+------+------+------+|+------+------+------+------+| + * +-----------------------------+-------^---------------------+ + *                                ^      | + *                                |      --- quad offset* + *                                ---- quad number + * + *   * PHY port 5 is port 1 in quad 1 + *   */  /** diff --git a/drivers/net/ethernet/intel/ice/ice_vf_lib.c b/drivers/net/ethernet/intel/ice/ice_vf_lib.c index cd8e6b50968c..7adf9ddf129e 100644 --- a/drivers/net/ethernet/intel/ice/ice_vf_lib.c +++ b/drivers/net/ethernet/intel/ice/ice_vf_lib.c @@ -504,6 +504,11 @@ int ice_reset_vf(struct ice_vf *vf, u32 flags)  	}  	if (ice_is_vf_disabled(vf)) { +		vsi = ice_get_vf_vsi(vf); +		if (WARN_ON(!vsi)) +			return -EINVAL; +		ice_vsi_stop_lan_tx_rings(vsi, ICE_NO_RESET, vf->vf_id); +		ice_vsi_stop_all_rx_rings(vsi);  		dev_dbg(dev, "VF is already disabled, there is no need for resetting it, telling VM, all is fine %d\n",  			vf->vf_id);  		return 0; diff --git a/drivers/net/ethernet/intel/ice/ice_virtchnl.c b/drivers/net/ethernet/intel/ice/ice_virtchnl.c index 1d9b84c3937a..4547bc1f7cee 100644 --- a/drivers/net/ethernet/intel/ice/ice_virtchnl.c +++ b/drivers/net/ethernet/intel/ice/ice_virtchnl.c @@ -1569,35 +1569,27 @@ error_param:   */  static int ice_vc_cfg_qs_msg(struct ice_vf *vf, u8 *msg)  { -	enum virtchnl_status_code v_ret = VIRTCHNL_STATUS_SUCCESS;  	struct virtchnl_vsi_queue_config_info *qci =  	    (struct virtchnl_vsi_queue_config_info *)msg;  	struct virtchnl_queue_pair_info *qpi;  	struct ice_pf *pf = vf->pf;  	struct ice_vsi *vsi; -	int i, q_idx; +	int i = -1, q_idx; -	if (!test_bit(ICE_VF_STATE_ACTIVE, vf->vf_states)) { -		v_ret = VIRTCHNL_STATUS_ERR_PARAM; +	if (!test_bit(ICE_VF_STATE_ACTIVE, vf->vf_states))  		goto error_param; -	} -	if (!ice_vc_isvalid_vsi_id(vf, qci->vsi_id)) { -		v_ret = VIRTCHNL_STATUS_ERR_PARAM; +	if (!ice_vc_isvalid_vsi_id(vf, qci->vsi_id))  		goto error_param; -	}  	vsi = ice_get_vf_vsi(vf); -	if (!vsi) { -		v_ret = VIRTCHNL_STATUS_ERR_PARAM; +	if (!vsi)  		goto error_param; -	}  	if (qci->num_queue_pairs > ICE_MAX_RSS_QS_PER_VF ||  	    qci->num_queue_pairs > min_t(u16, vsi->alloc_txq, vsi->alloc_rxq)) {  		dev_err(ice_pf_to_dev(pf), "VF-%d requesting more than supported number of queues: %d\n",  			vf->vf_id, min_t(u16, vsi->alloc_txq, vsi->alloc_rxq)); -		v_ret = VIRTCHNL_STATUS_ERR_PARAM;  		goto error_param;  	} @@ -1610,7 +1602,6 @@ static int ice_vc_cfg_qs_msg(struct ice_vf *vf, u8 *msg)  		    !ice_vc_isvalid_ring_len(qpi->txq.ring_len) ||  		    !ice_vc_isvalid_ring_len(qpi->rxq.ring_len) ||  		    !ice_vc_isvalid_q_id(vf, qci->vsi_id, qpi->txq.queue_id)) { -			v_ret = VIRTCHNL_STATUS_ERR_PARAM;  			goto error_param;  		} @@ -1620,7 +1611,6 @@ static int ice_vc_cfg_qs_msg(struct ice_vf *vf, u8 *msg)  		 * for selected "vsi"  		 */  		if (q_idx >= vsi->alloc_txq || q_idx >= vsi->alloc_rxq) { -			v_ret = VIRTCHNL_STATUS_ERR_PARAM;  			goto error_param;  		} @@ -1630,14 +1620,13 @@ static int ice_vc_cfg_qs_msg(struct ice_vf *vf, u8 *msg)  			vsi->tx_rings[i]->count = qpi->txq.ring_len;  			/* Disable any existing queue first */ -			if (ice_vf_vsi_dis_single_txq(vf, vsi, q_idx)) { -				v_ret = VIRTCHNL_STATUS_ERR_PARAM; +			if (ice_vf_vsi_dis_single_txq(vf, vsi, q_idx))  				goto error_param; -			}  			/* Configure a queue with the requested settings */  			if (ice_vsi_cfg_single_txq(vsi, vsi->tx_rings, q_idx)) { -				v_ret = VIRTCHNL_STATUS_ERR_PARAM; +				dev_warn(ice_pf_to_dev(pf), "VF-%d failed to configure TX queue %d\n", +					 vf->vf_id, i);  				goto error_param;  			}  		} @@ -1651,17 +1640,13 @@ static int ice_vc_cfg_qs_msg(struct ice_vf *vf, u8 *msg)  			if (qpi->rxq.databuffer_size != 0 &&  			    (qpi->rxq.databuffer_size > ((16 * 1024) - 128) || -			     qpi->rxq.databuffer_size < 1024)) { -				v_ret = VIRTCHNL_STATUS_ERR_PARAM; +			     qpi->rxq.databuffer_size < 1024))  				goto error_param; -			}  			vsi->rx_buf_len = qpi->rxq.databuffer_size;  			vsi->rx_rings[i]->rx_buf_len = vsi->rx_buf_len;  			if (qpi->rxq.max_pkt_size > max_frame_size || -			    qpi->rxq.max_pkt_size < 64) { -				v_ret = VIRTCHNL_STATUS_ERR_PARAM; +			    qpi->rxq.max_pkt_size < 64)  				goto error_param; -			}  			vsi->max_frame = qpi->rxq.max_pkt_size;  			/* add space for the port VLAN since the VF driver is @@ -1672,16 +1657,30 @@ static int ice_vc_cfg_qs_msg(struct ice_vf *vf, u8 *msg)  				vsi->max_frame += VLAN_HLEN;  			if (ice_vsi_cfg_single_rxq(vsi, q_idx)) { -				v_ret = VIRTCHNL_STATUS_ERR_PARAM; +				dev_warn(ice_pf_to_dev(pf), "VF-%d failed to configure RX queue %d\n", +					 vf->vf_id, i);  				goto error_param;  			}  		}  	} +	/* send the response to the VF */ +	return ice_vc_send_msg_to_vf(vf, VIRTCHNL_OP_CONFIG_VSI_QUEUES, +				     VIRTCHNL_STATUS_SUCCESS, NULL, 0);  error_param: +	/* disable whatever we can */ +	for (; i >= 0; i--) { +		if (ice_vsi_ctrl_one_rx_ring(vsi, false, i, true)) +			dev_err(ice_pf_to_dev(pf), "VF-%d could not disable RX queue %d\n", +				vf->vf_id, i); +		if (ice_vf_vsi_dis_single_txq(vf, vsi, i)) +			dev_err(ice_pf_to_dev(pf), "VF-%d could not disable TX queue %d\n", +				vf->vf_id, i); +	} +  	/* send the response to the VF */ -	return ice_vc_send_msg_to_vf(vf, VIRTCHNL_OP_CONFIG_VSI_QUEUES, v_ret, -				     NULL, 0); +	return ice_vc_send_msg_to_vf(vf, VIRTCHNL_OP_CONFIG_VSI_QUEUES, +				     VIRTCHNL_STATUS_ERR_PARAM, NULL, 0);  }  /**  |