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.c61
1 files changed, 34 insertions, 27 deletions
diff --git a/drivers/net/wireless/rndis_wlan.c b/drivers/net/wireless/rndis_wlan.c
index a330c69583d6..d66e2980bc27 100644
--- a/drivers/net/wireless/rndis_wlan.c
+++ b/drivers/net/wireless/rndis_wlan.c
@@ -518,7 +518,7 @@ struct rndis_wlan_private {
518 __le32 current_command_oid; 518 __le32 current_command_oid;
519 519
520 /* encryption stuff */ 520 /* encryption stuff */
521 int encr_tx_key_index; 521 u8 encr_tx_key_index;
522 struct rndis_wlan_encr_key encr_keys[RNDIS_WLAN_NUM_KEYS]; 522 struct rndis_wlan_encr_key encr_keys[RNDIS_WLAN_NUM_KEYS];
523 int wpa_version; 523 int wpa_version;
524 524
@@ -634,7 +634,7 @@ static u32 get_bcm4320_power_dbm(struct rndis_wlan_private *priv)
634 } 634 }
635} 635}
636 636
637static bool is_wpa_key(struct rndis_wlan_private *priv, int idx) 637static bool is_wpa_key(struct rndis_wlan_private *priv, u8 idx)
638{ 638{
639 int cipher = priv->encr_keys[idx].cipher; 639 int cipher = priv->encr_keys[idx].cipher;
640 640
@@ -1350,7 +1350,7 @@ static int set_channel(struct usbnet *usbdev, int channel)
1350} 1350}
1351 1351
1352static struct ieee80211_channel *get_current_channel(struct usbnet *usbdev, 1352static struct ieee80211_channel *get_current_channel(struct usbnet *usbdev,
1353 u16 *beacon_interval) 1353 u32 *beacon_period)
1354{ 1354{
1355 struct rndis_wlan_private *priv = get_rndis_wlan_priv(usbdev); 1355 struct rndis_wlan_private *priv = get_rndis_wlan_priv(usbdev);
1356 struct ieee80211_channel *channel; 1356 struct ieee80211_channel *channel;
@@ -1370,14 +1370,14 @@ static struct ieee80211_channel *get_current_channel(struct usbnet *usbdev,
1370 if (!channel) 1370 if (!channel)
1371 return NULL; 1371 return NULL;
1372 1372
1373 if (beacon_interval) 1373 if (beacon_period)
1374 *beacon_interval = le16_to_cpu(config.beacon_period); 1374 *beacon_period = le32_to_cpu(config.beacon_period);
1375 return channel; 1375 return channel;
1376} 1376}
1377 1377
1378/* index must be 0 - N, as per NDIS */ 1378/* index must be 0 - N, as per NDIS */
1379static 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,
1380 int index) 1380 u8 index)
1381{ 1381{
1382 struct rndis_wlan_private *priv = get_rndis_wlan_priv(usbdev); 1382 struct rndis_wlan_private *priv = get_rndis_wlan_priv(usbdev);
1383 struct ndis_80211_wep_key ndis_key; 1383 struct ndis_80211_wep_key ndis_key;
@@ -1387,13 +1387,15 @@ static int add_wep_key(struct usbnet *usbdev, const u8 *key, int key_len,
1387 netdev_dbg(usbdev->net, "%s(idx: %d, len: %d)\n", 1387 netdev_dbg(usbdev->net, "%s(idx: %d, len: %d)\n",
1388 __func__, index, key_len); 1388 __func__, index, key_len);
1389 1389
1390 if ((key_len != 5 && key_len != 13) || index < 0 || index > 3) 1390 if (index >= RNDIS_WLAN_NUM_KEYS)
1391 return -EINVAL; 1391 return -EINVAL;
1392 1392
1393 if (key_len == 5) 1393 if (key_len == 5)
1394 cipher = WLAN_CIPHER_SUITE_WEP40; 1394 cipher = WLAN_CIPHER_SUITE_WEP40;
1395 else 1395 else if (key_len == 13)
1396 cipher = WLAN_CIPHER_SUITE_WEP104; 1396 cipher = WLAN_CIPHER_SUITE_WEP104;
1397 else
1398 return -EINVAL;
1397 1399
1398 memset(&ndis_key, 0, sizeof(ndis_key)); 1400 memset(&ndis_key, 0, sizeof(ndis_key));
1399 1401
@@ -1428,7 +1430,7 @@ static int add_wep_key(struct usbnet *usbdev, const u8 *key, int key_len,
1428} 1430}
1429 1431
1430static int add_wpa_key(struct usbnet *usbdev, const u8 *key, int key_len, 1432static int add_wpa_key(struct usbnet *usbdev, const u8 *key, int key_len,
1431 int index, const u8 *addr, const u8 *rx_seq, 1433 u8 index, const u8 *addr, const u8 *rx_seq,
1432 int seq_len, u32 cipher, __le32 flags) 1434 int seq_len, u32 cipher, __le32 flags)
1433{ 1435{
1434 struct rndis_wlan_private *priv = get_rndis_wlan_priv(usbdev); 1436 struct rndis_wlan_private *priv = get_rndis_wlan_priv(usbdev);
@@ -1436,7 +1438,7 @@ static int add_wpa_key(struct usbnet *usbdev, const u8 *key, int key_len,
1436 bool is_addr_ok; 1438 bool is_addr_ok;
1437 int ret; 1439 int ret;
1438 1440
1439 if (index < 0 || index >= 4) { 1441 if (index >= RNDIS_WLAN_NUM_KEYS) {
1440 netdev_dbg(usbdev->net, "%s(): index out of range (%i)\n", 1442 netdev_dbg(usbdev->net, "%s(): index out of range (%i)\n",
1441 __func__, index); 1443 __func__, index);
1442 return -EINVAL; 1444 return -EINVAL;
@@ -1524,7 +1526,7 @@ static int add_wpa_key(struct usbnet *usbdev, const u8 *key, int key_len,
1524 return 0; 1526 return 0;
1525} 1527}
1526 1528
1527static int restore_key(struct usbnet *usbdev, int key_idx) 1529static int restore_key(struct usbnet *usbdev, u8 key_idx)
1528{ 1530{
1529 struct rndis_wlan_private *priv = get_rndis_wlan_priv(usbdev); 1531 struct rndis_wlan_private *priv = get_rndis_wlan_priv(usbdev);
1530 struct rndis_wlan_encr_key key; 1532 struct rndis_wlan_encr_key key;
@@ -1550,13 +1552,13 @@ static void restore_keys(struct usbnet *usbdev)
1550 restore_key(usbdev, i); 1552 restore_key(usbdev, i);
1551} 1553}
1552 1554
1553static void clear_key(struct rndis_wlan_private *priv, int idx) 1555static void clear_key(struct rndis_wlan_private *priv, u8 idx)
1554{ 1556{
1555 memset(&priv->encr_keys[idx], 0, sizeof(priv->encr_keys[idx])); 1557 memset(&priv->encr_keys[idx], 0, sizeof(priv->encr_keys[idx]));
1556} 1558}
1557 1559
1558/* remove_key is for both wep and wpa */ 1560/* remove_key is for both wep and wpa */
1559static int remove_key(struct usbnet *usbdev, int index, const u8 *bssid) 1561static int remove_key(struct usbnet *usbdev, u8 index, const u8 *bssid)
1560{ 1562{
1561 struct rndis_wlan_private *priv = get_rndis_wlan_priv(usbdev); 1563 struct rndis_wlan_private *priv = get_rndis_wlan_priv(usbdev);
1562 struct ndis_80211_remove_key remove_key; 1564 struct ndis_80211_remove_key remove_key;
@@ -1790,9 +1792,9 @@ static struct ndis_80211_pmkid *remove_pmkid(struct usbnet *usbdev,
1790 struct cfg80211_pmksa *pmksa, 1792 struct cfg80211_pmksa *pmksa,
1791 int max_pmkids) 1793 int max_pmkids)
1792{ 1794{
1793 int i, len, count, newlen, err; 1795 int i, newlen, err;
1796 unsigned int count;
1794 1797
1795 len = le32_to_cpu(pmkids->length);
1796 count = le32_to_cpu(pmkids->bssid_info_count); 1798 count = le32_to_cpu(pmkids->bssid_info_count);
1797 1799
1798 if (count > max_pmkids) 1800 if (count > max_pmkids)
@@ -1831,9 +1833,9 @@ static struct ndis_80211_pmkid *update_pmkid(struct usbnet *usbdev,
1831 struct cfg80211_pmksa *pmksa, 1833 struct cfg80211_pmksa *pmksa,
1832 int max_pmkids) 1834 int max_pmkids)
1833{ 1835{
1834 int i, err, len, count, newlen; 1836 int i, err, newlen;
1837 unsigned int count;
1835 1838
1836 len = le32_to_cpu(pmkids->length);
1837 count = le32_to_cpu(pmkids->bssid_info_count); 1839 count = le32_to_cpu(pmkids->bssid_info_count);
1838 1840
1839 if (count > max_pmkids) 1841 if (count > max_pmkids)
@@ -2683,7 +2685,7 @@ static void rndis_wlan_craft_connected_bss(struct usbnet *usbdev, u8 *bssid,
2683 s32 signal; 2685 s32 signal;
2684 u64 timestamp; 2686 u64 timestamp;
2685 u16 capability; 2687 u16 capability;
2686 u16 beacon_interval = 0; 2688 u32 beacon_period = 0;
2687 __le32 rssi; 2689 __le32 rssi;
2688 u8 ie_buf[34]; 2690 u8 ie_buf[34];
2689 int len, ret, ie_len; 2691 int len, ret, ie_len;
@@ -2708,7 +2710,7 @@ static void rndis_wlan_craft_connected_bss(struct usbnet *usbdev, u8 *bssid,
2708 } 2710 }
2709 2711
2710 /* Get channel and beacon interval */ 2712 /* Get channel and beacon interval */
2711 channel = get_current_channel(usbdev, &beacon_interval); 2713 channel = get_current_channel(usbdev, &beacon_period);
2712 if (!channel) { 2714 if (!channel) {
2713 netdev_warn(usbdev->net, "%s(): could not get channel.\n", 2715 netdev_warn(usbdev->net, "%s(): could not get channel.\n",
2714 __func__); 2716 __func__);
@@ -2738,11 +2740,11 @@ static void rndis_wlan_craft_connected_bss(struct usbnet *usbdev, u8 *bssid,
2738 netdev_dbg(usbdev->net, "%s(): channel:%d(freq), bssid:[%pM], tsf:%d, " 2740 netdev_dbg(usbdev->net, "%s(): channel:%d(freq), bssid:[%pM], tsf:%d, "
2739 "capa:%x, beacon int:%d, resp_ie(len:%d, essid:'%.32s'), " 2741 "capa:%x, beacon int:%d, resp_ie(len:%d, essid:'%.32s'), "
2740 "signal:%d\n", __func__, (channel ? channel->center_freq : -1), 2742 "signal:%d\n", __func__, (channel ? channel->center_freq : -1),
2741 bssid, (u32)timestamp, capability, beacon_interval, ie_len, 2743 bssid, (u32)timestamp, capability, beacon_period, ie_len,
2742 ssid.essid, signal); 2744 ssid.essid, signal);
2743 2745
2744 bss = cfg80211_inform_bss(priv->wdev.wiphy, channel, bssid, 2746 bss = cfg80211_inform_bss(priv->wdev.wiphy, channel, bssid,
2745 timestamp, capability, beacon_interval, ie_buf, ie_len, 2747 timestamp, capability, beacon_period, ie_buf, ie_len,
2746 signal, GFP_KERNEL); 2748 signal, GFP_KERNEL);
2747 cfg80211_put_bss(bss); 2749 cfg80211_put_bss(bss);
2748} 2750}
@@ -2755,9 +2757,10 @@ static void rndis_wlan_do_link_up_work(struct usbnet *usbdev)
2755 struct rndis_wlan_private *priv = get_rndis_wlan_priv(usbdev); 2757 struct rndis_wlan_private *priv = get_rndis_wlan_priv(usbdev);
2756 struct ndis_80211_assoc_info *info = NULL; 2758 struct ndis_80211_assoc_info *info = NULL;
2757 u8 bssid[ETH_ALEN]; 2759 u8 bssid[ETH_ALEN];
2758 int resp_ie_len, req_ie_len; 2760 unsigned int resp_ie_len, req_ie_len;
2761 unsigned int offset;
2759 u8 *req_ie, *resp_ie; 2762 u8 *req_ie, *resp_ie;
2760 int ret, offset; 2763 int ret;
2761 bool roamed = false; 2764 bool roamed = false;
2762 bool match_bss; 2765 bool match_bss;
2763 2766
@@ -2785,7 +2788,9 @@ static void rndis_wlan_do_link_up_work(struct usbnet *usbdev)
2785 ret = get_association_info(usbdev, info, CONTROL_BUFFER_SIZE); 2788 ret = get_association_info(usbdev, info, CONTROL_BUFFER_SIZE);
2786 if (!ret) { 2789 if (!ret) {
2787 req_ie_len = le32_to_cpu(info->req_ie_length); 2790 req_ie_len = le32_to_cpu(info->req_ie_length);
2788 if (req_ie_len > 0) { 2791 if (req_ie_len > CONTROL_BUFFER_SIZE)
2792 req_ie_len = CONTROL_BUFFER_SIZE;
2793 if (req_ie_len != 0) {
2789 offset = le32_to_cpu(info->offset_req_ies); 2794 offset = le32_to_cpu(info->offset_req_ies);
2790 2795
2791 if (offset > CONTROL_BUFFER_SIZE) 2796 if (offset > CONTROL_BUFFER_SIZE)
@@ -2799,7 +2804,9 @@ static void rndis_wlan_do_link_up_work(struct usbnet *usbdev)
2799 } 2804 }
2800 2805
2801 resp_ie_len = le32_to_cpu(info->resp_ie_length); 2806 resp_ie_len = le32_to_cpu(info->resp_ie_length);
2802 if (resp_ie_len > 0) { 2807 if (resp_ie_len > CONTROL_BUFFER_SIZE)
2808 resp_ie_len = CONTROL_BUFFER_SIZE;
2809 if (resp_ie_len != 0) {
2803 offset = le32_to_cpu(info->offset_resp_ies); 2810 offset = le32_to_cpu(info->offset_resp_ies);
2804 2811
2805 if (offset > CONTROL_BUFFER_SIZE) 2812 if (offset > CONTROL_BUFFER_SIZE)
@@ -3038,7 +3045,7 @@ static void rndis_wlan_media_specific_indication(struct usbnet *usbdev,
3038 struct rndis_indicate *msg, int buflen) 3045 struct rndis_indicate *msg, int buflen)
3039{ 3046{
3040 struct ndis_80211_status_indication *indication; 3047 struct ndis_80211_status_indication *indication;
3041 int len, offset; 3048 unsigned int len, offset;
3042 3049
3043 offset = offsetof(struct rndis_indicate, status) + 3050 offset = offsetof(struct rndis_indicate, status) +
3044 le32_to_cpu(msg->offset); 3051 le32_to_cpu(msg->offset);
@@ -3050,7 +3057,7 @@ static void rndis_wlan_media_specific_indication(struct usbnet *usbdev,
3050 return; 3057 return;
3051 } 3058 }
3052 3059
3053 if (offset + len > buflen) { 3060 if (len > buflen || offset > buflen || offset + len > buflen) {
3054 netdev_info(usbdev->net, "media specific indication, too large to fit to buffer (%i > %i)\n", 3061 netdev_info(usbdev->net, "media specific indication, too large to fit to buffer (%i > %i)\n",
3055 offset + len, buflen); 3062 offset + len, buflen);
3056 return; 3063 return;