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