1 /* 2 * net/dsa/dsa.c - Hardware switch handling 3 * Copyright (c) 2008-2009 Marvell Semiconductor 4 * 5 * This program is free software; you can redistribute it and/or modify 6 * it under the terms of the GNU General Public License as published by 7 * the Free Software Foundation; either version 2 of the License, or 8 * (at your option) any later version. 9 */ 10 11 #include <linux/list.h> 12 #include <linux/netdevice.h> 13 #include <linux/platform_device.h> 14 #include <linux/slab.h> 15 #include <net/dsa.h> 16 #include "dsa_priv.h" 17 18 char dsa_driver_version[] = "0.1"; 19 20 21 /* switch driver registration ***********************************************/ 22 static DEFINE_MUTEX(dsa_switch_drivers_mutex); 23 static LIST_HEAD(dsa_switch_drivers); 24 25 void register_switch_driver(struct dsa_switch_driver *drv) 26 { 27 mutex_lock(&dsa_switch_drivers_mutex); 28 list_add_tail(&drv->list, &dsa_switch_drivers); 29 mutex_unlock(&dsa_switch_drivers_mutex); 30 } 31 32 void unregister_switch_driver(struct dsa_switch_driver *drv) 33 { 34 mutex_lock(&dsa_switch_drivers_mutex); 35 list_del_init(&drv->list); 36 mutex_unlock(&dsa_switch_drivers_mutex); 37 } 38 39 static struct dsa_switch_driver * 40 dsa_switch_probe(struct mii_bus *bus, int sw_addr, char **_name) 41 { 42 struct dsa_switch_driver *ret; 43 struct list_head *list; 44 char *name; 45 46 ret = NULL; 47 name = NULL; 48 49 mutex_lock(&dsa_switch_drivers_mutex); 50 list_for_each(list, &dsa_switch_drivers) { 51 struct dsa_switch_driver *drv; 52 53 drv = list_entry(list, struct dsa_switch_driver, list); 54 55 name = drv->probe(bus, sw_addr); 56 if (name != NULL) { 57 ret = drv; 58 break; 59 } 60 } 61 mutex_unlock(&dsa_switch_drivers_mutex); 62 63 *_name = name; 64 65 return ret; 66 } 67 68 69 /* basic switch operations **************************************************/ 70 static struct dsa_switch * 71 dsa_switch_setup(struct dsa_switch_tree *dst, int index, 72 struct device *parent, struct mii_bus *bus) 73 { 74 struct dsa_chip_data *pd = dst->pd->chip + index; 75 struct dsa_switch_driver *drv; 76 struct dsa_switch *ds; 77 int ret; 78 char *name; 79 int i; 80 81 /* 82 * Probe for switch model. 83 */ 84 drv = dsa_switch_probe(bus, pd->sw_addr, &name); 85 if (drv == NULL) { 86 printk(KERN_ERR "%s[%d]: could not detect attached switch\n", 87 dst->master_netdev->name, index); 88 return ERR_PTR(-EINVAL); 89 } 90 printk(KERN_INFO "%s[%d]: detected a %s switch\n", 91 dst->master_netdev->name, index, name); 92 93 94 /* 95 * Allocate and initialise switch state. 96 */ 97 ds = kzalloc(sizeof(*ds) + drv->priv_size, GFP_KERNEL); 98 if (ds == NULL) 99 return ERR_PTR(-ENOMEM); 100 101 ds->dst = dst; 102 ds->index = index; 103 ds->pd = dst->pd->chip + index; 104 ds->drv = drv; 105 ds->master_mii_bus = bus; 106 107 108 /* 109 * Validate supplied switch configuration. 110 */ 111 for (i = 0; i < DSA_MAX_PORTS; i++) { 112 char *name; 113 114 name = pd->port_names[i]; 115 if (name == NULL) 116 continue; 117 118 if (!strcmp(name, "cpu")) { 119 if (dst->cpu_switch != -1) { 120 printk(KERN_ERR "multiple cpu ports?!\n"); 121 ret = -EINVAL; 122 goto out; 123 } 124 dst->cpu_switch = index; 125 dst->cpu_port = i; 126 } else if (!strcmp(name, "dsa")) { 127 ds->dsa_port_mask |= 1 << i; 128 } else { 129 ds->phys_port_mask |= 1 << i; 130 } 131 } 132 133 134 /* 135 * If the CPU connects to this switch, set the switch tree 136 * tagging protocol to the preferred tagging format of this 137 * switch. 138 */ 139 if (ds->dst->cpu_switch == index) 140 ds->dst->tag_protocol = drv->tag_protocol; 141 142 143 /* 144 * Do basic register setup. 145 */ 146 ret = drv->setup(ds); 147 if (ret < 0) 148 goto out; 149 150 ret = drv->set_addr(ds, dst->master_netdev->dev_addr); 151 if (ret < 0) 152 goto out; 153 154 ds->slave_mii_bus = mdiobus_alloc(); 155 if (ds->slave_mii_bus == NULL) { 156 ret = -ENOMEM; 157 goto out; 158 } 159 dsa_slave_mii_bus_init(ds); 160 161 ret = mdiobus_register(ds->slave_mii_bus); 162 if (ret < 0) 163 goto out_free; 164 165 166 /* 167 * Create network devices for physical switch ports. 168 */ 169 for (i = 0; i < DSA_MAX_PORTS; i++) { 170 struct net_device *slave_dev; 171 172 if (!(ds->phys_port_mask & (1 << i))) 173 continue; 174 175 slave_dev = dsa_slave_create(ds, parent, i, pd->port_names[i]); 176 if (slave_dev == NULL) { 177 printk(KERN_ERR "%s[%d]: can't create dsa " 178 "slave device for port %d(%s)\n", 179 dst->master_netdev->name, 180 index, i, pd->port_names[i]); 181 continue; 182 } 183 184 ds->ports[i] = slave_dev; 185 } 186 187 return ds; 188 189 out_free: 190 mdiobus_free(ds->slave_mii_bus); 191 out: 192 kfree(ds); 193 return ERR_PTR(ret); 194 } 195 196 static void dsa_switch_destroy(struct dsa_switch *ds) 197 { 198 } 199 200 201 /* hooks for ethertype-less tagging formats *********************************/ 202 /* 203 * The original DSA tag format and some other tag formats have no 204 * ethertype, which means that we need to add a little hack to the 205 * networking receive path to make sure that received frames get 206 * the right ->protocol assigned to them when one of those tag 207 * formats is in use. 208 */ 209 bool dsa_uses_dsa_tags(void *dsa_ptr) 210 { 211 struct dsa_switch_tree *dst = dsa_ptr; 212 213 return !!(dst->tag_protocol == htons(ETH_P_DSA)); 214 } 215 216 bool dsa_uses_trailer_tags(void *dsa_ptr) 217 { 218 struct dsa_switch_tree *dst = dsa_ptr; 219 220 return !!(dst->tag_protocol == htons(ETH_P_TRAILER)); 221 } 222 223 224 /* link polling *************************************************************/ 225 static void dsa_link_poll_work(struct work_struct *ugly) 226 { 227 struct dsa_switch_tree *dst; 228 int i; 229 230 dst = container_of(ugly, struct dsa_switch_tree, link_poll_work); 231 232 for (i = 0; i < dst->pd->nr_chips; i++) { 233 struct dsa_switch *ds = dst->ds[i]; 234 235 if (ds != NULL && ds->drv->poll_link != NULL) 236 ds->drv->poll_link(ds); 237 } 238 239 mod_timer(&dst->link_poll_timer, round_jiffies(jiffies + HZ)); 240 } 241 242 static void dsa_link_poll_timer(unsigned long _dst) 243 { 244 struct dsa_switch_tree *dst = (void *)_dst; 245 246 schedule_work(&dst->link_poll_work); 247 } 248 249 250 /* platform driver init and cleanup *****************************************/ 251 static int dev_is_class(struct device *dev, void *class) 252 { 253 if (dev->class != NULL && !strcmp(dev->class->name, class)) 254 return 1; 255 256 return 0; 257 } 258 259 static struct device *dev_find_class(struct device *parent, char *class) 260 { 261 if (dev_is_class(parent, class)) { 262 get_device(parent); 263 return parent; 264 } 265 266 return device_find_child(parent, class, dev_is_class); 267 } 268 269 static struct mii_bus *dev_to_mii_bus(struct device *dev) 270 { 271 struct device *d; 272 273 d = dev_find_class(dev, "mdio_bus"); 274 if (d != NULL) { 275 struct mii_bus *bus; 276 277 bus = to_mii_bus(d); 278 put_device(d); 279 280 return bus; 281 } 282 283 return NULL; 284 } 285 286 static struct net_device *dev_to_net_device(struct device *dev) 287 { 288 struct device *d; 289 290 d = dev_find_class(dev, "net"); 291 if (d != NULL) { 292 struct net_device *nd; 293 294 nd = to_net_dev(d); 295 dev_hold(nd); 296 put_device(d); 297 298 return nd; 299 } 300 301 return NULL; 302 } 303 304 static int dsa_probe(struct platform_device *pdev) 305 { 306 static int dsa_version_printed; 307 struct dsa_platform_data *pd = pdev->dev.platform_data; 308 struct net_device *dev; 309 struct dsa_switch_tree *dst; 310 int i; 311 312 if (!dsa_version_printed++) 313 printk(KERN_NOTICE "Distributed Switch Architecture " 314 "driver version %s\n", dsa_driver_version); 315 316 if (pd == NULL || pd->netdev == NULL) 317 return -EINVAL; 318 319 dev = dev_to_net_device(pd->netdev); 320 if (dev == NULL) 321 return -EINVAL; 322 323 if (dev->dsa_ptr != NULL) { 324 dev_put(dev); 325 return -EEXIST; 326 } 327 328 dst = kzalloc(sizeof(*dst), GFP_KERNEL); 329 if (dst == NULL) { 330 dev_put(dev); 331 return -ENOMEM; 332 } 333 334 platform_set_drvdata(pdev, dst); 335 336 dst->pd = pd; 337 dst->master_netdev = dev; 338 dst->cpu_switch = -1; 339 dst->cpu_port = -1; 340 341 for (i = 0; i < pd->nr_chips; i++) { 342 struct mii_bus *bus; 343 struct dsa_switch *ds; 344 345 bus = dev_to_mii_bus(pd->chip[i].mii_bus); 346 if (bus == NULL) { 347 printk(KERN_ERR "%s[%d]: no mii bus found for " 348 "dsa switch\n", dev->name, i); 349 continue; 350 } 351 352 ds = dsa_switch_setup(dst, i, &pdev->dev, bus); 353 if (IS_ERR(ds)) { 354 printk(KERN_ERR "%s[%d]: couldn't create dsa switch " 355 "instance (error %ld)\n", dev->name, i, 356 PTR_ERR(ds)); 357 continue; 358 } 359 360 dst->ds[i] = ds; 361 if (ds->drv->poll_link != NULL) 362 dst->link_poll_needed = 1; 363 } 364 365 /* 366 * If we use a tagging format that doesn't have an ethertype 367 * field, make sure that all packets from this point on get 368 * sent to the tag format's receive function. 369 */ 370 wmb(); 371 dev->dsa_ptr = (void *)dst; 372 373 if (dst->link_poll_needed) { 374 INIT_WORK(&dst->link_poll_work, dsa_link_poll_work); 375 init_timer(&dst->link_poll_timer); 376 dst->link_poll_timer.data = (unsigned long)dst; 377 dst->link_poll_timer.function = dsa_link_poll_timer; 378 dst->link_poll_timer.expires = round_jiffies(jiffies + HZ); 379 add_timer(&dst->link_poll_timer); 380 } 381 382 return 0; 383 } 384 385 static int dsa_remove(struct platform_device *pdev) 386 { 387 struct dsa_switch_tree *dst = platform_get_drvdata(pdev); 388 int i; 389 390 if (dst->link_poll_needed) 391 del_timer_sync(&dst->link_poll_timer); 392 393 flush_work_sync(&dst->link_poll_work); 394 395 for (i = 0; i < dst->pd->nr_chips; i++) { 396 struct dsa_switch *ds = dst->ds[i]; 397 398 if (ds != NULL) 399 dsa_switch_destroy(ds); 400 } 401 402 return 0; 403 } 404 405 static void dsa_shutdown(struct platform_device *pdev) 406 { 407 } 408 409 static struct platform_driver dsa_driver = { 410 .probe = dsa_probe, 411 .remove = dsa_remove, 412 .shutdown = dsa_shutdown, 413 .driver = { 414 .name = "dsa", 415 .owner = THIS_MODULE, 416 }, 417 }; 418 419 static int __init dsa_init_module(void) 420 { 421 return platform_driver_register(&dsa_driver); 422 } 423 module_init(dsa_init_module); 424 425 static void __exit dsa_cleanup_module(void) 426 { 427 platform_driver_unregister(&dsa_driver); 428 } 429 module_exit(dsa_cleanup_module); 430 431 MODULE_AUTHOR("Lennert Buytenhek <buytenh@wantstofly.org>"); 432 MODULE_DESCRIPTION("Driver for Distributed Switch Architecture switch chips"); 433 MODULE_LICENSE("GPL"); 434 MODULE_ALIAS("platform:dsa"); 435