dsa: Change dsa_uses_{dsa, trailer}_tags() into inline functions
[linux-2.6-block.git] / net / dsa / dsa.c
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 /* link polling *************************************************************/
203 static void dsa_link_poll_work(struct work_struct *ugly)
204 {
205         struct dsa_switch_tree *dst;
206         int i;
207
208         dst = container_of(ugly, struct dsa_switch_tree, link_poll_work);
209
210         for (i = 0; i < dst->pd->nr_chips; i++) {
211                 struct dsa_switch *ds = dst->ds[i];
212
213                 if (ds != NULL && ds->drv->poll_link != NULL)
214                         ds->drv->poll_link(ds);
215         }
216
217         mod_timer(&dst->link_poll_timer, round_jiffies(jiffies + HZ));
218 }
219
220 static void dsa_link_poll_timer(unsigned long _dst)
221 {
222         struct dsa_switch_tree *dst = (void *)_dst;
223
224         schedule_work(&dst->link_poll_work);
225 }
226
227
228 /* platform driver init and cleanup *****************************************/
229 static int dev_is_class(struct device *dev, void *class)
230 {
231         if (dev->class != NULL && !strcmp(dev->class->name, class))
232                 return 1;
233
234         return 0;
235 }
236
237 static struct device *dev_find_class(struct device *parent, char *class)
238 {
239         if (dev_is_class(parent, class)) {
240                 get_device(parent);
241                 return parent;
242         }
243
244         return device_find_child(parent, class, dev_is_class);
245 }
246
247 static struct mii_bus *dev_to_mii_bus(struct device *dev)
248 {
249         struct device *d;
250
251         d = dev_find_class(dev, "mdio_bus");
252         if (d != NULL) {
253                 struct mii_bus *bus;
254
255                 bus = to_mii_bus(d);
256                 put_device(d);
257
258                 return bus;
259         }
260
261         return NULL;
262 }
263
264 static struct net_device *dev_to_net_device(struct device *dev)
265 {
266         struct device *d;
267
268         d = dev_find_class(dev, "net");
269         if (d != NULL) {
270                 struct net_device *nd;
271
272                 nd = to_net_dev(d);
273                 dev_hold(nd);
274                 put_device(d);
275
276                 return nd;
277         }
278
279         return NULL;
280 }
281
282 static int dsa_probe(struct platform_device *pdev)
283 {
284         static int dsa_version_printed;
285         struct dsa_platform_data *pd = pdev->dev.platform_data;
286         struct net_device *dev;
287         struct dsa_switch_tree *dst;
288         int i;
289
290         if (!dsa_version_printed++)
291                 printk(KERN_NOTICE "Distributed Switch Architecture "
292                         "driver version %s\n", dsa_driver_version);
293
294         if (pd == NULL || pd->netdev == NULL)
295                 return -EINVAL;
296
297         dev = dev_to_net_device(pd->netdev);
298         if (dev == NULL)
299                 return -EINVAL;
300
301         if (dev->dsa_ptr != NULL) {
302                 dev_put(dev);
303                 return -EEXIST;
304         }
305
306         dst = kzalloc(sizeof(*dst), GFP_KERNEL);
307         if (dst == NULL) {
308                 dev_put(dev);
309                 return -ENOMEM;
310         }
311
312         platform_set_drvdata(pdev, dst);
313
314         dst->pd = pd;
315         dst->master_netdev = dev;
316         dst->cpu_switch = -1;
317         dst->cpu_port = -1;
318
319         for (i = 0; i < pd->nr_chips; i++) {
320                 struct mii_bus *bus;
321                 struct dsa_switch *ds;
322
323                 bus = dev_to_mii_bus(pd->chip[i].mii_bus);
324                 if (bus == NULL) {
325                         printk(KERN_ERR "%s[%d]: no mii bus found for "
326                                 "dsa switch\n", dev->name, i);
327                         continue;
328                 }
329
330                 ds = dsa_switch_setup(dst, i, &pdev->dev, bus);
331                 if (IS_ERR(ds)) {
332                         printk(KERN_ERR "%s[%d]: couldn't create dsa switch "
333                                 "instance (error %ld)\n", dev->name, i,
334                                 PTR_ERR(ds));
335                         continue;
336                 }
337
338                 dst->ds[i] = ds;
339                 if (ds->drv->poll_link != NULL)
340                         dst->link_poll_needed = 1;
341         }
342
343         /*
344          * If we use a tagging format that doesn't have an ethertype
345          * field, make sure that all packets from this point on get
346          * sent to the tag format's receive function.
347          */
348         wmb();
349         dev->dsa_ptr = (void *)dst;
350
351         if (dst->link_poll_needed) {
352                 INIT_WORK(&dst->link_poll_work, dsa_link_poll_work);
353                 init_timer(&dst->link_poll_timer);
354                 dst->link_poll_timer.data = (unsigned long)dst;
355                 dst->link_poll_timer.function = dsa_link_poll_timer;
356                 dst->link_poll_timer.expires = round_jiffies(jiffies + HZ);
357                 add_timer(&dst->link_poll_timer);
358         }
359
360         return 0;
361 }
362
363 static int dsa_remove(struct platform_device *pdev)
364 {
365         struct dsa_switch_tree *dst = platform_get_drvdata(pdev);
366         int i;
367
368         if (dst->link_poll_needed)
369                 del_timer_sync(&dst->link_poll_timer);
370
371         flush_work_sync(&dst->link_poll_work);
372
373         for (i = 0; i < dst->pd->nr_chips; i++) {
374                 struct dsa_switch *ds = dst->ds[i];
375
376                 if (ds != NULL)
377                         dsa_switch_destroy(ds);
378         }
379
380         return 0;
381 }
382
383 static void dsa_shutdown(struct platform_device *pdev)
384 {
385 }
386
387 static struct platform_driver dsa_driver = {
388         .probe          = dsa_probe,
389         .remove         = dsa_remove,
390         .shutdown       = dsa_shutdown,
391         .driver = {
392                 .name   = "dsa",
393                 .owner  = THIS_MODULE,
394         },
395 };
396
397 static int __init dsa_init_module(void)
398 {
399         return platform_driver_register(&dsa_driver);
400 }
401 module_init(dsa_init_module);
402
403 static void __exit dsa_cleanup_module(void)
404 {
405         platform_driver_unregister(&dsa_driver);
406 }
407 module_exit(dsa_cleanup_module);
408
409 MODULE_AUTHOR("Lennert Buytenhek <buytenh@wantstofly.org>");
410 MODULE_DESCRIPTION("Driver for Distributed Switch Architecture switch chips");
411 MODULE_LICENSE("GPL");
412 MODULE_ALIAS("platform:dsa");