Commit e312b3a1 authored by Junfeng Guo's avatar Junfeng Guo Committed by Tony Nguyen

ice: add API for parser profile initialization

Add API ice_parser_profile_init() to init a parser profile based on
a parser result and a mask buffer. The ice_parser_profile struct is used
by the low level FXP engine to create HW profile/field vectors.
Reviewed-by: default avatarMarcin Szycik <marcin.szycik@linux.intel.com>
Signed-off-by: default avatarQi Zhang <qi.z.zhang@intel.com>
Signed-off-by: default avatarJunfeng Guo <junfeng.guo@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 80a48007
......@@ -2243,9 +2243,9 @@ static int ice_tunnel_port_set(struct ice_parser *psr, enum ice_lbl_type type,
/* found a matched slot to delete */
} else if (!on &&
(item->key_inv[ICE_BT_TUN_PORT_OFF_L] ==
buf[ICE_UDP_PORT_OFF_L] ||
buf[ICE_UDP_PORT_OFF_L] ||
item->key_inv[ICE_BT_TUN_PORT_OFF_H] ==
buf[ICE_UDP_PORT_OFF_H])) {
buf[ICE_UDP_PORT_OFF_H])) {
item->key_inv[ICE_BT_TUN_PORT_OFF_L] = ICE_BT_VLD_KEY;
item->key_inv[ICE_BT_TUN_PORT_OFF_H] = ICE_BT_INV_KEY;
......@@ -2302,3 +2302,129 @@ int ice_parser_ecpri_tunnel_set(struct ice_parser *psr,
return ice_tunnel_port_set(psr, ICE_LBL_BST_TYPE_UDP_ECPRI,
udp_port, on);
}
/**
* ice_nearest_proto_id - find nearest protocol ID
* @rslt: pointer to a parser result instance
* @offset: a min value for the protocol offset
* @proto_id: the protocol ID (output)
* @proto_off: the protocol offset (output)
*
* From the protocols in @rslt, find the nearest protocol that has offset
* larger than @offset.
*
* Return: if true, the protocol's ID and offset
*/
static bool ice_nearest_proto_id(struct ice_parser_result *rslt, u16 offset,
u8 *proto_id, u16 *proto_off)
{
u16 dist = U16_MAX;
u8 proto = 0;
int i;
for (i = 0; i < rslt->po_num; i++) {
if (offset < rslt->po[i].offset)
continue;
if (offset - rslt->po[i].offset < dist) {
proto = rslt->po[i].proto_id;
dist = offset - rslt->po[i].offset;
}
}
if (dist % 2)
return false;
*proto_id = proto;
*proto_off = dist;
return true;
}
/* default flag mask to cover GTP_EH_PDU, GTP_EH_PDU_LINK and TUN2
* In future, the flag masks should learn from DDP
*/
#define ICE_KEYBUILD_FLAG_MASK_DEFAULT_SW 0x4002
#define ICE_KEYBUILD_FLAG_MASK_DEFAULT_ACL 0x0000
#define ICE_KEYBUILD_FLAG_MASK_DEFAULT_FD 0x6080
#define ICE_KEYBUILD_FLAG_MASK_DEFAULT_RSS 0x6010
/**
* ice_parser_profile_init - initialize a FXP profile based on parser result
* @rslt: a instance of a parser result
* @pkt_buf: packet data buffer
* @msk_buf: packet mask buffer
* @buf_len: packet length
* @blk: FXP pipeline stage
* @prof: input/output parameter to save the profile
*
* Return: 0 on success or errno on failure.
*/
int ice_parser_profile_init(struct ice_parser_result *rslt,
const u8 *pkt_buf, const u8 *msk_buf,
int buf_len, enum ice_block blk,
struct ice_parser_profile *prof)
{
u8 proto_id = U8_MAX;
u16 proto_off = 0;
u16 off;
memset(prof, 0, sizeof(*prof));
set_bit(rslt->ptype, prof->ptypes);
if (blk == ICE_BLK_SW) {
prof->flags = rslt->flags_sw;
prof->flags_msk = ICE_KEYBUILD_FLAG_MASK_DEFAULT_SW;
} else if (blk == ICE_BLK_ACL) {
prof->flags = rslt->flags_acl;
prof->flags_msk = ICE_KEYBUILD_FLAG_MASK_DEFAULT_ACL;
} else if (blk == ICE_BLK_FD) {
prof->flags = rslt->flags_fd;
prof->flags_msk = ICE_KEYBUILD_FLAG_MASK_DEFAULT_FD;
} else if (blk == ICE_BLK_RSS) {
prof->flags = rslt->flags_rss;
prof->flags_msk = ICE_KEYBUILD_FLAG_MASK_DEFAULT_RSS;
} else {
return -EINVAL;
}
for (off = 0; off < buf_len - 1; off++) {
if (msk_buf[off] == 0 && msk_buf[off + 1] == 0)
continue;
if (!ice_nearest_proto_id(rslt, off, &proto_id, &proto_off))
continue;
if (prof->fv_num >= ICE_PARSER_FV_MAX)
return -EINVAL;
prof->fv[prof->fv_num].proto_id = proto_id;
prof->fv[prof->fv_num].offset = proto_off;
prof->fv[prof->fv_num].spec = *(const u16 *)&pkt_buf[off];
prof->fv[prof->fv_num].msk = *(const u16 *)&msk_buf[off];
prof->fv_num++;
}
return 0;
}
/**
* ice_parser_profile_dump - dump an FXP profile info
* @hw: pointer to the hardware structure
* @prof: profile info to dump
*/
void ice_parser_profile_dump(struct ice_hw *hw,
struct ice_parser_profile *prof)
{
struct device *dev = ice_hw_to_dev(hw);
u16 i;
dev_info(dev, "ptypes:\n");
for (i = 0; i < ICE_FLOW_PTYPE_MAX; i++)
if (test_bit(i, prof->ptypes))
dev_info(dev, "\t%u\n", i);
for (i = 0; i < prof->fv_num; i++)
dev_info(dev, "proto = %u, offset = %2u, spec = 0x%04x, mask = 0x%04x\n",
prof->fv[i].proto_id, prof->fv[i].offset,
prof->fv[i].spec, prof->fv[i].msk);
dev_info(dev, "flags = 0x%04x\n", prof->flags);
dev_info(dev, "flags_msk = 0x%04x\n", prof->flags_msk);
}
......@@ -451,6 +451,8 @@ struct ice_parser_proto_off {
#define ICE_PARSER_PROTO_OFF_PAIR_SIZE 16
#define ICE_PARSER_FLAG_PSR_SIZE 8
#define ICE_PARSER_FV_SIZE 48
#define ICE_PARSER_FV_MAX 24
#define ICE_BT_TUN_PORT_OFF_H 16
#define ICE_BT_TUN_PORT_OFF_L 15
#define ICE_BT_VM_OFF 0
......@@ -511,4 +513,28 @@ int ice_parser_ecpri_tunnel_set(struct ice_parser *psr, u16 udp_port, bool on);
int ice_parser_run(struct ice_parser *psr, const u8 *pkt_buf,
int pkt_len, struct ice_parser_result *rslt);
void ice_parser_result_dump(struct ice_hw *hw, struct ice_parser_result *rslt);
struct ice_parser_fv {
u8 proto_id; /* hardware protocol ID */
u16 offset; /* offset from the start of the protocol header */
u16 spec; /* pattern to match */
u16 msk; /* pattern mask */
};
struct ice_parser_profile {
/* array of field vectors */
struct ice_parser_fv fv[ICE_PARSER_FV_SIZE];
int fv_num; /* # of field vectors must <= 48 */
u16 flags; /* key builder flags */
u16 flags_msk; /* key builder flag mask */
DECLARE_BITMAP(ptypes, ICE_FLOW_PTYPE_MAX); /* PTYPE bitmap */
};
int ice_parser_profile_init(struct ice_parser_result *rslt,
const u8 *pkt_buf, const u8 *msk_buf,
int buf_len, enum ice_block blk,
struct ice_parser_profile *prof);
void ice_parser_profile_dump(struct ice_hw *hw,
struct ice_parser_profile *prof);
#endif /* _ICE_PARSER_H_ */
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