aboutsummaryrefslogtreecommitdiffstats
path: root/net/wimax
diff options
context:
space:
mode:
authorPatrick McHardy <kaber@trash.net>2009-06-11 10:00:49 -0400
committerPatrick McHardy <kaber@trash.net>2009-06-11 10:00:49 -0400
commit36432dae73cf2c90a59b39c8df9fd8219272b005 (patch)
tree660b9104305a809ec4fdeb295ca13d6e90790ecc /net/wimax
parent440f0d588555892601cfe511728a0fc0c8204063 (diff)
parentbb400801c2f40bbd9a688818323ad09abfc4e581 (diff)
Merge branch 'master' of git://git.kernel.org/pub/scm/linux/kernel/git/davem/net-next-2.6
Diffstat (limited to 'net/wimax')
-rw-r--r--net/wimax/Kconfig15
-rw-r--r--net/wimax/Makefile1
-rw-r--r--net/wimax/debug-levels.h1
-rw-r--r--net/wimax/debugfs.c1
-rw-r--r--net/wimax/op-msg.c17
-rw-r--r--net/wimax/op-rfkill.c123
-rw-r--r--net/wimax/op-state-get.c86
-rw-r--r--net/wimax/stack.c5
8 files changed, 134 insertions, 115 deletions
diff --git a/net/wimax/Kconfig b/net/wimax/Kconfig
index 1b46747a5f5a..e4d97ab476d5 100644
--- a/net/wimax/Kconfig
+++ b/net/wimax/Kconfig
@@ -1,23 +1,10 @@
1# 1#
2# WiMAX LAN device configuration 2# WiMAX LAN device configuration
3# 3#
4# Note the ugly 'depends on' on WIMAX: that disallows RFKILL to be a
5# module if WIMAX is to be linked in. The WiMAX code is done in such a
6# way that it doesn't require and explicit dependency on RFKILL in
7# case an embedded system wants to rip it out.
8#
9# As well, enablement of the RFKILL code means we need the INPUT layer
10# support to inject events coming from hw rfkill switches. That
11# dependency could be killed if input.h provided appropriate means to
12# work when input is disabled.
13
14comment "WiMAX Wireless Broadband support requires CONFIG_INPUT enabled"
15 depends on INPUT = n && RFKILL != n
16 4
17menuconfig WIMAX 5menuconfig WIMAX
18 tristate "WiMAX Wireless Broadband support" 6 tristate "WiMAX Wireless Broadband support"
19 depends on (y && RFKILL != m) || m 7 depends on RFKILL || !RFKILL
20 depends on (INPUT && RFKILL != n) || RFKILL = n
21 help 8 help
22 9
23 Select to configure support for devices that provide 10 Select to configure support for devices that provide
diff --git a/net/wimax/Makefile b/net/wimax/Makefile
index 5b80b941c2c9..8f1510d0cc2b 100644
--- a/net/wimax/Makefile
+++ b/net/wimax/Makefile
@@ -6,6 +6,7 @@ wimax-y := \
6 op-msg.o \ 6 op-msg.o \
7 op-reset.o \ 7 op-reset.o \
8 op-rfkill.o \ 8 op-rfkill.o \
9 op-state-get.o \
9 stack.o 10 stack.o
10 11
11wimax-$(CONFIG_DEBUG_FS) += debugfs.o 12wimax-$(CONFIG_DEBUG_FS) += debugfs.o
diff --git a/net/wimax/debug-levels.h b/net/wimax/debug-levels.h
index 1c29123a3aa9..0975adba6b71 100644
--- a/net/wimax/debug-levels.h
+++ b/net/wimax/debug-levels.h
@@ -36,6 +36,7 @@ enum d_module {
36 D_SUBMODULE_DECLARE(op_msg), 36 D_SUBMODULE_DECLARE(op_msg),
37 D_SUBMODULE_DECLARE(op_reset), 37 D_SUBMODULE_DECLARE(op_reset),
38 D_SUBMODULE_DECLARE(op_rfkill), 38 D_SUBMODULE_DECLARE(op_rfkill),
39 D_SUBMODULE_DECLARE(op_state_get),
39 D_SUBMODULE_DECLARE(stack), 40 D_SUBMODULE_DECLARE(stack),
40}; 41};
41 42
diff --git a/net/wimax/debugfs.c b/net/wimax/debugfs.c
index 94d216a46407..6c9bedb7431e 100644
--- a/net/wimax/debugfs.c
+++ b/net/wimax/debugfs.c
@@ -61,6 +61,7 @@ int wimax_debugfs_add(struct wimax_dev *wimax_dev)
61 __debugfs_register("wimax_dl_", op_msg, dentry); 61 __debugfs_register("wimax_dl_", op_msg, dentry);
62 __debugfs_register("wimax_dl_", op_reset, dentry); 62 __debugfs_register("wimax_dl_", op_reset, dentry);
63 __debugfs_register("wimax_dl_", op_rfkill, dentry); 63 __debugfs_register("wimax_dl_", op_rfkill, dentry);
64 __debugfs_register("wimax_dl_", op_state_get, dentry);
64 __debugfs_register("wimax_dl_", stack, dentry); 65 __debugfs_register("wimax_dl_", stack, dentry);
65 result = 0; 66 result = 0;
66out: 67out:
diff --git a/net/wimax/op-msg.c b/net/wimax/op-msg.c
index 9ad4d893a566..d631a17186bc 100644
--- a/net/wimax/op-msg.c
+++ b/net/wimax/op-msg.c
@@ -108,6 +108,12 @@
108 * Don't use skb_push()/skb_pull()/skb_reserve() on the skb, as 108 * Don't use skb_push()/skb_pull()/skb_reserve() on the skb, as
109 * wimax_msg_send() depends on skb->data being placed at the 109 * wimax_msg_send() depends on skb->data being placed at the
110 * beginning of the user message. 110 * beginning of the user message.
111 *
112 * Unlike other WiMAX stack calls, this call can be used way early,
113 * even before wimax_dev_add() is called, as long as the
114 * wimax_dev->net_dev pointer is set to point to a proper
115 * net_dev. This is so that drivers can use it early in case they need
116 * to send stuff around or communicate with user space.
111 */ 117 */
112struct sk_buff *wimax_msg_alloc(struct wimax_dev *wimax_dev, 118struct sk_buff *wimax_msg_alloc(struct wimax_dev *wimax_dev,
113 const char *pipe_name, 119 const char *pipe_name,
@@ -115,7 +121,7 @@ struct sk_buff *wimax_msg_alloc(struct wimax_dev *wimax_dev,
115 gfp_t gfp_flags) 121 gfp_t gfp_flags)
116{ 122{
117 int result; 123 int result;
118 struct device *dev = wimax_dev->net_dev->dev.parent; 124 struct device *dev = wimax_dev_to_dev(wimax_dev);
119 size_t msg_size; 125 size_t msg_size;
120 void *genl_msg; 126 void *genl_msg;
121 struct sk_buff *skb; 127 struct sk_buff *skb;
@@ -161,7 +167,6 @@ error_genlmsg_put:
161error_new: 167error_new:
162 nlmsg_free(skb); 168 nlmsg_free(skb);
163 return ERR_PTR(result); 169 return ERR_PTR(result);
164
165} 170}
166EXPORT_SYMBOL_GPL(wimax_msg_alloc); 171EXPORT_SYMBOL_GPL(wimax_msg_alloc);
167 172
@@ -256,10 +261,16 @@ EXPORT_SYMBOL_GPL(wimax_msg_len);
256 * Don't use skb_push()/skb_pull()/skb_reserve() on the skb, as 261 * Don't use skb_push()/skb_pull()/skb_reserve() on the skb, as
257 * wimax_msg_send() depends on skb->data being placed at the 262 * wimax_msg_send() depends on skb->data being placed at the
258 * beginning of the user message. 263 * beginning of the user message.
264 *
265 * Unlike other WiMAX stack calls, this call can be used way early,
266 * even before wimax_dev_add() is called, as long as the
267 * wimax_dev->net_dev pointer is set to point to a proper
268 * net_dev. This is so that drivers can use it early in case they need
269 * to send stuff around or communicate with user space.
259 */ 270 */
260int wimax_msg_send(struct wimax_dev *wimax_dev, struct sk_buff *skb) 271int wimax_msg_send(struct wimax_dev *wimax_dev, struct sk_buff *skb)
261{ 272{
262 struct device *dev = wimax_dev->net_dev->dev.parent; 273 struct device *dev = wimax_dev_to_dev(wimax_dev);
263 void *msg = skb->data; 274 void *msg = skb->data;
264 size_t size = skb->len; 275 size_t size = skb->len;
265 might_sleep(); 276 might_sleep();
diff --git a/net/wimax/op-rfkill.c b/net/wimax/op-rfkill.c
index a3616e2ccb8a..bb102e4aa3e9 100644
--- a/net/wimax/op-rfkill.c
+++ b/net/wimax/op-rfkill.c
@@ -29,8 +29,8 @@
29 * A non-polled generic rfkill device is embedded into the WiMAX 29 * A non-polled generic rfkill device is embedded into the WiMAX
30 * subsystem's representation of a device. 30 * subsystem's representation of a device.
31 * 31 *
32 * FIXME: Need polled support? use a timer or add the implementation 32 * FIXME: Need polled support? Let drivers provide a poll routine
33 * to the stack. 33 * and hand it to rfkill ops then?
34 * 34 *
35 * All device drivers have to do is after wimax_dev_init(), call 35 * All device drivers have to do is after wimax_dev_init(), call
36 * wimax_report_rfkill_hw() and wimax_report_rfkill_sw() to update 36 * wimax_report_rfkill_hw() and wimax_report_rfkill_sw() to update
@@ -43,7 +43,7 @@
43 * wimax_rfkill() Kernel calling wimax_rfkill() 43 * wimax_rfkill() Kernel calling wimax_rfkill()
44 * __wimax_rf_toggle_radio() 44 * __wimax_rf_toggle_radio()
45 * 45 *
46 * wimax_rfkill_toggle_radio() RF-Kill subsytem calling 46 * wimax_rfkill_set_radio_block() RF-Kill subsytem calling
47 * __wimax_rf_toggle_radio() 47 * __wimax_rf_toggle_radio()
48 * 48 *
49 * __wimax_rf_toggle_radio() 49 * __wimax_rf_toggle_radio()
@@ -65,15 +65,11 @@
65#include <linux/wimax.h> 65#include <linux/wimax.h>
66#include <linux/security.h> 66#include <linux/security.h>
67#include <linux/rfkill.h> 67#include <linux/rfkill.h>
68#include <linux/input.h>
69#include "wimax-internal.h" 68#include "wimax-internal.h"
70 69
71#define D_SUBMODULE op_rfkill 70#define D_SUBMODULE op_rfkill
72#include "debug-levels.h" 71#include "debug-levels.h"
73 72
74#if defined(CONFIG_RFKILL) || defined(CONFIG_RFKILL_MODULE)
75
76
77/** 73/**
78 * wimax_report_rfkill_hw - Reports changes in the hardware RF switch 74 * wimax_report_rfkill_hw - Reports changes in the hardware RF switch
79 * 75 *
@@ -99,7 +95,6 @@ void wimax_report_rfkill_hw(struct wimax_dev *wimax_dev,
99 int result; 95 int result;
100 struct device *dev = wimax_dev_to_dev(wimax_dev); 96 struct device *dev = wimax_dev_to_dev(wimax_dev);
101 enum wimax_st wimax_state; 97 enum wimax_st wimax_state;
102 enum rfkill_state rfkill_state;
103 98
104 d_fnstart(3, dev, "(wimax_dev %p state %u)\n", wimax_dev, state); 99 d_fnstart(3, dev, "(wimax_dev %p state %u)\n", wimax_dev, state);
105 BUG_ON(state == WIMAX_RF_QUERY); 100 BUG_ON(state == WIMAX_RF_QUERY);
@@ -112,16 +107,15 @@ void wimax_report_rfkill_hw(struct wimax_dev *wimax_dev,
112 107
113 if (state != wimax_dev->rf_hw) { 108 if (state != wimax_dev->rf_hw) {
114 wimax_dev->rf_hw = state; 109 wimax_dev->rf_hw = state;
115 rfkill_state = state == WIMAX_RF_ON ?
116 RFKILL_STATE_UNBLOCKED : RFKILL_STATE_SOFT_BLOCKED;
117 if (wimax_dev->rf_hw == WIMAX_RF_ON 110 if (wimax_dev->rf_hw == WIMAX_RF_ON
118 && wimax_dev->rf_sw == WIMAX_RF_ON) 111 && wimax_dev->rf_sw == WIMAX_RF_ON)
119 wimax_state = WIMAX_ST_READY; 112 wimax_state = WIMAX_ST_READY;
120 else 113 else
121 wimax_state = WIMAX_ST_RADIO_OFF; 114 wimax_state = WIMAX_ST_RADIO_OFF;
115
116 rfkill_set_hw_state(wimax_dev->rfkill, state == WIMAX_RF_OFF);
117
122 __wimax_state_change(wimax_dev, wimax_state); 118 __wimax_state_change(wimax_dev, wimax_state);
123 input_report_key(wimax_dev->rfkill_input, KEY_WIMAX,
124 rfkill_state);
125 } 119 }
126error_not_ready: 120error_not_ready:
127 mutex_unlock(&wimax_dev->mutex); 121 mutex_unlock(&wimax_dev->mutex);
@@ -174,6 +168,7 @@ void wimax_report_rfkill_sw(struct wimax_dev *wimax_dev,
174 else 168 else
175 wimax_state = WIMAX_ST_RADIO_OFF; 169 wimax_state = WIMAX_ST_RADIO_OFF;
176 __wimax_state_change(wimax_dev, wimax_state); 170 __wimax_state_change(wimax_dev, wimax_state);
171 rfkill_set_sw_state(wimax_dev->rfkill, state == WIMAX_RF_OFF);
177 } 172 }
178error_not_ready: 173error_not_ready:
179 mutex_unlock(&wimax_dev->mutex); 174 mutex_unlock(&wimax_dev->mutex);
@@ -249,36 +244,31 @@ out_no_change:
249 * 244 *
250 * NOTE: This call will block until the operation is completed. 245 * NOTE: This call will block until the operation is completed.
251 */ 246 */
252static 247static int wimax_rfkill_set_radio_block(void *data, bool blocked)
253int wimax_rfkill_toggle_radio(void *data, enum rfkill_state state)
254{ 248{
255 int result; 249 int result;
256 struct wimax_dev *wimax_dev = data; 250 struct wimax_dev *wimax_dev = data;
257 struct device *dev = wimax_dev_to_dev(wimax_dev); 251 struct device *dev = wimax_dev_to_dev(wimax_dev);
258 enum wimax_rf_state rf_state; 252 enum wimax_rf_state rf_state;
259 253
260 d_fnstart(3, dev, "(wimax_dev %p state %u)\n", wimax_dev, state); 254 d_fnstart(3, dev, "(wimax_dev %p blocked %u)\n", wimax_dev, blocked);
261 switch (state) { 255 rf_state = WIMAX_RF_ON;
262 case RFKILL_STATE_SOFT_BLOCKED: 256 if (blocked)
263 rf_state = WIMAX_RF_OFF; 257 rf_state = WIMAX_RF_OFF;
264 break;
265 case RFKILL_STATE_UNBLOCKED:
266 rf_state = WIMAX_RF_ON;
267 break;
268 default:
269 BUG();
270 }
271 mutex_lock(&wimax_dev->mutex); 258 mutex_lock(&wimax_dev->mutex);
272 if (wimax_dev->state <= __WIMAX_ST_QUIESCING) 259 if (wimax_dev->state <= __WIMAX_ST_QUIESCING)
273 result = 0; /* just pretend it didn't happen */ 260 result = 0;
274 else 261 else
275 result = __wimax_rf_toggle_radio(wimax_dev, rf_state); 262 result = __wimax_rf_toggle_radio(wimax_dev, rf_state);
276 mutex_unlock(&wimax_dev->mutex); 263 mutex_unlock(&wimax_dev->mutex);
277 d_fnend(3, dev, "(wimax_dev %p state %u) = %d\n", 264 d_fnend(3, dev, "(wimax_dev %p blocked %u) = %d\n",
278 wimax_dev, state, result); 265 wimax_dev, blocked, result);
279 return result; 266 return result;
280} 267}
281 268
269static const struct rfkill_ops wimax_rfkill_ops = {
270 .set_block = wimax_rfkill_set_radio_block,
271};
282 272
283/** 273/**
284 * wimax_rfkill - Set the software RF switch state for a WiMAX device 274 * wimax_rfkill - Set the software RF switch state for a WiMAX device
@@ -322,6 +312,7 @@ int wimax_rfkill(struct wimax_dev *wimax_dev, enum wimax_rf_state state)
322 result = __wimax_rf_toggle_radio(wimax_dev, state); 312 result = __wimax_rf_toggle_radio(wimax_dev, state);
323 if (result < 0) 313 if (result < 0)
324 goto error; 314 goto error;
315 rfkill_set_sw_state(wimax_dev->rfkill, state == WIMAX_RF_OFF);
325 break; 316 break;
326 case WIMAX_RF_QUERY: 317 case WIMAX_RF_QUERY:
327 break; 318 break;
@@ -349,40 +340,20 @@ int wimax_rfkill_add(struct wimax_dev *wimax_dev)
349{ 340{
350 int result; 341 int result;
351 struct rfkill *rfkill; 342 struct rfkill *rfkill;
352 struct input_dev *input_dev;
353 struct device *dev = wimax_dev_to_dev(wimax_dev); 343 struct device *dev = wimax_dev_to_dev(wimax_dev);
354 344
355 d_fnstart(3, dev, "(wimax_dev %p)\n", wimax_dev); 345 d_fnstart(3, dev, "(wimax_dev %p)\n", wimax_dev);
356 /* Initialize RF Kill */ 346 /* Initialize RF Kill */
357 result = -ENOMEM; 347 result = -ENOMEM;
358 rfkill = rfkill_allocate(dev, RFKILL_TYPE_WIMAX); 348 rfkill = rfkill_alloc(wimax_dev->name, dev, RFKILL_TYPE_WIMAX,
349 &wimax_rfkill_ops, wimax_dev);
359 if (rfkill == NULL) 350 if (rfkill == NULL)
360 goto error_rfkill_allocate; 351 goto error_rfkill_allocate;
352
353 d_printf(1, dev, "rfkill %p\n", rfkill);
354
361 wimax_dev->rfkill = rfkill; 355 wimax_dev->rfkill = rfkill;
362 356
363 rfkill->name = wimax_dev->name;
364 rfkill->state = RFKILL_STATE_UNBLOCKED;
365 rfkill->data = wimax_dev;
366 rfkill->toggle_radio = wimax_rfkill_toggle_radio;
367
368 /* Initialize the input device for the hw key */
369 input_dev = input_allocate_device();
370 if (input_dev == NULL)
371 goto error_input_allocate;
372 wimax_dev->rfkill_input = input_dev;
373 d_printf(1, dev, "rfkill %p input %p\n", rfkill, input_dev);
374
375 input_dev->name = wimax_dev->name;
376 /* FIXME: get a real device bus ID and stuff? do we care? */
377 input_dev->id.bustype = BUS_HOST;
378 input_dev->id.vendor = 0xffff;
379 input_dev->evbit[0] = BIT(EV_KEY);
380 set_bit(KEY_WIMAX, input_dev->keybit);
381
382 /* Register both */
383 result = input_register_device(wimax_dev->rfkill_input);
384 if (result < 0)
385 goto error_input_register;
386 result = rfkill_register(wimax_dev->rfkill); 357 result = rfkill_register(wimax_dev->rfkill);
387 if (result < 0) 358 if (result < 0)
388 goto error_rfkill_register; 359 goto error_rfkill_register;
@@ -394,17 +365,8 @@ int wimax_rfkill_add(struct wimax_dev *wimax_dev)
394 d_fnend(3, dev, "(wimax_dev %p) = 0\n", wimax_dev); 365 d_fnend(3, dev, "(wimax_dev %p) = 0\n", wimax_dev);
395 return 0; 366 return 0;
396 367
397 /* if rfkill_register() suceeds, can't use rfkill_free() any
398 * more, only rfkill_unregister() [it owns the refcount]; with
399 * the input device we have the same issue--hence the if. */
400error_rfkill_register: 368error_rfkill_register:
401 input_unregister_device(wimax_dev->rfkill_input); 369 rfkill_destroy(wimax_dev->rfkill);
402 wimax_dev->rfkill_input = NULL;
403error_input_register:
404 if (wimax_dev->rfkill_input)
405 input_free_device(wimax_dev->rfkill_input);
406error_input_allocate:
407 rfkill_free(wimax_dev->rfkill);
408error_rfkill_allocate: 370error_rfkill_allocate:
409 d_fnend(3, dev, "(wimax_dev %p) = %d\n", wimax_dev, result); 371 d_fnend(3, dev, "(wimax_dev %p) = %d\n", wimax_dev, result);
410 return result; 372 return result;
@@ -423,45 +385,12 @@ void wimax_rfkill_rm(struct wimax_dev *wimax_dev)
423{ 385{
424 struct device *dev = wimax_dev_to_dev(wimax_dev); 386 struct device *dev = wimax_dev_to_dev(wimax_dev);
425 d_fnstart(3, dev, "(wimax_dev %p)\n", wimax_dev); 387 d_fnstart(3, dev, "(wimax_dev %p)\n", wimax_dev);
426 rfkill_unregister(wimax_dev->rfkill); /* frees */ 388 rfkill_unregister(wimax_dev->rfkill);
427 input_unregister_device(wimax_dev->rfkill_input); 389 rfkill_destroy(wimax_dev->rfkill);
428 d_fnend(3, dev, "(wimax_dev %p)\n", wimax_dev); 390 d_fnend(3, dev, "(wimax_dev %p)\n", wimax_dev);
429} 391}
430 392
431 393
432#else /* #ifdef CONFIG_RFKILL */
433
434void wimax_report_rfkill_hw(struct wimax_dev *wimax_dev,
435 enum wimax_rf_state state)
436{
437}
438EXPORT_SYMBOL_GPL(wimax_report_rfkill_hw);
439
440void wimax_report_rfkill_sw(struct wimax_dev *wimax_dev,
441 enum wimax_rf_state state)
442{
443}
444EXPORT_SYMBOL_GPL(wimax_report_rfkill_sw);
445
446int wimax_rfkill(struct wimax_dev *wimax_dev,
447 enum wimax_rf_state state)
448{
449 return WIMAX_RF_ON << 1 | WIMAX_RF_ON;
450}
451EXPORT_SYMBOL_GPL(wimax_rfkill);
452
453int wimax_rfkill_add(struct wimax_dev *wimax_dev)
454{
455 return 0;
456}
457
458void wimax_rfkill_rm(struct wimax_dev *wimax_dev)
459{
460}
461
462#endif /* #ifdef CONFIG_RFKILL */
463
464
465/* 394/*
466 * Exporting to user space over generic netlink 395 * Exporting to user space over generic netlink
467 * 396 *
diff --git a/net/wimax/op-state-get.c b/net/wimax/op-state-get.c
new file mode 100644
index 000000000000..a76b8fcb056d
--- /dev/null
+++ b/net/wimax/op-state-get.c
@@ -0,0 +1,86 @@
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
36static const
37struct 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 */
52static
53int 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);
74error_no_wimax_dev:
75 d_fnend(3, NULL, "(skb %p info %p) = %d\n", skb, info, result);
76 return result;
77}
78
79
80struct 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};
diff --git a/net/wimax/stack.c b/net/wimax/stack.c
index 933e1422b09f..79fb7d7c640f 100644
--- a/net/wimax/stack.c
+++ b/net/wimax/stack.c
@@ -402,13 +402,15 @@ EXPORT_SYMBOL_GPL(wimax_dev_init);
402extern struct genl_ops 402extern struct genl_ops
403 wimax_gnl_msg_from_user, 403 wimax_gnl_msg_from_user,
404 wimax_gnl_reset, 404 wimax_gnl_reset,
405 wimax_gnl_rfkill; 405 wimax_gnl_rfkill,
406 wimax_gnl_state_get;
406 407
407static 408static
408struct genl_ops *wimax_gnl_ops[] = { 409struct genl_ops *wimax_gnl_ops[] = {
409 &wimax_gnl_msg_from_user, 410 &wimax_gnl_msg_from_user,
410 &wimax_gnl_reset, 411 &wimax_gnl_reset,
411 &wimax_gnl_rfkill, 412 &wimax_gnl_rfkill,
413 &wimax_gnl_state_get,
412}; 414};
413 415
414 416
@@ -533,6 +535,7 @@ struct d_level D_LEVEL[] = {
533 D_SUBMODULE_DEFINE(op_msg), 535 D_SUBMODULE_DEFINE(op_msg),
534 D_SUBMODULE_DEFINE(op_reset), 536 D_SUBMODULE_DEFINE(op_reset),
535 D_SUBMODULE_DEFINE(op_rfkill), 537 D_SUBMODULE_DEFINE(op_rfkill),
538 D_SUBMODULE_DEFINE(op_state_get),
536 D_SUBMODULE_DEFINE(stack), 539 D_SUBMODULE_DEFINE(stack),
537}; 540};
538size_t D_LEVEL_SIZE = ARRAY_SIZE(D_LEVEL); 541size_t D_LEVEL_SIZE = ARRAY_SIZE(D_LEVEL);