Netdev List
 help / color / mirror / Atom feed
* Re: [PATCH] net: ftmac100: fix scheduling while atomic during PHY link status change
From: Po-Yu Chuang @ 2011-04-28  9:11 UTC (permalink / raw)
  To: Adam Jaremko
  Cc: Ratbert Po-Yu Chuang(莊博宇), netdev,
	David Miller, Eric Dumazet
In-Reply-To: <BANLkTi=gcFB4mbmWKu4neep77Jp8R4HWGQ@mail.gmail.com>

Hi Adam,

2011/4/27 Adam Jaremko <adam.jaremko@gmail.com>:
> Signed-off-by: Adam Jaremko <adam.jaremko@gmail.com>
> ---
>  drivers/net/ftmac100.c |    8 ++++----
>  1 files changed, 4 insertions(+), 4 deletions(-)
>
> diff --git a/drivers/net/ftmac100.c b/drivers/net/ftmac100.c
> index a316619..9bd7746 100644
> --- a/drivers/net/ftmac100.c
> +++ b/drivers/net/ftmac100.c
> @@ -139,11 +139,11 @@ static int ftmac100_reset(struct ftmac100 *priv)
>                         * that hardware reset completed (what the f*ck).
>                         * We still need to wait for a while.
>                         */
> -                       usleep_range(500, 1000);
> +                       udelay(500);
>                        return 0;
>                }
>
> -               usleep_range(1000, 10000);
> +               udelay(1000);
>        }
>
>        netdev_err(netdev, "software reset failed\n");
> @@ -772,7 +772,7 @@ static int ftmac100_mdio_read(struct net_device
> *netdev, int phy_id, int reg)
>                if ((phycr & FTMAC100_PHYCR_MIIRD) == 0)
>                        return phycr & FTMAC100_PHYCR_MIIRDATA;
>
> -               usleep_range(100, 1000);
> +               udelay(100);
>        }
>
>        netdev_err(netdev, "mdio read timed out\n");
> @@ -801,7 +801,7 @@ static void ftmac100_mdio_write(struct net_device
> *netdev, int phy_id, int reg,
>                if ((phycr & FTMAC100_PHYCR_MIIWR) == 0)
>                        return;
>
> -               usleep_range(100, 1000);
> +               udelay(100);
>        }
>
>        netdev_err(netdev, "mdio write timed out\n");
> --
> 1.7.4.4
>

Not sure if your patch is indeed corrupt or it's my fault
while downloading patch from gmail:

ERROR: patch seems to be corrupt (line wrapped?)
#62: FILE: drivers/net/ftmac100.c:771:
*netdev, int phy_id, int reg)

total: 1 errors, 0 warnings, 31 lines checked

ftmac100-fix.patch has style problems, please review.  If any of these errors
are false positives report them to the maintainer, see
CHECKPATCH in MAINTAINERS.


Except that,

Acked-by: Po-Yu Chuang <ratbert@faraday-tech.com>

best regards,
Po-Yu Chuang

^ permalink raw reply

* Re: [PATCH 6/6 v8] sctp: Add ASCONF operation on the single-homed host
From: Wei Yongjun @ 2011-04-28  8:59 UTC (permalink / raw)
  To: Michio Honda; +Cc: netdev, YOSHIFUJI Hideaki
In-Reply-To: <5183C2C0-C377-4FF7-89A1-3F19D53FBBBF@sfc.wide.ad.jp>


>>>>> +			/* reuse the parameter length from the same scope one */
>>>>> +			totallen += paramlen;
>>>>> +			totallen += addr_param_len;
>>>>> +			del_pickup = 1;
>>>>> +			asoc->src_out_of_asoc_ok = 1;
>>>> src_out_of_asoc_ok should be marked when the last address is
>>>> assigned to asoc->asconf_addr_del_pending?
>>> I thought marking src_out_of_asoc_ok should be set when the candidate new address appears, rather than when the last address is being deleted.  
>>> Because until such address appears, there is no situation to send any chunk from the address not in the association.  
>> The last address have been marked as DEL, will never using
>> for sending chunks. At this time, there is no valid address in the
>> host, chunk can not be send out by host.
> I understand that, marking out_of_asoc_ok at the last address being deleted does same thing.  
> However, out_of_asoc_ok state is not regular, so I think we should shorten that duration as much as possible.  
> But this is my personal opinion, so if you don't think so, I will mark it when the last address being deleted.  

You can do some test about this(I do not test :-) )

remove all the address while data still be sent, wait
some time before the new address is added, and see
whether there is some different between those. Not
sure which or both is right. If it is the same, remain
the code not change.

>>>>> +			SCTP_DEBUG_PRINTK("mkasconf_update_ip: picked same-scope del_pending addr, totallen for all addresses is %d\n", totallen);
>>>>> +		}
>>>>> 	}
>>>>>
>>>>> 	/* Create an asconf chunk with the required length. */
>>>>> @@ -2802,6 +2819,19 @@ struct sctp_chunk *sctp_make_asconf_update_ip(struct sctp_association *asoc,
>>>>>
>>>>> 		addr_buf += af->sockaddr_len;
>>>>> 	}
>>>>> +	if (flags == SCTP_PARAM_ADD_IP && del_pickup) {
>>>>> +		addr = asoc->asconf_addr_del_pending;
>>>>> +		del_af = sctp_get_af_specific(addr->v4.sin_family);
>>>>> +		del_addr_param_len = del_af->to_addr_param(addr,
>>>>> +		    &del_addr_param);
>>>>> +		del_param.param_hdr.type = SCTP_PARAM_DEL_IP;
>>>>> +		del_param.param_hdr.length = htons(del_paramlen +
>>>>> +		    del_addr_param_len);
>>>>> +		del_param.crr_id = i;
>>>>> +
>>>>> +		sctp_addto_chunk(retval, del_paramlen, &del_param);
>>>>> +		sctp_addto_chunk(retval, del_addr_param_len, &del_addr_param);
>>>>> +	}
>>>>> 	return retval;
>>>>> }
>>>> How about clean up this part as:
>>>>
>>>> +       if (...) {
>>>> +               addr = asoc->asconf_addr_del_pending;
>>>> +               af = sctp_get_af_specific(addr->v4.sin_family);
>>>> +               addr_param_len = af->to_addr_param(addr, &addr_param);
>>>> +               totallen += paramlen;
>>>> +               totallen += addr_param_len;
>>>> +		...
>>>> +       }
>>>> +
>>>>      /* Create an asconf chunk with the required length. */
>>>>      retval = sctp_make_asconf(asoc, laddr, totallen);
>>>>      if (!retval)
>>>> @@ -2802,6 +2812,18 @@ struct sctp_chunk *sctp_make_asconf_update_ip(struct sctp_association *asoc,
>>>>
>>>>              addr_buf += af->sockaddr_len;
>>>>      }
>>>> +
>>>> +       if (...) {
>>>> +               addr = asoc->asconf_addr_del_pending;
>>>> +               af = sctp_get_af_specific(addr->v4.sin_family);
>>>> +               addr_param_len = af->to_addr_param(addr, &addr_param);
>>>> +               param.param_hdr.type = SCTP_PARAM_DEL_IP;
>>>> +               param.param_hdr.length = htons(paramlen + addr_param_len);
>>>> +               param.crr_id = i;
>>>> +
>>>> +               sctp_addto_chunk(retval, paramlen, &param);
>>>> +               sctp_addto_chunk(retval, addr_param_len, &addr_param);
>>>> +       }
>>> agreed with reusing af instead of defining del_af.  
>>> --
>>> 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
>>>
> --
> 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

* [PATCH net-next-2.6] net: dont hold rtnl mutex during netlink dump callbacks
From: Eric Dumazet @ 2011-04-28  8:56 UTC (permalink / raw)
  To: David Miller; +Cc: Patrick McHardy, netdev, Remi Denis-Courmont

Four years ago, Patrick made a change to hold rtnl mutex during netlink
dump callbacks.

I believe it was a wrong move. This slows down concurrent dumps, making
good old /proc/net/ files faster than rtnetlink in some situations.

This occurred to me because one "ip link show dev ..." was _very_ slow
on a workload adding/removing network devices in background.

All dump callbacks are able to use RCU locking now, so this patch does
roughly a revert of commits :

1c2d670f366 : [RTNETLINK]: Hold rtnl_mutex during netlink dump callbacks
6313c1e0992 : [RTNETLINK]: Remove unnecessary locking in dump callbacks

This let writers fight for rtnl mutex and readers going full speed.

It also takes care of phonet : phonet_route_get() is now called from rcu
read section. I renamed it to phonet_route_get_rcu()

Signed-off-by: Eric Dumazet <eric.dumazet@gmail.com>
Cc: Patrick McHardy <kaber@trash.net>
Cc: Remi Denis-Courmont <remi.denis-courmont@nokia.com>
---
 include/net/phonet/pn_dev.h |    2 +-
 net/bridge/br_netlink.c     |    7 ++++---
 net/core/fib_rules.c        |    3 ++-
 net/core/rtnetlink.c        |   12 +++++-------
 net/decnet/dn_dev.c         |   10 ++++++----
 net/ipv6/ip6_fib.c          |    4 +++-
 net/phonet/pn_dev.c         |    6 +-----
 net/phonet/pn_netlink.c     |    4 +++-
 8 files changed, 25 insertions(+), 23 deletions(-)

diff --git a/include/net/phonet/pn_dev.h b/include/net/phonet/pn_dev.h
index 13649eb..8639de5 100644
--- a/include/net/phonet/pn_dev.h
+++ b/include/net/phonet/pn_dev.h
@@ -51,7 +51,7 @@ void phonet_address_notify(int event, struct net_device *dev, u8 addr);
 int phonet_route_add(struct net_device *dev, u8 daddr);
 int phonet_route_del(struct net_device *dev, u8 daddr);
 void rtm_phonet_notify(int event, struct net_device *dev, u8 dst);
-struct net_device *phonet_route_get(struct net *net, u8 daddr);
+struct net_device *phonet_route_get_rcu(struct net *net, u8 daddr);
 struct net_device *phonet_route_output(struct net *net, u8 daddr);
 
 #define PN_NO_ADDR	0xff
diff --git a/net/bridge/br_netlink.c b/net/bridge/br_netlink.c
index 134a2ff..ffb0dc4 100644
--- a/net/bridge/br_netlink.c
+++ b/net/bridge/br_netlink.c
@@ -120,8 +120,9 @@ static int br_dump_ifinfo(struct sk_buff *skb, struct netlink_callback *cb)
 	int idx;
 
 	idx = 0;
-	for_each_netdev(net, dev) {
-		struct net_bridge_port *port = br_port_get_rtnl(dev);
+	rcu_read_lock();
+	for_each_netdev_rcu(net, dev) {
+		struct net_bridge_port *port = br_port_get_rcu(dev);
 
 		/* not a bridge port */
 		if (!port || idx < cb->args[0])
@@ -135,7 +136,7 @@ static int br_dump_ifinfo(struct sk_buff *skb, struct netlink_callback *cb)
 skip:
 		++idx;
 	}
-
+	rcu_read_unlock();
 	cb->args[0] = idx;
 
 	return skb->len;
diff --git a/net/core/fib_rules.c b/net/core/fib_rules.c
index 8248ebb..3911586 100644
--- a/net/core/fib_rules.c
+++ b/net/core/fib_rules.c
@@ -590,7 +590,8 @@ static int dump_rules(struct sk_buff *skb, struct netlink_callback *cb,
 	int idx = 0;
 	struct fib_rule *rule;
 
-	list_for_each_entry(rule, &ops->rules_list, list) {
+	rcu_read_lock();
+	list_for_each_entry_rcu(rule, &ops->rules_list, list) {
 		if (idx < cb->args[1])
 			goto skip;
 
diff --git a/net/core/rtnetlink.c b/net/core/rtnetlink.c
index d7c4bb4..2963312 100644
--- a/net/core/rtnetlink.c
+++ b/net/core/rtnetlink.c
@@ -1007,10 +1007,11 @@ static int rtnl_dump_ifinfo(struct sk_buff *skb, struct netlink_callback *cb)
 	s_h = cb->args[0];
 	s_idx = cb->args[1];
 
+	rcu_read_lock();
 	for (h = s_h; h < NETDEV_HASHENTRIES; h++, s_idx = 0) {
 		idx = 0;
 		head = &net->dev_index_head[h];
-		hlist_for_each_entry(dev, node, head, index_hlist) {
+		hlist_for_each_entry_rcu(dev, node, head, index_hlist) {
 			if (idx < s_idx)
 				goto cont;
 			if (rtnl_fill_ifinfo(skb, dev, RTM_NEWLINK,
@@ -1023,6 +1024,7 @@ cont:
 		}
 	}
 out:
+	rcu_read_unlock();
 	cb->args[1] = idx;
 	cb->args[0] = h;
 
@@ -1879,7 +1881,6 @@ static int rtnetlink_rcv_msg(struct sk_buff *skb, struct nlmsghdr *nlh)
 	int min_len;
 	int family;
 	int type;
-	int err;
 
 	type = nlh->nlmsg_type;
 	if (type > RTM_MAX)
@@ -1906,11 +1907,8 @@ static int rtnetlink_rcv_msg(struct sk_buff *skb, struct nlmsghdr *nlh)
 		if (dumpit == NULL)
 			return -EOPNOTSUPP;
 
-		__rtnl_unlock();
 		rtnl = net->rtnl;
-		err = netlink_dump_start(rtnl, skb, nlh, dumpit, NULL);
-		rtnl_lock();
-		return err;
+		return netlink_dump_start(rtnl, skb, nlh, dumpit, NULL);
 	}
 
 	memset(rta_buf, 0, (rtattr_max * sizeof(struct rtattr *)));
@@ -1980,7 +1978,7 @@ static int __net_init rtnetlink_net_init(struct net *net)
 {
 	struct sock *sk;
 	sk = netlink_kernel_create(net, NETLINK_ROUTE, RTNLGRP_MAX,
-				   rtnetlink_rcv, &rtnl_mutex, THIS_MODULE);
+				   rtnetlink_rcv, NULL, THIS_MODULE);
 	if (!sk)
 		return -ENOMEM;
 	net->rtnl = sk;
diff --git a/net/decnet/dn_dev.c b/net/decnet/dn_dev.c
index 0dcaa90..404fa15 100644
--- a/net/decnet/dn_dev.c
+++ b/net/decnet/dn_dev.c
@@ -752,7 +752,8 @@ static int dn_nl_dump_ifaddr(struct sk_buff *skb, struct netlink_callback *cb)
 	skip_naddr = cb->args[1];
 
 	idx = 0;
-	for_each_netdev(&init_net, dev) {
+	rcu_read_lock();
+	for_each_netdev_rcu(&init_net, dev) {
 		if (idx < skip_ndevs)
 			goto cont;
 		else if (idx > skip_ndevs) {
@@ -761,11 +762,11 @@ static int dn_nl_dump_ifaddr(struct sk_buff *skb, struct netlink_callback *cb)
 			skip_naddr = 0;
 		}
 
-		if ((dn_db = rtnl_dereference(dev->dn_ptr)) == NULL)
+		if ((dn_db = rcu_dereference(dev->dn_ptr)) == NULL)
 			goto cont;
 
-		for (ifa = rtnl_dereference(dn_db->ifa_list), dn_idx = 0; ifa;
-		     ifa = rtnl_dereference(ifa->ifa_next), dn_idx++) {
+		for (ifa = rcu_dereference(dn_db->ifa_list), dn_idx = 0; ifa;
+		     ifa = rcu_dereference(ifa->ifa_next), dn_idx++) {
 			if (dn_idx < skip_naddr)
 				continue;
 
@@ -778,6 +779,7 @@ cont:
 		idx++;
 	}
 done:
+	rcu_read_unlock();
 	cb->args[0] = idx;
 	cb->args[1] = dn_idx;
 
diff --git a/net/ipv6/ip6_fib.c b/net/ipv6/ip6_fib.c
index dd88df0..4076a0b 100644
--- a/net/ipv6/ip6_fib.c
+++ b/net/ipv6/ip6_fib.c
@@ -394,10 +394,11 @@ static int inet6_dump_fib(struct sk_buff *skb, struct netlink_callback *cb)
 	arg.net = net;
 	w->args = &arg;
 
+	rcu_read_lock();
 	for (h = s_h; h < FIB6_TABLE_HASHSZ; h++, s_e = 0) {
 		e = 0;
 		head = &net->ipv6.fib_table_hash[h];
-		hlist_for_each_entry(tb, node, head, tb6_hlist) {
+		hlist_for_each_entry_rcu(tb, node, head, tb6_hlist) {
 			if (e < s_e)
 				goto next;
 			res = fib6_dump_table(tb, skb, cb);
@@ -408,6 +409,7 @@ next:
 		}
 	}
 out:
+	rcu_read_unlock();
 	cb->args[1] = e;
 	cb->args[0] = h;
 
diff --git a/net/phonet/pn_dev.c b/net/phonet/pn_dev.c
index 947038d..47b3452 100644
--- a/net/phonet/pn_dev.c
+++ b/net/phonet/pn_dev.c
@@ -426,18 +426,14 @@ int phonet_route_del(struct net_device *dev, u8 daddr)
 	return 0;
 }
 
-struct net_device *phonet_route_get(struct net *net, u8 daddr)
+struct net_device *phonet_route_get_rcu(struct net *net, u8 daddr)
 {
 	struct phonet_net *pnn = phonet_pernet(net);
 	struct phonet_routes *routes = &pnn->routes;
 	struct net_device *dev;
 
-	ASSERT_RTNL(); /* no need to hold the device */
-
 	daddr >>= 2;
-	rcu_read_lock();
 	dev = rcu_dereference(routes->table[daddr]);
-	rcu_read_unlock();
 	return dev;
 }
 
diff --git a/net/phonet/pn_netlink.c b/net/phonet/pn_netlink.c
index 58b3b1f..438accb 100644
--- a/net/phonet/pn_netlink.c
+++ b/net/phonet/pn_netlink.c
@@ -264,10 +264,11 @@ static int route_dumpit(struct sk_buff *skb, struct netlink_callback *cb)
 	struct net *net = sock_net(skb->sk);
 	u8 addr, addr_idx = 0, addr_start_idx = cb->args[0];
 
+	rcu_read_lock();
 	for (addr = 0; addr < 64; addr++) {
 		struct net_device *dev;
 
-		dev = phonet_route_get(net, addr << 2);
+		dev = phonet_route_get_rcu(net, addr << 2);
 		if (!dev)
 			continue;
 
@@ -279,6 +280,7 @@ static int route_dumpit(struct sk_buff *skb, struct netlink_callback *cb)
 	}
 
 out:
+	rcu_read_unlock();
 	cb->args[0] = addr_idx;
 	cb->args[1] = 0;
 



^ permalink raw reply related

* Re: [PATCH] Applying inappropriate ioctl operation on socket should return ENOTTY
From: Lifeng Sun @ 2011-04-28  8:49 UTC (permalink / raw)
  To: Alan Cox; +Cc: linux-kernel, netdev
In-Reply-To: <20110427130904.47331a9f@lxorguk.ukuu.org.uk>

On Wed, Apr 27, 2011 at 8:09 PM, Alan Cox <alan@lxorguk.ukuu.org.uk> wrote:
>> diff --git a/drivers/char/viotape.c b/drivers/char/viotape.c
>> index ad6e64a..a427d40 100644
>> --- a/drivers/char/viotape.c
>> +++ b/drivers/char/viotape.c
>> @@ -529,7 +529,7 @@ static int viotap_ioctl(struct inode *inode, struct file *file,
>>
>>       down(&reqSem);
>>
>> -     ret = -EINVAL;
>> +     ret = -ENOTTY;
>
> Again this messes up the returns because code assumes the initial
> default.

> The original code also has bugs too (wrong error off
> copy_*_user() again)

It seems alright.

- Lifeng

^ permalink raw reply

* Re: [PATCH] usbnet: add support for some Huawei modems with cdc-ether ports
From: Oliver Neukum @ 2011-04-28  8:46 UTC (permalink / raw)
  To: Dan Williams; +Cc: netdev, linux-usb
In-Reply-To: <1303934071.25456.2.camel@dcbw.foobar.com>

Am Mittwoch, 27. April 2011, 21:54:28 schrieb Dan Williams:
> Some newer Huawei devices (T-Mobile Rocket, others) have cdc-ether
> compatible ports, so recognize and expose them.
> 
> Signed-off-by: Dan Williams <dcbw@redhat.com>

Acked-by: Oliver Neukum <oneukum@suse.de>

	Regards
		Oliver

^ permalink raw reply

* [PATCH 1/5] networking: inappropriate ioctl operation should return ENOTTY
From: Lifeng Sun @ 2011-04-28  8:04 UTC (permalink / raw)
  To: Alan Cox; +Cc: David S. Miller, netdev, linux-kernel, Lifeng Sun
In-Reply-To: <20110427130904.47331a9f@lxorguk.ukuu.org.uk>

ioctl() calls against a socket with an inappropriate ioctl operation
are incorrectly returning EINVAL rather than ENOTTY:

  [ENOTTY]
      Inappropriate I/O control operation.

BugLink: https://bugzilla.kernel.org/show_bug.cgi?id=33992

Signed-off-by: Lifeng Sun <lifongsun@gmail.com>
---
 net/core/dev.c |    6 +++---
 1 files changed, 3 insertions(+), 3 deletions(-)

diff --git a/net/core/dev.c b/net/core/dev.c
index c2ac599..856b6ee 100644
--- a/net/core/dev.c
+++ b/net/core/dev.c
@@ -4773,7 +4773,7 @@ static int dev_ifsioc_locked(struct net *net, struct ifreq *ifr, unsigned int cm
 		 * is never reached
 		 */
 		WARN_ON(1);
-		err = -EINVAL;
+		err = -ENOTTY;
 		break;
 
 	}
@@ -5041,7 +5041,7 @@ int dev_ioctl(struct net *net, unsigned int cmd, void __user *arg)
 		/* Set the per device memory buffer space.
 		 * Not applicable in our case */
 	case SIOCSIFLINK:
-		return -EINVAL;
+		return -ENOTTY;
 
 	/*
 	 *	Unknown or private ioctl.
@@ -5062,7 +5062,7 @@ int dev_ioctl(struct net *net, unsigned int cmd, void __user *arg)
 		/* Take care of Wireless Extensions */
 		if (cmd >= SIOCIWFIRST && cmd <= SIOCIWLAST)
 			return wext_handle_ioctl(net, &ifr, cmd, arg);
-		return -EINVAL;
+		return -ENOTTY;
 	}
 }
 
-- 
1.7.5.rc1

^ permalink raw reply related

* Re: [PATCH 6/6 v8] sctp: Add ASCONF operation on the single-homed host
From: Michio Honda @ 2011-04-28  8:04 UTC (permalink / raw)
  To: Wei Yongjun; +Cc: netdev, YOSHIFUJI Hideaki
In-Reply-To: <4DB915EF.8000003@cn.fujitsu.com>

>> 
>>>> +			/* reuse the parameter length from the same scope one */
>>>> +			totallen += paramlen;
>>>> +			totallen += addr_param_len;
>>>> +			del_pickup = 1;
>>>> +			asoc->src_out_of_asoc_ok = 1;
>>> src_out_of_asoc_ok should be marked when the last address is
>>> assigned to asoc->asconf_addr_del_pending?
>> I thought marking src_out_of_asoc_ok should be set when the candidate new address appears, rather than when the last address is being deleted.  
>> Because until such address appears, there is no situation to send any chunk from the address not in the association.  
> 
> The last address have been marked as DEL, will never using
> for sending chunks. At this time, there is no valid address in the
> host, chunk can not be send out by host.
I understand that, marking out_of_asoc_ok at the last address being deleted does same thing.  
However, out_of_asoc_ok state is not regular, so I think we should shorten that duration as much as possible.  
But this is my personal opinion, so if you don't think so, I will mark it when the last address being deleted.  
> 
>>>> +			SCTP_DEBUG_PRINTK("mkasconf_update_ip: picked same-scope del_pending addr, totallen for all addresses is %d\n", totallen);
>>>> +		}
>>>> 	}
>>>> 
>>>> 	/* Create an asconf chunk with the required length. */
>>>> @@ -2802,6 +2819,19 @@ struct sctp_chunk *sctp_make_asconf_update_ip(struct sctp_association *asoc,
>>>> 
>>>> 		addr_buf += af->sockaddr_len;
>>>> 	}
>>>> +	if (flags == SCTP_PARAM_ADD_IP && del_pickup) {
>>>> +		addr = asoc->asconf_addr_del_pending;
>>>> +		del_af = sctp_get_af_specific(addr->v4.sin_family);
>>>> +		del_addr_param_len = del_af->to_addr_param(addr,
>>>> +		    &del_addr_param);
>>>> +		del_param.param_hdr.type = SCTP_PARAM_DEL_IP;
>>>> +		del_param.param_hdr.length = htons(del_paramlen +
>>>> +		    del_addr_param_len);
>>>> +		del_param.crr_id = i;
>>>> +
>>>> +		sctp_addto_chunk(retval, del_paramlen, &del_param);
>>>> +		sctp_addto_chunk(retval, del_addr_param_len, &del_addr_param);
>>>> +	}
>>>> 	return retval;
>>>> }
>>> How about clean up this part as:
>>> 
>>> +       if (...) {
>>> +               addr = asoc->asconf_addr_del_pending;
>>> +               af = sctp_get_af_specific(addr->v4.sin_family);
>>> +               addr_param_len = af->to_addr_param(addr, &addr_param);
>>> +               totallen += paramlen;
>>> +               totallen += addr_param_len;
>>> +		...
>>> +       }
>>> +
>>>      /* Create an asconf chunk with the required length. */
>>>      retval = sctp_make_asconf(asoc, laddr, totallen);
>>>      if (!retval)
>>> @@ -2802,6 +2812,18 @@ struct sctp_chunk *sctp_make_asconf_update_ip(struct sctp_association *asoc,
>>> 
>>>              addr_buf += af->sockaddr_len;
>>>      }
>>> +
>>> +       if (...) {
>>> +               addr = asoc->asconf_addr_del_pending;
>>> +               af = sctp_get_af_specific(addr->v4.sin_family);
>>> +               addr_param_len = af->to_addr_param(addr, &addr_param);
>>> +               param.param_hdr.type = SCTP_PARAM_DEL_IP;
>>> +               param.param_hdr.length = htons(paramlen + addr_param_len);
>>> +               param.crr_id = i;
>>> +
>>> +               sctp_addto_chunk(retval, paramlen, &param);
>>> +               sctp_addto_chunk(retval, addr_param_len, &addr_param);
>>> +       }
>> agreed with reusing af instead of defining del_af.  
>> --
>> 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: [PATCHv4 2/7] ethtool: Call ethtool's get/set_settings callbacks with cleaned data
From: Stanislaw Gruszka @ 2011-04-28  7:34 UTC (permalink / raw)
  To: David Decotigny
  Cc: Grant Grundler, e1000-devel, linux-kernel, Eilon Greenstein,
	mirq-linux, netdev, Ben Hutchings, David S. Miller
In-Reply-To: <1303965163-8198-3-git-send-email-decot@google.com>

On Wed, Apr 27, 2011 at 09:32:38PM -0700, David Decotigny wrote:
> --- a/drivers/net/stmmac/stmmac_ethtool.c
> +++ b/drivers/net/stmmac/stmmac_ethtool.c
> @@ -237,13 +237,12 @@ stmmac_set_pauseparam(struct net_device *netdev,
>  
>  	if (phy->autoneg) {
>  		if (netif_running(netdev)) {
> -			struct ethtool_cmd cmd;
> +			struct ethtool_cmd cmd = { .cmd = ETHTOOL_SSET };
>  			/* auto-negotiation automatically restarted */
> -			cmd.cmd = ETHTOOL_NWAY_RST;

Why did you change ETHTOOL_NWAY_RST to ETHTOOL_SSET ?


------------------------------------------------------------------------------
WhatsUp Gold - Download Free Network Management Software
The most intuitive, comprehensive, and cost-effective network 
management toolset available today.  Delivers lowest initial 
acquisition cost and overall TCO of any competing solution.
http://p.sf.net/sfu/whatsupgold-sd
_______________________________________________
E1000-devel mailing list
E1000-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/e1000-devel
To learn more about Intel&#174; Ethernet, visit http://communities.intel.com/community/wired

^ permalink raw reply

* Is 802.3ad mode in bonding useful ?
From: WeipingPan @ 2011-04-28  7:33 UTC (permalink / raw)
  To: netdev

Hi, all,

802.3ad mode in bonding implements 802.3ad standard.

I am just wondering  802.3ad mode is useful,
since  bonding has many modes like balance-rr, active-backup, etc.

thanks
Weiping Pan

^ permalink raw reply

* Re: [PATCH 6/6 v8] sctp: Add ASCONF operation on the single-homed host
From: Wei Yongjun @ 2011-04-28  7:23 UTC (permalink / raw)
  To: Michio Honda; +Cc: netdev, YOSHIFUJI Hideaki
In-Reply-To: <8B2DF56A-11D6-41F6-85E5-01AA47C0F774@sfc.wide.ad.jp>



> Hi, 
>
>>>
>>> diff --git a/net/sctp/sm_make_chunk.c b/net/sctp/sm_make_chunk.c
>>> index 3740603..6363c46 100644
>>> --- a/net/sctp/sm_make_chunk.c
>>> +++ b/net/sctp/sm_make_chunk.c
>>> @@ -2768,6 +2768,12 @@ struct sctp_chunk *sctp_make_asconf_update_ip(struct sctp_association *asoc,
>>> 	int			addr_param_len = 0;
>>> 	int 			totallen = 0;
>>> 	int 			i;
>>> +	sctp_addip_param_t del_param; /* 8 Bytes (Type 0xC002, Len and CrrID) */
>>> +	struct sctp_af *del_af;
>>> +	int del_addr_param_len = 0;
>>> +	int del_paramlen = sizeof(sctp_addip_param_t);
>>> +	union sctp_addr_param del_addr_param; /* (v4) 8 Bytes, (v6) 20 Bytes */
>>> +	int			del_pickup = 0;
>>>
>>> 	/* Get total length of all the address parameters. */
>>> 	addr_buf = addrs;
>>> @@ -2780,6 +2786,17 @@ struct sctp_chunk *sctp_make_asconf_update_ip(struct sctp_association *asoc,
>>> 		totallen += addr_param_len;
>>>
>>> 		addr_buf += af->sockaddr_len;
>>> +		if (asoc->asconf_addr_del_pending && !del_pickup) {
>>> +			if (!sctp_in_scope(asoc->asconf_addr_del_pending,
>>> +			    sctp_scope(addr)))
>>> +				continue;
>> scope should olny be check before address is added to the asoc.
>> delete does not need this, since we have checked that the address
>> be deleted is existed in the asoc.
> Exactly, I remove this check and add the code to check scope for adding address in sctp_asconf_mgmt().  
>> You can test with the last test commands I send to your, instead,
>> ifdown/up the lo device.
>> $ ifdown lo && ifup lo
> Ah, I see, I try.  
>>> +			/* reuse the parameter length from the same scope one */
>>> +			totallen += paramlen;
>>> +			totallen += addr_param_len;
>>> +			del_pickup = 1;
>>> +			asoc->src_out_of_asoc_ok = 1;
>> src_out_of_asoc_ok should be marked when the last address is
>> assigned to asoc->asconf_addr_del_pending?
> I thought marking src_out_of_asoc_ok should be set when the candidate new address appears, rather than when the last address is being deleted.  
> Because until such address appears, there is no situation to send any chunk from the address not in the association.  

The last address have been marked as DEL, will never using
for sending chunks. At this time, there is no valid address in the
host, chunk can not be send out by host.

>>> +			SCTP_DEBUG_PRINTK("mkasconf_update_ip: picked same-scope del_pending addr, totallen for all addresses is %d\n", totallen);
>>> +		}
>>> 	}
>>>
>>> 	/* Create an asconf chunk with the required length. */
>>> @@ -2802,6 +2819,19 @@ struct sctp_chunk *sctp_make_asconf_update_ip(struct sctp_association *asoc,
>>>
>>> 		addr_buf += af->sockaddr_len;
>>> 	}
>>> +	if (flags == SCTP_PARAM_ADD_IP && del_pickup) {
>>> +		addr = asoc->asconf_addr_del_pending;
>>> +		del_af = sctp_get_af_specific(addr->v4.sin_family);
>>> +		del_addr_param_len = del_af->to_addr_param(addr,
>>> +		    &del_addr_param);
>>> +		del_param.param_hdr.type = SCTP_PARAM_DEL_IP;
>>> +		del_param.param_hdr.length = htons(del_paramlen +
>>> +		    del_addr_param_len);
>>> +		del_param.crr_id = i;
>>> +
>>> +		sctp_addto_chunk(retval, del_paramlen, &del_param);
>>> +		sctp_addto_chunk(retval, del_addr_param_len, &del_addr_param);
>>> +	}
>>> 	return retval;
>>> }
>> How about clean up this part as:
>>
>> +       if (...) {
>> +               addr = asoc->asconf_addr_del_pending;
>> +               af = sctp_get_af_specific(addr->v4.sin_family);
>> +               addr_param_len = af->to_addr_param(addr, &addr_param);
>> +               totallen += paramlen;
>> +               totallen += addr_param_len;
>> +		...
>> +       }
>> +
>>       /* Create an asconf chunk with the required length. */
>>       retval = sctp_make_asconf(asoc, laddr, totallen);
>>       if (!retval)
>> @@ -2802,6 +2812,18 @@ struct sctp_chunk *sctp_make_asconf_update_ip(struct sctp_association *asoc,
>>
>>               addr_buf += af->sockaddr_len;
>>       }
>> +
>> +       if (...) {
>> +               addr = asoc->asconf_addr_del_pending;
>> +               af = sctp_get_af_specific(addr->v4.sin_family);
>> +               addr_param_len = af->to_addr_param(addr, &addr_param);
>> +               param.param_hdr.type = SCTP_PARAM_DEL_IP;
>> +               param.param_hdr.length = htons(paramlen + addr_param_len);
>> +               param.crr_id = i;
>> +
>> +               sctp_addto_chunk(retval, paramlen, &param);
>> +               sctp_addto_chunk(retval, addr_param_len, &addr_param);
>> +       }
> agreed with reusing af instead of defining del_af.  
> --
> 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 6/6 v8] sctp: Add ASCONF operation on the single-homed host
From: Michio Honda @ 2011-04-28  7:04 UTC (permalink / raw)
  To: Wei Yongjun; +Cc: netdev, YOSHIFUJI Hideaki
In-Reply-To: <4DB8F287.2070000@cn.fujitsu.com>

Hi, 

>> 
>> 
>> diff --git a/net/sctp/sm_make_chunk.c b/net/sctp/sm_make_chunk.c
>> index 3740603..6363c46 100644
>> --- a/net/sctp/sm_make_chunk.c
>> +++ b/net/sctp/sm_make_chunk.c
>> @@ -2768,6 +2768,12 @@ struct sctp_chunk *sctp_make_asconf_update_ip(struct sctp_association *asoc,
>> 	int			addr_param_len = 0;
>> 	int 			totallen = 0;
>> 	int 			i;
>> +	sctp_addip_param_t del_param; /* 8 Bytes (Type 0xC002, Len and CrrID) */
>> +	struct sctp_af *del_af;
>> +	int del_addr_param_len = 0;
>> +	int del_paramlen = sizeof(sctp_addip_param_t);
>> +	union sctp_addr_param del_addr_param; /* (v4) 8 Bytes, (v6) 20 Bytes */
>> +	int			del_pickup = 0;
>> 
>> 	/* Get total length of all the address parameters. */
>> 	addr_buf = addrs;
>> @@ -2780,6 +2786,17 @@ struct sctp_chunk *sctp_make_asconf_update_ip(struct sctp_association *asoc,
>> 		totallen += addr_param_len;
>> 
>> 		addr_buf += af->sockaddr_len;
>> +		if (asoc->asconf_addr_del_pending && !del_pickup) {
>> +			if (!sctp_in_scope(asoc->asconf_addr_del_pending,
>> +			    sctp_scope(addr)))
>> +				continue;
> 
> scope should olny be check before address is added to the asoc.
> delete does not need this, since we have checked that the address
> be deleted is existed in the asoc.
Exactly, I remove this check and add the code to check scope for adding address in sctp_asconf_mgmt().  
> 
> You can test with the last test commands I send to your, instead,
> ifdown/up the lo device.
> $ ifdown lo && ifup lo
Ah, I see, I try.  
> 
>> +			/* reuse the parameter length from the same scope one */
>> +			totallen += paramlen;
>> +			totallen += addr_param_len;
>> +			del_pickup = 1;
>> +			asoc->src_out_of_asoc_ok = 1;
> 
> src_out_of_asoc_ok should be marked when the last address is
> assigned to asoc->asconf_addr_del_pending?
I thought marking src_out_of_asoc_ok should be set when the candidate new address appears, rather than when the last address is being deleted.  
Because until such address appears, there is no situation to send any chunk from the address not in the association.  
> 
>> +			SCTP_DEBUG_PRINTK("mkasconf_update_ip: picked same-scope del_pending addr, totallen for all addresses is %d\n", totallen);
>> +		}
>> 	}
>> 
>> 	/* Create an asconf chunk with the required length. */
>> @@ -2802,6 +2819,19 @@ struct sctp_chunk *sctp_make_asconf_update_ip(struct sctp_association *asoc,
>> 
>> 		addr_buf += af->sockaddr_len;
>> 	}
>> +	if (flags == SCTP_PARAM_ADD_IP && del_pickup) {
>> +		addr = asoc->asconf_addr_del_pending;
>> +		del_af = sctp_get_af_specific(addr->v4.sin_family);
>> +		del_addr_param_len = del_af->to_addr_param(addr,
>> +		    &del_addr_param);
>> +		del_param.param_hdr.type = SCTP_PARAM_DEL_IP;
>> +		del_param.param_hdr.length = htons(del_paramlen +
>> +		    del_addr_param_len);
>> +		del_param.crr_id = i;
>> +
>> +		sctp_addto_chunk(retval, del_paramlen, &del_param);
>> +		sctp_addto_chunk(retval, del_addr_param_len, &del_addr_param);
>> +	}
>> 	return retval;
>> }
> 
> How about clean up this part as:
> 
> +       if (...) {
> +               addr = asoc->asconf_addr_del_pending;
> +               af = sctp_get_af_specific(addr->v4.sin_family);
> +               addr_param_len = af->to_addr_param(addr, &addr_param);
> +               totallen += paramlen;
> +               totallen += addr_param_len;
> +		...
> +       }
> +
>       /* Create an asconf chunk with the required length. */
>       retval = sctp_make_asconf(asoc, laddr, totallen);
>       if (!retval)
> @@ -2802,6 +2812,18 @@ struct sctp_chunk *sctp_make_asconf_update_ip(struct sctp_association *asoc,
> 
>               addr_buf += af->sockaddr_len;
>       }
> +
> +       if (...) {
> +               addr = asoc->asconf_addr_del_pending;
> +               af = sctp_get_af_specific(addr->v4.sin_family);
> +               addr_param_len = af->to_addr_param(addr, &addr_param);
> +               param.param_hdr.type = SCTP_PARAM_DEL_IP;
> +               param.param_hdr.length = htons(paramlen + addr_param_len);
> +               param.crr_id = i;
> +
> +               sctp_addto_chunk(retval, paramlen, &param);
> +               sctp_addto_chunk(retval, addr_param_len, &addr_param);
> +       }
agreed with reusing af instead of defining del_af.  
> 


^ permalink raw reply

* Re: Maximum no of bytes Ethernet can transfer at a time ??
From: Eric Dumazet @ 2011-04-28  6:40 UTC (permalink / raw)
  To: Ajit; +Cc: netdev
In-Reply-To: <loom.20110428T083015-693@post.gmane.org>

Le jeudi 28 avril 2011 à 06:36 +0000, Ajit a écrit :
> Ajit <ajitsa_bes <at> yahoo.com> writes:
> 
> > 
> > Eric Dumazet <eric.dumazet <at> gmail.com> writes:
> > 
> > > Sure, check your syscall returns values, and search for SO_RCVBUF &
> > > SO_SNDBUF   (man 7 socket)
> > > 
> > > --
> > 
> > okies..I dont know exactly how to use those but I will google and try it..
> > will post my result after some time.
> > 
> > Thank you
> > 
> > --
> > To unsubscribe from this list: send the line "unsubscribe netdev" in
> > the body of a message to majordomo <at> vger.kernel.org
> > More majordomo info at  http://vger.kernel.org/majordomo-info.html
> > 
> > 
> 
> 
> hi sir,
> I tried out something as you said.
> 
> I introduces this lines in my code,
> 
> getsockopt(s,SOL_SOCKET,SO_RCVBUF,&optval,&optlen);
> printf("The value of optlen is %d\n",optlen);
> 

Oh well, netdev is really not the place to discussion like that.

int optval;
socklen_t optlen = sizeof(optval);
getsockopt(s,SOL_SOCKET,SO_RCVBUF, &optval, &optlen);
printf("The value of optval is %d\n", optval);

> It always displays 4.
> 
> I really have no idea about it. Do I need to use setsockopt options in my
> receiver code ??
> If so, what difference will it make ??

It makes sure your socket can really receive enough messages (or kernel
drops them)




^ permalink raw reply

* Re: Maximum no of bytes Ethernet can transfer at a time ??
From: Ajit @ 2011-04-28  6:36 UTC (permalink / raw)
  To: netdev
In-Reply-To: <loom.20110427T142551-736@post.gmane.org>

Ajit <ajitsa_bes <at> yahoo.com> writes:

> 
> Eric Dumazet <eric.dumazet <at> gmail.com> writes:
> 
> > Sure, check your syscall returns values, and search for SO_RCVBUF &
> > SO_SNDBUF   (man 7 socket)
> > 
> > --
> 
> okies..I dont know exactly how to use those but I will google and try it..
> will post my result after some time.
> 
> Thank you
> 
> --
> To unsubscribe from this list: send the line "unsubscribe netdev" in
> the body of a message to majordomo <at> vger.kernel.org
> More majordomo info at  http://vger.kernel.org/majordomo-info.html
> 
> 


hi sir,
I tried out something as you said.

I introduces this lines in my code,

getsockopt(s,SOL_SOCKET,SO_RCVBUF,&optval,&optlen);
printf("The value of optlen is %d\n",optlen);

It always displays 4.

I really have no idea about it. Do I need to use setsockopt options in my
receiver code ??
If so, what difference will it make ??


^ permalink raw reply

* Re: [PATCH 08/13] netvm: Allow skb allocation to use PFMEMALLOC reserves
From: NeilBrown @ 2011-04-28  6:19 UTC (permalink / raw)
  To: Mel Gorman; +Cc: Linux-MM, Linux-Netdev, LKML, David Miller, Peter Zijlstra
In-Reply-To: <1303920491-25302-9-git-send-email-mgorman@suse.de>

On Wed, 27 Apr 2011 17:08:06 +0100 Mel Gorman <mgorman@suse.de> wrote:


> @@ -1578,7 +1589,7 @@ static inline struct sk_buff *netdev_alloc_skb_ip_align(struct net_device *dev,
>   */
>  static inline struct page *__netdev_alloc_page(struct net_device *dev, gfp_t gfp_mask)
>  {
> -	return alloc_pages_node(NUMA_NO_NODE, gfp_mask, 0);
> +	return alloc_pages_node(NUMA_NO_NODE, gfp_mask | __GFP_MEMALLOC, 0);
>  }
>  

I'm puzzling a bit over this change.
__netdev_alloc_page appears to be used to get pages to put in ring buffer
for a network card to DMA received packets into.  So it is OK to use
__GFP_MEMALLOC for these allocations providing we mark the resulting skb as
'pfmemalloc' if a reserved page was used.

However I don't see where that marking is done.
I think it should be in skb_fill_page_desc, something like:

  if (page->pfmemalloc)
	skb->pfmemalloc = true;

Is this covered somewhere else that I am missing?

Thanks,
NeilBrown

--
To unsubscribe, send a message with 'unsubscribe linux-mm' in
the body to majordomo@kvack.org.  For more info on Linux MM,
see: http://www.linux-mm.org/ .
Fight unfair telecom internet charges in Canada: sign http://stopthemeter.ca/
Don't email: <a href=mailto:"dont@kvack.org"> email@kvack.org </a>

^ permalink raw reply

* Re: Linux TCP's Robustness to Multipath Packet Reordering
From: Alexander Zimmermann @ 2011-04-28  6:11 UTC (permalink / raw)
  To: Yuchung Cheng
  Cc: Dominik Kaspar, Carsten Wolff, John Heffner, Eric Dumazet, netdev,
	Lennart Schulte, Arnd Hannemann
In-Reply-To: <BANLkTin5dsubSjOhz3enOjubfVVk6uiNbQ@mail.gmail.com>

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


Am 27.04.2011 um 23:41 schrieb Yuchung Cheng:

> AFAIK, FACK is disabled throughout the life of the connection after
> sender detects reordering degree > 3.

Right.

> 
> But Alex said the reordering has some bugs. I suspect these bugs may
> affect FACK/sack auto-tuning.

No. It affects reordering detection only. 

> Maybe Alex could describe the reordering
> bugs?
> 

Yes, I can. With DSACK, you have two cases. DSACK below and above SEG.ACK.
DSACK below SEG.ACK is the come case. However, Linux doesn't calculate a
reordering extent in this case. We will fix this. In the other case, DSACK
above SEG.ACK, Linux quantifies the reordering as the distance between the
received DSACK and snd_fack. However, this is only correct if the reordering
delay is greater the RTT. We will fix that too.

As a result, in the first case, we waste the opportunity to calculate an
extent (loosing performance). In the second case we overestimate the
reordering.

Alex

//
// Dipl.-Inform. Alexander Zimmermann
// Department of Computer Science, Informatik 4
// RWTH Aachen University
// Ahornstr. 55, 52056 Aachen, Germany
// phone: (49-241) 80-21422, fax: (49-241) 80-22222
// email: zimmermann@cs.rwth-aachen.de
// web: http://www.umic-mesh.net
//


[-- Attachment #2: Signierter Teil der Nachricht --]
[-- Type: application/pgp-signature, Size: 243 bytes --]

^ permalink raw reply

* Re: [PATCH 2/2] macvlan: Send frames to AF_PACKET sockets attached to lowerdev
From: David Miller @ 2011-04-28  6:09 UTC (permalink / raw)
  To: david.ward; +Cc: netdev, kaber
In-Reply-To: <1303392693-1350-3-git-send-email-david.ward@ll.mit.edu>

From: David Ward <david.ward@ll.mit.edu>
Date: Thu, 21 Apr 2011 09:31:33 -0400

>  		dest = macvlan_hash_lookup(port, eth->h_dest);
>  		if (dest && dest->mode == MACVLAN_MODE_BRIDGE) {
> +			dev_queue_xmit_nit(skb, vlan->lowerdev);
>  			unsigned int length = skb->len + ETH_HLEN;
>  			int ret = dest->forward(dest->dev, skb);
>  			macvlan_count_rx(dest, length,

Don't put actual code before variable declarations in a basic
block, modern variants of C accept this but this isn't C++.

^ permalink raw reply

* Re: [PATCH net-next] net: Allow ethtool to set interface in loopback mode.
From: David Miller @ 2011-04-28  6:08 UTC (permalink / raw)
  To: maheshb; +Cc: netdev
In-Reply-To: <1303347458-14499-1-git-send-email-maheshb@google.com>

From: Mahesh Bandewar <maheshb@google.com>
Date: Wed, 20 Apr 2011 17:57:38 -0700

> This patch enables ethtool to set the loopback mode on a given interface.
> By configuring the interface in loopback mode in conjunction with a policy
> route / rule, a userland application can stress the egress / ingress path
> exposing the flows of the change in progress and potentially help developer(s)
> understand the impact of those changes without even sending a packet out
> on the network.
> 
> Following set of commands illustrates one such example -
>     a) ip -4 addr add 192.168.1.1/24 dev eth1
>     b) ip -4 rule add from all iif eth1 lookup 250
>     c) ip -4 route add local 0/0 dev lo proto kernel scope host table 250
>     d) arp -Ds 192.168.1.100 eth1
>     e) arp -Ds 192.168.1.200 eth1
>     f) sysctl -w net.ipv4.ip_nonlocal_bind=1
>     g) sysctl -w net.ipv4.conf.all.accept_local=1
>     # Assuming that the machine has 8 cores
>     h) taskset 000f netserver -L 192.168.1.200
>     i) taskset 00f0 netperf -t TCP_CRR -L 192.168.1.100 -H 192.168.1.200 -l 30
> 
> Signed-off-by: Mahesh Bandewar <maheshb@google.com>

It's impossible to evaluate this patch without you also showing us some
users.

I'm not applying this.

^ permalink raw reply

* Re: [PATCH v2] net: filter: Just In Time compiler
From: David Miller @ 2011-04-28  6:05 UTC (permalink / raw)
  To: eric.dumazet; +Cc: avi, hagen, netdev, acme, bhutchings
In-Reply-To: <1303327652.2690.23.camel@edumazet-laptop>

From: Eric Dumazet <eric.dumazet@gmail.com>
Date: Wed, 20 Apr 2011 21:27:32 +0200

> [PATCH v3] net: filter: Just In Time compiler

Applied, thanks Eric!

^ permalink raw reply

* Re: [PATCHv7] usbnet: Resubmit interrupt URB if device is open
From: David Miller @ 2011-04-28  6:00 UTC (permalink / raw)
  To: pstew-F7+t8E8rja9g9hUCZPvPmw
  Cc: netdev-u79uwXL29TY76Z2rM5mHXA, oliver-GvhC2dPhHPQdnm+yROfE0A,
	stern-nwvwT67g6+6dFdvTe/nMLpVzexx5G7lz,
	bhutchings-s/n/eUQHGBpZroRs9YW3xA,
	linux-usb-u79uwXL29TY76Z2rM5mHXA
In-Reply-To: <20110426172059.4C9B320242-6A69KNNYBwgF248FYctl9mCaruZE5nAUZeezCHUQhQ4@public.gmane.org>

From: Paul Stewart <pstew-F7+t8E8rja9g9hUCZPvPmw@public.gmane.org>
Date: Tue, 26 Apr 2011 09:58:32 -0700

> Resubmit interrupt URB if device is open.  Use a flag set in
> usbnet_open() to determine this state.  Also kill and free
> interrupt URB in usbnet_disconnect().
> 
> Signed-off-by: Paul Stewart <pstew-F7+t8E8rja9g9hUCZPvPmw@public.gmane.org>

This doesn't apply at all to Linus's current tree.

Several new EVENT_* flags have been added, and usbnet_resume() does
a lot more things than whatever version your patch is against.

I'm not going to pick a new value EVENT_* mask and force the rest of
this to apply, because all of these other changes that have happened
to the driver meanwhile might interact with your changes in ways I
won't understand.

You'll therefore need to look this over and submit a patch which will
apply cleanly.
--
To unsubscribe from this list: send the line "unsubscribe linux-usb" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

^ permalink raw reply

* Re: Maximum no of bytes Ethernet can transfer at a time ??
From: Ajit @ 2011-04-28  5:49 UTC (permalink / raw)
  To: netdev
In-Reply-To: <20110427130114.GA1895@hmsreliant.think-freely.org>

Neil Horman <nhorman <at> tuxdriver.com> writes:


hii Neil,

I am not using the transport layer neither the Network layer. I have written a
small protocol which work of a LAN without a router. So ideally there is no need
of the network layer (I am using physical address for the transfer). 

I have defined a filed called as "offset" and another one called as "id".
Whenever you send a file, it is divided into various frames depending upon the
size of the file and send with the same "id" and an offset incremented by 1.

As you said the firewall issues. I don't think that is the problem because I am
sending the file to myself, but , on eth0 rather than lo, because send on lo
wont give the expected results.

If you still want some explanation then please ask me.

Thank you. 



^ permalink raw reply

* Re: [PATCH 6/6 v8] sctp: Add ASCONF operation on the single-homed host
From: Wei Yongjun @ 2011-04-28  4:52 UTC (permalink / raw)
  To: Michio Honda; +Cc: netdev, YOSHIFUJI Hideaki
In-Reply-To: <4947D5B3-9FCA-42AA-81D0-9D55594108F1@sfc.wide.ad.jp>


> From 983b3d3f2ffe0173f0e63af029610ce301ff397c Mon Sep 17 00:00:00 2001
> From: Michio Honda <micchie@sfc.wide.ad.jp>
> Date: Tue, 26 Apr 2011 20:19:36 +0900
> Subject: [PATCH 6/6 v8] sctp: Add ASCONF operation on the single-homed host
>
> In this case, the SCTP association transmits an ASCONF packet
> including addition of the new IP address and deletion of the old
> address.  This patch implements this functionality.
> In this case, the ASCONF chunk is added to the beginning of the
> queue, because the other chunks cannot be transmitted in this state.
>
> Signed-off-by: Michio Honda <micchie@sfc.wide.ad.jp>
> Signed-off-by: YOSHIFUJI Hideaki <yoshfuji@linux-ipv6.org>
> ---
>  include/net/sctp/structs.h |    2 +
>  net/sctp/associola.c       |    6 ++++
>  net/sctp/ipv6.c            |    7 +++++
>  net/sctp/outqueue.c        |   13 ++++++++++
>  net/sctp/protocol.c        |    4 ++-
>  net/sctp/sm_make_chunk.c   |   38 ++++++++++++++++++++++++++++++
>  net/sctp/socket.c          |   55 +++++++++++++++++++++++++++++++++++++++----
>  7 files changed, 118 insertions(+), 7 deletions(-)
>
> diff --git a/include/net/sctp/structs.h b/include/net/sctp/structs.h
> index f7f6add..095f698 100644
> --- a/include/net/sctp/structs.h
> +++ b/include/net/sctp/structs.h
> @@ -1916,6 +1916,8 @@ struct sctp_association {
>  	 * after reaching 4294967295.
>  	 */
>  	__u32 addip_serial;
> +	union sctp_addr *asconf_addr_del_pending;
> +	int src_out_of_asoc_ok;
>  
>  	/* SCTP AUTH: list of the endpoint shared keys.  These
>  	 * keys are provided out of band by the user applicaton
> diff --git a/net/sctp/associola.c b/net/sctp/associola.c
> index 1a21c57..10dc059 100644
> --- a/net/sctp/associola.c
> +++ b/net/sctp/associola.c
> @@ -279,6 +279,8 @@ static struct sctp_association *sctp_association_init(struct sctp_association *a
>  	asoc->peer.asconf_capable = 0;
>  	if (sctp_addip_noauth)
>  		asoc->peer.asconf_capable = 1;
> +	asoc->asconf_addr_del_pending = NULL;
> +	asoc->src_out_of_asoc_ok = 0;
>  
>  	/* Create an input queue.  */
>  	sctp_inq_init(&asoc->base.inqueue);
> @@ -443,6 +445,10 @@ void sctp_association_free(struct sctp_association *asoc)
>  
>  	asoc->peer.transport_count = 0;
>  
> +	/* Free pending address space being deleted */
> +	if (asoc->asconf_addr_del_pending != NULL)
> +		kfree(asoc->asconf_addr_del_pending);
> +
>  	/* Free any cached ASCONF_ACK chunk. */
>  	sctp_assoc_free_asconf_acks(asoc);
>  
> diff --git a/net/sctp/ipv6.c b/net/sctp/ipv6.c
> index 233eb3a..b493916 100644
> --- a/net/sctp/ipv6.c
> +++ b/net/sctp/ipv6.c
> @@ -334,6 +334,13 @@ static void sctp_v6_get_saddr(struct sctp_sock *sk,
>  				matchlen = bmatchlen;
>  			}
>  		}
> +		if (laddr->state == SCTP_ADDR_NEW && asoc->src_out_of_asoc_ok) {
> +			bmatchlen = sctp_v6_addr_match_len(daddr, &laddr->a);
> +			if (!baddr || (matchlen < bmatchlen)) {
> +				baddr = &laddr->a;
> +				matchlen = bmatchlen;
> +			}
> +		}
>  	}
>  
>  	if (baddr) {
> diff --git a/net/sctp/outqueue.c b/net/sctp/outqueue.c
> index 1c88c89..edc7532 100644
> --- a/net/sctp/outqueue.c
> +++ b/net/sctp/outqueue.c
> @@ -754,6 +754,16 @@ static int sctp_outq_flush(struct sctp_outq *q, int rtx_timeout)
>  	 */
>  
>  	list_for_each_entry_safe(chunk, tmp, &q->control_chunk_list, list) {
> +		/* RFC 5061, 5.3
> +		 * F1) This means that until such time as the ASCONF
> +		 * containing the add is acknowledged, the sender MUST
> +		 * NOT use the new IP address as a source for ANY SCTP
> +		 * packet except on carrying an ASCONF Chunk.
> +		 */
> +		if (asoc->src_out_of_asoc_ok &&
> +		    chunk->chunk_hdr->type != SCTP_CID_ASCONF)
> +			continue;
> +
>  		list_del_init(&chunk->list);
>  
>  		/* Pick the right transport to use. */
> @@ -881,6 +891,9 @@ static int sctp_outq_flush(struct sctp_outq *q, int rtx_timeout)
>  		}
>  	}
>  
> +	if (q->asoc->src_out_of_asoc_ok)
> +		goto sctp_flush_out;
> +
>  	/* Is it OK to send data chunks?  */
>  	switch (asoc->state) {
>  	case SCTP_STATE_COOKIE_ECHOED:
> diff --git a/net/sctp/protocol.c b/net/sctp/protocol.c
> index b58a820..d7309927 100644
> --- a/net/sctp/protocol.c
> +++ b/net/sctp/protocol.c
> @@ -510,7 +510,9 @@ static struct dst_entry *sctp_v4_get_dst(struct sctp_association *asoc,
>  		sctp_v4_dst_saddr(&dst_saddr, dst, htons(bp->port));
>  		rcu_read_lock();
>  		list_for_each_entry_rcu(laddr, &bp->address_list, list) {
> -			if (!laddr->valid || (laddr->state != SCTP_ADDR_SRC))
> +			if (!laddr->valid || (laddr->state == SCTP_ADDR_DEL) ||
> +			    (laddr->state != SCTP_ADDR_SRC &&
> +			    !asoc->src_out_of_asoc_ok))
>  				continue;
>  			if (sctp_v4_cmp_addr(&dst_saddr, &laddr->a))
>  				goto out_unlock;
> diff --git a/net/sctp/sm_make_chunk.c b/net/sctp/sm_make_chunk.c
> index 3740603..6363c46 100644
> --- a/net/sctp/sm_make_chunk.c
> +++ b/net/sctp/sm_make_chunk.c
> @@ -2768,6 +2768,12 @@ struct sctp_chunk *sctp_make_asconf_update_ip(struct sctp_association *asoc,
>  	int			addr_param_len = 0;
>  	int 			totallen = 0;
>  	int 			i;
> +	sctp_addip_param_t del_param; /* 8 Bytes (Type 0xC002, Len and CrrID) */
> +	struct sctp_af *del_af;
> +	int del_addr_param_len = 0;
> +	int del_paramlen = sizeof(sctp_addip_param_t);
> +	union sctp_addr_param del_addr_param; /* (v4) 8 Bytes, (v6) 20 Bytes */
> +	int			del_pickup = 0;
>  
>  	/* Get total length of all the address parameters. */
>  	addr_buf = addrs;
> @@ -2780,6 +2786,17 @@ struct sctp_chunk *sctp_make_asconf_update_ip(struct sctp_association *asoc,
>  		totallen += addr_param_len;
>  
>  		addr_buf += af->sockaddr_len;
> +		if (asoc->asconf_addr_del_pending && !del_pickup) {
> +			if (!sctp_in_scope(asoc->asconf_addr_del_pending,
> +			    sctp_scope(addr)))
> +				continue;

scope should olny be check before address is added to the asoc.
delete does not need this, since we have checked that the address
be deleted is existed in the asoc.

You can test with the last test commands I send to your, instead,
ifdown/up the lo device.
$ ifdown lo && ifup lo

> +			/* reuse the parameter length from the same scope one */
> +			totallen += paramlen;
> +			totallen += addr_param_len;
> +			del_pickup = 1;
> +			asoc->src_out_of_asoc_ok = 1;

src_out_of_asoc_ok should be marked when the last address is
assigned to asoc->asconf_addr_del_pending?

> +			SCTP_DEBUG_PRINTK("mkasconf_update_ip: picked same-scope del_pending addr, totallen for all addresses is %d\n", totallen);
> +		}
>  	}
>  
>  	/* Create an asconf chunk with the required length. */
> @@ -2802,6 +2819,19 @@ struct sctp_chunk *sctp_make_asconf_update_ip(struct sctp_association *asoc,
>  
>  		addr_buf += af->sockaddr_len;
>  	}
> +	if (flags == SCTP_PARAM_ADD_IP && del_pickup) {
> +		addr = asoc->asconf_addr_del_pending;
> +		del_af = sctp_get_af_specific(addr->v4.sin_family);
> +		del_addr_param_len = del_af->to_addr_param(addr,
> +		    &del_addr_param);
> +		del_param.param_hdr.type = SCTP_PARAM_DEL_IP;
> +		del_param.param_hdr.length = htons(del_paramlen +
> +		    del_addr_param_len);
> +		del_param.crr_id = i;
> +
> +		sctp_addto_chunk(retval, del_paramlen, &del_param);
> +		sctp_addto_chunk(retval, del_addr_param_len, &del_addr_param);
> +	}
>  	return retval;
>  }

How about clean up this part as:

+       if (...) {
+               addr = asoc->asconf_addr_del_pending;
+               af = sctp_get_af_specific(addr->v4.sin_family);
+               addr_param_len = af->to_addr_param(addr, &addr_param);
+               totallen += paramlen;
+               totallen += addr_param_len;
+		...
+       }
+
        /* Create an asconf chunk with the required length. */
        retval = sctp_make_asconf(asoc, laddr, totallen);
        if (!retval)
@@ -2802,6 +2812,18 @@ struct sctp_chunk *sctp_make_asconf_update_ip(struct sctp_association *asoc,
 
                addr_buf += af->sockaddr_len;
        }
+
+       if (...) {
+               addr = asoc->asconf_addr_del_pending;
+               af = sctp_get_af_specific(addr->v4.sin_family);
+               addr_param_len = af->to_addr_param(addr, &addr_param);
+               param.param_hdr.type = SCTP_PARAM_DEL_IP;
+               param.param_hdr.length = htons(paramlen + addr_param_len);
+               param.crr_id = i;
+
+               sctp_addto_chunk(retval, paramlen, &param);
+               sctp_addto_chunk(retval, addr_param_len, &addr_param);
+       }


>  
> @@ -3224,6 +3254,11 @@ static void sctp_asconf_param_success(struct sctp_association *asoc,
>  	case SCTP_PARAM_DEL_IP:
>  		local_bh_disable();
>  		sctp_del_bind_addr(bp, &addr);
> +		if (asoc->asconf_addr_del_pending != NULL &&
> +		    sctp_cmp_addr_exact(asoc->asconf_addr_del_pending, &addr)) {
> +			kfree(asoc->asconf_addr_del_pending);
> +			asoc->asconf_addr_del_pending = NULL;
> +		}
>  		local_bh_enable();
>  		list_for_each_entry(transport, &asoc->peer.transport_addr_list,
>  				transports) {
> @@ -3381,6 +3416,9 @@ int sctp_process_asconf_ack(struct sctp_association *asoc,
>  		asconf_len -= length;
>  	}
>  
> +	if (no_err && asoc->src_out_of_asoc_ok)
> +		asoc->src_out_of_asoc_ok = 0;
> +
>  	/* Free the cached last sent asconf chunk. */
>  	list_del_init(&asconf->transmitted_list);
>  	sctp_chunk_free(asconf);
> diff --git a/net/sctp/socket.c b/net/sctp/socket.c
> index bfa4e8f..d9d9fc2 100644
> --- a/net/sctp/socket.c
> +++ b/net/sctp/socket.c
> @@ -583,10 +583,6 @@ static int sctp_send_asconf_add_ip(struct sock		*sk,
>  			goto out;
>  		}
>  
> -		retval = sctp_send_asconf(asoc, chunk);
> -		if (retval)
> -			goto out;
> -
>  		/* Add the new addresses to the bind address list with
>  		 * use_as_src set to 0.
>  		 */
> @@ -599,6 +595,23 @@ static int sctp_send_asconf_add_ip(struct sock		*sk,
>  						    SCTP_ADDR_NEW, GFP_ATOMIC);
>  			addr_buf += af->sockaddr_len;
>  		}
> +		if (asoc->src_out_of_asoc_ok) {
> +			struct sctp_transport *trans;
> +
> +			list_for_each_entry(trans,
> +			    &asoc->peer.transport_addr_list, transports) {
> +				/* Clear the source and route cache */
> +				dst_release(trans->dst);
> +				trans->cwnd = min(4*asoc->pathmtu, max_t(__u32,
> +				    2*asoc->pathmtu, 4380));
> +				trans->ssthresh = asoc->peer.i.a_rwnd;
> +				trans->rto = asoc->rto_initial;
> +				trans->rtt = trans->srtt = trans->rttvar = 0;
> +				sctp_transport_route(trans, NULL,
> +				    sctp_sk(asoc->base.sk));
> +			}
> +		}
> +		retval = sctp_send_asconf(asoc, chunk);
>  	}
>  
>  out:
> @@ -715,7 +728,9 @@ static int sctp_send_asconf_del_ip(struct sock		*sk,
>  	struct sctp_sockaddr_entry *saddr;
>  	int 			i;
>  	int 			retval = 0;
> +	int			stored = 0;
>  
> +	chunk = NULL;
>  	if (!sctp_addip_enable)
>  		return retval;
>  
> @@ -766,8 +781,32 @@ static int sctp_send_asconf_del_ip(struct sock		*sk,
>  		bp = &asoc->base.bind_addr;
>  		laddr = sctp_find_unmatch_addr(bp, (union sctp_addr *)addrs,
>  					       addrcnt, sp);
> -		if (!laddr)
> -			continue;
> +		if ((laddr == NULL) && (addrcnt == 1)) {
> +			if (asoc->asconf_addr_del_pending)
> +				continue;
> +			asoc->asconf_addr_del_pending =
> +			    kzalloc(sizeof(union sctp_addr), GFP_ATOMIC);
> +			asoc->asconf_addr_del_pending->sa.sa_family =
> +				    addrs->sa_family;
> +			asoc->asconf_addr_del_pending->v4.sin_port =
> +				    htons(bp->port);
> +			if (addrs->sa_family == AF_INET) {
> +				struct sockaddr_in *sin;
> +
> +				sin = (struct sockaddr_in *)addrs;
> +				asoc->asconf_addr_del_pending->v4.sin_addr.s_addr = sin->sin_addr.s_addr;
> +			} else if (addrs->sa_family == AF_INET6) {
> +				struct sockaddr_in6 *sin6;
> +
> +				sin6 = (struct sockaddr_in6 *)addrs;
> +				ipv6_addr_copy(&asoc->asconf_addr_del_pending->v6.sin6_addr, &sin6->sin6_addr);
> +			}
> +			SCTP_DEBUG_PRINTK_IPADDR("send_asconf_del_ip: keep the last address asoc: %p ",
> +			    " at %p\n", asoc, asoc->asconf_addr_del_pending,
> +			    asoc->asconf_addr_del_pending);
> +			stored = 1;
> +			goto skip_mkasconf;
> +		}
>  
>  		/* We do not need RCU protection throughout this loop
>  		 * because this is done under a socket lock from the
> @@ -780,6 +819,7 @@ static int sctp_send_asconf_del_ip(struct sock		*sk,
>  			goto out;
>  		}
>  
> +skip_mkasconf:
>  		/* Reset use_as_src flag for the addresses in the bind address
>  		 * list that are to be deleted.
>  		 */
> @@ -805,6 +845,9 @@ static int sctp_send_asconf_del_ip(struct sock		*sk,
>  					     sctp_sk(asoc->base.sk));
>  		}
>  
> +		if (stored)
> +			/* We don't need to transmit ASCONF */
> +			continue;
>  		retval = sctp_send_asconf(asoc, chunk);
>  	}
>  out:

^ permalink raw reply

* Re: [PATCH 2.6.38.4] mii: add support of pause frames in mii_get_an
From: Stephen Hemminger @ 2011-04-28  4:49 UTC (permalink / raw)
  To: artpol; +Cc: linux-kernel, davem, bhutchings, netdev
In-Reply-To: <1303962554.15395.1.camel@artpol-thinkpad>

On Thu, 28 Apr 2011 10:49:14 +0700
artpol <artpol84@gmail.com> wrote:

> Add support of pause frames advertise in mii_get_an. This provides all drivers 
> that use mii_ethtool_gset to represent their own and Link partner flow control
> abilities in ethtool.
> 
> Signed-off-by: Artem Polyakov <artpol84@gmail.com>
> 
> ---
> 
> --- linux-2.6.38.4/drivers/net/mii.c.orig	2011-04-28 08:46:13.000000000 +0700
> +++ linux-2.6.38.4/drivers/net/mii.c	2011-04-25 23:04:20.694981968 +0700
> @@ -49,6 +49,10 @@ static u32 mii_get_an(struct mii_if_info
>  		result |= ADVERTISED_100baseT_Half;
>  	if (advert & ADVERTISE_100FULL)
>  		result |= ADVERTISED_100baseT_Full;
> +	if (advert & ADVERTISE_PAUSE_CAP)
> +		result |= ADVERTISED_Pause;
> +	if (advert & ADVERTISE_PAUSE_ASYM)
> +		result |= ADVERTISED_Asym_Pause;
>  
>  	return result;
>  }

One common driver problem is that auto negotiation of pause
is really a separate operation from negotiation of speed.
It should be possible to force no flow-control but still negotiate
speed and vice-versa.  The ethtool api breaks this into two operations
but many drivers munge them together.

^ permalink raw reply

* [PATCHv4 6/7] tulip/de2104x: don't report different speeds depending on port type
From: David Decotigny @ 2011-04-28  4:32 UTC (permalink / raw)
  To: David S. Miller, Ben Hutchings, mirq-linux, Stanislaw Gruszka,
	Alexander Duyck <alexander.h.duyc
  Cc: David Decotigny
In-Reply-To: <1303965163-8198-1-git-send-email-decot@google.com>

Initial driver reported different speeds depending on the port being
used. This advertises the speed to be 10Mbps in any case, which is
what it actually is on the wire.

Signed-off-by: David Decotigny <decot@google.com>
---
 drivers/net/tulip/de2104x.c |   10 +++-------
 1 files changed, 3 insertions(+), 7 deletions(-)

diff --git a/drivers/net/tulip/de2104x.c b/drivers/net/tulip/de2104x.c
index ab78e1d..46d5a1b 100644
--- a/drivers/net/tulip/de2104x.c
+++ b/drivers/net/tulip/de2104x.c
@@ -1518,18 +1518,17 @@ static int __de_get_settings(struct de_private *de, struct ethtool_cmd *ecmd)
 	switch (de->media_type) {
 	case DE_MEDIA_AUI:
 		ecmd->port = PORT_AUI;
-		ethtool_cmd_speed_set(ecmd, 5);
 		break;
 	case DE_MEDIA_BNC:
 		ecmd->port = PORT_BNC;
-		ethtool_cmd_speed_set(ecmd, 2);
 		break;
 	default:
 		ecmd->port = PORT_TP;
-		ethtool_cmd_speed_set(ecmd, SPEED_10);
 		break;
 	}
 
+	ethtool_cmd_speed_set(ecmd, 10);
+
 	if (dr32(MacMode) & FullDuplex)
 		ecmd->duplex = DUPLEX_FULL;
 	else
@@ -1549,11 +1548,8 @@ static int __de_set_settings(struct de_private *de, struct ethtool_cmd *ecmd)
 {
 	u32 new_media;
 	unsigned int media_lock;
-	u32 speed = ethtool_cmd_speed(ecmd);
 
-	if (speed != SPEED_10 && speed != 5 && speed != 2)
-		return -EINVAL;
-	if (de->de21040 && speed == 2)
+	if (ethtool_cmd_speed(ecmd) != 10)
 		return -EINVAL;
 	if (ecmd->duplex != DUPLEX_HALF && ecmd->duplex != DUPLEX_FULL)
 		return -EINVAL;
-- 
1.7.3.1


^ permalink raw reply related

* [PATCHv4 7/7] net/igb/e1000/e1000e: more robust ethtool duplex/speed configuration
From: David Decotigny @ 2011-04-28  4:32 UTC (permalink / raw)
  To: David S. Miller, Ben Hutchings, mirq-linux, Stanislaw Gruszka,
	Alexander Duyck <alexander.h.duyc
  Cc: David Decotigny
In-Reply-To: <1303965163-8198-1-git-send-email-decot@google.com>

This makes sure that one cannot request a 99Mbps full-duplex and get a
100Mbps half-duplex configuration in return due to the way the
speed/duplex parameters are handled internally.

Tested: e1000 works
Signed-off-by: David Decotigny <decot@google.com>
---
 drivers/net/e1000/e1000.h         |    2 +-
 drivers/net/e1000/e1000_ethtool.c |    2 +-
 drivers/net/e1000/e1000_main.c    |   42 +++++++++++++++++++++---------------
 drivers/net/e1000e/ethtool.c      |   24 ++++++++++++++-------
 drivers/net/igb/igb.h             |    2 +-
 drivers/net/igb/igb_ethtool.c     |    2 +-
 drivers/net/igb/igb_main.c        |   23 +++++++++++++-------
 7 files changed, 59 insertions(+), 38 deletions(-)

diff --git a/drivers/net/e1000/e1000.h b/drivers/net/e1000/e1000.h
index a881dd0..b1b23dd 100644
--- a/drivers/net/e1000/e1000.h
+++ b/drivers/net/e1000/e1000.h
@@ -349,7 +349,7 @@ extern int e1000_up(struct e1000_adapter *adapter);
 extern void e1000_down(struct e1000_adapter *adapter);
 extern void e1000_reinit_locked(struct e1000_adapter *adapter);
 extern void e1000_reset(struct e1000_adapter *adapter);
-extern int e1000_set_spd_dplx(struct e1000_adapter *adapter, u16 spddplx);
+extern int e1000_set_spd_dplx(struct e1000_adapter *adapter, u32 spd, u8 dplx);
 extern int e1000_setup_all_rx_resources(struct e1000_adapter *adapter);
 extern int e1000_setup_all_tx_resources(struct e1000_adapter *adapter);
 extern void e1000_free_all_rx_resources(struct e1000_adapter *adapter);
diff --git a/drivers/net/e1000/e1000_ethtool.c b/drivers/net/e1000/e1000_ethtool.c
index 127fef4..4fa727c 100644
--- a/drivers/net/e1000/e1000_ethtool.c
+++ b/drivers/net/e1000/e1000_ethtool.c
@@ -199,7 +199,7 @@ static int e1000_set_settings(struct net_device *netdev,
 		ecmd->advertising = hw->autoneg_advertised;
 	} else {
 		u32 speed = ethtool_cmd_speed(ecmd);
-		if (e1000_set_spd_dplx(adapter, speed + ecmd->duplex)) {
+		if (e1000_set_spd_dplx(adapter, speed, ecmd->duplex)) {
 			clear_bit(__E1000_RESETTING, &adapter->flags);
 			return -EINVAL;
 		}
diff --git a/drivers/net/e1000/e1000_main.c b/drivers/net/e1000/e1000_main.c
index 477e066..c18cb8e 100644
--- a/drivers/net/e1000/e1000_main.c
+++ b/drivers/net/e1000/e1000_main.c
@@ -96,7 +96,6 @@ int e1000_up(struct e1000_adapter *adapter);
 void e1000_down(struct e1000_adapter *adapter);
 void e1000_reinit_locked(struct e1000_adapter *adapter);
 void e1000_reset(struct e1000_adapter *adapter);
-int e1000_set_spd_dplx(struct e1000_adapter *adapter, u16 spddplx);
 int e1000_setup_all_tx_resources(struct e1000_adapter *adapter);
 int e1000_setup_all_rx_resources(struct e1000_adapter *adapter);
 void e1000_free_all_tx_resources(struct e1000_adapter *adapter);
@@ -4385,7 +4384,6 @@ static int e1000_mii_ioctl(struct net_device *netdev, struct ifreq *ifr,
 	struct mii_ioctl_data *data = if_mii(ifr);
 	int retval;
 	u16 mii_reg;
-	u16 spddplx;
 	unsigned long flags;
 
 	if (hw->media_type != e1000_media_type_copper)
@@ -4424,17 +4422,18 @@ static int e1000_mii_ioctl(struct net_device *netdev, struct ifreq *ifr,
 					hw->autoneg = 1;
 					hw->autoneg_advertised = 0x2F;
 				} else {
+					u32 speed;
 					if (mii_reg & 0x40)
-						spddplx = SPEED_1000;
+						speed = SPEED_1000;
 					else if (mii_reg & 0x2000)
-						spddplx = SPEED_100;
+						speed = SPEED_100;
 					else
-						spddplx = SPEED_10;
-					spddplx += (mii_reg & 0x100)
-						   ? DUPLEX_FULL :
-						   DUPLEX_HALF;
-					retval = e1000_set_spd_dplx(adapter,
-								    spddplx);
+						speed = SPEED_10;
+					retval = e1000_set_spd_dplx(
+						adapter, speed,
+						((mii_reg & 0x100)
+						 ? DUPLEX_FULL :
+						 DUPLEX_HALF));
 					if (retval)
 						return retval;
 				}
@@ -4596,20 +4595,24 @@ static void e1000_restore_vlan(struct e1000_adapter *adapter)
 	}
 }
 
-int e1000_set_spd_dplx(struct e1000_adapter *adapter, u16 spddplx)
+int e1000_set_spd_dplx(struct e1000_adapter *adapter, u32 spd, u8 dplx)
 {
 	struct e1000_hw *hw = &adapter->hw;
 
 	hw->autoneg = 0;
 
+	/* Make sure dplx is at most 1 bit and lsb of speed is not set
+	 * for the switch() below to work */
+	if ((spd & 1) || (dplx & ~1))
+		goto err_inval;
+
 	/* Fiber NICs only allow 1000 gbps Full duplex */
 	if ((hw->media_type == e1000_media_type_fiber) &&
-		spddplx != (SPEED_1000 + DUPLEX_FULL)) {
-		e_err(probe, "Unsupported Speed/Duplex configuration\n");
-		return -EINVAL;
-	}
+	    spd != SPEED_1000 &&
+	    dplx != DUPLEX_FULL)
+		goto err_inval;
 
-	switch (spddplx) {
+	switch (spd + dplx) {
 	case SPEED_10 + DUPLEX_HALF:
 		hw->forced_speed_duplex = e1000_10_half;
 		break;
@@ -4628,10 +4631,13 @@ int e1000_set_spd_dplx(struct e1000_adapter *adapter, u16 spddplx)
 		break;
 	case SPEED_1000 + DUPLEX_HALF: /* not supported */
 	default:
-		e_err(probe, "Unsupported Speed/Duplex configuration\n");
-		return -EINVAL;
+		goto err_inval;
 	}
 	return 0;
+
+err_inval:
+	e_err(probe, "Unsupported Speed/Duplex configuration\n");
+	return -EINVAL;
 }
 
 static int __e1000_shutdown(struct pci_dev *pdev, bool *enable_wake)
diff --git a/drivers/net/e1000e/ethtool.c b/drivers/net/e1000e/ethtool.c
index 12f1ee2..859d0d3 100644
--- a/drivers/net/e1000e/ethtool.c
+++ b/drivers/net/e1000e/ethtool.c
@@ -200,20 +200,25 @@ static int e1000_get_settings(struct net_device *netdev,
 	return 0;
 }
 
-static int e1000_set_spd_dplx(struct e1000_adapter *adapter, u16 spddplx)
+static int e1000_set_spd_dplx(struct e1000_adapter *adapter, u32 spd, u8 dplx)
 {
 	struct e1000_mac_info *mac = &adapter->hw.mac;
 
 	mac->autoneg = 0;
 
+	/* Make sure dplx is at most 1 bit and lsb of speed is not set
+	 * for the switch() below to work */
+	if ((spd & 1) || (dplx & ~1))
+		goto err_inval;
+
 	/* Fiber NICs only allow 1000 gbps Full duplex */
 	if ((adapter->hw.phy.media_type == e1000_media_type_fiber) &&
-		spddplx != (SPEED_1000 + DUPLEX_FULL)) {
-		e_err("Unsupported Speed/Duplex configuration\n");
-		return -EINVAL;
+	    spd != SPEED_1000 &&
+	    dplx != DUPLEX_FULL) {
+		goto err_inval;
 	}
 
-	switch (spddplx) {
+	switch (spd + dplx) {
 	case SPEED_10 + DUPLEX_HALF:
 		mac->forced_speed_duplex = ADVERTISE_10_HALF;
 		break;
@@ -232,10 +237,13 @@ static int e1000_set_spd_dplx(struct e1000_adapter *adapter, u16 spddplx)
 		break;
 	case SPEED_1000 + DUPLEX_HALF: /* not supported */
 	default:
-		e_err("Unsupported Speed/Duplex configuration\n");
-		return -EINVAL;
+		goto err_inval;
 	}
 	return 0;
+
+err_inval:
+	e_err("Unsupported Speed/Duplex configuration\n");
+	return -EINVAL;
 }
 
 static int e1000_set_settings(struct net_device *netdev,
@@ -272,7 +280,7 @@ static int e1000_set_settings(struct net_device *netdev,
 			hw->fc.requested_mode = e1000_fc_default;
 	} else {
 		u32 speed = ethtool_cmd_speed(ecmd);
-		if (e1000_set_spd_dplx(adapter, speed + ecmd->duplex)) {
+		if (e1000_set_spd_dplx(adapter, speed, ecmd->duplex)) {
 			clear_bit(__E1000_RESETTING, &adapter->state);
 			return -EINVAL;
 		}
diff --git a/drivers/net/igb/igb.h b/drivers/net/igb/igb.h
index 1c687e2..f4fa4b1 100644
--- a/drivers/net/igb/igb.h
+++ b/drivers/net/igb/igb.h
@@ -360,7 +360,7 @@ extern int igb_up(struct igb_adapter *);
 extern void igb_down(struct igb_adapter *);
 extern void igb_reinit_locked(struct igb_adapter *);
 extern void igb_reset(struct igb_adapter *);
-extern int igb_set_spd_dplx(struct igb_adapter *, u16);
+extern int igb_set_spd_dplx(struct igb_adapter *, u32, u8);
 extern int igb_setup_tx_resources(struct igb_ring *);
 extern int igb_setup_rx_resources(struct igb_ring *);
 extern void igb_free_tx_resources(struct igb_ring *);
diff --git a/drivers/net/igb/igb_ethtool.c b/drivers/net/igb/igb_ethtool.c
index 023aa9b..6e29634 100644
--- a/drivers/net/igb/igb_ethtool.c
+++ b/drivers/net/igb/igb_ethtool.c
@@ -224,7 +224,7 @@ static int igb_set_settings(struct net_device *netdev, struct ethtool_cmd *ecmd)
 			hw->fc.requested_mode = e1000_fc_default;
 	} else {
 		u32 speed = ethtool_cmd_speed(ecmd);
-		if (igb_set_spd_dplx(adapter, speed + ecmd->duplex)) {
+		if (igb_set_spd_dplx(adapter, speed, ecmd->duplex)) {
 			clear_bit(__IGB_RESETTING, &adapter->state);
 			return -EINVAL;
 		}
diff --git a/drivers/net/igb/igb_main.c b/drivers/net/igb/igb_main.c
index cdfd572..ce7838e 100644
--- a/drivers/net/igb/igb_main.c
+++ b/drivers/net/igb/igb_main.c
@@ -6349,21 +6349,25 @@ static void igb_restore_vlan(struct igb_adapter *adapter)
 	}
 }
 
-int igb_set_spd_dplx(struct igb_adapter *adapter, u16 spddplx)
+int igb_set_spd_dplx(struct igb_adapter *adapter, u32 spd, u8 dplx)
 {
 	struct pci_dev *pdev = adapter->pdev;
 	struct e1000_mac_info *mac = &adapter->hw.mac;
 
 	mac->autoneg = 0;
 
+	/* Make sure dplx is at most 1 bit and lsb of speed is not set
+	 * for the switch() below to work */
+	if ((spd & 1) || (dplx & ~1))
+		goto err_inval;
+
 	/* Fiber NIC's only allow 1000 Gbps Full duplex */
 	if ((adapter->hw.phy.media_type == e1000_media_type_internal_serdes) &&
-		spddplx != (SPEED_1000 + DUPLEX_FULL)) {
-		dev_err(&pdev->dev, "Unsupported Speed/Duplex configuration\n");
-		return -EINVAL;
-	}
+	    spd != SPEED_1000 &&
+	    dplx != DUPLEX_FULL)
+		goto err_inval;
 
-	switch (spddplx) {
+	switch (spd + dplx) {
 	case SPEED_10 + DUPLEX_HALF:
 		mac->forced_speed_duplex = ADVERTISE_10_HALF;
 		break;
@@ -6382,10 +6386,13 @@ int igb_set_spd_dplx(struct igb_adapter *adapter, u16 spddplx)
 		break;
 	case SPEED_1000 + DUPLEX_HALF: /* not supported */
 	default:
-		dev_err(&pdev->dev, "Unsupported Speed/Duplex configuration\n");
-		return -EINVAL;
+		goto err_inval;
 	}
 	return 0;
+
+err_inval:
+	dev_err(&pdev->dev, "Unsupported Speed/Duplex configuration\n");
+	return -EINVAL;
 }
 
 static int __igb_shutdown(struct pci_dev *pdev, bool *enable_wake)
-- 
1.7.3.1


^ permalink raw reply related

* [PATCHv4 2/7] ethtool: Call ethtool's get/set_settings callbacks with cleaned data
From: David Decotigny @ 2011-04-28  4:32 UTC (permalink / raw)
  To: David S. Miller, Ben Hutchings, mirq-linux, Stanislaw Gruszka,
	Alexander Duyck <alexander.h.duyc
  Cc: David Decotigny
In-Reply-To: <1303965163-8198-1-git-send-email-decot@google.com>

This makes sure that when a driver calls the ethtool's
get/set_settings() callback of another driver, the data passed to it
is clean. This guarantees that speed_hi will be zeroed correctly if
the called callback doesn't explicitely set it: we are sure we don't
get a corrupted speed from the underlying driver. We also take care of
setting the cmd field appropriately (ETHTOOL_GSET/SSET).

This applies to dev_ethtool_get_settings(), which now makes sure it
sets up that ethtool command parameter correctly before passing it to
drivers. This also means that whoever calls dev_ethtool_get_settings()
does not have to clean the ethtool command parameter. This function
also becomes an exported symbol instead of an inline.

All drivers visible to make allyesconfig under x86_64 have been
updated.

Signed-off-by: David Decotigny <decot@google.com>
---
 arch/mips/txx9/generic/setup_tx4939.c |   21 ++++++++-------------
 drivers/net/e100.c                    |    2 +-
 drivers/net/mdio.c                    |    3 +++
 drivers/net/mii.c                     |    3 +++
 drivers/net/pch_gbe/pch_gbe_main.c    |    6 +++---
 drivers/net/pch_gbe/pch_gbe_phy.c     |    2 +-
 drivers/net/pcnet32.c                 |   16 ++++++++--------
 drivers/net/sfc/mdio_10g.c            |    4 ++--
 drivers/net/stmmac/stmmac_ethtool.c   |    5 ++---
 drivers/net/usb/asix.c                |   28 +++++++++++++++-------------
 drivers/net/usb/dm9601.c              |    6 +++---
 drivers/net/usb/smsc75xx.c            |    7 ++++---
 drivers/net/usb/smsc95xx.c            |    7 ++++---
 drivers/scsi/bnx2fc/bnx2fc_fcoe.c     |   11 +++++++----
 drivers/scsi/fcoe/fcoe.c              |   11 +++++++----
 include/linux/ethtool.h               |    4 +++-
 include/linux/netdevice.h             |    9 ++-------
 include/rdma/ib_addr.h                |   13 +++++++------
 net/core/dev.c                        |   24 ++++++++++++++++++++++++
 net/core/net-sysfs.c                  |   24 ++++++++++--------------
 20 files changed, 117 insertions(+), 89 deletions(-)

diff --git a/arch/mips/txx9/generic/setup_tx4939.c b/arch/mips/txx9/generic/setup_tx4939.c
index 3dc19f4..e9f95dc 100644
--- a/arch/mips/txx9/generic/setup_tx4939.c
+++ b/arch/mips/txx9/generic/setup_tx4939.c
@@ -318,19 +318,15 @@ void __init tx4939_sio_init(unsigned int sclk, unsigned int cts_mask)
 }
 
 #if defined(CONFIG_TC35815) || defined(CONFIG_TC35815_MODULE)
-static int tx4939_get_eth_speed(struct net_device *dev)
+static u32 tx4939_get_eth_speed(struct net_device *dev)
 {
-	struct ethtool_cmd cmd = { ETHTOOL_GSET };
-	int speed = 100;	/* default 100Mbps */
-	int err;
-	if (!dev->ethtool_ops || !dev->ethtool_ops->get_settings)
-		return speed;
-	err = dev->ethtool_ops->get_settings(dev, &cmd);
-	if (err < 0)
-		return speed;
-	speed = cmd.speed == SPEED_100 ? 100 : 10;
-	return speed;
+	struct ethtool_cmd cmd;
+	if (dev_ethtool_get_settings(dev, &cmd))
+		return 100;	/* default 100Mbps */
+
+	return ethtool_cmd_speed(&cmd);
 }
+
 static int tx4939_netdev_event(struct notifier_block *this,
 			       unsigned long event,
 			       void *ptr)
@@ -343,8 +339,7 @@ static int tx4939_netdev_event(struct notifier_block *this,
 		else if (dev->irq == TXX9_IRQ_BASE + TX4939_IR_ETH(1))
 			bit = TX4939_PCFG_SPEED1;
 		if (bit) {
-			int speed = tx4939_get_eth_speed(dev);
-			if (speed == 100)
+			if (tx4939_get_eth_speed(dev) == 100)
 				txx9_set64(&tx4939_ccfgptr->pcfg, bit);
 			else
 				txx9_clear64(&tx4939_ccfgptr->pcfg, bit);
diff --git a/drivers/net/e100.c b/drivers/net/e100.c
index b0aa9e6..66ba596 100644
--- a/drivers/net/e100.c
+++ b/drivers/net/e100.c
@@ -1668,7 +1668,7 @@ static void e100_adjust_adaptive_ifs(struct nic *nic, int speed, int duplex)
 static void e100_watchdog(unsigned long data)
 {
 	struct nic *nic = (struct nic *)data;
-	struct ethtool_cmd cmd;
+	struct ethtool_cmd cmd = { .cmd = ETHTOOL_GSET };
 
 	netif_printk(nic, timer, KERN_DEBUG, nic->netdev,
 		     "right now = %ld\n", jiffies);
diff --git a/drivers/net/mdio.c b/drivers/net/mdio.c
index e85bf04..f2d10ab 100644
--- a/drivers/net/mdio.c
+++ b/drivers/net/mdio.c
@@ -176,6 +176,9 @@ static u32 mdio45_get_an(const struct mdio_if_info *mdio, u16 addr)
  * @npage_adv: Modes currently advertised on next pages
  * @npage_lpa: Modes advertised by link partner on next pages
  *
+ * The @ecmd parameter is expected to have been cleared before calling
+ * mdio45_ethtool_gset_npage().
+ *
  * Since the CSRs for auto-negotiation using next pages are not fully
  * standardised, this function does not attempt to decode them.  The
  * caller must pass them in.
diff --git a/drivers/net/mii.c b/drivers/net/mii.c
index 0a6c6a2..05acca7 100644
--- a/drivers/net/mii.c
+++ b/drivers/net/mii.c
@@ -58,6 +58,9 @@ static u32 mii_get_an(struct mii_if_info *mii, u16 addr)
  * @mii: MII interface
  * @ecmd: requested ethtool_cmd
  *
+ * The @ecmd parameter is expected to have been cleared before calling
+ * mii_ethtool_gset().
+ *
  * Returns 0 for success, negative on error.
  */
 int mii_ethtool_gset(struct mii_if_info *mii, struct ethtool_cmd *ecmd)
diff --git a/drivers/net/pch_gbe/pch_gbe_main.c b/drivers/net/pch_gbe/pch_gbe_main.c
index 4cc9872..f3e4b0a 100644
--- a/drivers/net/pch_gbe/pch_gbe_main.c
+++ b/drivers/net/pch_gbe/pch_gbe_main.c
@@ -888,12 +888,12 @@ static void pch_gbe_watchdog(unsigned long data)
 	struct pch_gbe_adapter *adapter = (struct pch_gbe_adapter *)data;
 	struct net_device *netdev = adapter->netdev;
 	struct pch_gbe_hw *hw = &adapter->hw;
-	struct ethtool_cmd cmd;
 
 	pr_debug("right now = %ld\n", jiffies);
 
 	pch_gbe_update_stats(adapter);
 	if ((mii_link_ok(&adapter->mii)) && (!netif_carrier_ok(netdev))) {
+		struct ethtool_cmd cmd = { .cmd = ETHTOOL_GSET };
 		netdev->tx_queue_len = adapter->tx_queue_len;
 		/* mii library handles link maintenance tasks */
 		if (mii_ethtool_gset(&adapter->mii, &cmd)) {
@@ -903,7 +903,7 @@ static void pch_gbe_watchdog(unsigned long data)
 						PCH_GBE_WATCHDOG_PERIOD));
 			return;
 		}
-		hw->mac.link_speed = cmd.speed;
+		hw->mac.link_speed = ethtool_cmd_speed(&cmd);
 		hw->mac.link_duplex = cmd.duplex;
 		/* Set the RGMII control. */
 		pch_gbe_set_rgmii_ctrl(adapter, hw->mac.link_speed,
@@ -913,7 +913,7 @@ static void pch_gbe_watchdog(unsigned long data)
 				 hw->mac.link_duplex);
 		netdev_dbg(netdev,
 			   "Link is Up %d Mbps %s-Duplex\n",
-			   cmd.speed,
+			   hw->mac.link_speed,
 			   cmd.duplex == DUPLEX_FULL ? "Full" : "Half");
 		netif_carrier_on(netdev);
 		netif_wake_queue(netdev);
diff --git a/drivers/net/pch_gbe/pch_gbe_phy.c b/drivers/net/pch_gbe/pch_gbe_phy.c
index 923a687..9a8207f 100644
--- a/drivers/net/pch_gbe/pch_gbe_phy.c
+++ b/drivers/net/pch_gbe/pch_gbe_phy.c
@@ -247,7 +247,7 @@ inline void pch_gbe_phy_set_rgmii(struct pch_gbe_hw *hw)
 void pch_gbe_phy_init_setting(struct pch_gbe_hw *hw)
 {
 	struct pch_gbe_adapter *adapter;
-	struct ethtool_cmd     cmd;
+	struct ethtool_cmd     cmd = { .cmd = ETHTOOL_GSET };
 	int ret;
 	u16 mii_reg;
 
diff --git a/drivers/net/pcnet32.c b/drivers/net/pcnet32.c
index 0a1efba..b48aba9 100644
--- a/drivers/net/pcnet32.c
+++ b/drivers/net/pcnet32.c
@@ -2099,7 +2099,7 @@ static int pcnet32_open(struct net_device *dev)
 		int first_phy = -1;
 		u16 bmcr;
 		u32 bcr9;
-		struct ethtool_cmd ecmd;
+		struct ethtool_cmd ecmd = { .cmd = ETHTOOL_GSET };
 
 		/*
 		 * There is really no good other way to handle multiple PHYs
@@ -2115,9 +2115,9 @@ static int pcnet32_open(struct net_device *dev)
 			ecmd.port = PORT_MII;
 			ecmd.transceiver = XCVR_INTERNAL;
 			ecmd.autoneg = AUTONEG_DISABLE;
-			ecmd.speed =
-			    lp->
-			    options & PCNET32_PORT_100 ? SPEED_100 : SPEED_10;
+			ethtool_cmd_speed_set(&ecmd,
+					      (lp->options & PCNET32_PORT_100) ?
+					      SPEED_100 : SPEED_10);
 			bcr9 = lp->a.read_bcr(ioaddr, 9);
 
 			if (lp->options & PCNET32_PORT_FD) {
@@ -2763,11 +2763,11 @@ static void pcnet32_check_media(struct net_device *dev, int verbose)
 		netif_carrier_on(dev);
 		if (lp->mii) {
 			if (netif_msg_link(lp)) {
-				struct ethtool_cmd ecmd;
+				struct ethtool_cmd ecmd = {
+					.cmd = ETHTOOL_GSET };
 				mii_ethtool_gset(&lp->mii_if, &ecmd);
-				netdev_info(dev, "link up, %sMbps, %s-duplex\n",
-					    (ecmd.speed == SPEED_100)
-					    ? "100" : "10",
+				netdev_info(dev, "link up, %uMbps, %s-duplex\n",
+					    ethtool_cmd_speed(&ecmd),
 					    (ecmd.duplex == DUPLEX_FULL)
 					    ? "full" : "half");
 			}
diff --git a/drivers/net/sfc/mdio_10g.c b/drivers/net/sfc/mdio_10g.c
index 19e68c2..7115914 100644
--- a/drivers/net/sfc/mdio_10g.c
+++ b/drivers/net/sfc/mdio_10g.c
@@ -232,12 +232,12 @@ void efx_mdio_set_mmds_lpower(struct efx_nic *efx,
  */
 int efx_mdio_set_settings(struct efx_nic *efx, struct ethtool_cmd *ecmd)
 {
-	struct ethtool_cmd prev;
+	struct ethtool_cmd prev = { .cmd = ETHTOOL_GSET };
 
 	efx->phy_op->get_settings(efx, &prev);
 
 	if (ecmd->advertising == prev.advertising &&
-	    ecmd->speed == prev.speed &&
+	    ethtool_cmd_speed(ecmd) == ethtool_cmd_speed(&prev) &&
 	    ecmd->duplex == prev.duplex &&
 	    ecmd->port == prev.port &&
 	    ecmd->autoneg == prev.autoneg)
diff --git a/drivers/net/stmmac/stmmac_ethtool.c b/drivers/net/stmmac/stmmac_ethtool.c
index 0e61ac8..6f5aaeb 100644
--- a/drivers/net/stmmac/stmmac_ethtool.c
+++ b/drivers/net/stmmac/stmmac_ethtool.c
@@ -237,13 +237,12 @@ stmmac_set_pauseparam(struct net_device *netdev,
 
 	if (phy->autoneg) {
 		if (netif_running(netdev)) {
-			struct ethtool_cmd cmd;
+			struct ethtool_cmd cmd = { .cmd = ETHTOOL_SSET };
 			/* auto-negotiation automatically restarted */
-			cmd.cmd = ETHTOOL_NWAY_RST;
 			cmd.supported = phy->supported;
 			cmd.advertising = phy->advertising;
 			cmd.autoneg = phy->autoneg;
-			cmd.speed = phy->speed;
+			ethtool_cmd_speed_set(&cmd, phy->speed);
 			cmd.duplex = phy->duplex;
 			cmd.phy_address = phy->addr;
 			ret = phy_ethtool_sset(phy, &cmd);
diff --git a/drivers/net/usb/asix.c b/drivers/net/usb/asix.c
index 6140b56..6998aa6 100644
--- a/drivers/net/usb/asix.c
+++ b/drivers/net/usb/asix.c
@@ -847,7 +847,7 @@ static void ax88172_set_multicast(struct net_device *net)
 static int ax88172_link_reset(struct usbnet *dev)
 {
 	u8 mode;
-	struct ethtool_cmd ecmd;
+	struct ethtool_cmd ecmd = { .cmd = ETHTOOL_GSET };
 
 	mii_check_media(&dev->mii, 1, 1);
 	mii_ethtool_gset(&dev->mii, &ecmd);
@@ -856,8 +856,8 @@ static int ax88172_link_reset(struct usbnet *dev)
 	if (ecmd.duplex != DUPLEX_FULL)
 		mode |= ~AX88172_MEDIUM_FD;
 
-	netdev_dbg(dev->net, "ax88172_link_reset() speed: %d duplex: %d setting mode to 0x%04x\n",
-		   ecmd.speed, ecmd.duplex, mode);
+	netdev_dbg(dev->net, "ax88172_link_reset() speed: %u duplex: %d setting mode to 0x%04x\n",
+		   ethtool_cmd_speed(&ecmd), ecmd.duplex, mode);
 
 	asix_write_medium_mode(dev, mode);
 
@@ -947,20 +947,20 @@ static const struct ethtool_ops ax88772_ethtool_ops = {
 static int ax88772_link_reset(struct usbnet *dev)
 {
 	u16 mode;
-	struct ethtool_cmd ecmd;
+	struct ethtool_cmd ecmd = { .cmd = ETHTOOL_GSET };
 
 	mii_check_media(&dev->mii, 1, 1);
 	mii_ethtool_gset(&dev->mii, &ecmd);
 	mode = AX88772_MEDIUM_DEFAULT;
 
-	if (ecmd.speed != SPEED_100)
+	if (ethtool_cmd_speed(&ecmd) != SPEED_100)
 		mode &= ~AX_MEDIUM_PS;
 
 	if (ecmd.duplex != DUPLEX_FULL)
 		mode &= ~AX_MEDIUM_FD;
 
-	netdev_dbg(dev->net, "ax88772_link_reset() speed: %d duplex: %d setting mode to 0x%04x\n",
-		   ecmd.speed, ecmd.duplex, mode);
+	netdev_dbg(dev->net, "ax88772_link_reset() speed: %u duplex: %d setting mode to 0x%04x\n",
+		   ethtool_cmd_speed(&ecmd), ecmd.duplex, mode);
 
 	asix_write_medium_mode(dev, mode);
 
@@ -1173,18 +1173,20 @@ static int marvell_led_status(struct usbnet *dev, u16 speed)
 static int ax88178_link_reset(struct usbnet *dev)
 {
 	u16 mode;
-	struct ethtool_cmd ecmd;
+	struct ethtool_cmd ecmd = { .cmd = ETHTOOL_GSET };
 	struct asix_data *data = (struct asix_data *)&dev->data;
+	u32 speed;
 
 	netdev_dbg(dev->net, "ax88178_link_reset()\n");
 
 	mii_check_media(&dev->mii, 1, 1);
 	mii_ethtool_gset(&dev->mii, &ecmd);
 	mode = AX88178_MEDIUM_DEFAULT;
+	speed = ethtool_cmd_speed(&ecmd);
 
-	if (ecmd.speed == SPEED_1000)
+	if (speed == SPEED_1000)
 		mode |= AX_MEDIUM_GM;
-	else if (ecmd.speed == SPEED_100)
+	else if (speed == SPEED_100)
 		mode |= AX_MEDIUM_PS;
 	else
 		mode &= ~(AX_MEDIUM_PS | AX_MEDIUM_GM);
@@ -1196,13 +1198,13 @@ static int ax88178_link_reset(struct usbnet *dev)
 	else
 		mode &= ~AX_MEDIUM_FD;
 
-	netdev_dbg(dev->net, "ax88178_link_reset() speed: %d duplex: %d setting mode to 0x%04x\n",
-		   ecmd.speed, ecmd.duplex, mode);
+	netdev_dbg(dev->net, "ax88178_link_reset() speed: %u duplex: %d setting mode to 0x%04x\n",
+		   speed, ecmd.duplex, mode);
 
 	asix_write_medium_mode(dev, mode);
 
 	if (data->phymode == PHY_MODE_MARVELL && data->ledmode)
-		marvell_led_status(dev, ecmd.speed);
+		marvell_led_status(dev, speed);
 
 	return 0;
 }
diff --git a/drivers/net/usb/dm9601.c b/drivers/net/usb/dm9601.c
index 5002f5b..1d93133 100644
--- a/drivers/net/usb/dm9601.c
+++ b/drivers/net/usb/dm9601.c
@@ -599,13 +599,13 @@ static void dm9601_status(struct usbnet *dev, struct urb *urb)
 
 static int dm9601_link_reset(struct usbnet *dev)
 {
-	struct ethtool_cmd ecmd;
+	struct ethtool_cmd ecmd = { .cmd = ETHTOOL_GSET };
 
 	mii_check_media(&dev->mii, 1, 1);
 	mii_ethtool_gset(&dev->mii, &ecmd);
 
-	netdev_dbg(dev->net, "link_reset() speed: %d duplex: %d\n",
-		   ecmd.speed, ecmd.duplex);
+	netdev_dbg(dev->net, "link_reset() speed: %u duplex: %d\n",
+		   ethtool_cmd_speed(&ecmd), ecmd.duplex);
 
 	return 0;
 }
diff --git a/drivers/net/usb/smsc75xx.c b/drivers/net/usb/smsc75xx.c
index 860a20c..15b3d68 100644
--- a/drivers/net/usb/smsc75xx.c
+++ b/drivers/net/usb/smsc75xx.c
@@ -503,7 +503,7 @@ static int smsc75xx_update_flowcontrol(struct usbnet *dev, u8 duplex,
 static int smsc75xx_link_reset(struct usbnet *dev)
 {
 	struct mii_if_info *mii = &dev->mii;
-	struct ethtool_cmd ecmd;
+	struct ethtool_cmd ecmd = { .cmd = ETHTOOL_GSET };
 	u16 lcladv, rmtadv;
 	int ret;
 
@@ -519,8 +519,9 @@ static int smsc75xx_link_reset(struct usbnet *dev)
 	lcladv = smsc75xx_mdio_read(dev->net, mii->phy_id, MII_ADVERTISE);
 	rmtadv = smsc75xx_mdio_read(dev->net, mii->phy_id, MII_LPA);
 
-	netif_dbg(dev, link, dev->net, "speed: %d duplex: %d lcladv: %04x"
-		" rmtadv: %04x", ecmd.speed, ecmd.duplex, lcladv, rmtadv);
+	netif_dbg(dev, link, dev->net, "speed: %u duplex: %d lcladv: %04x"
+		  " rmtadv: %04x", ethtool_cmd_speed(&ecmd),
+		  ecmd.duplex, lcladv, rmtadv);
 
 	return smsc75xx_update_flowcontrol(dev, ecmd.duplex, lcladv, rmtadv);
 }
diff --git a/drivers/net/usb/smsc95xx.c b/drivers/net/usb/smsc95xx.c
index 24f4b37..b374a99 100644
--- a/drivers/net/usb/smsc95xx.c
+++ b/drivers/net/usb/smsc95xx.c
@@ -457,7 +457,7 @@ static int smsc95xx_link_reset(struct usbnet *dev)
 {
 	struct smsc95xx_priv *pdata = (struct smsc95xx_priv *)(dev->data[0]);
 	struct mii_if_info *mii = &dev->mii;
-	struct ethtool_cmd ecmd;
+	struct ethtool_cmd ecmd = { .cmd = ETHTOOL_GSET };
 	unsigned long flags;
 	u16 lcladv, rmtadv;
 	u32 intdata;
@@ -472,8 +472,9 @@ static int smsc95xx_link_reset(struct usbnet *dev)
 	lcladv = smsc95xx_mdio_read(dev->net, mii->phy_id, MII_ADVERTISE);
 	rmtadv = smsc95xx_mdio_read(dev->net, mii->phy_id, MII_LPA);
 
-	netif_dbg(dev, link, dev->net, "speed: %d duplex: %d lcladv: %04x rmtadv: %04x\n",
-		  ecmd.speed, ecmd.duplex, lcladv, rmtadv);
+	netif_dbg(dev, link, dev->net,
+		  "speed: %u duplex: %d lcladv: %04x rmtadv: %04x\n",
+		  ethtool_cmd_speed(&ecmd), ecmd.duplex, lcladv, rmtadv);
 
 	spin_lock_irqsave(&pdata->mac_cr_lock, flags);
 	if (ecmd.duplex != DUPLEX_FULL) {
diff --git a/drivers/scsi/bnx2fc/bnx2fc_fcoe.c b/drivers/scsi/bnx2fc/bnx2fc_fcoe.c
index e2e6475..cd05019 100644
--- a/drivers/scsi/bnx2fc/bnx2fc_fcoe.c
+++ b/drivers/scsi/bnx2fc/bnx2fc_fcoe.c
@@ -664,7 +664,7 @@ static void bnx2fc_link_speed_update(struct fc_lport *lport)
 	struct fcoe_port *port = lport_priv(lport);
 	struct bnx2fc_hba *hba = port->priv;
 	struct net_device *netdev = hba->netdev;
-	struct ethtool_cmd ecmd = { ETHTOOL_GSET };
+	struct ethtool_cmd ecmd;
 
 	if (!dev_ethtool_get_settings(netdev, &ecmd)) {
 		lport->link_supported_speeds &=
@@ -675,12 +675,15 @@ static void bnx2fc_link_speed_update(struct fc_lport *lport)
 		if (ecmd.supported & SUPPORTED_10000baseT_Full)
 			lport->link_supported_speeds |= FC_PORTSPEED_10GBIT;
 
-		if (ecmd.speed == SPEED_1000)
+		switch (ethtool_cmd_speed(&ecmd)) {
+		case SPEED_1000:
 			lport->link_speed = FC_PORTSPEED_1GBIT;
-		if (ecmd.speed == SPEED_10000)
+			break;
+		case SPEED_10000:
 			lport->link_speed = FC_PORTSPEED_10GBIT;
+			break;
+		}
 	}
-	return;
 }
 static int bnx2fc_link_ok(struct fc_lport *lport)
 {
diff --git a/drivers/scsi/fcoe/fcoe.c b/drivers/scsi/fcoe/fcoe.c
index bde6ee5..04f346b 100644
--- a/drivers/scsi/fcoe/fcoe.c
+++ b/drivers/scsi/fcoe/fcoe.c
@@ -2026,7 +2026,7 @@ out_nodev:
 int fcoe_link_speed_update(struct fc_lport *lport)
 {
 	struct net_device *netdev = fcoe_netdev(lport);
-	struct ethtool_cmd ecmd = { ETHTOOL_GSET };
+	struct ethtool_cmd ecmd;
 
 	if (!dev_ethtool_get_settings(netdev, &ecmd)) {
 		lport->link_supported_speeds &=
@@ -2037,11 +2037,14 @@ int fcoe_link_speed_update(struct fc_lport *lport)
 		if (ecmd.supported & SUPPORTED_10000baseT_Full)
 			lport->link_supported_speeds |=
 				FC_PORTSPEED_10GBIT;
-		if (ecmd.speed == SPEED_1000)
+		switch (ethtool_cmd_speed(&ecmd)) {
+		case SPEED_1000:
 			lport->link_speed = FC_PORTSPEED_1GBIT;
-		if (ecmd.speed == SPEED_10000)
+			break;
+		case SPEED_10000:
 			lport->link_speed = FC_PORTSPEED_10GBIT;
-
+			break;
+		}
 		return 0;
 	}
 	return -1;
diff --git a/include/linux/ethtool.h b/include/linux/ethtool.h
index 7e6e0a8..4194a20 100644
--- a/include/linux/ethtool.h
+++ b/include/linux/ethtool.h
@@ -744,7 +744,9 @@ bool ethtool_invalid_flags(struct net_device *dev, u32 data, u32 supported);
 /**
  * struct ethtool_ops - optional netdev operations
  * @get_settings: Get various device settings including Ethernet link
- *	settings.  Returns a negative error code or zero.
+ *	settings. The @cmd parameter is expected to have been cleared
+ *	before get_settings is called. Returns a negative error code or
+ *	zero.
  * @set_settings: Set various device settings including Ethernet link
  *	settings.  Returns a negative error code or zero.
  * @get_drvinfo: Report driver/device information.  Should only set the
diff --git a/include/linux/netdevice.h b/include/linux/netdevice.h
index cb8178a..3f09a71 100644
--- a/include/linux/netdevice.h
+++ b/include/linux/netdevice.h
@@ -2590,13 +2590,8 @@ static inline int netif_is_bond_slave(struct net_device *dev)
 
 extern struct pernet_operations __net_initdata loopback_net_ops;
 
-static inline int dev_ethtool_get_settings(struct net_device *dev,
-					   struct ethtool_cmd *cmd)
-{
-	if (!dev->ethtool_ops || !dev->ethtool_ops->get_settings)
-		return -EOPNOTSUPP;
-	return dev->ethtool_ops->get_settings(dev, cmd);
-}
+int dev_ethtool_get_settings(struct net_device *dev,
+			     struct ethtool_cmd *cmd);
 
 static inline u32 dev_ethtool_get_rx_csum(struct net_device *dev)
 {
diff --git a/include/rdma/ib_addr.h b/include/rdma/ib_addr.h
index b5fc9f3..ae8c68f 100644
--- a/include/rdma/ib_addr.h
+++ b/include/rdma/ib_addr.h
@@ -217,18 +217,19 @@ static inline enum ib_mtu iboe_get_mtu(int mtu)
 static inline int iboe_get_rate(struct net_device *dev)
 {
 	struct ethtool_cmd cmd;
+	u32 speed;
 
-	if (!dev->ethtool_ops || !dev->ethtool_ops->get_settings ||
-	    dev->ethtool_ops->get_settings(dev, &cmd))
+	if (dev_ethtool_get_settings(dev, &cmd))
 		return IB_RATE_PORT_CURRENT;
 
-	if (cmd.speed >= 40000)
+	speed = ethtool_cmd_speed(&cmd);
+	if (speed >= 40000)
 		return IB_RATE_40_GBPS;
-	else if (cmd.speed >= 30000)
+	else if (speed >= 30000)
 		return IB_RATE_30_GBPS;
-	else if (cmd.speed >= 20000)
+	else if (speed >= 20000)
 		return IB_RATE_20_GBPS;
-	else if (cmd.speed >= 10000)
+	else if (speed >= 10000)
 		return IB_RATE_10_GBPS;
 	else
 		return IB_RATE_PORT_CURRENT;
diff --git a/net/core/dev.c b/net/core/dev.c
index 3bbb4c2..f499693 100644
--- a/net/core/dev.c
+++ b/net/core/dev.c
@@ -4496,6 +4496,30 @@ void dev_set_rx_mode(struct net_device *dev)
 }
 
 /**
+ *	dev_ethtool_get_settings - call device's ethtool_ops::get_settings()
+ *	@dev: device
+ *	@cmd: memory area for ethtool_ops::get_settings() result
+ *
+ *      The cmd arg is initialized properly (cleared and
+ *      ethtool_cmd::cmd field set to ETHTOOL_GSET).
+ *
+ *	Return device's ethtool_ops::get_settings() result value or
+ *	-EOPNOTSUPP when device doesn't expose
+ *	ethtool_ops::get_settings() operation.
+ */
+int dev_ethtool_get_settings(struct net_device *dev,
+			     struct ethtool_cmd *cmd)
+{
+	if (!dev->ethtool_ops || !dev->ethtool_ops->get_settings)
+		return -EOPNOTSUPP;
+
+	memset(cmd, 0, sizeof(struct ethtool_cmd));
+	cmd->cmd = ETHTOOL_GSET;
+	return dev->ethtool_ops->get_settings(dev, cmd);
+}
+EXPORT_SYMBOL(dev_ethtool_get_settings);
+
+/**
  *	dev_get_flags - get flags reported to userspace
  *	@dev: device
  *
diff --git a/net/core/net-sysfs.c b/net/core/net-sysfs.c
index 5ceb257..381813e 100644
--- a/net/core/net-sysfs.c
+++ b/net/core/net-sysfs.c
@@ -28,6 +28,7 @@
 static const char fmt_hex[] = "%#x\n";
 static const char fmt_long_hex[] = "%#lx\n";
 static const char fmt_dec[] = "%d\n";
+static const char fmt_udec[] = "%u\n";
 static const char fmt_ulong[] = "%lu\n";
 static const char fmt_u64[] = "%llu\n";
 
@@ -145,13 +146,10 @@ static ssize_t show_speed(struct device *dev,
 	if (!rtnl_trylock())
 		return restart_syscall();
 
-	if (netif_running(netdev) &&
-	    netdev->ethtool_ops &&
-	    netdev->ethtool_ops->get_settings) {
-		struct ethtool_cmd cmd = { ETHTOOL_GSET };
-
-		if (!netdev->ethtool_ops->get_settings(netdev, &cmd))
-			ret = sprintf(buf, fmt_dec, ethtool_cmd_speed(&cmd));
+	if (netif_running(netdev)) {
+		struct ethtool_cmd cmd;
+		if (!dev_ethtool_get_settings(netdev, &cmd))
+			ret = sprintf(buf, fmt_udec, ethtool_cmd_speed(&cmd));
 	}
 	rtnl_unlock();
 	return ret;
@@ -166,13 +164,11 @@ static ssize_t show_duplex(struct device *dev,
 	if (!rtnl_trylock())
 		return restart_syscall();
 
-	if (netif_running(netdev) &&
-	    netdev->ethtool_ops &&
-	    netdev->ethtool_ops->get_settings) {
-		struct ethtool_cmd cmd = { ETHTOOL_GSET };
-
-		if (!netdev->ethtool_ops->get_settings(netdev, &cmd))
-			ret = sprintf(buf, "%s\n", cmd.duplex ? "full" : "half");
+	if (netif_running(netdev)) {
+		struct ethtool_cmd cmd;
+		if (!dev_ethtool_get_settings(netdev, &cmd))
+			ret = sprintf(buf, "%s\n",
+				      cmd.duplex ? "full" : "half");
 	}
 	rtnl_unlock();
 	return ret;
-- 
1.7.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