hc
2023-12-11 d2ccde1c8e90d38cee87a1b0309ad2827f3fd30d
kernel/net/dsa/master.c
....@@ -1,16 +1,76 @@
1
+// SPDX-License-Identifier: GPL-2.0-or-later
12 /*
23 * Handling of a master device, switching frames via its switch fabric CPU port
34 *
45 * Copyright (c) 2017 Savoir-faire Linux Inc.
56 * Vivien Didelot <vivien.didelot@savoirfairelinux.com>
6
- *
7
- * This program is free software; you can redistribute it and/or modify
8
- * it under the terms of the GNU General Public License as published by
9
- * the Free Software Foundation; either version 2 of the License, or
10
- * (at your option) any later version.
117 */
128
139 #include "dsa_priv.h"
10
+
11
+static int dsa_master_get_regs_len(struct net_device *dev)
12
+{
13
+ struct dsa_port *cpu_dp = dev->dsa_ptr;
14
+ const struct ethtool_ops *ops = cpu_dp->orig_ethtool_ops;
15
+ struct dsa_switch *ds = cpu_dp->ds;
16
+ int port = cpu_dp->index;
17
+ int ret = 0;
18
+ int len;
19
+
20
+ if (ops->get_regs_len) {
21
+ len = ops->get_regs_len(dev);
22
+ if (len < 0)
23
+ return len;
24
+ ret += len;
25
+ }
26
+
27
+ ret += sizeof(struct ethtool_drvinfo);
28
+ ret += sizeof(struct ethtool_regs);
29
+
30
+ if (ds->ops->get_regs_len) {
31
+ len = ds->ops->get_regs_len(ds, port);
32
+ if (len < 0)
33
+ return len;
34
+ ret += len;
35
+ }
36
+
37
+ return ret;
38
+}
39
+
40
+static void dsa_master_get_regs(struct net_device *dev,
41
+ struct ethtool_regs *regs, void *data)
42
+{
43
+ struct dsa_port *cpu_dp = dev->dsa_ptr;
44
+ const struct ethtool_ops *ops = cpu_dp->orig_ethtool_ops;
45
+ struct dsa_switch *ds = cpu_dp->ds;
46
+ struct ethtool_drvinfo *cpu_info;
47
+ struct ethtool_regs *cpu_regs;
48
+ int port = cpu_dp->index;
49
+ int len;
50
+
51
+ if (ops->get_regs_len && ops->get_regs) {
52
+ len = ops->get_regs_len(dev);
53
+ if (len < 0)
54
+ return;
55
+ regs->len = len;
56
+ ops->get_regs(dev, regs, data);
57
+ data += regs->len;
58
+ }
59
+
60
+ cpu_info = (struct ethtool_drvinfo *)data;
61
+ strlcpy(cpu_info->driver, "dsa", sizeof(cpu_info->driver));
62
+ data += sizeof(*cpu_info);
63
+ cpu_regs = (struct ethtool_regs *)data;
64
+ data += sizeof(*cpu_regs);
65
+
66
+ if (ds->ops->get_regs_len && ds->ops->get_regs) {
67
+ len = ds->ops->get_regs_len(ds, port);
68
+ if (len < 0)
69
+ return;
70
+ cpu_regs->len = len;
71
+ ds->ops->get_regs(ds, port, cpu_regs, data);
72
+ }
73
+}
1474
1575 static void dsa_master_get_ethtool_stats(struct net_device *dev,
1676 struct ethtool_stats *stats,
....@@ -127,6 +187,39 @@
127187 }
128188 }
129189
190
+static int dsa_master_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd)
191
+{
192
+ struct dsa_port *cpu_dp = dev->dsa_ptr;
193
+ struct dsa_switch *ds = cpu_dp->ds;
194
+ struct dsa_switch_tree *dst;
195
+ int err = -EOPNOTSUPP;
196
+ struct dsa_port *dp;
197
+
198
+ dst = ds->dst;
199
+
200
+ switch (cmd) {
201
+ case SIOCGHWTSTAMP:
202
+ case SIOCSHWTSTAMP:
203
+ /* Deny PTP operations on master if there is at least one
204
+ * switch in the tree that is PTP capable.
205
+ */
206
+ list_for_each_entry(dp, &dst->ports, list)
207
+ if (dp->ds->ops->port_hwtstamp_get ||
208
+ dp->ds->ops->port_hwtstamp_set)
209
+ return -EBUSY;
210
+ break;
211
+ }
212
+
213
+ if (dev->netdev_ops->ndo_do_ioctl)
214
+ err = dev->netdev_ops->ndo_do_ioctl(dev, ifr, cmd);
215
+
216
+ return err;
217
+}
218
+
219
+static const struct dsa_netdevice_ops dsa_netdev_ops = {
220
+ .ndo_do_ioctl = dsa_master_ioctl,
221
+};
222
+
130223 static int dsa_master_ethtool_setup(struct net_device *dev)
131224 {
132225 struct dsa_port *cpu_dp = dev->dsa_ptr;
....@@ -141,6 +234,8 @@
141234 if (cpu_dp->orig_ethtool_ops)
142235 memcpy(ops, cpu_dp->orig_ethtool_ops, sizeof(*ops));
143236
237
+ ops->get_regs_len = dsa_master_get_regs_len;
238
+ ops->get_regs = dsa_master_get_regs;
144239 ops->get_sset_count = dsa_master_get_sset_count;
145240 ops->get_ethtool_stats = dsa_master_get_ethtool_stats;
146241 ops->get_strings = dsa_master_get_strings;
....@@ -159,10 +254,80 @@
159254 cpu_dp->orig_ethtool_ops = NULL;
160255 }
161256
257
+static void dsa_netdev_ops_set(struct net_device *dev,
258
+ const struct dsa_netdevice_ops *ops)
259
+{
260
+ dev->dsa_ptr->netdev_ops = ops;
261
+}
262
+
263
+static void dsa_master_set_promiscuity(struct net_device *dev, int inc)
264
+{
265
+ const struct dsa_device_ops *ops = dev->dsa_ptr->tag_ops;
266
+
267
+ if (!ops->promisc_on_master)
268
+ return;
269
+
270
+ rtnl_lock();
271
+ dev_set_promiscuity(dev, inc);
272
+ rtnl_unlock();
273
+}
274
+
275
+static ssize_t tagging_show(struct device *d, struct device_attribute *attr,
276
+ char *buf)
277
+{
278
+ struct net_device *dev = to_net_dev(d);
279
+ struct dsa_port *cpu_dp = dev->dsa_ptr;
280
+
281
+ return sprintf(buf, "%s\n",
282
+ dsa_tag_protocol_to_str(cpu_dp->tag_ops));
283
+}
284
+static DEVICE_ATTR_RO(tagging);
285
+
286
+static struct attribute *dsa_slave_attrs[] = {
287
+ &dev_attr_tagging.attr,
288
+ NULL
289
+};
290
+
291
+static const struct attribute_group dsa_group = {
292
+ .name = "dsa",
293
+ .attrs = dsa_slave_attrs,
294
+};
295
+
296
+static void dsa_master_reset_mtu(struct net_device *dev)
297
+{
298
+ int err;
299
+
300
+ rtnl_lock();
301
+ err = dev_set_mtu(dev, ETH_DATA_LEN);
302
+ if (err)
303
+ netdev_dbg(dev,
304
+ "Unable to reset MTU to exclude DSA overheads\n");
305
+ rtnl_unlock();
306
+}
307
+
162308 static struct lock_class_key dsa_master_addr_list_lock_key;
163309
164310 int dsa_master_setup(struct net_device *dev, struct dsa_port *cpu_dp)
165311 {
312
+ struct dsa_switch *ds = cpu_dp->ds;
313
+ struct device_link *consumer_link;
314
+ int ret;
315
+
316
+ /* The DSA master must use SET_NETDEV_DEV for this to work. */
317
+ consumer_link = device_link_add(ds->dev, dev->dev.parent,
318
+ DL_FLAG_AUTOREMOVE_CONSUMER);
319
+ if (!consumer_link)
320
+ netdev_err(dev,
321
+ "Failed to create a device link to DSA switch %s\n",
322
+ dev_name(ds->dev));
323
+
324
+ rtnl_lock();
325
+ ret = dev_set_mtu(dev, ETH_DATA_LEN + cpu_dp->tag_ops->overhead);
326
+ rtnl_unlock();
327
+ if (ret)
328
+ netdev_warn(dev, "error %d setting MTU to include DSA overhead\n",
329
+ ret);
330
+
166331 /* If we use a tagging format that doesn't have an ethertype
167332 * field, make sure that all packets from this point on get
168333 * sent to the tag format's receive function.
....@@ -173,12 +338,35 @@
173338 lockdep_set_class(&dev->addr_list_lock,
174339 &dsa_master_addr_list_lock_key);
175340
176
- return dsa_master_ethtool_setup(dev);
341
+ dsa_master_set_promiscuity(dev, 1);
342
+
343
+ ret = dsa_master_ethtool_setup(dev);
344
+ if (ret)
345
+ goto out_err_reset_promisc;
346
+
347
+ dsa_netdev_ops_set(dev, &dsa_netdev_ops);
348
+
349
+ ret = sysfs_create_group(&dev->dev.kobj, &dsa_group);
350
+ if (ret)
351
+ goto out_err_ndo_teardown;
352
+
353
+ return ret;
354
+
355
+out_err_ndo_teardown:
356
+ dsa_netdev_ops_set(dev, NULL);
357
+ dsa_master_ethtool_teardown(dev);
358
+out_err_reset_promisc:
359
+ dsa_master_set_promiscuity(dev, -1);
360
+ return ret;
177361 }
178362
179363 void dsa_master_teardown(struct net_device *dev)
180364 {
365
+ sysfs_remove_group(&dev->dev.kobj, &dsa_group);
366
+ dsa_netdev_ops_set(dev, NULL);
181367 dsa_master_ethtool_teardown(dev);
368
+ dsa_master_reset_mtu(dev);
369
+ dsa_master_set_promiscuity(dev, -1);
182370
183371 dev->dsa_ptr = NULL;
184372