aboutsummaryrefslogtreecommitdiffstats
path: root/net/mac80211
diff options
context:
space:
mode:
Diffstat (limited to 'net/mac80211')
-rw-r--r--net/mac80211/ieee80211_i.h3
-rw-r--r--net/mac80211/mlme.c107
-rw-r--r--net/mac80211/scan.c8
3 files changed, 60 insertions, 58 deletions
diff --git a/net/mac80211/ieee80211_i.h b/net/mac80211/ieee80211_i.h
index cbc0b7d647f9..87d63fe61bf9 100644
--- a/net/mac80211/ieee80211_i.h
+++ b/net/mac80211/ieee80211_i.h
@@ -953,9 +953,6 @@ ieee80211_bss_info_update(struct ieee80211_local *local,
953 struct ieee80211_channel *channel, 953 struct ieee80211_channel *channel,
954 bool beacon); 954 bool beacon);
955struct ieee80211_bss * 955struct ieee80211_bss *
956ieee80211_rx_bss_add(struct ieee80211_local *local, u8 *bssid, int freq,
957 u8 *ssid, u8 ssid_len);
958struct ieee80211_bss *
959ieee80211_rx_bss_get(struct ieee80211_local *local, u8 *bssid, int freq, 956ieee80211_rx_bss_get(struct ieee80211_local *local, u8 *bssid, int freq,
960 u8 *ssid, u8 ssid_len); 957 u8 *ssid, u8 ssid_len);
961void ieee80211_rx_bss_put(struct ieee80211_local *local, 958void ieee80211_rx_bss_put(struct ieee80211_local *local,
diff --git a/net/mac80211/mlme.c b/net/mac80211/mlme.c
index 46b4817cdea9..c5991ec047be 100644
--- a/net/mac80211/mlme.c
+++ b/net/mac80211/mlme.c
@@ -546,14 +546,15 @@ void ieee80211_send_pspoll(struct ieee80211_local *local,
546 546
547/* MLME */ 547/* MLME */
548static void ieee80211_sta_def_wmm_params(struct ieee80211_sub_if_data *sdata, 548static void ieee80211_sta_def_wmm_params(struct ieee80211_sub_if_data *sdata,
549 struct ieee80211_bss *bss) 549 const size_t supp_rates_len,
550 const u8 *supp_rates)
550{ 551{
551 struct ieee80211_local *local = sdata->local; 552 struct ieee80211_local *local = sdata->local;
552 int i, have_higher_than_11mbit = 0; 553 int i, have_higher_than_11mbit = 0;
553 554
554 /* cf. IEEE 802.11 9.2.12 */ 555 /* cf. IEEE 802.11 9.2.12 */
555 for (i = 0; i < bss->supp_rates_len; i++) 556 for (i = 0; i < supp_rates_len; i++)
556 if ((bss->supp_rates[i] & 0x7f) * 5 > 110) 557 if ((supp_rates[i] & 0x7f) * 5 > 110)
557 have_higher_than_11mbit = 1; 558 have_higher_than_11mbit = 1;
558 559
559 if (local->hw.conf.channel->band == IEEE80211_BAND_2GHZ && 560 if (local->hw.conf.channel->band == IEEE80211_BAND_2GHZ &&
@@ -1546,9 +1547,13 @@ static void ieee80211_rx_mgmt_assoc_resp(struct ieee80211_sub_if_data *sdata,
1546} 1547}
1547 1548
1548 1549
1549static int ieee80211_sta_join_ibss(struct ieee80211_sub_if_data *sdata, 1550static int __ieee80211_sta_join_ibss(struct ieee80211_sub_if_data *sdata,
1550 struct ieee80211_if_sta *ifsta, 1551 struct ieee80211_if_sta *ifsta,
1551 struct ieee80211_bss *bss) 1552 const u8 *bssid, const int beacon_int,
1553 const int freq,
1554 const size_t supp_rates_len,
1555 const u8 *supp_rates,
1556 const u16 capability)
1552{ 1557{
1553 struct ieee80211_local *local = sdata->local; 1558 struct ieee80211_local *local = sdata->local;
1554 int res = 0, rates, i, j; 1559 int res = 0, rates, i, j;
@@ -1564,7 +1569,7 @@ static int ieee80211_sta_join_ibss(struct ieee80211_sub_if_data *sdata,
1564 } 1569 }
1565 1570
1566 if ((ifsta->flags & IEEE80211_STA_PREV_BSSID_SET) && 1571 if ((ifsta->flags & IEEE80211_STA_PREV_BSSID_SET) &&
1567 memcmp(ifsta->bssid, bss->bssid, ETH_ALEN) == 0) 1572 memcmp(ifsta->bssid, bssid, ETH_ALEN) == 0)
1568 return res; 1573 return res;
1569 1574
1570 skb = dev_alloc_skb(local->hw.extra_tx_headroom + 400 + 1575 skb = dev_alloc_skb(local->hw.extra_tx_headroom + 400 +
@@ -1575,28 +1580,28 @@ static int ieee80211_sta_join_ibss(struct ieee80211_sub_if_data *sdata,
1575 return -ENOMEM; 1580 return -ENOMEM;
1576 } 1581 }
1577 1582
1578 sband = local->hw.wiphy->bands[local->hw.conf.channel->band];
1579
1580 if (!(ifsta->flags & IEEE80211_STA_PREV_BSSID_SET)) { 1583 if (!(ifsta->flags & IEEE80211_STA_PREV_BSSID_SET)) {
1581 /* Remove possible STA entries from other IBSS networks. */ 1584 /* Remove possible STA entries from other IBSS networks. */
1582 sta_info_flush_delayed(sdata); 1585 sta_info_flush_delayed(sdata);
1583 } 1586 }
1584 1587
1585 memcpy(ifsta->bssid, bss->bssid, ETH_ALEN); 1588 memcpy(ifsta->bssid, bssid, ETH_ALEN);
1586 res = ieee80211_if_config(sdata, IEEE80211_IFCC_BSSID); 1589 res = ieee80211_if_config(sdata, IEEE80211_IFCC_BSSID);
1587 if (res) 1590 if (res)
1588 return res; 1591 return res;
1589 1592
1590 local->hw.conf.beacon_int = bss->beacon_int >= 10 ? bss->beacon_int : 10; 1593 local->hw.conf.beacon_int = beacon_int >= 10 ? beacon_int : 10;
1591 1594
1592 sdata->drop_unencrypted = bss->capability & 1595 sdata->drop_unencrypted = capability &
1593 WLAN_CAPABILITY_PRIVACY ? 1 : 0; 1596 WLAN_CAPABILITY_PRIVACY ? 1 : 0;
1594 1597
1595 res = ieee80211_set_freq(sdata, bss->freq); 1598 res = ieee80211_set_freq(sdata, freq);
1596 1599
1597 if (res) 1600 if (res)
1598 return res; 1601 return res;
1599 1602
1603 sband = local->hw.wiphy->bands[local->hw.conf.channel->band];
1604
1600 /* Build IBSS probe response */ 1605 /* Build IBSS probe response */
1601 1606
1602 skb_reserve(skb, local->hw.extra_tx_headroom); 1607 skb_reserve(skb, local->hw.extra_tx_headroom);
@@ -1605,33 +1610,32 @@ static int ieee80211_sta_join_ibss(struct ieee80211_sub_if_data *sdata,
1605 skb_put(skb, 24 + sizeof(mgmt->u.beacon)); 1610 skb_put(skb, 24 + sizeof(mgmt->u.beacon));
1606 memset(mgmt, 0, 24 + sizeof(mgmt->u.beacon)); 1611 memset(mgmt, 0, 24 + sizeof(mgmt->u.beacon));
1607 mgmt->frame_control = cpu_to_le16(IEEE80211_FTYPE_MGMT | 1612 mgmt->frame_control = cpu_to_le16(IEEE80211_FTYPE_MGMT |
1608 IEEE80211_STYPE_PROBE_RESP); 1613 IEEE80211_STYPE_PROBE_RESP);
1609 memset(mgmt->da, 0xff, ETH_ALEN); 1614 memset(mgmt->da, 0xff, ETH_ALEN);
1610 memcpy(mgmt->sa, sdata->dev->dev_addr, ETH_ALEN); 1615 memcpy(mgmt->sa, sdata->dev->dev_addr, ETH_ALEN);
1611 memcpy(mgmt->bssid, ifsta->bssid, ETH_ALEN); 1616 memcpy(mgmt->bssid, ifsta->bssid, ETH_ALEN);
1612 mgmt->u.beacon.beacon_int = 1617 mgmt->u.beacon.beacon_int =
1613 cpu_to_le16(local->hw.conf.beacon_int); 1618 cpu_to_le16(local->hw.conf.beacon_int);
1614 mgmt->u.beacon.timestamp = cpu_to_le64(bss->timestamp); 1619 mgmt->u.beacon.capab_info = cpu_to_le16(capability);
1615 mgmt->u.beacon.capab_info = cpu_to_le16(bss->capability);
1616 1620
1617 pos = skb_put(skb, 2 + ifsta->ssid_len); 1621 pos = skb_put(skb, 2 + ifsta->ssid_len);
1618 *pos++ = WLAN_EID_SSID; 1622 *pos++ = WLAN_EID_SSID;
1619 *pos++ = ifsta->ssid_len; 1623 *pos++ = ifsta->ssid_len;
1620 memcpy(pos, ifsta->ssid, ifsta->ssid_len); 1624 memcpy(pos, ifsta->ssid, ifsta->ssid_len);
1621 1625
1622 rates = bss->supp_rates_len; 1626 rates = supp_rates_len;
1623 if (rates > 8) 1627 if (rates > 8)
1624 rates = 8; 1628 rates = 8;
1625 pos = skb_put(skb, 2 + rates); 1629 pos = skb_put(skb, 2 + rates);
1626 *pos++ = WLAN_EID_SUPP_RATES; 1630 *pos++ = WLAN_EID_SUPP_RATES;
1627 *pos++ = rates; 1631 *pos++ = rates;
1628 memcpy(pos, bss->supp_rates, rates); 1632 memcpy(pos, supp_rates, rates);
1629 1633
1630 if (bss->band == IEEE80211_BAND_2GHZ) { 1634 if (sband->band == IEEE80211_BAND_2GHZ) {
1631 pos = skb_put(skb, 2 + 1); 1635 pos = skb_put(skb, 2 + 1);
1632 *pos++ = WLAN_EID_DS_PARAMS; 1636 *pos++ = WLAN_EID_DS_PARAMS;
1633 *pos++ = 1; 1637 *pos++ = 1;
1634 *pos++ = ieee80211_frequency_to_channel(bss->freq); 1638 *pos++ = ieee80211_frequency_to_channel(freq);
1635 } 1639 }
1636 1640
1637 pos = skb_put(skb, 2 + 2); 1641 pos = skb_put(skb, 2 + 2);
@@ -1641,12 +1645,12 @@ static int ieee80211_sta_join_ibss(struct ieee80211_sub_if_data *sdata,
1641 *pos++ = 0; 1645 *pos++ = 0;
1642 *pos++ = 0; 1646 *pos++ = 0;
1643 1647
1644 if (bss->supp_rates_len > 8) { 1648 if (supp_rates_len > 8) {
1645 rates = bss->supp_rates_len - 8; 1649 rates = supp_rates_len - 8;
1646 pos = skb_put(skb, 2 + rates); 1650 pos = skb_put(skb, 2 + rates);
1647 *pos++ = WLAN_EID_EXT_SUPP_RATES; 1651 *pos++ = WLAN_EID_EXT_SUPP_RATES;
1648 *pos++ = rates; 1652 *pos++ = rates;
1649 memcpy(pos, &bss->supp_rates[8], rates); 1653 memcpy(pos, &supp_rates[8], rates);
1650 } 1654 }
1651 1655
1652 add_extra_ies(skb, sdata->u.sta.ie_proberesp, 1656 add_extra_ies(skb, sdata->u.sta.ie_proberesp,
@@ -1659,16 +1663,15 @@ static int ieee80211_sta_join_ibss(struct ieee80211_sub_if_data *sdata,
1659 1663
1660 1664
1661 rates = 0; 1665 rates = 0;
1662 sband = local->hw.wiphy->bands[local->hw.conf.channel->band]; 1666 for (i = 0; i < supp_rates_len; i++) {
1663 for (i = 0; i < bss->supp_rates_len; i++) { 1667 int bitrate = (supp_rates[i] & 0x7f) * 5;
1664 int bitrate = (bss->supp_rates[i] & 0x7f) * 5;
1665 for (j = 0; j < sband->n_bitrates; j++) 1668 for (j = 0; j < sband->n_bitrates; j++)
1666 if (sband->bitrates[j].bitrate == bitrate) 1669 if (sband->bitrates[j].bitrate == bitrate)
1667 rates |= BIT(j); 1670 rates |= BIT(j);
1668 } 1671 }
1669 ifsta->supp_rates_bits[local->hw.conf.channel->band] = rates; 1672 ifsta->supp_rates_bits[local->hw.conf.channel->band] = rates;
1670 1673
1671 ieee80211_sta_def_wmm_params(sdata, bss); 1674 ieee80211_sta_def_wmm_params(sdata, supp_rates_len, supp_rates);
1672 1675
1673 ifsta->flags |= IEEE80211_STA_PREV_BSSID_SET; 1676 ifsta->flags |= IEEE80211_STA_PREV_BSSID_SET;
1674 ifsta->state = IEEE80211_STA_MLME_IBSS_JOINED; 1677 ifsta->state = IEEE80211_STA_MLME_IBSS_JOINED;
@@ -1677,12 +1680,23 @@ static int ieee80211_sta_join_ibss(struct ieee80211_sub_if_data *sdata,
1677 ieee80211_led_assoc(local, true); 1680 ieee80211_led_assoc(local, true);
1678 1681
1679 memset(&wrqu, 0, sizeof(wrqu)); 1682 memset(&wrqu, 0, sizeof(wrqu));
1680 memcpy(wrqu.ap_addr.sa_data, bss->bssid, ETH_ALEN); 1683 memcpy(wrqu.ap_addr.sa_data, bssid, ETH_ALEN);
1681 wireless_send_event(sdata->dev, SIOCGIWAP, &wrqu, NULL); 1684 wireless_send_event(sdata->dev, SIOCGIWAP, &wrqu, NULL);
1682 1685
1683 return res; 1686 return res;
1684} 1687}
1685 1688
1689static int ieee80211_sta_join_ibss(struct ieee80211_sub_if_data *sdata,
1690 struct ieee80211_if_sta *ifsta,
1691 struct ieee80211_bss *bss)
1692{
1693 return __ieee80211_sta_join_ibss(sdata, ifsta,
1694 bss->bssid, bss->beacon_int,
1695 bss->freq,
1696 bss->supp_rates_len, bss->supp_rates,
1697 bss->capability);
1698}
1699
1686static void ieee80211_rx_bss_info(struct ieee80211_sub_if_data *sdata, 1700static void ieee80211_rx_bss_info(struct ieee80211_sub_if_data *sdata,
1687 struct ieee80211_mgmt *mgmt, 1701 struct ieee80211_mgmt *mgmt,
1688 size_t len, 1702 size_t len,
@@ -2251,11 +2265,12 @@ static int ieee80211_sta_create_ibss(struct ieee80211_sub_if_data *sdata,
2251 struct ieee80211_if_sta *ifsta) 2265 struct ieee80211_if_sta *ifsta)
2252{ 2266{
2253 struct ieee80211_local *local = sdata->local; 2267 struct ieee80211_local *local = sdata->local;
2254 struct ieee80211_bss *bss;
2255 struct ieee80211_supported_band *sband; 2268 struct ieee80211_supported_band *sband;
2256 u8 bssid[ETH_ALEN], *pos; 2269 u8 *pos;
2270 u8 bssid[ETH_ALEN];
2271 u8 supp_rates[IEEE80211_MAX_SUPP_RATES];
2272 u16 capability;
2257 int i; 2273 int i;
2258 int ret;
2259 2274
2260 if (sdata->u.sta.flags & IEEE80211_STA_BSSID_SET) { 2275 if (sdata->u.sta.flags & IEEE80211_STA_BSSID_SET) {
2261 memcpy(bssid, ifsta->bssid, ETH_ALEN); 2276 memcpy(bssid, ifsta->bssid, ETH_ALEN);
@@ -2273,36 +2288,29 @@ static int ieee80211_sta_create_ibss(struct ieee80211_sub_if_data *sdata,
2273 printk(KERN_DEBUG "%s: Creating new IBSS network, BSSID %pM\n", 2288 printk(KERN_DEBUG "%s: Creating new IBSS network, BSSID %pM\n",
2274 sdata->dev->name, bssid); 2289 sdata->dev->name, bssid);
2275 2290
2276 bss = ieee80211_rx_bss_add(local, bssid, 2291 sband = local->hw.wiphy->bands[local->hw.conf.channel->band];
2277 local->hw.conf.channel->center_freq,
2278 sdata->u.sta.ssid, sdata->u.sta.ssid_len);
2279 if (!bss)
2280 return -ENOMEM;
2281
2282 bss->band = local->hw.conf.channel->band;
2283 sband = local->hw.wiphy->bands[bss->band];
2284 2292
2285 if (local->hw.conf.beacon_int == 0) 2293 if (local->hw.conf.beacon_int == 0)
2286 local->hw.conf.beacon_int = 100; 2294 local->hw.conf.beacon_int = 100;
2287 bss->beacon_int = local->hw.conf.beacon_int; 2295
2288 bss->last_update = jiffies; 2296 capability = WLAN_CAPABILITY_IBSS;
2289 bss->capability = WLAN_CAPABILITY_IBSS;
2290 2297
2291 if (sdata->default_key) 2298 if (sdata->default_key)
2292 bss->capability |= WLAN_CAPABILITY_PRIVACY; 2299 capability |= WLAN_CAPABILITY_PRIVACY;
2293 else 2300 else
2294 sdata->drop_unencrypted = 0; 2301 sdata->drop_unencrypted = 0;
2295 2302
2296 bss->supp_rates_len = sband->n_bitrates; 2303 pos = supp_rates;
2297 pos = bss->supp_rates;
2298 for (i = 0; i < sband->n_bitrates; i++) { 2304 for (i = 0; i < sband->n_bitrates; i++) {
2299 int rate = sband->bitrates[i].bitrate; 2305 int rate = sband->bitrates[i].bitrate;
2300 *pos++ = (u8) (rate / 5); 2306 *pos++ = (u8) (rate / 5);
2301 } 2307 }
2302 2308
2303 ret = ieee80211_sta_join_ibss(sdata, ifsta, bss); 2309 return __ieee80211_sta_join_ibss(sdata, ifsta,
2304 ieee80211_rx_bss_put(local, bss); 2310 bssid, local->hw.conf.beacon_int,
2305 return ret; 2311 local->hw.conf.channel->center_freq,
2312 sband->n_bitrates, supp_rates,
2313 capability);
2306} 2314}
2307 2315
2308 2316
@@ -2471,7 +2479,8 @@ static int ieee80211_sta_config_auth(struct ieee80211_sub_if_data *sdata,
2471 ieee80211_sta_set_ssid(sdata, selected->ssid, 2479 ieee80211_sta_set_ssid(sdata, selected->ssid,
2472 selected->ssid_len); 2480 selected->ssid_len);
2473 ieee80211_sta_set_bssid(sdata, selected->bssid); 2481 ieee80211_sta_set_bssid(sdata, selected->bssid);
2474 ieee80211_sta_def_wmm_params(sdata, selected); 2482 ieee80211_sta_def_wmm_params(sdata, selected->supp_rates_len,
2483 selected->supp_rates);
2475 if (sdata->u.sta.mfp == IEEE80211_MFP_REQUIRED) 2484 if (sdata->u.sta.mfp == IEEE80211_MFP_REQUIRED)
2476 sdata->u.sta.flags |= IEEE80211_STA_MFP_ENABLED; 2485 sdata->u.sta.flags |= IEEE80211_STA_MFP_ENABLED;
2477 else 2486 else
diff --git a/net/mac80211/scan.c b/net/mac80211/scan.c
index c6b275b10cf9..fc88e2e2f923 100644
--- a/net/mac80211/scan.c
+++ b/net/mac80211/scan.c
@@ -14,11 +14,7 @@
14 14
15/* TODO: 15/* TODO:
16 * figure out how to avoid that the "current BSS" expires 16 * figure out how to avoid that the "current BSS" expires
17 * clean up IBSS code (in MLME), see why it adds a BSS to the list 17 * use cfg80211's BSS handling
18 * use cfg80211's BSS handling (depends on IBSS TODO above)
19 * order BSS list by RSSI(?) ("quality of AP")
20 * scan result table filtering (by capability (privacy, IBSS/BSS, WPA/RSN IE,
21 * SSID)
22 */ 18 */
23 19
24#include <linux/wireless.h> 20#include <linux/wireless.h>
@@ -107,7 +103,7 @@ static void __ieee80211_rx_bss_hash_del(struct ieee80211_local *local,
107 } 103 }
108} 104}
109 105
110struct ieee80211_bss * 106static struct ieee80211_bss *
111ieee80211_rx_bss_add(struct ieee80211_local *local, u8 *bssid, int freq, 107ieee80211_rx_bss_add(struct ieee80211_local *local, u8 *bssid, int freq,
112 u8 *ssid, u8 ssid_len) 108 u8 *ssid, u8 ssid_len)
113{ 109{