aboutsummaryrefslogtreecommitdiffstats
path: root/net/mac80211
diff options
context:
space:
mode:
authorJohn W. Linville <linville@tuxdriver.com>2013-11-04 14:45:14 -0500
committerJohn W. Linville <linville@tuxdriver.com>2013-11-04 14:45:14 -0500
commit01925efdf7e03b4b803b5c9f985163d687f7f017 (patch)
tree6c318f9bf002efac5ccd87e8edad35863d72bd17 /net/mac80211
parenta1b13b9ad3759dca24c6b721ee026c540a4e6564 (diff)
parent8ce9beac4661f576ea0d518b9f086bb52a171a37 (diff)
Merge branch 'master' of git://git.kernel.org/pub/scm/linux/kernel/git/linville/wireless
Conflicts: drivers/net/wireless/iwlwifi/pcie/drv.c
Diffstat (limited to 'net/mac80211')
-rw-r--r--net/mac80211/cfg.c2
-rw-r--r--net/mac80211/ieee80211_i.h4
-rw-r--r--net/mac80211/mlme.c95
-rw-r--r--net/mac80211/offchannel.c2
-rw-r--r--net/mac80211/rate.c15
-rw-r--r--net/mac80211/rx.c3
-rw-r--r--net/mac80211/scan.c19
-rw-r--r--net/mac80211/status.c3
-rw-r--r--net/mac80211/tx.c3
-rw-r--r--net/mac80211/util.c9
10 files changed, 137 insertions, 18 deletions
diff --git a/net/mac80211/cfg.c b/net/mac80211/cfg.c
index ac28af74a414..b0a651cc389f 100644
--- a/net/mac80211/cfg.c
+++ b/net/mac80211/cfg.c
@@ -3564,7 +3564,7 @@ static int ieee80211_probe_client(struct wiphy *wiphy, struct net_device *dev,
3564 return -EINVAL; 3564 return -EINVAL;
3565 } 3565 }
3566 band = chanctx_conf->def.chan->band; 3566 band = chanctx_conf->def.chan->band;
3567 sta = sta_info_get(sdata, peer); 3567 sta = sta_info_get_bss(sdata, peer);
3568 if (sta) { 3568 if (sta) {
3569 qos = test_sta_flag(sta, WLAN_STA_WME); 3569 qos = test_sta_flag(sta, WLAN_STA_WME);
3570 } else { 3570 } else {
diff --git a/net/mac80211/ieee80211_i.h b/net/mac80211/ieee80211_i.h
index 3a87c8976a32..fe48b093d4dc 100644
--- a/net/mac80211/ieee80211_i.h
+++ b/net/mac80211/ieee80211_i.h
@@ -334,6 +334,7 @@ enum ieee80211_sta_flags {
334 IEEE80211_STA_DISABLE_VHT = BIT(11), 334 IEEE80211_STA_DISABLE_VHT = BIT(11),
335 IEEE80211_STA_DISABLE_80P80MHZ = BIT(12), 335 IEEE80211_STA_DISABLE_80P80MHZ = BIT(12),
336 IEEE80211_STA_DISABLE_160MHZ = BIT(13), 336 IEEE80211_STA_DISABLE_160MHZ = BIT(13),
337 IEEE80211_STA_DISABLE_WMM = BIT(14),
337}; 338};
338 339
339struct ieee80211_mgd_auth_data { 340struct ieee80211_mgd_auth_data {
@@ -893,6 +894,8 @@ struct tpt_led_trigger {
893 * that the scan completed. 894 * that the scan completed.
894 * @SCAN_ABORTED: Set for our scan work function when the driver reported 895 * @SCAN_ABORTED: Set for our scan work function when the driver reported
895 * a scan complete for an aborted scan. 896 * a scan complete for an aborted scan.
897 * @SCAN_HW_CANCELLED: Set for our scan work function when the scan is being
898 * cancelled.
896 */ 899 */
897enum { 900enum {
898 SCAN_SW_SCANNING, 901 SCAN_SW_SCANNING,
@@ -900,6 +903,7 @@ enum {
900 SCAN_ONCHANNEL_SCANNING, 903 SCAN_ONCHANNEL_SCANNING,
901 SCAN_COMPLETED, 904 SCAN_COMPLETED,
902 SCAN_ABORTED, 905 SCAN_ABORTED,
906 SCAN_HW_CANCELLED,
903}; 907};
904 908
905/** 909/**
diff --git a/net/mac80211/mlme.c b/net/mac80211/mlme.c
index 91cc8281e266..d7bdc4b97dde 100644
--- a/net/mac80211/mlme.c
+++ b/net/mac80211/mlme.c
@@ -2527,7 +2527,7 @@ static bool ieee80211_assoc_success(struct ieee80211_sub_if_data *sdata,
2527 */ 2527 */
2528 ifmgd->wmm_last_param_set = -1; 2528 ifmgd->wmm_last_param_set = -1;
2529 2529
2530 if (elems.wmm_param) 2530 if (!(ifmgd->flags & IEEE80211_STA_DISABLE_WMM) && elems.wmm_param)
2531 ieee80211_sta_wmm_params(local, sdata, elems.wmm_param, 2531 ieee80211_sta_wmm_params(local, sdata, elems.wmm_param,
2532 elems.wmm_param_len); 2532 elems.wmm_param_len);
2533 else 2533 else
@@ -2955,7 +2955,8 @@ static void ieee80211_rx_mgmt_beacon(struct ieee80211_sub_if_data *sdata,
2955 ieee80211_sta_process_chanswitch(sdata, rx_status->mactime, 2955 ieee80211_sta_process_chanswitch(sdata, rx_status->mactime,
2956 &elems, true); 2956 &elems, true);
2957 2957
2958 if (ieee80211_sta_wmm_params(local, sdata, elems.wmm_param, 2958 if (!(ifmgd->flags & IEEE80211_STA_DISABLE_WMM) &&
2959 ieee80211_sta_wmm_params(local, sdata, elems.wmm_param,
2959 elems.wmm_param_len)) 2960 elems.wmm_param_len))
2960 changed |= BSS_CHANGED_QOS; 2961 changed |= BSS_CHANGED_QOS;
2961 2962
@@ -3937,6 +3938,44 @@ int ieee80211_mgd_auth(struct ieee80211_sub_if_data *sdata,
3937 return err; 3938 return err;
3938} 3939}
3939 3940
3941static bool ieee80211_usable_wmm_params(struct ieee80211_sub_if_data *sdata,
3942 const u8 *wmm_param, int len)
3943{
3944 const u8 *pos;
3945 size_t left;
3946
3947 if (len < 8)
3948 return false;
3949
3950 if (wmm_param[5] != 1 /* version */)
3951 return false;
3952
3953 pos = wmm_param + 8;
3954 left = len - 8;
3955
3956 for (; left >= 4; left -= 4, pos += 4) {
3957 u8 aifsn = pos[0] & 0x0f;
3958 u8 ecwmin = pos[1] & 0x0f;
3959 u8 ecwmax = (pos[1] & 0xf0) >> 4;
3960 int aci = (pos[0] >> 5) & 0x03;
3961
3962 if (aifsn < 2) {
3963 sdata_info(sdata,
3964 "AP has invalid WMM params (AIFSN=%d for ACI %d), disabling WMM\n",
3965 aifsn, aci);
3966 return false;
3967 }
3968 if (ecwmin > ecwmax) {
3969 sdata_info(sdata,
3970 "AP has invalid WMM params (ECWmin/max=%d/%d for ACI %d), disabling WMM\n",
3971 ecwmin, ecwmax, aci);
3972 return false;
3973 }
3974 }
3975
3976 return true;
3977}
3978
3940int ieee80211_mgd_assoc(struct ieee80211_sub_if_data *sdata, 3979int ieee80211_mgd_assoc(struct ieee80211_sub_if_data *sdata,
3941 struct cfg80211_assoc_request *req) 3980 struct cfg80211_assoc_request *req)
3942{ 3981{
@@ -3994,9 +4033,45 @@ int ieee80211_mgd_assoc(struct ieee80211_sub_if_data *sdata,
3994 } 4033 }
3995 4034
3996 /* prepare assoc data */ 4035 /* prepare assoc data */
3997 4036
3998 ifmgd->beacon_crc_valid = false; 4037 ifmgd->beacon_crc_valid = false;
3999 4038
4039 assoc_data->wmm = bss->wmm_used &&
4040 (local->hw.queues >= IEEE80211_NUM_ACS);
4041 if (assoc_data->wmm) {
4042 /* try to check validity of WMM params IE */
4043 const struct cfg80211_bss_ies *ies;
4044 const u8 *wp, *start, *end;
4045
4046 rcu_read_lock();
4047 ies = rcu_dereference(req->bss->ies);
4048 start = ies->data;
4049 end = start + ies->len;
4050
4051 while (true) {
4052 wp = cfg80211_find_vendor_ie(
4053 WLAN_OUI_MICROSOFT,
4054 WLAN_OUI_TYPE_MICROSOFT_WMM,
4055 start, end - start);
4056 if (!wp)
4057 break;
4058 start = wp + wp[1] + 2;
4059 /* if this IE is too short, try the next */
4060 if (wp[1] <= 4)
4061 continue;
4062 /* if this IE is WMM params, we found what we wanted */
4063 if (wp[6] == 1)
4064 break;
4065 }
4066
4067 if (!wp || !ieee80211_usable_wmm_params(sdata, wp + 2,
4068 wp[1] - 2)) {
4069 assoc_data->wmm = false;
4070 ifmgd->flags |= IEEE80211_STA_DISABLE_WMM;
4071 }
4072 rcu_read_unlock();
4073 }
4074
4000 /* 4075 /*
4001 * IEEE802.11n does not allow TKIP/WEP as pairwise ciphers in HT mode. 4076 * IEEE802.11n does not allow TKIP/WEP as pairwise ciphers in HT mode.
4002 * We still associate in non-HT mode (11a/b/g) if any one of these 4077 * We still associate in non-HT mode (11a/b/g) if any one of these
@@ -4026,18 +4101,22 @@ int ieee80211_mgd_assoc(struct ieee80211_sub_if_data *sdata,
4026 /* Also disable HT if we don't support it or the AP doesn't use WMM */ 4101 /* Also disable HT if we don't support it or the AP doesn't use WMM */
4027 sband = local->hw.wiphy->bands[req->bss->channel->band]; 4102 sband = local->hw.wiphy->bands[req->bss->channel->band];
4028 if (!sband->ht_cap.ht_supported || 4103 if (!sband->ht_cap.ht_supported ||
4029 local->hw.queues < IEEE80211_NUM_ACS || !bss->wmm_used) { 4104 local->hw.queues < IEEE80211_NUM_ACS || !bss->wmm_used ||
4105 ifmgd->flags & IEEE80211_STA_DISABLE_WMM) {
4030 ifmgd->flags |= IEEE80211_STA_DISABLE_HT; 4106 ifmgd->flags |= IEEE80211_STA_DISABLE_HT;
4031 if (!bss->wmm_used) 4107 if (!bss->wmm_used &&
4108 !(ifmgd->flags & IEEE80211_STA_DISABLE_WMM))
4032 netdev_info(sdata->dev, 4109 netdev_info(sdata->dev,
4033 "disabling HT as WMM/QoS is not supported by the AP\n"); 4110 "disabling HT as WMM/QoS is not supported by the AP\n");
4034 } 4111 }
4035 4112
4036 /* disable VHT if we don't support it or the AP doesn't use WMM */ 4113 /* disable VHT if we don't support it or the AP doesn't use WMM */
4037 if (!sband->vht_cap.vht_supported || 4114 if (!sband->vht_cap.vht_supported ||
4038 local->hw.queues < IEEE80211_NUM_ACS || !bss->wmm_used) { 4115 local->hw.queues < IEEE80211_NUM_ACS || !bss->wmm_used ||
4116 ifmgd->flags & IEEE80211_STA_DISABLE_WMM) {
4039 ifmgd->flags |= IEEE80211_STA_DISABLE_VHT; 4117 ifmgd->flags |= IEEE80211_STA_DISABLE_VHT;
4040 if (!bss->wmm_used) 4118 if (!bss->wmm_used &&
4119 !(ifmgd->flags & IEEE80211_STA_DISABLE_WMM))
4041 netdev_info(sdata->dev, 4120 netdev_info(sdata->dev,
4042 "disabling VHT as WMM/QoS is not supported by the AP\n"); 4121 "disabling VHT as WMM/QoS is not supported by the AP\n");
4043 } 4122 }
@@ -4066,8 +4145,6 @@ int ieee80211_mgd_assoc(struct ieee80211_sub_if_data *sdata,
4066 sdata->smps_mode = ifmgd->req_smps; 4145 sdata->smps_mode = ifmgd->req_smps;
4067 4146
4068 assoc_data->capability = req->bss->capability; 4147 assoc_data->capability = req->bss->capability;
4069 assoc_data->wmm = bss->wmm_used &&
4070 (local->hw.queues >= IEEE80211_NUM_ACS);
4071 assoc_data->supp_rates = bss->supp_rates; 4148 assoc_data->supp_rates = bss->supp_rates;
4072 assoc_data->supp_rates_len = bss->supp_rates_len; 4149 assoc_data->supp_rates_len = bss->supp_rates_len;
4073 4150
diff --git a/net/mac80211/offchannel.c b/net/mac80211/offchannel.c
index acd1f71adc03..0c2a29484c07 100644
--- a/net/mac80211/offchannel.c
+++ b/net/mac80211/offchannel.c
@@ -394,6 +394,8 @@ void ieee80211_sw_roc_work(struct work_struct *work)
394 394
395 if (started) 395 if (started)
396 ieee80211_start_next_roc(local); 396 ieee80211_start_next_roc(local);
397 else if (list_empty(&local->roc_list))
398 ieee80211_run_deferred_scan(local);
397 } 399 }
398 400
399 out_unlock: 401 out_unlock:
diff --git a/net/mac80211/rate.c b/net/mac80211/rate.c
index e126605cec66..22b223f13c9f 100644
--- a/net/mac80211/rate.c
+++ b/net/mac80211/rate.c
@@ -235,7 +235,8 @@ static void rc_send_low_basicrate(s8 *idx, u32 basic_rates,
235static void __rate_control_send_low(struct ieee80211_hw *hw, 235static void __rate_control_send_low(struct ieee80211_hw *hw,
236 struct ieee80211_supported_band *sband, 236 struct ieee80211_supported_band *sband,
237 struct ieee80211_sta *sta, 237 struct ieee80211_sta *sta,
238 struct ieee80211_tx_info *info) 238 struct ieee80211_tx_info *info,
239 u32 rate_mask)
239{ 240{
240 int i; 241 int i;
241 u32 rate_flags = 242 u32 rate_flags =
@@ -247,6 +248,12 @@ static void __rate_control_send_low(struct ieee80211_hw *hw,
247 248
248 info->control.rates[0].idx = 0; 249 info->control.rates[0].idx = 0;
249 for (i = 0; i < sband->n_bitrates; i++) { 250 for (i = 0; i < sband->n_bitrates; i++) {
251 if (!(rate_mask & BIT(i)))
252 continue;
253
254 if ((rate_flags & sband->bitrates[i].flags) != rate_flags)
255 continue;
256
250 if (!rate_supported(sta, sband->band, i)) 257 if (!rate_supported(sta, sband->band, i))
251 continue; 258 continue;
252 259
@@ -274,7 +281,8 @@ bool rate_control_send_low(struct ieee80211_sta *pubsta,
274 bool use_basicrate = false; 281 bool use_basicrate = false;
275 282
276 if (!pubsta || !priv_sta || rc_no_data_or_no_ack_use_min(txrc)) { 283 if (!pubsta || !priv_sta || rc_no_data_or_no_ack_use_min(txrc)) {
277 __rate_control_send_low(txrc->hw, sband, pubsta, info); 284 __rate_control_send_low(txrc->hw, sband, pubsta, info,
285 txrc->rate_idx_mask);
278 286
279 if (!pubsta && txrc->bss) { 287 if (!pubsta && txrc->bss) {
280 mcast_rate = txrc->bss_conf->mcast_rate[sband->band]; 288 mcast_rate = txrc->bss_conf->mcast_rate[sband->band];
@@ -656,7 +664,8 @@ void ieee80211_get_tx_rates(struct ieee80211_vif *vif,
656 rate_control_apply_mask(sdata, sta, sband, info, dest, max_rates); 664 rate_control_apply_mask(sdata, sta, sband, info, dest, max_rates);
657 665
658 if (dest[0].idx < 0) 666 if (dest[0].idx < 0)
659 __rate_control_send_low(&sdata->local->hw, sband, sta, info); 667 __rate_control_send_low(&sdata->local->hw, sband, sta, info,
668 sdata->rc_rateidx_mask[info->band]);
660 669
661 if (sta) 670 if (sta)
662 rate_fixup_ratelist(vif, sband, info, dest, max_rates); 671 rate_fixup_ratelist(vif, sband, info, dest, max_rates);
diff --git a/net/mac80211/rx.c b/net/mac80211/rx.c
index f0247a43a75c..0011ac815097 100644
--- a/net/mac80211/rx.c
+++ b/net/mac80211/rx.c
@@ -3073,6 +3073,9 @@ static int prepare_for_handlers(struct ieee80211_rx_data *rx,
3073 case NL80211_IFTYPE_ADHOC: 3073 case NL80211_IFTYPE_ADHOC:
3074 if (!bssid) 3074 if (!bssid)
3075 return 0; 3075 return 0;
3076 if (ether_addr_equal(sdata->vif.addr, hdr->addr2) ||
3077 ether_addr_equal(sdata->u.ibss.bssid, hdr->addr2))
3078 return 0;
3076 if (ieee80211_is_beacon(hdr->frame_control)) { 3079 if (ieee80211_is_beacon(hdr->frame_control)) {
3077 return 1; 3080 return 1;
3078 } else if (!ieee80211_bssid_match(bssid, sdata->u.ibss.bssid)) { 3081 } else if (!ieee80211_bssid_match(bssid, sdata->u.ibss.bssid)) {
diff --git a/net/mac80211/scan.c b/net/mac80211/scan.c
index ecb57b0bf74a..5ad66a83ef7f 100644
--- a/net/mac80211/scan.c
+++ b/net/mac80211/scan.c
@@ -238,6 +238,9 @@ static bool ieee80211_prep_hw_scan(struct ieee80211_local *local)
238 enum ieee80211_band band; 238 enum ieee80211_band band;
239 int i, ielen, n_chans; 239 int i, ielen, n_chans;
240 240
241 if (test_bit(SCAN_HW_CANCELLED, &local->scanning))
242 return false;
243
241 do { 244 do {
242 if (local->hw_scan_band == IEEE80211_NUM_BANDS) 245 if (local->hw_scan_band == IEEE80211_NUM_BANDS)
243 return false; 246 return false;
@@ -939,7 +942,23 @@ void ieee80211_scan_cancel(struct ieee80211_local *local)
939 if (!local->scan_req) 942 if (!local->scan_req)
940 goto out; 943 goto out;
941 944
945 /*
946 * We have a scan running and the driver already reported completion,
947 * but the worker hasn't run yet or is stuck on the mutex - mark it as
948 * cancelled.
949 */
950 if (test_bit(SCAN_HW_SCANNING, &local->scanning) &&
951 test_bit(SCAN_COMPLETED, &local->scanning)) {
952 set_bit(SCAN_HW_CANCELLED, &local->scanning);
953 goto out;
954 }
955
942 if (test_bit(SCAN_HW_SCANNING, &local->scanning)) { 956 if (test_bit(SCAN_HW_SCANNING, &local->scanning)) {
957 /*
958 * Make sure that __ieee80211_scan_completed doesn't trigger a
959 * scan on another band.
960 */
961 set_bit(SCAN_HW_CANCELLED, &local->scanning);
943 if (local->ops->cancel_hw_scan) 962 if (local->ops->cancel_hw_scan)
944 drv_cancel_hw_scan(local, 963 drv_cancel_hw_scan(local,
945 rcu_dereference_protected(local->scan_sdata, 964 rcu_dereference_protected(local->scan_sdata,
diff --git a/net/mac80211/status.c b/net/mac80211/status.c
index 368837fe3b80..78dc2e99027e 100644
--- a/net/mac80211/status.c
+++ b/net/mac80211/status.c
@@ -180,6 +180,9 @@ static void ieee80211_frame_acked(struct sta_info *sta, struct sk_buff *skb)
180 struct ieee80211_local *local = sta->local; 180 struct ieee80211_local *local = sta->local;
181 struct ieee80211_sub_if_data *sdata = sta->sdata; 181 struct ieee80211_sub_if_data *sdata = sta->sdata;
182 182
183 if (local->hw.flags & IEEE80211_HW_REPORTS_TX_ACK_STATUS)
184 sta->last_rx = jiffies;
185
183 if (ieee80211_is_data_qos(mgmt->frame_control)) { 186 if (ieee80211_is_data_qos(mgmt->frame_control)) {
184 struct ieee80211_hdr *hdr = (void *) skb->data; 187 struct ieee80211_hdr *hdr = (void *) skb->data;
185 u8 *qc = ieee80211_get_qos_ctl(hdr); 188 u8 *qc = ieee80211_get_qos_ctl(hdr);
diff --git a/net/mac80211/tx.c b/net/mac80211/tx.c
index 4fcbf634b548..9993fcb19ecd 100644
--- a/net/mac80211/tx.c
+++ b/net/mac80211/tx.c
@@ -1120,7 +1120,8 @@ ieee80211_tx_prepare(struct ieee80211_sub_if_data *sdata,
1120 tx->sta = rcu_dereference(sdata->u.vlan.sta); 1120 tx->sta = rcu_dereference(sdata->u.vlan.sta);
1121 if (!tx->sta && sdata->dev->ieee80211_ptr->use_4addr) 1121 if (!tx->sta && sdata->dev->ieee80211_ptr->use_4addr)
1122 return TX_DROP; 1122 return TX_DROP;
1123 } else if (info->flags & IEEE80211_TX_CTL_INJECTED || 1123 } else if (info->flags & (IEEE80211_TX_CTL_INJECTED |
1124 IEEE80211_TX_INTFL_NL80211_FRAME_TX) ||
1124 tx->sdata->control_port_protocol == tx->skb->protocol) { 1125 tx->sdata->control_port_protocol == tx->skb->protocol) {
1125 tx->sta = sta_info_get_bss(sdata, hdr->addr1); 1126 tx->sta = sta_info_get_bss(sdata, hdr->addr1);
1126 } 1127 }
diff --git a/net/mac80211/util.c b/net/mac80211/util.c
index 550a6880625d..aefb9d5b9620 100644
--- a/net/mac80211/util.c
+++ b/net/mac80211/util.c
@@ -2101,7 +2101,7 @@ int ieee80211_add_ext_srates_ie(struct ieee80211_sub_if_data *sdata,
2101{ 2101{
2102 struct ieee80211_local *local = sdata->local; 2102 struct ieee80211_local *local = sdata->local;
2103 struct ieee80211_supported_band *sband; 2103 struct ieee80211_supported_band *sband;
2104 int rate, skip, shift; 2104 int rate, shift;
2105 u8 i, exrates, *pos; 2105 u8 i, exrates, *pos;
2106 u32 basic_rates = sdata->vif.bss_conf.basic_rates; 2106 u32 basic_rates = sdata->vif.bss_conf.basic_rates;
2107 u32 rate_flags; 2107 u32 rate_flags;
@@ -2129,14 +2129,11 @@ int ieee80211_add_ext_srates_ie(struct ieee80211_sub_if_data *sdata,
2129 pos = skb_put(skb, exrates + 2); 2129 pos = skb_put(skb, exrates + 2);
2130 *pos++ = WLAN_EID_EXT_SUPP_RATES; 2130 *pos++ = WLAN_EID_EXT_SUPP_RATES;
2131 *pos++ = exrates; 2131 *pos++ = exrates;
2132 skip = 0;
2133 for (i = 8; i < sband->n_bitrates; i++) { 2132 for (i = 8; i < sband->n_bitrates; i++) {
2134 u8 basic = 0; 2133 u8 basic = 0;
2135 if ((rate_flags & sband->bitrates[i].flags) 2134 if ((rate_flags & sband->bitrates[i].flags)
2136 != rate_flags) 2135 != rate_flags)
2137 continue; 2136 continue;
2138 if (skip++ < 8)
2139 continue;
2140 if (need_basic && basic_rates & BIT(i)) 2137 if (need_basic && basic_rates & BIT(i))
2141 basic = 0x80; 2138 basic = 0x80;
2142 rate = DIV_ROUND_UP(sband->bitrates[i].bitrate, 2139 rate = DIV_ROUND_UP(sband->bitrates[i].bitrate,
@@ -2239,6 +2236,10 @@ u64 ieee80211_calculate_rx_timestamp(struct ieee80211_local *local,
2239 } 2236 }
2240 2237
2241 rate = cfg80211_calculate_bitrate(&ri); 2238 rate = cfg80211_calculate_bitrate(&ri);
2239 if (WARN_ONCE(!rate,
2240 "Invalid bitrate: flags=0x%x, idx=%d, vht_nss=%d\n",
2241 status->flag, status->rate_idx, status->vht_nss))
2242 return 0;
2242 2243
2243 /* rewind from end of MPDU */ 2244 /* rewind from end of MPDU */
2244 if (status->flag & RX_FLAG_MACTIME_END) 2245 if (status->flag & RX_FLAG_MACTIME_END)