diff options
Diffstat (limited to 'drivers/net/vxge/vxge-main.c')
-rw-r--r-- | drivers/net/vxge/vxge-main.c | 53 |
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) | |||
87 | static inline void VXGE_COMPLETE_VPATH_TX(struct vxge_fifo *fifo) | 87 | static 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 | ||
108 | static inline void VXGE_COMPLETE_ALL_TX(struct vxgedev *vdev) | 111 | static inline void VXGE_COMPLETE_ALL_TX(struct vxgedev *vdev) |
@@ -600,11 +603,10 @@ vxge_rx_1b_compl(struct __vxge_hw_ring *ringh, void *dtr, | |||
600 | enum vxge_hw_status | 603 | enum vxge_hw_status |
601 | vxge_xmit_compl(struct __vxge_hw_fifo *fifo_hw, void *dtr, | 604 | vxge_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__); |