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 u8 stp_state
= dp
->bridge_dev
? BR_STATE_BLOCKING
: BR_STATE_FORWARDING
;
73 struct dsa_switch
*ds
= dp
->ds
;
77 if (ds
->ops
->port_enable
) {
78 err
= ds
->ops
->port_enable(ds
, port
, phy
);
83 dsa_port_set_state_now(dp
, stp_state
);
88 void dsa_port_disable(struct dsa_port
*dp
, struct phy_device
*phy
)
90 struct dsa_switch
*ds
= dp
->ds
;
93 dsa_port_set_state_now(dp
, BR_STATE_DISABLED
);
95 if (ds
->ops
->port_disable
)
96 ds
->ops
->port_disable(ds
, port
, phy
);
99 int dsa_port_bridge_join(struct dsa_port
*dp
, struct net_device
*br
)
101 struct dsa_notifier_bridge_info info
= {
102 .sw_index
= dp
->ds
->index
,
108 /* Here the port is already bridged. Reflect the current configuration
109 * so that drivers can program their chips accordingly.
113 err
= dsa_port_notify(dp
, DSA_NOTIFIER_BRIDGE_JOIN
, &info
);
115 /* The bridging is rolled back on error */
117 dp
->bridge_dev
= NULL
;
122 void dsa_port_bridge_leave(struct dsa_port
*dp
, struct net_device
*br
)
124 struct dsa_notifier_bridge_info info
= {
125 .sw_index
= dp
->ds
->index
,
131 /* Here the port is already unbridged. Reflect the current configuration
132 * so that drivers can program their chips accordingly.
134 dp
->bridge_dev
= NULL
;
136 err
= dsa_port_notify(dp
, DSA_NOTIFIER_BRIDGE_LEAVE
, &info
);
138 pr_err("DSA: failed to notify DSA_NOTIFIER_BRIDGE_LEAVE\n");
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
143 dsa_port_set_state_now(dp
, BR_STATE_FORWARDING
);
146 int dsa_port_vlan_filtering(struct dsa_port
*dp
, bool vlan_filtering
,
147 struct switchdev_trans
*trans
)
149 struct dsa_switch
*ds
= dp
->ds
;
151 /* bridge skips -EOPNOTSUPP, so skip the prepare phase */
152 if (switchdev_trans_ph_prepare(trans
))
155 if (ds
->ops
->port_vlan_filtering
)
156 return ds
->ops
->port_vlan_filtering(ds
, dp
->index
,
162 int dsa_port_ageing_time(struct dsa_port
*dp
, clock_t ageing_clock
,
163 struct switchdev_trans
*trans
)
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
,
172 if (switchdev_trans_ph_prepare(trans
))
173 return dsa_port_notify(dp
, DSA_NOTIFIER_AGEING_TIME
, &info
);
175 dp
->ageing_time
= ageing_time
;
177 return dsa_port_notify(dp
, DSA_NOTIFIER_AGEING_TIME
, &info
);
180 int dsa_port_fdb_add(struct dsa_port
*dp
, const unsigned char *addr
,
183 struct dsa_notifier_fdb_info info
= {
184 .sw_index
= dp
->ds
->index
,
190 return dsa_port_notify(dp
, DSA_NOTIFIER_FDB_ADD
, &info
);
193 int dsa_port_fdb_del(struct dsa_port
*dp
, const unsigned char *addr
,
196 struct dsa_notifier_fdb_info info
= {
197 .sw_index
= dp
->ds
->index
,
204 return dsa_port_notify(dp
, DSA_NOTIFIER_FDB_DEL
, &info
);
207 int dsa_port_fdb_dump(struct dsa_port
*dp
, dsa_fdb_dump_cb_t
*cb
, void *data
)
209 struct dsa_switch
*ds
= dp
->ds
;
210 int port
= dp
->index
;
212 if (!ds
->ops
->port_fdb_dump
)
215 return ds
->ops
->port_fdb_dump(ds
, port
, cb
, data
);
218 int dsa_port_mdb_add(const struct dsa_port
*dp
,
219 const struct switchdev_obj_port_mdb
*mdb
,
220 struct switchdev_trans
*trans
)
222 struct dsa_notifier_mdb_info info
= {
223 .sw_index
= dp
->ds
->index
,
229 return dsa_port_notify(dp
, DSA_NOTIFIER_MDB_ADD
, &info
);
232 int dsa_port_mdb_del(const struct dsa_port
*dp
,
233 const struct switchdev_obj_port_mdb
*mdb
)
235 struct dsa_notifier_mdb_info info
= {
236 .sw_index
= dp
->ds
->index
,
241 return dsa_port_notify(dp
, DSA_NOTIFIER_MDB_DEL
, &info
);
244 int dsa_port_vlan_add(struct dsa_port
*dp
,
245 const struct switchdev_obj_port_vlan
*vlan
,
246 struct switchdev_trans
*trans
)
248 struct dsa_notifier_vlan_info info
= {
249 .sw_index
= dp
->ds
->index
,
255 if (netif_is_bridge_master(vlan
->obj
.orig_dev
))
258 if (br_vlan_enabled(dp
->bridge_dev
))
259 return dsa_port_notify(dp
, DSA_NOTIFIER_VLAN_ADD
, &info
);
264 int dsa_port_vlan_del(struct dsa_port
*dp
,
265 const struct switchdev_obj_port_vlan
*vlan
)
267 struct dsa_notifier_vlan_info info
= {
268 .sw_index
= dp
->ds
->index
,
273 if (netif_is_bridge_master(vlan
->obj
.orig_dev
))
276 if (br_vlan_enabled(dp
->bridge_dev
))
277 return dsa_port_notify(dp
, DSA_NOTIFIER_VLAN_DEL
, &info
);
282 static struct phy_device
*dsa_port_get_phy_device(struct dsa_port
*dp
)
284 struct device_node
*phy_dn
;
285 struct phy_device
*phydev
;
287 phy_dn
= of_parse_phandle(dp
->dn
, "phy-handle", 0);
291 phydev
= of_phy_find_device(phy_dn
);
294 return ERR_PTR(-EPROBE_DEFER
);
300 static int dsa_port_setup_phy_of(struct dsa_port
*dp
, bool enable
)
302 struct dsa_switch
*ds
= dp
->ds
;
303 struct phy_device
*phydev
;
304 int port
= dp
->index
;
307 phydev
= dsa_port_get_phy_device(dp
);
312 return PTR_ERR(phydev
);
315 err
= genphy_config_init(phydev
);
319 err
= genphy_resume(phydev
);
323 err
= genphy_read_status(phydev
);
327 err
= genphy_suspend(phydev
);
332 if (ds
->ops
->adjust_link
)
333 ds
->ops
->adjust_link(ds
, port
, phydev
);
335 dev_dbg(ds
->dev
, "enabled port's phy: %s", phydev_name(phydev
));
338 put_device(&phydev
->mdio
.dev
);
342 static int dsa_port_fixed_link_register_of(struct dsa_port
*dp
)
344 struct device_node
*dn
= dp
->dn
;
345 struct dsa_switch
*ds
= dp
->ds
;
346 struct phy_device
*phydev
;
347 int port
= dp
->index
;
351 err
= of_phy_register_fixed_link(dn
);
354 "failed to register the fixed PHY of port %d\n",
359 phydev
= of_phy_find_device(dn
);
361 mode
= of_get_phy_mode(dn
);
363 mode
= PHY_INTERFACE_MODE_NA
;
364 phydev
->interface
= mode
;
366 genphy_config_init(phydev
);
367 genphy_read_status(phydev
);
369 if (ds
->ops
->adjust_link
)
370 ds
->ops
->adjust_link(ds
, port
, phydev
);
372 put_device(&phydev
->mdio
.dev
);
377 int dsa_port_link_register_of(struct dsa_port
*dp
)
379 if (of_phy_is_fixed_link(dp
->dn
))
380 return dsa_port_fixed_link_register_of(dp
);
382 return dsa_port_setup_phy_of(dp
, true);
385 void dsa_port_link_unregister_of(struct dsa_port
*dp
)
387 if (of_phy_is_fixed_link(dp
->dn
))
388 of_phy_deregister_fixed_link(dp
->dn
);
390 dsa_port_setup_phy_of(dp
, false);
393 int dsa_port_get_phy_strings(struct dsa_port
*dp
, uint8_t *data
)
395 struct phy_device
*phydev
;
396 int ret
= -EOPNOTSUPP
;
398 if (of_phy_is_fixed_link(dp
->dn
))
401 phydev
= dsa_port_get_phy_device(dp
);
402 if (IS_ERR_OR_NULL(phydev
))
405 ret
= phy_ethtool_get_strings(phydev
, data
);
406 put_device(&phydev
->mdio
.dev
);
410 EXPORT_SYMBOL_GPL(dsa_port_get_phy_strings
);
412 int dsa_port_get_ethtool_phy_stats(struct dsa_port
*dp
, uint64_t *data
)
414 struct phy_device
*phydev
;
415 int ret
= -EOPNOTSUPP
;
417 if (of_phy_is_fixed_link(dp
->dn
))
420 phydev
= dsa_port_get_phy_device(dp
);
421 if (IS_ERR_OR_NULL(phydev
))
424 ret
= phy_ethtool_get_stats(phydev
, NULL
, data
);
425 put_device(&phydev
->mdio
.dev
);
429 EXPORT_SYMBOL_GPL(dsa_port_get_ethtool_phy_stats
);
431 int dsa_port_get_phy_sset_count(struct dsa_port
*dp
)
433 struct phy_device
*phydev
;
434 int ret
= -EOPNOTSUPP
;
436 if (of_phy_is_fixed_link(dp
->dn
))
439 phydev
= dsa_port_get_phy_device(dp
);
440 if (IS_ERR_OR_NULL(phydev
))
443 ret
= phy_ethtool_get_sset_count(phydev
);
444 put_device(&phydev
->mdio
.dev
);
448 EXPORT_SYMBOL_GPL(dsa_port_get_phy_sset_count
);