diff options
author | Intiyaz Basha <intiyaz.basha@cavium.com> | 2017-08-14 12:01:50 -0700 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2017-08-14 22:21:40 -0700 |
commit | d314ac222829c4e5cf7c0f505f207cb8848e0b8f (patch) | |
tree | bb8f68882b84c5f3e64bef511bcbdebb322d4abd /drivers/net/ethernet/cavium/liquidio/lio_core.c | |
parent | liquidio: moved liquidio_napi_drv_callback to lio_core.c (diff) | |
download | linux-dev-d314ac222829c4e5cf7c0f505f207cb8848e0b8f.tar.xz linux-dev-d314ac222829c4e5cf7c0f505f207cb8848e0b8f.zip |
liquidio: moved liquidio_napi_poll to lio_core.c
Moving common liquidio_napi_poll to lio_core.c
Signed-off-by: Intiyaz Basha <intiyaz.basha@cavium.com>
Signed-off-by: Felix Manlunas <felix.manlunas@cavium.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'drivers/net/ethernet/cavium/liquidio/lio_core.c')
-rw-r--r-- | drivers/net/ethernet/cavium/liquidio/lio_core.c | 61 |
1 files changed, 60 insertions, 1 deletions
diff --git a/drivers/net/ethernet/cavium/liquidio/lio_core.c b/drivers/net/ethernet/cavium/liquidio/lio_core.c index 8cba9278c274..2030c2531309 100644 --- a/drivers/net/ethernet/cavium/liquidio/lio_core.c +++ b/drivers/net/ethernet/cavium/liquidio/lio_core.c @@ -366,7 +366,7 @@ void cleanup_rx_oom_poll_fn(struct net_device *netdev) } /* Runs in interrupt context. */ -void lio_update_txq_status(struct octeon_device *oct, int iq_num) +static void lio_update_txq_status(struct octeon_device *oct, int iq_num) { struct octeon_instr_queue *iq = oct->instr_queue[iq_num]; struct net_device *netdev; @@ -620,3 +620,62 @@ void liquidio_napi_drv_callback(void *arg) smp_call_function_single_async(droq->cpu_id, csd); } } + +/** + * \brief Entry point for NAPI polling + * @param napi NAPI structure + * @param budget maximum number of items to process + */ +int liquidio_napi_poll(struct napi_struct *napi, int budget) +{ + struct octeon_instr_queue *iq; + struct octeon_device *oct; + struct octeon_droq *droq; + int tx_done = 0, iq_no; + int work_done; + + droq = container_of(napi, struct octeon_droq, napi); + oct = droq->oct_dev; + iq_no = droq->q_no; + + /* Handle Droq descriptors */ + work_done = octeon_process_droq_poll_cmd(oct, droq->q_no, + POLL_EVENT_PROCESS_PKTS, + budget); + + /* Flush the instruction queue */ + iq = oct->instr_queue[iq_no]; + if (iq) { + /* TODO: move this check to inside octeon_flush_iq, + * once check_db_timeout is removed + */ + if (atomic_read(&iq->instr_pending)) + /* Process iq buffers with in the budget limits */ + tx_done = octeon_flush_iq(oct, iq, budget); + else + tx_done = 1; + /* Update iq read-index rather than waiting for next interrupt. + * Return back if tx_done is false. + */ + /* sub-queue status update */ + lio_update_txq_status(oct, iq_no); + } else { + dev_err(&oct->pci_dev->dev, "%s: iq (%d) num invalid\n", + __func__, iq_no); + } + +#define MAX_REG_CNT 2000000U + /* force enable interrupt if reg cnts are high to avoid wraparound */ + if (((work_done < budget) && (tx_done)) || + (iq->pkt_in_done >= MAX_REG_CNT) || + (droq->pkt_count >= MAX_REG_CNT)) { + tx_done = 1; + napi_complete_done(napi, work_done); + + octeon_process_droq_poll_cmd(droq->oct_dev, droq->q_no, + POLL_EVENT_ENABLE_INTR, 0); + return 0; + } + + return (!tx_done) ? (budget) : (work_done); +} |