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

Merge tag 'wireless-next-2024-02-22' of git://git.kernel.org/pub/scm/linux/kernel/git/wireless/wireless-next

Kalle Valo says:

====================
wireless-next patches for v6.9

The third "new features" pull request for v6.9. This is a quick
followup to send commit 04edb5dc68f4 ("wifi: ath12k: Fix uninitialized
use of ret in ath12k_mac_allocate()") to fix the ath12k clang warning
introduced in the previous pull request.

We also have support for QCA2066 in ath11k, several new features in
ath12k and few other changes in drivers. In stack it's mostly cleanup
and refactoring.

Major changes:

ath12k
* firmware-2.bin support
* support having multiple identical PCI devices (firmware needs to
have ATH12K_FW_FEATURE_MULTI_QRTR_ID)
* QCN9274: support split-PHY devices
* WCN7850: enable Power Save Mode in station mode
* WCN7850: P2P support

ath11k:
* QCA6390 & WCN6855: support 2 concurrent station interfaces
* QCA2066 support

iwlwifi
* mvm: support wider-bandwidth OFDMA
* bump firmware API to 90 for BZ/SC devices

brcmfmac
* DMI nvram filename quirk for ACEPC W5 Pro

* tag 'wireless-next-2024-02-22' of git://git.kernel.org/pub/scm/linux/kernel/git/wireless/wireless-next: (75 commits)
wifi: wilc1000: revert reset line logic flip
wifi: brcmfmac: Add DMI nvram filename quirk for ACEPC W5 Pro
wifi: rtlwifi: set initial values for unexpected cases of USB endpoint priority
wifi: rtl8xxxu: check vif before using in rtl8xxxu_tx()
wifi: rtlwifi: rtl8192cu: Fix TX aggregation
wifi: wilc1000: remove AKM suite be32 conversion for external auth request
wifi: nl80211: refactor parsing CSA offsets
wifi: nl80211: force WLAN_AKM_SUITE_SAE in big endian in NL80211_CMD_EXTERNAL_AUTH
wifi: iwlwifi: load b0 version of ucode for HR1/HR2
wifi: iwlwifi: handle per-phy statistics from fw
wifi: iwlwifi: iwl-fh.h: fix kernel-doc issues
wifi: iwlwifi: api: fix kernel-doc reference
wifi: iwlwifi: mvm: unlock mvm if there is no primary link
wifi: iwlwifi: bump FW API to 90 for BZ/SC devices
wifi: iwlwifi: mvm: support PHY context version 6
wifi: iwlwifi: mvm: partially support PHY context version 6
wifi: iwlwifi: mvm: support wider-bandwidth OFDMA
wifi: cfg80211: use ML element parsing helpers
wifi: mac80211: align ieee80211_mle_get_bss_param_ch_cnt()
wifi: cfg80211: refactor RNR parsing
...
====================

Link: https://lore.kernel.org/r/20240222105205.CEC54C433F1@smtp.kernel.org
Signed-off-by: Jakub Kicinski <kuba@kernel.org>

+2948 -962
+1 -1
drivers/net/wireless/ath/ath10k/mac.c
··· 2034 2034 if (!arvif->is_up) 2035 2035 return; 2036 2036 2037 - if (!ieee80211_beacon_cntdwn_is_complete(vif)) { 2037 + if (!ieee80211_beacon_cntdwn_is_complete(vif, 0)) { 2038 2038 ieee80211_beacon_update_cntdwn(vif, 0); 2039 2039 2040 2040 ret = ath10k_mac_setup_bcn_tmpl(arvif);
+1 -1
drivers/net/wireless/ath/ath10k/wmi.c
··· 3884 3884 * actual channel switch is done 3885 3885 */ 3886 3886 if (arvif->vif->bss_conf.csa_active && 3887 - ieee80211_beacon_cntdwn_is_complete(arvif->vif)) { 3887 + ieee80211_beacon_cntdwn_is_complete(arvif->vif, 0)) { 3888 3888 ieee80211_csa_finish(arvif->vif, 0); 3889 3889 continue; 3890 3890 }
+97 -3
drivers/net/wireless/ath/ath11k/core.c
··· 122 122 .tcl_ring_retry = true, 123 123 .tx_ring_size = DP_TCL_DATA_RING_SIZE, 124 124 .smp2p_wow_exit = false, 125 + .support_dual_stations = false, 125 126 }, 126 127 { 127 128 .hw_rev = ATH11K_HW_IPQ6018_HW10, ··· 206 205 .tx_ring_size = DP_TCL_DATA_RING_SIZE, 207 206 .smp2p_wow_exit = false, 208 207 .support_fw_mac_sequence = false, 208 + .support_dual_stations = false, 209 209 }, 210 210 { 211 211 .name = "qca6390 hw2.0", ··· 257 255 .coldboot_cal_ftm = false, 258 256 .cbcal_restart_fw = false, 259 257 .fw_mem_mode = 0, 260 - .num_vdevs = 16 + 1, 258 + .num_vdevs = 2 + 1, 261 259 .num_peers = 512, 262 260 .supports_suspend = true, 263 261 .hal_desc_sz = sizeof(struct hal_rx_desc_ipq8074), ··· 292 290 .tx_ring_size = DP_TCL_DATA_RING_SIZE, 293 291 .smp2p_wow_exit = false, 294 292 .support_fw_mac_sequence = true, 293 + .support_dual_stations = true, 295 294 }, 296 295 { 297 296 .name = "qcn9074 hw1.0", ··· 375 372 .tx_ring_size = DP_TCL_DATA_RING_SIZE, 376 373 .smp2p_wow_exit = false, 377 374 .support_fw_mac_sequence = false, 375 + .support_dual_stations = false, 378 376 }, 379 377 { 380 378 .name = "wcn6855 hw2.0", ··· 426 422 .coldboot_cal_ftm = false, 427 423 .cbcal_restart_fw = false, 428 424 .fw_mem_mode = 0, 429 - .num_vdevs = 16 + 1, 425 + .num_vdevs = 2 + 1, 430 426 .num_peers = 512, 431 427 .supports_suspend = true, 432 428 .hal_desc_sz = sizeof(struct hal_rx_desc_wcn6855), ··· 461 457 .tx_ring_size = DP_TCL_DATA_RING_SIZE, 462 458 .smp2p_wow_exit = false, 463 459 .support_fw_mac_sequence = true, 460 + .support_dual_stations = true, 464 461 }, 465 462 { 466 463 .name = "wcn6855 hw2.1", ··· 510 505 .coldboot_cal_ftm = false, 511 506 .cbcal_restart_fw = false, 512 507 .fw_mem_mode = 0, 513 - .num_vdevs = 16 + 1, 508 + .num_vdevs = 2 + 1, 514 509 .num_peers = 512, 515 510 .supports_suspend = true, 516 511 .hal_desc_sz = sizeof(struct hal_rx_desc_wcn6855), ··· 545 540 .tx_ring_size = DP_TCL_DATA_RING_SIZE, 546 541 .smp2p_wow_exit = false, 547 542 .support_fw_mac_sequence = true, 543 + .support_dual_stations = true, 548 544 }, 549 545 { 550 546 .name = "wcn6750 hw1.0", ··· 627 621 .tx_ring_size = DP_TCL_DATA_RING_SIZE_WCN6750, 628 622 .smp2p_wow_exit = true, 629 623 .support_fw_mac_sequence = true, 624 + .support_dual_stations = false, 630 625 }, 631 626 { 632 627 .hw_rev = ATH11K_HW_IPQ5018_HW10, ··· 709 702 .tx_ring_size = DP_TCL_DATA_RING_SIZE, 710 703 .smp2p_wow_exit = false, 711 704 .support_fw_mac_sequence = false, 705 + .support_dual_stations = false, 706 + }, 707 + { 708 + .name = "qca2066 hw2.1", 709 + .hw_rev = ATH11K_HW_QCA2066_HW21, 710 + .fw = { 711 + .dir = "QCA2066/hw2.1", 712 + .board_size = 256 * 1024, 713 + .cal_offset = 128 * 1024, 714 + }, 715 + .max_radios = 3, 716 + .bdf_addr = 0x4B0C0000, 717 + .hw_ops = &wcn6855_ops, 718 + .ring_mask = &ath11k_hw_ring_mask_qca6390, 719 + .internal_sleep_clock = true, 720 + .regs = &wcn6855_regs, 721 + .qmi_service_ins_id = ATH11K_QMI_WLFW_SERVICE_INS_ID_V01_QCA6390, 722 + .host_ce_config = ath11k_host_ce_config_qca6390, 723 + .ce_count = 9, 724 + .target_ce_config = ath11k_target_ce_config_wlan_qca6390, 725 + .target_ce_count = 9, 726 + .svc_to_ce_map = ath11k_target_service_to_ce_map_wlan_qca6390, 727 + .svc_to_ce_map_len = 14, 728 + .ce_ie_addr = &ath11k_ce_ie_addr_ipq8074, 729 + .single_pdev_only = true, 730 + .rxdma1_enable = false, 731 + .num_rxmda_per_pdev = 2, 732 + .rx_mac_buf_ring = true, 733 + .vdev_start_delay = true, 734 + .htt_peer_map_v2 = false, 735 + 736 + .spectral = { 737 + .fft_sz = 0, 738 + .fft_pad_sz = 0, 739 + .summary_pad_sz = 0, 740 + .fft_hdr_len = 0, 741 + .max_fft_bins = 0, 742 + .fragment_160mhz = false, 743 + }, 744 + 745 + .interface_modes = BIT(NL80211_IFTYPE_STATION) | 746 + BIT(NL80211_IFTYPE_AP), 747 + .supports_monitor = false, 748 + .full_monitor_mode = false, 749 + .supports_shadow_regs = true, 750 + .idle_ps = true, 751 + .supports_sta_ps = true, 752 + .coldboot_cal_mm = false, 753 + .coldboot_cal_ftm = false, 754 + .cbcal_restart_fw = false, 755 + .fw_mem_mode = 0, 756 + .num_vdevs = 2 + 1, 757 + .num_peers = 512, 758 + .supports_suspend = true, 759 + .hal_desc_sz = sizeof(struct hal_rx_desc_wcn6855), 760 + .supports_regdb = true, 761 + .fix_l1ss = false, 762 + .credit_flow = true, 763 + .max_tx_ring = DP_TCL_NUM_RING_MAX_QCA6390, 764 + .hal_params = &ath11k_hw_hal_params_qca6390, 765 + .supports_dynamic_smps_6ghz = false, 766 + .alloc_cacheable_memory = false, 767 + .supports_rssi_stats = true, 768 + .fw_wmi_diag_event = true, 769 + .current_cc_support = true, 770 + .dbr_debug_support = false, 771 + .global_reset = true, 772 + .bios_sar_capa = &ath11k_hw_sar_capa_wcn6855, 773 + .m3_fw_support = true, 774 + .fixed_bdf_addr = false, 775 + .fixed_mem_region = false, 776 + .static_window_map = false, 777 + .hybrid_bus_type = false, 778 + .fixed_fw_mem = false, 779 + .support_off_channel_tx = true, 780 + .supports_multi_bssid = true, 781 + 782 + .sram_dump = { 783 + .start = 0x01400000, 784 + .end = 0x0177ffff, 785 + }, 786 + 787 + .tcl_ring_retry = true, 788 + .tx_ring_size = DP_TCL_DATA_RING_SIZE, 789 + .smp2p_wow_exit = false, 790 + .support_fw_mac_sequence = true, 791 + .support_dual_stations = true, 712 792 }, 713 793 }; 714 794
+1
drivers/net/wireless/ath/ath11k/core.h
··· 147 147 ATH11K_HW_WCN6855_HW21, 148 148 ATH11K_HW_WCN6750_HW10, 149 149 ATH11K_HW_IPQ5018_HW10, 150 + ATH11K_HW_QCA2066_HW21, 150 151 }; 151 152 152 153 enum ath11k_firmware_mode {
+1 -1
drivers/net/wireless/ath/ath11k/hw.c
··· 58 58 static void ath11k_init_wmi_config_qca6390(struct ath11k_base *ab, 59 59 struct target_resource_config *config) 60 60 { 61 - config->num_vdevs = 4; 61 + config->num_vdevs = ab->hw_params.num_vdevs; 62 62 config->num_peers = 16; 63 63 config->num_tids = 32; 64 64
+1
drivers/net/wireless/ath/ath11k/hw.h
··· 226 226 u32 tx_ring_size; 227 227 bool smp2p_wow_exit; 228 228 bool support_fw_mac_sequence; 229 + bool support_dual_stations; 229 230 }; 230 231 231 232 struct ath11k_hw_ops {
+86 -32
drivers/net/wireless/ath/ath11k/mac.c
··· 1577 1577 return; 1578 1578 1579 1579 if (vif->bss_conf.color_change_active && 1580 - ieee80211_beacon_cntdwn_is_complete(vif)) { 1580 + ieee80211_beacon_cntdwn_is_complete(vif, 0)) { 1581 1581 arvif->bcca_zero_sent = true; 1582 1582 ieee80211_color_change_finish(vif); 1583 1583 return; ··· 2294 2294 mcs_160_map = le16_to_cpu(he_cap->he_mcs_nss_supp.rx_mcs_160); 2295 2295 mcs_80_map = le16_to_cpu(he_cap->he_mcs_nss_supp.rx_mcs_80); 2296 2296 2297 + /* Initialize rx_mcs_160 to 9 which is an invalid value */ 2298 + rx_mcs_160 = 9; 2297 2299 if (support_160) { 2298 2300 for (i = 7; i >= 0; i--) { 2299 2301 u8 mcs_160 = (mcs_160_map >> (2 * i)) & 3; ··· 2307 2305 } 2308 2306 } 2309 2307 2308 + /* Initialize rx_mcs_80 to 9 which is an invalid value */ 2309 + rx_mcs_80 = 9; 2310 2310 for (i = 7; i >= 0; i--) { 2311 2311 u8 mcs_80 = (mcs_80_map >> (2 * i)) & 3; 2312 2312 ··· 3027 3023 3028 3024 rcu_read_unlock(); 3029 3025 3026 + if (!ath11k_mac_vif_recalc_sta_he_txbf(ar, vif, &he_cap)) { 3027 + ath11k_warn(ar->ab, "failed to recalc he txbf for vdev %i on bss %pM\n", 3028 + arvif->vdev_id, bss_conf->bssid); 3029 + return; 3030 + } 3031 + 3030 3032 peer_arg.is_assoc = true; 3033 + 3031 3034 ret = ath11k_wmi_send_peer_assoc_cmd(ar, &peer_arg); 3032 3035 if (ret) { 3033 3036 ath11k_warn(ar->ab, "failed to run peer assoc for %pM vdev %i: %d\n", ··· 3054 3043 if (ret) { 3055 3044 ath11k_warn(ar->ab, "failed to setup peer SMPS for vdev %d: %d\n", 3056 3045 arvif->vdev_id, ret); 3057 - return; 3058 - } 3059 - 3060 - if (!ath11k_mac_vif_recalc_sta_he_txbf(ar, vif, &he_cap)) { 3061 - ath11k_warn(ar->ab, "failed to recalc he txbf for vdev %i on bss %pM\n", 3062 - arvif->vdev_id, bss_conf->bssid); 3063 3046 return; 3064 3047 } 3065 3048 ··· 4013 4008 req->ssids[i].ssid_len); 4014 4009 } 4015 4010 } else { 4016 - arg->scan_flags |= WMI_SCAN_FLAG_PASSIVE; 4011 + arg->scan_f_passive = 1; 4017 4012 } 4018 4013 4019 4014 if (req->n_channels) { ··· 7590 7585 struct ieee80211_chanctx_conf *ctx) 7591 7586 { 7592 7587 struct ath11k_base *ab = ar->ab; 7593 - struct ath11k_vif *arvif = (void *)vif->drv_priv; 7588 + struct ath11k_vif *arvif = ath11k_vif_to_arvif(vif); 7594 7589 struct ieee80211_bss_conf *bss_conf = &vif->bss_conf; 7595 7590 struct ath11k_reg_tpc_power_info *reg_tpc_info = &arvif->reg_tpc_info; 7596 7591 struct ieee80211_channel *chan, *temp_chan; 7597 7592 u8 pwr_lvl_idx, num_pwr_levels, pwr_reduction; 7598 7593 bool is_psd_power = false, is_tpe_present = false; 7599 7594 s8 max_tx_power[IEEE80211_MAX_NUM_PWR_LEVEL], 7600 - psd_power, tx_power, eirp_power; 7595 + psd_power, tx_power; 7596 + s8 eirp_power = 0; 7601 7597 u16 start_freq, center_freq; 7602 7598 7603 7599 chan = ctx->def.chan; ··· 7764 7758 struct ieee80211_chanctx_conf *ctx) 7765 7759 { 7766 7760 struct ath11k_base *ab = ar->ab; 7767 - struct ath11k_vif *arvif = (void *)vif->drv_priv; 7761 + struct ath11k_vif *arvif = ath11k_vif_to_arvif(vif); 7768 7762 struct ieee80211_bss_conf *bss_conf = &vif->bss_conf; 7769 7763 struct ieee80211_tx_pwr_env *single_tpe; 7770 7764 enum wmi_reg_6ghz_client_type client_type; ··· 9252 9246 arg->dwell_time_active = scan_time_msec; 9253 9247 arg->dwell_time_passive = scan_time_msec; 9254 9248 arg->max_scan_time = scan_time_msec; 9255 - arg->scan_flags |= WMI_SCAN_FLAG_PASSIVE; 9256 - arg->scan_flags |= WMI_SCAN_FILTER_PROBE_REQ; 9249 + arg->scan_f_passive = 1; 9250 + arg->scan_f_filter_prb_req = 1; 9257 9251 arg->burst_duration = duration; 9258 9252 9259 9253 ret = ath11k_start_scan(ar, arg); ··· 9824 9818 return 0; 9825 9819 } 9826 9820 9821 + static void ath11k_mac_setup_mac_address_list(struct ath11k *ar) 9822 + { 9823 + struct mac_address *addresses; 9824 + u16 n_addresses; 9825 + int i; 9826 + 9827 + if (!ar->ab->hw_params.support_dual_stations) 9828 + return; 9829 + 9830 + n_addresses = ar->ab->hw_params.num_vdevs; 9831 + addresses = kcalloc(n_addresses, sizeof(*addresses), GFP_KERNEL); 9832 + if (!addresses) 9833 + return; 9834 + 9835 + memcpy(addresses[0].addr, ar->mac_addr, ETH_ALEN); 9836 + for (i = 1; i < n_addresses; i++) { 9837 + memcpy(addresses[i].addr, ar->mac_addr, ETH_ALEN); 9838 + /* set Local Administered Address bit */ 9839 + addresses[i].addr[0] |= 0x2; 9840 + 9841 + addresses[i].addr[0] += (i - 1) << 4; 9842 + } 9843 + 9844 + ar->hw->wiphy->addresses = addresses; 9845 + ar->hw->wiphy->n_addresses = n_addresses; 9846 + } 9847 + 9827 9848 static int ath11k_mac_setup_iface_combinations(struct ath11k *ar) 9828 9849 { 9829 9850 struct ath11k_base *ab = ar->ab; ··· 9870 9837 return -ENOMEM; 9871 9838 } 9872 9839 9873 - limits[0].max = 1; 9874 - limits[0].types |= BIT(NL80211_IFTYPE_STATION); 9840 + if (ab->hw_params.support_dual_stations) { 9841 + limits[0].max = 2; 9842 + limits[0].types |= BIT(NL80211_IFTYPE_STATION); 9875 9843 9876 - limits[1].max = 16; 9877 - limits[1].types |= BIT(NL80211_IFTYPE_AP); 9844 + limits[1].max = 1; 9845 + limits[1].types |= BIT(NL80211_IFTYPE_AP); 9846 + if (IS_ENABLED(CONFIG_MAC80211_MESH) && 9847 + ab->hw_params.interface_modes & BIT(NL80211_IFTYPE_MESH_POINT)) 9848 + limits[1].types |= BIT(NL80211_IFTYPE_MESH_POINT); 9878 9849 9879 - if (IS_ENABLED(CONFIG_MAC80211_MESH) && 9880 - ab->hw_params.interface_modes & BIT(NL80211_IFTYPE_MESH_POINT)) 9881 - limits[1].types |= BIT(NL80211_IFTYPE_MESH_POINT); 9850 + combinations[0].limits = limits; 9851 + combinations[0].n_limits = 2; 9852 + combinations[0].max_interfaces = ab->hw_params.num_vdevs; 9853 + combinations[0].num_different_channels = 2; 9854 + combinations[0].beacon_int_infra_match = true; 9855 + combinations[0].beacon_int_min_gcd = 100; 9856 + } else { 9857 + limits[0].max = 1; 9858 + limits[0].types |= BIT(NL80211_IFTYPE_STATION); 9882 9859 9883 - combinations[0].limits = limits; 9884 - combinations[0].n_limits = n_limits; 9885 - combinations[0].max_interfaces = 16; 9886 - combinations[0].num_different_channels = 1; 9887 - combinations[0].beacon_int_infra_match = true; 9888 - combinations[0].beacon_int_min_gcd = 100; 9889 - combinations[0].radar_detect_widths = BIT(NL80211_CHAN_WIDTH_20_NOHT) | 9890 - BIT(NL80211_CHAN_WIDTH_20) | 9891 - BIT(NL80211_CHAN_WIDTH_40) | 9892 - BIT(NL80211_CHAN_WIDTH_80) | 9893 - BIT(NL80211_CHAN_WIDTH_80P80) | 9894 - BIT(NL80211_CHAN_WIDTH_160); 9860 + limits[1].max = 16; 9861 + limits[1].types |= BIT(NL80211_IFTYPE_AP); 9862 + 9863 + if (IS_ENABLED(CONFIG_MAC80211_MESH) && 9864 + ab->hw_params.interface_modes & BIT(NL80211_IFTYPE_MESH_POINT)) 9865 + limits[1].types |= BIT(NL80211_IFTYPE_MESH_POINT); 9866 + 9867 + combinations[0].limits = limits; 9868 + combinations[0].n_limits = 2; 9869 + combinations[0].max_interfaces = 16; 9870 + combinations[0].num_different_channels = 1; 9871 + combinations[0].beacon_int_infra_match = true; 9872 + combinations[0].beacon_int_min_gcd = 100; 9873 + combinations[0].radar_detect_widths = BIT(NL80211_CHAN_WIDTH_20_NOHT) | 9874 + BIT(NL80211_CHAN_WIDTH_20) | 9875 + BIT(NL80211_CHAN_WIDTH_40) | 9876 + BIT(NL80211_CHAN_WIDTH_80) | 9877 + BIT(NL80211_CHAN_WIDTH_80P80) | 9878 + BIT(NL80211_CHAN_WIDTH_160); 9879 + } 9895 9880 9896 9881 ar->hw->wiphy->iface_combinations = combinations; 9897 9882 ar->hw->wiphy->n_iface_combinations = 1; ··· 9974 9923 kfree(ar->hw->wiphy->iface_combinations[0].limits); 9975 9924 kfree(ar->hw->wiphy->iface_combinations); 9976 9925 9926 + kfree(ar->hw->wiphy->addresses); 9927 + 9977 9928 SET_IEEE80211_DEV(ar->hw, NULL); 9978 9929 } 9979 9930 ··· 10018 9965 ath11k_pdev_caps_update(ar); 10019 9966 10020 9967 SET_IEEE80211_PERM_ADDR(ar->hw, ar->mac_addr); 9968 + ath11k_mac_setup_mac_address_list(ar); 10021 9969 10022 9970 SET_IEEE80211_DEV(ar->hw, ab->dev); 10023 9971
+1
drivers/net/wireless/ath/ath11k/mhi.c
··· 443 443 case ATH11K_HW_QCA6390_HW20: 444 444 case ATH11K_HW_WCN6855_HW20: 445 445 case ATH11K_HW_WCN6855_HW21: 446 + case ATH11K_HW_QCA2066_HW21: 446 447 ath11k_mhi_config = &ath11k_mhi_config_qca6390; 447 448 break; 448 449 default:
+32 -11
drivers/net/wireless/ath/ath11k/pci.c
··· 29 29 #define QCN9074_DEVICE_ID 0x1104 30 30 #define WCN6855_DEVICE_ID 0x1103 31 31 32 + #define TCSR_SOC_HW_SUB_VER 0x1910010 33 + 32 34 static const struct pci_device_id ath11k_pci_id_table[] = { 33 35 { PCI_VDEVICE(QCOM, QCA6390_DEVICE_ID) }, 34 36 { PCI_VDEVICE(QCOM, WCN6855_DEVICE_ID) }, ··· 744 742 struct ath11k_base *ab; 745 743 struct ath11k_pci *ab_pci; 746 744 u32 soc_hw_version_major, soc_hw_version_minor, addr; 747 - const struct ath11k_pci_ops *pci_ops; 748 745 int ret; 746 + u32 sub_version; 749 747 750 748 ab = ath11k_core_alloc(&pdev->dev, sizeof(*ab_pci), ATH11K_BUS_PCI); 751 749 ··· 790 788 791 789 switch (pci_dev->device) { 792 790 case QCA6390_DEVICE_ID: 791 + ret = ath11k_pcic_register_pci_ops(ab, &ath11k_pci_ops_qca6390); 792 + if (ret) { 793 + ath11k_err(ab, "failed to register PCI ops: %d\n", ret); 794 + goto err_pci_free_region; 795 + } 796 + 793 797 ath11k_pci_read_hw_version(ab, &soc_hw_version_major, 794 798 &soc_hw_version_minor); 795 799 switch (soc_hw_version_major) { ··· 809 801 goto err_pci_free_region; 810 802 } 811 803 812 - pci_ops = &ath11k_pci_ops_qca6390; 813 804 break; 814 805 case QCN9074_DEVICE_ID: 815 - pci_ops = &ath11k_pci_ops_qcn9074; 806 + ret = ath11k_pcic_register_pci_ops(ab, &ath11k_pci_ops_qcn9074); 807 + if (ret) { 808 + ath11k_err(ab, "failed to register PCI ops: %d\n", ret); 809 + goto err_pci_free_region; 810 + } 816 811 ab->hw_rev = ATH11K_HW_QCN9074_HW10; 817 812 break; 818 813 case WCN6855_DEVICE_ID: 814 + ret = ath11k_pcic_register_pci_ops(ab, &ath11k_pci_ops_qca6390); 815 + if (ret) { 816 + ath11k_err(ab, "failed to register PCI ops: %d\n", ret); 817 + goto err_pci_free_region; 818 + } 819 819 ab->id.bdf_search = ATH11K_BDF_SEARCH_BUS_AND_BOARD; 820 820 ath11k_pci_read_hw_version(ab, &soc_hw_version_major, 821 821 &soc_hw_version_minor); ··· 836 820 break; 837 821 case 0x10: 838 822 case 0x11: 839 - ab->hw_rev = ATH11K_HW_WCN6855_HW21; 823 + sub_version = ath11k_pcic_read32(ab, TCSR_SOC_HW_SUB_VER); 824 + ath11k_dbg(ab, ATH11K_DBG_PCI, "sub_version 0x%x\n", 825 + sub_version); 826 + switch (sub_version) { 827 + case 0x1019A0E1: 828 + case 0x1019B0E1: 829 + case 0x1019C0E1: 830 + case 0x1019D0E1: 831 + ab->hw_rev = ATH11K_HW_QCA2066_HW21; 832 + break; 833 + default: 834 + ab->hw_rev = ATH11K_HW_WCN6855_HW21; 835 + } 840 836 break; 841 837 default: 842 838 goto unsupported_wcn6855_soc; ··· 862 834 goto err_pci_free_region; 863 835 } 864 836 865 - pci_ops = &ath11k_pci_ops_qca6390; 866 837 break; 867 838 default: 868 839 dev_err(&pdev->dev, "Unknown PCI device found: 0x%x\n", 869 840 pci_dev->device); 870 841 ret = -EOPNOTSUPP; 871 - goto err_pci_free_region; 872 - } 873 - 874 - ret = ath11k_pcic_register_pci_ops(ab, pci_ops); 875 - if (ret) { 876 - ath11k_err(ab, "failed to register PCI ops: %d\n", ret); 877 842 goto err_pci_free_region; 878 843 } 879 844
+11
drivers/net/wireless/ath/ath11k/pcic.c
··· 115 115 }, 116 116 .hw_rev = ATH11K_HW_WCN6750_HW10, 117 117 }, 118 + { 119 + .total_vectors = 32, 120 + .total_users = 4, 121 + .users = (struct ath11k_msi_user[]) { 122 + { .name = "MHI", .num_vectors = 3, .base_vector = 0 }, 123 + { .name = "CE", .num_vectors = 10, .base_vector = 3 }, 124 + { .name = "WAKE", .num_vectors = 1, .base_vector = 13 }, 125 + { .name = "DP", .num_vectors = 18, .base_vector = 14 }, 126 + }, 127 + .hw_rev = ATH11K_HW_QCA2066_HW21, 128 + }, 118 129 }; 119 130 120 131 int ath11k_pcic_init_msi_config(struct ath11k_base *ab)
+1 -1
drivers/net/wireless/ath/ath11k/wmi.c
··· 2098 2098 WMI_SCAN_EVENT_BSS_CHANNEL | 2099 2099 WMI_SCAN_EVENT_FOREIGN_CHAN | 2100 2100 WMI_SCAN_EVENT_DEQUEUED; 2101 - arg->scan_flags |= WMI_SCAN_CHAN_STAT_EVENT; 2101 + arg->scan_f_chan_stat_evnt = 1; 2102 2102 2103 2103 if (test_bit(WMI_TLV_SERVICE_PASSIVE_SCAN_START_TIME_ENHANCE, 2104 2104 ar->ab->wmi_ab.svc_map))
+38 -48
drivers/net/wireless/ath/ath11k/wmi.h
··· 3363 3363 u32 vdev_id; 3364 3364 u32 pdev_id; 3365 3365 enum wmi_scan_priority scan_priority; 3366 - union { 3367 - struct { 3368 - u32 scan_ev_started:1, 3369 - scan_ev_completed:1, 3370 - scan_ev_bss_chan:1, 3371 - scan_ev_foreign_chan:1, 3372 - scan_ev_dequeued:1, 3373 - scan_ev_preempted:1, 3374 - scan_ev_start_failed:1, 3375 - scan_ev_restarted:1, 3376 - scan_ev_foreign_chn_exit:1, 3377 - scan_ev_invalid:1, 3378 - scan_ev_gpio_timeout:1, 3379 - scan_ev_suspended:1, 3380 - scan_ev_resumed:1; 3381 - }; 3382 - u32 scan_events; 3383 - }; 3366 + u32 scan_ev_started:1, 3367 + scan_ev_completed:1, 3368 + scan_ev_bss_chan:1, 3369 + scan_ev_foreign_chan:1, 3370 + scan_ev_dequeued:1, 3371 + scan_ev_preempted:1, 3372 + scan_ev_start_failed:1, 3373 + scan_ev_restarted:1, 3374 + scan_ev_foreign_chn_exit:1, 3375 + scan_ev_invalid:1, 3376 + scan_ev_gpio_timeout:1, 3377 + scan_ev_suspended:1, 3378 + scan_ev_resumed:1; 3384 3379 u32 scan_ctrl_flags_ext; 3385 3380 u32 dwell_time_active; 3386 3381 u32 dwell_time_active_2g; ··· 3389 3394 u32 idle_time; 3390 3395 u32 max_scan_time; 3391 3396 u32 probe_delay; 3392 - union { 3393 - struct { 3394 - u32 scan_f_passive:1, 3395 - scan_f_bcast_probe:1, 3396 - scan_f_cck_rates:1, 3397 - scan_f_ofdm_rates:1, 3398 - scan_f_chan_stat_evnt:1, 3399 - scan_f_filter_prb_req:1, 3400 - scan_f_bypass_dfs_chn:1, 3401 - scan_f_continue_on_err:1, 3402 - scan_f_offchan_mgmt_tx:1, 3403 - scan_f_offchan_data_tx:1, 3404 - scan_f_promisc_mode:1, 3405 - scan_f_capture_phy_err:1, 3406 - scan_f_strict_passive_pch:1, 3407 - scan_f_half_rate:1, 3408 - scan_f_quarter_rate:1, 3409 - scan_f_force_active_dfs_chn:1, 3410 - scan_f_add_tpc_ie_in_probe:1, 3411 - scan_f_add_ds_ie_in_probe:1, 3412 - scan_f_add_spoofed_mac_in_probe:1, 3413 - scan_f_add_rand_seq_in_probe:1, 3414 - scan_f_en_ie_whitelist_in_probe:1, 3415 - scan_f_forced:1, 3416 - scan_f_2ghz:1, 3417 - scan_f_5ghz:1, 3418 - scan_f_80mhz:1; 3419 - }; 3420 - u32 scan_flags; 3421 - }; 3397 + u32 scan_f_passive:1, 3398 + scan_f_bcast_probe:1, 3399 + scan_f_cck_rates:1, 3400 + scan_f_ofdm_rates:1, 3401 + scan_f_chan_stat_evnt:1, 3402 + scan_f_filter_prb_req:1, 3403 + scan_f_bypass_dfs_chn:1, 3404 + scan_f_continue_on_err:1, 3405 + scan_f_offchan_mgmt_tx:1, 3406 + scan_f_offchan_data_tx:1, 3407 + scan_f_promisc_mode:1, 3408 + scan_f_capture_phy_err:1, 3409 + scan_f_strict_passive_pch:1, 3410 + scan_f_half_rate:1, 3411 + scan_f_quarter_rate:1, 3412 + scan_f_force_active_dfs_chn:1, 3413 + scan_f_add_tpc_ie_in_probe:1, 3414 + scan_f_add_ds_ie_in_probe:1, 3415 + scan_f_add_spoofed_mac_in_probe:1, 3416 + scan_f_add_rand_seq_in_probe:1, 3417 + scan_f_en_ie_whitelist_in_probe:1, 3418 + scan_f_forced:1, 3419 + scan_f_2ghz:1, 3420 + scan_f_5ghz:1, 3421 + scan_f_80mhz:1; 3422 3422 enum scan_dwelltime_adaptive_mode adaptive_dwell_time_mode; 3423 3423 u32 burst_duration; 3424 3424 u32 num_chan;
+3 -1
drivers/net/wireless/ath/ath12k/Makefile
··· 19 19 hw.o \ 20 20 mhi.o \ 21 21 pci.o \ 22 - dp_mon.o 22 + dp_mon.o \ 23 + fw.o \ 24 + p2p.o 23 25 24 26 ath12k-$(CONFIG_ATH12K_TRACING) += trace.o 25 27
+49 -6
drivers/net/wireless/ath/ath12k/core.c
··· 14 14 #include "dp_rx.h" 15 15 #include "debug.h" 16 16 #include "hif.h" 17 + #include "fw.h" 17 18 18 19 unsigned int ath12k_debug_mask; 19 20 module_param_named(debug_mask, ath12k_debug_mask, uint, 0644); ··· 510 509 return ret; 511 510 } 512 511 512 + u32 ath12k_core_get_max_station_per_radio(struct ath12k_base *ab) 513 + { 514 + if (ab->num_radios == 2) 515 + return TARGET_NUM_STATIONS_DBS; 516 + else if (ab->num_radios == 3) 517 + return TARGET_NUM_PEERS_PDEV_DBS_SBS; 518 + return TARGET_NUM_STATIONS_SINGLE; 519 + } 520 + 521 + u32 ath12k_core_get_max_peers_per_radio(struct ath12k_base *ab) 522 + { 523 + if (ab->num_radios == 2) 524 + return TARGET_NUM_PEERS_PDEV_DBS; 525 + else if (ab->num_radios == 3) 526 + return TARGET_NUM_PEERS_PDEV_DBS_SBS; 527 + return TARGET_NUM_PEERS_PDEV_SINGLE; 528 + } 529 + 530 + u32 ath12k_core_get_max_num_tids(struct ath12k_base *ab) 531 + { 532 + if (ab->num_radios == 2) 533 + return TARGET_NUM_TIDS(DBS); 534 + else if (ab->num_radios == 3) 535 + return TARGET_NUM_TIDS(DBS_SBS); 536 + return TARGET_NUM_TIDS(SINGLE); 537 + } 538 + 513 539 static void ath12k_core_stop(struct ath12k_base *ab) 514 540 { 515 541 if (!test_bit(ATH12K_FLAG_CRASH_FLUSH, &ab->dev_flags)) ··· 748 720 goto err_mac_destroy; 749 721 } 750 722 723 + ath12k_dp_hal_rx_desc_init(ab); 724 + 751 725 ret = ath12k_wmi_cmd_init(ab); 752 726 if (ret) { 753 727 ath12k_err(ab, "failed to send wmi init cmd: %d\n", ret); ··· 909 879 { 910 880 struct ath12k_base *ab = container_of(work, struct ath12k_base, rfkill_work); 911 881 struct ath12k *ar; 882 + struct ath12k_hw *ah; 912 883 struct ieee80211_hw *hw; 913 884 bool rfkill_radio_on; 914 - int i; 885 + int i, j; 915 886 916 887 spin_lock_bh(&ab->base_lock); 917 888 rfkill_radio_on = ab->rfkill_radio_on; 918 889 spin_unlock_bh(&ab->base_lock); 919 890 920 - for (i = 0; i < ab->num_radios; i++) { 921 - ar = ab->pdevs[i].ar; 922 - if (!ar) 891 + for (i = 0; i < ab->num_hw; i++) { 892 + ah = ab->ah[i]; 893 + if (!ah) 923 894 continue; 924 895 925 - hw = ath12k_ar_to_hw(ar); 926 - ath12k_mac_rfkill_enable_radio(ar, rfkill_radio_on); 896 + for (j = 0; j < ah->num_radio; j++) { 897 + ar = &ah->radio[j]; 898 + if (!ar) 899 + continue; 900 + 901 + ath12k_mac_rfkill_enable_radio(ar, rfkill_radio_on); 902 + } 903 + 904 + hw = ah->hw; 927 905 wiphy_rfkill_set_hw_state(hw->wiphy, !rfkill_radio_on); 928 906 } 929 907 } ··· 988 950 ath12k_mac_drain_tx(ar); 989 951 complete(&ar->scan.started); 990 952 complete(&ar->scan.completed); 953 + complete(&ar->scan.on_channel); 991 954 complete(&ar->peer_assoc_done); 992 955 complete(&ar->peer_delete_done); 993 956 complete(&ar->install_key_done); ··· 1148 1109 return ret; 1149 1110 } 1150 1111 1112 + ath12k_fw_map(ab); 1113 + 1151 1114 return 0; 1152 1115 } 1153 1116 ··· 1178 1137 ath12k_hif_power_down(ab); 1179 1138 ath12k_mac_destroy(ab); 1180 1139 ath12k_core_soc_destroy(ab); 1140 + ath12k_fw_unmap(ab); 1181 1141 } 1182 1142 1183 1143 void ath12k_core_free(struct ath12k_base *ab) ··· 1227 1185 ab->dev = dev; 1228 1186 ab->hif.bus = bus; 1229 1187 ab->qmi.num_radios = U8_MAX; 1188 + ab->slo_capable = true; 1230 1189 1231 1190 return ab; 1232 1191
+27
drivers/net/wireless/ath/ath12k/core.h
··· 13 13 #include <linux/bitfield.h> 14 14 #include <linux/dmi.h> 15 15 #include <linux/ctype.h> 16 + #include <linux/firmware.h> 16 17 #include "qmi.h" 17 18 #include "htc.h" 18 19 #include "wmi.h" ··· 25 24 #include "hal_rx.h" 26 25 #include "reg.h" 27 26 #include "dbring.h" 27 + #include "fw.h" 28 28 29 29 #define SM(_v, _f) (((_v) << _f##_LSB) & _f##_MASK) 30 30 ··· 266 264 u8 tx_encap_type; 267 265 u8 vdev_stats_id; 268 266 u32 punct_bitmap; 267 + bool ps; 269 268 }; 270 269 271 270 struct ath12k_vif_iter { ··· 827 824 u32 subsystem_device; 828 825 } id; 829 826 827 + struct { 828 + u32 api_version; 829 + 830 + const struct firmware *fw; 831 + const u8 *amss_data; 832 + size_t amss_len; 833 + const u8 *amss_dualmac_data; 834 + size_t amss_dualmac_len; 835 + const u8 *m3_data; 836 + size_t m3_len; 837 + 838 + DECLARE_BITMAP(fw_features, ATH12K_FW_FEATURE_COUNT); 839 + } fw; 840 + 841 + const struct hal_rx_ops *hal_rx_ops; 842 + 843 + /* slo_capable denotes if the single/multi link operation 844 + * is supported within the same chip (SoC). 845 + */ 846 + bool slo_capable; 847 + 830 848 /* must be last */ 831 849 u8 drv_priv[] __aligned(sizeof(void *)); 832 850 }; ··· 879 855 880 856 const struct firmware *ath12k_core_firmware_request(struct ath12k_base *ab, 881 857 const char *filename); 858 + u32 ath12k_core_get_max_station_per_radio(struct ath12k_base *ab); 859 + u32 ath12k_core_get_max_peers_per_radio(struct ath12k_base *ab); 860 + u32 ath12k_core_get_max_num_tids(struct ath12k_base *ab); 882 861 883 862 static inline const char *ath12k_scan_state_str(enum ath12k_scan_state state) 884 863 {
+24 -1
drivers/net/wireless/ath/ath12k/dp.c
··· 1 1 // SPDX-License-Identifier: BSD-3-Clause-Clear 2 2 /* 3 3 * Copyright (c) 2018-2021 The Linux Foundation. All rights reserved. 4 - * Copyright (c) 2021-2023 Qualcomm Innovation Center, Inc. All rights reserved. 4 + * Copyright (c) 2021-2024 Qualcomm Innovation Center, Inc. All rights reserved. 5 5 */ 6 6 7 7 #include <crypto/hash.h> ··· 995 995 996 996 /* TODO: Add any RXDMA setup required per pdev */ 997 997 } 998 + } 999 + 1000 + bool ath12k_dp_wmask_compaction_rx_tlv_supported(struct ath12k_base *ab) 1001 + { 1002 + if (test_bit(WMI_TLV_SERVICE_WMSK_COMPACTION_RX_TLVS, ab->wmi_ab.svc_map) && 1003 + ab->hw_params->hal_ops->rxdma_ring_wmask_rx_mpdu_start && 1004 + ab->hw_params->hal_ops->rxdma_ring_wmask_rx_msdu_end && 1005 + ab->hw_params->hal_ops->get_hal_rx_compact_ops) { 1006 + return true; 1007 + } 1008 + return false; 1009 + } 1010 + 1011 + void ath12k_dp_hal_rx_desc_init(struct ath12k_base *ab) 1012 + { 1013 + if (ath12k_dp_wmask_compaction_rx_tlv_supported(ab)) { 1014 + /* RX TLVS compaction is supported, hence change the hal_rx_ops 1015 + * to compact hal_rx_ops. 1016 + */ 1017 + ab->hal_rx_ops = ab->hw_params->hal_ops->get_hal_rx_compact_ops(); 1018 + } 1019 + ab->hal.hal_desc_sz = 1020 + ab->hal_rx_ops->rx_desc_get_desc_size(); 998 1021 } 999 1022 1000 1023 static void ath12k_dp_service_mon_ring(struct timer_list *t)
+16 -1
drivers/net/wireless/ath/ath12k/dp.h
··· 1 1 /* SPDX-License-Identifier: BSD-3-Clause-Clear */ 2 2 /* 3 3 * Copyright (c) 2018-2021 The Linux Foundation. All rights reserved. 4 - * Copyright (c) 2021-2023 Qualcomm Innovation Center, Inc. All rights reserved. 4 + * Copyright (c) 2021-2024 Qualcomm Innovation Center, Inc. All rights reserved. 5 5 */ 6 6 7 7 #ifndef ATH12K_DP_H ··· 766 766 #define HTT_RX_RING_SELECTION_CFG_RX_MSDU_START_OFFSET GENMASK(31, 16) 767 767 #define HTT_RX_RING_SELECTION_CFG_RX_ATTENTION_OFFSET GENMASK(15, 0) 768 768 769 + #define HTT_RX_RING_SELECTION_CFG_WORD_MASK_COMPACT_SET BIT(23) 770 + #define HTT_RX_RING_SELECTION_CFG_RX_MPDU_START_MASK GENMASK(15, 0) 771 + #define HTT_RX_RING_SELECTION_CFG_RX_MPDU_END_MASK GENMASK(18, 16) 772 + #define HTT_RX_RING_SELECTION_CFG_RX_MSDU_END_MASK GENMASK(16, 0) 773 + 769 774 enum htt_rx_filter_tlv_flags { 770 775 HTT_RX_FILTER_TLV_FLAGS_MPDU_START = BIT(0), 771 776 HTT_RX_FILTER_TLV_FLAGS_MSDU_START = BIT(1), ··· 1094 1089 __le32 rx_mpdu_offset; 1095 1090 __le32 rx_msdu_offset; 1096 1091 __le32 rx_attn_offset; 1092 + __le32 info2; 1093 + __le32 reserved[2]; 1094 + __le32 rx_mpdu_start_end_mask; 1095 + __le32 rx_msdu_end_word_mask; 1096 + __le32 info3; 1097 1097 } __packed; 1098 1098 1099 1099 struct htt_rx_ring_tlv_filter { ··· 1115 1105 u16 rx_msdu_end_offset; 1116 1106 u16 rx_msdu_start_offset; 1117 1107 u16 rx_attn_offset; 1108 + u16 rx_mpdu_start_wmask; 1109 + u16 rx_mpdu_end_wmask; 1110 + u32 rx_msdu_end_wmask; 1118 1111 }; 1119 1112 1120 1113 #define HTT_STATS_FRAME_CTRL_TYPE_MGMT 0x0 ··· 1834 1821 u32 cookie); 1835 1822 struct ath12k_tx_desc_info *ath12k_dp_get_tx_desc(struct ath12k_base *ab, 1836 1823 u32 desc_id); 1824 + bool ath12k_dp_wmask_compaction_rx_tlv_supported(struct ath12k_base *ab); 1825 + void ath12k_dp_hal_rx_desc_init(struct ath12k_base *ab); 1837 1826 #endif
+3 -2
drivers/net/wireless/ath/ath12k/dp_mon.c
··· 864 864 { 865 865 u32 rx_pkt_offset, l2_hdr_offset; 866 866 867 - rx_pkt_offset = ar->ab->hw_params->hal_desc_sz; 867 + rx_pkt_offset = ar->ab->hal.hal_desc_sz; 868 868 l2_hdr_offset = ath12k_dp_rx_h_l3pad(ar->ab, 869 869 (struct hal_rx_desc *)msdu->data); 870 870 skb_pull(msdu, rx_pkt_offset + l2_hdr_offset); ··· 917 917 u8 qos_pkt = 0; 918 918 919 919 rx_desc = (struct hal_rx_desc *)head_msdu->data; 920 - hdr_desc = ab->hw_params->hal_ops->rx_desc_get_msdu_payload(rx_desc); 920 + hdr_desc = 921 + ab->hal_rx_ops->rx_desc_get_msdu_payload(rx_desc); 921 922 922 923 /* Base size */ 923 924 wh = (struct ieee80211_hdr_3addr *)hdr_desc;
+83 -75
drivers/net/wireless/ath/ath12k/dp_rx.c
··· 23 23 static enum hal_encrypt_type ath12k_dp_rx_h_enctype(struct ath12k_base *ab, 24 24 struct hal_rx_desc *desc) 25 25 { 26 - if (!ab->hw_params->hal_ops->rx_desc_encrypt_valid(desc)) 26 + if (!ab->hal_rx_ops->rx_desc_encrypt_valid(desc)) 27 27 return HAL_ENCRYPT_TYPE_OPEN; 28 28 29 - return ab->hw_params->hal_ops->rx_desc_get_encrypt_type(desc); 29 + return ab->hal_rx_ops->rx_desc_get_encrypt_type(desc); 30 30 } 31 31 32 32 u8 ath12k_dp_rx_h_decap_type(struct ath12k_base *ab, 33 33 struct hal_rx_desc *desc) 34 34 { 35 - return ab->hw_params->hal_ops->rx_desc_get_decap_type(desc); 35 + return ab->hal_rx_ops->rx_desc_get_decap_type(desc); 36 36 } 37 37 38 38 static u8 ath12k_dp_rx_h_mesh_ctl_present(struct ath12k_base *ab, 39 39 struct hal_rx_desc *desc) 40 40 { 41 - return ab->hw_params->hal_ops->rx_desc_get_mesh_ctl(desc); 41 + return ab->hal_rx_ops->rx_desc_get_mesh_ctl(desc); 42 42 } 43 43 44 44 static bool ath12k_dp_rx_h_seq_ctrl_valid(struct ath12k_base *ab, 45 45 struct hal_rx_desc *desc) 46 46 { 47 - return ab->hw_params->hal_ops->rx_desc_get_mpdu_seq_ctl_vld(desc); 47 + return ab->hal_rx_ops->rx_desc_get_mpdu_seq_ctl_vld(desc); 48 48 } 49 49 50 50 static bool ath12k_dp_rx_h_fc_valid(struct ath12k_base *ab, 51 51 struct hal_rx_desc *desc) 52 52 { 53 - return ab->hw_params->hal_ops->rx_desc_get_mpdu_fc_valid(desc); 53 + return ab->hal_rx_ops->rx_desc_get_mpdu_fc_valid(desc); 54 54 } 55 55 56 56 static bool ath12k_dp_rx_h_more_frags(struct ath12k_base *ab, ··· 58 58 { 59 59 struct ieee80211_hdr *hdr; 60 60 61 - hdr = (struct ieee80211_hdr *)(skb->data + ab->hw_params->hal_desc_sz); 61 + hdr = (struct ieee80211_hdr *)(skb->data + ab->hal.hal_desc_sz); 62 62 return ieee80211_has_morefrags(hdr->frame_control); 63 63 } 64 64 ··· 67 67 { 68 68 struct ieee80211_hdr *hdr; 69 69 70 - hdr = (struct ieee80211_hdr *)(skb->data + ab->hw_params->hal_desc_sz); 70 + hdr = (struct ieee80211_hdr *)(skb->data + ab->hal.hal_desc_sz); 71 71 return le16_to_cpu(hdr->seq_ctrl) & IEEE80211_SCTL_FRAG; 72 72 } 73 73 74 74 static u16 ath12k_dp_rx_h_seq_no(struct ath12k_base *ab, 75 75 struct hal_rx_desc *desc) 76 76 { 77 - return ab->hw_params->hal_ops->rx_desc_get_mpdu_start_seq_no(desc); 77 + return ab->hal_rx_ops->rx_desc_get_mpdu_start_seq_no(desc); 78 78 } 79 79 80 80 static bool ath12k_dp_rx_h_msdu_done(struct ath12k_base *ab, 81 81 struct hal_rx_desc *desc) 82 82 { 83 - return ab->hw_params->hal_ops->dp_rx_h_msdu_done(desc); 83 + return ab->hal_rx_ops->dp_rx_h_msdu_done(desc); 84 84 } 85 85 86 86 static bool ath12k_dp_rx_h_l4_cksum_fail(struct ath12k_base *ab, 87 87 struct hal_rx_desc *desc) 88 88 { 89 - return ab->hw_params->hal_ops->dp_rx_h_l4_cksum_fail(desc); 89 + return ab->hal_rx_ops->dp_rx_h_l4_cksum_fail(desc); 90 90 } 91 91 92 92 static bool ath12k_dp_rx_h_ip_cksum_fail(struct ath12k_base *ab, 93 93 struct hal_rx_desc *desc) 94 94 { 95 - return ab->hw_params->hal_ops->dp_rx_h_ip_cksum_fail(desc); 95 + return ab->hal_rx_ops->dp_rx_h_ip_cksum_fail(desc); 96 96 } 97 97 98 98 static bool ath12k_dp_rx_h_is_decrypted(struct ath12k_base *ab, 99 99 struct hal_rx_desc *desc) 100 100 { 101 - return ab->hw_params->hal_ops->dp_rx_h_is_decrypted(desc); 101 + return ab->hal_rx_ops->dp_rx_h_is_decrypted(desc); 102 102 } 103 103 104 104 u32 ath12k_dp_rx_h_mpdu_err(struct ath12k_base *ab, 105 105 struct hal_rx_desc *desc) 106 106 { 107 - return ab->hw_params->hal_ops->dp_rx_h_mpdu_err(desc); 107 + return ab->hal_rx_ops->dp_rx_h_mpdu_err(desc); 108 108 } 109 109 110 110 static u16 ath12k_dp_rx_h_msdu_len(struct ath12k_base *ab, 111 111 struct hal_rx_desc *desc) 112 112 { 113 - return ab->hw_params->hal_ops->rx_desc_get_msdu_len(desc); 113 + return ab->hal_rx_ops->rx_desc_get_msdu_len(desc); 114 114 } 115 115 116 116 static u8 ath12k_dp_rx_h_sgi(struct ath12k_base *ab, 117 117 struct hal_rx_desc *desc) 118 118 { 119 - return ab->hw_params->hal_ops->rx_desc_get_msdu_sgi(desc); 119 + return ab->hal_rx_ops->rx_desc_get_msdu_sgi(desc); 120 120 } 121 121 122 122 static u8 ath12k_dp_rx_h_rate_mcs(struct ath12k_base *ab, 123 123 struct hal_rx_desc *desc) 124 124 { 125 - return ab->hw_params->hal_ops->rx_desc_get_msdu_rate_mcs(desc); 125 + return ab->hal_rx_ops->rx_desc_get_msdu_rate_mcs(desc); 126 126 } 127 127 128 128 static u8 ath12k_dp_rx_h_rx_bw(struct ath12k_base *ab, 129 129 struct hal_rx_desc *desc) 130 130 { 131 - return ab->hw_params->hal_ops->rx_desc_get_msdu_rx_bw(desc); 131 + return ab->hal_rx_ops->rx_desc_get_msdu_rx_bw(desc); 132 132 } 133 133 134 134 static u32 ath12k_dp_rx_h_freq(struct ath12k_base *ab, 135 135 struct hal_rx_desc *desc) 136 136 { 137 - return ab->hw_params->hal_ops->rx_desc_get_msdu_freq(desc); 137 + return ab->hal_rx_ops->rx_desc_get_msdu_freq(desc); 138 138 } 139 139 140 140 static u8 ath12k_dp_rx_h_pkt_type(struct ath12k_base *ab, 141 141 struct hal_rx_desc *desc) 142 142 { 143 - return ab->hw_params->hal_ops->rx_desc_get_msdu_pkt_type(desc); 143 + return ab->hal_rx_ops->rx_desc_get_msdu_pkt_type(desc); 144 144 } 145 145 146 146 static u8 ath12k_dp_rx_h_nss(struct ath12k_base *ab, 147 147 struct hal_rx_desc *desc) 148 148 { 149 - return hweight8(ab->hw_params->hal_ops->rx_desc_get_msdu_nss(desc)); 149 + return hweight8(ab->hal_rx_ops->rx_desc_get_msdu_nss(desc)); 150 150 } 151 151 152 152 static u8 ath12k_dp_rx_h_tid(struct ath12k_base *ab, 153 153 struct hal_rx_desc *desc) 154 154 { 155 - return ab->hw_params->hal_ops->rx_desc_get_mpdu_tid(desc); 155 + return ab->hal_rx_ops->rx_desc_get_mpdu_tid(desc); 156 156 } 157 157 158 158 static u16 ath12k_dp_rx_h_peer_id(struct ath12k_base *ab, 159 159 struct hal_rx_desc *desc) 160 160 { 161 - return ab->hw_params->hal_ops->rx_desc_get_mpdu_peer_id(desc); 161 + return ab->hal_rx_ops->rx_desc_get_mpdu_peer_id(desc); 162 162 } 163 163 164 164 u8 ath12k_dp_rx_h_l3pad(struct ath12k_base *ab, 165 165 struct hal_rx_desc *desc) 166 166 { 167 - return ab->hw_params->hal_ops->rx_desc_get_l3_pad_bytes(desc); 167 + return ab->hal_rx_ops->rx_desc_get_l3_pad_bytes(desc); 168 168 } 169 169 170 170 static bool ath12k_dp_rx_h_first_msdu(struct ath12k_base *ab, 171 171 struct hal_rx_desc *desc) 172 172 { 173 - return ab->hw_params->hal_ops->rx_desc_get_first_msdu(desc); 173 + return ab->hal_rx_ops->rx_desc_get_first_msdu(desc); 174 174 } 175 175 176 176 static bool ath12k_dp_rx_h_last_msdu(struct ath12k_base *ab, 177 177 struct hal_rx_desc *desc) 178 178 { 179 - return ab->hw_params->hal_ops->rx_desc_get_last_msdu(desc); 179 + return ab->hal_rx_ops->rx_desc_get_last_msdu(desc); 180 180 } 181 181 182 182 static void ath12k_dp_rx_desc_end_tlv_copy(struct ath12k_base *ab, 183 183 struct hal_rx_desc *fdesc, 184 184 struct hal_rx_desc *ldesc) 185 185 { 186 - ab->hw_params->hal_ops->rx_desc_copy_end_tlv(fdesc, ldesc); 186 + ab->hal_rx_ops->rx_desc_copy_end_tlv(fdesc, ldesc); 187 187 } 188 188 189 189 static void ath12k_dp_rxdesc_set_msdu_len(struct ath12k_base *ab, 190 190 struct hal_rx_desc *desc, 191 191 u16 len) 192 192 { 193 - ab->hw_params->hal_ops->rx_desc_set_msdu_len(desc, len); 193 + ab->hal_rx_ops->rx_desc_set_msdu_len(desc, len); 194 194 } 195 195 196 196 static bool ath12k_dp_rx_h_is_da_mcbc(struct ath12k_base *ab, 197 197 struct hal_rx_desc *desc) 198 198 { 199 199 return (ath12k_dp_rx_h_first_msdu(ab, desc) && 200 - ab->hw_params->hal_ops->rx_desc_is_da_mcbc(desc)); 200 + ab->hal_rx_ops->rx_desc_is_da_mcbc(desc)); 201 201 } 202 202 203 203 static bool ath12k_dp_rxdesc_mac_addr2_valid(struct ath12k_base *ab, 204 204 struct hal_rx_desc *desc) 205 205 { 206 - return ab->hw_params->hal_ops->rx_desc_mac_addr2_valid(desc); 206 + return ab->hal_rx_ops->rx_desc_mac_addr2_valid(desc); 207 207 } 208 208 209 209 static u8 *ath12k_dp_rxdesc_get_mpdu_start_addr2(struct ath12k_base *ab, 210 210 struct hal_rx_desc *desc) 211 211 { 212 - return ab->hw_params->hal_ops->rx_desc_mpdu_start_addr2(desc); 212 + return ab->hal_rx_ops->rx_desc_mpdu_start_addr2(desc); 213 213 } 214 214 215 215 static void ath12k_dp_rx_desc_get_dot11_hdr(struct ath12k_base *ab, 216 216 struct hal_rx_desc *desc, 217 217 struct ieee80211_hdr *hdr) 218 218 { 219 - ab->hw_params->hal_ops->rx_desc_get_dot11_hdr(desc, hdr); 219 + ab->hal_rx_ops->rx_desc_get_dot11_hdr(desc, hdr); 220 220 } 221 221 222 222 static void ath12k_dp_rx_desc_get_crypto_header(struct ath12k_base *ab, ··· 224 224 u8 *crypto_hdr, 225 225 enum hal_encrypt_type enctype) 226 226 { 227 - ab->hw_params->hal_ops->rx_desc_get_crypto_header(desc, crypto_hdr, enctype); 227 + ab->hal_rx_ops->rx_desc_get_crypto_header(desc, crypto_hdr, enctype); 228 228 } 229 229 230 230 static u16 ath12k_dp_rxdesc_get_mpdu_frame_ctrl(struct ath12k_base *ab, 231 231 struct hal_rx_desc *desc) 232 232 { 233 - return ab->hw_params->hal_ops->rx_desc_get_mpdu_frame_ctl(desc); 233 + return ab->hal_rx_ops->rx_desc_get_mpdu_frame_ctl(desc); 234 + } 235 + 236 + static inline u8 ath12k_dp_rx_get_msdu_src_link(struct ath12k_base *ab, 237 + struct hal_rx_desc *desc) 238 + { 239 + return ab->hal_rx_ops->rx_desc_get_msdu_src_link_id(desc); 234 240 } 235 241 236 242 static int ath12k_dp_purge_mon_ring(struct ath12k_base *ab) ··· 1767 1761 int buf_first_hdr_len, buf_first_len; 1768 1762 struct hal_rx_desc *ldesc; 1769 1763 int space_extra, rem_len, buf_len; 1770 - u32 hal_rx_desc_sz = ar->ab->hw_params->hal_desc_sz; 1764 + u32 hal_rx_desc_sz = ar->ab->hal.hal_desc_sz; 1771 1765 1772 1766 /* As the msdu is spread across multiple rx buffers, 1773 1767 * find the offset to the start of msdu for computing ··· 2479 2473 u8 l3_pad_bytes; 2480 2474 u16 msdu_len; 2481 2475 int ret; 2482 - u32 hal_rx_desc_sz = ar->ab->hw_params->hal_desc_sz; 2476 + u32 hal_rx_desc_sz = ar->ab->hal.hal_desc_sz; 2483 2477 2484 2478 last_buf = ath12k_dp_rx_get_msdu_last_buf(msdu_list, msdu); 2485 2479 if (!last_buf) { ··· 2810 2804 u8 mic[IEEE80211_CCMP_MIC_LEN]; 2811 2805 int head_len, tail_len, ret; 2812 2806 size_t data_len; 2813 - u32 hdr_len, hal_rx_desc_sz = ar->ab->hw_params->hal_desc_sz; 2807 + u32 hdr_len, hal_rx_desc_sz = ar->ab->hal.hal_desc_sz; 2814 2808 u8 *key, *data; 2815 2809 u8 key_idx; 2816 2810 ··· 2860 2854 struct ieee80211_hdr *hdr; 2861 2855 size_t hdr_len; 2862 2856 size_t crypto_len; 2863 - u32 hal_rx_desc_sz = ar->ab->hw_params->hal_desc_sz; 2857 + u32 hal_rx_desc_sz = ar->ab->hal.hal_desc_sz; 2864 2858 2865 2859 if (!flags) 2866 2860 return; ··· 2898 2892 bool is_decrypted = false; 2899 2893 int msdu_len = 0; 2900 2894 int extra_space; 2901 - u32 flags, hal_rx_desc_sz = ar->ab->hw_params->hal_desc_sz; 2895 + u32 flags, hal_rx_desc_sz = ar->ab->hal.hal_desc_sz; 2902 2896 2903 2897 first_frag = skb_peek(&rx_tid->rx_frags); 2904 2898 last_frag = skb_peek_tail(&rx_tid->rx_frags); ··· 2974 2968 struct ath12k_rx_desc_info *desc_info; 2975 2969 u8 dst_ind; 2976 2970 2977 - hal_rx_desc_sz = ab->hw_params->hal_desc_sz; 2971 + hal_rx_desc_sz = ab->hal.hal_desc_sz; 2978 2972 link_desc_banks = dp->link_desc_banks; 2979 2973 reo_dest_ring = rx_tid->dst_ring_desc; 2980 2974 ··· 3128 3122 struct ieee80211_hdr *hdr; 3129 3123 u64 pn = 0; 3130 3124 u8 *ehdr; 3131 - u32 hal_rx_desc_sz = ar->ab->hw_params->hal_desc_sz; 3125 + u32 hal_rx_desc_sz = ar->ab->hal.hal_desc_sz; 3132 3126 3133 3127 hdr = (struct ieee80211_hdr *)(skb->data + hal_rx_desc_sz); 3134 3128 ehdr = skb->data + hal_rx_desc_sz + ieee80211_hdrlen(hdr->frame_control); ··· 3311 3305 struct ath12k_skb_rxcb *rxcb; 3312 3306 struct hal_rx_desc *rx_desc; 3313 3307 u16 msdu_len; 3314 - u32 hal_rx_desc_sz = ab->hw_params->hal_desc_sz; 3308 + u32 hal_rx_desc_sz = ab->hal.hal_desc_sz; 3315 3309 struct ath12k_rx_desc_info *desc_info; 3316 3310 u64 desc_va; 3317 3311 ··· 3492 3486 int n_buffs; 3493 3487 3494 3488 n_buffs = DIV_ROUND_UP(msdu_len, 3495 - (DP_RX_BUFFER_SIZE - ar->ab->hw_params->hal_desc_sz)); 3489 + (DP_RX_BUFFER_SIZE - ar->ab->hal.hal_desc_sz)); 3496 3490 3497 3491 skb_queue_walk_safe(msdu_list, skb, tmp) { 3498 3492 rxcb = ATH12K_SKB_RXCB(skb); ··· 3516 3510 struct hal_rx_desc *desc = (struct hal_rx_desc *)msdu->data; 3517 3511 u8 l3pad_bytes; 3518 3512 struct ath12k_skb_rxcb *rxcb = ATH12K_SKB_RXCB(msdu); 3519 - u32 hal_rx_desc_sz = ar->ab->hw_params->hal_desc_sz; 3513 + u32 hal_rx_desc_sz = ar->ab->hal.hal_desc_sz; 3520 3514 3521 3515 msdu_len = ath12k_dp_rx_h_msdu_len(ab, desc); 3522 3516 ··· 3613 3607 struct hal_rx_desc *desc = (struct hal_rx_desc *)msdu->data; 3614 3608 u8 l3pad_bytes; 3615 3609 struct ath12k_skb_rxcb *rxcb = ATH12K_SKB_RXCB(msdu); 3616 - u32 hal_rx_desc_sz = ar->ab->hw_params->hal_desc_sz; 3610 + u32 hal_rx_desc_sz = ar->ab->hal.hal_desc_sz; 3617 3611 3618 3612 rxcb->is_first_msdu = ath12k_dp_rx_h_first_msdu(ab, desc); 3619 3613 rxcb->is_last_msdu = ath12k_dp_rx_h_last_msdu(ab, desc); ··· 3701 3695 struct hal_rx_wbm_rel_info err_info; 3702 3696 struct hal_srng *srng; 3703 3697 struct sk_buff *msdu; 3704 - struct sk_buff_head msdu_list[MAX_RADIOS]; 3698 + struct sk_buff_head msdu_list; 3705 3699 struct ath12k_skb_rxcb *rxcb; 3706 3700 void *rx_desc; 3707 - int mac_id; 3701 + u8 mac_id; 3708 3702 int num_buffs_reaped = 0; 3709 3703 struct ath12k_rx_desc_info *desc_info; 3710 - int ret, i; 3704 + int ret, pdev_id; 3711 3705 3712 - for (i = 0; i < ab->num_radios; i++) 3713 - __skb_queue_head_init(&msdu_list[i]); 3706 + __skb_queue_head_init(&msdu_list); 3714 3707 3715 3708 srng = &ab->hal.srng_list[dp->rx_rel_ring.ring_id]; 3716 3709 rx_ring = &dp->rx_refill_buf_ring; ··· 3742 3737 } 3743 3738 } 3744 3739 3745 - /* FIXME: Extract mac id correctly. Since descs are not tied 3746 - * to mac, we can extract from vdev id in ring desc. 3747 - */ 3748 - mac_id = 0; 3749 - 3750 3740 if (desc_info->magic != ATH12K_DP_RX_DESC_MAGIC) 3751 3741 ath12k_warn(ab, "WBM RX err, Check HW CC implementation"); 3752 3742 ··· 3771 3771 rxcb->err_rel_src = err_info.err_rel_src; 3772 3772 rxcb->err_code = err_info.err_code; 3773 3773 rxcb->rx_desc = (struct hal_rx_desc *)msdu->data; 3774 - __skb_queue_tail(&msdu_list[mac_id], msdu); 3774 + 3775 + __skb_queue_tail(&msdu_list, msdu); 3775 3776 3776 3777 rxcb->is_first_msdu = err_info.first_msdu; 3777 3778 rxcb->is_last_msdu = err_info.last_msdu; ··· 3789 3788 ath12k_dp_rx_bufs_replenish(ab, rx_ring, num_buffs_reaped); 3790 3789 3791 3790 rcu_read_lock(); 3792 - for (i = 0; i < ab->num_radios; i++) { 3793 - if (!rcu_dereference(ab->pdevs_active[i])) { 3794 - __skb_queue_purge(&msdu_list[i]); 3791 + while ((msdu = __skb_dequeue(&msdu_list))) { 3792 + mac_id = ath12k_dp_rx_get_msdu_src_link(ab, 3793 + (struct hal_rx_desc *)msdu->data); 3794 + pdev_id = ath12k_hw_mac_id_to_pdev_id(ab->hw_params, mac_id); 3795 + ar = ab->pdevs[pdev_id].ar; 3796 + 3797 + if (!ar || !rcu_dereference(ar->ab->pdevs_active[mac_id])) { 3798 + dev_kfree_skb_any(msdu); 3795 3799 continue; 3796 3800 } 3797 - 3798 - ar = ab->pdevs[i].ar; 3799 3801 3800 3802 if (test_bit(ATH12K_CAC_RUNNING, &ar->dev_flags)) { 3801 - __skb_queue_purge(&msdu_list[i]); 3803 + dev_kfree_skb_any(msdu); 3802 3804 continue; 3803 3805 } 3804 - 3805 - while ((msdu = __skb_dequeue(&msdu_list[i])) != NULL) 3806 - ath12k_dp_rx_wbm_err(ar, napi, msdu, &msdu_list[i]); 3806 + ath12k_dp_rx_wbm_err(ar, napi, msdu, &msdu_list); 3807 3807 } 3808 3808 rcu_read_unlock(); 3809 3809 done: ··· 3924 3922 struct htt_rx_ring_tlv_filter tlv_filter = {0}; 3925 3923 u32 ring_id; 3926 3924 int ret; 3927 - u32 hal_rx_desc_sz = ab->hw_params->hal_desc_sz; 3925 + u32 hal_rx_desc_sz = ab->hal.hal_desc_sz; 3928 3926 3929 3927 ring_id = dp->rx_refill_buf_ring.refill_buf_ring.ring_id; 3930 3928 ··· 3937 3935 tlv_filter.rx_packet_offset = hal_rx_desc_sz; 3938 3936 3939 3937 tlv_filter.rx_mpdu_start_offset = 3940 - ab->hw_params->hal_ops->rx_desc_get_mpdu_start_offset(); 3938 + ab->hal_rx_ops->rx_desc_get_mpdu_start_offset(); 3941 3939 tlv_filter.rx_msdu_end_offset = 3942 - ab->hw_params->hal_ops->rx_desc_get_msdu_end_offset(); 3940 + ab->hal_rx_ops->rx_desc_get_msdu_end_offset(); 3943 3941 3944 - /* TODO: Selectively subscribe to required qwords within msdu_end 3945 - * and mpdu_start and setup the mask in below msg 3946 - * and modify the rx_desc struct 3947 - */ 3942 + if (ath12k_dp_wmask_compaction_rx_tlv_supported(ab)) { 3943 + tlv_filter.rx_mpdu_start_wmask = 3944 + ab->hw_params->hal_ops->rxdma_ring_wmask_rx_mpdu_start(); 3945 + tlv_filter.rx_msdu_end_wmask = 3946 + ab->hw_params->hal_ops->rxdma_ring_wmask_rx_msdu_end(); 3947 + ath12k_dbg(ab, ATH12K_DBG_DATA, 3948 + "Configuring compact tlv masks rx_mpdu_start_wmask 0x%x rx_msdu_end_wmask 0x%x\n", 3949 + tlv_filter.rx_mpdu_start_wmask, tlv_filter.rx_msdu_end_wmask); 3950 + } 3951 + 3948 3952 ret = ath12k_dp_tx_htt_rx_filter_setup(ab, ring_id, 0, 3949 3953 HAL_RXDMA_BUF, 3950 3954 DP_RXDMA_REFILL_RING_SIZE, ··· 3965 3957 struct htt_rx_ring_tlv_filter tlv_filter = {0}; 3966 3958 u32 ring_id; 3967 3959 int ret; 3968 - u32 hal_rx_desc_sz = ab->hw_params->hal_desc_sz; 3960 + u32 hal_rx_desc_sz = ab->hal.hal_desc_sz; 3969 3961 int i; 3970 3962 3971 3963 ring_id = dp->rx_refill_buf_ring.refill_buf_ring.ring_id; ··· 3981 3973 tlv_filter.rx_header_offset = offsetof(struct hal_rx_desc_wcn7850, pkt_hdr_tlv); 3982 3974 3983 3975 tlv_filter.rx_mpdu_start_offset = 3984 - ab->hw_params->hal_ops->rx_desc_get_mpdu_start_offset(); 3976 + ab->hal_rx_ops->rx_desc_get_mpdu_start_offset(); 3985 3977 tlv_filter.rx_msdu_end_offset = 3986 - ab->hw_params->hal_ops->rx_desc_get_msdu_end_offset(); 3978 + ab->hal_rx_ops->rx_desc_get_msdu_end_offset(); 3987 3979 3988 3980 /* TODO: Selectively subscribe to required qwords within msdu_end 3989 3981 * and mpdu_start and setup the mask in below msg
+20
drivers/net/wireless/ath/ath12k/dp_tx.c
··· 964 964 HTT_RX_RING_SELECTION_CFG_RX_ATTENTION_OFFSET); 965 965 } 966 966 967 + if (tlv_filter->rx_mpdu_start_wmask > 0 && 968 + tlv_filter->rx_msdu_end_wmask > 0) { 969 + cmd->info2 |= 970 + le32_encode_bits(true, 971 + HTT_RX_RING_SELECTION_CFG_WORD_MASK_COMPACT_SET); 972 + cmd->rx_mpdu_start_end_mask = 973 + le32_encode_bits(tlv_filter->rx_mpdu_start_wmask, 974 + HTT_RX_RING_SELECTION_CFG_RX_MPDU_START_MASK); 975 + /* mpdu_end is not used for any hardwares so far 976 + * please assign it in future if any chip is 977 + * using through hal ops 978 + */ 979 + cmd->rx_mpdu_start_end_mask |= 980 + le32_encode_bits(tlv_filter->rx_mpdu_end_wmask, 981 + HTT_RX_RING_SELECTION_CFG_RX_MPDU_END_MASK); 982 + cmd->rx_msdu_end_word_mask = 983 + le32_encode_bits(tlv_filter->rx_msdu_end_wmask, 984 + HTT_RX_RING_SELECTION_CFG_RX_MSDU_END_MASK); 985 + } 986 + 967 987 ret = ath12k_htc_send(&ab->htc, ab->dp.eid, skb); 968 988 if (ret) 969 989 goto err_free;
+171
drivers/net/wireless/ath/ath12k/fw.c
··· 1 + // SPDX-License-Identifier: BSD-3-Clause-Clear 2 + /* 3 + * Copyright (c) 2022-2024 Qualcomm Innovation Center, Inc. All rights reserved. 4 + */ 5 + 6 + #include "core.h" 7 + 8 + #include "debug.h" 9 + 10 + static int ath12k_fw_request_firmware_api_n(struct ath12k_base *ab, 11 + const char *name) 12 + { 13 + size_t magic_len, len, ie_len; 14 + int ie_id, i, index, bit, ret; 15 + struct ath12k_fw_ie *hdr; 16 + const u8 *data; 17 + __le32 *timestamp; 18 + 19 + ab->fw.fw = ath12k_core_firmware_request(ab, name); 20 + if (IS_ERR(ab->fw.fw)) { 21 + ret = PTR_ERR(ab->fw.fw); 22 + ath12k_dbg(ab, ATH12K_DBG_BOOT, "failed to load %s: %d\n", name, ret); 23 + ab->fw.fw = NULL; 24 + return ret; 25 + } 26 + 27 + data = ab->fw.fw->data; 28 + len = ab->fw.fw->size; 29 + 30 + /* magic also includes the null byte, check that as well */ 31 + magic_len = strlen(ATH12K_FIRMWARE_MAGIC) + 1; 32 + 33 + if (len < magic_len) { 34 + ath12k_err(ab, "firmware image too small to contain magic: %zu\n", 35 + len); 36 + ret = -EINVAL; 37 + goto err; 38 + } 39 + 40 + if (memcmp(data, ATH12K_FIRMWARE_MAGIC, magic_len) != 0) { 41 + ath12k_err(ab, "Invalid firmware magic\n"); 42 + ret = -EINVAL; 43 + goto err; 44 + } 45 + 46 + /* jump over the padding */ 47 + magic_len = ALIGN(magic_len, 4); 48 + 49 + /* make sure there's space for padding */ 50 + if (magic_len > len) { 51 + ath12k_err(ab, "No space for padding after magic\n"); 52 + ret = -EINVAL; 53 + goto err; 54 + } 55 + 56 + len -= magic_len; 57 + data += magic_len; 58 + 59 + /* loop elements */ 60 + while (len > sizeof(struct ath12k_fw_ie)) { 61 + hdr = (struct ath12k_fw_ie *)data; 62 + 63 + ie_id = le32_to_cpu(hdr->id); 64 + ie_len = le32_to_cpu(hdr->len); 65 + 66 + len -= sizeof(*hdr); 67 + data += sizeof(*hdr); 68 + 69 + if (len < ie_len) { 70 + ath12k_err(ab, "Invalid length for FW IE %d (%zu < %zu)\n", 71 + ie_id, len, ie_len); 72 + ret = -EINVAL; 73 + goto err; 74 + } 75 + 76 + switch (ie_id) { 77 + case ATH12K_FW_IE_TIMESTAMP: 78 + if (ie_len != sizeof(u32)) 79 + break; 80 + 81 + timestamp = (__le32 *)data; 82 + 83 + ath12k_dbg(ab, ATH12K_DBG_BOOT, "found fw timestamp %d\n", 84 + le32_to_cpup(timestamp)); 85 + break; 86 + case ATH12K_FW_IE_FEATURES: 87 + ath12k_dbg(ab, ATH12K_DBG_BOOT, 88 + "found firmware features ie (%zd B)\n", 89 + ie_len); 90 + 91 + for (i = 0; i < ATH12K_FW_FEATURE_COUNT; i++) { 92 + index = i / 8; 93 + bit = i % 8; 94 + 95 + if (index == ie_len) 96 + break; 97 + 98 + if (data[index] & (1 << bit)) 99 + __set_bit(i, ab->fw.fw_features); 100 + } 101 + 102 + ath12k_dbg_dump(ab, ATH12K_DBG_BOOT, "features", "", 103 + ab->fw.fw_features, 104 + sizeof(ab->fw.fw_features)); 105 + break; 106 + case ATH12K_FW_IE_AMSS_IMAGE: 107 + ath12k_dbg(ab, ATH12K_DBG_BOOT, 108 + "found fw image ie (%zd B)\n", 109 + ie_len); 110 + 111 + ab->fw.amss_data = data; 112 + ab->fw.amss_len = ie_len; 113 + break; 114 + case ATH12K_FW_IE_M3_IMAGE: 115 + ath12k_dbg(ab, ATH12K_DBG_BOOT, 116 + "found m3 image ie (%zd B)\n", 117 + ie_len); 118 + 119 + ab->fw.m3_data = data; 120 + ab->fw.m3_len = ie_len; 121 + break; 122 + case ATH12K_FW_IE_AMSS_DUALMAC_IMAGE: 123 + ath12k_dbg(ab, ATH12K_DBG_BOOT, 124 + "found dualmac fw image ie (%zd B)\n", 125 + ie_len); 126 + ab->fw.amss_dualmac_data = data; 127 + ab->fw.amss_dualmac_len = ie_len; 128 + break; 129 + default: 130 + ath12k_warn(ab, "Unknown FW IE: %u\n", ie_id); 131 + break; 132 + } 133 + 134 + /* jump over the padding */ 135 + ie_len = ALIGN(ie_len, 4); 136 + 137 + /* make sure there's space for padding */ 138 + if (ie_len > len) 139 + break; 140 + 141 + len -= ie_len; 142 + data += ie_len; 143 + } 144 + 145 + return 0; 146 + 147 + err: 148 + release_firmware(ab->fw.fw); 149 + ab->fw.fw = NULL; 150 + return ret; 151 + } 152 + 153 + void ath12k_fw_map(struct ath12k_base *ab) 154 + { 155 + int ret; 156 + 157 + ret = ath12k_fw_request_firmware_api_n(ab, ATH12K_FW_API2_FILE); 158 + if (ret == 0) 159 + ab->fw.api_version = 2; 160 + else 161 + ab->fw.api_version = 1; 162 + 163 + ath12k_dbg(ab, ATH12K_DBG_BOOT, "using fw api %d\n", 164 + ab->fw.api_version); 165 + } 166 + 167 + void ath12k_fw_unmap(struct ath12k_base *ab) 168 + { 169 + release_firmware(ab->fw.fw); 170 + memset(&ab->fw, 0, sizeof(ab->fw)); 171 + }
+33
drivers/net/wireless/ath/ath12k/fw.h
··· 1 + /* SPDX-License-Identifier: BSD-3-Clause-Clear */ 2 + /* 3 + * Copyright (c) 2022-2024 Qualcomm Innovation Center, Inc. All rights reserved. 4 + */ 5 + 6 + #ifndef ATH12K_FW_H 7 + #define ATH12K_FW_H 8 + 9 + #define ATH12K_FW_API2_FILE "firmware-2.bin" 10 + #define ATH12K_FIRMWARE_MAGIC "QCOM-ATH12K-FW" 11 + 12 + enum ath12k_fw_ie_type { 13 + ATH12K_FW_IE_TIMESTAMP = 0, 14 + ATH12K_FW_IE_FEATURES = 1, 15 + ATH12K_FW_IE_AMSS_IMAGE = 2, 16 + ATH12K_FW_IE_M3_IMAGE = 3, 17 + ATH12K_FW_IE_AMSS_DUALMAC_IMAGE = 4, 18 + }; 19 + 20 + enum ath12k_fw_features { 21 + /* The firmware supports setting the QRTR id via register 22 + * PCIE_LOCAL_REG_QRTR_NODE_ID 23 + */ 24 + ATH12K_FW_FEATURE_MULTI_QRTR_ID = 0, 25 + 26 + /* keep last */ 27 + ATH12K_FW_FEATURE_COUNT, 28 + }; 29 + 30 + void ath12k_fw_map(struct ath12k_base *ab); 31 + void ath12k_fw_unmap(struct ath12k_base *ab); 32 + 33 + #endif /* ATH12K_FW_H */
+406 -9
drivers/net/wireless/ath/ath12k/hal.c
··· 1 1 // SPDX-License-Identifier: BSD-3-Clause-Clear 2 2 /* 3 3 * Copyright (c) 2018-2021 The Linux Foundation. All rights reserved. 4 - * Copyright (c) 2021-2023 Qualcomm Innovation Center, Inc. All rights reserved. 4 + * Copyright (c) 2021-2024 Qualcomm Innovation Center, Inc. All rights reserved. 5 5 */ 6 6 #include <linux/dma-mapping.h> 7 7 #include "hal_tx.h" ··· 449 449 450 450 static bool ath12k_hw_qcn9274_rx_desc_is_da_mcbc(struct hal_rx_desc *desc) 451 451 { 452 - return __le16_to_cpu(desc->u.qcn9274.msdu_end.info5) & 453 - RX_MSDU_END_INFO5_DA_IS_MCBC; 452 + return __le32_to_cpu(desc->u.qcn9274.mpdu_start.info6) & 453 + RX_MPDU_START_INFO6_MCAST_BCAST; 454 454 } 455 455 456 456 static void ath12k_hw_qcn9274_rx_desc_get_dot11_hdr(struct hal_rx_desc *desc, ··· 626 626 return 0; 627 627 } 628 628 629 + static u16 ath12k_hal_qcn9274_rx_mpdu_start_wmask_get(void) 630 + { 631 + return QCN9274_MPDU_START_WMASK; 632 + } 633 + 634 + static u32 ath12k_hal_qcn9274_rx_msdu_end_wmask_get(void) 635 + { 636 + return QCN9274_MSDU_END_WMASK; 637 + } 638 + 639 + static const struct hal_rx_ops *ath12k_hal_qcn9274_get_hal_rx_compact_ops(void) 640 + { 641 + return &hal_rx_qcn9274_compact_ops; 642 + } 643 + 629 644 static bool ath12k_hw_qcn9274_dp_rx_h_msdu_done(struct hal_rx_desc *desc) 630 645 { 631 646 return !!le32_get_bits(desc->u.qcn9274.msdu_end.info14, ··· 695 680 return errmap; 696 681 } 697 682 698 - const struct hal_ops hal_qcn9274_ops = { 683 + static u32 ath12k_hw_qcn9274_get_rx_desc_size(void) 684 + { 685 + return sizeof(struct hal_rx_desc_qcn9274); 686 + } 687 + 688 + static u8 ath12k_hw_qcn9274_rx_desc_get_msdu_src_link(struct hal_rx_desc *desc) 689 + { 690 + return 0; 691 + } 692 + 693 + const struct hal_rx_ops hal_rx_qcn9274_ops = { 699 694 .rx_desc_get_first_msdu = ath12k_hw_qcn9274_rx_desc_get_first_msdu, 700 695 .rx_desc_get_last_msdu = ath12k_hw_qcn9274_rx_desc_get_last_msdu, 701 696 .rx_desc_get_l3_pad_bytes = ath12k_hw_qcn9274_rx_desc_get_l3_pad_bytes, ··· 737 712 .rx_desc_get_dot11_hdr = ath12k_hw_qcn9274_rx_desc_get_dot11_hdr, 738 713 .rx_desc_get_crypto_header = ath12k_hw_qcn9274_rx_desc_get_crypto_hdr, 739 714 .rx_desc_get_mpdu_frame_ctl = ath12k_hw_qcn9274_rx_desc_get_mpdu_frame_ctl, 740 - .create_srng_config = ath12k_hal_srng_create_config_qcn9274, 741 - .tcl_to_wbm_rbm_map = ath12k_hal_qcn9274_tcl_to_wbm_rbm_map, 742 715 .dp_rx_h_msdu_done = ath12k_hw_qcn9274_dp_rx_h_msdu_done, 743 716 .dp_rx_h_l4_cksum_fail = ath12k_hw_qcn9274_dp_rx_h_l4_cksum_fail, 744 717 .dp_rx_h_ip_cksum_fail = ath12k_hw_qcn9274_dp_rx_h_ip_cksum_fail, 745 718 .dp_rx_h_is_decrypted = ath12k_hw_qcn9274_dp_rx_h_is_decrypted, 746 719 .dp_rx_h_mpdu_err = ath12k_hw_qcn9274_dp_rx_h_mpdu_err, 720 + .rx_desc_get_desc_size = ath12k_hw_qcn9274_get_rx_desc_size, 721 + .rx_desc_get_msdu_src_link_id = ath12k_hw_qcn9274_rx_desc_get_msdu_src_link, 722 + }; 723 + 724 + static bool ath12k_hw_qcn9274_compact_rx_desc_get_first_msdu(struct hal_rx_desc *desc) 725 + { 726 + return !!le16_get_bits(desc->u.qcn9274_compact.msdu_end.info5, 727 + RX_MSDU_END_INFO5_FIRST_MSDU); 728 + } 729 + 730 + static bool ath12k_hw_qcn9274_compact_rx_desc_get_last_msdu(struct hal_rx_desc *desc) 731 + { 732 + return !!le16_get_bits(desc->u.qcn9274_compact.msdu_end.info5, 733 + RX_MSDU_END_INFO5_LAST_MSDU); 734 + } 735 + 736 + static u8 ath12k_hw_qcn9274_compact_rx_desc_get_l3_pad_bytes(struct hal_rx_desc *desc) 737 + { 738 + return le16_get_bits(desc->u.qcn9274_compact.msdu_end.info5, 739 + RX_MSDU_END_INFO5_L3_HDR_PADDING); 740 + } 741 + 742 + static bool ath12k_hw_qcn9274_compact_rx_desc_encrypt_valid(struct hal_rx_desc *desc) 743 + { 744 + return !!le32_get_bits(desc->u.qcn9274_compact.mpdu_start.info4, 745 + RX_MPDU_START_INFO4_ENCRYPT_INFO_VALID); 746 + } 747 + 748 + static u32 ath12k_hw_qcn9274_compact_rx_desc_get_encrypt_type(struct hal_rx_desc *desc) 749 + { 750 + return le32_get_bits(desc->u.qcn9274_compact.mpdu_start.info2, 751 + RX_MPDU_START_INFO2_ENC_TYPE); 752 + } 753 + 754 + static u8 ath12k_hw_qcn9274_compact_rx_desc_get_decap_type(struct hal_rx_desc *desc) 755 + { 756 + return le32_get_bits(desc->u.qcn9274_compact.msdu_end.info11, 757 + RX_MSDU_END_INFO11_DECAP_FORMAT); 758 + } 759 + 760 + static u8 ath12k_hw_qcn9274_compact_rx_desc_get_mesh_ctl(struct hal_rx_desc *desc) 761 + { 762 + return le32_get_bits(desc->u.qcn9274.msdu_end.info11, 763 + RX_MSDU_END_INFO11_MESH_CTRL_PRESENT); 764 + } 765 + 766 + static bool 767 + ath12k_hw_qcn9274_compact_rx_desc_get_mpdu_seq_ctl_vld(struct hal_rx_desc *desc) 768 + { 769 + return !!le32_get_bits(desc->u.qcn9274_compact.mpdu_start.info4, 770 + RX_MPDU_START_INFO4_MPDU_SEQ_CTRL_VALID); 771 + } 772 + 773 + static bool ath12k_hw_qcn9274_compact_rx_desc_get_mpdu_fc_valid(struct hal_rx_desc *desc) 774 + { 775 + return !!le32_get_bits(desc->u.qcn9274_compact.mpdu_start.info4, 776 + RX_MPDU_START_INFO4_MPDU_FCTRL_VALID); 777 + } 778 + 779 + static u16 780 + ath12k_hw_qcn9274_compact_rx_desc_get_mpdu_start_seq_no(struct hal_rx_desc *desc) 781 + { 782 + return le32_get_bits(desc->u.qcn9274_compact.mpdu_start.info4, 783 + RX_MPDU_START_INFO4_MPDU_SEQ_NUM); 784 + } 785 + 786 + static u16 ath12k_hw_qcn9274_compact_rx_desc_get_msdu_len(struct hal_rx_desc *desc) 787 + { 788 + return le32_get_bits(desc->u.qcn9274_compact.msdu_end.info10, 789 + RX_MSDU_END_INFO10_MSDU_LENGTH); 790 + } 791 + 792 + static u8 ath12k_hw_qcn9274_compact_rx_desc_get_msdu_sgi(struct hal_rx_desc *desc) 793 + { 794 + return le32_get_bits(desc->u.qcn9274_compact.msdu_end.info12, 795 + RX_MSDU_END_INFO12_SGI); 796 + } 797 + 798 + static u8 ath12k_hw_qcn9274_compact_rx_desc_get_msdu_rate_mcs(struct hal_rx_desc *desc) 799 + { 800 + return le32_get_bits(desc->u.qcn9274_compact.msdu_end.info12, 801 + RX_MSDU_END_INFO12_RATE_MCS); 802 + } 803 + 804 + static u8 ath12k_hw_qcn9274_compact_rx_desc_get_msdu_rx_bw(struct hal_rx_desc *desc) 805 + { 806 + return le32_get_bits(desc->u.qcn9274_compact.msdu_end.info12, 807 + RX_MSDU_END_INFO12_RECV_BW); 808 + } 809 + 810 + static u32 ath12k_hw_qcn9274_compact_rx_desc_get_msdu_freq(struct hal_rx_desc *desc) 811 + { 812 + return __le32_to_cpu(desc->u.qcn9274_compact.msdu_end.phy_meta_data); 813 + } 814 + 815 + static u8 ath12k_hw_qcn9274_compact_rx_desc_get_msdu_pkt_type(struct hal_rx_desc *desc) 816 + { 817 + return le32_get_bits(desc->u.qcn9274_compact.msdu_end.info12, 818 + RX_MSDU_END_INFO12_PKT_TYPE); 819 + } 820 + 821 + static u8 ath12k_hw_qcn9274_compact_rx_desc_get_msdu_nss(struct hal_rx_desc *desc) 822 + { 823 + return le32_get_bits(desc->u.qcn9274_compact.msdu_end.info12, 824 + RX_MSDU_END_QCN9274_INFO12_MIMO_SS_BITMAP); 825 + } 826 + 827 + static u8 ath12k_hw_qcn9274_compact_rx_desc_get_mpdu_tid(struct hal_rx_desc *desc) 828 + { 829 + return le16_get_bits(desc->u.qcn9274_compact.msdu_end.info5, 830 + RX_MSDU_END_QCN9274_INFO5_TID); 831 + } 832 + 833 + static u16 ath12k_hw_qcn9274_compact_rx_desc_get_mpdu_peer_id(struct hal_rx_desc *desc) 834 + { 835 + return __le16_to_cpu(desc->u.qcn9274_compact.mpdu_start.sw_peer_id); 836 + } 837 + 838 + static void ath12k_hw_qcn9274_compact_rx_desc_copy_end_tlv(struct hal_rx_desc *fdesc, 839 + struct hal_rx_desc *ldesc) 840 + { 841 + fdesc->u.qcn9274_compact.msdu_end = ldesc->u.qcn9274_compact.msdu_end; 842 + } 843 + 844 + static u32 ath12k_hw_qcn9274_compact_rx_desc_get_mpdu_ppdu_id(struct hal_rx_desc *desc) 845 + { 846 + return __le16_to_cpu(desc->u.qcn9274_compact.mpdu_start.phy_ppdu_id); 847 + } 848 + 849 + static void 850 + ath12k_hw_qcn9274_compact_rx_desc_set_msdu_len(struct hal_rx_desc *desc, u16 len) 851 + { 852 + u32 info = __le32_to_cpu(desc->u.qcn9274_compact.msdu_end.info10); 853 + 854 + info = u32_replace_bits(info, len, RX_MSDU_END_INFO10_MSDU_LENGTH); 855 + desc->u.qcn9274_compact.msdu_end.info10 = __cpu_to_le32(info); 856 + } 857 + 858 + static u8 *ath12k_hw_qcn9274_compact_rx_desc_get_msdu_payload(struct hal_rx_desc *desc) 859 + { 860 + return &desc->u.qcn9274_compact.msdu_payload[0]; 861 + } 862 + 863 + static u32 ath12k_hw_qcn9274_compact_rx_desc_get_mpdu_start_offset(void) 864 + { 865 + return offsetof(struct hal_rx_desc_qcn9274_compact, mpdu_start); 866 + } 867 + 868 + static u32 ath12k_hw_qcn9274_compact_rx_desc_get_msdu_end_offset(void) 869 + { 870 + return offsetof(struct hal_rx_desc_qcn9274_compact, msdu_end); 871 + } 872 + 873 + static bool ath12k_hw_qcn9274_compact_rx_desc_mac_addr2_valid(struct hal_rx_desc *desc) 874 + { 875 + return __le32_to_cpu(desc->u.qcn9274_compact.mpdu_start.info4) & 876 + RX_MPDU_START_INFO4_MAC_ADDR2_VALID; 877 + } 878 + 879 + static u8 *ath12k_hw_qcn9274_compact_rx_desc_mpdu_start_addr2(struct hal_rx_desc *desc) 880 + { 881 + return desc->u.qcn9274_compact.mpdu_start.addr2; 882 + } 883 + 884 + static bool ath12k_hw_qcn9274_compact_rx_desc_is_da_mcbc(struct hal_rx_desc *desc) 885 + { 886 + return __le32_to_cpu(desc->u.qcn9274_compact.mpdu_start.info6) & 887 + RX_MPDU_START_INFO6_MCAST_BCAST; 888 + } 889 + 890 + static void ath12k_hw_qcn9274_compact_rx_desc_get_dot11_hdr(struct hal_rx_desc *desc, 891 + struct ieee80211_hdr *hdr) 892 + { 893 + hdr->frame_control = desc->u.qcn9274_compact.mpdu_start.frame_ctrl; 894 + hdr->duration_id = desc->u.qcn9274_compact.mpdu_start.duration; 895 + ether_addr_copy(hdr->addr1, desc->u.qcn9274_compact.mpdu_start.addr1); 896 + ether_addr_copy(hdr->addr2, desc->u.qcn9274_compact.mpdu_start.addr2); 897 + ether_addr_copy(hdr->addr3, desc->u.qcn9274_compact.mpdu_start.addr3); 898 + if (__le32_to_cpu(desc->u.qcn9274_compact.mpdu_start.info4) & 899 + RX_MPDU_START_INFO4_MAC_ADDR4_VALID) { 900 + ether_addr_copy(hdr->addr4, desc->u.qcn9274_compact.mpdu_start.addr4); 901 + } 902 + hdr->seq_ctrl = desc->u.qcn9274_compact.mpdu_start.seq_ctrl; 903 + } 904 + 905 + static void 906 + ath12k_hw_qcn9274_compact_rx_desc_get_crypto_hdr(struct hal_rx_desc *desc, 907 + u8 *crypto_hdr, 908 + enum hal_encrypt_type enctype) 909 + { 910 + unsigned int key_id; 911 + 912 + switch (enctype) { 913 + case HAL_ENCRYPT_TYPE_OPEN: 914 + return; 915 + case HAL_ENCRYPT_TYPE_TKIP_NO_MIC: 916 + case HAL_ENCRYPT_TYPE_TKIP_MIC: 917 + crypto_hdr[0] = 918 + HAL_RX_MPDU_INFO_PN_GET_BYTE2(desc->u.qcn9274_compact.mpdu_start.pn[0]); 919 + crypto_hdr[1] = 0; 920 + crypto_hdr[2] = 921 + HAL_RX_MPDU_INFO_PN_GET_BYTE1(desc->u.qcn9274_compact.mpdu_start.pn[0]); 922 + break; 923 + case HAL_ENCRYPT_TYPE_CCMP_128: 924 + case HAL_ENCRYPT_TYPE_CCMP_256: 925 + case HAL_ENCRYPT_TYPE_GCMP_128: 926 + case HAL_ENCRYPT_TYPE_AES_GCMP_256: 927 + crypto_hdr[0] = 928 + HAL_RX_MPDU_INFO_PN_GET_BYTE1(desc->u.qcn9274_compact.mpdu_start.pn[0]); 929 + crypto_hdr[1] = 930 + HAL_RX_MPDU_INFO_PN_GET_BYTE2(desc->u.qcn9274_compact.mpdu_start.pn[0]); 931 + crypto_hdr[2] = 0; 932 + break; 933 + case HAL_ENCRYPT_TYPE_WEP_40: 934 + case HAL_ENCRYPT_TYPE_WEP_104: 935 + case HAL_ENCRYPT_TYPE_WEP_128: 936 + case HAL_ENCRYPT_TYPE_WAPI_GCM_SM4: 937 + case HAL_ENCRYPT_TYPE_WAPI: 938 + return; 939 + } 940 + key_id = le32_get_bits(desc->u.qcn9274_compact.mpdu_start.info5, 941 + RX_MPDU_START_INFO5_KEY_ID); 942 + crypto_hdr[3] = 0x20 | (key_id << 6); 943 + crypto_hdr[4] = 944 + HAL_RX_MPDU_INFO_PN_GET_BYTE3(desc->u.qcn9274_compact.mpdu_start.pn[0]); 945 + crypto_hdr[5] = 946 + HAL_RX_MPDU_INFO_PN_GET_BYTE4(desc->u.qcn9274_compact.mpdu_start.pn[0]); 947 + crypto_hdr[6] = 948 + HAL_RX_MPDU_INFO_PN_GET_BYTE1(desc->u.qcn9274_compact.mpdu_start.pn[1]); 949 + crypto_hdr[7] = 950 + HAL_RX_MPDU_INFO_PN_GET_BYTE2(desc->u.qcn9274_compact.mpdu_start.pn[1]); 951 + } 952 + 953 + static u16 ath12k_hw_qcn9274_compact_rx_desc_get_mpdu_frame_ctl(struct hal_rx_desc *desc) 954 + { 955 + return __le16_to_cpu(desc->u.qcn9274_compact.mpdu_start.frame_ctrl); 956 + } 957 + 958 + static bool ath12k_hw_qcn9274_compact_dp_rx_h_msdu_done(struct hal_rx_desc *desc) 959 + { 960 + return !!le32_get_bits(desc->u.qcn9274_compact.msdu_end.info14, 961 + RX_MSDU_END_INFO14_MSDU_DONE); 962 + } 963 + 964 + static bool ath12k_hw_qcn9274_compact_dp_rx_h_l4_cksum_fail(struct hal_rx_desc *desc) 965 + { 966 + return !!le32_get_bits(desc->u.qcn9274_compact.msdu_end.info13, 967 + RX_MSDU_END_INFO13_TCP_UDP_CKSUM_FAIL); 968 + } 969 + 970 + static bool ath12k_hw_qcn9274_compact_dp_rx_h_ip_cksum_fail(struct hal_rx_desc *desc) 971 + { 972 + return !!le32_get_bits(desc->u.qcn9274_compact.msdu_end.info13, 973 + RX_MSDU_END_INFO13_IP_CKSUM_FAIL); 974 + } 975 + 976 + static bool ath12k_hw_qcn9274_compact_dp_rx_h_is_decrypted(struct hal_rx_desc *desc) 977 + { 978 + return (le32_get_bits(desc->u.qcn9274_compact.msdu_end.info14, 979 + RX_MSDU_END_INFO14_DECRYPT_STATUS_CODE) == 980 + RX_DESC_DECRYPT_STATUS_CODE_OK); 981 + } 982 + 983 + static u32 ath12k_hw_qcn9274_compact_dp_rx_h_mpdu_err(struct hal_rx_desc *desc) 984 + { 985 + u32 info = __le32_to_cpu(desc->u.qcn9274_compact.msdu_end.info13); 986 + u32 errmap = 0; 987 + 988 + if (info & RX_MSDU_END_INFO13_FCS_ERR) 989 + errmap |= HAL_RX_MPDU_ERR_FCS; 990 + 991 + if (info & RX_MSDU_END_INFO13_DECRYPT_ERR) 992 + errmap |= HAL_RX_MPDU_ERR_DECRYPT; 993 + 994 + if (info & RX_MSDU_END_INFO13_TKIP_MIC_ERR) 995 + errmap |= HAL_RX_MPDU_ERR_TKIP_MIC; 996 + 997 + if (info & RX_MSDU_END_INFO13_A_MSDU_ERROR) 998 + errmap |= HAL_RX_MPDU_ERR_AMSDU_ERR; 999 + 1000 + if (info & RX_MSDU_END_INFO13_OVERFLOW_ERR) 1001 + errmap |= HAL_RX_MPDU_ERR_OVERFLOW; 1002 + 1003 + if (info & RX_MSDU_END_INFO13_MSDU_LEN_ERR) 1004 + errmap |= HAL_RX_MPDU_ERR_MSDU_LEN; 1005 + 1006 + if (info & RX_MSDU_END_INFO13_MPDU_LEN_ERR) 1007 + errmap |= HAL_RX_MPDU_ERR_MPDU_LEN; 1008 + 1009 + return errmap; 1010 + } 1011 + 1012 + static u32 ath12k_hw_qcn9274_compact_get_rx_desc_size(void) 1013 + { 1014 + return sizeof(struct hal_rx_desc_qcn9274_compact); 1015 + } 1016 + 1017 + static u8 ath12k_hw_qcn9274_compact_rx_desc_get_msdu_src_link(struct hal_rx_desc *desc) 1018 + { 1019 + return le64_get_bits(desc->u.qcn9274_compact.msdu_end.msdu_end_tag, 1020 + RX_MSDU_END_64_TLV_SRC_LINK_ID); 1021 + } 1022 + 1023 + const struct hal_rx_ops hal_rx_qcn9274_compact_ops = { 1024 + .rx_desc_get_first_msdu = ath12k_hw_qcn9274_compact_rx_desc_get_first_msdu, 1025 + .rx_desc_get_last_msdu = ath12k_hw_qcn9274_compact_rx_desc_get_last_msdu, 1026 + .rx_desc_get_l3_pad_bytes = ath12k_hw_qcn9274_compact_rx_desc_get_l3_pad_bytes, 1027 + .rx_desc_encrypt_valid = ath12k_hw_qcn9274_compact_rx_desc_encrypt_valid, 1028 + .rx_desc_get_encrypt_type = ath12k_hw_qcn9274_compact_rx_desc_get_encrypt_type, 1029 + .rx_desc_get_decap_type = ath12k_hw_qcn9274_compact_rx_desc_get_decap_type, 1030 + .rx_desc_get_mesh_ctl = ath12k_hw_qcn9274_compact_rx_desc_get_mesh_ctl, 1031 + .rx_desc_get_mpdu_seq_ctl_vld = 1032 + ath12k_hw_qcn9274_compact_rx_desc_get_mpdu_seq_ctl_vld, 1033 + .rx_desc_get_mpdu_fc_valid = ath12k_hw_qcn9274_compact_rx_desc_get_mpdu_fc_valid, 1034 + .rx_desc_get_mpdu_start_seq_no = 1035 + ath12k_hw_qcn9274_compact_rx_desc_get_mpdu_start_seq_no, 1036 + .rx_desc_get_msdu_len = ath12k_hw_qcn9274_compact_rx_desc_get_msdu_len, 1037 + .rx_desc_get_msdu_sgi = ath12k_hw_qcn9274_compact_rx_desc_get_msdu_sgi, 1038 + .rx_desc_get_msdu_rate_mcs = ath12k_hw_qcn9274_compact_rx_desc_get_msdu_rate_mcs, 1039 + .rx_desc_get_msdu_rx_bw = ath12k_hw_qcn9274_compact_rx_desc_get_msdu_rx_bw, 1040 + .rx_desc_get_msdu_freq = ath12k_hw_qcn9274_compact_rx_desc_get_msdu_freq, 1041 + .rx_desc_get_msdu_pkt_type = ath12k_hw_qcn9274_compact_rx_desc_get_msdu_pkt_type, 1042 + .rx_desc_get_msdu_nss = ath12k_hw_qcn9274_compact_rx_desc_get_msdu_nss, 1043 + .rx_desc_get_mpdu_tid = ath12k_hw_qcn9274_compact_rx_desc_get_mpdu_tid, 1044 + .rx_desc_get_mpdu_peer_id = ath12k_hw_qcn9274_compact_rx_desc_get_mpdu_peer_id, 1045 + .rx_desc_copy_end_tlv = ath12k_hw_qcn9274_compact_rx_desc_copy_end_tlv, 1046 + .rx_desc_get_mpdu_ppdu_id = ath12k_hw_qcn9274_compact_rx_desc_get_mpdu_ppdu_id, 1047 + .rx_desc_set_msdu_len = ath12k_hw_qcn9274_compact_rx_desc_set_msdu_len, 1048 + .rx_desc_get_msdu_payload = ath12k_hw_qcn9274_compact_rx_desc_get_msdu_payload, 1049 + .rx_desc_get_mpdu_start_offset = 1050 + ath12k_hw_qcn9274_compact_rx_desc_get_mpdu_start_offset, 1051 + .rx_desc_get_msdu_end_offset = 1052 + ath12k_hw_qcn9274_compact_rx_desc_get_msdu_end_offset, 1053 + .rx_desc_mac_addr2_valid = ath12k_hw_qcn9274_compact_rx_desc_mac_addr2_valid, 1054 + .rx_desc_mpdu_start_addr2 = ath12k_hw_qcn9274_compact_rx_desc_mpdu_start_addr2, 1055 + .rx_desc_is_da_mcbc = ath12k_hw_qcn9274_compact_rx_desc_is_da_mcbc, 1056 + .rx_desc_get_dot11_hdr = ath12k_hw_qcn9274_compact_rx_desc_get_dot11_hdr, 1057 + .rx_desc_get_crypto_header = ath12k_hw_qcn9274_compact_rx_desc_get_crypto_hdr, 1058 + .rx_desc_get_mpdu_frame_ctl = 1059 + ath12k_hw_qcn9274_compact_rx_desc_get_mpdu_frame_ctl, 1060 + .dp_rx_h_msdu_done = ath12k_hw_qcn9274_compact_dp_rx_h_msdu_done, 1061 + .dp_rx_h_l4_cksum_fail = ath12k_hw_qcn9274_compact_dp_rx_h_l4_cksum_fail, 1062 + .dp_rx_h_ip_cksum_fail = ath12k_hw_qcn9274_compact_dp_rx_h_ip_cksum_fail, 1063 + .dp_rx_h_is_decrypted = ath12k_hw_qcn9274_compact_dp_rx_h_is_decrypted, 1064 + .dp_rx_h_mpdu_err = ath12k_hw_qcn9274_compact_dp_rx_h_mpdu_err, 1065 + .rx_desc_get_desc_size = ath12k_hw_qcn9274_compact_get_rx_desc_size, 1066 + .rx_desc_get_msdu_src_link_id = 1067 + ath12k_hw_qcn9274_compact_rx_desc_get_msdu_src_link, 1068 + }; 1069 + 1070 + const struct hal_ops hal_qcn9274_ops = { 1071 + .create_srng_config = ath12k_hal_srng_create_config_qcn9274, 1072 + .tcl_to_wbm_rbm_map = ath12k_hal_qcn9274_tcl_to_wbm_rbm_map, 1073 + .rxdma_ring_wmask_rx_mpdu_start = ath12k_hal_qcn9274_rx_mpdu_start_wmask_get, 1074 + .rxdma_ring_wmask_rx_msdu_end = ath12k_hal_qcn9274_rx_msdu_end_wmask_get, 1075 + .get_hal_rx_compact_ops = ath12k_hal_qcn9274_get_hal_rx_compact_ops, 747 1076 }; 748 1077 749 1078 static bool ath12k_hw_wcn7850_rx_desc_get_first_msdu(struct hal_rx_desc *desc) ··· 1513 1134 return errmap; 1514 1135 } 1515 1136 1516 - const struct hal_ops hal_wcn7850_ops = { 1137 + static u32 ath12k_hw_wcn7850_get_rx_desc_size(void) 1138 + { 1139 + return sizeof(struct hal_rx_desc_wcn7850); 1140 + } 1141 + 1142 + static u8 ath12k_hw_wcn7850_rx_desc_get_msdu_src_link(struct hal_rx_desc *desc) 1143 + { 1144 + return 0; 1145 + } 1146 + 1147 + const struct hal_rx_ops hal_rx_wcn7850_ops = { 1517 1148 .rx_desc_get_first_msdu = ath12k_hw_wcn7850_rx_desc_get_first_msdu, 1518 1149 .rx_desc_get_last_msdu = ath12k_hw_wcn7850_rx_desc_get_last_msdu, 1519 1150 .rx_desc_get_l3_pad_bytes = ath12k_hw_wcn7850_rx_desc_get_l3_pad_bytes, ··· 1556 1167 .rx_desc_get_dot11_hdr = ath12k_hw_wcn7850_rx_desc_get_dot11_hdr, 1557 1168 .rx_desc_get_crypto_header = ath12k_hw_wcn7850_rx_desc_get_crypto_hdr, 1558 1169 .rx_desc_get_mpdu_frame_ctl = ath12k_hw_wcn7850_rx_desc_get_mpdu_frame_ctl, 1559 - .create_srng_config = ath12k_hal_srng_create_config_wcn7850, 1560 - .tcl_to_wbm_rbm_map = ath12k_hal_wcn7850_tcl_to_wbm_rbm_map, 1561 1170 .dp_rx_h_msdu_done = ath12k_hw_wcn7850_dp_rx_h_msdu_done, 1562 1171 .dp_rx_h_l4_cksum_fail = ath12k_hw_wcn7850_dp_rx_h_l4_cksum_fail, 1563 1172 .dp_rx_h_ip_cksum_fail = ath12k_hw_wcn7850_dp_rx_h_ip_cksum_fail, 1564 1173 .dp_rx_h_is_decrypted = ath12k_hw_wcn7850_dp_rx_h_is_decrypted, 1565 1174 .dp_rx_h_mpdu_err = ath12k_hw_wcn7850_dp_rx_h_mpdu_err, 1175 + .rx_desc_get_desc_size = ath12k_hw_wcn7850_get_rx_desc_size, 1176 + .rx_desc_get_msdu_src_link_id = ath12k_hw_wcn7850_rx_desc_get_msdu_src_link, 1177 + }; 1178 + 1179 + const struct hal_ops hal_wcn7850_ops = { 1180 + .create_srng_config = ath12k_hal_srng_create_config_wcn7850, 1181 + .tcl_to_wbm_rbm_map = ath12k_hal_wcn7850_tcl_to_wbm_rbm_map, 1182 + .rxdma_ring_wmask_rx_mpdu_start = NULL, 1183 + .rxdma_ring_wmask_rx_msdu_end = NULL, 1184 + .get_hal_rx_compact_ops = NULL, 1566 1185 }; 1567 1186 1568 1187 static int ath12k_hal_alloc_cont_rdp(struct ath12k_base *ab)
+17 -3
drivers/net/wireless/ath/ath12k/hal.h
··· 1 1 /* SPDX-License-Identifier: BSD-3-Clause-Clear */ 2 2 /* 3 3 * Copyright (c) 2018-2021 The Linux Foundation. All rights reserved. 4 - * Copyright (c) 2021-2023 Qualcomm Innovation Center, Inc. All rights reserved. 4 + * Copyright (c) 2021-2024 Qualcomm Innovation Center, Inc. All rights reserved. 5 5 */ 6 6 7 7 #ifndef ATH12K_HAL_H ··· 1023 1023 /* shadow register configuration */ 1024 1024 u32 shadow_reg_addr[HAL_SHADOW_NUM_REGS]; 1025 1025 int num_shadow_reg_configured; 1026 + 1027 + u32 hal_desc_sz; 1026 1028 }; 1027 1029 1028 1030 /* Maps WBM ring number and Return Buffer Manager Id per TCL ring */ ··· 1033 1031 u8 rbm_id; 1034 1032 }; 1035 1033 1036 - struct hal_ops { 1034 + struct hal_rx_ops { 1037 1035 bool (*rx_desc_get_first_msdu)(struct hal_rx_desc *desc); 1038 1036 bool (*rx_desc_get_last_msdu)(struct hal_rx_desc *desc); 1039 1037 u8 (*rx_desc_get_l3_pad_bytes)(struct hal_rx_desc *desc); ··· 1072 1070 void (*rx_desc_get_crypto_header)(struct hal_rx_desc *desc, 1073 1071 u8 *crypto_hdr, 1074 1072 enum hal_encrypt_type enctype); 1075 - int (*create_srng_config)(struct ath12k_base *ab); 1076 1073 bool (*dp_rx_h_msdu_done)(struct hal_rx_desc *desc); 1077 1074 bool (*dp_rx_h_l4_cksum_fail)(struct hal_rx_desc *desc); 1078 1075 bool (*dp_rx_h_ip_cksum_fail)(struct hal_rx_desc *desc); 1079 1076 bool (*dp_rx_h_is_decrypted)(struct hal_rx_desc *desc); 1080 1077 u32 (*dp_rx_h_mpdu_err)(struct hal_rx_desc *desc); 1078 + u32 (*rx_desc_get_desc_size)(void); 1079 + u8 (*rx_desc_get_msdu_src_link_id)(struct hal_rx_desc *desc); 1080 + }; 1081 + 1082 + struct hal_ops { 1083 + int (*create_srng_config)(struct ath12k_base *ab); 1084 + u16 (*rxdma_ring_wmask_rx_mpdu_start)(void); 1085 + u32 (*rxdma_ring_wmask_rx_msdu_end)(void); 1086 + const struct hal_rx_ops *(*get_hal_rx_compact_ops)(void); 1081 1087 const struct ath12k_hal_tcl_to_wbm_rbm_map *tcl_to_wbm_rbm_map; 1082 1088 }; 1083 1089 1084 1090 extern const struct hal_ops hal_qcn9274_ops; 1085 1091 extern const struct hal_ops hal_wcn7850_ops; 1092 + 1093 + extern const struct hal_rx_ops hal_rx_qcn9274_ops; 1094 + extern const struct hal_rx_ops hal_rx_qcn9274_compact_ops; 1095 + extern const struct hal_rx_ops hal_rx_wcn7850_ops; 1086 1096 1087 1097 u32 ath12k_hal_reo_qdesc_size(u32 ba_window_size, u8 tid); 1088 1098 void ath12k_hal_reo_qdesc_setup(struct hal_rx_reo_queue *qdesc,
+18 -6
drivers/net/wireless/ath/ath12k/hw.c
··· 1 1 // SPDX-License-Identifier: BSD-3-Clause-Clear 2 2 /* 3 3 * Copyright (c) 2018-2021 The Linux Foundation. All rights reserved. 4 - * Copyright (c) 2021-2023 Qualcomm Innovation Center, Inc. All rights reserved. 4 + * Copyright (c) 2021-2024 Qualcomm Innovation Center, Inc. All rights reserved. 5 5 */ 6 6 7 7 #include <linux/types.h> ··· 897 897 .reoq_lut_support = false, 898 898 .supports_shadow_regs = false, 899 899 900 - .hal_desc_sz = sizeof(struct hal_rx_desc_qcn9274), 901 900 .num_tcl_banks = 48, 902 901 .max_tx_ring = 4, 903 902 ··· 916 917 917 918 .def_num_link = 0, 918 919 .max_mlo_peer = 256, 920 + 921 + .otp_board_id_register = QCN9274_QFPROM_RAW_RFA_PDET_ROW13_LSB, 922 + 923 + .supports_sta_ps = false, 919 924 }, 920 925 { 921 926 .name = "wcn7850 hw2.0", ··· 956 953 .vdev_start_delay = true, 957 954 958 955 .interface_modes = BIT(NL80211_IFTYPE_STATION) | 959 - BIT(NL80211_IFTYPE_AP), 956 + BIT(NL80211_IFTYPE_AP) | 957 + BIT(NL80211_IFTYPE_P2P_DEVICE) | 958 + BIT(NL80211_IFTYPE_P2P_CLIENT) | 959 + BIT(NL80211_IFTYPE_P2P_GO), 960 960 .supports_monitor = false, 961 961 962 962 .idle_ps = true, ··· 969 963 .reoq_lut_support = false, 970 964 .supports_shadow_regs = true, 971 965 972 - .hal_desc_sz = sizeof(struct hal_rx_desc_wcn7850), 973 966 .num_tcl_banks = 7, 974 967 .max_tx_ring = 3, 975 968 ··· 989 984 990 985 .def_num_link = 2, 991 986 .max_mlo_peer = 32, 987 + 988 + .otp_board_id_register = 0, 989 + 990 + .supports_sta_ps = true, 992 991 }, 993 992 { 994 993 .name = "qcn9274 hw2.0", ··· 1002 993 .board_size = 256 * 1024, 1003 994 .cal_offset = 128 * 1024, 1004 995 }, 1005 - .max_radios = 1, 996 + .max_radios = 2, 1006 997 .single_pdev_only = false, 1007 998 .qmi_service_ins_id = ATH12K_QMI_WLFW_SERVICE_INS_ID_V01_QCN9274, 1008 999 .internal_sleep_clock = false, ··· 1038 1029 .reoq_lut_support = false, 1039 1030 .supports_shadow_regs = false, 1040 1031 1041 - .hal_desc_sz = sizeof(struct hal_rx_desc_qcn9274), 1042 1032 .num_tcl_banks = 48, 1043 1033 .max_tx_ring = 4, 1044 1034 ··· 1057 1049 1058 1050 .def_num_link = 0, 1059 1051 .max_mlo_peer = 256, 1052 + 1053 + .otp_board_id_register = QCN9274_QFPROM_RAW_RFA_PDET_ROW13_LSB, 1054 + 1055 + .supports_sta_ps = false, 1060 1056 }, 1061 1057 }; 1062 1058
+24 -8
drivers/net/wireless/ath/ath12k/hw.h
··· 1 1 /* SPDX-License-Identifier: BSD-3-Clause-Clear */ 2 2 /* 3 3 * Copyright (c) 2018-2021 The Linux Foundation. All rights reserved. 4 - * Copyright (c) 2021-2023 Qualcomm Innovation Center, Inc. All rights reserved. 4 + * Copyright (c) 2021-2024 Qualcomm Innovation Center, Inc. All rights reserved. 5 5 */ 6 6 7 7 #ifndef ATH12K_HW_H ··· 17 17 /* Num VDEVS per radio */ 18 18 #define TARGET_NUM_VDEVS (16 + 1) 19 19 20 - #define TARGET_NUM_PEERS_PDEV (512 + TARGET_NUM_VDEVS) 20 + #define TARGET_NUM_PEERS_PDEV_SINGLE (TARGET_NUM_STATIONS_SINGLE + \ 21 + TARGET_NUM_VDEVS) 22 + #define TARGET_NUM_PEERS_PDEV_DBS (TARGET_NUM_STATIONS_DBS + \ 23 + TARGET_NUM_VDEVS) 24 + #define TARGET_NUM_PEERS_PDEV_DBS_SBS (TARGET_NUM_STATIONS_DBS_SBS + \ 25 + TARGET_NUM_VDEVS) 21 26 22 27 /* Num of peers for Single Radio mode */ 23 - #define TARGET_NUM_PEERS_SINGLE (TARGET_NUM_PEERS_PDEV) 28 + #define TARGET_NUM_PEERS_SINGLE (TARGET_NUM_PEERS_PDEV_SINGLE) 24 29 25 30 /* Num of peers for DBS */ 26 - #define TARGET_NUM_PEERS_DBS (2 * TARGET_NUM_PEERS_PDEV) 31 + #define TARGET_NUM_PEERS_DBS (2 * TARGET_NUM_PEERS_PDEV_DBS) 27 32 28 33 /* Num of peers for DBS_SBS */ 29 - #define TARGET_NUM_PEERS_DBS_SBS (3 * TARGET_NUM_PEERS_PDEV) 34 + #define TARGET_NUM_PEERS_DBS_SBS (3 * TARGET_NUM_PEERS_PDEV_DBS_SBS) 30 35 31 - /* Max num of stations (per radio) */ 32 - #define TARGET_NUM_STATIONS 512 36 + /* Max num of stations for Single Radio mode */ 37 + #define TARGET_NUM_STATIONS_SINGLE 512 38 + 39 + /* Max num of stations for DBS */ 40 + #define TARGET_NUM_STATIONS_DBS 128 41 + 42 + /* Max num of stations for DBS_SBS */ 43 + #define TARGET_NUM_STATIONS_DBS_SBS 128 33 44 34 45 #define TARGET_NUM_PEERS(x) TARGET_NUM_PEERS_##x 35 46 #define TARGET_NUM_PEER_KEYS 2 ··· 77 66 #define TARGET_NUM_WDS_ENTRIES 32 78 67 #define TARGET_DMA_BURST_SIZE 1 79 68 #define TARGET_RX_BATCHMODE 1 69 + #define TARGET_RX_PEER_METADATA_VER_V1A 2 70 + #define TARGET_RX_PEER_METADATA_VER_V1B 3 80 71 81 72 #define ATH12K_HW_MAX_QUEUES 4 82 73 #define ATH12K_QUEUE_LEN 4096 ··· 187 174 bool reoq_lut_support:1; 188 175 bool supports_shadow_regs:1; 189 176 190 - u32 hal_desc_sz; 191 177 u32 num_tcl_banks; 192 178 u32 max_tx_ring; 193 179 ··· 207 195 208 196 u8 def_num_link; 209 197 u16 max_mlo_peer; 198 + 199 + u32 otp_board_id_register; 200 + 201 + bool supports_sta_ps; 210 202 }; 211 203 212 204 struct ath12k_hw_ops {
+384 -59
drivers/net/wireless/ath/ath12k/mac.c
··· 563 563 564 564 for (i = 0; i < ab->num_radios; i++) { 565 565 pdev = rcu_dereference(ab->pdevs_active[i]); 566 - if (pdev && pdev->ar) { 566 + if (pdev && pdev->ar && 567 + (pdev->ar->allocated_vdev_map & (1LL << vdev_id))) { 567 568 arvif = ath12k_mac_get_arvif(pdev->ar, vdev_id); 568 569 if (arvif) 569 570 return arvif; ··· 1084 1083 return ret; 1085 1084 } 1086 1085 1086 + static int ath12k_mac_vdev_stop(struct ath12k_vif *arvif) 1087 + { 1088 + struct ath12k *ar = arvif->ar; 1089 + int ret; 1090 + 1091 + lockdep_assert_held(&ar->conf_mutex); 1092 + 1093 + reinit_completion(&ar->vdev_setup_done); 1094 + 1095 + ret = ath12k_wmi_vdev_stop(ar, arvif->vdev_id); 1096 + if (ret) { 1097 + ath12k_warn(ar->ab, "failed to stop WMI vdev %i: %d\n", 1098 + arvif->vdev_id, ret); 1099 + goto err; 1100 + } 1101 + 1102 + ret = ath12k_mac_vdev_setup_sync(ar); 1103 + if (ret) { 1104 + ath12k_warn(ar->ab, "failed to synchronize setup for vdev %i: %d\n", 1105 + arvif->vdev_id, ret); 1106 + goto err; 1107 + } 1108 + 1109 + WARN_ON(ar->num_started_vdevs == 0); 1110 + 1111 + ar->num_started_vdevs--; 1112 + ath12k_dbg(ar->ab, ATH12K_DBG_MAC, "vdev %pM stopped, vdev_id %d\n", 1113 + arvif->vif->addr, arvif->vdev_id); 1114 + 1115 + if (test_bit(ATH12K_CAC_RUNNING, &ar->dev_flags)) { 1116 + clear_bit(ATH12K_CAC_RUNNING, &ar->dev_flags); 1117 + ath12k_dbg(ar->ab, ATH12K_DBG_MAC, "CAC Stopped for vdev %d\n", 1118 + arvif->vdev_id); 1119 + } 1120 + 1121 + return 0; 1122 + err: 1123 + return ret; 1124 + } 1125 + 1087 1126 static int ath12k_mac_config(struct ath12k *ar, u32 changed) 1088 1127 { 1089 1128 struct ieee80211_hw *hw = ath12k_ar_to_hw(ar); ··· 1179 1138 return ret; 1180 1139 } 1181 1140 1141 + static int ath12k_mac_setup_bcn_p2p_ie(struct ath12k_vif *arvif, 1142 + struct sk_buff *bcn) 1143 + { 1144 + struct ath12k *ar = arvif->ar; 1145 + struct ieee80211_mgmt *mgmt; 1146 + const u8 *p2p_ie; 1147 + int ret; 1148 + 1149 + mgmt = (void *)bcn->data; 1150 + p2p_ie = cfg80211_find_vendor_ie(WLAN_OUI_WFA, WLAN_OUI_TYPE_WFA_P2P, 1151 + mgmt->u.beacon.variable, 1152 + bcn->len - (mgmt->u.beacon.variable - 1153 + bcn->data)); 1154 + if (!p2p_ie) { 1155 + ath12k_warn(ar->ab, "no P2P ie found in beacon\n"); 1156 + return -ENOENT; 1157 + } 1158 + 1159 + ret = ath12k_wmi_p2p_go_bcn_ie(ar, arvif->vdev_id, p2p_ie); 1160 + if (ret) { 1161 + ath12k_warn(ar->ab, "failed to submit P2P GO bcn ie for vdev %i: %d\n", 1162 + arvif->vdev_id, ret); 1163 + return ret; 1164 + } 1165 + 1166 + return 0; 1167 + } 1168 + 1169 + static int ath12k_mac_remove_vendor_ie(struct sk_buff *skb, unsigned int oui, 1170 + u8 oui_type, size_t ie_offset) 1171 + { 1172 + const u8 *next, *end; 1173 + size_t len; 1174 + u8 *ie; 1175 + 1176 + if (WARN_ON(skb->len < ie_offset)) 1177 + return -EINVAL; 1178 + 1179 + ie = (u8 *)cfg80211_find_vendor_ie(oui, oui_type, 1180 + skb->data + ie_offset, 1181 + skb->len - ie_offset); 1182 + if (!ie) 1183 + return -ENOENT; 1184 + 1185 + len = ie[1] + 2; 1186 + end = skb->data + skb->len; 1187 + next = ie + len; 1188 + 1189 + if (WARN_ON(next > end)) 1190 + return -EINVAL; 1191 + 1192 + memmove(ie, next, end - next); 1193 + skb_trim(skb, skb->len - len); 1194 + 1195 + return 0; 1196 + } 1197 + 1182 1198 static int ath12k_mac_setup_bcn_tmpl(struct ath12k_vif *arvif) 1183 1199 { 1184 1200 struct ath12k *ar = arvif->ar; ··· 1268 1170 ies, (skb_tail_pointer(bcn) - ies))) 1269 1171 arvif->wpaie_present = true; 1270 1172 1271 - ret = ath12k_wmi_bcn_tmpl(ar, arvif->vdev_id, &offs, bcn); 1173 + if (arvif->vif->type == NL80211_IFTYPE_AP && arvif->vif->p2p) { 1174 + ret = ath12k_mac_setup_bcn_p2p_ie(arvif, bcn); 1175 + if (ret) { 1176 + ath12k_warn(ab, "failed to setup P2P GO bcn ie: %d\n", 1177 + ret); 1178 + goto free_bcn_skb; 1179 + } 1272 1180 1273 - kfree_skb(bcn); 1181 + /* P2P IE is inserted by firmware automatically (as 1182 + * configured above) so remove it from the base beacon 1183 + * template to avoid duplicate P2P IEs in beacon frames. 1184 + */ 1185 + ret = ath12k_mac_remove_vendor_ie(bcn, WLAN_OUI_WFA, 1186 + WLAN_OUI_TYPE_WFA_P2P, 1187 + offsetof(struct ieee80211_mgmt, 1188 + u.beacon.variable)); 1189 + if (ret) { 1190 + ath12k_warn(ab, "failed to remove P2P vendor ie: %d\n", 1191 + ret); 1192 + goto free_bcn_skb; 1193 + } 1194 + } 1195 + 1196 + ret = ath12k_wmi_bcn_tmpl(ar, arvif->vdev_id, &offs, bcn); 1274 1197 1275 1198 if (ret) 1276 1199 ath12k_warn(ab, "failed to submit beacon template command: %d\n", 1277 1200 ret); 1278 1201 1202 + free_bcn_skb: 1203 + kfree_skb(bcn); 1279 1204 return ret; 1280 1205 } 1281 1206 ··· 2630 2509 return ret; 2631 2510 } 2632 2511 2512 + static void ath12k_mac_vif_setup_ps(struct ath12k_vif *arvif) 2513 + { 2514 + struct ath12k *ar = arvif->ar; 2515 + struct ieee80211_vif *vif = arvif->vif; 2516 + struct ieee80211_conf *conf = &ath12k_ar_to_hw(ar)->conf; 2517 + enum wmi_sta_powersave_param param; 2518 + enum wmi_sta_ps_mode psmode; 2519 + int ret; 2520 + int timeout; 2521 + bool enable_ps; 2522 + 2523 + lockdep_assert_held(&ar->conf_mutex); 2524 + 2525 + if (vif->type != NL80211_IFTYPE_STATION) 2526 + return; 2527 + 2528 + enable_ps = arvif->ps; 2529 + if (enable_ps) { 2530 + psmode = WMI_STA_PS_MODE_ENABLED; 2531 + param = WMI_STA_PS_PARAM_INACTIVITY_TIME; 2532 + 2533 + timeout = conf->dynamic_ps_timeout; 2534 + if (timeout == 0) { 2535 + /* firmware doesn't like 0 */ 2536 + timeout = ieee80211_tu_to_usec(vif->bss_conf.beacon_int) / 1000; 2537 + } 2538 + 2539 + ret = ath12k_wmi_set_sta_ps_param(ar, arvif->vdev_id, param, 2540 + timeout); 2541 + if (ret) { 2542 + ath12k_warn(ar->ab, "failed to set inactivity time for vdev %d: %i\n", 2543 + arvif->vdev_id, ret); 2544 + return; 2545 + } 2546 + } else { 2547 + psmode = WMI_STA_PS_MODE_DISABLED; 2548 + } 2549 + 2550 + ath12k_dbg(ar->ab, ATH12K_DBG_MAC, "mac vdev %d psmode %s\n", 2551 + arvif->vdev_id, psmode ? "enable" : "disable"); 2552 + 2553 + ret = ath12k_wmi_pdev_set_ps_mode(ar, arvif->vdev_id, psmode); 2554 + if (ret) 2555 + ath12k_warn(ar->ab, "failed to set sta power save mode %d for vdev %d: %d\n", 2556 + psmode, arvif->vdev_id, ret); 2557 + } 2558 + 2633 2559 static void ath12k_mac_bss_info_changed(struct ath12k *ar, 2634 2560 struct ath12k_vif *arvif, 2635 2561 struct ieee80211_bss_conf *info, 2636 2562 u64 changed) 2637 2563 { 2638 2564 struct ieee80211_vif *vif = arvif->vif; 2565 + struct ieee80211_vif_cfg *vif_cfg = &vif->cfg; 2639 2566 struct cfg80211_chan_def def; 2640 2567 u32 param_id, param_value; 2641 2568 enum nl80211_band band; ··· 2953 2784 } 2954 2785 2955 2786 ath12k_mac_fils_discovery(arvif, info); 2787 + 2788 + if (changed & BSS_CHANGED_PS && 2789 + ar->ab->hw_params->supports_sta_ps) { 2790 + arvif->ps = vif_cfg->ps; 2791 + ath12k_mac_vif_setup_ps(arvif); 2792 + } 2956 2793 } 2957 2794 2958 2795 static void ath12k_mac_op_bss_info_changed(struct ieee80211_hw *hw, ··· 3198 3023 for (i = 0; i < arg.num_ssids; i++) 3199 3024 arg.ssid[i] = req->ssids[i]; 3200 3025 } else { 3201 - arg.scan_flags |= WMI_SCAN_FLAG_PASSIVE; 3026 + arg.scan_f_passive = 1; 3202 3027 } 3203 3028 3204 3029 if (req->n_channels) { ··· 3996 3821 sta->addr, arvif->vdev_id); 3997 3822 } else if ((old_state == IEEE80211_STA_NONE && 3998 3823 new_state == IEEE80211_STA_NOTEXIST)) { 3824 + if (arvif->vdev_type == WMI_VDEV_TYPE_STA) { 3825 + ath12k_bss_disassoc(ar, arvif); 3826 + ret = ath12k_mac_vdev_stop(arvif); 3827 + if (ret) 3828 + ath12k_warn(ar->ab, "failed to stop vdev %i: %d\n", 3829 + arvif->vdev_id, ret); 3830 + } 3999 3831 ath12k_dp_peer_cleanup(ar, arvif->vdev_id, sta->addr); 4000 3832 4001 3833 ret = ath12k_peer_delete(ar, arvif->vdev_id, sta->addr); ··· 5167 4985 } 5168 4986 5169 4987 arvif = ath12k_vif_to_arvif(skb_cb->vif); 5170 - if (ar->allocated_vdev_map & (1LL << arvif->vdev_id) && 5171 - arvif->is_started) { 4988 + 4989 + if (ar->allocated_vdev_map & (1LL << arvif->vdev_id)) { 5172 4990 ret = ath12k_mac_mgmt_tx_wmi(ar, arvif, skb); 5173 4991 if (ret) { 5174 4992 ath12k_warn(ar->ab, "failed to tx mgmt frame, vdev_id %d :%d\n", ··· 5217 5035 return 0; 5218 5036 } 5219 5037 5038 + static void ath12k_mac_add_p2p_noa_ie(struct ath12k *ar, 5039 + struct ieee80211_vif *vif, 5040 + struct sk_buff *skb, 5041 + bool is_prb_rsp) 5042 + { 5043 + struct ath12k_vif *arvif = ath12k_vif_to_arvif(vif); 5044 + 5045 + if (likely(!is_prb_rsp)) 5046 + return; 5047 + 5048 + spin_lock_bh(&ar->data_lock); 5049 + 5050 + if (arvif->u.ap.noa_data && 5051 + !pskb_expand_head(skb, 0, arvif->u.ap.noa_len, 5052 + GFP_ATOMIC)) 5053 + skb_put_data(skb, arvif->u.ap.noa_data, 5054 + arvif->u.ap.noa_len); 5055 + 5056 + spin_unlock_bh(&ar->data_lock); 5057 + } 5058 + 5220 5059 static void ath12k_mac_op_tx(struct ieee80211_hw *hw, 5221 5060 struct ieee80211_tx_control *control, 5222 5061 struct sk_buff *skb) ··· 5261 5058 skb_cb->flags |= ATH12K_SKB_CIPHER_SET; 5262 5059 } 5263 5060 5061 + is_prb_rsp = ieee80211_is_probe_resp(hdr->frame_control); 5062 + 5264 5063 if (info_flags & IEEE80211_TX_CTL_HW_80211_ENCAP) { 5265 5064 skb_cb->flags |= ATH12K_SKB_HW_80211_ENCAP; 5266 5065 } else if (ieee80211_is_mgmt(hdr->frame_control)) { 5267 - is_prb_rsp = ieee80211_is_probe_resp(hdr->frame_control); 5268 5066 ret = ath12k_mac_mgmt_tx(ar, skb, is_prb_rsp); 5269 5067 if (ret) { 5270 5068 ath12k_warn(ar->ab, "failed to queue management frame %d\n", ··· 5274 5070 } 5275 5071 return; 5276 5072 } 5073 + 5074 + /* This is case only for P2P_GO */ 5075 + if (vif->type == NL80211_IFTYPE_AP && vif->p2p) 5076 + ath12k_mac_add_p2p_noa_ie(ar, vif, skb, is_prb_rsp); 5277 5077 5278 5078 ret = ath12k_dp_tx(ar, arvif, skb); 5279 5079 if (ret) { ··· 5571 5363 do { 5572 5364 if (ab->free_vdev_stats_id_map & (1LL << vdev_stats_id)) { 5573 5365 vdev_stats_id++; 5574 - if (vdev_stats_id <= ATH12K_INVAL_VDEV_STATS_ID) { 5366 + if (vdev_stats_id >= ATH12K_MAX_VDEV_STATS_ID) { 5575 5367 vdev_stats_id = ATH12K_INVAL_VDEV_STATS_ID; 5576 5368 break; 5577 5369 } ··· 5796 5588 case NL80211_IFTYPE_UNSPECIFIED: 5797 5589 case NL80211_IFTYPE_STATION: 5798 5590 arvif->vdev_type = WMI_VDEV_TYPE_STA; 5591 + 5592 + if (vif->p2p) 5593 + arvif->vdev_subtype = WMI_VDEV_SUBTYPE_P2P_CLIENT; 5594 + 5799 5595 break; 5800 5596 case NL80211_IFTYPE_MESH_POINT: 5801 5597 arvif->vdev_subtype = WMI_VDEV_SUBTYPE_MESH_11S; 5802 5598 fallthrough; 5803 5599 case NL80211_IFTYPE_AP: 5804 5600 arvif->vdev_type = WMI_VDEV_TYPE_AP; 5601 + 5602 + if (vif->p2p) 5603 + arvif->vdev_subtype = WMI_VDEV_SUBTYPE_P2P_GO; 5604 + 5805 5605 break; 5806 5606 case NL80211_IFTYPE_MONITOR: 5807 5607 arvif->vdev_type = WMI_VDEV_TYPE_MONITOR; 5808 5608 ar->monitor_vdev_id = bit; 5609 + break; 5610 + case NL80211_IFTYPE_P2P_DEVICE: 5611 + arvif->vdev_type = WMI_VDEV_TYPE_STA; 5612 + arvif->vdev_subtype = WMI_VDEV_SUBTYPE_P2P_DEVICE; 5809 5613 break; 5810 5614 default: 5811 5615 WARN_ON(1); ··· 6370 6150 arg.pref_tx_streams = ar->num_tx_chains; 6371 6151 arg.pref_rx_streams = ar->num_rx_chains; 6372 6152 6153 + /* Fill the MBSSID flags to indicate AP is non MBSSID by default 6154 + * Corresponding flags would be updated with MBSSID support. 6155 + */ 6156 + arg.mbssid_flags = WMI_VDEV_MBSSID_FLAGS_NON_MBSSID_AP; 6157 + 6373 6158 if (arvif->vdev_type == WMI_VDEV_TYPE_AP) { 6374 6159 arg.ssid = arvif->u.ap.ssid; 6375 6160 arg.ssid_len = arvif->u.ap.ssid_len; ··· 6449 6224 arvif->vdev_id, ret); 6450 6225 6451 6226 return 0; 6452 - } 6453 - 6454 - static int ath12k_mac_vdev_stop(struct ath12k_vif *arvif) 6455 - { 6456 - struct ath12k *ar = arvif->ar; 6457 - int ret; 6458 - 6459 - lockdep_assert_held(&ar->conf_mutex); 6460 - 6461 - reinit_completion(&ar->vdev_setup_done); 6462 - 6463 - ret = ath12k_wmi_vdev_stop(ar, arvif->vdev_id); 6464 - if (ret) { 6465 - ath12k_warn(ar->ab, "failed to stop WMI vdev %i: %d\n", 6466 - arvif->vdev_id, ret); 6467 - goto err; 6468 - } 6469 - 6470 - ret = ath12k_mac_vdev_setup_sync(ar); 6471 - if (ret) { 6472 - ath12k_warn(ar->ab, "failed to synchronize setup for vdev %i: %d\n", 6473 - arvif->vdev_id, ret); 6474 - goto err; 6475 - } 6476 - 6477 - WARN_ON(ar->num_started_vdevs == 0); 6478 - 6479 - ar->num_started_vdevs--; 6480 - ath12k_dbg(ar->ab, ATH12K_DBG_MAC, "vdev %pM stopped, vdev_id %d\n", 6481 - arvif->vif->addr, arvif->vdev_id); 6482 - 6483 - if (test_bit(ATH12K_CAC_RUNNING, &ar->dev_flags)) { 6484 - clear_bit(ATH12K_CAC_RUNNING, &ar->dev_flags); 6485 - ath12k_dbg(ar->ab, ATH12K_DBG_MAC, "CAC Stopped for vdev %d\n", 6486 - arvif->vdev_id); 6487 - } 6488 - 6489 - return 0; 6490 - err: 6491 - return ret; 6492 6227 } 6493 6228 6494 6229 static int ath12k_mac_vdev_start(struct ath12k_vif *arvif, ··· 6820 6635 arvif->is_started = false; 6821 6636 } 6822 6637 6823 - ret = ath12k_mac_vdev_stop(arvif); 6824 - if (ret) 6825 - ath12k_warn(ab, "failed to stop vdev %i: %d\n", 6826 - arvif->vdev_id, ret); 6827 - 6638 + if (arvif->vdev_type != WMI_VDEV_TYPE_STA) { 6639 + ath12k_bss_disassoc(ar, arvif); 6640 + ret = ath12k_mac_vdev_stop(arvif); 6641 + if (ret) 6642 + ath12k_warn(ab, "failed to stop vdev %i: %d\n", 6643 + arvif->vdev_id, ret); 6644 + } 6828 6645 arvif->is_started = false; 6829 6646 6830 6647 if (ab->hw_params->vdev_start_delay && ··· 7472 7285 sinfo->filled |= BIT_ULL(NL80211_STA_INFO_SIGNAL); 7473 7286 } 7474 7287 7288 + static int ath12k_mac_op_cancel_remain_on_channel(struct ieee80211_hw *hw, 7289 + struct ieee80211_vif *vif) 7290 + { 7291 + struct ath12k_hw *ah = ath12k_hw_to_ah(hw); 7292 + struct ath12k *ar; 7293 + 7294 + ar = ath12k_ah_to_ar(ah); 7295 + 7296 + mutex_lock(&ar->conf_mutex); 7297 + 7298 + spin_lock_bh(&ar->data_lock); 7299 + ar->scan.roc_notify = false; 7300 + spin_unlock_bh(&ar->data_lock); 7301 + 7302 + ath12k_scan_abort(ar); 7303 + 7304 + mutex_unlock(&ar->conf_mutex); 7305 + 7306 + cancel_delayed_work_sync(&ar->scan.timeout); 7307 + 7308 + return 0; 7309 + } 7310 + 7311 + static int ath12k_mac_op_remain_on_channel(struct ieee80211_hw *hw, 7312 + struct ieee80211_vif *vif, 7313 + struct ieee80211_channel *chan, 7314 + int duration, 7315 + enum ieee80211_roc_type type) 7316 + { 7317 + struct ath12k_vif *arvif = ath12k_vif_to_arvif(vif); 7318 + struct ath12k_hw *ah = ath12k_hw_to_ah(hw); 7319 + struct ath12k_wmi_scan_req_arg arg; 7320 + struct ath12k *ar; 7321 + u32 scan_time_msec; 7322 + int ret; 7323 + 7324 + ar = ath12k_ah_to_ar(ah); 7325 + 7326 + mutex_lock(&ar->conf_mutex); 7327 + spin_lock_bh(&ar->data_lock); 7328 + 7329 + switch (ar->scan.state) { 7330 + case ATH12K_SCAN_IDLE: 7331 + reinit_completion(&ar->scan.started); 7332 + reinit_completion(&ar->scan.completed); 7333 + reinit_completion(&ar->scan.on_channel); 7334 + ar->scan.state = ATH12K_SCAN_STARTING; 7335 + ar->scan.is_roc = true; 7336 + ar->scan.vdev_id = arvif->vdev_id; 7337 + ar->scan.roc_freq = chan->center_freq; 7338 + ar->scan.roc_notify = true; 7339 + ret = 0; 7340 + break; 7341 + case ATH12K_SCAN_STARTING: 7342 + case ATH12K_SCAN_RUNNING: 7343 + case ATH12K_SCAN_ABORTING: 7344 + ret = -EBUSY; 7345 + break; 7346 + } 7347 + 7348 + spin_unlock_bh(&ar->data_lock); 7349 + 7350 + if (ret) 7351 + goto exit; 7352 + 7353 + scan_time_msec = hw->wiphy->max_remain_on_channel_duration * 2; 7354 + 7355 + memset(&arg, 0, sizeof(arg)); 7356 + ath12k_wmi_start_scan_init(ar, &arg); 7357 + arg.num_chan = 1; 7358 + arg.chan_list = kcalloc(arg.num_chan, sizeof(*arg.chan_list), 7359 + GFP_KERNEL); 7360 + if (!arg.chan_list) { 7361 + ret = -ENOMEM; 7362 + goto exit; 7363 + } 7364 + 7365 + arg.vdev_id = arvif->vdev_id; 7366 + arg.scan_id = ATH12K_SCAN_ID; 7367 + arg.chan_list[0] = chan->center_freq; 7368 + arg.dwell_time_active = scan_time_msec; 7369 + arg.dwell_time_passive = scan_time_msec; 7370 + arg.max_scan_time = scan_time_msec; 7371 + arg.scan_f_passive = 1; 7372 + arg.burst_duration = duration; 7373 + 7374 + ret = ath12k_start_scan(ar, &arg); 7375 + if (ret) { 7376 + ath12k_warn(ar->ab, "failed to start roc scan: %d\n", ret); 7377 + 7378 + spin_lock_bh(&ar->data_lock); 7379 + ar->scan.state = ATH12K_SCAN_IDLE; 7380 + spin_unlock_bh(&ar->data_lock); 7381 + goto free_chan_list; 7382 + } 7383 + 7384 + ret = wait_for_completion_timeout(&ar->scan.on_channel, 3 * HZ); 7385 + if (ret == 0) { 7386 + ath12k_warn(ar->ab, "failed to switch to channel for roc scan\n"); 7387 + ret = ath12k_scan_stop(ar); 7388 + if (ret) 7389 + ath12k_warn(ar->ab, "failed to stop scan: %d\n", ret); 7390 + ret = -ETIMEDOUT; 7391 + goto free_chan_list; 7392 + } 7393 + 7394 + ieee80211_queue_delayed_work(hw, &ar->scan.timeout, 7395 + msecs_to_jiffies(duration)); 7396 + 7397 + ret = 0; 7398 + 7399 + free_chan_list: 7400 + kfree(arg.chan_list); 7401 + exit: 7402 + mutex_unlock(&ar->conf_mutex); 7403 + 7404 + return ret; 7405 + } 7406 + 7475 7407 static const struct ieee80211_ops ath12k_ops = { 7476 7408 .tx = ath12k_mac_op_tx, 7477 7409 .wake_tx_queue = ieee80211_handle_wake_tx_queue, ··· 7625 7319 .get_survey = ath12k_mac_op_get_survey, 7626 7320 .flush = ath12k_mac_op_flush, 7627 7321 .sta_statistics = ath12k_mac_op_sta_statistics, 7322 + .remain_on_channel = ath12k_mac_op_remain_on_channel, 7323 + .cancel_remain_on_channel = ath12k_mac_op_cancel_remain_on_channel, 7628 7324 }; 7629 7325 7630 7326 static void ath12k_mac_update_ch_list(struct ath12k *ar, ··· 7787 7479 struct ieee80211_iface_combination *combinations; 7788 7480 struct ieee80211_iface_limit *limits; 7789 7481 int n_limits, max_interfaces; 7790 - bool ap, mesh; 7482 + bool ap, mesh, p2p; 7791 7483 7792 7484 ap = ath12k_mac_is_iface_mode_enable(ah, NL80211_IFTYPE_AP); 7485 + p2p = ath12k_mac_is_iface_mode_enable(ah, NL80211_IFTYPE_P2P_DEVICE); 7793 7486 7794 7487 mesh = IS_ENABLED(CONFIG_MAC80211_MESH) && 7795 7488 ath12k_mac_is_iface_mode_enable(ah, NL80211_IFTYPE_MESH_POINT); ··· 7799 7490 if (!combinations) 7800 7491 return -ENOMEM; 7801 7492 7802 - if (ap || mesh) { 7493 + if ((ap || mesh) && !p2p) { 7803 7494 n_limits = 2; 7804 7495 max_interfaces = 16; 7496 + } else if (p2p) { 7497 + n_limits = 3; 7498 + if (ap || mesh) 7499 + max_interfaces = 16; 7500 + else 7501 + max_interfaces = 3; 7805 7502 } else { 7806 7503 n_limits = 1; 7807 7504 max_interfaces = 1; ··· 7822 7507 limits[0].max = 1; 7823 7508 limits[0].types |= BIT(NL80211_IFTYPE_STATION); 7824 7509 7825 - if (ap) { 7510 + if (ap || mesh || p2p) 7826 7511 limits[1].max = max_interfaces; 7512 + 7513 + if (ap) 7827 7514 limits[1].types |= BIT(NL80211_IFTYPE_AP); 7828 - } 7829 7515 7830 7516 if (mesh) 7831 7517 limits[1].types |= BIT(NL80211_IFTYPE_MESH_POINT); 7518 + 7519 + if (p2p) { 7520 + limits[1].types |= BIT(NL80211_IFTYPE_P2P_CLIENT) | 7521 + BIT(NL80211_IFTYPE_P2P_GO); 7522 + limits[2].max = 1; 7523 + limits[2].types |= BIT(NL80211_IFTYPE_P2P_DEVICE); 7524 + } 7832 7525 7833 7526 combinations[0].limits = limits; 7834 7527 combinations[0].n_limits = n_limits; ··· 7942 7619 ath12k_mac_setup_ht_vht_cap(ar, cap, ht_cap); 7943 7620 ath12k_mac_setup_sband_iftype_data(ar, cap); 7944 7621 7945 - ar->max_num_stations = TARGET_NUM_STATIONS; 7946 - ar->max_num_peers = TARGET_NUM_PEERS_PDEV; 7622 + ar->max_num_stations = ath12k_core_get_max_station_per_radio(ar->ab); 7623 + ar->max_num_peers = ath12k_core_get_max_peers_per_radio(ar->ab); 7947 7624 7948 7625 return 0; 7949 7626 } ··· 8154 7831 init_completion(&ar->bss_survey_done); 8155 7832 init_completion(&ar->scan.started); 8156 7833 init_completion(&ar->scan.completed); 7834 + init_completion(&ar->scan.on_channel); 8157 7835 8158 7836 INIT_DELAYED_WORK(&ar->scan.timeout, ath12k_scan_timeout_work); 8159 7837 INIT_WORK(&ar->regd_update_work, ath12k_regd_update_work); ··· 8302 7978 if (!ah) { 8303 7979 ath12k_warn(ab, "failed to allocate mac80211 hw device for hw_idx %d\n", 8304 7980 i); 7981 + ret = -ENOMEM; 8305 7982 goto err; 8306 7983 } 8307 7984
+46 -6
drivers/net/wireless/ath/ath12k/mhi.c
··· 1 1 // SPDX-License-Identifier: BSD-3-Clause-Clear 2 2 /* 3 3 * Copyright (c) 2020-2021 The Linux Foundation. All rights reserved. 4 - * Copyright (c) 2021-2023 Qualcomm Innovation Center, Inc. All rights reserved. 4 + * Copyright (c) 2021-2024 Qualcomm Innovation Center, Inc. All rights reserved. 5 5 */ 6 6 7 7 #include <linux/msi.h> 8 8 #include <linux/pci.h> 9 + #include <linux/firmware.h> 9 10 10 11 #include "core.h" 11 12 #include "debug.h" ··· 14 13 #include "pci.h" 15 14 16 15 #define MHI_TIMEOUT_DEFAULT_MS 90000 16 + #define OTP_INVALID_BOARD_ID 0xFFFF 17 + #define OTP_VALID_DUALMAC_BOARD_ID_MASK 0x1000 17 18 18 19 static const struct mhi_channel_config ath12k_mhi_channels_qcn9274[] = { 19 20 { ··· 361 358 { 362 359 struct ath12k_base *ab = ab_pci->ab; 363 360 struct mhi_controller *mhi_ctrl; 361 + unsigned int board_id; 364 362 int ret; 363 + bool dualmac = false; 365 364 366 365 mhi_ctrl = mhi_alloc_controller(); 367 366 if (!mhi_ctrl) 368 367 return -ENOMEM; 369 368 370 - ath12k_core_create_firmware_path(ab, ATH12K_AMSS_FILE, 371 - ab_pci->amss_path, 372 - sizeof(ab_pci->amss_path)); 373 - 374 369 ab_pci->mhi_ctrl = mhi_ctrl; 375 370 mhi_ctrl->cntrl_dev = ab->dev; 376 - mhi_ctrl->fw_image = ab_pci->amss_path; 377 371 mhi_ctrl->regs = ab->mem; 378 372 mhi_ctrl->reg_len = ab->mem_len; 379 373 mhi_ctrl->rddm_size = ab->hw_params->rddm_size; 374 + 375 + if (ab->hw_params->otp_board_id_register) { 376 + board_id = 377 + ath12k_pci_read32(ab, ab->hw_params->otp_board_id_register); 378 + board_id = u32_get_bits(board_id, OTP_BOARD_ID_MASK); 379 + 380 + if (!board_id || (board_id == OTP_INVALID_BOARD_ID)) { 381 + ath12k_dbg(ab, ATH12K_DBG_BOOT, 382 + "failed to read board id\n"); 383 + } else if (board_id & OTP_VALID_DUALMAC_BOARD_ID_MASK) { 384 + dualmac = true; 385 + ab->slo_capable = false; 386 + ath12k_dbg(ab, ATH12K_DBG_BOOT, 387 + "dualmac fw selected for board id: %x\n", board_id); 388 + } 389 + } 390 + 391 + if (dualmac) { 392 + if (ab->fw.amss_dualmac_data && ab->fw.amss_dualmac_len > 0) { 393 + /* use MHI firmware file from firmware-N.bin */ 394 + mhi_ctrl->fw_data = ab->fw.amss_dualmac_data; 395 + mhi_ctrl->fw_sz = ab->fw.amss_dualmac_len; 396 + } else { 397 + ath12k_warn(ab, "dualmac firmware IE not present in firmware-N.bin\n"); 398 + ret = -ENOENT; 399 + goto free_controller; 400 + } 401 + } else { 402 + if (ab->fw.amss_data && ab->fw.amss_len > 0) { 403 + /* use MHI firmware file from firmware-N.bin */ 404 + mhi_ctrl->fw_data = ab->fw.amss_data; 405 + mhi_ctrl->fw_sz = ab->fw.amss_len; 406 + } else { 407 + /* use the old separate mhi.bin MHI firmware file */ 408 + ath12k_core_create_firmware_path(ab, ATH12K_AMSS_FILE, 409 + ab_pci->amss_path, 410 + sizeof(ab_pci->amss_path)); 411 + mhi_ctrl->fw_image = ab_pci->amss_path; 412 + } 413 + } 380 414 381 415 ret = ath12k_mhi_get_msi(ab_pci); 382 416 if (ret) {
+142
drivers/net/wireless/ath/ath12k/p2p.c
··· 1 + // SPDX-License-Identifier: ISC 2 + /* 3 + * Copyright (c) 2024 Qualcomm Innovation Center, Inc. All rights reserved. 4 + */ 5 + 6 + #include <net/mac80211.h> 7 + #include "core.h" 8 + #include "mac.h" 9 + #include "p2p.h" 10 + 11 + static void ath12k_p2p_noa_ie_fill(u8 *data, size_t len, 12 + const struct ath12k_wmi_p2p_noa_info *noa) 13 + { 14 + struct ieee80211_p2p_noa_attr *noa_attr; 15 + u8 ctwindow = le32_get_bits(noa->noa_attr, WMI_P2P_NOA_INFO_CTWIN_TU); 16 + bool oppps = le32_get_bits(noa->noa_attr, WMI_P2P_NOA_INFO_OPP_PS); 17 + __le16 *noa_attr_len; 18 + u16 attr_len; 19 + u8 noa_descriptors = le32_get_bits(noa->noa_attr, 20 + WMI_P2P_NOA_INFO_DESC_NUM); 21 + int i; 22 + 23 + /* P2P IE */ 24 + data[0] = WLAN_EID_VENDOR_SPECIFIC; 25 + data[1] = len - 2; 26 + data[2] = (WLAN_OUI_WFA >> 16) & 0xff; 27 + data[3] = (WLAN_OUI_WFA >> 8) & 0xff; 28 + data[4] = (WLAN_OUI_WFA >> 0) & 0xff; 29 + data[5] = WLAN_OUI_TYPE_WFA_P2P; 30 + 31 + /* NOA ATTR */ 32 + data[6] = IEEE80211_P2P_ATTR_ABSENCE_NOTICE; 33 + noa_attr_len = (__le16 *)&data[7]; /* 2 bytes */ 34 + noa_attr = (struct ieee80211_p2p_noa_attr *)&data[9]; 35 + 36 + noa_attr->index = le32_get_bits(noa->noa_attr, 37 + WMI_P2P_NOA_INFO_INDEX); 38 + noa_attr->oppps_ctwindow = ctwindow; 39 + if (oppps) 40 + noa_attr->oppps_ctwindow |= IEEE80211_P2P_OPPPS_ENABLE_BIT; 41 + 42 + for (i = 0; i < noa_descriptors; i++) { 43 + noa_attr->desc[i].count = 44 + __le32_to_cpu(noa->descriptors[i].type_count); 45 + noa_attr->desc[i].duration = noa->descriptors[i].duration; 46 + noa_attr->desc[i].interval = noa->descriptors[i].interval; 47 + noa_attr->desc[i].start_time = noa->descriptors[i].start_time; 48 + } 49 + 50 + attr_len = 2; /* index + oppps_ctwindow */ 51 + attr_len += noa_descriptors * sizeof(struct ieee80211_p2p_noa_desc); 52 + *noa_attr_len = __cpu_to_le16(attr_len); 53 + } 54 + 55 + static size_t ath12k_p2p_noa_ie_len_compute(const struct ath12k_wmi_p2p_noa_info *noa) 56 + { 57 + size_t len = 0; 58 + 59 + if (!(le32_get_bits(noa->noa_attr, WMI_P2P_NOA_INFO_DESC_NUM)) && 60 + !(le32_get_bits(noa->noa_attr, WMI_P2P_NOA_INFO_OPP_PS))) 61 + return 0; 62 + 63 + len += 1 + 1 + 4; /* EID + len + OUI */ 64 + len += 1 + 2; /* noa attr + attr len */ 65 + len += 1 + 1; /* index + oppps_ctwindow */ 66 + len += le32_get_bits(noa->noa_attr, WMI_P2P_NOA_INFO_DESC_NUM) * 67 + sizeof(struct ieee80211_p2p_noa_desc); 68 + 69 + return len; 70 + } 71 + 72 + static void ath12k_p2p_noa_ie_assign(struct ath12k_vif *arvif, void *ie, 73 + size_t len) 74 + { 75 + struct ath12k *ar = arvif->ar; 76 + 77 + lockdep_assert_held(&ar->data_lock); 78 + 79 + kfree(arvif->u.ap.noa_data); 80 + 81 + arvif->u.ap.noa_data = ie; 82 + arvif->u.ap.noa_len = len; 83 + } 84 + 85 + static void __ath12k_p2p_noa_update(struct ath12k_vif *arvif, 86 + const struct ath12k_wmi_p2p_noa_info *noa) 87 + { 88 + struct ath12k *ar = arvif->ar; 89 + void *ie; 90 + size_t len; 91 + 92 + lockdep_assert_held(&ar->data_lock); 93 + 94 + ath12k_p2p_noa_ie_assign(arvif, NULL, 0); 95 + 96 + len = ath12k_p2p_noa_ie_len_compute(noa); 97 + if (!len) 98 + return; 99 + 100 + ie = kmalloc(len, GFP_ATOMIC); 101 + if (!ie) 102 + return; 103 + 104 + ath12k_p2p_noa_ie_fill(ie, len, noa); 105 + ath12k_p2p_noa_ie_assign(arvif, ie, len); 106 + } 107 + 108 + void ath12k_p2p_noa_update(struct ath12k_vif *arvif, 109 + const struct ath12k_wmi_p2p_noa_info *noa) 110 + { 111 + struct ath12k *ar = arvif->ar; 112 + 113 + spin_lock_bh(&ar->data_lock); 114 + __ath12k_p2p_noa_update(arvif, noa); 115 + spin_unlock_bh(&ar->data_lock); 116 + } 117 + 118 + static void ath12k_p2p_noa_update_vdev_iter(void *data, u8 *mac, 119 + struct ieee80211_vif *vif) 120 + { 121 + struct ath12k_vif *arvif = ath12k_vif_to_arvif(vif); 122 + struct ath12k_p2p_noa_arg *arg = data; 123 + 124 + if (arvif->vdev_id != arg->vdev_id) 125 + return; 126 + 127 + ath12k_p2p_noa_update(arvif, arg->noa); 128 + } 129 + 130 + void ath12k_p2p_noa_update_by_vdev_id(struct ath12k *ar, u32 vdev_id, 131 + const struct ath12k_wmi_p2p_noa_info *noa) 132 + { 133 + struct ath12k_p2p_noa_arg arg = { 134 + .vdev_id = vdev_id, 135 + .noa = noa, 136 + }; 137 + 138 + ieee80211_iterate_active_interfaces_atomic(ath12k_ar_to_hw(ar), 139 + IEEE80211_IFACE_ITER_NORMAL, 140 + ath12k_p2p_noa_update_vdev_iter, 141 + &arg); 142 + }
+23
drivers/net/wireless/ath/ath12k/p2p.h
··· 1 + /* SPDX-License-Identifier: ISC */ 2 + /* 3 + * Copyright (c) 2024 Qualcomm Innovation Center, Inc. All rights reserved.. 4 + */ 5 + 6 + #ifndef ATH12K_P2P_H 7 + #define ATH12K_P2P_H 8 + 9 + #include "wmi.h" 10 + 11 + struct ath12k_wmi_p2p_noa_info; 12 + 13 + struct ath12k_p2p_noa_arg { 14 + u32 vdev_id; 15 + const struct ath12k_wmi_p2p_noa_info *noa; 16 + }; 17 + 18 + void ath12k_p2p_noa_update(struct ath12k_vif *arvif, 19 + const struct ath12k_wmi_p2p_noa_info *noa); 20 + void ath12k_p2p_noa_update_by_vdev_id(struct ath12k *ar, u32 vdev_id, 21 + const struct ath12k_wmi_p2p_noa_info *noa); 22 + 23 + #endif
+63 -21
drivers/net/wireless/ath/ath12k/pci.c
··· 1 1 // SPDX-License-Identifier: BSD-3-Clause-Clear 2 2 /* 3 3 * Copyright (c) 2019-2021 The Linux Foundation. All rights reserved. 4 - * Copyright (c) 2021-2023 Qualcomm Innovation Center, Inc. All rights reserved. 4 + * Copyright (c) 2021-2024 Qualcomm Innovation Center, Inc. All rights reserved. 5 5 */ 6 6 7 7 #include <linux/module.h> ··· 38 38 39 39 #define QCN9274_DEVICE_ID 0x1109 40 40 #define WCN7850_DEVICE_ID 0x1107 41 + 42 + #define PCIE_LOCAL_REG_QRTR_NODE_ID 0x1E03164 43 + #define DOMAIN_NUMBER_MASK GENMASK(7, 4) 44 + #define BUS_NUMBER_MASK GENMASK(3, 0) 41 45 42 46 static const struct pci_device_id ath12k_pci_id_table[] = { 43 47 { PCI_VDEVICE(QCOM, QCN9274_DEVICE_ID) }, ··· 205 201 /* If offset lies within CE register range, use 2nd window */ 206 202 else if ((offset ^ HAL_CE_WFSS_CE_REG_BASE) < WINDOW_RANGE_MASK) 207 203 window_start = 2 * WINDOW_START; 208 - /* If offset lies within PCI_BAR_WINDOW0_BASE and within PCI_SOC_PCI_REG_BASE 209 - * use 0th window 210 - */ 211 - else if (((offset ^ PCI_BAR_WINDOW0_BASE) < WINDOW_RANGE_MASK) && 212 - !((offset ^ PCI_SOC_PCI_REG_BASE) < PCI_SOC_RANGE_MASK)) 213 - window_start = 0; 214 204 else 215 205 window_start = WINDOW_START; 216 206 217 207 return window_start; 208 + } 209 + 210 + static inline bool ath12k_pci_is_offset_within_mhi_region(u32 offset) 211 + { 212 + return (offset >= PCI_MHIREGLEN_REG && offset <= PCI_MHI_REGION_END); 218 213 } 219 214 220 215 static void ath12k_pci_soc_global_reset(struct ath12k_base *ab) ··· 685 682 { 686 683 struct ath12k_qmi_ce_cfg *cfg = &ab->qmi.ce_cfg; 687 684 685 + struct ath12k_pci *ab_pci = ath12k_pci_priv(ab); 686 + struct pci_bus *bus = ab_pci->pdev->bus; 687 + 688 688 cfg->tgt_ce = ab->hw_params->target_ce_config; 689 689 cfg->tgt_ce_len = ab->hw_params->target_ce_count; 690 690 691 691 cfg->svc_to_ce_map = ab->hw_params->svc_to_ce_map; 692 692 cfg->svc_to_ce_map_len = ab->hw_params->svc_to_ce_map_len; 693 693 ab->qmi.service_ins_id = ab->hw_params->qmi_service_ins_id; 694 + 695 + if (test_bit(ATH12K_FW_FEATURE_MULTI_QRTR_ID, ab->fw.fw_features)) { 696 + ab_pci->qmi_instance = 697 + u32_encode_bits(pci_domain_nr(bus), DOMAIN_NUMBER_MASK) | 698 + u32_encode_bits(bus->number, BUS_NUMBER_MASK); 699 + ab->qmi.service_ins_id += ab_pci->qmi_instance; 700 + } 694 701 } 695 702 696 703 static void ath12k_pci_ce_irqs_enable(struct ath12k_base *ab) ··· 912 899 PCI_EXP_LNKCTL_ASPMC); 913 900 914 901 set_bit(ATH12K_PCI_ASPM_RESTORE, &ab_pci->flags); 902 + } 903 + 904 + static void ath12k_pci_update_qrtr_node_id(struct ath12k_base *ab) 905 + { 906 + struct ath12k_pci *ab_pci = ath12k_pci_priv(ab); 907 + u32 reg; 908 + 909 + /* On platforms with two or more identical mhi devices, qmi service run 910 + * with identical qrtr-node-id. Because of this identical ID qrtr-lookup 911 + * cannot register more than one qmi service with identical node ID. 912 + * 913 + * This generates a unique instance ID from PCIe domain number and bus number, 914 + * writes to the given register, it is available for firmware when the QMI service 915 + * is spawned. 916 + */ 917 + reg = PCIE_LOCAL_REG_QRTR_NODE_ID & WINDOW_RANGE_MASK; 918 + ath12k_pci_write32(ab, reg, ab_pci->qmi_instance); 919 + 920 + ath12k_dbg(ab, ATH12K_DBG_PCI, "pci reg 0x%x instance 0x%x read val 0x%x\n", 921 + reg, ab_pci->qmi_instance, ath12k_pci_read32(ab, reg)); 915 922 } 916 923 917 924 static void ath12k_pci_aspm_restore(struct ath12k_pci *ab_pci) ··· 1171 1138 if (window_start == WINDOW_START) { 1172 1139 spin_lock_bh(&ab_pci->window_lock); 1173 1140 ath12k_pci_select_window(ab_pci, offset); 1174 - val = ioread32(ab->mem + window_start + 1175 - (offset & WINDOW_RANGE_MASK)); 1141 + 1142 + if (ath12k_pci_is_offset_within_mhi_region(offset)) { 1143 + offset = offset - PCI_MHIREGLEN_REG; 1144 + val = ioread32(ab->mem + 1145 + (offset & WINDOW_RANGE_MASK)); 1146 + } else { 1147 + val = ioread32(ab->mem + window_start + 1148 + (offset & WINDOW_RANGE_MASK)); 1149 + } 1176 1150 spin_unlock_bh(&ab_pci->window_lock); 1177 1151 } else { 1178 - if ((!window_start) && 1179 - (offset >= PCI_MHIREGLEN_REG && 1180 - offset <= PCI_MHI_REGION_END)) 1181 - offset = offset - PCI_MHIREGLEN_REG; 1182 - 1183 1152 val = ioread32(ab->mem + window_start + 1184 1153 (offset & WINDOW_RANGE_MASK)); 1185 1154 } ··· 1218 1183 if (window_start == WINDOW_START) { 1219 1184 spin_lock_bh(&ab_pci->window_lock); 1220 1185 ath12k_pci_select_window(ab_pci, offset); 1221 - iowrite32(value, ab->mem + window_start + 1222 - (offset & WINDOW_RANGE_MASK)); 1186 + 1187 + if (ath12k_pci_is_offset_within_mhi_region(offset)) { 1188 + offset = offset - PCI_MHIREGLEN_REG; 1189 + iowrite32(value, ab->mem + 1190 + (offset & WINDOW_RANGE_MASK)); 1191 + } else { 1192 + iowrite32(value, ab->mem + window_start + 1193 + (offset & WINDOW_RANGE_MASK)); 1194 + } 1223 1195 spin_unlock_bh(&ab_pci->window_lock); 1224 1196 } else { 1225 - if ((!window_start) && 1226 - (offset >= PCI_MHIREGLEN_REG && 1227 - offset <= PCI_MHI_REGION_END)) 1228 - offset = offset - PCI_MHIREGLEN_REG; 1229 - 1230 1197 iowrite32(value, ab->mem + window_start + 1231 1198 (offset & WINDOW_RANGE_MASK)); 1232 1199 } ··· 1255 1218 ath12k_pci_aspm_disable(ab_pci); 1256 1219 1257 1220 ath12k_pci_msi_enable(ab_pci); 1221 + 1222 + if (test_bit(ATH12K_FW_FEATURE_MULTI_QRTR_ID, ab->fw.fw_features)) 1223 + ath12k_pci_update_qrtr_node_id(ab); 1258 1224 1259 1225 ret = ath12k_mhi_start(ab_pci); 1260 1226 if (ret) { ··· 1364 1324 ab_pci->msi_config = &ath12k_msi_config[0]; 1365 1325 ab->static_window_map = true; 1366 1326 ab_pci->pci_ops = &ath12k_pci_ops_qcn9274; 1327 + ab->hal_rx_ops = &hal_rx_qcn9274_ops; 1367 1328 ath12k_pci_read_hw_version(ab, &soc_hw_version_major, 1368 1329 &soc_hw_version_minor); 1369 1330 switch (soc_hw_version_major) { ··· 1387 1346 ab_pci->msi_config = &ath12k_msi_config[0]; 1388 1347 ab->static_window_map = false; 1389 1348 ab_pci->pci_ops = &ath12k_pci_ops_wcn7850; 1349 + ab->hal_rx_ops = &hal_rx_wcn7850_ops; 1390 1350 ath12k_pci_read_hw_version(ab, &soc_hw_version_major, 1391 1351 &soc_hw_version_minor); 1392 1352 switch (soc_hw_version_major) {
+5 -1
drivers/net/wireless/ath/ath12k/pci.h
··· 1 1 /* SPDX-License-Identifier: BSD-3-Clause-Clear */ 2 2 /* 3 3 * Copyright (c) 2019-2021 The Linux Foundation. All rights reserved. 4 - * Copyright (c) 2021-2023 Qualcomm Innovation Center, Inc. All rights reserved. 4 + * Copyright (c) 2021-2024 Qualcomm Innovation Center, Inc. All rights reserved. 5 5 */ 6 6 #ifndef ATH12K_PCI_H 7 7 #define ATH12K_PCI_H ··· 52 52 53 53 #define WLAON_QFPROM_PWR_CTRL_REG 0x01f8031c 54 54 #define QFPROM_PWR_CTRL_VDD4BLOW_MASK 0x4 55 + 56 + #define QCN9274_QFPROM_RAW_RFA_PDET_ROW13_LSB 0x1E20338 57 + #define OTP_BOARD_ID_MASK GENMASK(15, 0) 55 58 56 59 #define PCI_BAR_WINDOW0_BASE 0x1E00000 57 60 #define PCI_BAR_WINDOW0_END 0x1E7FFFC ··· 114 111 u16 link_ctl; 115 112 unsigned long irq_flags; 116 113 const struct ath12k_pci_ops *pci_ops; 114 + u32 qmi_instance; 117 115 }; 118 116 119 117 static inline struct ath12k_pci *ath12k_pci_priv(struct ath12k_base *ab)
+37 -15
drivers/net/wireless/ath/ath12k/qmi.c
··· 2124 2124 struct qmi_txn txn; 2125 2125 int ret; 2126 2126 2127 + if (!ab->slo_capable) 2128 + goto out; 2129 + 2127 2130 ret = qmi_txn_init(&ab->qmi.handle, &txn, 2128 2131 qmi_wlanfw_phy_cap_resp_msg_v01_ei, &resp); 2129 2132 if (ret < 0) ··· 2669 2666 static int ath12k_qmi_m3_load(struct ath12k_base *ab) 2670 2667 { 2671 2668 struct m3_mem_region *m3_mem = &ab->qmi.m3_mem; 2672 - const struct firmware *fw; 2669 + const struct firmware *fw = NULL; 2670 + const void *m3_data; 2673 2671 char path[100]; 2672 + size_t m3_len; 2674 2673 int ret; 2675 2674 2676 - if (m3_mem->vaddr || m3_mem->size) 2675 + if (m3_mem->vaddr) 2676 + /* m3 firmware buffer is already available in the DMA buffer */ 2677 2677 return 0; 2678 2678 2679 - fw = ath12k_core_firmware_request(ab, ATH12K_M3_FILE); 2680 - if (IS_ERR(fw)) { 2681 - ret = PTR_ERR(fw); 2682 - ath12k_core_create_firmware_path(ab, ATH12K_M3_FILE, 2683 - path, sizeof(path)); 2684 - ath12k_err(ab, "failed to load %s: %d\n", path, ret); 2685 - return ret; 2679 + if (ab->fw.m3_data && ab->fw.m3_len > 0) { 2680 + /* firmware-N.bin had a m3 firmware file so use that */ 2681 + m3_data = ab->fw.m3_data; 2682 + m3_len = ab->fw.m3_len; 2683 + } else { 2684 + /* No m3 file in firmware-N.bin so try to request old 2685 + * separate m3.bin. 2686 + */ 2687 + fw = ath12k_core_firmware_request(ab, ATH12K_M3_FILE); 2688 + if (IS_ERR(fw)) { 2689 + ret = PTR_ERR(fw); 2690 + ath12k_core_create_firmware_path(ab, ATH12K_M3_FILE, 2691 + path, sizeof(path)); 2692 + ath12k_err(ab, "failed to load %s: %d\n", path, ret); 2693 + return ret; 2694 + } 2695 + 2696 + m3_data = fw->data; 2697 + m3_len = fw->size; 2686 2698 } 2687 2699 2688 2700 m3_mem->vaddr = dma_alloc_coherent(ab->dev, 2689 - fw->size, &m3_mem->paddr, 2701 + m3_len, &m3_mem->paddr, 2690 2702 GFP_KERNEL); 2691 2703 if (!m3_mem->vaddr) { 2692 2704 ath12k_err(ab, "failed to allocate memory for M3 with size %zu\n", 2693 2705 fw->size); 2694 - release_firmware(fw); 2695 - return -ENOMEM; 2706 + ret = -ENOMEM; 2707 + goto out; 2696 2708 } 2697 2709 2698 - memcpy(m3_mem->vaddr, fw->data, fw->size); 2699 - m3_mem->size = fw->size; 2710 + memcpy(m3_mem->vaddr, m3_data, m3_len); 2711 + m3_mem->size = m3_len; 2712 + 2713 + ret = 0; 2714 + 2715 + out: 2700 2716 release_firmware(fw); 2701 2717 2702 - return 0; 2718 + return ret; 2703 2719 } 2704 2720 2705 2721 static void ath12k_qmi_m3_free(struct ath12k_base *ab)
-1
drivers/net/wireless/ath/ath12k/qmi.h
··· 15 15 #define ATH12K_QMI_MAX_BDF_FILE_NAME_SIZE 64 16 16 #define ATH12K_QMI_CALDB_ADDRESS 0x4BA00000 17 17 #define ATH12K_QMI_WLANFW_MAX_BUILD_ID_LEN_V01 128 18 - #define ATH12K_QMI_WLFW_NODE_ID_BASE 0x07 19 18 #define ATH12K_QMI_WLFW_SERVICE_ID_V01 0x45 20 19 #define ATH12K_QMI_WLFW_SERVICE_VERS_V01 0x01 21 20 #define ATH12K_QMI_WLFW_SERVICE_INS_ID_V01 0x02
+111 -5
drivers/net/wireless/ath/ath12k/rx_desc.h
··· 1 1 /* SPDX-License-Identifier: BSD-3-Clause-Clear */ 2 2 /* 3 3 * Copyright (c) 2018-2021 The Linux Foundation. All rights reserved. 4 - * Copyright (c) 2021-2023 Qualcomm Innovation Center, Inc. All rights reserved. 4 + * Copyright (c) 2021-2024 Qualcomm Innovation Center, Inc. All rights reserved. 5 5 */ 6 6 #ifndef ATH12K_RX_DESC_H 7 7 #define ATH12K_RX_DESC_H ··· 145 145 __le32 info8; 146 146 __le32 res0; 147 147 __le32 res1; 148 + } __packed; 149 + 150 + #define QCN9274_MPDU_START_SELECT_MPDU_START_TAG BIT(0) 151 + #define QCN9274_MPDU_START_SELECT_INFO0_REO_QUEUE_DESC_LO BIT(1) 152 + #define QCN9274_MPDU_START_SELECT_INFO1_PN_31_0 BIT(2) 153 + #define QCN9274_MPDU_START_SELECT_PN_95_32 BIT(3) 154 + #define QCN9274_MPDU_START_SELECT_PN_127_96_INFO2 BIT(4) 155 + #define QCN9274_MPDU_START_SELECT_PEER_MDATA_INFO3_PHY_PPDU_ID BIT(5) 156 + #define QCN9274_MPDU_START_SELECT_AST_IDX_SW_PEER_ID_INFO4 BIT(6) 157 + #define QCN9274_MPDU_START_SELECT_INFO5_INFO6 BIT(7) 158 + #define QCN9274_MPDU_START_SELECT_FRAME_CTRL_DURATION_ADDR1_31_0 BIT(8) 159 + #define QCN9274_MPDU_START_SELECT_ADDR2_47_0_ADDR1_47_32 BIT(9) 160 + #define QCN9274_MPDU_START_SELECT_ADDR3_47_0_SEQ_CTRL BIT(10) 161 + #define QCN9274_MPDU_START_SELECT_ADDR4_47_0_QOS_CTRL BIT(11) 162 + #define QCN9274_MPDU_START_SELECT_HT_CTRL_INFO7 BIT(12) 163 + #define QCN9274_MPDU_START_SELECT_ML_ADDR1_47_0_ML_ADDR2_15_0 BIT(13) 164 + #define QCN9274_MPDU_START_SELECT_ML_ADDR2_47_16_INFO8 BIT(14) 165 + #define QCN9274_MPDU_START_SELECT_RES_0_RES_1 BIT(15) 166 + 167 + #define QCN9274_MPDU_START_WMASK (QCN9274_MPDU_START_SELECT_INFO1_PN_31_0 | \ 168 + QCN9274_MPDU_START_SELECT_PN_95_32 | \ 169 + QCN9274_MPDU_START_SELECT_PN_127_96_INFO2 | \ 170 + QCN9274_MPDU_START_SELECT_PEER_MDATA_INFO3_PHY_PPDU_ID | \ 171 + QCN9274_MPDU_START_SELECT_AST_IDX_SW_PEER_ID_INFO4 | \ 172 + QCN9274_MPDU_START_SELECT_INFO5_INFO6 | \ 173 + QCN9274_MPDU_START_SELECT_FRAME_CTRL_DURATION_ADDR1_31_0 | \ 174 + QCN9274_MPDU_START_SELECT_ADDR2_47_0_ADDR1_47_32 | \ 175 + QCN9274_MPDU_START_SELECT_ADDR3_47_0_SEQ_CTRL | \ 176 + QCN9274_MPDU_START_SELECT_ADDR4_47_0_QOS_CTRL) 177 + 178 + /* The below rx_mpdu_start_qcn9274_compact structure is tied with the mask 179 + * value QCN9274_MPDU_START_WMASK. If the mask value changes the structure 180 + * will also change. 181 + */ 182 + 183 + struct rx_mpdu_start_qcn9274_compact { 184 + __le32 info1; 185 + __le32 pn[4]; 186 + __le32 info2; 187 + __le32 peer_meta_data; 188 + __le16 info3; 189 + __le16 phy_ppdu_id; 190 + __le16 ast_index; 191 + __le16 sw_peer_id; 192 + __le32 info4; 193 + __le32 info5; 194 + __le32 info6; 195 + __le16 frame_ctrl; 196 + __le16 duration; 197 + u8 addr1[ETH_ALEN]; 198 + u8 addr2[ETH_ALEN]; 199 + u8 addr3[ETH_ALEN]; 200 + __le16 seq_ctrl; 201 + u8 addr4[ETH_ALEN]; 202 + __le16 qos_ctrl; 148 203 } __packed; 149 204 150 205 /* rx_mpdu_start ··· 663 608 RX_MSDU_START_RECEPTION_TYPE_UL_MU_OFDMA_MIMO, 664 609 }; 665 610 611 + #define RX_MSDU_END_64_TLV_SRC_LINK_ID GENMASK(24, 22) 612 + 666 613 #define RX_MSDU_END_INFO0_RXPCU_MPDU_FITLER GENMASK(1, 0) 667 614 #define RX_MSDU_END_INFO0_SW_FRAME_GRP_ID GENMASK(8, 2) 668 615 ··· 839 782 __le16 res0; 840 783 __le16 sa_15_0; 841 784 __le32 sa_47_16; 785 + __le32 info13; 786 + __le32 info14; 787 + } __packed; 788 + 789 + #define QCN9274_MSDU_END_SELECT_MSDU_END_TAG BIT(0) 790 + #define QCN9274_MSDU_END_SELECT_INFO0_PHY_PPDUID_IP_HDR_CSUM_INFO1 BIT(1) 791 + #define QCN9274_MSDU_END_SELECT_INFO2_CUMULATIVE_CSUM_RULE_IND_0 BIT(2) 792 + #define QCN9274_MSDU_END_SELECT_IPV6_OP_CRC_INFO3_TYPE13 BIT(3) 793 + #define QCN9274_MSDU_END_SELECT_RULE_IND_1_TCP_SEQ_NUM BIT(4) 794 + #define QCN9274_MSDU_END_SELECT_TCP_ACK_NUM_INFO4_WINDOW_SIZE BIT(5) 795 + #define QCN9274_MSDU_END_SELECT_SA_SW_PER_ID_INFO5_SA_DA_ID BIT(6) 796 + #define QCN9274_MSDU_END_SELECT_INFO6_FSE_METADATA BIT(7) 797 + #define QCN9274_MSDU_END_SELECT_CCE_MDATA_TCP_UDP_CSUM_INFO7_IP_LEN BIT(8) 798 + #define QCN9274_MSDU_END_SELECT_INFO8_INFO9 BIT(9) 799 + #define QCN9274_MSDU_END_SELECT_INFO10_INFO11 BIT(10) 800 + #define QCN9274_MSDU_END_SELECT_VLAN_CTAG_STAG_CI_PEER_MDATA BIT(11) 801 + #define QCN9274_MSDU_END_SELECT_INFO12_AND_FLOW_ID_TOEPLITZ BIT(12) 802 + #define QCN9274_MSDU_END_SELECT_PPDU_START_TS_63_32_PHY_MDATA BIT(13) 803 + #define QCN9274_MSDU_END_SELECT_PPDU_START_TS_31_0_TOEPLITZ_HASH_2_4 BIT(14) 804 + #define QCN9274_MSDU_END_SELECT_RES0_SA_47_0 BIT(15) 805 + #define QCN9274_MSDU_END_SELECT_INFO13_INFO14 BIT(16) 806 + 807 + #define QCN9274_MSDU_END_WMASK (QCN9274_MSDU_END_SELECT_MSDU_END_TAG | \ 808 + QCN9274_MSDU_END_SELECT_SA_SW_PER_ID_INFO5_SA_DA_ID | \ 809 + QCN9274_MSDU_END_SELECT_INFO10_INFO11 | \ 810 + QCN9274_MSDU_END_SELECT_INFO12_AND_FLOW_ID_TOEPLITZ | \ 811 + QCN9274_MSDU_END_SELECT_PPDU_START_TS_63_32_PHY_MDATA | \ 812 + QCN9274_MSDU_END_SELECT_INFO13_INFO14) 813 + 814 + /* The below rx_msdu_end_qcn9274_compact structure is tied with the mask value 815 + * QCN9274_MSDU_END_WMASK. If the mask value changes the structure will also 816 + * change. 817 + */ 818 + 819 + struct rx_msdu_end_qcn9274_compact { 820 + __le64 msdu_end_tag; 821 + __le16 sa_sw_peer_id; 822 + __le16 info5; 823 + __le16 sa_idx; 824 + __le16 da_idx_or_sw_peer_id; 825 + __le32 info10; 826 + __le32 info11; 827 + __le32 info12; 828 + __le32 flow_id_toeplitz; 829 + __le32 ppdu_start_timestamp_63_32; 830 + __le32 phy_meta_data; 842 831 __le32 info13; 843 832 __le32 info14; 844 833 } __packed; ··· 1553 1450 * 1554 1451 */ 1555 1452 1556 - /* TODO: Move to compact TLV approach 1557 - * By default these tlv's are not aligned to 128b boundary 1558 - * Need to remove unused qwords and make them compact/aligned 1559 - */ 1560 1453 struct hal_rx_desc_qcn9274 { 1561 1454 struct rx_msdu_end_qcn9274 msdu_end; 1562 1455 struct rx_mpdu_start_qcn9274 mpdu_start; 1456 + u8 msdu_payload[]; 1457 + } __packed; 1458 + 1459 + struct hal_rx_desc_qcn9274_compact { 1460 + struct rx_msdu_end_qcn9274_compact msdu_end; 1461 + struct rx_mpdu_start_qcn9274_compact mpdu_start; 1563 1462 u8 msdu_payload[]; 1564 1463 } __packed; 1565 1464 ··· 1589 1484 struct hal_rx_desc { 1590 1485 union { 1591 1486 struct hal_rx_desc_qcn9274 qcn9274; 1487 + struct hal_rx_desc_qcn9274_compact qcn9274_compact; 1592 1488 struct hal_rx_desc_wcn7850 wcn7850; 1593 1489 } u; 1594 1490 } __packed;
+209 -21
drivers/net/wireless/ath/ath12k/wmi.c
··· 19 19 #include "mac.h" 20 20 #include "hw.h" 21 21 #include "peer.h" 22 + #include "p2p.h" 22 23 23 24 struct ath12k_wmi_svc_ready_parse { 24 25 bool wmi_svc_bitmap_done; ··· 163 162 .min_len = sizeof(struct wmi_probe_resp_tx_status_event) }, 164 163 [WMI_TAG_VDEV_DELETE_RESP_EVENT] = { 165 164 .min_len = sizeof(struct wmi_vdev_delete_resp_event) }, 165 + [WMI_TAG_TWT_ENABLE_COMPLETE_EVENT] = { 166 + .min_len = sizeof(struct wmi_twt_enable_event) }, 167 + [WMI_TAG_TWT_DISABLE_COMPLETE_EVENT] = { 168 + .min_len = sizeof(struct wmi_twt_disable_event) }, 169 + [WMI_TAG_P2P_NOA_INFO] = { 170 + .min_len = sizeof(struct ath12k_wmi_p2p_noa_info) }, 171 + [WMI_TAG_P2P_NOA_EVENT] = { 172 + .min_len = sizeof(struct wmi_p2p_noa_event) }, 166 173 }; 167 174 168 175 static __le32 ath12k_wmi_tlv_hdr(u32 cmd, u32 len) ··· 188 179 struct ath12k_wmi_resource_config_arg *config) 189 180 { 190 181 config->num_vdevs = ab->num_radios * TARGET_NUM_VDEVS; 191 - 192 - if (ab->num_radios == 2) { 193 - config->num_peers = TARGET_NUM_PEERS(DBS); 194 - config->num_tids = TARGET_NUM_TIDS(DBS); 195 - } else if (ab->num_radios == 3) { 196 - config->num_peers = TARGET_NUM_PEERS(DBS_SBS); 197 - config->num_tids = TARGET_NUM_TIDS(DBS_SBS); 198 - } else { 199 - /* Control should not reach here */ 200 - config->num_peers = TARGET_NUM_PEERS(SINGLE); 201 - config->num_tids = TARGET_NUM_TIDS(SINGLE); 202 - } 182 + config->num_peers = ab->num_radios * 183 + ath12k_core_get_max_peers_per_radio(ab); 184 + config->num_tids = ath12k_core_get_max_num_tids(ab); 203 185 config->num_offload_peers = TARGET_NUM_OFFLD_PEERS; 204 186 config->num_offload_reorder_buffs = TARGET_NUM_OFFLD_REORDER_BUFFS; 205 187 config->num_peer_keys = TARGET_NUM_PEER_KEYS; ··· 228 228 config->peer_map_unmap_version = 0x32; 229 229 config->twt_ap_pdev_count = ab->num_radios; 230 230 config->twt_ap_sta_count = 1000; 231 + 232 + if (test_bit(WMI_TLV_SERVICE_PEER_METADATA_V1A_V1B_SUPPORT, ab->wmi_ab.svc_map)) 233 + config->dp_peer_meta_data_ver = TARGET_RX_PEER_METADATA_VER_V1B; 231 234 } 232 235 233 236 void ath12k_wmi_init_wcn7850(struct ath12k_base *ab, ··· 496 493 497 494 mac_caps = wmi_mac_phy_caps + phy_idx; 498 495 499 - pdev->pdev_id = le32_to_cpu(mac_caps->pdev_id); 496 + pdev->pdev_id = ath12k_wmi_mac_phy_get_pdev_id(mac_caps); 500 497 pdev_cap->supported_bands |= le32_to_cpu(mac_caps->supported_bands); 501 498 pdev_cap->ampdu_density = le32_to_cpu(mac_caps->ampdu_density); 502 499 503 500 fw_pdev = &ab->fw_pdev[ab->fw_pdev_count]; 504 501 fw_pdev->supported_bands = le32_to_cpu(mac_caps->supported_bands); 505 - fw_pdev->pdev_id = le32_to_cpu(mac_caps->pdev_id); 502 + fw_pdev->pdev_id = ath12k_wmi_mac_phy_get_pdev_id(mac_caps); 506 503 fw_pdev->phy_id = le32_to_cpu(mac_caps->phy_id); 507 504 ab->fw_pdev_count++; 508 505 ··· 730 727 return 0; 731 728 } 732 729 730 + static u32 ath12k_wmi_mgmt_get_freq(struct ath12k *ar, 731 + struct ieee80211_tx_info *info) 732 + { 733 + struct ath12k_base *ab = ar->ab; 734 + u32 freq = 0; 735 + 736 + if (ab->hw_params->single_pdev_only && 737 + ar->scan.is_roc && 738 + (info->flags & IEEE80211_TX_CTL_TX_OFFCHAN)) 739 + freq = ar->scan.roc_freq; 740 + 741 + return freq; 742 + } 743 + 733 744 struct sk_buff *ath12k_wmi_alloc_skb(struct ath12k_wmi_base *wmi_ab, u32 len) 734 745 { 735 746 struct sk_buff *skb; ··· 769 752 { 770 753 struct ath12k_wmi_pdev *wmi = ar->wmi; 771 754 struct wmi_mgmt_send_cmd *cmd; 755 + struct ieee80211_tx_info *info = IEEE80211_SKB_CB(frame); 772 756 struct wmi_tlv *frame_tlv; 773 757 struct sk_buff *skb; 774 758 u32 buf_len; ··· 788 770 sizeof(*cmd)); 789 771 cmd->vdev_id = cpu_to_le32(vdev_id); 790 772 cmd->desc_id = cpu_to_le32(buf_id); 791 - cmd->chanfreq = 0; 773 + cmd->chanfreq = cpu_to_le32(ath12k_wmi_mgmt_get_freq(ar, info)); 792 774 cmd->paddr_lo = cpu_to_le32(lower_32_bits(ATH12K_SKB_CB(frame)->paddr)); 793 775 cmd->paddr_hi = cpu_to_le32(upper_32_bits(ATH12K_SKB_CB(frame)->paddr)); 794 776 cmd->frame_len = cpu_to_le32(frame->len); ··· 843 825 cmd->pdev_id = cpu_to_le32(args->pdev_id); 844 826 cmd->vdev_stats_id = cpu_to_le32(args->if_stats_id); 845 827 ether_addr_copy(cmd->vdev_macaddr.addr, macaddr); 828 + 829 + if (args->if_stats_id != ATH12K_INVAL_VDEV_STATS_ID) 830 + cmd->vdev_stats_id_valid = cpu_to_le32(BIT(0)); 846 831 847 832 ptr = skb->data + sizeof(*cmd); 848 833 len = WMI_NUM_SUPPORTED_BAND_MAX * sizeof(*txrx_streams); ··· 1045 1024 cmd->regdomain = cpu_to_le32(arg->regdomain); 1046 1025 cmd->he_ops = cpu_to_le32(arg->he_ops); 1047 1026 cmd->punct_bitmap = cpu_to_le32(arg->punct_bitmap); 1027 + cmd->mbssid_flags = cpu_to_le32(arg->mbssid_flags); 1048 1028 1049 1029 if (!restart) { 1050 1030 if (arg->ssid) { ··· 1073 1051 tlv->header = ath12k_wmi_tlv_hdr(WMI_TAG_ARRAY_STRUCT, 0); 1074 1052 1075 1053 /* Note: This is a nested TLV containing: 1076 - * [wmi_tlv][wmi_p2p_noa_descriptor][wmi_tlv].. 1054 + * [wmi_tlv][ath12k_wmi_p2p_noa_descriptor][wmi_tlv].. 1077 1055 */ 1078 1056 1079 1057 ptr += sizeof(*tlv); ··· 1732 1710 return ret; 1733 1711 } 1734 1712 1713 + int ath12k_wmi_p2p_go_bcn_ie(struct ath12k *ar, u32 vdev_id, 1714 + const u8 *p2p_ie) 1715 + { 1716 + struct ath12k_wmi_pdev *wmi = ar->wmi; 1717 + struct wmi_p2p_go_set_beacon_ie_cmd *cmd; 1718 + size_t p2p_ie_len, aligned_len; 1719 + struct wmi_tlv *tlv; 1720 + struct sk_buff *skb; 1721 + void *ptr; 1722 + int ret, len; 1723 + 1724 + p2p_ie_len = p2p_ie[1] + 2; 1725 + aligned_len = roundup(p2p_ie_len, sizeof(u32)); 1726 + 1727 + len = sizeof(*cmd) + TLV_HDR_SIZE + aligned_len; 1728 + 1729 + skb = ath12k_wmi_alloc_skb(wmi->wmi_ab, len); 1730 + if (!skb) 1731 + return -ENOMEM; 1732 + 1733 + ptr = skb->data; 1734 + cmd = ptr; 1735 + cmd->tlv_header = ath12k_wmi_tlv_cmd_hdr(WMI_TAG_P2P_GO_SET_BEACON_IE, 1736 + sizeof(*cmd)); 1737 + cmd->vdev_id = cpu_to_le32(vdev_id); 1738 + cmd->ie_buf_len = cpu_to_le32(p2p_ie_len); 1739 + 1740 + ptr += sizeof(*cmd); 1741 + tlv = ptr; 1742 + tlv->header = ath12k_wmi_tlv_cmd_hdr(WMI_TAG_ARRAY_BYTE, 1743 + aligned_len); 1744 + memcpy(tlv->value, p2p_ie, p2p_ie_len); 1745 + 1746 + ret = ath12k_wmi_cmd_send(wmi, skb, WMI_P2P_GO_SET_BEACON_IE); 1747 + if (ret) { 1748 + ath12k_warn(ar->ab, "failed to send WMI_P2P_GO_SET_BEACON_IE\n"); 1749 + dev_kfree_skb(skb); 1750 + } 1751 + 1752 + return ret; 1753 + } 1754 + 1735 1755 int ath12k_wmi_bcn_tmpl(struct ath12k *ar, u32 vdev_id, 1736 1756 struct ieee80211_mutable_offsets *offs, 1737 1757 struct sk_buff *bcn) ··· 2194 2130 WMI_SCAN_EVENT_BSS_CHANNEL | 2195 2131 WMI_SCAN_EVENT_FOREIGN_CHAN | 2196 2132 WMI_SCAN_EVENT_DEQUEUED; 2197 - arg->scan_flags |= WMI_SCAN_CHAN_STAT_EVENT; 2133 + arg->scan_f_chan_stat_evnt = 1; 2198 2134 arg->num_bssid = 1; 2199 2135 2200 2136 /* fill bssid_list[0] with 0xff, otherwise bssid and RA will be ··· 3329 3265 wmi_cfg->sched_params = cpu_to_le32(tg_cfg->sched_params); 3330 3266 wmi_cfg->twt_ap_pdev_count = cpu_to_le32(tg_cfg->twt_ap_pdev_count); 3331 3267 wmi_cfg->twt_ap_sta_count = cpu_to_le32(tg_cfg->twt_ap_sta_count); 3268 + wmi_cfg->flags2 = le32_encode_bits(tg_cfg->dp_peer_meta_data_ver, 3269 + WMI_RSRC_CFG_FLAGS2_RX_PEER_METADATA_VERSION); 3270 + 3332 3271 wmi_cfg->host_service_flags = cpu_to_le32(tg_cfg->is_reg_cc_ext_event_supported << 3333 3272 WMI_RSRC_CFG_HOST_SVC_FLAG_REG_CC_EXT_SUPPORT_BIT); 3334 3273 } ··· 4281 4214 for (i = 0; i < ab->fw_pdev_count; i++) { 4282 4215 struct ath12k_fw_pdev *fw_pdev = &ab->fw_pdev[i]; 4283 4216 4284 - if (fw_pdev->pdev_id == le32_to_cpu(caps->pdev_id) && 4217 + if (fw_pdev->pdev_id == ath12k_wmi_caps_ext_get_pdev_id(caps) && 4285 4218 fw_pdev->phy_id == le32_to_cpu(caps->phy_id)) { 4286 4219 bands = fw_pdev->supported_bands; 4287 4220 break; ··· 4338 4271 return 0; 4339 4272 } else { 4340 4273 for (i = 0; i < ab->num_radios; i++) { 4341 - if (ab->pdevs[i].pdev_id == le32_to_cpu(caps->pdev_id)) 4274 + if (ab->pdevs[i].pdev_id == 4275 + ath12k_wmi_caps_ext_get_pdev_id(caps)) 4342 4276 break; 4343 4277 } 4344 4278 ··· 5074 5006 break; 5075 5007 case ATH12K_SCAN_STARTING: 5076 5008 ar->scan.state = ATH12K_SCAN_RUNNING; 5009 + 5010 + if (ar->scan.is_roc) 5011 + ieee80211_ready_on_channel(ath12k_ar_to_hw(ar)); 5012 + 5077 5013 complete(&ar->scan.started); 5078 5014 break; 5079 5015 } ··· 5162 5090 case ATH12K_SCAN_RUNNING: 5163 5091 case ATH12K_SCAN_ABORTING: 5164 5092 ar->scan_channel = ieee80211_get_channel(hw->wiphy, freq); 5093 + 5094 + if (ar->scan.is_roc && ar->scan.roc_freq == freq) 5095 + complete(&ar->scan.on_channel); 5096 + 5165 5097 break; 5166 5098 } 5167 5099 } ··· 6706 6630 kfree(tb); 6707 6631 } 6708 6632 6633 + static int ath12k_wmi_p2p_noa_event(struct ath12k_base *ab, 6634 + struct sk_buff *skb) 6635 + { 6636 + const void **tb; 6637 + const struct wmi_p2p_noa_event *ev; 6638 + const struct ath12k_wmi_p2p_noa_info *noa; 6639 + struct ath12k *ar; 6640 + int ret, vdev_id; 6641 + 6642 + tb = ath12k_wmi_tlv_parse_alloc(ab, skb, GFP_ATOMIC); 6643 + if (IS_ERR(tb)) { 6644 + ret = PTR_ERR(tb); 6645 + ath12k_warn(ab, "failed to parse P2P NoA TLV: %d\n", ret); 6646 + return ret; 6647 + } 6648 + 6649 + ev = tb[WMI_TAG_P2P_NOA_EVENT]; 6650 + noa = tb[WMI_TAG_P2P_NOA_INFO]; 6651 + 6652 + if (!ev || !noa) { 6653 + ret = -EPROTO; 6654 + goto out; 6655 + } 6656 + 6657 + vdev_id = __le32_to_cpu(ev->vdev_id); 6658 + 6659 + ath12k_dbg(ab, ATH12K_DBG_WMI, 6660 + "wmi tlv p2p noa vdev_id %i descriptors %u\n", 6661 + vdev_id, le32_get_bits(noa->noa_attr, WMI_P2P_NOA_INFO_DESC_NUM)); 6662 + 6663 + ar = ath12k_mac_get_ar_by_vdev_id(ab, vdev_id); 6664 + if (!ar) { 6665 + ath12k_warn(ab, "invalid vdev id %d in P2P NoA event\n", 6666 + vdev_id); 6667 + ret = -EINVAL; 6668 + goto out; 6669 + } 6670 + 6671 + ath12k_p2p_noa_update_by_vdev_id(ar, vdev_id, noa); 6672 + 6673 + ret = 0; 6674 + 6675 + out: 6676 + kfree(tb); 6677 + return ret; 6678 + } 6679 + 6709 6680 static void ath12k_rfkill_state_change_event(struct ath12k_base *ab, 6710 6681 struct sk_buff *skb) 6711 6682 { ··· 6791 6668 ath12k_wmi_diag_event(struct ath12k_base *ab, struct sk_buff *skb) 6792 6669 { 6793 6670 trace_ath12k_wmi_diag(ab, skb->data, skb->len); 6671 + } 6672 + 6673 + static void ath12k_wmi_twt_enable_event(struct ath12k_base *ab, 6674 + struct sk_buff *skb) 6675 + { 6676 + const void **tb; 6677 + const struct wmi_twt_enable_event *ev; 6678 + int ret; 6679 + 6680 + tb = ath12k_wmi_tlv_parse_alloc(ab, skb, GFP_ATOMIC); 6681 + if (IS_ERR(tb)) { 6682 + ret = PTR_ERR(tb); 6683 + ath12k_warn(ab, "failed to parse wmi twt enable status event tlv: %d\n", 6684 + ret); 6685 + return; 6686 + } 6687 + 6688 + ev = tb[WMI_TAG_TWT_ENABLE_COMPLETE_EVENT]; 6689 + if (!ev) { 6690 + ath12k_warn(ab, "failed to fetch twt enable wmi event\n"); 6691 + goto exit; 6692 + } 6693 + 6694 + ath12k_dbg(ab, ATH12K_DBG_MAC, "wmi twt enable event pdev id %u status %u\n", 6695 + le32_to_cpu(ev->pdev_id), 6696 + le32_to_cpu(ev->status)); 6697 + 6698 + exit: 6699 + kfree(tb); 6700 + } 6701 + 6702 + static void ath12k_wmi_twt_disable_event(struct ath12k_base *ab, 6703 + struct sk_buff *skb) 6704 + { 6705 + const void **tb; 6706 + const struct wmi_twt_disable_event *ev; 6707 + int ret; 6708 + 6709 + tb = ath12k_wmi_tlv_parse_alloc(ab, skb, GFP_ATOMIC); 6710 + if (IS_ERR(tb)) { 6711 + ret = PTR_ERR(tb); 6712 + ath12k_warn(ab, "failed to parse wmi twt disable status event tlv: %d\n", 6713 + ret); 6714 + return; 6715 + } 6716 + 6717 + ev = tb[WMI_TAG_TWT_DISABLE_COMPLETE_EVENT]; 6718 + if (!ev) { 6719 + ath12k_warn(ab, "failed to fetch twt disable wmi event\n"); 6720 + goto exit; 6721 + } 6722 + 6723 + ath12k_dbg(ab, ATH12K_DBG_MAC, "wmi twt disable event pdev id %d status %u\n", 6724 + le32_to_cpu(ev->pdev_id), 6725 + le32_to_cpu(ev->status)); 6726 + 6727 + exit: 6728 + kfree(tb); 6794 6729 } 6795 6730 6796 6731 static void ath12k_wmi_op_rx(struct ath12k_base *ab, struct sk_buff *skb) ··· 6946 6765 case WMI_RFKILL_STATE_CHANGE_EVENTID: 6947 6766 ath12k_rfkill_state_change_event(ab, skb); 6948 6767 break; 6768 + case WMI_TWT_ENABLE_EVENTID: 6769 + ath12k_wmi_twt_enable_event(ab, skb); 6770 + break; 6771 + case WMI_TWT_DISABLE_EVENTID: 6772 + ath12k_wmi_twt_disable_event(ab, skb); 6773 + break; 6774 + case WMI_P2P_NOA_EVENTID: 6775 + ath12k_wmi_p2p_noa_event(ab, skb); 6776 + break; 6949 6777 /* add Unsupported events here */ 6950 6778 case WMI_TBTTOFFSET_EXT_UPDATE_EVENTID: 6951 6779 case WMI_PEER_OPER_MODE_CHANGE_EVENTID: 6952 - case WMI_TWT_ENABLE_EVENTID: 6953 - case WMI_TWT_DISABLE_EVENTID: 6954 6780 case WMI_PDEV_DMA_RING_CFG_RSP_EVENTID: 6955 6781 ath12k_dbg(ab, ATH12K_DBG_WMI, 6956 6782 "ignoring unsupported event 0x%x\n", id);
+139 -63
drivers/net/wireless/ath/ath12k/wmi.h
··· 1 1 /* SPDX-License-Identifier: BSD-3-Clause-Clear */ 2 2 /* 3 3 * Copyright (c) 2018-2021 The Linux Foundation. All rights reserved. 4 - * Copyright (c) 2021-2023 Qualcomm Innovation Center, Inc. All rights reserved. 4 + * Copyright (c) 2021-2024 Qualcomm Innovation Center, Inc. All rights reserved. 5 5 */ 6 6 7 7 #ifndef ATH12K_WMI_H ··· 167 167 #define WLAN_SCAN_MAX_HINT_S_SSID 10 168 168 #define WLAN_SCAN_MAX_HINT_BSSID 10 169 169 #define MAX_RNR_BSS 5 170 - 171 - #define WLAN_SCAN_PARAMS_MAX_SSID 16 172 - #define WLAN_SCAN_PARAMS_MAX_BSSID 4 173 - #define WLAN_SCAN_PARAMS_MAX_IE_LEN 256 174 170 175 171 #define WMI_APPEND_TO_EXISTING_CHAN_LIST_FLAG 1 176 172 ··· 2159 2163 2160 2164 WMI_TLV_SERVICE_11BE = 289, 2161 2165 2166 + WMI_TLV_SERVICE_WMSK_COMPACTION_RX_TLVS = 361, 2167 + 2168 + WMI_TLV_SERVICE_PEER_METADATA_V1A_V1B_SUPPORT = 365, 2169 + 2162 2170 WMI_MAX_EXT2_SERVICE, 2163 2171 }; 2164 2172 ··· 2350 2350 u32 twt_ap_pdev_count; 2351 2351 u32 twt_ap_sta_count; 2352 2352 bool is_reg_cc_ext_event_supported; 2353 + u8 dp_peer_meta_data_ver; 2353 2354 }; 2354 2355 2355 2356 struct ath12k_wmi_init_cmd_arg { ··· 2403 2402 } __packed; 2404 2403 2405 2404 #define WMI_RSRC_CFG_HOST_SVC_FLAG_REG_CC_EXT_SUPPORT_BIT 4 2405 + #define WMI_RSRC_CFG_FLAGS2_RX_PEER_METADATA_VERSION GENMASK(5, 4) 2406 2406 2407 2407 struct ath12k_wmi_resource_config_params { 2408 2408 __le32 tlv_header; ··· 2544 2542 2545 2543 #define WMI_MAX_HECAP_PHY_SIZE (3) 2546 2544 2545 + /* pdev_id is present in lower 16 bits of pdev_and_hw_link_ids in 2546 + * ath12k_wmi_mac_phy_caps_params & ath12k_wmi_caps_ext_params. 2547 + * 2548 + * hw_link_id is present in higher 16 bits of pdev_and_hw_link_ids. 2549 + */ 2550 + #define WMI_CAPS_PARAMS_PDEV_ID GENMASK(15, 0) 2551 + #define WMI_CAPS_PARAMS_HW_LINK_ID GENMASK(31, 16) 2552 + 2547 2553 struct ath12k_wmi_mac_phy_caps_params { 2548 2554 __le32 hw_mode_id; 2549 - __le32 pdev_id; 2555 + __le32 pdev_and_hw_link_ids; 2550 2556 __le32 phy_id; 2551 2557 __le32 supported_flags; 2552 2558 __le32 supported_bands; ··· 2646 2636 2647 2637 struct ath12k_wmi_caps_ext_params { 2648 2638 __le32 hw_mode_id; 2649 - union { 2650 - struct { 2651 - __le16 pdev_id; 2652 - __le16 hw_link_id; 2653 - } __packed ath12k_wmi_pdev_to_link_map; 2654 - __le32 pdev_id; 2655 - }; 2639 + __le32 pdev_and_hw_link_ids; 2656 2640 __le32 phy_id; 2657 2641 __le32 wireless_modes_ext; 2658 2642 __le32 eht_cap_mac_info_2ghz[WMI_MAX_EHTCAP_MAC_SIZE]; ··· 2720 2716 struct ath12k_wmi_mac_addr_params vdev_macaddr; 2721 2717 __le32 num_cfg_txrx_streams; 2722 2718 __le32 pdev_id; 2719 + __le32 mbssid_flags; 2720 + __le32 mbssid_tx_vdev_id; 2721 + __le32 vdev_stats_id_valid; 2723 2722 __le32 vdev_stats_id; 2724 2723 } __packed; 2725 2724 ··· 2771 2764 2772 2765 #define ATH12K_VDEV_SETUP_TIMEOUT_HZ (5 * HZ) 2773 2766 2767 + enum wmi_vdev_mbssid_flags { 2768 + WMI_VDEV_MBSSID_FLAGS_NON_MBSSID_AP = BIT(0), 2769 + }; 2770 + 2774 2771 struct wmi_vdev_start_request_cmd { 2775 2772 __le32 tlv_header; 2776 2773 __le32 vdev_id; ··· 2793 2782 __le32 cac_duration_ms; 2794 2783 __le32 regdomain; 2795 2784 __le32 min_data_rate; 2796 - __le32 mbssid_flags; 2785 + __le32 mbssid_flags; /* uses enum wmi_vdev_mbssid_flags */ 2797 2786 __le32 mbssid_tx_vdev_id; 2798 2787 __le32 eht_ops; 2799 2788 __le32 punct_bitmap; ··· 3157 3146 3158 3147 #define WLAN_SCAN_PARAMS_MAX_SSID 16 3159 3148 #define WLAN_SCAN_PARAMS_MAX_BSSID 4 3160 - #define WLAN_SCAN_PARAMS_MAX_IE_LEN 256 3149 + #define WLAN_SCAN_PARAMS_MAX_IE_LEN 512 3161 3150 3162 3151 /* Values lower than this may be refused by some firmware revisions with a scan 3163 3152 * completion with a timedout reason. ··· 3281 3270 u32 vdev_id; 3282 3271 u32 pdev_id; 3283 3272 enum wmi_scan_priority scan_priority; 3284 - union { 3285 - struct { 3286 - u32 scan_ev_started:1, 3287 - scan_ev_completed:1, 3288 - scan_ev_bss_chan:1, 3289 - scan_ev_foreign_chan:1, 3290 - scan_ev_dequeued:1, 3291 - scan_ev_preempted:1, 3292 - scan_ev_start_failed:1, 3293 - scan_ev_restarted:1, 3294 - scan_ev_foreign_chn_exit:1, 3295 - scan_ev_invalid:1, 3296 - scan_ev_gpio_timeout:1, 3297 - scan_ev_suspended:1, 3298 - scan_ev_resumed:1; 3299 - }; 3300 - u32 scan_events; 3301 - }; 3273 + u32 scan_ev_started:1, 3274 + scan_ev_completed:1, 3275 + scan_ev_bss_chan:1, 3276 + scan_ev_foreign_chan:1, 3277 + scan_ev_dequeued:1, 3278 + scan_ev_preempted:1, 3279 + scan_ev_start_failed:1, 3280 + scan_ev_restarted:1, 3281 + scan_ev_foreign_chn_exit:1, 3282 + scan_ev_invalid:1, 3283 + scan_ev_gpio_timeout:1, 3284 + scan_ev_suspended:1, 3285 + scan_ev_resumed:1; 3302 3286 u32 dwell_time_active; 3303 3287 u32 dwell_time_active_2g; 3304 3288 u32 dwell_time_passive; ··· 3306 3300 u32 idle_time; 3307 3301 u32 max_scan_time; 3308 3302 u32 probe_delay; 3309 - union { 3310 - struct { 3311 - u32 scan_f_passive:1, 3312 - scan_f_bcast_probe:1, 3313 - scan_f_cck_rates:1, 3314 - scan_f_ofdm_rates:1, 3315 - scan_f_chan_stat_evnt:1, 3316 - scan_f_filter_prb_req:1, 3317 - scan_f_bypass_dfs_chn:1, 3318 - scan_f_continue_on_err:1, 3319 - scan_f_offchan_mgmt_tx:1, 3320 - scan_f_offchan_data_tx:1, 3321 - scan_f_promisc_mode:1, 3322 - scan_f_capture_phy_err:1, 3323 - scan_f_strict_passive_pch:1, 3324 - scan_f_half_rate:1, 3325 - scan_f_quarter_rate:1, 3326 - scan_f_force_active_dfs_chn:1, 3327 - scan_f_add_tpc_ie_in_probe:1, 3328 - scan_f_add_ds_ie_in_probe:1, 3329 - scan_f_add_spoofed_mac_in_probe:1, 3330 - scan_f_add_rand_seq_in_probe:1, 3331 - scan_f_en_ie_whitelist_in_probe:1, 3332 - scan_f_forced:1, 3333 - scan_f_2ghz:1, 3334 - scan_f_5ghz:1, 3335 - scan_f_80mhz:1; 3336 - }; 3337 - u32 scan_flags; 3338 - }; 3303 + u32 scan_f_passive:1, 3304 + scan_f_bcast_probe:1, 3305 + scan_f_cck_rates:1, 3306 + scan_f_ofdm_rates:1, 3307 + scan_f_chan_stat_evnt:1, 3308 + scan_f_filter_prb_req:1, 3309 + scan_f_bypass_dfs_chn:1, 3310 + scan_f_continue_on_err:1, 3311 + scan_f_offchan_mgmt_tx:1, 3312 + scan_f_offchan_data_tx:1, 3313 + scan_f_promisc_mode:1, 3314 + scan_f_capture_phy_err:1, 3315 + scan_f_strict_passive_pch:1, 3316 + scan_f_half_rate:1, 3317 + scan_f_quarter_rate:1, 3318 + scan_f_force_active_dfs_chn:1, 3319 + scan_f_add_tpc_ie_in_probe:1, 3320 + scan_f_add_ds_ie_in_probe:1, 3321 + scan_f_add_spoofed_mac_in_probe:1, 3322 + scan_f_add_rand_seq_in_probe:1, 3323 + scan_f_en_ie_whitelist_in_probe:1, 3324 + scan_f_forced:1, 3325 + scan_f_2ghz:1, 3326 + scan_f_5ghz:1, 3327 + scan_f_80mhz:1; 3339 3328 enum scan_dwelltime_adaptive_mode adaptive_dwell_time_mode; 3340 3329 u32 burst_duration; 3341 3330 u32 num_chan; ··· 3490 3489 __le32 pdev_id; 3491 3490 } __packed; 3492 3491 3492 + #define WMI_P2P_MAX_NOA_DESCRIPTORS 4 3493 + 3494 + struct wmi_p2p_noa_event { 3495 + __le32 vdev_id; 3496 + } __packed; 3497 + 3498 + struct ath12k_wmi_p2p_noa_descriptor { 3499 + __le32 type_count; /* 255: continuous schedule, 0: reserved */ 3500 + __le32 duration; /* Absent period duration in micro seconds */ 3501 + __le32 interval; /* Absent period interval in micro seconds */ 3502 + __le32 start_time; /* 32 bit tsf time when in starts */ 3503 + } __packed; 3504 + 3505 + #define WMI_P2P_NOA_INFO_CHANGED_FLAG BIT(0) 3506 + #define WMI_P2P_NOA_INFO_INDEX GENMASK(15, 8) 3507 + #define WMI_P2P_NOA_INFO_OPP_PS BIT(16) 3508 + #define WMI_P2P_NOA_INFO_CTWIN_TU GENMASK(23, 17) 3509 + #define WMI_P2P_NOA_INFO_DESC_NUM GENMASK(31, 24) 3510 + 3511 + struct ath12k_wmi_p2p_noa_info { 3512 + /* Bit 0 - Flag to indicate an update in NOA schedule 3513 + * Bits 7-1 - Reserved 3514 + * Bits 15-8 - Index (identifies the instance of NOA sub element) 3515 + * Bit 16 - Opp PS state of the AP 3516 + * Bits 23-17 - Ctwindow in TUs 3517 + * Bits 31-24 - Number of NOA descriptors 3518 + */ 3519 + __le32 noa_attr; 3520 + struct ath12k_wmi_p2p_noa_descriptor descriptors[WMI_P2P_MAX_NOA_DESCRIPTORS]; 3521 + } __packed; 3522 + 3493 3523 #define WMI_BEACON_TX_BUFFER_SIZE 512 3494 3524 3495 3525 struct wmi_bcn_tmpl_cmd { ··· 3533 3501 __le32 csa_event_bitmap; 3534 3502 __le32 mbssid_ie_offset; 3535 3503 __le32 esp_ie_offset; 3504 + } __packed; 3505 + 3506 + struct wmi_p2p_go_set_beacon_ie_cmd { 3507 + __le32 tlv_header; 3508 + __le32 vdev_id; 3509 + __le32 ie_buf_len; 3536 3510 } __packed; 3537 3511 3538 3512 struct wmi_vdev_install_key_cmd { ··· 4835 4797 __le32 radio_state; 4836 4798 } __packed; 4837 4799 4800 + struct wmi_twt_enable_event { 4801 + __le32 pdev_id; 4802 + __le32 status; 4803 + } __packed; 4804 + 4805 + struct wmi_twt_disable_event { 4806 + __le32 pdev_id; 4807 + __le32 status; 4808 + } __packed; 4809 + 4838 4810 void ath12k_wmi_init_qcn9274(struct ath12k_base *ab, 4839 4811 struct ath12k_wmi_resource_config_arg *config); 4840 4812 void ath12k_wmi_init_wcn7850(struct ath12k_base *ab, ··· 4854 4806 struct sk_buff *ath12k_wmi_alloc_skb(struct ath12k_wmi_base *wmi_sc, u32 len); 4855 4807 int ath12k_wmi_mgmt_send(struct ath12k *ar, u32 vdev_id, u32 buf_id, 4856 4808 struct sk_buff *frame); 4809 + int ath12k_wmi_p2p_go_bcn_ie(struct ath12k *ar, u32 vdev_id, 4810 + const u8 *p2p_ie); 4857 4811 int ath12k_wmi_bcn_tmpl(struct ath12k *ar, u32 vdev_id, 4858 4812 struct ieee80211_mutable_offsets *offs, 4859 4813 struct sk_buff *bcn); ··· 4966 4916 struct sk_buff *tmpl); 4967 4917 int ath12k_wmi_set_hw_mode(struct ath12k_base *ab, 4968 4918 enum wmi_host_hw_mode_config_type mode); 4919 + 4920 + static inline u32 4921 + ath12k_wmi_caps_ext_get_pdev_id(const struct ath12k_wmi_caps_ext_params *param) 4922 + { 4923 + return le32_get_bits(param->pdev_and_hw_link_ids, WMI_CAPS_PARAMS_PDEV_ID); 4924 + } 4925 + 4926 + static inline u32 4927 + ath12k_wmi_caps_ext_get_hw_link_id(const struct ath12k_wmi_caps_ext_params *param) 4928 + { 4929 + return le32_get_bits(param->pdev_and_hw_link_ids, WMI_CAPS_PARAMS_HW_LINK_ID); 4930 + } 4931 + 4932 + static inline u32 4933 + ath12k_wmi_mac_phy_get_pdev_id(const struct ath12k_wmi_mac_phy_caps_params *param) 4934 + { 4935 + return le32_get_bits(param->pdev_and_hw_link_ids, 4936 + WMI_CAPS_PARAMS_PDEV_ID); 4937 + } 4938 + 4939 + static inline u32 4940 + ath12k_wmi_mac_phy_get_hw_link_id(const struct ath12k_wmi_mac_phy_caps_params *param) 4941 + { 4942 + return le32_get_bits(param->pdev_and_hw_link_ids, 4943 + WMI_CAPS_PARAMS_HW_LINK_ID); 4944 + } 4969 4945 4970 4946 #endif
+1 -1
drivers/net/wireless/ath/ath9k/beacon.c
··· 365 365 if (!vif || !vif->bss_conf.csa_active) 366 366 return false; 367 367 368 - if (!ieee80211_beacon_cntdwn_is_complete(vif)) 368 + if (!ieee80211_beacon_cntdwn_is_complete(vif, 0)) 369 369 return false; 370 370 371 371 ieee80211_csa_finish(vif, 0);
+1 -1
drivers/net/wireless/ath/ath9k/htc.h
··· 306 306 DECLARE_BITMAP(tx_slot, MAX_TX_BUF_NUM); 307 307 struct timer_list cleanup_timer; 308 308 spinlock_t tx_lock; 309 - bool initialized; 310 309 }; 311 310 312 311 struct ath9k_htc_tx_ctl { ··· 514 515 unsigned long ps_usecount; 515 516 bool ps_enabled; 516 517 bool ps_idle; 518 + bool initialized; 517 519 518 520 #ifdef CONFIG_MAC80211_LEDS 519 521 enum led_brightness brightness;
+1 -1
drivers/net/wireless/ath/ath9k/htc_drv_beacon.c
··· 514 514 if (!vif || !vif->bss_conf.csa_active) 515 515 return false; 516 516 517 - if (!ieee80211_beacon_cntdwn_is_complete(vif)) 517 + if (!ieee80211_beacon_cntdwn_is_complete(vif, 0)) 518 518 return false; 519 519 520 520 ieee80211_csa_finish(vif, 0);
+4
drivers/net/wireless/ath/ath9k/htc_drv_init.c
··· 966 966 967 967 htc_handle->drv_priv = priv; 968 968 969 + /* Allow ath9k_wmi_event_tasklet() to operate. */ 970 + smp_wmb(); 971 + priv->initialized = true; 972 + 969 973 return 0; 970 974 971 975 err_init:
-4
drivers/net/wireless/ath/ath9k/htc_drv_txrx.c
··· 815 815 skb_queue_head_init(&priv->tx.data_vo_queue); 816 816 skb_queue_head_init(&priv->tx.tx_failed); 817 817 818 - /* Allow ath9k_wmi_event_tasklet(WMI_TXSTATUS_EVENTID) to operate. */ 819 - smp_wmb(); 820 - priv->tx.initialized = true; 821 - 822 818 return 0; 823 819 } 824 820
+6 -4
drivers/net/wireless/ath/ath9k/wmi.c
··· 155 155 } 156 156 spin_unlock_irqrestore(&wmi->wmi_lock, flags); 157 157 158 + /* Check if ath9k_htc_probe_device() completed. */ 159 + if (!data_race(priv->initialized)) { 160 + kfree_skb(skb); 161 + continue; 162 + } 163 + 158 164 hdr = (struct wmi_cmd_hdr *) skb->data; 159 165 cmd_id = be16_to_cpu(hdr->command_id); 160 166 wmi_event = skb_pull(skb, sizeof(struct wmi_cmd_hdr)); ··· 175 169 &wmi->drv_priv->fatal_work); 176 170 break; 177 171 case WMI_TXSTATUS_EVENTID: 178 - /* Check if ath9k_tx_init() completed. */ 179 - if (!data_race(priv->tx.initialized)) 180 - break; 181 - 182 172 spin_lock_bh(&priv->tx.tx_lock); 183 173 if (priv->tx.flags & ATH9K_HTC_OP_TX_DRAIN) { 184 174 spin_unlock_bh(&priv->tx.tx_lock);
+1 -2
drivers/net/wireless/ath/ath9k/xmit.c
··· 369 369 struct list_head bf_head; 370 370 struct ath_tx_status ts; 371 371 struct ath_frame_info *fi; 372 - int ret; 373 372 374 373 memset(&ts, 0, sizeof(ts)); 375 374 INIT_LIST_HEAD(&bf_head); 376 375 377 - while ((ret = ath_tid_dequeue(tid, &skb)) == 0) { 376 + while (ath_tid_dequeue(tid, &skb) == 0) { 378 377 fi = get_frame_info(skb); 379 378 bf = fi->bf; 380 379
+1 -1
drivers/net/wireless/ath/carl9170/tx.c
··· 189 189 190 190 static int carl9170_alloc_dev_space(struct ar9170 *ar, struct sk_buff *skb) 191 191 { 192 - struct _carl9170_tx_superframe *super = (void *) skb->data; 192 + struct _carl9170_tx_superframe *super; 193 193 unsigned int chunks; 194 194 int cookie = -1; 195 195
+9
drivers/net/wireless/broadcom/brcm80211/brcmfmac/dmi.c
··· 83 83 .driver_data = (void *)&acepc_t8_data, 84 84 }, 85 85 { 86 + /* ACEPC W5 Pro Cherry Trail Z8350 HDMI stick, same wifi as the T8 */ 87 + .matches = { 88 + DMI_MATCH(DMI_BOARD_NAME, "T3 MRD"), 89 + DMI_MATCH(DMI_CHASSIS_TYPE, "3"), 90 + DMI_MATCH(DMI_BIOS_VENDOR, "American Megatrends Inc."), 91 + }, 92 + .driver_data = (void *)&acepc_t8_data, 93 + }, 94 + { 86 95 /* Chuwi Hi8 Pro with D2D3_Hi8Pro.233 BIOS */ 87 96 .matches = { 88 97 DMI_EXACT_MATCH(DMI_BOARD_VENDOR, "Hampoo"),
+1 -1
drivers/net/wireless/intel/iwlwifi/cfg/bz.c
··· 10 10 #include "fw/api/txq.h" 11 11 12 12 /* Highest firmware API version supported */ 13 - #define IWL_BZ_UCODE_API_MAX 89 13 + #define IWL_BZ_UCODE_API_MAX 90 14 14 15 15 /* Lowest firmware API version supported */ 16 16 #define IWL_BZ_UCODE_API_MIN 80
+1 -1
drivers/net/wireless/intel/iwlwifi/cfg/sc.c
··· 10 10 #include "fw/api/txq.h" 11 11 12 12 /* Highest firmware API version supported */ 13 - #define IWL_SC_UCODE_API_MAX 89 13 + #define IWL_SC_UCODE_API_MAX 90 14 14 15 15 /* Lowest firmware API version supported */ 16 16 #define IWL_SC_UCODE_API_MIN 82
+4 -6
drivers/net/wireless/intel/iwlwifi/fw/api/mac-cfg.h
··· 373 373 * iwl_link_ctx_cfg_cmd::bss_color_disable 374 374 * @LINK_CONTEXT_MODIFY_EHT_PARAMS: covers iwl_link_ctx_cfg_cmd::puncture_mask. 375 375 * This flag can be set only if the MAC that this link relates to has 376 - * eht_support set to true. 376 + * eht_support set to true. No longer used since _VER_3 of this command. 377 377 * @LINK_CONTEXT_MODIFY_ALL: set all above flags 378 378 */ 379 379 enum iwl_link_ctx_modify_flags { ··· 462 462 * @bi: beacon interval in TU, applicable only when associated 463 463 * @dtim_interval: DTIM interval in TU. 464 464 * Relevant only for GO, otherwise this is offloaded. 465 - * @puncture_mask: puncture mask for EHT 465 + * @puncture_mask: puncture mask for EHT (removed in VER_3) 466 466 * @frame_time_rts_th: HE duration RTS threshold, in units of 32us 467 467 * @flags: a combination from &enum iwl_link_ctx_flags 468 468 * @flags_mask: what of %flags have changed. Also &enum iwl_link_ctx_flags ··· 505 505 struct iwl_he_backoff_conf trig_based_txf[AC_NUM]; 506 506 __le32 bi; 507 507 __le32 dtim_interval; 508 - __le16 puncture_mask; 508 + __le16 puncture_mask; /* removed in _VER_3 */ 509 509 __le16 frame_time_rts_th; 510 510 __le32 flags; 511 511 __le32 flags_mask; ··· 519 519 u8 ibss_bssid_addr[6]; 520 520 __le16 reserved_for_ibss_bssid_addr; 521 521 __le32 reserved3[8]; 522 - } __packed; /* LINK_CONTEXT_CONFIG_CMD_API_S_VER_1 and 523 - * LINK_CONTEXT_CONFIG_CMD_API_S_VER_2 524 - */ 522 + } __packed; /* LINK_CONTEXT_CONFIG_CMD_API_S_VER_1, _VER_2, _VER_3 */ 525 523 526 524 /* Currently FW supports link ids in the range 0-3 and can have 527 525 * at most two active links for each vif.
+2 -2
drivers/net/wireless/intel/iwlwifi/fw/api/nvm-reg.h
··· 1 1 /* SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause */ 2 2 /* 3 - * Copyright (C) 2012-2014, 2018-2023 Intel Corporation 3 + * Copyright (C) 2012-2014, 2018-2024 Intel Corporation 4 4 * Copyright (C) 2013-2015 Intel Mobile Communications GmbH 5 5 * Copyright (C) 2016-2017 Intel Deutschland GmbH 6 6 */ ··· 462 462 } __packed; /* TAS_CONFIG_CMD_API_S_VER_3 */ 463 463 464 464 /** 465 - * struct iwl_tas_config_cmd_v3 - configures the TAS 465 + * struct iwl_tas_config_cmd_v4 - configures the TAS 466 466 * @override_tas_iec: indicates whether to override default value of IEC regulatory 467 467 * @enable_tas_iec: in case override_tas_iec is set - 468 468 * indicates whether IEC regulatory is enabled or disabled
+5 -4
drivers/net/wireless/intel/iwlwifi/fw/api/phy-ctxt.h
··· 156 156 __le32 lmac_id; 157 157 union { 158 158 __le32 rxchain_info; /* reserved in _VER_4 */ 159 - struct { /* used for _VER_5 */ 159 + struct { /* used for _VER_5/_VER_6 */ 160 160 u8 sbb_bandwidth; 161 161 u8 sbb_ctrl_channel_loc; 162 - __le16 reserved; 163 - } v5; 162 + __le16 puncture_mask; /* added in VER_6 */ 163 + }; 164 164 }; 165 165 __le32 dsp_cfg_flags; 166 166 __le32 reserved; 167 167 } __packed; /* PHY_CONTEXT_CMD_API_VER_3, 168 168 * PHY_CONTEXT_CMD_API_VER_4, 169 - * PHY_CONTEXT_CMD_API_VER_5 169 + * PHY_CONTEXT_CMD_API_VER_5, 170 + * PHY_CONTEXT_CMD_API_VER_6 170 171 */ 171 172 172 173 #endif /* __iwl_fw_api_phy_ctxt_h__ */
+2 -1
drivers/net/wireless/intel/iwlwifi/iwl-drv.c
··· 1 1 // SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause 2 2 /* 3 - * Copyright (C) 2005-2014, 2018-2023 Intel Corporation 3 + * Copyright (C) 2005-2014, 2018-2024 Intel Corporation 4 4 * Copyright (C) 2013-2015 Intel Mobile Communications GmbH 5 5 * Copyright (C) 2016-2017 Intel Deutschland GmbH 6 6 */ ··· 187 187 case IWL_CFG_RF_TYPE_HR1: 188 188 case IWL_CFG_RF_TYPE_HR2: 189 189 rf = "hr"; 190 + rf_step = 'b'; 190 191 break; 191 192 case IWL_CFG_RF_TYPE_GF: 192 193 rf = "gf";
+20 -16
drivers/net/wireless/intel/iwlwifi/iwl-fh.h
··· 1 1 /* SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause */ 2 2 /* 3 - * Copyright (C) 2005-2014, 2018-2021, 2023 Intel Corporation 3 + * Copyright (C) 2005-2014, 2018-2021, 2023-2024 Intel Corporation 4 4 * Copyright (C) 2015-2017 Intel Deutschland GmbH 5 5 */ 6 6 #ifndef __iwl_fh_h__ ··· 570 570 /** 571 571 * struct iwl_rb_status - reserve buffer status 572 572 * host memory mapped FH registers 573 - * @closed_rb_num [0:11] - Indicates the index of the RB which was closed 574 - * @closed_fr_num [0:11] - Indicates the index of the RX Frame which was closed 575 - * @finished_rb_num [0:11] - Indicates the index of the current RB 573 + * @closed_rb_num: [0:11] Indicates the index of the RB which was closed 574 + * @closed_fr_num: [0:11] Indicates the index of the RX Frame which was closed 575 + * @finished_rb_num: [0:11] Indicates the index of the current RB 576 576 * in which the last frame was written to 577 - * @finished_fr_num [0:11] - Indicates the index of the RX Frame 577 + * @finished_fr_num: [0:11] Indicates the index of the RX Frame 578 578 * which was transferred 579 + * @__spare: reserved 579 580 */ 580 581 struct iwl_rb_status { 581 582 __le16 closed_rb_num; 582 583 __le16 closed_fr_num; 583 584 __le16 finished_rb_num; 584 - __le16 finished_fr_nam; 585 + __le16 finished_fr_num; 585 586 __le32 __spare; 586 587 } __packed; 587 588 ··· 652 651 * 653 652 * This structure contains dma address and length of transmission address 654 653 * 655 - * @tb_len length of the tx buffer 656 - * @addr 64 bits dma address 654 + * @tb_len: length of the tx buffer 655 + * @addr: 64 bits dma address 657 656 */ 658 657 struct iwl_tfh_tb { 659 658 __le16 tb_len; 660 659 __le64 addr; 661 660 } __packed; 662 661 663 - /** 662 + /* 664 663 * Each Tx queue uses a circular buffer of 256 TFDs stored in host DRAM. 665 664 * Both driver and device share these circular buffers, each of which must be 666 665 * contiguous 256 TFDs. ··· 699 698 700 699 /** 701 700 * struct iwl_tfh_tfd - Transmit Frame Descriptor (TFD) 702 - * @ num_tbs 0-4 number of active tbs 703 - * 5 -15 reserved 704 - * @ tbs[25] transmit frame buffer descriptors 705 - * @ __pad padding 701 + * @num_tbs: 702 + * 0-4 number of active tbs 703 + * 5-15 reserved 704 + * @tbs: transmit frame buffer descriptors 705 + * @__pad: padding 706 706 */ 707 707 struct iwl_tfh_tfd { 708 708 __le16 num_tbs; ··· 720 718 * struct iwlagn_schedq_bc_tbl scheduler byte count table 721 719 * base physical address provided by SCD_DRAM_BASE_ADDR 722 720 * For devices up to 22000: 723 - * @tfd_offset 0-12 - tx command byte count 721 + * @tfd_offset: 722 + * For devices up to 22000: 723 + * 0-12 - tx command byte count 724 724 * 12-16 - station index 725 - * For 22000: 726 - * @tfd_offset 0-12 - tx command byte count 725 + * For 22000: 726 + * 0-12 - tx command byte count 727 727 * 12-13 - number of 64 byte chunks 728 728 * 14-16 - reserved 729 729 */
+7 -4
drivers/net/wireless/intel/iwlwifi/mvm/d3.c
··· 720 720 struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif); 721 721 struct ieee80211_chanctx_conf *ctx; 722 722 u8 chains_static, chains_dynamic; 723 - struct cfg80211_chan_def chandef; 723 + struct cfg80211_chan_def chandef, ap_def; 724 724 int ret, i; 725 725 struct iwl_binding_cmd_v1 binding_cmd = {}; 726 726 struct iwl_time_quota_cmd quota_cmd = {}; ··· 742 742 return -EINVAL; 743 743 } 744 744 chandef = ctx->def; 745 + ap_def = ctx->ap; 745 746 chains_static = ctx->rx_chains_static; 746 747 chains_dynamic = ctx->rx_chains_dynamic; 747 748 rcu_read_unlock(); 748 749 749 750 ret = iwl_mvm_phy_ctxt_add(mvm, mvmvif->deflink.phy_ctxt, &chandef, 750 - chains_static, chains_dynamic); 751 + &ap_def, chains_static, chains_dynamic); 751 752 if (ret) 752 753 return ret; 753 754 ··· 1290 1289 mvmvif = iwl_mvm_vif_from_mac80211(vif); 1291 1290 1292 1291 mvm_link = mvmvif->link[primary_link]; 1293 - if (WARN_ON_ONCE(!mvm_link)) 1294 - return -EINVAL; 1292 + if (WARN_ON_ONCE(!mvm_link)) { 1293 + ret = -EINVAL; 1294 + goto out_noreset; 1295 + } 1295 1296 1296 1297 if (mvm_link->ap_sta_id == IWL_MVM_INVALID_STA) { 1297 1298 /* if we're not associated, this must be netdetect */
+3 -2
drivers/net/wireless/intel/iwlwifi/mvm/debugfs-vif.c
··· 592 592 593 593 for_each_vif_active_link(vif, link_conf, link_id) { 594 594 struct ieee80211_chanctx_conf *chanctx_conf; 595 - struct cfg80211_chan_def min_def; 595 + struct cfg80211_chan_def min_def, ap_def; 596 596 struct iwl_mvm_phy_ctxt *phy_ctxt; 597 597 u8 chains_static, chains_dynamic; 598 598 ··· 606 606 * everything here and use it after unlocking 607 607 */ 608 608 min_def = chanctx_conf->min_def; 609 + ap_def = chanctx_conf->ap; 609 610 chains_static = chanctx_conf->rx_chains_static; 610 611 chains_dynamic = chanctx_conf->rx_chains_dynamic; 611 612 rcu_read_unlock(); ··· 615 614 if (!phy_ctxt) 616 615 continue; 617 616 618 - ret = iwl_mvm_phy_ctxt_changed(mvm, phy_ctxt, &min_def, 617 + ret = iwl_mvm_phy_ctxt_changed(mvm, phy_ctxt, &min_def, &ap_def, 619 618 chains_static, chains_dynamic); 620 619 } 621 620
+1 -1
drivers/net/wireless/intel/iwlwifi/mvm/ftm-responder.c
··· 438 438 rcu_read_unlock(); 439 439 440 440 phy_ctxt = &mvm->phy_ctxts[*phy_ctxt_id]; 441 - ret = iwl_mvm_phy_ctxt_changed(mvm, phy_ctxt, &ctx.def, 441 + ret = iwl_mvm_phy_ctxt_changed(mvm, phy_ctxt, &ctx.def, &ctx.ap, 442 442 ctx.rx_chains_static, 443 443 ctx.rx_chains_dynamic); 444 444 if (ret)
+2 -1
drivers/net/wireless/intel/iwlwifi/mvm/link.c
··· 204 204 def = iwl_mvm_chanctx_def(mvm, ctx); 205 205 206 206 if (iwlwifi_mod_params.disable_11be || 207 - !link_conf->eht_support || !def) 207 + !link_conf->eht_support || !def || 208 + iwl_fw_lookup_cmd_ver(mvm->fw, PHY_CONTEXT_CMD, 1) >= 6) 208 209 changes &= ~LINK_CONTEXT_MODIFY_EHT_PARAMS; 209 210 else 210 211 cmd.puncture_mask = cpu_to_le16(def->punctured);
+1 -1
drivers/net/wireless/intel/iwlwifi/mvm/mac-ctxt.c
··· 1466 1466 1467 1467 mvmvif->csa_countdown = true; 1468 1468 1469 - if (!ieee80211_beacon_cntdwn_is_complete(csa_vif)) { 1469 + if (!ieee80211_beacon_cntdwn_is_complete(csa_vif, 0)) { 1470 1470 int c = ieee80211_beacon_update_cntdwn(csa_vif, 0); 1471 1471 1472 1472 iwl_mvm_mac_ctxt_beacon_changed(mvm, csa_vif,
+6 -3
drivers/net/wireless/intel/iwlwifi/mvm/mac80211.c
··· 1644 1644 IEEE80211_VIF_SUPPORTS_CQM_RSSI; 1645 1645 } 1646 1646 1647 + if (vif->p2p || iwl_fw_lookup_cmd_ver(mvm->fw, PHY_CONTEXT_CMD, 1) < 5) 1648 + vif->driver_flags |= IEEE80211_VIF_IGNORE_OFDMA_WIDER_BW; 1649 + 1647 1650 if (vif->type == NL80211_IFTYPE_P2P_DEVICE) 1648 1651 mvm->p2p_device_vif = vif; 1649 1652 ··· 4654 4651 cfg80211_chandef_create(&chandef, channel, NL80211_CHAN_NO_HT); 4655 4652 4656 4653 return iwl_mvm_phy_ctxt_add(mvm, mvmvif->deflink.phy_ctxt, 4657 - &chandef, 1, 1); 4654 + &chandef, NULL, 1, 1); 4658 4655 } 4659 4656 4660 4657 /* Execute the common part for MLD and non-MLD modes */ ··· 4775 4772 goto out; 4776 4773 } 4777 4774 4778 - ret = iwl_mvm_phy_ctxt_add(mvm, phy_ctxt, def, 4775 + ret = iwl_mvm_phy_ctxt_add(mvm, phy_ctxt, def, &ctx->ap, 4779 4776 ctx->rx_chains_static, 4780 4777 ctx->rx_chains_dynamic); 4781 4778 if (ret) { ··· 4853 4850 } 4854 4851 4855 4852 iwl_mvm_bt_coex_vif_change(mvm); 4856 - iwl_mvm_phy_ctxt_changed(mvm, phy_ctxt, def, 4853 + iwl_mvm_phy_ctxt_changed(mvm, phy_ctxt, def, &ctx->ap, 4857 4854 ctx->rx_chains_static, 4858 4855 ctx->rx_chains_dynamic); 4859 4856
+3
drivers/net/wireless/intel/iwlwifi/mvm/mvm.h
··· 106 106 /* track for RLC config command */ 107 107 u32 center_freq1; 108 108 bool rlc_disabled; 109 + u32 channel_load_by_us; 109 110 }; 110 111 111 112 struct iwl_mvm_time_event_data { ··· 1811 1810 struct iwl_mvm_phy_ctxt *iwl_mvm_get_free_phy_ctxt(struct iwl_mvm *mvm); 1812 1811 int iwl_mvm_phy_ctxt_add(struct iwl_mvm *mvm, struct iwl_mvm_phy_ctxt *ctxt, 1813 1812 const struct cfg80211_chan_def *chandef, 1813 + const struct cfg80211_chan_def *ap, 1814 1814 u8 chains_static, u8 chains_dynamic); 1815 1815 int iwl_mvm_phy_ctxt_changed(struct iwl_mvm *mvm, struct iwl_mvm_phy_ctxt *ctxt, 1816 1816 const struct cfg80211_chan_def *chandef, 1817 + const struct cfg80211_chan_def *ap, 1817 1818 u8 chains_static, u8 chains_dynamic); 1818 1819 void iwl_mvm_phy_ctxt_ref(struct iwl_mvm *mvm, 1819 1820 struct iwl_mvm_phy_ctxt *ctxt);
+20 -6
drivers/net/wireless/intel/iwlwifi/mvm/phy-ctxt.c
··· 1 1 // SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause 2 2 /* 3 - * Copyright (C) 2012-2014, 2018-2023 Intel Corporation 3 + * Copyright (C) 2012-2014, 2018-2024 Intel Corporation 4 4 * Copyright (C) 2013-2014 Intel Mobile Communications GmbH 5 5 * Copyright (C) 2017 Intel Deutschland GmbH 6 6 */ ··· 198 198 static int iwl_mvm_phy_ctxt_apply(struct iwl_mvm *mvm, 199 199 struct iwl_mvm_phy_ctxt *ctxt, 200 200 const struct cfg80211_chan_def *chandef, 201 + const struct cfg80211_chan_def *ap, 201 202 u8 chains_static, u8 chains_dynamic, 202 203 u32 action) 203 204 { 204 205 int ret; 205 206 int ver = iwl_fw_lookup_cmd_ver(mvm->fw, PHY_CONTEXT_CMD, 1); 206 207 207 - if (ver >= 3 && ver <= 5) { 208 + if (ver < 5 || !ap || !ap->chan) 209 + ap = NULL; 210 + 211 + if (ver >= 3 && ver <= 6) { 208 212 struct iwl_phy_context_cmd cmd = {}; 209 213 210 214 /* Set the command header fields */ ··· 218 214 iwl_mvm_phy_ctxt_cmd_data(mvm, ctxt, &cmd, chandef, 219 215 chains_static, 220 216 chains_dynamic); 217 + 218 + if (ap) { 219 + cmd.sbb_bandwidth = iwl_mvm_get_channel_width(ap); 220 + cmd.sbb_ctrl_channel_loc = iwl_mvm_get_ctrl_pos(ap); 221 + } 222 + 223 + if (ver == 6) 224 + cmd.puncture_mask = cpu_to_le16(chandef->punctured); 221 225 222 226 ret = iwl_mvm_send_cmd_pdu(mvm, PHY_CONTEXT_CMD, 223 227 0, sizeof(cmd), &cmd); ··· 267 255 */ 268 256 int iwl_mvm_phy_ctxt_add(struct iwl_mvm *mvm, struct iwl_mvm_phy_ctxt *ctxt, 269 257 const struct cfg80211_chan_def *chandef, 258 + const struct cfg80211_chan_def *ap, 270 259 u8 chains_static, u8 chains_dynamic) 271 260 { 272 261 int ret; ··· 280 267 ctxt->width = chandef->width; 281 268 ctxt->center_freq1 = chandef->center_freq1; 282 269 283 - ret = iwl_mvm_phy_ctxt_apply(mvm, ctxt, chandef, 270 + ret = iwl_mvm_phy_ctxt_apply(mvm, ctxt, chandef, ap, 284 271 chains_static, chains_dynamic, 285 272 FW_CTXT_ACTION_ADD); 286 273 ··· 314 301 */ 315 302 int iwl_mvm_phy_ctxt_changed(struct iwl_mvm *mvm, struct iwl_mvm_phy_ctxt *ctxt, 316 303 const struct cfg80211_chan_def *chandef, 304 + const struct cfg80211_chan_def *ap, 317 305 u8 chains_static, u8 chains_dynamic) 318 306 { 319 307 enum iwl_ctxt_action action = FW_CTXT_ACTION_MODIFY; ··· 338 324 int ret; 339 325 340 326 /* ... remove it here ...*/ 341 - ret = iwl_mvm_phy_ctxt_apply(mvm, ctxt, chandef, 327 + ret = iwl_mvm_phy_ctxt_apply(mvm, ctxt, chandef, NULL, 342 328 chains_static, chains_dynamic, 343 329 FW_CTXT_ACTION_REMOVE); 344 330 if (ret) ··· 352 338 ctxt->width = chandef->width; 353 339 ctxt->center_freq1 = chandef->center_freq1; 354 340 355 - return iwl_mvm_phy_ctxt_apply(mvm, ctxt, chandef, 341 + return iwl_mvm_phy_ctxt_apply(mvm, ctxt, chandef, ap, 356 342 chains_static, chains_dynamic, 357 343 action); 358 344 } ··· 372 358 373 359 cfg80211_chandef_create(&chandef, ctxt->channel, NL80211_CHAN_NO_HT); 374 360 375 - iwl_mvm_phy_ctxt_apply(mvm, ctxt, &chandef, 1, 1, 361 + iwl_mvm_phy_ctxt_apply(mvm, ctxt, &chandef, NULL, 1, 1, 376 362 FW_CTXT_ACTION_REMOVE); 377 363 } 378 364
+16 -1
drivers/net/wireless/intel/iwlwifi/mvm/rx.c
··· 1 1 // SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause 2 2 /* 3 - * Copyright (C) 2012-2014, 2018-2023 Intel Corporation 3 + * Copyright (C) 2012-2014, 2018-2024 Intel Corporation 4 4 * Copyright (C) 2013-2015 Intel Mobile Communications GmbH 5 5 * Copyright (C) 2016-2017 Intel Deutschland GmbH 6 6 */ ··· 752 752 spin_unlock(&mvm->tcm.lock); 753 753 } 754 754 755 + static void iwl_mvm_handle_per_phy_stats(struct iwl_mvm *mvm, 756 + struct iwl_stats_ntfy_per_phy *per_phy) 757 + { 758 + int i; 759 + 760 + for (i = 0; i < NUM_PHY_CTX; i++) { 761 + if (!mvm->phy_ctxts[i].ref) 762 + continue; 763 + mvm->phy_ctxts[i].channel_load_by_us = 764 + le32_to_cpu(per_phy[i].channel_load_by_us); 765 + } 766 + } 767 + 755 768 static void 756 769 iwl_mvm_stats_ver_15(struct iwl_mvm *mvm, 757 770 struct iwl_statistics_operational_ntfy *stats) ··· 779 766 IEEE80211_IFACE_ITER_NORMAL, 780 767 iwl_mvm_stat_iterator_all_macs, 781 768 &data); 769 + iwl_mvm_handle_per_phy_stats(mvm, stats->per_phy); 782 770 } 783 771 784 772 static void ··· 956 942 957 943 ieee80211_iterate_stations_atomic(mvm->hw, iwl_mvm_stats_energy_iter, 958 944 average_energy); 945 + iwl_mvm_handle_per_phy_stats(mvm, stats->per_phy); 959 946 } 960 947 961 948 void iwl_mvm_handle_rx_system_oper_part1_stats(struct iwl_mvm *mvm,
+1 -1
drivers/net/wireless/intel/iwlwifi/mvm/time-event.c
··· 156 156 * So we just do nothing here and the switch 157 157 * will be performed on the last TBTT. 158 158 */ 159 - if (!ieee80211_beacon_cntdwn_is_complete(csa_vif)) { 159 + if (!ieee80211_beacon_cntdwn_is_complete(csa_vif, 0)) { 160 160 IWL_WARN(mvm, "CSA NOA started too early\n"); 161 161 goto out_unlock; 162 162 }
+2 -2
drivers/net/wireless/mediatek/mt76/mac80211.c
··· 1613 1613 static void 1614 1614 __mt76_csa_finish(void *priv, u8 *mac, struct ieee80211_vif *vif) 1615 1615 { 1616 - if (vif->bss_conf.csa_active && ieee80211_beacon_cntdwn_is_complete(vif)) 1616 + if (vif->bss_conf.csa_active && ieee80211_beacon_cntdwn_is_complete(vif, 0)) 1617 1617 ieee80211_csa_finish(vif, 0); 1618 1618 } 1619 1619 ··· 1638 1638 if (!vif->bss_conf.csa_active) 1639 1639 return; 1640 1640 1641 - dev->csa_complete |= ieee80211_beacon_cntdwn_is_complete(vif); 1641 + dev->csa_complete |= ieee80211_beacon_cntdwn_is_complete(vif, 0); 1642 1642 } 1643 1643 1644 1644 void mt76_csa_check(struct mt76_dev *dev)
+1 -1
drivers/net/wireless/microchip/wilc1000/cfg80211.c
··· 356 356 memcpy(vif->auth.ssid.ssid, sme->ssid, sme->ssid_len); 357 357 vif->auth.ssid.ssid_len = sme->ssid_len; 358 358 } 359 - vif->auth.key_mgmt_suite = cpu_to_be32(sme->crypto.akm_suites[0]); 359 + vif->auth.key_mgmt_suite = sme->crypto.akm_suites[0]; 360 360 ether_addr_copy(vif->auth.bssid, sme->bssid); 361 361 break; 362 362
+3 -3
drivers/net/wireless/microchip/wilc1000/spi.c
··· 194 194 /* assert ENABLE: */ 195 195 gpiod_set_value(gpios->enable, 1); 196 196 mdelay(5); 197 - /* assert RESET: */ 198 - gpiod_set_value(gpios->reset, 1); 199 - } else { 200 197 /* deassert RESET: */ 201 198 gpiod_set_value(gpios->reset, 0); 199 + } else { 200 + /* assert RESET: */ 201 + gpiod_set_value(gpios->reset, 1); 202 202 /* deassert ENABLE: */ 203 203 gpiod_set_value(gpios->enable, 0); 204 204 }
+3 -3
drivers/net/wireless/realtek/rtl8xxxu/rtl8xxxu_core.c
··· 5550 5550 struct rtl8xxxu_tx_urb *tx_urb; 5551 5551 struct ieee80211_sta *sta = NULL; 5552 5552 struct ieee80211_vif *vif = tx_info->control.vif; 5553 - struct rtl8xxxu_vif *rtlvif = (struct rtl8xxxu_vif *)vif->drv_priv; 5553 + struct rtl8xxxu_vif *rtlvif = vif ? (struct rtl8xxxu_vif *)vif->drv_priv : NULL; 5554 5554 struct device *dev = &priv->udev->dev; 5555 5555 u32 queue, rts_rate; 5556 5556 u16 pktlen = skb->len; ··· 5621 5621 default: 5622 5622 break; 5623 5623 } 5624 - if (bmc && rtlvif->hw_key_idx != 0xff) { 5624 + if (bmc && rtlvif && rtlvif->hw_key_idx != 0xff) { 5625 5625 tx_desc->txdw1 |= cpu_to_le32(TXDESC_EN_DESC_ID); 5626 5626 macid = rtlvif->hw_key_idx; 5627 5627 } ··· 5739 5739 } 5740 5740 5741 5741 if (vif->bss_conf.csa_active) { 5742 - if (ieee80211_beacon_cntdwn_is_complete(vif)) { 5742 + if (ieee80211_beacon_cntdwn_is_complete(vif, 0)) { 5743 5743 ieee80211_csa_finish(vif, 0); 5744 5744 return; 5745 5745 }
+3 -3
drivers/net/wireless/realtek/rtlwifi/rtl8192cu/hw.c
··· 622 622 u16 valuelow; 623 623 624 624 switch (queue_sel) { 625 + default: 626 + WARN_ON(1); 627 + fallthrough; 625 628 case (TX_SELE_HQ | TX_SELE_LQ): 626 629 valuehi = QUEUE_HIGH; 627 630 valuelow = QUEUE_LOW; ··· 636 633 case (TX_SELE_HQ | TX_SELE_NQ): 637 634 valuehi = QUEUE_HIGH; 638 635 valuelow = QUEUE_NORMAL; 639 - break; 640 - default: 641 - WARN_ON(1); 642 636 break; 643 637 } 644 638 if (!wmm_enable) {
+17 -12
drivers/net/wireless/realtek/rtlwifi/rtl8192cu/trx.c
··· 482 482 struct rtl_priv *rtlpriv = rtl_priv(hw); 483 483 struct rtl_mac *mac = rtl_mac(rtl_priv(hw)); 484 484 struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw)); 485 - u8 *qc = ieee80211_get_qos_ctl(hdr); 486 - u8 tid = qc[0] & IEEE80211_QOS_CTL_TID_MASK; 485 + struct rtl_sta_info *sta_entry; 486 + u8 agg_state = RTL_AGG_STOP; 487 + u8 ampdu_density = 0; 487 488 u16 seq_number; 488 489 __le16 fc = hdr->frame_control; 489 490 u8 rate_flag = info->control.rates[0].flags; ··· 493 492 skb_get_queue_mapping(skb)); 494 493 u8 *txdesc8; 495 494 __le32 *txdesc; 495 + u8 tid; 496 496 497 497 seq_number = (le16_to_cpu(hdr->seq_ctrl) & IEEE80211_SCTL_SEQ) >> 4; 498 498 rtl_get_tcb_desc(hw, info, sta, skb, tcb_desc); ··· 507 505 set_tx_desc_tx_rate(txdesc, tcb_desc->hw_rate); 508 506 if (tcb_desc->use_shortgi || tcb_desc->use_shortpreamble) 509 507 set_tx_desc_data_shortgi(txdesc, 1); 510 - if (mac->tids[tid].agg.agg_state == RTL_AGG_ON && 511 - info->flags & IEEE80211_TX_CTL_AMPDU) { 508 + 509 + if (sta) { 510 + sta_entry = (struct rtl_sta_info *)sta->drv_priv; 511 + tid = ieee80211_get_tid(hdr); 512 + agg_state = sta_entry->tids[tid].agg.agg_state; 513 + ampdu_density = sta->deflink.ht_cap.ampdu_density; 514 + } 515 + 516 + if (agg_state == RTL_AGG_OPERATIONAL && 517 + info->flags & IEEE80211_TX_CTL_AMPDU) { 512 518 set_tx_desc_agg_enable(txdesc, 1); 513 519 set_tx_desc_max_agg_num(txdesc, 0x14); 520 + set_tx_desc_ampdu_density(txdesc, ampdu_density); 521 + tcb_desc->rts_enable = 1; 522 + tcb_desc->rts_rate = DESC_RATE24M; 514 523 } else { 515 524 set_tx_desc_agg_break(txdesc, 1); 516 525 } ··· 556 543 set_tx_desc_data_bw(txdesc, 0); 557 544 set_tx_desc_data_sc(txdesc, 0); 558 545 } 559 - rcu_read_lock(); 560 - sta = ieee80211_find_sta(mac->vif, mac->bssid); 561 - if (sta) { 562 - u8 ampdu_density = sta->deflink.ht_cap.ampdu_density; 563 - 564 - set_tx_desc_ampdu_density(txdesc, ampdu_density); 565 - } 566 - rcu_read_unlock(); 567 546 if (info->control.hw_key) { 568 547 struct ieee80211_key_conf *keyconf = info->control.hw_key; 569 548
-2
drivers/net/wireless/realtek/rtlwifi/rtl8192cu/trx.h
··· 10 10 #define RTL92C_SIZE_MAX_RX_BUFFER 15360 /* 8192 */ 11 11 #define RX_DRV_INFO_SIZE_UNIT 8 12 12 13 - #define RTL_AGG_ON 1 14 - 15 13 enum usb_rx_agg_mode { 16 14 USB_RX_AGG_DISABLE, 17 15 USB_RX_AGG_DMA,
-3
drivers/net/wireless/realtek/rtlwifi/wifi.h
··· 1397 1397 #define RTL_AGG_PROGRESS 1 1398 1398 #define RTL_AGG_START 2 1399 1399 #define RTL_AGG_OPERATIONAL 3 1400 - #define RTL_AGG_OFF 0 1401 - #define RTL_AGG_ON 1 1402 1400 #define RTL_RX_AGG_START 1 1403 1401 #define RTL_RX_AGG_STOP 0 1404 1402 #define RTL_AGG_EMPTYING_HW_QUEUE_ADDBA 2 ··· 1471 1473 enum nl80211_iftype opmode; 1472 1474 1473 1475 /*Probe Beacon management */ 1474 - struct rtl_tid_data tids[MAX_TID_COUNT]; 1475 1476 enum rtl_link_state link_state; 1476 1477 1477 1478 int n_channels;
+44 -2
drivers/net/wireless/virtual/mac80211_hwsim.c
··· 2305 2305 rcu_dereference(link_conf->chanctx_conf)->def.chan); 2306 2306 } 2307 2307 2308 - if (link_conf->csa_active && ieee80211_beacon_cntdwn_is_complete(vif)) 2308 + if (link_conf->csa_active && ieee80211_beacon_cntdwn_is_complete(vif, link_id)) 2309 2309 ieee80211_csa_finish(vif, link_id); 2310 2310 } 2311 2311 ··· 3215 3215 } 3216 3216 } 3217 3217 3218 + static int mac80211_hwsim_switch_vif_chanctx(struct ieee80211_hw *hw, 3219 + struct ieee80211_vif_chanctx_switch *vifs, 3220 + int n_vifs, 3221 + enum ieee80211_chanctx_switch_mode mode) 3222 + { 3223 + int i; 3224 + 3225 + if (n_vifs <= 0) 3226 + return -EINVAL; 3227 + 3228 + wiphy_dbg(hw->wiphy, 3229 + "switch vif channel context mode: %u\n", mode); 3230 + 3231 + for (i = 0; i < n_vifs; i++) { 3232 + hwsim_check_chanctx_magic(vifs[i].old_ctx); 3233 + wiphy_dbg(hw->wiphy, 3234 + "switch vif channel context: %d MHz/width: %d/cfreqs:%d/%d MHz -> %d MHz/width: %d/cfreqs:%d/%d MHz\n", 3235 + vifs[i].old_ctx->def.chan->center_freq, 3236 + vifs[i].old_ctx->def.width, 3237 + vifs[i].old_ctx->def.center_freq1, 3238 + vifs[i].old_ctx->def.center_freq2, 3239 + vifs[i].new_ctx->def.chan->center_freq, 3240 + vifs[i].new_ctx->def.width, 3241 + vifs[i].new_ctx->def.center_freq1, 3242 + vifs[i].new_ctx->def.center_freq2); 3243 + 3244 + switch (mode) { 3245 + case CHANCTX_SWMODE_REASSIGN_VIF: 3246 + hwsim_check_chanctx_magic(vifs[i].new_ctx); 3247 + break; 3248 + case CHANCTX_SWMODE_SWAP_CONTEXTS: 3249 + hwsim_set_chanctx_magic(vifs[i].new_ctx); 3250 + hwsim_clear_chanctx_magic(vifs[i].old_ctx); 3251 + break; 3252 + default: 3253 + WARN_ON("Invalid mode"); 3254 + } 3255 + } 3256 + return 0; 3257 + } 3258 + 3218 3259 static const char mac80211_hwsim_gstrings_stats[][ETH_GSTRING_LEN] = { 3219 3260 "tx_pkts_nic", 3220 3261 "tx_bytes_nic", ··· 3981 3940 .remove_chanctx = mac80211_hwsim_remove_chanctx, \ 3982 3941 .change_chanctx = mac80211_hwsim_change_chanctx, \ 3983 3942 .assign_vif_chanctx = mac80211_hwsim_assign_vif_chanctx,\ 3984 - .unassign_vif_chanctx = mac80211_hwsim_unassign_vif_chanctx, 3943 + .unassign_vif_chanctx = mac80211_hwsim_unassign_vif_chanctx, \ 3944 + .switch_vif_chanctx = mac80211_hwsim_switch_vif_chanctx, 3985 3945 3986 3946 static const struct ieee80211_ops mac80211_hwsim_mchan_ops = { 3987 3947 HWSIM_COMMON_OPS
+44 -5
include/linux/ieee80211.h
··· 4990 4990 4991 4991 /** 4992 4992 * ieee80211_mle_get_bss_param_ch_cnt - returns the BSS parameter change count 4993 - * @mle: the basic multi link element 4993 + * @data: pointer to the basic multi link element 4994 4994 * 4995 4995 * The element is assumed to be of the correct type (BASIC) and big enough, 4996 4996 * this must be checked using ieee80211_mle_type_ok(). 4997 4997 * 4998 4998 * If the BSS parameter change count value can't be found (the presence bit 4999 - * for it is clear), 0 will be returned. 4999 + * for it is clear), -1 will be returned. 5000 5000 */ 5001 - static inline u8 5002 - ieee80211_mle_get_bss_param_ch_cnt(const struct ieee80211_multi_link_elem *mle) 5001 + static inline int 5002 + ieee80211_mle_get_bss_param_ch_cnt(const u8 *data) 5003 5003 { 5004 + const struct ieee80211_multi_link_elem *mle = (const void *)data; 5004 5005 u16 control = le16_to_cpu(mle->control); 5005 5006 const u8 *common = mle->variable; 5006 5007 ··· 5009 5008 common += sizeof(struct ieee80211_mle_basic_common_info); 5010 5009 5011 5010 if (!(control & IEEE80211_MLC_BASIC_PRES_BSS_PARAM_CH_CNT)) 5012 - return 0; 5011 + return -1; 5013 5012 5014 5013 if (control & IEEE80211_MLC_BASIC_PRES_LINK_ID) 5015 5014 common += 1; ··· 5113 5112 common += 2; 5114 5113 5115 5114 return get_unaligned_le16(common); 5115 + } 5116 + 5117 + /** 5118 + * ieee80211_mle_get_mld_id - returns the MLD ID 5119 + * @data: pointer to the multi link element 5120 + * 5121 + * The element is assumed to be of the correct type (BASIC) and big enough, 5122 + * this must be checked using ieee80211_mle_type_ok(). 5123 + * 5124 + * If the MLD ID is not present, 0 will be returned. 5125 + */ 5126 + static inline u8 ieee80211_mle_get_mld_id(const u8 *data) 5127 + { 5128 + const struct ieee80211_multi_link_elem *mle = (const void *)data; 5129 + u16 control = le16_to_cpu(mle->control); 5130 + const u8 *common = mle->variable; 5131 + 5132 + /* 5133 + * common points now at the beginning of 5134 + * ieee80211_mle_basic_common_info 5135 + */ 5136 + common += sizeof(struct ieee80211_mle_basic_common_info); 5137 + 5138 + if (!(control & IEEE80211_MLC_BASIC_PRES_MLD_ID)) 5139 + return 0; 5140 + 5141 + if (control & IEEE80211_MLC_BASIC_PRES_LINK_ID) 5142 + common += 1; 5143 + if (control & IEEE80211_MLC_BASIC_PRES_BSS_PARAM_CH_CNT) 5144 + common += 1; 5145 + if (control & IEEE80211_MLC_BASIC_PRES_MED_SYNC_DELAY) 5146 + common += 2; 5147 + if (control & IEEE80211_MLC_BASIC_PRES_EML_CAPA) 5148 + common += 2; 5149 + if (control & IEEE80211_MLC_BASIC_PRES_MLD_CAPA_OP) 5150 + common += 2; 5151 + 5152 + return *common; 5116 5153 } 5117 5154 5118 5155 /**
+4 -1
include/linux/units.h
··· 24 24 #define NANOHZ_PER_HZ 1000000000UL 25 25 #define MICROHZ_PER_HZ 1000000UL 26 26 #define MILLIHZ_PER_HZ 1000UL 27 + 27 28 #define HZ_PER_KHZ 1000UL 28 - #define KHZ_PER_MHZ 1000UL 29 29 #define HZ_PER_MHZ 1000000UL 30 + 31 + #define KHZ_PER_MHZ 1000UL 32 + #define KHZ_PER_GHZ 1000000UL 30 33 31 34 #define MILLIWATT_PER_WATT 1000UL 32 35 #define MICROWATT_PER_MILLIWATT 1000UL
+2
include/net/cfg80211.h
··· 7175 7175 * from a beacon or probe response 7176 7176 * @CFG80211_BSS_FTYPE_BEACON: data comes from a beacon 7177 7177 * @CFG80211_BSS_FTYPE_PRESP: data comes from a probe response 7178 + * @CFG80211_BSS_FTYPE_S1G_BEACON: data comes from an S1G beacon 7178 7179 */ 7179 7180 enum cfg80211_bss_frame_type { 7180 7181 CFG80211_BSS_FTYPE_UNKNOWN, 7181 7182 CFG80211_BSS_FTYPE_BEACON, 7182 7183 CFG80211_BSS_FTYPE_PRESP, 7184 + CFG80211_BSS_FTYPE_S1G_BEACON, 7183 7185 }; 7184 7186 7185 7187 /**
+8 -1
include/net/mac80211.h
··· 557 557 * to that BSS) that can change during the lifetime of the BSS. 558 558 * 559 559 * @vif: reference to owning VIF 560 + * @bss: the cfg80211 bss descriptor. Valid only for a station, and only 561 + * when associated. Note: This contains information which is not 562 + * necessarily authenticated. For example, information coming from probe 563 + * responses. 560 564 * @addr: (link) address used locally 561 565 * @link_id: link ID, or 0 for non-MLO 562 566 * @htc_trig_based_pkt_ext: default PE in 4us units, if BSS supports HE ··· 704 700 */ 705 701 struct ieee80211_bss_conf { 706 702 struct ieee80211_vif *vif; 703 + struct cfg80211_bss *bss; 707 704 708 705 const u8 *bssid; 709 706 unsigned int link_id; ··· 5571 5566 /** 5572 5567 * ieee80211_beacon_cntdwn_is_complete - find out if countdown reached 1 5573 5568 * @vif: &struct ieee80211_vif pointer from the add_interface callback. 5569 + * @link_id: valid link_id during MLO or 0 for non-MLO 5574 5570 * 5575 5571 * This function returns whether the countdown reached zero. 5576 5572 */ 5577 - bool ieee80211_beacon_cntdwn_is_complete(struct ieee80211_vif *vif); 5573 + bool ieee80211_beacon_cntdwn_is_complete(struct ieee80211_vif *vif, 5574 + unsigned int link_id); 5578 5575 5579 5576 /** 5580 5577 * ieee80211_color_change_finish - notify mac80211 about color change
-2
net/mac80211/ieee80211_i.h
··· 1006 1006 int mu_edca_last_param_set; 1007 1007 1008 1008 u8 bss_param_ch_cnt; 1009 - 1010 - struct cfg80211_bss *bss; 1011 1009 }; 1012 1010 1013 1011 struct ieee80211_link_data_ap {
+1 -5
net/mac80211/mesh_pathtbl.c
··· 600 600 void mesh_fast_tx_gc(struct ieee80211_sub_if_data *sdata) 601 601 { 602 602 unsigned long timeout = msecs_to_jiffies(MESH_FAST_TX_CACHE_TIMEOUT); 603 - struct mesh_tx_cache *cache; 603 + struct mesh_tx_cache *cache = &sdata->u.mesh.tx_cache; 604 604 struct ieee80211_mesh_fast_tx *entry; 605 605 struct hlist_node *n; 606 606 607 - cache = &sdata->u.mesh.tx_cache; 608 607 if (atomic_read(&cache->rht.nelems) < MESH_FAST_TX_CACHE_THRESHOLD_SIZE) 609 608 return; 610 609 ··· 621 622 struct ieee80211_mesh_fast_tx *entry; 622 623 struct hlist_node *n; 623 624 624 - cache = &sdata->u.mesh.tx_cache; 625 625 spin_lock_bh(&cache->walk_lock); 626 626 hlist_for_each_entry_safe(entry, n, &cache->walk_head, walk_list) 627 627 if (entry->mpath == mpath) ··· 635 637 struct ieee80211_mesh_fast_tx *entry; 636 638 struct hlist_node *n; 637 639 638 - cache = &sdata->u.mesh.tx_cache; 639 640 spin_lock_bh(&cache->walk_lock); 640 641 hlist_for_each_entry_safe(entry, n, &cache->walk_head, walk_list) 641 642 if (rcu_access_pointer(entry->mpath->next_hop) == sta) ··· 648 651 struct mesh_tx_cache *cache = &sdata->u.mesh.tx_cache; 649 652 struct ieee80211_mesh_fast_tx *entry; 650 653 651 - cache = &sdata->u.mesh.tx_cache; 652 654 spin_lock_bh(&cache->walk_lock); 653 655 entry = rhashtable_lookup_fast(&cache->rht, addr, fast_tx_rht_params); 654 656 if (entry)
+14 -13
net/mac80211/mlme.c
··· 2015 2015 struct ieee80211_sub_if_data *sdata = link->sdata; 2016 2016 struct ieee80211_local *local = sdata->local; 2017 2017 struct ieee80211_if_managed *ifmgd = &sdata->u.mgd; 2018 - struct cfg80211_bss *cbss = link->u.mgd.bss; 2018 + struct cfg80211_bss *cbss = link->conf->bss; 2019 2019 struct ieee80211_chanctx_conf *conf; 2020 2020 struct ieee80211_chanctx *chanctx; 2021 2021 enum nl80211_band current_band; ··· 2928 2928 2929 2929 ieee80211_check_rate_mask(link); 2930 2930 2931 - link->u.mgd.bss = cbss; 2931 + link->conf->bss = cbss; 2932 2932 memcpy(link->u.mgd.bssid, cbss->bssid, ETH_ALEN); 2933 2933 2934 2934 if (sdata->vif.p2p || ··· 3076 3076 ifmgd->associated = false; 3077 3077 3078 3078 /* other links will be destroyed */ 3079 - sdata->deflink.u.mgd.bss = NULL; 3079 + sdata->deflink.conf->bss = NULL; 3080 3080 sdata->deflink.smps_mode = IEEE80211_SMPS_OFF; 3081 3081 3082 3082 netif_carrier_off(sdata->dev); ··· 3406 3406 ieee80211_mlme_send_probe_req(sdata, sdata->vif.addr, dst, 3407 3407 sdata->vif.cfg.ssid, 3408 3408 sdata->vif.cfg.ssid_len, 3409 - sdata->deflink.u.mgd.bss->channel); 3409 + sdata->deflink.conf->bss->channel); 3410 3410 } 3411 3411 3412 3412 ifmgd->probe_timeout = jiffies + msecs_to_jiffies(probe_wait_ms); ··· 3489 3489 return NULL; 3490 3490 3491 3491 if (ifmgd->associated) 3492 - cbss = sdata->deflink.u.mgd.bss; 3492 + cbss = sdata->deflink.conf->bss; 3493 3493 else if (ifmgd->auth_data) 3494 3494 cbss = ifmgd->auth_data->bss; 3495 3495 else if (ifmgd->assoc_data && ifmgd->assoc_data->link[0].bss) ··· 3568 3568 link = sdata_dereference(sdata->link[link_id], sdata); 3569 3569 if (!link) 3570 3570 continue; 3571 - cfg80211_unlink_bss(local->hw.wiphy, link->u.mgd.bss); 3572 - link->u.mgd.bss = NULL; 3571 + cfg80211_unlink_bss(local->hw.wiphy, link->conf->bss); 3572 + link->conf->bss = NULL; 3573 3573 } 3574 3574 } 3575 3575 ··· 4202 4202 */ 4203 4203 assoc_data->link[link_id].status = WLAN_STATUS_SUCCESS; 4204 4204 if (elems->ml_basic) { 4205 - if (!(elems->ml_basic->control & 4206 - cpu_to_le16(IEEE80211_MLC_BASIC_PRES_BSS_PARAM_CH_CNT))) { 4205 + int bss_param_ch_cnt = 4206 + ieee80211_mle_get_bss_param_ch_cnt((const void *)elems->ml_basic); 4207 + 4208 + if (bss_param_ch_cnt < 0) { 4207 4209 ret = false; 4208 4210 goto out; 4209 4211 } 4210 - link->u.mgd.bss_param_ch_cnt = 4211 - ieee80211_mle_get_bss_param_ch_cnt(elems->ml_basic); 4212 + link->u.mgd.bss_param_ch_cnt = bss_param_ch_cnt; 4212 4213 } 4213 4214 } else if (elems->parse_error & IEEE80211_PARSE_ERR_DUP_NEST_ML_BASIC || 4214 4215 !elems->prof || ··· 6209 6208 } 6210 6209 6211 6210 if (!ifmgd->associated || 6212 - !ieee80211_rx_our_beacon(bssid, link->u.mgd.bss)) 6211 + !ieee80211_rx_our_beacon(bssid, link->conf->bss)) 6213 6212 return; 6214 6213 bssid = link->u.mgd.bssid; 6215 6214 ··· 6236 6235 */ 6237 6236 if (!ieee80211_is_s1g_beacon(hdr->frame_control)) 6238 6237 ncrc = crc32_be(0, (void *)&mgmt->u.beacon.beacon_int, 4); 6239 - parse_params.bss = link->u.mgd.bss; 6238 + parse_params.bss = link->conf->bss; 6240 6239 parse_params.filter = care_about_ies; 6241 6240 parse_params.crc = ncrc; 6242 6241 elems = ieee802_11_parse_elems_full(&parse_params);
+12 -2
net/mac80211/tx.c
··· 5095 5095 } 5096 5096 EXPORT_SYMBOL(ieee80211_beacon_set_cntdwn); 5097 5097 5098 - bool ieee80211_beacon_cntdwn_is_complete(struct ieee80211_vif *vif) 5098 + bool ieee80211_beacon_cntdwn_is_complete(struct ieee80211_vif *vif, 5099 + unsigned int link_id) 5099 5100 { 5100 5101 struct ieee80211_sub_if_data *sdata = vif_to_sdata(vif); 5102 + struct ieee80211_link_data *link; 5101 5103 struct beacon_data *beacon = NULL; 5102 5104 u8 *beacon_data; 5103 5105 size_t beacon_data_len; ··· 5108 5106 if (!ieee80211_sdata_running(sdata)) 5109 5107 return false; 5110 5108 5109 + if (WARN_ON(link_id >= IEEE80211_MLD_MAX_NUM_LINKS)) 5110 + return 0; 5111 + 5111 5112 rcu_read_lock(); 5113 + 5114 + link = rcu_dereference(sdata->link[link_id]); 5115 + if (!link) 5116 + goto out; 5117 + 5112 5118 if (vif->type == NL80211_IFTYPE_AP) { 5113 - beacon = rcu_dereference(sdata->deflink.u.ap.beacon); 5119 + beacon = rcu_dereference(link->u.ap.beacon); 5114 5120 if (WARN_ON(!beacon || !beacon->tail)) 5115 5121 goto out; 5116 5122 beacon_data = beacon->tail;
+74 -82
net/wireless/nl80211.c
··· 10048 10048 return 0; 10049 10049 } 10050 10050 10051 + static int nl80211_parse_counter_offsets(struct cfg80211_registered_device *rdev, 10052 + const u8 *data, size_t datalen, 10053 + int first_count, struct nlattr *attr, 10054 + const u16 **offsets, unsigned int *n_offsets) 10055 + { 10056 + int i; 10057 + 10058 + *n_offsets = 0; 10059 + 10060 + if (!attr) 10061 + return 0; 10062 + 10063 + if (!nla_len(attr) || (nla_len(attr) % sizeof(u16))) 10064 + return -EINVAL; 10065 + 10066 + *n_offsets = nla_len(attr) / sizeof(u16); 10067 + if (rdev->wiphy.max_num_csa_counters && 10068 + (*n_offsets > rdev->wiphy.max_num_csa_counters)) 10069 + return -EINVAL; 10070 + 10071 + *offsets = nla_data(attr); 10072 + 10073 + /* sanity checks - counters should fit and be the same */ 10074 + for (i = 0; i < *n_offsets; i++) { 10075 + u16 offset = (*offsets)[i]; 10076 + 10077 + if (offset >= datalen) 10078 + return -EINVAL; 10079 + 10080 + if (first_count != -1 && data[offset] != first_count) 10081 + return -EINVAL; 10082 + } 10083 + 10084 + return 0; 10085 + } 10086 + 10051 10087 static int nl80211_channel_switch(struct sk_buff *skb, struct genl_info *info) 10052 10088 { 10053 10089 struct cfg80211_registered_device *rdev = info->user_ptr[0]; ··· 10095 10059 int err; 10096 10060 bool need_new_beacon = false; 10097 10061 bool need_handle_dfs_flag = true; 10098 - int len, i; 10099 10062 u32 cs_count; 10100 10063 10101 10064 if (!rdev->ops->channel_switch || ··· 10179 10144 goto free; 10180 10145 } 10181 10146 10182 - len = nla_len(csa_attrs[NL80211_ATTR_CNTDWN_OFFS_BEACON]); 10183 - if (!len || (len % sizeof(u16))) { 10184 - err = -EINVAL; 10147 + err = nl80211_parse_counter_offsets(rdev, params.beacon_csa.tail, 10148 + params.beacon_csa.tail_len, 10149 + params.count, 10150 + csa_attrs[NL80211_ATTR_CNTDWN_OFFS_BEACON], 10151 + &params.counter_offsets_beacon, 10152 + &params.n_counter_offsets_beacon); 10153 + if (err) 10185 10154 goto free; 10186 - } 10187 10155 10188 - params.n_counter_offsets_beacon = len / sizeof(u16); 10189 - if (rdev->wiphy.max_num_csa_counters && 10190 - (params.n_counter_offsets_beacon > 10191 - rdev->wiphy.max_num_csa_counters)) { 10192 - err = -EINVAL; 10156 + err = nl80211_parse_counter_offsets(rdev, params.beacon_csa.probe_resp, 10157 + params.beacon_csa.probe_resp_len, 10158 + params.count, 10159 + csa_attrs[NL80211_ATTR_CNTDWN_OFFS_PRESP], 10160 + &params.counter_offsets_presp, 10161 + &params.n_counter_offsets_presp); 10162 + if (err) 10193 10163 goto free; 10194 - } 10195 - 10196 - params.counter_offsets_beacon = 10197 - nla_data(csa_attrs[NL80211_ATTR_CNTDWN_OFFS_BEACON]); 10198 - 10199 - /* sanity checks - counters should fit and be the same */ 10200 - for (i = 0; i < params.n_counter_offsets_beacon; i++) { 10201 - u16 offset = params.counter_offsets_beacon[i]; 10202 - 10203 - if (offset >= params.beacon_csa.tail_len) { 10204 - err = -EINVAL; 10205 - goto free; 10206 - } 10207 - 10208 - if (params.beacon_csa.tail[offset] != params.count) { 10209 - err = -EINVAL; 10210 - goto free; 10211 - } 10212 - } 10213 - 10214 - if (csa_attrs[NL80211_ATTR_CNTDWN_OFFS_PRESP]) { 10215 - len = nla_len(csa_attrs[NL80211_ATTR_CNTDWN_OFFS_PRESP]); 10216 - if (!len || (len % sizeof(u16))) { 10217 - err = -EINVAL; 10218 - goto free; 10219 - } 10220 - 10221 - params.n_counter_offsets_presp = len / sizeof(u16); 10222 - if (rdev->wiphy.max_num_csa_counters && 10223 - (params.n_counter_offsets_presp > 10224 - rdev->wiphy.max_num_csa_counters)) { 10225 - err = -EINVAL; 10226 - goto free; 10227 - } 10228 - 10229 - params.counter_offsets_presp = 10230 - nla_data(csa_attrs[NL80211_ATTR_CNTDWN_OFFS_PRESP]); 10231 - 10232 - /* sanity checks - counters should fit and be the same */ 10233 - for (i = 0; i < params.n_counter_offsets_presp; i++) { 10234 - u16 offset = params.counter_offsets_presp[i]; 10235 - 10236 - if (offset >= params.beacon_csa.probe_resp_len) { 10237 - err = -EINVAL; 10238 - goto free; 10239 - } 10240 - 10241 - if (params.beacon_csa.probe_resp[offset] != 10242 - params.count) { 10243 - err = -EINVAL; 10244 - goto free; 10245 - } 10246 - } 10247 - } 10248 10164 10249 10165 skip_beacons: 10250 10166 err = nl80211_parse_chandef(rdev, info, &params.chandef); ··· 12624 12638 params.buf = nla_data(info->attrs[NL80211_ATTR_FRAME]); 12625 12639 params.len = nla_len(info->attrs[NL80211_ATTR_FRAME]); 12626 12640 12627 - if (info->attrs[NL80211_ATTR_CSA_C_OFFSETS_TX]) { 12628 - int len = nla_len(info->attrs[NL80211_ATTR_CSA_C_OFFSETS_TX]); 12629 - int i; 12630 - 12631 - if (len % sizeof(u16)) 12632 - return -EINVAL; 12633 - 12634 - params.n_csa_offsets = len / sizeof(u16); 12635 - params.csa_offsets = 12636 - nla_data(info->attrs[NL80211_ATTR_CSA_C_OFFSETS_TX]); 12637 - 12638 - /* check that all the offsets fit the frame */ 12639 - for (i = 0; i < params.n_csa_offsets; i++) { 12640 - if (params.csa_offsets[i] >= params.len) 12641 - return -EINVAL; 12642 - } 12643 - } 12641 + err = nl80211_parse_counter_offsets(rdev, NULL, params.len, -1, 12642 + info->attrs[NL80211_ATTR_CSA_C_OFFSETS_TX], 12643 + &params.csa_offsets, 12644 + &params.n_csa_offsets); 12645 + if (err) 12646 + return err; 12644 12647 12645 12648 if (!params.dont_wait_for_ack) { 12646 12649 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL); ··· 20107 20132 if (!hdr) 20108 20133 goto nla_put_failure; 20109 20134 20135 + /* Some historical mistakes in drivers <-> userspace interface (notably 20136 + * between drivers and wpa_supplicant) led to a big-endian conversion 20137 + * being needed on NL80211_ATTR_AKM_SUITES _only_ when its value is 20138 + * WLAN_AKM_SUITE_SAE. This is now fixed on userspace side, but for the 20139 + * benefit of older wpa_supplicant versions, send this particular value 20140 + * in big-endian. Note that newer wpa_supplicant will also detect this 20141 + * particular value in big endian still, so it all continues to work. 20142 + */ 20143 + if (params->key_mgmt_suite == WLAN_AKM_SUITE_SAE) { 20144 + if (nla_put_be32(msg, NL80211_ATTR_AKM_SUITES, 20145 + cpu_to_be32(WLAN_AKM_SUITE_SAE))) 20146 + goto nla_put_failure; 20147 + } else { 20148 + if (nla_put_u32(msg, NL80211_ATTR_AKM_SUITES, 20149 + params->key_mgmt_suite)) 20150 + goto nla_put_failure; 20151 + } 20152 + 20110 20153 if (nla_put_u32(msg, NL80211_ATTR_WIPHY, rdev->wiphy_idx) || 20111 20154 nla_put_u32(msg, NL80211_ATTR_IFINDEX, dev->ifindex) || 20112 - nla_put_u32(msg, NL80211_ATTR_AKM_SUITES, params->key_mgmt_suite) || 20113 20155 nla_put_u32(msg, NL80211_ATTR_EXTERNAL_AUTH_ACTION, 20114 20156 params->action) || 20115 20157 nla_put(msg, NL80211_ATTR_BSSID, ETH_ALEN, params->bssid) ||
+3 -4
net/wireless/reg.c
··· 57 57 #include <linux/verification.h> 58 58 #include <linux/moduleparam.h> 59 59 #include <linux/firmware.h> 60 + #include <linux/units.h> 61 + 60 62 #include <net/cfg80211.h> 61 63 #include "core.h" 62 64 #include "reg.h" ··· 1291 1289 static bool freq_in_rule_band(const struct ieee80211_freq_range *freq_range, 1292 1290 u32 freq_khz) 1293 1291 { 1294 - #define ONE_GHZ_IN_KHZ 1000000 1295 1292 /* 1296 1293 * From 802.11ad: directional multi-gigabit (DMG): 1297 1294 * Pertaining to operation in a frequency band containing a channel 1298 1295 * with the Channel starting frequency above 45 GHz. 1299 1296 */ 1300 - u32 limit = freq_khz > 45 * ONE_GHZ_IN_KHZ ? 1301 - 20 * ONE_GHZ_IN_KHZ : 2 * ONE_GHZ_IN_KHZ; 1297 + u32 limit = freq_khz > 45 * KHZ_PER_GHZ ? 20 * KHZ_PER_GHZ : 2 * KHZ_PER_GHZ; 1302 1298 if (abs(freq_khz - freq_range->start_freq_khz) <= limit) 1303 1299 return true; 1304 1300 if (abs(freq_khz - freq_range->end_freq_khz) <= limit) 1305 1301 return true; 1306 1302 return false; 1307 - #undef ONE_GHZ_IN_KHZ 1308 1303 } 1309 1304 1310 1305 /*
+270 -349
net/wireless/scan.c
··· 611 611 return 0; 612 612 } 613 613 614 - VISIBLE_IF_CFG80211_KUNIT int 615 - cfg80211_parse_colocated_ap(const struct cfg80211_bss_ies *ies, 616 - struct list_head *list) 614 + enum cfg80211_rnr_iter_ret { 615 + RNR_ITER_CONTINUE, 616 + RNR_ITER_BREAK, 617 + RNR_ITER_ERROR, 618 + }; 619 + 620 + static bool 621 + cfg80211_iter_rnr(const u8 *elems, size_t elems_len, 622 + enum cfg80211_rnr_iter_ret 623 + (*iter)(void *data, u8 type, 624 + const struct ieee80211_neighbor_ap_info *info, 625 + const u8 *tbtt_info, u8 tbtt_info_len), 626 + void *iter_data) 617 627 { 618 - struct ieee80211_neighbor_ap_info *ap_info; 619 - const struct element *elem, *ssid_elem; 628 + const struct element *rnr; 620 629 const u8 *pos, *end; 621 - u32 s_ssid_tmp; 622 - int n_coloc = 0, ret; 623 - LIST_HEAD(ap_list); 624 630 625 - ret = cfg80211_calc_short_ssid(ies, &ssid_elem, &s_ssid_tmp); 626 - if (ret) 627 - return 0; 631 + for_each_element_id(rnr, WLAN_EID_REDUCED_NEIGHBOR_REPORT, 632 + elems, elems_len) { 633 + const struct ieee80211_neighbor_ap_info *info; 628 634 629 - for_each_element_id(elem, WLAN_EID_REDUCED_NEIGHBOR_REPORT, 630 - ies->data, ies->len) { 631 - pos = elem->data; 632 - end = elem->data + elem->datalen; 635 + pos = rnr->data; 636 + end = rnr->data + rnr->datalen; 633 637 634 638 /* RNR IE may contain more than one NEIGHBOR_AP_INFO */ 635 - while (pos + sizeof(*ap_info) <= end) { 636 - enum nl80211_band band; 637 - int freq; 639 + while (sizeof(*info) <= end - pos) { 638 640 u8 length, i, count; 641 + u8 type; 639 642 640 - ap_info = (void *)pos; 641 - count = u8_get_bits(ap_info->tbtt_info_hdr, 642 - IEEE80211_AP_INFO_TBTT_HDR_COUNT) + 1; 643 - length = ap_info->tbtt_info_len; 643 + info = (void *)pos; 644 + count = u8_get_bits(info->tbtt_info_hdr, 645 + IEEE80211_AP_INFO_TBTT_HDR_COUNT) + 646 + 1; 647 + length = info->tbtt_info_len; 644 648 645 - pos += sizeof(*ap_info); 649 + pos += sizeof(*info); 646 650 647 - if (!ieee80211_operating_class_to_band(ap_info->op_class, 648 - &band)) 649 - break; 651 + if (count * length > end - pos) 652 + return false; 650 653 651 - freq = ieee80211_channel_to_frequency(ap_info->channel, 652 - band); 653 - 654 - if (end - pos < count * length) 655 - break; 656 - 657 - if (u8_get_bits(ap_info->tbtt_info_hdr, 658 - IEEE80211_AP_INFO_TBTT_HDR_TYPE) != 659 - IEEE80211_TBTT_INFO_TYPE_TBTT) { 660 - pos += count * length; 661 - continue; 662 - } 663 - 664 - /* TBTT info must include bss param + BSSID + 665 - * (short SSID or same_ssid bit to be set). 666 - * ignore other options, and move to the 667 - * next AP info 668 - */ 669 - if (band != NL80211_BAND_6GHZ || 670 - !(length == offsetofend(struct ieee80211_tbtt_info_7_8_9, 671 - bss_params) || 672 - length == sizeof(struct ieee80211_tbtt_info_7_8_9) || 673 - length >= offsetofend(struct ieee80211_tbtt_info_ge_11, 674 - bss_params))) { 675 - pos += count * length; 676 - continue; 677 - } 654 + type = u8_get_bits(info->tbtt_info_hdr, 655 + IEEE80211_AP_INFO_TBTT_HDR_TYPE); 678 656 679 657 for (i = 0; i < count; i++) { 680 - struct cfg80211_colocated_ap *entry; 681 - 682 - entry = kzalloc(sizeof(*entry) + IEEE80211_MAX_SSID_LEN, 683 - GFP_ATOMIC); 684 - 685 - if (!entry) 686 - goto error; 687 - 688 - entry->center_freq = freq; 689 - 690 - if (!cfg80211_parse_ap_info(entry, pos, length, 691 - ssid_elem, 692 - s_ssid_tmp)) { 693 - n_coloc++; 694 - list_add_tail(&entry->list, &ap_list); 695 - } else { 696 - kfree(entry); 658 + switch (iter(iter_data, type, info, 659 + pos, length)) { 660 + case RNR_ITER_CONTINUE: 661 + break; 662 + case RNR_ITER_BREAK: 663 + return true; 664 + case RNR_ITER_ERROR: 665 + return false; 697 666 } 698 667 699 668 pos += length; 700 669 } 701 670 } 702 671 703 - error: 704 - if (pos != end) { 705 - cfg80211_free_coloc_ap_list(&ap_list); 706 - return 0; 707 - } 672 + if (pos != end) 673 + return false; 708 674 } 709 675 710 - list_splice_tail(&ap_list, list); 711 - return n_coloc; 676 + return true; 677 + } 678 + 679 + struct colocated_ap_data { 680 + const struct element *ssid_elem; 681 + struct list_head ap_list; 682 + u32 s_ssid_tmp; 683 + int n_coloc; 684 + }; 685 + 686 + static enum cfg80211_rnr_iter_ret 687 + cfg80211_parse_colocated_ap_iter(void *_data, u8 type, 688 + const struct ieee80211_neighbor_ap_info *info, 689 + const u8 *tbtt_info, u8 tbtt_info_len) 690 + { 691 + struct colocated_ap_data *data = _data; 692 + struct cfg80211_colocated_ap *entry; 693 + enum nl80211_band band; 694 + 695 + if (type != IEEE80211_TBTT_INFO_TYPE_TBTT) 696 + return RNR_ITER_CONTINUE; 697 + 698 + if (!ieee80211_operating_class_to_band(info->op_class, &band)) 699 + return RNR_ITER_CONTINUE; 700 + 701 + /* TBTT info must include bss param + BSSID + (short SSID or 702 + * same_ssid bit to be set). Ignore other options, and move to 703 + * the next AP info 704 + */ 705 + if (band != NL80211_BAND_6GHZ || 706 + !(tbtt_info_len == offsetofend(struct ieee80211_tbtt_info_7_8_9, 707 + bss_params) || 708 + tbtt_info_len == sizeof(struct ieee80211_tbtt_info_7_8_9) || 709 + tbtt_info_len >= offsetofend(struct ieee80211_tbtt_info_ge_11, 710 + bss_params))) 711 + return RNR_ITER_CONTINUE; 712 + 713 + entry = kzalloc(sizeof(*entry) + IEEE80211_MAX_SSID_LEN, GFP_ATOMIC); 714 + if (!entry) 715 + return RNR_ITER_ERROR; 716 + 717 + entry->center_freq = 718 + ieee80211_channel_to_frequency(info->channel, band); 719 + 720 + if (!cfg80211_parse_ap_info(entry, tbtt_info, tbtt_info_len, 721 + data->ssid_elem, data->s_ssid_tmp)) { 722 + data->n_coloc++; 723 + list_add_tail(&entry->list, &data->ap_list); 724 + } else { 725 + kfree(entry); 726 + } 727 + 728 + return RNR_ITER_CONTINUE; 729 + } 730 + 731 + VISIBLE_IF_CFG80211_KUNIT int 732 + cfg80211_parse_colocated_ap(const struct cfg80211_bss_ies *ies, 733 + struct list_head *list) 734 + { 735 + struct colocated_ap_data data = {}; 736 + int ret; 737 + 738 + INIT_LIST_HEAD(&data.ap_list); 739 + 740 + ret = cfg80211_calc_short_ssid(ies, &data.ssid_elem, &data.s_ssid_tmp); 741 + if (ret) 742 + return 0; 743 + 744 + if (!cfg80211_iter_rnr(ies->data, ies->len, 745 + cfg80211_parse_colocated_ap_iter, &data)) { 746 + cfg80211_free_coloc_ap_list(&data.ap_list); 747 + return 0; 748 + } 749 + 750 + list_splice_tail(&data.ap_list, list); 751 + return data.n_coloc; 712 752 } 713 753 EXPORT_SYMBOL_IF_CFG80211_KUNIT(cfg80211_parse_colocated_ap); 714 754 ··· 2127 2087 u64 cannot_use_reasons; 2128 2088 }; 2129 2089 2090 + static bool cfg80211_6ghz_power_type_valid(const u8 *ie, size_t ielen, 2091 + const u32 flags) 2092 + { 2093 + const struct element *tmp; 2094 + struct ieee80211_he_operation *he_oper; 2095 + 2096 + tmp = cfg80211_find_ext_elem(WLAN_EID_EXT_HE_OPERATION, ie, ielen); 2097 + if (tmp && tmp->datalen >= sizeof(*he_oper) + 1) { 2098 + const struct ieee80211_he_6ghz_oper *he_6ghz_oper; 2099 + 2100 + he_oper = (void *)&tmp->data[1]; 2101 + he_6ghz_oper = ieee80211_he_6ghz_oper(he_oper); 2102 + 2103 + if (!he_6ghz_oper) 2104 + return false; 2105 + 2106 + switch (u8_get_bits(he_6ghz_oper->control, 2107 + IEEE80211_HE_6GHZ_OPER_CTRL_REG_INFO)) { 2108 + case IEEE80211_6GHZ_CTRL_REG_LPI_AP: 2109 + return true; 2110 + case IEEE80211_6GHZ_CTRL_REG_SP_AP: 2111 + return !(flags & IEEE80211_CHAN_NO_6GHZ_AFC_CLIENT); 2112 + case IEEE80211_6GHZ_CTRL_REG_VLP_AP: 2113 + return !(flags & IEEE80211_CHAN_NO_6GHZ_VLP_CLIENT); 2114 + } 2115 + } 2116 + return false; 2117 + } 2118 + 2130 2119 /* Returned bss is reference counted and must be cleaned up appropriately. */ 2131 2120 static struct cfg80211_bss * 2132 2121 cfg80211_inform_single_bss_data(struct wiphy *wiphy, ··· 2188 2119 if (!channel) 2189 2120 return NULL; 2190 2121 2122 + if (channel->band == NL80211_BAND_6GHZ && 2123 + !cfg80211_6ghz_power_type_valid(data->ie, data->ielen, 2124 + channel->flags)) { 2125 + data->use_for = 0; 2126 + data->cannot_use_reasons = 2127 + NL80211_BSS_CANNOT_USE_6GHZ_PWR_MISMATCH; 2128 + } 2129 + 2191 2130 memcpy(tmp.pub.bssid, data->bssid, ETH_ALEN); 2192 2131 tmp.pub.channel = channel; 2193 2132 if (data->bss_source != BSS_SOURCE_STA_PROFILE) ··· 2207 2130 tmp.ts_boottime = drv_data->boottime_ns; 2208 2131 tmp.parent_tsf = drv_data->parent_tsf; 2209 2132 ether_addr_copy(tmp.parent_bssid, drv_data->parent_bssid); 2133 + tmp.pub.chains = drv_data->chains; 2134 + memcpy(tmp.pub.chain_signal, drv_data->chain_signal, 2135 + IEEE80211_MAX_CHAINS); 2210 2136 tmp.pub.use_for = data->use_for; 2211 2137 tmp.pub.cannot_use_reasons = data->cannot_use_reasons; 2212 2138 ··· 2253 2173 2254 2174 switch (data->ftype) { 2255 2175 case CFG80211_BSS_FTYPE_BEACON: 2176 + case CFG80211_BSS_FTYPE_S1G_BEACON: 2256 2177 ies->from_beacon = true; 2257 2178 fallthrough; 2258 2179 case CFG80211_BSS_FTYPE_UNKNOWN: ··· 2647 2566 return NULL; 2648 2567 } 2649 2568 2650 - static u8 2651 - cfg80211_tbtt_info_for_mld_ap(const u8 *ie, size_t ielen, u8 mld_id, u8 link_id, 2652 - const struct ieee80211_neighbor_ap_info **ap_info, 2653 - const u8 **tbtt_info) 2569 + struct tbtt_info_iter_data { 2570 + const struct ieee80211_neighbor_ap_info *ap_info; 2571 + u8 param_ch_count; 2572 + u32 use_for; 2573 + u8 mld_id, link_id; 2574 + }; 2575 + 2576 + static enum cfg80211_rnr_iter_ret 2577 + cfg802121_mld_ap_rnr_iter(void *_data, u8 type, 2578 + const struct ieee80211_neighbor_ap_info *info, 2579 + const u8 *tbtt_info, u8 tbtt_info_len) 2654 2580 { 2655 - const struct ieee80211_neighbor_ap_info *info; 2656 - const struct element *rnr; 2657 - const u8 *pos, *end; 2581 + const struct ieee80211_rnr_mld_params *mld_params; 2582 + struct tbtt_info_iter_data *data = _data; 2583 + u8 link_id; 2658 2584 2659 - for_each_element_id(rnr, WLAN_EID_REDUCED_NEIGHBOR_REPORT, ie, ielen) { 2660 - pos = rnr->data; 2661 - end = rnr->data + rnr->datalen; 2585 + if (type == IEEE80211_TBTT_INFO_TYPE_TBTT && 2586 + tbtt_info_len >= offsetofend(struct ieee80211_tbtt_info_ge_11, 2587 + mld_params)) 2588 + mld_params = (void *)(tbtt_info + 2589 + offsetof(struct ieee80211_tbtt_info_ge_11, 2590 + mld_params)); 2591 + else if (type == IEEE80211_TBTT_INFO_TYPE_MLD && 2592 + tbtt_info_len >= sizeof(struct ieee80211_rnr_mld_params)) 2593 + mld_params = (void *)tbtt_info; 2594 + else 2595 + return RNR_ITER_CONTINUE; 2662 2596 2663 - /* RNR IE may contain more than one NEIGHBOR_AP_INFO */ 2664 - while (sizeof(*info) <= end - pos) { 2665 - const struct ieee80211_rnr_mld_params *mld_params; 2666 - u16 params; 2667 - u8 length, i, count, mld_params_offset; 2668 - u8 type, lid; 2669 - u32 use_for; 2597 + link_id = le16_get_bits(mld_params->params, 2598 + IEEE80211_RNR_MLD_PARAMS_LINK_ID); 2670 2599 2671 - info = (void *)pos; 2672 - count = u8_get_bits(info->tbtt_info_hdr, 2673 - IEEE80211_AP_INFO_TBTT_HDR_COUNT) + 1; 2674 - length = info->tbtt_info_len; 2600 + if (data->mld_id != mld_params->mld_id) 2601 + return RNR_ITER_CONTINUE; 2675 2602 2676 - pos += sizeof(*info); 2603 + if (data->link_id != link_id) 2604 + return RNR_ITER_CONTINUE; 2677 2605 2678 - if (count * length > end - pos) 2679 - return 0; 2606 + data->ap_info = info; 2607 + data->param_ch_count = 2608 + le16_get_bits(mld_params->params, 2609 + IEEE80211_RNR_MLD_PARAMS_BSS_CHANGE_COUNT); 2680 2610 2681 - type = u8_get_bits(info->tbtt_info_hdr, 2682 - IEEE80211_AP_INFO_TBTT_HDR_TYPE); 2611 + if (type == IEEE80211_TBTT_INFO_TYPE_TBTT) 2612 + data->use_for = NL80211_BSS_USE_FOR_ALL; 2613 + else 2614 + data->use_for = NL80211_BSS_USE_FOR_MLD_LINK; 2615 + return RNR_ITER_BREAK; 2616 + } 2683 2617 2684 - if (type == IEEE80211_TBTT_INFO_TYPE_TBTT && 2685 - length >= 2686 - offsetofend(struct ieee80211_tbtt_info_ge_11, 2687 - mld_params)) { 2688 - mld_params_offset = 2689 - offsetof(struct ieee80211_tbtt_info_ge_11, mld_params); 2690 - use_for = NL80211_BSS_USE_FOR_ALL; 2691 - } else if (type == IEEE80211_TBTT_INFO_TYPE_MLD && 2692 - length >= sizeof(struct ieee80211_rnr_mld_params)) { 2693 - mld_params_offset = 0; 2694 - use_for = NL80211_BSS_USE_FOR_MLD_LINK; 2695 - } else { 2696 - pos += count * length; 2697 - continue; 2698 - } 2618 + static u8 2619 + cfg80211_rnr_info_for_mld_ap(const u8 *ie, size_t ielen, u8 mld_id, u8 link_id, 2620 + const struct ieee80211_neighbor_ap_info **ap_info, 2621 + u8 *param_ch_count) 2622 + { 2623 + struct tbtt_info_iter_data data = { 2624 + .mld_id = mld_id, 2625 + .link_id = link_id, 2626 + }; 2699 2627 2700 - for (i = 0; i < count; i++) { 2701 - mld_params = (void *)pos + mld_params_offset; 2702 - params = le16_to_cpu(mld_params->params); 2628 + cfg80211_iter_rnr(ie, ielen, cfg802121_mld_ap_rnr_iter, &data); 2703 2629 2704 - lid = u16_get_bits(params, 2705 - IEEE80211_RNR_MLD_PARAMS_LINK_ID); 2630 + *ap_info = data.ap_info; 2631 + *param_ch_count = data.param_ch_count; 2706 2632 2707 - if (mld_id == mld_params->mld_id && 2708 - link_id == lid) { 2709 - *ap_info = info; 2710 - *tbtt_info = pos; 2711 - 2712 - return use_for; 2713 - } 2714 - 2715 - pos += length; 2716 - } 2717 - } 2718 - } 2719 - 2720 - return 0; 2633 + return data.use_for; 2721 2634 } 2722 2635 2723 2636 static struct element * ··· 2833 2758 struct cfg80211_bss *bss; 2834 2759 u8 mld_id, reporter_link_id, bss_change_count; 2835 2760 u16 seen_links = 0; 2836 - const u8 *pos; 2837 2761 u8 i; 2838 2762 2839 - if (!ieee80211_mle_size_ok(elem->data + 1, elem->datalen - 1)) 2763 + if (!ieee80211_mle_type_ok(elem->data + 1, 2764 + IEEE80211_ML_CONTROL_TYPE_BASIC, 2765 + elem->datalen - 1)) 2840 2766 return; 2841 2767 2842 - ml_elem = (void *)elem->data + 1; 2768 + ml_elem = (void *)(elem->data + 1); 2843 2769 control = le16_to_cpu(ml_elem->control); 2844 - if (u16_get_bits(control, IEEE80211_ML_CONTROL_TYPE) != 2845 - IEEE80211_ML_CONTROL_TYPE_BASIC) 2846 - return; 2770 + ml_common_len = ml_elem->variable[0]; 2847 2771 2848 2772 /* Must be present when transmitted by an AP (in a probe response) */ 2849 2773 if (!(control & IEEE80211_MLC_BASIC_PRES_BSS_PARAM_CH_CNT) || ··· 2850 2776 !(control & IEEE80211_MLC_BASIC_PRES_MLD_CAPA_OP)) 2851 2777 return; 2852 2778 2853 - ml_common_len = ml_elem->variable[0]; 2854 - 2855 - /* length + MLD MAC address */ 2856 - pos = ml_elem->variable + 1 + 6; 2857 - 2858 - reporter_link_id = pos[0]; 2859 - pos += 1; 2860 - 2861 - bss_change_count = pos[0]; 2862 - pos += 1; 2863 - 2864 - if (u16_get_bits(control, IEEE80211_MLC_BASIC_PRES_MED_SYNC_DELAY)) 2865 - pos += 2; 2866 - if (u16_get_bits(control, IEEE80211_MLC_BASIC_PRES_EML_CAPA)) 2867 - pos += 2; 2868 - 2869 - /* MLD capabilities and operations */ 2870 - pos += 2; 2779 + reporter_link_id = ieee80211_mle_get_link_id(elem->data + 1); 2780 + bss_change_count = ieee80211_mle_get_bss_param_ch_cnt(elem->data + 1); 2871 2781 2872 2782 /* 2873 2783 * The MLD ID of the reporting AP is always zero. It is set if the AP ··· 2859 2801 * relating to a nontransmitted BSS (matching the Multi-BSSID Index, 2860 2802 * Draft P802.11be_D3.2, 35.3.4.2) 2861 2803 */ 2862 - if (u16_get_bits(control, IEEE80211_MLC_BASIC_PRES_MLD_ID)) { 2863 - mld_id = *pos; 2864 - pos += 1; 2865 - } else { 2866 - mld_id = 0; 2867 - } 2868 - 2869 - /* Extended MLD capabilities and operations */ 2870 - pos += 2; 2804 + mld_id = ieee80211_mle_get_mld_id(elem->data + 1); 2871 2805 2872 2806 /* Fully defrag the ML element for sta information/profile iteration */ 2873 2807 mle = cfg80211_defrag_mle(elem, tx_data->ie, tx_data->ielen, gfp); ··· 2886 2836 enum nl80211_band band; 2887 2837 u32 freq; 2888 2838 const u8 *profile; 2889 - const u8 *tbtt_info; 2890 2839 ssize_t profile_len; 2840 + u8 param_ch_count; 2891 2841 u8 link_id, use_for; 2892 2842 2893 2843 if (!ieee80211_mle_basic_sta_prof_size_ok((u8 *)mle->sta_prof[i], ··· 2930 2880 profile_len -= 2; 2931 2881 2932 2882 /* Find in RNR to look up channel information */ 2933 - use_for = cfg80211_tbtt_info_for_mld_ap(tx_data->ie, 2934 - tx_data->ielen, 2935 - mld_id, link_id, 2936 - &ap_info, &tbtt_info); 2883 + use_for = cfg80211_rnr_info_for_mld_ap(tx_data->ie, 2884 + tx_data->ielen, 2885 + mld_id, link_id, 2886 + &ap_info, 2887 + &param_ch_count); 2937 2888 if (!use_for) 2938 2889 continue; 2939 2890 ··· 2977 2926 continue; 2978 2927 2979 2928 /* Copy the Basic Multi-Link element including the common 2980 - * information, and then fix up the link ID. 2929 + * information, and then fix up the link ID and BSS param 2930 + * change count. 2981 2931 * Note that the ML element length has been verified and we 2982 2932 * also checked that it contains the link ID. 2983 2933 */ ··· 2989 2937 sizeof(*ml_elem) + ml_common_len); 2990 2938 2991 2939 new_ie[data.ielen + sizeof(*ml_elem) + 1 + ETH_ALEN] = link_id; 2940 + new_ie[data.ielen + sizeof(*ml_elem) + 1 + ETH_ALEN + 1] = 2941 + param_ch_count; 2992 2942 2993 2943 data.ielen += sizeof(*ml_elem) + ml_common_len; 2994 2944 ··· 3065 3011 if (!res) 3066 3012 return NULL; 3067 3013 3014 + /* don't do any further MBSSID/ML handling for S1G */ 3015 + if (ftype == CFG80211_BSS_FTYPE_S1G_BEACON) 3016 + return res; 3017 + 3068 3018 cfg80211_parse_mbssid_data(wiphy, &inform_data, res, gfp); 3069 3019 3070 3020 cfg80211_parse_ml_sta_data(wiphy, &inform_data, res, gfp); ··· 3077 3019 } 3078 3020 EXPORT_SYMBOL(cfg80211_inform_bss_data); 3079 3021 3080 - static bool cfg80211_uhb_power_type_valid(const u8 *ie, 3081 - size_t ielen, 3082 - const u32 flags) 3022 + struct cfg80211_bss * 3023 + cfg80211_inform_bss_frame_data(struct wiphy *wiphy, 3024 + struct cfg80211_inform_bss *data, 3025 + struct ieee80211_mgmt *mgmt, size_t len, 3026 + gfp_t gfp) 3083 3027 { 3084 - const struct element *tmp; 3085 - struct ieee80211_he_operation *he_oper; 3086 - 3087 - tmp = cfg80211_find_ext_elem(WLAN_EID_EXT_HE_OPERATION, ie, ielen); 3088 - if (tmp && tmp->datalen >= sizeof(*he_oper) + 1) { 3089 - const struct ieee80211_he_6ghz_oper *he_6ghz_oper; 3090 - 3091 - he_oper = (void *)&tmp->data[1]; 3092 - he_6ghz_oper = ieee80211_he_6ghz_oper(he_oper); 3093 - 3094 - if (!he_6ghz_oper) 3095 - return false; 3096 - 3097 - switch (u8_get_bits(he_6ghz_oper->control, 3098 - IEEE80211_HE_6GHZ_OPER_CTRL_REG_INFO)) { 3099 - case IEEE80211_6GHZ_CTRL_REG_LPI_AP: 3100 - return true; 3101 - case IEEE80211_6GHZ_CTRL_REG_SP_AP: 3102 - return !(flags & IEEE80211_CHAN_NO_6GHZ_AFC_CLIENT); 3103 - case IEEE80211_6GHZ_CTRL_REG_VLP_AP: 3104 - return !(flags & IEEE80211_CHAN_NO_6GHZ_VLP_CLIENT); 3105 - } 3106 - } 3107 - return false; 3108 - } 3109 - 3110 - /* cfg80211_inform_bss_width_frame helper */ 3111 - static struct cfg80211_bss * 3112 - cfg80211_inform_single_bss_frame_data(struct wiphy *wiphy, 3113 - struct cfg80211_inform_bss *data, 3114 - struct ieee80211_mgmt *mgmt, size_t len, 3115 - gfp_t gfp) 3116 - { 3117 - struct cfg80211_registered_device *rdev = wiphy_to_rdev(wiphy); 3118 - struct cfg80211_internal_bss tmp = {}, *res; 3119 - struct cfg80211_bss_ies *ies; 3120 - struct ieee80211_channel *channel; 3121 - bool signal_valid; 3028 + size_t min_hdr_len = offsetof(struct ieee80211_mgmt, 3029 + u.probe_resp.variable); 3122 3030 struct ieee80211_ext *ext = NULL; 3123 - u8 *bssid, *variable; 3124 - u16 capability, beacon_int; 3125 - size_t ielen, min_hdr_len = offsetof(struct ieee80211_mgmt, 3126 - u.probe_resp.variable); 3127 - int bss_type; 3128 - 3129 - BUILD_BUG_ON(offsetof(struct ieee80211_mgmt, u.probe_resp.variable) != 3130 - offsetof(struct ieee80211_mgmt, u.beacon.variable)); 3131 - 3132 - trace_cfg80211_inform_bss_frame(wiphy, data, mgmt, len); 3031 + enum cfg80211_bss_frame_type ftype; 3032 + u16 beacon_interval; 3033 + const u8 *bssid; 3034 + u16 capability; 3035 + const u8 *ie; 3036 + size_t ielen; 3037 + u64 tsf; 3133 3038 3134 3039 if (WARN_ON(!mgmt)) 3135 3040 return NULL; ··· 3100 3079 if (WARN_ON(!wiphy)) 3101 3080 return NULL; 3102 3081 3103 - if (WARN_ON(wiphy->signal_type == CFG80211_SIGNAL_TYPE_UNSPEC && 3104 - (data->signal < 0 || data->signal > 100))) 3105 - return NULL; 3082 + BUILD_BUG_ON(offsetof(struct ieee80211_mgmt, u.probe_resp.variable) != 3083 + offsetof(struct ieee80211_mgmt, u.beacon.variable)); 3084 + 3085 + trace_cfg80211_inform_bss_frame(wiphy, data, mgmt, len); 3106 3086 3107 3087 if (ieee80211_is_s1g_beacon(mgmt->frame_control)) { 3108 3088 ext = (void *) mgmt; ··· 3117 3095 return NULL; 3118 3096 3119 3097 ielen = len - min_hdr_len; 3120 - variable = mgmt->u.probe_resp.variable; 3121 - if (ext) { 3122 - if (ieee80211_is_s1g_short_beacon(mgmt->frame_control)) 3123 - variable = ext->u.s1g_short_beacon.variable; 3124 - else 3125 - variable = ext->u.s1g_beacon.variable; 3126 - } 3127 - 3128 - channel = cfg80211_get_bss_channel(wiphy, variable, ielen, data->chan); 3129 - if (!channel) 3130 - return NULL; 3131 - 3132 - if (channel->band == NL80211_BAND_6GHZ && 3133 - !cfg80211_uhb_power_type_valid(variable, ielen, channel->flags)) { 3134 - data->restrict_use = 1; 3135 - data->use_for = 0; 3136 - data->cannot_use_reasons = 3137 - NL80211_BSS_CANNOT_USE_6GHZ_PWR_MISMATCH; 3138 - } 3139 - 3098 + ie = mgmt->u.probe_resp.variable; 3140 3099 if (ext) { 3141 3100 const struct ieee80211_s1g_bcn_compat_ie *compat; 3142 3101 const struct element *elem; 3143 3102 3144 - elem = cfg80211_find_elem(WLAN_EID_S1G_BCN_COMPAT, 3145 - variable, ielen); 3103 + if (ieee80211_is_s1g_short_beacon(mgmt->frame_control)) 3104 + ie = ext->u.s1g_short_beacon.variable; 3105 + else 3106 + ie = ext->u.s1g_beacon.variable; 3107 + 3108 + elem = cfg80211_find_elem(WLAN_EID_S1G_BCN_COMPAT, ie, ielen); 3146 3109 if (!elem) 3147 3110 return NULL; 3148 3111 if (elem->datalen < sizeof(*compat)) ··· 3135 3128 compat = (void *)elem->data; 3136 3129 bssid = ext->u.s1g_beacon.sa; 3137 3130 capability = le16_to_cpu(compat->compat_info); 3138 - beacon_int = le16_to_cpu(compat->beacon_int); 3131 + beacon_interval = le16_to_cpu(compat->beacon_int); 3139 3132 } else { 3140 3133 bssid = mgmt->bssid; 3141 - beacon_int = le16_to_cpu(mgmt->u.probe_resp.beacon_int); 3134 + beacon_interval = le16_to_cpu(mgmt->u.probe_resp.beacon_int); 3142 3135 capability = le16_to_cpu(mgmt->u.probe_resp.capab_info); 3143 3136 } 3144 3137 3145 - if (channel->band == NL80211_BAND_60GHZ) { 3146 - bss_type = capability & WLAN_CAPABILITY_DMG_TYPE_MASK; 3147 - if (bss_type == WLAN_CAPABILITY_DMG_TYPE_AP || 3148 - bss_type == WLAN_CAPABILITY_DMG_TYPE_PBSS) 3149 - regulatory_hint_found_beacon(wiphy, channel, gfp); 3150 - } else { 3151 - if (capability & WLAN_CAPABILITY_ESS) 3152 - regulatory_hint_found_beacon(wiphy, channel, gfp); 3153 - } 3154 - 3155 - ies = kzalloc(sizeof(*ies) + ielen, gfp); 3156 - if (!ies) 3157 - return NULL; 3158 - ies->len = ielen; 3159 - ies->tsf = le64_to_cpu(mgmt->u.probe_resp.timestamp); 3160 - ies->from_beacon = ieee80211_is_beacon(mgmt->frame_control) || 3161 - ieee80211_is_s1g_beacon(mgmt->frame_control); 3162 - memcpy(ies->data, variable, ielen); 3138 + tsf = le64_to_cpu(mgmt->u.probe_resp.timestamp); 3163 3139 3164 3140 if (ieee80211_is_probe_resp(mgmt->frame_control)) 3165 - rcu_assign_pointer(tmp.pub.proberesp_ies, ies); 3141 + ftype = CFG80211_BSS_FTYPE_PRESP; 3142 + else if (ext) 3143 + ftype = CFG80211_BSS_FTYPE_S1G_BEACON; 3166 3144 else 3167 - rcu_assign_pointer(tmp.pub.beacon_ies, ies); 3168 - rcu_assign_pointer(tmp.pub.ies, ies); 3145 + ftype = CFG80211_BSS_FTYPE_BEACON; 3169 3146 3170 - memcpy(tmp.pub.bssid, bssid, ETH_ALEN); 3171 - tmp.pub.beacon_interval = beacon_int; 3172 - tmp.pub.capability = capability; 3173 - tmp.pub.channel = channel; 3174 - tmp.pub.signal = data->signal; 3175 - tmp.ts_boottime = data->boottime_ns; 3176 - tmp.parent_tsf = data->parent_tsf; 3177 - tmp.pub.chains = data->chains; 3178 - memcpy(tmp.pub.chain_signal, data->chain_signal, IEEE80211_MAX_CHAINS); 3179 - ether_addr_copy(tmp.parent_bssid, data->parent_bssid); 3180 - tmp.pub.use_for = data->restrict_use ? 3181 - data->use_for : 3182 - NL80211_BSS_USE_FOR_ALL; 3183 - tmp.pub.cannot_use_reasons = data->cannot_use_reasons; 3184 - 3185 - signal_valid = data->chan == channel; 3186 - spin_lock_bh(&rdev->bss_lock); 3187 - res = __cfg80211_bss_update(rdev, &tmp, signal_valid, jiffies); 3188 - if (!res) 3189 - goto drop; 3190 - 3191 - rdev_inform_bss(rdev, &res->pub, ies, data->drv_data); 3192 - 3193 - spin_unlock_bh(&rdev->bss_lock); 3194 - 3195 - trace_cfg80211_return_bss(&res->pub); 3196 - /* __cfg80211_bss_update gives us a referenced result */ 3197 - return &res->pub; 3198 - 3199 - drop: 3200 - spin_unlock_bh(&rdev->bss_lock); 3201 - return NULL; 3202 - } 3203 - 3204 - struct cfg80211_bss * 3205 - cfg80211_inform_bss_frame_data(struct wiphy *wiphy, 3206 - struct cfg80211_inform_bss *data, 3207 - struct ieee80211_mgmt *mgmt, size_t len, 3208 - gfp_t gfp) 3209 - { 3210 - struct cfg80211_inform_single_bss_data inform_data = { 3211 - .drv_data = data, 3212 - .ie = mgmt->u.probe_resp.variable, 3213 - .ielen = len - offsetof(struct ieee80211_mgmt, 3214 - u.probe_resp.variable), 3215 - .use_for = data->restrict_use ? 3216 - data->use_for : 3217 - NL80211_BSS_USE_FOR_ALL, 3218 - .cannot_use_reasons = data->cannot_use_reasons, 3219 - }; 3220 - struct cfg80211_bss *res; 3221 - 3222 - res = cfg80211_inform_single_bss_frame_data(wiphy, data, mgmt, 3223 - len, gfp); 3224 - if (!res) 3225 - return NULL; 3226 - 3227 - /* don't do any further MBSSID/ML handling for S1G */ 3228 - if (ieee80211_is_s1g_beacon(mgmt->frame_control)) 3229 - return res; 3230 - 3231 - inform_data.ftype = ieee80211_is_beacon(mgmt->frame_control) ? 3232 - CFG80211_BSS_FTYPE_BEACON : CFG80211_BSS_FTYPE_PRESP; 3233 - memcpy(inform_data.bssid, mgmt->bssid, ETH_ALEN); 3234 - inform_data.tsf = le64_to_cpu(mgmt->u.probe_resp.timestamp); 3235 - inform_data.beacon_interval = 3236 - le16_to_cpu(mgmt->u.probe_resp.beacon_int); 3237 - 3238 - /* process each non-transmitting bss */ 3239 - cfg80211_parse_mbssid_data(wiphy, &inform_data, res, gfp); 3240 - 3241 - cfg80211_parse_ml_sta_data(wiphy, &inform_data, res, gfp); 3242 - 3243 - return res; 3147 + return cfg80211_inform_bss_data(wiphy, data, ftype, 3148 + bssid, tsf, capability, 3149 + beacon_interval, ie, ielen, 3150 + gfp); 3244 3151 } 3245 3152 EXPORT_SYMBOL(cfg80211_inform_bss_frame_data); 3246 3153