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