Netdev List
 help / color / mirror / Atom feed
* [PATCH 10/10] stmmac: update the driver version March 2012
From: Giuseppe CAVALLARO @ 2012-04-04 14:33 UTC (permalink / raw)
  To: netdev
  Cc: davem, deepak.sikri, spear-devel, shiraz.hashim, viresh.kumar,
	srinivas.kandagatla, Giuseppe Cavallaro
In-Reply-To: <1333550008-16500-1-git-send-email-peppe.cavallaro@st.com>

Signed-off-by: Giuseppe Cavallaro <peppe.cavallaro@st.com>
---
 drivers/net/ethernet/stmicro/stmmac/stmmac.h |    2 +-
 1 files changed, 1 insertions(+), 1 deletions(-)

diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac.h b/drivers/net/ethernet/stmicro/stmmac/stmmac.h
index ddd0769..9f2435c 100644
--- a/drivers/net/ethernet/stmicro/stmmac/stmmac.h
+++ b/drivers/net/ethernet/stmicro/stmmac/stmmac.h
@@ -21,7 +21,7 @@
 *******************************************************************************/
 
 #define STMMAC_RESOURCE_NAME   "stmmaceth"
-#define DRV_MODULE_VERSION	"Feb_2012"
+#define DRV_MODULE_VERSION	"March_2012"
 
 #include <linux/clk.h>
 #include <linux/stmmac.h>
-- 
1.7.4.4

^ permalink raw reply related

* Re: [PATCH net-next 21/34] tulip_core: stop using net_device.{base_addr, irq}.
From: Grant Grundler @ 2012-04-04 14:52 UTC (permalink / raw)
  To: Francois Romieu; +Cc: netdev, David Miller, Grant Grundler
In-Reply-To: <62c6b5fe7ebcbc0d4b5c5ecdc92b9d82e4405b4c.1331814082.git.romieu@fr.zoreil.com>

On Thu, Mar 15, 2012 at 6:57 AM, Francois Romieu <romieu@fr.zoreil.com> wrote:
> Signed-off-by: Francois Romieu <romieu@fr.zoreil.com>
> Cc: Grant Grundler <grundler@parisc-linux.org>

Acked-by; Grant Grundler <grundler@parisc-linux.org>

thanks!
grant

> ---
>  drivers/net/ethernet/dec/tulip/tulip_core.c |   27 ++++++++++++++++-----------
>  1 files changed, 16 insertions(+), 11 deletions(-)
>
> diff --git a/drivers/net/ethernet/dec/tulip/tulip_core.c b/drivers/net/ethernet/dec/tulip/tulip_core.c
> index fea3641..25fe117 100644
> --- a/drivers/net/ethernet/dec/tulip/tulip_core.c
> +++ b/drivers/net/ethernet/dec/tulip/tulip_core.c
> @@ -328,7 +328,7 @@ static void tulip_up(struct net_device *dev)
>        udelay(100);
>
>        if (tulip_debug > 1)
> -               netdev_dbg(dev, "tulip_up(), irq==%d\n", dev->irq);
> +               netdev_dbg(dev, "tulip_up(), irq==%d\n", tp->pdev->irq);
>
>        iowrite32(tp->rx_ring_dma, ioaddr + CSR3);
>        iowrite32(tp->tx_ring_dma, ioaddr + CSR4);
> @@ -515,11 +515,13 @@ media_picked:
>  static int
>  tulip_open(struct net_device *dev)
>  {
> +       struct tulip_private *tp = netdev_priv(dev);
>        int retval;
>
>        tulip_init_ring (dev);
>
> -       retval = request_irq(dev->irq, tulip_interrupt, IRQF_SHARED, dev->name, dev);
> +       retval = request_irq(tp->pdev->irq, tulip_interrupt, IRQF_SHARED,
> +                            dev->name, dev);
>        if (retval)
>                goto free_ring;
>
> @@ -841,7 +843,7 @@ static int tulip_close (struct net_device *dev)
>                netdev_dbg(dev, "Shutting down ethercard, status was %02x\n",
>                           ioread32 (ioaddr + CSR5));
>
> -       free_irq (dev->irq, dev);
> +       free_irq (tp->pdev->irq, dev);
>
>        tulip_free_ring (dev);
>
> @@ -1489,8 +1491,6 @@ static int __devinit tulip_init_one (struct pci_dev *pdev,
>
>        INIT_WORK(&tp->media_work, tulip_tbl[tp->chip_id].media_task);
>
> -       dev->base_addr = (unsigned long)ioaddr;
> -
>  #ifdef CONFIG_TULIP_MWI
>        if (!force_csr0 && (tp->flags & HAS_PCI_MWI))
>                tulip_mwi_config (pdev, dev);
> @@ -1650,7 +1650,6 @@ static int __devinit tulip_init_one (struct pci_dev *pdev,
>        for (i = 0; i < 6; i++)
>                last_phys_addr[i] = dev->dev_addr[i];
>        last_irq = irq;
> -       dev->irq = irq;
>
>        /* The lower four bits are the media type. */
>        if (board_idx >= 0  &&  board_idx < MAX_UNITS) {
> @@ -1858,7 +1857,8 @@ static int tulip_suspend (struct pci_dev *pdev, pm_message_t state)
>        tulip_down(dev);
>
>        netif_device_detach(dev);
> -       free_irq(dev->irq, dev);
> +       /* FIXME: it needlessly adds an error path. */
> +       free_irq(tp->pdev->irq, dev);
>
>  save_state:
>        pci_save_state(pdev);
> @@ -1900,7 +1900,9 @@ static int tulip_resume(struct pci_dev *pdev)
>                return retval;
>        }
>
> -       if ((retval = request_irq(dev->irq, tulip_interrupt, IRQF_SHARED, dev->name, dev))) {
> +       retval = request_irq(pdev->irq, tulip_interrupt, IRQF_SHARED,
> +                            dev->name, dev);
> +       if (retval < 0) {
>                pr_err("request_irq failed in resume\n");
>                return retval;
>        }
> @@ -1960,11 +1962,14 @@ static void __devexit tulip_remove_one (struct pci_dev *pdev)
>
>  static void poll_tulip (struct net_device *dev)
>  {
> +       struct tulip_private *tp = netdev_priv(dev);
> +       const int irq = tp->pdev->irq;
> +
>        /* disable_irq here is not very nice, but with the lockless
>           interrupt handler we have no other choice. */
> -       disable_irq(dev->irq);
> -       tulip_interrupt (dev->irq, dev);
> -       enable_irq(dev->irq);
> +       disable_irq(irq);
> +       tulip_interrupt (irq, dev);
> +       enable_irq(irq);
>  }
>  #endif
>
> --
> 1.7.7.6
>

^ permalink raw reply

* INFO: rcu_sched detected stall on CPU 0 (with whost module)
From: Jean-Philippe Menil @ 2012-04-04 14:47 UTC (permalink / raw)
  To: netdev

Hi,

several times a day, i can observe the following trace:

Apr  3 19:51:41 ayrshire.u06.univ-nantes.prive kernel: [1659525.600004] 
INFO: rcu_sched detected stall on CPU 0 (t=6000 jiffies)
Apr  3 19:51:41 ayrshire.u06.univ-nantes.prive kernel: [1659525.600015] 
Pid: 2487, comm: vhost-2475 Not tainted 3.2.1-dsiun-120113 #55
Apr  3 19:51:41 ayrshire.u06.univ-nantes.prive kernel: [1659525.600015] 
Call Trace:
Apr  3 19:51:41 ayrshire.u06.univ-nantes.prive kernel: [1659525.600015] 
<IRQ>  [<ffffffff810ac986>] ? __rcu_pending+0x1e6/0x400
Apr  3 19:51:41 ayrshire.u06.univ-nantes.prive kernel: [1659525.600015]  
[<ffffffff810ace3b>] ? rcu_check_callbacks+0x6b/0x1d0
Apr  3 19:51:41 ayrshire.u06.univ-nantes.prive kernel: [1659525.600015]  
[<ffffffff810586df>] ? update_process_times+0x3f/0x80
Apr  3 19:51:41 ayrshire.u06.univ-nantes.prive kernel: [1659525.600015]  
[<ffffffff8107998b>] ? tick_sched_timer+0x5b/0xb0
Apr  3 19:51:41 ayrshire.u06.univ-nantes.prive kernel: [1659525.600015]  
[<ffffffff8106d099>] ? __run_hrtimer+0x69/0x1e0
Apr  3 19:51:41 ayrshire.u06.univ-nantes.prive kernel: [1659525.600015]  
[<ffffffff81079930>] ? tick_nohz_handler+0xe0/0xe0
Apr  3 19:51:41 ayrshire.u06.univ-nantes.prive kernel: [1659525.600015]  
[<ffffffff81009e85>] ? read_tsc+0x5/0x20
Apr  3 19:51:41 ayrshire.u06.univ-nantes.prive kernel: [1659525.600015]  
[<ffffffff8106d9d5>] ? hrtimer_interrupt+0xe5/0x200
Apr  3 19:51:41 ayrshire.u06.univ-nantes.prive kernel: [1659525.600015]  
[<ffffffff8101f563>] ? smp_apic_timer_interrupt+0x63/0xa0
Apr  3 19:51:41 ayrshire.u06.univ-nantes.prive kernel: [1659525.600015]  
[<ffffffff813ad79e>] ? apic_timer_interrupt+0x6e/0x80
Apr  3 19:51:41 ayrshire.u06.univ-nantes.prive kernel: [1659525.600015]  
[<ffffffff812f1d01>] ? __kfree_skb+0x11/0x90
Apr  3 19:51:41 ayrshire.u06.univ-nantes.prive kernel: [1659525.600015]  
[<ffffffffa00d4437>] ? bnx2_poll_work+0x247/0x1370 [bnx2]
Apr  3 19:51:41 ayrshire.u06.univ-nantes.prive kernel: [1659525.600015]  
[<ffffffffa00d4437>] ? bnx2_poll_work+0x247/0x1370 [bnx2]
Apr  3 19:51:41 ayrshire.u06.univ-nantes.prive kernel: [1659525.600015]  
[<ffffffff813a6e7c>] ? put_cpu_partial+0x90/0x90
Apr  3 19:51:41 ayrshire.u06.univ-nantes.prive kernel: [1659525.600015]  
[<ffffffff8111b453>] ? kmem_cache_free+0x103/0x110
Apr  3 19:51:41 ayrshire.u06.univ-nantes.prive kernel: [1659525.600015]  
[<ffffffffa00d4437>] ? bnx2_poll_work+0x247/0x1370 [bnx2]
Apr  3 19:51:41 ayrshire.u06.univ-nantes.prive kernel: [1659525.600015]  
[<ffffffffa00d5691>] ? bnx2_poll+0x61/0x264 [bnx2]
Apr  3 19:51:41 ayrshire.u06.univ-nantes.prive kernel: [1659525.600015]  
[<ffffffff812febd9>] ? net_rx_action+0x119/0x260
Apr  3 19:51:41 ayrshire.u06.univ-nantes.prive kernel: [1659525.600015]  
[<ffffffff8104fa1d>] ? __do_softirq+0x9d/0x1f0
Apr  3 19:51:41 ayrshire.u06.univ-nantes.prive kernel: [1659525.600015]  
[<ffffffff813aef2c>] ? call_softirq+0x1c/0x30
Apr  3 19:51:41 ayrshire.u06.univ-nantes.prive kernel: [1659525.600015]  
[<ffffffff813aef2c>] ? call_softirq+0x1c/0x30
Apr  3 19:51:41 ayrshire.u06.univ-nantes.prive kernel: [1659525.600015] 
<EOI>  [<ffffffff81004725>] ? do_softirq+0x65/0xa0
Apr  3 19:51:41 ayrshire.u06.univ-nantes.prive kernel: [1659525.600015]  
[<ffffffff812ff05e>] ? netif_rx_ni+0x1e/0x30
Apr  3 19:51:41 ayrshire.u06.univ-nantes.prive kernel: [1659525.600015]  
[<ffffffffa04fb5af>] ? tun_get_user+0x30f/0x4c0 [tun]
Apr  3 19:51:41 ayrshire.u06.univ-nantes.prive kernel: [1659525.600015]  
[<ffffffffa04fb780>] ? tun_sendmsg+0x20/0x30 [tun]
Apr  3 19:51:41 ayrshire.u06.univ-nantes.prive kernel: [1659525.600015]  
[<ffffffffa051426e>] ? handle_tx+0x27e/0x4f0 [vhost_net]
Apr  3 19:51:41 ayrshire.u06.univ-nantes.prive kernel: [1659525.600015]  
[<ffffffffa0511781>] ? vhost_worker+0xc1/0x150 [vhost_net]
Apr  3 19:51:41 ayrshire.u06.univ-nantes.prive kernel: [1659525.600015]  
[<ffffffffa05116c0>] ? memory_access_ok.isra.11+0xd0/0xd0 [vhost_net]
Apr  3 19:51:41 ayrshire.u06.univ-nantes.prive kernel: [1659525.600015]  
[<ffffffff8106905e>] ? kthread+0x7e/0x90
Apr  3 19:51:41 ayrshire.u06.univ-nantes.prive kernel: [1659525.600015]  
[<ffffffff813aee34>] ? kernel_thread_helper+0x4/0x10
Apr  3 19:51:41 ayrshire.u06.univ-nantes.prive kernel: [1659525.600015]  
[<ffffffff81068fe0>] ? kthread_worker_fn+0x190/0x190
Apr  3 19:51:41 ayrshire.u06.univ-nantes.prive kernel: [1659525.600015]  
[<ffffffff813aee30>] ? gs_change+0x13/0x13
Apr  3 19:59:23 ayrshire.u06.univ-nantes.prive kernel: [1659986.950000] 
INFO: rcu_sched detected stall on CPU 0 (t=6000 jiffies)
Apr  3 19:59:23 ayrshire.u06.univ-nantes.prive kernel: [1659986.950014] 
Pid: 2485, comm: vhost-2475 Not tainted 3.2.1-dsiun-120113 #55
Apr  3 19:59:23 ayrshire.u06.univ-nantes.prive kernel: [1659986.950014] 
Call Trace:
Apr  3 19:59:23 ayrshire.u06.univ-nantes.prive kernel: [1659986.950014] 
<IRQ>  [<ffffffff810ac986>] ? __rcu_pending+0x1e6/0x400
Apr  3 19:59:23 ayrshire.u06.univ-nantes.prive kernel: [1659986.950014]  
[<ffffffff810ace3b>] ? rcu_check_callbacks+0x6b/0x1d0
Apr  3 19:59:23 ayrshire.u06.univ-nantes.prive kernel: [1659986.950014]  
[<ffffffff810586df>] ? update_process_times+0x3f/0x80
Apr  3 19:59:23 ayrshire.u06.univ-nantes.prive kernel: [1659986.950014]  
[<ffffffff8107998b>] ? tick_sched_timer+0x5b/0xb0
Apr  3 19:59:23 ayrshire.u06.univ-nantes.prive kernel: [1659986.950014]  
[<ffffffff8106d099>] ? __run_hrtimer+0x69/0x1e0
Apr  3 19:59:23 ayrshire.u06.univ-nantes.prive kernel: [1659986.950014]  
[<ffffffff81079930>] ? tick_nohz_handler+0xe0/0xe0
Apr  3 19:59:23 ayrshire.u06.univ-nantes.prive kernel: [1659986.950014]  
[<ffffffff81009e85>] ? read_tsc+0x5/0x20
Apr  3 19:59:23 ayrshire.u06.univ-nantes.prive kernel: [1659986.950014]  
[<ffffffff8106d9d5>] ? hrtimer_interrupt+0xe5/0x200
Apr  3 19:59:23 ayrshire.u06.univ-nantes.prive kernel: [1659986.950014]  
[<ffffffff8101f563>] ? smp_apic_timer_interrupt+0x63/0xa0
Apr  3 19:59:23 ayrshire.u06.univ-nantes.prive kernel: [1659986.950014]  
[<ffffffff8111b1c7>] ? unfreeze_partials+0xc7/0x250
Apr  3 19:59:23 ayrshire.u06.univ-nantes.prive kernel: [1659986.950014]  
[<ffffffff813ad79e>] ? apic_timer_interrupt+0x6e/0x80
Apr  3 19:59:23 ayrshire.u06.univ-nantes.prive kernel: [1659986.950014]  
[<ffffffff812f1fc5>] ? skb_release_head_state+0xa5/0x110
Apr  3 19:59:23 ayrshire.u06.univ-nantes.prive kernel: [1659986.950014]  
[<ffffffff813a6e33>] ? put_cpu_partial+0x47/0x90
Apr  3 19:59:23 ayrshire.u06.univ-nantes.prive kernel: [1659986.950014]  
[<ffffffff812f1fc5>] ? skb_release_head_state+0xa5/0x110
Apr  3 19:59:23 ayrshire.u06.univ-nantes.prive kernel: [1659986.950014]  
[<ffffffff812f1cf9>] ? __kfree_skb+0x9/0x90
Apr  3 19:59:23 ayrshire.u06.univ-nantes.prive kernel: [1659986.950014]  
[<ffffffffa00d4437>] ? bnx2_poll_work+0x247/0x1370 [bnx2]
Apr  3 19:59:23 ayrshire.u06.univ-nantes.prive kernel: [1659986.950014]  
[<ffffffffa00d5691>] ? bnx2_poll+0x61/0x264 [bnx2]
Apr  3 19:59:23 ayrshire.u06.univ-nantes.prive kernel: [1659986.950014]  
[<ffffffff8134e3d0>] ? tcp_init_xmit_timers+0x20/0x20
Apr  3 19:59:23 ayrshire.u06.univ-nantes.prive kernel: [1659986.950014]  
[<ffffffff812febd9>] ? net_rx_action+0x119/0x260
Apr  3 19:59:23 ayrshire.u06.univ-nantes.prive kernel: [1659986.950014]  
[<ffffffff8104fa1d>] ? __do_softirq+0x9d/0x1f0
Apr  3 19:59:23 ayrshire.u06.univ-nantes.prive kernel: [1659986.950014]  
[<ffffffff813aef2c>] ? call_softirq+0x1c/0x30
Apr  3 19:59:23 ayrshire.u06.univ-nantes.prive kernel: [1659986.950014] 
<EOI>  [<ffffffff81004725>] ? do_softirq+0x65/0xa0
Apr  3 19:59:23 ayrshire.u06.univ-nantes.prive kernel: [1659986.950014]  
[<ffffffff812ff05e>] ? netif_rx_ni+0x1e/0x30
Apr  3 19:59:23 ayrshire.u06.univ-nantes.prive kernel: [1659986.950014]  
[<ffffffffa04fb5af>] ? tun_get_user+0x30f/0x4c0 [tun]
Apr  3 19:59:23 ayrshire.u06.univ-nantes.prive kernel: [1659986.950014]  
[<ffffffffa04fb780>] ? tun_sendmsg+0x20/0x30 [tun]
Apr  3 19:59:23 ayrshire.u06.univ-nantes.prive kernel: [1659986.950014]  
[<ffffffffa051426e>] ? handle_tx+0x27e/0x4f0 [vhost_net]
Apr  3 19:59:23 ayrshire.u06.univ-nantes.prive kernel: [1659986.950014]  
[<ffffffffa0511781>] ? vhost_worker+0xc1/0x150 [vhost_net]
Apr  3 19:59:23 ayrshire.u06.univ-nantes.prive kernel: [1659986.950014]  
[<ffffffffa05116c0>] ? memory_access_ok.isra.11+0xd0/0xd0 [vhost_net]
Apr  3 19:59:23 ayrshire.u06.univ-nantes.prive kernel: [1659986.950014]  
[<ffffffff8106905e>] ? kthread+0x7e/0x90
Apr  3 19:59:23 ayrshire.u06.univ-nantes.prive kernel: [1659986.950014]  
[<ffffffff813aee34>] ? kernel_thread_helper+0x4/0x10
Apr  3 19:59:23 ayrshire.u06.univ-nantes.prive kernel: [1659986.950014]  
[<ffffffff81068fe0>] ? kthread_worker_fn+0x190/0x190
Apr  3 19:59:23 ayrshire.u06.univ-nantes.prive kernel: [1659986.950014]  
[<ffffffff813aee30>] ? gs_change+0x13/0x13

This host run several kvm (with multiple tun/tap devices attached on 
bridge) with the vhost module with experimental_zcopytx to 1

Both eth0 and eth2 are BCM5708S, with followinf parameter:
root@ayrshire:~# ethtool -k eth0
Offload parameters for eth0:
rx-checksumming: on
tx-checksumming: on
scatter-gather: on
tcp-segmentation-offload: on
udp-fragmentation-offload: off
generic-segmentation-offload: on
generic-receive-offload: on
large-receive-offload: off
ntuple-filters: off
receive-hashing: on

root@ayrshire:~# ethtool -i eth0
driver: bnx2
version: 2.1.11
firmware-version: 5.2.7 bc 5.0.5
bus-info: 0000:04:00.0

Is it a know issue?

Regards


-- 
Jean-Philippe Menil - Pôle réseau Service IRTS
DSI Université de Nantes
jean-philippe.menil@univ-nantes.fr
Tel : 02.53.48.49.27 - Fax : 02.53.48.49.09

^ permalink raw reply

* Re: [PATCH] netfilter: don't scale the size of the window up twice
From: Pablo Neira Ayuso @ 2012-04-04 15:08 UTC (permalink / raw)
  To: Jozsef Kadlecsik
  Cc: Patrick McHardy, David S. Miller, netfilter-devel, netdev,
	Changli Gao
In-Reply-To: <1333337106-8279-1-git-send-email-xiaosuo@gmail.com>

On Mon, Apr 02, 2012 at 11:25:06AM +0800, Changli Gao wrote:
> For a picked up connection, the window win is scaled twice: one is by the
> initialization code, and the other is by the sender updating code.
> 
> I use the temporary variable swin instead of modifying the variable win.
> 
> Signed-off-by: Changli Gao <xiaosuo@gmail.com>
> ---
>  net/netfilter/nf_conntrack_proto_tcp.c |    4 ++--
>  1 file changed, 2 insertions(+), 2 deletions(-)
> diff --git a/net/netfilter/nf_conntrack_proto_tcp.c b/net/netfilter/nf_conntrack_proto_tcp.c
> index 361eade..0d07a1d 100644
> --- a/net/netfilter/nf_conntrack_proto_tcp.c
> +++ b/net/netfilter/nf_conntrack_proto_tcp.c
> @@ -584,8 +584,8 @@ static bool tcp_in_window(const struct nf_conn *ct,
>  			 * Let's try to use the data from the packet.
>  			 */
>  			sender->td_end = end;
> -			win <<= sender->td_scale;
> -			sender->td_maxwin = (win == 0 ? 1 : win);
> +			swin = win << sender->td_scale;
> +			sender->td_maxwin = (swin == 0 ? 1 : swin);
>  			sender->td_maxend = end + sender->td_maxwin;
>  			/*
>  			 * We haven't seen traffic in the other direction yet

Jozsef, do you remember if this is intentional?

I'm going to test this patch in my testbed to make sure this does not
break conntrackd.

^ permalink raw reply

* [PATCH 0/7] bna: Update driver version to 3.0.23.0 (resubmit)
From: Jing Huang @ 2012-04-04 15:41 UTC (permalink / raw)
  To: davem, netdev; +Cc: AdapterLinuxOpenSrcExtTeam, Jing Huang

I am resubmit this patch set since it seems that the net-next merge window is
over. 

This patch set contains fixes in adapter initialization and tx/rx cleanup path.
It also include code cleanups by removing and renaming some functions.

The driver version has been updated to 3.0.23.0 to reflect the changes.

Jing Huang (7):
  bna: Serialize smem access during adapter initialization
  bna: Flash controller ioc pll init fixes
  bna: ioc cleanups
  bfa: tx rx cleanup fix
  bna: Remove tx tasklet
  bfa: Function name changes and cleanups
  bfa: Update driver version to 3.0.23.0

 drivers/net/ethernet/brocade/bna/bfa_ioc.c      |   61 +++--
 drivers/net/ethernet/brocade/bna/bfa_ioc_ct.c   |  142 +++++++----
 drivers/net/ethernet/brocade/bna/bfi_reg.h      |    6 +
 drivers/net/ethernet/brocade/bna/bnad.c         |  316 +++++++++++------------
 drivers/net/ethernet/brocade/bna/bnad.h         |   11 +-
 drivers/net/ethernet/brocade/bna/bnad_ethtool.c |    6 +-
 6 files changed, 300 insertions(+), 242 deletions(-)

^ permalink raw reply

* [PATCH 1/7] bna: Serialize smem access during adapter initialization
From: Jing Huang @ 2012-04-04 15:42 UTC (permalink / raw)
  To: davem, netdev; +Cc: AdapterLinuxOpenSrcExtTeam, Jing Huang

Use init semaphore to serialize execution of the "unlock IOC semaphore"
code. Added bfa_ioc_fwver_clear() function to clear the firmware header if
last firmwar boot is not from driver.

Signed-off-by: Jing Huang <huangj@brocade.com>
---
 drivers/net/ethernet/brocade/bna/bfa_ioc.c |   50 +++++++++++++++++++++++----
 1 files changed, 42 insertions(+), 8 deletions(-)

diff --git a/drivers/net/ethernet/brocade/bna/bfa_ioc.c b/drivers/net/ethernet/brocade/bna/bfa_ioc.c
index 77977d7..7a3e79c 100644
--- a/drivers/net/ethernet/brocade/bna/bfa_ioc.c
+++ b/drivers/net/ethernet/brocade/bna/bfa_ioc.c
@@ -1207,27 +1207,62 @@ bfa_nw_ioc_sem_release(void __iomem *sem_reg)
 	writel(1, sem_reg);
 }
 
+/* Clear fwver hdr */
+static void
+bfa_ioc_fwver_clear(struct bfa_ioc *ioc)
+{
+	u32 pgnum, pgoff, loff = 0;
+	int i;
+
+	pgnum = PSS_SMEM_PGNUM(ioc->ioc_regs.smem_pg0, loff);
+	pgoff = PSS_SMEM_PGOFF(loff);
+	writel(pgnum, ioc->ioc_regs.host_page_num_fn);
+
+	for (i = 0; i < (sizeof(struct bfi_ioc_image_hdr) / sizeof(u32)); i++) {
+		writel(0, ioc->ioc_regs.smem_page_start + loff);
+		loff += sizeof(u32);
+	}
+}
+
+
 static void
 bfa_ioc_hw_sem_init(struct bfa_ioc *ioc)
 {
 	struct bfi_ioc_image_hdr fwhdr;
-	u32 fwstate = readl(ioc->ioc_regs.ioc_fwstate);
+	u32 fwstate, r32;
 
-	if (fwstate == BFI_IOC_UNINIT)
+	/* Spin on init semaphore to serialize. */
+	r32 = readl(ioc->ioc_regs.ioc_init_sem_reg);
+	while (r32 & 0x1) {
+		udelay(20);
+		r32 = readl(ioc->ioc_regs.ioc_init_sem_reg);
+	}
+
+	fwstate = readl(ioc->ioc_regs.ioc_fwstate);
+	if (fwstate == BFI_IOC_UNINIT) {
+		writel(1, ioc->ioc_regs.ioc_init_sem_reg);
 		return;
+	}
 
 	bfa_nw_ioc_fwver_get(ioc, &fwhdr);
 
-	if (swab32(fwhdr.exec) == BFI_FWBOOT_TYPE_NORMAL)
+	if (swab32(fwhdr.exec) == BFI_FWBOOT_TYPE_NORMAL) {
+		writel(1, ioc->ioc_regs.ioc_init_sem_reg);
 		return;
+	}
 
+	bfa_ioc_fwver_clear(ioc);
 	writel(BFI_IOC_UNINIT, ioc->ioc_regs.ioc_fwstate);
+	writel(BFI_IOC_UNINIT, ioc->ioc_regs.alt_ioc_fwstate);
 
 	/*
 	 * Try to lock and then unlock the semaphore.
 	 */
 	readl(ioc->ioc_regs.ioc_sem_reg);
 	writel(1, ioc->ioc_regs.ioc_sem_reg);
+
+	/* Unlock init semaphore */
+	writel(1, ioc->ioc_regs.ioc_init_sem_reg);
 }
 
 static void
@@ -1585,11 +1620,6 @@ bfa_ioc_download_fw(struct bfa_ioc *ioc, u32 boot_type,
 	u32 i;
 	u32 asicmode;
 
-	/**
-	 * Initialize LMEM first before code download
-	 */
-	bfa_ioc_lmem_init(ioc);
-
 	fwimg = bfa_cb_image_get_chunk(bfa_ioc_asic_gen(ioc), chunkno);
 
 	pgnum = bfa_ioc_smem_pgnum(ioc, loff);
@@ -1914,6 +1944,10 @@ bfa_ioc_pll_init(struct bfa_ioc *ioc)
 	bfa_ioc_pll_init_asic(ioc);
 
 	ioc->pllinit = true;
+
+	/* Initialize LMEM */
+	bfa_ioc_lmem_init(ioc);
+
 	/*
 	 *  release semaphore.
 	 */
-- 
1.6.5.2

^ permalink raw reply related

* [PATCH 2/7] bna: Flash controller ioc pll init fixes
From: Jing Huang @ 2012-04-04 15:42 UTC (permalink / raw)
  To: davem, netdev; +Cc: AdapterLinuxOpenSrcExtTeam, Jing Huang

Added NFC pause/resume logic. We only do NFC pause/resume if NFC version
is greater than 0x143 and it was halted before, otherwise we revert to
old NFC halt mechanism.

Made changes to avoid clearing off the interrupts during the initial
pll initialization.

Signed-off-by: Jing Huang <huangj@brocade.com>
---
 drivers/net/ethernet/brocade/bna/bfa_ioc_ct.c |  142 +++++++++++++++++--------
 drivers/net/ethernet/brocade/bna/bfi_reg.h    |    6 +
 2 files changed, 102 insertions(+), 46 deletions(-)

diff --git a/drivers/net/ethernet/brocade/bna/bfa_ioc_ct.c b/drivers/net/ethernet/brocade/bna/bfa_ioc_ct.c
index 348479b..b6b036a 100644
--- a/drivers/net/ethernet/brocade/bna/bfa_ioc_ct.c
+++ b/drivers/net/ethernet/brocade/bna/bfa_ioc_ct.c
@@ -199,9 +199,9 @@ bfa_ioc_ct_notify_fail(struct bfa_ioc *ioc)
  * Host to LPU mailbox message addresses
  */
 static const struct {
-	u32 	hfn_mbox;
-	u32 	lpu_mbox;
-	u32 	hfn_pgn;
+	u32	hfn_mbox;
+	u32	lpu_mbox;
+	u32	hfn_pgn;
 } ct_fnreg[] = {
 	{ HOSTFN0_LPU_MBOX0_0, LPU_HOSTFN0_MBOX0_0, HOST_PAGE_NUM_FN0 },
 	{ HOSTFN1_LPU_MBOX0_8, LPU_HOSTFN1_MBOX0_8, HOST_PAGE_NUM_FN1 },
@@ -803,17 +803,72 @@ bfa_ioc_ct2_mac_reset(void __iomem *rb)
 }
 
 #define CT2_NFC_MAX_DELAY       1000
+#define CT2_NFC_VER_VALID       0x143
+#define BFA_IOC_PLL_POLL        1000000
+
+static bool
+bfa_ioc_ct2_nfc_halted(void __iomem *rb)
+{
+	volatile u32 r32;
+
+	r32 = readl(rb + CT2_NFC_CSR_SET_REG);
+	if (r32 & __NFC_CONTROLLER_HALTED)
+		return true;
+
+	return false;
+}
+
+static void
+bfa_ioc_ct2_nfc_resume(void __iomem *rb)
+{
+	volatile u32 r32;
+	int i;
+
+	writel(__HALT_NFC_CONTROLLER, rb + CT2_NFC_CSR_CLR_REG);
+	for (i = 0; i < CT2_NFC_MAX_DELAY; i++) {
+		r32 = readl(rb + CT2_NFC_CSR_SET_REG);
+		if (!(r32 & __NFC_CONTROLLER_HALTED))
+			return;
+		udelay(1000);
+	}
+	BUG_ON(1);
+}
+
 static enum bfa_status
 bfa_ioc_ct2_pll_init(void __iomem *rb, enum bfi_asic_mode asic_mode)
 {
 	volatile u32 wgn, r32;
-	int i;
+	u32 nfc_ver, i;
 
-	/*
-	 * Initialize PLL if not already done by NFC
-	 */
 	wgn = readl(rb + CT2_WGN_STATUS);
-	if (!(wgn & __GLBL_PF_VF_CFG_RDY)) {
+
+	nfc_ver = readl(rb + CT2_RSC_GPR15_REG);
+
+	if ((wgn == (__A2T_AHB_LOAD | __WGN_READY)) &&
+		(nfc_ver >= CT2_NFC_VER_VALID)) {
+		if (bfa_ioc_ct2_nfc_halted(rb))
+			bfa_ioc_ct2_nfc_resume(rb);
+		writel(__RESET_AND_START_SCLK_LCLK_PLLS,
+				rb + CT2_CSI_FW_CTL_SET_REG);
+
+		for (i = 0; i < BFA_IOC_PLL_POLL; i++) {
+			r32 = readl(rb + CT2_APP_PLL_LCLK_CTL_REG);
+			if (r32 & __RESET_AND_START_SCLK_LCLK_PLLS)
+				break;
+		}
+		BUG_ON(!(r32 & __RESET_AND_START_SCLK_LCLK_PLLS));
+
+		for (i = 0; i < BFA_IOC_PLL_POLL; i++) {
+			r32 = readl(rb + CT2_APP_PLL_LCLK_CTL_REG);
+			if (!(r32 & __RESET_AND_START_SCLK_LCLK_PLLS))
+				break;
+		}
+		BUG_ON(r32 & __RESET_AND_START_SCLK_LCLK_PLLS);
+		udelay(1000);
+
+		r32 = readl(rb + CT2_CSI_FW_CTL_REG);
+		BUG_ON(r32 & __RESET_AND_START_SCLK_LCLK_PLLS);
+	} else {
 		writel(__HALT_NFC_CONTROLLER, (rb + CT2_NFC_CSR_SET_REG));
 		for (i = 0; i < CT2_NFC_MAX_DELAY; i++) {
 			r32 = readl(rb + CT2_NFC_CSR_SET_REG);
@@ -821,53 +876,48 @@ bfa_ioc_ct2_pll_init(void __iomem *rb, enum bfi_asic_mode asic_mode)
 				break;
 			udelay(1000);
 		}
+
+		bfa_ioc_ct2_mac_reset(rb);
+		bfa_ioc_ct2_sclk_init(rb);
+		bfa_ioc_ct2_lclk_init(rb);
+
+		/* release soft reset on s_clk & l_clk */
+		r32 = readl((rb + CT2_APP_PLL_SCLK_CTL_REG));
+		writel(r32 & ~__APP_PLL_SCLK_LOGIC_SOFT_RESET,
+				rb + CT2_APP_PLL_SCLK_CTL_REG);
+		r32 = readl((rb + CT2_APP_PLL_LCLK_CTL_REG));
+		writel(r32 & ~__APP_PLL_LCLK_LOGIC_SOFT_RESET,
+				rb + CT2_APP_PLL_LCLK_CTL_REG);
+	}
+
+	/* Announce flash device presence, if flash was corrupted. */
+	if (wgn == (__WGN_READY | __GLBL_PF_VF_CFG_RDY)) {
+		r32 = readl((rb + PSS_GPIO_OUT_REG));
+		writel(r32 & ~1, rb + PSS_GPIO_OUT_REG);
+		r32 = readl((rb + PSS_GPIO_OE_REG));
+		writel(r32 | 1, rb + PSS_GPIO_OE_REG);
 	}
 
 	/*
 	 * Mask the interrupts and clear any
 	 * pending interrupts left by BIOS/EFI
 	 */
-
 	writel(1, (rb + CT2_LPU0_HOSTFN_MBOX0_MSK));
 	writel(1, (rb + CT2_LPU1_HOSTFN_MBOX0_MSK));
 
-	r32 = readl((rb + CT2_LPU0_HOSTFN_CMD_STAT));
-	if (r32 == 1) {
-		writel(1, (rb + CT2_LPU0_HOSTFN_CMD_STAT));
-		readl((rb + CT2_LPU0_HOSTFN_CMD_STAT));
-	}
-	r32 = readl((rb + CT2_LPU1_HOSTFN_CMD_STAT));
-	if (r32 == 1) {
-		writel(1, (rb + CT2_LPU1_HOSTFN_CMD_STAT));
-		readl((rb + CT2_LPU1_HOSTFN_CMD_STAT));
-	}
-
-	bfa_ioc_ct2_mac_reset(rb);
-	bfa_ioc_ct2_sclk_init(rb);
-	bfa_ioc_ct2_lclk_init(rb);
-
-	/*
-	 * release soft reset on s_clk & l_clk
-	 */
-	r32 = readl((rb + CT2_APP_PLL_SCLK_CTL_REG));
-	writel((r32 & ~__APP_PLL_SCLK_LOGIC_SOFT_RESET),
-			(rb + CT2_APP_PLL_SCLK_CTL_REG));
-
-	/*
-	 * release soft reset on s_clk & l_clk
-	 */
-	r32 = readl((rb + CT2_APP_PLL_LCLK_CTL_REG));
-	writel(r32 & ~__APP_PLL_LCLK_LOGIC_SOFT_RESET,
-		      (rb + CT2_APP_PLL_LCLK_CTL_REG));
-
-	/*
-	 * Announce flash device presence, if flash was corrupted.
-	 */
-	if (wgn == (__WGN_READY | __GLBL_PF_VF_CFG_RDY)) {
-		r32 = readl((rb + PSS_GPIO_OUT_REG));
-		writel((r32 & ~1), (rb + PSS_GPIO_OUT_REG));
-		r32 = readl((rb + PSS_GPIO_OE_REG));
-		writel((r32 | 1), (rb + PSS_GPIO_OE_REG));
+	/* For first time initialization, no need to clear interrupts */
+	r32 = readl(rb + HOST_SEM5_REG);
+	if (r32 & 0x1) {
+		r32 = readl((rb + CT2_LPU0_HOSTFN_CMD_STAT));
+		if (r32 == 1) {
+			writel(1, (rb + CT2_LPU0_HOSTFN_CMD_STAT));
+			readl((rb + CT2_LPU0_HOSTFN_CMD_STAT));
+		}
+		r32 = readl((rb + CT2_LPU1_HOSTFN_CMD_STAT));
+		if (r32 == 1) {
+			writel(1, (rb + CT2_LPU1_HOSTFN_CMD_STAT));
+			readl((rb + CT2_LPU1_HOSTFN_CMD_STAT));
+		}
 	}
 
 	bfa_ioc_ct2_mem_init(rb);
diff --git a/drivers/net/ethernet/brocade/bna/bfi_reg.h b/drivers/net/ethernet/brocade/bna/bfi_reg.h
index efacff3..0e094fe 100644
--- a/drivers/net/ethernet/brocade/bna/bfi_reg.h
+++ b/drivers/net/ethernet/brocade/bna/bfi_reg.h
@@ -339,10 +339,16 @@ enum {
 #define __A2T_AHB_LOAD			0x00000800
 #define __WGN_READY			0x00000400
 #define __GLBL_PF_VF_CFG_RDY		0x00000200
+#define CT2_NFC_CSR_CLR_REG             0x00027420
 #define CT2_NFC_CSR_SET_REG		0x00027424
 #define __HALT_NFC_CONTROLLER		0x00000002
 #define __NFC_CONTROLLER_HALTED		0x00001000
 
+#define CT2_RSC_GPR15_REG		0x0002765c
+#define CT2_CSI_FW_CTL_REG              0x00027080
+#define __RESET_AND_START_SCLK_LCLK_PLLS 0x00010000
+#define CT2_CSI_FW_CTL_SET_REG          0x00027088
+
 #define CT2_CSI_MAC0_CONTROL_REG	0x000270d0
 #define __CSI_MAC_RESET			0x00000010
 #define __CSI_MAC_AHB_RESET		0x00000008
-- 
1.6.5.2

^ permalink raw reply related

* [PATCH 3/7] bna: ioc cleanups
From: Jing Huang @ 2012-04-04 15:42 UTC (permalink / raw)
  To: davem, netdev; +Cc: AdapterLinuxOpenSrcExtTeam, Jing Huang

Remove irrelevant code. Change to start Hearbeat failure moniter after IOC
become operational.

Signed-off-by: Jing Huang <huangj@brocade.com>
---
 drivers/net/ethernet/brocade/bna/bfa_ioc.c |   11 +----------
 1 files changed, 1 insertions(+), 10 deletions(-)

diff --git a/drivers/net/ethernet/brocade/bna/bfa_ioc.c b/drivers/net/ethernet/brocade/bna/bfa_ioc.c
index 7a3e79c..0b640fa 100644
--- a/drivers/net/ethernet/brocade/bna/bfa_ioc.c
+++ b/drivers/net/ethernet/brocade/bna/bfa_ioc.c
@@ -70,7 +70,6 @@ static void bfa_ioc_reset(struct bfa_ioc *ioc, bool force);
 static void bfa_ioc_mbox_poll(struct bfa_ioc *ioc);
 static void bfa_ioc_mbox_flush(struct bfa_ioc *ioc);
 static void bfa_ioc_recover(struct bfa_ioc *ioc);
-static void bfa_ioc_check_attr_wwns(struct bfa_ioc *ioc);
 static void bfa_ioc_event_notify(struct bfa_ioc *, enum bfa_ioc_event);
 static void bfa_ioc_disable_comp(struct bfa_ioc *ioc);
 static void bfa_ioc_lpu_stop(struct bfa_ioc *ioc);
@@ -346,8 +345,6 @@ bfa_ioc_sm_getattr(struct bfa_ioc *ioc, enum ioc_event event)
 	switch (event) {
 	case IOC_E_FWRSP_GETATTR:
 		del_timer(&ioc->ioc_timer);
-		bfa_ioc_check_attr_wwns(ioc);
-		bfa_ioc_hb_monitor(ioc);
 		bfa_fsm_set_state(ioc, bfa_ioc_sm_op);
 		break;
 
@@ -380,6 +377,7 @@ bfa_ioc_sm_op_entry(struct bfa_ioc *ioc)
 {
 	ioc->cbfn->enable_cbfn(ioc->bfa, BFA_STATUS_OK);
 	bfa_ioc_event_notify(ioc, BFA_IOC_E_ENABLED);
+	bfa_ioc_hb_monitor(ioc);
 }
 
 static void
@@ -2547,13 +2545,6 @@ bfa_ioc_recover(struct bfa_ioc *ioc)
 	bfa_fsm_send_event(ioc, IOC_E_HBFAIL);
 }
 
-static void
-bfa_ioc_check_attr_wwns(struct bfa_ioc *ioc)
-{
-	if (bfa_ioc_get_type(ioc) == BFA_IOC_TYPE_LL)
-		return;
-}
-
 /**
  * @dg hal_iocpf_pvt BFA IOC PF private functions
  * @{
-- 
1.6.5.2

^ permalink raw reply related

* [PATCH 4/7] bna: tx rx cleanup fix
From: Jing Huang @ 2012-04-04 15:43 UTC (permalink / raw)
  To: davem, netdev; +Cc: AdapterLinuxOpenSrcExtTeam, Jing Huang

This patch removes busy wait in tx/rx cleanup. bnad_cb_tx_cleanup() and
bnad_cb_rx_cleanup() functions are called from irq context, and currently
they do busy wait for the in-flight transmit or the currently executing napi
polling routine to complete. To fix the issue, we create a workqueue to defer
tx & rx cleanup processing, an in the tx rx cleanup handler, we will
wait respective in flight processing to complete, before freeing the buffers.

Signed-off-by: Jing Huang <huangj@brocade.com>
---
 drivers/net/ethernet/brocade/bna/bnad.c |  201 +++++++++++++++++++------------
 drivers/net/ethernet/brocade/bna/bnad.h |    4 +
 2 files changed, 125 insertions(+), 80 deletions(-)

diff --git a/drivers/net/ethernet/brocade/bna/bnad.c b/drivers/net/ethernet/brocade/bna/bnad.c
index ff78f77..032a306 100644
--- a/drivers/net/ethernet/brocade/bna/bnad.c
+++ b/drivers/net/ethernet/brocade/bna/bnad.c
@@ -80,8 +80,6 @@ do {								\
 	(sizeof(struct bnad_skb_unmap) * ((_depth) - 1));	\
 } while (0)
 
-#define BNAD_TXRX_SYNC_MDELAY	250	/* 250 msecs */
-
 static void
 bnad_add_to_list(struct bnad *bnad)
 {
@@ -141,7 +139,8 @@ bnad_pci_unmap_skb(struct device *pdev, struct bnad_skb_unmap *array,
 
 	for (j = 0; j < frag; j++) {
 		dma_unmap_page(pdev, dma_unmap_addr(&array[index], dma_addr),
-			  skb_frag_size(&skb_shinfo(skb)->frags[j]), DMA_TO_DEVICE);
+			  skb_frag_size(&skb_shinfo(skb)->frags[j]),
+						DMA_TO_DEVICE);
 		dma_unmap_addr_set(&array[index], dma_addr, 0);
 		BNA_QE_INDX_ADD(index, 1, depth);
 	}
@@ -453,12 +452,8 @@ bnad_poll_cq(struct bnad *bnad, struct bna_ccb *ccb, int budget)
 	struct bna_pkt_rate *pkt_rt = &ccb->pkt_rate;
 	struct bnad_rx_ctrl *rx_ctrl = (struct bnad_rx_ctrl *)(ccb->ctrl);
 
-	set_bit(BNAD_FP_IN_RX_PATH, &rx_ctrl->flags);
-
-	if (!test_bit(BNAD_RXQ_STARTED, &ccb->rcb[0]->flags)) {
-		clear_bit(BNAD_FP_IN_RX_PATH, &rx_ctrl->flags);
+	if (!test_bit(BNAD_RXQ_STARTED, &ccb->rcb[0]->flags))
 		return 0;
-	}
 
 	prefetch(bnad->netdev);
 	BNA_CQ_QPGE_PTR_GET(ccb->producer_index, ccb->sw_qpt, cmpl,
@@ -533,9 +528,8 @@ bnad_poll_cq(struct bnad *bnad, struct bna_ccb *ccb, int budget)
 
 		if (skb->ip_summed == CHECKSUM_UNNECESSARY)
 			napi_gro_receive(&rx_ctrl->napi, skb);
-		else {
+		else
 			netif_receive_skb(skb);
-		}
 
 next:
 		cmpl->valid = 0;
@@ -839,20 +833,9 @@ bnad_cb_tcb_destroy(struct bnad *bnad, struct bna_tcb *tcb)
 {
 	struct bnad_tx_info *tx_info =
 			(struct bnad_tx_info *)tcb->txq->tx->priv;
-	struct bnad_unmap_q *unmap_q = tcb->unmap_q;
-
-	while (test_and_set_bit(BNAD_TXQ_FREE_SENT, &tcb->flags))
-		cpu_relax();
-
-	bnad_free_all_txbufs(bnad, tcb);
-
-	unmap_q->producer_index = 0;
-	unmap_q->consumer_index = 0;
-
-	smp_mb__before_clear_bit();
-	clear_bit(BNAD_TXQ_FREE_SENT, &tcb->flags);
 
 	tx_info->tcb[tcb->id] = NULL;
+	tcb->priv = NULL;
 }
 
 static void
@@ -866,12 +849,6 @@ bnad_cb_rcb_setup(struct bnad *bnad, struct bna_rcb *rcb)
 }
 
 static void
-bnad_cb_rcb_destroy(struct bnad *bnad, struct bna_rcb *rcb)
-{
-	bnad_free_all_rxbufs(bnad, rcb);
-}
-
-static void
 bnad_cb_ccb_setup(struct bnad *bnad, struct bna_ccb *ccb)
 {
 	struct bnad_rx_info *rx_info =
@@ -916,7 +893,6 @@ bnad_cb_tx_resume(struct bnad *bnad, struct bna_tx *tx)
 {
 	struct bnad_tx_info *tx_info = (struct bnad_tx_info *)tx->priv;
 	struct bna_tcb *tcb;
-	struct bnad_unmap_q *unmap_q;
 	u32 txq_id;
 	int i;
 
@@ -926,23 +902,9 @@ bnad_cb_tx_resume(struct bnad *bnad, struct bna_tx *tx)
 			continue;
 		txq_id = tcb->id;
 
-		unmap_q = tcb->unmap_q;
-
-		if (test_bit(BNAD_TXQ_TX_STARTED, &tcb->flags))
-			continue;
-
-		while (test_and_set_bit(BNAD_TXQ_FREE_SENT, &tcb->flags))
-			cpu_relax();
-
-		bnad_free_all_txbufs(bnad, tcb);
-
-		unmap_q->producer_index = 0;
-		unmap_q->consumer_index = 0;
-
-		smp_mb__before_clear_bit();
-		clear_bit(BNAD_TXQ_FREE_SENT, &tcb->flags);
-
+		BUG_ON(test_bit(BNAD_TXQ_TX_STARTED, &tcb->flags));
 		set_bit(BNAD_TXQ_TX_STARTED, &tcb->flags);
+		BUG_ON(*(tcb->hw_consumer_index) != 0);
 
 		if (netif_carrier_ok(bnad->netdev)) {
 			printk(KERN_INFO "bna: %s %d TXQ_STARTED\n",
@@ -963,6 +925,54 @@ bnad_cb_tx_resume(struct bnad *bnad, struct bna_tx *tx)
 	}
 }
 
+/*
+ * Free all TxQs buffers and then notify TX_E_CLEANUP_DONE to Tx fsm.
+ */
+static void
+bnad_tx_cleanup(struct delayed_work *work)
+{
+	struct bnad_tx_info *tx_info =
+		container_of(work, struct bnad_tx_info, tx_cleanup_work);
+	struct bnad *bnad = NULL;
+	struct bnad_unmap_q *unmap_q;
+	struct bna_tcb *tcb;
+	unsigned long flags;
+	uint32_t i, pending = 0;
+
+	for (i = 0; i < BNAD_MAX_TXQ_PER_TX; i++) {
+		tcb = tx_info->tcb[i];
+		if (!tcb)
+			continue;
+
+		bnad = tcb->bnad;
+
+		if (test_and_set_bit(BNAD_TXQ_FREE_SENT, &tcb->flags)) {
+			pending++;
+			continue;
+		}
+
+		bnad_free_all_txbufs(bnad, tcb);
+
+		unmap_q = tcb->unmap_q;
+		unmap_q->producer_index = 0;
+		unmap_q->consumer_index = 0;
+
+		smp_mb__before_clear_bit();
+		clear_bit(BNAD_TXQ_FREE_SENT, &tcb->flags);
+	}
+
+	if (pending) {
+		queue_delayed_work(bnad->work_q, &tx_info->tx_cleanup_work,
+			msecs_to_jiffies(1));
+		return;
+	}
+
+	spin_lock_irqsave(&bnad->bna_lock, flags);
+	bna_tx_cleanup_complete(tx_info->tx);
+	spin_unlock_irqrestore(&bnad->bna_lock, flags);
+}
+
+
 static void
 bnad_cb_tx_cleanup(struct bnad *bnad, struct bna_tx *tx)
 {
@@ -976,8 +986,7 @@ bnad_cb_tx_cleanup(struct bnad *bnad, struct bna_tx *tx)
 			continue;
 	}
 
-	mdelay(BNAD_TXRX_SYNC_MDELAY);
-	bna_tx_cleanup_complete(tx);
+	queue_delayed_work(bnad->work_q, &tx_info->tx_cleanup_work, 0);
 }
 
 static void
@@ -1001,6 +1010,44 @@ bnad_cb_rx_stall(struct bnad *bnad, struct bna_rx *rx)
 	}
 }
 
+/*
+ * Free all RxQs buffers and then notify RX_E_CLEANUP_DONE to Rx fsm.
+ */
+static void
+bnad_rx_cleanup(void *work)
+{
+	struct bnad_rx_info *rx_info =
+		container_of(work, struct bnad_rx_info, rx_cleanup_work);
+	struct bnad_rx_ctrl *rx_ctrl;
+	struct bnad *bnad = NULL;
+	unsigned long flags;
+	uint32_t i;
+
+	for (i = 0; i < BNAD_MAX_RXP_PER_RX; i++) {
+		rx_ctrl = &rx_info->rx_ctrl[i];
+
+		if (!rx_ctrl->ccb)
+			continue;
+
+		bnad = rx_ctrl->ccb->bnad;
+
+		/*
+		 * Wait till the poll handler has exited
+		 * and nothing can be scheduled anymore
+		 */
+		napi_disable(&rx_ctrl->napi);
+
+		bnad_cq_cmpl_init(bnad, rx_ctrl->ccb);
+		bnad_free_all_rxbufs(bnad, rx_ctrl->ccb->rcb[0]);
+		if (rx_ctrl->ccb->rcb[1])
+			bnad_free_all_rxbufs(bnad, rx_ctrl->ccb->rcb[1]);
+	}
+
+	spin_lock_irqsave(&bnad->bna_lock, flags);
+	bna_rx_cleanup_complete(rx_info->rx);
+	spin_unlock_irqrestore(&bnad->bna_lock, flags);
+}
+
 static void
 bnad_cb_rx_cleanup(struct bnad *bnad, struct bna_rx *rx)
 {
@@ -1009,8 +1056,6 @@ bnad_cb_rx_cleanup(struct bnad *bnad, struct bna_rx *rx)
 	struct bnad_rx_ctrl *rx_ctrl;
 	int i;
 
-	mdelay(BNAD_TXRX_SYNC_MDELAY);
-
 	for (i = 0; i < BNAD_MAX_RXP_PER_RX; i++) {
 		rx_ctrl = &rx_info->rx_ctrl[i];
 		ccb = rx_ctrl->ccb;
@@ -1021,12 +1066,9 @@ bnad_cb_rx_cleanup(struct bnad *bnad, struct bna_rx *rx)
 
 		if (ccb->rcb[1])
 			clear_bit(BNAD_RXQ_STARTED, &ccb->rcb[1]->flags);
-
-		while (test_bit(BNAD_FP_IN_RX_PATH, &rx_ctrl->flags))
-			cpu_relax();
 	}
 
-	bna_rx_cleanup_complete(rx);
+	queue_work(bnad->work_q, &rx_info->rx_cleanup_work);
 }
 
 static void
@@ -1046,13 +1088,12 @@ bnad_cb_rx_post(struct bnad *bnad, struct bna_rx *rx)
 		if (!ccb)
 			continue;
 
-		bnad_cq_cmpl_init(bnad, ccb);
+		napi_enable(&rx_ctrl->napi);
 
 		for (j = 0; j < BNAD_MAX_RXQ_PER_RXP; j++) {
 			rcb = ccb->rcb[j];
 			if (!rcb)
 				continue;
-			bnad_free_all_rxbufs(bnad, rcb);
 
 			set_bit(BNAD_RXQ_STARTED, &rcb->flags);
 			set_bit(BNAD_RXQ_POST_OK, &rcb->flags);
@@ -1704,7 +1745,7 @@ poll_exit:
 
 #define BNAD_NAPI_POLL_QUOTA		64
 static void
-bnad_napi_init(struct bnad *bnad, u32 rx_id)
+bnad_napi_add(struct bnad *bnad, u32 rx_id)
 {
 	struct bnad_rx_ctrl *rx_ctrl;
 	int i;
@@ -1718,29 +1759,13 @@ bnad_napi_init(struct bnad *bnad, u32 rx_id)
 }
 
 static void
-bnad_napi_enable(struct bnad *bnad, u32 rx_id)
-{
-	struct bnad_rx_ctrl *rx_ctrl;
-	int i;
-
-	/* Initialize & enable NAPI */
-	for (i = 0; i <	bnad->num_rxp_per_rx; i++) {
-		rx_ctrl = &bnad->rx_info[rx_id].rx_ctrl[i];
-
-		napi_enable(&rx_ctrl->napi);
-	}
-}
-
-static void
-bnad_napi_disable(struct bnad *bnad, u32 rx_id)
+bnad_napi_delete(struct bnad *bnad, u32 rx_id)
 {
 	int i;
 
 	/* First disable and then clean up */
-	for (i = 0; i < bnad->num_rxp_per_rx; i++) {
-		napi_disable(&bnad->rx_info[rx_id].rx_ctrl[i].napi);
+	for (i = 0; i < bnad->num_rxp_per_rx; i++)
 		netif_napi_del(&bnad->rx_info[rx_id].rx_ctrl[i].napi);
-	}
 }
 
 /* Should be held with conf_lock held */
@@ -1832,6 +1857,9 @@ bnad_setup_tx(struct bnad *bnad, u32 tx_id)
 		goto err_return;
 	tx_info->tx = tx;
 
+	INIT_DELAYED_WORK(&tx_info->tx_cleanup_work,
+			(work_func_t)bnad_tx_cleanup);
+
 	/* Register ISR for the Tx object */
 	if (intr_info->intr_type == BNA_INTR_T_MSIX) {
 		err = bnad_tx_msix_register(bnad, tx_info,
@@ -1928,7 +1956,7 @@ bnad_cleanup_rx(struct bnad *bnad, u32 rx_id)
 	if (rx_info->rx_ctrl[0].ccb->intr_type == BNA_INTR_T_MSIX)
 		bnad_rx_msix_unregister(bnad, rx_info, rx_config->num_paths);
 
-	bnad_napi_disable(bnad, rx_id);
+	bnad_napi_delete(bnad, rx_id);
 
 	spin_lock_irqsave(&bnad->bna_lock, flags);
 	bna_rx_destroy(rx_info->rx);
@@ -1952,7 +1980,7 @@ bnad_setup_rx(struct bnad *bnad, u32 rx_id)
 	struct bna_rx_config *rx_config = &bnad->rx_config[rx_id];
 	static const struct bna_rx_event_cbfn rx_cbfn = {
 		.rcb_setup_cbfn = bnad_cb_rcb_setup,
-		.rcb_destroy_cbfn = bnad_cb_rcb_destroy,
+		.rcb_destroy_cbfn = NULL,
 		.ccb_setup_cbfn = bnad_cb_ccb_setup,
 		.ccb_destroy_cbfn = bnad_cb_ccb_destroy,
 		.rx_stall_cbfn = bnad_cb_rx_stall,
@@ -1998,11 +2026,14 @@ bnad_setup_rx(struct bnad *bnad, u32 rx_id)
 	rx_info->rx = rx;
 	spin_unlock_irqrestore(&bnad->bna_lock, flags);
 
+	INIT_WORK(&rx_info->rx_cleanup_work,
+			(work_func_t)(bnad_rx_cleanup));
+
 	/*
 	 * Init NAPI, so that state is set to NAPI_STATE_SCHED,
 	 * so that IRQ handler cannot schedule NAPI at this point.
 	 */
-	bnad_napi_init(bnad, rx_id);
+	bnad_napi_add(bnad, rx_id);
 
 	/* Register ISR for the Rx object */
 	if (intr_info->intr_type == BNA_INTR_T_MSIX) {
@@ -2028,9 +2059,6 @@ bnad_setup_rx(struct bnad *bnad, u32 rx_id)
 	bna_rx_enable(rx);
 	spin_unlock_irqrestore(&bnad->bna_lock, flags);
 
-	/* Enable scheduling of NAPI */
-	bnad_napi_enable(bnad, rx_id);
-
 	return 0;
 
 err_return:
@@ -3129,6 +3157,7 @@ bnad_netdev_init(struct bnad *bnad, bool using_dac)
  * 2. Setup netdev pointer in pci_dev
  * 3. Initialze Tx free tasklet
  * 4. Initialize no. of TxQ & CQs & MSIX vectors
+ * 5. Initialize work queue.
  */
 static int
 bnad_init(struct bnad *bnad,
@@ -3174,6 +3203,12 @@ bnad_init(struct bnad *bnad,
 	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);
+
+	if (!bnad->work_q)
+		return -ENOMEM;
+
 	return 0;
 }
 
@@ -3185,6 +3220,12 @@ bnad_init(struct bnad *bnad,
 static void
 bnad_uninit(struct bnad *bnad)
 {
+	if (bnad->work_q) {
+		flush_workqueue(bnad->work_q);
+		destroy_workqueue(bnad->work_q);
+		bnad->work_q = NULL;
+	}
+
 	if (bnad->bar0)
 		iounmap(bnad->bar0);
 	pci_set_drvdata(bnad->pcidev, NULL);
diff --git a/drivers/net/ethernet/brocade/bna/bnad.h b/drivers/net/ethernet/brocade/bna/bnad.h
index 55824d9..ff129aa 100644
--- a/drivers/net/ethernet/brocade/bna/bnad.h
+++ b/drivers/net/ethernet/brocade/bna/bnad.h
@@ -210,6 +210,7 @@ struct bnad_tx_info {
 	struct bna_tx *tx; /* 1:1 between tx_info & tx */
 	struct bna_tcb *tcb[BNAD_MAX_TXQ_PER_TX];
 	u32 tx_id;
+	struct delayed_work tx_cleanup_work;
 } ____cacheline_aligned;
 
 struct bnad_rx_info {
@@ -217,6 +218,7 @@ struct bnad_rx_info {
 
 	struct bnad_rx_ctrl rx_ctrl[BNAD_MAX_RXP_PER_RX];
 	u32 rx_id;
+	struct work_struct rx_cleanup_work;
 } ____cacheline_aligned;
 
 /* Unmap queues for Tx / Rx cleanup */
@@ -319,6 +321,7 @@ struct bnad {
 	mac_t			perm_addr;
 
 	struct tasklet_struct	tx_free_tasklet;
+	struct workqueue_struct *work_q;
 
 	/* Statistics */
 	struct bnad_stats stats;
@@ -328,6 +331,7 @@ struct bnad {
 	char			adapter_name[BNAD_NAME_LEN];
 	char			port_name[BNAD_NAME_LEN];
 	char			mbox_irq_name[BNAD_NAME_LEN];
+	char			wq_name[BNAD_NAME_LEN];
 
 	/* debugfs specific data */
 	char	*regdata;
-- 
1.6.5.2

^ permalink raw reply related

* [PATCH 5/7] bna: Remove tx tasklet
From: Jing Huang @ 2012-04-04 15:43 UTC (permalink / raw)
  To: davem, netdev; +Cc: AdapterLinuxOpenSrcExtTeam, Jing Huang

The scheduling of tasklet and keeping the interrupts enabled makes interrupt
reduntant. 20% of the Tx interrupts have nothing left to process or could not
process as Tx tasklet was running.

Signed-off-by: Jing Huang <huangj@brocade.com>
---
 drivers/net/ethernet/brocade/bna/bnad.c |   73 +-----------------------------
 drivers/net/ethernet/brocade/bna/bnad.h |    1 -
 2 files changed, 3 insertions(+), 71 deletions(-)

diff --git a/drivers/net/ethernet/brocade/bna/bnad.c b/drivers/net/ethernet/brocade/bna/bnad.c
index 032a306..f1103e6 100644
--- a/drivers/net/ethernet/brocade/bna/bnad.c
+++ b/drivers/net/ethernet/brocade/bna/bnad.c
@@ -185,7 +185,6 @@ bnad_free_all_txbufs(struct bnad *bnad,
  * 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,
@@ -197,13 +196,7 @@ 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;
 
@@ -242,55 +235,6 @@ bnad_free_txbufs(struct bnad *bnad,
 	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)
 {
@@ -1789,9 +1733,6 @@ bnad_cleanup_tx(struct bnad *bnad, u32 tx_id)
 		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);
@@ -2871,9 +2812,6 @@ bnad_start_xmit(struct sk_buff *skb, struct net_device *netdev)
 	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;
 }
 
@@ -3155,9 +3093,8 @@ bnad_netdev_init(struct bnad *bnad, bool using_dac)
 /*
  * 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,
@@ -3200,9 +3137,6 @@ 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);
 
@@ -3345,7 +3279,6 @@ bnad_pci_probe(struct pci_dev *pdev,
 	/*
 	 * Initialize bnad structure
 	 * Setup relation between pci_dev & netdev
-	 * Init Tx free tasklet
 	 */
 	err = bnad_init(bnad, pdev, netdev);
 	if (err)
diff --git a/drivers/net/ethernet/brocade/bna/bnad.h b/drivers/net/ethernet/brocade/bna/bnad.h
index ff129aa..cf1d3ba 100644
--- a/drivers/net/ethernet/brocade/bna/bnad.h
+++ b/drivers/net/ethernet/brocade/bna/bnad.h
@@ -320,7 +320,6 @@ struct bnad {
 	/* Burnt in MAC address */
 	mac_t			perm_addr;
 
-	struct tasklet_struct	tx_free_tasklet;
 	struct workqueue_struct *work_q;
 
 	/* Statistics */
-- 
1.6.5.2

^ permalink raw reply related

* [PATCH 6/7] bna: Function name changes and cleanups
From: Jing Huang @ 2012-04-04 15:44 UTC (permalink / raw)
  To: davem, netdev; +Cc: AdapterLinuxOpenSrcExtTeam, Jing Huang

Renamed following functions:
bnad_cleanup_tx to bnad_destroy_tx
bnad_free_all_txbufs to bnad_txq_cleanup
bnad_free_txbufs to bnad_txcmpl_process
bnad_tx to bnad_tx_complete
bnad_cleanup_rx to bnad_destroy_rx
bnad_reset_rcb to bnad_rcb_cleanup
bnad_free_all_rxbufs to bnad_rxq_cleanup
bnad_cq_cmpl_init to bnad_cq_cleanup
bnad_alloc_n_post_rxbufs to bnad_rxq_post
bnad_poll_cq to bnad_cq_process

Signed-off-by: Jing Huang <huangj@brocade.com>
---
 drivers/net/ethernet/brocade/bna/bnad.c         |   54 +++++++++++-----------
 drivers/net/ethernet/brocade/bna/bnad.h         |    4 +-
 drivers/net/ethernet/brocade/bna/bnad_ethtool.c |    6 +-
 3 files changed, 32 insertions(+), 32 deletions(-)

diff --git a/drivers/net/ethernet/brocade/bna/bnad.c b/drivers/net/ethernet/brocade/bna/bnad.c
index f1103e6..25c4e7f 100644
--- a/drivers/net/ethernet/brocade/bna/bnad.c
+++ b/drivers/net/ethernet/brocade/bna/bnad.c
@@ -101,7 +101,7 @@ bnad_remove_from_list(struct bnad *bnad)
  * Reinitialize completions in CQ, once Rx is taken down
  */
 static void
-bnad_cq_cmpl_init(struct bnad *bnad, struct bna_ccb *ccb)
+bnad_cq_cleanup(struct bnad *bnad, struct bna_ccb *ccb)
 {
 	struct bna_cq_entry *cmpl, *next_cmpl;
 	unsigned int wi_range, wis = 0, ccb_prod = 0;
@@ -154,7 +154,7 @@ bnad_pci_unmap_skb(struct device *pdev, struct bnad_skb_unmap *array,
  * so DMA unmap & freeing is fine.
  */
 static void
-bnad_free_all_txbufs(struct bnad *bnad,
+bnad_txq_cleanup(struct bnad *bnad,
 		 struct bna_tcb *tcb)
 {
 	u32		unmap_cons;
@@ -182,12 +182,12 @@ bnad_free_all_txbufs(struct bnad *bnad,
 /* Data Path Handlers */
 
 /*
- * bnad_free_txbufs : Frees the Tx bufs on Tx completion
+ * bnad_txcmpl_process : Frees the Tx bufs on Tx completion
  * Can be called in a) Interrupt context
  *		    b) Sending context
  */
 static u32
-bnad_free_txbufs(struct bnad *bnad,
+bnad_txcmpl_process(struct bnad *bnad,
 		 struct bna_tcb *tcb)
 {
 	u32		unmap_cons, sent_packets = 0, sent_bytes = 0;
@@ -236,7 +236,7 @@ bnad_free_txbufs(struct bnad *bnad,
 }
 
 static u32
-bnad_tx(struct bnad *bnad, struct bna_tcb *tcb)
+bnad_tx_complete(struct bnad *bnad, struct bna_tcb *tcb)
 {
 	struct net_device *netdev = bnad->netdev;
 	u32 sent = 0;
@@ -244,7 +244,7 @@ bnad_tx(struct bnad *bnad, struct bna_tcb *tcb)
 	if (test_and_set_bit(BNAD_TXQ_FREE_SENT, &tcb->flags))
 		return 0;
 
-	sent = bnad_free_txbufs(bnad, tcb);
+	sent = bnad_txcmpl_process(bnad, tcb);
 	if (sent) {
 		if (netif_queue_stopped(netdev) &&
 		    netif_carrier_ok(netdev) &&
@@ -273,13 +273,13 @@ bnad_msix_tx(int irq, void *data)
 	struct bna_tcb *tcb = (struct bna_tcb *)data;
 	struct bnad *bnad = tcb->bnad;
 
-	bnad_tx(bnad, tcb);
+	bnad_tx_complete(bnad, tcb);
 
 	return IRQ_HANDLED;
 }
 
 static void
-bnad_reset_rcb(struct bnad *bnad, struct bna_rcb *rcb)
+bnad_rcb_cleanup(struct bnad *bnad, struct bna_rcb *rcb)
 {
 	struct bnad_unmap_q *unmap_q = rcb->unmap_q;
 
@@ -291,7 +291,7 @@ bnad_reset_rcb(struct bnad *bnad, struct bna_rcb *rcb)
 }
 
 static void
-bnad_free_all_rxbufs(struct bnad *bnad, struct bna_rcb *rcb)
+bnad_rxq_cleanup(struct bnad *bnad, struct bna_rcb *rcb)
 {
 	struct bnad_unmap_q *unmap_q;
 	struct bnad_skb_unmap *unmap_array;
@@ -312,11 +312,11 @@ bnad_free_all_rxbufs(struct bnad *bnad, struct bna_rcb *rcb)
 				 DMA_FROM_DEVICE);
 		dev_kfree_skb(skb);
 	}
-	bnad_reset_rcb(bnad, rcb);
+	bnad_rcb_cleanup(bnad, rcb);
 }
 
 static void
-bnad_alloc_n_post_rxbufs(struct bnad *bnad, struct bna_rcb *rcb)
+bnad_rxq_post(struct bnad *bnad, struct bna_rcb *rcb)
 {
 	u16 to_alloc, alloced, unmap_prod, wi_range;
 	struct bnad_unmap_q *unmap_q = rcb->unmap_q;
@@ -377,14 +377,14 @@ bnad_refill_rxq(struct bnad *bnad, struct bna_rcb *rcb)
 	if (!test_and_set_bit(BNAD_RXQ_REFILL, &rcb->flags)) {
 		if (BNA_QE_FREE_CNT(unmap_q, unmap_q->q_depth)
 			 >> BNAD_RXQ_REFILL_THRESHOLD_SHIFT)
-			bnad_alloc_n_post_rxbufs(bnad, rcb);
+			bnad_rxq_post(bnad, rcb);
 		smp_mb__before_clear_bit();
 		clear_bit(BNAD_RXQ_REFILL, &rcb->flags);
 	}
 }
 
 static u32
-bnad_poll_cq(struct bnad *bnad, struct bna_ccb *ccb, int budget)
+bnad_cq_process(struct bnad *bnad, struct bna_ccb *ccb, int budget)
 {
 	struct bna_cq_entry *cmpl, *next_cmpl;
 	struct bna_rcb *rcb = NULL;
@@ -584,7 +584,7 @@ bnad_isr(int irq, void *data)
 		for (j = 0; j < bnad->num_txq_per_tx; j++) {
 			tcb = bnad->tx_info[i].tcb[j];
 			if (tcb && test_bit(BNAD_TXQ_TX_STARTED, &tcb->flags))
-				bnad_tx(bnad, bnad->tx_info[i].tcb[j]);
+				bnad_tx_complete(bnad, bnad->tx_info[i].tcb[j]);
 		}
 	}
 	/* Rx processing */
@@ -895,7 +895,7 @@ bnad_tx_cleanup(struct delayed_work *work)
 			continue;
 		}
 
-		bnad_free_all_txbufs(bnad, tcb);
+		bnad_txq_cleanup(bnad, tcb);
 
 		unmap_q = tcb->unmap_q;
 		unmap_q->producer_index = 0;
@@ -981,10 +981,10 @@ bnad_rx_cleanup(void *work)
 		 */
 		napi_disable(&rx_ctrl->napi);
 
-		bnad_cq_cmpl_init(bnad, rx_ctrl->ccb);
-		bnad_free_all_rxbufs(bnad, rx_ctrl->ccb->rcb[0]);
+		bnad_cq_cleanup(bnad, rx_ctrl->ccb);
+		bnad_rxq_cleanup(bnad, rx_ctrl->ccb->rcb[0]);
 		if (rx_ctrl->ccb->rcb[1])
-			bnad_free_all_rxbufs(bnad, rx_ctrl->ccb->rcb[1]);
+			bnad_rxq_cleanup(bnad, rx_ctrl->ccb->rcb[1]);
 	}
 
 	spin_lock_irqsave(&bnad->bna_lock, flags);
@@ -1048,7 +1048,7 @@ bnad_cb_rx_post(struct bnad *bnad, struct bna_rx *rx)
 			if (!test_and_set_bit(BNAD_RXQ_REFILL, &rcb->flags)) {
 				if (BNA_QE_FREE_CNT(unmap_q, unmap_q->q_depth)
 					>> BNAD_RXQ_REFILL_THRESHOLD_SHIFT)
-					bnad_alloc_n_post_rxbufs(bnad, rcb);
+					bnad_rxq_post(bnad, rcb);
 					smp_mb__before_clear_bit();
 				clear_bit(BNAD_RXQ_REFILL, &rcb->flags);
 			}
@@ -1672,7 +1672,7 @@ bnad_napi_poll_rx(struct napi_struct *napi, int budget)
 	if (!netif_carrier_ok(bnad->netdev))
 		goto poll_exit;
 
-	rcvd = bnad_poll_cq(bnad, rx_ctrl->ccb, budget);
+	rcvd = bnad_cq_process(bnad, rx_ctrl->ccb, budget);
 	if (rcvd >= budget)
 		return rcvd;
 
@@ -1714,7 +1714,7 @@ bnad_napi_delete(struct bnad *bnad, u32 rx_id)
 
 /* Should be held with conf_lock held */
 void
-bnad_cleanup_tx(struct bnad *bnad, u32 tx_id)
+bnad_destroy_tx(struct bnad *bnad, u32 tx_id)
 {
 	struct bnad_tx_info *tx_info = &bnad->tx_info[tx_id];
 	struct bna_res_info *res_info = &bnad->tx_res_info[tx_id].res_info[0];
@@ -1865,7 +1865,7 @@ bnad_rx_ctrl_init(struct bnad *bnad, u32 rx_id)
 
 /* Called with mutex_lock(&bnad->conf_mutex) held */
 void
-bnad_cleanup_rx(struct bnad *bnad, u32 rx_id)
+bnad_destroy_rx(struct bnad *bnad, u32 rx_id)
 {
 	struct bnad_rx_info *rx_info = &bnad->rx_info[rx_id];
 	struct bna_rx_config *rx_config = &bnad->rx_config[rx_id];
@@ -2003,7 +2003,7 @@ bnad_setup_rx(struct bnad *bnad, u32 rx_id)
 	return 0;
 
 err_return:
-	bnad_cleanup_rx(bnad, rx_id);
+	bnad_destroy_rx(bnad, rx_id);
 	return err;
 }
 
@@ -2488,7 +2488,7 @@ bnad_open(struct net_device *netdev)
 	return 0;
 
 cleanup_tx:
-	bnad_cleanup_tx(bnad, 0);
+	bnad_destroy_tx(bnad, 0);
 
 err_return:
 	mutex_unlock(&bnad->conf_mutex);
@@ -2515,8 +2515,8 @@ bnad_stop(struct net_device *netdev)
 
 	wait_for_completion(&bnad->bnad_completions.enet_comp);
 
-	bnad_cleanup_tx(bnad, 0);
-	bnad_cleanup_rx(bnad, 0);
+	bnad_destroy_tx(bnad, 0);
+	bnad_destroy_rx(bnad, 0);
 
 	/* Synchronize mailbox IRQ */
 	bnad_mbox_irq_sync(bnad);
@@ -2589,7 +2589,7 @@ bnad_start_xmit(struct sk_buff *skb, struct net_device *netdev)
 		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);
+			acked = bnad_txcmpl_process(bnad, tcb);
 			if (likely(test_bit(BNAD_TXQ_TX_STARTED, &tcb->flags)))
 				bna_ib_ack(tcb->i_dbell, acked);
 			smp_mb__before_clear_bit();
diff --git a/drivers/net/ethernet/brocade/bna/bnad.h b/drivers/net/ethernet/brocade/bna/bnad.h
index cf1d3ba..d73967a 100644
--- a/drivers/net/ethernet/brocade/bna/bnad.h
+++ b/drivers/net/ethernet/brocade/bna/bnad.h
@@ -373,8 +373,8 @@ extern void bnad_rx_coalescing_timeo_set(struct bnad *bnad);
 
 extern int bnad_setup_rx(struct bnad *bnad, u32 rx_id);
 extern int bnad_setup_tx(struct bnad *bnad, u32 tx_id);
-extern void bnad_cleanup_tx(struct bnad *bnad, u32 tx_id);
-extern void bnad_cleanup_rx(struct bnad *bnad, u32 rx_id);
+extern void bnad_destroy_tx(struct bnad *bnad, u32 tx_id);
+extern void bnad_destroy_rx(struct bnad *bnad, u32 rx_id);
 
 /* Timer start/stop protos */
 extern void bnad_dim_timer_start(struct bnad *bnad);
diff --git a/drivers/net/ethernet/brocade/bna/bnad_ethtool.c b/drivers/net/ethernet/brocade/bna/bnad_ethtool.c
index ab753d7..40e1e84 100644
--- a/drivers/net/ethernet/brocade/bna/bnad_ethtool.c
+++ b/drivers/net/ethernet/brocade/bna/bnad_ethtool.c
@@ -464,7 +464,7 @@ bnad_set_ringparam(struct net_device *netdev,
 		for (i = 0; i < bnad->num_rx; i++) {
 			if (!bnad->rx_info[i].rx)
 				continue;
-			bnad_cleanup_rx(bnad, i);
+			bnad_destroy_rx(bnad, i);
 			current_err = bnad_setup_rx(bnad, i);
 			if (current_err && !err)
 				err = current_err;
@@ -492,7 +492,7 @@ bnad_set_ringparam(struct net_device *netdev,
 		for (i = 0; i < bnad->num_tx; i++) {
 			if (!bnad->tx_info[i].tx)
 				continue;
-			bnad_cleanup_tx(bnad, i);
+			bnad_destroy_tx(bnad, i);
 			current_err = bnad_setup_tx(bnad, i);
 			if (current_err && !err)
 				err = current_err;
@@ -539,7 +539,7 @@ bnad_set_pauseparam(struct net_device *netdev,
 }
 
 static void
-bnad_get_strings(struct net_device *netdev, u32 stringset, u8 * string)
+bnad_get_strings(struct net_device *netdev, u32 stringset, u8 *string)
 {
 	struct bnad *bnad = netdev_priv(netdev);
 	int i, j, q_num;
-- 
1.6.5.2

^ permalink raw reply related

* [PATCH 7/7] bna: Update driver version to 3.0.23.0
From: Jing Huang @ 2012-04-04 15:44 UTC (permalink / raw)
  To: davem, netdev; +Cc: AdapterLinuxOpenSrcExtTeam, Jing Huang

Driver version update

Signed-off-by: Jing Huang <huangj@brocade.com>
---
 drivers/net/ethernet/brocade/bna/bnad.h |    2 +-
 1 files changed, 1 insertions(+), 1 deletions(-)

diff --git a/drivers/net/ethernet/brocade/bna/bnad.h b/drivers/net/ethernet/brocade/bna/bnad.h
index d73967a..72742be 100644
--- a/drivers/net/ethernet/brocade/bna/bnad.h
+++ b/drivers/net/ethernet/brocade/bna/bnad.h
@@ -71,7 +71,7 @@ struct bnad_rx_ctrl {
 #define BNAD_NAME			"bna"
 #define BNAD_NAME_LEN			64
 
-#define BNAD_VERSION			"3.0.2.2"
+#define BNAD_VERSION			"3.0.23.0"
 
 #define BNAD_MAILBOX_MSIX_INDEX		0
 #define BNAD_MAILBOX_MSIX_VECTORS	1
-- 
1.6.5.2

^ permalink raw reply related

* Re: [PATCH net-next V6 7/8] net/dcb: Add an optional max rate attribute
From: John Fastabend @ 2012-04-04 15:48 UTC (permalink / raw)
  To: Amir Vadai
  Cc: David S. Miller, netdev, Roland Dreier, Yevgeny Petrilin,
	Oren Duer, Amir Vadai
In-Reply-To: <1333537084-9186-8-git-send-email-amirv@mellanox.com>

On 4/4/2012 3:58 AM, Amir Vadai wrote:
> Although not specified in 8021Qaz spec, it could be useful to enable drivers
> whose HW supports setting a rate limit for an ETS TC. This patch adds this
> optional attribute to DCB netlink. To use it, drivers should implement and
> register the callbacks ieee_setmaxrate and ieee_getmaxrate. The units are 64
> bits long and specified in Kbps to enable usage over both slow and very fast
> networks.
> 
> Signed-off-by: Amir Vadai <amirv@mellanox.com>
> ---
>  include/linux/dcbnl.h |    5 +++++
>  include/net/dcbnl.h   |    2 ++
>  net/dcb/dcbnl.c       |   21 +++++++++++++++++++++
>  3 files changed, 28 insertions(+), 0 deletions(-)
> 
> diff --git a/include/linux/dcbnl.h b/include/linux/dcbnl.h
> index 65a2562..ec8e372 100644
> --- a/include/linux/dcbnl.h
> +++ b/include/linux/dcbnl.h
> @@ -67,6 +67,10 @@ struct ieee_ets {
>  	__u8	reco_prio_tc[IEEE_8021QAZ_MAX_TCS];
>  };
>  
> +struct ieee_maxrate {
> +	__u64	tc_maxrate[IEEE_8021QAZ_MAX_TCS];
> +};
> +

And I think the last comment. We really should have a comment here describing
what the tc_maxrate field is. Its described in the commit log but its much
harder for implementers to get it wrong when the struct is annotated.

Thanks!
John

^ permalink raw reply

* Re: bridge: Do not send queries on multicast group leaves
From: Dave Taht @ 2012-04-04 15:54 UTC (permalink / raw)
  To: netdev
In-Reply-To: <CAA93jw658iHuuYWSz7QrV3ZHOvn1gL7DxAtFfQ0gos6jZjTKiw@mail.gmail.com>

Grumble,  resend in plain text.

On Wed, Apr 4, 2012 at 8:52 AM, Dave Taht <dave.taht@gmail.com> wrote:
>
>
>
> On Wed, Apr 4, 2012 at 4:01 AM, Herbert Xu <herbert@gondor.apana.org.au>
> wrote:
>>
>> Hi:
>>
>> bridge: Do not send queries on multicast group leaves
>>
>> As it stands the bridge IGMP snooping system will respond to
>> group leave messages with queries for remaining membership.
>> This is both unnecessary and undesirable.  First of all any
>> multicast routers present should be doing this rather than us.
>
>

Can I turn this question around on you? Theoretically Linux can be
a multicast router... as well as a bridge... as well as anything else.

So questions

1) Has anyone seen linux working as a multicast router of late?
because I sure haven't.

Pimd & mrd6 seem to not work across interfaces. I haven't tried xorp
yet...

And lacking a reference, working multicast router to start with tracking
down the causes (rp filtering? bustage? what), I'm a little stuck.

>
IGMP is the only thing that sort of seems to work and...
>
2) Does this bridge code change break existing applications of IGMP over a
lonely bridge?
>
>>
>> What's more the queries that we send may end up upsetting other
>> multicast snooping swithces in the system that are buggy.
>>
>
To me that's their problem.
>
>>
>> In fact, we can simply remove the code that send these queries
>> because the existing membership expiry mechanism doesn't rely
>> on them anyway.
>>
>> So this patch simply removes all code associated with group
>> queries in response to group leave messages.
>>
>> Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
>>
>>
>> diff --git a/net/bridge/br_multicast.c b/net/bridge/br_multicast.c
>> index 702a1ae..27ca25e 100644
>> --- a/net/bridge/br_multicast.c
>> +++ b/net/bridge/br_multicast.c
>> @@ -241,7 +241,6 @@ static void br_multicast_group_expired(unsigned long
>> data)
>>        hlist_del_rcu(&mp->hlist[mdb->ver]);
>>        mdb->size--;
>>
>> -       del_timer(&mp->query_timer);
>>        call_rcu_bh(&mp->rcu, br_multicast_free_group);
>>
>>  out:
>> @@ -271,7 +270,6 @@ static void br_multicast_del_pg(struct net_bridge
>> *br,
>>                rcu_assign_pointer(*pp, p->next);
>>                hlist_del_init(&p->mglist);
>>                del_timer(&p->timer);
>> -               del_timer(&p->query_timer);
>>                call_rcu_bh(&p->rcu, br_multicast_free_pg);
>>
>>                if (!mp->ports && !mp->mglist &&
>> @@ -507,74 +505,6 @@ static struct sk_buff
>> *br_multicast_alloc_query(struct net_bridge *br,
>>        return NULL;
>>  }
>>
>> -static void br_multicast_send_group_query(struct net_bridge_mdb_entry
>> *mp)
>> -{
>> -       struct net_bridge *br = mp->br;
>> -       struct sk_buff *skb;
>> -
>> -       skb = br_multicast_alloc_query(br, &mp->addr);
>> -       if (!skb)
>> -               goto timer;
>> -
>> -       netif_rx(skb);
>> -
>> -timer:
>> -       if (++mp->queries_sent < br->multicast_last_member_count)
>> -               mod_timer(&mp->query_timer,
>> -                         jiffies + br->multicast_last_member_interval);
>> -}
>> -
>> -static void br_multicast_group_query_expired(unsigned long data)
>> -{
>> -       struct net_bridge_mdb_entry *mp = (void *)data;
>> -       struct net_bridge *br = mp->br;
>> -
>> -       spin_lock(&br->multicast_lock);
>> -       if (!netif_running(br->dev) || !mp->mglist ||
>> -           mp->queries_sent >= br->multicast_last_member_count)
>> -               goto out;
>> -
>> -       br_multicast_send_group_query(mp);
>> -
>> -out:
>> -       spin_unlock(&br->multicast_lock);
>> -}
>> -
>> -static void br_multicast_send_port_group_query(struct
>> net_bridge_port_group *pg)
>> -{
>> -       struct net_bridge_port *port = pg->port;
>> -       struct net_bridge *br = port->br;
>> -       struct sk_buff *skb;
>> -
>> -       skb = br_multicast_alloc_query(br, &pg->addr);
>> -       if (!skb)
>> -               goto timer;
>> -
>> -       br_deliver(port, skb);
>> -
>> -timer:
>> -       if (++pg->queries_sent < br->multicast_last_member_count)
>> -               mod_timer(&pg->query_timer,
>> -                         jiffies + br->multicast_last_member_interval);
>> -}
>> -
>> -static void br_multicast_port_group_query_expired(unsigned long data)
>> -{
>> -       struct net_bridge_port_group *pg = (void *)data;
>> -       struct net_bridge_port *port = pg->port;
>> -       struct net_bridge *br = port->br;
>> -
>> -       spin_lock(&br->multicast_lock);
>> -       if (!netif_running(br->dev) || hlist_unhashed(&pg->mglist) ||
>> -           pg->queries_sent >= br->multicast_last_member_count)
>> -               goto out;
>> -
>> -       br_multicast_send_port_group_query(pg);
>> -
>> -out:
>> -       spin_unlock(&br->multicast_lock);
>> -}
>> -
>>  static struct net_bridge_mdb_entry *br_multicast_get_group(
>>        struct net_bridge *br, struct net_bridge_port *port,
>>        struct br_ip *group, int hash)
>> @@ -690,8 +620,6 @@ rehash:
>>        mp->addr = *group;
>>        setup_timer(&mp->timer, br_multicast_group_expired,
>>                    (unsigned long)mp);
>> -       setup_timer(&mp->query_timer, br_multicast_group_query_expired,
>> -                   (unsigned long)mp);
>>
>>        hlist_add_head_rcu(&mp->hlist[mdb->ver], &mdb->mhash[hash]);
>>        mdb->size++;
>> @@ -746,8 +674,6 @@ static int br_multicast_add_group(struct net_bridge
>> *br,
>>        hlist_add_head(&p->mglist, &port->mglist);
>>        setup_timer(&p->timer, br_multicast_port_group_expired,
>>                    (unsigned long)p);
>> -       setup_timer(&p->query_timer,
>> br_multicast_port_group_query_expired,
>> -                   (unsigned long)p);
>>
>>        rcu_assign_pointer(*pp, p);
>>
>> @@ -1291,9 +1217,6 @@ static void br_multicast_leave_group(struct
>> net_bridge *br,
>>                     time_after(mp->timer.expires, time) :
>>                     try_to_del_timer_sync(&mp->timer) >= 0)) {
>>                        mod_timer(&mp->timer, time);
>> -
>> -                       mp->queries_sent = 0;
>> -                       mod_timer(&mp->query_timer, now);
>>                }
>>
>>                goto out;
>> @@ -1310,9 +1233,6 @@ static void br_multicast_leave_group(struct
>> net_bridge *br,
>>                     time_after(p->timer.expires, time) :
>>                     try_to_del_timer_sync(&p->timer) >= 0)) {
>>                        mod_timer(&p->timer, time);
>> -
>> -                       p->queries_sent = 0;
>> -                       mod_timer(&p->query_timer, now);
>>                }
>>
>>                break;
>> @@ -1681,7 +1601,6 @@ void br_multicast_stop(struct net_bridge *br)
>>                hlist_for_each_entry_safe(mp, p, n, &mdb->mhash[i],
>>                                          hlist[ver]) {
>>                        del_timer(&mp->timer);
>> -                       del_timer(&mp->query_timer);
>>                        call_rcu_bh(&mp->rcu, br_multicast_free_group);
>>                }
>>        }
>> diff --git a/net/bridge/br_private.h b/net/bridge/br_private.h
>> index 0b67a63..e1d8822 100644
>> --- a/net/bridge/br_private.h
>> +++ b/net/bridge/br_private.h
>> @@ -82,9 +82,7 @@ struct net_bridge_port_group {
>>        struct hlist_node               mglist;
>>        struct rcu_head                 rcu;
>>        struct timer_list               timer;
>> -       struct timer_list               query_timer;
>>        struct br_ip                    addr;
>> -       u32                             queries_sent;
>>  };
>>
>>  struct net_bridge_mdb_entry
>> @@ -94,10 +92,8 @@ struct net_bridge_mdb_entry
>>        struct net_bridge_port_group __rcu *ports;
>>        struct rcu_head                 rcu;
>>        struct timer_list               timer;
>> -       struct timer_list               query_timer;
>>        struct br_ip                    addr;
>>        bool                            mglist;
>> -       u32                             queries_sent;
>>  };
>>
>>  struct net_bridge_mdb_htable
>> Thanks,
>> --
>> Email: Herbert Xu <herbert@gondor.apana.org.au>
>> Home Page: http://gondor.apana.org.au/~herbert/
>> PGP Key: http://gondor.apana.org.au/~herbert/pubkey.txt
>> --
>> To unsubscribe from this list: send the line "unsubscribe netdev" in
>> the body of a message to majordomo@vger.kernel.org
>> More majordomo info at  http://vger.kernel.org/majordomo-info.html
>
>
>
>
> --
> Dave Täht
> SKYPE: davetaht
> US Tel: 1-239-829-5608
> http://www.bufferbloat.net




--
Dave Täht
SKYPE: davetaht
US Tel: 1-239-829-5608
http://www.bufferbloat.net

^ permalink raw reply

* Re: [PATCH v2] marvell sky2 driver: fix so it works without unaligned accesses
From: Stephen Hemminger @ 2012-04-04 16:04 UTC (permalink / raw)
  To: Chris Metcalf; +Cc: David Miller, netdev, linux-kernel
In-Reply-To: <201204041419.q34EJ49H025297@farm-0012.internal.tilera.com>

On Wed, 4 Apr 2012 10:13:32 -0400
Chris Metcalf <cmetcalf@tilera.com> wrote:

> The driver uses a receive_new() routine that ends up requiring unaligned
> accesses in IP header processing.  If the architecture doesn't support
> efficient unaligned accesses, and SKY2_HW_RAM_BUFFER is set,
> just copy all ingress packets to the bounce buffers instead.
> Thanks to Eric Dumazet for pointing out the SKY2_HW_RAM_BUFFER issue.
> 
> This allows the driver to be used on the Tilera TILEmpower-Gx, since
> the tile architecture doesn't currently handle kernel unaligned accesses,
> just userspace.
> 
> Signed-off-by: Chris Metcalf <cmetcalf@tilera.com>

Still kind of ugly, I will cleanup

^ permalink raw reply

* Re: [PATCH] ARM: OMAP: AM33XX: CAN: d_can: Add support for Bosch D_CAN controller
From: Wolfgang Grandegger @ 2012-04-04 16:21 UTC (permalink / raw)
  To: AnilKumar, Chimata
  Cc: Marc Kleine-Budde, socketcan@hartkopp.net,
	m.kleine-budde@pengutronix.de, linux-can@vger.kernel.org,
	netdev@vger.kernel.org, linux-omap@vger.kernel.org,
	linux-kernel@vger.kernel.org, Gole, Anant, Nori, Sekhar
In-Reply-To: <331ABD5ECB02734CA317220B2BBEABC1317D88B7@DBDE01.ent.ti.com>

On 04/03/2012 05:58 PM, AnilKumar, Chimata wrote:
> On Tue, Apr 03, 2012 at 21:03:40, Marc Kleine-Budde wrote:
>> On 04/03/2012 04:29 PM, AnilKumar, Chimata wrote:
>>>>>> Please explain why this CAN controller cannot be handled by the existing
>>>>>> C_CAN driver, eventually with some extensions. The register layout seems
>>>>>> almost identical, at least.
>>>>>>
>>>>>> Wolfgang.
>>>>>>
>>>>>
>>>>> These are the some of the pointers I can say, why I had gone for separate
>>>>> file instead of existing driver:
>>>>> * In case of D_CAN driver we can see all the registers are 32bit length
>>>>>   but in case of C_CAN registers are in 16bit length.
>>>>
>>>> How many bits in these 32 bit registers are used?
>>>
>>> In some cases (D_CAN_TXRQ, D_CAN_INTPND, D_CAN_MSGVAL) I have used all the
>>> bits, in some cases used few bits.
>>>
>>> Roughly I can say that its (higher 16bits) % of usages is similar as compare
>>> to 16bits 
>>>
>>> While checking the status of TXRequest registers and INT pending register,
>>> which is a hot code path, we have to put if checks for register access.
>>
>> The c_can already has a c_can_read_reg32() function. It's for example
>> used in the rx_poll function. You can make it a function pointer (i.e.
>> pric->read_reg32()) for easy abstraction.
> 
> This won't fit for D_CAN case because offsets are different in c_can compared
> to d_can. For example if I read CONTROL_REG register (0x0) in case of d_can,
> which will read only control register. In case of c_can it will read
> CONTROL_REG + STATUS register values in single read
> 
>>
>>>>> * Some of the registers, bit masks are different, so we have to add
>>>>>   checks on every API for differentiating the kind of device
>>>>
>>>> Which registers are this? Can you give us an example?
>>>
>>> I am pointing out some of the resisters
>>> * Single registers in case of D_CAN but multiple register in case of C_CAN
>>>   So masks will change MASK, ARB, INTPND
>>> * D_CAN_IFCMD is the combination of COMM request and COMM mask registers
>>
>> Maybe you can use the read_reg32 function on both c_can and d_can.
> 
> Above comment applies here as well

I did look into the manual. Unfortunately, a direct mapping of the C_CAN
to the D_CAN registers seems not possible. It's not just a different
alignment but sometimes two 16-bit C_CAN registers are folded into *one*
32-bit D_CAN register. Therefore we need something more clever, e.g.
using a separate struct or union or handling those register separately.
I still think, if feasible, we should avoid an extra driver for the
D_CAN controller, also because we sooner than later need the same
infrastructure (register_c_can_dev etc.).

Wolfgang.

^ permalink raw reply

* Re: [PATCH net V1 1/2] net/bonding: emit address change event also in bond_release
From: Jay Vosburgh @ 2012-04-04 16:57 UTC (permalink / raw)
  To: Or Gerlitz; +Cc: davem, roland, netdev, Shlomo Pongratz
In-Reply-To: <1333529780-28421-2-git-send-email-ogerlitz@mellanox.com>

Or Gerlitz <ogerlitz@mellanox.com> wrote:

>From: Shlomo Pongratz <shlomop@mellanox.com>
>
>commit 7d26bb103c4 "bonding: emit event when bonding changes MAC" didn't
>take care to emit the NETDEV_CHANGEADDR event in bond_release, where bonding
>actually changes the mac address (to all zeroes). As a result the neighbours
>aren't deleted by the core networking code (which does so upon getting that
>event).
>
>Signed-off-by: Shlomo Pongratz <shlomop@mellanox.com>

Signed-off-by: Jay Vosburgh <fubar@us.ibm.com>

>---
> drivers/net/bonding/bond_main.c |    3 +++
> 1 files changed, 3 insertions(+), 0 deletions(-)
>
>diff --git a/drivers/net/bonding/bond_main.c b/drivers/net/bonding/bond_main.c
>index a20b585..d38f635 100644
>--- a/drivers/net/bonding/bond_main.c
>+++ b/drivers/net/bonding/bond_main.c
>@@ -2035,6 +2035,9 @@ int bond_release(struct net_device *bond_dev, struct net_device *slave_dev)
> 	write_unlock_bh(&bond->lock);
> 	unblock_netpoll_tx();
>
>+	if (bond->slave_cnt == 0)
>+		call_netdevice_notifiers(NETDEV_CHANGEADDR, bond->dev);
>+
> 	bond_compute_features(bond);
> 	if (!(bond_dev->features & NETIF_F_VLAN_CHALLENGED) &&
> 	    (old_features & NETIF_F_VLAN_CHALLENGED))
>-- 
>1.7.1
>

^ permalink raw reply

* Re: [RFC PATCH 2/2] PID-based packet filtering support
From: chetan loke @ 2012-04-04 17:01 UTC (permalink / raw)
  To: Nuno Martins; +Cc: netdev, Alfredo Matos, Paulo Trezentos
In-Reply-To: <19b9f7a0f38c1bab367da6f6cf622c8c2b3a4920.1333466900.git.nuno.martins@caixamagica.pt>

On Wed, Apr 4, 2012 at 5:16 AM, Nuno Martins
<nuno.martins@caixamagica.pt> wrote:

>  net/pidmonitor/Makefile           |    3 +

might make sense to prefix files with 'net' tag. Like: net_pidmonitor,
net_proc_monitor.c etc. Because proc_monitor is too generic.


> +static int is_equal_packet_info(struct packetInfo *pi,

It should be 'packet_info' and not 'packetInfo'. Init-char convention
is not used in linux. same goes for portInfo and other structs(if
any).


> +static int insert_address(struct packetInfo *lpi, struct portInfo *port_info)
> +{
> +
> +       switch (lpi->protocol) {
> +       case IPPROTO_TCP:
> +               if (!(port_info->tcp)) {
> +                       port_info->tcp = kmalloc(sizeof(struct local_addresses_list), GFP_KERNEL);

Do you think it might make sense to pre-alloc a list? or
managing/growing that list would add more pain/code than it's worth?
I'm just thinking in terms of search scalability when memory is
fragmented and we have lots of nodes in the tree.But I'm sure you
must've done some light tests.


> +static struct portInfo *create_packet_info(struct packetInfo *lpi)
> +{
> +       struct portInfo *pi = NULL;
> +       pi = kmalloc(sizeof(*pi), GFP_KERNEL);
> +
> +       if (!pi)
> +               return NULL;
> +
> +       pi->port = lpi->port;
> +       pi->tcp = NULL;
> +       pi->tcp_list_counter = 0;
> +       pi->udp = NULL;
> +       pi->udp_list_counter = 0;
> +
> +       insert_address(lpi, pi);
> +
> +       return pi;
> +}
> +

Just thinking out loud - what if packet_info and pid were introduced
as part of struct sock or something? The no need to kmalloc.
And at the end of the bind/accept/other-calls-you-intercept-via-probes
you can populate the structs. Then the kprobes could go away too. But
I know nothing about BPF so I can't really comment for sure.


Chetan

^ permalink raw reply

* Re: [PATCH net V1 2/2] net/bonding: correctly proxy slave neigh param setup ndo function
From: Jay Vosburgh @ 2012-04-04 17:00 UTC (permalink / raw)
  To: Or Gerlitz; +Cc: davem, roland, netdev, Shlomo Pongratz
In-Reply-To: <1333529780-28421-3-git-send-email-ogerlitz@mellanox.com>

Or Gerlitz <ogerlitz@mellanox.com> wrote:

>From: Shlomo Pongratz <shlomop@mellanox.com>
>
>The current implemenation was buggy for slaves who use ndo_neigh_setup,
>since the networking stack invokes the bonding device ndo entry (from
>neigh_params_alloc) before any devices are enslaved, and the bonding
>driver can't further delegate the call at that point in time. As a
>result when bonding IPoIB devices, the neigh_cleanup hasn't been called.
>
>Fix that by deferring the actual call into the slave ndo_neigh_setup
>from the time the bonding neigh_setup is called.
>
>Signed-off-by: Shlomo Pongratz <shlomop@mellanox.com>

Signed-off-by: Jay Vosburgh <fubar@us.ibm.com>

>---
> drivers/net/bonding/bond_main.c |   51 ++++++++++++++++++++++++++++++++------
> 1 files changed, 43 insertions(+), 8 deletions(-)
>
>diff --git a/drivers/net/bonding/bond_main.c b/drivers/net/bonding/bond_main.c
>index d38f635..c8dc1a5 100644
>--- a/drivers/net/bonding/bond_main.c
>+++ b/drivers/net/bonding/bond_main.c
>@@ -3705,17 +3705,52 @@ static void bond_set_multicast_list(struct net_device *bond_dev)
> 	read_unlock(&bond->lock);
> }
>
>-static int bond_neigh_setup(struct net_device *dev, struct neigh_parms *parms)
>+static int bond_neigh_init(struct neighbour *n)
> {
>-	struct bonding *bond = netdev_priv(dev);
>+	struct bonding *bond = netdev_priv(n->dev);
> 	struct slave *slave = bond->first_slave;
>+	const struct net_device_ops *slave_ops;
>+	struct neigh_parms parms;
>+	int ret;
>+
>+	if (!slave)
>+		return 0;
>+
>+	slave_ops = slave->dev->netdev_ops;
>+
>+	if (!slave_ops->ndo_neigh_setup)
>+		return 0;
>+
>+	parms.neigh_setup = NULL;
>+	parms.neigh_cleanup = NULL;
>+	ret = slave_ops->ndo_neigh_setup(slave->dev, &parms);
>+	if (ret)
>+		return ret;
>+
>+	/*
>+	 * Assign slave's neigh_cleanup to neighbour in case cleanup is called
>+	 * after the last slave has been detached.  Assumes that all slaves
>+	 * utilize the same neigh_cleanup (true at this writing as only user
>+	 * is ipoib).
>+	 */
>+	n->parms->neigh_cleanup = parms.neigh_cleanup;
>+
>+	if (!parms.neigh_setup)
>+		return 0;
>+
>+	return parms.neigh_setup(n);
>+}
>+
>+/*
>+ * The bonding ndo_neigh_setup is called at init time beofre any
>+ * slave exists. So we must declare proxy setup function which will
>+ * be used at run time to resolve the actual slave neigh param setup.
>+ */
>+static int bond_neigh_setup(struct net_device *dev,
>+			    struct neigh_parms *parms)
>+{
>+	parms->neigh_setup   = bond_neigh_init;
>
>-	if (slave) {
>-		const struct net_device_ops *slave_ops
>-			= slave->dev->netdev_ops;
>-		if (slave_ops->ndo_neigh_setup)
>-			return slave_ops->ndo_neigh_setup(slave->dev, parms);
>-	}
> 	return 0;
> }
>
>-- 
>1.7.1
>
>--
>To unsubscribe from this list: send the line "unsubscribe netdev" in
>the body of a message to majordomo@vger.kernel.org
>More majordomo info at  http://vger.kernel.org/majordomo-info.html
>

^ permalink raw reply

* Re: [PATCH net 2/2] net/bonding: correctly proxy slave neigh param setup ndo function
From: Jay Vosburgh @ 2012-04-04 16:56 UTC (permalink / raw)
  To: Or Gerlitz; +Cc: davem, roland, netdev, Shlomo Pongratz
In-Reply-To: <4F7C005D.60709@mellanox.com>

Or Gerlitz <ogerlitz@mellanox.com> wrote:

>On 4/4/2012 1:53 AM, Jay Vosburgh wrote:
>> Or Gerlitz<ogerlitz@mellanox.com>  wrote:
>>
>>> From: Shlomo Pongratz<shlomop@mellanox.com>
>>>
>>> The current implemenation was buggy for slaves who use ndo_neigh_setup,
>>> since the networking stack invokes the bonding device ndo entry (from
>>> neigh_params_alloc) before any devices are enslaved, and the bonding
>>> driver can't further delegate the call at that point in time. As a
>>> result when bonding IPoIB devices, the neigh_cleanup hasn't been called.
>>>
>>> Fix that by deferring the actual call into the slave ndo_neigh_setup
>> >from the time the bonding neigh_setup is called.
>>>
>>> Signed-off-by: Shlomo Pongratz<shlomop@mellanox.com>
>>> ---
>>> drivers/net/bonding/bond_main.c |   51 ++++++++++++++++++++++++++++++++------
>>> 1 files changed, 43 insertions(+), 8 deletions(-)
>>>
>>> diff --git a/drivers/net/bonding/bond_main.c b/drivers/net/bonding/bond_main.c
>>> index b0a278d..2eed155 100644
>>> --- a/drivers/net/bonding/bond_main.c
>>> +++ b/drivers/net/bonding/bond_main.c
>>> @@ -3707,17 +3707,52 @@ static void bond_set_multicast_list(struct net_device *bond_dev)
>>> 	read_unlock(&bond->lock);
>>> }
>>>
>>> -static int bond_neigh_setup(struct net_device *dev, struct neigh_parms *parms)
>>> +static int bond_neigh_init(struct neighbour *n)
>>> {
>>> -	struct bonding *bond = netdev_priv(dev);
>>> +	struct bonding *bond = netdev_priv(n->dev);
>>> 	struct slave *slave = bond->first_slave;
>>> +	const struct net_device_ops *slave_ops;
>>> +	struct neigh_parms parms;
>>> +	int ret;
>>> +
>>> +	if (!slave)
>>> +		return 0;
>>> +
>>> +	slave_ops = slave->dev->netdev_ops;
>>> +
>>> +	if (!slave_ops->ndo_neigh_setup)
>>> +		return 0;
>>> +
>>> +	parms.neigh_setup = NULL;
>>> +	parms.neigh_cleanup = NULL;
>>> +	ret = slave_ops->ndo_neigh_setup(slave->dev,&parms);
>>> +	if (ret)
>>> +		return ret;
>>> +
>>> +	/*
>>> +	 * must bind here to the slave clenaup. Since when last slave is removed
>>> +	 * there will be no slave device to dereference in a bonding
>>> +	 * neigh_cleanup function that we have could add.
>>> +	 */
>>> +	n->parms->neigh_cleanup = parms.neigh_cleanup;
>>
>> 	I'd write this comment as:
>>
>> 	/* Assign slave's neigh_cleanup to neighbour in case cleanup is
>> 	 * called after bond has been destroyed.  Assumes that all slaves
>> 	 * utilize the same neigh_cleanup (true at this writing as only user
>> 	 * is ipoib).
>> 	 */
>>
>> 	I.e., this logic works only because there cannot currently be a
>> situation wherein two slaves have different neigh_cleanup functions
>> (including one slave with a neigh_cleanup, and another without).
>
>Jay, we do need that proxy-ing for the specific case of deleting the last
>slave, since in bond_release
>the address change and the event emission happen --after-- calling
>bond_detach_slave. Still, will pick
>your phrasing for the comment and replace "after bond has been destroyed"
>with "after last slave has been detached"

	Yes, I understand that the proxying is needed; the point of the
comment is that if there's ever a situation in the future that two
slaves have different neigh_cleanup functions, this methodology will not
work.  There is no guarantee that the slave on which ndo_neigh_setup is
called on will also be the last slave to be removed.

	The change to the comment is ok; I was thinking about ipoib
always destroying the bond itself immediately after releasing the final
slave, so for ipoib, the two events always happen together.

	-J

>>
>> +	/* Does slave implement neigh_setup ? */
>> +	if (!parms.neigh_setup)
>> +		return 0;
>>
>> 	I don't think this comment is necessary.
>
>okay, will remove
>
>Or.
>

---
	-Jay Vosburgh, IBM Linux Technology Center, fubar@us.ibm.com

^ permalink raw reply

* Re: [PATCH 0/7] bna: Update driver version to 3.0.23.0
From: Stephen Hemminger @ 2012-04-04 17:15 UTC (permalink / raw)
  To: Jing Huang; +Cc: davem, netdev, adapter_linux_open_src_team
In-Reply-To: <1332790673-9562-1-git-send-email-huangj@brocade.com>

On Mon, 26 Mar 2012 12:37:53 -0700
Jing Huang <huangj@brocade.com> wrote:

> This patch set contains fixes in adapter initialization and tx/rx cleanup path.
> It also include code cleanups by removing and renaming some functions.
> 
> The driver version has been updated to 3.0.23.0 to reflect the changes.
> 
> Jing Huang (7):
>   bna: Serialize smem access during adapter initialization
>   bna: Flash controller ioc pll init fixes
>   bna: ioc cleanups
>   bfa: tx rx cleanup fix
>   bna: Remove tx tasklet
>   bfa: Function name changes and cleanups
>   bfa: Update driver version to 3.0.23.0
> 
>  drivers/net/ethernet/brocade/bna/bfa_ioc.c      |   61 +++--
>  drivers/net/ethernet/brocade/bna/bfa_ioc_ct.c   |  142 +++++++----
>  drivers/net/ethernet/brocade/bna/bfi_reg.h      |    6 +
>  drivers/net/ethernet/brocade/bna/bnad.c         |  316 +++++++++++------------
>  drivers/net/ethernet/brocade/bna/bnad.h         |   11 +-
>  drivers/net/ethernet/brocade/bna/bnad_ethtool.c |    6 +-
>  6 files changed, 300 insertions(+), 242 deletions(-)
> 

When are you going to integrate multi-queue support which is already
available in your out of tree driver?

^ permalink raw reply

* Re: [PATCH v2] marvell sky2 driver: fix so it works without unaligned accesses
From: Stephen Hemminger @ 2012-04-04 18:42 UTC (permalink / raw)
  To: Chris Metcalf; +Cc: David Miller, netdev, linux-kernel
In-Reply-To: <201204041419.q34EJ49H025297@farm-0012.internal.tilera.com>

On Wed, 4 Apr 2012 10:13:32 -0400
Chris Metcalf <cmetcalf@tilera.com> wrote:

> The driver uses a receive_new() routine that ends up requiring unaligned
> accesses in IP header processing.  If the architecture doesn't support
> efficient unaligned accesses, and SKY2_HW_RAM_BUFFER is set,
> just copy all ingress packets to the bounce buffers instead.
> Thanks to Eric Dumazet for pointing out the SKY2_HW_RAM_BUFFER issue.
> 
> This allows the driver to be used on the Tilera TILEmpower-Gx, since
> the tile architecture doesn't currently handle kernel unaligned accesses,
> just userspace.
> 
> Signed-off-by: Chris Metcalf <cmetcalf@tilera.com>
> ---
>  drivers/net/ethernet/marvell/sky2.c |    6 +++++-
>  1 files changed, 5 insertions(+), 1 deletions(-)

What about the following (compile tested only)
--- a/drivers/net/ethernet/marvell/sky2.c	2012-04-04 08:49:05.954853108 -0700
+++ b/drivers/net/ethernet/marvell/sky2.c	2012-04-04 11:30:54.201432707 -0700
@@ -2468,6 +2468,17 @@ static int sky2_change_mtu(struct net_de
 	return err;
 }
 
+static inline bool needs_copy(const struct rx_ring_info *re,
+			      unsigned length)
+{
+#ifndef CONFIG_HAVE_EFFICIENT_UNALIGNED_ACCESS
+	/* Some architectures need the IP header to be aligned */
+	if (!IS_ALIGNED(re->data_addr + ETH_HLEN, sizeof(u32)))
+		return 1;
+#endif
+	return length < copybreak;
+}
+
 /* For small just reuse existing skb for next receive */
 static struct sk_buff *receive_copy(struct sky2_port *sky2,
 				    const struct rx_ring_info *re,
@@ -2605,7 +2616,7 @@ static struct sk_buff *sky2_receive(stru
 		goto error;
 
 okay:
-	if (length < copybreak)
+	if (needs_copy(re, length))
 		skb = receive_copy(sky2, re, length);
 	else
 		skb = receive_new(sky2, re, length);

^ permalink raw reply

* Re: [RFC PATCH 2/2] PID-based packet filtering support
From: chetan loke @ 2012-04-04 18:57 UTC (permalink / raw)
  To: Nuno Martins; +Cc: netdev, Alfredo Matos, Paulo Trezentos
In-Reply-To: <19b9f7a0f38c1bab367da6f6cf622c8c2b3a4920.1333466900.git.nuno.martins@caixamagica.pt>

On Wed, Apr 4, 2012 at 5:16 AM, Nuno Martins
<nuno.martins@caixamagica.pt> wrote:


> +int get_local_packet_info_from_fd(unsigned int fd, struct packetInfo *ret)

rename 'ret' to 'pi' or pkt_info or pick a name (must match the
struct). And not just here but everywhere else.

> +{
> +       struct file *f = fget(fd);
> +
> +       if (f != NULL) {
> +               fput(f);

why not 'fput' after you return from 'get_local_packet_info_from_file' ?

> +               return get_local_packet_info_from_file(f, ret);
> +       }
> +       return -3;
> +}
> +


> +int get_local_packet_info_from_file(struct file *f, struct packetInfo *ret)
> +{
> +       struct socket *socket = NULL;
> +       short type;
> +       unsigned short family;
> +       int err = 0;
> +
> +       if (f != NULL) {

This check is redundant because the
caller(get_local_packet_info_from_fd) checks for NULL.

Move this function before get_local_packet_info_from_fd().

re-arranged code looks like:

int get_local_packet_info_from_file(...) {
....
}

int get_local_packet_info_from_fd(...) {
   ...
   ... get_local_packet_info_from_file(f, ret);
   ....
}


Chetan

^ permalink raw reply

* Re: [PATCH] netfilter: don't scale the size of the window up twice
From: Jozsef Kadlecsik @ 2012-04-04 19:05 UTC (permalink / raw)
  To: Pablo Neira Ayuso
  Cc: Patrick McHardy, David S. Miller, netfilter-devel, netdev,
	Changli Gao
In-Reply-To: <20120404150854.GA4148@1984>

On Wed, 4 Apr 2012, Pablo Neira Ayuso wrote:

> On Mon, Apr 02, 2012 at 11:25:06AM +0800, Changli Gao wrote:
> > For a picked up connection, the window win is scaled twice: one is by the
> > initialization code, and the other is by the sender updating code.
> > 
> > I use the temporary variable swin instead of modifying the variable win.
> > 
> > Signed-off-by: Changli Gao <xiaosuo@gmail.com>
> > ---
> >  net/netfilter/nf_conntrack_proto_tcp.c |    4 ++--
> >  1 file changed, 2 insertions(+), 2 deletions(-)
> > diff --git a/net/netfilter/nf_conntrack_proto_tcp.c b/net/netfilter/nf_conntrack_proto_tcp.c
> > index 361eade..0d07a1d 100644
> > --- a/net/netfilter/nf_conntrack_proto_tcp.c
> > +++ b/net/netfilter/nf_conntrack_proto_tcp.c
> > @@ -584,8 +584,8 @@ static bool tcp_in_window(const struct nf_conn *ct,
> >  			 * Let's try to use the data from the packet.
> >  			 */
> >  			sender->td_end = end;
> > -			win <<= sender->td_scale;
> > -			sender->td_maxwin = (win == 0 ? 1 : win);
> > +			swin = win << sender->td_scale;
> > +			sender->td_maxwin = (swin == 0 ? 1 : swin);
> >  			sender->td_maxend = end + sender->td_maxwin;
> >  			/*
> >  			 * We haven't seen traffic in the other direction yet
> 
> Jozsef, do you remember if this is intentional?

No, it's a good spotting.

Acked-by: Jozsef Kadlecsik <kadlec@blackhole.kfki.hu>

> I'm going to test this patch in my testbed to make sure this does not
> break conntrackd.

A checking in a testbed doesn't hurt :-).

Best regards,
Jozsef
-
E-mail  : kadlec@blackhole.kfki.hu, kadlecsik.jozsef@wigner.mta.hu
PGP key : http://www.kfki.hu/~kadlec/pgp_public_key.txt
Address : Wigner Research Centre for Physics, Hungarian Academy of Sciences
          H-1525 Budapest 114, POB. 49, Hungary

^ permalink raw reply

* Re: [PATCH net-next 23/34] uli526x: fix regions leak in driver probe error path.
From: Grant Grundler @ 2012-04-04 19:10 UTC (permalink / raw)
  To: Francois Romieu; +Cc: netdev, David Miller, Grant Grundler
In-Reply-To: <cc6d6ac73b8297d3eda5ef20a83a1eb0587b52e9.1331814082.git.romieu@fr.zoreil.com>

On Thu, Mar 15, 2012 at 6:57 AM, Francois Romieu <romieu@fr.zoreil.com> wrote:
> Signed-off-by: Francois Romieu <romieu@fr.zoreil.com>
> Cc: Grant Grundler <grundler@parisc-linux.org>

Acked-by: Grant Grundler <grundler@parisc-linux.org>

cheers,
grant

> ---
>  drivers/net/ethernet/dec/tulip/uli526x.c |   48 ++++++++++++-----------------
>  1 files changed, 20 insertions(+), 28 deletions(-)
>
> diff --git a/drivers/net/ethernet/dec/tulip/uli526x.c b/drivers/net/ethernet/dec/tulip/uli526x.c
> index fc4001f..c9b3396 100644
> --- a/drivers/net/ethernet/dec/tulip/uli526x.c
> +++ b/drivers/net/ethernet/dec/tulip/uli526x.c
> @@ -313,9 +313,9 @@ static int __devinit uli526x_init_one (struct pci_dev *pdev,
>                goto err_out_disable;
>        }
>
> -       if (pci_request_regions(pdev, DRV_NAME)) {
> +       err = pci_request_regions(pdev, DRV_NAME);
> +       if (err < 0) {
>                pr_err("Failed to request PCI regions\n");
> -               err = -ENODEV;
>                goto err_out_disable;
>        }
>
> @@ -323,18 +323,15 @@ static int __devinit uli526x_init_one (struct pci_dev *pdev,
>        db = netdev_priv(dev);
>
>        /* Allocate Tx/Rx descriptor memory */
> +       err = -ENOMEM;
> +
>        db->desc_pool_ptr = pci_alloc_consistent(pdev, sizeof(struct tx_desc) * DESC_ALL_CNT + 0x20, &db->desc_pool_dma_ptr);
> -       if(db->desc_pool_ptr == NULL)
> -       {
> -               err = -ENOMEM;
> -               goto err_out_nomem;
> -       }
> +       if (!db->desc_pool_ptr)
> +               goto err_out_release;
> +
>        db->buf_pool_ptr = pci_alloc_consistent(pdev, TX_BUF_ALLOC * TX_DESC_CNT + 4, &db->buf_pool_dma_ptr);
> -       if(db->buf_pool_ptr == NULL)
> -       {
> -               err = -ENOMEM;
> -               goto err_out_nomem;
> -       }
> +       if (!db->buf_pool_ptr)
> +               goto err_out_free_tx_desc;
>
>        db->first_tx_desc = (struct tx_desc *) db->desc_pool_ptr;
>        db->first_tx_desc_dma = db->desc_pool_dma_ptr;
> @@ -387,7 +384,7 @@ static int __devinit uli526x_init_one (struct pci_dev *pdev,
>        }
>        err = register_netdev (dev);
>        if (err)
> -               goto err_out_res;
> +               goto err_out_free_tx_buf;
>
>        netdev_info(dev, "ULi M%04lx at pci%s, %pM, irq %d\n",
>                    ent->driver_data >> 16, pci_name(pdev),
> @@ -397,16 +394,14 @@ static int __devinit uli526x_init_one (struct pci_dev *pdev,
>
>        return 0;
>
> -err_out_res:
> +err_out_free_tx_buf:
> +       pci_free_consistent(pdev, TX_BUF_ALLOC * TX_DESC_CNT + 4,
> +                           db->buf_pool_ptr, db->buf_pool_dma_ptr);
> +err_out_free_tx_desc:
> +       pci_free_consistent(pdev, sizeof(struct tx_desc) * DESC_ALL_CNT + 0x20,
> +                           db->desc_pool_ptr, db->desc_pool_dma_ptr);
> +err_out_release:
>        pci_release_regions(pdev);
> -err_out_nomem:
> -       if(db->desc_pool_ptr)
> -               pci_free_consistent(pdev, sizeof(struct tx_desc) * DESC_ALL_CNT + 0x20,
> -                       db->desc_pool_ptr, db->desc_pool_dma_ptr);
> -
> -       if(db->buf_pool_ptr != NULL)
> -               pci_free_consistent(pdev, TX_BUF_ALLOC * TX_DESC_CNT + 4,
> -                       db->buf_pool_ptr, db->buf_pool_dma_ptr);
>  err_out_disable:
>        pci_disable_device(pdev);
>  err_out_free:
> @@ -422,19 +417,16 @@ static void __devexit uli526x_remove_one (struct pci_dev *pdev)
>        struct net_device *dev = pci_get_drvdata(pdev);
>        struct uli526x_board_info *db = netdev_priv(dev);
>
> -       ULI526X_DBUG(0, "uli526x_remove_one()", 0);
> -
> +       unregister_netdev(dev);
>        pci_free_consistent(db->pdev, sizeof(struct tx_desc) *
>                                DESC_ALL_CNT + 0x20, db->desc_pool_ptr,
>                                db->desc_pool_dma_ptr);
>        pci_free_consistent(db->pdev, TX_BUF_ALLOC * TX_DESC_CNT + 4,
>                                db->buf_pool_ptr, db->buf_pool_dma_ptr);
> -       unregister_netdev(dev);
>        pci_release_regions(pdev);
> -       free_netdev(dev);       /* free board information */
> -       pci_set_drvdata(pdev, NULL);
>        pci_disable_device(pdev);
> -       ULI526X_DBUG(0, "uli526x_remove_one() exit", 0);
> +       pci_set_drvdata(pdev, NULL);
> +       free_netdev(dev);
>  }
>
>
> --
> 1.7.7.6
>

^ permalink raw reply


This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox