* [PATCH] support static-only systems
From: Mike Frysinger @ 2009-11-06 11:09 UTC (permalink / raw)
To: stephen.hemminger, netdev
The iptables code supports a "no shared libs" mode where it can be used
without requiring dlfcn related functionality. This adds similar support
to iproute2 so that it can easily be used on systems like nommu Linux (but
obviously with a few limitations -- no dynamic plugins).
Rather than modify every location that uses dlfcn.h, I hooked the dlfcn.h
header with stub functions when shared library support is disabled. Then
symbol lookup is done via a local static lookup table (which is generated
automatically at build time) so that internal symbols can be found.
Signed-off-by: Mike Frysinger <vapier@gentoo.org>
---
.gitignore | 1 +
Makefile | 5 +++++
genl/Makefile | 15 +++++++++++++++
genl/static-syms.c | 6 ++++++
include/dlfcn.h | 39 +++++++++++++++++++++++++++++++++++++++
ip/Makefile | 16 +++++++++++++++-
ip/static-syms.c | 6 ++++++
tc/Makefile | 23 +++++++++++++++++++----
tc/m_ipt.c | 4 ++++
tc/static-syms.c | 6 ++++++
10 files changed, 116 insertions(+), 5 deletions(-)
create mode 100644 genl/static-syms.c
create mode 100644 include/dlfcn.h
create mode 100644 ip/static-syms.c
create mode 100644 tc/static-syms.c
diff --git a/.gitignore b/.gitignore
index 5a3d20f..390ffb1 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1,4 +1,5 @@
Config
+static-syms.h
.gdbinit
.gdb_history
*.o
diff --git a/Makefile b/Makefile
index 74e9d62..77a85c6 100644
--- a/Makefile
+++ b/Makefile
@@ -10,7 +10,12 @@ ARPDDIR=/var/lib/arpd
# Path to db_185.h include
DBM_INCLUDE:=$(ROOTDIR)/usr/include
+SHARED_LIBS = y
+
DEFINES= -DRESOLVE_HOSTNAMES -DLIBDIR=\"$(LIBDIR)\"
+ifneq ($(SHARED_LIBS),y)
+DEFINES+= -DNO_SHARED_LIBS
+endif
#options if you have a bind>=4.9.4 libresolv (or, maybe, glibc)
LDLIBS=-lresolv
diff --git a/genl/Makefile b/genl/Makefile
index 6435875..44bb83c 100644
--- a/genl/Makefile
+++ b/genl/Makefile
@@ -1,6 +1,7 @@
GENLOBJ=genl.o
include ../Config
+SHARED_LIBS ?= y
GENLMODULES :=
GENLMODULES += ctrl.o
@@ -9,8 +10,10 @@ GENLOBJ += $(GENLMODULES)
GENLLIB :=
+ifeq ($(SHARED_LIBS),y)
LDFLAGS += -Wl,-export-dynamic
LDLIBS += -lm -ldl
+endif
all: genl
@@ -21,3 +24,15 @@ install: all
clean:
rm -f $(GENLOBJ) $(GENLLIB) genl
+
+ifneq ($(SHARED_LIBS),y)
+
+genl: static-syms.o
+static-syms.o: static-syms.h
+static-syms.h: $(wildcard *.c)
+ files="$^" ; \
+ for s in `grep -B 3 '\<dlsym' $$files | sed -n '/snprintf/{s:.*"\([^"]*\)".*:\1:;s:%s::;p}'` ; do \
+ sed -n '/'$$s'[^ ]* =/{s:.* \([^ ]*'$$s'[^ ]*\) .*:extern char \1[] __attribute__((weak)); if (!strcmp(sym, "\1")) return \1;:;p}' $$files ; \
+ done > $@
+
+endif
diff --git a/genl/static-syms.c b/genl/static-syms.c
new file mode 100644
index 0000000..1ed3a8a
--- /dev/null
+++ b/genl/static-syms.c
@@ -0,0 +1,6 @@
+#include <string.h>
+void *_dlsym(const char *sym)
+{
+#include "static-syms.h"
+ return NULL;
+}
diff --git a/include/dlfcn.h b/include/dlfcn.h
new file mode 100644
index 0000000..b0be5a0
--- /dev/null
+++ b/include/dlfcn.h
@@ -0,0 +1,39 @@
+/*
+ * Stub dlfcn implementation for systems that lack shared library support
+ * but obviously can still reference compiled-in symbols.
+ */
+
+#ifndef NO_SHARED_LIBS
+#include_next <dlfcn.h>
+#else
+
+#define RTLD_LAZY 0
+#define _FAKE_DLFCN_HDL (void *)0xbeefcafe
+
+static inline void *dlopen(const char *file, int flag)
+{
+ if (file == NULL)
+ return _FAKE_DLFCN_HDL;
+ else
+ return NULL;
+}
+
+extern void *_dlsym(const char *sym);
+static inline void *dlsym(void *handle, const char *sym)
+{
+ if (handle != _FAKE_DLFCN_HDL)
+ return NULL;
+ return _dlsym(sym);
+}
+
+static inline char *dlerror(void)
+{
+ return NULL;
+}
+
+static inline int dlclose(void *handle)
+{
+ return (handle == _FAKE_DLFCN_HDL) ? 0 : 1;
+}
+
+#endif
diff --git a/ip/Makefile b/ip/Makefile
index 3c185cf..51914e8 100644
--- a/ip/Makefile
+++ b/ip/Makefile
@@ -23,6 +23,20 @@ install: all
clean:
rm -f $(ALLOBJ) $(TARGETS)
-LDLIBS += -ldl
+SHARED_LIBS ?= y
+ifeq ($(SHARED_LIBS),y)
+LDLIBS += -ldl
LDFLAGS += -Wl,-export-dynamic
+
+else
+
+ip: static-syms.o
+static-syms.o: static-syms.h
+static-syms.h: $(wildcard *.c)
+ files="$^" ; \
+ for s in `grep -B 3 '\<dlsym' $$files | sed -n '/snprintf/{s:.*"\([^"]*\)".*:\1:;s:%s::;p}'` ; do \
+ sed -n '/'$$s'[^ ]* =/{s:.* \([^ ]*'$$s'[^ ]*\) .*:extern char \1[] __attribute__((weak)); if (!strcmp(sym, "\1")) return \1;:;p}' $$files ; \
+ done > $@
+
+endif
diff --git a/ip/static-syms.c b/ip/static-syms.c
new file mode 100644
index 0000000..1ed3a8a
--- /dev/null
+++ b/ip/static-syms.c
@@ -0,0 +1,6 @@
+#include <string.h>
+void *_dlsym(const char *sym)
+{
+#include "static-syms.h"
+ return NULL;
+}
diff --git a/tc/Makefile b/tc/Makefile
index 3ff2535..027055c 100644
--- a/tc/Makefile
+++ b/tc/Makefile
@@ -3,6 +3,7 @@ TCOBJ= tc.o tc_qdisc.o tc_class.o tc_filter.o tc_util.o \
m_ematch.o emp_ematch.yacc.o emp_ematch.lex.o
include ../Config
+SHARED_LIBS ?= y
TCMODULES :=
TCMODULES += q_fifo.o
@@ -57,7 +58,12 @@ else
endif
TCOBJ += $(TCMODULES)
-LDLIBS += -L. -ltc -lm -ldl
+LDLIBS += -L. -ltc -lm
+
+ifeq ($(SHARED_LIBS),y)
+LDLIBS += -ldl
+LDFLAGS += -Wl,-export-dynamic
+endif
TCLIB := tc_core.o
TCLIB += tc_red.o
@@ -72,9 +78,6 @@ ifeq ($(TC_CONFIG_ATM),y)
TCSO += q_atm.so
endif
-
-LDFLAGS += -Wl,-export-dynamic
-
YACC := bison
LEX := flex
@@ -108,3 +111,15 @@ q_atm.so: q_atm.c
%.lex.c: %.l
$(LEX) $(LEXFLAGS) -o$@ $<
+
+ifneq ($(SHARED_LIBS),y)
+
+tc: static-syms.o
+static-syms.o: static-syms.h
+static-syms.h: $(wildcard *.c)
+ files="$^" ; \
+ for s in `grep -B 3 '\<dlsym' $$files | sed -n '/snprintf/{s:.*"\([^"]*\)".*:\1:;s:%s::;p}'` ; do \
+ sed -n '/'$$s'[^ ]* =/{s:.* \([^ ]*'$$s'[^ ]*\) .*:extern char \1[] __attribute__((weak)); if (!strcmp(sym, "\1")) return \1;:;p}' $$files ; \
+ done > $@
+
+endif
diff --git a/tc/m_ipt.c b/tc/m_ipt.c
index d17d324..99d9965 100644
--- a/tc/m_ipt.c
+++ b/tc/m_ipt.c
@@ -226,6 +226,10 @@ get_target_name(const char *name)
struct iptables_target *m;
char path[strlen(lib_dir) + sizeof ("/libipt_.so") + strlen(name)];
+#ifdef NO_SHARED_LIBS
+ return NULL;
+#endif
+
new_name = malloc(strlen(name) + 1);
lname = malloc(strlen(name) + 1);
if (new_name)
diff --git a/tc/static-syms.c b/tc/static-syms.c
new file mode 100644
index 0000000..1ed3a8a
--- /dev/null
+++ b/tc/static-syms.c
@@ -0,0 +1,6 @@
+#include <string.h>
+void *_dlsym(const char *sym)
+{
+#include "static-syms.h"
+ return NULL;
+}
--
1.6.5.1
^ permalink raw reply related
* Re: [PATCH 0/5] Candidate fix for increased number of GFP_ATOMIC failures V2
From: Tobias Diedrich @ 2009-11-06 11:15 UTC (permalink / raw)
To: Mel Gorman
Cc: Frans Pop, Jiri Kosina, Sven Geggus, Karol Lewandowski,
Tobias Oetiker, Rafael J. Wysocki, David Miller, Reinette Chatre,
Kalle Valo, David Rientjes, KOSAKI Motohiro, Mohamed Abbas,
Jens Axboe, John W. Linville, Pekka Enberg,
Bartlomiej Zolnierkiewicz, Greg Kroah-Hartman,
Stephan von Krawczynski, Kernel Testers List, netdev,
linux-kernel, linux-mm@kvack.org
In-Reply-To: <20091106092447.GC25926@csn.ul.ie>
Mel Gorman wrote:
> On Fri, Nov 06, 2009 at 07:03:23AM +0100, Tobias Diedrich wrote:
> > Mel Gorman wrote:
> > > [No BZ ID] Kernel crash on 2.6.31.x (kcryptd: page allocation failure..)
> > > This apparently is easily reproducible, particular in comparison to
> > > the other reports. The point of greatest interest is that this is
> > > order-0 GFP_ATOMIC failures. Sven, I'm hoping that you in particular
> > > will be able to follow the tests below as you are the most likely
> > > person to have an easily reproducible situation.
> >
> > I've also seen order-0 failures on 2.6.31.5:
> > Note that this is with a one process hogging and mlocking memory and
> > min_free_kbytes reduced to 100 to reproduce the problem more easily.
> >
>
> Is that a vanilla, with patches 1-3 applied or both?
That was on vanilla 2.6.31.5.
I tried 2.6.31.5 before with patches 1+2 and netconsole enabled and
still got the order-1 failures (apparently I get order-1 failures
with netconsole and order-0 failures without).
> > I tried bisecting the issue, but in the end without memory pressure
> > I can't reproduce it reliably and with the above mentioned pressure
> > I get allocation failures even on 2.6.30.o
>
> To be honest, it's not entirely unexpected with min_free_kbytes set that
> low. The system should cope with a certain amount of pressure but with
> pressure and a low min_free_kbytes, the system will simply be reacting
> too late to free memory in the non-atomic paths.
Maybe I should try again on 2.6.30 without netconsole und try
increasing min_free_kbytes until the allocation failures
disappear and try to bisect again with that setting...
--
Tobias PGP: http://8ef7ddba.uguu.de
--
To unsubscribe, send a message with 'unsubscribe linux-mm' in
the body to majordomo@kvack.org. For more info on Linux MM,
see: http://www.linux-mm.org/ .
Don't email: <a href=mailto:"dont@kvack.org"> email@kvack.org </a>
^ permalink raw reply
* [PATCH 1/2] be2net: fix to set proper flow control on resume
From: Ajit Khaparde @ 2009-11-06 12:06 UTC (permalink / raw)
To: David Miller; +Cc: netdev
If be2 goes into suspend after a user changes the flow control settings,
we are not programming them back after resume. This patch takes care of it.
We now get the flow control settings before going to suspend mode and
then apply them during resume.
Signed-off-by: Ajit Khaparde <ajitk@serverengines.com>
---
drivers/net/benet/be.h | 2 ++
drivers/net/benet/be_ethtool.c | 8 +++++---
drivers/net/benet/be_main.c | 8 +++++++-
3 files changed, 14 insertions(+), 4 deletions(-)
diff --git a/drivers/net/benet/be.h b/drivers/net/benet/be.h
index a80da0e..3b79a22 100644
--- a/drivers/net/benet/be.h
+++ b/drivers/net/benet/be.h
@@ -259,6 +259,8 @@ struct be_adapter {
u32 port_num;
bool promiscuous;
u32 cap;
+ u32 rx_fc; /* Rx flow control */
+ u32 tx_fc; /* Tx flow control */
};
extern const struct ethtool_ops be_ethtool_ops;
diff --git a/drivers/net/benet/be_ethtool.c b/drivers/net/benet/be_ethtool.c
index cda5bf2..f0fd95b 100644
--- a/drivers/net/benet/be_ethtool.c
+++ b/drivers/net/benet/be_ethtool.c
@@ -323,10 +323,12 @@ be_set_pauseparam(struct net_device *netdev, struct ethtool_pauseparam *ecmd)
if (ecmd->autoneg != 0)
return -EINVAL;
+ adapter->tx_fc = ecmd->tx_pause;
+ adapter->rx_fc = ecmd->rx_pause;
- status = be_cmd_set_flow_control(adapter, ecmd->tx_pause,
- ecmd->rx_pause);
- if (!status)
+ status = be_cmd_set_flow_control(adapter,
+ adapter->tx_fc, adapter->rx_fc);
+ if (status)
dev_warn(&adapter->pdev->dev, "Pause param set failed.\n");
return status;
diff --git a/drivers/net/benet/be_main.c b/drivers/net/benet/be_main.c
index 1f941f0..4a7a452 100644
--- a/drivers/net/benet/be_main.c
+++ b/drivers/net/benet/be_main.c
@@ -1652,7 +1652,8 @@ static int be_setup(struct be_adapter *adapter)
if (status != 0)
goto mccqs_destroy;
- status = be_cmd_set_flow_control(adapter, true, true);
+ status = be_cmd_set_flow_control(adapter,
+ adapter->tx_fc, adapter->rx_fc);
if (status != 0)
goto mccqs_destroy;
return 0;
@@ -1909,6 +1910,10 @@ static void be_netdev_init(struct net_device *netdev)
adapter->rx_csum = true;
+ /* Default settings for Rx and Tx flow control */
+ adapter->rx_fc = true;
+ adapter->tx_fc = true;
+
netif_set_gso_max_size(netdev, 65535);
BE_SET_NETDEV_OPS(netdev, &be_netdev_ops);
@@ -2171,6 +2176,7 @@ static int be_suspend(struct pci_dev *pdev, pm_message_t state)
be_close(netdev);
rtnl_unlock();
}
+ be_cmd_get_flow_control(adapter, &adapter->tx_fc, &adapter->rx_fc);
be_clear(adapter);
pci_save_state(pdev);
--
1.6.3.3
^ permalink raw reply related
* [PATCH 2/2] be2net: Bug fix to send config commands to hardware after netdev_register
From: Ajit Khaparde @ 2009-11-06 12:07 UTC (permalink / raw)
To: David Miller; +Cc: netdev
Sending config commands to be2 hardware before netdev_register is
completed, is sometimes causing the async link notification to arrive
even before the driver is ready to handle it. The commands for vlan
config and flow control settings can infact wait till be_open.
This patch takes care of that.
Signed-off-by: Ajit Khaparde <ajitk@serverengines.com>
---
drivers/net/benet/be_main.c | 24 ++++++++++++------------
1 files changed, 12 insertions(+), 12 deletions(-)
diff --git a/drivers/net/benet/be_main.c b/drivers/net/benet/be_main.c
index 4a7a452..876b357 100644
--- a/drivers/net/benet/be_main.c
+++ b/drivers/net/benet/be_main.c
@@ -1610,11 +1610,21 @@ static int be_open(struct net_device *netdev)
status = be_cmd_link_status_query(adapter, &link_up);
if (status)
- return status;
+ goto ret_sts;
be_link_status_update(adapter, link_up);
+ status = be_vid_config(adapter);
+ if (status)
+ goto ret_sts;
+
+ status = be_cmd_set_flow_control(adapter,
+ adapter->tx_fc, adapter->rx_fc);
+ if (status)
+ goto ret_sts;
+
schedule_delayed_work(&adapter->work, msecs_to_jiffies(100));
- return 0;
+ret_sts:
+ return status;
}
static int be_setup(struct be_adapter *adapter)
@@ -1648,18 +1658,8 @@ static int be_setup(struct be_adapter *adapter)
if (status != 0)
goto rx_qs_destroy;
- status = be_vid_config(adapter);
- if (status != 0)
- goto mccqs_destroy;
-
- status = be_cmd_set_flow_control(adapter,
- adapter->tx_fc, adapter->rx_fc);
- if (status != 0)
- goto mccqs_destroy;
return 0;
-mccqs_destroy:
- be_mcc_queues_destroy(adapter);
rx_qs_destroy:
be_rx_queues_destroy(adapter);
tx_qs_destroy:
--
1.6.3.3
^ permalink raw reply related
* [NEXT PULL 00/17] IEEE 802.15.4 stack updates.
From: Dmitry Eremin-Solenikov @ 2009-11-06 12:39 UTC (permalink / raw)
To: David S. Miller; +Cc: netdev, Sergey Lapin
Please pull into net-next an update for IEEE 802.15.4
The following changes since commit 6a2a2d6bf8581216e08be15fcb563cfd6c430e1e:
Gilad Ben-Yossef (1):
tcp: Use defaults when no route options are available
are available in the git repository at:
git://git.kernel.org/pub/scm/linux/kernel/git/lowpan/lowpan.git for-next
Dmitry Eremin-Solenikov (17):
wpan-phy: add a helper to put the wpan_phy device
wpan-phy: add wpan-phy iteration functions
wpan-phy: init channel/page fields
wpan-phy: use snprintf to limit the amount of chars written
wpan-phy: allow specifying a per-page channel mask
wpan-phy: follow usual patter of devices registration
ieee802154: constify struct net_device in some operations
ieee802154: merge nl802154 and wpan-class in single module
ieee802154: split away MAC commands implementation
ieee802154: add LIST_PHY command support
fakehard: no need to export net_to_phy, make it static
fakehard: claim all 2.4 Ghz channels as supported
ieee802154: add an mlme_ops call to retrieve PHY object
fakehard: mlme_ops->get_phy implementation
ieee802154: add two nl802154 helpers
ieee802154: add PHY_NAME to LIST_IFACE command results
ieee802154: add support for creation/removal of logic interfaces
drivers/ieee802154/fakehard.c | 59 +++-
include/linux/nl802154.h | 6 +
include/net/ieee802154_netdev.h | 16 +-
include/net/wpan-phy.h | 22 ++-
net/ieee802154/Makefile | 4 +-
net/ieee802154/ieee802154.h | 53 ++++
net/ieee802154/netlink.c | 613 ++------------------------------------
net/ieee802154/nl-mac.c | 617 +++++++++++++++++++++++++++++++++++++++
net/ieee802154/nl-phy.c | 344 ++++++++++++++++++++++
net/ieee802154/nl_policy.c | 2 +
net/ieee802154/wpan-class.c | 77 +++++-
11 files changed, 1202 insertions(+), 611 deletions(-)
create mode 100644 net/ieee802154/ieee802154.h
create mode 100644 net/ieee802154/nl-mac.c
create mode 100644 net/ieee802154/nl-phy.c
^ permalink raw reply
* [PATCH 01/17] wpan-phy: add a helper to put the wpan_phy device
From: Dmitry Eremin-Solenikov @ 2009-11-06 12:39 UTC (permalink / raw)
To: David S. Miller; +Cc: netdev, Sergey Lapin
In-Reply-To: <1257511181-19403-1-git-send-email-dbaryshkov@gmail.com>
Signed-off-by: Dmitry Eremin-Solenikov <dbaryshkov@gmail.com>
---
include/net/wpan-phy.h | 6 ++++++
1 files changed, 6 insertions(+), 0 deletions(-)
diff --git a/include/net/wpan-phy.h b/include/net/wpan-phy.h
index 547b1e2..5e803a0 100644
--- a/include/net/wpan-phy.h
+++ b/include/net/wpan-phy.h
@@ -56,6 +56,12 @@ static inline void *wpan_phy_priv(struct wpan_phy *phy)
}
struct wpan_phy *wpan_phy_find(const char *str);
+
+static inline void wpan_phy_put(struct wpan_phy *phy)
+{
+ put_device(&phy->dev);
+}
+
static inline const char *wpan_phy_name(struct wpan_phy *phy)
{
return dev_name(&phy->dev);
--
1.6.5
^ permalink raw reply related
* [PATCH 02/17] wpan-phy: add wpan-phy iteration functions
From: Dmitry Eremin-Solenikov @ 2009-11-06 12:39 UTC (permalink / raw)
To: David S. Miller; +Cc: netdev, Sergey Lapin
In-Reply-To: <1257511181-19403-1-git-send-email-dbaryshkov@gmail.com>
Add API to iterate over the wpan-phy instances.
Signed-off-by: Dmitry Eremin-Solenikov <dbaryshkov@gmail.com>
---
include/net/wpan-phy.h | 2 ++
net/ieee802154/wpan-class.c | 25 +++++++++++++++++++++++++
2 files changed, 27 insertions(+), 0 deletions(-)
diff --git a/include/net/wpan-phy.h b/include/net/wpan-phy.h
index 5e803a0..3367dd9 100644
--- a/include/net/wpan-phy.h
+++ b/include/net/wpan-phy.h
@@ -48,6 +48,8 @@ struct wpan_phy *wpan_phy_alloc(size_t priv_size);
int wpan_phy_register(struct device *parent, struct wpan_phy *phy);
void wpan_phy_unregister(struct wpan_phy *phy);
void wpan_phy_free(struct wpan_phy *phy);
+/* Same semantics as for class_for_each_device */
+int wpan_phy_for_each(int (*fn)(struct wpan_phy *phy, void *data), void *data);
static inline void *wpan_phy_priv(struct wpan_phy *phy)
{
diff --git a/net/ieee802154/wpan-class.c b/net/ieee802154/wpan-class.c
index f306604..0cec138 100644
--- a/net/ieee802154/wpan-class.c
+++ b/net/ieee802154/wpan-class.c
@@ -91,6 +91,31 @@ struct wpan_phy *wpan_phy_find(const char *str)
}
EXPORT_SYMBOL(wpan_phy_find);
+struct wpan_phy_iter_data {
+ int (*fn)(struct wpan_phy *phy, void *data);
+ void *data;
+};
+
+static int wpan_phy_iter(struct device *dev, void *_data)
+{
+ struct wpan_phy_iter_data *wpid = _data;
+ struct wpan_phy *phy = container_of(dev, struct wpan_phy, dev);
+ return wpid->fn(phy, wpid->data);
+}
+
+int wpan_phy_for_each(int (*fn)(struct wpan_phy *phy, void *data),
+ void *data)
+{
+ struct wpan_phy_iter_data wpid = {
+ .fn = fn,
+ .data = data,
+ };
+
+ return class_for_each_device(&wpan_phy_class, NULL,
+ &wpid, wpan_phy_iter);
+}
+EXPORT_SYMBOL(wpan_phy_for_each);
+
static int wpan_phy_idx_valid(int idx)
{
return idx >= 0;
--
1.6.5
^ permalink raw reply related
* [PATCH 03/17] wpan-phy: init channel/page fields
From: Dmitry Eremin-Solenikov @ 2009-11-06 12:39 UTC (permalink / raw)
To: David S. Miller; +Cc: netdev, Sergey Lapin
In-Reply-To: <1257511181-19403-1-git-send-email-dbaryshkov@gmail.com>
Set page to zero (for compatibility w/ devices supporting only first page).
Also init channel by default to -1 to disallow transfers for non-initialised
devices.
Signed-off-by: Dmitry Eremin-Solenikov <dbaryshkov@gmail.com>
---
net/ieee802154/wpan-class.c | 3 +++
1 files changed, 3 insertions(+), 0 deletions(-)
diff --git a/net/ieee802154/wpan-class.c b/net/ieee802154/wpan-class.c
index 0cec138..a10ae5b 100644
--- a/net/ieee802154/wpan-class.c
+++ b/net/ieee802154/wpan-class.c
@@ -143,6 +143,9 @@ struct wpan_phy *wpan_phy_alloc(size_t priv_size)
phy->dev.class = &wpan_phy_class;
+ phy->current_channel = -1; /* not initialised */
+ phy->current_page = 0; /* for compatibility */
+
return phy;
}
EXPORT_SYMBOL(wpan_phy_alloc);
--
1.6.5
^ permalink raw reply related
* [PATCH 04/17] wpan-phy: use snprintf to limit the amount of chars written
From: Dmitry Eremin-Solenikov @ 2009-11-06 12:39 UTC (permalink / raw)
To: David S. Miller; +Cc: netdev, Sergey Lapin
In-Reply-To: <1257511181-19403-1-git-send-email-dbaryshkov@gmail.com>
Use snprintf to limit the amount of chars put in the buffer for attr -> show.
Signed-off-by: Dmitry Eremin-Solenikov <dbaryshkov@gmail.com>
---
net/ieee802154/wpan-class.c | 2 +-
1 files changed, 1 insertions(+), 1 deletions(-)
diff --git a/net/ieee802154/wpan-class.c b/net/ieee802154/wpan-class.c
index a10ae5b..68ccde6 100644
--- a/net/ieee802154/wpan-class.c
+++ b/net/ieee802154/wpan-class.c
@@ -30,7 +30,7 @@ static ssize_t name ## _show(struct device *dev, \
int ret; \
\
mutex_lock(&phy->pib_lock); \
- ret = sprintf(buf, format_string "\n", args); \
+ ret = snprintf(buf, PAGE_SIZE, format_string "\n", args); \
mutex_unlock(&phy->pib_lock); \
return ret; \
}
--
1.6.5
^ permalink raw reply related
* [PATCH 05/17] wpan-phy: allow specifying a per-page channel mask
From: Dmitry Eremin-Solenikov @ 2009-11-06 12:39 UTC (permalink / raw)
To: David S. Miller; +Cc: netdev, Sergey Lapin
In-Reply-To: <1257511181-19403-1-git-send-email-dbaryshkov@gmail.com>
IEEE 802.15.4-2006 defines channel pages that hold channels (max 32 pages,
27 channels per page). Allow the driver to specify supported channels
on pages, other than the first one.
Signed-off-by: Dmitry Eremin-Solenikov <dbaryshkov@gmail.com>
---
drivers/ieee802154/fakehard.c | 2 +-
include/net/wpan-phy.h | 2 +-
net/ieee802154/wpan-class.c | 20 +++++++++++++++++++-
3 files changed, 21 insertions(+), 3 deletions(-)
diff --git a/drivers/ieee802154/fakehard.c b/drivers/ieee802154/fakehard.c
index 96a2959..f6f2afe 100644
--- a/drivers/ieee802154/fakehard.c
+++ b/drivers/ieee802154/fakehard.c
@@ -356,7 +356,7 @@ static int __devinit ieee802154fake_probe(struct platform_device *pdev)
dev->addr_len);
memcpy(dev->perm_addr, dev->dev_addr, dev->addr_len);
- phy->channels_supported = (1 << 27) - 1;
+ phy->channels_supported[0] = (1 << 27) - 1;
phy->transmit_power = 0xbf;
dev->netdev_ops = &fake_ops;
diff --git a/include/net/wpan-phy.h b/include/net/wpan-phy.h
index 3367dd9..7b7fc58 100644
--- a/include/net/wpan-phy.h
+++ b/include/net/wpan-phy.h
@@ -34,7 +34,7 @@ struct wpan_phy {
*/
u8 current_channel;
u8 current_page;
- u32 channels_supported;
+ u32 channels_supported[32];
u8 transmit_power;
u8 cca_mode;
diff --git a/net/ieee802154/wpan-class.c b/net/ieee802154/wpan-class.c
index 68ccde6..0c51f85 100644
--- a/net/ieee802154/wpan-class.c
+++ b/net/ieee802154/wpan-class.c
@@ -40,12 +40,30 @@ static ssize_t name ## _show(struct device *dev, \
MASTER_SHOW(current_channel, "%d");
MASTER_SHOW(current_page, "%d");
-MASTER_SHOW(channels_supported, "%#x");
MASTER_SHOW_COMPLEX(transmit_power, "%d +- %d dB",
((signed char) (phy->transmit_power << 2)) >> 2,
(phy->transmit_power >> 6) ? (phy->transmit_power >> 6) * 3 : 1 );
MASTER_SHOW(cca_mode, "%d");
+static ssize_t channels_supported_show(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ struct wpan_phy *phy = container_of(dev, struct wpan_phy, dev);
+ int ret;
+ int i, len = 0;
+
+ mutex_lock(&phy->pib_lock);
+ for (i = 0; i < 32; i++) {
+ ret = snprintf(buf + len, PAGE_SIZE - len,
+ "%#09x\n", phy->channels_supported[i]);
+ if (ret < 0)
+ break;
+ len += ret;
+ }
+ mutex_unlock(&phy->pib_lock);
+ return len;
+}
+
static struct device_attribute pmib_attrs[] = {
__ATTR_RO(current_channel),
__ATTR_RO(current_page),
--
1.6.5
^ permalink raw reply related
* [PATCH 06/17] wpan-phy: follow usual patter of devices registration
From: Dmitry Eremin-Solenikov @ 2009-11-06 12:39 UTC (permalink / raw)
To: David S. Miller; +Cc: netdev, Sergey Lapin
In-Reply-To: <1257511181-19403-1-git-send-email-dbaryshkov@gmail.com>
Follow the usual pattern of devices registration by adding new function
(wpan_phy_set_dev) that sets child->parent relationship and removing
parent argument from wpan_phy_register call.
Signed-off-by: Dmitry Eremin-Solenikov <dbaryshkov@gmail.com>
---
drivers/ieee802154/fakehard.c | 3 ++-
include/net/wpan-phy.h | 6 +++++-
net/ieee802154/wpan-class.c | 4 +---
3 files changed, 8 insertions(+), 5 deletions(-)
diff --git a/drivers/ieee802154/fakehard.c b/drivers/ieee802154/fakehard.c
index f6f2afe..4ea93cc 100644
--- a/drivers/ieee802154/fakehard.c
+++ b/drivers/ieee802154/fakehard.c
@@ -372,11 +372,12 @@ static int __devinit ieee802154fake_probe(struct platform_device *pdev)
goto out;
}
+ wpan_phy_set_dev(phy, &pdev->dev);
SET_NETDEV_DEV(dev, &phy->dev);
platform_set_drvdata(pdev, dev);
- err = wpan_phy_register(&pdev->dev, phy);
+ err = wpan_phy_register(phy);
if (err)
goto out;
diff --git a/include/net/wpan-phy.h b/include/net/wpan-phy.h
index 7b7fc58..f63537c 100644
--- a/include/net/wpan-phy.h
+++ b/include/net/wpan-phy.h
@@ -45,7 +45,11 @@ struct wpan_phy {
};
struct wpan_phy *wpan_phy_alloc(size_t priv_size);
-int wpan_phy_register(struct device *parent, struct wpan_phy *phy);
+static inline void wpan_phy_set_dev(struct wpan_phy *phy, struct device *dev)
+{
+ phy->dev.parent = dev;
+}
+int wpan_phy_register(struct wpan_phy *phy);
void wpan_phy_unregister(struct wpan_phy *phy);
void wpan_phy_free(struct wpan_phy *phy);
/* Same semantics as for class_for_each_device */
diff --git a/net/ieee802154/wpan-class.c b/net/ieee802154/wpan-class.c
index 0c51f85..cd42e88 100644
--- a/net/ieee802154/wpan-class.c
+++ b/net/ieee802154/wpan-class.c
@@ -168,10 +168,8 @@ struct wpan_phy *wpan_phy_alloc(size_t priv_size)
}
EXPORT_SYMBOL(wpan_phy_alloc);
-int wpan_phy_register(struct device *parent, struct wpan_phy *phy)
+int wpan_phy_register(struct wpan_phy *phy)
{
- phy->dev.parent = parent;
-
return device_add(&phy->dev);
}
EXPORT_SYMBOL(wpan_phy_register);
--
1.6.5
^ permalink raw reply related
* [PATCH 07/17] ieee802154: constify struct net_device in some operations
From: Dmitry Eremin-Solenikov @ 2009-11-06 12:39 UTC (permalink / raw)
To: David S. Miller; +Cc: netdev, Sergey Lapin
In-Reply-To: <1257511181-19403-1-git-send-email-dbaryshkov@gmail.com>
Some of ieee802154 operations really shouldn't change passed net_device.
Constify passed argument.
Signed-off-by: Dmitry Eremin-Solenikov <dbaryshkov@gmail.com>
---
drivers/ieee802154/fakehard.c | 8 ++++----
include/net/ieee802154_netdev.h | 10 +++++-----
2 files changed, 9 insertions(+), 9 deletions(-)
diff --git a/drivers/ieee802154/fakehard.c b/drivers/ieee802154/fakehard.c
index 4ea93cc..77fbb51 100644
--- a/drivers/ieee802154/fakehard.c
+++ b/drivers/ieee802154/fakehard.c
@@ -43,7 +43,7 @@ struct wpan_phy *net_to_phy(struct net_device *dev)
*
* Return the ID of the PAN from the PIB.
*/
-static u16 fake_get_pan_id(struct net_device *dev)
+static u16 fake_get_pan_id(const struct net_device *dev)
{
BUG_ON(dev->type != ARPHRD_IEEE802154);
@@ -58,7 +58,7 @@ static u16 fake_get_pan_id(struct net_device *dev)
* device. If the device has not yet had a short address assigned
* then this should return 0xFFFF to indicate a lack of association.
*/
-static u16 fake_get_short_addr(struct net_device *dev)
+static u16 fake_get_short_addr(const struct net_device *dev)
{
BUG_ON(dev->type != ARPHRD_IEEE802154);
@@ -78,7 +78,7 @@ static u16 fake_get_short_addr(struct net_device *dev)
* Note: This is in section 7.2.1.2 of the IEEE 802.15.4-2006
* document.
*/
-static u8 fake_get_dsn(struct net_device *dev)
+static u8 fake_get_dsn(const struct net_device *dev)
{
BUG_ON(dev->type != ARPHRD_IEEE802154);
@@ -98,7 +98,7 @@ static u8 fake_get_dsn(struct net_device *dev)
* Note: This is in section 7.2.1.2 of the IEEE 802.15.4-2006
* document.
*/
-static u8 fake_get_bsn(struct net_device *dev)
+static u8 fake_get_bsn(const struct net_device *dev)
{
BUG_ON(dev->type != ARPHRD_IEEE802154);
diff --git a/include/net/ieee802154_netdev.h b/include/net/ieee802154_netdev.h
index 5dc6a61..d23fb5a 100644
--- a/include/net/ieee802154_netdev.h
+++ b/include/net/ieee802154_netdev.h
@@ -98,14 +98,14 @@ struct ieee802154_mlme_ops {
* FIXME: these should become the part of PIB/MIB interface.
* However we still don't have IB interface of any kind
*/
- u16 (*get_pan_id)(struct net_device *dev);
- u16 (*get_short_addr)(struct net_device *dev);
- u8 (*get_dsn)(struct net_device *dev);
- u8 (*get_bsn)(struct net_device *dev);
+ u16 (*get_pan_id)(const struct net_device *dev);
+ u16 (*get_short_addr)(const struct net_device *dev);
+ u8 (*get_dsn)(const struct net_device *dev);
+ u8 (*get_bsn)(const struct net_device *dev);
};
static inline struct ieee802154_mlme_ops *ieee802154_mlme_ops(
- struct net_device *dev)
+ const struct net_device *dev)
{
return dev->ml_priv;
}
--
1.6.5
^ permalink raw reply related
* [PATCH 08/17] ieee802154: merge nl802154 and wpan-class in single module
From: Dmitry Eremin-Solenikov @ 2009-11-06 12:39 UTC (permalink / raw)
To: David S. Miller; +Cc: netdev, Sergey Lapin
In-Reply-To: <1257511181-19403-1-git-send-email-dbaryshkov@gmail.com>
There is no real need to have ieee802154 interfaces separate
into several small modules, as neither of them has it's own use.
Signed-off-by: Dmitry Eremin-Solenikov <dbaryshkov@gmail.com>
---
net/ieee802154/Makefile | 4 ++--
net/ieee802154/netlink.c | 9 ++-------
net/ieee802154/wpan-class.c | 23 ++++++++++++++++++++---
3 files changed, 24 insertions(+), 12 deletions(-)
diff --git a/net/ieee802154/Makefile b/net/ieee802154/Makefile
index 4068a9f..42b1f0d 100644
--- a/net/ieee802154/Makefile
+++ b/net/ieee802154/Makefile
@@ -1,5 +1,5 @@
-obj-$(CONFIG_IEEE802154) += nl802154.o af_802154.o wpan-class.o
-nl802154-y := netlink.o nl_policy.o
+obj-$(CONFIG_IEEE802154) += ieee802154.o af_802154.o
+ieee802154-y := netlink.o nl_policy.o wpan-class.o
af_802154-y := af_ieee802154.o raw.o dgram.o
ccflags-y += -Wall -DDEBUG
diff --git a/net/ieee802154/netlink.c b/net/ieee802154/netlink.c
index ca767bd..0fadd6b 100644
--- a/net/ieee802154/netlink.c
+++ b/net/ieee802154/netlink.c
@@ -643,7 +643,7 @@ static struct genl_ops ieee802154_coordinator_ops[] = {
ieee802154_dump_iface),
};
-static int __init ieee802154_nl_init(void)
+int __init ieee802154_nl_init(void)
{
int rc;
int i;
@@ -676,14 +676,9 @@ fail:
genl_unregister_family(&ieee802154_coordinator_family);
return rc;
}
-module_init(ieee802154_nl_init);
-static void __exit ieee802154_nl_exit(void)
+void __exit ieee802154_nl_exit(void)
{
genl_unregister_family(&ieee802154_coordinator_family);
}
-module_exit(ieee802154_nl_exit);
-
-MODULE_LICENSE("GPL v2");
-MODULE_DESCRIPTION("ieee 802.15.4 configuration interface");
diff --git a/net/ieee802154/wpan-class.c b/net/ieee802154/wpan-class.c
index cd42e88..38bac70 100644
--- a/net/ieee802154/wpan-class.c
+++ b/net/ieee802154/wpan-class.c
@@ -22,6 +22,8 @@
#include <net/wpan-phy.h>
+#include "ieee802154.h"
+
#define MASTER_SHOW_COMPLEX(name, format_string, args...) \
static ssize_t name ## _show(struct device *dev, \
struct device_attribute *attr, char *buf) \
@@ -188,16 +190,31 @@ EXPORT_SYMBOL(wpan_phy_free);
static int __init wpan_phy_class_init(void)
{
- return class_register(&wpan_phy_class);
+ int rc;
+ rc = class_register(&wpan_phy_class);
+ if (rc)
+ goto err;
+
+ rc = ieee802154_nl_init();
+ if (rc)
+ goto err_nl;
+
+ return 0;
+err_nl:
+ class_unregister(&wpan_phy_class);
+err:
+ return rc;
}
-subsys_initcall(wpan_phy_class_init);
+module_init(wpan_phy_class_init);
static void __exit wpan_phy_class_exit(void)
{
+ ieee802154_nl_exit();
class_unregister(&wpan_phy_class);
}
module_exit(wpan_phy_class_exit);
-MODULE_DESCRIPTION("IEEE 802.15.4 device class");
MODULE_LICENSE("GPL v2");
+MODULE_DESCRIPTION("IEEE 802.15.4 configuration interface");
+MODULE_AUTHOR("Dmitry Eremin-Solenikov");
--
1.6.5
^ permalink raw reply related
* [PATCH 09/17] ieee802154: split away MAC commands implementation
From: Dmitry Eremin-Solenikov @ 2009-11-06 12:39 UTC (permalink / raw)
To: David S. Miller; +Cc: netdev, Sergey Lapin
In-Reply-To: <1257511181-19403-1-git-send-email-dbaryshkov@gmail.com>
Move all mac-related stuff to separate file so that ieee802154/netlink.c
contains only generic code.
Signed-off-by: Dmitry Eremin-Solenikov <dbaryshkov@gmail.com>
---
net/ieee802154/Makefile | 2 +-
net/ieee802154/ieee802154.h | 48 +++
net/ieee802154/netlink.c | 605 +-------------------------------
net/ieee802154/{netlink.c => nl-mac.c} | 117 ++-----
4 files changed, 81 insertions(+), 691 deletions(-)
create mode 100644 net/ieee802154/ieee802154.h
copy net/ieee802154/{netlink.c => nl-mac.c} (86%)
diff --git a/net/ieee802154/Makefile b/net/ieee802154/Makefile
index 42b1f0d..69af9f6 100644
--- a/net/ieee802154/Makefile
+++ b/net/ieee802154/Makefile
@@ -1,5 +1,5 @@
obj-$(CONFIG_IEEE802154) += ieee802154.o af_802154.o
-ieee802154-y := netlink.o nl_policy.o wpan-class.o
+ieee802154-y := netlink.o nl-mac.o nl_policy.o wpan-class.o
af_802154-y := af_ieee802154.o raw.o dgram.o
ccflags-y += -Wall -DDEBUG
diff --git a/net/ieee802154/ieee802154.h b/net/ieee802154/ieee802154.h
new file mode 100644
index 0000000..0790eb0
--- /dev/null
+++ b/net/ieee802154/ieee802154.h
@@ -0,0 +1,48 @@
+/*
+ * Copyright (C) 2007, 2008, 2009 Siemens AG
+ *
+ * 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.
+ *
+ */
+#ifndef IEEE_802154_LOCAL_H
+#define IEEE_802154_LOCAL_H
+
+int __init ieee802154_nl_init(void);
+void __exit ieee802154_nl_exit(void);
+
+#define IEEE802154_OP(_cmd, _func) \
+ { \
+ .cmd = _cmd, \
+ .policy = ieee802154_policy, \
+ .doit = _func, \
+ .dumpit = NULL, \
+ .flags = GENL_ADMIN_PERM, \
+ }
+
+#define IEEE802154_DUMP(_cmd, _func, _dump) \
+ { \
+ .cmd = _cmd, \
+ .policy = ieee802154_policy, \
+ .doit = _func, \
+ .dumpit = _dump, \
+ }
+
+struct sk_buff *ieee802154_nl_create(int flags, u8 req);
+int ieee802154_nl_mcast(struct sk_buff *msg, unsigned int group);
+
+extern struct genl_family nl802154_family;
+int nl802154_mac_register(void);
+int nl802154_phy_register(void);
+
+#endif
diff --git a/net/ieee802154/netlink.c b/net/ieee802154/netlink.c
index 0fadd6b..5b738ec 100644
--- a/net/ieee802154/netlink.c
+++ b/net/ieee802154/netlink.c
@@ -23,21 +23,15 @@
*/
#include <linux/kernel.h>
-#include <linux/if_arp.h>
-#include <linux/netdevice.h>
-#include <net/netlink.h>
#include <net/genetlink.h>
-#include <net/sock.h>
#include <linux/nl802154.h>
-#include <net/af_ieee802154.h>
-#include <net/nl802154.h>
-#include <net/ieee802154.h>
-#include <net/ieee802154_netdev.h>
+
+#include "ieee802154.h"
static unsigned int ieee802154_seq_num;
static DEFINE_SPINLOCK(ieee802154_seq_lock);
-static struct genl_family ieee802154_coordinator_family = {
+struct genl_family nl802154_family = {
.id = GENL_ID_GENERATE,
.hdrsize = 0,
.name = IEEE802154_NL_NAME,
@@ -45,16 +39,8 @@ static struct genl_family ieee802154_coordinator_family = {
.maxattr = IEEE802154_ATTR_MAX,
};
-static struct genl_multicast_group ieee802154_coord_mcgrp = {
- .name = IEEE802154_MCAST_COORD_NAME,
-};
-
-static struct genl_multicast_group ieee802154_beacon_mcgrp = {
- .name = IEEE802154_MCAST_BEACON_NAME,
-};
-
/* Requests to userspace */
-static struct sk_buff *ieee802154_nl_create(int flags, u8 req)
+struct sk_buff *ieee802154_nl_create(int flags, u8 req)
{
void *hdr;
struct sk_buff *msg = nlmsg_new(NLMSG_GOODSIZE, GFP_ATOMIC);
@@ -65,7 +51,7 @@ static struct sk_buff *ieee802154_nl_create(int flags, u8 req)
spin_lock_irqsave(&ieee802154_seq_lock, f);
hdr = genlmsg_put(msg, 0, ieee802154_seq_num++,
- &ieee802154_coordinator_family, flags, req);
+ &nl802154_family, flags, req);
spin_unlock_irqrestore(&ieee802154_seq_lock, f);
if (!hdr) {
nlmsg_free(msg);
@@ -75,7 +61,7 @@ static struct sk_buff *ieee802154_nl_create(int flags, u8 req)
return msg;
}
-static int ieee802154_nl_finish(struct sk_buff *msg)
+int ieee802154_nl_mcast(struct sk_buff *msg, unsigned int group)
{
/* XXX: nlh is right at the start of msg */
void *hdr = genlmsg_data(NLMSG_DATA(msg->data));
@@ -83,602 +69,33 @@ static int ieee802154_nl_finish(struct sk_buff *msg)
if (genlmsg_end(msg, hdr) < 0)
goto out;
- return genlmsg_multicast(msg, 0, ieee802154_coord_mcgrp.id,
- GFP_ATOMIC);
+ return genlmsg_multicast(msg, 0, group, GFP_ATOMIC);
out:
nlmsg_free(msg);
return -ENOBUFS;
}
-int ieee802154_nl_assoc_indic(struct net_device *dev,
- struct ieee802154_addr *addr, u8 cap)
-{
- struct sk_buff *msg;
-
- pr_debug("%s\n", __func__);
-
- if (addr->addr_type != IEEE802154_ADDR_LONG) {
- pr_err("%s: received non-long source address!\n", __func__);
- return -EINVAL;
- }
-
- msg = ieee802154_nl_create(0, IEEE802154_ASSOCIATE_INDIC);
- if (!msg)
- return -ENOBUFS;
-
- NLA_PUT_STRING(msg, IEEE802154_ATTR_DEV_NAME, dev->name);
- NLA_PUT_U32(msg, IEEE802154_ATTR_DEV_INDEX, dev->ifindex);
- NLA_PUT(msg, IEEE802154_ATTR_HW_ADDR, IEEE802154_ADDR_LEN,
- dev->dev_addr);
-
- NLA_PUT(msg, IEEE802154_ATTR_SRC_HW_ADDR, IEEE802154_ADDR_LEN,
- addr->hwaddr);
-
- NLA_PUT_U8(msg, IEEE802154_ATTR_CAPABILITY, cap);
-
- return ieee802154_nl_finish(msg);
-
-nla_put_failure:
- nlmsg_free(msg);
- return -ENOBUFS;
-}
-EXPORT_SYMBOL(ieee802154_nl_assoc_indic);
-
-int ieee802154_nl_assoc_confirm(struct net_device *dev, u16 short_addr,
- u8 status)
-{
- struct sk_buff *msg;
-
- pr_debug("%s\n", __func__);
-
- msg = ieee802154_nl_create(0, IEEE802154_ASSOCIATE_CONF);
- if (!msg)
- return -ENOBUFS;
-
- NLA_PUT_STRING(msg, IEEE802154_ATTR_DEV_NAME, dev->name);
- NLA_PUT_U32(msg, IEEE802154_ATTR_DEV_INDEX, dev->ifindex);
- NLA_PUT(msg, IEEE802154_ATTR_HW_ADDR, IEEE802154_ADDR_LEN,
- dev->dev_addr);
-
- NLA_PUT_U16(msg, IEEE802154_ATTR_SHORT_ADDR, short_addr);
- NLA_PUT_U8(msg, IEEE802154_ATTR_STATUS, status);
-
- return ieee802154_nl_finish(msg);
-
-nla_put_failure:
- nlmsg_free(msg);
- return -ENOBUFS;
-}
-EXPORT_SYMBOL(ieee802154_nl_assoc_confirm);
-
-int ieee802154_nl_disassoc_indic(struct net_device *dev,
- struct ieee802154_addr *addr, u8 reason)
-{
- struct sk_buff *msg;
-
- pr_debug("%s\n", __func__);
-
- msg = ieee802154_nl_create(0, IEEE802154_DISASSOCIATE_INDIC);
- if (!msg)
- return -ENOBUFS;
-
- NLA_PUT_STRING(msg, IEEE802154_ATTR_DEV_NAME, dev->name);
- NLA_PUT_U32(msg, IEEE802154_ATTR_DEV_INDEX, dev->ifindex);
- NLA_PUT(msg, IEEE802154_ATTR_HW_ADDR, IEEE802154_ADDR_LEN,
- dev->dev_addr);
-
- if (addr->addr_type == IEEE802154_ADDR_LONG)
- NLA_PUT(msg, IEEE802154_ATTR_SRC_HW_ADDR, IEEE802154_ADDR_LEN,
- addr->hwaddr);
- else
- NLA_PUT_U16(msg, IEEE802154_ATTR_SRC_SHORT_ADDR,
- addr->short_addr);
-
- NLA_PUT_U8(msg, IEEE802154_ATTR_REASON, reason);
-
- return ieee802154_nl_finish(msg);
-
-nla_put_failure:
- nlmsg_free(msg);
- return -ENOBUFS;
-}
-EXPORT_SYMBOL(ieee802154_nl_disassoc_indic);
-
-int ieee802154_nl_disassoc_confirm(struct net_device *dev, u8 status)
-{
- struct sk_buff *msg;
-
- pr_debug("%s\n", __func__);
-
- msg = ieee802154_nl_create(0, IEEE802154_DISASSOCIATE_CONF);
- if (!msg)
- return -ENOBUFS;
-
- NLA_PUT_STRING(msg, IEEE802154_ATTR_DEV_NAME, dev->name);
- NLA_PUT_U32(msg, IEEE802154_ATTR_DEV_INDEX, dev->ifindex);
- NLA_PUT(msg, IEEE802154_ATTR_HW_ADDR, IEEE802154_ADDR_LEN,
- dev->dev_addr);
-
- NLA_PUT_U8(msg, IEEE802154_ATTR_STATUS, status);
-
- return ieee802154_nl_finish(msg);
-
-nla_put_failure:
- nlmsg_free(msg);
- return -ENOBUFS;
-}
-EXPORT_SYMBOL(ieee802154_nl_disassoc_confirm);
-
-int ieee802154_nl_beacon_indic(struct net_device *dev,
- u16 panid, u16 coord_addr)
-{
- struct sk_buff *msg;
-
- pr_debug("%s\n", __func__);
-
- msg = ieee802154_nl_create(0, IEEE802154_BEACON_NOTIFY_INDIC);
- if (!msg)
- return -ENOBUFS;
-
- NLA_PUT_STRING(msg, IEEE802154_ATTR_DEV_NAME, dev->name);
- NLA_PUT_U32(msg, IEEE802154_ATTR_DEV_INDEX, dev->ifindex);
- NLA_PUT(msg, IEEE802154_ATTR_HW_ADDR, IEEE802154_ADDR_LEN,
- dev->dev_addr);
- NLA_PUT_U16(msg, IEEE802154_ATTR_COORD_SHORT_ADDR, coord_addr);
- NLA_PUT_U16(msg, IEEE802154_ATTR_COORD_PAN_ID, panid);
-
- return ieee802154_nl_finish(msg);
-
-nla_put_failure:
- nlmsg_free(msg);
- return -ENOBUFS;
-}
-EXPORT_SYMBOL(ieee802154_nl_beacon_indic);
-
-int ieee802154_nl_scan_confirm(struct net_device *dev,
- u8 status, u8 scan_type, u32 unscanned, u8 page,
- u8 *edl/* , struct list_head *pan_desc_list */)
-{
- struct sk_buff *msg;
-
- pr_debug("%s\n", __func__);
-
- msg = ieee802154_nl_create(0, IEEE802154_SCAN_CONF);
- if (!msg)
- return -ENOBUFS;
-
- NLA_PUT_STRING(msg, IEEE802154_ATTR_DEV_NAME, dev->name);
- NLA_PUT_U32(msg, IEEE802154_ATTR_DEV_INDEX, dev->ifindex);
- NLA_PUT(msg, IEEE802154_ATTR_HW_ADDR, IEEE802154_ADDR_LEN,
- dev->dev_addr);
-
- NLA_PUT_U8(msg, IEEE802154_ATTR_STATUS, status);
- NLA_PUT_U8(msg, IEEE802154_ATTR_SCAN_TYPE, scan_type);
- NLA_PUT_U32(msg, IEEE802154_ATTR_CHANNELS, unscanned);
- NLA_PUT_U8(msg, IEEE802154_ATTR_PAGE, page);
-
- if (edl)
- NLA_PUT(msg, IEEE802154_ATTR_ED_LIST, 27, edl);
-
- return ieee802154_nl_finish(msg);
-
-nla_put_failure:
- nlmsg_free(msg);
- return -ENOBUFS;
-}
-EXPORT_SYMBOL(ieee802154_nl_scan_confirm);
-
-int ieee802154_nl_start_confirm(struct net_device *dev, u8 status)
-{
- struct sk_buff *msg;
-
- pr_debug("%s\n", __func__);
-
- msg = ieee802154_nl_create(0, IEEE802154_START_CONF);
- if (!msg)
- return -ENOBUFS;
-
- NLA_PUT_STRING(msg, IEEE802154_ATTR_DEV_NAME, dev->name);
- NLA_PUT_U32(msg, IEEE802154_ATTR_DEV_INDEX, dev->ifindex);
- NLA_PUT(msg, IEEE802154_ATTR_HW_ADDR, IEEE802154_ADDR_LEN,
- dev->dev_addr);
-
- NLA_PUT_U8(msg, IEEE802154_ATTR_STATUS, status);
-
- return ieee802154_nl_finish(msg);
-
-nla_put_failure:
- nlmsg_free(msg);
- return -ENOBUFS;
-}
-EXPORT_SYMBOL(ieee802154_nl_start_confirm);
-
-static int ieee802154_nl_fill_iface(struct sk_buff *msg, u32 pid,
- u32 seq, int flags, struct net_device *dev)
-{
- void *hdr;
-
- pr_debug("%s\n", __func__);
-
- hdr = genlmsg_put(msg, 0, seq, &ieee802154_coordinator_family, flags,
- IEEE802154_LIST_IFACE);
- if (!hdr)
- goto out;
-
- NLA_PUT_STRING(msg, IEEE802154_ATTR_DEV_NAME, dev->name);
- NLA_PUT_U32(msg, IEEE802154_ATTR_DEV_INDEX, dev->ifindex);
-
- NLA_PUT(msg, IEEE802154_ATTR_HW_ADDR, IEEE802154_ADDR_LEN,
- dev->dev_addr);
- NLA_PUT_U16(msg, IEEE802154_ATTR_SHORT_ADDR,
- ieee802154_mlme_ops(dev)->get_short_addr(dev));
- NLA_PUT_U16(msg, IEEE802154_ATTR_PAN_ID,
- ieee802154_mlme_ops(dev)->get_pan_id(dev));
- return genlmsg_end(msg, hdr);
-
-nla_put_failure:
- genlmsg_cancel(msg, hdr);
-out:
- return -EMSGSIZE;
-}
-
-/* Requests from userspace */
-static struct net_device *ieee802154_nl_get_dev(struct genl_info *info)
-{
- struct net_device *dev;
-
- if (info->attrs[IEEE802154_ATTR_DEV_NAME]) {
- char name[IFNAMSIZ + 1];
- nla_strlcpy(name, info->attrs[IEEE802154_ATTR_DEV_NAME],
- sizeof(name));
- dev = dev_get_by_name(&init_net, name);
- } else if (info->attrs[IEEE802154_ATTR_DEV_INDEX])
- dev = dev_get_by_index(&init_net,
- nla_get_u32(info->attrs[IEEE802154_ATTR_DEV_INDEX]));
- else
- return NULL;
-
- if (!dev)
- return NULL;
-
- if (dev->type != ARPHRD_IEEE802154) {
- dev_put(dev);
- return NULL;
- }
-
- return dev;
-}
-
-static int ieee802154_associate_req(struct sk_buff *skb,
- struct genl_info *info)
-{
- struct net_device *dev;
- struct ieee802154_addr addr;
- u8 page;
- int ret = -EINVAL;
-
- if (!info->attrs[IEEE802154_ATTR_CHANNEL] ||
- !info->attrs[IEEE802154_ATTR_COORD_PAN_ID] ||
- (!info->attrs[IEEE802154_ATTR_COORD_HW_ADDR] &&
- !info->attrs[IEEE802154_ATTR_COORD_SHORT_ADDR]) ||
- !info->attrs[IEEE802154_ATTR_CAPABILITY])
- return -EINVAL;
-
- dev = ieee802154_nl_get_dev(info);
- if (!dev)
- return -ENODEV;
-
- if (info->attrs[IEEE802154_ATTR_COORD_HW_ADDR]) {
- addr.addr_type = IEEE802154_ADDR_LONG;
- nla_memcpy(addr.hwaddr,
- info->attrs[IEEE802154_ATTR_COORD_HW_ADDR],
- IEEE802154_ADDR_LEN);
- } else {
- addr.addr_type = IEEE802154_ADDR_SHORT;
- addr.short_addr = nla_get_u16(
- info->attrs[IEEE802154_ATTR_COORD_SHORT_ADDR]);
- }
- addr.pan_id = nla_get_u16(info->attrs[IEEE802154_ATTR_COORD_PAN_ID]);
-
- if (info->attrs[IEEE802154_ATTR_PAGE])
- page = nla_get_u8(info->attrs[IEEE802154_ATTR_PAGE]);
- else
- page = 0;
-
- ret = ieee802154_mlme_ops(dev)->assoc_req(dev, &addr,
- nla_get_u8(info->attrs[IEEE802154_ATTR_CHANNEL]),
- page,
- nla_get_u8(info->attrs[IEEE802154_ATTR_CAPABILITY]));
-
- dev_put(dev);
- return ret;
-}
-
-static int ieee802154_associate_resp(struct sk_buff *skb,
- struct genl_info *info)
-{
- struct net_device *dev;
- struct ieee802154_addr addr;
- int ret = -EINVAL;
-
- if (!info->attrs[IEEE802154_ATTR_STATUS] ||
- !info->attrs[IEEE802154_ATTR_DEST_HW_ADDR] ||
- !info->attrs[IEEE802154_ATTR_DEST_SHORT_ADDR])
- return -EINVAL;
-
- dev = ieee802154_nl_get_dev(info);
- if (!dev)
- return -ENODEV;
-
- addr.addr_type = IEEE802154_ADDR_LONG;
- nla_memcpy(addr.hwaddr, info->attrs[IEEE802154_ATTR_DEST_HW_ADDR],
- IEEE802154_ADDR_LEN);
- addr.pan_id = ieee802154_mlme_ops(dev)->get_pan_id(dev);
-
-
- ret = ieee802154_mlme_ops(dev)->assoc_resp(dev, &addr,
- nla_get_u16(info->attrs[IEEE802154_ATTR_DEST_SHORT_ADDR]),
- nla_get_u8(info->attrs[IEEE802154_ATTR_STATUS]));
-
- dev_put(dev);
- return ret;
-}
-
-static int ieee802154_disassociate_req(struct sk_buff *skb,
- struct genl_info *info)
-{
- struct net_device *dev;
- struct ieee802154_addr addr;
- int ret = -EINVAL;
-
- if ((!info->attrs[IEEE802154_ATTR_DEST_HW_ADDR] &&
- !info->attrs[IEEE802154_ATTR_DEST_SHORT_ADDR]) ||
- !info->attrs[IEEE802154_ATTR_REASON])
- return -EINVAL;
-
- dev = ieee802154_nl_get_dev(info);
- if (!dev)
- return -ENODEV;
-
- if (info->attrs[IEEE802154_ATTR_DEST_HW_ADDR]) {
- addr.addr_type = IEEE802154_ADDR_LONG;
- nla_memcpy(addr.hwaddr,
- info->attrs[IEEE802154_ATTR_DEST_HW_ADDR],
- IEEE802154_ADDR_LEN);
- } else {
- addr.addr_type = IEEE802154_ADDR_SHORT;
- addr.short_addr = nla_get_u16(
- info->attrs[IEEE802154_ATTR_DEST_SHORT_ADDR]);
- }
- addr.pan_id = ieee802154_mlme_ops(dev)->get_pan_id(dev);
-
- ret = ieee802154_mlme_ops(dev)->disassoc_req(dev, &addr,
- nla_get_u8(info->attrs[IEEE802154_ATTR_REASON]));
-
- dev_put(dev);
- return ret;
-}
-
-/*
- * PANid, channel, beacon_order = 15, superframe_order = 15,
- * PAN_coordinator, battery_life_extension = 0,
- * coord_realignment = 0, security_enable = 0
-*/
-static int ieee802154_start_req(struct sk_buff *skb, struct genl_info *info)
-{
- struct net_device *dev;
- struct ieee802154_addr addr;
-
- u8 channel, bcn_ord, sf_ord;
- u8 page;
- int pan_coord, blx, coord_realign;
- int ret;
-
- if (!info->attrs[IEEE802154_ATTR_COORD_PAN_ID] ||
- !info->attrs[IEEE802154_ATTR_COORD_SHORT_ADDR] ||
- !info->attrs[IEEE802154_ATTR_CHANNEL] ||
- !info->attrs[IEEE802154_ATTR_BCN_ORD] ||
- !info->attrs[IEEE802154_ATTR_SF_ORD] ||
- !info->attrs[IEEE802154_ATTR_PAN_COORD] ||
- !info->attrs[IEEE802154_ATTR_BAT_EXT] ||
- !info->attrs[IEEE802154_ATTR_COORD_REALIGN]
- )
- return -EINVAL;
-
- dev = ieee802154_nl_get_dev(info);
- if (!dev)
- return -ENODEV;
-
- addr.addr_type = IEEE802154_ADDR_SHORT;
- addr.short_addr = nla_get_u16(
- info->attrs[IEEE802154_ATTR_COORD_SHORT_ADDR]);
- addr.pan_id = nla_get_u16(info->attrs[IEEE802154_ATTR_COORD_PAN_ID]);
-
- channel = nla_get_u8(info->attrs[IEEE802154_ATTR_CHANNEL]);
- bcn_ord = nla_get_u8(info->attrs[IEEE802154_ATTR_BCN_ORD]);
- sf_ord = nla_get_u8(info->attrs[IEEE802154_ATTR_SF_ORD]);
- pan_coord = nla_get_u8(info->attrs[IEEE802154_ATTR_PAN_COORD]);
- blx = nla_get_u8(info->attrs[IEEE802154_ATTR_BAT_EXT]);
- coord_realign = nla_get_u8(info->attrs[IEEE802154_ATTR_COORD_REALIGN]);
-
- if (info->attrs[IEEE802154_ATTR_PAGE])
- page = nla_get_u8(info->attrs[IEEE802154_ATTR_PAGE]);
- else
- page = 0;
-
-
- if (addr.short_addr == IEEE802154_ADDR_BROADCAST) {
- ieee802154_nl_start_confirm(dev, IEEE802154_NO_SHORT_ADDRESS);
- dev_put(dev);
- return -EINVAL;
- }
-
- ret = ieee802154_mlme_ops(dev)->start_req(dev, &addr, channel, page,
- bcn_ord, sf_ord, pan_coord, blx, coord_realign);
-
- dev_put(dev);
- return ret;
-}
-
-static int ieee802154_scan_req(struct sk_buff *skb, struct genl_info *info)
-{
- struct net_device *dev;
- int ret;
- u8 type;
- u32 channels;
- u8 duration;
- u8 page;
-
- if (!info->attrs[IEEE802154_ATTR_SCAN_TYPE] ||
- !info->attrs[IEEE802154_ATTR_CHANNELS] ||
- !info->attrs[IEEE802154_ATTR_DURATION])
- return -EINVAL;
-
- dev = ieee802154_nl_get_dev(info);
- if (!dev)
- return -ENODEV;
-
- type = nla_get_u8(info->attrs[IEEE802154_ATTR_SCAN_TYPE]);
- channels = nla_get_u32(info->attrs[IEEE802154_ATTR_CHANNELS]);
- duration = nla_get_u8(info->attrs[IEEE802154_ATTR_DURATION]);
-
- if (info->attrs[IEEE802154_ATTR_PAGE])
- page = nla_get_u8(info->attrs[IEEE802154_ATTR_PAGE]);
- else
- page = 0;
-
-
- ret = ieee802154_mlme_ops(dev)->scan_req(dev, type, channels, page,
- duration);
-
- dev_put(dev);
- return ret;
-}
-
-static int ieee802154_list_iface(struct sk_buff *skb,
- struct genl_info *info)
-{
- /* Request for interface name, index, type, IEEE address,
- PAN Id, short address */
- struct sk_buff *msg;
- struct net_device *dev = NULL;
- int rc = -ENOBUFS;
-
- pr_debug("%s\n", __func__);
-
- dev = ieee802154_nl_get_dev(info);
- if (!dev)
- return -ENODEV;
-
- msg = nlmsg_new(NLMSG_GOODSIZE, GFP_KERNEL);
- if (!msg)
- goto out_dev;
-
- rc = ieee802154_nl_fill_iface(msg, info->snd_pid, info->snd_seq,
- 0, dev);
- if (rc < 0)
- goto out_free;
-
- dev_put(dev);
-
- return genlmsg_unicast(&init_net, msg, info->snd_pid);
-out_free:
- nlmsg_free(msg);
-out_dev:
- dev_put(dev);
- return rc;
-
-}
-
-static int ieee802154_dump_iface(struct sk_buff *skb,
- struct netlink_callback *cb)
-{
- struct net *net = sock_net(skb->sk);
- struct net_device *dev;
- int idx;
- int s_idx = cb->args[0];
-
- pr_debug("%s\n", __func__);
-
- idx = 0;
- for_each_netdev(net, dev) {
- if (idx < s_idx || (dev->type != ARPHRD_IEEE802154))
- goto cont;
-
- if (ieee802154_nl_fill_iface(skb, NETLINK_CB(cb->skb).pid,
- cb->nlh->nlmsg_seq, NLM_F_MULTI, dev) < 0)
- break;
-cont:
- idx++;
- }
- cb->args[0] = idx;
-
- return skb->len;
-}
-
-#define IEEE802154_OP(_cmd, _func) \
- { \
- .cmd = _cmd, \
- .policy = ieee802154_policy, \
- .doit = _func, \
- .dumpit = NULL, \
- .flags = GENL_ADMIN_PERM, \
- }
-
-#define IEEE802154_DUMP(_cmd, _func, _dump) \
- { \
- .cmd = _cmd, \
- .policy = ieee802154_policy, \
- .doit = _func, \
- .dumpit = _dump, \
- }
-
-static struct genl_ops ieee802154_coordinator_ops[] = {
- IEEE802154_OP(IEEE802154_ASSOCIATE_REQ, ieee802154_associate_req),
- IEEE802154_OP(IEEE802154_ASSOCIATE_RESP, ieee802154_associate_resp),
- IEEE802154_OP(IEEE802154_DISASSOCIATE_REQ, ieee802154_disassociate_req),
- IEEE802154_OP(IEEE802154_SCAN_REQ, ieee802154_scan_req),
- IEEE802154_OP(IEEE802154_START_REQ, ieee802154_start_req),
- IEEE802154_DUMP(IEEE802154_LIST_IFACE, ieee802154_list_iface,
- ieee802154_dump_iface),
-};
-
int __init ieee802154_nl_init(void)
{
int rc;
- int i;
- rc = genl_register_family(&ieee802154_coordinator_family);
+ rc = genl_register_family(&nl802154_family);
if (rc)
goto fail;
- rc = genl_register_mc_group(&ieee802154_coordinator_family,
- &ieee802154_coord_mcgrp);
+ rc = nl802154_mac_register();
if (rc)
goto fail;
- rc = genl_register_mc_group(&ieee802154_coordinator_family,
- &ieee802154_beacon_mcgrp);
- if (rc)
- goto fail;
-
-
- for (i = 0; i < ARRAY_SIZE(ieee802154_coordinator_ops); i++) {
- rc = genl_register_ops(&ieee802154_coordinator_family,
- &ieee802154_coordinator_ops[i]);
- if (rc)
- goto fail;
- }
-
return 0;
fail:
- genl_unregister_family(&ieee802154_coordinator_family);
+ genl_unregister_family(&nl802154_family);
return rc;
}
void __exit ieee802154_nl_exit(void)
{
- genl_unregister_family(&ieee802154_coordinator_family);
+ genl_unregister_family(&nl802154_family);
}
diff --git a/net/ieee802154/netlink.c b/net/ieee802154/nl-mac.c
similarity index 86%
copy from net/ieee802154/netlink.c
copy to net/ieee802154/nl-mac.c
index 0fadd6b..e8816bf 100644
--- a/net/ieee802154/netlink.c
+++ b/net/ieee802154/nl-mac.c
@@ -34,16 +34,7 @@
#include <net/ieee802154.h>
#include <net/ieee802154_netdev.h>
-static unsigned int ieee802154_seq_num;
-static DEFINE_SPINLOCK(ieee802154_seq_lock);
-
-static struct genl_family ieee802154_coordinator_family = {
- .id = GENL_ID_GENERATE,
- .hdrsize = 0,
- .name = IEEE802154_NL_NAME,
- .version = 1,
- .maxattr = IEEE802154_ATTR_MAX,
-};
+#include "ieee802154.h"
static struct genl_multicast_group ieee802154_coord_mcgrp = {
.name = IEEE802154_MCAST_COORD_NAME,
@@ -53,43 +44,6 @@ static struct genl_multicast_group ieee802154_beacon_mcgrp = {
.name = IEEE802154_MCAST_BEACON_NAME,
};
-/* Requests to userspace */
-static struct sk_buff *ieee802154_nl_create(int flags, u8 req)
-{
- void *hdr;
- struct sk_buff *msg = nlmsg_new(NLMSG_GOODSIZE, GFP_ATOMIC);
- unsigned long f;
-
- if (!msg)
- return NULL;
-
- spin_lock_irqsave(&ieee802154_seq_lock, f);
- hdr = genlmsg_put(msg, 0, ieee802154_seq_num++,
- &ieee802154_coordinator_family, flags, req);
- spin_unlock_irqrestore(&ieee802154_seq_lock, f);
- if (!hdr) {
- nlmsg_free(msg);
- return NULL;
- }
-
- return msg;
-}
-
-static int ieee802154_nl_finish(struct sk_buff *msg)
-{
- /* XXX: nlh is right at the start of msg */
- void *hdr = genlmsg_data(NLMSG_DATA(msg->data));
-
- if (genlmsg_end(msg, hdr) < 0)
- goto out;
-
- return genlmsg_multicast(msg, 0, ieee802154_coord_mcgrp.id,
- GFP_ATOMIC);
-out:
- nlmsg_free(msg);
- return -ENOBUFS;
-}
-
int ieee802154_nl_assoc_indic(struct net_device *dev,
struct ieee802154_addr *addr, u8 cap)
{
@@ -116,7 +70,7 @@ int ieee802154_nl_assoc_indic(struct net_device *dev,
NLA_PUT_U8(msg, IEEE802154_ATTR_CAPABILITY, cap);
- return ieee802154_nl_finish(msg);
+ return ieee802154_nl_mcast(msg, ieee802154_coord_mcgrp.id);
nla_put_failure:
nlmsg_free(msg);
@@ -143,7 +97,7 @@ int ieee802154_nl_assoc_confirm(struct net_device *dev, u16 short_addr,
NLA_PUT_U16(msg, IEEE802154_ATTR_SHORT_ADDR, short_addr);
NLA_PUT_U8(msg, IEEE802154_ATTR_STATUS, status);
- return ieee802154_nl_finish(msg);
+ return ieee802154_nl_mcast(msg, ieee802154_coord_mcgrp.id);
nla_put_failure:
nlmsg_free(msg);
@@ -176,7 +130,7 @@ int ieee802154_nl_disassoc_indic(struct net_device *dev,
NLA_PUT_U8(msg, IEEE802154_ATTR_REASON, reason);
- return ieee802154_nl_finish(msg);
+ return ieee802154_nl_mcast(msg, ieee802154_coord_mcgrp.id);
nla_put_failure:
nlmsg_free(msg);
@@ -201,7 +155,7 @@ int ieee802154_nl_disassoc_confirm(struct net_device *dev, u8 status)
NLA_PUT_U8(msg, IEEE802154_ATTR_STATUS, status);
- return ieee802154_nl_finish(msg);
+ return ieee802154_nl_mcast(msg, ieee802154_coord_mcgrp.id);
nla_put_failure:
nlmsg_free(msg);
@@ -227,7 +181,7 @@ int ieee802154_nl_beacon_indic(struct net_device *dev,
NLA_PUT_U16(msg, IEEE802154_ATTR_COORD_SHORT_ADDR, coord_addr);
NLA_PUT_U16(msg, IEEE802154_ATTR_COORD_PAN_ID, panid);
- return ieee802154_nl_finish(msg);
+ return ieee802154_nl_mcast(msg, ieee802154_coord_mcgrp.id);
nla_put_failure:
nlmsg_free(msg);
@@ -260,7 +214,7 @@ int ieee802154_nl_scan_confirm(struct net_device *dev,
if (edl)
NLA_PUT(msg, IEEE802154_ATTR_ED_LIST, 27, edl);
- return ieee802154_nl_finish(msg);
+ return ieee802154_nl_mcast(msg, ieee802154_coord_mcgrp.id);
nla_put_failure:
nlmsg_free(msg);
@@ -285,7 +239,7 @@ int ieee802154_nl_start_confirm(struct net_device *dev, u8 status)
NLA_PUT_U8(msg, IEEE802154_ATTR_STATUS, status);
- return ieee802154_nl_finish(msg);
+ return ieee802154_nl_mcast(msg, ieee802154_coord_mcgrp.id);
nla_put_failure:
nlmsg_free(msg);
@@ -300,7 +254,7 @@ static int ieee802154_nl_fill_iface(struct sk_buff *msg, u32 pid,
pr_debug("%s\n", __func__);
- hdr = genlmsg_put(msg, 0, seq, &ieee802154_coordinator_family, flags,
+ hdr = genlmsg_put(msg, 0, seq, &nl802154_family, flags,
IEEE802154_LIST_IFACE);
if (!hdr)
goto out;
@@ -581,7 +535,7 @@ static int ieee802154_list_iface(struct sk_buff *skb,
dev_put(dev);
- return genlmsg_unicast(&init_net, msg, info->snd_pid);
+ return genlmsg_reply(msg, info);
out_free:
nlmsg_free(msg);
out_dev:
@@ -616,23 +570,6 @@ cont:
return skb->len;
}
-#define IEEE802154_OP(_cmd, _func) \
- { \
- .cmd = _cmd, \
- .policy = ieee802154_policy, \
- .doit = _func, \
- .dumpit = NULL, \
- .flags = GENL_ADMIN_PERM, \
- }
-
-#define IEEE802154_DUMP(_cmd, _func, _dump) \
- { \
- .cmd = _cmd, \
- .policy = ieee802154_policy, \
- .doit = _func, \
- .dumpit = _dump, \
- }
-
static struct genl_ops ieee802154_coordinator_ops[] = {
IEEE802154_OP(IEEE802154_ASSOCIATE_REQ, ieee802154_associate_req),
IEEE802154_OP(IEEE802154_ASSOCIATE_RESP, ieee802154_associate_resp),
@@ -643,42 +580,30 @@ static struct genl_ops ieee802154_coordinator_ops[] = {
ieee802154_dump_iface),
};
-int __init ieee802154_nl_init(void)
+/*
+ * No need to unregister as family unregistration will do it.
+ */
+int nl802154_mac_register(void)
{
- int rc;
int i;
+ int rc;
- rc = genl_register_family(&ieee802154_coordinator_family);
- if (rc)
- goto fail;
-
- rc = genl_register_mc_group(&ieee802154_coordinator_family,
+ rc = genl_register_mc_group(&nl802154_family,
&ieee802154_coord_mcgrp);
if (rc)
- goto fail;
+ return rc;
- rc = genl_register_mc_group(&ieee802154_coordinator_family,
+ rc = genl_register_mc_group(&nl802154_family,
&ieee802154_beacon_mcgrp);
if (rc)
- goto fail;
-
+ return rc;
for (i = 0; i < ARRAY_SIZE(ieee802154_coordinator_ops); i++) {
- rc = genl_register_ops(&ieee802154_coordinator_family,
+ rc = genl_register_ops(&nl802154_family,
&ieee802154_coordinator_ops[i]);
if (rc)
- goto fail;
+ return rc;
}
return 0;
-
-fail:
- genl_unregister_family(&ieee802154_coordinator_family);
- return rc;
}
-
-void __exit ieee802154_nl_exit(void)
-{
- genl_unregister_family(&ieee802154_coordinator_family);
-}
-
--
1.6.5
^ permalink raw reply related
* [PATCH 10/17] ieee802154: add LIST_PHY command support
From: Dmitry Eremin-Solenikov @ 2009-11-06 12:39 UTC (permalink / raw)
To: David S. Miller; +Cc: netdev, Sergey Lapin
In-Reply-To: <1257511181-19403-1-git-send-email-dbaryshkov@gmail.com>
Add nl802154 command to get information about PHY's present in
the system.
Signed-off-by: Dmitry Eremin-Solenikov <dbaryshkov@gmail.com>
---
include/linux/nl802154.h | 4 +
net/ieee802154/Makefile | 2 +-
net/ieee802154/netlink.c | 4 +
net/ieee802154/nl-phy.c | 188 ++++++++++++++++++++++++++++++++++++++++++++
net/ieee802154/nl_policy.c | 2 +
5 files changed, 199 insertions(+), 1 deletions(-)
create mode 100644 net/ieee802154/nl-phy.c
diff --git a/include/linux/nl802154.h b/include/linux/nl802154.h
index b7d9435..275fd94 100644
--- a/include/linux/nl802154.h
+++ b/include/linux/nl802154.h
@@ -65,6 +65,9 @@ enum {
IEEE802154_ATTR_SEC,
IEEE802154_ATTR_PAGE,
+ IEEE802154_ATTR_CHANNEL_PAGE_LIST,
+
+ IEEE802154_ATTR_PHY_NAME,
__IEEE802154_ATTR_MAX,
};
@@ -114,6 +117,7 @@ enum {
IEEE802154_RX_ENABLE_CONF, /* Not supported yet */
IEEE802154_LIST_IFACE,
+ IEEE802154_LIST_PHY,
__IEEE802154_CMD_MAX,
};
diff --git a/net/ieee802154/Makefile b/net/ieee802154/Makefile
index 69af9f6..ce2d335 100644
--- a/net/ieee802154/Makefile
+++ b/net/ieee802154/Makefile
@@ -1,5 +1,5 @@
obj-$(CONFIG_IEEE802154) += ieee802154.o af_802154.o
-ieee802154-y := netlink.o nl-mac.o nl_policy.o wpan-class.o
+ieee802154-y := netlink.o nl-mac.o nl-phy.o nl_policy.o wpan-class.o
af_802154-y := af_ieee802154.o raw.o dgram.o
ccflags-y += -Wall -DDEBUG
diff --git a/net/ieee802154/netlink.c b/net/ieee802154/netlink.c
index 5b738ec..8a22173 100644
--- a/net/ieee802154/netlink.c
+++ b/net/ieee802154/netlink.c
@@ -87,6 +87,10 @@ int __init ieee802154_nl_init(void)
if (rc)
goto fail;
+ rc = nl802154_phy_register();
+ if (rc)
+ goto fail;
+
return 0;
fail:
diff --git a/net/ieee802154/nl-phy.c b/net/ieee802154/nl-phy.c
new file mode 100644
index 0000000..b7af722
--- /dev/null
+++ b/net/ieee802154/nl-phy.c
@@ -0,0 +1,188 @@
+/*
+ * Netlink inteface for IEEE 802.15.4 stack
+ *
+ * Copyright 2007, 2008 Siemens AG
+ *
+ * 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.
+ *
+ * Written by:
+ * Sergey Lapin <slapin@ossfans.org>
+ * Dmitry Eremin-Solenikov <dbaryshkov@gmail.com>
+ * Maxim Osipov <maxim.osipov@siemens.com>
+ */
+
+#include <linux/kernel.h>
+#include <net/netlink.h>
+#include <net/genetlink.h>
+#include <net/wpan-phy.h>
+#include <linux/nl802154.h>
+
+#include "ieee802154.h"
+
+static int ieee802154_nl_fill_phy(struct sk_buff *msg, u32 pid,
+ u32 seq, int flags, struct wpan_phy *phy)
+{
+ void *hdr;
+ int i, pages = 0;
+ uint32_t *buf = kzalloc(32 * sizeof(uint32_t), GFP_KERNEL);
+
+ pr_debug("%s\n", __func__);
+
+ if (!buf)
+ goto out;
+
+ hdr = genlmsg_put(msg, 0, seq, &nl802154_family, flags,
+ IEEE802154_LIST_PHY);
+ if (!hdr)
+ goto out;
+
+ mutex_lock(&phy->pib_lock);
+ NLA_PUT_STRING(msg, IEEE802154_ATTR_PHY_NAME, wpan_phy_name(phy));
+
+ NLA_PUT_U8(msg, IEEE802154_ATTR_PAGE, phy->current_page);
+ NLA_PUT_U8(msg, IEEE802154_ATTR_CHANNEL, phy->current_channel);
+ for (i = 0; i < 32; i++) {
+ if (phy->channels_supported[i])
+ buf[pages++] = phy->channels_supported[i] | (i << 27);
+ }
+ if (pages)
+ NLA_PUT(msg, IEEE802154_ATTR_CHANNEL_PAGE_LIST,
+ pages * sizeof(uint32_t), buf);
+
+ mutex_unlock(&phy->pib_lock);
+ return genlmsg_end(msg, hdr);
+
+nla_put_failure:
+ mutex_unlock(&phy->pib_lock);
+ genlmsg_cancel(msg, hdr);
+out:
+ kfree(buf);
+ return -EMSGSIZE;
+}
+
+static int ieee802154_list_phy(struct sk_buff *skb,
+ struct genl_info *info)
+{
+ /* Request for interface name, index, type, IEEE address,
+ PAN Id, short address */
+ struct sk_buff *msg;
+ struct wpan_phy *phy;
+ const char *name;
+ int rc = -ENOBUFS;
+
+ pr_debug("%s\n", __func__);
+
+ if (!info->attrs[IEEE802154_ATTR_PHY_NAME])
+ return -EINVAL;
+
+ name = nla_data(info->attrs[IEEE802154_ATTR_PHY_NAME]);
+ if (name[nla_len(info->attrs[IEEE802154_ATTR_PHY_NAME]) - 1] != '\0')
+ return -EINVAL; /* phy name should be null-terminated */
+
+
+ phy = wpan_phy_find(name);
+ if (!phy)
+ return -ENODEV;
+
+ msg = nlmsg_new(NLMSG_GOODSIZE, GFP_KERNEL);
+ if (!msg)
+ goto out_dev;
+
+ rc = ieee802154_nl_fill_phy(msg, info->snd_pid, info->snd_seq,
+ 0, phy);
+ if (rc < 0)
+ goto out_free;
+
+ wpan_phy_put(phy);
+
+ return genlmsg_reply(msg, info);
+out_free:
+ nlmsg_free(msg);
+out_dev:
+ wpan_phy_put(phy);
+ return rc;
+
+}
+
+struct dump_phy_data {
+ struct sk_buff *skb;
+ struct netlink_callback *cb;
+ int idx, s_idx;
+};
+
+static int ieee802154_dump_phy_iter(struct wpan_phy *phy, void *_data)
+{
+ int rc;
+ struct dump_phy_data *data = _data;
+
+ pr_debug("%s\n", __func__);
+
+ if (data->idx++ < data->s_idx)
+ return 0;
+
+ rc = ieee802154_nl_fill_phy(data->skb,
+ NETLINK_CB(data->cb->skb).pid,
+ data->cb->nlh->nlmsg_seq,
+ NLM_F_MULTI,
+ phy);
+
+ if (rc < 0) {
+ data->idx--;
+ return rc;
+ }
+
+ return 0;
+}
+
+static int ieee802154_dump_phy(struct sk_buff *skb,
+ struct netlink_callback *cb)
+{
+ struct dump_phy_data data = {
+ .cb = cb,
+ .skb = skb,
+ .s_idx = cb->args[0],
+ .idx = 0,
+ };
+
+ pr_debug("%s\n", __func__);
+
+ wpan_phy_for_each(ieee802154_dump_phy_iter, &data);
+
+ cb->args[0] = data.idx;
+
+ return skb->len;
+}
+
+static struct genl_ops ieee802154_phy_ops[] = {
+ IEEE802154_DUMP(IEEE802154_LIST_PHY, ieee802154_list_phy,
+ ieee802154_dump_phy),
+};
+
+/*
+ * No need to unregister as family unregistration will do it.
+ */
+int nl802154_phy_register(void)
+{
+ int i;
+ int rc;
+
+ for (i = 0; i < ARRAY_SIZE(ieee802154_phy_ops); i++) {
+ rc = genl_register_ops(&nl802154_family,
+ &ieee802154_phy_ops[i]);
+ if (rc)
+ return rc;
+ }
+
+ return 0;
+}
diff --git a/net/ieee802154/nl_policy.c b/net/ieee802154/nl_policy.c
index 2363ebe..6adda4d 100644
--- a/net/ieee802154/nl_policy.c
+++ b/net/ieee802154/nl_policy.c
@@ -27,6 +27,7 @@
const struct nla_policy ieee802154_policy[IEEE802154_ATTR_MAX + 1] = {
[IEEE802154_ATTR_DEV_NAME] = { .type = NLA_STRING, },
[IEEE802154_ATTR_DEV_INDEX] = { .type = NLA_U32, },
+ [IEEE802154_ATTR_PHY_NAME] = { .type = NLA_STRING, },
[IEEE802154_ATTR_STATUS] = { .type = NLA_U8, },
[IEEE802154_ATTR_SHORT_ADDR] = { .type = NLA_U16, },
@@ -50,5 +51,6 @@ const struct nla_policy ieee802154_policy[IEEE802154_ATTR_MAX + 1] = {
[IEEE802154_ATTR_CHANNELS] = { .type = NLA_U32, },
[IEEE802154_ATTR_DURATION] = { .type = NLA_U8, },
[IEEE802154_ATTR_ED_LIST] = { .len = 27 },
+ [IEEE802154_ATTR_CHANNEL_PAGE_LIST] = { .len = 32 * 4, },
};
--
1.6.5
^ permalink raw reply related
* [PATCH 11/17] fakehard: no need to export net_to_phy, make it static
From: Dmitry Eremin-Solenikov @ 2009-11-06 12:39 UTC (permalink / raw)
To: David S. Miller; +Cc: netdev, Sergey Lapin
In-Reply-To: <1257511181-19403-1-git-send-email-dbaryshkov@gmail.com>
Signed-off-by: Dmitry Eremin-Solenikov <dbaryshkov@gmail.com>
---
drivers/ieee802154/fakehard.c | 2 +-
1 files changed, 1 insertions(+), 1 deletions(-)
diff --git a/drivers/ieee802154/fakehard.c b/drivers/ieee802154/fakehard.c
index 77fbb51..ccf83eb 100644
--- a/drivers/ieee802154/fakehard.c
+++ b/drivers/ieee802154/fakehard.c
@@ -32,7 +32,7 @@
#include <net/nl802154.h>
#include <net/wpan-phy.h>
-struct wpan_phy *net_to_phy(struct net_device *dev)
+static struct wpan_phy *net_to_phy(struct net_device *dev)
{
return container_of(dev->dev.parent, struct wpan_phy, dev);
}
--
1.6.5
^ permalink raw reply related
* [PATCH 12/17] fakehard: claim all 2.4 Ghz channels as supported
From: Dmitry Eremin-Solenikov @ 2009-11-06 12:39 UTC (permalink / raw)
To: David S. Miller; +Cc: netdev, Sergey Lapin
In-Reply-To: <1257511181-19403-1-git-send-email-dbaryshkov@gmail.com>
Make fakehard device claim all 2.4 Ghz channels from 802.15.4-2006,
802.15.4a-2007 as supported by the hw.
Signed-off-by: Dmitry Eremin-Solenikov <dbaryshkov@gmail.com>
---
drivers/ieee802154/fakehard.c | 10 +++++++++-
1 files changed, 9 insertions(+), 1 deletions(-)
diff --git a/drivers/ieee802154/fakehard.c b/drivers/ieee802154/fakehard.c
index ccf83eb..70a9f9c 100644
--- a/drivers/ieee802154/fakehard.c
+++ b/drivers/ieee802154/fakehard.c
@@ -356,7 +356,15 @@ static int __devinit ieee802154fake_probe(struct platform_device *pdev)
dev->addr_len);
memcpy(dev->perm_addr, dev->dev_addr, dev->addr_len);
- phy->channels_supported[0] = (1 << 27) - 1;
+ /*
+ * For now we'd like to emulate 2.4 GHz-only device,
+ * both O-QPSK and CSS
+ */
+ /* 2.4 GHz O-QPSK 802.15.4-2003 */
+ phy->channels_supported[0] |= 0x7FFF800;
+ /* 2.4 GHz CSS 802.15.4a-2007 */
+ phy->channels_supported[3] |= 0x3fff;
+
phy->transmit_power = 0xbf;
dev->netdev_ops = &fake_ops;
--
1.6.5
^ permalink raw reply related
* [PATCH 13/17] ieee802154: add an mlme_ops call to retrieve PHY object
From: Dmitry Eremin-Solenikov @ 2009-11-06 12:39 UTC (permalink / raw)
To: David S. Miller; +Cc: netdev, Sergey Lapin
In-Reply-To: <1257511181-19403-1-git-send-email-dbaryshkov@gmail.com>
ops->get_phy should increment reference to wpan-phy. As we return
the external structure, we should do refcounting correctly.
Signed-off-by: Dmitry Eremin-Solenikov <dbaryshkov@gmail.com>
---
include/net/ieee802154_netdev.h | 6 ++++++
include/net/wpan-phy.h | 2 ++
2 files changed, 8 insertions(+), 0 deletions(-)
diff --git a/include/net/ieee802154_netdev.h b/include/net/ieee802154_netdev.h
index d23fb5a..5743055 100644
--- a/include/net/ieee802154_netdev.h
+++ b/include/net/ieee802154_netdev.h
@@ -74,8 +74,12 @@ static inline int mac_cb_type(struct sk_buff *skb)
#define IEEE802154_MAC_SCAN_PASSIVE 2
#define IEEE802154_MAC_SCAN_ORPHAN 3
+struct wpan_phy;
/*
* This should be located at net_device->ml_priv
+ *
+ * get_phy should increment the reference counting on returned phy.
+ * Use wpan_wpy_put to put that reference.
*/
struct ieee802154_mlme_ops {
int (*assoc_req)(struct net_device *dev,
@@ -94,6 +98,8 @@ struct ieee802154_mlme_ops {
int (*scan_req)(struct net_device *dev,
u8 type, u32 channels, u8 page, u8 duration);
+ struct wpan_phy *(*get_phy)(const struct net_device *dev);
+
/*
* FIXME: these should become the part of PIB/MIB interface.
* However we still don't have IB interface of any kind
diff --git a/include/net/wpan-phy.h b/include/net/wpan-phy.h
index f63537c..a65e985 100644
--- a/include/net/wpan-phy.h
+++ b/include/net/wpan-phy.h
@@ -44,6 +44,8 @@ struct wpan_phy {
char priv[0] __attribute__((__aligned__(NETDEV_ALIGN)));
};
+#define to_phy(_dev) container_of(_dev, struct wpan_phy, dev)
+
struct wpan_phy *wpan_phy_alloc(size_t priv_size);
static inline void wpan_phy_set_dev(struct wpan_phy *phy, struct device *dev)
{
--
1.6.5
^ permalink raw reply related
* [PATCH 14/17] fakehard: mlme_ops->get_phy implementation
From: Dmitry Eremin-Solenikov @ 2009-11-06 12:39 UTC (permalink / raw)
To: David S. Miller; +Cc: netdev, Sergey Lapin
In-Reply-To: <1257511181-19403-1-git-send-email-dbaryshkov@gmail.com>
Signed-off-by: Dmitry Eremin-Solenikov <dbaryshkov@gmail.com>
---
drivers/ieee802154/fakehard.c | 38 ++++++++++++++++++++++++++++++++------
1 files changed, 32 insertions(+), 6 deletions(-)
diff --git a/drivers/ieee802154/fakehard.c b/drivers/ieee802154/fakehard.c
index 70a9f9c..f877f13 100644
--- a/drivers/ieee802154/fakehard.c
+++ b/drivers/ieee802154/fakehard.c
@@ -32,9 +32,29 @@
#include <net/nl802154.h>
#include <net/wpan-phy.h>
-static struct wpan_phy *net_to_phy(struct net_device *dev)
+struct fakehard_priv {
+ struct wpan_phy *phy;
+};
+
+static struct wpan_phy *fake_to_phy(const struct net_device *dev)
+{
+ struct fakehard_priv *priv = netdev_priv(dev);
+ return priv->phy;
+}
+
+/**
+ * fake_get_phy - Return a phy corresponding to this device.
+ * @dev: The network device for which to return the wan-phy object
+ *
+ * This function returns a wpan-phy object corresponding to the passed
+ * network device. Reference counter for wpan-phy object is incremented,
+ * so when the wpan-phy isn't necessary, you should drop the reference
+ * via @wpan_phy_put() call.
+ */
+static struct wpan_phy *fake_get_phy(const struct net_device *dev)
{
- return container_of(dev->dev.parent, struct wpan_phy, dev);
+ struct wpan_phy *phy = fake_to_phy(dev);
+ return to_phy(get_device(&phy->dev));
}
/**
@@ -121,7 +141,7 @@ static u8 fake_get_bsn(const struct net_device *dev)
static int fake_assoc_req(struct net_device *dev,
struct ieee802154_addr *addr, u8 channel, u8 page, u8 cap)
{
- struct wpan_phy *phy = net_to_phy(dev);
+ struct wpan_phy *phy = fake_to_phy(dev);
mutex_lock(&phy->pib_lock);
phy->current_channel = channel;
@@ -196,7 +216,7 @@ static int fake_start_req(struct net_device *dev, struct ieee802154_addr *addr,
u8 bcn_ord, u8 sf_ord, u8 pan_coord, u8 blx,
u8 coord_realign)
{
- struct wpan_phy *phy = net_to_phy(dev);
+ struct wpan_phy *phy = fake_to_phy(dev);
mutex_lock(&phy->pib_lock);
phy->current_channel = channel;
@@ -239,6 +259,8 @@ static struct ieee802154_mlme_ops fake_mlme = {
.start_req = fake_start_req,
.scan_req = fake_scan_req,
+ .get_phy = fake_get_phy,
+
.get_pan_id = fake_get_pan_id,
.get_short_addr = fake_get_short_addr,
.get_dsn = fake_get_dsn,
@@ -313,7 +335,7 @@ static const struct net_device_ops fake_ops = {
static void ieee802154_fake_destruct(struct net_device *dev)
{
- struct wpan_phy *phy = net_to_phy(dev);
+ struct wpan_phy *phy = fake_to_phy(dev);
wpan_phy_unregister(phy);
free_netdev(dev);
@@ -338,13 +360,14 @@ static void ieee802154_fake_setup(struct net_device *dev)
static int __devinit ieee802154fake_probe(struct platform_device *pdev)
{
struct net_device *dev;
+ struct fakehard_priv *priv;
struct wpan_phy *phy = wpan_phy_alloc(0);
int err;
if (!phy)
return -ENOMEM;
- dev = alloc_netdev(0, "hardwpan%d", ieee802154_fake_setup);
+ dev = alloc_netdev(sizeof(struct fakehard_priv), "hardwpan%d", ieee802154_fake_setup);
if (!dev) {
wpan_phy_free(phy);
return -ENOMEM;
@@ -370,6 +393,9 @@ static int __devinit ieee802154fake_probe(struct platform_device *pdev)
dev->netdev_ops = &fake_ops;
dev->ml_priv = &fake_mlme;
+ priv = netdev_priv(dev);
+ priv->phy = phy;
+
/*
* If the name is a format string the caller wants us to do a
* name allocation.
--
1.6.5
^ permalink raw reply related
* [PATCH 15/17] ieee802154: add two nl802154 helpers
From: Dmitry Eremin-Solenikov @ 2009-11-06 12:39 UTC (permalink / raw)
To: David S. Miller; +Cc: netdev, Sergey Lapin
In-Reply-To: <1257511181-19403-1-git-send-email-dbaryshkov@gmail.com>
Add two nl802154 helpers: one for starting a reply message, one for sending.
Signed-off-by: Dmitry Eremin-Solenikov <dbaryshkov@gmail.com>
---
net/ieee802154/ieee802154.h | 5 +++++
net/ieee802154/netlink.c | 33 +++++++++++++++++++++++++++++++++
2 files changed, 38 insertions(+), 0 deletions(-)
diff --git a/net/ieee802154/ieee802154.h b/net/ieee802154/ieee802154.h
index 0790eb0..aadec42 100644
--- a/net/ieee802154/ieee802154.h
+++ b/net/ieee802154/ieee802154.h
@@ -38,8 +38,13 @@ void __exit ieee802154_nl_exit(void);
.dumpit = _dump, \
}
+struct genl_info;
+
struct sk_buff *ieee802154_nl_create(int flags, u8 req);
int ieee802154_nl_mcast(struct sk_buff *msg, unsigned int group);
+struct sk_buff *ieee802154_nl_new_reply(struct genl_info *info,
+ int flags, u8 req);
+int ieee802154_nl_reply(struct sk_buff *msg, struct genl_info *info);
extern struct genl_family nl802154_family;
int nl802154_mac_register(void);
diff --git a/net/ieee802154/netlink.c b/net/ieee802154/netlink.c
index 8a22173..33137b9 100644
--- a/net/ieee802154/netlink.c
+++ b/net/ieee802154/netlink.c
@@ -75,6 +75,39 @@ out:
return -ENOBUFS;
}
+struct sk_buff *ieee802154_nl_new_reply(struct genl_info *info,
+ int flags, u8 req)
+{
+ void *hdr;
+ struct sk_buff *msg = nlmsg_new(NLMSG_GOODSIZE, GFP_ATOMIC);
+
+ if (!msg)
+ return NULL;
+
+ hdr = genlmsg_put_reply(msg, info,
+ &nl802154_family, flags, req);
+ if (!hdr) {
+ nlmsg_free(msg);
+ return NULL;
+ }
+
+ return msg;
+}
+
+int ieee802154_nl_reply(struct sk_buff *msg, struct genl_info *info)
+{
+ /* XXX: nlh is right at the start of msg */
+ void *hdr = genlmsg_data(NLMSG_DATA(msg->data));
+
+ if (genlmsg_end(msg, hdr) < 0)
+ goto out;
+
+ return genlmsg_reply(msg, info);
+out:
+ nlmsg_free(msg);
+ return -ENOBUFS;
+}
+
int __init ieee802154_nl_init(void)
{
int rc;
--
1.6.5
^ permalink raw reply related
* [PATCH 16/17] ieee802154: add PHY_NAME to LIST_IFACE command results
From: Dmitry Eremin-Solenikov @ 2009-11-06 12:39 UTC (permalink / raw)
To: David S. Miller; +Cc: netdev, Sergey Lapin
In-Reply-To: <1257511181-19403-1-git-send-email-dbaryshkov@gmail.com>
Signed-off-by: Dmitry Eremin-Solenikov <dbaryshkov@gmail.com>
---
net/ieee802154/nl-mac.c | 8 ++++++++
1 files changed, 8 insertions(+), 0 deletions(-)
diff --git a/net/ieee802154/nl-mac.c b/net/ieee802154/nl-mac.c
index e8816bf..135c167 100644
--- a/net/ieee802154/nl-mac.c
+++ b/net/ieee802154/nl-mac.c
@@ -33,6 +33,7 @@
#include <net/nl802154.h>
#include <net/ieee802154.h>
#include <net/ieee802154_netdev.h>
+#include <net/wpan-phy.h>
#include "ieee802154.h"
@@ -251,6 +252,7 @@ static int ieee802154_nl_fill_iface(struct sk_buff *msg, u32 pid,
u32 seq, int flags, struct net_device *dev)
{
void *hdr;
+ struct wpan_phy *phy;
pr_debug("%s\n", __func__);
@@ -259,7 +261,11 @@ static int ieee802154_nl_fill_iface(struct sk_buff *msg, u32 pid,
if (!hdr)
goto out;
+ phy = ieee802154_mlme_ops(dev)->get_phy(dev);
+ BUG_ON(!phy);
+
NLA_PUT_STRING(msg, IEEE802154_ATTR_DEV_NAME, dev->name);
+ NLA_PUT_STRING(msg, IEEE802154_ATTR_PHY_NAME, wpan_phy_name(phy));
NLA_PUT_U32(msg, IEEE802154_ATTR_DEV_INDEX, dev->ifindex);
NLA_PUT(msg, IEEE802154_ATTR_HW_ADDR, IEEE802154_ADDR_LEN,
@@ -268,9 +274,11 @@ static int ieee802154_nl_fill_iface(struct sk_buff *msg, u32 pid,
ieee802154_mlme_ops(dev)->get_short_addr(dev));
NLA_PUT_U16(msg, IEEE802154_ATTR_PAN_ID,
ieee802154_mlme_ops(dev)->get_pan_id(dev));
+ wpan_phy_put(phy);
return genlmsg_end(msg, hdr);
nla_put_failure:
+ wpan_phy_put(phy);
genlmsg_cancel(msg, hdr);
out:
return -EMSGSIZE;
--
1.6.5
^ permalink raw reply related
* [PATCH 17/17] ieee802154: add support for creation/removal of logic interfaces
From: Dmitry Eremin-Solenikov @ 2009-11-06 12:39 UTC (permalink / raw)
To: David S. Miller; +Cc: netdev, Sergey Lapin
In-Reply-To: <1257511181-19403-1-git-send-email-dbaryshkov@gmail.com>
Add support for two more NL802154 commands: ADD_IFACE and DEL_IFACE,
thus allowing creation and removal of logic WPAN interfaces on the top
of wpan-phy.
Signed-off-by: Dmitry Eremin-Solenikov <dbaryshkov@gmail.com>
---
include/linux/nl802154.h | 2 +
include/net/wpan-phy.h | 4 +
net/ieee802154/nl-phy.c | 156 ++++++++++++++++++++++++++++++++++++++++++++++
3 files changed, 162 insertions(+), 0 deletions(-)
diff --git a/include/linux/nl802154.h b/include/linux/nl802154.h
index 275fd94..33d9f51 100644
--- a/include/linux/nl802154.h
+++ b/include/linux/nl802154.h
@@ -118,6 +118,8 @@ enum {
IEEE802154_LIST_IFACE,
IEEE802154_LIST_PHY,
+ IEEE802154_ADD_IFACE,
+ IEEE802154_DEL_IFACE,
__IEEE802154_CMD_MAX,
};
diff --git a/include/net/wpan-phy.h b/include/net/wpan-phy.h
index a65e985..8592623 100644
--- a/include/net/wpan-phy.h
+++ b/include/net/wpan-phy.h
@@ -41,6 +41,10 @@ struct wpan_phy {
struct device dev;
int idx;
+ struct net_device *(*add_iface)(struct wpan_phy *phy,
+ const char *name);
+ void (*del_iface)(struct wpan_phy *phy, struct net_device *dev);
+
char priv[0] __attribute__((__aligned__(NETDEV_ALIGN)));
};
diff --git a/net/ieee802154/nl-phy.c b/net/ieee802154/nl-phy.c
index b7af722..199a2d9 100644
--- a/net/ieee802154/nl-phy.c
+++ b/net/ieee802154/nl-phy.c
@@ -26,6 +26,9 @@
#include <net/netlink.h>
#include <net/genetlink.h>
#include <net/wpan-phy.h>
+#include <net/af_ieee802154.h>
+#include <net/ieee802154_netdev.h>
+#include <net/rtnetlink.h> /* for rtnl_{un,}lock */
#include <linux/nl802154.h>
#include "ieee802154.h"
@@ -164,9 +167,162 @@ static int ieee802154_dump_phy(struct sk_buff *skb,
return skb->len;
}
+static int ieee802154_add_iface(struct sk_buff *skb,
+ struct genl_info *info)
+{
+ struct sk_buff *msg;
+ struct wpan_phy *phy;
+ const char *name;
+ const char *devname;
+ int rc = -ENOBUFS;
+ struct net_device *dev;
+
+ pr_debug("%s\n", __func__);
+
+ if (!info->attrs[IEEE802154_ATTR_PHY_NAME])
+ return -EINVAL;
+
+ name = nla_data(info->attrs[IEEE802154_ATTR_PHY_NAME]);
+ if (name[nla_len(info->attrs[IEEE802154_ATTR_PHY_NAME]) - 1] != '\0')
+ return -EINVAL; /* phy name should be null-terminated */
+
+ if (info->attrs[IEEE802154_ATTR_DEV_NAME]) {
+ devname = nla_data(info->attrs[IEEE802154_ATTR_DEV_NAME]);
+ if (devname[nla_len(info->attrs[IEEE802154_ATTR_DEV_NAME]) - 1]
+ != '\0')
+ return -EINVAL; /* phy name should be null-terminated */
+ } else {
+ devname = "wpan%d";
+ }
+
+ if (strlen(devname) >= IFNAMSIZ)
+ return -ENAMETOOLONG;
+
+ phy = wpan_phy_find(name);
+ if (!phy)
+ return -ENODEV;
+
+ msg = ieee802154_nl_new_reply(info, 0, IEEE802154_ADD_IFACE);
+ if (!msg)
+ goto out_dev;
+
+ if (!phy->add_iface) {
+ rc = -EINVAL;
+ goto nla_put_failure;
+ }
+
+ dev = phy->add_iface(phy, devname);
+ if (IS_ERR(dev)) {
+ rc = PTR_ERR(dev);
+ goto nla_put_failure;
+ }
+
+ NLA_PUT_STRING(msg, IEEE802154_ATTR_PHY_NAME, wpan_phy_name(phy));
+ NLA_PUT_STRING(msg, IEEE802154_ATTR_DEV_NAME, dev->name);
+
+ dev_put(dev);
+
+ wpan_phy_put(phy);
+
+ return ieee802154_nl_reply(msg, info);
+
+nla_put_failure:
+ nlmsg_free(msg);
+out_dev:
+ wpan_phy_put(phy);
+ return rc;
+}
+
+static int ieee802154_del_iface(struct sk_buff *skb,
+ struct genl_info *info)
+{
+ struct sk_buff *msg;
+ struct wpan_phy *phy;
+ const char *name;
+ int rc;
+ struct net_device *dev;
+
+ pr_debug("%s\n", __func__);
+
+ if (!info->attrs[IEEE802154_ATTR_DEV_NAME])
+ return -EINVAL;
+
+ name = nla_data(info->attrs[IEEE802154_ATTR_DEV_NAME]);
+ if (name[nla_len(info->attrs[IEEE802154_ATTR_DEV_NAME]) - 1] != '\0')
+ return -EINVAL; /* name should be null-terminated */
+
+ dev = dev_get_by_name(genl_info_net(info), name);
+ if (!dev)
+ return -ENODEV;
+
+ phy = ieee802154_mlme_ops(dev)->get_phy(dev);
+ BUG_ON(!phy);
+
+ rc = -EINVAL;
+ /* phy name is optional, but should be checked if it's given */
+ if (info->attrs[IEEE802154_ATTR_PHY_NAME]) {
+ struct wpan_phy *phy2;
+
+ const char *pname =
+ nla_data(info->attrs[IEEE802154_ATTR_PHY_NAME]);
+ if (pname[nla_len(info->attrs[IEEE802154_ATTR_PHY_NAME]) - 1]
+ != '\0')
+ /* name should be null-terminated */
+ goto out_dev;
+
+ phy2 = wpan_phy_find(pname);
+ if (!phy2)
+ goto out_dev;
+
+ if (phy != phy2) {
+ wpan_phy_put(phy2);
+ goto out_dev;
+ }
+ }
+
+ rc = -ENOBUFS;
+
+ msg = ieee802154_nl_new_reply(info, 0, IEEE802154_DEL_IFACE);
+ if (!msg)
+ goto out_dev;
+
+ if (!phy->del_iface) {
+ rc = -EINVAL;
+ goto nla_put_failure;
+ }
+
+ rtnl_lock();
+ phy->del_iface(phy, dev);
+
+ /* We don't have device anymore */
+ dev_put(dev);
+ dev = NULL;
+
+ rtnl_unlock();
+
+
+ NLA_PUT_STRING(msg, IEEE802154_ATTR_PHY_NAME, wpan_phy_name(phy));
+ NLA_PUT_STRING(msg, IEEE802154_ATTR_DEV_NAME, name);
+
+ wpan_phy_put(phy);
+
+ return ieee802154_nl_reply(msg, info);
+
+nla_put_failure:
+ nlmsg_free(msg);
+out_dev:
+ wpan_phy_put(phy);
+ if (dev)
+ dev_put(dev);
+
+ return rc;
+}
+
static struct genl_ops ieee802154_phy_ops[] = {
IEEE802154_DUMP(IEEE802154_LIST_PHY, ieee802154_list_phy,
ieee802154_dump_phy),
+ IEEE802154_OP(IEEE802154_ADD_IFACE, ieee802154_add_iface),
+ IEEE802154_OP(IEEE802154_DEL_IFACE, ieee802154_del_iface),
};
/*
--
1.6.5
^ permalink raw reply related
* Re: [PATCH 2.6.33/1 00/12] WiMAX patches for 2.6.33 (batch #1)
From: David Miller @ 2009-11-06 13:23 UTC (permalink / raw)
To: inaky; +Cc: netdev, wimax
In-Reply-To: <1257445051.3263.12.camel@localhost.localdomain>
From: Inaky Perez-Gonzalez <inaky@linux.intel.com>
Date: Thu, 05 Nov 2009 10:17:31 -0800
> So this pull should be against:
>
> REPO git://git.kernel.org/pub/scm/linux/kernel/git/inaky/wimax.git
> BRANCH linux-2.6.33.y
This looks a lot better, pulled and pushed back out to net-next-2.6
Thanks.
^ permalink raw reply
* [PATCH net-next] Phonet: use rwlock for sockets list
From: Rémi Denis-Courmont @ 2009-11-06 13:41 UTC (permalink / raw)
To: netdev; +Cc: Rémi Denis-Courmont
From: Rémi Denis-Courmont <remi.denis-courmont@nokia.com>
Signed-off-by: Rémi Denis-Courmont <remi.denis-courmont@nokia.com>
---
net/phonet/socket.c | 24 ++++++++++++------------
1 files changed, 12 insertions(+), 12 deletions(-)
diff --git a/net/phonet/socket.c b/net/phonet/socket.c
index 0412beb..ecb5f20 100644
--- a/net/phonet/socket.c
+++ b/net/phonet/socket.c
@@ -47,10 +47,10 @@ static int pn_socket_release(struct socket *sock)
static struct {
struct hlist_head hlist;
- spinlock_t lock;
+ rwlock_t lock;
} pnsocks = {
.hlist = HLIST_HEAD_INIT,
- .lock = __SPIN_LOCK_UNLOCKED(pnsocks.lock),
+ .lock = __RW_LOCK_UNLOCKED(pnsocks.lock),
};
/*
@@ -65,7 +65,7 @@ struct sock *pn_find_sock_by_sa(struct net *net, const struct sockaddr_pn *spn)
u16 obj = pn_sockaddr_get_object(spn);
u8 res = spn->spn_resource;
- spin_lock_bh(&pnsocks.lock);
+ read_lock_bh(&pnsocks.lock);
sk_for_each(sknode, node, &pnsocks.hlist) {
struct pn_sock *pn = pn_sk(sknode);
@@ -91,7 +91,7 @@ struct sock *pn_find_sock_by_sa(struct net *net, const struct sockaddr_pn *spn)
break;
}
- spin_unlock_bh(&pnsocks.lock);
+ read_unlock_bh(&pnsocks.lock);
return rval;
}
@@ -102,7 +102,7 @@ void pn_deliver_sock_broadcast(struct net *net, struct sk_buff *skb)
struct hlist_node *node;
struct sock *sknode;
- spin_lock(&pnsocks.lock);
+ read_lock(&pnsocks.lock);
sk_for_each(sknode, node, &pnsocks.hlist) {
struct sk_buff *clone;
@@ -117,22 +117,22 @@ void pn_deliver_sock_broadcast(struct net *net, struct sk_buff *skb)
sk_receive_skb(sknode, clone, 0);
}
}
- spin_unlock(&pnsocks.lock);
+ read_unlock(&pnsocks.lock);
}
void pn_sock_hash(struct sock *sk)
{
- spin_lock_bh(&pnsocks.lock);
+ write_lock_bh(&pnsocks.lock);
sk_add_node(sk, &pnsocks.hlist);
- spin_unlock_bh(&pnsocks.lock);
+ write_unlock_bh(&pnsocks.lock);
}
EXPORT_SYMBOL(pn_sock_hash);
void pn_sock_unhash(struct sock *sk)
{
- spin_lock_bh(&pnsocks.lock);
+ write_lock_bh(&pnsocks.lock);
sk_del_node_init(sk);
- spin_unlock_bh(&pnsocks.lock);
+ write_unlock_bh(&pnsocks.lock);
}
EXPORT_SYMBOL(pn_sock_unhash);
@@ -466,7 +466,7 @@ static struct sock *pn_sock_get_next(struct seq_file *seq, struct sock *sk)
static void *pn_sock_seq_start(struct seq_file *seq, loff_t *pos)
__acquires(pnsocks.lock)
{
- spin_lock_bh(&pnsocks.lock);
+ read_lock_bh(&pnsocks.lock);
return *pos ? pn_sock_get_idx(seq, *pos - 1) : SEQ_START_TOKEN;
}
@@ -485,7 +485,7 @@ static void *pn_sock_seq_next(struct seq_file *seq, void *v, loff_t *pos)
static void pn_sock_seq_stop(struct seq_file *seq, void *v)
__releases(pnsocks.lock)
{
- spin_unlock_bh(&pnsocks.lock);
+ read_unlock_bh(&pnsocks.lock);
}
static int pn_sock_seq_show(struct seq_file *seq, void *v)
--
1.6.3.3
^ permalink raw reply related
* Re: [PATCH net-next] Phonet: use rwlock for sockets list
From: Eric Dumazet @ 2009-11-06 13:44 UTC (permalink / raw)
To: Rémi Denis-Courmont; +Cc: netdev, Rémi Denis-Courmont
In-Reply-To: <1257514891-18917-1-git-send-email-remi@remlab.net>
Rémi Denis-Courmont a écrit :
> From: Rémi Denis-Courmont <remi.denis-courmont@nokia.com>
>
> Signed-off-by: Rémi Denis-Courmont <remi.denis-courmont@nokia.com>
> ---
> net/phonet/socket.c | 24 ++++++++++++------------
> 1 files changed, 12 insertions(+), 12 deletions(-)
Hmm... rwlocks are bad...
Would you care to explain why you introduce a rwlock ?
Thanks
^ permalink raw reply
page: next (older) | prev (newer) | latest
- recent:[subjects (threaded)|topics (new)|topics (active)]
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox