]> git.ipfire.org Git - thirdparty/iw.git/commitdiff
add (optional) hwsim code
authorJohannes Berg <johannes.berg@intel.com>
Fri, 6 Jul 2012 06:50:00 +0000 (08:50 +0200)
committerJohannes Berg <johannes.berg@intel.com>
Fri, 6 Jul 2012 06:50:47 +0000 (08:50 +0200)
As an example, the hwsim code was useful, but for normal
distros it's not. Allow developers to build hwsim code
into the iw binary with "make HWSIM=y".

Makefile
hwsim.c [new file with mode: 0644]

index ac238be17097690f7221e34a7da9be7013af7077..9cf8a8e92392c79a2a898c90c9dee0df636f14bc 100644 (file)
--- a/Makefile
+++ b/Makefile
@@ -20,6 +20,9 @@ OBJS = iw.o genl.o event.o info.o phy.o \
        reason.o status.o connect.o link.o offch.o ps.o cqm.o \
        bitrate.o wowlan.o roc.o
 OBJS += sections.o
+
+OBJS-$(HWSIM) += hwsim.o
+
 ALL = iw
 
 NL3xFOUND := $(shell $(PKG_CONFIG) --atleast-version=3.2 libnl-3.0 && echo Y)
@@ -85,7 +88,7 @@ endif
 
 all: $(ALL)
 
-VERSION_OBJS := $(filter-out version.o, $(OBJS))
+VERSION_OBJS := $(filter-out version.o, $(OBJS) $(OBJS-y))
 
 version.c: version.sh $(patsubst %.o,%.c,$(VERSION_OBJS)) nl80211.h iw.h Makefile \
                $(wildcard .git/index .git/refs/tags)
@@ -96,9 +99,9 @@ version.c: version.sh $(patsubst %.o,%.c,$(VERSION_OBJS)) nl80211.h iw.h Makefil
        @$(NQ) ' CC  ' $@
        $(Q)$(CC) $(CFLAGS) -c -o $@ $<
 
-iw:    $(OBJS)
+iw:    $(OBJS) $(OBJS-y)
        @$(NQ) ' CC  ' iw
-       $(Q)$(CC) $(LDFLAGS) $(OBJS) $(LIBS) -o iw
+       $(Q)$(CC) $(LDFLAGS) $(OBJS) $(OBJS-y) $(LIBS) -o iw
 
 check:
        $(Q)$(MAKE) all CC="REAL_CC=$(CC) CHECK=\"sparse -Wall\" cgcc"
diff --git a/hwsim.c b/hwsim.c
new file mode 100644 (file)
index 0000000..188c1cb
--- /dev/null
+++ b/hwsim.c
@@ -0,0 +1,147 @@
+#include <net/if.h>
+#include <errno.h>
+#include <string.h>
+
+#include <netlink/genl/genl.h>
+#include <netlink/genl/family.h>
+#include <netlink/genl/ctrl.h>
+#include <netlink/msg.h>
+#include <netlink/attr.h>
+
+#include "nl80211.h"
+#include "iw.h"
+
+/* These enums need to be kept in sync with the kernel */
+enum hwsim_testmode_attr {
+       __HWSIM_TM_ATTR_INVALID = 0,
+       HWSIM_TM_ATTR_CMD       = 1,
+       HWSIM_TM_ATTR_PS        = 2,
+
+       /* keep last */
+       __HWSIM_TM_ATTR_AFTER_LAST,
+       HWSIM_TM_ATTR_MAX       = __HWSIM_TM_ATTR_AFTER_LAST - 1
+};
+
+enum hwsim_testmode_cmd {
+       HWSIM_TM_CMD_SET_PS             = 0,
+       HWSIM_TM_CMD_GET_PS             = 1,
+       HWSIM_TM_CMD_STOP_QUEUES        = 2,
+       HWSIM_TM_CMD_WAKE_QUEUES        = 3,
+};
+
+
+SECTION(hwsim);
+
+static int print_hwsim_ps_handler(struct nl_msg *msg, void *arg)
+{
+       struct nlattr *attrs[NL80211_ATTR_MAX + 1];
+       struct nlattr *tb[HWSIM_TM_ATTR_MAX + 1];
+       struct genlmsghdr *gnlh = nlmsg_data(nlmsg_hdr(msg));
+
+       nla_parse(attrs, NL80211_ATTR_MAX, genlmsg_attrdata(gnlh, 0),
+                 genlmsg_attrlen(gnlh, 0), NULL);
+
+       if (!attrs[NL80211_ATTR_TESTDATA])
+               return NL_SKIP;
+
+       nla_parse(tb, HWSIM_TM_ATTR_MAX, nla_data(attrs[NL80211_ATTR_TESTDATA]),
+                 nla_len(attrs[NL80211_ATTR_TESTDATA]), NULL);
+
+       printf("HWSIM PS: %d\n", nla_get_u32(tb[HWSIM_TM_ATTR_PS]));
+
+       return NL_SKIP;
+}
+
+static int handle_hwsim_getps(struct nl80211_state *state, struct nl_cb *cb,
+                             struct nl_msg *msg, int argc, char **argv)
+{
+       struct nlattr *tmdata;
+
+       tmdata = nla_nest_start(msg, NL80211_ATTR_TESTDATA);
+       if (!tmdata)
+               goto nla_put_failure;
+
+       NLA_PUT_U32(msg, HWSIM_TM_ATTR_CMD, HWSIM_TM_CMD_GET_PS);
+
+       nla_nest_end(msg, tmdata);
+
+       nl_cb_set(cb, NL_CB_VALID, NL_CB_CUSTOM,
+                 print_hwsim_ps_handler, NULL);
+       return 0;
+ nla_put_failure:
+       return -ENOBUFS;
+}
+COMMAND(hwsim, getps, "", NL80211_CMD_TESTMODE, 0, CIB_PHY, handle_hwsim_getps, "");
+
+static int handle_hwsim_setps(struct nl80211_state *state, struct nl_cb *cb,
+                             struct nl_msg *msg, int argc, char **argv)
+{
+       struct nlattr *tmdata;
+       __u32 ps;
+       char *end;
+
+       if (argc != 1)
+               return 1;
+
+       ps = strtoul(argv[0], &end, 0);
+       if (*end)
+               return 1;
+
+       tmdata = nla_nest_start(msg, NL80211_ATTR_TESTDATA);
+       if (!tmdata)
+               goto nla_put_failure;
+
+       NLA_PUT_U32(msg, HWSIM_TM_ATTR_CMD, HWSIM_TM_CMD_SET_PS);
+       NLA_PUT_U32(msg, HWSIM_TM_ATTR_PS, ps);
+
+       nla_nest_end(msg, tmdata);
+
+       nl_cb_set(cb, NL_CB_VALID, NL_CB_CUSTOM,
+                 print_hwsim_ps_handler, NULL);
+       return 0;
+ nla_put_failure:
+       return -ENOBUFS;
+}
+COMMAND(hwsim, setps, "<value>", NL80211_CMD_TESTMODE, 0, CIB_PHY, handle_hwsim_setps, "");
+
+static int handle_hwsim_stop_queues(struct nl80211_state *state, struct nl_cb *cb,
+                                   struct nl_msg *msg, int argc, char **argv)
+{
+       struct nlattr *tmdata;
+
+       if (argc != 0)
+               return 1;
+
+       tmdata = nla_nest_start(msg, NL80211_ATTR_TESTDATA);
+       if (!tmdata)
+               goto nla_put_failure;
+
+       NLA_PUT_U32(msg, HWSIM_TM_ATTR_CMD, HWSIM_TM_CMD_STOP_QUEUES);
+
+       nla_nest_end(msg, tmdata);
+       return 0;
+ nla_put_failure:
+       return -ENOBUFS;
+}
+COMMAND(hwsim, stopqueues, "", NL80211_CMD_TESTMODE, 0, CIB_PHY, handle_hwsim_stop_queues, "");
+
+static int handle_hwsim_wake_queues(struct nl80211_state *state, struct nl_cb *cb,
+                                   struct nl_msg *msg, int argc, char **argv)
+{
+       struct nlattr *tmdata;
+
+       if (argc != 0)
+               return 1;
+
+       tmdata = nla_nest_start(msg, NL80211_ATTR_TESTDATA);
+       if (!tmdata)
+               goto nla_put_failure;
+
+       NLA_PUT_U32(msg, HWSIM_TM_ATTR_CMD, HWSIM_TM_CMD_WAKE_QUEUES);
+
+       nla_nest_end(msg, tmdata);
+       return 0;
+ nla_put_failure:
+       return -ENOBUFS;
+}
+COMMAND(hwsim, wakequeues, "", NL80211_CMD_TESTMODE, 0, CIB_PHY, handle_hwsim_wake_queues, "");