Netdev List
 help / color / mirror / Atom feed
* [PATCH 1/3] net: Make dst_alloc() take more explicit initializations.
From: David Miller @ 2011-04-29  5:25 UTC (permalink / raw)
  To: netdev


Now the dst->dev, dev->obsolete, and dst->flags values can
be specified as well.

Signed-off-by: David S. Miller <davem@davemloft.net>
---
 include/net/dst.h      |    3 ++-
 net/core/dst.c         |   18 +++++++++++++-----
 net/decnet/dn_route.c  |   13 ++-----------
 net/ipv4/route.c       |   40 +++++++++++++++-------------------------
 net/ipv6/route.c       |   29 +++++++++++------------------
 net/xfrm/xfrm_policy.c |    2 +-
 6 files changed, 44 insertions(+), 61 deletions(-)

diff --git a/include/net/dst.h b/include/net/dst.h
index d7bb740..2588a9a 100644
--- a/include/net/dst.h
+++ b/include/net/dst.h
@@ -350,7 +350,8 @@ static inline struct dst_entry *skb_dst_pop(struct sk_buff *skb)
 }
 
 extern int dst_discard(struct sk_buff *skb);
-extern void *dst_alloc(struct dst_ops * ops, int initial_ref);
+extern void *dst_alloc(struct dst_ops * ops, struct net_device *dev,
+		       int initial_ref, int initial_obsolete, int flags);
 extern void __dst_free(struct dst_entry * dst);
 extern struct dst_entry *dst_destroy(struct dst_entry * dst);
 
diff --git a/net/core/dst.c b/net/core/dst.c
index 91104d3..9505778 100644
--- a/net/core/dst.c
+++ b/net/core/dst.c
@@ -166,7 +166,8 @@ EXPORT_SYMBOL(dst_discard);
 
 const u32 dst_default_metrics[RTAX_MAX];
 
-void *dst_alloc(struct dst_ops *ops, int initial_ref)
+void *dst_alloc(struct dst_ops *ops, struct net_device *dev,
+		int initial_ref, int initial_obsolete, int flags)
 {
 	struct dst_entry *dst;
 
@@ -177,12 +178,19 @@ void *dst_alloc(struct dst_ops *ops, int initial_ref)
 	dst = kmem_cache_zalloc(ops->kmem_cachep, GFP_ATOMIC);
 	if (!dst)
 		return NULL;
-	atomic_set(&dst->__refcnt, initial_ref);
 	dst->ops = ops;
-	dst->lastuse = jiffies;
-	dst->path = dst;
-	dst->input = dst->output = dst_discard;
+	dst->dev = dev;
+	if (dev)
+		dev_hold(dev);
 	dst_init_metrics(dst, dst_default_metrics, true);
+	dst->path = dst;
+	dst->input = dst_discard;
+	dst->output = dst_discard;
+
+	dst->obsolete = initial_obsolete;
+	atomic_set(&dst->__refcnt, initial_ref);
+	dst->lastuse = jiffies;
+	dst->flags = flags;
 #if RT_CACHE_DEBUG >= 2
 	atomic_inc(&dst_total);
 #endif
diff --git a/net/decnet/dn_route.c b/net/decnet/dn_route.c
index 9f09d4f..f489b08 100644
--- a/net/decnet/dn_route.c
+++ b/net/decnet/dn_route.c
@@ -1125,13 +1125,10 @@ make_route:
 	if (dev_out->flags & IFF_LOOPBACK)
 		flags |= RTCF_LOCAL;
 
-	rt = dst_alloc(&dn_dst_ops, 0);
+	rt = dst_alloc(&dn_dst_ops, dev_out, 1, 0, DST_HOST);
 	if (rt == NULL)
 		goto e_nobufs;
 
-	atomic_set(&rt->dst.__refcnt, 1);
-	rt->dst.flags   = DST_HOST;
-
 	rt->fld.saddr        = oldflp->saddr;
 	rt->fld.daddr        = oldflp->daddr;
 	rt->fld.flowidn_oif  = oldflp->flowidn_oif;
@@ -1146,8 +1143,6 @@ make_route:
 	rt->rt_dst_map    = fld.daddr;
 	rt->rt_src_map    = fld.saddr;
 
-	rt->dst.dev = dev_out;
-	dev_hold(dev_out);
 	rt->dst.neighbour = neigh;
 	neigh = NULL;
 
@@ -1399,7 +1394,7 @@ static int dn_route_input_slow(struct sk_buff *skb)
 	}
 
 make_route:
-	rt = dst_alloc(&dn_dst_ops, 0);
+	rt = dst_alloc(&dn_dst_ops, out_dev, 0, 0, DST_HOST);
 	if (rt == NULL)
 		goto e_nobufs;
 
@@ -1419,9 +1414,7 @@ make_route:
 	rt->fld.flowidn_iif  = in_dev->ifindex;
 	rt->fld.flowidn_mark = fld.flowidn_mark;
 
-	rt->dst.flags = DST_HOST;
 	rt->dst.neighbour = neigh;
-	rt->dst.dev = out_dev;
 	rt->dst.lastuse = jiffies;
 	rt->dst.output = dn_rt_bug;
 	switch(res.type) {
@@ -1440,8 +1433,6 @@ make_route:
 			rt->dst.input = dst_discard;
 	}
 	rt->rt_flags = flags;
-	if (rt->dst.dev)
-		dev_hold(rt->dst.dev);
 
 	err = dn_rt_set_next_hop(rt, &res);
 	if (err)
diff --git a/net/ipv4/route.c b/net/ipv4/route.c
index d63f780..b471d89 100644
--- a/net/ipv4/route.c
+++ b/net/ipv4/route.c
@@ -1833,17 +1833,13 @@ static void rt_set_nexthop(struct rtable *rt, const struct flowi4 *oldflp4,
 	rt->rt_type = type;
 }
 
-static struct rtable *rt_dst_alloc(bool nopolicy, bool noxfrm)
+static struct rtable *rt_dst_alloc(struct net_device *dev,
+				   bool nopolicy, bool noxfrm)
 {
-	struct rtable *rt = dst_alloc(&ipv4_dst_ops, 1);
-	if (rt) {
-		rt->dst.obsolete = -1;
-
-		rt->dst.flags = DST_HOST |
-			(nopolicy ? DST_NOPOLICY : 0) |
-			(noxfrm ? DST_NOXFRM : 0);
-	}
-	return rt;
+	return dst_alloc(&ipv4_dst_ops, dev, 1, -1,
+			 DST_HOST |
+			 (nopolicy ? DST_NOPOLICY : 0) |
+			 (noxfrm ? DST_NOXFRM : 0));
 }
 
 /* called in rcu_read_lock() section */
@@ -1876,7 +1872,8 @@ static int ip_route_input_mc(struct sk_buff *skb, __be32 daddr, __be32 saddr,
 		if (err < 0)
 			goto e_err;
 	}
-	rth = rt_dst_alloc(IN_DEV_CONF_GET(in_dev, NOPOLICY), false);
+	rth = rt_dst_alloc(init_net.loopback_dev,
+			   IN_DEV_CONF_GET(in_dev, NOPOLICY), false);
 	if (!rth)
 		goto e_nobufs;
 
@@ -1893,8 +1890,6 @@ static int ip_route_input_mc(struct sk_buff *skb, __be32 daddr, __be32 saddr,
 #endif
 	rth->rt_route_iif = dev->ifindex;
 	rth->rt_iif	= dev->ifindex;
-	rth->dst.dev	= init_net.loopback_dev;
-	dev_hold(rth->dst.dev);
 	rth->rt_oif	= 0;
 	rth->rt_gateway	= daddr;
 	rth->rt_spec_dst= spec_dst;
@@ -2013,7 +2008,8 @@ static int __mkroute_input(struct sk_buff *skb,
 		}
 	}
 
-	rth = rt_dst_alloc(IN_DEV_CONF_GET(in_dev, NOPOLICY),
+	rth = rt_dst_alloc(out_dev->dev,
+			   IN_DEV_CONF_GET(in_dev, NOPOLICY),
 			   IN_DEV_CONF_GET(out_dev, NOXFRM));
 	if (!rth) {
 		err = -ENOBUFS;
@@ -2029,8 +2025,6 @@ static int __mkroute_input(struct sk_buff *skb,
 	rth->rt_gateway	= daddr;
 	rth->rt_route_iif = in_dev->dev->ifindex;
 	rth->rt_iif 	= in_dev->dev->ifindex;
-	rth->dst.dev	= (out_dev)->dev;
-	dev_hold(rth->dst.dev);
 	rth->rt_oif 	= 0;
 	rth->rt_spec_dst= spec_dst;
 
@@ -2188,7 +2182,8 @@ brd_input:
 	RT_CACHE_STAT_INC(in_brd);
 
 local_input:
-	rth = rt_dst_alloc(IN_DEV_CONF_GET(in_dev, NOPOLICY), false);
+	rth = rt_dst_alloc(net->loopback_dev,
+			   IN_DEV_CONF_GET(in_dev, NOPOLICY), false);
 	if (!rth)
 		goto e_nobufs;
 
@@ -2206,8 +2201,6 @@ local_input:
 #endif
 	rth->rt_route_iif = dev->ifindex;
 	rth->rt_iif	= dev->ifindex;
-	rth->dst.dev	= net->loopback_dev;
-	dev_hold(rth->dst.dev);
 	rth->rt_gateway	= daddr;
 	rth->rt_spec_dst= spec_dst;
 	rth->dst.input= ip_local_deliver;
@@ -2392,7 +2385,8 @@ static struct rtable *__mkroute_output(const struct fib_result *res,
 			fi = NULL;
 	}
 
-	rth = rt_dst_alloc(IN_DEV_CONF_GET(in_dev, NOPOLICY),
+	rth = rt_dst_alloc(dev_out,
+			   IN_DEV_CONF_GET(in_dev, NOPOLICY),
 			   IN_DEV_CONF_GET(in_dev, NOXFRM));
 	if (!rth)
 		return ERR_PTR(-ENOBUFS);
@@ -2406,10 +2400,6 @@ static struct rtable *__mkroute_output(const struct fib_result *res,
 	rth->rt_src	= fl4->saddr;
 	rth->rt_route_iif = 0;
 	rth->rt_iif	= oldflp4->flowi4_oif ? : dev_out->ifindex;
-	/* get references to the devices that are to be hold by the routing
-	   cache entry */
-	rth->dst.dev	= dev_out;
-	dev_hold(dev_out);
 	rth->rt_gateway = fl4->daddr;
 	rth->rt_spec_dst= fl4->saddr;
 
@@ -2711,7 +2701,7 @@ static struct dst_ops ipv4_dst_blackhole_ops = {
 
 struct dst_entry *ipv4_blackhole_route(struct net *net, struct dst_entry *dst_orig)
 {
-	struct rtable *rt = dst_alloc(&ipv4_dst_blackhole_ops, 1);
+	struct rtable *rt = dst_alloc(&ipv4_dst_blackhole_ops, NULL, 1, 0, 0);
 	struct rtable *ort = (struct rtable *) dst_orig;
 
 	if (rt) {
diff --git a/net/ipv6/route.c b/net/ipv6/route.c
index 19a77d0..e8b2bb9 100644
--- a/net/ipv6/route.c
+++ b/net/ipv6/route.c
@@ -227,9 +227,10 @@ static struct rt6_info ip6_blk_hole_entry_template = {
 #endif
 
 /* allocate dst with ip6_dst_ops */
-static inline struct rt6_info *ip6_dst_alloc(struct dst_ops *ops)
+static inline struct rt6_info *ip6_dst_alloc(struct dst_ops *ops,
+					     struct net_device *dev)
 {
-	return (struct rt6_info *)dst_alloc(ops, 0);
+	return (struct rt6_info *)dst_alloc(ops, dev, 0, 0, 0);
 }
 
 static void ip6_dst_destroy(struct dst_entry *dst)
@@ -881,10 +882,10 @@ EXPORT_SYMBOL(ip6_route_output);
 
 struct dst_entry *ip6_blackhole_route(struct net *net, struct dst_entry *dst_orig)
 {
-	struct rt6_info *rt = dst_alloc(&ip6_dst_blackhole_ops, 1);
-	struct rt6_info *ort = (struct rt6_info *) dst_orig;
+	struct rt6_info *rt, *ort = (struct rt6_info *) dst_orig;
 	struct dst_entry *new = NULL;
 
+	rt = dst_alloc(&ip6_dst_blackhole_ops, ort->dst.dev, 1, 0, 0);
 	if (rt) {
 		new = &rt->dst;
 
@@ -893,9 +894,6 @@ struct dst_entry *ip6_blackhole_route(struct net *net, struct dst_entry *dst_ori
 		new->output = dst_discard;
 
 		dst_copy_metrics(new, &ort->dst);
-		new->dev = ort->dst.dev;
-		if (new->dev)
-			dev_hold(new->dev);
 		rt->rt6i_idev = ort->rt6i_idev;
 		if (rt->rt6i_idev)
 			in6_dev_hold(rt->rt6i_idev);
@@ -1038,13 +1036,12 @@ struct dst_entry *icmp6_dst_alloc(struct net_device *dev,
 	if (unlikely(idev == NULL))
 		return NULL;
 
-	rt = ip6_dst_alloc(&net->ipv6.ip6_dst_ops);
+	rt = ip6_dst_alloc(&net->ipv6.ip6_dst_ops, dev);
 	if (unlikely(rt == NULL)) {
 		in6_dev_put(idev);
 		goto out;
 	}
 
-	dev_hold(dev);
 	if (neigh)
 		neigh_hold(neigh);
 	else {
@@ -1053,7 +1050,6 @@ struct dst_entry *icmp6_dst_alloc(struct net_device *dev,
 			neigh = NULL;
 	}
 
-	rt->rt6i_dev	  = dev;
 	rt->rt6i_idev     = idev;
 	rt->rt6i_nexthop  = neigh;
 	atomic_set(&rt->dst.__refcnt, 1);
@@ -1212,7 +1208,7 @@ int ip6_route_add(struct fib6_config *cfg)
 		goto out;
 	}
 
-	rt = ip6_dst_alloc(&net->ipv6.ip6_dst_ops);
+	rt = ip6_dst_alloc(&net->ipv6.ip6_dst_ops, NULL);
 
 	if (rt == NULL) {
 		err = -ENOMEM;
@@ -1731,7 +1727,8 @@ void rt6_pmtu_discovery(const struct in6_addr *daddr, const struct in6_addr *sad
 static struct rt6_info * ip6_rt_copy(struct rt6_info *ort)
 {
 	struct net *net = dev_net(ort->rt6i_dev);
-	struct rt6_info *rt = ip6_dst_alloc(&net->ipv6.ip6_dst_ops);
+	struct rt6_info *rt = ip6_dst_alloc(&net->ipv6.ip6_dst_ops,
+					    ort->dst.dev);
 
 	if (rt) {
 		rt->dst.input = ort->dst.input;
@@ -1739,9 +1736,6 @@ static struct rt6_info * ip6_rt_copy(struct rt6_info *ort)
 
 		dst_copy_metrics(&rt->dst, &ort->dst);
 		rt->dst.error = ort->dst.error;
-		rt->dst.dev = ort->dst.dev;
-		if (rt->dst.dev)
-			dev_hold(rt->dst.dev);
 		rt->rt6i_idev = ort->rt6i_idev;
 		if (rt->rt6i_idev)
 			in6_dev_hold(rt->rt6i_idev);
@@ -2011,7 +2005,8 @@ struct rt6_info *addrconf_dst_alloc(struct inet6_dev *idev,
 				    int anycast)
 {
 	struct net *net = dev_net(idev->dev);
-	struct rt6_info *rt = ip6_dst_alloc(&net->ipv6.ip6_dst_ops);
+	struct rt6_info *rt = ip6_dst_alloc(&net->ipv6.ip6_dst_ops,
+					    net->loopback_dev);
 	struct neighbour *neigh;
 
 	if (rt == NULL) {
@@ -2021,13 +2016,11 @@ struct rt6_info *addrconf_dst_alloc(struct inet6_dev *idev,
 		return ERR_PTR(-ENOMEM);
 	}
 
-	dev_hold(net->loopback_dev);
 	in6_dev_hold(idev);
 
 	rt->dst.flags = DST_HOST;
 	rt->dst.input = ip6_input;
 	rt->dst.output = ip6_output;
-	rt->rt6i_dev = net->loopback_dev;
 	rt->rt6i_idev = idev;
 	rt->dst.obsolete = -1;
 
diff --git a/net/xfrm/xfrm_policy.c b/net/xfrm/xfrm_policy.c
index 15792d8..70552c4 100644
--- a/net/xfrm/xfrm_policy.c
+++ b/net/xfrm/xfrm_policy.c
@@ -1348,7 +1348,7 @@ static inline struct xfrm_dst *xfrm_alloc_dst(struct net *net, int family)
 	default:
 		BUG();
 	}
-	xdst = dst_alloc(dst_ops, 0);
+	xdst = dst_alloc(dst_ops, NULL, 0, 0, 0);
 	xfrm_policy_put_afinfo(afinfo);
 
 	if (likely(xdst))
-- 
1.7.4.5


^ permalink raw reply related

* [PATCH 0/3] Routing refinements.
From: David Miller @ 2011-04-29  5:25 UTC (permalink / raw)
  To: netdev


Don't initialize dst entries multiple times during allocation
and creation.

Use caller's flowi object in output route lookup paths.

These changes open the door to getting rid of several aspect of struct
rtcache.  For example, since the output route lookup updates the flow
keys, there is no need to use things like rt->rt_src since the same
information is present in the lookup flow key.

For example, connect() of stream sockets and sendmsg() of datagram
sockets do something like:

	rt = ip_route_connect(... &fl ...);
	...
	something using rt->rt_src

When we can now replace rt->rt_src with fl.saddr

Eventually all instance specific aspects of struct rtable can be
removed and we are left with a routing object that can exist as
a single instance pointed to directly from the routing table
nexthop slots.

The only part I don't have a clean vision on is the inetpeer and
metrics.  But I don't anticipate that being insurmountable.

^ permalink raw reply

* [PATCH 0/2] wireless: Make and use const struct ieee80211_channel
From: Joe Perches @ 2011-04-29  5:25 UTC (permalink / raw)
  To: linux-wireless, libertas-dev, orinoco-users, orinoco-devel,
	netdev
  Cc: linux-kernel

Joe Perches (2):
  wireless: Make struct ieee80211_channel const where possible
  wireless: Use const struct ieee80211_channel where possible

 drivers/net/wireless/iwlegacy/iwl-4965-lib.c |    2 +-
 drivers/net/wireless/iwlegacy/iwl3945-base.c |    2 +-
 drivers/net/wireless/iwlwifi/iwl-agn-lib.c   |    2 +-
 drivers/net/wireless/iwmc3200wifi/cfg80211.c |    4 +-
 drivers/net/wireless/libertas/cfg.c          |    2 +-
 drivers/net/wireless/mwifiex/cfg80211.c      |    9 ++++---
 drivers/net/wireless/orinoco/cfg.c           |    2 +-
 drivers/net/wireless/rndis_wlan.c            |    9 ++++---
 drivers/net/wireless/wl1251/cmd.c            |    2 +-
 drivers/net/wireless/wl1251/cmd.h            |    2 +-
 include/net/cfg80211.h                       |   34 +++++++++++++-------------
 net/wireless/chan.c                          |   10 ++++----
 net/wireless/core.h                          |   14 ++++++----
 net/wireless/debugfs.c                       |    2 +-
 net/wireless/ibss.c                          |    6 ++--
 net/wireless/mlme.c                          |   15 ++++++-----
 net/wireless/nl80211.c                       |   31 ++++++++++++-----------
 net/wireless/nl80211.h                       |    9 ++++---
 net/wireless/reg.c                           |   11 ++++----
 net/wireless/reg.h                           |    4 +-
 net/wireless/scan.c                          |    6 ++--
 net/wireless/wext-sme.c                      |    2 +-
 22 files changed, 94 insertions(+), 86 deletions(-)

-- 
1.7.5.rc3.dirty


^ permalink raw reply

* [PATCH 2/2] wireless: Use const struct ieee80211_channel where possible
From: Joe Perches @ 2011-04-29  5:25 UTC (permalink / raw)
  To: Stanislaw Gruszka, Wey-Yi Guy, Intel Linux Wireless, Samuel Ortiz,
	Dan Williams
  Cc: linux-wireless, netdev, linux-kernel, libertas-dev, orinoco-users,
	orinoco-devel
In-Reply-To: <cover.1304054543.git.joe@perches.com>

Make some structure uses const.

Signed-off-by: Joe Perches <joe@perches.com>
---
 drivers/net/wireless/iwlegacy/iwl-4965-lib.c |    2 +-
 drivers/net/wireless/iwlegacy/iwl3945-base.c |    2 +-
 drivers/net/wireless/iwlwifi/iwl-agn-lib.c   |    2 +-
 drivers/net/wireless/iwmc3200wifi/cfg80211.c |    4 ++--
 drivers/net/wireless/libertas/cfg.c          |    2 +-
 drivers/net/wireless/mwifiex/cfg80211.c      |    9 +++++----
 drivers/net/wireless/orinoco/cfg.c           |    2 +-
 drivers/net/wireless/rndis_wlan.c            |    9 +++++----
 drivers/net/wireless/wl1251/cmd.c            |    2 +-
 drivers/net/wireless/wl1251/cmd.h            |    2 +-
 10 files changed, 19 insertions(+), 17 deletions(-)

diff --git a/drivers/net/wireless/iwlegacy/iwl-4965-lib.c b/drivers/net/wireless/iwlegacy/iwl-4965-lib.c
index 5a8a3cc..41ec864 100644
--- a/drivers/net/wireless/iwlegacy/iwl-4965-lib.c
+++ b/drivers/net/wireless/iwlegacy/iwl-4965-lib.c
@@ -741,7 +741,7 @@ static int iwl4965_get_channels_for_scan(struct iwl_priv *priv,
 				     u8 is_active, u8 n_probes,
 				     struct iwl_scan_channel *scan_ch)
 {
-	struct ieee80211_channel *chan;
+	const struct ieee80211_channel *chan;
 	const struct ieee80211_supported_band *sband;
 	const struct iwl_channel_info *ch_info;
 	u16 passive_dwell = 0;
diff --git a/drivers/net/wireless/iwlegacy/iwl3945-base.c b/drivers/net/wireless/iwlegacy/iwl3945-base.c
index cc7ebce..5bcfaf5 100644
--- a/drivers/net/wireless/iwlegacy/iwl3945-base.c
+++ b/drivers/net/wireless/iwlegacy/iwl3945-base.c
@@ -1811,7 +1811,7 @@ static int iwl3945_get_channels_for_scan(struct iwl_priv *priv,
 				     struct iwl3945_scan_channel *scan_ch,
 				     struct ieee80211_vif *vif)
 {
-	struct ieee80211_channel *chan;
+	const struct ieee80211_channel *chan;
 	const struct ieee80211_supported_band *sband;
 	const struct iwl_channel_info *ch_info;
 	u16 passive_dwell = 0;
diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-lib.c b/drivers/net/wireless/iwlwifi/iwl-agn-lib.c
index e202a40..75badb1 100644
--- a/drivers/net/wireless/iwlwifi/iwl-agn-lib.c
+++ b/drivers/net/wireless/iwlwifi/iwl-agn-lib.c
@@ -1051,7 +1051,7 @@ static int iwl_get_channels_for_scan(struct iwl_priv *priv,
 				     u8 is_active, u8 n_probes,
 				     struct iwl_scan_channel *scan_ch)
 {
-	struct ieee80211_channel *chan;
+	const struct ieee80211_channel *chan;
 	const struct ieee80211_supported_band *sband;
 	const struct iwl_channel_info *ch_info;
 	u16 passive_dwell = 0;
diff --git a/drivers/net/wireless/iwmc3200wifi/cfg80211.c b/drivers/net/wireless/iwmc3200wifi/cfg80211.c
index ed57e44..a9d1b44 100644
--- a/drivers/net/wireless/iwmc3200wifi/cfg80211.c
+++ b/drivers/net/wireless/iwmc3200wifi/cfg80211.c
@@ -408,7 +408,7 @@ static int iwm_cfg80211_join_ibss(struct wiphy *wiphy, struct net_device *dev,
 				  struct cfg80211_ibss_params *params)
 {
 	struct iwm_priv *iwm = wiphy_to_iwm(wiphy);
-	struct ieee80211_channel *chan = params->channel;
+	const struct ieee80211_channel *chan = params->channel;
 
 	if (!test_bit(IWM_STATUS_READY, &iwm->status))
 		return -EIO;
@@ -549,7 +549,7 @@ static int iwm_cfg80211_connect(struct wiphy *wiphy, struct net_device *dev,
 				 struct cfg80211_connect_params *sme)
 {
 	struct iwm_priv *iwm = wiphy_to_iwm(wiphy);
-	struct ieee80211_channel *chan = sme->channel;
+	const struct ieee80211_channel *chan = sme->channel;
 	struct key_params key_param;
 	int ret;
 
diff --git a/drivers/net/wireless/libertas/cfg.c b/drivers/net/wireless/libertas/cfg.c
index 5caa2ac..66d6b58 100644
--- a/drivers/net/wireless/libertas/cfg.c
+++ b/drivers/net/wireless/libertas/cfg.c
@@ -431,7 +431,7 @@ static int lbs_add_wpa_tlv(u8 *tlv, const u8 *ie, u8 ie_len)
 
 static int lbs_cfg_set_channel(struct wiphy *wiphy,
 	struct net_device *netdev,
-	struct ieee80211_channel *channel,
+	const struct ieee80211_channel *channel,
 	enum nl80211_channel_type channel_type)
 {
 	struct lbs_private *priv = wiphy_priv(wiphy);
diff --git a/drivers/net/wireless/mwifiex/cfg80211.c b/drivers/net/wireless/mwifiex/cfg80211.c
index b99ae26..5508dc0 100644
--- a/drivers/net/wireless/mwifiex/cfg80211.c
+++ b/drivers/net/wireless/mwifiex/cfg80211.c
@@ -329,7 +329,7 @@ static int mwifiex_reg_notifier(struct wiphy *wiphy,
  */
 static int
 mwifiex_set_rf_channel(struct mwifiex_private *priv,
-		       struct ieee80211_channel *chan,
+		       const struct ieee80211_channel *chan,
 		       enum nl80211_channel_type channel_type)
 {
 	struct mwifiex_chan_freq_power cfp;
@@ -385,7 +385,7 @@ mwifiex_set_rf_channel(struct mwifiex_private *priv,
  */
 static int
 mwifiex_cfg80211_set_channel(struct wiphy *wiphy, struct net_device *dev,
-			     struct ieee80211_channel *chan,
+			     const struct ieee80211_channel *chan,
 			     enum nl80211_channel_type channel_type)
 {
 	struct mwifiex_private *priv = mwifiex_cfg80211_get_priv(wiphy);
@@ -898,7 +898,8 @@ static int mwifiex_inform_bss_from_scan_result(struct mwifiex_private *priv,
  */
 static int
 mwifiex_cfg80211_assoc(struct mwifiex_private *priv, size_t ssid_len, u8 *ssid,
-		       u8 *bssid, int mode, struct ieee80211_channel *channel,
+		       u8 *bssid, int mode,
+		       const struct ieee80211_channel *channel,
 		       struct cfg80211_connect_params *sme, bool privacy)
 {
 	struct mwifiex_802_11_ssid req_ssid;
@@ -1304,7 +1305,7 @@ mwifiex_cfg80211_results(struct work_struct *work)
 		container_of(work, struct mwifiex_private, cfg_workqueue);
 	struct mwifiex_user_scan_cfg *scan_req;
 	int ret = 0, i;
-	struct ieee80211_channel *chan;
+	const struct ieee80211_channel *chan;
 
 	if (priv->scan_request) {
 		scan_req = kzalloc(sizeof(struct mwifiex_user_scan_cfg),
diff --git a/drivers/net/wireless/orinoco/cfg.c b/drivers/net/wireless/orinoco/cfg.c
index 736bbb9..975c915 100644
--- a/drivers/net/wireless/orinoco/cfg.c
+++ b/drivers/net/wireless/orinoco/cfg.c
@@ -162,7 +162,7 @@ static int orinoco_scan(struct wiphy *wiphy, struct net_device *dev,
 
 static int orinoco_set_channel(struct wiphy *wiphy,
 			struct net_device *netdev,
-			struct ieee80211_channel *chan,
+			const struct ieee80211_channel *chan,
 			enum nl80211_channel_type channel_type)
 {
 	struct orinoco_private *priv = wiphy_priv(wiphy);
diff --git a/drivers/net/wireless/rndis_wlan.c b/drivers/net/wireless/rndis_wlan.c
index 518542b..c22d516 100644
--- a/drivers/net/wireless/rndis_wlan.c
+++ b/drivers/net/wireless/rndis_wlan.c
@@ -554,7 +554,8 @@ static int rndis_join_ibss(struct wiphy *wiphy, struct net_device *dev,
 static int rndis_leave_ibss(struct wiphy *wiphy, struct net_device *dev);
 
 static int rndis_set_channel(struct wiphy *wiphy, struct net_device *dev,
-	struct ieee80211_channel *chan, enum nl80211_channel_type channel_type);
+			     const struct ieee80211_channel *chan,
+			     enum nl80211_channel_type channel_type);
 
 static int rndis_add_key(struct wiphy *wiphy, struct net_device *netdev,
 			 u8 key_index, bool pairwise, const u8 *mac_addr,
@@ -2143,7 +2144,7 @@ static int rndis_connect(struct wiphy *wiphy, struct net_device *dev,
 {
 	struct rndis_wlan_private *priv = wiphy_priv(wiphy);
 	struct usbnet *usbdev = priv->usbdev;
-	struct ieee80211_channel *channel = sme->channel;
+	const struct ieee80211_channel *channel = sme->channel;
 	struct ndis_80211_ssid ssid;
 	int pairwise = RNDIS_WLAN_ALG_NONE;
 	int groupwise = RNDIS_WLAN_ALG_NONE;
@@ -2280,7 +2281,7 @@ static int rndis_join_ibss(struct wiphy *wiphy, struct net_device *dev,
 {
 	struct rndis_wlan_private *priv = wiphy_priv(wiphy);
 	struct usbnet *usbdev = priv->usbdev;
-	struct ieee80211_channel *channel = params->channel;
+	const struct ieee80211_channel *channel = params->channel;
 	struct ndis_80211_ssid ssid;
 	enum nl80211_auth_type auth_type;
 	int ret, alg, length, chan = -1;
@@ -2388,7 +2389,7 @@ static int rndis_leave_ibss(struct wiphy *wiphy, struct net_device *dev)
 }
 
 static int rndis_set_channel(struct wiphy *wiphy, struct net_device *netdev,
-	struct ieee80211_channel *chan, enum nl80211_channel_type channel_type)
+	const struct ieee80211_channel *chan, enum nl80211_channel_type channel_type)
 {
 	struct rndis_wlan_private *priv = wiphy_priv(wiphy);
 	struct usbnet *usbdev = priv->usbdev;
diff --git a/drivers/net/wireless/wl1251/cmd.c b/drivers/net/wireless/wl1251/cmd.c
index 81f164b..ed5e62a 100644
--- a/drivers/net/wireless/wl1251/cmd.c
+++ b/drivers/net/wireless/wl1251/cmd.c
@@ -413,7 +413,7 @@ out:
 }
 
 int wl1251_cmd_scan(struct wl1251 *wl, u8 *ssid, size_t ssid_len,
-		    struct ieee80211_channel *channels[],
+		    const struct ieee80211_channel *channels[],
 		    unsigned int n_channels, unsigned int n_probes)
 {
 	struct wl1251_cmd_scan *cmd;
diff --git a/drivers/net/wireless/wl1251/cmd.h b/drivers/net/wireless/wl1251/cmd.h
index 79ca527..f1ff4bf 100644
--- a/drivers/net/wireless/wl1251/cmd.h
+++ b/drivers/net/wireless/wl1251/cmd.h
@@ -44,7 +44,7 @@ int wl1251_cmd_read_memory(struct wl1251 *wl, u32 addr, void *answer,
 int wl1251_cmd_template_set(struct wl1251 *wl, u16 cmd_id,
 			    void *buf, size_t buf_len);
 int wl1251_cmd_scan(struct wl1251 *wl, u8 *ssid, size_t ssid_len,
-		    struct ieee80211_channel *channels[],
+		    const struct ieee80211_channel *channels[],
 		    unsigned int n_channels, unsigned int n_probes);
 int wl1251_cmd_trigger_scan_to(struct wl1251 *wl, u32 timeout);
 
-- 
1.7.5.rc3.dirty

^ permalink raw reply related

* [PATCH 1/2] wireless: Make struct ieee80211_channel const where possible
From: Joe Perches @ 2011-04-29  5:25 UTC (permalink / raw)
  To: Johannes Berg, David S. Miller, John W. Linville
  Cc: linux-wireless, netdev, linux-kernel
In-Reply-To: <cover.1304054543.git.joe@perches.com>

Useful for declarations of static const.

Signed-off-by: Joe Perches <joe@perches.com>
---
 include/net/cfg80211.h  |   34 +++++++++++++++++-----------------
 net/wireless/chan.c     |   10 +++++-----
 net/wireless/core.h     |   14 ++++++++------
 net/wireless/debugfs.c  |    2 +-
 net/wireless/ibss.c     |    6 +++---
 net/wireless/mlme.c     |   15 ++++++++-------
 net/wireless/nl80211.c  |   31 ++++++++++++++++---------------
 net/wireless/nl80211.h  |    9 +++++----
 net/wireless/reg.c      |   11 ++++++-----
 net/wireless/reg.h      |    4 ++--
 net/wireless/scan.c     |    6 +++---
 net/wireless/wext-sme.c |    2 +-
 12 files changed, 75 insertions(+), 69 deletions(-)

diff --git a/include/net/cfg80211.h b/include/net/cfg80211.h
index d30eada..0a14bd9 100644
--- a/include/net/cfg80211.h
+++ b/include/net/cfg80211.h
@@ -789,7 +789,7 @@ struct cfg80211_scan_request {
 	bool aborted;
 
 	/* keep last */
-	struct ieee80211_channel *channels[0];
+	const struct ieee80211_channel *channels[0];
 };
 
 /**
@@ -830,7 +830,7 @@ enum cfg80211_signal_type {
  * @priv: private area for driver use, has at least wiphy->bss_priv_size bytes
  */
 struct cfg80211_bss {
-	struct ieee80211_channel *channel;
+	const struct ieee80211_channel *channel;
 
 	u8 bssid[ETH_ALEN];
 	u64 tsf;
@@ -1002,7 +1002,7 @@ struct cfg80211_disassoc_request {
 struct cfg80211_ibss_params {
 	u8 *ssid;
 	u8 *bssid;
-	struct ieee80211_channel *channel;
+	const struct ieee80211_channel *channel;
 	u8 *ie;
 	u8 ssid_len, ie_len;
 	u16 beacon_interval;
@@ -1034,7 +1034,7 @@ struct cfg80211_ibss_params {
  * @key: WEP key for shared key authentication
  */
 struct cfg80211_connect_params {
-	struct ieee80211_channel *channel;
+	const struct ieee80211_channel *channel;
 	u8 *bssid;
 	u8 *ssid;
 	size_t ssid_len;
@@ -1322,7 +1322,7 @@ struct cfg80211_ops {
 				  struct ieee80211_txq_params *params);
 
 	int	(*set_channel)(struct wiphy *wiphy, struct net_device *dev,
-			       struct ieee80211_channel *chan,
+			       const struct ieee80211_channel *chan,
 			       enum nl80211_channel_type channel_type);
 
 	int	(*scan)(struct wiphy *wiphy, struct net_device *dev,
@@ -1379,7 +1379,7 @@ struct cfg80211_ops {
 
 	int	(*remain_on_channel)(struct wiphy *wiphy,
 				     struct net_device *dev,
-				     struct ieee80211_channel *chan,
+				     const struct ieee80211_channel *chan,
 				     enum nl80211_channel_type channel_type,
 				     unsigned int duration,
 				     u64 *cookie);
@@ -1388,10 +1388,10 @@ struct cfg80211_ops {
 					    u64 cookie);
 
 	int	(*mgmt_tx)(struct wiphy *wiphy, struct net_device *dev,
-			  struct ieee80211_channel *chan, bool offchan,
-			  enum nl80211_channel_type channel_type,
-			  bool channel_type_valid, unsigned int wait,
-			  const u8 *buf, size_t len, u64 *cookie);
+			   const struct ieee80211_channel *chan, bool offchan,
+			   enum nl80211_channel_type channel_type,
+			   bool channel_type_valid, unsigned int wait,
+			   const u8 *buf, size_t len, u64 *cookie);
 	int	(*mgmt_tx_cancel_wait)(struct wiphy *wiphy,
 				       struct net_device *dev,
 				       u64 cookie);
@@ -1804,7 +1804,7 @@ struct wireless_dev {
 	struct cfg80211_internal_bss *authtry_bsses[MAX_AUTH_BSSES];
 	struct cfg80211_internal_bss *auth_bsses[MAX_AUTH_BSSES];
 	struct cfg80211_internal_bss *current_bss; /* associated / joined */
-	struct ieee80211_channel *channel;
+	const struct ieee80211_channel *channel;
 
 	bool ps;
 	int ps_timeout;
@@ -2294,20 +2294,20 @@ cfg80211_inform_bss_frame(struct wiphy *wiphy,
  */
 struct cfg80211_bss*
 cfg80211_inform_bss(struct wiphy *wiphy,
-		    struct ieee80211_channel *channel,
+		    const struct ieee80211_channel *channel,
 		    const u8 *bssid,
 		    u64 timestamp, u16 capability, u16 beacon_interval,
 		    const u8 *ie, size_t ielen,
 		    s32 signal, gfp_t gfp);
 
 struct cfg80211_bss *cfg80211_get_bss(struct wiphy *wiphy,
-				      struct ieee80211_channel *channel,
+				      const struct ieee80211_channel *channel,
 				      const u8 *bssid,
 				      const u8 *ssid, size_t ssid_len,
 				      u16 capa_mask, u16 capa_val);
 static inline struct cfg80211_bss *
 cfg80211_get_ibss(struct wiphy *wiphy,
-		  struct ieee80211_channel *channel,
+		  const struct ieee80211_channel *channel,
 		  const u8 *ssid, size_t ssid_len)
 {
 	return cfg80211_get_bss(wiphy, channel, NULL, ssid, ssid_len,
@@ -2315,7 +2315,7 @@ cfg80211_get_ibss(struct wiphy *wiphy,
 }
 
 struct cfg80211_bss *cfg80211_get_mesh(struct wiphy *wiphy,
-				       struct ieee80211_channel *channel,
+				       const struct ieee80211_channel *channel,
 				       const u8 *meshid, size_t meshidlen,
 				       const u8 *meshcfg);
 void cfg80211_put_bss(struct cfg80211_bss *bss);
@@ -2695,7 +2695,7 @@ void cfg80211_disconnected(struct net_device *dev, u16 reason,
  * @gfp: allocation flags
  */
 void cfg80211_ready_on_channel(struct net_device *dev, u64 cookie,
-			       struct ieee80211_channel *chan,
+			       const struct ieee80211_channel *chan,
 			       enum nl80211_channel_type channel_type,
 			       unsigned int duration, gfp_t gfp);
 
@@ -2709,7 +2709,7 @@ void cfg80211_ready_on_channel(struct net_device *dev, u64 cookie,
  */
 void cfg80211_remain_on_channel_expired(struct net_device *dev,
 					u64 cookie,
-					struct ieee80211_channel *chan,
+					const struct ieee80211_channel *chan,
 					enum nl80211_channel_type channel_type,
 					gfp_t gfp);
 
diff --git a/net/wireless/chan.c b/net/wireless/chan.c
index 17cd0c0..d2fcf62 100644
--- a/net/wireless/chan.c
+++ b/net/wireless/chan.c
@@ -9,11 +9,11 @@
 #include <net/cfg80211.h>
 #include "core.h"
 
-struct ieee80211_channel *
+const struct ieee80211_channel *
 rdev_freq_to_chan(struct cfg80211_registered_device *rdev,
 		  int freq, enum nl80211_channel_type channel_type)
 {
-	struct ieee80211_channel *chan;
+	const struct ieee80211_channel *chan;
 	struct ieee80211_sta_ht_cap *ht_cap;
 
 	chan = ieee80211_get_channel(&rdev->wiphy, freq);
@@ -45,10 +45,10 @@ rdev_freq_to_chan(struct cfg80211_registered_device *rdev,
 }
 
 static bool can_beacon_sec_chan(struct wiphy *wiphy,
-				struct ieee80211_channel *chan,
+				const struct ieee80211_channel *chan,
 				enum nl80211_channel_type channel_type)
 {
-	struct ieee80211_channel *sec_chan;
+	const struct ieee80211_channel *sec_chan;
 	int diff;
 
 	switch (channel_type) {
@@ -80,7 +80,7 @@ int cfg80211_set_freq(struct cfg80211_registered_device *rdev,
 		      struct wireless_dev *wdev, int freq,
 		      enum nl80211_channel_type channel_type)
 {
-	struct ieee80211_channel *chan;
+	const struct ieee80211_channel *chan;
 	int result;
 
 	if (wdev && wdev->iftype == NL80211_IFTYPE_MONITOR)
diff --git a/net/wireless/core.h b/net/wireless/core.h
index 26a0a08..48c79d2 100644
--- a/net/wireless/core.h
+++ b/net/wireless/core.h
@@ -302,7 +302,7 @@ int cfg80211_leave_mesh(struct cfg80211_registered_device *rdev,
 /* MLME */
 int __cfg80211_mlme_auth(struct cfg80211_registered_device *rdev,
 			 struct net_device *dev,
-			 struct ieee80211_channel *chan,
+			 const struct ieee80211_channel *chan,
 			 enum nl80211_auth_type auth_type,
 			 const u8 *bssid,
 			 const u8 *ssid, int ssid_len,
@@ -310,7 +310,8 @@ int __cfg80211_mlme_auth(struct cfg80211_registered_device *rdev,
 			 const u8 *key, int key_len, int key_idx,
 			 bool local_state_change);
 int cfg80211_mlme_auth(struct cfg80211_registered_device *rdev,
-		       struct net_device *dev, struct ieee80211_channel *chan,
+		       struct net_device *dev,
+		       const struct ieee80211_channel *chan,
 		       enum nl80211_auth_type auth_type, const u8 *bssid,
 		       const u8 *ssid, int ssid_len,
 		       const u8 *ie, int ie_len,
@@ -318,13 +319,14 @@ int cfg80211_mlme_auth(struct cfg80211_registered_device *rdev,
 		       bool local_state_change);
 int __cfg80211_mlme_assoc(struct cfg80211_registered_device *rdev,
 			  struct net_device *dev,
-			  struct ieee80211_channel *chan,
+			  const struct ieee80211_channel *chan,
 			  const u8 *bssid, const u8 *prev_bssid,
 			  const u8 *ssid, int ssid_len,
 			  const u8 *ie, int ie_len, bool use_mfp,
 			  struct cfg80211_crypto_settings *crypt);
 int cfg80211_mlme_assoc(struct cfg80211_registered_device *rdev,
-			struct net_device *dev, struct ieee80211_channel *chan,
+			struct net_device *dev,
+			const struct ieee80211_channel *chan,
 			const u8 *bssid, const u8 *prev_bssid,
 			const u8 *ssid, int ssid_len,
 			const u8 *ie, int ie_len, bool use_mfp,
@@ -355,7 +357,7 @@ void cfg80211_mlme_unregister_socket(struct wireless_dev *wdev, u32 nlpid);
 void cfg80211_mlme_purge_registrations(struct wireless_dev *wdev);
 int cfg80211_mlme_mgmt_tx(struct cfg80211_registered_device *rdev,
 			  struct net_device *dev,
-			  struct ieee80211_channel *chan, bool offchan,
+			  const struct ieee80211_channel *chan, bool offchan,
 			  enum nl80211_channel_type channel_type,
 			  bool channel_type_valid, unsigned int wait,
 			  const u8 *buf, size_t len, u64 *cookie);
@@ -403,7 +405,7 @@ int cfg80211_change_iface(struct cfg80211_registered_device *rdev,
 			  u32 *flags, struct vif_params *params);
 void cfg80211_process_rdev_events(struct cfg80211_registered_device *rdev);
 
-struct ieee80211_channel *
+const struct ieee80211_channel *
 rdev_freq_to_chan(struct cfg80211_registered_device *rdev,
 		  int freq, enum nl80211_channel_type channel_type);
 int cfg80211_set_freq(struct cfg80211_registered_device *rdev,
diff --git a/net/wireless/debugfs.c b/net/wireless/debugfs.c
index 39765bc..9bb06a2 100644
--- a/net/wireless/debugfs.c
+++ b/net/wireless/debugfs.c
@@ -46,7 +46,7 @@ DEBUGFS_READONLY_FILE(short_retry_limit, 20, "%d",
 DEBUGFS_READONLY_FILE(long_retry_limit, 20, "%d",
 		      wiphy->retry_long);
 
-static int ht_print_chan(struct ieee80211_channel *chan,
+static int ht_print_chan(const struct ieee80211_channel *chan,
 			 char *buf, int buf_size, int offset)
 {
 	if (WARN_ON(offset > buf_size))
diff --git a/net/wireless/ibss.c b/net/wireless/ibss.c
index f33fbb7..92a16a7 100644
--- a/net/wireless/ibss.c
+++ b/net/wireless/ibss.c
@@ -235,7 +235,7 @@ int cfg80211_ibss_wext_join(struct cfg80211_registered_device *rdev,
 	if (!wdev->wext.ibss.channel) {
 		for (band = 0; band < IEEE80211_NUM_BANDS; band++) {
 			struct ieee80211_supported_band *sband;
-			struct ieee80211_channel *chan;
+			const struct ieee80211_channel *chan;
 
 			sband = rdev->wiphy.bands[band];
 			if (!sband)
@@ -294,7 +294,7 @@ int cfg80211_ibss_wext_siwfreq(struct net_device *dev,
 {
 	struct wireless_dev *wdev = dev->ieee80211_ptr;
 	struct cfg80211_registered_device *rdev = wiphy_to_dev(wdev->wiphy);
-	struct ieee80211_channel *chan = NULL;
+	const struct ieee80211_channel *chan = NULL;
 	int err, freq;
 
 	/* call only for ibss! */
@@ -351,7 +351,7 @@ int cfg80211_ibss_wext_giwfreq(struct net_device *dev,
 			       struct iw_freq *freq, char *extra)
 {
 	struct wireless_dev *wdev = dev->ieee80211_ptr;
-	struct ieee80211_channel *chan = NULL;
+	const struct ieee80211_channel *chan = NULL;
 
 	/* call only for ibss! */
 	if (WARN_ON(wdev->iftype != NL80211_IFTYPE_ADHOC))
diff --git a/net/wireless/mlme.c b/net/wireless/mlme.c
index 16881fe..b5fefd0 100644
--- a/net/wireless/mlme.c
+++ b/net/wireless/mlme.c
@@ -396,7 +396,7 @@ EXPORT_SYMBOL(cfg80211_michael_mic_failure);
 /* some MLME handling for userspace SME */
 int __cfg80211_mlme_auth(struct cfg80211_registered_device *rdev,
 			 struct net_device *dev,
-			 struct ieee80211_channel *chan,
+			 const struct ieee80211_channel *chan,
 			 enum nl80211_auth_type auth_type,
 			 const u8 *bssid,
 			 const u8 *ssid, int ssid_len,
@@ -481,7 +481,8 @@ int __cfg80211_mlme_auth(struct cfg80211_registered_device *rdev,
 }
 
 int cfg80211_mlme_auth(struct cfg80211_registered_device *rdev,
-		       struct net_device *dev, struct ieee80211_channel *chan,
+		       struct net_device *dev,
+		       const struct ieee80211_channel *chan,
 		       enum nl80211_auth_type auth_type, const u8 *bssid,
 		       const u8 *ssid, int ssid_len,
 		       const u8 *ie, int ie_len,
@@ -501,7 +502,7 @@ int cfg80211_mlme_auth(struct cfg80211_registered_device *rdev,
 
 int __cfg80211_mlme_assoc(struct cfg80211_registered_device *rdev,
 			  struct net_device *dev,
-			  struct ieee80211_channel *chan,
+			  const struct ieee80211_channel *chan,
 			  const u8 *bssid, const u8 *prev_bssid,
 			  const u8 *ssid, int ssid_len,
 			  const u8 *ie, int ie_len, bool use_mfp,
@@ -568,7 +569,7 @@ int __cfg80211_mlme_assoc(struct cfg80211_registered_device *rdev,
 
 int cfg80211_mlme_assoc(struct cfg80211_registered_device *rdev,
 			struct net_device *dev,
-			struct ieee80211_channel *chan,
+			const struct ieee80211_channel *chan,
 			const u8 *bssid, const u8 *prev_bssid,
 			const u8 *ssid, int ssid_len,
 			const u8 *ie, int ie_len, bool use_mfp,
@@ -734,7 +735,7 @@ void cfg80211_mlme_down(struct cfg80211_registered_device *rdev,
 }
 
 void cfg80211_ready_on_channel(struct net_device *dev, u64 cookie,
-			       struct ieee80211_channel *chan,
+			       const struct ieee80211_channel *chan,
 			       enum nl80211_channel_type channel_type,
 			       unsigned int duration, gfp_t gfp)
 {
@@ -748,7 +749,7 @@ EXPORT_SYMBOL(cfg80211_ready_on_channel);
 
 void cfg80211_remain_on_channel_expired(struct net_device *dev,
 					u64 cookie,
-					struct ieee80211_channel *chan,
+					const struct ieee80211_channel *chan,
 					enum nl80211_channel_type channel_type,
 					gfp_t gfp)
 {
@@ -895,7 +896,7 @@ void cfg80211_mlme_purge_registrations(struct wireless_dev *wdev)
 
 int cfg80211_mlme_mgmt_tx(struct cfg80211_registered_device *rdev,
 			  struct net_device *dev,
-			  struct ieee80211_channel *chan, bool offchan,
+			  const struct ieee80211_channel *chan, bool offchan,
 			  enum nl80211_channel_type channel_type,
 			  bool channel_type_valid, unsigned int wait,
 			  const u8 *buf, size_t len, u64 *cookie)
diff --git a/net/wireless/nl80211.c b/net/wireless/nl80211.c
index 0efa7fd..fcb1c91 100644
--- a/net/wireless/nl80211.c
+++ b/net/wireless/nl80211.c
@@ -294,7 +294,7 @@ static inline void *nl80211hdr_put(struct sk_buff *skb, u32 pid, u32 seq,
 }
 
 static int nl80211_msg_put_channel(struct sk_buff *msg,
-				   struct ieee80211_channel *chan)
+				   const struct ieee80211_channel *chan)
 {
 	NLA_PUT_U32(msg, NL80211_FREQUENCY_ATTR_FREQ,
 		    chan->center_freq);
@@ -561,7 +561,7 @@ static int nl80211_send_wiphy(struct sk_buff *msg, u32 pid, u32 seq, int flags,
 	struct nlattr *nl_modes;
 	struct nlattr *nl_cmds;
 	enum ieee80211_band band;
-	struct ieee80211_channel *chan;
+	const struct ieee80211_channel *chan;
 	struct ieee80211_rate *rate;
 	int i;
 	u16 ifmodes = dev->wiphy.interface_modes;
@@ -3170,7 +3170,7 @@ static int nl80211_trigger_scan(struct sk_buff *skb, struct genl_info *info)
 	struct net_device *dev = info->user_ptr[1];
 	struct cfg80211_scan_request *request;
 	struct cfg80211_ssid *ssid;
-	struct ieee80211_channel *channel;
+	const struct ieee80211_channel *channel;
 	struct nlattr *attr;
 	struct wiphy *wiphy;
 	int err, tmp, n_ssids = 0, n_channels, i;
@@ -3237,7 +3237,7 @@ static int nl80211_trigger_scan(struct sk_buff *skb, struct genl_info *info)
 	if (info->attrs[NL80211_ATTR_SCAN_FREQUENCIES]) {
 		/* user specified, bail out if channel not found */
 		nla_for_each_nested(attr, info->attrs[NL80211_ATTR_SCAN_FREQUENCIES], tmp) {
-			struct ieee80211_channel *chan;
+			const struct ieee80211_channel *chan;
 
 			chan = ieee80211_get_channel(wiphy, nla_get_u32(attr));
 
@@ -3260,7 +3260,7 @@ static int nl80211_trigger_scan(struct sk_buff *skb, struct genl_info *info)
 			if (!wiphy->bands[band])
 				continue;
 			for (j = 0; j < wiphy->bands[band]->n_channels; j++) {
-				struct ieee80211_channel *chan;
+				const struct ieee80211_channel *chan;
 
 				chan = &wiphy->bands[band]->channels[j];
 
@@ -3572,7 +3572,7 @@ static int nl80211_authenticate(struct sk_buff *skb, struct genl_info *info)
 {
 	struct cfg80211_registered_device *rdev = info->user_ptr[0];
 	struct net_device *dev = info->user_ptr[1];
-	struct ieee80211_channel *chan;
+	const struct ieee80211_channel *chan;
 	const u8 *bssid, *ssid, *ie = NULL;
 	int err, ssid_len, ie_len = 0;
 	enum nl80211_auth_type auth_type;
@@ -3745,7 +3745,7 @@ static int nl80211_associate(struct sk_buff *skb, struct genl_info *info)
 	struct cfg80211_registered_device *rdev = info->user_ptr[0];
 	struct net_device *dev = info->user_ptr[1];
 	struct cfg80211_crypto_settings crypto;
-	struct ieee80211_channel *chan;
+	const struct ieee80211_channel *chan;
 	const u8 *bssid, *ssid, *ie = NULL, *prev_bssid = NULL;
 	int err, ssid_len, ie_len = 0;
 	bool use_mfp = false;
@@ -4322,7 +4322,7 @@ static int nl80211_remain_on_channel(struct sk_buff *skb,
 {
 	struct cfg80211_registered_device *rdev = info->user_ptr[0];
 	struct net_device *dev = info->user_ptr[1];
-	struct ieee80211_channel *chan;
+	const struct ieee80211_channel *chan;
 	struct sk_buff *msg;
 	void *hdr;
 	u64 cookie;
@@ -4527,7 +4527,7 @@ static int nl80211_tx_mgmt(struct sk_buff *skb, struct genl_info *info)
 {
 	struct cfg80211_registered_device *rdev = info->user_ptr[0];
 	struct net_device *dev = info->user_ptr[1];
-	struct ieee80211_channel *chan;
+	const struct ieee80211_channel *chan;
 	enum nl80211_channel_type channel_type = NL80211_CHAN_NO_HT;
 	bool channel_type_valid = false;
 	u32 freq;
@@ -5900,9 +5900,10 @@ void nl80211_michael_mic_failure(struct cfg80211_registered_device *rdev,
 	nlmsg_free(msg);
 }
 
-void nl80211_send_beacon_hint_event(struct wiphy *wiphy,
-				    struct ieee80211_channel *channel_before,
-				    struct ieee80211_channel *channel_after)
+void
+nl80211_send_beacon_hint_event(struct wiphy *wiphy,
+			       const struct ieee80211_channel *channel_before,
+			       const struct ieee80211_channel *channel_after)
 {
 	struct sk_buff *msg;
 	void *hdr;
@@ -5960,7 +5961,7 @@ nla_put_failure:
 static void nl80211_send_remain_on_chan_event(
 	int cmd, struct cfg80211_registered_device *rdev,
 	struct net_device *netdev, u64 cookie,
-	struct ieee80211_channel *chan,
+	const struct ieee80211_channel *chan,
 	enum nl80211_channel_type channel_type,
 	unsigned int duration, gfp_t gfp)
 {
@@ -6002,7 +6003,7 @@ static void nl80211_send_remain_on_chan_event(
 
 void nl80211_send_remain_on_channel(struct cfg80211_registered_device *rdev,
 				    struct net_device *netdev, u64 cookie,
-				    struct ieee80211_channel *chan,
+				    const struct ieee80211_channel *chan,
 				    enum nl80211_channel_type channel_type,
 				    unsigned int duration, gfp_t gfp)
 {
@@ -6013,7 +6014,7 @@ void nl80211_send_remain_on_channel(struct cfg80211_registered_device *rdev,
 
 void nl80211_send_remain_on_channel_cancel(
 	struct cfg80211_registered_device *rdev, struct net_device *netdev,
-	u64 cookie, struct ieee80211_channel *chan,
+	u64 cookie, const struct ieee80211_channel *chan,
 	enum nl80211_channel_type channel_type, gfp_t gfp)
 {
 	nl80211_send_remain_on_chan_event(NL80211_CMD_CANCEL_REMAIN_ON_CHANNEL,
diff --git a/net/wireless/nl80211.h b/net/wireless/nl80211.h
index f2af695..3039286 100644
--- a/net/wireless/nl80211.h
+++ b/net/wireless/nl80211.h
@@ -62,8 +62,8 @@ nl80211_michael_mic_failure(struct cfg80211_registered_device *rdev,
 
 void
 nl80211_send_beacon_hint_event(struct wiphy *wiphy,
-			       struct ieee80211_channel *channel_before,
-			       struct ieee80211_channel *channel_after);
+			       const struct ieee80211_channel *channel_before,
+			       const struct ieee80211_channel *channel_after);
 
 void nl80211_send_ibss_bssid(struct cfg80211_registered_device *rdev,
 			     struct net_device *netdev, const u8 *bssid,
@@ -72,12 +72,13 @@ void nl80211_send_ibss_bssid(struct cfg80211_registered_device *rdev,
 void nl80211_send_remain_on_channel(struct cfg80211_registered_device *rdev,
 				    struct net_device *netdev,
 				    u64 cookie,
-				    struct ieee80211_channel *chan,
+				    const struct ieee80211_channel *chan,
 				    enum nl80211_channel_type channel_type,
 				    unsigned int duration, gfp_t gfp);
 void nl80211_send_remain_on_channel_cancel(
 	struct cfg80211_registered_device *rdev, struct net_device *netdev,
-	u64 cookie, struct ieee80211_channel *chan,
+	u64 cookie,
+	const struct ieee80211_channel *chan,
 	enum nl80211_channel_type channel_type, gfp_t gfp);
 
 void nl80211_send_sta_event(struct cfg80211_registered_device *rdev,
diff --git a/net/wireless/reg.c b/net/wireless/reg.c
index 1613080..2768846 100644
--- a/net/wireless/reg.c
+++ b/net/wireless/reg.c
@@ -734,7 +734,7 @@ static const char *reg_initiator_name(enum nl80211_reg_initiator initiator)
 	}
 }
 
-static void chan_reg_rule_print_dbg(struct ieee80211_channel *chan,
+static void chan_reg_rule_print_dbg(const struct ieee80211_channel *chan,
 				    u32 desired_bw_khz,
 				    const struct ieee80211_reg_rule *reg_rule)
 {
@@ -762,7 +762,7 @@ static void chan_reg_rule_print_dbg(struct ieee80211_channel *chan,
 		      power_rule->max_eirp);
 }
 #else
-static void chan_reg_rule_print_dbg(struct ieee80211_channel *chan,
+static void chan_reg_rule_print_dbg(const struct ieee80211_channel *chan,
 				    u32 desired_bw_khz,
 				    const struct ieee80211_reg_rule *reg_rule)
 {
@@ -1034,7 +1034,7 @@ static void reg_process_beacons(struct wiphy *wiphy)
 	wiphy_update_beacon_reg(wiphy);
 }
 
-static bool is_ht40_not_allowed(struct ieee80211_channel *chan)
+static bool is_ht40_not_allowed(const struct ieee80211_channel *chan)
 {
 	if (!chan)
 		return true;
@@ -1052,7 +1052,8 @@ static void reg_process_ht_flags_channel(struct wiphy *wiphy,
 {
 	struct ieee80211_supported_band *sband;
 	struct ieee80211_channel *channel;
-	struct ieee80211_channel *channel_before = NULL, *channel_after = NULL;
+	struct ieee80211_channel *channel_before = NULL;
+	struct ieee80211_channel *channel_after = NULL;
 	unsigned int i;
 
 	assert_cfg80211_lock();
@@ -1865,7 +1866,7 @@ static bool freq_is_chan_12_13_14(u16 freq)
 }
 
 int regulatory_hint_found_beacon(struct wiphy *wiphy,
-				 struct ieee80211_channel *beacon_chan,
+				 const struct ieee80211_channel *beacon_chan,
 				 gfp_t gfp)
 {
 	struct reg_beacon *reg_beacon;
diff --git a/net/wireless/reg.h b/net/wireless/reg.h
index b67d1c3..2a4cf5c 100644
--- a/net/wireless/reg.h
+++ b/net/wireless/reg.h
@@ -35,8 +35,8 @@ int set_regdom(const struct ieee80211_regdomain *rd);
  * set the wiphy->disable_beacon_hints to true.
  */
 int regulatory_hint_found_beacon(struct wiphy *wiphy,
-					struct ieee80211_channel *beacon_chan,
-					gfp_t gfp);
+				 const struct ieee80211_channel *beacon_chan,
+				 gfp_t gfp);
 
 /**
  * regulatory_hint_11d - hints a country IE as a regulatory domain
diff --git a/net/wireless/scan.c b/net/wireless/scan.c
index fbf6f33..756c8e7 100644
--- a/net/wireless/scan.c
+++ b/net/wireless/scan.c
@@ -275,7 +275,7 @@ static int cmp_bss(struct cfg80211_bss *a,
 }
 
 struct cfg80211_bss *cfg80211_get_bss(struct wiphy *wiphy,
-				      struct ieee80211_channel *channel,
+				      const struct ieee80211_channel *channel,
 				      const u8 *bssid,
 				      const u8 *ssid, size_t ssid_len,
 				      u16 capa_mask, u16 capa_val)
@@ -310,7 +310,7 @@ struct cfg80211_bss *cfg80211_get_bss(struct wiphy *wiphy,
 EXPORT_SYMBOL(cfg80211_get_bss);
 
 struct cfg80211_bss *cfg80211_get_mesh(struct wiphy *wiphy,
-				       struct ieee80211_channel *channel,
+				       const struct ieee80211_channel *channel,
 				       const u8 *meshid, size_t meshidlen,
 				       const u8 *meshcfg)
 {
@@ -524,7 +524,7 @@ cfg80211_bss_update(struct cfg80211_registered_device *dev,
 
 struct cfg80211_bss*
 cfg80211_inform_bss(struct wiphy *wiphy,
-		    struct ieee80211_channel *channel,
+		    const struct ieee80211_channel *channel,
 		    const u8 *bssid,
 		    u64 timestamp, u16 capability, u16 beacon_interval,
 		    const u8 *ie, size_t ielen,
diff --git a/net/wireless/wext-sme.c b/net/wireless/wext-sme.c
index 6fffe62..357c9f7 100644
--- a/net/wireless/wext-sme.c
+++ b/net/wireless/wext-sme.c
@@ -125,7 +125,7 @@ int cfg80211_mgd_wext_giwfreq(struct net_device *dev,
 			      struct iw_freq *freq, char *extra)
 {
 	struct wireless_dev *wdev = dev->ieee80211_ptr;
-	struct ieee80211_channel *chan = NULL;
+	const struct ieee80211_channel *chan = NULL;
 
 	/* call only for station! */
 	if (WARN_ON(wdev->iftype != NL80211_IFTYPE_STATION))
-- 
1.7.5.rc3.dirty

^ permalink raw reply related

* [PATCH 1/2] net: use NETIF_F_ALL_TSO for vlan features
From: Shan Wei @ 2011-04-29  5:20 UTC (permalink / raw)
  To: David Miller, netdev, eilong, dm, leedom, mirqus, bhutchings, dm


As Dimitris Michailidis suggested, use NETIF_F_ALL_TSO for vlan_features,
which is a mask, but not hw_features. 

Compile test.


Signed-off-by: Shan Wei <shanwei@cn.fujitsu.com>
---
 drivers/net/bnx2x/bnx2x_main.c     |    2 +-
 drivers/net/cxgb4/cxgb4_main.c     |    2 +-
 drivers/net/cxgb4vf/cxgb4vf_main.c |    2 +-
 3 files changed, 3 insertions(+), 3 deletions(-)

diff --git a/drivers/net/bnx2x/bnx2x_main.c b/drivers/net/bnx2x/bnx2x_main.c
index bfd7ac9..67b1011 100644
--- a/drivers/net/bnx2x/bnx2x_main.c
+++ b/drivers/net/bnx2x/bnx2x_main.c
@@ -9429,7 +9429,7 @@ static int __devinit bnx2x_init_dev(struct pci_dev *pdev,
 		NETIF_F_RXCSUM | NETIF_F_LRO | NETIF_F_HW_VLAN_TX;
 
 	dev->vlan_features = NETIF_F_SG | NETIF_F_IP_CSUM | NETIF_F_IPV6_CSUM |
-		NETIF_F_TSO | NETIF_F_TSO_ECN | NETIF_F_TSO6 | NETIF_F_HIGHDMA;
+		NETIF_F_ALL_TSO | NETIF_F_HIGHDMA;
 
 	dev->features |= dev->hw_features | NETIF_F_HW_VLAN_RX;
 	if (bp->flags & USING_DAC_FLAG)
diff --git a/drivers/net/cxgb4/cxgb4_main.c b/drivers/net/cxgb4/cxgb4_main.c
index bdc868c..d6b1a91 100644
--- a/drivers/net/cxgb4/cxgb4_main.c
+++ b/drivers/net/cxgb4/cxgb4_main.c
@@ -3526,7 +3526,7 @@ static void free_some_resources(struct adapter *adapter)
 }
 
 #define TSO_FLAGS (NETIF_F_TSO | NETIF_F_TSO6 | NETIF_F_TSO_ECN)
-#define VLAN_FEAT (NETIF_F_SG | NETIF_F_IP_CSUM | TSO_FLAGS | \
+#define VLAN_FEAT (NETIF_F_SG | NETIF_F_IP_CSUM | NETIF_F_ALL_TSO | \
 		   NETIF_F_IPV6_CSUM | NETIF_F_HIGHDMA)
 
 static int __devinit init_one(struct pci_dev *pdev,
diff --git a/drivers/net/cxgb4vf/cxgb4vf_main.c b/drivers/net/cxgb4vf/cxgb4vf_main.c
index 8cf9890..b735c52 100644
--- a/drivers/net/cxgb4vf/cxgb4vf_main.c
+++ b/drivers/net/cxgb4vf/cxgb4vf_main.c
@@ -2603,7 +2603,7 @@ static int __devinit cxgb4vf_pci_probe(struct pci_dev *pdev,
 		netdev->hw_features = NETIF_F_SG | TSO_FLAGS |
 			NETIF_F_IP_CSUM | NETIF_F_IPV6_CSUM |
 			NETIF_F_HW_VLAN_TX | NETIF_F_RXCSUM;
-		netdev->vlan_features = NETIF_F_SG | TSO_FLAGS |
+		netdev->vlan_features = NETIF_F_SG | NETIF_F_ALL_TSO |
 			NETIF_F_IP_CSUM | NETIF_F_IPV6_CSUM |
 			NETIF_F_HIGHDMA;
 		netdev->features = netdev->hw_features |
-- 
1.7.3.1

^ permalink raw reply related

* Re: r8169 :  always copying the rx buffer to new skb
From: Eric Dumazet @ 2011-04-29  4:54 UTC (permalink / raw)
  To: John Lumby; +Cc: Francois Romieu, netdev, Ben Hutchings, nic_swsd
In-Reply-To: <4DBA1A9A.3000703@hotmail.com>

Le jeudi 28 avril 2011 à 21:55 -0400, John Lumby a écrit :
> *
>    Conclusions  :
>      . setting copybreak to 16383 seems to be a valid way of avoiding 
> alloc failures when under heavy memory pressure,  although the alloc 
> failures don't seem to cause much trouble in these runs.
>      .  But I am surprised to see how well the copybreak=16383 case runs 
> with no memory pressure,   much better than I saw for the unpatched 
> 2.6.39rc2 earlier on,  and I need to run some more tests to check 
> that.     I will also run same tests on the vanilla 2.6.39.

Doing the copy of data and building an exact size skb has benefit of
providing 'right' skb->truesize (might reduce RCVBUF contention and
avoid backlog drops) and already cached data (hot in cpu caches). Next
'copy' is almost free (L1 cache access)

It all depends on workload. If you want to receive a huge number of
small datagrams, [and feed them to several cpus], results might be
completely different.


>     .    for my next patch submission  -   what should I base it on?     
> Is there a git project which has the "latest" version of r8169.c?    I 
> think it's not  torvalds/linux-2.6.git as fixes to r8169.c in that 
> project go only to 2011-03-21.   Sorry if this is dumb question.

This one ?

http://git.kernel.org/?p=linux/kernel/git/davem/net-next-2.6.git




^ permalink raw reply

* Re: pull request: wireless-next-2.6 2011-04-25
From: David Miller @ 2011-04-29  3:31 UTC (permalink / raw)
  To: padovan-Y3ZbgMPKUGA34EUeqzHoZw
  Cc: Larry.Finger-tQ5ms3gMjBLk1uMJSBkQmQ,
	linville-2XuSBdqkA4R54TAoqtyWWQ,
	linux-wireless-u79uwXL29TY76Z2rM5mHXA,
	netdev-u79uwXL29TY76Z2rM5mHXA
In-Reply-To: <20110429031143.GA2353@joana>

From: "Gustavo F. Padovan" <padovan-Y3ZbgMPKUGA34EUeqzHoZw@public.gmane.org>
Date: Fri, 29 Apr 2011 00:11:43 -0300

> * Larry Finger <Larry.Finger-tQ5ms3gMjBLk1uMJSBkQmQ@public.gmane.org> [2011-04-25 15:55:24 -0500]:
> 
>> Unfortunately, the 64-bit variant of gcc v4.5.1 will miss some of these. I find 
>> I need to compile code on a 32-bit system and using an older compiler to catch 
>> all. Perhaps that explains the error that crept through here.
> 
> That could be a reason, I have gcc 4.5.2 (64-bit). I've built this code many times
> before send pull request and never saw that warning, and it's clearly a bug,
> indeed. 

I would buy this line of reasoning.

Except that I do all of my test builds with 64-bit gcc's, on sparc64
and x86-64.
--
To unsubscribe from this list: send the line "unsubscribe linux-wireless" 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: Is 802.3ad mode in bonding useful ?
From: WeipingPan @ 2011-04-29  3:17 UTC (permalink / raw)
  To: Neil Horman; +Cc: netdev
In-Reply-To: <20110428122102.GB4165@hmsreliant.think-freely.org>

On 04/28/2011 08:21 PM, Neil Horman wrote:
> On Thu, Apr 28, 2011 at 03:33:50PM +0800, WeipingPan wrote:
>> 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.
>>
> Yes, of course its usefull.  For switches which support 802.3ad, this mode
> allows for both peers to understand that the links in the bond are acting as an
> aggregate, which makes it easier to prevent things like inadvertently looped
> back frames, for which the other modes have to have all sorts of hacks to
> prevent.
What is looped back frames here ?
I didn't see any special code to handle looped back frames in other 
modes in bonding,
can you take an example ?

thanks
Weiping Pan

> Neil
>


^ permalink raw reply

* Re: pull request: wireless-next-2.6 2011-04-25
From: Gustavo F. Padovan @ 2011-04-29  3:11 UTC (permalink / raw)
  To: Larry Finger; +Cc: David Miller, linville, linux-wireless, netdev
In-Reply-To: <4DB5DFBC.3070203@lwfinger.net>

* Larry Finger <Larry.Finger@lwfinger.net> [2011-04-25 15:55:24 -0500]:

> On 04/25/2011 03:04 PM, David Miller wrote:
> > From: David Miller<davem@davemloft.net>
> > Date: Mon, 25 Apr 2011 12:58:35 -0700 (PDT)
> >
> >> From: "John W. Linville"<linville@tuxdriver.com>
> >> Date: Mon, 25 Apr 2011 15:30:17 -0400
> >>
> >>> Here is another big batch of updates intended for 2.6.40...
> >>>
> >>> There is the usual huge batch of changes for ath9k, and iwlagn, a bunch
> >>> for ath9k_htc, rt2x00, and ath5k, a few more for mwifiex, and a handful
> >>> of others.  Also included is a big batch of Bluetooth updates as well.
> >>>
> >>> Please let me know if there are problems!
> >>
> >> Pulled, thanks a lot John.
> >
> > I guess watching the build logs for new warnings is too old fashioned
> > for people, and besides Dave will do it for everyone anyways right?
> >
> > And this one is a real bug too. :-/
> >
> > I'll push this out to net-next-2.6 on top of the wireless-next pull,
> > but please be more mindful in the future.
> 
> Unfortunately, the 64-bit variant of gcc v4.5.1 will miss some of these. I find 
> I need to compile code on a 32-bit system and using an older compiler to catch 
> all. Perhaps that explains the error that crept through here.

That could be a reason, I have gcc 4.5.2 (64-bit). I've built this code many times
before send pull request and never saw that warning, and it's clearly a bug,
indeed. 

-- 
Gustavo F. Padovan
http://profusion.mobi

^ permalink raw reply

* Re: [ethtool PATCH 6/6] Update documentation for -u/-U operations
From: Ben Hutchings @ 2011-04-29  2:57 UTC (permalink / raw)
  To: Alexander Duyck
  Cc: davem@davemloft.net, Kirsher, Jeffrey T, netdev@vger.kernel.org
In-Reply-To: <4DB9D0D9.2000401@intel.com>

On Thu, 2011-04-28 at 13:40 -0700, Alexander Duyck wrote:
> On 4/27/2011 11:23 AM, Ben Hutchings wrote:
> > On Thu, 2011-04-21 at 13:40 -0700, Alexander Duyck wrote:
[...]
> >> --- a/ethtool.8.in
> >> +++ b/ethtool.8.in
> >> @@ -42,10 +42,20 @@
> >>   [\\fB\\$1\\fP\ \\fIN\\fP]
> >>   ..
> >>   .\"
> >> +.\"	.BM - same as above but has a mask field for format "[value N [value-mask N]]"
> >> +.\"
> >> +.de BM
> >> +[\\fB\\$1\\fP\ \\fIN\\fP\ [\\fB\\$1\-mask\\fP\ \\fIN\\fP]]
> >
> > You've changed the code to accept 'm' as an alternative to
> > <field>  '-mask', so this should be changed accordingly.
> 
> What would be the preferred way of stating that?  For now I just 
> replaced the \\$1\-mask with m.  However I am assuming that probably 
> isn't the best approach either.  Should I state somewhere that m can be 
> replaced with "field name"-mask?

I think that's reasonable.

[...]
> >> +.BN class-rule-del
> >> +.RB [\  flow-type \ \*(NC
> >> +.RB [ src \ \*(MA\ [ src-mask \ \*(MA]]
> >> +.RB [ dst \ \*(MA\ [ dst-mask \ \*(MA]]
> >> +.BM proto
> >> +.RB [ src-ip \ \*(PA\ [ src-ip-mask \ \*(PA]]
> >> +.RB [ dst-ip \ \*(PA\ [ dst-ip-mask \ \*(PA]]
> >> +.BM tos
> >> +.BM l4proto
> >> +.BM src-port
> >> +.BM dst-port
> >> +.BM spi
> >> +.BM vlan-etype
> >> +.BM vlan
> >> +.BM user-def
> >> +.BN action
> >> +.BN loc
> >> +.RB ]
> >
> > But these options aren't all applicable to all flow-types.
> 
> This is the part that gets messy and I am not sure what the best 
> approach is.  I have more comments on that below.  For now what I am 
> planning to implement to address this is that in the "DESCRIPTION" 
> section below I add a statement to each specifier that has restrictions 
> by stating "Valid for flow-types X, Y, and Z."

OK.

> > [...]
> >> diff --git a/ethtool.c b/ethtool.c
> >> index 421fe20..e65979d 100644
> >> --- a/ethtool.c
> >> +++ b/ethtool.c
> >> @@ -243,20 +243,26 @@ static struct option {
> >>   		"		equal N | weight W0 W1 ...\n" },
> >>       { "-U", "--config-ntuple", MODE_SCLSRULE, "Configure Rx ntuple filters "
> >>   		"and actions",
> >> -		"		{ flow-type tcp4|udp4|sctp4\n"
> >> -		"		  [ src-ip ADDR [src-ip-mask MASK] ]\n"
> >> -		"		  [ dst-ip ADDR [dst-ip-mask MASK] ]\n"
> >> -		"		  [ src-port PORT [src-port-mask MASK] ]\n"
> >> -		"		  [ dst-port PORT [dst-port-mask MASK] ]\n"
> >> -		"		| flow-type ether\n"
> >> -		"		  [ src MAC-ADDR [src-mask MASK] ]\n"
> >> -		"		  [ dst MAC-ADDR [dst-mask MASK] ]\n"
> >> -		"		  [ proto N [proto-mask MASK] ] }\n"
> >> -		"		[ vlan VLAN-TAG [vlan-mask MASK] ]\n"
> >> -		"		[ user-def DATA [user-def-mask MASK] ]\n"
> >> -		"		action N\n" },
> >> +		"		[ class-rule-del %d ] |\n"
> >> +		"		[ flow-type ether|ip4|tcp4|udp4|sctp4|ah4|esp4\n"
> >> +		"			[ src %x:%x:%x:%x:%x:%x [src-mask %x:%x:%x:%x:%x:%x] ]\n"
> >> +		"			[ dst %x:%x:%x:%x:%x:%x [dst-mask %x:%x:%x:%x:%x:%x] ]\n"
> >> +		"			[ proto %d [proto-mask MASK] ]\n"
> >> +		"			[ src-ip %d.%d.%d.%d [src-ip-mask %d.%d.%d.%d] ]\n"
> >> +		"			[ dst-ip %d.%d.%d.%d [dst-ip-mask %d.%d.%d.%d] ]\n"
> >> +		"			[ tos %d [tos-mask %x] ]\n"
> >> +		"			[ l4proto %d [l4proto-mask MASK] ]\n"
> >> +		"			[ src-port %d [src-port-mask %x] ]\n"
> >> +		"			[ dst-port %d [dst-port-mask %x] ]\n"
> >> +		"			[ spi %d [spi-mask %x] ]\n"
> >> +		"			[ vlan-etype %x [vlan-etype-mask %x] ]\n"
> >> +		"			[ vlan %x [vlan-mask %x] ]\n"
> >> +		"			[ user-def %x [user-def-mask %x] ]\n"
> >> +		"			[ action %d ]\n"
> >> +		"			[ loc %d]]\n" },
> > [...]
> >
> > Again, it's not clear which options apply to which flow-types, and the
> > 'm' shortcut is not documented.
> 
> The 'm' part I agree with 100%, however the flow types are going to 
> become kinda hairy using that approach.  You basically end up with 
> something like this:
[...]

Yes, I see the problem.

> As you can see it will be a bit oversized to go through and specify 
> which flow-type options support what fields.  If that is what you want I 
> can implement it that way but for now I would prefer calling out the 
> flow-type limitations of the fields in the "DESCRIPTION" portion of the 
> man page.

In fact, even with this patch, the help for -U is pretty oversized.  It
might be better to replace the list of field names with '...' here and
only list them in full in the man page.

Ben.

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


^ permalink raw reply

* Re: [PATCH 08/13] netvm: Allow skb allocation to use PFMEMALLOC reserves
From: NeilBrown @ 2011-04-29  2:55 UTC (permalink / raw)
  To: Mel Gorman; +Cc: Linux-MM, Linux-Netdev, LKML, David Miller, Peter Zijlstra
In-Reply-To: <20110428111854.GV4658@suse.de>

On Thu, 28 Apr 2011 12:18:54 +0100 Mel Gorman <mgorman@suse.de> wrote:

> On Thu, Apr 28, 2011 at 08:47:55PM +1000, NeilBrown wrote:
> > On Thu, 28 Apr 2011 11:05:06 +0100 Mel Gorman <mgorman@suse.de> wrote:
> > 
> > > On Thu, Apr 28, 2011 at 04:19:33PM +1000, NeilBrown wrote:
> > > > 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?
> > > > 
> > > 
> > > You're not missing anything.
> > > 
> > > >From the context of __netdev_alloc_page, we do not know if the skb
> > > is suitable for marking pfmemalloc or not (we don't have SKB_ALLOC_RX
> > > flag for example that __alloc_skb has). The reserves are potentially
> > > being dipped into for an unsuitable packet but it gets dropped in
> > > __netif_receive_skb() and the memory is returned. If we mark the skb
> > > pfmemalloc as a result of __netdev_alloc_page using a reserve page, the
> > > packets would not get dropped as expected.
> > > 
> > 
> > The only code in __netif_receive_skb that seems to drop packets is
> > 
> > +	if (skb_pfmemalloc(skb) && !skb_pfmemalloc_protocol(skb))
> > +		goto drop;
> > +
> > 
> > which requires that the skb have pfmemalloc set before it will be dropped.
> > 
> 
> Yes, I only wanted to drop the packet if we were under pressure
> when skb was allocated. If we hit pressure between when skb was
> allocated and when __netdev_alloc_page is called, then the PFMEMALLOC
> reserves may be used for packet receive unnecessarily but the next skb
> allocation that grows slab will have the flag set appropriately. There
> is a window during which we use reserves where we did not have to
> but it's limited. Again, the throttling if pfmemalloc reserves gets too
> depleted comes into play.

I don't find this very convincing...
It seems inconsistent that you are doing precise accounting inside slab so
that you know which object used reserved memory and which did not, yet you
get sloppy with the accounting of whole pages on network receive.

Is there a clear upper bound on how many reserve pages could slip into
non-reserve skbs before skbs start getting the pfmalloc flag set?

I just think it is safer to mark an skb as pfmalloc if any part of the memory
associated with it came from reserves.

Also I find the throttling argument hard to reason about.  Certainly
some things get throttles, but incoming packets don't...

I'm certainly not saying that the code is clearly wrong, but I'm having
trouble convincing myself that it is clearly right (or at least 'safe').

> 
> > Actually ... I'm expecting to find code that says:
> >    if (skb_pfmalloc(skb) && !sock_flag(sk, SOCK_MEMALLOC))
> > 	drop_packet();
> > 
> > but I cannot find it.  Where is the code that discard pfmalloc packets for
> > non-memalloc sockets?
> > 
> > I can see similar code in sk_filter but that doesn't drop the packet, it just
> > avoids filtering it.
> > 
> 
> hmm, if sk_filter is returning -ENOMEM then things like
> sock_queue_rcv_skb() return error and the skb does not get queued and I
> expected it to get dropped. What did I miss?
> 

Just that I was making incorrect assumptions about code that I wasn't
familiar with.
Make sense now.

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: [PATCH 2/2] tg3: Add code to allow ethtool to enable/disable loopback.
From: Matt Carlson @ 2011-04-29  2:46 UTC (permalink / raw)
  To: Mahesh Bandewar
  Cc: Matthew Carlson, David Miller, netdev, Michael Chan,
	Ben Hutchings, Micha? Miros?aw
In-Reply-To: <BANLkTimA9YGFKjB0_UMsAJeSGEbKGoFJXQ@mail.gmail.com>

On Thu, Apr 28, 2011 at 06:42:02PM -0700, Mahesh Bandewar wrote:
> >> + ? ? spin_unlock_bh(&tp->lock);
> >> +
> >> + ? ? return err;
> >> +}
> >> +
> >> ?static inline void tg3_set_mtu(struct net_device *dev, struct tg3 *tp,
> >> ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?int new_mtu)
> >> ?{
> >> @@ -15028,6 +15055,7 @@ static const struct net_device_ops tg3_netdev_ops = {
> >> ? ? ? .ndo_tx_timeout ? ? ? ? = tg3_tx_timeout,
> >> ? ? ? .ndo_change_mtu ? ? ? ? = tg3_change_mtu,
> >> ? ? ? .ndo_fix_features ? ? ? = tg3_fix_features,
> >> + ? ? .ndo_set_features ? ? ? = tg3_set_features,
> >> ?#ifdef CONFIG_NET_POLL_CONTROLLER
> >> ? ? ? .ndo_poll_controller ? ?= tg3_poll_controller,
> >> ?#endif
> >> @@ -15044,6 +15072,7 @@ static const struct net_device_ops tg3_netdev_ops_dma_bug = {
> >> ? ? ? .ndo_do_ioctl ? ? ? ? ? = tg3_ioctl,
> >> ? ? ? .ndo_tx_timeout ? ? ? ? = tg3_tx_timeout,
> >> ? ? ? .ndo_change_mtu ? ? ? ? = tg3_change_mtu,
> >> + ? ? .ndo_set_features ? ? ? = tg3_set_features,
> >> ?#ifdef CONFIG_NET_POLL_CONTROLLER
> >> ? ? ? .ndo_poll_controller ? ?= tg3_poll_controller,
> >> ?#endif
> >> @@ -15241,6 +15270,9 @@ static int __devinit tg3_init_one(struct pci_dev *pdev,
> >> ? ? ? dev->features |= hw_features;
> >> ? ? ? dev->vlan_features |= hw_features;
> >>
> >> + ? ? /* Add the loopback capability */
> >> + ? ? dev->hw_features |= NETIF_F_LOOPBACK;
> >
> > Not all tg3 devices can do MAC loopback. ?I'd suggest qualifying this
> > with:
> >
> > ? ? ? ? ? ? ? ?if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5780 ||
> > ? ? ? ? ? ? ? ? ? ?(tp->tg3_flags & TG3_FLAG_CPMU_PRESENT))
> >
> > But that will exclude a lot of our newer devices. ?Does it matter what
> > type of loopback is used? ?Newer devices prefer internal phy loopback
> > over MAC loopback.
> >
> As long as device supports some sort of loopback, we should be setting
> this capability and move this logic (or similar) to set_features() and
> choose the method that is supported. Since several devices support
> loopback at various levels, to keep it consistent, we should be
> setting the loopback closest to the host. So can I simply set the
> int-phy loopback in the else part of the above 'provided if' or would
> need other logic? or in other words -
> 
>  if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5780 ||
> (tp->tg3_flags & TG3_FLAG_CPMU_PRESENT))
>     supported_mode = MAC;
> else
>     supported_mode = INTPHY;
> 
> if (supported_mode == MAC)
>     cur_mode = tr32(MAC_MODE);
> else
>     tg3_readphy(tp, MII_BMCR, &cur_mode);
> 
> Would something like this work?

That might be where we want to end up, but it'll be some work to get
there.  Maybe it makes sense to just keep MAC loopback mode for now and
only enable it for a subset of devices.  Adding phy loopback mode sounds
like it will require some surgery.


^ permalink raw reply

* Re: [PATCH 2/2] tg3: Add code to allow ethtool to enable/disable loopback.
From: Matt Carlson @ 2011-04-29  2:23 UTC (permalink / raw)
  To: Mahesh Bandewar
  Cc: David Miller, Matthew Carlson, netdev, Michael Chan,
	Ben Hutchings, Micha? Miros?aw
In-Reply-To: <1304033599-8395-3-git-send-email-maheshb@google.com>

On Thu, Apr 28, 2011 at 04:33:19PM -0700, Mahesh Bandewar wrote:
> ---
>  drivers/net/tg3.c |   32 ++++++++++++++++++++++++++++++++
>  1 files changed, 32 insertions(+), 0 deletions(-)
> 
> diff --git a/drivers/net/tg3.c b/drivers/net/tg3.c
> index fa57e3d..208884d 100644
> --- a/drivers/net/tg3.c
> +++ b/drivers/net/tg3.c
> @@ -6319,6 +6319,33 @@ static u32 tg3_fix_features(struct net_device *dev, u32 features)
>  	return features;
>  }
>  
> +static int tg3_set_features(struct net_device *dev, u32 features)
> +{
> +	struct tg3 *tp = netdev_priv(dev);
> +	u32 cur_mode = 0;
> +	int err = 0;
> +
> +	spin_lock_bh(&tp->lock);
> +	cur_mode = tr32(MAC_MODE);
> +
> +	if (features & NETIF_F_LOOPBACK) {
> +		/* Enable internal MAC loopback mode */
> +		tw32(MAC_MODE, cur_mode | MAC_MODE_PORT_INT_LPBACK);

I didn't notice this before, but you will want to clear
MAC_MODE_HALF_DUPLEX when going into loopback mode.  You won't get
packets back if you happen to negotiate to HD.



^ permalink raw reply

* linux-next: manual merge of the suspend tree with the net tree
From: Stephen Rothwell @ 2011-04-29  2:05 UTC (permalink / raw)
  To: Rafael J. Wysocki
  Cc: linux-next, linux-kernel, Eric Dumazet, David Miller, netdev

Hi Rafael,

Today's linux-next merge of the suspend tree got a conflict in
arch/x86/Kconfig between commit 0a14842f5a3c ("net: filter: Just In Time
compiler for x86-64") from the  tree and commit d9f1ce017fcf ("PM: Remove
sysdev suspend, resume and shutdown operations") from the suspend tree.

Just context changes.  I fixed it up (see below) and can carry the fix as
necessary.
-- 
Cheers,
Stephen Rothwell                    sfr@canb.auug.org.au

diff --cc arch/x86/Kconfig
index 92d07bd,140e254..0000000
--- a/arch/x86/Kconfig
+++ b/arch/x86/Kconfig
@@@ -71,8 -71,6 +71,7 @@@ config X8
  	select GENERIC_IRQ_SHOW
  	select IRQ_FORCED_THREADING
  	select USE_GENERIC_SMP_HELPERS if SMP
- 	select ARCH_NO_SYSDEV_OPS
 +	select HAVE_BPF_JIT if X86_64
  
  config INSTRUCTION_DECODER
  	def_bool (KPROBES || PERF_EVENTS)

^ permalink raw reply

* Re: r8169 :  always copying the rx buffer to new skb
From: John Lumby @ 2011-04-29  1:55 UTC (permalink / raw)
  To: Francois Romieu; +Cc: netdev, Ben Hutchings, nic_swsd
In-Reply-To: <20110427203544.GB19708@electric-eye.fr.zoreil.com>

On 04/27/11 16:35, Francois Romieu wrote:
>
> The patch mixes different changes. Please avoid it.

Sorry about that,  I'll rewrite with only the changes absolutely needed 
for avoiding memcpy (and maybe the setting of num_rx_bufs ring param?)

> Your MUA damaged the patch. Documentation/SubmittingPatches
> could help if you have not read it yet.

I see some truncation happened,  will fix that in next submission

> The patch makes some gratuitous changes which needlessly
> increase the differences (dirty_xy rename for instance).

will revert those

> A set_ringparam() method which does nothing until open()
> is used does not exactly ring like "least surprize behavior"
> to me.

Please see questions below

> The behavior under memory pressure is still unknown.

I have run some initial tests with memory pressure  -  the pressure 
provided by running n concurrent memory hogs,  each of which loops 
endlessly on allocating 1024 blocks of 1MB bytes each,  writing 
something into all bytes in each block,   then freeing each block,   
then repeating.  result:

*
copybreak        numhogs     workload throughput  swapping alloc 
failures?     dropped packets
                                    
Mb/sec                                   or other NIC err reports?

  16383              0              1043            none           
no                 no
     64              0              1086              |            
no                 no

  16383              1               935           moderate        
no                 no
     64              1               902              |            
no                 no

  16383              2               854           heavy           
no                 no
     64              2               851              |           yes, 
many           no

  16383              3               817           very heavy      
no                 no
     64              3            did not attempt     |
*
   Conclusions  :
     . setting copybreak to 16383 seems to be a valid way of avoiding 
alloc failures when under heavy memory pressure,  although the alloc 
failures don't seem to cause much trouble in these runs.
     .  But I am surprised to see how well the copybreak=16383 case runs 
with no memory pressure,   much better than I saw for the unpatched 
2.6.39rc2 earlier on,  and I need to run some more tests to check 
that.     I will also run same tests on the vanilla 2.6.39.

> I am mildly convinced by the implementation.
>

Thanks for all comments.

I do have a couple more questions:

    .    for my next patch submission  -   what should I base it on?     
Is there a git project which has the "latest" version of r8169.c?    I 
think it's not  torvalds/linux-2.6.git as fixes to r8169.c in that 
project go only to 2011-03-21.   Sorry if this is dumb question.
    .     regarding setting the ring param  -  I understand your comment 
but is it safe to close and open the NIC when called by ethtool 
ioctl?        Would some locking be needed?
    .     and again on the ring params  -   what is the minimum and 
maximum valid value for num rx bufs and separately for num  tx bufs   
that the r8169 supports?


Cheers,   John Lumby

^ permalink raw reply

* Re: [PATCH 2/2] tg3: Add code to allow ethtool to enable/disable loopback.
From: Mahesh Bandewar @ 2011-04-29  1:42 UTC (permalink / raw)
  To: Matt Carlson
  Cc: David Miller, netdev, Michael Chan, Ben Hutchings,
	Micha? Miros?aw
In-Reply-To: <20110429002855.GC19665@mcarlson.broadcom.com>

On Thu, Apr 28, 2011 at 5:28 PM, Matt Carlson <mcarlson@broadcom.com> wrote:
> On Thu, Apr 28, 2011 at 04:33:19PM -0700, Mahesh Bandewar wrote:
>> ---
>>  drivers/net/tg3.c |   32 ++++++++++++++++++++++++++++++++
>>  1 files changed, 32 insertions(+), 0 deletions(-)
>>
>> diff --git a/drivers/net/tg3.c b/drivers/net/tg3.c
>> index fa57e3d..208884d 100644
>> --- a/drivers/net/tg3.c
>> +++ b/drivers/net/tg3.c
>> @@ -6319,6 +6319,33 @@ static u32 tg3_fix_features(struct net_device *dev, u32 features)
>>       return features;
>>  }
>>
>> +static int tg3_set_features(struct net_device *dev, u32 features)
>> +{
>> +     struct tg3 *tp = netdev_priv(dev);
>> +     u32 cur_mode = 0;
>> +     int err = 0;
>> +
>> +     spin_lock_bh(&tp->lock);
>> +     cur_mode = tr32(MAC_MODE);
>> +
>> +     if (features & NETIF_F_LOOPBACK) {
>> +             /* Enable internal MAC loopback mode */
>> +             tw32(MAC_MODE, cur_mode | MAC_MODE_PORT_INT_LPBACK);
>> +             netif_carrier_on(tp->dev);
>> +             netdev_info(dev, "Internal MAC loopback mode enabled.\n");
>> +     } else {
>> +             /* Disable internal MAC loopback mode */
>> +             tw32(MAC_MODE, cur_mode & ~MAC_MODE_PORT_INT_LPBACK);
>> +             /* Force link status check */
>> +             if (netif_running(dev))
>> +                     tg3_setup_phy(tp, 1);
>> +             netdev_info(dev, "Internal MAC loopback mode disabled.\n");
>> +     }
>
> I think we should be checking netif_running() before touching the
> hardware at all.  It might be in a low power state.
>
makes sense. I'll change that.

> Also, wouldn't it be better to verify this particular bit changed before
> doing any of these operations?
>
Right! Since netdev infrastructure initiates ndo_set_features() only
when the feature-set is changed, and loopback is the only thing that
is set; I lazily ignored that. But in future additional features could
be set and it's not going to hurt checking before setting that bit.

>> +     spin_unlock_bh(&tp->lock);
>> +
>> +     return err;
>> +}
>> +
>>  static inline void tg3_set_mtu(struct net_device *dev, struct tg3 *tp,
>>                              int new_mtu)
>>  {
>> @@ -15028,6 +15055,7 @@ static const struct net_device_ops tg3_netdev_ops = {
>>       .ndo_tx_timeout         = tg3_tx_timeout,
>>       .ndo_change_mtu         = tg3_change_mtu,
>>       .ndo_fix_features       = tg3_fix_features,
>> +     .ndo_set_features       = tg3_set_features,
>>  #ifdef CONFIG_NET_POLL_CONTROLLER
>>       .ndo_poll_controller    = tg3_poll_controller,
>>  #endif
>> @@ -15044,6 +15072,7 @@ static const struct net_device_ops tg3_netdev_ops_dma_bug = {
>>       .ndo_do_ioctl           = tg3_ioctl,
>>       .ndo_tx_timeout         = tg3_tx_timeout,
>>       .ndo_change_mtu         = tg3_change_mtu,
>> +     .ndo_set_features       = tg3_set_features,
>>  #ifdef CONFIG_NET_POLL_CONTROLLER
>>       .ndo_poll_controller    = tg3_poll_controller,
>>  #endif
>> @@ -15241,6 +15270,9 @@ static int __devinit tg3_init_one(struct pci_dev *pdev,
>>       dev->features |= hw_features;
>>       dev->vlan_features |= hw_features;
>>
>> +     /* Add the loopback capability */
>> +     dev->hw_features |= NETIF_F_LOOPBACK;
>
> Not all tg3 devices can do MAC loopback.  I'd suggest qualifying this
> with:
>
>                if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5780 ||
>                    (tp->tg3_flags & TG3_FLAG_CPMU_PRESENT))
>
> But that will exclude a lot of our newer devices.  Does it matter what
> type of loopback is used?  Newer devices prefer internal phy loopback
> over MAC loopback.
>
As long as device supports some sort of loopback, we should be setting
this capability and move this logic (or similar) to set_features() and
choose the method that is supported. Since several devices support
loopback at various levels, to keep it consistent, we should be
setting the loopback closest to the host. So can I simply set the
int-phy loopback in the else part of the above 'provided if' or would
need other logic? or in other words -

 if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5780 ||
(tp->tg3_flags & TG3_FLAG_CPMU_PRESENT))
    supported_mode = MAC;
else
    supported_mode = INTPHY;

if (supported_mode == MAC)
    cur_mode = tr32(MAC_MODE);
else
    tg3_readphy(tp, MII_BMCR, &cur_mode);

Would something like this work?

Thanks,
--mahesh..

>>       if (tp->pci_chip_rev_id == CHIPREV_ID_5705_A1 &&
>>           !tg3_flag(tp, TSO_CAPABLE) &&
>>           !(tr32(TG3PCI_PCISTATE) & PCISTATE_BUS_SPEED_HIGH)) {
>> --
>> 1.7.3.1
>>
>>
>
>

^ permalink raw reply

* [PATCHv2 2/2] macvlan: Send frames to AF_PACKET sockets attached to lowerdev
From: David Ward @ 2011-04-29  0:22 UTC (permalink / raw)
  To: netdev; +Cc: David Ward, Patrick McHardy
In-Reply-To: <1304036552-1589-1-git-send-email-david.ward@ll.mit.edu>

In bridge mode, unicast frames can be forwarded directly between macvlan
interfaces attached to the same lowerdev without calling dev_queue_xmit.
These frames should still be sent to any AF_PACKET sockets (network taps)
attached to the lowerdev.

Signed-off-by: David Ward <david.ward@ll.mit.edu>
---
 drivers/net/macvlan.c |    5 ++++-
 1 files changed, 4 insertions(+), 1 deletions(-)

diff --git a/drivers/net/macvlan.c b/drivers/net/macvlan.c
index 3ad5425..25c7632 100644
--- a/drivers/net/macvlan.c
+++ b/drivers/net/macvlan.c
@@ -238,7 +238,10 @@ static int macvlan_queue_xmit(struct sk_buff *skb, struct net_device *dev)
 		dest = macvlan_hash_lookup(port, eth->h_dest);
 		if (dest && dest->mode == MACVLAN_MODE_BRIDGE) {
 			unsigned int length = skb->len + ETH_HLEN;
-			int ret = dest->forward(dest->dev, skb);
+			int ret = NET_RX_DROP;
+
+			dev_queue_xmit_nit(skb, vlan->lowerdev);
+			ret = dest->forward(dest->dev, skb);
 			macvlan_count_rx(dest, length,
 					 ret == NET_RX_SUCCESS, 0);
 
-- 
1.7.4.4


^ permalink raw reply related

* [PATCHv2 0/2] Resolve packet capturing on macvlan lowerdev
From: David Ward @ 2011-04-29  0:22 UTC (permalink / raw)
  To: netdev; +Cc: David Ward, Patrick McHardy

Change in v2: Declare variables in basic block before other code appears

The following two patches address situations where macvlan interfaces on 
the same lowerdev are created inside separate containers/namespaces, and 
traffic between these interfaces needs to be captured by monitoring the 
lowerdev outside the containers/namespaces using tcpdump or Wireshark. 
The only case where this doesn't work now is for unicast frames when the 
macvlan interfaces are operating in bridge mode; this fixes that case.

Should the dev_queue_xmit_nit function be renamed to something more 
meaningful, which would indicate its role in sending outgoing frames to 
AF_PACKET sockets? It is currently a misnomer: this function used to be 
invoked by dev_queue_xmit, but that is no longer the case.

Thanks,

David

David Ward (2):
  net: Export dev_queue_xmit_nit for use by macvlan driver
  macvlan: Send frames to AF_PACKET sockets attached to lowerdev

 drivers/net/macvlan.c     |    5 ++++-
 include/linux/netdevice.h |    2 ++
 net/core/dev.c            |   14 +++++++++-----
 3 files changed, 15 insertions(+), 6 deletions(-)

-- 
1.7.4.4


^ permalink raw reply

* [PATCHv2 1/2] net: Export dev_queue_xmit_nit for use by macvlan driver
From: David Ward @ 2011-04-29  0:22 UTC (permalink / raw)
  To: netdev; +Cc: David Ward, Patrick McHardy
In-Reply-To: <1304036552-1589-1-git-send-email-david.ward@ll.mit.edu>

Export dev_queue_xmit_nit for use by the macvlan virtual network device
driver. Also, use 'dev' instead of 'skb->dev' in this function.

Signed-off-by: David Ward <david.ward@ll.mit.edu>
---
 include/linux/netdevice.h |    2 ++
 net/core/dev.c            |   14 +++++++++-----
 2 files changed, 11 insertions(+), 5 deletions(-)

diff --git a/include/linux/netdevice.h b/include/linux/netdevice.h
index cb8178a..b63e517 100644
--- a/include/linux/netdevice.h
+++ b/include/linux/netdevice.h
@@ -2099,6 +2099,8 @@ extern int		dev_hard_start_xmit(struct sk_buff *skb,
 					    struct netdev_queue *txq);
 extern int		dev_forward_skb(struct net_device *dev,
 					struct sk_buff *skb);
+extern void		dev_queue_xmit_nit(struct sk_buff *skb,
+					   struct net_device *dev);
 
 extern int		netdev_budget;
 
diff --git a/net/core/dev.c b/net/core/dev.c
index 3bbb4c2..b15622e 100644
--- a/net/core/dev.c
+++ b/net/core/dev.c
@@ -1521,11 +1521,13 @@ static inline int deliver_skb(struct sk_buff *skb,
 }
 
 /*
- *	Support routine. Sends outgoing frames to any network
- *	taps currently in use.
+ * dev_queue_xmit_nit - send outgoing frame to AF_PACKET sockets
+ *
+ * @skb: buffer to send
+ * @dev: network device that AF_PACKET sockets are attached to (if any)
  */
 
-static void dev_queue_xmit_nit(struct sk_buff *skb, struct net_device *dev)
+void dev_queue_xmit_nit(struct sk_buff *skb, struct net_device *dev)
 {
 	struct packet_type *ptype;
 	struct sk_buff *skb2 = NULL;
@@ -1540,7 +1542,8 @@ static void dev_queue_xmit_nit(struct sk_buff *skb, struct net_device *dev)
 		    (ptype->af_packet_priv == NULL ||
 		     (struct sock *)ptype->af_packet_priv != skb->sk)) {
 			if (pt_prev) {
-				deliver_skb(skb2, pt_prev, skb->dev);
+				atomic_inc(&skb2->users);
+				pt_prev->func(skb2, dev, pt_prev, dev);
 				pt_prev = ptype;
 				continue;
 			}
@@ -1573,9 +1576,10 @@ static void dev_queue_xmit_nit(struct sk_buff *skb, struct net_device *dev)
 		}
 	}
 	if (pt_prev)
-		pt_prev->func(skb2, skb->dev, pt_prev, skb->dev);
+		pt_prev->func(skb2, dev, pt_prev, dev);
 	rcu_read_unlock();
 }
+EXPORT_SYMBOL(dev_queue_xmit_nit);
 
 /* netif_setup_tc - Handle tc mappings on real_num_tx_queues change
  * @dev: Network device
-- 
1.7.4.4


^ permalink raw reply related

* Re: [PATCH 2/2] tg3: Add code to allow ethtool to enable/disable loopback.
From: Matt Carlson @ 2011-04-29  0:28 UTC (permalink / raw)
  To: Mahesh Bandewar
  Cc: David Miller, Matthew Carlson, netdev, Michael Chan,
	Ben Hutchings, Micha? Miros?aw
In-Reply-To: <1304033599-8395-3-git-send-email-maheshb@google.com>

On Thu, Apr 28, 2011 at 04:33:19PM -0700, Mahesh Bandewar wrote:
> ---
>  drivers/net/tg3.c |   32 ++++++++++++++++++++++++++++++++
>  1 files changed, 32 insertions(+), 0 deletions(-)
> 
> diff --git a/drivers/net/tg3.c b/drivers/net/tg3.c
> index fa57e3d..208884d 100644
> --- a/drivers/net/tg3.c
> +++ b/drivers/net/tg3.c
> @@ -6319,6 +6319,33 @@ static u32 tg3_fix_features(struct net_device *dev, u32 features)
>  	return features;
>  }
>  
> +static int tg3_set_features(struct net_device *dev, u32 features)
> +{
> +	struct tg3 *tp = netdev_priv(dev);
> +	u32 cur_mode = 0;
> +	int err = 0;
> +
> +	spin_lock_bh(&tp->lock);
> +	cur_mode = tr32(MAC_MODE);
> +
> +	if (features & NETIF_F_LOOPBACK) {
> +		/* Enable internal MAC loopback mode */
> +		tw32(MAC_MODE, cur_mode | MAC_MODE_PORT_INT_LPBACK);
> +		netif_carrier_on(tp->dev);
> +		netdev_info(dev, "Internal MAC loopback mode enabled.\n");
> +	} else {
> +		/* Disable internal MAC loopback mode */
> +		tw32(MAC_MODE, cur_mode & ~MAC_MODE_PORT_INT_LPBACK);
> +		/* Force link status check */
> +		if (netif_running(dev))
> +			tg3_setup_phy(tp, 1);
> +		netdev_info(dev, "Internal MAC loopback mode disabled.\n");
> +	}

I think we should be checking netif_running() before touching the
hardware at all.  It might be in a low power state.

Also, wouldn't it be better to verify this particular bit changed before
doing any of these operations?

> +	spin_unlock_bh(&tp->lock);
> +
> +	return err;
> +}
> +
>  static inline void tg3_set_mtu(struct net_device *dev, struct tg3 *tp,
>  			       int new_mtu)
>  {
> @@ -15028,6 +15055,7 @@ static const struct net_device_ops tg3_netdev_ops = {
>  	.ndo_tx_timeout		= tg3_tx_timeout,
>  	.ndo_change_mtu		= tg3_change_mtu,
>  	.ndo_fix_features	= tg3_fix_features,
> +	.ndo_set_features	= tg3_set_features,
>  #ifdef CONFIG_NET_POLL_CONTROLLER
>  	.ndo_poll_controller	= tg3_poll_controller,
>  #endif
> @@ -15044,6 +15072,7 @@ static const struct net_device_ops tg3_netdev_ops_dma_bug = {
>  	.ndo_do_ioctl		= tg3_ioctl,
>  	.ndo_tx_timeout		= tg3_tx_timeout,
>  	.ndo_change_mtu		= tg3_change_mtu,
> +	.ndo_set_features	= tg3_set_features,
>  #ifdef CONFIG_NET_POLL_CONTROLLER
>  	.ndo_poll_controller	= tg3_poll_controller,
>  #endif
> @@ -15241,6 +15270,9 @@ static int __devinit tg3_init_one(struct pci_dev *pdev,
>  	dev->features |= hw_features;
>  	dev->vlan_features |= hw_features;
>  
> +	/* Add the loopback capability */
> +	dev->hw_features |= NETIF_F_LOOPBACK;

Not all tg3 devices can do MAC loopback.  I'd suggest qualifying this
with:

		if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5780 ||
		    (tp->tg3_flags & TG3_FLAG_CPMU_PRESENT))

But that will exclude a lot of our newer devices.  Does it matter what
type of loopback is used?  Newer devices prefer internal phy loopback
over MAC loopback.

>  	if (tp->pci_chip_rev_id == CHIPREV_ID_5705_A1 &&
>  	    !tg3_flag(tp, TSO_CAPABLE) &&
>  	    !(tr32(TG3PCI_PCISTATE) & PCISTATE_BUS_SPEED_HIGH)) {
> -- 
> 1.7.3.1
> 
> 


^ permalink raw reply

* Re: A race in register_netdevice()
From: Stephen Hemminger @ 2011-04-28 23:52 UTC (permalink / raw)
  To: Kalle Valo
  Cc: netdev-u79uwXL29TY76Z2rM5mHXA,
	linux-wireless-u79uwXL29TY76Z2rM5mHXA
In-Reply-To: <87y62ugg0a.fsf-5ukZ45wKbUHoml4zekdYB16hYfS7NtTn@public.gmane.org>

On Fri, 29 Apr 2011 01:36:37 +0300
Kalle Valo <kvalo-BkwN83ws05HQT0dZR+AlfA@public.gmane.org> wrote:

> Hi,
> 
> there seems to be a race in register_netdevice(), which is reported here:
> 
> https://bugzilla.kernel.org/show_bug.cgi?id=15606
> 
> This is visible at least with flimflam and ath6kl. Basically what
> happens is this:
> 
> Apr 29 00:21:35 roska flimflamd[2598]: src/udev.c:add_net_device() 
> Apr 29 00:21:35 roska flimflamd[2598]: connman_inet_ifname: SIOCGIFNAME(index
> 4): No such device
> Apr 29 00:21:45 roska flimflamd[2598]: src/rtnl.c:rtnl_message() buf
> 0xbfefda3c len 1004
> Apr 29 00:21:45 roska flimflamd[2598]: src/rtnl.c:rtnl_message()
> NEWLINK len 1004 type 16 flags 0x0000 seq 0
> 
> (ignore the 10 s delay, I added that to reproduce the issue easily)
> 
> There are two ways to fix this, first is to move kobject registration
> after the call to list_netdevice():
> 
> --- a/net/core/dev.c
> +++ b/net/core/dev.c
> @@ -5425,11 +5425,6 @@ int register_netdevice(struct net_device *dev)
>         if (ret)
>                 goto err_uninit;
>  
> -       ret = netdev_register_kobject(dev);
> -       if (ret)
> -               goto err_uninit;
> -       dev->reg_state = NETREG_REGISTERED;
> -
>         netdev_update_features(dev);
>  
>         /*
> @@ -5443,6 +5438,11 @@ int register_netdevice(struct net_device *dev)
>         dev_hold(dev);
>         list_netdevice(dev);
>  
> +       ret = netdev_register_kobject(dev);
> +       if (ret)
> +               goto err_uninit;
> +       dev->reg_state = NETREG_REGISTERED;
> +
>         /* Notify protocols, that a new device appeared. */
>         ret = call_netdevice_notifiers(NETDEV_REGISTER, dev);
>         ret = notifier_to_errno(ret);
> 
> Other option, noticed by Jouni Malinen, is to take rtnl for
> SIOCGIFNAME. For some reason it's currently unprotected:
> 
> --- a/net/core/dev.c
> +++ b/net/core/dev.c
> @@ -4917,8 +4917,12 @@ int dev_ioctl(struct net *net, unsigned int
> cmd, void __user *arg)
>           rtnl_unlock();
>                 return ret;
>                 }
> -               if (cmd == SIOCGIFNAME)
> -                  return dev_ifname(net, (struct ifreq __user *)arg);
> +                  if (cmd == SIOCGIFNAME) {
> +                     rtnl_lock();
> +                       ret = dev_ifname(net, (struct ifreq __user
> -                  *)arg);
> +                       rtnl_unlock();
> +                               return ret;
> +                               }
>  
>         if (copy_from_user(&ifr, arg, sizeof(struct ifreq)))
>            return -EFAULT;
> 
> I have confirmed that both of these patches fix the issue. Now I'm
> wondering which one is the best way forward. Or is there a better way
> to fix this?
> 

I see no problem with moving this.
SIOCGIFNAME should not need to hold rtnl.


-- 
--
To unsubscribe from this list: send the line "unsubscribe linux-wireless" 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

* [PATCH 2/2] tg3: Add code to allow ethtool to enable/disable loopback.
From: Mahesh Bandewar @ 2011-04-28 23:33 UTC (permalink / raw)
  To: David Miller, Matt Carlson
  Cc: netdev, Michael Chan, Ben Hutchings, Michał Mirosław,
	Mahesh Bandewar
In-Reply-To: <1304033599-8395-2-git-send-email-maheshb@google.com>

---
 drivers/net/tg3.c |   32 ++++++++++++++++++++++++++++++++
 1 files changed, 32 insertions(+), 0 deletions(-)

diff --git a/drivers/net/tg3.c b/drivers/net/tg3.c
index fa57e3d..208884d 100644
--- a/drivers/net/tg3.c
+++ b/drivers/net/tg3.c
@@ -6319,6 +6319,33 @@ static u32 tg3_fix_features(struct net_device *dev, u32 features)
 	return features;
 }
 
+static int tg3_set_features(struct net_device *dev, u32 features)
+{
+	struct tg3 *tp = netdev_priv(dev);
+	u32 cur_mode = 0;
+	int err = 0;
+
+	spin_lock_bh(&tp->lock);
+	cur_mode = tr32(MAC_MODE);
+
+	if (features & NETIF_F_LOOPBACK) {
+		/* Enable internal MAC loopback mode */
+		tw32(MAC_MODE, cur_mode | MAC_MODE_PORT_INT_LPBACK);
+		netif_carrier_on(tp->dev);
+		netdev_info(dev, "Internal MAC loopback mode enabled.\n");
+	} else {
+		/* Disable internal MAC loopback mode */
+		tw32(MAC_MODE, cur_mode & ~MAC_MODE_PORT_INT_LPBACK);
+		/* Force link status check */
+		if (netif_running(dev))
+			tg3_setup_phy(tp, 1);
+		netdev_info(dev, "Internal MAC loopback mode disabled.\n");
+	}
+	spin_unlock_bh(&tp->lock);
+
+	return err;
+}
+
 static inline void tg3_set_mtu(struct net_device *dev, struct tg3 *tp,
 			       int new_mtu)
 {
@@ -15028,6 +15055,7 @@ static const struct net_device_ops tg3_netdev_ops = {
 	.ndo_tx_timeout		= tg3_tx_timeout,
 	.ndo_change_mtu		= tg3_change_mtu,
 	.ndo_fix_features	= tg3_fix_features,
+	.ndo_set_features	= tg3_set_features,
 #ifdef CONFIG_NET_POLL_CONTROLLER
 	.ndo_poll_controller	= tg3_poll_controller,
 #endif
@@ -15044,6 +15072,7 @@ static const struct net_device_ops tg3_netdev_ops_dma_bug = {
 	.ndo_do_ioctl		= tg3_ioctl,
 	.ndo_tx_timeout		= tg3_tx_timeout,
 	.ndo_change_mtu		= tg3_change_mtu,
+	.ndo_set_features	= tg3_set_features,
 #ifdef CONFIG_NET_POLL_CONTROLLER
 	.ndo_poll_controller	= tg3_poll_controller,
 #endif
@@ -15241,6 +15270,9 @@ static int __devinit tg3_init_one(struct pci_dev *pdev,
 	dev->features |= hw_features;
 	dev->vlan_features |= hw_features;
 
+	/* Add the loopback capability */
+	dev->hw_features |= NETIF_F_LOOPBACK;
+
 	if (tp->pci_chip_rev_id == CHIPREV_ID_5705_A1 &&
 	    !tg3_flag(tp, TSO_CAPABLE) &&
 	    !(tr32(TG3PCI_PCISTATE) & PCISTATE_BUS_SPEED_HIGH)) {
-- 
1.7.3.1


^ permalink raw reply related

* [PATCH 0/2] Loopback
From: Mahesh Bandewar @ 2011-04-28 23:33 UTC (permalink / raw)
  To: David Miller, Matt Carlson
  Cc: netdev, Michael Chan, Ben Hutchings, Michał Mirosław,
	Mahesh Bandewar

First patch is the repost of the earlier loopback patch. tg3 implementation / patch demonstrates one such usage.

Mahesh Bandewar (2):
  net: Allow ethtool to set interface in loopback mode.
  tg3: Add code to allow ethtool to enable/disable loopback.

 drivers/net/tg3.c         |   32 ++++++++++++++++++++++++++++++++
 include/linux/netdevice.h |    3 ++-
 net/core/ethtool.c        |    2 +-
 3 files changed, 35 insertions(+), 2 deletions(-)

-- 
1.7.3.1


^ permalink raw reply

* [PATCH 1/2] net: Allow ethtool to set interface in loopback mode.
From: Mahesh Bandewar @ 2011-04-28 23:33 UTC (permalink / raw)
  To: David Miller, Matt Carlson
  Cc: netdev, Michael Chan, Ben Hutchings, Michał Mirosław,
	Mahesh Bandewar
In-Reply-To: <1304033599-8395-1-git-send-email-maheshb@google.com>

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
---
 include/linux/netdevice.h |    3 ++-
 net/core/ethtool.c        |    2 +-
 2 files changed, 3 insertions(+), 2 deletions(-)

diff --git a/include/linux/netdevice.h b/include/linux/netdevice.h
index e03af35..0e17c81 100644
--- a/include/linux/netdevice.h
+++ b/include/linux/netdevice.h
@@ -1067,6 +1067,7 @@ struct net_device {
 #define NETIF_F_RXHASH		(1 << 28) /* Receive hashing offload */
 #define NETIF_F_RXCSUM		(1 << 29) /* Receive checksumming offload */
 #define NETIF_F_NOCACHE_COPY	(1 << 30) /* Use no-cache copyfromuser */
+#define NETIF_F_LOOPBACK	(1 << 31) /* Enable loopback */
 
 	/* Segmentation offload features */
 #define NETIF_F_GSO_SHIFT	16
@@ -1082,7 +1083,7 @@ struct net_device {
 	/* = all defined minus driver/device-class-related */
 #define NETIF_F_NEVER_CHANGE	(NETIF_F_VLAN_CHALLENGED | \
 				  NETIF_F_LLTX | NETIF_F_NETNS_LOCAL)
-#define NETIF_F_ETHTOOL_BITS	(0x7f3fffff & ~NETIF_F_NEVER_CHANGE)
+#define NETIF_F_ETHTOOL_BITS	(0xff3fffff & ~NETIF_F_NEVER_CHANGE)
 
 	/* List of features with software fallbacks. */
 #define NETIF_F_GSO_SOFTWARE	(NETIF_F_TSO | NETIF_F_TSO_ECN | \
diff --git a/net/core/ethtool.c b/net/core/ethtool.c
index d8b1a8d..f26649d 100644
--- a/net/core/ethtool.c
+++ b/net/core/ethtool.c
@@ -362,7 +362,7 @@ static const char netdev_features_strings[ETHTOOL_DEV_FEATURE_WORDS * 32][ETH_GS
 	/* NETIF_F_RXHASH */          "rx-hashing",
 	/* NETIF_F_RXCSUM */          "rx-checksum",
 	/* NETIF_F_NOCACHE_COPY */    "tx-nocache-copy"
-	"",
+	/* NETIF_F_LOOPBACK */        "loopback",
 };
 
 static int __ethtool_get_sset_count(struct net_device *dev, int sset)
-- 
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