Skip to content

Commit 3935ccc

Browse files
Xinming HuKalle Valo
authored andcommitted
mwifiex: add cfg80211 testmode support
This patch adds cfg80211 testmode support so that userspace tools can download necessary commands to firmware during manufacturing mode tests. Signed-off-by: Xinming Hu <[email protected]> Signed-off-by: Amitkumar Karwar <[email protected]> Signed-off-by: Kalle Valo <[email protected]>
1 parent cf5383b commit 3935ccc

File tree

1 file changed

+83
-0
lines changed

1 file changed

+83
-0
lines changed

drivers/net/wireless/marvell/mwifiex/cfg80211.c

Lines changed: 83 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3919,6 +3919,88 @@ static int mwifiex_cfg80211_get_channel(struct wiphy *wiphy,
39193919
return ret;
39203920
}
39213921

3922+
#ifdef CONFIG_NL80211_TESTMODE
3923+
3924+
enum mwifiex_tm_attr {
3925+
__MWIFIEX_TM_ATTR_INVALID = 0,
3926+
MWIFIEX_TM_ATTR_CMD = 1,
3927+
MWIFIEX_TM_ATTR_DATA = 2,
3928+
3929+
/* keep last */
3930+
__MWIFIEX_TM_ATTR_AFTER_LAST,
3931+
MWIFIEX_TM_ATTR_MAX = __MWIFIEX_TM_ATTR_AFTER_LAST - 1,
3932+
};
3933+
3934+
static const struct nla_policy mwifiex_tm_policy[MWIFIEX_TM_ATTR_MAX + 1] = {
3935+
[MWIFIEX_TM_ATTR_CMD] = { .type = NLA_U32 },
3936+
[MWIFIEX_TM_ATTR_DATA] = { .type = NLA_BINARY,
3937+
.len = MWIFIEX_SIZE_OF_CMD_BUFFER },
3938+
};
3939+
3940+
enum mwifiex_tm_command {
3941+
MWIFIEX_TM_CMD_HOSTCMD = 0,
3942+
};
3943+
3944+
static int mwifiex_tm_cmd(struct wiphy *wiphy, struct wireless_dev *wdev,
3945+
void *data, int len)
3946+
{
3947+
struct mwifiex_private *priv = mwifiex_netdev_get_priv(wdev->netdev);
3948+
struct mwifiex_ds_misc_cmd *hostcmd;
3949+
struct nlattr *tb[MWIFIEX_TM_ATTR_MAX + 1];
3950+
struct mwifiex_adapter *adapter;
3951+
struct sk_buff *skb;
3952+
int err;
3953+
3954+
if (!priv)
3955+
return -EINVAL;
3956+
adapter = priv->adapter;
3957+
3958+
err = nla_parse(tb, MWIFIEX_TM_ATTR_MAX, data, len,
3959+
mwifiex_tm_policy);
3960+
if (err)
3961+
return err;
3962+
3963+
if (!tb[MWIFIEX_TM_ATTR_CMD])
3964+
return -EINVAL;
3965+
3966+
switch (nla_get_u32(tb[MWIFIEX_TM_ATTR_CMD])) {
3967+
case MWIFIEX_TM_CMD_HOSTCMD:
3968+
if (!tb[MWIFIEX_TM_ATTR_DATA])
3969+
return -EINVAL;
3970+
3971+
hostcmd = kzalloc(sizeof(*hostcmd), GFP_KERNEL);
3972+
if (!hostcmd)
3973+
return -ENOMEM;
3974+
3975+
hostcmd->len = nla_len(tb[MWIFIEX_TM_ATTR_DATA]);
3976+
memcpy(hostcmd->cmd, nla_data(tb[MWIFIEX_TM_ATTR_DATA]),
3977+
hostcmd->len);
3978+
3979+
if (mwifiex_send_cmd(priv, 0, 0, 0, hostcmd, true)) {
3980+
dev_err(priv->adapter->dev, "Failed to process hostcmd\n");
3981+
return -EFAULT;
3982+
}
3983+
3984+
/* process hostcmd response*/
3985+
skb = cfg80211_testmode_alloc_reply_skb(wiphy, hostcmd->len);
3986+
if (!skb)
3987+
return -ENOMEM;
3988+
err = nla_put(skb, MWIFIEX_TM_ATTR_DATA,
3989+
hostcmd->len, hostcmd->cmd);
3990+
if (err) {
3991+
kfree_skb(skb);
3992+
return -EMSGSIZE;
3993+
}
3994+
3995+
err = cfg80211_testmode_reply(skb);
3996+
kfree(hostcmd);
3997+
return err;
3998+
default:
3999+
return -EOPNOTSUPP;
4000+
}
4001+
}
4002+
#endif
4003+
39224004
static int
39234005
mwifiex_cfg80211_start_radar_detection(struct wiphy *wiphy,
39244006
struct net_device *dev,
@@ -4031,6 +4113,7 @@ static struct cfg80211_ops mwifiex_cfg80211_ops = {
40314113
.tdls_cancel_channel_switch = mwifiex_cfg80211_tdls_cancel_chan_switch,
40324114
.add_station = mwifiex_cfg80211_add_station,
40334115
.change_station = mwifiex_cfg80211_change_station,
4116+
CFG80211_TESTMODE_CMD(mwifiex_tm_cmd)
40344117
.get_channel = mwifiex_cfg80211_get_channel,
40354118
.start_radar_detection = mwifiex_cfg80211_start_radar_detection,
40364119
.channel_switch = mwifiex_cfg80211_channel_switch,

0 commit comments

Comments
 (0)