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

Configure Feed

Select the types of activity you want to include in your feed.

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

Johannes Berg says:

====================
Here are quite a large number of fixes, notably:
* various A-MSDU building fixes (currently only affects mt76)
* syzkaller & spectre fixes in hwsim
* TXQ vs. teardown fix that was causing crashes
* embed WMM info in reg rule, bad code here had been causing crashes
* one compilation issue with fix from Arnd (rfkill-gpio includes)
* fixes for a race and bad data during/after channel switch
* nl80211: a validation fix, attribute type & unit fixes
along with other small fixes.
====================

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

+182 -187
+5 -45
drivers/net/wireless/intel/iwlwifi/iwl-nvm-parse.c
··· 985 985 const u8 *nvm_chan = cfg->nvm_type == IWL_NVM_EXT ? 986 986 iwl_ext_nvm_channels : iwl_nvm_channels; 987 987 struct ieee80211_regdomain *regd, *copy_rd; 988 - int size_of_regd, regd_to_copy, wmms_to_copy; 989 - int size_of_wmms = 0; 988 + int size_of_regd, regd_to_copy; 990 989 struct ieee80211_reg_rule *rule; 991 - struct ieee80211_wmm_rule *wmm_rule, *d_wmm, *s_wmm; 992 990 struct regdb_ptrs *regdb_ptrs; 993 991 enum nl80211_band band; 994 992 int center_freq, prev_center_freq = 0; 995 - int valid_rules = 0, n_wmms = 0; 996 - int i; 993 + int valid_rules = 0; 997 994 bool new_rule; 998 995 int max_num_ch = cfg->nvm_type == IWL_NVM_EXT ? 999 996 IWL_NVM_NUM_CHANNELS_EXT : IWL_NVM_NUM_CHANNELS; ··· 1009 1012 sizeof(struct ieee80211_regdomain) + 1010 1013 num_of_ch * sizeof(struct ieee80211_reg_rule); 1011 1014 1012 - if (geo_info & GEO_WMM_ETSI_5GHZ_INFO) 1013 - size_of_wmms = 1014 - num_of_ch * sizeof(struct ieee80211_wmm_rule); 1015 - 1016 - regd = kzalloc(size_of_regd + size_of_wmms, GFP_KERNEL); 1015 + regd = kzalloc(size_of_regd, GFP_KERNEL); 1017 1016 if (!regd) 1018 1017 return ERR_PTR(-ENOMEM); 1019 1018 ··· 1022 1029 /* set alpha2 from FW. */ 1023 1030 regd->alpha2[0] = fw_mcc >> 8; 1024 1031 regd->alpha2[1] = fw_mcc & 0xff; 1025 - 1026 - wmm_rule = (struct ieee80211_wmm_rule *)((u8 *)regd + size_of_regd); 1027 1032 1028 1033 for (ch_idx = 0; ch_idx < num_of_ch; ch_idx++) { 1029 1034 ch_flags = (u16)__le32_to_cpup(channels + ch_idx); ··· 1076 1085 band == NL80211_BAND_2GHZ) 1077 1086 continue; 1078 1087 1079 - if (!reg_query_regdb_wmm(regd->alpha2, center_freq, 1080 - &regdb_ptrs[n_wmms].token, wmm_rule)) { 1081 - /* Add only new rules */ 1082 - for (i = 0; i < n_wmms; i++) { 1083 - if (regdb_ptrs[i].token == 1084 - regdb_ptrs[n_wmms].token) { 1085 - rule->wmm_rule = regdb_ptrs[i].rule; 1086 - break; 1087 - } 1088 - } 1089 - if (i == n_wmms) { 1090 - rule->wmm_rule = wmm_rule; 1091 - regdb_ptrs[n_wmms++].rule = wmm_rule; 1092 - wmm_rule++; 1093 - } 1094 - } 1088 + reg_query_regdb_wmm(regd->alpha2, center_freq, rule); 1095 1089 } 1096 1090 1097 1091 regd->n_reg_rules = valid_rules; 1098 - regd->n_wmm_rules = n_wmms; 1099 1092 1100 1093 /* 1101 1094 * Narrow down regdom for unused regulatory rules to prevent hole ··· 1088 1113 regd_to_copy = sizeof(struct ieee80211_regdomain) + 1089 1114 valid_rules * sizeof(struct ieee80211_reg_rule); 1090 1115 1091 - wmms_to_copy = sizeof(struct ieee80211_wmm_rule) * n_wmms; 1092 - 1093 - copy_rd = kzalloc(regd_to_copy + wmms_to_copy, GFP_KERNEL); 1116 + copy_rd = kzalloc(regd_to_copy, GFP_KERNEL); 1094 1117 if (!copy_rd) { 1095 1118 copy_rd = ERR_PTR(-ENOMEM); 1096 1119 goto out; 1097 1120 } 1098 1121 1099 1122 memcpy(copy_rd, regd, regd_to_copy); 1100 - memcpy((u8 *)copy_rd + regd_to_copy, (u8 *)regd + size_of_regd, 1101 - wmms_to_copy); 1102 - 1103 - d_wmm = (struct ieee80211_wmm_rule *)((u8 *)copy_rd + regd_to_copy); 1104 - s_wmm = (struct ieee80211_wmm_rule *)((u8 *)regd + size_of_regd); 1105 - 1106 - for (i = 0; i < regd->n_reg_rules; i++) { 1107 - if (!regd->reg_rules[i].wmm_rule) 1108 - continue; 1109 - 1110 - copy_rd->reg_rules[i].wmm_rule = d_wmm + 1111 - (regd->reg_rules[i].wmm_rule - s_wmm); 1112 - } 1113 1123 1114 1124 out: 1115 1125 kfree(regdb_ptrs);
+9 -3
drivers/net/wireless/mac80211_hwsim.c
··· 34 34 #include <net/net_namespace.h> 35 35 #include <net/netns/generic.h> 36 36 #include <linux/rhashtable.h> 37 + #include <linux/nospec.h> 37 38 #include "mac80211_hwsim.h" 38 39 39 40 #define WARN_QUEUE 100 ··· 2821 2820 IEEE80211_VHT_CAP_SHORT_GI_80 | 2822 2821 IEEE80211_VHT_CAP_SHORT_GI_160 | 2823 2822 IEEE80211_VHT_CAP_TXSTBC | 2824 - IEEE80211_VHT_CAP_RXSTBC_1 | 2825 - IEEE80211_VHT_CAP_RXSTBC_2 | 2826 - IEEE80211_VHT_CAP_RXSTBC_3 | 2827 2823 IEEE80211_VHT_CAP_RXSTBC_4 | 2828 2824 IEEE80211_VHT_CAP_MAX_A_MPDU_LENGTH_EXPONENT_MASK; 2829 2825 sband->vht_cap.vht_mcs.rx_mcs_map = ··· 3315 3317 if (info->attrs[HWSIM_ATTR_CHANNELS]) 3316 3318 param.channels = nla_get_u32(info->attrs[HWSIM_ATTR_CHANNELS]); 3317 3319 3320 + if (param.channels < 1) { 3321 + GENL_SET_ERR_MSG(info, "must have at least one channel"); 3322 + return -EINVAL; 3323 + } 3324 + 3318 3325 if (param.channels > CFG80211_MAX_NUM_DIFFERENT_CHANNELS) { 3319 3326 GENL_SET_ERR_MSG(info, "too many channels specified"); 3320 3327 return -EINVAL; ··· 3353 3350 kfree(hwname); 3354 3351 return -EINVAL; 3355 3352 } 3353 + 3354 + idx = array_index_nospec(idx, 3355 + ARRAY_SIZE(hwsim_world_regdom_custom)); 3356 3356 param.regd = hwsim_world_regdom_custom[idx]; 3357 3357 } 3358 3358
+2 -2
include/net/cfg80211.h
··· 4865 4865 * 4866 4866 * Return: 0 on success. -ENODATA. 4867 4867 */ 4868 - int reg_query_regdb_wmm(char *alpha2, int freq, u32 *ptr, 4869 - struct ieee80211_wmm_rule *rule); 4868 + int reg_query_regdb_wmm(char *alpha2, int freq, 4869 + struct ieee80211_reg_rule *rule); 4870 4870 4871 4871 /* 4872 4872 * callbacks for asynchronous cfg80211 methods, notification
+2 -2
include/net/regulatory.h
··· 217 217 struct ieee80211_reg_rule { 218 218 struct ieee80211_freq_range freq_range; 219 219 struct ieee80211_power_rule power_rule; 220 - struct ieee80211_wmm_rule *wmm_rule; 220 + struct ieee80211_wmm_rule wmm_rule; 221 221 u32 flags; 222 222 u32 dfs_cac_ms; 223 + bool has_wmm; 223 224 }; 224 225 225 226 struct ieee80211_regdomain { 226 227 struct rcu_head rcu_head; 227 228 u32 n_reg_rules; 228 - u32 n_wmm_rules; 229 229 char alpha2[3]; 230 230 enum nl80211_dfs_regions dfs_region; 231 231 struct ieee80211_reg_rule reg_rules[];
+11 -11
net/mac80211/ibss.c
··· 947 947 if (len < IEEE80211_DEAUTH_FRAME_LEN) 948 948 return; 949 949 950 - ibss_dbg(sdata, "RX DeAuth SA=%pM DA=%pM BSSID=%pM (reason: %d)\n", 951 - mgmt->sa, mgmt->da, mgmt->bssid, reason); 950 + ibss_dbg(sdata, "RX DeAuth SA=%pM DA=%pM\n", mgmt->sa, mgmt->da); 951 + ibss_dbg(sdata, "\tBSSID=%pM (reason: %d)\n", mgmt->bssid, reason); 952 952 sta_info_destroy_addr(sdata, mgmt->sa); 953 953 } 954 954 ··· 966 966 auth_alg = le16_to_cpu(mgmt->u.auth.auth_alg); 967 967 auth_transaction = le16_to_cpu(mgmt->u.auth.auth_transaction); 968 968 969 - ibss_dbg(sdata, 970 - "RX Auth SA=%pM DA=%pM BSSID=%pM (auth_transaction=%d)\n", 971 - mgmt->sa, mgmt->da, mgmt->bssid, auth_transaction); 969 + ibss_dbg(sdata, "RX Auth SA=%pM DA=%pM\n", mgmt->sa, mgmt->da); 970 + ibss_dbg(sdata, "\tBSSID=%pM (auth_transaction=%d)\n", 971 + mgmt->bssid, auth_transaction); 972 972 973 973 if (auth_alg != WLAN_AUTH_OPEN || auth_transaction != 1) 974 974 return; ··· 1175 1175 rx_timestamp = drv_get_tsf(local, sdata); 1176 1176 } 1177 1177 1178 - ibss_dbg(sdata, 1179 - "RX beacon SA=%pM BSSID=%pM TSF=0x%llx BCN=0x%llx diff=%lld @%lu\n", 1178 + ibss_dbg(sdata, "RX beacon SA=%pM BSSID=%pM TSF=0x%llx\n", 1180 1179 mgmt->sa, mgmt->bssid, 1181 - (unsigned long long)rx_timestamp, 1180 + (unsigned long long)rx_timestamp); 1181 + ibss_dbg(sdata, "\tBCN=0x%llx diff=%lld @%lu\n", 1182 1182 (unsigned long long)beacon_timestamp, 1183 1183 (unsigned long long)(rx_timestamp - beacon_timestamp), 1184 1184 jiffies); ··· 1537 1537 1538 1538 tx_last_beacon = drv_tx_last_beacon(local); 1539 1539 1540 - ibss_dbg(sdata, 1541 - "RX ProbeReq SA=%pM DA=%pM BSSID=%pM (tx_last_beacon=%d)\n", 1542 - mgmt->sa, mgmt->da, mgmt->bssid, tx_last_beacon); 1540 + ibss_dbg(sdata, "RX ProbeReq SA=%pM DA=%pM\n", mgmt->sa, mgmt->da); 1541 + ibss_dbg(sdata, "\tBSSID=%pM (tx_last_beacon=%d)\n", 1542 + mgmt->bssid, tx_last_beacon); 1543 1543 1544 1544 if (!tx_last_beacon && is_multicast_ether_addr(mgmt->da)) 1545 1545 return;
+22 -6
net/mac80211/main.c
··· 256 256 257 257 flush_work(&local->radar_detected_work); 258 258 rtnl_lock(); 259 - list_for_each_entry(sdata, &local->interfaces, list) 259 + list_for_each_entry(sdata, &local->interfaces, list) { 260 + /* 261 + * XXX: there may be more work for other vif types and even 262 + * for station mode: a good thing would be to run most of 263 + * the iface type's dependent _stop (ieee80211_mg_stop, 264 + * ieee80211_ibss_stop) etc... 265 + * For now, fix only the specific bug that was seen: race 266 + * between csa_connection_drop_work and us. 267 + */ 268 + if (sdata->vif.type == NL80211_IFTYPE_STATION) { 269 + /* 270 + * This worker is scheduled from the iface worker that 271 + * runs on mac80211's workqueue, so we can't be 272 + * scheduling this worker after the cancel right here. 273 + * The exception is ieee80211_chswitch_done. 274 + * Then we can have a race... 275 + */ 276 + cancel_work_sync(&sdata->u.mgd.csa_connection_drop_work); 277 + } 260 278 flush_delayed_work(&sdata->dec_tailroom_needed_wk); 279 + } 261 280 ieee80211_scan_cancel(local); 262 281 263 282 /* make sure any new ROC will consider local->in_reconfig */ ··· 490 471 cpu_to_le32(IEEE80211_VHT_CAP_RXLDPC | 491 472 IEEE80211_VHT_CAP_SHORT_GI_80 | 492 473 IEEE80211_VHT_CAP_SHORT_GI_160 | 493 - IEEE80211_VHT_CAP_RXSTBC_1 | 494 - IEEE80211_VHT_CAP_RXSTBC_2 | 495 - IEEE80211_VHT_CAP_RXSTBC_3 | 496 - IEEE80211_VHT_CAP_RXSTBC_4 | 474 + IEEE80211_VHT_CAP_RXSTBC_MASK | 497 475 IEEE80211_VHT_CAP_TXSTBC | 498 476 IEEE80211_VHT_CAP_SU_BEAMFORMER_CAPABLE | 499 477 IEEE80211_VHT_CAP_SU_BEAMFORMEE_CAPABLE | ··· 1224 1208 #if IS_ENABLED(CONFIG_IPV6) 1225 1209 unregister_inet6addr_notifier(&local->ifa6_notifier); 1226 1210 #endif 1211 + ieee80211_txq_teardown_flows(local); 1227 1212 1228 1213 rtnl_lock(); 1229 1214 ··· 1253 1236 skb_queue_purge(&local->skb_queue); 1254 1237 skb_queue_purge(&local->skb_queue_unreliable); 1255 1238 skb_queue_purge(&local->skb_queue_tdls_chsw); 1256 - ieee80211_txq_teardown_flows(local); 1257 1239 1258 1240 destroy_workqueue(local->workqueue); 1259 1241 wiphy_unregister(local->hw.wiphy);
+4
net/mac80211/mesh_hwmp.c
··· 572 572 forward = false; 573 573 reply = true; 574 574 target_metric = 0; 575 + 576 + if (SN_GT(target_sn, ifmsh->sn)) 577 + ifmsh->sn = target_sn; 578 + 575 579 if (time_after(jiffies, ifmsh->last_sn_update + 576 580 net_traversal_jiffies(sdata)) || 577 581 time_before(jiffies, ifmsh->last_sn_update)) {
+68 -2
net/mac80211/mlme.c
··· 1073 1073 */ 1074 1074 1075 1075 if (sdata->reserved_chanctx) { 1076 + struct ieee80211_supported_band *sband = NULL; 1077 + struct sta_info *mgd_sta = NULL; 1078 + enum ieee80211_sta_rx_bandwidth bw = IEEE80211_STA_RX_BW_20; 1079 + 1076 1080 /* 1077 1081 * with multi-vif csa driver may call ieee80211_csa_finish() 1078 1082 * many times while waiting for other interfaces to use their ··· 1084 1080 */ 1085 1081 if (sdata->reserved_ready) 1086 1082 goto out; 1083 + 1084 + if (sdata->vif.bss_conf.chandef.width != 1085 + sdata->csa_chandef.width) { 1086 + /* 1087 + * For managed interface, we need to also update the AP 1088 + * station bandwidth and align the rate scale algorithm 1089 + * on the bandwidth change. Here we only consider the 1090 + * bandwidth of the new channel definition (as channel 1091 + * switch flow does not have the full HT/VHT/HE 1092 + * information), assuming that if additional changes are 1093 + * required they would be done as part of the processing 1094 + * of the next beacon from the AP. 1095 + */ 1096 + switch (sdata->csa_chandef.width) { 1097 + case NL80211_CHAN_WIDTH_20_NOHT: 1098 + case NL80211_CHAN_WIDTH_20: 1099 + default: 1100 + bw = IEEE80211_STA_RX_BW_20; 1101 + break; 1102 + case NL80211_CHAN_WIDTH_40: 1103 + bw = IEEE80211_STA_RX_BW_40; 1104 + break; 1105 + case NL80211_CHAN_WIDTH_80: 1106 + bw = IEEE80211_STA_RX_BW_80; 1107 + break; 1108 + case NL80211_CHAN_WIDTH_80P80: 1109 + case NL80211_CHAN_WIDTH_160: 1110 + bw = IEEE80211_STA_RX_BW_160; 1111 + break; 1112 + } 1113 + 1114 + mgd_sta = sta_info_get(sdata, ifmgd->bssid); 1115 + sband = 1116 + local->hw.wiphy->bands[sdata->csa_chandef.chan->band]; 1117 + } 1118 + 1119 + if (sdata->vif.bss_conf.chandef.width > 1120 + sdata->csa_chandef.width) { 1121 + mgd_sta->sta.bandwidth = bw; 1122 + rate_control_rate_update(local, sband, mgd_sta, 1123 + IEEE80211_RC_BW_CHANGED); 1124 + } 1087 1125 1088 1126 ret = ieee80211_vif_use_reserved_context(sdata); 1089 1127 if (ret) { ··· 1135 1089 ieee80211_queue_work(&sdata->local->hw, 1136 1090 &ifmgd->csa_connection_drop_work); 1137 1091 goto out; 1092 + } 1093 + 1094 + if (sdata->vif.bss_conf.chandef.width < 1095 + sdata->csa_chandef.width) { 1096 + mgd_sta->sta.bandwidth = bw; 1097 + rate_control_rate_update(local, sband, mgd_sta, 1098 + IEEE80211_RC_BW_CHANGED); 1138 1099 } 1139 1100 1140 1101 goto out; ··· 1365 1312 cbss->beacon_interval)); 1366 1313 return; 1367 1314 drop_connection: 1315 + /* 1316 + * This is just so that the disconnect flow will know that 1317 + * we were trying to switch channel and failed. In case the 1318 + * mode is 1 (we are not allowed to Tx), we will know not to 1319 + * send a deauthentication frame. Those two fields will be 1320 + * reset when the disconnection worker runs. 1321 + */ 1322 + sdata->vif.csa_active = true; 1323 + sdata->csa_block_tx = csa_ie.mode; 1324 + 1368 1325 ieee80211_queue_work(&local->hw, &ifmgd->csa_connection_drop_work); 1369 1326 mutex_unlock(&local->chanctx_mtx); 1370 1327 mutex_unlock(&local->mtx); ··· 2585 2522 struct ieee80211_local *local = sdata->local; 2586 2523 struct ieee80211_if_managed *ifmgd = &sdata->u.mgd; 2587 2524 u8 frame_buf[IEEE80211_DEAUTH_FRAME_LEN]; 2525 + bool tx; 2588 2526 2589 2527 sdata_lock(sdata); 2590 2528 if (!ifmgd->associated) { 2591 2529 sdata_unlock(sdata); 2592 2530 return; 2593 2531 } 2532 + 2533 + tx = !sdata->csa_block_tx; 2594 2534 2595 2535 /* AP is probably out of range (or not reachable for another reason) so 2596 2536 * remove the bss struct for that AP. ··· 2602 2536 2603 2537 ieee80211_set_disassoc(sdata, IEEE80211_STYPE_DEAUTH, 2604 2538 WLAN_REASON_DISASSOC_DUE_TO_INACTIVITY, 2605 - true, frame_buf); 2539 + tx, frame_buf); 2606 2540 mutex_lock(&local->mtx); 2607 2541 sdata->vif.csa_active = false; 2608 2542 ifmgd->csa_waiting_bcn = false; ··· 2613 2547 } 2614 2548 mutex_unlock(&local->mtx); 2615 2549 2616 - ieee80211_report_disconnect(sdata, frame_buf, sizeof(frame_buf), true, 2550 + ieee80211_report_disconnect(sdata, frame_buf, sizeof(frame_buf), tx, 2617 2551 WLAN_REASON_DISASSOC_DUE_TO_INACTIVITY); 2618 2552 2619 2553 sdata_unlock(sdata);
+1
net/mac80211/rx.c
··· 1728 1728 */ 1729 1729 if (!ieee80211_hw_check(&sta->local->hw, AP_LINK_PS) && 1730 1730 !ieee80211_has_morefrags(hdr->frame_control) && 1731 + !is_multicast_ether_addr(hdr->addr1) && 1731 1732 (ieee80211_is_mgmt(hdr->frame_control) || 1732 1733 ieee80211_is_data(hdr->frame_control)) && 1733 1734 !(status->rx_flags & IEEE80211_RX_DEFERRED_RELEASE) &&
+30 -24
net/mac80211/tx.c
··· 3078 3078 } 3079 3079 3080 3080 static bool ieee80211_amsdu_realloc_pad(struct ieee80211_local *local, 3081 - struct sk_buff *skb, int headroom, 3082 - int *subframe_len) 3081 + struct sk_buff *skb, int headroom) 3083 3082 { 3084 - int amsdu_len = *subframe_len + sizeof(struct ethhdr); 3085 - int padding = (4 - amsdu_len) & 3; 3086 - 3087 - if (skb_headroom(skb) < headroom || skb_tailroom(skb) < padding) { 3083 + if (skb_headroom(skb) < headroom) { 3088 3084 I802_DEBUG_INC(local->tx_expand_skb_head); 3089 3085 3090 - if (pskb_expand_head(skb, headroom, padding, GFP_ATOMIC)) { 3086 + if (pskb_expand_head(skb, headroom, 0, GFP_ATOMIC)) { 3091 3087 wiphy_debug(local->hw.wiphy, 3092 3088 "failed to reallocate TX buffer\n"); 3093 3089 return false; 3094 3090 } 3095 - } 3096 - 3097 - if (padding) { 3098 - *subframe_len += padding; 3099 - skb_put_zero(skb, padding); 3100 3091 } 3101 3092 3102 3093 return true; ··· 3113 3122 if (info->control.flags & IEEE80211_TX_CTRL_AMSDU) 3114 3123 return true; 3115 3124 3116 - if (!ieee80211_amsdu_realloc_pad(local, skb, sizeof(*amsdu_hdr), 3117 - &subframe_len)) 3125 + if (!ieee80211_amsdu_realloc_pad(local, skb, sizeof(*amsdu_hdr))) 3118 3126 return false; 3119 3127 3120 3128 data = skb_push(skb, sizeof(*amsdu_hdr)); ··· 3179 3189 void *data; 3180 3190 bool ret = false; 3181 3191 unsigned int orig_len; 3182 - int n = 1, nfrags; 3192 + int n = 2, nfrags, pad = 0; 3193 + u16 hdrlen; 3183 3194 3184 3195 if (!ieee80211_hw_check(&local->hw, TX_AMSDU)) 3185 3196 return false; ··· 3213 3222 if (skb->len + head->len > max_amsdu_len) 3214 3223 goto out; 3215 3224 3216 - if (!ieee80211_amsdu_prepare_head(sdata, fast_tx, head)) 3217 - goto out; 3218 - 3219 3225 nfrags = 1 + skb_shinfo(skb)->nr_frags; 3220 3226 nfrags += 1 + skb_shinfo(head)->nr_frags; 3221 3227 frag_tail = &skb_shinfo(head)->frag_list; ··· 3228 3240 if (max_frags && nfrags > max_frags) 3229 3241 goto out; 3230 3242 3231 - if (!ieee80211_amsdu_realloc_pad(local, skb, sizeof(rfc1042_header) + 2, 3232 - &subframe_len)) 3243 + if (!ieee80211_amsdu_prepare_head(sdata, fast_tx, head)) 3233 3244 goto out; 3245 + 3246 + /* 3247 + * Pad out the previous subframe to a multiple of 4 by adding the 3248 + * padding to the next one, that's being added. Note that head->len 3249 + * is the length of the full A-MSDU, but that works since each time 3250 + * we add a new subframe we pad out the previous one to a multiple 3251 + * of 4 and thus it no longer matters in the next round. 3252 + */ 3253 + hdrlen = fast_tx->hdr_len - sizeof(rfc1042_header); 3254 + if ((head->len - hdrlen) & 3) 3255 + pad = 4 - ((head->len - hdrlen) & 3); 3256 + 3257 + if (!ieee80211_amsdu_realloc_pad(local, skb, sizeof(rfc1042_header) + 3258 + 2 + pad)) 3259 + goto out_recalc; 3234 3260 3235 3261 ret = true; 3236 3262 data = skb_push(skb, ETH_ALEN + 2); ··· 3255 3253 memcpy(data, &len, 2); 3256 3254 memcpy(data + 2, rfc1042_header, sizeof(rfc1042_header)); 3257 3255 3256 + memset(skb_push(skb, pad), 0, pad); 3257 + 3258 3258 head->len += skb->len; 3259 3259 head->data_len += skb->len; 3260 3260 *frag_tail = skb; 3261 3261 3262 - flow->backlog += head->len - orig_len; 3263 - tin->backlog_bytes += head->len - orig_len; 3262 + out_recalc: 3263 + if (head->len != orig_len) { 3264 + flow->backlog += head->len - orig_len; 3265 + tin->backlog_bytes += head->len - orig_len; 3264 3266 3265 - fq_recalc_backlog(fq, tin, flow); 3266 - 3267 + fq_recalc_backlog(fq, tin, flow); 3268 + } 3267 3269 out: 3268 3270 spin_unlock_bh(&fq->lock); 3269 3271
+5 -6
net/mac80211/util.c
··· 1135 1135 { 1136 1136 struct ieee80211_chanctx_conf *chanctx_conf; 1137 1137 const struct ieee80211_reg_rule *rrule; 1138 - struct ieee80211_wmm_ac *wmm_ac; 1138 + const struct ieee80211_wmm_ac *wmm_ac; 1139 1139 u16 center_freq = 0; 1140 1140 1141 1141 if (sdata->vif.type != NL80211_IFTYPE_AP && ··· 1154 1154 1155 1155 rrule = freq_reg_info(sdata->wdev.wiphy, MHZ_TO_KHZ(center_freq)); 1156 1156 1157 - if (IS_ERR_OR_NULL(rrule) || !rrule->wmm_rule) { 1157 + if (IS_ERR_OR_NULL(rrule) || !rrule->has_wmm) { 1158 1158 rcu_read_unlock(); 1159 1159 return; 1160 1160 } 1161 1161 1162 1162 if (sdata->vif.type == NL80211_IFTYPE_AP) 1163 - wmm_ac = &rrule->wmm_rule->ap[ac]; 1163 + wmm_ac = &rrule->wmm_rule.ap[ac]; 1164 1164 else 1165 - wmm_ac = &rrule->wmm_rule->client[ac]; 1165 + wmm_ac = &rrule->wmm_rule.client[ac]; 1166 1166 qparam->cw_min = max_t(u16, qparam->cw_min, wmm_ac->cw_min); 1167 1167 qparam->cw_max = max_t(u16, qparam->cw_max, wmm_ac->cw_max); 1168 1168 qparam->aifs = max_t(u8, qparam->aifs, wmm_ac->aifsn); 1169 - qparam->txop = !qparam->txop ? wmm_ac->cot / 32 : 1170 - min_t(u16, qparam->txop, wmm_ac->cot / 32); 1169 + qparam->txop = min_t(u16, qparam->txop, wmm_ac->cot / 32); 1171 1170 rcu_read_unlock(); 1172 1171 } 1173 1172
+1
net/rfkill/rfkill-gpio.c
··· 20 20 #include <linux/init.h> 21 21 #include <linux/kernel.h> 22 22 #include <linux/module.h> 23 + #include <linux/mod_devicetable.h> 23 24 #include <linux/rfkill.h> 24 25 #include <linux/platform_device.h> 25 26 #include <linux/clk.h>
+8 -7
net/wireless/nl80211.c
··· 669 669 goto nla_put_failure; 670 670 671 671 if (nla_put_u16(msg, NL80211_WMMR_CW_MIN, 672 - rule->wmm_rule->client[j].cw_min) || 672 + rule->wmm_rule.client[j].cw_min) || 673 673 nla_put_u16(msg, NL80211_WMMR_CW_MAX, 674 - rule->wmm_rule->client[j].cw_max) || 674 + rule->wmm_rule.client[j].cw_max) || 675 675 nla_put_u8(msg, NL80211_WMMR_AIFSN, 676 - rule->wmm_rule->client[j].aifsn) || 677 - nla_put_u8(msg, NL80211_WMMR_TXOP, 678 - rule->wmm_rule->client[j].cot)) 676 + rule->wmm_rule.client[j].aifsn) || 677 + nla_put_u16(msg, NL80211_WMMR_TXOP, 678 + rule->wmm_rule.client[j].cot)) 679 679 goto nla_put_failure; 680 680 681 681 nla_nest_end(msg, nl_wmm_rule); ··· 766 766 767 767 if (large) { 768 768 const struct ieee80211_reg_rule *rule = 769 - freq_reg_info(wiphy, chan->center_freq); 769 + freq_reg_info(wiphy, MHZ_TO_KHZ(chan->center_freq)); 770 770 771 - if (!IS_ERR(rule) && rule->wmm_rule) { 771 + if (!IS_ERR_OR_NULL(rule) && rule->has_wmm) { 772 772 if (nl80211_msg_put_wmm_rules(msg, rule)) 773 773 goto nla_put_failure; 774 774 } ··· 12205 12205 return -EOPNOTSUPP; 12206 12206 12207 12207 if (!info->attrs[NL80211_ATTR_MDID] || 12208 + !info->attrs[NL80211_ATTR_IE] || 12208 12209 !is_valid_ie_attr(info->attrs[NL80211_ATTR_IE])) 12209 12210 return -EINVAL; 12210 12211
+13 -78
net/wireless/reg.c
··· 425 425 reg_copy_regd(const struct ieee80211_regdomain *src_regd) 426 426 { 427 427 struct ieee80211_regdomain *regd; 428 - int size_of_regd, size_of_wmms; 428 + int size_of_regd; 429 429 unsigned int i; 430 - struct ieee80211_wmm_rule *d_wmm, *s_wmm; 431 430 432 431 size_of_regd = 433 432 sizeof(struct ieee80211_regdomain) + 434 433 src_regd->n_reg_rules * sizeof(struct ieee80211_reg_rule); 435 - size_of_wmms = src_regd->n_wmm_rules * 436 - sizeof(struct ieee80211_wmm_rule); 437 434 438 - regd = kzalloc(size_of_regd + size_of_wmms, GFP_KERNEL); 435 + regd = kzalloc(size_of_regd, GFP_KERNEL); 439 436 if (!regd) 440 437 return ERR_PTR(-ENOMEM); 441 438 442 439 memcpy(regd, src_regd, sizeof(struct ieee80211_regdomain)); 443 440 444 - d_wmm = (struct ieee80211_wmm_rule *)((u8 *)regd + size_of_regd); 445 - s_wmm = (struct ieee80211_wmm_rule *)((u8 *)src_regd + size_of_regd); 446 - memcpy(d_wmm, s_wmm, size_of_wmms); 447 - 448 - for (i = 0; i < src_regd->n_reg_rules; i++) { 441 + for (i = 0; i < src_regd->n_reg_rules; i++) 449 442 memcpy(&regd->reg_rules[i], &src_regd->reg_rules[i], 450 443 sizeof(struct ieee80211_reg_rule)); 451 - if (!src_regd->reg_rules[i].wmm_rule) 452 - continue; 453 444 454 - regd->reg_rules[i].wmm_rule = d_wmm + 455 - (src_regd->reg_rules[i].wmm_rule - s_wmm) / 456 - sizeof(struct ieee80211_wmm_rule); 457 - } 458 445 return regd; 459 446 } 460 447 ··· 847 860 return true; 848 861 } 849 862 850 - static void set_wmm_rule(struct ieee80211_wmm_rule *rule, 863 + static void set_wmm_rule(struct ieee80211_reg_rule *rrule, 851 864 struct fwdb_wmm_rule *wmm) 852 865 { 866 + struct ieee80211_wmm_rule *rule = &rrule->wmm_rule; 853 867 unsigned int i; 854 868 855 869 for (i = 0; i < IEEE80211_NUM_ACS; i++) { ··· 864 876 rule->ap[i].aifsn = wmm->ap[i].aifsn; 865 877 rule->ap[i].cot = 1000 * be16_to_cpu(wmm->ap[i].cot); 866 878 } 879 + 880 + rrule->has_wmm = true; 867 881 } 868 882 869 883 static int __regdb_query_wmm(const struct fwdb_header *db, 870 884 const struct fwdb_country *country, int freq, 871 - u32 *dbptr, struct ieee80211_wmm_rule *rule) 885 + struct ieee80211_reg_rule *rule) 872 886 { 873 887 unsigned int ptr = be16_to_cpu(country->coll_ptr) << 2; 874 888 struct fwdb_collection *coll = (void *)((u8 *)db + ptr); ··· 891 901 wmm_ptr = be16_to_cpu(rrule->wmm_ptr) << 2; 892 902 wmm = (void *)((u8 *)db + wmm_ptr); 893 903 set_wmm_rule(rule, wmm); 894 - if (dbptr) 895 - *dbptr = wmm_ptr; 896 904 return 0; 897 905 } 898 906 } ··· 898 910 return -ENODATA; 899 911 } 900 912 901 - int reg_query_regdb_wmm(char *alpha2, int freq, u32 *dbptr, 902 - struct ieee80211_wmm_rule *rule) 913 + int reg_query_regdb_wmm(char *alpha2, int freq, struct ieee80211_reg_rule *rule) 903 914 { 904 915 const struct fwdb_header *hdr = regdb; 905 916 const struct fwdb_country *country; ··· 912 925 country = &hdr->country[0]; 913 926 while (country->coll_ptr) { 914 927 if (alpha2_equal(alpha2, country->alpha2)) 915 - return __regdb_query_wmm(regdb, country, freq, dbptr, 916 - rule); 928 + return __regdb_query_wmm(regdb, country, freq, rule); 917 929 918 930 country++; 919 931 } ··· 921 935 } 922 936 EXPORT_SYMBOL(reg_query_regdb_wmm); 923 937 924 - struct wmm_ptrs { 925 - struct ieee80211_wmm_rule *rule; 926 - u32 ptr; 927 - }; 928 - 929 - static struct ieee80211_wmm_rule *find_wmm_ptr(struct wmm_ptrs *wmm_ptrs, 930 - u32 wmm_ptr, int n_wmms) 931 - { 932 - int i; 933 - 934 - for (i = 0; i < n_wmms; i++) { 935 - if (wmm_ptrs[i].ptr == wmm_ptr) 936 - return wmm_ptrs[i].rule; 937 - } 938 - return NULL; 939 - } 940 - 941 938 static int regdb_query_country(const struct fwdb_header *db, 942 939 const struct fwdb_country *country) 943 940 { 944 941 unsigned int ptr = be16_to_cpu(country->coll_ptr) << 2; 945 942 struct fwdb_collection *coll = (void *)((u8 *)db + ptr); 946 943 struct ieee80211_regdomain *regdom; 947 - struct ieee80211_regdomain *tmp_rd; 948 - unsigned int size_of_regd, i, n_wmms = 0; 949 - struct wmm_ptrs *wmm_ptrs; 944 + unsigned int size_of_regd, i; 950 945 951 946 size_of_regd = sizeof(struct ieee80211_regdomain) + 952 947 coll->n_rules * sizeof(struct ieee80211_reg_rule); ··· 935 968 regdom = kzalloc(size_of_regd, GFP_KERNEL); 936 969 if (!regdom) 937 970 return -ENOMEM; 938 - 939 - wmm_ptrs = kcalloc(coll->n_rules, sizeof(*wmm_ptrs), GFP_KERNEL); 940 - if (!wmm_ptrs) { 941 - kfree(regdom); 942 - return -ENOMEM; 943 - } 944 971 945 972 regdom->n_reg_rules = coll->n_rules; 946 973 regdom->alpha2[0] = country->alpha2[0]; ··· 974 1013 1000 * be16_to_cpu(rule->cac_timeout); 975 1014 if (rule->len >= offsetofend(struct fwdb_rule, wmm_ptr)) { 976 1015 u32 wmm_ptr = be16_to_cpu(rule->wmm_ptr) << 2; 977 - struct ieee80211_wmm_rule *wmm_pos = 978 - find_wmm_ptr(wmm_ptrs, wmm_ptr, n_wmms); 979 - struct fwdb_wmm_rule *wmm; 980 - struct ieee80211_wmm_rule *wmm_rule; 1016 + struct fwdb_wmm_rule *wmm = (void *)((u8 *)db + wmm_ptr); 981 1017 982 - if (wmm_pos) { 983 - rrule->wmm_rule = wmm_pos; 984 - continue; 985 - } 986 - wmm = (void *)((u8 *)db + wmm_ptr); 987 - tmp_rd = krealloc(regdom, size_of_regd + (n_wmms + 1) * 988 - sizeof(struct ieee80211_wmm_rule), 989 - GFP_KERNEL); 990 - 991 - if (!tmp_rd) { 992 - kfree(regdom); 993 - kfree(wmm_ptrs); 994 - return -ENOMEM; 995 - } 996 - regdom = tmp_rd; 997 - 998 - wmm_rule = (struct ieee80211_wmm_rule *) 999 - ((u8 *)regdom + size_of_regd + n_wmms * 1000 - sizeof(struct ieee80211_wmm_rule)); 1001 - 1002 - set_wmm_rule(wmm_rule, wmm); 1003 - wmm_ptrs[n_wmms].ptr = wmm_ptr; 1004 - wmm_ptrs[n_wmms++].rule = wmm_rule; 1018 + set_wmm_rule(rrule, wmm); 1005 1019 } 1006 1020 } 1007 - kfree(wmm_ptrs); 1008 1021 1009 1022 return reg_schedule_apply(regdom); 1010 1023 }
+1 -1
net/wireless/util.c
··· 1456 1456 u8 *op_class) 1457 1457 { 1458 1458 u8 vht_opclass; 1459 - u16 freq = chandef->center_freq1; 1459 + u32 freq = chandef->center_freq1; 1460 1460 1461 1461 if (freq >= 2412 && freq <= 2472) { 1462 1462 if (chandef->width > NL80211_CHAN_WIDTH_40)