Blame view

net/core/net-sysfs.c 37.7 KB
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1
2
3
4
  /*
   * net-sysfs.c - network device class and attributes
   *
   * Copyright (c) 2003 Stephen Hemminger <shemminger@osdl.org>
4ec93edb1   YOSHIFUJI Hideaki   [NET] CORE: Fix w...
5
   *
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
6
7
8
9
10
   *	This program is free software; you can redistribute it and/or
   *	modify it under the terms of the GNU General Public License
   *	as published by the Free Software Foundation; either version
   *	2 of the License, or (at your option) any later version.
   */
4fc268d24   Randy Dunlap   [PATCH] capable/c...
11
  #include <linux/capability.h>
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
12
13
  #include <linux/kernel.h>
  #include <linux/netdevice.h>
aecbe01e7   Jiri Pirko   net-sysfs: expose...
14
  #include <net/switchdev.h>
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
15
  #include <linux/if_arp.h>
5a0e3ad6a   Tejun Heo   include cleanup: ...
16
  #include <linux/slab.h>
174cd4b1e   Ingo Molnar   sched/headers: Pr...
17
  #include <linux/sched/signal.h>
608b4b954   Eric W. Biederman   netns: Teach netw...
18
  #include <linux/nsproxy.h>
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
19
  #include <net/sock.h>
608b4b954   Eric W. Biederman   netns: Teach netw...
20
  #include <net/net_namespace.h>
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
21
  #include <linux/rtnetlink.h>
fec5e652e   Tom Herbert   rfs: Receive Flow...
22
  #include <linux/vmalloc.h>
bc3b2d7fb   Paul Gortmaker   net: Add export.h...
23
  #include <linux/export.h>
114cf5802   Tom Herbert   bql: Byte queue l...
24
  #include <linux/jiffies.h>
9802c8e22   Ming Lei   net/core: apply p...
25
  #include <linux/pm_runtime.h>
aa836df95   Florian Fainelli   net: core: add of...
26
  #include <linux/of.h>
88832a22d   Ben Dooks   net-sysfs: fix mi...
27
  #include <linux/of_net.h>
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
28

342709efc   Pavel Emelyanov   [NET]: Remove in-...
29
  #include "net-sysfs.h"
8b41d1887   Eric W. Biederman   [NET]: Fix runnin...
30
  #ifdef CONFIG_SYSFS
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
31
32
33
34
35
36
  static const char fmt_hex[] = "%#x
  ";
  static const char fmt_dec[] = "%d
  ";
  static const char fmt_ulong[] = "%lu
  ";
be1f3c2c0   Ben Hutchings   net: Enable 64-bi...
37
38
  static const char fmt_u64[] = "%llu
  ";
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
39

4ec93edb1   YOSHIFUJI Hideaki   [NET] CORE: Fix w...
40
  static inline int dev_isalive(const struct net_device *dev)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
41
  {
fe9925b55   Stephen Hemminger   [NET]: Create net...
42
  	return dev->reg_state <= NETREG_REGISTERED;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
43
44
45
  }
  
  /* use same locking rules as GIF* ioctl's */
43cb76d91   Greg Kroah-Hartman   Network: convert ...
46
47
  static ssize_t netdev_show(const struct device *dev,
  			   struct device_attribute *attr, char *buf,
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
48
49
  			   ssize_t (*format)(const struct net_device *, char *))
  {
6b53dafe2   WANG Cong   net: do not name ...
50
  	struct net_device *ndev = to_net_dev(dev);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
51
52
53
  	ssize_t ret = -EINVAL;
  
  	read_lock(&dev_base_lock);
6b53dafe2   WANG Cong   net: do not name ...
54
55
  	if (dev_isalive(ndev))
  		ret = (*format)(ndev, buf);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
56
57
58
59
60
61
62
  	read_unlock(&dev_base_lock);
  
  	return ret;
  }
  
  /* generate a show function for simple field */
  #define NETDEVICE_SHOW(field, format_string)				\
6b53dafe2   WANG Cong   net: do not name ...
63
  static ssize_t format_##field(const struct net_device *dev, char *buf)	\
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
64
  {									\
6b53dafe2   WANG Cong   net: do not name ...
65
  	return sprintf(buf, format_string, dev->field);			\
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
66
  }									\
6be8aeef3   Greg Kroah-Hartman   net: core: conver...
67
  static ssize_t field##_show(struct device *dev,				\
43cb76d91   Greg Kroah-Hartman   Network: convert ...
68
  			    struct device_attribute *attr, char *buf)	\
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
69
  {									\
43cb76d91   Greg Kroah-Hartman   Network: convert ...
70
  	return netdev_show(dev, attr, buf, format_##field);		\
6be8aeef3   Greg Kroah-Hartman   net: core: conver...
71
72
73
74
75
  }									\
  
  #define NETDEVICE_SHOW_RO(field, format_string)				\
  NETDEVICE_SHOW(field, format_string);					\
  static DEVICE_ATTR_RO(field)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
76

6be8aeef3   Greg Kroah-Hartman   net: core: conver...
77
78
79
  #define NETDEVICE_SHOW_RW(field, format_string)				\
  NETDEVICE_SHOW(field, format_string);					\
  static DEVICE_ATTR_RW(field)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
80
81
  
  /* use same locking and permission rules as SIF* ioctl's */
43cb76d91   Greg Kroah-Hartman   Network: convert ...
82
  static ssize_t netdev_store(struct device *dev, struct device_attribute *attr,
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
83
84
85
  			    const char *buf, size_t len,
  			    int (*set)(struct net_device *, unsigned long))
  {
5e1fccc0b   Eric W. Biederman   net: Allow userns...
86
87
  	struct net_device *netdev = to_net_dev(dev);
  	struct net *net = dev_net(netdev);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
88
89
  	unsigned long new;
  	int ret = -EINVAL;
5e1fccc0b   Eric W. Biederman   net: Allow userns...
90
  	if (!ns_capable(net->user_ns, CAP_NET_ADMIN))
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
91
  		return -EPERM;
e1e420c71   Shuah Khan   net/core: simple_...
92
93
  	ret = kstrtoul(buf, 0, &new);
  	if (ret)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
94
  		goto err;
5a5990d30   Stephen Hemminger   net: Avoid race b...
95
  	if (!rtnl_trylock())
336ca57c3   Eric W. Biederman   net-sysfs: Use rt...
96
  		return restart_syscall();
5a5990d30   Stephen Hemminger   net: Avoid race b...
97

5e1fccc0b   Eric W. Biederman   net: Allow userns...
98
  	if (dev_isalive(netdev)) {
6648c65e7   stephen hemminger   net: style cleanups
99
100
  		ret = (*set)(netdev, new);
  		if (ret == 0)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
101
102
103
104
105
106
  			ret = len;
  	}
  	rtnl_unlock();
   err:
  	return ret;
  }
6be8aeef3   Greg Kroah-Hartman   net: core: conver...
107
  NETDEVICE_SHOW_RO(dev_id, fmt_hex);
3f85944fe   Amir Vadai   net: Add sysfs fi...
108
  NETDEVICE_SHOW_RO(dev_port, fmt_dec);
6be8aeef3   Greg Kroah-Hartman   net: core: conver...
109
110
  NETDEVICE_SHOW_RO(addr_assign_type, fmt_dec);
  NETDEVICE_SHOW_RO(addr_len, fmt_dec);
6be8aeef3   Greg Kroah-Hartman   net: core: conver...
111
112
113
  NETDEVICE_SHOW_RO(ifindex, fmt_dec);
  NETDEVICE_SHOW_RO(type, fmt_dec);
  NETDEVICE_SHOW_RO(link_mode, fmt_dec);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
114

a54acb3a6   Nicolas Dichtel   dev: introduce de...
115
116
117
118
119
120
121
122
  static ssize_t iflink_show(struct device *dev, struct device_attribute *attr,
  			   char *buf)
  {
  	struct net_device *ndev = to_net_dev(dev);
  
  	return sprintf(buf, fmt_dec, dev_get_iflink(ndev));
  }
  static DEVICE_ATTR_RO(iflink);
6b53dafe2   WANG Cong   net: do not name ...
123
  static ssize_t format_name_assign_type(const struct net_device *dev, char *buf)
685343fc3   Tom Gundersen   net: add name_ass...
124
  {
6b53dafe2   WANG Cong   net: do not name ...
125
  	return sprintf(buf, fmt_dec, dev->name_assign_type);
685343fc3   Tom Gundersen   net: add name_ass...
126
127
128
129
130
131
  }
  
  static ssize_t name_assign_type_show(struct device *dev,
  				     struct device_attribute *attr,
  				     char *buf)
  {
6b53dafe2   WANG Cong   net: do not name ...
132
  	struct net_device *ndev = to_net_dev(dev);
685343fc3   Tom Gundersen   net: add name_ass...
133
  	ssize_t ret = -EINVAL;
6b53dafe2   WANG Cong   net: do not name ...
134
  	if (ndev->name_assign_type != NET_NAME_UNKNOWN)
685343fc3   Tom Gundersen   net: add name_ass...
135
136
137
138
139
  		ret = netdev_show(dev, attr, buf, format_name_assign_type);
  
  	return ret;
  }
  static DEVICE_ATTR_RO(name_assign_type);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
140
  /* use same locking rules as GIFHWADDR ioctl's */
6be8aeef3   Greg Kroah-Hartman   net: core: conver...
141
  static ssize_t address_show(struct device *dev, struct device_attribute *attr,
43cb76d91   Greg Kroah-Hartman   Network: convert ...
142
  			    char *buf)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
143
  {
6b53dafe2   WANG Cong   net: do not name ...
144
  	struct net_device *ndev = to_net_dev(dev);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
145
146
147
  	ssize_t ret = -EINVAL;
  
  	read_lock(&dev_base_lock);
6b53dafe2   WANG Cong   net: do not name ...
148
149
  	if (dev_isalive(ndev))
  		ret = sysfs_format_mac(buf, ndev->dev_addr, ndev->addr_len);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
150
151
152
  	read_unlock(&dev_base_lock);
  	return ret;
  }
6be8aeef3   Greg Kroah-Hartman   net: core: conver...
153
  static DEVICE_ATTR_RO(address);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
154

6be8aeef3   Greg Kroah-Hartman   net: core: conver...
155
156
  static ssize_t broadcast_show(struct device *dev,
  			      struct device_attribute *attr, char *buf)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
157
  {
6b53dafe2   WANG Cong   net: do not name ...
158
  	struct net_device *ndev = to_net_dev(dev);
6648c65e7   stephen hemminger   net: style cleanups
159

6b53dafe2   WANG Cong   net: do not name ...
160
161
  	if (dev_isalive(ndev))
  		return sysfs_format_mac(buf, ndev->broadcast, ndev->addr_len);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
162
163
  	return -EINVAL;
  }
6be8aeef3   Greg Kroah-Hartman   net: core: conver...
164
  static DEVICE_ATTR_RO(broadcast);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
165

6b53dafe2   WANG Cong   net: do not name ...
166
  static int change_carrier(struct net_device *dev, unsigned long new_carrier)
fdae0fde5   Jiri Pirko   net: allow to cha...
167
  {
6b53dafe2   WANG Cong   net: do not name ...
168
  	if (!netif_running(dev))
fdae0fde5   Jiri Pirko   net: allow to cha...
169
  		return -EINVAL;
6648c65e7   stephen hemminger   net: style cleanups
170
  	return dev_change_carrier(dev, (bool)new_carrier);
fdae0fde5   Jiri Pirko   net: allow to cha...
171
  }
6be8aeef3   Greg Kroah-Hartman   net: core: conver...
172
173
  static ssize_t carrier_store(struct device *dev, struct device_attribute *attr,
  			     const char *buf, size_t len)
fdae0fde5   Jiri Pirko   net: allow to cha...
174
175
176
  {
  	return netdev_store(dev, attr, buf, len, change_carrier);
  }
6be8aeef3   Greg Kroah-Hartman   net: core: conver...
177
  static ssize_t carrier_show(struct device *dev,
43cb76d91   Greg Kroah-Hartman   Network: convert ...
178
  			    struct device_attribute *attr, char *buf)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
179
180
  {
  	struct net_device *netdev = to_net_dev(dev);
6648c65e7   stephen hemminger   net: style cleanups
181
182
  
  	if (netif_running(netdev))
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
183
  		return sprintf(buf, fmt_dec, !!netif_carrier_ok(netdev));
6648c65e7   stephen hemminger   net: style cleanups
184

1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
185
186
  	return -EINVAL;
  }
6be8aeef3   Greg Kroah-Hartman   net: core: conver...
187
  static DEVICE_ATTR_RW(carrier);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
188

6be8aeef3   Greg Kroah-Hartman   net: core: conver...
189
  static ssize_t speed_show(struct device *dev,
d519e17e2   Andy Gospodarek   net: export devic...
190
191
192
193
194
195
196
  			  struct device_attribute *attr, char *buf)
  {
  	struct net_device *netdev = to_net_dev(dev);
  	int ret = -EINVAL;
  
  	if (!rtnl_trylock())
  		return restart_syscall();
8ae6daca8   David Decotigny   ethtool: Call eth...
197
  	if (netif_running(netdev)) {
7cad1bac9   David Decotigny   net: core: use __...
198
199
200
201
  		struct ethtool_link_ksettings cmd;
  
  		if (!__ethtool_get_link_ksettings(netdev, &cmd))
  			ret = sprintf(buf, fmt_dec, cmd.base.speed);
d519e17e2   Andy Gospodarek   net: export devic...
202
203
204
205
  	}
  	rtnl_unlock();
  	return ret;
  }
6be8aeef3   Greg Kroah-Hartman   net: core: conver...
206
  static DEVICE_ATTR_RO(speed);
d519e17e2   Andy Gospodarek   net: export devic...
207

6be8aeef3   Greg Kroah-Hartman   net: core: conver...
208
  static ssize_t duplex_show(struct device *dev,
d519e17e2   Andy Gospodarek   net: export devic...
209
210
211
212
213
214
215
  			   struct device_attribute *attr, char *buf)
  {
  	struct net_device *netdev = to_net_dev(dev);
  	int ret = -EINVAL;
  
  	if (!rtnl_trylock())
  		return restart_syscall();
8ae6daca8   David Decotigny   ethtool: Call eth...
216
  	if (netif_running(netdev)) {
7cad1bac9   David Decotigny   net: core: use __...
217
218
219
  		struct ethtool_link_ksettings cmd;
  
  		if (!__ethtool_get_link_ksettings(netdev, &cmd)) {
c6c13965f   Nikolay Aleksandrov   net: add unknown ...
220
  			const char *duplex;
7cad1bac9   David Decotigny   net: core: use __...
221
222
  
  			switch (cmd.base.duplex) {
c6c13965f   Nikolay Aleksandrov   net: add unknown ...
223
224
225
226
227
228
229
230
231
232
233
234
235
  			case DUPLEX_HALF:
  				duplex = "half";
  				break;
  			case DUPLEX_FULL:
  				duplex = "full";
  				break;
  			default:
  				duplex = "unknown";
  				break;
  			}
  			ret = sprintf(buf, "%s
  ", duplex);
  		}
d519e17e2   Andy Gospodarek   net: export devic...
236
237
238
239
  	}
  	rtnl_unlock();
  	return ret;
  }
6be8aeef3   Greg Kroah-Hartman   net: core: conver...
240
  static DEVICE_ATTR_RO(duplex);
d519e17e2   Andy Gospodarek   net: export devic...
241

6be8aeef3   Greg Kroah-Hartman   net: core: conver...
242
  static ssize_t dormant_show(struct device *dev,
43cb76d91   Greg Kroah-Hartman   Network: convert ...
243
  			    struct device_attribute *attr, char *buf)
b00055aac   Stefan Rompf   [NET] core: add R...
244
245
246
247
248
249
250
251
  {
  	struct net_device *netdev = to_net_dev(dev);
  
  	if (netif_running(netdev))
  		return sprintf(buf, fmt_dec, !!netif_dormant(netdev));
  
  	return -EINVAL;
  }
6be8aeef3   Greg Kroah-Hartman   net: core: conver...
252
  static DEVICE_ATTR_RO(dormant);
b00055aac   Stefan Rompf   [NET] core: add R...
253

36cbd3dcc   Jan Engelhardt   net: mark read-on...
254
  static const char *const operstates[] = {
b00055aac   Stefan Rompf   [NET] core: add R...
255
256
257
258
259
260
261
262
  	"unknown",
  	"notpresent", /* currently unused */
  	"down",
  	"lowerlayerdown",
  	"testing", /* currently unused */
  	"dormant",
  	"up"
  };
6be8aeef3   Greg Kroah-Hartman   net: core: conver...
263
  static ssize_t operstate_show(struct device *dev,
43cb76d91   Greg Kroah-Hartman   Network: convert ...
264
  			      struct device_attribute *attr, char *buf)
b00055aac   Stefan Rompf   [NET] core: add R...
265
266
267
268
269
270
271
272
273
  {
  	const struct net_device *netdev = to_net_dev(dev);
  	unsigned char operstate;
  
  	read_lock(&dev_base_lock);
  	operstate = netdev->operstate;
  	if (!netif_running(netdev))
  		operstate = IF_OPER_DOWN;
  	read_unlock(&dev_base_lock);
e3a5cd9ed   Adrian Bunk   [NET]: Fix an off...
274
  	if (operstate >= ARRAY_SIZE(operstates))
b00055aac   Stefan Rompf   [NET] core: add R...
275
276
277
278
279
  		return -EINVAL; /* should not happen */
  
  	return sprintf(buf, "%s
  ", operstates[operstate]);
  }
6be8aeef3   Greg Kroah-Hartman   net: core: conver...
280
  static DEVICE_ATTR_RO(operstate);
b00055aac   Stefan Rompf   [NET] core: add R...
281

2d3b479df   david decotigny   net-sysfs: expose...
282
283
284
285
286
  static ssize_t carrier_changes_show(struct device *dev,
  				    struct device_attribute *attr,
  				    char *buf)
  {
  	struct net_device *netdev = to_net_dev(dev);
6648c65e7   stephen hemminger   net: style cleanups
287

2d3b479df   david decotigny   net-sysfs: expose...
288
289
290
291
  	return sprintf(buf, fmt_dec,
  		       atomic_read(&netdev->carrier_changes));
  }
  static DEVICE_ATTR_RO(carrier_changes);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
292
  /* read-write attributes */
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
293

6b53dafe2   WANG Cong   net: do not name ...
294
  static int change_mtu(struct net_device *dev, unsigned long new_mtu)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
295
  {
6648c65e7   stephen hemminger   net: style cleanups
296
  	return dev_set_mtu(dev, (int)new_mtu);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
297
  }
6be8aeef3   Greg Kroah-Hartman   net: core: conver...
298
  static ssize_t mtu_store(struct device *dev, struct device_attribute *attr,
43cb76d91   Greg Kroah-Hartman   Network: convert ...
299
  			 const char *buf, size_t len)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
300
  {
43cb76d91   Greg Kroah-Hartman   Network: convert ...
301
  	return netdev_store(dev, attr, buf, len, change_mtu);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
302
  }
6be8aeef3   Greg Kroah-Hartman   net: core: conver...
303
  NETDEVICE_SHOW_RW(mtu, fmt_dec);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
304

6b53dafe2   WANG Cong   net: do not name ...
305
  static int change_flags(struct net_device *dev, unsigned long new_flags)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
306
  {
6648c65e7   stephen hemminger   net: style cleanups
307
  	return dev_change_flags(dev, (unsigned int)new_flags);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
308
  }
6be8aeef3   Greg Kroah-Hartman   net: core: conver...
309
  static ssize_t flags_store(struct device *dev, struct device_attribute *attr,
43cb76d91   Greg Kroah-Hartman   Network: convert ...
310
  			   const char *buf, size_t len)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
311
  {
43cb76d91   Greg Kroah-Hartman   Network: convert ...
312
  	return netdev_store(dev, attr, buf, len, change_flags);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
313
  }
6be8aeef3   Greg Kroah-Hartman   net: core: conver...
314
  NETDEVICE_SHOW_RW(flags, fmt_hex);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
315

6b53dafe2   WANG Cong   net: do not name ...
316
  static int change_tx_queue_len(struct net_device *dev, unsigned long new_len)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
317
  {
0cd295035   Alexey Dobriyan   net: make struct ...
318
319
320
321
322
  	unsigned int orig_len = dev->tx_queue_len;
  	int res;
  
  	if (new_len != (unsigned int)new_len)
  		return -ERANGE;
08294a26e   Jason Wang   net: introduce NE...
323
324
325
326
327
328
329
330
331
332
333
334
335
  
  	if (new_len != orig_len) {
  		dev->tx_queue_len = new_len;
  		res = call_netdevice_notifiers(NETDEV_CHANGE_TX_QUEUE_LEN, dev);
  		res = notifier_to_errno(res);
  		if (res) {
  			netdev_err(dev,
  				   "refused to change device tx_queue_len
  ");
  			dev->tx_queue_len = orig_len;
  			return -EFAULT;
  		}
  	}
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
336
337
  	return 0;
  }
6be8aeef3   Greg Kroah-Hartman   net: core: conver...
338
  static ssize_t tx_queue_len_store(struct device *dev,
43cb76d91   Greg Kroah-Hartman   Network: convert ...
339
340
  				  struct device_attribute *attr,
  				  const char *buf, size_t len)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
341
  {
5e1fccc0b   Eric W. Biederman   net: Allow userns...
342
343
  	if (!capable(CAP_NET_ADMIN))
  		return -EPERM;
43cb76d91   Greg Kroah-Hartman   Network: convert ...
344
  	return netdev_store(dev, attr, buf, len, change_tx_queue_len);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
345
  }
0cd295035   Alexey Dobriyan   net: make struct ...
346
  NETDEVICE_SHOW_RW(tx_queue_len, fmt_dec);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
347

3b47d3039   Eric Dumazet   net: gro: add a p...
348
349
350
351
352
353
354
  static int change_gro_flush_timeout(struct net_device *dev, unsigned long val)
  {
  	dev->gro_flush_timeout = val;
  	return 0;
  }
  
  static ssize_t gro_flush_timeout_store(struct device *dev,
6648c65e7   stephen hemminger   net: style cleanups
355
356
  				       struct device_attribute *attr,
  				       const char *buf, size_t len)
3b47d3039   Eric Dumazet   net: gro: add a p...
357
358
359
360
361
362
363
  {
  	if (!capable(CAP_NET_ADMIN))
  		return -EPERM;
  
  	return netdev_store(dev, attr, buf, len, change_gro_flush_timeout);
  }
  NETDEVICE_SHOW_RW(gro_flush_timeout, fmt_ulong);
6be8aeef3   Greg Kroah-Hartman   net: core: conver...
364
  static ssize_t ifalias_store(struct device *dev, struct device_attribute *attr,
0b815a1a6   Stephen Hemminger   net: network devi...
365
366
367
  			     const char *buf, size_t len)
  {
  	struct net_device *netdev = to_net_dev(dev);
5e1fccc0b   Eric W. Biederman   net: Allow userns...
368
  	struct net *net = dev_net(netdev);
0b815a1a6   Stephen Hemminger   net: network devi...
369
370
  	size_t count = len;
  	ssize_t ret;
5e1fccc0b   Eric W. Biederman   net: Allow userns...
371
  	if (!ns_capable(net->user_ns, CAP_NET_ADMIN))
0b815a1a6   Stephen Hemminger   net: network devi...
372
373
374
375
376
377
  		return -EPERM;
  
  	/* ignore trailing newline */
  	if (len >  0 && buf[len - 1] == '
  ')
  		--count;
336ca57c3   Eric W. Biederman   net-sysfs: Use rt...
378
379
  	if (!rtnl_trylock())
  		return restart_syscall();
0b815a1a6   Stephen Hemminger   net: network devi...
380
381
382
383
384
  	ret = dev_set_alias(netdev, buf, count);
  	rtnl_unlock();
  
  	return ret < 0 ? ret : len;
  }
6be8aeef3   Greg Kroah-Hartman   net: core: conver...
385
  static ssize_t ifalias_show(struct device *dev,
0b815a1a6   Stephen Hemminger   net: network devi...
386
387
388
389
  			    struct device_attribute *attr, char *buf)
  {
  	const struct net_device *netdev = to_net_dev(dev);
  	ssize_t ret = 0;
336ca57c3   Eric W. Biederman   net-sysfs: Use rt...
390
391
  	if (!rtnl_trylock())
  		return restart_syscall();
0b815a1a6   Stephen Hemminger   net: network devi...
392
393
394
395
396
397
  	if (netdev->ifalias)
  		ret = sprintf(buf, "%s
  ", netdev->ifalias);
  	rtnl_unlock();
  	return ret;
  }
6be8aeef3   Greg Kroah-Hartman   net: core: conver...
398
  static DEVICE_ATTR_RW(ifalias);
a512b92b3   Vlad Dogaru   net: add sysfs en...
399

6b53dafe2   WANG Cong   net: do not name ...
400
  static int change_group(struct net_device *dev, unsigned long new_group)
a512b92b3   Vlad Dogaru   net: add sysfs en...
401
  {
6648c65e7   stephen hemminger   net: style cleanups
402
  	dev_set_group(dev, (int)new_group);
a512b92b3   Vlad Dogaru   net: add sysfs en...
403
404
  	return 0;
  }
6be8aeef3   Greg Kroah-Hartman   net: core: conver...
405
406
  static ssize_t group_store(struct device *dev, struct device_attribute *attr,
  			   const char *buf, size_t len)
a512b92b3   Vlad Dogaru   net: add sysfs en...
407
408
409
  {
  	return netdev_store(dev, attr, buf, len, change_group);
  }
6be8aeef3   Greg Kroah-Hartman   net: core: conver...
410
411
  NETDEVICE_SHOW(group, fmt_dec);
  static DEVICE_ATTR(netdev_group, S_IRUGO | S_IWUSR, group_show, group_store);
d746d707a   Anuradha Karuppiah   net core: Add pro...
412
413
  static int change_proto_down(struct net_device *dev, unsigned long proto_down)
  {
6648c65e7   stephen hemminger   net: style cleanups
414
  	return dev_change_proto_down(dev, (bool)proto_down);
d746d707a   Anuradha Karuppiah   net core: Add pro...
415
416
417
418
419
420
421
422
423
  }
  
  static ssize_t proto_down_store(struct device *dev,
  				struct device_attribute *attr,
  				const char *buf, size_t len)
  {
  	return netdev_store(dev, attr, buf, len, change_proto_down);
  }
  NETDEVICE_SHOW_RW(proto_down, fmt_dec);
cc998ff88   Linus Torvalds   Merge git://git.k...
424
  static ssize_t phys_port_id_show(struct device *dev,
ff80e519a   Jiri Pirko   net: export physi...
425
426
427
428
429
430
431
432
433
  				 struct device_attribute *attr, char *buf)
  {
  	struct net_device *netdev = to_net_dev(dev);
  	ssize_t ret = -EINVAL;
  
  	if (!rtnl_trylock())
  		return restart_syscall();
  
  	if (dev_isalive(netdev)) {
02637fce3   Jiri Pirko   net: rename netde...
434
  		struct netdev_phys_item_id ppid;
ff80e519a   Jiri Pirko   net: export physi...
435
436
437
438
439
440
441
442
443
444
  
  		ret = dev_get_phys_port_id(netdev, &ppid);
  		if (!ret)
  			ret = sprintf(buf, "%*phN
  ", ppid.id_len, ppid.id);
  	}
  	rtnl_unlock();
  
  	return ret;
  }
cc998ff88   Linus Torvalds   Merge git://git.k...
445
  static DEVICE_ATTR_RO(phys_port_id);
db24a9044   David Ahern   net: add support ...
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
  static ssize_t phys_port_name_show(struct device *dev,
  				   struct device_attribute *attr, char *buf)
  {
  	struct net_device *netdev = to_net_dev(dev);
  	ssize_t ret = -EINVAL;
  
  	if (!rtnl_trylock())
  		return restart_syscall();
  
  	if (dev_isalive(netdev)) {
  		char name[IFNAMSIZ];
  
  		ret = dev_get_phys_port_name(netdev, name, sizeof(name));
  		if (!ret)
  			ret = sprintf(buf, "%s
  ", name);
  	}
  	rtnl_unlock();
  
  	return ret;
  }
  static DEVICE_ATTR_RO(phys_port_name);
aecbe01e7   Jiri Pirko   net-sysfs: expose...
468
469
470
471
472
473
474
475
476
477
  static ssize_t phys_switch_id_show(struct device *dev,
  				   struct device_attribute *attr, char *buf)
  {
  	struct net_device *netdev = to_net_dev(dev);
  	ssize_t ret = -EINVAL;
  
  	if (!rtnl_trylock())
  		return restart_syscall();
  
  	if (dev_isalive(netdev)) {
f8e20a9f8   Scott Feldman   switchdev: conver...
478
  		struct switchdev_attr attr = {
6ff64f6f9   Ido Schimmel   switchdev: Pass o...
479
  			.orig_dev = netdev,
1f8683987   Jiri Pirko   switchdev: rename...
480
  			.id = SWITCHDEV_ATTR_ID_PORT_PARENT_ID,
f8e20a9f8   Scott Feldman   switchdev: conver...
481
482
  			.flags = SWITCHDEV_F_NO_RECURSE,
  		};
aecbe01e7   Jiri Pirko   net-sysfs: expose...
483

f8e20a9f8   Scott Feldman   switchdev: conver...
484
  		ret = switchdev_port_attr_get(netdev, &attr);
aecbe01e7   Jiri Pirko   net-sysfs: expose...
485
  		if (!ret)
42275bd8f   Scott Feldman   switchdev: don't ...
486
487
488
  			ret = sprintf(buf, "%*phN
  ", attr.u.ppid.id_len,
  				      attr.u.ppid.id);
aecbe01e7   Jiri Pirko   net-sysfs: expose...
489
490
491
492
493
494
  	}
  	rtnl_unlock();
  
  	return ret;
  }
  static DEVICE_ATTR_RO(phys_switch_id);
ec6cc5993   stephen hemminger   net: make net sys...
495
  static struct attribute *net_class_attrs[] __ro_after_init = {
6be8aeef3   Greg Kroah-Hartman   net: core: conver...
496
497
498
  	&dev_attr_netdev_group.attr,
  	&dev_attr_type.attr,
  	&dev_attr_dev_id.attr,
3f85944fe   Amir Vadai   net: Add sysfs fi...
499
  	&dev_attr_dev_port.attr,
6be8aeef3   Greg Kroah-Hartman   net: core: conver...
500
501
  	&dev_attr_iflink.attr,
  	&dev_attr_ifindex.attr,
685343fc3   Tom Gundersen   net: add name_ass...
502
  	&dev_attr_name_assign_type.attr,
6be8aeef3   Greg Kroah-Hartman   net: core: conver...
503
504
505
506
507
508
509
510
511
  	&dev_attr_addr_assign_type.attr,
  	&dev_attr_addr_len.attr,
  	&dev_attr_link_mode.attr,
  	&dev_attr_address.attr,
  	&dev_attr_broadcast.attr,
  	&dev_attr_speed.attr,
  	&dev_attr_duplex.attr,
  	&dev_attr_dormant.attr,
  	&dev_attr_operstate.attr,
2d3b479df   david decotigny   net-sysfs: expose...
512
  	&dev_attr_carrier_changes.attr,
6be8aeef3   Greg Kroah-Hartman   net: core: conver...
513
514
515
516
517
  	&dev_attr_ifalias.attr,
  	&dev_attr_carrier.attr,
  	&dev_attr_mtu.attr,
  	&dev_attr_flags.attr,
  	&dev_attr_tx_queue_len.attr,
3b47d3039   Eric Dumazet   net: gro: add a p...
518
  	&dev_attr_gro_flush_timeout.attr,
cc998ff88   Linus Torvalds   Merge git://git.k...
519
  	&dev_attr_phys_port_id.attr,
db24a9044   David Ahern   net: add support ...
520
  	&dev_attr_phys_port_name.attr,
aecbe01e7   Jiri Pirko   net-sysfs: expose...
521
  	&dev_attr_phys_switch_id.attr,
d746d707a   Anuradha Karuppiah   net core: Add pro...
522
  	&dev_attr_proto_down.attr,
6be8aeef3   Greg Kroah-Hartman   net: core: conver...
523
  	NULL,
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
524
  };
6be8aeef3   Greg Kroah-Hartman   net: core: conver...
525
  ATTRIBUTE_GROUPS(net_class);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
526
527
  
  /* Show a given an attribute in the statistics group */
43cb76d91   Greg Kroah-Hartman   Network: convert ...
528
529
  static ssize_t netstat_show(const struct device *d,
  			    struct device_attribute *attr, char *buf,
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
530
531
  			    unsigned long offset)
  {
43cb76d91   Greg Kroah-Hartman   Network: convert ...
532
  	struct net_device *dev = to_net_dev(d);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
533
  	ssize_t ret = -EINVAL;
be1f3c2c0   Ben Hutchings   net: Enable 64-bi...
534
  	WARN_ON(offset > sizeof(struct rtnl_link_stats64) ||
6648c65e7   stephen hemminger   net: style cleanups
535
  		offset % sizeof(u64) != 0);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
536
537
  
  	read_lock(&dev_base_lock);
96e74088f   Pavel Emelyanov   net: The dev->get...
538
  	if (dev_isalive(dev)) {
28172739f   Eric Dumazet   net: fix 64 bit c...
539
540
  		struct rtnl_link_stats64 temp;
  		const struct rtnl_link_stats64 *stats = dev_get_stats(dev, &temp);
6648c65e7   stephen hemminger   net: style cleanups
541
  		ret = sprintf(buf, fmt_u64, *(u64 *)(((u8 *)stats) + offset));
96e74088f   Pavel Emelyanov   net: The dev->get...
542
  	}
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
543
544
545
546
547
548
  	read_unlock(&dev_base_lock);
  	return ret;
  }
  
  /* generate a read-only statistics attribute */
  #define NETSTAT_ENTRY(name)						\
6be8aeef3   Greg Kroah-Hartman   net: core: conver...
549
  static ssize_t name##_show(struct device *d,				\
6648c65e7   stephen hemminger   net: style cleanups
550
  			   struct device_attribute *attr, char *buf)	\
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
551
  {									\
43cb76d91   Greg Kroah-Hartman   Network: convert ...
552
  	return netstat_show(d, attr, buf,				\
be1f3c2c0   Ben Hutchings   net: Enable 64-bi...
553
  			    offsetof(struct rtnl_link_stats64, name));	\
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
554
  }									\
6be8aeef3   Greg Kroah-Hartman   net: core: conver...
555
  static DEVICE_ATTR_RO(name)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
  
  NETSTAT_ENTRY(rx_packets);
  NETSTAT_ENTRY(tx_packets);
  NETSTAT_ENTRY(rx_bytes);
  NETSTAT_ENTRY(tx_bytes);
  NETSTAT_ENTRY(rx_errors);
  NETSTAT_ENTRY(tx_errors);
  NETSTAT_ENTRY(rx_dropped);
  NETSTAT_ENTRY(tx_dropped);
  NETSTAT_ENTRY(multicast);
  NETSTAT_ENTRY(collisions);
  NETSTAT_ENTRY(rx_length_errors);
  NETSTAT_ENTRY(rx_over_errors);
  NETSTAT_ENTRY(rx_crc_errors);
  NETSTAT_ENTRY(rx_frame_errors);
  NETSTAT_ENTRY(rx_fifo_errors);
  NETSTAT_ENTRY(rx_missed_errors);
  NETSTAT_ENTRY(tx_aborted_errors);
  NETSTAT_ENTRY(tx_carrier_errors);
  NETSTAT_ENTRY(tx_fifo_errors);
  NETSTAT_ENTRY(tx_heartbeat_errors);
  NETSTAT_ENTRY(tx_window_errors);
  NETSTAT_ENTRY(rx_compressed);
  NETSTAT_ENTRY(tx_compressed);
6e7333d31   Jarod Wilson   net: add rx_nohan...
580
  NETSTAT_ENTRY(rx_nohandler);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
581

ec6cc5993   stephen hemminger   net: make net sys...
582
  static struct attribute *netstat_attrs[] __ro_after_init = {
43cb76d91   Greg Kroah-Hartman   Network: convert ...
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
  	&dev_attr_rx_packets.attr,
  	&dev_attr_tx_packets.attr,
  	&dev_attr_rx_bytes.attr,
  	&dev_attr_tx_bytes.attr,
  	&dev_attr_rx_errors.attr,
  	&dev_attr_tx_errors.attr,
  	&dev_attr_rx_dropped.attr,
  	&dev_attr_tx_dropped.attr,
  	&dev_attr_multicast.attr,
  	&dev_attr_collisions.attr,
  	&dev_attr_rx_length_errors.attr,
  	&dev_attr_rx_over_errors.attr,
  	&dev_attr_rx_crc_errors.attr,
  	&dev_attr_rx_frame_errors.attr,
  	&dev_attr_rx_fifo_errors.attr,
  	&dev_attr_rx_missed_errors.attr,
  	&dev_attr_tx_aborted_errors.attr,
  	&dev_attr_tx_carrier_errors.attr,
  	&dev_attr_tx_fifo_errors.attr,
  	&dev_attr_tx_heartbeat_errors.attr,
  	&dev_attr_tx_window_errors.attr,
  	&dev_attr_rx_compressed.attr,
  	&dev_attr_tx_compressed.attr,
6e7333d31   Jarod Wilson   net: add rx_nohan...
606
  	&dev_attr_rx_nohandler.attr,
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
607
608
  	NULL
  };
38ef00cc3   Arvind Yadav   net: constify att...
609
  static const struct attribute_group netstat_group = {
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
610
611
612
  	.name  = "statistics",
  	.attrs  = netstat_attrs,
  };
38c1a01cf   Johannes Berg   wireless: add bac...
613
614
615
616
617
  
  #if IS_ENABLED(CONFIG_WIRELESS_EXT) || IS_ENABLED(CONFIG_CFG80211)
  static struct attribute *wireless_attrs[] = {
  	NULL
  };
38ef00cc3   Arvind Yadav   net: constify att...
618
  static const struct attribute_group wireless_group = {
38c1a01cf   Johannes Berg   wireless: add bac...
619
620
621
622
  	.name = "wireless",
  	.attrs = wireless_attrs,
  };
  #endif
6be8aeef3   Greg Kroah-Hartman   net: core: conver...
623
624
625
  
  #else /* CONFIG_SYSFS */
  #define net_class_groups	NULL
d6523ddf2   Eric W. Biederman   net/sysfs: Fix th...
626
  #endif /* CONFIG_SYSFS */
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
627

a953be53c   Michael Dalton   net-sysfs: add su...
628
  #ifdef CONFIG_SYSFS
6648c65e7   stephen hemminger   net: style cleanups
629
630
  #define to_rx_queue_attr(_attr) \
  	container_of(_attr, struct rx_queue_attribute, attr)
0a9627f26   Tom Herbert   rps: Receive Pack...
631
632
633
634
635
636
  
  #define to_rx_queue(obj) container_of(obj, struct netdev_rx_queue, kobj)
  
  static ssize_t rx_queue_attr_show(struct kobject *kobj, struct attribute *attr,
  				  char *buf)
  {
667e427bc   stephen hemminger   net: mark receive...
637
  	const struct rx_queue_attribute *attribute = to_rx_queue_attr(attr);
0a9627f26   Tom Herbert   rps: Receive Pack...
638
639
640
641
  	struct netdev_rx_queue *queue = to_rx_queue(kobj);
  
  	if (!attribute->show)
  		return -EIO;
718ad681e   stephen hemminger   net: drop unused ...
642
  	return attribute->show(queue, buf);
0a9627f26   Tom Herbert   rps: Receive Pack...
643
644
645
646
647
  }
  
  static ssize_t rx_queue_attr_store(struct kobject *kobj, struct attribute *attr,
  				   const char *buf, size_t count)
  {
667e427bc   stephen hemminger   net: mark receive...
648
  	const struct rx_queue_attribute *attribute = to_rx_queue_attr(attr);
0a9627f26   Tom Herbert   rps: Receive Pack...
649
650
651
652
  	struct netdev_rx_queue *queue = to_rx_queue(kobj);
  
  	if (!attribute->store)
  		return -EIO;
718ad681e   stephen hemminger   net: drop unused ...
653
  	return attribute->store(queue, buf, count);
0a9627f26   Tom Herbert   rps: Receive Pack...
654
  }
fa50d6457   stephen hemminger   net: make rx_queu...
655
  static const struct sysfs_ops rx_queue_sysfs_ops = {
0a9627f26   Tom Herbert   rps: Receive Pack...
656
657
658
  	.show = rx_queue_attr_show,
  	.store = rx_queue_attr_store,
  };
a953be53c   Michael Dalton   net-sysfs: add su...
659
  #ifdef CONFIG_RPS
718ad681e   stephen hemminger   net: drop unused ...
660
  static ssize_t show_rps_map(struct netdev_rx_queue *queue, char *buf)
0a9627f26   Tom Herbert   rps: Receive Pack...
661
662
663
  {
  	struct rps_map *map;
  	cpumask_var_t mask;
f09068276   Tejun Heo   net: use %*pb[l] ...
664
  	int i, len;
0a9627f26   Tom Herbert   rps: Receive Pack...
665
666
667
668
669
670
671
672
673
  
  	if (!zalloc_cpumask_var(&mask, GFP_KERNEL))
  		return -ENOMEM;
  
  	rcu_read_lock();
  	map = rcu_dereference(queue->rps_map);
  	if (map)
  		for (i = 0; i < map->len; i++)
  			cpumask_set_cpu(map->cpus[i], mask);
f09068276   Tejun Heo   net: use %*pb[l] ...
674
675
  	len = snprintf(buf, PAGE_SIZE, "%*pb
  ", cpumask_pr_args(mask));
0a9627f26   Tom Herbert   rps: Receive Pack...
676
  	rcu_read_unlock();
0a9627f26   Tom Herbert   rps: Receive Pack...
677
  	free_cpumask_var(mask);
f09068276   Tejun Heo   net: use %*pb[l] ...
678
679
  
  	return len < PAGE_SIZE ? len : -EINVAL;
0a9627f26   Tom Herbert   rps: Receive Pack...
680
  }
f5acb907d   Eric Dumazet   rps: static funct...
681
  static ssize_t store_rps_map(struct netdev_rx_queue *queue,
718ad681e   stephen hemminger   net: drop unused ...
682
  			     const char *buf, size_t len)
0a9627f26   Tom Herbert   rps: Receive Pack...
683
684
685
686
  {
  	struct rps_map *old_map, *map;
  	cpumask_var_t mask;
  	int err, cpu, i;
da65ad1fe   Sasha Levin   net: allow sleepi...
687
  	static DEFINE_MUTEX(rps_map_mutex);
0a9627f26   Tom Herbert   rps: Receive Pack...
688
689
690
691
692
693
694
695
696
697
698
699
  
  	if (!capable(CAP_NET_ADMIN))
  		return -EPERM;
  
  	if (!alloc_cpumask_var(&mask, GFP_KERNEL))
  		return -ENOMEM;
  
  	err = bitmap_parse(buf, len, cpumask_bits(mask), nr_cpumask_bits);
  	if (err) {
  		free_cpumask_var(mask);
  		return err;
  	}
95c961747   Eric Dumazet   net: cleanup unsi...
700
  	map = kzalloc(max_t(unsigned int,
6648c65e7   stephen hemminger   net: style cleanups
701
702
  			    RPS_MAP_SIZE(cpumask_weight(mask)), L1_CACHE_BYTES),
  		      GFP_KERNEL);
0a9627f26   Tom Herbert   rps: Receive Pack...
703
704
705
706
707
708
709
710
  	if (!map) {
  		free_cpumask_var(mask);
  		return -ENOMEM;
  	}
  
  	i = 0;
  	for_each_cpu_and(cpu, mask, cpu_online_mask)
  		map->cpus[i++] = cpu;
6648c65e7   stephen hemminger   net: style cleanups
711
  	if (i) {
0a9627f26   Tom Herbert   rps: Receive Pack...
712
  		map->len = i;
6648c65e7   stephen hemminger   net: style cleanups
713
  	} else {
0a9627f26   Tom Herbert   rps: Receive Pack...
714
715
716
  		kfree(map);
  		map = NULL;
  	}
da65ad1fe   Sasha Levin   net: allow sleepi...
717
  	mutex_lock(&rps_map_mutex);
6e3f7faf3   Eric Dumazet   rps: add __rcu an...
718
  	old_map = rcu_dereference_protected(queue->rps_map,
da65ad1fe   Sasha Levin   net: allow sleepi...
719
  					    mutex_is_locked(&rps_map_mutex));
0a9627f26   Tom Herbert   rps: Receive Pack...
720
  	rcu_assign_pointer(queue->rps_map, map);
0a9627f26   Tom Herbert   rps: Receive Pack...
721

adc9300e7   Eric Dumazet   net: use jump_lab...
722
  	if (map)
c5905afb0   Ingo Molnar   static keys: Intr...
723
  		static_key_slow_inc(&rps_needed);
10e4ea751   Tom Herbert   net: Fix race con...
724
  	if (old_map)
c5905afb0   Ingo Molnar   static keys: Intr...
725
  		static_key_slow_dec(&rps_needed);
10e4ea751   Tom Herbert   net: Fix race con...
726

da65ad1fe   Sasha Levin   net: allow sleepi...
727
  	mutex_unlock(&rps_map_mutex);
10e4ea751   Tom Herbert   net: Fix race con...
728
729
730
  
  	if (old_map)
  		kfree_rcu(old_map, rcu);
0a9627f26   Tom Herbert   rps: Receive Pack...
731
732
733
  	free_cpumask_var(mask);
  	return len;
  }
fec5e652e   Tom Herbert   rfs: Receive Flow...
734
  static ssize_t show_rps_dev_flow_table_cnt(struct netdev_rx_queue *queue,
fec5e652e   Tom Herbert   rfs: Receive Flow...
735
736
737
  					   char *buf)
  {
  	struct rps_dev_flow_table *flow_table;
60b778ce5   Eric Dumazet   rfs: better sizin...
738
  	unsigned long val = 0;
fec5e652e   Tom Herbert   rfs: Receive Flow...
739
740
741
742
  
  	rcu_read_lock();
  	flow_table = rcu_dereference(queue->rps_flow_table);
  	if (flow_table)
60b778ce5   Eric Dumazet   rfs: better sizin...
743
  		val = (unsigned long)flow_table->mask + 1;
fec5e652e   Tom Herbert   rfs: Receive Flow...
744
  	rcu_read_unlock();
60b778ce5   Eric Dumazet   rfs: better sizin...
745
746
  	return sprintf(buf, "%lu
  ", val);
fec5e652e   Tom Herbert   rfs: Receive Flow...
747
  }
fec5e652e   Tom Herbert   rfs: Receive Flow...
748
749
750
751
  static void rps_dev_flow_table_release(struct rcu_head *rcu)
  {
  	struct rps_dev_flow_table *table = container_of(rcu,
  	    struct rps_dev_flow_table, rcu);
243198d09   Al Viro   rps_dev_flow_tabl...
752
  	vfree(table);
fec5e652e   Tom Herbert   rfs: Receive Flow...
753
  }
f5acb907d   Eric Dumazet   rps: static funct...
754
  static ssize_t store_rps_dev_flow_table_cnt(struct netdev_rx_queue *queue,
718ad681e   stephen hemminger   net: drop unused ...
755
  					    const char *buf, size_t len)
fec5e652e   Tom Herbert   rfs: Receive Flow...
756
  {
60b778ce5   Eric Dumazet   rfs: better sizin...
757
  	unsigned long mask, count;
fec5e652e   Tom Herbert   rfs: Receive Flow...
758
759
  	struct rps_dev_flow_table *table, *old_table;
  	static DEFINE_SPINLOCK(rps_dev_flow_lock);
60b778ce5   Eric Dumazet   rfs: better sizin...
760
  	int rc;
fec5e652e   Tom Herbert   rfs: Receive Flow...
761
762
763
  
  	if (!capable(CAP_NET_ADMIN))
  		return -EPERM;
60b778ce5   Eric Dumazet   rfs: better sizin...
764
765
766
  	rc = kstrtoul(buf, 0, &count);
  	if (rc < 0)
  		return rc;
fec5e652e   Tom Herbert   rfs: Receive Flow...
767
768
  
  	if (count) {
60b778ce5   Eric Dumazet   rfs: better sizin...
769
770
771
772
773
774
775
  		mask = count - 1;
  		/* mask = roundup_pow_of_two(count) - 1;
  		 * without overflows...
  		 */
  		while ((mask | (mask >> 1)) != mask)
  			mask |= (mask >> 1);
  		/* On 64 bit arches, must check mask fits in table->mask (u32),
8e3bff96a   stephen hemminger   net: more spellin...
776
777
  		 * and on 32bit arches, must check
  		 * RPS_DEV_FLOW_TABLE_SIZE(mask + 1) doesn't overflow.
60b778ce5   Eric Dumazet   rfs: better sizin...
778
779
780
  		 */
  #if BITS_PER_LONG > 32
  		if (mask > (unsigned long)(u32)mask)
a0a129f8b   Xi Wang   rps: fix insuffic...
781
  			return -EINVAL;
60b778ce5   Eric Dumazet   rfs: better sizin...
782
783
  #else
  		if (mask > (ULONG_MAX - RPS_DEV_FLOW_TABLE_SIZE(1))
a0a129f8b   Xi Wang   rps: fix insuffic...
784
  				/ sizeof(struct rps_dev_flow)) {
fec5e652e   Tom Herbert   rfs: Receive Flow...
785
786
787
  			/* Enforce a limit to prevent overflow */
  			return -EINVAL;
  		}
60b778ce5   Eric Dumazet   rfs: better sizin...
788
789
  #endif
  		table = vmalloc(RPS_DEV_FLOW_TABLE_SIZE(mask + 1));
fec5e652e   Tom Herbert   rfs: Receive Flow...
790
791
  		if (!table)
  			return -ENOMEM;
60b778ce5   Eric Dumazet   rfs: better sizin...
792
793
794
  		table->mask = mask;
  		for (count = 0; count <= mask; count++)
  			table->flows[count].cpu = RPS_NO_CPU;
6648c65e7   stephen hemminger   net: style cleanups
795
  	} else {
fec5e652e   Tom Herbert   rfs: Receive Flow...
796
  		table = NULL;
6648c65e7   stephen hemminger   net: style cleanups
797
  	}
fec5e652e   Tom Herbert   rfs: Receive Flow...
798
799
  
  	spin_lock(&rps_dev_flow_lock);
6e3f7faf3   Eric Dumazet   rps: add __rcu an...
800
801
  	old_table = rcu_dereference_protected(queue->rps_flow_table,
  					      lockdep_is_held(&rps_dev_flow_lock));
fec5e652e   Tom Herbert   rfs: Receive Flow...
802
803
804
805
806
807
808
809
  	rcu_assign_pointer(queue->rps_flow_table, table);
  	spin_unlock(&rps_dev_flow_lock);
  
  	if (old_table)
  		call_rcu(&old_table->rcu, rps_dev_flow_table_release);
  
  	return len;
  }
667e427bc   stephen hemminger   net: mark receive...
810
811
  static struct rx_queue_attribute rps_cpus_attribute __ro_after_init
  	= __ATTR(rps_cpus, S_IRUGO | S_IWUSR, show_rps_map, store_rps_map);
0a9627f26   Tom Herbert   rps: Receive Pack...
812

667e427bc   stephen hemminger   net: mark receive...
813
814
815
  static struct rx_queue_attribute rps_dev_flow_table_cnt_attribute __ro_after_init
  	= __ATTR(rps_flow_cnt, S_IRUGO | S_IWUSR,
  		 show_rps_dev_flow_table_cnt, store_rps_dev_flow_table_cnt);
a953be53c   Michael Dalton   net-sysfs: add su...
816
  #endif /* CONFIG_RPS */
fec5e652e   Tom Herbert   rfs: Receive Flow...
817

667e427bc   stephen hemminger   net: mark receive...
818
  static struct attribute *rx_queue_default_attrs[] __ro_after_init = {
a953be53c   Michael Dalton   net-sysfs: add su...
819
  #ifdef CONFIG_RPS
0a9627f26   Tom Herbert   rps: Receive Pack...
820
  	&rps_cpus_attribute.attr,
fec5e652e   Tom Herbert   rfs: Receive Flow...
821
  	&rps_dev_flow_table_cnt_attribute.attr,
a953be53c   Michael Dalton   net-sysfs: add su...
822
  #endif
0a9627f26   Tom Herbert   rps: Receive Pack...
823
824
825
826
827
828
  	NULL
  };
  
  static void rx_queue_release(struct kobject *kobj)
  {
  	struct netdev_rx_queue *queue = to_rx_queue(kobj);
a953be53c   Michael Dalton   net-sysfs: add su...
829
  #ifdef CONFIG_RPS
6e3f7faf3   Eric Dumazet   rps: add __rcu an...
830
831
  	struct rps_map *map;
  	struct rps_dev_flow_table *flow_table;
0a9627f26   Tom Herbert   rps: Receive Pack...
832

33d480ce6   Eric Dumazet   net: cleanup some...
833
  	map = rcu_dereference_protected(queue->rps_map, 1);
9ea19481d   John Fastabend   net: zero kobject...
834
835
  	if (map) {
  		RCU_INIT_POINTER(queue->rps_map, NULL);
f6f80238f   Lai Jiangshan   net,rcu: convert ...
836
  		kfree_rcu(map, rcu);
9ea19481d   John Fastabend   net: zero kobject...
837
  	}
6e3f7faf3   Eric Dumazet   rps: add __rcu an...
838

33d480ce6   Eric Dumazet   net: cleanup some...
839
  	flow_table = rcu_dereference_protected(queue->rps_flow_table, 1);
9ea19481d   John Fastabend   net: zero kobject...
840
841
  	if (flow_table) {
  		RCU_INIT_POINTER(queue->rps_flow_table, NULL);
6e3f7faf3   Eric Dumazet   rps: add __rcu an...
842
  		call_rcu(&flow_table->rcu, rps_dev_flow_table_release);
9ea19481d   John Fastabend   net: zero kobject...
843
  	}
a953be53c   Michael Dalton   net-sysfs: add su...
844
  #endif
0a9627f26   Tom Herbert   rps: Receive Pack...
845

9ea19481d   John Fastabend   net: zero kobject...
846
  	memset(kobj, 0, sizeof(*kobj));
fe8222406   Tom Herbert   net: Simplify RX ...
847
  	dev_put(queue->dev);
0a9627f26   Tom Herbert   rps: Receive Pack...
848
  }
82ef3d5d5   Weilong Chen   net: fix "queues"...
849
850
851
852
853
854
855
856
857
858
859
  static const void *rx_queue_namespace(struct kobject *kobj)
  {
  	struct netdev_rx_queue *queue = to_rx_queue(kobj);
  	struct device *dev = &queue->dev->dev;
  	const void *ns = NULL;
  
  	if (dev->class && dev->class->ns_type)
  		ns = dev->class->namespace(dev);
  
  	return ns;
  }
667e427bc   stephen hemminger   net: mark receive...
860
  static struct kobj_type rx_queue_ktype __ro_after_init = {
0a9627f26   Tom Herbert   rps: Receive Pack...
861
862
863
  	.sysfs_ops = &rx_queue_sysfs_ops,
  	.release = rx_queue_release,
  	.default_attrs = rx_queue_default_attrs,
82ef3d5d5   Weilong Chen   net: fix "queues"...
864
  	.namespace = rx_queue_namespace
0a9627f26   Tom Herbert   rps: Receive Pack...
865
  };
6b53dafe2   WANG Cong   net: do not name ...
866
  static int rx_queue_add_kobject(struct net_device *dev, int index)
0a9627f26   Tom Herbert   rps: Receive Pack...
867
  {
6b53dafe2   WANG Cong   net: do not name ...
868
  	struct netdev_rx_queue *queue = dev->_rx + index;
0a9627f26   Tom Herbert   rps: Receive Pack...
869
870
  	struct kobject *kobj = &queue->kobj;
  	int error = 0;
6b53dafe2   WANG Cong   net: do not name ...
871
  	kobj->kset = dev->queues_kset;
0a9627f26   Tom Herbert   rps: Receive Pack...
872
  	error = kobject_init_and_add(kobj, &rx_queue_ktype, NULL,
6648c65e7   stephen hemminger   net: style cleanups
873
  				     "rx-%u", index);
a953be53c   Michael Dalton   net-sysfs: add su...
874
  	if (error)
d0d668371   stephen hemminger   net: don't decrem...
875
  		return error;
a953be53c   Michael Dalton   net-sysfs: add su...
876

6b53dafe2   WANG Cong   net: do not name ...
877
878
  	if (dev->sysfs_rx_queue_group) {
  		error = sysfs_create_group(kobj, dev->sysfs_rx_queue_group);
d0d668371   stephen hemminger   net: don't decrem...
879
880
881
882
  		if (error) {
  			kobject_put(kobj);
  			return error;
  		}
0a9627f26   Tom Herbert   rps: Receive Pack...
883
884
885
  	}
  
  	kobject_uevent(kobj, KOBJ_ADD);
fe8222406   Tom Herbert   net: Simplify RX ...
886
  	dev_hold(queue->dev);
0a9627f26   Tom Herbert   rps: Receive Pack...
887
888
889
  
  	return error;
  }
80dd6eac0   Paul Bolle   net-sysfs: fix co...
890
  #endif /* CONFIG_SYSFS */
0a9627f26   Tom Herbert   rps: Receive Pack...
891

62fe0b40a   Ben Hutchings   net: Allow changi...
892
  int
6b53dafe2   WANG Cong   net: do not name ...
893
  net_rx_queue_update_kobjects(struct net_device *dev, int old_num, int new_num)
0a9627f26   Tom Herbert   rps: Receive Pack...
894
  {
a953be53c   Michael Dalton   net-sysfs: add su...
895
  #ifdef CONFIG_SYSFS
0a9627f26   Tom Herbert   rps: Receive Pack...
896
897
  	int i;
  	int error = 0;
a953be53c   Michael Dalton   net-sysfs: add su...
898
  #ifndef CONFIG_RPS
6b53dafe2   WANG Cong   net: do not name ...
899
  	if (!dev->sysfs_rx_queue_group)
a953be53c   Michael Dalton   net-sysfs: add su...
900
901
  		return 0;
  #endif
62fe0b40a   Ben Hutchings   net: Allow changi...
902
  	for (i = old_num; i < new_num; i++) {
6b53dafe2   WANG Cong   net: do not name ...
903
  		error = rx_queue_add_kobject(dev, i);
62fe0b40a   Ben Hutchings   net: Allow changi...
904
905
  		if (error) {
  			new_num = old_num;
0a9627f26   Tom Herbert   rps: Receive Pack...
906
  			break;
62fe0b40a   Ben Hutchings   net: Allow changi...
907
  		}
0a9627f26   Tom Herbert   rps: Receive Pack...
908
  	}
a953be53c   Michael Dalton   net-sysfs: add su...
909
  	while (--i >= new_num) {
002d8a1a6   Andrey Vagin   net: skip genener...
910
  		struct kobject *kobj = &dev->_rx[i].kobj;
91864f585   Andrey Vagin   net: use net->cou...
911
  		if (!atomic_read(&dev_net(dev)->count))
002d8a1a6   Andrey Vagin   net: skip genener...
912
  			kobj->uevent_suppress = 1;
6b53dafe2   WANG Cong   net: do not name ...
913
  		if (dev->sysfs_rx_queue_group)
002d8a1a6   Andrey Vagin   net: skip genener...
914
915
  			sysfs_remove_group(kobj, dev->sysfs_rx_queue_group);
  		kobject_put(kobj);
a953be53c   Michael Dalton   net-sysfs: add su...
916
  	}
0a9627f26   Tom Herbert   rps: Receive Pack...
917
918
  
  	return error;
bf2641451   Tom Herbert   xps: Add CONFIG_XPS
919
920
921
  #else
  	return 0;
  #endif
0a9627f26   Tom Herbert   rps: Receive Pack...
922
  }
ccf5ff69f   david decotigny   net: new counter ...
923
  #ifdef CONFIG_SYSFS
1d24eb481   Tom Herbert   xps: Transmit Pac...
924
925
926
927
928
  /*
   * netdev_queue sysfs structures and functions.
   */
  struct netdev_queue_attribute {
  	struct attribute attr;
718ad681e   stephen hemminger   net: drop unused ...
929
  	ssize_t (*show)(struct netdev_queue *queue, char *buf);
1d24eb481   Tom Herbert   xps: Transmit Pac...
930
  	ssize_t (*store)(struct netdev_queue *queue,
718ad681e   stephen hemminger   net: drop unused ...
931
  			 const char *buf, size_t len);
1d24eb481   Tom Herbert   xps: Transmit Pac...
932
  };
6648c65e7   stephen hemminger   net: style cleanups
933
934
  #define to_netdev_queue_attr(_attr) \
  	container_of(_attr, struct netdev_queue_attribute, attr)
1d24eb481   Tom Herbert   xps: Transmit Pac...
935
936
937
938
939
940
  
  #define to_netdev_queue(obj) container_of(obj, struct netdev_queue, kobj)
  
  static ssize_t netdev_queue_attr_show(struct kobject *kobj,
  				      struct attribute *attr, char *buf)
  {
667e427bc   stephen hemminger   net: mark receive...
941
942
  	const struct netdev_queue_attribute *attribute
  		= to_netdev_queue_attr(attr);
1d24eb481   Tom Herbert   xps: Transmit Pac...
943
944
945
946
  	struct netdev_queue *queue = to_netdev_queue(kobj);
  
  	if (!attribute->show)
  		return -EIO;
718ad681e   stephen hemminger   net: drop unused ...
947
  	return attribute->show(queue, buf);
1d24eb481   Tom Herbert   xps: Transmit Pac...
948
949
950
951
952
953
  }
  
  static ssize_t netdev_queue_attr_store(struct kobject *kobj,
  				       struct attribute *attr,
  				       const char *buf, size_t count)
  {
667e427bc   stephen hemminger   net: mark receive...
954
955
  	const struct netdev_queue_attribute *attribute
  		= to_netdev_queue_attr(attr);
1d24eb481   Tom Herbert   xps: Transmit Pac...
956
957
958
959
  	struct netdev_queue *queue = to_netdev_queue(kobj);
  
  	if (!attribute->store)
  		return -EIO;
718ad681e   stephen hemminger   net: drop unused ...
960
  	return attribute->store(queue, buf, count);
1d24eb481   Tom Herbert   xps: Transmit Pac...
961
962
963
964
965
966
  }
  
  static const struct sysfs_ops netdev_queue_sysfs_ops = {
  	.show = netdev_queue_attr_show,
  	.store = netdev_queue_attr_store,
  };
2b9c75812   stephen hemminger   net: make queue a...
967
  static ssize_t tx_timeout_show(struct netdev_queue *queue, char *buf)
ccf5ff69f   david decotigny   net: new counter ...
968
969
970
971
972
973
974
975
976
  {
  	unsigned long trans_timeout;
  
  	spin_lock_irq(&queue->_xmit_lock);
  	trans_timeout = queue->trans_timeout;
  	spin_unlock_irq(&queue->_xmit_lock);
  
  	return sprintf(buf, "%lu", trans_timeout);
  }
c4047f533   Thadeu Lima de Souza Cascardo   net-sysfs: get_ne...
977
  static unsigned int get_netdev_queue_index(struct netdev_queue *queue)
822b3b2eb   John Fastabend   net: Add max rate...
978
979
  {
  	struct net_device *dev = queue->dev;
c4047f533   Thadeu Lima de Souza Cascardo   net-sysfs: get_ne...
980
  	unsigned int i;
822b3b2eb   John Fastabend   net: Add max rate...
981

c4047f533   Thadeu Lima de Souza Cascardo   net-sysfs: get_ne...
982
  	i = queue - dev->_tx;
822b3b2eb   John Fastabend   net: Add max rate...
983
984
985
986
  	BUG_ON(i >= dev->num_tx_queues);
  
  	return i;
  }
2b9c75812   stephen hemminger   net: make queue a...
987
  static ssize_t traffic_class_show(struct netdev_queue *queue,
8d059b0f6   Alexander Duyck   net: Add sysfs va...
988
989
990
991
992
993
994
995
996
997
998
999
1000
1001
  				  char *buf)
  {
  	struct net_device *dev = queue->dev;
  	int index = get_netdev_queue_index(queue);
  	int tc = netdev_txq_to_tc(dev, index);
  
  	if (tc < 0)
  		return -EINVAL;
  
  	return sprintf(buf, "%u
  ", tc);
  }
  
  #ifdef CONFIG_XPS
2b9c75812   stephen hemminger   net: make queue a...
1002
  static ssize_t tx_maxrate_show(struct netdev_queue *queue,
822b3b2eb   John Fastabend   net: Add max rate...
1003
1004
1005
1006
1007
  			       char *buf)
  {
  	return sprintf(buf, "%lu
  ", queue->tx_maxrate);
  }
2b9c75812   stephen hemminger   net: make queue a...
1008
1009
  static ssize_t tx_maxrate_store(struct netdev_queue *queue,
  				const char *buf, size_t len)
822b3b2eb   John Fastabend   net: Add max rate...
1010
1011
1012
1013
1014
1015
1016
1017
1018
1019
1020
1021
1022
1023
1024
1025
1026
1027
1028
1029
1030
1031
1032
  {
  	struct net_device *dev = queue->dev;
  	int err, index = get_netdev_queue_index(queue);
  	u32 rate = 0;
  
  	err = kstrtou32(buf, 10, &rate);
  	if (err < 0)
  		return err;
  
  	if (!rtnl_trylock())
  		return restart_syscall();
  
  	err = -EOPNOTSUPP;
  	if (dev->netdev_ops->ndo_set_tx_maxrate)
  		err = dev->netdev_ops->ndo_set_tx_maxrate(dev, index, rate);
  
  	rtnl_unlock();
  	if (!err) {
  		queue->tx_maxrate = rate;
  		return len;
  	}
  	return err;
  }
2b9c75812   stephen hemminger   net: make queue a...
1033
1034
  static struct netdev_queue_attribute queue_tx_maxrate __ro_after_init
  	= __ATTR_RW(tx_maxrate);
822b3b2eb   John Fastabend   net: Add max rate...
1035
  #endif
2b9c75812   stephen hemminger   net: make queue a...
1036
1037
  static struct netdev_queue_attribute queue_trans_timeout __ro_after_init
  	= __ATTR_RO(tx_timeout);
ccf5ff69f   david decotigny   net: new counter ...
1038

2b9c75812   stephen hemminger   net: make queue a...
1039
1040
  static struct netdev_queue_attribute queue_traffic_class __ro_after_init
  	= __ATTR_RO(traffic_class);
8d059b0f6   Alexander Duyck   net: Add sysfs va...
1041

114cf5802   Tom Herbert   bql: Byte queue l...
1042
1043
1044
1045
1046
1047
1048
1049
1050
1051
1052
1053
1054
1055
1056
  #ifdef CONFIG_BQL
  /*
   * Byte queue limits sysfs structures and functions.
   */
  static ssize_t bql_show(char *buf, unsigned int value)
  {
  	return sprintf(buf, "%u
  ", value);
  }
  
  static ssize_t bql_set(const char *buf, const size_t count,
  		       unsigned int *pvalue)
  {
  	unsigned int value;
  	int err;
6648c65e7   stephen hemminger   net: style cleanups
1057
1058
  	if (!strcmp(buf, "max") || !strcmp(buf, "max
  ")) {
114cf5802   Tom Herbert   bql: Byte queue l...
1059
  		value = DQL_MAX_LIMIT;
6648c65e7   stephen hemminger   net: style cleanups
1060
  	} else {
114cf5802   Tom Herbert   bql: Byte queue l...
1061
1062
1063
1064
1065
1066
1067
1068
1069
1070
1071
1072
1073
  		err = kstrtouint(buf, 10, &value);
  		if (err < 0)
  			return err;
  		if (value > DQL_MAX_LIMIT)
  			return -EINVAL;
  	}
  
  	*pvalue = value;
  
  	return count;
  }
  
  static ssize_t bql_show_hold_time(struct netdev_queue *queue,
114cf5802   Tom Herbert   bql: Byte queue l...
1074
1075
1076
1077
1078
1079
1080
1081
1082
  				  char *buf)
  {
  	struct dql *dql = &queue->dql;
  
  	return sprintf(buf, "%u
  ", jiffies_to_msecs(dql->slack_hold_time));
  }
  
  static ssize_t bql_set_hold_time(struct netdev_queue *queue,
114cf5802   Tom Herbert   bql: Byte queue l...
1083
1084
1085
  				 const char *buf, size_t len)
  {
  	struct dql *dql = &queue->dql;
95c961747   Eric Dumazet   net: cleanup unsi...
1086
  	unsigned int value;
114cf5802   Tom Herbert   bql: Byte queue l...
1087
1088
1089
1090
1091
1092
1093
1094
1095
1096
  	int err;
  
  	err = kstrtouint(buf, 10, &value);
  	if (err < 0)
  		return err;
  
  	dql->slack_hold_time = msecs_to_jiffies(value);
  
  	return len;
  }
170c658af   stephen hemminger   net: make BQL sys...
1097
1098
1099
  static struct netdev_queue_attribute bql_hold_time_attribute __ro_after_init
  	= __ATTR(hold_time, S_IRUGO | S_IWUSR,
  		 bql_show_hold_time, bql_set_hold_time);
114cf5802   Tom Herbert   bql: Byte queue l...
1100
1101
  
  static ssize_t bql_show_inflight(struct netdev_queue *queue,
114cf5802   Tom Herbert   bql: Byte queue l...
1102
1103
1104
1105
1106
1107
1108
  				 char *buf)
  {
  	struct dql *dql = &queue->dql;
  
  	return sprintf(buf, "%u
  ", dql->num_queued - dql->num_completed);
  }
170c658af   stephen hemminger   net: make BQL sys...
1109
  static struct netdev_queue_attribute bql_inflight_attribute __ro_after_init =
795d9a253   Hiroaki SHIMODA   bql: Fix inconsis...
1110
  	__ATTR(inflight, S_IRUGO, bql_show_inflight, NULL);
114cf5802   Tom Herbert   bql: Byte queue l...
1111
1112
1113
  
  #define BQL_ATTR(NAME, FIELD)						\
  static ssize_t bql_show_ ## NAME(struct netdev_queue *queue,		\
114cf5802   Tom Herbert   bql: Byte queue l...
1114
1115
1116
1117
1118
1119
  				 char *buf)				\
  {									\
  	return bql_show(buf, queue->dql.FIELD);				\
  }									\
  									\
  static ssize_t bql_set_ ## NAME(struct netdev_queue *queue,		\
114cf5802   Tom Herbert   bql: Byte queue l...
1120
1121
1122
1123
1124
  				const char *buf, size_t len)		\
  {									\
  	return bql_set(buf, len, &queue->dql.FIELD);			\
  }									\
  									\
170c658af   stephen hemminger   net: make BQL sys...
1125
1126
1127
  static struct netdev_queue_attribute bql_ ## NAME ## _attribute __ro_after_init \
  	= __ATTR(NAME, S_IRUGO | S_IWUSR,				\
  		 bql_show_ ## NAME, bql_set_ ## NAME)
114cf5802   Tom Herbert   bql: Byte queue l...
1128

170c658af   stephen hemminger   net: make BQL sys...
1129
1130
1131
  BQL_ATTR(limit, limit);
  BQL_ATTR(limit_max, max_limit);
  BQL_ATTR(limit_min, min_limit);
114cf5802   Tom Herbert   bql: Byte queue l...
1132

170c658af   stephen hemminger   net: make BQL sys...
1133
  static struct attribute *dql_attrs[] __ro_after_init = {
114cf5802   Tom Herbert   bql: Byte queue l...
1134
1135
1136
1137
1138
1139
1140
  	&bql_limit_attribute.attr,
  	&bql_limit_max_attribute.attr,
  	&bql_limit_min_attribute.attr,
  	&bql_hold_time_attribute.attr,
  	&bql_inflight_attribute.attr,
  	NULL
  };
38ef00cc3   Arvind Yadav   net: constify att...
1141
  static const struct attribute_group dql_group = {
114cf5802   Tom Herbert   bql: Byte queue l...
1142
1143
1144
1145
  	.name  = "byte_queue_limits",
  	.attrs  = dql_attrs,
  };
  #endif /* CONFIG_BQL */
ccf5ff69f   david decotigny   net: new counter ...
1146
  #ifdef CONFIG_XPS
2b9c75812   stephen hemminger   net: make queue a...
1147
1148
  static ssize_t xps_cpus_show(struct netdev_queue *queue,
  			     char *buf)
1d24eb481   Tom Herbert   xps: Transmit Pac...
1149
1150
  {
  	struct net_device *dev = queue->dev;
184c449f9   Alexander Duyck   net: Add support ...
1151
  	int cpu, len, num_tc = 1, tc = 0;
1d24eb481   Tom Herbert   xps: Transmit Pac...
1152
1153
1154
  	struct xps_dev_maps *dev_maps;
  	cpumask_var_t mask;
  	unsigned long index;
1d24eb481   Tom Herbert   xps: Transmit Pac...
1155

1d24eb481   Tom Herbert   xps: Transmit Pac...
1156
  	index = get_netdev_queue_index(queue);
184c449f9   Alexander Duyck   net: Add support ...
1157
1158
1159
1160
1161
1162
  	if (dev->num_tc) {
  		num_tc = dev->num_tc;
  		tc = netdev_txq_to_tc(dev, index);
  		if (tc < 0)
  			return -EINVAL;
  	}
0dbd822f6   Alexander Duyck   net-sysfs: Fix me...
1163
1164
  	if (!zalloc_cpumask_var(&mask, GFP_KERNEL))
  		return -ENOMEM;
1d24eb481   Tom Herbert   xps: Transmit Pac...
1165
1166
1167
  	rcu_read_lock();
  	dev_maps = rcu_dereference(dev->xps_maps);
  	if (dev_maps) {
184c449f9   Alexander Duyck   net: Add support ...
1168
1169
1170
1171
1172
1173
1174
1175
1176
1177
1178
1179
  		for_each_possible_cpu(cpu) {
  			int i, tci = cpu * num_tc + tc;
  			struct xps_map *map;
  
  			map = rcu_dereference(dev_maps->cpu_map[tci]);
  			if (!map)
  				continue;
  
  			for (i = map->len; i--;) {
  				if (map->queues[i] == index) {
  					cpumask_set_cpu(cpu, mask);
  					break;
1d24eb481   Tom Herbert   xps: Transmit Pac...
1180
1181
1182
1183
1184
  				}
  			}
  		}
  	}
  	rcu_read_unlock();
f09068276   Tejun Heo   net: use %*pb[l] ...
1185
1186
  	len = snprintf(buf, PAGE_SIZE, "%*pb
  ", cpumask_pr_args(mask));
1d24eb481   Tom Herbert   xps: Transmit Pac...
1187
  	free_cpumask_var(mask);
f09068276   Tejun Heo   net: use %*pb[l] ...
1188
  	return len < PAGE_SIZE ? len : -EINVAL;
1d24eb481   Tom Herbert   xps: Transmit Pac...
1189
  }
2b9c75812   stephen hemminger   net: make queue a...
1190
1191
  static ssize_t xps_cpus_store(struct netdev_queue *queue,
  			      const char *buf, size_t len)
1d24eb481   Tom Herbert   xps: Transmit Pac...
1192
1193
  {
  	struct net_device *dev = queue->dev;
1d24eb481   Tom Herbert   xps: Transmit Pac...
1194
  	unsigned long index;
537c00de1   Alexander Duyck   net: Add function...
1195
1196
  	cpumask_var_t mask;
  	int err;
1d24eb481   Tom Herbert   xps: Transmit Pac...
1197
1198
1199
1200
1201
1202
1203
1204
1205
1206
1207
1208
1209
1210
  
  	if (!capable(CAP_NET_ADMIN))
  		return -EPERM;
  
  	if (!alloc_cpumask_var(&mask, GFP_KERNEL))
  		return -ENOMEM;
  
  	index = get_netdev_queue_index(queue);
  
  	err = bitmap_parse(buf, len, cpumask_bits(mask), nr_cpumask_bits);
  	if (err) {
  		free_cpumask_var(mask);
  		return err;
  	}
537c00de1   Alexander Duyck   net: Add function...
1211
  	err = netif_set_xps_queue(dev, mask, index);
1d24eb481   Tom Herbert   xps: Transmit Pac...
1212
1213
  
  	free_cpumask_var(mask);
1d24eb481   Tom Herbert   xps: Transmit Pac...
1214

537c00de1   Alexander Duyck   net: Add function...
1215
  	return err ? : len;
1d24eb481   Tom Herbert   xps: Transmit Pac...
1216
  }
2b9c75812   stephen hemminger   net: make queue a...
1217
1218
  static struct netdev_queue_attribute xps_cpus_attribute __ro_after_init
  	= __ATTR_RW(xps_cpus);
ccf5ff69f   david decotigny   net: new counter ...
1219
  #endif /* CONFIG_XPS */
1d24eb481   Tom Herbert   xps: Transmit Pac...
1220

2b9c75812   stephen hemminger   net: make queue a...
1221
  static struct attribute *netdev_queue_default_attrs[] __ro_after_init = {
ccf5ff69f   david decotigny   net: new counter ...
1222
  	&queue_trans_timeout.attr,
8d059b0f6   Alexander Duyck   net: Add sysfs va...
1223
  	&queue_traffic_class.attr,
ccf5ff69f   david decotigny   net: new counter ...
1224
  #ifdef CONFIG_XPS
1d24eb481   Tom Herbert   xps: Transmit Pac...
1225
  	&xps_cpus_attribute.attr,
822b3b2eb   John Fastabend   net: Add max rate...
1226
  	&queue_tx_maxrate.attr,
ccf5ff69f   david decotigny   net: new counter ...
1227
  #endif
1d24eb481   Tom Herbert   xps: Transmit Pac...
1228
1229
1230
1231
1232
1233
  	NULL
  };
  
  static void netdev_queue_release(struct kobject *kobj)
  {
  	struct netdev_queue *queue = to_netdev_queue(kobj);
1d24eb481   Tom Herbert   xps: Transmit Pac...
1234

1d24eb481   Tom Herbert   xps: Transmit Pac...
1235
1236
1237
  	memset(kobj, 0, sizeof(*kobj));
  	dev_put(queue->dev);
  }
82ef3d5d5   Weilong Chen   net: fix "queues"...
1238
1239
1240
1241
1242
1243
1244
1245
1246
1247
1248
  static const void *netdev_queue_namespace(struct kobject *kobj)
  {
  	struct netdev_queue *queue = to_netdev_queue(kobj);
  	struct device *dev = &queue->dev->dev;
  	const void *ns = NULL;
  
  	if (dev->class && dev->class->ns_type)
  		ns = dev->class->namespace(dev);
  
  	return ns;
  }
2b9c75812   stephen hemminger   net: make queue a...
1249
  static struct kobj_type netdev_queue_ktype __ro_after_init = {
1d24eb481   Tom Herbert   xps: Transmit Pac...
1250
1251
1252
  	.sysfs_ops = &netdev_queue_sysfs_ops,
  	.release = netdev_queue_release,
  	.default_attrs = netdev_queue_default_attrs,
82ef3d5d5   Weilong Chen   net: fix "queues"...
1253
  	.namespace = netdev_queue_namespace,
1d24eb481   Tom Herbert   xps: Transmit Pac...
1254
  };
6b53dafe2   WANG Cong   net: do not name ...
1255
  static int netdev_queue_add_kobject(struct net_device *dev, int index)
1d24eb481   Tom Herbert   xps: Transmit Pac...
1256
  {
6b53dafe2   WANG Cong   net: do not name ...
1257
  	struct netdev_queue *queue = dev->_tx + index;
1d24eb481   Tom Herbert   xps: Transmit Pac...
1258
1259
  	struct kobject *kobj = &queue->kobj;
  	int error = 0;
6b53dafe2   WANG Cong   net: do not name ...
1260
  	kobj->kset = dev->queues_kset;
1d24eb481   Tom Herbert   xps: Transmit Pac...
1261
  	error = kobject_init_and_add(kobj, &netdev_queue_ktype, NULL,
6648c65e7   stephen hemminger   net: style cleanups
1262
  				     "tx-%u", index);
114cf5802   Tom Herbert   bql: Byte queue l...
1263
  	if (error)
d0d668371   stephen hemminger   net: don't decrem...
1264
  		return error;
114cf5802   Tom Herbert   bql: Byte queue l...
1265
1266
1267
  
  #ifdef CONFIG_BQL
  	error = sysfs_create_group(kobj, &dql_group);
d0d668371   stephen hemminger   net: don't decrem...
1268
1269
1270
1271
  	if (error) {
  		kobject_put(kobj);
  		return error;
  	}
114cf5802   Tom Herbert   bql: Byte queue l...
1272
  #endif
1d24eb481   Tom Herbert   xps: Transmit Pac...
1273
1274
1275
  
  	kobject_uevent(kobj, KOBJ_ADD);
  	dev_hold(queue->dev);
114cf5802   Tom Herbert   bql: Byte queue l...
1276
  	return 0;
1d24eb481   Tom Herbert   xps: Transmit Pac...
1277
  }
ccf5ff69f   david decotigny   net: new counter ...
1278
  #endif /* CONFIG_SYSFS */
1d24eb481   Tom Herbert   xps: Transmit Pac...
1279
1280
  
  int
6b53dafe2   WANG Cong   net: do not name ...
1281
  netdev_queue_update_kobjects(struct net_device *dev, int old_num, int new_num)
1d24eb481   Tom Herbert   xps: Transmit Pac...
1282
  {
ccf5ff69f   david decotigny   net: new counter ...
1283
  #ifdef CONFIG_SYSFS
1d24eb481   Tom Herbert   xps: Transmit Pac...
1284
1285
1286
1287
  	int i;
  	int error = 0;
  
  	for (i = old_num; i < new_num; i++) {
6b53dafe2   WANG Cong   net: do not name ...
1288
  		error = netdev_queue_add_kobject(dev, i);
1d24eb481   Tom Herbert   xps: Transmit Pac...
1289
1290
1291
1292
1293
  		if (error) {
  			new_num = old_num;
  			break;
  		}
  	}
114cf5802   Tom Herbert   bql: Byte queue l...
1294
  	while (--i >= new_num) {
6b53dafe2   WANG Cong   net: do not name ...
1295
  		struct netdev_queue *queue = dev->_tx + i;
114cf5802   Tom Herbert   bql: Byte queue l...
1296

91864f585   Andrey Vagin   net: use net->cou...
1297
  		if (!atomic_read(&dev_net(dev)->count))
002d8a1a6   Andrey Vagin   net: skip genener...
1298
  			queue->kobj.uevent_suppress = 1;
114cf5802   Tom Herbert   bql: Byte queue l...
1299
1300
1301
1302
1303
  #ifdef CONFIG_BQL
  		sysfs_remove_group(&queue->kobj, &dql_group);
  #endif
  		kobject_put(&queue->kobj);
  	}
1d24eb481   Tom Herbert   xps: Transmit Pac...
1304
1305
  
  	return error;
bf2641451   Tom Herbert   xps: Add CONFIG_XPS
1306
1307
  #else
  	return 0;
ccf5ff69f   david decotigny   net: new counter ...
1308
  #endif /* CONFIG_SYSFS */
1d24eb481   Tom Herbert   xps: Transmit Pac...
1309
  }
6b53dafe2   WANG Cong   net: do not name ...
1310
  static int register_queue_kobjects(struct net_device *dev)
1d24eb481   Tom Herbert   xps: Transmit Pac...
1311
  {
bf2641451   Tom Herbert   xps: Add CONFIG_XPS
1312
  	int error = 0, txq = 0, rxq = 0, real_rx = 0, real_tx = 0;
1d24eb481   Tom Herbert   xps: Transmit Pac...
1313

ccf5ff69f   david decotigny   net: new counter ...
1314
  #ifdef CONFIG_SYSFS
6b53dafe2   WANG Cong   net: do not name ...
1315
  	dev->queues_kset = kset_create_and_add("queues",
6648c65e7   stephen hemminger   net: style cleanups
1316
  					       NULL, &dev->dev.kobj);
6b53dafe2   WANG Cong   net: do not name ...
1317
  	if (!dev->queues_kset)
62fe0b40a   Ben Hutchings   net: Allow changi...
1318
  		return -ENOMEM;
6b53dafe2   WANG Cong   net: do not name ...
1319
  	real_rx = dev->real_num_rx_queues;
bf2641451   Tom Herbert   xps: Add CONFIG_XPS
1320
  #endif
6b53dafe2   WANG Cong   net: do not name ...
1321
  	real_tx = dev->real_num_tx_queues;
1d24eb481   Tom Herbert   xps: Transmit Pac...
1322

6b53dafe2   WANG Cong   net: do not name ...
1323
  	error = net_rx_queue_update_kobjects(dev, 0, real_rx);
1d24eb481   Tom Herbert   xps: Transmit Pac...
1324
1325
  	if (error)
  		goto error;
bf2641451   Tom Herbert   xps: Add CONFIG_XPS
1326
  	rxq = real_rx;
1d24eb481   Tom Herbert   xps: Transmit Pac...
1327

6b53dafe2   WANG Cong   net: do not name ...
1328
  	error = netdev_queue_update_kobjects(dev, 0, real_tx);
1d24eb481   Tom Herbert   xps: Transmit Pac...
1329
1330
  	if (error)
  		goto error;
bf2641451   Tom Herbert   xps: Add CONFIG_XPS
1331
  	txq = real_tx;
1d24eb481   Tom Herbert   xps: Transmit Pac...
1332
1333
1334
1335
  
  	return 0;
  
  error:
6b53dafe2   WANG Cong   net: do not name ...
1336
1337
  	netdev_queue_update_kobjects(dev, txq, 0);
  	net_rx_queue_update_kobjects(dev, rxq, 0);
1d24eb481   Tom Herbert   xps: Transmit Pac...
1338
  	return error;
62fe0b40a   Ben Hutchings   net: Allow changi...
1339
  }
0a9627f26   Tom Herbert   rps: Receive Pack...
1340

6b53dafe2   WANG Cong   net: do not name ...
1341
  static void remove_queue_kobjects(struct net_device *dev)
62fe0b40a   Ben Hutchings   net: Allow changi...
1342
  {
bf2641451   Tom Herbert   xps: Add CONFIG_XPS
1343
  	int real_rx = 0, real_tx = 0;
a953be53c   Michael Dalton   net-sysfs: add su...
1344
  #ifdef CONFIG_SYSFS
6b53dafe2   WANG Cong   net: do not name ...
1345
  	real_rx = dev->real_num_rx_queues;
bf2641451   Tom Herbert   xps: Add CONFIG_XPS
1346
  #endif
6b53dafe2   WANG Cong   net: do not name ...
1347
  	real_tx = dev->real_num_tx_queues;
bf2641451   Tom Herbert   xps: Add CONFIG_XPS
1348

6b53dafe2   WANG Cong   net: do not name ...
1349
1350
  	net_rx_queue_update_kobjects(dev, real_rx, 0);
  	netdev_queue_update_kobjects(dev, real_tx, 0);
ccf5ff69f   david decotigny   net: new counter ...
1351
  #ifdef CONFIG_SYSFS
6b53dafe2   WANG Cong   net: do not name ...
1352
  	kset_unregister(dev->queues_kset);
bf2641451   Tom Herbert   xps: Add CONFIG_XPS
1353
  #endif
0a9627f26   Tom Herbert   rps: Receive Pack...
1354
  }
608b4b954   Eric W. Biederman   netns: Teach netw...
1355

7dc5dbc87   Eric W. Biederman   sysfs: Restrict m...
1356
1357
1358
1359
1360
1361
  static bool net_current_may_mount(void)
  {
  	struct net *net = current->nsproxy->net_ns;
  
  	return ns_capable(net->user_ns, CAP_SYS_ADMIN);
  }
a685e0898   Al Viro   Delay struct net ...
1362
  static void *net_grab_current_ns(void)
608b4b954   Eric W. Biederman   netns: Teach netw...
1363
  {
a685e0898   Al Viro   Delay struct net ...
1364
1365
1366
  	struct net *ns = current->nsproxy->net_ns;
  #ifdef CONFIG_NET_NS
  	if (ns)
c122e14df   Reshetova, Elena   net: convert net....
1367
  		refcount_inc(&ns->passive);
a685e0898   Al Viro   Delay struct net ...
1368
1369
  #endif
  	return ns;
608b4b954   Eric W. Biederman   netns: Teach netw...
1370
1371
1372
1373
1374
1375
1376
1377
1378
1379
1380
  }
  
  static const void *net_initial_ns(void)
  {
  	return &init_net;
  }
  
  static const void *net_netlink_ns(struct sock *sk)
  {
  	return sock_net(sk);
  }
737aec57c   stephen hemminger   net: constify net...
1381
  const struct kobj_ns_type_operations net_ns_type_operations = {
608b4b954   Eric W. Biederman   netns: Teach netw...
1382
  	.type = KOBJ_NS_TYPE_NET,
7dc5dbc87   Eric W. Biederman   sysfs: Restrict m...
1383
  	.current_may_mount = net_current_may_mount,
a685e0898   Al Viro   Delay struct net ...
1384
  	.grab_current_ns = net_grab_current_ns,
608b4b954   Eric W. Biederman   netns: Teach netw...
1385
1386
  	.netlink_ns = net_netlink_ns,
  	.initial_ns = net_initial_ns,
a685e0898   Al Viro   Delay struct net ...
1387
  	.drop_ns = net_drop_ns,
608b4b954   Eric W. Biederman   netns: Teach netw...
1388
  };
046007949   Johannes Berg   cfg80211: support...
1389
  EXPORT_SYMBOL_GPL(net_ns_type_operations);
608b4b954   Eric W. Biederman   netns: Teach netw...
1390

7eff2e7a8   Kay Sievers   Driver core: chan...
1391
  static int netdev_uevent(struct device *d, struct kobj_uevent_env *env)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1392
  {
43cb76d91   Greg Kroah-Hartman   Network: convert ...
1393
  	struct net_device *dev = to_net_dev(d);
7eff2e7a8   Kay Sievers   Driver core: chan...
1394
  	int retval;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1395

312c004d3   Kay Sievers   [PATCH] driver co...
1396
  	/* pass interface to uevent. */
7eff2e7a8   Kay Sievers   Driver core: chan...
1397
  	retval = add_uevent_var(env, "INTERFACE=%s", dev->name);
bf62456eb   Eric Rannaud   uevent: use add_u...
1398
1399
  	if (retval)
  		goto exit;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1400

ca2f37dbc   Jean Tourrilhes   Driver core: noti...
1401
1402
  	/* pass ifindex to uevent.
  	 * ifindex is useful as it won't change (interface name may change)
6648c65e7   stephen hemminger   net: style cleanups
1403
1404
  	 * and is what RtNetlink uses natively.
  	 */
7eff2e7a8   Kay Sievers   Driver core: chan...
1405
  	retval = add_uevent_var(env, "IFINDEX=%d", dev->ifindex);
ca2f37dbc   Jean Tourrilhes   Driver core: noti...
1406

bf62456eb   Eric Rannaud   uevent: use add_u...
1407
  exit:
bf62456eb   Eric Rannaud   uevent: use add_u...
1408
  	return retval;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1409
  }
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1410
1411
  
  /*
4ec93edb1   YOSHIFUJI Hideaki   [NET] CORE: Fix w...
1412
   *	netdev_release -- destroy and free a dead device.
43cb76d91   Greg Kroah-Hartman   Network: convert ...
1413
   *	Called when last reference to device kobject is gone.
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1414
   */
43cb76d91   Greg Kroah-Hartman   Network: convert ...
1415
  static void netdev_release(struct device *d)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1416
  {
43cb76d91   Greg Kroah-Hartman   Network: convert ...
1417
  	struct net_device *dev = to_net_dev(d);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1418
1419
  
  	BUG_ON(dev->reg_state != NETREG_RELEASED);
0b815a1a6   Stephen Hemminger   net: network devi...
1420
  	kfree(dev->ifalias);
74d332c13   Eric Dumazet   net: extend net_d...
1421
  	netdev_freemem(dev);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1422
  }
608b4b954   Eric W. Biederman   netns: Teach netw...
1423
1424
  static const void *net_namespace(struct device *d)
  {
5c29482dd   Geliang Tang   net-sysfs: use to...
1425
  	struct net_device *dev = to_net_dev(d);
608b4b954   Eric W. Biederman   netns: Teach netw...
1426
1427
  	return dev_net(dev);
  }
e6d473e63   stephen hemminger   net: make net_cla...
1428
  static struct class net_class __ro_after_init = {
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1429
  	.name = "net",
43cb76d91   Greg Kroah-Hartman   Network: convert ...
1430
  	.dev_release = netdev_release,
6be8aeef3   Greg Kroah-Hartman   net: core: conver...
1431
  	.dev_groups = net_class_groups,
43cb76d91   Greg Kroah-Hartman   Network: convert ...
1432
  	.dev_uevent = netdev_uevent,
608b4b954   Eric W. Biederman   netns: Teach netw...
1433
1434
  	.ns_type = &net_ns_type_operations,
  	.namespace = net_namespace,
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1435
  };
aa836df95   Florian Fainelli   net: core: add of...
1436
1437
1438
1439
1440
1441
1442
1443
1444
1445
  #ifdef CONFIG_OF_NET
  static int of_dev_node_match(struct device *dev, const void *data)
  {
  	int ret = 0;
  
  	if (dev->parent)
  		ret = dev->parent->of_node == data;
  
  	return ret == 0 ? dev->of_node == data : ret;
  }
9861f7207   Russell King   net: fix net_devi...
1446
1447
1448
1449
1450
1451
1452
1453
1454
  /*
   * of_find_net_device_by_node - lookup the net device for the device node
   * @np: OF device node
   *
   * Looks up the net_device structure corresponding with the device node.
   * If successful, returns a pointer to the net_device with the embedded
   * struct device refcount incremented by one, or NULL on failure. The
   * refcount must be dropped when done with the net_device.
   */
aa836df95   Florian Fainelli   net: core: add of...
1455
1456
1457
1458
1459
1460
1461
1462
1463
1464
1465
1466
  struct net_device *of_find_net_device_by_node(struct device_node *np)
  {
  	struct device *dev;
  
  	dev = class_find_device(&net_class, NULL, np, of_dev_node_match);
  	if (!dev)
  		return NULL;
  
  	return to_net_dev(dev);
  }
  EXPORT_SYMBOL(of_find_net_device_by_node);
  #endif
9093bbb2d   Stephen Hemminger   [NET]: Fix race c...
1467
1468
1469
  /* Delete sysfs entries but hold kobject reference until after all
   * netdev references are gone.
   */
6b53dafe2   WANG Cong   net: do not name ...
1470
  void netdev_unregister_kobject(struct net_device *ndev)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1471
  {
6648c65e7   stephen hemminger   net: style cleanups
1472
  	struct device *dev = &ndev->dev;
9093bbb2d   Stephen Hemminger   [NET]: Fix race c...
1473

91864f585   Andrey Vagin   net: use net->cou...
1474
  	if (!atomic_read(&dev_net(ndev)->count))
002d8a1a6   Andrey Vagin   net: skip genener...
1475
  		dev_set_uevent_suppress(dev, 1);
9093bbb2d   Stephen Hemminger   [NET]: Fix race c...
1476
  	kobject_get(&dev->kobj);
3891845e1   Eric W. Biederman   netns: Coexist wi...
1477

6b53dafe2   WANG Cong   net: do not name ...
1478
  	remove_queue_kobjects(ndev);
0a9627f26   Tom Herbert   rps: Receive Pack...
1479

9802c8e22   Ming Lei   net/core: apply p...
1480
  	pm_runtime_set_memalloc_noio(dev, false);
9093bbb2d   Stephen Hemminger   [NET]: Fix race c...
1481
  	device_del(dev);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1482
1483
1484
  }
  
  /* Create sysfs entries for network device. */
6b53dafe2   WANG Cong   net: do not name ...
1485
  int netdev_register_kobject(struct net_device *ndev)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1486
  {
6648c65e7   stephen hemminger   net: style cleanups
1487
  	struct device *dev = &ndev->dev;
6b53dafe2   WANG Cong   net: do not name ...
1488
  	const struct attribute_group **groups = ndev->sysfs_groups;
0a9627f26   Tom Herbert   rps: Receive Pack...
1489
  	int error = 0;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1490

a1b3f594d   Eric W. Biederman   net: Expose all n...
1491
  	device_initialize(dev);
43cb76d91   Greg Kroah-Hartman   Network: convert ...
1492
  	dev->class = &net_class;
6b53dafe2   WANG Cong   net: do not name ...
1493
  	dev->platform_data = ndev;
43cb76d91   Greg Kroah-Hartman   Network: convert ...
1494
  	dev->groups = groups;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1495

6b53dafe2   WANG Cong   net: do not name ...
1496
  	dev_set_name(dev, "%s", ndev->name);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1497

8b41d1887   Eric W. Biederman   [NET]: Fix runnin...
1498
  #ifdef CONFIG_SYSFS
0c509a6c9   Eric W. Biederman   net: Allow device...
1499
1500
1501
  	/* Allow for a device specific group */
  	if (*groups)
  		groups++;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1502

0c509a6c9   Eric W. Biederman   net: Allow device...
1503
  	*groups++ = &netstat_group;
38c1a01cf   Johannes Berg   wireless: add bac...
1504
1505
  
  #if IS_ENABLED(CONFIG_WIRELESS_EXT) || IS_ENABLED(CONFIG_CFG80211)
6b53dafe2   WANG Cong   net: do not name ...
1506
  	if (ndev->ieee80211_ptr)
38c1a01cf   Johannes Berg   wireless: add bac...
1507
1508
  		*groups++ = &wireless_group;
  #if IS_ENABLED(CONFIG_WIRELESS_EXT)
6b53dafe2   WANG Cong   net: do not name ...
1509
  	else if (ndev->wireless_handlers)
38c1a01cf   Johannes Berg   wireless: add bac...
1510
1511
1512
  		*groups++ = &wireless_group;
  #endif
  #endif
8b41d1887   Eric W. Biederman   [NET]: Fix runnin...
1513
  #endif /* CONFIG_SYSFS */
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1514

0a9627f26   Tom Herbert   rps: Receive Pack...
1515
1516
1517
  	error = device_add(dev);
  	if (error)
  		return error;
6b53dafe2   WANG Cong   net: do not name ...
1518
  	error = register_queue_kobjects(ndev);
0a9627f26   Tom Herbert   rps: Receive Pack...
1519
1520
1521
1522
  	if (error) {
  		device_del(dev);
  		return error;
  	}
9802c8e22   Ming Lei   net/core: apply p...
1523
  	pm_runtime_set_memalloc_noio(dev, true);
0a9627f26   Tom Herbert   rps: Receive Pack...
1524
  	return error;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1525
  }
b793dc5c6   stephen hemminger   net: constify net...
1526
  int netdev_class_create_file_ns(const struct class_attribute *class_attr,
58292cbe6   Tejun Heo   sysfs: make attr ...
1527
  				const void *ns)
b8a9787ed   Jay Vosburgh   bonding: Allow se...
1528
  {
58292cbe6   Tejun Heo   sysfs: make attr ...
1529
  	return class_create_file_ns(&net_class, class_attr, ns);
b8a9787ed   Jay Vosburgh   bonding: Allow se...
1530
  }
58292cbe6   Tejun Heo   sysfs: make attr ...
1531
  EXPORT_SYMBOL(netdev_class_create_file_ns);
b8a9787ed   Jay Vosburgh   bonding: Allow se...
1532

b793dc5c6   stephen hemminger   net: constify net...
1533
  void netdev_class_remove_file_ns(const struct class_attribute *class_attr,
58292cbe6   Tejun Heo   sysfs: make attr ...
1534
  				 const void *ns)
b8a9787ed   Jay Vosburgh   bonding: Allow se...
1535
  {
58292cbe6   Tejun Heo   sysfs: make attr ...
1536
  	class_remove_file_ns(&net_class, class_attr, ns);
b8a9787ed   Jay Vosburgh   bonding: Allow se...
1537
  }
58292cbe6   Tejun Heo   sysfs: make attr ...
1538
  EXPORT_SYMBOL(netdev_class_remove_file_ns);
b8a9787ed   Jay Vosburgh   bonding: Allow se...
1539

a48d4bb0b   Daniel Borkmann   net: netdev_kobje...
1540
  int __init netdev_kobject_init(void)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1541
  {
608b4b954   Eric W. Biederman   netns: Teach netw...
1542
  	kobj_ns_type_register(&net_ns_type_operations);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1543
1544
  	return class_register(&net_class);
  }