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