aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/wireless/rndis_wlan.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/net/wireless/rndis_wlan.c')
-rw-r--r--drivers/net/wireless/rndis_wlan.c86
1 files changed, 45 insertions, 41 deletions
diff --git a/drivers/net/wireless/rndis_wlan.c b/drivers/net/wireless/rndis_wlan.c
index 620e3c0e88e0..3802c31fefcd 100644
--- a/drivers/net/wireless/rndis_wlan.c
+++ b/drivers/net/wireless/rndis_wlan.c
@@ -244,6 +244,10 @@ enum ndis_80211_power_mode {
244 NDIS_80211_POWER_MODE_FAST_PSP, 244 NDIS_80211_POWER_MODE_FAST_PSP,
245}; 245};
246 246
247enum ndis_80211_pmkid_cand_list_flag_bits {
248 NDIS_80211_PMKID_CAND_PREAUTH = cpu_to_le32(1 << 0)
249};
250
247struct ndis_80211_auth_request { 251struct ndis_80211_auth_request {
248 __le32 length; 252 __le32 length;
249 u8 bssid[6]; 253 u8 bssid[6];
@@ -387,19 +391,17 @@ struct ndis_80211_capability {
387struct ndis_80211_bssid_info { 391struct ndis_80211_bssid_info {
388 u8 bssid[6]; 392 u8 bssid[6];
389 u8 pmkid[16]; 393 u8 pmkid[16];
390}; 394} __packed;
391 395
392struct ndis_80211_pmkid { 396struct ndis_80211_pmkid {
393 __le32 length; 397 __le32 length;
394 __le32 bssid_info_count; 398 __le32 bssid_info_count;
395 struct ndis_80211_bssid_info bssid_info[0]; 399 struct ndis_80211_bssid_info bssid_info[0];
396}; 400} __packed;
397 401
398/* 402/*
399 * private data 403 * private data
400 */ 404 */
401#define NET_TYPE_11FB 0
402
403#define CAP_MODE_80211A 1 405#define CAP_MODE_80211A 1
404#define CAP_MODE_80211B 2 406#define CAP_MODE_80211B 2
405#define CAP_MODE_80211G 4 407#define CAP_MODE_80211G 4
@@ -1347,6 +1349,32 @@ static int set_channel(struct usbnet *usbdev, int channel)
1347 return ret; 1349 return ret;
1348} 1350}
1349 1351
1352static struct ieee80211_channel *get_current_channel(struct usbnet *usbdev,
1353 u16 *beacon_interval)
1354{
1355 struct rndis_wlan_private *priv = get_rndis_wlan_priv(usbdev);
1356 struct ieee80211_channel *channel;
1357 struct ndis_80211_conf config;
1358 int len, ret;
1359
1360 /* Get channel and beacon interval */
1361 len = sizeof(config);
1362 ret = rndis_query_oid(usbdev, OID_802_11_CONFIGURATION, &config, &len);
1363 netdev_dbg(usbdev->net, "%s(): OID_802_11_CONFIGURATION -> %d\n",
1364 __func__, ret);
1365 if (ret < 0)
1366 return NULL;
1367
1368 channel = ieee80211_get_channel(priv->wdev.wiphy,
1369 KHZ_TO_MHZ(le32_to_cpu(config.ds_config)));
1370 if (!channel)
1371 return NULL;
1372
1373 if (beacon_interval)
1374 *beacon_interval = le16_to_cpu(config.beacon_period);
1375 return channel;
1376}
1377
1350/* index must be 0 - N, as per NDIS */ 1378/* index must be 0 - N, as per NDIS */
1351static int add_wep_key(struct usbnet *usbdev, const u8 *key, int key_len, 1379static int add_wep_key(struct usbnet *usbdev, const u8 *key, int key_len,
1352 int index) 1380 int index)
@@ -2650,13 +2678,12 @@ static void rndis_wlan_craft_connected_bss(struct usbnet *usbdev, u8 *bssid,
2650{ 2678{
2651 struct rndis_wlan_private *priv = get_rndis_wlan_priv(usbdev); 2679 struct rndis_wlan_private *priv = get_rndis_wlan_priv(usbdev);
2652 struct ieee80211_channel *channel; 2680 struct ieee80211_channel *channel;
2653 struct ndis_80211_conf config;
2654 struct ndis_80211_ssid ssid; 2681 struct ndis_80211_ssid ssid;
2655 struct cfg80211_bss *bss; 2682 struct cfg80211_bss *bss;
2656 s32 signal; 2683 s32 signal;
2657 u64 timestamp; 2684 u64 timestamp;
2658 u16 capability; 2685 u16 capability;
2659 u16 beacon_interval; 2686 u16 beacon_interval = 0;
2660 __le32 rssi; 2687 __le32 rssi;
2661 u8 ie_buf[34]; 2688 u8 ie_buf[34];
2662 int len, ret, ie_len; 2689 int len, ret, ie_len;
@@ -2681,22 +2708,10 @@ static void rndis_wlan_craft_connected_bss(struct usbnet *usbdev, u8 *bssid,
2681 } 2708 }
2682 2709
2683 /* Get channel and beacon interval */ 2710 /* Get channel and beacon interval */
2684 len = sizeof(config); 2711 channel = get_current_channel(usbdev, &beacon_interval);
2685 ret = rndis_query_oid(usbdev, OID_802_11_CONFIGURATION, &config, &len); 2712 if (!channel) {
2686 netdev_dbg(usbdev->net, "%s(): OID_802_11_CONFIGURATION -> %d\n", 2713 netdev_warn(usbdev->net, "%s(): could not get channel.\n",
2687 __func__, ret); 2714 __func__);
2688 if (ret >= 0) {
2689 beacon_interval = le16_to_cpu(config.beacon_period);
2690 channel = ieee80211_get_channel(priv->wdev.wiphy,
2691 KHZ_TO_MHZ(le32_to_cpu(config.ds_config)));
2692 if (!channel) {
2693 netdev_warn(usbdev->net, "%s(): could not get channel."
2694 "\n", __func__);
2695 return;
2696 }
2697 } else {
2698 netdev_warn(usbdev->net, "%s(): could not get configuration.\n",
2699 __func__);
2700 return; 2715 return;
2701 } 2716 }
2702 2717
@@ -2841,8 +2856,9 @@ static void rndis_wlan_do_link_up_work(struct usbnet *usbdev)
2841 req_ie_len, resp_ie, 2856 req_ie_len, resp_ie,
2842 resp_ie_len, 0, GFP_KERNEL); 2857 resp_ie_len, 0, GFP_KERNEL);
2843 else 2858 else
2844 cfg80211_roamed(usbdev->net, NULL, bssid, 2859 cfg80211_roamed(usbdev->net,
2845 req_ie, req_ie_len, 2860 get_current_channel(usbdev, NULL),
2861 bssid, req_ie, req_ie_len,
2846 resp_ie, resp_ie_len, GFP_KERNEL); 2862 resp_ie, resp_ie_len, GFP_KERNEL);
2847 } else if (priv->infra_mode == NDIS_80211_INFRA_ADHOC) 2863 } else if (priv->infra_mode == NDIS_80211_INFRA_ADHOC)
2848 cfg80211_ibss_joined(usbdev->net, bssid, GFP_KERNEL); 2864 cfg80211_ibss_joined(usbdev->net, bssid, GFP_KERNEL);
@@ -3008,25 +3024,13 @@ static void rndis_wlan_pmkid_cand_list_indication(struct usbnet *usbdev,
3008 for (i = 0; i < le32_to_cpu(cand_list->num_candidates); i++) { 3024 for (i = 0; i < le32_to_cpu(cand_list->num_candidates); i++) {
3009 struct ndis_80211_pmkid_candidate *cand = 3025 struct ndis_80211_pmkid_candidate *cand =
3010 &cand_list->candidate_list[i]; 3026 &cand_list->candidate_list[i];
3027 bool preauth = !!(cand->flags & NDIS_80211_PMKID_CAND_PREAUTH);
3011 3028
3012 netdev_dbg(usbdev->net, "cand[%i]: flags: 0x%08x, bssid: %pM\n", 3029 netdev_dbg(usbdev->net, "cand[%i]: flags: 0x%08x, preauth: %d, bssid: %pM\n",
3013 i, le32_to_cpu(cand->flags), cand->bssid); 3030 i, le32_to_cpu(cand->flags), preauth, cand->bssid);
3014
3015#if 0
3016 struct iw_pmkid_cand pcand;
3017 union iwreq_data wrqu;
3018 3031
3019 memset(&pcand, 0, sizeof(pcand)); 3032 cfg80211_pmksa_candidate_notify(usbdev->net, i, cand->bssid,
3020 if (le32_to_cpu(cand->flags) & 0x01) 3033 preauth, GFP_ATOMIC);
3021 pcand.flags |= IW_PMKID_CAND_PREAUTH;
3022 pcand.index = i;
3023 memcpy(pcand.bssid.sa_data, cand->bssid, ETH_ALEN);
3024
3025 memset(&wrqu, 0, sizeof(wrqu));
3026 wrqu.data.length = sizeof(pcand);
3027 wireless_send_event(usbdev->net, IWEVPMKIDCAND, &wrqu,
3028 (u8 *)&pcand);
3029#endif
3030 } 3034 }
3031} 3035}
3032 3036