app/testpmd: add dcb support
authorIntel <intel.com>
Wed, 19 Dec 2012 23:00:00 +0000 (00:00 +0100)
committerThomas Monjalon <thomas.monjalon@6wind.com>
Thu, 25 Jul 2013 13:54:18 +0000 (15:54 +0200)
Signed-off-by: Intel
app/test-pmd/cmdline.c
app/test-pmd/config.c
app/test-pmd/testpmd.c
app/test-pmd/testpmd.h

index ef7211a..9e82d28 100644 (file)
@@ -243,6 +243,8 @@ static void cmd_help_parsed(__attribute__((unused)) void *parsed_result,
                       "\n"
                       "- port config all rss ip|udp|none\n"
                       "    set rss mode\n"
+                      "- port config port-id dcb vt on|off nb-tcs pfc on|off\n"
+                      "    set dcb mode\n"
                       "- port config all burst value\n"
                       "    set the number of packet per burst\n"
                       "- port config all txpt|txht|txwt|rxpt|rxht|rxwt value\n"
@@ -879,6 +881,99 @@ cmdline_parse_inst_t cmd_config_rss = {
        },
 };
 
+/* *** Configure DCB *** */
+struct cmd_config_dcb {
+       cmdline_fixed_string_t port;
+       cmdline_fixed_string_t config;
+       uint8_t port_id; 
+       cmdline_fixed_string_t dcb;
+       cmdline_fixed_string_t vt;
+       cmdline_fixed_string_t vt_en;
+       uint8_t num_tcs; 
+       cmdline_fixed_string_t pfc;
+       cmdline_fixed_string_t pfc_en;
+};
+
+static void
+cmd_config_dcb_parsed(void *parsed_result,
+                        __attribute__((unused)) struct cmdline *cl,
+                        __attribute__((unused)) void *data)
+{
+       struct cmd_config_dcb *res = parsed_result;
+       struct dcb_config dcb_conf;
+       portid_t port_id = res->port_id;
+       struct rte_port *port;
+       
+       port = &ports[port_id];
+       /** Check if the port is not started **/
+       if (port->port_status != RTE_PORT_STOPPED) {
+               printf("Please stop port %d first\n",port_id);
+               return;
+       }
+               
+       dcb_conf.num_tcs = (enum rte_eth_nb_tcs) res->num_tcs;
+       if ((dcb_conf.num_tcs != ETH_4_TCS) && (dcb_conf.num_tcs != ETH_8_TCS)){
+               printf("The invalid number of traffic class,only 4 or 8 allowed\n");
+               return;
+       }
+
+       /* DCB in VT mode */
+       if (!strncmp(res->vt_en, "on",2)) 
+               dcb_conf.dcb_mode = DCB_VT_ENABLED;     
+       else
+               dcb_conf.dcb_mode = DCB_ENABLED;
+
+       if (!strncmp(res->pfc_en, "on",2)) {
+               dcb_conf.pfc_en = 1;
+       }
+       else
+               dcb_conf.pfc_en = 0;
+
+       if (init_port_dcb_config(port_id,&dcb_conf) != 0) {
+               printf("Cannot initialize network ports\n");
+               return;
+       }
+
+       cmd_reconfig_device_queue(port_id, 1, 1);
+}
+cmdline_parse_token_string_t cmd_config_dcb_port =
+        TOKEN_STRING_INITIALIZER(struct cmd_config_dcb, port, "port");
+cmdline_parse_token_string_t cmd_config_dcb_config =
+        TOKEN_STRING_INITIALIZER(struct cmd_config_dcb, config, "config");
+cmdline_parse_token_num_t cmd_config_dcb_port_id =
+        TOKEN_NUM_INITIALIZER(struct cmd_config_dcb, port_id, UINT8);
+cmdline_parse_token_string_t cmd_config_dcb_dcb =
+        TOKEN_STRING_INITIALIZER(struct cmd_config_dcb, dcb, "dcb");
+cmdline_parse_token_string_t cmd_config_dcb_vt =
+        TOKEN_STRING_INITIALIZER(struct cmd_config_dcb, vt, "vt");
+cmdline_parse_token_string_t cmd_config_dcb_vt_en =
+        TOKEN_STRING_INITIALIZER(struct cmd_config_dcb, vt_en, "on#off");
+cmdline_parse_token_num_t cmd_config_dcb_num_tcs =
+        TOKEN_NUM_INITIALIZER(struct cmd_config_dcb, num_tcs, UINT8);
+cmdline_parse_token_string_t cmd_config_dcb_pfc=
+        TOKEN_STRING_INITIALIZER(struct cmd_config_dcb, pfc, "pfc");
+cmdline_parse_token_string_t cmd_config_dcb_pfc_en =
+        TOKEN_STRING_INITIALIZER(struct cmd_config_dcb, pfc_en, "on#off");
+
+cmdline_parse_inst_t cmd_config_dcb = {
+        .f = cmd_config_dcb_parsed,
+        .data = NULL,
+        .help_str = "port config port-id dcb vt on|off nb-tcs pfc on|off",
+        .tokens = {
+               (void *)&cmd_config_dcb_port,
+               (void *)&cmd_config_dcb_config,
+               (void *)&cmd_config_dcb_port_id,
+               (void *)&cmd_config_dcb_dcb,
+               (void *)&cmd_config_dcb_vt,
+               (void *)&cmd_config_dcb_vt_en,
+               (void *)&cmd_config_dcb_num_tcs,
+               (void *)&cmd_config_dcb_pfc,
+               (void *)&cmd_config_dcb_pfc_en,
+                NULL,
+        },
+};
+
 /* *** configure number of packets per burst *** */
 struct cmd_config_burst {
        cmdline_fixed_string_t port;
@@ -3266,6 +3361,7 @@ cmdline_parse_ctx_t main_ctx[] = {
        (cmdline_parse_inst_t *)&cmd_tx_vlan_reset,
        (cmdline_parse_inst_t *)&cmd_tx_cksum_set,
        (cmdline_parse_inst_t *)&cmd_link_flow_control_set,
+       (cmdline_parse_inst_t *)&cmd_config_dcb,
        (cmdline_parse_inst_t *)&cmd_read_reg,
        (cmdline_parse_inst_t *)&cmd_read_reg_bit_field,
        (cmdline_parse_inst_t *)&cmd_read_reg_bit,
index b366405..809d2b5 100644 (file)
@@ -761,12 +761,126 @@ rss_fwd_config_setup(void)
        }
 }
 
+/*
+ * In DCB and VT on,the mapping of 128 receive queues to 128 transmit queues.
+ */
+static void
+dcb_rxq_2_txq_mapping(queueid_t rxq, queueid_t *txq)
+{
+       if(dcb_q_mapping == DCB_4_TCS_Q_MAPPING) {
+
+               if (rxq < 32)
+                       /* tc0: 0-31 */ 
+                       *txq = rxq;  
+               else if (rxq < 64) {
+                       /* tc1: 64-95 */ 
+                       *txq =  (uint16_t)(rxq + 32);
+               } 
+               else {  
+                       /* tc2: 96-111;tc3:112-127 */
+                       *txq =  (uint16_t)(rxq/2 + 64);
+               }
+       }
+       else {
+               if (rxq < 16)
+                       /* tc0 mapping*/
+                       *txq = rxq;
+               else if (rxq < 32) {
+                       /* tc1 mapping*/
+                        *txq = (uint16_t)(rxq + 16);
+               }
+               else if (rxq < 64) {
+                       /*tc2,tc3 mapping */
+                       *txq =  (uint16_t)(rxq + 32);
+               }
+               else {
+                       /* tc4,tc5,tc6 and tc7 mapping */
+                       *txq =  (uint16_t)(rxq/2 + 64);
+               }
+       }
+}
+
+/**
+ * For the DCB forwarding test, each core is assigned on every port multi-transmit
+ * queue. 
+ *
+ * Each core is assigned a multi-stream, each stream being composed of
+ * a RX queue to poll on a RX port for input messages, associated with
+ * a TX queue of a TX port where to send forwarded packets.
+ * All packets received on the RX queue of index "RxQj" of the RX port "RxPi"
+ * are sent on the TX queue "TxQl" of the TX port "TxPk" according to the two
+ * following rules:
+ * In VT mode,
+ *    - TxPk = (RxPi + 1) if RxPi is even, (RxPi - 1) if RxPi is odd
+ *    - TxQl = RxQj
+ * In non-VT mode,
+ *    - TxPk = (RxPi + 1) if RxPi is even, (RxPi - 1) if RxPi is odd  
+ *    There is a mapping of RxQj to TxQl to be required,and the mapping was implemented
+ *    in dcb_rxq_2_txq_mapping function.
+ */
+static void
+dcb_fwd_config_setup(void)
+{
+       portid_t   rxp;
+       portid_t   txp;
+       queueid_t  rxq;
+       queueid_t  nb_q;
+       lcoreid_t  lc_id;
+       uint8_t sm_id;
+
+       nb_q = nb_rxq;
+
+       cur_fwd_config.nb_fwd_lcores = (lcoreid_t) nb_fwd_lcores;
+       cur_fwd_config.nb_fwd_ports = nb_fwd_ports;
+       cur_fwd_config.nb_fwd_streams = 
+               (streamid_t) (nb_q * cur_fwd_config.nb_fwd_ports);
+
+       /* reinitialize forwarding streams */
+       init_fwd_streams();
+
+       setup_fwd_config_of_each_lcore(&cur_fwd_config);
+       rxp = 0; rxq = 0;
+       for (lc_id = 0; lc_id < cur_fwd_config.nb_fwd_lcores; lc_id++) {
+               /* a fwd core can run multi-streams */
+               for (sm_id = 0; sm_id < fwd_lcores[lc_id]->stream_nb; sm_id++)
+               {
+                       struct fwd_stream *fs;
+                       fs = fwd_streams[fwd_lcores[lc_id]->stream_idx + sm_id];
+                       if ((rxp & 0x1) == 0)
+                               txp = (portid_t) (rxp + 1);
+                       else
+                               txp = (portid_t) (rxp - 1);
+                       fs->rx_port = fwd_ports_ids[rxp];
+                       fs->rx_queue = rxq;
+                       fs->tx_port = fwd_ports_ids[txp];
+                       if (dcb_q_mapping == DCB_VT_Q_MAPPING)
+                               fs->tx_queue = rxq;
+                       else
+                               dcb_rxq_2_txq_mapping(rxq, &fs->tx_queue);
+                       fs->peer_addr = fs->tx_port;
+                       rxq = (queueid_t) (rxq + 1);
+                       if (rxq < nb_q)
+                               continue;
+                       rxq = 0;
+                       if (numa_support && (nb_fwd_ports <= (nb_ports >> 1)))
+                               rxp = (portid_t)
+                                       (rxp + ((nb_ports >> 1) / nb_fwd_ports));
+                       else
+                               rxp = (portid_t) (rxp + 1);
+               }
+       }
+}
+
 void
 fwd_config_setup(void)
 {
        cur_fwd_config.fwd_eng = cur_fwd_eng;
-       if ((nb_rxq > 1) && (nb_txq > 1))
-               rss_fwd_config_setup();
+       if ((nb_rxq > 1) && (nb_txq > 1)){
+               if (dcb_config)
+                       dcb_fwd_config_setup();
+               else
+                       rss_fwd_config_setup();
+       }
        else
                simple_fwd_config_setup();
 }
@@ -809,6 +923,10 @@ pkt_fwd_config_display(struct fwd_config *cfg)
 void
 fwd_config_display(void)
 {
+       if((dcb_config) && (nb_fwd_lcores == 1)) {
+               printf("In DCB mode,the nb forwarding cores should be larger than 1\n");
+               return;
+       } 
        fwd_config_setup();
        pkt_fwd_config_display(&cur_fwd_config);
 }
index 2e828e4..f2df50b 100644 (file)
@@ -157,10 +157,14 @@ uint8_t  tx_pkt_nb_segs = 1; /**< Number of segments in TXONLY packets */
 uint16_t nb_pkt_per_burst = DEF_PKT_BURST; /**< Number of packets per burst. */
 uint16_t mb_mempool_cache = DEF_PKT_BURST; /**< Size of mbuf mempool cache. */
 
-/*
- * Ethernet Ports Configuration.
- */
-int promiscuous_on = 1; /**< Ports set in promiscuous mode by default. */
+/* current configuration is in DCB or not,0 means it is not in DCB mode */
+uint8_t dcb_config = 0;
+/* Whether the dcb is in testing status */
+uint8_t dcb_test = 0;
+/* DCB on and VT on mapping is default */
+enum dcb_queue_mapping_mode dcb_q_mapping = DCB_VT_Q_MAPPING;
 
 /*
  * Configurable number of RX/TX queues.
index ea09584..0b4b42b 100644 (file)
@@ -215,6 +215,34 @@ struct fwd_config {
        portid_t   nb_fwd_ports;    /**< Nb. of ports involved. */
 };
 
+/**
+ * DCB mode enable
+ */
+enum dcb_mode_enable
+{
+       DCB_VT_ENABLED,
+       DCB_ENABLED
+};
+
+/*
+ * DCB general config info
+ */
+struct dcb_config {
+       enum dcb_mode_enable dcb_mode;
+       uint8_t vt_en;
+       enum rte_eth_nb_tcs num_tcs;
+       uint8_t pfc_en;
+};
+/*
+ * In DCB io FWD mode, 128 RX queue to 128 TX queue mapping
+ */
+enum dcb_queue_mapping_mode {
+       DCB_VT_Q_MAPPING = 0,
+       DCB_4_TCS_Q_MAPPING,
+       DCB_8_TCS_Q_MAPPING
+};
+
 #define MAX_TX_QUEUE_STATS_MAPPINGS 1024 /* MAX_PORT of 32 @ 32 tx_queues/port */
 #define MAX_RX_QUEUE_STATS_MAPPINGS 4096 /* MAX_PORT of 32 @ 128 rx_queues/port */
 
@@ -274,6 +302,10 @@ extern uint16_t tx_free_thresh;
 extern uint16_t tx_rs_thresh;
 extern uint32_t txq_flags;
 
+extern uint8_t dcb_config;
+extern uint8_t dcb_test;
+extern enum dcb_queue_mapping_mode dcb_q_mapping;
+
 extern uint16_t mbuf_data_size; /**< Mbuf data space size. */
 extern uint32_t param_total_num_mbufs;
 
@@ -422,6 +454,7 @@ void set_pkt_forwarding_mode(const char *fwd_mode);
 void start_packet_forwarding(int with_tx_first);
 void stop_packet_forwarding(void);
 void init_port_config(void);
+int init_port_dcb_config(portid_t pid,struct dcb_config *dcb_conf);
 void start_port(portid_t pid);
 void stop_port(portid_t pid);
 void close_port(portid_t pid);