net/ice: support protocol extraction per Rx queue
The ice has the feature to extract protocol fields into flex descriptor by programming per queue. Currently, the ice PMD will put the protocol fields into rte_mbuf::udata64 with different type format. Application can access the protocol fields quickly. Signed-off-by: Haiyue Wang <haiyue.wang@intel.com> Reviewed-by: Xiaolong Ye <xiaolong.ye@intel.com> Acked-by: Qi Zhang <qi.z.zhang@intel.com>
This commit is contained in:
parent
dbf3c0e77a
commit
7e124ff12c
@ -61,6 +61,107 @@ Runtime Config Options
|
||||
NOTE: In Safe mode, only very limited features are available, features like RSS,
|
||||
checksum, fdir, tunneling ... are all disabled.
|
||||
|
||||
- ``Protocol extraction for per queue``
|
||||
|
||||
Configure the RX queues to do protocol extraction into ``rte_mbuf::udata64``
|
||||
for protocol handling acceleration, like checking the TCP SYN packets quickly.
|
||||
|
||||
The argument format is::
|
||||
|
||||
-w 18:00.0,proto_xtr=<queues:protocol>[<queues:protocol>...]
|
||||
-w 18:00.0,proto_xtr=<protocol>
|
||||
|
||||
Queues are grouped by ``(`` and ``)`` within the group. The ``-`` character
|
||||
is used as a range separator and ``,`` is used as a single number separator.
|
||||
The grouping ``()`` can be omitted for single element group. If no queues are
|
||||
specified, PMD will use this protocol extraction type for all queues.
|
||||
|
||||
Protocol is : ``vlan, ipv4, ipv6, ipv6_flow, tcp``.
|
||||
|
||||
.. code-block:: console
|
||||
|
||||
testpmd -w 18:00.0,proto_xtr='[(1,2-3,8-9):tcp,10-13:vlan]'
|
||||
|
||||
This setting means queues 1, 2-3, 8-9 are TCP extraction, queues 10-13 are
|
||||
VLAN extraction, other queues run with no protocol extraction.
|
||||
|
||||
.. code-block:: console
|
||||
|
||||
testpmd -w 18:00.0,proto_xtr=vlan,proto_xtr='[(1,2-3,8-9):tcp,10-23:ipv6]'
|
||||
|
||||
This setting means queues 1, 2-3, 8-9 are TCP extraction, queues 10-23 are
|
||||
IPv6 extraction, other queues use the default VLAN extraction.
|
||||
|
||||
The extraction will be copied into the lower 32 bit of ``rte_mbuf::udata64``.
|
||||
|
||||
.. table:: Protocol extraction : ``vlan``
|
||||
|
||||
+----------------------------+----------------------------+
|
||||
| VLAN2 | VLAN1 |
|
||||
+======+===+=================+======+===+=================+
|
||||
| PCP | D | VID | PCP | D | VID |
|
||||
+------+---+-----------------+------+---+-----------------+
|
||||
|
||||
VLAN1 - single or EVLAN (first for QinQ).
|
||||
|
||||
VLAN2 - C-VLAN (second for QinQ).
|
||||
|
||||
.. table:: Protocol extraction : ``ipv4``
|
||||
|
||||
+----------------------------+----------------------------+
|
||||
| IPHDR2 | IPHDR1 |
|
||||
+======+=======+=============+==============+=============+
|
||||
| Ver |Hdr Len| ToS | TTL | Protocol |
|
||||
+------+-------+-------------+--------------+-------------+
|
||||
|
||||
IPHDR1 - IPv4 header word 4, "TTL" and "Protocol" fields.
|
||||
|
||||
IPHDR2 - IPv4 header word 0, "Ver", "Hdr Len" and "Type of Service" fields.
|
||||
|
||||
.. table:: Protocol extraction : ``ipv6``
|
||||
|
||||
+----------------------------+----------------------------+
|
||||
| IPHDR2 | IPHDR1 |
|
||||
+=====+=============+========+=============+==============+
|
||||
| Ver |Traffic class| Flow | Next Header | Hop Limit |
|
||||
+-----+-------------+--------+-------------+--------------+
|
||||
|
||||
IPHDR1 - IPv6 header word 3, "Next Header" and "Hop Limit" fields.
|
||||
|
||||
IPHDR2 - IPv6 header word 0, "Ver", "Traffic class" and high 4 bits of
|
||||
"Flow Label" fields.
|
||||
|
||||
.. table:: Protocol extraction : ``ipv6_flow``
|
||||
|
||||
+----------------------------+----------------------------+
|
||||
| IPHDR2 | IPHDR1 |
|
||||
+=====+=============+========+============================+
|
||||
| Ver |Traffic class| Flow Label |
|
||||
+-----+-------------+-------------------------------------+
|
||||
|
||||
IPHDR1 - IPv6 header word 1, 16 low bits of the "Flow Label" field.
|
||||
|
||||
IPHDR2 - IPv6 header word 0, "Ver", "Traffic class" and high 4 bits of
|
||||
"Flow Label" fields.
|
||||
|
||||
.. table:: Protocol extraction : ``tcp``
|
||||
|
||||
+----------------------------+----------------------------+
|
||||
| TCPHDR2 | TCPHDR1 |
|
||||
+============================+======+======+==============+
|
||||
| Reserved |Offset| RSV | Flags |
|
||||
+----------------------------+------+------+--------------+
|
||||
|
||||
TCPHDR1 - TCP header word 6, "Data Offset" and "Flags" fields.
|
||||
|
||||
TCPHDR2 - Reserved
|
||||
|
||||
Use ``get_proto_xtr_flds(struct rte_mbuf *mb)`` to access the protocol
|
||||
extraction, do not use ``rte_mbuf::udata64`` directly.
|
||||
|
||||
The ``dump_proto_xtr_flds(struct rte_mbuf *mb)`` routine shows how to
|
||||
access the protocol extraction result in ``struct rte_mbuf``.
|
||||
|
||||
Driver compilation and testing
|
||||
------------------------------
|
||||
|
||||
|
@ -61,6 +61,8 @@ New Features
|
||||
Updated the Intel ice driver with new features and improvements, including:
|
||||
|
||||
* Added support for device-specific DDP package loading.
|
||||
* Added support for handling Receive Flex Descriptor.
|
||||
* Added support for protocol extraction on per Rx queue.
|
||||
|
||||
* **Added Marvell NITROX symmetric crypto PMD.**
|
||||
|
||||
|
@ -82,4 +82,7 @@ ifeq ($(CC_AVX2_SUPPORT), 1)
|
||||
endif
|
||||
SRCS-$(CONFIG_RTE_LIBRTE_ICE_PMD) += ice_generic_flow.c
|
||||
|
||||
# install this header file
|
||||
SYMLINK-$(CONFIG_RTE_LIBRTE_ICE_PMD)-include := rte_pmd_ice.h
|
||||
|
||||
include $(RTE_SDK)/mk/rte.lib.mk
|
||||
|
@ -19,9 +19,11 @@
|
||||
|
||||
/* devargs */
|
||||
#define ICE_SAFE_MODE_SUPPORT_ARG "safe-mode-support"
|
||||
#define ICE_PROTO_XTR_ARG "proto_xtr"
|
||||
|
||||
static const char * const ice_valid_args[] = {
|
||||
ICE_SAFE_MODE_SUPPORT_ARG,
|
||||
ICE_PROTO_XTR_ARG,
|
||||
NULL
|
||||
};
|
||||
|
||||
@ -266,6 +268,280 @@ ice_init_controlq_parameter(struct ice_hw *hw)
|
||||
hw->mailboxq.sq_buf_size = ICE_MAILBOXQ_BUF_SZ;
|
||||
}
|
||||
|
||||
static int
|
||||
lookup_proto_xtr_type(const char *xtr_name)
|
||||
{
|
||||
static struct {
|
||||
const char *name;
|
||||
enum proto_xtr_type type;
|
||||
} xtr_type_map[] = {
|
||||
{ "vlan", PROTO_XTR_VLAN },
|
||||
{ "ipv4", PROTO_XTR_IPV4 },
|
||||
{ "ipv6", PROTO_XTR_IPV6 },
|
||||
{ "ipv6_flow", PROTO_XTR_IPV6_FLOW },
|
||||
{ "tcp", PROTO_XTR_TCP },
|
||||
};
|
||||
uint32_t i;
|
||||
|
||||
for (i = 0; i < RTE_DIM(xtr_type_map); i++) {
|
||||
if (strcmp(xtr_name, xtr_type_map[i].name) == 0)
|
||||
return xtr_type_map[i].type;
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
/*
|
||||
* Parse elem, the elem could be single number/range or '(' ')' group
|
||||
* 1) A single number elem, it's just a simple digit. e.g. 9
|
||||
* 2) A single range elem, two digits with a '-' between. e.g. 2-6
|
||||
* 3) A group elem, combines multiple 1) or 2) with '( )'. e.g (0,2-4,6)
|
||||
* Within group elem, '-' used for a range separator;
|
||||
* ',' used for a single number.
|
||||
*/
|
||||
static int
|
||||
parse_queue_set(const char *input, int xtr_type, struct ice_devargs *devargs)
|
||||
{
|
||||
const char *str = input;
|
||||
char *end = NULL;
|
||||
uint32_t min, max;
|
||||
uint32_t idx;
|
||||
|
||||
while (isblank(*str))
|
||||
str++;
|
||||
|
||||
if (!isdigit(*str) && *str != '(')
|
||||
return -1;
|
||||
|
||||
/* process single number or single range of number */
|
||||
if (*str != '(') {
|
||||
errno = 0;
|
||||
idx = strtoul(str, &end, 10);
|
||||
if (errno || end == NULL || idx >= ICE_MAX_QUEUE_NUM)
|
||||
return -1;
|
||||
|
||||
while (isblank(*end))
|
||||
end++;
|
||||
|
||||
min = idx;
|
||||
max = idx;
|
||||
|
||||
/* process single <number>-<number> */
|
||||
if (*end == '-') {
|
||||
end++;
|
||||
while (isblank(*end))
|
||||
end++;
|
||||
if (!isdigit(*end))
|
||||
return -1;
|
||||
|
||||
errno = 0;
|
||||
idx = strtoul(end, &end, 10);
|
||||
if (errno || end == NULL || idx >= ICE_MAX_QUEUE_NUM)
|
||||
return -1;
|
||||
|
||||
max = idx;
|
||||
while (isblank(*end))
|
||||
end++;
|
||||
}
|
||||
|
||||
if (*end != ':')
|
||||
return -1;
|
||||
|
||||
for (idx = RTE_MIN(min, max);
|
||||
idx <= RTE_MAX(min, max); idx++)
|
||||
devargs->proto_xtr[idx] = xtr_type;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* process set within bracket */
|
||||
str++;
|
||||
while (isblank(*str))
|
||||
str++;
|
||||
if (*str == '\0')
|
||||
return -1;
|
||||
|
||||
min = ICE_MAX_QUEUE_NUM;
|
||||
do {
|
||||
/* go ahead to the first digit */
|
||||
while (isblank(*str))
|
||||
str++;
|
||||
if (!isdigit(*str))
|
||||
return -1;
|
||||
|
||||
/* get the digit value */
|
||||
errno = 0;
|
||||
idx = strtoul(str, &end, 10);
|
||||
if (errno || end == NULL || idx >= ICE_MAX_QUEUE_NUM)
|
||||
return -1;
|
||||
|
||||
/* go ahead to separator '-',',' and ')' */
|
||||
while (isblank(*end))
|
||||
end++;
|
||||
if (*end == '-') {
|
||||
if (min == ICE_MAX_QUEUE_NUM)
|
||||
min = idx;
|
||||
else /* avoid continuous '-' */
|
||||
return -1;
|
||||
} else if (*end == ',' || *end == ')') {
|
||||
max = idx;
|
||||
if (min == ICE_MAX_QUEUE_NUM)
|
||||
min = idx;
|
||||
|
||||
for (idx = RTE_MIN(min, max);
|
||||
idx <= RTE_MAX(min, max); idx++)
|
||||
devargs->proto_xtr[idx] = xtr_type;
|
||||
|
||||
min = ICE_MAX_QUEUE_NUM;
|
||||
} else {
|
||||
return -1;
|
||||
}
|
||||
|
||||
str = end + 1;
|
||||
} while (*end != ')' && *end != '\0');
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
parse_queue_proto_xtr(const char *queues, struct ice_devargs *devargs)
|
||||
{
|
||||
const char *queue_start;
|
||||
uint32_t idx;
|
||||
int xtr_type;
|
||||
char xtr_name[32];
|
||||
|
||||
while (isblank(*queues))
|
||||
queues++;
|
||||
|
||||
if (*queues != '[') {
|
||||
xtr_type = lookup_proto_xtr_type(queues);
|
||||
if (xtr_type < 0)
|
||||
return -1;
|
||||
|
||||
memset(devargs->proto_xtr, xtr_type,
|
||||
sizeof(devargs->proto_xtr));
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
queues++;
|
||||
do {
|
||||
while (isblank(*queues))
|
||||
queues++;
|
||||
if (*queues == '\0')
|
||||
return -1;
|
||||
|
||||
queue_start = queues;
|
||||
|
||||
/* go across a complete bracket */
|
||||
if (*queue_start == '(') {
|
||||
queues += strcspn(queues, ")");
|
||||
if (*queues != ')')
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* scan the separator ':' */
|
||||
queues += strcspn(queues, ":");
|
||||
if (*queues++ != ':')
|
||||
return -1;
|
||||
while (isblank(*queues))
|
||||
queues++;
|
||||
|
||||
for (idx = 0; ; idx++) {
|
||||
if (isblank(queues[idx]) ||
|
||||
queues[idx] == ',' ||
|
||||
queues[idx] == ']' ||
|
||||
queues[idx] == '\0')
|
||||
break;
|
||||
|
||||
if (idx > sizeof(xtr_name) - 2)
|
||||
return -1;
|
||||
|
||||
xtr_name[idx] = queues[idx];
|
||||
}
|
||||
xtr_name[idx] = '\0';
|
||||
xtr_type = lookup_proto_xtr_type(xtr_name);
|
||||
if (xtr_type < 0)
|
||||
return -1;
|
||||
|
||||
queues += idx;
|
||||
|
||||
while (isblank(*queues) || *queues == ',' || *queues == ']')
|
||||
queues++;
|
||||
|
||||
if (parse_queue_set(queue_start, xtr_type, devargs) < 0)
|
||||
return -1;
|
||||
} while (*queues != '\0');
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
handle_proto_xtr_arg(__rte_unused const char *key, const char *value,
|
||||
void *extra_args)
|
||||
{
|
||||
struct ice_devargs *devargs = extra_args;
|
||||
|
||||
if (value == NULL || extra_args == NULL)
|
||||
return -EINVAL;
|
||||
|
||||
if (parse_queue_proto_xtr(value, devargs) < 0) {
|
||||
PMD_DRV_LOG(ERR,
|
||||
"The protocol extraction parameter is wrong : '%s'",
|
||||
value);
|
||||
return -1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static bool
|
||||
ice_proto_xtr_support(struct ice_hw *hw)
|
||||
{
|
||||
#define FLX_REG(val, fld, idx) \
|
||||
(((val) & GLFLXP_RXDID_FLX_WRD_##idx##_##fld##_M) >> \
|
||||
GLFLXP_RXDID_FLX_WRD_##idx##_##fld##_S)
|
||||
static struct {
|
||||
uint32_t rxdid;
|
||||
uint16_t protid_0;
|
||||
uint16_t protid_1;
|
||||
} xtr_sets[] = {
|
||||
{ ICE_RXDID_COMMS_AUX_VLAN, ICE_PROT_EVLAN_O, ICE_PROT_VLAN_O },
|
||||
{ ICE_RXDID_COMMS_AUX_IPV4, ICE_PROT_IPV4_OF_OR_S,
|
||||
ICE_PROT_IPV4_OF_OR_S },
|
||||
{ ICE_RXDID_COMMS_AUX_IPV6, ICE_PROT_IPV6_OF_OR_S,
|
||||
ICE_PROT_IPV6_OF_OR_S },
|
||||
{ ICE_RXDID_COMMS_AUX_IPV6_FLOW, ICE_PROT_IPV6_OF_OR_S,
|
||||
ICE_PROT_IPV6_OF_OR_S },
|
||||
{ ICE_RXDID_COMMS_AUX_TCP, ICE_PROT_TCP_IL, ICE_PROT_ID_INVAL },
|
||||
};
|
||||
uint32_t i;
|
||||
|
||||
for (i = 0; i < RTE_DIM(xtr_sets); i++) {
|
||||
uint32_t rxdid = xtr_sets[i].rxdid;
|
||||
uint32_t v;
|
||||
|
||||
if (xtr_sets[i].protid_0 != ICE_PROT_ID_INVAL) {
|
||||
v = ICE_READ_REG(hw, GLFLXP_RXDID_FLX_WRD_4(rxdid));
|
||||
|
||||
if (FLX_REG(v, PROT_MDID, 4) != xtr_sets[i].protid_0 ||
|
||||
FLX_REG(v, RXDID_OPCODE, 4) != ICE_RX_OPC_EXTRACT)
|
||||
return false;
|
||||
}
|
||||
|
||||
if (xtr_sets[i].protid_1 != ICE_PROT_ID_INVAL) {
|
||||
v = ICE_READ_REG(hw, GLFLXP_RXDID_FLX_WRD_5(rxdid));
|
||||
|
||||
if (FLX_REG(v, PROT_MDID, 5) != xtr_sets[i].protid_1 ||
|
||||
FLX_REG(v, RXDID_OPCODE, 5) != ICE_RX_OPC_EXTRACT)
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
static int
|
||||
ice_res_pool_init(struct ice_res_pool_info *pool, uint32_t base,
|
||||
uint32_t num)
|
||||
@ -1088,6 +1364,8 @@ ice_interrupt_handler(void *param)
|
||||
static int
|
||||
ice_pf_sw_init(struct rte_eth_dev *dev)
|
||||
{
|
||||
struct ice_adapter *ad =
|
||||
ICE_DEV_PRIVATE_TO_ADAPTER(dev->data->dev_private);
|
||||
struct ice_pf *pf = ICE_DEV_PRIVATE_TO_PF(dev->data->dev_private);
|
||||
struct ice_hw *hw = ICE_PF_TO_HW(pf);
|
||||
|
||||
@ -1097,6 +1375,16 @@ ice_pf_sw_init(struct rte_eth_dev *dev)
|
||||
|
||||
pf->lan_nb_qps = pf->lan_nb_qp_max;
|
||||
|
||||
if (ice_proto_xtr_support(hw))
|
||||
pf->proto_xtr = rte_zmalloc(NULL, pf->lan_nb_qps, 0);
|
||||
|
||||
if (pf->proto_xtr != NULL)
|
||||
rte_memcpy(pf->proto_xtr, ad->devargs.proto_xtr,
|
||||
RTE_MIN((size_t)pf->lan_nb_qps,
|
||||
sizeof(ad->devargs.proto_xtr)));
|
||||
else
|
||||
PMD_DRV_LOG(NOTICE, "Protocol extraction is disabled");
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -1508,9 +1796,18 @@ static int ice_parse_devargs(struct rte_eth_dev *dev)
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
memset(ad->devargs.proto_xtr, PROTO_XTR_NONE,
|
||||
sizeof(ad->devargs.proto_xtr));
|
||||
|
||||
ret = rte_kvargs_process(kvlist, ICE_PROTO_XTR_ARG,
|
||||
&handle_proto_xtr_arg, &ad->devargs);
|
||||
if (ret)
|
||||
goto bail;
|
||||
|
||||
ret = rte_kvargs_process(kvlist, ICE_SAFE_MODE_SUPPORT_ARG,
|
||||
&parse_bool, &ad->devargs.safe_mode_support);
|
||||
|
||||
bail:
|
||||
rte_kvargs_free(kvlist);
|
||||
return ret;
|
||||
}
|
||||
@ -1686,6 +1983,7 @@ ice_dev_init(struct rte_eth_dev *dev)
|
||||
ice_sched_cleanup_all(hw);
|
||||
rte_free(hw->port_info);
|
||||
ice_shutdown_all_ctrlq(hw);
|
||||
rte_free(pf->proto_xtr);
|
||||
|
||||
return ret;
|
||||
}
|
||||
@ -1811,6 +2109,8 @@ ice_dev_close(struct rte_eth_dev *dev)
|
||||
rte_free(hw->port_info);
|
||||
hw->port_info = NULL;
|
||||
ice_shutdown_all_ctrlq(hw);
|
||||
rte_free(pf->proto_xtr);
|
||||
pf->proto_xtr = NULL;
|
||||
}
|
||||
|
||||
static int
|
||||
@ -3970,6 +4270,7 @@ RTE_PMD_REGISTER_PCI(net_ice, rte_ice_pmd);
|
||||
RTE_PMD_REGISTER_PCI_TABLE(net_ice, pci_id_ice_map);
|
||||
RTE_PMD_REGISTER_KMOD_DEP(net_ice, "* igb_uio | uio_pci_generic | vfio-pci");
|
||||
RTE_PMD_REGISTER_PARAM_STRING(net_ice,
|
||||
ICE_PROTO_XTR_ARG "=[queue:]<vlan|ipv4|ipv6|ipv6_flow|tcp>"
|
||||
ICE_SAFE_MODE_SUPPORT_ARG "=<0|1>");
|
||||
|
||||
RTE_INIT(ice_init_log)
|
||||
|
@ -270,6 +270,7 @@ struct ice_pf {
|
||||
uint16_t lan_nb_qp_max;
|
||||
uint16_t lan_nb_qps; /* The number of queue pairs of LAN */
|
||||
uint16_t base_queue; /* The base queue pairs index in the device */
|
||||
uint8_t *proto_xtr; /* Protocol extraction type for all queues */
|
||||
struct ice_hw_port_stats stats_offset;
|
||||
struct ice_hw_port_stats stats;
|
||||
/* internal packet statistics, it should be excluded from the total */
|
||||
@ -280,11 +281,14 @@ struct ice_pf {
|
||||
struct ice_flow_list flow_list;
|
||||
};
|
||||
|
||||
#define ICE_MAX_QUEUE_NUM 2048
|
||||
|
||||
/**
|
||||
* Cache devargs parse result.
|
||||
*/
|
||||
struct ice_devargs {
|
||||
int safe_mode_support;
|
||||
uint8_t proto_xtr[ICE_MAX_QUEUE_NUM];
|
||||
};
|
||||
|
||||
/**
|
||||
|
@ -13,6 +13,35 @@
|
||||
PKT_TX_TCP_SEG | \
|
||||
PKT_TX_OUTER_IP_CKSUM)
|
||||
|
||||
static inline uint8_t
|
||||
ice_rxdid_to_proto_xtr_type(uint8_t rxdid)
|
||||
{
|
||||
static uint8_t xtr_map[] = {
|
||||
[ICE_RXDID_COMMS_AUX_VLAN] = PROTO_XTR_VLAN,
|
||||
[ICE_RXDID_COMMS_AUX_IPV4] = PROTO_XTR_IPV4,
|
||||
[ICE_RXDID_COMMS_AUX_IPV6] = PROTO_XTR_IPV6,
|
||||
[ICE_RXDID_COMMS_AUX_IPV6_FLOW] = PROTO_XTR_IPV6_FLOW,
|
||||
[ICE_RXDID_COMMS_AUX_TCP] = PROTO_XTR_TCP,
|
||||
};
|
||||
|
||||
return rxdid < RTE_DIM(xtr_map) ? xtr_map[rxdid] : PROTO_XTR_NONE;
|
||||
}
|
||||
|
||||
static inline uint8_t
|
||||
ice_proto_xtr_type_to_rxdid(uint8_t xtr_type)
|
||||
{
|
||||
static uint8_t rxdid_map[] = {
|
||||
[PROTO_XTR_NONE] = ICE_RXDID_COMMS_GENERIC,
|
||||
[PROTO_XTR_VLAN] = ICE_RXDID_COMMS_AUX_VLAN,
|
||||
[PROTO_XTR_IPV4] = ICE_RXDID_COMMS_AUX_IPV4,
|
||||
[PROTO_XTR_IPV6] = ICE_RXDID_COMMS_AUX_IPV6,
|
||||
[PROTO_XTR_IPV6_FLOW] = ICE_RXDID_COMMS_AUX_IPV6_FLOW,
|
||||
[PROTO_XTR_TCP] = ICE_RXDID_COMMS_AUX_TCP,
|
||||
};
|
||||
|
||||
return xtr_type < RTE_DIM(rxdid_map) ?
|
||||
rxdid_map[xtr_type] : ICE_RXDID_COMMS_GENERIC;
|
||||
}
|
||||
|
||||
static enum ice_status
|
||||
ice_program_hw_rx_queue(struct ice_rx_queue *rxq)
|
||||
@ -84,6 +113,11 @@ ice_program_hw_rx_queue(struct ice_rx_queue *rxq)
|
||||
rx_ctx.showiv = 0;
|
||||
rx_ctx.crcstrip = (rxq->crc_len == 0) ? 1 : 0;
|
||||
|
||||
rxdid = ice_proto_xtr_type_to_rxdid(rxq->proto_xtr);
|
||||
|
||||
PMD_DRV_LOG(DEBUG, "Port (%u) - Rx queue (%u) is set with RXDID : %u",
|
||||
rxq->port_id, rxq->queue_id, rxdid);
|
||||
|
||||
/* Enable Flexible Descriptors in the queue context which
|
||||
* allows this driver to select a specific receive descriptor format
|
||||
*/
|
||||
@ -641,6 +675,8 @@ ice_rx_queue_setup(struct rte_eth_dev *dev,
|
||||
rxq->drop_en = rx_conf->rx_drop_en;
|
||||
rxq->vsi = vsi;
|
||||
rxq->rx_deferred_start = rx_conf->rx_deferred_start;
|
||||
rxq->proto_xtr = pf->proto_xtr != NULL ?
|
||||
pf->proto_xtr[queue_idx] : PROTO_XTR_NONE;
|
||||
|
||||
/* Allocate the maximun number of RX ring hardware descriptor. */
|
||||
len = ICE_MAX_RING_DESC;
|
||||
@ -1062,6 +1098,10 @@ ice_rxd_to_vlan_tci(struct rte_mbuf *mb, volatile union ice_rx_flex_desc *rxdp)
|
||||
mb->vlan_tci, mb->vlan_tci_outer);
|
||||
}
|
||||
|
||||
#define ICE_RX_PROTO_XTR_VALID \
|
||||
((1 << ICE_RX_FLEX_DESC_STATUS1_XTRMD4_VALID_S) | \
|
||||
(1 << ICE_RX_FLEX_DESC_STATUS1_XTRMD5_VALID_S))
|
||||
|
||||
static inline void
|
||||
ice_rxd_to_pkt_fields(struct rte_mbuf *mb,
|
||||
volatile union ice_rx_flex_desc *rxdp)
|
||||
@ -1075,6 +1115,26 @@ ice_rxd_to_pkt_fields(struct rte_mbuf *mb,
|
||||
mb->ol_flags |= PKT_RX_RSS_HASH;
|
||||
mb->hash.rss = rte_le_to_cpu_32(desc->rss_hash);
|
||||
}
|
||||
|
||||
#ifndef RTE_LIBRTE_ICE_16BYTE_RX_DESC
|
||||
init_proto_xtr_flds(mb);
|
||||
|
||||
stat_err = rte_le_to_cpu_16(desc->status_error1);
|
||||
if (stat_err & ICE_RX_PROTO_XTR_VALID) {
|
||||
struct proto_xtr_flds *xtr = get_proto_xtr_flds(mb);
|
||||
|
||||
if (stat_err & (1 << ICE_RX_FLEX_DESC_STATUS1_XTRMD4_VALID_S))
|
||||
xtr->u.raw.data0 =
|
||||
rte_le_to_cpu_16(desc->flex_ts.flex.aux0);
|
||||
|
||||
if (stat_err & (1 << ICE_RX_FLEX_DESC_STATUS1_XTRMD5_VALID_S))
|
||||
xtr->u.raw.data1 =
|
||||
rte_le_to_cpu_16(desc->flex_ts.flex.aux1);
|
||||
|
||||
xtr->type = ice_rxdid_to_proto_xtr_type(desc->rxdid);
|
||||
xtr->magic = PROTO_XTR_MAGIC_ID;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
#ifdef RTE_LIBRTE_ICE_RX_ALLOW_BULK_ALLOC
|
||||
|
@ -5,6 +5,7 @@
|
||||
#ifndef _ICE_RXTX_H_
|
||||
#define _ICE_RXTX_H_
|
||||
|
||||
#include "rte_pmd_ice.h"
|
||||
#include "ice_ethdev.h"
|
||||
|
||||
#define ICE_ALIGN_RING_DESC 32
|
||||
@ -78,6 +79,7 @@ struct ice_rx_queue {
|
||||
uint16_t max_pkt_len; /* Maximum packet length */
|
||||
bool q_set; /* indicate if rx queue has been configured */
|
||||
bool rx_deferred_start; /* don't start this queue in dev start */
|
||||
uint8_t proto_xtr; /* Protocol extraction from flexible descriptor */
|
||||
ice_rx_release_mbufs_t rx_rel_mbufs;
|
||||
};
|
||||
|
||||
|
@ -234,6 +234,9 @@ ice_rx_vec_queue_default(struct ice_rx_queue *rxq)
|
||||
if (rxq->nb_rx_desc % rxq->rx_free_thresh)
|
||||
return -1;
|
||||
|
||||
if (rxq->proto_xtr != PROTO_XTR_NONE)
|
||||
return -1;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -34,3 +34,5 @@ if arch_subdir == 'x86'
|
||||
objs += ice_avx2_lib.extract_objects('ice_rxtx_vec_avx2.c')
|
||||
endif
|
||||
endif
|
||||
|
||||
install_headers('rte_pmd_ice.h')
|
||||
|
152
drivers/net/ice/rte_pmd_ice.h
Normal file
152
drivers/net/ice/rte_pmd_ice.h
Normal file
@ -0,0 +1,152 @@
|
||||
/* SPDX-License-Identifier: BSD-3-Clause
|
||||
* Copyright(c) 2019 Intel Corporation
|
||||
*/
|
||||
|
||||
#ifndef _RTE_PMD_ICE_H_
|
||||
#define _RTE_PMD_ICE_H_
|
||||
|
||||
#include <stdio.h>
|
||||
#include <rte_mbuf.h>
|
||||
#include <rte_ethdev.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
enum proto_xtr_type {
|
||||
PROTO_XTR_NONE,
|
||||
PROTO_XTR_VLAN,
|
||||
PROTO_XTR_IPV4,
|
||||
PROTO_XTR_IPV6,
|
||||
PROTO_XTR_IPV6_FLOW,
|
||||
PROTO_XTR_TCP,
|
||||
};
|
||||
|
||||
struct proto_xtr_flds {
|
||||
union {
|
||||
struct {
|
||||
uint16_t data0;
|
||||
uint16_t data1;
|
||||
} raw;
|
||||
struct {
|
||||
uint16_t stag_vid:12,
|
||||
stag_dei:1,
|
||||
stag_pcp:3;
|
||||
uint16_t ctag_vid:12,
|
||||
ctag_dei:1,
|
||||
ctag_pcp:3;
|
||||
} vlan;
|
||||
struct {
|
||||
uint16_t protocol:8,
|
||||
ttl:8;
|
||||
uint16_t tos:8,
|
||||
ihl:4,
|
||||
version:4;
|
||||
} ipv4;
|
||||
struct {
|
||||
uint16_t hoplimit:8,
|
||||
nexthdr:8;
|
||||
uint16_t flowhi4:4,
|
||||
tc:8,
|
||||
version:4;
|
||||
} ipv6;
|
||||
struct {
|
||||
uint16_t flowlo16;
|
||||
uint16_t flowhi4:4,
|
||||
tc:8,
|
||||
version:4;
|
||||
} ipv6_flow;
|
||||
struct {
|
||||
uint16_t fin:1,
|
||||
syn:1,
|
||||
rst:1,
|
||||
psh:1,
|
||||
ack:1,
|
||||
urg:1,
|
||||
ece:1,
|
||||
cwr:1,
|
||||
res1:4,
|
||||
doff:4;
|
||||
uint16_t rsvd;
|
||||
} tcp;
|
||||
} u;
|
||||
|
||||
uint16_t rsvd;
|
||||
|
||||
uint8_t type;
|
||||
|
||||
#define PROTO_XTR_MAGIC_ID 0xCE
|
||||
uint8_t magic;
|
||||
};
|
||||
|
||||
static inline void
|
||||
init_proto_xtr_flds(struct rte_mbuf *mb)
|
||||
{
|
||||
mb->udata64 = 0;
|
||||
}
|
||||
|
||||
static inline struct proto_xtr_flds *
|
||||
get_proto_xtr_flds(struct rte_mbuf *mb)
|
||||
{
|
||||
RTE_BUILD_BUG_ON(sizeof(struct proto_xtr_flds) > sizeof(mb->udata64));
|
||||
|
||||
return (struct proto_xtr_flds *)&mb->udata64;
|
||||
}
|
||||
|
||||
static inline void
|
||||
dump_proto_xtr_flds(struct rte_mbuf *mb)
|
||||
{
|
||||
struct proto_xtr_flds *xtr = get_proto_xtr_flds(mb);
|
||||
|
||||
if (xtr->magic != PROTO_XTR_MAGIC_ID || xtr->type == PROTO_XTR_NONE)
|
||||
return;
|
||||
|
||||
printf(" - Protocol Extraction:[0x%04x:0x%04x],",
|
||||
xtr->u.raw.data0, xtr->u.raw.data1);
|
||||
|
||||
if (xtr->type == PROTO_XTR_VLAN)
|
||||
printf("vlan,stag=%u:%u:%u,ctag=%u:%u:%u ",
|
||||
xtr->u.vlan.stag_pcp,
|
||||
xtr->u.vlan.stag_dei,
|
||||
xtr->u.vlan.stag_vid,
|
||||
xtr->u.vlan.ctag_pcp,
|
||||
xtr->u.vlan.ctag_dei,
|
||||
xtr->u.vlan.ctag_vid);
|
||||
else if (xtr->type == PROTO_XTR_IPV4)
|
||||
printf("ipv4,ver=%u,hdrlen=%u,tos=%u,ttl=%u,proto=%u ",
|
||||
xtr->u.ipv4.version,
|
||||
xtr->u.ipv4.ihl,
|
||||
xtr->u.ipv4.tos,
|
||||
xtr->u.ipv4.ttl,
|
||||
xtr->u.ipv4.protocol);
|
||||
else if (xtr->type == PROTO_XTR_IPV6)
|
||||
printf("ipv6,ver=%u,tc=%u,flow_hi4=0x%x,nexthdr=%u,hoplimit=%u ",
|
||||
xtr->u.ipv6.version,
|
||||
xtr->u.ipv6.tc,
|
||||
xtr->u.ipv6.flowhi4,
|
||||
xtr->u.ipv6.nexthdr,
|
||||
xtr->u.ipv6.hoplimit);
|
||||
else if (xtr->type == PROTO_XTR_IPV6_FLOW)
|
||||
printf("ipv6_flow,ver=%u,tc=%u,flow=0x%x%04x ",
|
||||
xtr->u.ipv6_flow.version,
|
||||
xtr->u.ipv6_flow.tc,
|
||||
xtr->u.ipv6_flow.flowhi4,
|
||||
xtr->u.ipv6_flow.flowlo16);
|
||||
else if (xtr->type == PROTO_XTR_TCP)
|
||||
printf("tcp,doff=%u,flags=%s%s%s%s%s%s%s%s ",
|
||||
xtr->u.tcp.doff,
|
||||
xtr->u.tcp.cwr ? "C" : "",
|
||||
xtr->u.tcp.ece ? "E" : "",
|
||||
xtr->u.tcp.urg ? "U" : "",
|
||||
xtr->u.tcp.ack ? "A" : "",
|
||||
xtr->u.tcp.psh ? "P" : "",
|
||||
xtr->u.tcp.rst ? "R" : "",
|
||||
xtr->u.tcp.syn ? "S" : "",
|
||||
xtr->u.tcp.fin ? "F" : "");
|
||||
}
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* _RTE_PMD_ICE_H_ */
|
Loading…
Reference in New Issue
Block a user