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 <ajit.khaparde@broadcom.com>
This commit is contained in:
Ajit Khaparde 2017-06-30 09:20:13 -05:00 committed by Ferruh Yigit
parent 3aec2d14d6
commit 1cd45aeb32
4 changed files with 80 additions and 4 deletions

View File

@ -162,6 +162,7 @@ struct bnxt_cos_queue_info {
uint8_t profile; uint8_t profile;
}; };
#define BNXT_HWRM_SHORT_REQ_LEN sizeof(struct hwrm_short_input)
struct bnxt { struct bnxt {
void *bar0; void *bar0;
@ -173,6 +174,7 @@ struct bnxt {
#define BNXT_FLAG_VF (1 << 1) #define BNXT_FLAG_VF (1 << 1)
#define BNXT_FLAG_PORT_STATS (1 << 2) #define BNXT_FLAG_PORT_STATS (1 << 2)
#define BNXT_FLAG_JUMBO (1 << 3) #define BNXT_FLAG_JUMBO (1 << 3)
#define BNXT_FLAG_SHORT_CMD (1 << 4)
#define BNXT_PF(bp) (!((bp)->flags & BNXT_FLAG_VF)) #define BNXT_PF(bp) (!((bp)->flags & BNXT_FLAG_VF))
#define BNXT_VF(bp) ((bp)->flags & BNXT_FLAG_VF) #define BNXT_VF(bp) ((bp)->flags & BNXT_FLAG_VF)
#define BNXT_NPAR_ENABLED(bp) ((bp)->port_partition_type) #define BNXT_NPAR_ENABLED(bp) ((bp)->port_partition_type)
@ -217,6 +219,8 @@ struct bnxt {
uint16_t hwrm_cmd_seq; uint16_t hwrm_cmd_seq;
void *hwrm_cmd_resp_addr; void *hwrm_cmd_resp_addr;
phys_addr_t hwrm_cmd_resp_dma_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; rte_spinlock_t hwrm_lock;
uint16_t max_req_len; uint16_t max_req_len;
uint16_t max_resp_len; uint16_t max_resp_len;

View File

@ -60,6 +60,7 @@ static const char bnxt_version[] =
#define PCI_VENDOR_ID_BROADCOM 0x14E4 #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_STRATUS_NIC 0x1614
#define BROADCOM_DEV_ID_57414_VF 0x16c1 #define BROADCOM_DEV_ID_57414_VF 0x16c1
#define BROADCOM_DEV_ID_57301 0x16c8 #define BROADCOM_DEV_ID_57301 0x16c8
@ -96,6 +97,8 @@ static const char bnxt_version[] =
#define BROADCOM_DEV_ID_57416_MF 0x16ee #define BROADCOM_DEV_ID_57416_MF 0x16ee
static const struct rte_pci_id bnxt_pci_id_map[] = { 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_STRATUS_NIC) },
{ RTE_PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, BROADCOM_DEV_ID_57414_VF) }, { RTE_PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, BROADCOM_DEV_ID_57414_VF) },
{ RTE_PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, BROADCOM_DEV_ID_57301) }, { 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_57406_VF ||
id == BROADCOM_DEV_ID_5731X_VF || id == BROADCOM_DEV_ID_5731X_VF ||
id == BROADCOM_DEV_ID_5741X_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 true;
return false; return false;
} }

View File

@ -106,6 +106,30 @@ static int bnxt_hwrm_send_message_locked(struct bnxt *bp, void *msg,
uint32_t *data = msg; uint32_t *data = msg;
uint8_t *bar; uint8_t *bar;
uint8_t *valid; 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 */ /* Write request msg to hwrm channel */
for (i = 0; i < msg_len; i += 4) { 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 */ /* 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; bar = (uint8_t *)bp->bar0 + i;
rte_write32(0, bar); rte_write32(0, bar);
} }
@ -457,7 +481,9 @@ int bnxt_hwrm_ver_get(struct bnxt *bp)
uint32_t fw_version; uint32_t fw_version;
uint16_t max_resp_len; uint16_t max_resp_len;
char type[RTE_MEMZONE_NAMESIZE]; 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); HWRM_PREP(req, VER_GET, -1, resp);
req.hwrm_intf_maj = HWRM_VERSION_MAJOR; 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"); RTE_LOG(ERR, PMD, "Unsupported request length\n");
rc = -EINVAL; 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; 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) { if (bp->max_resp_len != max_resp_len) {
sprintf(type, "bnxt_hwrm_%04x:%02x:%02x:%02x", sprintf(type, "bnxt_hwrm_%04x:%02x:%02x:%02x",
bp->pdev->addr.domain, bp->pdev->addr.bus, 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; 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: error:
rte_spinlock_unlock(&bp->hwrm_lock); rte_spinlock_unlock(&bp->hwrm_lock);
return rc; return rc;
@ -1529,8 +1585,11 @@ void bnxt_free_hwrm_resources(struct bnxt *bp)
{ {
/* Release memzone */ /* Release memzone */
rte_free(bp->hwrm_cmd_resp_addr); rte_free(bp->hwrm_cmd_resp_addr);
rte_free(bp->hwrm_short_cmd_req_addr);
bp->hwrm_cmd_resp_addr = NULL; bp->hwrm_cmd_resp_addr = NULL;
bp->hwrm_short_cmd_req_addr = NULL;
bp->hwrm_cmd_resp_dma_addr = 0; bp->hwrm_cmd_resp_dma_addr = 0;
bp->hwrm_short_cmd_req_dma_addr = 0;
} }
int bnxt_alloc_hwrm_resources(struct bnxt *bp) 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, sprintf(type, "bnxt_hwrm_%04x:%02x:%02x:%02x", pdev->addr.domain,
pdev->addr.bus, pdev->addr.devid, pdev->addr.function); 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->max_resp_len = HWRM_MAX_RESP_LEN;
bp->hwrm_cmd_resp_addr = rte_malloc(type, bp->max_resp_len, 0); bp->hwrm_cmd_resp_addr = rte_malloc(type, bp->max_resp_len, 0);
rte_mem_lock_page(bp->hwrm_cmd_resp_addr); rte_mem_lock_page(bp->hwrm_cmd_resp_addr);

View File

@ -10300,6 +10300,16 @@ struct output {
*/ */
} __attribute__((packed)); } __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) \ #define HWRM_GET_HWRM_ERROR_CODE(arg) \
{ \ { \
typeof(arg) x = (arg); \ typeof(arg) x = (arg); \