1 | // SPDX-License-Identifier: GPL-2.0-or-later |
2 | /* |
3 | * net/dsa/user.c - user device handling |
4 | * Copyright (c) 2008-2009 Marvell Semiconductor |
5 | */ |
6 | |
7 | #include <linux/list.h> |
8 | #include <linux/etherdevice.h> |
9 | #include <linux/netdevice.h> |
10 | #include <linux/phy.h> |
11 | #include <linux/phy_fixed.h> |
12 | #include <linux/phylink.h> |
13 | #include <linux/of_net.h> |
14 | #include <linux/of_mdio.h> |
15 | #include <linux/mdio.h> |
16 | #include <net/rtnetlink.h> |
17 | #include <net/pkt_cls.h> |
18 | #include <net/selftests.h> |
19 | #include <net/tc_act/tc_mirred.h> |
20 | #include <linux/if_bridge.h> |
21 | #include <linux/if_hsr.h> |
22 | #include <net/dcbnl.h> |
23 | #include <linux/netpoll.h> |
24 | #include <linux/string.h> |
25 | |
26 | #include "conduit.h" |
27 | #include "dsa.h" |
28 | #include "netlink.h" |
29 | #include "port.h" |
30 | #include "switch.h" |
31 | #include "tag.h" |
32 | #include "user.h" |
33 | |
34 | struct dsa_switchdev_event_work { |
35 | struct net_device *dev; |
36 | struct net_device *orig_dev; |
37 | struct work_struct work; |
38 | unsigned long event; |
39 | /* Specific for SWITCHDEV_FDB_ADD_TO_DEVICE and |
40 | * SWITCHDEV_FDB_DEL_TO_DEVICE |
41 | */ |
42 | unsigned char addr[ETH_ALEN]; |
43 | u16 vid; |
44 | bool host_addr; |
45 | }; |
46 | |
47 | enum dsa_standalone_event { |
48 | DSA_UC_ADD, |
49 | DSA_UC_DEL, |
50 | DSA_MC_ADD, |
51 | DSA_MC_DEL, |
52 | }; |
53 | |
54 | struct dsa_standalone_event_work { |
55 | struct work_struct work; |
56 | struct net_device *dev; |
57 | enum dsa_standalone_event event; |
58 | unsigned char addr[ETH_ALEN]; |
59 | u16 vid; |
60 | }; |
61 | |
62 | struct dsa_host_vlan_rx_filtering_ctx { |
63 | struct net_device *dev; |
64 | const unsigned char *addr; |
65 | enum dsa_standalone_event event; |
66 | }; |
67 | |
68 | static bool dsa_switch_supports_uc_filtering(struct dsa_switch *ds) |
69 | { |
70 | return ds->ops->port_fdb_add && ds->ops->port_fdb_del && |
71 | ds->fdb_isolation && !ds->vlan_filtering_is_global && |
72 | !ds->needs_standalone_vlan_filtering; |
73 | } |
74 | |
75 | static bool dsa_switch_supports_mc_filtering(struct dsa_switch *ds) |
76 | { |
77 | return ds->ops->port_mdb_add && ds->ops->port_mdb_del && |
78 | ds->fdb_isolation && !ds->vlan_filtering_is_global && |
79 | !ds->needs_standalone_vlan_filtering; |
80 | } |
81 | |
82 | static void dsa_user_standalone_event_work(struct work_struct *work) |
83 | { |
84 | struct dsa_standalone_event_work *standalone_work = |
85 | container_of(work, struct dsa_standalone_event_work, work); |
86 | const unsigned char *addr = standalone_work->addr; |
87 | struct net_device *dev = standalone_work->dev; |
88 | struct dsa_port *dp = dsa_user_to_port(dev); |
89 | struct switchdev_obj_port_mdb mdb; |
90 | struct dsa_switch *ds = dp->ds; |
91 | u16 vid = standalone_work->vid; |
92 | int err; |
93 | |
94 | switch (standalone_work->event) { |
95 | case DSA_UC_ADD: |
96 | err = dsa_port_standalone_host_fdb_add(dp, addr, vid); |
97 | if (err) { |
98 | dev_err(ds->dev, |
99 | "port %d failed to add %pM vid %d to fdb: %d\n" , |
100 | dp->index, addr, vid, err); |
101 | break; |
102 | } |
103 | break; |
104 | |
105 | case DSA_UC_DEL: |
106 | err = dsa_port_standalone_host_fdb_del(dp, addr, vid); |
107 | if (err) { |
108 | dev_err(ds->dev, |
109 | "port %d failed to delete %pM vid %d from fdb: %d\n" , |
110 | dp->index, addr, vid, err); |
111 | } |
112 | |
113 | break; |
114 | case DSA_MC_ADD: |
115 | ether_addr_copy(dst: mdb.addr, src: addr); |
116 | mdb.vid = vid; |
117 | |
118 | err = dsa_port_standalone_host_mdb_add(dp, mdb: &mdb); |
119 | if (err) { |
120 | dev_err(ds->dev, |
121 | "port %d failed to add %pM vid %d to mdb: %d\n" , |
122 | dp->index, addr, vid, err); |
123 | break; |
124 | } |
125 | break; |
126 | case DSA_MC_DEL: |
127 | ether_addr_copy(dst: mdb.addr, src: addr); |
128 | mdb.vid = vid; |
129 | |
130 | err = dsa_port_standalone_host_mdb_del(dp, mdb: &mdb); |
131 | if (err) { |
132 | dev_err(ds->dev, |
133 | "port %d failed to delete %pM vid %d from mdb: %d\n" , |
134 | dp->index, addr, vid, err); |
135 | } |
136 | |
137 | break; |
138 | } |
139 | |
140 | kfree(objp: standalone_work); |
141 | } |
142 | |
143 | static int dsa_user_schedule_standalone_work(struct net_device *dev, |
144 | enum dsa_standalone_event event, |
145 | const unsigned char *addr, |
146 | u16 vid) |
147 | { |
148 | struct dsa_standalone_event_work *standalone_work; |
149 | |
150 | standalone_work = kzalloc(size: sizeof(*standalone_work), GFP_ATOMIC); |
151 | if (!standalone_work) |
152 | return -ENOMEM; |
153 | |
154 | INIT_WORK(&standalone_work->work, dsa_user_standalone_event_work); |
155 | standalone_work->event = event; |
156 | standalone_work->dev = dev; |
157 | |
158 | ether_addr_copy(dst: standalone_work->addr, src: addr); |
159 | standalone_work->vid = vid; |
160 | |
161 | dsa_schedule_work(work: &standalone_work->work); |
162 | |
163 | return 0; |
164 | } |
165 | |
166 | static int dsa_user_host_vlan_rx_filtering(void *arg, int vid) |
167 | { |
168 | struct dsa_host_vlan_rx_filtering_ctx *ctx = arg; |
169 | |
170 | return dsa_user_schedule_standalone_work(dev: ctx->dev, event: ctx->event, |
171 | addr: ctx->addr, vid); |
172 | } |
173 | |
174 | static int dsa_user_vlan_for_each(struct net_device *dev, |
175 | int (*cb)(void *arg, int vid), void *arg) |
176 | { |
177 | struct dsa_port *dp = dsa_user_to_port(dev); |
178 | struct dsa_vlan *v; |
179 | int err; |
180 | |
181 | lockdep_assert_held(&dev->addr_list_lock); |
182 | |
183 | err = cb(arg, 0); |
184 | if (err) |
185 | return err; |
186 | |
187 | list_for_each_entry(v, &dp->user_vlans, list) { |
188 | err = cb(arg, v->vid); |
189 | if (err) |
190 | return err; |
191 | } |
192 | |
193 | return 0; |
194 | } |
195 | |
196 | static int dsa_user_sync_uc(struct net_device *dev, |
197 | const unsigned char *addr) |
198 | { |
199 | struct net_device *conduit = dsa_user_to_conduit(dev); |
200 | struct dsa_port *dp = dsa_user_to_port(dev); |
201 | struct dsa_host_vlan_rx_filtering_ctx ctx = { |
202 | .dev = dev, |
203 | .addr = addr, |
204 | .event = DSA_UC_ADD, |
205 | }; |
206 | |
207 | dev_uc_add(dev: conduit, addr); |
208 | |
209 | if (!dsa_switch_supports_uc_filtering(ds: dp->ds)) |
210 | return 0; |
211 | |
212 | return dsa_user_vlan_for_each(dev, cb: dsa_user_host_vlan_rx_filtering, |
213 | arg: &ctx); |
214 | } |
215 | |
216 | static int dsa_user_unsync_uc(struct net_device *dev, |
217 | const unsigned char *addr) |
218 | { |
219 | struct net_device *conduit = dsa_user_to_conduit(dev); |
220 | struct dsa_port *dp = dsa_user_to_port(dev); |
221 | struct dsa_host_vlan_rx_filtering_ctx ctx = { |
222 | .dev = dev, |
223 | .addr = addr, |
224 | .event = DSA_UC_DEL, |
225 | }; |
226 | |
227 | dev_uc_del(dev: conduit, addr); |
228 | |
229 | if (!dsa_switch_supports_uc_filtering(ds: dp->ds)) |
230 | return 0; |
231 | |
232 | return dsa_user_vlan_for_each(dev, cb: dsa_user_host_vlan_rx_filtering, |
233 | arg: &ctx); |
234 | } |
235 | |
236 | static int dsa_user_sync_mc(struct net_device *dev, |
237 | const unsigned char *addr) |
238 | { |
239 | struct net_device *conduit = dsa_user_to_conduit(dev); |
240 | struct dsa_port *dp = dsa_user_to_port(dev); |
241 | struct dsa_host_vlan_rx_filtering_ctx ctx = { |
242 | .dev = dev, |
243 | .addr = addr, |
244 | .event = DSA_MC_ADD, |
245 | }; |
246 | |
247 | dev_mc_add(dev: conduit, addr); |
248 | |
249 | if (!dsa_switch_supports_mc_filtering(ds: dp->ds)) |
250 | return 0; |
251 | |
252 | return dsa_user_vlan_for_each(dev, cb: dsa_user_host_vlan_rx_filtering, |
253 | arg: &ctx); |
254 | } |
255 | |
256 | static int dsa_user_unsync_mc(struct net_device *dev, |
257 | const unsigned char *addr) |
258 | { |
259 | struct net_device *conduit = dsa_user_to_conduit(dev); |
260 | struct dsa_port *dp = dsa_user_to_port(dev); |
261 | struct dsa_host_vlan_rx_filtering_ctx ctx = { |
262 | .dev = dev, |
263 | .addr = addr, |
264 | .event = DSA_MC_DEL, |
265 | }; |
266 | |
267 | dev_mc_del(dev: conduit, addr); |
268 | |
269 | if (!dsa_switch_supports_mc_filtering(ds: dp->ds)) |
270 | return 0; |
271 | |
272 | return dsa_user_vlan_for_each(dev, cb: dsa_user_host_vlan_rx_filtering, |
273 | arg: &ctx); |
274 | } |
275 | |
276 | void dsa_user_sync_ha(struct net_device *dev) |
277 | { |
278 | struct dsa_port *dp = dsa_user_to_port(dev); |
279 | struct dsa_switch *ds = dp->ds; |
280 | struct netdev_hw_addr *ha; |
281 | |
282 | netif_addr_lock_bh(dev); |
283 | |
284 | netdev_for_each_synced_mc_addr(ha, dev) |
285 | dsa_user_sync_mc(dev, addr: ha->addr); |
286 | |
287 | netdev_for_each_synced_uc_addr(ha, dev) |
288 | dsa_user_sync_uc(dev, addr: ha->addr); |
289 | |
290 | netif_addr_unlock_bh(dev); |
291 | |
292 | if (dsa_switch_supports_uc_filtering(ds) || |
293 | dsa_switch_supports_mc_filtering(ds)) |
294 | dsa_flush_workqueue(); |
295 | } |
296 | |
297 | void dsa_user_unsync_ha(struct net_device *dev) |
298 | { |
299 | struct dsa_port *dp = dsa_user_to_port(dev); |
300 | struct dsa_switch *ds = dp->ds; |
301 | struct netdev_hw_addr *ha; |
302 | |
303 | netif_addr_lock_bh(dev); |
304 | |
305 | netdev_for_each_synced_uc_addr(ha, dev) |
306 | dsa_user_unsync_uc(dev, addr: ha->addr); |
307 | |
308 | netdev_for_each_synced_mc_addr(ha, dev) |
309 | dsa_user_unsync_mc(dev, addr: ha->addr); |
310 | |
311 | netif_addr_unlock_bh(dev); |
312 | |
313 | if (dsa_switch_supports_uc_filtering(ds) || |
314 | dsa_switch_supports_mc_filtering(ds)) |
315 | dsa_flush_workqueue(); |
316 | } |
317 | |
318 | /* user mii_bus handling ***************************************************/ |
319 | static int dsa_user_phy_read(struct mii_bus *bus, int addr, int reg) |
320 | { |
321 | struct dsa_switch *ds = bus->priv; |
322 | |
323 | if (ds->phys_mii_mask & (1 << addr)) |
324 | return ds->ops->phy_read(ds, addr, reg); |
325 | |
326 | return 0xffff; |
327 | } |
328 | |
329 | static int dsa_user_phy_write(struct mii_bus *bus, int addr, int reg, u16 val) |
330 | { |
331 | struct dsa_switch *ds = bus->priv; |
332 | |
333 | if (ds->phys_mii_mask & (1 << addr)) |
334 | return ds->ops->phy_write(ds, addr, reg, val); |
335 | |
336 | return 0; |
337 | } |
338 | |
339 | void dsa_user_mii_bus_init(struct dsa_switch *ds) |
340 | { |
341 | ds->user_mii_bus->priv = (void *)ds; |
342 | ds->user_mii_bus->name = "dsa user smi" ; |
343 | ds->user_mii_bus->read = dsa_user_phy_read; |
344 | ds->user_mii_bus->write = dsa_user_phy_write; |
345 | snprintf(buf: ds->user_mii_bus->id, MII_BUS_ID_SIZE, fmt: "dsa-%d.%d" , |
346 | ds->dst->index, ds->index); |
347 | ds->user_mii_bus->parent = ds->dev; |
348 | ds->user_mii_bus->phy_mask = ~ds->phys_mii_mask; |
349 | } |
350 | |
351 | |
352 | /* user device handling ****************************************************/ |
353 | static int dsa_user_get_iflink(const struct net_device *dev) |
354 | { |
355 | return READ_ONCE(dsa_user_to_conduit(dev)->ifindex); |
356 | } |
357 | |
358 | static int dsa_user_open(struct net_device *dev) |
359 | { |
360 | struct net_device *conduit = dsa_user_to_conduit(dev); |
361 | struct dsa_port *dp = dsa_user_to_port(dev); |
362 | struct dsa_switch *ds = dp->ds; |
363 | int err; |
364 | |
365 | err = dev_open(dev: conduit, NULL); |
366 | if (err < 0) { |
367 | netdev_err(dev, format: "failed to open conduit %s\n" , conduit->name); |
368 | goto out; |
369 | } |
370 | |
371 | if (dsa_switch_supports_uc_filtering(ds)) { |
372 | err = dsa_port_standalone_host_fdb_add(dp, addr: dev->dev_addr, vid: 0); |
373 | if (err) |
374 | goto out; |
375 | } |
376 | |
377 | if (!ether_addr_equal(addr1: dev->dev_addr, addr2: conduit->dev_addr)) { |
378 | err = dev_uc_add(dev: conduit, addr: dev->dev_addr); |
379 | if (err < 0) |
380 | goto del_host_addr; |
381 | } |
382 | |
383 | err = dsa_port_enable_rt(dp, phy: dev->phydev); |
384 | if (err) |
385 | goto del_unicast; |
386 | |
387 | return 0; |
388 | |
389 | del_unicast: |
390 | if (!ether_addr_equal(addr1: dev->dev_addr, addr2: conduit->dev_addr)) |
391 | dev_uc_del(dev: conduit, addr: dev->dev_addr); |
392 | del_host_addr: |
393 | if (dsa_switch_supports_uc_filtering(ds)) |
394 | dsa_port_standalone_host_fdb_del(dp, addr: dev->dev_addr, vid: 0); |
395 | out: |
396 | return err; |
397 | } |
398 | |
399 | static int dsa_user_close(struct net_device *dev) |
400 | { |
401 | struct net_device *conduit = dsa_user_to_conduit(dev); |
402 | struct dsa_port *dp = dsa_user_to_port(dev); |
403 | struct dsa_switch *ds = dp->ds; |
404 | |
405 | dsa_port_disable_rt(dp); |
406 | |
407 | if (!ether_addr_equal(addr1: dev->dev_addr, addr2: conduit->dev_addr)) |
408 | dev_uc_del(dev: conduit, addr: dev->dev_addr); |
409 | |
410 | if (dsa_switch_supports_uc_filtering(ds)) |
411 | dsa_port_standalone_host_fdb_del(dp, addr: dev->dev_addr, vid: 0); |
412 | |
413 | return 0; |
414 | } |
415 | |
416 | static void dsa_user_manage_host_flood(struct net_device *dev) |
417 | { |
418 | bool mc = dev->flags & (IFF_PROMISC | IFF_ALLMULTI); |
419 | struct dsa_port *dp = dsa_user_to_port(dev); |
420 | bool uc = dev->flags & IFF_PROMISC; |
421 | |
422 | dsa_port_set_host_flood(dp, uc, mc); |
423 | } |
424 | |
425 | static void dsa_user_change_rx_flags(struct net_device *dev, int change) |
426 | { |
427 | struct net_device *conduit = dsa_user_to_conduit(dev); |
428 | struct dsa_port *dp = dsa_user_to_port(dev); |
429 | struct dsa_switch *ds = dp->ds; |
430 | |
431 | if (change & IFF_ALLMULTI) |
432 | dev_set_allmulti(dev: conduit, |
433 | inc: dev->flags & IFF_ALLMULTI ? 1 : -1); |
434 | if (change & IFF_PROMISC) |
435 | dev_set_promiscuity(dev: conduit, |
436 | inc: dev->flags & IFF_PROMISC ? 1 : -1); |
437 | |
438 | if (dsa_switch_supports_uc_filtering(ds) && |
439 | dsa_switch_supports_mc_filtering(ds)) |
440 | dsa_user_manage_host_flood(dev); |
441 | } |
442 | |
443 | static void dsa_user_set_rx_mode(struct net_device *dev) |
444 | { |
445 | __dev_mc_sync(dev, sync: dsa_user_sync_mc, unsync: dsa_user_unsync_mc); |
446 | __dev_uc_sync(dev, sync: dsa_user_sync_uc, unsync: dsa_user_unsync_uc); |
447 | } |
448 | |
449 | static int dsa_user_set_mac_address(struct net_device *dev, void *a) |
450 | { |
451 | struct net_device *conduit = dsa_user_to_conduit(dev); |
452 | struct dsa_port *dp = dsa_user_to_port(dev); |
453 | struct dsa_switch *ds = dp->ds; |
454 | struct sockaddr *addr = a; |
455 | int err; |
456 | |
457 | if (!is_valid_ether_addr(addr: addr->sa_data)) |
458 | return -EADDRNOTAVAIL; |
459 | |
460 | if (ds->ops->port_set_mac_address) { |
461 | err = ds->ops->port_set_mac_address(ds, dp->index, |
462 | addr->sa_data); |
463 | if (err) |
464 | return err; |
465 | } |
466 | |
467 | /* If the port is down, the address isn't synced yet to hardware or |
468 | * to the DSA conduit, so there is nothing to change. |
469 | */ |
470 | if (!(dev->flags & IFF_UP)) |
471 | goto out_change_dev_addr; |
472 | |
473 | if (dsa_switch_supports_uc_filtering(ds)) { |
474 | err = dsa_port_standalone_host_fdb_add(dp, addr: addr->sa_data, vid: 0); |
475 | if (err) |
476 | return err; |
477 | } |
478 | |
479 | if (!ether_addr_equal(addr1: addr->sa_data, addr2: conduit->dev_addr)) { |
480 | err = dev_uc_add(dev: conduit, addr: addr->sa_data); |
481 | if (err < 0) |
482 | goto del_unicast; |
483 | } |
484 | |
485 | if (!ether_addr_equal(addr1: dev->dev_addr, addr2: conduit->dev_addr)) |
486 | dev_uc_del(dev: conduit, addr: dev->dev_addr); |
487 | |
488 | if (dsa_switch_supports_uc_filtering(ds)) |
489 | dsa_port_standalone_host_fdb_del(dp, addr: dev->dev_addr, vid: 0); |
490 | |
491 | out_change_dev_addr: |
492 | eth_hw_addr_set(dev, addr: addr->sa_data); |
493 | |
494 | return 0; |
495 | |
496 | del_unicast: |
497 | if (dsa_switch_supports_uc_filtering(ds)) |
498 | dsa_port_standalone_host_fdb_del(dp, addr: addr->sa_data, vid: 0); |
499 | |
500 | return err; |
501 | } |
502 | |
503 | struct dsa_user_dump_ctx { |
504 | struct net_device *dev; |
505 | struct sk_buff *skb; |
506 | struct netlink_callback *cb; |
507 | int idx; |
508 | }; |
509 | |
510 | static int |
511 | dsa_user_port_fdb_do_dump(const unsigned char *addr, u16 vid, |
512 | bool is_static, void *data) |
513 | { |
514 | struct dsa_user_dump_ctx *dump = data; |
515 | u32 portid = NETLINK_CB(dump->cb->skb).portid; |
516 | u32 seq = dump->cb->nlh->nlmsg_seq; |
517 | struct nlmsghdr *nlh; |
518 | struct ndmsg *ndm; |
519 | |
520 | if (dump->idx < dump->cb->args[2]) |
521 | goto skip; |
522 | |
523 | nlh = nlmsg_put(skb: dump->skb, portid, seq, RTM_NEWNEIGH, |
524 | payload: sizeof(*ndm), NLM_F_MULTI); |
525 | if (!nlh) |
526 | return -EMSGSIZE; |
527 | |
528 | ndm = nlmsg_data(nlh); |
529 | ndm->ndm_family = AF_BRIDGE; |
530 | ndm->ndm_pad1 = 0; |
531 | ndm->ndm_pad2 = 0; |
532 | ndm->ndm_flags = NTF_SELF; |
533 | ndm->ndm_type = 0; |
534 | ndm->ndm_ifindex = dump->dev->ifindex; |
535 | ndm->ndm_state = is_static ? NUD_NOARP : NUD_REACHABLE; |
536 | |
537 | if (nla_put(skb: dump->skb, attrtype: NDA_LLADDR, ETH_ALEN, data: addr)) |
538 | goto nla_put_failure; |
539 | |
540 | if (vid && nla_put_u16(skb: dump->skb, attrtype: NDA_VLAN, value: vid)) |
541 | goto nla_put_failure; |
542 | |
543 | nlmsg_end(skb: dump->skb, nlh); |
544 | |
545 | skip: |
546 | dump->idx++; |
547 | return 0; |
548 | |
549 | nla_put_failure: |
550 | nlmsg_cancel(skb: dump->skb, nlh); |
551 | return -EMSGSIZE; |
552 | } |
553 | |
554 | static int |
555 | dsa_user_fdb_dump(struct sk_buff *skb, struct netlink_callback *cb, |
556 | struct net_device *dev, struct net_device *filter_dev, |
557 | int *idx) |
558 | { |
559 | struct dsa_port *dp = dsa_user_to_port(dev); |
560 | struct dsa_user_dump_ctx dump = { |
561 | .dev = dev, |
562 | .skb = skb, |
563 | .cb = cb, |
564 | .idx = *idx, |
565 | }; |
566 | int err; |
567 | |
568 | err = dsa_port_fdb_dump(dp, cb: dsa_user_port_fdb_do_dump, data: &dump); |
569 | *idx = dump.idx; |
570 | |
571 | return err; |
572 | } |
573 | |
574 | static int dsa_user_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd) |
575 | { |
576 | struct dsa_user_priv *p = netdev_priv(dev); |
577 | struct dsa_switch *ds = p->dp->ds; |
578 | int port = p->dp->index; |
579 | |
580 | /* Pass through to switch driver if it supports timestamping */ |
581 | switch (cmd) { |
582 | case SIOCGHWTSTAMP: |
583 | if (ds->ops->port_hwtstamp_get) |
584 | return ds->ops->port_hwtstamp_get(ds, port, ifr); |
585 | break; |
586 | case SIOCSHWTSTAMP: |
587 | if (ds->ops->port_hwtstamp_set) |
588 | return ds->ops->port_hwtstamp_set(ds, port, ifr); |
589 | break; |
590 | } |
591 | |
592 | return phylink_mii_ioctl(p->dp->pl, ifr, cmd); |
593 | } |
594 | |
595 | static int dsa_user_port_attr_set(struct net_device *dev, const void *ctx, |
596 | const struct switchdev_attr *attr, |
597 | struct netlink_ext_ack *extack) |
598 | { |
599 | struct dsa_port *dp = dsa_user_to_port(dev); |
600 | int ret; |
601 | |
602 | if (ctx && ctx != dp) |
603 | return 0; |
604 | |
605 | switch (attr->id) { |
606 | case SWITCHDEV_ATTR_ID_PORT_STP_STATE: |
607 | if (!dsa_port_offloads_bridge_port(dp, dev: attr->orig_dev)) |
608 | return -EOPNOTSUPP; |
609 | |
610 | ret = dsa_port_set_state(dp, state: attr->u.stp_state, do_fast_age: true); |
611 | break; |
612 | case SWITCHDEV_ATTR_ID_PORT_MST_STATE: |
613 | if (!dsa_port_offloads_bridge_port(dp, dev: attr->orig_dev)) |
614 | return -EOPNOTSUPP; |
615 | |
616 | ret = dsa_port_set_mst_state(dp, state: &attr->u.mst_state, extack); |
617 | break; |
618 | case SWITCHDEV_ATTR_ID_BRIDGE_VLAN_FILTERING: |
619 | if (!dsa_port_offloads_bridge_dev(dp, bridge_dev: attr->orig_dev)) |
620 | return -EOPNOTSUPP; |
621 | |
622 | ret = dsa_port_vlan_filtering(dp, vlan_filtering: attr->u.vlan_filtering, |
623 | extack); |
624 | break; |
625 | case SWITCHDEV_ATTR_ID_BRIDGE_AGEING_TIME: |
626 | if (!dsa_port_offloads_bridge_dev(dp, bridge_dev: attr->orig_dev)) |
627 | return -EOPNOTSUPP; |
628 | |
629 | ret = dsa_port_ageing_time(dp, ageing_clock: attr->u.ageing_time); |
630 | break; |
631 | case SWITCHDEV_ATTR_ID_BRIDGE_MST: |
632 | if (!dsa_port_offloads_bridge_dev(dp, bridge_dev: attr->orig_dev)) |
633 | return -EOPNOTSUPP; |
634 | |
635 | ret = dsa_port_mst_enable(dp, on: attr->u.mst, extack); |
636 | break; |
637 | case SWITCHDEV_ATTR_ID_PORT_PRE_BRIDGE_FLAGS: |
638 | if (!dsa_port_offloads_bridge_port(dp, dev: attr->orig_dev)) |
639 | return -EOPNOTSUPP; |
640 | |
641 | ret = dsa_port_pre_bridge_flags(dp, flags: attr->u.brport_flags, |
642 | extack); |
643 | break; |
644 | case SWITCHDEV_ATTR_ID_PORT_BRIDGE_FLAGS: |
645 | if (!dsa_port_offloads_bridge_port(dp, dev: attr->orig_dev)) |
646 | return -EOPNOTSUPP; |
647 | |
648 | ret = dsa_port_bridge_flags(dp, flags: attr->u.brport_flags, extack); |
649 | break; |
650 | case SWITCHDEV_ATTR_ID_VLAN_MSTI: |
651 | if (!dsa_port_offloads_bridge_dev(dp, bridge_dev: attr->orig_dev)) |
652 | return -EOPNOTSUPP; |
653 | |
654 | ret = dsa_port_vlan_msti(dp, msti: &attr->u.vlan_msti); |
655 | break; |
656 | default: |
657 | ret = -EOPNOTSUPP; |
658 | break; |
659 | } |
660 | |
661 | return ret; |
662 | } |
663 | |
664 | /* Must be called under rcu_read_lock() */ |
665 | static int |
666 | dsa_user_vlan_check_for_8021q_uppers(struct net_device *user, |
667 | const struct switchdev_obj_port_vlan *vlan) |
668 | { |
669 | struct net_device *upper_dev; |
670 | struct list_head *iter; |
671 | |
672 | netdev_for_each_upper_dev_rcu(user, upper_dev, iter) { |
673 | u16 vid; |
674 | |
675 | if (!is_vlan_dev(dev: upper_dev)) |
676 | continue; |
677 | |
678 | vid = vlan_dev_vlan_id(dev: upper_dev); |
679 | if (vid == vlan->vid) |
680 | return -EBUSY; |
681 | } |
682 | |
683 | return 0; |
684 | } |
685 | |
686 | static int dsa_user_vlan_add(struct net_device *dev, |
687 | const struct switchdev_obj *obj, |
688 | struct netlink_ext_ack *extack) |
689 | { |
690 | struct dsa_port *dp = dsa_user_to_port(dev); |
691 | struct switchdev_obj_port_vlan *vlan; |
692 | int err; |
693 | |
694 | if (dsa_port_skip_vlan_configuration(dp)) { |
695 | NL_SET_ERR_MSG_MOD(extack, "skipping configuration of VLAN" ); |
696 | return 0; |
697 | } |
698 | |
699 | vlan = SWITCHDEV_OBJ_PORT_VLAN(obj); |
700 | |
701 | /* Deny adding a bridge VLAN when there is already an 802.1Q upper with |
702 | * the same VID. |
703 | */ |
704 | if (br_vlan_enabled(dev: dsa_port_bridge_dev_get(dp))) { |
705 | rcu_read_lock(); |
706 | err = dsa_user_vlan_check_for_8021q_uppers(user: dev, vlan); |
707 | rcu_read_unlock(); |
708 | if (err) { |
709 | NL_SET_ERR_MSG_MOD(extack, |
710 | "Port already has a VLAN upper with this VID" ); |
711 | return err; |
712 | } |
713 | } |
714 | |
715 | return dsa_port_vlan_add(dp, vlan, extack); |
716 | } |
717 | |
718 | /* Offload a VLAN installed on the bridge or on a foreign interface by |
719 | * installing it as a VLAN towards the CPU port. |
720 | */ |
721 | static int dsa_user_host_vlan_add(struct net_device *dev, |
722 | const struct switchdev_obj *obj, |
723 | struct netlink_ext_ack *extack) |
724 | { |
725 | struct dsa_port *dp = dsa_user_to_port(dev); |
726 | struct switchdev_obj_port_vlan vlan; |
727 | |
728 | /* Do nothing if this is a software bridge */ |
729 | if (!dp->bridge) |
730 | return -EOPNOTSUPP; |
731 | |
732 | if (dsa_port_skip_vlan_configuration(dp)) { |
733 | NL_SET_ERR_MSG_MOD(extack, "skipping configuration of VLAN" ); |
734 | return 0; |
735 | } |
736 | |
737 | vlan = *SWITCHDEV_OBJ_PORT_VLAN(obj); |
738 | |
739 | /* Even though drivers often handle CPU membership in special ways, |
740 | * it doesn't make sense to program a PVID, so clear this flag. |
741 | */ |
742 | vlan.flags &= ~BRIDGE_VLAN_INFO_PVID; |
743 | |
744 | return dsa_port_host_vlan_add(dp, vlan: &vlan, extack); |
745 | } |
746 | |
747 | static int dsa_user_port_obj_add(struct net_device *dev, const void *ctx, |
748 | const struct switchdev_obj *obj, |
749 | struct netlink_ext_ack *extack) |
750 | { |
751 | struct dsa_port *dp = dsa_user_to_port(dev); |
752 | int err; |
753 | |
754 | if (ctx && ctx != dp) |
755 | return 0; |
756 | |
757 | switch (obj->id) { |
758 | case SWITCHDEV_OBJ_ID_PORT_MDB: |
759 | if (!dsa_port_offloads_bridge_port(dp, dev: obj->orig_dev)) |
760 | return -EOPNOTSUPP; |
761 | |
762 | err = dsa_port_mdb_add(dp, SWITCHDEV_OBJ_PORT_MDB(obj)); |
763 | break; |
764 | case SWITCHDEV_OBJ_ID_HOST_MDB: |
765 | if (!dsa_port_offloads_bridge_dev(dp, bridge_dev: obj->orig_dev)) |
766 | return -EOPNOTSUPP; |
767 | |
768 | err = dsa_port_bridge_host_mdb_add(dp, SWITCHDEV_OBJ_PORT_MDB(obj)); |
769 | break; |
770 | case SWITCHDEV_OBJ_ID_PORT_VLAN: |
771 | if (dsa_port_offloads_bridge_port(dp, dev: obj->orig_dev)) |
772 | err = dsa_user_vlan_add(dev, obj, extack); |
773 | else |
774 | err = dsa_user_host_vlan_add(dev, obj, extack); |
775 | break; |
776 | case SWITCHDEV_OBJ_ID_MRP: |
777 | if (!dsa_port_offloads_bridge_dev(dp, bridge_dev: obj->orig_dev)) |
778 | return -EOPNOTSUPP; |
779 | |
780 | err = dsa_port_mrp_add(dp, SWITCHDEV_OBJ_MRP(obj)); |
781 | break; |
782 | case SWITCHDEV_OBJ_ID_RING_ROLE_MRP: |
783 | if (!dsa_port_offloads_bridge_dev(dp, bridge_dev: obj->orig_dev)) |
784 | return -EOPNOTSUPP; |
785 | |
786 | err = dsa_port_mrp_add_ring_role(dp, |
787 | SWITCHDEV_OBJ_RING_ROLE_MRP(obj)); |
788 | break; |
789 | default: |
790 | err = -EOPNOTSUPP; |
791 | break; |
792 | } |
793 | |
794 | return err; |
795 | } |
796 | |
797 | static int dsa_user_vlan_del(struct net_device *dev, |
798 | const struct switchdev_obj *obj) |
799 | { |
800 | struct dsa_port *dp = dsa_user_to_port(dev); |
801 | struct switchdev_obj_port_vlan *vlan; |
802 | |
803 | if (dsa_port_skip_vlan_configuration(dp)) |
804 | return 0; |
805 | |
806 | vlan = SWITCHDEV_OBJ_PORT_VLAN(obj); |
807 | |
808 | return dsa_port_vlan_del(dp, vlan); |
809 | } |
810 | |
811 | static int dsa_user_host_vlan_del(struct net_device *dev, |
812 | const struct switchdev_obj *obj) |
813 | { |
814 | struct dsa_port *dp = dsa_user_to_port(dev); |
815 | struct switchdev_obj_port_vlan *vlan; |
816 | |
817 | /* Do nothing if this is a software bridge */ |
818 | if (!dp->bridge) |
819 | return -EOPNOTSUPP; |
820 | |
821 | if (dsa_port_skip_vlan_configuration(dp)) |
822 | return 0; |
823 | |
824 | vlan = SWITCHDEV_OBJ_PORT_VLAN(obj); |
825 | |
826 | return dsa_port_host_vlan_del(dp, vlan); |
827 | } |
828 | |
829 | static int dsa_user_port_obj_del(struct net_device *dev, const void *ctx, |
830 | const struct switchdev_obj *obj) |
831 | { |
832 | struct dsa_port *dp = dsa_user_to_port(dev); |
833 | int err; |
834 | |
835 | if (ctx && ctx != dp) |
836 | return 0; |
837 | |
838 | switch (obj->id) { |
839 | case SWITCHDEV_OBJ_ID_PORT_MDB: |
840 | if (!dsa_port_offloads_bridge_port(dp, dev: obj->orig_dev)) |
841 | return -EOPNOTSUPP; |
842 | |
843 | err = dsa_port_mdb_del(dp, SWITCHDEV_OBJ_PORT_MDB(obj)); |
844 | break; |
845 | case SWITCHDEV_OBJ_ID_HOST_MDB: |
846 | if (!dsa_port_offloads_bridge_dev(dp, bridge_dev: obj->orig_dev)) |
847 | return -EOPNOTSUPP; |
848 | |
849 | err = dsa_port_bridge_host_mdb_del(dp, SWITCHDEV_OBJ_PORT_MDB(obj)); |
850 | break; |
851 | case SWITCHDEV_OBJ_ID_PORT_VLAN: |
852 | if (dsa_port_offloads_bridge_port(dp, dev: obj->orig_dev)) |
853 | err = dsa_user_vlan_del(dev, obj); |
854 | else |
855 | err = dsa_user_host_vlan_del(dev, obj); |
856 | break; |
857 | case SWITCHDEV_OBJ_ID_MRP: |
858 | if (!dsa_port_offloads_bridge_dev(dp, bridge_dev: obj->orig_dev)) |
859 | return -EOPNOTSUPP; |
860 | |
861 | err = dsa_port_mrp_del(dp, SWITCHDEV_OBJ_MRP(obj)); |
862 | break; |
863 | case SWITCHDEV_OBJ_ID_RING_ROLE_MRP: |
864 | if (!dsa_port_offloads_bridge_dev(dp, bridge_dev: obj->orig_dev)) |
865 | return -EOPNOTSUPP; |
866 | |
867 | err = dsa_port_mrp_del_ring_role(dp, |
868 | SWITCHDEV_OBJ_RING_ROLE_MRP(obj)); |
869 | break; |
870 | default: |
871 | err = -EOPNOTSUPP; |
872 | break; |
873 | } |
874 | |
875 | return err; |
876 | } |
877 | |
878 | static netdev_tx_t dsa_user_netpoll_send_skb(struct net_device *dev, |
879 | struct sk_buff *skb) |
880 | { |
881 | #ifdef CONFIG_NET_POLL_CONTROLLER |
882 | struct dsa_user_priv *p = netdev_priv(dev); |
883 | |
884 | return netpoll_send_skb(np: p->netpoll, skb); |
885 | #else |
886 | BUG(); |
887 | return NETDEV_TX_OK; |
888 | #endif |
889 | } |
890 | |
891 | static void dsa_skb_tx_timestamp(struct dsa_user_priv *p, |
892 | struct sk_buff *skb) |
893 | { |
894 | struct dsa_switch *ds = p->dp->ds; |
895 | |
896 | if (!(skb_shinfo(skb)->tx_flags & SKBTX_HW_TSTAMP)) |
897 | return; |
898 | |
899 | if (!ds->ops->port_txtstamp) |
900 | return; |
901 | |
902 | ds->ops->port_txtstamp(ds, p->dp->index, skb); |
903 | } |
904 | |
905 | netdev_tx_t dsa_enqueue_skb(struct sk_buff *skb, struct net_device *dev) |
906 | { |
907 | /* SKB for netpoll still need to be mangled with the protocol-specific |
908 | * tag to be successfully transmitted |
909 | */ |
910 | if (unlikely(netpoll_tx_running(dev))) |
911 | return dsa_user_netpoll_send_skb(dev, skb); |
912 | |
913 | /* Queue the SKB for transmission on the parent interface, but |
914 | * do not modify its EtherType |
915 | */ |
916 | skb->dev = dsa_user_to_conduit(dev); |
917 | dev_queue_xmit(skb); |
918 | |
919 | return NETDEV_TX_OK; |
920 | } |
921 | EXPORT_SYMBOL_GPL(dsa_enqueue_skb); |
922 | |
923 | static netdev_tx_t dsa_user_xmit(struct sk_buff *skb, struct net_device *dev) |
924 | { |
925 | struct dsa_user_priv *p = netdev_priv(dev); |
926 | struct sk_buff *nskb; |
927 | |
928 | dev_sw_netstats_tx_add(dev, packets: 1, len: skb->len); |
929 | |
930 | memset(skb->cb, 0, sizeof(skb->cb)); |
931 | |
932 | /* Handle tx timestamp if any */ |
933 | dsa_skb_tx_timestamp(p, skb); |
934 | |
935 | if (skb_ensure_writable_head_tail(skb, dev)) { |
936 | dev_kfree_skb_any(skb); |
937 | return NETDEV_TX_OK; |
938 | } |
939 | |
940 | /* needed_tailroom should still be 'warm' in the cache line from |
941 | * skb_ensure_writable_head_tail(), which has also ensured that |
942 | * padding is safe. |
943 | */ |
944 | if (dev->needed_tailroom) |
945 | eth_skb_pad(skb); |
946 | |
947 | /* Transmit function may have to reallocate the original SKB, |
948 | * in which case it must have freed it. Only free it here on error. |
949 | */ |
950 | nskb = p->xmit(skb, dev); |
951 | if (!nskb) { |
952 | kfree_skb(skb); |
953 | return NETDEV_TX_OK; |
954 | } |
955 | |
956 | return dsa_enqueue_skb(nskb, dev); |
957 | } |
958 | |
959 | /* ethtool operations *******************************************************/ |
960 | |
961 | static void dsa_user_get_drvinfo(struct net_device *dev, |
962 | struct ethtool_drvinfo *drvinfo) |
963 | { |
964 | strscpy(drvinfo->driver, "dsa" , sizeof(drvinfo->driver)); |
965 | strscpy(drvinfo->fw_version, "N/A" , sizeof(drvinfo->fw_version)); |
966 | strscpy(drvinfo->bus_info, "platform" , sizeof(drvinfo->bus_info)); |
967 | } |
968 | |
969 | static int dsa_user_get_regs_len(struct net_device *dev) |
970 | { |
971 | struct dsa_port *dp = dsa_user_to_port(dev); |
972 | struct dsa_switch *ds = dp->ds; |
973 | |
974 | if (ds->ops->get_regs_len) |
975 | return ds->ops->get_regs_len(ds, dp->index); |
976 | |
977 | return -EOPNOTSUPP; |
978 | } |
979 | |
980 | static void |
981 | dsa_user_get_regs(struct net_device *dev, struct ethtool_regs *regs, void *_p) |
982 | { |
983 | struct dsa_port *dp = dsa_user_to_port(dev); |
984 | struct dsa_switch *ds = dp->ds; |
985 | |
986 | if (ds->ops->get_regs) |
987 | ds->ops->get_regs(ds, dp->index, regs, _p); |
988 | } |
989 | |
990 | static int dsa_user_nway_reset(struct net_device *dev) |
991 | { |
992 | struct dsa_port *dp = dsa_user_to_port(dev); |
993 | |
994 | return phylink_ethtool_nway_reset(dp->pl); |
995 | } |
996 | |
997 | static int dsa_user_get_eeprom_len(struct net_device *dev) |
998 | { |
999 | struct dsa_port *dp = dsa_user_to_port(dev); |
1000 | struct dsa_switch *ds = dp->ds; |
1001 | |
1002 | if (ds->cd && ds->cd->eeprom_len) |
1003 | return ds->cd->eeprom_len; |
1004 | |
1005 | if (ds->ops->get_eeprom_len) |
1006 | return ds->ops->get_eeprom_len(ds); |
1007 | |
1008 | return 0; |
1009 | } |
1010 | |
1011 | static int dsa_user_get_eeprom(struct net_device *dev, |
1012 | struct ethtool_eeprom *eeprom, u8 *data) |
1013 | { |
1014 | struct dsa_port *dp = dsa_user_to_port(dev); |
1015 | struct dsa_switch *ds = dp->ds; |
1016 | |
1017 | if (ds->ops->get_eeprom) |
1018 | return ds->ops->get_eeprom(ds, eeprom, data); |
1019 | |
1020 | return -EOPNOTSUPP; |
1021 | } |
1022 | |
1023 | static int dsa_user_set_eeprom(struct net_device *dev, |
1024 | struct ethtool_eeprom *eeprom, u8 *data) |
1025 | { |
1026 | struct dsa_port *dp = dsa_user_to_port(dev); |
1027 | struct dsa_switch *ds = dp->ds; |
1028 | |
1029 | if (ds->ops->set_eeprom) |
1030 | return ds->ops->set_eeprom(ds, eeprom, data); |
1031 | |
1032 | return -EOPNOTSUPP; |
1033 | } |
1034 | |
1035 | static void dsa_user_get_strings(struct net_device *dev, |
1036 | uint32_t stringset, uint8_t *data) |
1037 | { |
1038 | struct dsa_port *dp = dsa_user_to_port(dev); |
1039 | struct dsa_switch *ds = dp->ds; |
1040 | |
1041 | if (stringset == ETH_SS_STATS) { |
1042 | int len = ETH_GSTRING_LEN; |
1043 | |
1044 | strscpy_pad(data, "tx_packets" , len); |
1045 | strscpy_pad(data + len, "tx_bytes" , len); |
1046 | strscpy_pad(data + 2 * len, "rx_packets" , len); |
1047 | strscpy_pad(data + 3 * len, "rx_bytes" , len); |
1048 | if (ds->ops->get_strings) |
1049 | ds->ops->get_strings(ds, dp->index, stringset, |
1050 | data + 4 * len); |
1051 | } else if (stringset == ETH_SS_TEST) { |
1052 | net_selftest_get_strings(data); |
1053 | } |
1054 | |
1055 | } |
1056 | |
1057 | static void dsa_user_get_ethtool_stats(struct net_device *dev, |
1058 | struct ethtool_stats *stats, |
1059 | uint64_t *data) |
1060 | { |
1061 | struct dsa_port *dp = dsa_user_to_port(dev); |
1062 | struct dsa_switch *ds = dp->ds; |
1063 | struct pcpu_sw_netstats *s; |
1064 | unsigned int start; |
1065 | int i; |
1066 | |
1067 | for_each_possible_cpu(i) { |
1068 | u64 tx_packets, tx_bytes, rx_packets, rx_bytes; |
1069 | |
1070 | s = per_cpu_ptr(dev->tstats, i); |
1071 | do { |
1072 | start = u64_stats_fetch_begin(syncp: &s->syncp); |
1073 | tx_packets = u64_stats_read(p: &s->tx_packets); |
1074 | tx_bytes = u64_stats_read(p: &s->tx_bytes); |
1075 | rx_packets = u64_stats_read(p: &s->rx_packets); |
1076 | rx_bytes = u64_stats_read(p: &s->rx_bytes); |
1077 | } while (u64_stats_fetch_retry(syncp: &s->syncp, start)); |
1078 | data[0] += tx_packets; |
1079 | data[1] += tx_bytes; |
1080 | data[2] += rx_packets; |
1081 | data[3] += rx_bytes; |
1082 | } |
1083 | if (ds->ops->get_ethtool_stats) |
1084 | ds->ops->get_ethtool_stats(ds, dp->index, data + 4); |
1085 | } |
1086 | |
1087 | static int dsa_user_get_sset_count(struct net_device *dev, int sset) |
1088 | { |
1089 | struct dsa_port *dp = dsa_user_to_port(dev); |
1090 | struct dsa_switch *ds = dp->ds; |
1091 | |
1092 | if (sset == ETH_SS_STATS) { |
1093 | int count = 0; |
1094 | |
1095 | if (ds->ops->get_sset_count) { |
1096 | count = ds->ops->get_sset_count(ds, dp->index, sset); |
1097 | if (count < 0) |
1098 | return count; |
1099 | } |
1100 | |
1101 | return count + 4; |
1102 | } else if (sset == ETH_SS_TEST) { |
1103 | return net_selftest_get_count(); |
1104 | } |
1105 | |
1106 | return -EOPNOTSUPP; |
1107 | } |
1108 | |
1109 | static void dsa_user_get_eth_phy_stats(struct net_device *dev, |
1110 | struct ethtool_eth_phy_stats *phy_stats) |
1111 | { |
1112 | struct dsa_port *dp = dsa_user_to_port(dev); |
1113 | struct dsa_switch *ds = dp->ds; |
1114 | |
1115 | if (ds->ops->get_eth_phy_stats) |
1116 | ds->ops->get_eth_phy_stats(ds, dp->index, phy_stats); |
1117 | } |
1118 | |
1119 | static void dsa_user_get_eth_mac_stats(struct net_device *dev, |
1120 | struct ethtool_eth_mac_stats *mac_stats) |
1121 | { |
1122 | struct dsa_port *dp = dsa_user_to_port(dev); |
1123 | struct dsa_switch *ds = dp->ds; |
1124 | |
1125 | if (ds->ops->get_eth_mac_stats) |
1126 | ds->ops->get_eth_mac_stats(ds, dp->index, mac_stats); |
1127 | } |
1128 | |
1129 | static void |
1130 | dsa_user_get_eth_ctrl_stats(struct net_device *dev, |
1131 | struct ethtool_eth_ctrl_stats *ctrl_stats) |
1132 | { |
1133 | struct dsa_port *dp = dsa_user_to_port(dev); |
1134 | struct dsa_switch *ds = dp->ds; |
1135 | |
1136 | if (ds->ops->get_eth_ctrl_stats) |
1137 | ds->ops->get_eth_ctrl_stats(ds, dp->index, ctrl_stats); |
1138 | } |
1139 | |
1140 | static void |
1141 | dsa_user_get_rmon_stats(struct net_device *dev, |
1142 | struct ethtool_rmon_stats *rmon_stats, |
1143 | const struct ethtool_rmon_hist_range **ranges) |
1144 | { |
1145 | struct dsa_port *dp = dsa_user_to_port(dev); |
1146 | struct dsa_switch *ds = dp->ds; |
1147 | |
1148 | if (ds->ops->get_rmon_stats) |
1149 | ds->ops->get_rmon_stats(ds, dp->index, rmon_stats, ranges); |
1150 | } |
1151 | |
1152 | static void dsa_user_net_selftest(struct net_device *ndev, |
1153 | struct ethtool_test *etest, u64 *buf) |
1154 | { |
1155 | struct dsa_port *dp = dsa_user_to_port(dev: ndev); |
1156 | struct dsa_switch *ds = dp->ds; |
1157 | |
1158 | if (ds->ops->self_test) { |
1159 | ds->ops->self_test(ds, dp->index, etest, buf); |
1160 | return; |
1161 | } |
1162 | |
1163 | net_selftest(ndev, etest, buf); |
1164 | } |
1165 | |
1166 | static int dsa_user_get_mm(struct net_device *dev, |
1167 | struct ethtool_mm_state *state) |
1168 | { |
1169 | struct dsa_port *dp = dsa_user_to_port(dev); |
1170 | struct dsa_switch *ds = dp->ds; |
1171 | |
1172 | if (!ds->ops->get_mm) |
1173 | return -EOPNOTSUPP; |
1174 | |
1175 | return ds->ops->get_mm(ds, dp->index, state); |
1176 | } |
1177 | |
1178 | static int dsa_user_set_mm(struct net_device *dev, struct ethtool_mm_cfg *cfg, |
1179 | struct netlink_ext_ack *extack) |
1180 | { |
1181 | struct dsa_port *dp = dsa_user_to_port(dev); |
1182 | struct dsa_switch *ds = dp->ds; |
1183 | |
1184 | if (!ds->ops->set_mm) |
1185 | return -EOPNOTSUPP; |
1186 | |
1187 | return ds->ops->set_mm(ds, dp->index, cfg, extack); |
1188 | } |
1189 | |
1190 | static void dsa_user_get_mm_stats(struct net_device *dev, |
1191 | struct ethtool_mm_stats *stats) |
1192 | { |
1193 | struct dsa_port *dp = dsa_user_to_port(dev); |
1194 | struct dsa_switch *ds = dp->ds; |
1195 | |
1196 | if (ds->ops->get_mm_stats) |
1197 | ds->ops->get_mm_stats(ds, dp->index, stats); |
1198 | } |
1199 | |
1200 | static void dsa_user_get_wol(struct net_device *dev, struct ethtool_wolinfo *w) |
1201 | { |
1202 | struct dsa_port *dp = dsa_user_to_port(dev); |
1203 | struct dsa_switch *ds = dp->ds; |
1204 | |
1205 | phylink_ethtool_get_wol(dp->pl, w); |
1206 | |
1207 | if (ds->ops->get_wol) |
1208 | ds->ops->get_wol(ds, dp->index, w); |
1209 | } |
1210 | |
1211 | static int dsa_user_set_wol(struct net_device *dev, struct ethtool_wolinfo *w) |
1212 | { |
1213 | struct dsa_port *dp = dsa_user_to_port(dev); |
1214 | struct dsa_switch *ds = dp->ds; |
1215 | int ret = -EOPNOTSUPP; |
1216 | |
1217 | phylink_ethtool_set_wol(dp->pl, w); |
1218 | |
1219 | if (ds->ops->set_wol) |
1220 | ret = ds->ops->set_wol(ds, dp->index, w); |
1221 | |
1222 | return ret; |
1223 | } |
1224 | |
1225 | static int dsa_user_set_eee(struct net_device *dev, struct ethtool_keee *e) |
1226 | { |
1227 | struct dsa_port *dp = dsa_user_to_port(dev); |
1228 | struct dsa_switch *ds = dp->ds; |
1229 | int ret; |
1230 | |
1231 | /* Port's PHY and MAC both need to be EEE capable */ |
1232 | if (!dev->phydev || !dp->pl) |
1233 | return -ENODEV; |
1234 | |
1235 | if (!ds->ops->set_mac_eee) |
1236 | return -EOPNOTSUPP; |
1237 | |
1238 | ret = ds->ops->set_mac_eee(ds, dp->index, e); |
1239 | if (ret) |
1240 | return ret; |
1241 | |
1242 | return phylink_ethtool_set_eee(link: dp->pl, eee: e); |
1243 | } |
1244 | |
1245 | static int dsa_user_get_eee(struct net_device *dev, struct ethtool_keee *e) |
1246 | { |
1247 | struct dsa_port *dp = dsa_user_to_port(dev); |
1248 | struct dsa_switch *ds = dp->ds; |
1249 | int ret; |
1250 | |
1251 | /* Port's PHY and MAC both need to be EEE capable */ |
1252 | if (!dev->phydev || !dp->pl) |
1253 | return -ENODEV; |
1254 | |
1255 | if (!ds->ops->get_mac_eee) |
1256 | return -EOPNOTSUPP; |
1257 | |
1258 | ret = ds->ops->get_mac_eee(ds, dp->index, e); |
1259 | if (ret) |
1260 | return ret; |
1261 | |
1262 | return phylink_ethtool_get_eee(link: dp->pl, eee: e); |
1263 | } |
1264 | |
1265 | static int dsa_user_get_link_ksettings(struct net_device *dev, |
1266 | struct ethtool_link_ksettings *cmd) |
1267 | { |
1268 | struct dsa_port *dp = dsa_user_to_port(dev); |
1269 | |
1270 | return phylink_ethtool_ksettings_get(dp->pl, cmd); |
1271 | } |
1272 | |
1273 | static int dsa_user_set_link_ksettings(struct net_device *dev, |
1274 | const struct ethtool_link_ksettings *cmd) |
1275 | { |
1276 | struct dsa_port *dp = dsa_user_to_port(dev); |
1277 | |
1278 | return phylink_ethtool_ksettings_set(dp->pl, cmd); |
1279 | } |
1280 | |
1281 | static void dsa_user_get_pause_stats(struct net_device *dev, |
1282 | struct ethtool_pause_stats *pause_stats) |
1283 | { |
1284 | struct dsa_port *dp = dsa_user_to_port(dev); |
1285 | struct dsa_switch *ds = dp->ds; |
1286 | |
1287 | if (ds->ops->get_pause_stats) |
1288 | ds->ops->get_pause_stats(ds, dp->index, pause_stats); |
1289 | } |
1290 | |
1291 | static void dsa_user_get_pauseparam(struct net_device *dev, |
1292 | struct ethtool_pauseparam *pause) |
1293 | { |
1294 | struct dsa_port *dp = dsa_user_to_port(dev); |
1295 | |
1296 | phylink_ethtool_get_pauseparam(dp->pl, pause); |
1297 | } |
1298 | |
1299 | static int dsa_user_set_pauseparam(struct net_device *dev, |
1300 | struct ethtool_pauseparam *pause) |
1301 | { |
1302 | struct dsa_port *dp = dsa_user_to_port(dev); |
1303 | |
1304 | return phylink_ethtool_set_pauseparam(dp->pl, pause); |
1305 | } |
1306 | |
1307 | #ifdef CONFIG_NET_POLL_CONTROLLER |
1308 | static int dsa_user_netpoll_setup(struct net_device *dev, |
1309 | struct netpoll_info *ni) |
1310 | { |
1311 | struct net_device *conduit = dsa_user_to_conduit(dev); |
1312 | struct dsa_user_priv *p = netdev_priv(dev); |
1313 | struct netpoll *netpoll; |
1314 | int err = 0; |
1315 | |
1316 | netpoll = kzalloc(size: sizeof(*netpoll), GFP_KERNEL); |
1317 | if (!netpoll) |
1318 | return -ENOMEM; |
1319 | |
1320 | err = __netpoll_setup(np: netpoll, ndev: conduit); |
1321 | if (err) { |
1322 | kfree(objp: netpoll); |
1323 | goto out; |
1324 | } |
1325 | |
1326 | p->netpoll = netpoll; |
1327 | out: |
1328 | return err; |
1329 | } |
1330 | |
1331 | static void dsa_user_netpoll_cleanup(struct net_device *dev) |
1332 | { |
1333 | struct dsa_user_priv *p = netdev_priv(dev); |
1334 | struct netpoll *netpoll = p->netpoll; |
1335 | |
1336 | if (!netpoll) |
1337 | return; |
1338 | |
1339 | p->netpoll = NULL; |
1340 | |
1341 | __netpoll_free(np: netpoll); |
1342 | } |
1343 | |
1344 | static void dsa_user_poll_controller(struct net_device *dev) |
1345 | { |
1346 | } |
1347 | #endif |
1348 | |
1349 | static struct dsa_mall_tc_entry * |
1350 | dsa_user_mall_tc_entry_find(struct net_device *dev, unsigned long cookie) |
1351 | { |
1352 | struct dsa_user_priv *p = netdev_priv(dev); |
1353 | struct dsa_mall_tc_entry *mall_tc_entry; |
1354 | |
1355 | list_for_each_entry(mall_tc_entry, &p->mall_tc_list, list) |
1356 | if (mall_tc_entry->cookie == cookie) |
1357 | return mall_tc_entry; |
1358 | |
1359 | return NULL; |
1360 | } |
1361 | |
1362 | static int |
1363 | dsa_user_add_cls_matchall_mirred(struct net_device *dev, |
1364 | struct tc_cls_matchall_offload *cls, |
1365 | bool ingress) |
1366 | { |
1367 | struct netlink_ext_ack *extack = cls->common.extack; |
1368 | struct dsa_port *dp = dsa_user_to_port(dev); |
1369 | struct dsa_user_priv *p = netdev_priv(dev); |
1370 | struct dsa_mall_mirror_tc_entry *mirror; |
1371 | struct dsa_mall_tc_entry *mall_tc_entry; |
1372 | struct dsa_switch *ds = dp->ds; |
1373 | struct flow_action_entry *act; |
1374 | struct dsa_port *to_dp; |
1375 | int err; |
1376 | |
1377 | if (!ds->ops->port_mirror_add) |
1378 | return -EOPNOTSUPP; |
1379 | |
1380 | if (!flow_action_basic_hw_stats_check(action: &cls->rule->action, |
1381 | extack: cls->common.extack)) |
1382 | return -EOPNOTSUPP; |
1383 | |
1384 | act = &cls->rule->action.entries[0]; |
1385 | |
1386 | if (!act->dev) |
1387 | return -EINVAL; |
1388 | |
1389 | if (!dsa_user_dev_check(dev: act->dev)) |
1390 | return -EOPNOTSUPP; |
1391 | |
1392 | mall_tc_entry = kzalloc(size: sizeof(*mall_tc_entry), GFP_KERNEL); |
1393 | if (!mall_tc_entry) |
1394 | return -ENOMEM; |
1395 | |
1396 | mall_tc_entry->cookie = cls->cookie; |
1397 | mall_tc_entry->type = DSA_PORT_MALL_MIRROR; |
1398 | mirror = &mall_tc_entry->mirror; |
1399 | |
1400 | to_dp = dsa_user_to_port(dev: act->dev); |
1401 | |
1402 | mirror->to_local_port = to_dp->index; |
1403 | mirror->ingress = ingress; |
1404 | |
1405 | err = ds->ops->port_mirror_add(ds, dp->index, mirror, ingress, extack); |
1406 | if (err) { |
1407 | kfree(objp: mall_tc_entry); |
1408 | return err; |
1409 | } |
1410 | |
1411 | list_add_tail(new: &mall_tc_entry->list, head: &p->mall_tc_list); |
1412 | |
1413 | return err; |
1414 | } |
1415 | |
1416 | static int |
1417 | dsa_user_add_cls_matchall_police(struct net_device *dev, |
1418 | struct tc_cls_matchall_offload *cls, |
1419 | bool ingress) |
1420 | { |
1421 | struct netlink_ext_ack *extack = cls->common.extack; |
1422 | struct dsa_port *dp = dsa_user_to_port(dev); |
1423 | struct dsa_user_priv *p = netdev_priv(dev); |
1424 | struct dsa_mall_policer_tc_entry *policer; |
1425 | struct dsa_mall_tc_entry *mall_tc_entry; |
1426 | struct dsa_switch *ds = dp->ds; |
1427 | struct flow_action_entry *act; |
1428 | int err; |
1429 | |
1430 | if (!ds->ops->port_policer_add) { |
1431 | NL_SET_ERR_MSG_MOD(extack, |
1432 | "Policing offload not implemented" ); |
1433 | return -EOPNOTSUPP; |
1434 | } |
1435 | |
1436 | if (!ingress) { |
1437 | NL_SET_ERR_MSG_MOD(extack, |
1438 | "Only supported on ingress qdisc" ); |
1439 | return -EOPNOTSUPP; |
1440 | } |
1441 | |
1442 | if (!flow_action_basic_hw_stats_check(action: &cls->rule->action, |
1443 | extack: cls->common.extack)) |
1444 | return -EOPNOTSUPP; |
1445 | |
1446 | list_for_each_entry(mall_tc_entry, &p->mall_tc_list, list) { |
1447 | if (mall_tc_entry->type == DSA_PORT_MALL_POLICER) { |
1448 | NL_SET_ERR_MSG_MOD(extack, |
1449 | "Only one port policer allowed" ); |
1450 | return -EEXIST; |
1451 | } |
1452 | } |
1453 | |
1454 | act = &cls->rule->action.entries[0]; |
1455 | |
1456 | mall_tc_entry = kzalloc(size: sizeof(*mall_tc_entry), GFP_KERNEL); |
1457 | if (!mall_tc_entry) |
1458 | return -ENOMEM; |
1459 | |
1460 | mall_tc_entry->cookie = cls->cookie; |
1461 | mall_tc_entry->type = DSA_PORT_MALL_POLICER; |
1462 | policer = &mall_tc_entry->policer; |
1463 | policer->rate_bytes_per_sec = act->police.rate_bytes_ps; |
1464 | policer->burst = act->police.burst; |
1465 | |
1466 | err = ds->ops->port_policer_add(ds, dp->index, policer); |
1467 | if (err) { |
1468 | kfree(objp: mall_tc_entry); |
1469 | return err; |
1470 | } |
1471 | |
1472 | list_add_tail(new: &mall_tc_entry->list, head: &p->mall_tc_list); |
1473 | |
1474 | return err; |
1475 | } |
1476 | |
1477 | static int dsa_user_add_cls_matchall(struct net_device *dev, |
1478 | struct tc_cls_matchall_offload *cls, |
1479 | bool ingress) |
1480 | { |
1481 | int err = -EOPNOTSUPP; |
1482 | |
1483 | if (cls->common.protocol == htons(ETH_P_ALL) && |
1484 | flow_offload_has_one_action(action: &cls->rule->action) && |
1485 | cls->rule->action.entries[0].id == FLOW_ACTION_MIRRED) |
1486 | err = dsa_user_add_cls_matchall_mirred(dev, cls, ingress); |
1487 | else if (flow_offload_has_one_action(action: &cls->rule->action) && |
1488 | cls->rule->action.entries[0].id == FLOW_ACTION_POLICE) |
1489 | err = dsa_user_add_cls_matchall_police(dev, cls, ingress); |
1490 | |
1491 | return err; |
1492 | } |
1493 | |
1494 | static void dsa_user_del_cls_matchall(struct net_device *dev, |
1495 | struct tc_cls_matchall_offload *cls) |
1496 | { |
1497 | struct dsa_port *dp = dsa_user_to_port(dev); |
1498 | struct dsa_mall_tc_entry *mall_tc_entry; |
1499 | struct dsa_switch *ds = dp->ds; |
1500 | |
1501 | mall_tc_entry = dsa_user_mall_tc_entry_find(dev, cookie: cls->cookie); |
1502 | if (!mall_tc_entry) |
1503 | return; |
1504 | |
1505 | list_del(entry: &mall_tc_entry->list); |
1506 | |
1507 | switch (mall_tc_entry->type) { |
1508 | case DSA_PORT_MALL_MIRROR: |
1509 | if (ds->ops->port_mirror_del) |
1510 | ds->ops->port_mirror_del(ds, dp->index, |
1511 | &mall_tc_entry->mirror); |
1512 | break; |
1513 | case DSA_PORT_MALL_POLICER: |
1514 | if (ds->ops->port_policer_del) |
1515 | ds->ops->port_policer_del(ds, dp->index); |
1516 | break; |
1517 | default: |
1518 | WARN_ON(1); |
1519 | } |
1520 | |
1521 | kfree(objp: mall_tc_entry); |
1522 | } |
1523 | |
1524 | static int dsa_user_setup_tc_cls_matchall(struct net_device *dev, |
1525 | struct tc_cls_matchall_offload *cls, |
1526 | bool ingress) |
1527 | { |
1528 | if (cls->common.chain_index) |
1529 | return -EOPNOTSUPP; |
1530 | |
1531 | switch (cls->command) { |
1532 | case TC_CLSMATCHALL_REPLACE: |
1533 | return dsa_user_add_cls_matchall(dev, cls, ingress); |
1534 | case TC_CLSMATCHALL_DESTROY: |
1535 | dsa_user_del_cls_matchall(dev, cls); |
1536 | return 0; |
1537 | default: |
1538 | return -EOPNOTSUPP; |
1539 | } |
1540 | } |
1541 | |
1542 | static int dsa_user_add_cls_flower(struct net_device *dev, |
1543 | struct flow_cls_offload *cls, |
1544 | bool ingress) |
1545 | { |
1546 | struct dsa_port *dp = dsa_user_to_port(dev); |
1547 | struct dsa_switch *ds = dp->ds; |
1548 | int port = dp->index; |
1549 | |
1550 | if (!ds->ops->cls_flower_add) |
1551 | return -EOPNOTSUPP; |
1552 | |
1553 | return ds->ops->cls_flower_add(ds, port, cls, ingress); |
1554 | } |
1555 | |
1556 | static int dsa_user_del_cls_flower(struct net_device *dev, |
1557 | struct flow_cls_offload *cls, |
1558 | bool ingress) |
1559 | { |
1560 | struct dsa_port *dp = dsa_user_to_port(dev); |
1561 | struct dsa_switch *ds = dp->ds; |
1562 | int port = dp->index; |
1563 | |
1564 | if (!ds->ops->cls_flower_del) |
1565 | return -EOPNOTSUPP; |
1566 | |
1567 | return ds->ops->cls_flower_del(ds, port, cls, ingress); |
1568 | } |
1569 | |
1570 | static int dsa_user_stats_cls_flower(struct net_device *dev, |
1571 | struct flow_cls_offload *cls, |
1572 | bool ingress) |
1573 | { |
1574 | struct dsa_port *dp = dsa_user_to_port(dev); |
1575 | struct dsa_switch *ds = dp->ds; |
1576 | int port = dp->index; |
1577 | |
1578 | if (!ds->ops->cls_flower_stats) |
1579 | return -EOPNOTSUPP; |
1580 | |
1581 | return ds->ops->cls_flower_stats(ds, port, cls, ingress); |
1582 | } |
1583 | |
1584 | static int dsa_user_setup_tc_cls_flower(struct net_device *dev, |
1585 | struct flow_cls_offload *cls, |
1586 | bool ingress) |
1587 | { |
1588 | switch (cls->command) { |
1589 | case FLOW_CLS_REPLACE: |
1590 | return dsa_user_add_cls_flower(dev, cls, ingress); |
1591 | case FLOW_CLS_DESTROY: |
1592 | return dsa_user_del_cls_flower(dev, cls, ingress); |
1593 | case FLOW_CLS_STATS: |
1594 | return dsa_user_stats_cls_flower(dev, cls, ingress); |
1595 | default: |
1596 | return -EOPNOTSUPP; |
1597 | } |
1598 | } |
1599 | |
1600 | static int dsa_user_setup_tc_block_cb(enum tc_setup_type type, void *type_data, |
1601 | void *cb_priv, bool ingress) |
1602 | { |
1603 | struct net_device *dev = cb_priv; |
1604 | |
1605 | if (!tc_can_offload(dev)) |
1606 | return -EOPNOTSUPP; |
1607 | |
1608 | switch (type) { |
1609 | case TC_SETUP_CLSMATCHALL: |
1610 | return dsa_user_setup_tc_cls_matchall(dev, cls: type_data, ingress); |
1611 | case TC_SETUP_CLSFLOWER: |
1612 | return dsa_user_setup_tc_cls_flower(dev, cls: type_data, ingress); |
1613 | default: |
1614 | return -EOPNOTSUPP; |
1615 | } |
1616 | } |
1617 | |
1618 | static int dsa_user_setup_tc_block_cb_ig(enum tc_setup_type type, |
1619 | void *type_data, void *cb_priv) |
1620 | { |
1621 | return dsa_user_setup_tc_block_cb(type, type_data, cb_priv, ingress: true); |
1622 | } |
1623 | |
1624 | static int dsa_user_setup_tc_block_cb_eg(enum tc_setup_type type, |
1625 | void *type_data, void *cb_priv) |
1626 | { |
1627 | return dsa_user_setup_tc_block_cb(type, type_data, cb_priv, ingress: false); |
1628 | } |
1629 | |
1630 | static LIST_HEAD(dsa_user_block_cb_list); |
1631 | |
1632 | static int dsa_user_setup_tc_block(struct net_device *dev, |
1633 | struct flow_block_offload *f) |
1634 | { |
1635 | struct flow_block_cb *block_cb; |
1636 | flow_setup_cb_t *cb; |
1637 | |
1638 | if (f->binder_type == FLOW_BLOCK_BINDER_TYPE_CLSACT_INGRESS) |
1639 | cb = dsa_user_setup_tc_block_cb_ig; |
1640 | else if (f->binder_type == FLOW_BLOCK_BINDER_TYPE_CLSACT_EGRESS) |
1641 | cb = dsa_user_setup_tc_block_cb_eg; |
1642 | else |
1643 | return -EOPNOTSUPP; |
1644 | |
1645 | f->driver_block_list = &dsa_user_block_cb_list; |
1646 | |
1647 | switch (f->command) { |
1648 | case FLOW_BLOCK_BIND: |
1649 | if (flow_block_cb_is_busy(cb, cb_ident: dev, driver_block_list: &dsa_user_block_cb_list)) |
1650 | return -EBUSY; |
1651 | |
1652 | block_cb = flow_block_cb_alloc(cb, cb_ident: dev, cb_priv: dev, NULL); |
1653 | if (IS_ERR(ptr: block_cb)) |
1654 | return PTR_ERR(ptr: block_cb); |
1655 | |
1656 | flow_block_cb_add(block_cb, offload: f); |
1657 | list_add_tail(new: &block_cb->driver_list, head: &dsa_user_block_cb_list); |
1658 | return 0; |
1659 | case FLOW_BLOCK_UNBIND: |
1660 | block_cb = flow_block_cb_lookup(block: f->block, cb, cb_ident: dev); |
1661 | if (!block_cb) |
1662 | return -ENOENT; |
1663 | |
1664 | flow_block_cb_remove(block_cb, offload: f); |
1665 | list_del(entry: &block_cb->driver_list); |
1666 | return 0; |
1667 | default: |
1668 | return -EOPNOTSUPP; |
1669 | } |
1670 | } |
1671 | |
1672 | static int dsa_user_setup_ft_block(struct dsa_switch *ds, int port, |
1673 | void *type_data) |
1674 | { |
1675 | struct net_device *conduit = dsa_port_to_conduit(dp: dsa_to_port(ds, p: port)); |
1676 | |
1677 | if (!conduit->netdev_ops->ndo_setup_tc) |
1678 | return -EOPNOTSUPP; |
1679 | |
1680 | return conduit->netdev_ops->ndo_setup_tc(conduit, TC_SETUP_FT, type_data); |
1681 | } |
1682 | |
1683 | static int dsa_user_setup_tc(struct net_device *dev, enum tc_setup_type type, |
1684 | void *type_data) |
1685 | { |
1686 | struct dsa_port *dp = dsa_user_to_port(dev); |
1687 | struct dsa_switch *ds = dp->ds; |
1688 | |
1689 | switch (type) { |
1690 | case TC_SETUP_BLOCK: |
1691 | return dsa_user_setup_tc_block(dev, f: type_data); |
1692 | case TC_SETUP_FT: |
1693 | return dsa_user_setup_ft_block(ds, port: dp->index, type_data); |
1694 | default: |
1695 | break; |
1696 | } |
1697 | |
1698 | if (!ds->ops->port_setup_tc) |
1699 | return -EOPNOTSUPP; |
1700 | |
1701 | return ds->ops->port_setup_tc(ds, dp->index, type, type_data); |
1702 | } |
1703 | |
1704 | static int dsa_user_get_rxnfc(struct net_device *dev, |
1705 | struct ethtool_rxnfc *nfc, u32 *rule_locs) |
1706 | { |
1707 | struct dsa_port *dp = dsa_user_to_port(dev); |
1708 | struct dsa_switch *ds = dp->ds; |
1709 | |
1710 | if (!ds->ops->get_rxnfc) |
1711 | return -EOPNOTSUPP; |
1712 | |
1713 | return ds->ops->get_rxnfc(ds, dp->index, nfc, rule_locs); |
1714 | } |
1715 | |
1716 | static int dsa_user_set_rxnfc(struct net_device *dev, |
1717 | struct ethtool_rxnfc *nfc) |
1718 | { |
1719 | struct dsa_port *dp = dsa_user_to_port(dev); |
1720 | struct dsa_switch *ds = dp->ds; |
1721 | |
1722 | if (!ds->ops->set_rxnfc) |
1723 | return -EOPNOTSUPP; |
1724 | |
1725 | return ds->ops->set_rxnfc(ds, dp->index, nfc); |
1726 | } |
1727 | |
1728 | static int dsa_user_get_ts_info(struct net_device *dev, |
1729 | struct ethtool_ts_info *ts) |
1730 | { |
1731 | struct dsa_user_priv *p = netdev_priv(dev); |
1732 | struct dsa_switch *ds = p->dp->ds; |
1733 | |
1734 | if (!ds->ops->get_ts_info) |
1735 | return -EOPNOTSUPP; |
1736 | |
1737 | return ds->ops->get_ts_info(ds, p->dp->index, ts); |
1738 | } |
1739 | |
1740 | static int dsa_user_vlan_rx_add_vid(struct net_device *dev, __be16 proto, |
1741 | u16 vid) |
1742 | { |
1743 | struct dsa_port *dp = dsa_user_to_port(dev); |
1744 | struct switchdev_obj_port_vlan vlan = { |
1745 | .obj.id = SWITCHDEV_OBJ_ID_PORT_VLAN, |
1746 | .vid = vid, |
1747 | /* This API only allows programming tagged, non-PVID VIDs */ |
1748 | .flags = 0, |
1749 | }; |
1750 | struct netlink_ext_ack extack = {0}; |
1751 | struct dsa_switch *ds = dp->ds; |
1752 | struct netdev_hw_addr *ha; |
1753 | struct dsa_vlan *v; |
1754 | int ret; |
1755 | |
1756 | /* User port... */ |
1757 | ret = dsa_port_vlan_add(dp, vlan: &vlan, extack: &extack); |
1758 | if (ret) { |
1759 | if (extack._msg) |
1760 | netdev_err(dev, format: "%s\n" , extack._msg); |
1761 | return ret; |
1762 | } |
1763 | |
1764 | /* And CPU port... */ |
1765 | ret = dsa_port_host_vlan_add(dp, vlan: &vlan, extack: &extack); |
1766 | if (ret) { |
1767 | if (extack._msg) |
1768 | netdev_err(dev, format: "CPU port %d: %s\n" , dp->cpu_dp->index, |
1769 | extack._msg); |
1770 | return ret; |
1771 | } |
1772 | |
1773 | if (!dsa_switch_supports_uc_filtering(ds) && |
1774 | !dsa_switch_supports_mc_filtering(ds)) |
1775 | return 0; |
1776 | |
1777 | v = kzalloc(size: sizeof(*v), GFP_KERNEL); |
1778 | if (!v) { |
1779 | ret = -ENOMEM; |
1780 | goto rollback; |
1781 | } |
1782 | |
1783 | netif_addr_lock_bh(dev); |
1784 | |
1785 | v->vid = vid; |
1786 | list_add_tail(new: &v->list, head: &dp->user_vlans); |
1787 | |
1788 | if (dsa_switch_supports_mc_filtering(ds)) { |
1789 | netdev_for_each_synced_mc_addr(ha, dev) { |
1790 | dsa_user_schedule_standalone_work(dev, event: DSA_MC_ADD, |
1791 | addr: ha->addr, vid); |
1792 | } |
1793 | } |
1794 | |
1795 | if (dsa_switch_supports_uc_filtering(ds)) { |
1796 | netdev_for_each_synced_uc_addr(ha, dev) { |
1797 | dsa_user_schedule_standalone_work(dev, event: DSA_UC_ADD, |
1798 | addr: ha->addr, vid); |
1799 | } |
1800 | } |
1801 | |
1802 | netif_addr_unlock_bh(dev); |
1803 | |
1804 | dsa_flush_workqueue(); |
1805 | |
1806 | return 0; |
1807 | |
1808 | rollback: |
1809 | dsa_port_host_vlan_del(dp, vlan: &vlan); |
1810 | dsa_port_vlan_del(dp, vlan: &vlan); |
1811 | |
1812 | return ret; |
1813 | } |
1814 | |
1815 | static int dsa_user_vlan_rx_kill_vid(struct net_device *dev, __be16 proto, |
1816 | u16 vid) |
1817 | { |
1818 | struct dsa_port *dp = dsa_user_to_port(dev); |
1819 | struct switchdev_obj_port_vlan vlan = { |
1820 | .vid = vid, |
1821 | /* This API only allows programming tagged, non-PVID VIDs */ |
1822 | .flags = 0, |
1823 | }; |
1824 | struct dsa_switch *ds = dp->ds; |
1825 | struct netdev_hw_addr *ha; |
1826 | struct dsa_vlan *v; |
1827 | int err; |
1828 | |
1829 | err = dsa_port_vlan_del(dp, vlan: &vlan); |
1830 | if (err) |
1831 | return err; |
1832 | |
1833 | err = dsa_port_host_vlan_del(dp, vlan: &vlan); |
1834 | if (err) |
1835 | return err; |
1836 | |
1837 | if (!dsa_switch_supports_uc_filtering(ds) && |
1838 | !dsa_switch_supports_mc_filtering(ds)) |
1839 | return 0; |
1840 | |
1841 | netif_addr_lock_bh(dev); |
1842 | |
1843 | v = dsa_vlan_find(vlan_list: &dp->user_vlans, vlan: &vlan); |
1844 | if (!v) { |
1845 | netif_addr_unlock_bh(dev); |
1846 | return -ENOENT; |
1847 | } |
1848 | |
1849 | list_del(entry: &v->list); |
1850 | kfree(objp: v); |
1851 | |
1852 | if (dsa_switch_supports_mc_filtering(ds)) { |
1853 | netdev_for_each_synced_mc_addr(ha, dev) { |
1854 | dsa_user_schedule_standalone_work(dev, event: DSA_MC_DEL, |
1855 | addr: ha->addr, vid); |
1856 | } |
1857 | } |
1858 | |
1859 | if (dsa_switch_supports_uc_filtering(ds)) { |
1860 | netdev_for_each_synced_uc_addr(ha, dev) { |
1861 | dsa_user_schedule_standalone_work(dev, event: DSA_UC_DEL, |
1862 | addr: ha->addr, vid); |
1863 | } |
1864 | } |
1865 | |
1866 | netif_addr_unlock_bh(dev); |
1867 | |
1868 | dsa_flush_workqueue(); |
1869 | |
1870 | return 0; |
1871 | } |
1872 | |
1873 | static int dsa_user_restore_vlan(struct net_device *vdev, int vid, void *arg) |
1874 | { |
1875 | __be16 proto = vdev ? vlan_dev_vlan_proto(dev: vdev) : htons(ETH_P_8021Q); |
1876 | |
1877 | return dsa_user_vlan_rx_add_vid(dev: arg, proto, vid); |
1878 | } |
1879 | |
1880 | static int dsa_user_clear_vlan(struct net_device *vdev, int vid, void *arg) |
1881 | { |
1882 | __be16 proto = vdev ? vlan_dev_vlan_proto(dev: vdev) : htons(ETH_P_8021Q); |
1883 | |
1884 | return dsa_user_vlan_rx_kill_vid(dev: arg, proto, vid); |
1885 | } |
1886 | |
1887 | /* Keep the VLAN RX filtering list in sync with the hardware only if VLAN |
1888 | * filtering is enabled. The baseline is that only ports that offload a |
1889 | * VLAN-aware bridge are VLAN-aware, and standalone ports are VLAN-unaware, |
1890 | * but there are exceptions for quirky hardware. |
1891 | * |
1892 | * If ds->vlan_filtering_is_global = true, then standalone ports which share |
1893 | * the same switch with other ports that offload a VLAN-aware bridge are also |
1894 | * inevitably VLAN-aware. |
1895 | * |
1896 | * To summarize, a DSA switch port offloads: |
1897 | * |
1898 | * - If standalone (this includes software bridge, software LAG): |
1899 | * - if ds->needs_standalone_vlan_filtering = true, OR if |
1900 | * (ds->vlan_filtering_is_global = true AND there are bridges spanning |
1901 | * this switch chip which have vlan_filtering=1) |
1902 | * - the 8021q upper VLANs |
1903 | * - else (standalone VLAN filtering is not needed, VLAN filtering is not |
1904 | * global, or it is, but no port is under a VLAN-aware bridge): |
1905 | * - no VLAN (any 8021q upper is a software VLAN) |
1906 | * |
1907 | * - If under a vlan_filtering=0 bridge which it offload: |
1908 | * - if ds->configure_vlan_while_not_filtering = true (default): |
1909 | * - the bridge VLANs. These VLANs are committed to hardware but inactive. |
1910 | * - else (deprecated): |
1911 | * - no VLAN. The bridge VLANs are not restored when VLAN awareness is |
1912 | * enabled, so this behavior is broken and discouraged. |
1913 | * |
1914 | * - If under a vlan_filtering=1 bridge which it offload: |
1915 | * - the bridge VLANs |
1916 | * - the 8021q upper VLANs |
1917 | */ |
1918 | int dsa_user_manage_vlan_filtering(struct net_device *user, |
1919 | bool vlan_filtering) |
1920 | { |
1921 | int err; |
1922 | |
1923 | if (vlan_filtering) { |
1924 | user->features |= NETIF_F_HW_VLAN_CTAG_FILTER; |
1925 | |
1926 | err = vlan_for_each(dev: user, action: dsa_user_restore_vlan, arg: user); |
1927 | if (err) { |
1928 | vlan_for_each(dev: user, action: dsa_user_clear_vlan, arg: user); |
1929 | user->features &= ~NETIF_F_HW_VLAN_CTAG_FILTER; |
1930 | return err; |
1931 | } |
1932 | } else { |
1933 | err = vlan_for_each(dev: user, action: dsa_user_clear_vlan, arg: user); |
1934 | if (err) |
1935 | return err; |
1936 | |
1937 | user->features &= ~NETIF_F_HW_VLAN_CTAG_FILTER; |
1938 | } |
1939 | |
1940 | return 0; |
1941 | } |
1942 | |
1943 | struct dsa_hw_port { |
1944 | struct list_head list; |
1945 | struct net_device *dev; |
1946 | int old_mtu; |
1947 | }; |
1948 | |
1949 | static int dsa_hw_port_list_set_mtu(struct list_head *hw_port_list, int mtu) |
1950 | { |
1951 | const struct dsa_hw_port *p; |
1952 | int err; |
1953 | |
1954 | list_for_each_entry(p, hw_port_list, list) { |
1955 | if (p->dev->mtu == mtu) |
1956 | continue; |
1957 | |
1958 | err = dev_set_mtu(p->dev, mtu); |
1959 | if (err) |
1960 | goto rollback; |
1961 | } |
1962 | |
1963 | return 0; |
1964 | |
1965 | rollback: |
1966 | list_for_each_entry_continue_reverse(p, hw_port_list, list) { |
1967 | if (p->dev->mtu == p->old_mtu) |
1968 | continue; |
1969 | |
1970 | if (dev_set_mtu(p->dev, p->old_mtu)) |
1971 | netdev_err(dev: p->dev, format: "Failed to restore MTU\n" ); |
1972 | } |
1973 | |
1974 | return err; |
1975 | } |
1976 | |
1977 | static void dsa_hw_port_list_free(struct list_head *hw_port_list) |
1978 | { |
1979 | struct dsa_hw_port *p, *n; |
1980 | |
1981 | list_for_each_entry_safe(p, n, hw_port_list, list) |
1982 | kfree(objp: p); |
1983 | } |
1984 | |
1985 | /* Make the hardware datapath to/from @dev limited to a common MTU */ |
1986 | static void dsa_bridge_mtu_normalization(struct dsa_port *dp) |
1987 | { |
1988 | struct list_head hw_port_list; |
1989 | struct dsa_switch_tree *dst; |
1990 | int min_mtu = ETH_MAX_MTU; |
1991 | struct dsa_port *other_dp; |
1992 | int err; |
1993 | |
1994 | if (!dp->ds->mtu_enforcement_ingress) |
1995 | return; |
1996 | |
1997 | if (!dp->bridge) |
1998 | return; |
1999 | |
2000 | INIT_LIST_HEAD(list: &hw_port_list); |
2001 | |
2002 | /* Populate the list of ports that are part of the same bridge |
2003 | * as the newly added/modified port |
2004 | */ |
2005 | list_for_each_entry(dst, &dsa_tree_list, list) { |
2006 | list_for_each_entry(other_dp, &dst->ports, list) { |
2007 | struct dsa_hw_port *hw_port; |
2008 | struct net_device *user; |
2009 | |
2010 | if (other_dp->type != DSA_PORT_TYPE_USER) |
2011 | continue; |
2012 | |
2013 | if (!dsa_port_bridge_same(a: dp, b: other_dp)) |
2014 | continue; |
2015 | |
2016 | if (!other_dp->ds->mtu_enforcement_ingress) |
2017 | continue; |
2018 | |
2019 | user = other_dp->user; |
2020 | |
2021 | if (min_mtu > user->mtu) |
2022 | min_mtu = user->mtu; |
2023 | |
2024 | hw_port = kzalloc(size: sizeof(*hw_port), GFP_KERNEL); |
2025 | if (!hw_port) |
2026 | goto out; |
2027 | |
2028 | hw_port->dev = user; |
2029 | hw_port->old_mtu = user->mtu; |
2030 | |
2031 | list_add(new: &hw_port->list, head: &hw_port_list); |
2032 | } |
2033 | } |
2034 | |
2035 | /* Attempt to configure the entire hardware bridge to the newly added |
2036 | * interface's MTU first, regardless of whether the intention of the |
2037 | * user was to raise or lower it. |
2038 | */ |
2039 | err = dsa_hw_port_list_set_mtu(hw_port_list: &hw_port_list, mtu: dp->user->mtu); |
2040 | if (!err) |
2041 | goto out; |
2042 | |
2043 | /* Clearly that didn't work out so well, so just set the minimum MTU on |
2044 | * all hardware bridge ports now. If this fails too, then all ports will |
2045 | * still have their old MTU rolled back anyway. |
2046 | */ |
2047 | dsa_hw_port_list_set_mtu(hw_port_list: &hw_port_list, mtu: min_mtu); |
2048 | |
2049 | out: |
2050 | dsa_hw_port_list_free(hw_port_list: &hw_port_list); |
2051 | } |
2052 | |
2053 | int dsa_user_change_mtu(struct net_device *dev, int new_mtu) |
2054 | { |
2055 | struct net_device *conduit = dsa_user_to_conduit(dev); |
2056 | struct dsa_port *dp = dsa_user_to_port(dev); |
2057 | struct dsa_port *cpu_dp = dp->cpu_dp; |
2058 | struct dsa_switch *ds = dp->ds; |
2059 | struct dsa_port *other_dp; |
2060 | int largest_mtu = 0; |
2061 | int new_conduit_mtu; |
2062 | int old_conduit_mtu; |
2063 | int mtu_limit; |
2064 | int overhead; |
2065 | int cpu_mtu; |
2066 | int err; |
2067 | |
2068 | if (!ds->ops->port_change_mtu) |
2069 | return -EOPNOTSUPP; |
2070 | |
2071 | dsa_tree_for_each_user_port(other_dp, ds->dst) { |
2072 | int user_mtu; |
2073 | |
2074 | /* During probe, this function will be called for each user |
2075 | * device, while not all of them have been allocated. That's |
2076 | * ok, it doesn't change what the maximum is, so ignore it. |
2077 | */ |
2078 | if (!other_dp->user) |
2079 | continue; |
2080 | |
2081 | /* Pretend that we already applied the setting, which we |
2082 | * actually haven't (still haven't done all integrity checks) |
2083 | */ |
2084 | if (dp == other_dp) |
2085 | user_mtu = new_mtu; |
2086 | else |
2087 | user_mtu = other_dp->user->mtu; |
2088 | |
2089 | if (largest_mtu < user_mtu) |
2090 | largest_mtu = user_mtu; |
2091 | } |
2092 | |
2093 | overhead = dsa_tag_protocol_overhead(ops: cpu_dp->tag_ops); |
2094 | mtu_limit = min_t(int, conduit->max_mtu, dev->max_mtu + overhead); |
2095 | old_conduit_mtu = conduit->mtu; |
2096 | new_conduit_mtu = largest_mtu + overhead; |
2097 | if (new_conduit_mtu > mtu_limit) |
2098 | return -ERANGE; |
2099 | |
2100 | /* If the conduit MTU isn't over limit, there's no need to check the CPU |
2101 | * MTU, since that surely isn't either. |
2102 | */ |
2103 | cpu_mtu = largest_mtu; |
2104 | |
2105 | /* Start applying stuff */ |
2106 | if (new_conduit_mtu != old_conduit_mtu) { |
2107 | err = dev_set_mtu(conduit, new_conduit_mtu); |
2108 | if (err < 0) |
2109 | goto out_conduit_failed; |
2110 | |
2111 | /* We only need to propagate the MTU of the CPU port to |
2112 | * upstream switches, so emit a notifier which updates them. |
2113 | */ |
2114 | err = dsa_port_mtu_change(dp: cpu_dp, new_mtu: cpu_mtu); |
2115 | if (err) |
2116 | goto out_cpu_failed; |
2117 | } |
2118 | |
2119 | err = ds->ops->port_change_mtu(ds, dp->index, new_mtu); |
2120 | if (err) |
2121 | goto out_port_failed; |
2122 | |
2123 | dev->mtu = new_mtu; |
2124 | |
2125 | dsa_bridge_mtu_normalization(dp); |
2126 | |
2127 | return 0; |
2128 | |
2129 | out_port_failed: |
2130 | if (new_conduit_mtu != old_conduit_mtu) |
2131 | dsa_port_mtu_change(dp: cpu_dp, new_mtu: old_conduit_mtu - overhead); |
2132 | out_cpu_failed: |
2133 | if (new_conduit_mtu != old_conduit_mtu) |
2134 | dev_set_mtu(conduit, old_conduit_mtu); |
2135 | out_conduit_failed: |
2136 | return err; |
2137 | } |
2138 | |
2139 | static int __maybe_unused |
2140 | dsa_user_dcbnl_set_default_prio(struct net_device *dev, struct dcb_app *app) |
2141 | { |
2142 | struct dsa_port *dp = dsa_user_to_port(dev); |
2143 | struct dsa_switch *ds = dp->ds; |
2144 | unsigned long mask, new_prio; |
2145 | int err, port = dp->index; |
2146 | |
2147 | if (!ds->ops->port_set_default_prio) |
2148 | return -EOPNOTSUPP; |
2149 | |
2150 | err = dcb_ieee_setapp(dev, app); |
2151 | if (err) |
2152 | return err; |
2153 | |
2154 | mask = dcb_ieee_getapp_mask(dev, app); |
2155 | new_prio = __fls(word: mask); |
2156 | |
2157 | err = ds->ops->port_set_default_prio(ds, port, new_prio); |
2158 | if (err) { |
2159 | dcb_ieee_delapp(dev, app); |
2160 | return err; |
2161 | } |
2162 | |
2163 | return 0; |
2164 | } |
2165 | |
2166 | static int __maybe_unused |
2167 | dsa_user_dcbnl_add_dscp_prio(struct net_device *dev, struct dcb_app *app) |
2168 | { |
2169 | struct dsa_port *dp = dsa_user_to_port(dev); |
2170 | struct dsa_switch *ds = dp->ds; |
2171 | unsigned long mask, new_prio; |
2172 | int err, port = dp->index; |
2173 | u8 dscp = app->protocol; |
2174 | |
2175 | if (!ds->ops->port_add_dscp_prio) |
2176 | return -EOPNOTSUPP; |
2177 | |
2178 | if (dscp >= 64) { |
2179 | netdev_err(dev, format: "DSCP APP entry with protocol value %u is invalid\n" , |
2180 | dscp); |
2181 | return -EINVAL; |
2182 | } |
2183 | |
2184 | err = dcb_ieee_setapp(dev, app); |
2185 | if (err) |
2186 | return err; |
2187 | |
2188 | mask = dcb_ieee_getapp_mask(dev, app); |
2189 | new_prio = __fls(word: mask); |
2190 | |
2191 | err = ds->ops->port_add_dscp_prio(ds, port, dscp, new_prio); |
2192 | if (err) { |
2193 | dcb_ieee_delapp(dev, app); |
2194 | return err; |
2195 | } |
2196 | |
2197 | return 0; |
2198 | } |
2199 | |
2200 | static int __maybe_unused dsa_user_dcbnl_ieee_setapp(struct net_device *dev, |
2201 | struct dcb_app *app) |
2202 | { |
2203 | switch (app->selector) { |
2204 | case IEEE_8021QAZ_APP_SEL_ETHERTYPE: |
2205 | switch (app->protocol) { |
2206 | case 0: |
2207 | return dsa_user_dcbnl_set_default_prio(dev, app); |
2208 | default: |
2209 | return -EOPNOTSUPP; |
2210 | } |
2211 | break; |
2212 | case IEEE_8021QAZ_APP_SEL_DSCP: |
2213 | return dsa_user_dcbnl_add_dscp_prio(dev, app); |
2214 | default: |
2215 | return -EOPNOTSUPP; |
2216 | } |
2217 | } |
2218 | |
2219 | static int __maybe_unused |
2220 | dsa_user_dcbnl_del_default_prio(struct net_device *dev, struct dcb_app *app) |
2221 | { |
2222 | struct dsa_port *dp = dsa_user_to_port(dev); |
2223 | struct dsa_switch *ds = dp->ds; |
2224 | unsigned long mask, new_prio; |
2225 | int err, port = dp->index; |
2226 | |
2227 | if (!ds->ops->port_set_default_prio) |
2228 | return -EOPNOTSUPP; |
2229 | |
2230 | err = dcb_ieee_delapp(dev, app); |
2231 | if (err) |
2232 | return err; |
2233 | |
2234 | mask = dcb_ieee_getapp_mask(dev, app); |
2235 | new_prio = mask ? __fls(word: mask) : 0; |
2236 | |
2237 | err = ds->ops->port_set_default_prio(ds, port, new_prio); |
2238 | if (err) { |
2239 | dcb_ieee_setapp(dev, app); |
2240 | return err; |
2241 | } |
2242 | |
2243 | return 0; |
2244 | } |
2245 | |
2246 | static int __maybe_unused |
2247 | dsa_user_dcbnl_del_dscp_prio(struct net_device *dev, struct dcb_app *app) |
2248 | { |
2249 | struct dsa_port *dp = dsa_user_to_port(dev); |
2250 | struct dsa_switch *ds = dp->ds; |
2251 | int err, port = dp->index; |
2252 | u8 dscp = app->protocol; |
2253 | |
2254 | if (!ds->ops->port_del_dscp_prio) |
2255 | return -EOPNOTSUPP; |
2256 | |
2257 | err = dcb_ieee_delapp(dev, app); |
2258 | if (err) |
2259 | return err; |
2260 | |
2261 | err = ds->ops->port_del_dscp_prio(ds, port, dscp, app->priority); |
2262 | if (err) { |
2263 | dcb_ieee_setapp(dev, app); |
2264 | return err; |
2265 | } |
2266 | |
2267 | return 0; |
2268 | } |
2269 | |
2270 | static int __maybe_unused dsa_user_dcbnl_ieee_delapp(struct net_device *dev, |
2271 | struct dcb_app *app) |
2272 | { |
2273 | switch (app->selector) { |
2274 | case IEEE_8021QAZ_APP_SEL_ETHERTYPE: |
2275 | switch (app->protocol) { |
2276 | case 0: |
2277 | return dsa_user_dcbnl_del_default_prio(dev, app); |
2278 | default: |
2279 | return -EOPNOTSUPP; |
2280 | } |
2281 | break; |
2282 | case IEEE_8021QAZ_APP_SEL_DSCP: |
2283 | return dsa_user_dcbnl_del_dscp_prio(dev, app); |
2284 | default: |
2285 | return -EOPNOTSUPP; |
2286 | } |
2287 | } |
2288 | |
2289 | /* Pre-populate the DCB application priority table with the priorities |
2290 | * configured during switch setup, which we read from hardware here. |
2291 | */ |
2292 | static int dsa_user_dcbnl_init(struct net_device *dev) |
2293 | { |
2294 | struct dsa_port *dp = dsa_user_to_port(dev); |
2295 | struct dsa_switch *ds = dp->ds; |
2296 | int port = dp->index; |
2297 | int err; |
2298 | |
2299 | if (ds->ops->port_get_default_prio) { |
2300 | int prio = ds->ops->port_get_default_prio(ds, port); |
2301 | struct dcb_app app = { |
2302 | .selector = IEEE_8021QAZ_APP_SEL_ETHERTYPE, |
2303 | .protocol = 0, |
2304 | .priority = prio, |
2305 | }; |
2306 | |
2307 | if (prio < 0) |
2308 | return prio; |
2309 | |
2310 | err = dcb_ieee_setapp(dev, &app); |
2311 | if (err) |
2312 | return err; |
2313 | } |
2314 | |
2315 | if (ds->ops->port_get_dscp_prio) { |
2316 | int protocol; |
2317 | |
2318 | for (protocol = 0; protocol < 64; protocol++) { |
2319 | struct dcb_app app = { |
2320 | .selector = IEEE_8021QAZ_APP_SEL_DSCP, |
2321 | .protocol = protocol, |
2322 | }; |
2323 | int prio; |
2324 | |
2325 | prio = ds->ops->port_get_dscp_prio(ds, port, protocol); |
2326 | if (prio == -EOPNOTSUPP) |
2327 | continue; |
2328 | if (prio < 0) |
2329 | return prio; |
2330 | |
2331 | app.priority = prio; |
2332 | |
2333 | err = dcb_ieee_setapp(dev, &app); |
2334 | if (err) |
2335 | return err; |
2336 | } |
2337 | } |
2338 | |
2339 | return 0; |
2340 | } |
2341 | |
2342 | static const struct ethtool_ops dsa_user_ethtool_ops = { |
2343 | .get_drvinfo = dsa_user_get_drvinfo, |
2344 | .get_regs_len = dsa_user_get_regs_len, |
2345 | .get_regs = dsa_user_get_regs, |
2346 | .nway_reset = dsa_user_nway_reset, |
2347 | .get_link = ethtool_op_get_link, |
2348 | .get_eeprom_len = dsa_user_get_eeprom_len, |
2349 | .get_eeprom = dsa_user_get_eeprom, |
2350 | .set_eeprom = dsa_user_set_eeprom, |
2351 | .get_strings = dsa_user_get_strings, |
2352 | .get_ethtool_stats = dsa_user_get_ethtool_stats, |
2353 | .get_sset_count = dsa_user_get_sset_count, |
2354 | .get_eth_phy_stats = dsa_user_get_eth_phy_stats, |
2355 | .get_eth_mac_stats = dsa_user_get_eth_mac_stats, |
2356 | .get_eth_ctrl_stats = dsa_user_get_eth_ctrl_stats, |
2357 | .get_rmon_stats = dsa_user_get_rmon_stats, |
2358 | .set_wol = dsa_user_set_wol, |
2359 | .get_wol = dsa_user_get_wol, |
2360 | .set_eee = dsa_user_set_eee, |
2361 | .get_eee = dsa_user_get_eee, |
2362 | .get_link_ksettings = dsa_user_get_link_ksettings, |
2363 | .set_link_ksettings = dsa_user_set_link_ksettings, |
2364 | .get_pause_stats = dsa_user_get_pause_stats, |
2365 | .get_pauseparam = dsa_user_get_pauseparam, |
2366 | .set_pauseparam = dsa_user_set_pauseparam, |
2367 | .get_rxnfc = dsa_user_get_rxnfc, |
2368 | .set_rxnfc = dsa_user_set_rxnfc, |
2369 | .get_ts_info = dsa_user_get_ts_info, |
2370 | .self_test = dsa_user_net_selftest, |
2371 | .get_mm = dsa_user_get_mm, |
2372 | .set_mm = dsa_user_set_mm, |
2373 | .get_mm_stats = dsa_user_get_mm_stats, |
2374 | }; |
2375 | |
2376 | static const struct dcbnl_rtnl_ops __maybe_unused dsa_user_dcbnl_ops = { |
2377 | .ieee_setapp = dsa_user_dcbnl_ieee_setapp, |
2378 | .ieee_delapp = dsa_user_dcbnl_ieee_delapp, |
2379 | }; |
2380 | |
2381 | static void dsa_user_get_stats64(struct net_device *dev, |
2382 | struct rtnl_link_stats64 *s) |
2383 | { |
2384 | struct dsa_port *dp = dsa_user_to_port(dev); |
2385 | struct dsa_switch *ds = dp->ds; |
2386 | |
2387 | if (ds->ops->get_stats64) |
2388 | ds->ops->get_stats64(ds, dp->index, s); |
2389 | else |
2390 | dev_get_tstats64(dev, s); |
2391 | } |
2392 | |
2393 | static int dsa_user_fill_forward_path(struct net_device_path_ctx *ctx, |
2394 | struct net_device_path *path) |
2395 | { |
2396 | struct dsa_port *dp = dsa_user_to_port(dev: ctx->dev); |
2397 | struct net_device *conduit = dsa_port_to_conduit(dp); |
2398 | struct dsa_port *cpu_dp = dp->cpu_dp; |
2399 | |
2400 | path->dev = ctx->dev; |
2401 | path->type = DEV_PATH_DSA; |
2402 | path->dsa.proto = cpu_dp->tag_ops->proto; |
2403 | path->dsa.port = dp->index; |
2404 | ctx->dev = conduit; |
2405 | |
2406 | return 0; |
2407 | } |
2408 | |
2409 | static const struct net_device_ops dsa_user_netdev_ops = { |
2410 | .ndo_open = dsa_user_open, |
2411 | .ndo_stop = dsa_user_close, |
2412 | .ndo_start_xmit = dsa_user_xmit, |
2413 | .ndo_change_rx_flags = dsa_user_change_rx_flags, |
2414 | .ndo_set_rx_mode = dsa_user_set_rx_mode, |
2415 | .ndo_set_mac_address = dsa_user_set_mac_address, |
2416 | .ndo_fdb_dump = dsa_user_fdb_dump, |
2417 | .ndo_eth_ioctl = dsa_user_ioctl, |
2418 | .ndo_get_iflink = dsa_user_get_iflink, |
2419 | #ifdef CONFIG_NET_POLL_CONTROLLER |
2420 | .ndo_netpoll_setup = dsa_user_netpoll_setup, |
2421 | .ndo_netpoll_cleanup = dsa_user_netpoll_cleanup, |
2422 | .ndo_poll_controller = dsa_user_poll_controller, |
2423 | #endif |
2424 | .ndo_setup_tc = dsa_user_setup_tc, |
2425 | .ndo_get_stats64 = dsa_user_get_stats64, |
2426 | .ndo_vlan_rx_add_vid = dsa_user_vlan_rx_add_vid, |
2427 | .ndo_vlan_rx_kill_vid = dsa_user_vlan_rx_kill_vid, |
2428 | .ndo_change_mtu = dsa_user_change_mtu, |
2429 | .ndo_fill_forward_path = dsa_user_fill_forward_path, |
2430 | }; |
2431 | |
2432 | static const struct device_type dsa_type = { |
2433 | .name = "dsa" , |
2434 | }; |
2435 | |
2436 | void dsa_port_phylink_mac_change(struct dsa_switch *ds, int port, bool up) |
2437 | { |
2438 | const struct dsa_port *dp = dsa_to_port(ds, p: port); |
2439 | |
2440 | if (dp->pl) |
2441 | phylink_mac_change(dp->pl, up); |
2442 | } |
2443 | EXPORT_SYMBOL_GPL(dsa_port_phylink_mac_change); |
2444 | |
2445 | static void dsa_user_phylink_fixed_state(struct phylink_config *config, |
2446 | struct phylink_link_state *state) |
2447 | { |
2448 | struct dsa_port *dp = container_of(config, struct dsa_port, pl_config); |
2449 | struct dsa_switch *ds = dp->ds; |
2450 | |
2451 | /* No need to check that this operation is valid, the callback would |
2452 | * not be called if it was not. |
2453 | */ |
2454 | ds->ops->phylink_fixed_state(ds, dp->index, state); |
2455 | } |
2456 | |
2457 | /* user device setup *******************************************************/ |
2458 | static int dsa_user_phy_connect(struct net_device *user_dev, int addr, |
2459 | u32 flags) |
2460 | { |
2461 | struct dsa_port *dp = dsa_user_to_port(dev: user_dev); |
2462 | struct dsa_switch *ds = dp->ds; |
2463 | |
2464 | user_dev->phydev = mdiobus_get_phy(bus: ds->user_mii_bus, addr); |
2465 | if (!user_dev->phydev) { |
2466 | netdev_err(dev: user_dev, format: "no phy at %d\n" , addr); |
2467 | return -ENODEV; |
2468 | } |
2469 | |
2470 | user_dev->phydev->dev_flags |= flags; |
2471 | |
2472 | return phylink_connect_phy(dp->pl, user_dev->phydev); |
2473 | } |
2474 | |
2475 | static int dsa_user_phy_setup(struct net_device *user_dev) |
2476 | { |
2477 | struct dsa_port *dp = dsa_user_to_port(dev: user_dev); |
2478 | struct device_node *port_dn = dp->dn; |
2479 | struct dsa_switch *ds = dp->ds; |
2480 | u32 phy_flags = 0; |
2481 | int ret; |
2482 | |
2483 | dp->pl_config.dev = &user_dev->dev; |
2484 | dp->pl_config.type = PHYLINK_NETDEV; |
2485 | |
2486 | /* The get_fixed_state callback takes precedence over polling the |
2487 | * link GPIO in PHYLINK (see phylink_get_fixed_state). Only set |
2488 | * this if the switch provides such a callback. |
2489 | */ |
2490 | if (ds->ops->phylink_fixed_state) { |
2491 | dp->pl_config.get_fixed_state = dsa_user_phylink_fixed_state; |
2492 | dp->pl_config.poll_fixed_state = true; |
2493 | } |
2494 | |
2495 | ret = dsa_port_phylink_create(dp); |
2496 | if (ret) |
2497 | return ret; |
2498 | |
2499 | if (ds->ops->get_phy_flags) |
2500 | phy_flags = ds->ops->get_phy_flags(ds, dp->index); |
2501 | |
2502 | ret = phylink_of_phy_connect(dp->pl, port_dn, flags: phy_flags); |
2503 | if (ret == -ENODEV && ds->user_mii_bus) { |
2504 | /* We could not connect to a designated PHY or SFP, so try to |
2505 | * use the switch internal MDIO bus instead |
2506 | */ |
2507 | ret = dsa_user_phy_connect(user_dev, addr: dp->index, flags: phy_flags); |
2508 | } |
2509 | if (ret) { |
2510 | netdev_err(dev: user_dev, format: "failed to connect to PHY: %pe\n" , |
2511 | ERR_PTR(error: ret)); |
2512 | dsa_port_phylink_destroy(dp); |
2513 | } |
2514 | |
2515 | return ret; |
2516 | } |
2517 | |
2518 | void dsa_user_setup_tagger(struct net_device *user) |
2519 | { |
2520 | struct dsa_port *dp = dsa_user_to_port(dev: user); |
2521 | struct net_device *conduit = dsa_port_to_conduit(dp); |
2522 | struct dsa_user_priv *p = netdev_priv(dev: user); |
2523 | const struct dsa_port *cpu_dp = dp->cpu_dp; |
2524 | const struct dsa_switch *ds = dp->ds; |
2525 | |
2526 | user->needed_headroom = cpu_dp->tag_ops->needed_headroom; |
2527 | user->needed_tailroom = cpu_dp->tag_ops->needed_tailroom; |
2528 | /* Try to save one extra realloc later in the TX path (in the conduit) |
2529 | * by also inheriting the conduit's needed headroom and tailroom. |
2530 | * The 8021q driver also does this. |
2531 | */ |
2532 | user->needed_headroom += conduit->needed_headroom; |
2533 | user->needed_tailroom += conduit->needed_tailroom; |
2534 | |
2535 | p->xmit = cpu_dp->tag_ops->xmit; |
2536 | |
2537 | user->features = conduit->vlan_features | NETIF_F_HW_TC; |
2538 | user->hw_features |= NETIF_F_HW_TC; |
2539 | user->features |= NETIF_F_LLTX; |
2540 | if (user->needed_tailroom) |
2541 | user->features &= ~(NETIF_F_SG | NETIF_F_FRAGLIST); |
2542 | if (ds->needs_standalone_vlan_filtering) |
2543 | user->features |= NETIF_F_HW_VLAN_CTAG_FILTER; |
2544 | } |
2545 | |
2546 | int dsa_user_suspend(struct net_device *user_dev) |
2547 | { |
2548 | struct dsa_port *dp = dsa_user_to_port(dev: user_dev); |
2549 | |
2550 | if (!netif_running(dev: user_dev)) |
2551 | return 0; |
2552 | |
2553 | netif_device_detach(dev: user_dev); |
2554 | |
2555 | rtnl_lock(); |
2556 | phylink_stop(dp->pl); |
2557 | rtnl_unlock(); |
2558 | |
2559 | return 0; |
2560 | } |
2561 | |
2562 | int dsa_user_resume(struct net_device *user_dev) |
2563 | { |
2564 | struct dsa_port *dp = dsa_user_to_port(dev: user_dev); |
2565 | |
2566 | if (!netif_running(dev: user_dev)) |
2567 | return 0; |
2568 | |
2569 | netif_device_attach(dev: user_dev); |
2570 | |
2571 | rtnl_lock(); |
2572 | phylink_start(dp->pl); |
2573 | rtnl_unlock(); |
2574 | |
2575 | return 0; |
2576 | } |
2577 | |
2578 | int dsa_user_create(struct dsa_port *port) |
2579 | { |
2580 | struct net_device *conduit = dsa_port_to_conduit(dp: port); |
2581 | struct dsa_switch *ds = port->ds; |
2582 | struct net_device *user_dev; |
2583 | struct dsa_user_priv *p; |
2584 | const char *name; |
2585 | int assign_type; |
2586 | int ret; |
2587 | |
2588 | if (!ds->num_tx_queues) |
2589 | ds->num_tx_queues = 1; |
2590 | |
2591 | if (port->name) { |
2592 | name = port->name; |
2593 | assign_type = NET_NAME_PREDICTABLE; |
2594 | } else { |
2595 | name = "eth%d" ; |
2596 | assign_type = NET_NAME_ENUM; |
2597 | } |
2598 | |
2599 | user_dev = alloc_netdev_mqs(sizeof_priv: sizeof(struct dsa_user_priv), name, |
2600 | name_assign_type: assign_type, setup: ether_setup, |
2601 | txqs: ds->num_tx_queues, rxqs: 1); |
2602 | if (user_dev == NULL) |
2603 | return -ENOMEM; |
2604 | |
2605 | user_dev->rtnl_link_ops = &dsa_link_ops; |
2606 | user_dev->ethtool_ops = &dsa_user_ethtool_ops; |
2607 | #if IS_ENABLED(CONFIG_DCB) |
2608 | user_dev->dcbnl_ops = &dsa_user_dcbnl_ops; |
2609 | #endif |
2610 | if (!is_zero_ether_addr(addr: port->mac)) |
2611 | eth_hw_addr_set(dev: user_dev, addr: port->mac); |
2612 | else |
2613 | eth_hw_addr_inherit(dst: user_dev, src: conduit); |
2614 | user_dev->priv_flags |= IFF_NO_QUEUE; |
2615 | if (dsa_switch_supports_uc_filtering(ds)) |
2616 | user_dev->priv_flags |= IFF_UNICAST_FLT; |
2617 | user_dev->netdev_ops = &dsa_user_netdev_ops; |
2618 | if (ds->ops->port_max_mtu) |
2619 | user_dev->max_mtu = ds->ops->port_max_mtu(ds, port->index); |
2620 | SET_NETDEV_DEVTYPE(user_dev, &dsa_type); |
2621 | |
2622 | SET_NETDEV_DEV(user_dev, port->ds->dev); |
2623 | SET_NETDEV_DEVLINK_PORT(user_dev, &port->devlink_port); |
2624 | user_dev->dev.of_node = port->dn; |
2625 | user_dev->vlan_features = conduit->vlan_features; |
2626 | |
2627 | p = netdev_priv(dev: user_dev); |
2628 | user_dev->pcpu_stat_type = NETDEV_PCPU_STAT_TSTATS; |
2629 | |
2630 | ret = gro_cells_init(gcells: &p->gcells, dev: user_dev); |
2631 | if (ret) |
2632 | goto out_free; |
2633 | |
2634 | p->dp = port; |
2635 | INIT_LIST_HEAD(list: &p->mall_tc_list); |
2636 | port->user = user_dev; |
2637 | dsa_user_setup_tagger(user: user_dev); |
2638 | |
2639 | netif_carrier_off(dev: user_dev); |
2640 | |
2641 | ret = dsa_user_phy_setup(user_dev); |
2642 | if (ret) { |
2643 | netdev_err(dev: user_dev, |
2644 | format: "error %d setting up PHY for tree %d, switch %d, port %d\n" , |
2645 | ret, ds->dst->index, ds->index, port->index); |
2646 | goto out_gcells; |
2647 | } |
2648 | |
2649 | rtnl_lock(); |
2650 | |
2651 | ret = dsa_user_change_mtu(dev: user_dev, ETH_DATA_LEN); |
2652 | if (ret && ret != -EOPNOTSUPP) |
2653 | dev_warn(ds->dev, "nonfatal error %d setting MTU to %d on port %d\n" , |
2654 | ret, ETH_DATA_LEN, port->index); |
2655 | |
2656 | ret = register_netdevice(dev: user_dev); |
2657 | if (ret) { |
2658 | netdev_err(dev: conduit, format: "error %d registering interface %s\n" , |
2659 | ret, user_dev->name); |
2660 | rtnl_unlock(); |
2661 | goto out_phy; |
2662 | } |
2663 | |
2664 | if (IS_ENABLED(CONFIG_DCB)) { |
2665 | ret = dsa_user_dcbnl_init(dev: user_dev); |
2666 | if (ret) { |
2667 | netdev_err(dev: user_dev, |
2668 | format: "failed to initialize DCB: %pe\n" , |
2669 | ERR_PTR(error: ret)); |
2670 | rtnl_unlock(); |
2671 | goto out_unregister; |
2672 | } |
2673 | } |
2674 | |
2675 | ret = netdev_upper_dev_link(dev: conduit, upper_dev: user_dev, NULL); |
2676 | |
2677 | rtnl_unlock(); |
2678 | |
2679 | if (ret) |
2680 | goto out_unregister; |
2681 | |
2682 | return 0; |
2683 | |
2684 | out_unregister: |
2685 | unregister_netdev(dev: user_dev); |
2686 | out_phy: |
2687 | rtnl_lock(); |
2688 | phylink_disconnect_phy(p->dp->pl); |
2689 | rtnl_unlock(); |
2690 | dsa_port_phylink_destroy(dp: p->dp); |
2691 | out_gcells: |
2692 | gro_cells_destroy(gcells: &p->gcells); |
2693 | out_free: |
2694 | free_netdev(dev: user_dev); |
2695 | port->user = NULL; |
2696 | return ret; |
2697 | } |
2698 | |
2699 | void dsa_user_destroy(struct net_device *user_dev) |
2700 | { |
2701 | struct net_device *conduit = dsa_user_to_conduit(dev: user_dev); |
2702 | struct dsa_port *dp = dsa_user_to_port(dev: user_dev); |
2703 | struct dsa_user_priv *p = netdev_priv(dev: user_dev); |
2704 | |
2705 | netif_carrier_off(dev: user_dev); |
2706 | rtnl_lock(); |
2707 | netdev_upper_dev_unlink(dev: conduit, upper_dev: user_dev); |
2708 | unregister_netdevice(dev: user_dev); |
2709 | phylink_disconnect_phy(dp->pl); |
2710 | rtnl_unlock(); |
2711 | |
2712 | dsa_port_phylink_destroy(dp); |
2713 | gro_cells_destroy(gcells: &p->gcells); |
2714 | free_netdev(dev: user_dev); |
2715 | } |
2716 | |
2717 | int dsa_user_change_conduit(struct net_device *dev, struct net_device *conduit, |
2718 | struct netlink_ext_ack *extack) |
2719 | { |
2720 | struct net_device *old_conduit = dsa_user_to_conduit(dev); |
2721 | struct dsa_port *dp = dsa_user_to_port(dev); |
2722 | struct dsa_switch *ds = dp->ds; |
2723 | struct net_device *upper; |
2724 | struct list_head *iter; |
2725 | int err; |
2726 | |
2727 | if (conduit == old_conduit) |
2728 | return 0; |
2729 | |
2730 | if (!ds->ops->port_change_conduit) { |
2731 | NL_SET_ERR_MSG_MOD(extack, |
2732 | "Driver does not support changing DSA conduit" ); |
2733 | return -EOPNOTSUPP; |
2734 | } |
2735 | |
2736 | if (!netdev_uses_dsa(dev: conduit)) { |
2737 | NL_SET_ERR_MSG_MOD(extack, |
2738 | "Interface not eligible as DSA conduit" ); |
2739 | return -EOPNOTSUPP; |
2740 | } |
2741 | |
2742 | netdev_for_each_upper_dev_rcu(conduit, upper, iter) { |
2743 | if (dsa_user_dev_check(dev: upper)) |
2744 | continue; |
2745 | if (netif_is_bridge_master(dev: upper)) |
2746 | continue; |
2747 | NL_SET_ERR_MSG_MOD(extack, "Cannot join conduit with unknown uppers" ); |
2748 | return -EOPNOTSUPP; |
2749 | } |
2750 | |
2751 | /* Since we allow live-changing the DSA conduit, plus we auto-open the |
2752 | * DSA conduit when the user port opens => we need to ensure that the |
2753 | * new DSA conduit is open too. |
2754 | */ |
2755 | if (dev->flags & IFF_UP) { |
2756 | err = dev_open(dev: conduit, extack); |
2757 | if (err) |
2758 | return err; |
2759 | } |
2760 | |
2761 | netdev_upper_dev_unlink(dev: old_conduit, upper_dev: dev); |
2762 | |
2763 | err = netdev_upper_dev_link(dev: conduit, upper_dev: dev, extack); |
2764 | if (err) |
2765 | goto out_revert_old_conduit_unlink; |
2766 | |
2767 | err = dsa_port_change_conduit(dp, conduit, extack); |
2768 | if (err) |
2769 | goto out_revert_conduit_link; |
2770 | |
2771 | /* Update the MTU of the new CPU port through cross-chip notifiers */ |
2772 | err = dsa_user_change_mtu(dev, new_mtu: dev->mtu); |
2773 | if (err && err != -EOPNOTSUPP) { |
2774 | netdev_warn(dev, |
2775 | format: "nonfatal error updating MTU with new conduit: %pe\n" , |
2776 | ERR_PTR(error: err)); |
2777 | } |
2778 | |
2779 | /* If the port doesn't have its own MAC address and relies on the DSA |
2780 | * conduit's one, inherit it again from the new DSA conduit. |
2781 | */ |
2782 | if (is_zero_ether_addr(addr: dp->mac)) |
2783 | eth_hw_addr_inherit(dst: dev, src: conduit); |
2784 | |
2785 | return 0; |
2786 | |
2787 | out_revert_conduit_link: |
2788 | netdev_upper_dev_unlink(dev: conduit, upper_dev: dev); |
2789 | out_revert_old_conduit_unlink: |
2790 | netdev_upper_dev_link(dev: old_conduit, upper_dev: dev, NULL); |
2791 | return err; |
2792 | } |
2793 | |
2794 | bool dsa_user_dev_check(const struct net_device *dev) |
2795 | { |
2796 | return dev->netdev_ops == &dsa_user_netdev_ops; |
2797 | } |
2798 | EXPORT_SYMBOL_GPL(dsa_user_dev_check); |
2799 | |
2800 | static int dsa_user_changeupper(struct net_device *dev, |
2801 | struct netdev_notifier_changeupper_info *info) |
2802 | { |
2803 | struct netlink_ext_ack *extack; |
2804 | int err = NOTIFY_DONE; |
2805 | struct dsa_port *dp; |
2806 | |
2807 | if (!dsa_user_dev_check(dev)) |
2808 | return err; |
2809 | |
2810 | dp = dsa_user_to_port(dev); |
2811 | extack = netdev_notifier_info_to_extack(info: &info->info); |
2812 | |
2813 | if (netif_is_bridge_master(dev: info->upper_dev)) { |
2814 | if (info->linking) { |
2815 | err = dsa_port_bridge_join(dp, br: info->upper_dev, extack); |
2816 | if (!err) |
2817 | dsa_bridge_mtu_normalization(dp); |
2818 | if (err == -EOPNOTSUPP) { |
2819 | NL_SET_ERR_MSG_WEAK_MOD(extack, |
2820 | "Offloading not supported" ); |
2821 | err = 0; |
2822 | } |
2823 | err = notifier_from_errno(err); |
2824 | } else { |
2825 | dsa_port_bridge_leave(dp, br: info->upper_dev); |
2826 | err = NOTIFY_OK; |
2827 | } |
2828 | } else if (netif_is_lag_master(dev: info->upper_dev)) { |
2829 | if (info->linking) { |
2830 | err = dsa_port_lag_join(dp, lag_dev: info->upper_dev, |
2831 | uinfo: info->upper_info, extack); |
2832 | if (err == -EOPNOTSUPP) { |
2833 | NL_SET_ERR_MSG_WEAK_MOD(extack, |
2834 | "Offloading not supported" ); |
2835 | err = 0; |
2836 | } |
2837 | err = notifier_from_errno(err); |
2838 | } else { |
2839 | dsa_port_lag_leave(dp, lag_dev: info->upper_dev); |
2840 | err = NOTIFY_OK; |
2841 | } |
2842 | } else if (is_hsr_master(dev: info->upper_dev)) { |
2843 | if (info->linking) { |
2844 | err = dsa_port_hsr_join(dp, hsr: info->upper_dev, extack); |
2845 | if (err == -EOPNOTSUPP) { |
2846 | NL_SET_ERR_MSG_WEAK_MOD(extack, |
2847 | "Offloading not supported" ); |
2848 | err = 0; |
2849 | } |
2850 | err = notifier_from_errno(err); |
2851 | } else { |
2852 | dsa_port_hsr_leave(dp, hsr: info->upper_dev); |
2853 | err = NOTIFY_OK; |
2854 | } |
2855 | } |
2856 | |
2857 | return err; |
2858 | } |
2859 | |
2860 | static int dsa_user_prechangeupper(struct net_device *dev, |
2861 | struct netdev_notifier_changeupper_info *info) |
2862 | { |
2863 | struct dsa_port *dp; |
2864 | |
2865 | if (!dsa_user_dev_check(dev)) |
2866 | return NOTIFY_DONE; |
2867 | |
2868 | dp = dsa_user_to_port(dev); |
2869 | |
2870 | if (netif_is_bridge_master(dev: info->upper_dev) && !info->linking) |
2871 | dsa_port_pre_bridge_leave(dp, br: info->upper_dev); |
2872 | else if (netif_is_lag_master(dev: info->upper_dev) && !info->linking) |
2873 | dsa_port_pre_lag_leave(dp, lag_dev: info->upper_dev); |
2874 | /* dsa_port_pre_hsr_leave is not yet necessary since hsr devices cannot |
2875 | * meaningfully placed under a bridge yet |
2876 | */ |
2877 | |
2878 | return NOTIFY_DONE; |
2879 | } |
2880 | |
2881 | static int |
2882 | dsa_user_lag_changeupper(struct net_device *dev, |
2883 | struct netdev_notifier_changeupper_info *info) |
2884 | { |
2885 | struct net_device *lower; |
2886 | struct list_head *iter; |
2887 | int err = NOTIFY_DONE; |
2888 | struct dsa_port *dp; |
2889 | |
2890 | if (!netif_is_lag_master(dev)) |
2891 | return err; |
2892 | |
2893 | netdev_for_each_lower_dev(dev, lower, iter) { |
2894 | if (!dsa_user_dev_check(lower)) |
2895 | continue; |
2896 | |
2897 | dp = dsa_user_to_port(dev: lower); |
2898 | if (!dp->lag) |
2899 | /* Software LAG */ |
2900 | continue; |
2901 | |
2902 | err = dsa_user_changeupper(dev: lower, info); |
2903 | if (notifier_to_errno(ret: err)) |
2904 | break; |
2905 | } |
2906 | |
2907 | return err; |
2908 | } |
2909 | |
2910 | /* Same as dsa_user_lag_changeupper() except that it calls |
2911 | * dsa_user_prechangeupper() |
2912 | */ |
2913 | static int |
2914 | dsa_user_lag_prechangeupper(struct net_device *dev, |
2915 | struct netdev_notifier_changeupper_info *info) |
2916 | { |
2917 | struct net_device *lower; |
2918 | struct list_head *iter; |
2919 | int err = NOTIFY_DONE; |
2920 | struct dsa_port *dp; |
2921 | |
2922 | if (!netif_is_lag_master(dev)) |
2923 | return err; |
2924 | |
2925 | netdev_for_each_lower_dev(dev, lower, iter) { |
2926 | if (!dsa_user_dev_check(lower)) |
2927 | continue; |
2928 | |
2929 | dp = dsa_user_to_port(dev: lower); |
2930 | if (!dp->lag) |
2931 | /* Software LAG */ |
2932 | continue; |
2933 | |
2934 | err = dsa_user_prechangeupper(dev: lower, info); |
2935 | if (notifier_to_errno(ret: err)) |
2936 | break; |
2937 | } |
2938 | |
2939 | return err; |
2940 | } |
2941 | |
2942 | static int |
2943 | dsa_prevent_bridging_8021q_upper(struct net_device *dev, |
2944 | struct netdev_notifier_changeupper_info *info) |
2945 | { |
2946 | struct netlink_ext_ack *ext_ack; |
2947 | struct net_device *user, *br; |
2948 | struct dsa_port *dp; |
2949 | |
2950 | ext_ack = netdev_notifier_info_to_extack(info: &info->info); |
2951 | |
2952 | if (!is_vlan_dev(dev)) |
2953 | return NOTIFY_DONE; |
2954 | |
2955 | user = vlan_dev_real_dev(dev); |
2956 | if (!dsa_user_dev_check(user)) |
2957 | return NOTIFY_DONE; |
2958 | |
2959 | dp = dsa_user_to_port(dev: user); |
2960 | br = dsa_port_bridge_dev_get(dp); |
2961 | if (!br) |
2962 | return NOTIFY_DONE; |
2963 | |
2964 | /* Deny enslaving a VLAN device into a VLAN-aware bridge */ |
2965 | if (br_vlan_enabled(dev: br) && |
2966 | netif_is_bridge_master(dev: info->upper_dev) && info->linking) { |
2967 | NL_SET_ERR_MSG_MOD(ext_ack, |
2968 | "Cannot make VLAN device join VLAN-aware bridge" ); |
2969 | return notifier_from_errno(err: -EINVAL); |
2970 | } |
2971 | |
2972 | return NOTIFY_DONE; |
2973 | } |
2974 | |
2975 | static int |
2976 | dsa_user_check_8021q_upper(struct net_device *dev, |
2977 | struct netdev_notifier_changeupper_info *info) |
2978 | { |
2979 | struct dsa_port *dp = dsa_user_to_port(dev); |
2980 | struct net_device *br = dsa_port_bridge_dev_get(dp); |
2981 | struct bridge_vlan_info br_info; |
2982 | struct netlink_ext_ack *extack; |
2983 | int err = NOTIFY_DONE; |
2984 | u16 vid; |
2985 | |
2986 | if (!br || !br_vlan_enabled(dev: br)) |
2987 | return NOTIFY_DONE; |
2988 | |
2989 | extack = netdev_notifier_info_to_extack(info: &info->info); |
2990 | vid = vlan_dev_vlan_id(dev: info->upper_dev); |
2991 | |
2992 | /* br_vlan_get_info() returns -EINVAL or -ENOENT if the |
2993 | * device, respectively the VID is not found, returning |
2994 | * 0 means success, which is a failure for us here. |
2995 | */ |
2996 | err = br_vlan_get_info(dev: br, vid, p_vinfo: &br_info); |
2997 | if (err == 0) { |
2998 | NL_SET_ERR_MSG_MOD(extack, |
2999 | "This VLAN is already configured by the bridge" ); |
3000 | return notifier_from_errno(err: -EBUSY); |
3001 | } |
3002 | |
3003 | return NOTIFY_DONE; |
3004 | } |
3005 | |
3006 | static int |
3007 | dsa_user_prechangeupper_sanity_check(struct net_device *dev, |
3008 | struct netdev_notifier_changeupper_info *info) |
3009 | { |
3010 | struct dsa_switch *ds; |
3011 | struct dsa_port *dp; |
3012 | int err; |
3013 | |
3014 | if (!dsa_user_dev_check(dev)) |
3015 | return dsa_prevent_bridging_8021q_upper(dev, info); |
3016 | |
3017 | dp = dsa_user_to_port(dev); |
3018 | ds = dp->ds; |
3019 | |
3020 | if (ds->ops->port_prechangeupper) { |
3021 | err = ds->ops->port_prechangeupper(ds, dp->index, info); |
3022 | if (err) |
3023 | return notifier_from_errno(err); |
3024 | } |
3025 | |
3026 | if (is_vlan_dev(dev: info->upper_dev)) |
3027 | return dsa_user_check_8021q_upper(dev, info); |
3028 | |
3029 | return NOTIFY_DONE; |
3030 | } |
3031 | |
3032 | /* To be eligible as a DSA conduit, a LAG must have all lower interfaces be |
3033 | * eligible DSA conduits. Additionally, all LAG slaves must be DSA conduits of |
3034 | * switches in the same switch tree. |
3035 | */ |
3036 | static int dsa_lag_conduit_validate(struct net_device *lag_dev, |
3037 | struct netlink_ext_ack *extack) |
3038 | { |
3039 | struct net_device *lower1, *lower2; |
3040 | struct list_head *iter1, *iter2; |
3041 | |
3042 | netdev_for_each_lower_dev(lag_dev, lower1, iter1) { |
3043 | netdev_for_each_lower_dev(lag_dev, lower2, iter2) { |
3044 | if (!netdev_uses_dsa(dev: lower1) || |
3045 | !netdev_uses_dsa(dev: lower2)) { |
3046 | NL_SET_ERR_MSG_MOD(extack, |
3047 | "All LAG ports must be eligible as DSA conduits" ); |
3048 | return notifier_from_errno(err: -EINVAL); |
3049 | } |
3050 | |
3051 | if (lower1 == lower2) |
3052 | continue; |
3053 | |
3054 | if (!dsa_port_tree_same(a: lower1->dsa_ptr, |
3055 | b: lower2->dsa_ptr)) { |
3056 | NL_SET_ERR_MSG_MOD(extack, |
3057 | "LAG contains DSA conduits of disjoint switch trees" ); |
3058 | return notifier_from_errno(err: -EINVAL); |
3059 | } |
3060 | } |
3061 | } |
3062 | |
3063 | return NOTIFY_DONE; |
3064 | } |
3065 | |
3066 | static int |
3067 | dsa_conduit_prechangeupper_sanity_check(struct net_device *conduit, |
3068 | struct netdev_notifier_changeupper_info *info) |
3069 | { |
3070 | struct netlink_ext_ack *extack = netdev_notifier_info_to_extack(info: &info->info); |
3071 | |
3072 | if (!netdev_uses_dsa(dev: conduit)) |
3073 | return NOTIFY_DONE; |
3074 | |
3075 | if (!info->linking) |
3076 | return NOTIFY_DONE; |
3077 | |
3078 | /* Allow DSA switch uppers */ |
3079 | if (dsa_user_dev_check(info->upper_dev)) |
3080 | return NOTIFY_DONE; |
3081 | |
3082 | /* Allow bridge uppers of DSA conduits, subject to further |
3083 | * restrictions in dsa_bridge_prechangelower_sanity_check() |
3084 | */ |
3085 | if (netif_is_bridge_master(dev: info->upper_dev)) |
3086 | return NOTIFY_DONE; |
3087 | |
3088 | /* Allow LAG uppers, subject to further restrictions in |
3089 | * dsa_lag_conduit_prechangelower_sanity_check() |
3090 | */ |
3091 | if (netif_is_lag_master(dev: info->upper_dev)) |
3092 | return dsa_lag_conduit_validate(lag_dev: info->upper_dev, extack); |
3093 | |
3094 | NL_SET_ERR_MSG_MOD(extack, |
3095 | "DSA conduit cannot join unknown upper interfaces" ); |
3096 | return notifier_from_errno(err: -EBUSY); |
3097 | } |
3098 | |
3099 | static int |
3100 | dsa_lag_conduit_prechangelower_sanity_check(struct net_device *dev, |
3101 | struct netdev_notifier_changeupper_info *info) |
3102 | { |
3103 | struct netlink_ext_ack *extack = netdev_notifier_info_to_extack(info: &info->info); |
3104 | struct net_device *lag_dev = info->upper_dev; |
3105 | struct net_device *lower; |
3106 | struct list_head *iter; |
3107 | |
3108 | if (!netdev_uses_dsa(dev: lag_dev) || !netif_is_lag_master(dev: lag_dev)) |
3109 | return NOTIFY_DONE; |
3110 | |
3111 | if (!info->linking) |
3112 | return NOTIFY_DONE; |
3113 | |
3114 | if (!netdev_uses_dsa(dev)) { |
3115 | NL_SET_ERR_MSG(extack, |
3116 | "Only DSA conduits can join a LAG DSA conduit" ); |
3117 | return notifier_from_errno(err: -EINVAL); |
3118 | } |
3119 | |
3120 | netdev_for_each_lower_dev(lag_dev, lower, iter) { |
3121 | if (!dsa_port_tree_same(a: dev->dsa_ptr, b: lower->dsa_ptr)) { |
3122 | NL_SET_ERR_MSG(extack, |
3123 | "Interface is DSA conduit for a different switch tree than this LAG" ); |
3124 | return notifier_from_errno(err: -EINVAL); |
3125 | } |
3126 | |
3127 | break; |
3128 | } |
3129 | |
3130 | return NOTIFY_DONE; |
3131 | } |
3132 | |
3133 | /* Don't allow bridging of DSA conduits, since the bridge layer rx_handler |
3134 | * prevents the DSA fake ethertype handler to be invoked, so we don't get the |
3135 | * chance to strip off and parse the DSA switch tag protocol header (the bridge |
3136 | * layer just returns RX_HANDLER_CONSUMED, stopping RX processing for these |
3137 | * frames). |
3138 | * The only case where that would not be an issue is when bridging can already |
3139 | * be offloaded, such as when the DSA conduit is itself a DSA or plain switchdev |
3140 | * port, and is bridged only with other ports from the same hardware device. |
3141 | */ |
3142 | static int |
3143 | dsa_bridge_prechangelower_sanity_check(struct net_device *new_lower, |
3144 | struct netdev_notifier_changeupper_info *info) |
3145 | { |
3146 | struct net_device *br = info->upper_dev; |
3147 | struct netlink_ext_ack *extack; |
3148 | struct net_device *lower; |
3149 | struct list_head *iter; |
3150 | |
3151 | if (!netif_is_bridge_master(dev: br)) |
3152 | return NOTIFY_DONE; |
3153 | |
3154 | if (!info->linking) |
3155 | return NOTIFY_DONE; |
3156 | |
3157 | extack = netdev_notifier_info_to_extack(info: &info->info); |
3158 | |
3159 | netdev_for_each_lower_dev(br, lower, iter) { |
3160 | if (!netdev_uses_dsa(dev: new_lower) && !netdev_uses_dsa(dev: lower)) |
3161 | continue; |
3162 | |
3163 | if (!netdev_port_same_parent_id(a: lower, b: new_lower)) { |
3164 | NL_SET_ERR_MSG(extack, |
3165 | "Cannot do software bridging with a DSA conduit" ); |
3166 | return notifier_from_errno(err: -EINVAL); |
3167 | } |
3168 | } |
3169 | |
3170 | return NOTIFY_DONE; |
3171 | } |
3172 | |
3173 | static void dsa_tree_migrate_ports_from_lag_conduit(struct dsa_switch_tree *dst, |
3174 | struct net_device *lag_dev) |
3175 | { |
3176 | struct net_device *new_conduit = dsa_tree_find_first_conduit(dst); |
3177 | struct dsa_port *dp; |
3178 | int err; |
3179 | |
3180 | dsa_tree_for_each_user_port(dp, dst) { |
3181 | if (dsa_port_to_conduit(dp) != lag_dev) |
3182 | continue; |
3183 | |
3184 | err = dsa_user_change_conduit(dev: dp->user, conduit: new_conduit, NULL); |
3185 | if (err) { |
3186 | netdev_err(dev: dp->user, |
3187 | format: "failed to restore conduit to %s: %pe\n" , |
3188 | new_conduit->name, ERR_PTR(error: err)); |
3189 | } |
3190 | } |
3191 | } |
3192 | |
3193 | static int dsa_conduit_lag_join(struct net_device *conduit, |
3194 | struct net_device *lag_dev, |
3195 | struct netdev_lag_upper_info *uinfo, |
3196 | struct netlink_ext_ack *extack) |
3197 | { |
3198 | struct dsa_port *cpu_dp = conduit->dsa_ptr; |
3199 | struct dsa_switch_tree *dst = cpu_dp->dst; |
3200 | struct dsa_port *dp; |
3201 | int err; |
3202 | |
3203 | err = dsa_conduit_lag_setup(lag_dev, cpu_dp, uinfo, extack); |
3204 | if (err) |
3205 | return err; |
3206 | |
3207 | dsa_tree_for_each_user_port(dp, dst) { |
3208 | if (dsa_port_to_conduit(dp) != conduit) |
3209 | continue; |
3210 | |
3211 | err = dsa_user_change_conduit(dev: dp->user, conduit: lag_dev, extack); |
3212 | if (err) |
3213 | goto restore; |
3214 | } |
3215 | |
3216 | return 0; |
3217 | |
3218 | restore: |
3219 | dsa_tree_for_each_user_port_continue_reverse(dp, dst) { |
3220 | if (dsa_port_to_conduit(dp) != lag_dev) |
3221 | continue; |
3222 | |
3223 | err = dsa_user_change_conduit(dev: dp->user, conduit, NULL); |
3224 | if (err) { |
3225 | netdev_err(dev: dp->user, |
3226 | format: "failed to restore conduit to %s: %pe\n" , |
3227 | conduit->name, ERR_PTR(error: err)); |
3228 | } |
3229 | } |
3230 | |
3231 | dsa_conduit_lag_teardown(lag_dev, cpu_dp: conduit->dsa_ptr); |
3232 | |
3233 | return err; |
3234 | } |
3235 | |
3236 | static void dsa_conduit_lag_leave(struct net_device *conduit, |
3237 | struct net_device *lag_dev) |
3238 | { |
3239 | struct dsa_port *dp, *cpu_dp = lag_dev->dsa_ptr; |
3240 | struct dsa_switch_tree *dst = cpu_dp->dst; |
3241 | struct dsa_port *new_cpu_dp = NULL; |
3242 | struct net_device *lower; |
3243 | struct list_head *iter; |
3244 | |
3245 | netdev_for_each_lower_dev(lag_dev, lower, iter) { |
3246 | if (netdev_uses_dsa(dev: lower)) { |
3247 | new_cpu_dp = lower->dsa_ptr; |
3248 | break; |
3249 | } |
3250 | } |
3251 | |
3252 | if (new_cpu_dp) { |
3253 | /* Update the CPU port of the user ports still under the LAG |
3254 | * so that dsa_port_to_conduit() continues to work properly |
3255 | */ |
3256 | dsa_tree_for_each_user_port(dp, dst) |
3257 | if (dsa_port_to_conduit(dp) == lag_dev) |
3258 | dp->cpu_dp = new_cpu_dp; |
3259 | |
3260 | /* Update the index of the virtual CPU port to match the lowest |
3261 | * physical CPU port |
3262 | */ |
3263 | lag_dev->dsa_ptr = new_cpu_dp; |
3264 | wmb(); |
3265 | } else { |
3266 | /* If the LAG DSA conduit has no ports left, migrate back all |
3267 | * user ports to the first physical CPU port |
3268 | */ |
3269 | dsa_tree_migrate_ports_from_lag_conduit(dst, lag_dev); |
3270 | } |
3271 | |
3272 | /* This DSA conduit has left its LAG in any case, so let |
3273 | * the CPU port leave the hardware LAG as well |
3274 | */ |
3275 | dsa_conduit_lag_teardown(lag_dev, cpu_dp: conduit->dsa_ptr); |
3276 | } |
3277 | |
3278 | static int dsa_conduit_changeupper(struct net_device *dev, |
3279 | struct netdev_notifier_changeupper_info *info) |
3280 | { |
3281 | struct netlink_ext_ack *extack; |
3282 | int err = NOTIFY_DONE; |
3283 | |
3284 | if (!netdev_uses_dsa(dev)) |
3285 | return err; |
3286 | |
3287 | extack = netdev_notifier_info_to_extack(info: &info->info); |
3288 | |
3289 | if (netif_is_lag_master(dev: info->upper_dev)) { |
3290 | if (info->linking) { |
3291 | err = dsa_conduit_lag_join(conduit: dev, lag_dev: info->upper_dev, |
3292 | uinfo: info->upper_info, extack); |
3293 | err = notifier_from_errno(err); |
3294 | } else { |
3295 | dsa_conduit_lag_leave(conduit: dev, lag_dev: info->upper_dev); |
3296 | err = NOTIFY_OK; |
3297 | } |
3298 | } |
3299 | |
3300 | return err; |
3301 | } |
3302 | |
3303 | static int dsa_user_netdevice_event(struct notifier_block *nb, |
3304 | unsigned long event, void *ptr) |
3305 | { |
3306 | struct net_device *dev = netdev_notifier_info_to_dev(info: ptr); |
3307 | |
3308 | switch (event) { |
3309 | case NETDEV_PRECHANGEUPPER: { |
3310 | struct netdev_notifier_changeupper_info *info = ptr; |
3311 | int err; |
3312 | |
3313 | err = dsa_user_prechangeupper_sanity_check(dev, info); |
3314 | if (notifier_to_errno(ret: err)) |
3315 | return err; |
3316 | |
3317 | err = dsa_conduit_prechangeupper_sanity_check(conduit: dev, info); |
3318 | if (notifier_to_errno(ret: err)) |
3319 | return err; |
3320 | |
3321 | err = dsa_lag_conduit_prechangelower_sanity_check(dev, info); |
3322 | if (notifier_to_errno(ret: err)) |
3323 | return err; |
3324 | |
3325 | err = dsa_bridge_prechangelower_sanity_check(new_lower: dev, info); |
3326 | if (notifier_to_errno(ret: err)) |
3327 | return err; |
3328 | |
3329 | err = dsa_user_prechangeupper(dev, info: ptr); |
3330 | if (notifier_to_errno(ret: err)) |
3331 | return err; |
3332 | |
3333 | err = dsa_user_lag_prechangeupper(dev, info: ptr); |
3334 | if (notifier_to_errno(ret: err)) |
3335 | return err; |
3336 | |
3337 | break; |
3338 | } |
3339 | case NETDEV_CHANGEUPPER: { |
3340 | int err; |
3341 | |
3342 | err = dsa_user_changeupper(dev, info: ptr); |
3343 | if (notifier_to_errno(ret: err)) |
3344 | return err; |
3345 | |
3346 | err = dsa_user_lag_changeupper(dev, info: ptr); |
3347 | if (notifier_to_errno(ret: err)) |
3348 | return err; |
3349 | |
3350 | err = dsa_conduit_changeupper(dev, info: ptr); |
3351 | if (notifier_to_errno(ret: err)) |
3352 | return err; |
3353 | |
3354 | break; |
3355 | } |
3356 | case NETDEV_CHANGELOWERSTATE: { |
3357 | struct netdev_notifier_changelowerstate_info *info = ptr; |
3358 | struct dsa_port *dp; |
3359 | int err = 0; |
3360 | |
3361 | if (dsa_user_dev_check(dev)) { |
3362 | dp = dsa_user_to_port(dev); |
3363 | |
3364 | err = dsa_port_lag_change(dp, linfo: info->lower_state_info); |
3365 | } |
3366 | |
3367 | /* Mirror LAG port events on DSA conduits that are in |
3368 | * a LAG towards their respective switch CPU ports |
3369 | */ |
3370 | if (netdev_uses_dsa(dev)) { |
3371 | dp = dev->dsa_ptr; |
3372 | |
3373 | err = dsa_port_lag_change(dp, linfo: info->lower_state_info); |
3374 | } |
3375 | |
3376 | return notifier_from_errno(err); |
3377 | } |
3378 | case NETDEV_CHANGE: |
3379 | case NETDEV_UP: { |
3380 | /* Track state of conduit port. |
3381 | * DSA driver may require the conduit port (and indirectly |
3382 | * the tagger) to be available for some special operation. |
3383 | */ |
3384 | if (netdev_uses_dsa(dev)) { |
3385 | struct dsa_port *cpu_dp = dev->dsa_ptr; |
3386 | struct dsa_switch_tree *dst = cpu_dp->ds->dst; |
3387 | |
3388 | /* Track when the conduit port is UP */ |
3389 | dsa_tree_conduit_oper_state_change(dst, conduit: dev, |
3390 | up: netif_oper_up(dev)); |
3391 | |
3392 | /* Track when the conduit port is ready and can accept |
3393 | * packet. |
3394 | * NETDEV_UP event is not enough to flag a port as ready. |
3395 | * We also have to wait for linkwatch_do_dev to dev_activate |
3396 | * and emit a NETDEV_CHANGE event. |
3397 | * We check if a conduit port is ready by checking if the dev |
3398 | * have a qdisc assigned and is not noop. |
3399 | */ |
3400 | dsa_tree_conduit_admin_state_change(dst, conduit: dev, |
3401 | up: !qdisc_tx_is_noop(dev)); |
3402 | |
3403 | return NOTIFY_OK; |
3404 | } |
3405 | |
3406 | return NOTIFY_DONE; |
3407 | } |
3408 | case NETDEV_GOING_DOWN: { |
3409 | struct dsa_port *dp, *cpu_dp; |
3410 | struct dsa_switch_tree *dst; |
3411 | LIST_HEAD(close_list); |
3412 | |
3413 | if (!netdev_uses_dsa(dev)) |
3414 | return NOTIFY_DONE; |
3415 | |
3416 | cpu_dp = dev->dsa_ptr; |
3417 | dst = cpu_dp->ds->dst; |
3418 | |
3419 | dsa_tree_conduit_admin_state_change(dst, conduit: dev, up: false); |
3420 | |
3421 | list_for_each_entry(dp, &dst->ports, list) { |
3422 | if (!dsa_port_is_user(dp)) |
3423 | continue; |
3424 | |
3425 | if (dp->cpu_dp != cpu_dp) |
3426 | continue; |
3427 | |
3428 | list_add(new: &dp->user->close_list, head: &close_list); |
3429 | } |
3430 | |
3431 | dev_close_many(head: &close_list, unlink: true); |
3432 | |
3433 | return NOTIFY_OK; |
3434 | } |
3435 | default: |
3436 | break; |
3437 | } |
3438 | |
3439 | return NOTIFY_DONE; |
3440 | } |
3441 | |
3442 | static void |
3443 | dsa_fdb_offload_notify(struct dsa_switchdev_event_work *switchdev_work) |
3444 | { |
3445 | struct switchdev_notifier_fdb_info info = {}; |
3446 | |
3447 | info.addr = switchdev_work->addr; |
3448 | info.vid = switchdev_work->vid; |
3449 | info.offloaded = true; |
3450 | call_switchdev_notifiers(val: SWITCHDEV_FDB_OFFLOADED, |
3451 | dev: switchdev_work->orig_dev, info: &info.info, NULL); |
3452 | } |
3453 | |
3454 | static void dsa_user_switchdev_event_work(struct work_struct *work) |
3455 | { |
3456 | struct dsa_switchdev_event_work *switchdev_work = |
3457 | container_of(work, struct dsa_switchdev_event_work, work); |
3458 | const unsigned char *addr = switchdev_work->addr; |
3459 | struct net_device *dev = switchdev_work->dev; |
3460 | u16 vid = switchdev_work->vid; |
3461 | struct dsa_switch *ds; |
3462 | struct dsa_port *dp; |
3463 | int err; |
3464 | |
3465 | dp = dsa_user_to_port(dev); |
3466 | ds = dp->ds; |
3467 | |
3468 | switch (switchdev_work->event) { |
3469 | case SWITCHDEV_FDB_ADD_TO_DEVICE: |
3470 | if (switchdev_work->host_addr) |
3471 | err = dsa_port_bridge_host_fdb_add(dp, addr, vid); |
3472 | else if (dp->lag) |
3473 | err = dsa_port_lag_fdb_add(dp, addr, vid); |
3474 | else |
3475 | err = dsa_port_fdb_add(dp, addr, vid); |
3476 | if (err) { |
3477 | dev_err(ds->dev, |
3478 | "port %d failed to add %pM vid %d to fdb: %d\n" , |
3479 | dp->index, addr, vid, err); |
3480 | break; |
3481 | } |
3482 | dsa_fdb_offload_notify(switchdev_work); |
3483 | break; |
3484 | |
3485 | case SWITCHDEV_FDB_DEL_TO_DEVICE: |
3486 | if (switchdev_work->host_addr) |
3487 | err = dsa_port_bridge_host_fdb_del(dp, addr, vid); |
3488 | else if (dp->lag) |
3489 | err = dsa_port_lag_fdb_del(dp, addr, vid); |
3490 | else |
3491 | err = dsa_port_fdb_del(dp, addr, vid); |
3492 | if (err) { |
3493 | dev_err(ds->dev, |
3494 | "port %d failed to delete %pM vid %d from fdb: %d\n" , |
3495 | dp->index, addr, vid, err); |
3496 | } |
3497 | |
3498 | break; |
3499 | } |
3500 | |
3501 | kfree(objp: switchdev_work); |
3502 | } |
3503 | |
3504 | static bool dsa_foreign_dev_check(const struct net_device *dev, |
3505 | const struct net_device *foreign_dev) |
3506 | { |
3507 | const struct dsa_port *dp = dsa_user_to_port(dev); |
3508 | struct dsa_switch_tree *dst = dp->ds->dst; |
3509 | |
3510 | if (netif_is_bridge_master(dev: foreign_dev)) |
3511 | return !dsa_tree_offloads_bridge_dev(dst, bridge_dev: foreign_dev); |
3512 | |
3513 | if (netif_is_bridge_port(dev: foreign_dev)) |
3514 | return !dsa_tree_offloads_bridge_port(dst, dev: foreign_dev); |
3515 | |
3516 | /* Everything else is foreign */ |
3517 | return true; |
3518 | } |
3519 | |
3520 | static int dsa_user_fdb_event(struct net_device *dev, |
3521 | struct net_device *orig_dev, |
3522 | unsigned long event, const void *ctx, |
3523 | const struct switchdev_notifier_fdb_info *fdb_info) |
3524 | { |
3525 | struct dsa_switchdev_event_work *switchdev_work; |
3526 | struct dsa_port *dp = dsa_user_to_port(dev); |
3527 | bool host_addr = fdb_info->is_local; |
3528 | struct dsa_switch *ds = dp->ds; |
3529 | |
3530 | if (ctx && ctx != dp) |
3531 | return 0; |
3532 | |
3533 | if (!dp->bridge) |
3534 | return 0; |
3535 | |
3536 | if (switchdev_fdb_is_dynamically_learned(fdb_info)) { |
3537 | if (dsa_port_offloads_bridge_port(dp, dev: orig_dev)) |
3538 | return 0; |
3539 | |
3540 | /* FDB entries learned by the software bridge or by foreign |
3541 | * bridge ports should be installed as host addresses only if |
3542 | * the driver requests assisted learning. |
3543 | */ |
3544 | if (!ds->assisted_learning_on_cpu_port) |
3545 | return 0; |
3546 | } |
3547 | |
3548 | /* Also treat FDB entries on foreign interfaces bridged with us as host |
3549 | * addresses. |
3550 | */ |
3551 | if (dsa_foreign_dev_check(dev, foreign_dev: orig_dev)) |
3552 | host_addr = true; |
3553 | |
3554 | /* Check early that we're not doing work in vain. |
3555 | * Host addresses on LAG ports still require regular FDB ops, |
3556 | * since the CPU port isn't in a LAG. |
3557 | */ |
3558 | if (dp->lag && !host_addr) { |
3559 | if (!ds->ops->lag_fdb_add || !ds->ops->lag_fdb_del) |
3560 | return -EOPNOTSUPP; |
3561 | } else { |
3562 | if (!ds->ops->port_fdb_add || !ds->ops->port_fdb_del) |
3563 | return -EOPNOTSUPP; |
3564 | } |
3565 | |
3566 | switchdev_work = kzalloc(size: sizeof(*switchdev_work), GFP_ATOMIC); |
3567 | if (!switchdev_work) |
3568 | return -ENOMEM; |
3569 | |
3570 | netdev_dbg(dev, "%s FDB entry towards %s, addr %pM vid %d%s\n" , |
3571 | event == SWITCHDEV_FDB_ADD_TO_DEVICE ? "Adding" : "Deleting" , |
3572 | orig_dev->name, fdb_info->addr, fdb_info->vid, |
3573 | host_addr ? " as host address" : "" ); |
3574 | |
3575 | INIT_WORK(&switchdev_work->work, dsa_user_switchdev_event_work); |
3576 | switchdev_work->event = event; |
3577 | switchdev_work->dev = dev; |
3578 | switchdev_work->orig_dev = orig_dev; |
3579 | |
3580 | ether_addr_copy(dst: switchdev_work->addr, src: fdb_info->addr); |
3581 | switchdev_work->vid = fdb_info->vid; |
3582 | switchdev_work->host_addr = host_addr; |
3583 | |
3584 | dsa_schedule_work(work: &switchdev_work->work); |
3585 | |
3586 | return 0; |
3587 | } |
3588 | |
3589 | /* Called under rcu_read_lock() */ |
3590 | static int dsa_user_switchdev_event(struct notifier_block *unused, |
3591 | unsigned long event, void *ptr) |
3592 | { |
3593 | struct net_device *dev = switchdev_notifier_info_to_dev(info: ptr); |
3594 | int err; |
3595 | |
3596 | switch (event) { |
3597 | case SWITCHDEV_PORT_ATTR_SET: |
3598 | err = switchdev_handle_port_attr_set(dev, port_attr_info: ptr, |
3599 | check_cb: dsa_user_dev_check, |
3600 | set_cb: dsa_user_port_attr_set); |
3601 | return notifier_from_errno(err); |
3602 | case SWITCHDEV_FDB_ADD_TO_DEVICE: |
3603 | case SWITCHDEV_FDB_DEL_TO_DEVICE: |
3604 | err = switchdev_handle_fdb_event_to_device(dev, event, fdb_info: ptr, |
3605 | check_cb: dsa_user_dev_check, |
3606 | foreign_dev_check_cb: dsa_foreign_dev_check, |
3607 | mod_cb: dsa_user_fdb_event); |
3608 | return notifier_from_errno(err); |
3609 | default: |
3610 | return NOTIFY_DONE; |
3611 | } |
3612 | |
3613 | return NOTIFY_OK; |
3614 | } |
3615 | |
3616 | static int dsa_user_switchdev_blocking_event(struct notifier_block *unused, |
3617 | unsigned long event, void *ptr) |
3618 | { |
3619 | struct net_device *dev = switchdev_notifier_info_to_dev(info: ptr); |
3620 | int err; |
3621 | |
3622 | switch (event) { |
3623 | case SWITCHDEV_PORT_OBJ_ADD: |
3624 | err = switchdev_handle_port_obj_add_foreign(dev, port_obj_info: ptr, |
3625 | check_cb: dsa_user_dev_check, |
3626 | foreign_dev_check_cb: dsa_foreign_dev_check, |
3627 | add_cb: dsa_user_port_obj_add); |
3628 | return notifier_from_errno(err); |
3629 | case SWITCHDEV_PORT_OBJ_DEL: |
3630 | err = switchdev_handle_port_obj_del_foreign(dev, port_obj_info: ptr, |
3631 | check_cb: dsa_user_dev_check, |
3632 | foreign_dev_check_cb: dsa_foreign_dev_check, |
3633 | del_cb: dsa_user_port_obj_del); |
3634 | return notifier_from_errno(err); |
3635 | case SWITCHDEV_PORT_ATTR_SET: |
3636 | err = switchdev_handle_port_attr_set(dev, port_attr_info: ptr, |
3637 | check_cb: dsa_user_dev_check, |
3638 | set_cb: dsa_user_port_attr_set); |
3639 | return notifier_from_errno(err); |
3640 | } |
3641 | |
3642 | return NOTIFY_DONE; |
3643 | } |
3644 | |
3645 | static struct notifier_block dsa_user_nb __read_mostly = { |
3646 | .notifier_call = dsa_user_netdevice_event, |
3647 | }; |
3648 | |
3649 | struct notifier_block dsa_user_switchdev_notifier = { |
3650 | .notifier_call = dsa_user_switchdev_event, |
3651 | }; |
3652 | |
3653 | struct notifier_block dsa_user_switchdev_blocking_notifier = { |
3654 | .notifier_call = dsa_user_switchdev_blocking_event, |
3655 | }; |
3656 | |
3657 | int dsa_user_register_notifier(void) |
3658 | { |
3659 | struct notifier_block *nb; |
3660 | int err; |
3661 | |
3662 | err = register_netdevice_notifier(nb: &dsa_user_nb); |
3663 | if (err) |
3664 | return err; |
3665 | |
3666 | err = register_switchdev_notifier(nb: &dsa_user_switchdev_notifier); |
3667 | if (err) |
3668 | goto err_switchdev_nb; |
3669 | |
3670 | nb = &dsa_user_switchdev_blocking_notifier; |
3671 | err = register_switchdev_blocking_notifier(nb); |
3672 | if (err) |
3673 | goto err_switchdev_blocking_nb; |
3674 | |
3675 | return 0; |
3676 | |
3677 | err_switchdev_blocking_nb: |
3678 | unregister_switchdev_notifier(nb: &dsa_user_switchdev_notifier); |
3679 | err_switchdev_nb: |
3680 | unregister_netdevice_notifier(nb: &dsa_user_nb); |
3681 | return err; |
3682 | } |
3683 | |
3684 | void dsa_user_unregister_notifier(void) |
3685 | { |
3686 | struct notifier_block *nb; |
3687 | int err; |
3688 | |
3689 | nb = &dsa_user_switchdev_blocking_notifier; |
3690 | err = unregister_switchdev_blocking_notifier(nb); |
3691 | if (err) |
3692 | pr_err("DSA: failed to unregister switchdev blocking notifier (%d)\n" , err); |
3693 | |
3694 | err = unregister_switchdev_notifier(nb: &dsa_user_switchdev_notifier); |
3695 | if (err) |
3696 | pr_err("DSA: failed to unregister switchdev notifier (%d)\n" , err); |
3697 | |
3698 | err = unregister_netdevice_notifier(nb: &dsa_user_nb); |
3699 | if (err) |
3700 | pr_err("DSA: failed to unregister user notifier (%d)\n" , err); |
3701 | } |
3702 | |