Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 158876
b: refs/heads/master
c: aff89a9
h: refs/heads/master
v: v3
  • Loading branch information
Johannes Berg authored and John W. Linville committed Jul 10, 2009
1 parent 0c993b1 commit 4d204a2
Show file tree
Hide file tree
Showing 9 changed files with 336 additions and 1 deletion.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: 5121ea0481f9cea1dfd958f18d7b4ac78778cd40
refs/heads/master: aff89a9b9084931e51b89d8f3ee3c547bea6c422
68 changes: 68 additions & 0 deletions trunk/drivers/net/wireless/mac80211_hwsim.c
Original file line number Diff line number Diff line change
Expand Up @@ -700,6 +700,73 @@ static int mac80211_hwsim_conf_tx(
return 0;
}

#ifdef CONFIG_NL80211_TESTMODE
/*
* This section contains example code for using netlink
* attributes with the testmode command in nl80211.
*/

/* These enums need to be kept in sync with userspace */
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,
};

static const struct nla_policy hwsim_testmode_policy[HWSIM_TM_ATTR_MAX + 1] = {
[HWSIM_TM_ATTR_CMD] = { .type = NLA_U32 },
[HWSIM_TM_ATTR_PS] = { .type = NLA_U32 },
};

static int hwsim_fops_ps_write(void *dat, u64 val);

int mac80211_hwsim_testmode_cmd(struct ieee80211_hw *hw, void *data, int len)
{
struct mac80211_hwsim_data *hwsim = hw->priv;
struct nlattr *tb[HWSIM_TM_ATTR_MAX + 1];
struct sk_buff *skb;
int err, ps;

err = nla_parse(tb, HWSIM_TM_ATTR_MAX, data, len,
hwsim_testmode_policy);
if (err)
return err;

if (!tb[HWSIM_TM_ATTR_CMD])
return -EINVAL;

switch (nla_get_u32(tb[HWSIM_TM_ATTR_CMD])) {
case HWSIM_TM_CMD_SET_PS:
if (!tb[HWSIM_TM_ATTR_PS])
return -EINVAL;
ps = nla_get_u32(tb[HWSIM_TM_ATTR_PS]);
return hwsim_fops_ps_write(hwsim, ps);
case HWSIM_TM_CMD_GET_PS:
skb = cfg80211_testmode_alloc_reply_skb(hw->wiphy,
nla_total_size(sizeof(u32)));
if (!skb)
return -ENOMEM;
NLA_PUT_U32(skb, HWSIM_TM_ATTR_PS, hwsim->ps);
return cfg80211_testmode_reply(skb);
default:
return -EOPNOTSUPP;
}

nla_put_failure:
kfree_skb(skb);
return -ENOBUFS;
}
#endif

static const struct ieee80211_ops mac80211_hwsim_ops =
{
.tx = mac80211_hwsim_tx,
Expand All @@ -713,6 +780,7 @@ static const struct ieee80211_ops mac80211_hwsim_ops =
.sta_notify = mac80211_hwsim_sta_notify,
.set_tim = mac80211_hwsim_set_tim,
.conf_tx = mac80211_hwsim_conf_tx,
CFG80211_TESTMODE_CMD(mac80211_hwsim_testmode_cmd)
};


Expand Down
11 changes: 11 additions & 0 deletions trunk/include/linux/nl80211.h
Original file line number Diff line number Diff line change
Expand Up @@ -242,6 +242,10 @@
* @NL80211_CMD_LEAVE_IBSS: Leave the IBSS -- no special arguments, the IBSS is
* determined by the network interface.
*
* @NL80211_CMD_TESTMODE: testmode command, takes a wiphy (or ifindex) attribute
* to identify the device, and the TESTDATA blob attribute to pass through
* to the driver.
*
* @NL80211_CMD_MAX: highest used command number
* @__NL80211_CMD_AFTER_LAST: internal use
*/
Expand Down Expand Up @@ -310,6 +314,8 @@ enum nl80211_commands {
NL80211_CMD_JOIN_IBSS,
NL80211_CMD_LEAVE_IBSS,

NL80211_CMD_TESTMODE,

/* add new commands above here */

/* used to define NL80211_CMD_MAX below */
Expand Down Expand Up @@ -511,6 +517,9 @@ enum nl80211_commands {
* authorized by user space. Otherwise, port is marked authorized by
* default in station mode.
*
* @NL80211_ATTR_TESTDATA: Testmode data blob, passed through to the driver.
* We recommend using nested, driver-specific attributes within this.
*
* @NL80211_ATTR_MAX: highest attribute number currently defined
* @__NL80211_ATTR_AFTER_LAST: internal use
*/
Expand Down Expand Up @@ -619,6 +628,8 @@ enum nl80211_attrs {

NL80211_ATTR_CONTROL_PORT,

NL80211_ATTR_TESTDATA,

/* add attributes here, update the policy in nl80211.c */

__NL80211_ATTR_AFTER_LAST,
Expand Down
83 changes: 83 additions & 0 deletions trunk/include/net/cfg80211.h
Original file line number Diff line number Diff line change
Expand Up @@ -857,6 +857,8 @@ enum tx_power_setting {
*
* @rfkill_poll: polls the hw rfkill line, use cfg80211 reporting
* functions to adjust rfkill hw state
*
* @testmode_cmd: run a test mode command
*/
struct cfg80211_ops {
int (*suspend)(struct wiphy *wiphy);
Expand Down Expand Up @@ -955,6 +957,10 @@ struct cfg80211_ops {
int (*get_tx_power)(struct wiphy *wiphy, int *dbm);

void (*rfkill_poll)(struct wiphy *wiphy);

#ifdef CONFIG_NL80211_TESTMODE
int (*testmode_cmd)(struct wiphy *wiphy, void *data, int len);
#endif
};

/*
Expand Down Expand Up @@ -1705,4 +1711,81 @@ void wiphy_rfkill_start_polling(struct wiphy *wiphy);
*/
void wiphy_rfkill_stop_polling(struct wiphy *wiphy);

#ifdef CONFIG_NL80211_TESTMODE
/**
* cfg80211_testmode_alloc_reply_skb - allocate testmode reply
* @wiphy: the wiphy
* @approxlen: an upper bound of the length of the data that will
* be put into the skb
*
* This function allocates and pre-fills an skb for a reply to
* the testmode command. Since it is intended for a reply, calling
* it outside of the @testmode_cmd operation is invalid.
*
* The returned skb (or %NULL if any errors happen) is pre-filled
* with the wiphy index and set up in a way that any data that is
* put into the skb (with skb_put(), nla_put() or similar) will end
* up being within the %NL80211_ATTR_TESTDATA attribute, so all that
* needs to be done with the skb is adding data for the corresponding
* userspace tool which can then read that data out of the testdata
* attribute. You must not modify the skb in any other way.
*
* When done, call cfg80211_testmode_reply() with the skb and return
* its error code as the result of the @testmode_cmd operation.
*/
struct sk_buff *cfg80211_testmode_alloc_reply_skb(struct wiphy *wiphy,
int approxlen);

/**
* cfg80211_testmode_reply - send the reply skb
* @skb: The skb, must have been allocated with
* cfg80211_testmode_alloc_reply_skb()
*
* Returns an error code or 0 on success, since calling this
* function will usually be the last thing before returning
* from the @testmode_cmd you should return the error code.
* Note that this function consumes the skb regardless of the
* return value.
*/
int cfg80211_testmode_reply(struct sk_buff *skb);

/**
* cfg80211_testmode_alloc_event_skb - allocate testmode event
* @wiphy: the wiphy
* @approxlen: an upper bound of the length of the data that will
* be put into the skb
* @gfp: allocation flags
*
* This function allocates and pre-fills an skb for an event on the
* testmode multicast group.
*
* The returned skb (or %NULL if any errors happen) is set up in the
* same way as with cfg80211_testmode_alloc_reply_skb() but prepared
* for an event. As there, you should simply add data to it that will
* then end up in the %NL80211_ATTR_TESTDATA attribute. Again, you must
* not modify the skb in any other way.
*
* When done filling the skb, call cfg80211_testmode_event() with the
* skb to send the event.
*/
struct sk_buff *cfg80211_testmode_alloc_event_skb(struct wiphy *wiphy,
int approxlen, gfp_t gfp);

/**
* cfg80211_testmode_event - send the event
* @skb: The skb, must have been allocated with
* cfg80211_testmode_alloc_event_skb()
* @gfp: allocation flags
*
* This function sends the given @skb, which must have been allocated
* by cfg80211_testmode_alloc_event_skb(), as an event. It always
* consumes it.
*/
void cfg80211_testmode_event(struct sk_buff *skb, gfp_t gfp);

#define CFG80211_TESTMODE_CMD(cmd) .testmode_cmd = (cmd),
#else
#define CFG80211_TESTMODE_CMD(cmd)
#endif

#endif /* __NET_CFG80211_H */
5 changes: 5 additions & 0 deletions trunk/include/net/mac80211.h
Original file line number Diff line number Diff line change
Expand Up @@ -1416,6 +1416,8 @@ enum ieee80211_ampdu_mlme_action {
* @rfkill_poll: Poll rfkill hardware state. If you need this, you also
* need to set wiphy->rfkill_poll to %true before registration,
* and need to call wiphy_rfkill_set_hw_state() in the callback.
*
* @testmode_cmd: Implement a cfg80211 test mode command.
*/
struct ieee80211_ops {
int (*tx)(struct ieee80211_hw *hw, struct sk_buff *skb);
Expand Down Expand Up @@ -1466,6 +1468,9 @@ struct ieee80211_ops {
struct ieee80211_sta *sta, u16 tid, u16 *ssn);

void (*rfkill_poll)(struct ieee80211_hw *hw);
#ifdef CONFIG_NL80211_TESTMODE
int (*testmode_cmd)(struct ieee80211_hw *hw, void *data, int len);
#endif
};

/**
Expand Down
13 changes: 13 additions & 0 deletions trunk/net/mac80211/cfg.c
Original file line number Diff line number Diff line change
Expand Up @@ -1376,6 +1376,18 @@ static void ieee80211_rfkill_poll(struct wiphy *wiphy)
drv_rfkill_poll(local);
}

#ifdef CONFIG_NL80211_TESTMODE
int ieee80211_testmode_cmd(struct wiphy *wiphy, void *data, int len)
{
struct ieee80211_local *local = wiphy_priv(wiphy);

if (!local->ops->testmode_cmd)
return -EOPNOTSUPP;

return local->ops->testmode_cmd(&local->hw, data, len);
}
#endif

struct cfg80211_ops mac80211_config_ops = {
.add_virtual_intf = ieee80211_add_iface,
.del_virtual_intf = ieee80211_del_iface,
Expand Down Expand Up @@ -1418,4 +1430,5 @@ struct cfg80211_ops mac80211_config_ops = {
.set_tx_power = ieee80211_set_tx_power,
.get_tx_power = ieee80211_get_tx_power,
.rfkill_poll = ieee80211_rfkill_poll,
CFG80211_TESTMODE_CMD(ieee80211_testmode_cmd)
};
15 changes: 15 additions & 0 deletions trunk/net/wireless/Kconfig
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,21 @@ config CFG80211
tristate "Improved wireless configuration API"
depends on RFKILL || !RFKILL

config NL80211_TESTMODE
bool "nl80211 testmode command"
depends on CFG80211
help
The nl80211 testmode command helps implementing things like
factory calibration or validation tools for wireless chips.

Select this option ONLY for kernels that are specifically
built for such purposes.

Debugging tools that are supposed to end up in the hands of
users should better be implemented with debugfs.

Say N.

config CFG80211_REG_DEBUG
bool "cfg80211 regulatory debugging"
depends on CFG80211
Expand Down
4 changes: 4 additions & 0 deletions trunk/net/wireless/core.h
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,10 @@ struct cfg80211_registered_device {
struct cfg80211_scan_request *scan_req; /* protected by RTNL */
unsigned long suspend_at;

#ifdef CONFIG_NL80211_TESTMODE
struct genl_info *testmode_info;
#endif

#ifdef CONFIG_CFG80211_DEBUGFS
/* Debugfs entries */
struct wiphy_debugfsdentries {
Expand Down
Loading

0 comments on commit 4d204a2

Please sign in to comment.