From 7958b1310d5e5650de629b066af5475d427b45e2 Mon Sep 17 00:00:00 2001 From: Xiao Wang Date: Wed, 2 Mar 2016 19:19:13 +0800 Subject: [PATCH] fm10k: enable FTAG based forwarding This patch enables reading sglort (global resource tag) info into the mbuf for RX and inserting an FTAG (Fabric Tag) at the beginning of the packet for TX. The vlan_tci_outer field selected from rte_mbuf structure for sglort is not used in fm10k now. In FTAG based forwarding mode, the switch will forward packets according to glort info in FTAG rather than mac and vlan table. To activate this feature, user needs to pass a devargs parameter to eal for fm10k device like "-w 0000:84:00.0,enable_ftag=1". Currently this feature is supported only on PF, because FM10K_PFVTCTL register is read-only for VF. Signed-off-by: Wang Xiao W Acked-by: Jing Chen Acked-by: John McNamara --- doc/guides/nics/fm10k.rst | 16 ++++++- doc/guides/rel_notes/release_16_04.rst | 2 + drivers/net/fm10k/fm10k.h | 2 + drivers/net/fm10k/fm10k_ethdev.c | 65 +++++++++++++++++++++++++- drivers/net/fm10k/fm10k_rxtx.c | 15 ++++++ drivers/net/fm10k/fm10k_rxtx_vec.c | 3 ++ 6 files changed, 101 insertions(+), 2 deletions(-) diff --git a/doc/guides/nics/fm10k.rst b/doc/guides/nics/fm10k.rst index 2d1b6b734b..c4915d8298 100644 --- a/doc/guides/nics/fm10k.rst +++ b/doc/guides/nics/fm10k.rst @@ -1,5 +1,5 @@ .. BSD LICENSE - Copyright(c) 2015 Intel Corporation. All rights reserved. + Copyright(c) 2015-2016 Intel Corporation. All rights reserved. All rights reserved. Redistribution and use in source and binary forms, with or without @@ -34,6 +34,20 @@ FM10K Poll Mode Driver The FM10K poll mode driver library provides support for the Intel FM10000 (FM10K) family of 40GbE/100GbE adapters. +FTAG Based Forwarding of FM10K +------------------------------ + +FTAG Based Forwarding is a unique feature of FM10K. The FM10K family of NICs +support the addition of a Fabric Tag (FTAG) to carry special information. +The FTAG is placed at the beginning of the frame, it contains information +such as where the packet comes from and goes, and the vlan tag. In FTAG based +forwarding mode, the switch logic forwards packets according to glort (global +resource tag) information, rather than the mac and vlan table. Currently this +feature works only on PF. + +To enable this feature, the user should pass a devargs parameter to the eal +like "-w 84:00.0,enable_ftag=1", and the application should make sure an +appropriate FTAG is inserted for every frame on TX side. Vector PMD for FM10K -------------------- diff --git a/doc/guides/rel_notes/release_16_04.rst b/doc/guides/rel_notes/release_16_04.rst index 2cf171d146..05e3190ff5 100644 --- a/doc/guides/rel_notes/release_16_04.rst +++ b/doc/guides/rel_notes/release_16_04.rst @@ -166,6 +166,8 @@ This section should contain new features added in this release. Sample format: Parse err flags in Rx desc and set error bits in mbuf with vector instructions. +* **Added fm10k FTAG based forwarding support.** + * **Increased number of next hops for LPM IPv4 to 2^24.** The next_hop field is extended from 8 bits to 24 bits for IPv4. diff --git a/drivers/net/fm10k/fm10k.h b/drivers/net/fm10k/fm10k.h index 770d6baff2..05aa1a2526 100644 --- a/drivers/net/fm10k/fm10k.h +++ b/drivers/net/fm10k/fm10k.h @@ -204,6 +204,7 @@ struct fm10k_rx_queue { uint8_t port_id; uint8_t drop_en; uint8_t rx_deferred_start; /* don't start this queue in dev start. */ + uint16_t rx_ftag_en; /* indicates FTAG RX supported */ }; /* @@ -240,6 +241,7 @@ struct fm10k_tx_queue { uint8_t port_id; uint8_t tx_deferred_start; /** don't start this queue in dev start. */ uint16_t queue_id; + uint16_t tx_ftag_en; /* indicates FTAG TX supported */ }; struct fm10k_txq_ops { diff --git a/drivers/net/fm10k/fm10k_ethdev.c b/drivers/net/fm10k/fm10k_ethdev.c index a455e988a7..4b07a8ba89 100644 --- a/drivers/net/fm10k/fm10k_ethdev.c +++ b/drivers/net/fm10k/fm10k_ethdev.c @@ -37,6 +37,7 @@ #include #include #include +#include #include "fm10k.h" #include "base/fm10k_api.h" @@ -79,6 +80,7 @@ static void fm10k_tx_queue_release(void *queue); static void fm10k_rx_queue_release(void *queue); static void fm10k_set_rx_function(struct rte_eth_dev *dev); static void fm10k_set_tx_function(struct rte_eth_dev *dev); +static int fm10k_check_ftag(struct rte_devargs *devargs); struct fm10k_xstats_name_off { char name[RTE_ETH_XSTATS_NAME_SIZE]; @@ -668,6 +670,19 @@ fm10k_dev_tx_init(struct rte_eth_dev *dev) PMD_INIT_LOG(ERR, "failed to disable queue %d", i); return -1; } + /* Enable use of FTAG bit in TX descriptor, PFVTCTL + * register is read-only for VF. + */ + if (fm10k_check_ftag(dev->pci_dev->devargs)) { + if (hw->mac.type == fm10k_mac_pf) { + FM10K_WRITE_REG(hw, FM10K_PFVTCTL(i), + FM10K_PFVTCTL_FTAG_DESC_ENABLE); + PMD_INIT_LOG(DEBUG, "FTAG mode is enabled"); + } else { + PMD_INIT_LOG(ERR, "VF FTAG is not supported."); + return -ENOTSUP; + } + } /* set location and size for descriptor ring */ FM10K_WRITE_REG(hw, FM10K_TDBAL(i), @@ -2584,15 +2599,57 @@ static const struct eth_dev_ops fm10k_eth_dev_ops = { .rss_hash_conf_get = fm10k_rss_hash_conf_get, }; +static int ftag_check_handler(__rte_unused const char *key, + const char *value, __rte_unused void *opaque) +{ + if (strcmp(value, "1")) + return -1; + + return 0; +} + +static int +fm10k_check_ftag(struct rte_devargs *devargs) +{ + struct rte_kvargs *kvlist; + const char *ftag_key = "enable_ftag"; + + if (devargs == NULL) + return 0; + + kvlist = rte_kvargs_parse(devargs->args, NULL); + if (kvlist == NULL) + return 0; + + if (!rte_kvargs_count(kvlist, ftag_key)) { + rte_kvargs_free(kvlist); + return 0; + } + /* FTAG is enabled when there's key-value pair: enable_ftag=1 */ + if (rte_kvargs_process(kvlist, ftag_key, + ftag_check_handler, NULL) < 0) { + rte_kvargs_free(kvlist); + return 0; + } + rte_kvargs_free(kvlist); + + return 1; +} + static void __attribute__((cold)) fm10k_set_tx_function(struct rte_eth_dev *dev) { struct fm10k_tx_queue *txq; int i; int use_sse = 1; + uint16_t tx_ftag_en = 0; + + if (fm10k_check_ftag(dev->pci_dev->devargs)) + tx_ftag_en = 1; for (i = 0; i < dev->data->nb_tx_queues; i++) { txq = dev->data->tx_queues[i]; + txq->tx_ftag_en = tx_ftag_en; /* Check if Vector Tx is satisfied */ if (fm10k_tx_vec_condition_check(txq)) { use_sse = 0; @@ -2618,11 +2675,16 @@ fm10k_set_rx_function(struct rte_eth_dev *dev) { struct fm10k_dev_info *dev_info = FM10K_DEV_PRIVATE_TO_INFO(dev); uint16_t i, rx_using_sse; + uint16_t rx_ftag_en = 0; + + if (fm10k_check_ftag(dev->pci_dev->devargs)) + rx_ftag_en = 1; /* In order to allow Vector Rx there are a few configuration * conditions to be met. */ - if (!fm10k_rx_vec_condition_check(dev) && dev_info->rx_vec_allowed) { + if (!fm10k_rx_vec_condition_check(dev) && + dev_info->rx_vec_allowed && !rx_ftag_en) { if (dev->data->scattered_rx) dev->rx_pkt_burst = fm10k_recv_scattered_pkts_vec; else @@ -2645,6 +2707,7 @@ fm10k_set_rx_function(struct rte_eth_dev *dev) struct fm10k_rx_queue *rxq = dev->data->rx_queues[i]; rxq->rx_using_sse = rx_using_sse; + rxq->rx_ftag_en = rx_ftag_en; } } diff --git a/drivers/net/fm10k/fm10k_rxtx.c b/drivers/net/fm10k/fm10k_rxtx.c index 9f832c14a1..66db5b6bdc 100644 --- a/drivers/net/fm10k/fm10k_rxtx.c +++ b/drivers/net/fm10k/fm10k_rxtx.c @@ -152,6 +152,12 @@ fm10k_recv_pkts(void *rx_queue, struct rte_mbuf **rx_pkts, */ mbuf->ol_flags |= PKT_RX_VLAN_PKT; mbuf->vlan_tci = desc.w.vlan; + /** + * mbuf->vlan_tci_outer is an idle field in fm10k driver, + * so it can be selected to store sglort value. + */ + if (q->rx_ftag_en) + mbuf->vlan_tci_outer = rte_le_to_cpu_16(desc.w.sglort); rx_pkts[count] = mbuf; if (++next_dd == q->nb_desc) { @@ -307,6 +313,13 @@ fm10k_recv_scattered_pkts(void *rx_queue, struct rte_mbuf **rx_pkts, */ first_seg->ol_flags |= PKT_RX_VLAN_PKT; first_seg->vlan_tci = desc.w.vlan; + /** + * mbuf->vlan_tci_outer is an idle field in fm10k driver, + * so it can be selected to store sglort value. + */ + if (q->rx_ftag_en) + first_seg->vlan_tci_outer = + rte_le_to_cpu_16(desc.w.sglort); /* Prefetch data of first segment, if configured to do so. */ rte_packet_prefetch((char *)first_seg->buf_addr + @@ -498,6 +511,8 @@ static inline void tx_xmit_pkt(struct fm10k_tx_queue *q, struct rte_mbuf *mb) q->nb_free -= mb->nb_segs; q->hw_ring[q->next_free].flags = 0; + if (q->tx_ftag_en) + q->hw_ring[q->next_free].flags |= FM10K_TXD_FLAG_FTAG; /* set checksum flags on first descriptor of packet. SCTP checksum * offload is not supported, but we do not explicitly check for this * case in favor of greatly simplified processing. */ diff --git a/drivers/net/fm10k/fm10k_rxtx_vec.c b/drivers/net/fm10k/fm10k_rxtx_vec.c index 9f178dbbdf..1c7872533c 100644 --- a/drivers/net/fm10k/fm10k_rxtx_vec.c +++ b/drivers/net/fm10k/fm10k_rxtx_vec.c @@ -688,6 +688,9 @@ fm10k_tx_vec_condition_check(struct fm10k_tx_queue *txq) if ((txq->txq_flags & FM10K_SIMPLE_TX_FLAG) != FM10K_SIMPLE_TX_FLAG) return -1; + if (txq->tx_ftag_en) + return -1; + return 0; } -- 2.20.1