xref: /openbmc/linux/net/dsa/port.c (revision d003d772)
1 /*
2  * Handling of a single switch port
3  *
4  * Copyright (c) 2017 Savoir-faire Linux Inc.
5  *	Vivien Didelot <vivien.didelot@savoirfairelinux.com>
6  *
7  * This program is free software; you can redistribute it and/or modify
8  * it under the terms of the GNU General Public License as published by
9  * the Free Software Foundation; either version 2 of the License, or
10  * (at your option) any later version.
11  */
12 
13 #include <linux/if_bridge.h>
14 #include <linux/notifier.h>
15 #include <linux/of_mdio.h>
16 #include <linux/of_net.h>
17 
18 #include "dsa_priv.h"
19 
20 static int dsa_port_notify(const struct dsa_port *dp, unsigned long e, void *v)
21 {
22 	struct raw_notifier_head *nh = &dp->ds->dst->nh;
23 	int err;
24 
25 	err = raw_notifier_call_chain(nh, e, v);
26 
27 	return notifier_to_errno(err);
28 }
29 
30 int dsa_port_set_state(struct dsa_port *dp, u8 state,
31 		       struct switchdev_trans *trans)
32 {
33 	struct dsa_switch *ds = dp->ds;
34 	int port = dp->index;
35 
36 	if (switchdev_trans_ph_prepare(trans))
37 		return ds->ops->port_stp_state_set ? 0 : -EOPNOTSUPP;
38 
39 	if (ds->ops->port_stp_state_set)
40 		ds->ops->port_stp_state_set(ds, port, state);
41 
42 	if (ds->ops->port_fast_age) {
43 		/* Fast age FDB entries or flush appropriate forwarding database
44 		 * for the given port, if we are moving it from Learning or
45 		 * Forwarding state, to Disabled or Blocking or Listening state.
46 		 */
47 
48 		if ((dp->stp_state == BR_STATE_LEARNING ||
49 		     dp->stp_state == BR_STATE_FORWARDING) &&
50 		    (state == BR_STATE_DISABLED ||
51 		     state == BR_STATE_BLOCKING ||
52 		     state == BR_STATE_LISTENING))
53 			ds->ops->port_fast_age(ds, port);
54 	}
55 
56 	dp->stp_state = state;
57 
58 	return 0;
59 }
60 
61 static void dsa_port_set_state_now(struct dsa_port *dp, u8 state)
62 {
63 	int err;
64 
65 	err = dsa_port_set_state(dp, state, NULL);
66 	if (err)
67 		pr_err("DSA: failed to set STP state %u (%d)\n", state, err);
68 }
69 
70 int dsa_port_enable(struct dsa_port *dp, struct phy_device *phy)
71 {
72 	struct dsa_switch *ds = dp->ds;
73 	int port = dp->index;
74 	int err;
75 
76 	if (ds->ops->port_enable) {
77 		err = ds->ops->port_enable(ds, port, phy);
78 		if (err)
79 			return err;
80 	}
81 
82 	if (!dp->bridge_dev)
83 		dsa_port_set_state_now(dp, BR_STATE_FORWARDING);
84 
85 	return 0;
86 }
87 
88 void dsa_port_disable(struct dsa_port *dp)
89 {
90 	struct dsa_switch *ds = dp->ds;
91 	int port = dp->index;
92 
93 	if (!dp->bridge_dev)
94 		dsa_port_set_state_now(dp, BR_STATE_DISABLED);
95 
96 	if (ds->ops->port_disable)
97 		ds->ops->port_disable(ds, port);
98 }
99 
100 int dsa_port_bridge_join(struct dsa_port *dp, struct net_device *br)
101 {
102 	struct dsa_notifier_bridge_info info = {
103 		.sw_index = dp->ds->index,
104 		.port = dp->index,
105 		.br = br,
106 	};
107 	int err;
108 
109 	/* Set the flooding mode before joining the port in the switch */
110 	err = dsa_port_bridge_flags(dp, BR_FLOOD | BR_MCAST_FLOOD, NULL);
111 	if (err)
112 		return err;
113 
114 	/* Here the interface is already bridged. Reflect the current
115 	 * configuration so that drivers can program their chips accordingly.
116 	 */
117 	dp->bridge_dev = br;
118 
119 	err = dsa_port_notify(dp, DSA_NOTIFIER_BRIDGE_JOIN, &info);
120 
121 	/* The bridging is rolled back on error */
122 	if (err) {
123 		dsa_port_bridge_flags(dp, 0, NULL);
124 		dp->bridge_dev = NULL;
125 	}
126 
127 	return err;
128 }
129 
130 void dsa_port_bridge_leave(struct dsa_port *dp, struct net_device *br)
131 {
132 	struct dsa_notifier_bridge_info info = {
133 		.sw_index = dp->ds->index,
134 		.port = dp->index,
135 		.br = br,
136 	};
137 	int err;
138 
139 	/* Here the port is already unbridged. Reflect the current configuration
140 	 * so that drivers can program their chips accordingly.
141 	 */
142 	dp->bridge_dev = NULL;
143 
144 	err = dsa_port_notify(dp, DSA_NOTIFIER_BRIDGE_LEAVE, &info);
145 	if (err)
146 		pr_err("DSA: failed to notify DSA_NOTIFIER_BRIDGE_LEAVE\n");
147 
148 	/* Port is leaving the bridge, disable flooding */
149 	dsa_port_bridge_flags(dp, 0, NULL);
150 
151 	/* Port left the bridge, put in BR_STATE_DISABLED by the bridge layer,
152 	 * so allow it to be in BR_STATE_FORWARDING to be kept functional
153 	 */
154 	dsa_port_set_state_now(dp, BR_STATE_FORWARDING);
155 }
156 
157 int dsa_port_vlan_filtering(struct dsa_port *dp, bool vlan_filtering,
158 			    struct switchdev_trans *trans)
159 {
160 	struct dsa_switch *ds = dp->ds;
161 
162 	/* bridge skips -EOPNOTSUPP, so skip the prepare phase */
163 	if (switchdev_trans_ph_prepare(trans))
164 		return 0;
165 
166 	if (ds->ops->port_vlan_filtering)
167 		return ds->ops->port_vlan_filtering(ds, dp->index,
168 						    vlan_filtering);
169 
170 	return 0;
171 }
172 
173 int dsa_port_ageing_time(struct dsa_port *dp, clock_t ageing_clock,
174 			 struct switchdev_trans *trans)
175 {
176 	unsigned long ageing_jiffies = clock_t_to_jiffies(ageing_clock);
177 	unsigned int ageing_time = jiffies_to_msecs(ageing_jiffies);
178 	struct dsa_notifier_ageing_time_info info = {
179 		.ageing_time = ageing_time,
180 		.trans = trans,
181 	};
182 
183 	if (switchdev_trans_ph_prepare(trans))
184 		return dsa_port_notify(dp, DSA_NOTIFIER_AGEING_TIME, &info);
185 
186 	dp->ageing_time = ageing_time;
187 
188 	return dsa_port_notify(dp, DSA_NOTIFIER_AGEING_TIME, &info);
189 }
190 
191 int dsa_port_pre_bridge_flags(const struct dsa_port *dp, unsigned long flags,
192 			      struct switchdev_trans *trans)
193 {
194 	struct dsa_switch *ds = dp->ds;
195 
196 	if (!ds->ops->port_egress_floods ||
197 	    (flags & ~(BR_FLOOD | BR_MCAST_FLOOD)))
198 		return -EINVAL;
199 
200 	return 0;
201 }
202 
203 int dsa_port_bridge_flags(const struct dsa_port *dp, unsigned long flags,
204 			  struct switchdev_trans *trans)
205 {
206 	struct dsa_switch *ds = dp->ds;
207 	int port = dp->index;
208 	int err = 0;
209 
210 	if (switchdev_trans_ph_prepare(trans))
211 		return 0;
212 
213 	if (ds->ops->port_egress_floods)
214 		err = ds->ops->port_egress_floods(ds, port, flags & BR_FLOOD,
215 						  flags & BR_MCAST_FLOOD);
216 
217 	return err;
218 }
219 
220 int dsa_port_fdb_add(struct dsa_port *dp, const unsigned char *addr,
221 		     u16 vid)
222 {
223 	struct dsa_notifier_fdb_info info = {
224 		.sw_index = dp->ds->index,
225 		.port = dp->index,
226 		.addr = addr,
227 		.vid = vid,
228 	};
229 
230 	return dsa_port_notify(dp, DSA_NOTIFIER_FDB_ADD, &info);
231 }
232 
233 int dsa_port_fdb_del(struct dsa_port *dp, const unsigned char *addr,
234 		     u16 vid)
235 {
236 	struct dsa_notifier_fdb_info info = {
237 		.sw_index = dp->ds->index,
238 		.port = dp->index,
239 		.addr = addr,
240 		.vid = vid,
241 
242 	};
243 
244 	return dsa_port_notify(dp, DSA_NOTIFIER_FDB_DEL, &info);
245 }
246 
247 int dsa_port_fdb_dump(struct dsa_port *dp, dsa_fdb_dump_cb_t *cb, void *data)
248 {
249 	struct dsa_switch *ds = dp->ds;
250 	int port = dp->index;
251 
252 	if (!ds->ops->port_fdb_dump)
253 		return -EOPNOTSUPP;
254 
255 	return ds->ops->port_fdb_dump(ds, port, cb, data);
256 }
257 
258 int dsa_port_mdb_add(const struct dsa_port *dp,
259 		     const struct switchdev_obj_port_mdb *mdb,
260 		     struct switchdev_trans *trans)
261 {
262 	struct dsa_notifier_mdb_info info = {
263 		.sw_index = dp->ds->index,
264 		.port = dp->index,
265 		.trans = trans,
266 		.mdb = mdb,
267 	};
268 
269 	return dsa_port_notify(dp, DSA_NOTIFIER_MDB_ADD, &info);
270 }
271 
272 int dsa_port_mdb_del(const struct dsa_port *dp,
273 		     const struct switchdev_obj_port_mdb *mdb)
274 {
275 	struct dsa_notifier_mdb_info info = {
276 		.sw_index = dp->ds->index,
277 		.port = dp->index,
278 		.mdb = mdb,
279 	};
280 
281 	return dsa_port_notify(dp, DSA_NOTIFIER_MDB_DEL, &info);
282 }
283 
284 int dsa_port_vlan_add(struct dsa_port *dp,
285 		      const struct switchdev_obj_port_vlan *vlan,
286 		      struct switchdev_trans *trans)
287 {
288 	struct dsa_notifier_vlan_info info = {
289 		.sw_index = dp->ds->index,
290 		.port = dp->index,
291 		.trans = trans,
292 		.vlan = vlan,
293 	};
294 
295 	/* Can be called from dsa_slave_port_obj_add() or
296 	 * dsa_slave_vlan_rx_add_vid()
297 	 */
298 	if (!dp->bridge_dev || br_vlan_enabled(dp->bridge_dev))
299 		return dsa_port_notify(dp, DSA_NOTIFIER_VLAN_ADD, &info);
300 
301 	return 0;
302 }
303 
304 int dsa_port_vlan_del(struct dsa_port *dp,
305 		      const struct switchdev_obj_port_vlan *vlan)
306 {
307 	struct dsa_notifier_vlan_info info = {
308 		.sw_index = dp->ds->index,
309 		.port = dp->index,
310 		.vlan = vlan,
311 	};
312 
313 	if (vlan->obj.orig_dev && netif_is_bridge_master(vlan->obj.orig_dev))
314 		return -EOPNOTSUPP;
315 
316 	/* Can be called from dsa_slave_port_obj_del() or
317 	 * dsa_slave_vlan_rx_kill_vid()
318 	 */
319 	if (!dp->bridge_dev || br_vlan_enabled(dp->bridge_dev))
320 		return dsa_port_notify(dp, DSA_NOTIFIER_VLAN_DEL, &info);
321 
322 	return 0;
323 }
324 
325 static struct phy_device *dsa_port_get_phy_device(struct dsa_port *dp)
326 {
327 	struct device_node *phy_dn;
328 	struct phy_device *phydev;
329 
330 	phy_dn = of_parse_phandle(dp->dn, "phy-handle", 0);
331 	if (!phy_dn)
332 		return NULL;
333 
334 	phydev = of_phy_find_device(phy_dn);
335 	if (!phydev) {
336 		of_node_put(phy_dn);
337 		return ERR_PTR(-EPROBE_DEFER);
338 	}
339 
340 	of_node_put(phy_dn);
341 	return phydev;
342 }
343 
344 static int dsa_port_setup_phy_of(struct dsa_port *dp, bool enable)
345 {
346 	struct dsa_switch *ds = dp->ds;
347 	struct phy_device *phydev;
348 	int port = dp->index;
349 	int err = 0;
350 
351 	phydev = dsa_port_get_phy_device(dp);
352 	if (!phydev)
353 		return 0;
354 
355 	if (IS_ERR(phydev))
356 		return PTR_ERR(phydev);
357 
358 	if (enable) {
359 		err = genphy_config_init(phydev);
360 		if (err < 0)
361 			goto err_put_dev;
362 
363 		err = genphy_resume(phydev);
364 		if (err < 0)
365 			goto err_put_dev;
366 
367 		err = genphy_read_status(phydev);
368 		if (err < 0)
369 			goto err_put_dev;
370 	} else {
371 		err = genphy_suspend(phydev);
372 		if (err < 0)
373 			goto err_put_dev;
374 	}
375 
376 	if (ds->ops->adjust_link)
377 		ds->ops->adjust_link(ds, port, phydev);
378 
379 	dev_dbg(ds->dev, "enabled port's phy: %s", phydev_name(phydev));
380 
381 err_put_dev:
382 	put_device(&phydev->mdio.dev);
383 	return err;
384 }
385 
386 static int dsa_port_fixed_link_register_of(struct dsa_port *dp)
387 {
388 	struct device_node *dn = dp->dn;
389 	struct dsa_switch *ds = dp->ds;
390 	struct phy_device *phydev;
391 	int port = dp->index;
392 	int mode;
393 	int err;
394 
395 	err = of_phy_register_fixed_link(dn);
396 	if (err) {
397 		dev_err(ds->dev,
398 			"failed to register the fixed PHY of port %d\n",
399 			port);
400 		return err;
401 	}
402 
403 	phydev = of_phy_find_device(dn);
404 
405 	mode = of_get_phy_mode(dn);
406 	if (mode < 0)
407 		mode = PHY_INTERFACE_MODE_NA;
408 	phydev->interface = mode;
409 
410 	genphy_config_init(phydev);
411 	genphy_read_status(phydev);
412 
413 	if (ds->ops->adjust_link)
414 		ds->ops->adjust_link(ds, port, phydev);
415 
416 	put_device(&phydev->mdio.dev);
417 
418 	return 0;
419 }
420 
421 int dsa_port_link_register_of(struct dsa_port *dp)
422 {
423 	if (of_phy_is_fixed_link(dp->dn))
424 		return dsa_port_fixed_link_register_of(dp);
425 	else
426 		return dsa_port_setup_phy_of(dp, true);
427 }
428 
429 void dsa_port_link_unregister_of(struct dsa_port *dp)
430 {
431 	if (of_phy_is_fixed_link(dp->dn))
432 		of_phy_deregister_fixed_link(dp->dn);
433 	else
434 		dsa_port_setup_phy_of(dp, false);
435 }
436 
437 int dsa_port_get_phy_strings(struct dsa_port *dp, uint8_t *data)
438 {
439 	struct phy_device *phydev;
440 	int ret = -EOPNOTSUPP;
441 
442 	if (of_phy_is_fixed_link(dp->dn))
443 		return ret;
444 
445 	phydev = dsa_port_get_phy_device(dp);
446 	if (IS_ERR_OR_NULL(phydev))
447 		return ret;
448 
449 	ret = phy_ethtool_get_strings(phydev, data);
450 	put_device(&phydev->mdio.dev);
451 
452 	return ret;
453 }
454 EXPORT_SYMBOL_GPL(dsa_port_get_phy_strings);
455 
456 int dsa_port_get_ethtool_phy_stats(struct dsa_port *dp, uint64_t *data)
457 {
458 	struct phy_device *phydev;
459 	int ret = -EOPNOTSUPP;
460 
461 	if (of_phy_is_fixed_link(dp->dn))
462 		return ret;
463 
464 	phydev = dsa_port_get_phy_device(dp);
465 	if (IS_ERR_OR_NULL(phydev))
466 		return ret;
467 
468 	ret = phy_ethtool_get_stats(phydev, NULL, data);
469 	put_device(&phydev->mdio.dev);
470 
471 	return ret;
472 }
473 EXPORT_SYMBOL_GPL(dsa_port_get_ethtool_phy_stats);
474 
475 int dsa_port_get_phy_sset_count(struct dsa_port *dp)
476 {
477 	struct phy_device *phydev;
478 	int ret = -EOPNOTSUPP;
479 
480 	if (of_phy_is_fixed_link(dp->dn))
481 		return ret;
482 
483 	phydev = dsa_port_get_phy_device(dp);
484 	if (IS_ERR_OR_NULL(phydev))
485 		return ret;
486 
487 	ret = phy_ethtool_get_sset_count(phydev);
488 	put_device(&phydev->mdio.dev);
489 
490 	return ret;
491 }
492 EXPORT_SYMBOL_GPL(dsa_port_get_phy_sset_count);
493