Merge branch 'topic/asoc' into next/asoc
[linux-2.6] / net / wimax / stack.c
1 /*
2  * Linux WiMAX
3  * Initialization, addition and removal of wimax devices
4  *
5  *
6  * Copyright (C) 2005-2006 Intel Corporation <linux-wimax@intel.com>
7  * Inaky Perez-Gonzalez <inaky.perez-gonzalez@intel.com>
8  *
9  * This program is free software; you can redistribute it and/or
10  * modify it under the terms of the GNU General Public License version
11  * 2 as published by the Free Software Foundation.
12  *
13  * This program is distributed in the hope that it will be useful,
14  * but WITHOUT ANY WARRANTY; without even the implied warranty of
15  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16  * GNU General Public License for more details.
17  *
18  * You should have received a copy of the GNU General Public License
19  * along with this program; if not, write to the Free Software
20  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
21  * 02110-1301, USA.
22  *
23  *
24  * This implements:
25  *
26  *   - basic life cycle of 'struct wimax_dev' [wimax_dev_*()]; on
27  *     addition/registration initialize all subfields and allocate
28  *     generic netlink resources for user space communication. On
29  *     removal/unregistration, undo all that.
30  *
31  *   - device state machine [wimax_state_change()] and support to send
32  *     reports to user space when the state changes
33  *     [wimax_gnl_re_state_change*()].
34  *
35  * See include/net/wimax.h for rationales and design.
36  *
37  * ROADMAP
38  *
39  * [__]wimax_state_change()     Called by drivers to update device's state
40  *   wimax_gnl_re_state_change_alloc()
41  *   wimax_gnl_re_state_change_send()
42  *
43  * wimax_dev_init()             Init a device
44  * wimax_dev_add()              Register
45  *   wimax_rfkill_add()
46  *   wimax_gnl_add()            Register all the generic netlink resources.
47  *   wimax_id_table_add()
48  * wimax_dev_rm()               Unregister
49  *   wimax_id_table_rm()
50  *   wimax_gnl_rm()
51  *   wimax_rfkill_rm()
52  */
53 #include <linux/device.h>
54 #include <net/genetlink.h>
55 #include <linux/netdevice.h>
56 #include <linux/wimax.h>
57 #include "wimax-internal.h"
58
59
60 #define D_SUBMODULE stack
61 #include "debug-levels.h"
62
63 /*
64  * Authoritative source for the RE_STATE_CHANGE attribute policy
65  *
66  * We don't really use it here, but /me likes to keep the definition
67  * close to where the data is generated.
68  */
69 /*
70 static const
71 struct nla_policy wimax_gnl_re_status_change[WIMAX_GNL_ATTR_MAX + 1] = {
72         [WIMAX_GNL_STCH_STATE_OLD] = { .type = NLA_U8 },
73         [WIMAX_GNL_STCH_STATE_NEW] = { .type = NLA_U8 },
74 };
75 */
76
77
78 /*
79  * Allocate a Report State Change message
80  *
81  * @header: save it, you need it for _send()
82  *
83  * Creates and fills a basic state change message; different code
84  * paths can then add more attributes to the message as needed.
85  *
86  * Use wimax_gnl_re_state_change_send() to send the returned skb.
87  *
88  * Returns: skb with the genl message if ok, IS_ERR() ptr on error
89  *     with an errno code.
90  */
91 static
92 struct sk_buff *wimax_gnl_re_state_change_alloc(
93         struct wimax_dev *wimax_dev,
94         enum wimax_st new_state, enum wimax_st old_state,
95         void **header)
96 {
97         int result;
98         struct device *dev = wimax_dev_to_dev(wimax_dev);
99         void *data;
100         struct sk_buff *report_skb;
101
102         d_fnstart(3, dev, "(wimax_dev %p new_state %u old_state %u)\n",
103                   wimax_dev, new_state, old_state);
104         result = -ENOMEM;
105         report_skb = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
106         if (report_skb == NULL) {
107                 dev_err(dev, "RE_STCH: can't create message\n");
108                 goto error_new;
109         }
110         data = genlmsg_put(report_skb, 0, wimax_gnl_mcg.id, &wimax_gnl_family,
111                            0, WIMAX_GNL_RE_STATE_CHANGE);
112         if (data == NULL) {
113                 dev_err(dev, "RE_STCH: can't put data into message\n");
114                 goto error_put;
115         }
116         *header = data;
117
118         result = nla_put_u8(report_skb, WIMAX_GNL_STCH_STATE_OLD, old_state);
119         if (result < 0) {
120                 dev_err(dev, "RE_STCH: Error adding OLD attr: %d\n", result);
121                 goto error_put;
122         }
123         result = nla_put_u8(report_skb, WIMAX_GNL_STCH_STATE_NEW, new_state);
124         if (result < 0) {
125                 dev_err(dev, "RE_STCH: Error adding NEW attr: %d\n", result);
126                 goto error_put;
127         }
128         result = nla_put_u32(report_skb, WIMAX_GNL_STCH_IFIDX,
129                              wimax_dev->net_dev->ifindex);
130         if (result < 0) {
131                 dev_err(dev, "RE_STCH: Error adding IFINDEX attribute\n");
132                 goto error_put;
133         }
134         d_fnend(3, dev, "(wimax_dev %p new_state %u old_state %u) = %p\n",
135                 wimax_dev, new_state, old_state, report_skb);
136         return report_skb;
137
138 error_put:
139         nlmsg_free(report_skb);
140 error_new:
141         d_fnend(3, dev, "(wimax_dev %p new_state %u old_state %u) = %d\n",
142                 wimax_dev, new_state, old_state, result);
143         return ERR_PTR(result);
144 }
145
146
147 /*
148  * Send a Report State Change message (as created with _alloc).
149  *
150  * @report_skb: as returned by wimax_gnl_re_state_change_alloc()
151  * @header: as returned by wimax_gnl_re_state_change_alloc()
152  *
153  * Returns: 0 if ok, < 0 errno code on error.
154  *
155  * If the message is  NULL, pretend it didn't happen.
156  */
157 static
158 int wimax_gnl_re_state_change_send(
159         struct wimax_dev *wimax_dev, struct sk_buff *report_skb,
160         void *header)
161 {
162         int result = 0;
163         struct device *dev = wimax_dev_to_dev(wimax_dev);
164         d_fnstart(3, dev, "(wimax_dev %p report_skb %p)\n",
165                   wimax_dev, report_skb);
166         if (report_skb == NULL)
167                 goto out;
168         genlmsg_end(report_skb, header);
169         result = genlmsg_multicast(report_skb, 0, wimax_gnl_mcg.id, GFP_KERNEL);
170         if (result == -ESRCH)   /* Nobody connected, ignore it */
171                 result = 0;     /* btw, the skb is freed already */
172         if (result < 0) {
173                 dev_err(dev, "RE_STCH: Error sending: %d\n", result);
174                 nlmsg_free(report_skb);
175         }
176 out:
177         d_fnend(3, dev, "(wimax_dev %p report_skb %p) = %d\n",
178                 wimax_dev, report_skb, result);
179         return result;
180 }
181
182
183 static
184 void __check_new_state(enum wimax_st old_state, enum wimax_st new_state,
185                        unsigned allowed_states_bm)
186 {
187         if (WARN_ON(((1 << new_state) & allowed_states_bm) == 0)) {
188                 printk(KERN_ERR "SW BUG! Forbidden state change %u -> %u\n",
189                         old_state, new_state);
190         }
191 }
192
193
194 /*
195  * Set the current state of a WiMAX device [unlocking version of
196  * wimax_state_change().
197  */
198 void __wimax_state_change(struct wimax_dev *wimax_dev, enum wimax_st new_state)
199 {
200         struct device *dev = wimax_dev_to_dev(wimax_dev);
201         enum wimax_st old_state = wimax_dev->state;
202         struct sk_buff *stch_skb;
203         void *header;
204
205         d_fnstart(3, dev, "(wimax_dev %p new_state %u [old %u])\n",
206                   wimax_dev, new_state, old_state);
207
208         if (WARN_ON(new_state >= __WIMAX_ST_INVALID)) {
209                 dev_err(dev, "SW BUG: requesting invalid state %u\n",
210                         new_state);
211                 goto out;
212         }
213         if (old_state == new_state)
214                 goto out;
215         header = NULL;  /* gcc complains? can't grok why */
216         stch_skb = wimax_gnl_re_state_change_alloc(
217                 wimax_dev, new_state, old_state, &header);
218
219         /* Verify the state transition and do exit-from-state actions */
220         switch (old_state) {
221         case __WIMAX_ST_NULL:
222                 __check_new_state(old_state, new_state,
223                                   1 << WIMAX_ST_DOWN);
224                 break;
225         case WIMAX_ST_DOWN:
226                 __check_new_state(old_state, new_state,
227                                   1 << __WIMAX_ST_QUIESCING
228                                   | 1 << WIMAX_ST_UNINITIALIZED
229                                   | 1 << WIMAX_ST_RADIO_OFF);
230                 break;
231         case __WIMAX_ST_QUIESCING:
232                 __check_new_state(old_state, new_state, 1 << WIMAX_ST_DOWN);
233                 break;
234         case WIMAX_ST_UNINITIALIZED:
235                 __check_new_state(old_state, new_state,
236                                   1 << __WIMAX_ST_QUIESCING
237                                   | 1 << WIMAX_ST_RADIO_OFF);
238                 break;
239         case WIMAX_ST_RADIO_OFF:
240                 __check_new_state(old_state, new_state,
241                                   1 << __WIMAX_ST_QUIESCING
242                                   | 1 << WIMAX_ST_READY);
243                 break;
244         case WIMAX_ST_READY:
245                 __check_new_state(old_state, new_state,
246                                   1 << __WIMAX_ST_QUIESCING
247                                   | 1 << WIMAX_ST_RADIO_OFF
248                                   | 1 << WIMAX_ST_SCANNING
249                                   | 1 << WIMAX_ST_CONNECTING
250                                   | 1 << WIMAX_ST_CONNECTED);
251                 break;
252         case WIMAX_ST_SCANNING:
253                 __check_new_state(old_state, new_state,
254                                   1 << __WIMAX_ST_QUIESCING
255                                   | 1 << WIMAX_ST_RADIO_OFF
256                                   | 1 << WIMAX_ST_READY
257                                   | 1 << WIMAX_ST_CONNECTING
258                                   | 1 << WIMAX_ST_CONNECTED);
259                 break;
260         case WIMAX_ST_CONNECTING:
261                 __check_new_state(old_state, new_state,
262                                   1 << __WIMAX_ST_QUIESCING
263                                   | 1 << WIMAX_ST_RADIO_OFF
264                                   | 1 << WIMAX_ST_READY
265                                   | 1 << WIMAX_ST_SCANNING
266                                   | 1 << WIMAX_ST_CONNECTED);
267                 break;
268         case WIMAX_ST_CONNECTED:
269                 __check_new_state(old_state, new_state,
270                                   1 << __WIMAX_ST_QUIESCING
271                                   | 1 << WIMAX_ST_RADIO_OFF
272                                   | 1 << WIMAX_ST_READY);
273                 netif_tx_disable(wimax_dev->net_dev);
274                 netif_carrier_off(wimax_dev->net_dev);
275                 break;
276         case __WIMAX_ST_INVALID:
277         default:
278                 dev_err(dev, "SW BUG: wimax_dev %p is in unknown state %u\n",
279                         wimax_dev, wimax_dev->state);
280                 WARN_ON(1);
281                 goto out;
282         }
283
284         /* Execute the actions of entry to the new state */
285         switch (new_state) {
286         case __WIMAX_ST_NULL:
287                 dev_err(dev, "SW BUG: wimax_dev %p entering NULL state "
288                         "from %u\n", wimax_dev, wimax_dev->state);
289                 WARN_ON(1);             /* Nobody can enter this state */
290                 break;
291         case WIMAX_ST_DOWN:
292                 break;
293         case __WIMAX_ST_QUIESCING:
294                 break;
295         case WIMAX_ST_UNINITIALIZED:
296                 break;
297         case WIMAX_ST_RADIO_OFF:
298                 break;
299         case WIMAX_ST_READY:
300                 break;
301         case WIMAX_ST_SCANNING:
302                 break;
303         case WIMAX_ST_CONNECTING:
304                 break;
305         case WIMAX_ST_CONNECTED:
306                 netif_carrier_on(wimax_dev->net_dev);
307                 netif_wake_queue(wimax_dev->net_dev);
308                 break;
309         case __WIMAX_ST_INVALID:
310         default:
311                 BUG();
312         }
313         __wimax_state_set(wimax_dev, new_state);
314         if (stch_skb)
315                 wimax_gnl_re_state_change_send(wimax_dev, stch_skb, header);
316 out:
317         d_fnend(3, dev, "(wimax_dev %p new_state %u [old %u]) = void\n",
318                 wimax_dev, new_state, old_state);
319         return;
320 }
321
322
323 /**
324  * wimax_state_change - Set the current state of a WiMAX device
325  *
326  * @wimax_dev: WiMAX device descriptor (properly referenced)
327  * @new_state: New state to switch to
328  *
329  * This implements the state changes for the wimax devices. It will
330  *
331  * - verify that the state transition is legal (for now it'll just
332  *   print a warning if not) according to the table in
333  *   linux/wimax.h's documentation for 'enum wimax_st'.
334  *
335  * - perform the actions needed for leaving the current state and
336  *   whichever are needed for entering the new state.
337  *
338  * - issue a report to user space indicating the new state (and an
339  *   optional payload with information about the new state).
340  *
341  * NOTE: @wimax_dev must be locked
342  */
343 void wimax_state_change(struct wimax_dev *wimax_dev, enum wimax_st new_state)
344 {
345         mutex_lock(&wimax_dev->mutex);
346         __wimax_state_change(wimax_dev, new_state);
347         mutex_unlock(&wimax_dev->mutex);
348         return;
349 }
350 EXPORT_SYMBOL_GPL(wimax_state_change);
351
352
353 /**
354  * wimax_state_get() - Return the current state of a WiMAX device
355  *
356  * @wimax_dev: WiMAX device descriptor
357  *
358  * Returns: Current state of the device according to its driver.
359  */
360 enum wimax_st wimax_state_get(struct wimax_dev *wimax_dev)
361 {
362         enum wimax_st state;
363         mutex_lock(&wimax_dev->mutex);
364         state = wimax_dev->state;
365         mutex_unlock(&wimax_dev->mutex);
366         return state;
367 }
368 EXPORT_SYMBOL_GPL(wimax_state_get);
369
370
371 /**
372  * wimax_dev_init - initialize a newly allocated instance
373  *
374  * @wimax_dev: WiMAX device descriptor to initialize.
375  *
376  * Initializes fields of a freshly allocated @wimax_dev instance. This
377  * function assumes that after allocation, the memory occupied by
378  * @wimax_dev was zeroed.
379  */
380 void wimax_dev_init(struct wimax_dev *wimax_dev)
381 {
382         INIT_LIST_HEAD(&wimax_dev->id_table_node);
383         __wimax_state_set(wimax_dev, WIMAX_ST_UNINITIALIZED);
384         mutex_init(&wimax_dev->mutex);
385         mutex_init(&wimax_dev->mutex_reset);
386 }
387 EXPORT_SYMBOL_GPL(wimax_dev_init);
388
389 /*
390  * This extern is declared here because it's easier to keep track --
391  * both declarations are a list of the same
392  */
393 extern struct genl_ops
394         wimax_gnl_msg_from_user,
395         wimax_gnl_reset,
396         wimax_gnl_rfkill;
397
398 static
399 struct genl_ops *wimax_gnl_ops[] = {
400         &wimax_gnl_msg_from_user,
401         &wimax_gnl_reset,
402         &wimax_gnl_rfkill,
403 };
404
405
406 static
407 size_t wimax_addr_scnprint(char *addr_str, size_t addr_str_size,
408                            unsigned char *addr, size_t addr_len)
409 {
410         unsigned cnt, total;
411         for (total = cnt = 0; cnt < addr_len; cnt++)
412                 total += scnprintf(addr_str + total, addr_str_size - total,
413                                    "%02x%c", addr[cnt],
414                                    cnt == addr_len - 1 ? '\0' : ':');
415         return total;
416 }
417
418
419 /**
420  * wimax_dev_add - Register a new WiMAX device
421  *
422  * @wimax_dev: WiMAX device descriptor (as embedded in your @net_dev's
423  *     priv data). You must have called wimax_dev_init() on it before.
424  *
425  * @net_dev: net device the @wimax_dev is associated with. The
426  *     function expects SET_NETDEV_DEV() and register_netdev() were
427  *     already called on it.
428  *
429  * Registers the new WiMAX device, sets up the user-kernel control
430  * interface (generic netlink) and common WiMAX infrastructure.
431  *
432  * Note that the parts that will allow interaction with user space are
433  * setup at the very end, when the rest is in place, as once that
434  * happens, the driver might get user space control requests via
435  * netlink or from debugfs that might translate into calls into
436  * wimax_dev->op_*().
437  */
438 int wimax_dev_add(struct wimax_dev *wimax_dev, struct net_device *net_dev)
439 {
440         int result;
441         struct device *dev = net_dev->dev.parent;
442         char addr_str[32];
443
444         d_fnstart(3, dev, "(wimax_dev %p net_dev %p)\n", wimax_dev, net_dev);
445
446         /* Do the RFKILL setup before locking, as RFKILL will call
447          * into our functions. */
448         wimax_dev->net_dev = net_dev;
449         result = wimax_rfkill_add(wimax_dev);
450         if (result < 0)
451                 goto error_rfkill_add;
452
453         /* Set up user-space interaction */
454         mutex_lock(&wimax_dev->mutex);
455         wimax_id_table_add(wimax_dev);
456         result = wimax_debugfs_add(wimax_dev);
457         if (result < 0) {
458                 dev_err(dev, "cannot initialize debugfs: %d\n",
459                         result);
460                 goto error_debugfs_add;
461         }
462
463         __wimax_state_set(wimax_dev, WIMAX_ST_DOWN);
464         mutex_unlock(&wimax_dev->mutex);
465
466         wimax_addr_scnprint(addr_str, sizeof(addr_str),
467                             net_dev->dev_addr, net_dev->addr_len);
468         dev_err(dev, "WiMAX interface %s (%s) ready\n",
469                 net_dev->name, addr_str);
470         d_fnend(3, dev, "(wimax_dev %p net_dev %p) = 0\n", wimax_dev, net_dev);
471         return 0;
472
473 error_debugfs_add:
474         wimax_id_table_rm(wimax_dev);
475         mutex_unlock(&wimax_dev->mutex);
476         wimax_rfkill_rm(wimax_dev);
477 error_rfkill_add:
478         d_fnend(3, dev, "(wimax_dev %p net_dev %p) = %d\n",
479                 wimax_dev, net_dev, result);
480         return result;
481 }
482 EXPORT_SYMBOL_GPL(wimax_dev_add);
483
484
485 /**
486  * wimax_dev_rm - Unregister an existing WiMAX device
487  *
488  * @wimax_dev: WiMAX device descriptor
489  *
490  * Unregisters a WiMAX device previously registered for use with
491  * wimax_add_rm().
492  *
493  * IMPORTANT! Must call before calling unregister_netdev().
494  *
495  * After this function returns, you will not get any more user space
496  * control requests (via netlink or debugfs) and thus to wimax_dev->ops.
497  *
498  * Reentrancy control is ensured by setting the state to
499  * %__WIMAX_ST_QUIESCING. rfkill operations coming through
500  * wimax_*rfkill*() will be stopped by the quiescing state; ops coming
501  * from the rfkill subsystem will be stopped by the support being
502  * removed by wimax_rfkill_rm().
503  */
504 void wimax_dev_rm(struct wimax_dev *wimax_dev)
505 {
506         d_fnstart(3, NULL, "(wimax_dev %p)\n", wimax_dev);
507
508         mutex_lock(&wimax_dev->mutex);
509         __wimax_state_change(wimax_dev, __WIMAX_ST_QUIESCING);
510         wimax_debugfs_rm(wimax_dev);
511         wimax_id_table_rm(wimax_dev);
512         __wimax_state_change(wimax_dev, WIMAX_ST_DOWN);
513         mutex_unlock(&wimax_dev->mutex);
514         wimax_rfkill_rm(wimax_dev);
515         d_fnend(3, NULL, "(wimax_dev %p) = void\n", wimax_dev);
516 }
517 EXPORT_SYMBOL_GPL(wimax_dev_rm);
518
519 struct genl_family wimax_gnl_family = {
520         .id = GENL_ID_GENERATE,
521         .name = "WiMAX",
522         .version = WIMAX_GNL_VERSION,
523         .hdrsize = 0,
524         .maxattr = WIMAX_GNL_ATTR_MAX,
525 };
526
527 struct genl_multicast_group wimax_gnl_mcg = {
528         .name = "msg",
529 };
530
531
532
533 /* Shutdown the wimax stack */
534 static
535 int __init wimax_subsys_init(void)
536 {
537         int result, cnt;
538
539         d_fnstart(4, NULL, "()\n");
540         snprintf(wimax_gnl_family.name, sizeof(wimax_gnl_family.name),
541                  "WiMAX");
542         result = genl_register_family(&wimax_gnl_family);
543         if (unlikely(result < 0)) {
544                 printk(KERN_ERR "cannot register generic netlink family: %d\n",
545                        result);
546                 goto error_register_family;
547         }
548
549         for (cnt = 0; cnt < ARRAY_SIZE(wimax_gnl_ops); cnt++) {
550                 result = genl_register_ops(&wimax_gnl_family,
551                                            wimax_gnl_ops[cnt]);
552                 d_printf(4, NULL, "registering generic netlink op code "
553                          "%u: %d\n", wimax_gnl_ops[cnt]->cmd, result);
554                 if (unlikely(result < 0)) {
555                         printk(KERN_ERR "cannot register generic netlink op "
556                                "code %u: %d\n",
557                                wimax_gnl_ops[cnt]->cmd, result);
558                         goto error_register_ops;
559                 }
560         }
561
562         result = genl_register_mc_group(&wimax_gnl_family, &wimax_gnl_mcg);
563         if (result < 0)
564                 goto error_mc_group;
565         d_fnend(4, NULL, "() = 0\n");
566         return 0;
567
568 error_mc_group:
569 error_register_ops:
570         for (cnt--; cnt >= 0; cnt--)
571                 genl_unregister_ops(&wimax_gnl_family,
572                                     wimax_gnl_ops[cnt]);
573         genl_unregister_family(&wimax_gnl_family);
574 error_register_family:
575         d_fnend(4, NULL, "() = %d\n", result);
576         return result;
577
578 }
579 module_init(wimax_subsys_init);
580
581
582 /* Shutdown the wimax stack */
583 static
584 void __exit wimax_subsys_exit(void)
585 {
586         int cnt;
587         wimax_id_table_release();
588         genl_unregister_mc_group(&wimax_gnl_family, &wimax_gnl_mcg);
589         for (cnt = ARRAY_SIZE(wimax_gnl_ops) - 1; cnt >= 0; cnt--)
590                 genl_unregister_ops(&wimax_gnl_family,
591                                     wimax_gnl_ops[cnt]);
592         genl_unregister_family(&wimax_gnl_family);
593 }
594 module_exit(wimax_subsys_exit);
595
596 MODULE_AUTHOR("Intel Corporation <linux-wimax@intel.com>");
597 MODULE_DESCRIPTION("Linux WiMAX stack");
598 MODULE_LICENSE("GPL");
599