1 // SPDX-License-Identifier: GPL-2.0-only
4 * Initialization, addition and removal of wimax devices
6 * Copyright (C) 2005-2006 Intel Corporation <linux-wimax@intel.com>
7 * Inaky Perez-Gonzalez <inaky.perez-gonzalez@intel.com>
11 * - basic life cycle of 'struct wimax_dev' [wimax_dev_*()]; on
12 * addition/registration initialize all subfields and allocate
13 * generic netlink resources for user space communication. On
14 * removal/unregistration, undo all that.
16 * - device state machine [wimax_state_change()] and support to send
17 * reports to user space when the state changes
18 * [wimax_gnl_re_state_change*()].
20 * See include/net/wimax.h for rationales and design.
24 * [__]wimax_state_change() Called by drivers to update device's state
25 * wimax_gnl_re_state_change_alloc()
26 * wimax_gnl_re_state_change_send()
28 * wimax_dev_init() Init a device
29 * wimax_dev_add() Register
31 * wimax_gnl_add() Register all the generic netlink resources.
32 * wimax_id_table_add()
33 * wimax_dev_rm() Unregister
38 #include <linux/device.h>
39 #include <linux/gfp.h>
40 #include <net/genetlink.h>
41 #include <linux/netdevice.h>
42 #include "linux-wimax.h"
43 #include <linux/module.h>
44 #include "wimax-internal.h"
47 #define D_SUBMODULE stack
48 #include "debug-levels.h"
50 static char wimax_debug_params
[128];
51 module_param_string(debug
, wimax_debug_params
, sizeof(wimax_debug_params
),
53 MODULE_PARM_DESC(debug
,
54 "String of space-separated NAME:VALUE pairs, where NAMEs "
55 "are the different debug submodules and VALUE are the "
56 "initial debug value to set.");
59 * Authoritative source for the RE_STATE_CHANGE attribute policy
61 * We don't really use it here, but /me likes to keep the definition
62 * close to where the data is generated.
65 static const struct nla_policy wimax_gnl_re_status_change[WIMAX_GNL_ATTR_MAX + 1] = {
66 [WIMAX_GNL_STCH_STATE_OLD] = { .type = NLA_U8 },
67 [WIMAX_GNL_STCH_STATE_NEW] = { .type = NLA_U8 },
73 * Allocate a Report State Change message
75 * @header: save it, you need it for _send()
77 * Creates and fills a basic state change message; different code
78 * paths can then add more attributes to the message as needed.
80 * Use wimax_gnl_re_state_change_send() to send the returned skb.
82 * Returns: skb with the genl message if ok, IS_ERR() ptr on error
86 struct sk_buff
*wimax_gnl_re_state_change_alloc(
87 struct wimax_dev
*wimax_dev
,
88 enum wimax_st new_state
, enum wimax_st old_state
,
92 struct device
*dev
= wimax_dev_to_dev(wimax_dev
);
94 struct sk_buff
*report_skb
;
96 d_fnstart(3, dev
, "(wimax_dev %p new_state %u old_state %u)\n",
97 wimax_dev
, new_state
, old_state
);
99 report_skb
= nlmsg_new(NLMSG_DEFAULT_SIZE
, GFP_KERNEL
);
100 if (report_skb
== NULL
) {
101 dev_err(dev
, "RE_STCH: can't create message\n");
104 /* FIXME: sending a group ID as the seq is wrong */
105 data
= genlmsg_put(report_skb
, 0, wimax_gnl_family
.mcgrp_offset
,
106 &wimax_gnl_family
, 0, WIMAX_GNL_RE_STATE_CHANGE
);
108 dev_err(dev
, "RE_STCH: can't put data into message\n");
113 result
= nla_put_u8(report_skb
, WIMAX_GNL_STCH_STATE_OLD
, old_state
);
115 dev_err(dev
, "RE_STCH: Error adding OLD attr: %d\n", result
);
118 result
= nla_put_u8(report_skb
, WIMAX_GNL_STCH_STATE_NEW
, new_state
);
120 dev_err(dev
, "RE_STCH: Error adding NEW attr: %d\n", result
);
123 result
= nla_put_u32(report_skb
, WIMAX_GNL_STCH_IFIDX
,
124 wimax_dev
->net_dev
->ifindex
);
126 dev_err(dev
, "RE_STCH: Error adding IFINDEX attribute\n");
129 d_fnend(3, dev
, "(wimax_dev %p new_state %u old_state %u) = %p\n",
130 wimax_dev
, new_state
, old_state
, report_skb
);
134 nlmsg_free(report_skb
);
136 d_fnend(3, dev
, "(wimax_dev %p new_state %u old_state %u) = %d\n",
137 wimax_dev
, new_state
, old_state
, result
);
138 return ERR_PTR(result
);
143 * Send a Report State Change message (as created with _alloc).
145 * @report_skb: as returned by wimax_gnl_re_state_change_alloc()
146 * @header: as returned by wimax_gnl_re_state_change_alloc()
148 * Returns: 0 if ok, < 0 errno code on error.
150 * If the message is NULL, pretend it didn't happen.
153 int wimax_gnl_re_state_change_send(
154 struct wimax_dev
*wimax_dev
, struct sk_buff
*report_skb
,
158 struct device
*dev
= wimax_dev_to_dev(wimax_dev
);
159 d_fnstart(3, dev
, "(wimax_dev %p report_skb %p)\n",
160 wimax_dev
, report_skb
);
161 if (report_skb
== NULL
) {
165 genlmsg_end(report_skb
, header
);
166 genlmsg_multicast(&wimax_gnl_family
, report_skb
, 0, 0, GFP_KERNEL
);
168 d_fnend(3, dev
, "(wimax_dev %p report_skb %p) = %d\n",
169 wimax_dev
, report_skb
, result
);
175 void __check_new_state(enum wimax_st old_state
, enum wimax_st new_state
,
176 unsigned int allowed_states_bm
)
178 if (WARN_ON(((1 << new_state
) & allowed_states_bm
) == 0)) {
179 pr_err("SW BUG! Forbidden state change %u -> %u\n",
180 old_state
, new_state
);
186 * Set the current state of a WiMAX device [unlocking version of
187 * wimax_state_change().
189 void __wimax_state_change(struct wimax_dev
*wimax_dev
, enum wimax_st new_state
)
191 struct device
*dev
= wimax_dev_to_dev(wimax_dev
);
192 enum wimax_st old_state
= wimax_dev
->state
;
193 struct sk_buff
*stch_skb
;
196 d_fnstart(3, dev
, "(wimax_dev %p new_state %u [old %u])\n",
197 wimax_dev
, new_state
, old_state
);
199 if (WARN_ON(new_state
>= __WIMAX_ST_INVALID
)) {
200 dev_err(dev
, "SW BUG: requesting invalid state %u\n",
204 if (old_state
== new_state
)
206 header
= NULL
; /* gcc complains? can't grok why */
207 stch_skb
= wimax_gnl_re_state_change_alloc(
208 wimax_dev
, new_state
, old_state
, &header
);
210 /* Verify the state transition and do exit-from-state actions */
212 case __WIMAX_ST_NULL
:
213 __check_new_state(old_state
, new_state
,
217 __check_new_state(old_state
, new_state
,
218 1 << __WIMAX_ST_QUIESCING
219 | 1 << WIMAX_ST_UNINITIALIZED
220 | 1 << WIMAX_ST_RADIO_OFF
);
222 case __WIMAX_ST_QUIESCING
:
223 __check_new_state(old_state
, new_state
, 1 << WIMAX_ST_DOWN
);
225 case WIMAX_ST_UNINITIALIZED
:
226 __check_new_state(old_state
, new_state
,
227 1 << __WIMAX_ST_QUIESCING
228 | 1 << WIMAX_ST_RADIO_OFF
);
230 case WIMAX_ST_RADIO_OFF
:
231 __check_new_state(old_state
, new_state
,
232 1 << __WIMAX_ST_QUIESCING
233 | 1 << WIMAX_ST_READY
);
236 __check_new_state(old_state
, new_state
,
237 1 << __WIMAX_ST_QUIESCING
238 | 1 << WIMAX_ST_RADIO_OFF
239 | 1 << WIMAX_ST_SCANNING
240 | 1 << WIMAX_ST_CONNECTING
241 | 1 << WIMAX_ST_CONNECTED
);
243 case WIMAX_ST_SCANNING
:
244 __check_new_state(old_state
, new_state
,
245 1 << __WIMAX_ST_QUIESCING
246 | 1 << WIMAX_ST_RADIO_OFF
247 | 1 << WIMAX_ST_READY
248 | 1 << WIMAX_ST_CONNECTING
249 | 1 << WIMAX_ST_CONNECTED
);
251 case WIMAX_ST_CONNECTING
:
252 __check_new_state(old_state
, new_state
,
253 1 << __WIMAX_ST_QUIESCING
254 | 1 << WIMAX_ST_RADIO_OFF
255 | 1 << WIMAX_ST_READY
256 | 1 << WIMAX_ST_SCANNING
257 | 1 << WIMAX_ST_CONNECTED
);
259 case WIMAX_ST_CONNECTED
:
260 __check_new_state(old_state
, new_state
,
261 1 << __WIMAX_ST_QUIESCING
262 | 1 << WIMAX_ST_RADIO_OFF
263 | 1 << WIMAX_ST_READY
);
264 netif_tx_disable(wimax_dev
->net_dev
);
265 netif_carrier_off(wimax_dev
->net_dev
);
267 case __WIMAX_ST_INVALID
:
269 dev_err(dev
, "SW BUG: wimax_dev %p is in unknown state %u\n",
270 wimax_dev
, wimax_dev
->state
);
275 /* Execute the actions of entry to the new state */
277 case __WIMAX_ST_NULL
:
278 dev_err(dev
, "SW BUG: wimax_dev %p entering NULL state "
279 "from %u\n", wimax_dev
, wimax_dev
->state
);
280 WARN_ON(1); /* Nobody can enter this state */
284 case __WIMAX_ST_QUIESCING
:
286 case WIMAX_ST_UNINITIALIZED
:
288 case WIMAX_ST_RADIO_OFF
:
292 case WIMAX_ST_SCANNING
:
294 case WIMAX_ST_CONNECTING
:
296 case WIMAX_ST_CONNECTED
:
297 netif_carrier_on(wimax_dev
->net_dev
);
298 netif_wake_queue(wimax_dev
->net_dev
);
300 case __WIMAX_ST_INVALID
:
304 __wimax_state_set(wimax_dev
, new_state
);
305 if (!IS_ERR(stch_skb
))
306 wimax_gnl_re_state_change_send(wimax_dev
, stch_skb
, header
);
308 d_fnend(3, dev
, "(wimax_dev %p new_state %u [old %u]) = void\n",
309 wimax_dev
, new_state
, old_state
);
314 * wimax_state_change - Set the current state of a WiMAX device
316 * @wimax_dev: WiMAX device descriptor (properly referenced)
317 * @new_state: New state to switch to
319 * This implements the state changes for the wimax devices. It will
321 * - verify that the state transition is legal (for now it'll just
322 * print a warning if not) according to the table in
323 * linux/wimax.h's documentation for 'enum wimax_st'.
325 * - perform the actions needed for leaving the current state and
326 * whichever are needed for entering the new state.
328 * - issue a report to user space indicating the new state (and an
329 * optional payload with information about the new state).
331 * NOTE: @wimax_dev must be locked
333 void wimax_state_change(struct wimax_dev
*wimax_dev
, enum wimax_st new_state
)
336 * A driver cannot take the wimax_dev out of the
337 * __WIMAX_ST_NULL state unless by calling wimax_dev_add(). If
338 * the wimax_dev's state is still NULL, we ignore any request
339 * to change its state because it means it hasn't been yet
342 * There is no need to complain about it, as routines that
343 * call this might be shared from different code paths that
344 * are called before or after wimax_dev_add() has done its
347 mutex_lock(&wimax_dev
->mutex
);
348 if (wimax_dev
->state
> __WIMAX_ST_NULL
)
349 __wimax_state_change(wimax_dev
, new_state
);
350 mutex_unlock(&wimax_dev
->mutex
);
352 EXPORT_SYMBOL_GPL(wimax_state_change
);
356 * wimax_state_get() - Return the current state of a WiMAX device
358 * @wimax_dev: WiMAX device descriptor
360 * Returns: Current state of the device according to its driver.
362 enum wimax_st
wimax_state_get(struct wimax_dev
*wimax_dev
)
365 mutex_lock(&wimax_dev
->mutex
);
366 state
= wimax_dev
->state
;
367 mutex_unlock(&wimax_dev
->mutex
);
370 EXPORT_SYMBOL_GPL(wimax_state_get
);
374 * wimax_dev_init - initialize a newly allocated instance
376 * @wimax_dev: WiMAX device descriptor to initialize.
378 * Initializes fields of a freshly allocated @wimax_dev instance. This
379 * function assumes that after allocation, the memory occupied by
380 * @wimax_dev was zeroed.
382 void wimax_dev_init(struct wimax_dev
*wimax_dev
)
384 INIT_LIST_HEAD(&wimax_dev
->id_table_node
);
385 __wimax_state_set(wimax_dev
, __WIMAX_ST_NULL
);
386 mutex_init(&wimax_dev
->mutex
);
387 mutex_init(&wimax_dev
->mutex_reset
);
389 EXPORT_SYMBOL_GPL(wimax_dev_init
);
392 * There are multiple enums reusing the same values, adding
393 * others is only possible if they use a compatible policy.
395 static const struct nla_policy wimax_gnl_policy
[WIMAX_GNL_ATTR_MAX
+ 1] = {
397 * WIMAX_GNL_RESET_IFIDX, WIMAX_GNL_RFKILL_IFIDX,
398 * WIMAX_GNL_STGET_IFIDX, WIMAX_GNL_MSG_IFIDX
400 [1] = { .type
= NLA_U32
, },
402 * WIMAX_GNL_RFKILL_STATE, WIMAX_GNL_MSG_PIPE_NAME
404 [2] = { .type
= NLA_U32
, }, /* enum wimax_rf_state */
408 [3] = { .type
= NLA_UNSPEC
, }, /* libnl doesn't grok BINARY yet */
411 static const struct genl_small_ops wimax_gnl_ops
[] = {
413 .cmd
= WIMAX_GNL_OP_MSG_FROM_USER
,
414 .validate
= GENL_DONT_VALIDATE_STRICT
| GENL_DONT_VALIDATE_DUMP
,
415 .flags
= GENL_ADMIN_PERM
,
416 .doit
= wimax_gnl_doit_msg_from_user
,
419 .cmd
= WIMAX_GNL_OP_RESET
,
420 .validate
= GENL_DONT_VALIDATE_STRICT
| GENL_DONT_VALIDATE_DUMP
,
421 .flags
= GENL_ADMIN_PERM
,
422 .doit
= wimax_gnl_doit_reset
,
425 .cmd
= WIMAX_GNL_OP_RFKILL
,
426 .validate
= GENL_DONT_VALIDATE_STRICT
| GENL_DONT_VALIDATE_DUMP
,
427 .flags
= GENL_ADMIN_PERM
,
428 .doit
= wimax_gnl_doit_rfkill
,
431 .cmd
= WIMAX_GNL_OP_STATE_GET
,
432 .validate
= GENL_DONT_VALIDATE_STRICT
| GENL_DONT_VALIDATE_DUMP
,
433 .flags
= GENL_ADMIN_PERM
,
434 .doit
= wimax_gnl_doit_state_get
,
440 size_t wimax_addr_scnprint(char *addr_str
, size_t addr_str_size
,
441 unsigned char *addr
, size_t addr_len
)
443 unsigned int cnt
, total
;
445 for (total
= cnt
= 0; cnt
< addr_len
; cnt
++)
446 total
+= scnprintf(addr_str
+ total
, addr_str_size
- total
,
448 cnt
== addr_len
- 1 ? '\0' : ':');
454 * wimax_dev_add - Register a new WiMAX device
456 * @wimax_dev: WiMAX device descriptor (as embedded in your @net_dev's
457 * priv data). You must have called wimax_dev_init() on it before.
459 * @net_dev: net device the @wimax_dev is associated with. The
460 * function expects SET_NETDEV_DEV() and register_netdev() were
461 * already called on it.
463 * Registers the new WiMAX device, sets up the user-kernel control
464 * interface (generic netlink) and common WiMAX infrastructure.
466 * Note that the parts that will allow interaction with user space are
467 * setup at the very end, when the rest is in place, as once that
468 * happens, the driver might get user space control requests via
469 * netlink or from debugfs that might translate into calls into
472 int wimax_dev_add(struct wimax_dev
*wimax_dev
, struct net_device
*net_dev
)
475 struct device
*dev
= net_dev
->dev
.parent
;
478 d_fnstart(3, dev
, "(wimax_dev %p net_dev %p)\n", wimax_dev
, net_dev
);
480 /* Do the RFKILL setup before locking, as RFKILL will call
481 * into our functions.
483 wimax_dev
->net_dev
= net_dev
;
484 result
= wimax_rfkill_add(wimax_dev
);
486 goto error_rfkill_add
;
488 /* Set up user-space interaction */
489 mutex_lock(&wimax_dev
->mutex
);
490 wimax_id_table_add(wimax_dev
);
491 wimax_debugfs_add(wimax_dev
);
493 __wimax_state_set(wimax_dev
, WIMAX_ST_DOWN
);
494 mutex_unlock(&wimax_dev
->mutex
);
496 wimax_addr_scnprint(addr_str
, sizeof(addr_str
),
497 net_dev
->dev_addr
, net_dev
->addr_len
);
498 dev_err(dev
, "WiMAX interface %s (%s) ready\n",
499 net_dev
->name
, addr_str
);
500 d_fnend(3, dev
, "(wimax_dev %p net_dev %p) = 0\n", wimax_dev
, net_dev
);
504 d_fnend(3, dev
, "(wimax_dev %p net_dev %p) = %d\n",
505 wimax_dev
, net_dev
, result
);
508 EXPORT_SYMBOL_GPL(wimax_dev_add
);
512 * wimax_dev_rm - Unregister an existing WiMAX device
514 * @wimax_dev: WiMAX device descriptor
516 * Unregisters a WiMAX device previously registered for use with
519 * IMPORTANT! Must call before calling unregister_netdev().
521 * After this function returns, you will not get any more user space
522 * control requests (via netlink or debugfs) and thus to wimax_dev->ops.
524 * Reentrancy control is ensured by setting the state to
525 * %__WIMAX_ST_QUIESCING. rfkill operations coming through
526 * wimax_*rfkill*() will be stopped by the quiescing state; ops coming
527 * from the rfkill subsystem will be stopped by the support being
528 * removed by wimax_rfkill_rm().
530 void wimax_dev_rm(struct wimax_dev
*wimax_dev
)
532 d_fnstart(3, NULL
, "(wimax_dev %p)\n", wimax_dev
);
534 mutex_lock(&wimax_dev
->mutex
);
535 __wimax_state_change(wimax_dev
, __WIMAX_ST_QUIESCING
);
536 wimax_debugfs_rm(wimax_dev
);
537 wimax_id_table_rm(wimax_dev
);
538 __wimax_state_change(wimax_dev
, WIMAX_ST_DOWN
);
539 mutex_unlock(&wimax_dev
->mutex
);
540 wimax_rfkill_rm(wimax_dev
);
541 d_fnend(3, NULL
, "(wimax_dev %p) = void\n", wimax_dev
);
543 EXPORT_SYMBOL_GPL(wimax_dev_rm
);
546 /* Debug framework control of debug levels */
547 struct d_level D_LEVEL
[] = {
548 D_SUBMODULE_DEFINE(debugfs
),
549 D_SUBMODULE_DEFINE(id_table
),
550 D_SUBMODULE_DEFINE(op_msg
),
551 D_SUBMODULE_DEFINE(op_reset
),
552 D_SUBMODULE_DEFINE(op_rfkill
),
553 D_SUBMODULE_DEFINE(op_state_get
),
554 D_SUBMODULE_DEFINE(stack
),
556 size_t D_LEVEL_SIZE
= ARRAY_SIZE(D_LEVEL
);
559 static const struct genl_multicast_group wimax_gnl_mcgrps
[] = {
563 struct genl_family wimax_gnl_family __ro_after_init
= {
565 .version
= WIMAX_GNL_VERSION
,
567 .maxattr
= WIMAX_GNL_ATTR_MAX
,
568 .policy
= wimax_gnl_policy
,
569 .module
= THIS_MODULE
,
570 .small_ops
= wimax_gnl_ops
,
571 .n_small_ops
= ARRAY_SIZE(wimax_gnl_ops
),
572 .mcgrps
= wimax_gnl_mcgrps
,
573 .n_mcgrps
= ARRAY_SIZE(wimax_gnl_mcgrps
),
578 /* Shutdown the wimax stack */
580 int __init
wimax_subsys_init(void)
584 d_fnstart(4, NULL
, "()\n");
585 d_parse_params(D_LEVEL
, D_LEVEL_SIZE
, wimax_debug_params
,
588 result
= genl_register_family(&wimax_gnl_family
);
589 if (unlikely(result
< 0)) {
590 pr_err("cannot register generic netlink family: %d\n", result
);
591 goto error_register_family
;
594 d_fnend(4, NULL
, "() = 0\n");
597 error_register_family
:
598 d_fnend(4, NULL
, "() = %d\n", result
);
602 module_init(wimax_subsys_init
);
605 /* Shutdown the wimax stack */
607 void __exit
wimax_subsys_exit(void)
609 wimax_id_table_release();
610 genl_unregister_family(&wimax_gnl_family
);
612 module_exit(wimax_subsys_exit
);
614 MODULE_AUTHOR("Intel Corporation <linux-wimax@intel.com>");
615 MODULE_DESCRIPTION("Linux WiMAX stack");
616 MODULE_LICENSE("GPL");