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 8ba58d93532..58970e0f7d1 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, * information. */ int mwifiex_fill_new_bss_desc(struct mwifiex_private *priv, - u8 *bssid, s32 rssi, u8 *ie_buf, - size_t ie_len, u16 beacon_period, - u16 cap_info_bitmap, u8 band, + struct cfg80211_bss *bss, struct mwifiex_bssdescriptor *bss_desc) { int ret; + u8 *beacon_ie; + struct mwifiex_bss_priv *bss_priv = (void *)bss->priv; - memcpy(bss_desc->mac_address, bssid, ETH_ALEN); - bss_desc->rssi = rssi; - bss_desc->beacon_buf = ie_buf; - bss_desc->beacon_buf_size = ie_len; - bss_desc->beacon_period = beacon_period; - bss_desc->cap_info_bitmap = cap_info_bitmap; - bss_desc->bss_band = band; + beacon_ie = kmemdup(bss->information_elements, bss->len_beacon_ies, + GFP_KERNEL); + if (!beacon_ie) { + dev_err(priv->adapter->dev, " failed to alloc beacon_ie\n"); + return -ENOMEM; + } + + memcpy(bss_desc->mac_address, bss->bssid, ETH_ALEN); + bss_desc->rssi = bss->signal; + bss_desc->beacon_buf = beacon_ie; + bss_desc->beacon_buf_size = bss->len_beacon_ies; + bss_desc->beacon_period = bss->beacon_interval; + bss_desc->cap_info_bitmap = bss->capability; + bss_desc->bss_band = bss_priv->band; + bss_desc->fw_tsf = bss_priv->fw_tsf; + bss_desc->timestamp = bss->tsf; if (bss_desc->cap_info_bitmap & WLAN_CAPABILITY_PRIVACY) { dev_dbg(priv->adapter->dev, "info: InterpretIE: AP WEP enabled\n"); bss_desc->privacy = MWIFIEX_802_11_PRIV_FILTER_8021X_WEP; @@ -180,9 +189,9 @@ int mwifiex_fill_new_bss_desc(struct mwifiex_private *priv, else bss_desc->bss_mode = NL80211_IFTYPE_STATION; - ret = mwifiex_update_bss_desc_with_ie(priv->adapter, bss_desc, - ie_buf, ie_len); + ret = mwifiex_update_bss_desc_with_ie(priv->adapter, bss_desc); + kfree(beacon_ie); return ret; } @@ -197,7 +206,6 @@ int mwifiex_bss_start(struct mwifiex_private *priv, struct cfg80211_bss *bss, int ret; struct mwifiex_adapter *adapter = priv->adapter; struct mwifiex_bssdescriptor *bss_desc = NULL; - u8 *beacon_ie = NULL; priv->scan_block = false; @@ -210,19 +218,7 @@ int mwifiex_bss_start(struct mwifiex_private *priv, struct cfg80211_bss *bss, return -ENOMEM; } - beacon_ie = kmemdup(bss->information_elements, - bss->len_beacon_ies, GFP_KERNEL); - if (!beacon_ie) { - kfree(bss_desc); - dev_err(priv->adapter->dev, " failed to alloc beacon_ie\n"); - return -ENOMEM; - } - - ret = mwifiex_fill_new_bss_desc(priv, bss->bssid, bss->signal, - beacon_ie, bss->len_beacon_ies, - bss->beacon_interval, - bss->capability, - *(u8 *)bss->priv, bss_desc); + ret = mwifiex_fill_new_bss_desc(priv, bss, bss_desc); if (ret) goto done; } @@ -269,7 +265,6 @@ int mwifiex_bss_start(struct mwifiex_private *priv, struct cfg80211_bss *bss, (!mwifiex_ssid_cmp(&priv->curr_bss_params.bss_descriptor. ssid, &bss_desc->ssid))) { kfree(bss_desc); - kfree(beacon_ie); return 0; } @@ -304,7 +299,6 @@ int mwifiex_bss_start(struct mwifiex_private *priv, struct cfg80211_bss *bss, done: kfree(bss_desc); - kfree(beacon_ie); return ret; } @@ -468,7 +462,8 @@ int mwifiex_get_bss_info(struct mwifiex_private *priv, info->bss_chan = bss_desc->channel; - info->region_code = adapter->region_code; + memcpy(info->country_code, priv->country_code, + IEEE80211_COUNTRY_STRING_LEN); info->media_connected = priv->media_connected; @@ -996,6 +991,39 @@ static int mwifiex_set_wapi_ie(struct mwifiex_private *priv, } /* + * IOCTL request handler to set/reset WPS IE. + * + * The supplied WPS IE is treated as a opaque buffer. Only the first field + * is checked to internally enable WPS. If buffer length is zero, the existing + * WPS IE is reset. + */ +static int mwifiex_set_wps_ie(struct mwifiex_private *priv, + u8 *ie_data_ptr, u16 ie_len) +{ + if (ie_len) { + priv->wps_ie = kzalloc(MWIFIEX_MAX_VSIE_LEN, GFP_KERNEL); + if (!priv->wps_ie) + return -ENOMEM; + if (ie_len > sizeof(priv->wps_ie)) { + dev_dbg(priv->adapter->dev, + "info: failed to copy WPS IE, too big\n"); + kfree(priv->wps_ie); + return -1; + } + memcpy(priv->wps_ie, ie_data_ptr, ie_len); + priv->wps_ie_len = ie_len; + dev_dbg(priv->adapter->dev, "cmd: Set wps_ie_len=%d IE=%#x\n", + priv->wps_ie_len, priv->wps_ie[0]); + } else { + kfree(priv->wps_ie); + priv->wps_ie_len = ie_len; + dev_dbg(priv->adapter->dev, + "info: Reset wps_ie_len=%d\n", priv->wps_ie_len); + } + return 0; +} + +/* * IOCTL request handler to set WAPI key. * * 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, priv->wps.session_enable = true; dev_dbg(priv->adapter->dev, "info: WPS Session Enabled.\n"); + ret = mwifiex_set_wps_ie(priv, ie_data_ptr, ie_len); } /* Append the passed data to the end of the |