1 // SPDX-License-Identifier: GPL-2.0+
2
3 #include <linux/module.h>
4 #include <linux/regmap.h>
5 #include <linux/of_mdio.h>
6 #include <linux/if_bridge.h>
7 #include <linux/etherdevice.h>
8
9 #include "realtek.h"
10 #include "rtl83xx.h"
11
12 /**
13 * rtl83xx_lock() - Locks the mutex used by regmaps
14 * @ctx: realtek_priv pointer
15 *
16 * This function is passed to regmap to be used as the lock function.
17 * It is also used externally to block regmap before executing multiple
18 * operations that must happen in sequence (which will use
19 * realtek_priv.map_nolock instead).
20 *
21 * Context: Can sleep. Holds priv->map_lock lock.
22 * Return: nothing
23 */
rtl83xx_lock(void * ctx)24 void rtl83xx_lock(void *ctx)
25 {
26 struct realtek_priv *priv = ctx;
27
28 mutex_lock(&priv->map_lock);
29 }
30 EXPORT_SYMBOL_NS_GPL(rtl83xx_lock, "REALTEK_DSA");
31
32 /**
33 * rtl83xx_unlock() - Unlocks the mutex used by regmaps
34 * @ctx: realtek_priv pointer
35 *
36 * This function unlocks the lock acquired by rtl83xx_lock.
37 *
38 * Context: Releases priv->map_lock lock.
39 * Return: nothing
40 */
rtl83xx_unlock(void * ctx)41 void rtl83xx_unlock(void *ctx)
42 {
43 struct realtek_priv *priv = ctx;
44
45 mutex_unlock(&priv->map_lock);
46 }
47 EXPORT_SYMBOL_NS_GPL(rtl83xx_unlock, "REALTEK_DSA");
48
rtl83xx_user_mdio_read(struct mii_bus * bus,int addr,int regnum)49 static int rtl83xx_user_mdio_read(struct mii_bus *bus, int addr, int regnum)
50 {
51 struct realtek_priv *priv = bus->priv;
52
53 return priv->ops->phy_read(priv, addr, regnum);
54 }
55
rtl83xx_user_mdio_write(struct mii_bus * bus,int addr,int regnum,u16 val)56 static int rtl83xx_user_mdio_write(struct mii_bus *bus, int addr, int regnum,
57 u16 val)
58 {
59 struct realtek_priv *priv = bus->priv;
60
61 return priv->ops->phy_write(priv, addr, regnum, val);
62 }
63
64 /**
65 * rtl83xx_setup_user_mdio() - register the user mii bus driver
66 * @ds: DSA switch associated with this user_mii_bus
67 *
68 * Registers the MDIO bus for built-in Ethernet PHYs, and associates it with
69 * the mandatory 'mdio' child OF node of the switch.
70 *
71 * Context: Can sleep.
72 * Return: 0 on success, negative value for failure.
73 */
rtl83xx_setup_user_mdio(struct dsa_switch * ds)74 int rtl83xx_setup_user_mdio(struct dsa_switch *ds)
75 {
76 struct realtek_priv *priv = ds->priv;
77 struct device_node *mdio_np;
78 struct mii_bus *bus;
79 int ret = 0;
80
81 mdio_np = of_get_child_by_name(priv->dev->of_node, "mdio");
82 if (!mdio_np) {
83 dev_err(priv->dev, "no MDIO bus node\n");
84 return -ENODEV;
85 }
86
87 bus = devm_mdiobus_alloc(priv->dev);
88 if (!bus) {
89 ret = -ENOMEM;
90 goto err_put_node;
91 }
92
93 bus->priv = priv;
94 bus->name = "Realtek user MII";
95 bus->read = rtl83xx_user_mdio_read;
96 bus->write = rtl83xx_user_mdio_write;
97 snprintf(bus->id, MII_BUS_ID_SIZE, "%s:user_mii", dev_name(priv->dev));
98 bus->parent = priv->dev;
99
100 ret = devm_of_mdiobus_register(priv->dev, bus, mdio_np);
101 if (ret) {
102 dev_err(priv->dev, "unable to register MDIO bus %s\n",
103 bus->id);
104 goto err_put_node;
105 }
106
107 priv->user_mii_bus = bus;
108
109 err_put_node:
110 of_node_put(mdio_np);
111
112 return ret;
113 }
114 EXPORT_SYMBOL_NS_GPL(rtl83xx_setup_user_mdio, "REALTEK_DSA");
115
116 /**
117 * rtl83xx_probe() - probe a Realtek switch
118 * @dev: the device being probed
119 * @interface_info: specific management interface info.
120 *
121 * This function initializes realtek_priv and reads data from the device tree
122 * node. The switch is hard resetted if a method is provided.
123 *
124 * Context: Can sleep.
125 * Return: Pointer to the realtek_priv or ERR_PTR() in case of failure.
126 *
127 * The realtek_priv pointer does not need to be freed as it is controlled by
128 * devres.
129 */
130 struct realtek_priv *
rtl83xx_probe(struct device * dev,const struct realtek_interface_info * interface_info)131 rtl83xx_probe(struct device *dev,
132 const struct realtek_interface_info *interface_info)
133 {
134 const struct realtek_variant *var;
135 struct realtek_priv *priv;
136 struct regmap_config rc = {
137 .reg_bits = 10, /* A4..A0 R4..R0 */
138 .val_bits = 16,
139 .reg_stride = 1,
140 .max_register = 0xffff,
141 .reg_format_endian = REGMAP_ENDIAN_BIG,
142 .reg_read = interface_info->reg_read,
143 .reg_write = interface_info->reg_write,
144 .cache_type = REGCACHE_NONE,
145 .lock = rtl83xx_lock,
146 .unlock = rtl83xx_unlock,
147 };
148 int ret;
149
150 var = of_device_get_match_data(dev);
151 if (!var)
152 return ERR_PTR(-EINVAL);
153
154 priv = devm_kzalloc(dev, size_add(sizeof(*priv), var->chip_data_sz),
155 GFP_KERNEL);
156 if (!priv)
157 return ERR_PTR(-ENOMEM);
158
159 ret = devm_mutex_init(dev, &priv->map_lock);
160 if (ret)
161 return ERR_PTR(ret);
162
163 ret = devm_mutex_init(dev, &priv->vlan_lock);
164 if (ret)
165 return ERR_PTR(ret);
166
167 ret = devm_mutex_init(dev, &priv->l2_lock);
168 if (ret)
169 return ERR_PTR(ret);
170
171 rc.lock_arg = priv;
172 priv->map = devm_regmap_init(dev, NULL, priv, &rc);
173 if (IS_ERR(priv->map)) {
174 ret = PTR_ERR(priv->map);
175 dev_err(dev, "regmap init failed: %d\n", ret);
176 return ERR_PTR(ret);
177 }
178
179 rc.disable_locking = true;
180 priv->map_nolock = devm_regmap_init(dev, NULL, priv, &rc);
181 if (IS_ERR(priv->map_nolock)) {
182 ret = PTR_ERR(priv->map_nolock);
183 dev_err(dev, "regmap init failed: %d\n", ret);
184 return ERR_PTR(ret);
185 }
186
187 /* Link forward and backward */
188 priv->dev = dev;
189 priv->variant = var;
190 priv->ops = var->ops;
191 priv->chip_data = (void *)priv + sizeof(*priv);
192
193 spin_lock_init(&priv->lock);
194
195 priv->leds_disabled = of_property_read_bool(dev->of_node,
196 "realtek,disable-leds");
197
198 /* TODO: if power is software controlled, set up any regulators here */
199 priv->reset_ctl = devm_reset_control_get_optional(dev, NULL);
200 if (IS_ERR(priv->reset_ctl))
201 return dev_err_cast_probe(dev, priv->reset_ctl,
202 "failed to get reset control\n");
203
204 priv->reset = devm_gpiod_get_optional(dev, "reset", GPIOD_OUT_LOW);
205 if (IS_ERR(priv->reset)) {
206 dev_err(dev, "failed to get RESET GPIO\n");
207 return ERR_CAST(priv->reset);
208 }
209
210 dev_set_drvdata(dev, priv);
211
212 if (priv->reset_ctl || priv->reset) {
213 rtl83xx_reset_assert(priv);
214 dev_dbg(dev, "asserted RESET\n");
215 msleep(REALTEK_HW_STOP_DELAY);
216 rtl83xx_reset_deassert(priv);
217 msleep(REALTEK_HW_START_DELAY);
218 dev_dbg(dev, "deasserted RESET\n");
219 }
220
221 return priv;
222 }
223 EXPORT_SYMBOL_NS_GPL(rtl83xx_probe, "REALTEK_DSA");
224
225 /**
226 * rtl83xx_register_switch() - detects and register a switch
227 * @priv: realtek_priv pointer
228 *
229 * This function first checks the switch chip ID and register a DSA
230 * switch.
231 *
232 * Context: Can sleep. Takes and releases priv->map_lock.
233 * Return: 0 on success, negative value for failure.
234 */
rtl83xx_register_switch(struct realtek_priv * priv)235 int rtl83xx_register_switch(struct realtek_priv *priv)
236 {
237 struct dsa_switch *ds = &priv->ds;
238 int ret;
239
240 ret = priv->ops->detect(priv);
241 if (ret) {
242 dev_err_probe(priv->dev, ret, "unable to detect switch\n");
243 return ret;
244 }
245
246 ds->priv = priv;
247 ds->dev = priv->dev;
248 ds->ops = priv->variant->ds_ops;
249 ds->phylink_mac_ops = priv->variant->phylink_mac_ops;
250 ds->num_ports = priv->num_ports;
251
252 ret = dsa_register_switch(ds);
253 if (ret) {
254 dev_err_probe(priv->dev, ret, "unable to register switch\n");
255 return ret;
256 }
257
258 return 0;
259 }
260 EXPORT_SYMBOL_NS_GPL(rtl83xx_register_switch, "REALTEK_DSA");
261
262 /**
263 * rtl83xx_unregister_switch() - unregister a switch
264 * @priv: realtek_priv pointer
265 *
266 * This function unregister a DSA switch.
267 *
268 * Context: Can sleep.
269 * Return: Nothing.
270 */
rtl83xx_unregister_switch(struct realtek_priv * priv)271 void rtl83xx_unregister_switch(struct realtek_priv *priv)
272 {
273 struct dsa_switch *ds = &priv->ds;
274
275 dsa_unregister_switch(ds);
276 }
277 EXPORT_SYMBOL_NS_GPL(rtl83xx_unregister_switch, "REALTEK_DSA");
278
279 /**
280 * rtl83xx_shutdown() - shutdown a switch
281 * @priv: realtek_priv pointer
282 *
283 * This function shuts down the DSA switch and cleans the platform driver data,
284 * to prevent realtek_{smi,mdio}_remove() from running afterwards, which is
285 * possible if the parent bus implements its own .shutdown() as .remove().
286 *
287 * Context: Can sleep.
288 * Return: Nothing.
289 */
rtl83xx_shutdown(struct realtek_priv * priv)290 void rtl83xx_shutdown(struct realtek_priv *priv)
291 {
292 struct dsa_switch *ds = &priv->ds;
293
294 dsa_switch_shutdown(ds);
295
296 dev_set_drvdata(priv->dev, NULL);
297 }
298 EXPORT_SYMBOL_NS_GPL(rtl83xx_shutdown, "REALTEK_DSA");
299
300 /**
301 * rtl83xx_remove() - Cleanup a realtek switch driver
302 * @priv: realtek_priv pointer
303 *
304 * Placehold for common cleanup procedures.
305 *
306 * Context: Any
307 * Return: nothing
308 */
rtl83xx_remove(struct realtek_priv * priv)309 void rtl83xx_remove(struct realtek_priv *priv)
310 {
311 }
312 EXPORT_SYMBOL_NS_GPL(rtl83xx_remove, "REALTEK_DSA");
313
rtl83xx_reset_assert(struct realtek_priv * priv)314 void rtl83xx_reset_assert(struct realtek_priv *priv)
315 {
316 int ret;
317
318 ret = reset_control_assert(priv->reset_ctl);
319 if (ret)
320 dev_warn(priv->dev,
321 "Failed to assert the switch reset control: %pe\n",
322 ERR_PTR(ret));
323
324 gpiod_set_value_cansleep(priv->reset, true);
325 }
326
rtl83xx_reset_deassert(struct realtek_priv * priv)327 void rtl83xx_reset_deassert(struct realtek_priv *priv)
328 {
329 int ret;
330
331 ret = reset_control_deassert(priv->reset_ctl);
332 if (ret)
333 dev_warn(priv->dev,
334 "Failed to deassert the switch reset control: %pe\n",
335 ERR_PTR(ret));
336
337 gpiod_set_value_cansleep(priv->reset, false);
338 }
339
340 /**
341 * rtl83xx_port_bridge_join() - join a port to a bridge
342 * @ds: DSA switch instance
343 * @port: port index
344 * @bridge: bridge being joined
345 * @tx_forward_offload: if the switch can offload TX forwarding
346 * @extack: netlink extended ack for reporting errors
347 *
348 * This function handles joining a port to a bridge. It updates the port
349 * isolation masks and EFID.
350 *
351 * Context: Can sleep.
352 * Return: 0 on success, negative value for failure.
353 */
rtl83xx_port_bridge_join(struct dsa_switch * ds,int port,struct dsa_bridge bridge,bool * tx_forward_offload,struct netlink_ext_ack * extack)354 int rtl83xx_port_bridge_join(struct dsa_switch *ds, int port,
355 struct dsa_bridge bridge,
356 bool *tx_forward_offload,
357 struct netlink_ext_ack *extack)
358 {
359 struct realtek_priv *priv = ds->priv;
360 struct dsa_port *dp;
361 u32 mask = 0;
362 int ret;
363
364 if (!priv->ops->port_add_isolation)
365 return -EOPNOTSUPP;
366
367 dev_dbg(priv->dev, "bridge %d join port %d\n", bridge.num, port);
368
369 /* Add this port to the isolation group of every other port
370 * offloading this bridge.
371 */
372 dsa_switch_for_each_user_port(dp, ds) {
373 /* Handle this port after */
374 if (dp->index == port)
375 continue;
376
377 /* Skip ports that are not in this bridge */
378 if (!dsa_port_offloads_bridge(dp, &bridge))
379 continue;
380
381 ret = priv->ops->port_add_isolation(priv, dp->index, BIT(port));
382 if (ret)
383 goto undo_isolation;
384
385 mask |= BIT(dp->index);
386 }
387
388 /* If we support cascade switches, it should also include the
389 * downstream DSA ports to the isolation group.
390 */
391
392 /* Add those ports to the isolation group of this port */
393 ret = priv->ops->port_add_isolation(priv, port, mask);
394 if (ret)
395 goto undo_isolation;
396
397 /* Use the bridge number as the EFID for this port */
398 if (priv->ops->port_set_efid) {
399 ret = priv->ops->port_set_efid(priv, port, bridge.num);
400 if (ret)
401 goto undo_self_isolation;
402 }
403
404 if (priv->ops->port_set_learning) {
405 ret = priv->ops->port_set_learning(priv, port, true);
406 if (ret)
407 goto undo_efid;
408 }
409
410 return 0;
411
412 undo_efid:
413 if (priv->ops->port_set_efid)
414 priv->ops->port_set_efid(priv, port, 0);
415
416 undo_self_isolation:
417 priv->ops->port_remove_isolation(priv, port, mask);
418
419 undo_isolation:
420 dsa_switch_for_each_port(dp, ds) {
421 if (mask & BIT(dp->index))
422 priv->ops->port_remove_isolation(priv, dp->index,
423 BIT(port));
424 }
425
426 return ret;
427 }
428 EXPORT_SYMBOL_NS_GPL(rtl83xx_port_bridge_join, "REALTEK_DSA");
429
430 /**
431 * rtl83xx_port_bridge_leave() - leave a bridge
432 * @ds: DSA switch instance
433 * @port: port index
434 * @bridge: bridge being left
435 *
436 * This function handles removing a port from a bridge. It updates the port
437 * isolation masks and EFID.
438 *
439 * Context: Can sleep.
440 * Return: nothing
441 */
rtl83xx_port_bridge_leave(struct dsa_switch * ds,int port,struct dsa_bridge bridge)442 void rtl83xx_port_bridge_leave(struct dsa_switch *ds, int port,
443 struct dsa_bridge bridge)
444 {
445 struct realtek_priv *priv = ds->priv;
446 struct dsa_port *dp;
447 u32 mask = 0;
448 int ret;
449
450 if (!priv->ops->port_remove_isolation)
451 return;
452
453 dev_dbg(priv->dev, "bridge %d leave port %d\n", bridge.num, port);
454
455 /* Remove this port from the isolation group of every other
456 * port offloading this bridge.
457 */
458 dsa_switch_for_each_user_port(dp, ds) {
459 /* Handle this port after */
460 if (dp->index == port)
461 continue;
462
463 /* Skip ports that are not in this bridge */
464 if (!dsa_port_offloads_bridge(dp, &bridge))
465 continue;
466
467 ret = priv->ops->port_remove_isolation(priv, dp->index,
468 BIT(port));
469 if (ret)
470 dev_err(priv->dev,
471 "failed to isolate port %d from port %d: %pe\n",
472 port, dp->index, ERR_PTR(ret));
473
474 mask |= BIT(dp->index);
475 }
476
477 /* If we support cascade switches, it should also exclude the
478 * downstream DSA ports from the isolation group.
479 */
480
481 if (priv->ops->port_set_learning) {
482 ret = priv->ops->port_set_learning(priv, port, false);
483 if (ret)
484 dev_err(priv->dev,
485 "failed to disable learning on port %d: %pe\n",
486 port, ERR_PTR(ret));
487 }
488
489 /* Remove those ports from the isolation group of this port */
490 ret = priv->ops->port_remove_isolation(priv, port, mask);
491 if (ret)
492 dev_err(priv->dev,
493 "failed to remove isolation mask from port %d: %pe\n",
494 port, ERR_PTR(ret));
495
496 /* Revert to the default EFID 0 for standalone mode */
497 if (priv->ops->port_set_efid) {
498 ret = priv->ops->port_set_efid(priv, port, 0);
499 if (ret)
500 dev_err(priv->dev,
501 "failed to clear EFID on port %d: %pe\n",
502 port, ERR_PTR(ret));
503 }
504 }
505 EXPORT_SYMBOL_NS_GPL(rtl83xx_port_bridge_leave, "REALTEK_DSA");
506
507 /**
508 * rtl83xx_port_fast_age() - flush dynamic FDB entries learned on a port
509 * @ds: DSA switch instance
510 * @port: port index
511 *
512 * This function requests the switch to age out dynamic FDB entries learned on
513 * @port.
514 *
515 * Context: Can sleep.
516 * Return: Nothing.
517 */
rtl83xx_port_fast_age(struct dsa_switch * ds,int port)518 void rtl83xx_port_fast_age(struct dsa_switch *ds, int port)
519 {
520 struct realtek_priv *priv = ds->priv;
521 int ret;
522
523 if (!priv->ops->l2_flush) {
524 dev_warn_once(priv->dev, "l2_flush op not defined\n");
525 return;
526 }
527
528 dev_dbg(priv->dev, "fast_age port %d\n", port);
529
530 mutex_lock(&priv->l2_lock);
531 ret = priv->ops->l2_flush(priv, port, 0);
532 mutex_unlock(&priv->l2_lock);
533 if (ret)
534 dev_err(priv->dev, "failed to fast age on port %d: %d\n", port,
535 ret);
536 }
537 EXPORT_SYMBOL_NS_GPL(rtl83xx_port_fast_age, "REALTEK_DSA");
538
539 /**
540 * rtl83xx_port_fdb_add() - add a static FDB entry to a port database
541 * @ds: DSA switch instance
542 * @port: port index
543 * @addr: MAC address to add
544 * @vid: VLAN ID associated with @addr
545 * @db: database where the entry should be added
546 *
547 * This function adds a static unicast FDB entry to the standalone port
548 * database or to a bridge database.
549 *
550 * Context: Can sleep.
551 * Return: 0 on success, negative value for failure.
552 */
rtl83xx_port_fdb_add(struct dsa_switch * ds,int port,const unsigned char * addr,u16 vid,struct dsa_db db)553 int rtl83xx_port_fdb_add(struct dsa_switch *ds, int port,
554 const unsigned char *addr, u16 vid,
555 struct dsa_db db)
556 {
557 struct realtek_priv *priv = ds->priv;
558 int efid;
559 int ret;
560
561 if (is_multicast_ether_addr(addr))
562 return -EOPNOTSUPP;
563
564 if (!priv->ops->l2_add_uc)
565 return -EOPNOTSUPP;
566
567 if (db.type != DSA_DB_PORT && db.type != DSA_DB_BRIDGE)
568 return -EOPNOTSUPP;
569
570 /* Bridge ports use bridge.num as EFID, while standalone ports use
571 * EFID 0. FDB entries for the CPU port follow the bridge EFID due
572 * to assisted learning.
573 */
574 efid = db.type == DSA_DB_BRIDGE ? db.bridge.num : 0;
575
576 dev_dbg(priv->dev, "%s: port:%d addr:%pM efid:%d vid:%d dbtype:%d\n",
577 __func__, port, addr, efid, vid, db.type);
578
579 mutex_lock(&priv->l2_lock);
580 ret = priv->ops->l2_add_uc(priv, port, addr, efid, vid);
581
582 mutex_unlock(&priv->l2_lock);
583
584 if (ret)
585 dev_err(priv->dev, "fdb_add ERROR %pe\n", ERR_PTR(ret));
586 return ret;
587 }
588 EXPORT_SYMBOL_NS_GPL(rtl83xx_port_fdb_add, "REALTEK_DSA");
589
590 /**
591 * rtl83xx_port_fdb_del() - delete a static FDB entry from a port database
592 * @ds: DSA switch instance
593 * @port: port index
594 * @addr: MAC address to delete
595 * @vid: VLAN ID associated with @addr
596 * @db: database where the entry should be removed
597 *
598 * This function deletes a static unicast FDB entry from the standalone port
599 * database or from a bridge database.
600 *
601 * Context: Can sleep.
602 * Return: 0 on success, negative value for failure.
603 */
rtl83xx_port_fdb_del(struct dsa_switch * ds,int port,const unsigned char * addr,u16 vid,struct dsa_db db)604 int rtl83xx_port_fdb_del(struct dsa_switch *ds, int port,
605 const unsigned char *addr, u16 vid,
606 struct dsa_db db)
607 {
608 struct realtek_priv *priv = ds->priv;
609 int efid;
610 int ret;
611
612 if (is_multicast_ether_addr(addr))
613 return -EOPNOTSUPP;
614
615 if (!priv->ops->l2_del_uc)
616 return -EOPNOTSUPP;
617
618 if (db.type != DSA_DB_PORT && db.type != DSA_DB_BRIDGE)
619 return -EOPNOTSUPP;
620
621 /*
622 * DSA_DB_BRIDGE ports use bridge number [1..N] as EFID, while
623 * DSA_DB_PORT use the default EFID (0), not used by any bridge.
624 */
625 efid = db.type == DSA_DB_BRIDGE ? db.bridge.num : 0;
626
627 dev_dbg(priv->dev, "%s: port:%d addr:%pM efid:%d vid:%d dbtype:%d\n",
628 __func__, port, addr, efid, vid, db.type);
629
630 mutex_lock(&priv->l2_lock);
631 ret = priv->ops->l2_del_uc(priv, port, addr, efid, vid);
632 mutex_unlock(&priv->l2_lock);
633
634 if (ret)
635 dev_err(priv->dev, "fdb_del ERROR %pe\n", ERR_PTR(ret));
636 return ret;
637 }
638 EXPORT_SYMBOL_NS_GPL(rtl83xx_port_fdb_del, "REALTEK_DSA");
639
640 /**
641 * rtl83xx_port_fdb_dump() - iterate over FDB entries associated with a port
642 * @ds: DSA switch instance
643 * @port: port index
644 * @cb: callback invoked for each entry
645 * @data: opaque pointer passed to @cb
646 *
647 * This function walks the unicast FDB entries associated with @port and calls
648 * @cb for each matching entry.
649 *
650 * Context: Can sleep.
651 * Return: 0 on success, or negative value for failure.
652 */
rtl83xx_port_fdb_dump(struct dsa_switch * ds,int port,dsa_fdb_dump_cb_t * cb,void * data)653 int rtl83xx_port_fdb_dump(struct dsa_switch *ds, int port,
654 dsa_fdb_dump_cb_t *cb, void *data)
655 {
656 struct realtek_fdb_entry entry = { 0 };
657 struct realtek_priv *priv = ds->priv;
658 u16 start_addr, addr = 0;
659 int ret = 0;
660
661 if (!priv->ops->l2_get_next_uc)
662 return -EOPNOTSUPP;
663
664 mutex_lock(&priv->l2_lock);
665 while (true) {
666 start_addr = addr;
667
668 dev_dbg(priv->dev, "l2_get_next_uc, addr:%d, port:%d\n",
669 addr, port);
670 ret = priv->ops->l2_get_next_uc(priv, &addr, port, &entry);
671 dev_dbg(priv->dev,
672 "%s addr:%d mac:%pM vid:%d static:%d ret:%pe\n",
673 __func__, addr, entry.mac_addr, entry.vid,
674 entry.is_static, ERR_PTR(ret));
675
676 if (ret == -ENOENT) {
677 /* If the table is empty, returns without errors. Note
678 * that the l2_get_next_uc overflow to the first match
679 * when it reaches the end of the table.
680 */
681 ret = 0;
682 break;
683 }
684
685 if (ret)
686 break;
687
688 /* When the addr returned is before the requested one, it
689 * indicates that we reached the end.
690 */
691 if (addr < start_addr)
692 break;
693
694 ret = cb(entry.mac_addr, entry.vid, entry.is_static, data);
695 if (ret)
696 break;
697
698 addr++;
699 }
700 mutex_unlock(&priv->l2_lock);
701
702 return ret;
703 }
704 EXPORT_SYMBOL_NS_GPL(rtl83xx_port_fdb_dump, "REALTEK_DSA");
705
706 /**
707 * rtl83xx_port_mdb_add() - add a multicast database entry to a port database
708 * @ds: DSA switch instance
709 * @port: port index
710 * @mdb: multicast database entry to add
711 * @db: database where the entry should be added
712 *
713 * This function adds a multicast database entry to the standalone port
714 * database or to a bridge database.
715 *
716 * Context: Can sleep.
717 * Return: 0 on success, negative value for failure.
718 */
rtl83xx_port_mdb_add(struct dsa_switch * ds,int port,const struct switchdev_obj_port_mdb * mdb,struct dsa_db db)719 int rtl83xx_port_mdb_add(struct dsa_switch *ds, int port,
720 const struct switchdev_obj_port_mdb *mdb,
721 struct dsa_db db)
722 {
723 struct realtek_priv *priv = ds->priv;
724 const unsigned char *addr = mdb->addr;
725 u16 vid = mdb->vid;
726 int efid;
727 int ret;
728
729 if (!priv->ops->l2_add_mc)
730 return -EOPNOTSUPP;
731
732 if (db.type != DSA_DB_PORT && db.type != DSA_DB_BRIDGE)
733 return -EOPNOTSUPP;
734
735 /* EFID is not used by hardware MDB entries; debugging only */
736 efid = db.type == DSA_DB_BRIDGE ? db.bridge.num : 0;
737
738 dev_dbg(priv->dev, "%s: port:%d addr:%pM efid:%d vid:%d dbtype:%d\n",
739 __func__, port, addr, efid, vid, db.type);
740
741 mutex_lock(&priv->l2_lock);
742 ret = priv->ops->l2_add_mc(priv, port, addr, vid);
743 mutex_unlock(&priv->l2_lock);
744
745 if (ret)
746 dev_err(priv->dev, "mdb_add ERROR %pe\n", ERR_PTR(ret));
747 return ret;
748 }
749 EXPORT_SYMBOL_NS_GPL(rtl83xx_port_mdb_add, "REALTEK_DSA");
750
751 /**
752 * rtl83xx_port_mdb_del() - delete a multicast database entry from a port
753 * database
754 * @ds: DSA switch instance
755 * @port: port index
756 * @mdb: multicast database entry to delete
757 * @db: database where the entry should be removed
758 *
759 * This function deletes a multicast database entry from the standalone port
760 * database or from a bridge database.
761 *
762 * Context: Can sleep.
763 * Return: 0 on success, negative value for failure.
764 */
rtl83xx_port_mdb_del(struct dsa_switch * ds,int port,const struct switchdev_obj_port_mdb * mdb,struct dsa_db db)765 int rtl83xx_port_mdb_del(struct dsa_switch *ds, int port,
766 const struct switchdev_obj_port_mdb *mdb,
767 struct dsa_db db)
768 {
769 struct realtek_priv *priv = ds->priv;
770 const unsigned char *addr = mdb->addr;
771 u16 vid = mdb->vid;
772 int efid;
773 int ret;
774
775 if (!priv->ops->l2_del_mc)
776 return -EOPNOTSUPP;
777
778 if (db.type != DSA_DB_PORT && db.type != DSA_DB_BRIDGE)
779 return -EOPNOTSUPP;
780
781 /* EFID is not used by hardware MDB entries; debugging only */
782 efid = db.type == DSA_DB_BRIDGE ? db.bridge.num : 0;
783
784 dev_dbg(priv->dev, "%s: port:%d addr:%pM efid:%d vid:%d dbtype:%d\n",
785 __func__, port, addr, efid, vid, db.type);
786
787 mutex_lock(&priv->l2_lock);
788 ret = priv->ops->l2_del_mc(priv, port, addr, vid);
789 mutex_unlock(&priv->l2_lock);
790
791 if (ret)
792 dev_err(priv->dev, "mdb_del ERROR %pe\n", ERR_PTR(ret));
793 return ret;
794 }
795 EXPORT_SYMBOL_NS_GPL(rtl83xx_port_mdb_del, "REALTEK_DSA");
796
797 /**
798 * rtl83xx_port_bridge_flags() - set port bridge flags
799 * @ds: DSA switch instance
800 * @port: port index
801 * @flags: bridge port flags
802 * @extack: netlink extended ack for reporting errors
803 *
804 * This function handles setting bridge port flags like learning and flooding.
805 *
806 * Context: Can sleep.
807 * Return: 0 on success, negative value for failure.
808 */
rtl83xx_port_bridge_flags(struct dsa_switch * ds,int port,struct switchdev_brport_flags flags,struct netlink_ext_ack * extack)809 int rtl83xx_port_bridge_flags(struct dsa_switch *ds, int port,
810 struct switchdev_brport_flags flags,
811 struct netlink_ext_ack *extack)
812 {
813 struct realtek_priv *priv = ds->priv;
814 bool enable;
815 int ret;
816
817 if (flags.mask & BR_LEARNING) {
818 if (!priv->ops->port_set_learning)
819 return -EOPNOTSUPP;
820
821 enable = !!(flags.val & BR_LEARNING);
822 ret = priv->ops->port_set_learning(priv, port, enable);
823 if (ret)
824 return ret;
825 }
826
827 if (flags.mask & BR_FLOOD) {
828 if (!priv->ops->port_set_ucast_flood)
829 return -EOPNOTSUPP;
830
831 enable = !!(flags.val & BR_FLOOD);
832 ret = priv->ops->port_set_ucast_flood(priv, port, enable);
833 if (ret)
834 return ret;
835 }
836
837 if (flags.mask & BR_MCAST_FLOOD) {
838 if (!priv->ops->port_set_mcast_flood)
839 return -EOPNOTSUPP;
840
841 enable = !!(flags.val & BR_MCAST_FLOOD);
842 ret = priv->ops->port_set_mcast_flood(priv, port, enable);
843 if (ret)
844 return ret;
845 }
846
847 if (flags.mask & BR_BCAST_FLOOD) {
848 if (!priv->ops->port_set_bcast_flood)
849 return -EOPNOTSUPP;
850
851 enable = !!(flags.val & BR_BCAST_FLOOD);
852 ret = priv->ops->port_set_bcast_flood(priv, port, enable);
853 if (ret)
854 return ret;
855 }
856
857 return 0;
858 }
859 EXPORT_SYMBOL_NS_GPL(rtl83xx_port_bridge_flags, "REALTEK_DSA");
860
861 /**
862 * rtl83xx_setup_port_flood_control() - setup default flood control for a port
863 * @priv: realtek_priv pointer
864 * @port: port index
865 *
866 * This function enables flooding for a given port.
867 *
868 * Context: Can sleep.
869 * Return: 0 on success, negative value for failure.
870 */
rtl83xx_setup_port_flood_control(struct realtek_priv * priv,int port)871 int rtl83xx_setup_port_flood_control(struct realtek_priv *priv, int port)
872 {
873 int ret;
874
875 if (priv->ops->port_set_ucast_flood) {
876 ret = priv->ops->port_set_ucast_flood(priv, port, true);
877 if (ret)
878 return ret;
879 }
880
881 if (priv->ops->port_set_mcast_flood) {
882 ret = priv->ops->port_set_mcast_flood(priv, port, true);
883 if (ret)
884 return ret;
885 }
886
887 if (priv->ops->port_set_bcast_flood) {
888 ret = priv->ops->port_set_bcast_flood(priv, port, true);
889 if (ret)
890 return ret;
891 }
892
893 return 0;
894 }
895 EXPORT_SYMBOL_NS_GPL(rtl83xx_setup_port_flood_control, "REALTEK_DSA");
896
897 MODULE_AUTHOR("Luiz Angelo Daros de Luca <luizluca@gmail.com>");
898 MODULE_AUTHOR("Linus Walleij <linus.walleij@linaro.org>");
899 MODULE_DESCRIPTION("Realtek DSA switches common module");
900 MODULE_LICENSE("GPL");
901