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: Marcin Szycik <marcin.szycik@linux.intel.com> Signed-off-by: Qi Zhang <qi.z.zhang@intel.com> Signed-off-by: Junfeng Guo <junfeng.guo@intel.com> Signed-off-by: Ahmed Zaki <ahmed.zaki@intel.com> Tested-by: Rafal Romanowski <rafal.romanowski@intel.com> Reviewed-by: Simon Horman <horms@kernel.org> Signed-off-by: Tony Nguyen <anthony.l.nguyen@intel.com>
This commit is contained in:
@@ -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_ */
|
||||
|
||||
Reference in New Issue
Block a user