diff mbox series

[S48,v3,07/14] ice: Enable RSS Configure for AVF

Message ID 20200702225805.32167-8-qi.z.zhang@intel.com
State Superseded
Headers show
Series Support Advanced AVF features | expand

Commit Message

Qi Zhang July 2, 2020, 10:57 p.m. UTC
The virtual channel is going to be extended to support FDIR and
RSS configure from AVF. New data structures and OP codes will be
added, the patch enable the RSS part.

To support above advanced AVF feature, we need to figure out
what kind of data structure should be passed from VF to PF to describe
an FDIR rule or RSS config rule. The common part of the requirement is
we need a data structure to represent the input set selection of a rule's
hash key.

An input set selection is a group of fields be selected from one or more
network protocol layers that could be identified as a specific flow.
For example, select dst IP address from an IPv4 header combined with
dst port from the TCP header as the input set for an IPv4/TCP flow.

The patch adds a new data structure virtchnl_proto_hdrs to abstract
a network protocol headers group which is composed of layers of network
protocol header(virtchnl_proto_hdr).

A protocol header contains a 32 bits mask (field_selector) to describe
which fields are selected as input sets, as well as a header type
(enum virtchnl_proto_hdr_type). Each bit is mapped to a field in
enum virtchnl_proto_hdr_field guided by its header type.

+------------+-----------+------------------------------+
|            | Proto Hdr | Header Type A                |
|            |           +------------------------------+
|            |           | BIT 31 | ... | BIT 1 | BIT 0 |
|            |-----------+------------------------------+
|Proto Hdrs  | Proto Hdr | Header Type B                |
|            |           +------------------------------+
|            |           | BIT 31 | ... | BIT 1 | BIT 0 |
|            |-----------+------------------------------+
|            | Proto Hdr | Header Type C                |
|            |           +------------------------------+
|            |           | BIT 31 | ... | BIT 1 | BIT 0 |
|            |-----------+------------------------------+
|            |    ....                                  |
+-------------------------------------------------------+

All fields in enum virtchnl_proto_hdr_fields are grouped with header type
and the value of the first field of a header type is always 32 aligned.

enum proto_hdr_type {
        header_type_A = 0;
        header_type_B = 1;
        ....
}

enum proto_hdr_field {
        /* header type A */
        header_A_field_0 = 0,
        header_A_field_1 = 1,
        header_A_field_2 = 2,
        header_A_field_3 = 3,

        /* header type B */
        header_B_field_0 = 32, // = header_type_B << 5
        header_B_field_0 = 33,
        header_B_field_0 = 34
        header_B_field_0 = 35,
        ....
};

So we have:
proto_hdr_type = proto_hdr_field / 32
bit offset = proto_hdr_field % 32

To simply the protocol header's operations, couple help macros are added.
For example, to select src IP and dst port as input set for an IPv4/UDP
flow.

we have:
struct virtchnl_proto_hdr hdr[2];

VIRTCHNL_SET_PROTO_HDR_TYPE(&hdr[0], IPV4)
VIRTCHNL_ADD_PROTO_HDR_FIELD(&hdr[0], IPV4, SRC)

VIRTCHNL_SET_PROTO_HDR_TYPE(&hdr[1], UDP)
VIRTCHNL_ADD_PROTO_HDR_FIELD(&hdr[1], UDP, DST)

A protocol header also contains a byte array, this field should only
be used by an FDIR rule and should be ignored by RSS. For an FDIR rule,
the byte array is used to store the protocol header of a training
package. The byte array must be network order.

Signed-off-by: Jeff Guo <jia.guo@intel.com>
Signed-off-by: Qi Zhang <qi.z.zhang@intel.com>
---
 drivers/net/ethernet/intel/ice/ice_flow.h        |   3 +
 drivers/net/ethernet/intel/ice/ice_virtchnl_pf.c | 459 +++++++++++++++++++++++
 include/linux/avf/virtchnl.h                     | 187 ++++++++-
 3 files changed, 641 insertions(+), 8 deletions(-)

Comments

Kirsher, Jeffrey T July 3, 2020, 5:14 a.m. UTC | #1
> -----Original Message-----
> From: Intel-wired-lan <intel-wired-lan-bounces@osuosl.org> On Behalf Of Qi
> Zhang
> Sent: Thursday, July 2, 2020 15:58
> To: intel-wired-lan@lists.osuosl.org
> Cc: Zhang, Qi Z <qi.z.zhang@intel.com>
> Subject: [Intel-wired-lan] [PATCH S48 v3 07/14] ice: Enable RSS Configure for
> AVF
> 
> The virtual channel is going to be extended to support FDIR and RSS configure
> from AVF. New data structures and OP codes will be added, the patch enable
> the RSS part.
> 
> To support above advanced AVF feature, we need to figure out what kind of
> data structure should be passed from VF to PF to describe an FDIR rule or RSS
> config rule. The common part of the requirement is we need a data structure to
> represent the input set selection of a rule's hash key.
> 
> An input set selection is a group of fields be selected from one or more
> network protocol layers that could be identified as a specific flow.
> For example, select dst IP address from an IPv4 header combined with dst port
> from the TCP header as the input set for an IPv4/TCP flow.
> 
> The patch adds a new data structure virtchnl_proto_hdrs to abstract a network
> protocol headers group which is composed of layers of network protocol
> header(virtchnl_proto_hdr).
> 
> A protocol header contains a 32 bits mask (field_selector) to describe which
> fields are selected as input sets, as well as a header type (enum
> virtchnl_proto_hdr_type). Each bit is mapped to a field in enum
> virtchnl_proto_hdr_field guided by its header type.
> 
> +------------+-----------+------------------------------+
> |            | Proto Hdr | Header Type A                |
> |            |           +------------------------------+
> |            |           | BIT 31 | ... | BIT 1 | BIT 0 |
> |            |-----------+------------------------------+
> |Proto Hdrs  | Proto Hdr | Header Type B                |
> |            |           +------------------------------+
> |            |           | BIT 31 | ... | BIT 1 | BIT 0 |
> |            |-----------+------------------------------+
> |            | Proto Hdr | Header Type C                |
> |            |           +------------------------------+
> |            |           | BIT 31 | ... | BIT 1 | BIT 0 |
> |            |-----------+------------------------------+
> |            |    ....                                  |
> +-------------------------------------------------------+
> 
> All fields in enum virtchnl_proto_hdr_fields are grouped with header type and
> the value of the first field of a header type is always 32 aligned.
> 
> enum proto_hdr_type {
>         header_type_A = 0;
>         header_type_B = 1;
>         ....
> }
> 
> enum proto_hdr_field {
>         /* header type A */
>         header_A_field_0 = 0,
>         header_A_field_1 = 1,
>         header_A_field_2 = 2,
>         header_A_field_3 = 3,
> 
>         /* header type B */
>         header_B_field_0 = 32, // = header_type_B << 5
>         header_B_field_0 = 33,
>         header_B_field_0 = 34
>         header_B_field_0 = 35,
>         ....
> };
> 
> So we have:
> proto_hdr_type = proto_hdr_field / 32
> bit offset = proto_hdr_field % 32
> 
> To simply the protocol header's operations, couple help macros are added.
> For example, to select src IP and dst port as input set for an IPv4/UDP flow.
> 
> we have:
> struct virtchnl_proto_hdr hdr[2];
> 
> VIRTCHNL_SET_PROTO_HDR_TYPE(&hdr[0], IPV4)
> VIRTCHNL_ADD_PROTO_HDR_FIELD(&hdr[0], IPV4, SRC)
> 
> VIRTCHNL_SET_PROTO_HDR_TYPE(&hdr[1], UDP)
> VIRTCHNL_ADD_PROTO_HDR_FIELD(&hdr[1], UDP, DST)
> 
> A protocol header also contains a byte array, this field should only be used by
> an FDIR rule and should be ignored by RSS. For an FDIR rule, the byte array is
> used to store the protocol header of a training package. The byte array must
> be network order.
> 
> Signed-off-by: Jeff Guo <jia.guo@intel.com>
> Signed-off-by: Qi Zhang <qi.z.zhang@intel.com>
> ---
>  drivers/net/ethernet/intel/ice/ice_flow.h        |   3 +
>  drivers/net/ethernet/intel/ice/ice_virtchnl_pf.c | 459
> +++++++++++++++++++++++
>  include/linux/avf/virtchnl.h                     | 187 ++++++++-
>  3 files changed, 641 insertions(+), 8 deletions(-)
> 
> diff --git a/drivers/net/ethernet/intel/ice/ice_flow.h
> b/drivers/net/ethernet/intel/ice/ice_flow.h
> index 68d1ec7cf8fd..f3cfcfd2c296 100644
> --- a/drivers/net/ethernet/intel/ice/ice_flow.h
> +++ b/drivers/net/ethernet/intel/ice/ice_flow.h
> @@ -8,6 +8,9 @@
>  #define ICE_FLOW_FLD_OFF_INVAL		0xffff
> 
>  /* Generate flow hash field from flow field type(s) */
> +#define ICE_FLOW_HASH_ETH	\
> +	(BIT_ULL(ICE_FLOW_FIELD_IDX_ETH_DA) | \
> +	 BIT_ULL(ICE_FLOW_FIELD_IDX_ETH_SA))
>  #define ICE_FLOW_HASH_IPV4	\
>  	(BIT_ULL(ICE_FLOW_FIELD_IDX_IPV4_SA) | \
>  	 BIT_ULL(ICE_FLOW_FIELD_IDX_IPV4_DA))
> diff --git a/drivers/net/ethernet/intel/ice/ice_virtchnl_pf.c
> b/drivers/net/ethernet/intel/ice/ice_virtchnl_pf.c
> index 8022300f9c8e..ede343016f94 100644
> --- a/drivers/net/ethernet/intel/ice/ice_virtchnl_pf.c
> +++ b/drivers/net/ethernet/intel/ice/ice_virtchnl_pf.c
> @@ -5,6 +5,246 @@
>  #include "ice_base.h"
>  #include "ice_lib.h"
>  #include "ice_fltr.h"
> +#include "ice_flow.h"
> +
> +#define FIELD_SELECTOR(proto_hdr_field) \
> +		(1UL << ((proto_hdr_field) & PROTO_HDR_FIELD_MASK))
> +
> +struct ice_vc_hdr_match_type {
> +	u32 vc_hdr;	/* virtchnl headers (VIRTCHNL_PROTO_HDR_XXX) */
> +	u32 ice_hdr;	/* ice headers (ICE_FLOW_SEG_HDR_XXX) */
> +};
> +
> +static const struct ice_vc_hdr_match_type ice_vc_hdr_list_os[] = {
> +	{VIRTCHNL_PROTO_HDR_NONE,	ICE_FLOW_SEG_HDR_NONE},
> +	{VIRTCHNL_PROTO_HDR_IPV4,	ICE_FLOW_SEG_HDR_IPV4 |
> +					ICE_FLOW_SEG_HDR_IPV_OTHER},
> +	{VIRTCHNL_PROTO_HDR_IPV6,	ICE_FLOW_SEG_HDR_IPV6 |
> +					ICE_FLOW_SEG_HDR_IPV_OTHER},
> +	{VIRTCHNL_PROTO_HDR_TCP,	ICE_FLOW_SEG_HDR_TCP},
> +	{VIRTCHNL_PROTO_HDR_UDP,	ICE_FLOW_SEG_HDR_UDP},
> +	{VIRTCHNL_PROTO_HDR_SCTP,	ICE_FLOW_SEG_HDR_SCTP},
> +};
> +
> +static const struct ice_vc_hdr_match_type ice_vc_hdr_list_comms[] = {
> +	{VIRTCHNL_PROTO_HDR_NONE,	ICE_FLOW_SEG_HDR_NONE},
> +	{VIRTCHNL_PROTO_HDR_ETH,	ICE_FLOW_SEG_HDR_ETH},
> +	{VIRTCHNL_PROTO_HDR_S_VLAN,	ICE_FLOW_SEG_HDR_VLAN},
> +	{VIRTCHNL_PROTO_HDR_C_VLAN,	ICE_FLOW_SEG_HDR_VLAN},
> +	{VIRTCHNL_PROTO_HDR_IPV4,	ICE_FLOW_SEG_HDR_IPV4 |
> +					ICE_FLOW_SEG_HDR_IPV_OTHER},
> +	{VIRTCHNL_PROTO_HDR_IPV6,	ICE_FLOW_SEG_HDR_IPV6 |
> +					ICE_FLOW_SEG_HDR_IPV_OTHER},
> +	{VIRTCHNL_PROTO_HDR_TCP,	ICE_FLOW_SEG_HDR_TCP},
> +	{VIRTCHNL_PROTO_HDR_UDP,	ICE_FLOW_SEG_HDR_UDP},
> +	{VIRTCHNL_PROTO_HDR_SCTP,	ICE_FLOW_SEG_HDR_SCTP},
> +	{VIRTCHNL_PROTO_HDR_PPPOE,	ICE_FLOW_SEG_HDR_PPPOE},
> +	{VIRTCHNL_PROTO_HDR_GTPU_IP,
> 	ICE_FLOW_SEG_HDR_GTPU_IP},
> +	{VIRTCHNL_PROTO_HDR_GTPU_EH,
> 	ICE_FLOW_SEG_HDR_GTPU_EH},
> +	{VIRTCHNL_PROTO_HDR_GTPU_EH_PDU_DWN,
> +					ICE_FLOW_SEG_HDR_GTPU_DWN},
> +	{VIRTCHNL_PROTO_HDR_GTPU_EH_PDU_UP,
> +					ICE_FLOW_SEG_HDR_GTPU_UP},
> +	{VIRTCHNL_PROTO_HDR_L2TPV3,	ICE_FLOW_SEG_HDR_L2TPV3},
> +	{VIRTCHNL_PROTO_HDR_ESP,	ICE_FLOW_SEG_HDR_ESP},
> +	{VIRTCHNL_PROTO_HDR_AH,		ICE_FLOW_SEG_HDR_AH},
> +	{VIRTCHNL_PROTO_HDR_PFCP,
> 	ICE_FLOW_SEG_HDR_PFCP_SESSION},
> +};
> +
> +struct ice_vc_hash_field_match_type {
> +	u32 vc_hdr;		/* virtchnl headers
> +				 * (VIRTCHNL_PROTO_HDR_XXX)
> +				 */
> +	u32 vc_hash_field;	/* virtchnl hash fields selector
> +				 *
> FIELD_SELECTOR((VIRTCHNL_PROTO_HDR_ETH_XXX))
> +				 */
> +	u64 ice_hash_field;	/* ice hash fields
> +				 * (BIT_ULL(ICE_FLOW_FIELD_IDX_XXX))
> +				 */
> +};
> +
> +static const struct
> +ice_vc_hash_field_match_type ice_vc_hash_field_list_os[] = {
> +	{VIRTCHNL_PROTO_HDR_IPV4,
> FIELD_SELECTOR(VIRTCHNL_PROTO_HDR_IPV4_SRC),
> +		BIT_ULL(ICE_FLOW_FIELD_IDX_IPV4_SA)},
> +	{VIRTCHNL_PROTO_HDR_IPV4,
> FIELD_SELECTOR(VIRTCHNL_PROTO_HDR_IPV4_DST),
> +		BIT_ULL(ICE_FLOW_FIELD_IDX_IPV4_DA)},
> +	{VIRTCHNL_PROTO_HDR_IPV4,
> FIELD_SELECTOR(VIRTCHNL_PROTO_HDR_IPV4_SRC) |
> +		FIELD_SELECTOR(VIRTCHNL_PROTO_HDR_IPV4_DST),
> +		ICE_FLOW_HASH_IPV4},
> +	{VIRTCHNL_PROTO_HDR_IPV4,
> FIELD_SELECTOR(VIRTCHNL_PROTO_HDR_IPV4_SRC) |
> +		FIELD_SELECTOR(VIRTCHNL_PROTO_HDR_IPV4_PROT),
> +		BIT_ULL(ICE_FLOW_FIELD_IDX_IPV4_SA) |
> +		BIT_ULL(ICE_FLOW_FIELD_IDX_IPV4_PROT)},
> +	{VIRTCHNL_PROTO_HDR_IPV4,
> FIELD_SELECTOR(VIRTCHNL_PROTO_HDR_IPV4_DST) |
> +		FIELD_SELECTOR(VIRTCHNL_PROTO_HDR_IPV4_PROT),
> +		BIT_ULL(ICE_FLOW_FIELD_IDX_IPV4_DA) |
> +		BIT_ULL(ICE_FLOW_FIELD_IDX_IPV4_PROT)},
> +	{VIRTCHNL_PROTO_HDR_IPV4,
> FIELD_SELECTOR(VIRTCHNL_PROTO_HDR_IPV4_SRC) |
> +		FIELD_SELECTOR(VIRTCHNL_PROTO_HDR_IPV4_DST) |
> +		FIELD_SELECTOR(VIRTCHNL_PROTO_HDR_IPV4_PROT),
> +		ICE_FLOW_HASH_IPV4 |
> BIT_ULL(ICE_FLOW_FIELD_IDX_IPV4_PROT)},
> +	{VIRTCHNL_PROTO_HDR_IPV4,
> FIELD_SELECTOR(VIRTCHNL_PROTO_HDR_IPV4_PROT),
> +		BIT_ULL(ICE_FLOW_FIELD_IDX_IPV4_PROT)},
> +	{VIRTCHNL_PROTO_HDR_IPV6,
> FIELD_SELECTOR(VIRTCHNL_PROTO_HDR_IPV6_SRC),
> +		BIT_ULL(ICE_FLOW_FIELD_IDX_IPV6_SA)},
> +	{VIRTCHNL_PROTO_HDR_IPV6,
> FIELD_SELECTOR(VIRTCHNL_PROTO_HDR_IPV6_DST),
> +		BIT_ULL(ICE_FLOW_FIELD_IDX_IPV6_DA)},
> +	{VIRTCHNL_PROTO_HDR_IPV6,
> FIELD_SELECTOR(VIRTCHNL_PROTO_HDR_IPV6_SRC) |
> +		FIELD_SELECTOR(VIRTCHNL_PROTO_HDR_IPV6_DST),
> +		ICE_FLOW_HASH_IPV6},
> +	{VIRTCHNL_PROTO_HDR_IPV6,
> FIELD_SELECTOR(VIRTCHNL_PROTO_HDR_IPV6_SRC) |
> +		FIELD_SELECTOR(VIRTCHNL_PROTO_HDR_IPV6_PROT),
> +		BIT_ULL(ICE_FLOW_FIELD_IDX_IPV6_SA) |
> +		BIT_ULL(ICE_FLOW_FIELD_IDX_IPV6_PROT)},
> +	{VIRTCHNL_PROTO_HDR_IPV6,
> FIELD_SELECTOR(VIRTCHNL_PROTO_HDR_IPV6_DST) |
> +		FIELD_SELECTOR(VIRTCHNL_PROTO_HDR_IPV6_PROT),
> +		BIT_ULL(ICE_FLOW_FIELD_IDX_IPV6_DA) |
> +		BIT_ULL(ICE_FLOW_FIELD_IDX_IPV6_PROT)},
> +	{VIRTCHNL_PROTO_HDR_IPV6,
> FIELD_SELECTOR(VIRTCHNL_PROTO_HDR_IPV6_SRC) |
> +		FIELD_SELECTOR(VIRTCHNL_PROTO_HDR_IPV6_DST) |
> +		FIELD_SELECTOR(VIRTCHNL_PROTO_HDR_IPV6_PROT),
> +		ICE_FLOW_HASH_IPV6 |
> BIT_ULL(ICE_FLOW_FIELD_IDX_IPV6_PROT)},
> +	{VIRTCHNL_PROTO_HDR_IPV6,
> FIELD_SELECTOR(VIRTCHNL_PROTO_HDR_IPV6_PROT),
> +		BIT_ULL(ICE_FLOW_FIELD_IDX_IPV6_PROT)},
> +	{VIRTCHNL_PROTO_HDR_TCP,
> +		FIELD_SELECTOR(VIRTCHNL_PROTO_HDR_TCP_SRC_PORT),
> +		BIT_ULL(ICE_FLOW_FIELD_IDX_TCP_SRC_PORT)},
> +	{VIRTCHNL_PROTO_HDR_TCP,
> +		FIELD_SELECTOR(VIRTCHNL_PROTO_HDR_TCP_DST_PORT),
> +		BIT_ULL(ICE_FLOW_FIELD_IDX_TCP_DST_PORT)},
> +	{VIRTCHNL_PROTO_HDR_TCP,
> +		FIELD_SELECTOR(VIRTCHNL_PROTO_HDR_TCP_SRC_PORT) |
> +		FIELD_SELECTOR(VIRTCHNL_PROTO_HDR_TCP_DST_PORT),
> +		ICE_FLOW_HASH_TCP_PORT},
> +	{VIRTCHNL_PROTO_HDR_UDP,
> +		FIELD_SELECTOR(VIRTCHNL_PROTO_HDR_UDP_SRC_PORT),
> +		BIT_ULL(ICE_FLOW_FIELD_IDX_UDP_SRC_PORT)},
> +	{VIRTCHNL_PROTO_HDR_UDP,
> +		FIELD_SELECTOR(VIRTCHNL_PROTO_HDR_UDP_DST_PORT),
> +		BIT_ULL(ICE_FLOW_FIELD_IDX_UDP_DST_PORT)},
> +	{VIRTCHNL_PROTO_HDR_UDP,
> +		FIELD_SELECTOR(VIRTCHNL_PROTO_HDR_UDP_SRC_PORT) |
> +		FIELD_SELECTOR(VIRTCHNL_PROTO_HDR_UDP_DST_PORT),
> +		ICE_FLOW_HASH_UDP_PORT},
> +	{VIRTCHNL_PROTO_HDR_SCTP,
> +		FIELD_SELECTOR(VIRTCHNL_PROTO_HDR_SCTP_SRC_PORT),
> +		BIT_ULL(ICE_FLOW_FIELD_IDX_SCTP_SRC_PORT)},
> +	{VIRTCHNL_PROTO_HDR_SCTP,
> +		FIELD_SELECTOR(VIRTCHNL_PROTO_HDR_SCTP_DST_PORT),
> +		BIT_ULL(ICE_FLOW_FIELD_IDX_SCTP_DST_PORT)},
> +	{VIRTCHNL_PROTO_HDR_SCTP,
> +		FIELD_SELECTOR(VIRTCHNL_PROTO_HDR_SCTP_SRC_PORT) |
> +		FIELD_SELECTOR(VIRTCHNL_PROTO_HDR_SCTP_DST_PORT),
> +		ICE_FLOW_HASH_SCTP_PORT},
> +};
> +
> +static const struct
> +ice_vc_hash_field_match_type ice_vc_hash_field_list_comms[] = {
> +	{VIRTCHNL_PROTO_HDR_ETH,
> FIELD_SELECTOR(VIRTCHNL_PROTO_HDR_ETH_SRC),
> +		BIT_ULL(ICE_FLOW_FIELD_IDX_ETH_SA)},
> +	{VIRTCHNL_PROTO_HDR_ETH,
> FIELD_SELECTOR(VIRTCHNL_PROTO_HDR_ETH_DST),
> +		BIT_ULL(ICE_FLOW_FIELD_IDX_ETH_DA)},
> +	{VIRTCHNL_PROTO_HDR_ETH,
> FIELD_SELECTOR(VIRTCHNL_PROTO_HDR_ETH_SRC) |
> +		FIELD_SELECTOR(VIRTCHNL_PROTO_HDR_ETH_DST),
> +		ICE_FLOW_HASH_ETH},
> +	{VIRTCHNL_PROTO_HDR_ETH,
> +		FIELD_SELECTOR(VIRTCHNL_PROTO_HDR_ETH_ETHERTYPE),
> +		BIT_ULL(ICE_FLOW_FIELD_IDX_ETH_TYPE)},
> +	{VIRTCHNL_PROTO_HDR_S_VLAN,
> +		FIELD_SELECTOR(VIRTCHNL_PROTO_HDR_S_VLAN_ID),
> +		BIT_ULL(ICE_FLOW_FIELD_IDX_S_VLAN)},
> +	{VIRTCHNL_PROTO_HDR_C_VLAN,
> +		FIELD_SELECTOR(VIRTCHNL_PROTO_HDR_C_VLAN_ID),
> +		BIT_ULL(ICE_FLOW_FIELD_IDX_C_VLAN)},
> +	{VIRTCHNL_PROTO_HDR_IPV4,
> FIELD_SELECTOR(VIRTCHNL_PROTO_HDR_IPV4_SRC),
> +		BIT_ULL(ICE_FLOW_FIELD_IDX_IPV4_SA)},
> +	{VIRTCHNL_PROTO_HDR_IPV4,
> FIELD_SELECTOR(VIRTCHNL_PROTO_HDR_IPV4_DST),
> +		BIT_ULL(ICE_FLOW_FIELD_IDX_IPV4_DA)},
> +	{VIRTCHNL_PROTO_HDR_IPV4,
> FIELD_SELECTOR(VIRTCHNL_PROTO_HDR_IPV4_SRC) |
> +		FIELD_SELECTOR(VIRTCHNL_PROTO_HDR_IPV4_DST),
> +		ICE_FLOW_HASH_IPV4},
> +	{VIRTCHNL_PROTO_HDR_IPV4,
> FIELD_SELECTOR(VIRTCHNL_PROTO_HDR_IPV4_SRC) |
> +		FIELD_SELECTOR(VIRTCHNL_PROTO_HDR_IPV4_PROT),
> +		BIT_ULL(ICE_FLOW_FIELD_IDX_IPV4_SA) |
> +		BIT_ULL(ICE_FLOW_FIELD_IDX_IPV4_PROT)},
> +	{VIRTCHNL_PROTO_HDR_IPV4,
> FIELD_SELECTOR(VIRTCHNL_PROTO_HDR_IPV4_DST) |
> +		FIELD_SELECTOR(VIRTCHNL_PROTO_HDR_IPV4_PROT),
> +		BIT_ULL(ICE_FLOW_FIELD_IDX_IPV4_DA) |
> +		BIT_ULL(ICE_FLOW_FIELD_IDX_IPV4_PROT)},
> +	{VIRTCHNL_PROTO_HDR_IPV4,
> FIELD_SELECTOR(VIRTCHNL_PROTO_HDR_IPV4_SRC) |
> +		FIELD_SELECTOR(VIRTCHNL_PROTO_HDR_IPV4_DST) |
> +		FIELD_SELECTOR(VIRTCHNL_PROTO_HDR_IPV4_PROT),
> +		ICE_FLOW_HASH_IPV4 |
> BIT_ULL(ICE_FLOW_FIELD_IDX_IPV4_PROT)},
> +	{VIRTCHNL_PROTO_HDR_IPV4,
> FIELD_SELECTOR(VIRTCHNL_PROTO_HDR_IPV4_PROT),
> +		BIT_ULL(ICE_FLOW_FIELD_IDX_IPV4_PROT)},
> +	{VIRTCHNL_PROTO_HDR_IPV6,
> FIELD_SELECTOR(VIRTCHNL_PROTO_HDR_IPV6_SRC),
> +		BIT_ULL(ICE_FLOW_FIELD_IDX_IPV6_SA)},
> +	{VIRTCHNL_PROTO_HDR_IPV6,
> FIELD_SELECTOR(VIRTCHNL_PROTO_HDR_IPV6_DST),
> +		BIT_ULL(ICE_FLOW_FIELD_IDX_IPV6_DA)},
> +	{VIRTCHNL_PROTO_HDR_IPV6,
> FIELD_SELECTOR(VIRTCHNL_PROTO_HDR_IPV6_SRC) |
> +		FIELD_SELECTOR(VIRTCHNL_PROTO_HDR_IPV6_DST),
> +		ICE_FLOW_HASH_IPV6},
> +	{VIRTCHNL_PROTO_HDR_IPV6,
> FIELD_SELECTOR(VIRTCHNL_PROTO_HDR_IPV6_SRC) |
> +		FIELD_SELECTOR(VIRTCHNL_PROTO_HDR_IPV6_PROT),
> +		BIT_ULL(ICE_FLOW_FIELD_IDX_IPV6_SA) |
> +		BIT_ULL(ICE_FLOW_FIELD_IDX_IPV6_PROT)},
> +	{VIRTCHNL_PROTO_HDR_IPV6,
> FIELD_SELECTOR(VIRTCHNL_PROTO_HDR_IPV6_DST) |
> +		FIELD_SELECTOR(VIRTCHNL_PROTO_HDR_IPV6_PROT),
> +		BIT_ULL(ICE_FLOW_FIELD_IDX_IPV6_DA) |
> +		BIT_ULL(ICE_FLOW_FIELD_IDX_IPV6_PROT)},
> +	{VIRTCHNL_PROTO_HDR_IPV6,
> FIELD_SELECTOR(VIRTCHNL_PROTO_HDR_IPV6_SRC) |
> +		FIELD_SELECTOR(VIRTCHNL_PROTO_HDR_IPV6_DST) |
> +		FIELD_SELECTOR(VIRTCHNL_PROTO_HDR_IPV6_PROT),
> +		ICE_FLOW_HASH_IPV6 |
> BIT_ULL(ICE_FLOW_FIELD_IDX_IPV6_PROT)},
> +	{VIRTCHNL_PROTO_HDR_IPV6,
> FIELD_SELECTOR(VIRTCHNL_PROTO_HDR_IPV6_PROT),
> +		BIT_ULL(ICE_FLOW_FIELD_IDX_IPV6_PROT)},
> +	{VIRTCHNL_PROTO_HDR_TCP,
> +		FIELD_SELECTOR(VIRTCHNL_PROTO_HDR_TCP_SRC_PORT),
> +		BIT_ULL(ICE_FLOW_FIELD_IDX_TCP_SRC_PORT)},
> +	{VIRTCHNL_PROTO_HDR_TCP,
> +		FIELD_SELECTOR(VIRTCHNL_PROTO_HDR_TCP_DST_PORT),
> +		BIT_ULL(ICE_FLOW_FIELD_IDX_TCP_DST_PORT)},
> +	{VIRTCHNL_PROTO_HDR_TCP,
> +		FIELD_SELECTOR(VIRTCHNL_PROTO_HDR_TCP_SRC_PORT) |
> +		FIELD_SELECTOR(VIRTCHNL_PROTO_HDR_TCP_DST_PORT),
> +		ICE_FLOW_HASH_TCP_PORT},
> +	{VIRTCHNL_PROTO_HDR_UDP,
> +		FIELD_SELECTOR(VIRTCHNL_PROTO_HDR_UDP_SRC_PORT),
> +		BIT_ULL(ICE_FLOW_FIELD_IDX_UDP_SRC_PORT)},
> +	{VIRTCHNL_PROTO_HDR_UDP,
> +		FIELD_SELECTOR(VIRTCHNL_PROTO_HDR_UDP_DST_PORT),
> +		BIT_ULL(ICE_FLOW_FIELD_IDX_UDP_DST_PORT)},
> +	{VIRTCHNL_PROTO_HDR_UDP,
> +		FIELD_SELECTOR(VIRTCHNL_PROTO_HDR_UDP_SRC_PORT) |
> +		FIELD_SELECTOR(VIRTCHNL_PROTO_HDR_UDP_DST_PORT),
> +		ICE_FLOW_HASH_UDP_PORT},
> +	{VIRTCHNL_PROTO_HDR_SCTP,
> +		FIELD_SELECTOR(VIRTCHNL_PROTO_HDR_SCTP_SRC_PORT),
> +		BIT_ULL(ICE_FLOW_FIELD_IDX_SCTP_SRC_PORT)},
> +	{VIRTCHNL_PROTO_HDR_SCTP,
> +		FIELD_SELECTOR(VIRTCHNL_PROTO_HDR_SCTP_DST_PORT),
> +		BIT_ULL(ICE_FLOW_FIELD_IDX_SCTP_DST_PORT)},
> +	{VIRTCHNL_PROTO_HDR_SCTP,
> +		FIELD_SELECTOR(VIRTCHNL_PROTO_HDR_SCTP_SRC_PORT) |
> +		FIELD_SELECTOR(VIRTCHNL_PROTO_HDR_SCTP_DST_PORT),
> +		ICE_FLOW_HASH_SCTP_PORT},
> +	{VIRTCHNL_PROTO_HDR_PPPOE,
> +		FIELD_SELECTOR(VIRTCHNL_PROTO_HDR_PPPOE_SESS_ID),
> +		BIT_ULL(ICE_FLOW_FIELD_IDX_PPPOE_SESS_ID)},
> +	{VIRTCHNL_PROTO_HDR_GTPU_IP,
> +		FIELD_SELECTOR(VIRTCHNL_PROTO_HDR_GTPU_IP_TEID),
> +		BIT_ULL(ICE_FLOW_FIELD_IDX_GTPU_IP_TEID)},
> +	{VIRTCHNL_PROTO_HDR_L2TPV3,
> +		FIELD_SELECTOR(VIRTCHNL_PROTO_HDR_L2TPV3_SESS_ID),
> +		BIT_ULL(ICE_FLOW_FIELD_IDX_L2TPV3_SESS_ID)},
> +	{VIRTCHNL_PROTO_HDR_ESP,
> FIELD_SELECTOR(VIRTCHNL_PROTO_HDR_ESP_SPI),
> +		BIT_ULL(ICE_FLOW_FIELD_IDX_ESP_SPI)},
> +	{VIRTCHNL_PROTO_HDR_AH,
> FIELD_SELECTOR(VIRTCHNL_PROTO_HDR_AH_SPI),
> +		BIT_ULL(ICE_FLOW_FIELD_IDX_AH_SPI)},
> +	{VIRTCHNL_PROTO_HDR_PFCP,
> FIELD_SELECTOR(VIRTCHNL_PROTO_HDR_PFCP_SEID),
> +		BIT_ULL(ICE_FLOW_FIELD_IDX_PFCP_SEID)},
> +};
> 
>  /**
>   * ice_validate_vf_id - helper to check if VF ID is valid @@ -2009,6 +2249,9
> @@ static int ice_vc_get_vf_res_msg(struct ice_vf *vf, u8 *msg)
>  	if (vf->driver_caps & VIRTCHNL_VF_CAP_ADV_LINK_SPEED)
>  		vfres->vf_cap_flags |= VIRTCHNL_VF_CAP_ADV_LINK_SPEED;
> 
> +	if (vf->driver_caps & VIRTCHNL_VF_OFFLOAD_ADV_RSS_PF)
> +		vfres->vf_cap_flags |= VIRTCHNL_VF_OFFLOAD_ADV_RSS_PF;
> +
>  	/* Negotiate DCF capability. */
>  	if (vf->driver_caps & VIRTCHNL_VF_CAP_DCF) {
>  		if (!ice_check_dcf_allowed(vf)) {
> @@ -2141,6 +2384,216 @@ static bool ice_vc_isvalid_ring_len(u16 ring_len)  }
> 
>  /**
> + * ice_vc_parse_rss_cfg - parses hash fields and headers from
> + * a specific virtchnl RSS cfg
> + * @hw: pointer to the hardware
> + * @rss_cfg: pointer to the virtchnl rss cfg
> + * @addl_hdrs: pointer to the protocol header fields
> +(ICE_FLOW_SEG_HDR_*)
> + * to configure
> + * @hash_flds: pointer to the hash bit fields (ICE_FLOW_HASH_*) to
> +configure
> + *
> + * Return true if all the protocol header and hash fields in the rss
> +cfg could
> + * be parsed, else return false
> + *
> + * This function parses the virtchnl rss cfg to be the intended
> + * hash fields and the intended header for RSS configuration  */ static
> +bool ice_vc_parse_rss_cfg(struct ice_hw *hw, struct virtchnl_rss_cfg
> +*rss_cfg,
> +		     u32 *addl_hdrs, u64 *hash_flds)
> +{
> +	const struct ice_vc_hash_field_match_type *hf_list;
> +	const struct ice_vc_hdr_match_type *hdr_list;
> +	int i, hf_list_len, hdr_list_len;
> +
> +	if (!strncmp(hw->active_pkg_name, "ICE COMMS Package",
> +		     sizeof(hw->active_pkg_name))) {
> +		hf_list = ice_vc_hash_field_list_comms;
> +		hf_list_len = ARRAY_SIZE(ice_vc_hash_field_list_comms);
> +		hdr_list = ice_vc_hdr_list_comms;
> +		hdr_list_len = ARRAY_SIZE(ice_vc_hdr_list_comms);
> +	} else {
> +		hf_list = ice_vc_hash_field_list_os;
> +		hf_list_len = ARRAY_SIZE(ice_vc_hash_field_list_os);
> +		hdr_list = ice_vc_hdr_list_os;
> +		hdr_list_len = ARRAY_SIZE(ice_vc_hdr_list_os);
> +	}
> +
> +	for (i = 0; i < rss_cfg->proto_hdrs.count; i++) {
> +		struct virtchnl_proto_hdr *proto_hdr =
> +				&rss_cfg->proto_hdrs.proto_hdr[i];

This might all fit on one line

> +		bool hdr_found = false;
> +		int j;
> +
> +		/* Find matched ice headers according to virtchnl headers. */
> +		for (j = 0; j < hdr_list_len; j++) {
> +			struct ice_vc_hdr_match_type hdr_map =
> +				hdr_list[j];

This definitely can fit on one line (no wrapping needed)

> +
> +			if (proto_hdr->type == hdr_map.vc_hdr) {
> +				*addl_hdrs |= hdr_map.ice_hdr;
> +				hdr_found = true;
> +			}
> +		}
> +
> +		if (!hdr_found)
> +			return false;
> +
> +		/* Find matched ice hash fields according to
> +		 * virtchnl hash fields.
> +		 */
> +		for (j = 0; j < hf_list_len; j++) {
> +			struct ice_vc_hash_field_match_type hf_map =
> +				hf_list[j];

Here too

> +
> +			if (proto_hdr->type == hf_map.vc_hdr &&
> +			    proto_hdr->field_selector ==
> +			     hf_map.vc_hash_field) {

Overzealous wrapping here

> +				*hash_flds |= hf_map.ice_hash_field;
> +				break;
> +			}
> +		}
> +	}
> +
> +	return true;
> +}
> +
> +/**
> + * ice_vf_adv_rss_offload_ena - determine if capabilities support
> +advanced
> + * rss offloads
> + * @caps: VF driver negotiated capabilities
> + *
> + * Return true if VIRTCHNL_VF_OFFLOAD_ADV_RSS_PF capability is set,
> + * else return false
> + */
> +static bool ice_vf_adv_rss_offload_ena(u32 caps) {
> +	return !!(caps & VIRTCHNL_VF_OFFLOAD_ADV_RSS_PF); }
> +
> +/**
> + * ice_vc_handle_rss_cfg
> + * @vf: pointer to the VF info
> + * @msg: pointer to the msg buffer
> + * @add: add a rss cfg if true, otherwise delete a rss cfg
> + *
> + * This function adds/deletes a rss cfg  */ static int
> +ice_vc_handle_rss_cfg(struct ice_vf *vf, u8 *msg, bool add) {
> +	struct virtchnl_rss_cfg *rss_cfg = (struct virtchnl_rss_cfg *)msg;
> +	enum virtchnl_status_code v_ret = VIRTCHNL_STATUS_SUCCESS;
> +	u32 v_opcode = add ? VIRTCHNL_OP_ADD_RSS_CFG :
> +			VIRTCHNL_OP_DEL_RSS_CFG;

RCT issues and wrapping issues

> +	struct device *dev = ice_pf_to_dev(vf->pf);
> +	struct ice_hw *hw = &vf->pf->hw;
> +	struct ice_vsi *vsi;
> +
> +	if (!test_bit(ICE_FLAG_RSS_ENA, vf->pf->flags)) {
> +		dev_dbg(dev, "VF %d attempting to configure RSS, but RSS is
> not supported by the PF\n",
> +			vf->vf_id);
> +		v_ret = VIRTCHNL_STATUS_ERR_NOT_SUPPORTED;
> +		goto error_param;
> +	}
> +
> +	if (!ice_vf_adv_rss_offload_ena(vf->driver_caps)) {
> +		dev_dbg(dev, "VF %d attempting to configure RSS, but Advanced
> RSS offload is not supported\n",
> +			vf->vf_id);
> +		v_ret = VIRTCHNL_STATUS_ERR_PARAM;
> +		goto error_param;
> +	}
> +
> +	if (!test_bit(ICE_VF_STATE_ACTIVE, vf->vf_states)) {
> +		v_ret = VIRTCHNL_STATUS_ERR_PARAM;
> +		goto error_param;
> +	}
> +
> +	if (rss_cfg->proto_hdrs.count > VIRTCHNL_MAX_NUM_PROTO_HDRS ||
> +	    rss_cfg->rss_algorithm <
> VIRTCHNL_RSS_ALG_TOEPLITZ_ASYMMETRIC ||
> +	    rss_cfg->rss_algorithm > VIRTCHNL_RSS_ALG_XOR_SYMMETRIC) {
> +		dev_dbg(dev, "VF %d attempting to configure RSS, but RSS
> configuration is not valid\n",
> +			vf->vf_id);
> +		v_ret = VIRTCHNL_STATUS_ERR_PARAM;
> +		goto error_param;
> +	}
> +
> +	vsi = vf->pf->vsi[vf->lan_vsi_idx];
> +	if (!vsi) {
> +		v_ret = VIRTCHNL_STATUS_ERR_PARAM;
> +		goto error_param;
> +	}
> +
> +	if (rss_cfg->rss_algorithm == VIRTCHNL_RSS_ALG_R_ASYMMETRIC) {
> +		struct ice_vsi_ctx *ctx;
> +		enum ice_status status;
> +		u8 lut_type, hash_type;
> +
> +		lut_type = ICE_AQ_VSI_Q_OPT_RSS_LUT_VSI;
> +		hash_type = add ? ICE_AQ_VSI_Q_OPT_RSS_XOR :
> +				ICE_AQ_VSI_Q_OPT_RSS_TPLZ;
> +
> +		ctx = kzalloc(sizeof(*ctx), GFP_KERNEL);
> +		if (!ctx) {
> +			v_ret = VIRTCHNL_STATUS_ERR_NO_MEMORY;
> +			goto error_param;
> +		}
> +
> +		ctx->info.q_opt_rss = ((lut_type <<
> +					ICE_AQ_VSI_Q_OPT_RSS_LUT_S) &
> +				       ICE_AQ_VSI_Q_OPT_RSS_LUT_M) |
> +				       (hash_type &
> +					ICE_AQ_VSI_Q_OPT_RSS_HASH_M);
> +
> +		/* Preserve existing queueing option setting */
> +		ctx->info.q_opt_rss |= (vsi->info.q_opt_rss &
> +					  ICE_AQ_VSI_Q_OPT_RSS_GBL_LUT_M);
> +		ctx->info.q_opt_tc = vsi->info.q_opt_tc;
> +		ctx->info.q_opt_flags = vsi->info.q_opt_rss;
> +
> +		ctx->info.valid_sections =
> +				cpu_to_le16(ICE_AQ_VSI_PROP_Q_OPT_VALID);
> +
> +		status = ice_update_vsi(hw, vsi->idx, ctx, NULL);
> +		if (status) {
> +			dev_err(dev,
> +				"update VSI for RSS failed, err %s aq_err %s\n",
> +				ice_stat_str(status),
> +				ice_aq_str(hw->adminq.sq_last_status));
> +			v_ret = VIRTCHNL_STATUS_ERR_PARAM;
> +		} else {
> +			vsi->info.q_opt_rss = ctx->info.q_opt_rss;
> +		}
> +
> +		kfree(ctx);
> +	} else {
> +		u32 addl_hdrs = ICE_FLOW_SEG_HDR_NONE;
> +		u64 hash_flds = ICE_HASH_INVALID;
> +
> +		if (!ice_vc_parse_rss_cfg(hw, rss_cfg, &addl_hdrs,
> +					  &hash_flds)) {
> +			v_ret = VIRTCHNL_STATUS_ERR_PARAM;
> +			goto error_param;
> +		}
> +
> +		if (add) {
> +			if (ice_add_rss_cfg(hw, vsi->idx, hash_flds,
> +					    addl_hdrs)) {
> +				v_ret = VIRTCHNL_STATUS_ERR_PARAM;
> +				dev_err(dev,
> +					"ice_add_rss_cfg failed for vsi = %d, v_ret
> = %d\n",
> +					vsi->vsi_num, v_ret);
> +			}
> +		} else {
> +			v_ret = VIRTCHNL_STATUS_ERR_PARAM;
> +			dev_err(dev, "RSS removal not support\n");
> +		}
> +	}
> +
> +error_param:
> +	return ice_vc_send_msg_to_vf(vf, v_opcode, v_ret, NULL, 0); }
> +
> +/**
>   * ice_vc_config_rss_key
>   * @vf: pointer to the VF info
>   * @msg: pointer to the msg buffer
> @@ -4221,6 +4674,12 @@ void ice_vc_process_vf_msg(struct ice_pf *pf,
> struct ice_rq_event_info *event)
>  	case VIRTCHNL_OP_DCF_GET_PKG_INFO:
>  		err = ice_vc_dcf_query_pkg_info(vf);
>  		break;
> +	case VIRTCHNL_OP_ADD_RSS_CFG:
> +		err = ice_vc_handle_rss_cfg(vf, msg, true);
> +		break;
> +	case VIRTCHNL_OP_DEL_RSS_CFG:
> +		err = ice_vc_handle_rss_cfg(vf, msg, false);
> +		break;
>  	case VIRTCHNL_OP_UNKNOWN:
>  	default:
>  		dev_err(dev, "Unsupported opcode %d from VF %d\n",
> v_opcode, diff --git a/include/linux/avf/virtchnl.h b/include/linux/avf/virtchnl.h
> index 825cdc0e9ffe..d7e5263fd2ec 100644
> --- a/include/linux/avf/virtchnl.h
> +++ b/include/linux/avf/virtchnl.h
> @@ -143,6 +143,8 @@ enum virtchnl_ops {
>  	VIRTCHNL_OP_DCF_GET_VSI_MAP = 42,
>  	VIRTCHNL_OP_DCF_GET_PKG_INFO = 43,
>  	VIRTCHNL_OP_GET_SUPPORTED_RXDIDS = 44,
> +	VIRTCHNL_OP_ADD_RSS_CFG = 45,
> +	VIRTCHNL_OP_DEL_RSS_CFG = 46,
>  	/* New major set of opcodes introduced and so leaving room for
>  	 * old misc opcodes to be added in future. Also these opcodes may only
>  	 * be used if both the PF and VF have successfully negotiated the @@ -
> 283,6 +285,7 @@ VIRTCHNL_CHECK_STRUCT_LEN(16, virtchnl_vsi_resource);
>  #define VIRTCHNL_VF_OFFLOAD_RX_ENCAP_CSUM	0X00400000
>  #define VIRTCHNL_VF_OFFLOAD_ADQ			0X00800000
>  #define VIRTCHNL_VF_OFFLOAD_RX_FLEX_DESC	0X04000000
> +#define VIRTCHNL_VF_OFFLOAD_ADV_RSS_PF		0X08000000
>  #define VIRTCHNL_VF_CAP_DCF			0X40000000
> 
>  /* Define below the capability flags that are not offloads */ @@ -557,6
> +560,14 @@ struct virtchnl_rss_hena {
> 
>  VIRTCHNL_CHECK_STRUCT_LEN(8, virtchnl_rss_hena);
> 
> +/* Type of RSS algorithm */
> +enum virtchnl_rss_algorithm {
> +	VIRTCHNL_RSS_ALG_TOEPLITZ_ASYMMETRIC	= 0,
> +	VIRTCHNL_RSS_ALG_R_ASYMMETRIC		= 1,
> +	VIRTCHNL_RSS_ALG_TOEPLITZ_SYMMETRIC	= 2,
> +	VIRTCHNL_RSS_ALG_XOR_SYMMETRIC		= 3,
> +};
> +
>  /* VIRTCHNL_OP_ENABLE_CHANNELS
>   * VIRTCHNL_OP_DISABLE_CHANNELS
>   * VF sends these messages to enable or disable channels based on @@ -
> 773,6 +784,170 @@ enum virtchnl_vfr_states {
>  	VIRTCHNL_VFR_VFACTIVE,
>  };
> 
> +#define VIRTCHNL_MAX_NUM_PROTO_HDRS	32
> +#define PROTO_HDR_SHIFT			5
> +#define PROTO_HDR_FIELD_START(proto_hdr_type) \
> +					(proto_hdr_type << PROTO_HDR_SHIFT)
> #define PROTO_HDR_FIELD_MASK
> +((1UL << PROTO_HDR_SHIFT) - 1)
> +
> +/* VF use these macros to configure each protocol header.
> + * Specify which protocol headers and protocol header fields base on
> + * virtchnl_proto_hdr_type and virtchnl_proto_hdr_field.
> + * @param hdr: a struct of virtchnl_proto_hdr
> + * @param hdr_type: ETH/IPV4/TCP, etc
> + * @param field: SRC/DST/TEID/SPI, etc
> + */
> +#define VIRTCHNL_ADD_PROTO_HDR_FIELD(hdr, field) \
> +	((hdr)->field_selector |= BIT((field) & PROTO_HDR_FIELD_MASK))
> #define
> +VIRTCHNL_DEL_PROTO_HDR_FIELD(hdr, field) \
> +	((hdr)->field_selector &= ~BIT((field) & PROTO_HDR_FIELD_MASK))
> +#define VIRTCHNL_TEST_PROTO_HDR_FIELD(hdr, val) \
> +	((hdr)->field_selector & BIT((val) & PROTO_HDR_FIELD_MASK))
> +#define VIRTCHNL_GET_PROTO_HDR_FIELD(hdr)	((hdr)->field_selector)
> +
> +#define VIRTCHNL_ADD_PROTO_HDR_FIELD_BIT(hdr, hdr_type, field) \
> +	(VIRTCHNL_ADD_PROTO_HDR_FIELD(hdr, \
> +		VIRTCHNL_PROTO_HDR_ ## hdr_type ## _ ## field)) #define
> +VIRTCHNL_DEL_PROTO_HDR_FIELD_BIT(hdr, hdr_type, field) \
> +	(VIRTCHNL_DEL_PROTO_HDR_FIELD(hdr, \
> +		VIRTCHNL_PROTO_HDR_ ## hdr_type ## _ ## field))
> +
> +#define VIRTCHNL_SET_PROTO_HDR_TYPE(hdr, hdr_type) \
> +	((hdr)->type = VIRTCHNL_PROTO_HDR_ ## hdr_type) #define
> +VIRTCHNL_GET_PROTO_HDR_TYPE(hdr) \
> +	(((hdr)->type) >> PROTO_HDR_SHIFT)
> +#define VIRTCHNL_TEST_PROTO_HDR_TYPE(hdr, val) \
> +	((hdr)->type == ((val) >> PROTO_HDR_SHIFT)) #define
> +VIRTCHNL_TEST_PROTO_HDR(hdr, val) \
> +	(VIRTCHNL_TEST_PROTO_HDR_TYPE(hdr, val) && \
> +	 VIRTCHNL_TEST_PROTO_HDR_FIELD(hdr, val))
> +
> +/* Protocol header type within a packet segment. A segment consists of
> +one or
> + * more protocol headers that make up a logical group of protocol
> +headers. Each
> + * logical group of protocol headers encapsulates or is encapsulated
> +using/by
> + * tunneling or encapsulation protocols for network virtualization.
> + */
> +enum virtchnl_proto_hdr_type {
> +	VIRTCHNL_PROTO_HDR_NONE,
> +	VIRTCHNL_PROTO_HDR_ETH,
> +	VIRTCHNL_PROTO_HDR_S_VLAN,
> +	VIRTCHNL_PROTO_HDR_C_VLAN,
> +	VIRTCHNL_PROTO_HDR_IPV4,
> +	VIRTCHNL_PROTO_HDR_IPV6,
> +	VIRTCHNL_PROTO_HDR_TCP,
> +	VIRTCHNL_PROTO_HDR_UDP,
> +	VIRTCHNL_PROTO_HDR_SCTP,
> +	VIRTCHNL_PROTO_HDR_GTPU_IP,
> +	VIRTCHNL_PROTO_HDR_GTPU_EH,
> +	VIRTCHNL_PROTO_HDR_GTPU_EH_PDU_DWN,
> +	VIRTCHNL_PROTO_HDR_GTPU_EH_PDU_UP,
> +	VIRTCHNL_PROTO_HDR_PPPOE,
> +	VIRTCHNL_PROTO_HDR_L2TPV3,
> +	VIRTCHNL_PROTO_HDR_ESP,
> +	VIRTCHNL_PROTO_HDR_AH,
> +	VIRTCHNL_PROTO_HDR_PFCP,
> +};
> +
> +/* Protocol header field within a protocol header. */ enum
> +virtchnl_proto_hdr_field {
> +	/* ETHER */
> +	VIRTCHNL_PROTO_HDR_ETH_SRC =
> +		PROTO_HDR_FIELD_START(VIRTCHNL_PROTO_HDR_ETH),
> +	VIRTCHNL_PROTO_HDR_ETH_DST,
> +	VIRTCHNL_PROTO_HDR_ETH_ETHERTYPE,
> +	/* S-VLAN */
> +	VIRTCHNL_PROTO_HDR_S_VLAN_ID =
> +		PROTO_HDR_FIELD_START(VIRTCHNL_PROTO_HDR_S_VLAN),
> +	/* C-VLAN */
> +	VIRTCHNL_PROTO_HDR_C_VLAN_ID =
> +		PROTO_HDR_FIELD_START(VIRTCHNL_PROTO_HDR_C_VLAN),
> +	/* IPV4 */
> +	VIRTCHNL_PROTO_HDR_IPV4_SRC =
> +		PROTO_HDR_FIELD_START(VIRTCHNL_PROTO_HDR_IPV4),
> +	VIRTCHNL_PROTO_HDR_IPV4_DST,
> +	VIRTCHNL_PROTO_HDR_IPV4_DSCP,
> +	VIRTCHNL_PROTO_HDR_IPV4_TTL,
> +	VIRTCHNL_PROTO_HDR_IPV4_PROT,
> +	/* IPV6 */
> +	VIRTCHNL_PROTO_HDR_IPV6_SRC =
> +		PROTO_HDR_FIELD_START(VIRTCHNL_PROTO_HDR_IPV6),
> +	VIRTCHNL_PROTO_HDR_IPV6_DST,
> +	VIRTCHNL_PROTO_HDR_IPV6_TC,
> +	VIRTCHNL_PROTO_HDR_IPV6_HOP_LIMIT,
> +	VIRTCHNL_PROTO_HDR_IPV6_PROT,
> +	/* TCP */
> +	VIRTCHNL_PROTO_HDR_TCP_SRC_PORT =
> +		PROTO_HDR_FIELD_START(VIRTCHNL_PROTO_HDR_TCP),
> +	VIRTCHNL_PROTO_HDR_TCP_DST_PORT,
> +	/* UDP */
> +	VIRTCHNL_PROTO_HDR_UDP_SRC_PORT =
> +		PROTO_HDR_FIELD_START(VIRTCHNL_PROTO_HDR_UDP),
> +	VIRTCHNL_PROTO_HDR_UDP_DST_PORT,
> +	/* SCTP */
> +	VIRTCHNL_PROTO_HDR_SCTP_SRC_PORT =
> +		PROTO_HDR_FIELD_START(VIRTCHNL_PROTO_HDR_SCTP),
> +	VIRTCHNL_PROTO_HDR_SCTP_DST_PORT,
> +	/* GTPU_IP */
> +	VIRTCHNL_PROTO_HDR_GTPU_IP_TEID =
> +		PROTO_HDR_FIELD_START(VIRTCHNL_PROTO_HDR_GTPU_IP),
> +	/* GTPU_EH */
> +	VIRTCHNL_PROTO_HDR_GTPU_EH_PDU =
> +		PROTO_HDR_FIELD_START(VIRTCHNL_PROTO_HDR_GTPU_EH),
> +	VIRTCHNL_PROTO_HDR_GTPU_EH_QFI,
> +	/* PPPOE */
> +	VIRTCHNL_PROTO_HDR_PPPOE_SESS_ID =
> +		PROTO_HDR_FIELD_START(VIRTCHNL_PROTO_HDR_PPPOE),
> +	/* L2TPV3 */
> +	VIRTCHNL_PROTO_HDR_L2TPV3_SESS_ID =
> +		PROTO_HDR_FIELD_START(VIRTCHNL_PROTO_HDR_L2TPV3),
> +	/* ESP */
> +	VIRTCHNL_PROTO_HDR_ESP_SPI =
> +		PROTO_HDR_FIELD_START(VIRTCHNL_PROTO_HDR_ESP),
> +	/* AH */
> +	VIRTCHNL_PROTO_HDR_AH_SPI =
> +		PROTO_HDR_FIELD_START(VIRTCHNL_PROTO_HDR_AH),
> +	/* PFCP */
> +	VIRTCHNL_PROTO_HDR_PFCP_S_FIELD =
> +		PROTO_HDR_FIELD_START(VIRTCHNL_PROTO_HDR_PFCP),
> +	VIRTCHNL_PROTO_HDR_PFCP_SEID,
> +};
> +
> +struct virtchnl_proto_hdr {
> +	enum virtchnl_proto_hdr_type type;
> +	u32 field_selector; /* a bit mask to select field for header type */
> +	u8 buffer[64];
> +	/**
> +	 * binary buffer in network order for specific header type.
> +	 * For example, if type = VIRTCHNL_PROTO_HDR_IPV4, a IPv4
> +	 * header is expected to be copied into the buffer.
> +	 */
> +};
> +
> +VIRTCHNL_CHECK_STRUCT_LEN(72, virtchnl_proto_hdr);
> +
> +struct virtchnl_proto_hdrs {
> +	u8 tunnel_level;
> +	/**
> +	 * specify where protocol header start from.
> +	 * 0 - from the outer layer
> +	 * 1 - from the first inner layer
> +	 * 2 - from the second inner layer
> +	 * ....
> +	 **/
> +	int count; /* the proto layers must <
> VIRTCHNL_MAX_NUM_PROTO_HDRS */
> +	struct virtchnl_proto_hdr
> proto_hdr[VIRTCHNL_MAX_NUM_PROTO_HDRS];
> +};
> +
> +VIRTCHNL_CHECK_STRUCT_LEN(2312, virtchnl_proto_hdrs);
> +
> +struct virtchnl_rss_cfg {
> +	struct virtchnl_proto_hdrs proto_hdrs;	   /* protocol headers */
> +	enum virtchnl_rss_algorithm rss_algorithm; /* rss algorithm type */
> +	u8 reserved[128];                          /* reserve for future */
> +};
> +
> +VIRTCHNL_CHECK_STRUCT_LEN(2444, virtchnl_rss_cfg);
> +
>  /* PF capability flags
>   * VIRTCHNL_CAP_STATELESS_OFFLOADS flag indicates stateless offloads
>   * such as TX/RX Checksum offloading and TSO for non-tunneled packets.
> Please @@ -839,14 +1014,6 @@ enum virtchnl_desc_profile {
>          VIRTCHNL_TXQ_DESC_PROFILE_NATIVE        = 1,
>  };
> 
> -/* Type of RSS algorithm */
> -enum virtchnl_rss_algorithm {
> -        VIRTCHNL_RSS_ALG_TOEPLITZ_ASYMMETRIC    = 0,
> -        VIRTCHNL_RSS_ALG_R_ASYMMETRIC           = 1,
> -        VIRTCHNL_RSS_ALG_TOEPLITZ_SYMMETRIC     = 2,
> -        VIRTCHNL_RSS_ALG_XOR_SYMMETRIC          = 3,
> -};
> -
>  /* VIRTCHNL_OP_GET_CAPS
>   * PF sends this message to CP to negotiate capabilities by filling
>   * in the u64 bitmap of its desired capabilities, max_num_vfs and @@ -1336,6
> +1503,10 @@ virtchnl_vc_validate_vf_msg(struct virtchnl_version_info *ver,
> u32 v_opcode,
>  	case VIRTCHNL_OP_DCF_GET_PKG_INFO:
>  	case VIRTCHNL_OP_GET_SUPPORTED_RXDIDS:
>  		break;
> +	case VIRTCHNL_OP_ADD_RSS_CFG:
> +	case VIRTCHNL_OP_DEL_RSS_CFG:
> +		valid_len = sizeof(struct virtchnl_rss_cfg);
> +		break;
>  	case VIRTCHNL_OP_GET_CAPS:
>  		valid_len = sizeof(struct virtchnl_get_capabilities);
>  		break;
> --
> 2.13.6
> 
> _______________________________________________
> Intel-wired-lan mailing list
> Intel-wired-lan@osuosl.org
> https://lists.osuosl.org/mailman/listinfo/intel-wired-lan
kernel test robot July 3, 2020, 7:37 a.m. UTC | #2
Hi Qi,

Thank you for the patch! Yet something to improve:

[auto build test ERROR on jkirsher-next-queue/dev-queue]
[cannot apply to v5.8-rc3 next-20200702]
[If your patch is applied to the wrong git tree, kindly drop us a note.
And when submitting patch, we suggest to use  as documented in
https://git-scm.com/docs/git-format-patch]

url:    https://github.com/0day-ci/linux/commits/Qi-Zhang/Support-Advanced-AVF-features/20200703-070522
base:   https://git.kernel.org/pub/scm/linux/kernel/git/jkirsher/next-queue.git dev-queue
config: m68k-randconfig-r026-20200702 (attached as .config)
compiler: m68k-linux-gcc (GCC) 9.3.0
reproduce (this is a W=1 build):
        wget https://raw.githubusercontent.com/intel/lkp-tests/master/sbin/make.cross -O ~/bin/make.cross
        chmod +x ~/bin/make.cross
        # save the attached .config to linux build tree
        COMPILER_INSTALL_PATH=$HOME/0day COMPILER=gcc-9.3.0 make.cross ARCH=m68k 

If you fix the issue, kindly add following tag as appropriate
Reported-by: kernel test robot <lkp@intel.com>

All errors (new ones prefixed by >>):

   In file included from arch/m68k/include/asm/bug.h:32,
                    from include/linux/bug.h:5,
                    from include/linux/thread_info.h:12,
                    from include/asm-generic/preempt.h:5,
                    from ./arch/m68k/include/generated/asm/preempt.h:1,
                    from include/linux/preempt.h:78,
                    from include/linux/spinlock.h:51,
                    from include/linux/seqlock.h:36,
                    from include/linux/time.h:6,
                    from include/linux/skbuff.h:15,
                    from include/linux/if_ether.h:19,
                    from include/linux/etherdevice.h:20,
                    from drivers/net/ethernet/intel/i40e/i40e_main.c:4:
   include/linux/dma-mapping.h: In function 'dma_map_resource':
   arch/m68k/include/asm/page_mm.h:169:49: warning: ordered comparison of pointer with null pointer [-Wextra]
     169 | #define virt_addr_valid(kaddr) ((void *)(kaddr) >= (void *)PAGE_OFFSET && (void *)(kaddr) < high_memory)
         |                                                 ^~
   include/asm-generic/bug.h:144:27: note: in definition of macro 'WARN_ON_ONCE'
     144 |  int __ret_warn_once = !!(condition);   \
         |                           ^~~~~~~~~
   arch/m68k/include/asm/page_mm.h:170:25: note: in expansion of macro 'virt_addr_valid'
     170 | #define pfn_valid(pfn)  virt_addr_valid(pfn_to_virt(pfn))
         |                         ^~~~~~~~~~~~~~~
   include/linux/dma-mapping.h:352:19: note: in expansion of macro 'pfn_valid'
     352 |  if (WARN_ON_ONCE(pfn_valid(PHYS_PFN(phys_addr))))
         |                   ^~~~~~~~~
   In file included from drivers/net/ethernet/intel/i40e/i40e_prototype.h:9,
                    from drivers/net/ethernet/intel/i40e/i40e.h:40,
                    from drivers/net/ethernet/intel/i40e/i40e_main.c:11:
   include/linux/avf/virtchnl.h: At top level:
   include/linux/avf/virtchnl.h:184:36: warning: division by zero [-Wdiv-by-zero]
     184 |  { virtchnl_static_assert_##X = (n)/((sizeof(struct X) == (n)) ? 1 : 0) }
         |                                    ^
   include/linux/avf/virtchnl.h:941:1: note: in expansion of macro 'VIRTCHNL_CHECK_STRUCT_LEN'
     941 | VIRTCHNL_CHECK_STRUCT_LEN(2312, virtchnl_proto_hdrs);
         | ^~~~~~~~~~~~~~~~~~~~~~~~~
>> include/linux/avf/virtchnl.h:941:33: error: enumerator value for 'virtchnl_static_assert_virtchnl_proto_hdrs' is not an integer constant
     941 | VIRTCHNL_CHECK_STRUCT_LEN(2312, virtchnl_proto_hdrs);
         |                                 ^~~~~~~~~~~~~~~~~~~
   include/linux/avf/virtchnl.h:184:53: note: in definition of macro 'VIRTCHNL_CHECK_STRUCT_LEN'
     184 |  { virtchnl_static_assert_##X = (n)/((sizeof(struct X) == (n)) ? 1 : 0) }
         |                                                     ^
   include/linux/avf/virtchnl.h:184:36: warning: division by zero [-Wdiv-by-zero]
     184 |  { virtchnl_static_assert_##X = (n)/((sizeof(struct X) == (n)) ? 1 : 0) }
         |                                    ^
   include/linux/avf/virtchnl.h:949:1: note: in expansion of macro 'VIRTCHNL_CHECK_STRUCT_LEN'
     949 | VIRTCHNL_CHECK_STRUCT_LEN(2444, virtchnl_rss_cfg);
         | ^~~~~~~~~~~~~~~~~~~~~~~~~
>> include/linux/avf/virtchnl.h:949:33: error: enumerator value for 'virtchnl_static_assert_virtchnl_rss_cfg' is not an integer constant
     949 | VIRTCHNL_CHECK_STRUCT_LEN(2444, virtchnl_rss_cfg);
         |                                 ^~~~~~~~~~~~~~~~
   include/linux/avf/virtchnl.h:184:53: note: in definition of macro 'VIRTCHNL_CHECK_STRUCT_LEN'
     184 |  { virtchnl_static_assert_##X = (n)/((sizeof(struct X) == (n)) ? 1 : 0) }
         |                                                     ^
   include/linux/avf/virtchnl.h:184:36: warning: division by zero [-Wdiv-by-zero]
     184 |  { virtchnl_static_assert_##X = (n)/((sizeof(struct X) == (n)) ? 1 : 0) }
         |                                    ^
   include/linux/avf/virtchnl.h:1038:1: note: in expansion of macro 'VIRTCHNL_CHECK_STRUCT_LEN'
    1038 | VIRTCHNL_CHECK_STRUCT_LEN(16, virtchnl_get_capabilities);
         | ^~~~~~~~~~~~~~~~~~~~~~~~~
   include/linux/avf/virtchnl.h:1038:31: error: enumerator value for 'virtchnl_static_assert_virtchnl_get_capabilities' is not an integer constant
    1038 | VIRTCHNL_CHECK_STRUCT_LEN(16, virtchnl_get_capabilities);
         |                               ^~~~~~~~~~~~~~~~~~~~~~~~~
   include/linux/avf/virtchnl.h:184:53: note: in definition of macro 'VIRTCHNL_CHECK_STRUCT_LEN'
     184 |  { virtchnl_static_assert_##X = (n)/((sizeof(struct X) == (n)) ? 1 : 0) }
         |                                                     ^
   include/linux/avf/virtchnl.h:184:36: warning: division by zero [-Wdiv-by-zero]
     184 |  { virtchnl_static_assert_##X = (n)/((sizeof(struct X) == (n)) ? 1 : 0) }
         |                                    ^
   include/linux/avf/virtchnl.h:1088:1: note: in expansion of macro 'VIRTCHNL_CHECK_STRUCT_LEN'
    1088 | VIRTCHNL_CHECK_STRUCT_LEN(56, virtchnl_create_vport);
         | ^~~~~~~~~~~~~~~~~~~~~~~~~
   include/linux/avf/virtchnl.h:1088:31: error: enumerator value for 'virtchnl_static_assert_virtchnl_create_vport' is not an integer constant
    1088 | VIRTCHNL_CHECK_STRUCT_LEN(56, virtchnl_create_vport);
         |                               ^~~~~~~~~~~~~~~~~~~~~
   include/linux/avf/virtchnl.h:184:53: note: in definition of macro 'VIRTCHNL_CHECK_STRUCT_LEN'
     184 |  { virtchnl_static_assert_##X = (n)/((sizeof(struct X) == (n)) ? 1 : 0) }
         |                                                     ^
   include/linux/avf/virtchnl.h:184:36: warning: division by zero [-Wdiv-by-zero]
     184 |  { virtchnl_static_assert_##X = (n)/((sizeof(struct X) == (n)) ? 1 : 0) }
         |                                    ^
   include/linux/avf/virtchnl.h:1120:1: note: in expansion of macro 'VIRTCHNL_CHECK_STRUCT_LEN'
    1120 | VIRTCHNL_CHECK_STRUCT_LEN(40, virtchnl_txq_info_v2);
         | ^~~~~~~~~~~~~~~~~~~~~~~~~
   include/linux/avf/virtchnl.h:1120:31: error: enumerator value for 'virtchnl_static_assert_virtchnl_txq_info_v2' is not an integer constant
    1120 | VIRTCHNL_CHECK_STRUCT_LEN(40, virtchnl_txq_info_v2);
         |                               ^~~~~~~~~~~~~~~~~~~~
   include/linux/avf/virtchnl.h:184:53: note: in definition of macro 'VIRTCHNL_CHECK_STRUCT_LEN'
     184 |  { virtchnl_static_assert_##X = (n)/((sizeof(struct X) == (n)) ? 1 : 0) }
         |                                                     ^
   include/linux/avf/virtchnl.h:184:36: warning: division by zero [-Wdiv-by-zero]
     184 |  { virtchnl_static_assert_##X = (n)/((sizeof(struct X) == (n)) ? 1 : 0) }
         |                                    ^
   include/linux/avf/virtchnl.h:1136:1: note: in expansion of macro 'VIRTCHNL_CHECK_STRUCT_LEN'
    1136 | VIRTCHNL_CHECK_STRUCT_LEN(48, virtchnl_config_tx_queues);
         | ^~~~~~~~~~~~~~~~~~~~~~~~~
   include/linux/avf/virtchnl.h:1136:31: error: enumerator value for 'virtchnl_static_assert_virtchnl_config_tx_queues' is not an integer constant
    1136 | VIRTCHNL_CHECK_STRUCT_LEN(48, virtchnl_config_tx_queues);
         |                               ^~~~~~~~~~~~~~~~~~~~~~~~~
   include/linux/avf/virtchnl.h:184:53: note: in definition of macro 'VIRTCHNL_CHECK_STRUCT_LEN'
     184 |  { virtchnl_static_assert_##X = (n)/((sizeof(struct X) == (n)) ? 1 : 0) }
         |                                                     ^
   include/linux/avf/virtchnl.h:184:36: warning: division by zero [-Wdiv-by-zero]
     184 |  { virtchnl_static_assert_##X = (n)/((sizeof(struct X) == (n)) ? 1 : 0) }
         |                                    ^
   include/linux/avf/virtchnl.h:1166:1: note: in expansion of macro 'VIRTCHNL_CHECK_STRUCT_LEN'
    1166 | VIRTCHNL_CHECK_STRUCT_LEN(72, virtchnl_rxq_info_v2);
         | ^~~~~~~~~~~~~~~~~~~~~~~~~
   include/linux/avf/virtchnl.h:1166:31: error: enumerator value for 'virtchnl_static_assert_virtchnl_rxq_info_v2' is not an integer constant
    1166 | VIRTCHNL_CHECK_STRUCT_LEN(72, virtchnl_rxq_info_v2);
         |                               ^~~~~~~~~~~~~~~~~~~~
   include/linux/avf/virtchnl.h:184:53: note: in definition of macro 'VIRTCHNL_CHECK_STRUCT_LEN'
     184 |  { virtchnl_static_assert_##X = (n)/((sizeof(struct X) == (n)) ? 1 : 0) }
         |                                                     ^
   include/linux/avf/virtchnl.h:184:36: warning: division by zero [-Wdiv-by-zero]
     184 |  { virtchnl_static_assert_##X = (n)/((sizeof(struct X) == (n)) ? 1 : 0) }
         |                                    ^
   include/linux/avf/virtchnl.h:1181:1: note: in expansion of macro 'VIRTCHNL_CHECK_STRUCT_LEN'
    1181 | VIRTCHNL_CHECK_STRUCT_LEN(80, virtchnl_config_rx_queues);
         | ^~~~~~~~~~~~~~~~~~~~~~~~~
   include/linux/avf/virtchnl.h:1181:31: error: enumerator value for 'virtchnl_static_assert_virtchnl_config_rx_queues' is not an integer constant
    1181 | VIRTCHNL_CHECK_STRUCT_LEN(80, virtchnl_config_rx_queues);
         |                               ^~~~~~~~~~~~~~~~~~~~~~~~~
   include/linux/avf/virtchnl.h:184:53: note: in definition of macro 'VIRTCHNL_CHECK_STRUCT_LEN'
     184 |  { virtchnl_static_assert_##X = (n)/((sizeof(struct X) == (n)) ? 1 : 0) }
         |                                                     ^
   include/linux/avf/virtchnl.h:184:36: warning: division by zero [-Wdiv-by-zero]
     184 |  { virtchnl_static_assert_##X = (n)/((sizeof(struct X) == (n)) ? 1 : 0) }
         |                                    ^
   include/linux/avf/virtchnl.h:1199:1: note: in expansion of macro 'VIRTCHNL_CHECK_STRUCT_LEN'
    1199 | VIRTCHNL_CHECK_STRUCT_LEN(24, virtchnl_add_queues);
         | ^~~~~~~~~~~~~~~~~~~~~~~~~
   include/linux/avf/virtchnl.h:1199:31: error: enumerator value for 'virtchnl_static_assert_virtchnl_add_queues' is not an integer constant
    1199 | VIRTCHNL_CHECK_STRUCT_LEN(24, virtchnl_add_queues);
         |                               ^~~~~~~~~~~~~~~~~~~
   include/linux/avf/virtchnl.h:184:53: note: in definition of macro 'VIRTCHNL_CHECK_STRUCT_LEN'
     184 |  { virtchnl_static_assert_##X = (n)/((sizeof(struct X) == (n)) ? 1 : 0) }
         |                                                     ^
   include/linux/avf/virtchnl.h:184:36: warning: division by zero [-Wdiv-by-zero]
     184 |  { virtchnl_static_assert_##X = (n)/((sizeof(struct X) == (n)) ? 1 : 0) }
         |                                    ^
   include/linux/avf/virtchnl.h:1214:1: note: in expansion of macro 'VIRTCHNL_CHECK_STRUCT_LEN'
    1214 | VIRTCHNL_CHECK_STRUCT_LEN(16, virtchnl_del_ena_dis_queues);
         | ^~~~~~~~~~~~~~~~~~~~~~~~~
   include/linux/avf/virtchnl.h:1214:31: error: enumerator value for 'virtchnl_static_assert_virtchnl_del_ena_dis_queues' is not an integer constant
    1214 | VIRTCHNL_CHECK_STRUCT_LEN(16, virtchnl_del_ena_dis_queues);
         |                               ^~~~~~~~~~~~~~~~~~~~~~~~~~~
   include/linux/avf/virtchnl.h:184:53: note: in definition of macro 'VIRTCHNL_CHECK_STRUCT_LEN'
     184 |  { virtchnl_static_assert_##X = (n)/((sizeof(struct X) == (n)) ? 1 : 0) }
--
   In file included from arch/m68k/include/asm/bug.h:32,
                    from include/linux/bug.h:5,
                    from include/linux/thread_info.h:12,
                    from include/asm-generic/preempt.h:5,
                    from ./arch/m68k/include/generated/asm/preempt.h:1,
                    from include/linux/preempt.h:78,
                    from include/linux/spinlock.h:51,
                    from include/linux/seqlock.h:36,
                    from include/linux/time.h:6,
                    from include/linux/skbuff.h:15,
                    from include/linux/if_ether.h:19,
                    from include/linux/etherdevice.h:20,
                    from drivers/net/ethernet/intel/i40e/i40e_main.c:4:
   include/linux/dma-mapping.h: In function 'dma_map_resource':
   arch/m68k/include/asm/page_mm.h:169:49: warning: ordered comparison of pointer with null pointer [-Wextra]
     169 | #define virt_addr_valid(kaddr) ((void *)(kaddr) >= (void *)PAGE_OFFSET && (void *)(kaddr) < high_memory)
         |                                                 ^~
   include/asm-generic/bug.h:144:27: note: in definition of macro 'WARN_ON_ONCE'
     144 |  int __ret_warn_once = !!(condition);   \
         |                           ^~~~~~~~~
   arch/m68k/include/asm/page_mm.h:170:25: note: in expansion of macro 'virt_addr_valid'
     170 | #define pfn_valid(pfn)  virt_addr_valid(pfn_to_virt(pfn))
         |                         ^~~~~~~~~~~~~~~
   include/linux/dma-mapping.h:352:19: note: in expansion of macro 'pfn_valid'
     352 |  if (WARN_ON_ONCE(pfn_valid(PHYS_PFN(phys_addr))))
         |                   ^~~~~~~~~
   In file included from drivers/net/ethernet/intel/i40e/i40e_prototype.h:9,
                    from drivers/net/ethernet/intel/i40e/i40e.h:40,
                    from drivers/net/ethernet/intel/i40e/i40e_main.c:11:
   include/linux/avf/virtchnl.h: At top level:
   include/linux/avf/virtchnl.h:184:36: warning: division by zero [-Wdiv-by-zero]
     184 |  { virtchnl_static_assert_##X = (n)/((sizeof(struct X) == (n)) ? 1 : 0) }
         |                                    ^
   include/linux/avf/virtchnl.h:941:1: note: in expansion of macro 'VIRTCHNL_CHECK_STRUCT_LEN'
     941 | VIRTCHNL_CHECK_STRUCT_LEN(2312, virtchnl_proto_hdrs);
         | ^~~~~~~~~~~~~~~~~~~~~~~~~
>> include/linux/avf/virtchnl.h:941:33: error: enumerator value for 'virtchnl_static_assert_virtchnl_proto_hdrs' is not an integer constant
     941 | VIRTCHNL_CHECK_STRUCT_LEN(2312, virtchnl_proto_hdrs);
         |                                 ^~~~~~~~~~~~~~~~~~~
   include/linux/avf/virtchnl.h:184:53: note: in definition of macro 'VIRTCHNL_CHECK_STRUCT_LEN'
     184 |  { virtchnl_static_assert_##X = (n)/((sizeof(struct X) == (n)) ? 1 : 0) }
         |                                                     ^
   include/linux/avf/virtchnl.h:184:36: warning: division by zero [-Wdiv-by-zero]
     184 |  { virtchnl_static_assert_##X = (n)/((sizeof(struct X) == (n)) ? 1 : 0) }
         |                                    ^
   include/linux/avf/virtchnl.h:949:1: note: in expansion of macro 'VIRTCHNL_CHECK_STRUCT_LEN'
     949 | VIRTCHNL_CHECK_STRUCT_LEN(2444, virtchnl_rss_cfg);
         | ^~~~~~~~~~~~~~~~~~~~~~~~~
>> include/linux/avf/virtchnl.h:949:33: error: enumerator value for 'virtchnl_static_assert_virtchnl_rss_cfg' is not an integer constant
     949 | VIRTCHNL_CHECK_STRUCT_LEN(2444, virtchnl_rss_cfg);
         |                                 ^~~~~~~~~~~~~~~~
   include/linux/avf/virtchnl.h:184:53: note: in definition of macro 'VIRTCHNL_CHECK_STRUCT_LEN'
     184 |  { virtchnl_static_assert_##X = (n)/((sizeof(struct X) == (n)) ? 1 : 0) }
         |                                                     ^
   include/linux/avf/virtchnl.h:184:36: warning: division by zero [-Wdiv-by-zero]
     184 |  { virtchnl_static_assert_##X = (n)/((sizeof(struct X) == (n)) ? 1 : 0) }
         |                                    ^
   include/linux/avf/virtchnl.h:1038:1: note: in expansion of macro 'VIRTCHNL_CHECK_STRUCT_LEN'
    1038 | VIRTCHNL_CHECK_STRUCT_LEN(16, virtchnl_get_capabilities);
         | ^~~~~~~~~~~~~~~~~~~~~~~~~
   include/linux/avf/virtchnl.h:1038:31: error: enumerator value for 'virtchnl_static_assert_virtchnl_get_capabilities' is not an integer constant
    1038 | VIRTCHNL_CHECK_STRUCT_LEN(16, virtchnl_get_capabilities);
         |                               ^~~~~~~~~~~~~~~~~~~~~~~~~
   include/linux/avf/virtchnl.h:184:53: note: in definition of macro 'VIRTCHNL_CHECK_STRUCT_LEN'
     184 |  { virtchnl_static_assert_##X = (n)/((sizeof(struct X) == (n)) ? 1 : 0) }
         |                                                     ^
   include/linux/avf/virtchnl.h:184:36: warning: division by zero [-Wdiv-by-zero]
     184 |  { virtchnl_static_assert_##X = (n)/((sizeof(struct X) == (n)) ? 1 : 0) }
         |                                    ^
   include/linux/avf/virtchnl.h:1088:1: note: in expansion of macro 'VIRTCHNL_CHECK_STRUCT_LEN'
    1088 | VIRTCHNL_CHECK_STRUCT_LEN(56, virtchnl_create_vport);
         | ^~~~~~~~~~~~~~~~~~~~~~~~~
   include/linux/avf/virtchnl.h:1088:31: error: enumerator value for 'virtchnl_static_assert_virtchnl_create_vport' is not an integer constant
    1088 | VIRTCHNL_CHECK_STRUCT_LEN(56, virtchnl_create_vport);
         |                               ^~~~~~~~~~~~~~~~~~~~~
   include/linux/avf/virtchnl.h:184:53: note: in definition of macro 'VIRTCHNL_CHECK_STRUCT_LEN'
     184 |  { virtchnl_static_assert_##X = (n)/((sizeof(struct X) == (n)) ? 1 : 0) }
         |                                                     ^
   include/linux/avf/virtchnl.h:184:36: warning: division by zero [-Wdiv-by-zero]
     184 |  { virtchnl_static_assert_##X = (n)/((sizeof(struct X) == (n)) ? 1 : 0) }
         |                                    ^
   include/linux/avf/virtchnl.h:1120:1: note: in expansion of macro 'VIRTCHNL_CHECK_STRUCT_LEN'
    1120 | VIRTCHNL_CHECK_STRUCT_LEN(40, virtchnl_txq_info_v2);
         | ^~~~~~~~~~~~~~~~~~~~~~~~~
   include/linux/avf/virtchnl.h:1120:31: error: enumerator value for 'virtchnl_static_assert_virtchnl_txq_info_v2' is not an integer constant
    1120 | VIRTCHNL_CHECK_STRUCT_LEN(40, virtchnl_txq_info_v2);
         |                               ^~~~~~~~~~~~~~~~~~~~
   include/linux/avf/virtchnl.h:184:53: note: in definition of macro 'VIRTCHNL_CHECK_STRUCT_LEN'
     184 |  { virtchnl_static_assert_##X = (n)/((sizeof(struct X) == (n)) ? 1 : 0) }
         |                                                     ^
   include/linux/avf/virtchnl.h:184:36: warning: division by zero [-Wdiv-by-zero]
     184 |  { virtchnl_static_assert_##X = (n)/((sizeof(struct X) == (n)) ? 1 : 0) }
         |                                    ^
   include/linux/avf/virtchnl.h:1136:1: note: in expansion of macro 'VIRTCHNL_CHECK_STRUCT_LEN'
    1136 | VIRTCHNL_CHECK_STRUCT_LEN(48, virtchnl_config_tx_queues);
         | ^~~~~~~~~~~~~~~~~~~~~~~~~
   include/linux/avf/virtchnl.h:1136:31: error: enumerator value for 'virtchnl_static_assert_virtchnl_config_tx_queues' is not an integer constant
    1136 | VIRTCHNL_CHECK_STRUCT_LEN(48, virtchnl_config_tx_queues);
         |                               ^~~~~~~~~~~~~~~~~~~~~~~~~
   include/linux/avf/virtchnl.h:184:53: note: in definition of macro 'VIRTCHNL_CHECK_STRUCT_LEN'
     184 |  { virtchnl_static_assert_##X = (n)/((sizeof(struct X) == (n)) ? 1 : 0) }
         |                                                     ^
   include/linux/avf/virtchnl.h:184:36: warning: division by zero [-Wdiv-by-zero]
     184 |  { virtchnl_static_assert_##X = (n)/((sizeof(struct X) == (n)) ? 1 : 0) }
         |                                    ^
   include/linux/avf/virtchnl.h:1166:1: note: in expansion of macro 'VIRTCHNL_CHECK_STRUCT_LEN'
    1166 | VIRTCHNL_CHECK_STRUCT_LEN(72, virtchnl_rxq_info_v2);
         | ^~~~~~~~~~~~~~~~~~~~~~~~~
   include/linux/avf/virtchnl.h:1166:31: error: enumerator value for 'virtchnl_static_assert_virtchnl_rxq_info_v2' is not an integer constant
    1166 | VIRTCHNL_CHECK_STRUCT_LEN(72, virtchnl_rxq_info_v2);
         |                               ^~~~~~~~~~~~~~~~~~~~
   include/linux/avf/virtchnl.h:184:53: note: in definition of macro 'VIRTCHNL_CHECK_STRUCT_LEN'
     184 |  { virtchnl_static_assert_##X = (n)/((sizeof(struct X) == (n)) ? 1 : 0) }
         |                                                     ^
   include/linux/avf/virtchnl.h:184:36: warning: division by zero [-Wdiv-by-zero]
     184 |  { virtchnl_static_assert_##X = (n)/((sizeof(struct X) == (n)) ? 1 : 0) }
         |                                    ^
   include/linux/avf/virtchnl.h:1181:1: note: in expansion of macro 'VIRTCHNL_CHECK_STRUCT_LEN'
    1181 | VIRTCHNL_CHECK_STRUCT_LEN(80, virtchnl_config_rx_queues);
         | ^~~~~~~~~~~~~~~~~~~~~~~~~
   include/linux/avf/virtchnl.h:1181:31: error: enumerator value for 'virtchnl_static_assert_virtchnl_config_rx_queues' is not an integer constant
    1181 | VIRTCHNL_CHECK_STRUCT_LEN(80, virtchnl_config_rx_queues);
         |                               ^~~~~~~~~~~~~~~~~~~~~~~~~
   include/linux/avf/virtchnl.h:184:53: note: in definition of macro 'VIRTCHNL_CHECK_STRUCT_LEN'
     184 |  { virtchnl_static_assert_##X = (n)/((sizeof(struct X) == (n)) ? 1 : 0) }
         |                                                     ^
   include/linux/avf/virtchnl.h:184:36: warning: division by zero [-Wdiv-by-zero]
     184 |  { virtchnl_static_assert_##X = (n)/((sizeof(struct X) == (n)) ? 1 : 0) }
         |                                    ^
   include/linux/avf/virtchnl.h:1199:1: note: in expansion of macro 'VIRTCHNL_CHECK_STRUCT_LEN'
    1199 | VIRTCHNL_CHECK_STRUCT_LEN(24, virtchnl_add_queues);
         | ^~~~~~~~~~~~~~~~~~~~~~~~~
   include/linux/avf/virtchnl.h:1199:31: error: enumerator value for 'virtchnl_static_assert_virtchnl_add_queues' is not an integer constant
    1199 | VIRTCHNL_CHECK_STRUCT_LEN(24, virtchnl_add_queues);
         |                               ^~~~~~~~~~~~~~~~~~~
   include/linux/avf/virtchnl.h:184:53: note: in definition of macro 'VIRTCHNL_CHECK_STRUCT_LEN'
     184 |  { virtchnl_static_assert_##X = (n)/((sizeof(struct X) == (n)) ? 1 : 0) }
         |                                                     ^
   include/linux/avf/virtchnl.h:184:36: warning: division by zero [-Wdiv-by-zero]
     184 |  { virtchnl_static_assert_##X = (n)/((sizeof(struct X) == (n)) ? 1 : 0) }
         |                                    ^
   include/linux/avf/virtchnl.h:1214:1: note: in expansion of macro 'VIRTCHNL_CHECK_STRUCT_LEN'
    1214 | VIRTCHNL_CHECK_STRUCT_LEN(16, virtchnl_del_ena_dis_queues);
         | ^~~~~~~~~~~~~~~~~~~~~~~~~
   include/linux/avf/virtchnl.h:1214:31: error: enumerator value for 'virtchnl_static_assert_virtchnl_del_ena_dis_queues' is not an integer constant
    1214 | VIRTCHNL_CHECK_STRUCT_LEN(16, virtchnl_del_ena_dis_queues);
         |                               ^~~~~~~~~~~~~~~~~~~~~~~~~~~
   include/linux/avf/virtchnl.h:184:53: note: in definition of macro 'VIRTCHNL_CHECK_STRUCT_LEN'
     184 |  { virtchnl_static_assert_##X = (n)/((sizeof(struct X) == (n)) ? 1 : 0) }
--
   In file included from arch/m68k/include/asm/bug.h:32,
                    from include/linux/bug.h:5,
                    from include/linux/thread_info.h:12,
                    from include/asm-generic/preempt.h:5,
                    from ./arch/m68k/include/generated/asm/preempt.h:1,
                    from include/linux/preempt.h:78,
                    from include/linux/spinlock.h:51,
                    from include/linux/seqlock.h:36,
                    from include/linux/time.h:6,
                    from include/linux/stat.h:19,
                    from include/linux/module.h:13,
                    from drivers/net/ethernet/intel/iavf/iavf.h:7,
                    from drivers/net/ethernet/intel/iavf/iavf_main.c:4:
   include/linux/dma-mapping.h: In function 'dma_map_resource':
   arch/m68k/include/asm/page_mm.h:169:49: warning: ordered comparison of pointer with null pointer [-Wextra]
     169 | #define virt_addr_valid(kaddr) ((void *)(kaddr) >= (void *)PAGE_OFFSET && (void *)(kaddr) < high_memory)
         |                                                 ^~
   include/asm-generic/bug.h:144:27: note: in definition of macro 'WARN_ON_ONCE'
     144 |  int __ret_warn_once = !!(condition);   \
         |                           ^~~~~~~~~
   arch/m68k/include/asm/page_mm.h:170:25: note: in expansion of macro 'virt_addr_valid'
     170 | #define pfn_valid(pfn)  virt_addr_valid(pfn_to_virt(pfn))
         |                         ^~~~~~~~~~~~~~~
   include/linux/dma-mapping.h:352:19: note: in expansion of macro 'pfn_valid'
     352 |  if (WARN_ON_ONCE(pfn_valid(PHYS_PFN(phys_addr))))
         |                   ^~~~~~~~~
   In file included from drivers/net/ethernet/intel/iavf/iavf.h:38,
                    from drivers/net/ethernet/intel/iavf/iavf_main.c:4:
   include/linux/avf/virtchnl.h: At top level:
   include/linux/avf/virtchnl.h:184:36: warning: division by zero [-Wdiv-by-zero]
     184 |  { virtchnl_static_assert_##X = (n)/((sizeof(struct X) == (n)) ? 1 : 0) }
         |                                    ^
   include/linux/avf/virtchnl.h:941:1: note: in expansion of macro 'VIRTCHNL_CHECK_STRUCT_LEN'
     941 | VIRTCHNL_CHECK_STRUCT_LEN(2312, virtchnl_proto_hdrs);
         | ^~~~~~~~~~~~~~~~~~~~~~~~~
>> include/linux/avf/virtchnl.h:941:33: error: enumerator value for 'virtchnl_static_assert_virtchnl_proto_hdrs' is not an integer constant
     941 | VIRTCHNL_CHECK_STRUCT_LEN(2312, virtchnl_proto_hdrs);
         |                                 ^~~~~~~~~~~~~~~~~~~
   include/linux/avf/virtchnl.h:184:53: note: in definition of macro 'VIRTCHNL_CHECK_STRUCT_LEN'
     184 |  { virtchnl_static_assert_##X = (n)/((sizeof(struct X) == (n)) ? 1 : 0) }
         |                                                     ^
   include/linux/avf/virtchnl.h:184:36: warning: division by zero [-Wdiv-by-zero]
     184 |  { virtchnl_static_assert_##X = (n)/((sizeof(struct X) == (n)) ? 1 : 0) }
         |                                    ^
   include/linux/avf/virtchnl.h:949:1: note: in expansion of macro 'VIRTCHNL_CHECK_STRUCT_LEN'
     949 | VIRTCHNL_CHECK_STRUCT_LEN(2444, virtchnl_rss_cfg);
         | ^~~~~~~~~~~~~~~~~~~~~~~~~
>> include/linux/avf/virtchnl.h:949:33: error: enumerator value for 'virtchnl_static_assert_virtchnl_rss_cfg' is not an integer constant
     949 | VIRTCHNL_CHECK_STRUCT_LEN(2444, virtchnl_rss_cfg);
         |                                 ^~~~~~~~~~~~~~~~
   include/linux/avf/virtchnl.h:184:53: note: in definition of macro 'VIRTCHNL_CHECK_STRUCT_LEN'
     184 |  { virtchnl_static_assert_##X = (n)/((sizeof(struct X) == (n)) ? 1 : 0) }
         |                                                     ^
   include/linux/avf/virtchnl.h:184:36: warning: division by zero [-Wdiv-by-zero]
     184 |  { virtchnl_static_assert_##X = (n)/((sizeof(struct X) == (n)) ? 1 : 0) }
         |                                    ^
   include/linux/avf/virtchnl.h:1038:1: note: in expansion of macro 'VIRTCHNL_CHECK_STRUCT_LEN'
    1038 | VIRTCHNL_CHECK_STRUCT_LEN(16, virtchnl_get_capabilities);
         | ^~~~~~~~~~~~~~~~~~~~~~~~~
   include/linux/avf/virtchnl.h:1038:31: error: enumerator value for 'virtchnl_static_assert_virtchnl_get_capabilities' is not an integer constant
    1038 | VIRTCHNL_CHECK_STRUCT_LEN(16, virtchnl_get_capabilities);
         |                               ^~~~~~~~~~~~~~~~~~~~~~~~~
   include/linux/avf/virtchnl.h:184:53: note: in definition of macro 'VIRTCHNL_CHECK_STRUCT_LEN'
     184 |  { virtchnl_static_assert_##X = (n)/((sizeof(struct X) == (n)) ? 1 : 0) }
         |                                                     ^
   include/linux/avf/virtchnl.h:184:36: warning: division by zero [-Wdiv-by-zero]
     184 |  { virtchnl_static_assert_##X = (n)/((sizeof(struct X) == (n)) ? 1 : 0) }
         |                                    ^
   include/linux/avf/virtchnl.h:1088:1: note: in expansion of macro 'VIRTCHNL_CHECK_STRUCT_LEN'
    1088 | VIRTCHNL_CHECK_STRUCT_LEN(56, virtchnl_create_vport);
         | ^~~~~~~~~~~~~~~~~~~~~~~~~
   include/linux/avf/virtchnl.h:1088:31: error: enumerator value for 'virtchnl_static_assert_virtchnl_create_vport' is not an integer constant
    1088 | VIRTCHNL_CHECK_STRUCT_LEN(56, virtchnl_create_vport);
         |                               ^~~~~~~~~~~~~~~~~~~~~
   include/linux/avf/virtchnl.h:184:53: note: in definition of macro 'VIRTCHNL_CHECK_STRUCT_LEN'
     184 |  { virtchnl_static_assert_##X = (n)/((sizeof(struct X) == (n)) ? 1 : 0) }
         |                                                     ^
   include/linux/avf/virtchnl.h:184:36: warning: division by zero [-Wdiv-by-zero]
     184 |  { virtchnl_static_assert_##X = (n)/((sizeof(struct X) == (n)) ? 1 : 0) }
         |                                    ^
   include/linux/avf/virtchnl.h:1120:1: note: in expansion of macro 'VIRTCHNL_CHECK_STRUCT_LEN'
    1120 | VIRTCHNL_CHECK_STRUCT_LEN(40, virtchnl_txq_info_v2);
         | ^~~~~~~~~~~~~~~~~~~~~~~~~
   include/linux/avf/virtchnl.h:1120:31: error: enumerator value for 'virtchnl_static_assert_virtchnl_txq_info_v2' is not an integer constant
    1120 | VIRTCHNL_CHECK_STRUCT_LEN(40, virtchnl_txq_info_v2);
         |                               ^~~~~~~~~~~~~~~~~~~~
   include/linux/avf/virtchnl.h:184:53: note: in definition of macro 'VIRTCHNL_CHECK_STRUCT_LEN'
     184 |  { virtchnl_static_assert_##X = (n)/((sizeof(struct X) == (n)) ? 1 : 0) }
         |                                                     ^
   include/linux/avf/virtchnl.h:184:36: warning: division by zero [-Wdiv-by-zero]
     184 |  { virtchnl_static_assert_##X = (n)/((sizeof(struct X) == (n)) ? 1 : 0) }
         |                                    ^
   include/linux/avf/virtchnl.h:1136:1: note: in expansion of macro 'VIRTCHNL_CHECK_STRUCT_LEN'
    1136 | VIRTCHNL_CHECK_STRUCT_LEN(48, virtchnl_config_tx_queues);
         | ^~~~~~~~~~~~~~~~~~~~~~~~~
   include/linux/avf/virtchnl.h:1136:31: error: enumerator value for 'virtchnl_static_assert_virtchnl_config_tx_queues' is not an integer constant
    1136 | VIRTCHNL_CHECK_STRUCT_LEN(48, virtchnl_config_tx_queues);
         |                               ^~~~~~~~~~~~~~~~~~~~~~~~~
   include/linux/avf/virtchnl.h:184:53: note: in definition of macro 'VIRTCHNL_CHECK_STRUCT_LEN'
     184 |  { virtchnl_static_assert_##X = (n)/((sizeof(struct X) == (n)) ? 1 : 0) }
         |                                                     ^
   include/linux/avf/virtchnl.h:184:36: warning: division by zero [-Wdiv-by-zero]
     184 |  { virtchnl_static_assert_##X = (n)/((sizeof(struct X) == (n)) ? 1 : 0) }
         |                                    ^
   include/linux/avf/virtchnl.h:1166:1: note: in expansion of macro 'VIRTCHNL_CHECK_STRUCT_LEN'
    1166 | VIRTCHNL_CHECK_STRUCT_LEN(72, virtchnl_rxq_info_v2);
         | ^~~~~~~~~~~~~~~~~~~~~~~~~
   include/linux/avf/virtchnl.h:1166:31: error: enumerator value for 'virtchnl_static_assert_virtchnl_rxq_info_v2' is not an integer constant
    1166 | VIRTCHNL_CHECK_STRUCT_LEN(72, virtchnl_rxq_info_v2);
         |                               ^~~~~~~~~~~~~~~~~~~~
   include/linux/avf/virtchnl.h:184:53: note: in definition of macro 'VIRTCHNL_CHECK_STRUCT_LEN'
     184 |  { virtchnl_static_assert_##X = (n)/((sizeof(struct X) == (n)) ? 1 : 0) }
         |                                                     ^
   include/linux/avf/virtchnl.h:184:36: warning: division by zero [-Wdiv-by-zero]
     184 |  { virtchnl_static_assert_##X = (n)/((sizeof(struct X) == (n)) ? 1 : 0) }
         |                                    ^
   include/linux/avf/virtchnl.h:1181:1: note: in expansion of macro 'VIRTCHNL_CHECK_STRUCT_LEN'
    1181 | VIRTCHNL_CHECK_STRUCT_LEN(80, virtchnl_config_rx_queues);
         | ^~~~~~~~~~~~~~~~~~~~~~~~~
   include/linux/avf/virtchnl.h:1181:31: error: enumerator value for 'virtchnl_static_assert_virtchnl_config_rx_queues' is not an integer constant
    1181 | VIRTCHNL_CHECK_STRUCT_LEN(80, virtchnl_config_rx_queues);
         |                               ^~~~~~~~~~~~~~~~~~~~~~~~~
   include/linux/avf/virtchnl.h:184:53: note: in definition of macro 'VIRTCHNL_CHECK_STRUCT_LEN'
     184 |  { virtchnl_static_assert_##X = (n)/((sizeof(struct X) == (n)) ? 1 : 0) }
         |                                                     ^
   include/linux/avf/virtchnl.h:184:36: warning: division by zero [-Wdiv-by-zero]
     184 |  { virtchnl_static_assert_##X = (n)/((sizeof(struct X) == (n)) ? 1 : 0) }
         |                                    ^
   include/linux/avf/virtchnl.h:1199:1: note: in expansion of macro 'VIRTCHNL_CHECK_STRUCT_LEN'
    1199 | VIRTCHNL_CHECK_STRUCT_LEN(24, virtchnl_add_queues);
         | ^~~~~~~~~~~~~~~~~~~~~~~~~
   include/linux/avf/virtchnl.h:1199:31: error: enumerator value for 'virtchnl_static_assert_virtchnl_add_queues' is not an integer constant
    1199 | VIRTCHNL_CHECK_STRUCT_LEN(24, virtchnl_add_queues);
         |                               ^~~~~~~~~~~~~~~~~~~
   include/linux/avf/virtchnl.h:184:53: note: in definition of macro 'VIRTCHNL_CHECK_STRUCT_LEN'
     184 |  { virtchnl_static_assert_##X = (n)/((sizeof(struct X) == (n)) ? 1 : 0) }
         |                                                     ^
   include/linux/avf/virtchnl.h:184:36: warning: division by zero [-Wdiv-by-zero]
     184 |  { virtchnl_static_assert_##X = (n)/((sizeof(struct X) == (n)) ? 1 : 0) }
         |                                    ^
   include/linux/avf/virtchnl.h:1214:1: note: in expansion of macro 'VIRTCHNL_CHECK_STRUCT_LEN'
    1214 | VIRTCHNL_CHECK_STRUCT_LEN(16, virtchnl_del_ena_dis_queues);
         | ^~~~~~~~~~~~~~~~~~~~~~~~~
   include/linux/avf/virtchnl.h:1214:31: error: enumerator value for 'virtchnl_static_assert_virtchnl_del_ena_dis_queues' is not an integer constant
    1214 | VIRTCHNL_CHECK_STRUCT_LEN(16, virtchnl_del_ena_dis_queues);
         |                               ^~~~~~~~~~~~~~~~~~~~~~~~~~~
   include/linux/avf/virtchnl.h:184:53: note: in definition of macro 'VIRTCHNL_CHECK_STRUCT_LEN'
     184 |  { virtchnl_static_assert_##X = (n)/((sizeof(struct X) == (n)) ? 1 : 0) }

vim +/virtchnl_static_assert_virtchnl_proto_hdrs +941 include/linux/avf/virtchnl.h

   940	
 > 941	VIRTCHNL_CHECK_STRUCT_LEN(2312, virtchnl_proto_hdrs);
   942	
   943	struct virtchnl_rss_cfg {
   944		struct virtchnl_proto_hdrs proto_hdrs;	   /* protocol headers */
   945		enum virtchnl_rss_algorithm rss_algorithm; /* rss algorithm type */
   946		u8 reserved[128];                          /* reserve for future */
   947	};
   948	
 > 949	VIRTCHNL_CHECK_STRUCT_LEN(2444, virtchnl_rss_cfg);
   950	

---
0-DAY CI Kernel Test Service, Intel Corporation
https://lists.01.org/hyperkitty/list/kbuild-all@lists.01.org
diff mbox series

Patch

diff --git a/drivers/net/ethernet/intel/ice/ice_flow.h b/drivers/net/ethernet/intel/ice/ice_flow.h
index 68d1ec7cf8fd..f3cfcfd2c296 100644
--- a/drivers/net/ethernet/intel/ice/ice_flow.h
+++ b/drivers/net/ethernet/intel/ice/ice_flow.h
@@ -8,6 +8,9 @@ 
 #define ICE_FLOW_FLD_OFF_INVAL		0xffff
 
 /* Generate flow hash field from flow field type(s) */
+#define ICE_FLOW_HASH_ETH	\
+	(BIT_ULL(ICE_FLOW_FIELD_IDX_ETH_DA) | \
+	 BIT_ULL(ICE_FLOW_FIELD_IDX_ETH_SA))
 #define ICE_FLOW_HASH_IPV4	\
 	(BIT_ULL(ICE_FLOW_FIELD_IDX_IPV4_SA) | \
 	 BIT_ULL(ICE_FLOW_FIELD_IDX_IPV4_DA))
diff --git a/drivers/net/ethernet/intel/ice/ice_virtchnl_pf.c b/drivers/net/ethernet/intel/ice/ice_virtchnl_pf.c
index 8022300f9c8e..ede343016f94 100644
--- a/drivers/net/ethernet/intel/ice/ice_virtchnl_pf.c
+++ b/drivers/net/ethernet/intel/ice/ice_virtchnl_pf.c
@@ -5,6 +5,246 @@ 
 #include "ice_base.h"
 #include "ice_lib.h"
 #include "ice_fltr.h"
+#include "ice_flow.h"
+
+#define FIELD_SELECTOR(proto_hdr_field) \
+		(1UL << ((proto_hdr_field) & PROTO_HDR_FIELD_MASK))
+
+struct ice_vc_hdr_match_type {
+	u32 vc_hdr;	/* virtchnl headers (VIRTCHNL_PROTO_HDR_XXX) */
+	u32 ice_hdr;	/* ice headers (ICE_FLOW_SEG_HDR_XXX) */
+};
+
+static const struct ice_vc_hdr_match_type ice_vc_hdr_list_os[] = {
+	{VIRTCHNL_PROTO_HDR_NONE,	ICE_FLOW_SEG_HDR_NONE},
+	{VIRTCHNL_PROTO_HDR_IPV4,	ICE_FLOW_SEG_HDR_IPV4 |
+					ICE_FLOW_SEG_HDR_IPV_OTHER},
+	{VIRTCHNL_PROTO_HDR_IPV6,	ICE_FLOW_SEG_HDR_IPV6 |
+					ICE_FLOW_SEG_HDR_IPV_OTHER},
+	{VIRTCHNL_PROTO_HDR_TCP,	ICE_FLOW_SEG_HDR_TCP},
+	{VIRTCHNL_PROTO_HDR_UDP,	ICE_FLOW_SEG_HDR_UDP},
+	{VIRTCHNL_PROTO_HDR_SCTP,	ICE_FLOW_SEG_HDR_SCTP},
+};
+
+static const struct ice_vc_hdr_match_type ice_vc_hdr_list_comms[] = {
+	{VIRTCHNL_PROTO_HDR_NONE,	ICE_FLOW_SEG_HDR_NONE},
+	{VIRTCHNL_PROTO_HDR_ETH,	ICE_FLOW_SEG_HDR_ETH},
+	{VIRTCHNL_PROTO_HDR_S_VLAN,	ICE_FLOW_SEG_HDR_VLAN},
+	{VIRTCHNL_PROTO_HDR_C_VLAN,	ICE_FLOW_SEG_HDR_VLAN},
+	{VIRTCHNL_PROTO_HDR_IPV4,	ICE_FLOW_SEG_HDR_IPV4 |
+					ICE_FLOW_SEG_HDR_IPV_OTHER},
+	{VIRTCHNL_PROTO_HDR_IPV6,	ICE_FLOW_SEG_HDR_IPV6 |
+					ICE_FLOW_SEG_HDR_IPV_OTHER},
+	{VIRTCHNL_PROTO_HDR_TCP,	ICE_FLOW_SEG_HDR_TCP},
+	{VIRTCHNL_PROTO_HDR_UDP,	ICE_FLOW_SEG_HDR_UDP},
+	{VIRTCHNL_PROTO_HDR_SCTP,	ICE_FLOW_SEG_HDR_SCTP},
+	{VIRTCHNL_PROTO_HDR_PPPOE,	ICE_FLOW_SEG_HDR_PPPOE},
+	{VIRTCHNL_PROTO_HDR_GTPU_IP,	ICE_FLOW_SEG_HDR_GTPU_IP},
+	{VIRTCHNL_PROTO_HDR_GTPU_EH,	ICE_FLOW_SEG_HDR_GTPU_EH},
+	{VIRTCHNL_PROTO_HDR_GTPU_EH_PDU_DWN,
+					ICE_FLOW_SEG_HDR_GTPU_DWN},
+	{VIRTCHNL_PROTO_HDR_GTPU_EH_PDU_UP,
+					ICE_FLOW_SEG_HDR_GTPU_UP},
+	{VIRTCHNL_PROTO_HDR_L2TPV3,	ICE_FLOW_SEG_HDR_L2TPV3},
+	{VIRTCHNL_PROTO_HDR_ESP,	ICE_FLOW_SEG_HDR_ESP},
+	{VIRTCHNL_PROTO_HDR_AH,		ICE_FLOW_SEG_HDR_AH},
+	{VIRTCHNL_PROTO_HDR_PFCP,	ICE_FLOW_SEG_HDR_PFCP_SESSION},
+};
+
+struct ice_vc_hash_field_match_type {
+	u32 vc_hdr;		/* virtchnl headers
+				 * (VIRTCHNL_PROTO_HDR_XXX)
+				 */
+	u32 vc_hash_field;	/* virtchnl hash fields selector
+				 * FIELD_SELECTOR((VIRTCHNL_PROTO_HDR_ETH_XXX))
+				 */
+	u64 ice_hash_field;	/* ice hash fields
+				 * (BIT_ULL(ICE_FLOW_FIELD_IDX_XXX))
+				 */
+};
+
+static const struct
+ice_vc_hash_field_match_type ice_vc_hash_field_list_os[] = {
+	{VIRTCHNL_PROTO_HDR_IPV4, FIELD_SELECTOR(VIRTCHNL_PROTO_HDR_IPV4_SRC),
+		BIT_ULL(ICE_FLOW_FIELD_IDX_IPV4_SA)},
+	{VIRTCHNL_PROTO_HDR_IPV4, FIELD_SELECTOR(VIRTCHNL_PROTO_HDR_IPV4_DST),
+		BIT_ULL(ICE_FLOW_FIELD_IDX_IPV4_DA)},
+	{VIRTCHNL_PROTO_HDR_IPV4, FIELD_SELECTOR(VIRTCHNL_PROTO_HDR_IPV4_SRC) |
+		FIELD_SELECTOR(VIRTCHNL_PROTO_HDR_IPV4_DST),
+		ICE_FLOW_HASH_IPV4},
+	{VIRTCHNL_PROTO_HDR_IPV4, FIELD_SELECTOR(VIRTCHNL_PROTO_HDR_IPV4_SRC) |
+		FIELD_SELECTOR(VIRTCHNL_PROTO_HDR_IPV4_PROT),
+		BIT_ULL(ICE_FLOW_FIELD_IDX_IPV4_SA) |
+		BIT_ULL(ICE_FLOW_FIELD_IDX_IPV4_PROT)},
+	{VIRTCHNL_PROTO_HDR_IPV4, FIELD_SELECTOR(VIRTCHNL_PROTO_HDR_IPV4_DST) |
+		FIELD_SELECTOR(VIRTCHNL_PROTO_HDR_IPV4_PROT),
+		BIT_ULL(ICE_FLOW_FIELD_IDX_IPV4_DA) |
+		BIT_ULL(ICE_FLOW_FIELD_IDX_IPV4_PROT)},
+	{VIRTCHNL_PROTO_HDR_IPV4, FIELD_SELECTOR(VIRTCHNL_PROTO_HDR_IPV4_SRC) |
+		FIELD_SELECTOR(VIRTCHNL_PROTO_HDR_IPV4_DST) |
+		FIELD_SELECTOR(VIRTCHNL_PROTO_HDR_IPV4_PROT),
+		ICE_FLOW_HASH_IPV4 | BIT_ULL(ICE_FLOW_FIELD_IDX_IPV4_PROT)},
+	{VIRTCHNL_PROTO_HDR_IPV4, FIELD_SELECTOR(VIRTCHNL_PROTO_HDR_IPV4_PROT),
+		BIT_ULL(ICE_FLOW_FIELD_IDX_IPV4_PROT)},
+	{VIRTCHNL_PROTO_HDR_IPV6, FIELD_SELECTOR(VIRTCHNL_PROTO_HDR_IPV6_SRC),
+		BIT_ULL(ICE_FLOW_FIELD_IDX_IPV6_SA)},
+	{VIRTCHNL_PROTO_HDR_IPV6, FIELD_SELECTOR(VIRTCHNL_PROTO_HDR_IPV6_DST),
+		BIT_ULL(ICE_FLOW_FIELD_IDX_IPV6_DA)},
+	{VIRTCHNL_PROTO_HDR_IPV6, FIELD_SELECTOR(VIRTCHNL_PROTO_HDR_IPV6_SRC) |
+		FIELD_SELECTOR(VIRTCHNL_PROTO_HDR_IPV6_DST),
+		ICE_FLOW_HASH_IPV6},
+	{VIRTCHNL_PROTO_HDR_IPV6, FIELD_SELECTOR(VIRTCHNL_PROTO_HDR_IPV6_SRC) |
+		FIELD_SELECTOR(VIRTCHNL_PROTO_HDR_IPV6_PROT),
+		BIT_ULL(ICE_FLOW_FIELD_IDX_IPV6_SA) |
+		BIT_ULL(ICE_FLOW_FIELD_IDX_IPV6_PROT)},
+	{VIRTCHNL_PROTO_HDR_IPV6, FIELD_SELECTOR(VIRTCHNL_PROTO_HDR_IPV6_DST) |
+		FIELD_SELECTOR(VIRTCHNL_PROTO_HDR_IPV6_PROT),
+		BIT_ULL(ICE_FLOW_FIELD_IDX_IPV6_DA) |
+		BIT_ULL(ICE_FLOW_FIELD_IDX_IPV6_PROT)},
+	{VIRTCHNL_PROTO_HDR_IPV6, FIELD_SELECTOR(VIRTCHNL_PROTO_HDR_IPV6_SRC) |
+		FIELD_SELECTOR(VIRTCHNL_PROTO_HDR_IPV6_DST) |
+		FIELD_SELECTOR(VIRTCHNL_PROTO_HDR_IPV6_PROT),
+		ICE_FLOW_HASH_IPV6 | BIT_ULL(ICE_FLOW_FIELD_IDX_IPV6_PROT)},
+	{VIRTCHNL_PROTO_HDR_IPV6, FIELD_SELECTOR(VIRTCHNL_PROTO_HDR_IPV6_PROT),
+		BIT_ULL(ICE_FLOW_FIELD_IDX_IPV6_PROT)},
+	{VIRTCHNL_PROTO_HDR_TCP,
+		FIELD_SELECTOR(VIRTCHNL_PROTO_HDR_TCP_SRC_PORT),
+		BIT_ULL(ICE_FLOW_FIELD_IDX_TCP_SRC_PORT)},
+	{VIRTCHNL_PROTO_HDR_TCP,
+		FIELD_SELECTOR(VIRTCHNL_PROTO_HDR_TCP_DST_PORT),
+		BIT_ULL(ICE_FLOW_FIELD_IDX_TCP_DST_PORT)},
+	{VIRTCHNL_PROTO_HDR_TCP,
+		FIELD_SELECTOR(VIRTCHNL_PROTO_HDR_TCP_SRC_PORT) |
+		FIELD_SELECTOR(VIRTCHNL_PROTO_HDR_TCP_DST_PORT),
+		ICE_FLOW_HASH_TCP_PORT},
+	{VIRTCHNL_PROTO_HDR_UDP,
+		FIELD_SELECTOR(VIRTCHNL_PROTO_HDR_UDP_SRC_PORT),
+		BIT_ULL(ICE_FLOW_FIELD_IDX_UDP_SRC_PORT)},
+	{VIRTCHNL_PROTO_HDR_UDP,
+		FIELD_SELECTOR(VIRTCHNL_PROTO_HDR_UDP_DST_PORT),
+		BIT_ULL(ICE_FLOW_FIELD_IDX_UDP_DST_PORT)},
+	{VIRTCHNL_PROTO_HDR_UDP,
+		FIELD_SELECTOR(VIRTCHNL_PROTO_HDR_UDP_SRC_PORT) |
+		FIELD_SELECTOR(VIRTCHNL_PROTO_HDR_UDP_DST_PORT),
+		ICE_FLOW_HASH_UDP_PORT},
+	{VIRTCHNL_PROTO_HDR_SCTP,
+		FIELD_SELECTOR(VIRTCHNL_PROTO_HDR_SCTP_SRC_PORT),
+		BIT_ULL(ICE_FLOW_FIELD_IDX_SCTP_SRC_PORT)},
+	{VIRTCHNL_PROTO_HDR_SCTP,
+		FIELD_SELECTOR(VIRTCHNL_PROTO_HDR_SCTP_DST_PORT),
+		BIT_ULL(ICE_FLOW_FIELD_IDX_SCTP_DST_PORT)},
+	{VIRTCHNL_PROTO_HDR_SCTP,
+		FIELD_SELECTOR(VIRTCHNL_PROTO_HDR_SCTP_SRC_PORT) |
+		FIELD_SELECTOR(VIRTCHNL_PROTO_HDR_SCTP_DST_PORT),
+		ICE_FLOW_HASH_SCTP_PORT},
+};
+
+static const struct
+ice_vc_hash_field_match_type ice_vc_hash_field_list_comms[] = {
+	{VIRTCHNL_PROTO_HDR_ETH, FIELD_SELECTOR(VIRTCHNL_PROTO_HDR_ETH_SRC),
+		BIT_ULL(ICE_FLOW_FIELD_IDX_ETH_SA)},
+	{VIRTCHNL_PROTO_HDR_ETH, FIELD_SELECTOR(VIRTCHNL_PROTO_HDR_ETH_DST),
+		BIT_ULL(ICE_FLOW_FIELD_IDX_ETH_DA)},
+	{VIRTCHNL_PROTO_HDR_ETH, FIELD_SELECTOR(VIRTCHNL_PROTO_HDR_ETH_SRC) |
+		FIELD_SELECTOR(VIRTCHNL_PROTO_HDR_ETH_DST),
+		ICE_FLOW_HASH_ETH},
+	{VIRTCHNL_PROTO_HDR_ETH,
+		FIELD_SELECTOR(VIRTCHNL_PROTO_HDR_ETH_ETHERTYPE),
+		BIT_ULL(ICE_FLOW_FIELD_IDX_ETH_TYPE)},
+	{VIRTCHNL_PROTO_HDR_S_VLAN,
+		FIELD_SELECTOR(VIRTCHNL_PROTO_HDR_S_VLAN_ID),
+		BIT_ULL(ICE_FLOW_FIELD_IDX_S_VLAN)},
+	{VIRTCHNL_PROTO_HDR_C_VLAN,
+		FIELD_SELECTOR(VIRTCHNL_PROTO_HDR_C_VLAN_ID),
+		BIT_ULL(ICE_FLOW_FIELD_IDX_C_VLAN)},
+	{VIRTCHNL_PROTO_HDR_IPV4, FIELD_SELECTOR(VIRTCHNL_PROTO_HDR_IPV4_SRC),
+		BIT_ULL(ICE_FLOW_FIELD_IDX_IPV4_SA)},
+	{VIRTCHNL_PROTO_HDR_IPV4, FIELD_SELECTOR(VIRTCHNL_PROTO_HDR_IPV4_DST),
+		BIT_ULL(ICE_FLOW_FIELD_IDX_IPV4_DA)},
+	{VIRTCHNL_PROTO_HDR_IPV4, FIELD_SELECTOR(VIRTCHNL_PROTO_HDR_IPV4_SRC) |
+		FIELD_SELECTOR(VIRTCHNL_PROTO_HDR_IPV4_DST),
+		ICE_FLOW_HASH_IPV4},
+	{VIRTCHNL_PROTO_HDR_IPV4, FIELD_SELECTOR(VIRTCHNL_PROTO_HDR_IPV4_SRC) |
+		FIELD_SELECTOR(VIRTCHNL_PROTO_HDR_IPV4_PROT),
+		BIT_ULL(ICE_FLOW_FIELD_IDX_IPV4_SA) |
+		BIT_ULL(ICE_FLOW_FIELD_IDX_IPV4_PROT)},
+	{VIRTCHNL_PROTO_HDR_IPV4, FIELD_SELECTOR(VIRTCHNL_PROTO_HDR_IPV4_DST) |
+		FIELD_SELECTOR(VIRTCHNL_PROTO_HDR_IPV4_PROT),
+		BIT_ULL(ICE_FLOW_FIELD_IDX_IPV4_DA) |
+		BIT_ULL(ICE_FLOW_FIELD_IDX_IPV4_PROT)},
+	{VIRTCHNL_PROTO_HDR_IPV4, FIELD_SELECTOR(VIRTCHNL_PROTO_HDR_IPV4_SRC) |
+		FIELD_SELECTOR(VIRTCHNL_PROTO_HDR_IPV4_DST) |
+		FIELD_SELECTOR(VIRTCHNL_PROTO_HDR_IPV4_PROT),
+		ICE_FLOW_HASH_IPV4 | BIT_ULL(ICE_FLOW_FIELD_IDX_IPV4_PROT)},
+	{VIRTCHNL_PROTO_HDR_IPV4, FIELD_SELECTOR(VIRTCHNL_PROTO_HDR_IPV4_PROT),
+		BIT_ULL(ICE_FLOW_FIELD_IDX_IPV4_PROT)},
+	{VIRTCHNL_PROTO_HDR_IPV6, FIELD_SELECTOR(VIRTCHNL_PROTO_HDR_IPV6_SRC),
+		BIT_ULL(ICE_FLOW_FIELD_IDX_IPV6_SA)},
+	{VIRTCHNL_PROTO_HDR_IPV6, FIELD_SELECTOR(VIRTCHNL_PROTO_HDR_IPV6_DST),
+		BIT_ULL(ICE_FLOW_FIELD_IDX_IPV6_DA)},
+	{VIRTCHNL_PROTO_HDR_IPV6, FIELD_SELECTOR(VIRTCHNL_PROTO_HDR_IPV6_SRC) |
+		FIELD_SELECTOR(VIRTCHNL_PROTO_HDR_IPV6_DST),
+		ICE_FLOW_HASH_IPV6},
+	{VIRTCHNL_PROTO_HDR_IPV6, FIELD_SELECTOR(VIRTCHNL_PROTO_HDR_IPV6_SRC) |
+		FIELD_SELECTOR(VIRTCHNL_PROTO_HDR_IPV6_PROT),
+		BIT_ULL(ICE_FLOW_FIELD_IDX_IPV6_SA) |
+		BIT_ULL(ICE_FLOW_FIELD_IDX_IPV6_PROT)},
+	{VIRTCHNL_PROTO_HDR_IPV6, FIELD_SELECTOR(VIRTCHNL_PROTO_HDR_IPV6_DST) |
+		FIELD_SELECTOR(VIRTCHNL_PROTO_HDR_IPV6_PROT),
+		BIT_ULL(ICE_FLOW_FIELD_IDX_IPV6_DA) |
+		BIT_ULL(ICE_FLOW_FIELD_IDX_IPV6_PROT)},
+	{VIRTCHNL_PROTO_HDR_IPV6, FIELD_SELECTOR(VIRTCHNL_PROTO_HDR_IPV6_SRC) |
+		FIELD_SELECTOR(VIRTCHNL_PROTO_HDR_IPV6_DST) |
+		FIELD_SELECTOR(VIRTCHNL_PROTO_HDR_IPV6_PROT),
+		ICE_FLOW_HASH_IPV6 | BIT_ULL(ICE_FLOW_FIELD_IDX_IPV6_PROT)},
+	{VIRTCHNL_PROTO_HDR_IPV6, FIELD_SELECTOR(VIRTCHNL_PROTO_HDR_IPV6_PROT),
+		BIT_ULL(ICE_FLOW_FIELD_IDX_IPV6_PROT)},
+	{VIRTCHNL_PROTO_HDR_TCP,
+		FIELD_SELECTOR(VIRTCHNL_PROTO_HDR_TCP_SRC_PORT),
+		BIT_ULL(ICE_FLOW_FIELD_IDX_TCP_SRC_PORT)},
+	{VIRTCHNL_PROTO_HDR_TCP,
+		FIELD_SELECTOR(VIRTCHNL_PROTO_HDR_TCP_DST_PORT),
+		BIT_ULL(ICE_FLOW_FIELD_IDX_TCP_DST_PORT)},
+	{VIRTCHNL_PROTO_HDR_TCP,
+		FIELD_SELECTOR(VIRTCHNL_PROTO_HDR_TCP_SRC_PORT) |
+		FIELD_SELECTOR(VIRTCHNL_PROTO_HDR_TCP_DST_PORT),
+		ICE_FLOW_HASH_TCP_PORT},
+	{VIRTCHNL_PROTO_HDR_UDP,
+		FIELD_SELECTOR(VIRTCHNL_PROTO_HDR_UDP_SRC_PORT),
+		BIT_ULL(ICE_FLOW_FIELD_IDX_UDP_SRC_PORT)},
+	{VIRTCHNL_PROTO_HDR_UDP,
+		FIELD_SELECTOR(VIRTCHNL_PROTO_HDR_UDP_DST_PORT),
+		BIT_ULL(ICE_FLOW_FIELD_IDX_UDP_DST_PORT)},
+	{VIRTCHNL_PROTO_HDR_UDP,
+		FIELD_SELECTOR(VIRTCHNL_PROTO_HDR_UDP_SRC_PORT) |
+		FIELD_SELECTOR(VIRTCHNL_PROTO_HDR_UDP_DST_PORT),
+		ICE_FLOW_HASH_UDP_PORT},
+	{VIRTCHNL_PROTO_HDR_SCTP,
+		FIELD_SELECTOR(VIRTCHNL_PROTO_HDR_SCTP_SRC_PORT),
+		BIT_ULL(ICE_FLOW_FIELD_IDX_SCTP_SRC_PORT)},
+	{VIRTCHNL_PROTO_HDR_SCTP,
+		FIELD_SELECTOR(VIRTCHNL_PROTO_HDR_SCTP_DST_PORT),
+		BIT_ULL(ICE_FLOW_FIELD_IDX_SCTP_DST_PORT)},
+	{VIRTCHNL_PROTO_HDR_SCTP,
+		FIELD_SELECTOR(VIRTCHNL_PROTO_HDR_SCTP_SRC_PORT) |
+		FIELD_SELECTOR(VIRTCHNL_PROTO_HDR_SCTP_DST_PORT),
+		ICE_FLOW_HASH_SCTP_PORT},
+	{VIRTCHNL_PROTO_HDR_PPPOE,
+		FIELD_SELECTOR(VIRTCHNL_PROTO_HDR_PPPOE_SESS_ID),
+		BIT_ULL(ICE_FLOW_FIELD_IDX_PPPOE_SESS_ID)},
+	{VIRTCHNL_PROTO_HDR_GTPU_IP,
+		FIELD_SELECTOR(VIRTCHNL_PROTO_HDR_GTPU_IP_TEID),
+		BIT_ULL(ICE_FLOW_FIELD_IDX_GTPU_IP_TEID)},
+	{VIRTCHNL_PROTO_HDR_L2TPV3,
+		FIELD_SELECTOR(VIRTCHNL_PROTO_HDR_L2TPV3_SESS_ID),
+		BIT_ULL(ICE_FLOW_FIELD_IDX_L2TPV3_SESS_ID)},
+	{VIRTCHNL_PROTO_HDR_ESP, FIELD_SELECTOR(VIRTCHNL_PROTO_HDR_ESP_SPI),
+		BIT_ULL(ICE_FLOW_FIELD_IDX_ESP_SPI)},
+	{VIRTCHNL_PROTO_HDR_AH, FIELD_SELECTOR(VIRTCHNL_PROTO_HDR_AH_SPI),
+		BIT_ULL(ICE_FLOW_FIELD_IDX_AH_SPI)},
+	{VIRTCHNL_PROTO_HDR_PFCP, FIELD_SELECTOR(VIRTCHNL_PROTO_HDR_PFCP_SEID),
+		BIT_ULL(ICE_FLOW_FIELD_IDX_PFCP_SEID)},
+};
 
 /**
  * ice_validate_vf_id - helper to check if VF ID is valid
@@ -2009,6 +2249,9 @@  static int ice_vc_get_vf_res_msg(struct ice_vf *vf, u8 *msg)
 	if (vf->driver_caps & VIRTCHNL_VF_CAP_ADV_LINK_SPEED)
 		vfres->vf_cap_flags |= VIRTCHNL_VF_CAP_ADV_LINK_SPEED;
 
+	if (vf->driver_caps & VIRTCHNL_VF_OFFLOAD_ADV_RSS_PF)
+		vfres->vf_cap_flags |= VIRTCHNL_VF_OFFLOAD_ADV_RSS_PF;
+
 	/* Negotiate DCF capability. */
 	if (vf->driver_caps & VIRTCHNL_VF_CAP_DCF) {
 		if (!ice_check_dcf_allowed(vf)) {
@@ -2141,6 +2384,216 @@  static bool ice_vc_isvalid_ring_len(u16 ring_len)
 }
 
 /**
+ * ice_vc_parse_rss_cfg - parses hash fields and headers from
+ * a specific virtchnl RSS cfg
+ * @hw: pointer to the hardware
+ * @rss_cfg: pointer to the virtchnl rss cfg
+ * @addl_hdrs: pointer to the protocol header fields (ICE_FLOW_SEG_HDR_*)
+ * to configure
+ * @hash_flds: pointer to the hash bit fields (ICE_FLOW_HASH_*) to configure
+ *
+ * Return true if all the protocol header and hash fields in the rss cfg could
+ * be parsed, else return false
+ *
+ * This function parses the virtchnl rss cfg to be the intended
+ * hash fields and the intended header for RSS configuration
+ */
+static bool
+ice_vc_parse_rss_cfg(struct ice_hw *hw, struct virtchnl_rss_cfg *rss_cfg,
+		     u32 *addl_hdrs, u64 *hash_flds)
+{
+	const struct ice_vc_hash_field_match_type *hf_list;
+	const struct ice_vc_hdr_match_type *hdr_list;
+	int i, hf_list_len, hdr_list_len;
+
+	if (!strncmp(hw->active_pkg_name, "ICE COMMS Package",
+		     sizeof(hw->active_pkg_name))) {
+		hf_list = ice_vc_hash_field_list_comms;
+		hf_list_len = ARRAY_SIZE(ice_vc_hash_field_list_comms);
+		hdr_list = ice_vc_hdr_list_comms;
+		hdr_list_len = ARRAY_SIZE(ice_vc_hdr_list_comms);
+	} else {
+		hf_list = ice_vc_hash_field_list_os;
+		hf_list_len = ARRAY_SIZE(ice_vc_hash_field_list_os);
+		hdr_list = ice_vc_hdr_list_os;
+		hdr_list_len = ARRAY_SIZE(ice_vc_hdr_list_os);
+	}
+
+	for (i = 0; i < rss_cfg->proto_hdrs.count; i++) {
+		struct virtchnl_proto_hdr *proto_hdr =
+				&rss_cfg->proto_hdrs.proto_hdr[i];
+		bool hdr_found = false;
+		int j;
+
+		/* Find matched ice headers according to virtchnl headers. */
+		for (j = 0; j < hdr_list_len; j++) {
+			struct ice_vc_hdr_match_type hdr_map =
+				hdr_list[j];
+
+			if (proto_hdr->type == hdr_map.vc_hdr) {
+				*addl_hdrs |= hdr_map.ice_hdr;
+				hdr_found = true;
+			}
+		}
+
+		if (!hdr_found)
+			return false;
+
+		/* Find matched ice hash fields according to
+		 * virtchnl hash fields.
+		 */
+		for (j = 0; j < hf_list_len; j++) {
+			struct ice_vc_hash_field_match_type hf_map =
+				hf_list[j];
+
+			if (proto_hdr->type == hf_map.vc_hdr &&
+			    proto_hdr->field_selector ==
+			     hf_map.vc_hash_field) {
+				*hash_flds |= hf_map.ice_hash_field;
+				break;
+			}
+		}
+	}
+
+	return true;
+}
+
+/**
+ * ice_vf_adv_rss_offload_ena - determine if capabilities support advanced
+ * rss offloads
+ * @caps: VF driver negotiated capabilities
+ *
+ * Return true if VIRTCHNL_VF_OFFLOAD_ADV_RSS_PF capability is set,
+ * else return false
+ */
+static bool ice_vf_adv_rss_offload_ena(u32 caps)
+{
+	return !!(caps & VIRTCHNL_VF_OFFLOAD_ADV_RSS_PF);
+}
+
+/**
+ * ice_vc_handle_rss_cfg
+ * @vf: pointer to the VF info
+ * @msg: pointer to the msg buffer
+ * @add: add a rss cfg if true, otherwise delete a rss cfg
+ *
+ * This function adds/deletes a rss cfg
+ */
+static int ice_vc_handle_rss_cfg(struct ice_vf *vf, u8 *msg, bool add)
+{
+	struct virtchnl_rss_cfg *rss_cfg = (struct virtchnl_rss_cfg *)msg;
+	enum virtchnl_status_code v_ret = VIRTCHNL_STATUS_SUCCESS;
+	u32 v_opcode = add ? VIRTCHNL_OP_ADD_RSS_CFG :
+			VIRTCHNL_OP_DEL_RSS_CFG;
+	struct device *dev = ice_pf_to_dev(vf->pf);
+	struct ice_hw *hw = &vf->pf->hw;
+	struct ice_vsi *vsi;
+
+	if (!test_bit(ICE_FLAG_RSS_ENA, vf->pf->flags)) {
+		dev_dbg(dev, "VF %d attempting to configure RSS, but RSS is not supported by the PF\n",
+			vf->vf_id);
+		v_ret = VIRTCHNL_STATUS_ERR_NOT_SUPPORTED;
+		goto error_param;
+	}
+
+	if (!ice_vf_adv_rss_offload_ena(vf->driver_caps)) {
+		dev_dbg(dev, "VF %d attempting to configure RSS, but Advanced RSS offload is not supported\n",
+			vf->vf_id);
+		v_ret = VIRTCHNL_STATUS_ERR_PARAM;
+		goto error_param;
+	}
+
+	if (!test_bit(ICE_VF_STATE_ACTIVE, vf->vf_states)) {
+		v_ret = VIRTCHNL_STATUS_ERR_PARAM;
+		goto error_param;
+	}
+
+	if (rss_cfg->proto_hdrs.count > VIRTCHNL_MAX_NUM_PROTO_HDRS ||
+	    rss_cfg->rss_algorithm < VIRTCHNL_RSS_ALG_TOEPLITZ_ASYMMETRIC ||
+	    rss_cfg->rss_algorithm > VIRTCHNL_RSS_ALG_XOR_SYMMETRIC) {
+		dev_dbg(dev, "VF %d attempting to configure RSS, but RSS configuration is not valid\n",
+			vf->vf_id);
+		v_ret = VIRTCHNL_STATUS_ERR_PARAM;
+		goto error_param;
+	}
+
+	vsi = vf->pf->vsi[vf->lan_vsi_idx];
+	if (!vsi) {
+		v_ret = VIRTCHNL_STATUS_ERR_PARAM;
+		goto error_param;
+	}
+
+	if (rss_cfg->rss_algorithm == VIRTCHNL_RSS_ALG_R_ASYMMETRIC) {
+		struct ice_vsi_ctx *ctx;
+		enum ice_status status;
+		u8 lut_type, hash_type;
+
+		lut_type = ICE_AQ_VSI_Q_OPT_RSS_LUT_VSI;
+		hash_type = add ? ICE_AQ_VSI_Q_OPT_RSS_XOR :
+				ICE_AQ_VSI_Q_OPT_RSS_TPLZ;
+
+		ctx = kzalloc(sizeof(*ctx), GFP_KERNEL);
+		if (!ctx) {
+			v_ret = VIRTCHNL_STATUS_ERR_NO_MEMORY;
+			goto error_param;
+		}
+
+		ctx->info.q_opt_rss = ((lut_type <<
+					ICE_AQ_VSI_Q_OPT_RSS_LUT_S) &
+				       ICE_AQ_VSI_Q_OPT_RSS_LUT_M) |
+				       (hash_type &
+					ICE_AQ_VSI_Q_OPT_RSS_HASH_M);
+
+		/* Preserve existing queueing option setting */
+		ctx->info.q_opt_rss |= (vsi->info.q_opt_rss &
+					  ICE_AQ_VSI_Q_OPT_RSS_GBL_LUT_M);
+		ctx->info.q_opt_tc = vsi->info.q_opt_tc;
+		ctx->info.q_opt_flags = vsi->info.q_opt_rss;
+
+		ctx->info.valid_sections =
+				cpu_to_le16(ICE_AQ_VSI_PROP_Q_OPT_VALID);
+
+		status = ice_update_vsi(hw, vsi->idx, ctx, NULL);
+		if (status) {
+			dev_err(dev,
+				"update VSI for RSS failed, err %s aq_err %s\n",
+				ice_stat_str(status),
+				ice_aq_str(hw->adminq.sq_last_status));
+			v_ret = VIRTCHNL_STATUS_ERR_PARAM;
+		} else {
+			vsi->info.q_opt_rss = ctx->info.q_opt_rss;
+		}
+
+		kfree(ctx);
+	} else {
+		u32 addl_hdrs = ICE_FLOW_SEG_HDR_NONE;
+		u64 hash_flds = ICE_HASH_INVALID;
+
+		if (!ice_vc_parse_rss_cfg(hw, rss_cfg, &addl_hdrs,
+					  &hash_flds)) {
+			v_ret = VIRTCHNL_STATUS_ERR_PARAM;
+			goto error_param;
+		}
+
+		if (add) {
+			if (ice_add_rss_cfg(hw, vsi->idx, hash_flds,
+					    addl_hdrs)) {
+				v_ret = VIRTCHNL_STATUS_ERR_PARAM;
+				dev_err(dev,
+					"ice_add_rss_cfg failed for vsi = %d, v_ret = %d\n",
+					vsi->vsi_num, v_ret);
+			}
+		} else {
+			v_ret = VIRTCHNL_STATUS_ERR_PARAM;
+			dev_err(dev, "RSS removal not support\n");
+		}
+	}
+
+error_param:
+	return ice_vc_send_msg_to_vf(vf, v_opcode, v_ret, NULL, 0);
+}
+
+/**
  * ice_vc_config_rss_key
  * @vf: pointer to the VF info
  * @msg: pointer to the msg buffer
@@ -4221,6 +4674,12 @@  void ice_vc_process_vf_msg(struct ice_pf *pf, struct ice_rq_event_info *event)
 	case VIRTCHNL_OP_DCF_GET_PKG_INFO:
 		err = ice_vc_dcf_query_pkg_info(vf);
 		break;
+	case VIRTCHNL_OP_ADD_RSS_CFG:
+		err = ice_vc_handle_rss_cfg(vf, msg, true);
+		break;
+	case VIRTCHNL_OP_DEL_RSS_CFG:
+		err = ice_vc_handle_rss_cfg(vf, msg, false);
+		break;
 	case VIRTCHNL_OP_UNKNOWN:
 	default:
 		dev_err(dev, "Unsupported opcode %d from VF %d\n", v_opcode,
diff --git a/include/linux/avf/virtchnl.h b/include/linux/avf/virtchnl.h
index 825cdc0e9ffe..d7e5263fd2ec 100644
--- a/include/linux/avf/virtchnl.h
+++ b/include/linux/avf/virtchnl.h
@@ -143,6 +143,8 @@  enum virtchnl_ops {
 	VIRTCHNL_OP_DCF_GET_VSI_MAP = 42,
 	VIRTCHNL_OP_DCF_GET_PKG_INFO = 43,
 	VIRTCHNL_OP_GET_SUPPORTED_RXDIDS = 44,
+	VIRTCHNL_OP_ADD_RSS_CFG = 45,
+	VIRTCHNL_OP_DEL_RSS_CFG = 46,
 	/* New major set of opcodes introduced and so leaving room for
 	 * old misc opcodes to be added in future. Also these opcodes may only
 	 * be used if both the PF and VF have successfully negotiated the
@@ -283,6 +285,7 @@  VIRTCHNL_CHECK_STRUCT_LEN(16, virtchnl_vsi_resource);
 #define VIRTCHNL_VF_OFFLOAD_RX_ENCAP_CSUM	0X00400000
 #define VIRTCHNL_VF_OFFLOAD_ADQ			0X00800000
 #define VIRTCHNL_VF_OFFLOAD_RX_FLEX_DESC	0X04000000
+#define VIRTCHNL_VF_OFFLOAD_ADV_RSS_PF		0X08000000
 #define VIRTCHNL_VF_CAP_DCF			0X40000000
 
 /* Define below the capability flags that are not offloads */
@@ -557,6 +560,14 @@  struct virtchnl_rss_hena {
 
 VIRTCHNL_CHECK_STRUCT_LEN(8, virtchnl_rss_hena);
 
+/* Type of RSS algorithm */
+enum virtchnl_rss_algorithm {
+	VIRTCHNL_RSS_ALG_TOEPLITZ_ASYMMETRIC	= 0,
+	VIRTCHNL_RSS_ALG_R_ASYMMETRIC		= 1,
+	VIRTCHNL_RSS_ALG_TOEPLITZ_SYMMETRIC	= 2,
+	VIRTCHNL_RSS_ALG_XOR_SYMMETRIC		= 3,
+};
+
 /* VIRTCHNL_OP_ENABLE_CHANNELS
  * VIRTCHNL_OP_DISABLE_CHANNELS
  * VF sends these messages to enable or disable channels based on
@@ -773,6 +784,170 @@  enum virtchnl_vfr_states {
 	VIRTCHNL_VFR_VFACTIVE,
 };
 
+#define VIRTCHNL_MAX_NUM_PROTO_HDRS	32
+#define PROTO_HDR_SHIFT			5
+#define PROTO_HDR_FIELD_START(proto_hdr_type) \
+					(proto_hdr_type << PROTO_HDR_SHIFT)
+#define PROTO_HDR_FIELD_MASK ((1UL << PROTO_HDR_SHIFT) - 1)
+
+/* VF use these macros to configure each protocol header.
+ * Specify which protocol headers and protocol header fields base on
+ * virtchnl_proto_hdr_type and virtchnl_proto_hdr_field.
+ * @param hdr: a struct of virtchnl_proto_hdr
+ * @param hdr_type: ETH/IPV4/TCP, etc
+ * @param field: SRC/DST/TEID/SPI, etc
+ */
+#define VIRTCHNL_ADD_PROTO_HDR_FIELD(hdr, field) \
+	((hdr)->field_selector |= BIT((field) & PROTO_HDR_FIELD_MASK))
+#define VIRTCHNL_DEL_PROTO_HDR_FIELD(hdr, field) \
+	((hdr)->field_selector &= ~BIT((field) & PROTO_HDR_FIELD_MASK))
+#define VIRTCHNL_TEST_PROTO_HDR_FIELD(hdr, val) \
+	((hdr)->field_selector & BIT((val) & PROTO_HDR_FIELD_MASK))
+#define VIRTCHNL_GET_PROTO_HDR_FIELD(hdr)	((hdr)->field_selector)
+
+#define VIRTCHNL_ADD_PROTO_HDR_FIELD_BIT(hdr, hdr_type, field) \
+	(VIRTCHNL_ADD_PROTO_HDR_FIELD(hdr, \
+		VIRTCHNL_PROTO_HDR_ ## hdr_type ## _ ## field))
+#define VIRTCHNL_DEL_PROTO_HDR_FIELD_BIT(hdr, hdr_type, field) \
+	(VIRTCHNL_DEL_PROTO_HDR_FIELD(hdr, \
+		VIRTCHNL_PROTO_HDR_ ## hdr_type ## _ ## field))
+
+#define VIRTCHNL_SET_PROTO_HDR_TYPE(hdr, hdr_type) \
+	((hdr)->type = VIRTCHNL_PROTO_HDR_ ## hdr_type)
+#define VIRTCHNL_GET_PROTO_HDR_TYPE(hdr) \
+	(((hdr)->type) >> PROTO_HDR_SHIFT)
+#define VIRTCHNL_TEST_PROTO_HDR_TYPE(hdr, val) \
+	((hdr)->type == ((val) >> PROTO_HDR_SHIFT))
+#define VIRTCHNL_TEST_PROTO_HDR(hdr, val) \
+	(VIRTCHNL_TEST_PROTO_HDR_TYPE(hdr, val) && \
+	 VIRTCHNL_TEST_PROTO_HDR_FIELD(hdr, val))
+
+/* Protocol header type within a packet segment. A segment consists of one or
+ * more protocol headers that make up a logical group of protocol headers. Each
+ * logical group of protocol headers encapsulates or is encapsulated using/by
+ * tunneling or encapsulation protocols for network virtualization.
+ */
+enum virtchnl_proto_hdr_type {
+	VIRTCHNL_PROTO_HDR_NONE,
+	VIRTCHNL_PROTO_HDR_ETH,
+	VIRTCHNL_PROTO_HDR_S_VLAN,
+	VIRTCHNL_PROTO_HDR_C_VLAN,
+	VIRTCHNL_PROTO_HDR_IPV4,
+	VIRTCHNL_PROTO_HDR_IPV6,
+	VIRTCHNL_PROTO_HDR_TCP,
+	VIRTCHNL_PROTO_HDR_UDP,
+	VIRTCHNL_PROTO_HDR_SCTP,
+	VIRTCHNL_PROTO_HDR_GTPU_IP,
+	VIRTCHNL_PROTO_HDR_GTPU_EH,
+	VIRTCHNL_PROTO_HDR_GTPU_EH_PDU_DWN,
+	VIRTCHNL_PROTO_HDR_GTPU_EH_PDU_UP,
+	VIRTCHNL_PROTO_HDR_PPPOE,
+	VIRTCHNL_PROTO_HDR_L2TPV3,
+	VIRTCHNL_PROTO_HDR_ESP,
+	VIRTCHNL_PROTO_HDR_AH,
+	VIRTCHNL_PROTO_HDR_PFCP,
+};
+
+/* Protocol header field within a protocol header. */
+enum virtchnl_proto_hdr_field {
+	/* ETHER */
+	VIRTCHNL_PROTO_HDR_ETH_SRC =
+		PROTO_HDR_FIELD_START(VIRTCHNL_PROTO_HDR_ETH),
+	VIRTCHNL_PROTO_HDR_ETH_DST,
+	VIRTCHNL_PROTO_HDR_ETH_ETHERTYPE,
+	/* S-VLAN */
+	VIRTCHNL_PROTO_HDR_S_VLAN_ID =
+		PROTO_HDR_FIELD_START(VIRTCHNL_PROTO_HDR_S_VLAN),
+	/* C-VLAN */
+	VIRTCHNL_PROTO_HDR_C_VLAN_ID =
+		PROTO_HDR_FIELD_START(VIRTCHNL_PROTO_HDR_C_VLAN),
+	/* IPV4 */
+	VIRTCHNL_PROTO_HDR_IPV4_SRC =
+		PROTO_HDR_FIELD_START(VIRTCHNL_PROTO_HDR_IPV4),
+	VIRTCHNL_PROTO_HDR_IPV4_DST,
+	VIRTCHNL_PROTO_HDR_IPV4_DSCP,
+	VIRTCHNL_PROTO_HDR_IPV4_TTL,
+	VIRTCHNL_PROTO_HDR_IPV4_PROT,
+	/* IPV6 */
+	VIRTCHNL_PROTO_HDR_IPV6_SRC =
+		PROTO_HDR_FIELD_START(VIRTCHNL_PROTO_HDR_IPV6),
+	VIRTCHNL_PROTO_HDR_IPV6_DST,
+	VIRTCHNL_PROTO_HDR_IPV6_TC,
+	VIRTCHNL_PROTO_HDR_IPV6_HOP_LIMIT,
+	VIRTCHNL_PROTO_HDR_IPV6_PROT,
+	/* TCP */
+	VIRTCHNL_PROTO_HDR_TCP_SRC_PORT =
+		PROTO_HDR_FIELD_START(VIRTCHNL_PROTO_HDR_TCP),
+	VIRTCHNL_PROTO_HDR_TCP_DST_PORT,
+	/* UDP */
+	VIRTCHNL_PROTO_HDR_UDP_SRC_PORT =
+		PROTO_HDR_FIELD_START(VIRTCHNL_PROTO_HDR_UDP),
+	VIRTCHNL_PROTO_HDR_UDP_DST_PORT,
+	/* SCTP */
+	VIRTCHNL_PROTO_HDR_SCTP_SRC_PORT =
+		PROTO_HDR_FIELD_START(VIRTCHNL_PROTO_HDR_SCTP),
+	VIRTCHNL_PROTO_HDR_SCTP_DST_PORT,
+	/* GTPU_IP */
+	VIRTCHNL_PROTO_HDR_GTPU_IP_TEID =
+		PROTO_HDR_FIELD_START(VIRTCHNL_PROTO_HDR_GTPU_IP),
+	/* GTPU_EH */
+	VIRTCHNL_PROTO_HDR_GTPU_EH_PDU =
+		PROTO_HDR_FIELD_START(VIRTCHNL_PROTO_HDR_GTPU_EH),
+	VIRTCHNL_PROTO_HDR_GTPU_EH_QFI,
+	/* PPPOE */
+	VIRTCHNL_PROTO_HDR_PPPOE_SESS_ID =
+		PROTO_HDR_FIELD_START(VIRTCHNL_PROTO_HDR_PPPOE),
+	/* L2TPV3 */
+	VIRTCHNL_PROTO_HDR_L2TPV3_SESS_ID =
+		PROTO_HDR_FIELD_START(VIRTCHNL_PROTO_HDR_L2TPV3),
+	/* ESP */
+	VIRTCHNL_PROTO_HDR_ESP_SPI =
+		PROTO_HDR_FIELD_START(VIRTCHNL_PROTO_HDR_ESP),
+	/* AH */
+	VIRTCHNL_PROTO_HDR_AH_SPI =
+		PROTO_HDR_FIELD_START(VIRTCHNL_PROTO_HDR_AH),
+	/* PFCP */
+	VIRTCHNL_PROTO_HDR_PFCP_S_FIELD =
+		PROTO_HDR_FIELD_START(VIRTCHNL_PROTO_HDR_PFCP),
+	VIRTCHNL_PROTO_HDR_PFCP_SEID,
+};
+
+struct virtchnl_proto_hdr {
+	enum virtchnl_proto_hdr_type type;
+	u32 field_selector; /* a bit mask to select field for header type */
+	u8 buffer[64];
+	/**
+	 * binary buffer in network order for specific header type.
+	 * For example, if type = VIRTCHNL_PROTO_HDR_IPV4, a IPv4
+	 * header is expected to be copied into the buffer.
+	 */
+};
+
+VIRTCHNL_CHECK_STRUCT_LEN(72, virtchnl_proto_hdr);
+
+struct virtchnl_proto_hdrs {
+	u8 tunnel_level;
+	/**
+	 * specify where protocol header start from.
+	 * 0 - from the outer layer
+	 * 1 - from the first inner layer
+	 * 2 - from the second inner layer
+	 * ....
+	 **/
+	int count; /* the proto layers must < VIRTCHNL_MAX_NUM_PROTO_HDRS */
+	struct virtchnl_proto_hdr proto_hdr[VIRTCHNL_MAX_NUM_PROTO_HDRS];
+};
+
+VIRTCHNL_CHECK_STRUCT_LEN(2312, virtchnl_proto_hdrs);
+
+struct virtchnl_rss_cfg {
+	struct virtchnl_proto_hdrs proto_hdrs;	   /* protocol headers */
+	enum virtchnl_rss_algorithm rss_algorithm; /* rss algorithm type */
+	u8 reserved[128];                          /* reserve for future */
+};
+
+VIRTCHNL_CHECK_STRUCT_LEN(2444, virtchnl_rss_cfg);
+
 /* PF capability flags
  * VIRTCHNL_CAP_STATELESS_OFFLOADS flag indicates stateless offloads
  * such as TX/RX Checksum offloading and TSO for non-tunneled packets. Please
@@ -839,14 +1014,6 @@  enum virtchnl_desc_profile {
         VIRTCHNL_TXQ_DESC_PROFILE_NATIVE        = 1,
 };
 
-/* Type of RSS algorithm */
-enum virtchnl_rss_algorithm {
-        VIRTCHNL_RSS_ALG_TOEPLITZ_ASYMMETRIC    = 0,
-        VIRTCHNL_RSS_ALG_R_ASYMMETRIC           = 1,
-        VIRTCHNL_RSS_ALG_TOEPLITZ_SYMMETRIC     = 2,
-        VIRTCHNL_RSS_ALG_XOR_SYMMETRIC          = 3,
-};
-
 /* VIRTCHNL_OP_GET_CAPS
  * PF sends this message to CP to negotiate capabilities by filling
  * in the u64 bitmap of its desired capabilities, max_num_vfs and
@@ -1336,6 +1503,10 @@  virtchnl_vc_validate_vf_msg(struct virtchnl_version_info *ver, u32 v_opcode,
 	case VIRTCHNL_OP_DCF_GET_PKG_INFO:
 	case VIRTCHNL_OP_GET_SUPPORTED_RXDIDS:
 		break;
+	case VIRTCHNL_OP_ADD_RSS_CFG:
+	case VIRTCHNL_OP_DEL_RSS_CFG:
+		valid_len = sizeof(struct virtchnl_rss_cfg);
+		break;
 	case VIRTCHNL_OP_GET_CAPS:
 		valid_len = sizeof(struct virtchnl_get_capabilities);
 		break;