From: Ajit Khaparde Date: Fri, 30 Jun 2017 14:20:13 +0000 (-0500) Subject: net/bnxt: support Stratus VF device X-Git-Url: http://git.droids-corp.org/?a=commitdiff_plain;h=1cd45aeb3270ecb1f20b79810b40244a462bb501;p=dpdk.git net/bnxt: support Stratus VF device 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 --- diff --git a/drivers/net/bnxt/bnxt.h b/drivers/net/bnxt/bnxt.h index 1538aa59a3..d39baf11aa 100644 --- a/drivers/net/bnxt/bnxt.h +++ b/drivers/net/bnxt/bnxt.h @@ -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; diff --git a/drivers/net/bnxt/bnxt_ethdev.c b/drivers/net/bnxt/bnxt_ethdev.c index a2d46eee19..c9d11228be 100644 --- a/drivers/net/bnxt/bnxt_ethdev.c +++ b/drivers/net/bnxt/bnxt_ethdev.c @@ -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; } diff --git a/drivers/net/bnxt/bnxt_hwrm.c b/drivers/net/bnxt/bnxt_hwrm.c index f45b883ae0..e237041ca9 100644 --- a/drivers/net/bnxt/bnxt_hwrm.c +++ b/drivers/net/bnxt/bnxt_hwrm.c @@ -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); diff --git a/drivers/net/bnxt/hsi_struct_def_dpdk.h b/drivers/net/bnxt/hsi_struct_def_dpdk.h index e082d339ae..c2335d06a4 100644 --- a/drivers/net/bnxt/hsi_struct_def_dpdk.h +++ b/drivers/net/bnxt/hsi_struct_def_dpdk.h @@ -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); \