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

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
......@@ -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
......
......@@ -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);
......
......@@ -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,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);
......
......@@ -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 */
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment