Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

Merge tag 'mac80211-for-davem-2018-09-27' of git://git.kernel.org/pub/scm/linux/kernel/git/jberg/mac80211

Johannes Berg says:

====================
More patches than I'd like perhaps, but each seems reasonable:
* two new spectre-v1 mitigations in nl80211
* TX status fix in general, and mesh in particular
* powersave vs. offchannel fix
* regulatory initialization fix
* fix for a queue hang due to a bad return value
* allocate TXQs for active monitor interfaces, fixing my
earlier patch to avoid unnecessary allocations where I
missed this case needed them
* fix TDLS data frames priority assignment
* fix scan results processing to take into account duplicate
channel numbers (over different operating classes, but we
don't necessarily know the operating class)
* various hwsim fixes for radio destruction and new radio
announcement messages
* remove an extraneous kernel-doc line
====================

Signed-off-by: David S. Miller <davem@davemloft.net>

+103 -54
+17 -19
drivers/net/wireless/mac80211_hwsim.c
··· 520 520 int channels, idx; 521 521 bool use_chanctx; 522 522 bool destroy_on_close; 523 - struct work_struct destroy_work; 524 523 u32 portid; 525 524 char alpha2[2]; 526 525 const struct ieee80211_regdomain *regd; ··· 2934 2935 hwsim_radios_generation++; 2935 2936 spin_unlock_bh(&hwsim_radio_lock); 2936 2937 2937 - if (idx > 0) 2938 - hwsim_mcast_new_radio(idx, info, param); 2938 + hwsim_mcast_new_radio(idx, info, param); 2939 2939 2940 2940 return idx; 2941 2941 ··· 3563 3565 .n_mcgrps = ARRAY_SIZE(hwsim_mcgrps), 3564 3566 }; 3565 3567 3566 - static void destroy_radio(struct work_struct *work) 3567 - { 3568 - struct mac80211_hwsim_data *data = 3569 - container_of(work, struct mac80211_hwsim_data, destroy_work); 3570 - 3571 - hwsim_radios_generation++; 3572 - mac80211_hwsim_del_radio(data, wiphy_name(data->hw->wiphy), NULL); 3573 - } 3574 - 3575 3568 static void remove_user_radios(u32 portid) 3576 3569 { 3577 3570 struct mac80211_hwsim_data *entry, *tmp; 3571 + LIST_HEAD(list); 3578 3572 3579 3573 spin_lock_bh(&hwsim_radio_lock); 3580 3574 list_for_each_entry_safe(entry, tmp, &hwsim_radios, list) { 3581 3575 if (entry->destroy_on_close && entry->portid == portid) { 3582 - list_del(&entry->list); 3576 + list_move(&entry->list, &list); 3583 3577 rhashtable_remove_fast(&hwsim_radios_rht, &entry->rht, 3584 3578 hwsim_rht_params); 3585 - INIT_WORK(&entry->destroy_work, destroy_radio); 3586 - queue_work(hwsim_wq, &entry->destroy_work); 3579 + hwsim_radios_generation++; 3587 3580 } 3588 3581 } 3589 3582 spin_unlock_bh(&hwsim_radio_lock); 3583 + 3584 + list_for_each_entry_safe(entry, tmp, &list, list) { 3585 + list_del(&entry->list); 3586 + mac80211_hwsim_del_radio(entry, wiphy_name(entry->hw->wiphy), 3587 + NULL); 3588 + } 3590 3589 } 3591 3590 3592 3591 static int mac80211_hwsim_netlink_notify(struct notifier_block *nb, ··· 3641 3646 static void __net_exit hwsim_exit_net(struct net *net) 3642 3647 { 3643 3648 struct mac80211_hwsim_data *data, *tmp; 3649 + LIST_HEAD(list); 3644 3650 3645 3651 spin_lock_bh(&hwsim_radio_lock); 3646 3652 list_for_each_entry_safe(data, tmp, &hwsim_radios, list) { ··· 3652 3656 if (data->netgroup == hwsim_net_get_netgroup(&init_net)) 3653 3657 continue; 3654 3658 3655 - list_del(&data->list); 3659 + list_move(&data->list, &list); 3656 3660 rhashtable_remove_fast(&hwsim_radios_rht, &data->rht, 3657 3661 hwsim_rht_params); 3658 3662 hwsim_radios_generation++; 3659 - spin_unlock_bh(&hwsim_radio_lock); 3663 + } 3664 + spin_unlock_bh(&hwsim_radio_lock); 3665 + 3666 + list_for_each_entry_safe(data, tmp, &list, list) { 3667 + list_del(&data->list); 3660 3668 mac80211_hwsim_del_radio(data, 3661 3669 wiphy_name(data->hw->wiphy), 3662 3670 NULL); 3663 - spin_lock_bh(&hwsim_radio_lock); 3664 3671 } 3665 - spin_unlock_bh(&hwsim_radio_lock); 3666 3672 3667 3673 ida_simple_remove(&hwsim_netgroup_ida, hwsim_net_get_netgroup(net)); 3668 3674 }
-2
include/net/cfg80211.h
··· 4852 4852 * 4853 4853 * @alpha2: the ISO/IEC 3166 alpha2 wmm rule to be queried. 4854 4854 * @freq: the freqency(in MHz) to be queried. 4855 - * @ptr: pointer where the regdb wmm data is to be stored (or %NULL if 4856 - * irrelevant). This can be used later for deduplication. 4857 4855 * @rule: pointer to store the wmm rule from the regulatory db. 4858 4856 * 4859 4857 * Self-managed wireless drivers can use this function to query
+2 -1
net/mac80211/iface.c
··· 1756 1756 1757 1757 if (local->ops->wake_tx_queue && 1758 1758 type != NL80211_IFTYPE_AP_VLAN && 1759 - type != NL80211_IFTYPE_MONITOR) 1759 + (type != NL80211_IFTYPE_MONITOR || 1760 + (params->flags & MONITOR_FLAG_ACTIVE))) 1760 1761 txq_size += sizeof(struct txq_info) + 1761 1762 local->hw.txq_data_size; 1762 1763
+2 -1
net/mac80211/mesh.h
··· 217 217 int mesh_rmc_init(struct ieee80211_sub_if_data *sdata); 218 218 void ieee80211s_init(void); 219 219 void ieee80211s_update_metric(struct ieee80211_local *local, 220 - struct sta_info *sta, struct sk_buff *skb); 220 + struct sta_info *sta, 221 + struct ieee80211_tx_status *st); 221 222 void ieee80211_mesh_init_sdata(struct ieee80211_sub_if_data *sdata); 222 223 void ieee80211_mesh_teardown_sdata(struct ieee80211_sub_if_data *sdata); 223 224 int ieee80211_start_mesh(struct ieee80211_sub_if_data *sdata);
+3 -6
net/mac80211/mesh_hwmp.c
··· 295 295 } 296 296 297 297 void ieee80211s_update_metric(struct ieee80211_local *local, 298 - struct sta_info *sta, struct sk_buff *skb) 298 + struct sta_info *sta, 299 + struct ieee80211_tx_status *st) 299 300 { 300 - struct ieee80211_tx_info *txinfo = IEEE80211_SKB_CB(skb); 301 - struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) skb->data; 301 + struct ieee80211_tx_info *txinfo = st->info; 302 302 int failed; 303 - 304 - if (!ieee80211_is_data(hdr->frame_control)) 305 - return; 306 303 307 304 failed = !(txinfo->flags & IEEE80211_TX_STAT_ACK); 308 305
+5 -6
net/mac80211/status.c
··· 479 479 if (!skb) 480 480 return; 481 481 482 - if (dropped) { 483 - dev_kfree_skb_any(skb); 484 - return; 485 - } 486 - 487 482 if (info->flags & IEEE80211_TX_INTFL_NL80211_FRAME_TX) { 488 483 u64 cookie = IEEE80211_SKB_CB(skb)->ack.cookie; 489 484 struct ieee80211_sub_if_data *sdata; ··· 501 506 } 502 507 rcu_read_unlock(); 503 508 509 + dev_kfree_skb_any(skb); 510 + } else if (dropped) { 504 511 dev_kfree_skb_any(skb); 505 512 } else { 506 513 /* consumes skb */ ··· 808 811 809 812 rate_control_tx_status(local, sband, status); 810 813 if (ieee80211_vif_is_mesh(&sta->sdata->vif)) 811 - ieee80211s_update_metric(local, sta, skb); 814 + ieee80211s_update_metric(local, sta, status); 812 815 813 816 if (!(info->flags & IEEE80211_TX_CTL_INJECTED) && acked) 814 817 ieee80211_frame_acked(sta, skb); ··· 969 972 } 970 973 971 974 rate_control_tx_status(local, sband, status); 975 + if (ieee80211_vif_is_mesh(&sta->sdata->vif)) 976 + ieee80211s_update_metric(local, sta, status); 972 977 } 973 978 974 979 if (acked || noack_success) {
+4 -4
net/mac80211/tdls.c
··· 16 16 #include "ieee80211_i.h" 17 17 #include "driver-ops.h" 18 18 #include "rate.h" 19 + #include "wme.h" 19 20 20 21 /* give usermode some time for retries in setting up the TDLS session */ 21 22 #define TDLS_PEER_SETUP_TIMEOUT (15 * HZ) ··· 1011 1010 switch (action_code) { 1012 1011 case WLAN_TDLS_SETUP_REQUEST: 1013 1012 case WLAN_TDLS_SETUP_RESPONSE: 1014 - skb_set_queue_mapping(skb, IEEE80211_AC_BK); 1015 - skb->priority = 2; 1013 + skb->priority = 256 + 2; 1016 1014 break; 1017 1015 default: 1018 - skb_set_queue_mapping(skb, IEEE80211_AC_VI); 1019 - skb->priority = 5; 1016 + skb->priority = 256 + 5; 1020 1017 break; 1021 1018 } 1019 + skb_set_queue_mapping(skb, ieee80211_select_queue(sdata, skb)); 1022 1020 1023 1021 /* 1024 1022 * Set the WLAN_TDLS_TEARDOWN flag to indicate a teardown in progress.
+5 -1
net/mac80211/tx.c
··· 214 214 { 215 215 struct ieee80211_local *local = tx->local; 216 216 struct ieee80211_if_managed *ifmgd; 217 + struct ieee80211_tx_info *info = IEEE80211_SKB_CB(tx->skb); 217 218 218 219 /* driver doesn't support power save */ 219 220 if (!ieee80211_hw_check(&local->hw, SUPPORTS_PS)) ··· 241 240 242 241 /* dynamic ps is supported only in managed mode */ 243 242 if (tx->sdata->vif.type != NL80211_IFTYPE_STATION) 243 + return TX_CONTINUE; 244 + 245 + if (unlikely(info->flags & IEEE80211_TX_INTFL_OFFCHAN_TX_OK)) 244 246 return TX_CONTINUE; 245 247 246 248 ifmgd = &tx->sdata->u.mgd; ··· 1894 1890 sdata->vif.hw_queue[skb_get_queue_mapping(skb)]; 1895 1891 1896 1892 if (invoke_tx_handlers_early(&tx)) 1897 - return false; 1893 + return true; 1898 1894 1899 1895 if (ieee80211_queue_skb(local, sdata, tx.sta, tx.skb)) 1900 1896 return true;
+15 -5
net/wireless/nl80211.c
··· 3756 3756 return false; 3757 3757 3758 3758 /* check availability */ 3759 + ridx = array_index_nospec(ridx, IEEE80211_HT_MCS_MASK_LEN); 3759 3760 if (sband->ht_cap.mcs.rx_mask[ridx] & rbit) 3760 3761 mcs[ridx] |= rbit; 3761 3762 else ··· 10231 10230 struct wireless_dev *wdev = dev->ieee80211_ptr; 10232 10231 s32 last, low, high; 10233 10232 u32 hyst; 10234 - int i, n; 10233 + int i, n, low_index; 10235 10234 int err; 10236 10235 10237 10236 /* RSSI reporting disabled? */ ··· 10268 10267 if (last < wdev->cqm_config->rssi_thresholds[i]) 10269 10268 break; 10270 10269 10271 - low = i > 0 ? 10272 - (wdev->cqm_config->rssi_thresholds[i - 1] - hyst) : S32_MIN; 10273 - high = i < n ? 10274 - (wdev->cqm_config->rssi_thresholds[i] + hyst - 1) : S32_MAX; 10270 + low_index = i - 1; 10271 + if (low_index >= 0) { 10272 + low_index = array_index_nospec(low_index, n); 10273 + low = wdev->cqm_config->rssi_thresholds[low_index] - hyst; 10274 + } else { 10275 + low = S32_MIN; 10276 + } 10277 + if (i < n) { 10278 + i = array_index_nospec(i, n); 10279 + high = wdev->cqm_config->rssi_thresholds[i] + hyst - 1; 10280 + } else { 10281 + high = S32_MAX; 10282 + } 10275 10283 10276 10284 return rdev_set_cqm_rssi_range_config(rdev, dev, low, high); 10277 10285 }
+1
net/wireless/reg.c
··· 2867 2867 request->alpha2[0] = alpha2[0]; 2868 2868 request->alpha2[1] = alpha2[1]; 2869 2869 request->initiator = NL80211_REGDOM_SET_BY_CORE; 2870 + request->wiphy_idx = WIPHY_IDX_INVALID; 2870 2871 2871 2872 queue_regulatory_request(request); 2872 2873
+49 -9
net/wireless/scan.c
··· 1058 1058 return NULL; 1059 1059 } 1060 1060 1061 + /* 1062 + * Update RX channel information based on the available frame payload 1063 + * information. This is mainly for the 2.4 GHz band where frames can be received 1064 + * from neighboring channels and the Beacon frames use the DSSS Parameter Set 1065 + * element to indicate the current (transmitting) channel, but this might also 1066 + * be needed on other bands if RX frequency does not match with the actual 1067 + * operating channel of a BSS. 1068 + */ 1061 1069 static struct ieee80211_channel * 1062 1070 cfg80211_get_bss_channel(struct wiphy *wiphy, const u8 *ie, size_t ielen, 1063 - struct ieee80211_channel *channel) 1071 + struct ieee80211_channel *channel, 1072 + enum nl80211_bss_scan_width scan_width) 1064 1073 { 1065 1074 const u8 *tmp; 1066 1075 u32 freq; 1067 1076 int channel_number = -1; 1077 + struct ieee80211_channel *alt_channel; 1068 1078 1069 1079 tmp = cfg80211_find_ie(WLAN_EID_DS_PARAMS, ie, ielen); 1070 1080 if (tmp && tmp[1] == 1) { ··· 1088 1078 } 1089 1079 } 1090 1080 1091 - if (channel_number < 0) 1081 + if (channel_number < 0) { 1082 + /* No channel information in frame payload */ 1092 1083 return channel; 1084 + } 1093 1085 1094 1086 freq = ieee80211_channel_to_frequency(channel_number, channel->band); 1095 - channel = ieee80211_get_channel(wiphy, freq); 1096 - if (!channel) 1087 + alt_channel = ieee80211_get_channel(wiphy, freq); 1088 + if (!alt_channel) { 1089 + if (channel->band == NL80211_BAND_2GHZ) { 1090 + /* 1091 + * Better not allow unexpected channels when that could 1092 + * be going beyond the 1-11 range (e.g., discovering 1093 + * BSS on channel 12 when radio is configured for 1094 + * channel 11. 1095 + */ 1096 + return NULL; 1097 + } 1098 + 1099 + /* No match for the payload channel number - ignore it */ 1100 + return channel; 1101 + } 1102 + 1103 + if (scan_width == NL80211_BSS_CHAN_WIDTH_10 || 1104 + scan_width == NL80211_BSS_CHAN_WIDTH_5) { 1105 + /* 1106 + * Ignore channel number in 5 and 10 MHz channels where there 1107 + * may not be an n:1 or 1:n mapping between frequencies and 1108 + * channel numbers. 1109 + */ 1110 + return channel; 1111 + } 1112 + 1113 + /* 1114 + * Use the channel determined through the payload channel number 1115 + * instead of the RX channel reported by the driver. 1116 + */ 1117 + if (alt_channel->flags & IEEE80211_CHAN_DISABLED) 1097 1118 return NULL; 1098 - if (channel->flags & IEEE80211_CHAN_DISABLED) 1099 - return NULL; 1100 - return channel; 1119 + return alt_channel; 1101 1120 } 1102 1121 1103 1122 /* Returned bss is reference counted and must be cleaned up appropriately. */ ··· 1151 1112 (data->signal < 0 || data->signal > 100))) 1152 1113 return NULL; 1153 1114 1154 - channel = cfg80211_get_bss_channel(wiphy, ie, ielen, data->chan); 1115 + channel = cfg80211_get_bss_channel(wiphy, ie, ielen, data->chan, 1116 + data->scan_width); 1155 1117 if (!channel) 1156 1118 return NULL; 1157 1119 ··· 1250 1210 return NULL; 1251 1211 1252 1212 channel = cfg80211_get_bss_channel(wiphy, mgmt->u.beacon.variable, 1253 - ielen, data->chan); 1213 + ielen, data->chan, data->scan_width); 1254 1214 if (!channel) 1255 1215 return NULL; 1256 1216