From a6d36d5689b1806a3365c909192e9f03a43a632b Mon Sep 17 00:00:00 2001 From: Ben Menchaca Date: Wed, 24 Mar 2010 05:05:02 +0000 Subject: gianfar: fix undo of reserve() Fix undo of reserve() before RX recycle gfar_new_skb reserve()s space in the SKB to align it. If an error occurs, and the skb needs to be returned to the RX recycle queue, the current code attempts to reset head, but did not reset tail. This patch remembers the alignment amount, and reverses the reserve() when needed. Signed-off-by: Ben Menchaca Signed-off-by: David S. Miller --- drivers/net/gianfar.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) (limited to 'drivers/net/gianfar.c') diff --git a/drivers/net/gianfar.c b/drivers/net/gianfar.c index b6715553cf17..669de028d44f 100644 --- a/drivers/net/gianfar.c +++ b/drivers/net/gianfar.c @@ -2393,6 +2393,7 @@ struct sk_buff * gfar_new_skb(struct net_device *dev) * as many bytes as needed to align the data properly */ skb_reserve(skb, alignamount); + GFAR_CB(skb)->alignamount = alignamount; return skb; } @@ -2533,13 +2534,13 @@ int gfar_clean_rx_ring(struct gfar_priv_rx_q *rx_queue, int rx_work_limit) newskb = skb; else if (skb) { /* - * We need to reset ->data to what it + * We need to un-reserve() the skb to what it * was before gfar_new_skb() re-aligned * it to an RXBUF_ALIGNMENT boundary * before we put the skb back on the * recycle list. */ - skb->data = skb->head + NET_SKB_PAD; + skb_reserve(skb, -GFAR_CB(skb)->alignamount); __skb_queue_head(&priv->rx_recycle, skb); } } else { -- cgit v1.2.3 From 7c0d10d35f7f47d00cc5f2b85ee5e95c2b1fdb7e Mon Sep 17 00:00:00 2001 From: Andy Fleming Date: Mon, 29 Mar 2010 15:42:23 +0000 Subject: gianfar: Fix a memory leak in gianfar close code gianfar needed to ensure existence of the *skbuff arrays before freeing the skbs in them, rather than ensuring their nonexistence. Signed-off-by: Andy Fleming Signed-off-by: David S. Miller --- drivers/net/gianfar.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers/net/gianfar.c') diff --git a/drivers/net/gianfar.c b/drivers/net/gianfar.c index 669de028d44f..c98fead8412b 100644 --- a/drivers/net/gianfar.c +++ b/drivers/net/gianfar.c @@ -1638,13 +1638,13 @@ static void free_skb_resources(struct gfar_private *priv) /* Go through all the buffer descriptors and free their data buffers */ for (i = 0; i < priv->num_tx_queues; i++) { tx_queue = priv->tx_queue[i]; - if(!tx_queue->tx_skbuff) + if(tx_queue->tx_skbuff) free_skb_tx_queue(tx_queue); } for (i = 0; i < priv->num_rx_queues; i++) { rx_queue = priv->rx_queue[i]; - if(!rx_queue->rx_skbuff) + if(rx_queue->rx_skbuff) free_skb_rx_queue(rx_queue); } -- cgit v1.2.3 From ed130589d9afa3238c94b9537f2024355b9638e1 Mon Sep 17 00:00:00 2001 From: Kim Phillips Date: Tue, 30 Mar 2010 11:54:21 +0000 Subject: net: gianfar - initialize per-queue statistics Interfaces come up claiming having already received 3.0 GiB. Use kzalloc to properly initialize per-queue data. Signed-off-by: Kim Phillips Signed-off-by: David S. Miller --- drivers/net/gianfar.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers/net/gianfar.c') diff --git a/drivers/net/gianfar.c b/drivers/net/gianfar.c index c98fead8412b..8ea78353d1e2 100644 --- a/drivers/net/gianfar.c +++ b/drivers/net/gianfar.c @@ -676,7 +676,7 @@ static int gfar_of_init(struct of_device *ofdev, struct net_device **pdev) priv->rx_queue[i] = NULL; for (i = 0; i < priv->num_tx_queues; i++) { - priv->tx_queue[i] = (struct gfar_priv_tx_q *)kmalloc( + priv->tx_queue[i] = (struct gfar_priv_tx_q *)kzalloc( sizeof (struct gfar_priv_tx_q), GFP_KERNEL); if (!priv->tx_queue[i]) { err = -ENOMEM; @@ -689,7 +689,7 @@ static int gfar_of_init(struct of_device *ofdev, struct net_device **pdev) } for (i = 0; i < priv->num_rx_queues; i++) { - priv->rx_queue[i] = (struct gfar_priv_rx_q *)kmalloc( + priv->rx_queue[i] = (struct gfar_priv_rx_q *)kzalloc( sizeof (struct gfar_priv_rx_q), GFP_KERNEL); if (!priv->rx_queue[i]) { err = -ENOMEM; -- cgit v1.2.3 From ddc01b3b8ab224b346daf61976078b166f36b7e8 Mon Sep 17 00:00:00 2001 From: Kim Phillips Date: Tue, 30 Mar 2010 11:54:22 +0000 Subject: net: gianfar - align BD ring size console messages fix this: eth2: :RX BD ring size for Q[0]: 256 eth2:TX BD ring size for Q[0]: 256 to look like: eth2: RX BD ring size for Q[0]: 256 eth2: TX BD ring size for Q[0]: 256 Signed-off-by: Kim Phillips Signed-off-by: David S. Miller --- drivers/net/gianfar.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers/net/gianfar.c') diff --git a/drivers/net/gianfar.c b/drivers/net/gianfar.c index 8ea78353d1e2..080d1cea5b26 100644 --- a/drivers/net/gianfar.c +++ b/drivers/net/gianfar.c @@ -1120,10 +1120,10 @@ static int gfar_probe(struct of_device *ofdev, /* provided which set of benchmarks. */ printk(KERN_INFO "%s: Running with NAPI enabled\n", dev->name); for (i = 0; i < priv->num_rx_queues; i++) - printk(KERN_INFO "%s: :RX BD ring size for Q[%d]: %d\n", + printk(KERN_INFO "%s: RX BD ring size for Q[%d]: %d\n", dev->name, i, priv->rx_queue[i]->rx_ring_size); for(i = 0; i < priv->num_tx_queues; i++) - printk(KERN_INFO "%s:TX BD ring size for Q[%d]: %d\n", + printk(KERN_INFO "%s: TX BD ring size for Q[%d]: %d\n", dev->name, i, priv->tx_queue[i]->tx_ring_size); return 0; -- cgit v1.2.3 From 7ce97d4f78b62e3af24cdd4df953d777e7efb2f6 Mon Sep 17 00:00:00 2001 From: Anton Vorontsov Date: Fri, 23 Apr 2010 07:12:44 +0000 Subject: gianfar: Fix potential oops during OF address translation gianfar driver may pass NULL pointer to the of_translate_address(), which may lead to a kernel oops. Fix this by using of_iomap(), which is also much simpler and shorter. Signed-off-by: Anton Vorontsov Signed-off-by: David S. Miller --- drivers/net/gianfar.c | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) (limited to 'drivers/net/gianfar.c') diff --git a/drivers/net/gianfar.c b/drivers/net/gianfar.c index 080d1cea5b26..df49af382159 100644 --- a/drivers/net/gianfar.c +++ b/drivers/net/gianfar.c @@ -549,12 +549,8 @@ static int gfar_parse_group(struct device_node *np, struct gfar_private *priv, const char *model) { u32 *queue_mask; - u64 addr, size; - - addr = of_translate_address(np, - of_get_address(np, 0, &size, NULL)); - priv->gfargrp[priv->num_grps].regs = ioremap(addr, size); + priv->gfargrp[priv->num_grps].regs = of_iomap(np, 0); if (!priv->gfargrp[priv->num_grps].regs) return -ENOMEM; -- cgit v1.2.3 From 761ed01b35ca32bfd4166cc3862ae80ee33e3a4b Mon Sep 17 00:00:00 2001 From: Andy Fleming Date: Tue, 27 Apr 2010 16:43:31 -0700 Subject: gianfar: Wait for both RX and TX to stop When gracefully stopping the controller, the driver was continuing if *either* RX or TX had stopped. We need to wait for both, or the controller could get into an invalid state. Signed-off-by: Andy Fleming Signed-off-by: David S. Miller --- drivers/net/gianfar.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'drivers/net/gianfar.c') diff --git a/drivers/net/gianfar.c b/drivers/net/gianfar.c index df49af382159..4e97ca182997 100644 --- a/drivers/net/gianfar.c +++ b/drivers/net/gianfar.c @@ -1511,9 +1511,9 @@ static void gfar_halt_nodisable(struct net_device *dev) tempval |= (DMACTRL_GRS | DMACTRL_GTS); gfar_write(®s->dmactrl, tempval); - while (!(gfar_read(®s->ievent) & - (IEVENT_GRSC | IEVENT_GTSC))) - cpu_relax(); + spin_event_timeout(((gfar_read(®s->ievent) & + (IEVENT_GRSC | IEVENT_GTSC)) == + (IEVENT_GRSC | IEVENT_GTSC)), -1, 0); } } -- cgit v1.2.3