net: dsa: Store vlan_filtering as a property of dsa_port
[linux-2.6-block.git] / net / dsa / port.c
CommitLineData
a40c175b
VD
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>
cfbed329 14#include <linux/notifier.h>
57ab1ca2
VD
15#include <linux/of_mdio.h>
16#include <linux/of_net.h>
a40c175b
VD
17
18#include "dsa_priv.h"
19
bb9f6031 20static int dsa_port_notify(const struct dsa_port *dp, unsigned long e, void *v)
cfbed329
VD
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
a40c175b
VD
30int 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
fb8a6a2b 61static void dsa_port_set_state_now(struct dsa_port *dp, u8 state)
a40c175b
VD
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}
cfbed329 69
fb8a6a2b
VD
70int dsa_port_enable(struct dsa_port *dp, struct phy_device *phy)
71{
fb8a6a2b
VD
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
9c2054a5
RK
82 if (!dp->bridge_dev)
83 dsa_port_set_state_now(dp, BR_STATE_FORWARDING);
fb8a6a2b
VD
84
85 return 0;
86}
87
75104db0 88void dsa_port_disable(struct dsa_port *dp)
fb8a6a2b
VD
89{
90 struct dsa_switch *ds = dp->ds;
91 int port = dp->index;
92
9c2054a5
RK
93 if (!dp->bridge_dev)
94 dsa_port_set_state_now(dp, BR_STATE_DISABLED);
fb8a6a2b
VD
95
96 if (ds->ops->port_disable)
75104db0 97 ds->ops->port_disable(ds, port);
fb8a6a2b
VD
98}
99
cfbed329
VD
100int 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
c1388063
RK
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.
cfbed329
VD
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 */
c1388063
RK
122 if (err) {
123 dsa_port_bridge_flags(dp, 0, NULL);
cfbed329 124 dp->bridge_dev = NULL;
c1388063 125 }
cfbed329
VD
126
127 return err;
128}
129
130void 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
c1388063
RK
148 /* Port is leaving the bridge, disable flooding */
149 dsa_port_bridge_flags(dp, 0, NULL);
150
cfbed329
VD
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}
4d61d304
VD
156
157int dsa_port_vlan_filtering(struct dsa_port *dp, bool vlan_filtering,
158 struct switchdev_trans *trans)
159{
160 struct dsa_switch *ds = dp->ds;
33162e9a 161 int err;
4d61d304
VD
162
163 /* bridge skips -EOPNOTSUPP, so skip the prepare phase */
164 if (switchdev_trans_ph_prepare(trans))
165 return 0;
166
33162e9a
VO
167 if (ds->ops->port_vlan_filtering) {
168 err = ds->ops->port_vlan_filtering(ds, dp->index,
169 vlan_filtering);
170 if (err)
171 return err;
172 dp->vlan_filtering = vlan_filtering;
173 }
4d61d304
VD
174 return 0;
175}
d87bd94e 176
d87bd94e
VD
177int dsa_port_ageing_time(struct dsa_port *dp, clock_t ageing_clock,
178 struct switchdev_trans *trans)
179{
180 unsigned long ageing_jiffies = clock_t_to_jiffies(ageing_clock);
181 unsigned int ageing_time = jiffies_to_msecs(ageing_jiffies);
1faabf74
VD
182 struct dsa_notifier_ageing_time_info info = {
183 .ageing_time = ageing_time,
1faabf74
VD
184 .trans = trans,
185 };
d87bd94e 186
1faabf74
VD
187 if (switchdev_trans_ph_prepare(trans))
188 return dsa_port_notify(dp, DSA_NOTIFIER_AGEING_TIME, &info);
d87bd94e 189
d87bd94e 190 dp->ageing_time = ageing_time;
d87bd94e 191
1faabf74 192 return dsa_port_notify(dp, DSA_NOTIFIER_AGEING_TIME, &info);
d87bd94e 193}
d1cffff0 194
ea87005a
FF
195int dsa_port_pre_bridge_flags(const struct dsa_port *dp, unsigned long flags,
196 struct switchdev_trans *trans)
197{
198 struct dsa_switch *ds = dp->ds;
199
200 if (!ds->ops->port_egress_floods ||
201 (flags & ~(BR_FLOOD | BR_MCAST_FLOOD)))
202 return -EINVAL;
203
204 return 0;
205}
206
57652796
RK
207int dsa_port_bridge_flags(const struct dsa_port *dp, unsigned long flags,
208 struct switchdev_trans *trans)
209{
210 struct dsa_switch *ds = dp->ds;
211 int port = dp->index;
212 int err = 0;
213
214 if (switchdev_trans_ph_prepare(trans))
215 return 0;
216
217 if (ds->ops->port_egress_floods)
218 err = ds->ops->port_egress_floods(ds, port, flags & BR_FLOOD,
219 flags & BR_MCAST_FLOOD);
220
221 return err;
222}
223
2acf4e6a
AS
224int dsa_port_fdb_add(struct dsa_port *dp, const unsigned char *addr,
225 u16 vid)
d1cffff0 226{
685fb6a4
VD
227 struct dsa_notifier_fdb_info info = {
228 .sw_index = dp->ds->index,
229 .port = dp->index,
2acf4e6a
AS
230 .addr = addr,
231 .vid = vid,
685fb6a4 232 };
d1cffff0 233
685fb6a4 234 return dsa_port_notify(dp, DSA_NOTIFIER_FDB_ADD, &info);
d1cffff0
VD
235}
236
2acf4e6a
AS
237int dsa_port_fdb_del(struct dsa_port *dp, const unsigned char *addr,
238 u16 vid)
d1cffff0 239{
685fb6a4
VD
240 struct dsa_notifier_fdb_info info = {
241 .sw_index = dp->ds->index,
242 .port = dp->index,
2acf4e6a
AS
243 .addr = addr,
244 .vid = vid,
245
685fb6a4 246 };
d1cffff0 247
685fb6a4 248 return dsa_port_notify(dp, DSA_NOTIFIER_FDB_DEL, &info);
d1cffff0
VD
249}
250
de40fc5d
VD
251int dsa_port_fdb_dump(struct dsa_port *dp, dsa_fdb_dump_cb_t *cb, void *data)
252{
253 struct dsa_switch *ds = dp->ds;
254 int port = dp->index;
255
256 if (!ds->ops->port_fdb_dump)
257 return -EOPNOTSUPP;
258
259 return ds->ops->port_fdb_dump(ds, port, cb, data);
260}
261
bb9f6031 262int dsa_port_mdb_add(const struct dsa_port *dp,
3a9afea3
VD
263 const struct switchdev_obj_port_mdb *mdb,
264 struct switchdev_trans *trans)
265{
8ae5bcdc
VD
266 struct dsa_notifier_mdb_info info = {
267 .sw_index = dp->ds->index,
268 .port = dp->index,
269 .trans = trans,
270 .mdb = mdb,
271 };
3a9afea3 272
8ae5bcdc 273 return dsa_port_notify(dp, DSA_NOTIFIER_MDB_ADD, &info);
3a9afea3
VD
274}
275
bb9f6031 276int dsa_port_mdb_del(const struct dsa_port *dp,
3a9afea3
VD
277 const struct switchdev_obj_port_mdb *mdb)
278{
8ae5bcdc
VD
279 struct dsa_notifier_mdb_info info = {
280 .sw_index = dp->ds->index,
281 .port = dp->index,
282 .mdb = mdb,
283 };
3a9afea3 284
8ae5bcdc 285 return dsa_port_notify(dp, DSA_NOTIFIER_MDB_DEL, &info);
3a9afea3
VD
286}
287
076e7133
VD
288int dsa_port_vlan_add(struct dsa_port *dp,
289 const struct switchdev_obj_port_vlan *vlan,
290 struct switchdev_trans *trans)
291{
d0c627b8
VD
292 struct dsa_notifier_vlan_info info = {
293 .sw_index = dp->ds->index,
294 .port = dp->index,
295 .trans = trans,
296 .vlan = vlan,
297 };
076e7133 298
061f6a50
FF
299 /* Can be called from dsa_slave_port_obj_add() or
300 * dsa_slave_vlan_rx_add_vid()
301 */
302 if (!dp->bridge_dev || br_vlan_enabled(dp->bridge_dev))
2ea7a679
AL
303 return dsa_port_notify(dp, DSA_NOTIFIER_VLAN_ADD, &info);
304
305 return 0;
076e7133
VD
306}
307
308int dsa_port_vlan_del(struct dsa_port *dp,
309 const struct switchdev_obj_port_vlan *vlan)
310{
d0c627b8
VD
311 struct dsa_notifier_vlan_info info = {
312 .sw_index = dp->ds->index,
313 .port = dp->index,
314 .vlan = vlan,
315 };
076e7133 316
061f6a50 317 if (vlan->obj.orig_dev && netif_is_bridge_master(vlan->obj.orig_dev))
da0efa88
PM
318 return -EOPNOTSUPP;
319
061f6a50
FF
320 /* Can be called from dsa_slave_port_obj_del() or
321 * dsa_slave_vlan_rx_kill_vid()
322 */
323 if (!dp->bridge_dev || br_vlan_enabled(dp->bridge_dev))
2ea7a679
AL
324 return dsa_port_notify(dp, DSA_NOTIFIER_VLAN_DEL, &info);
325
326 return 0;
076e7133 327}
57ab1ca2 328
6207a78c 329static struct phy_device *dsa_port_get_phy_device(struct dsa_port *dp)
33615367 330{
33615367 331 struct device_node *phy_dn;
33615367 332 struct phy_device *phydev;
33615367 333
6207a78c 334 phy_dn = of_parse_phandle(dp->dn, "phy-handle", 0);
33615367 335 if (!phy_dn)
6207a78c 336 return NULL;
33615367
SR
337
338 phydev = of_phy_find_device(phy_dn);
339 if (!phydev) {
6207a78c
FF
340 of_node_put(phy_dn);
341 return ERR_PTR(-EPROBE_DEFER);
33615367
SR
342 }
343
9919a363 344 of_node_put(phy_dn);
6207a78c
FF
345 return phydev;
346}
347
348static int dsa_port_setup_phy_of(struct dsa_port *dp, bool enable)
349{
350 struct dsa_switch *ds = dp->ds;
351 struct phy_device *phydev;
352 int port = dp->index;
353 int err = 0;
354
355 phydev = dsa_port_get_phy_device(dp);
356 if (!phydev)
357 return 0;
358
359 if (IS_ERR(phydev))
360 return PTR_ERR(phydev);
361
33615367
SR
362 if (enable) {
363 err = genphy_config_init(phydev);
364 if (err < 0)
365 goto err_put_dev;
366
367 err = genphy_resume(phydev);
368 if (err < 0)
369 goto err_put_dev;
370
371 err = genphy_read_status(phydev);
372 if (err < 0)
373 goto err_put_dev;
374 } else {
375 err = genphy_suspend(phydev);
376 if (err < 0)
377 goto err_put_dev;
378 }
379
380 if (ds->ops->adjust_link)
381 ds->ops->adjust_link(ds, port, phydev);
382
383 dev_dbg(ds->dev, "enabled port's phy: %s", phydev_name(phydev));
384
385err_put_dev:
386 put_device(&phydev->mdio.dev);
33615367
SR
387 return err;
388}
389
390static int dsa_port_fixed_link_register_of(struct dsa_port *dp)
57ab1ca2
VD
391{
392 struct device_node *dn = dp->dn;
393 struct dsa_switch *ds = dp->ds;
394 struct phy_device *phydev;
395 int port = dp->index;
396 int mode;
397 int err;
398
33615367
SR
399 err = of_phy_register_fixed_link(dn);
400 if (err) {
401 dev_err(ds->dev,
402 "failed to register the fixed PHY of port %d\n",
403 port);
404 return err;
405 }
57ab1ca2 406
33615367 407 phydev = of_phy_find_device(dn);
57ab1ca2 408
33615367
SR
409 mode = of_get_phy_mode(dn);
410 if (mode < 0)
411 mode = PHY_INTERFACE_MODE_NA;
412 phydev->interface = mode;
57ab1ca2 413
33615367
SR
414 genphy_config_init(phydev);
415 genphy_read_status(phydev);
57ab1ca2 416
33615367
SR
417 if (ds->ops->adjust_link)
418 ds->ops->adjust_link(ds, port, phydev);
57ab1ca2 419
33615367 420 put_device(&phydev->mdio.dev);
57ab1ca2
VD
421
422 return 0;
423}
424
33615367 425int dsa_port_link_register_of(struct dsa_port *dp)
57ab1ca2 426{
33615367
SR
427 if (of_phy_is_fixed_link(dp->dn))
428 return dsa_port_fixed_link_register_of(dp);
429 else
430 return dsa_port_setup_phy_of(dp, true);
431}
57ab1ca2 432
33615367
SR
433void dsa_port_link_unregister_of(struct dsa_port *dp)
434{
435 if (of_phy_is_fixed_link(dp->dn))
436 of_phy_deregister_fixed_link(dp->dn);
437 else
438 dsa_port_setup_phy_of(dp, false);
57ab1ca2 439}
cf963573
FF
440
441int dsa_port_get_phy_strings(struct dsa_port *dp, uint8_t *data)
442{
443 struct phy_device *phydev;
444 int ret = -EOPNOTSUPP;
445
446 if (of_phy_is_fixed_link(dp->dn))
447 return ret;
448
449 phydev = dsa_port_get_phy_device(dp);
450 if (IS_ERR_OR_NULL(phydev))
451 return ret;
452
453 ret = phy_ethtool_get_strings(phydev, data);
454 put_device(&phydev->mdio.dev);
455
456 return ret;
457}
458EXPORT_SYMBOL_GPL(dsa_port_get_phy_strings);
459
460int dsa_port_get_ethtool_phy_stats(struct dsa_port *dp, uint64_t *data)
461{
462 struct phy_device *phydev;
463 int ret = -EOPNOTSUPP;
464
465 if (of_phy_is_fixed_link(dp->dn))
466 return ret;
467
468 phydev = dsa_port_get_phy_device(dp);
469 if (IS_ERR_OR_NULL(phydev))
470 return ret;
471
472 ret = phy_ethtool_get_stats(phydev, NULL, data);
473 put_device(&phydev->mdio.dev);
474
475 return ret;
476}
477EXPORT_SYMBOL_GPL(dsa_port_get_ethtool_phy_stats);
478
479int dsa_port_get_phy_sset_count(struct dsa_port *dp)
480{
481 struct phy_device *phydev;
482 int ret = -EOPNOTSUPP;
483
484 if (of_phy_is_fixed_link(dp->dn))
485 return ret;
486
487 phydev = dsa_port_get_phy_device(dp);
488 if (IS_ERR_OR_NULL(phydev))
489 return ret;
490
491 ret = phy_ethtool_get_sset_count(phydev);
492 put_device(&phydev->mdio.dev);
493
494 return ret;
495}
496EXPORT_SYMBOL_GPL(dsa_port_get_phy_sset_count);