* [PATCH net] net: sctp: fix memory leak in auth key management
From: Daniel Borkmann @ 2014-11-10 17:00 UTC (permalink / raw)
To: davem; +Cc: linux-sctp, netdev, Vlad Yasevich
A very minimal and simple user space application allocating an SCTP
socket, setting SCTP_AUTH_KEY setsockopt(2) on it and then closing
the socket again will leak the memory containing the authentication
key from user space:
unreferenced object 0xffff8800837047c0 (size 16):
comm "a.out", pid 2789, jiffies 4296954322 (age 192.258s)
hex dump (first 16 bytes):
01 00 00 00 04 00 00 00 00 00 00 00 00 00 00 00 ................
backtrace:
[<ffffffff816d7e8e>] kmemleak_alloc+0x4e/0xb0
[<ffffffff811c88d8>] __kmalloc+0xe8/0x270
[<ffffffffa0870c23>] sctp_auth_create_key+0x23/0x50 [sctp]
[<ffffffffa08718b1>] sctp_auth_set_key+0xa1/0x140 [sctp]
[<ffffffffa086b383>] sctp_setsockopt+0xd03/0x1180 [sctp]
[<ffffffff815bfd94>] sock_common_setsockopt+0x14/0x20
[<ffffffff815beb61>] SyS_setsockopt+0x71/0xd0
[<ffffffff816e58a9>] system_call_fastpath+0x12/0x17
[<ffffffffffffffff>] 0xffffffffffffffff
This is bad because of two things, we can bring down a machine from
user space when auth_enable=1, but also we would leave security sensitive
keying material in memory without clearing it after use. The issue is
that sctp_auth_create_key() already sets the refcount to 1, but after
allocation sctp_auth_set_key() does an additional refcount on it, and
thus leaving it around when we free the socket.
Fixes: 65b07e5d0d0 ("[SCTP]: API updates to suport SCTP-AUTH extensions.")
Signed-off-by: Daniel Borkmann <dborkman@redhat.com>
Cc: Vlad Yasevich <vyasevich@gmail.com>
---
net/sctp/auth.c | 2 --
1 file changed, 2 deletions(-)
diff --git a/net/sctp/auth.c b/net/sctp/auth.c
index 0e85291..fb7976a 100644
--- a/net/sctp/auth.c
+++ b/net/sctp/auth.c
@@ -862,8 +862,6 @@ int sctp_auth_set_key(struct sctp_endpoint *ep,
list_add(&cur_key->key_list, sh_keys);
cur_key->key = key;
- sctp_auth_key_hold(key);
-
return 0;
nomem:
if (!replace)
--
1.7.11.7
^ permalink raw reply related
* Re: [Xen-devel] BUG in xennet_make_frags with paged skb data
From: Eric Dumazet @ 2014-11-10 17:02 UTC (permalink / raw)
To: David Vrabel
Cc: Zoltan Kiss, netdev, David S. Miller, Konrad Rzeszutek Wilk,
Boris Ostrovsky, Stefan Bader, Jay Vosburgh, linux-kernel,
xen-devel
In-Reply-To: <5460EAF1.5020903@citrix.com>
On Mon, 2014-11-10 at 16:42 +0000, David Vrabel wrote:
> On 10/11/14 16:39, Zoltan Kiss wrote:
> >
> > The BUG_ON suggested by Stefan would be still reasonable:
> >
> > BUG_ON(((page-compound_head(page))*PAGE_SIZE)+offset+len >
> > PAGE_SIZE<<compound_order(compound_head(page)));
>
> Well, it wouldn't trigger but I don't think it is useful any more.
Right.
This BUG_ON() does not make sense (its current implementation is
assuming a very precise layout anyway)
If we really wanted some debugging, we would need something more generic
and done in core networking stack, not in a particular driver.
^ permalink raw reply
* Re: BUG in xennet_make_frags with paged skb data
From: Frediano Ziglio @ 2014-11-10 17:20 UTC (permalink / raw)
To: David Vrabel
Cc: Zoltan Kiss, Eric Dumazet, netdev, linux-kernel, Stefan Bader,
xen-devel, Jay Vosburgh, Boris Ostrovsky, David S. Miller
In-Reply-To: <5460EAF1.5020903@citrix.com>
[-- Attachment #1.1: Type: text/plain, Size: 860 bytes --]
2014-11-10 16:42 GMT+00:00 David Vrabel <david.vrabel@citrix.com>:
> On 10/11/14 16:39, Zoltan Kiss wrote:
> >
> > The BUG_ON suggested by Stefan would be still reasonable:
> >
> > BUG_ON(((page-compound_head(page))*PAGE_SIZE)+offset+len >
> > PAGE_SIZE<<compound_order(compound_head(page)));
>
> Well, it wouldn't trigger but I don't think it is useful any more.
>
> David
>
>
Looks like this structure was designed to just contains physical single
pages and was extended to support compound pages however there are still
some functions that assume the usage of single pages. Just for instance the
offset/size of fragments are computed from PAGE_SIZE. On x86 (4KB pages) if
your compound page is bigger than 64KB you cannot fully use for a fragment
as offset/size are 16 bits. Some functions in skbuff.c use kmap which is
limited to physical page.
Frediano
[-- Attachment #1.2: Type: text/html, Size: 1336 bytes --]
[-- Attachment #2: Type: text/plain, Size: 126 bytes --]
_______________________________________________
Xen-devel mailing list
Xen-devel@lists.xen.org
http://lists.xen.org/xen-devel
^ permalink raw reply
* Re: [patch net-next v2 06/10] bridge: introduce fdb offloading via switchdev
From: Andy Gospodarek @ 2014-11-10 17:30 UTC (permalink / raw)
To: Thomas Graf
Cc: Jiri Pirko, Jamal Hadi Salim, netdev, davem, nhorman, andy,
dborkman, ogerlitz, jesse, pshelar, azhou, ben, stephen,
jeffrey.t.kirsher, vyasevic, xiyou.wangcong, john.r.fastabend,
edumazet, sfeldma, f.fainelli, roopa, linville, jasowang,
ebiederm, nicolas.dichtel, ryazanov.s.a, buytenh, aviadr, nbd,
alexei.starovoitov, Neil.Jerram, ronye, simon.horman,
alexander.h.duyck, john.ronciak, mleitner, shrijeet, b
In-Reply-To: <20141110135100.GA19157@casper.infradead.org>
On Mon, Nov 10, 2014 at 01:51:00PM +0000, Thomas Graf wrote:
> On 11/10/14 at 09:15am, Jiri Pirko wrote:
> > There are few problems in re-using this. It is netlink based so for calling
> > it from bridge code, we would have to construct netlink message. But
> > that could be probably changed.
> > As you can see from the list of parameters, this is no longer about fdb (addr,
> > vlanid) but this has been extended to something else. See vxlan code for
> > what this is used for. I believe that fdb_add/del should be renamed to
> > something else, perhaps l2neigh_add/del or something like that.
> > The other problem is that fdb_add/del is currently used by various
> > drivers for different purpose (adding macs to unicast list).
>
> Can you elaborate a bit on the intended semantic differences between
> the existing ndo_fdb_add() and ndo_sw_port_fdb_add()? I'm not sure we
> need the sw_ prefix for this specific ndo.
>
> I completely agree that relying on Netlink is wrong because we'll have
> in-kernel users of the API but I believe that existing ndo_fdb_add()
> implementations in i40e, ixgbe, qlcnic and macvlan could use the new
> API you propose.
I also think the same API could be used quite easily on the current
drivers that use it.
I was looking at this earlier today and there are only 5 drivers
(outside the bridge code) that support ndo_fdb_add. The 3 hardware
drivers and vxlan driver seem like they could use this new API. The
macvlan code appears to simply set the uc and mc lists, which seems like
it could be done other ways -- confirmation from John Fastabend, Roopa,
and mst would be good.
> How about we rename the existing ndo_fdb_add() to ndo_neigh_add() as
> you propose and convert vxlan over to it and have all others which don't
> even depend on the Netlink attributes being passed in (i40e, ixgbe,
> qlcnic, macvlan) use ndo_fdb_add() which would have the behaviour of your
> proposed ndo_sw_port_fdb_add()?
I would much rather see something like Thomas proposes here. I know you
would like to see these patches get included (I'm anxious to see better
in-kernel offload support too!), but separate, possibly unnecessary
APIs like this can get painful for driver maintainers (upstream and
distro maintainers).
^ permalink raw reply
* Re: [patch net-next v2 10/10] rocker: implement L2 bridge offloading
From: Scott Feldman @ 2014-11-10 17:36 UTC (permalink / raw)
To: Roopa Prabhu
Cc: Jamal Hadi Salim, Jiri Pirko, Netdev, David S. Miller, nhorman,
Andy Gospodarek, Thomas Graf, dborkman, ogerlitz, jesse, pshelar,
azhou, ben, stephen, Kirsher, Jeffrey T, vyasevic, Cong Wang,
Fastabend, John R, Eric Dumazet, Florian Fainelli, John Linville,
jasowang, ebiederm, nicolas.dichtel, ryazanov.s.a, buytenh,
aviadr, nbd, Alexei Starovoitov, Neil
In-Reply-To: <5460E3D5.3000104@cumulusnetworks.com>
On Mon, Nov 10, 2014 at 6:12 AM, Roopa Prabhu <roopa@cumulusnetworks.com> wrote:
> On 11/10/14, 4:27 AM, Jamal Hadi Salim wrote:
>>
>> On 11/10/14 03:46, Scott Feldman wrote:
>>
>>>
>>> IFLA_BRPORT_LEARNING is u8 attr and we're only using lower bit to turn
>>> learning on/off. Maybe we can use another bit to indicate learning to
>>> be done in sw or hw. I don't think adding another bit would break
>>> existing iproute2.
>>>
>>> LEARNING_ENABLED (1 << 0)
>>> LEARNING_HW (1 << 1)
>>>
>>> Would this work?
>>>
>>
>> Yes to making it a bit. But:
>> This is not *learning*. You are doing a *sync*.
>> Those are two different things.
>>
>> Learning on/off exists today. It signals to the L2 whether you
>> should learn or not.
>> I like the way fdb_add/del work with a flag which says
>> it is the software and/or offloaded version. Please keep that
>> semantic.
>> What you are doing above is letting the hardware learn then
>> syncing to software. You need a different flag there. something
>> like:
>>
>> SYNC_HW_FDB (1<<1)
>>
> And in any case, It seems like this policy should be per bridge or per
> switch chip...or per fdb..
> entry (like the original fdb_add/del) and not a "port" flag.. ?
Per-port gives more flexibility, and it looks like we can extend
existing IFLA_BRPORT_LEARNING without much trouble.
I didn't follow the fdb_add/del comment? Isn't an fdb entry
port-specific by nature? fdb entry = {port, mac, vlan} tuple.
^ permalink raw reply
* Re: [patch net-next v2 10/10] rocker: implement L2 bridge offloading
From: Scott Feldman @ 2014-11-10 17:22 UTC (permalink / raw)
To: Jamal Hadi Salim
Cc: Jiri Pirko, Netdev, David S. Miller, nhorman, Andy Gospodarek,
Thomas Graf, dborkman, ogerlitz, jesse, pshelar, azhou, ben,
stephen, Kirsher, Jeffrey T, vyasevic, Cong Wang,
Fastabend, John R, Eric Dumazet, Florian Fainelli, Roopa Prabhu,
John Linville, jasowang, ebiederm, nicolas.dichtel, ryazanov.s.a,
buytenh, aviadr, nbd, Alexei Starovoitov, Neil.Je
In-Reply-To: <5460AF22.2040701@mojatatu.com>
On Mon, Nov 10, 2014 at 2:27 AM, Jamal Hadi Salim <jhs@mojatatu.com> wrote:
> On 11/10/14 03:46, Scott Feldman wrote:
>
>>
>> IFLA_BRPORT_LEARNING is u8 attr and we're only using lower bit to turn
>> learning on/off. Maybe we can use another bit to indicate learning to
>> be done in sw or hw. I don't think adding another bit would break
>> existing iproute2.
>>
>> LEARNING_ENABLED (1 << 0)
>> LEARNING_HW (1 << 1)
>>
>> Would this work?
>>
>
> Yes to making it a bit. But:
> This is not *learning*. You are doing a *sync*.
> Those are two different things.
>
> Learning on/off exists today. It signals to the L2 whether you
> should learn or not.
> I like the way fdb_add/del work with a flag which says
> it is the software and/or offloaded version. Please keep that
> semantic.
> What you are doing above is letting the hardware learn then
> syncing to software. You need a different flag there. something
> like:
>
> SYNC_HW_FDB (1<<1)
Agreed, that's more accurate. Thanks for the refinement.
>
> cheers,
> jamal
^ permalink raw reply
* Re: linux-next: manual merge of the tiny tree with the net-next tree
From: Josh Triplett @ 2014-11-10 17:56 UTC (permalink / raw)
To: Stephen Rothwell
Cc: David Miller, netdev, linux-next, linux-kernel,
Hannes Frederic Sowa, Catalina Mocanu
In-Reply-To: <20141110142511.03354f6a@canb.auug.org.au>
On Mon, Nov 10, 2014 at 02:25:11PM +1100, Stephen Rothwell wrote:
> Hi Josh,
>
> Today's linux-next merge of the tiny tree got a conflict in
> lib/Makefile between commit e5a2c8999576 ("fast_hash: avoid indirect
> function calls") from the net-next tree and commit 4ecea0db79ef ("lib:
> rhashtable: Make rhashtable.c optional") from the tiny tree.
>
> I fixed it up (see below) and can carry the fix as necessary (no action
> is required).
This resolution looks correct to me.
- Josh Triplett
> diff --cc lib/Makefile
> index 04e53dd16070,47b8305288e2..000000000000
> --- a/lib/Makefile
> +++ b/lib/Makefile
> @@@ -22,11 -22,14 +22,14 @@@ lib-$(CONFIG_SMP) += cpumask.
> lib-y += kobject.o klist.o
> obj-y += lockref.o
>
> - obj-y += bcd.o div64.o sort.o parser.o halfmd4.o debug_locks.o random32.o \
> + obj-y += bcd.o div64.o sort.o parser.o debug_locks.o random32.o \
> bust_spinlocks.o hexdump.o kasprintf.o bitmap.o scatterlist.o \
> - gcd.o lcm.o list_sort.o uuid.o flex_array.o iovec.o clz_ctz.o \
> + gcd.o lcm.o list_sort.o uuid.o iovec.o clz_ctz.o \
> bsearch.o find_last_bit.o find_next_bit.o llist.o memweight.o kfifo.o \
> - percpu-refcount.o percpu_ida.o rhashtable.o
> - percpu-refcount.o percpu_ida.o hash.o
> ++ percpu-refcount.o percpu_ida.o
> + obj-$(CONFIG_FLEX_ARRAY) += flex_array.o
> + obj-$(CONFIG_HALFMD4) += halfmd4.o
> + obj-$(CONFIG_RHASHTABLE) += rhashtable.o
> obj-y += string_helpers.o
> obj-$(CONFIG_TEST_STRING_HELPERS) += test-string_helpers.o
> obj-y += kstrtox.o
^ permalink raw reply
* Re: [patch net-next v2 03/10] rtnl: expose physical switch id for particular device
From: Roopa Prabhu @ 2014-11-10 17:58 UTC (permalink / raw)
To: Jiri Pirko
Cc: netdev, davem, nhorman, andy, tgraf, dborkman, ogerlitz, jesse,
pshelar, azhou, ben, stephen, jeffrey.t.kirsher, vyasevic,
xiyou.wangcong, john.r.fastabend, edumazet, jhs, sfeldma,
f.fainelli, linville, jasowang, ebiederm, nicolas.dichtel,
ryazanov.s.a, buytenh, aviadr, nbd, alexei.starovoitov,
Neil.Jerram, ronye, simon.horman, alexander.h.duyck, john.ronciak,
mleitner, shrijeet, gospo, bcrl
In-Reply-To: <1415530280-9190-4-git-send-email-jiri@resnulli.us>
On 11/9/14, 2:51 AM, Jiri Pirko wrote:
> The netdevice represents a port in a switch, it will expose
> IFLA_PHYS_SWITCH_ID value via rtnl. Two netdevices with the same value
> belong to one physical switch.
>
> Signed-off-by: Jiri Pirko <jiri@resnulli.us>
> ---
> include/uapi/linux/if_link.h | 1 +
> net/core/rtnetlink.c | 26 +++++++++++++++++++++++++-
> 2 files changed, 26 insertions(+), 1 deletion(-)
>
> diff --git a/include/uapi/linux/if_link.h b/include/uapi/linux/if_link.h
> index 7072d83..4163753 100644
> --- a/include/uapi/linux/if_link.h
> +++ b/include/uapi/linux/if_link.h
> @@ -145,6 +145,7 @@ enum {
> IFLA_CARRIER,
> IFLA_PHYS_PORT_ID,
> IFLA_CARRIER_CHANGES,
> + IFLA_PHYS_SWITCH_ID,
Jiri, since we have not really converged on the switchdev class or
having a separate switchdev instance,
am thinking it is better if we dont expose any such switch_id to
userspace yet until absolutely needed. Do you need it today ?
There is no real in kernel hw switch driver that will use it today. And
quite likely this will need to change when we introduce real hw switch
drivers.
> __IFLA_MAX
> };
>
> diff --git a/net/core/rtnetlink.c b/net/core/rtnetlink.c
> index 1087c6d..f839354 100644
> --- a/net/core/rtnetlink.c
> +++ b/net/core/rtnetlink.c
> @@ -43,6 +43,7 @@
>
> #include <linux/inet.h>
> #include <linux/netdevice.h>
> +#include <net/switchdev.h>
> #include <net/ip.h>
> #include <net/protocol.h>
> #include <net/arp.h>
> @@ -868,7 +869,8 @@ static noinline size_t if_nlmsg_size(const struct net_device *dev,
> + rtnl_port_size(dev, ext_filter_mask) /* IFLA_VF_PORTS + IFLA_PORT_SELF */
> + rtnl_link_get_size(dev) /* IFLA_LINKINFO */
> + rtnl_link_get_af_size(dev) /* IFLA_AF_SPEC */
> - + nla_total_size(MAX_PHYS_ITEM_ID_LEN); /* IFLA_PHYS_PORT_ID */
> + + nla_total_size(MAX_PHYS_ITEM_ID_LEN) /* IFLA_PHYS_PORT_ID */
> + + nla_total_size(MAX_PHYS_ITEM_ID_LEN); /* IFLA_PHYS_SWITCH_ID */
> }
>
> static int rtnl_vf_ports_fill(struct sk_buff *skb, struct net_device *dev)
> @@ -967,6 +969,24 @@ static int rtnl_phys_port_id_fill(struct sk_buff *skb, struct net_device *dev)
> return 0;
> }
>
> +static int rtnl_phys_switch_id_fill(struct sk_buff *skb, struct net_device *dev)
> +{
> + int err;
> + struct netdev_phys_item_id psid;
> +
> + err = netdev_sw_parent_id_get(dev, &psid);
> + if (err) {
> + if (err == -EOPNOTSUPP)
> + return 0;
> + return err;
> + }
> +
> + if (nla_put(skb, IFLA_PHYS_SWITCH_ID, psid.id_len, psid.id))
> + return -EMSGSIZE;
> +
> + return 0;
> +}
> +
> static int rtnl_fill_ifinfo(struct sk_buff *skb, struct net_device *dev,
> int type, u32 pid, u32 seq, u32 change,
> unsigned int flags, u32 ext_filter_mask)
> @@ -1039,6 +1059,9 @@ static int rtnl_fill_ifinfo(struct sk_buff *skb, struct net_device *dev,
> if (rtnl_phys_port_id_fill(skb, dev))
> goto nla_put_failure;
>
> + if (rtnl_phys_switch_id_fill(skb, dev))
> + goto nla_put_failure;
> +
> attr = nla_reserve(skb, IFLA_STATS,
> sizeof(struct rtnl_link_stats));
> if (attr == NULL)
> @@ -1198,6 +1221,7 @@ static const struct nla_policy ifla_policy[IFLA_MAX+1] = {
> [IFLA_NUM_RX_QUEUES] = { .type = NLA_U32 },
> [IFLA_PHYS_PORT_ID] = { .type = NLA_BINARY, .len = MAX_PHYS_ITEM_ID_LEN },
> [IFLA_CARRIER_CHANGES] = { .type = NLA_U32 }, /* ignored */
> + [IFLA_PHYS_SWITCH_ID] = { .type = NLA_BINARY, .len = MAX_PHYS_ITEM_ID_LEN },
> };
>
> static const struct nla_policy ifla_info_policy[IFLA_INFO_MAX+1] = {
^ permalink raw reply
* Re: [PATCH v2 net-next 2/2] mlx4: use napi_complete_done()
From: Eric Dumazet @ 2014-11-10 18:01 UTC (permalink / raw)
To: David Miller; +Cc: netdev, amirv, ogerlitz, willemb
In-Reply-To: <20141107.170053.1003349690694025765.davem@redhat.com>
On Fri, 2014-11-07 at 17:00 -0500, David Miller wrote:
> From: Eric Dumazet <eric.dumazet@gmail.com>
> Date: Thu, 06 Nov 2014 21:10:11 -0800
...
> > Signed-off-by: Eric Dumazet <edumazet@google.com>
>
> Applied.
I managed to add a bug in this trivial patch.
I'll send a fix asap.
^ permalink raw reply
* Re: [PATCH] brcmfmac: unlink URB when request timed out
From: Arend van Spriel @ 2014-11-10 18:03 UTC (permalink / raw)
To: Mathy Vanhoef, brudley, frankyl, meuleman, linville, pieterpg,
linux-wireless, brcm80211-dev-list, netdev, Oliver Neukum
In-Reply-To: <5460E2FA.40201@gmail.com>
On 10-11-14 17:08, Mathy Vanhoef wrote:
> On 11/10/2014 06:18 AM, Arend van Spriel wrote:
>> On 09-11-14 19:10, Mathy Vanhoef wrote:
>>> From: Mathy Vanhoef <vanhoefm@gmail.com>
>>>
>>> Unlink the submitted URB in brcmf_usb_dl_cmd if the request timed out. This
>>> assures the URB is never submitted twice, preventing a driver crash.
>>
>> Hi Mathy,
>>
>> What driver crash are you referring to? The log only shows the WARNING
>> ending in a USB disconnect but no actual crash. Does your patch get the
>> driver running properly or does it only avoid the warning.
>
> Hi Arend,
>
> It shows a warning, after which the device doesn't work (but the computer is
> still usable). But I've noticed that when *unplugging* the USB cable the OS may
> freeze. This doesn't always happen though, sometimes unplugging works OK. The
> patch both avoids the warning, and gets the device/driver running properly
> (unplugging also works OK).
>
>>
>> With that said, it seems there is some need for improvement, but I also
>> notice you are running this on a virtual machine so could that affect
>> the timeout to kick in before completion. Could you try to increase the
>> timeout. Still when a timeout occurs this needs to be handled properly.
>> Could you also try the following patch?
>
> I did a few additional tests:
Thanks for being thorough here.
> 1. When increasing IOCTL_RESP_TIMEOUT to 20000 (ten times the normal value) the
> timeout and warning still occur. Device/driver doesn't work.
> 2. When increasing BRCMF_USB_RESET_GETVER_SPINWAIT to 1000 (ten timers the
> normal value) everything works. Device/driver works.
Just to clarify, but did you have IOCTL_RESP_TIMEOUT back on normal
value here?
> 3. Quick test using backports-3.18-rc1-1 (aka unpatched driver) on a non-
> virtualized Linux install: In that case everything worked fine. So the bug
> may only be triggered in a virtualized environment / VMWare.
My colleague has been running brcmfmac with USB devices under VirtualBox
and I know he needed to fix something to get it working properly. Just
could not ask him yet as he (hopefully) enjoyed an extended weekend.
> 4. When applying your patch, the driver stops early during initialization of
> the device. I included a WARN_ONCE before returning EINVAL and got the
> output below.
I expected as much. It only avoids the resubmit of the ctl_urb. Given
your description of the unplug freezes I suspect some issue in the
VMware usb virtualization.
Regards,
Arend
> Kind regards,
> Mathy
> ---
> [ 220.955647] usb 1-1: new high-speed USB device number 3 using ehci-pci
> [ 221.487797] usb 1-1: New USB device found, idVendor=043e, idProduct=3004
> [ 221.487802] usb 1-1: New USB device strings: Mfr=1, Product=2, SerialNumber=3
> [ 221.487804] usb 1-1: Product: Remote Download Wireless Adapter
> [ 221.487806] usb 1-1: Manufacturer: Broadcom
> [ 221.487808] usb 1-1: SerialNumber: 000000000001
> [ 221.490472] brcmfmac: brcmf_usb_probe Enter 0x043e:0x3004
> [ 221.490476] brcmfmac: brcmf_usb_probe Broadcom high speed USB WLAN interface detected
> [ 221.490477] brcmfmac: brcmf_usb_probe_cb Enter
> [ 221.490480] brcmfmac: brcmf_usb_attach Enter
> [ 221.490494] brcmfmac: brcmf_usb_dlneeded Enter
> [ 221.490495] ------------[ cut here ]------------
> [ 221.490503] WARNING: CPU: 0 PID: 100 at drivers/net/wireless/brcm80211/brcmfmac/usb.c:716 brcmf_usb_dl_cmd+0x75/0x1a0 [brcmfmac]()
> [ 221.490505] EINVAL devinfo=c0044000 ctl_rub=ef898380 completed=0
> [ 221.490506] Modules linked in: brcmfmac brcmutil vmw_pvscsi pcnet32 mptspi mptscsih mptbase
> [ 221.490514] CPU: 0 PID: 100 Comm: kworker/0:1 Not tainted 3.18.0-rc3-wl+ #2
> [ 221.490515] Hardware name: VMware, Inc. VMware Virtual Platform/440BX Desktop Reference Platform, BIOS 6.00 07/31/2013
> [ 221.490528] Workqueue: usb_hub_wq hub_event
> [ 221.490530] 00000000 00000000 eecffb58 c1711f4a eecffb98 eecffb88 c103edaf f11cbc58
> [ 221.490534] eecffbb4 00000064 f11cbc84 000002cc f11c1595 f11c1595 c0044000 ffffffea
> [ 221.490537] ef726000 eecffba0 c103ee4e 00000009 eecffb98 f11cbc58 eecffbb4 eecffbd0
> [ 221.490541] Call Trace:
> [ 221.490550] [<c1711f4a>] dump_stack+0x41/0x52
> [ 221.490558] [<c103edaf>] warn_slowpath_common+0x7f/0xa0
> [ 221.490563] [<f11c1595>] ? brcmf_usb_dl_cmd+0x75/0x1a0 [brcmfmac]
> [ 221.490567] [<f11c1595>] ? brcmf_usb_dl_cmd+0x75/0x1a0 [brcmfmac]
> [ 221.490570] [<c103ee4e>] warn_slowpath_fmt+0x2e/0x30
> [ 221.490575] [<f11c1595>] brcmf_usb_dl_cmd+0x75/0x1a0 [brcmfmac]
> [ 221.490580] [<f11c2cd8>] brcmf_usb_probe+0x3c8/0x640 [brcmfmac]
> [ 221.490583] [<c1717d53>] ? mutex_lock+0x13/0x32
> [ 221.490586] [<c1493ae3>] usb_probe_interface+0xa3/0x180
> [ 221.490590] [<c13f5690>] ? __driver_attach+0x90/0x90
> [ 221.490592] [<c13f546e>] driver_probe_device+0x5e/0x1f0
> [ 221.490595] [<c13f5690>] ? __driver_attach+0x90/0x90
> [ 221.490597] [<c13f56c9>] __device_attach+0x39/0x50
> [ 221.490600] [<c13f3d84>] bus_for_each_drv+0x34/0x70
> [ 221.490602] [<c13f53db>] device_attach+0x7b/0x90
> [ 221.490604] [<c13f5690>] ? __driver_attach+0x90/0x90
> [ 221.490607] [<c13f4b8f>] bus_probe_device+0x6f/0x90
> [ 221.490609] [<c13f3256>] device_add+0x426/0x520
> [ 221.490611] [<c1491503>] ? usb_control_msg+0xb3/0xd0
> [ 221.490614] [<c1717d53>] ? mutex_lock+0x13/0x32
> [ 221.490627] [<c14922f8>] usb_set_configuration+0x3f8/0x700
> [ 221.490630] [<c13f5690>] ? __driver_attach+0x90/0x90
> [ 221.490633] [<c149ac7b>] generic_probe+0x2b/0x90
> [ 221.490637] [<c1188bc0>] ? sysfs_create_link+0x20/0x40
> [ 221.490639] [<c1492bec>] usb_probe_device+0xc/0x10
> [ 221.490641] [<c13f546e>] driver_probe_device+0x5e/0x1f0
> [ 221.490644] [<c13f5690>] ? __driver_attach+0x90/0x90
> [ 221.490646] [<c13f56c9>] __device_attach+0x39/0x50
> [ 221.490649] [<c13f3d84>] bus_for_each_drv+0x34/0x70
> [ 221.490651] [<c13f53db>] device_attach+0x7b/0x90
> [ 221.490653] [<c13f5690>] ? __driver_attach+0x90/0x90
> [ 221.490656] [<c13f4b8f>] bus_probe_device+0x6f/0x90
> [ 221.490658] [<c13f3256>] device_add+0x426/0x520
> [ 221.490661] [<c148aa2e>] ? usb_new_device+0x16e/0x3a0
> [ 221.490663] [<c148aad7>] usb_new_device+0x217/0x3a0
> [ 221.490666] [<c148bff7>] hub_event+0xa17/0xda0
> [ 221.490668] [<c1716918>] ? __schedule+0x2f8/0x710
> [ 221.490672] [<c105127c>] ? pwq_dec_nr_in_flight+0x3c/0x90
> [ 221.490674] [<c10513ee>] process_one_work+0x11e/0x360
> [ 221.490677] [<c1051750>] worker_thread+0xf0/0x3c0
> [ 221.490680] [<c106e14a>] ? __wake_up_locked+0x1a/0x20
> [ 221.490682] [<c1051660>] ? process_scheduled_works+0x30/0x30
> [ 221.490685] [<c1055b56>] kthread+0x96/0xb0
> [ 221.490687] [<c1050000>] ? put_unbound_pool+0x110/0x170
> [ 221.490691] [<c1719c81>] ret_from_kernel_thread+0x21/0x30
> [ 221.490693] [<c1055ac0>] ? kthread_worker_fn+0x110/0x110
> [ 221.490695] ---[ end trace 9befd914693f3083 ]---
> [ 221.490697] brcmfmac: brcmf_usb_dlneeded chip 57005 rev 0xf11cfcec
> [ 221.490699] brcmfmac: brcmf_fw_get_firmwares enter: dev=1-1
>
> diff --git a/drivers/net/wireless/brcm80211/brcmfmac/usb.c b/drivers/net/wireless/brcm80211/brcmfmac/usb.c
> index 5265aa7..15b1aa7 100644
> --- a/drivers/net/wireless/brcm80211/brcmfmac/usb.c
> +++ b/drivers/net/wireless/brcm80211/brcmfmac/usb.c
> @@ -709,8 +709,13 @@ static int brcmf_usb_dl_cmd(struct brcmf_usbdev_info *devinfo, u8 cmd,
> char *tmpbuf;
> u16 size;
>
> - if ((!devinfo) || (devinfo->ctl_urb == NULL))
> + if (!devinfo || !devinfo->ctl_urb || !devinfo->ctl_completed) {
> + WARN_ONCE(1, "EINVAL devinfo=%p ctl_rub=%p completed=%d\n",
> + devinfo,
> + devinfo ? devinfo->ctl_urb : NULL,
> + devinfo ? devinfo->ctl_completed : -1);
> return -EINVAL;
> + }
>
> tmpbuf = kmalloc(buflen, GFP_ATOMIC);
> if (!tmpbuf)
>
>
>>
>> Regards,
>> Arend
>> ---
>> drivers/net/wireless/brcm80211/brcmfmac/usb.c | 2 +-
>> 1 file changed, 1 insertion(+), 1 deletion(-)
>>
>> diff --git a/drivers/net/wireless/brcm80211/brcmfmac/usb.c
>> b/drivers/net/wireles
>> index dc13591..786c40b 100644
>> --- a/drivers/net/wireless/brcm80211/brcmfmac/usb.c
>> +++ b/drivers/net/wireless/brcm80211/brcmfmac/usb.c
>> @@ -640,7 +640,7 @@ static int brcmf_usb_dl_cmd(struct brcmf_usbdev_info
>> *devinf
>> char *tmpbuf;
>> u16 size;
>>
>> - if ((!devinfo) || (devinfo->ctl_urb == NULL))
>> + if (!devinfo || !devinfo->ctl_urb || !devinfo->ctl_completed)
>> return -EINVAL;
>>
>> tmpbuf = kmalloc(buflen, GFP_ATOMIC);
>>
>>> Signed-off-by: Mathy Vanhoef <vanhoefm@gmail.com>
>>> ---
>>> Currently brcmfmac may crash when a USB device is attached (tested with a LG
>>> TWFM-B003D). In particular it fails on the second call to brcmf_usb_dl_cmd in
>>> the while loop of brcmf_usb_resetcfg. The problem is that an URB is being
>>> submitted twice:
>>>
>>> [ 169.861800] brcmfmac: brcmf_usb_dl_writeimage Enter, fw f14db000, len 348160
>>> [ 171.787791] brcmfmac: brcmf_usb_dl_writeimage Exit, err=0
>>> [ 171.787797] brcmfmac: brcmf_usb_dlstart Exit, err=0
>>> [ 171.787799] brcmfmac: brcmf_usb_dlrun Enter
>>> [ 171.791794] brcmfmac: brcmf_usb_resetcfg Enter
>>> [ 173.988072] ------------[ cut here ]------------
>>> [ 173.988083] WARNING: CPU: 0 PID: 369 at drivers/usb/core/urb.c:339 usb_submit_urb+0x4e6/0x500()
>>> [ 173.988085] URB eaf45f00 submitted while active
>>> [ 173.988086] Modules linked in: brcmfmac brcmutil vmw_pvscsi pcnet32 mptspi mptscsih mptbase
>>> [ 173.988100] CPU: 0 PID: 369 Comm: kworker/0:2 Not tainted 3.18.0-rc3-wl #1
>>> [ 173.988102] Hardware name: VMware, Inc. VMware Virtual Platform/440BX Desktop Reference Platform, BIOS 6.00 07/31/2013
>>> [ 173.988106] Workqueue: events request_firmware_work_func
>>> [ 173.988108] 00000000 00000000 ee747db8 c1711f4a ee747df8 ee747de8 c103edaf c18d1e10
>>> [ 173.988112] ee747e14 00000171 c18a8b29 00000153 c1490556 c1490556 eaf45f00 eafdc660
>>> [ 173.988115] f14b8fa0 ee747e00 c103ee4e 00000009 ee747df8 c18d1e10 ee747e14 ee747e50
>>> [ 173.988119] Call Trace:
>>> [ 173.988129] [<c1711f4a>] dump_stack+0x41/0x52
>>> [ 173.988136] [<c103edaf>] warn_slowpath_common+0x7f/0xa0
>>> [ 173.988139] [<c1490556>] ? usb_submit_urb+0x4e6/0x500
>>> [ 173.988141] [<c1490556>] ? usb_submit_urb+0x4e6/0x500
>>> [ 173.988147] [<f14b8fa0>] ? brcmf_usb_ioctl_resp_wake+0x40/0x40 [brcmfmac]
>>> [ 173.988150] [<c103ee4e>] warn_slowpath_fmt+0x2e/0x30
>>> [ 173.988152] [<c1490556>] usb_submit_urb+0x4e6/0x500
>>> [ 173.988156] [<c1123de1>] ? __kmalloc+0x21/0x140
>>> [ 173.988161] [<f14b91c3>] ? brcmf_usb_dl_cmd+0x33/0x120 [brcmfmac]
>>> [ 173.988166] [<f14b9243>] brcmf_usb_dl_cmd+0xb3/0x120 [brcmfmac]
>>> [ 173.988170] [<f14ba6c4>] brcmf_usb_probe_phase2+0x4e4/0x640 [brcmfmac]
>>> [ 173.988176] [<f14b4900>] brcmf_fw_request_code_done+0xd0/0xf0 [brcmfmac]
>>> [ 173.988178] [<c1400876>] request_firmware_work_func+0x26/0x50
>>> [ 173.988182] [<c10513ee>] process_one_work+0x11e/0x360
>>> [ 173.988184] [<c1051750>] worker_thread+0xf0/0x3c0
>>> [ 173.988205] [<c106e14a>] ? __wake_up_locked+0x1a/0x20
>>> [ 173.988208] [<c1051660>] ? process_scheduled_works+0x30/0x30
>>> [ 173.988211] [<c1055b56>] kthread+0x96/0xb0
>>> [ 173.988214] [<c1719c81>] ret_from_kernel_thread+0x21/0x30
>>> [ 173.988217] [<c1055ac0>] ? kthread_worker_fn+0x110/0x110
>>> [ 173.988219] ---[ end trace 0c88bf46801de083 ]---
>>> [ 173.988221] brcmf_usb_dl_cmd: usb_submit_urb failed -16
>>> [ 173.988396] brcmfmac: brcmf_usb_probe_phase2 failed: dev=1-1, err=-19
>>> [ 173.989503] brcmfmac: brcmf_usb_disconnect Enter
>>>
>>> This patch fixes the brcmf_usb_dl_cmd function to prevent an URB from being
>>> submitted twice. Tested using a LG TWFM-B003D, which now works properly.
>>>
>>>
>>> drivers/net/wireless/brcm80211/brcmfmac/usb.c | 6 ++++--
>>> 1 file changed, 4 insertions(+), 2 deletions(-)
>>>
>>> diff --git a/drivers/net/wireless/brcm80211/brcmfmac/usb.c b/drivers/net/wireless/brcm80211/brcmfmac/usb.c
>>> index 5265aa7..1bc7858 100644
>>> --- a/drivers/net/wireless/brcm80211/brcmfmac/usb.c
>>> +++ b/drivers/net/wireless/brcm80211/brcmfmac/usb.c
>>> @@ -738,10 +738,12 @@ static int brcmf_usb_dl_cmd(struct brcmf_usbdev_info *devinfo, u8 cmd,
>>> goto finalize;
>>> }
>>>
>>> - if (!brcmf_usb_ioctl_resp_wait(devinfo))
>>> + if (!brcmf_usb_ioctl_resp_wait(devinfo)) {
>>> + usb_unlink_urb(devinfo->ctl_urb);
>>> ret = -ETIMEDOUT;
>>> - else
>>> + } else {
>>> memcpy(buffer, tmpbuf, buflen);
>>> + }
>>>
>>> finalize:
>>> kfree(tmpbuf);
>>>
>>
^ permalink raw reply
* Re: [PATCHv3 net-next 0/3] RDMA/cxgb4,cxgb4vf,cxgb4i,csiostor: Cleanup macros
From: David Miller @ 2014-11-10 17:57 UTC (permalink / raw)
To: hariprasad
Cc: netdev, linux-rdma, linux-scsi, roland, JBottomley, hch, swise,
leedom, anish, praveenm, nirranjan, kumaras
In-Reply-To: <1415333125-10635-1-git-send-email-hariprasad@chelsio.com>
From: Hariprasad Shenai <hariprasad@chelsio.com>
Date: Fri, 7 Nov 2014 09:35:22 +0530
> This series moves the debugfs code to a new file debugfs.c and cleans up
> macros/register defines.
>
> Various patches have ended up changing the style of the symbolic macros/register
> defines and some of them used the macros/register defines that matches the
> output of the script from the hardware team.
>
> As a result, the current kernel.org files are a mix of different macro styles.
> Since this macro/register defines is used by five different drivers, a
> few patch series have ended up adding duplicate macro/register define entries
> with different styles. This makes these register define/macro files a complete
> mess and we want to make them clean and consistent.
>
> Will post few more series so that we can cover all the macros so that they all
> follow the same style to be consistent.
>
> The patches series is created against 'net-next' tree.
> And includes patches on cxgb4, cxgb4vf, iw_cxgb4, csiostor and cxgb4i driver.
>
> We have included all the maintainers of respective drivers. Kindly review the
> change and let us know in case of any review comments.
...
> V3: Use suffix instead of prefix for macros/register defines
> V2: Changes the description and cover-letter content to answer David Miller's
> question
Series applied, thanks.
^ permalink raw reply
* Re: linux-next: Tree for Nov 10 (net/ipv4/ip_tunnel.c)
From: Randy Dunlap @ 2014-11-10 18:15 UTC (permalink / raw)
To: Stephen Rothwell, linux-next; +Cc: linux-kernel, netdev@vger.kernel.org
In-Reply-To: <20141110205945.51af32a6@canb.auug.org.au>
On 11/10/14 01:59, Stephen Rothwell wrote:
> Hi all,
>
> Changes since 20141106:
>
on x86_64:
when CONFIG_NET_IP_TUNNEL=y and CONFIG_NET_FOU=m:
net/built-in.o: In function `ip_tunnel_encap':
(.text+0xb04d8): undefined reference to `gue_build_header'
net/built-in.o: In function `ip_tunnel_encap':
(.text+0xb04ea): undefined reference to `fou_build_header'
--
~Randy
^ permalink raw reply
* [PATCH] smsc911x: power-up phydev before doing a software reset.
From: Enric Balletbo i Serra @ 2014-11-10 18:23 UTC (permalink / raw)
To: netdev, Steve Glendinning; +Cc: javier, ebutera, Enric Balletbo i Serra
With commit be9dad1f9f26604fb ("net: phy: suspend phydev when going
to HALTED"), the PHY device will be put in a low-power mode using
BMCR_PDOWN if the the interface is set down. The smsc911x driver does
a software_reset opening the device driver (ndo_open). In such case,
the PHY must be powered-up before access to any register and before
calling the software_reset function. Otherwise, as the PHY is powered
down the software reset fails and the interface can not be enabled
again.
This patch fixes this scenario that is easy to reproduce setting down
the network interface and setting up again.
$ ifconfig eth0 down
$ ifconfig eth0 up
ifconfig: SIOCSIFFLAGS: Input/output error
Signed-off-by: Enric Balletbo i Serra <eballetbo@iseebcn.com>
---
drivers/net/ethernet/smsc/smsc911x.c | 46 ++++++++++++++++++++++++++++++++++++
1 file changed, 46 insertions(+)
diff --git a/drivers/net/ethernet/smsc/smsc911x.c b/drivers/net/ethernet/smsc/smsc911x.c
index affb29d..d8bfe94 100644
--- a/drivers/net/ethernet/smsc/smsc911x.c
+++ b/drivers/net/ethernet/smsc/smsc911x.c
@@ -1342,6 +1342,42 @@ static void smsc911x_rx_multicast_update_workaround(struct smsc911x_data *pdata)
spin_unlock(&pdata->mac_lock);
}
+static int smsc911x_phy_general_power_up(struct smsc911x_data *pdata)
+{
+ int rc = 0;
+
+ if (!pdata->phy_dev)
+ return rc;
+
+ /* If the internal PHY is in General Power-Down mode, all, except the
+ * management interface, is powered-down and stays in that condition as
+ * long as Phy register bit 0.11 is HIGH.
+ *
+ * In that case, clear the bit 0.11, so the PHY powers up and we can
+ * access to the phy registers.
+ */
+ rc = phy_read(pdata->phy_dev, MII_BMCR);
+ if (rc < 0) {
+ SMSC_WARN(pdata, drv, "Failed reading PHY control reg");
+ return rc;
+ }
+
+ /* If the PHY general power-down bit is not set is not necessary to
+ * disable the general power down-mode.
+ */
+ if (rc & BMCR_PDOWN) {
+ rc = phy_write(pdata->phy_dev, MII_BMCR, rc & ~BMCR_PDOWN);
+ if (rc < 0) {
+ SMSC_WARN(pdata, drv, "Failed writing PHY control reg");
+ return rc;
+ }
+
+ mdelay(1);
+ }
+
+ return 0;
+}
+
static int smsc911x_phy_disable_energy_detect(struct smsc911x_data *pdata)
{
int rc = 0;
@@ -1415,6 +1451,16 @@ static int smsc911x_soft_reset(struct smsc911x_data *pdata)
int ret;
/*
+ * Make sure to power-up the PHY chip before doing a reset, otherwise
+ * the reset fails.
+ */
+ ret = smsc911x_phy_general_power_up(pdata);
+ if (ret) {
+ SMSC_WARN(pdata, drv, "Failed to power-up the PHY chip");
+ return ret;
+ }
+
+ /*
* LAN9210/LAN9211/LAN9220/LAN9221 chips have an internal PHY that
* are initialized in a Energy Detect Power-Down mode that prevents
* the MAC chip to be software reseted. So we have to wakeup the PHY
--
1.9.1
^ permalink raw reply related
* Re: [PATCH v2 net-next] PPC: bpf_jit_comp: add SKF_AD_HATYPE instruction
From: Alexei Starovoitov @ 2014-11-10 18:26 UTC (permalink / raw)
To: Denis Kirjanov
Cc: netdev@vger.kernel.org, linuxppc-dev, Daniel Borkmann,
Philippe Bergheaud
In-Reply-To: <1415599183-3883-1-git-send-email-kda@linux-powerpc.org>
On Sun, Nov 9, 2014 at 9:59 PM, Denis Kirjanov <kda@linux-powerpc.org> wrote:
> Add BPF extension SKF_AD_HATYPE to ppc JIT to check
> the hw type of the interface
>
> Before:
> [ 57.723666] test_bpf: #20 LD_HATYPE
> [ 57.723675] BPF filter opcode 0020 (@0) unsupported
> [ 57.724168] 48 48 PASS
>
> After:
> [ 103.053184] test_bpf: #20 LD_HATYPE 7 6 PASS
>
> CC: Alexei Starovoitov<alexei.starovoitov@gmail.com>
> CC: Daniel Borkmann<dborkman@redhat.com>
> CC: Philippe Bergheaud<felix@linux.vnet.ibm.com>
> Signed-off-by: Denis Kirjanov <kda@linux-powerpc.org>
>
> v2: address Alexei's comments
> ---
> arch/powerpc/net/bpf_jit_comp.c | 17 +++++++++++++----
> 1 file changed, 13 insertions(+), 4 deletions(-)
>
> diff --git a/arch/powerpc/net/bpf_jit_comp.c b/arch/powerpc/net/bpf_jit_comp.c
> index d110e28..d3fa80d 100644
> --- a/arch/powerpc/net/bpf_jit_comp.c
> +++ b/arch/powerpc/net/bpf_jit_comp.c
> @@ -361,6 +361,11 @@ static int bpf_jit_build_body(struct bpf_prog *fp, u32 *image,
> protocol));
> break;
> case BPF_ANC | SKF_AD_IFINDEX:
> + case BPF_ANC | SKF_AD_HATYPE:
> + BUILD_BUG_ON(FIELD_SIZEOF(struct net_device,
> + ifindex) != 4);
> + BUILD_BUG_ON(FIELD_SIZEOF(struct net_device,
> + type) != 2);
> PPC_LD_OFFS(r_scratch1, r_skb, offsetof(struct sk_buff,
> dev));
> PPC_CMPDI(r_scratch1, 0);
> @@ -368,14 +373,18 @@ static int bpf_jit_build_body(struct bpf_prog *fp, u32 *image,
> PPC_BCC(COND_EQ, addrs[ctx->pc_ret0]);
> } else {
> /* Exit, returning 0; first pass hits here. */
> - PPC_BCC_SHORT(COND_NE, (ctx->idx*4)+12);
> + PPC_BCC_SHORT(COND_NE, ctx->idx * 4 + 12);
> PPC_LI(r_ret, 0);
> PPC_JMP(exit_addr);
> }
> - BUILD_BUG_ON(FIELD_SIZEOF(struct net_device,
> - ifindex) != 4);
> - PPC_LWZ_OFFS(r_A, r_scratch1,
> + if (code == (BPF_ANC | SKF_AD_IFINDEX)) {
> + PPC_LWZ_OFFS(r_A, r_scratch1,
> offsetof(struct net_device, ifindex));
> + } else {
> + PPC_LHZ_OFFS(r_A, r_scratch1,
> + offsetof(struct net_device, type));
formatting is a bit off here, but that's minor.
Acked-by: Alexei Starovoitov <ast@plumgrid.com>
^ permalink raw reply
* Re: [PATCH net-next] cxgb4: Remove unnecessary struct in6_addr * casts
From: David Miller @ 2014-11-10 18:28 UTC (permalink / raw)
To: joe
Cc: hariprasad, netdev, leedom, anish, praveenm, nirranjan, kumaras,
j.vosburgh, vfalico, andy
In-Reply-To: <1415335574.23530.4.camel@perches.com>
From: Joe Perches <joe@perches.com>
Date: Thu, 06 Nov 2014 20:46:14 -0800
> Just use the address of the in6_addr.
>
> Signed-off-by: Joe Perches <joe@perches.com>
Applied, thanks.
> ---
>> diff --git a/drivers/net/ethernet/chelsio/cxgb4/cxgb4_main.c b/drivers/net/ethernet/chelsio/cxgb4/cxgb4_main.c
> []
>> #include <../drivers/net/bonding/bonding.h>
>
> This include path seems unfortunate so I looked
> at the code a bit. I don't see an easy way to change it.
>
> Maybe some of bonding.h should be moved into a new file
> like 'include/net/bonding.h' or something.
I just committed the following into net-next, thanks for pointing
this out.
====================
[PATCH] net: Move bonding headers under include/net
This ways drivers like cxgb4 don't need to do ugly relative includes.
Reported-by: Joe Perches <joe@perches.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
---
drivers/net/bonding/bond_3ad.c | 4 +-
drivers/net/bonding/bond_3ad.h | 283 ----------
drivers/net/bonding/bond_alb.c | 4 +-
drivers/net/bonding/bond_alb.h | 181 -------
drivers/net/bonding/bond_debugfs.c | 4 +-
drivers/net/bonding/bond_main.c | 6 +-
drivers/net/bonding/bond_netlink.c | 2 +-
drivers/net/bonding/bond_options.c | 2 +-
drivers/net/bonding/bond_options.h | 130 -----
drivers/net/bonding/bond_procfs.c | 2 +-
drivers/net/bonding/bond_sysfs.c | 2 +-
drivers/net/bonding/bond_sysfs_slave.c | 2 +-
drivers/net/bonding/bonding.h | 654 ------------------------
drivers/net/ethernet/chelsio/cxgb4/cxgb4_main.c | 3 +-
include/net/bond_3ad.h | 283 ++++++++++
include/net/bond_alb.h | 181 +++++++
include/net/bond_options.h | 130 +++++
include/net/bonding.h | 654 ++++++++++++++++++++++++
18 files changed, 1263 insertions(+), 1264 deletions(-)
delete mode 100644 drivers/net/bonding/bond_3ad.h
delete mode 100644 drivers/net/bonding/bond_alb.h
delete mode 100644 drivers/net/bonding/bond_options.h
delete mode 100644 drivers/net/bonding/bonding.h
create mode 100644 include/net/bond_3ad.h
create mode 100644 include/net/bond_alb.h
create mode 100644 include/net/bond_options.h
create mode 100644 include/net/bonding.h
diff --git a/drivers/net/bonding/bond_3ad.c b/drivers/net/bonding/bond_3ad.c
index 2110215f..0a32143 100644
--- a/drivers/net/bonding/bond_3ad.c
+++ b/drivers/net/bonding/bond_3ad.c
@@ -29,8 +29,8 @@
#include <linux/if_bonding.h>
#include <linux/pkt_sched.h>
#include <net/net_namespace.h>
-#include "bonding.h"
-#include "bond_3ad.h"
+#include <net/bonding.h>
+#include <net/bond_3ad.h>
/* General definitions */
#define AD_SHORT_TIMEOUT 1
diff --git a/drivers/net/bonding/bond_3ad.h b/drivers/net/bonding/bond_3ad.h
deleted file mode 100644
index c5f14ac..0000000
--- a/drivers/net/bonding/bond_3ad.h
+++ /dev/null
@@ -1,283 +0,0 @@
-/*
- * Copyright(c) 1999 - 2004 Intel Corporation. All rights reserved.
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the Free
- * Software Foundation; either version 2 of the License, or (at your option)
- * any later version.
- *
- * This program is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
- * more details.
- *
- * You should have received a copy of the GNU General Public License along with
- * this program; if not, write to the Free Software Foundation, Inc., 59
- * Temple Place - Suite 330, Boston, MA 02111-1307, USA.
- *
- * The full GNU General Public License is included in this distribution in the
- * file called LICENSE.
- *
- */
-
-#ifndef __BOND_3AD_H__
-#define __BOND_3AD_H__
-
-#include <asm/byteorder.h>
-#include <linux/skbuff.h>
-#include <linux/netdevice.h>
-#include <linux/if_ether.h>
-
-/* General definitions */
-#define PKT_TYPE_LACPDU cpu_to_be16(ETH_P_SLOW)
-#define AD_TIMER_INTERVAL 100 /*msec*/
-
-#define MULTICAST_LACPDU_ADDR {0x01, 0x80, 0xC2, 0x00, 0x00, 0x02}
-
-#define AD_LACP_SLOW 0
-#define AD_LACP_FAST 1
-
-typedef struct mac_addr {
- u8 mac_addr_value[ETH_ALEN];
-} __packed mac_addr_t;
-
-enum {
- BOND_AD_STABLE = 0,
- BOND_AD_BANDWIDTH = 1,
- BOND_AD_COUNT = 2,
-};
-
-/* rx machine states(43.4.11 in the 802.3ad standard) */
-typedef enum {
- AD_RX_DUMMY,
- AD_RX_INITIALIZE, /* rx Machine */
- AD_RX_PORT_DISABLED, /* rx Machine */
- AD_RX_LACP_DISABLED, /* rx Machine */
- AD_RX_EXPIRED, /* rx Machine */
- AD_RX_DEFAULTED, /* rx Machine */
- AD_RX_CURRENT /* rx Machine */
-} rx_states_t;
-
-/* periodic machine states(43.4.12 in the 802.3ad standard) */
-typedef enum {
- AD_PERIODIC_DUMMY,
- AD_NO_PERIODIC, /* periodic machine */
- AD_FAST_PERIODIC, /* periodic machine */
- AD_SLOW_PERIODIC, /* periodic machine */
- AD_PERIODIC_TX /* periodic machine */
-} periodic_states_t;
-
-/* mux machine states(43.4.13 in the 802.3ad standard) */
-typedef enum {
- AD_MUX_DUMMY,
- AD_MUX_DETACHED, /* mux machine */
- AD_MUX_WAITING, /* mux machine */
- AD_MUX_ATTACHED, /* mux machine */
- AD_MUX_COLLECTING_DISTRIBUTING /* mux machine */
-} mux_states_t;
-
-/* tx machine states(43.4.15 in the 802.3ad standard) */
-typedef enum {
- AD_TX_DUMMY,
- AD_TRANSMIT /* tx Machine */
-} tx_states_t;
-
-/* rx indication types */
-typedef enum {
- AD_TYPE_LACPDU = 1, /* type lacpdu */
- AD_TYPE_MARKER /* type marker */
-} pdu_type_t;
-
-/* rx marker indication types */
-typedef enum {
- AD_MARKER_INFORMATION_SUBTYPE = 1, /* marker imformation subtype */
- AD_MARKER_RESPONSE_SUBTYPE /* marker response subtype */
-} bond_marker_subtype_t;
-
-/* timers types(43.4.9 in the 802.3ad standard) */
-typedef enum {
- AD_CURRENT_WHILE_TIMER,
- AD_ACTOR_CHURN_TIMER,
- AD_PERIODIC_TIMER,
- AD_PARTNER_CHURN_TIMER,
- AD_WAIT_WHILE_TIMER
-} ad_timers_t;
-
-#pragma pack(1)
-
-/* Link Aggregation Control Protocol(LACP) data unit structure(43.4.2.2 in the 802.3ad standard) */
-typedef struct lacpdu {
- u8 subtype; /* = LACP(= 0x01) */
- u8 version_number;
- u8 tlv_type_actor_info; /* = actor information(type/length/value) */
- u8 actor_information_length; /* = 20 */
- __be16 actor_system_priority;
- struct mac_addr actor_system;
- __be16 actor_key;
- __be16 actor_port_priority;
- __be16 actor_port;
- u8 actor_state;
- u8 reserved_3_1[3]; /* = 0 */
- u8 tlv_type_partner_info; /* = partner information */
- u8 partner_information_length; /* = 20 */
- __be16 partner_system_priority;
- struct mac_addr partner_system;
- __be16 partner_key;
- __be16 partner_port_priority;
- __be16 partner_port;
- u8 partner_state;
- u8 reserved_3_2[3]; /* = 0 */
- u8 tlv_type_collector_info; /* = collector information */
- u8 collector_information_length;/* = 16 */
- __be16 collector_max_delay;
- u8 reserved_12[12];
- u8 tlv_type_terminator; /* = terminator */
- u8 terminator_length; /* = 0 */
- u8 reserved_50[50]; /* = 0 */
-} __packed lacpdu_t;
-
-typedef struct lacpdu_header {
- struct ethhdr hdr;
- struct lacpdu lacpdu;
-} __packed lacpdu_header_t;
-
-/* Marker Protocol Data Unit(PDU) structure(43.5.3.2 in the 802.3ad standard) */
-typedef struct bond_marker {
- u8 subtype; /* = 0x02 (marker PDU) */
- u8 version_number; /* = 0x01 */
- u8 tlv_type; /* = 0x01 (marker information) */
- /* = 0x02 (marker response information) */
- u8 marker_length; /* = 0x16 */
- u16 requester_port; /* The number assigned to the port by the requester */
- struct mac_addr requester_system; /* The requester's system id */
- u32 requester_transaction_id; /* The transaction id allocated by the requester, */
- u16 pad; /* = 0 */
- u8 tlv_type_terminator; /* = 0x00 */
- u8 terminator_length; /* = 0x00 */
- u8 reserved_90[90]; /* = 0 */
-} __packed bond_marker_t;
-
-typedef struct bond_marker_header {
- struct ethhdr hdr;
- struct bond_marker marker;
-} __packed bond_marker_header_t;
-
-#pragma pack()
-
-struct slave;
-struct bonding;
-struct ad_info;
-struct port;
-
-#ifdef __ia64__
-#pragma pack(8)
-#endif
-
-/* aggregator structure(43.4.5 in the 802.3ad standard) */
-typedef struct aggregator {
- struct mac_addr aggregator_mac_address;
- u16 aggregator_identifier;
- bool is_individual;
- u16 actor_admin_aggregator_key;
- u16 actor_oper_aggregator_key;
- struct mac_addr partner_system;
- u16 partner_system_priority;
- u16 partner_oper_aggregator_key;
- u16 receive_state; /* BOOLEAN */
- u16 transmit_state; /* BOOLEAN */
- struct port *lag_ports;
- /* ****** PRIVATE PARAMETERS ****** */
- struct slave *slave; /* pointer to the bond slave that this aggregator belongs to */
- u16 is_active; /* BOOLEAN. Indicates if this aggregator is active */
- u16 num_of_ports;
-} aggregator_t;
-
-struct port_params {
- struct mac_addr system;
- u16 system_priority;
- u16 key;
- u16 port_number;
- u16 port_priority;
- u16 port_state;
-};
-
-/* port structure(43.4.6 in the 802.3ad standard) */
-typedef struct port {
- u16 actor_port_number;
- u16 actor_port_priority;
- struct mac_addr actor_system; /* This parameter is added here although it is not specified in the standard, just for simplification */
- u16 actor_system_priority; /* This parameter is added here although it is not specified in the standard, just for simplification */
- u16 actor_port_aggregator_identifier;
- bool ntt;
- u16 actor_admin_port_key;
- u16 actor_oper_port_key;
- u8 actor_admin_port_state;
- u8 actor_oper_port_state;
-
- struct port_params partner_admin;
- struct port_params partner_oper;
-
- bool is_enabled;
-
- /* ****** PRIVATE PARAMETERS ****** */
- u16 sm_vars; /* all state machines variables for this port */
- rx_states_t sm_rx_state; /* state machine rx state */
- u16 sm_rx_timer_counter; /* state machine rx timer counter */
- periodic_states_t sm_periodic_state; /* state machine periodic state */
- u16 sm_periodic_timer_counter; /* state machine periodic timer counter */
- mux_states_t sm_mux_state; /* state machine mux state */
- u16 sm_mux_timer_counter; /* state machine mux timer counter */
- tx_states_t sm_tx_state; /* state machine tx state */
- u16 sm_tx_timer_counter; /* state machine tx timer counter(allways on - enter to transmit state 3 time per second) */
- struct slave *slave; /* pointer to the bond slave that this port belongs to */
- struct aggregator *aggregator; /* pointer to an aggregator that this port related to */
- struct port *next_port_in_aggregator; /* Next port on the linked list of the parent aggregator */
- u32 transaction_id; /* continuous number for identification of Marker PDU's; */
- struct lacpdu lacpdu; /* the lacpdu that will be sent for this port */
-} port_t;
-
-/* system structure */
-struct ad_system {
- u16 sys_priority;
- struct mac_addr sys_mac_addr;
-};
-
-#ifdef __ia64__
-#pragma pack()
-#endif
-
-/* ========== AD Exported structures to the main bonding code ========== */
-#define BOND_AD_INFO(bond) ((bond)->ad_info)
-#define SLAVE_AD_INFO(slave) ((slave)->ad_info)
-
-struct ad_bond_info {
- struct ad_system system; /* 802.3ad system structure */
- u32 agg_select_timer; /* Timer to select aggregator after all adapter's hand shakes */
- u16 aggregator_identifier;
-};
-
-struct ad_slave_info {
- struct aggregator aggregator; /* 802.3ad aggregator structure */
- struct port port; /* 802.3ad port structure */
- u16 id;
-};
-
-/* ========== AD Exported functions to the main bonding code ========== */
-void bond_3ad_initialize(struct bonding *bond, u16 tick_resolution);
-void bond_3ad_bind_slave(struct slave *slave);
-void bond_3ad_unbind_slave(struct slave *slave);
-void bond_3ad_state_machine_handler(struct work_struct *);
-void bond_3ad_initiate_agg_selection(struct bonding *bond, int timeout);
-void bond_3ad_adapter_speed_changed(struct slave *slave);
-void bond_3ad_adapter_duplex_changed(struct slave *slave);
-void bond_3ad_handle_link_change(struct slave *slave, char link);
-int bond_3ad_get_active_agg_info(struct bonding *bond, struct ad_info *ad_info);
-int __bond_3ad_get_active_agg_info(struct bonding *bond,
- struct ad_info *ad_info);
-int bond_3ad_xmit_xor(struct sk_buff *skb, struct net_device *dev);
-int bond_3ad_lacpdu_recv(const struct sk_buff *skb, struct bonding *bond,
- struct slave *slave);
-int bond_3ad_set_carrier(struct bonding *bond);
-void bond_3ad_update_lacp_rate(struct bonding *bond);
-#endif /* __BOND_3AD_H__ */
-
diff --git a/drivers/net/bonding/bond_alb.c b/drivers/net/bonding/bond_alb.c
index baa58e7..e1f1a00 100644
--- a/drivers/net/bonding/bond_alb.c
+++ b/drivers/net/bonding/bond_alb.c
@@ -37,8 +37,8 @@
#include <net/arp.h>
#include <net/ipv6.h>
#include <asm/byteorder.h>
-#include "bonding.h"
-#include "bond_alb.h"
+#include <net/bonding.h>
+#include <net/bond_alb.h>
diff --git a/drivers/net/bonding/bond_alb.h b/drivers/net/bonding/bond_alb.h
deleted file mode 100644
index 1ad473b..0000000
--- a/drivers/net/bonding/bond_alb.h
+++ /dev/null
@@ -1,181 +0,0 @@
-/*
- * Copyright(c) 1999 - 2004 Intel Corporation. All rights reserved.
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
- * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, see <http://www.gnu.org/licenses/>.
- *
- * The full GNU General Public License is included in this distribution in the
- * file called LICENSE.
- *
- */
-
-#ifndef __BOND_ALB_H__
-#define __BOND_ALB_H__
-
-#include <linux/if_ether.h>
-
-struct bonding;
-struct slave;
-
-#define BOND_ALB_INFO(bond) ((bond)->alb_info)
-#define SLAVE_TLB_INFO(slave) ((slave)->tlb_info)
-
-#define ALB_TIMER_TICKS_PER_SEC 10 /* should be a divisor of HZ */
-#define BOND_TLB_REBALANCE_INTERVAL 10 /* In seconds, periodic re-balancing.
- * Used for division - never set
- * to zero !!!
- */
-#define BOND_ALB_DEFAULT_LP_INTERVAL 1
-#define BOND_ALB_LP_INTERVAL(bond) (bond->params.lp_interval) /* In seconds, periodic send of
- * learning packets to the switch
- */
-
-#define BOND_TLB_REBALANCE_TICKS (BOND_TLB_REBALANCE_INTERVAL \
- * ALB_TIMER_TICKS_PER_SEC)
-
-#define BOND_ALB_LP_TICKS(bond) (BOND_ALB_LP_INTERVAL(bond) \
- * ALB_TIMER_TICKS_PER_SEC)
-
-#define TLB_HASH_TABLE_SIZE 256 /* The size of the clients hash table.
- * Note that this value MUST NOT be smaller
- * because the key hash table is BYTE wide !
- */
-
-
-#define TLB_NULL_INDEX 0xffffffff
-
-/* rlb defs */
-#define RLB_HASH_TABLE_SIZE 256
-#define RLB_NULL_INDEX 0xffffffff
-#define RLB_UPDATE_DELAY (2*ALB_TIMER_TICKS_PER_SEC) /* 2 seconds */
-#define RLB_ARP_BURST_SIZE 2
-#define RLB_UPDATE_RETRY 3 /* 3-ticks - must be smaller than the rlb
- * rebalance interval (5 min).
- */
-/* RLB_PROMISC_TIMEOUT = 10 sec equals the time that the current slave is
- * promiscuous after failover
- */
-#define RLB_PROMISC_TIMEOUT (10*ALB_TIMER_TICKS_PER_SEC)
-
-
-struct tlb_client_info {
- struct slave *tx_slave; /* A pointer to slave used for transmiting
- * packets to a Client that the Hash function
- * gave this entry index.
- */
- u32 tx_bytes; /* Each Client accumulates the BytesTx that
- * were transmitted to it, and after each
- * CallBack the LoadHistory is divided
- * by the balance interval
- */
- u32 load_history; /* This field contains the amount of Bytes
- * that were transmitted to this client by
- * the server on the previous balance
- * interval in Bps.
- */
- u32 next; /* The next Hash table entry index, assigned
- * to use the same adapter for transmit.
- */
- u32 prev; /* The previous Hash table entry index,
- * assigned to use the same
- */
-};
-
-/* -------------------------------------------------------------------------
- * struct rlb_client_info contains all info related to a specific rx client
- * connection. This is the Clients Hash Table entry struct.
- * Note that this is not a proper hash table; if a new client's IP address
- * hash collides with an existing client entry, the old entry is replaced.
- *
- * There is a linked list (linked by the used_next and used_prev members)
- * linking all the used entries of the hash table. This allows updating
- * all the clients without walking over all the unused elements of the table.
- *
- * There are also linked lists of entries with identical hash(ip_src). These
- * allow cleaning up the table from ip_src<->mac_src associations that have
- * become outdated and would cause sending out invalid ARP updates to the
- * network. These are linked by the (src_next and src_prev members).
- * -------------------------------------------------------------------------
- */
-struct rlb_client_info {
- __be32 ip_src; /* the server IP address */
- __be32 ip_dst; /* the client IP address */
- u8 mac_src[ETH_ALEN]; /* the server MAC address */
- u8 mac_dst[ETH_ALEN]; /* the client MAC address */
-
- /* list of used hash table entries, starting at rx_hashtbl_used_head */
- u32 used_next;
- u32 used_prev;
-
- /* ip_src based hashing */
- u32 src_next; /* next entry with same hash(ip_src) */
- u32 src_prev; /* prev entry with same hash(ip_src) */
- u32 src_first; /* first entry with hash(ip_src) == this entry's index */
-
- u8 assigned; /* checking whether this entry is assigned */
- u8 ntt; /* flag - need to transmit client info */
- struct slave *slave; /* the slave assigned to this client */
- unsigned short vlan_id; /* VLAN tag associated with IP address */
-};
-
-struct tlb_slave_info {
- u32 head; /* Index to the head of the bi-directional clients
- * hash table entries list. The entries in the list
- * are the entries that were assigned to use this
- * slave for transmit.
- */
- u32 load; /* Each slave sums the loadHistory of all clients
- * assigned to it
- */
-};
-
-struct alb_bond_info {
- struct tlb_client_info *tx_hashtbl; /* Dynamically allocated */
- u32 unbalanced_load;
- int tx_rebalance_counter;
- int lp_counter;
- /* -------- rlb parameters -------- */
- int rlb_enabled;
- struct rlb_client_info *rx_hashtbl; /* Receive hash table */
- u32 rx_hashtbl_used_head;
- u8 rx_ntt; /* flag - need to transmit
- * to all rx clients
- */
- struct slave *rx_slave;/* last slave to xmit from */
- u8 primary_is_promisc; /* boolean */
- u32 rlb_promisc_timeout_counter;/* counts primary
- * promiscuity time
- */
- u32 rlb_update_delay_counter;
- u32 rlb_update_retry_counter;/* counter of retries
- * of client update
- */
- u8 rlb_rebalance; /* flag - indicates that the
- * rx traffic should be
- * rebalanced
- */
-};
-
-int bond_alb_initialize(struct bonding *bond, int rlb_enabled);
-void bond_alb_deinitialize(struct bonding *bond);
-int bond_alb_init_slave(struct bonding *bond, struct slave *slave);
-void bond_alb_deinit_slave(struct bonding *bond, struct slave *slave);
-void bond_alb_handle_link_change(struct bonding *bond, struct slave *slave, char link);
-void bond_alb_handle_active_change(struct bonding *bond, struct slave *new_slave);
-int bond_alb_xmit(struct sk_buff *skb, struct net_device *bond_dev);
-int bond_tlb_xmit(struct sk_buff *skb, struct net_device *bond_dev);
-void bond_alb_monitor(struct work_struct *);
-int bond_alb_set_mac_address(struct net_device *bond_dev, void *addr);
-void bond_alb_clear_vlan(struct bonding *bond, unsigned short vlan_id);
-#endif /* __BOND_ALB_H__ */
-
diff --git a/drivers/net/bonding/bond_debugfs.c b/drivers/net/bonding/bond_debugfs.c
index 8f99082..e52e25a 100644
--- a/drivers/net/bonding/bond_debugfs.c
+++ b/drivers/net/bonding/bond_debugfs.c
@@ -3,8 +3,8 @@
#include <linux/device.h>
#include <linux/netdevice.h>
-#include "bonding.h"
-#include "bond_alb.h"
+#include <net/bonding.h>
+#include <net/bond_alb.h>
#if defined(CONFIG_DEBUG_FS) && !defined(CONFIG_NET_NS)
diff --git a/drivers/net/bonding/bond_main.c b/drivers/net/bonding/bond_main.c
index c752008..b9b3456 100644
--- a/drivers/net/bonding/bond_main.c
+++ b/drivers/net/bonding/bond_main.c
@@ -77,9 +77,9 @@
#include <net/pkt_sched.h>
#include <linux/rculist.h>
#include <net/flow_keys.h>
-#include "bonding.h"
-#include "bond_3ad.h"
-#include "bond_alb.h"
+#include <net/bonding.h>
+#include <net/bond_3ad.h>
+#include <net/bond_alb.h>
/*---------------------------- Module parameters ----------------------------*/
diff --git a/drivers/net/bonding/bond_netlink.c b/drivers/net/bonding/bond_netlink.c
index c13d83e..3e6eebd 100644
--- a/drivers/net/bonding/bond_netlink.c
+++ b/drivers/net/bonding/bond_netlink.c
@@ -17,7 +17,7 @@
#include <linux/if_ether.h>
#include <net/netlink.h>
#include <net/rtnetlink.h>
-#include "bonding.h"
+#include <net/bonding.h>
static size_t bond_get_slave_size(const struct net_device *bond_dev,
const struct net_device *slave_dev)
diff --git a/drivers/net/bonding/bond_options.c b/drivers/net/bonding/bond_options.c
index b62697f..1a61cc9 100644
--- a/drivers/net/bonding/bond_options.c
+++ b/drivers/net/bonding/bond_options.c
@@ -16,7 +16,7 @@
#include <linux/rcupdate.h>
#include <linux/ctype.h>
#include <linux/inet.h>
-#include "bonding.h"
+#include <net/bonding.h>
static int bond_option_active_slave_set(struct bonding *bond,
const struct bond_opt_value *newval);
diff --git a/drivers/net/bonding/bond_options.h b/drivers/net/bonding/bond_options.h
deleted file mode 100644
index 17ded5b..0000000
--- a/drivers/net/bonding/bond_options.h
+++ /dev/null
@@ -1,130 +0,0 @@
-/*
- * drivers/net/bond/bond_options.h - bonding options
- * Copyright (c) 2013 Nikolay Aleksandrov <nikolay@redhat.com>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- */
-
-#ifndef _BOND_OPTIONS_H
-#define _BOND_OPTIONS_H
-
-#define BOND_OPT_MAX_NAMELEN 32
-#define BOND_OPT_VALID(opt) ((opt) < BOND_OPT_LAST)
-#define BOND_MODE_ALL_EX(x) (~(x))
-
-/* Option flags:
- * BOND_OPTFLAG_NOSLAVES - check if the bond device is empty before setting
- * BOND_OPTFLAG_IFDOWN - check if the bond device is down before setting
- * BOND_OPTFLAG_RAWVAL - the option parses the value itself
- */
-enum {
- BOND_OPTFLAG_NOSLAVES = BIT(0),
- BOND_OPTFLAG_IFDOWN = BIT(1),
- BOND_OPTFLAG_RAWVAL = BIT(2)
-};
-
-/* Value type flags:
- * BOND_VALFLAG_DEFAULT - mark the value as default
- * BOND_VALFLAG_(MIN|MAX) - mark the value as min/max
- */
-enum {
- BOND_VALFLAG_DEFAULT = BIT(0),
- BOND_VALFLAG_MIN = BIT(1),
- BOND_VALFLAG_MAX = BIT(2)
-};
-
-/* Option IDs, their bit positions correspond to their IDs */
-enum {
- BOND_OPT_MODE,
- BOND_OPT_PACKETS_PER_SLAVE,
- BOND_OPT_XMIT_HASH,
- BOND_OPT_ARP_VALIDATE,
- BOND_OPT_ARP_ALL_TARGETS,
- BOND_OPT_FAIL_OVER_MAC,
- BOND_OPT_ARP_INTERVAL,
- BOND_OPT_ARP_TARGETS,
- BOND_OPT_DOWNDELAY,
- BOND_OPT_UPDELAY,
- BOND_OPT_LACP_RATE,
- BOND_OPT_MINLINKS,
- BOND_OPT_AD_SELECT,
- BOND_OPT_NUM_PEER_NOTIF,
- BOND_OPT_MIIMON,
- BOND_OPT_PRIMARY,
- BOND_OPT_PRIMARY_RESELECT,
- BOND_OPT_USE_CARRIER,
- BOND_OPT_ACTIVE_SLAVE,
- BOND_OPT_QUEUE_ID,
- BOND_OPT_ALL_SLAVES_ACTIVE,
- BOND_OPT_RESEND_IGMP,
- BOND_OPT_LP_INTERVAL,
- BOND_OPT_SLAVES,
- BOND_OPT_TLB_DYNAMIC_LB,
- BOND_OPT_LAST
-};
-
-/* This structure is used for storing option values and for passing option
- * values when changing an option. The logic when used as an arg is as follows:
- * - if string != NULL -> parse it, if the opt is RAW type then return it, else
- * return the parse result
- * - if string == NULL -> parse value
- */
-struct bond_opt_value {
- char *string;
- u64 value;
- u32 flags;
-};
-
-struct bonding;
-
-struct bond_option {
- int id;
- const char *name;
- const char *desc;
- u32 flags;
-
- /* unsuppmodes is used to denote modes in which the option isn't
- * supported.
- */
- unsigned long unsuppmodes;
- /* supported values which this option can have, can be a subset of
- * BOND_OPTVAL_RANGE's value range
- */
- const struct bond_opt_value *values;
-
- int (*set)(struct bonding *bond, const struct bond_opt_value *val);
-};
-
-int __bond_opt_set(struct bonding *bond, unsigned int option,
- struct bond_opt_value *val);
-int bond_opt_tryset_rtnl(struct bonding *bond, unsigned int option, char *buf);
-
-const struct bond_opt_value *bond_opt_parse(const struct bond_option *opt,
- struct bond_opt_value *val);
-const struct bond_option *bond_opt_get(unsigned int option);
-const struct bond_option *bond_opt_get_by_name(const char *name);
-const struct bond_opt_value *bond_opt_get_val(unsigned int option, u64 val);
-
-/* This helper is used to initialize a bond_opt_value structure for parameter
- * passing. There should be either a valid string or value, but not both.
- * When value is ULLONG_MAX then string will be used.
- */
-static inline void __bond_opt_init(struct bond_opt_value *optval,
- char *string, u64 value)
-{
- memset(optval, 0, sizeof(*optval));
- optval->value = ULLONG_MAX;
- if (value == ULLONG_MAX)
- optval->string = string;
- else
- optval->value = value;
-}
-#define bond_opt_initval(optval, value) __bond_opt_init(optval, NULL, value)
-#define bond_opt_initstr(optval, str) __bond_opt_init(optval, str, ULLONG_MAX)
-
-void bond_option_arp_ip_targets_clear(struct bonding *bond);
-
-#endif /* _BOND_OPTIONS_H */
diff --git a/drivers/net/bonding/bond_procfs.c b/drivers/net/bonding/bond_procfs.c
index a3948f8..976f5ad 100644
--- a/drivers/net/bonding/bond_procfs.c
+++ b/drivers/net/bonding/bond_procfs.c
@@ -2,7 +2,7 @@
#include <linux/export.h>
#include <net/net_namespace.h>
#include <net/netns/generic.h>
-#include "bonding.h"
+#include <net/bonding.h>
static void *bond_info_seq_start(struct seq_file *seq, loff_t *pos)
diff --git a/drivers/net/bonding/bond_sysfs.c b/drivers/net/bonding/bond_sysfs.c
index 8ffbafd..7e9e151 100644
--- a/drivers/net/bonding/bond_sysfs.c
+++ b/drivers/net/bonding/bond_sysfs.c
@@ -40,7 +40,7 @@
#include <net/netns/generic.h>
#include <linux/nsproxy.h>
-#include "bonding.h"
+#include <net/bonding.h>
#define to_dev(obj) container_of(obj, struct device, kobj)
#define to_bond(cd) ((struct bonding *)(netdev_priv(to_net_dev(cd))))
diff --git a/drivers/net/bonding/bond_sysfs_slave.c b/drivers/net/bonding/bond_sysfs_slave.c
index b01b0ce..23618a8 100644
--- a/drivers/net/bonding/bond_sysfs_slave.c
+++ b/drivers/net/bonding/bond_sysfs_slave.c
@@ -12,7 +12,7 @@
#include <linux/kernel.h>
#include <linux/netdevice.h>
-#include "bonding.h"
+#include <net/bonding.h>
struct slave_attribute {
struct attribute attr;
diff --git a/drivers/net/bonding/bonding.h b/drivers/net/bonding/bonding.h
deleted file mode 100644
index bfb0b51..0000000
--- a/drivers/net/bonding/bonding.h
+++ /dev/null
@@ -1,654 +0,0 @@
-/*
- * Bond several ethernet interfaces into a Cisco, running 'Etherchannel'.
- *
- * Portions are (c) Copyright 1995 Simon "Guru Aleph-Null" Janes
- * NCM: Network and Communications Management, Inc.
- *
- * BUT, I'm the one who modified it for ethernet, so:
- * (c) Copyright 1999, Thomas Davis, tadavis@lbl.gov
- *
- * This software may be used and distributed according to the terms
- * of the GNU Public License, incorporated herein by reference.
- *
- */
-
-#ifndef _LINUX_BONDING_H
-#define _LINUX_BONDING_H
-
-#include <linux/timer.h>
-#include <linux/proc_fs.h>
-#include <linux/if_bonding.h>
-#include <linux/cpumask.h>
-#include <linux/in6.h>
-#include <linux/netpoll.h>
-#include <linux/inetdevice.h>
-#include <linux/etherdevice.h>
-#include <linux/reciprocal_div.h>
-#include <linux/if_link.h>
-
-#include "bond_3ad.h"
-#include "bond_alb.h"
-#include "bond_options.h"
-
-#define DRV_VERSION "3.7.1"
-#define DRV_RELDATE "April 27, 2011"
-#define DRV_NAME "bonding"
-#define DRV_DESCRIPTION "Ethernet Channel Bonding Driver"
-
-#define bond_version DRV_DESCRIPTION ": v" DRV_VERSION " (" DRV_RELDATE ")\n"
-
-#define BOND_MAX_ARP_TARGETS 16
-
-#define BOND_DEFAULT_MIIMON 100
-
-/*
- * Less bad way to call ioctl from within the kernel; this needs to be
- * done some other way to get the call out of interrupt context.
- * Needs "ioctl" variable to be supplied by calling context.
- */
-#define IOCTL(dev, arg, cmd) ({ \
- int res = 0; \
- mm_segment_t fs = get_fs(); \
- set_fs(get_ds()); \
- res = ioctl(dev, arg, cmd); \
- set_fs(fs); \
- res; })
-
-#define BOND_MODE(bond) ((bond)->params.mode)
-
-/* slave list primitives */
-#define bond_slave_list(bond) (&(bond)->dev->adj_list.lower)
-
-#define bond_has_slaves(bond) !list_empty(bond_slave_list(bond))
-
-/* IMPORTANT: bond_first/last_slave can return NULL in case of an empty list */
-#define bond_first_slave(bond) \
- (bond_has_slaves(bond) ? \
- netdev_adjacent_get_private(bond_slave_list(bond)->next) : \
- NULL)
-#define bond_last_slave(bond) \
- (bond_has_slaves(bond) ? \
- netdev_adjacent_get_private(bond_slave_list(bond)->prev) : \
- NULL)
-
-/* Caller must have rcu_read_lock */
-#define bond_first_slave_rcu(bond) \
- netdev_lower_get_first_private_rcu(bond->dev)
-
-#define bond_is_first_slave(bond, pos) (pos == bond_first_slave(bond))
-#define bond_is_last_slave(bond, pos) (pos == bond_last_slave(bond))
-
-/**
- * bond_for_each_slave - iterate over all slaves
- * @bond: the bond holding this list
- * @pos: current slave
- * @iter: list_head * iterator
- *
- * Caller must hold RTNL
- */
-#define bond_for_each_slave(bond, pos, iter) \
- netdev_for_each_lower_private((bond)->dev, pos, iter)
-
-/* Caller must have rcu_read_lock */
-#define bond_for_each_slave_rcu(bond, pos, iter) \
- netdev_for_each_lower_private_rcu((bond)->dev, pos, iter)
-
-#ifdef CONFIG_NET_POLL_CONTROLLER
-extern atomic_t netpoll_block_tx;
-
-static inline void block_netpoll_tx(void)
-{
- atomic_inc(&netpoll_block_tx);
-}
-
-static inline void unblock_netpoll_tx(void)
-{
- atomic_dec(&netpoll_block_tx);
-}
-
-static inline int is_netpoll_tx_blocked(struct net_device *dev)
-{
- if (unlikely(netpoll_tx_running(dev)))
- return atomic_read(&netpoll_block_tx);
- return 0;
-}
-#else
-#define block_netpoll_tx()
-#define unblock_netpoll_tx()
-#define is_netpoll_tx_blocked(dev) (0)
-#endif
-
-struct bond_params {
- int mode;
- int xmit_policy;
- int miimon;
- u8 num_peer_notif;
- int arp_interval;
- int arp_validate;
- int arp_all_targets;
- int use_carrier;
- int fail_over_mac;
- int updelay;
- int downdelay;
- int lacp_fast;
- unsigned int min_links;
- int ad_select;
- char primary[IFNAMSIZ];
- int primary_reselect;
- __be32 arp_targets[BOND_MAX_ARP_TARGETS];
- int tx_queues;
- int all_slaves_active;
- int resend_igmp;
- int lp_interval;
- int packets_per_slave;
- int tlb_dynamic_lb;
- struct reciprocal_value reciprocal_packets_per_slave;
-};
-
-struct bond_parm_tbl {
- char *modename;
- int mode;
-};
-
-struct slave {
- struct net_device *dev; /* first - useful for panic debug */
- struct bonding *bond; /* our master */
- int delay;
- /* all three in jiffies */
- unsigned long last_link_up;
- unsigned long last_rx;
- unsigned long target_last_arp_rx[BOND_MAX_ARP_TARGETS];
- s8 link; /* one of BOND_LINK_XXXX */
- s8 new_link;
- u8 backup:1, /* indicates backup slave. Value corresponds with
- BOND_STATE_ACTIVE and BOND_STATE_BACKUP */
- inactive:1, /* indicates inactive slave */
- should_notify:1; /* indicateds whether the state changed */
- u8 duplex;
- u32 original_mtu;
- u32 link_failure_count;
- u32 speed;
- u16 queue_id;
- u8 perm_hwaddr[ETH_ALEN];
- struct ad_slave_info *ad_info;
- struct tlb_slave_info tlb_info;
-#ifdef CONFIG_NET_POLL_CONTROLLER
- struct netpoll *np;
-#endif
- struct kobject kobj;
- struct rtnl_link_stats64 slave_stats;
-};
-
-struct bond_up_slave {
- unsigned int count;
- struct rcu_head rcu;
- struct slave *arr[0];
-};
-
-/*
- * Link pseudo-state only used internally by monitors
- */
-#define BOND_LINK_NOCHANGE -1
-
-/*
- * Here are the locking policies for the two bonding locks:
- * Get rcu_read_lock when reading or RTNL when writing slave list.
- */
-struct bonding {
- struct net_device *dev; /* first - useful for panic debug */
- struct slave __rcu *curr_active_slave;
- struct slave __rcu *current_arp_slave;
- struct slave __rcu *primary_slave;
- struct bond_up_slave __rcu *slave_arr; /* Array of usable slaves */
- bool force_primary;
- s32 slave_cnt; /* never change this value outside the attach/detach wrappers */
- int (*recv_probe)(const struct sk_buff *, struct bonding *,
- struct slave *);
- /* mode_lock is used for mode-specific locking needs, currently used by:
- * 3ad mode (4) - protect against running bond_3ad_unbind_slave() and
- * bond_3ad_state_machine_handler() concurrently and also
- * the access to the state machine shared variables.
- * TLB mode (5) - to sync the use and modifications of its hash table
- * ALB mode (6) - to sync the use and modifications of its hash table
- */
- spinlock_t mode_lock;
- u8 send_peer_notif;
- u8 igmp_retrans;
-#ifdef CONFIG_PROC_FS
- struct proc_dir_entry *proc_entry;
- char proc_file_name[IFNAMSIZ];
-#endif /* CONFIG_PROC_FS */
- struct list_head bond_list;
- u32 rr_tx_counter;
- struct ad_bond_info ad_info;
- struct alb_bond_info alb_info;
- struct bond_params params;
- struct workqueue_struct *wq;
- struct delayed_work mii_work;
- struct delayed_work arp_work;
- struct delayed_work alb_work;
- struct delayed_work ad_work;
- struct delayed_work mcast_work;
- struct delayed_work slave_arr_work;
-#ifdef CONFIG_DEBUG_FS
- /* debugging support via debugfs */
- struct dentry *debug_dir;
-#endif /* CONFIG_DEBUG_FS */
- struct rtnl_link_stats64 bond_stats;
-};
-
-#define bond_slave_get_rcu(dev) \
- ((struct slave *) rcu_dereference(dev->rx_handler_data))
-
-#define bond_slave_get_rtnl(dev) \
- ((struct slave *) rtnl_dereference(dev->rx_handler_data))
-
-struct bond_vlan_tag {
- __be16 vlan_proto;
- unsigned short vlan_id;
-};
-
-/**
- * Returns NULL if the net_device does not belong to any of the bond's slaves
- *
- * Caller must hold bond lock for read
- */
-static inline struct slave *bond_get_slave_by_dev(struct bonding *bond,
- struct net_device *slave_dev)
-{
- return netdev_lower_dev_get_private(bond->dev, slave_dev);
-}
-
-static inline struct bonding *bond_get_bond_by_slave(struct slave *slave)
-{
- return slave->bond;
-}
-
-static inline bool bond_should_override_tx_queue(struct bonding *bond)
-{
- return BOND_MODE(bond) == BOND_MODE_ACTIVEBACKUP ||
- BOND_MODE(bond) == BOND_MODE_ROUNDROBIN;
-}
-
-static inline bool bond_is_lb(const struct bonding *bond)
-{
- return BOND_MODE(bond) == BOND_MODE_TLB ||
- BOND_MODE(bond) == BOND_MODE_ALB;
-}
-
-static inline bool bond_is_nondyn_tlb(const struct bonding *bond)
-{
- return (BOND_MODE(bond) == BOND_MODE_TLB) &&
- (bond->params.tlb_dynamic_lb == 0);
-}
-
-static inline bool bond_mode_uses_xmit_hash(const struct bonding *bond)
-{
- return (BOND_MODE(bond) == BOND_MODE_8023AD ||
- BOND_MODE(bond) == BOND_MODE_XOR ||
- bond_is_nondyn_tlb(bond));
-}
-
-static inline bool bond_mode_uses_arp(int mode)
-{
- return mode != BOND_MODE_8023AD && mode != BOND_MODE_TLB &&
- mode != BOND_MODE_ALB;
-}
-
-static inline bool bond_mode_uses_primary(int mode)
-{
- return mode == BOND_MODE_ACTIVEBACKUP || mode == BOND_MODE_TLB ||
- mode == BOND_MODE_ALB;
-}
-
-static inline bool bond_uses_primary(struct bonding *bond)
-{
- return bond_mode_uses_primary(BOND_MODE(bond));
-}
-
-static inline bool bond_slave_is_up(struct slave *slave)
-{
- return netif_running(slave->dev) && netif_carrier_ok(slave->dev);
-}
-
-static inline void bond_set_active_slave(struct slave *slave)
-{
- if (slave->backup) {
- slave->backup = 0;
- rtmsg_ifinfo(RTM_NEWLINK, slave->dev, 0, GFP_ATOMIC);
- }
-}
-
-static inline void bond_set_backup_slave(struct slave *slave)
-{
- if (!slave->backup) {
- slave->backup = 1;
- rtmsg_ifinfo(RTM_NEWLINK, slave->dev, 0, GFP_ATOMIC);
- }
-}
-
-static inline void bond_set_slave_state(struct slave *slave,
- int slave_state, bool notify)
-{
- if (slave->backup == slave_state)
- return;
-
- slave->backup = slave_state;
- if (notify) {
- rtmsg_ifinfo(RTM_NEWLINK, slave->dev, 0, GFP_ATOMIC);
- slave->should_notify = 0;
- } else {
- if (slave->should_notify)
- slave->should_notify = 0;
- else
- slave->should_notify = 1;
- }
-}
-
-static inline void bond_slave_state_change(struct bonding *bond)
-{
- struct list_head *iter;
- struct slave *tmp;
-
- bond_for_each_slave(bond, tmp, iter) {
- if (tmp->link == BOND_LINK_UP)
- bond_set_active_slave(tmp);
- else if (tmp->link == BOND_LINK_DOWN)
- bond_set_backup_slave(tmp);
- }
-}
-
-static inline void bond_slave_state_notify(struct bonding *bond)
-{
- struct list_head *iter;
- struct slave *tmp;
-
- bond_for_each_slave(bond, tmp, iter) {
- if (tmp->should_notify) {
- rtmsg_ifinfo(RTM_NEWLINK, tmp->dev, 0, GFP_ATOMIC);
- tmp->should_notify = 0;
- }
- }
-}
-
-static inline int bond_slave_state(struct slave *slave)
-{
- return slave->backup;
-}
-
-static inline bool bond_is_active_slave(struct slave *slave)
-{
- return !bond_slave_state(slave);
-}
-
-static inline bool bond_slave_can_tx(struct slave *slave)
-{
- return bond_slave_is_up(slave) && slave->link == BOND_LINK_UP &&
- bond_is_active_slave(slave);
-}
-
-#define BOND_PRI_RESELECT_ALWAYS 0
-#define BOND_PRI_RESELECT_BETTER 1
-#define BOND_PRI_RESELECT_FAILURE 2
-
-#define BOND_FOM_NONE 0
-#define BOND_FOM_ACTIVE 1
-#define BOND_FOM_FOLLOW 2
-
-#define BOND_ARP_TARGETS_ANY 0
-#define BOND_ARP_TARGETS_ALL 1
-
-#define BOND_ARP_VALIDATE_NONE 0
-#define BOND_ARP_VALIDATE_ACTIVE (1 << BOND_STATE_ACTIVE)
-#define BOND_ARP_VALIDATE_BACKUP (1 << BOND_STATE_BACKUP)
-#define BOND_ARP_VALIDATE_ALL (BOND_ARP_VALIDATE_ACTIVE | \
- BOND_ARP_VALIDATE_BACKUP)
-#define BOND_ARP_FILTER (BOND_ARP_VALIDATE_ALL + 1)
-#define BOND_ARP_FILTER_ACTIVE (BOND_ARP_VALIDATE_ACTIVE | \
- BOND_ARP_FILTER)
-#define BOND_ARP_FILTER_BACKUP (BOND_ARP_VALIDATE_BACKUP | \
- BOND_ARP_FILTER)
-
-#define BOND_SLAVE_NOTIFY_NOW true
-#define BOND_SLAVE_NOTIFY_LATER false
-
-static inline int slave_do_arp_validate(struct bonding *bond,
- struct slave *slave)
-{
- return bond->params.arp_validate & (1 << bond_slave_state(slave));
-}
-
-static inline int slave_do_arp_validate_only(struct bonding *bond)
-{
- return bond->params.arp_validate & BOND_ARP_FILTER;
-}
-
-static inline int bond_is_ip_target_ok(__be32 addr)
-{
- return !ipv4_is_lbcast(addr) && !ipv4_is_zeronet(addr);
-}
-
-/* Get the oldest arp which we've received on this slave for bond's
- * arp_targets.
- */
-static inline unsigned long slave_oldest_target_arp_rx(struct bonding *bond,
- struct slave *slave)
-{
- int i = 1;
- unsigned long ret = slave->target_last_arp_rx[0];
-
- for (; (i < BOND_MAX_ARP_TARGETS) && bond->params.arp_targets[i]; i++)
- if (time_before(slave->target_last_arp_rx[i], ret))
- ret = slave->target_last_arp_rx[i];
-
- return ret;
-}
-
-static inline unsigned long slave_last_rx(struct bonding *bond,
- struct slave *slave)
-{
- if (bond->params.arp_all_targets == BOND_ARP_TARGETS_ALL)
- return slave_oldest_target_arp_rx(bond, slave);
-
- return slave->last_rx;
-}
-
-#ifdef CONFIG_NET_POLL_CONTROLLER
-static inline void bond_netpoll_send_skb(const struct slave *slave,
- struct sk_buff *skb)
-{
- struct netpoll *np = slave->np;
-
- if (np)
- netpoll_send_skb(np, skb);
-}
-#else
-static inline void bond_netpoll_send_skb(const struct slave *slave,
- struct sk_buff *skb)
-{
-}
-#endif
-
-static inline void bond_set_slave_inactive_flags(struct slave *slave,
- bool notify)
-{
- if (!bond_is_lb(slave->bond))
- bond_set_slave_state(slave, BOND_STATE_BACKUP, notify);
- if (!slave->bond->params.all_slaves_active)
- slave->inactive = 1;
-}
-
-static inline void bond_set_slave_active_flags(struct slave *slave,
- bool notify)
-{
- bond_set_slave_state(slave, BOND_STATE_ACTIVE, notify);
- slave->inactive = 0;
-}
-
-static inline bool bond_is_slave_inactive(struct slave *slave)
-{
- return slave->inactive;
-}
-
-static inline __be32 bond_confirm_addr(struct net_device *dev, __be32 dst, __be32 local)
-{
- struct in_device *in_dev;
- __be32 addr = 0;
-
- rcu_read_lock();
- in_dev = __in_dev_get_rcu(dev);
-
- if (in_dev)
- addr = inet_confirm_addr(dev_net(dev), in_dev, dst, local,
- RT_SCOPE_HOST);
- rcu_read_unlock();
- return addr;
-}
-
-struct bond_net {
- struct net *net; /* Associated network namespace */
- struct list_head dev_list;
-#ifdef CONFIG_PROC_FS
- struct proc_dir_entry *proc_dir;
-#endif
- struct class_attribute class_attr_bonding_masters;
-};
-
-int bond_arp_rcv(const struct sk_buff *skb, struct bonding *bond, struct slave *slave);
-void bond_dev_queue_xmit(struct bonding *bond, struct sk_buff *skb, struct net_device *slave_dev);
-int bond_create(struct net *net, const char *name);
-int bond_create_sysfs(struct bond_net *net);
-void bond_destroy_sysfs(struct bond_net *net);
-void bond_prepare_sysfs_group(struct bonding *bond);
-int bond_sysfs_slave_add(struct slave *slave);
-void bond_sysfs_slave_del(struct slave *slave);
-int bond_enslave(struct net_device *bond_dev, struct net_device *slave_dev);
-int bond_release(struct net_device *bond_dev, struct net_device *slave_dev);
-u32 bond_xmit_hash(struct bonding *bond, struct sk_buff *skb);
-void bond_select_active_slave(struct bonding *bond);
-void bond_change_active_slave(struct bonding *bond, struct slave *new_active);
-void bond_create_debugfs(void);
-void bond_destroy_debugfs(void);
-void bond_debug_register(struct bonding *bond);
-void bond_debug_unregister(struct bonding *bond);
-void bond_debug_reregister(struct bonding *bond);
-const char *bond_mode_name(int mode);
-void bond_setup(struct net_device *bond_dev);
-unsigned int bond_get_num_tx_queues(void);
-int bond_netlink_init(void);
-void bond_netlink_fini(void);
-struct net_device *bond_option_active_slave_get_rcu(struct bonding *bond);
-const char *bond_slave_link_status(s8 link);
-struct bond_vlan_tag *bond_verify_device_path(struct net_device *start_dev,
- struct net_device *end_dev,
- int level);
-int bond_update_slave_arr(struct bonding *bond, struct slave *skipslave);
-void bond_slave_arr_work_rearm(struct bonding *bond, unsigned long delay);
-
-#ifdef CONFIG_PROC_FS
-void bond_create_proc_entry(struct bonding *bond);
-void bond_remove_proc_entry(struct bonding *bond);
-void bond_create_proc_dir(struct bond_net *bn);
-void bond_destroy_proc_dir(struct bond_net *bn);
-#else
-static inline void bond_create_proc_entry(struct bonding *bond)
-{
-}
-
-static inline void bond_remove_proc_entry(struct bonding *bond)
-{
-}
-
-static inline void bond_create_proc_dir(struct bond_net *bn)
-{
-}
-
-static inline void bond_destroy_proc_dir(struct bond_net *bn)
-{
-}
-#endif
-
-static inline struct slave *bond_slave_has_mac(struct bonding *bond,
- const u8 *mac)
-{
- struct list_head *iter;
- struct slave *tmp;
-
- bond_for_each_slave(bond, tmp, iter)
- if (ether_addr_equal_64bits(mac, tmp->dev->dev_addr))
- return tmp;
-
- return NULL;
-}
-
-/* Caller must hold rcu_read_lock() for read */
-static inline struct slave *bond_slave_has_mac_rcu(struct bonding *bond,
- const u8 *mac)
-{
- struct list_head *iter;
- struct slave *tmp;
-
- bond_for_each_slave_rcu(bond, tmp, iter)
- if (ether_addr_equal_64bits(mac, tmp->dev->dev_addr))
- return tmp;
-
- return NULL;
-}
-
-/* Caller must hold rcu_read_lock() for read */
-static inline bool bond_slave_has_mac_rx(struct bonding *bond, const u8 *mac)
-{
- struct list_head *iter;
- struct slave *tmp;
- struct netdev_hw_addr *ha;
-
- bond_for_each_slave_rcu(bond, tmp, iter)
- if (ether_addr_equal_64bits(mac, tmp->dev->dev_addr))
- return true;
-
- if (netdev_uc_empty(bond->dev))
- return false;
-
- netdev_for_each_uc_addr(ha, bond->dev)
- if (ether_addr_equal_64bits(mac, ha->addr))
- return true;
-
- return false;
-}
-
-/* Check if the ip is present in arp ip list, or first free slot if ip == 0
- * Returns -1 if not found, index if found
- */
-static inline int bond_get_targets_ip(__be32 *targets, __be32 ip)
-{
- int i;
-
- for (i = 0; i < BOND_MAX_ARP_TARGETS; i++)
- if (targets[i] == ip)
- return i;
- else if (targets[i] == 0)
- break;
-
- return -1;
-}
-
-/* exported from bond_main.c */
-extern int bond_net_id;
-extern const struct bond_parm_tbl bond_lacp_tbl[];
-extern const struct bond_parm_tbl xmit_hashtype_tbl[];
-extern const struct bond_parm_tbl arp_validate_tbl[];
-extern const struct bond_parm_tbl arp_all_targets_tbl[];
-extern const struct bond_parm_tbl fail_over_mac_tbl[];
-extern const struct bond_parm_tbl pri_reselect_tbl[];
-extern struct bond_parm_tbl ad_select_tbl[];
-
-/* exported from bond_netlink.c */
-extern struct rtnl_link_ops bond_link_ops;
-
-static inline void bond_tx_drop(struct net_device *dev, struct sk_buff *skb)
-{
- atomic_long_inc(&dev->tx_dropped);
- dev_kfree_skb_any(skb);
-}
-
-#endif /* _LINUX_BONDING_H */
diff --git a/drivers/net/ethernet/chelsio/cxgb4/cxgb4_main.c b/drivers/net/ethernet/chelsio/cxgb4/cxgb4_main.c
index a9c117f..d13d36a 100644
--- a/drivers/net/ethernet/chelsio/cxgb4/cxgb4_main.c
+++ b/drivers/net/ethernet/chelsio/cxgb4/cxgb4_main.c
@@ -61,6 +61,7 @@
#include <net/neighbour.h>
#include <net/netevent.h>
#include <net/addrconf.h>
+#include <net/bonding.h>
#include <asm/uaccess.h>
#include "cxgb4.h"
@@ -71,8 +72,6 @@
#include "cxgb4_debugfs.h"
#include "l2t.h"
-#include <../drivers/net/bonding/bonding.h>
-
#ifdef DRV_VERSION
#undef DRV_VERSION
#endif
diff --git a/include/net/bond_3ad.h b/include/net/bond_3ad.h
new file mode 100644
index 0000000..e01d903
--- /dev/null
+++ b/include/net/bond_3ad.h
@@ -0,0 +1,283 @@
+/*
+ * Copyright(c) 1999 - 2004 Intel Corporation. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the Free
+ * Software Foundation; either version 2 of the License, or (at your option)
+ * any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program; if not, write to the Free Software Foundation, Inc., 59
+ * Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ * The full GNU General Public License is included in this distribution in the
+ * file called LICENSE.
+ *
+ */
+
+#ifndef _NET_BOND_3AD_H
+#define _NET_BOND_3AD_H
+
+#include <asm/byteorder.h>
+#include <linux/skbuff.h>
+#include <linux/netdevice.h>
+#include <linux/if_ether.h>
+
+/* General definitions */
+#define PKT_TYPE_LACPDU cpu_to_be16(ETH_P_SLOW)
+#define AD_TIMER_INTERVAL 100 /*msec*/
+
+#define MULTICAST_LACPDU_ADDR {0x01, 0x80, 0xC2, 0x00, 0x00, 0x02}
+
+#define AD_LACP_SLOW 0
+#define AD_LACP_FAST 1
+
+typedef struct mac_addr {
+ u8 mac_addr_value[ETH_ALEN];
+} __packed mac_addr_t;
+
+enum {
+ BOND_AD_STABLE = 0,
+ BOND_AD_BANDWIDTH = 1,
+ BOND_AD_COUNT = 2,
+};
+
+/* rx machine states(43.4.11 in the 802.3ad standard) */
+typedef enum {
+ AD_RX_DUMMY,
+ AD_RX_INITIALIZE, /* rx Machine */
+ AD_RX_PORT_DISABLED, /* rx Machine */
+ AD_RX_LACP_DISABLED, /* rx Machine */
+ AD_RX_EXPIRED, /* rx Machine */
+ AD_RX_DEFAULTED, /* rx Machine */
+ AD_RX_CURRENT /* rx Machine */
+} rx_states_t;
+
+/* periodic machine states(43.4.12 in the 802.3ad standard) */
+typedef enum {
+ AD_PERIODIC_DUMMY,
+ AD_NO_PERIODIC, /* periodic machine */
+ AD_FAST_PERIODIC, /* periodic machine */
+ AD_SLOW_PERIODIC, /* periodic machine */
+ AD_PERIODIC_TX /* periodic machine */
+} periodic_states_t;
+
+/* mux machine states(43.4.13 in the 802.3ad standard) */
+typedef enum {
+ AD_MUX_DUMMY,
+ AD_MUX_DETACHED, /* mux machine */
+ AD_MUX_WAITING, /* mux machine */
+ AD_MUX_ATTACHED, /* mux machine */
+ AD_MUX_COLLECTING_DISTRIBUTING /* mux machine */
+} mux_states_t;
+
+/* tx machine states(43.4.15 in the 802.3ad standard) */
+typedef enum {
+ AD_TX_DUMMY,
+ AD_TRANSMIT /* tx Machine */
+} tx_states_t;
+
+/* rx indication types */
+typedef enum {
+ AD_TYPE_LACPDU = 1, /* type lacpdu */
+ AD_TYPE_MARKER /* type marker */
+} pdu_type_t;
+
+/* rx marker indication types */
+typedef enum {
+ AD_MARKER_INFORMATION_SUBTYPE = 1, /* marker imformation subtype */
+ AD_MARKER_RESPONSE_SUBTYPE /* marker response subtype */
+} bond_marker_subtype_t;
+
+/* timers types(43.4.9 in the 802.3ad standard) */
+typedef enum {
+ AD_CURRENT_WHILE_TIMER,
+ AD_ACTOR_CHURN_TIMER,
+ AD_PERIODIC_TIMER,
+ AD_PARTNER_CHURN_TIMER,
+ AD_WAIT_WHILE_TIMER
+} ad_timers_t;
+
+#pragma pack(1)
+
+/* Link Aggregation Control Protocol(LACP) data unit structure(43.4.2.2 in the 802.3ad standard) */
+typedef struct lacpdu {
+ u8 subtype; /* = LACP(= 0x01) */
+ u8 version_number;
+ u8 tlv_type_actor_info; /* = actor information(type/length/value) */
+ u8 actor_information_length; /* = 20 */
+ __be16 actor_system_priority;
+ struct mac_addr actor_system;
+ __be16 actor_key;
+ __be16 actor_port_priority;
+ __be16 actor_port;
+ u8 actor_state;
+ u8 reserved_3_1[3]; /* = 0 */
+ u8 tlv_type_partner_info; /* = partner information */
+ u8 partner_information_length; /* = 20 */
+ __be16 partner_system_priority;
+ struct mac_addr partner_system;
+ __be16 partner_key;
+ __be16 partner_port_priority;
+ __be16 partner_port;
+ u8 partner_state;
+ u8 reserved_3_2[3]; /* = 0 */
+ u8 tlv_type_collector_info; /* = collector information */
+ u8 collector_information_length;/* = 16 */
+ __be16 collector_max_delay;
+ u8 reserved_12[12];
+ u8 tlv_type_terminator; /* = terminator */
+ u8 terminator_length; /* = 0 */
+ u8 reserved_50[50]; /* = 0 */
+} __packed lacpdu_t;
+
+typedef struct lacpdu_header {
+ struct ethhdr hdr;
+ struct lacpdu lacpdu;
+} __packed lacpdu_header_t;
+
+/* Marker Protocol Data Unit(PDU) structure(43.5.3.2 in the 802.3ad standard) */
+typedef struct bond_marker {
+ u8 subtype; /* = 0x02 (marker PDU) */
+ u8 version_number; /* = 0x01 */
+ u8 tlv_type; /* = 0x01 (marker information) */
+ /* = 0x02 (marker response information) */
+ u8 marker_length; /* = 0x16 */
+ u16 requester_port; /* The number assigned to the port by the requester */
+ struct mac_addr requester_system; /* The requester's system id */
+ u32 requester_transaction_id; /* The transaction id allocated by the requester, */
+ u16 pad; /* = 0 */
+ u8 tlv_type_terminator; /* = 0x00 */
+ u8 terminator_length; /* = 0x00 */
+ u8 reserved_90[90]; /* = 0 */
+} __packed bond_marker_t;
+
+typedef struct bond_marker_header {
+ struct ethhdr hdr;
+ struct bond_marker marker;
+} __packed bond_marker_header_t;
+
+#pragma pack()
+
+struct slave;
+struct bonding;
+struct ad_info;
+struct port;
+
+#ifdef __ia64__
+#pragma pack(8)
+#endif
+
+/* aggregator structure(43.4.5 in the 802.3ad standard) */
+typedef struct aggregator {
+ struct mac_addr aggregator_mac_address;
+ u16 aggregator_identifier;
+ bool is_individual;
+ u16 actor_admin_aggregator_key;
+ u16 actor_oper_aggregator_key;
+ struct mac_addr partner_system;
+ u16 partner_system_priority;
+ u16 partner_oper_aggregator_key;
+ u16 receive_state; /* BOOLEAN */
+ u16 transmit_state; /* BOOLEAN */
+ struct port *lag_ports;
+ /* ****** PRIVATE PARAMETERS ****** */
+ struct slave *slave; /* pointer to the bond slave that this aggregator belongs to */
+ u16 is_active; /* BOOLEAN. Indicates if this aggregator is active */
+ u16 num_of_ports;
+} aggregator_t;
+
+struct port_params {
+ struct mac_addr system;
+ u16 system_priority;
+ u16 key;
+ u16 port_number;
+ u16 port_priority;
+ u16 port_state;
+};
+
+/* port structure(43.4.6 in the 802.3ad standard) */
+typedef struct port {
+ u16 actor_port_number;
+ u16 actor_port_priority;
+ struct mac_addr actor_system; /* This parameter is added here although it is not specified in the standard, just for simplification */
+ u16 actor_system_priority; /* This parameter is added here although it is not specified in the standard, just for simplification */
+ u16 actor_port_aggregator_identifier;
+ bool ntt;
+ u16 actor_admin_port_key;
+ u16 actor_oper_port_key;
+ u8 actor_admin_port_state;
+ u8 actor_oper_port_state;
+
+ struct port_params partner_admin;
+ struct port_params partner_oper;
+
+ bool is_enabled;
+
+ /* ****** PRIVATE PARAMETERS ****** */
+ u16 sm_vars; /* all state machines variables for this port */
+ rx_states_t sm_rx_state; /* state machine rx state */
+ u16 sm_rx_timer_counter; /* state machine rx timer counter */
+ periodic_states_t sm_periodic_state; /* state machine periodic state */
+ u16 sm_periodic_timer_counter; /* state machine periodic timer counter */
+ mux_states_t sm_mux_state; /* state machine mux state */
+ u16 sm_mux_timer_counter; /* state machine mux timer counter */
+ tx_states_t sm_tx_state; /* state machine tx state */
+ u16 sm_tx_timer_counter; /* state machine tx timer counter(allways on - enter to transmit state 3 time per second) */
+ struct slave *slave; /* pointer to the bond slave that this port belongs to */
+ struct aggregator *aggregator; /* pointer to an aggregator that this port related to */
+ struct port *next_port_in_aggregator; /* Next port on the linked list of the parent aggregator */
+ u32 transaction_id; /* continuous number for identification of Marker PDU's; */
+ struct lacpdu lacpdu; /* the lacpdu that will be sent for this port */
+} port_t;
+
+/* system structure */
+struct ad_system {
+ u16 sys_priority;
+ struct mac_addr sys_mac_addr;
+};
+
+#ifdef __ia64__
+#pragma pack()
+#endif
+
+/* ========== AD Exported structures to the main bonding code ========== */
+#define BOND_AD_INFO(bond) ((bond)->ad_info)
+#define SLAVE_AD_INFO(slave) ((slave)->ad_info)
+
+struct ad_bond_info {
+ struct ad_system system; /* 802.3ad system structure */
+ u32 agg_select_timer; /* Timer to select aggregator after all adapter's hand shakes */
+ u16 aggregator_identifier;
+};
+
+struct ad_slave_info {
+ struct aggregator aggregator; /* 802.3ad aggregator structure */
+ struct port port; /* 802.3ad port structure */
+ u16 id;
+};
+
+/* ========== AD Exported functions to the main bonding code ========== */
+void bond_3ad_initialize(struct bonding *bond, u16 tick_resolution);
+void bond_3ad_bind_slave(struct slave *slave);
+void bond_3ad_unbind_slave(struct slave *slave);
+void bond_3ad_state_machine_handler(struct work_struct *);
+void bond_3ad_initiate_agg_selection(struct bonding *bond, int timeout);
+void bond_3ad_adapter_speed_changed(struct slave *slave);
+void bond_3ad_adapter_duplex_changed(struct slave *slave);
+void bond_3ad_handle_link_change(struct slave *slave, char link);
+int bond_3ad_get_active_agg_info(struct bonding *bond, struct ad_info *ad_info);
+int __bond_3ad_get_active_agg_info(struct bonding *bond,
+ struct ad_info *ad_info);
+int bond_3ad_xmit_xor(struct sk_buff *skb, struct net_device *dev);
+int bond_3ad_lacpdu_recv(const struct sk_buff *skb, struct bonding *bond,
+ struct slave *slave);
+int bond_3ad_set_carrier(struct bonding *bond);
+void bond_3ad_update_lacp_rate(struct bonding *bond);
+#endif /* _NET_BOND_3AD_H */
+
diff --git a/include/net/bond_alb.h b/include/net/bond_alb.h
new file mode 100644
index 0000000..313a8d3
--- /dev/null
+++ b/include/net/bond_alb.h
@@ -0,0 +1,181 @@
+/*
+ * Copyright(c) 1999 - 2004 Intel Corporation. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, see <http://www.gnu.org/licenses/>.
+ *
+ * The full GNU General Public License is included in this distribution in the
+ * file called LICENSE.
+ *
+ */
+
+#ifndef _NET_BOND_ALB_H
+#define _NET_BOND_ALB_H
+
+#include <linux/if_ether.h>
+
+struct bonding;
+struct slave;
+
+#define BOND_ALB_INFO(bond) ((bond)->alb_info)
+#define SLAVE_TLB_INFO(slave) ((slave)->tlb_info)
+
+#define ALB_TIMER_TICKS_PER_SEC 10 /* should be a divisor of HZ */
+#define BOND_TLB_REBALANCE_INTERVAL 10 /* In seconds, periodic re-balancing.
+ * Used for division - never set
+ * to zero !!!
+ */
+#define BOND_ALB_DEFAULT_LP_INTERVAL 1
+#define BOND_ALB_LP_INTERVAL(bond) (bond->params.lp_interval) /* In seconds, periodic send of
+ * learning packets to the switch
+ */
+
+#define BOND_TLB_REBALANCE_TICKS (BOND_TLB_REBALANCE_INTERVAL \
+ * ALB_TIMER_TICKS_PER_SEC)
+
+#define BOND_ALB_LP_TICKS(bond) (BOND_ALB_LP_INTERVAL(bond) \
+ * ALB_TIMER_TICKS_PER_SEC)
+
+#define TLB_HASH_TABLE_SIZE 256 /* The size of the clients hash table.
+ * Note that this value MUST NOT be smaller
+ * because the key hash table is BYTE wide !
+ */
+
+
+#define TLB_NULL_INDEX 0xffffffff
+
+/* rlb defs */
+#define RLB_HASH_TABLE_SIZE 256
+#define RLB_NULL_INDEX 0xffffffff
+#define RLB_UPDATE_DELAY (2*ALB_TIMER_TICKS_PER_SEC) /* 2 seconds */
+#define RLB_ARP_BURST_SIZE 2
+#define RLB_UPDATE_RETRY 3 /* 3-ticks - must be smaller than the rlb
+ * rebalance interval (5 min).
+ */
+/* RLB_PROMISC_TIMEOUT = 10 sec equals the time that the current slave is
+ * promiscuous after failover
+ */
+#define RLB_PROMISC_TIMEOUT (10*ALB_TIMER_TICKS_PER_SEC)
+
+
+struct tlb_client_info {
+ struct slave *tx_slave; /* A pointer to slave used for transmiting
+ * packets to a Client that the Hash function
+ * gave this entry index.
+ */
+ u32 tx_bytes; /* Each Client accumulates the BytesTx that
+ * were transmitted to it, and after each
+ * CallBack the LoadHistory is divided
+ * by the balance interval
+ */
+ u32 load_history; /* This field contains the amount of Bytes
+ * that were transmitted to this client by
+ * the server on the previous balance
+ * interval in Bps.
+ */
+ u32 next; /* The next Hash table entry index, assigned
+ * to use the same adapter for transmit.
+ */
+ u32 prev; /* The previous Hash table entry index,
+ * assigned to use the same
+ */
+};
+
+/* -------------------------------------------------------------------------
+ * struct rlb_client_info contains all info related to a specific rx client
+ * connection. This is the Clients Hash Table entry struct.
+ * Note that this is not a proper hash table; if a new client's IP address
+ * hash collides with an existing client entry, the old entry is replaced.
+ *
+ * There is a linked list (linked by the used_next and used_prev members)
+ * linking all the used entries of the hash table. This allows updating
+ * all the clients without walking over all the unused elements of the table.
+ *
+ * There are also linked lists of entries with identical hash(ip_src). These
+ * allow cleaning up the table from ip_src<->mac_src associations that have
+ * become outdated and would cause sending out invalid ARP updates to the
+ * network. These are linked by the (src_next and src_prev members).
+ * -------------------------------------------------------------------------
+ */
+struct rlb_client_info {
+ __be32 ip_src; /* the server IP address */
+ __be32 ip_dst; /* the client IP address */
+ u8 mac_src[ETH_ALEN]; /* the server MAC address */
+ u8 mac_dst[ETH_ALEN]; /* the client MAC address */
+
+ /* list of used hash table entries, starting at rx_hashtbl_used_head */
+ u32 used_next;
+ u32 used_prev;
+
+ /* ip_src based hashing */
+ u32 src_next; /* next entry with same hash(ip_src) */
+ u32 src_prev; /* prev entry with same hash(ip_src) */
+ u32 src_first; /* first entry with hash(ip_src) == this entry's index */
+
+ u8 assigned; /* checking whether this entry is assigned */
+ u8 ntt; /* flag - need to transmit client info */
+ struct slave *slave; /* the slave assigned to this client */
+ unsigned short vlan_id; /* VLAN tag associated with IP address */
+};
+
+struct tlb_slave_info {
+ u32 head; /* Index to the head of the bi-directional clients
+ * hash table entries list. The entries in the list
+ * are the entries that were assigned to use this
+ * slave for transmit.
+ */
+ u32 load; /* Each slave sums the loadHistory of all clients
+ * assigned to it
+ */
+};
+
+struct alb_bond_info {
+ struct tlb_client_info *tx_hashtbl; /* Dynamically allocated */
+ u32 unbalanced_load;
+ int tx_rebalance_counter;
+ int lp_counter;
+ /* -------- rlb parameters -------- */
+ int rlb_enabled;
+ struct rlb_client_info *rx_hashtbl; /* Receive hash table */
+ u32 rx_hashtbl_used_head;
+ u8 rx_ntt; /* flag - need to transmit
+ * to all rx clients
+ */
+ struct slave *rx_slave;/* last slave to xmit from */
+ u8 primary_is_promisc; /* boolean */
+ u32 rlb_promisc_timeout_counter;/* counts primary
+ * promiscuity time
+ */
+ u32 rlb_update_delay_counter;
+ u32 rlb_update_retry_counter;/* counter of retries
+ * of client update
+ */
+ u8 rlb_rebalance; /* flag - indicates that the
+ * rx traffic should be
+ * rebalanced
+ */
+};
+
+int bond_alb_initialize(struct bonding *bond, int rlb_enabled);
+void bond_alb_deinitialize(struct bonding *bond);
+int bond_alb_init_slave(struct bonding *bond, struct slave *slave);
+void bond_alb_deinit_slave(struct bonding *bond, struct slave *slave);
+void bond_alb_handle_link_change(struct bonding *bond, struct slave *slave, char link);
+void bond_alb_handle_active_change(struct bonding *bond, struct slave *new_slave);
+int bond_alb_xmit(struct sk_buff *skb, struct net_device *bond_dev);
+int bond_tlb_xmit(struct sk_buff *skb, struct net_device *bond_dev);
+void bond_alb_monitor(struct work_struct *);
+int bond_alb_set_mac_address(struct net_device *bond_dev, void *addr);
+void bond_alb_clear_vlan(struct bonding *bond, unsigned short vlan_id);
+#endif /* _NET_BOND_ALB_H */
+
diff --git a/include/net/bond_options.h b/include/net/bond_options.h
new file mode 100644
index 0000000..ea6546d
--- /dev/null
+++ b/include/net/bond_options.h
@@ -0,0 +1,130 @@
+/*
+ * drivers/net/bond/bond_options.h - bonding options
+ * Copyright (c) 2013 Nikolay Aleksandrov <nikolay@redhat.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ */
+
+#ifndef _NET_BOND_OPTIONS_H
+#define _NET_BOND_OPTIONS_H
+
+#define BOND_OPT_MAX_NAMELEN 32
+#define BOND_OPT_VALID(opt) ((opt) < BOND_OPT_LAST)
+#define BOND_MODE_ALL_EX(x) (~(x))
+
+/* Option flags:
+ * BOND_OPTFLAG_NOSLAVES - check if the bond device is empty before setting
+ * BOND_OPTFLAG_IFDOWN - check if the bond device is down before setting
+ * BOND_OPTFLAG_RAWVAL - the option parses the value itself
+ */
+enum {
+ BOND_OPTFLAG_NOSLAVES = BIT(0),
+ BOND_OPTFLAG_IFDOWN = BIT(1),
+ BOND_OPTFLAG_RAWVAL = BIT(2)
+};
+
+/* Value type flags:
+ * BOND_VALFLAG_DEFAULT - mark the value as default
+ * BOND_VALFLAG_(MIN|MAX) - mark the value as min/max
+ */
+enum {
+ BOND_VALFLAG_DEFAULT = BIT(0),
+ BOND_VALFLAG_MIN = BIT(1),
+ BOND_VALFLAG_MAX = BIT(2)
+};
+
+/* Option IDs, their bit positions correspond to their IDs */
+enum {
+ BOND_OPT_MODE,
+ BOND_OPT_PACKETS_PER_SLAVE,
+ BOND_OPT_XMIT_HASH,
+ BOND_OPT_ARP_VALIDATE,
+ BOND_OPT_ARP_ALL_TARGETS,
+ BOND_OPT_FAIL_OVER_MAC,
+ BOND_OPT_ARP_INTERVAL,
+ BOND_OPT_ARP_TARGETS,
+ BOND_OPT_DOWNDELAY,
+ BOND_OPT_UPDELAY,
+ BOND_OPT_LACP_RATE,
+ BOND_OPT_MINLINKS,
+ BOND_OPT_AD_SELECT,
+ BOND_OPT_NUM_PEER_NOTIF,
+ BOND_OPT_MIIMON,
+ BOND_OPT_PRIMARY,
+ BOND_OPT_PRIMARY_RESELECT,
+ BOND_OPT_USE_CARRIER,
+ BOND_OPT_ACTIVE_SLAVE,
+ BOND_OPT_QUEUE_ID,
+ BOND_OPT_ALL_SLAVES_ACTIVE,
+ BOND_OPT_RESEND_IGMP,
+ BOND_OPT_LP_INTERVAL,
+ BOND_OPT_SLAVES,
+ BOND_OPT_TLB_DYNAMIC_LB,
+ BOND_OPT_LAST
+};
+
+/* This structure is used for storing option values and for passing option
+ * values when changing an option. The logic when used as an arg is as follows:
+ * - if string != NULL -> parse it, if the opt is RAW type then return it, else
+ * return the parse result
+ * - if string == NULL -> parse value
+ */
+struct bond_opt_value {
+ char *string;
+ u64 value;
+ u32 flags;
+};
+
+struct bonding;
+
+struct bond_option {
+ int id;
+ const char *name;
+ const char *desc;
+ u32 flags;
+
+ /* unsuppmodes is used to denote modes in which the option isn't
+ * supported.
+ */
+ unsigned long unsuppmodes;
+ /* supported values which this option can have, can be a subset of
+ * BOND_OPTVAL_RANGE's value range
+ */
+ const struct bond_opt_value *values;
+
+ int (*set)(struct bonding *bond, const struct bond_opt_value *val);
+};
+
+int __bond_opt_set(struct bonding *bond, unsigned int option,
+ struct bond_opt_value *val);
+int bond_opt_tryset_rtnl(struct bonding *bond, unsigned int option, char *buf);
+
+const struct bond_opt_value *bond_opt_parse(const struct bond_option *opt,
+ struct bond_opt_value *val);
+const struct bond_option *bond_opt_get(unsigned int option);
+const struct bond_option *bond_opt_get_by_name(const char *name);
+const struct bond_opt_value *bond_opt_get_val(unsigned int option, u64 val);
+
+/* This helper is used to initialize a bond_opt_value structure for parameter
+ * passing. There should be either a valid string or value, but not both.
+ * When value is ULLONG_MAX then string will be used.
+ */
+static inline void __bond_opt_init(struct bond_opt_value *optval,
+ char *string, u64 value)
+{
+ memset(optval, 0, sizeof(*optval));
+ optval->value = ULLONG_MAX;
+ if (value == ULLONG_MAX)
+ optval->string = string;
+ else
+ optval->value = value;
+}
+#define bond_opt_initval(optval, value) __bond_opt_init(optval, NULL, value)
+#define bond_opt_initstr(optval, str) __bond_opt_init(optval, str, ULLONG_MAX)
+
+void bond_option_arp_ip_targets_clear(struct bonding *bond);
+
+#endif /* _NET_BOND_OPTIONS_H */
diff --git a/include/net/bonding.h b/include/net/bonding.h
new file mode 100644
index 0000000..983a94b
--- /dev/null
+++ b/include/net/bonding.h
@@ -0,0 +1,654 @@
+/*
+ * Bond several ethernet interfaces into a Cisco, running 'Etherchannel'.
+ *
+ * Portions are (c) Copyright 1995 Simon "Guru Aleph-Null" Janes
+ * NCM: Network and Communications Management, Inc.
+ *
+ * BUT, I'm the one who modified it for ethernet, so:
+ * (c) Copyright 1999, Thomas Davis, tadavis@lbl.gov
+ *
+ * This software may be used and distributed according to the terms
+ * of the GNU Public License, incorporated herein by reference.
+ *
+ */
+
+#ifndef _NET_BONDING_H
+#define _NET_BONDING_H
+
+#include <linux/timer.h>
+#include <linux/proc_fs.h>
+#include <linux/if_bonding.h>
+#include <linux/cpumask.h>
+#include <linux/in6.h>
+#include <linux/netpoll.h>
+#include <linux/inetdevice.h>
+#include <linux/etherdevice.h>
+#include <linux/reciprocal_div.h>
+#include <linux/if_link.h>
+
+#include <net/bond_3ad.h>
+#include <net/bond_alb.h>
+#include <net/bond_options.h>
+
+#define DRV_VERSION "3.7.1"
+#define DRV_RELDATE "April 27, 2011"
+#define DRV_NAME "bonding"
+#define DRV_DESCRIPTION "Ethernet Channel Bonding Driver"
+
+#define bond_version DRV_DESCRIPTION ": v" DRV_VERSION " (" DRV_RELDATE ")\n"
+
+#define BOND_MAX_ARP_TARGETS 16
+
+#define BOND_DEFAULT_MIIMON 100
+
+/*
+ * Less bad way to call ioctl from within the kernel; this needs to be
+ * done some other way to get the call out of interrupt context.
+ * Needs "ioctl" variable to be supplied by calling context.
+ */
+#define IOCTL(dev, arg, cmd) ({ \
+ int res = 0; \
+ mm_segment_t fs = get_fs(); \
+ set_fs(get_ds()); \
+ res = ioctl(dev, arg, cmd); \
+ set_fs(fs); \
+ res; })
+
+#define BOND_MODE(bond) ((bond)->params.mode)
+
+/* slave list primitives */
+#define bond_slave_list(bond) (&(bond)->dev->adj_list.lower)
+
+#define bond_has_slaves(bond) !list_empty(bond_slave_list(bond))
+
+/* IMPORTANT: bond_first/last_slave can return NULL in case of an empty list */
+#define bond_first_slave(bond) \
+ (bond_has_slaves(bond) ? \
+ netdev_adjacent_get_private(bond_slave_list(bond)->next) : \
+ NULL)
+#define bond_last_slave(bond) \
+ (bond_has_slaves(bond) ? \
+ netdev_adjacent_get_private(bond_slave_list(bond)->prev) : \
+ NULL)
+
+/* Caller must have rcu_read_lock */
+#define bond_first_slave_rcu(bond) \
+ netdev_lower_get_first_private_rcu(bond->dev)
+
+#define bond_is_first_slave(bond, pos) (pos == bond_first_slave(bond))
+#define bond_is_last_slave(bond, pos) (pos == bond_last_slave(bond))
+
+/**
+ * bond_for_each_slave - iterate over all slaves
+ * @bond: the bond holding this list
+ * @pos: current slave
+ * @iter: list_head * iterator
+ *
+ * Caller must hold RTNL
+ */
+#define bond_for_each_slave(bond, pos, iter) \
+ netdev_for_each_lower_private((bond)->dev, pos, iter)
+
+/* Caller must have rcu_read_lock */
+#define bond_for_each_slave_rcu(bond, pos, iter) \
+ netdev_for_each_lower_private_rcu((bond)->dev, pos, iter)
+
+#ifdef CONFIG_NET_POLL_CONTROLLER
+extern atomic_t netpoll_block_tx;
+
+static inline void block_netpoll_tx(void)
+{
+ atomic_inc(&netpoll_block_tx);
+}
+
+static inline void unblock_netpoll_tx(void)
+{
+ atomic_dec(&netpoll_block_tx);
+}
+
+static inline int is_netpoll_tx_blocked(struct net_device *dev)
+{
+ if (unlikely(netpoll_tx_running(dev)))
+ return atomic_read(&netpoll_block_tx);
+ return 0;
+}
+#else
+#define block_netpoll_tx()
+#define unblock_netpoll_tx()
+#define is_netpoll_tx_blocked(dev) (0)
+#endif
+
+struct bond_params {
+ int mode;
+ int xmit_policy;
+ int miimon;
+ u8 num_peer_notif;
+ int arp_interval;
+ int arp_validate;
+ int arp_all_targets;
+ int use_carrier;
+ int fail_over_mac;
+ int updelay;
+ int downdelay;
+ int lacp_fast;
+ unsigned int min_links;
+ int ad_select;
+ char primary[IFNAMSIZ];
+ int primary_reselect;
+ __be32 arp_targets[BOND_MAX_ARP_TARGETS];
+ int tx_queues;
+ int all_slaves_active;
+ int resend_igmp;
+ int lp_interval;
+ int packets_per_slave;
+ int tlb_dynamic_lb;
+ struct reciprocal_value reciprocal_packets_per_slave;
+};
+
+struct bond_parm_tbl {
+ char *modename;
+ int mode;
+};
+
+struct slave {
+ struct net_device *dev; /* first - useful for panic debug */
+ struct bonding *bond; /* our master */
+ int delay;
+ /* all three in jiffies */
+ unsigned long last_link_up;
+ unsigned long last_rx;
+ unsigned long target_last_arp_rx[BOND_MAX_ARP_TARGETS];
+ s8 link; /* one of BOND_LINK_XXXX */
+ s8 new_link;
+ u8 backup:1, /* indicates backup slave. Value corresponds with
+ BOND_STATE_ACTIVE and BOND_STATE_BACKUP */
+ inactive:1, /* indicates inactive slave */
+ should_notify:1; /* indicateds whether the state changed */
+ u8 duplex;
+ u32 original_mtu;
+ u32 link_failure_count;
+ u32 speed;
+ u16 queue_id;
+ u8 perm_hwaddr[ETH_ALEN];
+ struct ad_slave_info *ad_info;
+ struct tlb_slave_info tlb_info;
+#ifdef CONFIG_NET_POLL_CONTROLLER
+ struct netpoll *np;
+#endif
+ struct kobject kobj;
+ struct rtnl_link_stats64 slave_stats;
+};
+
+struct bond_up_slave {
+ unsigned int count;
+ struct rcu_head rcu;
+ struct slave *arr[0];
+};
+
+/*
+ * Link pseudo-state only used internally by monitors
+ */
+#define BOND_LINK_NOCHANGE -1
+
+/*
+ * Here are the locking policies for the two bonding locks:
+ * Get rcu_read_lock when reading or RTNL when writing slave list.
+ */
+struct bonding {
+ struct net_device *dev; /* first - useful for panic debug */
+ struct slave __rcu *curr_active_slave;
+ struct slave __rcu *current_arp_slave;
+ struct slave __rcu *primary_slave;
+ struct bond_up_slave __rcu *slave_arr; /* Array of usable slaves */
+ bool force_primary;
+ s32 slave_cnt; /* never change this value outside the attach/detach wrappers */
+ int (*recv_probe)(const struct sk_buff *, struct bonding *,
+ struct slave *);
+ /* mode_lock is used for mode-specific locking needs, currently used by:
+ * 3ad mode (4) - protect against running bond_3ad_unbind_slave() and
+ * bond_3ad_state_machine_handler() concurrently and also
+ * the access to the state machine shared variables.
+ * TLB mode (5) - to sync the use and modifications of its hash table
+ * ALB mode (6) - to sync the use and modifications of its hash table
+ */
+ spinlock_t mode_lock;
+ u8 send_peer_notif;
+ u8 igmp_retrans;
+#ifdef CONFIG_PROC_FS
+ struct proc_dir_entry *proc_entry;
+ char proc_file_name[IFNAMSIZ];
+#endif /* CONFIG_PROC_FS */
+ struct list_head bond_list;
+ u32 rr_tx_counter;
+ struct ad_bond_info ad_info;
+ struct alb_bond_info alb_info;
+ struct bond_params params;
+ struct workqueue_struct *wq;
+ struct delayed_work mii_work;
+ struct delayed_work arp_work;
+ struct delayed_work alb_work;
+ struct delayed_work ad_work;
+ struct delayed_work mcast_work;
+ struct delayed_work slave_arr_work;
+#ifdef CONFIG_DEBUG_FS
+ /* debugging support via debugfs */
+ struct dentry *debug_dir;
+#endif /* CONFIG_DEBUG_FS */
+ struct rtnl_link_stats64 bond_stats;
+};
+
+#define bond_slave_get_rcu(dev) \
+ ((struct slave *) rcu_dereference(dev->rx_handler_data))
+
+#define bond_slave_get_rtnl(dev) \
+ ((struct slave *) rtnl_dereference(dev->rx_handler_data))
+
+struct bond_vlan_tag {
+ __be16 vlan_proto;
+ unsigned short vlan_id;
+};
+
+/**
+ * Returns NULL if the net_device does not belong to any of the bond's slaves
+ *
+ * Caller must hold bond lock for read
+ */
+static inline struct slave *bond_get_slave_by_dev(struct bonding *bond,
+ struct net_device *slave_dev)
+{
+ return netdev_lower_dev_get_private(bond->dev, slave_dev);
+}
+
+static inline struct bonding *bond_get_bond_by_slave(struct slave *slave)
+{
+ return slave->bond;
+}
+
+static inline bool bond_should_override_tx_queue(struct bonding *bond)
+{
+ return BOND_MODE(bond) == BOND_MODE_ACTIVEBACKUP ||
+ BOND_MODE(bond) == BOND_MODE_ROUNDROBIN;
+}
+
+static inline bool bond_is_lb(const struct bonding *bond)
+{
+ return BOND_MODE(bond) == BOND_MODE_TLB ||
+ BOND_MODE(bond) == BOND_MODE_ALB;
+}
+
+static inline bool bond_is_nondyn_tlb(const struct bonding *bond)
+{
+ return (BOND_MODE(bond) == BOND_MODE_TLB) &&
+ (bond->params.tlb_dynamic_lb == 0);
+}
+
+static inline bool bond_mode_uses_xmit_hash(const struct bonding *bond)
+{
+ return (BOND_MODE(bond) == BOND_MODE_8023AD ||
+ BOND_MODE(bond) == BOND_MODE_XOR ||
+ bond_is_nondyn_tlb(bond));
+}
+
+static inline bool bond_mode_uses_arp(int mode)
+{
+ return mode != BOND_MODE_8023AD && mode != BOND_MODE_TLB &&
+ mode != BOND_MODE_ALB;
+}
+
+static inline bool bond_mode_uses_primary(int mode)
+{
+ return mode == BOND_MODE_ACTIVEBACKUP || mode == BOND_MODE_TLB ||
+ mode == BOND_MODE_ALB;
+}
+
+static inline bool bond_uses_primary(struct bonding *bond)
+{
+ return bond_mode_uses_primary(BOND_MODE(bond));
+}
+
+static inline bool bond_slave_is_up(struct slave *slave)
+{
+ return netif_running(slave->dev) && netif_carrier_ok(slave->dev);
+}
+
+static inline void bond_set_active_slave(struct slave *slave)
+{
+ if (slave->backup) {
+ slave->backup = 0;
+ rtmsg_ifinfo(RTM_NEWLINK, slave->dev, 0, GFP_ATOMIC);
+ }
+}
+
+static inline void bond_set_backup_slave(struct slave *slave)
+{
+ if (!slave->backup) {
+ slave->backup = 1;
+ rtmsg_ifinfo(RTM_NEWLINK, slave->dev, 0, GFP_ATOMIC);
+ }
+}
+
+static inline void bond_set_slave_state(struct slave *slave,
+ int slave_state, bool notify)
+{
+ if (slave->backup == slave_state)
+ return;
+
+ slave->backup = slave_state;
+ if (notify) {
+ rtmsg_ifinfo(RTM_NEWLINK, slave->dev, 0, GFP_ATOMIC);
+ slave->should_notify = 0;
+ } else {
+ if (slave->should_notify)
+ slave->should_notify = 0;
+ else
+ slave->should_notify = 1;
+ }
+}
+
+static inline void bond_slave_state_change(struct bonding *bond)
+{
+ struct list_head *iter;
+ struct slave *tmp;
+
+ bond_for_each_slave(bond, tmp, iter) {
+ if (tmp->link == BOND_LINK_UP)
+ bond_set_active_slave(tmp);
+ else if (tmp->link == BOND_LINK_DOWN)
+ bond_set_backup_slave(tmp);
+ }
+}
+
+static inline void bond_slave_state_notify(struct bonding *bond)
+{
+ struct list_head *iter;
+ struct slave *tmp;
+
+ bond_for_each_slave(bond, tmp, iter) {
+ if (tmp->should_notify) {
+ rtmsg_ifinfo(RTM_NEWLINK, tmp->dev, 0, GFP_ATOMIC);
+ tmp->should_notify = 0;
+ }
+ }
+}
+
+static inline int bond_slave_state(struct slave *slave)
+{
+ return slave->backup;
+}
+
+static inline bool bond_is_active_slave(struct slave *slave)
+{
+ return !bond_slave_state(slave);
+}
+
+static inline bool bond_slave_can_tx(struct slave *slave)
+{
+ return bond_slave_is_up(slave) && slave->link == BOND_LINK_UP &&
+ bond_is_active_slave(slave);
+}
+
+#define BOND_PRI_RESELECT_ALWAYS 0
+#define BOND_PRI_RESELECT_BETTER 1
+#define BOND_PRI_RESELECT_FAILURE 2
+
+#define BOND_FOM_NONE 0
+#define BOND_FOM_ACTIVE 1
+#define BOND_FOM_FOLLOW 2
+
+#define BOND_ARP_TARGETS_ANY 0
+#define BOND_ARP_TARGETS_ALL 1
+
+#define BOND_ARP_VALIDATE_NONE 0
+#define BOND_ARP_VALIDATE_ACTIVE (1 << BOND_STATE_ACTIVE)
+#define BOND_ARP_VALIDATE_BACKUP (1 << BOND_STATE_BACKUP)
+#define BOND_ARP_VALIDATE_ALL (BOND_ARP_VALIDATE_ACTIVE | \
+ BOND_ARP_VALIDATE_BACKUP)
+#define BOND_ARP_FILTER (BOND_ARP_VALIDATE_ALL + 1)
+#define BOND_ARP_FILTER_ACTIVE (BOND_ARP_VALIDATE_ACTIVE | \
+ BOND_ARP_FILTER)
+#define BOND_ARP_FILTER_BACKUP (BOND_ARP_VALIDATE_BACKUP | \
+ BOND_ARP_FILTER)
+
+#define BOND_SLAVE_NOTIFY_NOW true
+#define BOND_SLAVE_NOTIFY_LATER false
+
+static inline int slave_do_arp_validate(struct bonding *bond,
+ struct slave *slave)
+{
+ return bond->params.arp_validate & (1 << bond_slave_state(slave));
+}
+
+static inline int slave_do_arp_validate_only(struct bonding *bond)
+{
+ return bond->params.arp_validate & BOND_ARP_FILTER;
+}
+
+static inline int bond_is_ip_target_ok(__be32 addr)
+{
+ return !ipv4_is_lbcast(addr) && !ipv4_is_zeronet(addr);
+}
+
+/* Get the oldest arp which we've received on this slave for bond's
+ * arp_targets.
+ */
+static inline unsigned long slave_oldest_target_arp_rx(struct bonding *bond,
+ struct slave *slave)
+{
+ int i = 1;
+ unsigned long ret = slave->target_last_arp_rx[0];
+
+ for (; (i < BOND_MAX_ARP_TARGETS) && bond->params.arp_targets[i]; i++)
+ if (time_before(slave->target_last_arp_rx[i], ret))
+ ret = slave->target_last_arp_rx[i];
+
+ return ret;
+}
+
+static inline unsigned long slave_last_rx(struct bonding *bond,
+ struct slave *slave)
+{
+ if (bond->params.arp_all_targets == BOND_ARP_TARGETS_ALL)
+ return slave_oldest_target_arp_rx(bond, slave);
+
+ return slave->last_rx;
+}
+
+#ifdef CONFIG_NET_POLL_CONTROLLER
+static inline void bond_netpoll_send_skb(const struct slave *slave,
+ struct sk_buff *skb)
+{
+ struct netpoll *np = slave->np;
+
+ if (np)
+ netpoll_send_skb(np, skb);
+}
+#else
+static inline void bond_netpoll_send_skb(const struct slave *slave,
+ struct sk_buff *skb)
+{
+}
+#endif
+
+static inline void bond_set_slave_inactive_flags(struct slave *slave,
+ bool notify)
+{
+ if (!bond_is_lb(slave->bond))
+ bond_set_slave_state(slave, BOND_STATE_BACKUP, notify);
+ if (!slave->bond->params.all_slaves_active)
+ slave->inactive = 1;
+}
+
+static inline void bond_set_slave_active_flags(struct slave *slave,
+ bool notify)
+{
+ bond_set_slave_state(slave, BOND_STATE_ACTIVE, notify);
+ slave->inactive = 0;
+}
+
+static inline bool bond_is_slave_inactive(struct slave *slave)
+{
+ return slave->inactive;
+}
+
+static inline __be32 bond_confirm_addr(struct net_device *dev, __be32 dst, __be32 local)
+{
+ struct in_device *in_dev;
+ __be32 addr = 0;
+
+ rcu_read_lock();
+ in_dev = __in_dev_get_rcu(dev);
+
+ if (in_dev)
+ addr = inet_confirm_addr(dev_net(dev), in_dev, dst, local,
+ RT_SCOPE_HOST);
+ rcu_read_unlock();
+ return addr;
+}
+
+struct bond_net {
+ struct net *net; /* Associated network namespace */
+ struct list_head dev_list;
+#ifdef CONFIG_PROC_FS
+ struct proc_dir_entry *proc_dir;
+#endif
+ struct class_attribute class_attr_bonding_masters;
+};
+
+int bond_arp_rcv(const struct sk_buff *skb, struct bonding *bond, struct slave *slave);
+void bond_dev_queue_xmit(struct bonding *bond, struct sk_buff *skb, struct net_device *slave_dev);
+int bond_create(struct net *net, const char *name);
+int bond_create_sysfs(struct bond_net *net);
+void bond_destroy_sysfs(struct bond_net *net);
+void bond_prepare_sysfs_group(struct bonding *bond);
+int bond_sysfs_slave_add(struct slave *slave);
+void bond_sysfs_slave_del(struct slave *slave);
+int bond_enslave(struct net_device *bond_dev, struct net_device *slave_dev);
+int bond_release(struct net_device *bond_dev, struct net_device *slave_dev);
+u32 bond_xmit_hash(struct bonding *bond, struct sk_buff *skb);
+void bond_select_active_slave(struct bonding *bond);
+void bond_change_active_slave(struct bonding *bond, struct slave *new_active);
+void bond_create_debugfs(void);
+void bond_destroy_debugfs(void);
+void bond_debug_register(struct bonding *bond);
+void bond_debug_unregister(struct bonding *bond);
+void bond_debug_reregister(struct bonding *bond);
+const char *bond_mode_name(int mode);
+void bond_setup(struct net_device *bond_dev);
+unsigned int bond_get_num_tx_queues(void);
+int bond_netlink_init(void);
+void bond_netlink_fini(void);
+struct net_device *bond_option_active_slave_get_rcu(struct bonding *bond);
+const char *bond_slave_link_status(s8 link);
+struct bond_vlan_tag *bond_verify_device_path(struct net_device *start_dev,
+ struct net_device *end_dev,
+ int level);
+int bond_update_slave_arr(struct bonding *bond, struct slave *skipslave);
+void bond_slave_arr_work_rearm(struct bonding *bond, unsigned long delay);
+
+#ifdef CONFIG_PROC_FS
+void bond_create_proc_entry(struct bonding *bond);
+void bond_remove_proc_entry(struct bonding *bond);
+void bond_create_proc_dir(struct bond_net *bn);
+void bond_destroy_proc_dir(struct bond_net *bn);
+#else
+static inline void bond_create_proc_entry(struct bonding *bond)
+{
+}
+
+static inline void bond_remove_proc_entry(struct bonding *bond)
+{
+}
+
+static inline void bond_create_proc_dir(struct bond_net *bn)
+{
+}
+
+static inline void bond_destroy_proc_dir(struct bond_net *bn)
+{
+}
+#endif
+
+static inline struct slave *bond_slave_has_mac(struct bonding *bond,
+ const u8 *mac)
+{
+ struct list_head *iter;
+ struct slave *tmp;
+
+ bond_for_each_slave(bond, tmp, iter)
+ if (ether_addr_equal_64bits(mac, tmp->dev->dev_addr))
+ return tmp;
+
+ return NULL;
+}
+
+/* Caller must hold rcu_read_lock() for read */
+static inline struct slave *bond_slave_has_mac_rcu(struct bonding *bond,
+ const u8 *mac)
+{
+ struct list_head *iter;
+ struct slave *tmp;
+
+ bond_for_each_slave_rcu(bond, tmp, iter)
+ if (ether_addr_equal_64bits(mac, tmp->dev->dev_addr))
+ return tmp;
+
+ return NULL;
+}
+
+/* Caller must hold rcu_read_lock() for read */
+static inline bool bond_slave_has_mac_rx(struct bonding *bond, const u8 *mac)
+{
+ struct list_head *iter;
+ struct slave *tmp;
+ struct netdev_hw_addr *ha;
+
+ bond_for_each_slave_rcu(bond, tmp, iter)
+ if (ether_addr_equal_64bits(mac, tmp->dev->dev_addr))
+ return true;
+
+ if (netdev_uc_empty(bond->dev))
+ return false;
+
+ netdev_for_each_uc_addr(ha, bond->dev)
+ if (ether_addr_equal_64bits(mac, ha->addr))
+ return true;
+
+ return false;
+}
+
+/* Check if the ip is present in arp ip list, or first free slot if ip == 0
+ * Returns -1 if not found, index if found
+ */
+static inline int bond_get_targets_ip(__be32 *targets, __be32 ip)
+{
+ int i;
+
+ for (i = 0; i < BOND_MAX_ARP_TARGETS; i++)
+ if (targets[i] == ip)
+ return i;
+ else if (targets[i] == 0)
+ break;
+
+ return -1;
+}
+
+/* exported from bond_main.c */
+extern int bond_net_id;
+extern const struct bond_parm_tbl bond_lacp_tbl[];
+extern const struct bond_parm_tbl xmit_hashtype_tbl[];
+extern const struct bond_parm_tbl arp_validate_tbl[];
+extern const struct bond_parm_tbl arp_all_targets_tbl[];
+extern const struct bond_parm_tbl fail_over_mac_tbl[];
+extern const struct bond_parm_tbl pri_reselect_tbl[];
+extern struct bond_parm_tbl ad_select_tbl[];
+
+/* exported from bond_netlink.c */
+extern struct rtnl_link_ops bond_link_ops;
+
+static inline void bond_tx_drop(struct net_device *dev, struct sk_buff *skb)
+{
+ atomic_long_inc(&dev->tx_dropped);
+ dev_kfree_skb_any(skb);
+}
+
+#endif /* _NET_BONDING_H */
--
1.9.3
^ permalink raw reply related
* Re: [patch net-next v2 10/10] rocker: implement L2 bridge offloading
From: Roopa Prabhu @ 2014-11-10 18:35 UTC (permalink / raw)
To: Scott Feldman
Cc: Jamal Hadi Salim, Jiri Pirko, Netdev, David S. Miller, nhorman,
Andy Gospodarek, Thomas Graf, dborkman, ogerlitz, jesse, pshelar,
azhou, ben, stephen, Kirsher, Jeffrey T, vyasevic, Cong Wang,
Fastabend, John R, Eric Dumazet, Florian Fainelli, John Linville,
jasowang, ebiederm, nicolas.dichtel, ryazanov.s.a, buytenh,
aviadr, nbd, Alexei Starovoitov, Neil
In-Reply-To: <CAE4R7bARr8_=sS+6aezKDX0FfERUj8AD6eOGONKAeRd-g+9nDA@mail.gmail.com>
On 11/10/14, 9:36 AM, Scott Feldman wrote:
> On Mon, Nov 10, 2014 at 6:12 AM, Roopa Prabhu <roopa@cumulusnetworks.com> wrote:
>> On 11/10/14, 4:27 AM, Jamal Hadi Salim wrote:
>>> On 11/10/14 03:46, Scott Feldman wrote:
>>>
>>>> IFLA_BRPORT_LEARNING is u8 attr and we're only using lower bit to turn
>>>> learning on/off. Maybe we can use another bit to indicate learning to
>>>> be done in sw or hw. I don't think adding another bit would break
>>>> existing iproute2.
>>>>
>>>> LEARNING_ENABLED (1 << 0)
>>>> LEARNING_HW (1 << 1)
>>>>
>>>> Would this work?
>>>>
>>> Yes to making it a bit. But:
>>> This is not *learning*. You are doing a *sync*.
>>> Those are two different things.
>>>
>>> Learning on/off exists today. It signals to the L2 whether you
>>> should learn or not.
>>> I like the way fdb_add/del work with a flag which says
>>> it is the software and/or offloaded version. Please keep that
>>> semantic.
>>> What you are doing above is letting the hardware learn then
>>> syncing to software. You need a different flag there. something
>>> like:
>>>
>>> SYNC_HW_FDB (1<<1)
>>>
>> And in any case, It seems like this policy should be per bridge or per
>> switch chip...or per fdb..
>> entry (like the original fdb_add/del) and not a "port" flag.. ?
> Per-port gives more flexibility, and it looks like we can extend
> existing IFLA_BRPORT_LEARNING without much trouble.
>
> I didn't follow the fdb_add/del comment? Isn't an fdb entry
> port-specific by nature? fdb entry = {port, mac, vlan} tuple.
yes it is, But if i remember correctly, the api (ndo op) could indicate
offload to hw (or nic in this case)
by giving 'self'. And in those cases the netdev nic port represents the
switch.
(Will be nice to check and confirm this though).
^ permalink raw reply
* Re: [PATCH net-next] cxgb4: Remove unnecessary struct in6_addr * casts
From: Joe Perches @ 2014-11-10 18:48 UTC (permalink / raw)
To: David Miller
Cc: hariprasad, netdev, leedom, anish, praveenm, nirranjan, kumaras,
j.vosburgh, vfalico, andy
In-Reply-To: <20141110.132837.1817456437352515704.davem@davemloft.net>
On Mon, 2014-11-10 at 13:28 -0500, David Miller wrote:
> From: Joe Perches <joe@perches.com> Date: Thu, 06 Nov 2014 20:46:14 -0800
[]
> >> diff --git a/drivers/net/ethernet/chelsio/cxgb4/cxgb4_main.c b/drivers/net/ethernet/chelsio/cxgb4/cxgb4_main.c
> > []
> >> #include <../drivers/net/bonding/bonding.h>
> >
> > This include path seems unfortunate so I looked
> > at the code a bit. I don't see an easy way to change it.
> >
> > Maybe some of bonding.h should be moved into a new file
> > like 'include/net/bonding.h' or something.
>
> I just committed the following into net-next, thanks for pointing
> this out.
Thanks.
btw: using "git format-patch -M" makes reading and
verifying the patch a lot easier.
Unfortunately, there's no current way to make this
a global default for everyone, but I have this in
my ~/.gitconfig:
[diff]
renames = true
^ permalink raw reply
* [PATCH -next 0/2] seq: Convert seq_puts and seq_putc to return void
From: Joe Perches @ 2014-11-10 18:58 UTC (permalink / raw)
To: Steven Rostedt, openipmi-developer, linux-parisc, linux-kernel,
linux-watchdog, linux-fsdevel, netfilter-devel, coreteam
Cc: Petr Mladek, linux-usb, netdev
These are error prone, so return void adn use seq_has_overflowed instead
Joe Perches (2):
seq_puts: Convert to return void and convert uses too.
seq_putc: Convert to return void and convert uses too.
drivers/char/ipmi/ipmi_msghandler.c | 4 +-
drivers/parisc/ccio-dma.c | 7 +-
drivers/regulator/dbx500-prcmu.c | 21 ++----
drivers/usb/gadget/udc/goku_udc.c | 81 +++++++++++-----------
drivers/watchdog/bcm_kona_wdt.c | 43 +++++++-----
fs/seq_file.c | 26 +++----
include/linux/seq_file.h | 4 +-
ipc/util.c | 6 +-
.../netfilter/nf_conntrack_l3proto_ipv4_compat.c | 4 +-
net/netfilter/nf_conntrack_expect.c | 4 +-
10 files changed, 105 insertions(+), 95 deletions(-)
--
2.1.2
^ permalink raw reply
* [PATCH -next 2/2] seq_putc: Convert to return void and convert uses too.
From: Joe Perches @ 2014-11-10 18:58 UTC (permalink / raw)
To: Steven Rostedt, Corey Minyard, Alexander Viro, Pablo Neira Ayuso,
Patrick McHardy, Jozsef Kadlecsik
Cc: Hideaki YOSHIFUJI, netdev, James Morris, Petr Mladek,
linux-kernel, coreteam, netfilter-devel, linux-fsdevel,
Alexey Kuznetsov, openipmi-developer, David S. Miller
In-Reply-To: <cover.1415645476.git.joe@perches.com>
Using the return value of seq_putc is error-prone, so
make it return void instead.
Reverse the logic in seq_putc to make it like seq_puts.
Signed-off-by: Joe Perches <joe@perches.com>
---
drivers/char/ipmi/ipmi_msghandler.c | 4 +++-
fs/seq_file.c | 11 ++++++-----
include/linux/seq_file.h | 2 +-
net/ipv4/netfilter/nf_conntrack_l3proto_ipv4_compat.c | 4 +++-
net/netfilter/nf_conntrack_expect.c | 4 +++-
5 files changed, 16 insertions(+), 9 deletions(-)
diff --git a/drivers/char/ipmi/ipmi_msghandler.c b/drivers/char/ipmi/ipmi_msghandler.c
index f816211..c12fb30 100644
--- a/drivers/char/ipmi/ipmi_msghandler.c
+++ b/drivers/char/ipmi/ipmi_msghandler.c
@@ -1953,7 +1953,9 @@ static int smi_ipmb_proc_show(struct seq_file *m, void *v)
seq_printf(m, "%x", intf->channels[0].address);
for (i = 1; i < IPMI_MAX_CHANNELS; i++)
seq_printf(m, " %x", intf->channels[i].address);
- return seq_putc(m, '\n');
+ seq_putc(m, '\n');
+
+ return 0;
}
static int smi_ipmb_proc_open(struct inode *inode, struct file *file)
diff --git a/fs/seq_file.c b/fs/seq_file.c
index e6be05a..5ca5af9 100644
--- a/fs/seq_file.c
+++ b/fs/seq_file.c
@@ -673,13 +673,14 @@ int seq_open_private(struct file *filp, const struct seq_operations *ops,
}
EXPORT_SYMBOL(seq_open_private);
-int seq_putc(struct seq_file *m, char c)
+void seq_putc(struct seq_file *m, char c)
{
- if (m->count < m->size) {
- m->buf[m->count++] = c;
- return 0;
+ if (m->count >= m->size) {
+ seq_set_overflow(m);
+ return;
}
- return -1;
+
+ m->buf[m->count++] = c;
}
EXPORT_SYMBOL(seq_putc);
diff --git a/include/linux/seq_file.h b/include/linux/seq_file.h
index 9b02cb6..c1e47ff 100644
--- a/include/linux/seq_file.h
+++ b/include/linux/seq_file.h
@@ -115,7 +115,7 @@ ssize_t seq_read(struct file *, char __user *, size_t, loff_t *);
loff_t seq_lseek(struct file *, loff_t, int);
int seq_release(struct inode *, struct file *);
int seq_escape(struct seq_file *, const char *, const char *);
-int seq_putc(struct seq_file *m, char c);
+void seq_putc(struct seq_file *m, char c);
void seq_puts(struct seq_file *m, const char *s);
int seq_write(struct seq_file *seq, const void *data, size_t len);
diff --git a/net/ipv4/netfilter/nf_conntrack_l3proto_ipv4_compat.c b/net/ipv4/netfilter/nf_conntrack_l3proto_ipv4_compat.c
index a460a87..f0dfe92 100644
--- a/net/ipv4/netfilter/nf_conntrack_l3proto_ipv4_compat.c
+++ b/net/ipv4/netfilter/nf_conntrack_l3proto_ipv4_compat.c
@@ -300,7 +300,9 @@ static int exp_seq_show(struct seq_file *s, void *v)
__nf_ct_l3proto_find(exp->tuple.src.l3num),
__nf_ct_l4proto_find(exp->tuple.src.l3num,
exp->tuple.dst.protonum));
- return seq_putc(s, '\n');
+ seq_putc(s, '\n');
+
+ return 0;
}
static const struct seq_operations exp_seq_ops = {
diff --git a/net/netfilter/nf_conntrack_expect.c b/net/netfilter/nf_conntrack_expect.c
index 91a1837..7a17070 100644
--- a/net/netfilter/nf_conntrack_expect.c
+++ b/net/netfilter/nf_conntrack_expect.c
@@ -561,7 +561,9 @@ static int exp_seq_show(struct seq_file *s, void *v)
helper->expect_policy[expect->class].name);
}
- return seq_putc(s, '\n');
+ seq_putc(s, '\n');
+
+ return 0;
}
static const struct seq_operations exp_seq_ops = {
--
2.1.2
------------------------------------------------------------------------------
Comprehensive Server Monitoring with Site24x7.
Monitor 10 servers for $9/Month.
Get alerted through email, SMS, voice calls or mobile push notifications.
Take corrective actions from your mobile device.
http://pubads.g.doubleclick.net/gampad/clk?id=154624111&iu=/4140/ostg.clktrk
^ permalink raw reply related
* Re: [patch net-next v2 01/10] net: rename netdev_phys_port_id to more generic name
From: Jamal Hadi Salim @ 2014-11-10 19:03 UTC (permalink / raw)
To: David Miller
Cc: jiri, netdev@vger.kernel.org, nhorman, andy, tgraf, dborkman,
ogerlitz, jesse, pshelar, azhou, ben, stephen, jeffrey.t.kirsher,
vyasevic, xiyou.wangcong, john.r.fastabend, edumazet, sfeldma,
f.fainelli, roopa, linville, jasowang, ebiederm, nicolas.dichtel,
ryazanov.s.a, buytenh, aviadr, nbd, alexei.starovoitov,
Neil.Jerram, ronye, simon.horman, alexander.h.duyck, john.ronciak,
mleitner, shrijeet, gospo, bc
In-Reply-To: <20141110.112857.1873381550982989519.davem@davemloft.net>
On 11/10/14 11:28, David Miller wrote:
> From: Jamal Hadi Salim <jhs@mojatatu.com>
>
> Jamal, this is really driving me crazy, this is a non-issue.
>
You are right Dave it is a non-issue, I am sorry. I was still humping on
the wrong tree on the attribute size change.
But please let us have the discussion so the right thing can happen.
I am not trying to beat up on Jiri. I actually think he is doing the
right thing; we just need to make sure input from other people is taken
into consideration because they have implemented on real devices.
cheers,
jamal
^ permalink raw reply
* Re: [patch net-next v2 06/10] bridge: introduce fdb offloading via switchdev
From: Roopa Prabhu @ 2014-11-10 19:03 UTC (permalink / raw)
To: Andy Gospodarek
Cc: Thomas Graf, Jiri Pirko, Jamal Hadi Salim, netdev, davem, nhorman,
andy, dborkman, ogerlitz, jesse, pshelar, azhou, ben, stephen,
jeffrey.t.kirsher, vyasevic, xiyou.wangcong, john.r.fastabend,
edumazet, sfeldma, f.fainelli, linville, jasowang, ebiederm,
nicolas.dichtel, ryazanov.s.a, buytenh, aviadr, nbd,
alexei.starovoitov, Neil.Jerram, ronye, simon.horman,
alexander.h.duyck, john.ronciak, mleitner, shrijeet
In-Reply-To: <20141110173058.GA2002@gospo.home.greyhouse.net>
On 11/10/14, 9:30 AM, Andy Gospodarek wrote:
> On Mon, Nov 10, 2014 at 01:51:00PM +0000, Thomas Graf wrote:
>> On 11/10/14 at 09:15am, Jiri Pirko wrote:
>>> There are few problems in re-using this. It is netlink based so for calling
>>> it from bridge code, we would have to construct netlink message. But
>>> that could be probably changed.
>>> As you can see from the list of parameters, this is no longer about fdb (addr,
>>> vlanid) but this has been extended to something else. See vxlan code for
>>> what this is used for. I believe that fdb_add/del should be renamed to
>>> something else, perhaps l2neigh_add/del or something like that.
>>> The other problem is that fdb_add/del is currently used by various
>>> drivers for different purpose (adding macs to unicast list).
>> Can you elaborate a bit on the intended semantic differences between
>> the existing ndo_fdb_add() and ndo_sw_port_fdb_add()? I'm not sure we
>> need the sw_ prefix for this specific ndo.
>>
>> I completely agree that relying on Netlink is wrong because we'll have
>> in-kernel users of the API but I believe that existing ndo_fdb_add()
>> implementations in i40e, ixgbe, qlcnic and macvlan could use the new
>> API you propose.
> I also think the same API could be used quite easily on the current
> drivers that use it.
>
> I was looking at this earlier today and there are only 5 drivers
> (outside the bridge code) that support ndo_fdb_add. The 3 hardware
> drivers and vxlan driver seem like they could use this new API. The
> macvlan code appears to simply set the uc and mc lists, which seems like
> it could be done other ways -- confirmation from John Fastabend, Roopa,
> and mst would be good.
yes, that is correct. The macvlan code, when not set for passthru mode,
seems to just program the uc-mc lists,
which again get synched to the lowerdev (and possibly from lowerdev to
hw in some cases).
I agree that it would be really nice if the existing api's can be made
to work.
>> How about we rename the existing ndo_fdb_add() to ndo_neigh_add() as
>> you propose and convert vxlan over to it and have all others which don't
>> even depend on the Netlink attributes being passed in (i40e, ixgbe,
>> qlcnic, macvlan) use ndo_fdb_add() which would have the behaviour of your
>> proposed ndo_sw_port_fdb_add()?
> I would much rather see something like Thomas proposes here. I know you
> would like to see these patches get included (I'm anxious to see better
> in-kernel offload support too!), but separate, possibly unnecessary
> APIs like this can get painful for driver maintainers (upstream and
> distro maintainers).
>
Ack!.
^ permalink raw reply
* Re: [PATCH net-next] cxgb4: Remove unnecessary struct in6_addr * casts
From: David Miller @ 2014-11-10 19:09 UTC (permalink / raw)
To: joe
Cc: hariprasad, netdev, leedom, anish, praveenm, nirranjan, kumaras,
j.vosburgh, vfalico, andy
In-Reply-To: <1415645298.8868.10.camel@perches.com>
From: Joe Perches <joe@perches.com>
Date: Mon, 10 Nov 2014 10:48:18 -0800
> btw: using "git format-patch -M" makes reading and
> verifying the patch a lot easier.
>
> Unfortunately, there's no current way to make this
> a global default for everyone, but I have this in
> my ~/.gitconfig:
None of those moves were pure moves, I adjusted the top-level
cpp guard names in every file plus there were some path changes
in net/bonding.h as well.
^ permalink raw reply
* Re: [patch net-next v2 06/10] bridge: introduce fdb offloading via switchdev
From: Jamal Hadi Salim @ 2014-11-10 19:13 UTC (permalink / raw)
To: Jiri Pirko
Cc: netdev, davem, nhorman, andy, tgraf, dborkman, ogerlitz, jesse,
pshelar, azhou, ben, stephen, jeffrey.t.kirsher, vyasevic,
xiyou.wangcong, john.r.fastabend, edumazet, sfeldma, f.fainelli,
roopa, linville, jasowang, ebiederm, nicolas.dichtel,
ryazanov.s.a, buytenh, aviadr, nbd, alexei.starovoitov,
Neil.Jerram, ronye, simon.horman, alexander.h.duyck, john.ronciak,
mleitner, shrijeet, gospo, bcrl
In-Reply-To: <20141110134715.GD4256@nanopsycho.orion>
On 11/10/14 08:47, Jiri Pirko wrote:
> Mon, Nov 10, 2014 at 01:47:33PM CET, jhs@mojatatu.com wrote:
>
> Because now, If you would like to pass one of NDA_DST, NDA_LLADDR,
> NDA_CACHEINFO, NDA_PROBES, NDA_VLAN, NDA_PORT, NDA_VNI, NDA_IFINDEX,
> NDA_MASTER values via ndo_fdb_add/del to the driver, you have to
> construct "struct nlattr *tb[]". Preprocessing this tb into struct might
> be suitable for some use-case, for some it may not.
>
Ok, I see what you mean now. yes, netlink attributes are passed around.
>
> What I try to say is that the naming ndo_fdb_add/del is not accurate
> because it is now used for far more than fdb (addr, vlan). See vxlan
> code for example.
>
In vxlan semantics that is an "fdb".
In any case, I am indifferent to be honest - netlink attributes in
this case seem to be easier. i.e For the driver:
Ignore what you dont want and suck in what you need (whether vxlan
or vlan or nvgre etc).
cheers,
jamal
^ permalink raw reply
* Re: [PATCH net 0/3] cxgb4/cxgb4vf: Misc. fixes for cxgb4vf
From: David Miller @ 2014-11-10 19:15 UTC (permalink / raw)
To: hariprasad; +Cc: netdev, leedom, nirranjan
In-Reply-To: <1415360191-25395-1-git-send-email-hariprasad@chelsio.com>
From: Hariprasad Shenai <hariprasad@chelsio.com>
Date: Fri, 7 Nov 2014 17:06:28 +0530
> For T5 use Packing and Padding Boundaries for SGE DMA transfers, move
> fl_starve_thres to adpater structure, since they are different for each
> adapter. The cxgb4vf driver's Free List Starvation Threshold needs to be larger
> than the SGE's Egress Congestion Threshold or we'll end up in a mutual stall
> where the driver waits for Ingress Packets to drive replacing Free List
> Pointers and the SGE waits for Free List Pointers before pushing Ingress
> Packets to the host.
>
> The patches series is created against 'net' tree.
> And includes patches on cxgb4 and cxgb4vf driver.
>
> We have included all the maintainers of respective drivers. Kindly review the
> change and let us know in case of any review comments.
Series applied, thanks.
^ permalink raw reply
* [PATCH] net: phy: Correctly handle MII ioctl which changes autonegotiation.
From: Brian Hill @ 2014-11-10 19:18 UTC (permalink / raw)
To: netdev
When advertised capabilities are changed with mii-tool,
such as:
mii-tool -A 10baseT
the existing handler has two errors.
- An actual PHY register value is provided by mii-tool, and this
must be mapped to internal state with mii_adv_to_ethtool_adv_t().
- The PHY state machine needs to be told that autonegotiation has
again been performed. If not, the MAC will not be notified of
the new link speed and duplex, resulting in a possible config
mismatch.
Signed-off-by: Brian Hill <Brian@houston-radar.com>
---
drivers/net/phy/phy.c | 36 ++++++++++++++++++++++++------------
1 file changed, 24 insertions(+), 12 deletions(-)
diff --git a/drivers/net/phy/phy.c b/drivers/net/phy/phy.c
index c94e2a2..ee9f0c9 100644
--- a/drivers/net/phy/phy.c
+++ b/drivers/net/phy/phy.c
@@ -352,6 +352,7 @@ int phy_mii_ioctl(struct phy_device *phydev, struct
ifreq *ifr, int cmd)
{
struct mii_ioctl_data *mii_data = if_mii(ifr);
u16 val = mii_data->val_in;
+ int change_autoneg = 0;
switch (cmd) {
case SIOCGMIIPHY:
@@ -367,22 +368,29 @@ int phy_mii_ioctl(struct phy_device *phydev,
struct ifreq *ifr, int cmd)
if (mii_data->phy_id == phydev->addr) {
switch (mii_data->reg_num) {
case MII_BMCR:
- if ((val & (BMCR_RESET | BMCR_ANENABLE)) == 0)
+ if ((val & (BMCR_RESET | BMCR_ANENABLE)) == 0) {
+ if (phydev->autoneg == AUTONEG_ENABLE)
+ change_autoneg = 1;
phydev->autoneg = AUTONEG_DISABLE;
- else
+ if (val & BMCR_FULLDPLX)
+ phydev->duplex = DUPLEX_FULL;
+ else
+ phydev->duplex = DUPLEX_HALF;
+ if (val & BMCR_SPEED1000)
+ phydev->speed = SPEED_1000;
+ else if (val & BMCR_SPEED100)
+ phydev->speed = SPEED_100;
+ else phydev->speed = SPEED_10;
+ }
+ else {
+ if (phydev->autoneg == AUTONEG_DISABLE)
+ change_autoneg = 1;
phydev->autoneg = AUTONEG_ENABLE;
- if (!phydev->autoneg && (val & BMCR_FULLDPLX))
- phydev->duplex = DUPLEX_FULL;
- else
- phydev->duplex = DUPLEX_HALF;
- if (!phydev->autoneg && (val & BMCR_SPEED1000))
- phydev->speed = SPEED_1000;
- else if (!phydev->autoneg &&
- (val & BMCR_SPEED100))
- phydev->speed = SPEED_100;
+ }
break;
case MII_ADVERTISE:
- phydev->advertising = val;
+ phydev->advertising = mii_adv_to_ethtool_adv_t(val);
+ change_autoneg = 1;
break;
default:
/* do nothing */
@@ -396,6 +404,10 @@ int phy_mii_ioctl(struct phy_device *phydev, struct
ifreq *ifr, int cmd)
if (mii_data->reg_num == MII_BMCR &&
val & BMCR_RESET)
return phy_init_hw(phydev);
+
+ if (change_autoneg)
+ return phy_start_aneg(phydev);
+
return 0;
case SIOCSHWTSTAMP:
--
1.7.9.5
^ permalink raw reply related
page: next (older) | prev (newer) | latest
- recent:[subjects (threaded)|topics (new)|topics (active)]
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox