提交 4db16a18 编写于 作者: A Avinash Patil 提交者: John W. Linville

mwifiex: add AP command sys_config and set channel

1. support for AP sys_config command and added parsing of channel
information.
2. support for setting AP channel from cfg80211 set_channel handler
Signed-off-by: NAvinash Patil <patila@marvell.com>
Signed-off-by: NYogesh Ashok Powar <yogeshp@marvell.com>
Signed-off-by: NKiran Divekar <dkiran@marvell.com>
Signed-off-by: NBing Zhao <bzhao@marvell.com>
Signed-off-by: NJohn W. Linville <linville@tuxdriver.com>
上级 40d07030
......@@ -387,7 +387,10 @@ mwifiex_set_rf_channel(struct mwifiex_private *priv,
if (mwifiex_bss_set_channel(priv, &cfp))
return -EFAULT;
return mwifiex_drv_change_adhoc_chan(priv, cfp.channel);
if (priv->bss_type == MWIFIEX_BSS_TYPE_STA)
return mwifiex_drv_change_adhoc_chan(priv, cfp.channel);
else
return mwifiex_uap_set_channel(priv, cfp.channel);
}
/*
......
......@@ -1112,11 +1112,22 @@ struct host_cmd_tlv {
__le16 len;
} __packed;
struct host_cmd_ds_sys_config {
__le16 action;
u8 tlv[0];
};
struct host_cmd_tlv_mac_addr {
struct host_cmd_tlv tlv;
u8 mac_addr[ETH_ALEN];
} __packed;
struct host_cmd_tlv_channel_band {
struct host_cmd_tlv tlv;
u8 band_config;
u8 channel;
} __packed;
struct host_cmd_ds_802_11_rf_channel {
__le16 action;
__le16 current_channel;
......@@ -1231,6 +1242,7 @@ struct host_cmd_ds_command {
struct host_cmd_ds_pcie_details pcie_host_spec;
struct host_cmd_ds_802_11_eeprom_access eeprom;
struct host_cmd_ds_802_11_subsc_evt subsc_evt;
struct host_cmd_ds_sys_config uap_sys_config;
} params;
} __packed;
......
......@@ -62,6 +62,12 @@ enum {
BAND_AN = 16,
};
#define BAND_CONFIG_MANUAL 0x00
struct mwifiex_uap_bss_param {
u8 channel;
u8 band_cfg;
};
enum {
ADHOC_IDLE,
ADHOC_STARTED,
......
......@@ -975,6 +975,7 @@ int mwifiex_set_tx_power(struct mwifiex_private *priv,
int mwifiex_main_process(struct mwifiex_adapter *);
int mwifiex_uap_set_channel(struct mwifiex_private *priv, int channel);
int mwifiex_bss_set_channel(struct mwifiex_private *,
struct mwifiex_chan_freq_power *cfp);
int mwifiex_get_bss_info(struct mwifiex_private *,
......
......@@ -19,6 +19,41 @@
#include "main.h"
/* Parse AP config structure and prepare TLV based command structure
* to be sent to FW for uAP configuration
*/
static int mwifiex_cmd_uap_sys_config(struct host_cmd_ds_command *cmd,
u16 cmd_action, void *cmd_buf)
{
u8 *tlv;
struct host_cmd_ds_sys_config *sys_config = &cmd->params.uap_sys_config;
struct host_cmd_tlv_channel_band *chan_band;
struct mwifiex_uap_bss_param *bss_cfg = cmd_buf;
u16 cmd_size;
cmd->command = cpu_to_le16(HostCmd_CMD_UAP_SYS_CONFIG);
cmd_size = (u16)(sizeof(struct host_cmd_ds_sys_config) + S_DS_GEN);
sys_config->action = cpu_to_le16(cmd_action);
tlv = sys_config->tlv;
if (bss_cfg->channel && bss_cfg->channel <= MAX_CHANNEL_BAND_BG) {
chan_band = (struct host_cmd_tlv_channel_band *)tlv;
chan_band->tlv.type = cpu_to_le16(TLV_TYPE_CHANNELBANDLIST);
chan_band->tlv.len =
cpu_to_le16(sizeof(struct host_cmd_tlv_channel_band) -
sizeof(struct host_cmd_tlv));
chan_band->band_config = bss_cfg->band_cfg;
chan_band->channel = bss_cfg->channel;
cmd_size += sizeof(struct host_cmd_tlv_channel_band);
tlv += sizeof(struct host_cmd_tlv_channel_band);
}
cmd->size = cpu_to_le16(cmd_size);
return 0;
}
/* This function prepares the AP specific commands before sending them
* to the firmware.
* This is a generic function which calls specific command preparation
......@@ -31,6 +66,10 @@ int mwifiex_uap_prepare_cmd(struct mwifiex_private *priv, u16 cmd_no,
struct host_cmd_ds_command *cmd = cmd_buf;
switch (cmd_no) {
case HostCmd_CMD_UAP_SYS_CONFIG:
if (mwifiex_cmd_uap_sys_config(cmd, cmd_action, data_buf))
return -1;
break;
case HostCmd_CMD_UAP_BSS_START:
case HostCmd_CMD_UAP_BSS_STOP:
cmd->command = cpu_to_le16(cmd_no);
......@@ -44,3 +83,31 @@ int mwifiex_uap_prepare_cmd(struct mwifiex_private *priv, u16 cmd_no,
return 0;
}
/* This function sets the RF channel for AP.
*
* This function populates channel information in AP config structure
* and sends command to configure channel information in AP.
*/
int mwifiex_uap_set_channel(struct mwifiex_private *priv, int channel)
{
struct mwifiex_uap_bss_param *bss_cfg;
struct wiphy *wiphy = priv->wdev->wiphy;
bss_cfg = kzalloc(sizeof(struct mwifiex_uap_bss_param), GFP_KERNEL);
if (!bss_cfg)
return -ENOMEM;
bss_cfg->band_cfg = BAND_CONFIG_MANUAL;
bss_cfg->channel = channel;
if (mwifiex_send_cmd_async(priv, HostCmd_CMD_UAP_SYS_CONFIG,
HostCmd_ACT_GEN_SET, 0, bss_cfg)) {
wiphy_err(wiphy, "Failed to set the uAP channel\n");
kfree(bss_cfg);
return -1;
}
kfree(bss_cfg);
return 0;
}
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册