diff options
Diffstat (limited to 'net/mac80211/scan.c')
| -rw-r--r-- | net/mac80211/scan.c | 53 |
1 files changed, 40 insertions, 13 deletions
diff --git a/net/mac80211/scan.c b/net/mac80211/scan.c index e1a3defdf581..e14c44195ae9 100644 --- a/net/mac80211/scan.c +++ b/net/mac80211/scan.c | |||
| @@ -85,7 +85,7 @@ ieee80211_bss_info_update(struct ieee80211_local *local, | |||
| 85 | { | 85 | { |
| 86 | struct cfg80211_bss *cbss; | 86 | struct cfg80211_bss *cbss; |
| 87 | struct ieee80211_bss *bss; | 87 | struct ieee80211_bss *bss; |
| 88 | int clen; | 88 | int clen, srlen; |
| 89 | s32 signal = 0; | 89 | s32 signal = 0; |
| 90 | 90 | ||
| 91 | if (local->hw.flags & IEEE80211_HW_SIGNAL_DBM) | 91 | if (local->hw.flags & IEEE80211_HW_SIGNAL_DBM) |
| @@ -114,23 +114,24 @@ ieee80211_bss_info_update(struct ieee80211_local *local, | |||
| 114 | bss->dtim_period = tim_ie->dtim_period; | 114 | bss->dtim_period = tim_ie->dtim_period; |
| 115 | } | 115 | } |
| 116 | 116 | ||
| 117 | bss->supp_rates_len = 0; | 117 | /* replace old supported rates if we get new values */ |
| 118 | srlen = 0; | ||
| 118 | if (elems->supp_rates) { | 119 | if (elems->supp_rates) { |
| 119 | clen = IEEE80211_MAX_SUPP_RATES - bss->supp_rates_len; | 120 | clen = IEEE80211_MAX_SUPP_RATES; |
| 120 | if (clen > elems->supp_rates_len) | 121 | if (clen > elems->supp_rates_len) |
| 121 | clen = elems->supp_rates_len; | 122 | clen = elems->supp_rates_len; |
| 122 | memcpy(&bss->supp_rates[bss->supp_rates_len], elems->supp_rates, | 123 | memcpy(bss->supp_rates, elems->supp_rates, clen); |
| 123 | clen); | 124 | srlen += clen; |
| 124 | bss->supp_rates_len += clen; | ||
| 125 | } | 125 | } |
| 126 | if (elems->ext_supp_rates) { | 126 | if (elems->ext_supp_rates) { |
| 127 | clen = IEEE80211_MAX_SUPP_RATES - bss->supp_rates_len; | 127 | clen = IEEE80211_MAX_SUPP_RATES - srlen; |
| 128 | if (clen > elems->ext_supp_rates_len) | 128 | if (clen > elems->ext_supp_rates_len) |
| 129 | clen = elems->ext_supp_rates_len; | 129 | clen = elems->ext_supp_rates_len; |
| 130 | memcpy(&bss->supp_rates[bss->supp_rates_len], | 130 | memcpy(bss->supp_rates + srlen, elems->ext_supp_rates, clen); |
| 131 | elems->ext_supp_rates, clen); | 131 | srlen += clen; |
| 132 | bss->supp_rates_len += clen; | ||
| 133 | } | 132 | } |
| 133 | if (srlen) | ||
| 134 | bss->supp_rates_len = srlen; | ||
| 134 | 135 | ||
| 135 | bss->wmm_used = elems->wmm_param || elems->wmm_info; | 136 | bss->wmm_used = elems->wmm_param || elems->wmm_info; |
| 136 | bss->uapsd_supported = is_uapsd_supported(elems); | 137 | bss->uapsd_supported = is_uapsd_supported(elems); |
| @@ -411,7 +412,7 @@ static int __ieee80211_start_scan(struct ieee80211_sub_if_data *sdata, | |||
| 411 | 412 | ||
| 412 | if (local->ops->hw_scan) { | 413 | if (local->ops->hw_scan) { |
| 413 | WARN_ON(!ieee80211_prep_hw_scan(local)); | 414 | WARN_ON(!ieee80211_prep_hw_scan(local)); |
| 414 | rc = drv_hw_scan(local, local->hw_scan_req); | 415 | rc = drv_hw_scan(local, sdata, local->hw_scan_req); |
| 415 | } else | 416 | } else |
| 416 | rc = ieee80211_start_sw_scan(local); | 417 | rc = ieee80211_start_sw_scan(local); |
| 417 | 418 | ||
| @@ -655,7 +656,7 @@ void ieee80211_scan_work(struct work_struct *work) | |||
| 655 | } | 656 | } |
| 656 | 657 | ||
| 657 | if (local->hw_scan_req) { | 658 | if (local->hw_scan_req) { |
| 658 | int rc = drv_hw_scan(local, local->hw_scan_req); | 659 | int rc = drv_hw_scan(local, sdata, local->hw_scan_req); |
| 659 | mutex_unlock(&local->scan_mtx); | 660 | mutex_unlock(&local->scan_mtx); |
| 660 | if (rc) | 661 | if (rc) |
| 661 | ieee80211_scan_completed(&local->hw, true); | 662 | ieee80211_scan_completed(&local->hw, true); |
| @@ -728,10 +729,12 @@ int ieee80211_request_scan(struct ieee80211_sub_if_data *sdata, | |||
| 728 | } | 729 | } |
| 729 | 730 | ||
| 730 | int ieee80211_request_internal_scan(struct ieee80211_sub_if_data *sdata, | 731 | int ieee80211_request_internal_scan(struct ieee80211_sub_if_data *sdata, |
| 731 | const u8 *ssid, u8 ssid_len) | 732 | const u8 *ssid, u8 ssid_len, |
| 733 | struct ieee80211_channel *chan) | ||
| 732 | { | 734 | { |
| 733 | struct ieee80211_local *local = sdata->local; | 735 | struct ieee80211_local *local = sdata->local; |
| 734 | int ret = -EBUSY; | 736 | int ret = -EBUSY; |
| 737 | enum nl80211_band band; | ||
| 735 | 738 | ||
| 736 | mutex_lock(&local->scan_mtx); | 739 | mutex_lock(&local->scan_mtx); |
| 737 | 740 | ||
| @@ -739,6 +742,30 @@ int ieee80211_request_internal_scan(struct ieee80211_sub_if_data *sdata, | |||
| 739 | if (local->scan_req) | 742 | if (local->scan_req) |
| 740 | goto unlock; | 743 | goto unlock; |
| 741 | 744 | ||
| 745 | /* fill internal scan request */ | ||
| 746 | if (!chan) { | ||
| 747 | int i, nchan = 0; | ||
| 748 | |||
| 749 | for (band = 0; band < IEEE80211_NUM_BANDS; band++) { | ||
| 750 | if (!local->hw.wiphy->bands[band]) | ||
| 751 | continue; | ||
| 752 | for (i = 0; | ||
| 753 | i < local->hw.wiphy->bands[band]->n_channels; | ||
| 754 | i++) { | ||
| 755 | local->int_scan_req->channels[nchan] = | ||
| 756 | &local->hw.wiphy->bands[band]->channels[i]; | ||
| 757 | nchan++; | ||
| 758 | } | ||
| 759 | } | ||
| 760 | |||
| 761 | local->int_scan_req->n_channels = nchan; | ||
| 762 | } else { | ||
| 763 | local->int_scan_req->channels[0] = chan; | ||
| 764 | local->int_scan_req->n_channels = 1; | ||
| 765 | } | ||
| 766 | |||
| 767 | local->int_scan_req->ssids = &local->scan_ssid; | ||
| 768 | local->int_scan_req->n_ssids = 1; | ||
| 742 | memcpy(local->int_scan_req->ssids[0].ssid, ssid, IEEE80211_MAX_SSID_LEN); | 769 | memcpy(local->int_scan_req->ssids[0].ssid, ssid, IEEE80211_MAX_SSID_LEN); |
| 743 | local->int_scan_req->ssids[0].ssid_len = ssid_len; | 770 | local->int_scan_req->ssids[0].ssid_len = ssid_len; |
| 744 | 771 | ||
