diff options
Diffstat (limited to 'drivers/net/wireless/mwifiex/sta_ioctl.c')
-rw-r--r-- | drivers/net/wireless/mwifiex/sta_ioctl.c | 87 |
1 files changed, 58 insertions, 29 deletions
diff --git a/drivers/net/wireless/mwifiex/sta_ioctl.c b/drivers/net/wireless/mwifiex/sta_ioctl.c index 8ba58d935328..58970e0f7d13 100644 --- a/drivers/net/wireless/mwifiex/sta_ioctl.c +++ b/drivers/net/wireless/mwifiex/sta_ioctl.c | |||
@@ -155,20 +155,29 @@ int mwifiex_request_set_multicast_list(struct mwifiex_private *priv, | |||
155 | * information. | 155 | * information. |
156 | */ | 156 | */ |
157 | int mwifiex_fill_new_bss_desc(struct mwifiex_private *priv, | 157 | int mwifiex_fill_new_bss_desc(struct mwifiex_private *priv, |
158 | u8 *bssid, s32 rssi, u8 *ie_buf, | 158 | struct cfg80211_bss *bss, |
159 | size_t ie_len, u16 beacon_period, | ||
160 | u16 cap_info_bitmap, u8 band, | ||
161 | struct mwifiex_bssdescriptor *bss_desc) | 159 | struct mwifiex_bssdescriptor *bss_desc) |
162 | { | 160 | { |
163 | int ret; | 161 | int ret; |
162 | u8 *beacon_ie; | ||
163 | struct mwifiex_bss_priv *bss_priv = (void *)bss->priv; | ||
164 | 164 | ||
165 | memcpy(bss_desc->mac_address, bssid, ETH_ALEN); | 165 | beacon_ie = kmemdup(bss->information_elements, bss->len_beacon_ies, |
166 | bss_desc->rssi = rssi; | 166 | GFP_KERNEL); |
167 | bss_desc->beacon_buf = ie_buf; | 167 | if (!beacon_ie) { |
168 | bss_desc->beacon_buf_size = ie_len; | 168 | dev_err(priv->adapter->dev, " failed to alloc beacon_ie\n"); |
169 | bss_desc->beacon_period = beacon_period; | 169 | return -ENOMEM; |
170 | bss_desc->cap_info_bitmap = cap_info_bitmap; | 170 | } |
171 | bss_desc->bss_band = band; | 171 | |
172 | memcpy(bss_desc->mac_address, bss->bssid, ETH_ALEN); | ||
173 | bss_desc->rssi = bss->signal; | ||
174 | bss_desc->beacon_buf = beacon_ie; | ||
175 | bss_desc->beacon_buf_size = bss->len_beacon_ies; | ||
176 | bss_desc->beacon_period = bss->beacon_interval; | ||
177 | bss_desc->cap_info_bitmap = bss->capability; | ||
178 | bss_desc->bss_band = bss_priv->band; | ||
179 | bss_desc->fw_tsf = bss_priv->fw_tsf; | ||
180 | bss_desc->timestamp = bss->tsf; | ||
172 | if (bss_desc->cap_info_bitmap & WLAN_CAPABILITY_PRIVACY) { | 181 | if (bss_desc->cap_info_bitmap & WLAN_CAPABILITY_PRIVACY) { |
173 | dev_dbg(priv->adapter->dev, "info: InterpretIE: AP WEP enabled\n"); | 182 | dev_dbg(priv->adapter->dev, "info: InterpretIE: AP WEP enabled\n"); |
174 | bss_desc->privacy = MWIFIEX_802_11_PRIV_FILTER_8021X_WEP; | 183 | bss_desc->privacy = MWIFIEX_802_11_PRIV_FILTER_8021X_WEP; |
@@ -180,9 +189,9 @@ int mwifiex_fill_new_bss_desc(struct mwifiex_private *priv, | |||
180 | else | 189 | else |
181 | bss_desc->bss_mode = NL80211_IFTYPE_STATION; | 190 | bss_desc->bss_mode = NL80211_IFTYPE_STATION; |
182 | 191 | ||
183 | ret = mwifiex_update_bss_desc_with_ie(priv->adapter, bss_desc, | 192 | ret = mwifiex_update_bss_desc_with_ie(priv->adapter, bss_desc); |
184 | ie_buf, ie_len); | ||
185 | 193 | ||
194 | kfree(beacon_ie); | ||
186 | return ret; | 195 | return ret; |
187 | } | 196 | } |
188 | 197 | ||
@@ -197,7 +206,6 @@ int mwifiex_bss_start(struct mwifiex_private *priv, struct cfg80211_bss *bss, | |||
197 | int ret; | 206 | int ret; |
198 | struct mwifiex_adapter *adapter = priv->adapter; | 207 | struct mwifiex_adapter *adapter = priv->adapter; |
199 | struct mwifiex_bssdescriptor *bss_desc = NULL; | 208 | struct mwifiex_bssdescriptor *bss_desc = NULL; |
200 | u8 *beacon_ie = NULL; | ||
201 | 209 | ||
202 | priv->scan_block = false; | 210 | priv->scan_block = false; |
203 | 211 | ||
@@ -210,19 +218,7 @@ int mwifiex_bss_start(struct mwifiex_private *priv, struct cfg80211_bss *bss, | |||
210 | return -ENOMEM; | 218 | return -ENOMEM; |
211 | } | 219 | } |
212 | 220 | ||
213 | beacon_ie = kmemdup(bss->information_elements, | 221 | ret = mwifiex_fill_new_bss_desc(priv, bss, bss_desc); |
214 | bss->len_beacon_ies, GFP_KERNEL); | ||
215 | if (!beacon_ie) { | ||
216 | kfree(bss_desc); | ||
217 | dev_err(priv->adapter->dev, " failed to alloc beacon_ie\n"); | ||
218 | return -ENOMEM; | ||
219 | } | ||
220 | |||
221 | ret = mwifiex_fill_new_bss_desc(priv, bss->bssid, bss->signal, | ||
222 | beacon_ie, bss->len_beacon_ies, | ||
223 | bss->beacon_interval, | ||
224 | bss->capability, | ||
225 | *(u8 *)bss->priv, bss_desc); | ||
226 | if (ret) | 222 | if (ret) |
227 | goto done; | 223 | goto done; |
228 | } | 224 | } |
@@ -269,7 +265,6 @@ int mwifiex_bss_start(struct mwifiex_private *priv, struct cfg80211_bss *bss, | |||
269 | (!mwifiex_ssid_cmp(&priv->curr_bss_params.bss_descriptor. | 265 | (!mwifiex_ssid_cmp(&priv->curr_bss_params.bss_descriptor. |
270 | ssid, &bss_desc->ssid))) { | 266 | ssid, &bss_desc->ssid))) { |
271 | kfree(bss_desc); | 267 | kfree(bss_desc); |
272 | kfree(beacon_ie); | ||
273 | return 0; | 268 | return 0; |
274 | } | 269 | } |
275 | 270 | ||
@@ -304,7 +299,6 @@ int mwifiex_bss_start(struct mwifiex_private *priv, struct cfg80211_bss *bss, | |||
304 | 299 | ||
305 | done: | 300 | done: |
306 | kfree(bss_desc); | 301 | kfree(bss_desc); |
307 | kfree(beacon_ie); | ||
308 | return ret; | 302 | return ret; |
309 | } | 303 | } |
310 | 304 | ||
@@ -468,7 +462,8 @@ int mwifiex_get_bss_info(struct mwifiex_private *priv, | |||
468 | 462 | ||
469 | info->bss_chan = bss_desc->channel; | 463 | info->bss_chan = bss_desc->channel; |
470 | 464 | ||
471 | info->region_code = adapter->region_code; | 465 | memcpy(info->country_code, priv->country_code, |
466 | IEEE80211_COUNTRY_STRING_LEN); | ||
472 | 467 | ||
473 | info->media_connected = priv->media_connected; | 468 | info->media_connected = priv->media_connected; |
474 | 469 | ||
@@ -996,6 +991,39 @@ static int mwifiex_set_wapi_ie(struct mwifiex_private *priv, | |||
996 | } | 991 | } |
997 | 992 | ||
998 | /* | 993 | /* |
994 | * IOCTL request handler to set/reset WPS IE. | ||
995 | * | ||
996 | * The supplied WPS IE is treated as a opaque buffer. Only the first field | ||
997 | * is checked to internally enable WPS. If buffer length is zero, the existing | ||
998 | * WPS IE is reset. | ||
999 | */ | ||
1000 | static int mwifiex_set_wps_ie(struct mwifiex_private *priv, | ||
1001 | u8 *ie_data_ptr, u16 ie_len) | ||
1002 | { | ||
1003 | if (ie_len) { | ||
1004 | priv->wps_ie = kzalloc(MWIFIEX_MAX_VSIE_LEN, GFP_KERNEL); | ||
1005 | if (!priv->wps_ie) | ||
1006 | return -ENOMEM; | ||
1007 | if (ie_len > sizeof(priv->wps_ie)) { | ||
1008 | dev_dbg(priv->adapter->dev, | ||
1009 | "info: failed to copy WPS IE, too big\n"); | ||
1010 | kfree(priv->wps_ie); | ||
1011 | return -1; | ||
1012 | } | ||
1013 | memcpy(priv->wps_ie, ie_data_ptr, ie_len); | ||
1014 | priv->wps_ie_len = ie_len; | ||
1015 | dev_dbg(priv->adapter->dev, "cmd: Set wps_ie_len=%d IE=%#x\n", | ||
1016 | priv->wps_ie_len, priv->wps_ie[0]); | ||
1017 | } else { | ||
1018 | kfree(priv->wps_ie); | ||
1019 | priv->wps_ie_len = ie_len; | ||
1020 | dev_dbg(priv->adapter->dev, | ||
1021 | "info: Reset wps_ie_len=%d\n", priv->wps_ie_len); | ||
1022 | } | ||
1023 | return 0; | ||
1024 | } | ||
1025 | |||
1026 | /* | ||
999 | * IOCTL request handler to set WAPI key. | 1027 | * IOCTL request handler to set WAPI key. |
1000 | * | 1028 | * |
1001 | * This function prepares the correct firmware command and | 1029 | * This function prepares the correct firmware command and |
@@ -1408,6 +1436,7 @@ mwifiex_set_gen_ie_helper(struct mwifiex_private *priv, u8 *ie_data_ptr, | |||
1408 | priv->wps.session_enable = true; | 1436 | priv->wps.session_enable = true; |
1409 | dev_dbg(priv->adapter->dev, | 1437 | dev_dbg(priv->adapter->dev, |
1410 | "info: WPS Session Enabled.\n"); | 1438 | "info: WPS Session Enabled.\n"); |
1439 | ret = mwifiex_set_wps_ie(priv, ie_data_ptr, ie_len); | ||
1411 | } | 1440 | } |
1412 | 1441 | ||
1413 | /* Append the passed data to the end of the | 1442 | /* Append the passed data to the end of the |