]> www.infradead.org Git - users/dwmw2/linux.git/commitdiff
octeon_ep: implement xmit_more in transmit
authorShinas Rasheed <srasheed@marvell.com>
Tue, 14 Nov 2023 13:45:34 +0000 (05:45 -0800)
committerDavid S. Miller <davem@davemloft.net>
Thu, 16 Nov 2023 21:55:05 +0000 (21:55 +0000)
Add xmit_more handling in tx datapath for octeon_ep pf.

Signed-off-by: Shinas Rasheed <srasheed@marvell.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
drivers/net/ethernet/marvell/octeon_ep/octep_config.h
drivers/net/ethernet/marvell/octeon_ep/octep_main.c

index 1622a6ebf036230a2b239f7df9a275f41f352863..ed8b1ace56b9457c7f7e6fc81e2ecf68feddd69d 100644 (file)
@@ -15,7 +15,7 @@
 /* Tx Queue: maximum descriptors per ring */
 #define OCTEP_IQ_MAX_DESCRIPTORS    1024
 /* Minimum input (Tx) requests to be enqueued to ring doorbell */
-#define OCTEP_DB_MIN                1
+#define OCTEP_DB_MIN                8
 /* Packet threshold for Tx queue interrupt */
 #define OCTEP_IQ_INTR_THRESHOLD     0x0
 
index 1c02304677c9e1624ee43a9f2442bc07330397bb..2d1bcdc589f301ba46cd31df154f004ff79b732d 100644 (file)
@@ -784,6 +784,13 @@ static inline int octep_iq_full_check(struct octep_iq *iq)
        /* Stop the queue if unable to send */
        netif_stop_subqueue(iq->netdev, iq->q_no);
 
+       /* Allow for pending updates in write index
+        * from iq_process_completion in other cpus
+        * to reflect, in case queue gets free
+        * entries.
+        */
+       smp_mb();
+
        /* check again and restart the queue, in case NAPI has just freed
         * enough Tx ring entries.
         */
@@ -818,6 +825,7 @@ static netdev_tx_t octep_start_xmit(struct sk_buff *skb,
        struct octep_iq *iq;
        skb_frag_t *frag;
        u16 nr_frags, si;
+       int xmit_more;
        u16 q_no, wi;
 
        if (skb_put_padto(skb, ETH_ZLEN))
@@ -830,10 +838,6 @@ static netdev_tx_t octep_start_xmit(struct sk_buff *skb,
        }
 
        iq = oct->iq[q_no];
-       if (octep_iq_full_check(iq)) {
-               iq->stats.tx_busy++;
-               return NETDEV_TX_BUSY;
-       }
 
        shinfo = skb_shinfo(skb);
        nr_frags = shinfo->nr_frags;
@@ -894,19 +898,33 @@ static netdev_tx_t octep_start_xmit(struct sk_buff *skb,
                hw_desc->dptr = tx_buffer->sglist_dma;
        }
 
-       netdev_tx_sent_queue(iq->netdev_q, skb->len);
+       xmit_more = netdev_xmit_more();
+
+       __netdev_tx_sent_queue(iq->netdev_q, skb->len, xmit_more);
+
        skb_tx_timestamp(skb);
        atomic_inc(&iq->instr_pending);
+       iq->fill_cnt++;
        wi++;
        if (wi == iq->max_count)
                wi = 0;
        iq->host_write_index = wi;
+
+       /* octep_iq_full_check stops the queue and returns
+        * true if so, in case the queue has become full
+        * by inserting current packet. If so, we can
+        * go ahead and ring doorbell.
+        */
+       if (!octep_iq_full_check(iq) && xmit_more &&
+           iq->fill_cnt < iq->fill_threshold)
+               return NETDEV_TX_OK;
+
        /* Flush the hw descriptor before writing to doorbell */
        wmb();
-
-       /* Ring Doorbell to notify the NIC there is a new packet */
-       writel(1, iq->doorbell_reg);
-       iq->stats.instr_posted++;
+       /* Ring Doorbell to notify the NIC of new packets */
+       writel(iq->fill_cnt, iq->doorbell_reg);
+       iq->stats.instr_posted += iq->fill_cnt;
+       iq->fill_cnt = 0;
        return NETDEV_TX_OK;
 
 dma_map_sg_err: