xref: /linux/drivers/net/dsa/realtek/rtl83xx.c (revision 91ec2035134982b98fab0609a9fd8480e8217dc1)
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