net/bnxt: support to add a VF MAC address
authorAjit Khaparde <ajit.khaparde@broadcom.com>
Thu, 1 Jun 2017 17:07:20 +0000 (12:07 -0500)
committerFerruh Yigit <ferruh.yigit@intel.com>
Mon, 12 Jun 2017 09:41:29 +0000 (10:41 +0100)
This patch adds support to allocate a filter and program
it in the hardware for every MAC address added to the specified
function.

Signed-off-by: Stephen Hurd <stephen.hurd@broadcom.com>
Signed-off-by: Ajit Khaparde <ajit.khaparde@broadcom.com>
drivers/net/bnxt/bnxt_filter.c
drivers/net/bnxt/bnxt_filter.h
drivers/net/bnxt/rte_pmd_bnxt.c
drivers/net/bnxt/rte_pmd_bnxt.h
drivers/net/bnxt/rte_pmd_bnxt_version.map

index 0afde86..e9aac27 100644 (file)
@@ -68,6 +68,22 @@ struct bnxt_filter_info *bnxt_alloc_filter(struct bnxt *bp)
        return filter;
 }
 
+struct bnxt_filter_info *bnxt_alloc_vf_filter(struct bnxt *bp, uint16_t vf)
+{
+       struct bnxt_filter_info *filter;
+
+       filter = rte_zmalloc("bnxt_vf_filter_info", sizeof(*filter), 0);
+       if (!filter) {
+               RTE_LOG(ERR, PMD, "Failed to alloc memory for VF %hu filters\n",
+                       vf);
+               return NULL;
+       }
+
+       filter->fw_l2_filter_id = UINT64_MAX;
+       STAILQ_INSERT_TAIL(&bp->pf.vf_info[vf].filter, filter, next);
+       return filter;
+}
+
 void bnxt_init_filters(struct bnxt *bp)
 {
        struct bnxt_filter_info *filter;
@@ -102,6 +118,12 @@ void bnxt_free_all_filters(struct bnxt *bp)
                        STAILQ_INIT(&vnic->filter);
                }
        }
+
+       for (i = 0; i < bp->pf.max_vfs; i++) {
+               STAILQ_FOREACH(filter, &bp->pf.vf_info[i].filter, next) {
+                       bnxt_hwrm_clear_filter(bp, filter);
+               }
+       }
 }
 
 void bnxt_free_filter_mem(struct bnxt *bp)
index 353b7f7..613b2ee 100644 (file)
@@ -68,6 +68,7 @@ struct bnxt_filter_info {
 };
 
 struct bnxt_filter_info *bnxt_alloc_filter(struct bnxt *bp);
+struct bnxt_filter_info *bnxt_alloc_vf_filter(struct bnxt *bp, uint16_t vf);
 void bnxt_init_filters(struct bnxt *bp);
 void bnxt_free_all_filters(struct bnxt *bp);
 void bnxt_free_filter_mem(struct bnxt *bp);
index 39428a8..59bd1ff 100644 (file)
@@ -568,3 +568,79 @@ int rte_pmd_bnxt_get_vf_tx_drop_count(uint8_t port, uint16_t vf_id,
        return bnxt_hwrm_func_qstats_tx_drop(bp, bp->pf.first_vf_id + vf_id,
                                             count);
 }
+
+int rte_pmd_bnxt_mac_addr_add(uint8_t port, struct ether_addr *addr,
+                               uint32_t vf_id)
+{
+       struct rte_eth_dev *dev;
+       struct rte_eth_dev_info dev_info;
+       struct bnxt *bp;
+       struct bnxt_filter_info *filter;
+       struct bnxt_vnic_info vnic;
+       struct ether_addr dflt_mac;
+       int rc;
+
+       dev = &rte_eth_devices[port];
+       if (!is_bnxt_supported(dev))
+               return -ENOTSUP;
+
+       rte_eth_dev_info_get(port, &dev_info);
+       bp = (struct bnxt *)dev->data->dev_private;
+
+       if (vf_id >= dev_info.max_vfs)
+               return -EINVAL;
+
+       if (!BNXT_PF(bp)) {
+               RTE_LOG(ERR, PMD,
+                       "Attempt to config VF %d MAC on non-PF port %d!\n",
+                       vf_id, port);
+               return -ENOTSUP;
+       }
+
+       /* If the VF currently uses a random MAC, update default to this one */
+       if (bp->pf.vf_info[vf_id].random_mac) {
+               if (rte_pmd_bnxt_get_vf_rx_status(port, vf_id) <= 0)
+                       rc = bnxt_hwrm_func_vf_mac(bp, vf_id, (uint8_t *)addr);
+       }
+
+       /* query the default VNIC id used by the function */
+       rc = bnxt_hwrm_func_qcfg_vf_dflt_vnic_id(bp, vf_id);
+       if (rc < 0)
+               goto exit;
+
+       memset(&vnic, 0, sizeof(struct bnxt_vnic_info));
+       vnic.fw_vnic_id = rte_le_to_cpu_16(rc);
+       rc = bnxt_hwrm_vnic_qcfg(bp, &vnic, bp->pf.first_vf_id + vf_id);
+       if (rc < 0)
+               goto exit;
+
+       STAILQ_FOREACH(filter, &bp->pf.vf_info[vf_id].filter, next) {
+               if (filter->flags ==
+                   HWRM_CFA_L2_FILTER_ALLOC_INPUT_FLAGS_PATH_RX &&
+                   filter->enables ==
+                   (HWRM_CFA_L2_FILTER_ALLOC_INPUT_ENABLES_L2_ADDR |
+                    HWRM_CFA_L2_FILTER_ALLOC_INPUT_ENABLES_L2_ADDR_MASK) &&
+                   memcmp(addr, filter->l2_addr, ETHER_ADDR_LEN) == 0) {
+                       bnxt_hwrm_clear_filter(bp, filter);
+                       break;
+               }
+       }
+
+       if (filter == NULL)
+               filter = bnxt_alloc_vf_filter(bp, vf_id);
+
+       filter->fw_l2_filter_id = UINT64_MAX;
+       filter->flags = HWRM_CFA_L2_FILTER_ALLOC_INPUT_FLAGS_PATH_RX;
+       filter->enables = HWRM_CFA_L2_FILTER_ALLOC_INPUT_ENABLES_L2_ADDR |
+                       HWRM_CFA_L2_FILTER_ALLOC_INPUT_ENABLES_L2_ADDR_MASK;
+       memcpy(filter->l2_addr, addr, ETHER_ADDR_LEN);
+       memset(filter->l2_addr_mask, 0xff, ETHER_ADDR_LEN);
+
+       /* Do not add a filter for the default MAC */
+       if (bnxt_hwrm_func_qcfg_vf_default_mac(bp, vf_id, &dflt_mac) ||
+           memcmp(filter->l2_addr, dflt_mac.addr_bytes, ETHER_ADDR_LEN))
+               rc = bnxt_hwrm_set_filter(bp, vnic.fw_vnic_id, filter);
+
+exit:
+       return rc;
+}
index 0987c0f..a523a95 100644 (file)
@@ -250,4 +250,22 @@ int rte_pmd_bnxt_get_vf_rx_status(uint8_t port, uint16_t vf_id);
  */
 int rte_pmd_bnxt_get_vf_tx_drop_count(uint8_t port, uint16_t vf_id,
                                      uint64_t *count);
+
+/**
+ * Programs the MAC address for the function specified
+ *
+ * @param port
+ *    The port identifier of the Ethernet device.
+ * @param mac_addr
+ *    The MAC address to be programmed in the filter.
+ * @param vf_id
+ *    VF on which to get.
+ * @return
+ *   - Positive Non-zero value - Error code from HWRM
+ *   - (-EINVAL) invalid vf_id specified.
+ *   - (-ENOTSUP) Ethernet device is not a PF
+ *   - (-ENOMEM) on an allocation failure
+ */
+int rte_pmd_bnxt_mac_addr_add(uint8_t port, struct ether_addr *mac_addr,
+                               uint32_t vf_id);
 #endif /* _PMD_BNXT_H_ */
index c9e53f5..803c6f2 100644 (file)
@@ -4,6 +4,7 @@ DPDK_17.08 {
        rte_pmd_bnxt_get_vf_rx_status;
        rte_pmd_bnxt_get_vf_stats;
        rte_pmd_bnxt_get_vf_tx_drop_count;
+       rte_pmd_bnxt_mac_addr_add;
        rte_pmd_bnxt_reset_vf_stats;
        rte_pmd_bnxt_set_all_queues_drop_en;
        rte_pmd_bnxt_set_tx_loopback;