diff mbox series

[iwl-next,v2,15/15] ice: add API for parser profile initialization

Message ID 20230605054641.2865142-16-junfeng.guo@intel.com
State Superseded
Headers show
Series Introduce the Parser Library | expand

Commit Message

Junfeng Guo June 5, 2023, 5:46 a.m. UTC
Add API ice_parser_profile_init to init a parser profile base on
a parser result and a mask buffer. The ice_parser_profile can feed to
low level FXP engine to create HW profile / field vector directly.

Signed-off-by: Junfeng Guo <junfeng.guo@intel.com>
---
 drivers/net/ethernet/intel/ice/ice_parser.c | 113 ++++++++++++++++++++
 drivers/net/ethernet/intel/ice/ice_parser.h |  24 +++++
 2 files changed, 137 insertions(+)

Comments

Ivan Vecera July 24, 2023, 11:17 a.m. UTC | #1
On 05. 06. 23 7:46, Junfeng Guo wrote:
> Add API ice_parser_profile_init to init a parser profile base on
> a parser result and a mask buffer. The ice_parser_profile can feed to
> low level FXP engine to create HW profile / field vector directly.
> 
> Signed-off-by: Junfeng Guo <junfeng.guo@intel.com>
> ---
>   drivers/net/ethernet/intel/ice/ice_parser.c | 113 ++++++++++++++++++++
>   drivers/net/ethernet/intel/ice/ice_parser.h |  24 +++++
>   2 files changed, 137 insertions(+)
> 
> diff --git a/drivers/net/ethernet/intel/ice/ice_parser.c b/drivers/net/ethernet/intel/ice/ice_parser.c
> index 1ca0886e6590..ad42dcd31cb3 100644
> --- a/drivers/net/ethernet/intel/ice/ice_parser.c
> +++ b/drivers/net/ethernet/intel/ice/ice_parser.c
> @@ -448,3 +448,116 @@ int ice_parser_ecpri_tunnel_set(struct ice_parser *psr,
>   {
>   	return _tunnel_port_set(psr, "TNL_UDP_ECPRI", udp_port, on);
>   }
> +
> +static bool _nearest_proto_id(struct ice_parser_result *rslt, u16 offset,
> +			      u8 *proto_id, u16 *proto_off)
> +{
> +	u16 dist = 0xffff;

Use U16_MAX here...

> +	u8 p = 0

Also 'proto' instead of 'p' would be better.

> +	int i;
> +
> +	for (i = 0; i < rslt->po_num; i++) {
> +		if (offset < rslt->po[i].offset)
> +			continue;
> +		if (offset - rslt->po[i].offset < dist) {
> +			p = rslt->po[i].proto_id;
> +			dist = offset - rslt->po[i].offset;
> +		}
> +	}
> +
> +	if (dist % 2)
> +		return false;
> +
> +	*proto_id = p;
> +	*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 base 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
> + * @prefix_match: match protocol stack exactly or only prefix
> + * @prof: input/output parameter to save the profile
> + */
> +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,
> +			    bool prefix_match,
> +			    struct ice_parser_profile *prof)
> +{
> +	u8 proto_id = 0xff;
> +	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 (!_nearest_proto_id(rslt, off, &proto_id, &proto_off))
> +			continue;
> +		if (prof->fv_num >= 32)
> +			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)
> +{
> +	u16 i;
> +
> +	dev_info(ice_hw_to_dev(hw), "ptypes:\n");
> +	for (i = 0; i < ICE_FLOW_PTYPE_MAX; i++)
> +		if (test_bit(i, prof->ptypes))
> +			dev_info(ice_hw_to_dev(hw), "\t%d\n", i);
> +
> +	for (i = 0; i < prof->fv_num; i++)
> +		dev_info(ice_hw_to_dev(hw),
> +			 "proto = %d, offset = %d 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(ice_hw_to_dev(hw), "flags = 0x%04x\n", prof->flags);
> +	dev_info(ice_hw_to_dev(hw), "flags_msk = 0x%04x\n", prof->flags_msk);
> +}
> diff --git a/drivers/net/ethernet/intel/ice/ice_parser.h b/drivers/net/ethernet/intel/ice/ice_parser.h
> index 432d47031298..ecbec5843e9f 100644
> --- a/drivers/net/ethernet/intel/ice/ice_parser.h
> +++ b/drivers/net/ethernet/intel/ice/ice_parser.h
> @@ -85,4 +85,28 @@ struct ice_parser_result {
>   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; /* 16 bits pattern to match */
> +	u16 msk; /* 16 bits pattern mask */
> +};
> +
> +struct ice_parser_profile {
> +	struct ice_parser_fv fv[48]; /* field vector arrary */
> +	int fv_num; /* field vector number must <= 48 */
> +	u16 flags; /* 16 bits key builder flag */
> +	u16 flags_msk; /* key builder flag masker */
> +	/* 1024 bits PTYPE bitmap */
> +	DECLARE_BITMAP(ptypes, ICE_FLOW_PTYPE_MAX);
> +};
> +
> +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,
> +					bool prefix_match,
> +					struct ice_parser_profile *prof);
> +void ice_parser_profile_dump(struct ice_hw *hw,
> +			     struct ice_parser_profile *prof);
>   #endif /* _ICE_PARSER_H_ */
Junfeng Guo Aug. 2, 2023, 7:56 a.m. UTC | #2
> -----Original Message-----
> From: Ivan Vecera <ivecera@redhat.com>
> Sent: Monday, July 24, 2023 19:17
> To: Guo, Junfeng <junfeng.guo@intel.com>; intel-wired-
> lan@lists.osuosl.org
> Cc: Zhang, Qi Z <qi.z.zhang@intel.com>; mschmidt
> <mschmidt@redhat.com>; poros <poros@redhat.com>
> Subject: Re: [Intel-wired-lan] [PATCH iwl-next v2 15/15] ice: add API for
> parser profile initialization
> 
> 
> 
> On 05. 06. 23 7:46, Junfeng Guo wrote:
> > Add API ice_parser_profile_init to init a parser profile base on
> > a parser result and a mask buffer. The ice_parser_profile can feed to
> > low level FXP engine to create HW profile / field vector directly.
> >
> > Signed-off-by: Junfeng Guo <junfeng.guo@intel.com>
> > ---
> >   drivers/net/ethernet/intel/ice/ice_parser.c | 113
> ++++++++++++++++++++
> >   drivers/net/ethernet/intel/ice/ice_parser.h |  24 +++++
> >   2 files changed, 137 insertions(+)
> >
> > diff --git a/drivers/net/ethernet/intel/ice/ice_parser.c
> b/drivers/net/ethernet/intel/ice/ice_parser.c
> > index 1ca0886e6590..ad42dcd31cb3 100644
> > --- a/drivers/net/ethernet/intel/ice/ice_parser.c
> > +++ b/drivers/net/ethernet/intel/ice/ice_parser.c
> > @@ -448,3 +448,116 @@ int ice_parser_ecpri_tunnel_set(struct
> ice_parser *psr,
> >   {
> >   	return _tunnel_port_set(psr, "TNL_UDP_ECPRI", udp_port, on);
> >   }
> > +
> > +static bool _nearest_proto_id(struct ice_parser_result *rslt, u16 offset,
> > +			      u8 *proto_id, u16 *proto_off)
> > +{
> > +	u16 dist = 0xffff;
> 
> Use U16_MAX here...

Sure, make sense! Will update in the coming version. Thanks!

> 
> > +	u8 p = 0
> 
> Also 'proto' instead of 'p' would be better.

Sure, make sense! Will update in the coming version. Thanks!

> 
> > +	int i;
> > +
> > +	for (i = 0; i < rslt->po_num; i++) {
> > +		if (offset < rslt->po[i].offset)
> > +			continue;
> > +		if (offset - rslt->po[i].offset < dist) {
> > +			p = rslt->po[i].proto_id;
> > +			dist = offset - rslt->po[i].offset;
> > +		}
> > +	}
> > +
> > +	if (dist % 2)
> > +		return false;
> > +
> > +	*proto_id = p;
> > +	*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 base 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
> > + * @prefix_match: match protocol stack exactly or only prefix
> > + * @prof: input/output parameter to save the profile
> > + */
> > +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,
> > +			    bool prefix_match,
> > +			    struct ice_parser_profile *prof)
> > +{
> > +	u8 proto_id = 0xff;
> > +	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 (!_nearest_proto_id(rslt, off, &proto_id, &proto_off))
> > +			continue;
> > +		if (prof->fv_num >= 32)
> > +			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)
> > +{
> > +	u16 i;
> > +
> > +	dev_info(ice_hw_to_dev(hw), "ptypes:\n");
> > +	for (i = 0; i < ICE_FLOW_PTYPE_MAX; i++)
> > +		if (test_bit(i, prof->ptypes))
> > +			dev_info(ice_hw_to_dev(hw), "\t%d\n", i);
> > +
> > +	for (i = 0; i < prof->fv_num; i++)
> > +		dev_info(ice_hw_to_dev(hw),
> > +			 "proto = %d, offset = %d 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(ice_hw_to_dev(hw), "flags = 0x%04x\n", prof->flags);
> > +	dev_info(ice_hw_to_dev(hw), "flags_msk = 0x%04x\n", prof-
> >flags_msk);
> > +}
> > diff --git a/drivers/net/ethernet/intel/ice/ice_parser.h
> b/drivers/net/ethernet/intel/ice/ice_parser.h
> > index 432d47031298..ecbec5843e9f 100644
> > --- a/drivers/net/ethernet/intel/ice/ice_parser.h
> > +++ b/drivers/net/ethernet/intel/ice/ice_parser.h
> > @@ -85,4 +85,28 @@ struct ice_parser_result {
> >   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; /* 16 bits pattern to match */
> > +	u16 msk; /* 16 bits pattern mask */
> > +};
> > +
> > +struct ice_parser_profile {
> > +	struct ice_parser_fv fv[48]; /* field vector arrary */
> > +	int fv_num; /* field vector number must <= 48 */
> > +	u16 flags; /* 16 bits key builder flag */
> > +	u16 flags_msk; /* key builder flag masker */
> > +	/* 1024 bits PTYPE bitmap */
> > +	DECLARE_BITMAP(ptypes, ICE_FLOW_PTYPE_MAX);
> > +};
> > +
> > +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,
> > +					bool prefix_match,
> > +					struct ice_parser_profile *prof);
> > +void ice_parser_profile_dump(struct ice_hw *hw,
> > +			     struct ice_parser_profile *prof);
> >   #endif /* _ICE_PARSER_H_ */
Ivan Vecera Aug. 2, 2023, 3:59 p.m. UTC | #3
On 02. 08. 23 9:56, Guo, Junfeng wrote:
> 
>> -----Original Message-----
>> From: Ivan Vecera<ivecera@redhat.com>
>> Sent: Monday, July 24, 2023 19:17
>> To: Guo, Junfeng<junfeng.guo@intel.com>; intel-wired-
>> lan@lists.osuosl.org
>> Cc: Zhang, Qi Z<qi.z.zhang@intel.com>; mschmidt
>> <mschmidt@redhat.com>; poros<poros@redhat.com>
>> Subject: Re: [Intel-wired-lan] [PATCH iwl-next v2 15/15] ice: add API for
>> parser profile initialization
>>
>>
>>
>> On 05. 06. 23 7:46, Junfeng Guo wrote:
>>> Add API ice_parser_profile_init to init a parser profile base on
>>> a parser result and a mask buffer. The ice_parser_profile can feed to
>>> low level FXP engine to create HW profile / field vector directly.
>>>
>>> Signed-off-by: Junfeng Guo<junfeng.guo@intel.com>
>>> ---
>>>    drivers/net/ethernet/intel/ice/ice_parser.c | 113
>> ++++++++++++++++++++
>>>    drivers/net/ethernet/intel/ice/ice_parser.h |  24 +++++
>>>    2 files changed, 137 insertions(+)
>>>
>>> diff --git a/drivers/net/ethernet/intel/ice/ice_parser.c
>> b/drivers/net/ethernet/intel/ice/ice_parser.c
>>> index 1ca0886e6590..ad42dcd31cb3 100644
>>> --- a/drivers/net/ethernet/intel/ice/ice_parser.c
>>> +++ b/drivers/net/ethernet/intel/ice/ice_parser.c
>>> @@ -448,3 +448,116 @@ int ice_parser_ecpri_tunnel_set(struct
>> ice_parser *psr,
>>>    {
>>>    	return _tunnel_port_set(psr, "TNL_UDP_ECPRI", udp_port, on);
>>>    }
>>> +
>>> +static bool _nearest_proto_id(struct ice_parser_result *rslt, u16 offset,
>>> +			      u8 *proto_id, u16 *proto_off)
>>> +{
>>> +	u16 dist = 0xffff;
>> Use U16_MAX here...
> Sure, make sense! Will update in the coming version. Thanks!
> 
>>> +	u8 p = 0
>> Also 'proto' instead of 'p' would be better.
> Sure, make sense! Will update in the coming version. Thanks!
> 

I'm looking forward for the next version.

Thank you,

Ivan
diff mbox series

Patch

diff --git a/drivers/net/ethernet/intel/ice/ice_parser.c b/drivers/net/ethernet/intel/ice/ice_parser.c
index 1ca0886e6590..ad42dcd31cb3 100644
--- a/drivers/net/ethernet/intel/ice/ice_parser.c
+++ b/drivers/net/ethernet/intel/ice/ice_parser.c
@@ -448,3 +448,116 @@  int ice_parser_ecpri_tunnel_set(struct ice_parser *psr,
 {
 	return _tunnel_port_set(psr, "TNL_UDP_ECPRI", udp_port, on);
 }
+
+static bool _nearest_proto_id(struct ice_parser_result *rslt, u16 offset,
+			      u8 *proto_id, u16 *proto_off)
+{
+	u16 dist = 0xffff;
+	u8 p = 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) {
+			p = rslt->po[i].proto_id;
+			dist = offset - rslt->po[i].offset;
+		}
+	}
+
+	if (dist % 2)
+		return false;
+
+	*proto_id = p;
+	*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 base 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
+ * @prefix_match: match protocol stack exactly or only prefix
+ * @prof: input/output parameter to save the profile
+ */
+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,
+			    bool prefix_match,
+			    struct ice_parser_profile *prof)
+{
+	u8 proto_id = 0xff;
+	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 (!_nearest_proto_id(rslt, off, &proto_id, &proto_off))
+			continue;
+		if (prof->fv_num >= 32)
+			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)
+{
+	u16 i;
+
+	dev_info(ice_hw_to_dev(hw), "ptypes:\n");
+	for (i = 0; i < ICE_FLOW_PTYPE_MAX; i++)
+		if (test_bit(i, prof->ptypes))
+			dev_info(ice_hw_to_dev(hw), "\t%d\n", i);
+
+	for (i = 0; i < prof->fv_num; i++)
+		dev_info(ice_hw_to_dev(hw),
+			 "proto = %d, offset = %d 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(ice_hw_to_dev(hw), "flags = 0x%04x\n", prof->flags);
+	dev_info(ice_hw_to_dev(hw), "flags_msk = 0x%04x\n", prof->flags_msk);
+}
diff --git a/drivers/net/ethernet/intel/ice/ice_parser.h b/drivers/net/ethernet/intel/ice/ice_parser.h
index 432d47031298..ecbec5843e9f 100644
--- a/drivers/net/ethernet/intel/ice/ice_parser.h
+++ b/drivers/net/ethernet/intel/ice/ice_parser.h
@@ -85,4 +85,28 @@  struct ice_parser_result {
 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; /* 16 bits pattern to match */
+	u16 msk; /* 16 bits pattern mask */
+};
+
+struct ice_parser_profile {
+	struct ice_parser_fv fv[48]; /* field vector arrary */
+	int fv_num; /* field vector number must <= 48 */
+	u16 flags; /* 16 bits key builder flag */
+	u16 flags_msk; /* key builder flag masker */
+	/* 1024 bits PTYPE bitmap */
+	DECLARE_BITMAP(ptypes, ICE_FLOW_PTYPE_MAX);
+};
+
+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,
+					bool prefix_match,
+					struct ice_parser_profile *prof);
+void ice_parser_profile_dump(struct ice_hw *hw,
+			     struct ice_parser_profile *prof);
 #endif /* _ICE_PARSER_H_ */