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