aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/vxge/vxge-main.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/net/vxge/vxge-main.c')
-rw-r--r--drivers/net/vxge/vxge-main.c53
1 files changed, 28 insertions, 25 deletions
diff --git a/drivers/net/vxge/vxge-main.c b/drivers/net/vxge/vxge-main.c
index beee4ab2ed30..4b22513bed40 100644
--- a/drivers/net/vxge/vxge-main.c
+++ b/drivers/net/vxge/vxge-main.c
@@ -87,22 +87,25 @@ static inline int is_vxge_card_up(struct vxgedev *vdev)
87static inline void VXGE_COMPLETE_VPATH_TX(struct vxge_fifo *fifo) 87static inline void VXGE_COMPLETE_VPATH_TX(struct vxge_fifo *fifo)
88{ 88{
89 unsigned long flags = 0; 89 unsigned long flags = 0;
90 struct sk_buff *skb_ptr = NULL; 90 struct sk_buff **skb_ptr = NULL;
91 struct sk_buff **temp, *head, *skb; 91 struct sk_buff **temp;
92 92#define NR_SKB_COMPLETED 128
93 if (spin_trylock_irqsave(&fifo->tx_lock, flags)) { 93 struct sk_buff *completed[NR_SKB_COMPLETED];
94 vxge_hw_vpath_poll_tx(fifo->handle, (void **)&skb_ptr); 94 int more;
95 spin_unlock_irqrestore(&fifo->tx_lock, flags); 95
96 } 96 do {
97 /* free SKBs */ 97 more = 0;
98 head = skb_ptr; 98 skb_ptr = completed;
99 while (head) { 99
100 skb = head; 100 if (spin_trylock_irqsave(&fifo->tx_lock, flags)) {
101 temp = (struct sk_buff **)&skb->cb; 101 vxge_hw_vpath_poll_tx(fifo->handle, &skb_ptr,
102 head = *temp; 102 NR_SKB_COMPLETED, &more);
103 *temp = NULL; 103 spin_unlock_irqrestore(&fifo->tx_lock, flags);
104 dev_kfree_skb_irq(skb); 104 }
105 } 105 /* free SKBs */
106 for (temp = completed; temp != skb_ptr; temp++)
107 dev_kfree_skb_irq(*temp);
108 } while (more) ;
106} 109}
107 110
108static inline void VXGE_COMPLETE_ALL_TX(struct vxgedev *vdev) 111static inline void VXGE_COMPLETE_ALL_TX(struct vxgedev *vdev)
@@ -600,11 +603,10 @@ vxge_rx_1b_compl(struct __vxge_hw_ring *ringh, void *dtr,
600enum vxge_hw_status 603enum vxge_hw_status
601vxge_xmit_compl(struct __vxge_hw_fifo *fifo_hw, void *dtr, 604vxge_xmit_compl(struct __vxge_hw_fifo *fifo_hw, void *dtr,
602 enum vxge_hw_fifo_tcode t_code, void *userdata, 605 enum vxge_hw_fifo_tcode t_code, void *userdata,
603 void **skb_ptr) 606 struct sk_buff ***skb_ptr, int nr_skb, int *more)
604{ 607{
605 struct vxge_fifo *fifo = (struct vxge_fifo *)userdata; 608 struct vxge_fifo *fifo = (struct vxge_fifo *)userdata;
606 struct sk_buff *skb, *head = NULL; 609 struct sk_buff *skb, **done_skb = *skb_ptr;
607 struct sk_buff **temp;
608 int pkt_cnt = 0; 610 int pkt_cnt = 0;
609 611
610 vxge_debug_entryexit(VXGE_TRACE, 612 vxge_debug_entryexit(VXGE_TRACE,
@@ -657,9 +659,12 @@ vxge_xmit_compl(struct __vxge_hw_fifo *fifo_hw, void *dtr,
657 fifo->stats.tx_frms++; 659 fifo->stats.tx_frms++;
658 fifo->stats.tx_bytes += skb->len; 660 fifo->stats.tx_bytes += skb->len;
659 661
660 temp = (struct sk_buff **)&skb->cb; 662 *done_skb++ = skb;
661 *temp = head; 663
662 head = skb; 664 if (--nr_skb <= 0) {
665 *more = 1;
666 break;
667 }
663 668
664 pkt_cnt++; 669 pkt_cnt++;
665 if (pkt_cnt > fifo->indicate_max_pkts) 670 if (pkt_cnt > fifo->indicate_max_pkts)
@@ -668,11 +673,9 @@ vxge_xmit_compl(struct __vxge_hw_fifo *fifo_hw, void *dtr,
668 } while (vxge_hw_fifo_txdl_next_completed(fifo_hw, 673 } while (vxge_hw_fifo_txdl_next_completed(fifo_hw,
669 &dtr, &t_code) == VXGE_HW_OK); 674 &dtr, &t_code) == VXGE_HW_OK);
670 675
676 *skb_ptr = done_skb;
671 vxge_wake_tx_queue(fifo, skb); 677 vxge_wake_tx_queue(fifo, skb);
672 678
673 if (skb_ptr)
674 *skb_ptr = (void *) head;
675
676 vxge_debug_entryexit(VXGE_TRACE, 679 vxge_debug_entryexit(VXGE_TRACE,
677 "%s: %s:%d Exiting...", 680 "%s: %s:%d Exiting...",
678 fifo->ndev->name, __func__, __LINE__); 681 fifo->ndev->name, __func__, __LINE__);