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