aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/niu.c
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2008-09-13 17:46:57 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2008-09-13 17:46:57 -0400
commitc19e80808b34b3de5c20884f11f58c3b6988daff (patch)
tree97a19986b95a23fb9da450e7d6b19fcc94ed6da9 /drivers/net/niu.c
parent344a7829c421ce6c626cb94c6576f66a7c28a871 (diff)
parentcff502a38394fd33693f6233e03fca363dfa956d (diff)
Merge git://git.kernel.org/pub/scm/linux/kernel/git/davem/net-2.6
* git://git.kernel.org/pub/scm/linux/kernel/git/davem/net-2.6: niu: panic on reset netlink: fix overrun in attribute iteration [Bluetooth] Fix regression from using default link policy ath9k: Assign seq# when mac80211 requests this
Diffstat (limited to 'drivers/net/niu.c')
-rw-r--r--drivers/net/niu.c56
1 files changed, 56 insertions, 0 deletions
diff --git a/drivers/net/niu.c b/drivers/net/niu.c
index e4765b713aba..e3be81eba8a4 100644
--- a/drivers/net/niu.c
+++ b/drivers/net/niu.c
@@ -5984,6 +5984,56 @@ static void niu_netif_start(struct niu *np)
5984 niu_enable_interrupts(np, 1); 5984 niu_enable_interrupts(np, 1);
5985} 5985}
5986 5986
5987static void niu_reset_buffers(struct niu *np)
5988{
5989 int i, j, k, err;
5990
5991 if (np->rx_rings) {
5992 for (i = 0; i < np->num_rx_rings; i++) {
5993 struct rx_ring_info *rp = &np->rx_rings[i];
5994
5995 for (j = 0, k = 0; j < MAX_RBR_RING_SIZE; j++) {
5996 struct page *page;
5997
5998 page = rp->rxhash[j];
5999 while (page) {
6000 struct page *next =
6001 (struct page *) page->mapping;
6002 u64 base = page->index;
6003 base = base >> RBR_DESCR_ADDR_SHIFT;
6004 rp->rbr[k++] = cpu_to_le32(base);
6005 page = next;
6006 }
6007 }
6008 for (; k < MAX_RBR_RING_SIZE; k++) {
6009 err = niu_rbr_add_page(np, rp, GFP_ATOMIC, k);
6010 if (unlikely(err))
6011 break;
6012 }
6013
6014 rp->rbr_index = rp->rbr_table_size - 1;
6015 rp->rcr_index = 0;
6016 rp->rbr_pending = 0;
6017 rp->rbr_refill_pending = 0;
6018 }
6019 }
6020 if (np->tx_rings) {
6021 for (i = 0; i < np->num_tx_rings; i++) {
6022 struct tx_ring_info *rp = &np->tx_rings[i];
6023
6024 for (j = 0; j < MAX_TX_RING_SIZE; j++) {
6025 if (rp->tx_buffs[j].skb)
6026 (void) release_tx_packet(np, rp, j);
6027 }
6028
6029 rp->pending = MAX_TX_RING_SIZE;
6030 rp->prod = 0;
6031 rp->cons = 0;
6032 rp->wrap_bit = 0;
6033 }
6034 }
6035}
6036
5987static void niu_reset_task(struct work_struct *work) 6037static void niu_reset_task(struct work_struct *work)
5988{ 6038{
5989 struct niu *np = container_of(work, struct niu, reset_task); 6039 struct niu *np = container_of(work, struct niu, reset_task);
@@ -6006,6 +6056,12 @@ static void niu_reset_task(struct work_struct *work)
6006 6056
6007 niu_stop_hw(np); 6057 niu_stop_hw(np);
6008 6058
6059 spin_unlock_irqrestore(&np->lock, flags);
6060
6061 niu_reset_buffers(np);
6062
6063 spin_lock_irqsave(&np->lock, flags);
6064
6009 err = niu_init_hw(np); 6065 err = niu_init_hw(np);
6010 if (!err) { 6066 if (!err) {
6011 np->timer.expires = jiffies + HZ; 6067 np->timer.expires = jiffies + HZ;