forked from Minki/linux
bnxt_en: Support for Short Firmware Message
The new short message format is used on the new BCM57454 VFs. Each firmware message is a fixed 16-byte message sent using the standard firmware communication channel. The short message has a DMA address pointing to the legacy long firmware message. Signed-off-by: Deepak Khungar <deepak.khungar@broadcom.com> Signed-off-by: Michael Chan <michael.chan@broadcom.com> Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:
parent
e6cbef0ced
commit
e605db801b
@ -2868,6 +2868,32 @@ static int bnxt_alloc_hwrm_resources(struct bnxt *bp)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void bnxt_free_hwrm_short_cmd_req(struct bnxt *bp)
|
||||||
|
{
|
||||||
|
if (bp->hwrm_short_cmd_req_addr) {
|
||||||
|
struct pci_dev *pdev = bp->pdev;
|
||||||
|
|
||||||
|
dma_free_coherent(&pdev->dev, BNXT_HWRM_MAX_REQ_LEN,
|
||||||
|
bp->hwrm_short_cmd_req_addr,
|
||||||
|
bp->hwrm_short_cmd_req_dma_addr);
|
||||||
|
bp->hwrm_short_cmd_req_addr = NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static int bnxt_alloc_hwrm_short_cmd_req(struct bnxt *bp)
|
||||||
|
{
|
||||||
|
struct pci_dev *pdev = bp->pdev;
|
||||||
|
|
||||||
|
bp->hwrm_short_cmd_req_addr =
|
||||||
|
dma_alloc_coherent(&pdev->dev, BNXT_HWRM_MAX_REQ_LEN,
|
||||||
|
&bp->hwrm_short_cmd_req_dma_addr,
|
||||||
|
GFP_KERNEL);
|
||||||
|
if (!bp->hwrm_short_cmd_req_addr)
|
||||||
|
return -ENOMEM;
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
static void bnxt_free_stats(struct bnxt *bp)
|
static void bnxt_free_stats(struct bnxt *bp)
|
||||||
{
|
{
|
||||||
u32 size, i;
|
u32 size, i;
|
||||||
@ -3215,16 +3241,41 @@ static int bnxt_hwrm_do_send_msg(struct bnxt *bp, void *msg, u32 msg_len,
|
|||||||
__le32 *resp_len, *valid;
|
__le32 *resp_len, *valid;
|
||||||
u16 cp_ring_id, len = 0;
|
u16 cp_ring_id, len = 0;
|
||||||
struct hwrm_err_output *resp = bp->hwrm_cmd_resp_addr;
|
struct hwrm_err_output *resp = bp->hwrm_cmd_resp_addr;
|
||||||
|
u16 max_req_len = BNXT_HWRM_MAX_REQ_LEN;
|
||||||
|
|
||||||
req->seq_id = cpu_to_le16(bp->hwrm_cmd_seq++);
|
req->seq_id = cpu_to_le16(bp->hwrm_cmd_seq++);
|
||||||
memset(resp, 0, PAGE_SIZE);
|
memset(resp, 0, PAGE_SIZE);
|
||||||
cp_ring_id = le16_to_cpu(req->cmpl_ring);
|
cp_ring_id = le16_to_cpu(req->cmpl_ring);
|
||||||
intr_process = (cp_ring_id == INVALID_HW_RING_ID) ? 0 : 1;
|
intr_process = (cp_ring_id == INVALID_HW_RING_ID) ? 0 : 1;
|
||||||
|
|
||||||
|
if (bp->flags & BNXT_FLAG_SHORT_CMD) {
|
||||||
|
void *short_cmd_req = bp->hwrm_short_cmd_req_addr;
|
||||||
|
struct hwrm_short_input short_input = {0};
|
||||||
|
|
||||||
|
memcpy(short_cmd_req, req, msg_len);
|
||||||
|
memset(short_cmd_req + msg_len, 0, BNXT_HWRM_MAX_REQ_LEN -
|
||||||
|
msg_len);
|
||||||
|
|
||||||
|
short_input.req_type = req->req_type;
|
||||||
|
short_input.signature =
|
||||||
|
cpu_to_le16(SHORT_REQ_SIGNATURE_SHORT_CMD);
|
||||||
|
short_input.size = cpu_to_le16(msg_len);
|
||||||
|
short_input.req_addr =
|
||||||
|
cpu_to_le64(bp->hwrm_short_cmd_req_dma_addr);
|
||||||
|
|
||||||
|
data = (u32 *)&short_input;
|
||||||
|
msg_len = sizeof(short_input);
|
||||||
|
|
||||||
|
/* Sync memory write before updating doorbell */
|
||||||
|
wmb();
|
||||||
|
|
||||||
|
max_req_len = BNXT_HWRM_SHORT_REQ_LEN;
|
||||||
|
}
|
||||||
|
|
||||||
/* Write request msg to hwrm channel */
|
/* Write request msg to hwrm channel */
|
||||||
__iowrite32_copy(bp->bar0, data, msg_len / 4);
|
__iowrite32_copy(bp->bar0, data, msg_len / 4);
|
||||||
|
|
||||||
for (i = msg_len; i < BNXT_HWRM_MAX_REQ_LEN; i += 4)
|
for (i = msg_len; i < max_req_len; i += 4)
|
||||||
writel(0, bp->bar0 + i);
|
writel(0, bp->bar0 + i);
|
||||||
|
|
||||||
/* currently supports only one outstanding message */
|
/* currently supports only one outstanding message */
|
||||||
@ -4662,6 +4713,7 @@ static int bnxt_hwrm_ver_get(struct bnxt *bp)
|
|||||||
int rc;
|
int rc;
|
||||||
struct hwrm_ver_get_input req = {0};
|
struct hwrm_ver_get_input req = {0};
|
||||||
struct hwrm_ver_get_output *resp = bp->hwrm_cmd_resp_addr;
|
struct hwrm_ver_get_output *resp = bp->hwrm_cmd_resp_addr;
|
||||||
|
u32 dev_caps_cfg;
|
||||||
|
|
||||||
bp->hwrm_max_req_len = HWRM_MAX_REQ_LEN;
|
bp->hwrm_max_req_len = HWRM_MAX_REQ_LEN;
|
||||||
bnxt_hwrm_cmd_hdr_init(bp, &req, HWRM_VER_GET, -1, -1);
|
bnxt_hwrm_cmd_hdr_init(bp, &req, HWRM_VER_GET, -1, -1);
|
||||||
@ -4699,6 +4751,11 @@ static int bnxt_hwrm_ver_get(struct bnxt *bp)
|
|||||||
!resp->chip_metal)
|
!resp->chip_metal)
|
||||||
bp->flags |= BNXT_FLAG_CHIP_NITRO_A0;
|
bp->flags |= BNXT_FLAG_CHIP_NITRO_A0;
|
||||||
|
|
||||||
|
dev_caps_cfg = le32_to_cpu(resp->dev_caps_cfg);
|
||||||
|
if ((dev_caps_cfg & VER_GET_RESP_DEV_CAPS_CFG_SHORT_CMD_SUPPORTED) &&
|
||||||
|
(dev_caps_cfg & VER_GET_RESP_DEV_CAPS_CFG_SHORT_CMD_REQUIRED))
|
||||||
|
bp->flags |= BNXT_FLAG_SHORT_CMD;
|
||||||
|
|
||||||
hwrm_ver_get_exit:
|
hwrm_ver_get_exit:
|
||||||
mutex_unlock(&bp->hwrm_cmd_lock);
|
mutex_unlock(&bp->hwrm_cmd_lock);
|
||||||
return rc;
|
return rc;
|
||||||
@ -7357,6 +7414,7 @@ static void bnxt_remove_one(struct pci_dev *pdev)
|
|||||||
bnxt_clear_int_mode(bp);
|
bnxt_clear_int_mode(bp);
|
||||||
bnxt_hwrm_func_drv_unrgtr(bp);
|
bnxt_hwrm_func_drv_unrgtr(bp);
|
||||||
bnxt_free_hwrm_resources(bp);
|
bnxt_free_hwrm_resources(bp);
|
||||||
|
bnxt_free_hwrm_short_cmd_req(bp);
|
||||||
bnxt_ethtool_free(bp);
|
bnxt_ethtool_free(bp);
|
||||||
bnxt_dcb_free(bp);
|
bnxt_dcb_free(bp);
|
||||||
kfree(bp->edev);
|
kfree(bp->edev);
|
||||||
@ -7607,6 +7665,12 @@ static int bnxt_init_one(struct pci_dev *pdev, const struct pci_device_id *ent)
|
|||||||
if (rc)
|
if (rc)
|
||||||
goto init_err_pci_clean;
|
goto init_err_pci_clean;
|
||||||
|
|
||||||
|
if (bp->flags & BNXT_FLAG_SHORT_CMD) {
|
||||||
|
rc = bnxt_alloc_hwrm_short_cmd_req(bp);
|
||||||
|
if (rc)
|
||||||
|
goto init_err_pci_clean;
|
||||||
|
}
|
||||||
|
|
||||||
rc = bnxt_hwrm_func_reset(bp);
|
rc = bnxt_hwrm_func_reset(bp);
|
||||||
if (rc)
|
if (rc)
|
||||||
goto init_err_pci_clean;
|
goto init_err_pci_clean;
|
||||||
|
@ -500,6 +500,7 @@ struct rx_tpa_end_cmp_ext {
|
|||||||
#define NEXT_CMP(idx) RING_CMP(ADV_RAW_CMP(idx, 1))
|
#define NEXT_CMP(idx) RING_CMP(ADV_RAW_CMP(idx, 1))
|
||||||
|
|
||||||
#define BNXT_HWRM_MAX_REQ_LEN (bp->hwrm_max_req_len)
|
#define BNXT_HWRM_MAX_REQ_LEN (bp->hwrm_max_req_len)
|
||||||
|
#define BNXT_HWRM_SHORT_REQ_LEN sizeof(struct hwrm_short_input)
|
||||||
#define DFLT_HWRM_CMD_TIMEOUT 500
|
#define DFLT_HWRM_CMD_TIMEOUT 500
|
||||||
#define HWRM_CMD_TIMEOUT (bp->hwrm_cmd_timeout)
|
#define HWRM_CMD_TIMEOUT (bp->hwrm_cmd_timeout)
|
||||||
#define HWRM_RESET_TIMEOUT ((HWRM_CMD_TIMEOUT) * 4)
|
#define HWRM_RESET_TIMEOUT ((HWRM_CMD_TIMEOUT) * 4)
|
||||||
@ -1006,6 +1007,7 @@ struct bnxt {
|
|||||||
#define BNXT_FLAG_RX_PAGE_MODE 0x40000
|
#define BNXT_FLAG_RX_PAGE_MODE 0x40000
|
||||||
#define BNXT_FLAG_FW_LLDP_AGENT 0x80000
|
#define BNXT_FLAG_FW_LLDP_AGENT 0x80000
|
||||||
#define BNXT_FLAG_MULTI_HOST 0x100000
|
#define BNXT_FLAG_MULTI_HOST 0x100000
|
||||||
|
#define BNXT_FLAG_SHORT_CMD 0x200000
|
||||||
#define BNXT_FLAG_CHIP_NITRO_A0 0x1000000
|
#define BNXT_FLAG_CHIP_NITRO_A0 0x1000000
|
||||||
|
|
||||||
#define BNXT_FLAG_ALL_CONFIG_FEATS (BNXT_FLAG_TPA | \
|
#define BNXT_FLAG_ALL_CONFIG_FEATS (BNXT_FLAG_TPA | \
|
||||||
@ -1106,6 +1108,8 @@ struct bnxt {
|
|||||||
u32 hwrm_spec_code;
|
u32 hwrm_spec_code;
|
||||||
u16 hwrm_cmd_seq;
|
u16 hwrm_cmd_seq;
|
||||||
u32 hwrm_intr_seq_id;
|
u32 hwrm_intr_seq_id;
|
||||||
|
void *hwrm_short_cmd_req_addr;
|
||||||
|
dma_addr_t hwrm_short_cmd_req_dma_addr;
|
||||||
void *hwrm_cmd_resp_addr;
|
void *hwrm_cmd_resp_addr;
|
||||||
dma_addr_t hwrm_cmd_resp_dma_addr;
|
dma_addr_t hwrm_cmd_resp_dma_addr;
|
||||||
void *hwrm_dbg_resp_addr;
|
void *hwrm_dbg_resp_addr;
|
||||||
|
Loading…
Reference in New Issue
Block a user