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