Add functions rte_pmd_bnxt_set_tx_loopback and
rte_pmd_bnxt_set_all_queues_drop_en to configure tx_loopback and
queue_drop setting in the hardware.

This patch also adds code to testpmd app to call the appropriate
function when the bnxt driver is in use.

Signed-off-by: Steeven Li <steeven...@broadcom.com>
Signed-off-by: Ajit Khaparde <ajit.khapa...@broadcom.com>
---
 app/test-pmd/cmdline.c                    |  13 ++-
 drivers/net/bnxt/Makefile                 |   2 +
 drivers/net/bnxt/bnxt.h                   |   8 ++
 drivers/net/bnxt/bnxt_cpr.c               |  41 ++++++---
 drivers/net/bnxt/bnxt_ethdev.c            |   1 +
 drivers/net/bnxt/bnxt_hwrm.c              | 114 +++++++++++++++++++++++-
 drivers/net/bnxt/bnxt_hwrm.h              |   4 +
 drivers/net/bnxt/bnxt_irq.c               |   3 +-
 drivers/net/bnxt/bnxt_vnic.h              |   3 +
 drivers/net/bnxt/rte_pmd_bnxt.c           | 143 ++++++++++++++++++++++++++++++
 drivers/net/bnxt/rte_pmd_bnxt.h           |  98 ++++++++++++++++++++
 drivers/net/bnxt/rte_pmd_bnxt_version.map |   7 +-
 12 files changed, 417 insertions(+), 20 deletions(-)
 create mode 100644 drivers/net/bnxt/rte_pmd_bnxt.c
 create mode 100644 drivers/net/bnxt/rte_pmd_bnxt.h

diff --git a/app/test-pmd/cmdline.c b/app/test-pmd/cmdline.c
index 47f935d..1465685 100644
--- a/app/test-pmd/cmdline.c
+++ b/app/test-pmd/cmdline.c
@@ -94,6 +94,9 @@
 #ifdef RTE_LIBRTE_I40E_PMD
 #include <rte_pmd_i40e.h>
 #endif
+#ifdef RTE_LIBRTE_BNXT_PMD
+#include <rte_pmd_bnxt.h>
+#endif
 #include "testpmd.h"
 
 static struct cmdline *testpmd_cl;
@@ -11353,6 +11356,9 @@ cmd_set_tx_loopback_parsed(
        if (ret == -ENOTSUP)
                ret = rte_pmd_ixgbe_set_tx_loopback(res->port_id, is_on);
 #endif
+#ifdef RTE_LIBRTE_BNXT_PMD
+               ret = rte_pmd_bnxt_set_tx_loopback(res->port_id, is_on);
+#endif
 #ifdef RTE_LIBRTE_I40E_PMD
        if (ret == -ENOTSUP)
                ret = rte_pmd_i40e_set_tx_loopback(res->port_id, is_on);
@@ -11441,7 +11447,12 @@ cmd_set_all_queues_drop_en_parsed(
        if (port_id_is_invalid(res->port_id, ENABLED_WARN))
                return;
 
-       ret = rte_pmd_ixgbe_set_all_queues_drop_en(res->port_id, is_on);
+#ifdef RTE_LIBRTE_BNXT_PMD
+               ret = rte_pmd_bnxt_set_all_queues_drop_en(res->port_id, is_on);
+#endif
+#ifdef RTE_LIBRTE_IXGBE_PMD
+               ret = rte_pmd_ixgbe_set_all_queues_drop_en(res->port_id, is_on);
+#endif
        switch (ret) {
        case 0:
                break;
diff --git a/drivers/net/bnxt/Makefile b/drivers/net/bnxt/Makefile
index 65aaa92..c06476b 100644
--- a/drivers/net/bnxt/Makefile
+++ b/drivers/net/bnxt/Makefile
@@ -60,11 +60,13 @@ SRCS-$(CONFIG_RTE_LIBRTE_BNXT_PMD) += bnxt_txq.c
 SRCS-$(CONFIG_RTE_LIBRTE_BNXT_PMD) += bnxt_txr.c
 SRCS-$(CONFIG_RTE_LIBRTE_BNXT_PMD) += bnxt_vnic.c
 SRCS-$(CONFIG_RTE_LIBRTE_BNXT_PMD) += bnxt_irq.c
+SRCS-$(CONFIG_RTE_LIBRTE_BNXT_PMD) += rte_pmd_bnxt.c
 
 #
 # Export include files
 #
 SYMLINK-y-include +=
+SYMLINK-$(CONFIG_RTE_LIBRTE_BNXT_PMD)-include += rte_pmd_bnxt.h
 
 # this lib depends upon:
 DEPDIRS-$(CONFIG_RTE_LIBRTE_BNXT_PMD) += lib/librte_mbuf
diff --git a/drivers/net/bnxt/bnxt.h b/drivers/net/bnxt/bnxt.h
index f2887d1..7cc3f3f 100644
--- a/drivers/net/bnxt/bnxt.h
+++ b/drivers/net/bnxt/bnxt.h
@@ -74,7 +74,13 @@ struct bnxt_pf_info {
        uint32_t                func_cfg_flags;
        void                    *vf_req_buf;
        uint32_t                vf_req_fwd[8];
+       uint16_t                total_vnics;
        struct bnxt_child_vf_info       *vf_info;
+#define BNXT_EVB_MODE_NONE     0
+#define BNXT_EVB_MODE_VEB      1
+#define BNXT_EVB_MODE_VEPA     2
+       uint8_t                 evb_mode;
+       uint16_t                vnic_dflt_ring_group[340];
 };
 
 /* Max wait time is 10 * 100ms = 1s */
@@ -177,4 +183,6 @@ struct bnxt {
 
 int bnxt_link_update_op(struct rte_eth_dev *eth_dev, int wait_to_complete);
 
+int bnxt_rcv_msg_from_vf(struct bnxt *bp, uint16_t vf_id, void *msg);
+
 #endif
diff --git a/drivers/net/bnxt/bnxt_cpr.c b/drivers/net/bnxt/bnxt_cpr.c
index 5d961f6..3fc3758 100644
--- a/drivers/net/bnxt/bnxt_cpr.c
+++ b/drivers/net/bnxt/bnxt_cpr.c
@@ -68,8 +68,9 @@ void bnxt_handle_fwd_req(struct bnxt *bp, struct cmpl_base 
*cmpl)
        struct hwrm_exec_fwd_resp_input *fwreq;
        struct hwrm_fwd_req_cmpl *fwd_cmpl = (struct hwrm_fwd_req_cmpl *)cmpl;
        struct input *fwd_cmd;
-       uint16_t vf_id;
+       uint16_t fw_vf_id;
        uint16_t req_len;
+       int rc;
 
        if (bp->pf.active_vfs <= 0) {
                RTE_LOG(ERR, PMD, "Forwarded VF with no active VFs\n");
@@ -77,7 +78,7 @@ void bnxt_handle_fwd_req(struct bnxt *bp, struct cmpl_base 
*cmpl)
        }
 
        /* Qualify the fwd request */
-       vf_id = rte_le_to_cpu_16(fwd_cmpl->source_id);
+       fw_vf_id = rte_le_to_cpu_16(fwd_cmpl->source_id);
 
        /*
         * TODO: req_len is always 128, is there a way to get the
@@ -90,28 +91,42 @@ void bnxt_handle_fwd_req(struct bnxt *bp, struct cmpl_base 
*cmpl)
 
        /* Locate VF's forwarded command */
        fwd_cmd = (struct input *)
-               bp->pf.vf_info[vf_id - bp->pf.first_vf_id].req_buf;
+               bp->pf.vf_info[fw_vf_id - bp->pf.first_vf_id].req_buf;
        /* Force the target ID to the source VF */
-       fwd_cmd->target_id = rte_cpu_to_le_16(vf_id);
+       fwd_cmd->target_id = rte_cpu_to_le_16(fw_vf_id);
 
-       if (vf_id < bp->pf.first_vf_id ||
-           vf_id >= (bp->pf.first_vf_id) + bp->pf.active_vfs) {
+       if (fw_vf_id < bp->pf.first_vf_id ||
+           fw_vf_id >= (bp->pf.first_vf_id) + bp->pf.active_vfs) {
                RTE_LOG(ERR, PMD,
                        "FWD req src_id 0x%x out of range 0x%x - 0x%x(%d %d)\n",
-                       vf_id, bp->pf.first_vf_id,
+                       fw_vf_id, bp->pf.first_vf_id,
                        (bp->pf.first_vf_id) + bp->pf.active_vfs - 1,
                        bp->pf.first_vf_id, bp->pf.active_vfs);
                goto reject;
        }
 
-       /* TODO: Call "mailbox" callback if necessary */
-
-       /* Forward */
-       bnxt_hwrm_exec_fwd_resp(bp, vf_id, fwd_cmd, req_len);
-       return;
+       if (bnxt_rcv_msg_from_vf(bp, fw_vf_id - bp->pf.first_vf_id, fwd_cmd) ==
+           true) {
+               /* Forward */
+               rc = bnxt_hwrm_exec_fwd_resp(bp, fw_vf_id, fwd_cmd, req_len);
+               if (rc) {
+                       RTE_LOG(ERR, PMD,
+                               "Failed to send FWD req VF 0x%x, type 0x%x.\n",
+                               fw_vf_id - bp->pf.first_vf_id,
+                               rte_le_to_cpu_16(fwd_cmd->req_type));
+               }
+               return;
+       }
 
 reject:
-       bnxt_hwrm_reject_fwd_resp(bp, vf_id, fwd_cmd, req_len);
+       rc = bnxt_hwrm_reject_fwd_resp(bp, fw_vf_id, fwd_cmd, req_len);
+       if (rc) {
+               RTE_LOG(ERR, PMD,
+                       "Failed to send REJECT req VF 0x%x, type 0x%x.\n",
+                       fw_vf_id - bp->pf.first_vf_id,
+                       rte_le_to_cpu_16(fwd_cmd->req_type));
+       }
+
        return;
 }
 
diff --git a/drivers/net/bnxt/bnxt_ethdev.c b/drivers/net/bnxt/bnxt_ethdev.c
index b7732e0..ea5e11c 100644
--- a/drivers/net/bnxt/bnxt_ethdev.c
+++ b/drivers/net/bnxt/bnxt_ethdev.c
@@ -52,6 +52,7 @@
 #include "bnxt_txr.h"
 #include "bnxt_vnic.h"
 #include "hsi_struct_def_dpdk.h"
+#include "rte_pmd_bnxt.h"
 
 #define DRV_MODULE_NAME                "bnxt"
 static const char bnxt_version[] =
diff --git a/drivers/net/bnxt/bnxt_hwrm.c b/drivers/net/bnxt/bnxt_hwrm.c
index 02e483e..f0107d6 100644
--- a/drivers/net/bnxt/bnxt_hwrm.c
+++ b/drivers/net/bnxt/bnxt_hwrm.c
@@ -128,7 +128,7 @@ static int bnxt_hwrm_send_message_locked(struct bnxt *bp, 
void *msg,
        }
 
        if (i >= HWRM_CMD_TIMEOUT) {
-               RTE_LOG(ERR, PMD, "Error sending msg %x\n",
+               RTE_LOG(ERR, PMD, "Error sending msg 0x%04x\n",
                        req->req_type);
                goto err_ret;
        }
@@ -333,6 +333,8 @@ int bnxt_hwrm_func_qcaps(struct bnxt *bp)
        bp->max_l2_ctx = rte_le_to_cpu_16(resp->max_l2_ctxs);
        bp->max_vnics = rte_le_to_cpu_16(resp->max_vnics);
        bp->max_stat_ctx = rte_le_to_cpu_16(resp->max_stat_ctx);
+       if (BNXT_PF(bp))
+               bp->pf.total_vnics = rte_le_to_cpu_16(resp->max_vnics);
 
        return rc;
 }
@@ -851,10 +853,11 @@ int bnxt_hwrm_vnic_alloc(struct bnxt *bp, struct 
bnxt_vnic_info *vnic)
                }
                vnic->fw_grp_ids[j] = bp->grp_info[i].fw_grp_id;
        }
-
+       vnic->dflt_ring_grp = bp->grp_info[vnic->start_grp_id].fw_grp_id;
        vnic->fw_rss_cos_lb_ctx = (uint16_t)HWRM_NA_SIGNATURE;
        vnic->ctx_is_rss_cos_lb = HW_CONTEXT_NONE;
-
+       vnic->mru = bp->eth_dev->data->mtu + ETHER_HDR_LEN +
+                               ETHER_CRC_LEN + VLAN_TAG_SIZE;
        HWRM_PREP(req, VNIC_ALLOC, -1, resp);
 
        rc = bnxt_hwrm_send_message(bp, &req, sizeof(req));
@@ -892,11 +895,47 @@ int bnxt_hwrm_vnic_cfg(struct bnxt *bp, struct 
bnxt_vnic_info *vnic)
        if (vnic->vlan_strip)
                req.flags |=
                    rte_cpu_to_le_32(HWRM_VNIC_CFG_INPUT_FLAGS_VLAN_STRIP_MODE);
+       if (vnic->bd_stall)
+               req.flags |=
+                   rte_cpu_to_le_32(HWRM_VNIC_CFG_INPUT_FLAGS_BD_STALL_MODE);
+
+       rc = bnxt_hwrm_send_message(bp, &req, sizeof(req));
+
+       HWRM_CHECK_RESULT;
+
+       return rc;
+}
+
+int bnxt_hwrm_vnic_qcfg(struct bnxt *bp, struct bnxt_vnic_info *vnic,
+               int16_t fw_vf_id)
+{
+       int rc = 0;
+       struct hwrm_vnic_qcfg_input req = {.req_type = 0 };
+       struct hwrm_vnic_qcfg_output *resp = bp->hwrm_cmd_resp_addr;
+
+       HWRM_PREP(req, VNIC_QCFG, -1, resp);
+
+       req.enables =
+               rte_cpu_to_le_32(HWRM_VNIC_QCFG_INPUT_ENABLES_VF_ID_VALID);
+       req.vnic_id = rte_cpu_to_le_16(vnic->fw_vnic_id);
+       req.vf_id = rte_cpu_to_le_16(fw_vf_id);
 
        rc = bnxt_hwrm_send_message(bp, &req, sizeof(req));
 
        HWRM_CHECK_RESULT;
 
+       vnic->dflt_ring_grp = rte_le_to_cpu_16(resp->dflt_ring_grp);
+       vnic->fw_rss_cos_lb_ctx = rte_le_to_cpu_16(resp->rss_rule);
+       // vnic->cos_rule = rte_le_to_cpu_16(resp->cos_rule);
+       // vnic->lb_rule = rte_le_to_cpu_16(resp->lb_rule);
+       vnic->mru = rte_le_to_cpu_16(resp->mru);
+       vnic->func_default = rte_le_to_cpu_32(resp->flags) &
+               HWRM_VNIC_QCFG_OUTPUT_FLAGS_DEFAULT;
+       vnic->vlan_strip = rte_le_to_cpu_32(resp->flags) &
+               HWRM_VNIC_QCFG_OUTPUT_FLAGS_VLAN_STRIP_MODE;
+       vnic->bd_stall = rte_le_to_cpu_32(resp->flags) &
+               HWRM_VNIC_QCFG_OUTPUT_FLAGS_BD_STALL_MODE;
+
        return rc;
 }
 
@@ -983,6 +1022,56 @@ int bnxt_hwrm_vnic_rss_cfg(struct bnxt *bp,
        return rc;
 }
 
+int bnxt_hwrm_func_vf_stall(struct bnxt *bp, uint16_t vf, uint8_t on)
+{
+       struct hwrm_func_vf_vnic_ids_query_input req = {0};
+       struct hwrm_func_vf_vnic_ids_query_output *resp =
+                                               bp->hwrm_cmd_resp_addr;
+       struct bnxt_vnic_info vnic;
+       int rc;
+       uint32_t i, num_vnic_ids;
+       uint16_t *vnic_ids;
+
+       /* First query all VNIC ids */
+
+       vnic_ids = rte_malloc("bnxt_hwrm_vf_vnic_ids_query",
+                             bp->pf.total_vnics * sizeof(*vnic_ids),
+                             RTE_CACHE_LINE_SIZE);
+       if (vnic_ids == NULL)
+               return -ENOMEM;
+
+       HWRM_PREP(req, FUNC_VF_VNIC_IDS_QUERY, -1, resp_vf_vnic_ids);
+
+       req.vf_id = rte_cpu_to_le_16(bp->pf.first_vf_id + vf);
+       req.max_vnic_id_cnt = rte_cpu_to_le_32(bp->pf.total_vnics);
+       req.vnic_id_tbl_addr = rte_malloc_virt2phy(vnic_ids);
+
+       rc = bnxt_hwrm_send_message(bp, &req, sizeof(req));
+       HWRM_CHECK_RESULT;
+
+       num_vnic_ids = rte_le_to_cpu_32(resp->vnic_id_cnt);
+
+       /* Retrieve VNIC, update bd_stall then update */
+
+       for (i = 0; i < num_vnic_ids; i++) {
+               memset(&vnic, 0, sizeof(struct bnxt_vnic_info));
+               vnic.fw_vnic_id = rte_le_to_cpu_16(vnic_ids[i]);
+               rc = bnxt_hwrm_vnic_qcfg(bp, &vnic, bp->pf.first_vf_id + vf);
+               if (rc)
+                       break;
+
+               vnic.bd_stall = on;
+
+               rc = bnxt_hwrm_vnic_cfg(bp, &vnic);
+               if (rc)
+                       break;
+       }
+
+       rte_free(vnic_ids);
+
+       return rc;
+}
+
 int bnxt_hwrm_func_buf_rgtr(struct bnxt *bp)
 {
        int rc = 0;
@@ -1812,6 +1901,7 @@ static int update_pf_resource_max(struct bnxt *bp)
        HWRM_CHECK_RESULT;
 
        bp->max_tx_rings = rte_le_to_cpu_16(resp->alloc_tx_rings);
+       bp->pf.evb_mode = resp->evb_mode;
        /* TODO: Only TX ring value reflects actual allocation */
        //bp->pf.active_vfs = rte_le_to_cpu_16(resp->alloc_vfs);
        //bp->max_rx_rings = rte_le_to_cpu_16(resp->alloc_rx_rings);
@@ -1943,3 +2033,21 @@ int bnxt_hwrm_allocate_vfs(struct bnxt *bp, int num_vfs)
        bnxt_hwrm_func_buf_unrgtr(bp);
        return rc;
 }
+
+int bnxt_hwrm_pf_evb_mode(struct bnxt *bp)
+{
+       struct hwrm_func_cfg_input req = {0};
+       struct hwrm_func_cfg_output *resp = bp->hwrm_cmd_resp_addr;
+       int rc;
+
+       HWRM_PREP(req, FUNC_CFG, -1, resp);
+
+       req.fid = rte_cpu_to_le_16(0xffff);
+       req.enables = rte_cpu_to_le_32(HWRM_FUNC_CFG_INPUT_ENABLES_EVB_MODE);
+       req.evb_mode = bp->pf.evb_mode;
+
+       rc = bnxt_hwrm_send_message(bp, &req, sizeof(req));
+       HWRM_CHECK_RESULT;
+
+       return rc;
+}
diff --git a/drivers/net/bnxt/bnxt_hwrm.h b/drivers/net/bnxt/bnxt_hwrm.h
index 6ae2380..b7c5b34 100644
--- a/drivers/net/bnxt/bnxt_hwrm.h
+++ b/drivers/net/bnxt/bnxt_hwrm.h
@@ -85,6 +85,8 @@ int bnxt_hwrm_ver_get(struct bnxt *bp);
 
 int bnxt_hwrm_vnic_alloc(struct bnxt *bp, struct bnxt_vnic_info *vnic);
 int bnxt_hwrm_vnic_cfg(struct bnxt *bp, struct bnxt_vnic_info *vnic);
+int bnxt_hwrm_vnic_qcfg(struct bnxt *bp, struct bnxt_vnic_info *vnic,
+                               int16_t fw_vf_id);
 int bnxt_hwrm_vnic_ctx_alloc(struct bnxt *bp, struct bnxt_vnic_info *vnic);
 int bnxt_hwrm_vnic_ctx_free(struct bnxt *bp, struct bnxt_vnic_info *vnic);
 int bnxt_hwrm_vnic_free(struct bnxt *bp, struct bnxt_vnic_info *vnic);
@@ -107,5 +109,7 @@ int bnxt_set_hwrm_link_config(struct bnxt *bp, bool 
link_up);
 int bnxt_hwrm_func_qcfg(struct bnxt *bp);
 int bnxt_hwrm_allocate_pf_only(struct bnxt *bp);
 int bnxt_hwrm_allocate_vfs(struct bnxt *bp, int num_vfs);
+int bnxt_hwrm_func_vf_stall(struct bnxt *bp, uint16_t vf, uint8_t on);
+int bnxt_hwrm_pf_evb_mode(struct bnxt *bp);
 
 #endif
diff --git a/drivers/net/bnxt/bnxt_irq.c b/drivers/net/bnxt/bnxt_irq.c
index 2842ba8..86f844c 100644
--- a/drivers/net/bnxt/bnxt_irq.c
+++ b/drivers/net/bnxt/bnxt_irq.c
@@ -104,7 +104,8 @@ void bnxt_disable_int(struct bnxt *bp)
        struct bnxt_cp_ring_info *cpr = bp->def_cp_ring;
 
        /* Only the default completion ring */
-       B_CP_DIS_DB(cpr, cpr->cp_raw_cons);
+       if (cpr != NULL && cpr->cp_doorbell != NULL)
+               B_CP_DIS_DB(cpr, cpr->cp_raw_cons);
 }
 
 void bnxt_enable_int(struct bnxt *bp)
diff --git a/drivers/net/bnxt/bnxt_vnic.h b/drivers/net/bnxt/bnxt_vnic.h
index 9671ba4..6f099a9 100644
--- a/drivers/net/bnxt/bnxt_vnic.h
+++ b/drivers/net/bnxt/bnxt_vnic.h
@@ -51,6 +51,8 @@ struct bnxt_vnic_info {
        uint16_t        start_grp_id;
        uint16_t        end_grp_id;
        uint16_t        fw_grp_ids[MAX_QUEUES_PER_VNIC];
+       uint16_t        dflt_ring_grp;
+       uint16_t        mru;
        uint16_t        hash_type;
        phys_addr_t     rss_table_dma_addr;
        uint16_t        *rss_table;
@@ -62,6 +64,7 @@ struct bnxt_vnic_info {
 
        bool            vlan_strip;
        bool            func_default;
+       bool            bd_stall;
 
        STAILQ_HEAD(, bnxt_filter_info) filter;
 };
diff --git a/drivers/net/bnxt/rte_pmd_bnxt.c b/drivers/net/bnxt/rte_pmd_bnxt.c
new file mode 100644
index 0000000..679e2c1
--- /dev/null
+++ b/drivers/net/bnxt/rte_pmd_bnxt.c
@@ -0,0 +1,143 @@
+/*-
+ *   BSD LICENSE
+ *
+ *   Copyright(c) Broadcom Limited.
+ *   All rights reserved.
+ *
+ *   Redistribution and use in source and binary forms, with or without
+ *   modification, are permitted provided that the following conditions
+ *   are met:
+ *
+ *     * Redistributions of source code must retain the above copyright
+ *       notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above copyright
+ *       notice, this list of conditions and the following disclaimer in
+ *       the documentation and/or other materials provided with the
+ *       distribution.
+ *     * Neither the name of Broadcom Corporation nor the names of its
+ *       contributors may be used to endorse or promote products derived
+ *       from this software without specific prior written permission.
+ *
+ *   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ *   "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ *   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ *   A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ *   OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ *   SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ *   LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ *   DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ *   THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ *   (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ *   OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <inttypes.h>
+#include <stdbool.h>
+
+#include <rte_dev.h>
+#include <rte_ethdev.h>
+#include <rte_malloc.h>
+#include <rte_cycles.h>
+#include <rte_byteorder.h>
+
+#include "bnxt.h"
+#include "bnxt_filter.h"
+#include "bnxt_hwrm.h"
+#include "bnxt_vnic.h"
+#include "rte_pmd_bnxt.h"
+#include "hsi_struct_def_dpdk.h"
+
+int rte_pmd_bnxt_set_tx_loopback(uint8_t port, uint8_t on)
+{
+       struct rte_eth_dev *eth_dev;
+       struct bnxt *bp;
+       int rc;
+
+       RTE_ETH_VALID_PORTID_OR_ERR_RET(port, -ENODEV);
+
+       if (on > 1)
+               return -EINVAL;
+
+       eth_dev = &rte_eth_devices[port];
+       bp = (struct bnxt *)eth_dev->data->dev_private;
+
+       if (!BNXT_PF(bp)) {
+               RTE_LOG(ERR, PMD,
+                       "Attempt to set Tx loopback on non-PF port %d!\n",
+                       port);
+               return -ENOTSUP;
+       }
+
+       if (on)
+               bp->pf.evb_mode = BNXT_EVB_MODE_VEB;
+       else
+               bp->pf.evb_mode = BNXT_EVB_MODE_VEPA;
+
+       rc = bnxt_hwrm_pf_evb_mode(bp);
+
+       return rc;
+}
+
+int rte_pmd_bnxt_set_all_queues_drop_en(uint8_t port, uint8_t on)
+{
+       struct rte_eth_dev *eth_dev;
+       struct bnxt *bp;
+       uint32_t i;
+       int rc;
+
+       RTE_ETH_VALID_PORTID_OR_ERR_RET(port, -ENODEV);
+
+       if (on > 1)
+               return -EINVAL;
+
+       eth_dev = &rte_eth_devices[port];
+       bp = (struct bnxt *)eth_dev->data->dev_private;
+
+       if (!BNXT_PF(bp)) {
+               RTE_LOG(ERR, PMD,
+                       "Attempt to set all queues drop on non-PF port!\n");
+               return -ENOTSUP;
+       }
+
+       if (bp->vnic_info == NULL)
+               return -ENODEV;
+
+       /* Stall PF */
+       for (i = 0; i < bp->nr_vnics; i++) {
+               bp->vnic_info[i].bd_stall = !on;
+               rc = bnxt_hwrm_vnic_cfg(bp, &bp->vnic_info[i]);
+               if (rc) {
+                       RTE_LOG(ERR, PMD, "Failed to update PF VNIC %d.\n", i);
+                       return rc;
+               }
+       }
+
+       /* Stall all active VFs */
+       for (i = 0; i < bp->pf.active_vfs; i++) {
+               rc = bnxt_hwrm_func_vf_stall(bp, i, !on);
+               if (rc) {
+                       RTE_LOG(ERR, PMD, "Failed to update VF VNIC %d.\n", i);
+                       break;
+               }
+       }
+
+       return rc;
+}
+
+int bnxt_rcv_msg_from_vf(struct bnxt *bp, uint16_t vf_id, void *msg)
+{
+       struct rte_pmd_bnxt_mb_event_param cb_param;
+
+       cb_param.retval = RTE_PMD_BNXT_MB_EVENT_PROCEED;
+       cb_param.vf_id = vf_id;
+       cb_param.msg = msg;
+
+       _rte_eth_dev_callback_process(bp->eth_dev, RTE_ETH_EVENT_VF_MBOX,
+                       &cb_param);
+
+       /* Default to approve */
+       if (cb_param.retval == RTE_PMD_BNXT_MB_EVENT_PROCEED)
+               cb_param.retval = RTE_PMD_BNXT_MB_EVENT_NOOP_ACK;
+
+       return cb_param.retval == RTE_PMD_BNXT_MB_EVENT_NOOP_ACK ? true : false;
+}
diff --git a/drivers/net/bnxt/rte_pmd_bnxt.h b/drivers/net/bnxt/rte_pmd_bnxt.h
new file mode 100644
index 0000000..4394a66
--- /dev/null
+++ b/drivers/net/bnxt/rte_pmd_bnxt.h
@@ -0,0 +1,98 @@
+/*-
+ *   BSD LICENSE
+ *
+ *   Copyright(c) Broadcom Limited.
+ *   All rights reserved.
+ *
+ *   Redistribution and use in source and binary forms, with or without
+ *   modification, are permitted provided that the following conditions
+ *   are met:
+ *
+ *     * Redistributions of source code must retain the above copyright
+ *       notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above copyright
+ *       notice, this list of conditions and the following disclaimer in
+ *       the documentation and/or other materials provided with the
+ *       distribution.
+ *     * Neither the name of Broadcom Corporation nor the names of its
+ *       contributors may be used to endorse or promote products derived
+ *       from this software without specific prior written permission.
+ *
+ *   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ *   "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ *   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ *   A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ *   OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ *   SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ *   LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ *   DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ *   THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ *   (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ *   OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef _PMD_BNXT_H_
+#define _PMD_BNXT_H_
+
+#include <rte_ethdev.h>
+
+/**
+ * Response sent back to bnxt driver from user app after callback
+ */
+enum rte_pmd_bnxt_mb_event_rsp {
+       RTE_PMD_BNXT_MB_EVENT_NOOP_ACK,  /**< skip mbox request and ACK */
+       RTE_PMD_BNXT_MB_EVENT_NOOP_NACK, /**< skip mbox request and NACK */
+       RTE_PMD_BNXT_MB_EVENT_PROCEED,  /**< proceed with mbox request  */
+       RTE_PMD_BNXT_MB_EVENT_MAX       /**< max value of this enum */
+};
+
+/* mailbox message types */
+#define BNXT_VF_RESET                  0x01 /* VF requests reset */
+#define BNXT_VF_SET_MAC_ADDR           0x02 /* VF requests PF to set MAC */
+#define BNXT_VF_SET_VLAN               0x03 /* VF requests PF to set VLAN */
+#define BNXT_VF_SET_MTU                        0x04 /* VF requests PF to set 
MTU */
+#define BNXT_VF_SET_MRU                        0x05 /* VF requests PF to set 
MRU */
+/* TODO expose more */
+
+/**
+ * Data sent to the user application when the callback is executed.
+ */
+struct rte_pmd_bnxt_mb_event_param {
+       uint16_t                vf_id;     /**< Virtual Function number */
+       int16_t                 retval;   /**< return value */
+       void                    *msg;      /**< pointer to message */
+};
+
+/**
+ * Enable/Disable tx loopback
+ *
+ * @param port
+ *    The port identifier of the Ethernet device.
+ * @param on
+ *    1 - Enable tx loopback.
+ *    0 - Disable tx loopback.
+ *
+ * @return
+ *   - (0) if successful.
+ *   - (-ENODEV) if *port* invalid.
+ *   - (-EINVAL) if bad parameter.
+ */
+int rte_pmd_bnxt_set_tx_loopback(uint8_t port, uint8_t on);
+
+/**
+ * set all queues drop enable bit
+ *
+ * @param port
+ *    The port identifier of the Ethernet device.
+ * @param on
+ *    1 - set the queue drop enable bit for all pools.
+ *    0 - reset the queue drop enable bit for all pools.
+ *
+ * @return
+ *   - (0) if successful.
+ *   - (-ENODEV) if *port* invalid.
+ *   - (-EINVAL) if bad parameter.
+ */
+int rte_pmd_bnxt_set_all_queues_drop_en(uint8_t port, uint8_t on);
+
+#endif /* _PMD_BNXT_H_ */
diff --git a/drivers/net/bnxt/rte_pmd_bnxt_version.map 
b/drivers/net/bnxt/rte_pmd_bnxt_version.map
index 349c6e1..6bfafaa 100644
--- a/drivers/net/bnxt/rte_pmd_bnxt_version.map
+++ b/drivers/net/bnxt/rte_pmd_bnxt_version.map
@@ -1,4 +1,7 @@
-DPDK_16.04 {
+DPDK_17.05 {
+       global:
 
-       local: *;
+       rte_pmd_bnxt_set_tx_loopback;
+       rte_pmd_bnxt_set_all_queues_drop_en;
 };
+
-- 
2.10.1 (Apple Git-78)

Reply via email to