Netdev List
 help / color / mirror / Atom feed
* Re: Possible networking regression in 3.6.0
From: Eric Dumazet @ 2012-10-01 16:37 UTC (permalink / raw)
  To: Chris Clayton; +Cc: David Miller, netdev, gpiez
In-Reply-To: <5069C27A.3090706@googlemail.com>

On Mon, 2012-10-01 at 17:19 +0100, Chris Clayton wrote:
> 
> On 10/01/12 16:31, Eric Dumazet wrote:
> > On Mon, 2012-10-01 at 16:13 +0100, Chris Clayton wrote:
> >>
> >> On 10/01/12 10:15, Eric Dumazet wrote:
> >>> On Mon, 2012-10-01 at 09:36 +0100, Chris Clayton wrote:
> >>>>
> >>>
> >>>>        0 ICMP messages received
> >>>>        0 input ICMP message failed.
> >>>>        ICMP input histogram:
> >>>>        0 ICMP messages sent
> >>>>        0 ICMP messages failed
> >>>>        ICMP output histogram:
> >>>
> >>>>
> >>>> After:
> >>>>
> >>>> $ netstat -s
> >>>> Icmp:
> >>>>        4 ICMP messages received
> >>>>        4 input ICMP message failed.
> >>>>        ICMP input histogram:
> >>>>            echo replies: 4
> >>>
> >>> So icmp replies come back and are delivered to host instead of being
> >>> forwarded.
> >>>
> >>> I wonder if MASQUERADE broke...
> >>>
> >>> Could you send
> >>>
> >>> iptables -t -nat -nvL
> >>
> >> $ iptables -t -nat -nvL
> >> iptables v1.4.15: can't initialize iptables table `-nat': Table does not
> >> exist (do you need to insmod?)
> >> Perhaps iptables or your kernel needs to be upgraded.
> >>
> >>> conntrack -L   # while ping is running from guest
> >>
> >> $ conntrack -L
> >> conntrack v1.2.2 (conntrack-tools): Operation failed: invalid parameters
> >>
> >
> > Thats not expected, you described you used MASQUERADE target, so
> > "iptables -t nat -nvL" should display something.
> >
> 
> To check this I've booted a 3.5.4 kernel. I get the same response to the 
> two commands. I also double checked that, with a 3.5.4 kernel, pinging 
> the router and browsing the internet from the client work and they do.
> 
> Except for the packets and bytes columns, the command iptables -nvL 
> gives the following output under both 3.5.4 and 3.6.0 kernels:
> 
> Chain INPUT (policy ACCEPT 0 packets, 0 bytes)
>   pkts bytes target     prot opt in     out     source destination
>   3757 3240K ACCEPT     all  --  *      *       0.0.0.0/0 0.0.0.0/0 
>         state RELATED,ESTABLISHED
>     14   840 ACCEPT     all  --  *      *       127.0.0.1 127.0.0.1
>     41  4362 ACCEPT     all  --  *      *       192.168.0.0/24 0.0.0.0/0
>     90 12780 ACCEPT     all  --  *      *       192.168.200.0/24 0.0.0.0/0
>      0     0 ACCEPT     all  --  *      *       192.168.201.0/24 0.0.0.0/0
>      0     0 DROP       all  --  *      *       0.0.0.0/0 0.0.0.0/0
> 
> Chain FORWARD (policy ACCEPT 4470 packets, 3065K bytes)
>   pkts bytes target     prot opt in     out     source destination
> 
> Chain OUTPUT (policy ACCEPT 3243 packets, 349K bytes)
>   pkts bytes target     prot opt in     out     source destination
>     64  8344 ACCEPT     all  --  *      *       0.0.0.0/0 192.168.200.0/24
>      0     0 ACCEPT     all  --  *      *       0.0.0.0/0 192.168.201.0/24

I am lost, since n your first mail you said :
-----------------------------------------------------------------------------
# Load the connection-sharing for qemu/kvm guests
echo 1 > /proc/sys/net/ipv4/ip_forward
iptables -t nat -A POSTROUTING -o eth0 -j MASQUERADE
...
# allow traffic to and from the qemu/kvm virtual networks
NETS="200 201"
for net in $NETS; do
   iptables -A INPUT -s 192.168.$net.0/24 -j ACCEPT
   iptables -A OUTPUT -d 192.168.$net.0/24 -j ACCEPT
done
...

The network-related modules that are loaded are:

$ lsmod
Module                  Size  Used by
tun                    12412  0
xt_state                 891  1
iptable_filter           852  1
ipt_MASQUERADE          1222  1
iptable_nat             3087  1
nf_nat                 10901  2 ipt_MASQUERADE,iptable_nat
nf_conntrack_ipv4       4942  4 nf_nat,iptable_nat
nf_defrag_ipv4           815  1 nf_conntrack_ipv4
nf_conntrack           37644  5 
ipt_MASQUERADE,nf_nat,xt_state,iptable_nat,nf_conntrack_ipv4
...
r8169                  47159  0


-----------------------------------------------

Now you say you dont have nat ?

Something is wrong.

^ permalink raw reply

* Re: Possible networking regression in 3.6.0
From: Chris Clayton @ 2012-10-01 16:19 UTC (permalink / raw)
  To: Eric Dumazet; +Cc: David Miller, netdev, gpiez
In-Reply-To: <1349105498.12401.706.camel@edumazet-glaptop>



On 10/01/12 16:31, Eric Dumazet wrote:
> On Mon, 2012-10-01 at 16:13 +0100, Chris Clayton wrote:
>>
>> On 10/01/12 10:15, Eric Dumazet wrote:
>>> On Mon, 2012-10-01 at 09:36 +0100, Chris Clayton wrote:
>>>>
>>>
>>>>        0 ICMP messages received
>>>>        0 input ICMP message failed.
>>>>        ICMP input histogram:
>>>>        0 ICMP messages sent
>>>>        0 ICMP messages failed
>>>>        ICMP output histogram:
>>>
>>>>
>>>> After:
>>>>
>>>> $ netstat -s
>>>> Icmp:
>>>>        4 ICMP messages received
>>>>        4 input ICMP message failed.
>>>>        ICMP input histogram:
>>>>            echo replies: 4
>>>
>>> So icmp replies come back and are delivered to host instead of being
>>> forwarded.
>>>
>>> I wonder if MASQUERADE broke...
>>>
>>> Could you send
>>>
>>> iptables -t -nat -nvL
>>
>> $ iptables -t -nat -nvL
>> iptables v1.4.15: can't initialize iptables table `-nat': Table does not
>> exist (do you need to insmod?)
>> Perhaps iptables or your kernel needs to be upgraded.
>>
>>> conntrack -L   # while ping is running from guest
>>
>> $ conntrack -L
>> conntrack v1.2.2 (conntrack-tools): Operation failed: invalid parameters
>>
>
> Thats not expected, you described you used MASQUERADE target, so
> "iptables -t nat -nvL" should display something.
>

To check this I've booted a 3.5.4 kernel. I get the same response to the 
two commands. I also double checked that, with a 3.5.4 kernel, pinging 
the router and browsing the internet from the client work and they do.

Except for the packets and bytes columns, the command iptables -nvL 
gives the following output under both 3.5.4 and 3.6.0 kernels:

Chain INPUT (policy ACCEPT 0 packets, 0 bytes)
  pkts bytes target     prot opt in     out     source destination
  3757 3240K ACCEPT     all  --  *      *       0.0.0.0/0 0.0.0.0/0 
        state RELATED,ESTABLISHED
    14   840 ACCEPT     all  --  *      *       127.0.0.1 127.0.0.1
    41  4362 ACCEPT     all  --  *      *       192.168.0.0/24 0.0.0.0/0
    90 12780 ACCEPT     all  --  *      *       192.168.200.0/24 0.0.0.0/0
     0     0 ACCEPT     all  --  *      *       192.168.201.0/24 0.0.0.0/0
     0     0 DROP       all  --  *      *       0.0.0.0/0 0.0.0.0/0

Chain FORWARD (policy ACCEPT 4470 packets, 3065K bytes)
  pkts bytes target     prot opt in     out     source destination

Chain OUTPUT (policy ACCEPT 3243 packets, 349K bytes)
  pkts bytes target     prot opt in     out     source destination
    64  8344 ACCEPT     all  --  *      *       0.0.0.0/0 192.168.200.0/24
     0     0 ACCEPT     all  --  *      *       0.0.0.0/0 192.168.201.0/24

>
>> Forgive me for asking, but why is the problem not down to the change
>> that I identified by bisecting? The title of the patch is "ipv4: Cache
>> local output routes" and, although I'm a million miles from being an
>> expert here, to me it does make it look a good candidate.
>> http://marc.info/?l=linux-netdev&m=134797809611847&w=2
>
> Because I cant reproduce your problem at all, using your setup.
>
OK, thanks.
>
>
>
>

^ permalink raw reply

* Re: [PATCH 2/2] tg3: fix build-time dependency with IS_DEPENDENCY_SATISFIED()
From: Paul Gortmaker @ 2012-10-01 16:10 UTC (permalink / raw)
  To: Anisse Astier
  Cc: linux-kernel, netdev, Michal Marek, Linus Torvalds, Michael Chan,
	Matt Carlson
In-Reply-To: <1349094080-769-2-git-send-email-anisse@astier.eu>

[[PATCH 2/2] tg3: fix build-time dependency with IS_DEPENDENCY_SATISFIED()] On 01/10/2012 (Mon 14:21) Anisse Astier wrote:

> When CONFIG_TIGON3=y and CONFIG_HWMON=y, we will get this error:
>   LD      init/built-in.o
> drivers/built-in.o: In function `tg3_hwmon_open':
> tg3.c:(.text+0xc1d12): undefined reference to `hwmon_device_register'
> drivers/built-in.o: In function `tg3_close':
> tg3.c:(.text+0xc2e7f): undefined reference to `hwmon_device_unregister'
> make: *** [vmlinux] Error 1
> 
> Use the new IS_DEPENDENCY_SATISFIED() facility to solve this problem.

Even though my fingerprints may be on IS_ENABLED, I'm not a fan of using
it (or things like this extension) all over the place for #ifdef blocks
that can be avoided some other clean way.

How about we just fix this the way Dave suggested a few months ago?

P.

--

>From e7c432cf5eb44b188c1aa2b188877c42300de8b9 Mon Sep 17 00:00:00 2001
From: Paul Gortmaker <paul.gortmaker@windriver.com>
Date: Mon, 1 Oct 2012 11:43:49 -0400
Subject: [PATCH] tg3: unconditionally select HWMON support when tg3 is
 enabled.

There is the seldom used corner case where HWMON=m at the same
time as TIGON3=y (typically randconfigs) which will cause a link
fail like:

drivers/built-in.o: In function `tg3_close':
tg3.c:(.text+0x16bd86): undefined reference to `hwmon_device_unregister'
drivers/built-in.o: In function `tg3_hwmon_open':
tg3.c:(.text+0x16fc4b): undefined reference to `hwmon_device_register'
make[1]: *** [vmlinux] Error 1

Fix it as suggested by DaveM[1] by having the Kconfig logic simply
select HWMON when TIGON3 is selected.  This gets rid of all the
extra IS_ENABLED ifdeffery in tg3.c as a side benefit.

[1] http://marc.info/?l=linux-netdev&m=134250573718151&w=2

Cc: Michael Chan <mchan@broadcom.com>
Reported-by: Benjamin Herrenschmidt <benh@kernel.crashing.org>
Reported-by: Anisse Astier <anisse@astier.eu>
Suggested-by: David S. Miller <davem@davemloft.net>
Signed-off-by: Paul Gortmaker <paul.gortmaker@windriver.com>
---
 drivers/net/ethernet/broadcom/Kconfig | 1 +
 drivers/net/ethernet/broadcom/tg3.c   | 9 ---------
 2 files changed, 1 insertion(+), 9 deletions(-)

diff --git a/drivers/net/ethernet/broadcom/Kconfig b/drivers/net/ethernet/broadcom/Kconfig
index f15e72e..4bd416b 100644
--- a/drivers/net/ethernet/broadcom/Kconfig
+++ b/drivers/net/ethernet/broadcom/Kconfig
@@ -101,6 +101,7 @@ config TIGON3
 	tristate "Broadcom Tigon3 support"
 	depends on PCI
 	select PHYLIB
+	select HWMON
 	---help---
 	  This driver supports Broadcom Tigon3 based gigabit Ethernet cards.
 
diff --git a/drivers/net/ethernet/broadcom/tg3.c b/drivers/net/ethernet/broadcom/tg3.c
index bf906c5..711eb14 100644
--- a/drivers/net/ethernet/broadcom/tg3.c
+++ b/drivers/net/ethernet/broadcom/tg3.c
@@ -44,10 +44,8 @@
 #include <linux/prefetch.h>
 #include <linux/dma-mapping.h>
 #include <linux/firmware.h>
-#if IS_ENABLED(CONFIG_HWMON)
 #include <linux/hwmon.h>
 #include <linux/hwmon-sysfs.h>
-#endif
 
 #include <net/checksum.h>
 #include <net/ip.h>
@@ -9517,7 +9515,6 @@ static int tg3_init_hw(struct tg3 *tp, int reset_phy)
 	return tg3_reset_hw(tp, reset_phy);
 }
 
-#if IS_ENABLED(CONFIG_HWMON)
 static void tg3_sd_scan_scratchpad(struct tg3 *tp, struct tg3_ocir *ocir)
 {
 	int i;
@@ -9570,22 +9567,17 @@ static const struct attribute_group tg3_group = {
 	.attrs = tg3_attributes,
 };
 
-#endif
-
 static void tg3_hwmon_close(struct tg3 *tp)
 {
-#if IS_ENABLED(CONFIG_HWMON)
 	if (tp->hwmon_dev) {
 		hwmon_device_unregister(tp->hwmon_dev);
 		tp->hwmon_dev = NULL;
 		sysfs_remove_group(&tp->pdev->dev.kobj, &tg3_group);
 	}
-#endif
 }
 
 static void tg3_hwmon_open(struct tg3 *tp)
 {
-#if IS_ENABLED(CONFIG_HWMON)
 	int i, err;
 	u32 size = 0;
 	struct pci_dev *pdev = tp->pdev;
@@ -9617,7 +9609,6 @@ static void tg3_hwmon_open(struct tg3 *tp)
 		dev_err(&pdev->dev, "Cannot register hwmon device, aborting\n");
 		sysfs_remove_group(&pdev->dev.kobj, &tg3_group);
 	}
-#endif
 }
 
 
-- 
1.7.11.1

^ permalink raw reply related

* [ANNOUNCE] iproute2 v3.6.0
From: Stephen Hemminger @ 2012-10-01 16:01 UTC (permalink / raw)
  To: netdev; +Cc: linux-kernel

I am happy to announce the update to iproute2 for v3.6 kernel.
In addition to lots of documentation and minor bugfixes,
this version contains support for controlling the forwarding
tables of software and external device bridges.

This also means that if there are changes to iproute2 to support
features added to 3.7 merge window, please submit them now.


Iproute2 package is available at:
  http://kernel.org/pub/linux/utils/net/iproute2/iproute2-3.6.0.tar.gz

You can download the source from:
  git://git.kernel.org/pub/scm/linux/kernel/git/shemminger/iproute2.git

---

Andreas Schwab (1):
      iproute2: Fix various manpage formatting nits

Chris Webb (1):
      Correct the bridge command name in help messages

Dan Kenigsberg (1):
      utils: invarg: msg precedes the faulty arg

Eric Dumazet (1):
      ss: report SK_MEMINFO_BACKLOG

Florian Westphal (2):
      tc: add ipset ematch
      add ematch man page

Jiri Pirko (1):
      iplink: add support for num[tr]xqueues

John Fastabend (4):
      iproute2: Add FDB print and update cmds for self and master
      iproute2: build failure due to missing '\' in Makefile
      iproute2: bridge: remove replace and change options
      iproute2: bridge: finish removing replace option in man pages

Julian Anastasov (3):
      iproute2: add libgenl files
      iproute2: use libgenl in ipl2tp
      iproute2: GENL: merge GENL_REQUEST and GENL_INITIALIZER

Li Wei (3):
      iproute2: fix typo in help message.
      iproute2: configure: Add search path for 64bit library.
      iproute2: tc.8: update UNITS section.

Mathias Krause (1):
      configure: remove TMPDIR on exit

Mike Frysinger (1):
      Fix regression with 'ip address show'

Oliver Hartkopp (1):
      iproute2: Add missing tc-ematch.8 for man page installation

Pavel Emelyanov (4):
      iproute: Fix errno propagation from rtnl_talk
      iproute: Add magic cookie to route dump file
      iproute: Add route showdump command (v2)
      iproute: Add ability to save, restore and show the interfaces' addresses (resend)

Rostislav Lisovy (2):
      add can.h
      Ematch used to classify CAN frames according to their identifiers

Saurabh (1):
      iproute2: VTI support for ip link command.

Saurabh Mohan (1):
      VTI support for ip tunnel

Stephen Hemminger (9):
      Update to 3.6.0-pre headers
      Fix formatting of ip.8 family man page
      Explain TC class id limits
      Update can.h to 3.6-rc2
      Install all tc and ip sub pages
      man: make sure tc man page gets installed
      Add support for AF_BRIDGE
      update header files to 3.6
      v3.6.0

Werner Fink (1):
      Change how pdf doc's are created

Xose Vazquez Perez (1):
      Fix Makefile's

^ permalink raw reply

* Re: [PATCHv4 1/4] modem_shm: Add Modem Access Framework
From: Greg KH @ 2012-10-01 15:59 UTC (permalink / raw)
  To: Arun MURTHY
  Cc: linux-kernel@vger.kernel.org, netdev@vger.kernel.org,
	linux-doc@vger.kernel.org, alan@lxorguk.ukuu.org.uk
In-Reply-To: <F45880696056844FA6A73F415B568C695B6962C153@EXDCVYMBSTM006.EQ1STM.local>

On Mon, Oct 01, 2012 at 07:30:38AM +0200, Arun MURTHY wrote:
> > On Fri, Sep 28, 2012 at 01:35:01PM +0530, Arun Murthy wrote:
> > > +#include <linux/module.h>
> > > +#include <linux/slab.h>
> > > +#include <linux/err.h>
> > > +#include <linux/printk.h>
> > > +#include <linux/modem_shm/modem.h>
> > > +
> > > +static struct class *modem_class;
> > 
> > What's wrong with a bus_type instead?
> 
> Can I know the advantage of using bus_type over class?

You have devices living on a bus, and it's much more descriptive than a
class (which we are going to eventually get rid of one of these
days...).

Might I ask why you choose a class over a bus_type?

> > > +int modem_release(struct modem_desc *mdesc) {
> > > +	if (!mdesc->release)
> > > +		return -EFAULT;
> > > +
> > > +	if (modem_is_requested(mdesc)) {
> > > +		atomic_dec(&mdesc->mclients->cnt);
> > > +		if (atomic_read(&mdesc->use_cnt) == 1) {
> > > +			mdesc->release(mdesc);
> > > +			atomic_dec(&mdesc->use_cnt);
> > > +		}
> > 
> > Eeek, why aren't you using the built-in reference counting that the struct
> > device provided to you, and instead are rolling your own?  This happens in
> > many places, why?
> 
> My usage of counters over here is for each modem there are many clients.
> Each of the clients will have a ref to modem_desc. Each of them use this for
> requesting and releasing the modem. One counter for tracking the request
> and release for each client which is done by variable 'cnt' in struct clients.
> The counter use_cnt is used for tracking the modem request/release irrespective
> of the clients and counter cli_cnt is used for restricting the modem_get to
> the no of clients defined in no_clients.
> 
> So totally 3 counter one for restricting the usage of modem_get by clients,
> second for restricting modem request/release at top level, and 3rd for
> restricting modem release/request for per client per modem basis.
> 
> Can you let me know if the same can be achieved by using built-in ref
> counting?

Yes, because you don't need all of those different levels, just stick
with one and you should be fine. :)

thanks,

greg k-h

^ permalink raw reply

* Re: [RFC] gre: conform to RFC6040 ECN progogation
From: Stephen Hemminger @ 2012-10-01 15:56 UTC (permalink / raw)
  To: Ben Hutchings; +Cc: Chris Wright, David Miller, netdev
In-Reply-To: <1349106919.2577.9.camel@bwh-desktop.uk.solarflarecom.com>

On Mon, 1 Oct 2012 16:55:19 +0100
Ben Hutchings <bhutchings@solarflare.com> wrote:

> On Mon, 2012-09-24 at 14:44 -0700, Stephen Hemminger wrote:
> [...]
> > --- a/net/ipv4/ip_gre.c	2012-09-21 08:45:55.948772761 -0700
> > +++ b/net/ipv4/ip_gre.c	2012-09-24 14:35:54.666185603 -0700
> [...]
> > @@ -703,17 +704,18 @@ static int ipgre_rcv(struct sk_buff *skb
> >  			skb_postpull_rcsum(skb, eth_hdr(skb), ETH_HLEN);
> >  		}
> >  
> > +		__skb_tunnel_rx(skb, tunnel->dev);
> > +
> > +		skb_reset_network_header(skb);
> > +		if (!ipgre_ecn_decapsulate(iph, skb))
> > +			goto drop;
> > +
> >  		tstats = this_cpu_ptr(tunnel->dev->tstats);
> >  		u64_stats_update_begin(&tstats->syncp);
> >  		tstats->rx_packets++;
> >  		tstats->rx_bytes += skb->len;
> >  		u64_stats_update_end(&tstats->syncp);
> 
> I don't know why you're moving this code above the stats update;
> rx_packets/rx_bytes should include dropped packets.
> 
> Ben.
> 
> > -		__skb_tunnel_rx(skb, tunnel->dev);
> > -
> > -		skb_reset_network_header(skb);
> > -		ipgre_ecn_decapsulate(iph, skb);
> > -
> >  		netif_rx(skb);
> >  
> >  		rcu_read_unlock();
> 

Is that true? I thought they were accounted for by rx_dropped.

^ permalink raw reply

* Re: [RFC] gre: conform to RFC6040 ECN progogation
From: Ben Hutchings @ 2012-10-01 15:55 UTC (permalink / raw)
  To: Stephen Hemminger; +Cc: Chris Wright, David Miller, netdev
In-Reply-To: <20120924144457.0c76bce2@nehalam.linuxnetplumber.net>

On Mon, 2012-09-24 at 14:44 -0700, Stephen Hemminger wrote:
[...]
> --- a/net/ipv4/ip_gre.c	2012-09-21 08:45:55.948772761 -0700
> +++ b/net/ipv4/ip_gre.c	2012-09-24 14:35:54.666185603 -0700
[...]
> @@ -703,17 +704,18 @@ static int ipgre_rcv(struct sk_buff *skb
>  			skb_postpull_rcsum(skb, eth_hdr(skb), ETH_HLEN);
>  		}
>  
> +		__skb_tunnel_rx(skb, tunnel->dev);
> +
> +		skb_reset_network_header(skb);
> +		if (!ipgre_ecn_decapsulate(iph, skb))
> +			goto drop;
> +
>  		tstats = this_cpu_ptr(tunnel->dev->tstats);
>  		u64_stats_update_begin(&tstats->syncp);
>  		tstats->rx_packets++;
>  		tstats->rx_bytes += skb->len;
>  		u64_stats_update_end(&tstats->syncp);

I don't know why you're moving this code above the stats update;
rx_packets/rx_bytes should include dropped packets.

Ben.

> -		__skb_tunnel_rx(skb, tunnel->dev);
> -
> -		skb_reset_network_header(skb);
> -		ipgre_ecn_decapsulate(iph, skb);
> -
>  		netif_rx(skb);
>  
>  		rcu_read_unlock();

-- 
Ben Hutchings, Staff Engineer, Solarflare
Not speaking for my employer; that's the marketing department's job.
They asked us to note that Solarflare product names are trademarked.

^ permalink raw reply

* Re: [PATCH RFC] pkt_sched: QFQ Plus: fair-queueing service at DRR cost
From: Paolo Valente @ 2012-10-01 15:50 UTC (permalink / raw)
  To: Stephen Hemminger; +Cc: jhs, davem, linux-kernel, netdev, rizzo, fchecconi
In-Reply-To: <20121001083100.13fc231c@nehalam.linuxnetplumber.net>

Il 01/10/2012 17:31, Stephen Hemminger ha scritto:
> On Sun, 30 Sep 2012 19:40:49 +0200
> Paolo Valente <paolo.valente@unimore.it> wrote:
>
>> Hi,
>> this patch turns QFQ into QFQ+, a faster variant of QFQ that groups
>> classes into aggregates, and uses the original QFQ scheduling
>> algorithm to schedule aggregates instead of single classes. An
>> aggregate is made of at most M classes, all with the same weight and
>> maximum packet size.  M is equal to the minimum between tx_queue_len+1
>> and 8 (value chosen to get a good trade-off between execution time and
>> service guarantees). QFQ+ associates each aggregate with a budget
>> equal to the maximum packet size for the classes in the aggregate,
>> multiplied by the number of classes of the aggregate. Once selected an
>> aggregate for service, QFQ+ dequeues only the packets of its classes,
>> until the aggregate finishes its budget. Finally, within an aggregate,
>> classes are scheduled with DRR. In my tests, described below, the
>> execution time of QFQ+ with M=8 was from 16% to 31% lower than that of
>> QFQ, and close to that of DRR.
>>
>> QFQ+ does not use packet lengths for computing aggregate timestamps,
>> but budgets. Hence it does not need to modify any timestamp if the
>> head packet of a class changes. As a consequence, differently from
>> QFQ, which uses head-packet lengths to compute class timestamps, QFQ+
>> does not need further modifications to correctly schedule also
>> non-leaf classes and classes with non-FIFO qdiscs. Finally, QFQ+ is
>> more robust than QFQ against corruption of the data structures
>> implementing the bucket lists. A detailed description of QFQ+ can be
>> found in [1].
>>
>> As for service guarantees, thanks to the way how M is computed, the
>> service of QFQ+ is close to the one of QFQ. For example, as proved in
>> [1], under QFQ+ every packet of a given class is guaranteed the same
>> worst-case completion time as under QFQ, plus an additional delay
>> equal to the transmission time, at the rate reserved to the class, of
>> three maximum-size packet. See [1, Section 7.1] for a numerical
>> comparison among the packet delays guaranteed by QFQ+, QFQ and DRR.
>>
>> I measured the execution time of QFQ+, DRR and QFQ using the testing
>> environment [2]. In particular, for each scheduler I measured the
>> average total execution time of a packet enqueue plus a packet
>> dequeue.  For practical reasons, in this testing environment each
>> enqueue&dequeue is also charged for the cost of generating and
>> discarding an empty, fixed-size packet (using a free list). The
>> following table reports the results with an i7-2760QM, against four
>> different class sets. Time is measured in nanoseconds, while each set
>> or subset of classes is denoted as <num_classes>-w<weight>, where
>> <num_classes> and <weight> are, respectively, the number of classes
>> and the weight of every class in the set/subset (for example, 250-w1
>> stands for 250 classes with weight 1). For QFQ+, the table shows the
>> results for the two extremes for M: 1 and 8 (see [1, Section 7.2] for
>> results with other values of M and for more information).
>>
>>   -----------------------------------------------
>> | Set of  |      QFQ+ (M)     |   DRR      QFQ  |
>> | classes |    1          8   |                 |
>> |-----------------------------------------------|
>> | 1k-w1   |   89         63   |    56       81  |
>> |-----------------------------------------------|
>> | 500-w1, |                   |                 |
>> | 250-w2, |  102         71   |    87      103  |
>> | 250-w4  |                   |                 |
>> |-----------------------------------------------|
>> | 32k-w1  |  267        225   |   173      257  |
>> |-----------------------------------------------|
>> | 16k-w1, |                   |                 |
>> | 8k-w2,  |  253        187   |   252      257  |
>> | 8k-w4   |                   |                 |
>>   -----------------------------------------------
>>
>> About DRR, it achieves its best performance when all the classes have
>> the same weight. This is fortunate, because in such scenarios it is
>> actually pointless to use a fair-queueing scheduler, as the latter
>> would provide the same quality of service as DRR. In contrast, when
>> classes have differentiated weights and the better service properties
>> of QFQ+ make a difference, QFQ+ has better performance than DRR. It
>> happens mainly because QFQ+ dequeues packets in an order that causes
>> about 8% less cache misses than DRR. As for the number of
>> instructions, QFQ+ executes instead about 7% more instructions than
>> DRR, whereas QFQ executes from 25% to 34% more instructions than DRR.
>>
>> Paolo
>>
>> [1] P. Valente, "Reducing the Execution Time of Fair-Queueing Schedulers"
>> http://algo.ing.unimo.it/people/paolo/agg-sched/agg-sched.pdf
>>
>> [2] http://algo.ing.unimo.it/people/paolo/agg-sched/test-env.tgz
>>
>> Signed-off-by: Paolo Valente <paolo.valente@unimore.it>
> I like the improvement and the performance improvement.
> Is there some concern that changing the implementation this much might
> upset some people already using QFQ?
>
> What happens if an existing working QFQ config is used in QFQ+?
>
>
>
QFQ+ has the same interface as QFQ, so existing QFQ configs should work 
without problems (if i am not missing anything)

^ permalink raw reply

* Re: Possible networking regression in 3.6.0
From: Eric Dumazet @ 2012-10-01 15:31 UTC (permalink / raw)
  To: Chris Clayton; +Cc: David Miller, netdev, gpiez
In-Reply-To: <5069B300.9080308@googlemail.com>

On Mon, 2012-10-01 at 16:13 +0100, Chris Clayton wrote:
> 
> On 10/01/12 10:15, Eric Dumazet wrote:
> > On Mon, 2012-10-01 at 09:36 +0100, Chris Clayton wrote:
> >>
> >
> >>       0 ICMP messages received
> >>       0 input ICMP message failed.
> >>       ICMP input histogram:
> >>       0 ICMP messages sent
> >>       0 ICMP messages failed
> >>       ICMP output histogram:
> >
> >>
> >> After:
> >>
> >> $ netstat -s
> >> Icmp:
> >>       4 ICMP messages received
> >>       4 input ICMP message failed.
> >>       ICMP input histogram:
> >>           echo replies: 4
> >
> > So icmp replies come back and are delivered to host instead of being
> > forwarded.
> >
> > I wonder if MASQUERADE broke...
> >
> > Could you send
> >
> > iptables -t -nat -nvL
> 
> $ iptables -t -nat -nvL
> iptables v1.4.15: can't initialize iptables table `-nat': Table does not 
> exist (do you need to insmod?)
> Perhaps iptables or your kernel needs to be upgraded.
> 
> > conntrack -L   # while ping is running from guest
> 
> $ conntrack -L
> conntrack v1.2.2 (conntrack-tools): Operation failed: invalid parameters
> 

Thats not expected, you described you used MASQUERADE target, so
"iptables -t nat -nvL" should display something.


> Forgive me for asking, but why is the problem not down to the change 
> that I identified by bisecting? The title of the patch is "ipv4: Cache 
> local output routes" and, although I'm a million miles from being an 
> expert here, to me it does make it look a good candidate. 
> http://marc.info/?l=linux-netdev&m=134797809611847&w=2

Because I cant reproduce your problem at all, using your setup.

^ permalink raw reply

* Re: [PATCH RFC] pkt_sched: QFQ Plus: fair-queueing service at DRR cost
From: Stephen Hemminger @ 2012-10-01 15:31 UTC (permalink / raw)
  To: Paolo Valente; +Cc: jhs, davem, linux-kernel, netdev, rizzo, fchecconi
In-Reply-To: <20120930174049.GA13793@paolo-ThinkPad-W520>

On Sun, 30 Sep 2012 19:40:49 +0200
Paolo Valente <paolo.valente@unimore.it> wrote:

> Hi,
> this patch turns QFQ into QFQ+, a faster variant of QFQ that groups
> classes into aggregates, and uses the original QFQ scheduling
> algorithm to schedule aggregates instead of single classes. An
> aggregate is made of at most M classes, all with the same weight and
> maximum packet size.  M is equal to the minimum between tx_queue_len+1
> and 8 (value chosen to get a good trade-off between execution time and
> service guarantees). QFQ+ associates each aggregate with a budget
> equal to the maximum packet size for the classes in the aggregate,
> multiplied by the number of classes of the aggregate. Once selected an
> aggregate for service, QFQ+ dequeues only the packets of its classes,
> until the aggregate finishes its budget. Finally, within an aggregate,
> classes are scheduled with DRR. In my tests, described below, the
> execution time of QFQ+ with M=8 was from 16% to 31% lower than that of
> QFQ, and close to that of DRR.
> 
> QFQ+ does not use packet lengths for computing aggregate timestamps,
> but budgets. Hence it does not need to modify any timestamp if the
> head packet of a class changes. As a consequence, differently from
> QFQ, which uses head-packet lengths to compute class timestamps, QFQ+
> does not need further modifications to correctly schedule also
> non-leaf classes and classes with non-FIFO qdiscs. Finally, QFQ+ is
> more robust than QFQ against corruption of the data structures
> implementing the bucket lists. A detailed description of QFQ+ can be
> found in [1].
> 
> As for service guarantees, thanks to the way how M is computed, the
> service of QFQ+ is close to the one of QFQ. For example, as proved in
> [1], under QFQ+ every packet of a given class is guaranteed the same
> worst-case completion time as under QFQ, plus an additional delay
> equal to the transmission time, at the rate reserved to the class, of
> three maximum-size packet. See [1, Section 7.1] for a numerical
> comparison among the packet delays guaranteed by QFQ+, QFQ and DRR.
> 
> I measured the execution time of QFQ+, DRR and QFQ using the testing
> environment [2]. In particular, for each scheduler I measured the
> average total execution time of a packet enqueue plus a packet
> dequeue.  For practical reasons, in this testing environment each
> enqueue&dequeue is also charged for the cost of generating and
> discarding an empty, fixed-size packet (using a free list). The
> following table reports the results with an i7-2760QM, against four
> different class sets. Time is measured in nanoseconds, while each set
> or subset of classes is denoted as <num_classes>-w<weight>, where
> <num_classes> and <weight> are, respectively, the number of classes
> and the weight of every class in the set/subset (for example, 250-w1
> stands for 250 classes with weight 1). For QFQ+, the table shows the
> results for the two extremes for M: 1 and 8 (see [1, Section 7.2] for
> results with other values of M and for more information).
> 
>  -----------------------------------------------
> | Set of  |      QFQ+ (M)     |   DRR      QFQ  |
> | classes |    1          8   |                 |
> |-----------------------------------------------|     
> | 1k-w1   |   89         63   |    56       81  |
> |-----------------------------------------------|
> | 500-w1, |                   |                 |
> | 250-w2, |  102         71   |    87      103  |
> | 250-w4  |                   |                 |
> |-----------------------------------------------|
> | 32k-w1  |  267        225   |   173      257  |
> |-----------------------------------------------|
> | 16k-w1, |                   |                 |
> | 8k-w2,  |  253        187   |   252      257  |
> | 8k-w4   |                   |                 |
>  -----------------------------------------------
> 
> About DRR, it achieves its best performance when all the classes have
> the same weight. This is fortunate, because in such scenarios it is
> actually pointless to use a fair-queueing scheduler, as the latter
> would provide the same quality of service as DRR. In contrast, when
> classes have differentiated weights and the better service properties
> of QFQ+ make a difference, QFQ+ has better performance than DRR. It
> happens mainly because QFQ+ dequeues packets in an order that causes
> about 8% less cache misses than DRR. As for the number of
> instructions, QFQ+ executes instead about 7% more instructions than
> DRR, whereas QFQ executes from 25% to 34% more instructions than DRR.
> 
> Paolo
> 
> [1] P. Valente, "Reducing the Execution Time of Fair-Queueing Schedulers"
> http://algo.ing.unimo.it/people/paolo/agg-sched/agg-sched.pdf
> 
> [2] http://algo.ing.unimo.it/people/paolo/agg-sched/test-env.tgz
> 
> Signed-off-by: Paolo Valente <paolo.valente@unimore.it>

I like the improvement and the performance improvement.
Is there some concern that changing the implementation this much might
upset some people already using QFQ?

What happens if an existing working QFQ config is used in QFQ+?

^ permalink raw reply

* [PATCH] gre: fix sparse warning
From: Stephen Hemminger @ 2012-10-01 15:21 UTC (permalink / raw)
  To: Fengguang Wu; +Cc: kernel-janitors, netdev
In-Reply-To: <20120929011210.GA10053@localhost>

Use be16 consistently when looking at flags.

Signed-off-by: Stephen Hemminger <shemminger@vyatta.com>


--- a/net/ipv4/ip_gre.c	2012-09-27 15:47:35.076895836 -0700
+++ b/net/ipv4/ip_gre.c	2012-10-01 08:18:50.990145746 -0700
@@ -222,7 +222,7 @@ static struct rtnl_link_stats64 *ipgre_g
 
 /* Does key in tunnel parameters match packet */
 static bool ipgre_key_match(const struct ip_tunnel_parm *p,
-			    __u32 flags, __be32 key)
+			    __be16 flags, __be32 key)
 {
 	if (p->i_flags & GRE_KEY) {
 		if (flags & GRE_KEY)
@@ -237,7 +237,7 @@ static bool ipgre_key_match(const struct
 
 static struct ip_tunnel *ipgre_tunnel_lookup(struct net_device *dev,
 					     __be32 remote, __be32 local,
-					     __u32 flags, __be32 key,
+					     __be16 flags, __be32 key,
 					     __be16 gre_proto)
 {
 	struct net *net = dev_net(dev);

^ permalink raw reply

* Re: Possible networking regression in 3.6.0
From: Chris Clayton @ 2012-10-01 15:13 UTC (permalink / raw)
  To: Eric Dumazet; +Cc: David Miller, netdev, gpiez
In-Reply-To: <1349082950.12401.669.camel@edumazet-glaptop>



On 10/01/12 10:15, Eric Dumazet wrote:
> On Mon, 2012-10-01 at 09:36 +0100, Chris Clayton wrote:
>>
>
>>       0 ICMP messages received
>>       0 input ICMP message failed.
>>       ICMP input histogram:
>>       0 ICMP messages sent
>>       0 ICMP messages failed
>>       ICMP output histogram:
>
>>
>> After:
>>
>> $ netstat -s
>> Icmp:
>>       4 ICMP messages received
>>       4 input ICMP message failed.
>>       ICMP input histogram:
>>           echo replies: 4
>
> So icmp replies come back and are delivered to host instead of being
> forwarded.
>
> I wonder if MASQUERADE broke...
>
> Could you send
>
> iptables -t -nat -nvL

$ iptables -t -nat -nvL
iptables v1.4.15: can't initialize iptables table `-nat': Table does not 
exist (do you need to insmod?)
Perhaps iptables or your kernel needs to be upgraded.

> conntrack -L   # while ping is running from guest

$ conntrack -L
conntrack v1.2.2 (conntrack-tools): Operation failed: invalid parameters

Forgive me for asking, but why is the problem not down to the change 
that I identified by bisecting? The title of the patch is "ipv4: Cache 
local output routes" and, although I'm a million miles from being an 
expert here, to me it does make it look a good candidate. 
http://marc.info/?l=linux-netdev&m=134797809611847&w=2

>
>
>

^ permalink raw reply

* Re: [PATCH 3/3] net/mlx4_en: Add HW timestamping (TS) support
From: Ben Hutchings @ 2012-10-01 15:08 UTC (permalink / raw)
  To: Yevgeny Petrilin; +Cc: davem, netdev, eugenia
In-Reply-To: <1348826603-17439-4-git-send-email-yevgenyp@mellanox.com>

On Fri, 2012-09-28 at 12:03 +0200, Yevgeny Petrilin wrote:
> From: Eugenia Emantayev <eugenia@mellanox.co.il>
> 
> The patch allows to enable/disable HW timestamping for incoming and/or
> outgoing packets. It adds and initializes all structs and callbacks
> needed by kernel TS API.
> To enable/disable HW timestamping appropriate ioctl should be used.
> Currently HWTSTAMP_FILTER_ALL/NONE and HWTSAMP_TX_ON/OFF only are
> supported.
> When enabling TS on receive flow - VLAN stripping will be disabled.
> Also were made all relevant changes in RX/TX flows to consider TS request
> and plant HW timestamps into relevant structures.
> mlx4_ib was fixed to compile with new mlx4_cq_alloc() signature.
[...]
> --- /dev/null
> +++ b/drivers/net/ethernet/mellanox/mlx4/en_timestamp.c
[...]
> +int mlx4_en_timestamp_config(struct net_device *dev, int tx_type, int rx_filter)
> +{
> +	struct mlx4_en_priv *priv = netdev_priv(dev);
> +	struct mlx4_en_dev *mdev = priv->mdev;
> +	int port_up = 0;
> +	int err = 0;
> +
> +	mutex_lock(&mdev->state_lock);
> +	if (priv->port_up) {
> +		port_up = 1;
> +		mlx4_en_stop_port(dev);
> +	}
> +
> +	mlx4_en_free_resources(priv);
> +
> +	en_err(priv, "Changing Time Stamp configuration\n");
> +
> +	priv->hwtstamp_config.tx_type = tx_type;
> +	priv->hwtstamp_config.rx_filter = rx_filter;
> +
> +	if (rx_filter != HWTSTAMP_FILTER_NONE)
> +		dev->features &= ~NETIF_F_HW_VLAN_RX;
> +	else
> +		dev->features |= NETIF_F_HW_VLAN_RX;
[...]

If you change dev->features you should also call
netdev_features_change(dev) (holding only the RTNL lock, so after you
unlock mdev->state_lock).

Ben.

-- 
Ben Hutchings, Staff Engineer, Solarflare
Not speaking for my employer; that's the marketing department's job.
They asked us to note that Solarflare product names are trademarked.

^ permalink raw reply

* Re: New commands to configure IOV features
From: Don Dutile @ 2012-10-01 14:12 UTC (permalink / raw)
  To: Yuval Mintz
  Cc: Yinghai Lu, Rose, Gregory V, Ben Hutchings, Bjorn Helgaas,
	davem@davemloft.net, netdev@vger.kernel.org, Ariel Elior,
	Eilon Greenstein, linux-pci
In-Reply-To: <5067E90B.2030908@broadcom.com>

On 09/30/2012 02:39 AM, Yuval Mintz wrote:
>>>> yuk, no.
>>>> I have a set of patches almost done.
>>>> i'm tied up until Monday on RHEL6, then I'll switch gears&   post a set of
>>>> patches.
>
> hi Don - anything new about this incoming patch-series?
>
>>>
>>> so that is your employer 'sinternal policy? for RHEL 6 kernel first,
>>> then upstream kernel?
>> No, I have deadlines for RHEL6 for *other work* until Monday.  After that,
>> I can re-focus on upstream work.  Some of us actually have other work than
>> just upstream.... crazy talk, I know! ;-)
>
>
I should have the sysfs-level patches done & posted today.
Need another day or 2 to get a driver refactored to use it (ixgbe).

Although the patches will enable per-device sriov enablement/disablement,
further thought on tools that will stack on top of it, probably will need
to augment a new pci sysfs directory that tools can find sriov devices
quicker/easier w/o traversing the entire /sys/bus/pci/devices tree
searching for a 'sriov_max_vfs' file, but, I can do that as a follow-on patch.
I'm thinking of what is done now with virtfn<X> linked files in the pf,
but the inverse link in a directory, like /sys/bus/pci/sriov.

Then there's the additional patches needed to do an 'all', or <DOMAIN:B:D.F>
qualified enable/disable from a per-sysfs-driver perspective. ... fun stuff!

^ permalink raw reply

* [PATCH net-next v5 1/1] ipv6: add support of ECMP
From: Nicolas Dichtel @ 2012-10-01 13:56 UTC (permalink / raw)
  To: davem; +Cc: bernat, netdev, yoshfuji, Nicolas Dichtel
In-Reply-To: <1349099807-3907-1-git-send-email-nicolas.dichtel@6wind.com>

This patch adds the support of equal cost multipath for IPv6.

The patch is based on a previous work from
Luc Saillard <luc.saillard@6wind.com>.

Signed-off-by: Nicolas Dichtel <nicolas.dichtel@6wind.com>
---
 include/net/ip6_fib.h |  13 ++++
 net/ipv6/Kconfig      |  10 +++
 net/ipv6/ip6_fib.c    |  73 +++++++++++++++++++++
 net/ipv6/route.c      | 177 +++++++++++++++++++++++++++++++++++++++++++++++++-
 4 files changed, 270 insertions(+), 3 deletions(-)

diff --git a/include/net/ip6_fib.h b/include/net/ip6_fib.h
index 8a2a203..ed3f9c5 100644
--- a/include/net/ip6_fib.h
+++ b/include/net/ip6_fib.h
@@ -47,6 +47,10 @@ struct fib6_config {
 	unsigned long	fc_expires;
 	struct nlattr	*fc_mx;
 	int		fc_mx_len;
+#ifdef CONFIG_IPV6_MULTIPATH
+	struct nlattr	*fc_mp;
+	int		fc_mp_len;
+#endif
 
 	struct nl_info	fc_nlinfo;
 };
@@ -98,6 +102,15 @@ struct rt6_info {
 	struct fib6_node		*rt6i_node;
 
 	struct in6_addr			rt6i_gateway;
+#ifdef CONFIG_IPV6_MULTIPATH
+	/*
+	 * siblings is a list of rt6_info that have the the same metric/weight,
+	 * destination, but not the same gateway. nsiblings is just a cache
+	 * to speed up lookup.
+	 */
+	unsigned int			rt6i_nsiblings;
+	struct list_head		rt6i_siblings;
+#endif
 
 	atomic_t			rt6i_ref;
 
diff --git a/net/ipv6/Kconfig b/net/ipv6/Kconfig
index 4f7fe72..fc2f3cb 100644
--- a/net/ipv6/Kconfig
+++ b/net/ipv6/Kconfig
@@ -266,4 +266,14 @@ config IPV6_PIMSM_V2
 	  Support for IPv6 PIM multicast routing protocol PIM-SMv2.
 	  If unsure, say N.
 
+config IPV6_MULTIPATH
+	bool "IPv6: equal cost multipath for IPv6 routing"
+	depends on IPV6
+	default y
+	---help---
+	  Enable this option to support ECMP for IPv6.
+
+	  The algorithm used for route selection is based on a hash of packet
+	  header (recommanded by RFC4311) and flowlabel (RFC6438).
+
 endif # IPV6
diff --git a/net/ipv6/ip6_fib.c b/net/ipv6/ip6_fib.c
index 24995a9..754888c 100644
--- a/net/ipv6/ip6_fib.c
+++ b/net/ipv6/ip6_fib.c
@@ -672,6 +672,10 @@ static int fib6_add_rt2node(struct fib6_node *fn, struct rt6_info *rt,
 			    iter->rt6i_idev == rt->rt6i_idev &&
 			    ipv6_addr_equal(&iter->rt6i_gateway,
 					    &rt->rt6i_gateway)) {
+#ifdef CONFIG_IPV6_MULTIPATH
+				if (rt->rt6i_nsiblings)
+					rt->rt6i_nsiblings = 0;
+#endif
 				if (!(iter->rt6i_flags & RTF_EXPIRES))
 					return -EEXIST;
 				if (!(rt->rt6i_flags & RTF_EXPIRES))
@@ -680,6 +684,23 @@ static int fib6_add_rt2node(struct fib6_node *fn, struct rt6_info *rt,
 					rt6_set_expires(iter, rt->dst.expires);
 				return -EEXIST;
 			}
+#ifdef CONFIG_IPV6_MULTIPATH
+			/* If we have the same destination and the same metric,
+			 * but not the same gateway, then the route we try to
+			 * add is sibling to this route, increment our counter
+			 * of siblings, and later we will add our route to the
+			 * list.
+			 * Only static routes (which don't have flag
+			 * RTF_EXPIRES) are used for ECMPv6.
+			 *
+			 * To avoid long list, we only had siblings if the
+			 * route have a gateway.
+			 */
+			if (rt->rt6i_flags & RTF_GATEWAY &&
+			    !(rt->rt6i_flags & RTF_EXPIRES) &&
+			    !(iter->rt6i_flags & RTF_EXPIRES))
+				rt->rt6i_nsiblings++;
+#endif
 		}
 
 		if (iter->rt6i_metric > rt->rt6i_metric)
@@ -692,6 +713,43 @@ static int fib6_add_rt2node(struct fib6_node *fn, struct rt6_info *rt,
 	if (ins == &fn->leaf)
 		fn->rr_ptr = NULL;
 
+#ifdef CONFIG_IPV6_MULTIPATH
+	/* Link this route to others same route. */
+	if (rt->rt6i_nsiblings) {
+		unsigned int rt6i_nsiblings;
+		struct rt6_info *sibling, *temp_sibling;
+
+		/* Find the first route that have the same metric */
+		sibling = fn->leaf;
+		while (sibling) {
+			if (sibling->rt6i_metric == rt->rt6i_metric) {
+				list_add_tail(&rt->rt6i_siblings,
+					      &sibling->rt6i_siblings);
+				break;
+			}
+			sibling = sibling->dst.rt6_next;
+		}
+		/* For each sibling in the list, increment the counter of
+		 * siblings. We can check if all the counter are equal.
+		 */
+		rt6i_nsiblings = 0;
+		list_for_each_entry_safe(sibling, temp_sibling,
+					 &rt->rt6i_siblings,
+					 rt6i_siblings) {
+			sibling->rt6i_nsiblings++;
+			if (unlikely(sibling->rt6i_nsiblings !=
+				     rt->rt6i_nsiblings)) {
+				pr_err("Wrong number of siblings for route %p (%d)\n",
+				       sibling, sibling->rt6i_nsiblings);
+			}
+			rt6i_nsiblings++;
+		}
+		if (unlikely(rt6i_nsiblings != rt->rt6i_nsiblings)) {
+			pr_err("Wrong number of siblings for route %p. I have %d routes, but count %d siblings\n",
+			       rt, rt6i_nsiblings, rt->rt6i_nsiblings);
+		}
+	}
+#endif
 	/*
 	 *	insert node
 	 */
@@ -1193,6 +1251,21 @@ static void fib6_del_route(struct fib6_node *fn, struct rt6_info **rtp,
 	if (fn->rr_ptr == rt)
 		fn->rr_ptr = NULL;
 
+#ifdef CONFIG_IPV6_MULTIPATH
+	/* Remove this entry from other siblings */
+	if (rt->rt6i_nsiblings) {
+		struct rt6_info *sibling, *next_sibling;
+
+		/* For each siblings, decrement the counter of siblings */
+		list_for_each_entry_safe(sibling, next_sibling,
+					 &rt->rt6i_siblings, rt6i_siblings) {
+			sibling->rt6i_nsiblings--;
+		}
+		rt->rt6i_nsiblings = 0;
+		list_del_init(&rt->rt6i_siblings);
+	}
+#endif
+
 	/* Adjust walkers */
 	read_lock(&fib6_walker_lock);
 	FOR_WALKERS(w) {
diff --git a/net/ipv6/route.c b/net/ipv6/route.c
index d1ddbc6..0a8e16d 100644
--- a/net/ipv6/route.c
+++ b/net/ipv6/route.c
@@ -57,6 +57,9 @@
 #include <net/xfrm.h>
 #include <net/netevent.h>
 #include <net/netlink.h>
+#ifdef CONFIG_IPV6_MULTIPATH
+#include <net/nexthop.h>
+#endif
 
 #include <asm/uaccess.h>
 
@@ -289,6 +292,10 @@ static inline struct rt6_info *ip6_dst_alloc(struct net *net,
 		memset(dst + 1, 0, sizeof(*rt) - sizeof(*dst));
 		rt6_init_peer(rt, table ? &table->tb6_peers : net->ipv6.peers);
 		rt->rt6i_genid = rt_genid(net);
+#ifdef CONFIG_IPV6_MULTIPATH
+		INIT_LIST_HEAD(&rt->rt6i_siblings);
+		rt->rt6i_nsiblings = 0;
+#endif
 	}
 	return rt;
 }
@@ -385,6 +392,92 @@ static bool rt6_need_strict(const struct in6_addr *daddr)
 		(IPV6_ADDR_MULTICAST | IPV6_ADDR_LINKLOCAL | IPV6_ADDR_LOOPBACK);
 }
 
+#ifdef CONFIG_IPV6_MULTIPATH
+/*
+ *	Multipath route selection.
+ */
+
+/*
+ * Hash based function using packet header and flowlabel.
+ * Adapted from fib_info_hashfn()
+ */
+static int rt6_info_hash_nhsfn(unsigned int candidate_count,
+			       const struct flowi6 *fl6)
+{
+	unsigned int val = fl6->flowi6_proto;
+
+	val ^= fl6->daddr.s6_addr32[0];
+	val ^= fl6->daddr.s6_addr32[1];
+	val ^= fl6->daddr.s6_addr32[2];
+	val ^= fl6->daddr.s6_addr32[3];
+
+	val ^= fl6->saddr.s6_addr32[0];
+	val ^= fl6->saddr.s6_addr32[1];
+	val ^= fl6->saddr.s6_addr32[2];
+	val ^= fl6->saddr.s6_addr32[3];
+
+	/* Work only if this not encapsulated */
+	switch (fl6->flowi6_proto) {
+	case IPPROTO_UDP:
+	case IPPROTO_TCP:
+	case IPPROTO_SCTP:
+		val ^= fl6->fl6_sport;
+		val ^= fl6->fl6_dport;
+		break;
+
+	case IPPROTO_ICMPV6:
+		val ^= fl6->fl6_icmp_type;
+		val ^= fl6->fl6_icmp_code;
+		break;
+	}
+	/* RFC6438 recommands to use flowlabel */
+	val ^= fl6->flowlabel;
+
+	/* Perhaps, we need to tune, this function? */
+	val = val ^ (val >> 7) ^ (val >> 12);
+	return val % candidate_count;
+}
+
+/*
+ * This function returns an index used to select a route between any siblings.
+ *
+ * Note: fl6 can be NULL
+ */
+static unsigned int rt6_info_hashfn(struct net *net,
+				    const struct rt6_info *rt,
+				    const struct flowi6 *fl6)
+{
+	int candidate_count = rt->rt6i_nsiblings + 1;
+
+	if (fl6 == NULL)
+		return 0;
+	return rt6_info_hash_nhsfn(candidate_count, fl6);
+}
+
+static struct rt6_info *rt6_multipath_select(struct net *net,
+					     struct rt6_info *match,
+					     struct flowi6 *fl6)
+{
+	struct rt6_info *sibling, *next_sibling;
+	int route_choosen;
+
+	route_choosen = rt6_info_hashfn(net, match, fl6);
+	/* Don't change the route, if route_choosen == 0
+	 * (siblings does not include ourself)
+	 */
+	if (route_choosen)
+		list_for_each_entry_safe(sibling, next_sibling,
+				&match->rt6i_siblings, rt6i_siblings) {
+			route_choosen--;
+			if (route_choosen == 0) {
+				match = sibling;
+				break;
+			}
+		}
+	return match;
+}
+#endif /* CONFIG_IPV6_MULTIPATH */
+
 /*
  *	Route lookup. Any table->tb6_lock is implied.
  */
@@ -702,6 +795,10 @@ static struct rt6_info *ip6_pol_route_lookup(struct net *net,
 restart:
 	rt = fn->leaf;
 	rt = rt6_device_match(net, rt, &fl6->saddr, fl6->flowi6_oif, flags);
+#ifdef CONFIG_IPV6_MULTIPATH
+	if (rt->rt6i_nsiblings && fl6->flowi6_oif == 0)
+		rt = rt6_multipath_select(net, rt, fl6);
+#endif
 	BACKTRACK(net, &fl6->saddr);
 out:
 	dst_use(&rt->dst, jiffies);
@@ -863,7 +960,10 @@ restart_2:
 
 restart:
 	rt = rt6_select(fn, oif, strict | reachable);
-
+#ifdef CONFIG_IPV6_MULTIPATH
+	if (rt->rt6i_nsiblings && oif == 0)
+		rt = rt6_multipath_select(net, rt, fl6);
+#endif
 	BACKTRACK(net, &fl6->saddr);
 	if (rt == net->ipv6.ip6_null_entry ||
 	    rt->rt6i_flags & RTF_CACHE)
@@ -2248,6 +2348,9 @@ static const struct nla_policy rtm_ipv6_policy[RTA_MAX+1] = {
 	[RTA_IIF]		= { .type = NLA_U32 },
 	[RTA_PRIORITY]          = { .type = NLA_U32 },
 	[RTA_METRICS]           = { .type = NLA_NESTED },
+#ifdef CONFIG_IPV6_MULTIPATH
+	[RTA_MULTIPATH]		= { .len = sizeof(struct rtnexthop) },
+#endif
 };
 
 static int rtm_to_fib6_config(struct sk_buff *skb, struct nlmsghdr *nlh,
@@ -2325,11 +2428,69 @@ static int rtm_to_fib6_config(struct sk_buff *skb, struct nlmsghdr *nlh,
 	if (tb[RTA_TABLE])
 		cfg->fc_table = nla_get_u32(tb[RTA_TABLE]);
 
+#ifdef CONFIG_IPV6_MULTIPATH
+	if (tb[RTA_MULTIPATH]) {
+		cfg->fc_mp = nla_data(tb[RTA_MULTIPATH]);
+		cfg->fc_mp_len = nla_len(tb[RTA_MULTIPATH]);
+	}
+#endif
+
 	err = 0;
 errout:
 	return err;
 }
 
+#ifdef CONFIG_IPV6_MULTIPATH
+static int ip6_route_multipath(struct fib6_config *cfg, int add)
+{
+	struct fib6_config r_cfg;
+	struct rtnexthop *rtnh;
+	int remaining;
+	int attrlen;
+	int err = 0, last_err = 0;
+
+beginning:
+	rtnh = (struct rtnexthop *)cfg->fc_mp;
+	remaining = cfg->fc_mp_len;
+
+	/* Parse a Multipath Entry */
+	while (rtnh_ok(rtnh, remaining)) {
+		memcpy(&r_cfg, cfg, sizeof(*cfg));
+		if (rtnh->rtnh_ifindex)
+			r_cfg.fc_ifindex = rtnh->rtnh_ifindex;
+
+		attrlen = rtnh_attrlen(rtnh);
+		if (attrlen > 0) {
+			struct nlattr *nla, *attrs = rtnh_attrs(rtnh);
+
+			nla = nla_find(attrs, attrlen, RTA_GATEWAY);
+			if (nla) {
+				nla_memcpy(&r_cfg.fc_gateway, nla, 16);
+				r_cfg.fc_flags |= RTF_GATEWAY;
+			}
+		}
+		err = add ? ip6_route_add(&r_cfg) : ip6_route_del(&r_cfg);
+		if (err) {
+			last_err = err;
+			/* If we are trying to remove a route, do not stop the
+			 * loop when ip6_route_del() fails (because next hop is
+			 * already gone), we should try to remove all next hops.
+			 */
+			if (add) {
+				/* If add fails, we should try to delete all
+				 * next hops that have been already added.
+				 */
+				add = 0;
+				goto beginning;
+			}
+		}
+		rtnh = rtnh_next(rtnh, &remaining);
+	}
+
+	return last_err;
+}
+#endif /* CONFIG_IPV6_MULTIPATH */
+
 static int inet6_rtm_delroute(struct sk_buff *skb, struct nlmsghdr* nlh, void *arg)
 {
 	struct fib6_config cfg;
@@ -2339,7 +2500,12 @@ static int inet6_rtm_delroute(struct sk_buff *skb, struct nlmsghdr* nlh, void *a
 	if (err < 0)
 		return err;
 
-	return ip6_route_del(&cfg);
+#ifdef CONFIG_IPV6_MULTIPATH
+	if (cfg.fc_mp)
+		return ip6_route_multipath(&cfg, 0);
+	else
+#endif
+		return ip6_route_del(&cfg);
 }
 
 static int inet6_rtm_newroute(struct sk_buff *skb, struct nlmsghdr* nlh, void *arg)
@@ -2351,7 +2517,12 @@ static int inet6_rtm_newroute(struct sk_buff *skb, struct nlmsghdr* nlh, void *a
 	if (err < 0)
 		return err;
 
-	return ip6_route_add(&cfg);
+#ifdef CONFIG_IPV6_MULTIPATH
+	if (cfg.fc_mp)
+		return ip6_route_multipath(&cfg, 1);
+	else
+#endif
+		return ip6_route_add(&cfg);
 }
 
 static inline size_t rt6_nlmsg_size(void)
-- 
1.7.12

^ permalink raw reply related

* [PATCH net-next v5 0/1] Add support of ECMPv6
From: Nicolas Dichtel @ 2012-10-01 13:56 UTC (permalink / raw)
  To: davem; +Cc: bernat, netdev, yoshfuji
In-Reply-To: <20120921.134833.1294721941180523200.davem@davemloft.net>

Here is a proposal to add the support of ECMPv6. The previous patch
from Vincent against iproute2 can be used, but a little other patch is needed
too, see http://patchwork.ozlabs.org/patch/183277/

If the kernel patch is approved, I can submit formally the patch for
iproute2.

Here is an example of a command to add an ECMP route:
$ ip -6 route add 3ffe:304:124:2306::/64 \
	nexthop via fe80::230:1bff:feb4:e05c dev eth0 \
	nexthop via fe80::230:1bff:feb4:dd4f dev eth0

But note that this command is a shortcut and previous patches are not
mandatory to set ECMP routes. The following commands can be used too:
$ ip -6 route add 3ffe:304:124:2306::/64 via fe80::230:1bff:feb4:dd4f dev
eth0
$ ip -6 route append 3ffe:304:124:2306::/64 via fe80::230:1bff:feb4:e05c dev
eth0

Here is an example of a dump:
$ ip -6 route | grep 3ffe:304:124:2306::/64
3ffe:304:124:2306::/64 via fe80::230:1bff:feb4:dd4f dev eth0  metric 1024
3ffe:304:124:2306::/64 via fe80::230:1bff:feb4:e05c dev eth0  metric 1024

v5: to minimize the patch and ease its integration, remove roundrobin and random
    algorithms for route selection. It will be possible to add new algorithms
    through rt6_info_hashfn() when the basic support of ECMP is integrated.

v4: remove compilation options to choose multipath algorithm for next hop
    selection. Now the choice can be done at run time via
    /proc/sys/net/ipv6/route/multipath_algorithm

v3: rebase after updating net-next

v2: rename CONFIG_IPV6_MULTIPATH_ROUTE to CONFIG_IPV6_MULTIPATH_HASH
    use flowlabel in the hash function
    add reference to RFC
    fix a small identation issue
    remove "If unsure, say N." from the help of CONFIG_IPV6_MULTIPATH

Comments are welcome.

Regards,
Nicolas

^ permalink raw reply

* [PATCH net-next v2 2/2] bnx2x: update version to 1.78.00-0.
From: Dmitry Kravkov @ 2012-10-01 13:46 UTC (permalink / raw)
  To: davem, netdev; +Cc: Yuval Mintz, Ariel Elior, Eilon Greenstein
In-Reply-To: <1349099180-5606-1-git-send-email-dmitry@broadcom.com>

From: Yuval Mintz <yuvalmin@broadcom.com>

Signed-off-by: Yuval Mintz <yuvalmin@broadcom.com>
Signed-off-by: Ariel Elior <ariele@broadcom.com>
Signed-off-by: Eilon Greenstein <eilong@broadcom.com>
---
 drivers/net/ethernet/broadcom/bnx2x/bnx2x.h |    4 ++--
 1 files changed, 2 insertions(+), 2 deletions(-)

diff --git a/drivers/net/ethernet/broadcom/bnx2x/bnx2x.h b/drivers/net/ethernet/broadcom/bnx2x/bnx2x.h
index 6d1a24a..3865084 100644
--- a/drivers/net/ethernet/broadcom/bnx2x/bnx2x.h
+++ b/drivers/net/ethernet/broadcom/bnx2x/bnx2x.h
@@ -23,8 +23,8 @@
  * (you will need to reboot afterwards) */
 /* #define BNX2X_STOP_ON_ERROR */
 
-#define DRV_MODULE_VERSION      "1.72.51-0"
-#define DRV_MODULE_RELDATE      "2012/06/18"
+#define DRV_MODULE_VERSION      "1.78.00-0"
+#define DRV_MODULE_RELDATE      "2012/09/27"
 #define BNX2X_BC_VER            0x040200
 
 #if defined(CONFIG_DCB)
-- 
1.7.1

^ permalink raw reply related

* [PATCH net-next v2 0/2] bnx2x: net-next FW upgrade
From: Dmitry Kravkov @ 2012-10-01 13:46 UTC (permalink / raw)
  To: davem, netdev

Hi Dave,

This is a respin of previous series contains 2 patches -
the first allows the bnx2x and cnic driver to
utilize the recently submitted bnx2x FW 7.8.2, while the second advances
the bnx2x version to 1.78.00-0.

Changes since V1:
	Integrated changes to CNIC driver for FW 7.8.2.

Thanks,
Dmitry

^ permalink raw reply

* [PATCH net-next v2 1/2] bnx2x,cnic: use FW 7.8.2
From: Dmitry Kravkov @ 2012-10-01 13:46 UTC (permalink / raw)
  To: davem, netdev
  Cc: Yuval Mintz, Dmitry Kravkov, Ariel Elior, Eilon Greenstein,
	Michael Chan
In-Reply-To: <1349099180-5606-1-git-send-email-dmitry@broadcom.com>

From: Yuval Mintz <yuvalmin@broadcom.com>

This patch moves the bnx2x and cnic drivers into using FW 7.8.2
which was recently submitted into the linux-firmware tree.

A short summary of minor bugs fixed by this FW:
 1. In switch dependent mode, fix several issues regarding inner vlan
    vs. DCB priorities.
 2. iSCSI - not all packets were completed on a forward channel.
 3. DCB - fixed for 4-port devices.
 4. Fixed false parity reported in CAM memories when operating near -5%
    on the 1.0V core supply.
 5. ETS default settings are set to fairness between traffic classes
    (rather than strict priority), and uses the same chip receive buffer
    configuration for both PFC and pause.

For a complete list of fixes made by this FW, see commit 236367db
in the linux-firmware git repository.

Signed-off-by: Yuval Mintz <yuvalmin@broadcom.com>
Signed-off-by: Dmitry Kravkov <dmitry@broadcom.com>
Signed-off-by: Ariel Elior <ariele@broadcom.com>
Signed-off-by: Eilon Greenstein <eilong@broadcom.com>
Signed-off-by: Michael Chan <mchan@broadcom.com>
---
 drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.c    |   12 +-
 drivers/net/ethernet/broadcom/bnx2x/bnx2x_dcb.c    |   12 +-
 .../net/ethernet/broadcom/bnx2x/bnx2x_ethtool.c    |   31 +-
 .../net/ethernet/broadcom/bnx2x/bnx2x_fw_defs.h    |    3 -
 drivers/net/ethernet/broadcom/bnx2x/bnx2x_hsi.h    |   58 ++--
 drivers/net/ethernet/broadcom/bnx2x/bnx2x_init.h   |    2 +-
 drivers/net/ethernet/broadcom/bnx2x/bnx2x_link.c   |  504 --------------------
 drivers/net/ethernet/broadcom/bnx2x/bnx2x_sp.c     |    2 +-
 drivers/net/ethernet/broadcom/cnic.c               |   12 +-
 drivers/net/ethernet/broadcom/cnic_defs.h          |    2 +-
 drivers/net/ethernet/broadcom/cnic_if.h            |    4 +-
 11 files changed, 79 insertions(+), 563 deletions(-)

diff --git a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.c b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.c
index f67e700..30f04a3 100644
--- a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.c
+++ b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.c
@@ -3026,8 +3026,9 @@ netdev_tx_t bnx2x_start_xmit(struct sk_buff *skb, struct net_device *dev)
 	first_bd = tx_start_bd;
 
 	tx_start_bd->bd_flags.as_bitfield = ETH_TX_BD_FLAGS_START_BD;
-	SET_FLAG(tx_start_bd->general_data, ETH_TX_START_BD_ETH_ADDR_TYPE,
-		 mac_type);
+	SET_FLAG(tx_start_bd->general_data,
+		 ETH_TX_START_BD_PARSE_NBDS,
+		 0);
 
 	/* header nbd */
 	SET_FLAG(tx_start_bd->general_data, ETH_TX_START_BD_HDR_NBDS, 1);
@@ -3077,13 +3078,20 @@ netdev_tx_t bnx2x_start_xmit(struct sk_buff *skb, struct net_device *dev)
 					      &pbd_e2->dst_mac_addr_lo,
 					      eth->h_dest);
 		}
+
+		SET_FLAG(pbd_e2_parsing_data,
+			 ETH_TX_PARSE_BD_E2_ETH_ADDR_TYPE, mac_type);
 	} else {
+		u16 global_data = 0;
 		pbd_e1x = &txdata->tx_desc_ring[bd_prod].parse_bd_e1x;
 		memset(pbd_e1x, 0, sizeof(struct eth_tx_parse_bd_e1x));
 		/* Set PBD in checksum offload case */
 		if (xmit_type & XMIT_CSUM)
 			hlen = bnx2x_set_pbd_csum(bp, skb, pbd_e1x, xmit_type);
 
+		SET_FLAG(global_data,
+			 ETH_TX_PARSE_BD_E1X_ETH_ADDR_TYPE, mac_type);
+		pbd_e1x->global_data |= cpu_to_le16(global_data);
 	}
 
 	/* Setup the data pointer of the first BD of the packet */
diff --git a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_dcb.c b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_dcb.c
index 8a73374..2245c38 100644
--- a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_dcb.c
+++ b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_dcb.c
@@ -91,25 +91,21 @@ static void bnx2x_pfc_set(struct bnx2x *bp)
 	/*
 	 * Rx COS configuration
 	 * Changing PFC RX configuration .
-	 * In RX COS0 will always be configured to lossy and COS1 to lossless
+	 * In RX COS0 will always be configured to lossless and COS1 to lossy
 	 */
 	for (i = 0 ; i < MAX_PFC_PRIORITIES ; i++) {
 		pri_bit = 1 << i;
 
-		if (pri_bit & DCBX_PFC_PRI_PAUSE_MASK(bp))
+		if (!(pri_bit & DCBX_PFC_PRI_PAUSE_MASK(bp)))
 			val |= 1 << (i * 4);
 	}
 
 	pfc_params.pkt_priority_to_cos = val;
 
 	/* RX COS0 */
-	pfc_params.llfc_low_priority_classes = 0;
+	pfc_params.llfc_low_priority_classes = DCBX_PFC_PRI_PAUSE_MASK(bp);
 	/* RX COS1 */
-	pfc_params.llfc_high_priority_classes = DCBX_PFC_PRI_PAUSE_MASK(bp);
-
-	/* BRB configuration */
-	pfc_params.cos0_pauseable = false;
-	pfc_params.cos1_pauseable = true;
+	pfc_params.llfc_high_priority_classes = 0;
 
 	bnx2x_acquire_phy_lock(bp);
 	bp->link_params.feature_config_flags |= FEATURE_CONFIG_PFC_ENABLED;
diff --git a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_ethtool.c b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_ethtool.c
index a19c9e0..c65295d 100644
--- a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_ethtool.c
+++ b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_ethtool.c
@@ -2040,8 +2040,6 @@ static int bnx2x_run_loopback(struct bnx2x *bp, int loopback_mode)
 	u16 pkt_prod, bd_prod;
 	struct sw_tx_bd *tx_buf;
 	struct eth_tx_start_bd *tx_start_bd;
-	struct eth_tx_parse_bd_e1x  *pbd_e1x = NULL;
-	struct eth_tx_parse_bd_e2  *pbd_e2 = NULL;
 	dma_addr_t mapping;
 	union eth_rx_cqe *cqe;
 	u8 cqe_fp_flags, cqe_fp_type;
@@ -2133,21 +2131,32 @@ static int bnx2x_run_loopback(struct bnx2x *bp, int loopback_mode)
 	tx_start_bd->vlan_or_ethertype = cpu_to_le16(pkt_prod);
 	tx_start_bd->bd_flags.as_bitfield = ETH_TX_BD_FLAGS_START_BD;
 	SET_FLAG(tx_start_bd->general_data,
-		 ETH_TX_START_BD_ETH_ADDR_TYPE,
-		 UNICAST_ADDRESS);
-	SET_FLAG(tx_start_bd->general_data,
 		 ETH_TX_START_BD_HDR_NBDS,
 		 1);
+	SET_FLAG(tx_start_bd->general_data,
+		 ETH_TX_START_BD_PARSE_NBDS,
+		 0);
 
 	/* turn on parsing and get a BD */
 	bd_prod = TX_BD(NEXT_TX_IDX(bd_prod));
 
-	pbd_e1x = &txdata->tx_desc_ring[bd_prod].parse_bd_e1x;
-	pbd_e2 = &txdata->tx_desc_ring[bd_prod].parse_bd_e2;
-
-	memset(pbd_e2, 0, sizeof(struct eth_tx_parse_bd_e2));
-	memset(pbd_e1x, 0, sizeof(struct eth_tx_parse_bd_e1x));
-
+	if (CHIP_IS_E1x(bp)) {
+		u16 global_data = 0;
+		struct eth_tx_parse_bd_e1x  *pbd_e1x =
+			&txdata->tx_desc_ring[bd_prod].parse_bd_e1x;
+		memset(pbd_e1x, 0, sizeof(struct eth_tx_parse_bd_e1x));
+		SET_FLAG(global_data,
+			 ETH_TX_PARSE_BD_E1X_ETH_ADDR_TYPE, UNICAST_ADDRESS);
+		pbd_e1x->global_data = cpu_to_le16(global_data);
+	} else {
+		u32 parsing_data = 0;
+		struct eth_tx_parse_bd_e2  *pbd_e2 =
+			&txdata->tx_desc_ring[bd_prod].parse_bd_e2;
+		memset(pbd_e2, 0, sizeof(struct eth_tx_parse_bd_e2));
+		SET_FLAG(parsing_data,
+			 ETH_TX_PARSE_BD_E2_ETH_ADDR_TYPE, UNICAST_ADDRESS);
+		pbd_e2->parsing_data = cpu_to_le32(parsing_data);
+	}
 	wmb();
 
 	txdata->tx_db.data.prod += 2;
diff --git a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_fw_defs.h b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_fw_defs.h
index bbc66ce..620fe93 100644
--- a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_fw_defs.h
+++ b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_fw_defs.h
@@ -88,9 +88,6 @@
 #define TSTORM_ASSERT_LIST_INDEX_OFFSET	(IRO[102].base)
 #define TSTORM_ASSERT_LIST_OFFSET(assertListEntry) \
 	(IRO[101].base + ((assertListEntry) * IRO[101].m1))
-#define TSTORM_COMMON_SAFC_WORKAROUND_ENABLE_OFFSET (IRO[107].base)
-#define TSTORM_COMMON_SAFC_WORKAROUND_TIMEOUT_10USEC_OFFSET \
-	(IRO[108].base)
 #define TSTORM_FUNCTION_COMMON_CONFIG_OFFSET(pfId) \
 	(IRO[201].base + ((pfId) * IRO[201].m1))
 #define TSTORM_FUNC_EN_OFFSET(funcId) \
diff --git a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_hsi.h b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_hsi.h
index c795cfc..1870492 100644
--- a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_hsi.h
+++ b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_hsi.h
@@ -2789,8 +2789,8 @@ struct afex_stats {
 };
 
 #define BCM_5710_FW_MAJOR_VERSION			7
-#define BCM_5710_FW_MINOR_VERSION			2
-#define BCM_5710_FW_REVISION_VERSION			51
+#define BCM_5710_FW_MINOR_VERSION			8
+#define BCM_5710_FW_REVISION_VERSION		2
 #define BCM_5710_FW_ENGINEERING_VERSION			0
 #define BCM_5710_FW_COMPILE_FLAGS			1
 
@@ -3912,10 +3912,8 @@ struct eth_rss_update_ramrod_data {
 #define ETH_RSS_UPDATE_RAMROD_DATA_IPV6_TCP_CAPABILITY_SHIFT 4
 #define ETH_RSS_UPDATE_RAMROD_DATA_IPV6_UDP_CAPABILITY (0x1<<5)
 #define ETH_RSS_UPDATE_RAMROD_DATA_IPV6_UDP_CAPABILITY_SHIFT 5
-#define ETH_RSS_UPDATE_RAMROD_DATA_UPDATE_RSS_KEY (0x1<<6)
-#define ETH_RSS_UPDATE_RAMROD_DATA_UPDATE_RSS_KEY_SHIFT 6
-#define __ETH_RSS_UPDATE_RAMROD_DATA_RESERVED0 (0x1<<7)
-#define __ETH_RSS_UPDATE_RAMROD_DATA_RESERVED0_SHIFT 7
+#define ETH_RSS_UPDATE_RAMROD_DATA_UPDATE_RSS_KEY (0x1<<7)
+#define ETH_RSS_UPDATE_RAMROD_DATA_UPDATE_RSS_KEY_SHIFT 7
 	u8 rss_result_mask;
 	u8 rss_mode;
 	__le32 __reserved2;
@@ -4131,27 +4129,29 @@ struct eth_tx_start_bd {
 #define ETH_TX_START_BD_HDR_NBDS_SHIFT 0
 #define ETH_TX_START_BD_FORCE_VLAN_MODE (0x1<<4)
 #define ETH_TX_START_BD_FORCE_VLAN_MODE_SHIFT 4
-#define ETH_TX_START_BD_RESREVED (0x1<<5)
-#define ETH_TX_START_BD_RESREVED_SHIFT 5
-#define ETH_TX_START_BD_ETH_ADDR_TYPE (0x3<<6)
-#define ETH_TX_START_BD_ETH_ADDR_TYPE_SHIFT 6
+#define ETH_TX_START_BD_PARSE_NBDS (0x3<<5)
+#define ETH_TX_START_BD_PARSE_NBDS_SHIFT 5
+#define ETH_TX_START_BD_RESREVED (0x1<<7)
+#define ETH_TX_START_BD_RESREVED_SHIFT 7
 };
 
 /*
  * Tx parsing BD structure for ETH E1/E1h
  */
 struct eth_tx_parse_bd_e1x {
-	u8 global_data;
+	__le16 global_data;
 #define ETH_TX_PARSE_BD_E1X_IP_HDR_START_OFFSET_W (0xF<<0)
 #define ETH_TX_PARSE_BD_E1X_IP_HDR_START_OFFSET_W_SHIFT 0
-#define ETH_TX_PARSE_BD_E1X_RESERVED0 (0x1<<4)
-#define ETH_TX_PARSE_BD_E1X_RESERVED0_SHIFT 4
-#define ETH_TX_PARSE_BD_E1X_PSEUDO_CS_WITHOUT_LEN (0x1<<5)
-#define ETH_TX_PARSE_BD_E1X_PSEUDO_CS_WITHOUT_LEN_SHIFT 5
-#define ETH_TX_PARSE_BD_E1X_LLC_SNAP_EN (0x1<<6)
-#define ETH_TX_PARSE_BD_E1X_LLC_SNAP_EN_SHIFT 6
-#define ETH_TX_PARSE_BD_E1X_NS_FLG (0x1<<7)
-#define ETH_TX_PARSE_BD_E1X_NS_FLG_SHIFT 7
+#define ETH_TX_PARSE_BD_E1X_ETH_ADDR_TYPE (0x3<<4)
+#define ETH_TX_PARSE_BD_E1X_ETH_ADDR_TYPE_SHIFT 4
+#define ETH_TX_PARSE_BD_E1X_PSEUDO_CS_WITHOUT_LEN (0x1<<6)
+#define ETH_TX_PARSE_BD_E1X_PSEUDO_CS_WITHOUT_LEN_SHIFT 6
+#define ETH_TX_PARSE_BD_E1X_LLC_SNAP_EN (0x1<<7)
+#define ETH_TX_PARSE_BD_E1X_LLC_SNAP_EN_SHIFT 7
+#define ETH_TX_PARSE_BD_E1X_NS_FLG (0x1<<8)
+#define ETH_TX_PARSE_BD_E1X_NS_FLG_SHIFT 8
+#define ETH_TX_PARSE_BD_E1X_RESERVED0 (0x7F<<9)
+#define ETH_TX_PARSE_BD_E1X_RESERVED0_SHIFT 9
 	u8 tcp_flags;
 #define ETH_TX_PARSE_BD_E1X_FIN_FLG (0x1<<0)
 #define ETH_TX_PARSE_BD_E1X_FIN_FLG_SHIFT 0
@@ -4170,7 +4170,6 @@ struct eth_tx_parse_bd_e1x {
 #define ETH_TX_PARSE_BD_E1X_CWR_FLG (0x1<<7)
 #define ETH_TX_PARSE_BD_E1X_CWR_FLG_SHIFT 7
 	u8 ip_hlen_w;
-	s8 reserved;
 	__le16 total_hlen_w;
 	__le16 tcp_pseudo_csum;
 	__le16 lso_mss;
@@ -4189,14 +4188,16 @@ struct eth_tx_parse_bd_e2 {
 	__le16 src_mac_addr_mid;
 	__le16 src_mac_addr_hi;
 	__le32 parsing_data;
-#define ETH_TX_PARSE_BD_E2_TCP_HDR_START_OFFSET_W (0x1FFF<<0)
+#define ETH_TX_PARSE_BD_E2_TCP_HDR_START_OFFSET_W (0x7FF<<0)
 #define ETH_TX_PARSE_BD_E2_TCP_HDR_START_OFFSET_W_SHIFT 0
-#define ETH_TX_PARSE_BD_E2_TCP_HDR_LENGTH_DW (0xF<<13)
-#define ETH_TX_PARSE_BD_E2_TCP_HDR_LENGTH_DW_SHIFT 13
-#define ETH_TX_PARSE_BD_E2_LSO_MSS (0x3FFF<<17)
-#define ETH_TX_PARSE_BD_E2_LSO_MSS_SHIFT 17
-#define ETH_TX_PARSE_BD_E2_IPV6_WITH_EXT_HDR (0x1<<31)
-#define ETH_TX_PARSE_BD_E2_IPV6_WITH_EXT_HDR_SHIFT 31
+#define ETH_TX_PARSE_BD_E2_TCP_HDR_LENGTH_DW (0xF<<11)
+#define ETH_TX_PARSE_BD_E2_TCP_HDR_LENGTH_DW_SHIFT 11
+#define ETH_TX_PARSE_BD_E2_IPV6_WITH_EXT_HDR (0x1<<15)
+#define ETH_TX_PARSE_BD_E2_IPV6_WITH_EXT_HDR_SHIFT 15
+#define ETH_TX_PARSE_BD_E2_LSO_MSS (0x3FFF<<16)
+#define ETH_TX_PARSE_BD_E2_LSO_MSS_SHIFT 16
+#define ETH_TX_PARSE_BD_E2_ETH_ADDR_TYPE (0x3<<30)
+#define ETH_TX_PARSE_BD_E2_ETH_ADDR_TYPE_SHIFT 30
 };
 
 /*
@@ -4964,7 +4965,8 @@ struct flow_control_configuration {
  *
  */
 struct function_start_data {
-	__le16 function_mode;
+	u8 function_mode;
+	u8 reserved;
 	__le16 sd_vlan_tag;
 	__le16 vif_id;
 	u8 path_id;
diff --git a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_init.h b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_init.h
index 559c396..c8f10f0 100644
--- a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_init.h
+++ b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_init.h
@@ -566,7 +566,7 @@ static const struct {
 		u32 e2;		/* 57712 */
 		u32 e3;		/* 578xx */
 	} reg_mask;		/* Register mask (all valid bits) */
-	char name[7];		/* Block's longest name is 6 characters long
+	char name[8];		/* Block's longest name is 7 characters long
 				 * (name + suffix)
 				 */
 } bnx2x_blocks_parity_data[] = {
diff --git a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_link.c b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_link.c
index bcc112b..e2e45ee 100644
--- a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_link.c
+++ b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_link.c
@@ -161,120 +161,6 @@
 #define EDC_MODE_LIMITING				0x0044
 #define EDC_MODE_PASSIVE_DAC			0x0055
 
-/* BRB default for class 0 E2 */
-#define DEFAULT0_E2_BRB_MAC_PAUSE_XOFF_THR	170
-#define DEFAULT0_E2_BRB_MAC_PAUSE_XON_THR		250
-#define DEFAULT0_E2_BRB_MAC_FULL_XOFF_THR		10
-#define DEFAULT0_E2_BRB_MAC_FULL_XON_THR		50
-
-/* BRB thresholds for E2*/
-#define PFC_E2_BRB_MAC_PAUSE_XOFF_THR_PAUSE		170
-#define PFC_E2_BRB_MAC_PAUSE_XOFF_THR_NON_PAUSE		0
-
-#define PFC_E2_BRB_MAC_PAUSE_XON_THR_PAUSE		250
-#define PFC_E2_BRB_MAC_PAUSE_XON_THR_NON_PAUSE		0
-
-#define PFC_E2_BRB_MAC_FULL_XOFF_THR_PAUSE		10
-#define PFC_E2_BRB_MAC_FULL_XOFF_THR_NON_PAUSE		90
-
-#define PFC_E2_BRB_MAC_FULL_XON_THR_PAUSE			50
-#define PFC_E2_BRB_MAC_FULL_XON_THR_NON_PAUSE		250
-
-/* BRB default for class 0 E3A0 */
-#define DEFAULT0_E3A0_BRB_MAC_PAUSE_XOFF_THR	290
-#define DEFAULT0_E3A0_BRB_MAC_PAUSE_XON_THR	410
-#define DEFAULT0_E3A0_BRB_MAC_FULL_XOFF_THR	10
-#define DEFAULT0_E3A0_BRB_MAC_FULL_XON_THR	50
-
-/* BRB thresholds for E3A0 */
-#define PFC_E3A0_BRB_MAC_PAUSE_XOFF_THR_PAUSE		290
-#define PFC_E3A0_BRB_MAC_PAUSE_XOFF_THR_NON_PAUSE		0
-
-#define PFC_E3A0_BRB_MAC_PAUSE_XON_THR_PAUSE		410
-#define PFC_E3A0_BRB_MAC_PAUSE_XON_THR_NON_PAUSE		0
-
-#define PFC_E3A0_BRB_MAC_FULL_XOFF_THR_PAUSE		10
-#define PFC_E3A0_BRB_MAC_FULL_XOFF_THR_NON_PAUSE		170
-
-#define PFC_E3A0_BRB_MAC_FULL_XON_THR_PAUSE		50
-#define PFC_E3A0_BRB_MAC_FULL_XON_THR_NON_PAUSE		410
-
-/* BRB default for E3B0 */
-#define DEFAULT0_E3B0_BRB_MAC_PAUSE_XOFF_THR	330
-#define DEFAULT0_E3B0_BRB_MAC_PAUSE_XON_THR	490
-#define DEFAULT0_E3B0_BRB_MAC_FULL_XOFF_THR	15
-#define DEFAULT0_E3B0_BRB_MAC_FULL_XON_THR	55
-
-/* BRB thresholds for E3B0 2 port mode*/
-#define PFC_E3B0_2P_BRB_MAC_PAUSE_XOFF_THR_PAUSE		1025
-#define PFC_E3B0_2P_BRB_MAC_PAUSE_XOFF_THR_NON_PAUSE	0
-
-#define PFC_E3B0_2P_BRB_MAC_PAUSE_XON_THR_PAUSE		1025
-#define PFC_E3B0_2P_BRB_MAC_PAUSE_XON_THR_NON_PAUSE	0
-
-#define PFC_E3B0_2P_BRB_MAC_FULL_XOFF_THR_PAUSE		10
-#define PFC_E3B0_2P_BRB_MAC_FULL_XOFF_THR_NON_PAUSE	1025
-
-#define PFC_E3B0_2P_BRB_MAC_FULL_XON_THR_PAUSE		50
-#define PFC_E3B0_2P_BRB_MAC_FULL_XON_THR_NON_PAUSE	1025
-
-/* only for E3B0*/
-#define PFC_E3B0_2P_BRB_FULL_LB_XOFF_THR			1025
-#define PFC_E3B0_2P_BRB_FULL_LB_XON_THR			1025
-
-/* Lossy +Lossless GUARANTIED == GUART */
-#define PFC_E3B0_2P_MIX_PAUSE_LB_GUART			284
-/* Lossless +Lossless*/
-#define PFC_E3B0_2P_PAUSE_LB_GUART			236
-/* Lossy +Lossy*/
-#define PFC_E3B0_2P_NON_PAUSE_LB_GUART			342
-
-/* Lossy +Lossless*/
-#define PFC_E3B0_2P_MIX_PAUSE_MAC_0_CLASS_T_GUART		284
-/* Lossless +Lossless*/
-#define PFC_E3B0_2P_PAUSE_MAC_0_CLASS_T_GUART		236
-/* Lossy +Lossy*/
-#define PFC_E3B0_2P_NON_PAUSE_MAC_0_CLASS_T_GUART		336
-#define PFC_E3B0_2P_BRB_MAC_0_CLASS_T_GUART_HYST		80
-
-#define PFC_E3B0_2P_BRB_MAC_1_CLASS_T_GUART		0
-#define PFC_E3B0_2P_BRB_MAC_1_CLASS_T_GUART_HYST		0
-
-/* BRB thresholds for E3B0 4 port mode */
-#define PFC_E3B0_4P_BRB_MAC_PAUSE_XOFF_THR_PAUSE		304
-#define PFC_E3B0_4P_BRB_MAC_PAUSE_XOFF_THR_NON_PAUSE	0
-
-#define PFC_E3B0_4P_BRB_MAC_PAUSE_XON_THR_PAUSE		384
-#define PFC_E3B0_4P_BRB_MAC_PAUSE_XON_THR_NON_PAUSE	0
-
-#define PFC_E3B0_4P_BRB_MAC_FULL_XOFF_THR_PAUSE		10
-#define PFC_E3B0_4P_BRB_MAC_FULL_XOFF_THR_NON_PAUSE	304
-
-#define PFC_E3B0_4P_BRB_MAC_FULL_XON_THR_PAUSE		50
-#define PFC_E3B0_4P_BRB_MAC_FULL_XON_THR_NON_PAUSE	384
-
-/* only for E3B0*/
-#define PFC_E3B0_4P_BRB_FULL_LB_XOFF_THR			304
-#define PFC_E3B0_4P_BRB_FULL_LB_XON_THR			384
-#define PFC_E3B0_4P_LB_GUART		120
-
-#define PFC_E3B0_4P_BRB_MAC_0_CLASS_T_GUART		120
-#define PFC_E3B0_4P_BRB_MAC_0_CLASS_T_GUART_HYST	80
-
-#define PFC_E3B0_4P_BRB_MAC_1_CLASS_T_GUART		80
-#define PFC_E3B0_4P_BRB_MAC_1_CLASS_T_GUART_HYST	120
-
-/* Pause defines*/
-#define DEFAULT_E3B0_BRB_FULL_LB_XOFF_THR			330
-#define DEFAULT_E3B0_BRB_FULL_LB_XON_THR			490
-#define DEFAULT_E3B0_LB_GUART		40
-
-#define DEFAULT_E3B0_BRB_MAC_0_CLASS_T_GUART		40
-#define DEFAULT_E3B0_BRB_MAC_0_CLASS_T_GUART_HYST	0
-
-#define DEFAULT_E3B0_BRB_MAC_1_CLASS_T_GUART		40
-#define DEFAULT_E3B0_BRB_MAC_1_CLASS_T_GUART_HYST	0
-
 /* ETS defines*/
 #define DCBX_INVALID_COS					(0xFF)
 
@@ -2144,391 +2030,6 @@ static void bnx2x_update_pfc_bmac2(struct link_params *params,
 	REG_WR_DMAE(bp, bmac_addr + BIGMAC2_REGISTER_BMAC_CONTROL, wb_data, 2);
 }
 
-/* PFC BRB internal port configuration params */
-struct bnx2x_pfc_brb_threshold_val {
-	u32 pause_xoff;
-	u32 pause_xon;
-	u32 full_xoff;
-	u32 full_xon;
-};
-
-struct bnx2x_pfc_brb_e3b0_val {
-	u32 per_class_guaranty_mode;
-	u32 lb_guarantied_hyst;
-	u32 full_lb_xoff_th;
-	u32 full_lb_xon_threshold;
-	u32 lb_guarantied;
-	u32 mac_0_class_t_guarantied;
-	u32 mac_0_class_t_guarantied_hyst;
-	u32 mac_1_class_t_guarantied;
-	u32 mac_1_class_t_guarantied_hyst;
-};
-
-struct bnx2x_pfc_brb_th_val {
-	struct bnx2x_pfc_brb_threshold_val pauseable_th;
-	struct bnx2x_pfc_brb_threshold_val non_pauseable_th;
-	struct bnx2x_pfc_brb_threshold_val default_class0;
-	struct bnx2x_pfc_brb_threshold_val default_class1;
-
-};
-static int bnx2x_pfc_brb_get_config_params(
-				struct link_params *params,
-				struct bnx2x_pfc_brb_th_val *config_val)
-{
-	struct bnx2x *bp = params->bp;
-	DP(NETIF_MSG_LINK, "Setting PFC BRB configuration\n");
-
-	config_val->default_class1.pause_xoff = 0;
-	config_val->default_class1.pause_xon = 0;
-	config_val->default_class1.full_xoff = 0;
-	config_val->default_class1.full_xon = 0;
-
-	if (CHIP_IS_E2(bp)) {
-		/* Class0 defaults */
-		config_val->default_class0.pause_xoff =
-			DEFAULT0_E2_BRB_MAC_PAUSE_XOFF_THR;
-		config_val->default_class0.pause_xon =
-			DEFAULT0_E2_BRB_MAC_PAUSE_XON_THR;
-		config_val->default_class0.full_xoff =
-			DEFAULT0_E2_BRB_MAC_FULL_XOFF_THR;
-		config_val->default_class0.full_xon =
-			DEFAULT0_E2_BRB_MAC_FULL_XON_THR;
-		/* Pause able*/
-		config_val->pauseable_th.pause_xoff =
-			PFC_E2_BRB_MAC_PAUSE_XOFF_THR_PAUSE;
-		config_val->pauseable_th.pause_xon =
-			PFC_E2_BRB_MAC_PAUSE_XON_THR_PAUSE;
-		config_val->pauseable_th.full_xoff =
-			PFC_E2_BRB_MAC_FULL_XOFF_THR_PAUSE;
-		config_val->pauseable_th.full_xon =
-			PFC_E2_BRB_MAC_FULL_XON_THR_PAUSE;
-		/* Non pause able*/
-		config_val->non_pauseable_th.pause_xoff =
-			PFC_E2_BRB_MAC_PAUSE_XOFF_THR_NON_PAUSE;
-		config_val->non_pauseable_th.pause_xon =
-			PFC_E2_BRB_MAC_PAUSE_XON_THR_NON_PAUSE;
-		config_val->non_pauseable_th.full_xoff =
-			PFC_E2_BRB_MAC_FULL_XOFF_THR_NON_PAUSE;
-		config_val->non_pauseable_th.full_xon =
-			PFC_E2_BRB_MAC_FULL_XON_THR_NON_PAUSE;
-	} else if (CHIP_IS_E3A0(bp)) {
-		/* Class0 defaults */
-		config_val->default_class0.pause_xoff =
-			DEFAULT0_E3A0_BRB_MAC_PAUSE_XOFF_THR;
-		config_val->default_class0.pause_xon =
-			DEFAULT0_E3A0_BRB_MAC_PAUSE_XON_THR;
-		config_val->default_class0.full_xoff =
-			DEFAULT0_E3A0_BRB_MAC_FULL_XOFF_THR;
-		config_val->default_class0.full_xon =
-			DEFAULT0_E3A0_BRB_MAC_FULL_XON_THR;
-		/* Pause able */
-		config_val->pauseable_th.pause_xoff =
-			PFC_E3A0_BRB_MAC_PAUSE_XOFF_THR_PAUSE;
-		config_val->pauseable_th.pause_xon =
-			PFC_E3A0_BRB_MAC_PAUSE_XON_THR_PAUSE;
-		config_val->pauseable_th.full_xoff =
-			PFC_E3A0_BRB_MAC_FULL_XOFF_THR_PAUSE;
-		config_val->pauseable_th.full_xon =
-			PFC_E3A0_BRB_MAC_FULL_XON_THR_PAUSE;
-		/* Non pause able*/
-		config_val->non_pauseable_th.pause_xoff =
-			PFC_E3A0_BRB_MAC_PAUSE_XOFF_THR_NON_PAUSE;
-		config_val->non_pauseable_th.pause_xon =
-			PFC_E3A0_BRB_MAC_PAUSE_XON_THR_NON_PAUSE;
-		config_val->non_pauseable_th.full_xoff =
-			PFC_E3A0_BRB_MAC_FULL_XOFF_THR_NON_PAUSE;
-		config_val->non_pauseable_th.full_xon =
-			PFC_E3A0_BRB_MAC_FULL_XON_THR_NON_PAUSE;
-	} else if (CHIP_IS_E3B0(bp)) {
-		/* Class0 defaults */
-		config_val->default_class0.pause_xoff =
-			DEFAULT0_E3B0_BRB_MAC_PAUSE_XOFF_THR;
-		config_val->default_class0.pause_xon =
-		    DEFAULT0_E3B0_BRB_MAC_PAUSE_XON_THR;
-		config_val->default_class0.full_xoff =
-		    DEFAULT0_E3B0_BRB_MAC_FULL_XOFF_THR;
-		config_val->default_class0.full_xon =
-		    DEFAULT0_E3B0_BRB_MAC_FULL_XON_THR;
-
-		if (params->phy[INT_PHY].flags &
-		    FLAGS_4_PORT_MODE) {
-			config_val->pauseable_th.pause_xoff =
-				PFC_E3B0_4P_BRB_MAC_PAUSE_XOFF_THR_PAUSE;
-			config_val->pauseable_th.pause_xon =
-				PFC_E3B0_4P_BRB_MAC_PAUSE_XON_THR_PAUSE;
-			config_val->pauseable_th.full_xoff =
-				PFC_E3B0_4P_BRB_MAC_FULL_XOFF_THR_PAUSE;
-			config_val->pauseable_th.full_xon =
-				PFC_E3B0_4P_BRB_MAC_FULL_XON_THR_PAUSE;
-			/* Non pause able*/
-			config_val->non_pauseable_th.pause_xoff =
-			PFC_E3B0_4P_BRB_MAC_PAUSE_XOFF_THR_NON_PAUSE;
-			config_val->non_pauseable_th.pause_xon =
-			PFC_E3B0_4P_BRB_MAC_PAUSE_XON_THR_NON_PAUSE;
-			config_val->non_pauseable_th.full_xoff =
-			PFC_E3B0_4P_BRB_MAC_FULL_XOFF_THR_NON_PAUSE;
-			config_val->non_pauseable_th.full_xon =
-			PFC_E3B0_4P_BRB_MAC_FULL_XON_THR_NON_PAUSE;
-		} else {
-			config_val->pauseable_th.pause_xoff =
-				PFC_E3B0_2P_BRB_MAC_PAUSE_XOFF_THR_PAUSE;
-			config_val->pauseable_th.pause_xon =
-				PFC_E3B0_2P_BRB_MAC_PAUSE_XON_THR_PAUSE;
-			config_val->pauseable_th.full_xoff =
-				PFC_E3B0_2P_BRB_MAC_FULL_XOFF_THR_PAUSE;
-			config_val->pauseable_th.full_xon =
-				PFC_E3B0_2P_BRB_MAC_FULL_XON_THR_PAUSE;
-			/* Non pause able*/
-			config_val->non_pauseable_th.pause_xoff =
-				PFC_E3B0_2P_BRB_MAC_PAUSE_XOFF_THR_NON_PAUSE;
-			config_val->non_pauseable_th.pause_xon =
-				PFC_E3B0_2P_BRB_MAC_PAUSE_XON_THR_NON_PAUSE;
-			config_val->non_pauseable_th.full_xoff =
-				PFC_E3B0_2P_BRB_MAC_FULL_XOFF_THR_NON_PAUSE;
-			config_val->non_pauseable_th.full_xon =
-				PFC_E3B0_2P_BRB_MAC_FULL_XON_THR_NON_PAUSE;
-		}
-	} else
-	    return -EINVAL;
-
-	return 0;
-}
-
-static void bnx2x_pfc_brb_get_e3b0_config_params(
-		struct link_params *params,
-		struct bnx2x_pfc_brb_e3b0_val
-		*e3b0_val,
-		struct bnx2x_nig_brb_pfc_port_params *pfc_params,
-		const u8 pfc_enabled)
-{
-	if (pfc_enabled && pfc_params) {
-		e3b0_val->per_class_guaranty_mode = 1;
-		e3b0_val->lb_guarantied_hyst = 80;
-
-		if (params->phy[INT_PHY].flags &
-		    FLAGS_4_PORT_MODE) {
-			e3b0_val->full_lb_xoff_th =
-				PFC_E3B0_4P_BRB_FULL_LB_XOFF_THR;
-			e3b0_val->full_lb_xon_threshold =
-				PFC_E3B0_4P_BRB_FULL_LB_XON_THR;
-			e3b0_val->lb_guarantied =
-				PFC_E3B0_4P_LB_GUART;
-			e3b0_val->mac_0_class_t_guarantied =
-				PFC_E3B0_4P_BRB_MAC_0_CLASS_T_GUART;
-			e3b0_val->mac_0_class_t_guarantied_hyst =
-				PFC_E3B0_4P_BRB_MAC_0_CLASS_T_GUART_HYST;
-			e3b0_val->mac_1_class_t_guarantied =
-				PFC_E3B0_4P_BRB_MAC_1_CLASS_T_GUART;
-			e3b0_val->mac_1_class_t_guarantied_hyst =
-				PFC_E3B0_4P_BRB_MAC_1_CLASS_T_GUART_HYST;
-		} else {
-			e3b0_val->full_lb_xoff_th =
-				PFC_E3B0_2P_BRB_FULL_LB_XOFF_THR;
-			e3b0_val->full_lb_xon_threshold =
-				PFC_E3B0_2P_BRB_FULL_LB_XON_THR;
-			e3b0_val->mac_0_class_t_guarantied_hyst =
-				PFC_E3B0_2P_BRB_MAC_0_CLASS_T_GUART_HYST;
-			e3b0_val->mac_1_class_t_guarantied =
-				PFC_E3B0_2P_BRB_MAC_1_CLASS_T_GUART;
-			e3b0_val->mac_1_class_t_guarantied_hyst =
-				PFC_E3B0_2P_BRB_MAC_1_CLASS_T_GUART_HYST;
-
-			if (pfc_params->cos0_pauseable !=
-				pfc_params->cos1_pauseable) {
-				/* Nonpauseable= Lossy + pauseable = Lossless*/
-				e3b0_val->lb_guarantied =
-					PFC_E3B0_2P_MIX_PAUSE_LB_GUART;
-				e3b0_val->mac_0_class_t_guarantied =
-			       PFC_E3B0_2P_MIX_PAUSE_MAC_0_CLASS_T_GUART;
-			} else if (pfc_params->cos0_pauseable) {
-				/* Lossless +Lossless*/
-				e3b0_val->lb_guarantied =
-					PFC_E3B0_2P_PAUSE_LB_GUART;
-				e3b0_val->mac_0_class_t_guarantied =
-				   PFC_E3B0_2P_PAUSE_MAC_0_CLASS_T_GUART;
-			} else {
-				/* Lossy +Lossy*/
-				e3b0_val->lb_guarantied =
-					PFC_E3B0_2P_NON_PAUSE_LB_GUART;
-				e3b0_val->mac_0_class_t_guarantied =
-			       PFC_E3B0_2P_NON_PAUSE_MAC_0_CLASS_T_GUART;
-			}
-		}
-	} else {
-		e3b0_val->per_class_guaranty_mode = 0;
-		e3b0_val->lb_guarantied_hyst = 0;
-		e3b0_val->full_lb_xoff_th =
-			DEFAULT_E3B0_BRB_FULL_LB_XOFF_THR;
-		e3b0_val->full_lb_xon_threshold =
-			DEFAULT_E3B0_BRB_FULL_LB_XON_THR;
-		e3b0_val->lb_guarantied =
-			DEFAULT_E3B0_LB_GUART;
-		e3b0_val->mac_0_class_t_guarantied =
-			DEFAULT_E3B0_BRB_MAC_0_CLASS_T_GUART;
-		e3b0_val->mac_0_class_t_guarantied_hyst =
-			DEFAULT_E3B0_BRB_MAC_0_CLASS_T_GUART_HYST;
-		e3b0_val->mac_1_class_t_guarantied =
-			DEFAULT_E3B0_BRB_MAC_1_CLASS_T_GUART;
-		e3b0_val->mac_1_class_t_guarantied_hyst =
-			DEFAULT_E3B0_BRB_MAC_1_CLASS_T_GUART_HYST;
-	}
-}
-static int bnx2x_update_pfc_brb(struct link_params *params,
-				struct link_vars *vars,
-				struct bnx2x_nig_brb_pfc_port_params
-				*pfc_params)
-{
-	struct bnx2x *bp = params->bp;
-	struct bnx2x_pfc_brb_th_val config_val = { {0} };
-	struct bnx2x_pfc_brb_threshold_val *reg_th_config =
-		&config_val.pauseable_th;
-	struct bnx2x_pfc_brb_e3b0_val e3b0_val = {0};
-	const int set_pfc = params->feature_config_flags &
-		FEATURE_CONFIG_PFC_ENABLED;
-	const u8 pfc_enabled = (set_pfc && pfc_params);
-	int bnx2x_status = 0;
-	u8 port = params->port;
-
-	/* default - pause configuration */
-	reg_th_config = &config_val.pauseable_th;
-	bnx2x_status = bnx2x_pfc_brb_get_config_params(params, &config_val);
-	if (bnx2x_status)
-		return bnx2x_status;
-
-	if (pfc_enabled) {
-		/* First COS */
-		if (pfc_params->cos0_pauseable)
-			reg_th_config = &config_val.pauseable_th;
-		else
-			reg_th_config = &config_val.non_pauseable_th;
-	} else
-		reg_th_config = &config_val.default_class0;
-	/* The number of free blocks below which the pause signal to class 0
-	 * of MAC #n is asserted. n=0,1
-	 */
-	REG_WR(bp, (port) ? BRB1_REG_PAUSE_0_XOFF_THRESHOLD_1 :
-	       BRB1_REG_PAUSE_0_XOFF_THRESHOLD_0 ,
-	       reg_th_config->pause_xoff);
-	/* The number of free blocks above which the pause signal to class 0
-	 * of MAC #n is de-asserted. n=0,1
-	 */
-	REG_WR(bp, (port) ? BRB1_REG_PAUSE_0_XON_THRESHOLD_1 :
-	       BRB1_REG_PAUSE_0_XON_THRESHOLD_0 , reg_th_config->pause_xon);
-	/* The number of free blocks below which the full signal to class 0
-	 * of MAC #n is asserted. n=0,1
-	 */
-	REG_WR(bp, (port) ? BRB1_REG_FULL_0_XOFF_THRESHOLD_1 :
-	       BRB1_REG_FULL_0_XOFF_THRESHOLD_0 , reg_th_config->full_xoff);
-	/* The number of free blocks above which the full signal to class 0
-	 * of MAC #n is de-asserted. n=0,1
-	 */
-	REG_WR(bp, (port) ? BRB1_REG_FULL_0_XON_THRESHOLD_1 :
-	       BRB1_REG_FULL_0_XON_THRESHOLD_0 , reg_th_config->full_xon);
-
-	if (pfc_enabled) {
-		/* Second COS */
-		if (pfc_params->cos1_pauseable)
-			reg_th_config = &config_val.pauseable_th;
-		else
-			reg_th_config = &config_val.non_pauseable_th;
-	} else
-		reg_th_config = &config_val.default_class1;
-	/* The number of free blocks below which the pause signal to
-	 * class 1 of MAC #n is asserted. n=0,1
-	 */
-	REG_WR(bp, (port) ? BRB1_REG_PAUSE_1_XOFF_THRESHOLD_1 :
-	       BRB1_REG_PAUSE_1_XOFF_THRESHOLD_0,
-	       reg_th_config->pause_xoff);
-
-	/* The number of free blocks above which the pause signal to
-	 * class 1 of MAC #n is de-asserted. n=0,1
-	 */
-	REG_WR(bp, (port) ? BRB1_REG_PAUSE_1_XON_THRESHOLD_1 :
-	       BRB1_REG_PAUSE_1_XON_THRESHOLD_0,
-	       reg_th_config->pause_xon);
-	/* The number of free blocks below which the full signal to
-	 * class 1 of MAC #n is asserted. n=0,1
-	 */
-	REG_WR(bp, (port) ? BRB1_REG_FULL_1_XOFF_THRESHOLD_1 :
-	       BRB1_REG_FULL_1_XOFF_THRESHOLD_0,
-	       reg_th_config->full_xoff);
-	/* The number of free blocks above which the full signal to
-	 * class 1 of MAC #n is de-asserted. n=0,1
-	 */
-	REG_WR(bp, (port) ? BRB1_REG_FULL_1_XON_THRESHOLD_1 :
-	       BRB1_REG_FULL_1_XON_THRESHOLD_0,
-	       reg_th_config->full_xon);
-
-	if (CHIP_IS_E3B0(bp)) {
-		bnx2x_pfc_brb_get_e3b0_config_params(
-			params,
-			&e3b0_val,
-			pfc_params,
-			pfc_enabled);
-
-		REG_WR(bp, BRB1_REG_PER_CLASS_GUARANTY_MODE,
-			   e3b0_val.per_class_guaranty_mode);
-
-		/* The hysteresis on the guarantied buffer space for the Lb
-		 * port before signaling XON.
-		 */
-		REG_WR(bp, BRB1_REG_LB_GUARANTIED_HYST,
-			   e3b0_val.lb_guarantied_hyst);
-
-		/* The number of free blocks below which the full signal to the
-		 * LB port is asserted.
-		 */
-		REG_WR(bp, BRB1_REG_FULL_LB_XOFF_THRESHOLD,
-		       e3b0_val.full_lb_xoff_th);
-		/* The number of free blocks above which the full signal to the
-		 * LB port is de-asserted.
-		 */
-		REG_WR(bp, BRB1_REG_FULL_LB_XON_THRESHOLD,
-		       e3b0_val.full_lb_xon_threshold);
-		/* The number of blocks guarantied for the MAC #n port. n=0,1
-		 */
-
-		/* The number of blocks guarantied for the LB port. */
-		REG_WR(bp, BRB1_REG_LB_GUARANTIED,
-		       e3b0_val.lb_guarantied);
-
-		/* The number of blocks guarantied for the MAC #n port. */
-		REG_WR(bp, BRB1_REG_MAC_GUARANTIED_0,
-		       2 * e3b0_val.mac_0_class_t_guarantied);
-		REG_WR(bp, BRB1_REG_MAC_GUARANTIED_1,
-		       2 * e3b0_val.mac_1_class_t_guarantied);
-		/* The number of blocks guarantied for class #t in MAC0. t=0,1
-		 */
-		REG_WR(bp, BRB1_REG_MAC_0_CLASS_0_GUARANTIED,
-		       e3b0_val.mac_0_class_t_guarantied);
-		REG_WR(bp, BRB1_REG_MAC_0_CLASS_1_GUARANTIED,
-		       e3b0_val.mac_0_class_t_guarantied);
-		/* The hysteresis on the guarantied buffer space for class in
-		 * MAC0.  t=0,1
-		 */
-		REG_WR(bp, BRB1_REG_MAC_0_CLASS_0_GUARANTIED_HYST,
-		       e3b0_val.mac_0_class_t_guarantied_hyst);
-		REG_WR(bp, BRB1_REG_MAC_0_CLASS_1_GUARANTIED_HYST,
-		       e3b0_val.mac_0_class_t_guarantied_hyst);
-
-		/* The number of blocks guarantied for class #t in MAC1.t=0,1
-		 */
-		REG_WR(bp, BRB1_REG_MAC_1_CLASS_0_GUARANTIED,
-		       e3b0_val.mac_1_class_t_guarantied);
-		REG_WR(bp, BRB1_REG_MAC_1_CLASS_1_GUARANTIED,
-		       e3b0_val.mac_1_class_t_guarantied);
-		/* The hysteresis on the guarantied buffer space for class #t
-		 * in MAC1.  t=0,1
-		 */
-		REG_WR(bp, BRB1_REG_MAC_1_CLASS_0_GUARANTIED_HYST,
-		       e3b0_val.mac_1_class_t_guarantied_hyst);
-		REG_WR(bp, BRB1_REG_MAC_1_CLASS_1_GUARANTIED_HYST,
-		       e3b0_val.mac_1_class_t_guarantied_hyst);
-	}
-
-	return bnx2x_status;
-}
-
 /******************************************************************************
 * Description:
 *  This function is needed because NIG ARB_CREDIT_WEIGHT_X are
@@ -2705,11 +2206,6 @@ int bnx2x_update_pfc(struct link_params *params,
 	/* Update NIG params */
 	bnx2x_update_pfc_nig(params, vars, pfc_params);
 
-	/* Update BRB params */
-	bnx2x_status = bnx2x_update_pfc_brb(params, vars, pfc_params);
-	if (bnx2x_status)
-		return bnx2x_status;
-
 	if (!vars->link_up)
 		return bnx2x_status;
 
diff --git a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_sp.c b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_sp.c
index 5a5fbf5..71971a1 100644
--- a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_sp.c
+++ b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_sp.c
@@ -5619,7 +5619,7 @@ static inline int bnx2x_func_send_start(struct bnx2x *bp,
 	memset(rdata, 0, sizeof(*rdata));
 
 	/* Fill the ramrod data with provided parameters */
-	rdata->function_mode = cpu_to_le16(start_params->mf_mode);
+	rdata->function_mode = (u8)start_params->mf_mode;
 	rdata->sd_vlan_tag   = cpu_to_le16(start_params->sd_vlan_tag);
 	rdata->path_id       = BP_PATH(bp);
 	rdata->network_cos_mode = start_params->network_cos_mode;
diff --git a/drivers/net/ethernet/broadcom/cnic.c b/drivers/net/ethernet/broadcom/cnic.c
index 2107d79..cc8434f 100644
--- a/drivers/net/ethernet/broadcom/cnic.c
+++ b/drivers/net/ethernet/broadcom/cnic.c
@@ -4891,6 +4891,9 @@ static void cnic_init_bnx2x_tx_ring(struct cnic_dev *dev,
 	buf_map = udev->l2_buf_map;
 	for (i = 0; i < MAX_TX_DESC_CNT; i += 3, txbd += 3) {
 		struct eth_tx_start_bd *start_bd = &txbd->start_bd;
+		struct eth_tx_parse_bd_e1x *pbd_e1x =
+			&((txbd + 1)->parse_bd_e1x);
+		struct eth_tx_parse_bd_e2 *pbd_e2 = &((txbd + 1)->parse_bd_e2);
 		struct eth_tx_bd *reg_bd = &((txbd + 2)->reg_bd);
 
 		start_bd->addr_hi = cpu_to_le32((u64) buf_map >> 32);
@@ -4900,10 +4903,15 @@ static void cnic_init_bnx2x_tx_ring(struct cnic_dev *dev,
 		start_bd->nbytes = cpu_to_le16(0x10);
 		start_bd->nbd = cpu_to_le16(3);
 		start_bd->bd_flags.as_bitfield = ETH_TX_BD_FLAGS_START_BD;
-		start_bd->general_data = (UNICAST_ADDRESS <<
-			ETH_TX_START_BD_ETH_ADDR_TYPE_SHIFT);
+		start_bd->general_data &= ~ETH_TX_START_BD_PARSE_NBDS;
 		start_bd->general_data |= (1 << ETH_TX_START_BD_HDR_NBDS_SHIFT);
 
+		if (BNX2X_CHIP_IS_E2_PLUS(cp->chip_id))
+			pbd_e2->parsing_data = (UNICAST_ADDRESS <<
+				 ETH_TX_PARSE_BD_E2_ETH_ADDR_TYPE_SHIFT);
+		else
+			 pbd_e1x->global_data = (UNICAST_ADDRESS <<
+				ETH_TX_PARSE_BD_E1X_ETH_ADDR_TYPE_SHIFT);
 	}
 
 	val = (u64) ring_map >> 32;
diff --git a/drivers/net/ethernet/broadcom/cnic_defs.h b/drivers/net/ethernet/broadcom/cnic_defs.h
index 382c98b..ede3db3 100644
--- a/drivers/net/ethernet/broadcom/cnic_defs.h
+++ b/drivers/net/ethernet/broadcom/cnic_defs.h
@@ -896,7 +896,7 @@ struct tstorm_tcp_tcp_ag_context_section {
 	u32 snd_nxt;
 	u32 rtt_seq;
 	u32 rtt_time;
-	u32 __reserved66;
+	u32 wnd_right_edge_local;
 	u32 wnd_right_edge;
 	u32 tcp_agg_vars1;
 #define TSTORM_TCP_TCP_AG_CONTEXT_SECTION_FIN_SENT_FLAG (0x1<<0)
diff --git a/drivers/net/ethernet/broadcom/cnic_if.h b/drivers/net/ethernet/broadcom/cnic_if.h
index 2e92c34..865095a 100644
--- a/drivers/net/ethernet/broadcom/cnic_if.h
+++ b/drivers/net/ethernet/broadcom/cnic_if.h
@@ -14,8 +14,8 @@
 
 #include "bnx2x/bnx2x_mfw_req.h"
 
-#define CNIC_MODULE_VERSION	"2.5.13"
-#define CNIC_MODULE_RELDATE	"Sep 07, 2012"
+#define CNIC_MODULE_VERSION	"2.5.14"
+#define CNIC_MODULE_RELDATE	"Sep 30, 2012"
 
 #define CNIC_ULP_RDMA		0
 #define CNIC_ULP_ISCSI		1
-- 
1.7.1

^ permalink raw reply related

* RE: Please am dying of breast cancer !!!
From: Mrs. Maria Bristow @ 2012-10-01 12:36 UTC (permalink / raw)
  To: Recipients

Hello,

Am dying of breast cancer and I need your assistance to help me carry out my dream charity work with my funds €2.8M Euros with a Security firm, if you are interested please reach me for more details on this email: maria.bristow@1email.eu

Yours Sincerely,
Mrs. Maria Bristow

^ permalink raw reply

* [PATCH 2/2] tg3: fix build-time dependency with IS_DEPENDENCY_SATISFIED()
From: Anisse Astier @ 2012-10-01 12:21 UTC (permalink / raw)
  To: linux-kernel, netdev
  Cc: Paul Gortmaker, Michal Marek, Linus Torvalds, Michael Chan,
	Matt Carlson, Anisse Astier
In-Reply-To: <1349094080-769-1-git-send-email-anisse@astier.eu>

When CONFIG_TIGON3=y and CONFIG_HWMON=y, we will get this error:
  LD      init/built-in.o
drivers/built-in.o: In function `tg3_hwmon_open':
tg3.c:(.text+0xc1d12): undefined reference to `hwmon_device_register'
drivers/built-in.o: In function `tg3_close':
tg3.c:(.text+0xc2e7f): undefined reference to `hwmon_device_unregister'
make: *** [vmlinux] Error 1

Use the new IS_DEPENDENCY_SATISFIED() facility to solve this problem.

Signed-off-by: Anisse Astier <anisse@astier.eu>
---
 drivers/net/ethernet/broadcom/tg3.c |    8 ++++----
 drivers/net/ethernet/broadcom/tg3.h |    2 +-
 2 files changed, 5 insertions(+), 5 deletions(-)

diff --git a/drivers/net/ethernet/broadcom/tg3.c b/drivers/net/ethernet/broadcom/tg3.c
index bf906c5..cc81a59 100644
--- a/drivers/net/ethernet/broadcom/tg3.c
+++ b/drivers/net/ethernet/broadcom/tg3.c
@@ -44,7 +44,7 @@
 #include <linux/prefetch.h>
 #include <linux/dma-mapping.h>
 #include <linux/firmware.h>
-#if IS_ENABLED(CONFIG_HWMON)
+#if IS_DEPENDENCY_SATISFIED(CONFIG_TIGON3, CONFIG_HWMON)
 #include <linux/hwmon.h>
 #include <linux/hwmon-sysfs.h>
 #endif
@@ -9517,7 +9517,7 @@ static int tg3_init_hw(struct tg3 *tp, int reset_phy)
 	return tg3_reset_hw(tp, reset_phy);
 }
 
-#if IS_ENABLED(CONFIG_HWMON)
+#if IS_DEPENDENCY_SATISFIED(CONFIG_TIGON3, CONFIG_HWMON)
 static void tg3_sd_scan_scratchpad(struct tg3 *tp, struct tg3_ocir *ocir)
 {
 	int i;
@@ -9574,7 +9574,7 @@ static const struct attribute_group tg3_group = {
 
 static void tg3_hwmon_close(struct tg3 *tp)
 {
-#if IS_ENABLED(CONFIG_HWMON)
+#if IS_DEPENDENCY_SATISFIED(CONFIG_TIGON3, CONFIG_HWMON)
 	if (tp->hwmon_dev) {
 		hwmon_device_unregister(tp->hwmon_dev);
 		tp->hwmon_dev = NULL;
@@ -9585,7 +9585,7 @@ static void tg3_hwmon_close(struct tg3 *tp)
 
 static void tg3_hwmon_open(struct tg3 *tp)
 {
-#if IS_ENABLED(CONFIG_HWMON)
+#if IS_DEPENDENCY_SATISFIED(CONFIG_TIGON3, CONFIG_HWMON)
 	int i, err;
 	u32 size = 0;
 	struct pci_dev *pdev = tp->pdev;
diff --git a/drivers/net/ethernet/broadcom/tg3.h b/drivers/net/ethernet/broadcom/tg3.h
index 6d52cb2..867dae1 100644
--- a/drivers/net/ethernet/broadcom/tg3.h
+++ b/drivers/net/ethernet/broadcom/tg3.h
@@ -3252,7 +3252,7 @@ struct tg3 {
 	const struct firmware		*fw;
 	u32				fw_len; /* includes BSS */
 
-#if IS_ENABLED(CONFIG_HWMON)
+#if IS_DEPENDENCY_SATISFIED(CONFIG_TIGON3, CONFIG_HWMON)
 	struct device			*hwmon_dev;
 #endif
 };
-- 
1.7.10.3

^ permalink raw reply related

* [PATCH 1/2] kconfig: Introduce IS_DEPENDENCY_SATISFIED()
From: Anisse Astier @ 2012-10-01 12:21 UTC (permalink / raw)
  To: linux-kernel, netdev
  Cc: Paul Gortmaker, Michal Marek, Linus Torvalds, Michael Chan,
	Matt Carlson, Anisse Astier

Most of the time, when we use IS_ENABLED() it's to specify a dependency
on a config option that might be enabled. But if this option is enabled
as a module, and we are built-in, then we'll have missing symbols.

This new macro is therefore useful to specify a dependency on another
config. But it also needs to know our own config option in order to
check if the dependency is properly satisfied.

IS_DEPENDENCY_SATISFIED(CONFIG_SELF, CONFIG_FOO) evaluates to 1 if
CONFIG_FOO is set to 'y' or 'm', and set the same as CONFIG_SELF. It
evaluates to 0 otherwise.

Signed-off-by: Anisse Astier <anisse@astier.eu>
---
 include/linux/kconfig.h |   10 ++++++++++
 1 file changed, 10 insertions(+)

diff --git a/include/linux/kconfig.h b/include/linux/kconfig.h
index be342b9..8b8ec1f 100644
--- a/include/linux/kconfig.h
+++ b/include/linux/kconfig.h
@@ -43,4 +43,14 @@
  */
 #define IS_MODULE(option) config_enabled(option##_MODULE)
 
+
+/*
+ * IS_DEPENDENCY_SATISFIED(CONFIG_SELF, CONFIG_FOO) evaluates to 1 if
+ * CONFIG_FOO is set to 'y' or 'm', and set the same as CONFIG_SELF.
+ * Useful for specifying build-time config dependencies.
+ */
+#define IS_DEPENDENCY_SATISFIED(self, dependency) \
+	((config_enabled(self) && config_enabled(dependency)) || \
+	 (config_enabled(self##_MODULE) && config_enabled(dependency##_MODULE)))
+
 #endif /* __LINUX_KCONFIG_H */
-- 
1.7.10.3

^ permalink raw reply related

* [PATCH net-next v2] be2net: fix vfs enumeration
From: Ivan Vecera @ 2012-10-01 11:56 UTC (permalink / raw)
  To: netdev; +Cc: sathya.perla, subbu.seetharaman, ajit.khaparde, sfr, davem

Current VFs enumeration algorithm used in be_find_vfs does not take domain
number into the match. The match found in igb/ixgbe is more elegant and
safe.

This 2nd version uses pci_physfn instead of checking dev->physfn directly.

Signed-off-by: Ivan Vecera <ivecera@redhat.com>
---
 drivers/net/ethernet/emulex/benet/be_main.c |    6 ++----
 1 files changed, 2 insertions(+), 4 deletions(-)

diff --git a/drivers/net/ethernet/emulex/benet/be_main.c b/drivers/net/ethernet/emulex/benet/be_main.c
index 6accb0c..8dd42b3 100644
--- a/drivers/net/ethernet/emulex/benet/be_main.c
+++ b/drivers/net/ethernet/emulex/benet/be_main.c
@@ -1075,7 +1075,7 @@ static int be_set_vf_tx_rate(struct net_device *netdev,
 static int be_find_vfs(struct be_adapter *adapter, int vf_state)
 {
 	struct pci_dev *dev, *pdev = adapter->pdev;
-	int vfs = 0, assigned_vfs = 0, pos, vf_fn;
+	int vfs = 0, assigned_vfs = 0, pos;
 	u16 offset, stride;
 
 	pos = pci_find_ext_capability(pdev, PCI_EXT_CAP_ID_SRIOV);
@@ -1086,9 +1086,7 @@ static int be_find_vfs(struct be_adapter *adapter, int vf_state)
 
 	dev = pci_get_device(pdev->vendor, PCI_ANY_ID, NULL);
 	while (dev) {
-		vf_fn = (pdev->devfn + offset + stride * vfs) & 0xFFFF;
-		if (dev->is_virtfn && dev->devfn == vf_fn &&
-			dev->bus->number == pdev->bus->number) {
+		if (dev->is_virtfn && pci_physfn(dev) == pdev) {
 			vfs++;
 			if (dev->dev_flags & PCI_DEV_FLAGS_ASSIGNED)
 				assigned_vfs++;
-- 
1.7.8.6

^ permalink raw reply related

* Re: linux-next: build failure after merge of the net-next tree
From: Ivan Vecera @ 2012-10-01 11:53 UTC (permalink / raw)
  To: David Miller; +Cc: sfr, netdev, linux-next, linux-kernel
In-Reply-To: <20120927.221943.19056434713380159.davem@davemloft.net>

On 09/28/2012 04:19 AM, David Miller wrote:
> From: Stephen Rothwell <sfr@canb.auug.org.au>
> Date: Fri, 28 Sep 2012 11:43:35 +1000
> 
>> Hi all,
>>
>> After merging the net-next tree, today's linux-next build (powerpc
>> ppc64_defconfig) failed like this:
>>
>> drivers/net/ethernet/emulex/benet/be_main.c: In function 'be_find_vfs':
>> drivers/net/ethernet/emulex/benet/be_main.c:1090:28: error: 'struct pci_dev' has no member named 'physfn'
>>
>> Caused by commit 51af6d7c1f31 ("be2net: fix vfs enumeration").  physfn is
>> only defined if CONFIG_PCI_ATS is set.
>>
>> I have reverted that commit for today.
> 
> I'm reverting it too, thanks for reporting Stephen.
> 
Sorry for that, it will be better to use pci_physfn to access this
member. I'll repost the patch.

Ivan

^ permalink raw reply

* Re: [PATCHv2] rtlwifi: rtl8192ce: rtl8192cu: use %*ph[C] to dump small buffers
From: Joe Perches @ 2012-10-01 11:14 UTC (permalink / raw)
  To: Andy Shevchenko
  Cc: Larry Finger, Chaoming Li, David S . Miller, linux-wireless,
	netdev
In-Reply-To: <1349088899-15863-1-git-send-email-andriy.shevchenko@linux.intel.com>

On Mon, 2012-10-01 at 13:54 +0300, Andy Shevchenko wrote:
> Signed-off-by: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
> ACKed-by: Larry Finger <Larry.Finger@lwfinger.net>

Hey Andy.

The conversions are not all the same.
One uses "%*ph", the others use "%*phC"
even though all origin hex formats are "%x:%x:..."
Ideally all the conversions would use the same format style.

> diff --git a/drivers/net/wireless/rtlwifi/cam.c b/drivers/net/wireless/rtlwifi/cam.c

> @@ -52,11 +52,8 @@ static void rtl_cam_program_entry(struct ieee80211_hw *hw, u32 entry_no,
[]
> -	RT_TRACE(rtlpriv, COMP_SEC, DBG_LOUD,
> -		 "key_cont_128:\n %x:%x:%x:%x:%x:%x\n",
> -		 key_cont_128[0], key_cont_128[1],
> -		 key_cont_128[2], key_cont_128[3],
> -		 key_cont_128[4], key_cont_128[5]);
> +	RT_TRACE(rtlpriv, COMP_SEC, DBG_LOUD, "key_cont_128: %*ph\n",
> +			6, key_cont_128);

Uses "%*ph"
You removed a newline.
That should probably be mentioned in the changelog.

It would be a bit nicer as well to align the arguments
after the open paren like:

	RT_TRACE(rtlpriv, COMP_SEC, DBG_LOUD, "key_cont_128: %*ph\n",
		 6, key_cont_128);

> diff --git a/drivers/net/wireless/rtlwifi/rtl8192ce/hw.c b/drivers/net/wireless/rtlwifi/rtl8192ce/hw.c
[]
> @@ -1918,10 +1918,8 @@ static void rtl92ce_update_hal_rate_mask(struct ieee80211_hw *hw,
[]
> -		 "Rate_index:%x, ratr_val:%x, %x:%x:%x:%x:%x\n",
> -		 ratr_index, ratr_bitmap,
> -		 rate_mask[0], rate_mask[1], rate_mask[2], rate_mask[3],
> -		 rate_mask[4]);
> +		 "Rate_index:%x, ratr_val:%x, %*phC\n",
> +		 ratr_index, ratr_bitmap, 5, rate_mask);

Uaes "%*phC", etc...

> diff --git a/drivers/net/wireless/rtlwifi/rtl8192cu/hw.c b/drivers/net/wireless/rtlwifi/rtl8192cu/hw.c
[]
> @@ -2169,10 +2169,8 @@ void rtl92cu_update_hal_rate_mask(struct ieee80211_hw *hw, u8 rssi_level)
[]
> -		 "Rate_index:%x, ratr_val:%x, %x:%x:%x:%x:%x\n",
> -		 ratr_index, ratr_bitmap,
> -		 rate_mask[0], rate_mask[1], rate_mask[2], rate_mask[3],
> -		 rate_mask[4]);
> +		 "Rate_index:%x, ratr_val:%x, %*phC\n",
> +		 ratr_index, ratr_bitmap, 5, rate_mask);

here too

^ 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