root/net/dsa/port.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. dsa_port_notify
  2. dsa_port_set_state
  3. dsa_port_set_state_now
  4. dsa_port_enable_rt
  5. dsa_port_enable
  6. dsa_port_disable_rt
  7. dsa_port_disable
  8. dsa_port_bridge_join
  9. dsa_port_bridge_leave
  10. dsa_port_can_apply_vlan_filtering
  11. dsa_port_vlan_filtering
  12. dsa_port_ageing_time
  13. dsa_port_pre_bridge_flags
  14. dsa_port_bridge_flags
  15. dsa_port_mrouter
  16. dsa_port_fdb_add
  17. dsa_port_fdb_del
  18. dsa_port_fdb_dump
  19. dsa_port_mdb_add
  20. dsa_port_mdb_del
  21. dsa_port_vlan_add
  22. dsa_port_vlan_del
  23. dsa_port_vid_add
  24. dsa_port_vid_del
  25. dsa_port_get_phy_device
  26. dsa_port_phylink_validate
  27. dsa_port_phylink_mac_link_state
  28. dsa_port_phylink_mac_config
  29. dsa_port_phylink_mac_an_restart
  30. dsa_port_phylink_mac_link_down
  31. dsa_port_phylink_mac_link_up
  32. dsa_port_setup_phy_of
  33. dsa_port_fixed_link_register_of
  34. dsa_port_phylink_register
  35. dsa_port_link_register_of
  36. dsa_port_link_unregister_of
  37. dsa_port_get_phy_strings
  38. dsa_port_get_ethtool_phy_stats
  39. dsa_port_get_phy_sset_count

   1 // SPDX-License-Identifier: GPL-2.0-or-later
   2 /*
   3  * Handling of a single switch port
   4  *
   5  * Copyright (c) 2017 Savoir-faire Linux Inc.
   6  *      Vivien Didelot <vivien.didelot@savoirfairelinux.com>
   7  */
   8 
   9 #include <linux/if_bridge.h>
  10 #include <linux/notifier.h>
  11 #include <linux/of_mdio.h>
  12 #include <linux/of_net.h>
  13 
  14 #include "dsa_priv.h"
  15 
  16 static int dsa_port_notify(const struct dsa_port *dp, unsigned long e, void *v)
  17 {
  18         struct raw_notifier_head *nh = &dp->ds->dst->nh;
  19         int err;
  20 
  21         err = raw_notifier_call_chain(nh, e, v);
  22 
  23         return notifier_to_errno(err);
  24 }
  25 
  26 int dsa_port_set_state(struct dsa_port *dp, u8 state,
  27                        struct switchdev_trans *trans)
  28 {
  29         struct dsa_switch *ds = dp->ds;
  30         int port = dp->index;
  31 
  32         if (switchdev_trans_ph_prepare(trans))
  33                 return ds->ops->port_stp_state_set ? 0 : -EOPNOTSUPP;
  34 
  35         if (ds->ops->port_stp_state_set)
  36                 ds->ops->port_stp_state_set(ds, port, state);
  37 
  38         if (ds->ops->port_fast_age) {
  39                 /* Fast age FDB entries or flush appropriate forwarding database
  40                  * for the given port, if we are moving it from Learning or
  41                  * Forwarding state, to Disabled or Blocking or Listening state.
  42                  */
  43 
  44                 if ((dp->stp_state == BR_STATE_LEARNING ||
  45                      dp->stp_state == BR_STATE_FORWARDING) &&
  46                     (state == BR_STATE_DISABLED ||
  47                      state == BR_STATE_BLOCKING ||
  48                      state == BR_STATE_LISTENING))
  49                         ds->ops->port_fast_age(ds, port);
  50         }
  51 
  52         dp->stp_state = state;
  53 
  54         return 0;
  55 }
  56 
  57 static void dsa_port_set_state_now(struct dsa_port *dp, u8 state)
  58 {
  59         int err;
  60 
  61         err = dsa_port_set_state(dp, state, NULL);
  62         if (err)
  63                 pr_err("DSA: failed to set STP state %u (%d)\n", state, err);
  64 }
  65 
  66 int dsa_port_enable_rt(struct dsa_port *dp, struct phy_device *phy)
  67 {
  68         struct dsa_switch *ds = dp->ds;
  69         int port = dp->index;
  70         int err;
  71 
  72         if (ds->ops->port_enable) {
  73                 err = ds->ops->port_enable(ds, port, phy);
  74                 if (err)
  75                         return err;
  76         }
  77 
  78         if (!dp->bridge_dev)
  79                 dsa_port_set_state_now(dp, BR_STATE_FORWARDING);
  80 
  81         if (dp->pl)
  82                 phylink_start(dp->pl);
  83 
  84         return 0;
  85 }
  86 
  87 int dsa_port_enable(struct dsa_port *dp, struct phy_device *phy)
  88 {
  89         int err;
  90 
  91         rtnl_lock();
  92         err = dsa_port_enable_rt(dp, phy);
  93         rtnl_unlock();
  94 
  95         return err;
  96 }
  97 
  98 void dsa_port_disable_rt(struct dsa_port *dp)
  99 {
 100         struct dsa_switch *ds = dp->ds;
 101         int port = dp->index;
 102 
 103         if (dp->pl)
 104                 phylink_stop(dp->pl);
 105 
 106         if (!dp->bridge_dev)
 107                 dsa_port_set_state_now(dp, BR_STATE_DISABLED);
 108 
 109         if (ds->ops->port_disable)
 110                 ds->ops->port_disable(ds, port);
 111 }
 112 
 113 void dsa_port_disable(struct dsa_port *dp)
 114 {
 115         rtnl_lock();
 116         dsa_port_disable_rt(dp);
 117         rtnl_unlock();
 118 }
 119 
 120 int dsa_port_bridge_join(struct dsa_port *dp, struct net_device *br)
 121 {
 122         struct dsa_notifier_bridge_info info = {
 123                 .sw_index = dp->ds->index,
 124                 .port = dp->index,
 125                 .br = br,
 126         };
 127         int err;
 128 
 129         /* Set the flooding mode before joining the port in the switch */
 130         err = dsa_port_bridge_flags(dp, BR_FLOOD | BR_MCAST_FLOOD, NULL);
 131         if (err)
 132                 return err;
 133 
 134         /* Here the interface is already bridged. Reflect the current
 135          * configuration so that drivers can program their chips accordingly.
 136          */
 137         dp->bridge_dev = br;
 138 
 139         err = dsa_port_notify(dp, DSA_NOTIFIER_BRIDGE_JOIN, &info);
 140 
 141         /* The bridging is rolled back on error */
 142         if (err) {
 143                 dsa_port_bridge_flags(dp, 0, NULL);
 144                 dp->bridge_dev = NULL;
 145         }
 146 
 147         return err;
 148 }
 149 
 150 void dsa_port_bridge_leave(struct dsa_port *dp, struct net_device *br)
 151 {
 152         struct dsa_notifier_bridge_info info = {
 153                 .sw_index = dp->ds->index,
 154                 .port = dp->index,
 155                 .br = br,
 156         };
 157         int err;
 158 
 159         /* Here the port is already unbridged. Reflect the current configuration
 160          * so that drivers can program their chips accordingly.
 161          */
 162         dp->bridge_dev = NULL;
 163 
 164         err = dsa_port_notify(dp, DSA_NOTIFIER_BRIDGE_LEAVE, &info);
 165         if (err)
 166                 pr_err("DSA: failed to notify DSA_NOTIFIER_BRIDGE_LEAVE\n");
 167 
 168         /* Port is leaving the bridge, disable flooding */
 169         dsa_port_bridge_flags(dp, 0, NULL);
 170 
 171         /* Port left the bridge, put in BR_STATE_DISABLED by the bridge layer,
 172          * so allow it to be in BR_STATE_FORWARDING to be kept functional
 173          */
 174         dsa_port_set_state_now(dp, BR_STATE_FORWARDING);
 175 }
 176 
 177 static bool dsa_port_can_apply_vlan_filtering(struct dsa_port *dp,
 178                                               bool vlan_filtering)
 179 {
 180         struct dsa_switch *ds = dp->ds;
 181         int i;
 182 
 183         if (!ds->vlan_filtering_is_global)
 184                 return true;
 185 
 186         /* For cases where enabling/disabling VLAN awareness is global to the
 187          * switch, we need to handle the case where multiple bridges span
 188          * different ports of the same switch device and one of them has a
 189          * different setting than what is being requested.
 190          */
 191         for (i = 0; i < ds->num_ports; i++) {
 192                 struct net_device *other_bridge;
 193 
 194                 other_bridge = dsa_to_port(ds, i)->bridge_dev;
 195                 if (!other_bridge)
 196                         continue;
 197                 /* If it's the same bridge, it also has same
 198                  * vlan_filtering setting => no need to check
 199                  */
 200                 if (other_bridge == dp->bridge_dev)
 201                         continue;
 202                 if (br_vlan_enabled(other_bridge) != vlan_filtering) {
 203                         dev_err(ds->dev, "VLAN filtering is a global setting\n");
 204                         return false;
 205                 }
 206         }
 207         return true;
 208 }
 209 
 210 int dsa_port_vlan_filtering(struct dsa_port *dp, bool vlan_filtering,
 211                             struct switchdev_trans *trans)
 212 {
 213         struct dsa_switch *ds = dp->ds;
 214         int err;
 215 
 216         /* bridge skips -EOPNOTSUPP, so skip the prepare phase */
 217         if (switchdev_trans_ph_prepare(trans))
 218                 return 0;
 219 
 220         if (!ds->ops->port_vlan_filtering)
 221                 return 0;
 222 
 223         if (!dsa_port_can_apply_vlan_filtering(dp, vlan_filtering))
 224                 return -EINVAL;
 225 
 226         if (dsa_port_is_vlan_filtering(dp) == vlan_filtering)
 227                 return 0;
 228 
 229         err = ds->ops->port_vlan_filtering(ds, dp->index,
 230                                            vlan_filtering);
 231         if (err)
 232                 return err;
 233 
 234         if (ds->vlan_filtering_is_global)
 235                 ds->vlan_filtering = vlan_filtering;
 236         else
 237                 dp->vlan_filtering = vlan_filtering;
 238         return 0;
 239 }
 240 
 241 int dsa_port_ageing_time(struct dsa_port *dp, clock_t ageing_clock,
 242                          struct switchdev_trans *trans)
 243 {
 244         unsigned long ageing_jiffies = clock_t_to_jiffies(ageing_clock);
 245         unsigned int ageing_time = jiffies_to_msecs(ageing_jiffies);
 246         struct dsa_notifier_ageing_time_info info = {
 247                 .ageing_time = ageing_time,
 248                 .trans = trans,
 249         };
 250 
 251         if (switchdev_trans_ph_prepare(trans))
 252                 return dsa_port_notify(dp, DSA_NOTIFIER_AGEING_TIME, &info);
 253 
 254         dp->ageing_time = ageing_time;
 255 
 256         return dsa_port_notify(dp, DSA_NOTIFIER_AGEING_TIME, &info);
 257 }
 258 
 259 int dsa_port_pre_bridge_flags(const struct dsa_port *dp, unsigned long flags,
 260                               struct switchdev_trans *trans)
 261 {
 262         struct dsa_switch *ds = dp->ds;
 263 
 264         if (!ds->ops->port_egress_floods ||
 265             (flags & ~(BR_FLOOD | BR_MCAST_FLOOD)))
 266                 return -EINVAL;
 267 
 268         return 0;
 269 }
 270 
 271 int dsa_port_bridge_flags(const struct dsa_port *dp, unsigned long flags,
 272                           struct switchdev_trans *trans)
 273 {
 274         struct dsa_switch *ds = dp->ds;
 275         int port = dp->index;
 276         int err = 0;
 277 
 278         if (switchdev_trans_ph_prepare(trans))
 279                 return 0;
 280 
 281         if (ds->ops->port_egress_floods)
 282                 err = ds->ops->port_egress_floods(ds, port, flags & BR_FLOOD,
 283                                                   flags & BR_MCAST_FLOOD);
 284 
 285         return err;
 286 }
 287 
 288 int dsa_port_mrouter(struct dsa_port *dp, bool mrouter,
 289                      struct switchdev_trans *trans)
 290 {
 291         struct dsa_switch *ds = dp->ds;
 292         int port = dp->index;
 293 
 294         if (switchdev_trans_ph_prepare(trans))
 295                 return ds->ops->port_egress_floods ? 0 : -EOPNOTSUPP;
 296 
 297         return ds->ops->port_egress_floods(ds, port, true, mrouter);
 298 }
 299 
 300 int dsa_port_fdb_add(struct dsa_port *dp, const unsigned char *addr,
 301                      u16 vid)
 302 {
 303         struct dsa_notifier_fdb_info info = {
 304                 .sw_index = dp->ds->index,
 305                 .port = dp->index,
 306                 .addr = addr,
 307                 .vid = vid,
 308         };
 309 
 310         return dsa_port_notify(dp, DSA_NOTIFIER_FDB_ADD, &info);
 311 }
 312 
 313 int dsa_port_fdb_del(struct dsa_port *dp, const unsigned char *addr,
 314                      u16 vid)
 315 {
 316         struct dsa_notifier_fdb_info info = {
 317                 .sw_index = dp->ds->index,
 318                 .port = dp->index,
 319                 .addr = addr,
 320                 .vid = vid,
 321 
 322         };
 323 
 324         return dsa_port_notify(dp, DSA_NOTIFIER_FDB_DEL, &info);
 325 }
 326 
 327 int dsa_port_fdb_dump(struct dsa_port *dp, dsa_fdb_dump_cb_t *cb, void *data)
 328 {
 329         struct dsa_switch *ds = dp->ds;
 330         int port = dp->index;
 331 
 332         if (!ds->ops->port_fdb_dump)
 333                 return -EOPNOTSUPP;
 334 
 335         return ds->ops->port_fdb_dump(ds, port, cb, data);
 336 }
 337 
 338 int dsa_port_mdb_add(const struct dsa_port *dp,
 339                      const struct switchdev_obj_port_mdb *mdb,
 340                      struct switchdev_trans *trans)
 341 {
 342         struct dsa_notifier_mdb_info info = {
 343                 .sw_index = dp->ds->index,
 344                 .port = dp->index,
 345                 .trans = trans,
 346                 .mdb = mdb,
 347         };
 348 
 349         return dsa_port_notify(dp, DSA_NOTIFIER_MDB_ADD, &info);
 350 }
 351 
 352 int dsa_port_mdb_del(const struct dsa_port *dp,
 353                      const struct switchdev_obj_port_mdb *mdb)
 354 {
 355         struct dsa_notifier_mdb_info info = {
 356                 .sw_index = dp->ds->index,
 357                 .port = dp->index,
 358                 .mdb = mdb,
 359         };
 360 
 361         return dsa_port_notify(dp, DSA_NOTIFIER_MDB_DEL, &info);
 362 }
 363 
 364 int dsa_port_vlan_add(struct dsa_port *dp,
 365                       const struct switchdev_obj_port_vlan *vlan,
 366                       struct switchdev_trans *trans)
 367 {
 368         struct dsa_notifier_vlan_info info = {
 369                 .sw_index = dp->ds->index,
 370                 .port = dp->index,
 371                 .trans = trans,
 372                 .vlan = vlan,
 373         };
 374 
 375         return dsa_port_notify(dp, DSA_NOTIFIER_VLAN_ADD, &info);
 376 }
 377 
 378 int dsa_port_vlan_del(struct dsa_port *dp,
 379                       const struct switchdev_obj_port_vlan *vlan)
 380 {
 381         struct dsa_notifier_vlan_info info = {
 382                 .sw_index = dp->ds->index,
 383                 .port = dp->index,
 384                 .vlan = vlan,
 385         };
 386 
 387         return dsa_port_notify(dp, DSA_NOTIFIER_VLAN_DEL, &info);
 388 }
 389 
 390 int dsa_port_vid_add(struct dsa_port *dp, u16 vid, u16 flags)
 391 {
 392         struct switchdev_obj_port_vlan vlan = {
 393                 .obj.id = SWITCHDEV_OBJ_ID_PORT_VLAN,
 394                 .flags = flags,
 395                 .vid_begin = vid,
 396                 .vid_end = vid,
 397         };
 398         struct switchdev_trans trans;
 399         int err;
 400 
 401         trans.ph_prepare = true;
 402         err = dsa_port_vlan_add(dp, &vlan, &trans);
 403         if (err)
 404                 return err;
 405 
 406         trans.ph_prepare = false;
 407         return dsa_port_vlan_add(dp, &vlan, &trans);
 408 }
 409 EXPORT_SYMBOL(dsa_port_vid_add);
 410 
 411 int dsa_port_vid_del(struct dsa_port *dp, u16 vid)
 412 {
 413         struct switchdev_obj_port_vlan vlan = {
 414                 .obj.id = SWITCHDEV_OBJ_ID_PORT_VLAN,
 415                 .vid_begin = vid,
 416                 .vid_end = vid,
 417         };
 418 
 419         return dsa_port_vlan_del(dp, &vlan);
 420 }
 421 EXPORT_SYMBOL(dsa_port_vid_del);
 422 
 423 static struct phy_device *dsa_port_get_phy_device(struct dsa_port *dp)
 424 {
 425         struct device_node *phy_dn;
 426         struct phy_device *phydev;
 427 
 428         phy_dn = of_parse_phandle(dp->dn, "phy-handle", 0);
 429         if (!phy_dn)
 430                 return NULL;
 431 
 432         phydev = of_phy_find_device(phy_dn);
 433         if (!phydev) {
 434                 of_node_put(phy_dn);
 435                 return ERR_PTR(-EPROBE_DEFER);
 436         }
 437 
 438         of_node_put(phy_dn);
 439         return phydev;
 440 }
 441 
 442 void dsa_port_phylink_validate(struct phylink_config *config,
 443                                unsigned long *supported,
 444                                struct phylink_link_state *state)
 445 {
 446         struct dsa_port *dp = container_of(config, struct dsa_port, pl_config);
 447         struct dsa_switch *ds = dp->ds;
 448 
 449         if (!ds->ops->phylink_validate)
 450                 return;
 451 
 452         ds->ops->phylink_validate(ds, dp->index, supported, state);
 453 }
 454 EXPORT_SYMBOL_GPL(dsa_port_phylink_validate);
 455 
 456 int dsa_port_phylink_mac_link_state(struct phylink_config *config,
 457                                     struct phylink_link_state *state)
 458 {
 459         struct dsa_port *dp = container_of(config, struct dsa_port, pl_config);
 460         struct dsa_switch *ds = dp->ds;
 461 
 462         /* Only called for SGMII and 802.3z */
 463         if (!ds->ops->phylink_mac_link_state)
 464                 return -EOPNOTSUPP;
 465 
 466         return ds->ops->phylink_mac_link_state(ds, dp->index, state);
 467 }
 468 EXPORT_SYMBOL_GPL(dsa_port_phylink_mac_link_state);
 469 
 470 void dsa_port_phylink_mac_config(struct phylink_config *config,
 471                                  unsigned int mode,
 472                                  const struct phylink_link_state *state)
 473 {
 474         struct dsa_port *dp = container_of(config, struct dsa_port, pl_config);
 475         struct dsa_switch *ds = dp->ds;
 476 
 477         if (!ds->ops->phylink_mac_config)
 478                 return;
 479 
 480         ds->ops->phylink_mac_config(ds, dp->index, mode, state);
 481 }
 482 EXPORT_SYMBOL_GPL(dsa_port_phylink_mac_config);
 483 
 484 void dsa_port_phylink_mac_an_restart(struct phylink_config *config)
 485 {
 486         struct dsa_port *dp = container_of(config, struct dsa_port, pl_config);
 487         struct dsa_switch *ds = dp->ds;
 488 
 489         if (!ds->ops->phylink_mac_an_restart)
 490                 return;
 491 
 492         ds->ops->phylink_mac_an_restart(ds, dp->index);
 493 }
 494 EXPORT_SYMBOL_GPL(dsa_port_phylink_mac_an_restart);
 495 
 496 void dsa_port_phylink_mac_link_down(struct phylink_config *config,
 497                                     unsigned int mode,
 498                                     phy_interface_t interface)
 499 {
 500         struct dsa_port *dp = container_of(config, struct dsa_port, pl_config);
 501         struct phy_device *phydev = NULL;
 502         struct dsa_switch *ds = dp->ds;
 503 
 504         if (dsa_is_user_port(ds, dp->index))
 505                 phydev = dp->slave->phydev;
 506 
 507         if (!ds->ops->phylink_mac_link_down) {
 508                 if (ds->ops->adjust_link && phydev)
 509                         ds->ops->adjust_link(ds, dp->index, phydev);
 510                 return;
 511         }
 512 
 513         ds->ops->phylink_mac_link_down(ds, dp->index, mode, interface);
 514 }
 515 EXPORT_SYMBOL_GPL(dsa_port_phylink_mac_link_down);
 516 
 517 void dsa_port_phylink_mac_link_up(struct phylink_config *config,
 518                                   unsigned int mode,
 519                                   phy_interface_t interface,
 520                                   struct phy_device *phydev)
 521 {
 522         struct dsa_port *dp = container_of(config, struct dsa_port, pl_config);
 523         struct dsa_switch *ds = dp->ds;
 524 
 525         if (!ds->ops->phylink_mac_link_up) {
 526                 if (ds->ops->adjust_link && phydev)
 527                         ds->ops->adjust_link(ds, dp->index, phydev);
 528                 return;
 529         }
 530 
 531         ds->ops->phylink_mac_link_up(ds, dp->index, mode, interface, phydev);
 532 }
 533 EXPORT_SYMBOL_GPL(dsa_port_phylink_mac_link_up);
 534 
 535 const struct phylink_mac_ops dsa_port_phylink_mac_ops = {
 536         .validate = dsa_port_phylink_validate,
 537         .mac_link_state = dsa_port_phylink_mac_link_state,
 538         .mac_config = dsa_port_phylink_mac_config,
 539         .mac_an_restart = dsa_port_phylink_mac_an_restart,
 540         .mac_link_down = dsa_port_phylink_mac_link_down,
 541         .mac_link_up = dsa_port_phylink_mac_link_up,
 542 };
 543 
 544 static int dsa_port_setup_phy_of(struct dsa_port *dp, bool enable)
 545 {
 546         struct dsa_switch *ds = dp->ds;
 547         struct phy_device *phydev;
 548         int port = dp->index;
 549         int err = 0;
 550 
 551         phydev = dsa_port_get_phy_device(dp);
 552         if (!phydev)
 553                 return 0;
 554 
 555         if (IS_ERR(phydev))
 556                 return PTR_ERR(phydev);
 557 
 558         if (enable) {
 559                 err = genphy_resume(phydev);
 560                 if (err < 0)
 561                         goto err_put_dev;
 562 
 563                 err = genphy_read_status(phydev);
 564                 if (err < 0)
 565                         goto err_put_dev;
 566         } else {
 567                 err = genphy_suspend(phydev);
 568                 if (err < 0)
 569                         goto err_put_dev;
 570         }
 571 
 572         if (ds->ops->adjust_link)
 573                 ds->ops->adjust_link(ds, port, phydev);
 574 
 575         dev_dbg(ds->dev, "enabled port's phy: %s", phydev_name(phydev));
 576 
 577 err_put_dev:
 578         put_device(&phydev->mdio.dev);
 579         return err;
 580 }
 581 
 582 static int dsa_port_fixed_link_register_of(struct dsa_port *dp)
 583 {
 584         struct device_node *dn = dp->dn;
 585         struct dsa_switch *ds = dp->ds;
 586         struct phy_device *phydev;
 587         int port = dp->index;
 588         int mode;
 589         int err;
 590 
 591         err = of_phy_register_fixed_link(dn);
 592         if (err) {
 593                 dev_err(ds->dev,
 594                         "failed to register the fixed PHY of port %d\n",
 595                         port);
 596                 return err;
 597         }
 598 
 599         phydev = of_phy_find_device(dn);
 600 
 601         mode = of_get_phy_mode(dn);
 602         if (mode < 0)
 603                 mode = PHY_INTERFACE_MODE_NA;
 604         phydev->interface = mode;
 605 
 606         genphy_read_status(phydev);
 607 
 608         if (ds->ops->adjust_link)
 609                 ds->ops->adjust_link(ds, port, phydev);
 610 
 611         put_device(&phydev->mdio.dev);
 612 
 613         return 0;
 614 }
 615 
 616 static int dsa_port_phylink_register(struct dsa_port *dp)
 617 {
 618         struct dsa_switch *ds = dp->ds;
 619         struct device_node *port_dn = dp->dn;
 620         int mode, err;
 621 
 622         mode = of_get_phy_mode(port_dn);
 623         if (mode < 0)
 624                 mode = PHY_INTERFACE_MODE_NA;
 625 
 626         dp->pl_config.dev = ds->dev;
 627         dp->pl_config.type = PHYLINK_DEV;
 628 
 629         dp->pl = phylink_create(&dp->pl_config, of_fwnode_handle(port_dn),
 630                                 mode, &dsa_port_phylink_mac_ops);
 631         if (IS_ERR(dp->pl)) {
 632                 pr_err("error creating PHYLINK: %ld\n", PTR_ERR(dp->pl));
 633                 return PTR_ERR(dp->pl);
 634         }
 635 
 636         err = phylink_of_phy_connect(dp->pl, port_dn, 0);
 637         if (err && err != -ENODEV) {
 638                 pr_err("could not attach to PHY: %d\n", err);
 639                 goto err_phy_connect;
 640         }
 641 
 642         return 0;
 643 
 644 err_phy_connect:
 645         phylink_destroy(dp->pl);
 646         return err;
 647 }
 648 
 649 int dsa_port_link_register_of(struct dsa_port *dp)
 650 {
 651         struct dsa_switch *ds = dp->ds;
 652         struct device_node *phy_np;
 653 
 654         if (!ds->ops->adjust_link) {
 655                 phy_np = of_parse_phandle(dp->dn, "phy-handle", 0);
 656                 if (of_phy_is_fixed_link(dp->dn) || phy_np)
 657                         return dsa_port_phylink_register(dp);
 658                 return 0;
 659         }
 660 
 661         dev_warn(ds->dev,
 662                  "Using legacy PHYLIB callbacks. Please migrate to PHYLINK!\n");
 663 
 664         if (of_phy_is_fixed_link(dp->dn))
 665                 return dsa_port_fixed_link_register_of(dp);
 666         else
 667                 return dsa_port_setup_phy_of(dp, true);
 668 }
 669 
 670 void dsa_port_link_unregister_of(struct dsa_port *dp)
 671 {
 672         struct dsa_switch *ds = dp->ds;
 673 
 674         if (!ds->ops->adjust_link && dp->pl) {
 675                 rtnl_lock();
 676                 phylink_disconnect_phy(dp->pl);
 677                 rtnl_unlock();
 678                 phylink_destroy(dp->pl);
 679                 dp->pl = NULL;
 680                 return;
 681         }
 682 
 683         if (of_phy_is_fixed_link(dp->dn))
 684                 of_phy_deregister_fixed_link(dp->dn);
 685         else
 686                 dsa_port_setup_phy_of(dp, false);
 687 }
 688 
 689 int dsa_port_get_phy_strings(struct dsa_port *dp, uint8_t *data)
 690 {
 691         struct phy_device *phydev;
 692         int ret = -EOPNOTSUPP;
 693 
 694         if (of_phy_is_fixed_link(dp->dn))
 695                 return ret;
 696 
 697         phydev = dsa_port_get_phy_device(dp);
 698         if (IS_ERR_OR_NULL(phydev))
 699                 return ret;
 700 
 701         ret = phy_ethtool_get_strings(phydev, data);
 702         put_device(&phydev->mdio.dev);
 703 
 704         return ret;
 705 }
 706 EXPORT_SYMBOL_GPL(dsa_port_get_phy_strings);
 707 
 708 int dsa_port_get_ethtool_phy_stats(struct dsa_port *dp, uint64_t *data)
 709 {
 710         struct phy_device *phydev;
 711         int ret = -EOPNOTSUPP;
 712 
 713         if (of_phy_is_fixed_link(dp->dn))
 714                 return ret;
 715 
 716         phydev = dsa_port_get_phy_device(dp);
 717         if (IS_ERR_OR_NULL(phydev))
 718                 return ret;
 719 
 720         ret = phy_ethtool_get_stats(phydev, NULL, data);
 721         put_device(&phydev->mdio.dev);
 722 
 723         return ret;
 724 }
 725 EXPORT_SYMBOL_GPL(dsa_port_get_ethtool_phy_stats);
 726 
 727 int dsa_port_get_phy_sset_count(struct dsa_port *dp)
 728 {
 729         struct phy_device *phydev;
 730         int ret = -EOPNOTSUPP;
 731 
 732         if (of_phy_is_fixed_link(dp->dn))
 733                 return ret;
 734 
 735         phydev = dsa_port_get_phy_device(dp);
 736         if (IS_ERR_OR_NULL(phydev))
 737                 return ret;
 738 
 739         ret = phy_ethtool_get_sset_count(phydev);
 740         put_device(&phydev->mdio.dev);
 741 
 742         return ret;
 743 }
 744 EXPORT_SYMBOL_GPL(dsa_port_get_phy_sset_count);

/* [<][>][^][v][top][bottom][index][help] */