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) 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); 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 /* 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. 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 */ 122 if (err) { 123 dsa_port_bridge_flags(dp, 0, NULL); 124 dp->bridge_dev = NULL; 125 } 126 127 return err; 128 } 129 130 void 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 148 /* Port is leaving the bridge, disable flooding */ 149 dsa_port_bridge_flags(dp, 0, NULL); 150 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 } 156 157 static bool dsa_port_can_apply_vlan_filtering(struct dsa_port *dp, 158 bool vlan_filtering) 159 { 160 struct dsa_switch *ds = dp->ds; 161 int i; 162 163 if (!ds->vlan_filtering_is_global) 164 return true; 165 166 /* For cases where enabling/disabling VLAN awareness is global to the 167 * switch, we need to handle the case where multiple bridges span 168 * different ports of the same switch device and one of them has a 169 * different setting than what is being requested. 170 */ 171 for (i = 0; i < ds->num_ports; i++) { 172 struct net_device *other_bridge; 173 174 other_bridge = dsa_to_port(ds, i)->bridge_dev; 175 if (!other_bridge) 176 continue; 177 /* If it's the same bridge, it also has same 178 * vlan_filtering setting => no need to check 179 */ 180 if (other_bridge == dp->bridge_dev) 181 continue; 182 if (br_vlan_enabled(other_bridge) != vlan_filtering) { 183 dev_err(ds->dev, "VLAN filtering is a global setting\n"); 184 return false; 185 } 186 } 187 return true; 188 } 189 190 int dsa_port_vlan_filtering(struct dsa_port *dp, bool vlan_filtering, 191 struct switchdev_trans *trans) 192 { 193 struct dsa_switch *ds = dp->ds; 194 int err; 195 196 /* bridge skips -EOPNOTSUPP, so skip the prepare phase */ 197 if (switchdev_trans_ph_prepare(trans)) 198 return 0; 199 200 if (!ds->ops->port_vlan_filtering) 201 return 0; 202 203 if (!dsa_port_can_apply_vlan_filtering(dp, vlan_filtering)) 204 return -EINVAL; 205 206 if (dsa_port_is_vlan_filtering(dp) == vlan_filtering) 207 return 0; 208 209 err = ds->ops->port_vlan_filtering(ds, dp->index, 210 vlan_filtering); 211 if (err) 212 return err; 213 214 if (ds->vlan_filtering_is_global) 215 ds->vlan_filtering = vlan_filtering; 216 else 217 dp->vlan_filtering = vlan_filtering; 218 return 0; 219 } 220 221 int dsa_port_ageing_time(struct dsa_port *dp, clock_t ageing_clock, 222 struct switchdev_trans *trans) 223 { 224 unsigned long ageing_jiffies = clock_t_to_jiffies(ageing_clock); 225 unsigned int ageing_time = jiffies_to_msecs(ageing_jiffies); 226 struct dsa_notifier_ageing_time_info info = { 227 .ageing_time = ageing_time, 228 .trans = trans, 229 }; 230 231 if (switchdev_trans_ph_prepare(trans)) 232 return dsa_port_notify(dp, DSA_NOTIFIER_AGEING_TIME, &info); 233 234 dp->ageing_time = ageing_time; 235 236 return dsa_port_notify(dp, DSA_NOTIFIER_AGEING_TIME, &info); 237 } 238 239 int dsa_port_pre_bridge_flags(const struct dsa_port *dp, unsigned long flags, 240 struct switchdev_trans *trans) 241 { 242 struct dsa_switch *ds = dp->ds; 243 244 if (!ds->ops->port_egress_floods || 245 (flags & ~(BR_FLOOD | BR_MCAST_FLOOD))) 246 return -EINVAL; 247 248 return 0; 249 } 250 251 int dsa_port_bridge_flags(const struct dsa_port *dp, unsigned long flags, 252 struct switchdev_trans *trans) 253 { 254 struct dsa_switch *ds = dp->ds; 255 int port = dp->index; 256 int err = 0; 257 258 if (switchdev_trans_ph_prepare(trans)) 259 return 0; 260 261 if (ds->ops->port_egress_floods) 262 err = ds->ops->port_egress_floods(ds, port, flags & BR_FLOOD, 263 flags & BR_MCAST_FLOOD); 264 265 return err; 266 } 267 268 int dsa_port_fdb_add(struct dsa_port *dp, const unsigned char *addr, 269 u16 vid) 270 { 271 struct dsa_notifier_fdb_info info = { 272 .sw_index = dp->ds->index, 273 .port = dp->index, 274 .addr = addr, 275 .vid = vid, 276 }; 277 278 return dsa_port_notify(dp, DSA_NOTIFIER_FDB_ADD, &info); 279 } 280 281 int dsa_port_fdb_del(struct dsa_port *dp, const unsigned char *addr, 282 u16 vid) 283 { 284 struct dsa_notifier_fdb_info info = { 285 .sw_index = dp->ds->index, 286 .port = dp->index, 287 .addr = addr, 288 .vid = vid, 289 290 }; 291 292 return dsa_port_notify(dp, DSA_NOTIFIER_FDB_DEL, &info); 293 } 294 295 int dsa_port_fdb_dump(struct dsa_port *dp, dsa_fdb_dump_cb_t *cb, void *data) 296 { 297 struct dsa_switch *ds = dp->ds; 298 int port = dp->index; 299 300 if (!ds->ops->port_fdb_dump) 301 return -EOPNOTSUPP; 302 303 return ds->ops->port_fdb_dump(ds, port, cb, data); 304 } 305 306 int dsa_port_mdb_add(const struct dsa_port *dp, 307 const struct switchdev_obj_port_mdb *mdb, 308 struct switchdev_trans *trans) 309 { 310 struct dsa_notifier_mdb_info info = { 311 .sw_index = dp->ds->index, 312 .port = dp->index, 313 .trans = trans, 314 .mdb = mdb, 315 }; 316 317 return dsa_port_notify(dp, DSA_NOTIFIER_MDB_ADD, &info); 318 } 319 320 int dsa_port_mdb_del(const struct dsa_port *dp, 321 const struct switchdev_obj_port_mdb *mdb) 322 { 323 struct dsa_notifier_mdb_info info = { 324 .sw_index = dp->ds->index, 325 .port = dp->index, 326 .mdb = mdb, 327 }; 328 329 return dsa_port_notify(dp, DSA_NOTIFIER_MDB_DEL, &info); 330 } 331 332 int dsa_port_vlan_add(struct dsa_port *dp, 333 const struct switchdev_obj_port_vlan *vlan, 334 struct switchdev_trans *trans) 335 { 336 struct dsa_notifier_vlan_info info = { 337 .sw_index = dp->ds->index, 338 .port = dp->index, 339 .trans = trans, 340 .vlan = vlan, 341 }; 342 343 /* Can be called from dsa_slave_port_obj_add() or 344 * dsa_slave_vlan_rx_add_vid() 345 */ 346 if (!dp->bridge_dev || br_vlan_enabled(dp->bridge_dev)) 347 return dsa_port_notify(dp, DSA_NOTIFIER_VLAN_ADD, &info); 348 349 return 0; 350 } 351 352 int dsa_port_vlan_del(struct dsa_port *dp, 353 const struct switchdev_obj_port_vlan *vlan) 354 { 355 struct dsa_notifier_vlan_info info = { 356 .sw_index = dp->ds->index, 357 .port = dp->index, 358 .vlan = vlan, 359 }; 360 361 if (vlan->obj.orig_dev && netif_is_bridge_master(vlan->obj.orig_dev)) 362 return -EOPNOTSUPP; 363 364 /* Can be called from dsa_slave_port_obj_del() or 365 * dsa_slave_vlan_rx_kill_vid() 366 */ 367 if (!dp->bridge_dev || br_vlan_enabled(dp->bridge_dev)) 368 return dsa_port_notify(dp, DSA_NOTIFIER_VLAN_DEL, &info); 369 370 return 0; 371 } 372 373 int dsa_port_vid_add(struct dsa_port *dp, u16 vid, u16 flags) 374 { 375 struct switchdev_obj_port_vlan vlan = { 376 .obj.id = SWITCHDEV_OBJ_ID_PORT_VLAN, 377 .flags = flags, 378 .vid_begin = vid, 379 .vid_end = vid, 380 }; 381 struct switchdev_trans trans; 382 int err; 383 384 trans.ph_prepare = true; 385 err = dsa_port_vlan_add(dp, &vlan, &trans); 386 if (err == -EOPNOTSUPP) 387 return 0; 388 389 trans.ph_prepare = false; 390 return dsa_port_vlan_add(dp, &vlan, &trans); 391 } 392 EXPORT_SYMBOL(dsa_port_vid_add); 393 394 int dsa_port_vid_del(struct dsa_port *dp, u16 vid) 395 { 396 struct switchdev_obj_port_vlan vlan = { 397 .obj.id = SWITCHDEV_OBJ_ID_PORT_VLAN, 398 .vid_begin = vid, 399 .vid_end = vid, 400 }; 401 402 return dsa_port_vlan_del(dp, &vlan); 403 } 404 EXPORT_SYMBOL(dsa_port_vid_del); 405 406 static struct phy_device *dsa_port_get_phy_device(struct dsa_port *dp) 407 { 408 struct device_node *phy_dn; 409 struct phy_device *phydev; 410 411 phy_dn = of_parse_phandle(dp->dn, "phy-handle", 0); 412 if (!phy_dn) 413 return NULL; 414 415 phydev = of_phy_find_device(phy_dn); 416 if (!phydev) { 417 of_node_put(phy_dn); 418 return ERR_PTR(-EPROBE_DEFER); 419 } 420 421 of_node_put(phy_dn); 422 return phydev; 423 } 424 425 static int dsa_port_setup_phy_of(struct dsa_port *dp, bool enable) 426 { 427 struct dsa_switch *ds = dp->ds; 428 struct phy_device *phydev; 429 int port = dp->index; 430 int err = 0; 431 432 phydev = dsa_port_get_phy_device(dp); 433 if (!phydev) 434 return 0; 435 436 if (IS_ERR(phydev)) 437 return PTR_ERR(phydev); 438 439 if (enable) { 440 err = genphy_config_init(phydev); 441 if (err < 0) 442 goto err_put_dev; 443 444 err = genphy_resume(phydev); 445 if (err < 0) 446 goto err_put_dev; 447 448 err = genphy_read_status(phydev); 449 if (err < 0) 450 goto err_put_dev; 451 } else { 452 err = genphy_suspend(phydev); 453 if (err < 0) 454 goto err_put_dev; 455 } 456 457 if (ds->ops->adjust_link) 458 ds->ops->adjust_link(ds, port, phydev); 459 460 dev_dbg(ds->dev, "enabled port's phy: %s", phydev_name(phydev)); 461 462 err_put_dev: 463 put_device(&phydev->mdio.dev); 464 return err; 465 } 466 467 static int dsa_port_fixed_link_register_of(struct dsa_port *dp) 468 { 469 struct device_node *dn = dp->dn; 470 struct dsa_switch *ds = dp->ds; 471 struct phy_device *phydev; 472 int port = dp->index; 473 int mode; 474 int err; 475 476 err = of_phy_register_fixed_link(dn); 477 if (err) { 478 dev_err(ds->dev, 479 "failed to register the fixed PHY of port %d\n", 480 port); 481 return err; 482 } 483 484 phydev = of_phy_find_device(dn); 485 486 mode = of_get_phy_mode(dn); 487 if (mode < 0) 488 mode = PHY_INTERFACE_MODE_NA; 489 phydev->interface = mode; 490 491 genphy_config_init(phydev); 492 genphy_read_status(phydev); 493 494 if (ds->ops->adjust_link) 495 ds->ops->adjust_link(ds, port, phydev); 496 497 put_device(&phydev->mdio.dev); 498 499 return 0; 500 } 501 502 int dsa_port_link_register_of(struct dsa_port *dp) 503 { 504 if (of_phy_is_fixed_link(dp->dn)) 505 return dsa_port_fixed_link_register_of(dp); 506 else 507 return dsa_port_setup_phy_of(dp, true); 508 } 509 510 void dsa_port_link_unregister_of(struct dsa_port *dp) 511 { 512 if (of_phy_is_fixed_link(dp->dn)) 513 of_phy_deregister_fixed_link(dp->dn); 514 else 515 dsa_port_setup_phy_of(dp, false); 516 } 517 518 int dsa_port_get_phy_strings(struct dsa_port *dp, uint8_t *data) 519 { 520 struct phy_device *phydev; 521 int ret = -EOPNOTSUPP; 522 523 if (of_phy_is_fixed_link(dp->dn)) 524 return ret; 525 526 phydev = dsa_port_get_phy_device(dp); 527 if (IS_ERR_OR_NULL(phydev)) 528 return ret; 529 530 ret = phy_ethtool_get_strings(phydev, data); 531 put_device(&phydev->mdio.dev); 532 533 return ret; 534 } 535 EXPORT_SYMBOL_GPL(dsa_port_get_phy_strings); 536 537 int dsa_port_get_ethtool_phy_stats(struct dsa_port *dp, uint64_t *data) 538 { 539 struct phy_device *phydev; 540 int ret = -EOPNOTSUPP; 541 542 if (of_phy_is_fixed_link(dp->dn)) 543 return ret; 544 545 phydev = dsa_port_get_phy_device(dp); 546 if (IS_ERR_OR_NULL(phydev)) 547 return ret; 548 549 ret = phy_ethtool_get_stats(phydev, NULL, data); 550 put_device(&phydev->mdio.dev); 551 552 return ret; 553 } 554 EXPORT_SYMBOL_GPL(dsa_port_get_ethtool_phy_stats); 555 556 int dsa_port_get_phy_sset_count(struct dsa_port *dp) 557 { 558 struct phy_device *phydev; 559 int ret = -EOPNOTSUPP; 560 561 if (of_phy_is_fixed_link(dp->dn)) 562 return ret; 563 564 phydev = dsa_port_get_phy_device(dp); 565 if (IS_ERR_OR_NULL(phydev)) 566 return ret; 567 568 ret = phy_ethtool_get_sset_count(phydev); 569 put_device(&phydev->mdio.dev); 570 571 return ret; 572 } 573 EXPORT_SYMBOL_GPL(dsa_port_get_phy_sset_count); 574