Initially in the application,
a default structure is provided for VMDq configuration to be filled in later by the application.
-.. code-block:: c
-
- /* empty vmdq configuration structure. Filled in programmatically */
- static const struct rte_eth_conf vmdq_conf_default = {
- .rxmode = {
- .mq_mode = ETH_MQ_RX_VMDQ_ONLY,
- .split_hdr_size = 0,
- },
-
- .txmode = {
- .mq_mode = ETH_MQ_TX_NONE,
- },
- .rx_adv_conf = {
- /*
- * should be overridden separately in code with
- * appropriate values
- */
- .vmdq_rx_conf = {
- .nb_queue_pools = ETH_8_POOLS,
- .enable_default_pool = 0,
- .default_pool = 0,
- .nb_pool_maps = 0,
- .pool_map = {{0, 0},},
- },
- },
- };
+.. literalinclude:: ../../../examples/vmdq/main.c
+ :language: c
+ :start-after: Default structure for VMDq. 8<
+ :end-before: >8 End of Empty vdmq configuration structure.
The get_eth_conf() function fills in an rte_eth_conf structure with the appropriate values,
based on the global vlan_tags array.
is assigned to the MAC like 52:54:00:12:<port_id>:<pool_id>, that is,
the MAC of VMDq pool 2 on port 1 is 52:54:00:12:01:02.
-.. code-block:: c
-
- const uint16_t vlan_tags[] = {
- 0, 1, 2, 3, 4, 5, 6, 7,
- 8, 9, 10, 11, 12, 13, 14, 15,
- 16, 17, 18, 19, 20, 21, 22, 23,
- 24, 25, 26, 27, 28, 29, 30, 31,
- 32, 33, 34, 35, 36, 37, 38, 39,
- 40, 41, 42, 43, 44, 45, 46, 47,
- 48, 49, 50, 51, 52, 53, 54, 55,
- 56, 57, 58, 59, 60, 61, 62, 63,
- };
-
- /* pool mac addr template, pool mac addr is like: 52 54 00 12 port# pool# */
- static struct rte_ether_addr pool_addr_template = {
- .addr_bytes = {0x52, 0x54, 0x00, 0x12, 0x00, 0x00}
- };
-
- /*
- * Builds up the correct configuration for vmdq based on the vlan tags array
- * given above, and determine the queue number and pool map number according to
- * valid pool number
- */
- static inline int
- get_eth_conf(struct rte_eth_conf *eth_conf, uint32_t num_pools)
- {
- struct rte_eth_vmdq_rx_conf conf;
- unsigned i;
-
- conf.nb_queue_pools = (enum rte_eth_nb_pools)num_pools;
- conf.nb_pool_maps = num_pools;
- conf.enable_default_pool = 0;
- conf.default_pool = 0; /* set explicit value, even if not used */
-
- for (i = 0; i < conf.nb_pool_maps; i++) {
- conf.pool_map[i].vlan_id = vlan_tags[i];
- conf.pool_map[i].pools = (1UL << (i % num_pools));
- }
-
- (void)(rte_memcpy(eth_conf, &vmdq_conf_default, sizeof(*eth_conf)));
- (void)(rte_memcpy(ð_conf->rx_adv_conf.vmdq_rx_conf, &conf,
- sizeof(eth_conf->rx_adv_conf.vmdq_rx_conf)));
- return 0;
- }
-
- ......
-
- /*
- * Set mac for each pool.
- * There is no default mac for the pools in i40.
- * Removes this after i40e fixes this issue.
- */
- for (q = 0; q < num_pools; q++) {
- struct rte_ether_addr mac;
- mac = pool_addr_template;
- mac.addr_bytes[4] = port;
- mac.addr_bytes[5] = q;
- printf("Port %u vmdq pool %u set mac %02x:%02x:%02x:%02x:%02x:%02x\n",
- port, q,
- mac.addr_bytes[0], mac.addr_bytes[1],
- mac.addr_bytes[2], mac.addr_bytes[3],
- mac.addr_bytes[4], mac.addr_bytes[5]);
- retval = rte_eth_dev_mac_addr_add(port, &mac,
- q + vmdq_pool_base);
- if (retval) {
- printf("mac addr add failed at pool %d\n", q);
- return retval;
- }
- }
+.. literalinclude:: ../../../examples/vmdq/main.c
+ :language: c
+ :start-after: vlan_tags 8<
+ :end-before: >8 End of vlan_tags.
+
+.. literalinclude:: ../../../examples/vmdq/main.c
+ :language: c
+ :start-after: Pool mac address template. 8<
+ :end-before: >8 End of mac addr template.
+
+.. literalinclude:: ../../../examples/vmdq/main.c
+ :language: c
+ :start-after: Building correct configruration for vdmq. 8<
+ :end-before: >8 End of get_eth_conf.
Once the network port has been initialized using the correct VMDq values,
the initialization of the port's RX and TX hardware rings is performed similarly to that