|
@@ -175,6 +175,8 @@ static const struct pci_device_id bnxt_pci_tbl[] = {
|
|
|
{ PCI_VDEVICE(BROADCOM, 0x16f1), .driver_data = BCM57452 },
|
|
|
{ PCI_VDEVICE(BROADCOM, 0x1614), .driver_data = BCM57454 },
|
|
|
#ifdef CONFIG_BNXT_SRIOV
|
|
|
+ { PCI_VDEVICE(BROADCOM, 0x1606), .driver_data = NETXTREME_E_VF },
|
|
|
+ { PCI_VDEVICE(BROADCOM, 0x1609), .driver_data = NETXTREME_E_VF },
|
|
|
{ PCI_VDEVICE(BROADCOM, 0x16c1), .driver_data = NETXTREME_E_VF },
|
|
|
{ PCI_VDEVICE(BROADCOM, 0x16cb), .driver_data = NETXTREME_C_VF },
|
|
|
{ PCI_VDEVICE(BROADCOM, 0x16d3), .driver_data = NETXTREME_E_VF },
|
|
@@ -461,14 +463,17 @@ normal_tx:
|
|
|
prod = NEXT_TX(prod);
|
|
|
txr->tx_prod = prod;
|
|
|
|
|
|
- writel(DB_KEY_TX | prod, txr->tx_doorbell);
|
|
|
- writel(DB_KEY_TX | prod, txr->tx_doorbell);
|
|
|
+ if (!skb->xmit_more)
|
|
|
+ bnxt_db_write(bp, txr->tx_doorbell, DB_KEY_TX | prod);
|
|
|
|
|
|
tx_done:
|
|
|
|
|
|
mmiowb();
|
|
|
|
|
|
if (unlikely(bnxt_tx_avail(bp, txr) <= MAX_SKB_FRAGS + 1)) {
|
|
|
+ if (skb->xmit_more && !tx_buf->is_push)
|
|
|
+ bnxt_db_write(bp, txr->tx_doorbell, DB_KEY_TX | prod);
|
|
|
+
|
|
|
netif_tx_stop_queue(txq);
|
|
|
|
|
|
/* netif_tx_stop_queue() must be done before checking
|
|
@@ -1777,8 +1782,7 @@ static int bnxt_poll_work(struct bnxt *bp, struct bnxt_napi *bnapi, int budget)
|
|
|
/* Sync BD data before updating doorbell */
|
|
|
wmb();
|
|
|
|
|
|
- writel(DB_KEY_TX | prod, db);
|
|
|
- writel(DB_KEY_TX | prod, db);
|
|
|
+ bnxt_db_write(bp, db, DB_KEY_TX | prod);
|
|
|
}
|
|
|
|
|
|
cpr->cp_raw_cons = raw_cons;
|
|
@@ -1794,14 +1798,10 @@ static int bnxt_poll_work(struct bnxt *bp, struct bnxt_napi *bnapi, int budget)
|
|
|
if (event & BNXT_RX_EVENT) {
|
|
|
struct bnxt_rx_ring_info *rxr = bnapi->rx_ring;
|
|
|
|
|
|
- writel(DB_KEY_RX | rxr->rx_prod, rxr->rx_doorbell);
|
|
|
- writel(DB_KEY_RX | rxr->rx_prod, rxr->rx_doorbell);
|
|
|
- if (event & BNXT_AGG_EVENT) {
|
|
|
- writel(DB_KEY_RX | rxr->rx_agg_prod,
|
|
|
- rxr->rx_agg_doorbell);
|
|
|
- writel(DB_KEY_RX | rxr->rx_agg_prod,
|
|
|
- rxr->rx_agg_doorbell);
|
|
|
- }
|
|
|
+ bnxt_db_write(bp, rxr->rx_doorbell, DB_KEY_RX | rxr->rx_prod);
|
|
|
+ if (event & BNXT_AGG_EVENT)
|
|
|
+ bnxt_db_write(bp, rxr->rx_agg_doorbell,
|
|
|
+ DB_KEY_RX | rxr->rx_agg_prod);
|
|
|
}
|
|
|
return rx_pkts;
|
|
|
}
|
|
@@ -1861,13 +1861,11 @@ static int bnxt_poll_nitroa0(struct napi_struct *napi, int budget)
|
|
|
|
|
|
cpr->cp_raw_cons = raw_cons;
|
|
|
BNXT_CP_DB(cpr->cp_doorbell, cpr->cp_raw_cons);
|
|
|
- writel(DB_KEY_RX | rxr->rx_prod, rxr->rx_doorbell);
|
|
|
- writel(DB_KEY_RX | rxr->rx_prod, rxr->rx_doorbell);
|
|
|
+ bnxt_db_write(bp, rxr->rx_doorbell, DB_KEY_RX | rxr->rx_prod);
|
|
|
|
|
|
- if (event & BNXT_AGG_EVENT) {
|
|
|
- writel(DB_KEY_RX | rxr->rx_agg_prod, rxr->rx_agg_doorbell);
|
|
|
- writel(DB_KEY_RX | rxr->rx_agg_prod, rxr->rx_agg_doorbell);
|
|
|
- }
|
|
|
+ if (event & BNXT_AGG_EVENT)
|
|
|
+ bnxt_db_write(bp, rxr->rx_agg_doorbell,
|
|
|
+ DB_KEY_RX | rxr->rx_agg_prod);
|
|
|
|
|
|
if (!bnxt_has_work(bp, cpr) && rx_pkts < budget) {
|
|
|
napi_complete_done(napi, rx_pkts);
|
|
@@ -2868,6 +2866,32 @@ static int bnxt_alloc_hwrm_resources(struct bnxt *bp)
|
|
|
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)
|
|
|
{
|
|
|
u32 size, i;
|
|
@@ -3215,16 +3239,41 @@ static int bnxt_hwrm_do_send_msg(struct bnxt *bp, void *msg, u32 msg_len,
|
|
|
__le32 *resp_len, *valid;
|
|
|
u16 cp_ring_id, len = 0;
|
|
|
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++);
|
|
|
memset(resp, 0, PAGE_SIZE);
|
|
|
cp_ring_id = le16_to_cpu(req->cmpl_ring);
|
|
|
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 */
|
|
|
__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);
|
|
|
|
|
|
/* currently supports only one outstanding message */
|
|
@@ -4662,6 +4711,7 @@ static int bnxt_hwrm_ver_get(struct bnxt *bp)
|
|
|
int rc;
|
|
|
struct hwrm_ver_get_input req = {0};
|
|
|
struct hwrm_ver_get_output *resp = bp->hwrm_cmd_resp_addr;
|
|
|
+ u32 dev_caps_cfg;
|
|
|
|
|
|
bp->hwrm_max_req_len = HWRM_MAX_REQ_LEN;
|
|
|
bnxt_hwrm_cmd_hdr_init(bp, &req, HWRM_VER_GET, -1, -1);
|
|
@@ -4699,6 +4749,11 @@ static int bnxt_hwrm_ver_get(struct bnxt *bp)
|
|
|
!resp->chip_metal)
|
|
|
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:
|
|
|
mutex_unlock(&bp->hwrm_cmd_lock);
|
|
|
return rc;
|
|
@@ -7357,6 +7412,7 @@ static void bnxt_remove_one(struct pci_dev *pdev)
|
|
|
bnxt_clear_int_mode(bp);
|
|
|
bnxt_hwrm_func_drv_unrgtr(bp);
|
|
|
bnxt_free_hwrm_resources(bp);
|
|
|
+ bnxt_free_hwrm_short_cmd_req(bp);
|
|
|
bnxt_ethtool_free(bp);
|
|
|
bnxt_dcb_free(bp);
|
|
|
kfree(bp->edev);
|
|
@@ -7511,10 +7567,9 @@ static int bnxt_get_dflt_rings(struct bnxt *bp, int *max_rx, int *max_tx,
|
|
|
return rc;
|
|
|
}
|
|
|
|
|
|
-static int bnxt_set_dflt_rings(struct bnxt *bp)
|
|
|
+static int bnxt_set_dflt_rings(struct bnxt *bp, bool sh)
|
|
|
{
|
|
|
int dflt_rings, max_rx_rings, max_tx_rings, rc;
|
|
|
- bool sh = true;
|
|
|
|
|
|
if (sh)
|
|
|
bp->flags |= BNXT_FLAG_SHARED_RINGS;
|
|
@@ -7607,6 +7662,12 @@ static int bnxt_init_one(struct pci_dev *pdev, const struct pci_device_id *ent)
|
|
|
if (rc)
|
|
|
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);
|
|
|
if (rc)
|
|
|
goto init_err_pci_clean;
|
|
@@ -7646,8 +7707,10 @@ static int bnxt_init_one(struct pci_dev *pdev, const struct pci_device_id *ent)
|
|
|
init_waitqueue_head(&bp->sriov_cfg_wait);
|
|
|
#endif
|
|
|
bp->gro_func = bnxt_gro_func_5730x;
|
|
|
- if (BNXT_CHIP_NUM_57X1X(bp->chip_num))
|
|
|
+ if (BNXT_CHIP_P4_PLUS(bp))
|
|
|
bp->gro_func = bnxt_gro_func_5731x;
|
|
|
+ else
|
|
|
+ bp->flags |= BNXT_FLAG_DOUBLE_DB;
|
|
|
|
|
|
rc = bnxt_hwrm_func_drv_rgtr(bp);
|
|
|
if (rc)
|
|
@@ -7685,7 +7748,7 @@ static int bnxt_init_one(struct pci_dev *pdev, const struct pci_device_id *ent)
|
|
|
bnxt_set_tpa_flags(bp);
|
|
|
bnxt_set_ring_params(bp);
|
|
|
bnxt_set_max_func_irqs(bp, max_irqs);
|
|
|
- rc = bnxt_set_dflt_rings(bp);
|
|
|
+ rc = bnxt_set_dflt_rings(bp, true);
|
|
|
if (rc) {
|
|
|
netdev_err(bp->dev, "Not enough rings available.\n");
|
|
|
rc = -ENOMEM;
|
|
@@ -7697,9 +7760,7 @@ static int bnxt_init_one(struct pci_dev *pdev, const struct pci_device_id *ent)
|
|
|
VNIC_RSS_CFG_REQ_HASH_TYPE_TCP_IPV4 |
|
|
|
VNIC_RSS_CFG_REQ_HASH_TYPE_IPV6 |
|
|
|
VNIC_RSS_CFG_REQ_HASH_TYPE_TCP_IPV6;
|
|
|
- if (!BNXT_CHIP_NUM_57X0X(bp->chip_num) &&
|
|
|
- !BNXT_CHIP_TYPE_NITRO_A0(bp) &&
|
|
|
- bp->hwrm_spec_code >= 0x10501) {
|
|
|
+ if (BNXT_CHIP_P4_PLUS(bp) && bp->hwrm_spec_code >= 0x10501) {
|
|
|
bp->flags |= BNXT_FLAG_UDP_RSS_CAP;
|
|
|
bp->rss_hash_cfg |= VNIC_RSS_CFG_REQ_HASH_TYPE_UDP_IPV4 |
|
|
|
VNIC_RSS_CFG_REQ_HASH_TYPE_UDP_IPV6;
|
|
@@ -7771,6 +7832,7 @@ static void bnxt_shutdown(struct pci_dev *pdev)
|
|
|
dev_close(dev);
|
|
|
|
|
|
if (system_state == SYSTEM_POWER_OFF) {
|
|
|
+ bnxt_ulp_shutdown(bp);
|
|
|
bnxt_clear_int_mode(bp);
|
|
|
pci_wake_from_d3(pdev, bp->wol);
|
|
|
pci_set_power_state(pdev, PCI_D3hot);
|