aboutsummaryrefslogtreecommitdiff
path: root/net
diff options
context:
space:
mode:
authorDavid S. Miller <davem@davemloft.net>2009-05-29 01:41:32 -0700
committerDavid S. Miller <davem@davemloft.net>2009-05-29 01:41:32 -0700
commit3f1f39c42b24d5c20eb593ce80b9c4d5ec1e2148 (patch)
tree785e5d697e9c2e4b8fd012a7e9c8aac263c186a5 /net
parentdfe9a837987aacaffbce020fbf54d8e0afa4bde1 (diff)
parent7481806dcfd07e9a636155554f6f4b4fbd976381 (diff)
Merge branch 'linux-2.6.31.y' of git://git.kernel.org/pub/scm/linux/kernel/git/inaky/wimax
Diffstat (limited to 'net')
-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-state-get.c86
-rw-r--r--net/wimax/stack.c5
6 files changed, 107 insertions, 4 deletions
diff --git a/net/wimax/Makefile b/net/wimax/Makefile
index 5b80b941c2c..8f1510d0cc2 100644
--- a/net/wimax/Makefile
+++ b/net/wimax/Makefile
@@ -6,6 +6,7 @@ wimax-y := \
op-msg.o \
op-reset.o \
op-rfkill.o \
+ op-state-get.o \
stack.o
wimax-$(CONFIG_DEBUG_FS) += debugfs.o
diff --git a/net/wimax/debug-levels.h b/net/wimax/debug-levels.h
index 1c29123a3aa..0975adba6b7 100644
--- a/net/wimax/debug-levels.h
+++ b/net/wimax/debug-levels.h
@@ -36,6 +36,7 @@ enum d_module {
D_SUBMODULE_DECLARE(op_msg),
D_SUBMODULE_DECLARE(op_reset),
D_SUBMODULE_DECLARE(op_rfkill),
+ D_SUBMODULE_DECLARE(op_state_get),
D_SUBMODULE_DECLARE(stack),
};
diff --git a/net/wimax/debugfs.c b/net/wimax/debugfs.c
index 94d216a4640..6c9bedb7431 100644
--- a/net/wimax/debugfs.c
+++ b/net/wimax/debugfs.c
@@ -61,6 +61,7 @@ int wimax_debugfs_add(struct wimax_dev *wimax_dev)
__debugfs_register("wimax_dl_", op_msg, dentry);
__debugfs_register("wimax_dl_", op_reset, dentry);
__debugfs_register("wimax_dl_", op_rfkill, dentry);
+ __debugfs_register("wimax_dl_", op_state_get, dentry);
__debugfs_register("wimax_dl_", stack, dentry);
result = 0;
out:
diff --git a/net/wimax/op-msg.c b/net/wimax/op-msg.c
index 9ad4d893a56..d631a17186b 100644
--- a/net/wimax/op-msg.c
+++ b/net/wimax/op-msg.c
@@ -108,6 +108,12 @@
* Don't use skb_push()/skb_pull()/skb_reserve() on the skb, as
* wimax_msg_send() depends on skb->data being placed at the
* beginning of the user message.
+ *
+ * Unlike other WiMAX stack calls, this call can be used way early,
+ * even before wimax_dev_add() is called, as long as the
+ * wimax_dev->net_dev pointer is set to point to a proper
+ * net_dev. This is so that drivers can use it early in case they need
+ * to send stuff around or communicate with user space.
*/
struct sk_buff *wimax_msg_alloc(struct wimax_dev *wimax_dev,
const char *pipe_name,
@@ -115,7 +121,7 @@ struct sk_buff *wimax_msg_alloc(struct wimax_dev *wimax_dev,
gfp_t gfp_flags)
{
int result;
- struct device *dev = wimax_dev->net_dev->dev.parent;
+ struct device *dev = wimax_dev_to_dev(wimax_dev);
size_t msg_size;
void *genl_msg;
struct sk_buff *skb;
@@ -161,7 +167,6 @@ error_genlmsg_put:
error_new:
nlmsg_free(skb);
return ERR_PTR(result);
-
}
EXPORT_SYMBOL_GPL(wimax_msg_alloc);
@@ -256,10 +261,16 @@ EXPORT_SYMBOL_GPL(wimax_msg_len);
* Don't use skb_push()/skb_pull()/skb_reserve() on the skb, as
* wimax_msg_send() depends on skb->data being placed at the
* beginning of the user message.
+ *
+ * Unlike other WiMAX stack calls, this call can be used way early,
+ * even before wimax_dev_add() is called, as long as the
+ * wimax_dev->net_dev pointer is set to point to a proper
+ * net_dev. This is so that drivers can use it early in case they need
+ * to send stuff around or communicate with user space.
*/
int wimax_msg_send(struct wimax_dev *wimax_dev, struct sk_buff *skb)
{
- struct device *dev = wimax_dev->net_dev->dev.parent;
+ struct device *dev = wimax_dev_to_dev(wimax_dev);
void *msg = skb->data;
size_t size = skb->len;
might_sleep();
diff --git a/net/wimax/op-state-get.c b/net/wimax/op-state-get.c
new file mode 100644
index 00000000000..a76b8fcb056
--- /dev/null
+++ b/net/wimax/op-state-get.c
@@ -0,0 +1,86 @@
+/*
+ * Linux WiMAX
+ * Implement and export a method for getting a WiMAX device current state
+ *
+ * Copyright (C) 2009 Paulius Zaleckas <paulius.zaleckas@teltonika.lt>
+ *
+ * Based on previous WiMAX core work by:
+ * Copyright (C) 2008 Intel Corporation <linux-wimax@intel.com>
+ * Inaky Perez-Gonzalez <inaky.perez-gonzalez@intel.com>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License version
+ * 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+ * 02110-1301, USA.
+ */
+
+#include <net/wimax.h>
+#include <net/genetlink.h>
+#include <linux/wimax.h>
+#include <linux/security.h>
+#include "wimax-internal.h"
+
+#define D_SUBMODULE op_state_get
+#include "debug-levels.h"
+
+
+static const
+struct nla_policy wimax_gnl_state_get_policy[WIMAX_GNL_ATTR_MAX + 1] = {
+ [WIMAX_GNL_STGET_IFIDX] = {
+ .type = NLA_U32,
+ },
+};
+
+
+/*
+ * Exporting to user space over generic netlink
+ *
+ * Parse the state get command from user space, return a combination
+ * value that describe the current state.
+ *
+ * No attributes.
+ */
+static
+int wimax_gnl_doit_state_get(struct sk_buff *skb, struct genl_info *info)
+{
+ int result, ifindex;
+ struct wimax_dev *wimax_dev;
+ struct device *dev;
+
+ d_fnstart(3, NULL, "(skb %p info %p)\n", skb, info);
+ result = -ENODEV;
+ if (info->attrs[WIMAX_GNL_STGET_IFIDX] == NULL) {
+ printk(KERN_ERR "WIMAX_GNL_OP_STATE_GET: can't find IFIDX "
+ "attribute\n");
+ goto error_no_wimax_dev;
+ }
+ ifindex = nla_get_u32(info->attrs[WIMAX_GNL_STGET_IFIDX]);
+ wimax_dev = wimax_dev_get_by_genl_info(info, ifindex);
+ if (wimax_dev == NULL)
+ goto error_no_wimax_dev;
+ dev = wimax_dev_to_dev(wimax_dev);
+ /* Execute the operation and send the result back to user space */
+ result = wimax_state_get(wimax_dev);
+ dev_put(wimax_dev->net_dev);
+error_no_wimax_dev:
+ d_fnend(3, NULL, "(skb %p info %p) = %d\n", skb, info, result);
+ return result;
+}
+
+
+struct genl_ops wimax_gnl_state_get = {
+ .cmd = WIMAX_GNL_OP_STATE_GET,
+ .flags = GENL_ADMIN_PERM,
+ .policy = wimax_gnl_state_get_policy,
+ .doit = wimax_gnl_doit_state_get,
+ .dumpit = NULL,
+};
diff --git a/net/wimax/stack.c b/net/wimax/stack.c
index 933e1422b09..79fb7d7c640 100644
--- a/net/wimax/stack.c
+++ b/net/wimax/stack.c
@@ -402,13 +402,15 @@ EXPORT_SYMBOL_GPL(wimax_dev_init);
extern struct genl_ops
wimax_gnl_msg_from_user,
wimax_gnl_reset,
- wimax_gnl_rfkill;
+ wimax_gnl_rfkill,
+ wimax_gnl_state_get;
static
struct genl_ops *wimax_gnl_ops[] = {
&wimax_gnl_msg_from_user,
&wimax_gnl_reset,
&wimax_gnl_rfkill,
+ &wimax_gnl_state_get,
};
@@ -533,6 +535,7 @@ struct d_level D_LEVEL[] = {
D_SUBMODULE_DEFINE(op_msg),
D_SUBMODULE_DEFINE(op_reset),
D_SUBMODULE_DEFINE(op_rfkill),
+ D_SUBMODULE_DEFINE(op_state_get),
D_SUBMODULE_DEFINE(stack),
};
size_t D_LEVEL_SIZE = ARRAY_SIZE(D_LEVEL);