summaryrefslogtreecommitdiffstats
path: root/drivers/net/wireless/mwifiex
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/net/wireless/mwifiex')
-rw-r--r--drivers/net/wireless/mwifiex/cfg80211.c56
-rw-r--r--drivers/net/wireless/mwifiex/debugfs.c2
-rw-r--r--drivers/net/wireless/mwifiex/decl.h4
-rw-r--r--drivers/net/wireless/mwifiex/fw.h11
-rw-r--r--drivers/net/wireless/mwifiex/sta_cmd.c10
-rw-r--r--drivers/net/wireless/mwifiex/sta_tx.c13
6 files changed, 88 insertions, 8 deletions
diff --git a/drivers/net/wireless/mwifiex/cfg80211.c b/drivers/net/wireless/mwifiex/cfg80211.c
index 687c1f2..352d2c5 100644
--- a/drivers/net/wireless/mwifiex/cfg80211.c
+++ b/drivers/net/wireless/mwifiex/cfg80211.c
@@ -672,6 +672,59 @@ static const u32 mwifiex_cipher_suites[] = {
};
/*
+ * CFG802.11 operation handler for setting bit rates.
+ *
+ * Function selects legacy bang B/G/BG from corresponding bitrates selection.
+ * Currently only 2.4GHz band is supported.
+ */
+static int mwifiex_cfg80211_set_bitrate_mask(struct wiphy *wiphy,
+ struct net_device *dev,
+ const u8 *peer,
+ const struct cfg80211_bitrate_mask *mask)
+{
+ struct mwifiex_ds_band_cfg band_cfg;
+ struct mwifiex_private *priv = mwifiex_netdev_get_priv(dev);
+ int index = 0, mode = 0, i;
+
+ /* Currently only 2.4GHz is supported */
+ for (i = 0; i < mwifiex_band_2ghz.n_bitrates; i++) {
+ /*
+ * Rates below 6 Mbps in the table are CCK rates; 802.11b
+ * and from 6 they are OFDM; 802.11G
+ */
+ if (mwifiex_rates[i].bitrate == 60) {
+ index = 1 << i;
+ break;
+ }
+ }
+
+ if (mask->control[IEEE80211_BAND_2GHZ].legacy < index) {
+ mode = BAND_B;
+ } else {
+ mode = BAND_G;
+ if (mask->control[IEEE80211_BAND_2GHZ].legacy % index)
+ mode |= BAND_B;
+ }
+
+ memset(&band_cfg, 0, sizeof(band_cfg));
+ band_cfg.config_bands = mode;
+
+ if (priv->bss_mode == NL80211_IFTYPE_ADHOC)
+ band_cfg.adhoc_start_band = mode;
+
+ band_cfg.sec_chan_offset = NO_SEC_CHANNEL;
+
+ if (mwifiex_set_radio_band_cfg(priv, &band_cfg))
+ return -EFAULT;
+
+ wiphy_debug(wiphy, "info: device configured in 802.11%s%s mode\n",
+ (mode & BAND_B) ? "b" : "",
+ (mode & BAND_G) ? "g" : "");
+
+ return 0;
+}
+
+/*
* CFG802.11 operation handler for disconnection request.
*
* This function does not work when there is already a disconnection
@@ -960,7 +1013,7 @@ mwifiex_cfg80211_assoc(struct mwifiex_private *priv, size_t ssid_len, u8 *ssid,
ret = mwifiex_set_gen_ie(priv, sme->ie, sme->ie_len);
if (sme->key) {
- if (mwifiex_is_alg_wep(0) | mwifiex_is_alg_wep(0)) {
+ if (mwifiex_is_alg_wep(priv->sec_info.encryption_mode)) {
dev_dbg(priv->adapter->dev,
"info: setting wep encryption"
" with key len %d\n", sme->key_len);
@@ -1225,6 +1278,7 @@ static struct cfg80211_ops mwifiex_cfg80211_ops = {
.set_default_key = mwifiex_cfg80211_set_default_key,
.set_power_mgmt = mwifiex_cfg80211_set_power_mgmt,
.set_tx_power = mwifiex_cfg80211_set_tx_power,
+ .set_bitrate_mask = mwifiex_cfg80211_set_bitrate_mask,
};
/*
diff --git a/drivers/net/wireless/mwifiex/debugfs.c b/drivers/net/wireless/mwifiex/debugfs.c
index 46d65e0..1bcf9ea 100644
--- a/drivers/net/wireless/mwifiex/debugfs.c
+++ b/drivers/net/wireless/mwifiex/debugfs.c
@@ -27,8 +27,8 @@ static struct dentry *mwifiex_dfs_dir;
static char *bss_modes[] = {
"Unknown",
- "Managed",
"Ad-hoc",
+ "Managed",
"Auto"
};
diff --git a/drivers/net/wireless/mwifiex/decl.h b/drivers/net/wireless/mwifiex/decl.h
index 0e90b09..94ddc90 100644
--- a/drivers/net/wireless/mwifiex/decl.h
+++ b/drivers/net/wireless/mwifiex/decl.h
@@ -30,7 +30,9 @@
#define MWIFIEX_MAX_BSS_NUM (1)
-#define MWIFIEX_MIN_DATA_HEADER_LEN 32 /* (sizeof(mwifiex_txpd)) */
+#define MWIFIEX_MIN_DATA_HEADER_LEN 36 /* sizeof(mwifiex_txpd)
+ * + 4 byte alignment
+ */
#define MWIFIEX_MAX_TX_BASTREAM_SUPPORTED 2
#define MWIFIEX_MAX_RX_BASTREAM_SUPPORTED 16
diff --git a/drivers/net/wireless/mwifiex/fw.h b/drivers/net/wireless/mwifiex/fw.h
index afdd145..4fee099 100644
--- a/drivers/net/wireless/mwifiex/fw.h
+++ b/drivers/net/wireless/mwifiex/fw.h
@@ -157,6 +157,17 @@ enum MWIFIEX_802_11_WEP_STATUS {
#define ISSUPP_RXSTBC(Dot11nDevCap) (Dot11nDevCap & BIT(26))
#define ISSUPP_GREENFIELD(Dot11nDevCap) (Dot11nDevCap & BIT(29))
+/* httxcfg bitmap
+ * 0 reserved
+ * 1 20/40 Mhz enable(1)/disable(0)
+ * 2-3 reserved
+ * 4 green field enable(1)/disable(0)
+ * 5 short GI in 20 Mhz enable(1)/disable(0)
+ * 6 short GI in 40 Mhz enable(1)/disable(0)
+ * 7-15 reserved
+ */
+#define MWIFIEX_FW_DEF_HTTXCFG (BIT(1) | BIT(4) | BIT(5) | BIT(6))
+
#define GET_RXMCSSUPP(DevMCSSupported) (DevMCSSupported & 0x0f)
#define SETHT_MCS32(x) (x[4] |= 1)
diff --git a/drivers/net/wireless/mwifiex/sta_cmd.c b/drivers/net/wireless/mwifiex/sta_cmd.c
index 49b9c13..c54ee28 100644
--- a/drivers/net/wireless/mwifiex/sta_cmd.c
+++ b/drivers/net/wireless/mwifiex/sta_cmd.c
@@ -1113,6 +1113,7 @@ int mwifiex_sta_init_cmd(struct mwifiex_private *priv, u8 first_sta)
struct mwifiex_ds_11n_amsdu_aggr_ctrl amsdu_aggr_ctrl;
struct mwifiex_ds_auto_ds auto_ds;
enum state_11d_t state_11d;
+ struct mwifiex_ds_11n_tx_cfg tx_cfg;
if (first_sta) {
@@ -1198,8 +1199,15 @@ int mwifiex_sta_init_cmd(struct mwifiex_private *priv, u8 first_sta)
if (ret)
dev_err(priv->adapter->dev, "11D: failed to enable 11D\n");
+ /* Send cmd to FW to configure 11n specific configuration
+ * (Short GI, Channel BW, Green field support etc.) for transmit
+ */
+ tx_cfg.tx_htcap = MWIFIEX_FW_DEF_HTTXCFG;
+ ret = mwifiex_send_cmd_async(priv, HostCmd_CMD_11N_CFG,
+ HostCmd_ACT_GEN_SET, 0, &tx_cfg);
+
/* set last_init_cmd */
- priv->adapter->last_init_cmd = HostCmd_CMD_802_11_SNMP_MIB;
+ priv->adapter->last_init_cmd = HostCmd_CMD_11N_CFG;
ret = -EINPROGRESS;
return ret;
diff --git a/drivers/net/wireless/mwifiex/sta_tx.c b/drivers/net/wireless/mwifiex/sta_tx.c
index fa6221b..1822bfa 100644
--- a/drivers/net/wireless/mwifiex/sta_tx.c
+++ b/drivers/net/wireless/mwifiex/sta_tx.c
@@ -47,6 +47,7 @@ void *mwifiex_process_sta_txpd(struct mwifiex_private *priv,
struct mwifiex_adapter *adapter = priv->adapter;
struct txpd *local_tx_pd;
struct mwifiex_txinfo *tx_info = MWIFIEX_SKB_TXCB(skb);
+ u8 pad;
if (!skb->len) {
dev_err(adapter->dev, "Tx: bad packet length: %d\n",
@@ -55,15 +56,19 @@ void *mwifiex_process_sta_txpd(struct mwifiex_private *priv,
return skb->data;
}
- BUG_ON(skb_headroom(skb) < (sizeof(*local_tx_pd) + INTF_HEADER_LEN));
- skb_push(skb, sizeof(*local_tx_pd));
+ /* If skb->data is not aligned; add padding */
+ pad = (4 - (((void *)skb->data - NULL) & 0x3)) % 4;
+
+ BUG_ON(skb_headroom(skb) < (sizeof(*local_tx_pd) + INTF_HEADER_LEN
+ + pad));
+ skb_push(skb, sizeof(*local_tx_pd) + pad);
local_tx_pd = (struct txpd *) skb->data;
memset(local_tx_pd, 0, sizeof(struct txpd));
local_tx_pd->bss_num = priv->bss_num;
local_tx_pd->bss_type = priv->bss_type;
local_tx_pd->tx_pkt_length = cpu_to_le16((u16) (skb->len -
- sizeof(struct txpd)));
+ (sizeof(struct txpd) + pad)));
local_tx_pd->priority = (u8) skb->priority;
local_tx_pd->pkt_delay_2ms =
@@ -88,7 +93,7 @@ void *mwifiex_process_sta_txpd(struct mwifiex_private *priv,
}
/* Offset of actual data */
- local_tx_pd->tx_pkt_offset = cpu_to_le16(sizeof(struct txpd));
+ local_tx_pd->tx_pkt_offset = cpu_to_le16(sizeof(struct txpd) + pad);
/* make space for INTF_HEADER_LEN */
skb_push(skb, INTF_HEADER_LEN);
OpenPOWER on IntegriCloud