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 'wireless-2026-11-22' of https://git.kernel.org/pub/scm/linux/kernel/git/wireless/wireless

Johannes Berg says:

====================
Another set of updates:
- various small fixes for ath10k/ath12k/mwifiex/rsi
- cfg80211 fix for HE bitrate overflow
- mac80211 fixes
- S1G beacon handling in scan
- skb tailroom handling for HW encryption
- CSA fix for multi-link
- handling of disabled links during association

* tag 'wireless-2026-11-22' of https://git.kernel.org/pub/scm/linux/kernel/git/wireless/wireless:
wifi: cfg80211: ignore link disabled flag from userspace
wifi: mac80211: apply advertised TTLM from association response
wifi: mac80211: parse all TTLM entries
wifi: mac80211: don't increment crypto_tx_tailroom_needed_cnt twice
wifi: mac80211: don't perform DA check on S1G beacon
wifi: ath12k: Fix wrong P2P device link id issue
wifi: ath12k: fix dead lock while flushing management frames
wifi: ath12k: Fix scan state stuck in ABORTING after cancel_remain_on_channel
wifi: ath12k: cancel scan only on active scan vdev
wifi: mwifiex: Fix a loop in mwifiex_update_ampdu_rxwinsize()
wifi: mac80211: correctly check if CSA is active
wifi: cfg80211: Fix bitrate calculation overflow for HE rates
wifi: rsi: Fix memory corruption due to not set vif driver data size
wifi: ath12k: don't force radio frequency check in freq_to_idx()
wifi: ath12k: fix dma_free_coherent() pointer
wifi: ath10k: fix dma_free_coherent() pointer
====================

Link: https://patch.msgid.link/20260122110248.15450-3-johannes@sipsolutions.net
Signed-off-by: Jakub Kicinski <kuba@kernel.org>

+171 -150
+8 -8
drivers/net/wireless/ath/ath10k/ce.c
··· 1727 1727 (ce_state->src_ring->nentries * 1728 1728 sizeof(struct ce_desc) + 1729 1729 CE_DESC_RING_ALIGN), 1730 - ce_state->src_ring->base_addr_owner_space, 1731 - ce_state->src_ring->base_addr_ce_space); 1730 + ce_state->src_ring->base_addr_owner_space_unaligned, 1731 + ce_state->src_ring->base_addr_ce_space_unaligned); 1732 1732 kfree(ce_state->src_ring); 1733 1733 } 1734 1734 ··· 1737 1737 (ce_state->dest_ring->nentries * 1738 1738 sizeof(struct ce_desc) + 1739 1739 CE_DESC_RING_ALIGN), 1740 - ce_state->dest_ring->base_addr_owner_space, 1741 - ce_state->dest_ring->base_addr_ce_space); 1740 + ce_state->dest_ring->base_addr_owner_space_unaligned, 1741 + ce_state->dest_ring->base_addr_ce_space_unaligned); 1742 1742 kfree(ce_state->dest_ring); 1743 1743 } 1744 1744 ··· 1758 1758 (ce_state->src_ring->nentries * 1759 1759 sizeof(struct ce_desc_64) + 1760 1760 CE_DESC_RING_ALIGN), 1761 - ce_state->src_ring->base_addr_owner_space, 1762 - ce_state->src_ring->base_addr_ce_space); 1761 + ce_state->src_ring->base_addr_owner_space_unaligned, 1762 + ce_state->src_ring->base_addr_ce_space_unaligned); 1763 1763 kfree(ce_state->src_ring); 1764 1764 } 1765 1765 ··· 1768 1768 (ce_state->dest_ring->nentries * 1769 1769 sizeof(struct ce_desc_64) + 1770 1770 CE_DESC_RING_ALIGN), 1771 - ce_state->dest_ring->base_addr_owner_space, 1772 - ce_state->dest_ring->base_addr_ce_space); 1771 + ce_state->dest_ring->base_addr_owner_space_unaligned, 1772 + ce_state->dest_ring->base_addr_ce_space_unaligned); 1773 1773 kfree(ce_state->dest_ring); 1774 1774 } 1775 1775
+6 -6
drivers/net/wireless/ath/ath12k/ce.c
··· 984 984 dma_free_coherent(ab->dev, 985 985 pipe->src_ring->nentries * desc_sz + 986 986 CE_DESC_RING_ALIGN, 987 - pipe->src_ring->base_addr_owner_space, 988 - pipe->src_ring->base_addr_ce_space); 987 + pipe->src_ring->base_addr_owner_space_unaligned, 988 + pipe->src_ring->base_addr_ce_space_unaligned); 989 989 kfree(pipe->src_ring); 990 990 pipe->src_ring = NULL; 991 991 } ··· 995 995 dma_free_coherent(ab->dev, 996 996 pipe->dest_ring->nentries * desc_sz + 997 997 CE_DESC_RING_ALIGN, 998 - pipe->dest_ring->base_addr_owner_space, 999 - pipe->dest_ring->base_addr_ce_space); 998 + pipe->dest_ring->base_addr_owner_space_unaligned, 999 + pipe->dest_ring->base_addr_ce_space_unaligned); 1000 1000 kfree(pipe->dest_ring); 1001 1001 pipe->dest_ring = NULL; 1002 1002 } ··· 1007 1007 dma_free_coherent(ab->dev, 1008 1008 pipe->status_ring->nentries * desc_sz + 1009 1009 CE_DESC_RING_ALIGN, 1010 - pipe->status_ring->base_addr_owner_space, 1011 - pipe->status_ring->base_addr_ce_space); 1010 + pipe->status_ring->base_addr_owner_space_unaligned, 1011 + pipe->status_ring->base_addr_ce_space_unaligned); 1012 1012 kfree(pipe->status_ring); 1013 1013 pipe->status_ring = NULL; 1014 1014 }
+10 -6
drivers/net/wireless/ath/ath12k/mac.c
··· 5495 5495 5496 5496 for_each_set_bit(link_id, &links_map, ATH12K_NUM_MAX_LINKS) { 5497 5497 arvif = wiphy_dereference(hw->wiphy, ahvif->link[link_id]); 5498 - if (!arvif || arvif->is_started) 5498 + if (!arvif || !arvif->is_created || 5499 + arvif->ar->scan.arvif != arvif) 5499 5500 continue; 5500 5501 5501 5502 ar = arvif->ar; ··· 9173 9172 return; 9174 9173 } 9175 9174 } else { 9176 - link_id = 0; 9175 + if (vif->type == NL80211_IFTYPE_P2P_DEVICE) 9176 + link_id = ATH12K_FIRST_SCAN_LINK; 9177 + else 9178 + link_id = 0; 9177 9179 } 9178 9180 9179 9181 arvif = rcu_dereference(ahvif->link[link_id]); ··· 12146 12142 if (drop) 12147 12143 return; 12148 12144 12145 + for_each_ar(ah, ar, i) 12146 + wiphy_work_flush(hw->wiphy, &ar->wmi_mgmt_tx_work); 12147 + 12149 12148 /* vif can be NULL when flush() is considered for hw */ 12150 12149 if (!vif) { 12151 12150 for_each_ar(ah, ar, i) 12152 12151 ath12k_mac_flush(ar); 12153 12152 return; 12154 12153 } 12155 - 12156 - for_each_ar(ah, ar, i) 12157 - wiphy_work_flush(hw->wiphy, &ar->wmi_mgmt_tx_work); 12158 12154 12159 12155 ahvif = ath12k_vif_to_ahvif(vif); 12160 12156 links = ahvif->links_map; ··· 13347 13343 ath12k_scan_abort(ar); 13348 13344 13349 13345 cancel_delayed_work_sync(&ar->scan.timeout); 13350 - wiphy_work_cancel(hw->wiphy, &ar->scan.vdev_clean_wk); 13346 + wiphy_work_flush(hw->wiphy, &ar->scan.vdev_clean_wk); 13351 13347 13352 13348 return 0; 13353 13349 }
+1 -8
drivers/net/wireless/ath/ath12k/wmi.c
··· 6575 6575 if (!sband) 6576 6576 continue; 6577 6577 6578 - for (ch = 0; ch < sband->n_channels; ch++, idx++) { 6579 - if (sband->channels[ch].center_freq < 6580 - KHZ_TO_MHZ(ar->freq_range.start_freq) || 6581 - sband->channels[ch].center_freq > 6582 - KHZ_TO_MHZ(ar->freq_range.end_freq)) 6583 - continue; 6584 - 6578 + for (ch = 0; ch < sband->n_channels; ch++, idx++) 6585 6579 if (sband->channels[ch].center_freq == freq) 6586 6580 goto exit; 6587 - } 6588 6581 } 6589 6582 6590 6583 exit:
+3 -3
drivers/net/wireless/marvell/mwifiex/11n_rxreorder.c
··· 825 825 static void mwifiex_update_ampdu_rxwinsize(struct mwifiex_adapter *adapter, 826 826 bool coex_flag) 827 827 { 828 - u8 i; 828 + u8 i, j; 829 829 u32 rx_win_size; 830 830 struct mwifiex_private *priv; 831 831 ··· 863 863 if (rx_win_size != priv->add_ba_param.rx_win_size) { 864 864 if (!priv->media_connected) 865 865 continue; 866 - for (i = 0; i < MAX_NUM_TID; i++) 867 - mwifiex_11n_delba(priv, i); 866 + for (j = 0; j < MAX_NUM_TID; j++) 867 + mwifiex_11n_delba(priv, j); 868 868 } 869 869 } 870 870 }
+1
drivers/net/wireless/rsi/rsi_91x_mac80211.c
··· 2035 2035 2036 2036 hw->queues = MAX_HW_QUEUES; 2037 2037 hw->extra_tx_headroom = RSI_NEEDED_HEADROOM; 2038 + hw->vif_data_size = sizeof(struct vif_priv); 2038 2039 2039 2040 hw->max_rates = 1; 2040 2041 hw->max_rate_tries = MAX_RETRIES;
-3
include/net/cfg80211.h
··· 3221 3221 * if this is %NULL for a link, that link is not requested 3222 3222 * @elems: extra elements for the per-STA profile for this link 3223 3223 * @elems_len: length of the elements 3224 - * @disabled: If set this link should be included during association etc. but it 3225 - * should not be used until enabled by the AP MLD. 3226 3224 * @error: per-link error code, must be <= 0. If there is an error, then the 3227 3225 * operation as a whole must fail. 3228 3226 */ ··· 3228 3230 struct cfg80211_bss *bss; 3229 3231 const u8 *elems; 3230 3232 size_t elems_len; 3231 - bool disabled; 3232 3233 int error; 3233 3234 }; 3234 3235
+3 -2
include/uapi/linux/nl80211.h
··· 2880 2880 * index. If the userspace includes more RNR elements than number of 2881 2881 * MBSSID elements then these will be added in every EMA beacon. 2882 2882 * 2883 - * @NL80211_ATTR_MLO_LINK_DISABLED: Flag attribute indicating that the link is 2884 - * disabled. 2883 + * @NL80211_ATTR_MLO_LINK_DISABLED: Unused. It was used to indicate that a link 2884 + * is disabled during association. However, the AP will send the 2885 + * information by including a TTLM in the association response. 2885 2886 * 2886 2887 * @NL80211_ATTR_BSS_DUMP_INCLUDE_USE_DATA: Include BSS usage data, i.e. 2887 2888 * include BSSes that can only be used in restricted scenarios and/or
-2
net/mac80211/ieee80211_i.h
··· 451 451 struct ieee80211_conn_settings conn; 452 452 453 453 u16 status; 454 - 455 - bool disabled; 456 454 } link[IEEE80211_MLD_MAX_NUM_LINKS]; 457 455 458 456 u8 ap_addr[ETH_ALEN] __aligned(2);
+6 -2
net/mac80211/iface.c
··· 350 350 /* we hold the RTNL here so can safely walk the list */ 351 351 list_for_each_entry(nsdata, &local->interfaces, list) { 352 352 if (nsdata != sdata && ieee80211_sdata_running(nsdata)) { 353 + struct ieee80211_link_data *link; 354 + 353 355 /* 354 356 * Only OCB and monitor mode may coexist 355 357 */ ··· 378 376 * will not add another interface while any channel 379 377 * switch is active. 380 378 */ 381 - if (nsdata->vif.bss_conf.csa_active) 382 - return -EBUSY; 379 + for_each_link_data(nsdata, link) { 380 + if (link->conf->csa_active) 381 + return -EBUSY; 382 + } 383 383 384 384 /* 385 385 * The remaining checks are only performed for interfaces
+2 -1
net/mac80211/key.c
··· 987 987 988 988 if (ieee80211_sdata_running(sdata)) { 989 989 list_for_each_entry(key, &sdata->key_list, list) { 990 - increment_tailroom_need_count(sdata); 990 + if (!(key->flags & KEY_FLAG_TAINTED)) 991 + increment_tailroom_need_count(sdata); 991 992 ieee80211_key_enable_hw_accel(key); 992 993 } 993 994 }
+119 -94
net/mac80211/mlme.c
··· 6161 6161 return true; 6162 6162 } 6163 6163 6164 + static u16 ieee80211_get_ttlm(u8 bm_size, u8 *data) 6165 + { 6166 + if (bm_size == 1) 6167 + return *data; 6168 + 6169 + return get_unaligned_le16(data); 6170 + } 6171 + 6172 + static int 6173 + ieee80211_parse_adv_t2l(struct ieee80211_sub_if_data *sdata, 6174 + const struct ieee80211_ttlm_elem *ttlm, 6175 + struct ieee80211_adv_ttlm_info *ttlm_info) 6176 + { 6177 + /* The element size was already validated in 6178 + * ieee80211_tid_to_link_map_size_ok() 6179 + */ 6180 + u8 control, link_map_presence, map_size, tid; 6181 + u8 *pos; 6182 + 6183 + memset(ttlm_info, 0, sizeof(*ttlm_info)); 6184 + pos = (void *)ttlm->optional; 6185 + control = ttlm->control; 6186 + 6187 + if ((control & IEEE80211_TTLM_CONTROL_DIRECTION) != 6188 + IEEE80211_TTLM_DIRECTION_BOTH) { 6189 + sdata_info(sdata, "Invalid advertised T2L map direction\n"); 6190 + return -EINVAL; 6191 + } 6192 + 6193 + link_map_presence = *pos; 6194 + pos++; 6195 + 6196 + if (control & IEEE80211_TTLM_CONTROL_SWITCH_TIME_PRESENT) { 6197 + ttlm_info->switch_time = get_unaligned_le16(pos); 6198 + 6199 + /* Since ttlm_info->switch_time == 0 means no switch time, bump 6200 + * it by 1. 6201 + */ 6202 + if (!ttlm_info->switch_time) 6203 + ttlm_info->switch_time = 1; 6204 + 6205 + pos += 2; 6206 + } 6207 + 6208 + if (control & IEEE80211_TTLM_CONTROL_EXPECTED_DUR_PRESENT) { 6209 + ttlm_info->duration = pos[0] | pos[1] << 8 | pos[2] << 16; 6210 + pos += 3; 6211 + } 6212 + 6213 + if (control & IEEE80211_TTLM_CONTROL_DEF_LINK_MAP) { 6214 + ttlm_info->map = 0xffff; 6215 + return 0; 6216 + } 6217 + 6218 + if (control & IEEE80211_TTLM_CONTROL_LINK_MAP_SIZE) 6219 + map_size = 1; 6220 + else 6221 + map_size = 2; 6222 + 6223 + /* According to Draft P802.11be_D3.0 clause 35.3.7.1.7, an AP MLD shall 6224 + * not advertise a TID-to-link mapping that does not map all TIDs to the 6225 + * same link set, reject frame if not all links have mapping 6226 + */ 6227 + if (link_map_presence != 0xff) { 6228 + sdata_info(sdata, 6229 + "Invalid advertised T2L mapping presence indicator\n"); 6230 + return -EINVAL; 6231 + } 6232 + 6233 + ttlm_info->map = ieee80211_get_ttlm(map_size, pos); 6234 + if (!ttlm_info->map) { 6235 + sdata_info(sdata, 6236 + "Invalid advertised T2L map for TID 0\n"); 6237 + return -EINVAL; 6238 + } 6239 + 6240 + pos += map_size; 6241 + 6242 + for (tid = 1; tid < 8; tid++) { 6243 + u16 map = ieee80211_get_ttlm(map_size, pos); 6244 + 6245 + if (map != ttlm_info->map) { 6246 + sdata_info(sdata, "Invalid advertised T2L map for tid %d\n", 6247 + tid); 6248 + return -EINVAL; 6249 + } 6250 + 6251 + pos += map_size; 6252 + } 6253 + return 0; 6254 + } 6255 + 6164 6256 static bool ieee80211_assoc_success(struct ieee80211_sub_if_data *sdata, 6165 6257 struct ieee80211_mgmt *mgmt, 6166 6258 struct ieee802_11_elems *elems, ··· 6284 6192 continue; 6285 6193 6286 6194 valid_links |= BIT(link_id); 6287 - if (assoc_data->link[link_id].disabled) 6288 - dormant_links |= BIT(link_id); 6289 6195 6290 6196 if (link_id != assoc_data->assoc_link_id) { 6291 6197 err = ieee80211_sta_allocate_link(sta, link_id); 6292 6198 if (err) 6293 6199 goto out_err; 6294 6200 } 6201 + } 6202 + 6203 + /* 6204 + * We do not support setting a negotiated TTLM during 6205 + * association. As such, we can assume that if there is a TTLM, 6206 + * then it is the currently active advertised TTLM. 6207 + * In that case, there must be exactly one TTLM that does not 6208 + * have a switch time set. This mapping should also leave us 6209 + * with at least one usable link. 6210 + */ 6211 + if (elems->ttlm_num > 1) { 6212 + sdata_info(sdata, 6213 + "More than one advertised TTLM in association response\n"); 6214 + goto out_err; 6215 + } else if (elems->ttlm_num == 1) { 6216 + if (ieee80211_parse_adv_t2l(sdata, elems->ttlm[0], 6217 + &sdata->u.mgd.ttlm_info) || 6218 + sdata->u.mgd.ttlm_info.switch_time != 0 || 6219 + !(valid_links & sdata->u.mgd.ttlm_info.map)) { 6220 + sdata_info(sdata, 6221 + "Invalid advertised TTLM in association response\n"); 6222 + goto out_err; 6223 + } 6224 + 6225 + sdata->u.mgd.ttlm_info.active = true; 6226 + dormant_links = 6227 + valid_links & ~sdata->u.mgd.ttlm_info.map; 6295 6228 } 6296 6229 6297 6230 ieee80211_vif_set_links(sdata, valid_links, dormant_links); ··· 7107 6990 7108 6991 sdata->u.mgd.ttlm_info.active = true; 7109 6992 sdata->u.mgd.ttlm_info.switch_time = 0; 7110 - } 7111 - 7112 - static u16 ieee80211_get_ttlm(u8 bm_size, u8 *data) 7113 - { 7114 - if (bm_size == 1) 7115 - return *data; 7116 - else 7117 - return get_unaligned_le16(data); 7118 - } 7119 - 7120 - static int 7121 - ieee80211_parse_adv_t2l(struct ieee80211_sub_if_data *sdata, 7122 - const struct ieee80211_ttlm_elem *ttlm, 7123 - struct ieee80211_adv_ttlm_info *ttlm_info) 7124 - { 7125 - /* The element size was already validated in 7126 - * ieee80211_tid_to_link_map_size_ok() 7127 - */ 7128 - u8 control, link_map_presence, map_size, tid; 7129 - u8 *pos; 7130 - 7131 - memset(ttlm_info, 0, sizeof(*ttlm_info)); 7132 - pos = (void *)ttlm->optional; 7133 - control = ttlm->control; 7134 - 7135 - if ((control & IEEE80211_TTLM_CONTROL_DEF_LINK_MAP) || 7136 - !(control & IEEE80211_TTLM_CONTROL_SWITCH_TIME_PRESENT)) 7137 - return 0; 7138 - 7139 - if ((control & IEEE80211_TTLM_CONTROL_DIRECTION) != 7140 - IEEE80211_TTLM_DIRECTION_BOTH) { 7141 - sdata_info(sdata, "Invalid advertised T2L map direction\n"); 7142 - return -EINVAL; 7143 - } 7144 - 7145 - link_map_presence = *pos; 7146 - pos++; 7147 - 7148 - ttlm_info->switch_time = get_unaligned_le16(pos); 7149 - 7150 - /* Since ttlm_info->switch_time == 0 means no switch time, bump it 7151 - * by 1. 7152 - */ 7153 - if (!ttlm_info->switch_time) 7154 - ttlm_info->switch_time = 1; 7155 - 7156 - pos += 2; 7157 - 7158 - if (control & IEEE80211_TTLM_CONTROL_EXPECTED_DUR_PRESENT) { 7159 - ttlm_info->duration = pos[0] | pos[1] << 8 | pos[2] << 16; 7160 - pos += 3; 7161 - } 7162 - 7163 - if (control & IEEE80211_TTLM_CONTROL_LINK_MAP_SIZE) 7164 - map_size = 1; 7165 - else 7166 - map_size = 2; 7167 - 7168 - /* According to Draft P802.11be_D3.0 clause 35.3.7.1.7, an AP MLD shall 7169 - * not advertise a TID-to-link mapping that does not map all TIDs to the 7170 - * same link set, reject frame if not all links have mapping 7171 - */ 7172 - if (link_map_presence != 0xff) { 7173 - sdata_info(sdata, 7174 - "Invalid advertised T2L mapping presence indicator\n"); 7175 - return -EINVAL; 7176 - } 7177 - 7178 - ttlm_info->map = ieee80211_get_ttlm(map_size, pos); 7179 - if (!ttlm_info->map) { 7180 - sdata_info(sdata, 7181 - "Invalid advertised T2L map for TID 0\n"); 7182 - return -EINVAL; 7183 - } 7184 - 7185 - pos += map_size; 7186 - 7187 - for (tid = 1; tid < 8; tid++) { 7188 - u16 map = ieee80211_get_ttlm(map_size, pos); 7189 - 7190 - if (map != ttlm_info->map) { 7191 - sdata_info(sdata, "Invalid advertised T2L map for tid %d\n", 7192 - tid); 7193 - return -EINVAL; 7194 - } 7195 - 7196 - pos += map_size; 7197 - } 7198 - return 0; 7199 6993 } 7200 6994 7201 6995 static void ieee80211_process_adv_ttlm(struct ieee80211_sub_if_data *sdata, ··· 9765 9737 req, true, i, 9766 9738 &assoc_data->link[i].conn); 9767 9739 assoc_data->link[i].bss = link_cbss; 9768 - assoc_data->link[i].disabled = req->links[i].disabled; 9769 9740 9770 9741 if (!bss->uapsd_supported) 9771 9742 uapsd_supported = false; ··· 10746 10719 &data->link[link_id].conn); 10747 10720 10748 10721 data->link[link_id].bss = link_cbss; 10749 - data->link[link_id].disabled = 10750 - req->add_links[link_id].disabled; 10751 10722 data->link[link_id].elems = 10752 10723 (u8 *)req->add_links[link_id].elems; 10753 10724 data->link[link_id].elems_len =
+7 -2
net/mac80211/scan.c
··· 347 347 mgmt->da)) 348 348 return; 349 349 } else { 350 - /* Beacons are expected only with broadcast address */ 351 - if (!is_broadcast_ether_addr(mgmt->da)) 350 + /* 351 + * Non-S1G beacons are expected only with broadcast address. 352 + * S1G beacons only carry the SA so no DA check is required 353 + * nor possible. 354 + */ 355 + if (!ieee80211_is_s1g_beacon(mgmt->frame_control) && 356 + !is_broadcast_ether_addr(mgmt->da)) 352 357 return; 353 358 } 354 359
-10
net/wireless/nl80211.c
··· 12241 12241 return -EINVAL; 12242 12242 } 12243 12243 } 12244 - 12245 - links[link_id].disabled = 12246 - nla_get_flag(attrs[NL80211_ATTR_MLO_LINK_DISABLED]); 12247 12244 } 12248 12245 12249 12246 return 0; ··· 12416 12419 if (req.links[req.link_id].elems_len) { 12417 12420 GENL_SET_ERR_MSG(info, 12418 12421 "cannot have per-link elems on assoc link"); 12419 - err = -EINVAL; 12420 - goto free; 12421 - } 12422 - 12423 - if (req.links[req.link_id].disabled) { 12424 - GENL_SET_ERR_MSG(info, 12425 - "cannot have assoc link disabled"); 12426 12422 err = -EINVAL; 12427 12423 goto free; 12428 12424 }
+5 -3
net/wireless/util.c
··· 1561 1561 tmp = result; 1562 1562 tmp *= SCALE; 1563 1563 do_div(tmp, mcs_divisors[rate->mcs]); 1564 - result = tmp; 1565 1564 1566 1565 /* and take NSS, DCM into account */ 1567 - result = (result * rate->nss) / 8; 1566 + tmp *= rate->nss; 1567 + do_div(tmp, 8); 1568 1568 if (rate->he_dcm) 1569 - result /= 2; 1569 + do_div(tmp, 2); 1570 + 1571 + result = tmp; 1570 1572 1571 1573 return result / 10000; 1572 1574 }