summaryrefslogtreecommitdiff
path: root/drivers
diff options
context:
space:
mode:
Diffstat (limited to 'drivers')
-rw-r--r--drivers/net/wireless/mwifiex/cfg80211.c99
-rw-r--r--drivers/net/wireless/mwifiex/decl.h1
-rw-r--r--drivers/net/wireless/mwifiex/fw.h18
-rw-r--r--drivers/net/wireless/mwifiex/ioctl.h3
-rw-r--r--drivers/net/wireless/mwifiex/main.h2
-rw-r--r--drivers/net/wireless/mwifiex/uap_cmd.c47
6 files changed, 150 insertions, 20 deletions
diff --git a/drivers/net/wireless/mwifiex/cfg80211.c b/drivers/net/wireless/mwifiex/cfg80211.c
index a8fa5cba2028..daa7b4b1a250 100644
--- a/drivers/net/wireless/mwifiex/cfg80211.c
+++ b/drivers/net/wireless/mwifiex/cfg80211.c
@@ -428,18 +428,13 @@ mwifiex_cfg80211_set_channel(struct wiphy *wiphy, struct net_device *dev,
static int
mwifiex_set_frag(struct mwifiex_private *priv, u32 frag_thr)
{
- int ret;
-
if (frag_thr < MWIFIEX_FRAG_MIN_VALUE ||
frag_thr > MWIFIEX_FRAG_MAX_VALUE)
- return -EINVAL;
-
- /* Send request to firmware */
- ret = mwifiex_send_cmd_sync(priv, HostCmd_CMD_802_11_SNMP_MIB,
- HostCmd_ACT_GEN_SET, FRAG_THRESH_I,
- &frag_thr);
+ frag_thr = MWIFIEX_FRAG_MAX_VALUE;
- return ret;
+ return mwifiex_send_cmd_sync(priv, HostCmd_CMD_802_11_SNMP_MIB,
+ HostCmd_ACT_GEN_SET, FRAG_THRESH_I,
+ &frag_thr);
}
/*
@@ -469,20 +464,84 @@ static int
mwifiex_cfg80211_set_wiphy_params(struct wiphy *wiphy, u32 changed)
{
struct mwifiex_adapter *adapter = mwifiex_cfg80211_get_adapter(wiphy);
- struct mwifiex_private *priv = mwifiex_get_priv(adapter,
- MWIFIEX_BSS_ROLE_STA);
- int ret = 0;
+ struct mwifiex_private *priv;
+ struct mwifiex_uap_bss_param *bss_cfg;
+ int ret, bss_started, i;
+
+ for (i = 0; i < adapter->priv_num; i++) {
+ priv = adapter->priv[i];
+
+ switch (priv->bss_role) {
+ case MWIFIEX_BSS_ROLE_UAP:
+ bss_cfg = kzalloc(sizeof(struct mwifiex_uap_bss_param),
+ GFP_KERNEL);
+ if (!bss_cfg)
+ return -ENOMEM;
+
+ mwifiex_set_sys_config_invalid_data(bss_cfg);
+
+ if (changed & WIPHY_PARAM_RTS_THRESHOLD)
+ bss_cfg->rts_threshold = wiphy->rts_threshold;
+ if (changed & WIPHY_PARAM_FRAG_THRESHOLD)
+ bss_cfg->frag_threshold = wiphy->frag_threshold;
+ if (changed & WIPHY_PARAM_RETRY_LONG)
+ bss_cfg->retry_limit = wiphy->retry_long;
+
+ bss_started = priv->bss_started;
+
+ ret = mwifiex_send_cmd_sync(priv,
+ HostCmd_CMD_UAP_BSS_STOP,
+ HostCmd_ACT_GEN_SET, 0,
+ NULL);
+ if (ret) {
+ wiphy_err(wiphy, "Failed to stop the BSS\n");
+ kfree(bss_cfg);
+ return ret;
+ }
- if (changed & WIPHY_PARAM_RTS_THRESHOLD) {
- ret = mwifiex_set_rts(priv, wiphy->rts_threshold);
- if (ret)
- return ret;
- }
+ ret = mwifiex_send_cmd_async(priv,
+ HostCmd_CMD_UAP_SYS_CONFIG,
+ HostCmd_ACT_GEN_SET,
+ 0, bss_cfg);
- if (changed & WIPHY_PARAM_FRAG_THRESHOLD)
- ret = mwifiex_set_frag(priv, wiphy->frag_threshold);
+ kfree(bss_cfg);
- return ret;
+ if (ret) {
+ wiphy_err(wiphy, "Failed to set bss config\n");
+ return ret;
+ }
+
+ if (!bss_started)
+ break;
+
+ ret = mwifiex_send_cmd_async(priv,
+ HostCmd_CMD_UAP_BSS_START,
+ HostCmd_ACT_GEN_SET, 0,
+ NULL);
+ if (ret) {
+ wiphy_err(wiphy, "Failed to start BSS\n");
+ return ret;
+ }
+
+ break;
+ case MWIFIEX_BSS_ROLE_STA:
+ if (changed & WIPHY_PARAM_RTS_THRESHOLD) {
+ ret = mwifiex_set_rts(priv,
+ wiphy->rts_threshold);
+ if (ret)
+ return ret;
+ }
+ if (changed & WIPHY_PARAM_FRAG_THRESHOLD) {
+ ret = mwifiex_set_frag(priv,
+ wiphy->frag_threshold);
+ if (ret)
+ return ret;
+ }
+ break;
+ }
+ }
+
+ return 0;
}
/*
diff --git a/drivers/net/wireless/mwifiex/decl.h b/drivers/net/wireless/mwifiex/decl.h
index 6b8f9129b704..31dc2bada512 100644
--- a/drivers/net/wireless/mwifiex/decl.h
+++ b/drivers/net/wireless/mwifiex/decl.h
@@ -60,6 +60,7 @@
#define MWIFIEX_FRAG_MIN_VALUE (256)
#define MWIFIEX_FRAG_MAX_VALUE (2346)
+#define MWIFIEX_RETRY_LIMIT 14
#define MWIFIEX_SDIO_BLOCK_SIZE 256
#define MWIFIEX_BUF_FLAG_REQUEUED_PKT BIT(0)
diff --git a/drivers/net/wireless/mwifiex/fw.h b/drivers/net/wireless/mwifiex/fw.h
index a3e9c28465bf..a4c2fc3e3d71 100644
--- a/drivers/net/wireless/mwifiex/fw.h
+++ b/drivers/net/wireless/mwifiex/fw.h
@@ -106,9 +106,12 @@ enum MWIFIEX_802_11_PRIVACY_FILTER {
#define TLV_TYPE_AUTH_TYPE (PROPRIETARY_TLV_BASE_ID + 31)
#define TLV_TYPE_STA_MAC_ADDR (PROPRIETARY_TLV_BASE_ID + 32)
#define TLV_TYPE_CHANNELBANDLIST (PROPRIETARY_TLV_BASE_ID + 42)
+#define TLV_TYPE_UAP_RTS_THRESHOLD (PROPRIETARY_TLV_BASE_ID + 51)
+#define TLV_TYPE_UAP_FRAG_THRESHOLD (PROPRIETARY_TLV_BASE_ID + 70)
#define TLV_TYPE_RATE_DROP_CONTROL (PROPRIETARY_TLV_BASE_ID + 82)
#define TLV_TYPE_RATE_SCOPE (PROPRIETARY_TLV_BASE_ID + 83)
#define TLV_TYPE_POWER_GROUP (PROPRIETARY_TLV_BASE_ID + 84)
+#define TLV_TYPE_UAP_RETRY_LIMIT (PROPRIETARY_TLV_BASE_ID + 93)
#define TLV_TYPE_WAPI_IE (PROPRIETARY_TLV_BASE_ID + 94)
#define TLV_TYPE_MGMT_IE (PROPRIETARY_TLV_BASE_ID + 105)
#define TLV_TYPE_AUTO_DS_PARAM (PROPRIETARY_TLV_BASE_ID + 113)
@@ -1117,6 +1120,21 @@ struct host_cmd_ds_sys_config {
u8 tlv[0];
};
+struct host_cmd_tlv_frag_threshold {
+ struct host_cmd_tlv tlv;
+ __le16 frag_thr;
+} __packed;
+
+struct host_cmd_tlv_rts_threshold {
+ struct host_cmd_tlv tlv;
+ __le16 rts_thr;
+} __packed;
+
+struct host_cmd_tlv_retry_limit {
+ struct host_cmd_tlv tlv;
+ u8 limit;
+} __packed;
+
struct host_cmd_tlv_mac_addr {
struct host_cmd_tlv tlv;
u8 mac_addr[ETH_ALEN];
diff --git a/drivers/net/wireless/mwifiex/ioctl.h b/drivers/net/wireless/mwifiex/ioctl.h
index 50e9b7767da7..535a57a3f96e 100644
--- a/drivers/net/wireless/mwifiex/ioctl.h
+++ b/drivers/net/wireless/mwifiex/ioctl.h
@@ -66,6 +66,9 @@ enum {
struct mwifiex_uap_bss_param {
u8 channel;
u8 band_cfg;
+ u16 rts_threshold;
+ u16 frag_threshold;
+ u8 retry_limit;
};
enum {
diff --git a/drivers/net/wireless/mwifiex/main.h b/drivers/net/wireless/mwifiex/main.h
index 014a13f443ef..acea8d41c048 100644
--- a/drivers/net/wireless/mwifiex/main.h
+++ b/drivers/net/wireless/mwifiex/main.h
@@ -993,6 +993,8 @@ struct net_device *mwifiex_add_virtual_intf(struct wiphy *wiphy,
u32 *flags, struct vif_params *params);
int mwifiex_del_virtual_intf(struct wiphy *wiphy, struct net_device *dev);
+void mwifiex_set_sys_config_invalid_data(struct mwifiex_uap_bss_param *config);
+
u8 *mwifiex_11d_code_2_region(u8 code);
#ifdef CONFIG_DEBUG_FS
diff --git a/drivers/net/wireless/mwifiex/uap_cmd.c b/drivers/net/wireless/mwifiex/uap_cmd.c
index 795a72b94465..2225baca896a 100644
--- a/drivers/net/wireless/mwifiex/uap_cmd.c
+++ b/drivers/net/wireless/mwifiex/uap_cmd.c
@@ -19,6 +19,17 @@
#include "main.h"
+/* This function initializes some of mwifiex_uap_bss_param variables.
+ * This helps FW in ignoring invalid values. These values may or may not
+ * be get updated to valid ones at later stage.
+ */
+void mwifiex_set_sys_config_invalid_data(struct mwifiex_uap_bss_param *config)
+{
+ config->rts_threshold = 0x7FFF;
+ config->frag_threshold = 0x7FFF;
+ config->retry_limit = 0x7F;
+}
+
/* Parse AP config structure and prepare TLV based command structure
* to be sent to FW for uAP configuration
*/
@@ -28,6 +39,9 @@ static int mwifiex_cmd_uap_sys_config(struct host_cmd_ds_command *cmd,
u8 *tlv;
struct host_cmd_ds_sys_config *sys_config = &cmd->params.uap_sys_config;
struct host_cmd_tlv_channel_band *chan_band;
+ struct host_cmd_tlv_frag_threshold *frag_threshold;
+ struct host_cmd_tlv_rts_threshold *rts_threshold;
+ struct host_cmd_tlv_retry_limit *retry_limit;
struct mwifiex_uap_bss_param *bss_cfg = cmd_buf;
u16 cmd_size;
@@ -49,6 +63,39 @@ static int mwifiex_cmd_uap_sys_config(struct host_cmd_ds_command *cmd,
cmd_size += sizeof(struct host_cmd_tlv_channel_band);
tlv += sizeof(struct host_cmd_tlv_channel_band);
}
+ if (bss_cfg->rts_threshold <= MWIFIEX_RTS_MAX_VALUE) {
+ rts_threshold = (struct host_cmd_tlv_rts_threshold *)tlv;
+ rts_threshold->tlv.type =
+ cpu_to_le16(TLV_TYPE_UAP_RTS_THRESHOLD);
+ rts_threshold->tlv.len =
+ cpu_to_le16(sizeof(struct host_cmd_tlv_rts_threshold) -
+ sizeof(struct host_cmd_tlv));
+ rts_threshold->rts_thr = cpu_to_le16(bss_cfg->rts_threshold);
+ cmd_size += sizeof(struct host_cmd_tlv_frag_threshold);
+ tlv += sizeof(struct host_cmd_tlv_frag_threshold);
+ }
+ if ((bss_cfg->frag_threshold >= MWIFIEX_FRAG_MIN_VALUE) &&
+ (bss_cfg->frag_threshold <= MWIFIEX_FRAG_MAX_VALUE)) {
+ frag_threshold = (struct host_cmd_tlv_frag_threshold *)tlv;
+ frag_threshold->tlv.type =
+ cpu_to_le16(TLV_TYPE_UAP_FRAG_THRESHOLD);
+ frag_threshold->tlv.len =
+ cpu_to_le16(sizeof(struct host_cmd_tlv_frag_threshold) -
+ sizeof(struct host_cmd_tlv));
+ frag_threshold->frag_thr = cpu_to_le16(bss_cfg->frag_threshold);
+ cmd_size += sizeof(struct host_cmd_tlv_frag_threshold);
+ tlv += sizeof(struct host_cmd_tlv_frag_threshold);
+ }
+ if (bss_cfg->retry_limit <= MWIFIEX_RETRY_LIMIT) {
+ retry_limit = (struct host_cmd_tlv_retry_limit *)tlv;
+ retry_limit->tlv.type = cpu_to_le16(TLV_TYPE_UAP_RETRY_LIMIT);
+ retry_limit->tlv.len =
+ cpu_to_le16(sizeof(struct host_cmd_tlv_retry_limit) -
+ sizeof(struct host_cmd_tlv));
+ retry_limit->limit = (u8)bss_cfg->retry_limit;
+ cmd_size += sizeof(struct host_cmd_tlv_retry_limit);
+ tlv += sizeof(struct host_cmd_tlv_retry_limit);
+ }
cmd->size = cpu_to_le16(cmd_size);
return 0;