Merge branch '40GbE' of git://git.kernel.org/pub/scm/linux/kernel/git/tnguy/next-queue

Tony Nguyen says:

====================
Intel Wired LAN Driver Updates 2025-11-06 (i40, ice, iavf)

Mohammad Heib introduces a new devlink parameter, max_mac_per_vf, for
controlling the maximum number of MAC address filters allowed by a VF. This
allows administrators to control the VF behavior in a more nuanced manner.

Aleksandr and Przemek add support for Receive Side Scaling of GTP to iAVF
for VFs running on E800 series ice hardware. This improves performance and
scalability for virtualized network functions in 5G and LTE deployments.

* '40GbE' of git://git.kernel.org/pub/scm/linux/kernel/git/tnguy/next-queue:
  iavf: add RSS support for GTP protocol via ethtool
  ice: Extend PTYPE bitmap coverage for GTP encapsulated flows
  ice: improve TCAM priority handling for RSS profiles
  ice: implement GTP RSS context tracking and configuration
  ice: add virtchnl definitions and static data for GTP RSS
  ice: add flow parsing for GTP and new protocol field support
  i40e: support generic devlink param "max_mac_per_vf"
  devlink: Add new "max_mac_per_vf" generic device param
====================

Link: https://patch.msgid.link/20251106225321.1609605-1-anthony.l.nguyen@intel.com
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
This commit is contained in:
Jakub Kicinski
2025-11-07 19:15:36 -08:00
18 changed files with 2124 additions and 137 deletions
@@ -151,3 +151,7 @@ own name.
* - ``num_doorbells``
- u32
- Controls the number of doorbells used by the device.
* - ``max_mac_per_vf``
- u32
- Controls the maximum number of MAC address filters that can be assigned
to a Virtual Function (VF).
+34
View File
@@ -7,6 +7,40 @@ i40e devlink support
This document describes the devlink features implemented by the ``i40e``
device driver.
Parameters
==========
.. list-table:: Generic parameters implemented
:widths: 5 5 90
* - Name
- Mode
- Notes
* - ``max_mac_per_vf``
- runtime
- Controls the maximum number of MAC addresses a VF can use
on i40e devices.
By default (``0``), the driver enforces its internally calculated per-VF
MAC filter limit, which is based on the number of allocated VFS.
If set to a non-zero value, this parameter acts as a strict cap:
the driver will use the user-provided value instead of its internal
calculation.
**Important notes:**
- This value **must be set before enabling SR-IOV**.
Attempting to change it while SR-IOV is enabled will return an error.
- MAC filters are a **shared hardware resource** across all VFs.
Setting a high value may cause other VFs to be starved of filters.
- This value is a **Administrative policy**. The hardware may return
errors when its absolute limit is reached, regardless of the value
set here.
The default value is ``0`` (internal calculation is used).
Info versions
=============
+4
View File
@@ -574,6 +574,10 @@ struct i40e_pf {
struct i40e_vf *vf;
int num_alloc_vfs; /* actual number of VFs allocated */
u32 vf_aq_requests;
/* If set to non-zero, the device uses this value
* as maximum number of MAC filters per VF.
*/
u32 max_mac_per_vf;
u32 arq_overflows; /* Not fatal, possibly indicative of problems */
struct ratelimit_state mdd_message_rate_limit;
/* DCBx/DCBNL capability for PF that indicates
+52 -2
View File
@@ -5,6 +5,41 @@
#include "i40e.h"
#include "i40e_devlink.h"
static int i40e_max_mac_per_vf_set(struct devlink *devlink,
u32 id,
struct devlink_param_gset_ctx *ctx,
struct netlink_ext_ack *extack)
{
struct i40e_pf *pf = devlink_priv(devlink);
if (pf->num_alloc_vfs > 0) {
NL_SET_ERR_MSG_MOD(extack,
"Cannot change max_mac_per_vf while SR-IOV is enabled");
return -EBUSY;
}
pf->max_mac_per_vf = ctx->val.vu32;
return 0;
}
static int i40e_max_mac_per_vf_get(struct devlink *devlink,
u32 id,
struct devlink_param_gset_ctx *ctx)
{
struct i40e_pf *pf = devlink_priv(devlink);
ctx->val.vu32 = pf->max_mac_per_vf;
return 0;
}
static const struct devlink_param i40e_dl_params[] = {
DEVLINK_PARAM_GENERIC(MAX_MAC_PER_VF,
BIT(DEVLINK_PARAM_CMODE_RUNTIME),
i40e_max_mac_per_vf_get,
i40e_max_mac_per_vf_set,
NULL),
};
static void i40e_info_get_dsn(struct i40e_pf *pf, char *buf, size_t len)
{
u8 dsn[8];
@@ -165,7 +200,18 @@ void i40e_free_pf(struct i40e_pf *pf)
**/
void i40e_devlink_register(struct i40e_pf *pf)
{
devlink_register(priv_to_devlink(pf));
struct devlink *dl = priv_to_devlink(pf);
struct device *dev = &pf->pdev->dev;
int err;
err = devlink_params_register(dl, i40e_dl_params,
ARRAY_SIZE(i40e_dl_params));
if (err)
dev_err(dev,
"devlink params register failed with error %d", err);
devlink_register(dl);
}
/**
@@ -176,7 +222,11 @@ void i40e_devlink_register(struct i40e_pf *pf)
**/
void i40e_devlink_unregister(struct i40e_pf *pf)
{
devlink_unregister(priv_to_devlink(pf));
struct devlink *dl = priv_to_devlink(pf);
devlink_unregister(dl);
devlink_params_unregister(dl, i40e_dl_params,
ARRAY_SIZE(i40e_dl_params));
}
/**
@@ -2935,33 +2935,48 @@ static inline int i40e_check_vf_permission(struct i40e_vf *vf,
if (!f)
++mac_add_cnt;
}
/* If this VF is not privileged, then we can't add more than a limited
* number of addresses.
/* Determine the maximum number of MAC addresses this VF may use.
*
* If this VF is trusted, it can use more resources than untrusted.
* However to ensure that every trusted VF has appropriate number of
* resources, divide whole pool of resources per port and then across
* all VFs.
* - For untrusted VFs: use a fixed small limit.
*
* - For trusted VFs: limit is calculated by dividing total MAC
* filter pool across all VFs/ports.
*
* - User can override this by devlink param "max_mac_per_vf".
* If set its value is used as a strict cap for both trusted and
* untrusted VFs.
* Note:
* even when overridden, this is a theoretical maximum; hardware
* may reject additional MACs if the absolute HW limit is reached.
*/
if (!vf_trusted)
mac_add_max = I40E_VC_MAX_MAC_ADDR_PER_VF;
else
mac_add_max = I40E_VC_MAX_MACVLAN_PER_TRUSTED_VF(pf->num_alloc_vfs, hw->num_ports);
if (pf->max_mac_per_vf > 0)
mac_add_max = pf->max_mac_per_vf;
/* VF can replace all its filters in one step, in this case mac_add_max
* will be added as active and another mac_add_max will be in
* a to-be-removed state. Account for that.
*/
if ((i40e_count_active_filters(vsi) + mac_add_cnt) > mac_add_max ||
(i40e_count_all_filters(vsi) + mac_add_cnt) > 2 * mac_add_max) {
if (pf->max_mac_per_vf == mac_add_max && mac_add_max > 0) {
dev_err(&pf->pdev->dev,
"Cannot add more MAC addresses: VF reached its maximum allowed limit (%d)\n",
mac_add_max);
return -EPERM;
}
if (!vf_trusted) {
dev_err(&pf->pdev->dev,
"Cannot add more MAC addresses, VF is not trusted, switch the VF to trusted to add more functionality\n");
return -EPERM;
} else {
dev_err(&pf->pdev->dev,
"Cannot add more MAC addresses, trusted VF exhausted it's resources\n");
"Cannot add more MAC addresses: trusted VF reached its maximum allowed limit (%d)\n",
mac_add_max);
return -EPERM;
}
}
+96 -23
View File
@@ -90,6 +90,55 @@ iavf_fill_adv_rss_sctp_hdr(struct virtchnl_proto_hdr *hdr, u64 hash_flds)
VIRTCHNL_ADD_PROTO_HDR_FIELD_BIT(hdr, SCTP, DST_PORT);
}
/**
* iavf_fill_adv_rss_gtp_hdr - Fill GTP-related RSS protocol headers
* @proto_hdrs: pointer to the virtchnl protocol headers structure to populate
* @packet_hdrs: bitmask of packet header types to configure
* @hash_flds: RSS hash field configuration
*
* This function populates the virtchnl protocol header structure with
* appropriate GTP-related header types based on the specified packet_hdrs.
* It supports GTPC, GTPU with extension headers, and uplink/downlink PDU
* types. For certain GTPU types, it also appends an IPv4 header to enable
* hashing on the destination IP address.
*
* Return: 0 on success or -EOPNOTSUPP if the packet_hdrs value is unsupported.
*/
static int
iavf_fill_adv_rss_gtp_hdr(struct virtchnl_proto_hdrs *proto_hdrs,
u32 packet_hdrs, u64 hash_flds)
{
struct virtchnl_proto_hdr *hdr;
hdr = &proto_hdrs->proto_hdr[proto_hdrs->count - 1];
switch (packet_hdrs & IAVF_ADV_RSS_FLOW_SEG_HDR_GTP) {
case IAVF_ADV_RSS_FLOW_SEG_HDR_GTPC_TEID:
case IAVF_ADV_RSS_FLOW_SEG_HDR_GTPC:
VIRTCHNL_SET_PROTO_HDR_TYPE(hdr, GTPC);
break;
case IAVF_ADV_RSS_FLOW_SEG_HDR_GTPU_EH:
VIRTCHNL_SET_PROTO_HDR_TYPE(hdr, GTPU_EH);
break;
case IAVF_ADV_RSS_FLOW_SEG_HDR_GTPU_UP:
VIRTCHNL_SET_PROTO_HDR_TYPE(hdr, GTPU_EH_PDU_UP);
hdr = &proto_hdrs->proto_hdr[proto_hdrs->count++];
iavf_fill_adv_rss_ip4_hdr(hdr, IAVF_ADV_RSS_HASH_FLD_IPV4_DA);
break;
case IAVF_ADV_RSS_FLOW_SEG_HDR_GTPU_DWN:
VIRTCHNL_SET_PROTO_HDR_TYPE(hdr, GTPU_EH_PDU_DWN);
fallthrough;
case IAVF_ADV_RSS_FLOW_SEG_HDR_GTPU_IP:
hdr = &proto_hdrs->proto_hdr[proto_hdrs->count++];
iavf_fill_adv_rss_ip4_hdr(hdr, IAVF_ADV_RSS_HASH_FLD_IPV4_DA);
break;
default:
return -EOPNOTSUPP;
}
return 0;
}
/**
* iavf_fill_adv_rss_cfg_msg - fill the RSS configuration into virtchnl message
* @rss_cfg: the virtchnl message to be filled with RSS configuration setting
@@ -103,6 +152,8 @@ int
iavf_fill_adv_rss_cfg_msg(struct virtchnl_rss_cfg *rss_cfg,
u32 packet_hdrs, u64 hash_flds, bool symm)
{
const u32 packet_l3_hdrs = packet_hdrs & IAVF_ADV_RSS_FLOW_SEG_HDR_L3;
const u32 packet_l4_hdrs = packet_hdrs & IAVF_ADV_RSS_FLOW_SEG_HDR_L4;
struct virtchnl_proto_hdrs *proto_hdrs = &rss_cfg->proto_hdrs;
struct virtchnl_proto_hdr *hdr;
@@ -113,31 +164,41 @@ iavf_fill_adv_rss_cfg_msg(struct virtchnl_rss_cfg *rss_cfg,
proto_hdrs->tunnel_level = 0; /* always outer layer */
hdr = &proto_hdrs->proto_hdr[proto_hdrs->count++];
switch (packet_hdrs & IAVF_ADV_RSS_FLOW_SEG_HDR_L3) {
case IAVF_ADV_RSS_FLOW_SEG_HDR_IPV4:
iavf_fill_adv_rss_ip4_hdr(hdr, hash_flds);
break;
case IAVF_ADV_RSS_FLOW_SEG_HDR_IPV6:
iavf_fill_adv_rss_ip6_hdr(hdr, hash_flds);
break;
default:
return -EINVAL;
if (packet_l3_hdrs) {
hdr = &proto_hdrs->proto_hdr[proto_hdrs->count++];
switch (packet_l3_hdrs) {
case IAVF_ADV_RSS_FLOW_SEG_HDR_IPV4:
iavf_fill_adv_rss_ip4_hdr(hdr, hash_flds);
break;
case IAVF_ADV_RSS_FLOW_SEG_HDR_IPV6:
iavf_fill_adv_rss_ip6_hdr(hdr, hash_flds);
break;
default:
return -EINVAL;
}
}
hdr = &proto_hdrs->proto_hdr[proto_hdrs->count++];
switch (packet_hdrs & IAVF_ADV_RSS_FLOW_SEG_HDR_L4) {
case IAVF_ADV_RSS_FLOW_SEG_HDR_TCP:
iavf_fill_adv_rss_tcp_hdr(hdr, hash_flds);
break;
case IAVF_ADV_RSS_FLOW_SEG_HDR_UDP:
iavf_fill_adv_rss_udp_hdr(hdr, hash_flds);
break;
case IAVF_ADV_RSS_FLOW_SEG_HDR_SCTP:
iavf_fill_adv_rss_sctp_hdr(hdr, hash_flds);
break;
default:
return -EINVAL;
if (packet_l4_hdrs) {
hdr = &proto_hdrs->proto_hdr[proto_hdrs->count++];
switch (packet_l4_hdrs) {
case IAVF_ADV_RSS_FLOW_SEG_HDR_TCP:
iavf_fill_adv_rss_tcp_hdr(hdr, hash_flds);
break;
case IAVF_ADV_RSS_FLOW_SEG_HDR_UDP:
iavf_fill_adv_rss_udp_hdr(hdr, hash_flds);
break;
case IAVF_ADV_RSS_FLOW_SEG_HDR_SCTP:
iavf_fill_adv_rss_sctp_hdr(hdr, hash_flds);
break;
default:
return -EINVAL;
}
}
if (packet_hdrs & IAVF_ADV_RSS_FLOW_SEG_HDR_GTP) {
hdr = &proto_hdrs->proto_hdr[proto_hdrs->count++];
if (iavf_fill_adv_rss_gtp_hdr(proto_hdrs, packet_hdrs, hash_flds))
return -EINVAL;
}
return 0;
@@ -186,6 +247,8 @@ iavf_print_adv_rss_cfg(struct iavf_adapter *adapter, struct iavf_adv_rss *rss,
proto = "UDP";
else if (packet_hdrs & IAVF_ADV_RSS_FLOW_SEG_HDR_SCTP)
proto = "SCTP";
else if (packet_hdrs & IAVF_ADV_RSS_FLOW_SEG_HDR_GTP)
proto = "GTP";
else
return;
@@ -211,6 +274,16 @@ iavf_print_adv_rss_cfg(struct iavf_adapter *adapter, struct iavf_adv_rss *rss,
IAVF_ADV_RSS_HASH_FLD_UDP_DST_PORT |
IAVF_ADV_RSS_HASH_FLD_SCTP_DST_PORT))
strcat(hash_opt, "dst port,");
if (hash_flds & IAVF_ADV_RSS_HASH_FLD_GTPC_TEID)
strcat(hash_opt, "gtp-c,");
if (hash_flds & IAVF_ADV_RSS_HASH_FLD_GTPU_IP_TEID)
strcat(hash_opt, "gtp-u ip,");
if (hash_flds & IAVF_ADV_RSS_HASH_FLD_GTPU_EH_TEID)
strcat(hash_opt, "gtp-u ext,");
if (hash_flds & IAVF_ADV_RSS_HASH_FLD_GTPU_UP_TEID)
strcat(hash_opt, "gtp-u ul,");
if (hash_flds & IAVF_ADV_RSS_HASH_FLD_GTPU_DWN_TEID)
strcat(hash_opt, "gtp-u dl,");
if (!action)
action = "";
@@ -22,6 +22,12 @@ enum iavf_adv_rss_flow_seg_hdr {
IAVF_ADV_RSS_FLOW_SEG_HDR_TCP = 0x00000004,
IAVF_ADV_RSS_FLOW_SEG_HDR_UDP = 0x00000008,
IAVF_ADV_RSS_FLOW_SEG_HDR_SCTP = 0x00000010,
IAVF_ADV_RSS_FLOW_SEG_HDR_GTPC = 0x00000400,
IAVF_ADV_RSS_FLOW_SEG_HDR_GTPC_TEID = 0x00000800,
IAVF_ADV_RSS_FLOW_SEG_HDR_GTPU_IP = 0x00001000,
IAVF_ADV_RSS_FLOW_SEG_HDR_GTPU_EH = 0x00002000,
IAVF_ADV_RSS_FLOW_SEG_HDR_GTPU_DWN = 0x00004000,
IAVF_ADV_RSS_FLOW_SEG_HDR_GTPU_UP = 0x00008000,
};
#define IAVF_ADV_RSS_FLOW_SEG_HDR_L3 \
@@ -33,6 +39,14 @@ enum iavf_adv_rss_flow_seg_hdr {
IAVF_ADV_RSS_FLOW_SEG_HDR_UDP | \
IAVF_ADV_RSS_FLOW_SEG_HDR_SCTP)
#define IAVF_ADV_RSS_FLOW_SEG_HDR_GTP \
(IAVF_ADV_RSS_FLOW_SEG_HDR_GTPC | \
IAVF_ADV_RSS_FLOW_SEG_HDR_GTPC_TEID | \
IAVF_ADV_RSS_FLOW_SEG_HDR_GTPU_IP | \
IAVF_ADV_RSS_FLOW_SEG_HDR_GTPU_EH | \
IAVF_ADV_RSS_FLOW_SEG_HDR_GTPU_DWN | \
IAVF_ADV_RSS_FLOW_SEG_HDR_GTPU_UP)
enum iavf_adv_rss_flow_field {
/* L3 */
IAVF_ADV_RSS_FLOW_FIELD_IDX_IPV4_SA,
@@ -46,6 +60,17 @@ enum iavf_adv_rss_flow_field {
IAVF_ADV_RSS_FLOW_FIELD_IDX_UDP_DST_PORT,
IAVF_ADV_RSS_FLOW_FIELD_IDX_SCTP_SRC_PORT,
IAVF_ADV_RSS_FLOW_FIELD_IDX_SCTP_DST_PORT,
/* GTPC_TEID */
IAVF_ADV_RSS_FLOW_FIELD_IDX_GTPC_TEID,
/* GTPU_IP */
IAVF_ADV_RSS_FLOW_FIELD_IDX_GTPU_IP_TEID,
/* GTPU_EH */
IAVF_ADV_RSS_FLOW_FIELD_IDX_GTPU_EH_TEID,
IAVF_ADV_RSS_FLOW_FIELD_IDX_GTPU_EH_QFI,
/* GTPU_UP */
IAVF_ADV_RSS_FLOW_FIELD_IDX_GTPU_UP_TEID,
/* GTPU_DWN */
IAVF_ADV_RSS_FLOW_FIELD_IDX_GTPU_DWN_TEID,
/* The total number of enums must not exceed 64 */
IAVF_ADV_RSS_FLOW_FIELD_IDX_MAX
@@ -72,6 +97,12 @@ enum iavf_adv_rss_flow_field {
BIT_ULL(IAVF_ADV_RSS_FLOW_FIELD_IDX_SCTP_SRC_PORT)
#define IAVF_ADV_RSS_HASH_FLD_SCTP_DST_PORT \
BIT_ULL(IAVF_ADV_RSS_FLOW_FIELD_IDX_SCTP_DST_PORT)
#define IAVF_ADV_RSS_HASH_FLD_GTPC_TEID BIT_ULL(IAVF_ADV_RSS_FLOW_FIELD_IDX_GTPC_TEID)
#define IAVF_ADV_RSS_HASH_FLD_GTPU_IP_TEID BIT_ULL(IAVF_ADV_RSS_FLOW_FIELD_IDX_GTPU_IP_TEID)
#define IAVF_ADV_RSS_HASH_FLD_GTPU_EH_TEID BIT_ULL(IAVF_ADV_RSS_FLOW_FIELD_IDX_GTPU_EH_TEID)
#define IAVF_ADV_RSS_HASH_FLD_GTPU_UP_TEID BIT_ULL(IAVF_ADV_RSS_FLOW_FIELD_IDX_GTPU_UP_TEID)
#define IAVF_ADV_RSS_HASH_FLD_GTPU_DWN_TEID \
BIT_ULL(IAVF_ADV_RSS_FLOW_FIELD_IDX_GTPU_DWN_TEID)
/* bookkeeping of advanced RSS configuration */
struct iavf_adv_rss {
@@ -1336,6 +1336,56 @@ static u32 iavf_adv_rss_parse_hdrs(const struct ethtool_rxfh_fields *cmd)
hdrs |= IAVF_ADV_RSS_FLOW_SEG_HDR_SCTP |
IAVF_ADV_RSS_FLOW_SEG_HDR_IPV6;
break;
case GTPU_V4_FLOW:
hdrs |= IAVF_ADV_RSS_FLOW_SEG_HDR_GTPU_IP |
IAVF_ADV_RSS_FLOW_SEG_HDR_IPV4;
break;
case GTPC_V4_FLOW:
hdrs |= IAVF_ADV_RSS_FLOW_SEG_HDR_GTPC |
IAVF_ADV_RSS_FLOW_SEG_HDR_UDP |
IAVF_ADV_RSS_FLOW_SEG_HDR_IPV4;
break;
case GTPC_TEID_V4_FLOW:
hdrs |= IAVF_ADV_RSS_FLOW_SEG_HDR_GTPC_TEID |
IAVF_ADV_RSS_FLOW_SEG_HDR_UDP |
IAVF_ADV_RSS_FLOW_SEG_HDR_IPV4;
break;
case GTPU_EH_V4_FLOW:
hdrs |= IAVF_ADV_RSS_FLOW_SEG_HDR_GTPU_EH |
IAVF_ADV_RSS_FLOW_SEG_HDR_IPV4;
break;
case GTPU_UL_V4_FLOW:
hdrs |= IAVF_ADV_RSS_FLOW_SEG_HDR_GTPU_UP |
IAVF_ADV_RSS_FLOW_SEG_HDR_IPV4;
break;
case GTPU_DL_V4_FLOW:
hdrs |= IAVF_ADV_RSS_FLOW_SEG_HDR_GTPU_DWN |
IAVF_ADV_RSS_FLOW_SEG_HDR_IPV4;
break;
case GTPU_V6_FLOW:
hdrs |= IAVF_ADV_RSS_FLOW_SEG_HDR_GTPU_IP |
IAVF_ADV_RSS_FLOW_SEG_HDR_IPV6;
break;
case GTPC_V6_FLOW:
hdrs |= IAVF_ADV_RSS_FLOW_SEG_HDR_GTPC |
IAVF_ADV_RSS_FLOW_SEG_HDR_IPV6;
break;
case GTPC_TEID_V6_FLOW:
hdrs |= IAVF_ADV_RSS_FLOW_SEG_HDR_GTPC_TEID |
IAVF_ADV_RSS_FLOW_SEG_HDR_IPV6;
break;
case GTPU_EH_V6_FLOW:
hdrs |= IAVF_ADV_RSS_FLOW_SEG_HDR_GTPU_EH |
IAVF_ADV_RSS_FLOW_SEG_HDR_IPV6;
break;
case GTPU_UL_V6_FLOW:
hdrs |= IAVF_ADV_RSS_FLOW_SEG_HDR_GTPU_UP |
IAVF_ADV_RSS_FLOW_SEG_HDR_IPV6;
break;
case GTPU_DL_V6_FLOW:
hdrs |= IAVF_ADV_RSS_FLOW_SEG_HDR_GTPU_DWN |
IAVF_ADV_RSS_FLOW_SEG_HDR_IPV6;
break;
default:
break;
}
@@ -1353,6 +1403,12 @@ iavf_adv_rss_parse_hash_flds(const struct ethtool_rxfh_fields *cmd, bool symm)
case TCP_V4_FLOW:
case UDP_V4_FLOW:
case SCTP_V4_FLOW:
case GTPU_V4_FLOW:
case GTPC_V4_FLOW:
case GTPC_TEID_V4_FLOW:
case GTPU_EH_V4_FLOW:
case GTPU_UL_V4_FLOW:
case GTPU_DL_V4_FLOW:
if (cmd->data & RXH_IP_SRC)
hfld |= IAVF_ADV_RSS_HASH_FLD_IPV4_SA;
if (cmd->data & RXH_IP_DST)
@@ -1361,6 +1417,12 @@ iavf_adv_rss_parse_hash_flds(const struct ethtool_rxfh_fields *cmd, bool symm)
case TCP_V6_FLOW:
case UDP_V6_FLOW:
case SCTP_V6_FLOW:
case GTPU_V6_FLOW:
case GTPC_V6_FLOW:
case GTPC_TEID_V6_FLOW:
case GTPU_EH_V6_FLOW:
case GTPU_UL_V6_FLOW:
case GTPU_DL_V6_FLOW:
if (cmd->data & RXH_IP_SRC)
hfld |= IAVF_ADV_RSS_HASH_FLD_IPV6_SA;
if (cmd->data & RXH_IP_DST)
@@ -1382,6 +1444,7 @@ iavf_adv_rss_parse_hash_flds(const struct ethtool_rxfh_fields *cmd, bool symm)
break;
case UDP_V4_FLOW:
case UDP_V6_FLOW:
case GTPC_V4_FLOW:
if (cmd->data & RXH_L4_B_0_1)
hfld |= IAVF_ADV_RSS_HASH_FLD_UDP_SRC_PORT;
if (cmd->data & RXH_L4_B_2_3)
@@ -1398,6 +1461,32 @@ iavf_adv_rss_parse_hash_flds(const struct ethtool_rxfh_fields *cmd, bool symm)
break;
}
}
if (cmd->data & RXH_GTP_TEID) {
switch (cmd->flow_type) {
case GTPC_TEID_V4_FLOW:
case GTPC_TEID_V6_FLOW:
hfld |= IAVF_ADV_RSS_HASH_FLD_GTPC_TEID;
break;
case GTPU_V4_FLOW:
case GTPU_V6_FLOW:
hfld |= IAVF_ADV_RSS_HASH_FLD_GTPU_IP_TEID;
break;
case GTPU_EH_V4_FLOW:
case GTPU_EH_V6_FLOW:
hfld |= IAVF_ADV_RSS_HASH_FLD_GTPU_EH_TEID;
break;
case GTPU_UL_V4_FLOW:
case GTPU_UL_V6_FLOW:
hfld |= IAVF_ADV_RSS_HASH_FLD_GTPU_UP_TEID;
break;
case GTPU_DL_V4_FLOW:
case GTPU_DL_V6_FLOW:
hfld |= IAVF_ADV_RSS_HASH_FLD_GTPU_DWN_TEID;
break;
default:
break;
}
}
return hfld;
}
+77 -14
View File
@@ -3577,6 +3577,19 @@ ice_move_vsi(struct ice_hw *hw, enum ice_block blk, u16 vsi, u16 vsig,
return 0;
}
/**
* ice_set_tcam_flags - set TCAM flag don't care mask
* @mask: mask for flags
* @dc_mask: pointer to the don't care mask
*/
static void ice_set_tcam_flags(u16 mask, u8 dc_mask[ICE_TCAM_KEY_VAL_SZ])
{
u16 inverted_mask = ~mask;
/* flags are lowest u16 */
put_unaligned_le16(inverted_mask, dc_mask);
}
/**
* ice_rem_chg_tcam_ent - remove a specific TCAM entry from change list
* @hw: pointer to the HW struct
@@ -3647,6 +3660,9 @@ ice_prof_tcam_ena_dis(struct ice_hw *hw, enum ice_block blk, bool enable,
if (!p)
return -ENOMEM;
/* set don't care masks for TCAM flags */
ice_set_tcam_flags(tcam->attr.mask, dc_msk);
status = ice_tcam_write_entry(hw, blk, tcam->tcam_idx, tcam->prof_id,
tcam->ptg, vsig, 0, tcam->attr.flags,
vl_msk, dc_msk, nm_msk);
@@ -3672,6 +3688,34 @@ err_ice_prof_tcam_ena_dis:
return status;
}
/**
* ice_ptg_attr_in_use - determine if PTG and attribute pair is in use
* @ptg_attr: pointer to the PTG and attribute pair to check
* @ptgs_used: bitmap that denotes which PTGs are in use
* @attr_used: array of PTG and attributes pairs already used
* @attr_cnt: count of entries in the attr_used array
*
* Return: true if the PTG and attribute pair is in use, false otherwise.
*/
static bool
ice_ptg_attr_in_use(struct ice_tcam_inf *ptg_attr, unsigned long *ptgs_used,
struct ice_tcam_inf *attr_used[], u16 attr_cnt)
{
u16 i;
if (!test_bit(ptg_attr->ptg, ptgs_used))
return false;
/* the PTG is used, so now look for correct attributes */
for (i = 0; i < attr_cnt; i++)
if (attr_used[i]->ptg == ptg_attr->ptg &&
attr_used[i]->attr.flags == ptg_attr->attr.flags &&
attr_used[i]->attr.mask == ptg_attr->attr.mask)
return true;
return false;
}
/**
* ice_adj_prof_priorities - adjust profile based on priorities
* @hw: pointer to the HW struct
@@ -3684,10 +3728,16 @@ ice_adj_prof_priorities(struct ice_hw *hw, enum ice_block blk, u16 vsig,
struct list_head *chg)
{
DECLARE_BITMAP(ptgs_used, ICE_XLT1_CNT);
struct ice_tcam_inf **attr_used;
struct ice_vsig_prof *t;
int status;
u16 attr_used_cnt = 0;
int status = 0;
u16 idx;
attr_used = kcalloc(ICE_MAX_PTG_ATTRS, sizeof(*attr_used), GFP_KERNEL);
if (!attr_used)
return -ENOMEM;
bitmap_zero(ptgs_used, ICE_XLT1_CNT);
idx = vsig & ICE_VSIG_IDX_M;
@@ -3705,11 +3755,15 @@ ice_adj_prof_priorities(struct ice_hw *hw, enum ice_block blk, u16 vsig,
u16 i;
for (i = 0; i < t->tcam_count; i++) {
bool used;
/* Scan the priorities from newest to oldest.
* Make sure that the newest profiles take priority.
*/
if (test_bit(t->tcam[i].ptg, ptgs_used) &&
t->tcam[i].in_use) {
used = ice_ptg_attr_in_use(&t->tcam[i], ptgs_used,
attr_used, attr_used_cnt);
if (used && t->tcam[i].in_use) {
/* need to mark this PTG as never match, as it
* was already in use and therefore duplicate
* (and lower priority)
@@ -3719,9 +3773,8 @@ ice_adj_prof_priorities(struct ice_hw *hw, enum ice_block blk, u16 vsig,
&t->tcam[i],
chg);
if (status)
return status;
} else if (!test_bit(t->tcam[i].ptg, ptgs_used) &&
!t->tcam[i].in_use) {
goto free_attr_used;
} else if (!used && !t->tcam[i].in_use) {
/* need to enable this PTG, as it in not in use
* and not enabled (highest priority)
*/
@@ -3730,15 +3783,21 @@ ice_adj_prof_priorities(struct ice_hw *hw, enum ice_block blk, u16 vsig,
&t->tcam[i],
chg);
if (status)
return status;
goto free_attr_used;
}
/* keep track of used ptgs */
__set_bit(t->tcam[i].ptg, ptgs_used);
set_bit(t->tcam[i].ptg, ptgs_used);
if (attr_used_cnt < ICE_MAX_PTG_ATTRS)
attr_used[attr_used_cnt++] = &t->tcam[i];
else
ice_debug(hw, ICE_DBG_INIT, "Warn: ICE_MAX_PTG_ATTRS exceeded\n");
}
}
return 0;
free_attr_used:
kfree(attr_used);
return status;
}
/**
@@ -3821,11 +3880,15 @@ ice_add_prof_id_vsig(struct ice_hw *hw, enum ice_block blk, u16 vsig, u64 hdl,
p->vsig = vsig;
p->tcam_idx = t->tcam[i].tcam_idx;
/* set don't care masks for TCAM flags */
ice_set_tcam_flags(t->tcam[i].attr.mask, dc_msk);
/* write the TCAM entry */
status = ice_tcam_write_entry(hw, blk, t->tcam[i].tcam_idx,
t->tcam[i].prof_id,
t->tcam[i].ptg, vsig, 0, 0,
vl_msk, dc_msk, nm_msk);
t->tcam[i].ptg, vsig, 0,
t->tcam[i].attr.flags, vl_msk,
dc_msk, nm_msk);
if (status) {
devm_kfree(ice_hw_to_dev(hw), p);
goto err_ice_add_prof_id_vsig;
@@ -4139,9 +4202,6 @@ ice_flow_assoc_fdir_prof(struct ice_hw *hw, enum ice_block blk,
u16 vsi_num;
int status;
if (blk != ICE_BLK_FD)
return -EINVAL;
vsi_num = ice_get_hw_vsi_num(hw, dest_vsi);
status = ice_add_prof_id_flow(hw, blk, vsi_num, hdl);
if (status) {
@@ -4150,6 +4210,9 @@ ice_flow_assoc_fdir_prof(struct ice_hw *hw, enum ice_block blk,
return status;
}
if (blk != ICE_BLK_FD)
return 0;
vsi_num = ice_get_hw_vsi_num(hw, fdir_vsi);
status = ice_add_prof_id_flow(hw, blk, vsi_num, hdl);
if (status) {
@@ -187,6 +187,7 @@ struct ice_prof_map {
};
#define ICE_INVALID_TCAM 0xFFFF
#define ICE_MAX_PTG_ATTRS 1024
struct ice_tcam_inf {
u16 tcam_idx;
+238 -31
View File
@@ -5,6 +5,38 @@
#include "ice_flow.h"
#include <net/gre.h>
/* Size of known protocol header fields */
#define ICE_FLOW_FLD_SZ_ETH_TYPE 2
#define ICE_FLOW_FLD_SZ_VLAN 2
#define ICE_FLOW_FLD_SZ_IPV4_ADDR 4
#define ICE_FLOW_FLD_SZ_IPV6_ADDR 16
#define ICE_FLOW_FLD_SZ_IPV6_PRE32_ADDR 4
#define ICE_FLOW_FLD_SZ_IPV6_PRE48_ADDR 6
#define ICE_FLOW_FLD_SZ_IPV6_PRE64_ADDR 8
#define ICE_FLOW_FLD_SZ_IPV4_ID 2
#define ICE_FLOW_FLD_SZ_IPV6_ID 4
#define ICE_FLOW_FLD_SZ_IP_CHKSUM 2
#define ICE_FLOW_FLD_SZ_TCP_CHKSUM 2
#define ICE_FLOW_FLD_SZ_UDP_CHKSUM 2
#define ICE_FLOW_FLD_SZ_SCTP_CHKSUM 4
#define ICE_FLOW_FLD_SZ_IP_DSCP 1
#define ICE_FLOW_FLD_SZ_IP_TTL 1
#define ICE_FLOW_FLD_SZ_IP_PROT 1
#define ICE_FLOW_FLD_SZ_PORT 2
#define ICE_FLOW_FLD_SZ_TCP_FLAGS 1
#define ICE_FLOW_FLD_SZ_ICMP_TYPE 1
#define ICE_FLOW_FLD_SZ_ICMP_CODE 1
#define ICE_FLOW_FLD_SZ_ARP_OPER 2
#define ICE_FLOW_FLD_SZ_GRE_KEYID 4
#define ICE_FLOW_FLD_SZ_GTP_TEID 4
#define ICE_FLOW_FLD_SZ_GTP_QFI 2
#define ICE_FLOW_FLD_SZ_PFCP_SEID 8
#define ICE_FLOW_FLD_SZ_ESP_SPI 4
#define ICE_FLOW_FLD_SZ_AH_SPI 4
#define ICE_FLOW_FLD_SZ_NAT_T_ESP_SPI 4
#define ICE_FLOW_FLD_SZ_L2TPV2_SESS_ID 2
#define ICE_FLOW_FLD_SZ_L2TPV2_LEN_SESS_ID 2
/* Describe properties of a protocol header field */
struct ice_flow_field_info {
enum ice_flow_seg_hdr hdr;
@@ -20,6 +52,7 @@ struct ice_flow_field_info {
.mask = 0, \
}
/* QFI: 6-bit field in GTP-U PDU Session Container (3GPP TS 38.415) */
#define ICE_FLOW_FLD_INFO_MSK(_hdr, _offset_bytes, _size_bytes, _mask) { \
.hdr = _hdr, \
.off = (_offset_bytes) * BITS_PER_BYTE, \
@@ -61,7 +94,33 @@ struct ice_flow_field_info ice_flds_info[ICE_FLOW_FIELD_IDX_MAX] = {
/* ICE_FLOW_FIELD_IDX_IPV6_SA */
ICE_FLOW_FLD_INFO(ICE_FLOW_SEG_HDR_IPV6, 8, sizeof(struct in6_addr)),
/* ICE_FLOW_FIELD_IDX_IPV6_DA */
ICE_FLOW_FLD_INFO(ICE_FLOW_SEG_HDR_IPV6, 24, sizeof(struct in6_addr)),
ICE_FLOW_FLD_INFO(ICE_FLOW_SEG_HDR_IPV6, 24, ICE_FLOW_FLD_SZ_IPV6_ADDR),
/* ICE_FLOW_FIELD_IDX_IPV4_CHKSUM */
ICE_FLOW_FLD_INFO(ICE_FLOW_SEG_HDR_IPV4, 10, ICE_FLOW_FLD_SZ_IP_CHKSUM),
/* ICE_FLOW_FIELD_IDX_IPV4_FRAG */
ICE_FLOW_FLD_INFO(ICE_FLOW_SEG_HDR_IPV_FRAG, 4,
ICE_FLOW_FLD_SZ_IPV4_ID),
/* ICE_FLOW_FIELD_IDX_IPV6_FRAG */
ICE_FLOW_FLD_INFO(ICE_FLOW_SEG_HDR_IPV_FRAG, 4,
ICE_FLOW_FLD_SZ_IPV6_ID),
/* ICE_FLOW_FIELD_IDX_IPV6_PRE32_SA */
ICE_FLOW_FLD_INFO(ICE_FLOW_SEG_HDR_IPV6, 8,
ICE_FLOW_FLD_SZ_IPV6_PRE32_ADDR),
/* ICE_FLOW_FIELD_IDX_IPV6_PRE32_DA */
ICE_FLOW_FLD_INFO(ICE_FLOW_SEG_HDR_IPV6, 24,
ICE_FLOW_FLD_SZ_IPV6_PRE32_ADDR),
/* ICE_FLOW_FIELD_IDX_IPV6_PRE48_SA */
ICE_FLOW_FLD_INFO(ICE_FLOW_SEG_HDR_IPV6, 8,
ICE_FLOW_FLD_SZ_IPV6_PRE48_ADDR),
/* ICE_FLOW_FIELD_IDX_IPV6_PRE48_DA */
ICE_FLOW_FLD_INFO(ICE_FLOW_SEG_HDR_IPV6, 24,
ICE_FLOW_FLD_SZ_IPV6_PRE48_ADDR),
/* ICE_FLOW_FIELD_IDX_IPV6_PRE64_SA */
ICE_FLOW_FLD_INFO(ICE_FLOW_SEG_HDR_IPV6, 8,
ICE_FLOW_FLD_SZ_IPV6_PRE64_ADDR),
/* ICE_FLOW_FIELD_IDX_IPV6_PRE64_DA */
ICE_FLOW_FLD_INFO(ICE_FLOW_SEG_HDR_IPV6, 24,
ICE_FLOW_FLD_SZ_IPV6_PRE64_ADDR),
/* Transport */
/* ICE_FLOW_FIELD_IDX_TCP_SRC_PORT */
ICE_FLOW_FLD_INFO(ICE_FLOW_SEG_HDR_TCP, 0, sizeof(__be16)),
@@ -76,7 +135,14 @@ struct ice_flow_field_info ice_flds_info[ICE_FLOW_FIELD_IDX_MAX] = {
/* ICE_FLOW_FIELD_IDX_SCTP_DST_PORT */
ICE_FLOW_FLD_INFO(ICE_FLOW_SEG_HDR_SCTP, 2, sizeof(__be16)),
/* ICE_FLOW_FIELD_IDX_TCP_FLAGS */
ICE_FLOW_FLD_INFO(ICE_FLOW_SEG_HDR_TCP, 13, 1),
ICE_FLOW_FLD_INFO(ICE_FLOW_SEG_HDR_TCP, 13, ICE_FLOW_FLD_SZ_TCP_FLAGS),
/* ICE_FLOW_FIELD_IDX_TCP_CHKSUM */
ICE_FLOW_FLD_INFO(ICE_FLOW_SEG_HDR_TCP, 16, ICE_FLOW_FLD_SZ_TCP_CHKSUM),
/* ICE_FLOW_FIELD_IDX_UDP_CHKSUM */
ICE_FLOW_FLD_INFO(ICE_FLOW_SEG_HDR_UDP, 6, ICE_FLOW_FLD_SZ_UDP_CHKSUM),
/* ICE_FLOW_FIELD_IDX_SCTP_CHKSUM */
ICE_FLOW_FLD_INFO(ICE_FLOW_SEG_HDR_SCTP, 8,
ICE_FLOW_FLD_SZ_SCTP_CHKSUM),
/* ARP */
/* ICE_FLOW_FIELD_IDX_ARP_SIP */
ICE_FLOW_FLD_INFO(ICE_FLOW_SEG_HDR_ARP, 14, sizeof(struct in_addr)),
@@ -108,9 +174,17 @@ struct ice_flow_field_info ice_flds_info[ICE_FLOW_FIELD_IDX_MAX] = {
ICE_FLOW_FLD_INFO_MSK(ICE_FLOW_SEG_HDR_GTPU_EH, 22, sizeof(__be16),
0x3f00),
/* ICE_FLOW_FIELD_IDX_GTPU_UP_TEID */
ICE_FLOW_FLD_INFO(ICE_FLOW_SEG_HDR_GTPU_UP, 12, sizeof(__be32)),
ICE_FLOW_FLD_INFO(ICE_FLOW_SEG_HDR_GTPU_UP, 12,
ICE_FLOW_FLD_SZ_GTP_TEID),
/* ICE_FLOW_FIELD_IDX_GTPU_UP_QFI */
ICE_FLOW_FLD_INFO_MSK(ICE_FLOW_SEG_HDR_GTPU_UP, 22,
ICE_FLOW_FLD_SZ_GTP_QFI, 0x3f00),
/* ICE_FLOW_FIELD_IDX_GTPU_DWN_TEID */
ICE_FLOW_FLD_INFO(ICE_FLOW_SEG_HDR_GTPU_DWN, 12, sizeof(__be32)),
ICE_FLOW_FLD_INFO(ICE_FLOW_SEG_HDR_GTPU_DWN, 12,
ICE_FLOW_FLD_SZ_GTP_TEID),
/* ICE_FLOW_FIELD_IDX_GTPU_DWN_QFI */
ICE_FLOW_FLD_INFO_MSK(ICE_FLOW_SEG_HDR_GTPU_DWN, 22,
ICE_FLOW_FLD_SZ_GTP_QFI, 0x3f00),
/* PPPoE */
/* ICE_FLOW_FIELD_IDX_PPPOE_SESS_ID */
ICE_FLOW_FLD_INFO(ICE_FLOW_SEG_HDR_PPPOE, 2, sizeof(__be16)),
@@ -128,7 +202,16 @@ struct ice_flow_field_info ice_flds_info[ICE_FLOW_FIELD_IDX_MAX] = {
ICE_FLOW_FLD_INFO(ICE_FLOW_SEG_HDR_AH, 4, sizeof(__be32)),
/* NAT_T_ESP */
/* ICE_FLOW_FIELD_IDX_NAT_T_ESP_SPI */
ICE_FLOW_FLD_INFO(ICE_FLOW_SEG_HDR_NAT_T_ESP, 8, sizeof(__be32)),
ICE_FLOW_FLD_INFO(ICE_FLOW_SEG_HDR_NAT_T_ESP, 8,
ICE_FLOW_FLD_SZ_NAT_T_ESP_SPI),
/* L2TPV2 */
/* ICE_FLOW_FIELD_IDX_L2TPV2_SESS_ID */
ICE_FLOW_FLD_INFO(ICE_FLOW_SEG_HDR_L2TPV2, 12,
ICE_FLOW_FLD_SZ_L2TPV2_SESS_ID),
/* L2TPV2_LEN */
/* ICE_FLOW_FIELD_IDX_L2TPV2_LEN_SESS_ID */
ICE_FLOW_FLD_INFO(ICE_FLOW_SEG_HDR_L2TPV2, 14,
ICE_FLOW_FLD_SZ_L2TPV2_LEN_SESS_ID),
};
/* Bitmaps indicating relevant packet types for a particular protocol header
@@ -137,9 +220,9 @@ struct ice_flow_field_info ice_flds_info[ICE_FLOW_FIELD_IDX_MAX] = {
*/
static const u32 ice_ptypes_mac_ofos[] = {
0xFDC00846, 0xBFBF7F7E, 0xF70001DF, 0xFEFDFDFB,
0x0000077E, 0x00000000, 0x00000000, 0x00000000,
0x00400000, 0x03FFF000, 0x7FFFFFE0, 0x00000000,
0x00000000, 0x00000000, 0x00000000, 0x00000000,
0x0000077E, 0x000003FF, 0x00000000, 0x00000000,
0x00400000, 0x03FFF000, 0xFFFFFFE0, 0x00000707,
0xFFFFF000, 0x000003FF, 0x00000000, 0x00000000,
0x00000000, 0x00000000, 0x00000000, 0x00000000,
0x00000000, 0x00000000, 0x00000000, 0x00000000,
0x00000000, 0x00000000, 0x00000000, 0x00000000,
@@ -162,10 +245,10 @@ static const u32 ice_ptypes_macvlan_il[] = {
* include IPv4 other PTYPEs
*/
static const u32 ice_ptypes_ipv4_ofos[] = {
0x1DC00000, 0x04000800, 0x00000000, 0x00000000,
0x1D800000, 0xBFBF7800, 0x000001DF, 0x00000000,
0x00000000, 0x00000155, 0x00000000, 0x00000000,
0x00000000, 0x000FC000, 0x00000000, 0x00000000,
0x00000000, 0x00000000, 0x00000000, 0x00000000,
0x00000000, 0x000FC000, 0x000002A0, 0x00000000,
0x00015000, 0x00000000, 0x00000000, 0x00000000,
0x00000000, 0x00000000, 0x00000000, 0x00000000,
0x00000000, 0x00000000, 0x00000000, 0x00000000,
0x00000000, 0x00000000, 0x00000000, 0x00000000,
@@ -176,10 +259,10 @@ static const u32 ice_ptypes_ipv4_ofos[] = {
* IPv4 other PTYPEs
*/
static const u32 ice_ptypes_ipv4_ofos_all[] = {
0x1DC00000, 0x04000800, 0x00000000, 0x00000000,
0x1D800000, 0x27BF7800, 0x00000000, 0x00000000,
0x00000000, 0x00000155, 0x00000000, 0x00000000,
0x00000000, 0x000FC000, 0x83E0F800, 0x00000101,
0x00000000, 0x00000000, 0x00000000, 0x00000000,
0x00000000, 0x000FC000, 0x83E0FAA0, 0x00000101,
0x3FFD5000, 0x00000000, 0x02FBEFBC, 0x00000000,
0x00000000, 0x00000000, 0x00000000, 0x00000000,
0x00000000, 0x00000000, 0x00000000, 0x00000000,
0x00000000, 0x00000000, 0x00000000, 0x00000000,
@@ -191,7 +274,7 @@ static const u32 ice_ptypes_ipv4_il[] = {
0xE0000000, 0xB807700E, 0x80000003, 0xE01DC03B,
0x0000000E, 0x00000000, 0x00000000, 0x00000000,
0x00000000, 0x00000000, 0x001FF800, 0x00000000,
0x00000000, 0x00000000, 0x00000000, 0x00000000,
0xC0FC0000, 0x0000000F, 0xBC0BC0BC, 0x00000BC0,
0x00000000, 0x00000000, 0x00000000, 0x00000000,
0x00000000, 0x00000000, 0x00000000, 0x00000000,
0x00000000, 0x00000000, 0x00000000, 0x00000000,
@@ -202,10 +285,10 @@ static const u32 ice_ptypes_ipv4_il[] = {
* include IPv6 other PTYPEs
*/
static const u32 ice_ptypes_ipv6_ofos[] = {
0x00000000, 0x00000000, 0x77000000, 0x10002000,
0x00000000, 0x00000000, 0x76000000, 0x10002000,
0x00000000, 0x000002AA, 0x00000000, 0x00000000,
0x00000000, 0x03F00000, 0x00000000, 0x00000000,
0x00000000, 0x00000000, 0x00000000, 0x00000000,
0x00000000, 0x03F00000, 0x00000540, 0x00000000,
0x0002A000, 0x00000000, 0x00000000, 0x00000000,
0x00000000, 0x00000000, 0x00000000, 0x00000000,
0x00000000, 0x00000000, 0x00000000, 0x00000000,
0x00000000, 0x00000000, 0x00000000, 0x00000000,
@@ -216,10 +299,10 @@ static const u32 ice_ptypes_ipv6_ofos[] = {
* IPv6 other PTYPEs
*/
static const u32 ice_ptypes_ipv6_ofos_all[] = {
0x00000000, 0x00000000, 0x77000000, 0x10002000,
0x00000000, 0x000002AA, 0x00000000, 0x00000000,
0x00080F00, 0x03F00000, 0x7C1F0000, 0x00000206,
0x00000000, 0x00000000, 0x00000000, 0x00000000,
0x00000000, 0x00000000, 0x76000000, 0xFEFDE000,
0x0000077E, 0x000002AA, 0x00000000, 0x00000000,
0x00000000, 0x03F00000, 0x7C1F0540, 0x00000206,
0xC002A000, 0x000003FF, 0xBC000000, 0x0002FBEF,
0x00000000, 0x00000000, 0x00000000, 0x00000000,
0x00000000, 0x00000000, 0x00000000, 0x00000000,
0x00000000, 0x00000000, 0x00000000, 0x00000000,
@@ -231,7 +314,7 @@ static const u32 ice_ptypes_ipv6_il[] = {
0x00000000, 0x03B80770, 0x000001DC, 0x0EE00000,
0x00000770, 0x00000000, 0x00000000, 0x00000000,
0x00000000, 0x00000000, 0x7FE00000, 0x00000000,
0x00000000, 0x00000000, 0x00000000, 0x00000000,
0x3F000000, 0x000003F0, 0x02F02F00, 0x0002F02F,
0x00000000, 0x00000000, 0x00000000, 0x00000000,
0x00000000, 0x00000000, 0x00000000, 0x00000000,
0x00000000, 0x00000000, 0x00000000, 0x00000000,
@@ -304,8 +387,8 @@ static const u32 ice_ptypes_ipv6_il_no_l4[] = {
static const u32 ice_ptypes_udp_il[] = {
0x81000000, 0x20204040, 0x04000010, 0x80810102,
0x00000040, 0x00000000, 0x00000000, 0x00000000,
0x00000000, 0x00410000, 0x90842000, 0x00000007,
0x00000000, 0x00000000, 0x00000000, 0x00000000,
0x00000000, 0x00410000, 0x908427E0, 0x00000007,
0x0413F000, 0x00000041, 0x10410410, 0x00004104,
0x00000000, 0x00000000, 0x00000000, 0x00000000,
0x00000000, 0x00000000, 0x00000000, 0x00000000,
0x00000000, 0x00000000, 0x00000000, 0x00000000,
@@ -317,7 +400,7 @@ static const u32 ice_ptypes_tcp_il[] = {
0x04000000, 0x80810102, 0x10000040, 0x02040408,
0x00000102, 0x00000000, 0x00000000, 0x00000000,
0x00000000, 0x00820000, 0x21084000, 0x00000000,
0x00000000, 0x00000000, 0x00000000, 0x00000000,
0x08200000, 0x00000082, 0x20820820, 0x00008208,
0x00000000, 0x00000000, 0x00000000, 0x00000000,
0x00000000, 0x00000000, 0x00000000, 0x00000000,
0x00000000, 0x00000000, 0x00000000, 0x00000000,
@@ -329,7 +412,7 @@ static const u32 ice_ptypes_sctp_il[] = {
0x08000000, 0x01020204, 0x20000081, 0x04080810,
0x00000204, 0x00000000, 0x00000000, 0x00000000,
0x00000000, 0x01040000, 0x00000000, 0x00000000,
0x00000000, 0x00000000, 0x00000000, 0x00000000,
0x10400000, 0x00000104, 0x00000000, 0x00000000,
0x00000000, 0x00000000, 0x00000000, 0x00000000,
0x00000000, 0x00000000, 0x00000000, 0x00000000,
0x00000000, 0x00000000, 0x00000000, 0x00000000,
@@ -353,7 +436,7 @@ static const u32 ice_ptypes_icmp_il[] = {
0x00000000, 0x02040408, 0x40000102, 0x08101020,
0x00000408, 0x00000000, 0x00000000, 0x00000000,
0x00000000, 0x00000000, 0x42108000, 0x00000000,
0x00000000, 0x00000000, 0x00000000, 0x00000000,
0x20800000, 0x00000208, 0x00000000, 0x00000000,
0x00000000, 0x00000000, 0x00000000, 0x00000000,
0x00000000, 0x00000000, 0x00000000, 0x00000000,
0x00000000, 0x00000000, 0x00000000, 0x00000000,
@@ -365,7 +448,7 @@ static const u32 ice_ptypes_gre_of[] = {
0x00000000, 0xBFBF7800, 0x000001DF, 0xFEFDE000,
0x0000017E, 0x00000000, 0x00000000, 0x00000000,
0x00000000, 0x00000000, 0x00000000, 0x00000000,
0x00000000, 0x00000000, 0x00000000, 0x00000000,
0x00000000, 0x00000000, 0xBEFBEFBC, 0x0002FBEF,
0x00000000, 0x00000000, 0x00000000, 0x00000000,
0x00000000, 0x00000000, 0x00000000, 0x00000000,
0x00000000, 0x00000000, 0x00000000, 0x00000000,
@@ -374,7 +457,7 @@ static const u32 ice_ptypes_gre_of[] = {
/* Packet types for packets with an Innermost/Last MAC header */
static const u32 ice_ptypes_mac_il[] = {
0x00000000, 0x00000000, 0x00000000, 0x00000000,
0x00000000, 0x20000000, 0x00000000, 0x00000000,
0x00000000, 0x00000000, 0x00000000, 0x00000000,
0x00000000, 0x00000000, 0x00000000, 0x00000000,
0x00000000, 0x00000000, 0x00000000, 0x00000000,
@@ -388,7 +471,7 @@ static const u32 ice_ptypes_mac_il[] = {
static const u32 ice_ptypes_gtpc[] = {
0x00000000, 0x00000000, 0x00000000, 0x00000000,
0x00000000, 0x00000000, 0x00000000, 0x00000000,
0x00000000, 0x00000000, 0x00000180, 0x00000000,
0x00000000, 0x00000000, 0x000001E0, 0x00000000,
0x00000000, 0x00000000, 0x00000000, 0x00000000,
0x00000000, 0x00000000, 0x00000000, 0x00000000,
0x00000000, 0x00000000, 0x00000000, 0x00000000,
@@ -2324,6 +2407,130 @@ static void ice_rss_set_symm(struct ice_hw *hw, struct ice_flow_prof *prof)
}
}
/**
* ice_rss_cfg_raw_symm - Configure symmetric RSS for a raw parser profile
* @hw: device HW
* @prof: parser profile describing extracted FV (field vector) entries
* @prof_id: RSS profile identifier used to program symmetry registers
*
* The routine scans the parser profile's FV entries and looks for
* direction-sensitive pairs (L3 src/dst, L4 src/dst). When a pair is found,
* it programs XOR-based symmetry so that flows hash identically regardless
* of packet direction. This preserves CPU affinity for the same 5-tuple.
*
* Notes:
* - The size of each logical field (IPv4/IPv6 address, L4 port) is expressed
* in units of ICE_FLOW_FV_EXTRACT_SZ so we can step across fv[] correctly.
* - We guard against out-of-bounds access before looking at fv[i + len].
*/
static void ice_rss_cfg_raw_symm(struct ice_hw *hw,
const struct ice_parser_profile *prof,
u64 prof_id)
{
for (size_t i = 0; i < prof->fv_num; i++) {
u8 proto_id = prof->fv[i].proto_id;
u16 src_off = 0, dst_off = 0;
size_t src_idx, dst_idx;
bool is_matched = false;
unsigned int len = 0;
switch (proto_id) {
/* IPv4 address pairs (outer/inner variants) */
case ICE_PROT_IPV4_OF_OR_S:
case ICE_PROT_IPV4_IL:
case ICE_PROT_IPV4_IL_IL:
len = ICE_FLOW_FLD_SZ_IPV4_ADDR /
ICE_FLOW_FV_EXTRACT_SZ;
src_off = ICE_FLOW_FIELD_IPV4_SRC_OFFSET;
dst_off = ICE_FLOW_FIELD_IPV4_DST_OFFSET;
break;
/* IPv6 address pairs (outer/inner variants) */
case ICE_PROT_IPV6_OF_OR_S:
case ICE_PROT_IPV6_IL:
case ICE_PROT_IPV6_IL_IL:
len = ICE_FLOW_FLD_SZ_IPV6_ADDR /
ICE_FLOW_FV_EXTRACT_SZ;
src_off = ICE_FLOW_FIELD_IPV6_SRC_OFFSET;
dst_off = ICE_FLOW_FIELD_IPV6_DST_OFFSET;
break;
/* L4 port pairs (TCP/UDP/SCTP) */
case ICE_PROT_TCP_IL:
case ICE_PROT_UDP_IL_OR_S:
case ICE_PROT_SCTP_IL:
len = ICE_FLOW_FLD_SZ_PORT / ICE_FLOW_FV_EXTRACT_SZ;
src_off = ICE_FLOW_FIELD_SRC_PORT_OFFSET;
dst_off = ICE_FLOW_FIELD_DST_PORT_OFFSET;
break;
default:
continue;
}
/* Bounds check before accessing fv[i + len]. */
if (i + len >= prof->fv_num)
continue;
/* Verify src/dst pairing for this protocol id. */
is_matched = prof->fv[i].offset == src_off &&
prof->fv[i + len].proto_id == proto_id &&
prof->fv[i + len].offset == dst_off;
if (!is_matched)
continue;
/* Program XOR symmetry for this field pair. */
src_idx = i;
dst_idx = i + len;
ice_rss_config_xor(hw, prof_id, src_idx, dst_idx, len);
/* Skip over the pair we just handled; the loop's ++i advances
* one more element, hence the --i after the jump.
*/
i += (2 * len);
/* not strictly needed; keeps static analyzers happy */
if (i == 0)
break;
--i;
}
}
/* Max registers index per packet profile */
#define ICE_SYMM_REG_INDEX_MAX 6
/**
* ice_rss_update_raw_symm - update symmetric hash configuration
* for raw pattern
* @hw: pointer to the hardware structure
* @cfg: configure parameters for raw pattern
* @id: profile tracking ID
*
* Update symmetric hash configuration for raw pattern if required.
* Otherwise only clear to default.
*/
void
ice_rss_update_raw_symm(struct ice_hw *hw,
struct ice_rss_raw_cfg *cfg, u64 id)
{
struct ice_prof_map *map;
u8 prof_id, m;
mutex_lock(&hw->blk[ICE_BLK_RSS].es.prof_map_lock);
map = ice_search_prof_id(hw, ICE_BLK_RSS, id);
if (map)
prof_id = map->prof_id;
mutex_unlock(&hw->blk[ICE_BLK_RSS].es.prof_map_lock);
if (!map)
return;
/* clear to default */
for (m = 0; m < ICE_SYMM_REG_INDEX_MAX; m++)
wr32(hw, GLQF_HSYMM(prof_id, m), 0);
if (cfg->symm)
ice_rss_cfg_raw_symm(hw, &cfg->prof, prof_id);
}
/**
* ice_add_rss_cfg_sync - add an RSS configuration
* @hw: pointer to the hardware structure
+90 -4
View File
@@ -22,6 +22,15 @@
#define ICE_FLOW_HASH_IPV6 \
(BIT_ULL(ICE_FLOW_FIELD_IDX_IPV6_SA) | \
BIT_ULL(ICE_FLOW_FIELD_IDX_IPV6_DA))
#define ICE_FLOW_HASH_IPV6_PRE32 \
(BIT_ULL(ICE_FLOW_FIELD_IDX_IPV6_PRE32_SA) | \
BIT_ULL(ICE_FLOW_FIELD_IDX_IPV6_PRE32_DA))
#define ICE_FLOW_HASH_IPV6_PRE48 \
(BIT_ULL(ICE_FLOW_FIELD_IDX_IPV6_PRE48_SA) | \
BIT_ULL(ICE_FLOW_FIELD_IDX_IPV6_PRE48_DA))
#define ICE_FLOW_HASH_IPV6_PRE64 \
(BIT_ULL(ICE_FLOW_FIELD_IDX_IPV6_PRE64_SA) | \
BIT_ULL(ICE_FLOW_FIELD_IDX_IPV6_PRE64_DA))
#define ICE_FLOW_HASH_TCP_PORT \
(BIT_ULL(ICE_FLOW_FIELD_IDX_TCP_SRC_PORT) | \
BIT_ULL(ICE_FLOW_FIELD_IDX_TCP_DST_PORT))
@@ -40,6 +49,33 @@
#define ICE_HASH_SCTP_IPV4 (ICE_FLOW_HASH_IPV4 | ICE_FLOW_HASH_SCTP_PORT)
#define ICE_HASH_SCTP_IPV6 (ICE_FLOW_HASH_IPV6 | ICE_FLOW_HASH_SCTP_PORT)
#define ICE_HASH_TCP_IPV6_PRE32 \
(ICE_FLOW_HASH_IPV6_PRE32 | ICE_FLOW_HASH_TCP_PORT)
#define ICE_HASH_UDP_IPV6_PRE32 \
(ICE_FLOW_HASH_IPV6_PRE32 | ICE_FLOW_HASH_UDP_PORT)
#define ICE_HASH_SCTP_IPV6_PRE32 \
(ICE_FLOW_HASH_IPV6_PRE32 | ICE_FLOW_HASH_SCTP_PORT)
#define ICE_HASH_TCP_IPV6_PRE48 \
(ICE_FLOW_HASH_IPV6_PRE48 | ICE_FLOW_HASH_TCP_PORT)
#define ICE_HASH_UDP_IPV6_PRE48 \
(ICE_FLOW_HASH_IPV6_PRE48 | ICE_FLOW_HASH_UDP_PORT)
#define ICE_HASH_SCTP_IPV6_PRE48 \
(ICE_FLOW_HASH_IPV6_PRE48 | ICE_FLOW_HASH_SCTP_PORT)
#define ICE_HASH_TCP_IPV6_PRE64 \
(ICE_FLOW_HASH_IPV6_PRE64 | ICE_FLOW_HASH_TCP_PORT)
#define ICE_HASH_UDP_IPV6_PRE64 \
(ICE_FLOW_HASH_IPV6_PRE64 | ICE_FLOW_HASH_UDP_PORT)
#define ICE_HASH_SCTP_IPV6_PRE64 \
(ICE_FLOW_HASH_IPV6_PRE64 | ICE_FLOW_HASH_SCTP_PORT)
#define ICE_FLOW_HASH_GTP_TEID \
(BIT_ULL(ICE_FLOW_FIELD_IDX_GTPC_TEID))
#define ICE_FLOW_HASH_GTP_IPV4_TEID \
(ICE_FLOW_HASH_IPV4 | ICE_FLOW_HASH_GTP_TEID)
#define ICE_FLOW_HASH_GTP_IPV6_TEID \
(ICE_FLOW_HASH_IPV6 | ICE_FLOW_HASH_GTP_TEID)
#define ICE_FLOW_HASH_GTP_C_TEID \
(BIT_ULL(ICE_FLOW_FIELD_IDX_GTPC_TEID))
@@ -128,6 +164,23 @@
#define ICE_FLOW_HASH_NAT_T_ESP_IPV6_SPI \
(ICE_FLOW_HASH_IPV6 | ICE_FLOW_HASH_NAT_T_ESP_SPI)
#define ICE_FLOW_HASH_L2TPV2_SESS_ID \
(BIT_ULL(ICE_FLOW_FIELD_IDX_L2TPV2_SESS_ID))
#define ICE_FLOW_HASH_L2TPV2_SESS_ID_ETH \
(ICE_FLOW_HASH_ETH | ICE_FLOW_HASH_L2TPV2_SESS_ID)
#define ICE_FLOW_HASH_L2TPV2_LEN_SESS_ID \
(BIT_ULL(ICE_FLOW_FIELD_IDX_L2TPV2_LEN_SESS_ID))
#define ICE_FLOW_HASH_L2TPV2_LEN_SESS_ID_ETH \
(ICE_FLOW_HASH_ETH | ICE_FLOW_HASH_L2TPV2_LEN_SESS_ID)
#define ICE_FLOW_FIELD_IPV4_SRC_OFFSET 12
#define ICE_FLOW_FIELD_IPV4_DST_OFFSET 16
#define ICE_FLOW_FIELD_IPV6_SRC_OFFSET 8
#define ICE_FLOW_FIELD_IPV6_DST_OFFSET 24
#define ICE_FLOW_FIELD_SRC_PORT_OFFSET 0
#define ICE_FLOW_FIELD_DST_PORT_OFFSET 2
/* Protocol header fields 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
@@ -160,10 +213,13 @@ enum ice_flow_seg_hdr {
ICE_FLOW_SEG_HDR_AH = 0x00200000,
ICE_FLOW_SEG_HDR_NAT_T_ESP = 0x00400000,
ICE_FLOW_SEG_HDR_ETH_NON_IP = 0x00800000,
ICE_FLOW_SEG_HDR_GTPU_NON_IP = 0x01000000,
ICE_FLOW_SEG_HDR_L2TPV2 = 0x10000000,
/* The following is an additive bit for ICE_FLOW_SEG_HDR_IPV4 and
* ICE_FLOW_SEG_HDR_IPV6 which include the IPV4 other PTYPEs
* ICE_FLOW_SEG_HDR_IPV6.
*/
ICE_FLOW_SEG_HDR_IPV_OTHER = 0x20000000,
ICE_FLOW_SEG_HDR_IPV_FRAG = 0x40000000,
ICE_FLOW_SEG_HDR_IPV_OTHER = 0x80000000,
};
/* These segments all have the same PTYPES, but are otherwise distinguished by
@@ -200,6 +256,15 @@ enum ice_flow_field {
ICE_FLOW_FIELD_IDX_IPV4_DA,
ICE_FLOW_FIELD_IDX_IPV6_SA,
ICE_FLOW_FIELD_IDX_IPV6_DA,
ICE_FLOW_FIELD_IDX_IPV4_CHKSUM,
ICE_FLOW_FIELD_IDX_IPV4_ID,
ICE_FLOW_FIELD_IDX_IPV6_ID,
ICE_FLOW_FIELD_IDX_IPV6_PRE32_SA,
ICE_FLOW_FIELD_IDX_IPV6_PRE32_DA,
ICE_FLOW_FIELD_IDX_IPV6_PRE48_SA,
ICE_FLOW_FIELD_IDX_IPV6_PRE48_DA,
ICE_FLOW_FIELD_IDX_IPV6_PRE64_SA,
ICE_FLOW_FIELD_IDX_IPV6_PRE64_DA,
/* L4 */
ICE_FLOW_FIELD_IDX_TCP_SRC_PORT,
ICE_FLOW_FIELD_IDX_TCP_DST_PORT,
@@ -208,6 +273,9 @@ enum ice_flow_field {
ICE_FLOW_FIELD_IDX_SCTP_SRC_PORT,
ICE_FLOW_FIELD_IDX_SCTP_DST_PORT,
ICE_FLOW_FIELD_IDX_TCP_FLAGS,
ICE_FLOW_FIELD_IDX_TCP_CHKSUM,
ICE_FLOW_FIELD_IDX_UDP_CHKSUM,
ICE_FLOW_FIELD_IDX_SCTP_CHKSUM,
/* ARP */
ICE_FLOW_FIELD_IDX_ARP_SIP,
ICE_FLOW_FIELD_IDX_ARP_DIP,
@@ -228,13 +296,13 @@ enum ice_flow_field {
ICE_FLOW_FIELD_IDX_GTPU_EH_QFI,
/* GTPU_UP */
ICE_FLOW_FIELD_IDX_GTPU_UP_TEID,
ICE_FLOW_FIELD_IDX_GTPU_UP_QFI,
/* GTPU_DWN */
ICE_FLOW_FIELD_IDX_GTPU_DWN_TEID,
/* PPPoE */
ICE_FLOW_FIELD_IDX_GTPU_DWN_QFI,
ICE_FLOW_FIELD_IDX_PPPOE_SESS_ID,
/* PFCP */
ICE_FLOW_FIELD_IDX_PFCP_SEID,
/* L2TPv3 */
ICE_FLOW_FIELD_IDX_L2TPV3_SESS_ID,
/* ESP */
ICE_FLOW_FIELD_IDX_ESP_SPI,
@@ -242,10 +310,16 @@ enum ice_flow_field {
ICE_FLOW_FIELD_IDX_AH_SPI,
/* NAT_T ESP */
ICE_FLOW_FIELD_IDX_NAT_T_ESP_SPI,
/* L2TPV2 SESSION ID*/
ICE_FLOW_FIELD_IDX_L2TPV2_SESS_ID,
/* L2TPV2_LEN SESSION ID */
ICE_FLOW_FIELD_IDX_L2TPV2_LEN_SESS_ID,
/* The total number of enums must not exceed 64 */
ICE_FLOW_FIELD_IDX_MAX
};
static_assert(ICE_FLOW_FIELD_IDX_MAX <= 64, "The total number of enums must not exceed 64");
#define ICE_FLOW_HASH_FLD_IPV4_SA BIT_ULL(ICE_FLOW_FIELD_IDX_IPV4_SA)
#define ICE_FLOW_HASH_FLD_IPV6_SA BIT_ULL(ICE_FLOW_FIELD_IDX_IPV6_SA)
#define ICE_FLOW_HASH_FLD_IPV4_DA BIT_ULL(ICE_FLOW_FIELD_IDX_IPV4_DA)
@@ -296,6 +370,10 @@ enum ice_rss_cfg_hdr_type {
/* take inner headers as inputset for packet with outer ipv6. */
ICE_RSS_INNER_HEADERS_W_OUTER_IPV6,
/* take outer headers first then inner headers as inputset */
/* take inner as inputset for GTPoGRE with outer IPv4 + GRE. */
ICE_RSS_INNER_HEADERS_W_OUTER_IPV4_GRE,
/* take inner as inputset for GTPoGRE with outer IPv6 + GRE. */
ICE_RSS_INNER_HEADERS_W_OUTER_IPV6_GRE,
ICE_RSS_ANY_HEADERS
};
@@ -406,6 +484,12 @@ struct ice_flow_prof {
bool symm; /* Symmetric Hash for RSS */
};
struct ice_rss_raw_cfg {
struct ice_parser_profile prof;
bool raw_ena;
bool symm;
};
struct ice_rss_cfg {
struct list_head l_entry;
/* bitmap of VSIs added to the RSS entry */
@@ -444,4 +528,6 @@ int ice_add_rss_cfg(struct ice_hw *hw, struct ice_vsi *vsi,
int ice_rem_rss_cfg(struct ice_hw *hw, u16 vsi_handle,
const struct ice_rss_hash_cfg *cfg);
u64 ice_get_rss_cfg(struct ice_hw *hw, u16 vsi_handle, u32 hdrs, bool *symm);
void ice_rss_update_raw_symm(struct ice_hw *hw,
struct ice_rss_raw_cfg *cfg, u64 id);
#endif /* _ICE_FLOW_H_ */
@@ -82,26 +82,46 @@ enum ice_sw_tunnel_type {
enum ice_prot_id {
ICE_PROT_ID_INVAL = 0,
ICE_PROT_MAC_OF_OR_S = 1,
ICE_PROT_MAC_O2 = 2,
ICE_PROT_MAC_IL = 4,
ICE_PROT_MAC_IN_MAC = 7,
ICE_PROT_ETYPE_OL = 9,
ICE_PROT_ETYPE_IL = 10,
ICE_PROT_PAY = 15,
ICE_PROT_EVLAN_O = 16,
ICE_PROT_VLAN_O = 17,
ICE_PROT_VLAN_IF = 18,
ICE_PROT_MPLS_OL_MINUS_1 = 27,
ICE_PROT_MPLS_OL_OR_OS = 28,
ICE_PROT_MPLS_IL = 29,
ICE_PROT_IPV4_OF_OR_S = 32,
ICE_PROT_IPV4_IL = 33,
ICE_PROT_IPV4_IL_IL = 34,
ICE_PROT_IPV6_OF_OR_S = 40,
ICE_PROT_IPV6_IL = 41,
ICE_PROT_IPV6_IL_IL = 42,
ICE_PROT_IPV6_NEXT_PROTO = 43,
ICE_PROT_IPV6_FRAG = 47,
ICE_PROT_TCP_IL = 49,
ICE_PROT_UDP_OF = 52,
ICE_PROT_UDP_IL_OR_S = 53,
ICE_PROT_GRE_OF = 64,
ICE_PROT_NSH_F = 84,
ICE_PROT_ESP_F = 88,
ICE_PROT_ESP_2 = 89,
ICE_PROT_SCTP_IL = 96,
ICE_PROT_ICMP_IL = 98,
ICE_PROT_ICMPV6_IL = 100,
ICE_PROT_VRRP_F = 101,
ICE_PROT_OSPF = 102,
ICE_PROT_PPPOE = 103,
ICE_PROT_L2TPV3 = 104,
ICE_PROT_ATAOE_OF = 114,
ICE_PROT_CTRL_OF = 116,
ICE_PROT_LLDP_OF = 117,
ICE_PROT_ARP_OF = 118,
ICE_PROT_META_ID = 255, /* when offset == metadata */
ICE_PROT_EAPOL_OF = 120,
ICE_PROT_INVALID = 255 /* when offset == ICE_FV_OFFSET_INVAL */
};
@@ -53,6 +53,46 @@ struct ice_mdd_vf_events {
u16 last_printed;
};
enum ice_hash_ip_ctx_type {
ICE_HASH_IP_CTX_IP = 0,
ICE_HASH_IP_CTX_IP_ESP,
ICE_HASH_IP_CTX_IP_UDP_ESP,
ICE_HASH_IP_CTX_IP_AH,
ICE_HASH_IP_CTX_IP_PFCP,
ICE_HASH_IP_CTX_IP_UDP,
ICE_HASH_IP_CTX_IP_TCP,
ICE_HASH_IP_CTX_IP_SCTP,
ICE_HASH_IP_CTX_MAX,
};
struct ice_vf_hash_ip_ctx {
struct ice_rss_hash_cfg ctx[ICE_HASH_IP_CTX_MAX];
};
enum ice_hash_gtpu_ctx_type {
ICE_HASH_GTPU_CTX_EH_IP = 0,
ICE_HASH_GTPU_CTX_EH_IP_UDP,
ICE_HASH_GTPU_CTX_EH_IP_TCP,
ICE_HASH_GTPU_CTX_UP_IP,
ICE_HASH_GTPU_CTX_UP_IP_UDP,
ICE_HASH_GTPU_CTX_UP_IP_TCP,
ICE_HASH_GTPU_CTX_DW_IP,
ICE_HASH_GTPU_CTX_DW_IP_UDP,
ICE_HASH_GTPU_CTX_DW_IP_TCP,
ICE_HASH_GTPU_CTX_MAX,
};
struct ice_vf_hash_gtpu_ctx {
struct ice_rss_hash_cfg ctx[ICE_HASH_GTPU_CTX_MAX];
};
struct ice_vf_hash_ctx {
struct ice_vf_hash_ip_ctx v4;
struct ice_vf_hash_ip_ctx v6;
struct ice_vf_hash_gtpu_ctx ipv4;
struct ice_vf_hash_gtpu_ctx ipv6;
};
/* Structure to store fdir fv entry */
struct ice_fdir_prof_info {
struct ice_parser_profile prof;
@@ -66,6 +106,12 @@ struct ice_vf_qs_bw {
u8 tc;
};
/* Structure to store RSS field vector entry */
struct ice_rss_prof_info {
struct ice_parser_profile prof;
bool symm;
};
/* VF operations */
struct ice_vf_ops {
enum ice_disq_rst_src reset_type;
@@ -106,6 +152,8 @@ struct ice_vf {
u16 ctrl_vsi_idx;
struct ice_vf_fdir fdir;
struct ice_fdir_prof_info fdir_prof_info[ICE_MAX_PTGS];
struct ice_rss_prof_info rss_prof_info[ICE_MAX_PTGS];
struct ice_vf_hash_ctx hash_ctx;
u64 rss_hashcfg; /* RSS hash configuration */
struct ice_sw *vf_sw_id; /* switch ID the VF VSIs connect to */
struct virtchnl_version_info vf_ver;
File diff suppressed because it is too large Load Diff
+50
View File
@@ -1253,6 +1253,17 @@ enum virtchnl_proto_hdr_type {
VIRTCHNL_PROTO_HDR_ESP,
VIRTCHNL_PROTO_HDR_AH,
VIRTCHNL_PROTO_HDR_PFCP,
VIRTCHNL_PROTO_HDR_GTPC,
VIRTCHNL_PROTO_HDR_ECPRI,
VIRTCHNL_PROTO_HDR_L2TPV2,
VIRTCHNL_PROTO_HDR_PPP,
/* IPv4 and IPv6 Fragment header types are only associated to
* VIRTCHNL_PROTO_HDR_IPV4 and VIRTCHNL_PROTO_HDR_IPV6 respectively,
* cannot be used independently.
*/
VIRTCHNL_PROTO_HDR_IPV4_FRAG,
VIRTCHNL_PROTO_HDR_IPV6_EH_FRAG,
VIRTCHNL_PROTO_HDR_GRE,
};
/* Protocol header field within a protocol header. */
@@ -1275,6 +1286,7 @@ enum virtchnl_proto_hdr_field {
VIRTCHNL_PROTO_HDR_IPV4_DSCP,
VIRTCHNL_PROTO_HDR_IPV4_TTL,
VIRTCHNL_PROTO_HDR_IPV4_PROT,
VIRTCHNL_PROTO_HDR_IPV4_CHKSUM,
/* IPV6 */
VIRTCHNL_PROTO_HDR_IPV6_SRC =
PROTO_HDR_FIELD_START(VIRTCHNL_PROTO_HDR_IPV6),
@@ -1282,18 +1294,34 @@ enum virtchnl_proto_hdr_field {
VIRTCHNL_PROTO_HDR_IPV6_TC,
VIRTCHNL_PROTO_HDR_IPV6_HOP_LIMIT,
VIRTCHNL_PROTO_HDR_IPV6_PROT,
/* IPV6 Prefix */
VIRTCHNL_PROTO_HDR_IPV6_PREFIX32_SRC,
VIRTCHNL_PROTO_HDR_IPV6_PREFIX32_DST,
VIRTCHNL_PROTO_HDR_IPV6_PREFIX40_SRC,
VIRTCHNL_PROTO_HDR_IPV6_PREFIX40_DST,
VIRTCHNL_PROTO_HDR_IPV6_PREFIX48_SRC,
VIRTCHNL_PROTO_HDR_IPV6_PREFIX48_DST,
VIRTCHNL_PROTO_HDR_IPV6_PREFIX56_SRC,
VIRTCHNL_PROTO_HDR_IPV6_PREFIX56_DST,
VIRTCHNL_PROTO_HDR_IPV6_PREFIX64_SRC,
VIRTCHNL_PROTO_HDR_IPV6_PREFIX64_DST,
VIRTCHNL_PROTO_HDR_IPV6_PREFIX96_SRC,
VIRTCHNL_PROTO_HDR_IPV6_PREFIX96_DST,
/* TCP */
VIRTCHNL_PROTO_HDR_TCP_SRC_PORT =
PROTO_HDR_FIELD_START(VIRTCHNL_PROTO_HDR_TCP),
VIRTCHNL_PROTO_HDR_TCP_DST_PORT,
VIRTCHNL_PROTO_HDR_TCP_CHKSUM,
/* UDP */
VIRTCHNL_PROTO_HDR_UDP_SRC_PORT =
PROTO_HDR_FIELD_START(VIRTCHNL_PROTO_HDR_UDP),
VIRTCHNL_PROTO_HDR_UDP_DST_PORT,
VIRTCHNL_PROTO_HDR_UDP_CHKSUM,
/* SCTP */
VIRTCHNL_PROTO_HDR_SCTP_SRC_PORT =
PROTO_HDR_FIELD_START(VIRTCHNL_PROTO_HDR_SCTP),
VIRTCHNL_PROTO_HDR_SCTP_DST_PORT,
VIRTCHNL_PROTO_HDR_SCTP_CHKSUM,
/* GTPU_IP */
VIRTCHNL_PROTO_HDR_GTPU_IP_TEID =
PROTO_HDR_FIELD_START(VIRTCHNL_PROTO_HDR_GTPU_IP),
@@ -1317,6 +1345,28 @@ enum virtchnl_proto_hdr_field {
VIRTCHNL_PROTO_HDR_PFCP_S_FIELD =
PROTO_HDR_FIELD_START(VIRTCHNL_PROTO_HDR_PFCP),
VIRTCHNL_PROTO_HDR_PFCP_SEID,
/* GTPC */
VIRTCHNL_PROTO_HDR_GTPC_TEID =
PROTO_HDR_FIELD_START(VIRTCHNL_PROTO_HDR_GTPC),
/* ECPRI */
VIRTCHNL_PROTO_HDR_ECPRI_MSG_TYPE =
PROTO_HDR_FIELD_START(VIRTCHNL_PROTO_HDR_ECPRI),
VIRTCHNL_PROTO_HDR_ECPRI_PC_RTC_ID,
/* IPv4 Dummy Fragment */
VIRTCHNL_PROTO_HDR_IPV4_FRAG_PKID =
PROTO_HDR_FIELD_START(VIRTCHNL_PROTO_HDR_IPV4_FRAG),
/* IPv6 Extension Fragment */
VIRTCHNL_PROTO_HDR_IPV6_EH_FRAG_PKID =
PROTO_HDR_FIELD_START(VIRTCHNL_PROTO_HDR_IPV6_EH_FRAG),
/* GTPU_DWN/UP */
VIRTCHNL_PROTO_HDR_GTPU_DWN_QFI =
PROTO_HDR_FIELD_START(VIRTCHNL_PROTO_HDR_GTPU_EH_PDU_DWN),
VIRTCHNL_PROTO_HDR_GTPU_UP_QFI =
PROTO_HDR_FIELD_START(VIRTCHNL_PROTO_HDR_GTPU_EH_PDU_UP),
/* L2TPv2 */
VIRTCHNL_PROTO_HDR_L2TPV2_SESS_ID =
PROTO_HDR_FIELD_START(VIRTCHNL_PROTO_HDR_L2TPV2),
VIRTCHNL_PROTO_HDR_L2TPV2_LEN_SESS_ID,
};
struct virtchnl_proto_hdr {
+4
View File
@@ -532,6 +532,7 @@ enum devlink_param_generic_id {
DEVLINK_PARAM_GENERIC_ID_CLOCK_ID,
DEVLINK_PARAM_GENERIC_ID_TOTAL_VFS,
DEVLINK_PARAM_GENERIC_ID_NUM_DOORBELLS,
DEVLINK_PARAM_GENERIC_ID_MAX_MAC_PER_VF,
/* add new param generic ids above here*/
__DEVLINK_PARAM_GENERIC_ID_MAX,
@@ -602,6 +603,9 @@ enum devlink_param_generic_id {
#define DEVLINK_PARAM_GENERIC_NUM_DOORBELLS_NAME "num_doorbells"
#define DEVLINK_PARAM_GENERIC_NUM_DOORBELLS_TYPE DEVLINK_PARAM_TYPE_U32
#define DEVLINK_PARAM_GENERIC_MAX_MAC_PER_VF_NAME "max_mac_per_vf"
#define DEVLINK_PARAM_GENERIC_MAX_MAC_PER_VF_TYPE DEVLINK_PARAM_TYPE_U32
#define DEVLINK_PARAM_GENERIC(_id, _cmodes, _get, _set, _validate) \
{ \
.id = DEVLINK_PARAM_GENERIC_ID_##_id, \
+5
View File
@@ -112,6 +112,11 @@ static const struct devlink_param devlink_param_generic[] = {
.name = DEVLINK_PARAM_GENERIC_NUM_DOORBELLS_NAME,
.type = DEVLINK_PARAM_GENERIC_NUM_DOORBELLS_TYPE,
},
{
.id = DEVLINK_PARAM_GENERIC_ID_MAX_MAC_PER_VF,
.name = DEVLINK_PARAM_GENERIC_MAX_MAC_PER_VF_NAME,
.type = DEVLINK_PARAM_GENERIC_MAX_MAC_PER_VF_TYPE,
},
};
static int devlink_param_generic_verify(const struct devlink_param *param)