net: phy: fix reading fixed phy status
[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
88void 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
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)
97 ds->ops->port_disable(ds, port, phy);
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;
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}
d87bd94e 172
d87bd94e
VD
173int 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);
1faabf74
VD
178 struct dsa_notifier_ageing_time_info info = {
179 .ageing_time = ageing_time,
1faabf74
VD
180 .trans = trans,
181 };
d87bd94e 182
1faabf74
VD
183 if (switchdev_trans_ph_prepare(trans))
184 return dsa_port_notify(dp, DSA_NOTIFIER_AGEING_TIME, &info);
d87bd94e 185
d87bd94e 186 dp->ageing_time = ageing_time;
d87bd94e 187
1faabf74 188 return dsa_port_notify(dp, DSA_NOTIFIER_AGEING_TIME, &info);
d87bd94e 189}
d1cffff0 190
ea87005a
FF
191int 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
57652796
RK
203int 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
2acf4e6a
AS
220int dsa_port_fdb_add(struct dsa_port *dp, const unsigned char *addr,
221 u16 vid)
d1cffff0 222{
685fb6a4
VD
223 struct dsa_notifier_fdb_info info = {
224 .sw_index = dp->ds->index,
225 .port = dp->index,
2acf4e6a
AS
226 .addr = addr,
227 .vid = vid,
685fb6a4 228 };
d1cffff0 229
685fb6a4 230 return dsa_port_notify(dp, DSA_NOTIFIER_FDB_ADD, &info);
d1cffff0
VD
231}
232
2acf4e6a
AS
233int dsa_port_fdb_del(struct dsa_port *dp, const unsigned char *addr,
234 u16 vid)
d1cffff0 235{
685fb6a4
VD
236 struct dsa_notifier_fdb_info info = {
237 .sw_index = dp->ds->index,
238 .port = dp->index,
2acf4e6a
AS
239 .addr = addr,
240 .vid = vid,
241
685fb6a4 242 };
d1cffff0 243
685fb6a4 244 return dsa_port_notify(dp, DSA_NOTIFIER_FDB_DEL, &info);
d1cffff0
VD
245}
246
de40fc5d
VD
247int 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
bb9f6031 258int dsa_port_mdb_add(const struct dsa_port *dp,
3a9afea3
VD
259 const struct switchdev_obj_port_mdb *mdb,
260 struct switchdev_trans *trans)
261{
8ae5bcdc
VD
262 struct dsa_notifier_mdb_info info = {
263 .sw_index = dp->ds->index,
264 .port = dp->index,
265 .trans = trans,
266 .mdb = mdb,
267 };
3a9afea3 268
8ae5bcdc 269 return dsa_port_notify(dp, DSA_NOTIFIER_MDB_ADD, &info);
3a9afea3
VD
270}
271
bb9f6031 272int dsa_port_mdb_del(const struct dsa_port *dp,
3a9afea3
VD
273 const struct switchdev_obj_port_mdb *mdb)
274{
8ae5bcdc
VD
275 struct dsa_notifier_mdb_info info = {
276 .sw_index = dp->ds->index,
277 .port = dp->index,
278 .mdb = mdb,
279 };
3a9afea3 280
8ae5bcdc 281 return dsa_port_notify(dp, DSA_NOTIFIER_MDB_DEL, &info);
3a9afea3
VD
282}
283
076e7133
VD
284int dsa_port_vlan_add(struct dsa_port *dp,
285 const struct switchdev_obj_port_vlan *vlan,
286 struct switchdev_trans *trans)
287{
d0c627b8
VD
288 struct dsa_notifier_vlan_info info = {
289 .sw_index = dp->ds->index,
290 .port = dp->index,
291 .trans = trans,
292 .vlan = vlan,
293 };
076e7133 294
061f6a50
FF
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))
2ea7a679
AL
299 return dsa_port_notify(dp, DSA_NOTIFIER_VLAN_ADD, &info);
300
301 return 0;
076e7133
VD
302}
303
304int dsa_port_vlan_del(struct dsa_port *dp,
305 const struct switchdev_obj_port_vlan *vlan)
306{
d0c627b8
VD
307 struct dsa_notifier_vlan_info info = {
308 .sw_index = dp->ds->index,
309 .port = dp->index,
310 .vlan = vlan,
311 };
076e7133 312
061f6a50 313 if (vlan->obj.orig_dev && netif_is_bridge_master(vlan->obj.orig_dev))
da0efa88
PM
314 return -EOPNOTSUPP;
315
061f6a50
FF
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))
2ea7a679
AL
320 return dsa_port_notify(dp, DSA_NOTIFIER_VLAN_DEL, &info);
321
322 return 0;
076e7133 323}
57ab1ca2 324
6207a78c 325static struct phy_device *dsa_port_get_phy_device(struct dsa_port *dp)
33615367 326{
33615367 327 struct device_node *phy_dn;
33615367 328 struct phy_device *phydev;
33615367 329
6207a78c 330 phy_dn = of_parse_phandle(dp->dn, "phy-handle", 0);
33615367 331 if (!phy_dn)
6207a78c 332 return NULL;
33615367
SR
333
334 phydev = of_phy_find_device(phy_dn);
335 if (!phydev) {
6207a78c
FF
336 of_node_put(phy_dn);
337 return ERR_PTR(-EPROBE_DEFER);
33615367
SR
338 }
339
6207a78c
FF
340 return phydev;
341}
342
343static int dsa_port_setup_phy_of(struct dsa_port *dp, bool enable)
344{
345 struct dsa_switch *ds = dp->ds;
346 struct phy_device *phydev;
347 int port = dp->index;
348 int err = 0;
349
350 phydev = dsa_port_get_phy_device(dp);
351 if (!phydev)
352 return 0;
353
354 if (IS_ERR(phydev))
355 return PTR_ERR(phydev);
356
33615367
SR
357 if (enable) {
358 err = genphy_config_init(phydev);
359 if (err < 0)
360 goto err_put_dev;
361
362 err = genphy_resume(phydev);
363 if (err < 0)
364 goto err_put_dev;
365
366 err = genphy_read_status(phydev);
367 if (err < 0)
368 goto err_put_dev;
369 } else {
370 err = genphy_suspend(phydev);
371 if (err < 0)
372 goto err_put_dev;
373 }
374
375 if (ds->ops->adjust_link)
376 ds->ops->adjust_link(ds, port, phydev);
377
378 dev_dbg(ds->dev, "enabled port's phy: %s", phydev_name(phydev));
379
380err_put_dev:
381 put_device(&phydev->mdio.dev);
33615367
SR
382 return err;
383}
384
385static int dsa_port_fixed_link_register_of(struct dsa_port *dp)
57ab1ca2
VD
386{
387 struct device_node *dn = dp->dn;
388 struct dsa_switch *ds = dp->ds;
389 struct phy_device *phydev;
390 int port = dp->index;
391 int mode;
392 int err;
393
33615367
SR
394 err = of_phy_register_fixed_link(dn);
395 if (err) {
396 dev_err(ds->dev,
397 "failed to register the fixed PHY of port %d\n",
398 port);
399 return err;
400 }
57ab1ca2 401
33615367 402 phydev = of_phy_find_device(dn);
57ab1ca2 403
33615367
SR
404 mode = of_get_phy_mode(dn);
405 if (mode < 0)
406 mode = PHY_INTERFACE_MODE_NA;
407 phydev->interface = mode;
57ab1ca2 408
33615367
SR
409 genphy_config_init(phydev);
410 genphy_read_status(phydev);
57ab1ca2 411
33615367
SR
412 if (ds->ops->adjust_link)
413 ds->ops->adjust_link(ds, port, phydev);
57ab1ca2 414
33615367 415 put_device(&phydev->mdio.dev);
57ab1ca2
VD
416
417 return 0;
418}
419
33615367 420int dsa_port_link_register_of(struct dsa_port *dp)
57ab1ca2 421{
33615367
SR
422 if (of_phy_is_fixed_link(dp->dn))
423 return dsa_port_fixed_link_register_of(dp);
424 else
425 return dsa_port_setup_phy_of(dp, true);
426}
57ab1ca2 427
33615367
SR
428void dsa_port_link_unregister_of(struct dsa_port *dp)
429{
430 if (of_phy_is_fixed_link(dp->dn))
431 of_phy_deregister_fixed_link(dp->dn);
432 else
433 dsa_port_setup_phy_of(dp, false);
57ab1ca2 434}
cf963573
FF
435
436int dsa_port_get_phy_strings(struct dsa_port *dp, uint8_t *data)
437{
438 struct phy_device *phydev;
439 int ret = -EOPNOTSUPP;
440
441 if (of_phy_is_fixed_link(dp->dn))
442 return ret;
443
444 phydev = dsa_port_get_phy_device(dp);
445 if (IS_ERR_OR_NULL(phydev))
446 return ret;
447
448 ret = phy_ethtool_get_strings(phydev, data);
449 put_device(&phydev->mdio.dev);
450
451 return ret;
452}
453EXPORT_SYMBOL_GPL(dsa_port_get_phy_strings);
454
455int dsa_port_get_ethtool_phy_stats(struct dsa_port *dp, uint64_t *data)
456{
457 struct phy_device *phydev;
458 int ret = -EOPNOTSUPP;
459
460 if (of_phy_is_fixed_link(dp->dn))
461 return ret;
462
463 phydev = dsa_port_get_phy_device(dp);
464 if (IS_ERR_OR_NULL(phydev))
465 return ret;
466
467 ret = phy_ethtool_get_stats(phydev, NULL, data);
468 put_device(&phydev->mdio.dev);
469
470 return ret;
471}
472EXPORT_SYMBOL_GPL(dsa_port_get_ethtool_phy_stats);
473
474int dsa_port_get_phy_sset_count(struct dsa_port *dp)
475{
476 struct phy_device *phydev;
477 int ret = -EOPNOTSUPP;
478
479 if (of_phy_is_fixed_link(dp->dn))
480 return ret;
481
482 phydev = dsa_port_get_phy_device(dp);
483 if (IS_ERR_OR_NULL(phydev))
484 return ret;
485
486 ret = phy_ethtool_get_sset_count(phydev);
487 put_device(&phydev->mdio.dev);
488
489 return ret;
490}
491EXPORT_SYMBOL_GPL(dsa_port_get_phy_sset_count);