summaryrefslogtreecommitdiffstats
path: root/drivers/net/wireless/mwifiex/sta_ioctl.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/net/wireless/mwifiex/sta_ioctl.c')
-rw-r--r--drivers/net/wireless/mwifiex/sta_ioctl.c87
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