bnxt_en: Optimize doorbell write operations for newer chips.
authorMichael Chan <michael.chan@broadcom.com>
Mon, 29 May 2017 23:06:08 +0000 (19:06 -0400)
committerDavid S. Miller <davem@davemloft.net>
Tue, 30 May 2017 22:14:07 +0000 (18:14 -0400)
Older chips require the doorbells to be written twice, but newer chips
do not.  Add a new common function bnxt_db_write() to write all
doorbells appropriately depending on the chip.  Eliminating the extra
doorbell on newer chips has a significant performance improvement
on pktgen.

Signed-off-by: Michael Chan <michael.chan@broadcom.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
drivers/net/ethernet/broadcom/bnxt/bnxt.c
drivers/net/ethernet/broadcom/bnxt/bnxt.h
drivers/net/ethernet/broadcom/bnxt/bnxt_ethtool.c
drivers/net/ethernet/broadcom/bnxt/bnxt_xdp.c

index 427db49..d7c1295 100644 (file)
@@ -463,8 +463,7 @@ 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);
+       bnxt_db_write(bp, txr->tx_doorbell, DB_KEY_TX | prod);
 
 tx_done:
 
@@ -1779,8 +1778,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;
@@ -1796,14 +1794,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;
 }
@@ -1863,13 +1857,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);
@@ -7714,6 +7706,8 @@ static int bnxt_init_one(struct pci_dev *pdev, const struct pci_device_id *ent)
        bp->gro_func = bnxt_gro_func_5730x;
        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)
index c59b2cd..5984423 100644 (file)
@@ -1022,6 +1022,7 @@ struct bnxt {
        #define BNXT_FLAG_FW_LLDP_AGENT 0x80000
        #define BNXT_FLAG_MULTI_HOST    0x100000
        #define BNXT_FLAG_SHORT_CMD     0x200000
+       #define BNXT_FLAG_DOUBLE_DB     0x400000
        #define BNXT_FLAG_CHIP_NITRO_A0 0x1000000
 
        #define BNXT_FLAG_ALL_CONFIG_FEATS (BNXT_FLAG_TPA |             \
@@ -1254,6 +1255,14 @@ static inline u32 bnxt_tx_avail(struct bnxt *bp, struct bnxt_tx_ring_info *txr)
                ((txr->tx_prod - txr->tx_cons) & bp->tx_ring_mask);
 }
 
+/* For TX and RX ring doorbells */
+static inline void bnxt_db_write(struct bnxt *bp, void __iomem *db, u32 val)
+{
+       writel(val, db);
+       if (bp->flags & BNXT_FLAG_DOUBLE_DB)
+               writel(val, db);
+}
+
 extern const u16 bnxt_lhint_arr[];
 
 int bnxt_alloc_rx_data(struct bnxt *bp, struct bnxt_rx_ring_info *rxr,
index 11ddf0a..fd11815 100644 (file)
@@ -2376,8 +2376,7 @@ static int bnxt_run_loopback(struct bnxt *bp)
        /* Sync BD data before updating doorbell */
        wmb();
 
-       writel(DB_KEY_TX | txr->tx_prod, txr->tx_doorbell);
-       writel(DB_KEY_TX | txr->tx_prod, txr->tx_doorbell);
+       bnxt_db_write(bp, txr->tx_doorbell, DB_KEY_TX | txr->tx_prod);
        rc = bnxt_poll_loopback(bp, pkt_size);
 
        dma_unmap_single(&bp->pdev->dev, map, pkt_size, PCI_DMA_TODEVICE);
index 9dae327..8ce793a 100644 (file)
@@ -63,7 +63,7 @@ void bnxt_tx_int_xdp(struct bnxt *bp, struct bnxt_napi *bnapi, int nr_pkts)
                tx_buf = &txr->tx_buf_ring[last_tx_cons];
                rx_prod = tx_buf->rx_prod;
        }
-       writel(DB_KEY_RX | rx_prod, rxr->rx_doorbell);
+       bnxt_db_write(bp, rxr->rx_doorbell, DB_KEY_RX | rx_prod);
 }
 
 /* returns the following: