Netdev List
 help / color / mirror / Atom feed
* Re: [PATCH 4/8] net: fs_enet: use platform_{get,set}_drvdata()
From: Sergei Shtylyov @ 2013-08-12 18:16 UTC (permalink / raw)
  To: Libo Chen
  Cc: pantelis.antoniou, vbordug, David Miller, linuxppc-dev, netdev,
	LKML, Li Zefan
In-Reply-To: <5208E222.60300@huawei.com>

On 08/12/2013 05:24 PM, Libo Chen wrote:

> Use the wrapper functions for getting and setting the driver data using
> platform_device instead of using dev_{get,set}_drvdata() with &pdev->dev,
> so we can directly pass a struct platform_device.

> Signed-off-by: Libo Chen <libo.chen@huawei.com>
> ---
>   .../net/ethernet/freescale/fs_enet/fs_enet-main.c  |    1 -
>   1 files changed, 0 insertions(+), 1 deletions(-)

> diff --git a/drivers/net/ethernet/freescale/fs_enet/fs_enet-main.c b/drivers/net/ethernet/freescale/fs_enet/fs_enet-main.c
> index 8de53a1..7e3de10 100644
> --- a/drivers/net/ethernet/freescale/fs_enet/fs_enet-main.c
> +++ b/drivers/net/ethernet/freescale/fs_enet/fs_enet-main.c
> @@ -1122,7 +1122,6 @@ static int fs_enet_remove(struct platform_device *ofdev)
>
>   	fep->ops->free_bd(ndev);
>   	fep->ops->cleanup_data(ndev);
> -	dev_set_drvdata(fep->dev, NULL);
>   	of_node_put(fep->fpi->phy_node);
>   	free_netdev(ndev);
>   	return 0;

    Changelog simply doesn't match the patch.

WBR, Sergei

^ permalink raw reply

* Re: [PATCH 1/8] net: fsl_pq_mdio: use platform_{get,set}_drvdata()
From: Sergei Shtylyov @ 2013-08-12 18:10 UTC (permalink / raw)
  To: Libo Chen; +Cc: David Miller, netdev, LKML, Li Zefan, timur
In-Reply-To: <5208E215.6030007@huawei.com>

Hello.

On 08/12/2013 05:24 PM, Libo Chen wrote:

> Use the wrapper functions for getting and setting the driver data using
> platform_device instead of using dev_{get,set}_drvdata() with &pdev->dev,
> so we can directly pass a struct platform_device.

> Signed-off-by: Libo Chen <libo.chen@huawei.com>
> ---
>   drivers/net/ethernet/freescale/fsl_pq_mdio.c |    3 +--
>   1 files changed, 1 insertions(+), 2 deletions(-)

> diff --git a/drivers/net/ethernet/freescale/fsl_pq_mdio.c b/drivers/net/ethernet/freescale/fsl_pq_mdio.c
> index c93a056..995a3ab 100644
> --- a/drivers/net/ethernet/freescale/fsl_pq_mdio.c
> +++ b/drivers/net/ethernet/freescale/fsl_pq_mdio.c
[...]
> @@ -468,7 +468,6 @@ static int fsl_pq_mdio_remove(struct platform_device *pdev)
>
>   	mdiobus_unregister(bus);
>
> -	dev_set_drvdata(device, NULL);

    You don't mention this in the changelog.

WBR, Sergei

^ permalink raw reply

* Re: [patch net] ipv6: do not create neighbor entries for local delivery
From: Marcelo Ricardo Leitner @ 2013-08-12 18:09 UTC (permalink / raw)
  To: Debabrata Banerjee, Jiri Pirko, davem@davemloft.net,
	netdev@vger.kernel.org, Alexey Kuznetsov, jmorris@namei.org,
	yoshfuji@linux-ipv6.org, Patrick McHardy, Banerjee, Debabrata,
	Joshua Hunt
In-Reply-To: <20130808201627.GI14001@order.stressinduktion.org>

[-- Attachment #1: Type: text/plain, Size: 4060 bytes --]

Em 08-08-2013 17:16, Hannes Frederic Sowa escreveu:
> On Thu, Aug 08, 2013 at 09:47:02PM +0200, Hannes Frederic Sowa wrote:
>> On Thu, Aug 08, 2013 at 02:45:40PM -0400, Debabrata Banerjee wrote:
>>> On Wed, Jan 30, 2013 at 3:26 AM, Jiri Pirko <jiri@resnulli.us> wrote:
>>>> From: Marcelo Ricardo Leitner <mleitner@redhat.com>
>>>>
>>>> They will be created at output, if ever needed. This avoids creating
>>>> empty neighbor entries when TPROXYing/Forwarding packets for addresses
>>>> that are not even directly reachable.
>>>>
>>>> Note that IPv4 already handles it this way. No neighbor entries are
>>>> created for local input.
>>>>
>>>> Tested by myself and customer.
>>>>
>>>> Signed-off-by: Jiri Pirko <jiri@resnulli.us>
>>>> Signed-off-by: Marcelo Ricardo Leitner <mleitner@redhat.com>
>>>> ---
>>>>   net/ipv6/route.c | 2 +-
>>>>   1 file changed, 1 insertion(+), 1 deletion(-)
>>>>
>>>> diff --git a/net/ipv6/route.c b/net/ipv6/route.c
>>>> index e229a3b..363d8b7 100644
>>>> --- a/net/ipv6/route.c
>>>> +++ b/net/ipv6/route.c
>>>> @@ -928,7 +928,7 @@ restart:
>>>>          dst_hold(&rt->dst);
>>>>          read_unlock_bh(&table->tb6_lock);
>>>>
>>>> -       if (!rt->n && !(rt->rt6i_flags & RTF_NONEXTHOP))
>>>> +       if (!rt->n && !(rt->rt6i_flags & (RTF_NONEXTHOP | RTF_LOCAL)))
>>>>                  nrt = rt6_alloc_cow(rt, &fl6->daddr, &fl6->saddr);
>>>>          else if (!(rt->dst.flags & DST_HOST))
>>>>                  nrt = rt6_alloc_clone(rt, &fl6->daddr);
>>>
>>>
>>>
>>> I'm not sure this patch is doing the right thing. It seems to break
>>> IPv6 loopback functionality, it is no longer equivalent to IPv4, as
>>> stated above. It doesn't just stop neighbor creation but it stops
>>> cached route creation. Seems like a scary change for a stable tree.
>>> See below:
>>>
>>> $ ip -4 route show local
>>> local 127.0.0.0/8 dev lo  proto kernel  scope host  src 127.0.0.1
>>>
>>> This local route enables us to use the whole loopback network, any
>>> address inside 127.0.0.0/8 will work.
>>>
>>> $ ping -c1 127.0.0.9
>>> PING 127.0.0.9 (127.0.0.9) 56(84) bytes of data.
>>> 64 bytes from 127.0.0.9: icmp_seq=1 ttl=64 time=0.012 ms
>>>
>>> --- 127.0.0.9 ping statistics ---
>>> 1 packets transmitted, 1 received, 0% packet loss, time 0ms
>>> rtt min/avg/max/mdev = 0.012/0.012/0.012/0.000 ms
>>>
>>> This also used to work equivalently for IPv6 local loopback routes:
>>>
>>> $ ip -6 route add local 2001:::/64 dev lo
>>> $ ping6 -c1 2001::9
>>> PING 2001::9(2001::9) 56 data bytes
>>> 64 bytes from 2001::9: icmp_seq=1 ttl=64 time=0.010 ms
>>>
>>> --- 2001::9 ping statistics ---
>>> 1 packets transmitted, 1 received, 0% packet loss, time 0ms
>>> rtt min/avg/max/mdev = 0.010/0.010/0.010/0.000 ms
>>>
>>> However with this patch, this is very broken:
>>>
>>> $ ip -6 route add local 2001::/64 dev lo
>>> $ ping6 -c1 2001::9
>>> PING 2001::9(2001::9) 56 data bytes
>>> ping: sendmsg: Invalid argument
>>
>> I do think that the patch above is fine. I wonder why you get a blackhole
>> route back here. Maybe backtracking in ip6_pol_route or in fib6_lookup_1 was
>> way too aggressive?
>
> Ah sorry, before rt->n removal everything worked a bit
> different. rt6_alloc_cow did fill rt->n back then. To fix both things
> we would have to bind a neighbour towards the loopback interface into
> the non-cloned rt6_info if it feeds packets towards lo. Pretty big change for
> old stable kernels, I guess. :/
>
> Marcelo, any idea how to deal with this? My guess would be a revert, but I
> don't know the impact on the tproxy issue.

Hannes, would something like this be acceptable? I'm hoping it's not too 
ugly/hacky... as far as I could track back, input and output routines were 
merged mainly due code similarity.

TPROXY scenario needs to not create this neighbor entries on INPUT path, while 
Debabrata ping test needs it on OUTPUT path. This patch limits my previous 
patch to INPUT only then.

Initial testing here seems good, TPROXY seems to be working as expected and 
also the ping6 test.

What do you think?

Regards,
Marcelo


[-- Attachment #2: ipv6-rt.patch --]
[-- Type: text/x-patch, Size: 1914 bytes --]

diff --git a/net/ipv6/route.c b/net/ipv6/route.c
index 18ea73c..603f9d9 100644
--- a/net/ipv6/route.c
+++ b/net/ipv6/route.c
@@ -791,7 +791,7 @@ static struct rt6_info *rt6_alloc_clone(struct rt6_info *ort,
 }
 
 static struct rt6_info *ip6_pol_route(struct net *net, struct fib6_table *table, int oif,
-				      struct flowi6 *fl6, int flags)
+				      struct flowi6 *fl6, int flags, int output)
 {
 	struct fib6_node *fn;
 	struct rt6_info *rt, *nrt;
@@ -799,8 +799,11 @@ static struct rt6_info *ip6_pol_route(struct net *net, struct fib6_table *table,
 	int attempts = 3;
 	int err;
 	int reachable = net->ipv6.devconf_all->forwarding ? 0 : RT6_LOOKUP_F_REACHABLE;
+	int local = RTF_NONEXTHOP;
 
 	strict |= flags & RT6_LOOKUP_F_IFACE;
+	if (!output)
+			local |= RTF_LOCAL;
 
 relookup:
 	read_lock_bh(&table->tb6_lock);
@@ -820,7 +823,7 @@ restart:
 	read_unlock_bh(&table->tb6_lock);
 
 	if (!dst_get_neighbour_raw(&rt->dst)
-	    && !(rt->rt6i_flags & (RTF_NONEXTHOP | RTF_LOCAL)))
+	    && !(rt->rt6i_flags & local))
 		nrt = rt6_alloc_cow(rt, &fl6->daddr, &fl6->saddr);
 	else if (!(rt->dst.flags & DST_HOST))
 		nrt = rt6_alloc_clone(rt, &fl6->daddr);
@@ -864,7 +867,7 @@ out2:
 static struct rt6_info *ip6_pol_route_input(struct net *net, struct fib6_table *table,
 					    struct flowi6 *fl6, int flags)
 {
-	return ip6_pol_route(net, table, fl6->flowi6_iif, fl6, flags);
+	return ip6_pol_route(net, table, fl6->flowi6_iif, fl6, flags, 0);
 }
 
 void ip6_route_input(struct sk_buff *skb)
@@ -890,7 +893,7 @@ void ip6_route_input(struct sk_buff *skb)
 static struct rt6_info *ip6_pol_route_output(struct net *net, struct fib6_table *table,
 					     struct flowi6 *fl6, int flags)
 {
-	return ip6_pol_route(net, table, fl6->flowi6_oif, fl6, flags);
+	return ip6_pol_route(net, table, fl6->flowi6_oif, fl6, flags, 1);
 }
 
 struct dst_entry * ip6_route_output(struct net *net, const struct sock *sk,

^ permalink raw reply related

* SCTP and IP_TOS
From: Ben Greear @ 2013-08-12 17:00 UTC (permalink / raw)
  To: netdev

Hello!

I notice that I read 0x2 as IP_TOS getsockopt on an SCTP socket configured
for streaming mode.

Looks to me like the reason is that SCTP uses a socket type of SCTP_SOCKET_TCP
and the ipv4/ip_sockglue.c code is only masking out ECN for SOCK_STREAM types.

Is this per design, or should the ip_sockglue.c mask out ECN for SCTP_SOCKET_TCP
types as well?

Thanks,
Ben

-- 
Ben Greear <greearb@candelatech.com>
Candela Technologies Inc  http://www.candelatech.com

^ permalink raw reply

* Re: Where are OVS VXLAN patches?
From: Jesse Gross @ 2013-08-12 16:59 UTC (permalink / raw)
  To: Cong Wang; +Cc: David S. Miller, netdev, Pravin B Shelar, Stephen Hemminger
In-Reply-To: <1376291275.17589.18.camel@cr0>

On Mon, Aug 12, 2013 at 12:07 AM, Cong Wang <amwang@redhat.com> wrote:
> Hello, David
>
> I am wondering where are the patches for OVS VXLAN support from Pravin?
> v7 were posted one week ago:
> http://marc.info/?l=linux-netdev&m=137572485116601&w=2
>
> and no one complains about them, so I think they are ready for merge?
>
> But they still do not appear in net-next, nor I can find them in vxlan
> tree of Stephen or openvswitch tree of Jesse. What's more, I even can't
> find them in netdev patchwork [1].

I believe that Stephen is planning on taking the first part of the
series through his VXLAN tree.

^ permalink raw reply

* Re: [PATCH 8/8] net: davinci_mdio: use platform_{get,set}_drvdata()
From: Mugunthan V N @ 2013-08-12 16:53 UTC (permalink / raw)
  To: Libo Chen
  Cc: David Miller, bigeasy, prabhakar.csengg, b-liu, netdev, LKML,
	Li Zefan
In-Reply-To: <5208E231.60104@huawei.com>

On Monday 12 August 2013 06:55 PM, Libo Chen wrote:
> Use the wrapper functions for getting and setting the driver data using
> platform_device instead of using dev_{get,set}_drvdata() with &pdev->dev,
> so we can directly pass a struct platform_device.
>
> Signed-off-by: Libo Chen <libo.chen@huawei.com>
Looks good.
Acked-by: Mugunthan V N <mugunthanvnm@ti.com>

Regards
Mugunthan V N

^ permalink raw reply

* Re: [PATCH net-next] net/mlx4_en: Advertise HIGH DMA support only if dma mask is 64 bit
From: Ben Hutchings @ 2013-08-12 16:32 UTC (permalink / raw)
  To: Amir Vadai; +Cc: David S. Miller, netdev, Or Gerlitz, Alexander Guller
In-Reply-To: <1376296230-12276-1-git-send-email-amirv@mellanox.com>

On Mon, 2013-08-12 at 11:30 +0300, Amir Vadai wrote:
> Need to check that the pci device DMA mask was set to 64 bit support
> (done by mlx4_core) before advertising HIGH DMA support in higher drivers.
> Otherwise, may run into an issue that skb/frag/data is in high memory
> and can't dma map it, thus packets are dropped.

NETIF_F_HIGHDMA means that the driver can transmit skbs with page
fragments in high memory, i.e. it doesn't require them to have an
existing virtual mapping for the kernel.  If I'm not mistaken, this
should be cleared only for drivers that don't use DMA or kmap functions.

On a 64-bit machine there is no highmem and without NETIF_F_HIGHDMA you
can still be given pages at any physical address.

On a 32-bit machine highmem usually starts at 1GB and I doubt you have
any chips that are that limited in DMA range. :-)

I really doubt this is the fix you're looking for.

Ben.

> Signed-off-by: Alexander Guller <alexg@mellanox.com>
> Signed-off-by: Amir Vadai <amirv@mellanox.com>
> ---
>  drivers/net/ethernet/mellanox/mlx4/en_netdev.c | 6 +++++-
>  1 file changed, 5 insertions(+), 1 deletion(-)
> 
> diff --git a/drivers/net/ethernet/mellanox/mlx4/en_netdev.c b/drivers/net/ethernet/mellanox/mlx4/en_netdev.c
> index fa37b7a..9568b77 100644
> --- a/drivers/net/ethernet/mellanox/mlx4/en_netdev.c
> +++ b/drivers/net/ethernet/mellanox/mlx4/en_netdev.c
> @@ -2317,9 +2317,13 @@ int mlx4_en_init_netdev(struct mlx4_en_dev *mdev, int port,
>  	dev->vlan_features = dev->hw_features;
>  
>  	dev->hw_features |= NETIF_F_RXCSUM | NETIF_F_RXHASH;
> -	dev->features = dev->hw_features | NETIF_F_HIGHDMA |
> +	dev->features = dev->hw_features |
>  			NETIF_F_HW_VLAN_CTAG_TX | NETIF_F_HW_VLAN_CTAG_RX |
>  			NETIF_F_HW_VLAN_CTAG_FILTER;
> +
> +	if (mdev->dev->pdev->dma_mask == DMA_BIT_MASK(64))
> +		dev->features |= NETIF_F_HIGHDMA;
> +
>  	dev->hw_features |= NETIF_F_LOOPBACK;
>  
>  	if (mdev->dev->caps.steering_mode ==

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

^ permalink raw reply

* [PATCH] rtnetlink: rtnl_bridge_getlink: Call nlmsg_find_attr() with ifinfomsg header
From: Asbjoern Sloth Toennesen @ 2013-08-12 16:30 UTC (permalink / raw)
  To: David S. Miller, Vlad Yasevich, Stephen Hemminger, netdev, bridge
  Cc: linux-kernel
In-Reply-To: <52090C26.4090001@fiberby.net>

Fix the iproute2 command `bridge vlan show`, after switching from
rtgenmsg to ifinfomsg.

Signed-off-by: Asbjoern Sloth Toennesen <ast@fiberby.net>
---
 net/core/rtnetlink.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/net/core/rtnetlink.c b/net/core/rtnetlink.c
index 3de7408..a043171 100644
--- a/net/core/rtnetlink.c
+++ b/net/core/rtnetlink.c
@@ -2384,7 +2384,7 @@ static int rtnl_bridge_getlink(struct sk_buff *skb, struct netlink_callback *cb)
 	struct nlattr *extfilt;
 	u32 filter_mask = 0;
 
-	extfilt = nlmsg_find_attr(cb->nlh, sizeof(struct rtgenmsg),
+	extfilt = nlmsg_find_attr(cb->nlh, sizeof(struct ifinfomsg),
 				  IFLA_EXT_MASK);
 	if (extfilt)
 		filter_mask = nla_get_u32(extfilt);
-- 
1.8.4.rc1

^ permalink raw reply related

* Bridge VLAN kernel/iproute2 incompatibility
From: Asbjørn Sloth Tønnesen @ 2013-08-12 16:24 UTC (permalink / raw)
  To: David S. Miller, Vlad Yasevich, Stephen Hemminger, netdev, bridge
  Cc: linux-kernel

Hi,

Let's start with a little history:

Feb 20:   Vlad Yasevich got his VLAN-aware bridge patchset included in
          the 3.9 merge window.
          In the kernel commit 6cbdceeb, he added attribute support to
          bridge GETLINK requests sent with rtgenmsg.

Mar 6th:  Vlad got this iproute2 reference implementation of the bridge
          vlan netlink interface accepted (iproute2 9eff0e5c)

Apr 25th: iproute2 switched from using rtgenmsg to ifinfomsg (63338dca)
          http://patchwork.ozlabs.org/patch/239602/
          http://marc.info/?t=136680900700007

Apr 28th: Linus released 3.9

Apr 30th: Stephen released iproute2 3.9.0

The `bridge vlan show` command haven't been working since the switch to
ifinfomsg, or in a released version of iproute2. Since the kernel side
only supports rtgenmsg, which iproute2 switched away from just prior to
the iproute2 3.9.0 release.

I haven't been able to find any documentation, about neither rtgenmsg
nor ifinfomsg, and in which situation to use which, but kernel commit
88c5b5ce seams to suggest that ifinfomsg should be used.

Fixing this in kernel will break compatibility, but I doubt that anybody
have been using it due to this bug in the user space reference
implementation, at least not without noticing this bug. That said the
functionality is still fully functional in 3.9, when reversing iproute2
commit 63338dca.

This could also be fixed in iproute2, but thats an ugly patch that would
reintroduce rtgenmsg in iproute2, and from searching in netdev it seams
like rtgenmsg usage is discouraged. I'm assuming that the only reason
that Vlad implemented the kernel side to use rtgenmsg, was because
iproute2 was using it at the time.

I will reply with kernel patch, I can also post the alternative iproute2
patch if requested.

-- 
Best regards
Asbjørn Sloth Tønnesen
Network engineer
Fiberby ApS - AS42541

^ permalink raw reply

* How to debug a driver which hangs (niu)?
From: Andrew Brooks @ 2013-08-12 15:06 UTC (permalink / raw)
  To: Linux Net-Dev Mailing List

Hello

I'm using a network driver (niu) which regularly locks-up after
printing the message "transmit timed out"
(i.e. nothing else can be sent/received over that interface after the event).

Does anyone have any tips for helping me to debug this?
eg. how to find out what is causing the transmit timed out message;
how to find out what state the driver is going into which causes the lock-up;
how to get it out of this state and working again?

I'm a programmer but I'm new to kernel drivers so all tips are most
welcome, thanks!

Andrew

^ permalink raw reply

* Re: [PATCH] stmmac: fix init_dma_desc_rings() to handle errors
From: Denis Kirjanov @ 2013-08-12 13:46 UTC (permalink / raw)
  To: Bartlomiej Zolnierkiewicz; +Cc: Giuseppe Cavallaro, netdev
In-Reply-To: <5200219.68Ai310MOF@amdc1032>

On 8/12/13, Bartlomiej Zolnierkiewicz <b.zolnierkie@samsung.com> wrote:
> On Friday, August 09, 2013 11:51:19 PM Denis Kirjanov wrote:
>> On 8/9/13, Bartlomiej Zolnierkiewicz <b.zolnierkie@samsung.com> wrote:
>> > In stmmac_init_rx_buffers():
>> > * add missing handling of dma_map_single() error
>> > * remove superfluous unlikely() optimization while at it
>> >
>> > Add stmmac_free_rx_buffers() helper and use it in dma_free_rx_skbufs().
>> >
>> > In init_dma_desc_rings():
>> > * add missing handling of kmalloc_array() errors
>> > * fix handling of dma_alloc_coherent() and stmmac_init_rx_buffers()
>> > errors
>> > * make function return an error value on error and 0 on success
>> >
>> > In stmmac_open():
>> > * add handling of init_dma_desc_rings() return value
>> >
>> > Signed-off-by: Bartlomiej Zolnierkiewicz <b.zolnierkie@samsung.com>
>> > Signed-off-by: Kyungmin Park <kyungmin.park@samsung.com>
>> > ---
>> >  drivers/net/ethernet/stmicro/stmmac/stmmac_main.c |  111
>> > ++++++++++++++++++----
>> >  1 file changed, 92 insertions(+), 19 deletions(-)
>> >
>> > Index: b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
>> > ===================================================================
>> > --- a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c	2013-08-08
>> > 14:36:44.000000000 +0200
>> > +++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c	2013-08-08
>> > 15:31:27.015438117 +0200
>> > @@ -939,15 +939,20 @@ static int stmmac_init_rx_buffers(struct
>> >
>> >  	skb = __netdev_alloc_skb(priv->dev, priv->dma_buf_sz + NET_IP_ALIGN,
>> >  				 GFP_KERNEL);
>> > -	if (unlikely(skb == NULL)) {
>> > +	if (!skb) {
>> >  		pr_err("%s: Rx init fails; skb is NULL\n", __func__);
>> > -		return 1;
>> > +		return -ENOMEM;
>> >  	}
>> >  	skb_reserve(skb, NET_IP_ALIGN);
>> >  	priv->rx_skbuff[i] = skb;
>> >  	priv->rx_skbuff_dma[i] = dma_map_single(priv->device, skb->data,
>> >  						priv->dma_buf_sz,
>> >  						DMA_FROM_DEVICE);
>> > +	if (dma_mapping_error(priv->device, priv->rx_skbuff_dma[i])) {
>> > +		pr_err("%s: DMA mapping error\n", __func__);
>> > +		dev_kfree_skb_any(skb);
>> > +		return -EINVAL;
>> > +	}
>>
>> If dma fail here then you can crash in stmmac_free_rx_buffers()
>> while touching priv->rx_skbuff[i]
>
> Are you sure?
>
> stmmac_free_rx_buffers() is not called for the current "i" but only
> for the (fully initialized) past ones (please note "--i" in while loop
> under err_init_rx_buffers label).

Yes, you're right. I've missed stmmac_init_rx_buffers() return code check.

Thanks.
>
> Best regards,
> --
> Bartlomiej Zolnierkiewicz
> Samsung R&D Institute Poland
> Samsung Electronics
>
>> >  	p->des2 = priv->rx_skbuff_dma[i];
>> >
>> > @@ -958,6 +963,16 @@ static int stmmac_init_rx_buffers(struct
>> >  	return 0;
>> >  }
>> >
>> > +static void stmmac_free_rx_buffers(struct stmmac_priv *priv, int i)
>> > +{
>> > +	if (priv->rx_skbuff[i]) {
>> > +		dma_unmap_single(priv->device, priv->rx_skbuff_dma[i],
>> > +				 priv->dma_buf_sz, DMA_FROM_DEVICE);
>> > +		dev_kfree_skb_any(priv->rx_skbuff[i]);
>> > +	}
>> > +	priv->rx_skbuff[i] = NULL;
>> > +}
>> > +
>> >  /**
>> >   * init_dma_desc_rings - init the RX/TX descriptor rings
>> >   * @dev: net device structure
>> > @@ -965,13 +980,14 @@ static int stmmac_init_rx_buffers(struct
>> >   * and allocates the socket buffers. It suppors the chained and ring
>> >   * modes.
>> >   */
>> > -static void init_dma_desc_rings(struct net_device *dev)
>> > +static int init_dma_desc_rings(struct net_device *dev)
>> >  {
>> >  	int i;
>> >  	struct stmmac_priv *priv = netdev_priv(dev);
>> >  	unsigned int txsize = priv->dma_tx_size;
>> >  	unsigned int rxsize = priv->dma_rx_size;
>> >  	unsigned int bfsize = 0;
>> > +	int ret = -ENOMEM;
>> >
>> >  	/* Set the max buffer size according to the DESC mode
>> >  	 * and the MTU. Note that RING mode allows 16KiB bsize.
>> > @@ -992,34 +1008,60 @@ static void init_dma_desc_rings(struct n
>> >  							  dma_extended_desc),
>> >  						   &priv->dma_rx_phy,
>> >  						   GFP_KERNEL);
>> > +		if (!priv->dma_erx)
>> > +			goto err_dma;
>> > +
>> >  		priv->dma_etx = dma_alloc_coherent(priv->device, txsize *
>> >  						   sizeof(struct
>> >  							  dma_extended_desc),
>> >  						   &priv->dma_tx_phy,
>> >  						   GFP_KERNEL);
>> > -		if ((!priv->dma_erx) || (!priv->dma_etx))
>> > -			return;
>> > +		if (!priv->dma_etx) {
>> > +			dma_free_coherent(priv->device, priv->dma_rx_size *
>> > +					sizeof(struct dma_extended_desc),
>> > +					priv->dma_erx, priv->dma_rx_phy);
>> > +			goto err_dma;
>> > +		}
>> >  	} else {
>> >  		priv->dma_rx = dma_alloc_coherent(priv->device, rxsize *
>> >  						  sizeof(struct dma_desc),
>> >  						  &priv->dma_rx_phy,
>> >  						  GFP_KERNEL);
>> > +		if (!priv->dma_rx)
>> > +			goto err_dma;
>> > +
>> >  		priv->dma_tx = dma_alloc_coherent(priv->device, txsize *
>> >  						  sizeof(struct dma_desc),
>> >  						  &priv->dma_tx_phy,
>> >  						  GFP_KERNEL);
>> > -		if ((!priv->dma_rx) || (!priv->dma_tx))
>> > -			return;
>> > +		if (!priv->dma_tx) {
>> > +			dma_free_coherent(priv->device, priv->dma_rx_size *
>> > +					sizeof(struct dma_desc),
>> > +					priv->dma_rx, priv->dma_rx_phy);
>> > +			goto err_dma;
>> > +		}
>> >  	}
>> >
>> >  	priv->rx_skbuff_dma = kmalloc_array(rxsize, sizeof(dma_addr_t),
>> >  					    GFP_KERNEL);
>> > +	if (!priv->rx_skbuff_dma)
>> > +		goto err_rx_skbuff_dma;
>> > +
>> >  	priv->rx_skbuff = kmalloc_array(rxsize, sizeof(struct sk_buff *),
>> >  					GFP_KERNEL);
>> > +	if (!priv->rx_skbuff)
>> > +		goto err_rx_skbuff;
>> > +
>> >  	priv->tx_skbuff_dma = kmalloc_array(txsize, sizeof(dma_addr_t),
>> >  					    GFP_KERNEL);
>> > +	if (!priv->tx_skbuff_dma)
>> > +		goto err_tx_skbuff_dma;
>> > +
>> >  	priv->tx_skbuff = kmalloc_array(txsize, sizeof(struct sk_buff *),
>> >  					GFP_KERNEL);
>> > +	if (!priv->tx_skbuff)
>> > +		goto err_tx_skbuff;
>> > +
>> >  	if (netif_msg_probe(priv)) {
>> >  		pr_debug("(%s) dma_rx_phy=0x%08x dma_tx_phy=0x%08x\n", __func__,
>> >  			 (u32) priv->dma_rx_phy, (u32) priv->dma_tx_phy);
>> > @@ -1034,8 +1076,9 @@ static void init_dma_desc_rings(struct n
>> >  		else
>> >  			p = priv->dma_rx + i;
>> >
>> > -		if (stmmac_init_rx_buffers(priv, p, i))
>> > -			break;
>> > +		ret = stmmac_init_rx_buffers(priv, p, i);
>> > +		if (ret)
>> > +			goto err_init_rx_buffers;
>> >
>> >  		if (netif_msg_probe(priv))
>> >  			pr_debug("[%p]\t[%p]\t[%x]\n", priv->rx_skbuff[i],
>> > @@ -1081,20 +1124,44 @@ static void init_dma_desc_rings(struct n
>> >
>> >  	if (netif_msg_hw(priv))
>> >  		stmmac_display_rings(priv);
>> > +
>> > +	return 0;
>> > +err_init_rx_buffers:
>> > +	while (--i >= 0)
>> > +		stmmac_free_rx_buffers(priv, i);
>> > +	kfree(priv->tx_skbuff);
>> > +err_tx_skbuff:
>> > +	kfree(priv->tx_skbuff_dma);
>> > +err_tx_skbuff_dma:
>> > +	kfree(priv->rx_skbuff);
>> > +err_rx_skbuff:
>> > +	kfree(priv->rx_skbuff_dma);
>> > +err_rx_skbuff_dma:
>> > +	if (priv->extend_desc) {
>> > +		dma_free_coherent(priv->device, priv->dma_tx_size *
>> > +				  sizeof(struct dma_extended_desc),
>> > +				  priv->dma_etx, priv->dma_tx_phy);
>> > +		dma_free_coherent(priv->device, priv->dma_rx_size *
>> > +				  sizeof(struct dma_extended_desc),
>> > +				  priv->dma_erx, priv->dma_rx_phy);
>> > +	} else {
>> > +		dma_free_coherent(priv->device,
>> > +				priv->dma_tx_size * sizeof(struct dma_desc),
>> > +				priv->dma_tx, priv->dma_tx_phy);
>> > +		dma_free_coherent(priv->device,
>> > +				priv->dma_rx_size * sizeof(struct dma_desc),
>> > +				priv->dma_rx, priv->dma_rx_phy);
>> > +	}
>> > +err_dma:
>> > +	return ret;
>> >  }
>> >
>> >  static void dma_free_rx_skbufs(struct stmmac_priv *priv)
>> >  {
>> >  	int i;
>> >
>> > -	for (i = 0; i < priv->dma_rx_size; i++) {
>> > -		if (priv->rx_skbuff[i]) {
>> > -			dma_unmap_single(priv->device, priv->rx_skbuff_dma[i],
>> > -					 priv->dma_buf_sz, DMA_FROM_DEVICE);
>> > -			dev_kfree_skb_any(priv->rx_skbuff[i]);
>> > -		}
>> > -		priv->rx_skbuff[i] = NULL;
>> > -	}
>> > +	for (i = 0; i < priv->dma_rx_size; i++)
>> > +		stmmac_free_rx_buffers(priv, i);
>> >  }
>> >
>> >  static void dma_free_tx_skbufs(struct stmmac_priv *priv)
>> > @@ -1560,12 +1627,17 @@ static int stmmac_open(struct net_device
>> >  	priv->dma_tx_size = STMMAC_ALIGN(dma_txsize);
>> >  	priv->dma_rx_size = STMMAC_ALIGN(dma_rxsize);
>> >  	priv->dma_buf_sz = STMMAC_ALIGN(buf_sz);
>> > -	init_dma_desc_rings(dev);
>> > +
>> > +	ret = init_dma_desc_rings(dev);
>> > +	if (ret < 0) {
>> > +		pr_err("%s: DMA descriptors initialization failed\n", __func__);
>> > +		goto dma_desc_error;
>> > +	}
>> >
>> >  	/* DMA initialization and SW reset */
>> >  	ret = stmmac_init_dma_engine(priv);
>> >  	if (ret < 0) {
>> > -		pr_err("%s: DMA initialization failed\n", __func__);
>> > +		pr_err("%s: DMA engine initialization failed\n", __func__);
>> >  		goto init_error;
>> >  	}
>> >
>> > @@ -1672,6 +1744,7 @@ wolirq_error:
>> >
>> >  init_error:
>> >  	free_dma_desc_resources(priv);
>> > +dma_desc_error:
>> >  	if (priv->phydev)
>> >  		phy_disconnect(priv->phydev);
>> >  phy_error:
>> >
>> > --
>> > To unsubscribe from this list: send the line "unsubscribe netdev" in
>> > the body of a message to majordomo@vger.kernel.org
>> > More majordomo info at  http://vger.kernel.org/majordomo-info.html
>
>

^ permalink raw reply

* Re: [PATCH 7/8] net: xilinx_emaclite: use platform_{get,set}_drvdata()
From: Michal Simek @ 2013-08-12 13:28 UTC (permalink / raw)
  To: Libo Chen
  Cc: David Miller, michal.simek, renner, Greg KH, netdev, LKML,
	Li Zefan
In-Reply-To: <5208E22C.4090101@huawei.com>

[-- Attachment #1: Type: text/plain, Size: 1603 bytes --]

On 08/12/2013 03:25 PM, Libo Chen wrote:
> 
> Use the wrapper functions for getting and setting the driver data using
> platform_device instead of using dev_{get,set}_drvdata() with &pdev->dev,
> so we can directly pass a struct platform_device.
> 
> Signed-off-by: Libo Chen <libo.chen@huawei.com>
> ---
>  drivers/net/ethernet/xilinx/xilinx_emaclite.c |    4 +---
>  1 files changed, 1 insertions(+), 3 deletions(-)
> 
> diff --git a/drivers/net/ethernet/xilinx/xilinx_emaclite.c b/drivers/net/ethernet/xilinx/xilinx_emaclite.c
> index fd4dbda..4c619ea 100644
> --- a/drivers/net/ethernet/xilinx/xilinx_emaclite.c
> +++ b/drivers/net/ethernet/xilinx/xilinx_emaclite.c
> @@ -1230,8 +1230,7 @@ error:
>   */
>  static int xemaclite_of_remove(struct platform_device *of_dev)
>  {
> -	struct device *dev = &of_dev->dev;
> -	struct net_device *ndev = dev_get_drvdata(dev);
> +	struct net_device *ndev = platform_get_drvdata(of_dev);
> 
>  	struct net_local *lp = netdev_priv(ndev);
> 
> @@ -1250,7 +1249,6 @@ static int xemaclite_of_remove(struct platform_device *of_dev)
>  	lp->phy_node = NULL;
> 
>  	xemaclite_remove_ndev(ndev, of_dev);
> -	dev_set_drvdata(dev, NULL);
> 
>  	return 0;
>  }
> 

Acked-by: Michal Simek <monstr@monstr.eu>

Thanks,
Michal

-- 
Michal Simek, Ing. (M.Eng), OpenPGP -> KeyID: FE3D1F91
w: www.monstr.eu p: +42-0-721842854
Maintainer of Linux kernel - Microblaze cpu - http://www.monstr.eu/fdt/
Maintainer of Linux kernel - Xilinx Zynq ARM architecture
Microblaze U-BOOT custodian and responsible for u-boot arm zynq platform



[-- Attachment #2: OpenPGP digital signature --]
[-- Type: application/pgp-signature, Size: 263 bytes --]

^ permalink raw reply

* [PATCH 7/8] net: xilinx_emaclite: use platform_{get,set}_drvdata()
From: Libo Chen @ 2013-08-12 13:25 UTC (permalink / raw)
  To: David Miller; +Cc: michal.simek, renner, Greg KH, netdev, LKML, Li Zefan


Use the wrapper functions for getting and setting the driver data using
platform_device instead of using dev_{get,set}_drvdata() with &pdev->dev,
so we can directly pass a struct platform_device.

Signed-off-by: Libo Chen <libo.chen@huawei.com>
---
 drivers/net/ethernet/xilinx/xilinx_emaclite.c |    4 +---
 1 files changed, 1 insertions(+), 3 deletions(-)

diff --git a/drivers/net/ethernet/xilinx/xilinx_emaclite.c b/drivers/net/ethernet/xilinx/xilinx_emaclite.c
index fd4dbda..4c619ea 100644
--- a/drivers/net/ethernet/xilinx/xilinx_emaclite.c
+++ b/drivers/net/ethernet/xilinx/xilinx_emaclite.c
@@ -1230,8 +1230,7 @@ error:
  */
 static int xemaclite_of_remove(struct platform_device *of_dev)
 {
-	struct device *dev = &of_dev->dev;
-	struct net_device *ndev = dev_get_drvdata(dev);
+	struct net_device *ndev = platform_get_drvdata(of_dev);

 	struct net_local *lp = netdev_priv(ndev);

@@ -1250,7 +1249,6 @@ static int xemaclite_of_remove(struct platform_device *of_dev)
 	lp->phy_node = NULL;

 	xemaclite_remove_ndev(ndev, of_dev);
-	dev_set_drvdata(dev, NULL);

 	return 0;
 }
-- 
1.7.1

^ permalink raw reply related

* [PATCH 5/8] net: sunbmac: use platform_{get,set}_drvdata()
From: Libo Chen @ 2013-08-12 13:24 UTC (permalink / raw)
  To: David Miller; +Cc: emilio, Greg KH, netdev, LKML, Li Zefan

Use the wrapper functions for getting and setting the driver data using
platform_device instead of using dev_{get,set}_drvdata() with &pdev->dev,
so we can directly pass a struct platform_device.

Signed-off-by: Libo Chen <libo.chen@huawei.com>
---
 drivers/net/ethernet/sun/sunbmac.c |    3 +--
 1 files changed, 1 insertions(+), 2 deletions(-)

diff --git a/drivers/net/ethernet/sun/sunbmac.c b/drivers/net/ethernet/sun/sunbmac.c
index 0d43fa9..34b94cc 100644
--- a/drivers/net/ethernet/sun/sunbmac.c
+++ b/drivers/net/ethernet/sun/sunbmac.c
@@ -1239,7 +1239,7 @@ static int bigmac_sbus_probe(struct platform_device *op)

 static int bigmac_sbus_remove(struct platform_device *op)
 {
-	struct bigmac *bp = dev_get_drvdata(&op->dev);
+	struct bigmac *bp = platform_get_drvdata(op);
 	struct device *parent = op->dev.parent;
 	struct net_device *net_dev = bp->dev;
 	struct platform_device *qec_op;
@@ -1259,7 +1259,6 @@ static int bigmac_sbus_remove(struct platform_device *op)

 	free_netdev(net_dev);

-	dev_set_drvdata(&op->dev, NULL);

 	return 0;
 }
-- 
1.7.1

^ permalink raw reply related

* [PATCH 4/8] net: fs_enet: use platform_{get,set}_drvdata()
From: Libo Chen @ 2013-08-12 13:24 UTC (permalink / raw)
  To: pantelis.antoniou, vbordug, David Miller
  Cc: linuxppc-dev, netdev, LKML, Li Zefan

Use the wrapper functions for getting and setting the driver data using
platform_device instead of using dev_{get,set}_drvdata() with &pdev->dev,
so we can directly pass a struct platform_device.

Signed-off-by: Libo Chen <libo.chen@huawei.com>
---
 .../net/ethernet/freescale/fs_enet/fs_enet-main.c  |    1 -
 1 files changed, 0 insertions(+), 1 deletions(-)

diff --git a/drivers/net/ethernet/freescale/fs_enet/fs_enet-main.c b/drivers/net/ethernet/freescale/fs_enet/fs_enet-main.c
index 8de53a1..7e3de10 100644
--- a/drivers/net/ethernet/freescale/fs_enet/fs_enet-main.c
+++ b/drivers/net/ethernet/freescale/fs_enet/fs_enet-main.c
@@ -1122,7 +1122,6 @@ static int fs_enet_remove(struct platform_device *ofdev)

 	fep->ops->free_bd(ndev);
 	fep->ops->cleanup_data(ndev);
-	dev_set_drvdata(fep->dev, NULL);
 	of_node_put(fep->fpi->phy_node);
 	free_netdev(ndev);
 	return 0;
-- 
1.7.1

^ permalink raw reply related

* [PATCH 8/8] net: davinci_mdio: use platform_{get,set}_drvdata()
From: Libo Chen @ 2013-08-12 13:25 UTC (permalink / raw)
  To: David Miller
  Cc: mugunthanvnm, bigeasy, prabhakar.csengg, b-liu, netdev, LKML,
	Li Zefan


Use the wrapper functions for getting and setting the driver data using
platform_device instead of using dev_{get,set}_drvdata() with &pdev->dev,
so we can directly pass a struct platform_device.

Signed-off-by: Libo Chen <libo.chen@huawei.com>
---
 drivers/net/ethernet/ti/davinci_mdio.c |    4 +---
 1 files changed, 1 insertions(+), 3 deletions(-)

diff --git a/drivers/net/ethernet/ti/davinci_mdio.c b/drivers/net/ethernet/ti/davinci_mdio.c
index 16ddfc3..2249b2c 100644
--- a/drivers/net/ethernet/ti/davinci_mdio.c
+++ b/drivers/net/ethernet/ti/davinci_mdio.c
@@ -421,8 +421,7 @@ bail_out:

 static int davinci_mdio_remove(struct platform_device *pdev)
 {
-	struct device *dev = &pdev->dev;
-	struct davinci_mdio_data *data = dev_get_drvdata(dev);
+	struct davinci_mdio_data *data = platform_get_drvdata(pdev);

 	if (data->bus) {
 		mdiobus_unregister(data->bus);
@@ -434,7 +433,6 @@ static int davinci_mdio_remove(struct platform_device *pdev)
 	pm_runtime_put_sync(&pdev->dev);
 	pm_runtime_disable(&pdev->dev);

-	dev_set_drvdata(dev, NULL);

 	kfree(data);

-- 
1.7.1

^ permalink raw reply related

* [PATCH 6/8] net: sunhme: use platform_{get,set}_drvdata()
From: Libo Chen @ 2013-08-12 13:24 UTC (permalink / raw)
  To: David Miller; +Cc: Greg KH, jg1.han, Bill Pemberton, netdev, LKML


Use the wrapper functions for getting and setting the driver data using
platform_device instead of using dev_{get,set}_drvdata() with &pdev->dev,
so we can directly pass a struct platform_device.

Signed-off-by: Libo Chen <libo.chen@huawei.com>
---
 drivers/net/ethernet/sun/sunhme.c |    8 +++-----
 1 files changed, 3 insertions(+), 5 deletions(-)

diff --git a/drivers/net/ethernet/sun/sunhme.c b/drivers/net/ethernet/sun/sunhme.c
index 171f5b0..a111f29 100644
--- a/drivers/net/ethernet/sun/sunhme.c
+++ b/drivers/net/ethernet/sun/sunhme.c
@@ -3111,7 +3111,7 @@ static int happy_meal_pci_probe(struct pci_dev *pdev,
 		goto err_out_iounmap;
 	}

-	dev_set_drvdata(&pdev->dev, hp);
+	platform_set_drvdata(pdev, hp);

 	if (!qfe_slot) {
 		struct pci_dev *qpdev = qp->quattro_dev;
@@ -3159,7 +3159,7 @@ err_out:

 static void happy_meal_pci_remove(struct pci_dev *pdev)
 {
-	struct happy_meal *hp = dev_get_drvdata(&pdev->dev);
+	struct happy_meal *hp = platform_get_drvdata(pdev);
 	struct net_device *net_dev = hp->dev;

 	unregister_netdev(net_dev);
@@ -3171,7 +3171,6 @@ static void happy_meal_pci_remove(struct pci_dev *pdev)

 	free_netdev(net_dev);

-	dev_set_drvdata(&pdev->dev, NULL);
 }

 static DEFINE_PCI_DEVICE_TABLE(happymeal_pci_ids) = {
@@ -3231,7 +3230,7 @@ static int hme_sbus_probe(struct platform_device *op)

 static int hme_sbus_remove(struct platform_device *op)
 {
-	struct happy_meal *hp = dev_get_drvdata(&op->dev);
+	struct happy_meal *hp = platform_get_drvdata(op);
 	struct net_device *net_dev = hp->dev;

 	unregister_netdev(net_dev);
@@ -3250,7 +3249,6 @@ static int hme_sbus_remove(struct platform_device *op)

 	free_netdev(net_dev);

-	dev_set_drvdata(&op->dev, NULL);

 	return 0;
 }
-- 
1.7.1

^ permalink raw reply related

* [PATCH 1/8] net: fsl_pq_mdio: use platform_{get,set}_drvdata()
From: Libo Chen @ 2013-08-12 13:24 UTC (permalink / raw)
  To: David Miller; +Cc: netdev, LKML, Li Zefan, timur


Use the wrapper functions for getting and setting the driver data using
platform_device instead of using dev_{get,set}_drvdata() with &pdev->dev,
so we can directly pass a struct platform_device.

Signed-off-by: Libo Chen <libo.chen@huawei.com>
---
 drivers/net/ethernet/freescale/fsl_pq_mdio.c |    3 +--
 1 files changed, 1 insertions(+), 2 deletions(-)

diff --git a/drivers/net/ethernet/freescale/fsl_pq_mdio.c b/drivers/net/ethernet/freescale/fsl_pq_mdio.c
index c93a056..995a3ab 100644
--- a/drivers/net/ethernet/freescale/fsl_pq_mdio.c
+++ b/drivers/net/ethernet/freescale/fsl_pq_mdio.c
@@ -409,7 +409,7 @@ static int fsl_pq_mdio_probe(struct platform_device *pdev)
 	priv->regs = priv->map + data->mii_offset;

 	new_bus->parent = &pdev->dev;
-	dev_set_drvdata(&pdev->dev, new_bus);
+	platform_set_drvdata(pdev, new_bus);

 	if (data->get_tbipa) {
 		for_each_child_of_node(np, tbi) {
@@ -468,7 +468,6 @@ static int fsl_pq_mdio_remove(struct platform_device *pdev)

 	mdiobus_unregister(bus);

-	dev_set_drvdata(device, NULL);

 	iounmap(priv->map);
 	mdiobus_free(bus);
-- 
1.7.1

^ permalink raw reply related

* [PATCH 3/8] net: fec_mpc52xx_phy: use platform_{get,set}_drvdata()
From: Libo Chen @ 2013-08-12 13:24 UTC (permalink / raw)
  To: David Miller, timur; +Cc: netdev, LKML, Li Zefan


Use the wrapper functions for getting and setting the driver data using
platform_device instead of using dev_{get,set}_drvdata() with &pdev->dev,
so we can directly pass a struct platform_device.

Signed-off-by: Libo Chen <libo.chen@huawei.com>
---
 drivers/net/ethernet/freescale/fec_mpc52xx_phy.c |    4 +---
 1 files changed, 1 insertions(+), 3 deletions(-)

diff --git a/drivers/net/ethernet/freescale/fec_mpc52xx_phy.c b/drivers/net/ethernet/freescale/fec_mpc52xx_phy.c
index 360a578..e052890 100644
--- a/drivers/net/ethernet/freescale/fec_mpc52xx_phy.c
+++ b/drivers/net/ethernet/freescale/fec_mpc52xx_phy.c
@@ -123,12 +123,10 @@ static int mpc52xx_fec_mdio_probe(struct platform_device *of)

 static int mpc52xx_fec_mdio_remove(struct platform_device *of)
 {
-	struct device *dev = &of->dev;
-	struct mii_bus *bus = dev_get_drvdata(dev);
+	struct mii_bus *bus = platform_get_drvdata(of);
 	struct mpc52xx_fec_mdio_priv *priv = bus->priv;

 	mdiobus_unregister(bus);
-	dev_set_drvdata(dev, NULL);
 	iounmap(priv->regs);
 	kfree(priv);
 	mdiobus_free(bus);
-- 
1.7.1

^ permalink raw reply related

* use platform_{get,set}_drvdata()
From: Libo Chen @ 2013-08-12 13:24 UTC (permalink / raw)
  To: David Miller
  Cc: netdev, LKML, Li Zefan, timur, leoli, linuxppc-dev,
	pantelis.antoniou, vbordug, Greg KH, jg1.han, Bill Pemberton,
	michal.simek, renner, mugunthanvnm, bigeasy, prabhakar.csengg,
	b-liu


Use the wrapper functions for getting and setting the driver data using
platform_device instead of using dev_{get,set}_drvdata() with &pdev->dev,
so we can directly pass a struct platform_device.


Libo Chen (8):
  net: fsl_pq_mdio: use platform_{get,set}_drvdata()
  net: ucc_geth: use platform_{get,set}_drvdata()
  net: fec_mpc52xx_phy: use platform_{get,set}_drvdata()
  net: fs_enet: use platform_{get,set}_drvdata()
  net: sunbmac: use platform_{get,set}_drvdata()
  net: sunhme: use platform_{get,set}_drvdata()
  net: xilinx_emaclite: use platform_{get,set}_drvdata()
  net: davinci_mdio: use platform_{get,set}_drvdata()

 drivers/net/ethernet/freescale/fec_mpc52xx_phy.c   |    4 +---
 drivers/net/ethernet/freescale/fs_enet/fs_enet-main.c  |    1 -
 drivers/net/ethernet/freescale/fsl_pq_mdio.c       |    3 +--
 drivers/net/ethernet/freescale/ucc_geth.c          |    4 +---
 drivers/net/ethernet/sun/sunbmac.c                 |    3 +--
 drivers/net/ethernet/sun/sunhme.c                  |    8 +++-----
 drivers/net/ethernet/ti/davinci_mdio.c             |    4 +---
 drivers/net/ethernet/xilinx/xilinx_emaclite.c      |    4 +---
 8 files changed, 9 insertions(+), 22 deletions(-)

^ permalink raw reply

* [PATCH 2/8] net: ucc_geth: use platform_{get,set}_drvdata()
From: Libo Chen @ 2013-08-12 13:24 UTC (permalink / raw)
  To: leoli, David Miller; +Cc: netdev, LKML, Li Zefan, linuxppc-dev

Use the wrapper functions for getting and setting the driver data using
platform_device instead of using dev_{get,set}_drvdata() with &pdev->dev,
so we can directly pass a struct platform_device.

Signed-off-by: Libo Chen <libo.chen@huawei.com>
---
 drivers/net/ethernet/freescale/ucc_geth.c |    4 +---
 1 files changed, 1 insertions(+), 3 deletions(-)

diff --git a/drivers/net/ethernet/freescale/ucc_geth.c b/drivers/net/ethernet/freescale/ucc_geth.c
index 3c43dac..5930c39 100644
--- a/drivers/net/ethernet/freescale/ucc_geth.c
+++ b/drivers/net/ethernet/freescale/ucc_geth.c
@@ -3911,14 +3911,12 @@ static int ucc_geth_probe(struct platform_device* ofdev)

 static int ucc_geth_remove(struct platform_device* ofdev)
 {
-	struct device *device = &ofdev->dev;
-	struct net_device *dev = dev_get_drvdata(device);
+	struct net_device *dev = platform_get_drvdata(ofdev);
 	struct ucc_geth_private *ugeth = netdev_priv(dev);

 	unregister_netdev(dev);
 	free_netdev(dev);
 	ucc_geth_memclean(ugeth);
-	dev_set_drvdata(device, NULL);

 	return 0;
 }
-- 
1.7.1

^ permalink raw reply related

* ipsec smp scalability and cpu use fairness (softirqs)
From: Timo Teras @ 2013-08-12 13:01 UTC (permalink / raw)
  To: netdev

Hi,

I've been recently doing some ipsec benchmarking, and analysis on
system running out of cpu power. The setup is dmvpn gateway
(gre+xfrm+opennhrp) with traffic in forward path.

The system I have been using are VIA Nano (Padlock aes/sha accel) and
Intel Xeon (aes-ni and ssse3 sha1) based. In both setups the crypto
happens synchronously using special opcodes, or assembly implementation
of the algorithm.

It seems that the combination of softirq, napi and synchronous crypto
causes two problems.

1. Single core systems that are going out of cpu power, are
overwhelmed in uncontrollable manner. As softirq is doing the heavy
lifting, the user land processes are starved first. This can cause
userland IKE daemon to starve and lose tunnels when it is unable to
answer liveliness checks. The quick workaround is to setup traffic
shaping for the encrypted traffic.

2. On multicore (6-12 cores) systems, it would appear that it is not
easy to distribute the ipsec to multiple cores. as softirq is sticky to
the cpu where it was raised. The ipsec decryption/encryption is done
synchronously in the napi poll loop, and the throughput is limited by
one cpu. If the NIC supports multiple queues and balancing with ESP
SPI, we can use that to get some parallelism.

Fundamentally, both problems arise because synchronous crypto happens in
the softirq context. I'm wondering if it would make sense to execute
the synchronous crypto in low-priority per-xfrm_state workqueue or
similar.

Any suggestions or comments?

^ permalink raw reply

* [PATCH net-next] bonding: lacp_port_id setting for 802.3ad
From: Krisztian Ivancso @ 2013-08-12 11:19 UTC (permalink / raw)
  To: netdev

The patch adds port id setting feature by lacp_port_id module
parameter for 802.3ad ports.

Adding more linux boxes to a link aggregation makes possible to do
load-balancing by using port channel load balancing of switch
(eg. by source-dest-ip or src-ip).

It's essential to set the same MAC address to bonding interface and
to set different port ids on different linux boxes for a
working solution.

Possible use cases:
1. Redundant DNS servers with same IP address
2. Reverse proxies with same IP address
3. "multi-master" LVS

Beside redundancy it provides scalability, scalability depends on
hardware capability.
E.g. a LAG port with 4 members - linux LVS servers - using a Cisco
switch/router splits traffic to ports equally by src IP (2-2-2-2).
If a link fails, switch forwards traffic to 3 switch ports (3-3-3).
It means you can utilize overall bandwith as much as 66% with full
redundancy. It's better with 16% than using 2 master-slave LVS and
you use just 1 IP and can handle 100% more peak traffic.

Using this feature with vPC (virtual portchannel) or similar solution
it provides a physically redundant service from network devices
to servers using the same IP address.


>From 472fffa5a8f170daed9e4cc677af8e2560b86be2 Mon Sep 17 00:00:00 2001
From: Krisztian Ivancso <github-ivan@ivancso.net>
Date: Sun, 11 Aug 2013 20:30:44 +0200
Subject: [PATCH net-next] bonding: lacp_port_id setting for 802.3ad ports

By setting this parameter to different values on different hosts
it's possible to add more Linux boxes to the same Link Aggregation.

Signed-off-by: Krisztian Ivancso <github-ivan@ivancso.net>
---
 drivers/net/bonding/bond_main.c   | 18 ++++++++++++++++--
 drivers/net/bonding/bond_procfs.c |  1 +
 drivers/net/bonding/bond_sysfs.c  | 33 +++++++++++++++++++++++++++++++++
 drivers/net/bonding/bonding.h     |  1 +
 4 files changed, 51 insertions(+), 2 deletions(-)

diff --git a/drivers/net/bonding/bond_main.c b/drivers/net/bonding/bond_main.c
index 4264a76..452f4d4 100644
--- a/drivers/net/bonding/bond_main.c
+++ b/drivers/net/bonding/bond_main.c
@@ -110,6 +110,7 @@ static char *fail_over_mac;
 static int all_slaves_active;
 static struct bond_params bonding_defaults;
 static int resend_igmp = BOND_DEFAULT_RESEND_IGMP;
+static int lacp_port_id = 1;

 module_param(max_bonds, int, 0);
 MODULE_PARM_DESC(max_bonds, "Max number of bonded devices");
@@ -150,7 +151,7 @@ module_param(lacp_rate, charp, 0);
 MODULE_PARM_DESC(lacp_rate, "LACPDU tx rate to request from 802.3ad partner; "
 			    "0 for slow, 1 for fast");
 module_param(ad_select, charp, 0);
-MODULE_PARM_DESC(ad_select, "803.ad aggregation selection logic; "
+MODULE_PARM_DESC(ad_select, "802.3ad aggregation selection logic; "
 			    "0 for stable (default), 1 for bandwidth, "
 			    "2 for count");
 module_param(min_links, int, 0);
@@ -181,6 +182,8 @@ MODULE_PARM_DESC(all_slaves_active, "Keep all frames received on an interface"
 module_param(resend_igmp, int, 0);
 MODULE_PARM_DESC(resend_igmp, "Number of IGMP membership reports to send on "
 			      "link failure");
+module_param(lacp_port_id, int, 0);
+MODULE_PARM_DESC(lacp_port_id, "802.3ad port id to send to switch in LACPDU");

 /*----------------------------- Global variables ----------------------------*/

@@ -1699,7 +1702,7 @@ int bond_enslave(struct net_device *bond_dev, struct net_device *slave_dev)
 		bond_set_slave_inactive_flags(new_slave);
 		/* if this is the first slave */
 		if (bond_first_slave(bond) == new_slave) {
-			SLAVE_AD_INFO(new_slave).id = 1;
+			SLAVE_AD_INFO(new_slave).id = lacp_port_id;
 			/* Initialize AD with the number of times that the AD timer is called in 1 second
 			 * can be called only after the mac address of the bond is set
 			 */
@@ -4377,6 +4380,16 @@ static int bond_check_params(struct bond_params *params)
 		resend_igmp = BOND_DEFAULT_RESEND_IGMP;
 	}

+	if (bond_mode == BOND_MODE_8023AD) {
+		/* we set upper limit to 65000 because new slaves will increase port
+                   id so we don't want id to overflow */
+		if (lacp_port_id < 1 || lacp_port_id > 65000) {
+			pr_warning("Warning: lacp_port_id (%d) should be between "
+				   "1 and 65000, resetting to 1\n", lacp_port_id);
+			lacp_port_id = 1;
+		}
+	}
+
 	/* reset values for TLB/ALB */
 	if ((bond_mode == BOND_MODE_TLB) ||
 	    (bond_mode == BOND_MODE_ALB)) {
@@ -4565,6 +4578,7 @@ static int bond_check_params(struct bond_params *params)
 	params->all_slaves_active = all_slaves_active;
 	params->resend_igmp = resend_igmp;
 	params->min_links = min_links;
+	params->lacp_port_id = lacp_port_id;

 	if (primary) {
 		strncpy(params->primary, primary, IFNAMSIZ);
diff --git a/drivers/net/bonding/bond_procfs.c b/drivers/net/bonding/bond_procfs.c
index 20a6ee2..6d52716 100644
--- a/drivers/net/bonding/bond_procfs.c
+++ b/drivers/net/bonding/bond_procfs.c
@@ -129,6 +129,7 @@ static void bond_info_show_master(struct seq_file *seq)
 		seq_printf(seq, "Min links: %d\n", bond->params.min_links);
 		seq_printf(seq, "Aggregator selection policy (ad_select): %s\n",
 			   ad_select_tbl[bond->params.ad_select].modename);
+		seq_printf(seq, "802.3ad starting port id: %d\n", bond->params.lacp_port_id);

 		if (__bond_3ad_get_active_agg_info(bond, &ad_info)) {
 			seq_printf(seq, "bond %s has no active aggregator\n",
diff --git a/drivers/net/bonding/bond_sysfs.c b/drivers/net/bonding/bond_sysfs.c
index 0f539de..a79b7c3 100644
--- a/drivers/net/bonding/bond_sysfs.c
+++ b/drivers/net/bonding/bond_sysfs.c
@@ -920,6 +920,38 @@ static ssize_t bonding_store_min_links(struct device *d,
 static DEVICE_ATTR(min_links, S_IRUGO | S_IWUSR,
 		   bonding_show_min_links, bonding_store_min_links);

+static ssize_t bonding_show_lacp_port_id(struct device *d,
+				      struct device_attribute *attr,
+				      char *buf)
+{
+	struct bonding *bond = to_bond(d);
+
+	return sprintf(buf, "%d\n", bond->params.lacp_port_id);
+}
+
+static ssize_t bonding_store_lacp_port_id(struct device *d,
+				       struct device_attribute *attr,
+				       const char *buf, size_t count)
+{
+	struct bonding *bond = to_bond(d);
+	int ret;
+	unsigned int new_value;
+
+	ret = kstrtouint(buf, 0, &new_value);
+	if ((ret < 0) || (new_value < 1) || (new_value > 65000)) {
+		pr_err("%s: Ignoring invalid 802.3ad port id value %s.\n",
+		       bond->dev->name, buf);
+		return -EINVAL;
+	}
+
+	pr_info("%s: Setting 802.3ad port id value to %u\n",
+		bond->dev->name, new_value);
+	bond->params.lacp_port_id = new_value;
+	return count;
+}
+static DEVICE_ATTR(lacp_port_id, S_IRUGO | S_IWUSR,
+		   bonding_show_lacp_port_id, bonding_store_lacp_port_id);
+
 static ssize_t bonding_show_ad_select(struct device *d,
 				      struct device_attribute *attr,
 				      char *buf)
@@ -1705,6 +1737,7 @@ static struct attribute *per_bond_attrs[] = {
 	&dev_attr_all_slaves_active.attr,
 	&dev_attr_resend_igmp.attr,
 	&dev_attr_min_links.attr,
+	&dev_attr_lacp_port_id.attr,
 	NULL,
 };

diff --git a/drivers/net/bonding/bonding.h b/drivers/net/bonding/bonding.h
index 4bf52d5..8a078d6 100644
--- a/drivers/net/bonding/bonding.h
+++ b/drivers/net/bonding/bonding.h
@@ -176,6 +176,7 @@ struct bond_params {
 	int tx_queues;
 	int all_slaves_active;
 	int resend_igmp;
+	int lacp_port_id;
 };

 struct bond_parm_tbl {
-- 
1.8.3.1

^ permalink raw reply related

* [net-next PATCH 1/1] drivers: net: cpsw: Add support for new CPSW IP version present in AM43xx SoC
From: Mugunthan V N @ 2013-08-12 11:41 UTC (permalink / raw)
  To: netdev; +Cc: davem, linux-omap, Mugunthan V N

The new IP version which is present in AM43xx SoC has a minor changes and the
offsets are same as the previous version, so adding new IP version support in
the driver.

Signed-off-by: Mugunthan V N <mugunthanvnm@ti.com>
---
 drivers/net/ethernet/ti/cpsw.c | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/drivers/net/ethernet/ti/cpsw.c b/drivers/net/ethernet/ti/cpsw.c
index cd95671..0fcf212 100644
--- a/drivers/net/ethernet/ti/cpsw.c
+++ b/drivers/net/ethernet/ti/cpsw.c
@@ -83,6 +83,7 @@ do {								\
 #define CPSW_VERSION_1		0x19010a
 #define CPSW_VERSION_2		0x19010c
 #define CPSW_VERSION_3		0x19010f
+#define CPSW_VERSION_4		0x190112
 
 #define HOST_PORT_NUM		0
 #define SLIVER_SIZE		0x40
@@ -993,6 +994,7 @@ static void cpsw_slave_open(struct cpsw_slave *slave, struct cpsw_priv *priv)
 		break;
 	case CPSW_VERSION_2:
 	case CPSW_VERSION_3:
+	case CPSW_VERSION_4:
 		slave_write(slave, TX_PRIORITY_MAPPING, CPSW2_TX_PRI_MAP);
 		break;
 	}
@@ -2018,6 +2020,7 @@ static int cpsw_probe(struct platform_device *pdev)
 		break;
 	case CPSW_VERSION_2:
 	case CPSW_VERSION_3:
+	case CPSW_VERSION_4:
 		priv->host_port_regs = ss_regs + CPSW2_HOST_PORT_OFFSET;
 		priv->cpts->reg      = ss_regs + CPSW2_CPTS_OFFSET;
 		priv->hw_stats	     = ss_regs + CPSW2_HW_STATS;
-- 
1.8.4.rc1.21.gfb56570

^ permalink raw reply related

* [PATCH net-next v2] ipv6: make unsolicited report intervals configurable for mld
From: Hannes Frederic Sowa @ 2013-08-12 11:28 UTC (permalink / raw)
  To: netdev; +Cc: xiyou.wangcong, william.manley, bcrl, yoshfuji

Commit cab70040dfd95ee32144f02fade64f0cb94f31a0 ("net: igmp:
Reduce Unsolicited report interval to 1s when using IGMPv3") and
2690048c01f32bf45d1c1e1ab3079bc10ad2aea7 ("net: igmp: Allow user-space
configuration of igmp unsolicited report interval") by William Manley made
igmp unsolicited report intervals configurable per interface and corrected
the interval of unsolicited igmpv3 report messages resendings to 1s.

Same needs to be done for IPv6:

MLDv1 (RFC2710 7.10.): 10 seconds
MLDv2 (RFC3810 9.11.): 1 second

Both intervals are configurable via new procfs knobs
mldv1_unsolicited_report_interval and mldv2_unsolicited_report_interval.

(also added .force_mld_version to ipv6_devconf_dflt to bring structs in
line without semantic changes)

v2:
a) Joined documentation update for IPv4 and IPv6 MLD/IGMP
   unsolicited_report_interval procfs knobs.
b) incorporate stylistic feedback from William Manley

Cc: Cong Wang <xiyou.wangcong@gmail.com>
Cc: William Manley <william.manley@youview.com>
Cc: Benjamin LaHaise <bcrl@kvack.org>
Cc: YOSHIFUJI Hideaki <yoshfuji@linux-ipv6.org>
Signed-off-by: Hannes Frederic Sowa <hannes@stressinduktion.org>
---
 Documentation/networking/ip-sysctl.txt | 18 ++++++++++++++++++
 include/linux/ipv6.h                   |  2 ++
 include/uapi/linux/ipv6.h              |  2 ++
 net/ipv6/addrconf.c                    | 25 +++++++++++++++++++++++++
 net/ipv6/mcast.c                       | 17 ++++++++++++++---
 5 files changed, 61 insertions(+), 3 deletions(-)

diff --git a/Documentation/networking/ip-sysctl.txt b/Documentation/networking/ip-sysctl.txt
index 36be26b..debfe85 100644
--- a/Documentation/networking/ip-sysctl.txt
+++ b/Documentation/networking/ip-sysctl.txt
@@ -1039,7 +1039,15 @@ disable_policy - BOOLEAN
 disable_xfrm - BOOLEAN
 	Disable IPSEC encryption on this interface, whatever the policy
 
+igmpv2_unsolicited_report_interval - INTEGER
+	The interval in milliseconds in which the next unsolicited
+	IGMPv1 or IGMPv2 report retransmit will take place.
+	Default: 10000 (10 seconds)
 
+igmpv3_unsolicited_report_interval - INTEGER
+	The interval in milliseconds in which the next unsolicited
+	IGMPv3 report retransmit will take place.
+	Default: 1000 (1 seconds)
 
 tag - INTEGER
 	Allows you to write a number, which can be used as required.
@@ -1331,6 +1339,16 @@ ndisc_notify - BOOLEAN
 	1 - Generate unsolicited neighbour advertisements when device is brought
 	    up or hardware address changes.
 
+mldv1_unsolicited_report_interval - INTEGER
+	The interval in milliseconds in which the next unsolicited
+	MLDv1 report retransmit will take place.
+	Default: 10000 (10 seconds)
+
+mldv2_unsolicited_report_interval - INTEGER
+	The interval in milliseconds in which the next unsolicited
+	MLDv2 report retransmit will take place.
+	Default: 1000 (1 second)
+
 icmp/*:
 ratelimit - INTEGER
 	Limit the maximal rates for sending ICMPv6 packets.
diff --git a/include/linux/ipv6.h b/include/linux/ipv6.h
index 850e95b..77a4784 100644
--- a/include/linux/ipv6.h
+++ b/include/linux/ipv6.h
@@ -19,6 +19,8 @@ struct ipv6_devconf {
 	__s32		rtr_solicit_interval;
 	__s32		rtr_solicit_delay;
 	__s32		force_mld_version;
+	__s32		mldv1_unsolicited_report_interval;
+	__s32		mldv2_unsolicited_report_interval;
 #ifdef CONFIG_IPV6_PRIVACY
 	__s32		use_tempaddr;
 	__s32		temp_valid_lft;
diff --git a/include/uapi/linux/ipv6.h b/include/uapi/linux/ipv6.h
index 4bda4cf..315f133 100644
--- a/include/uapi/linux/ipv6.h
+++ b/include/uapi/linux/ipv6.h
@@ -147,6 +147,8 @@ enum {
 	DEVCONF_MAX_DESYNC_FACTOR,
 	DEVCONF_MAX_ADDRESSES,
 	DEVCONF_FORCE_MLD_VERSION,
+	DEVCONF_MLDV1_UNSOLICITED_REPORT_INTERVAL,
+	DEVCONF_MLDV2_UNSOLICITED_REPORT_INTERVAL,
 	DEVCONF_ACCEPT_RA_DEFRTR,
 	DEVCONF_ACCEPT_RA_PINFO,
 	DEVCONF_ACCEPT_RA_RTR_PREF,
diff --git a/net/ipv6/addrconf.c b/net/ipv6/addrconf.c
index 7fd8572..ad12f7c 100644
--- a/net/ipv6/addrconf.c
+++ b/net/ipv6/addrconf.c
@@ -177,6 +177,8 @@ static struct ipv6_devconf ipv6_devconf __read_mostly = {
 	.accept_redirects	= 1,
 	.autoconf		= 1,
 	.force_mld_version	= 0,
+	.mldv1_unsolicited_report_interval = 10 * HZ,
+	.mldv2_unsolicited_report_interval = HZ,
 	.dad_transmits		= 1,
 	.rtr_solicits		= MAX_RTR_SOLICITATIONS,
 	.rtr_solicit_interval	= RTR_SOLICITATION_INTERVAL,
@@ -211,6 +213,9 @@ static struct ipv6_devconf ipv6_devconf_dflt __read_mostly = {
 	.accept_ra		= 1,
 	.accept_redirects	= 1,
 	.autoconf		= 1,
+	.force_mld_version	= 0,
+	.mldv1_unsolicited_report_interval = 10 * HZ,
+	.mldv2_unsolicited_report_interval = HZ,
 	.dad_transmits		= 1,
 	.rtr_solicits		= MAX_RTR_SOLICITATIONS,
 	.rtr_solicit_interval	= RTR_SOLICITATION_INTERVAL,
@@ -4179,6 +4184,10 @@ static inline void ipv6_store_devconf(struct ipv6_devconf *cnf,
 	array[DEVCONF_RTR_SOLICIT_DELAY] =
 		jiffies_to_msecs(cnf->rtr_solicit_delay);
 	array[DEVCONF_FORCE_MLD_VERSION] = cnf->force_mld_version;
+	array[DEVCONF_MLDV1_UNSOLICITED_REPORT_INTERVAL] =
+		jiffies_to_msecs(cnf->mldv1_unsolicited_report_interval);
+	array[DEVCONF_MLDV2_UNSOLICITED_REPORT_INTERVAL] =
+		jiffies_to_msecs(cnf->mldv2_unsolicited_report_interval);
 #ifdef CONFIG_IPV6_PRIVACY
 	array[DEVCONF_USE_TEMPADDR] = cnf->use_tempaddr;
 	array[DEVCONF_TEMP_VALID_LFT] = cnf->temp_valid_lft;
@@ -4862,6 +4871,22 @@ static struct addrconf_sysctl_table
 			.mode		= 0644,
 			.proc_handler	= proc_dointvec,
 		},
+		{
+			.procname	= "mldv1_unsolicited_report_interval",
+			.data		=
+				&ipv6_devconf.mldv1_unsolicited_report_interval,
+			.maxlen		= sizeof(int),
+			.mode		= 0644,
+			.proc_handler	= proc_dointvec_ms_jiffies,
+		},
+		{
+			.procname	= "mldv2_unsolicited_report_interval",
+			.data		=
+				&ipv6_devconf.mldv2_unsolicited_report_interval,
+			.maxlen		= sizeof(int),
+			.mode		= 0644,
+			.proc_handler	= proc_dointvec_ms_jiffies,
+		},
 #ifdef CONFIG_IPV6_PRIVACY
 		{
 			.procname	= "use_tempaddr",
diff --git a/net/ipv6/mcast.c b/net/ipv6/mcast.c
index db25b8e..6c76df9 100644
--- a/net/ipv6/mcast.c
+++ b/net/ipv6/mcast.c
@@ -108,7 +108,6 @@ static int ip6_mc_leave_src(struct sock *sk, struct ipv6_mc_socklist *iml,
 			    struct inet6_dev *idev);
 
 
-#define IGMP6_UNSOLICITED_IVAL	(10*HZ)
 #define MLD_QRV_DEFAULT		2
 
 #define MLD_V1_SEEN(idev) (dev_net((idev)->dev)->ipv6.devconf_all->force_mld_version == 1 || \
@@ -129,6 +128,18 @@ int sysctl_mld_max_msf __read_mostly = IPV6_MLD_MAX_MSF;
 	     pmc != NULL;					\
 	     pmc = rcu_dereference(pmc->next))
 
+static int unsolicited_report_interval(struct inet6_dev *idev)
+{
+	int iv;
+
+	if (MLD_V1_SEEN(idev))
+		iv = idev->cnf.mldv1_unsolicited_report_interval;
+	else
+		iv = idev->cnf.mldv2_unsolicited_report_interval;
+
+	return iv > 0 ? iv : 1;
+}
+
 int ipv6_sock_mc_join(struct sock *sk, int ifindex, const struct in6_addr *addr)
 {
 	struct net_device *dev = NULL;
@@ -2158,7 +2169,7 @@ static void igmp6_join_group(struct ifmcaddr6 *ma)
 
 	igmp6_send(&ma->mca_addr, ma->idev->dev, ICMPV6_MGM_REPORT);
 
-	delay = net_random() % IGMP6_UNSOLICITED_IVAL;
+	delay = net_random() % unsolicited_report_interval(ma->idev);
 
 	spin_lock_bh(&ma->mca_lock);
 	if (del_timer(&ma->mca_timer)) {
@@ -2325,7 +2336,7 @@ void ipv6_mc_init_dev(struct inet6_dev *idev)
 	setup_timer(&idev->mc_dad_timer, mld_dad_timer_expire,
 		    (unsigned long)idev);
 	idev->mc_qrv = MLD_QRV_DEFAULT;
-	idev->mc_maxdelay = IGMP6_UNSOLICITED_IVAL;
+	idev->mc_maxdelay = unsolicited_report_interval(idev);
 	idev->mc_v1_seen = 0;
 	write_unlock_bh(&idev->lock);
 }
-- 
1.8.3.1

^ permalink raw reply related


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