Commit 99f419df authored by Junfeng Guo's avatar Junfeng Guo Committed by Tony Nguyen
Browse files

ice: enable FDIR filters from raw binary patterns for VFs



Enable VFs to create FDIR filters from raw binary patterns.
The corresponding processes for raw flow are added in the
Parse / Create / Destroy stages.

Reviewed-by: default avatarMarcin Szycik <marcin.szycik@linux.intel.com>
Signed-off-by: default avatarJunfeng Guo <junfeng.guo@intel.com>
Co-developed-by: default avatarAhmed Zaki <ahmed.zaki@intel.com>
Signed-off-by: default avatarAhmed Zaki <ahmed.zaki@intel.com>
Tested-by: default avatarRafal Romanowski <rafal.romanowski@intel.com>
Reviewed-by: default avatarSimon Horman <horms@kernel.org>
Signed-off-by: default avatarTony Nguyen <anthony.l.nguyen@intel.com>
parent f217c187
Loading
Loading
Loading
Loading
+48 −0
Original line number Diff line number Diff line
@@ -4145,6 +4145,54 @@ ice_add_prof_id_flow(struct ice_hw *hw, enum ice_block blk, u16 vsi, u64 hdl)
	return status;
}

/**
 * ice_flow_assoc_fdir_prof - add an FDIR profile for main/ctrl VSI
 * @hw: pointer to the HW struct
 * @blk: HW block
 * @dest_vsi: dest VSI
 * @fdir_vsi: fdir programming VSI
 * @hdl: profile handle
 *
 * Update the hardware tables to enable the FDIR profile indicated by @hdl for
 * the VSI specified by @dest_vsi. On success, the flow will be enabled.
 *
 * Return: 0 on success or negative errno on failure.
 */
int
ice_flow_assoc_fdir_prof(struct ice_hw *hw, enum ice_block blk,
			 u16 dest_vsi, u16 fdir_vsi, u64 hdl)
{
	u16 vsi_num;
	int status;

	if (blk != ICE_BLK_FD)
		return -EINVAL;

	vsi_num = ice_get_hw_vsi_num(hw, dest_vsi);
	status = ice_add_prof_id_flow(hw, blk, vsi_num, hdl);
	if (status) {
		ice_debug(hw, ICE_DBG_FLOW, "Adding HW profile failed for main VSI flow entry: %d\n",
			  status);
		return status;
	}

	vsi_num = ice_get_hw_vsi_num(hw, fdir_vsi);
	status = ice_add_prof_id_flow(hw, blk, vsi_num, hdl);
	if (status) {
		ice_debug(hw, ICE_DBG_FLOW, "Adding HW profile failed for ctrl VSI flow entry: %d\n",
			  status);
		goto err;
	}

	return 0;

err:
	vsi_num = ice_get_hw_vsi_num(hw, dest_vsi);
	ice_rem_prof_id_flow(hw, blk, vsi_num, hdl);

	return status;
}

/**
 * ice_rem_prof_from_list - remove a profile from list
 * @hw: pointer to the HW struct
+3 −0
Original line number Diff line number Diff line
@@ -51,6 +51,9 @@ int
ice_add_prof_id_flow(struct ice_hw *hw, enum ice_block blk, u16 vsi, u64 hdl);
int
ice_rem_prof_id_flow(struct ice_hw *hw, enum ice_block blk, u16 vsi, u64 hdl);
int
ice_flow_assoc_fdir_prof(struct ice_hw *hw, enum ice_block blk,
			 u16 dest_vsi, u16 fdir_vsi, u64 hdl);
enum ice_ddp_state ice_init_pkg(struct ice_hw *hw, u8 *buff, u32 len);
enum ice_ddp_state
ice_copy_and_init_pkg(struct ice_hw *hw, const u8 *buf, u32 len);
+107 −0
Original line number Diff line number Diff line
@@ -409,6 +409,29 @@ static const u32 ice_ptypes_gtpc_tid[] = {
};

/* Packet types for GTPU */
static const struct ice_ptype_attributes ice_attr_gtpu_session[] = {
	{ ICE_MAC_IPV4_GTPU_IPV4_FRAG,	  ICE_PTYPE_ATTR_GTP_SESSION },
	{ ICE_MAC_IPV4_GTPU_IPV4_PAY,	  ICE_PTYPE_ATTR_GTP_SESSION },
	{ ICE_MAC_IPV4_GTPU_IPV4_UDP_PAY, ICE_PTYPE_ATTR_GTP_SESSION },
	{ ICE_MAC_IPV4_GTPU_IPV4_TCP,	  ICE_PTYPE_ATTR_GTP_SESSION },
	{ ICE_MAC_IPV4_GTPU_IPV4_ICMP,	  ICE_PTYPE_ATTR_GTP_SESSION },
	{ ICE_MAC_IPV6_GTPU_IPV4_FRAG,	  ICE_PTYPE_ATTR_GTP_SESSION },
	{ ICE_MAC_IPV6_GTPU_IPV4_PAY,	  ICE_PTYPE_ATTR_GTP_SESSION },
	{ ICE_MAC_IPV6_GTPU_IPV4_UDP_PAY, ICE_PTYPE_ATTR_GTP_SESSION },
	{ ICE_MAC_IPV6_GTPU_IPV4_TCP,	  ICE_PTYPE_ATTR_GTP_SESSION },
	{ ICE_MAC_IPV6_GTPU_IPV4_ICMP,	  ICE_PTYPE_ATTR_GTP_SESSION },
	{ ICE_MAC_IPV4_GTPU_IPV6_FRAG,	  ICE_PTYPE_ATTR_GTP_SESSION },
	{ ICE_MAC_IPV4_GTPU_IPV6_PAY,	  ICE_PTYPE_ATTR_GTP_SESSION },
	{ ICE_MAC_IPV4_GTPU_IPV6_UDP_PAY, ICE_PTYPE_ATTR_GTP_SESSION },
	{ ICE_MAC_IPV4_GTPU_IPV6_TCP,	  ICE_PTYPE_ATTR_GTP_SESSION },
	{ ICE_MAC_IPV4_GTPU_IPV6_ICMPV6,  ICE_PTYPE_ATTR_GTP_SESSION },
	{ ICE_MAC_IPV6_GTPU_IPV6_FRAG,	  ICE_PTYPE_ATTR_GTP_SESSION },
	{ ICE_MAC_IPV6_GTPU_IPV6_PAY,	  ICE_PTYPE_ATTR_GTP_SESSION },
	{ ICE_MAC_IPV6_GTPU_IPV6_UDP_PAY, ICE_PTYPE_ATTR_GTP_SESSION },
	{ ICE_MAC_IPV6_GTPU_IPV6_TCP,	  ICE_PTYPE_ATTR_GTP_SESSION },
	{ ICE_MAC_IPV6_GTPU_IPV6_ICMPV6,  ICE_PTYPE_ATTR_GTP_SESSION },
};

static const struct ice_ptype_attributes ice_attr_gtpu_eh[] = {
	{ ICE_MAC_IPV4_GTPU_IPV4_FRAG,	  ICE_PTYPE_ATTR_GTP_PDU_EH },
	{ ICE_MAC_IPV4_GTPU_IPV4_PAY,	  ICE_PTYPE_ATTR_GTP_PDU_EH },
@@ -1523,6 +1546,90 @@ ice_flow_disassoc_prof(struct ice_hw *hw, enum ice_block blk,
	return status;
}

#define FLAG_GTP_EH_PDU_LINK	BIT_ULL(13)
#define FLAG_GTP_EH_PDU		BIT_ULL(14)

#define HI_BYTE_IN_WORD		GENMASK(15, 8)
#define LO_BYTE_IN_WORD		GENMASK(7, 0)

#define FLAG_GTPU_MSK	\
	(FLAG_GTP_EH_PDU | FLAG_GTP_EH_PDU_LINK)
#define FLAG_GTPU_UP	\
	(FLAG_GTP_EH_PDU | FLAG_GTP_EH_PDU_LINK)
#define FLAG_GTPU_DW	FLAG_GTP_EH_PDU

/**
 * ice_flow_set_parser_prof - Set flow profile based on the parsed profile info
 * @hw: pointer to the HW struct
 * @dest_vsi: dest VSI
 * @fdir_vsi: fdir programming VSI
 * @prof: stores parsed profile info from raw flow
 * @blk: classification blk
 *
 * Return: 0 on success or negative errno on failure.
 */
int
ice_flow_set_parser_prof(struct ice_hw *hw, u16 dest_vsi, u16 fdir_vsi,
			 struct ice_parser_profile *prof, enum ice_block blk)
{
	u64 id = find_first_bit(prof->ptypes, ICE_FLOW_PTYPE_MAX);
	struct ice_flow_prof_params *params __free(kfree);
	u8 fv_words = hw->blk[blk].es.fvw;
	int status;
	int i, idx;

	params = kzalloc(sizeof(*params), GFP_KERNEL);
	if (!params)
		return -ENOMEM;

	for (i = 0; i < ICE_MAX_FV_WORDS; i++) {
		params->es[i].prot_id = ICE_PROT_INVALID;
		params->es[i].off = ICE_FV_OFFSET_INVAL;
	}

	for (i = 0; i < prof->fv_num; i++) {
		if (hw->blk[blk].es.reverse)
			idx = fv_words - i - 1;
		else
			idx = i;
		params->es[idx].prot_id = prof->fv[i].proto_id;
		params->es[idx].off = prof->fv[i].offset;
		params->mask[idx] = (((prof->fv[i].msk) << BITS_PER_BYTE) &
				      HI_BYTE_IN_WORD) |
				    (((prof->fv[i].msk) >> BITS_PER_BYTE) &
				      LO_BYTE_IN_WORD);
	}

	switch (prof->flags) {
	case FLAG_GTPU_DW:
		params->attr = ice_attr_gtpu_down;
		params->attr_cnt = ARRAY_SIZE(ice_attr_gtpu_down);
		break;
	case FLAG_GTPU_UP:
		params->attr = ice_attr_gtpu_up;
		params->attr_cnt = ARRAY_SIZE(ice_attr_gtpu_up);
		break;
	default:
		if (prof->flags_msk & FLAG_GTPU_MSK) {
			params->attr = ice_attr_gtpu_session;
			params->attr_cnt = ARRAY_SIZE(ice_attr_gtpu_session);
		}
		break;
	}

	status = ice_add_prof(hw, blk, id, (u8 *)prof->ptypes,
			      params->attr, params->attr_cnt,
			      params->es, params->mask, false, false);
	if (status)
		return status;

	status = ice_flow_assoc_fdir_prof(hw, blk, dest_vsi, fdir_vsi, id);
	if (status)
		ice_rem_prof(hw, blk, id);

	return status;
}

/**
 * ice_flow_add_prof - Add a flow profile for packet segments and matched fields
 * @hw: pointer to the HW struct
+5 −0
Original line number Diff line number Diff line
@@ -5,6 +5,7 @@
#define _ICE_FLOW_H_

#include "ice_flex_type.h"
#include "ice_parser.h"

#define ICE_FLOW_ENTRY_HANDLE_INVAL	0
#define ICE_FLOW_FLD_OFF_INVAL		0xffff
@@ -326,6 +327,7 @@ enum ice_rss_cfg_hdr_type {
	ICE_RSS_ANY_HEADERS
};

struct ice_vsi;
struct ice_rss_hash_cfg {
	u32 addl_hdrs; /* protocol header fields */
	u64 hash_flds; /* hash bit field (ICE_FLOW_HASH_*) to configure */
@@ -445,6 +447,9 @@ ice_flow_add_prof(struct ice_hw *hw, enum ice_block blk, enum ice_flow_dir dir,
		  bool symm, struct ice_flow_prof **prof);
int ice_flow_rem_prof(struct ice_hw *hw, enum ice_block blk, u64 prof_id);
int
ice_flow_set_parser_prof(struct ice_hw *hw, u16 dest_vsi, u16 fdir_vsi,
			 struct ice_parser_profile *prof, enum ice_block blk);
int
ice_flow_add_entry(struct ice_hw *hw, enum ice_block blk, u64 prof_id,
		   u64 entry_id, u16 vsi, enum ice_flow_priority prio,
		   void *data, u64 *entry_h);
+8 −0
Original line number Diff line number Diff line
@@ -12,6 +12,7 @@
#include <net/devlink.h>
#include <linux/avf/virtchnl.h>
#include "ice_type.h"
#include "ice_flow.h"
#include "ice_virtchnl_fdir.h"
#include "ice_vsi_vlan_ops.h"

@@ -52,6 +53,12 @@ struct ice_mdd_vf_events {
	u16 last_printed;
};

/* Structure to store fdir fv entry */
struct ice_fdir_prof_info {
	struct ice_parser_profile prof;
	u64 fdir_active_cnt;
};

/* VF operations */
struct ice_vf_ops {
	enum ice_disq_rst_src reset_type;
@@ -91,6 +98,7 @@ struct ice_vf {
	u16 lan_vsi_idx;		/* index into PF struct */
	u16 ctrl_vsi_idx;
	struct ice_vf_fdir fdir;
	struct ice_fdir_prof_info fdir_prof_info[ICE_MAX_PTGS];
	/* first vector index of this VF in the PF space */
	int first_vector_idx;
	struct ice_sw *vf_sw_id;	/* switch ID the VF VSIs connect to */
Loading