2 * Handling of a single switch port
4 * Copyright (c) 2017 Savoir-faire Linux Inc.
5 * Vivien Didelot <vivien.didelot@savoirfairelinux.com>
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.
13 #include <linux/if_bridge.h>
14 #include <linux/notifier.h>
15 #include <linux/of_mdio.h>
16 #include <linux/of_net.h>
20 static int dsa_port_notify(const struct dsa_port
*dp
, unsigned long e
, void *v
)
22 struct raw_notifier_head
*nh
= &dp
->ds
->dst
->nh
;
25 err
= raw_notifier_call_chain(nh
, e
, v
);
27 return notifier_to_errno(err
);
30 int dsa_port_set_state(struct dsa_port
*dp
, u8 state
,
31 struct switchdev_trans
*trans
)
33 struct dsa_switch
*ds
= dp
->ds
;
36 if (switchdev_trans_ph_prepare(trans
))
37 return ds
->ops
->port_stp_state_set
? 0 : -EOPNOTSUPP
;
39 if (ds
->ops
->port_stp_state_set
)
40 ds
->ops
->port_stp_state_set(ds
, port
, state
);
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.
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
);
56 dp
->stp_state
= state
;
61 static void dsa_port_set_state_now(struct dsa_port
*dp
, u8 state
)
65 err
= dsa_port_set_state(dp
, state
, NULL
);
67 pr_err("DSA: failed to set STP state %u (%d)\n", state
, err
);
70 int dsa_port_enable(struct dsa_port
*dp
, struct phy_device
*phy
)
72 struct dsa_switch
*ds
= dp
->ds
;
76 if (ds
->ops
->port_enable
) {
77 err
= ds
->ops
->port_enable(ds
, port
, phy
);
83 dsa_port_set_state_now(dp
, BR_STATE_FORWARDING
);
88 void dsa_port_disable(struct dsa_port
*dp
, struct phy_device
*phy
)
90 struct dsa_switch
*ds
= dp
->ds
;
94 dsa_port_set_state_now(dp
, BR_STATE_DISABLED
);
96 if (ds
->ops
->port_disable
)
97 ds
->ops
->port_disable(ds
, port
, phy
);
100 int dsa_port_bridge_join(struct dsa_port
*dp
, struct net_device
*br
)
102 struct dsa_notifier_bridge_info info
= {
103 .sw_index
= dp
->ds
->index
,
109 /* Here the port is already bridged. Reflect the current configuration
110 * so that drivers can program their chips accordingly.
114 err
= dsa_port_notify(dp
, DSA_NOTIFIER_BRIDGE_JOIN
, &info
);
116 /* The bridging is rolled back on error */
118 dp
->bridge_dev
= NULL
;
123 void dsa_port_bridge_leave(struct dsa_port
*dp
, struct net_device
*br
)
125 struct dsa_notifier_bridge_info info
= {
126 .sw_index
= dp
->ds
->index
,
132 /* Here the port is already unbridged. Reflect the current configuration
133 * so that drivers can program their chips accordingly.
135 dp
->bridge_dev
= NULL
;
137 err
= dsa_port_notify(dp
, DSA_NOTIFIER_BRIDGE_LEAVE
, &info
);
139 pr_err("DSA: failed to notify DSA_NOTIFIER_BRIDGE_LEAVE\n");
141 /* Port left the bridge, put in BR_STATE_DISABLED by the bridge layer,
142 * so allow it to be in BR_STATE_FORWARDING to be kept functional
144 dsa_port_set_state_now(dp
, BR_STATE_FORWARDING
);
147 int dsa_port_vlan_filtering(struct dsa_port
*dp
, bool vlan_filtering
,
148 struct switchdev_trans
*trans
)
150 struct dsa_switch
*ds
= dp
->ds
;
152 /* bridge skips -EOPNOTSUPP, so skip the prepare phase */
153 if (switchdev_trans_ph_prepare(trans
))
156 if (ds
->ops
->port_vlan_filtering
)
157 return ds
->ops
->port_vlan_filtering(ds
, dp
->index
,
163 int dsa_port_ageing_time(struct dsa_port
*dp
, clock_t ageing_clock
,
164 struct switchdev_trans
*trans
)
166 unsigned long ageing_jiffies
= clock_t_to_jiffies(ageing_clock
);
167 unsigned int ageing_time
= jiffies_to_msecs(ageing_jiffies
);
168 struct dsa_notifier_ageing_time_info info
= {
169 .ageing_time
= ageing_time
,
173 if (switchdev_trans_ph_prepare(trans
))
174 return dsa_port_notify(dp
, DSA_NOTIFIER_AGEING_TIME
, &info
);
176 dp
->ageing_time
= ageing_time
;
178 return dsa_port_notify(dp
, DSA_NOTIFIER_AGEING_TIME
, &info
);
181 int dsa_port_fdb_add(struct dsa_port
*dp
, const unsigned char *addr
,
184 struct dsa_notifier_fdb_info info
= {
185 .sw_index
= dp
->ds
->index
,
191 return dsa_port_notify(dp
, DSA_NOTIFIER_FDB_ADD
, &info
);
194 int dsa_port_fdb_del(struct dsa_port
*dp
, const unsigned char *addr
,
197 struct dsa_notifier_fdb_info info
= {
198 .sw_index
= dp
->ds
->index
,
205 return dsa_port_notify(dp
, DSA_NOTIFIER_FDB_DEL
, &info
);
208 int dsa_port_fdb_dump(struct dsa_port
*dp
, dsa_fdb_dump_cb_t
*cb
, void *data
)
210 struct dsa_switch
*ds
= dp
->ds
;
211 int port
= dp
->index
;
213 if (!ds
->ops
->port_fdb_dump
)
216 return ds
->ops
->port_fdb_dump(ds
, port
, cb
, data
);
219 int dsa_port_mdb_add(const struct dsa_port
*dp
,
220 const struct switchdev_obj_port_mdb
*mdb
,
221 struct switchdev_trans
*trans
)
223 struct dsa_notifier_mdb_info info
= {
224 .sw_index
= dp
->ds
->index
,
230 return dsa_port_notify(dp
, DSA_NOTIFIER_MDB_ADD
, &info
);
233 int dsa_port_mdb_del(const struct dsa_port
*dp
,
234 const struct switchdev_obj_port_mdb
*mdb
)
236 struct dsa_notifier_mdb_info info
= {
237 .sw_index
= dp
->ds
->index
,
242 return dsa_port_notify(dp
, DSA_NOTIFIER_MDB_DEL
, &info
);
245 int dsa_port_vlan_add(struct dsa_port
*dp
,
246 const struct switchdev_obj_port_vlan
*vlan
,
247 struct switchdev_trans
*trans
)
249 struct dsa_notifier_vlan_info info
= {
250 .sw_index
= dp
->ds
->index
,
256 if (netif_is_bridge_master(vlan
->obj
.orig_dev
))
259 if (br_vlan_enabled(dp
->bridge_dev
))
260 return dsa_port_notify(dp
, DSA_NOTIFIER_VLAN_ADD
, &info
);
265 int dsa_port_vlan_del(struct dsa_port
*dp
,
266 const struct switchdev_obj_port_vlan
*vlan
)
268 struct dsa_notifier_vlan_info info
= {
269 .sw_index
= dp
->ds
->index
,
274 if (netif_is_bridge_master(vlan
->obj
.orig_dev
))
277 if (br_vlan_enabled(dp
->bridge_dev
))
278 return dsa_port_notify(dp
, DSA_NOTIFIER_VLAN_DEL
, &info
);
283 static struct phy_device
*dsa_port_get_phy_device(struct dsa_port
*dp
)
285 struct device_node
*phy_dn
;
286 struct phy_device
*phydev
;
288 phy_dn
= of_parse_phandle(dp
->dn
, "phy-handle", 0);
292 phydev
= of_phy_find_device(phy_dn
);
295 return ERR_PTR(-EPROBE_DEFER
);
301 static int dsa_port_setup_phy_of(struct dsa_port
*dp
, bool enable
)
303 struct dsa_switch
*ds
= dp
->ds
;
304 struct phy_device
*phydev
;
305 int port
= dp
->index
;
308 phydev
= dsa_port_get_phy_device(dp
);
313 return PTR_ERR(phydev
);
316 err
= genphy_config_init(phydev
);
320 err
= genphy_resume(phydev
);
324 err
= genphy_read_status(phydev
);
328 err
= genphy_suspend(phydev
);
333 if (ds
->ops
->adjust_link
)
334 ds
->ops
->adjust_link(ds
, port
, phydev
);
336 dev_dbg(ds
->dev
, "enabled port's phy: %s", phydev_name(phydev
));
339 put_device(&phydev
->mdio
.dev
);
343 static int dsa_port_fixed_link_register_of(struct dsa_port
*dp
)
345 struct device_node
*dn
= dp
->dn
;
346 struct dsa_switch
*ds
= dp
->ds
;
347 struct phy_device
*phydev
;
348 int port
= dp
->index
;
352 err
= of_phy_register_fixed_link(dn
);
355 "failed to register the fixed PHY of port %d\n",
360 phydev
= of_phy_find_device(dn
);
362 mode
= of_get_phy_mode(dn
);
364 mode
= PHY_INTERFACE_MODE_NA
;
365 phydev
->interface
= mode
;
367 genphy_config_init(phydev
);
368 genphy_read_status(phydev
);
370 if (ds
->ops
->adjust_link
)
371 ds
->ops
->adjust_link(ds
, port
, phydev
);
373 put_device(&phydev
->mdio
.dev
);
378 int dsa_port_link_register_of(struct dsa_port
*dp
)
380 if (of_phy_is_fixed_link(dp
->dn
))
381 return dsa_port_fixed_link_register_of(dp
);
383 return dsa_port_setup_phy_of(dp
, true);
386 void dsa_port_link_unregister_of(struct dsa_port
*dp
)
388 if (of_phy_is_fixed_link(dp
->dn
))
389 of_phy_deregister_fixed_link(dp
->dn
);
391 dsa_port_setup_phy_of(dp
, false);
394 int dsa_port_get_phy_strings(struct dsa_port
*dp
, uint8_t *data
)
396 struct phy_device
*phydev
;
397 int ret
= -EOPNOTSUPP
;
399 if (of_phy_is_fixed_link(dp
->dn
))
402 phydev
= dsa_port_get_phy_device(dp
);
403 if (IS_ERR_OR_NULL(phydev
))
406 ret
= phy_ethtool_get_strings(phydev
, data
);
407 put_device(&phydev
->mdio
.dev
);
411 EXPORT_SYMBOL_GPL(dsa_port_get_phy_strings
);
413 int dsa_port_get_ethtool_phy_stats(struct dsa_port
*dp
, uint64_t *data
)
415 struct phy_device
*phydev
;
416 int ret
= -EOPNOTSUPP
;
418 if (of_phy_is_fixed_link(dp
->dn
))
421 phydev
= dsa_port_get_phy_device(dp
);
422 if (IS_ERR_OR_NULL(phydev
))
425 ret
= phy_ethtool_get_stats(phydev
, NULL
, data
);
426 put_device(&phydev
->mdio
.dev
);
430 EXPORT_SYMBOL_GPL(dsa_port_get_ethtool_phy_stats
);
432 int dsa_port_get_phy_sset_count(struct dsa_port
*dp
)
434 struct phy_device
*phydev
;
435 int ret
= -EOPNOTSUPP
;
437 if (of_phy_is_fixed_link(dp
->dn
))
440 phydev
= dsa_port_get_phy_device(dp
);
441 if (IS_ERR_OR_NULL(phydev
))
444 ret
= phy_ethtool_get_sset_count(phydev
);
445 put_device(&phydev
->mdio
.dev
);
449 EXPORT_SYMBOL_GPL(dsa_port_get_phy_sset_count
);