From 477778bb0e7c671860528946b412294684337c5e Mon Sep 17 00:00:00 2001 From: Amitkumar Karwar Date: Wed, 1 Feb 2012 20:41:44 -0800 Subject: mwifiex: fix NULL pointer dereference in set_channel() In set_channel() callback handler, "priv" pointer is derived from net_device. Sometimes net_device pointer coming from the stack is NULL which causes kernel crash. This patch fixes the problem by deriving "priv" from wiphy when net_device pointer is NULL. Signed-off-by: Amitkumar Karwar Signed-off-by: Bing Zhao Signed-off-by: John W. Linville --- drivers/net/wireless/mwifiex/cfg80211.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) (limited to 'drivers/net/wireless/mwifiex') diff --git a/drivers/net/wireless/mwifiex/cfg80211.c b/drivers/net/wireless/mwifiex/cfg80211.c index 6fef4925d13a..54e45c829c53 100644 --- a/drivers/net/wireless/mwifiex/cfg80211.c +++ b/drivers/net/wireless/mwifiex/cfg80211.c @@ -376,7 +376,12 @@ mwifiex_cfg80211_set_channel(struct wiphy *wiphy, struct net_device *dev, struct ieee80211_channel *chan, enum nl80211_channel_type channel_type) { - struct mwifiex_private *priv = mwifiex_netdev_get_priv(dev); + struct mwifiex_private *priv; + + if (dev) + priv = mwifiex_netdev_get_priv(dev); + else + priv = mwifiex_cfg80211_get_priv(wiphy); if (priv->media_connected) { wiphy_err(wiphy, "This setting is valid only when station " -- cgit v1.2.2 From 3dc5e1751803e812806d7aa46150af92f91ef489 Mon Sep 17 00:00:00 2001 From: Amitkumar Karwar Date: Wed, 1 Feb 2012 20:41:45 -0800 Subject: mwifiex: enable HT operating mode This patch sets default adapter channel_type as HT. Hence the device will opearate in HT mode. Signed-off-by: Amitkumar Karwar Signed-off-by: Bing Zhao Signed-off-by: John W. Linville --- drivers/net/wireless/mwifiex/init.c | 1 + 1 file changed, 1 insertion(+) (limited to 'drivers/net/wireless/mwifiex') diff --git a/drivers/net/wireless/mwifiex/init.c b/drivers/net/wireless/mwifiex/init.c index e13b6d99171a..83cc10fca4bd 100644 --- a/drivers/net/wireless/mwifiex/init.c +++ b/drivers/net/wireless/mwifiex/init.c @@ -280,6 +280,7 @@ static void mwifiex_init_adapter(struct mwifiex_adapter *adapter) adapter->adhoc_awake_period = 0; memset(&adapter->arp_filter, 0, sizeof(adapter->arp_filter)); adapter->arp_filter_size = 0; + adapter->channel_type = NL80211_CHAN_HT20; } /* -- cgit v1.2.2 From f3c8d2591fa7278abe58ee0278a41d5b130d1718 Mon Sep 17 00:00:00 2001 From: Amitkumar Karwar Date: Thu, 2 Feb 2012 20:48:57 -0800 Subject: mwifiex: cleanup in snmp_mib command preparation code 1) Remove unnecessary switch case usage. 2) Replace "X=cpu_to_le16(le16_to_cpu(X) + Y)" by "le16_add_cpu(X, Y)" 3) Declare "ul_temp" variable as u16 instead of u32 to avoid unnecessary typecasting Signed-off-by: Amitkumar Karwar Signed-off-by: Bing Zhao Signed-off-by: John W. Linville --- drivers/net/wireless/mwifiex/sta_cmd.c | 60 +++++----------------------------- 1 file changed, 8 insertions(+), 52 deletions(-) (limited to 'drivers/net/wireless/mwifiex') diff --git a/drivers/net/wireless/mwifiex/sta_cmd.c b/drivers/net/wireless/mwifiex/sta_cmd.c index 6e443ffa0465..324c651527cb 100644 --- a/drivers/net/wireless/mwifiex/sta_cmd.c +++ b/drivers/net/wireless/mwifiex/sta_cmd.c @@ -103,7 +103,7 @@ static int mwifiex_cmd_mac_control(struct mwifiex_private *priv, static int mwifiex_cmd_802_11_snmp_mib(struct mwifiex_private *priv, struct host_cmd_ds_command *cmd, u16 cmd_action, u32 cmd_oid, - u32 *ul_temp) + u16 *ul_temp) { struct host_cmd_ds_802_11_snmp_mib *snmp_mib = &cmd->params.smib; @@ -112,62 +112,18 @@ static int mwifiex_cmd_802_11_snmp_mib(struct mwifiex_private *priv, cmd->size = cpu_to_le16(sizeof(struct host_cmd_ds_802_11_snmp_mib) - 1 + S_DS_GEN); + snmp_mib->oid = cpu_to_le16((u16)cmd_oid); if (cmd_action == HostCmd_ACT_GEN_GET) { snmp_mib->query_type = cpu_to_le16(HostCmd_ACT_GEN_GET); snmp_mib->buf_size = cpu_to_le16(MAX_SNMP_BUF_SIZE); - cmd->size = cpu_to_le16(le16_to_cpu(cmd->size) - + MAX_SNMP_BUF_SIZE); + le16_add_cpu(&cmd->size, MAX_SNMP_BUF_SIZE); + } else if (cmd_action == HostCmd_ACT_GEN_SET) { + snmp_mib->query_type = cpu_to_le16(HostCmd_ACT_GEN_SET); + snmp_mib->buf_size = cpu_to_le16(sizeof(u16)); + *((__le16 *) (snmp_mib->value)) = cpu_to_le16(*ul_temp); + le16_add_cpu(&cmd->size, sizeof(u16)); } - switch (cmd_oid) { - case FRAG_THRESH_I: - snmp_mib->oid = cpu_to_le16((u16) FRAG_THRESH_I); - if (cmd_action == HostCmd_ACT_GEN_SET) { - snmp_mib->query_type = cpu_to_le16(HostCmd_ACT_GEN_SET); - snmp_mib->buf_size = cpu_to_le16(sizeof(u16)); - *((__le16 *) (snmp_mib->value)) = - cpu_to_le16((u16) *ul_temp); - cmd->size = cpu_to_le16(le16_to_cpu(cmd->size) - + sizeof(u16)); - } - break; - case RTS_THRESH_I: - snmp_mib->oid = cpu_to_le16((u16) RTS_THRESH_I); - if (cmd_action == HostCmd_ACT_GEN_SET) { - snmp_mib->query_type = cpu_to_le16(HostCmd_ACT_GEN_SET); - snmp_mib->buf_size = cpu_to_le16(sizeof(u16)); - *(__le16 *) (snmp_mib->value) = - cpu_to_le16((u16) *ul_temp); - cmd->size = cpu_to_le16(le16_to_cpu(cmd->size) - + sizeof(u16)); - } - break; - - case SHORT_RETRY_LIM_I: - snmp_mib->oid = cpu_to_le16((u16) SHORT_RETRY_LIM_I); - if (cmd_action == HostCmd_ACT_GEN_SET) { - snmp_mib->query_type = cpu_to_le16(HostCmd_ACT_GEN_SET); - snmp_mib->buf_size = cpu_to_le16(sizeof(u16)); - *((__le16 *) (snmp_mib->value)) = - cpu_to_le16((u16) *ul_temp); - cmd->size = cpu_to_le16(le16_to_cpu(cmd->size) - + sizeof(u16)); - } - break; - case DOT11D_I: - snmp_mib->oid = cpu_to_le16((u16) DOT11D_I); - if (cmd_action == HostCmd_ACT_GEN_SET) { - snmp_mib->query_type = cpu_to_le16(HostCmd_ACT_GEN_SET); - snmp_mib->buf_size = cpu_to_le16(sizeof(u16)); - *((__le16 *) (snmp_mib->value)) = - cpu_to_le16((u16) *ul_temp); - cmd->size = cpu_to_le16(le16_to_cpu(cmd->size) - + sizeof(u16)); - } - break; - default: - break; - } dev_dbg(priv->adapter->dev, "cmd: SNMP_CMD: Action=0x%x, OID=0x%x, OIDSize=0x%x," " Value=0x%x\n", -- cgit v1.2.2 From caf60a6c957e7a35837a41f845e57b4433e20276 Mon Sep 17 00:00:00 2001 From: Amitkumar Karwar Date: Thu, 2 Feb 2012 20:48:58 -0800 Subject: mwifiex: update correct dtim_period in dump_station() Earlier we were using dtim period extracted from scan response buffer provided by FW in scan operation. But it is observed that sometimes the buffer doesn't contain dtim period tlv, and wrong value (0) was sent to user space. After association FW will start listening to beacon frames of connected AP and store dtim period. Therefore we can get it from FW in dump_station() instead of using wrong value obtained in scanning. Redundant code after adapting new approach for dtim period is also removed in this patch. Signed-off-by: Amitkumar Karwar Signed-off-by: Bing Zhao Signed-off-by: John W. Linville --- drivers/net/wireless/mwifiex/cfg80211.c | 8 ++++++-- drivers/net/wireless/mwifiex/main.h | 2 +- drivers/net/wireless/mwifiex/scan.c | 6 ------ drivers/net/wireless/mwifiex/sta_cmdresp.c | 3 +++ 4 files changed, 10 insertions(+), 9 deletions(-) (limited to 'drivers/net/wireless/mwifiex') diff --git a/drivers/net/wireless/mwifiex/cfg80211.c b/drivers/net/wireless/mwifiex/cfg80211.c index 54e45c829c53..478d2f12c024 100644 --- a/drivers/net/wireless/mwifiex/cfg80211.c +++ b/drivers/net/wireless/mwifiex/cfg80211.c @@ -539,6 +539,11 @@ mwifiex_dump_station_info(struct mwifiex_private *priv, ret = -EFAULT; } + /* Get DTIM period information from firmware */ + mwifiex_send_cmd_sync(priv, HostCmd_CMD_802_11_SNMP_MIB, + HostCmd_ACT_GEN_GET, DTIM_PERIOD_I, + &priv->dtim_period); + /* * Bit 0 in tx_htinfo indicates that current Tx rate is 11n rate. Valid * MCS index values for us are 0 to 7. @@ -573,8 +578,7 @@ mwifiex_dump_station_info(struct mwifiex_private *priv, WLAN_CAPABILITY_SHORT_SLOT_TIME) sinfo->bss_param.flags |= BSS_PARAM_FLAGS_SHORT_SLOT_TIME; - sinfo->bss_param.dtim_period = - priv->curr_bss_params.bss_descriptor.dtim_period; + sinfo->bss_param.dtim_period = priv->dtim_period; sinfo->bss_param.beacon_interval = priv->curr_bss_params.bss_descriptor.beacon_period; } diff --git a/drivers/net/wireless/mwifiex/main.h b/drivers/net/wireless/mwifiex/main.h index 3dc0f721c1db..52810b1497ea 100644 --- a/drivers/net/wireless/mwifiex/main.h +++ b/drivers/net/wireless/mwifiex/main.h @@ -249,7 +249,6 @@ struct mwifiex_bssdescriptor { u32 channel; u32 freq; u16 beacon_period; - u8 dtim_period; u8 erp_flags; u32 bss_mode; u8 supported_rates[MWIFIEX_SUPPORTED_RATES]; @@ -392,6 +391,7 @@ struct mwifiex_private { u8 prev_bssid[ETH_ALEN]; struct mwifiex_current_bss_params curr_bss_params; u16 beacon_period; + u8 dtim_period; u16 listen_interval; u16 atim_window; u8 adhoc_channel; diff --git a/drivers/net/wireless/mwifiex/scan.c b/drivers/net/wireless/mwifiex/scan.c index 135208596aff..98f1ca9cd6d8 100644 --- a/drivers/net/wireless/mwifiex/scan.c +++ b/drivers/net/wireless/mwifiex/scan.c @@ -1086,7 +1086,6 @@ mwifiex_update_bss_desc_with_ie(struct mwifiex_adapter *adapter, struct ieee_types_vendor_specific *vendor_ie; const u8 wpa_oui[4] = { 0x00, 0x50, 0xf2, 0x01 }; const u8 wmm_oui[4] = { 0x00, 0x50, 0xf2, 0x02 }; - struct ieee80211_tim_ie *tim_ie; found_data_rate_ie = false; rate_size = 0; @@ -1259,11 +1258,6 @@ mwifiex_update_bss_desc_with_ie(struct mwifiex_adapter *adapter, sizeof(struct ieee_types_header) - bss_entry->beacon_buf); break; - case WLAN_EID_TIM: - tim_ie = (void *) (current_ptr + - sizeof(struct ieee_types_header)); - bss_entry->dtim_period = tim_ie->dtim_period; - break; default: break; } diff --git a/drivers/net/wireless/mwifiex/sta_cmdresp.c b/drivers/net/wireless/mwifiex/sta_cmdresp.c index e812db8b695c..0d8618a8443f 100644 --- a/drivers/net/wireless/mwifiex/sta_cmdresp.c +++ b/drivers/net/wireless/mwifiex/sta_cmdresp.c @@ -210,6 +210,9 @@ static int mwifiex_ret_802_11_snmp_mib(struct mwifiex_private *priv, dev_dbg(priv->adapter->dev, "info: SNMP_RESP: TxRetryCount=%u\n", ul_temp); break; + case DTIM_PERIOD_I: + dev_dbg(priv->adapter->dev, + "info: SNMP_RESP: DTIM period=%u\n", ul_temp); default: break; } -- cgit v1.2.2 From 6670f15b1f6858a43b292d8ab64464e9f085a6aa Mon Sep 17 00:00:00 2001 From: Amitkumar Karwar Date: Thu, 9 Feb 2012 18:32:22 -0800 Subject: mwifiex: clear previous security setting during association Driver maintains different flags for WEP, WPA, WPA2 security modes. Appropriate flag is set using security information provided in connect request. mwifiex_is_network_compatible() routine uses them to check if driver's setting is compatible with AP. Association is aborted if the routine fails. For some corner cases, it is observed that association is failed even for valid security information based on association history. This patch fixes the problem by clearing previous security setting during each association. We should set WEP key provided in connect request as default tx key. This missing change is also added here. Signed-off-by: Amitkumar Karwar Signed-off-by: Bing Zhao Signed-off-by: John W. Linville --- drivers/net/wireless/mwifiex/cfg80211.c | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) (limited to 'drivers/net/wireless/mwifiex') diff --git a/drivers/net/wireless/mwifiex/cfg80211.c b/drivers/net/wireless/mwifiex/cfg80211.c index c3b6c4652cd6..5b2972b43b0e 100644 --- a/drivers/net/wireless/mwifiex/cfg80211.c +++ b/drivers/net/wireless/mwifiex/cfg80211.c @@ -841,7 +841,12 @@ mwifiex_cfg80211_assoc(struct mwifiex_private *priv, size_t ssid_len, u8 *ssid, ret = mwifiex_set_rf_channel(priv, channel, priv->adapter->channel_type); - ret = mwifiex_set_encode(priv, NULL, 0, 0, 1); /* Disable keys */ + /* As this is new association, clear locally stored + * keys and security related flags */ + priv->sec_info.wpa_enabled = false; + priv->sec_info.wpa2_enabled = false; + priv->wep_key_curr_index = 0; + ret = mwifiex_set_encode(priv, NULL, 0, 0, 1); if (mode == NL80211_IFTYPE_ADHOC) { /* "privacy" is set only for ad-hoc mode */ @@ -886,6 +891,7 @@ mwifiex_cfg80211_assoc(struct mwifiex_private *priv, size_t ssid_len, u8 *ssid, dev_dbg(priv->adapter->dev, "info: setting wep encryption" " with key len %d\n", sme->key_len); + priv->wep_key_curr_index = sme->key_idx; ret = mwifiex_set_encode(priv, sme->key, sme->key_len, sme->key_idx, 0); } -- cgit v1.2.2