diff options
Diffstat (limited to 'net/mac80211/ieee80211_sta.c')
-rw-r--r-- | net/mac80211/ieee80211_sta.c | 384 |
1 files changed, 208 insertions, 176 deletions
diff --git a/net/mac80211/ieee80211_sta.c b/net/mac80211/ieee80211_sta.c index d0273ccbdbae..2628222a5085 100644 --- a/net/mac80211/ieee80211_sta.c +++ b/net/mac80211/ieee80211_sta.c | |||
@@ -74,7 +74,7 @@ | |||
74 | static void ieee80211_send_probe_req(struct net_device *dev, u8 *dst, | 74 | static void ieee80211_send_probe_req(struct net_device *dev, u8 *dst, |
75 | u8 *ssid, size_t ssid_len); | 75 | u8 *ssid, size_t ssid_len); |
76 | static struct ieee80211_sta_bss * | 76 | static struct ieee80211_sta_bss * |
77 | ieee80211_rx_bss_get(struct net_device *dev, u8 *bssid, int channel, | 77 | ieee80211_rx_bss_get(struct net_device *dev, u8 *bssid, int freq, |
78 | u8 *ssid, u8 ssid_len); | 78 | u8 *ssid, u8 ssid_len); |
79 | static void ieee80211_rx_bss_put(struct net_device *dev, | 79 | static void ieee80211_rx_bss_put(struct net_device *dev, |
80 | struct ieee80211_sta_bss *bss); | 80 | struct ieee80211_sta_bss *bss); |
@@ -466,7 +466,7 @@ static void ieee80211_set_associated(struct net_device *dev, | |||
466 | return; | 466 | return; |
467 | 467 | ||
468 | bss = ieee80211_rx_bss_get(dev, ifsta->bssid, | 468 | bss = ieee80211_rx_bss_get(dev, ifsta->bssid, |
469 | local->hw.conf.channel, | 469 | local->hw.conf.channel->center_freq, |
470 | ifsta->ssid, ifsta->ssid_len); | 470 | ifsta->ssid, ifsta->ssid_len); |
471 | if (bss) { | 471 | if (bss) { |
472 | if (bss->has_erp_value) | 472 | if (bss->has_erp_value) |
@@ -593,7 +593,6 @@ static void ieee80211_send_assoc(struct net_device *dev, | |||
593 | struct ieee80211_if_sta *ifsta) | 593 | struct ieee80211_if_sta *ifsta) |
594 | { | 594 | { |
595 | struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr); | 595 | struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr); |
596 | struct ieee80211_hw_mode *mode; | ||
597 | struct sk_buff *skb; | 596 | struct sk_buff *skb; |
598 | struct ieee80211_mgmt *mgmt; | 597 | struct ieee80211_mgmt *mgmt; |
599 | u8 *pos, *ies; | 598 | u8 *pos, *ies; |
@@ -601,6 +600,7 @@ static void ieee80211_send_assoc(struct net_device *dev, | |||
601 | u16 capab; | 600 | u16 capab; |
602 | struct ieee80211_sta_bss *bss; | 601 | struct ieee80211_sta_bss *bss; |
603 | int wmm = 0; | 602 | int wmm = 0; |
603 | struct ieee80211_supported_band *sband; | ||
604 | 604 | ||
605 | skb = dev_alloc_skb(local->hw.extra_tx_headroom + | 605 | skb = dev_alloc_skb(local->hw.extra_tx_headroom + |
606 | sizeof(*mgmt) + 200 + ifsta->extra_ie_len + | 606 | sizeof(*mgmt) + 200 + ifsta->extra_ie_len + |
@@ -612,13 +612,19 @@ static void ieee80211_send_assoc(struct net_device *dev, | |||
612 | } | 612 | } |
613 | skb_reserve(skb, local->hw.extra_tx_headroom); | 613 | skb_reserve(skb, local->hw.extra_tx_headroom); |
614 | 614 | ||
615 | mode = local->oper_hw_mode; | 615 | sband = local->hw.wiphy->bands[local->hw.conf.channel->band]; |
616 | |||
616 | capab = ifsta->capab; | 617 | capab = ifsta->capab; |
617 | if (mode->mode == MODE_IEEE80211G) { | 618 | |
618 | capab |= WLAN_CAPABILITY_SHORT_SLOT_TIME | | 619 | if (local->hw.conf.channel->band == IEEE80211_BAND_2GHZ) { |
619 | WLAN_CAPABILITY_SHORT_PREAMBLE; | 620 | if (!(local->hw.flags & IEEE80211_HW_2GHZ_SHORT_SLOT_INCAPABLE)) |
621 | capab |= WLAN_CAPABILITY_SHORT_SLOT_TIME; | ||
622 | if (!(local->hw.flags & IEEE80211_HW_2GHZ_SHORT_PREAMBLE_INCAPABLE)) | ||
623 | capab |= WLAN_CAPABILITY_SHORT_PREAMBLE; | ||
620 | } | 624 | } |
621 | bss = ieee80211_rx_bss_get(dev, ifsta->bssid, local->hw.conf.channel, | 625 | |
626 | bss = ieee80211_rx_bss_get(dev, ifsta->bssid, | ||
627 | local->hw.conf.channel->center_freq, | ||
622 | ifsta->ssid, ifsta->ssid_len); | 628 | ifsta->ssid, ifsta->ssid_len); |
623 | if (bss) { | 629 | if (bss) { |
624 | if (bss->capability & WLAN_CAPABILITY_PRIVACY) | 630 | if (bss->capability & WLAN_CAPABILITY_PRIVACY) |
@@ -657,23 +663,23 @@ static void ieee80211_send_assoc(struct net_device *dev, | |||
657 | *pos++ = ifsta->ssid_len; | 663 | *pos++ = ifsta->ssid_len; |
658 | memcpy(pos, ifsta->ssid, ifsta->ssid_len); | 664 | memcpy(pos, ifsta->ssid, ifsta->ssid_len); |
659 | 665 | ||
660 | len = mode->num_rates; | 666 | len = sband->n_bitrates; |
661 | if (len > 8) | 667 | if (len > 8) |
662 | len = 8; | 668 | len = 8; |
663 | pos = skb_put(skb, len + 2); | 669 | pos = skb_put(skb, len + 2); |
664 | *pos++ = WLAN_EID_SUPP_RATES; | 670 | *pos++ = WLAN_EID_SUPP_RATES; |
665 | *pos++ = len; | 671 | *pos++ = len; |
666 | for (i = 0; i < len; i++) { | 672 | for (i = 0; i < len; i++) { |
667 | int rate = mode->rates[i].rate; | 673 | int rate = sband->bitrates[i].bitrate; |
668 | *pos++ = (u8) (rate / 5); | 674 | *pos++ = (u8) (rate / 5); |
669 | } | 675 | } |
670 | 676 | ||
671 | if (mode->num_rates > len) { | 677 | if (sband->n_bitrates > len) { |
672 | pos = skb_put(skb, mode->num_rates - len + 2); | 678 | pos = skb_put(skb, sband->n_bitrates - len + 2); |
673 | *pos++ = WLAN_EID_EXT_SUPP_RATES; | 679 | *pos++ = WLAN_EID_EXT_SUPP_RATES; |
674 | *pos++ = mode->num_rates - len; | 680 | *pos++ = sband->n_bitrates - len; |
675 | for (i = len; i < mode->num_rates; i++) { | 681 | for (i = len; i < sband->n_bitrates; i++) { |
676 | int rate = mode->rates[i].rate; | 682 | int rate = sband->bitrates[i].bitrate; |
677 | *pos++ = (u8) (rate / 5); | 683 | *pos++ = (u8) (rate / 5); |
678 | } | 684 | } |
679 | } | 685 | } |
@@ -696,17 +702,18 @@ static void ieee80211_send_assoc(struct net_device *dev, | |||
696 | *pos++ = 0; | 702 | *pos++ = 0; |
697 | } | 703 | } |
698 | /* wmm support is a must to HT */ | 704 | /* wmm support is a must to HT */ |
699 | if (wmm && mode->ht_info.ht_supported) { | 705 | if (wmm && sband->ht_info.ht_supported) { |
700 | __le16 tmp = cpu_to_le16(mode->ht_info.cap); | 706 | __le16 tmp = cpu_to_le16(sband->ht_info.cap); |
701 | pos = skb_put(skb, sizeof(struct ieee80211_ht_cap)+2); | 707 | pos = skb_put(skb, sizeof(struct ieee80211_ht_cap)+2); |
702 | *pos++ = WLAN_EID_HT_CAPABILITY; | 708 | *pos++ = WLAN_EID_HT_CAPABILITY; |
703 | *pos++ = sizeof(struct ieee80211_ht_cap); | 709 | *pos++ = sizeof(struct ieee80211_ht_cap); |
704 | memset(pos, 0, sizeof(struct ieee80211_ht_cap)); | 710 | memset(pos, 0, sizeof(struct ieee80211_ht_cap)); |
705 | memcpy(pos, &tmp, sizeof(u16)); | 711 | memcpy(pos, &tmp, sizeof(u16)); |
706 | pos += sizeof(u16); | 712 | pos += sizeof(u16); |
707 | *pos++ = (mode->ht_info.ampdu_factor | | 713 | /* TODO: needs a define here for << 2 */ |
708 | (mode->ht_info.ampdu_density << 2)); | 714 | *pos++ = sband->ht_info.ampdu_factor | |
709 | memcpy(pos, mode->ht_info.supp_mcs_set, 16); | 715 | (sband->ht_info.ampdu_density << 2); |
716 | memcpy(pos, sband->ht_info.supp_mcs_set, 16); | ||
710 | } | 717 | } |
711 | 718 | ||
712 | kfree(ifsta->assocreq_ies); | 719 | kfree(ifsta->assocreq_ies); |
@@ -789,7 +796,8 @@ static int ieee80211_privacy_mismatch(struct net_device *dev, | |||
789 | if (!ifsta || (ifsta->flags & IEEE80211_STA_MIXED_CELL)) | 796 | if (!ifsta || (ifsta->flags & IEEE80211_STA_MIXED_CELL)) |
790 | return 0; | 797 | return 0; |
791 | 798 | ||
792 | bss = ieee80211_rx_bss_get(dev, ifsta->bssid, local->hw.conf.channel, | 799 | bss = ieee80211_rx_bss_get(dev, ifsta->bssid, |
800 | local->hw.conf.channel->center_freq, | ||
793 | ifsta->ssid, ifsta->ssid_len); | 801 | ifsta->ssid, ifsta->ssid_len); |
794 | if (!bss) | 802 | if (!bss) |
795 | return 0; | 803 | return 0; |
@@ -899,7 +907,7 @@ static void ieee80211_send_probe_req(struct net_device *dev, u8 *dst, | |||
899 | u8 *ssid, size_t ssid_len) | 907 | u8 *ssid, size_t ssid_len) |
900 | { | 908 | { |
901 | struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr); | 909 | struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr); |
902 | struct ieee80211_hw_mode *mode; | 910 | struct ieee80211_supported_band *sband; |
903 | struct sk_buff *skb; | 911 | struct sk_buff *skb; |
904 | struct ieee80211_mgmt *mgmt; | 912 | struct ieee80211_mgmt *mgmt; |
905 | u8 *pos, *supp_rates, *esupp_rates = NULL; | 913 | u8 *pos, *supp_rates, *esupp_rates = NULL; |
@@ -933,11 +941,10 @@ static void ieee80211_send_probe_req(struct net_device *dev, u8 *dst, | |||
933 | supp_rates = skb_put(skb, 2); | 941 | supp_rates = skb_put(skb, 2); |
934 | supp_rates[0] = WLAN_EID_SUPP_RATES; | 942 | supp_rates[0] = WLAN_EID_SUPP_RATES; |
935 | supp_rates[1] = 0; | 943 | supp_rates[1] = 0; |
936 | mode = local->oper_hw_mode; | 944 | sband = local->hw.wiphy->bands[local->hw.conf.channel->band]; |
937 | for (i = 0; i < mode->num_rates; i++) { | 945 | |
938 | struct ieee80211_rate *rate = &mode->rates[i]; | 946 | for (i = 0; i < sband->n_bitrates; i++) { |
939 | if (!(rate->flags & IEEE80211_RATE_SUPPORTED)) | 947 | struct ieee80211_rate *rate = &sband->bitrates[i]; |
940 | continue; | ||
941 | if (esupp_rates) { | 948 | if (esupp_rates) { |
942 | pos = skb_put(skb, 1); | 949 | pos = skb_put(skb, 1); |
943 | esupp_rates[1]++; | 950 | esupp_rates[1]++; |
@@ -950,7 +957,7 @@ static void ieee80211_send_probe_req(struct net_device *dev, u8 *dst, | |||
950 | pos = skb_put(skb, 1); | 957 | pos = skb_put(skb, 1); |
951 | supp_rates[1]++; | 958 | supp_rates[1]++; |
952 | } | 959 | } |
953 | *pos = rate->rate / 5; | 960 | *pos = rate->bitrate / 5; |
954 | } | 961 | } |
955 | 962 | ||
956 | ieee80211_sta_tx(dev, skb, 0); | 963 | ieee80211_sta_tx(dev, skb, 0); |
@@ -1146,9 +1153,11 @@ static void ieee80211_sta_process_addba_request(struct net_device *dev, | |||
1146 | } | 1153 | } |
1147 | /* determine default buffer size */ | 1154 | /* determine default buffer size */ |
1148 | if (buf_size == 0) { | 1155 | if (buf_size == 0) { |
1149 | struct ieee80211_hw_mode *mode = conf->mode; | 1156 | struct ieee80211_supported_band *sband; |
1157 | |||
1158 | sband = local->hw.wiphy->bands[conf->channel->band]; | ||
1150 | buf_size = IEEE80211_MIN_AMPDU_BUF; | 1159 | buf_size = IEEE80211_MIN_AMPDU_BUF; |
1151 | buf_size = buf_size << mode->ht_info.ampdu_factor; | 1160 | buf_size = buf_size << sband->ht_info.ampdu_factor; |
1152 | } | 1161 | } |
1153 | 1162 | ||
1154 | tid_agg_rx = &sta->ampdu_mlme.tid_rx[tid]; | 1163 | tid_agg_rx = &sta->ampdu_mlme.tid_rx[tid]; |
@@ -1718,15 +1727,16 @@ static void ieee80211_rx_mgmt_assoc_resp(struct ieee80211_sub_if_data *sdata, | |||
1718 | { | 1727 | { |
1719 | struct ieee80211_local *local = sdata->local; | 1728 | struct ieee80211_local *local = sdata->local; |
1720 | struct net_device *dev = sdata->dev; | 1729 | struct net_device *dev = sdata->dev; |
1721 | struct ieee80211_hw_mode *mode; | 1730 | struct ieee80211_supported_band *sband; |
1722 | struct sta_info *sta; | 1731 | struct sta_info *sta; |
1723 | u32 rates; | 1732 | u64 rates, basic_rates; |
1724 | u16 capab_info, status_code, aid; | 1733 | u16 capab_info, status_code, aid; |
1725 | struct ieee802_11_elems elems; | 1734 | struct ieee802_11_elems elems; |
1726 | struct ieee80211_bss_conf *bss_conf = &sdata->bss_conf; | 1735 | struct ieee80211_bss_conf *bss_conf = &sdata->bss_conf; |
1727 | u8 *pos; | 1736 | u8 *pos; |
1728 | int i, j; | 1737 | int i, j; |
1729 | DECLARE_MAC_BUF(mac); | 1738 | DECLARE_MAC_BUF(mac); |
1739 | bool have_higher_than_11mbit = false; | ||
1730 | 1740 | ||
1731 | /* AssocResp and ReassocResp have identical structure, so process both | 1741 | /* AssocResp and ReassocResp have identical structure, so process both |
1732 | * of them in this function. */ | 1742 | * of them in this function. */ |
@@ -1796,10 +1806,6 @@ static void ieee80211_rx_mgmt_assoc_resp(struct ieee80211_sub_if_data *sdata, | |||
1796 | if (ifsta->assocresp_ies) | 1806 | if (ifsta->assocresp_ies) |
1797 | memcpy(ifsta->assocresp_ies, pos, ifsta->assocresp_ies_len); | 1807 | memcpy(ifsta->assocresp_ies, pos, ifsta->assocresp_ies_len); |
1798 | 1808 | ||
1799 | /* set AID, ieee80211_set_associated() will tell the driver */ | ||
1800 | bss_conf->aid = aid; | ||
1801 | ieee80211_set_associated(dev, ifsta, 1); | ||
1802 | |||
1803 | /* Add STA entry for the AP */ | 1809 | /* Add STA entry for the AP */ |
1804 | sta = sta_info_get(local, ifsta->bssid); | 1810 | sta = sta_info_get(local, ifsta->bssid); |
1805 | if (!sta) { | 1811 | if (!sta) { |
@@ -1811,7 +1817,7 @@ static void ieee80211_rx_mgmt_assoc_resp(struct ieee80211_sub_if_data *sdata, | |||
1811 | return; | 1817 | return; |
1812 | } | 1818 | } |
1813 | bss = ieee80211_rx_bss_get(dev, ifsta->bssid, | 1819 | bss = ieee80211_rx_bss_get(dev, ifsta->bssid, |
1814 | local->hw.conf.channel, | 1820 | local->hw.conf.channel->center_freq, |
1815 | ifsta->ssid, ifsta->ssid_len); | 1821 | ifsta->ssid, ifsta->ssid_len); |
1816 | if (bss) { | 1822 | if (bss) { |
1817 | sta->last_rssi = bss->rssi; | 1823 | sta->last_rssi = bss->rssi; |
@@ -1825,20 +1831,46 @@ static void ieee80211_rx_mgmt_assoc_resp(struct ieee80211_sub_if_data *sdata, | |||
1825 | sta->flags |= WLAN_STA_AUTH | WLAN_STA_ASSOC | WLAN_STA_ASSOC_AP; | 1831 | sta->flags |= WLAN_STA_AUTH | WLAN_STA_ASSOC | WLAN_STA_ASSOC_AP; |
1826 | 1832 | ||
1827 | rates = 0; | 1833 | rates = 0; |
1828 | mode = local->oper_hw_mode; | 1834 | basic_rates = 0; |
1835 | sband = local->hw.wiphy->bands[local->hw.conf.channel->band]; | ||
1836 | |||
1829 | for (i = 0; i < elems.supp_rates_len; i++) { | 1837 | for (i = 0; i < elems.supp_rates_len; i++) { |
1830 | int rate = (elems.supp_rates[i] & 0x7f) * 5; | 1838 | int rate = (elems.supp_rates[i] & 0x7f) * 5; |
1831 | for (j = 0; j < mode->num_rates; j++) | 1839 | |
1832 | if (mode->rates[j].rate == rate) | 1840 | if (rate > 110) |
1841 | have_higher_than_11mbit = true; | ||
1842 | |||
1843 | for (j = 0; j < sband->n_bitrates; j++) { | ||
1844 | if (sband->bitrates[j].bitrate == rate) | ||
1833 | rates |= BIT(j); | 1845 | rates |= BIT(j); |
1846 | if (elems.supp_rates[i] & 0x80) | ||
1847 | basic_rates |= BIT(j); | ||
1848 | } | ||
1834 | } | 1849 | } |
1850 | |||
1835 | for (i = 0; i < elems.ext_supp_rates_len; i++) { | 1851 | for (i = 0; i < elems.ext_supp_rates_len; i++) { |
1836 | int rate = (elems.ext_supp_rates[i] & 0x7f) * 5; | 1852 | int rate = (elems.ext_supp_rates[i] & 0x7f) * 5; |
1837 | for (j = 0; j < mode->num_rates; j++) | 1853 | |
1838 | if (mode->rates[j].rate == rate) | 1854 | if (rate > 110) |
1855 | have_higher_than_11mbit = true; | ||
1856 | |||
1857 | for (j = 0; j < sband->n_bitrates; j++) { | ||
1858 | if (sband->bitrates[j].bitrate == rate) | ||
1839 | rates |= BIT(j); | 1859 | rates |= BIT(j); |
1860 | if (elems.ext_supp_rates[i] & 0x80) | ||
1861 | basic_rates |= BIT(j); | ||
1862 | } | ||
1840 | } | 1863 | } |
1841 | sta->supp_rates = rates; | 1864 | |
1865 | sta->supp_rates[local->hw.conf.channel->band] = rates; | ||
1866 | sdata->basic_rates = basic_rates; | ||
1867 | |||
1868 | /* cf. IEEE 802.11 9.2.12 */ | ||
1869 | if (local->hw.conf.channel->band == IEEE80211_BAND_2GHZ && | ||
1870 | have_higher_than_11mbit) | ||
1871 | sdata->flags |= IEEE80211_SDATA_OPERATING_GMODE; | ||
1872 | else | ||
1873 | sdata->flags &= ~IEEE80211_SDATA_OPERATING_GMODE; | ||
1842 | 1874 | ||
1843 | if (elems.ht_cap_elem && elems.ht_info_elem && elems.wmm_param && | 1875 | if (elems.ht_cap_elem && elems.ht_info_elem && elems.wmm_param && |
1844 | local->ops->conf_ht) { | 1876 | local->ops->conf_ht) { |
@@ -1861,6 +1893,9 @@ static void ieee80211_rx_mgmt_assoc_resp(struct ieee80211_sub_if_data *sdata, | |||
1861 | elems.wmm_param_len); | 1893 | elems.wmm_param_len); |
1862 | } | 1894 | } |
1863 | 1895 | ||
1896 | /* set AID, ieee80211_set_associated() will tell the driver */ | ||
1897 | bss_conf->aid = aid; | ||
1898 | ieee80211_set_associated(dev, ifsta, 1); | ||
1864 | 1899 | ||
1865 | sta_info_put(sta); | 1900 | sta_info_put(sta); |
1866 | 1901 | ||
@@ -1901,7 +1936,7 @@ static void __ieee80211_rx_bss_hash_del(struct net_device *dev, | |||
1901 | 1936 | ||
1902 | 1937 | ||
1903 | static struct ieee80211_sta_bss * | 1938 | static struct ieee80211_sta_bss * |
1904 | ieee80211_rx_bss_add(struct net_device *dev, u8 *bssid, int channel, | 1939 | ieee80211_rx_bss_add(struct net_device *dev, u8 *bssid, int freq, |
1905 | u8 *ssid, u8 ssid_len) | 1940 | u8 *ssid, u8 ssid_len) |
1906 | { | 1941 | { |
1907 | struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr); | 1942 | struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr); |
@@ -1913,7 +1948,7 @@ ieee80211_rx_bss_add(struct net_device *dev, u8 *bssid, int channel, | |||
1913 | atomic_inc(&bss->users); | 1948 | atomic_inc(&bss->users); |
1914 | atomic_inc(&bss->users); | 1949 | atomic_inc(&bss->users); |
1915 | memcpy(bss->bssid, bssid, ETH_ALEN); | 1950 | memcpy(bss->bssid, bssid, ETH_ALEN); |
1916 | bss->channel = channel; | 1951 | bss->freq = freq; |
1917 | if (ssid && ssid_len <= IEEE80211_MAX_SSID_LEN) { | 1952 | if (ssid && ssid_len <= IEEE80211_MAX_SSID_LEN) { |
1918 | memcpy(bss->ssid, ssid, ssid_len); | 1953 | memcpy(bss->ssid, ssid, ssid_len); |
1919 | bss->ssid_len = ssid_len; | 1954 | bss->ssid_len = ssid_len; |
@@ -1929,7 +1964,7 @@ ieee80211_rx_bss_add(struct net_device *dev, u8 *bssid, int channel, | |||
1929 | 1964 | ||
1930 | 1965 | ||
1931 | static struct ieee80211_sta_bss * | 1966 | static struct ieee80211_sta_bss * |
1932 | ieee80211_rx_bss_get(struct net_device *dev, u8 *bssid, int channel, | 1967 | ieee80211_rx_bss_get(struct net_device *dev, u8 *bssid, int freq, |
1933 | u8 *ssid, u8 ssid_len) | 1968 | u8 *ssid, u8 ssid_len) |
1934 | { | 1969 | { |
1935 | struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr); | 1970 | struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr); |
@@ -1939,7 +1974,7 @@ ieee80211_rx_bss_get(struct net_device *dev, u8 *bssid, int channel, | |||
1939 | bss = local->sta_bss_hash[STA_HASH(bssid)]; | 1974 | bss = local->sta_bss_hash[STA_HASH(bssid)]; |
1940 | while (bss) { | 1975 | while (bss) { |
1941 | if (!memcmp(bss->bssid, bssid, ETH_ALEN) && | 1976 | if (!memcmp(bss->bssid, bssid, ETH_ALEN) && |
1942 | bss->channel == channel && | 1977 | bss->freq == freq && |
1943 | bss->ssid_len == ssid_len && | 1978 | bss->ssid_len == ssid_len && |
1944 | (ssid_len == 0 || !memcmp(bss->ssid, ssid, ssid_len))) { | 1979 | (ssid_len == 0 || !memcmp(bss->ssid, ssid, ssid_len))) { |
1945 | atomic_inc(&bss->users); | 1980 | atomic_inc(&bss->users); |
@@ -2004,7 +2039,7 @@ static void ieee80211_rx_bss_info(struct net_device *dev, | |||
2004 | struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr); | 2039 | struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr); |
2005 | struct ieee802_11_elems elems; | 2040 | struct ieee802_11_elems elems; |
2006 | size_t baselen; | 2041 | size_t baselen; |
2007 | int channel, clen; | 2042 | int freq, clen; |
2008 | struct ieee80211_sta_bss *bss; | 2043 | struct ieee80211_sta_bss *bss; |
2009 | struct sta_info *sta; | 2044 | struct sta_info *sta; |
2010 | struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev); | 2045 | struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev); |
@@ -2055,26 +2090,22 @@ static void ieee80211_rx_bss_info(struct net_device *dev, | |||
2055 | if (sdata->vif.type == IEEE80211_IF_TYPE_IBSS && elems.supp_rates && | 2090 | if (sdata->vif.type == IEEE80211_IF_TYPE_IBSS && elems.supp_rates && |
2056 | memcmp(mgmt->bssid, sdata->u.sta.bssid, ETH_ALEN) == 0 && | 2091 | memcmp(mgmt->bssid, sdata->u.sta.bssid, ETH_ALEN) == 0 && |
2057 | (sta = sta_info_get(local, mgmt->sa))) { | 2092 | (sta = sta_info_get(local, mgmt->sa))) { |
2058 | struct ieee80211_hw_mode *mode; | 2093 | struct ieee80211_supported_band *sband; |
2059 | struct ieee80211_rate *rates; | 2094 | struct ieee80211_rate *bitrates; |
2060 | size_t num_rates; | 2095 | size_t num_rates; |
2061 | u32 supp_rates, prev_rates; | 2096 | u64 supp_rates, prev_rates; |
2062 | int i, j; | 2097 | int i, j; |
2063 | 2098 | ||
2064 | mode = local->sta_sw_scanning ? | 2099 | sband = local->hw.wiphy->bands[rx_status->band]; |
2065 | local->scan_hw_mode : local->oper_hw_mode; | ||
2066 | |||
2067 | if (local->sta_hw_scanning) { | ||
2068 | /* search for the correct mode matches the beacon */ | ||
2069 | list_for_each_entry(mode, &local->modes_list, list) | ||
2070 | if (mode->mode == rx_status->phymode) | ||
2071 | break; | ||
2072 | 2100 | ||
2073 | if (mode == NULL) | 2101 | if (!sband) { |
2074 | mode = local->oper_hw_mode; | 2102 | WARN_ON(1); |
2103 | sband = local->hw.wiphy->bands[ | ||
2104 | local->hw.conf.channel->band]; | ||
2075 | } | 2105 | } |
2076 | rates = mode->rates; | 2106 | |
2077 | num_rates = mode->num_rates; | 2107 | bitrates = sband->bitrates; |
2108 | num_rates = sband->n_bitrates; | ||
2078 | 2109 | ||
2079 | supp_rates = 0; | 2110 | supp_rates = 0; |
2080 | for (i = 0; i < elems.supp_rates_len + | 2111 | for (i = 0; i < elems.supp_rates_len + |
@@ -2088,24 +2119,27 @@ static void ieee80211_rx_bss_info(struct net_device *dev, | |||
2088 | [i - elems.supp_rates_len]; | 2119 | [i - elems.supp_rates_len]; |
2089 | own_rate = 5 * (rate & 0x7f); | 2120 | own_rate = 5 * (rate & 0x7f); |
2090 | for (j = 0; j < num_rates; j++) | 2121 | for (j = 0; j < num_rates; j++) |
2091 | if (rates[j].rate == own_rate) | 2122 | if (bitrates[j].bitrate == own_rate) |
2092 | supp_rates |= BIT(j); | 2123 | supp_rates |= BIT(j); |
2093 | } | 2124 | } |
2094 | 2125 | ||
2095 | prev_rates = sta->supp_rates; | 2126 | prev_rates = sta->supp_rates[rx_status->band]; |
2096 | sta->supp_rates &= supp_rates; | 2127 | sta->supp_rates[rx_status->band] &= supp_rates; |
2097 | if (sta->supp_rates == 0) { | 2128 | if (sta->supp_rates[rx_status->band] == 0) { |
2098 | /* No matching rates - this should not really happen. | 2129 | /* No matching rates - this should not really happen. |
2099 | * Make sure that at least one rate is marked | 2130 | * Make sure that at least one rate is marked |
2100 | * supported to avoid issues with TX rate ctrl. */ | 2131 | * supported to avoid issues with TX rate ctrl. */ |
2101 | sta->supp_rates = sdata->u.sta.supp_rates_bits; | 2132 | sta->supp_rates[rx_status->band] = |
2133 | sdata->u.sta.supp_rates_bits[rx_status->band]; | ||
2102 | } | 2134 | } |
2103 | if (sta->supp_rates != prev_rates) { | 2135 | if (sta->supp_rates[rx_status->band] != prev_rates) { |
2104 | printk(KERN_DEBUG "%s: updated supp_rates set for " | 2136 | printk(KERN_DEBUG "%s: updated supp_rates set for " |
2105 | "%s based on beacon info (0x%x & 0x%x -> " | 2137 | "%s based on beacon info (0x%llx & 0x%llx -> " |
2106 | "0x%x)\n", | 2138 | "0x%llx)\n", |
2107 | dev->name, print_mac(mac, sta->addr), prev_rates, | 2139 | dev->name, print_mac(mac, sta->addr), |
2108 | supp_rates, sta->supp_rates); | 2140 | (unsigned long long) prev_rates, |
2141 | (unsigned long long) supp_rates, | ||
2142 | (unsigned long long) sta->supp_rates[rx_status->band]); | ||
2109 | } | 2143 | } |
2110 | sta_info_put(sta); | 2144 | sta_info_put(sta); |
2111 | } | 2145 | } |
@@ -2114,14 +2148,14 @@ static void ieee80211_rx_bss_info(struct net_device *dev, | |||
2114 | return; | 2148 | return; |
2115 | 2149 | ||
2116 | if (elems.ds_params && elems.ds_params_len == 1) | 2150 | if (elems.ds_params && elems.ds_params_len == 1) |
2117 | channel = elems.ds_params[0]; | 2151 | freq = ieee80211_channel_to_frequency(elems.ds_params[0]); |
2118 | else | 2152 | else |
2119 | channel = rx_status->channel; | 2153 | freq = rx_status->freq; |
2120 | 2154 | ||
2121 | bss = ieee80211_rx_bss_get(dev, mgmt->bssid, channel, | 2155 | bss = ieee80211_rx_bss_get(dev, mgmt->bssid, freq, |
2122 | elems.ssid, elems.ssid_len); | 2156 | elems.ssid, elems.ssid_len); |
2123 | if (!bss) { | 2157 | if (!bss) { |
2124 | bss = ieee80211_rx_bss_add(dev, mgmt->bssid, channel, | 2158 | bss = ieee80211_rx_bss_add(dev, mgmt->bssid, freq, |
2125 | elems.ssid, elems.ssid_len); | 2159 | elems.ssid, elems.ssid_len); |
2126 | if (!bss) | 2160 | if (!bss) |
2127 | return; | 2161 | return; |
@@ -2134,6 +2168,8 @@ static void ieee80211_rx_bss_info(struct net_device *dev, | |||
2134 | #endif | 2168 | #endif |
2135 | } | 2169 | } |
2136 | 2170 | ||
2171 | bss->band = rx_status->band; | ||
2172 | |||
2137 | if (bss->probe_resp && beacon) { | 2173 | if (bss->probe_resp && beacon) { |
2138 | /* Do not allow beacon to override data from Probe Response. */ | 2174 | /* Do not allow beacon to override data from Probe Response. */ |
2139 | ieee80211_rx_bss_put(dev, bss); | 2175 | ieee80211_rx_bss_put(dev, bss); |
@@ -2232,20 +2268,6 @@ static void ieee80211_rx_bss_info(struct net_device *dev, | |||
2232 | bss->ht_ie_len = 0; | 2268 | bss->ht_ie_len = 0; |
2233 | } | 2269 | } |
2234 | 2270 | ||
2235 | bss->hw_mode = rx_status->phymode; | ||
2236 | bss->freq = rx_status->freq; | ||
2237 | if (channel != rx_status->channel && | ||
2238 | (bss->hw_mode == MODE_IEEE80211G || | ||
2239 | bss->hw_mode == MODE_IEEE80211B) && | ||
2240 | channel >= 1 && channel <= 14) { | ||
2241 | static const int freq_list[] = { | ||
2242 | 2412, 2417, 2422, 2427, 2432, 2437, 2442, | ||
2243 | 2447, 2452, 2457, 2462, 2467, 2472, 2484 | ||
2244 | }; | ||
2245 | /* IEEE 802.11g/b mode can receive packets from neighboring | ||
2246 | * channels, so map the channel into frequency. */ | ||
2247 | bss->freq = freq_list[channel - 1]; | ||
2248 | } | ||
2249 | bss->timestamp = timestamp; | 2271 | bss->timestamp = timestamp; |
2250 | bss->last_update = jiffies; | 2272 | bss->last_update = jiffies; |
2251 | bss->rssi = rx_status->ssi; | 2273 | bss->rssi = rx_status->ssi; |
@@ -2817,7 +2839,7 @@ static int ieee80211_sta_config_auth(struct net_device *dev, | |||
2817 | } | 2839 | } |
2818 | 2840 | ||
2819 | spin_lock_bh(&local->sta_bss_lock); | 2841 | spin_lock_bh(&local->sta_bss_lock); |
2820 | freq = local->oper_channel->freq; | 2842 | freq = local->oper_channel->center_freq; |
2821 | list_for_each_entry(bss, &local->sta_bss_list, list) { | 2843 | list_for_each_entry(bss, &local->sta_bss_list, list) { |
2822 | if (!(bss->capability & WLAN_CAPABILITY_ESS)) | 2844 | if (!(bss->capability & WLAN_CAPABILITY_ESS)) |
2823 | continue; | 2845 | continue; |
@@ -2848,7 +2870,7 @@ static int ieee80211_sta_config_auth(struct net_device *dev, | |||
2848 | spin_unlock_bh(&local->sta_bss_lock); | 2870 | spin_unlock_bh(&local->sta_bss_lock); |
2849 | 2871 | ||
2850 | if (selected) { | 2872 | if (selected) { |
2851 | ieee80211_set_channel(local, -1, selected->freq); | 2873 | ieee80211_set_freq(local, selected->freq); |
2852 | if (!(ifsta->flags & IEEE80211_STA_SSID_SET)) | 2874 | if (!(ifsta->flags & IEEE80211_STA_SSID_SET)) |
2853 | ieee80211_sta_set_ssid(dev, selected->ssid, | 2875 | ieee80211_sta_set_ssid(dev, selected->ssid, |
2854 | selected->ssid_len); | 2876 | selected->ssid_len); |
@@ -2881,10 +2903,12 @@ static int ieee80211_sta_join_ibss(struct net_device *dev, | |||
2881 | struct sk_buff *skb; | 2903 | struct sk_buff *skb; |
2882 | struct ieee80211_mgmt *mgmt; | 2904 | struct ieee80211_mgmt *mgmt; |
2883 | struct ieee80211_tx_control control; | 2905 | struct ieee80211_tx_control control; |
2884 | struct ieee80211_hw_mode *mode; | ||
2885 | struct rate_selection ratesel; | 2906 | struct rate_selection ratesel; |
2886 | u8 *pos; | 2907 | u8 *pos; |
2887 | struct ieee80211_sub_if_data *sdata; | 2908 | struct ieee80211_sub_if_data *sdata; |
2909 | struct ieee80211_supported_band *sband; | ||
2910 | |||
2911 | sband = local->hw.wiphy->bands[local->hw.conf.channel->band]; | ||
2888 | 2912 | ||
2889 | /* Remove possible STA entries from other IBSS networks. */ | 2913 | /* Remove possible STA entries from other IBSS networks. */ |
2890 | sta_info_flush(local, NULL); | 2914 | sta_info_flush(local, NULL); |
@@ -2904,12 +2928,11 @@ static int ieee80211_sta_join_ibss(struct net_device *dev, | |||
2904 | sdata->drop_unencrypted = bss->capability & | 2928 | sdata->drop_unencrypted = bss->capability & |
2905 | WLAN_CAPABILITY_PRIVACY ? 1 : 0; | 2929 | WLAN_CAPABILITY_PRIVACY ? 1 : 0; |
2906 | 2930 | ||
2907 | res = ieee80211_set_channel(local, -1, bss->freq); | 2931 | res = ieee80211_set_freq(local, bss->freq); |
2908 | 2932 | ||
2909 | if (!(local->oper_channel->flag & IEEE80211_CHAN_W_IBSS)) { | 2933 | if (local->oper_channel->flags & IEEE80211_CHAN_NO_IBSS) { |
2910 | printk(KERN_DEBUG "%s: IBSS not allowed on channel %d " | 2934 | printk(KERN_DEBUG "%s: IBSS not allowed on frequency " |
2911 | "(%d MHz)\n", dev->name, local->hw.conf.channel, | 2935 | "%d MHz\n", dev->name, local->oper_channel->center_freq); |
2912 | local->hw.conf.freq); | ||
2913 | return -1; | 2936 | return -1; |
2914 | } | 2937 | } |
2915 | 2938 | ||
@@ -2946,10 +2969,12 @@ static int ieee80211_sta_join_ibss(struct net_device *dev, | |||
2946 | *pos++ = rates; | 2969 | *pos++ = rates; |
2947 | memcpy(pos, bss->supp_rates, rates); | 2970 | memcpy(pos, bss->supp_rates, rates); |
2948 | 2971 | ||
2949 | pos = skb_put(skb, 2 + 1); | 2972 | if (bss->band == IEEE80211_BAND_2GHZ) { |
2950 | *pos++ = WLAN_EID_DS_PARAMS; | 2973 | pos = skb_put(skb, 2 + 1); |
2951 | *pos++ = 1; | 2974 | *pos++ = WLAN_EID_DS_PARAMS; |
2952 | *pos++ = bss->channel; | 2975 | *pos++ = 1; |
2976 | *pos++ = ieee80211_frequency_to_channel(bss->freq); | ||
2977 | } | ||
2953 | 2978 | ||
2954 | pos = skb_put(skb, 2 + 2); | 2979 | pos = skb_put(skb, 2 + 2); |
2955 | *pos++ = WLAN_EID_IBSS_PARAMS; | 2980 | *pos++ = WLAN_EID_IBSS_PARAMS; |
@@ -2967,19 +2992,18 @@ static int ieee80211_sta_join_ibss(struct net_device *dev, | |||
2967 | } | 2992 | } |
2968 | 2993 | ||
2969 | memset(&control, 0, sizeof(control)); | 2994 | memset(&control, 0, sizeof(control)); |
2970 | rate_control_get_rate(dev, local->oper_hw_mode, skb, &ratesel); | 2995 | rate_control_get_rate(dev, sband, skb, &ratesel); |
2971 | if (!ratesel.rate) { | 2996 | if (!ratesel.rate) { |
2972 | printk(KERN_DEBUG "%s: Failed to determine TX rate " | 2997 | printk(KERN_DEBUG "%s: Failed to determine TX rate " |
2973 | "for IBSS beacon\n", dev->name); | 2998 | "for IBSS beacon\n", dev->name); |
2974 | break; | 2999 | break; |
2975 | } | 3000 | } |
2976 | control.vif = &sdata->vif; | 3001 | control.vif = &sdata->vif; |
2977 | control.tx_rate = | 3002 | control.tx_rate = ratesel.rate; |
2978 | (sdata->bss_conf.use_short_preamble && | 3003 | if (sdata->bss_conf.use_short_preamble && |
2979 | (ratesel.rate->flags & IEEE80211_RATE_PREAMBLE2)) ? | 3004 | ratesel.rate->flags & IEEE80211_RATE_SHORT_PREAMBLE) |
2980 | ratesel.rate->val2 : ratesel.rate->val; | 3005 | control.flags |= IEEE80211_TXCTL_SHORT_PREAMBLE; |
2981 | control.antenna_sel_tx = local->hw.conf.antenna_sel_tx; | 3006 | control.antenna_sel_tx = local->hw.conf.antenna_sel_tx; |
2982 | control.power_level = local->hw.conf.power_level; | ||
2983 | control.flags |= IEEE80211_TXCTL_NO_ACK; | 3007 | control.flags |= IEEE80211_TXCTL_NO_ACK; |
2984 | control.retry_limit = 1; | 3008 | control.retry_limit = 1; |
2985 | 3009 | ||
@@ -3004,14 +3028,14 @@ static int ieee80211_sta_join_ibss(struct net_device *dev, | |||
3004 | } | 3028 | } |
3005 | 3029 | ||
3006 | rates = 0; | 3030 | rates = 0; |
3007 | mode = local->oper_hw_mode; | 3031 | sband = local->hw.wiphy->bands[local->hw.conf.channel->band]; |
3008 | for (i = 0; i < bss->supp_rates_len; i++) { | 3032 | for (i = 0; i < bss->supp_rates_len; i++) { |
3009 | int bitrate = (bss->supp_rates[i] & 0x7f) * 5; | 3033 | int bitrate = (bss->supp_rates[i] & 0x7f) * 5; |
3010 | for (j = 0; j < mode->num_rates; j++) | 3034 | for (j = 0; j < sband->n_bitrates; j++) |
3011 | if (mode->rates[j].rate == bitrate) | 3035 | if (sband->bitrates[j].bitrate == bitrate) |
3012 | rates |= BIT(j); | 3036 | rates |= BIT(j); |
3013 | } | 3037 | } |
3014 | ifsta->supp_rates_bits = rates; | 3038 | ifsta->supp_rates_bits[local->hw.conf.channel->band] = rates; |
3015 | } while (0); | 3039 | } while (0); |
3016 | 3040 | ||
3017 | if (skb) { | 3041 | if (skb) { |
@@ -3035,7 +3059,7 @@ static int ieee80211_sta_create_ibss(struct net_device *dev, | |||
3035 | struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr); | 3059 | struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr); |
3036 | struct ieee80211_sta_bss *bss; | 3060 | struct ieee80211_sta_bss *bss; |
3037 | struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev); | 3061 | struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev); |
3038 | struct ieee80211_hw_mode *mode; | 3062 | struct ieee80211_supported_band *sband; |
3039 | u8 bssid[ETH_ALEN], *pos; | 3063 | u8 bssid[ETH_ALEN], *pos; |
3040 | int i; | 3064 | int i; |
3041 | DECLARE_MAC_BUF(mac); | 3065 | DECLARE_MAC_BUF(mac); |
@@ -3057,28 +3081,28 @@ static int ieee80211_sta_create_ibss(struct net_device *dev, | |||
3057 | printk(KERN_DEBUG "%s: Creating new IBSS network, BSSID %s\n", | 3081 | printk(KERN_DEBUG "%s: Creating new IBSS network, BSSID %s\n", |
3058 | dev->name, print_mac(mac, bssid)); | 3082 | dev->name, print_mac(mac, bssid)); |
3059 | 3083 | ||
3060 | bss = ieee80211_rx_bss_add(dev, bssid, local->hw.conf.channel, | 3084 | bss = ieee80211_rx_bss_add(dev, bssid, |
3085 | local->hw.conf.channel->center_freq, | ||
3061 | sdata->u.sta.ssid, sdata->u.sta.ssid_len); | 3086 | sdata->u.sta.ssid, sdata->u.sta.ssid_len); |
3062 | if (!bss) | 3087 | if (!bss) |
3063 | return -ENOMEM; | 3088 | return -ENOMEM; |
3064 | 3089 | ||
3065 | mode = local->oper_hw_mode; | 3090 | bss->band = local->hw.conf.channel->band; |
3091 | sband = local->hw.wiphy->bands[bss->band]; | ||
3066 | 3092 | ||
3067 | if (local->hw.conf.beacon_int == 0) | 3093 | if (local->hw.conf.beacon_int == 0) |
3068 | local->hw.conf.beacon_int = 100; | 3094 | local->hw.conf.beacon_int = 100; |
3069 | bss->beacon_int = local->hw.conf.beacon_int; | 3095 | bss->beacon_int = local->hw.conf.beacon_int; |
3070 | bss->hw_mode = local->hw.conf.phymode; | ||
3071 | bss->freq = local->hw.conf.freq; | ||
3072 | bss->last_update = jiffies; | 3096 | bss->last_update = jiffies; |
3073 | bss->capability = WLAN_CAPABILITY_IBSS; | 3097 | bss->capability = WLAN_CAPABILITY_IBSS; |
3074 | if (sdata->default_key) { | 3098 | if (sdata->default_key) { |
3075 | bss->capability |= WLAN_CAPABILITY_PRIVACY; | 3099 | bss->capability |= WLAN_CAPABILITY_PRIVACY; |
3076 | } else | 3100 | } else |
3077 | sdata->drop_unencrypted = 0; | 3101 | sdata->drop_unencrypted = 0; |
3078 | bss->supp_rates_len = mode->num_rates; | 3102 | bss->supp_rates_len = sband->n_bitrates; |
3079 | pos = bss->supp_rates; | 3103 | pos = bss->supp_rates; |
3080 | for (i = 0; i < mode->num_rates; i++) { | 3104 | for (i = 0; i < sband->n_bitrates; i++) { |
3081 | int rate = mode->rates[i].rate; | 3105 | int rate = sband->bitrates[i].bitrate; |
3082 | *pos++ = (u8) (rate / 5); | 3106 | *pos++ = (u8) (rate / 5); |
3083 | } | 3107 | } |
3084 | 3108 | ||
@@ -3127,7 +3151,8 @@ static int ieee80211_sta_find_ibss(struct net_device *dev, | |||
3127 | "%s\n", print_mac(mac, bssid), print_mac(mac2, ifsta->bssid)); | 3151 | "%s\n", print_mac(mac, bssid), print_mac(mac2, ifsta->bssid)); |
3128 | #endif /* CONFIG_MAC80211_IBSS_DEBUG */ | 3152 | #endif /* CONFIG_MAC80211_IBSS_DEBUG */ |
3129 | if (found && memcmp(ifsta->bssid, bssid, ETH_ALEN) != 0 && | 3153 | if (found && memcmp(ifsta->bssid, bssid, ETH_ALEN) != 0 && |
3130 | (bss = ieee80211_rx_bss_get(dev, bssid, local->hw.conf.channel, | 3154 | (bss = ieee80211_rx_bss_get(dev, bssid, |
3155 | local->hw.conf.channel->center_freq, | ||
3131 | ifsta->ssid, ifsta->ssid_len))) { | 3156 | ifsta->ssid, ifsta->ssid_len))) { |
3132 | printk(KERN_DEBUG "%s: Selected IBSS BSSID %s" | 3157 | printk(KERN_DEBUG "%s: Selected IBSS BSSID %s" |
3133 | " based on configured SSID\n", | 3158 | " based on configured SSID\n", |
@@ -3155,13 +3180,13 @@ static int ieee80211_sta_find_ibss(struct net_device *dev, | |||
3155 | if (time_after(jiffies, ifsta->ibss_join_req + | 3180 | if (time_after(jiffies, ifsta->ibss_join_req + |
3156 | IEEE80211_IBSS_JOIN_TIMEOUT)) { | 3181 | IEEE80211_IBSS_JOIN_TIMEOUT)) { |
3157 | if ((ifsta->flags & IEEE80211_STA_CREATE_IBSS) && | 3182 | if ((ifsta->flags & IEEE80211_STA_CREATE_IBSS) && |
3158 | local->oper_channel->flag & IEEE80211_CHAN_W_IBSS) | 3183 | (!(local->oper_channel->flags & |
3184 | IEEE80211_CHAN_NO_IBSS))) | ||
3159 | return ieee80211_sta_create_ibss(dev, ifsta); | 3185 | return ieee80211_sta_create_ibss(dev, ifsta); |
3160 | if (ifsta->flags & IEEE80211_STA_CREATE_IBSS) { | 3186 | if (ifsta->flags & IEEE80211_STA_CREATE_IBSS) { |
3161 | printk(KERN_DEBUG "%s: IBSS not allowed on the" | 3187 | printk(KERN_DEBUG "%s: IBSS not allowed on" |
3162 | " configured channel %d (%d MHz)\n", | 3188 | " %d MHz\n", dev->name, |
3163 | dev->name, local->hw.conf.channel, | 3189 | local->hw.conf.channel->center_freq); |
3164 | local->hw.conf.freq); | ||
3165 | } | 3190 | } |
3166 | 3191 | ||
3167 | /* No IBSS found - decrease scan interval and continue | 3192 | /* No IBSS found - decrease scan interval and continue |
@@ -3180,7 +3205,7 @@ static int ieee80211_sta_find_ibss(struct net_device *dev, | |||
3180 | 3205 | ||
3181 | int ieee80211_sta_set_ssid(struct net_device *dev, char *ssid, size_t len) | 3206 | int ieee80211_sta_set_ssid(struct net_device *dev, char *ssid, size_t len) |
3182 | { | 3207 | { |
3183 | struct ieee80211_sub_if_data *sdata; | 3208 | struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev); |
3184 | struct ieee80211_if_sta *ifsta; | 3209 | struct ieee80211_if_sta *ifsta; |
3185 | struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr); | 3210 | struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr); |
3186 | 3211 | ||
@@ -3194,18 +3219,23 @@ int ieee80211_sta_set_ssid(struct net_device *dev, char *ssid, size_t len) | |||
3194 | int i; | 3219 | int i; |
3195 | 3220 | ||
3196 | memset(&qparam, 0, sizeof(qparam)); | 3221 | memset(&qparam, 0, sizeof(qparam)); |
3197 | /* TODO: are these ok defaults for all hw_modes? */ | 3222 | |
3198 | qparam.aifs = 2; | 3223 | qparam.aifs = 2; |
3199 | qparam.cw_min = | 3224 | |
3200 | local->hw.conf.phymode == MODE_IEEE80211B ? 31 : 15; | 3225 | if (local->hw.conf.channel->band == IEEE80211_BAND_2GHZ && |
3226 | !(sdata->flags & IEEE80211_SDATA_OPERATING_GMODE)) | ||
3227 | qparam.cw_min = 31; | ||
3228 | else | ||
3229 | qparam.cw_min = 15; | ||
3230 | |||
3201 | qparam.cw_max = 1023; | 3231 | qparam.cw_max = 1023; |
3202 | qparam.burst_time = 0; | 3232 | qparam.burst_time = 0; |
3233 | |||
3203 | for (i = IEEE80211_TX_QUEUE_DATA0; i < NUM_TX_DATA_QUEUES; i++) | 3234 | for (i = IEEE80211_TX_QUEUE_DATA0; i < NUM_TX_DATA_QUEUES; i++) |
3204 | { | ||
3205 | local->ops->conf_tx(local_to_hw(local), | 3235 | local->ops->conf_tx(local_to_hw(local), |
3206 | i + IEEE80211_TX_QUEUE_DATA0, | 3236 | i + IEEE80211_TX_QUEUE_DATA0, |
3207 | &qparam); | 3237 | &qparam); |
3208 | } | 3238 | |
3209 | /* IBSS uses different parameters for Beacon sending */ | 3239 | /* IBSS uses different parameters for Beacon sending */ |
3210 | qparam.cw_min++; | 3240 | qparam.cw_min++; |
3211 | qparam.cw_min *= 2; | 3241 | qparam.cw_min *= 2; |
@@ -3214,7 +3244,6 @@ int ieee80211_sta_set_ssid(struct net_device *dev, char *ssid, size_t len) | |||
3214 | IEEE80211_TX_QUEUE_BEACON, &qparam); | 3244 | IEEE80211_TX_QUEUE_BEACON, &qparam); |
3215 | } | 3245 | } |
3216 | 3246 | ||
3217 | sdata = IEEE80211_DEV_TO_SUB_IF(dev); | ||
3218 | ifsta = &sdata->u.sta; | 3247 | ifsta = &sdata->u.sta; |
3219 | 3248 | ||
3220 | if (ifsta->ssid_len != len || memcmp(ifsta->ssid, ssid, len) != 0) | 3249 | if (ifsta->ssid_len != len || memcmp(ifsta->ssid, ssid, len) != 0) |
@@ -3373,7 +3402,7 @@ void ieee80211_sta_scan_work(struct work_struct *work) | |||
3373 | container_of(work, struct ieee80211_local, scan_work.work); | 3402 | container_of(work, struct ieee80211_local, scan_work.work); |
3374 | struct net_device *dev = local->scan_dev; | 3403 | struct net_device *dev = local->scan_dev; |
3375 | struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev); | 3404 | struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev); |
3376 | struct ieee80211_hw_mode *mode; | 3405 | struct ieee80211_supported_band *sband; |
3377 | struct ieee80211_channel *chan; | 3406 | struct ieee80211_channel *chan; |
3378 | int skip; | 3407 | int skip; |
3379 | unsigned long next_delay = 0; | 3408 | unsigned long next_delay = 0; |
@@ -3383,44 +3412,47 @@ void ieee80211_sta_scan_work(struct work_struct *work) | |||
3383 | 3412 | ||
3384 | switch (local->scan_state) { | 3413 | switch (local->scan_state) { |
3385 | case SCAN_SET_CHANNEL: | 3414 | case SCAN_SET_CHANNEL: |
3386 | mode = local->scan_hw_mode; | 3415 | /* get current scan band */ |
3387 | if (local->scan_hw_mode->list.next == &local->modes_list && | 3416 | if (local->scan_band < IEEE80211_NUM_BANDS) |
3388 | local->scan_channel_idx >= mode->num_channels) { | 3417 | sband = local->hw.wiphy->bands[local->scan_band]; |
3418 | else | ||
3419 | sband = NULL; | ||
3420 | |||
3421 | /* if we started at an unsupported one, advance */ | ||
3422 | while (!sband && local->scan_band < IEEE80211_NUM_BANDS) { | ||
3423 | local->scan_band++; | ||
3424 | sband = local->hw.wiphy->bands[local->scan_band]; | ||
3425 | local->scan_channel_idx = 0; | ||
3426 | } | ||
3427 | |||
3428 | if (!sband || | ||
3429 | (local->scan_channel_idx >= sband->n_channels && | ||
3430 | local->scan_band >= IEEE80211_NUM_BANDS)) { | ||
3389 | ieee80211_scan_completed(local_to_hw(local)); | 3431 | ieee80211_scan_completed(local_to_hw(local)); |
3390 | return; | 3432 | return; |
3391 | } | 3433 | } |
3392 | skip = !(local->enabled_modes & (1 << mode->mode)); | 3434 | skip = 0; |
3393 | chan = &mode->channels[local->scan_channel_idx]; | 3435 | chan = &sband->channels[local->scan_channel_idx]; |
3394 | if (!(chan->flag & IEEE80211_CHAN_W_SCAN) || | 3436 | |
3437 | if (chan->flags & IEEE80211_CHAN_DISABLED || | ||
3395 | (sdata->vif.type == IEEE80211_IF_TYPE_IBSS && | 3438 | (sdata->vif.type == IEEE80211_IF_TYPE_IBSS && |
3396 | !(chan->flag & IEEE80211_CHAN_W_IBSS)) || | 3439 | chan->flags & IEEE80211_CHAN_NO_IBSS)) |
3397 | (local->hw_modes & local->enabled_modes & | ||
3398 | (1 << MODE_IEEE80211G) && mode->mode == MODE_IEEE80211B)) | ||
3399 | skip = 1; | 3440 | skip = 1; |
3400 | 3441 | ||
3401 | if (!skip) { | 3442 | if (!skip) { |
3402 | #if 0 | ||
3403 | printk(KERN_DEBUG "%s: scan channel %d (%d MHz)\n", | ||
3404 | dev->name, chan->chan, chan->freq); | ||
3405 | #endif | ||
3406 | |||
3407 | local->scan_channel = chan; | 3443 | local->scan_channel = chan; |
3408 | if (ieee80211_hw_config(local)) { | 3444 | if (ieee80211_hw_config(local)) { |
3409 | printk(KERN_DEBUG "%s: failed to set channel " | 3445 | printk(KERN_DEBUG "%s: failed to set freq to " |
3410 | "%d (%d MHz) for scan\n", dev->name, | 3446 | "%d MHz for scan\n", dev->name, |
3411 | chan->chan, chan->freq); | 3447 | chan->center_freq); |
3412 | skip = 1; | 3448 | skip = 1; |
3413 | } | 3449 | } |
3414 | } | 3450 | } |
3415 | 3451 | ||
3416 | local->scan_channel_idx++; | 3452 | local->scan_channel_idx++; |
3417 | if (local->scan_channel_idx >= local->scan_hw_mode->num_channels) { | 3453 | if (local->scan_channel_idx >= sband->n_channels) { |
3418 | if (local->scan_hw_mode->list.next != &local->modes_list) { | 3454 | local->scan_band++; |
3419 | local->scan_hw_mode = list_entry(local->scan_hw_mode->list.next, | 3455 | local->scan_channel_idx = 0; |
3420 | struct ieee80211_hw_mode, | ||
3421 | list); | ||
3422 | local->scan_channel_idx = 0; | ||
3423 | } | ||
3424 | } | 3456 | } |
3425 | 3457 | ||
3426 | if (skip) | 3458 | if (skip) |
@@ -3431,13 +3463,14 @@ void ieee80211_sta_scan_work(struct work_struct *work) | |||
3431 | local->scan_state = SCAN_SEND_PROBE; | 3463 | local->scan_state = SCAN_SEND_PROBE; |
3432 | break; | 3464 | break; |
3433 | case SCAN_SEND_PROBE: | 3465 | case SCAN_SEND_PROBE: |
3434 | if (local->scan_channel->flag & IEEE80211_CHAN_W_ACTIVE_SCAN) { | 3466 | next_delay = IEEE80211_PASSIVE_CHANNEL_TIME; |
3435 | ieee80211_send_probe_req(dev, NULL, local->scan_ssid, | ||
3436 | local->scan_ssid_len); | ||
3437 | next_delay = IEEE80211_CHANNEL_TIME; | ||
3438 | } else | ||
3439 | next_delay = IEEE80211_PASSIVE_CHANNEL_TIME; | ||
3440 | local->scan_state = SCAN_SET_CHANNEL; | 3467 | local->scan_state = SCAN_SET_CHANNEL; |
3468 | |||
3469 | if (local->scan_channel->flags & IEEE80211_CHAN_PASSIVE_SCAN) | ||
3470 | break; | ||
3471 | ieee80211_send_probe_req(dev, NULL, local->scan_ssid, | ||
3472 | local->scan_ssid_len); | ||
3473 | next_delay = IEEE80211_CHANNEL_TIME; | ||
3441 | break; | 3474 | break; |
3442 | } | 3475 | } |
3443 | 3476 | ||
@@ -3512,10 +3545,8 @@ static int ieee80211_sta_start_scan(struct net_device *dev, | |||
3512 | } else | 3545 | } else |
3513 | local->scan_ssid_len = 0; | 3546 | local->scan_ssid_len = 0; |
3514 | local->scan_state = SCAN_SET_CHANNEL; | 3547 | local->scan_state = SCAN_SET_CHANNEL; |
3515 | local->scan_hw_mode = list_entry(local->modes_list.next, | ||
3516 | struct ieee80211_hw_mode, | ||
3517 | list); | ||
3518 | local->scan_channel_idx = 0; | 3548 | local->scan_channel_idx = 0; |
3549 | local->scan_band = IEEE80211_BAND_2GHZ; | ||
3519 | local->scan_dev = dev; | 3550 | local->scan_dev = dev; |
3520 | 3551 | ||
3521 | netif_tx_lock_bh(local->mdev); | 3552 | netif_tx_lock_bh(local->mdev); |
@@ -3570,9 +3601,6 @@ ieee80211_sta_scan_result(struct net_device *dev, | |||
3570 | bss->last_update + IEEE80211_SCAN_RESULT_EXPIRE)) | 3601 | bss->last_update + IEEE80211_SCAN_RESULT_EXPIRE)) |
3571 | return current_ev; | 3602 | return current_ev; |
3572 | 3603 | ||
3573 | if (!(local->enabled_modes & (1 << bss->hw_mode))) | ||
3574 | return current_ev; | ||
3575 | |||
3576 | memset(&iwe, 0, sizeof(iwe)); | 3604 | memset(&iwe, 0, sizeof(iwe)); |
3577 | iwe.cmd = SIOCGIWAP; | 3605 | iwe.cmd = SIOCGIWAP; |
3578 | iwe.u.ap_addr.sa_family = ARPHRD_ETHER; | 3606 | iwe.u.ap_addr.sa_family = ARPHRD_ETHER; |
@@ -3600,12 +3628,15 @@ ieee80211_sta_scan_result(struct net_device *dev, | |||
3600 | 3628 | ||
3601 | memset(&iwe, 0, sizeof(iwe)); | 3629 | memset(&iwe, 0, sizeof(iwe)); |
3602 | iwe.cmd = SIOCGIWFREQ; | 3630 | iwe.cmd = SIOCGIWFREQ; |
3603 | iwe.u.freq.m = bss->channel; | 3631 | iwe.u.freq.m = bss->freq; |
3604 | iwe.u.freq.e = 0; | 3632 | iwe.u.freq.e = 6; |
3605 | current_ev = iwe_stream_add_event(current_ev, end_buf, &iwe, | 3633 | current_ev = iwe_stream_add_event(current_ev, end_buf, &iwe, |
3606 | IW_EV_FREQ_LEN); | 3634 | IW_EV_FREQ_LEN); |
3607 | iwe.u.freq.m = bss->freq * 100000; | 3635 | |
3608 | iwe.u.freq.e = 1; | 3636 | memset(&iwe, 0, sizeof(iwe)); |
3637 | iwe.cmd = SIOCGIWFREQ; | ||
3638 | iwe.u.freq.m = ieee80211_frequency_to_channel(bss->freq); | ||
3639 | iwe.u.freq.e = 0; | ||
3609 | current_ev = iwe_stream_add_event(current_ev, end_buf, &iwe, | 3640 | current_ev = iwe_stream_add_event(current_ev, end_buf, &iwe, |
3610 | IW_EV_FREQ_LEN); | 3641 | IW_EV_FREQ_LEN); |
3611 | 3642 | ||
@@ -3748,7 +3779,8 @@ struct sta_info * ieee80211_ibss_add_sta(struct net_device *dev, | |||
3748 | if (!sta) | 3779 | if (!sta) |
3749 | return NULL; | 3780 | return NULL; |
3750 | 3781 | ||
3751 | sta->supp_rates = sdata->u.sta.supp_rates_bits; | 3782 | sta->supp_rates[local->hw.conf.channel->band] = |
3783 | sdata->u.sta.supp_rates_bits[local->hw.conf.channel->band]; | ||
3752 | 3784 | ||
3753 | rate_control_rate_init(sta, local); | 3785 | rate_control_rate_init(sta, local); |
3754 | 3786 | ||