liquidio: Common enable irq function
authorRaghu Vatsavayi <rvatsavayi@caviumnetworks.com>
Wed, 31 Aug 2016 18:03:22 +0000 (11:03 -0700)
committerDavid S. Miller <davem@davemloft.net>
Wed, 31 Aug 2016 21:12:47 +0000 (14:12 -0700)
Add support of common irq enable functionality for both
iq(instruction queue) and oq(output queue).

Signed-off-by: Derek Chickles <derek.chickles@caviumnetworks.com>
Signed-off-by: Satanand Burla <satananda.burla@caviumnetworks.com>
Signed-off-by: Felix Manlunas <felix.manlunas@caviumnetworks.com>
Signed-off-by: Raghu Vatsavayi <raghu.vatsavayi@caviumnetworks.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
drivers/net/ethernet/cavium/liquidio/lio_main.c
drivers/net/ethernet/cavium/liquidio/liquidio_common.h
drivers/net/ethernet/cavium/liquidio/octeon_device.c
drivers/net/ethernet/cavium/liquidio/octeon_device.h
drivers/net/ethernet/cavium/liquidio/octeon_droq.c
drivers/net/ethernet/cavium/liquidio/octeon_droq.h
drivers/net/ethernet/cavium/liquidio/octeon_iq.h
drivers/net/ethernet/cavium/liquidio/request_manager.c

index 1bbeae8802322277ba3dbb62d9703c230f214096..8f11a0b4a7adb58ce29a38cda9936aced7bae16f 100644 (file)
@@ -192,6 +192,7 @@ static void octeon_droq_bh(unsigned long pdev)
                        continue;
                reschedule |= octeon_droq_process_packets(oct, oct->droq[q_no],
                                                          MAX_PACKET_BUDGET);
+               lio_enable_irq(oct->droq[q_no], NULL);
        }
 
        if (reschedule)
index 11df55a5b2462c4e3c26c39208ad5c943c6fcb27..8ffd3b8c4d0fe8f34aeb3eabc589e520b6d89981 100644 (file)
@@ -846,7 +846,7 @@ struct oct_mdio_cmd {
 /* intrmod: max. packets to trigger interrupt */
 #define LIO_INTRMOD_RXMAXCNT_TRIGGER   384
 /* intrmod: min. packets to trigger interrupt */
-#define LIO_INTRMOD_RXMINCNT_TRIGGER   1
+#define LIO_INTRMOD_RXMINCNT_TRIGGER   0
 /* intrmod: max. time to trigger interrupt */
 #define LIO_INTRMOD_RXMAXTMR_TRIGGER   128
 /* 66xx:intrmod: min. time to trigger interrupt
index cff845ce8625cee5869790bb04228fb1ca142472..541137a60145a27271abdc22133bdb0253f17424 100644 (file)
@@ -1122,3 +1122,20 @@ int lio_get_device_id(void *dev)
                        return octeon_dev->octeon_id;
        return -1;
 }
+
+void lio_enable_irq(struct octeon_droq *droq, struct octeon_instr_queue *iq)
+{
+       /* the whole thing needs to be atomic, ideally */
+       if (droq) {
+               spin_lock_bh(&droq->lock);
+               writel(droq->pkt_count, droq->pkts_sent_reg);
+               droq->pkt_count = 0;
+               spin_unlock_bh(&droq->lock);
+       }
+       if (iq) {
+               spin_lock_bh(&iq->lock);
+               writel(iq->pkt_in_done, iq->inst_cnt_reg);
+               iq->pkt_in_done = 0;
+               spin_unlock_bh(&iq->lock);
+       }
+}
index d1251f4c55ded0b72a2355aa5789a21561f13909..02e9854477a12026d6c6e0f8f3466320da305496 100644 (file)
@@ -660,6 +660,8 @@ void *oct_get_config_info(struct octeon_device *oct, u16 card_type);
  */
 struct octeon_config *octeon_get_conf(struct octeon_device *oct);
 
+void lio_enable_irq(struct octeon_droq *droq, struct octeon_instr_queue *iq);
+
 /* LiquidIO driver pivate flags */
 enum {
        OCT_PRIV_FLAG_TX_BYTES = 0, /* Tx interrupts by pending byte count */
index e0afe4c1fd01e060b01f9d3f9a0acc43c0fc1f48..5dfc23d70d05d6ee75e7651cb5887b91ac7dcdce 100644 (file)
@@ -92,22 +92,25 @@ static inline void *octeon_get_dispatch_arg(struct octeon_device *octeon_dev,
        return fn_arg;
 }
 
-/** Check for packets on Droq. This function should be called with
- * lock held.
+/** Check for packets on Droq. This function should be called with lock held.
  *  @param  droq - Droq on which count is checked.
  *  @return Returns packet count.
  */
 u32 octeon_droq_check_hw_for_pkts(struct octeon_droq *droq)
 {
        u32 pkt_count = 0;
+       u32 last_count;
 
        pkt_count = readl(droq->pkts_sent_reg);
-       if (pkt_count) {
-               atomic_add(pkt_count, &droq->pkts_pending);
-               writel(pkt_count, droq->pkts_sent_reg);
-       }
 
-       return pkt_count;
+       last_count = pkt_count - droq->pkt_count;
+       droq->pkt_count = pkt_count;
+
+       /* we shall write to cnts  at napi irq enable or end of droq tasklet */
+       if (last_count)
+               atomic_add(last_count, &droq->pkts_pending);
+
+       return last_count;
 }
 
 static void octeon_droq_compute_max_packet_bufs(struct octeon_droq *droq)
@@ -735,16 +738,20 @@ octeon_droq_process_packets(struct octeon_device *oct,
        u32 pkt_count = 0, pkts_processed = 0;
        struct list_head *tmp, *tmp2;
 
+       /* Grab the droq lock */
+       spin_lock(&droq->lock);
+
+       octeon_droq_check_hw_for_pkts(droq);
        pkt_count = atomic_read(&droq->pkts_pending);
-       if (!pkt_count)
+
+       if (!pkt_count) {
+               spin_unlock(&droq->lock);
                return 0;
+       }
 
        if (pkt_count > budget)
                pkt_count = budget;
 
-       /* Grab the droq lock */
-       spin_lock(&droq->lock);
-
        pkts_processed = octeon_droq_fast_process_packets(oct, droq, pkt_count);
 
        atomic_sub(pkts_processed, &droq->pkts_pending);
@@ -789,6 +796,8 @@ octeon_droq_process_poll_pkts(struct octeon_device *oct,
        spin_lock(&droq->lock);
 
        while (total_pkts_processed < budget) {
+               octeon_droq_check_hw_for_pkts(droq);
+
                pkts_available =
                        CVM_MIN((budget - total_pkts_processed),
                                (u32)(atomic_read(&droq->pkts_pending)));
@@ -803,8 +812,6 @@ octeon_droq_process_poll_pkts(struct octeon_device *oct,
                atomic_sub(pkts_processed, &droq->pkts_pending);
 
                total_pkts_processed += pkts_processed;
-
-               octeon_droq_check_hw_for_pkts(droq);
        }
 
        spin_unlock(&droq->lock);
index 5a6fb9113bbdafb43c24ed61f377c7d6c47381d3..5be002d5dba4fb2f4a078e2a881d11b69172df70 100644 (file)
@@ -261,6 +261,8 @@ struct octeon_droq {
 
        u32 q_no;
 
+       u32 pkt_count;
+
        struct octeon_droq_ops ops;
 
        struct octeon_device *oct_dev;
index ff4b1d6f007bfb69a340eda87d1132f4e9db0358..e4d426ba18dcfa27e9e04894a0d390c9f04279ff 100644 (file)
@@ -88,6 +88,8 @@ struct octeon_instr_queue {
        /** A spinlock to protect while posting on the ring.  */
        spinlock_t post_lock;
 
+       u32 pkt_in_done;
+
        /** A spinlock to protect access to the input ring.*/
        spinlock_t iq_flush_running_lock;
 
index d32492f185ffc984be3abbcb5de1d81e53878348..3ee5d023c7896a49e1f8b89a7bc0f7e7b44e0fff 100644 (file)
@@ -499,6 +499,7 @@ static void __check_db_timeout(struct octeon_device *oct, u64 iq_no)
 
        if (!oct)
                return;
+
        iq = oct->instr_queue[iq_no];
        if (!iq)
                return;
@@ -514,6 +515,8 @@ static void __check_db_timeout(struct octeon_device *oct, u64 iq_no)
 
        /* Flush the instruction queue */
        octeon_flush_iq(oct, iq, 1, 0);
+
+       lio_enable_irq(NULL, iq);
 }
 
 /* Called by the Poll thread at regular intervals to check the instruction