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
);
391 static const struct nla_policy wimax_gnl_policy
[WIMAX_GNL_ATTR_MAX
+ 1] = {
392 [WIMAX_GNL_RESET_IFIDX
] = { .type
= NLA_U32
, },
393 [WIMAX_GNL_RFKILL_IFIDX
] = { .type
= NLA_U32
, },
394 [WIMAX_GNL_RFKILL_STATE
] = {
395 .type
= NLA_U32
/* enum wimax_rf_state */
397 [WIMAX_GNL_STGET_IFIDX
] = { .type
= NLA_U32
, },
398 [WIMAX_GNL_MSG_IFIDX
] = { .type
= NLA_U32
, },
399 [WIMAX_GNL_MSG_DATA
] = {
400 .type
= NLA_UNSPEC
, /* libnl doesn't grok BINARY yet */
404 static const struct genl_ops wimax_gnl_ops
[] = {
406 .cmd
= WIMAX_GNL_OP_MSG_FROM_USER
,
407 .validate
= GENL_DONT_VALIDATE_STRICT
| GENL_DONT_VALIDATE_DUMP
,
408 .flags
= GENL_ADMIN_PERM
,
409 .doit
= wimax_gnl_doit_msg_from_user
,
412 .cmd
= WIMAX_GNL_OP_RESET
,
413 .validate
= GENL_DONT_VALIDATE_STRICT
| GENL_DONT_VALIDATE_DUMP
,
414 .flags
= GENL_ADMIN_PERM
,
415 .doit
= wimax_gnl_doit_reset
,
418 .cmd
= WIMAX_GNL_OP_RFKILL
,
419 .validate
= GENL_DONT_VALIDATE_STRICT
| GENL_DONT_VALIDATE_DUMP
,
420 .flags
= GENL_ADMIN_PERM
,
421 .doit
= wimax_gnl_doit_rfkill
,
424 .cmd
= WIMAX_GNL_OP_STATE_GET
,
425 .validate
= GENL_DONT_VALIDATE_STRICT
| GENL_DONT_VALIDATE_DUMP
,
426 .flags
= GENL_ADMIN_PERM
,
427 .doit
= wimax_gnl_doit_state_get
,
433 size_t wimax_addr_scnprint(char *addr_str
, size_t addr_str_size
,
434 unsigned char *addr
, size_t addr_len
)
436 unsigned int cnt
, total
;
438 for (total
= cnt
= 0; cnt
< addr_len
; cnt
++)
439 total
+= scnprintf(addr_str
+ total
, addr_str_size
- total
,
441 cnt
== addr_len
- 1 ? '\0' : ':');
447 * wimax_dev_add - Register a new WiMAX device
449 * @wimax_dev: WiMAX device descriptor (as embedded in your @net_dev's
450 * priv data). You must have called wimax_dev_init() on it before.
452 * @net_dev: net device the @wimax_dev is associated with. The
453 * function expects SET_NETDEV_DEV() and register_netdev() were
454 * already called on it.
456 * Registers the new WiMAX device, sets up the user-kernel control
457 * interface (generic netlink) and common WiMAX infrastructure.
459 * Note that the parts that will allow interaction with user space are
460 * setup at the very end, when the rest is in place, as once that
461 * happens, the driver might get user space control requests via
462 * netlink or from debugfs that might translate into calls into
465 int wimax_dev_add(struct wimax_dev
*wimax_dev
, struct net_device
*net_dev
)
468 struct device
*dev
= net_dev
->dev
.parent
;
471 d_fnstart(3, dev
, "(wimax_dev %p net_dev %p)\n", wimax_dev
, net_dev
);
473 /* Do the RFKILL setup before locking, as RFKILL will call
474 * into our functions.
476 wimax_dev
->net_dev
= net_dev
;
477 result
= wimax_rfkill_add(wimax_dev
);
479 goto error_rfkill_add
;
481 /* Set up user-space interaction */
482 mutex_lock(&wimax_dev
->mutex
);
483 wimax_id_table_add(wimax_dev
);
484 wimax_debugfs_add(wimax_dev
);
486 __wimax_state_set(wimax_dev
, WIMAX_ST_DOWN
);
487 mutex_unlock(&wimax_dev
->mutex
);
489 wimax_addr_scnprint(addr_str
, sizeof(addr_str
),
490 net_dev
->dev_addr
, net_dev
->addr_len
);
491 dev_err(dev
, "WiMAX interface %s (%s) ready\n",
492 net_dev
->name
, addr_str
);
493 d_fnend(3, dev
, "(wimax_dev %p net_dev %p) = 0\n", wimax_dev
, net_dev
);
497 d_fnend(3, dev
, "(wimax_dev %p net_dev %p) = %d\n",
498 wimax_dev
, net_dev
, result
);
501 EXPORT_SYMBOL_GPL(wimax_dev_add
);
505 * wimax_dev_rm - Unregister an existing WiMAX device
507 * @wimax_dev: WiMAX device descriptor
509 * Unregisters a WiMAX device previously registered for use with
512 * IMPORTANT! Must call before calling unregister_netdev().
514 * After this function returns, you will not get any more user space
515 * control requests (via netlink or debugfs) and thus to wimax_dev->ops.
517 * Reentrancy control is ensured by setting the state to
518 * %__WIMAX_ST_QUIESCING. rfkill operations coming through
519 * wimax_*rfkill*() will be stopped by the quiescing state; ops coming
520 * from the rfkill subsystem will be stopped by the support being
521 * removed by wimax_rfkill_rm().
523 void wimax_dev_rm(struct wimax_dev
*wimax_dev
)
525 d_fnstart(3, NULL
, "(wimax_dev %p)\n", wimax_dev
);
527 mutex_lock(&wimax_dev
->mutex
);
528 __wimax_state_change(wimax_dev
, __WIMAX_ST_QUIESCING
);
529 wimax_debugfs_rm(wimax_dev
);
530 wimax_id_table_rm(wimax_dev
);
531 __wimax_state_change(wimax_dev
, WIMAX_ST_DOWN
);
532 mutex_unlock(&wimax_dev
->mutex
);
533 wimax_rfkill_rm(wimax_dev
);
534 d_fnend(3, NULL
, "(wimax_dev %p) = void\n", wimax_dev
);
536 EXPORT_SYMBOL_GPL(wimax_dev_rm
);
539 /* Debug framework control of debug levels */
540 struct d_level D_LEVEL
[] = {
541 D_SUBMODULE_DEFINE(debugfs
),
542 D_SUBMODULE_DEFINE(id_table
),
543 D_SUBMODULE_DEFINE(op_msg
),
544 D_SUBMODULE_DEFINE(op_reset
),
545 D_SUBMODULE_DEFINE(op_rfkill
),
546 D_SUBMODULE_DEFINE(op_state_get
),
547 D_SUBMODULE_DEFINE(stack
),
549 size_t D_LEVEL_SIZE
= ARRAY_SIZE(D_LEVEL
);
552 static const struct genl_multicast_group wimax_gnl_mcgrps
[] = {
556 struct genl_family wimax_gnl_family __ro_after_init
= {
558 .version
= WIMAX_GNL_VERSION
,
560 .maxattr
= WIMAX_GNL_ATTR_MAX
,
561 .policy
= wimax_gnl_policy
,
562 .module
= THIS_MODULE
,
563 .ops
= wimax_gnl_ops
,
564 .n_ops
= ARRAY_SIZE(wimax_gnl_ops
),
565 .mcgrps
= wimax_gnl_mcgrps
,
566 .n_mcgrps
= ARRAY_SIZE(wimax_gnl_mcgrps
),
571 /* Shutdown the wimax stack */
573 int __init
wimax_subsys_init(void)
577 d_fnstart(4, NULL
, "()\n");
578 d_parse_params(D_LEVEL
, D_LEVEL_SIZE
, wimax_debug_params
,
581 result
= genl_register_family(&wimax_gnl_family
);
582 if (unlikely(result
< 0)) {
583 pr_err("cannot register generic netlink family: %d\n", result
);
584 goto error_register_family
;
587 d_fnend(4, NULL
, "() = 0\n");
590 error_register_family
:
591 d_fnend(4, NULL
, "() = %d\n", result
);
595 module_init(wimax_subsys_init
);
598 /* Shutdown the wimax stack */
600 void __exit
wimax_subsys_exit(void)
602 wimax_id_table_release();
603 genl_unregister_family(&wimax_gnl_family
);
605 module_exit(wimax_subsys_exit
);
607 MODULE_AUTHOR("Intel Corporation <linux-wimax@intel.com>");
608 MODULE_DESCRIPTION("Linux WiMAX stack");
609 MODULE_LICENSE("GPL");