1 // SPDX-License-Identifier: BSD-3-Clause OR GPL-2.0
2 /* Copyright (c) 2019-2020 Marvell International Ltd. All rights reserved */
3
4 #include <linux/etherdevice.h>
5 #include <linux/jiffies.h>
6 #include <linux/list.h>
7 #include <linux/module.h>
8 #include <linux/netdev_features.h>
9 #include <linux/of.h>
10 #include <linux/of_net.h>
11 #include <linux/if_vlan.h>
12
13 #include "prestera.h"
14 #include "prestera_hw.h"
15 #include "prestera_acl.h"
16 #include "prestera_flow.h"
17 #include "prestera_span.h"
18 #include "prestera_rxtx.h"
19 #include "prestera_devlink.h"
20 #include "prestera_ethtool.h"
21 #include "prestera_switchdev.h"
22
23 #define PRESTERA_MTU_DEFAULT 1536
24
25 #define PRESTERA_STATS_DELAY_MS 1000
26
27 #define PRESTERA_MAC_ADDR_NUM_MAX 255
28
29 static struct workqueue_struct *prestera_wq;
30
prestera_port_pvid_set(struct prestera_port * port,u16 vid)31 int prestera_port_pvid_set(struct prestera_port *port, u16 vid)
32 {
33 enum prestera_accept_frm_type frm_type;
34 int err;
35
36 frm_type = PRESTERA_ACCEPT_FRAME_TYPE_TAGGED;
37
38 if (vid) {
39 err = prestera_hw_vlan_port_vid_set(port, vid);
40 if (err)
41 return err;
42
43 frm_type = PRESTERA_ACCEPT_FRAME_TYPE_ALL;
44 }
45
46 err = prestera_hw_port_accept_frm_type(port, frm_type);
47 if (err && frm_type == PRESTERA_ACCEPT_FRAME_TYPE_ALL)
48 prestera_hw_vlan_port_vid_set(port, port->pvid);
49
50 port->pvid = vid;
51 return 0;
52 }
53
prestera_port_find_by_hwid(struct prestera_switch * sw,u32 dev_id,u32 hw_id)54 struct prestera_port *prestera_port_find_by_hwid(struct prestera_switch *sw,
55 u32 dev_id, u32 hw_id)
56 {
57 struct prestera_port *port = NULL, *tmp;
58
59 read_lock(&sw->port_list_lock);
60 list_for_each_entry(tmp, &sw->port_list, list) {
61 if (tmp->dev_id == dev_id && tmp->hw_id == hw_id) {
62 port = tmp;
63 break;
64 }
65 }
66 read_unlock(&sw->port_list_lock);
67
68 return port;
69 }
70
prestera_find_port(struct prestera_switch * sw,u32 id)71 struct prestera_port *prestera_find_port(struct prestera_switch *sw, u32 id)
72 {
73 struct prestera_port *port = NULL, *tmp;
74
75 read_lock(&sw->port_list_lock);
76 list_for_each_entry(tmp, &sw->port_list, list) {
77 if (tmp->id == id) {
78 port = tmp;
79 break;
80 }
81 }
82 read_unlock(&sw->port_list_lock);
83
84 return port;
85 }
86
prestera_port_open(struct net_device * dev)87 static int prestera_port_open(struct net_device *dev)
88 {
89 struct prestera_port *port = netdev_priv(dev);
90 int err;
91
92 err = prestera_hw_port_state_set(port, true);
93 if (err)
94 return err;
95
96 netif_start_queue(dev);
97
98 return 0;
99 }
100
prestera_port_close(struct net_device * dev)101 static int prestera_port_close(struct net_device *dev)
102 {
103 struct prestera_port *port = netdev_priv(dev);
104
105 netif_stop_queue(dev);
106
107 return prestera_hw_port_state_set(port, false);
108 }
109
prestera_port_xmit(struct sk_buff * skb,struct net_device * dev)110 static netdev_tx_t prestera_port_xmit(struct sk_buff *skb,
111 struct net_device *dev)
112 {
113 return prestera_rxtx_xmit(netdev_priv(dev), skb);
114 }
115
prestera_is_valid_mac_addr(struct prestera_port * port,u8 * addr)116 static int prestera_is_valid_mac_addr(struct prestera_port *port, u8 *addr)
117 {
118 if (!is_valid_ether_addr(addr))
119 return -EADDRNOTAVAIL;
120
121 /* firmware requires that port's MAC address contains first 5 bytes
122 * of the base MAC address
123 */
124 if (memcmp(port->sw->base_mac, addr, ETH_ALEN - 1))
125 return -EINVAL;
126
127 return 0;
128 }
129
prestera_port_set_mac_address(struct net_device * dev,void * p)130 static int prestera_port_set_mac_address(struct net_device *dev, void *p)
131 {
132 struct prestera_port *port = netdev_priv(dev);
133 struct sockaddr *addr = p;
134 int err;
135
136 err = prestera_is_valid_mac_addr(port, addr->sa_data);
137 if (err)
138 return err;
139
140 err = prestera_hw_port_mac_set(port, addr->sa_data);
141 if (err)
142 return err;
143
144 eth_hw_addr_set(dev, addr->sa_data);
145
146 return 0;
147 }
148
prestera_port_change_mtu(struct net_device * dev,int mtu)149 static int prestera_port_change_mtu(struct net_device *dev, int mtu)
150 {
151 struct prestera_port *port = netdev_priv(dev);
152 int err;
153
154 err = prestera_hw_port_mtu_set(port, mtu);
155 if (err)
156 return err;
157
158 dev->mtu = mtu;
159
160 return 0;
161 }
162
prestera_port_get_stats64(struct net_device * dev,struct rtnl_link_stats64 * stats)163 static void prestera_port_get_stats64(struct net_device *dev,
164 struct rtnl_link_stats64 *stats)
165 {
166 struct prestera_port *port = netdev_priv(dev);
167 struct prestera_port_stats *port_stats = &port->cached_hw_stats.stats;
168
169 stats->rx_packets = port_stats->broadcast_frames_received +
170 port_stats->multicast_frames_received +
171 port_stats->unicast_frames_received;
172
173 stats->tx_packets = port_stats->broadcast_frames_sent +
174 port_stats->multicast_frames_sent +
175 port_stats->unicast_frames_sent;
176
177 stats->rx_bytes = port_stats->good_octets_received;
178
179 stats->tx_bytes = port_stats->good_octets_sent;
180
181 stats->rx_errors = port_stats->rx_error_frame_received;
182 stats->tx_errors = port_stats->mac_trans_error;
183
184 stats->rx_dropped = port_stats->buffer_overrun;
185 stats->tx_dropped = 0;
186
187 stats->multicast = port_stats->multicast_frames_received;
188 stats->collisions = port_stats->excessive_collision;
189
190 stats->rx_crc_errors = port_stats->bad_crc;
191 }
192
prestera_port_get_hw_stats(struct prestera_port * port)193 static void prestera_port_get_hw_stats(struct prestera_port *port)
194 {
195 prestera_hw_port_stats_get(port, &port->cached_hw_stats.stats);
196 }
197
prestera_port_stats_update(struct work_struct * work)198 static void prestera_port_stats_update(struct work_struct *work)
199 {
200 struct prestera_port *port =
201 container_of(work, struct prestera_port,
202 cached_hw_stats.caching_dw.work);
203
204 prestera_port_get_hw_stats(port);
205
206 queue_delayed_work(prestera_wq, &port->cached_hw_stats.caching_dw,
207 msecs_to_jiffies(PRESTERA_STATS_DELAY_MS));
208 }
209
prestera_port_setup_tc(struct net_device * dev,enum tc_setup_type type,void * type_data)210 static int prestera_port_setup_tc(struct net_device *dev,
211 enum tc_setup_type type,
212 void *type_data)
213 {
214 struct prestera_port *port = netdev_priv(dev);
215
216 switch (type) {
217 case TC_SETUP_BLOCK:
218 return prestera_flow_block_setup(port, type_data);
219 default:
220 return -EOPNOTSUPP;
221 }
222 }
223
224 static const struct net_device_ops prestera_netdev_ops = {
225 .ndo_open = prestera_port_open,
226 .ndo_stop = prestera_port_close,
227 .ndo_start_xmit = prestera_port_xmit,
228 .ndo_setup_tc = prestera_port_setup_tc,
229 .ndo_change_mtu = prestera_port_change_mtu,
230 .ndo_get_stats64 = prestera_port_get_stats64,
231 .ndo_set_mac_address = prestera_port_set_mac_address,
232 .ndo_get_devlink_port = prestera_devlink_get_port,
233 };
234
prestera_port_autoneg_set(struct prestera_port * port,bool enable,u64 adver_link_modes,u8 adver_fec)235 int prestera_port_autoneg_set(struct prestera_port *port, bool enable,
236 u64 adver_link_modes, u8 adver_fec)
237 {
238 bool refresh = false;
239 u64 link_modes;
240 int err;
241 u8 fec;
242
243 if (port->caps.type != PRESTERA_PORT_TYPE_TP)
244 return enable ? -EINVAL : 0;
245
246 if (!enable)
247 goto set_autoneg;
248
249 link_modes = port->caps.supp_link_modes & adver_link_modes;
250 fec = port->caps.supp_fec & adver_fec;
251
252 if (!link_modes && !fec)
253 return -EOPNOTSUPP;
254
255 if (link_modes && port->adver_link_modes != link_modes) {
256 port->adver_link_modes = link_modes;
257 refresh = true;
258 }
259
260 if (fec && port->adver_fec != fec) {
261 port->adver_fec = fec;
262 refresh = true;
263 }
264
265 set_autoneg:
266 if (port->autoneg == enable && !refresh)
267 return 0;
268
269 err = prestera_hw_port_autoneg_set(port, enable, port->adver_link_modes,
270 port->adver_fec);
271 if (err)
272 return err;
273
274 port->autoneg = enable;
275
276 return 0;
277 }
278
prestera_port_list_add(struct prestera_port * port)279 static void prestera_port_list_add(struct prestera_port *port)
280 {
281 write_lock(&port->sw->port_list_lock);
282 list_add(&port->list, &port->sw->port_list);
283 write_unlock(&port->sw->port_list_lock);
284 }
285
prestera_port_list_del(struct prestera_port * port)286 static void prestera_port_list_del(struct prestera_port *port)
287 {
288 write_lock(&port->sw->port_list_lock);
289 list_del(&port->list);
290 write_unlock(&port->sw->port_list_lock);
291 }
292
prestera_port_create(struct prestera_switch * sw,u32 id)293 static int prestera_port_create(struct prestera_switch *sw, u32 id)
294 {
295 struct prestera_port *port;
296 struct net_device *dev;
297 int err;
298
299 dev = alloc_etherdev(sizeof(*port));
300 if (!dev)
301 return -ENOMEM;
302
303 port = netdev_priv(dev);
304
305 INIT_LIST_HEAD(&port->vlans_list);
306 port->pvid = PRESTERA_DEFAULT_VID;
307 port->lag = NULL;
308 port->dev = dev;
309 port->id = id;
310 port->sw = sw;
311
312 err = prestera_hw_port_info_get(port, &port->dev_id, &port->hw_id,
313 &port->fp_id);
314 if (err) {
315 dev_err(prestera_dev(sw), "Failed to get port(%u) info\n", id);
316 goto err_port_info_get;
317 }
318
319 err = prestera_devlink_port_register(port);
320 if (err)
321 goto err_dl_port_register;
322
323 dev->features |= NETIF_F_NETNS_LOCAL | NETIF_F_HW_TC;
324 dev->netdev_ops = &prestera_netdev_ops;
325 dev->ethtool_ops = &prestera_ethtool_ops;
326
327 netif_carrier_off(dev);
328
329 dev->mtu = min_t(unsigned int, sw->mtu_max, PRESTERA_MTU_DEFAULT);
330 dev->min_mtu = sw->mtu_min;
331 dev->max_mtu = sw->mtu_max;
332
333 err = prestera_hw_port_mtu_set(port, dev->mtu);
334 if (err) {
335 dev_err(prestera_dev(sw), "Failed to set port(%u) mtu(%d)\n",
336 id, dev->mtu);
337 goto err_port_init;
338 }
339
340 if (port->fp_id >= PRESTERA_MAC_ADDR_NUM_MAX) {
341 err = -EINVAL;
342 goto err_port_init;
343 }
344
345 /* firmware requires that port's MAC address consist of the first
346 * 5 bytes of the base MAC address
347 */
348 memcpy(dev->dev_addr, sw->base_mac, dev->addr_len - 1);
349 dev->dev_addr[dev->addr_len - 1] = port->fp_id;
350
351 err = prestera_hw_port_mac_set(port, dev->dev_addr);
352 if (err) {
353 dev_err(prestera_dev(sw), "Failed to set port(%u) mac addr\n", id);
354 goto err_port_init;
355 }
356
357 err = prestera_hw_port_cap_get(port, &port->caps);
358 if (err) {
359 dev_err(prestera_dev(sw), "Failed to get port(%u) caps\n", id);
360 goto err_port_init;
361 }
362
363 port->adver_fec = BIT(PRESTERA_PORT_FEC_OFF);
364 prestera_port_autoneg_set(port, true, port->caps.supp_link_modes,
365 port->caps.supp_fec);
366
367 err = prestera_hw_port_state_set(port, false);
368 if (err) {
369 dev_err(prestera_dev(sw), "Failed to set port(%u) down\n", id);
370 goto err_port_init;
371 }
372
373 err = prestera_rxtx_port_init(port);
374 if (err)
375 goto err_port_init;
376
377 INIT_DELAYED_WORK(&port->cached_hw_stats.caching_dw,
378 &prestera_port_stats_update);
379
380 prestera_port_list_add(port);
381
382 err = register_netdev(dev);
383 if (err)
384 goto err_register_netdev;
385
386 prestera_devlink_port_set(port);
387
388 return 0;
389
390 err_register_netdev:
391 prestera_port_list_del(port);
392 err_port_init:
393 prestera_devlink_port_unregister(port);
394 err_dl_port_register:
395 err_port_info_get:
396 free_netdev(dev);
397 return err;
398 }
399
prestera_port_destroy(struct prestera_port * port)400 static void prestera_port_destroy(struct prestera_port *port)
401 {
402 struct net_device *dev = port->dev;
403
404 cancel_delayed_work_sync(&port->cached_hw_stats.caching_dw);
405 prestera_devlink_port_clear(port);
406 unregister_netdev(dev);
407 prestera_port_list_del(port);
408 prestera_devlink_port_unregister(port);
409 free_netdev(dev);
410 }
411
prestera_destroy_ports(struct prestera_switch * sw)412 static void prestera_destroy_ports(struct prestera_switch *sw)
413 {
414 struct prestera_port *port, *tmp;
415
416 list_for_each_entry_safe(port, tmp, &sw->port_list, list)
417 prestera_port_destroy(port);
418 }
419
prestera_create_ports(struct prestera_switch * sw)420 static int prestera_create_ports(struct prestera_switch *sw)
421 {
422 struct prestera_port *port, *tmp;
423 u32 port_idx;
424 int err;
425
426 for (port_idx = 0; port_idx < sw->port_count; port_idx++) {
427 err = prestera_port_create(sw, port_idx);
428 if (err)
429 goto err_port_create;
430 }
431
432 return 0;
433
434 err_port_create:
435 list_for_each_entry_safe(port, tmp, &sw->port_list, list)
436 prestera_port_destroy(port);
437
438 return err;
439 }
440
prestera_port_handle_event(struct prestera_switch * sw,struct prestera_event * evt,void * arg)441 static void prestera_port_handle_event(struct prestera_switch *sw,
442 struct prestera_event *evt, void *arg)
443 {
444 struct delayed_work *caching_dw;
445 struct prestera_port *port;
446
447 port = prestera_find_port(sw, evt->port_evt.port_id);
448 if (!port || !port->dev)
449 return;
450
451 caching_dw = &port->cached_hw_stats.caching_dw;
452
453 if (evt->id == PRESTERA_PORT_EVENT_STATE_CHANGED) {
454 if (evt->port_evt.data.oper_state) {
455 netif_carrier_on(port->dev);
456 if (!delayed_work_pending(caching_dw))
457 queue_delayed_work(prestera_wq, caching_dw, 0);
458 } else if (netif_running(port->dev) &&
459 netif_carrier_ok(port->dev)) {
460 netif_carrier_off(port->dev);
461 if (delayed_work_pending(caching_dw))
462 cancel_delayed_work(caching_dw);
463 }
464 }
465 }
466
prestera_event_handlers_register(struct prestera_switch * sw)467 static int prestera_event_handlers_register(struct prestera_switch *sw)
468 {
469 return prestera_hw_event_handler_register(sw, PRESTERA_EVENT_TYPE_PORT,
470 prestera_port_handle_event,
471 NULL);
472 }
473
prestera_event_handlers_unregister(struct prestera_switch * sw)474 static void prestera_event_handlers_unregister(struct prestera_switch *sw)
475 {
476 prestera_hw_event_handler_unregister(sw, PRESTERA_EVENT_TYPE_PORT,
477 prestera_port_handle_event);
478 }
479
prestera_switch_set_base_mac_addr(struct prestera_switch * sw)480 static int prestera_switch_set_base_mac_addr(struct prestera_switch *sw)
481 {
482 struct device_node *base_mac_np;
483 struct device_node *np;
484 int ret;
485
486 np = of_find_compatible_node(NULL, NULL, "marvell,prestera");
487 base_mac_np = of_parse_phandle(np, "base-mac-provider", 0);
488
489 ret = of_get_mac_address(base_mac_np, sw->base_mac);
490 if (ret) {
491 eth_random_addr(sw->base_mac);
492 dev_info(prestera_dev(sw), "using random base mac address\n");
493 }
494 of_node_put(base_mac_np);
495 of_node_put(np);
496
497 return prestera_hw_switch_mac_set(sw, sw->base_mac);
498 }
499
prestera_lag_by_id(struct prestera_switch * sw,u16 id)500 struct prestera_lag *prestera_lag_by_id(struct prestera_switch *sw, u16 id)
501 {
502 return id < sw->lag_max ? &sw->lags[id] : NULL;
503 }
504
prestera_lag_by_dev(struct prestera_switch * sw,struct net_device * dev)505 static struct prestera_lag *prestera_lag_by_dev(struct prestera_switch *sw,
506 struct net_device *dev)
507 {
508 struct prestera_lag *lag;
509 u16 id;
510
511 for (id = 0; id < sw->lag_max; id++) {
512 lag = &sw->lags[id];
513 if (lag->dev == dev)
514 return lag;
515 }
516
517 return NULL;
518 }
519
prestera_lag_create(struct prestera_switch * sw,struct net_device * lag_dev)520 static struct prestera_lag *prestera_lag_create(struct prestera_switch *sw,
521 struct net_device *lag_dev)
522 {
523 struct prestera_lag *lag = NULL;
524 u16 id;
525
526 for (id = 0; id < sw->lag_max; id++) {
527 lag = &sw->lags[id];
528 if (!lag->dev)
529 break;
530 }
531 if (lag) {
532 INIT_LIST_HEAD(&lag->members);
533 lag->dev = lag_dev;
534 }
535
536 return lag;
537 }
538
prestera_lag_destroy(struct prestera_switch * sw,struct prestera_lag * lag)539 static void prestera_lag_destroy(struct prestera_switch *sw,
540 struct prestera_lag *lag)
541 {
542 WARN_ON(!list_empty(&lag->members));
543 lag->member_count = 0;
544 lag->dev = NULL;
545 }
546
prestera_lag_port_add(struct prestera_port * port,struct net_device * lag_dev)547 static int prestera_lag_port_add(struct prestera_port *port,
548 struct net_device *lag_dev)
549 {
550 struct prestera_switch *sw = port->sw;
551 struct prestera_lag *lag;
552 int err;
553
554 lag = prestera_lag_by_dev(sw, lag_dev);
555 if (!lag) {
556 lag = prestera_lag_create(sw, lag_dev);
557 if (!lag)
558 return -ENOSPC;
559 }
560
561 if (lag->member_count >= sw->lag_member_max)
562 return -ENOSPC;
563
564 err = prestera_hw_lag_member_add(port, lag->lag_id);
565 if (err) {
566 if (!lag->member_count)
567 prestera_lag_destroy(sw, lag);
568 return err;
569 }
570
571 list_add(&port->lag_member, &lag->members);
572 lag->member_count++;
573 port->lag = lag;
574
575 return 0;
576 }
577
prestera_lag_port_del(struct prestera_port * port)578 static int prestera_lag_port_del(struct prestera_port *port)
579 {
580 struct prestera_switch *sw = port->sw;
581 struct prestera_lag *lag = port->lag;
582 int err;
583
584 if (!lag || !lag->member_count)
585 return -EINVAL;
586
587 err = prestera_hw_lag_member_del(port, lag->lag_id);
588 if (err)
589 return err;
590
591 list_del(&port->lag_member);
592 lag->member_count--;
593 port->lag = NULL;
594
595 if (netif_is_bridge_port(lag->dev)) {
596 struct net_device *br_dev;
597
598 br_dev = netdev_master_upper_dev_get(lag->dev);
599
600 prestera_bridge_port_leave(br_dev, port);
601 }
602
603 if (!lag->member_count)
604 prestera_lag_destroy(sw, lag);
605
606 return 0;
607 }
608
prestera_port_is_lag_member(const struct prestera_port * port)609 bool prestera_port_is_lag_member(const struct prestera_port *port)
610 {
611 return !!port->lag;
612 }
613
prestera_port_lag_id(const struct prestera_port * port)614 u16 prestera_port_lag_id(const struct prestera_port *port)
615 {
616 return port->lag->lag_id;
617 }
618
prestera_lag_init(struct prestera_switch * sw)619 static int prestera_lag_init(struct prestera_switch *sw)
620 {
621 u16 id;
622
623 sw->lags = kcalloc(sw->lag_max, sizeof(*sw->lags), GFP_KERNEL);
624 if (!sw->lags)
625 return -ENOMEM;
626
627 for (id = 0; id < sw->lag_max; id++)
628 sw->lags[id].lag_id = id;
629
630 return 0;
631 }
632
prestera_lag_fini(struct prestera_switch * sw)633 static void prestera_lag_fini(struct prestera_switch *sw)
634 {
635 u8 idx;
636
637 for (idx = 0; idx < sw->lag_max; idx++)
638 WARN_ON(sw->lags[idx].member_count);
639
640 kfree(sw->lags);
641 }
642
prestera_netdev_check(const struct net_device * dev)643 bool prestera_netdev_check(const struct net_device *dev)
644 {
645 return dev->netdev_ops == &prestera_netdev_ops;
646 }
647
prestera_lower_dev_walk(struct net_device * dev,struct netdev_nested_priv * priv)648 static int prestera_lower_dev_walk(struct net_device *dev,
649 struct netdev_nested_priv *priv)
650 {
651 struct prestera_port **pport = (struct prestera_port **)priv->data;
652
653 if (prestera_netdev_check(dev)) {
654 *pport = netdev_priv(dev);
655 return 1;
656 }
657
658 return 0;
659 }
660
prestera_port_dev_lower_find(struct net_device * dev)661 struct prestera_port *prestera_port_dev_lower_find(struct net_device *dev)
662 {
663 struct prestera_port *port = NULL;
664 struct netdev_nested_priv priv = {
665 .data = (void *)&port,
666 };
667
668 if (prestera_netdev_check(dev))
669 return netdev_priv(dev);
670
671 netdev_walk_all_lower_dev(dev, prestera_lower_dev_walk, &priv);
672
673 return port;
674 }
675
prestera_netdev_port_lower_event(struct net_device * dev,unsigned long event,void * ptr)676 static int prestera_netdev_port_lower_event(struct net_device *dev,
677 unsigned long event, void *ptr)
678 {
679 struct netdev_notifier_changelowerstate_info *info = ptr;
680 struct netdev_lag_lower_state_info *lower_state_info;
681 struct prestera_port *port = netdev_priv(dev);
682 bool enabled;
683
684 if (!netif_is_lag_port(dev))
685 return 0;
686 if (!prestera_port_is_lag_member(port))
687 return 0;
688
689 lower_state_info = info->lower_state_info;
690 enabled = lower_state_info->link_up && lower_state_info->tx_enabled;
691
692 return prestera_hw_lag_member_enable(port, port->lag->lag_id, enabled);
693 }
694
prestera_lag_master_check(struct net_device * lag_dev,struct netdev_lag_upper_info * info,struct netlink_ext_ack * ext_ack)695 static bool prestera_lag_master_check(struct net_device *lag_dev,
696 struct netdev_lag_upper_info *info,
697 struct netlink_ext_ack *ext_ack)
698 {
699 if (info->tx_type != NETDEV_LAG_TX_TYPE_HASH) {
700 NL_SET_ERR_MSG_MOD(ext_ack, "Unsupported LAG Tx type");
701 return false;
702 }
703
704 return true;
705 }
706
prestera_netdev_port_event(struct net_device * lower,struct net_device * dev,unsigned long event,void * ptr)707 static int prestera_netdev_port_event(struct net_device *lower,
708 struct net_device *dev,
709 unsigned long event, void *ptr)
710 {
711 struct netdev_notifier_info *info = ptr;
712 struct netdev_notifier_changeupper_info *cu_info;
713 struct prestera_port *port = netdev_priv(dev);
714 struct netlink_ext_ack *extack;
715 struct net_device *upper;
716
717 extack = netdev_notifier_info_to_extack(info);
718 cu_info = container_of(info,
719 struct netdev_notifier_changeupper_info,
720 info);
721
722 switch (event) {
723 case NETDEV_PRECHANGEUPPER:
724 upper = cu_info->upper_dev;
725 if (!netif_is_bridge_master(upper) &&
726 !netif_is_lag_master(upper)) {
727 NL_SET_ERR_MSG_MOD(extack, "Unknown upper device type");
728 return -EINVAL;
729 }
730
731 if (!cu_info->linking)
732 break;
733
734 if (netdev_has_any_upper_dev(upper)) {
735 NL_SET_ERR_MSG_MOD(extack, "Upper device is already enslaved");
736 return -EINVAL;
737 }
738
739 if (netif_is_lag_master(upper) &&
740 !prestera_lag_master_check(upper, cu_info->upper_info, extack))
741 return -EOPNOTSUPP;
742 if (netif_is_lag_master(upper) && vlan_uses_dev(dev)) {
743 NL_SET_ERR_MSG_MOD(extack,
744 "Master device is a LAG master and port has a VLAN");
745 return -EINVAL;
746 }
747 if (netif_is_lag_port(dev) && is_vlan_dev(upper) &&
748 !netif_is_lag_master(vlan_dev_real_dev(upper))) {
749 NL_SET_ERR_MSG_MOD(extack,
750 "Can not put a VLAN on a LAG port");
751 return -EINVAL;
752 }
753 break;
754
755 case NETDEV_CHANGEUPPER:
756 upper = cu_info->upper_dev;
757 if (netif_is_bridge_master(upper)) {
758 if (cu_info->linking)
759 return prestera_bridge_port_join(upper, port,
760 extack);
761 else
762 prestera_bridge_port_leave(upper, port);
763 } else if (netif_is_lag_master(upper)) {
764 if (cu_info->linking)
765 return prestera_lag_port_add(port, upper);
766 else
767 prestera_lag_port_del(port);
768 }
769 break;
770
771 case NETDEV_CHANGELOWERSTATE:
772 return prestera_netdev_port_lower_event(dev, event, ptr);
773 }
774
775 return 0;
776 }
777
prestera_netdevice_lag_event(struct net_device * lag_dev,unsigned long event,void * ptr)778 static int prestera_netdevice_lag_event(struct net_device *lag_dev,
779 unsigned long event, void *ptr)
780 {
781 struct net_device *dev;
782 struct list_head *iter;
783 int err;
784
785 netdev_for_each_lower_dev(lag_dev, dev, iter) {
786 if (prestera_netdev_check(dev)) {
787 err = prestera_netdev_port_event(lag_dev, dev, event,
788 ptr);
789 if (err)
790 return err;
791 }
792 }
793
794 return 0;
795 }
796
prestera_netdev_event_handler(struct notifier_block * nb,unsigned long event,void * ptr)797 static int prestera_netdev_event_handler(struct notifier_block *nb,
798 unsigned long event, void *ptr)
799 {
800 struct net_device *dev = netdev_notifier_info_to_dev(ptr);
801 int err = 0;
802
803 if (prestera_netdev_check(dev))
804 err = prestera_netdev_port_event(dev, dev, event, ptr);
805 else if (netif_is_lag_master(dev))
806 err = prestera_netdevice_lag_event(dev, event, ptr);
807
808 return notifier_from_errno(err);
809 }
810
prestera_netdev_event_handler_register(struct prestera_switch * sw)811 static int prestera_netdev_event_handler_register(struct prestera_switch *sw)
812 {
813 sw->netdev_nb.notifier_call = prestera_netdev_event_handler;
814
815 return register_netdevice_notifier(&sw->netdev_nb);
816 }
817
prestera_netdev_event_handler_unregister(struct prestera_switch * sw)818 static void prestera_netdev_event_handler_unregister(struct prestera_switch *sw)
819 {
820 unregister_netdevice_notifier(&sw->netdev_nb);
821 }
822
prestera_switch_init(struct prestera_switch * sw)823 static int prestera_switch_init(struct prestera_switch *sw)
824 {
825 int err;
826
827 err = prestera_hw_switch_init(sw);
828 if (err) {
829 dev_err(prestera_dev(sw), "Failed to init Switch device\n");
830 return err;
831 }
832
833 rwlock_init(&sw->port_list_lock);
834 INIT_LIST_HEAD(&sw->port_list);
835
836 err = prestera_switch_set_base_mac_addr(sw);
837 if (err)
838 return err;
839
840 err = prestera_netdev_event_handler_register(sw);
841 if (err)
842 return err;
843
844 err = prestera_switchdev_init(sw);
845 if (err)
846 goto err_swdev_register;
847
848 err = prestera_rxtx_switch_init(sw);
849 if (err)
850 goto err_rxtx_register;
851
852 err = prestera_event_handlers_register(sw);
853 if (err)
854 goto err_handlers_register;
855
856 err = prestera_acl_init(sw);
857 if (err)
858 goto err_acl_init;
859
860 err = prestera_span_init(sw);
861 if (err)
862 goto err_span_init;
863
864 err = prestera_devlink_register(sw);
865 if (err)
866 goto err_dl_register;
867
868 err = prestera_lag_init(sw);
869 if (err)
870 goto err_lag_init;
871
872 err = prestera_create_ports(sw);
873 if (err)
874 goto err_ports_create;
875
876 return 0;
877
878 err_ports_create:
879 prestera_lag_fini(sw);
880 err_lag_init:
881 prestera_devlink_unregister(sw);
882 err_dl_register:
883 prestera_span_fini(sw);
884 err_span_init:
885 prestera_acl_fini(sw);
886 err_acl_init:
887 prestera_event_handlers_unregister(sw);
888 err_handlers_register:
889 prestera_rxtx_switch_fini(sw);
890 err_rxtx_register:
891 prestera_switchdev_fini(sw);
892 err_swdev_register:
893 prestera_netdev_event_handler_unregister(sw);
894 prestera_hw_switch_fini(sw);
895
896 return err;
897 }
898
prestera_switch_fini(struct prestera_switch * sw)899 static void prestera_switch_fini(struct prestera_switch *sw)
900 {
901 prestera_destroy_ports(sw);
902 prestera_lag_fini(sw);
903 prestera_devlink_unregister(sw);
904 prestera_span_fini(sw);
905 prestera_acl_fini(sw);
906 prestera_event_handlers_unregister(sw);
907 prestera_rxtx_switch_fini(sw);
908 prestera_switchdev_fini(sw);
909 prestera_netdev_event_handler_unregister(sw);
910 prestera_hw_switch_fini(sw);
911 }
912
prestera_device_register(struct prestera_device * dev)913 int prestera_device_register(struct prestera_device *dev)
914 {
915 struct prestera_switch *sw;
916 int err;
917
918 sw = prestera_devlink_alloc(dev);
919 if (!sw)
920 return -ENOMEM;
921
922 dev->priv = sw;
923 sw->dev = dev;
924
925 err = prestera_switch_init(sw);
926 if (err) {
927 prestera_devlink_free(sw);
928 return err;
929 }
930
931 return 0;
932 }
933 EXPORT_SYMBOL(prestera_device_register);
934
prestera_device_unregister(struct prestera_device * dev)935 void prestera_device_unregister(struct prestera_device *dev)
936 {
937 struct prestera_switch *sw = dev->priv;
938
939 prestera_switch_fini(sw);
940 prestera_devlink_free(sw);
941 }
942 EXPORT_SYMBOL(prestera_device_unregister);
943
prestera_module_init(void)944 static int __init prestera_module_init(void)
945 {
946 prestera_wq = alloc_workqueue("prestera", 0, 0);
947 if (!prestera_wq)
948 return -ENOMEM;
949
950 return 0;
951 }
952
prestera_module_exit(void)953 static void __exit prestera_module_exit(void)
954 {
955 destroy_workqueue(prestera_wq);
956 }
957
958 module_init(prestera_module_init);
959 module_exit(prestera_module_exit);
960
961 MODULE_LICENSE("Dual BSD/GPL");
962 MODULE_DESCRIPTION("Marvell Prestera switch driver");
963