Commit 7f0333eb2f98bbfece4fbfe21076d0a3e49f0bb0

Authored by Paulius Zaleckas
Committed by Inaky Perez-Gonzalez
1 parent a0a4c4c9e5

wimax: Add netlink interface to get device state

wimax connection manager / daemon has to know what is current
state of the device. Previously it was only possible to get
notification whet state has changed.

Note:

 By mistake, the new generic netlink's number for
 WIMAX_GNL_OP_STATE_GET was declared inserting into the existing list
 of API calls, not appending; thus, it'd break existing API.

 Fixed by Inaky Perez-Gonzalez <inaky@linux.intel.com> by moving to
 the tail, where we add to the interface, not modify the interface.

 Thanks to Stephen Hemminger <shemminger@vyatta.com> for catching this.

Signed-off-by: Paulius Zaleckas <paulius.zaleckas@teltonika.lt>

Showing 6 changed files with 98 additions and 1 deletions Side-by-side Diff

include/linux/wimax.h
... ... @@ -78,6 +78,7 @@
78 78 WIMAX_GNL_OP_RFKILL, /* Run wimax_rfkill() */
79 79 WIMAX_GNL_OP_RESET, /* Run wimax_rfkill() */
80 80 WIMAX_GNL_RE_STATE_CHANGE, /* Report: status change */
  81 + WIMAX_GNL_OP_STATE_GET, /* Request for current state */
81 82 };
82 83  
83 84  
... ... @@ -113,6 +114,10 @@
113 114 WIMAX_GNL_RESET_IFIDX = 1,
114 115 };
115 116  
  117 +/* Atributes for wimax_state_get() */
  118 +enum {
  119 + WIMAX_GNL_STGET_IFIDX = 1,
  120 +};
116 121  
117 122 /*
118 123 * Attributes for the Report State Change
... ... @@ -6,6 +6,7 @@
6 6 op-msg.o \
7 7 op-reset.o \
8 8 op-rfkill.o \
  9 + op-state-get.o \
9 10 stack.o
10 11  
11 12 wimax-$(CONFIG_DEBUG_FS) += debugfs.o
net/wimax/debug-levels.h
... ... @@ -36,6 +36,7 @@
36 36 D_SUBMODULE_DECLARE(op_msg),
37 37 D_SUBMODULE_DECLARE(op_reset),
38 38 D_SUBMODULE_DECLARE(op_rfkill),
  39 + D_SUBMODULE_DECLARE(op_state_get),
39 40 D_SUBMODULE_DECLARE(stack),
40 41 };
41 42  
... ... @@ -61,6 +61,7 @@
61 61 __debugfs_register("wimax_dl_", op_msg, dentry);
62 62 __debugfs_register("wimax_dl_", op_reset, dentry);
63 63 __debugfs_register("wimax_dl_", op_rfkill, dentry);
  64 + __debugfs_register("wimax_dl_", op_state_get, dentry);
64 65 __debugfs_register("wimax_dl_", stack, dentry);
65 66 result = 0;
66 67 out:
net/wimax/op-state-get.c
  1 +/*
  2 + * Linux WiMAX
  3 + * Implement and export a method for getting a WiMAX device current state
  4 + *
  5 + * Copyright (C) 2009 Paulius Zaleckas <paulius.zaleckas@teltonika.lt>
  6 + *
  7 + * Based on previous WiMAX core work by:
  8 + * Copyright (C) 2008 Intel Corporation <linux-wimax@intel.com>
  9 + * Inaky Perez-Gonzalez <inaky.perez-gonzalez@intel.com>
  10 + *
  11 + * This program is free software; you can redistribute it and/or
  12 + * modify it under the terms of the GNU General Public License version
  13 + * 2 as published by the Free Software Foundation.
  14 + *
  15 + * This program is distributed in the hope that it will be useful,
  16 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
  17 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  18 + * GNU General Public License for more details.
  19 + *
  20 + * You should have received a copy of the GNU General Public License
  21 + * along with this program; if not, write to the Free Software
  22 + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
  23 + * 02110-1301, USA.
  24 + */
  25 +
  26 +#include <net/wimax.h>
  27 +#include <net/genetlink.h>
  28 +#include <linux/wimax.h>
  29 +#include <linux/security.h>
  30 +#include "wimax-internal.h"
  31 +
  32 +#define D_SUBMODULE op_state_get
  33 +#include "debug-levels.h"
  34 +
  35 +
  36 +static const
  37 +struct nla_policy wimax_gnl_state_get_policy[WIMAX_GNL_ATTR_MAX + 1] = {
  38 + [WIMAX_GNL_STGET_IFIDX] = {
  39 + .type = NLA_U32,
  40 + },
  41 +};
  42 +
  43 +
  44 +/*
  45 + * Exporting to user space over generic netlink
  46 + *
  47 + * Parse the state get command from user space, return a combination
  48 + * value that describe the current state.
  49 + *
  50 + * No attributes.
  51 + */
  52 +static
  53 +int wimax_gnl_doit_state_get(struct sk_buff *skb, struct genl_info *info)
  54 +{
  55 + int result, ifindex;
  56 + struct wimax_dev *wimax_dev;
  57 + struct device *dev;
  58 +
  59 + d_fnstart(3, NULL, "(skb %p info %p)\n", skb, info);
  60 + result = -ENODEV;
  61 + if (info->attrs[WIMAX_GNL_STGET_IFIDX] == NULL) {
  62 + printk(KERN_ERR "WIMAX_GNL_OP_STATE_GET: can't find IFIDX "
  63 + "attribute\n");
  64 + goto error_no_wimax_dev;
  65 + }
  66 + ifindex = nla_get_u32(info->attrs[WIMAX_GNL_STGET_IFIDX]);
  67 + wimax_dev = wimax_dev_get_by_genl_info(info, ifindex);
  68 + if (wimax_dev == NULL)
  69 + goto error_no_wimax_dev;
  70 + dev = wimax_dev_to_dev(wimax_dev);
  71 + /* Execute the operation and send the result back to user space */
  72 + result = wimax_state_get(wimax_dev);
  73 + dev_put(wimax_dev->net_dev);
  74 +error_no_wimax_dev:
  75 + d_fnend(3, NULL, "(skb %p info %p) = %d\n", skb, info, result);
  76 + return result;
  77 +}
  78 +
  79 +
  80 +struct genl_ops wimax_gnl_state_get = {
  81 + .cmd = WIMAX_GNL_OP_STATE_GET,
  82 + .flags = GENL_ADMIN_PERM,
  83 + .policy = wimax_gnl_state_get_policy,
  84 + .doit = wimax_gnl_doit_state_get,
  85 + .dumpit = NULL,
  86 +};
... ... @@ -402,13 +402,15 @@
402 402 extern struct genl_ops
403 403 wimax_gnl_msg_from_user,
404 404 wimax_gnl_reset,
405   - wimax_gnl_rfkill;
  405 + wimax_gnl_rfkill,
  406 + wimax_gnl_state_get;
406 407  
407 408 static
408 409 struct genl_ops *wimax_gnl_ops[] = {
409 410 &wimax_gnl_msg_from_user,
410 411 &wimax_gnl_reset,
411 412 &wimax_gnl_rfkill,
  413 + &wimax_gnl_state_get,
412 414 };
413 415  
414 416  
... ... @@ -533,6 +535,7 @@
533 535 D_SUBMODULE_DEFINE(op_msg),
534 536 D_SUBMODULE_DEFINE(op_reset),
535 537 D_SUBMODULE_DEFINE(op_rfkill),
  538 + D_SUBMODULE_DEFINE(op_state_get),
536 539 D_SUBMODULE_DEFINE(stack),
537 540 };
538 541 size_t D_LEVEL_SIZE = ARRAY_SIZE(D_LEVEL);