root/drivers/net/dsa/dsa_loop.c

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

DEFINITIONS

This source file includes following definitions.
  1. dsa_loop_get_protocol
  2. dsa_loop_setup
  3. dsa_loop_get_sset_count
  4. dsa_loop_get_strings
  5. dsa_loop_get_ethtool_stats
  6. dsa_loop_phy_read
  7. dsa_loop_phy_write
  8. dsa_loop_port_bridge_join
  9. dsa_loop_port_bridge_leave
  10. dsa_loop_port_stp_state_set
  11. dsa_loop_port_vlan_filtering
  12. dsa_loop_port_vlan_prepare
  13. dsa_loop_port_vlan_add
  14. dsa_loop_port_vlan_del
  15. dsa_loop_drv_probe
  16. dsa_loop_drv_remove
  17. dsa_loop_init
  18. dsa_loop_exit

   1 // SPDX-License-Identifier: GPL-2.0-or-later
   2 /*
   3  * Distributed Switch Architecture loopback driver
   4  *
   5  * Copyright (C) 2016, Florian Fainelli <f.fainelli@gmail.com>
   6  */
   7 
   8 #include <linux/platform_device.h>
   9 #include <linux/netdevice.h>
  10 #include <linux/phy.h>
  11 #include <linux/phy_fixed.h>
  12 #include <linux/export.h>
  13 #include <linux/ethtool.h>
  14 #include <linux/workqueue.h>
  15 #include <linux/module.h>
  16 #include <linux/if_bridge.h>
  17 #include <net/dsa.h>
  18 
  19 #include "dsa_loop.h"
  20 
  21 struct dsa_loop_vlan {
  22         u16 members;
  23         u16 untagged;
  24 };
  25 
  26 struct dsa_loop_mib_entry {
  27         char name[ETH_GSTRING_LEN];
  28         unsigned long val;
  29 };
  30 
  31 enum dsa_loop_mib_counters {
  32         DSA_LOOP_PHY_READ_OK,
  33         DSA_LOOP_PHY_READ_ERR,
  34         DSA_LOOP_PHY_WRITE_OK,
  35         DSA_LOOP_PHY_WRITE_ERR,
  36         __DSA_LOOP_CNT_MAX,
  37 };
  38 
  39 static struct dsa_loop_mib_entry dsa_loop_mibs[] = {
  40         [DSA_LOOP_PHY_READ_OK]  = { "phy_read_ok", },
  41         [DSA_LOOP_PHY_READ_ERR] = { "phy_read_err", },
  42         [DSA_LOOP_PHY_WRITE_OK] = { "phy_write_ok", },
  43         [DSA_LOOP_PHY_WRITE_ERR] = { "phy_write_err", },
  44 };
  45 
  46 struct dsa_loop_port {
  47         struct dsa_loop_mib_entry mib[__DSA_LOOP_CNT_MAX];
  48 };
  49 
  50 #define DSA_LOOP_VLANS  5
  51 
  52 struct dsa_loop_priv {
  53         struct mii_bus  *bus;
  54         unsigned int    port_base;
  55         struct dsa_loop_vlan vlans[DSA_LOOP_VLANS];
  56         struct net_device *netdev;
  57         struct dsa_loop_port ports[DSA_MAX_PORTS];
  58         u16 pvid;
  59 };
  60 
  61 static struct phy_device *phydevs[PHY_MAX_ADDR];
  62 
  63 static enum dsa_tag_protocol dsa_loop_get_protocol(struct dsa_switch *ds,
  64                                                    int port)
  65 {
  66         dev_dbg(ds->dev, "%s: port: %d\n", __func__, port);
  67 
  68         return DSA_TAG_PROTO_NONE;
  69 }
  70 
  71 static int dsa_loop_setup(struct dsa_switch *ds)
  72 {
  73         struct dsa_loop_priv *ps = ds->priv;
  74         unsigned int i;
  75 
  76         for (i = 0; i < ds->num_ports; i++)
  77                 memcpy(ps->ports[i].mib, dsa_loop_mibs,
  78                        sizeof(dsa_loop_mibs));
  79 
  80         dev_dbg(ds->dev, "%s\n", __func__);
  81 
  82         return 0;
  83 }
  84 
  85 static int dsa_loop_get_sset_count(struct dsa_switch *ds, int port, int sset)
  86 {
  87         if (sset != ETH_SS_STATS && sset != ETH_SS_PHY_STATS)
  88                 return 0;
  89 
  90         return __DSA_LOOP_CNT_MAX;
  91 }
  92 
  93 static void dsa_loop_get_strings(struct dsa_switch *ds, int port,
  94                                  u32 stringset, uint8_t *data)
  95 {
  96         struct dsa_loop_priv *ps = ds->priv;
  97         unsigned int i;
  98 
  99         if (stringset != ETH_SS_STATS && stringset != ETH_SS_PHY_STATS)
 100                 return;
 101 
 102         for (i = 0; i < __DSA_LOOP_CNT_MAX; i++)
 103                 memcpy(data + i * ETH_GSTRING_LEN,
 104                        ps->ports[port].mib[i].name, ETH_GSTRING_LEN);
 105 }
 106 
 107 static void dsa_loop_get_ethtool_stats(struct dsa_switch *ds, int port,
 108                                        uint64_t *data)
 109 {
 110         struct dsa_loop_priv *ps = ds->priv;
 111         unsigned int i;
 112 
 113         for (i = 0; i < __DSA_LOOP_CNT_MAX; i++)
 114                 data[i] = ps->ports[port].mib[i].val;
 115 }
 116 
 117 static int dsa_loop_phy_read(struct dsa_switch *ds, int port, int regnum)
 118 {
 119         struct dsa_loop_priv *ps = ds->priv;
 120         struct mii_bus *bus = ps->bus;
 121         int ret;
 122 
 123         ret = mdiobus_read_nested(bus, ps->port_base + port, regnum);
 124         if (ret < 0)
 125                 ps->ports[port].mib[DSA_LOOP_PHY_READ_ERR].val++;
 126         else
 127                 ps->ports[port].mib[DSA_LOOP_PHY_READ_OK].val++;
 128 
 129         return ret;
 130 }
 131 
 132 static int dsa_loop_phy_write(struct dsa_switch *ds, int port,
 133                               int regnum, u16 value)
 134 {
 135         struct dsa_loop_priv *ps = ds->priv;
 136         struct mii_bus *bus = ps->bus;
 137         int ret;
 138 
 139         ret = mdiobus_write_nested(bus, ps->port_base + port, regnum, value);
 140         if (ret < 0)
 141                 ps->ports[port].mib[DSA_LOOP_PHY_WRITE_ERR].val++;
 142         else
 143                 ps->ports[port].mib[DSA_LOOP_PHY_WRITE_OK].val++;
 144 
 145         return ret;
 146 }
 147 
 148 static int dsa_loop_port_bridge_join(struct dsa_switch *ds, int port,
 149                                      struct net_device *bridge)
 150 {
 151         dev_dbg(ds->dev, "%s: port: %d, bridge: %s\n",
 152                 __func__, port, bridge->name);
 153 
 154         return 0;
 155 }
 156 
 157 static void dsa_loop_port_bridge_leave(struct dsa_switch *ds, int port,
 158                                        struct net_device *bridge)
 159 {
 160         dev_dbg(ds->dev, "%s: port: %d, bridge: %s\n",
 161                 __func__, port, bridge->name);
 162 }
 163 
 164 static void dsa_loop_port_stp_state_set(struct dsa_switch *ds, int port,
 165                                         u8 state)
 166 {
 167         dev_dbg(ds->dev, "%s: port: %d, state: %d\n",
 168                 __func__, port, state);
 169 }
 170 
 171 static int dsa_loop_port_vlan_filtering(struct dsa_switch *ds, int port,
 172                                         bool vlan_filtering)
 173 {
 174         dev_dbg(ds->dev, "%s: port: %d, vlan_filtering: %d\n",
 175                 __func__, port, vlan_filtering);
 176 
 177         return 0;
 178 }
 179 
 180 static int
 181 dsa_loop_port_vlan_prepare(struct dsa_switch *ds, int port,
 182                            const struct switchdev_obj_port_vlan *vlan)
 183 {
 184         struct dsa_loop_priv *ps = ds->priv;
 185         struct mii_bus *bus = ps->bus;
 186 
 187         dev_dbg(ds->dev, "%s: port: %d, vlan: %d-%d",
 188                 __func__, port, vlan->vid_begin, vlan->vid_end);
 189 
 190         /* Just do a sleeping operation to make lockdep checks effective */
 191         mdiobus_read(bus, ps->port_base + port, MII_BMSR);
 192 
 193         if (vlan->vid_end > DSA_LOOP_VLANS)
 194                 return -ERANGE;
 195 
 196         return 0;
 197 }
 198 
 199 static void dsa_loop_port_vlan_add(struct dsa_switch *ds, int port,
 200                                    const struct switchdev_obj_port_vlan *vlan)
 201 {
 202         bool untagged = vlan->flags & BRIDGE_VLAN_INFO_UNTAGGED;
 203         bool pvid = vlan->flags & BRIDGE_VLAN_INFO_PVID;
 204         struct dsa_loop_priv *ps = ds->priv;
 205         struct mii_bus *bus = ps->bus;
 206         struct dsa_loop_vlan *vl;
 207         u16 vid;
 208 
 209         /* Just do a sleeping operation to make lockdep checks effective */
 210         mdiobus_read(bus, ps->port_base + port, MII_BMSR);
 211 
 212         for (vid = vlan->vid_begin; vid <= vlan->vid_end; ++vid) {
 213                 vl = &ps->vlans[vid];
 214 
 215                 vl->members |= BIT(port);
 216                 if (untagged)
 217                         vl->untagged |= BIT(port);
 218                 else
 219                         vl->untagged &= ~BIT(port);
 220 
 221                 dev_dbg(ds->dev, "%s: port: %d vlan: %d, %stagged, pvid: %d\n",
 222                         __func__, port, vid, untagged ? "un" : "", pvid);
 223         }
 224 
 225         if (pvid)
 226                 ps->pvid = vid;
 227 }
 228 
 229 static int dsa_loop_port_vlan_del(struct dsa_switch *ds, int port,
 230                                   const struct switchdev_obj_port_vlan *vlan)
 231 {
 232         bool untagged = vlan->flags & BRIDGE_VLAN_INFO_UNTAGGED;
 233         struct dsa_loop_priv *ps = ds->priv;
 234         struct mii_bus *bus = ps->bus;
 235         struct dsa_loop_vlan *vl;
 236         u16 vid, pvid = ps->pvid;
 237 
 238         /* Just do a sleeping operation to make lockdep checks effective */
 239         mdiobus_read(bus, ps->port_base + port, MII_BMSR);
 240 
 241         for (vid = vlan->vid_begin; vid <= vlan->vid_end; ++vid) {
 242                 vl = &ps->vlans[vid];
 243 
 244                 vl->members &= ~BIT(port);
 245                 if (untagged)
 246                         vl->untagged &= ~BIT(port);
 247 
 248                 if (pvid == vid)
 249                         pvid = 1;
 250 
 251                 dev_dbg(ds->dev, "%s: port: %d vlan: %d, %stagged, pvid: %d\n",
 252                         __func__, port, vid, untagged ? "un" : "", pvid);
 253         }
 254         ps->pvid = pvid;
 255 
 256         return 0;
 257 }
 258 
 259 static const struct dsa_switch_ops dsa_loop_driver = {
 260         .get_tag_protocol       = dsa_loop_get_protocol,
 261         .setup                  = dsa_loop_setup,
 262         .get_strings            = dsa_loop_get_strings,
 263         .get_ethtool_stats      = dsa_loop_get_ethtool_stats,
 264         .get_sset_count         = dsa_loop_get_sset_count,
 265         .get_ethtool_phy_stats  = dsa_loop_get_ethtool_stats,
 266         .phy_read               = dsa_loop_phy_read,
 267         .phy_write              = dsa_loop_phy_write,
 268         .port_bridge_join       = dsa_loop_port_bridge_join,
 269         .port_bridge_leave      = dsa_loop_port_bridge_leave,
 270         .port_stp_state_set     = dsa_loop_port_stp_state_set,
 271         .port_vlan_filtering    = dsa_loop_port_vlan_filtering,
 272         .port_vlan_prepare      = dsa_loop_port_vlan_prepare,
 273         .port_vlan_add          = dsa_loop_port_vlan_add,
 274         .port_vlan_del          = dsa_loop_port_vlan_del,
 275 };
 276 
 277 static int dsa_loop_drv_probe(struct mdio_device *mdiodev)
 278 {
 279         struct dsa_loop_pdata *pdata = mdiodev->dev.platform_data;
 280         struct dsa_loop_priv *ps;
 281         struct dsa_switch *ds;
 282 
 283         if (!pdata)
 284                 return -ENODEV;
 285 
 286         dev_info(&mdiodev->dev, "%s: 0x%0x\n",
 287                  pdata->name, pdata->enabled_ports);
 288 
 289         ds = dsa_switch_alloc(&mdiodev->dev, DSA_MAX_PORTS);
 290         if (!ds)
 291                 return -ENOMEM;
 292 
 293         ps = devm_kzalloc(&mdiodev->dev, sizeof(*ps), GFP_KERNEL);
 294         if (!ps)
 295                 return -ENOMEM;
 296 
 297         ps->netdev = dev_get_by_name(&init_net, pdata->netdev);
 298         if (!ps->netdev)
 299                 return -EPROBE_DEFER;
 300 
 301         pdata->cd.netdev[DSA_LOOP_CPU_PORT] = &ps->netdev->dev;
 302 
 303         ds->dev = &mdiodev->dev;
 304         ds->ops = &dsa_loop_driver;
 305         ds->priv = ps;
 306         ps->bus = mdiodev->bus;
 307 
 308         dev_set_drvdata(&mdiodev->dev, ds);
 309 
 310         return dsa_register_switch(ds);
 311 }
 312 
 313 static void dsa_loop_drv_remove(struct mdio_device *mdiodev)
 314 {
 315         struct dsa_switch *ds = dev_get_drvdata(&mdiodev->dev);
 316         struct dsa_loop_priv *ps = ds->priv;
 317 
 318         dsa_unregister_switch(ds);
 319         dev_put(ps->netdev);
 320 }
 321 
 322 static struct mdio_driver dsa_loop_drv = {
 323         .mdiodrv.driver = {
 324                 .name   = "dsa-loop",
 325         },
 326         .probe  = dsa_loop_drv_probe,
 327         .remove = dsa_loop_drv_remove,
 328 };
 329 
 330 #define NUM_FIXED_PHYS  (DSA_LOOP_NUM_PORTS - 2)
 331 
 332 static int __init dsa_loop_init(void)
 333 {
 334         struct fixed_phy_status status = {
 335                 .link = 1,
 336                 .speed = SPEED_100,
 337                 .duplex = DUPLEX_FULL,
 338         };
 339         unsigned int i;
 340 
 341         for (i = 0; i < NUM_FIXED_PHYS; i++)
 342                 phydevs[i] = fixed_phy_register(PHY_POLL, &status, NULL);
 343 
 344         return mdio_driver_register(&dsa_loop_drv);
 345 }
 346 module_init(dsa_loop_init);
 347 
 348 static void __exit dsa_loop_exit(void)
 349 {
 350         unsigned int i;
 351 
 352         mdio_driver_unregister(&dsa_loop_drv);
 353         for (i = 0; i < NUM_FIXED_PHYS; i++)
 354                 if (!IS_ERR(phydevs[i]))
 355                         fixed_phy_unregister(phydevs[i]);
 356 }
 357 module_exit(dsa_loop_exit);
 358 
 359 MODULE_SOFTDEP("pre: dsa_loop_bdinfo");
 360 MODULE_LICENSE("GPL");
 361 MODULE_AUTHOR("Florian Fainelli");
 362 MODULE_DESCRIPTION("DSA loopback driver");

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