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