net/bnxt: support Stratus VF device
authorAjit Khaparde <ajit.khaparde@broadcom.com>
Fri, 30 Jun 2017 14:20:13 +0000 (09:20 -0500)
committerFerruh Yigit <ferruh.yigit@intel.com>
Thu, 6 Jul 2017 13:00:57 +0000 (15:00 +0200)
This patch adds support for Stratus VF devices.
Other than adding the VF device ID, we also are adding
support for short message format.

The new short firmware message of size 16 bytes points to a location
in host memory that contains the firmware message that the driver
wants the adapter to process. This indirection requires the
firmware to DMA the message into its own memory for processing.

When the firmware receives a Short Command Format, it will DMA the
firmware message from host memory into its internal memory and then
processes the message as it would have if it received the message
directly in the firmware communication channel.

With BCM57454, the number of VFs increase to 1K and so the requirement
for firmware communication channel memory on adapter becomes expensive.
The short firmware message saves the amount of memory required to support
1K VFs on adapter.

Signed-off-by: Ajit Khaparde <ajit.khaparde@broadcom.com>
drivers/net/bnxt/bnxt.h
drivers/net/bnxt/bnxt_ethdev.c
drivers/net/bnxt/bnxt_hwrm.c
drivers/net/bnxt/hsi_struct_def_dpdk.h

index 1538aa5..d39baf1 100644 (file)
@@ -162,6 +162,7 @@ struct bnxt_cos_queue_info {
        uint8_t profile;
 };
 
+#define BNXT_HWRM_SHORT_REQ_LEN                sizeof(struct hwrm_short_input)
 struct bnxt {
        void                            *bar0;
 
@@ -173,6 +174,7 @@ struct bnxt {
 #define BNXT_FLAG_VF           (1 << 1)
 #define BNXT_FLAG_PORT_STATS   (1 << 2)
 #define BNXT_FLAG_JUMBO                (1 << 3)
+#define BNXT_FLAG_SHORT_CMD    (1 << 4)
 #define BNXT_PF(bp)            (!((bp)->flags & BNXT_FLAG_VF))
 #define BNXT_VF(bp)            ((bp)->flags & BNXT_FLAG_VF)
 #define BNXT_NPAR_ENABLED(bp)  ((bp)->port_partition_type)
@@ -217,6 +219,8 @@ struct bnxt {
        uint16_t                        hwrm_cmd_seq;
        void                            *hwrm_cmd_resp_addr;
        phys_addr_t                     hwrm_cmd_resp_dma_addr;
+       void                            *hwrm_short_cmd_req_addr;
+       phys_addr_t                     hwrm_short_cmd_req_dma_addr;
        rte_spinlock_t                  hwrm_lock;
        uint16_t                        max_req_len;
        uint16_t                        max_resp_len;
index a2d46ee..c9d1122 100644 (file)
@@ -60,6 +60,7 @@ static const char bnxt_version[] =
 
 #define PCI_VENDOR_ID_BROADCOM 0x14E4
 
+#define BROADCOM_DEV_ID_STRATUS_NIC_VF 0x1609
 #define BROADCOM_DEV_ID_STRATUS_NIC 0x1614
 #define BROADCOM_DEV_ID_57414_VF 0x16c1
 #define BROADCOM_DEV_ID_57301 0x16c8
@@ -96,6 +97,8 @@ static const char bnxt_version[] =
 #define BROADCOM_DEV_ID_57416_MF 0x16ee
 
 static const struct rte_pci_id bnxt_pci_id_map[] = {
+       { RTE_PCI_DEVICE(PCI_VENDOR_ID_BROADCOM,
+                        BROADCOM_DEV_ID_STRATUS_NIC_VF) },
        { RTE_PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, BROADCOM_DEV_ID_STRATUS_NIC) },
        { RTE_PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, BROADCOM_DEV_ID_57414_VF) },
        { RTE_PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, BROADCOM_DEV_ID_57301) },
@@ -1569,7 +1572,8 @@ static bool bnxt_vf_pciid(uint16_t id)
            id == BROADCOM_DEV_ID_57406_VF ||
            id == BROADCOM_DEV_ID_5731X_VF ||
            id == BROADCOM_DEV_ID_5741X_VF ||
-           id == BROADCOM_DEV_ID_57414_VF)
+           id == BROADCOM_DEV_ID_57414_VF ||
+           id == BROADCOM_DEV_ID_STRATUS_NIC_VF)
                return true;
        return false;
 }
index f45b883..e237041 100644 (file)
@@ -106,6 +106,30 @@ static int bnxt_hwrm_send_message_locked(struct bnxt *bp, void *msg,
        uint32_t *data = msg;
        uint8_t *bar;
        uint8_t *valid;
+       uint16_t max_req_len = bp->max_req_len;
+       struct hwrm_short_input short_input = { 0 };
+
+       if (bp->flags & BNXT_FLAG_SHORT_CMD) {
+               void *short_cmd_req = bp->hwrm_short_cmd_req_addr;
+
+               memset(short_cmd_req, 0, bp->max_req_len);
+               memcpy(short_cmd_req, req, msg_len);
+
+               short_input.req_type = rte_cpu_to_le_16(req->req_type);
+               short_input.signature = rte_cpu_to_le_16(
+                                       HWRM_SHORT_REQ_SIGNATURE_SHORT_CMD);
+               short_input.size = rte_cpu_to_le_16(msg_len);
+               short_input.req_addr =
+                       rte_cpu_to_le_64(bp->hwrm_short_cmd_req_dma_addr);
+
+               data = (uint32_t *)&short_input;
+               msg_len = sizeof(short_input);
+
+               /* Sync memory write before updating doorbell */
+               rte_wmb();
+
+               max_req_len = BNXT_HWRM_SHORT_REQ_LEN;
+       }
 
        /* Write request msg to hwrm channel */
        for (i = 0; i < msg_len; i += 4) {
@@ -115,7 +139,7 @@ static int bnxt_hwrm_send_message_locked(struct bnxt *bp, void *msg,
        }
 
        /* Zero the rest of the request space */
-       for (; i < bp->max_req_len; i += 4) {
+       for (; i < max_req_len; i += 4) {
                bar = (uint8_t *)bp->bar0 + i;
                rte_write32(0, bar);
        }
@@ -457,7 +481,9 @@ int bnxt_hwrm_ver_get(struct bnxt *bp)
        uint32_t fw_version;
        uint16_t max_resp_len;
        char type[RTE_MEMZONE_NAMESIZE];
+       uint32_t dev_caps_cfg;
 
+       bp->max_req_len = HWRM_MAX_REQ_LEN;
        HWRM_PREP(req, VER_GET, -1, resp);
 
        req.hwrm_intf_maj = HWRM_VERSION_MAJOR;
@@ -514,8 +540,10 @@ int bnxt_hwrm_ver_get(struct bnxt *bp)
                RTE_LOG(ERR, PMD, "Unsupported request length\n");
                rc = -EINVAL;
        }
-       bp->max_req_len = resp->max_req_win_len;
+       bp->max_req_len = rte_le_to_cpu_16(resp->max_req_win_len);
        max_resp_len = resp->max_resp_len;
+       dev_caps_cfg = rte_le_to_cpu_32(resp->dev_caps_cfg);
+
        if (bp->max_resp_len != max_resp_len) {
                sprintf(type, "bnxt_hwrm_%04x:%02x:%02x:%02x",
                        bp->pdev->addr.domain, bp->pdev->addr.bus,
@@ -540,6 +568,34 @@ int bnxt_hwrm_ver_get(struct bnxt *bp)
                bp->max_resp_len = max_resp_len;
        }
 
+       if ((dev_caps_cfg &
+               HWRM_VER_GET_OUTPUT_DEV_CAPS_CFG_SHORT_CMD_SUPPORTED) &&
+           (dev_caps_cfg &
+            HWRM_VER_GET_OUTPUT_DEV_CAPS_CFG_SHORT_CMD_INPUTUIRED)) {
+               RTE_LOG(DEBUG, PMD, "Short command supported\n");
+
+               rte_free(bp->hwrm_short_cmd_req_addr);
+
+               bp->hwrm_short_cmd_req_addr = rte_malloc(type,
+                                                       bp->max_req_len, 0);
+               if (bp->hwrm_short_cmd_req_addr == NULL) {
+                       rc = -ENOMEM;
+                       goto error;
+               }
+               rte_mem_lock_page(bp->hwrm_short_cmd_req_addr);
+               bp->hwrm_short_cmd_req_dma_addr =
+                       rte_mem_virt2phy(bp->hwrm_short_cmd_req_addr);
+               if (bp->hwrm_short_cmd_req_dma_addr == 0) {
+                       rte_free(bp->hwrm_short_cmd_req_addr);
+                       RTE_LOG(ERR, PMD,
+                               "Unable to map buffer to physical memory.\n");
+                       rc = -ENOMEM;
+                       goto error;
+               }
+
+               bp->flags |= BNXT_FLAG_SHORT_CMD;
+       }
+
 error:
        rte_spinlock_unlock(&bp->hwrm_lock);
        return rc;
@@ -1529,8 +1585,11 @@ void bnxt_free_hwrm_resources(struct bnxt *bp)
 {
        /* Release memzone */
        rte_free(bp->hwrm_cmd_resp_addr);
+       rte_free(bp->hwrm_short_cmd_req_addr);
        bp->hwrm_cmd_resp_addr = NULL;
+       bp->hwrm_short_cmd_req_addr = NULL;
        bp->hwrm_cmd_resp_dma_addr = 0;
+       bp->hwrm_short_cmd_req_dma_addr = 0;
 }
 
 int bnxt_alloc_hwrm_resources(struct bnxt *bp)
@@ -1540,7 +1599,6 @@ int bnxt_alloc_hwrm_resources(struct bnxt *bp)
 
        sprintf(type, "bnxt_hwrm_%04x:%02x:%02x:%02x", pdev->addr.domain,
                pdev->addr.bus, pdev->addr.devid, pdev->addr.function);
-       bp->max_req_len = HWRM_MAX_REQ_LEN;
        bp->max_resp_len = HWRM_MAX_RESP_LEN;
        bp->hwrm_cmd_resp_addr = rte_malloc(type, bp->max_resp_len, 0);
        rte_mem_lock_page(bp->hwrm_cmd_resp_addr);
index e082d33..c2335d0 100644 (file)
@@ -10300,6 +10300,16 @@ struct output {
         */
 } __attribute__((packed));
 
+/* Short Command Structure (16 bytes) */
+struct hwrm_short_input {
+       uint16_t req_type;
+       uint16_t signature;
+       #define HWRM_SHORT_REQ_SIGNATURE_SHORT_CMD      (UINT32_C(0x4321))
+       uint16_t unused_0;
+       uint16_t size;
+       uint64_t req_addr;
+} __attribute__((packed));
+
 #define HWRM_GET_HWRM_ERROR_CODE(arg) \
        { \
                typeof(arg) x = (arg); \