net/mrvl: support CRC and L3/L4 offloads
Add support for crc offload and l3/l4 checksum offloads. Signed-off-by: Jacek Siuda <jck@semihalf.com> Signed-off-by: Tomasz Duszynski <tdu@semihalf.com>
This commit is contained in:
parent
a8f3d6783a
commit
6ba75e403c
@ -14,3 +14,6 @@ Unicast MAC filter = Y
|
||||
Multicast MAC filter = Y
|
||||
RSS hash = Y
|
||||
VLAN filter = Y
|
||||
CRC offload = Y
|
||||
L3 checksum offload = Y
|
||||
L4 checksum offload = Y
|
||||
|
@ -134,6 +134,7 @@ struct mrvl_rxq {
|
||||
struct rte_mempool *mp;
|
||||
int queue_id;
|
||||
int port_id;
|
||||
int cksum_enabled;
|
||||
};
|
||||
|
||||
struct mrvl_txq {
|
||||
@ -863,7 +864,15 @@ mrvl_dev_infos_get(struct rte_eth_dev *dev __rte_unused,
|
||||
info->tx_desc_lim.nb_align = MRVL_PP2_TXD_ALIGN;
|
||||
|
||||
info->rx_offload_capa = DEV_RX_OFFLOAD_JUMBO_FRAME |
|
||||
DEV_RX_OFFLOAD_VLAN_FILTER;
|
||||
DEV_RX_OFFLOAD_VLAN_FILTER |
|
||||
DEV_RX_OFFLOAD_IPV4_CKSUM |
|
||||
DEV_RX_OFFLOAD_UDP_CKSUM |
|
||||
DEV_RX_OFFLOAD_TCP_CKSUM;
|
||||
|
||||
info->tx_offload_capa = DEV_TX_OFFLOAD_IPV4_CKSUM |
|
||||
DEV_TX_OFFLOAD_UDP_CKSUM |
|
||||
DEV_TX_OFFLOAD_TCP_CKSUM;
|
||||
|
||||
info->flow_type_rss_offloads = ETH_RSS_IPV4 |
|
||||
ETH_RSS_NONFRAG_IPV4_TCP |
|
||||
ETH_RSS_NONFRAG_IPV4_UDP;
|
||||
@ -1059,6 +1068,7 @@ mrvl_rx_queue_setup(struct rte_eth_dev *dev, uint16_t idx, uint16_t desc,
|
||||
|
||||
rxq->priv = priv;
|
||||
rxq->mp = mp;
|
||||
rxq->cksum_enabled = dev->data->dev_conf.rxmode.hw_ip_checksum;
|
||||
rxq->queue_id = idx;
|
||||
rxq->port_id = dev->data->port_id;
|
||||
mrvl_port_to_bpool_lookup[rxq->port_id] = priv->bpool;
|
||||
@ -1256,6 +1266,107 @@ static const struct eth_dev_ops mrvl_ops = {
|
||||
.rss_hash_conf_get = mrvl_rss_hash_conf_get,
|
||||
};
|
||||
|
||||
/**
|
||||
* Return packet type information and l3/l4 offsets.
|
||||
*
|
||||
* @param desc
|
||||
* Pointer to the received packet descriptor.
|
||||
* @param l3_offset
|
||||
* l3 packet offset.
|
||||
* @param l4_offset
|
||||
* l4 packet offset.
|
||||
*
|
||||
* @return
|
||||
* Packet type information.
|
||||
*/
|
||||
static inline uint64_t
|
||||
mrvl_desc_to_packet_type_and_offset(struct pp2_ppio_desc *desc,
|
||||
uint8_t *l3_offset, uint8_t *l4_offset)
|
||||
{
|
||||
enum pp2_inq_l3_type l3_type;
|
||||
enum pp2_inq_l4_type l4_type;
|
||||
uint64_t packet_type;
|
||||
|
||||
pp2_ppio_inq_desc_get_l3_info(desc, &l3_type, l3_offset);
|
||||
pp2_ppio_inq_desc_get_l4_info(desc, &l4_type, l4_offset);
|
||||
|
||||
packet_type = RTE_PTYPE_L2_ETHER;
|
||||
|
||||
switch (l3_type) {
|
||||
case PP2_INQ_L3_TYPE_IPV4_NO_OPTS:
|
||||
packet_type |= RTE_PTYPE_L3_IPV4;
|
||||
break;
|
||||
case PP2_INQ_L3_TYPE_IPV4_OK:
|
||||
packet_type |= RTE_PTYPE_L3_IPV4_EXT;
|
||||
break;
|
||||
case PP2_INQ_L3_TYPE_IPV4_TTL_ZERO:
|
||||
packet_type |= RTE_PTYPE_L3_IPV4_EXT_UNKNOWN;
|
||||
break;
|
||||
case PP2_INQ_L3_TYPE_IPV6_NO_EXT:
|
||||
packet_type |= RTE_PTYPE_L3_IPV6;
|
||||
break;
|
||||
case PP2_INQ_L3_TYPE_IPV6_EXT:
|
||||
packet_type |= RTE_PTYPE_L3_IPV6_EXT;
|
||||
break;
|
||||
case PP2_INQ_L3_TYPE_ARP:
|
||||
packet_type |= RTE_PTYPE_L2_ETHER_ARP;
|
||||
/*
|
||||
* In case of ARP l4_offset is set to wrong value.
|
||||
* Set it to proper one so that later on mbuf->l3_len can be
|
||||
* calculated subtracting l4_offset and l3_offset.
|
||||
*/
|
||||
*l4_offset = *l3_offset + MRVL_ARP_LENGTH;
|
||||
break;
|
||||
default:
|
||||
RTE_LOG(DEBUG, PMD, "Failed to recognise l3 packet type\n");
|
||||
break;
|
||||
}
|
||||
|
||||
switch (l4_type) {
|
||||
case PP2_INQ_L4_TYPE_TCP:
|
||||
packet_type |= RTE_PTYPE_L4_TCP;
|
||||
break;
|
||||
case PP2_INQ_L4_TYPE_UDP:
|
||||
packet_type |= RTE_PTYPE_L4_UDP;
|
||||
break;
|
||||
default:
|
||||
RTE_LOG(DEBUG, PMD, "Failed to recognise l4 packet type\n");
|
||||
break;
|
||||
}
|
||||
|
||||
return packet_type;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get offload information from the received packet descriptor.
|
||||
*
|
||||
* @param desc
|
||||
* Pointer to the received packet descriptor.
|
||||
*
|
||||
* @return
|
||||
* Mbuf offload flags.
|
||||
*/
|
||||
static inline uint64_t
|
||||
mrvl_desc_to_ol_flags(struct pp2_ppio_desc *desc)
|
||||
{
|
||||
uint64_t flags;
|
||||
enum pp2_inq_desc_status status;
|
||||
|
||||
status = pp2_ppio_inq_desc_get_l3_pkt_error(desc);
|
||||
if (unlikely(status != PP2_DESC_ERR_OK))
|
||||
flags = PKT_RX_IP_CKSUM_BAD;
|
||||
else
|
||||
flags = PKT_RX_IP_CKSUM_GOOD;
|
||||
|
||||
status = pp2_ppio_inq_desc_get_l4_pkt_error(desc);
|
||||
if (unlikely(status != PP2_DESC_ERR_OK))
|
||||
flags |= PKT_RX_L4_CKSUM_BAD;
|
||||
else
|
||||
flags |= PKT_RX_L4_CKSUM_GOOD;
|
||||
|
||||
return flags;
|
||||
}
|
||||
|
||||
/**
|
||||
* DPDK callback for receive.
|
||||
*
|
||||
@ -1294,6 +1405,7 @@ mrvl_rx_pkt_burst(void *rxq, struct rte_mbuf **rx_pkts, uint16_t nb_pkts)
|
||||
|
||||
for (i = 0; i < nb_pkts; i++) {
|
||||
struct rte_mbuf *mbuf;
|
||||
uint8_t l3_offset, l4_offset;
|
||||
enum pp2_inq_desc_status status;
|
||||
uint64_t addr;
|
||||
|
||||
@ -1331,6 +1443,15 @@ mrvl_rx_pkt_burst(void *rxq, struct rte_mbuf **rx_pkts, uint16_t nb_pkts)
|
||||
mbuf->pkt_len = pp2_ppio_inq_desc_get_pkt_len(&descs[i]);
|
||||
mbuf->data_len = mbuf->pkt_len;
|
||||
mbuf->port = q->port_id;
|
||||
mbuf->packet_type =
|
||||
mrvl_desc_to_packet_type_and_offset(&descs[i],
|
||||
&l3_offset,
|
||||
&l4_offset);
|
||||
mbuf->l2_len = l3_offset;
|
||||
mbuf->l3_len = l4_offset - l3_offset;
|
||||
|
||||
if (likely(q->cksum_enabled))
|
||||
mbuf->ol_flags = mrvl_desc_to_ol_flags(&descs[i]);
|
||||
|
||||
rx_pkts[rx_done++] = mbuf;
|
||||
}
|
||||
@ -1371,6 +1492,67 @@ mrvl_rx_pkt_burst(void *rxq, struct rte_mbuf **rx_pkts, uint16_t nb_pkts)
|
||||
return rx_done;
|
||||
}
|
||||
|
||||
/**
|
||||
* Prepare offload information.
|
||||
*
|
||||
* @param ol_flags
|
||||
* Offload flags.
|
||||
* @param packet_type
|
||||
* Packet type bitfield.
|
||||
* @param l3_type
|
||||
* Pointer to the pp2_ouq_l3_type structure.
|
||||
* @param l4_type
|
||||
* Pointer to the pp2_outq_l4_type structure.
|
||||
* @param gen_l3_cksum
|
||||
* Will be set to 1 in case l3 checksum is computed.
|
||||
* @param l4_cksum
|
||||
* Will be set to 1 in case l4 checksum is computed.
|
||||
*
|
||||
* @return
|
||||
* 0 on success, negative error value otherwise.
|
||||
*/
|
||||
static inline int
|
||||
mrvl_prepare_proto_info(uint64_t ol_flags, uint32_t packet_type,
|
||||
enum pp2_outq_l3_type *l3_type,
|
||||
enum pp2_outq_l4_type *l4_type,
|
||||
int *gen_l3_cksum,
|
||||
int *gen_l4_cksum)
|
||||
{
|
||||
/*
|
||||
* Based on ol_flags prepare information
|
||||
* for pp2_ppio_outq_desc_set_proto_info() which setups descriptor
|
||||
* for offloading.
|
||||
*/
|
||||
if (ol_flags & PKT_TX_IPV4) {
|
||||
*l3_type = PP2_OUTQ_L3_TYPE_IPV4;
|
||||
*gen_l3_cksum = ol_flags & PKT_TX_IP_CKSUM ? 1 : 0;
|
||||
} else if (ol_flags & PKT_TX_IPV6) {
|
||||
*l3_type = PP2_OUTQ_L3_TYPE_IPV6;
|
||||
/* no checksum for ipv6 header */
|
||||
*gen_l3_cksum = 0;
|
||||
} else {
|
||||
/* if something different then stop processing */
|
||||
return -1;
|
||||
}
|
||||
|
||||
ol_flags &= PKT_TX_L4_MASK;
|
||||
if ((packet_type & RTE_PTYPE_L4_TCP) &&
|
||||
ol_flags == PKT_TX_TCP_CKSUM) {
|
||||
*l4_type = PP2_OUTQ_L4_TYPE_TCP;
|
||||
*gen_l4_cksum = 1;
|
||||
} else if ((packet_type & RTE_PTYPE_L4_UDP) &&
|
||||
ol_flags == PKT_TX_UDP_CKSUM) {
|
||||
*l4_type = PP2_OUTQ_L4_TYPE_UDP;
|
||||
*gen_l4_cksum = 1;
|
||||
} else {
|
||||
*l4_type = PP2_OUTQ_L4_TYPE_OTHER;
|
||||
/* no checksum for other type */
|
||||
*gen_l4_cksum = 0;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Release already sent buffers to bpool (buffer-pool).
|
||||
*
|
||||
@ -1467,7 +1649,7 @@ mrvl_tx_pkt_burst(void *txq, struct rte_mbuf **tx_pkts, uint16_t nb_pkts)
|
||||
struct mrvl_shadow_txq *sq = &shadow_txqs[q->port_id][rte_lcore_id()];
|
||||
struct pp2_hif *hif = hifs[rte_lcore_id()];
|
||||
struct pp2_ppio_desc descs[nb_pkts];
|
||||
int i;
|
||||
int i, ret;
|
||||
uint16_t num, sq_free_size;
|
||||
|
||||
if (unlikely(!q->priv->ppio))
|
||||
@ -1486,6 +1668,9 @@ mrvl_tx_pkt_burst(void *txq, struct rte_mbuf **tx_pkts, uint16_t nb_pkts)
|
||||
|
||||
for (i = 0; i < nb_pkts; i++) {
|
||||
struct rte_mbuf *mbuf = tx_pkts[i];
|
||||
int gen_l3_cksum, gen_l4_cksum;
|
||||
enum pp2_outq_l3_type l3_type;
|
||||
enum pp2_outq_l4_type l4_type;
|
||||
|
||||
if (likely(nb_pkts - i > MRVL_MUSDK_PREFETCH_SHIFT)) {
|
||||
struct rte_mbuf *pref_pkt_hdr;
|
||||
@ -1510,6 +1695,21 @@ mrvl_tx_pkt_burst(void *txq, struct rte_mbuf **tx_pkts, uint16_t nb_pkts)
|
||||
pp2_ppio_outq_desc_set_pkt_offset(&descs[i], 0);
|
||||
pp2_ppio_outq_desc_set_pkt_len(&descs[i],
|
||||
rte_pktmbuf_pkt_len(mbuf));
|
||||
|
||||
/*
|
||||
* in case unsupported ol_flags were passed
|
||||
* do not update descriptor offload information
|
||||
*/
|
||||
ret = mrvl_prepare_proto_info(mbuf->ol_flags, mbuf->packet_type,
|
||||
&l3_type, &l4_type, &gen_l3_cksum,
|
||||
&gen_l4_cksum);
|
||||
if (unlikely(ret))
|
||||
continue;
|
||||
|
||||
pp2_ppio_outq_desc_set_proto_info(&descs[i], l3_type, l4_type,
|
||||
mbuf->l2_len,
|
||||
mbuf->l2_len + mbuf->l3_len,
|
||||
gen_l3_cksum, gen_l4_cksum);
|
||||
}
|
||||
|
||||
num = nb_pkts;
|
||||
|
Loading…
Reference in New Issue
Block a user