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