[Intel-wired-lan] [RFC 16/20] iavf: Add framework to enable ethtool ntuple filters

Creeley, Brett brett.creeley at intel.com
Tue Jan 26 16:33:14 UTC 2021


I'm fine with the flags updating, but it does look a little strange to
just skip bits for no apparent reason, i.e. if the patches Jan is
talking about aren't actually in the pipeline.

Brett

On Tue, 2021-01-26 at 15:12 +0000, Loktionov, Aleksandr wrote:
> +Brett
> 
> -----Original Message-----
> From: Sokolowski, Jan <jan.sokolowski at intel.com> 
> Sent: Tuesday, January 26, 2021 12:31 PM
> To: Wang, Haiyue <haiyue.wang at intel.com>; 
> intel-wired-lan at lists.osuosl.org
> Cc: Liang, Cunming <cunming.liang at intel.com>; Zhang, Qi Z <
> qi.z.zhang at intel.com>; kuba at kernel.org; davem at davemloft.net;
> Loktionov, Aleksandr <aleksandr.loktionov at intel.com>
> Subject: RE: [Intel-wired-lan] [RFC 16/20] iavf: Add framework to
> enable ethtool ntuple filters
> 
> Would it be possible to move these new flags to bits 35 and 36?
> Currently OOT uses bits up to 34, and as the changes are being
> prepared for upstreaming, there might be a conflict there.
> 
> Jan
> 
> -----Original Message-----
> From: Intel-wired-lan <intel-wired-lan-bounces at osuosl.org> On Behalf
> Of Haiyue Wang
> Sent: Tuesday, November 24, 2020 7:24 AM
> To: intel-wired-lan at lists.osuosl.org
> Cc: Liang, Cunming <cunming.liang at intel.com>; Zhang, Qi Z <
> qi.z.zhang at intel.com>; kuba at kernel.org; davem at davemloft.net
> Subject: [Intel-wired-lan] [RFC 16/20] iavf: Add framework to enable
> ethtool ntuple filters
> 
> Enable ethtool ntuple filter support on the VF driver using the
> virtchnl interface to the PF driver and the Flow director
> functionality in the hardware.
> 
> Signed-off-by: Haiyue Wang <haiyue.wang at intel.com>
> ---
>  drivers/net/ethernet/intel/iavf/iavf.h        |  12 ++
>  drivers/net/ethernet/intel/iavf/iavf_fdir.h   |  33 ++++
>  drivers/net/ethernet/intel/iavf/iavf_main.c   |  27 +++
>  .../net/ethernet/intel/iavf/iavf_virtchnl.c   | 187
> ++++++++++++++++++
>  4 files changed, 259 insertions(+)
>  create mode 100644 drivers/net/ethernet/intel/iavf/iavf_fdir.h
> 
> diff --git a/drivers/net/ethernet/intel/iavf/iavf.h
> b/drivers/net/ethernet/intel/iavf/iavf.h
> index 8a65525a7c0d..bda2a900df8e 100644
> --- a/drivers/net/ethernet/intel/iavf/iavf.h
> +++ b/drivers/net/ethernet/intel/iavf/iavf.h
> @@ -37,6 +37,7 @@
>  #include "iavf_type.h"
>  #include <linux/avf/virtchnl.h>
>  #include "iavf_txrx.h"
> +#include "iavf_fdir.h"
>  
>  #define DEFAULT_DEBUG_LEVEL_SHIFT 3
>  #define PFX "iavf: "
> @@ -300,6 +301,8 @@ struct iavf_adapter {
>  #define IAVF_FLAG_AQ_DISABLE_CHANNELS		BIT(22)
>  #define IAVF_FLAG_AQ_ADD_CLOUD_FILTER		BIT(23)
>  #define IAVF_FLAG_AQ_DEL_CLOUD_FILTER		BIT(24)
> +#define IAVF_FLAG_AQ_ADD_FDIR_FILTER		BIT(25)
> +#define IAVF_FLAG_AQ_DEL_FDIR_FILTER		BIT(26)
>  
>  	/* OS defined structs */
>  	struct net_device *netdev;
> @@ -340,6 +343,8 @@ struct iavf_adapter {
>  			  VIRTCHNL_VF_OFFLOAD_VLAN)
>  #define ADV_LINK_SUPPORT(_a) ((_a)->vf_res->vf_cap_flags & \
>  			      VIRTCHNL_VF_CAP_ADV_LINK_SPEED)
> +#define FDIR_FLTR_SUPPORT(_a) ((_a)->vf_res->vf_cap_flags & \
> +			       VIRTCHNL_VF_OFFLOAD_FDIR_PF)
>  	struct virtchnl_vf_resource *vf_res; /* incl. all VSIs */
>  	struct virtchnl_vsi_resource *vsi_res; /* our LAN VSI */
>  	struct virtchnl_version_info pf_version; @@ -362,6 +367,11 @@
> struct iavf_adapter {
>  	/* lock to protect access to the cloud filter list */
>  	spinlock_t cloud_filter_list_lock;
>  	u16 num_cloud_filters;
> +
> +#define IAVF_MAX_FDIR_FILTERS 128	/* max allowed Flow Director
> filters */
> +	u16 fdir_active_fltr;
> +	struct list_head fdir_list_head;
> +	spinlock_t fdir_fltr_lock;	/* protect the Flow Director
> filter list */
>  };
>  
>  
> @@ -432,6 +442,8 @@ void iavf_enable_channels(struct iavf_adapter
> *adapter);  void iavf_disable_channels(struct iavf_adapter
> *adapter);  void iavf_add_cloud_filter(struct iavf_adapter
> *adapter);  void iavf_del_cloud_filter(struct iavf_adapter *adapter);
> +void iavf_add_fdir_filter(struct iavf_adapter *adapter); void 
> +iavf_del_fdir_filter(struct iavf_adapter *adapter);
>  struct iavf_mac_filter *iavf_add_filter(struct iavf_adapter
> *adapter,
>  					const u8 *macaddr);
>  #endif /* _IAVF_H_ */
> diff --git a/drivers/net/ethernet/intel/iavf/iavf_fdir.h
> b/drivers/net/ethernet/intel/iavf/iavf_fdir.h
> new file mode 100644
> index 000000000000..429bc025d45a
> --- /dev/null
> +++ b/drivers/net/ethernet/intel/iavf/iavf_fdir.h
> @@ -0,0 +1,33 @@
> +/* SPDX-License-Identifier: GPL-2.0 */
> +/* Copyright (c) 2020, Intel Corporation. */
> +
> +#ifndef _IAVF_FDIR_H_
> +#define _IAVF_FDIR_H_
> +
> +struct iavf_adapter;
> +
> +/* State of Flow Director filter */
> +enum iavf_fdir_fltr_state_t {
> +	IAVF_FDIR_FLTR_ADD_REQUEST,	/* User requests to add Flow
> Director filter */
> +	IAVF_FDIR_FLTR_ADD_PENDING,	/* Flow Director filter
> pending add by the PF */
> +	IAVF_FDIR_FLTR_DEL_REQUEST,	/* User requests to delete
> Flow Director filter */
> +	IAVF_FDIR_FLTR_DEL_PENDING,	/* Flow Director filter
> pending delete by the PF */
> +	IAVF_FDIR_FLTR_ACTIVE,		/* Flow Director filter is
> active */
> +};
> +
> +/* bookkeeping of Flow Director filters */ struct iavf_fdir_fltr {
> +	enum iavf_fdir_fltr_state_t state;
> +	struct list_head list;
> +
> +	u32 flow_id;
> +
> +	struct virtchnl_fdir_add vc_add_msg;
> +};
> +
> +int iavf_fill_fdir_add_msg(struct iavf_adapter *adapter, struct 
> +iavf_fdir_fltr *fltr); void iavf_print_fdir_fltr(struct
> iavf_adapter 
> +*adapter, struct iavf_fdir_fltr *fltr); bool 
> +iavf_fdir_is_dup_fltr(struct iavf_adapter *adapter, struct 
> +iavf_fdir_fltr *fltr); void iavf_fdir_list_add_fltr(struct
> iavf_adapter 
> +*adapter, struct iavf_fdir_fltr *fltr); struct iavf_fdir_fltr 
> +*iavf_find_fdir_fltr_by_loc(struct iavf_adapter *adapter, u32 loc); 
> +#endif /* _IAVF_FDIR_H_ */
> diff --git a/drivers/net/ethernet/intel/iavf/iavf_main.c
> b/drivers/net/ethernet/intel/iavf/iavf_main.c
> index 814e59bf2c94..d9f9085421df 100644
> --- a/drivers/net/ethernet/intel/iavf/iavf_main.c
> +++ b/drivers/net/ethernet/intel/iavf/iavf_main.c
> @@ -958,6 +958,7 @@ static void iavf_up_complete(struct iavf_adapter
> *adapter)  void iavf_down(struct iavf_adapter *adapter)  {
>  	struct net_device *netdev = adapter->netdev;
> +	struct iavf_fdir_fltr *fdir;
>  	struct iavf_vlan_filter *vlf;
>  	struct iavf_mac_filter *f;
>  	struct iavf_cloud_filter *cf;
> @@ -996,6 +997,13 @@ void iavf_down(struct iavf_adapter *adapter)
>  	}
>  	spin_unlock_bh(&adapter->cloud_filter_list_lock);
>  
> +	/* remove all Flow Director filters */
> +	spin_lock_bh(&adapter->fdir_fltr_lock);
> +	list_for_each_entry(fdir, &adapter->fdir_list_head, list) {
> +		fdir->state = IAVF_FDIR_FLTR_DEL_REQUEST;
> +	}
> +	spin_unlock_bh(&adapter->fdir_fltr_lock);
> +
>  	if (!(adapter->flags & IAVF_FLAG_PF_COMMS_FAILED) &&
>  	    adapter->state != __IAVF_RESETTING) {
>  		/* cancel any current operation */
> @@ -1007,6 +1015,7 @@ void iavf_down(struct iavf_adapter *adapter)
>  		adapter->aq_required = IAVF_FLAG_AQ_DEL_MAC_FILTER;
>  		adapter->aq_required |= IAVF_FLAG_AQ_DEL_VLAN_FILTER;
>  		adapter->aq_required |= IAVF_FLAG_AQ_DEL_CLOUD_FILTER;
> +		adapter->aq_required |= IAVF_FLAG_AQ_DEL_FDIR_FILTER;
>  		adapter->aq_required |= IAVF_FLAG_AQ_DISABLE_QUEUES;
>  	}
>  
> @@ -1629,6 +1638,14 @@ static int iavf_process_aq_command(struct
> iavf_adapter *adapter)
>  		iavf_add_cloud_filter(adapter);
>  		return 0;
>  	}
> +	if (adapter->aq_required & IAVF_FLAG_AQ_ADD_FDIR_FILTER) {
> +		iavf_add_fdir_filter(adapter);
> +		return IAVF_SUCCESS;
> +	}
> +	if (adapter->aq_required & IAVF_FLAG_AQ_DEL_FDIR_FILTER) {
> +		iavf_del_fdir_filter(adapter);
> +		return IAVF_SUCCESS;
> +	}
>  	return -EAGAIN;
>  }
>  
> @@ -3739,10 +3756,12 @@ static int iavf_probe(struct pci_dev *pdev,
> const struct pci_device_id *ent)
>  
>  	spin_lock_init(&adapter->mac_vlan_list_lock);
>  	spin_lock_init(&adapter->cloud_filter_list_lock);
> +	spin_lock_init(&adapter->fdir_fltr_lock);
>  
>  	INIT_LIST_HEAD(&adapter->mac_filter_list);
>  	INIT_LIST_HEAD(&adapter->vlan_filter_list);
>  	INIT_LIST_HEAD(&adapter->cloud_filter_list);
> +	INIT_LIST_HEAD(&adapter->fdir_list_head);
>  
>  	INIT_WORK(&adapter->reset_task, iavf_reset_task);
>  	INIT_WORK(&adapter->adminq_task, iavf_adminq_task); @@ -3846,6
> +3865,7 @@ static void iavf_remove(struct pci_dev *pdev)  {
>  	struct net_device *netdev = pci_get_drvdata(pdev);
>  	struct iavf_adapter *adapter = netdev_priv(netdev);
> +	struct iavf_fdir_fltr *fdir, *fdirtmp;
>  	struct iavf_vlan_filter *vlf, *vlftmp;
>  	struct iavf_mac_filter *f, *ftmp;
>  	struct iavf_cloud_filter *cf, *cftmp;
> @@ -3927,6 +3947,13 @@ static void iavf_remove(struct pci_dev *pdev)
>  	}
>  	spin_unlock_bh(&adapter->cloud_filter_list_lock);
>  
> +	spin_lock_bh(&adapter->fdir_fltr_lock);
> +	list_for_each_entry_safe(fdir, fdirtmp, &adapter-
> >fdir_list_head, list) {
> +		list_del(&fdir->list);
> +		kfree(fdir);
> +	}
> +	spin_unlock_bh(&adapter->fdir_fltr_lock);
> +
>  	free_netdev(netdev);
>  
>  	pci_disable_pcie_error_reporting(pdev);
> diff --git a/drivers/net/ethernet/intel/iavf/iavf_virtchnl.c
> b/drivers/net/ethernet/intel/iavf/iavf_virtchnl.c
> index ed08ace4f05a..eb687081e94f 100644
> --- a/drivers/net/ethernet/intel/iavf/iavf_virtchnl.c
> +++ b/drivers/net/ethernet/intel/iavf/iavf_virtchnl.c
> @@ -140,6 +140,7 @@ int iavf_send_vf_config_msg(struct iavf_adapter
> *adapter)
>  	       VIRTCHNL_VF_OFFLOAD_ENCAP_CSUM |
>  	       VIRTCHNL_VF_OFFLOAD_REQ_QUEUES |
>  	       VIRTCHNL_VF_OFFLOAD_ADQ |
> +	       VIRTCHNL_VF_OFFLOAD_FDIR_PF |
>  	       VIRTCHNL_VF_CAP_ADV_LINK_SPEED;
>  
>  	adapter->current_op = VIRTCHNL_OP_GET_VF_RESOURCES; @@ -1197,6
> +1198,101 @@ void iavf_del_cloud_filter(struct iavf_adapter *adapter)
>  	kfree(f);
>  }
>  
> +/**
> + * iavf_add_fdir_filter
> + * @adapter: the VF adapter structure
> + *
> + * Request that the PF add Flow Director filters as specified
> + * by the user via ethtool.
> + **/
> +void iavf_add_fdir_filter(struct iavf_adapter *adapter) {
> +	struct iavf_fdir_fltr *fdir;
> +	struct virtchnl_fdir_add *f;
> +	bool process_fltr = false;
> +	int len;
> +
> +	if (adapter->current_op != VIRTCHNL_OP_UNKNOWN) {
> +		/* bail because we already have a command pending */
> +		dev_err(&adapter->pdev->dev, "Cannot add Flow Director
> filter, command %d pending\n",
> +			adapter->current_op);
> +		return;
> +	}
> +
> +	len = sizeof(struct virtchnl_fdir_add);
> +	f = kzalloc(len, GFP_KERNEL);
> +	if (!f)
> +		return;
> +
> +	spin_lock_bh(&adapter->fdir_fltr_lock);
> +	list_for_each_entry(fdir, &adapter->fdir_list_head, list) {
> +		if (fdir->state == IAVF_FDIR_FLTR_ADD_REQUEST) {
> +			process_fltr = true;
> +			fdir->state = IAVF_FDIR_FLTR_ADD_PENDING;
> +			memcpy(f, &fdir->vc_add_msg, len);
> +			break;
> +		}
> +	}
> +	spin_unlock_bh(&adapter->fdir_fltr_lock);
> +
> +	if (!process_fltr) {
> +		/* prevent iavf_add_fdir_filter() from being called
> when there
> +		 * are no filters to add
> +		 */
> +		adapter->aq_required &= ~IAVF_FLAG_AQ_ADD_FDIR_FILTER;
> +		kfree(f);
> +		return;
> +	}
> +	adapter->current_op = VIRTCHNL_OP_ADD_FDIR_FILTER;
> +	iavf_send_pf_msg(adapter, VIRTCHNL_OP_ADD_FDIR_FILTER, (u8 *)f,
> len);
> +	kfree(f);
> +}
> +
> +/**
> + * iavf_del_fdir_filter
> + * @adapter: the VF adapter structure
> + *
> + * Request that the PF delete Flow Director filters as specified
> + * by the user via ethtool.
> + **/
> +void iavf_del_fdir_filter(struct iavf_adapter *adapter) {
> +	struct iavf_fdir_fltr *fdir;
> +	struct virtchnl_fdir_del f;
> +	bool process_fltr = false;
> +	int len;
> +
> +	if (adapter->current_op != VIRTCHNL_OP_UNKNOWN) {
> +		/* bail because we already have a command pending */
> +		dev_err(&adapter->pdev->dev, "Cannot remove Flow
> Director filter, command %d pending\n",
> +			adapter->current_op);
> +		return;
> +	}
> +
> +	len = sizeof(struct virtchnl_fdir_del);
> +
> +	spin_lock_bh(&adapter->fdir_fltr_lock);
> +	list_for_each_entry(fdir, &adapter->fdir_list_head, list) {
> +		if (fdir->state == IAVF_FDIR_FLTR_DEL_REQUEST) {
> +			process_fltr = true;
> +			memset(&f, 0, len);
> +			f.vsi_id = fdir->vc_add_msg.vsi_id;
> +			f.flow_id = fdir->flow_id;
> +			fdir->state = IAVF_FDIR_FLTR_DEL_PENDING;
> +			break;
> +		}
> +	}
> +	spin_unlock_bh(&adapter->fdir_fltr_lock);
> +
> +	if (!process_fltr) {
> +		adapter->aq_required &= ~IAVF_FLAG_AQ_DEL_FDIR_FILTER;
> +		return;
> +	}
> +
> +	adapter->current_op = VIRTCHNL_OP_DEL_FDIR_FILTER;
> +	iavf_send_pf_msg(adapter, VIRTCHNL_OP_DEL_FDIR_FILTER, (u8
> *)&f, len); 
> +}
> +
>  /**
>   * iavf_request_reset
>   * @adapter: adapter structure
> @@ -1357,6 +1453,49 @@ void iavf_virtchnl_completion(struct
> iavf_adapter *adapter,
>  			}
>  			}
>  			break;
> +		case VIRTCHNL_OP_ADD_FDIR_FILTER: {
> +			struct iavf_fdir_fltr *fdir, *fdir_tmp;
> +
> +			spin_lock_bh(&adapter->fdir_fltr_lock);
> +			list_for_each_entry_safe(fdir, fdir_tmp,
> +						 &adapter-
> >fdir_list_head,
> +						 list) {
> +				if (fdir->state ==
> IAVF_FDIR_FLTR_ADD_PENDING) {
> +					dev_info(&adapter->pdev->dev,
> "Failed to add Flow Director filter, error %s\n",
> +						 iavf_stat_str(&adapter
> ->hw,
> +							       v_retval
> ));
> +					if (msglen)
> +						dev_err(&adapter->pdev-
> >dev,
> +							"%s\n", msg);
> +					list_del(&fdir->list);
> +					kfree(fdir);
> +					adapter->fdir_active_fltr--;
> +				}
> +			}
> +			spin_unlock_bh(&adapter->fdir_fltr_lock);
> +			}
> +			break;
> +		case VIRTCHNL_OP_DEL_FDIR_FILTER: {
> +			struct iavf_fdir_fltr *fdir;
> +
> +			spin_lock_bh(&adapter->fdir_fltr_lock);
> +			list_for_each_entry(fdir, &adapter-
> >fdir_list_head,
> +					    list) {
> +				if (fdir->state ==
> IAVF_FDIR_FLTR_DEL_PENDING) {
> +					fdir->state =
> IAVF_FDIR_FLTR_ACTIVE;
> +					dev_info(&adapter->pdev->dev,
> "Failed to del Flow Director filter, error %s\n",
> +						 iavf_stat_str(&adapter
> ->hw,
> +							       v_retval
> ));
> +				}
> +			}
> +			spin_unlock_bh(&adapter->fdir_fltr_lock);
> +			}
> +			break;
> +		case VIRTCHNL_OP_ENABLE_VLAN_STRIPPING:
> +		case VIRTCHNL_OP_DISABLE_VLAN_STRIPPING:
> +			dev_warn(&adapter->pdev->dev,
> +				 "Changing VLAN Stripping is not
> allowed when Port VLAN is configured\n");
> +			break;
>  		default:
>  			dev_err(&adapter->pdev->dev, "PF returned error
> %d (%s) to our request %d\n",
>  				v_retval, iavf_stat_str(&adapter->hw,
> v_retval), @@ -1490,6 +1629,54 @@ void
> iavf_virtchnl_completion(struct iavf_adapter *adapter,
>  		}
>  		}
>  		break;
> +	case VIRTCHNL_OP_ADD_FDIR_FILTER: {
> +		struct virtchnl_fdir_add *add_fltr = (struct
> virtchnl_fdir_add *)msg;
> +		struct iavf_fdir_fltr *fdir, *fdir_tmp;
> +
> +		spin_lock_bh(&adapter->fdir_fltr_lock);
> +		list_for_each_entry_safe(fdir, fdir_tmp,
> +					 &adapter->fdir_list_head,
> +					 list) {
> +			if (fdir->state == IAVF_FDIR_FLTR_ADD_PENDING)
> {
> +				if (add_fltr->status ==
> VIRTCHNL_FDIR_SUCCESS) {
> +					fdir->state =
> IAVF_FDIR_FLTR_ACTIVE;
> +					fdir->flow_id = add_fltr-
> >flow_id;
> +				} else {
> +					dev_info(&adapter->pdev->dev,
> +						 "Failed to add Flow
> Director filter with status : %d\n",
> +						 add_fltr->status);
> +					list_del(&fdir->list);
> +					kfree(fdir);
> +					adapter->fdir_active_fltr--;
> +				}
> +			}
> +		}
> +		spin_unlock_bh(&adapter->fdir_fltr_lock);
> +		}
> +		break;
> +	case VIRTCHNL_OP_DEL_FDIR_FILTER: {
> +		struct virtchnl_fdir_del *del_fltr = (struct
> virtchnl_fdir_del *)msg;
> +		struct iavf_fdir_fltr *fdir, *fdir_tmp;
> +
> +		spin_lock_bh(&adapter->fdir_fltr_lock);
> +		list_for_each_entry_safe(fdir, fdir_tmp, &adapter-
> >fdir_list_head,
> +					 list) {
> +			if (fdir->state == IAVF_FDIR_FLTR_DEL_PENDING)
> {
> +				if (del_fltr->status ==
> VIRTCHNL_FDIR_SUCCESS) {
> +					list_del(&fdir->list);
> +					kfree(fdir);
> +					adapter->fdir_active_fltr--;
> +				} else {
> +					fdir->state =
> IAVF_FDIR_FLTR_ACTIVE;
> +					dev_info(&adapter->pdev->dev,
> +						 "Failed to delete Flow
> Director filter with status : %d\n",
> +						 del_fltr->status);
> +				}
> +			}
> +		}
> +		spin_unlock_bh(&adapter->fdir_fltr_lock);
> +		}
> +		break;
>  	default:
>  		if (adapter->current_op && (v_opcode != adapter-
> >current_op))
>  			dev_warn(&adapter->pdev->dev, "Expected
> response %d from PF, received %d\n",
> --
> 2.29.2
> 
> _______________________________________________
> Intel-wired-lan mailing list
> Intel-wired-lan at osuosl.org
> https://lists.osuosl.org/mailman/listinfo/intel-wired-lan


More information about the Intel-wired-lan mailing list