xref: /openbmc/linux/net/dsa/port.c (revision 42bc47b3)
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 	u8 stp_state = dp->bridge_dev ? BR_STATE_BLOCKING : BR_STATE_FORWARDING;
73 	struct dsa_switch *ds = dp->ds;
74 	int port = dp->index;
75 	int err;
76 
77 	if (ds->ops->port_enable) {
78 		err = ds->ops->port_enable(ds, port, phy);
79 		if (err)
80 			return err;
81 	}
82 
83 	dsa_port_set_state_now(dp, stp_state);
84 
85 	return 0;
86 }
87 
88 void dsa_port_disable(struct dsa_port *dp, struct phy_device *phy)
89 {
90 	struct dsa_switch *ds = dp->ds;
91 	int port = dp->index;
92 
93 	dsa_port_set_state_now(dp, BR_STATE_DISABLED);
94 
95 	if (ds->ops->port_disable)
96 		ds->ops->port_disable(ds, port, phy);
97 }
98 
99 int dsa_port_bridge_join(struct dsa_port *dp, struct net_device *br)
100 {
101 	struct dsa_notifier_bridge_info info = {
102 		.sw_index = dp->ds->index,
103 		.port = dp->index,
104 		.br = br,
105 	};
106 	int err;
107 
108 	/* Here the port is already bridged. Reflect the current configuration
109 	 * so that drivers can program their chips accordingly.
110 	 */
111 	dp->bridge_dev = br;
112 
113 	err = dsa_port_notify(dp, DSA_NOTIFIER_BRIDGE_JOIN, &info);
114 
115 	/* The bridging is rolled back on error */
116 	if (err)
117 		dp->bridge_dev = NULL;
118 
119 	return err;
120 }
121 
122 void dsa_port_bridge_leave(struct dsa_port *dp, struct net_device *br)
123 {
124 	struct dsa_notifier_bridge_info info = {
125 		.sw_index = dp->ds->index,
126 		.port = dp->index,
127 		.br = br,
128 	};
129 	int err;
130 
131 	/* Here the port is already unbridged. Reflect the current configuration
132 	 * so that drivers can program their chips accordingly.
133 	 */
134 	dp->bridge_dev = NULL;
135 
136 	err = dsa_port_notify(dp, DSA_NOTIFIER_BRIDGE_LEAVE, &info);
137 	if (err)
138 		pr_err("DSA: failed to notify DSA_NOTIFIER_BRIDGE_LEAVE\n");
139 
140 	/* Port left the bridge, put in BR_STATE_DISABLED by the bridge layer,
141 	 * so allow it to be in BR_STATE_FORWARDING to be kept functional
142 	 */
143 	dsa_port_set_state_now(dp, BR_STATE_FORWARDING);
144 }
145 
146 int dsa_port_vlan_filtering(struct dsa_port *dp, bool vlan_filtering,
147 			    struct switchdev_trans *trans)
148 {
149 	struct dsa_switch *ds = dp->ds;
150 
151 	/* bridge skips -EOPNOTSUPP, so skip the prepare phase */
152 	if (switchdev_trans_ph_prepare(trans))
153 		return 0;
154 
155 	if (ds->ops->port_vlan_filtering)
156 		return ds->ops->port_vlan_filtering(ds, dp->index,
157 						    vlan_filtering);
158 
159 	return 0;
160 }
161 
162 int dsa_port_ageing_time(struct dsa_port *dp, clock_t ageing_clock,
163 			 struct switchdev_trans *trans)
164 {
165 	unsigned long ageing_jiffies = clock_t_to_jiffies(ageing_clock);
166 	unsigned int ageing_time = jiffies_to_msecs(ageing_jiffies);
167 	struct dsa_notifier_ageing_time_info info = {
168 		.ageing_time = ageing_time,
169 		.trans = trans,
170 	};
171 
172 	if (switchdev_trans_ph_prepare(trans))
173 		return dsa_port_notify(dp, DSA_NOTIFIER_AGEING_TIME, &info);
174 
175 	dp->ageing_time = ageing_time;
176 
177 	return dsa_port_notify(dp, DSA_NOTIFIER_AGEING_TIME, &info);
178 }
179 
180 int dsa_port_fdb_add(struct dsa_port *dp, const unsigned char *addr,
181 		     u16 vid)
182 {
183 	struct dsa_notifier_fdb_info info = {
184 		.sw_index = dp->ds->index,
185 		.port = dp->index,
186 		.addr = addr,
187 		.vid = vid,
188 	};
189 
190 	return dsa_port_notify(dp, DSA_NOTIFIER_FDB_ADD, &info);
191 }
192 
193 int dsa_port_fdb_del(struct dsa_port *dp, const unsigned char *addr,
194 		     u16 vid)
195 {
196 	struct dsa_notifier_fdb_info info = {
197 		.sw_index = dp->ds->index,
198 		.port = dp->index,
199 		.addr = addr,
200 		.vid = vid,
201 
202 	};
203 
204 	return dsa_port_notify(dp, DSA_NOTIFIER_FDB_DEL, &info);
205 }
206 
207 int dsa_port_fdb_dump(struct dsa_port *dp, dsa_fdb_dump_cb_t *cb, void *data)
208 {
209 	struct dsa_switch *ds = dp->ds;
210 	int port = dp->index;
211 
212 	if (!ds->ops->port_fdb_dump)
213 		return -EOPNOTSUPP;
214 
215 	return ds->ops->port_fdb_dump(ds, port, cb, data);
216 }
217 
218 int dsa_port_mdb_add(const struct dsa_port *dp,
219 		     const struct switchdev_obj_port_mdb *mdb,
220 		     struct switchdev_trans *trans)
221 {
222 	struct dsa_notifier_mdb_info info = {
223 		.sw_index = dp->ds->index,
224 		.port = dp->index,
225 		.trans = trans,
226 		.mdb = mdb,
227 	};
228 
229 	return dsa_port_notify(dp, DSA_NOTIFIER_MDB_ADD, &info);
230 }
231 
232 int dsa_port_mdb_del(const struct dsa_port *dp,
233 		     const struct switchdev_obj_port_mdb *mdb)
234 {
235 	struct dsa_notifier_mdb_info info = {
236 		.sw_index = dp->ds->index,
237 		.port = dp->index,
238 		.mdb = mdb,
239 	};
240 
241 	return dsa_port_notify(dp, DSA_NOTIFIER_MDB_DEL, &info);
242 }
243 
244 int dsa_port_vlan_add(struct dsa_port *dp,
245 		      const struct switchdev_obj_port_vlan *vlan,
246 		      struct switchdev_trans *trans)
247 {
248 	struct dsa_notifier_vlan_info info = {
249 		.sw_index = dp->ds->index,
250 		.port = dp->index,
251 		.trans = trans,
252 		.vlan = vlan,
253 	};
254 
255 	if (netif_is_bridge_master(vlan->obj.orig_dev))
256 		return -EOPNOTSUPP;
257 
258 	if (br_vlan_enabled(dp->bridge_dev))
259 		return dsa_port_notify(dp, DSA_NOTIFIER_VLAN_ADD, &info);
260 
261 	return 0;
262 }
263 
264 int dsa_port_vlan_del(struct dsa_port *dp,
265 		      const struct switchdev_obj_port_vlan *vlan)
266 {
267 	struct dsa_notifier_vlan_info info = {
268 		.sw_index = dp->ds->index,
269 		.port = dp->index,
270 		.vlan = vlan,
271 	};
272 
273 	if (netif_is_bridge_master(vlan->obj.orig_dev))
274 		return -EOPNOTSUPP;
275 
276 	if (br_vlan_enabled(dp->bridge_dev))
277 		return dsa_port_notify(dp, DSA_NOTIFIER_VLAN_DEL, &info);
278 
279 	return 0;
280 }
281 
282 static struct phy_device *dsa_port_get_phy_device(struct dsa_port *dp)
283 {
284 	struct device_node *phy_dn;
285 	struct phy_device *phydev;
286 
287 	phy_dn = of_parse_phandle(dp->dn, "phy-handle", 0);
288 	if (!phy_dn)
289 		return NULL;
290 
291 	phydev = of_phy_find_device(phy_dn);
292 	if (!phydev) {
293 		of_node_put(phy_dn);
294 		return ERR_PTR(-EPROBE_DEFER);
295 	}
296 
297 	return phydev;
298 }
299 
300 static int dsa_port_setup_phy_of(struct dsa_port *dp, bool enable)
301 {
302 	struct dsa_switch *ds = dp->ds;
303 	struct phy_device *phydev;
304 	int port = dp->index;
305 	int err = 0;
306 
307 	phydev = dsa_port_get_phy_device(dp);
308 	if (!phydev)
309 		return 0;
310 
311 	if (IS_ERR(phydev))
312 		return PTR_ERR(phydev);
313 
314 	if (enable) {
315 		err = genphy_config_init(phydev);
316 		if (err < 0)
317 			goto err_put_dev;
318 
319 		err = genphy_resume(phydev);
320 		if (err < 0)
321 			goto err_put_dev;
322 
323 		err = genphy_read_status(phydev);
324 		if (err < 0)
325 			goto err_put_dev;
326 	} else {
327 		err = genphy_suspend(phydev);
328 		if (err < 0)
329 			goto err_put_dev;
330 	}
331 
332 	if (ds->ops->adjust_link)
333 		ds->ops->adjust_link(ds, port, phydev);
334 
335 	dev_dbg(ds->dev, "enabled port's phy: %s", phydev_name(phydev));
336 
337 err_put_dev:
338 	put_device(&phydev->mdio.dev);
339 	return err;
340 }
341 
342 static int dsa_port_fixed_link_register_of(struct dsa_port *dp)
343 {
344 	struct device_node *dn = dp->dn;
345 	struct dsa_switch *ds = dp->ds;
346 	struct phy_device *phydev;
347 	int port = dp->index;
348 	int mode;
349 	int err;
350 
351 	err = of_phy_register_fixed_link(dn);
352 	if (err) {
353 		dev_err(ds->dev,
354 			"failed to register the fixed PHY of port %d\n",
355 			port);
356 		return err;
357 	}
358 
359 	phydev = of_phy_find_device(dn);
360 
361 	mode = of_get_phy_mode(dn);
362 	if (mode < 0)
363 		mode = PHY_INTERFACE_MODE_NA;
364 	phydev->interface = mode;
365 
366 	genphy_config_init(phydev);
367 	genphy_read_status(phydev);
368 
369 	if (ds->ops->adjust_link)
370 		ds->ops->adjust_link(ds, port, phydev);
371 
372 	put_device(&phydev->mdio.dev);
373 
374 	return 0;
375 }
376 
377 int dsa_port_link_register_of(struct dsa_port *dp)
378 {
379 	if (of_phy_is_fixed_link(dp->dn))
380 		return dsa_port_fixed_link_register_of(dp);
381 	else
382 		return dsa_port_setup_phy_of(dp, true);
383 }
384 
385 void dsa_port_link_unregister_of(struct dsa_port *dp)
386 {
387 	if (of_phy_is_fixed_link(dp->dn))
388 		of_phy_deregister_fixed_link(dp->dn);
389 	else
390 		dsa_port_setup_phy_of(dp, false);
391 }
392 
393 int dsa_port_get_phy_strings(struct dsa_port *dp, uint8_t *data)
394 {
395 	struct phy_device *phydev;
396 	int ret = -EOPNOTSUPP;
397 
398 	if (of_phy_is_fixed_link(dp->dn))
399 		return ret;
400 
401 	phydev = dsa_port_get_phy_device(dp);
402 	if (IS_ERR_OR_NULL(phydev))
403 		return ret;
404 
405 	ret = phy_ethtool_get_strings(phydev, data);
406 	put_device(&phydev->mdio.dev);
407 
408 	return ret;
409 }
410 EXPORT_SYMBOL_GPL(dsa_port_get_phy_strings);
411 
412 int dsa_port_get_ethtool_phy_stats(struct dsa_port *dp, uint64_t *data)
413 {
414 	struct phy_device *phydev;
415 	int ret = -EOPNOTSUPP;
416 
417 	if (of_phy_is_fixed_link(dp->dn))
418 		return ret;
419 
420 	phydev = dsa_port_get_phy_device(dp);
421 	if (IS_ERR_OR_NULL(phydev))
422 		return ret;
423 
424 	ret = phy_ethtool_get_stats(phydev, NULL, data);
425 	put_device(&phydev->mdio.dev);
426 
427 	return ret;
428 }
429 EXPORT_SYMBOL_GPL(dsa_port_get_ethtool_phy_stats);
430 
431 int dsa_port_get_phy_sset_count(struct dsa_port *dp)
432 {
433 	struct phy_device *phydev;
434 	int ret = -EOPNOTSUPP;
435 
436 	if (of_phy_is_fixed_link(dp->dn))
437 		return ret;
438 
439 	phydev = dsa_port_get_phy_device(dp);
440 	if (IS_ERR_OR_NULL(phydev))
441 		return ret;
442 
443 	ret = phy_ethtool_get_sset_count(phydev);
444 	put_device(&phydev->mdio.dev);
445 
446 	return ret;
447 }
448 EXPORT_SYMBOL_GPL(dsa_port_get_phy_sset_count);
449