Intel-Wired-Lan Archive on lore.kernel.org
 help / color / mirror / Atom feed
From: Alexander Lobakin <alexandr.lobakin@intel.com>
To: intel-wired-lan@osuosl.org
Subject: [Intel-wired-lan] [PATCH net-next 17/19] iecm: implement cloud filters
Date: Fri, 28 Jan 2022 20:38:09 +0100	[thread overview]
Message-ID: <20220128193809.30521-1-alexandr.lobakin@intel.com> (raw)
In-Reply-To: <20220128001009.721392-18-alan.brady@intel.com>

From: Alan Brady <alan.brady@intel.com>
Date: Thu, 27 Jan 2022 16:10:07 -0800

> This gives iecm the ability to deal with cloud filters and other traffic
> classes.
> 
> Signed-off-by: Phani Burra <phani.r.burra@intel.com>
> Signed-off-by: Joshua Hay <joshua.a.hay@intel.com>
> Signed-off-by: Madhu Chittim <madhu.chittim@intel.com>
> Signed-off-by: Pavan Kumar Linga <pavan.kumar.linga@intel.com>
> Signed-off-by: Alan Brady <alan.brady@intel.com>
> ---
>  drivers/net/ethernet/intel/iecm/iecm_lib.c    | 900 +++++++++++++++++-
>  .../net/ethernet/intel/iecm/iecm_virtchnl.c   |  68 ++
>  drivers/net/ethernet/intel/include/iecm.h     |  25 +
>  3 files changed, 992 insertions(+), 1 deletion(-)
> 
> diff --git a/drivers/net/ethernet/intel/iecm/iecm_lib.c b/drivers/net/ethernet/intel/iecm/iecm_lib.c
> index 35c0cbc42ebe..d11413cb438c 100644
> --- a/drivers/net/ethernet/intel/iecm/iecm_lib.c
> +++ b/drivers/net/ethernet/intel/iecm/iecm_lib.c
> @@ -43,9 +43,16 @@ static int iecm_get_vport_index(struct iecm_adapter *adapter,
>   */
>  bool iecm_is_feature_ena(struct iecm_vport *vport, netdev_features_t feature)
>  {
> +	struct iecm_channel_config *ch_config;
>  	bool ena;
>  
>  	switch (feature) {
> +	case NETIF_F_HW_TC:
> +		ch_config = &vport->adapter->config_data.ch_config;
> +		ena = (vport->netdev->features & feature) &&
> +			(ch_config->num_tc > IECM_START_CHNL_TC) &&
> +			(ch_config->tc_running);
> +		break;
>  	default:
>  		ena = vport->netdev->features & feature;
>  		break;
> @@ -53,6 +60,23 @@ bool iecm_is_feature_ena(struct iecm_vport *vport, netdev_features_t feature)
>  	return ena;
>  }
>  
> +/**
> + * iecm_is_adq_v2_ena - Determine whether ADQ V2 is enabled
> + * @vport: virtual port struct
> + *
> + * This function returns true based on negotiated capability ADQ_V2
> + * if set and ADQ enabled
> + */
> +static bool iecm_is_adq_v2_ena(struct iecm_vport *vport)
> +{
> +	/* iecm_is_feature_ena tells if the netdev flag is set and adq is
> +	 * enabled
> +	 */
> +	return (iecm_is_feature_ena(vport, NETIF_F_HW_TC) &&
> +		iecm_is_cap_ena(vport->adapter, IECM_OTHER_CAPS,
> +				VIRTCHNL2_CAP_ADQ));

The outermost braces are redundant.

> +}
> +
>  /**
>   * iecm_is_vlan_cap_ena - Check if VLAN capability is enabled
>   * @adapter: pointer to adapter
> @@ -946,6 +970,28 @@ static int iecm_get_free_slot(void *array, int size, int curr)
>  	return next;
>  }
>  
> +/**
> + * iecm_remove_cloud_filters - Remove all cloud filters
> + * @vport: vport structure
> + */
> +static void iecm_remove_cloud_filters(struct iecm_vport *vport)
> +{
> +	struct iecm_adapter *adapter = vport->adapter;
> +	struct iecm_cloud_filter_config *cf_config;
> +
> +	cf_config = &adapter->config_data.cf_config;
> +	if (!list_empty(&cf_config->cloud_filter_list)) {
> +		struct iecm_cloud_filter *cf;
> +
> +		spin_lock_bh(&adapter->cloud_filter_list_lock);
> +		list_for_each_entry(cf, &cf_config->cloud_filter_list, list) {
> +			cf->remove = true;
> +		}

One-liner, braces are redundant.

> +		spin_unlock_bh(&adapter->cloud_filter_list_lock);
> +		iecm_send_add_del_cloud_filter_msg(vport, false);
> +	}

	if (list_empty())
		return;

-1 level.

> +}
> +
>  /**
>   * iecm_remove_vlan_filters - Remove all vlan filters
>   * @vport: vport structure
> @@ -1044,8 +1090,14 @@ static void iecm_vport_stop(struct iecm_vport *vport)
>  	if (test_and_clear_bit(__IECM_DEL_QUEUES,
>  			       vport->adapter->flags))
>  		iecm_send_delete_queues_msg(vport);
> -	if (!test_bit(__IECM_REL_RES_IN_PROG, adapter->flags))
> +	/* In function reset/rmmod path we call unregister_netdev which
> +	 * internally calls delete cloud filters. We remove cloud filters only
> +	 * when the interface goes down
> +	 */
> +	if (!test_bit(__IECM_REL_RES_IN_PROG, adapter->flags)) {
> +		iecm_remove_cloud_filters(vport);
>  		iecm_remove_vlan_filters(vport);
> +	}
>  
>  	iecm_remove_fdir_filters(vport);
>  
> @@ -1258,6 +1310,28 @@ static void iecm_restore_vlans(struct iecm_vport *vport)
>  		iecm_set_all_vlans(vport);
>  }
>  
> +/**
> + * iecm_restore_cloud_filters - Restore cloud filters
> + * @vport: vport structure
> + */
> +static void iecm_restore_cloud_filters(struct iecm_vport *vport)
> +{
> +	struct iecm_adapter *adapter = vport->adapter;
> +	struct iecm_cloud_filter_config *cf_config;
> +
> +	cf_config = &adapter->config_data.cf_config;
> +	if (!list_empty(&cf_config->cloud_filter_list)) {
> +		struct iecm_cloud_filter *cf;
> +
> +		spin_lock_bh(&adapter->cloud_filter_list_lock);
> +		list_for_each_entry(cf, &cf_config->cloud_filter_list, list) {
> +			cf->add = true;
> +		}

Same here for braces.

> +		spin_unlock_bh(&adapter->cloud_filter_list_lock);
> +		iecm_send_add_del_cloud_filter_msg(vport, true);
> +	}

Same here for reducing indent level.

> +}
> +
>  /**
>   * iecm_restore_fdir_filters - Restore all Flow Director filters
>   * @vport: vport structure
> @@ -1302,6 +1376,10 @@ static void iecm_restore_features(struct iecm_vport *vport)
>  			dev_info(&adapter->pdev->dev, "Failed to restore promiscuous settings\n");
>  	}
>  
> +	/* Restore cloud filters if ADQ is enabled */
> +	if (iecm_is_feature_ena(vport, NETIF_F_HW_TC))
> +		iecm_restore_cloud_filters(vport);
> +
>  	if (iecm_is_cap_ena(adapter, IECM_OTHER_CAPS, VIRTCHNL2_CAP_FDIR))
>  		iecm_restore_fdir_filters(vport);
>  }
> @@ -2088,6 +2166,8 @@ int iecm_probe(struct pci_dev *pdev,
>  	spin_lock_init(&adapter->vlan_list_lock);
>  	spin_lock_init(&adapter->adv_rss_list_lock);
>  	spin_lock_init(&adapter->fdir_fltr_list_lock);
> +	INIT_LIST_HEAD(&adapter->config_data.cf_config.cloud_filter_list);
> +	INIT_LIST_HEAD(&adapter->config_data.cf_config.block_cb_list);
>  	INIT_LIST_HEAD(&adapter->config_data.mac_filter_list);
>  	INIT_LIST_HEAD(&adapter->config_data.vlan_filter_list);
>  	INIT_LIST_HEAD(&adapter->config_data.adv_rss_list);
> @@ -2389,6 +2469,810 @@ static int iecm_offload_txtime(struct iecm_vport *vport,
>  	return -EOPNOTSUPP;
>  }
>  
> +/**
> + * iecm_is_vlan_tc_filter_allowed - allowed to add tc-filter using VLAN
> + * @vport: vport structure
> + * @vlan: VLAN to verify
> + *
> + * Using specified "vlan" ID, there must be active VLAN filter in VF's
> + * MAC-VLAN filter list.
> + */
> +static bool
> +iecm_is_vlan_tc_filter_allowed(struct iecm_vport *vport,
> +			       struct iecm_vlan *vlan)
> +{
> +	struct iecm_vlan_filter *f;
> +	bool allowed;
> +
> +	spin_lock_bh(&vport->adapter->vlan_list_lock);
> +	f = iecm_find_vlan(vport, vlan);
> +	allowed = (f && !f->add && !f->remove);

Redundant braces here.

> +	spin_unlock_bh(&vport->adapter->vlan_list_lock);
> +	return allowed;
> +}
> +
> +/**
> + * iecm_is_mac_tc_filter_allowed - allowed to add tc-filter using MAC addr
> + * @vport: vport structure
> + * @macaddr: MAC address
> + *
> + * Using specified MAC address, there must be active MAC filter in
> + * MAC filter list.
> + */
> +static bool
> +iecm_is_mac_tc_filter_allowed(struct iecm_vport *vport, const u8 *macaddr)
> +{
> +	struct iecm_adapter *adapter = vport->adapter;
> +	struct iecm_mac_filter *f;
> +	bool allowed;
> +
> +	spin_lock_bh(&adapter->mac_filter_list_lock);
> +	f = iecm_find_mac_filter(vport, macaddr);
> +	allowed = (f && !f->add && !f->remove);

Same here.

> +	spin_unlock_bh(&adapter->mac_filter_list_lock);
> +	return allowed;
> +}
> +
> +/**
> + * iecm_parse_keyid - Parse keyid
> + * @rule: Flow rule structure
> + * @field_flags: Cloud filter flags
> + */
> +static void  iecm_parse_keyid(struct flow_rule *rule, u8 *field_flags)
> +{
> +	struct flow_match_enc_keyid match;
> +
> +	flow_rule_match_enc_keyid(rule, &match);
> +
> +	if (match.mask->keyid != 0)
> +		*field_flags |= IECM_CLOUD_FIELD_TEN_ID;
> +}
> +
> +/**
> + * iecm_parse_flow_type - Parse flow type based on L2 and L3 protocols
> + * @vport: vport structure
> + * @rule: rule from user
> + * @cf: Structure for the virtchnl filter
> + * @filter: Structure for the cloud filter
> + *
> + * Return 0 on success, negative on failure
> + */
> +static int
> +iecm_parse_flow_type(struct iecm_vport *vport,
> +		     struct flow_rule *rule, struct virtchnl_filter *cf,
> +		     struct iecm_cloud_filter *filter)
> +{
> +	struct iecm_adapter *adapter = vport->adapter;
> +	enum virtchnl_flow_type flow_type;
> +	struct flow_match_basic match;
> +	u16 n_proto_mask = 0;
> +	u16 n_proto_key = 0;
> +	u16 n_proto = 0;
> +	u8 ip_proto = 0;
> +
> +	flow_rule_match_basic(rule, &match);
> +
> +	n_proto_key = ntohs(match.key->n_proto);
> +	n_proto_mask = ntohs(match.mask->n_proto);
> +
> +	if (n_proto_key == ETH_P_ALL) {
> +		n_proto_key = 0;
> +		n_proto_mask = 0;
> +	}

	n_proto_key = ntohs();
	if (n_proto_key != ETH_P_ALL)
		n_proto_mask = ntohs();

> +	n_proto = n_proto_key & n_proto_mask;
> +	if (n_proto != ETH_P_IP && n_proto != ETH_P_IPV6)
> +		return -EINVAL;
> +
> +	if (iecm_is_cap_ena(adapter, IECM_OTHER_CAPS, VIRTCHNL2_CAP_ADQ)) {
> +		if (match.key->ip_proto != IPPROTO_TCP &&
> +		    match.key->ip_proto != IPPROTO_UDP) {
> +			dev_err(&adapter->pdev->dev,
> +				"Only TCP or UDP transport is supported\n");
> +			return -EINVAL;
> +		}
> +	} else if (match.key->ip_proto != IPPROTO_TCP) {
> +		dev_err(&adapter->pdev->dev,
> +			"Only TCP transport is supported\n");
> +		return -EINVAL;
> +	}
> +	ip_proto = match.key->ip_proto;
> +
> +	/* determine VIRTCHNL flow_type based on L3 and L4 protocol */
> +	if (n_proto == ETH_P_IP)
> +		flow_type = (ip_proto == IPPROTO_TCP) ?
> +			     VIRTCHNL_TCP_V4_FLOW :
> +			     VIRTCHNL_UDP_V4_FLOW;
> +	else
> +		flow_type = (ip_proto == IPPROTO_TCP) ?
> +			     VIRTCHNL_TCP_V6_FLOW :
> +			     VIRTCHNL_UDP_V6_FLOW;
> +	cf->flow_type = flow_type;
> +	filter->f.flow_type = flow_type;
> +
> +	return 0;
> +}
> +
> +/**
> + * iecm_parse_ether_header - Parse ethernet header fields
> + * @vport: vport structure
> + * @field_flags: Cloud filter flags
> + * @d_spec: Virtchnl structure for L4 specs
> + * @m_spec: Virtchnl structure for L4 specs
> + * @rule: Flow rule structure
> + *
> + * Return 0 on success, negative on failure
> + */
> +static int
> +iecm_parse_ether_header(struct iecm_vport *vport, u8 *field_flags,
> +			struct virtchnl_l4_spec *d_spec,
> +			struct virtchnl_l4_spec *m_spec,
> +			struct flow_rule *rule)
> +{
> +	struct iecm_adapter *adapter = vport->adapter;
> +	struct flow_match_eth_addrs match;
> +	bool adv_adq_ena;
> +
> +	adv_adq_ena = iecm_is_cap_ena(adapter, IECM_OTHER_CAPS,
> +				      VIRTCHNL2_CAP_ADQ);
> +
> +	flow_rule_match_eth_addrs(rule, &match);
> +
> +	/* use is_broadcast and is_zero to check for all 0xf or 0 */
> +	if (!is_zero_ether_addr(match.mask->dst)) {
> +		if (adv_adq_ena || is_broadcast_ether_addr(match.mask->dst)) {
> +			*field_flags |= IECM_CLOUD_FIELD_OMAC;
> +		} else {
> +			dev_err(&adapter->pdev->dev, "Bad ether dest mask %pM\n",
> +				match.mask->dst);
> +			return -EINVAL;
> +		}
> +	}
> +
> +	if (!is_zero_ether_addr(match.mask->src)) {
> +		if (adv_adq_ena || is_broadcast_ether_addr(match.mask->src)) {
> +			*field_flags |= IECM_CLOUD_FIELD_IMAC;
> +		} else {
> +			dev_err(&adapter->pdev->dev, "Bad ether src mask %pM\n",
> +				match.mask->src);
> +			return -EINVAL;
> +		}
> +	}
> +
> +	if (!is_zero_ether_addr(match.key->dst)) {
> +		if (!iecm_is_mac_tc_filter_allowed(adapter->vports[0],
> +						   match.key->dst)) {
> +			dev_err(&adapter->pdev->dev,
> +				"Dest MAC %pM doesn't belong to this device\n",
> +				match.key->dst);
> +			return -EINVAL;
> +		}
> +
> +		if (is_valid_ether_addr(match.key->dst) ||
> +		    is_multicast_ether_addr(match.key->dst)) {
> +			/* set the mask if a valid dst_mac address */
> +			if (adv_adq_ena)
> +				ether_addr_copy(m_spec->dst_mac,
> +						match.mask->dst);
> +			else
> +				eth_broadcast_addr(m_spec->dst_mac);
> +			ether_addr_copy(d_spec->dst_mac,
> +					match.key->dst);
> +		}
> +	}
> +
> +	if (!is_zero_ether_addr(match.key->src))
> +		if (is_valid_ether_addr(match.key->src) ||
> +		    is_multicast_ether_addr(match.key->src)) {
> +			/* set the mask if a valid src_mac address */
> +			if (adv_adq_ena) {
> +				ether_addr_copy(m_spec->src_mac,
> +						match.mask->src);
> +			} else {
> +				eth_broadcast_addr(m_spec->src_mac);
> +			}
> +			ether_addr_copy(d_spec->src_mac,
> +					match.key->src);
> +		}

All previous ifs had braces, and it way okay since we have multiple
nested if-elses, but here we don't have them.
Please either add them here or remove all the way above to keep the
code style consistent.

> +	return 0;
> +}
> +
> +/**
> + * iecm_parse_vlan_header - Parse vlan header fields
> + * @vport: vport structure
> + * @field_flags: Cloud filter flags
> + * @d_spec: Virtchnl structure for L4 specs
> + * @m_spec: Virtchnl structure for L4 specs
> + * @rule: Flow rule structure
> + *
> + * Return 0 on success, negative on failure
> + */
> +static int
> +iecm_parse_vlan_header(struct iecm_vport *vport, u8 *field_flags,
> +		       struct virtchnl_l4_spec *d_spec,
> +		       struct virtchnl_l4_spec *m_spec,
> +		       struct flow_rule *rule)
> +{
> +	struct iecm_adapter *adapter = vport->adapter;
> +	struct flow_match_vlan match;
> +
> +	flow_rule_match_vlan(rule, &match);
> +	if (match.mask->vlan_id) {
> +		u16 vid = match.key->vlan_id & VLAN_VID_MASK;
> +		struct iecm_vlan vlan;
> +
> +		vlan = IECM_VLAN(vid, ETH_P_8021Q);
> +
> +		if (match.mask->vlan_id != VLAN_VID_MASK) {
> +			dev_err(&adapter->pdev->dev, "Bad vlan mask %u\n",
> +				match.mask->vlan_id);
> +			return -EINVAL;
> +		}
> +		if (!iecm_is_vlan_tc_filter_allowed(vport, &vlan)) {
> +			dev_err(&adapter->pdev->dev,
> +				"VLAN %u doesn't belong to this VF\n",
> +				vid);
> +			return -EINVAL;
> +		}
> +		*field_flags |= IECM_CLOUD_FIELD_IVLAN;
> +		m_spec->vlan_id = cpu_to_be16(match.mask->vlan_id);
> +		d_spec->vlan_id = cpu_to_be16(match.key->vlan_id);
> +	}

	if (!vlan_id)
		return 0;

-1 level.

> +	return 0;
> +}
> +
> +/**
> + * iecm_parse_ipv4_header - Parse ipv4 header fields
> + * @vport: vport structure
> + * @field_flags: Cloud filter flags
> + * @d_spec: Virtchnl structure for L4 specs
> + * @m_spec: Virtchnl structure for L4 specs
> + * @rule: Flow rule structure
> + *
> + * Return 0 on success, negative on failure
> + */
> +static int
> +iecm_parse_ipv4_header(struct iecm_vport *vport, u8 *field_flags,
> +		       struct virtchnl_l4_spec *d_spec,
> +		       struct virtchnl_l4_spec *m_spec,
> +		       struct flow_rule *rule)
> +{
> +	struct iecm_adapter *adapter = vport->adapter;
> +	struct flow_match_ipv4_addrs match;
> +	bool adv_adq_ena;
> +
> +	adv_adq_ena = iecm_is_cap_ena(adapter, IECM_OTHER_CAPS,
> +				      VIRTCHNL2_CAP_ADQ);
> +
> +	flow_rule_match_ipv4_addrs(rule, &match);
> +
> +	if (*field_flags & IECM_CLOUD_FIELD_TEN_ID) {
> +		dev_info(&adapter->pdev->dev,
> +			 "Tenant id not allowed for ip filter\n");
> +		return -EINVAL;
> +	}
> +
> +	if (match.mask->dst) {
> +		if (adv_adq_ena || match.mask->dst == cpu_to_be32(0xffffffff)) {
> +			*field_flags |= IECM_CLOUD_FIELD_IIP;
> +		} else {
> +			dev_err(&adapter->pdev->dev, "Bad ip dst mask 0x%08x\n",
> +				be32_to_cpu(match.mask->dst));
> +			return -EINVAL;
> +		}
> +	}
> +
> +	if (match.mask->src) {
> +		if (adv_adq_ena || match.mask->src == cpu_to_be32(0xffffffff)) {
> +			*field_flags |= IECM_CLOUD_FIELD_IIP;
> +		} else {
> +			dev_err(&adapter->pdev->dev, "Bad ip src mask 0x%08x\n",
> +				be32_to_cpu(match.mask->dst));
> +			return -EINVAL;
> +		}
> +	}
> +
> +	if (match.key->dst) {
> +		if (adv_adq_ena)
> +			m_spec->dst_ip[0] = match.mask->dst;
> +		else
> +			m_spec->dst_ip[0] = cpu_to_be32(0xffffffff);
> +		d_spec->dst_ip[0] = match.key->dst;
> +	}
> +
> +	if (match.key->src) {
> +		if (adv_adq_ena)
> +			m_spec->src_ip[0] = match.mask->src;
> +		else
> +			m_spec->src_ip[0] = cpu_to_be32(0xffffffff);
> +		d_spec->src_ip[0] = match.key->src;
> +	}
> +	return 0;
> +}
> +
> +/**
> + * iecm_parse_ipv6_header - Parse ipv6 header fields
> + * @vport: vport structure
> + * @field_flags: Cloud filter flags
> + * @d_spec: Virtchnl structure for L4 specs
> + * @m_spec: Virtchnl structure for L4 specs
> + * @rule: Flow rule structure
> + *
> + * Return 0 on success, negative on failure
> + */
> +static int
> +iecm_parse_ipv6_header(struct iecm_vport *vport, u8 *field_flags,
> +		       struct virtchnl_l4_spec *d_spec,
> +		       struct virtchnl_l4_spec *m_spec,
> +		       struct flow_rule *rule)
> +{
> +	struct iecm_adapter *adapter = vport->adapter;
> +	struct flow_match_ipv6_addrs match;
> +	int i;
> +
> +	flow_rule_match_ipv6_addrs(rule, &match);
> +
> +	/* validate mask, make sure it is not IPV6_ADDR_ANY */
> +	if (ipv6_addr_any(&match.mask->dst)) {
> +		dev_err(&adapter->pdev->dev, "Bad ipv6 dst mask 0x%02x\n",
> +			IPV6_ADDR_ANY);
> +		return -EINVAL;
> +	}
> +
> +	/* src and dest IPv6 address should not be LOOPBACK
> +	 * (0:0:0:0:0:0:0:1) which can be represented as ::1
> +	 */
> +	if (ipv6_addr_loopback(&match.key->dst) ||
> +	    ipv6_addr_loopback(&match.key->src)) {
> +		dev_err(&adapter->pdev->dev,
> +			"ipv6 addr should not be loopback\n");
> +		return -EINVAL;
> +	}
> +
> +	if (!ipv6_addr_any(&match.mask->dst) ||
> +	    !ipv6_addr_any(&match.mask->src))
> +		*field_flags |= IECM_CLOUD_FIELD_IIP;
> +
> +	/* copy dest IPv6 mask and address */
> +	if (iecm_is_cap_ena(adapter, IECM_OTHER_CAPS, VIRTCHNL2_CAP_ADQ)) {
> +		memcpy(&m_spec->dst_ip, &match.mask->dst.s6_addr32,
> +		       sizeof(m_spec->dst_ip));
> +	} else {
> +		for (i = 0; i < 4; i++)
> +			m_spec->dst_ip[i] = cpu_to_be32(0xffffffff);
> +	}

One-liners, no braces needed for both `if` and `else`.

> +	memcpy(&d_spec->dst_ip, &match.key->dst.s6_addr32,
> +	       sizeof(d_spec->dst_ip));
> +
> +	/* copy source IPv6 mask and address */
> +	if (iecm_is_cap_ena(adapter, IECM_OTHER_CAPS, VIRTCHNL2_CAP_ADQ)) {
> +		memcpy(&m_spec->src_ip, &match.mask->src.s6_addr32,
> +		       sizeof(m_spec->src_ip));
> +	} else {
> +		for (i = 0; i < 4; i++)
> +			m_spec->src_ip[i] = cpu_to_be32(0xffffffff);
> +	}

Same here.

> +	memcpy(&d_spec->src_ip, &match.key->src.s6_addr32,
> +	       sizeof(d_spec->src_ip));
> +
> +	return 0;
> +}
> +
> +/**
> + * iecm_parse_l4_header - Parse l4 header fields
> + * @vport: vport structure
> + * @d_spec: Virtchnl structure for L4 specs
> + * @m_spec: Virtchnl structure for L4 specs
> + * @rule: Flow rule structure
> + *
> + * Return 0 on success, negative on failure
> + */
> +static int
> +iecm_parse_l4_header(struct iecm_vport *vport,
> +		     struct virtchnl_l4_spec *d_spec,
> +		     struct virtchnl_l4_spec *m_spec,
> +		     struct flow_rule *rule)
> +{
> +	struct iecm_adapter *adapter = vport->adapter;
> +	struct flow_match_ports match;
> +
> +	flow_rule_match_ports(rule, &match);
> +
> +	if (match.key->dst) {
> +		if (iecm_is_cap_ena(adapter, IECM_OTHER_CAPS,
> +				    VIRTCHNL2_CAP_ADQ) ||
> +		    match.mask->dst == cpu_to_be16(0xffff)) {
> +			m_spec->dst_port = match.mask->dst;
> +			d_spec->dst_port = match.key->dst;
> +		} else {
> +			dev_err(&adapter->pdev->dev, "Bad dst port mask %u\n",
> +				be16_to_cpu(match.mask->dst));
> +			return -EINVAL;
> +		}
> +	}
> +
> +	if (match.key->src) {
> +		if (iecm_is_cap_ena(adapter, IECM_OTHER_CAPS,
> +				    VIRTCHNL2_CAP_ADQ) ||
> +		    match.mask->src == cpu_to_be16(0xffff)) {
> +			m_spec->src_port = match.mask->src;
> +			d_spec->src_port = match.key->src;
> +		} else {
> +			dev_err(&adapter->pdev->dev, "Bad src port mask %u\n",
> +				be16_to_cpu(match.mask->src));
> +			return -EINVAL;
> +		}
> +	}
> +	return 0;
> +}
> +
> +/**
> + * iecm_parse_cls_flower - Parse tc flower filters provided by kernel
> + * @vport: vport structure
> + * @f: pointer to struct flow_cls_offload
> + * @filter: pointer to cloud filter structure
> + */
> +static int iecm_parse_cls_flower(struct iecm_vport *vport,
> +				 struct flow_cls_offload *f,
> +				 struct iecm_cloud_filter *filter)
> +{
> +	struct flow_rule *rule = flow_cls_offload_flow_rule(f);
> +	struct iecm_adapter *adapter = vport->adapter;
> +	struct virtchnl_l4_spec *d_spec, *m_spec;
> +	struct virtchnl_filter *cf = &filter->f;
> +	struct flow_dissector *dissector;
> +	u8 field_flags = 0;
> +	u16 addr_type = 0;
> +	int err;
> +
> +	dissector = rule->match.dissector;
> +	if (dissector->used_keys &
> +	    ~(BIT(FLOW_DISSECTOR_KEY_CONTROL) |
> +	      BIT(FLOW_DISSECTOR_KEY_BASIC) |
> +	      BIT(FLOW_DISSECTOR_KEY_ETH_ADDRS) |
> +	      BIT(FLOW_DISSECTOR_KEY_VLAN) |
> +	      BIT(FLOW_DISSECTOR_KEY_IPV4_ADDRS) |
> +	      BIT(FLOW_DISSECTOR_KEY_IPV6_ADDRS) |
> +	      BIT(FLOW_DISSECTOR_KEY_ENC_KEYID) |
> +	      BIT(FLOW_DISSECTOR_KEY_PORTS))) {
> +		dev_err(&adapter->pdev->dev, "Unsupported key used: 0x%x\n",
> +			dissector->used_keys);
> +		return -EOPNOTSUPP;
> +	}
> +	if (flow_rule_match_key(rule, FLOW_DISSECTOR_KEY_ENC_KEYID))
> +		iecm_parse_keyid(rule, &field_flags);
> +
> +	/* even though following code refers as "tcp_sec", it is not
> +	 * just for TCP but a generic struct representing
> +	 * L2, L3 + L4 fields if specified
> +	 */
> +	m_spec = &cf->mask.tcp_spec;
> +	d_spec = &cf->data.tcp_spec;
> +
> +	/* determine flow type, TCP/UDP_V4[6]_FLOW based on
> +	 * L2 proto (aka ETH proto) and L3 proto (aka IP_PROTO)
> +	 */
> +	if (flow_rule_match_key(rule, FLOW_DISSECTOR_KEY_BASIC)) {
> +		err = iecm_parse_flow_type(vport, rule, cf, filter);
> +		if (err)
> +			return err;
> +	}
> +
> +	/* process Ethernet header fields */
> +	if (flow_rule_match_key(rule, FLOW_DISSECTOR_KEY_ETH_ADDRS)) {
> +		err = iecm_parse_ether_header(vport, &field_flags,
> +					      d_spec, m_spec, rule);
> +		if (err)
> +			return err;
> +	}
> +
> +	/* process VLAN header for single VLAN (type could be S/C-tag) */
> +	if (flow_rule_match_key(rule, FLOW_DISSECTOR_KEY_VLAN)) {
> +		err = iecm_parse_vlan_header(vport, &field_flags,
> +					     d_spec, m_spec, rule);
> +		if (err)
> +			return err;
> +	}
> +
> +	if (flow_rule_match_key(rule, FLOW_DISSECTOR_KEY_CONTROL)) {
> +		struct flow_match_control match;
> +
> +		flow_rule_match_control(rule, &match);
> +		addr_type = match.key->addr_type;
> +	}
> +
> +	/* process IPv4 header */
> +	if (addr_type == FLOW_DISSECTOR_KEY_IPV4_ADDRS) {
> +		err = iecm_parse_ipv4_header(vport, &field_flags,
> +					     d_spec, m_spec, rule);
> +		if (err)
> +			return err;
> +	}
> +
> +	/* process IPv6 header */
> +	if (addr_type == FLOW_DISSECTOR_KEY_IPV6_ADDRS) {
> +		err = iecm_parse_ipv6_header(vport, &field_flags,
> +					     d_spec, m_spec, rule);
> +		if (err)
> +			return err;
> +	}
> +
> +	/* process L4 header, supported L4 protocols are TCP and UDP */
> +	if (flow_rule_match_key(rule, FLOW_DISSECTOR_KEY_PORTS)) {
> +		err = iecm_parse_l4_header(vport, d_spec, m_spec, rule);
> +		if (err)
> +			return err;
> +	}
> +	cf->field_flags = field_flags;
> +
> +	return 0;
> +}
> +
> +/**
> + * iecm_handle_tclass - Forward to a traffic class on the device
> + * @vport: vport structure
> + * @tc: traffic class index on the device
> + * @filter: pointer to cloud filter structure
> + *
> + * Return 0 on success, negative on failure
> + */
> +static int iecm_handle_tclass(struct iecm_vport *vport, int tc,
> +			      struct iecm_cloud_filter *filter)
> +{
> +	struct iecm_adapter *adapter = vport->adapter;
> +
> +	if (tc == 0)
> +		return 0;
> +	if ((!iecm_is_adq_v2_ena(vport)) &&
> +	    !filter->f.data.tcp_spec.dst_port) {
> +		dev_err(&adapter->pdev->dev,
> +			"Specify destination port to redirect to traffic class other than TC0\n");
> +		return -EINVAL;
> +	}
> +	/* redirect to a traffic class on the same device */
> +	filter->f.action = VIRTCHNL_ACTION_TC_REDIRECT;
> +	filter->f.action_meta = tc;
> +	return 0;
> +}
> +
> +/* iecm_find_cf - Find the cloud filter in the list
> + * @vport: vport structure
> + * @cookie: filter specific cookie
> + *
> + * Returns pointer to the filter object or NULL. Must be called while holding
> + * cloud_filter_list_lock.
> + */
> +static struct iecm_cloud_filter *iecm_find_cf(struct iecm_vport *vport,
> +					      unsigned long *cookie)
> +{
> +	struct iecm_adapter *adapter = vport->adapter;
> +	struct iecm_cloud_filter *filter = NULL;
> +
> +	if (!cookie)
> +		return NULL;
> +
> +	list_for_each_entry(filter,
> +			    &adapter->config_data.cf_config.cloud_filter_list,
> +			    list) {
> +		if (!memcmp(cookie, &filter->cookie, sizeof(filter->cookie)))
> +			return filter;
> +	}

Redundant braces round single statement.

> +	return NULL;
> +}
> +
> +/**
> + * iecm_configure_clsflower - Add tc flower filters
> + * @vport: vport structure
> + * @cls_flower: Pointer to struct flow_cls_offload
> + *
> + * Return 0 on success, negative on failure
> + */
> +static int iecm_configure_clsflower(struct iecm_vport *vport,
> +				    struct flow_cls_offload *cls_flower)
> +{
> +	struct iecm_adapter *adapter = vport->adapter;
> +	struct iecm_user_config_data *config_data;
> +	struct iecm_cloud_filter *filter = NULL;
> +	int err;
> +	int tc;
> +
> +	config_data = &adapter->config_data;
> +	tc = tc_classid_to_hwtc(vport->netdev, cls_flower->classid);
> +	if (tc < 0) {
> +		dev_err(&adapter->pdev->dev, "Invalid traffic class\n");
> +		return -EINVAL;
> +	}
> +
> +#define IECM_MAX_CLOUD_ADQ_FILTERS	128
> +
> +	if (config_data->cf_config.num_cloud_filters >=
> +						IECM_MAX_CLOUD_ADQ_FILTERS) {
> +		dev_err(&adapter->pdev->dev,
> +			"Unable to add filter (action is forward to TC), reached max allowed filters (%u)\n",
> +			IECM_MAX_CLOUD_ADQ_FILTERS);
> +		return -ENOSPC;
> +	}
> +
> +	/* bail out here if filter already exists */
> +	spin_lock_bh(&adapter->cloud_filter_list_lock);
> +	filter = iecm_find_cf(vport, &cls_flower->cookie);
> +	if (filter) {
> +		filter->remove = false;
> +		dev_err(&adapter->pdev->dev, "Failed to add TC Flower filter, it already exists\n");
> +		spin_unlock_bh(&adapter->cloud_filter_list_lock);
> +		return -EEXIST;
> +	}
> +	spin_unlock_bh(&adapter->cloud_filter_list_lock);
> +
> +	filter = kzalloc(sizeof(*filter), GFP_KERNEL);
> +	if (!filter)
> +		return -ENOMEM;
> +
> +	filter->cookie = cls_flower->cookie;
> +
> +	/* set the mask to all zeroes to begin with */
> +	memset(&filter->f.mask.tcp_spec, 0, sizeof(struct virtchnl_l4_spec));
> +
> +	/* start out with flow type and eth type IPv4 to begin with */
> +	filter->f.flow_type = VIRTCHNL_TCP_V4_FLOW;
> +	err = iecm_parse_cls_flower(vport, cls_flower, filter);
> +	if (err)
> +		goto error;
> +
> +	err = iecm_handle_tclass(vport, tc, filter);
> +	if (err)
> +		goto error;
> +
> +	/* add filter to the list */
> +	spin_lock_bh(&adapter->cloud_filter_list_lock);
> +	list_add_tail(&filter->list, &config_data->cf_config.cloud_filter_list);
> +	filter->add = true;
> +	spin_unlock_bh(&adapter->cloud_filter_list_lock);
> +	err = iecm_send_add_del_cloud_filter_msg(vport, true);
> +	spin_lock_bh(&adapter->cloud_filter_list_lock);
> +	/* We have to find it again in case another thread has already
> +	 * deleted and kfreed it.
> +	 */
> +	filter = iecm_find_cf(vport, &cls_flower->cookie);
> +	if (filter && err) {
> +		list_del(&filter->list);
> +		spin_unlock_bh(&adapter->cloud_filter_list_lock);
> +		goto error;
> +	}
> +	spin_unlock_bh(&adapter->cloud_filter_list_lock);
> +
> +	config_data->cf_config.num_cloud_filters++;
> +error:
> +	if (err)
> +		kfree(filter);
> +	return err;
> +}
> +
> +/**
> + * iecm_delete_clsflower - Remove tc flower filters
> + * @vport: vport structure
> + * @cls_flower: Pointer to struct flow_cls_offload
> + *
> + * Return 0 on success, negative on failure
> + */
> +static int iecm_delete_clsflower(struct iecm_vport *vport,
> +				 struct flow_cls_offload *cls_flower)
> +{
> +	struct iecm_adapter *adapter = vport->adapter;
> +	struct iecm_cloud_filter *filter = NULL;
> +	int err = 0;
> +
> +	spin_lock_bh(&adapter->cloud_filter_list_lock);
> +	filter = iecm_find_cf(vport, &cls_flower->cookie);
> +	if (filter) {
> +		filter->remove = true;
> +		adapter->config_data.cf_config.num_cloud_filters--;
> +	} else if (adapter->config_data.cf_config.num_cloud_filters) {
> +		/* "num_cloud_filters" can become zero if egress qdisc is
> +		 * detached as per design, driver deletes related filters
> +		 * when qdisc is detached to avoid stale filters, hence
> +		 * num_cloud_filters can become zero. But since netdev
> +		 * layer doesn't know that filters are deleted by driver
> +		 * implictly when egress qdisc is deleted, it sees filters
> +		 * being present and "in_hw". User can request delete
> +		 * of specific filter of detach ingress qdisc - in either of
> +		 * those operation, filter(s) won't be found in driver cache,
> +		 * hence instead of returning, let this function return SUCCESS
> +		 * Returning of err as -EINVAL is only applicable when
> +		 * unable to find filter and num_cloud_filters is non-zero
> +		 */
> +		err = -EINVAL;
> +	}
> +	spin_unlock_bh(&adapter->cloud_filter_list_lock);
> +
> +	if (filter) {
> +		err = iecm_send_add_del_cloud_filter_msg(vport, false);
> +		spin_lock_bh(&adapter->cloud_filter_list_lock);
> +		/* It can happen that asynchronously the filter was already
> +		 * deleted from the list. Make sure it's still there and marked
> +		 * for remove under spinlock before actually trying to delete
> +		 * from list.
> +		 */
> +		filter = iecm_find_cf(vport, &cls_flower->cookie);
> +		if (filter) {
> +			list_del(&filter->list);
> +			kfree(filter);
> +		}
> +		spin_unlock_bh(&adapter->cloud_filter_list_lock);
> +	}

	if (!filter)
		return err;

	err = ...

-1 level.

> +	return err;
> +}
> +
> +/**
> + * iecm_setup_tc_cls_flower - flower classifier offloads
> + * @vport: vport structure
> + * @cls_flower: pointer to struct flow_cls_offload
> + *
> + * Return 0 on success, negative on failure
> + */
> +static int iecm_setup_tc_cls_flower(struct iecm_vport *vport,
> +				    struct flow_cls_offload *cls_flower)
> +{
> +	if (cls_flower->common.chain_index)
> +		return -EOPNOTSUPP;
> +
> +	switch (cls_flower->command) {
> +	case FLOW_CLS_REPLACE:
> +		return iecm_configure_clsflower(vport, cls_flower);
> +	case FLOW_CLS_DESTROY:
> +		return iecm_delete_clsflower(vport, cls_flower);
> +	case FLOW_CLS_STATS:
> +		return -EOPNOTSUPP;
> +	default:
> +		return -EINVAL;
> +	}
> +}
> +
> +/**
> + * iecm_setup_tc_block_cb - block callback for tc
> + * @type: type of offload
> + * @type_data: offload data
> + * @cb_priv: Private adapter structure
> + *
> + * This function is the block callback for traffic classes
> + * Return 0 on success, negative on failure
> + **/
> +static int iecm_setup_tc_block_cb(enum tc_setup_type type, void *type_data,
> +				  void *cb_priv)
> +{
> +	switch (type) {
> +	case TC_SETUP_CLSFLOWER:
> +		return iecm_setup_tc_cls_flower((struct iecm_vport *)cb_priv,
> +						(struct flow_cls_offload *)
> +						 type_data);

Just dereference them in separate variables and they will fit into
one line. There shouldn't be any spaces or line breaks after a cast.

> +	default:
> +		return -EOPNOTSUPP;
> +	}
> +}
> +
> +/**
> + * iecm_del_all_cloud_filters - delete all cloud filters on the traffic classes
> + * @vport: vport structure
> + *
> + * This function will loop through the list of cloud filters and deletes them.
> + **/
> +static void iecm_del_all_cloud_filters(struct iecm_vport *vport)
> +{
> +	struct iecm_adapter *adapter = vport->adapter;
> +	struct iecm_cloud_filter_config *cf_config;
> +	struct iecm_cloud_filter *cf, *cftmp;
> +
> +	cf_config = &adapter->config_data.cf_config;
> +	spin_lock_bh(&adapter->cloud_filter_list_lock);
> +	list_for_each_entry_safe(cf, cftmp,
> +				 &cf_config->cloud_filter_list,
> +				 list) {
> +		list_del(&cf->list);
> +		kfree(cf);
> +		cf_config->num_cloud_filters--;
> +	}
> +	spin_unlock_bh(&adapter->cloud_filter_list_lock);
> +}
> +
>  /**
>   * iecm_validate_tx_bandwidth - validate the max Tx bandwidth
>   * @vport: vport structure
> @@ -2596,6 +3480,7 @@ static int __iecm_setup_tc(struct iecm_vport *vport, void *type_data)
>  			netif_tx_stop_all_queues(netdev);
>  			netif_tx_disable(netdev);
>  			ret = iecm_send_disable_channels_msg(vport);
> +			iecm_del_all_cloud_filters(vport);
>  			netif_tx_start_all_queues(netdev);
>  			if (!test_bit(__IECM_REL_RES_IN_PROG, adapter->flags) &&
>  			    !ret) {
> @@ -2709,8 +3594,10 @@ static int iecm_setup_tc(struct net_device *netdev, enum tc_setup_type type,
>  {
>  	struct iecm_vport *vport = iecm_netdev_to_vport(netdev);
>  	struct iecm_adapter *adapter = vport->adapter;
> +	struct iecm_cloud_filter_config *cf_config;
>  	int err = 0;
>  
> +	cf_config = &adapter->config_data.cf_config;
>  	switch (type) {
>  	case TC_SETUP_QDISC_ETF:
>  		if (iecm_is_queue_model_split(vport->txq_model))
> @@ -2720,6 +3607,17 @@ static int iecm_setup_tc(struct net_device *netdev, enum tc_setup_type type,
>  					     type_data);
>  		break;
>  	case TC_SETUP_BLOCK:
> +		if (iecm_is_cap_ena(adapter, IECM_BASE_CAPS,
> +				    VIRTCHNL2_CAP_ADQ) ||
> +		    iecm_is_cap_ena(adapter, IECM_OTHER_CAPS,
> +				    VIRTCHNL2_CAP_ADQ)) {
> +			err =
> +			flow_block_cb_setup_simple((struct flow_block_offload *)
> +						    type_data,
> +						   &cf_config->block_cb_list,
> +						   iecm_setup_tc_block_cb,
> +						   vport, vport, true);
> +		}

Invert the condition, and there'll be no line wraps (esp. if you
assign casted @type_data into a separate var).

>  		break;
>  	case TC_SETUP_QDISC_MQPRIO:
>  		if (iecm_is_cap_ena(adapter, IECM_BASE_CAPS,
> diff --git a/drivers/net/ethernet/intel/iecm/iecm_virtchnl.c b/drivers/net/ethernet/intel/iecm/iecm_virtchnl.c
> index 5601846b4674..94af45c36866 100644
> --- a/drivers/net/ethernet/intel/iecm/iecm_virtchnl.c
> +++ b/drivers/net/ethernet/intel/iecm/iecm_virtchnl.c
> @@ -2731,6 +2731,74 @@ static int iecm_send_insert_vlan_msg(struct iecm_vport *vport, bool ena)
>  	return err;
>  }
>  
> +/**
> + * iecm_send_add_del_cloud_filter_msg: Send add/del cloud filter message
> + * @vport: vport structure
> + * @add: True to add, false to delete cloud filter
> + *
> + * Request the CP/PF to add/del cloud filters as specified by the user via
> + * tc tool
> + *
> + * Return 0 on success, negative on failure
> + **/
> +int iecm_send_add_del_cloud_filter_msg(struct iecm_vport *vport, bool add)
> +{
> +	struct iecm_adapter *adapter = vport->adapter;
> +	struct iecm_cloud_filter_config *cf_config;
> +	struct iecm_cloud_filter *cf;
> +	struct virtchnl_filter f;
> +	int len = 0, err = 0;
> +
> +	cf_config = &adapter->config_data.cf_config;
> +
> +	while (true) {
> +		bool process_fltr = false;
> +
> +		spin_lock_bh(&adapter->cloud_filter_list_lock);
> +		list_for_each_entry(cf, &cf_config->cloud_filter_list, list) {
> +			if (add && cf->add) {
> +				process_fltr = true;
> +				cf->add = false;
> +				f = cf->f;
> +				break;
> +			} else if (!add && cf->remove) {
> +				process_fltr = true;
> +				cf->remove = false;
> +				f = cf->f;
> +				break;
> +			}
> +		}

Redundant braces.

> +		spin_unlock_bh(&adapter->cloud_filter_list_lock);
> +
> +		/* Don't send mailbox message when there are no filters to add/del */
> +		if (!process_fltr)
> +			goto error;
> +
> +		if (add) {
> +			err = iecm_send_mb_msg(adapter, VIRTCHNL_OP_ADD_CLOUD_FILTER,
> +					       len, (u8 *)&f);
> +			if (err)
> +				goto error;
> +
> +			err = iecm_wait_for_event(adapter, IECM_VC_ADD_CLOUD_FILTER,
> +						  IECM_VC_ADD_CLOUD_FILTER_ERR);
> +		} else {
> +			err = iecm_send_mb_msg(adapter, VIRTCHNL_OP_DEL_CLOUD_FILTER,
> +					       len, (u8 *)&f);
> +			if (err)
> +				goto error;
> +
> +			err =
> +			iecm_min_wait_for_event(adapter, IECM_VC_DEL_CLOUD_FILTER,
> +						IECM_VC_DEL_CLOUD_FILTER_ERR);

Too long lines here.

> +		}
> +		if (err)
> +			break;
> +	}
> +error:
> +	return err;
> +}
> +
>  /**
>   * iecm_send_add_fdir_filter_msg: Send add Flow Director filter message
>   * @vport: vport structure
> diff --git a/drivers/net/ethernet/intel/include/iecm.h b/drivers/net/ethernet/intel/include/iecm.h
> index b0785684cc63..0aab41cf982c 100644
> --- a/drivers/net/ethernet/intel/include/iecm.h
> +++ b/drivers/net/ethernet/intel/include/iecm.h
> @@ -403,6 +403,28 @@ enum iecm_user_flags {
>  	__IECM_USER_FLAGS_NBITS,
>  };
>  
> +#define IECM_CLOUD_FIELD_OMAC		BIT(0)
> +#define IECM_CLOUD_FIELD_IMAC		BIT(1)
> +#define IECM_CLOUD_FIELD_IVLAN		BIT(2)
> +#define IECM_CLOUD_FIELD_TEN_ID		BIT(3)
> +#define IECM_CLOUD_FIELD_IIP		BIT(4)
> +
> +#define IECM_START_CHNL_TC		1
> +
> +struct iecm_cloud_filter {
> +	struct list_head list;
> +	struct virtchnl_filter f;
> +	unsigned long cookie;
> +	bool remove;		/* filter needs to be deleted */
> +	bool add;		/* filter needs to be added */
> +};
> +
> +struct iecm_cloud_filter_config {
> +	struct list_head block_cb_list;		/* need to pass this to stack */
> +	struct list_head cloud_filter_list;
> +	u16 num_cloud_filters;
> +};
> +
>  struct iecm_channel_config {
>  	struct virtchnl_channel_info ch_info[VIRTCHNL_MAX_ADQ_V2_CHANNELS];
>  	bool tc_running;
> @@ -536,6 +558,7 @@ struct iecm_ptype_state {
>  	bool outer_frag;
>  	u8 tunnel_state;
>  };
> +

Please move this newline into the patch where iecm_ptype_state was
introduced, it doesn't belong here.

>  /* User defined configuration values */
>  struct iecm_user_config_data {
>  	u32 num_req_tx_qs; /* user requested TX queues through ethtool */
> @@ -550,6 +573,7 @@ struct iecm_user_config_data {
>  	struct list_head vlan_filter_list;
>  	struct list_head adv_rss_list;
>  	struct iecm_fdir_fltr_config fdir_config;
> +	struct iecm_cloud_filter_config cf_config;
>  	struct iecm_channel_config ch_config;
>  };
>  
> @@ -853,6 +877,7 @@ void iecm_set_ethtool_ops(struct net_device *netdev);
>  void iecm_vport_set_hsplit(struct iecm_vport *vport, bool ena);
>  void iecm_add_del_ether_addrs(struct iecm_vport *vport, bool add, bool async);
>  int iecm_set_promiscuous(struct iecm_adapter *adapter);
> +int iecm_send_add_del_cloud_filter_msg(struct iecm_vport *vport, bool add);
>  int iecm_send_add_fdir_filter_msg(struct iecm_vport *vport);
>  int iecm_send_del_fdir_filter_msg(struct iecm_vport *vport);
>  int iecm_get_fdir_fltr_entry(struct iecm_vport *vport,
> -- 
> 2.33.0

Thanks,
Al


  reply	other threads:[~2022-01-28 19:38 UTC|newest]

Thread overview: 83+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2022-01-28  0:09 [Intel-wired-lan] [PATCH net-next 00/19] Add iecm and idpf Alan Brady
2022-01-28  0:09 ` [Intel-wired-lan] [PATCH net-next 01/19] virtchnl: Add new virtchnl2 ops Alan Brady
2022-02-02 22:13   ` Brady, Alan
2022-01-28  0:09 ` [Intel-wired-lan] [PATCH net-next 02/19] iecm: add basic module init and documentation Alan Brady
2022-01-28 11:56   ` Alexander Lobakin
2022-02-02 22:15     ` Brady, Alan
2022-02-01 19:44   ` Shannon Nelson
2022-02-03  3:08     ` Brady, Alan
2022-01-28  0:09 ` [Intel-wired-lan] [PATCH net-next 03/19] iecm: add probe and remove Alan Brady
2022-02-01 20:02   ` Shannon Nelson
2022-02-03  3:13     ` Brady, Alan
2022-01-28  0:09 ` [Intel-wired-lan] [PATCH net-next 04/19] iecm: add api_init and controlq init Alan Brady
2022-01-28 12:09   ` Alexander Lobakin
2022-02-02 22:16     ` Brady, Alan
2022-02-01 21:26   ` Shannon Nelson
2022-02-03  3:24     ` Brady, Alan
2022-02-03  3:40       ` Brady, Alan
2022-02-03  5:26         ` Shannon Nelson
2022-02-03 13:13       ` Alexander Lobakin
2022-01-28  0:09 ` [Intel-wired-lan] [PATCH net-next 05/19] iecm: add vport alloc and virtchnl messages Alan Brady
2022-01-28  4:19   ` kernel test robot
2022-01-28 12:39     ` Alexander Lobakin
2022-02-02 22:23       ` Brady, Alan
2022-01-28 12:32   ` Alexander Lobakin
2022-02-02 22:21     ` Brady, Alan
2022-02-03 13:23       ` Alexander Lobakin
2022-01-28  0:09 ` [Intel-wired-lan] [PATCH net-next 06/19] iecm: add virtchnl messages for queues Alan Brady
2022-01-28 13:03   ` Alexander Lobakin
2022-02-02 22:48     ` Brady, Alan
2022-02-03 10:08       ` Maciej Fijalkowski
2022-02-03 14:09       ` Alexander Lobakin
2022-01-28  0:09 ` [Intel-wired-lan] [PATCH net-next 07/19] iecm: finish virtchnl messages Alan Brady
2022-01-28 13:19   ` Alexander Lobakin
2022-02-02 23:06     ` Brady, Alan
2022-02-03 15:05       ` Alexander Lobakin
2022-02-03 15:16         ` Maciej Fijalkowski
2022-01-28  0:09 ` [Intel-wired-lan] [PATCH net-next 08/19] iecm: add interrupts and configure netdev Alan Brady
2022-01-28 13:34   ` Alexander Lobakin
2022-02-02 23:17     ` Brady, Alan
2022-02-03 15:55       ` Alexander Lobakin
2022-01-28  0:09 ` [Intel-wired-lan] [PATCH net-next 09/19] iecm: alloc vport TX resources Alan Brady
2022-02-02 23:45   ` Brady, Alan
2022-02-03 17:56     ` Alexander Lobakin
2022-01-28  0:10 ` [Intel-wired-lan] [PATCH net-next 10/19] iecm: alloc vport RX resources Alan Brady
2022-01-28 14:16   ` Alexander Lobakin
2022-02-03  0:13     ` Brady, Alan
2022-02-03 18:29       ` Alexander Lobakin
2022-01-28  0:10 ` [Intel-wired-lan] [PATCH net-next 11/19] iecm: add start_xmit and set_rx_mode Alan Brady
2022-01-28 16:35   ` Alexander Lobakin
2022-01-28  0:10 ` [Intel-wired-lan] [PATCH net-next 12/19] iecm: finish netdev_ops Alan Brady
2022-01-28 17:06   ` Alexander Lobakin
2022-01-28  0:10 ` [Intel-wired-lan] [PATCH net-next 13/19] iecm: implement splitq napi_poll Alan Brady
2022-01-28  5:21   ` kernel test robot
2022-01-28 17:44     ` Alexander Lobakin
2022-02-03  1:15       ` Brady, Alan
2022-01-28 17:38   ` Alexander Lobakin
2022-02-03  1:07     ` Brady, Alan
2022-02-04 11:50       ` Alexander Lobakin
2022-01-28  0:10 ` [Intel-wired-lan] [PATCH net-next 14/19] iecm: implement singleq napi_poll Alan Brady
2022-01-28 17:57   ` Alexander Lobakin
2022-02-03  1:45     ` Brady, Alan
2022-02-03 19:05       ` Alexander Lobakin
2022-01-28  0:10 ` [Intel-wired-lan] [PATCH net-next 15/19] iecm: implement ethtool callbacks Alan Brady
2022-01-28 18:13   ` Alexander Lobakin
2022-02-03  2:13     ` Brady, Alan
2022-02-03 19:54       ` Alexander Lobakin
2022-01-28  0:10 ` [Intel-wired-lan] [PATCH net-next 16/19] iecm: implement flow director Alan Brady
2022-01-28 19:04   ` Alexander Lobakin
2022-02-03  2:41     ` Brady, Alan
2022-02-04 10:08       ` Alexander Lobakin
2022-01-28  0:10 ` [Intel-wired-lan] [PATCH net-next 17/19] iecm: implement cloud filters Alan Brady
2022-01-28 19:38   ` Alexander Lobakin [this message]
2022-02-03  2:53     ` Brady, Alan
2022-01-28  0:10 ` [Intel-wired-lan] [PATCH net-next 18/19] iecm: add advanced rss Alan Brady
2022-01-28 19:53   ` Alexander Lobakin
2022-02-03  2:55     ` Brady, Alan
2022-02-03 10:46       ` Maciej Fijalkowski
2022-02-04 10:22       ` Alexander Lobakin
2022-01-28  0:10 ` [Intel-wired-lan] [PATCH net-next 19/19] idpf: introduce idpf driver Alan Brady
2022-01-28 20:08   ` Alexander Lobakin
2022-02-03  3:07     ` Brady, Alan
2022-02-04 10:35       ` Alexander Lobakin
2022-02-04 12:05 ` [Intel-wired-lan] [PATCH net-next 00/19] Add iecm and idpf Alexander Lobakin

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20220128193809.30521-1-alexandr.lobakin@intel.com \
    --to=alexandr.lobakin@intel.com \
    --cc=intel-wired-lan@osuosl.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox