* bnad_free_txbufs : Frees the Tx bufs on Tx completion
* Can be called in a) Interrupt context
* b) Sending context
- * c) Tasklet context
*/
static u32
bnad_free_txbufs(struct bnad *bnad,
struct bnad_skb_unmap *unmap_array;
struct sk_buff *skb;
- /*
- * Just return if TX is stopped. This check is useful
- * when bnad_free_txbufs() runs out of a tasklet scheduled
- * before bnad_cb_tx_cleanup() cleared BNAD_TXQ_TX_STARTED bit
- * but this routine runs actually after the cleanup has been
- * executed.
- */
+ /* Just return if TX is stopped */
if (!test_bit(BNAD_TXQ_TX_STARTED, &tcb->flags))
return 0;
return sent_packets;
}
-/* Tx Free Tasklet function */
-/* Frees for all the tcb's in all the Tx's */
-/*
- * Scheduled from sending context, so that
- * the fat Tx lock is not held for too long
- * in the sending context.
- */
-static void
-bnad_tx_free_tasklet(unsigned long bnad_ptr)
-{
- struct bnad *bnad = (struct bnad *)bnad_ptr;
- struct bna_tcb *tcb;
- u32 acked = 0;
- int i, j;
-
- for (i = 0; i < bnad->num_tx; i++) {
- for (j = 0; j < bnad->num_txq_per_tx; j++) {
- tcb = bnad->tx_info[i].tcb[j];
- if (!tcb)
- continue;
- if (((u16) (*tcb->hw_consumer_index) !=
- tcb->consumer_index) &&
- (!test_and_set_bit(BNAD_TXQ_FREE_SENT,
- &tcb->flags))) {
- acked = bnad_free_txbufs(bnad, tcb);
- if (likely(test_bit(BNAD_TXQ_TX_STARTED,
- &tcb->flags)))
- bna_ib_ack(tcb->i_dbell, acked);
- smp_mb__before_clear_bit();
- clear_bit(BNAD_TXQ_FREE_SENT, &tcb->flags);
- }
- if (unlikely(!test_bit(BNAD_TXQ_TX_STARTED,
- &tcb->flags)))
- continue;
- if (netif_queue_stopped(bnad->netdev)) {
- if (acked && netif_carrier_ok(bnad->netdev) &&
- BNA_QE_FREE_CNT(tcb, tcb->q_depth) >=
- BNAD_NETIF_WAKE_THRESHOLD) {
- netif_wake_queue(bnad->netdev);
- /* TODO */
- /* Counters for individual TxQs? */
- BNAD_UPDATE_CTR(bnad,
- netif_queue_wakeup);
- }
- }
- }
- }
-}
-
static u32
bnad_tx(struct bnad *bnad, struct bna_tcb *tcb)
{
bnad_tx_msix_unregister(bnad, tx_info,
bnad->num_txq_per_tx);
- if (0 == tx_id)
- tasklet_kill(&bnad->tx_free_tasklet);
-
spin_lock_irqsave(&bnad->bna_lock, flags);
bna_tx_destroy(tx_info->tx);
spin_unlock_irqrestore(&bnad->bna_lock, flags);
bna_txq_prod_indx_doorbell(tcb);
smp_mb();
- if ((u16) (*tcb->hw_consumer_index) != tcb->consumer_index)
- tasklet_schedule(&bnad->tx_free_tasklet);
-
return NETDEV_TX_OK;
}
/*
* 1. Initialize the bnad structure
* 2. Setup netdev pointer in pci_dev
- * 3. Initialze Tx free tasklet
- * 4. Initialize no. of TxQ & CQs & MSIX vectors
- * 5. Initialize work queue.
+ * 3. Initialize no. of TxQ & CQs & MSIX vectors
+ * 4. Initialize work queue.
*/
static int
bnad_init(struct bnad *bnad,
bnad->tx_coalescing_timeo = BFI_TX_COALESCING_TIMEO;
bnad->rx_coalescing_timeo = BFI_RX_COALESCING_TIMEO;
- tasklet_init(&bnad->tx_free_tasklet, bnad_tx_free_tasklet,
- (unsigned long)bnad);
-
sprintf(bnad->wq_name, "%s_wq_%d", BNAD_NAME, bnad->id);
bnad->work_q = create_singlethread_workqueue(bnad->wq_name);
/*
* Initialize bnad structure
* Setup relation between pci_dev & netdev
- * Init Tx free tasklet
*/
err = bnad_init(bnad, pdev, netdev);
if (err)