diff options
author | 2025-03-04 08:50:40 -0800 | |
---|---|---|
committer | 2025-03-04 08:50:42 -0800 | |
commit | 71f8992e34a9f358a53da6bfcd8b00226df177a2 (patch) | |
tree | 99d62cb7f735cb38c336489305a9ede029a57dc8 /drivers/net | |
parent | Merge branch 'netconsole-add-taskname-sysdata-support' (diff) | |
parent | wifi: iwlwifi: remove mld/roc.c (diff) | |
download | wireguard-linux-71f8992e34a9f358a53da6bfcd8b00226df177a2.tar.xz wireguard-linux-71f8992e34a9f358a53da6bfcd8b00226df177a2.zip |
Merge tag 'wireless-next-2025-03-04-v2' of https://git.kernel.org/pub/scm/linux/kernel/git/wireless/wireless-next
Johannes Berg says:
====================
First 6.15 material:
* cfg80211/mac80211
- remove cooked monitor support
- strict mode for better AP testing
- basic EPCS support
- OMI RX bandwidth reduction support
* rtw88
- preparation for RTL8814AU support
* rtw89
- use wiphy_lock/wiphy_work
- preparations for MLO
- BT-Coex improvements
- regulatory support in firmware files
* iwlwifi
- preparations for the new iwlmld sub-driver
* tag 'wireless-next-2025-03-04-v2' of https://git.kernel.org/pub/scm/linux/kernel/git/wireless/wireless-next: (128 commits)
wifi: iwlwifi: remove mld/roc.c
wifi: mac80211: refactor populating mesh related fields in sinfo
wifi: cfg80211: reorg sinfo structure elements for mesh
wifi: iwlwifi: Fix spelling mistake "Increate" -> "Increase"
wifi: iwlwifi: add Debug Host Command APIs
wifi: iwlwifi: add IWL_MAX_NUM_IGTKS macro
wifi: iwlwifi: add OMI bandwidth reduction APIs
wifi: iwlwifi: remove mvm prefix from iwl_mvm_d3_end_notif
wifi: iwlwifi: remember if the UATS table was read successfully
wifi: iwlwifi: export iwl_get_lari_config_bitmap
wifi: iwlwifi: add support for external 32 KHz clock
wifi: iwlwifi: mld: add a debug level for EHT prints
wifi: iwlwifi: mld: add a debug level for PTP prints
wifi: iwlwifi: remove mvm prefix from iwl_mvm_esr_mode_notif
wifi: iwlwifi: use 0xff instead of 0xffffffff for invalid
wifi: iwlwifi: location api cleanup
wifi: cfg80211: expose update timestamp to drivers
wifi: mac80211: add ieee80211_iter_chan_contexts_mtx
wifi: mac80211: fix integer overflow in hwmp_route_info_get()
wifi: mac80211: Fix possible integer promotion issue
...
====================
Link: https://patch.msgid.link/20250304125605.127914-3-johannes@sipsolutions.net
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
Diffstat (limited to 'drivers/net')
121 files changed, 5276 insertions, 4450 deletions
diff --git a/drivers/net/wireless/broadcom/b43/main.c b/drivers/net/wireless/broadcom/b43/main.c index 25b4ef9d3c9a..7529afd24aed 100644 --- a/drivers/net/wireless/broadcom/b43/main.c +++ b/drivers/net/wireless/broadcom/b43/main.c @@ -2166,7 +2166,7 @@ static void b43_print_fw_helptext(struct b43_wl *wl, bool error) { const char text[] = "You must go to " \ - "https://wireless.wiki.kernel.org/en/users/Drivers/b43#devicefirmware " \ + "https://wireless.docs.kernel.org/en/latest/en/users/drivers/b43/developers.html#list-of-firmware " \ "and download the correct firmware for this driver version. " \ "Please carefully read all instructions on this website.\n"; diff --git a/drivers/net/wireless/intel/ipw2x00/ipw2200.c b/drivers/net/wireless/intel/ipw2x00/ipw2200.c index be1d971b3d32..24a5624ef207 100644 --- a/drivers/net/wireless/intel/ipw2x00/ipw2200.c +++ b/drivers/net/wireless/intel/ipw2x00/ipw2200.c @@ -3295,7 +3295,7 @@ static int ipw_init_nic(struct ipw_priv *priv) rc = ipw_poll_bit(priv, IPW_GP_CNTRL_RW, IPW_GP_CNTRL_BIT_CLOCK_READY, 250); if (rc < 0) - IPW_DEBUG_INFO("FAILED wait for clock stablization\n"); + IPW_DEBUG_INFO("FAILED wait for clock stabilization\n"); /* assert SW reset */ ipw_set_bit(priv, IPW_RESET_REG, IPW_RESET_REG_SW_RESET); diff --git a/drivers/net/wireless/intel/ipw2x00/libipw.h b/drivers/net/wireless/intel/ipw2x00/libipw.h index 3c20353e5a41..e031e8692ca6 100644 --- a/drivers/net/wireless/intel/ipw2x00/libipw.h +++ b/drivers/net/wireless/intel/ipw2x00/libipw.h @@ -1011,8 +1011,6 @@ netdev_tx_t libipw_xmit(struct sk_buff *skb, struct net_device *dev); void libipw_txb_free(struct libipw_txb *); /* libipw_rx.c */ -void libipw_rx_any(struct libipw_device *ieee, struct sk_buff *skb, - struct libipw_rx_stats *stats); int libipw_rx(struct libipw_device *ieee, struct sk_buff *skb, struct libipw_rx_stats *rx_stats); /* make sure to set stats->len */ diff --git a/drivers/net/wireless/intel/ipw2x00/libipw_rx.c b/drivers/net/wireless/intel/ipw2x00/libipw_rx.c index dc4e91f58bb4..b7bc94f7abd8 100644 --- a/drivers/net/wireless/intel/ipw2x00/libipw_rx.c +++ b/drivers/net/wireless/intel/ipw2x00/libipw_rx.c @@ -823,96 +823,6 @@ int libipw_rx(struct libipw_device *ieee, struct sk_buff *skb, return 0; } -/* Filter out unrelated packets, call libipw_rx[_mgt] - * This function takes over the skb, it should not be used again after calling - * this function. */ -void libipw_rx_any(struct libipw_device *ieee, - struct sk_buff *skb, struct libipw_rx_stats *stats) -{ - struct libipw_hdr_4addr *hdr; - int is_packet_for_us; - u16 fc; - - if (ieee->iw_mode == IW_MODE_MONITOR) { - if (!libipw_rx(ieee, skb, stats)) - dev_kfree_skb_irq(skb); - return; - } - - if (skb->len < sizeof(struct ieee80211_hdr)) - goto drop_free; - - hdr = (struct libipw_hdr_4addr *)skb->data; - fc = le16_to_cpu(hdr->frame_ctl); - - if ((fc & IEEE80211_FCTL_VERS) != 0) - goto drop_free; - - switch (fc & IEEE80211_FCTL_FTYPE) { - case IEEE80211_FTYPE_MGMT: - if (skb->len < sizeof(struct libipw_hdr_3addr)) - goto drop_free; - libipw_rx_mgt(ieee, hdr, stats); - dev_kfree_skb_irq(skb); - return; - case IEEE80211_FTYPE_DATA: - break; - case IEEE80211_FTYPE_CTL: - return; - default: - return; - } - - is_packet_for_us = 0; - switch (ieee->iw_mode) { - case IW_MODE_ADHOC: - /* our BSS and not from/to DS */ - if (ether_addr_equal(hdr->addr3, ieee->bssid) && - ((fc & (IEEE80211_FCTL_TODS + IEEE80211_FCTL_FROMDS)) == 0)) { - /* promisc: get all */ - if (ieee->dev->flags & IFF_PROMISC) - is_packet_for_us = 1; - /* to us */ - else if (ether_addr_equal(hdr->addr1, ieee->dev->dev_addr)) - is_packet_for_us = 1; - /* mcast */ - else if (is_multicast_ether_addr(hdr->addr1)) - is_packet_for_us = 1; - } - break; - case IW_MODE_INFRA: - /* our BSS (== from our AP) and from DS */ - if (ether_addr_equal(hdr->addr2, ieee->bssid) && - ((fc & (IEEE80211_FCTL_TODS + IEEE80211_FCTL_FROMDS)) == IEEE80211_FCTL_FROMDS)) { - /* promisc: get all */ - if (ieee->dev->flags & IFF_PROMISC) - is_packet_for_us = 1; - /* to us */ - else if (ether_addr_equal(hdr->addr1, ieee->dev->dev_addr)) - is_packet_for_us = 1; - /* mcast */ - else if (is_multicast_ether_addr(hdr->addr1)) { - /* not our own packet bcasted from AP */ - if (!ether_addr_equal(hdr->addr3, ieee->dev->dev_addr)) - is_packet_for_us = 1; - } - } - break; - default: - /* ? */ - break; - } - - if (is_packet_for_us) - if (!libipw_rx(ieee, skb, stats)) - dev_kfree_skb_irq(skb); - return; - -drop_free: - dev_kfree_skb_irq(skb); - ieee->dev->stats.rx_dropped++; -} - #define MGMT_FRAME_FIXED_PART_LENGTH 0x24 static u8 qos_oui[QOS_OUI_LEN] = { 0x00, 0x50, 0xF2 }; @@ -1729,6 +1639,5 @@ void libipw_rx_mgt(struct libipw_device *ieee, } } -EXPORT_SYMBOL_GPL(libipw_rx_any); EXPORT_SYMBOL(libipw_rx_mgt); EXPORT_SYMBOL(libipw_rx); diff --git a/drivers/net/wireless/intel/iwlegacy/4965-rs.c b/drivers/net/wireless/intel/iwlegacy/4965-rs.c index 718efb1aa1b0..f754fb979546 100644 --- a/drivers/net/wireless/intel/iwlegacy/4965-rs.c +++ b/drivers/net/wireless/intel/iwlegacy/4965-rs.c @@ -132,15 +132,8 @@ static void il4965_rs_fill_link_cmd(struct il_priv *il, static void il4965_rs_stay_in_table(struct il_lq_sta *lq_sta, bool force_search); -#ifdef CONFIG_MAC80211_DEBUGFS static void il4965_rs_dbgfs_set_mcs(struct il_lq_sta *lq_sta, u32 *rate_n_flags, int idx); -#else -static void -il4965_rs_dbgfs_set_mcs(struct il_lq_sta *lq_sta, u32 * rate_n_flags, int idx) -{ -} -#endif /* * The following tables contain the expected throughput metrics for all rates @@ -2495,8 +2488,6 @@ il4965_rs_free_sta(void *il_r, struct ieee80211_sta *sta, void *il_sta) D_RATE("leave\n"); } -#ifdef CONFIG_MAC80211_DEBUGFS - static void il4965_rs_dbgfs_set_mcs(struct il_lq_sta *lq_sta, u32 * rate_n_flags, int idx) { @@ -2758,7 +2749,6 @@ il4965_rs_add_debugfs(void *il, void *il_sta, struct dentry *dir) debugfs_create_u8("tx_agg_tid_enable", 0600, dir, &lq_sta->tx_agg_tid_en); } -#endif /* * Initialization of rate scaling information is done by driver after @@ -2781,9 +2771,8 @@ static const struct rate_control_ops rs_4965_ops = { .free = il4965_rs_free, .alloc_sta = il4965_rs_alloc_sta, .free_sta = il4965_rs_free_sta, -#ifdef CONFIG_MAC80211_DEBUGFS - .add_sta_debugfs = il4965_rs_add_debugfs, -#endif + .add_sta_debugfs = PTR_IF(IS_ENABLED(CONFIG_MAC80211_DEBUGFS), + il4965_rs_add_debugfs), }; int diff --git a/drivers/net/wireless/intel/iwlegacy/common.h b/drivers/net/wireless/intel/iwlegacy/common.h index 92285412ab10..52610f5e57a3 100644 --- a/drivers/net/wireless/intel/iwlegacy/common.h +++ b/drivers/net/wireless/intel/iwlegacy/common.h @@ -2815,9 +2815,7 @@ struct il_lq_sta { struct il_scale_tbl_info lq_info[LQ_SIZE]; /* "active", "search" */ struct il_traffic_load load[TID_MAX_LOAD_COUNT]; u8 tx_agg_tid_en; -#ifdef CONFIG_MAC80211_DEBUGFS u32 dbg_fixed_rate; -#endif struct il_priv *drv; /* used to be in sta_info */ diff --git a/drivers/net/wireless/intel/iwlwifi/cfg/22000.c b/drivers/net/wireless/intel/iwlwifi/cfg/22000.c index 2e2fcb3807ef..130b9a8aa7eb 100644 --- a/drivers/net/wireless/intel/iwlwifi/cfg/22000.c +++ b/drivers/net/wireless/intel/iwlwifi/cfg/22000.c @@ -205,7 +205,6 @@ const char iwl_ax101_name[] = "Intel(R) Wi-Fi 6 AX101"; const char iwl_ax200_name[] = "Intel(R) Wi-Fi 6 AX200 160MHz"; const char iwl_ax201_name[] = "Intel(R) Wi-Fi 6 AX201 160MHz"; const char iwl_ax203_name[] = "Intel(R) Wi-Fi 6 AX203"; -const char iwl_ax204_name[] = "Intel(R) Wi-Fi 6 AX204 160MHz"; const char iwl_ax200_killer_1650w_name[] = "Killer(R) Wi-Fi 6 AX1650w 160MHz Wireless Network Adapter (200D2W)"; diff --git a/drivers/net/wireless/intel/iwlwifi/cfg/ax210.c b/drivers/net/wireless/intel/iwlwifi/cfg/ax210.c index dcba1a5d793b..e87b57b9e2c0 100644 --- a/drivers/net/wireless/intel/iwlwifi/cfg/ax210.c +++ b/drivers/net/wireless/intel/iwlwifi/cfg/ax210.c @@ -180,7 +180,6 @@ const struct iwl_cfg_trans_params iwl_ma_trans_cfg = { }; const char iwl_ax211_name[] = "Intel(R) Wi-Fi 6E AX211 160MHz"; -const char iwl_ax221_name[] = "Intel(R) Wi-Fi 6E AX221 160MHz"; const char iwl_ax231_name[] = "Intel(R) Wi-Fi 6E AX231 160MHz"; const char iwl_ax411_name[] = "Intel(R) Wi-Fi 6E AX411 160MHz"; diff --git a/drivers/net/wireless/intel/iwlwifi/cfg/bz.c b/drivers/net/wireless/intel/iwlwifi/cfg/bz.c index efa3e0e35f79..64a5bbb45c83 100644 --- a/drivers/net/wireless/intel/iwlwifi/cfg/bz.c +++ b/drivers/net/wireless/intel/iwlwifi/cfg/bz.c @@ -50,6 +50,13 @@ static const struct iwl_base_params iwl_bz_base_params = { .pcie_l1_allowed = true, }; +const struct iwl_ht_params iwl_bz_ht_params = { + .stbc = true, + .ldpc = true, + .ht40_bands = BIT(NL80211_BAND_2GHZ) | BIT(NL80211_BAND_5GHZ) | + BIT(NL80211_BAND_6GHZ), +}; + #define IWL_DEVICE_BZ_COMMON \ .ucode_api_max = IWL_BZ_UCODE_API_MAX, \ .ucode_api_min = IWL_BZ_UCODE_API_MIN, \ @@ -113,7 +120,7 @@ static const struct iwl_base_params iwl_bz_base_params = { #define IWL_DEVICE_BZ \ IWL_DEVICE_BZ_COMMON, \ - .ht_params = &iwl_22000_ht_params + .ht_params = &iwl_bz_ht_params /* * This size was picked according to 8 MSDUs inside 512 A-MSDUs in an @@ -145,7 +152,6 @@ const struct iwl_cfg_trans_params iwl_gl_trans_cfg = { .low_latency_xtal = true, }; -const char iwl_bz_name[] = "Intel(R) TBD Bz device"; const char iwl_fm_name[] = "Intel(R) Wi-Fi 7 BE201 320MHz"; const char iwl_wh_name[] = "Intel(R) Wi-Fi 7 BE211 320MHz"; const char iwl_gl_name[] = "Intel(R) Wi-Fi 7 BE200 320MHz"; diff --git a/drivers/net/wireless/intel/iwlwifi/cfg/dr.c b/drivers/net/wireless/intel/iwlwifi/cfg/dr.c index ab7c0f8d54f4..69176b59b4de 100644 --- a/drivers/net/wireless/intel/iwlwifi/cfg/dr.c +++ b/drivers/net/wireless/intel/iwlwifi/cfg/dr.c @@ -114,7 +114,7 @@ static const struct iwl_base_params iwl_dr_base_params = { .uhb_supported = true, \ .features = IWL_TX_CSUM_NETIF_FLAGS | NETIF_F_RXCSUM, \ .num_rbds = IWL_NUM_RBDS_DR_EHT, \ - .ht_params = &iwl_22000_ht_params + .ht_params = &iwl_bz_ht_params /* * This size was picked according to 8 MSDUs inside 512 A-MSDUs in an diff --git a/drivers/net/wireless/intel/iwlwifi/cfg/sc.c b/drivers/net/wireless/intel/iwlwifi/cfg/sc.c index c9eeb3f6704e..eb56af9a8411 100644 --- a/drivers/net/wireless/intel/iwlwifi/cfg/sc.c +++ b/drivers/net/wireless/intel/iwlwifi/cfg/sc.c @@ -121,7 +121,7 @@ static const struct iwl_base_params iwl_sc_base_params = { .uhb_supported = true, \ .features = IWL_TX_CSUM_NETIF_FLAGS | NETIF_F_RXCSUM, \ .num_rbds = IWL_NUM_RBDS_SC_EHT, \ - .ht_params = &iwl_22000_ht_params + .ht_params = &iwl_bz_ht_params /* * This size was picked according to 8 MSDUs inside 512 A-MSDUs in an @@ -142,22 +142,16 @@ const struct iwl_cfg_trans_params iwl_sc_trans_cfg = { .ltr_delay = IWL_CFG_TRANS_LTR_DELAY_2500US, }; -const char iwl_sc_name[] = "Intel(R) TBD Sc device"; - const struct iwl_cfg iwl_cfg_sc = { .fw_name_mac = "sc", IWL_DEVICE_SC, }; -const char iwl_sc2_name[] = "Intel(R) TBD Sc2 device"; - const struct iwl_cfg iwl_cfg_sc2 = { .fw_name_mac = "sc2", IWL_DEVICE_SC, }; -const char iwl_sc2f_name[] = "Intel(R) TBD Sc2f device"; - const struct iwl_cfg iwl_cfg_sc2f = { .fw_name_mac = "sc2f", IWL_DEVICE_SC, diff --git a/drivers/net/wireless/intel/iwlwifi/dvm/tt.c b/drivers/net/wireless/intel/iwlwifi/dvm/tt.c index 43e8d04d5a8b..e1d78550e443 100644 --- a/drivers/net/wireless/intel/iwlwifi/dvm/tt.c +++ b/drivers/net/wireless/intel/iwlwifi/dvm/tt.c @@ -124,17 +124,6 @@ enum iwl_antenna_ok iwl_tx_ant_restriction(struct iwl_priv *priv) return restriction->tx_stream; } -enum iwl_antenna_ok iwl_rx_ant_restriction(struct iwl_priv *priv) -{ - struct iwl_tt_mgmt *tt = &priv->thermal_throttle; - struct iwl_tt_restriction *restriction; - - if (!priv->thermal_throttle.advanced_tt) - return IWL_ANT_OK_MULTI; - restriction = tt->restriction + tt->state; - return restriction->rx_stream; -} - #define CT_KILL_EXIT_DURATION (5) /* 5 seconds duration */ #define CT_KILL_WAITING_DURATION (300) /* 300ms duration */ diff --git a/drivers/net/wireless/intel/iwlwifi/dvm/tt.h b/drivers/net/wireless/intel/iwlwifi/dvm/tt.h index 4af792d41dce..198f934a0d16 100644 --- a/drivers/net/wireless/intel/iwlwifi/dvm/tt.h +++ b/drivers/net/wireless/intel/iwlwifi/dvm/tt.h @@ -100,7 +100,6 @@ u8 iwl_tt_current_power_mode(struct iwl_priv *priv); bool iwl_tt_is_low_power_state(struct iwl_priv *priv); bool iwl_ht_enabled(struct iwl_priv *priv); enum iwl_antenna_ok iwl_tx_ant_restriction(struct iwl_priv *priv); -enum iwl_antenna_ok iwl_rx_ant_restriction(struct iwl_priv *priv); void iwl_tt_enter_ct_kill(struct iwl_priv *priv); void iwl_tt_exit_ct_kill(struct iwl_priv *priv); void iwl_tt_handler(struct iwl_priv *priv); diff --git a/drivers/net/wireless/intel/iwlwifi/fw/api/alive.h b/drivers/net/wireless/intel/iwlwifi/fw/api/alive.h index ebe85fdf08d3..42360a8f23aa 100644 --- a/drivers/net/wireless/intel/iwlwifi/fw/api/alive.h +++ b/drivers/net/wireless/intel/iwlwifi/fw/api/alive.h @@ -1,6 +1,6 @@ /* SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause */ /* - * Copyright (C) 2012-2014, 2018, 2020-2021, 2024 Intel Corporation + * Copyright (C) 2012-2014, 2018, 2020-2021, 2024-2025 Intel Corporation * Copyright (C) 2013-2015 Intel Mobile Communications GmbH * Copyright (C) 2016-2017 Intel Deutschland GmbH */ @@ -117,7 +117,7 @@ struct iwl_alive_ntf_v6 { * finishing init flow * @IWL_INIT_DEBUG_CFG: driver is going to send debug config command * @IWL_INIT_NVM: driver is going to send NVM_ACCESS commands - * @IWL_INIT_PHY: driver is going to send PHY_DB commands + * @IWL_INIT_PHY: driver is going to send the PHY_CONFIGURATION_CMD */ enum iwl_extended_cfg_flags { IWL_INIT_DEBUG_CFG, diff --git a/drivers/net/wireless/intel/iwlwifi/fw/api/commands.h b/drivers/net/wireless/intel/iwlwifi/fw/api/commands.h index 34a1f97653c0..d43adb6f9220 100644 --- a/drivers/net/wireless/intel/iwlwifi/fw/api/commands.h +++ b/drivers/net/wireless/intel/iwlwifi/fw/api/commands.h @@ -502,11 +502,16 @@ enum iwl_legacy_cmds { /** * @DTS_MEASUREMENT_NOTIFICATION: * &struct iwl_dts_measurement_notif_v1 or - * &struct iwl_dts_measurement_notif_v2 + * &struct iwl_dts_measurement_notif */ DTS_MEASUREMENT_NOTIFICATION = 0xdd, /** + * @DEBUG_HOST_COMMAND: &struct iwl_dhc_cmd + */ + DEBUG_HOST_COMMAND = 0xf1, + + /** * @LDBG_CONFIG_CMD: configure continuous trace recording */ LDBG_CONFIG_CMD = 0xf6, diff --git a/drivers/net/wireless/intel/iwlwifi/fw/api/context.h b/drivers/net/wireless/intel/iwlwifi/fw/api/context.h index a9fa5f054ce0..464eed9b5e71 100644 --- a/drivers/net/wireless/intel/iwlwifi/fw/api/context.h +++ b/drivers/net/wireless/intel/iwlwifi/fw/api/context.h @@ -1,6 +1,6 @@ /* SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause */ /* - * Copyright (C) 2012-2014, 2022 Intel Corporation + * Copyright (C) 2012-2014, 2022, 2024 Intel Corporation * Copyright (C) 2013-2015 Intel Mobile Communications GmbH * Copyright (C) 2016-2017 Intel Deutschland GmbH */ @@ -14,6 +14,9 @@ * @FW_CTXT_COLOR_POS: position of the color * @FW_CTXT_COLOR_MSK: mask of the color * @FW_CTXT_INVALID: value used to indicate unused/invalid + * @FW_CTXT_ID_INVALID: value used to indicate unused/invalid. This can be + * used with newer firmware which no longer use the color. Typically, + * firmware versions supported by iwlmld can use this value. */ enum iwl_ctxt_id_and_color { FW_CTXT_ID_POS = 0, @@ -21,6 +24,7 @@ enum iwl_ctxt_id_and_color { FW_CTXT_COLOR_POS = 8, FW_CTXT_COLOR_MSK = 0xff << FW_CTXT_COLOR_POS, FW_CTXT_INVALID = 0xffffffff, + FW_CTXT_ID_INVALID = 0xff, }; #define FW_CMD_ID_AND_COLOR(_id, _color) (((_id) << FW_CTXT_ID_POS) |\ diff --git a/drivers/net/wireless/intel/iwlwifi/fw/api/d3.h b/drivers/net/wireless/intel/iwlwifi/fw/api/d3.h index c2362bc786b2..9c271ea67155 100644 --- a/drivers/net/wireless/intel/iwlwifi/fw/api/d3.h +++ b/drivers/net/wireless/intel/iwlwifi/fw/api/d3.h @@ -1006,7 +1006,7 @@ struct iwl_wowlan_wake_pkt_notif { * struct iwl_mvm_d3_end_notif - d3 end notification * @flags: See &enum iwl_d0i3_flags */ -struct iwl_mvm_d3_end_notif { +struct iwl_d3_end_notif { __le32 flags; } __packed; diff --git a/drivers/net/wireless/intel/iwlwifi/fw/api/datapath.h b/drivers/net/wireless/intel/iwlwifi/fw/api/datapath.h index 570a3f722510..c139b965980d 100644 --- a/drivers/net/wireless/intel/iwlwifi/fw/api/datapath.h +++ b/drivers/net/wireless/intel/iwlwifi/fw/api/datapath.h @@ -1,6 +1,6 @@ /* SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause */ /* - * Copyright (C) 2024 Intel Corporation + * Copyright (C) 2024-2025 Intel Corporation * Copyright (C) 2012-2014, 2018-2022 Intel Corporation * Copyright (C) 2013-2015 Intel Mobile Communications GmbH * Copyright (C) 2016-2017 Intel Deutschland GmbH @@ -91,8 +91,14 @@ enum iwl_data_path_subcmd_ids { SEC_KEY_CMD = 0x18, /** + * @OMI_SEND_STATUS_NOTIF: notification after OMI was sent + * uses &struct iwl_omi_send_status_notif + */ + OMI_SEND_STATUS_NOTIF = 0xF2, + + /** * @ESR_MODE_NOTIF: notification to recommend/force a wanted esr mode, - * uses &struct iwl_mvm_esr_mode_notif + * uses &struct iwl_esr_mode_notif */ ESR_MODE_NOTIF = 0xF3, @@ -688,4 +694,13 @@ struct iwl_sec_key_cmd { } __packed u; /* SEC_KEY_OPERATION_API_U_VER_1 */ } __packed; /* SEC_KEY_CMD_API_S_VER_1 */ +/** + * struct iwl_omi_send_status_notif - OMI status notification + * @success: indicates that the OMI was sent successfully + * (currently always set) + */ +struct iwl_omi_send_status_notif { + __le32 success; +} __packed; /* OMI_SEND_STATUS_NTFY_API_S_VER_1 */ + #endif /* __iwl_fw_api_datapath_h__ */ diff --git a/drivers/net/wireless/intel/iwlwifi/fw/api/dbg-tlv.h b/drivers/net/wireless/intel/iwlwifi/fw/api/dbg-tlv.h index 550de6db1834..4fab6c66994e 100644 --- a/drivers/net/wireless/intel/iwlwifi/fw/api/dbg-tlv.h +++ b/drivers/net/wireless/intel/iwlwifi/fw/api/dbg-tlv.h @@ -1,6 +1,6 @@ /* SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause */ /* - * Copyright (C) 2018-2024 Intel Corporation + * Copyright (C) 2018-2025 Intel Corporation */ #ifndef __iwl_fw_dbg_tlv_h__ #define __iwl_fw_dbg_tlv_h__ @@ -527,6 +527,8 @@ enum iwl_fw_ini_time_point { * @IWL_FW_INI_APPLY_POLICY_OVERRIDE_DATA: override trigger data. * Append otherwise * @IWL_FW_INI_APPLY_POLICY_DUMP_COMPLETE_CMD: send cmd once dump collected + * @IWL_FW_INI_APPLY_POLICY_RESET_HANDSHAKE: perform reset handshake and + * split dump to before/after with region marking */ enum iwl_fw_ini_trigger_apply_policy { IWL_FW_INI_APPLY_POLICY_MATCH_TIME_POINT = BIT(0), @@ -535,6 +537,7 @@ enum iwl_fw_ini_trigger_apply_policy { IWL_FW_INI_APPLY_POLICY_OVERRIDE_CFG = BIT(9), IWL_FW_INI_APPLY_POLICY_OVERRIDE_DATA = BIT(10), IWL_FW_INI_APPLY_POLICY_DUMP_COMPLETE_CMD = BIT(16), + IWL_FW_INI_APPLY_POLICY_RESET_HANDSHAKE = BIT(17), }; /** @@ -556,12 +559,14 @@ enum iwl_fw_ini_trigger_reset_fw_policy { * @IWL_FW_INI_DEBUG_DUMP_POLICY_NO_LIMIT: OS has no limit of dump size * @IWL_FW_INI_DEBUG_DUMP_POLICY_MAX_LIMIT_600KB: mini dump only 600KB region dump * @IWL_FW_IWL_DEBUG_DUMP_POLICY_MAX_LIMIT_5MB: mini dump 5MB size dump + * @IWL_FW_IWL_DEBUG_DUMP_POLICY_BEFORE_RESET: dump this region before reset + * handshake (if requested by %IWL_FW_INI_APPLY_POLICY_RESET_HANDSHAKE) */ enum iwl_fw_ini_dump_policy { IWL_FW_INI_DEBUG_DUMP_POLICY_NO_LIMIT = BIT(0), IWL_FW_INI_DEBUG_DUMP_POLICY_MAX_LIMIT_600KB = BIT(1), IWL_FW_IWL_DEBUG_DUMP_POLICY_MAX_LIMIT_5MB = BIT(2), - + IWL_FW_IWL_DEBUG_DUMP_POLICY_BEFORE_RESET = BIT(3), }; /** diff --git a/drivers/net/wireless/intel/iwlwifi/fw/api/dhc.h b/drivers/net/wireless/intel/iwlwifi/fw/api/dhc.h new file mode 100644 index 000000000000..dbe06f3fc662 --- /dev/null +++ b/drivers/net/wireless/intel/iwlwifi/fw/api/dhc.h @@ -0,0 +1,129 @@ +/* SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause */ +/* + * Copyright (C) 2025 Intel Corporation + */ +#ifndef __iwl_fw_api_dhc_h__ +#define __iwl_fw_api_dhc_h__ + +#define DHC_TABLE_MASK_POS (28) + +/** + * enum iwl_dhc_table_id - DHC table operations index + */ +enum iwl_dhc_table_id { + /** + * @DHC_TABLE_INTEGRATION: select the integration table + */ + DHC_TABLE_INTEGRATION = 2 << DHC_TABLE_MASK_POS, +}; + +/** + * enum iwl_dhc_umac_integration_table - integration operations + */ +enum iwl_dhc_umac_integration_table { + /** + * @DHC_INT_UMAC_TWT_OPERATION: trigger a TWT operation + */ + DHC_INT_UMAC_TWT_OPERATION = 4, + /** + * @DHC_INTEGRATION_TLC_DEBUG_CONFIG: TLC debug + */ + DHC_INTEGRATION_TLC_DEBUG_CONFIG = 1, + /** + * @DHC_INTEGRATION_MAX: Maximum UMAC integration table entries + */ + DHC_INTEGRATION_MAX +}; + +#define DHC_TARGET_UMAC BIT(27) + +/** + * struct iwl_dhc_cmd - debug host command + * @length: length in DWs of the data structure that is concatenated to the end + * of this struct + * @index_and_mask: bit 31 is 1 for data set operation else it's 0 + * bits 28-30 is the index of the table of the operation - + * &enum iwl_dhc_table_id * + * bit 27 is 0 if the cmd targeted to LMAC and 1 if targeted to UMAC, + * (LMAC is 0 for backward compatibility) + * bit 26 is 0 if the cmd targeted to LMAC0 and 1 if targeted to LMAC1, + * relevant only if bit 27 set to 0 + * bits 0-25 is a specific entry index in the table specified in bits 28-30 + * + * @data: the concatenated data. + */ +struct iwl_dhc_cmd { + __le32 length; + __le32 index_and_mask; + __le32 data[]; +} __packed; /* DHC_CMD_API_S */ + +/** + * enum iwl_dhc_twt_operation_type - describes the TWT operation type + * + * @DHC_TWT_REQUEST: Send a Request TWT command + * @DHC_TWT_SUGGEST: Send a Suggest TWT command + * @DHC_TWT_DEMAND: Send a Demand TWT command + * @DHC_TWT_GROUPING: Send a Grouping TWT command + * @DHC_TWT_ACCEPT: Send a Accept TWT command + * @DHC_TWT_ALTERNATE: Send a Alternate TWT command + * @DHC_TWT_DICTATE: Send a Dictate TWT command + * @DHC_TWT_REJECT: Send a Reject TWT command + * @DHC_TWT_TEARDOWN: Send a TearDown TWT command + */ +enum iwl_dhc_twt_operation_type { + DHC_TWT_REQUEST, + DHC_TWT_SUGGEST, + DHC_TWT_DEMAND, + DHC_TWT_GROUPING, + DHC_TWT_ACCEPT, + DHC_TWT_ALTERNATE, + DHC_TWT_DICTATE, + DHC_TWT_REJECT, + DHC_TWT_TEARDOWN, +}; /* DHC_TWT_OPERATION_TYPE_E */ + +/** + * struct iwl_dhc_twt_operation - trigger a TWT operation + * + * @mac_id: the mac Id on which to trigger TWT operation + * @twt_operation: see &enum iwl_dhc_twt_operation_type + * @target_wake_time: when should we be on channel + * @interval_exp: the exponent for the interval + * @interval_mantissa: the mantissa for the interval + * @min_wake_duration: the minimum duration for the wake period + * @trigger: is the TWT triggered or not + * @flow_type: is the TWT announced or not + * @flow_id: the TWT flow identifier from 0 to 7 + * @protection: is the TWT protected + * @ndo_paging_indicator: is ndo_paging_indicator set + * @responder_pm_mode: is responder_pm_mode set + * @negotiation_type: if the responder wants to doze outside the TWT SP + * @twt_request: 1 for TWT request, 0 otherwise + * @implicit: is TWT implicit + * @twt_group_assignment: the TWT group assignment + * @twt_channel: the TWT channel + * @reserved: reserved + */ +struct iwl_dhc_twt_operation { + __le32 mac_id; + __le32 twt_operation; + __le64 target_wake_time; + __le32 interval_exp; + __le32 interval_mantissa; + __le32 min_wake_duration; + u8 trigger; + u8 flow_type; + u8 flow_id; + u8 protection; + u8 ndo_paging_indicator; + u8 responder_pm_mode; + u8 negotiation_type; + u8 twt_request; + u8 implicit; + u8 twt_group_assignment; + u8 twt_channel; + u8 reserved; +}; /* DHC_TWT_OPERATION_API_S */ + +#endif /* __iwl_fw_api_dhc_h__ */ diff --git a/drivers/net/wireless/intel/iwlwifi/fw/api/location.h b/drivers/net/wireless/intel/iwlwifi/fw/api/location.h index b8dff139aa05..e1952fc6d149 100644 --- a/drivers/net/wireless/intel/iwlwifi/fw/api/location.h +++ b/drivers/net/wireless/intel/iwlwifi/fw/api/location.h @@ -2,7 +2,7 @@ /* * Copyright (C) 2015-2017 Intel Deutschland GmbH * Copyright (C) 2018-2022 Intel Corporation - * Copyright (C) 2024 Intel Corporation + * Copyright (C) 2024-2025 Intel Corporation */ #ifndef __iwl_fw_api_location_h__ #define __iwl_fw_api_location_h__ @@ -1015,7 +1015,7 @@ struct iwl_tof_range_req_ap_entry_v9 { } __packed; /* LOCATION_RANGE_REQ_AP_ENTRY_CMD_API_S_VER_9 */ /** - * struct iwl_tof_range_req_ap_entry_v10 - AP configuration parameters + * struct iwl_tof_range_req_ap_entry - AP configuration parameters * @initiator_ap_flags: see &enum iwl_initiator_ap_flags. * @band: 0 for 5.2 GHz, 1 for 2.4 GHz, 2 for 6GHz * @channel_num: AP Channel number @@ -1063,7 +1063,7 @@ struct iwl_tof_range_req_ap_entry_v9 { * @min_time_between_msr: For non trigger based NDP ranging, the minimum time * between measurements in units of milliseconds */ -struct iwl_tof_range_req_ap_entry_v10 { +struct iwl_tof_range_req_ap_entry { __le32 initiator_ap_flags; u8 band; u8 channel_num; @@ -1134,7 +1134,7 @@ enum iwl_tof_initiator_flags { IWL_TOF_INITIATOR_FLAGS_NON_ASAP_SUPPORT = BIT(20), }; /* LOCATION_RANGE_REQ_CMD_API_S_VER_5 */ -#define IWL_MVM_TOF_MAX_APS 5 +#define IWL_TOF_MAX_APS 5 #define IWL_MVM_TOF_MAX_TWO_SIDED_APS 5 /** @@ -1153,7 +1153,7 @@ enum iwl_tof_initiator_flags { * when the session is done (successfully / partially). * one of iwl_tof_response_mode. * @reserved0: reserved - * @num_of_ap: Number of APs to measure (error if > IWL_MVM_TOF_MAX_APS) + * @num_of_ap: Number of APs to measure (error if > IWL_TOF_MAX_APS) * @macaddr_random: '0' Use default source MAC address (i.e. p2_p), * '1' Use MAC Address randomization according to the below * @range_req_bssid: ranging request BSSID @@ -1183,7 +1183,7 @@ struct iwl_tof_range_req_cmd_v5 { u8 ftm_tx_chains; __le16 common_calib; __le16 specific_calib; - struct iwl_tof_range_req_ap_entry_v2 ap[IWL_MVM_TOF_MAX_APS]; + struct iwl_tof_range_req_ap_entry_v2 ap[IWL_TOF_MAX_APS]; } __packed; /* LOCATION_RANGE_REQ_CMD_API_S_VER_5 */ @@ -1192,7 +1192,7 @@ struct iwl_tof_range_req_cmd_v5 { * @initiator_flags: see flags @ iwl_tof_initiator_flags * @request_id: A Token incremented per request. The same Token will be * sent back in the range response - * @num_of_ap: Number of APs to measure (error if > IWL_MVM_TOF_MAX_APS) + * @num_of_ap: Number of APs to measure (error if > IWL_TOF_MAX_APS) * @range_req_bssid: ranging request BSSID * @macaddr_mask: Bits set to 0 shall be copied from the MAC address template. * Bits set to 1 shall be randomized by the UMAC @@ -1216,7 +1216,7 @@ struct iwl_tof_range_req_cmd_v7 { __le32 tsf_mac_id; __le16 common_calib; __le16 specific_calib; - struct iwl_tof_range_req_ap_entry_v3 ap[IWL_MVM_TOF_MAX_APS]; + struct iwl_tof_range_req_ap_entry_v3 ap[IWL_TOF_MAX_APS]; } __packed; /* LOCATION_RANGE_REQ_CMD_API_S_VER_7 */ /** @@ -1224,7 +1224,7 @@ struct iwl_tof_range_req_cmd_v7 { * @initiator_flags: see flags @ iwl_tof_initiator_flags * @request_id: A Token incremented per request. The same Token will be * sent back in the range response - * @num_of_ap: Number of APs to measure (error if > IWL_MVM_TOF_MAX_APS) + * @num_of_ap: Number of APs to measure (error if > IWL_TOF_MAX_APS) * @range_req_bssid: ranging request BSSID * @macaddr_mask: Bits set to 0 shall be copied from the MAC address template. * Bits set to 1 shall be randomized by the UMAC @@ -1248,7 +1248,7 @@ struct iwl_tof_range_req_cmd_v8 { __le32 tsf_mac_id; __le16 common_calib; __le16 specific_calib; - struct iwl_tof_range_req_ap_entry_v4 ap[IWL_MVM_TOF_MAX_APS]; + struct iwl_tof_range_req_ap_entry_v4 ap[IWL_TOF_MAX_APS]; } __packed; /* LOCATION_RANGE_REQ_CMD_API_S_VER_8 */ /** @@ -1256,7 +1256,7 @@ struct iwl_tof_range_req_cmd_v8 { * @initiator_flags: see flags @ iwl_tof_initiator_flags * @request_id: A Token incremented per request. The same Token will be * sent back in the range response - * @num_of_ap: Number of APs to measure (error if > IWL_MVM_TOF_MAX_APS) + * @num_of_ap: Number of APs to measure (error if > IWL_TOF_MAX_APS) * @range_req_bssid: ranging request BSSID * @macaddr_mask: Bits set to 0 shall be copied from the MAC address template. * Bits set to 1 shall be randomized by the UMAC @@ -1276,7 +1276,7 @@ struct iwl_tof_range_req_cmd_v9 { u8 macaddr_template[ETH_ALEN]; __le32 req_timeout_ms; __le32 tsf_mac_id; - struct iwl_tof_range_req_ap_entry_v6 ap[IWL_MVM_TOF_MAX_APS]; + struct iwl_tof_range_req_ap_entry_v6 ap[IWL_TOF_MAX_APS]; } __packed; /* LOCATION_RANGE_REQ_CMD_API_S_VER_9 */ /** @@ -1284,7 +1284,7 @@ struct iwl_tof_range_req_cmd_v9 { * @initiator_flags: see flags @ iwl_tof_initiator_flags * @request_id: A Token incremented per request. The same Token will be * sent back in the range response - * @num_of_ap: Number of APs to measure (error if > IWL_MVM_TOF_MAX_APS) + * @num_of_ap: Number of APs to measure (error if > IWL_TOF_MAX_APS) * @range_req_bssid: ranging request BSSID * @macaddr_mask: Bits set to 0 shall be copied from the MAC address template. * Bits set to 1 shall be randomized by the UMAC @@ -1304,7 +1304,7 @@ struct iwl_tof_range_req_cmd_v11 { u8 macaddr_template[ETH_ALEN]; __le32 req_timeout_ms; __le32 tsf_mac_id; - struct iwl_tof_range_req_ap_entry_v7 ap[IWL_MVM_TOF_MAX_APS]; + struct iwl_tof_range_req_ap_entry_v7 ap[IWL_TOF_MAX_APS]; } __packed; /* LOCATION_RANGE_REQ_CMD_API_S_VER_11 */ /** @@ -1312,7 +1312,7 @@ struct iwl_tof_range_req_cmd_v11 { * @initiator_flags: see flags @ iwl_tof_initiator_flags * @request_id: A Token incremented per request. The same Token will be * sent back in the range response - * @num_of_ap: Number of APs to measure (error if > IWL_MVM_TOF_MAX_APS) + * @num_of_ap: Number of APs to measure (error if > IWL_TOF_MAX_APS) * @range_req_bssid: ranging request BSSID * @macaddr_mask: Bits set to 0 shall be copied from the MAC address template. * Bits set to 1 shall be randomized by the UMAC @@ -1332,7 +1332,7 @@ struct iwl_tof_range_req_cmd_v12 { u8 macaddr_template[ETH_ALEN]; __le32 req_timeout_ms; __le32 tsf_mac_id; - struct iwl_tof_range_req_ap_entry_v8 ap[IWL_MVM_TOF_MAX_APS]; + struct iwl_tof_range_req_ap_entry_v8 ap[IWL_TOF_MAX_APS]; } __packed; /* LOCATION_RANGE_REQ_CMD_API_S_VER_12 */ /** @@ -1340,7 +1340,7 @@ struct iwl_tof_range_req_cmd_v12 { * @initiator_flags: see flags @ iwl_tof_initiator_flags * @request_id: A Token incremented per request. The same Token will be * sent back in the range response - * @num_of_ap: Number of APs to measure (error if > IWL_MVM_TOF_MAX_APS) + * @num_of_ap: Number of APs to measure (error if > IWL_TOF_MAX_APS) * @range_req_bssid: ranging request BSSID * @macaddr_mask: Bits set to 0 shall be copied from the MAC address template. * Bits set to 1 shall be randomized by the UMAC @@ -1360,15 +1360,15 @@ struct iwl_tof_range_req_cmd_v13 { u8 macaddr_template[ETH_ALEN]; __le32 req_timeout_ms; __le32 tsf_mac_id; - struct iwl_tof_range_req_ap_entry_v9 ap[IWL_MVM_TOF_MAX_APS]; + struct iwl_tof_range_req_ap_entry_v9 ap[IWL_TOF_MAX_APS]; } __packed; /* LOCATION_RANGE_REQ_CMD_API_S_VER_13 */ /** - * struct iwl_tof_range_req_cmd_v14 - start measurement cmd + * struct iwl_tof_range_req_cmd - start measurement cmd * @initiator_flags: see flags @ iwl_tof_initiator_flags * @request_id: A Token incremented per request. The same Token will be * sent back in the range response - * @num_of_ap: Number of APs to measure (error if > IWL_MVM_TOF_MAX_APS) + * @num_of_ap: Number of APs to measure (error if > IWL_TOF_MAX_APS) * @range_req_bssid: ranging request BSSID * @macaddr_mask: Bits set to 0 shall be copied from the MAC address template. * Bits set to 1 shall be randomized by the UMAC @@ -1377,9 +1377,9 @@ struct iwl_tof_range_req_cmd_v13 { * This is the session time for completing the measurement. * @tsf_mac_id: report the measurement start time for each ap in terms of the * TSF of this mac id. 0xff to disable TSF reporting. - * @ap: per-AP request data, see &struct iwl_tof_range_req_ap_entry_v10. + * @ap: per-AP request data, see &struct iwl_tof_range_req_ap_entry. */ -struct iwl_tof_range_req_cmd_v14 { +struct iwl_tof_range_req_cmd { __le32 initiator_flags; u8 request_id; u8 num_of_ap; @@ -1388,8 +1388,8 @@ struct iwl_tof_range_req_cmd_v14 { u8 macaddr_template[ETH_ALEN]; __le32 req_timeout_ms; __le32 tsf_mac_id; - struct iwl_tof_range_req_ap_entry_v10 ap[IWL_MVM_TOF_MAX_APS]; -} __packed; /* LOCATION_RANGE_REQ_CMD_API_S_VER_13 */ + struct iwl_tof_range_req_ap_entry ap[IWL_TOF_MAX_APS]; +} __packed; /* LOCATION_RANGE_REQ_CMD_API_S_VER_15 */ /* * enum iwl_tof_range_request_status - status of the sent request @@ -1609,7 +1609,7 @@ struct iwl_tof_range_rsp_ap_entry_ntfy_v5 { } __packed; /* LOCATION_RANGE_RSP_AP_ETRY_NTFY_API_S_VER_5 */ /** - * struct iwl_tof_range_rsp_ap_entry_ntfy_v6 - AP parameters (response) + * struct iwl_tof_range_rsp_ap_entry_ntfy - AP parameters (response) * @bssid: BSSID of the AP * @measure_status: current APs measurement status, one of * &enum iwl_tof_entry_status. @@ -1645,7 +1645,7 @@ struct iwl_tof_range_rsp_ap_entry_ntfy_v5 { * @tx_pn: the last PN used for this responder Tx in case PMF is configured in * LE byte order. */ -struct iwl_tof_range_rsp_ap_entry_ntfy_v6 { +struct iwl_tof_range_rsp_ap_entry_ntfy { u8 bssid[ETH_ALEN]; u8 measure_status; u8 measure_bw; @@ -1695,7 +1695,7 @@ enum iwl_tof_response_status { * @request_status: status of current measurement session, one of * &enum iwl_tof_response_status. * @last_in_batch: reprot policy (when not all responses are uploaded at once) - * @num_of_aps: Number of APs to measure (error if > IWL_MVM_TOF_MAX_APS) + * @num_of_aps: Number of APs to measure (error if > IWL_TOF_MAX_APS) * @ap: per-AP data */ struct iwl_tof_range_rsp_ntfy_v5 { @@ -1703,7 +1703,7 @@ struct iwl_tof_range_rsp_ntfy_v5 { u8 request_status; u8 last_in_batch; u8 num_of_aps; - struct iwl_tof_range_rsp_ap_entry_ntfy_v3 ap[IWL_MVM_TOF_MAX_APS]; + struct iwl_tof_range_rsp_ap_entry_ntfy_v3 ap[IWL_TOF_MAX_APS]; } __packed; /* LOCATION_RANGE_RSP_NTFY_API_S_VER_5 */ /** @@ -1719,7 +1719,7 @@ struct iwl_tof_range_rsp_ntfy_v6 { u8 num_of_aps; u8 last_report; u8 reserved; - struct iwl_tof_range_rsp_ap_entry_ntfy_v4 ap[IWL_MVM_TOF_MAX_APS]; + struct iwl_tof_range_rsp_ap_entry_ntfy_v4 ap[IWL_TOF_MAX_APS]; } __packed; /* LOCATION_RANGE_RSP_NTFY_API_S_VER_6 */ /** @@ -1735,23 +1735,23 @@ struct iwl_tof_range_rsp_ntfy_v7 { u8 num_of_aps; u8 last_report; u8 reserved; - struct iwl_tof_range_rsp_ap_entry_ntfy_v5 ap[IWL_MVM_TOF_MAX_APS]; + struct iwl_tof_range_rsp_ap_entry_ntfy_v5 ap[IWL_TOF_MAX_APS]; } __packed; /* LOCATION_RANGE_RSP_NTFY_API_S_VER_7 */ /** - * struct iwl_tof_range_rsp_ntfy_v8 - ranging response notification + * struct iwl_tof_range_rsp_ntfy - ranging response notification * @request_id: A Token ID of the corresponding Range request * @num_of_aps: Number of APs results * @last_report: 1 if no more FTM sessions are scheduled, 0 otherwise. * @reserved: reserved * @ap: per-AP data */ -struct iwl_tof_range_rsp_ntfy_v8 { +struct iwl_tof_range_rsp_ntfy { u8 request_id; u8 num_of_aps; u8 last_report; u8 reserved; - struct iwl_tof_range_rsp_ap_entry_ntfy_v6 ap[IWL_MVM_TOF_MAX_APS]; + struct iwl_tof_range_rsp_ap_entry_ntfy ap[IWL_TOF_MAX_APS]; } __packed; /* LOCATION_RANGE_RSP_NTFY_API_S_VER_8, LOCATION_RANGE_RSP_NTFY_API_S_VER_9 */ diff --git a/drivers/net/wireless/intel/iwlwifi/fw/api/mac-cfg.h b/drivers/net/wireless/intel/iwlwifi/fw/api/mac-cfg.h index 37bb7002c1c9..b511e3aa6bb2 100644 --- a/drivers/net/wireless/intel/iwlwifi/fw/api/mac-cfg.h +++ b/drivers/net/wireless/intel/iwlwifi/fw/api/mac-cfg.h @@ -1,6 +1,6 @@ /* SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause */ /* - * Copyright (C) 2012-2014, 2018-2019, 2021-2024 Intel Corporation + * Copyright (C) 2012-2014, 2018-2019, 2021-2025 Intel Corporation * Copyright (C) 2013-2015 Intel Mobile Communications GmbH * Copyright (C) 2016-2017 Intel Deutschland GmbH */ @@ -46,7 +46,7 @@ enum iwl_mac_conf_subcmd_ids { */ STA_CONFIG_CMD = 0xA, /** - * @AUX_STA_CMD: &struct iwl_mvm_aux_sta_cmd + * @AUX_STA_CMD: &struct iwl_aux_sta_cmd */ AUX_STA_CMD = 0xB, /** @@ -62,6 +62,10 @@ enum iwl_mac_conf_subcmd_ids { */ ROC_CMD = 0xE, /** + * @TWT_OPERATION_CMD: &struct iwl_twt_operation_cmd + */ + TWT_OPERATION_CMD = 0x10, + /** * @MISSED_BEACONS_NOTIF: &struct iwl_missed_beacons_notif */ MISSED_BEACONS_NOTIF = 0xF6, @@ -641,7 +645,7 @@ struct iwl_sta_cfg_cmd { } __packed; /* STA_CMD_API_S_VER_1 */ /** - * struct iwl_mvm_aux_sta_cmd - command for AUX STA configuration + * struct iwl_aux_sta_cmd - command for AUX STA configuration * ( AUX_STA_CMD = 0xB ) * * @sta_id: index of aux sta to configure @@ -649,7 +653,7 @@ struct iwl_sta_cfg_cmd { * @mac_addr: mac addr of the auxilary sta * @reserved_for_mac_addr: reserved */ -struct iwl_mvm_aux_sta_cmd { +struct iwl_aux_sta_cmd { __le32 sta_id; __le32 lmac_id; u8 mac_addr[ETH_ALEN]; @@ -693,11 +697,11 @@ enum iwl_mvm_fw_esr_recommendation { }; /* ESR_MODE_RECOMMENDATION_CODE_API_E_VER_1 */ /** - * struct iwl_mvm_esr_mode_notif - FWs recommendation/force for esr mode + * struct iwl_esr_mode_notif - FWs recommendation/force for esr mode * * @action: the action to apply on esr state. See &iwl_mvm_fw_esr_recommendation */ -struct iwl_mvm_esr_mode_notif { +struct iwl_esr_mode_notif { __le32 action; } __packed; /* ESR_MODE_RECOMMENDATION_NTFY_API_S_VER_1 */ @@ -748,4 +752,83 @@ struct iwl_esr_trans_fail_notif { __le32 err_code; } __packed; /* ESR_TRANSITION_FAILED_NTFY_API_S_VER_1 */ +/* + * enum iwl_twt_operation_type: TWT operation in a TWT action frame + * + * @TWT_OPERATION_REQUEST: TWT Request + * @TWT_OPERATION_SUGGEST: TWT Suggest + * @TWT_OPERATION_DEMAND: TWT Demand + * @TWT_OPERATION_GROUPING: TWT Grouping + * @TWT_OPERATION_ACCEPT: TWT Accept + * @TWT_OPERATION_ALTERNATE: TWT Alternate + * @TWT_OPERATION_DICTATE: TWT Dictate + * @TWT_OPERATION_REJECT: TWT Reject + * @TWT_OPERATION_TEARDOWN: TWT Teardown + * @TWT_OPERATION_UNAVAILABILITY: TWT Unavailability + */ +enum iwl_twt_operation_type { + TWT_OPERATION_REQUEST, + TWT_OPERATION_SUGGEST, + TWT_OPERATION_DEMAND, + TWT_OPERATION_GROUPING, + TWT_OPERATION_ACCEPT, + TWT_OPERATION_ALTERNATE, + TWT_OPERATION_DICTATE, + TWT_OPERATION_REJECT, + TWT_OPERATION_TEARDOWN, + TWT_OPERATION_UNAVAILABILITY, + TWT_OPERATION_MAX, +}; /* TWT_OPERATION_TYPE_E_VER_1 */ + +/** + * struct iwl_twt_operation_cmd - initiate a TWT session from driver + * + * @link_id: FW link id to initiate the TWT + * @twt_operation: &enum iwl_twt_operation_type + * @target_wake_time: TSF time to start the TWT + * @interval_exponent: the exponent for the interval + * @interval_mantissa: the mantissa for the interval + * @minimum_wake_duration: the minimum duration for the wake period + * @trigger: is the TWT triggered or not + * @flow_type: is the TWT announced (0) or not (1) + * @flow_id: the TWT flow identifier 0 - 7 + * @twt_protection: is the TWT protected + * @ndp_paging_indicator: is ndp paging indicator set + * @responder_pm_mode: is responder pm mode set + * @negotiation_type: if the responder wants to doze outside the TWT SP + * @twt_request: 1 for TWT request (STA), 0 for TWT response (AP) + * @implicit: is TWT implicit + * @twt_group_assignment: the TWT group assignment + * @twt_channel: the TWT channel + * @restricted_info_present: is this a restricted TWT + * @dl_bitmap_valid: is DL (download) bitmap valid (restricted TWT) + * @ul_bitmap_valid: is UL (upload) bitmap valid (restricted TWT) + * @dl_tid_bitmap: DL TID bitmap (restricted TWT) + * @ul_tid_bitmap: UL TID bitmap (restricted TWT) + */ +struct iwl_twt_operation_cmd { + __le32 link_id; + __le32 twt_operation; + __le64 target_wake_time; + __le32 interval_exponent; + __le32 interval_mantissa; + __le32 minimum_wake_duration; + u8 trigger; + u8 flow_type; + u8 flow_id; + u8 twt_protection; + u8 ndp_paging_indicator; + u8 responder_pm_mode; + u8 negotiation_type; + u8 twt_request; + u8 implicit; + u8 twt_group_assignment; + u8 twt_channel; + u8 restricted_info_present; + u8 dl_bitmap_valid; + u8 ul_bitmap_valid; + u8 dl_tid_bitmap; + u8 ul_tid_bitmap; +} __packed; /* TWT_OPERATION_API_S_VER_1 */ + #endif /* __iwl_fw_api_mac_cfg_h__ */ diff --git a/drivers/net/wireless/intel/iwlwifi/fw/api/phy.h b/drivers/net/wireless/intel/iwlwifi/fw/api/phy.h index c73d4d597857..eb8961b51cb0 100644 --- a/drivers/net/wireless/intel/iwlwifi/fw/api/phy.h +++ b/drivers/net/wireless/intel/iwlwifi/fw/api/phy.h @@ -19,7 +19,7 @@ enum iwl_phy_ops_subcmd_ids { CMD_DTS_MEASUREMENT_TRIGGER_WIDE = 0x0, /** - * @CTDP_CONFIG_CMD: &struct iwl_mvm_ctdp_cmd + * @CTDP_CONFIG_CMD: &struct iwl_ctdp_cmd */ CTDP_CONFIG_CMD = 0x03, @@ -55,7 +55,7 @@ enum iwl_phy_ops_subcmd_ids { /** * @DTS_MEASUREMENT_NOTIF_WIDE: * &struct iwl_dts_measurement_notif_v1 or - * &struct iwl_dts_measurement_notif_v2 + * &struct iwl_dts_measurement_notif */ DTS_MEASUREMENT_NOTIF_WIDE = 0xFF, }; @@ -152,13 +152,13 @@ struct iwl_dts_measurement_notif_v1 { } __packed; /* TEMPERATURE_MEASUREMENT_TRIGGER_NTFY_S_VER_1*/ /** - * struct iwl_dts_measurement_notif_v2 - measurements notification + * struct iwl_dts_measurement_notif - measurements notification * * @temp: the measured temperature * @voltage: the measured voltage * @threshold_idx: the trip index that was crossed */ -struct iwl_dts_measurement_notif_v2 { +struct iwl_dts_measurement_notif { __le32 temp; __le32 voltage; __le32 threshold_idx; @@ -195,25 +195,25 @@ struct ct_kill_notif { } __packed; /* CT_KILL_NOTIFICATION_API_S_VER_1, CT_KILL_NOTIFICATION_API_S_VER_2 */ /** -* enum iwl_mvm_ctdp_cmd_operation - CTDP command operations +* enum iwl_ctdp_cmd_operation - CTDP command operations * @CTDP_CMD_OPERATION_START: update the current budget * @CTDP_CMD_OPERATION_STOP: stop ctdp * @CTDP_CMD_OPERATION_REPORT: get the average budget */ -enum iwl_mvm_ctdp_cmd_operation { +enum iwl_ctdp_cmd_operation { CTDP_CMD_OPERATION_START = 0x1, CTDP_CMD_OPERATION_STOP = 0x2, CTDP_CMD_OPERATION_REPORT = 0x4, };/* CTDP_CMD_OPERATION_TYPE_E */ /** - * struct iwl_mvm_ctdp_cmd - track and manage the FW power consumption budget + * struct iwl_ctdp_cmd - track and manage the FW power consumption budget * - * @operation: see &enum iwl_mvm_ctdp_cmd_operation + * @operation: see &enum iwl_ctdp_cmd_operation * @budget: the budget in milliwatt * @window_size: defined in API but not used */ -struct iwl_mvm_ctdp_cmd { +struct iwl_ctdp_cmd { __le32 operation; __le32 budget; __le32 window_size; diff --git a/drivers/net/wireless/intel/iwlwifi/fw/api/rs.h b/drivers/net/wireless/intel/iwlwifi/fw/api/rs.h index 1a60f0cdf972..c2f806cbab59 100644 --- a/drivers/net/wireless/intel/iwlwifi/fw/api/rs.h +++ b/drivers/net/wireless/intel/iwlwifi/fw/api/rs.h @@ -226,6 +226,58 @@ struct iwl_tlc_update_notif { __le32 amsdu_enabled; } __packed; /* TLC_MNG_UPDATE_NTFY_API_S_VER_2 */ +/** + * enum iwl_tlc_debug_types - debug options + */ +enum iwl_tlc_debug_types { + /** + * @IWL_TLC_DEBUG_FIXED_RATE: set fixed rate for rate scaling + */ + IWL_TLC_DEBUG_FIXED_RATE, + /** + * @IWL_TLC_DEBUG_AGG_DURATION_LIM: time limit for a BA + * session, in usec + */ + IWL_TLC_DEBUG_AGG_DURATION_LIM, + /** + * @IWL_TLC_DEBUG_AGG_FRAME_CNT_LIM: set max number of frames + * in an aggregation + */ + IWL_TLC_DEBUG_AGG_FRAME_CNT_LIM, + /** + * @IWL_TLC_DEBUG_TPC_ENABLED: enable or disable tpc + */ + IWL_TLC_DEBUG_TPC_ENABLED, + /** + * @IWL_TLC_DEBUG_TPC_STATS: get number of frames Tx'ed in each + * tpc step + */ + IWL_TLC_DEBUG_TPC_STATS, + /** + * @IWL_TLC_DEBUG_RTS_DISABLE: disable RTS (bool true/false). + */ + IWL_TLC_DEBUG_RTS_DISABLE, + /** + * @IWL_TLC_DEBUG_PARTIAL_FIXED_RATE: set partial fixed rate to fw + */ + IWL_TLC_DEBUG_PARTIAL_FIXED_RATE, +}; /* TLC_MNG_DEBUG_TYPES_API_E */ + +#define MAX_DATA_IN_DHC_TLC_CMD 10 + +/** + * struct iwl_dhc_tlc_cmd - fixed debug config + * @sta_id: bit 0 - enable/disable, bits 1 - 7 hold station id + * @reserved1: reserved + * @type: type id of %enum iwl_tlc_debug_types + * @data: data to send + */ +struct iwl_dhc_tlc_cmd { + u8 sta_id; + u8 reserved1[3]; + __le32 type; + __le32 data[MAX_DATA_IN_DHC_TLC_CMD]; +} __packed; /* TLC_MNG_DEBUG_CMD_S */ #define IWL_MAX_MCS_DISPLAY_SIZE 12 diff --git a/drivers/net/wireless/intel/iwlwifi/fw/api/sta.h b/drivers/net/wireless/intel/iwlwifi/fw/api/sta.h index d7f8a276b683..ecbcd5084cd8 100644 --- a/drivers/net/wireless/intel/iwlwifi/fw/api/sta.h +++ b/drivers/net/wireless/intel/iwlwifi/fw/api/sta.h @@ -191,6 +191,7 @@ enum iwl_sta_sleep_flag { #define STA_KEY_IDX_INVALID (0xff) #define STA_KEY_MAX_DATA_KEY_NUM (4) #define IWL_MAX_GLOBAL_KEYS (4) +#define IWL_MAX_NUM_IGTKS 2 #define STA_KEY_LEN_WEP40 (5) #define STA_KEY_LEN_WEP104 (13) diff --git a/drivers/net/wireless/intel/iwlwifi/fw/api/time-event.h b/drivers/net/wireless/intel/iwlwifi/fw/api/time-event.h index 18d030334a6a..f586379d66dd 100644 --- a/drivers/net/wireless/intel/iwlwifi/fw/api/time-event.h +++ b/drivers/net/wireless/intel/iwlwifi/fw/api/time-event.h @@ -1,6 +1,6 @@ /* SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause */ /* - * Copyright (C) 2012-2014, 2018-2020, 2022-2024 Intel Corporation + * Copyright (C) 2012-2014, 2018-2020, 2022-2025 Intel Corporation * Copyright (C) 2013-2015 Intel Mobile Communications GmbH * Copyright (C) 2016-2017 Intel Deutschland GmbH */ @@ -351,7 +351,7 @@ enum iwl_roc_activity { }; /* ROC_ACTIVITY_API_E_VER_1 */ /* - * ROC command + * ROC command v5 * * Command requests the firmware to remain on a channel for a certain duration. * @@ -366,7 +366,7 @@ enum iwl_roc_activity { * @max_delay: max delay the ROC can start in TU * @duration: remain on channel duration in TU */ -struct iwl_roc_req { +struct iwl_roc_req_v5 { __le32 action; __le32 activity; __le32 sta_id; @@ -375,7 +375,41 @@ struct iwl_roc_req { __le16 reserved; __le32 max_delay; __le32 duration; -} __packed; /* ROC_CMD_API_S_VER_3 */ +} __packed; /* ROC_CMD_API_S_VER_5 */ + +/* + * ROC command + * + * Command requests the firmware to remain on a channel for a certain duration. + * + * ( MAC_CONF_GROUP 0x3, ROC_CMD 0xE ) + * + * @action: action to perform, see &enum iwl_ctxt_action + * @activity: type of activity, see &enum iwl_roc_activity + * @sta_id: station id, resumed during "Remain On Channel" activity. + * @channel_info: &struct iwl_fw_channel_info + * @node_addr: node MAC address for Rx filtering + * @reserved1: align to a dword + * @max_delay: max delay the ROC can start in TU + * @duration: remain on channel duration in TU + * @interval: interval between repetitions (when repetitions > 1). + * @repetitions: number of repetitions + * 0xFF: infinite repetitions. 0 or 1: single repetition. + * @reserved2: align to a dword + */ +struct iwl_roc_req { + __le32 action; + __le32 activity; + __le32 sta_id; + struct iwl_fw_channel_info channel_info; + u8 node_addr[ETH_ALEN]; + __le16 reserved1; + __le32 max_delay; + __le32 duration; + __le32 interval; + u8 repetitions; + u8 reserved2[3]; +} __packed; /* ROC_CMD_API_S_VER_6 */ /* * ROC notification diff --git a/drivers/net/wireless/intel/iwlwifi/fw/dbg.c b/drivers/net/wireless/intel/iwlwifi/fw/dbg.c index fb2ea38e89ac..634e2543ba6d 100644 --- a/drivers/net/wireless/intel/iwlwifi/fw/dbg.c +++ b/drivers/net/wireless/intel/iwlwifi/fw/dbg.c @@ -1,6 +1,6 @@ // SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause /* - * Copyright (C) 2005-2014, 2018-2024 Intel Corporation + * Copyright (C) 2005-2014, 2018-2025 Intel Corporation * Copyright (C) 2013-2015 Intel Mobile Communications GmbH * Copyright (C) 2015-2017 Intel Deutschland GmbH */ @@ -2588,29 +2588,28 @@ static const struct iwl_dump_ini_mem_ops iwl_dump_ini_region_ops[] = { }, }; -static u32 iwl_dump_ini_trigger(struct iwl_fw_runtime *fwrt, - struct iwl_fwrt_dump_data *dump_data, - struct list_head *list) +enum iwl_dump_ini_region_selector { + IWL_INI_DUMP_ALL_REGIONS, + IWL_INI_DUMP_EARLY_REGIONS, + IWL_INI_DUMP_LATE_REGIONS, +}; + +static u32 +iwl_dump_ini_dump_regions(struct iwl_fw_runtime *fwrt, + struct iwl_fwrt_dump_data *dump_data, + struct list_head *list, + enum iwl_fw_ini_time_point tp_id, + u64 regions_mask, + struct iwl_dump_ini_region_data *imr_reg_data, + enum iwl_dump_ini_region_selector which) { - struct iwl_fw_ini_trigger_tlv *trigger = dump_data->trig; - enum iwl_fw_ini_time_point tp_id = le32_to_cpu(trigger->time_point); - struct iwl_dump_ini_region_data reg_data = { - .dump_data = dump_data, - }; - struct iwl_dump_ini_region_data imr_reg_data = { - .dump_data = dump_data, - }; - int i; u32 size = 0; - u64 regions_mask = le64_to_cpu(trigger->regions_mask) & - ~(fwrt->trans->dbg.unsupported_region_msk); - BUILD_BUG_ON(sizeof(trigger->regions_mask) != sizeof(regions_mask)); - BUILD_BUG_ON((sizeof(trigger->regions_mask) * BITS_PER_BYTE) < - ARRAY_SIZE(fwrt->trans->dbg.active_regions)); - - for (i = 0; i < ARRAY_SIZE(fwrt->trans->dbg.active_regions); i++) { - u32 reg_type; + for (int i = 0; i < ARRAY_SIZE(fwrt->trans->dbg.active_regions); i++) { + struct iwl_dump_ini_region_data reg_data = { + .dump_data = dump_data, + }; + u32 reg_type, dp; struct iwl_fw_ini_region_tlv *reg; if (!(BIT_ULL(i) & regions_mask)) @@ -2628,6 +2627,8 @@ static u32 iwl_dump_ini_trigger(struct iwl_fw_runtime *fwrt, if (reg_type >= ARRAY_SIZE(iwl_dump_ini_region_ops)) continue; + dp = le32_get_bits(reg->id, IWL_FW_INI_REGION_DUMP_POLICY_MASK); + if ((reg_type == IWL_FW_INI_REGION_PERIPHERY_PHY || reg_type == IWL_FW_INI_REGION_PERIPHERY_PHY_RANGE || reg_type == IWL_FW_INI_REGION_PERIPHERY_SNPS_DPHYIP) && @@ -2637,6 +2638,20 @@ static u32 iwl_dump_ini_trigger(struct iwl_fw_runtime *fwrt, tp_id); continue; } + + switch (which) { + case IWL_INI_DUMP_ALL_REGIONS: + break; + case IWL_INI_DUMP_EARLY_REGIONS: + if (!(dp & IWL_FW_IWL_DEBUG_DUMP_POLICY_BEFORE_RESET)) + continue; + break; + case IWL_INI_DUMP_LATE_REGIONS: + if (dp & IWL_FW_IWL_DEBUG_DUMP_POLICY_BEFORE_RESET) + continue; + break; + } + /* * DRAM_IMR can be collected only for FW/HW error timepoint * when fw is not alive. In addition, it must be collected @@ -2646,7 +2661,8 @@ static u32 iwl_dump_ini_trigger(struct iwl_fw_runtime *fwrt, if (reg_type == IWL_FW_INI_REGION_DRAM_IMR) { if (tp_id == IWL_FW_INI_TIME_POINT_FW_ASSERT || tp_id == IWL_FW_INI_TIME_POINT_FW_HW_ERROR) - imr_reg_data.reg_tlv = fwrt->trans->dbg.active_regions[i]; + imr_reg_data->reg_tlv = + fwrt->trans->dbg.active_regions[i]; else IWL_INFO(fwrt, "WRT: trying to collect DRAM_IMR at time point: %d, skipping\n", @@ -2659,9 +2675,44 @@ static u32 iwl_dump_ini_trigger(struct iwl_fw_runtime *fwrt, size += iwl_dump_ini_mem(fwrt, list, ®_data, &iwl_dump_ini_region_ops[reg_type]); } + + return size; +} + +static u32 iwl_dump_ini_trigger(struct iwl_fw_runtime *fwrt, + struct iwl_fwrt_dump_data *dump_data, + struct list_head *list) +{ + struct iwl_fw_ini_trigger_tlv *trigger = dump_data->trig; + enum iwl_fw_ini_time_point tp_id = le32_to_cpu(trigger->time_point); + struct iwl_dump_ini_region_data imr_reg_data = { + .dump_data = dump_data, + }; + u32 size = 0; + u64 regions_mask = le64_to_cpu(trigger->regions_mask) & + ~(fwrt->trans->dbg.unsupported_region_msk); + + BUILD_BUG_ON(sizeof(trigger->regions_mask) != sizeof(regions_mask)); + BUILD_BUG_ON((sizeof(trigger->regions_mask) * BITS_PER_BYTE) < + ARRAY_SIZE(fwrt->trans->dbg.active_regions)); + + if (trigger->time_point & + cpu_to_le32(IWL_FW_INI_APPLY_POLICY_RESET_HANDSHAKE)) { + size += iwl_dump_ini_dump_regions(fwrt, dump_data, list, tp_id, + regions_mask, &imr_reg_data, + IWL_INI_DUMP_EARLY_REGIONS); + iwl_trans_pcie_fw_reset_handshake(fwrt->trans); + size += iwl_dump_ini_dump_regions(fwrt, dump_data, list, tp_id, + regions_mask, &imr_reg_data, + IWL_INI_DUMP_LATE_REGIONS); + } else { + size += iwl_dump_ini_dump_regions(fwrt, dump_data, list, tp_id, + regions_mask, &imr_reg_data, + IWL_INI_DUMP_ALL_REGIONS); + } /* collect DRAM_IMR region in the last */ if (imr_reg_data.reg_tlv) - size += iwl_dump_ini_mem(fwrt, list, ®_data, + size += iwl_dump_ini_mem(fwrt, list, &imr_reg_data, &iwl_dump_ini_region_ops[IWL_FW_INI_REGION_DRAM_IMR]); if (size) { @@ -3042,9 +3093,8 @@ int iwl_fw_start_dbg_conf(struct iwl_fw_runtime *fwrt, u8 conf_id) } IWL_EXPORT_SYMBOL(iwl_fw_start_dbg_conf); -void iwl_send_dbg_dump_complete_cmd(struct iwl_fw_runtime *fwrt, - u32 timepoint, - u32 timepoint_data) +static void iwl_send_dbg_dump_complete_cmd(struct iwl_fw_runtime *fwrt, + u32 timepoint, u32 timepoint_data) { struct iwl_dbg_dump_complete_cmd hcmd_data; struct iwl_host_cmd hcmd = { @@ -3072,6 +3122,7 @@ static void iwl_fw_dbg_collect_sync(struct iwl_fw_runtime *fwrt, u8 wk_idx) struct iwl_fw_dbg_params params = {0}; struct iwl_fwrt_dump_data *dump_data = &fwrt->dump.wks[wk_idx].dump_data; + if (!test_bit(wk_idx, &fwrt->dump.active_wks)) return; @@ -3096,9 +3147,9 @@ static void iwl_fw_dbg_collect_sync(struct iwl_fw_runtime *fwrt, u8 wk_idx) IWL_DEBUG_FW_INFO(fwrt, "WRT: Data collection start\n"); if (iwl_trans_dbg_ini_valid(fwrt->trans)) - iwl_fw_error_ini_dump(fwrt, &fwrt->dump.wks[wk_idx].dump_data); + iwl_fw_error_ini_dump(fwrt, dump_data); else - iwl_fw_error_dump(fwrt, &fwrt->dump.wks[wk_idx].dump_data); + iwl_fw_error_dump(fwrt, dump_data); IWL_DEBUG_FW_INFO(fwrt, "WRT: Data collection done\n"); iwl_fw_dbg_stop_restart_recording(fwrt, ¶ms, false); @@ -3115,7 +3166,6 @@ static void iwl_fw_dbg_collect_sync(struct iwl_fw_runtime *fwrt, u8 wk_idx) if (fwrt->trans->dbg.last_tp_resetfw == IWL_FW_INI_RESET_FW_MODE_STOP_FW_ONLY) iwl_force_nmi(fwrt->trans); - out: if (iwl_trans_dbg_ini_valid(fwrt->trans)) { iwl_fw_error_dump_data_free(dump_data); diff --git a/drivers/net/wireless/intel/iwlwifi/fw/dbg.h b/drivers/net/wireless/intel/iwlwifi/fw/dbg.h index 87998374f459..35e30e5db462 100644 --- a/drivers/net/wireless/intel/iwlwifi/fw/dbg.h +++ b/drivers/net/wireless/intel/iwlwifi/fw/dbg.h @@ -324,9 +324,6 @@ static inline void iwl_fwrt_update_fw_versions(struct iwl_fw_runtime *fwrt, } void iwl_fwrt_dump_error_logs(struct iwl_fw_runtime *fwrt); -void iwl_send_dbg_dump_complete_cmd(struct iwl_fw_runtime *fwrt, - u32 timepoint, - u32 timepoint_data); bool iwl_fwrt_read_err_table(struct iwl_trans *trans, u32 base, u32 *err_id); void iwl_fw_disable_dbg_asserts(struct iwl_fw_runtime *fwrt); void iwl_fw_dbg_clear_monitor_buf(struct iwl_fw_runtime *fwrt); diff --git a/drivers/net/wireless/intel/iwlwifi/fw/regulatory.c b/drivers/net/wireless/intel/iwlwifi/fw/regulatory.c index ea435ee94312..6adcfa6e214a 100644 --- a/drivers/net/wireless/intel/iwlwifi/fw/regulatory.c +++ b/drivers/net/wireless/intel/iwlwifi/fw/regulatory.c @@ -456,7 +456,25 @@ iwl_parse_tas_selection(const u32 tas_selection_in, const u8 tbl_rev) } IWL_EXPORT_SYMBOL(iwl_parse_tas_selection); -static __le32 iwl_get_lari_config_bitmap(struct iwl_fw_runtime *fwrt) +bool iwl_add_mcc_to_tas_block_list(u16 *list, u8 *size, u16 mcc) +{ + for (int i = 0; i < *size; i++) { + if (list[i] == mcc) + return true; + } + + /* Verify that there is room for another country + * If *size == IWL_WTAS_BLACK_LIST_MAX, then the table is full. + */ + if (*size >= IWL_WTAS_BLACK_LIST_MAX) + return false; + + list[*size++] = mcc; + return true; +} +IWL_EXPORT_SYMBOL(iwl_add_mcc_to_tas_block_list); + +__le32 iwl_get_lari_config_bitmap(struct iwl_fw_runtime *fwrt) { int ret; u32 val; @@ -503,6 +521,7 @@ static __le32 iwl_get_lari_config_bitmap(struct iwl_fw_runtime *fwrt) return config_bitmap; } +IWL_EXPORT_SYMBOL(iwl_get_lari_config_bitmap); static size_t iwl_get_lari_config_cmd_size(u8 cmd_ver) { @@ -553,6 +572,10 @@ int iwl_fill_lari_config(struct iwl_fw_runtime *fwrt, WIDE_ID(REGULATORY_AND_NVM_GROUP, LARI_CONFIG_CHANGE), 1); + if (WARN_ONCE(cmd_ver > 12, + "Don't add newer versions to this function\n")) + return -EINVAL; + memset(cmd, 0, sizeof(*cmd)); *cmd_size = iwl_get_lari_config_cmd_size(cmd_ver); @@ -674,3 +697,34 @@ bool iwl_puncturing_is_allowed_in_bios(u32 puncturing, u16 mcc) } } IWL_EXPORT_SYMBOL(iwl_puncturing_is_allowed_in_bios); + +bool iwl_rfi_is_enabled_in_bios(struct iwl_fw_runtime *fwrt) +{ + /* default behaviour is disabled */ + u32 value = 0; + int ret = iwl_bios_get_dsm(fwrt, DSM_FUNC_RFI_CONFIG, &value); + + if (ret < 0) { + IWL_DEBUG_RADIO(fwrt, "Failed to get DSM RFI, ret=%d\n", ret); + return false; + } + + value &= DSM_VALUE_RFI_DISABLE; + /* RFI BIOS CONFIG value can be 0 or 3 only. + * i.e 0 means DDR and DLVR enabled. 3 means DDR and DLVR disabled. + * 1 and 2 are invalid BIOS configurations, So, it's not possible to + * disable ddr/dlvr separately. + */ + if (!value) { + IWL_DEBUG_RADIO(fwrt, "DSM RFI is evaluated to enable\n"); + return true; + } else if (value == DSM_VALUE_RFI_DISABLE) { + IWL_DEBUG_RADIO(fwrt, "DSM RFI is evaluated to disable\n"); + } else { + IWL_DEBUG_RADIO(fwrt, + "DSM RFI got invalid value, value=%d\n", value); + } + + return false; +} +IWL_EXPORT_SYMBOL(iwl_rfi_is_enabled_in_bios); diff --git a/drivers/net/wireless/intel/iwlwifi/fw/regulatory.h b/drivers/net/wireless/intel/iwlwifi/fw/regulatory.h index b355d7bef14c..53693314d505 100644 --- a/drivers/net/wireless/intel/iwlwifi/fw/regulatory.h +++ b/drivers/net/wireless/intel/iwlwifi/fw/regulatory.h @@ -167,6 +167,8 @@ enum iwl_dsm_values_rfi { #define DSM_VALUE_RFI_DISABLE (DSM_VALUE_RFI_DLVR_DISABLE |\ DSM_VALUE_RFI_DDR_DISABLE) +bool iwl_rfi_is_enabled_in_bios(struct iwl_fw_runtime *fwrt); + enum iwl_dsm_masks_reg { DSM_MASK_CHINA_22_REG = BIT(2) }; @@ -190,6 +192,7 @@ int iwl_fill_ppag_table(struct iwl_fw_runtime *fwrt, bool iwl_is_ppag_approved(struct iwl_fw_runtime *fwrt); bool iwl_is_tas_approved(void); +bool iwl_add_mcc_to_tas_block_list(u16 *list, u8 *size, u16 mcc); struct iwl_tas_selection_data iwl_parse_tas_selection(const u32 tas_selection, const u8 tbl_rev); @@ -212,6 +215,7 @@ int iwl_bios_get_mcc(struct iwl_fw_runtime *fwrt, char *mcc); int iwl_bios_get_eckv(struct iwl_fw_runtime *fwrt, u32 *ext_clk); int iwl_bios_get_wbem(struct iwl_fw_runtime *fwrt, u32 *value); +__le32 iwl_get_lari_config_bitmap(struct iwl_fw_runtime *fwrt); int iwl_fill_lari_config(struct iwl_fw_runtime *fwrt, struct iwl_lari_config_change_cmd *cmd, size_t *cmd_size); diff --git a/drivers/net/wireless/intel/iwlwifi/fw/runtime.h b/drivers/net/wireless/intel/iwlwifi/fw/runtime.h index 048877fa7c71..a9e6bba2419e 100644 --- a/drivers/net/wireless/intel/iwlwifi/fw/runtime.h +++ b/drivers/net/wireless/intel/iwlwifi/fw/runtime.h @@ -104,6 +104,7 @@ struct iwl_txf_iter_data { * the driver by calling &iwl_fw_set_current_image() * @dump: debug dump data * @uats_table: AP type table + * @uats_valid: is AP type table valid * @uefi_tables_lock_status: The status of the WIFI GUID UEFI variables lock: * 0: Unlocked, 1 and 2: Locked. * Only read the UEFI variables if locked. @@ -181,6 +182,7 @@ struct iwl_fw_runtime { struct iwl_sar_offset_mapping_cmd sgom_table; bool sgom_enabled; struct iwl_mcc_allowed_ap_type_cmd uats_table; + bool uats_valid; u8 uefi_tables_lock_status; }; diff --git a/drivers/net/wireless/intel/iwlwifi/fw/uefi.c b/drivers/net/wireless/intel/iwlwifi/fw/uefi.c index 434eed4130b9..78bd0eb7aa92 100644 --- a/drivers/net/wireless/intel/iwlwifi/fw/uefi.c +++ b/drivers/net/wireless/intel/iwlwifi/fw/uefi.c @@ -402,6 +402,9 @@ static int iwl_uefi_uats_parse(struct uefi_cnv_wlan_uats_data *uats_data, memcpy(fwrt->uats_table.offset_map, uats_data->offset_map, sizeof(fwrt->uats_table.offset_map)); + + fwrt->uats_valid = true; + return 0; } diff --git a/drivers/net/wireless/intel/iwlwifi/iwl-config.h b/drivers/net/wireless/intel/iwlwifi/iwl-config.h index 2b6a80142aba..5fc9ce2b350e 100644 --- a/drivers/net/wireless/intel/iwlwifi/iwl-config.h +++ b/drivers/net/wireless/intel/iwlwifi/iwl-config.h @@ -2,7 +2,7 @@ /* * Copyright (C) 2005-2014, 2018-2021 Intel Corporation * Copyright (C) 2016-2017 Intel Deutschland GmbH - * Copyright (C) 2018-2024 Intel Corporation + * Copyright (C) 2018-2025 Intel Corporation */ #ifndef __IWL_CONFIG_H__ #define __IWL_CONFIG_H__ @@ -451,11 +451,8 @@ struct iwl_cfg { #define IWL_CFG_RF_ID_HR 0x7 #define IWL_CFG_RF_ID_HR1 0x4 -#define IWL_CFG_NO_160 0x1 -#define IWL_CFG_160 0x0 - -#define IWL_CFG_NO_320 0x1 -#define IWL_CFG_320 0x0 +#define IWL_CFG_BW_NO_LIM (U16_MAX - 1) +#define IWL_CFG_BW_ANY U16_MAX #define IWL_CFG_CORES_BT 0x0 #define IWL_CFG_CORES_BT_GNSS 0x5 @@ -467,7 +464,7 @@ struct iwl_cfg { #define IWL_CFG_IS_JACKET 0x1 #define IWL_SUBDEVICE_RF_ID(subdevice) ((u16)((subdevice) & 0x00F0) >> 4) -#define IWL_SUBDEVICE_NO_160(subdevice) ((u16)((subdevice) & 0x0200) >> 9) +#define IWL_SUBDEVICE_BW_LIM(subdevice) ((u16)((subdevice) & 0x0200) >> 9) #define IWL_SUBDEVICE_CORES(subdevice) ((u16)((subdevice) & 0x1C00) >> 10) struct iwl_dev_info { @@ -475,10 +472,10 @@ struct iwl_dev_info { u16 subdevice; u16 mac_type; u16 rf_type; + u16 bw_limit; u8 mac_step; u8 rf_step; u8 rf_id; - u8 no_160; u8 cores; u8 cdb; u8 jacket; @@ -492,7 +489,7 @@ extern const unsigned int iwl_dev_info_table_size; const struct iwl_dev_info * iwl_pci_find_dev_info(u16 device, u16 subsystem_device, u16 mac_type, u8 mac_step, u16 rf_type, u8 cdb, - u8 jacket, u8 rf_id, u8 no_160, u8 cores, u8 rf_step); + u8 jacket, u8 rf_id, u8 bw_limit, u8 cores, u8 rf_step); extern const struct pci_device_id iwl_hw_card_ids[]; #endif @@ -534,7 +531,6 @@ extern const char iwl9560_killer_1550i_name[]; extern const char iwl9560_killer_1550s_name[]; extern const char iwl_ax200_name[]; extern const char iwl_ax203_name[]; -extern const char iwl_ax204_name[]; extern const char iwl_ax201_name[]; extern const char iwl_ax101_name[]; extern const char iwl_ax200_killer_1650w_name[]; @@ -550,17 +546,12 @@ extern const char iwl_ax211_killer_1675i_name[]; extern const char iwl_ax411_killer_1690s_name[]; extern const char iwl_ax411_killer_1690i_name[]; extern const char iwl_ax211_name[]; -extern const char iwl_ax221_name[]; extern const char iwl_ax231_name[]; extern const char iwl_ax411_name[]; -extern const char iwl_bz_name[]; extern const char iwl_fm_name[]; extern const char iwl_wh_name[]; extern const char iwl_gl_name[]; extern const char iwl_mtp_name[]; -extern const char iwl_sc_name[]; -extern const char iwl_sc2_name[]; -extern const char iwl_sc2f_name[]; extern const char iwl_dr_name[]; extern const char iwl_br_name[]; #if IS_ENABLED(CONFIG_IWLDVM) @@ -663,6 +654,8 @@ extern const struct iwl_cfg iwl_cfg_ma; extern const struct iwl_cfg iwl_cfg_so_a0_hr_a0; extern const struct iwl_cfg iwl_cfg_quz_a0_hr_b0; +extern const struct iwl_ht_params iwl_bz_ht_params; + extern const struct iwl_cfg iwl_cfg_bz; extern const struct iwl_cfg iwl_cfg_gl; diff --git a/drivers/net/wireless/intel/iwlwifi/iwl-context-info-gen3.h b/drivers/net/wireless/intel/iwlwifi/iwl-context-info-gen3.h index cd25a1b9f2ff..20563a32a21a 100644 --- a/drivers/net/wireless/intel/iwlwifi/iwl-context-info-gen3.h +++ b/drivers/net/wireless/intel/iwlwifi/iwl-context-info-gen3.h @@ -1,6 +1,6 @@ /* SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause */ /* - * Copyright (C) 2018, 2020-2024 Intel Corporation + * Copyright (C) 2018, 2020-2025 Intel Corporation */ #ifndef __iwl_context_info_file_gen3_h__ #define __iwl_context_info_file_gen3_h__ @@ -80,10 +80,12 @@ enum iwl_prph_scratch_flags { * enum iwl_prph_scratch_ext_flags - PRPH scratch control ext flags * @IWL_PRPH_SCRATCH_EXT_URM_FW: switch to URM mode based on fw setting * @IWL_PRPH_SCRATCH_EXT_URM_PERM: switch to permanent URM mode + * @IWL_PRPH_SCRATCH_EXT_32KHZ_CLK_VALID: use external 32 KHz clock */ enum iwl_prph_scratch_ext_flags { - IWL_PRPH_SCRATCH_EXT_URM_FW = BIT(4), - IWL_PRPH_SCRATCH_EXT_URM_PERM = BIT(5), + IWL_PRPH_SCRATCH_EXT_URM_FW = BIT(4), + IWL_PRPH_SCRATCH_EXT_URM_PERM = BIT(5), + IWL_PRPH_SCRATCH_EXT_32KHZ_CLK_VALID = BIT(8), }; /** diff --git a/drivers/net/wireless/intel/iwlwifi/iwl-debug.h b/drivers/net/wireless/intel/iwlwifi/iwl-debug.h index bf52c2edaad1..ea32dc88584f 100644 --- a/drivers/net/wireless/intel/iwlwifi/iwl-debug.h +++ b/drivers/net/wireless/intel/iwlwifi/iwl-debug.h @@ -2,7 +2,7 @@ /****************************************************************************** * * Copyright(c) 2003 - 2014 Intel Corporation. All rights reserved. - * Copyright(c) 2018 - 2021, 2024 Intel Corporation + * Copyright(c) 2018 - 2021, 2024-2025 Intel Corporation * * Portions of this file are derived from the ipw3945 project. *****************************************************************************/ @@ -156,6 +156,7 @@ do { \ #define IWL_DL_FW 0x00010000 #define IWL_DL_RF_KILL 0x00020000 #define IWL_DL_TPT 0x00040000 +#define IWL_DL_PTP 0x00080000 /* 0x00F00000 - 0x00100000 */ #define IWL_DL_RATE 0x00100000 #define IWL_DL_CALIB 0x00200000 @@ -165,7 +166,7 @@ do { \ #define IWL_DL_RX 0x01000000 #define IWL_DL_ISR 0x02000000 #define IWL_DL_HT 0x04000000 -#define IWL_DL_EXTERNAL 0x08000000 +#define IWL_DL_EHT 0x08000000 /* 0xF0000000 - 0x10000000 */ #define IWL_DL_11H 0x10000000 #define IWL_DL_STATS 0x20000000 @@ -175,7 +176,6 @@ do { \ #define IWL_DEBUG_INFO(p, f, a...) IWL_DEBUG(p, IWL_DL_INFO, f, ## a) #define IWL_DEBUG_TDLS(p, f, a...) IWL_DEBUG(p, IWL_DL_TDLS, f, ## a) #define IWL_DEBUG_MAC80211(p, f, a...) IWL_DEBUG(p, IWL_DL_MAC80211, f, ## a) -#define IWL_DEBUG_EXTERNAL(p, f, a...) IWL_DEBUG(p, IWL_DL_EXTERNAL, f, ## a) #define IWL_DEBUG_TEMP(p, f, a...) IWL_DEBUG(p, IWL_DL_TEMP, f, ## a) #define IWL_DEBUG_SCAN(p, f, a...) IWL_DEBUG(p, IWL_DL_SCAN, f, ## a) #define IWL_DEBUG_RX(p, f, a...) IWL_DEBUG(p, IWL_DL_RX, f, ## a) @@ -216,5 +216,6 @@ do { \ #define IWL_DEBUG_LAR(p, f, a...) IWL_DEBUG(p, IWL_DL_LAR, f, ## a) #define IWL_DEBUG_FW_INFO(p, f, a...) \ IWL_DEBUG(p, IWL_DL_INFO | IWL_DL_FW, f, ## a) - +#define IWL_DEBUG_PTP(p, f, a...) IWL_DEBUG(p, IWL_DL_PTP, f, ## a) +#define IWL_DEBUG_EHT(p, f, a...) IWL_DEBUG(p, IWL_DL_EHT, f, ## a) #endif diff --git a/drivers/net/wireless/intel/iwlwifi/iwl-nvm-parse.c b/drivers/net/wireless/intel/iwlwifi/iwl-nvm-parse.c index 9f7e013252fe..08269168b2fa 100644 --- a/drivers/net/wireless/intel/iwlwifi/iwl-nvm-parse.c +++ b/drivers/net/wireless/intel/iwlwifi/iwl-nvm-parse.c @@ -1,6 +1,6 @@ // SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause /* - * Copyright (C) 2005-2014, 2018-2023 Intel Corporation + * Copyright (C) 2005-2014, 2018-2023, 2025 Intel Corporation * Copyright (C) 2013-2015 Intel Mobile Communications GmbH * Copyright (C) 2016-2017 Intel Deutschland GmbH */ @@ -684,10 +684,13 @@ static const struct ieee80211_sband_iftype_data iwl_he_eht_capa[] = { .has_eht = true, .eht_cap_elem = { .mac_cap_info[0] = + IEEE80211_EHT_MAC_CAP0_EPCS_PRIO_ACCESS | IEEE80211_EHT_MAC_CAP0_OM_CONTROL | IEEE80211_EHT_MAC_CAP0_TRIG_TXOP_SHARING_MODE1 | IEEE80211_EHT_MAC_CAP0_TRIG_TXOP_SHARING_MODE2 | IEEE80211_EHT_MAC_CAP0_SCS_TRAFFIC_DESC, + .mac_cap_info[1] = + IEEE80211_EHT_MAC_CAP1_UNSOL_EPCS_PRIO_ACCESS, .phy_cap_info[0] = IEEE80211_EHT_PHY_CAP0_242_TONE_RU_GT20MHZ | IEEE80211_EHT_PHY_CAP0_NDP_4_EHT_LFT_32_GI | @@ -913,11 +916,8 @@ iwl_nvm_fixup_sband_iftd(struct iwl_trans *trans, { bool is_ap = iftype_data->types_mask & (BIT(NL80211_IFTYPE_AP) | BIT(NL80211_IFTYPE_P2P_GO)); - bool no_320; - - no_320 = (!trans->trans_cfg->integrated && - trans->pcie_link_speed < PCI_EXP_LNKSTA_CLS_8_0GB) || - trans->reduced_cap_sku; + bool slow_pcie = (!trans->trans_cfg->integrated && + trans->pcie_link_speed < PCI_EXP_LNKSTA_CLS_8_0GB); if (!data->sku_cap_11be_enable || iwlwifi_mod_params.disable_11be) iftype_data->eht_cap.has_eht = false; @@ -944,7 +944,7 @@ iwl_nvm_fixup_sband_iftd(struct iwl_trans *trans, IEEE80211_EHT_MAC_CAP0_MAX_MPDU_LEN_MASK); break; case NL80211_BAND_6GHZ: - if (!no_320) { + if (!trans->reduced_cap_sku) { iftype_data->eht_cap.eht_cap_elem.phy_cap_info[0] |= IEEE80211_EHT_PHY_CAP0_320MHZ_IN_6GHZ; iftype_data->eht_cap.eht_cap_elem.phy_cap_info[1] |= @@ -986,6 +986,14 @@ iwl_nvm_fixup_sband_iftd(struct iwl_trans *trans, iftype_data->eht_cap.eht_cap_elem.phy_cap_info[4] |= 0x10; } } + + if (slow_pcie) { + struct ieee80211_eht_mcs_nss_supp *mcs_nss = + &iftype_data->eht_cap.eht_mcs_nss_supp; + + mcs_nss->bw._320.rx_tx_mcs11_max_nss = 0; + mcs_nss->bw._320.rx_tx_mcs13_max_nss = 0; + } } else { struct ieee80211_he_mcs_nss_supp *he_mcs_nss_supp = &iftype_data->he_cap.he_mcs_nss_supp; @@ -1086,7 +1094,7 @@ iwl_nvm_fixup_sband_iftd(struct iwl_trans *trans, iftype_data->eht_cap.eht_mcs_nss_supp.bw._320.rx_tx_mcs13_max_nss = 0; } - if (trans->no_160) + if (trans->bw_limit < 160) iftype_data->he_cap.he_cap_elem.phy_cap_info[0] &= ~IEEE80211_HE_PHY_CAP0_CHANNEL_WIDTH_SET_160MHZ_IN_5G; diff --git a/drivers/net/wireless/intel/iwlwifi/iwl-trans.c b/drivers/net/wireless/intel/iwlwifi/iwl-trans.c index 49c8507d1a6b..1632ab20a23f 100644 --- a/drivers/net/wireless/intel/iwlwifi/iwl-trans.c +++ b/drivers/net/wireless/intel/iwlwifi/iwl-trans.c @@ -97,7 +97,7 @@ static void iwl_trans_reprobe_wk(struct work_struct *wk) module_put(THIS_MODULE); } -#define IWL_TRANS_RESET_OK_TIME 180 /* seconds */ +#define IWL_TRANS_RESET_OK_TIME 7 /* seconds */ static enum iwl_reset_mode iwl_trans_determine_restart_mode(struct iwl_trans *trans) @@ -671,6 +671,9 @@ IWL_EXPORT_SYMBOL(iwl_trans_txq_enable_cfg); int iwl_trans_wait_txq_empty(struct iwl_trans *trans, int queue) { + if (unlikely(test_bit(STATUS_FW_ERROR, &trans->status))) + return -EIO; + if (WARN_ONCE(trans->state != IWL_TRANS_FW_ALIVE, "bad state = %d\n", trans->state)) return -EIO; diff --git a/drivers/net/wireless/intel/iwlwifi/iwl-trans.h b/drivers/net/wireless/intel/iwlwifi/iwl-trans.h index f6234065dbdd..25fb4c50e38b 100644 --- a/drivers/net/wireless/intel/iwlwifi/iwl-trans.h +++ b/drivers/net/wireless/intel/iwlwifi/iwl-trans.h @@ -1,6 +1,6 @@ /* SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause */ /* - * Copyright (C) 2005-2014, 2018-2023 Intel Corporation + * Copyright (C) 2005-2014, 2018-2023, 2025 Intel Corporation * Copyright (C) 2013-2015 Intel Mobile Communications GmbH * Copyright (C) 2016-2017 Intel Deutschland GmbH */ @@ -876,7 +876,7 @@ struct iwl_txq { * only valid for discrete (not integrated) NICs * @invalid_tx_cmd: invalid TX command buffer * @reduced_cap_sku: reduced capability supported SKU - * @no_160: device not supporting 160 MHz + * @bw_limit: the max bandwidth * @step_urm: STEP is in URM, no support for MCS>9 in 320 MHz * @restart: restart worker data * @restart.wk: restart worker @@ -888,6 +888,7 @@ struct iwl_txq { * @trans_specific: data for the specific transport this is allocated for/with * @dsbr_urm_fw_dependent: switch to URM based on fw settings * @dsbr_urm_permanent: switch to URM permanently + * @ext_32khz_clock_valid: if true, the external 32 KHz clock can be used */ struct iwl_trans { bool csme_own; @@ -910,11 +911,14 @@ struct iwl_trans { char hw_id_str[52]; u32 sku_id[3]; bool reduced_cap_sku; - u8 no_160:1, step_urm:1; + u16 bw_limit; + bool step_urm; u8 dsbr_urm_fw_dependent:1, dsbr_urm_permanent:1; + bool ext_32khz_clock_valid; + u8 rx_mpdu_cmd, rx_mpdu_cmd_hdr_size; bool pm_support; @@ -1261,6 +1265,7 @@ enum iwl_reset_mode { }; void iwl_trans_pcie_reset(struct iwl_trans *trans, enum iwl_reset_mode mode); +void iwl_trans_pcie_fw_reset_handshake(struct iwl_trans *trans); int iwl_trans_pcie_send_hcmd(struct iwl_trans *trans, struct iwl_host_cmd *cmd); diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/d3.c b/drivers/net/wireless/intel/iwlwifi/mvm/d3.c index 129b6bdf9ef9..632f1a26672c 100644 --- a/drivers/net/wireless/intel/iwlwifi/mvm/d3.c +++ b/drivers/net/wireless/intel/iwlwifi/mvm/d3.c @@ -3376,7 +3376,7 @@ static bool iwl_mvm_wait_d3_notif(struct iwl_notif_wait_data *notif_wait, break; } case WIDE_ID(PROT_OFFLOAD_GROUP, D3_END_NOTIFICATION): { - struct iwl_mvm_d3_end_notif *notif = (void *)pkt->data; + struct iwl_d3_end_notif *notif = (void *)pkt->data; d3_data->d3_end_flags = __le32_to_cpu(notif->flags); d3_data->notif_received |= IWL_D3_NOTIF_D3_END_NOTIF; diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/ftm-initiator.c b/drivers/net/wireless/intel/iwlwifi/mvm/ftm-initiator.c index b26141c30c61..dfb25b964f0e 100644 --- a/drivers/net/wireless/intel/iwlwifi/mvm/ftm-initiator.c +++ b/drivers/net/wireless/intel/iwlwifi/mvm/ftm-initiator.c @@ -1,7 +1,7 @@ // SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause /* * Copyright (C) 2015-2017 Intel Deutschland GmbH - * Copyright (C) 2018-2024 Intel Corporation + * Copyright (C) 2018-2025 Intel Corporation */ #include <linux/etherdevice.h> #include <linux/math64.h> @@ -46,107 +46,6 @@ struct iwl_mvm_ftm_iter_data { u8 *tk; }; -int iwl_mvm_ftm_add_pasn_sta(struct iwl_mvm *mvm, struct ieee80211_vif *vif, - u8 *addr, u32 cipher, u8 *tk, u32 tk_len, - u8 *hltk, u32 hltk_len) -{ - struct iwl_mvm_ftm_pasn_entry *pasn = kzalloc(sizeof(*pasn), - GFP_KERNEL); - u32 expected_tk_len; - - lockdep_assert_held(&mvm->mutex); - - if (!pasn) - return -ENOBUFS; - - iwl_mvm_ftm_remove_pasn_sta(mvm, addr); - - pasn->cipher = iwl_mvm_cipher_to_location_cipher(cipher); - - switch (pasn->cipher) { - case IWL_LOCATION_CIPHER_CCMP_128: - case IWL_LOCATION_CIPHER_GCMP_128: - expected_tk_len = WLAN_KEY_LEN_CCMP; - break; - case IWL_LOCATION_CIPHER_GCMP_256: - expected_tk_len = WLAN_KEY_LEN_GCMP_256; - break; - default: - goto out; - } - - /* - * If associated to this AP and already have security context, - * the TK is already configured for this station, so it - * shouldn't be set again here. - */ - if (vif->cfg.assoc) { - struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif); - struct ieee80211_bss_conf *link_conf; - unsigned int link_id; - struct ieee80211_sta *sta; - u8 sta_id; - - rcu_read_lock(); - for_each_vif_active_link(vif, link_conf, link_id) { - if (memcmp(addr, link_conf->bssid, ETH_ALEN)) - continue; - - sta_id = mvmvif->link[link_id]->ap_sta_id; - sta = rcu_dereference(mvm->fw_id_to_mac_id[sta_id]); - if (!IS_ERR_OR_NULL(sta) && sta->mfp) - expected_tk_len = 0; - break; - } - rcu_read_unlock(); - } - - if (tk_len != expected_tk_len || - (hltk_len && hltk_len != sizeof(pasn->hltk))) { - IWL_ERR(mvm, "Invalid key length: tk_len=%u hltk_len=%u\n", - tk_len, hltk_len); - goto out; - } - - if (!expected_tk_len && !hltk_len) { - IWL_ERR(mvm, "TK and HLTK not set\n"); - goto out; - } - - memcpy(pasn->addr, addr, sizeof(pasn->addr)); - - if (hltk_len) { - memcpy(pasn->hltk, hltk, sizeof(pasn->hltk)); - pasn->flags |= IWL_MVM_PASN_FLAG_HAS_HLTK; - } - - if (tk && tk_len) - memcpy(pasn->tk, tk, sizeof(pasn->tk)); - - list_add_tail(&pasn->list, &mvm->ftm_initiator.pasn_list); - return 0; -out: - kfree(pasn); - return -EINVAL; -} - -void iwl_mvm_ftm_remove_pasn_sta(struct iwl_mvm *mvm, u8 *addr) -{ - struct iwl_mvm_ftm_pasn_entry *entry, *prev; - - lockdep_assert_held(&mvm->mutex); - - list_for_each_entry_safe(entry, prev, &mvm->ftm_initiator.pasn_list, - list) { - if (memcmp(entry->addr, addr, sizeof(entry->addr))) - continue; - - list_del(&entry->list); - kfree(entry); - return; - } -} - static void iwl_mvm_ftm_reset(struct iwl_mvm *mvm) { struct iwl_mvm_loc_entry *e, *t; @@ -949,7 +848,7 @@ static int iwl_mvm_ftm_start_v13(struct iwl_mvm *mvm, static int iwl_mvm_ftm_put_target_v10(struct iwl_mvm *mvm, struct ieee80211_vif *vif, struct cfg80211_pmsr_request_peer *peer, - struct iwl_tof_range_req_ap_entry_v10 *target) + struct iwl_tof_range_req_ap_entry *target) { u32 i2r_max_sts, flags; int ret; @@ -1021,7 +920,7 @@ static int iwl_mvm_ftm_start_v14(struct iwl_mvm *mvm, struct ieee80211_vif *vif, struct cfg80211_pmsr_request *req) { - struct iwl_tof_range_req_cmd_v14 cmd; + struct iwl_tof_range_req_cmd cmd; struct iwl_host_cmd hcmd = { .id = WIDE_ID(LOCATION_GROUP, TOF_RANGE_REQ_CMD), .dataflags[0] = IWL_HCMD_DFL_DUP, @@ -1035,7 +934,7 @@ static int iwl_mvm_ftm_start_v14(struct iwl_mvm *mvm, for (i = 0; i < cmd.num_of_ap; i++) { struct cfg80211_pmsr_request_peer *peer = &req->peers[i]; - struct iwl_tof_range_req_ap_entry_v10 *target = &cmd.ap[i]; + struct iwl_tof_range_req_ap_entry *target = &cmd.ap[i]; err = iwl_mvm_ftm_put_target_v10(mvm, vif, peer, target); if (err) @@ -1301,7 +1200,7 @@ static void iwl_mvm_debug_range_resp(struct iwl_mvm *mvm, u8 index, static void iwl_mvm_ftm_pasn_update_pn(struct iwl_mvm *mvm, - struct iwl_tof_range_rsp_ap_entry_ntfy_v6 *fw_ap) + struct iwl_tof_range_rsp_ap_entry_ntfy *fw_ap) { struct iwl_mvm_ftm_pasn_entry *entry; @@ -1339,7 +1238,7 @@ static bool iwl_mvm_ftm_resp_size_validation(u8 ver, unsigned int pkt_len) switch (ver) { case 9: case 8: - return pkt_len == sizeof(struct iwl_tof_range_rsp_ntfy_v8); + return pkt_len == sizeof(struct iwl_tof_range_rsp_ntfy); case 7: return pkt_len == sizeof(struct iwl_tof_range_rsp_ntfy_v7); case 6: @@ -1359,7 +1258,7 @@ void iwl_mvm_ftm_range_resp(struct iwl_mvm *mvm, struct iwl_rx_cmd_buffer *rxb) struct iwl_tof_range_rsp_ntfy_v5 *fw_resp_v5 = (void *)pkt->data; struct iwl_tof_range_rsp_ntfy_v6 *fw_resp_v6 = (void *)pkt->data; struct iwl_tof_range_rsp_ntfy_v7 *fw_resp_v7 = (void *)pkt->data; - struct iwl_tof_range_rsp_ntfy_v8 *fw_resp_v8 = (void *)pkt->data; + struct iwl_tof_range_rsp_ntfy *fw_resp_v8 = (void *)pkt->data; int i; bool new_api = fw_has_api(&mvm->fw->ucode_capa, IWL_UCODE_TLV_API_FTM_NEW_RANGE_REQ); @@ -1395,9 +1294,9 @@ void iwl_mvm_ftm_range_resp(struct iwl_mvm *mvm, struct iwl_rx_cmd_buffer *rxb) IWL_DEBUG_INFO(mvm, "request id: %lld, num of entries: %u\n", mvm->ftm_initiator.req->cookie, num_of_aps); - for (i = 0; i < num_of_aps && i < IWL_MVM_TOF_MAX_APS; i++) { + for (i = 0; i < num_of_aps && i < IWL_TOF_MAX_APS; i++) { struct cfg80211_pmsr_result result = {}; - struct iwl_tof_range_rsp_ap_entry_ntfy_v6 *fw_ap; + struct iwl_tof_range_rsp_ap_entry_ntfy *fw_ap; int peer_idx; if (new_api) { diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/ftm-responder.c b/drivers/net/wireless/intel/iwlwifi/mvm/ftm-responder.c index e6e468e81ab3..83f6e508a094 100644 --- a/drivers/net/wireless/intel/iwlwifi/mvm/ftm-responder.c +++ b/drivers/net/wireless/intel/iwlwifi/mvm/ftm-responder.c @@ -324,92 +324,6 @@ static void iwl_mvm_resp_del_pasn_sta(struct iwl_mvm *mvm, kfree(sta); } -int iwl_mvm_ftm_respoder_add_pasn_sta(struct iwl_mvm *mvm, - struct ieee80211_vif *vif, - u8 *addr, u32 cipher, u8 *tk, u32 tk_len, - u8 *hltk, u32 hltk_len) -{ - int ret; - struct iwl_mvm_pasn_sta *sta = NULL; - struct iwl_mvm_pasn_hltk_data hltk_data = { - .addr = addr, - .hltk = hltk, - }; - struct iwl_mvm_pasn_hltk_data *hltk_data_ptr = NULL; - - u8 cmd_ver = iwl_fw_lookup_cmd_ver(mvm->fw, - WIDE_ID(LOCATION_GROUP, TOF_RESPONDER_DYN_CONFIG_CMD), - 2); - - lockdep_assert_held(&mvm->mutex); - - if (cmd_ver < 3) { - IWL_ERR(mvm, "Adding PASN station not supported by FW\n"); - return -EOPNOTSUPP; - } - - if ((!hltk || !hltk_len) && (!tk || !tk_len)) { - IWL_ERR(mvm, "TK and HLTK not set\n"); - return -EINVAL; - } - - if (hltk && hltk_len) { - if (!fw_has_capa(&mvm->fw->ucode_capa, - IWL_UCODE_TLV_CAPA_SECURE_LTF_SUPPORT)) { - IWL_ERR(mvm, "No support for secure LTF measurement\n"); - return -EINVAL; - } - - hltk_data.cipher = iwl_mvm_cipher_to_location_cipher(cipher); - if (hltk_data.cipher == IWL_LOCATION_CIPHER_INVALID) { - IWL_ERR(mvm, "invalid cipher: %u\n", cipher); - return -EINVAL; - } - - hltk_data_ptr = &hltk_data; - } - - if (tk && tk_len) { - sta = kzalloc(sizeof(*sta) + tk_len, GFP_KERNEL); - if (!sta) - return -ENOBUFS; - - ret = iwl_mvm_add_pasn_sta(mvm, vif, &sta->int_sta, addr, - cipher, tk, tk_len, &sta->keyconf); - if (ret) { - kfree(sta); - return ret; - } - - memcpy(sta->addr, addr, ETH_ALEN); - list_add_tail(&sta->list, &mvm->resp_pasn_list); - } - - ret = iwl_mvm_ftm_responder_dyn_cfg_v3(mvm, vif, NULL, hltk_data_ptr); - if (ret && sta) - iwl_mvm_resp_del_pasn_sta(mvm, vif, sta); - - return ret; -} - -int iwl_mvm_ftm_resp_remove_pasn_sta(struct iwl_mvm *mvm, - struct ieee80211_vif *vif, u8 *addr) -{ - struct iwl_mvm_pasn_sta *sta, *prev; - - lockdep_assert_held(&mvm->mutex); - - list_for_each_entry_safe(sta, prev, &mvm->resp_pasn_list, list) { - if (!memcmp(sta->addr, addr, ETH_ALEN)) { - iwl_mvm_resp_del_pasn_sta(mvm, vif, sta); - return 0; - } - } - - IWL_ERR(mvm, "FTM: PASN station %pM not found\n", addr); - return -EINVAL; -} - int iwl_mvm_ftm_start_responder(struct iwl_mvm *mvm, struct ieee80211_vif *vif, struct ieee80211_bss_conf *bss_conf) { diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/fw.c b/drivers/net/wireless/intel/iwlwifi/mvm/fw.c index df49dd2e2026..822244b87df3 100644 --- a/drivers/net/wireless/intel/iwlwifi/mvm/fw.c +++ b/drivers/net/wireless/intel/iwlwifi/mvm/fw.c @@ -1094,22 +1094,6 @@ static int iwl_mvm_ppag_init(struct iwl_mvm *mvm) return iwl_mvm_ppag_send_cmd(mvm); } -static bool -iwl_mvm_add_to_tas_block_list(u16 *list, u8 *size, u16 mcc) -{ - /* Verify that there is room for another country */ - if (*size >= IWL_WTAS_BLACK_LIST_MAX) - return false; - - for (u8 i = 0; i < *size; i++) { - if (list[i] == mcc) - return true; - } - - list[*size++] = mcc; - return true; -} - static void iwl_mvm_tas_init(struct iwl_mvm *mvm) { u32 cmd_id = WIDE_ID(REGULATORY_AND_NVM_GROUP, TAS_CONFIG); @@ -1150,10 +1134,10 @@ static void iwl_mvm_tas_init(struct iwl_mvm *mvm) IWL_DEBUG_RADIO(mvm, "System vendor '%s' is not in the approved list, disabling TAS in US and Canada.\n", dmi_get_system_info(DMI_SYS_VENDOR) ?: "<unknown>"); - if ((!iwl_mvm_add_to_tas_block_list(data.block_list_array, + if ((!iwl_add_mcc_to_tas_block_list(data.block_list_array, &data.block_list_size, IWL_MCC_US)) || - (!iwl_mvm_add_to_tas_block_list(data.block_list_array, + (!iwl_add_mcc_to_tas_block_list(data.block_list_array, &data.block_list_size, IWL_MCC_CANADA))) { IWL_DEBUG_RADIO(mvm, @@ -1213,38 +1197,6 @@ static void iwl_mvm_tas_init(struct iwl_mvm *mvm) IWL_DEBUG_RADIO(mvm, "failed to send TAS_CONFIG (%d)\n", ret); } -static bool iwl_mvm_eval_dsm_rfi(struct iwl_mvm *mvm) -{ - u32 value = 0; - /* default behaviour is disabled */ - bool bios_enable_rfi = false; - int ret = iwl_bios_get_dsm(&mvm->fwrt, DSM_FUNC_RFI_CONFIG, &value); - - - if (ret < 0) { - IWL_DEBUG_RADIO(mvm, "Failed to get DSM RFI, ret=%d\n", ret); - return bios_enable_rfi; - } - - value &= DSM_VALUE_RFI_DISABLE; - /* RFI BIOS CONFIG value can be 0 or 3 only. - * i.e 0 means DDR and DLVR enabled. 3 means DDR and DLVR disabled. - * 1 and 2 are invalid BIOS configurations, So, it's not possible to - * disable ddr/dlvr separately. - */ - if (!value) { - IWL_DEBUG_RADIO(mvm, "DSM RFI is evaluated to enable\n"); - bios_enable_rfi = true; - } else if (value == DSM_VALUE_RFI_DISABLE) { - IWL_DEBUG_RADIO(mvm, "DSM RFI is evaluated to disable\n"); - } else { - IWL_DEBUG_RADIO(mvm, - "DSM RFI got invalid value, value=%d\n", value); - } - - return bios_enable_rfi; -} - static void iwl_mvm_lari_cfg(struct iwl_mvm *mvm) { struct iwl_lari_config_change_cmd cmd; @@ -1631,7 +1583,7 @@ int iwl_mvm_up(struct iwl_mvm *mvm) iwl_mvm_uats_init(mvm); if (iwl_rfi_supported(mvm)) { - if (iwl_mvm_eval_dsm_rfi(mvm)) + if (iwl_rfi_is_enabled_in_bios(&mvm->fwrt)) iwl_rfi_send_config_cmd(mvm, NULL); } diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/mac-ctxt.c b/drivers/net/wireless/intel/iwlwifi/mvm/mac-ctxt.c index 6b06732441c3..bec18d197f31 100644 --- a/drivers/net/wireless/intel/iwlwifi/mvm/mac-ctxt.c +++ b/drivers/net/wireless/intel/iwlwifi/mvm/mac-ctxt.c @@ -1960,26 +1960,3 @@ void iwl_mvm_channel_switch_error_notif(struct iwl_mvm *mvm, ieee80211_channel_switch_disconnect(vif); rcu_read_unlock(); } - -void iwl_mvm_rx_missed_vap_notif(struct iwl_mvm *mvm, - struct iwl_rx_cmd_buffer *rxb) -{ - struct iwl_rx_packet *pkt = rxb_addr(rxb); - struct iwl_missed_vap_notif *mb = (void *)pkt->data; - struct ieee80211_vif *vif; - u32 id = le32_to_cpu(mb->mac_id); - - IWL_DEBUG_INFO(mvm, - "missed_vap notify mac_id=%u, num_beacon_intervals_elapsed=%u, profile_periodicity=%u\n", - le32_to_cpu(mb->mac_id), - mb->num_beacon_intervals_elapsed, - mb->profile_periodicity); - - rcu_read_lock(); - - vif = iwl_mvm_rcu_dereference_vif_id(mvm, id, true); - if (vif) - iwl_mvm_connection_loss(mvm, vif, "missed vap beacon"); - - rcu_read_unlock(); -} diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/mac80211.c b/drivers/net/wireless/intel/iwlwifi/mvm/mac80211.c index af6644b7e95f..20aaef913e3f 100644 --- a/drivers/net/wireless/intel/iwlwifi/mvm/mac80211.c +++ b/drivers/net/wireless/intel/iwlwifi/mvm/mac80211.c @@ -1,6 +1,6 @@ // SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause /* - * Copyright (C) 2012-2014, 2018-2024 Intel Corporation + * Copyright (C) 2012-2014, 2018-2025 Intel Corporation * Copyright (C) 2013-2015 Intel Mobile Communications GmbH * Copyright (C) 2016-2017 Intel Deutschland GmbH */ @@ -70,7 +70,7 @@ static const struct ieee80211_iface_combination iwl_mvm_iface_combinations[] = { }; static const struct cfg80211_pmsr_capabilities iwl_mvm_pmsr_capa = { - .max_peers = IWL_MVM_TOF_MAX_APS, + .max_peers = IWL_TOF_MAX_APS, .report_ap_tsf = 1, .randomize_mac_addr = 1, @@ -272,9 +272,10 @@ static const u8 tm_if_types_ext_capa_sta[] = { __bf_shf(IEEE80211_EML_CAP_EMLSR_PADDING_DELAY) | \ IEEE80211_EML_CAP_EMLSR_TRANSITION_DELAY_64US << \ __bf_shf(IEEE80211_EML_CAP_EMLSR_TRANSITION_DELAY)) -#define IWL_MVM_MLD_CAPA_OPS FIELD_PREP_CONST( \ +#define IWL_MVM_MLD_CAPA_OPS (FIELD_PREP_CONST( \ IEEE80211_MLD_CAP_OP_TID_TO_LINK_MAP_NEG_SUPP, \ - IEEE80211_MLD_CAP_OP_TID_TO_LINK_MAP_NEG_SUPP_SAME) + IEEE80211_MLD_CAP_OP_TID_TO_LINK_MAP_NEG_SUPP_SAME) | \ + IEEE80211_MLD_CAP_OP_LINK_RECONF_SUPPORT) static const struct wiphy_iftype_ext_capab add_iftypes_ext_capa[] = { { diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/mld-sta.c b/drivers/net/wireless/intel/iwlwifi/mvm/mld-sta.c index 2f159024eeb8..9dd670041137 100644 --- a/drivers/net/wireless/intel/iwlwifi/mvm/mld-sta.c +++ b/drivers/net/wireless/intel/iwlwifi/mvm/mld-sta.c @@ -121,7 +121,7 @@ static int iwl_mvm_add_aux_sta_to_fw(struct iwl_mvm *mvm, { int ret; - struct iwl_mvm_aux_sta_cmd cmd = { + struct iwl_aux_sta_cmd cmd = { .sta_id = cpu_to_le32(sta->sta_id), .lmac_id = cpu_to_le32(lmac_id), }; diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/mvm.h b/drivers/net/wireless/intel/iwlwifi/mvm/mvm.h index ee769da72e68..b6e0b63cbd3c 100644 --- a/drivers/net/wireless/intel/iwlwifi/mvm/mvm.h +++ b/drivers/net/wireless/intel/iwlwifi/mvm/mvm.h @@ -1,6 +1,6 @@ /* SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause */ /* - * Copyright (C) 2012-2014, 2018-2024 Intel Corporation + * Copyright (C) 2012-2014, 2018-2025 Intel Corporation * Copyright (C) 2013-2015 Intel Mobile Communications GmbH * Copyright (C) 2016-2017 Intel Deutschland GmbH */ @@ -1310,7 +1310,7 @@ struct iwl_mvm { struct cfg80211_pmsr_request *req; struct wireless_dev *req_wdev; struct list_head loc_list; - int responses[IWL_MVM_TOF_MAX_APS]; + int responses[IWL_TOF_MAX_APS]; struct { struct list_head resp; } smooth; @@ -2095,8 +2095,6 @@ void iwl_mvm_mac_ctxt_recalc_tsf_id(struct iwl_mvm *mvm, struct ieee80211_vif *vif); void iwl_mvm_probe_resp_data_notif(struct iwl_mvm *mvm, struct iwl_rx_cmd_buffer *rxb); -void iwl_mvm_rx_missed_vap_notif(struct iwl_mvm *mvm, - struct iwl_rx_cmd_buffer *rxb); void iwl_mvm_channel_switch_start_notif(struct iwl_mvm *mvm, struct iwl_rx_cmd_buffer *rxb); void iwl_mvm_channel_switch_error_notif(struct iwl_mvm *mvm, @@ -2520,12 +2518,6 @@ void iwl_mvm_ftm_restart_responder(struct iwl_mvm *mvm, struct ieee80211_bss_conf *bss_conf); void iwl_mvm_ftm_responder_stats(struct iwl_mvm *mvm, struct iwl_rx_cmd_buffer *rxb); -int iwl_mvm_ftm_resp_remove_pasn_sta(struct iwl_mvm *mvm, - struct ieee80211_vif *vif, u8 *addr); -int iwl_mvm_ftm_respoder_add_pasn_sta(struct iwl_mvm *mvm, - struct ieee80211_vif *vif, - u8 *addr, u32 cipher, u8 *tk, u32 tk_len, - u8 *hltk, u32 hltk_len); void iwl_mvm_ftm_responder_clear(struct iwl_mvm *mvm, struct ieee80211_vif *vif); @@ -2540,10 +2532,6 @@ int iwl_mvm_ftm_start(struct iwl_mvm *mvm, struct ieee80211_vif *vif, void iwl_mvm_ftm_abort(struct iwl_mvm *mvm, struct cfg80211_pmsr_request *req); void iwl_mvm_ftm_initiator_smooth_config(struct iwl_mvm *mvm); void iwl_mvm_ftm_initiator_smooth_stop(struct iwl_mvm *mvm); -int iwl_mvm_ftm_add_pasn_sta(struct iwl_mvm *mvm, struct ieee80211_vif *vif, - u8 *addr, u32 cipher, u8 *tk, u32 tk_len, - u8 *hltk, u32 hltk_len); -void iwl_mvm_ftm_remove_pasn_sta(struct iwl_mvm *mvm, u8 *addr); /* TDLS */ diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/ops.c b/drivers/net/wireless/intel/iwlwifi/mvm/ops.c index 984f407f7027..76603ef02704 100644 --- a/drivers/net/wireless/intel/iwlwifi/mvm/ops.c +++ b/drivers/net/wireless/intel/iwlwifi/mvm/ops.c @@ -1,6 +1,6 @@ // SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause /* - * Copyright (C) 2012-2014, 2018-2024 Intel Corporation + * Copyright (C) 2012-2014, 2018-2025 Intel Corporation * Copyright (C) 2013-2015 Intel Mobile Communications GmbH * Copyright (C) 2016-2017 Intel Deutschland GmbH */ @@ -145,7 +145,7 @@ static void iwl_mvm_rx_esr_mode_notif(struct iwl_mvm *mvm, struct iwl_rx_cmd_buffer *rxb) { struct iwl_rx_packet *pkt = rxb_addr(rxb); - struct iwl_mvm_esr_mode_notif *notif = (void *)pkt->data; + struct iwl_esr_mode_notif *notif = (void *)pkt->data; struct ieee80211_vif *vif = iwl_mvm_get_bss_vif(mvm); /* FW recommendations is only for entering EMLSR */ @@ -495,7 +495,7 @@ static const struct iwl_rx_handlers iwl_mvm_rx_handlers[] = { RX_HANDLER_GRP(DATA_PATH_GROUP, ESR_MODE_NOTIF, iwl_mvm_rx_esr_mode_notif, RX_HANDLER_ASYNC_LOCKED_WIPHY, - struct iwl_mvm_esr_mode_notif), + struct iwl_esr_mode_notif), RX_HANDLER_GRP(DATA_PATH_GROUP, MONITOR_NOTIF, iwl_mvm_rx_monitor_notif, RX_HANDLER_ASYNC_LOCKED, diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/rs.c b/drivers/net/wireless/intel/iwlwifi/mvm/rs.c index a8c4e354e2ce..068c58e9c1eb 100644 --- a/drivers/net/wireless/intel/iwlwifi/mvm/rs.c +++ b/drivers/net/wireless/intel/iwlwifi/mvm/rs.c @@ -1783,7 +1783,7 @@ static enum rs_action rs_get_rate_action(struct iwl_mvm *mvm, if ((high_tpt != IWL_INVALID_VALUE) && (high_tpt > current_tpt)) { IWL_DEBUG_RATE(mvm, - "Higher rate is better. Increate rate\n"); + "Higher rate is better. Increase rate\n"); return RS_ACTION_UPSCALE; } diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/sta.c b/drivers/net/wireless/intel/iwlwifi/mvm/sta.c index 7a4844ec3c10..78fd7faaed97 100644 --- a/drivers/net/wireless/intel/iwlwifi/mvm/sta.c +++ b/drivers/net/wireless/intel/iwlwifi/mvm/sta.c @@ -4311,67 +4311,6 @@ u16 iwl_mvm_tid_queued(struct iwl_mvm *mvm, struct iwl_mvm_tid_data *tid_data) return ieee80211_sn_sub(sn, tid_data->next_reclaimed); } -int iwl_mvm_add_pasn_sta(struct iwl_mvm *mvm, struct ieee80211_vif *vif, - struct iwl_mvm_int_sta *sta, u8 *addr, u32 cipher, - u8 *key, u32 key_len, - struct ieee80211_key_conf *keyconf) -{ - int ret; - u16 queue; - struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif); - unsigned int wdg_timeout = - iwl_mvm_get_wd_timeout(mvm, vif); - bool mld = iwl_mvm_has_mld_api(mvm->fw); - u32 type = IWL_STA_LINK; - - if (mld) - type = STATION_TYPE_PEER; - - ret = iwl_mvm_allocate_int_sta(mvm, sta, 0, - NL80211_IFTYPE_UNSPECIFIED, type); - if (ret) - return ret; - - if (mld) - ret = iwl_mvm_mld_add_int_sta_with_queue(mvm, sta, addr, - mvmvif->deflink.fw_link_id, - &queue, - IWL_MAX_TID_COUNT, - &wdg_timeout); - else - ret = iwl_mvm_add_int_sta_with_queue(mvm, mvmvif->id, - mvmvif->color, addr, sta, - &queue, - IWL_MVM_TX_FIFO_BE); - if (ret) - goto out; - - keyconf->cipher = cipher; - memcpy(keyconf->key, key, key_len); - keyconf->keylen = key_len; - keyconf->flags = IEEE80211_KEY_FLAG_PAIRWISE; - - if (mld) { - /* The MFP flag is set according to the station mfp field. Since - * we don't have a station, set it manually. - */ - u32 key_flags = - iwl_mvm_get_sec_flags(mvm, vif, NULL, keyconf) | - IWL_SEC_KEY_FLAG_MFP; - u32 sta_mask = BIT(sta->sta_id); - - ret = iwl_mvm_mld_send_key(mvm, sta_mask, key_flags, keyconf); - } else { - ret = iwl_mvm_send_sta_key(mvm, sta->sta_id, keyconf, false, - 0, NULL, 0, 0, true); - } - -out: - if (ret) - iwl_mvm_dealloc_int_sta(mvm, sta); - return ret; -} - void iwl_mvm_cancel_channel_switch(struct iwl_mvm *mvm, struct ieee80211_vif *vif, u32 id) diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/sta.h b/drivers/net/wireless/intel/iwlwifi/mvm/sta.h index 6856f7440ef3..19c905b641e2 100644 --- a/drivers/net/wireless/intel/iwlwifi/mvm/sta.h +++ b/drivers/net/wireless/intel/iwlwifi/mvm/sta.h @@ -597,10 +597,6 @@ void iwl_mvm_modify_all_sta_disable_tx(struct iwl_mvm *mvm, void iwl_mvm_csa_client_absent(struct iwl_mvm *mvm, struct ieee80211_vif *vif); int iwl_mvm_sta_ensure_queue(struct iwl_mvm *mvm, struct ieee80211_txq *txq); void iwl_mvm_add_new_dqa_stream_wk(struct work_struct *wk); -int iwl_mvm_add_pasn_sta(struct iwl_mvm *mvm, struct ieee80211_vif *vif, - struct iwl_mvm_int_sta *sta, u8 *addr, u32 cipher, - u8 *key, u32 key_len, - struct ieee80211_key_conf *key_conf_out); void iwl_mvm_cancel_channel_switch(struct iwl_mvm *mvm, struct ieee80211_vif *vif, u32 id); diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/time-event.c b/drivers/net/wireless/intel/iwlwifi/mvm/time-event.c index 9216c43a35c4..198f94292674 100644 --- a/drivers/net/wireless/intel/iwlwifi/mvm/time-event.c +++ b/drivers/net/wireless/intel/iwlwifi/mvm/time-event.c @@ -1,6 +1,6 @@ // SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause /* - * Copyright (C) 2012-2014, 2018-2024 Intel Corporation + * Copyright (C) 2012-2014, 2018-2025 Intel Corporation * Copyright (C) 2013-2015 Intel Mobile Communications GmbH * Copyright (C) 2017 Intel Deutschland GmbH */ @@ -771,7 +771,7 @@ static void iwl_mvm_cancel_session_protection(struct iwl_mvm *mvm, static void iwl_mvm_roc_rm_cmd(struct iwl_mvm *mvm, u32 activity) { - struct iwl_roc_req roc_cmd = { + struct iwl_roc_req_v5 roc_cmd = { .action = cpu_to_le32(FW_CTXT_ACTION_REMOVE), .activity = cpu_to_le32(activity), }; @@ -1100,7 +1100,7 @@ int iwl_mvm_roc_add_cmd(struct iwl_mvm *mvm, { int res; u32 duration_tu, delay; - struct iwl_roc_req roc_req = { + struct iwl_roc_req_v5 roc_req = { .action = cpu_to_le32(FW_CTXT_ACTION_ADD), .activity = cpu_to_le32(activity), .sta_id = cpu_to_le32(mvm->aux_sta.sta_id), diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/tt.c b/drivers/net/wireless/intel/iwlwifi/mvm/tt.c index d92470960b38..c851290e75a2 100644 --- a/drivers/net/wireless/intel/iwlwifi/mvm/tt.c +++ b/drivers/net/wireless/intel/iwlwifi/mvm/tt.c @@ -105,7 +105,7 @@ static bool iwl_mvm_temp_notif_wait(struct iwl_notif_wait_data *notif_wait, void iwl_mvm_temp_notif(struct iwl_mvm *mvm, struct iwl_rx_cmd_buffer *rxb) { struct iwl_rx_packet *pkt = rxb_addr(rxb); - struct iwl_dts_measurement_notif_v2 *notif_v2; + struct iwl_dts_measurement_notif *notif_v2; int len = iwl_rx_packet_payload_len(pkt); int temp; u32 ths_crossed; @@ -506,7 +506,7 @@ static const u32 iwl_mvm_cdev_budgets[] = { int iwl_mvm_ctdp_command(struct iwl_mvm *mvm, u32 op, u32 state) { - struct iwl_mvm_ctdp_cmd cmd = { + struct iwl_ctdp_cmd cmd = { .operation = cpu_to_le32(op), .budget = cpu_to_le32(iwl_mvm_cdev_budgets[state]), .window_size = 0, diff --git a/drivers/net/wireless/intel/iwlwifi/pcie/ctxt-info-gen3.c b/drivers/net/wireless/intel/iwlwifi/pcie/ctxt-info-gen3.c index 838c426db7f0..8aa7c455bdee 100644 --- a/drivers/net/wireless/intel/iwlwifi/pcie/ctxt-info-gen3.c +++ b/drivers/net/wireless/intel/iwlwifi/pcie/ctxt-info-gen3.c @@ -1,6 +1,6 @@ // SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause /* - * Copyright (C) 2018-2024 Intel Corporation + * Copyright (C) 2018-2025 Intel Corporation */ #include <linux/dmi.h> #include "iwl-trans.h" @@ -137,6 +137,9 @@ int iwl_pcie_ctxt_info_gen3_init(struct iwl_trans *trans, if (trans->dsbr_urm_permanent) control_flags_ext |= IWL_PRPH_SCRATCH_EXT_URM_PERM; + if (trans->ext_32khz_clock_valid) + control_flags_ext |= IWL_PRPH_SCRATCH_EXT_32KHZ_CLK_VALID; + /* Allocate prph scratch */ prph_scratch = dma_alloc_coherent(trans->dev, sizeof(*prph_scratch), &trans_pcie->prph_scratch_dma_addr, diff --git a/drivers/net/wireless/intel/iwlwifi/pcie/drv.c b/drivers/net/wireless/intel/iwlwifi/pcie/drv.c index e0b657b2f74b..cd347cd8176a 100644 --- a/drivers/net/wireless/intel/iwlwifi/pcie/drv.c +++ b/drivers/net/wireless/intel/iwlwifi/pcie/drv.c @@ -1,6 +1,6 @@ // SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause /* - * Copyright (C) 2005-2014, 2018-2024 Intel Corporation + * Copyright (C) 2005-2014, 2018-2025 Intel Corporation * Copyright (C) 2013-2015 Intel Mobile Communications GmbH * Copyright (C) 2016-2017 Intel Deutschland GmbH */ @@ -551,16 +551,17 @@ MODULE_DEVICE_TABLE(pci, iwl_hw_card_ids); EXPORT_SYMBOL_IF_IWLWIFI_KUNIT(iwl_hw_card_ids); #define _IWL_DEV_INFO(_device, _subdevice, _mac_type, _mac_step, _rf_type, \ - _rf_id, _rf_step, _no_160, _cores, _cdb, _cfg, _name) \ + _rf_id, _rf_step, _bw_limit, _cores, _cdb, _cfg, _name) \ { .device = (_device), .subdevice = (_subdevice), .cfg = &(_cfg), \ .name = _name, .mac_type = _mac_type, .rf_type = _rf_type, .rf_step = _rf_step, \ - .no_160 = _no_160, .cores = _cores, .rf_id = _rf_id, \ + .bw_limit = _bw_limit, .cores = _cores, .rf_id = _rf_id, \ .mac_step = _mac_step, .cdb = _cdb, .jacket = IWL_CFG_ANY } #define IWL_DEV_INFO(_device, _subdevice, _cfg, _name) \ _IWL_DEV_INFO(_device, _subdevice, IWL_CFG_ANY, IWL_CFG_ANY, \ - IWL_CFG_ANY, IWL_CFG_ANY, IWL_CFG_ANY, IWL_CFG_ANY, IWL_CFG_ANY, \ - IWL_CFG_ANY, _cfg, _name) + IWL_CFG_ANY, IWL_CFG_ANY, IWL_CFG_ANY, \ + IWL_CFG_BW_NO_LIM, IWL_CFG_ANY, IWL_CFG_ANY, \ + _cfg, _name) VISIBLE_IF_IWLWIFI_KUNIT const struct iwl_dev_info iwl_dev_info_table[] = { #if IS_ENABLED(CONFIG_IWLMVM) @@ -723,66 +724,66 @@ VISIBLE_IF_IWLWIFI_KUNIT const struct iwl_dev_info iwl_dev_info_table[] = { _IWL_DEV_INFO(IWL_CFG_ANY, IWL_CFG_ANY, IWL_CFG_MAC_TYPE_PU, IWL_CFG_ANY, IWL_CFG_RF_TYPE_JF1, IWL_CFG_RF_ID_JF1, IWL_CFG_ANY, - IWL_CFG_160, IWL_CFG_CORES_BT, IWL_CFG_NO_CDB, + IWL_CFG_BW_NO_LIM, IWL_CFG_CORES_BT, IWL_CFG_NO_CDB, iwl9560_2ac_cfg_soc, iwl9461_160_name), _IWL_DEV_INFO(IWL_CFG_ANY, IWL_CFG_ANY, IWL_CFG_MAC_TYPE_PU, IWL_CFG_ANY, IWL_CFG_RF_TYPE_JF1, IWL_CFG_RF_ID_JF1, IWL_CFG_ANY, - IWL_CFG_NO_160, IWL_CFG_CORES_BT, IWL_CFG_NO_CDB, + 80, IWL_CFG_CORES_BT, IWL_CFG_NO_CDB, iwl9560_2ac_cfg_soc, iwl9461_name), _IWL_DEV_INFO(IWL_CFG_ANY, IWL_CFG_ANY, IWL_CFG_MAC_TYPE_PU, IWL_CFG_ANY, IWL_CFG_RF_TYPE_JF1, IWL_CFG_RF_ID_JF1_DIV, IWL_CFG_ANY, - IWL_CFG_160, IWL_CFG_CORES_BT, IWL_CFG_NO_CDB, + IWL_CFG_BW_NO_LIM, IWL_CFG_CORES_BT, IWL_CFG_NO_CDB, iwl9560_2ac_cfg_soc, iwl9462_160_name), _IWL_DEV_INFO(IWL_CFG_ANY, IWL_CFG_ANY, IWL_CFG_MAC_TYPE_PU, IWL_CFG_ANY, IWL_CFG_RF_TYPE_JF1, IWL_CFG_RF_ID_JF1_DIV, IWL_CFG_ANY, - IWL_CFG_NO_160, IWL_CFG_CORES_BT, IWL_CFG_NO_CDB, + 80, IWL_CFG_CORES_BT, IWL_CFG_NO_CDB, iwl9560_2ac_cfg_soc, iwl9462_name), _IWL_DEV_INFO(IWL_CFG_ANY, IWL_CFG_ANY, IWL_CFG_MAC_TYPE_PU, IWL_CFG_ANY, IWL_CFG_RF_TYPE_JF2, IWL_CFG_RF_ID_JF, IWL_CFG_ANY, - IWL_CFG_160, IWL_CFG_CORES_BT, IWL_CFG_NO_CDB, + IWL_CFG_BW_NO_LIM, IWL_CFG_CORES_BT, IWL_CFG_NO_CDB, iwl9560_2ac_cfg_soc, iwl9560_160_name), _IWL_DEV_INFO(IWL_CFG_ANY, IWL_CFG_ANY, IWL_CFG_MAC_TYPE_PU, IWL_CFG_ANY, IWL_CFG_RF_TYPE_JF2, IWL_CFG_RF_ID_JF, IWL_CFG_ANY, - IWL_CFG_NO_160, IWL_CFG_CORES_BT, IWL_CFG_NO_CDB, + 80, IWL_CFG_CORES_BT, IWL_CFG_NO_CDB, iwl9560_2ac_cfg_soc, iwl9560_name), _IWL_DEV_INFO(0x2526, IWL_CFG_ANY, IWL_CFG_MAC_TYPE_TH, IWL_CFG_ANY, IWL_CFG_RF_TYPE_TH, IWL_CFG_ANY, IWL_CFG_ANY, - IWL_CFG_160, IWL_CFG_CORES_BT_GNSS, IWL_CFG_NO_CDB, + IWL_CFG_BW_NO_LIM, IWL_CFG_CORES_BT_GNSS, IWL_CFG_NO_CDB, iwl9260_2ac_cfg, iwl9270_160_name), _IWL_DEV_INFO(0x2526, IWL_CFG_ANY, IWL_CFG_MAC_TYPE_TH, IWL_CFG_ANY, IWL_CFG_RF_TYPE_TH, IWL_CFG_ANY, IWL_CFG_ANY, - IWL_CFG_NO_160, IWL_CFG_CORES_BT_GNSS, IWL_CFG_NO_CDB, + 80, IWL_CFG_CORES_BT_GNSS, IWL_CFG_NO_CDB, iwl9260_2ac_cfg, iwl9270_name), _IWL_DEV_INFO(0x271B, IWL_CFG_ANY, IWL_CFG_MAC_TYPE_TH, IWL_CFG_ANY, IWL_CFG_RF_TYPE_TH1, IWL_CFG_ANY, IWL_CFG_ANY, - IWL_CFG_160, IWL_CFG_CORES_BT, IWL_CFG_NO_CDB, + IWL_CFG_BW_NO_LIM, IWL_CFG_CORES_BT, IWL_CFG_NO_CDB, iwl9260_2ac_cfg, iwl9162_160_name), _IWL_DEV_INFO(0x271B, IWL_CFG_ANY, IWL_CFG_MAC_TYPE_TH, IWL_CFG_ANY, IWL_CFG_RF_TYPE_TH1, IWL_CFG_ANY, IWL_CFG_ANY, - IWL_CFG_NO_160, IWL_CFG_CORES_BT, IWL_CFG_NO_CDB, + 80, IWL_CFG_CORES_BT, IWL_CFG_NO_CDB, iwl9260_2ac_cfg, iwl9162_name), _IWL_DEV_INFO(0x2526, IWL_CFG_ANY, IWL_CFG_MAC_TYPE_TH, IWL_CFG_ANY, IWL_CFG_RF_TYPE_TH, IWL_CFG_ANY, IWL_CFG_ANY, - IWL_CFG_160, IWL_CFG_CORES_BT, IWL_CFG_NO_CDB, + IWL_CFG_BW_NO_LIM, IWL_CFG_CORES_BT, IWL_CFG_NO_CDB, iwl9260_2ac_cfg, iwl9260_160_name), _IWL_DEV_INFO(0x2526, IWL_CFG_ANY, IWL_CFG_MAC_TYPE_TH, IWL_CFG_ANY, IWL_CFG_RF_TYPE_TH, IWL_CFG_ANY, IWL_CFG_ANY, - IWL_CFG_NO_160, IWL_CFG_CORES_BT, IWL_CFG_NO_CDB, + 80, IWL_CFG_CORES_BT, IWL_CFG_NO_CDB, iwl9260_2ac_cfg, iwl9260_name), /* Qu with Jf */ @@ -790,132 +791,132 @@ VISIBLE_IF_IWLWIFI_KUNIT const struct iwl_dev_info iwl_dev_info_table[] = { _IWL_DEV_INFO(IWL_CFG_ANY, IWL_CFG_ANY, IWL_CFG_MAC_TYPE_QU, SILICON_B_STEP, IWL_CFG_RF_TYPE_JF1, IWL_CFG_RF_ID_JF1, IWL_CFG_ANY, - IWL_CFG_160, IWL_CFG_CORES_BT, IWL_CFG_NO_CDB, + IWL_CFG_BW_NO_LIM, IWL_CFG_CORES_BT, IWL_CFG_NO_CDB, iwl9560_qu_b0_jf_b0_cfg, iwl9461_160_name), _IWL_DEV_INFO(IWL_CFG_ANY, IWL_CFG_ANY, IWL_CFG_MAC_TYPE_QU, SILICON_B_STEP, IWL_CFG_RF_TYPE_JF1, IWL_CFG_RF_ID_JF1, IWL_CFG_ANY, - IWL_CFG_NO_160, IWL_CFG_CORES_BT, IWL_CFG_NO_CDB, + 80, IWL_CFG_CORES_BT, IWL_CFG_NO_CDB, iwl9560_qu_b0_jf_b0_cfg, iwl9461_name), _IWL_DEV_INFO(IWL_CFG_ANY, IWL_CFG_ANY, IWL_CFG_MAC_TYPE_QU, SILICON_B_STEP, IWL_CFG_RF_TYPE_JF1, IWL_CFG_RF_ID_JF1_DIV, IWL_CFG_ANY, - IWL_CFG_160, IWL_CFG_CORES_BT, IWL_CFG_NO_CDB, + IWL_CFG_BW_NO_LIM, IWL_CFG_CORES_BT, IWL_CFG_NO_CDB, iwl9560_qu_b0_jf_b0_cfg, iwl9462_160_name), _IWL_DEV_INFO(IWL_CFG_ANY, IWL_CFG_ANY, IWL_CFG_MAC_TYPE_QU, SILICON_B_STEP, IWL_CFG_RF_TYPE_JF1, IWL_CFG_RF_ID_JF1_DIV, IWL_CFG_ANY, - IWL_CFG_NO_160, IWL_CFG_CORES_BT, IWL_CFG_NO_CDB, + 80, IWL_CFG_CORES_BT, IWL_CFG_NO_CDB, iwl9560_qu_b0_jf_b0_cfg, iwl9462_name), _IWL_DEV_INFO(IWL_CFG_ANY, IWL_CFG_ANY, IWL_CFG_MAC_TYPE_QU, SILICON_B_STEP, IWL_CFG_RF_TYPE_JF2, IWL_CFG_RF_ID_JF, IWL_CFG_ANY, - IWL_CFG_160, IWL_CFG_CORES_BT, IWL_CFG_NO_CDB, + IWL_CFG_BW_NO_LIM, IWL_CFG_CORES_BT, IWL_CFG_NO_CDB, iwl9560_qu_b0_jf_b0_cfg, iwl9560_160_name), _IWL_DEV_INFO(IWL_CFG_ANY, IWL_CFG_ANY, IWL_CFG_MAC_TYPE_QU, SILICON_B_STEP, IWL_CFG_RF_TYPE_JF2, IWL_CFG_RF_ID_JF, IWL_CFG_ANY, - IWL_CFG_NO_160, IWL_CFG_CORES_BT, IWL_CFG_NO_CDB, + 80, IWL_CFG_CORES_BT, IWL_CFG_NO_CDB, iwl9560_qu_b0_jf_b0_cfg, iwl9560_name), _IWL_DEV_INFO(IWL_CFG_ANY, 0x1551, IWL_CFG_MAC_TYPE_QU, SILICON_B_STEP, IWL_CFG_RF_TYPE_JF2, IWL_CFG_RF_ID_JF, IWL_CFG_ANY, - IWL_CFG_NO_160, IWL_CFG_CORES_BT, IWL_CFG_NO_CDB, + 80, IWL_CFG_CORES_BT, IWL_CFG_NO_CDB, iwl9560_qu_b0_jf_b0_cfg, iwl9560_killer_1550s_name), _IWL_DEV_INFO(IWL_CFG_ANY, 0x1552, IWL_CFG_MAC_TYPE_QU, SILICON_B_STEP, IWL_CFG_RF_TYPE_JF2, IWL_CFG_RF_ID_JF, IWL_CFG_ANY, - IWL_CFG_NO_160, IWL_CFG_CORES_BT, IWL_CFG_NO_CDB, + 80, IWL_CFG_CORES_BT, IWL_CFG_NO_CDB, iwl9560_qu_b0_jf_b0_cfg, iwl9560_killer_1550i_name), /* Qu C step */ _IWL_DEV_INFO(IWL_CFG_ANY, IWL_CFG_ANY, IWL_CFG_MAC_TYPE_QU, SILICON_C_STEP, IWL_CFG_RF_TYPE_JF1, IWL_CFG_RF_ID_JF1, IWL_CFG_ANY, - IWL_CFG_160, IWL_CFG_CORES_BT, IWL_CFG_NO_CDB, + IWL_CFG_BW_NO_LIM, IWL_CFG_CORES_BT, IWL_CFG_NO_CDB, iwl9560_qu_c0_jf_b0_cfg, iwl9461_160_name), _IWL_DEV_INFO(IWL_CFG_ANY, IWL_CFG_ANY, IWL_CFG_MAC_TYPE_QU, SILICON_C_STEP, IWL_CFG_RF_TYPE_JF1, IWL_CFG_RF_ID_JF1, IWL_CFG_ANY, - IWL_CFG_NO_160, IWL_CFG_CORES_BT, IWL_CFG_NO_CDB, + 80, IWL_CFG_CORES_BT, IWL_CFG_NO_CDB, iwl9560_qu_c0_jf_b0_cfg, iwl9461_name), _IWL_DEV_INFO(IWL_CFG_ANY, IWL_CFG_ANY, IWL_CFG_MAC_TYPE_QU, SILICON_C_STEP, IWL_CFG_RF_TYPE_JF1, IWL_CFG_RF_ID_JF1_DIV, IWL_CFG_ANY, - IWL_CFG_160, IWL_CFG_CORES_BT, IWL_CFG_NO_CDB, + IWL_CFG_BW_NO_LIM, IWL_CFG_CORES_BT, IWL_CFG_NO_CDB, iwl9560_qu_c0_jf_b0_cfg, iwl9462_160_name), _IWL_DEV_INFO(IWL_CFG_ANY, IWL_CFG_ANY, IWL_CFG_MAC_TYPE_QU, SILICON_C_STEP, IWL_CFG_RF_TYPE_JF1, IWL_CFG_RF_ID_JF1_DIV, IWL_CFG_ANY, - IWL_CFG_NO_160, IWL_CFG_CORES_BT, IWL_CFG_NO_CDB, + 80, IWL_CFG_CORES_BT, IWL_CFG_NO_CDB, iwl9560_qu_c0_jf_b0_cfg, iwl9462_name), _IWL_DEV_INFO(IWL_CFG_ANY, IWL_CFG_ANY, IWL_CFG_MAC_TYPE_QU, SILICON_C_STEP, IWL_CFG_RF_TYPE_JF2, IWL_CFG_RF_ID_JF, IWL_CFG_ANY, - IWL_CFG_160, IWL_CFG_CORES_BT, IWL_CFG_NO_CDB, + IWL_CFG_BW_NO_LIM, IWL_CFG_CORES_BT, IWL_CFG_NO_CDB, iwl9560_qu_c0_jf_b0_cfg, iwl9560_160_name), _IWL_DEV_INFO(IWL_CFG_ANY, IWL_CFG_ANY, IWL_CFG_MAC_TYPE_QU, SILICON_C_STEP, IWL_CFG_RF_TYPE_JF2, IWL_CFG_RF_ID_JF, IWL_CFG_ANY, - IWL_CFG_NO_160, IWL_CFG_CORES_BT, IWL_CFG_NO_CDB, + 80, IWL_CFG_CORES_BT, IWL_CFG_NO_CDB, iwl9560_qu_c0_jf_b0_cfg, iwl9560_name), _IWL_DEV_INFO(IWL_CFG_ANY, 0x1551, IWL_CFG_MAC_TYPE_QU, SILICON_C_STEP, IWL_CFG_RF_TYPE_JF2, IWL_CFG_RF_ID_JF, IWL_CFG_ANY, - IWL_CFG_160, IWL_CFG_CORES_BT, IWL_CFG_NO_CDB, + IWL_CFG_BW_NO_LIM, IWL_CFG_CORES_BT, IWL_CFG_NO_CDB, iwl9560_qu_c0_jf_b0_cfg, iwl9560_killer_1550s_name), _IWL_DEV_INFO(IWL_CFG_ANY, 0x1552, IWL_CFG_MAC_TYPE_QU, SILICON_C_STEP, IWL_CFG_RF_TYPE_JF2, IWL_CFG_RF_ID_JF, IWL_CFG_ANY, - IWL_CFG_NO_160, IWL_CFG_CORES_BT, IWL_CFG_NO_CDB, + 80, IWL_CFG_CORES_BT, IWL_CFG_NO_CDB, iwl9560_qu_c0_jf_b0_cfg, iwl9560_killer_1550i_name), /* QuZ */ _IWL_DEV_INFO(IWL_CFG_ANY, IWL_CFG_ANY, IWL_CFG_MAC_TYPE_QUZ, IWL_CFG_ANY, IWL_CFG_RF_TYPE_JF1, IWL_CFG_RF_ID_JF1, IWL_CFG_ANY, - IWL_CFG_160, IWL_CFG_CORES_BT, IWL_CFG_NO_CDB, + IWL_CFG_BW_NO_LIM, IWL_CFG_CORES_BT, IWL_CFG_NO_CDB, iwl9560_quz_a0_jf_b0_cfg, iwl9461_160_name), _IWL_DEV_INFO(IWL_CFG_ANY, IWL_CFG_ANY, IWL_CFG_MAC_TYPE_QUZ, IWL_CFG_ANY, IWL_CFG_RF_TYPE_JF1, IWL_CFG_RF_ID_JF1, IWL_CFG_ANY, - IWL_CFG_NO_160, IWL_CFG_CORES_BT, IWL_CFG_NO_CDB, + 80, IWL_CFG_CORES_BT, IWL_CFG_NO_CDB, iwl9560_quz_a0_jf_b0_cfg, iwl9461_name), _IWL_DEV_INFO(IWL_CFG_ANY, IWL_CFG_ANY, IWL_CFG_MAC_TYPE_QUZ, IWL_CFG_ANY, IWL_CFG_RF_TYPE_JF1, IWL_CFG_RF_ID_JF1_DIV, IWL_CFG_ANY, - IWL_CFG_160, IWL_CFG_CORES_BT, IWL_CFG_NO_CDB, + IWL_CFG_BW_NO_LIM, IWL_CFG_CORES_BT, IWL_CFG_NO_CDB, iwl9560_quz_a0_jf_b0_cfg, iwl9462_160_name), _IWL_DEV_INFO(IWL_CFG_ANY, IWL_CFG_ANY, IWL_CFG_MAC_TYPE_QUZ, IWL_CFG_ANY, IWL_CFG_RF_TYPE_JF1, IWL_CFG_RF_ID_JF1_DIV, IWL_CFG_ANY, - IWL_CFG_NO_160, IWL_CFG_CORES_BT, IWL_CFG_NO_CDB, + 80, IWL_CFG_CORES_BT, IWL_CFG_NO_CDB, iwl9560_quz_a0_jf_b0_cfg, iwl9462_name), _IWL_DEV_INFO(IWL_CFG_ANY, IWL_CFG_ANY, IWL_CFG_MAC_TYPE_QUZ, IWL_CFG_ANY, IWL_CFG_RF_TYPE_JF2, IWL_CFG_RF_ID_JF, IWL_CFG_ANY, - IWL_CFG_160, IWL_CFG_CORES_BT, IWL_CFG_NO_CDB, + IWL_CFG_BW_NO_LIM, IWL_CFG_CORES_BT, IWL_CFG_NO_CDB, iwl9560_quz_a0_jf_b0_cfg, iwl9560_160_name), _IWL_DEV_INFO(IWL_CFG_ANY, IWL_CFG_ANY, IWL_CFG_MAC_TYPE_QUZ, IWL_CFG_ANY, IWL_CFG_RF_TYPE_JF2, IWL_CFG_RF_ID_JF, IWL_CFG_ANY, - IWL_CFG_NO_160, IWL_CFG_CORES_BT, IWL_CFG_NO_CDB, + 80, IWL_CFG_CORES_BT, IWL_CFG_NO_CDB, iwl9560_quz_a0_jf_b0_cfg, iwl9560_name), _IWL_DEV_INFO(IWL_CFG_ANY, 0x1551, IWL_CFG_MAC_TYPE_QUZ, IWL_CFG_ANY, IWL_CFG_RF_TYPE_JF2, IWL_CFG_RF_ID_JF, IWL_CFG_ANY, - IWL_CFG_160, IWL_CFG_CORES_BT, IWL_CFG_NO_CDB, + IWL_CFG_BW_NO_LIM, IWL_CFG_CORES_BT, IWL_CFG_NO_CDB, iwl9560_quz_a0_jf_b0_cfg, iwl9560_killer_1550s_name), _IWL_DEV_INFO(IWL_CFG_ANY, 0x1552, IWL_CFG_MAC_TYPE_QUZ, IWL_CFG_ANY, IWL_CFG_RF_TYPE_JF2, IWL_CFG_RF_ID_JF, IWL_CFG_ANY, - IWL_CFG_NO_160, IWL_CFG_CORES_BT, IWL_CFG_NO_CDB, + 80, IWL_CFG_CORES_BT, IWL_CFG_NO_CDB, iwl9560_quz_a0_jf_b0_cfg, iwl9560_killer_1550i_name), /* Qu with Hr */ @@ -923,202 +924,202 @@ VISIBLE_IF_IWLWIFI_KUNIT const struct iwl_dev_info iwl_dev_info_table[] = { _IWL_DEV_INFO(IWL_CFG_ANY, IWL_CFG_ANY, IWL_CFG_MAC_TYPE_QU, SILICON_B_STEP, IWL_CFG_RF_TYPE_HR1, IWL_CFG_ANY, IWL_CFG_ANY, - IWL_CFG_ANY, IWL_CFG_ANY, IWL_CFG_NO_CDB, + IWL_CFG_BW_ANY, IWL_CFG_ANY, IWL_CFG_NO_CDB, iwl_qu_b0_hr1_b0, iwl_ax101_name), _IWL_DEV_INFO(IWL_CFG_ANY, IWL_CFG_ANY, IWL_CFG_MAC_TYPE_QU, SILICON_B_STEP, IWL_CFG_RF_TYPE_HR2, IWL_CFG_ANY, IWL_CFG_ANY, - IWL_CFG_NO_160, IWL_CFG_ANY, IWL_CFG_NO_CDB, + 80, IWL_CFG_ANY, IWL_CFG_NO_CDB, iwl_qu_b0_hr_b0, iwl_ax203_name), /* Qu C step */ _IWL_DEV_INFO(IWL_CFG_ANY, IWL_CFG_ANY, IWL_CFG_MAC_TYPE_QU, SILICON_C_STEP, IWL_CFG_RF_TYPE_HR1, IWL_CFG_ANY, IWL_CFG_ANY, - IWL_CFG_ANY, IWL_CFG_ANY, IWL_CFG_NO_CDB, + IWL_CFG_BW_ANY, IWL_CFG_ANY, IWL_CFG_NO_CDB, iwl_qu_c0_hr1_b0, iwl_ax101_name), _IWL_DEV_INFO(IWL_CFG_ANY, IWL_CFG_ANY, IWL_CFG_MAC_TYPE_QU, SILICON_C_STEP, IWL_CFG_RF_TYPE_HR2, IWL_CFG_ANY, IWL_CFG_ANY, - IWL_CFG_NO_160, IWL_CFG_ANY, IWL_CFG_NO_CDB, + 80, IWL_CFG_ANY, IWL_CFG_NO_CDB, iwl_qu_c0_hr_b0, iwl_ax203_name), _IWL_DEV_INFO(IWL_CFG_ANY, IWL_CFG_ANY, IWL_CFG_MAC_TYPE_QU, SILICON_C_STEP, IWL_CFG_RF_TYPE_HR2, IWL_CFG_ANY, IWL_CFG_ANY, - IWL_CFG_160, IWL_CFG_ANY, IWL_CFG_NO_CDB, + IWL_CFG_BW_NO_LIM, IWL_CFG_ANY, IWL_CFG_NO_CDB, iwl_qu_c0_hr_b0, iwl_ax201_name), /* QuZ */ _IWL_DEV_INFO(IWL_CFG_ANY, IWL_CFG_ANY, IWL_CFG_MAC_TYPE_QUZ, IWL_CFG_ANY, IWL_CFG_RF_TYPE_HR1, IWL_CFG_ANY, IWL_CFG_ANY, - IWL_CFG_ANY, IWL_CFG_ANY, IWL_CFG_NO_CDB, + IWL_CFG_BW_ANY, IWL_CFG_ANY, IWL_CFG_NO_CDB, iwl_quz_a0_hr1_b0, iwl_ax101_name), _IWL_DEV_INFO(IWL_CFG_ANY, IWL_CFG_ANY, IWL_CFG_MAC_TYPE_QUZ, SILICON_B_STEP, IWL_CFG_RF_TYPE_HR2, IWL_CFG_ANY, IWL_CFG_ANY, - IWL_CFG_NO_160, IWL_CFG_ANY, IWL_CFG_NO_CDB, + 80, IWL_CFG_ANY, IWL_CFG_NO_CDB, iwl_cfg_quz_a0_hr_b0, iwl_ax203_name), _IWL_DEV_INFO(IWL_CFG_ANY, IWL_CFG_ANY, IWL_CFG_MAC_TYPE_QUZ, SILICON_B_STEP, IWL_CFG_RF_TYPE_HR2, IWL_CFG_ANY, IWL_CFG_ANY, - IWL_CFG_160, IWL_CFG_ANY, IWL_CFG_NO_CDB, + IWL_CFG_BW_NO_LIM, IWL_CFG_ANY, IWL_CFG_NO_CDB, iwl_cfg_quz_a0_hr_b0, iwl_ax201_name), /* Ma */ _IWL_DEV_INFO(IWL_CFG_ANY, IWL_CFG_ANY, IWL_CFG_MAC_TYPE_MA, IWL_CFG_ANY, IWL_CFG_RF_TYPE_HR2, IWL_CFG_ANY, IWL_CFG_ANY, - IWL_CFG_ANY, IWL_CFG_ANY, IWL_CFG_NO_CDB, + IWL_CFG_BW_ANY, IWL_CFG_ANY, IWL_CFG_NO_CDB, iwl_cfg_ma, iwl_ax201_name), _IWL_DEV_INFO(IWL_CFG_ANY, IWL_CFG_ANY, IWL_CFG_MAC_TYPE_MA, IWL_CFG_ANY, IWL_CFG_RF_TYPE_GF, IWL_CFG_ANY, IWL_CFG_ANY, - IWL_CFG_ANY, IWL_CFG_ANY, IWL_CFG_ANY, + IWL_CFG_BW_ANY, IWL_CFG_ANY, IWL_CFG_ANY, iwl_cfg_ma, iwl_ax211_name), _IWL_DEV_INFO(IWL_CFG_ANY, IWL_CFG_ANY, IWL_CFG_MAC_TYPE_MA, IWL_CFG_ANY, IWL_CFG_RF_TYPE_FM, IWL_CFG_ANY, IWL_CFG_ANY, - IWL_CFG_ANY, IWL_CFG_ANY, IWL_CFG_NO_CDB, + IWL_CFG_BW_ANY, IWL_CFG_ANY, IWL_CFG_NO_CDB, iwl_cfg_ma, iwl_ax231_name), /* So with Hr */ _IWL_DEV_INFO(IWL_CFG_ANY, IWL_CFG_ANY, IWL_CFG_MAC_TYPE_SO, IWL_CFG_ANY, IWL_CFG_RF_TYPE_HR2, IWL_CFG_ANY, IWL_CFG_ANY, - IWL_CFG_NO_160, IWL_CFG_ANY, IWL_CFG_NO_CDB, + 80, IWL_CFG_ANY, IWL_CFG_NO_CDB, iwl_cfg_so_a0_hr_a0, iwl_ax203_name), _IWL_DEV_INFO(IWL_CFG_ANY, IWL_CFG_ANY, IWL_CFG_MAC_TYPE_SO, IWL_CFG_ANY, IWL_CFG_RF_TYPE_HR1, IWL_CFG_ANY, IWL_CFG_ANY, - IWL_CFG_NO_160, IWL_CFG_ANY, IWL_CFG_NO_CDB, + 80, IWL_CFG_ANY, IWL_CFG_NO_CDB, iwl_cfg_so_a0_hr_a0, iwl_ax101_name), _IWL_DEV_INFO(IWL_CFG_ANY, IWL_CFG_ANY, IWL_CFG_MAC_TYPE_SO, IWL_CFG_ANY, IWL_CFG_RF_TYPE_HR2, IWL_CFG_ANY, IWL_CFG_ANY, - IWL_CFG_160, IWL_CFG_ANY, IWL_CFG_NO_CDB, + IWL_CFG_BW_NO_LIM, IWL_CFG_ANY, IWL_CFG_NO_CDB, iwl_cfg_so_a0_hr_a0, iwl_ax201_name), /* So-F with Hr */ _IWL_DEV_INFO(IWL_CFG_ANY, IWL_CFG_ANY, IWL_CFG_MAC_TYPE_SOF, IWL_CFG_ANY, IWL_CFG_RF_TYPE_HR2, IWL_CFG_ANY, IWL_CFG_ANY, - IWL_CFG_NO_160, IWL_CFG_ANY, IWL_CFG_NO_CDB, + 80, IWL_CFG_ANY, IWL_CFG_NO_CDB, iwl_cfg_so_a0_hr_a0, iwl_ax203_name), _IWL_DEV_INFO(IWL_CFG_ANY, IWL_CFG_ANY, IWL_CFG_MAC_TYPE_SOF, IWL_CFG_ANY, IWL_CFG_RF_TYPE_HR1, IWL_CFG_ANY, IWL_CFG_ANY, - IWL_CFG_NO_160, IWL_CFG_ANY, IWL_CFG_NO_CDB, + 80, IWL_CFG_ANY, IWL_CFG_NO_CDB, iwl_cfg_so_a0_hr_a0, iwl_ax101_name), _IWL_DEV_INFO(IWL_CFG_ANY, IWL_CFG_ANY, IWL_CFG_MAC_TYPE_SOF, IWL_CFG_ANY, IWL_CFG_RF_TYPE_HR2, IWL_CFG_ANY, IWL_CFG_ANY, - IWL_CFG_160, IWL_CFG_ANY, IWL_CFG_NO_CDB, + IWL_CFG_BW_NO_LIM, IWL_CFG_ANY, IWL_CFG_NO_CDB, iwl_cfg_so_a0_hr_a0, iwl_ax201_name), /* So-F with Gf */ _IWL_DEV_INFO(IWL_CFG_ANY, IWL_CFG_ANY, IWL_CFG_MAC_TYPE_SOF, IWL_CFG_ANY, IWL_CFG_RF_TYPE_GF, IWL_CFG_ANY, IWL_CFG_ANY, - IWL_CFG_160, IWL_CFG_ANY, IWL_CFG_NO_CDB, + IWL_CFG_BW_NO_LIM, IWL_CFG_ANY, IWL_CFG_NO_CDB, iwlax211_2ax_cfg_so_gf_a0, iwl_ax211_name), _IWL_DEV_INFO(IWL_CFG_ANY, IWL_CFG_ANY, IWL_CFG_MAC_TYPE_SOF, IWL_CFG_ANY, IWL_CFG_RF_TYPE_GF, IWL_CFG_ANY, IWL_CFG_ANY, - IWL_CFG_160, IWL_CFG_ANY, IWL_CFG_CDB, + IWL_CFG_BW_NO_LIM, IWL_CFG_ANY, IWL_CFG_CDB, iwlax411_2ax_cfg_so_gf4_a0, iwl_ax411_name), /* SoF with JF2 */ _IWL_DEV_INFO(IWL_CFG_ANY, IWL_CFG_ANY, IWL_CFG_MAC_TYPE_SOF, IWL_CFG_ANY, IWL_CFG_RF_TYPE_JF2, IWL_CFG_RF_ID_JF, IWL_CFG_ANY, - IWL_CFG_160, IWL_CFG_CORES_BT, IWL_CFG_NO_CDB, + IWL_CFG_BW_NO_LIM, IWL_CFG_CORES_BT, IWL_CFG_NO_CDB, iwlax210_2ax_cfg_so_jf_b0, iwl9560_160_name), _IWL_DEV_INFO(IWL_CFG_ANY, IWL_CFG_ANY, IWL_CFG_MAC_TYPE_SOF, IWL_CFG_ANY, IWL_CFG_RF_TYPE_JF2, IWL_CFG_RF_ID_JF, IWL_CFG_ANY, - IWL_CFG_NO_160, IWL_CFG_CORES_BT, IWL_CFG_NO_CDB, + 80, IWL_CFG_CORES_BT, IWL_CFG_NO_CDB, iwlax210_2ax_cfg_so_jf_b0, iwl9560_name), /* SoF with JF */ _IWL_DEV_INFO(IWL_CFG_ANY, IWL_CFG_ANY, IWL_CFG_MAC_TYPE_SOF, IWL_CFG_ANY, IWL_CFG_RF_TYPE_JF1, IWL_CFG_RF_ID_JF1, IWL_CFG_ANY, - IWL_CFG_160, IWL_CFG_CORES_BT, IWL_CFG_NO_CDB, + IWL_CFG_BW_NO_LIM, IWL_CFG_CORES_BT, IWL_CFG_NO_CDB, iwlax210_2ax_cfg_so_jf_b0, iwl9461_160_name), _IWL_DEV_INFO(IWL_CFG_ANY, IWL_CFG_ANY, IWL_CFG_MAC_TYPE_SOF, IWL_CFG_ANY, IWL_CFG_RF_TYPE_JF1, IWL_CFG_RF_ID_JF1_DIV, IWL_CFG_ANY, - IWL_CFG_160, IWL_CFG_CORES_BT, IWL_CFG_NO_CDB, + IWL_CFG_BW_NO_LIM, IWL_CFG_CORES_BT, IWL_CFG_NO_CDB, iwlax210_2ax_cfg_so_jf_b0, iwl9462_160_name), _IWL_DEV_INFO(IWL_CFG_ANY, IWL_CFG_ANY, IWL_CFG_MAC_TYPE_SOF, IWL_CFG_ANY, IWL_CFG_RF_TYPE_JF1, IWL_CFG_RF_ID_JF1, IWL_CFG_ANY, - IWL_CFG_NO_160, IWL_CFG_CORES_BT, IWL_CFG_NO_CDB, + 80, IWL_CFG_CORES_BT, IWL_CFG_NO_CDB, iwlax210_2ax_cfg_so_jf_b0, iwl9461_name), _IWL_DEV_INFO(IWL_CFG_ANY, IWL_CFG_ANY, IWL_CFG_MAC_TYPE_SOF, IWL_CFG_ANY, IWL_CFG_RF_TYPE_JF1, IWL_CFG_RF_ID_JF1_DIV, IWL_CFG_ANY, - IWL_CFG_NO_160, IWL_CFG_CORES_BT, IWL_CFG_NO_CDB, + 80, IWL_CFG_CORES_BT, IWL_CFG_NO_CDB, iwlax210_2ax_cfg_so_jf_b0, iwl9462_name), /* So with GF */ _IWL_DEV_INFO(IWL_CFG_ANY, IWL_CFG_ANY, IWL_CFG_MAC_TYPE_SO, IWL_CFG_ANY, IWL_CFG_RF_TYPE_GF, IWL_CFG_ANY, IWL_CFG_ANY, - IWL_CFG_160, IWL_CFG_ANY, IWL_CFG_NO_CDB, + IWL_CFG_BW_NO_LIM, IWL_CFG_ANY, IWL_CFG_NO_CDB, iwlax211_2ax_cfg_so_gf_a0, iwl_ax211_name), _IWL_DEV_INFO(IWL_CFG_ANY, IWL_CFG_ANY, IWL_CFG_MAC_TYPE_SO, IWL_CFG_ANY, IWL_CFG_RF_TYPE_GF, IWL_CFG_ANY, IWL_CFG_ANY, - IWL_CFG_160, IWL_CFG_ANY, IWL_CFG_CDB, + IWL_CFG_BW_NO_LIM, IWL_CFG_ANY, IWL_CFG_CDB, iwlax411_2ax_cfg_so_gf4_a0, iwl_ax411_name), /* So with JF2 */ _IWL_DEV_INFO(IWL_CFG_ANY, IWL_CFG_ANY, IWL_CFG_MAC_TYPE_SO, IWL_CFG_ANY, IWL_CFG_RF_TYPE_JF2, IWL_CFG_RF_ID_JF, IWL_CFG_ANY, - IWL_CFG_160, IWL_CFG_CORES_BT, IWL_CFG_NO_CDB, + IWL_CFG_BW_NO_LIM, IWL_CFG_CORES_BT, IWL_CFG_NO_CDB, iwlax210_2ax_cfg_so_jf_b0, iwl9560_160_name), _IWL_DEV_INFO(IWL_CFG_ANY, IWL_CFG_ANY, IWL_CFG_MAC_TYPE_SO, IWL_CFG_ANY, IWL_CFG_RF_TYPE_JF2, IWL_CFG_RF_ID_JF, IWL_CFG_ANY, - IWL_CFG_NO_160, IWL_CFG_CORES_BT, IWL_CFG_NO_CDB, + 80, IWL_CFG_CORES_BT, IWL_CFG_NO_CDB, iwlax210_2ax_cfg_so_jf_b0, iwl9560_name), /* So with JF */ _IWL_DEV_INFO(IWL_CFG_ANY, IWL_CFG_ANY, IWL_CFG_MAC_TYPE_SO, IWL_CFG_ANY, IWL_CFG_RF_TYPE_JF1, IWL_CFG_RF_ID_JF1, IWL_CFG_ANY, - IWL_CFG_160, IWL_CFG_CORES_BT, IWL_CFG_NO_CDB, + IWL_CFG_BW_NO_LIM, IWL_CFG_CORES_BT, IWL_CFG_NO_CDB, iwlax210_2ax_cfg_so_jf_b0, iwl9461_160_name), _IWL_DEV_INFO(IWL_CFG_ANY, IWL_CFG_ANY, IWL_CFG_MAC_TYPE_SO, IWL_CFG_ANY, IWL_CFG_RF_TYPE_JF1, IWL_CFG_RF_ID_JF1_DIV, IWL_CFG_ANY, - IWL_CFG_160, IWL_CFG_CORES_BT, IWL_CFG_NO_CDB, + IWL_CFG_BW_NO_LIM, IWL_CFG_CORES_BT, IWL_CFG_NO_CDB, iwlax210_2ax_cfg_so_jf_b0, iwl9462_160_name), _IWL_DEV_INFO(IWL_CFG_ANY, IWL_CFG_ANY, IWL_CFG_MAC_TYPE_SO, IWL_CFG_ANY, IWL_CFG_RF_TYPE_JF1, IWL_CFG_RF_ID_JF1, IWL_CFG_ANY, - IWL_CFG_NO_160, IWL_CFG_CORES_BT, IWL_CFG_NO_CDB, + 80, IWL_CFG_CORES_BT, IWL_CFG_NO_CDB, iwlax210_2ax_cfg_so_jf_b0, iwl9461_name), _IWL_DEV_INFO(IWL_CFG_ANY, IWL_CFG_ANY, IWL_CFG_MAC_TYPE_SO, IWL_CFG_ANY, IWL_CFG_RF_TYPE_JF1, IWL_CFG_RF_ID_JF1_DIV, IWL_CFG_ANY, - IWL_CFG_NO_160, IWL_CFG_CORES_BT, IWL_CFG_NO_CDB, + 80, IWL_CFG_CORES_BT, IWL_CFG_NO_CDB, iwlax210_2ax_cfg_so_jf_b0, iwl9462_name), /* Bz */ _IWL_DEV_INFO(IWL_CFG_ANY, IWL_CFG_ANY, IWL_CFG_MAC_TYPE_BZ, IWL_CFG_ANY, IWL_CFG_RF_TYPE_HR2, IWL_CFG_ANY, IWL_CFG_ANY, - IWL_CFG_ANY, IWL_CFG_ANY, IWL_CFG_ANY, + IWL_CFG_BW_ANY, IWL_CFG_ANY, IWL_CFG_ANY, iwl_cfg_bz, iwl_ax201_name), _IWL_DEV_INFO(IWL_CFG_ANY, IWL_CFG_ANY, IWL_CFG_MAC_TYPE_BZ, IWL_CFG_ANY, IWL_CFG_RF_TYPE_GF, IWL_CFG_ANY, IWL_CFG_ANY, - IWL_CFG_ANY, IWL_CFG_ANY, IWL_CFG_ANY, + IWL_CFG_BW_ANY, IWL_CFG_ANY, IWL_CFG_ANY, iwl_cfg_bz, iwl_ax211_name), _IWL_DEV_INFO(IWL_CFG_ANY, IWL_CFG_ANY, @@ -1130,73 +1131,104 @@ VISIBLE_IF_IWLWIFI_KUNIT const struct iwl_dev_info iwl_dev_info_table[] = { _IWL_DEV_INFO(IWL_CFG_ANY, IWL_CFG_ANY, IWL_CFG_MAC_TYPE_BZ, IWL_CFG_ANY, IWL_CFG_RF_TYPE_WH, IWL_CFG_ANY, IWL_CFG_ANY, - IWL_CFG_ANY, IWL_CFG_ANY, IWL_CFG_ANY, + IWL_CFG_BW_ANY, IWL_CFG_ANY, IWL_CFG_ANY, iwl_cfg_bz, iwl_wh_name), _IWL_DEV_INFO(IWL_CFG_ANY, IWL_CFG_ANY, IWL_CFG_MAC_TYPE_BZ_W, IWL_CFG_ANY, IWL_CFG_RF_TYPE_HR2, IWL_CFG_ANY, IWL_CFG_ANY, - IWL_CFG_ANY, IWL_CFG_ANY, IWL_CFG_ANY, + IWL_CFG_BW_ANY, IWL_CFG_ANY, IWL_CFG_ANY, iwl_cfg_bz, iwl_ax201_name), _IWL_DEV_INFO(IWL_CFG_ANY, IWL_CFG_ANY, IWL_CFG_MAC_TYPE_BZ_W, IWL_CFG_ANY, IWL_CFG_RF_TYPE_GF, IWL_CFG_ANY, IWL_CFG_ANY, - IWL_CFG_ANY, IWL_CFG_ANY, IWL_CFG_ANY, + IWL_CFG_BW_ANY, IWL_CFG_ANY, IWL_CFG_ANY, iwl_cfg_bz, iwl_ax211_name), _IWL_DEV_INFO(IWL_CFG_ANY, IWL_CFG_ANY, IWL_CFG_MAC_TYPE_BZ_W, IWL_CFG_ANY, IWL_CFG_RF_TYPE_FM, IWL_CFG_ANY, IWL_CFG_ANY, - IWL_CFG_ANY, IWL_CFG_ANY, IWL_CFG_ANY, + IWL_CFG_BW_ANY, IWL_CFG_ANY, IWL_CFG_ANY, iwl_cfg_bz, iwl_fm_name), _IWL_DEV_INFO(IWL_CFG_ANY, IWL_CFG_ANY, IWL_CFG_MAC_TYPE_BZ_W, IWL_CFG_ANY, IWL_CFG_RF_TYPE_WH, IWL_CFG_ANY, IWL_CFG_ANY, - IWL_CFG_ANY, IWL_CFG_ANY, IWL_CFG_ANY, + IWL_CFG_BW_ANY, IWL_CFG_ANY, IWL_CFG_ANY, iwl_cfg_bz, iwl_wh_name), /* Ga (Gl) */ _IWL_DEV_INFO(IWL_CFG_ANY, IWL_CFG_ANY, IWL_CFG_MAC_TYPE_GL, IWL_CFG_ANY, IWL_CFG_RF_TYPE_FM, IWL_CFG_ANY, IWL_CFG_ANY, - IWL_CFG_320, IWL_CFG_ANY, IWL_CFG_NO_CDB, + IWL_CFG_BW_NO_LIM, IWL_CFG_ANY, IWL_CFG_NO_CDB, iwl_cfg_gl, iwl_gl_name), _IWL_DEV_INFO(IWL_CFG_ANY, IWL_CFG_ANY, IWL_CFG_MAC_TYPE_GL, IWL_CFG_ANY, IWL_CFG_RF_TYPE_FM, IWL_CFG_ANY, IWL_CFG_ANY, - IWL_CFG_NO_320, IWL_CFG_ANY, IWL_CFG_NO_CDB, + 160, IWL_CFG_ANY, IWL_CFG_NO_CDB, iwl_cfg_gl, iwl_mtp_name), /* Sc */ _IWL_DEV_INFO(IWL_CFG_ANY, IWL_CFG_ANY, IWL_CFG_MAC_TYPE_SC, IWL_CFG_ANY, - IWL_CFG_ANY, IWL_CFG_ANY, IWL_CFG_ANY, - IWL_CFG_ANY, IWL_CFG_ANY, IWL_CFG_ANY, - iwl_cfg_sc, iwl_sc_name), + IWL_CFG_RF_TYPE_GF, IWL_CFG_ANY, IWL_CFG_ANY, + IWL_CFG_BW_ANY, IWL_CFG_ANY, IWL_CFG_ANY, + iwl_cfg_sc, iwl_ax211_name), + _IWL_DEV_INFO(IWL_CFG_ANY, IWL_CFG_ANY, + IWL_CFG_MAC_TYPE_SC, IWL_CFG_ANY, + IWL_CFG_RF_TYPE_FM, IWL_CFG_ANY, IWL_CFG_ANY, + IWL_CFG_BW_ANY, IWL_CFG_ANY, IWL_CFG_ANY, + iwl_cfg_sc, iwl_fm_name), + _IWL_DEV_INFO(IWL_CFG_ANY, IWL_CFG_ANY, + IWL_CFG_MAC_TYPE_SC, IWL_CFG_ANY, + IWL_CFG_RF_TYPE_WH, IWL_CFG_ANY, IWL_CFG_ANY, + IWL_CFG_BW_ANY, IWL_CFG_ANY, IWL_CFG_ANY, + iwl_cfg_sc, iwl_wh_name), _IWL_DEV_INFO(IWL_CFG_ANY, IWL_CFG_ANY, IWL_CFG_MAC_TYPE_SC2, IWL_CFG_ANY, - IWL_CFG_ANY, IWL_CFG_ANY, IWL_CFG_ANY, - IWL_CFG_ANY, IWL_CFG_ANY, IWL_CFG_ANY, - iwl_cfg_sc2, iwl_sc2_name), + IWL_CFG_RF_TYPE_GF, IWL_CFG_ANY, IWL_CFG_ANY, + IWL_CFG_BW_ANY, IWL_CFG_ANY, IWL_CFG_ANY, + iwl_cfg_sc2, iwl_ax211_name), + _IWL_DEV_INFO(IWL_CFG_ANY, IWL_CFG_ANY, + IWL_CFG_MAC_TYPE_SC2, IWL_CFG_ANY, + IWL_CFG_RF_TYPE_FM, IWL_CFG_ANY, IWL_CFG_ANY, + IWL_CFG_BW_ANY, IWL_CFG_ANY, IWL_CFG_ANY, + iwl_cfg_sc2, iwl_fm_name), + _IWL_DEV_INFO(IWL_CFG_ANY, IWL_CFG_ANY, + IWL_CFG_MAC_TYPE_SC2, IWL_CFG_ANY, + IWL_CFG_RF_TYPE_WH, IWL_CFG_ANY, IWL_CFG_ANY, + IWL_CFG_BW_ANY, IWL_CFG_ANY, IWL_CFG_ANY, + iwl_cfg_sc2, iwl_wh_name), _IWL_DEV_INFO(IWL_CFG_ANY, IWL_CFG_ANY, IWL_CFG_MAC_TYPE_SC2F, IWL_CFG_ANY, - IWL_CFG_ANY, IWL_CFG_ANY, IWL_CFG_ANY, - IWL_CFG_ANY, IWL_CFG_ANY, IWL_CFG_ANY, - iwl_cfg_sc2f, iwl_sc2f_name), + IWL_CFG_RF_TYPE_GF, IWL_CFG_ANY, IWL_CFG_ANY, + IWL_CFG_BW_ANY, IWL_CFG_ANY, IWL_CFG_ANY, + iwl_cfg_sc2f, iwl_ax211_name), + _IWL_DEV_INFO(IWL_CFG_ANY, IWL_CFG_ANY, + IWL_CFG_MAC_TYPE_SC2F, IWL_CFG_ANY, + IWL_CFG_RF_TYPE_FM, IWL_CFG_ANY, IWL_CFG_ANY, + IWL_CFG_BW_ANY, IWL_CFG_ANY, IWL_CFG_ANY, + iwl_cfg_sc2f, iwl_fm_name), + _IWL_DEV_INFO(IWL_CFG_ANY, IWL_CFG_ANY, + IWL_CFG_MAC_TYPE_SC2F, IWL_CFG_ANY, + IWL_CFG_RF_TYPE_WH, IWL_CFG_ANY, IWL_CFG_ANY, + IWL_CFG_BW_ANY, IWL_CFG_ANY, IWL_CFG_ANY, + iwl_cfg_sc2f, iwl_wh_name), + /* Dr */ _IWL_DEV_INFO(IWL_CFG_ANY, IWL_CFG_ANY, IWL_CFG_MAC_TYPE_DR, IWL_CFG_ANY, IWL_CFG_ANY, IWL_CFG_ANY, IWL_CFG_ANY, - IWL_CFG_ANY, IWL_CFG_ANY, IWL_CFG_ANY, + IWL_CFG_BW_ANY, IWL_CFG_ANY, IWL_CFG_ANY, iwl_cfg_dr, iwl_dr_name), /* Br */ _IWL_DEV_INFO(IWL_CFG_ANY, IWL_CFG_ANY, IWL_CFG_MAC_TYPE_BR, IWL_CFG_ANY, IWL_CFG_ANY, IWL_CFG_ANY, IWL_CFG_ANY, - IWL_CFG_ANY, IWL_CFG_ANY, IWL_CFG_ANY, + IWL_CFG_BW_ANY, IWL_CFG_ANY, IWL_CFG_ANY, iwl_cfg_br, iwl_br_name), #endif /* CONFIG_IWLMVM */ }; @@ -1348,7 +1380,7 @@ out: VISIBLE_IF_IWLWIFI_KUNIT const struct iwl_dev_info * iwl_pci_find_dev_info(u16 device, u16 subsystem_device, u16 mac_type, u8 mac_step, u16 rf_type, u8 cdb, - u8 jacket, u8 rf_id, u8 no_160, u8 cores, u8 rf_step) + u8 jacket, u8 rf_id, u8 bw_limit, u8 cores, u8 rf_step) { int num_devices = ARRAY_SIZE(iwl_dev_info_table); int i; @@ -1391,8 +1423,15 @@ iwl_pci_find_dev_info(u16 device, u16 subsystem_device, dev_info->rf_id != rf_id) continue; - if (dev_info->no_160 != (u8)IWL_CFG_ANY && - dev_info->no_160 != no_160) + /* + * Check that bw_limit have the same "boolean" value since + * IWL_SUBDEVICE_BW_LIM can only return a boolean value and + * dev_info->bw_limit encodes a non-boolean value. + * dev_info->bw_limit == IWL_CFG_BW_NO_LIM must be equal to + * !bw_limit to have a match. + */ + if (dev_info->bw_limit != IWL_CFG_BW_ANY && + (dev_info->bw_limit == IWL_CFG_BW_NO_LIM) == !!bw_limit) continue; if (dev_info->cores != (u8)IWL_CFG_ANY && @@ -1530,13 +1569,13 @@ static int iwl_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent) CSR_HW_RFID_IS_CDB(iwl_trans->hw_rf_id), CSR_HW_RFID_IS_JACKET(iwl_trans->hw_rf_id), IWL_SUBDEVICE_RF_ID(pdev->subsystem_device), - IWL_SUBDEVICE_NO_160(pdev->subsystem_device), + IWL_SUBDEVICE_BW_LIM(pdev->subsystem_device), IWL_SUBDEVICE_CORES(pdev->subsystem_device), CSR_HW_RFID_STEP(iwl_trans->hw_rf_id)); if (dev_info) { iwl_trans->cfg = dev_info->cfg; iwl_trans->name = dev_info->name; - iwl_trans->no_160 = dev_info->no_160 == IWL_CFG_NO_160; + iwl_trans->bw_limit = dev_info->bw_limit; } #if IS_ENABLED(CONFIG_IWLMVM) diff --git a/drivers/net/wireless/intel/iwlwifi/pcie/trans-gen2.c b/drivers/net/wireless/intel/iwlwifi/pcie/trans-gen2.c index 793514a1852a..3ece34e30d58 100644 --- a/drivers/net/wireless/intel/iwlwifi/pcie/trans-gen2.c +++ b/drivers/net/wireless/intel/iwlwifi/pcie/trans-gen2.c @@ -1,7 +1,7 @@ // SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause /* * Copyright (C) 2017 Intel Deutschland GmbH - * Copyright (C) 2018-2024 Intel Corporation + * Copyright (C) 2018-2025 Intel Corporation */ #include "iwl-trans.h" #include "iwl-prph.h" @@ -95,7 +95,7 @@ static void iwl_pcie_gen2_apm_stop(struct iwl_trans *trans, bool op_mode_leave) CSR_GP_CNTRL_REG_FLAG_INIT_DONE); } -static void iwl_trans_pcie_fw_reset_handshake(struct iwl_trans *trans) +void iwl_trans_pcie_fw_reset_handshake(struct iwl_trans *trans) { struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans); int ret; diff --git a/drivers/net/wireless/intel/iwlwifi/tests/devinfo.c b/drivers/net/wireless/intel/iwlwifi/tests/devinfo.c index d0bda23c628a..7ef5e89c6af2 100644 --- a/drivers/net/wireless/intel/iwlwifi/tests/devinfo.c +++ b/drivers/net/wireless/intel/iwlwifi/tests/devinfo.c @@ -2,7 +2,7 @@ /* * KUnit tests for the iwlwifi device info table * - * Copyright (C) 2023-2024 Intel Corporation + * Copyright (C) 2023-2025 Intel Corporation */ #include <kunit/test.h> #include <linux/pci.h> @@ -13,9 +13,9 @@ MODULE_IMPORT_NS("EXPORTED_FOR_KUNIT_TESTING"); static void iwl_pci_print_dev_info(const char *pfx, const struct iwl_dev_info *di) { - printk(KERN_DEBUG "%sdev=%.4x,subdev=%.4x,mac_type=%.4x,mac_step=%.4x,rf_type=%.4x,cdb=%d,jacket=%d,rf_id=%.2x,no_160=%d,cores=%.2x\n", + printk(KERN_DEBUG "%sdev=%.4x,subdev=%.4x,mac_type=%.4x,mac_step=%.4x,rf_type=%.4x,cdb=%d,jacket=%d,rf_id=%.2x,bw_limit=%d,cores=%.2x\n", pfx, di->device, di->subdevice, di->mac_type, di->mac_step, - di->rf_type, di->cdb, di->jacket, di->rf_id, di->no_160, + di->rf_type, di->cdb, di->jacket, di->rf_id, di->bw_limit, di->cores); } @@ -31,8 +31,13 @@ static void devinfo_table_order(struct kunit *test) di->mac_type, di->mac_step, di->rf_type, di->cdb, di->jacket, di->rf_id, - di->no_160, di->cores, di->rf_step); - if (ret != di) { + di->bw_limit != IWL_CFG_BW_NO_LIM, + di->cores, di->rf_step); + if (!ret) { + iwl_pci_print_dev_info("No entry found for: ", di); + KUNIT_FAIL(test, + "No entry found for entry at index %d\n", idx); + } else if (ret != di) { iwl_pci_print_dev_info("searched: ", di); iwl_pci_print_dev_info("found: ", ret); KUNIT_FAIL(test, diff --git a/drivers/net/wireless/marvell/libertas/cmd.c b/drivers/net/wireless/marvell/libertas/cmd.c index 5a525da434c2..21fde876bb0d 100644 --- a/drivers/net/wireless/marvell/libertas/cmd.c +++ b/drivers/net/wireless/marvell/libertas/cmd.c @@ -453,46 +453,6 @@ out: } /** - * lbs_get_snmp_mib - Get an SNMP MIB value - * - * @priv: A pointer to &struct lbs_private structure - * @oid: The OID to retrieve from the firmware - * @out_val: Location for the returned value - * - * returns: 0 on success, error on failure - */ -int lbs_get_snmp_mib(struct lbs_private *priv, u32 oid, u16 *out_val) -{ - struct cmd_ds_802_11_snmp_mib cmd; - int ret; - - memset(&cmd, 0, sizeof (cmd)); - cmd.hdr.size = cpu_to_le16(sizeof(cmd)); - cmd.action = cpu_to_le16(CMD_ACT_GET); - cmd.oid = cpu_to_le16(oid); - - ret = lbs_cmd_with_response(priv, CMD_802_11_SNMP_MIB, &cmd); - if (ret) - goto out; - - switch (le16_to_cpu(cmd.bufsize)) { - case sizeof(u8): - *out_val = cmd.value[0]; - break; - case sizeof(u16): - *out_val = le16_to_cpu(*((__le16 *)(&cmd.value))); - break; - default: - lbs_deb_cmd("SNMP_CMD: (get) unhandled OID 0x%x size %d\n", - oid, le16_to_cpu(cmd.bufsize)); - break; - } - -out: - return ret; -} - -/** * lbs_get_tx_power - Get the min, max, and current TX power * * @priv: A pointer to &struct lbs_private structure @@ -525,31 +485,6 @@ int lbs_get_tx_power(struct lbs_private *priv, s16 *curlevel, s16 *minlevel, } /** - * lbs_set_tx_power - Set the TX power - * - * @priv: A pointer to &struct lbs_private structure - * @dbm: The desired power level in dBm - * - * returns: 0 on success, error on failure - */ -int lbs_set_tx_power(struct lbs_private *priv, s16 dbm) -{ - struct cmd_ds_802_11_rf_tx_power cmd; - int ret; - - memset(&cmd, 0, sizeof(cmd)); - cmd.hdr.size = cpu_to_le16(sizeof(cmd)); - cmd.action = cpu_to_le16(CMD_ACT_SET); - cmd.curlevel = cpu_to_le16(dbm); - - lbs_deb_cmd("SET_RF_TX_POWER: %d dBm\n", dbm); - - ret = lbs_cmd_with_response(priv, CMD_802_11_RF_TX_POWER, &cmd); - - return ret; -} - -/** * lbs_set_monitor_mode - Enable or disable monitor mode * (only implemented on OLPC usb8388 FW) * @@ -968,10 +903,6 @@ static void lbs_submit_command(struct lbs_private *priv, } if (command == CMD_802_11_DEEP_SLEEP) { - if (priv->is_auto_deep_sleep_enabled) { - priv->wakeup_dev_required = 1; - priv->dnld_sent = 0; - } priv->is_deep_sleep = 1; lbs_complete_command(priv, cmdnode, 0); } else { @@ -1440,70 +1371,6 @@ void lbs_ps_confirm_sleep(struct lbs_private *priv) } -/** - * lbs_set_tpc_cfg - Configures the transmission power control functionality - * - * @priv: A pointer to &struct lbs_private structure - * @enable: Transmission power control enable - * @p0: Power level when link quality is good (dBm). - * @p1: Power level when link quality is fair (dBm). - * @p2: Power level when link quality is poor (dBm). - * @usesnr: Use Signal to Noise Ratio in TPC - * - * returns: 0 on success - */ -int lbs_set_tpc_cfg(struct lbs_private *priv, int enable, int8_t p0, int8_t p1, - int8_t p2, int usesnr) -{ - struct cmd_ds_802_11_tpc_cfg cmd; - int ret; - - memset(&cmd, 0, sizeof(cmd)); - cmd.hdr.size = cpu_to_le16(sizeof(cmd)); - cmd.action = cpu_to_le16(CMD_ACT_SET); - cmd.enable = !!enable; - cmd.usesnr = !!usesnr; - cmd.P0 = p0; - cmd.P1 = p1; - cmd.P2 = p2; - - ret = lbs_cmd_with_response(priv, CMD_802_11_TPC_CFG, &cmd); - - return ret; -} - -/** - * lbs_set_power_adapt_cfg - Configures the power adaptation settings - * - * @priv: A pointer to &struct lbs_private structure - * @enable: Power adaptation enable - * @p0: Power level for 1, 2, 5.5 and 11 Mbps (dBm). - * @p1: Power level for 6, 9, 12, 18, 22, 24 and 36 Mbps (dBm). - * @p2: Power level for 48 and 54 Mbps (dBm). - * - * returns: 0 on Success - */ - -int lbs_set_power_adapt_cfg(struct lbs_private *priv, int enable, int8_t p0, - int8_t p1, int8_t p2) -{ - struct cmd_ds_802_11_pa_cfg cmd; - int ret; - - memset(&cmd, 0, sizeof(cmd)); - cmd.hdr.size = cpu_to_le16(sizeof(cmd)); - cmd.action = cpu_to_le16(CMD_ACT_SET); - cmd.enable = !!enable; - cmd.P0 = p0; - cmd.P1 = p1; - cmd.P2 = p2; - - ret = lbs_cmd_with_response(priv, CMD_802_11_PA_CFG , &cmd); - - return ret; -} - - struct cmd_ctrl_node *__lbs_cmd_async(struct lbs_private *priv, uint16_t command, struct cmd_header *in_cmd, int in_cmd_size, int (*callback)(struct lbs_private *, unsigned long, struct cmd_header *), @@ -1520,12 +1387,10 @@ struct cmd_ctrl_node *__lbs_cmd_async(struct lbs_private *priv, /* No commands are allowed in Deep Sleep until we toggle the GPIO * to wake up the card and it has signaled that it's ready. */ - if (!priv->is_auto_deep_sleep_enabled) { - if (priv->is_deep_sleep) { - lbs_deb_cmd("command not allowed in deep sleep\n"); - cmdnode = ERR_PTR(-EBUSY); - goto done; - } + if (priv->is_deep_sleep) { + lbs_deb_cmd("command not allowed in deep sleep\n"); + cmdnode = ERR_PTR(-EBUSY); + goto done; } cmdnode = lbs_get_free_cmd_node(priv); diff --git a/drivers/net/wireless/marvell/libertas/cmd.h b/drivers/net/wireless/marvell/libertas/cmd.h index d7be232f5739..a95c2651e67f 100644 --- a/drivers/net/wireless/marvell/libertas/cmd.h +++ b/drivers/net/wireless/marvell/libertas/cmd.h @@ -105,19 +105,9 @@ int lbs_get_tx_power(struct lbs_private *priv, s16 *curlevel, s16 *minlevel, int lbs_set_snmp_mib(struct lbs_private *priv, u32 oid, u16 val); -int lbs_get_snmp_mib(struct lbs_private *priv, u32 oid, u16 *out_val); - /* Commands only used in wext.c, assoc. and scan.c */ -int lbs_set_power_adapt_cfg(struct lbs_private *priv, int enable, int8_t p0, - int8_t p1, int8_t p2); - -int lbs_set_tpc_cfg(struct lbs_private *priv, int enable, int8_t p0, int8_t p1, - int8_t p2, int usesnr); - -int lbs_set_tx_power(struct lbs_private *priv, s16 dbm); - int lbs_set_deep_sleep(struct lbs_private *priv, int deep_sleep); int lbs_set_host_sleep(struct lbs_private *priv, int host_sleep); diff --git a/drivers/net/wireless/marvell/libertas/cmdresp.c b/drivers/net/wireless/marvell/libertas/cmdresp.c index f2aa659e7714..8393f396eebe 100644 --- a/drivers/net/wireless/marvell/libertas/cmdresp.c +++ b/drivers/net/wireless/marvell/libertas/cmdresp.c @@ -279,7 +279,6 @@ void lbs_process_event(struct lbs_private *priv, u32 event) priv->reset_deep_sleep_wakeup(priv); lbs_deb_cmd("EVENT: ds awake\n"); priv->is_deep_sleep = 0; - priv->wakeup_dev_required = 0; wake_up_interruptible(&priv->ds_awake_q); break; diff --git a/drivers/net/wireless/marvell/libertas/decl.h b/drivers/net/wireless/marvell/libertas/decl.h index c1e0388ef01d..ea69007a2958 100644 --- a/drivers/net/wireless/marvell/libertas/decl.h +++ b/drivers/net/wireless/marvell/libertas/decl.h @@ -64,11 +64,7 @@ int lbs_resume(struct lbs_private *priv); void lbs_queue_event(struct lbs_private *priv, u32 event); void lbs_notify_command_response(struct lbs_private *priv, u8 resp_idx); -int lbs_enter_auto_deep_sleep(struct lbs_private *priv); -int lbs_exit_auto_deep_sleep(struct lbs_private *priv); - u32 lbs_fw_index_to_data_rate(u8 index); -u8 lbs_data_rate_to_fw_index(u32 rate); int lbs_get_firmware(struct device *dev, u32 card_model, const struct lbs_fw_table *fw_table, diff --git a/drivers/net/wireless/marvell/libertas/dev.h b/drivers/net/wireless/marvell/libertas/dev.h index 4b6e05a8e5d5..c4708ce4eb83 100644 --- a/drivers/net/wireless/marvell/libertas/dev.h +++ b/drivers/net/wireless/marvell/libertas/dev.h @@ -83,12 +83,8 @@ struct lbs_private { /* Deep sleep */ int is_deep_sleep; int deep_sleep_required; - int is_auto_deep_sleep_enabled; - int wakeup_dev_required; int is_activity_detected; - int auto_deep_sleep_timeout; /* in ms */ wait_queue_head_t ds_awake_q; - struct timer_list auto_deepsleep_timer; /* Host sleep*/ int is_host_sleep_configured; diff --git a/drivers/net/wireless/marvell/libertas/main.c b/drivers/net/wireless/marvell/libertas/main.c index 78e8b5aecec0..017e5c6bbade 100644 --- a/drivers/net/wireless/marvell/libertas/main.c +++ b/drivers/net/wireless/marvell/libertas/main.c @@ -79,26 +79,6 @@ u32 lbs_fw_index_to_data_rate(u8 idx) return fw_data_rates[idx]; } -/** - * lbs_data_rate_to_fw_index - use rate to get the index - * - * @rate: data rate - * returns: index or 0 - */ -u8 lbs_data_rate_to_fw_index(u32 rate) -{ - u8 i; - - if (!rate) - return 0; - - for (i = 0; i < sizeof(fw_data_rates); i++) { - if (rate == fw_data_rates[i]) - return i; - } - return 0; -} - int lbs_set_iface_type(struct lbs_private *priv, enum nl80211_iftype type) { int ret = 0; @@ -276,8 +256,7 @@ void lbs_host_to_card_done(struct lbs_private *priv) /* Wake main thread if commands are pending */ if (!priv->cur_cmd || priv->tx_pending_len > 0) { - if (!priv->wakeup_dev_required) - wake_up(&priv->waitq); + wake_up(&priv->waitq); } spin_unlock_irqrestore(&priv->driver_lock, flags); @@ -468,8 +447,7 @@ static int lbs_thread(void *data) shouldsleep = 0; /* We have a command response */ else if (priv->cur_cmd) shouldsleep = 1; /* Can't send a command; one already running */ - else if (!list_empty(&priv->cmdpendingq) && - !(priv->wakeup_dev_required)) + else if (!list_empty(&priv->cmdpendingq)) shouldsleep = 0; /* We have a command to send */ else if (kfifo_len(&priv->event_fifo)) shouldsleep = 0; /* We have an event to process */ @@ -536,14 +514,6 @@ static int lbs_thread(void *data) } spin_unlock_irq(&priv->driver_lock); - if (priv->wakeup_dev_required) { - lbs_deb_thread("Waking up device...\n"); - /* Wake up device */ - if (priv->exit_deep_sleep(priv)) - lbs_deb_thread("Wakeup device failed\n"); - continue; - } - /* command timeout stuff */ if (priv->cmd_timed_out && priv->cur_cmd) { struct cmd_ctrl_node *cmdnode = priv->cur_cmd; @@ -626,7 +596,6 @@ static int lbs_thread(void *data) del_timer(&priv->command_timer); del_timer(&priv->tx_lockup_timer); - del_timer(&priv->auto_deepsleep_timer); return 0; } @@ -773,55 +742,6 @@ static void lbs_tx_lockup_handler(struct timer_list *t) spin_unlock_irqrestore(&priv->driver_lock, flags); } -/** - * auto_deepsleep_timer_fn - put the device back to deep sleep mode when - * timer expires and no activity (command, event, data etc.) is detected. - * @t: Context from which to retrieve a &struct lbs_private pointer - * returns: N/A - */ -static void auto_deepsleep_timer_fn(struct timer_list *t) -{ - struct lbs_private *priv = from_timer(priv, t, auto_deepsleep_timer); - - if (priv->is_activity_detected) { - priv->is_activity_detected = 0; - } else { - if (priv->is_auto_deep_sleep_enabled && - (!priv->wakeup_dev_required) && - (priv->connect_status != LBS_CONNECTED)) { - struct cmd_header cmd; - - lbs_deb_main("Entering auto deep sleep mode...\n"); - memset(&cmd, 0, sizeof(cmd)); - cmd.size = cpu_to_le16(sizeof(cmd)); - lbs_cmd_async(priv, CMD_802_11_DEEP_SLEEP, &cmd, - sizeof(cmd)); - } - } - mod_timer(&priv->auto_deepsleep_timer , jiffies + - (priv->auto_deep_sleep_timeout * HZ)/1000); -} - -int lbs_enter_auto_deep_sleep(struct lbs_private *priv) -{ - priv->is_auto_deep_sleep_enabled = 1; - if (priv->is_deep_sleep) - priv->wakeup_dev_required = 1; - mod_timer(&priv->auto_deepsleep_timer , - jiffies + (priv->auto_deep_sleep_timeout * HZ)/1000); - - return 0; -} - -int lbs_exit_auto_deep_sleep(struct lbs_private *priv) -{ - priv->is_auto_deep_sleep_enabled = 0; - priv->auto_deep_sleep_timeout = 0; - del_timer(&priv->auto_deepsleep_timer); - - return 0; -} - static int lbs_init_adapter(struct lbs_private *priv) { int ret; @@ -835,9 +755,7 @@ static int lbs_init_adapter(struct lbs_private *priv) priv->psmode = LBS802_11POWERMODECAM; priv->psstate = PS_STATE_FULL_POWER; priv->is_deep_sleep = 0; - priv->is_auto_deep_sleep_enabled = 0; priv->deep_sleep_required = 0; - priv->wakeup_dev_required = 0; init_waitqueue_head(&priv->ds_awake_q); init_waitqueue_head(&priv->scan_q); priv->authtype_auto = 1; @@ -849,7 +767,6 @@ static int lbs_init_adapter(struct lbs_private *priv) timer_setup(&priv->command_timer, lbs_cmd_timeout_handler, 0); timer_setup(&priv->tx_lockup_timer, lbs_tx_lockup_handler, 0); - timer_setup(&priv->auto_deepsleep_timer, auto_deepsleep_timer_fn, 0); INIT_LIST_HEAD(&priv->cmdfreeq); INIT_LIST_HEAD(&priv->cmdpendingq); @@ -883,7 +800,6 @@ static void lbs_free_adapter(struct lbs_private *priv) kfifo_free(&priv->event_fifo); del_timer(&priv->command_timer); del_timer(&priv->tx_lockup_timer); - del_timer(&priv->auto_deepsleep_timer); } static const struct net_device_ops lbs_netdev_ops = { diff --git a/drivers/net/wireless/marvell/mwifiex/main.c b/drivers/net/wireless/marvell/mwifiex/main.c index 855019fe5485..45eecb5f643b 100644 --- a/drivers/net/wireless/marvell/mwifiex/main.c +++ b/drivers/net/wireless/marvell/mwifiex/main.c @@ -54,7 +54,7 @@ const u16 mwifiex_1d_to_wmm_queue[8] = { 1, 0, 0, 1, 2, 2, 3, 3 }; * proper cleanup before exiting. */ static int mwifiex_register(void *card, struct device *dev, - struct mwifiex_if_ops *if_ops, void **padapter) + const struct mwifiex_if_ops *if_ops, void **padapter) { struct mwifiex_adapter *adapter; int i; @@ -1713,7 +1713,7 @@ err_exit: */ int mwifiex_add_card(void *card, struct completion *fw_done, - struct mwifiex_if_ops *if_ops, u8 iface_type, + const struct mwifiex_if_ops *if_ops, u8 iface_type, struct device *dev) { struct mwifiex_adapter *adapter; diff --git a/drivers/net/wireless/marvell/mwifiex/main.h b/drivers/net/wireless/marvell/mwifiex/main.h index 0674dcf7a537..63f1c900e096 100644 --- a/drivers/net/wireless/marvell/mwifiex/main.h +++ b/drivers/net/wireless/marvell/mwifiex/main.h @@ -1470,7 +1470,7 @@ int mwifiex_init_shutdown_fw(struct mwifiex_private *priv, u32 func_init_shutdown); int mwifiex_add_card(void *card, struct completion *fw_done, - struct mwifiex_if_ops *if_ops, u8 iface_type, + const struct mwifiex_if_ops *if_ops, u8 iface_type, struct device *dev); int mwifiex_remove_card(struct mwifiex_adapter *adapter); @@ -1571,8 +1571,6 @@ void mwifiex_uap_set_channel(struct mwifiex_private *priv, struct cfg80211_chan_def chandef); int mwifiex_config_start_uap(struct mwifiex_private *priv, struct mwifiex_uap_bss_param *bss_cfg); -void mwifiex_uap_del_sta_data(struct mwifiex_private *priv, - struct mwifiex_sta_node *node); void mwifiex_config_uap_11d(struct mwifiex_private *priv, struct cfg80211_beacon_data *beacon_data); diff --git a/drivers/net/wireless/marvell/mwifiex/pcie.c b/drivers/net/wireless/marvell/mwifiex/pcie.c index 5f997becdbaa..e11458fd4d50 100644 --- a/drivers/net/wireless/marvell/mwifiex/pcie.c +++ b/drivers/net/wireless/marvell/mwifiex/pcie.c @@ -21,7 +21,7 @@ #define PCIE_VERSION "1.0" #define DRV_NAME "Marvell mwifiex PCIe" -static struct mwifiex_if_ops pcie_ops; +static const struct mwifiex_if_ops pcie_ops; static const struct mwifiex_pcie_card_reg mwifiex_reg_8766 = { .cmd_addr_lo = PCIE_SCRATCH_0_REG, @@ -3240,7 +3240,7 @@ static void mwifiex_pcie_down_dev(struct mwifiex_adapter *adapter) mwifiex_pcie_free_buffers(adapter); } -static struct mwifiex_if_ops pcie_ops = { +static const struct mwifiex_if_ops pcie_ops = { .init_if = mwifiex_init_pcie, .cleanup_if = mwifiex_cleanup_pcie, .check_fw_status = mwifiex_check_fw_status, diff --git a/drivers/net/wireless/marvell/mwifiex/sdio.c b/drivers/net/wireless/marvell/mwifiex/sdio.c index 490ffd981164..c1fe48448839 100644 --- a/drivers/net/wireless/marvell/mwifiex/sdio.c +++ b/drivers/net/wireless/marvell/mwifiex/sdio.c @@ -21,7 +21,7 @@ static void mwifiex_sdio_work(struct work_struct *work); -static struct mwifiex_if_ops sdio_ops; +static const struct mwifiex_if_ops sdio_ops; static const struct mwifiex_sdio_card_reg mwifiex_reg_sd87xx = { .start_rd_port = 1, @@ -3167,7 +3167,7 @@ static void mwifiex_sdio_up_dev(struct mwifiex_adapter *adapter) dev_err(&card->func->dev, "error enabling SDIO port\n"); } -static struct mwifiex_if_ops sdio_ops = { +static const struct mwifiex_if_ops sdio_ops = { .init_if = mwifiex_init_sdio, .cleanup_if = mwifiex_cleanup_sdio, .check_fw_status = mwifiex_check_fw_status, diff --git a/drivers/net/wireless/marvell/mwifiex/uap_event.c b/drivers/net/wireless/marvell/mwifiex/uap_event.c index 58ef5020a46a..245cb99a3daa 100644 --- a/drivers/net/wireless/marvell/mwifiex/uap_event.c +++ b/drivers/net/wireless/marvell/mwifiex/uap_event.c @@ -325,19 +325,3 @@ int mwifiex_process_uap_event(struct mwifiex_private *priv) return 0; } - -/* This function deletes station entry from associated station list. - * Also if both AP and STA are 11n enabled, RxReorder tables and TxBA stream - * tables created for this station are deleted. - */ -void mwifiex_uap_del_sta_data(struct mwifiex_private *priv, - struct mwifiex_sta_node *node) -{ - if (priv->ap_11n_enabled && node->is_11n_enabled) { - mwifiex_11n_del_rx_reorder_tbl_by_ta(priv, node->mac_addr); - mwifiex_del_tx_ba_stream_tbl_by_ra(priv, node->mac_addr); - } - mwifiex_del_sta_entry(priv, node->mac_addr); - - return; -} diff --git a/drivers/net/wireless/marvell/mwifiex/usb.c b/drivers/net/wireless/marvell/mwifiex/usb.c index 6085cd50970d..3034c4405cb5 100644 --- a/drivers/net/wireless/marvell/mwifiex/usb.c +++ b/drivers/net/wireless/marvell/mwifiex/usb.c @@ -10,7 +10,7 @@ #define USB_VERSION "1.0" -static struct mwifiex_if_ops usb_ops; +static const struct mwifiex_if_ops usb_ops; static const struct usb_device_id mwifiex_usb_table[] = { /* 8766 */ @@ -1585,7 +1585,7 @@ mwifiex_pm_wakeup_card_complete(struct mwifiex_adapter *adapter) return 0; } -static struct mwifiex_if_ops usb_ops = { +static const struct mwifiex_if_ops usb_ops = { .register_dev = mwifiex_register_dev, .unregister_dev = mwifiex_unregister_dev, .wakeup = mwifiex_pm_wakeup_card, diff --git a/drivers/net/wireless/quantenna/qtnfmac/qlink.h b/drivers/net/wireless/quantenna/qtnfmac/qlink.h index 674461fa7fb3..eae35b678952 100644 --- a/drivers/net/wireless/quantenna/qtnfmac/qlink.h +++ b/drivers/net/wireless/quantenna/qtnfmac/qlink.h @@ -1510,10 +1510,15 @@ enum qlink_tlv_id { }; struct qlink_tlv_hdr { - __le16 type; - __le16 len; + /* New members MUST be added within the struct_group() macro below. */ + __struct_group(qlink_tlv_hdr_fixed, __hdr, __packed, + __le16 type; + __le16 len; + ); u8 val[]; } __packed; +static_assert(offsetof(struct qlink_tlv_hdr, val) == sizeof(struct qlink_tlv_hdr_fixed), + "struct member likely outside of __struct_group()"); struct qlink_iface_limit { __le16 max_num; @@ -1567,7 +1572,7 @@ enum qlink_reg_rule_flags { * @dfs_cac_ms: DFS CAC period. */ struct qlink_tlv_reg_rule { - struct qlink_tlv_hdr hdr; + struct qlink_tlv_hdr_fixed hdr; __le32 start_freq_khz; __le32 end_freq_khz; __le32 max_bandwidth_khz; @@ -1606,7 +1611,7 @@ enum qlink_dfs_state { * @channel: ieee80211 channel settings. */ struct qlink_tlv_channel { - struct qlink_tlv_hdr hdr; + struct qlink_tlv_hdr_fixed hdr; struct qlink_channel chan; } __packed; @@ -1618,7 +1623,7 @@ struct qlink_tlv_channel { * @chan: channel definition data. */ struct qlink_tlv_chandef { - struct qlink_tlv_hdr hdr; + struct qlink_tlv_hdr_fixed hdr; struct qlink_chandef chdef; } __packed; @@ -1643,7 +1648,7 @@ enum qlink_ie_set_type { * @ie_data: IEs data. */ struct qlink_tlv_ie_set { - struct qlink_tlv_hdr hdr; + struct qlink_tlv_hdr_fixed hdr; u8 type; u8 flags; u8 rsvd[2]; @@ -1657,7 +1662,7 @@ struct qlink_tlv_ie_set { * @ie_data: IEs data. */ struct qlink_tlv_ext_ie { - struct qlink_tlv_hdr hdr; + struct qlink_tlv_hdr_fixed hdr; u8 eid_ext; u8 rsvd[3]; u8 ie_data[]; @@ -1678,7 +1683,7 @@ struct qlink_sband_iftype_data { * @iftype_data: interface type data entries. */ struct qlink_tlv_iftype_data { - struct qlink_tlv_hdr hdr; + struct qlink_tlv_hdr_fixed hdr; u8 n_iftype_data; u8 rsvd[3]; struct qlink_sband_iftype_data iftype_data[]; diff --git a/drivers/net/wireless/realtek/rtl8xxxu/8192c.c b/drivers/net/wireless/realtek/rtl8xxxu/8192c.c index 0abb1b092bc2..73034e7e41d1 100644 --- a/drivers/net/wireless/realtek/rtl8xxxu/8192c.c +++ b/drivers/net/wireless/realtek/rtl8xxxu/8192c.c @@ -644,6 +644,8 @@ struct rtl8xxxu_fileops rtl8192cu_fops = { .rx_agg_buf_size = 16000, .tx_desc_size = sizeof(struct rtl8xxxu_txdesc32), .rx_desc_size = sizeof(struct rtl8xxxu_rxdesc16), + .supports_ap = 1, + .max_macid_num = 32, .max_sec_cam_num = 32, .adda_1t_init = 0x0b1b25a0, .adda_1t_path_on = 0x0bdb25a0, diff --git a/drivers/net/wireless/realtek/rtl8xxxu/core.c b/drivers/net/wireless/realtek/rtl8xxxu/core.c index 4ce0c05c5129..569856ca677f 100644 --- a/drivers/net/wireless/realtek/rtl8xxxu/core.c +++ b/drivers/net/wireless/realtek/rtl8xxxu/core.c @@ -860,9 +860,10 @@ rtl8xxxu_writeN(struct rtl8xxxu_priv *priv, u16 addr, u8 *buf, u16 len) return len; write_error: - dev_info(&udev->dev, - "%s: Failed to write block at addr: %04x size: %04x\n", - __func__, addr, blocksize); + if (rtl8xxxu_debug & RTL8XXXU_DEBUG_REG_WRITE) + dev_info(&udev->dev, + "%s: Failed to write block at addr: %04x size: %04x\n", + __func__, addr, blocksize); return -EAGAIN; } @@ -4064,8 +4065,14 @@ static int rtl8xxxu_init_device(struct ieee80211_hw *hw) */ rtl8xxxu_write16(priv, REG_TRXFF_BNDY + 2, fops->trxff_boundary); - ret = rtl8xxxu_download_firmware(priv); - dev_dbg(dev, "%s: download_firmware %i\n", __func__, ret); + for (int retry = 5; retry >= 0 ; retry--) { + ret = rtl8xxxu_download_firmware(priv); + dev_dbg(dev, "%s: download_firmware %i\n", __func__, ret); + if (ret != -EAGAIN) + break; + if (retry) + dev_dbg(dev, "%s: retry firmware download\n", __func__); + } if (ret) goto exit; ret = rtl8xxxu_start_firmware(priv); diff --git a/drivers/net/wireless/realtek/rtlwifi/rtl8192de/phy.c b/drivers/net/wireless/realtek/rtlwifi/rtl8192de/phy.c index d429560009bb..e07402e73ba3 100644 --- a/drivers/net/wireless/realtek/rtlwifi/rtl8192de/phy.c +++ b/drivers/net/wireless/realtek/rtlwifi/rtl8192de/phy.c @@ -484,7 +484,7 @@ bool rtl92d_phy_config_rf_with_headerfile(struct ieee80211_hw *hw, * pathA or mac1 has to set phy0&phy1 pathA */ if ((content == radiob_txt) && (rfpath == RF90_PATH_A)) { rtl_dbg(rtlpriv, COMP_INIT, DBG_LOUD, - " ===> althougth Path A, we load radiob.txt\n"); + " ===> although Path A, we load radiob.txt\n"); radioa_arraylen = radiob_arraylen; radioa_array_table = radiob_array_table; } @@ -750,7 +750,7 @@ static void _rtl92d_phy_switch_rf_setting(struct ieee80211_hw *hw, u8 channel) && rtlhal->interfaceindex == 1) { need_pwr_down = rtl92d_phy_enable_anotherphy(hw, false); rtlhal->during_mac1init_radioa = true; - /* asume no this case */ + /* assume no this case */ if (need_pwr_down) rtl92d_phy_enable_rf_env(hw, path, &u4regvalue); @@ -1885,7 +1885,7 @@ static void _rtl92d_phy_reload_lck_setting(struct ieee80211_hw *hw, bneed_powerdown_radio = rtl92d_phy_enable_anotherphy(hw, false); rtlpriv->rtlhal.during_mac1init_radioa = true; - /* asume no this case */ + /* assume no this case */ if (bneed_powerdown_radio) rtl92d_phy_enable_rf_env(hw, erfpath, &u4regvalue); diff --git a/drivers/net/wireless/realtek/rtw88/fw.c b/drivers/net/wireless/realtek/rtw88/fw.c index 02389b7c6876..6b563ac489a7 100644 --- a/drivers/net/wireless/realtek/rtw88/fw.c +++ b/drivers/net/wireless/realtek/rtw88/fw.c @@ -735,6 +735,7 @@ void rtw_fw_send_ra_info(struct rtw_dev *rtwdev, struct rtw_sta_info *si, { u8 h2c_pkt[H2C_PKT_SIZE] = {0}; bool disable_pt = true; + u32 mask_hi; SET_H2C_CMD_ID_CLASS(h2c_pkt, H2C_CMD_RA_INFO); @@ -755,6 +756,20 @@ void rtw_fw_send_ra_info(struct rtw_dev *rtwdev, struct rtw_sta_info *si, si->init_ra_lv = 0; rtw_fw_send_h2c_command(rtwdev, h2c_pkt); + + if (rtwdev->chip->id != RTW_CHIP_TYPE_8814A) + return; + + SET_H2C_CMD_ID_CLASS(h2c_pkt, H2C_CMD_RA_INFO_HI); + + mask_hi = si->ra_mask >> 32; + + SET_RA_INFO_RA_MASK0(h2c_pkt, (mask_hi & 0xff)); + SET_RA_INFO_RA_MASK1(h2c_pkt, (mask_hi & 0xff00) >> 8); + SET_RA_INFO_RA_MASK2(h2c_pkt, (mask_hi & 0xff0000) >> 16); + SET_RA_INFO_RA_MASK3(h2c_pkt, (mask_hi & 0xff000000) >> 24); + + rtw_fw_send_h2c_command(rtwdev, h2c_pkt); } void rtw_fw_media_status_report(struct rtw_dev *rtwdev, u8 mac_id, bool connect) diff --git a/drivers/net/wireless/realtek/rtw88/fw.h b/drivers/net/wireless/realtek/rtw88/fw.h index 404de1b0c407..48ad9ceab6ea 100644 --- a/drivers/net/wireless/realtek/rtw88/fw.h +++ b/drivers/net/wireless/realtek/rtw88/fw.h @@ -557,6 +557,7 @@ static inline void rtw_h2c_pkt_set_header(u8 *h2c_pkt, u8 sub_id) #define H2C_CMD_DEFAULT_PORT 0x2c #define H2C_CMD_RA_INFO 0x40 #define H2C_CMD_RSSI_MONITOR 0x42 +#define H2C_CMD_RA_INFO_HI 0x46 #define H2C_CMD_BCN_FILTER_OFFLOAD_P0 0x56 #define H2C_CMD_BCN_FILTER_OFFLOAD_P1 0x57 #define H2C_CMD_WL_PHY_INFO 0x58 diff --git a/drivers/net/wireless/realtek/rtw88/mac.c b/drivers/net/wireless/realtek/rtw88/mac.c index cae9cca6dca3..63edf6461de8 100644 --- a/drivers/net/wireless/realtek/rtw88/mac.c +++ b/drivers/net/wireless/realtek/rtw88/mac.c @@ -784,7 +784,8 @@ static int __rtw_download_firmware(struct rtw_dev *rtwdev, if (!check_firmware_size(data, size)) return -EINVAL; - if (!ltecoex_read_reg(rtwdev, 0x38, <ecoex_bckp)) + if (rtwdev->chip->ltecoex_addr && + !ltecoex_read_reg(rtwdev, 0x38, <ecoex_bckp)) return -EBUSY; wlan_cpu_enable(rtwdev, false); @@ -802,7 +803,8 @@ static int __rtw_download_firmware(struct rtw_dev *rtwdev, wlan_cpu_enable(rtwdev, true); - if (!ltecoex_reg_write(rtwdev, 0x38, ltecoex_bckp)) { + if (rtwdev->chip->ltecoex_addr && + !ltecoex_reg_write(rtwdev, 0x38, ltecoex_bckp)) { ret = -EBUSY; goto dlfw_fail; } diff --git a/drivers/net/wireless/realtek/rtw88/main.c b/drivers/net/wireless/realtek/rtw88/main.c index 0cee0fd8c0ef..e4f9b744f24d 100644 --- a/drivers/net/wireless/realtek/rtw88/main.c +++ b/drivers/net/wireless/realtek/rtw88/main.c @@ -136,7 +136,7 @@ u16 rtw_desc_to_bitrate(u8 desc_rate) return rate.bitrate; } -static struct ieee80211_supported_band rtw_band_2ghz = { +static const struct ieee80211_supported_band rtw_band_2ghz = { .band = NL80211_BAND_2GHZ, .channels = rtw_channeltable_2g, @@ -149,7 +149,7 @@ static struct ieee80211_supported_band rtw_band_2ghz = { .vht_cap = {0}, }; -static struct ieee80211_supported_band rtw_band_5ghz = { +static const struct ieee80211_supported_band rtw_band_5ghz = { .band = NL80211_BAND_5GHZ, .channels = rtw_channeltable_5g, @@ -1234,7 +1234,9 @@ void rtw_update_sta_info(struct rtw_dev *rtwdev, struct rtw_sta_info *si, if (sta->deflink.vht_cap.cap & IEEE80211_VHT_CAP_RXLDPC) ldpc_en = VHT_LDPC_EN; } else if (sta->deflink.ht_cap.ht_supported) { - ra_mask |= (sta->deflink.ht_cap.mcs.rx_mask[1] << 20) | + ra_mask |= ((u64)sta->deflink.ht_cap.mcs.rx_mask[3] << 36) | + ((u64)sta->deflink.ht_cap.mcs.rx_mask[2] << 28) | + (sta->deflink.ht_cap.mcs.rx_mask[1] << 20) | (sta->deflink.ht_cap.mcs.rx_mask[0] << 12); if (sta->deflink.ht_cap.cap & IEEE80211_HT_CAP_RX_STBC) stbc_en = HT_STBC_EN; @@ -1244,6 +1246,9 @@ void rtw_update_sta_info(struct rtw_dev *rtwdev, struct rtw_sta_info *si, if (efuse->hw_cap.nss == 1 || rtwdev->hal.txrx_1ss) ra_mask &= RA_MASK_VHT_RATES_1SS | RA_MASK_HT_RATES_1SS; + else if (efuse->hw_cap.nss == 2) + ra_mask &= RA_MASK_VHT_RATES_2SS | RA_MASK_HT_RATES_2SS | + RA_MASK_VHT_RATES_1SS | RA_MASK_HT_RATES_1SS; if (hal->current_band_type == RTW_BAND_5G) { ra_mask |= (u64)sta->deflink.supp_rates[NL80211_BAND_5GHZ] << 4; @@ -1302,10 +1307,9 @@ void rtw_update_sta_info(struct rtw_dev *rtwdev, struct rtw_sta_info *si, break; } - if (sta->deflink.vht_cap.vht_supported && ra_mask & 0xffc00000) - tx_num = 2; - else if (sta->deflink.ht_cap.ht_supported && ra_mask & 0xfff00000) - tx_num = 2; + if (sta->deflink.vht_cap.vht_supported || + sta->deflink.ht_cap.ht_supported) + tx_num = efuse->hw_cap.nss; rate_id = get_rate_id(wireless_set, bw_mode, tx_num); diff --git a/drivers/net/wireless/realtek/rtw88/main.h b/drivers/net/wireless/realtek/rtw88/main.h index 62cd4c526301..24ac749271cc 100644 --- a/drivers/net/wireless/realtek/rtw88/main.h +++ b/drivers/net/wireless/realtek/rtw88/main.h @@ -61,7 +61,7 @@ enum rtw_hci_type { }; struct rtw_hci { - struct rtw_hci_ops *ops; + const struct rtw_hci_ops *ops; enum rtw_hci_type type; u32 rpwm_addr; @@ -166,9 +166,14 @@ enum rtw_rate_section { RTW_RATE_SECTION_HT_2S, RTW_RATE_SECTION_VHT_1S, RTW_RATE_SECTION_VHT_2S, + __RTW_RATE_SECTION_2SS_MAX = RTW_RATE_SECTION_VHT_2S, + RTW_RATE_SECTION_HT_3S, + RTW_RATE_SECTION_HT_4S, + RTW_RATE_SECTION_VHT_3S, + RTW_RATE_SECTION_VHT_4S, /* keep last */ - RTW_RATE_SECTION_MAX, + RTW_RATE_SECTION_NUM, }; enum rtw_wireless_set { @@ -191,6 +196,7 @@ enum rtw_chip_type { RTW_CHIP_TYPE_8703B, RTW_CHIP_TYPE_8821A, RTW_CHIP_TYPE_8812A, + RTW_CHIP_TYPE_8814A, }; enum rtw_tx_queue_type { @@ -1130,14 +1136,26 @@ struct rtw_rfe_def { * For 2G there are cck rate and ofdm rate with different settings. */ struct rtw_pwr_track_tbl { + const u8 *pwrtrk_5gd_n[RTW_PWR_TRK_5G_NUM]; + const u8 *pwrtrk_5gd_p[RTW_PWR_TRK_5G_NUM]; + const u8 *pwrtrk_5gc_n[RTW_PWR_TRK_5G_NUM]; + const u8 *pwrtrk_5gc_p[RTW_PWR_TRK_5G_NUM]; const u8 *pwrtrk_5gb_n[RTW_PWR_TRK_5G_NUM]; const u8 *pwrtrk_5gb_p[RTW_PWR_TRK_5G_NUM]; const u8 *pwrtrk_5ga_n[RTW_PWR_TRK_5G_NUM]; const u8 *pwrtrk_5ga_p[RTW_PWR_TRK_5G_NUM]; + const u8 *pwrtrk_2gd_n; + const u8 *pwrtrk_2gd_p; + const u8 *pwrtrk_2gc_n; + const u8 *pwrtrk_2gc_p; const u8 *pwrtrk_2gb_n; const u8 *pwrtrk_2gb_p; const u8 *pwrtrk_2ga_n; const u8 *pwrtrk_2ga_p; + const u8 *pwrtrk_2g_cckd_n; + const u8 *pwrtrk_2g_cckd_p; + const u8 *pwrtrk_2g_cckc_n; + const u8 *pwrtrk_2g_cckc_p; const u8 *pwrtrk_2g_cckb_n; const u8 *pwrtrk_2g_cckb_p; const u8 *pwrtrk_2g_ccka_n; @@ -1227,8 +1245,8 @@ struct rtw_chip_info { const struct rtw_hw_reg *dig; const struct rtw_hw_reg *dig_cck; - u32 rf_base_addr[2]; - u32 rf_sipi_addr[2]; + u32 rf_base_addr[RTW_RF_PATH_MAX]; + u32 rf_sipi_addr[RTW_RF_PATH_MAX]; const struct rtw_rf_sipi_addr *rf_sipi_read_addr; u8 fix_rf_phy_num; const struct rtw_ltecoex_addr *ltecoex_addr; @@ -1924,7 +1942,7 @@ union rtw_sar_cfg { struct rtw_sar { enum rtw_sar_sources src; - union rtw_sar_cfg cfg[RTW_RF_PATH_MAX][RTW_RATE_SECTION_MAX]; + union rtw_sar_cfg cfg[RTW_RF_PATH_MAX][RTW_RATE_SECTION_NUM]; }; struct rtw_hal { @@ -1968,16 +1986,16 @@ struct rtw_hal { s8 tx_pwr_by_rate_offset_5g[RTW_RF_PATH_MAX] [DESC_RATE_MAX]; s8 tx_pwr_by_rate_base_2g[RTW_RF_PATH_MAX] - [RTW_RATE_SECTION_MAX]; + [RTW_RATE_SECTION_NUM]; s8 tx_pwr_by_rate_base_5g[RTW_RF_PATH_MAX] - [RTW_RATE_SECTION_MAX]; + [RTW_RATE_SECTION_NUM]; s8 tx_pwr_limit_2g[RTW_REGD_MAX] [RTW_CHANNEL_WIDTH_MAX] - [RTW_RATE_SECTION_MAX] + [RTW_RATE_SECTION_NUM] [RTW_MAX_CHANNEL_NUM_2G]; s8 tx_pwr_limit_5g[RTW_REGD_MAX] [RTW_CHANNEL_WIDTH_MAX] - [RTW_RATE_SECTION_MAX] + [RTW_RATE_SECTION_NUM] [RTW_MAX_CHANNEL_NUM_5G]; s8 tx_pwr_tbl[RTW_RF_PATH_MAX] [DESC_RATE_MAX]; diff --git a/drivers/net/wireless/realtek/rtw88/pci.c b/drivers/net/wireless/realtek/rtw88/pci.c index 0ecaefc4c83d..bb4c4ccb31d4 100644 --- a/drivers/net/wireless/realtek/rtw88/pci.c +++ b/drivers/net/wireless/realtek/rtw88/pci.c @@ -20,7 +20,7 @@ module_param_named(disable_aspm, rtw_pci_disable_aspm, bool, 0644); MODULE_PARM_DESC(disable_msi, "Set Y to disable MSI interrupt support"); MODULE_PARM_DESC(disable_aspm, "Set Y to disable PCI ASPM support"); -static u32 rtw_pci_tx_queue_idx_addr[] = { +static const u32 rtw_pci_tx_queue_idx_addr[] = { [RTW_TX_QUEUE_BK] = RTK_PCI_TXBD_IDX_BKQ, [RTW_TX_QUEUE_BE] = RTK_PCI_TXBD_IDX_BEQ, [RTW_TX_QUEUE_VI] = RTK_PCI_TXBD_IDX_VIQ, @@ -1591,7 +1591,7 @@ static void rtw_pci_destroy(struct rtw_dev *rtwdev, struct pci_dev *pdev) rtw_pci_io_unmapping(rtwdev, pdev); } -static struct rtw_hci_ops rtw_pci_ops = { +static const struct rtw_hci_ops rtw_pci_ops = { .tx_write = rtw_pci_tx_write, .tx_kick_off = rtw_pci_tx_kick_off, .flush_queues = rtw_pci_flush_queues, diff --git a/drivers/net/wireless/realtek/rtw88/phy.c b/drivers/net/wireless/realtek/rtw88/phy.c index 8ed20c89d216..b487457d2215 100644 --- a/drivers/net/wireless/realtek/rtw88/phy.c +++ b/drivers/net/wireless/realtek/rtw88/phy.c @@ -52,60 +52,93 @@ static const u32 db_invert_table[12][8] = { 1995262315, 2511886432U, 3162277660U, 3981071706U} }; -u8 rtw_cck_rates[] = { DESC_RATE1M, DESC_RATE2M, DESC_RATE5_5M, DESC_RATE11M }; -u8 rtw_ofdm_rates[] = { +const u8 rtw_cck_rates[] = { DESC_RATE1M, DESC_RATE2M, DESC_RATE5_5M, DESC_RATE11M }; + +const u8 rtw_ofdm_rates[] = { DESC_RATE6M, DESC_RATE9M, DESC_RATE12M, DESC_RATE18M, DESC_RATE24M, DESC_RATE36M, DESC_RATE48M, DESC_RATE54M }; -u8 rtw_ht_1s_rates[] = { + +const u8 rtw_ht_1s_rates[] = { DESC_RATEMCS0, DESC_RATEMCS1, DESC_RATEMCS2, DESC_RATEMCS3, DESC_RATEMCS4, DESC_RATEMCS5, DESC_RATEMCS6, DESC_RATEMCS7 }; -u8 rtw_ht_2s_rates[] = { + +const u8 rtw_ht_2s_rates[] = { DESC_RATEMCS8, DESC_RATEMCS9, DESC_RATEMCS10, DESC_RATEMCS11, DESC_RATEMCS12, DESC_RATEMCS13, DESC_RATEMCS14, DESC_RATEMCS15 }; -u8 rtw_vht_1s_rates[] = { + +const u8 rtw_vht_1s_rates[] = { DESC_RATEVHT1SS_MCS0, DESC_RATEVHT1SS_MCS1, DESC_RATEVHT1SS_MCS2, DESC_RATEVHT1SS_MCS3, DESC_RATEVHT1SS_MCS4, DESC_RATEVHT1SS_MCS5, DESC_RATEVHT1SS_MCS6, DESC_RATEVHT1SS_MCS7, DESC_RATEVHT1SS_MCS8, DESC_RATEVHT1SS_MCS9 }; -u8 rtw_vht_2s_rates[] = { + +const u8 rtw_vht_2s_rates[] = { DESC_RATEVHT2SS_MCS0, DESC_RATEVHT2SS_MCS1, DESC_RATEVHT2SS_MCS2, DESC_RATEVHT2SS_MCS3, DESC_RATEVHT2SS_MCS4, DESC_RATEVHT2SS_MCS5, DESC_RATEVHT2SS_MCS6, DESC_RATEVHT2SS_MCS7, DESC_RATEVHT2SS_MCS8, DESC_RATEVHT2SS_MCS9 }; -u8 *rtw_rate_section[RTW_RATE_SECTION_MAX] = { + +const u8 rtw_ht_3s_rates[] = { + DESC_RATEMCS16, DESC_RATEMCS17, DESC_RATEMCS18, + DESC_RATEMCS19, DESC_RATEMCS20, DESC_RATEMCS21, + DESC_RATEMCS22, DESC_RATEMCS23 +}; + +const u8 rtw_ht_4s_rates[] = { + DESC_RATEMCS24, DESC_RATEMCS25, DESC_RATEMCS26, + DESC_RATEMCS27, DESC_RATEMCS28, DESC_RATEMCS29, + DESC_RATEMCS30, DESC_RATEMCS31 +}; + +const u8 rtw_vht_3s_rates[] = { + DESC_RATEVHT3SS_MCS0, DESC_RATEVHT3SS_MCS1, + DESC_RATEVHT3SS_MCS2, DESC_RATEVHT3SS_MCS3, + DESC_RATEVHT3SS_MCS4, DESC_RATEVHT3SS_MCS5, + DESC_RATEVHT3SS_MCS6, DESC_RATEVHT3SS_MCS7, + DESC_RATEVHT3SS_MCS8, DESC_RATEVHT3SS_MCS9 +}; + +const u8 rtw_vht_4s_rates[] = { + DESC_RATEVHT4SS_MCS0, DESC_RATEVHT4SS_MCS1, + DESC_RATEVHT4SS_MCS2, DESC_RATEVHT4SS_MCS3, + DESC_RATEVHT4SS_MCS4, DESC_RATEVHT4SS_MCS5, + DESC_RATEVHT4SS_MCS6, DESC_RATEVHT4SS_MCS7, + DESC_RATEVHT4SS_MCS8, DESC_RATEVHT4SS_MCS9 +}; + +const u8 * const rtw_rate_section[RTW_RATE_SECTION_NUM] = { rtw_cck_rates, rtw_ofdm_rates, rtw_ht_1s_rates, rtw_ht_2s_rates, - rtw_vht_1s_rates, rtw_vht_2s_rates + rtw_vht_1s_rates, rtw_vht_2s_rates, + rtw_ht_3s_rates, rtw_ht_4s_rates, + rtw_vht_3s_rates, rtw_vht_4s_rates }; EXPORT_SYMBOL(rtw_rate_section); -u8 rtw_rate_size[RTW_RATE_SECTION_MAX] = { +const u8 rtw_rate_size[RTW_RATE_SECTION_NUM] = { ARRAY_SIZE(rtw_cck_rates), ARRAY_SIZE(rtw_ofdm_rates), ARRAY_SIZE(rtw_ht_1s_rates), ARRAY_SIZE(rtw_ht_2s_rates), ARRAY_SIZE(rtw_vht_1s_rates), - ARRAY_SIZE(rtw_vht_2s_rates) + ARRAY_SIZE(rtw_vht_2s_rates), + ARRAY_SIZE(rtw_ht_3s_rates), + ARRAY_SIZE(rtw_ht_4s_rates), + ARRAY_SIZE(rtw_vht_3s_rates), + ARRAY_SIZE(rtw_vht_4s_rates) }; EXPORT_SYMBOL(rtw_rate_size); -static const u8 rtw_cck_size = ARRAY_SIZE(rtw_cck_rates); -static const u8 rtw_ofdm_size = ARRAY_SIZE(rtw_ofdm_rates); -static const u8 rtw_ht_1s_size = ARRAY_SIZE(rtw_ht_1s_rates); -static const u8 rtw_ht_2s_size = ARRAY_SIZE(rtw_ht_2s_rates); -static const u8 rtw_vht_1s_size = ARRAY_SIZE(rtw_vht_1s_rates); -static const u8 rtw_vht_2s_size = ARRAY_SIZE(rtw_vht_2s_rates); - enum rtw_phy_band_type { PHY_BAND_2G = 0, PHY_BAND_5G = 1, @@ -1590,7 +1623,7 @@ static void rtw_phy_set_tx_power_limit(struct rtw_dev *rtwdev, u8 regd, u8 band, ch_idx = rtw_channel_to_idx(band, ch); if (regd >= RTW_REGD_MAX || bw >= RTW_CHANNEL_WIDTH_MAX || - rs >= RTW_RATE_SECTION_MAX || ch_idx < 0) { + rs >= RTW_RATE_SECTION_NUM || ch_idx < 0) { WARN(1, "wrong txpwr_lmt regd=%u, band=%u bw=%u, rs=%u, ch_idx=%u, pwr_limit=%d\n", regd, band, bw, rs, ch_idx, pwr_limit); @@ -1634,11 +1667,15 @@ rtw_xref_5g_txpwr_lmt(struct rtw_dev *rtwdev, u8 regd, static void rtw_xref_txpwr_lmt_by_rs(struct rtw_dev *rtwdev, u8 regd, u8 bw, u8 ch_idx) { + static const u8 rs_cmp[4][2] = { + {RTW_RATE_SECTION_HT_1S, RTW_RATE_SECTION_VHT_1S}, + {RTW_RATE_SECTION_HT_2S, RTW_RATE_SECTION_VHT_2S}, + {RTW_RATE_SECTION_HT_3S, RTW_RATE_SECTION_VHT_3S}, + {RTW_RATE_SECTION_HT_4S, RTW_RATE_SECTION_VHT_4S} + }; u8 rs_idx, rs_ht, rs_vht; - u8 rs_cmp[2][2] = {{RTW_RATE_SECTION_HT_1S, RTW_RATE_SECTION_VHT_1S}, - {RTW_RATE_SECTION_HT_2S, RTW_RATE_SECTION_VHT_2S} }; - for (rs_idx = 0; rs_idx < 2; rs_idx++) { + for (rs_idx = 0; rs_idx < 4; rs_idx++) { rs_ht = rs_cmp[rs_idx][0]; rs_vht = rs_cmp[rs_idx][1]; @@ -1695,7 +1732,7 @@ rtw_cfg_txpwr_lmt_by_alt(struct rtw_dev *rtwdev, u8 regd, u8 regd_alt) u8 bw, rs; for (bw = 0; bw < RTW_CHANNEL_WIDTH_MAX; bw++) - for (rs = 0; rs < RTW_RATE_SECTION_MAX; rs++) + for (rs = 0; rs < RTW_RATE_SECTION_NUM; rs++) __cfg_txpwr_lmt_by_alt(&rtwdev->hal, regd, regd_alt, bw, rs); } @@ -1959,10 +1996,10 @@ static u8 rtw_phy_get_2g_tx_power_index(struct rtw_dev *rtwdev, u8 rate, u8 group) { const struct rtw_chip_info *chip = rtwdev->chip; - u8 tx_power; - bool mcs_rate; - bool above_2ss; + bool above_2ss, above_3ss, above_4ss; u8 factor = chip->txgi_factor; + bool mcs_rate; + u8 tx_power; if (rate <= DESC_RATE11M) tx_power = pwr_idx_2g->cck_base[group]; @@ -1972,11 +2009,15 @@ static u8 rtw_phy_get_2g_tx_power_index(struct rtw_dev *rtwdev, if (rate >= DESC_RATE6M && rate <= DESC_RATE54M) tx_power += pwr_idx_2g->ht_1s_diff.ofdm * factor; - mcs_rate = (rate >= DESC_RATEMCS0 && rate <= DESC_RATEMCS15) || + mcs_rate = (rate >= DESC_RATEMCS0 && rate <= DESC_RATEMCS31) || (rate >= DESC_RATEVHT1SS_MCS0 && - rate <= DESC_RATEVHT2SS_MCS9); - above_2ss = (rate >= DESC_RATEMCS8 && rate <= DESC_RATEMCS15) || + rate <= DESC_RATEVHT4SS_MCS9); + above_2ss = (rate >= DESC_RATEMCS8 && rate <= DESC_RATEMCS31) || (rate >= DESC_RATEVHT2SS_MCS0); + above_3ss = (rate >= DESC_RATEMCS16 && rate <= DESC_RATEMCS31) || + (rate >= DESC_RATEVHT3SS_MCS0); + above_4ss = (rate >= DESC_RATEMCS24 && rate <= DESC_RATEMCS31) || + (rate >= DESC_RATEVHT4SS_MCS0); if (!mcs_rate) return tx_power; @@ -1989,11 +2030,19 @@ static u8 rtw_phy_get_2g_tx_power_index(struct rtw_dev *rtwdev, tx_power += pwr_idx_2g->ht_1s_diff.bw20 * factor; if (above_2ss) tx_power += pwr_idx_2g->ht_2s_diff.bw20 * factor; + if (above_3ss) + tx_power += pwr_idx_2g->ht_3s_diff.bw20 * factor; + if (above_4ss) + tx_power += pwr_idx_2g->ht_4s_diff.bw20 * factor; break; case RTW_CHANNEL_WIDTH_40: /* bw40 is the base power */ if (above_2ss) tx_power += pwr_idx_2g->ht_2s_diff.bw40 * factor; + if (above_3ss) + tx_power += pwr_idx_2g->ht_3s_diff.bw40 * factor; + if (above_4ss) + tx_power += pwr_idx_2g->ht_4s_diff.bw40 * factor; break; } @@ -2006,19 +2055,23 @@ static u8 rtw_phy_get_5g_tx_power_index(struct rtw_dev *rtwdev, u8 rate, u8 group) { const struct rtw_chip_info *chip = rtwdev->chip; - u8 tx_power; + bool above_2ss, above_3ss, above_4ss; + u8 factor = chip->txgi_factor; u8 upper, lower; bool mcs_rate; - bool above_2ss; - u8 factor = chip->txgi_factor; + u8 tx_power; tx_power = pwr_idx_5g->bw40_base[group]; - mcs_rate = (rate >= DESC_RATEMCS0 && rate <= DESC_RATEMCS15) || + mcs_rate = (rate >= DESC_RATEMCS0 && rate <= DESC_RATEMCS31) || (rate >= DESC_RATEVHT1SS_MCS0 && - rate <= DESC_RATEVHT2SS_MCS9); - above_2ss = (rate >= DESC_RATEMCS8 && rate <= DESC_RATEMCS15) || + rate <= DESC_RATEVHT4SS_MCS9); + above_2ss = (rate >= DESC_RATEMCS8 && rate <= DESC_RATEMCS31) || (rate >= DESC_RATEVHT2SS_MCS0); + above_3ss = (rate >= DESC_RATEMCS16 && rate <= DESC_RATEMCS31) || + (rate >= DESC_RATEVHT3SS_MCS0); + above_4ss = (rate >= DESC_RATEMCS24 && rate <= DESC_RATEMCS31) || + (rate >= DESC_RATEVHT4SS_MCS0); if (!mcs_rate) { tx_power += pwr_idx_5g->ht_1s_diff.ofdm * factor; @@ -2033,11 +2086,19 @@ static u8 rtw_phy_get_5g_tx_power_index(struct rtw_dev *rtwdev, tx_power += pwr_idx_5g->ht_1s_diff.bw20 * factor; if (above_2ss) tx_power += pwr_idx_5g->ht_2s_diff.bw20 * factor; + if (above_3ss) + tx_power += pwr_idx_5g->ht_3s_diff.bw20 * factor; + if (above_4ss) + tx_power += pwr_idx_5g->ht_4s_diff.bw20 * factor; break; case RTW_CHANNEL_WIDTH_40: /* bw40 is the base power */ if (above_2ss) tx_power += pwr_idx_5g->ht_2s_diff.bw40 * factor; + if (above_3ss) + tx_power += pwr_idx_5g->ht_3s_diff.bw40 * factor; + if (above_4ss) + tx_power += pwr_idx_5g->ht_4s_diff.bw40 * factor; break; case RTW_CHANNEL_WIDTH_80: /* the base idx of bw80 is the average of bw40+/bw40- */ @@ -2048,13 +2109,17 @@ static u8 rtw_phy_get_5g_tx_power_index(struct rtw_dev *rtwdev, tx_power += pwr_idx_5g->vht_1s_diff.bw80 * factor; if (above_2ss) tx_power += pwr_idx_5g->vht_2s_diff.bw80 * factor; + if (above_3ss) + tx_power += pwr_idx_5g->vht_3s_diff.bw80 * factor; + if (above_4ss) + tx_power += pwr_idx_5g->vht_4s_diff.bw80 * factor; break; } return tx_power; } -/* return RTW_RATE_SECTION_MAX to indicate rate is invalid */ +/* return RTW_RATE_SECTION_NUM to indicate rate is invalid */ static u8 rtw_phy_rate_to_rate_section(u8 rate) { if (rate >= DESC_RATE1M && rate <= DESC_RATE11M) @@ -2065,12 +2130,20 @@ static u8 rtw_phy_rate_to_rate_section(u8 rate) return RTW_RATE_SECTION_HT_1S; else if (rate >= DESC_RATEMCS8 && rate <= DESC_RATEMCS15) return RTW_RATE_SECTION_HT_2S; + else if (rate >= DESC_RATEMCS16 && rate <= DESC_RATEMCS23) + return RTW_RATE_SECTION_HT_3S; + else if (rate >= DESC_RATEMCS24 && rate <= DESC_RATEMCS31) + return RTW_RATE_SECTION_HT_4S; else if (rate >= DESC_RATEVHT1SS_MCS0 && rate <= DESC_RATEVHT1SS_MCS9) return RTW_RATE_SECTION_VHT_1S; else if (rate >= DESC_RATEVHT2SS_MCS0 && rate <= DESC_RATEVHT2SS_MCS9) return RTW_RATE_SECTION_VHT_2S; + else if (rate >= DESC_RATEVHT3SS_MCS0 && rate <= DESC_RATEVHT3SS_MCS9) + return RTW_RATE_SECTION_VHT_3S; + else if (rate >= DESC_RATEVHT4SS_MCS0 && rate <= DESC_RATEVHT4SS_MCS9) + return RTW_RATE_SECTION_VHT_4S; else - return RTW_RATE_SECTION_MAX; + return RTW_RATE_SECTION_NUM; } static s8 rtw_phy_get_tx_power_limit(struct rtw_dev *rtwdev, u8 band, @@ -2088,7 +2161,7 @@ static s8 rtw_phy_get_tx_power_limit(struct rtw_dev *rtwdev, u8 band, if (regd > RTW_REGD_WW) return power_limit; - if (rs == RTW_RATE_SECTION_MAX) + if (rs == RTW_RATE_SECTION_NUM) goto err; /* only 20M BW with cck and ofdm */ @@ -2096,7 +2169,7 @@ static s8 rtw_phy_get_tx_power_limit(struct rtw_dev *rtwdev, u8 band, bw = RTW_CHANNEL_WIDTH_20; /* only 20/40M BW with ht */ - if (rs == RTW_RATE_SECTION_HT_1S || rs == RTW_RATE_SECTION_HT_2S) + if (rate >= DESC_RATEMCS0 && rate <= DESC_RATEMCS31) bw = min_t(u8, bw, RTW_CHANNEL_WIDTH_40); /* select min power limit among [20M BW ~ current BW] */ @@ -2132,7 +2205,7 @@ static s8 rtw_phy_get_tx_power_sar(struct rtw_dev *rtwdev, u8 sar_band, .rs = rs, }; - if (rs == RTW_RATE_SECTION_MAX) + if (rs == RTW_RATE_SECTION_NUM) goto err; return rtw_query_sar(rtwdev, &arg); @@ -2214,14 +2287,14 @@ static void rtw_phy_set_tx_power_index_by_rs(struct rtw_dev *rtwdev, { struct rtw_hal *hal = &rtwdev->hal; u8 regd = rtw_regd_get(rtwdev); - u8 *rates; + const u8 *rates; u8 size; u8 rate; u8 pwr_idx; u8 bw; int i; - if (rs >= RTW_RATE_SECTION_MAX) + if (rs >= RTW_RATE_SECTION_NUM) return; rates = rtw_rate_section[rs]; @@ -2252,7 +2325,7 @@ static void rtw_phy_set_tx_power_level_by_path(struct rtw_dev *rtwdev, else rs = RTW_RATE_SECTION_OFDM; - for (; rs < RTW_RATE_SECTION_MAX; rs++) + for (; rs < RTW_RATE_SECTION_NUM; rs++) rtw_phy_set_tx_power_index_by_rs(rtwdev, ch, path, rs); } @@ -2274,13 +2347,13 @@ EXPORT_SYMBOL(rtw_phy_set_tx_power_level); static void rtw_phy_tx_power_by_rate_config_by_path(struct rtw_hal *hal, u8 path, - u8 rs, u8 size, u8 *rates) + u8 rs, u8 size, const u8 *rates) { u8 rate; u8 base_idx, rate_idx; s8 base_2g, base_5g; - if (rs >= RTW_RATE_SECTION_VHT_1S) + if (size == 10) /* VHT rates */ base_idx = rates[size - 3]; else base_idx = rates[size - 1]; @@ -2297,28 +2370,12 @@ rtw_phy_tx_power_by_rate_config_by_path(struct rtw_hal *hal, u8 path, void rtw_phy_tx_power_by_rate_config(struct rtw_hal *hal) { - u8 path; + u8 path, rs; - for (path = 0; path < RTW_RF_PATH_MAX; path++) { - rtw_phy_tx_power_by_rate_config_by_path(hal, path, - RTW_RATE_SECTION_CCK, - rtw_cck_size, rtw_cck_rates); - rtw_phy_tx_power_by_rate_config_by_path(hal, path, - RTW_RATE_SECTION_OFDM, - rtw_ofdm_size, rtw_ofdm_rates); - rtw_phy_tx_power_by_rate_config_by_path(hal, path, - RTW_RATE_SECTION_HT_1S, - rtw_ht_1s_size, rtw_ht_1s_rates); - rtw_phy_tx_power_by_rate_config_by_path(hal, path, - RTW_RATE_SECTION_HT_2S, - rtw_ht_2s_size, rtw_ht_2s_rates); - rtw_phy_tx_power_by_rate_config_by_path(hal, path, - RTW_RATE_SECTION_VHT_1S, - rtw_vht_1s_size, rtw_vht_1s_rates); - rtw_phy_tx_power_by_rate_config_by_path(hal, path, - RTW_RATE_SECTION_VHT_2S, - rtw_vht_2s_size, rtw_vht_2s_rates); - } + for (path = 0; path < RTW_RF_PATH_MAX; path++) + for (rs = 0; rs < RTW_RATE_SECTION_NUM; rs++) + rtw_phy_tx_power_by_rate_config_by_path(hal, path, rs, + rtw_rate_size[rs], rtw_rate_section[rs]); } static void @@ -2347,7 +2404,7 @@ void rtw_phy_tx_power_limit_config(struct rtw_hal *hal) for (regd = 0; regd < RTW_REGD_MAX; regd++) for (bw = 0; bw < RTW_CHANNEL_WIDTH_MAX; bw++) - for (rs = 0; rs < RTW_RATE_SECTION_MAX; rs++) + for (rs = 0; rs < RTW_RATE_SECTION_NUM; rs++) __rtw_phy_tx_power_limit_config(hal, regd, bw, rs); } @@ -2383,7 +2440,7 @@ void rtw_phy_init_tx_power(struct rtw_dev *rtwdev) /* init tx power limit */ for (regd = 0; regd < RTW_REGD_MAX; regd++) for (bw = 0; bw < RTW_CHANNEL_WIDTH_MAX; bw++) - for (rs = 0; rs < RTW_RATE_SECTION_MAX; rs++) + for (rs = 0; rs < RTW_RATE_SECTION_NUM; rs++) rtw_phy_init_tx_power_limit(rtwdev, regd, bw, rs); } diff --git a/drivers/net/wireless/realtek/rtw88/phy.h b/drivers/net/wireless/realtek/rtw88/phy.h index ccfcbd3ced03..c9e6b869661d 100644 --- a/drivers/net/wireless/realtek/rtw88/phy.h +++ b/drivers/net/wireless/realtek/rtw88/phy.h @@ -7,14 +7,18 @@ #include "debug.h" -extern u8 rtw_cck_rates[]; -extern u8 rtw_ofdm_rates[]; -extern u8 rtw_ht_1s_rates[]; -extern u8 rtw_ht_2s_rates[]; -extern u8 rtw_vht_1s_rates[]; -extern u8 rtw_vht_2s_rates[]; -extern u8 *rtw_rate_section[]; -extern u8 rtw_rate_size[]; +extern const u8 rtw_cck_rates[]; +extern const u8 rtw_ofdm_rates[]; +extern const u8 rtw_ht_1s_rates[]; +extern const u8 rtw_ht_2s_rates[]; +extern const u8 rtw_vht_1s_rates[]; +extern const u8 rtw_vht_2s_rates[]; +extern const u8 rtw_ht_3s_rates[]; +extern const u8 rtw_ht_4s_rates[]; +extern const u8 rtw_vht_3s_rates[]; +extern const u8 rtw_vht_4s_rates[]; +extern const u8 * const rtw_rate_section[]; +extern const u8 rtw_rate_size[]; void rtw_phy_init(struct rtw_dev *rtwdev); void rtw_phy_dynamic_mechanism(struct rtw_dev *rtwdev); diff --git a/drivers/net/wireless/realtek/rtw88/reg.h b/drivers/net/wireless/realtek/rtw88/reg.h index e438405fba56..209b6fc08a73 100644 --- a/drivers/net/wireless/realtek/rtw88/reg.h +++ b/drivers/net/wireless/realtek/rtw88/reg.h @@ -130,6 +130,7 @@ #define BIT_SHIFT_ROM_PGE 16 #define BIT_FW_INIT_RDY BIT(15) #define BIT_FW_DW_RDY BIT(14) +#define BIT_CPU_CLK_SEL (BIT(12) | BIT(13)) #define BIT_RPWM_TOGGLE BIT(7) #define BIT_RAM_DL_SEL BIT(7) /* legacy only */ #define BIT_DMEM_CHKSUM_OK BIT(6) @@ -147,7 +148,7 @@ BIT_CHECK_SUM_OK) #define FW_READY_LEGACY (BIT_MCUFWDL_RDY | BIT_FWDL_CHK_RPT | \ BIT_WINTINI_RDY | BIT_RAM_DL_SEL) -#define FW_READY_MASK 0xffff +#define FW_READY_MASK (0xffff & ~BIT_CPU_CLK_SEL) #define REG_MCU_TST_CFG 0x84 #define VAL_FW_TRIGGER 0x1 diff --git a/drivers/net/wireless/realtek/rtw88/rtw8723d.c b/drivers/net/wireless/realtek/rtw88/rtw8723d.c index eeca31bf71f1..87715bd54860 100644 --- a/drivers/net/wireless/realtek/rtw88/rtw8723d.c +++ b/drivers/net/wireless/realtek/rtw88/rtw8723d.c @@ -444,7 +444,7 @@ static u8 rtw8723d_iqk_check_tx_failed(struct rtw_dev *rtwdev, rtw_read32(rtwdev, REG_IQK_RES_TX), rtw_read32(rtwdev, REG_IQK_RES_TY)); rtw_dbg(rtwdev, RTW_DBG_RFK, - "[IQK] 0xe90(before IQK)= 0x%x, 0xe98(afer IQK) = 0x%x\n", + "[IQK] 0xe90(before IQK)= 0x%x, 0xe98(after IQK) = 0x%x\n", rtw_read32(rtwdev, 0xe90), rtw_read32(rtwdev, 0xe98)); @@ -472,7 +472,7 @@ static u8 rtw8723d_iqk_check_rx_failed(struct rtw_dev *rtwdev, rtw_read32(rtwdev, REG_IQK_RES_RY)); rtw_dbg(rtwdev, RTW_DBG_RFK, - "[IQK] 0xea0(before IQK)= 0x%x, 0xea8(afer IQK) = 0x%x\n", + "[IQK] 0xea0(before IQK)= 0x%x, 0xea8(after IQK) = 0x%x\n", rtw_read32(rtwdev, 0xea0), rtw_read32(rtwdev, 0xea8)); diff --git a/drivers/net/wireless/realtek/rtw88/rtw8821c.c b/drivers/net/wireless/realtek/rtw88/rtw8821c.c index eb7e34c545d0..0ade7f11cbd2 100644 --- a/drivers/net/wireless/realtek/rtw88/rtw8821c.c +++ b/drivers/net/wireless/realtek/rtw88/rtw8821c.c @@ -680,11 +680,11 @@ static void query_phy_status(struct rtw_dev *rtwdev, u8 *phy_status, } static void -rtw8821c_set_tx_power_index_by_rate(struct rtw_dev *rtwdev, u8 path, u8 rs) +rtw8821c_set_tx_power_index_by_rate(struct rtw_dev *rtwdev, u8 path, + u8 rs, u32 *phy_pwr_idx) { struct rtw_hal *hal = &rtwdev->hal; static const u32 offset_txagc[2] = {0x1d00, 0x1d80}; - static u32 phy_pwr_idx; u8 rate, rate_idx, pwr_index, shift; int j; @@ -692,12 +692,12 @@ rtw8821c_set_tx_power_index_by_rate(struct rtw_dev *rtwdev, u8 path, u8 rs) rate = rtw_rate_section[rs][j]; pwr_index = hal->tx_pwr_tbl[path][rate]; shift = rate & 0x3; - phy_pwr_idx |= ((u32)pwr_index << (shift * 8)); + *phy_pwr_idx |= ((u32)pwr_index << (shift * 8)); if (shift == 0x3 || rate == DESC_RATEVHT1SS_MCS9) { rate_idx = rate & 0xfc; rtw_write32(rtwdev, offset_txagc[path] + rate_idx, - phy_pwr_idx); - phy_pwr_idx = 0; + *phy_pwr_idx); + *phy_pwr_idx = 0; } } } @@ -705,14 +705,16 @@ rtw8821c_set_tx_power_index_by_rate(struct rtw_dev *rtwdev, u8 path, u8 rs) static void rtw8821c_set_tx_power_index(struct rtw_dev *rtwdev) { struct rtw_hal *hal = &rtwdev->hal; + u32 phy_pwr_idx = 0; int rs, path; for (path = 0; path < hal->rf_path_num; path++) { - for (rs = 0; rs < RTW_RATE_SECTION_MAX; rs++) { + for (rs = 0; rs <= __RTW_RATE_SECTION_2SS_MAX; rs++) { if (rs == RTW_RATE_SECTION_HT_2S || rs == RTW_RATE_SECTION_VHT_2S) continue; - rtw8821c_set_tx_power_index_by_rate(rtwdev, path, rs); + rtw8821c_set_tx_power_index_by_rate(rtwdev, path, rs, + &phy_pwr_idx); } } } diff --git a/drivers/net/wireless/realtek/rtw88/rtw8822b.c b/drivers/net/wireless/realtek/rtw88/rtw8822b.c index 7f03903ddf4b..b4934da88e33 100644 --- a/drivers/net/wireless/realtek/rtw88/rtw8822b.c +++ b/drivers/net/wireless/realtek/rtw88/rtw8822b.c @@ -935,11 +935,11 @@ static void query_phy_status(struct rtw_dev *rtwdev, u8 *phy_status, } static void -rtw8822b_set_tx_power_index_by_rate(struct rtw_dev *rtwdev, u8 path, u8 rs) +rtw8822b_set_tx_power_index_by_rate(struct rtw_dev *rtwdev, u8 path, + u8 rs, u32 *phy_pwr_idx) { struct rtw_hal *hal = &rtwdev->hal; static const u32 offset_txagc[2] = {0x1d00, 0x1d80}; - static u32 phy_pwr_idx; u8 rate, rate_idx, pwr_index, shift; int j; @@ -947,12 +947,12 @@ rtw8822b_set_tx_power_index_by_rate(struct rtw_dev *rtwdev, u8 path, u8 rs) rate = rtw_rate_section[rs][j]; pwr_index = hal->tx_pwr_tbl[path][rate]; shift = rate & 0x3; - phy_pwr_idx |= ((u32)pwr_index << (shift * 8)); + *phy_pwr_idx |= ((u32)pwr_index << (shift * 8)); if (shift == 0x3) { rate_idx = rate & 0xfc; rtw_write32(rtwdev, offset_txagc[path] + rate_idx, - phy_pwr_idx); - phy_pwr_idx = 0; + *phy_pwr_idx); + *phy_pwr_idx = 0; } } } @@ -960,11 +960,13 @@ rtw8822b_set_tx_power_index_by_rate(struct rtw_dev *rtwdev, u8 path, u8 rs) static void rtw8822b_set_tx_power_index(struct rtw_dev *rtwdev) { struct rtw_hal *hal = &rtwdev->hal; + u32 phy_pwr_idx = 0; int rs, path; for (path = 0; path < hal->rf_path_num; path++) { - for (rs = 0; rs < RTW_RATE_SECTION_MAX; rs++) - rtw8822b_set_tx_power_index_by_rate(rtwdev, path, rs); + for (rs = 0; rs <= __RTW_RATE_SECTION_2SS_MAX; rs++) + rtw8822b_set_tx_power_index_by_rate(rtwdev, path, rs, + &phy_pwr_idx); } } diff --git a/drivers/net/wireless/realtek/rtw88/rtw8822c.c b/drivers/net/wireless/realtek/rtw88/rtw8822c.c index ec362a817f5f..5e53e0db177e 100644 --- a/drivers/net/wireless/realtek/rtw88/rtw8822c.c +++ b/drivers/net/wireless/realtek/rtw88/rtw8822c.c @@ -2746,7 +2746,7 @@ static void rtw8822c_set_tx_power_index(struct rtw_dev *rtwdev) s8 diff_idx[4]; rtw8822c_set_write_tx_power_ref(rtwdev, pwr_ref_cck, pwr_ref_ofdm); - for (rs = 0; rs < RTW_RATE_SECTION_MAX; rs++) { + for (rs = 0; rs <= __RTW_RATE_SECTION_2SS_MAX; rs++) { for (j = 0; j < rtw_rate_size[rs]; j++) { rate = rtw_rate_section[rs][j]; pwr_a = hal->tx_pwr_tbl[RF_PATH_A][rate]; diff --git a/drivers/net/wireless/realtek/rtw88/rtw88xxa.c b/drivers/net/wireless/realtek/rtw88/rtw88xxa.c index 71e61b9c0bec..0fa943271fb6 100644 --- a/drivers/net/wireless/realtek/rtw88/rtw88xxa.c +++ b/drivers/net/wireless/realtek/rtw88/rtw88xxa.c @@ -1637,7 +1637,7 @@ void rtw88xxa_set_tx_power_index(struct rtw_dev *rtwdev) int rs, path; for (path = 0; path < hal->rf_path_num; path++) { - for (rs = 0; rs < RTW_RATE_SECTION_MAX; rs++) { + for (rs = 0; rs <= __RTW_RATE_SECTION_2SS_MAX; rs++) { if (hal->rf_path_num == 1 && (rs == RTW_RATE_SECTION_HT_2S || rs == RTW_RATE_SECTION_VHT_2S)) diff --git a/drivers/net/wireless/realtek/rtw88/sar.c b/drivers/net/wireless/realtek/rtw88/sar.c index c472f1502b82..50b9c2412bb1 100644 --- a/drivers/net/wireless/realtek/rtw88/sar.c +++ b/drivers/net/wireless/realtek/rtw88/sar.c @@ -97,7 +97,7 @@ int rtw_set_sar_specs(struct rtw_dev *rtwdev, power, BIT(RTW_COMMON_SAR_FCT)); for (j = 0; j < RTW_RF_PATH_MAX; j++) { - for (k = 0; k < RTW_RATE_SECTION_MAX; k++) { + for (k = 0; k < RTW_RATE_SECTION_NUM; k++) { arg = (struct rtw_sar_arg){ .sar_band = idx, .path = j, diff --git a/drivers/net/wireless/realtek/rtw88/sdio.c b/drivers/net/wireless/realtek/rtw88/sdio.c index e024061bdbf7..6209a49312f1 100644 --- a/drivers/net/wireless/realtek/rtw88/sdio.c +++ b/drivers/net/wireless/realtek/rtw88/sdio.c @@ -1147,7 +1147,7 @@ static void rtw_sdio_declaim(struct rtw_dev *rtwdev, sdio_release_host(sdio_func); } -static struct rtw_hci_ops rtw_sdio_ops = { +static const struct rtw_hci_ops rtw_sdio_ops = { .tx_write = rtw_sdio_tx_write, .tx_kick_off = rtw_sdio_tx_kick_off, .setup = rtw_sdio_setup, diff --git a/drivers/net/wireless/realtek/rtw88/usb.c b/drivers/net/wireless/realtek/rtw88/usb.c index c4908db4ff0e..c8092fa0d9f1 100644 --- a/drivers/net/wireless/realtek/rtw88/usb.c +++ b/drivers/net/wireless/realtek/rtw88/usb.c @@ -881,7 +881,7 @@ static void rtw_usb_dynamic_rx_agg(struct rtw_dev *rtwdev, bool enable) } } -static struct rtw_hci_ops rtw_usb_ops = { +static const struct rtw_hci_ops rtw_usb_ops = { .tx_write = rtw_usb_tx_write, .tx_kick_off = rtw_usb_tx_kick_off, .setup = rtw_usb_setup, diff --git a/drivers/net/wireless/realtek/rtw89/Kconfig b/drivers/net/wireless/realtek/rtw89/Kconfig index b1c86cdd9c0e..205d7ecca7d7 100644 --- a/drivers/net/wireless/realtek/rtw89/Kconfig +++ b/drivers/net/wireless/realtek/rtw89/Kconfig @@ -123,7 +123,7 @@ config RTW89_DEBUGMSG config RTW89_DEBUGFS bool "Realtek rtw89 debugfs support" - depends on RTW89_CORE + depends on RTW89_CORE && CFG80211_DEBUGFS select RTW89_DEBUG help Enable debugfs support diff --git a/drivers/net/wireless/realtek/rtw89/chan.c b/drivers/net/wireless/realtek/rtw89/chan.c index 4df4e04c3e67..be6d73273910 100644 --- a/drivers/net/wireless/realtek/rtw89/chan.c +++ b/drivers/net/wireless/realtek/rtw89/chan.c @@ -155,7 +155,7 @@ int rtw89_iterate_entity_chan(struct rtw89_dev *rtwdev, int ret; u8 idx; - lockdep_assert_held(&rtwdev->mutex); + lockdep_assert_wiphy(rtwdev->hw->wiphy); for_each_set_bit(idx, hal->entity_map, NUM_OF_RTW89_CHANCTX) { chan = rtw89_chan_get(rtwdev, idx); @@ -310,7 +310,7 @@ const struct rtw89_chan *__rtw89_mgnt_chan_get(struct rtw89_dev *rtwdev, enum rtw89_entity_mode mode; u8 role_index; - lockdep_assert_held(&rtwdev->mutex); + lockdep_assert_wiphy(rtwdev->hw->wiphy); if (unlikely(link_index >= __RTW89_MLD_MAX_LINK_NUM)) { WARN(1, "link index %u is invalid (max link inst num: %d)\n", @@ -366,7 +366,7 @@ static void rtw89_entity_recalc_mgnt_roles(struct rtw89_dev *rtwdev) u8 pos = 0; int i, j; - lockdep_assert_held(&rtwdev->mutex); + lockdep_assert_wiphy(rtwdev->hw->wiphy); for (i = 0; i < RTW89_MAX_INTERFACE_NUM; i++) mgnt->active_roles[i] = NULL; @@ -427,7 +427,7 @@ enum rtw89_entity_mode rtw89_entity_recalc(struct rtw89_dev *rtwdev) struct rtw89_chan chan; u8 idx; - lockdep_assert_held(&rtwdev->mutex); + lockdep_assert_wiphy(rtwdev->hw->wiphy); bitmap_copy(recalc_map, hal->entity_map, NUM_OF_RTW89_CHANCTX); @@ -2390,7 +2390,7 @@ static void rtw89_mcc_update_limit(struct rtw89_dev *rtwdev) rtw89_iterate_mcc_roles(rtwdev, rtw89_mcc_upd_lmt_iterator, NULL); } -void rtw89_chanctx_work(struct work_struct *work) +void rtw89_chanctx_work(struct wiphy *wiphy, struct wiphy_work *work) { struct rtw89_dev *rtwdev = container_of(work, struct rtw89_dev, chanctx_work.work); @@ -2401,12 +2401,10 @@ void rtw89_chanctx_work(struct work_struct *work) int ret; int i; - mutex_lock(&rtwdev->mutex); + lockdep_assert_wiphy(wiphy); - if (hal->entity_pause) { - mutex_unlock(&rtwdev->mutex); + if (hal->entity_pause) return; - } for (i = 0; i < NUM_OF_RTW89_CHANCTX_CHANGES; i++) { if (test_and_clear_bit(i, hal->changes)) @@ -2445,8 +2443,6 @@ void rtw89_chanctx_work(struct work_struct *work) default: break; } - - mutex_unlock(&rtwdev->mutex); } void rtw89_queue_chanctx_change(struct rtw89_dev *rtwdev, @@ -2477,8 +2473,8 @@ void rtw89_queue_chanctx_change(struct rtw89_dev *rtwdev, rtw89_debug(rtwdev, RTW89_DBG_CHAN, "queue chanctx work for mode %d with delay %d us\n", mode, delay); - ieee80211_queue_delayed_work(rtwdev->hw, &rtwdev->chanctx_work, - usecs_to_jiffies(delay)); + wiphy_delayed_work_queue(rtwdev->hw->wiphy, &rtwdev->chanctx_work, + usecs_to_jiffies(delay)); } void rtw89_queue_chanctx_work(struct rtw89_dev *rtwdev) @@ -2491,7 +2487,7 @@ void rtw89_chanctx_track(struct rtw89_dev *rtwdev) struct rtw89_hal *hal = &rtwdev->hal; enum rtw89_entity_mode mode; - lockdep_assert_held(&rtwdev->mutex); + lockdep_assert_wiphy(rtwdev->hw->wiphy); if (hal->entity_pause) return; @@ -2512,7 +2508,7 @@ void rtw89_chanctx_pause(struct rtw89_dev *rtwdev, struct rtw89_hal *hal = &rtwdev->hal; enum rtw89_entity_mode mode; - lockdep_assert_held(&rtwdev->mutex); + lockdep_assert_wiphy(rtwdev->hw->wiphy); if (hal->entity_pause) return; @@ -2555,7 +2551,7 @@ void rtw89_chanctx_proceed(struct rtw89_dev *rtwdev, enum rtw89_entity_mode mode; int ret; - lockdep_assert_held(&rtwdev->mutex); + lockdep_assert_wiphy(rtwdev->hw->wiphy); if (unlikely(!hal->entity_pause)) { rtw89_chanctx_proceed_cb(rtwdev, cb_parm); diff --git a/drivers/net/wireless/realtek/rtw89/chan.h b/drivers/net/wireless/realtek/rtw89/chan.h index 092a6f676894..e6391f6f2aa7 100644 --- a/drivers/net/wireless/realtek/rtw89/chan.h +++ b/drivers/net/wireless/realtek/rtw89/chan.h @@ -99,7 +99,7 @@ void rtw89_config_roc_chandef(struct rtw89_dev *rtwdev, const struct cfg80211_chan_def *chandef); void rtw89_entity_init(struct rtw89_dev *rtwdev); enum rtw89_entity_mode rtw89_entity_recalc(struct rtw89_dev *rtwdev); -void rtw89_chanctx_work(struct work_struct *work); +void rtw89_chanctx_work(struct wiphy *wiphy, struct wiphy_work *work); void rtw89_queue_chanctx_work(struct rtw89_dev *rtwdev); void rtw89_queue_chanctx_change(struct rtw89_dev *rtwdev, enum rtw89_chanctx_changes change); diff --git a/drivers/net/wireless/realtek/rtw89/coex.c b/drivers/net/wireless/realtek/rtw89/coex.c index 68316d44b204..858ff0cd1a23 100644 --- a/drivers/net/wireless/realtek/rtw89/coex.c +++ b/drivers/net/wireless/realtek/rtw89/coex.c @@ -10,7 +10,7 @@ #include "ps.h" #include "reg.h" -#define RTW89_COEX_VERSION 0x07000113 +#define RTW89_COEX_VERSION 0x07000313 #define FCXDEF_STEP 50 /* MUST <= FCXMAX_STEP and match with wl fw*/ #define BTC_E2G_LIMIT_DEF 80 @@ -89,10 +89,10 @@ static const struct rtw89_btc_fbtc_slot s_def[] = { [CXST_B4] = __DEF_FBTC_SLOT(50, 0xe5555555, SLOT_MIX), [CXST_LK] = __DEF_FBTC_SLOT(20, 0xea5a5a5a, SLOT_ISO), [CXST_BLK] = __DEF_FBTC_SLOT(500, 0x55555555, SLOT_MIX), - [CXST_E2G] = __DEF_FBTC_SLOT(0, 0xea5a5a5a, SLOT_MIX), - [CXST_E5G] = __DEF_FBTC_SLOT(0, 0xffffffff, SLOT_ISO), + [CXST_E2G] = __DEF_FBTC_SLOT(5, 0xea5a5a5a, SLOT_MIX), + [CXST_E5G] = __DEF_FBTC_SLOT(5, 0xffffffff, SLOT_ISO), [CXST_EBT] = __DEF_FBTC_SLOT(5, 0xe5555555, SLOT_MIX), - [CXST_ENULL] = __DEF_FBTC_SLOT(0, 0xaaaaaaaa, SLOT_ISO), + [CXST_ENULL] = __DEF_FBTC_SLOT(5, 0xaaaaaaaa, SLOT_ISO), [CXST_WLK] = __DEF_FBTC_SLOT(250, 0xea5a5a5a, SLOT_MIX), [CXST_W1FDD] = __DEF_FBTC_SLOT(50, 0xffffffff, SLOT_ISO), [CXST_B1FDD] = __DEF_FBTC_SLOT(50, 0xffffdfff, SLOT_ISO), @@ -1602,7 +1602,7 @@ static u32 _chk_btc_report(struct rtw89_dev *rtwdev, wl->ver_info.fw = le32_to_cpu(prpt->v4.wl_fw_info.fw_ver); dm->wl_fw_cx_offload = !!le32_to_cpu(prpt->v4.wl_fw_info.cx_offload); - for (i = RTW89_PHY_0; i < RTW89_PHY_MAX; i++) + for (i = RTW89_PHY_0; i < RTW89_PHY_NUM; i++) memcpy(&dm->gnt.band[i], &prpt->v4.gnt_val[i], sizeof(dm->gnt.band[i])); @@ -1634,7 +1634,7 @@ static u32 _chk_btc_report(struct rtw89_dev *rtwdev, wl->ver_info.fw = le32_to_cpu(prpt->v5.rpt_info.fw_ver); dm->wl_fw_cx_offload = 0; - for (i = RTW89_PHY_0; i < RTW89_PHY_MAX; i++) + for (i = RTW89_PHY_0; i < RTW89_PHY_NUM; i++) memcpy(&dm->gnt.band[i], &prpt->v5.gnt_val[i][0], sizeof(dm->gnt.band[i])); @@ -1661,7 +1661,7 @@ static u32 _chk_btc_report(struct rtw89_dev *rtwdev, wl->ver_info.fw = le32_to_cpu(prpt->v105.rpt_info.fw_ver); dm->wl_fw_cx_offload = 0; - for (i = RTW89_PHY_0; i < RTW89_PHY_MAX; i++) + for (i = RTW89_PHY_0; i < RTW89_PHY_NUM; i++) memcpy(&dm->gnt.band[i], &prpt->v105.gnt_val[i][0], sizeof(dm->gnt.band[i])); @@ -1687,7 +1687,7 @@ static u32 _chk_btc_report(struct rtw89_dev *rtwdev, wl->ver_info.fw_coex = le32_to_cpu(prpt->v7.rpt_info.cx_ver); wl->ver_info.fw = le32_to_cpu(prpt->v7.rpt_info.fw_ver); - for (i = RTW89_PHY_0; i < RTW89_PHY_MAX; i++) + for (i = RTW89_PHY_0; i < RTW89_PHY_NUM; i++) memcpy(&dm->gnt.band[i], &prpt->v7.gnt_val[i][0], sizeof(dm->gnt.band[i])); @@ -1719,7 +1719,7 @@ static u32 _chk_btc_report(struct rtw89_dev *rtwdev, wl->ver_info.fw_coex = le32_to_cpu(prpt->v8.rpt_info.cx_ver); wl->ver_info.fw = le32_to_cpu(prpt->v8.rpt_info.fw_ver); - for (i = RTW89_PHY_0; i < RTW89_PHY_MAX; i++) + for (i = RTW89_PHY_0; i < RTW89_PHY_NUM; i++) memcpy(&dm->gnt.band[i], &prpt->v8.gnt_val[i][0], sizeof(dm->gnt.band[i])); @@ -2706,7 +2706,7 @@ static void _set_gnt(struct rtw89_dev *rtwdev, u8 phy_map, u8 wl_state, u8 bt_st if (phy_map > BTC_PHY_ALL) return; - for (i = 0; i < RTW89_PHY_MAX; i++) { + for (i = 0; i < RTW89_PHY_NUM; i++) { if (!(phy_map & BIT(i))) continue; @@ -2755,7 +2755,7 @@ static void _set_gnt_v1(struct rtw89_dev *rtwdev, u8 phy_map, if (phy_map > BTC_PHY_ALL) return; - for (i = 0; i < RTW89_PHY_MAX; i++) { + for (i = 0; i < RTW89_PHY_NUM; i++) { if (!(phy_map & BIT(i))) continue; @@ -2955,7 +2955,7 @@ static void _set_rf_trx_para(struct rtw89_dev *rtwdev) if (ver->fwlrole == 0) { link_mode = wl->role_info.link_mode; - for (i = 0; i < RTW89_PHY_MAX; i++) { + for (i = 0; i < RTW89_PHY_NUM; i++) { if (wl->dbcc_info.real_band[i] == RTW89_BAND_2G) dbcc_2g_phy = i; } @@ -4240,7 +4240,7 @@ static void _set_ant_v0(struct rtw89_dev *rtwdev, bool force_exec, case BTC_ANT_W2G: rtw89_chip_cfg_ctrl_path(rtwdev, BTC_CTRL_BY_WL); if (rtwdev->dbcc_en) { - for (i = 0; i < RTW89_PHY_MAX; i++) { + for (i = 0; i < RTW89_PHY_NUM; i++) { b2g = (wl_dinfo->real_band[i] == RTW89_BAND_2G); gnt_wl_ctrl = b2g ? BTC_GNT_HW : BTC_GNT_SW_HI; @@ -4583,23 +4583,16 @@ static void _action_bt_hid(struct rtw89_dev *rtwdev) static void _action_bt_a2dp(struct rtw89_dev *rtwdev) { struct rtw89_btc *btc = &rtwdev->btc; - struct rtw89_btc_bt_link_info *bt_linfo = &btc->cx.bt.link_info; - struct rtw89_btc_bt_a2dp_desc a2dp = bt_linfo->a2dp_desc; struct rtw89_btc_dm *dm = &btc->dm; _set_ant(rtwdev, NM_EXEC, BTC_PHY_ALL, BTC_ANT_W2G); + dm->slot_dur[CXST_W1] = 20; + dm->slot_dur[CXST_B1] = BTC_B1_MAX; + switch (btc->cx.state_map) { case BTC_WBUSY_BNOSCAN: /* wl-busy + bt-A2DP */ - if (a2dp.vendor_id == 0x4c || dm->leak_ap) { - dm->slot_dur[CXST_W1] = 40; - dm->slot_dur[CXST_B1] = 200; - _set_policy(rtwdev, - BTC_CXP_PAUTO_TDW1B1, BTC_ACT_BT_A2DP); - } else { - _set_policy(rtwdev, - BTC_CXP_PAUTO_TD50B1, BTC_ACT_BT_A2DP); - } + _set_policy(rtwdev, BTC_CXP_PAUTO_TDW1B1, BTC_ACT_BT_A2DP); break; case BTC_WBUSY_BSCAN: /* wl-busy + bt-inq + bt-A2DP */ _set_policy(rtwdev, BTC_CXP_PAUTO2_TD3050, BTC_ACT_BT_A2DP); @@ -4609,15 +4602,10 @@ static void _action_bt_a2dp(struct rtw89_dev *rtwdev) break; case BTC_WSCAN_BNOSCAN: /* wl-scan + bt-A2DP */ case BTC_WLINKING: /* wl-connecting + bt-A2DP */ - if (a2dp.vendor_id == 0x4c || dm->leak_ap) { - dm->slot_dur[CXST_W1] = 40; - dm->slot_dur[CXST_B1] = 200; - _set_policy(rtwdev, BTC_CXP_AUTO_TDW1B1, - BTC_ACT_BT_A2DP); - } else { - _set_policy(rtwdev, BTC_CXP_AUTO_TD50B1, - BTC_ACT_BT_A2DP); - } + if (btc->cx.wl.rfk_info.con_rfk) + _set_policy(rtwdev, BTC_CXP_OFF_BT, BTC_ACT_BT_A2DP); + else + _set_policy(rtwdev, BTC_CXP_AUTO_TDW1B1, BTC_ACT_BT_A2DP); break; case BTC_WIDLE: /* wl-idle + bt-A2DP */ _set_policy(rtwdev, BTC_CXP_AUTO_TD20B1, BTC_ACT_BT_A2DP); @@ -4645,7 +4633,10 @@ static void _action_bt_a2dpsink(struct rtw89_dev *rtwdev) _set_policy(rtwdev, BTC_CXP_FIX_TD2060, BTC_ACT_BT_A2DPSINK); break; case BTC_WLINKING: /* wl-connecting + bt-A2dp_Sink */ - _set_policy(rtwdev, BTC_CXP_FIX_TD3030, BTC_ACT_BT_A2DPSINK); + if (btc->cx.wl.rfk_info.con_rfk) + _set_policy(rtwdev, BTC_CXP_OFF_BT, BTC_ACT_BT_A2DPSINK); + else + _set_policy(rtwdev, BTC_CXP_FIX_TD3030, BTC_ACT_BT_A2DPSINK); break; case BTC_WIDLE: /* wl-idle + bt-A2dp_Sink */ _set_policy(rtwdev, BTC_CXP_FIX_TD2080, BTC_ACT_BT_A2DPSINK); @@ -4693,27 +4684,20 @@ static void _action_bt_pan(struct rtw89_dev *rtwdev) static void _action_bt_a2dp_hid(struct rtw89_dev *rtwdev) { struct rtw89_btc *btc = &rtwdev->btc; - struct rtw89_btc_bt_link_info *bt_linfo = &btc->cx.bt.link_info; - struct rtw89_btc_bt_a2dp_desc a2dp = bt_linfo->a2dp_desc; struct rtw89_btc_dm *dm = &btc->dm; _set_ant(rtwdev, NM_EXEC, BTC_PHY_ALL, BTC_ANT_W2G); + dm->slot_dur[CXST_W1] = 20; + dm->slot_dur[CXST_B1] = BTC_B1_MAX; + switch (btc->cx.state_map) { case BTC_WBUSY_BNOSCAN: /* wl-busy + bt-A2DP+HID */ case BTC_WIDLE: /* wl-idle + bt-A2DP */ - if (a2dp.vendor_id == 0x4c || dm->leak_ap) { - dm->slot_dur[CXST_W1] = 40; - dm->slot_dur[CXST_B1] = 200; - _set_policy(rtwdev, - BTC_CXP_PAUTO_TDW1B1, BTC_ACT_BT_A2DP_HID); - } else { - _set_policy(rtwdev, - BTC_CXP_PAUTO_TD50B1, BTC_ACT_BT_A2DP_HID); - } + _set_policy(rtwdev, BTC_CXP_PAUTO_TDW1B1, BTC_ACT_BT_A2DP_HID); break; case BTC_WBUSY_BSCAN: /* wl-busy + bt-inq + bt-A2DP+HID */ - _set_policy(rtwdev, BTC_CXP_PAUTO2_TD3050, BTC_ACT_BT_A2DP_HID); + _set_policy(rtwdev, BTC_CXP_PAUTO2_TD3070, BTC_ACT_BT_A2DP_HID); break; case BTC_WSCAN_BSCAN: /* wl-scan + bt-inq + bt-A2DP+HID */ @@ -4721,15 +4705,10 @@ static void _action_bt_a2dp_hid(struct rtw89_dev *rtwdev) break; case BTC_WSCAN_BNOSCAN: /* wl-scan + bt-A2DP+HID */ case BTC_WLINKING: /* wl-connecting + bt-A2DP+HID */ - if (a2dp.vendor_id == 0x4c || dm->leak_ap) { - dm->slot_dur[CXST_W1] = 40; - dm->slot_dur[CXST_B1] = 200; - _set_policy(rtwdev, BTC_CXP_AUTO_TDW1B1, - BTC_ACT_BT_A2DP_HID); - } else { - _set_policy(rtwdev, BTC_CXP_AUTO_TD50B1, - BTC_ACT_BT_A2DP_HID); - } + if (btc->cx.wl.rfk_info.con_rfk) + _set_policy(rtwdev, BTC_CXP_OFF_BT, BTC_ACT_BT_A2DP_HID); + else + _set_policy(rtwdev, BTC_CXP_AUTO_TDW1B1, BTC_ACT_BT_A2DP_HID); break; } } @@ -4905,9 +4884,9 @@ static void _set_btg_ctrl(struct rtw89_dev *rtwdev) if (rtwdev->dbcc_en) { if (ver->fwlrole == 0) { - wl_rinfo.dbcc_2g_phy = RTW89_PHY_MAX; + wl_rinfo.dbcc_2g_phy = RTW89_PHY_NUM; - for (i = 0; i < RTW89_PHY_MAX; i++) { + for (i = 0; i < RTW89_PHY_NUM; i++) { if (wl_dinfo->real_band[i] == RTW89_BAND_2G) wl_rinfo.dbcc_2g_phy = i; } @@ -5408,7 +5387,8 @@ static void _action_wl_scan(struct rtw89_dev *rtwdev) struct rtw89_btc_wl_info *wl = &btc->cx.wl; struct rtw89_btc_wl_dbcc_info *wl_dinfo = &wl->dbcc_info; - if (RTW89_CHK_FW_FEATURE(SCAN_OFFLOAD, &rtwdev->fw)) { + if (btc->cx.state_map != BTC_WLINKING && + RTW89_CHK_FW_FEATURE(SCAN_OFFLOAD, &rtwdev->fw)) { _action_wl_25g_mcc(rtwdev); rtw89_debug(rtwdev, RTW89_DBG_BTC, "[BTC], Scan offload!\n"); } else if (rtwdev->dbcc_en) { @@ -5798,7 +5778,7 @@ static void _update_wl_info(struct rtw89_dev *rtwdev) phy = wl_linfo[i].phy; /* check dbcc role */ - if (rtwdev->dbcc_en && phy < RTW89_PHY_MAX) { + if (rtwdev->dbcc_en && phy < RTW89_PHY_NUM) { wl_dinfo->role[phy] = wl_linfo[i].role; wl_dinfo->op_band[phy] = wl_linfo[i].band; _update_dbcc_band(rtwdev, phy); @@ -5948,7 +5928,7 @@ static void _update_wl_info_v1(struct rtw89_dev *rtwdev) phy = wl_linfo[i].phy; - if (rtwdev->dbcc_en && phy < RTW89_PHY_MAX) { + if (rtwdev->dbcc_en && phy < RTW89_PHY_NUM) { wl_dinfo->role[phy] = wl_linfo[i].role; wl_dinfo->op_band[phy] = wl_linfo[i].band; _update_dbcc_band(rtwdev, phy); @@ -6098,7 +6078,7 @@ static void _update_wl_info_v2(struct rtw89_dev *rtwdev) phy = wl_linfo[i].phy; - if (rtwdev->dbcc_en && phy < RTW89_PHY_MAX) { + if (rtwdev->dbcc_en && phy < RTW89_PHY_NUM) { wl_dinfo->role[phy] = wl_linfo[i].role; wl_dinfo->op_band[phy] = wl_linfo[i].band; _update_dbcc_band(rtwdev, phy); @@ -6389,7 +6369,7 @@ static void _update_wl_info_v7(struct rtw89_dev *rtwdev, u8 rid) struct rtw89_btc_wl_dbcc_info *wl_dinfo = &wl->dbcc_info; struct rtw89_btc_wl_link_info *wl_linfo = wl->link_info; struct rtw89_btc_wl_active_role_v7 *act_role = NULL; - u8 i, mode, cnt = 0, cnt_2g = 0, cnt_5g = 0, phy_now = RTW89_PHY_MAX, phy_dbcc; + u8 i, mode, cnt = 0, cnt_2g = 0, cnt_5g = 0, phy_now = RTW89_PHY_NUM, phy_dbcc; bool b2g = false, b5g = false, client_joined = false, client_inc_2g = false; u8 client_cnt_last[RTW89_BE_BTC_WL_MAX_ROLE_NUMBER] = {}; u8 cid_role[RTW89_BE_BTC_WL_MAX_ROLE_NUMBER] = {}; @@ -6400,7 +6380,7 @@ static void _update_wl_info_v7(struct rtw89_dev *rtwdev, u8 rid) memset(wl_rinfo, 0, sizeof(*wl_rinfo)); for (i = 0; i < RTW89_PORT_NUM; i++) { - if (!wl_linfo[i].active || wl_linfo[i].phy >= RTW89_PHY_MAX) + if (!wl_linfo[i].active || wl_linfo[i].phy >= RTW89_PHY_NUM) continue; act_role = &wl_rinfo->active_role[i]; @@ -6494,7 +6474,7 @@ static void _update_wl_info_v7(struct rtw89_dev *rtwdev, u8 rid) mode = _chk_dbcc(rtwdev, cid_ch, cid_phy, cid_role, &dbcc_2g_phy); /* correct 2G-located PHY band for gnt ctrl */ - if (dbcc_2g_phy < RTW89_PHY_MAX) + if (dbcc_2g_phy < RTW89_PHY_NUM) wl_dinfo->op_band[dbcc_2g_phy] = RTW89_BAND_2G; } else if (b2g && b5g && cnt == 2) { mode = BTC_WLINK_25G_MCC; @@ -6720,7 +6700,7 @@ static void _update_wl_info_v8(struct rtw89_dev *rtwdev, u8 role_id, u8 rlink_id _fw_set_drv_info(rtwdev, CXDRVINFO_ROLE); } -void rtw89_coex_act1_work(struct work_struct *work) +void rtw89_coex_act1_work(struct wiphy *wiphy, struct wiphy_work *work) { struct rtw89_dev *rtwdev = container_of(work, struct rtw89_dev, coex_act1_work.work); @@ -6729,7 +6709,8 @@ void rtw89_coex_act1_work(struct work_struct *work) struct rtw89_btc_cx *cx = &btc->cx; struct rtw89_btc_wl_info *wl = &cx->wl; - mutex_lock(&rtwdev->mutex); + lockdep_assert_wiphy(wiphy); + rtw89_debug(rtwdev, RTW89_DBG_BTC, "[BTC], %s(): enter\n", __func__); dm->cnt_notify[BTC_NCNT_TIMER]++; if (wl->status.map._4way) @@ -6738,10 +6719,9 @@ void rtw89_coex_act1_work(struct work_struct *work) wl->status.map.connecting = false; _run_coex(rtwdev, BTC_RSN_ACT1_WORK); - mutex_unlock(&rtwdev->mutex); } -void rtw89_coex_bt_devinfo_work(struct work_struct *work) +void rtw89_coex_bt_devinfo_work(struct wiphy *wiphy, struct wiphy_work *work) { struct rtw89_dev *rtwdev = container_of(work, struct rtw89_dev, coex_bt_devinfo_work.work); @@ -6749,15 +6729,15 @@ void rtw89_coex_bt_devinfo_work(struct work_struct *work) struct rtw89_btc_dm *dm = &rtwdev->btc.dm; struct rtw89_btc_bt_a2dp_desc *a2dp = &btc->cx.bt.link_info.a2dp_desc; - mutex_lock(&rtwdev->mutex); + lockdep_assert_wiphy(wiphy); + rtw89_debug(rtwdev, RTW89_DBG_BTC, "[BTC], %s(): enter\n", __func__); dm->cnt_notify[BTC_NCNT_TIMER]++; a2dp->play_latency = 0; _run_coex(rtwdev, BTC_RSN_BT_DEVINFO_WORK); - mutex_unlock(&rtwdev->mutex); } -void rtw89_coex_rfk_chk_work(struct work_struct *work) +void rtw89_coex_rfk_chk_work(struct wiphy *wiphy, struct wiphy_work *work) { struct rtw89_dev *rtwdev = container_of(work, struct rtw89_dev, coex_rfk_chk_work.work); @@ -6766,7 +6746,8 @@ void rtw89_coex_rfk_chk_work(struct work_struct *work) struct rtw89_btc_cx *cx = &btc->cx; struct rtw89_btc_wl_info *wl = &cx->wl; - mutex_lock(&rtwdev->mutex); + lockdep_assert_wiphy(wiphy); + rtw89_debug(rtwdev, RTW89_DBG_BTC, "[BTC], %s(): enter\n", __func__); dm->cnt_notify[BTC_NCNT_TIMER]++; if (wl->rfk_info.state != BTC_WRFK_STOP) { @@ -6778,7 +6759,6 @@ void rtw89_coex_rfk_chk_work(struct work_struct *work) _write_scbd(rtwdev, BTC_WSCB_WLRFK, false); _run_coex(rtwdev, BTC_RSN_RFK_CHK_WORK); } - mutex_unlock(&rtwdev->mutex); } static void _update_bt_scbd(struct rtw89_dev *rtwdev, bool only_update) @@ -6882,7 +6862,7 @@ void _run_coex(struct rtw89_dev *rtwdev, enum btc_reason_and_action reason) struct rtw89_btc_wl_role_info_v8 *wl_rinfo_v8 = &wl->role_info_v8; u8 mode, igno_bt, always_freerun; - lockdep_assert_held(&rtwdev->mutex); + lockdep_assert_wiphy(rtwdev->hw->wiphy); dm->run_reason = reason; _update_dm_step(rtwdev, reason); @@ -7002,7 +6982,7 @@ void _run_coex(struct rtw89_dev *rtwdev, enum btc_reason_and_action reason) goto exit; } - if (wl->status.val & btc_scanning_map.val) { + if (wl->status.val & btc_scanning_map.val && !wl->rfk_info.con_rfk) { _action_wl_scan(rtwdev); bt->scan_rx_low_pri = true; goto exit; @@ -7187,7 +7167,7 @@ void rtw89_btc_ntfy_scan_start(struct rtw89_dev *rtwdev, u8 phy_idx, u8 band) "[BTC], %s(): phy_idx=%d, band=%d\n", __func__, phy_idx, band); - if (phy_idx >= RTW89_PHY_MAX) + if (phy_idx >= RTW89_PHY_NUM) return; btc->dm.cnt_notify[BTC_NCNT_SCAN_START]++; @@ -7223,6 +7203,8 @@ void rtw89_btc_ntfy_scan_finish(struct rtw89_dev *rtwdev, u8 phy_idx) _fw_set_drv_info(rtwdev, CXDRVINFO_DBCC); } + btc->dm.tdma_instant_excute = 1; + _run_coex(rtwdev, BTC_RSN_NTFY_SCAN_FINISH); } @@ -7235,7 +7217,7 @@ void rtw89_btc_ntfy_switch_band(struct rtw89_dev *rtwdev, u8 phy_idx, u8 band) "[BTC], %s(): phy_idx=%d, band=%d\n", __func__, phy_idx, band); - if (phy_idx >= RTW89_PHY_MAX) + if (phy_idx >= RTW89_PHY_NUM) return; btc->dm.cnt_notify[BTC_NCNT_SWITCH_BAND]++; @@ -7284,7 +7266,7 @@ void rtw89_btc_ntfy_specific_packet(struct rtw89_dev *rtwdev, "[BTC], %s(): EAPOL_End cnt=%d\n", __func__, cnt); wl->status.map._4way = false; - cancel_delayed_work(&rtwdev->coex_act1_work); + wiphy_delayed_work_cancel(rtwdev->hw->wiphy, &rtwdev->coex_act1_work); break; case PACKET_ARP: cnt = ++cx->cnt_wl[BTC_WCNT_ARP]; @@ -7303,56 +7285,56 @@ void rtw89_btc_ntfy_specific_packet(struct rtw89_dev *rtwdev, } if (delay_work) { - cancel_delayed_work(&rtwdev->coex_act1_work); - ieee80211_queue_delayed_work(rtwdev->hw, - &rtwdev->coex_act1_work, delay); + wiphy_delayed_work_cancel(rtwdev->hw->wiphy, &rtwdev->coex_act1_work); + wiphy_delayed_work_queue(rtwdev->hw->wiphy, + &rtwdev->coex_act1_work, delay); } btc->dm.cnt_notify[BTC_NCNT_SPECIAL_PACKET]++; _run_coex(rtwdev, BTC_RSN_NTFY_SPECIFIC_PACKET); } -void rtw89_btc_ntfy_eapol_packet_work(struct work_struct *work) +void rtw89_btc_ntfy_eapol_packet_work(struct wiphy *wiphy, struct wiphy_work *work) { struct rtw89_dev *rtwdev = container_of(work, struct rtw89_dev, btc.eapol_notify_work); - mutex_lock(&rtwdev->mutex); + lockdep_assert_wiphy(wiphy); + rtw89_leave_ps_mode(rtwdev); rtw89_btc_ntfy_specific_packet(rtwdev, PACKET_EAPOL); - mutex_unlock(&rtwdev->mutex); } -void rtw89_btc_ntfy_arp_packet_work(struct work_struct *work) +void rtw89_btc_ntfy_arp_packet_work(struct wiphy *wiphy, struct wiphy_work *work) { struct rtw89_dev *rtwdev = container_of(work, struct rtw89_dev, btc.arp_notify_work); - mutex_lock(&rtwdev->mutex); + lockdep_assert_wiphy(wiphy); + rtw89_btc_ntfy_specific_packet(rtwdev, PACKET_ARP); - mutex_unlock(&rtwdev->mutex); } -void rtw89_btc_ntfy_dhcp_packet_work(struct work_struct *work) +void rtw89_btc_ntfy_dhcp_packet_work(struct wiphy *wiphy, struct wiphy_work *work) { struct rtw89_dev *rtwdev = container_of(work, struct rtw89_dev, btc.dhcp_notify_work); - mutex_lock(&rtwdev->mutex); + lockdep_assert_wiphy(wiphy); + rtw89_leave_ps_mode(rtwdev); rtw89_btc_ntfy_specific_packet(rtwdev, PACKET_DHCP); - mutex_unlock(&rtwdev->mutex); } -void rtw89_btc_ntfy_icmp_packet_work(struct work_struct *work) +void rtw89_btc_ntfy_icmp_packet_work(struct wiphy *wiphy, struct wiphy_work *work) { struct rtw89_dev *rtwdev = container_of(work, struct rtw89_dev, btc.icmp_notify_work); - mutex_lock(&rtwdev->mutex); + lockdep_assert_wiphy(wiphy); + rtw89_leave_ps_mode(rtwdev); rtw89_btc_ntfy_specific_packet(rtwdev, PACKET_ICMP); - mutex_unlock(&rtwdev->mutex); } static u8 _update_bt_rssi_level(struct rtw89_dev *rtwdev, u8 rssi) @@ -7531,9 +7513,9 @@ static void _update_bt_info(struct rtw89_dev *rtwdev, u8 *buf, u32 len) a2dp->vendor_id = 0; a2dp->flush_time = 0; a2dp->play_latency = 1; - ieee80211_queue_delayed_work(rtwdev->hw, - &rtwdev->coex_bt_devinfo_work, - RTW89_COEX_BT_DEVINFO_WORK_PERIOD); + wiphy_delayed_work_queue(rtwdev->hw->wiphy, + &rtwdev->coex_bt_devinfo_work, + RTW89_COEX_BT_DEVINFO_WORK_PERIOD); } _run_coex(rtwdev, BTC_RSN_UPDATE_BT_INFO); @@ -7671,7 +7653,8 @@ void rtw89_btc_ntfy_role_info(struct rtw89_dev *rtwdev, else wl->status.map.connecting = 0; - if (state == BTC_ROLE_MSTS_STA_DIS_CONN) + if (state == BTC_ROLE_MSTS_STA_DIS_CONN || + state == BTC_ROLE_MSTS_STA_CONN_END) wl->status.map._4way = false; _run_coex(rtwdev, BTC_RSN_NTFY_ROLE_INFO); @@ -7781,7 +7764,7 @@ static bool _ntfy_wl_rfk(struct rtw89_dev *rtwdev, u8 phy_path, wl->rfk_info.state = BTC_WRFK_STOP; _write_scbd(rtwdev, BTC_WSCB_WLRFK, false); - cancel_delayed_work(&rtwdev->coex_rfk_chk_work); + wiphy_delayed_work_cancel(rtwdev->hw->wiphy, &rtwdev->coex_rfk_chk_work); break; default: rtw89_debug(rtwdev, RTW89_DBG_BTC, @@ -7795,9 +7778,9 @@ static bool _ntfy_wl_rfk(struct rtw89_dev *rtwdev, u8 phy_path, _run_coex(rtwdev, BTC_RSN_NTFY_WL_RFK); if (wl->rfk_info.state == BTC_WRFK_START) - ieee80211_queue_delayed_work(rtwdev->hw, - &rtwdev->coex_rfk_chk_work, - RTW89_COEX_RFK_CHK_WORK_PERIOD); + wiphy_delayed_work_queue(rtwdev->hw->wiphy, + &rtwdev->coex_rfk_chk_work, + RTW89_COEX_RFK_CHK_WORK_PERIOD); } rtw89_debug(rtwdev, RTW89_DBG_BTC, @@ -7815,6 +7798,8 @@ void rtw89_btc_ntfy_wl_rfk(struct rtw89_dev *rtwdev, u8 phy_map, bool allow; int ret; + lockdep_assert_wiphy(rtwdev->hw->wiphy); + band = FIELD_GET(BTC_RFK_BAND_MAP, phy_map); rtw89_debug(rtwdev, RTW89_DBG_RFK, @@ -8156,7 +8141,7 @@ void rtw89_btc_c2h_handle(struct rtw89_dev *rtwdev, struct sk_buff *skb, #define BTC_CX_FW_OFFLOAD 0 -static void _show_cx_info(struct rtw89_dev *rtwdev, struct seq_file *m) +static int _show_cx_info(struct rtw89_dev *rtwdev, char *buf, size_t bufsz) { union rtw89_btc_module_info *md = &rtwdev->btc.mdinfo; const struct rtw89_chip_info *chip = rtwdev->chip; @@ -8168,40 +8153,43 @@ static void _show_cx_info(struct rtw89_dev *rtwdev, struct seq_file *m) struct rtw89_btc_wl_info *wl = &btc->cx.wl; u32 ver_main = 0, ver_sub = 0, ver_hotfix = 0, id_branch = 0; u8 cv, rfe, iso, ant_num, ant_single_pos; + char *p = buf, *end = buf + bufsz; if (!(dm->coex_info_map & BTC_COEX_INFO_CX)) - return; + return 0; dm->cnt_notify[BTC_NCNT_SHOW_COEX_INFO]++; - seq_printf(m, "========== [BTC COEX INFO (%d)] ==========\n", - chip->chip_id); + p += scnprintf(p, end - p, + "========== [BTC COEX INFO (%d)] ==========\n", + chip->chip_id); ver_main = FIELD_GET(GENMASK(31, 24), RTW89_COEX_VERSION); ver_sub = FIELD_GET(GENMASK(23, 16), RTW89_COEX_VERSION); ver_hotfix = FIELD_GET(GENMASK(15, 8), RTW89_COEX_VERSION); id_branch = FIELD_GET(GENMASK(7, 0), RTW89_COEX_VERSION); - seq_printf(m, " %-15s : Coex:%d.%d.%d(branch:%d), ", - "[coex_version]", ver_main, ver_sub, ver_hotfix, id_branch); + p += scnprintf(p, end - p, " %-15s : Coex:%d.%d.%d(branch:%d), ", + "[coex_version]", ver_main, ver_sub, ver_hotfix, + id_branch); ver_main = FIELD_GET(GENMASK(31, 24), wl->ver_info.fw_coex); ver_sub = FIELD_GET(GENMASK(23, 16), wl->ver_info.fw_coex); ver_hotfix = FIELD_GET(GENMASK(15, 8), wl->ver_info.fw_coex); id_branch = FIELD_GET(GENMASK(7, 0), wl->ver_info.fw_coex); - seq_printf(m, "WL_FW_coex:%d.%d.%d(branch:%d)", - ver_main, ver_sub, ver_hotfix, id_branch); + p += scnprintf(p, end - p, "WL_FW_coex:%d.%d.%d(branch:%d)", + ver_main, ver_sub, ver_hotfix, id_branch); ver_main = FIELD_GET(GENMASK(31, 24), chip->wlcx_desired); ver_sub = FIELD_GET(GENMASK(23, 16), chip->wlcx_desired); ver_hotfix = FIELD_GET(GENMASK(15, 8), chip->wlcx_desired); - seq_printf(m, "(%s, desired:%d.%d.%d), ", - (wl->ver_info.fw_coex >= chip->wlcx_desired ? - "Match" : "Mismatch"), ver_main, ver_sub, ver_hotfix); + p += scnprintf(p, end - p, "(%s, desired:%d.%d.%d), ", + (wl->ver_info.fw_coex >= chip->wlcx_desired ? + "Match" : "Mismatch"), ver_main, ver_sub, ver_hotfix); - seq_printf(m, "BT_FW_coex:%d(%s, desired:%d)\n", - bt->ver_info.fw_coex, - (bt->ver_info.fw_coex >= chip->btcx_desired ? - "Match" : "Mismatch"), chip->btcx_desired); + p += scnprintf(p, end - p, "BT_FW_coex:%d(%s, desired:%d)\n", + bt->ver_info.fw_coex, + (bt->ver_info.fw_coex >= chip->btcx_desired ? + "Match" : "Mismatch"), chip->btcx_desired); if (bt->enable.now && bt->ver_info.fw == 0) rtw89_btc_fw_en_rpt(rtwdev, RPT_EN_BT_VER_INFO, true); @@ -8212,10 +8200,11 @@ static void _show_cx_info(struct rtw89_dev *rtwdev, struct seq_file *m) ver_sub = FIELD_GET(GENMASK(23, 16), wl->ver_info.fw); ver_hotfix = FIELD_GET(GENMASK(15, 8), wl->ver_info.fw); id_branch = FIELD_GET(GENMASK(7, 0), wl->ver_info.fw); - seq_printf(m, " %-15s : WL_FW:%d.%d.%d.%d, BT_FW:0x%x(%s)\n", - "[sub_module]", - ver_main, ver_sub, ver_hotfix, id_branch, - bt->ver_info.fw, bt->run_patch_code ? "patch" : "ROM"); + p += scnprintf(p, end - p, + " %-15s : WL_FW:%d.%d.%d.%d, BT_FW:0x%x(%s)\n", + "[sub_module]", + ver_main, ver_sub, ver_hotfix, id_branch, + bt->ver_info.fw, bt->run_patch_code ? "patch" : "ROM"); if (ver->fcxinit == 7) { cv = md->md_v7.kt_ver; @@ -8231,36 +8220,41 @@ static void _show_cx_info(struct rtw89_dev *rtwdev, struct seq_file *m) ant_single_pos = md->md.ant.single_pos; } - seq_printf(m, " %-15s : cv:%x, rfe_type:0x%x, ant_iso:%d, ant_pg:%d, %s", - "[hw_info]", cv, rfe, iso, ant_num, - ant_num > 1 ? "" : - ant_single_pos ? "1Ant_Pos:S1, " : "1Ant_Pos:S0, "); + p += scnprintf(p, end - p, + " %-15s : cv:%x, rfe_type:0x%x, ant_iso:%d, ant_pg:%d, %s", + "[hw_info]", cv, rfe, iso, ant_num, + ant_num > 1 ? "" : + ant_single_pos ? "1Ant_Pos:S1, " : "1Ant_Pos:S0, "); - seq_printf(m, "3rd_coex:%d, dbcc:%d, tx_num:%d, rx_num:%d\n", - btc->cx.other.type, rtwdev->dbcc_en, hal->tx_nss, - hal->rx_nss); + p += scnprintf(p, end - p, + "3rd_coex:%d, dbcc:%d, tx_num:%d, rx_num:%d\n", + btc->cx.other.type, rtwdev->dbcc_en, hal->tx_nss, + hal->rx_nss); + + return p - buf; } -static void _show_wl_role_info(struct rtw89_dev *rtwdev, struct seq_file *m) +static int _show_wl_role_info(struct rtw89_dev *rtwdev, char *buf, size_t bufsz) { struct rtw89_btc *btc = &rtwdev->btc; struct rtw89_btc_wl_link_info *plink = NULL; struct rtw89_btc_wl_info *wl = &btc->cx.wl; struct rtw89_btc_wl_dbcc_info *wl_dinfo = &wl->dbcc_info; struct rtw89_traffic_stats *t; + char *p = buf, *end = buf + bufsz; u8 i; if (rtwdev->dbcc_en) { - seq_printf(m, - " %-15s : PHY0_band(op:%d/scan:%d/real:%d), ", - "[dbcc_info]", wl_dinfo->op_band[RTW89_PHY_0], - wl_dinfo->scan_band[RTW89_PHY_0], - wl_dinfo->real_band[RTW89_PHY_0]); - seq_printf(m, - "PHY1_band(op:%d/scan:%d/real:%d)\n", - wl_dinfo->op_band[RTW89_PHY_1], - wl_dinfo->scan_band[RTW89_PHY_1], - wl_dinfo->real_band[RTW89_PHY_1]); + p += scnprintf(p, end - p, + " %-15s : PHY0_band(op:%d/scan:%d/real:%d), ", + "[dbcc_info]", wl_dinfo->op_band[RTW89_PHY_0], + wl_dinfo->scan_band[RTW89_PHY_0], + wl_dinfo->real_band[RTW89_PHY_0]); + p += scnprintf(p, end - p, + "PHY1_band(op:%d/scan:%d/real:%d)\n", + wl_dinfo->op_band[RTW89_PHY_1], + wl_dinfo->scan_band[RTW89_PHY_1], + wl_dinfo->real_band[RTW89_PHY_1]); } for (i = 0; i < RTW89_PORT_NUM; i++) { @@ -8272,38 +8266,41 @@ static void _show_wl_role_info(struct rtw89_dev *rtwdev, struct seq_file *m) if (!plink->active) continue; - seq_printf(m, - " [port_%d] : role=%d(phy-%d), connect=%d(client_cnt=%d), mode=%d, center_ch=%d, bw=%d", - plink->pid, (u32)plink->role, plink->phy, - (u32)plink->connected, plink->client_cnt - 1, - (u32)plink->mode, plink->ch, (u32)plink->bw); + p += scnprintf(p, end - p, + " [port_%d] : role=%d(phy-%d), connect=%d(client_cnt=%d), mode=%d, center_ch=%d, bw=%d", + plink->pid, (u32)plink->role, plink->phy, + (u32)plink->connected, plink->client_cnt - 1, + (u32)plink->mode, plink->ch, (u32)plink->bw); if (plink->connected == MLME_NO_LINK) continue; - seq_printf(m, - ", mac_id=%d, max_tx_time=%dus, max_tx_retry=%d\n", - plink->mac_id, plink->tx_time, plink->tx_retry); + p += scnprintf(p, end - p, + ", mac_id=%d, max_tx_time=%dus, max_tx_retry=%d\n", + plink->mac_id, plink->tx_time, plink->tx_retry); - seq_printf(m, - " [port_%d] : rssi=-%ddBm(%d), busy=%d, dir=%s, ", - plink->pid, 110 - plink->stat.rssi, - plink->stat.rssi, plink->busy, - plink->dir == RTW89_TFC_UL ? "UL" : "DL"); + p += scnprintf(p, end - p, + " [port_%d] : rssi=-%ddBm(%d), busy=%d, dir=%s, ", + plink->pid, 110 - plink->stat.rssi, + plink->stat.rssi, plink->busy, + plink->dir == RTW89_TFC_UL ? "UL" : "DL"); t = &plink->stat.traffic; - seq_printf(m, - "tx[rate:%d/busy_level:%d], ", - (u32)t->tx_rate, t->tx_tfc_lv); + p += scnprintf(p, end - p, + "tx[rate:%d/busy_level:%d], ", + (u32)t->tx_rate, t->tx_tfc_lv); - seq_printf(m, "rx[rate:%d/busy_level:%d/drop:%d]\n", - (u32)t->rx_rate, - t->rx_tfc_lv, plink->rx_rate_drop_cnt); + p += scnprintf(p, end - p, + "rx[rate:%d/busy_level:%d/drop:%d]\n", + (u32)t->rx_rate, + t->rx_tfc_lv, plink->rx_rate_drop_cnt); } + + return p - buf; } -static void _show_wl_info(struct rtw89_dev *rtwdev, struct seq_file *m) +static int _show_wl_info(struct rtw89_dev *rtwdev, char *buf, size_t bufsz) { struct rtw89_btc *btc = &rtwdev->btc; const struct rtw89_btc_ver *ver = btc->ver; @@ -8314,12 +8311,13 @@ static void _show_wl_info(struct rtw89_dev *rtwdev, struct seq_file *m) struct rtw89_btc_wl_role_info_v2 *wl_rinfo_v2 = &wl->role_info_v2; struct rtw89_btc_wl_role_info_v7 *wl_rinfo_v7 = &wl->role_info_v7; struct rtw89_btc_wl_role_info_v8 *wl_rinfo_v8 = &wl->role_info_v8; + char *p = buf, *end = buf + bufsz; u8 mode; if (!(btc->dm.coex_info_map & BTC_COEX_INFO_WL)) - return; + return 0; - seq_puts(m, "========== [WL Status] ==========\n"); + p += scnprintf(p, end - p, "========== [WL Status] ==========\n"); if (ver->fwlrole == 0) mode = wl_rinfo->link_mode; @@ -8332,24 +8330,28 @@ static void _show_wl_info(struct rtw89_dev *rtwdev, struct seq_file *m) else if (ver->fwlrole == 8) mode = wl_rinfo_v8->link_mode; else - return; + goto out; - seq_printf(m, " %-15s : link_mode:%d, ", "[status]", mode); + p += scnprintf(p, end - p, " %-15s : link_mode:%d, ", "[status]", + mode); - seq_printf(m, - "rf_off:%d, power_save:%d, scan:%s(band:%d/phy_map:0x%x), ", - wl->status.map.rf_off, wl->status.map.lps, - wl->status.map.scan ? "Y" : "N", - wl->scan_info.band[RTW89_PHY_0], wl->scan_info.phy_map); + p += scnprintf(p, end - p, + "rf_off:%d, power_save:%d, scan:%s(band:%d/phy_map:0x%x), ", + wl->status.map.rf_off, wl->status.map.lps, + wl->status.map.scan ? "Y" : "N", + wl->scan_info.band[RTW89_PHY_0], wl->scan_info.phy_map); - seq_printf(m, - "connecting:%s, roam:%s, 4way:%s, init_ok:%s\n", - wl->status.map.connecting ? "Y" : "N", - wl->status.map.roaming ? "Y" : "N", - wl->status.map._4way ? "Y" : "N", - wl->status.map.init_ok ? "Y" : "N"); + p += scnprintf(p, end - p, + "connecting:%s, roam:%s, 4way:%s, init_ok:%s\n", + wl->status.map.connecting ? "Y" : "N", + wl->status.map.roaming ? "Y" : "N", + wl->status.map._4way ? "Y" : "N", + wl->status.map.init_ok ? "Y" : "N"); - _show_wl_role_info(rtwdev, m); + p += _show_wl_role_info(rtwdev, p, end - p); + +out: + return p - buf; } enum btc_bt_a2dp_type { @@ -8358,7 +8360,7 @@ enum btc_bt_a2dp_type { BTC_A2DP_TWS_RELAY = 2, }; -static void _show_bt_profile_info(struct rtw89_dev *rtwdev, struct seq_file *m) +static int _show_bt_profile_info(struct rtw89_dev *rtwdev, char *buf, size_t bufsz) { struct rtw89_btc *btc = &rtwdev->btc; struct rtw89_btc_bt_link_info *bt_linfo = &btc->cx.bt.link_info; @@ -8366,50 +8368,55 @@ static void _show_bt_profile_info(struct rtw89_dev *rtwdev, struct seq_file *m) struct rtw89_btc_bt_hid_desc hid = bt_linfo->hid_desc; struct rtw89_btc_bt_a2dp_desc a2dp = bt_linfo->a2dp_desc; struct rtw89_btc_bt_pan_desc pan = bt_linfo->pan_desc; + char *p = buf, *end = buf + bufsz; if (hfp.exist) { - seq_printf(m, " %-15s : type:%s, sut_pwr:%d, golden-rx:%d", - "[HFP]", (hfp.type == 0 ? "SCO" : "eSCO"), - bt_linfo->sut_pwr_level[0], - bt_linfo->golden_rx_shift[0]); + p += scnprintf(p, end - p, + " %-15s : type:%s, sut_pwr:%d, golden-rx:%d", + "[HFP]", (hfp.type == 0 ? "SCO" : "eSCO"), + bt_linfo->sut_pwr_level[0], + bt_linfo->golden_rx_shift[0]); } if (hid.exist) { - seq_printf(m, - "\n\r %-15s : type:%s%s%s%s%s pair-cnt:%d, sut_pwr:%d, golden-rx:%d\n", - "[HID]", - hid.type & BTC_HID_218 ? "2/18," : "", - hid.type & BTC_HID_418 ? "4/18," : "", - hid.type & BTC_HID_BLE ? "BLE," : "", - hid.type & BTC_HID_RCU ? "RCU," : "", - hid.type & BTC_HID_RCU_VOICE ? "RCU-Voice," : "", - hid.pair_cnt, bt_linfo->sut_pwr_level[1], - bt_linfo->golden_rx_shift[1]); + p += scnprintf(p, end - p, + "\n\r %-15s : type:%s%s%s%s%s pair-cnt:%d, sut_pwr:%d, golden-rx:%d\n", + "[HID]", + hid.type & BTC_HID_218 ? "2/18," : "", + hid.type & BTC_HID_418 ? "4/18," : "", + hid.type & BTC_HID_BLE ? "BLE," : "", + hid.type & BTC_HID_RCU ? "RCU," : "", + hid.type & BTC_HID_RCU_VOICE ? "RCU-Voice," : "", + hid.pair_cnt, bt_linfo->sut_pwr_level[1], + bt_linfo->golden_rx_shift[1]); } if (a2dp.exist) { - seq_printf(m, - " %-15s : type:%s, bit-pool:%d, flush-time:%d, ", - "[A2DP]", - a2dp.type == BTC_A2DP_LEGACY ? "Legacy" : "TWS", - a2dp.bitpool, a2dp.flush_time); + p += scnprintf(p, end - p, + " %-15s : type:%s, bit-pool:%d, flush-time:%d, ", + "[A2DP]", + a2dp.type == BTC_A2DP_LEGACY ? "Legacy" : "TWS", + a2dp.bitpool, a2dp.flush_time); - seq_printf(m, - "vid:0x%x, Dev-name:0x%x, sut_pwr:%d, golden-rx:%d\n", - a2dp.vendor_id, a2dp.device_name, - bt_linfo->sut_pwr_level[2], - bt_linfo->golden_rx_shift[2]); + p += scnprintf(p, end - p, + "vid:0x%x, Dev-name:0x%x, sut_pwr:%d, golden-rx:%d\n", + a2dp.vendor_id, a2dp.device_name, + bt_linfo->sut_pwr_level[2], + bt_linfo->golden_rx_shift[2]); } if (pan.exist) { - seq_printf(m, " %-15s : sut_pwr:%d, golden-rx:%d\n", - "[PAN]", - bt_linfo->sut_pwr_level[3], - bt_linfo->golden_rx_shift[3]); + p += scnprintf(p, end - p, + " %-15s : sut_pwr:%d, golden-rx:%d\n", + "[PAN]", + bt_linfo->sut_pwr_level[3], + bt_linfo->golden_rx_shift[3]); } + + return p - buf; } -static void _show_bt_info(struct rtw89_dev *rtwdev, struct seq_file *m) +static int _show_bt_info(struct rtw89_dev *rtwdev, char *buf, size_t bufsz) { struct rtw89_btc *btc = &rtwdev->btc; const struct rtw89_btc_ver *ver = btc->ver; @@ -8418,129 +8425,136 @@ static void _show_bt_info(struct rtw89_dev *rtwdev, struct seq_file *m) struct rtw89_btc_wl_info *wl = &cx->wl; struct rtw89_btc_bt_link_info *bt_linfo = &bt->link_info; union rtw89_btc_module_info *md = &btc->mdinfo; + char *p = buf, *end = buf + bufsz; u8 *afh = bt_linfo->afh_map; u8 *afh_le = bt_linfo->afh_map_le; u8 bt_pos; if (!(btc->dm.coex_info_map & BTC_COEX_INFO_BT)) - return; + return 0; if (ver->fcxinit == 7) bt_pos = md->md_v7.bt_pos; else bt_pos = md->md.bt_pos; - seq_puts(m, "========== [BT Status] ==========\n"); - - seq_printf(m, " %-15s : enable:%s, btg:%s%s, connect:%s, ", - "[status]", bt->enable.now ? "Y" : "N", - bt->btg_type ? "Y" : "N", - (bt->enable.now && (bt->btg_type != bt_pos) ? - "(efuse-mismatch!!)" : ""), - (bt_linfo->status.map.connect ? "Y" : "N")); - - seq_printf(m, "igno_wl:%s, mailbox_avl:%s, rfk_state:0x%x\n", - bt->igno_wl ? "Y" : "N", - bt->mbx_avl ? "Y" : "N", bt->rfk_info.val); - - seq_printf(m, " %-15s : profile:%s%s%s%s%s ", - "[profile]", - (bt_linfo->profile_cnt.now == 0) ? "None," : "", - bt_linfo->hfp_desc.exist ? "HFP," : "", - bt_linfo->hid_desc.exist ? "HID," : "", - bt_linfo->a2dp_desc.exist ? - (bt_linfo->a2dp_desc.sink ? "A2DP_sink," : "A2DP,") : "", - bt_linfo->pan_desc.exist ? "PAN," : ""); - - seq_printf(m, - "multi-link:%s, role:%s, ble-connect:%s, CQDDR:%s, A2DP_active:%s, PAN_active:%s\n", - bt_linfo->multi_link.now ? "Y" : "N", - bt_linfo->slave_role ? "Slave" : "Master", - bt_linfo->status.map.ble_connect ? "Y" : "N", - bt_linfo->cqddr ? "Y" : "N", - bt_linfo->a2dp_desc.active ? "Y" : "N", - bt_linfo->pan_desc.active ? "Y" : "N"); - - seq_printf(m, - " %-15s : rssi:%ddBm(lvl:%d), tx_rate:%dM, %s%s%s", - "[link]", bt_linfo->rssi - 100, - bt->rssi_level, - bt_linfo->tx_3m ? 3 : 2, - bt_linfo->status.map.inq_pag ? " inq-page!!" : "", - bt_linfo->status.map.acl_busy ? " acl_busy!!" : "", - bt_linfo->status.map.mesh_busy ? " mesh_busy!!" : ""); - - seq_printf(m, - "%s afh_map[%02x%02x_%02x%02x_%02x%02x_%02x%02x_%02x%02x], ", - bt_linfo->relink.now ? " ReLink!!" : "", - afh[0], afh[1], afh[2], afh[3], afh[4], - afh[5], afh[6], afh[7], afh[8], afh[9]); + p += scnprintf(p, end - p, "========== [BT Status] ==========\n"); + + p += scnprintf(p, end - p, + " %-15s : enable:%s, btg:%s%s, connect:%s, ", + "[status]", bt->enable.now ? "Y" : "N", + bt->btg_type ? "Y" : "N", + (bt->enable.now && (bt->btg_type != bt_pos) ? + "(efuse-mismatch!!)" : ""), + (bt_linfo->status.map.connect ? "Y" : "N")); + + p += scnprintf(p, end - p, + "igno_wl:%s, mailbox_avl:%s, rfk_state:0x%x\n", + bt->igno_wl ? "Y" : "N", + bt->mbx_avl ? "Y" : "N", bt->rfk_info.val); + + p += scnprintf(p, end - p, " %-15s : profile:%s%s%s%s%s ", + "[profile]", + (bt_linfo->profile_cnt.now == 0) ? "None," : "", + bt_linfo->hfp_desc.exist ? "HFP," : "", + bt_linfo->hid_desc.exist ? "HID," : "", + bt_linfo->a2dp_desc.exist ? + (bt_linfo->a2dp_desc.sink ? "A2DP_sink," : "A2DP,") : "", + bt_linfo->pan_desc.exist ? "PAN," : ""); + + p += scnprintf(p, end - p, + "multi-link:%s, role:%s, ble-connect:%s, CQDDR:%s, A2DP_active:%s, PAN_active:%s\n", + bt_linfo->multi_link.now ? "Y" : "N", + bt_linfo->slave_role ? "Slave" : "Master", + bt_linfo->status.map.ble_connect ? "Y" : "N", + bt_linfo->cqddr ? "Y" : "N", + bt_linfo->a2dp_desc.active ? "Y" : "N", + bt_linfo->pan_desc.active ? "Y" : "N"); + + p += scnprintf(p, end - p, + " %-15s : rssi:%ddBm(lvl:%d), tx_rate:%dM, %s%s%s", + "[link]", bt_linfo->rssi - 100, + bt->rssi_level, + bt_linfo->tx_3m ? 3 : 2, + bt_linfo->status.map.inq_pag ? " inq-page!!" : "", + bt_linfo->status.map.acl_busy ? " acl_busy!!" : "", + bt_linfo->status.map.mesh_busy ? " mesh_busy!!" : ""); + + p += scnprintf(p, end - p, + "%s afh_map[%02x%02x_%02x%02x_%02x%02x_%02x%02x_%02x%02x], ", + bt_linfo->relink.now ? " ReLink!!" : "", + afh[0], afh[1], afh[2], afh[3], afh[4], + afh[5], afh[6], afh[7], afh[8], afh[9]); if (ver->fcxbtafh == 2 && bt_linfo->status.map.ble_connect) - seq_printf(m, - "LE[%02x%02x_%02x_%02x%02x]", - afh_le[0], afh_le[1], afh_le[2], - afh_le[3], afh_le[4]); - - seq_printf(m, "wl_ch_map[en:%d/ch:%d/bw:%d]\n", - wl->afh_info.en, wl->afh_info.ch, wl->afh_info.bw); - - seq_printf(m, - " %-15s : retry:%d, relink:%d, rate_chg:%d, reinit:%d, reenable:%d, ", - "[stat_cnt]", cx->cnt_bt[BTC_BCNT_RETRY], - cx->cnt_bt[BTC_BCNT_RELINK], cx->cnt_bt[BTC_BCNT_RATECHG], - cx->cnt_bt[BTC_BCNT_REINIT], cx->cnt_bt[BTC_BCNT_REENABLE]); - - seq_printf(m, - "role-switch:%d, afh:%d, inq_page:%d(inq:%d/page:%d), igno_wl:%d\n", - cx->cnt_bt[BTC_BCNT_ROLESW], cx->cnt_bt[BTC_BCNT_AFH], - cx->cnt_bt[BTC_BCNT_INQPAG], cx->cnt_bt[BTC_BCNT_INQ], - cx->cnt_bt[BTC_BCNT_PAGE], cx->cnt_bt[BTC_BCNT_IGNOWL]); - - _show_bt_profile_info(rtwdev, m); - - seq_printf(m, - " %-15s : raw_data[%02x %02x %02x %02x %02x %02x] (type:%s/cnt:%d/same:%d)\n", - "[bt_info]", bt->raw_info[2], bt->raw_info[3], - bt->raw_info[4], bt->raw_info[5], bt->raw_info[6], - bt->raw_info[7], - bt->raw_info[0] == BTC_BTINFO_AUTO ? "auto" : "reply", - cx->cnt_bt[BTC_BCNT_INFOUPDATE], - cx->cnt_bt[BTC_BCNT_INFOSAME]); - - seq_printf(m, - " %-15s : Hi-rx = %d, Hi-tx = %d, Lo-rx = %d, Lo-tx = %d (bt_polut_wl_tx = %d)", - "[trx_req_cnt]", cx->cnt_bt[BTC_BCNT_HIPRI_RX], - cx->cnt_bt[BTC_BCNT_HIPRI_TX], cx->cnt_bt[BTC_BCNT_LOPRI_RX], - cx->cnt_bt[BTC_BCNT_LOPRI_TX], cx->cnt_bt[BTC_BCNT_POLUT]); + p += scnprintf(p, end - p, + "LE[%02x%02x_%02x_%02x%02x]", + afh_le[0], afh_le[1], afh_le[2], + afh_le[3], afh_le[4]); + + p += scnprintf(p, end - p, "wl_ch_map[en:%d/ch:%d/bw:%d]\n", + wl->afh_info.en, wl->afh_info.ch, wl->afh_info.bw); + + p += scnprintf(p, end - p, + " %-15s : retry:%d, relink:%d, rate_chg:%d, reinit:%d, reenable:%d, ", + "[stat_cnt]", cx->cnt_bt[BTC_BCNT_RETRY], + cx->cnt_bt[BTC_BCNT_RELINK], + cx->cnt_bt[BTC_BCNT_RATECHG], + cx->cnt_bt[BTC_BCNT_REINIT], + cx->cnt_bt[BTC_BCNT_REENABLE]); + + p += scnprintf(p, end - p, + "role-switch:%d, afh:%d, inq_page:%d(inq:%d/page:%d), igno_wl:%d\n", + cx->cnt_bt[BTC_BCNT_ROLESW], cx->cnt_bt[BTC_BCNT_AFH], + cx->cnt_bt[BTC_BCNT_INQPAG], cx->cnt_bt[BTC_BCNT_INQ], + cx->cnt_bt[BTC_BCNT_PAGE], cx->cnt_bt[BTC_BCNT_IGNOWL]); + + p += _show_bt_profile_info(rtwdev, p, end - p); + + p += scnprintf(p, end - p, + " %-15s : raw_data[%02x %02x %02x %02x %02x %02x] (type:%s/cnt:%d/same:%d)\n", + "[bt_info]", bt->raw_info[2], bt->raw_info[3], + bt->raw_info[4], bt->raw_info[5], bt->raw_info[6], + bt->raw_info[7], + bt->raw_info[0] == BTC_BTINFO_AUTO ? "auto" : "reply", + cx->cnt_bt[BTC_BCNT_INFOUPDATE], + cx->cnt_bt[BTC_BCNT_INFOSAME]); + + p += scnprintf(p, end - p, + " %-15s : Hi-rx = %d, Hi-tx = %d, Lo-rx = %d, Lo-tx = %d (bt_polut_wl_tx = %d)", + "[trx_req_cnt]", cx->cnt_bt[BTC_BCNT_HIPRI_RX], + cx->cnt_bt[BTC_BCNT_HIPRI_TX], + cx->cnt_bt[BTC_BCNT_LOPRI_RX], + cx->cnt_bt[BTC_BCNT_LOPRI_TX], + cx->cnt_bt[BTC_BCNT_POLUT]); if (!bt->scan_info_update) { rtw89_btc_fw_en_rpt(rtwdev, RPT_EN_BT_SCAN_INFO, true); - seq_puts(m, "\n"); + p += scnprintf(p, end - p, "\n"); } else { rtw89_btc_fw_en_rpt(rtwdev, RPT_EN_BT_SCAN_INFO, false); if (ver->fcxbtscan == 1) { - seq_printf(m, - "(INQ:%d-%d/PAGE:%d-%d/LE:%d-%d/INIT:%d-%d)", - le16_to_cpu(bt->scan_info_v1[BTC_SCAN_INQ].win), - le16_to_cpu(bt->scan_info_v1[BTC_SCAN_INQ].intvl), - le16_to_cpu(bt->scan_info_v1[BTC_SCAN_PAGE].win), - le16_to_cpu(bt->scan_info_v1[BTC_SCAN_PAGE].intvl), - le16_to_cpu(bt->scan_info_v1[BTC_SCAN_BLE].win), - le16_to_cpu(bt->scan_info_v1[BTC_SCAN_BLE].intvl), - le16_to_cpu(bt->scan_info_v1[BTC_SCAN_INIT].win), - le16_to_cpu(bt->scan_info_v1[BTC_SCAN_INIT].intvl)); + p += scnprintf(p, end - p, + "(INQ:%d-%d/PAGE:%d-%d/LE:%d-%d/INIT:%d-%d)", + le16_to_cpu(bt->scan_info_v1[BTC_SCAN_INQ].win), + le16_to_cpu(bt->scan_info_v1[BTC_SCAN_INQ].intvl), + le16_to_cpu(bt->scan_info_v1[BTC_SCAN_PAGE].win), + le16_to_cpu(bt->scan_info_v1[BTC_SCAN_PAGE].intvl), + le16_to_cpu(bt->scan_info_v1[BTC_SCAN_BLE].win), + le16_to_cpu(bt->scan_info_v1[BTC_SCAN_BLE].intvl), + le16_to_cpu(bt->scan_info_v1[BTC_SCAN_INIT].win), + le16_to_cpu(bt->scan_info_v1[BTC_SCAN_INIT].intvl)); } else if (ver->fcxbtscan == 2) { - seq_printf(m, - "(BG:%d-%d/INIT:%d-%d/LE:%d-%d)", - le16_to_cpu(bt->scan_info_v2[CXSCAN_BG].win), - le16_to_cpu(bt->scan_info_v2[CXSCAN_BG].intvl), - le16_to_cpu(bt->scan_info_v2[CXSCAN_INIT].win), - le16_to_cpu(bt->scan_info_v2[CXSCAN_INIT].intvl), - le16_to_cpu(bt->scan_info_v2[CXSCAN_LE].win), - le16_to_cpu(bt->scan_info_v2[CXSCAN_LE].intvl)); + p += scnprintf(p, end - p, + "(BG:%d-%d/INIT:%d-%d/LE:%d-%d)", + le16_to_cpu(bt->scan_info_v2[CXSCAN_BG].win), + le16_to_cpu(bt->scan_info_v2[CXSCAN_BG].intvl), + le16_to_cpu(bt->scan_info_v2[CXSCAN_INIT].win), + le16_to_cpu(bt->scan_info_v2[CXSCAN_INIT].intvl), + le16_to_cpu(bt->scan_info_v2[CXSCAN_LE].win), + le16_to_cpu(bt->scan_info_v2[CXSCAN_LE].intvl)); } - seq_puts(m, "\n"); + p += scnprintf(p, end - p, "\n"); } if (bt_linfo->profile_cnt.now || bt_linfo->status.map.ble_connect) @@ -8560,6 +8574,8 @@ static void _show_bt_info(struct rtw89_dev *rtwdev, struct seq_file *m) rtw89_btc_fw_en_rpt(rtwdev, RPT_EN_BT_DEVICE_INFO, true); else rtw89_btc_fw_en_rpt(rtwdev, RPT_EN_BT_DEVICE_INFO, false); + + return p - buf; } #define CASE_BTC_RSN_STR(e) case BTC_RSN_ ## e: return #e @@ -8853,114 +8869,132 @@ static const char *id_to_ant(u32 id) } static -void seq_print_segment(struct seq_file *m, const char *prefix, u16 *data, - u8 len, u8 seg_len, u8 start_idx, u8 ring_len) +int scnprintf_segment(char *buf, size_t bufsz, const char *prefix, const u16 *data, + u8 len, u8 seg_len, u8 start_idx, u8 ring_len) { - u8 i; + char *p = buf, *end = buf + bufsz; u8 cur_index; + u8 i; for (i = 0; i < len ; i++) { if ((i % seg_len) == 0) - seq_printf(m, " %-15s : ", prefix); + p += scnprintf(p, end - p, " %-15s : ", prefix); cur_index = (start_idx + i) % ring_len; if (i % 3 == 0) - seq_printf(m, "-> %-20s", - steps_to_str(*(data + cur_index))); + p += scnprintf(p, end - p, "-> %-20s", + steps_to_str(*(data + cur_index))); else if (i % 3 == 1) - seq_printf(m, "-> %-15s", - steps_to_str(*(data + cur_index))); + p += scnprintf(p, end - p, "-> %-15s", + steps_to_str(*(data + cur_index))); else - seq_printf(m, "-> %-13s", - steps_to_str(*(data + cur_index))); + p += scnprintf(p, end - p, "-> %-13s", + steps_to_str(*(data + cur_index))); if (i == (len - 1) || (i % seg_len) == (seg_len - 1)) - seq_puts(m, "\n"); + p += scnprintf(p, end - p, "\n"); } + + return p - buf; } -static void _show_dm_step(struct rtw89_dev *rtwdev, struct seq_file *m) +static int _show_dm_step(struct rtw89_dev *rtwdev, char *buf, size_t bufsz) { struct rtw89_btc *btc = &rtwdev->btc; struct rtw89_btc_dm *dm = &btc->dm; + char *p = buf, *end = buf + bufsz; u8 start_idx; u8 len; len = dm->dm_step.step_ov ? RTW89_BTC_DM_MAXSTEP : dm->dm_step.step_pos; start_idx = dm->dm_step.step_ov ? dm->dm_step.step_pos : 0; - seq_print_segment(m, "[dm_steps]", dm->dm_step.step, len, 6, start_idx, - ARRAY_SIZE(dm->dm_step.step)); + p += scnprintf_segment(p, end - p, "[dm_steps]", dm->dm_step.step, len, + 6, start_idx, ARRAY_SIZE(dm->dm_step.step)); + + return p - buf; } -static void _show_dm_info(struct rtw89_dev *rtwdev, struct seq_file *m) +static int _show_dm_info(struct rtw89_dev *rtwdev, char *buf, size_t bufsz) { struct rtw89_btc *btc = &rtwdev->btc; const struct rtw89_btc_ver *ver = btc->ver; struct rtw89_btc_dm *dm = &btc->dm; struct rtw89_btc_wl_info *wl = &btc->cx.wl; struct rtw89_btc_bt_info *bt = &btc->cx.bt; + char *p = buf, *end = buf + bufsz; u8 igno_bt; if (!(dm->coex_info_map & BTC_COEX_INFO_DM)) - return; + return 0; - seq_printf(m, "========== [Mechanism Status %s] ==========\n", - (btc->manual_ctrl ? "(Manual)" : "(Auto)")); + p += scnprintf(p, end - p, + "========== [Mechanism Status %s] ==========\n", + (btc->manual_ctrl ? "(Manual)" : "(Auto)")); - seq_printf(m, - " %-15s : type:%s, reason:%s(), action:%s(), ant_path:%s, init_mode:%s, run_cnt:%d\n", - "[status]", - btc->ant_type == BTC_ANT_SHARED ? "shared" : "dedicated", - steps_to_str(dm->run_reason), - steps_to_str(dm->run_action | BTC_ACT_EXT_BIT), - id_to_ant(FIELD_GET(GENMASK(7, 0), dm->set_ant_path)), - id_to_mode(wl->coex_mode), - dm->cnt_dm[BTC_DCNT_RUN]); + p += scnprintf(p, end - p, + " %-15s : type:%s, reason:%s(), action:%s(), ant_path:%s, init_mode:%s, run_cnt:%d\n", + "[status]", + btc->ant_type == BTC_ANT_SHARED ? "shared" : "dedicated", + steps_to_str(dm->run_reason), + steps_to_str(dm->run_action | BTC_ACT_EXT_BIT), + id_to_ant(FIELD_GET(GENMASK(7, 0), dm->set_ant_path)), + id_to_mode(wl->coex_mode), + dm->cnt_dm[BTC_DCNT_RUN]); - _show_dm_step(rtwdev, m); + p += _show_dm_step(rtwdev, p, end - p); if (ver->fcxctrl == 7) igno_bt = btc->ctrl.ctrl_v7.igno_bt; else igno_bt = btc->ctrl.ctrl.igno_bt; - seq_printf(m, " %-15s : wl_only:%d, bt_only:%d, igno_bt:%d, free_run:%d, wl_ps_ctrl:%d, wl_mimo_ps:%d, ", - "[dm_flag]", dm->wl_only, dm->bt_only, igno_bt, - dm->freerun, btc->lps, dm->wl_mimo_ps); + p += scnprintf(p, end - p, + " %-15s : wl_only:%d, bt_only:%d, igno_bt:%d, free_run:%d, wl_ps_ctrl:%d, wl_mimo_ps:%d, ", + "[dm_flag]", dm->wl_only, dm->bt_only, igno_bt, + dm->freerun, btc->lps, dm->wl_mimo_ps); - seq_printf(m, "leak_ap:%d, fw_offload:%s%s\n", dm->leak_ap, - (BTC_CX_FW_OFFLOAD ? "Y" : "N"), - (dm->wl_fw_cx_offload == BTC_CX_FW_OFFLOAD ? - "" : "(Mismatch!!)")); + p += scnprintf(p, end - p, "leak_ap:%d, fw_offload:%s%s\n", + dm->leak_ap, + (BTC_CX_FW_OFFLOAD ? "Y" : "N"), + (dm->wl_fw_cx_offload == BTC_CX_FW_OFFLOAD ? + "" : "(Mismatch!!)")); if (dm->rf_trx_para.wl_tx_power == 0xff) - seq_printf(m, - " %-15s : wl_rssi_lvl:%d, para_lvl:%d, wl_tx_pwr:orig, ", - "[trx_ctrl]", wl->rssi_level, dm->trx_para_level); + p += scnprintf(p, end - p, + " %-15s : wl_rssi_lvl:%d, para_lvl:%d, wl_tx_pwr:orig, ", + "[trx_ctrl]", wl->rssi_level, + dm->trx_para_level); else - seq_printf(m, - " %-15s : wl_rssi_lvl:%d, para_lvl:%d, wl_tx_pwr:%d, ", - "[trx_ctrl]", wl->rssi_level, dm->trx_para_level, - dm->rf_trx_para.wl_tx_power); + p += scnprintf(p, end - p, + " %-15s : wl_rssi_lvl:%d, para_lvl:%d, wl_tx_pwr:%d, ", + "[trx_ctrl]", wl->rssi_level, + dm->trx_para_level, + dm->rf_trx_para.wl_tx_power); + + p += scnprintf(p, end - p, + "wl_rx_lvl:%d, bt_tx_pwr_dec:%d, bt_rx_lna:%d(%s-tbl), wl_btg_rx:%d\n", + dm->rf_trx_para.wl_rx_gain, + dm->rf_trx_para.bt_tx_power, + dm->rf_trx_para.bt_rx_gain, + (bt->hi_lna_rx ? "Hi" : "Ori"), dm->wl_btg_rx); - seq_printf(m, - "wl_rx_lvl:%d, bt_tx_pwr_dec:%d, bt_rx_lna:%d(%s-tbl), wl_btg_rx:%d\n", - dm->rf_trx_para.wl_rx_gain, dm->rf_trx_para.bt_tx_power, - dm->rf_trx_para.bt_rx_gain, - (bt->hi_lna_rx ? "Hi" : "Ori"), dm->wl_btg_rx); + p += scnprintf(p, end - p, + " %-15s : wl_tx_limit[en:%d/max_t:%dus/max_retry:%d], bt_slot_reg:%d-TU, bt_scan_rx_low_pri:%d\n", + "[dm_ctrl]", dm->wl_tx_limit.enable, + dm->wl_tx_limit.tx_time, + dm->wl_tx_limit.tx_retry, btc->bt_req_len, + bt->scan_rx_low_pri); - seq_printf(m, - " %-15s : wl_tx_limit[en:%d/max_t:%dus/max_retry:%d], bt_slot_reg:%d-TU, bt_scan_rx_low_pri:%d\n", - "[dm_ctrl]", dm->wl_tx_limit.enable, dm->wl_tx_limit.tx_time, - dm->wl_tx_limit.tx_retry, btc->bt_req_len, bt->scan_rx_low_pri); + return p - buf; } -static void _show_error(struct rtw89_dev *rtwdev, struct seq_file *m) +static int _show_error(struct rtw89_dev *rtwdev, char *buf, size_t bufsz) { struct rtw89_btc *btc = &rtwdev->btc; const struct rtw89_btc_ver *ver = btc->ver; struct rtw89_btc_btf_fwinfo *pfwinfo = &btc->fwinfo; union rtw89_btc_fbtc_cysta_info *pcysta; + char *p = buf, *end = buf + bufsz; u32 except_cnt, exception_map; pcysta = &pfwinfo->rpt_fbtc_cysta.finfo; @@ -8985,81 +9019,87 @@ static void _show_error(struct rtw89_dev *rtwdev, struct seq_file *m) except_cnt = pcysta->v7.except_cnt; exception_map = le32_to_cpu(pcysta->v7.except_map); } else { - return; + return 0; } if (pfwinfo->event[BTF_EVNT_BUF_OVERFLOW] == 0 && except_cnt == 0 && !pfwinfo->len_mismch && !pfwinfo->fver_mismch) - return; + return 0; - seq_printf(m, " %-15s : ", "[error]"); + p += scnprintf(p, end - p, " %-15s : ", "[error]"); if (pfwinfo->event[BTF_EVNT_BUF_OVERFLOW]) { - seq_printf(m, - "overflow-cnt: %d, ", - pfwinfo->event[BTF_EVNT_BUF_OVERFLOW]); + p += scnprintf(p, end - p, + "overflow-cnt: %d, ", + pfwinfo->event[BTF_EVNT_BUF_OVERFLOW]); } if (pfwinfo->len_mismch) { - seq_printf(m, - "len-mismatch: 0x%x, ", - pfwinfo->len_mismch); + p += scnprintf(p, end - p, + "len-mismatch: 0x%x, ", + pfwinfo->len_mismch); } if (pfwinfo->fver_mismch) { - seq_printf(m, - "fver-mismatch: 0x%x, ", - pfwinfo->fver_mismch); + p += scnprintf(p, end - p, + "fver-mismatch: 0x%x, ", + pfwinfo->fver_mismch); } /* cycle statistics exceptions */ if (exception_map || except_cnt) { - seq_printf(m, - "exception-type: 0x%x, exception-cnt = %d", - exception_map, except_cnt); + p += scnprintf(p, end - p, + "exception-type: 0x%x, exception-cnt = %d", + exception_map, except_cnt); } - seq_puts(m, "\n"); + p += scnprintf(p, end - p, "\n"); + + return p - buf; } -static void _show_fbtc_tdma(struct rtw89_dev *rtwdev, struct seq_file *m) +static int _show_fbtc_tdma(struct rtw89_dev *rtwdev, char *buf, size_t bufsz) { struct rtw89_btc *btc = &rtwdev->btc; const struct rtw89_btc_ver *ver = btc->ver; struct rtw89_btc_btf_fwinfo *pfwinfo = &btc->fwinfo; struct rtw89_btc_rpt_cmn_info *pcinfo = NULL; struct rtw89_btc_fbtc_tdma *t = NULL; + char *p = buf, *end = buf + bufsz; pcinfo = &pfwinfo->rpt_fbtc_tdma.cinfo; if (!pcinfo->valid) - return; + return 0; if (ver->fcxtdma == 1) t = &pfwinfo->rpt_fbtc_tdma.finfo.v1; else t = &pfwinfo->rpt_fbtc_tdma.finfo.v3.tdma; - seq_printf(m, - " %-15s : ", "[tdma_policy]"); - seq_printf(m, - "type:%d, rx_flow_ctrl:%d, tx_pause:%d, ", - (u32)t->type, - t->rxflctrl, t->txpause); + p += scnprintf(p, end - p, + " %-15s : ", "[tdma_policy]"); + p += scnprintf(p, end - p, + "type:%d, rx_flow_ctrl:%d, tx_pause:%d, ", + (u32)t->type, + t->rxflctrl, t->txpause); + + p += scnprintf(p, end - p, + "wl_toggle_n:%d, leak_n:%d, ext_ctrl:%d, ", + t->wtgle_n, t->leak_n, t->ext_ctrl); - seq_printf(m, - "wl_toggle_n:%d, leak_n:%d, ext_ctrl:%d, ", - t->wtgle_n, t->leak_n, t->ext_ctrl); + p += scnprintf(p, end - p, + "policy_type:%d", + (u32)btc->policy_type); - seq_printf(m, - "policy_type:%d", - (u32)btc->policy_type); + p += scnprintf(p, end - p, "\n"); - seq_puts(m, "\n"); + return p - buf; } -static void _show_fbtc_slots(struct rtw89_dev *rtwdev, struct seq_file *m) +static int _show_fbtc_slots(struct rtw89_dev *rtwdev, char *buf, size_t bufsz) { struct rtw89_btc *btc = &rtwdev->btc; struct rtw89_btc_dm *dm = &btc->dm; + char *p = buf, *end = buf + bufsz; u16 dur, cxtype; u32 tbl; u8 i = 0; @@ -9074,28 +9114,30 @@ static void _show_fbtc_slots(struct rtw89_dev *rtwdev, struct seq_file *m) tbl = le32_to_cpu(dm->slot_now.v7[i].cxtbl); cxtype = le16_to_cpu(dm->slot_now.v7[i].cxtype); } else { - return; + return 0; } if (i % 5 == 0) - seq_printf(m, - " %-15s : %5s[%03d/0x%x/%d]", - "[slot_list]", - id_to_slot((u32)i), - dur, tbl, cxtype); + p += scnprintf(p, end - p, + " %-15s : %5s[%03d/0x%x/%d]", + "[slot_list]", + id_to_slot((u32)i), + dur, tbl, cxtype); else - seq_printf(m, - ", %5s[%03d/0x%x/%d]", - id_to_slot((u32)i), - dur, tbl, cxtype); + p += scnprintf(p, end - p, + ", %5s[%03d/0x%x/%d]", + id_to_slot((u32)i), + dur, tbl, cxtype); if (i % 5 == 4) - seq_puts(m, "\n"); + p += scnprintf(p, end - p, "\n"); } - seq_puts(m, "\n"); + p += scnprintf(p, end - p, "\n"); + + return p - buf; } -static void _show_fbtc_cysta_v2(struct rtw89_dev *rtwdev, struct seq_file *m) +static int _show_fbtc_cysta_v2(struct rtw89_dev *rtwdev, char *buf, size_t bufsz) { struct rtw89_btc *btc = &rtwdev->btc; struct rtw89_btc_btf_fwinfo *pfwinfo = &btc->fwinfo; @@ -9104,63 +9146,64 @@ static void _show_fbtc_cysta_v2(struct rtw89_dev *rtwdev, struct seq_file *m) struct rtw89_btc_rpt_cmn_info *pcinfo = NULL; struct rtw89_btc_fbtc_cysta_v2 *pcysta_le32 = NULL; union rtw89_btc_fbtc_rxflct r; - u8 i, cnt = 0, slot_pair; u16 cycle, c_begin, c_end, store_index; + char *p = buf, *end = buf + bufsz; + u8 i, cnt = 0, slot_pair; pcinfo = &pfwinfo->rpt_fbtc_cysta.cinfo; if (!pcinfo->valid) - return; + return 0; pcysta_le32 = &pfwinfo->rpt_fbtc_cysta.finfo.v2; - seq_printf(m, - " %-15s : cycle:%d, bcn[all:%d/all_ok:%d/bt:%d/bt_ok:%d]", - "[cycle_cnt]", - le16_to_cpu(pcysta_le32->cycles), - le32_to_cpu(pcysta_le32->bcn_cnt[CXBCN_ALL]), - le32_to_cpu(pcysta_le32->bcn_cnt[CXBCN_ALL_OK]), - le32_to_cpu(pcysta_le32->bcn_cnt[CXBCN_BT_SLOT]), - le32_to_cpu(pcysta_le32->bcn_cnt[CXBCN_BT_OK])); + p += scnprintf(p, end - p, + " %-15s : cycle:%d, bcn[all:%d/all_ok:%d/bt:%d/bt_ok:%d]", + "[cycle_cnt]", + le16_to_cpu(pcysta_le32->cycles), + le32_to_cpu(pcysta_le32->bcn_cnt[CXBCN_ALL]), + le32_to_cpu(pcysta_le32->bcn_cnt[CXBCN_ALL_OK]), + le32_to_cpu(pcysta_le32->bcn_cnt[CXBCN_BT_SLOT]), + le32_to_cpu(pcysta_le32->bcn_cnt[CXBCN_BT_OK])); for (i = 0; i < CXST_MAX; i++) { if (!le32_to_cpu(pcysta_le32->slot_cnt[i])) continue; - seq_printf(m, ", %s:%d", id_to_slot((u32)i), - le32_to_cpu(pcysta_le32->slot_cnt[i])); + p += scnprintf(p, end - p, ", %s:%d", id_to_slot((u32)i), + le32_to_cpu(pcysta_le32->slot_cnt[i])); } if (dm->tdma_now.rxflctrl) { - seq_printf(m, ", leak_rx:%d", - le32_to_cpu(pcysta_le32->leakrx_cnt)); + p += scnprintf(p, end - p, ", leak_rx:%d", + le32_to_cpu(pcysta_le32->leakrx_cnt)); } if (le32_to_cpu(pcysta_le32->collision_cnt)) { - seq_printf(m, ", collision:%d", - le32_to_cpu(pcysta_le32->collision_cnt)); + p += scnprintf(p, end - p, ", collision:%d", + le32_to_cpu(pcysta_le32->collision_cnt)); } if (le32_to_cpu(pcysta_le32->skip_cnt)) { - seq_printf(m, ", skip:%d", - le32_to_cpu(pcysta_le32->skip_cnt)); - } - seq_puts(m, "\n"); - - seq_printf(m, " %-15s : avg_t[wl:%d/bt:%d/lk:%d.%03d]", - "[cycle_time]", - le16_to_cpu(pcysta_le32->tavg_cycle[CXT_WL]), - le16_to_cpu(pcysta_le32->tavg_cycle[CXT_BT]), - le16_to_cpu(pcysta_le32->tavg_lk) / 1000, - le16_to_cpu(pcysta_le32->tavg_lk) % 1000); - seq_printf(m, ", max_t[wl:%d/bt:%d/lk:%d.%03d]", - le16_to_cpu(pcysta_le32->tmax_cycle[CXT_WL]), - le16_to_cpu(pcysta_le32->tmax_cycle[CXT_BT]), - le16_to_cpu(pcysta_le32->tmax_lk) / 1000, - le16_to_cpu(pcysta_le32->tmax_lk) % 1000); - seq_printf(m, ", maxdiff_t[wl:%d/bt:%d]\n", - le16_to_cpu(pcysta_le32->tmaxdiff_cycle[CXT_WL]), - le16_to_cpu(pcysta_le32->tmaxdiff_cycle[CXT_BT])); + p += scnprintf(p, end - p, ", skip:%d", + le32_to_cpu(pcysta_le32->skip_cnt)); + } + p += scnprintf(p, end - p, "\n"); + + p += scnprintf(p, end - p, " %-15s : avg_t[wl:%d/bt:%d/lk:%d.%03d]", + "[cycle_time]", + le16_to_cpu(pcysta_le32->tavg_cycle[CXT_WL]), + le16_to_cpu(pcysta_le32->tavg_cycle[CXT_BT]), + le16_to_cpu(pcysta_le32->tavg_lk) / 1000, + le16_to_cpu(pcysta_le32->tavg_lk) % 1000); + p += scnprintf(p, end - p, ", max_t[wl:%d/bt:%d/lk:%d.%03d]", + le16_to_cpu(pcysta_le32->tmax_cycle[CXT_WL]), + le16_to_cpu(pcysta_le32->tmax_cycle[CXT_BT]), + le16_to_cpu(pcysta_le32->tmax_lk) / 1000, + le16_to_cpu(pcysta_le32->tmax_lk) % 1000); + p += scnprintf(p, end - p, ", maxdiff_t[wl:%d/bt:%d]\n", + le16_to_cpu(pcysta_le32->tmaxdiff_cycle[CXT_WL]), + le16_to_cpu(pcysta_le32->tmaxdiff_cycle[CXT_BT])); if (le16_to_cpu(pcysta_le32->cycles) <= 1) - return; + goto out; /* 1 cycle record 1 wl-slot and 1 bt-slot */ slot_pair = BTC_CYCLE_SLOT_MAX / 2; @@ -9177,53 +9220,57 @@ static void _show_fbtc_cysta_v2(struct rtw89_dev *rtwdev, struct seq_file *m) store_index = ((cycle - 1) % slot_pair) * 2; if (cnt % (BTC_CYCLE_SLOT_MAX / 4) == 1) - seq_printf(m, - " %-15s : ->b%02d->w%02d", "[cycle_step]", - le16_to_cpu(pcysta_le32->tslot_cycle[store_index]), - le16_to_cpu(pcysta_le32->tslot_cycle[store_index + 1])); + p += scnprintf(p, end - p, + " %-15s : ->b%02d->w%02d", + "[cycle_step]", + le16_to_cpu(pcysta_le32->tslot_cycle[store_index]), + le16_to_cpu(pcysta_le32->tslot_cycle[store_index + 1])); else - seq_printf(m, - "->b%02d->w%02d", - le16_to_cpu(pcysta_le32->tslot_cycle[store_index]), - le16_to_cpu(pcysta_le32->tslot_cycle[store_index + 1])); + p += scnprintf(p, end - p, + "->b%02d->w%02d", + le16_to_cpu(pcysta_le32->tslot_cycle[store_index]), + le16_to_cpu(pcysta_le32->tslot_cycle[store_index + 1])); if (cnt % (BTC_CYCLE_SLOT_MAX / 4) == 0 || cnt == c_end) - seq_puts(m, "\n"); + p += scnprintf(p, end - p, "\n"); } if (a2dp->exist) { - seq_printf(m, - " %-15s : a2dp_ept:%d, a2dp_late:%d", - "[a2dp_t_sta]", - le16_to_cpu(pcysta_le32->a2dpept), - le16_to_cpu(pcysta_le32->a2dpeptto)); - - seq_printf(m, - ", avg_t:%d, max_t:%d", - le16_to_cpu(pcysta_le32->tavg_a2dpept), - le16_to_cpu(pcysta_le32->tmax_a2dpept)); + p += scnprintf(p, end - p, + " %-15s : a2dp_ept:%d, a2dp_late:%d", + "[a2dp_t_sta]", + le16_to_cpu(pcysta_le32->a2dpept), + le16_to_cpu(pcysta_le32->a2dpeptto)); + + p += scnprintf(p, end - p, + ", avg_t:%d, max_t:%d", + le16_to_cpu(pcysta_le32->tavg_a2dpept), + le16_to_cpu(pcysta_le32->tmax_a2dpept)); r.val = dm->tdma_now.rxflctrl; if (r.type && r.tgln_n) { - seq_printf(m, - ", cycle[PSTDMA:%d/TDMA:%d], ", - le16_to_cpu(pcysta_le32->cycles_a2dp[CXT_FLCTRL_ON]), - le16_to_cpu(pcysta_le32->cycles_a2dp[CXT_FLCTRL_OFF])); - - seq_printf(m, - "avg_t[PSTDMA:%d/TDMA:%d], ", - le16_to_cpu(pcysta_le32->tavg_a2dp[CXT_FLCTRL_ON]), - le16_to_cpu(pcysta_le32->tavg_a2dp[CXT_FLCTRL_OFF])); - - seq_printf(m, - "max_t[PSTDMA:%d/TDMA:%d]", - le16_to_cpu(pcysta_le32->tmax_a2dp[CXT_FLCTRL_ON]), - le16_to_cpu(pcysta_le32->tmax_a2dp[CXT_FLCTRL_OFF])); + p += scnprintf(p, end - p, + ", cycle[PSTDMA:%d/TDMA:%d], ", + le16_to_cpu(pcysta_le32->cycles_a2dp[CXT_FLCTRL_ON]), + le16_to_cpu(pcysta_le32->cycles_a2dp[CXT_FLCTRL_OFF])); + + p += scnprintf(p, end - p, + "avg_t[PSTDMA:%d/TDMA:%d], ", + le16_to_cpu(pcysta_le32->tavg_a2dp[CXT_FLCTRL_ON]), + le16_to_cpu(pcysta_le32->tavg_a2dp[CXT_FLCTRL_OFF])); + + p += scnprintf(p, end - p, + "max_t[PSTDMA:%d/TDMA:%d]", + le16_to_cpu(pcysta_le32->tmax_a2dp[CXT_FLCTRL_ON]), + le16_to_cpu(pcysta_le32->tmax_a2dp[CXT_FLCTRL_OFF])); } - seq_puts(m, "\n"); + p += scnprintf(p, end - p, "\n"); } + +out: + return p - buf; } -static void _show_fbtc_cysta_v3(struct rtw89_dev *rtwdev, struct seq_file *m) +static int _show_fbtc_cysta_v3(struct rtw89_dev *rtwdev, char *buf, size_t bufsz) { struct rtw89_btc *btc = &rtwdev->btc; struct rtw89_btc_bt_a2dp_desc *a2dp = &btc->cx.bt.link_info.a2dp_desc; @@ -9234,60 +9281,64 @@ static void _show_fbtc_cysta_v3(struct rtw89_dev *rtwdev, struct seq_file *m) struct rtw89_btc_rpt_cmn_info *pcinfo; u8 i, cnt = 0, slot_pair, divide_cnt; u16 cycle, c_begin, c_end, store_index; + char *p = buf, *end = buf + bufsz; pcinfo = &pfwinfo->rpt_fbtc_cysta.cinfo; if (!pcinfo->valid) - return; + return 0; pcysta = &pfwinfo->rpt_fbtc_cysta.finfo.v3; - seq_printf(m, - " %-15s : cycle:%d, bcn[all:%d/all_ok:%d/bt:%d/bt_ok:%d]", - "[cycle_cnt]", - le16_to_cpu(pcysta->cycles), - le32_to_cpu(pcysta->bcn_cnt[CXBCN_ALL]), - le32_to_cpu(pcysta->bcn_cnt[CXBCN_ALL_OK]), - le32_to_cpu(pcysta->bcn_cnt[CXBCN_BT_SLOT]), - le32_to_cpu(pcysta->bcn_cnt[CXBCN_BT_OK])); + p += scnprintf(p, end - p, + " %-15s : cycle:%d, bcn[all:%d/all_ok:%d/bt:%d/bt_ok:%d]", + "[cycle_cnt]", + le16_to_cpu(pcysta->cycles), + le32_to_cpu(pcysta->bcn_cnt[CXBCN_ALL]), + le32_to_cpu(pcysta->bcn_cnt[CXBCN_ALL_OK]), + le32_to_cpu(pcysta->bcn_cnt[CXBCN_BT_SLOT]), + le32_to_cpu(pcysta->bcn_cnt[CXBCN_BT_OK])); for (i = 0; i < CXST_MAX; i++) { if (!le32_to_cpu(pcysta->slot_cnt[i])) continue; - seq_printf(m, ", %s:%d", id_to_slot(i), - le32_to_cpu(pcysta->slot_cnt[i])); + p += scnprintf(p, end - p, ", %s:%d", id_to_slot(i), + le32_to_cpu(pcysta->slot_cnt[i])); } if (dm->tdma_now.rxflctrl) - seq_printf(m, ", leak_rx:%d", le32_to_cpu(pcysta->leak_slot.cnt_rximr)); + p += scnprintf(p, end - p, ", leak_rx:%d", + le32_to_cpu(pcysta->leak_slot.cnt_rximr)); if (le32_to_cpu(pcysta->collision_cnt)) - seq_printf(m, ", collision:%d", le32_to_cpu(pcysta->collision_cnt)); + p += scnprintf(p, end - p, ", collision:%d", + le32_to_cpu(pcysta->collision_cnt)); if (le32_to_cpu(pcysta->skip_cnt)) - seq_printf(m, ", skip:%d", le32_to_cpu(pcysta->skip_cnt)); - - seq_puts(m, "\n"); - - seq_printf(m, " %-15s : avg_t[wl:%d/bt:%d/lk:%d.%03d]", - "[cycle_time]", - le16_to_cpu(pcysta->cycle_time.tavg[CXT_WL]), - le16_to_cpu(pcysta->cycle_time.tavg[CXT_BT]), - le16_to_cpu(pcysta->leak_slot.tavg) / 1000, - le16_to_cpu(pcysta->leak_slot.tavg) % 1000); - seq_printf(m, - ", max_t[wl:%d/bt:%d/lk:%d.%03d]", - le16_to_cpu(pcysta->cycle_time.tmax[CXT_WL]), - le16_to_cpu(pcysta->cycle_time.tmax[CXT_BT]), - le16_to_cpu(pcysta->leak_slot.tmax) / 1000, - le16_to_cpu(pcysta->leak_slot.tmax) % 1000); - seq_printf(m, - ", maxdiff_t[wl:%d/bt:%d]\n", - le16_to_cpu(pcysta->cycle_time.tmaxdiff[CXT_WL]), - le16_to_cpu(pcysta->cycle_time.tmaxdiff[CXT_BT])); + p += scnprintf(p, end - p, ", skip:%d", + le32_to_cpu(pcysta->skip_cnt)); + + p += scnprintf(p, end - p, "\n"); + + p += scnprintf(p, end - p, " %-15s : avg_t[wl:%d/bt:%d/lk:%d.%03d]", + "[cycle_time]", + le16_to_cpu(pcysta->cycle_time.tavg[CXT_WL]), + le16_to_cpu(pcysta->cycle_time.tavg[CXT_BT]), + le16_to_cpu(pcysta->leak_slot.tavg) / 1000, + le16_to_cpu(pcysta->leak_slot.tavg) % 1000); + p += scnprintf(p, end - p, + ", max_t[wl:%d/bt:%d/lk:%d.%03d]", + le16_to_cpu(pcysta->cycle_time.tmax[CXT_WL]), + le16_to_cpu(pcysta->cycle_time.tmax[CXT_BT]), + le16_to_cpu(pcysta->leak_slot.tmax) / 1000, + le16_to_cpu(pcysta->leak_slot.tmax) % 1000); + p += scnprintf(p, end - p, + ", maxdiff_t[wl:%d/bt:%d]\n", + le16_to_cpu(pcysta->cycle_time.tmaxdiff[CXT_WL]), + le16_to_cpu(pcysta->cycle_time.tmaxdiff[CXT_BT])); cycle = le16_to_cpu(pcysta->cycles); if (cycle <= 1) - return; + goto out; /* 1 cycle record 1 wl-slot and 1 bt-slot */ slot_pair = BTC_CYCLE_SLOT_MAX / 2; @@ -9309,51 +9360,56 @@ static void _show_fbtc_cysta_v3(struct rtw89_dev *rtwdev, struct seq_file *m) store_index = ((cycle - 1) % slot_pair) * 2; if (cnt % divide_cnt == 1) - seq_printf(m, " %-15s : ", "[cycle_step]"); + p += scnprintf(p, end - p, " %-15s : ", + "[cycle_step]"); - seq_printf(m, "->b%02d", - le16_to_cpu(pcysta->slot_step_time[store_index])); + p += scnprintf(p, end - p, "->b%02d", + le16_to_cpu(pcysta->slot_step_time[store_index])); if (a2dp->exist) { a2dp_trx = &pcysta->a2dp_trx[store_index]; - seq_printf(m, "(%d/%d/%dM/%d/%d/%d)", - a2dp_trx->empty_cnt, - a2dp_trx->retry_cnt, - a2dp_trx->tx_rate ? 3 : 2, - a2dp_trx->tx_cnt, - a2dp_trx->ack_cnt, - a2dp_trx->nack_cnt); + p += scnprintf(p, end - p, "(%d/%d/%dM/%d/%d/%d)", + a2dp_trx->empty_cnt, + a2dp_trx->retry_cnt, + a2dp_trx->tx_rate ? 3 : 2, + a2dp_trx->tx_cnt, + a2dp_trx->ack_cnt, + a2dp_trx->nack_cnt); } - seq_printf(m, "->w%02d", - le16_to_cpu(pcysta->slot_step_time[store_index + 1])); + p += scnprintf(p, end - p, "->w%02d", + le16_to_cpu(pcysta->slot_step_time[store_index + 1])); if (a2dp->exist) { a2dp_trx = &pcysta->a2dp_trx[store_index + 1]; - seq_printf(m, "(%d/%d/%dM/%d/%d/%d)", - a2dp_trx->empty_cnt, - a2dp_trx->retry_cnt, - a2dp_trx->tx_rate ? 3 : 2, - a2dp_trx->tx_cnt, - a2dp_trx->ack_cnt, - a2dp_trx->nack_cnt); + p += scnprintf(p, end - p, "(%d/%d/%dM/%d/%d/%d)", + a2dp_trx->empty_cnt, + a2dp_trx->retry_cnt, + a2dp_trx->tx_rate ? 3 : 2, + a2dp_trx->tx_cnt, + a2dp_trx->ack_cnt, + a2dp_trx->nack_cnt); } if (cnt % divide_cnt == 0 || cnt == c_end) - seq_puts(m, "\n"); + p += scnprintf(p, end - p, "\n"); } if (a2dp->exist) { - seq_printf(m, " %-15s : a2dp_ept:%d, a2dp_late:%d", - "[a2dp_t_sta]", - le16_to_cpu(pcysta->a2dp_ept.cnt), - le16_to_cpu(pcysta->a2dp_ept.cnt_timeout)); + p += scnprintf(p, end - p, + " %-15s : a2dp_ept:%d, a2dp_late:%d", + "[a2dp_t_sta]", + le16_to_cpu(pcysta->a2dp_ept.cnt), + le16_to_cpu(pcysta->a2dp_ept.cnt_timeout)); - seq_printf(m, ", avg_t:%d, max_t:%d", - le16_to_cpu(pcysta->a2dp_ept.tavg), - le16_to_cpu(pcysta->a2dp_ept.tmax)); + p += scnprintf(p, end - p, ", avg_t:%d, max_t:%d", + le16_to_cpu(pcysta->a2dp_ept.tavg), + le16_to_cpu(pcysta->a2dp_ept.tmax)); - seq_puts(m, "\n"); + p += scnprintf(p, end - p, "\n"); } + +out: + return p - buf; } -static void _show_fbtc_cysta_v4(struct rtw89_dev *rtwdev, struct seq_file *m) +static int _show_fbtc_cysta_v4(struct rtw89_dev *rtwdev, char *buf, size_t bufsz) { struct rtw89_btc *btc = &rtwdev->btc; struct rtw89_btc_bt_a2dp_desc *a2dp = &btc->cx.bt.link_info.a2dp_desc; @@ -9364,62 +9420,64 @@ static void _show_fbtc_cysta_v4(struct rtw89_dev *rtwdev, struct seq_file *m) struct rtw89_btc_rpt_cmn_info *pcinfo; u8 i, cnt = 0, slot_pair, divide_cnt; u16 cycle, c_begin, c_end, store_index; + char *p = buf, *end = buf + bufsz; pcinfo = &pfwinfo->rpt_fbtc_cysta.cinfo; if (!pcinfo->valid) - return; + return 0; pcysta = &pfwinfo->rpt_fbtc_cysta.finfo.v4; - seq_printf(m, - " %-15s : cycle:%d, bcn[all:%d/all_ok:%d/bt:%d/bt_ok:%d]", - "[cycle_cnt]", - le16_to_cpu(pcysta->cycles), - le16_to_cpu(pcysta->bcn_cnt[CXBCN_ALL]), - le16_to_cpu(pcysta->bcn_cnt[CXBCN_ALL_OK]), - le16_to_cpu(pcysta->bcn_cnt[CXBCN_BT_SLOT]), - le16_to_cpu(pcysta->bcn_cnt[CXBCN_BT_OK])); + p += scnprintf(p, end - p, + " %-15s : cycle:%d, bcn[all:%d/all_ok:%d/bt:%d/bt_ok:%d]", + "[cycle_cnt]", + le16_to_cpu(pcysta->cycles), + le16_to_cpu(pcysta->bcn_cnt[CXBCN_ALL]), + le16_to_cpu(pcysta->bcn_cnt[CXBCN_ALL_OK]), + le16_to_cpu(pcysta->bcn_cnt[CXBCN_BT_SLOT]), + le16_to_cpu(pcysta->bcn_cnt[CXBCN_BT_OK])); for (i = 0; i < CXST_MAX; i++) { if (!le16_to_cpu(pcysta->slot_cnt[i])) continue; - seq_printf(m, ", %s:%d", id_to_slot(i), - le16_to_cpu(pcysta->slot_cnt[i])); + p += scnprintf(p, end - p, ", %s:%d", id_to_slot(i), + le16_to_cpu(pcysta->slot_cnt[i])); } if (dm->tdma_now.rxflctrl) - seq_printf(m, ", leak_rx:%d", - le32_to_cpu(pcysta->leak_slot.cnt_rximr)); + p += scnprintf(p, end - p, ", leak_rx:%d", + le32_to_cpu(pcysta->leak_slot.cnt_rximr)); if (pcysta->collision_cnt) - seq_printf(m, ", collision:%d", pcysta->collision_cnt); + p += scnprintf(p, end - p, ", collision:%d", + pcysta->collision_cnt); if (le16_to_cpu(pcysta->skip_cnt)) - seq_printf(m, ", skip:%d", - le16_to_cpu(pcysta->skip_cnt)); - - seq_puts(m, "\n"); - - seq_printf(m, " %-15s : avg_t[wl:%d/bt:%d/lk:%d.%03d]", - "[cycle_time]", - le16_to_cpu(pcysta->cycle_time.tavg[CXT_WL]), - le16_to_cpu(pcysta->cycle_time.tavg[CXT_BT]), - le16_to_cpu(pcysta->leak_slot.tavg) / 1000, - le16_to_cpu(pcysta->leak_slot.tavg) % 1000); - seq_printf(m, - ", max_t[wl:%d/bt:%d/lk:%d.%03d]", - le16_to_cpu(pcysta->cycle_time.tmax[CXT_WL]), - le16_to_cpu(pcysta->cycle_time.tmax[CXT_BT]), - le16_to_cpu(pcysta->leak_slot.tmax) / 1000, - le16_to_cpu(pcysta->leak_slot.tmax) % 1000); - seq_printf(m, - ", maxdiff_t[wl:%d/bt:%d]\n", - le16_to_cpu(pcysta->cycle_time.tmaxdiff[CXT_WL]), - le16_to_cpu(pcysta->cycle_time.tmaxdiff[CXT_BT])); + p += scnprintf(p, end - p, ", skip:%d", + le16_to_cpu(pcysta->skip_cnt)); + + p += scnprintf(p, end - p, "\n"); + + p += scnprintf(p, end - p, " %-15s : avg_t[wl:%d/bt:%d/lk:%d.%03d]", + "[cycle_time]", + le16_to_cpu(pcysta->cycle_time.tavg[CXT_WL]), + le16_to_cpu(pcysta->cycle_time.tavg[CXT_BT]), + le16_to_cpu(pcysta->leak_slot.tavg) / 1000, + le16_to_cpu(pcysta->leak_slot.tavg) % 1000); + p += scnprintf(p, end - p, + ", max_t[wl:%d/bt:%d/lk:%d.%03d]", + le16_to_cpu(pcysta->cycle_time.tmax[CXT_WL]), + le16_to_cpu(pcysta->cycle_time.tmax[CXT_BT]), + le16_to_cpu(pcysta->leak_slot.tmax) / 1000, + le16_to_cpu(pcysta->leak_slot.tmax) % 1000); + p += scnprintf(p, end - p, + ", maxdiff_t[wl:%d/bt:%d]\n", + le16_to_cpu(pcysta->cycle_time.tmaxdiff[CXT_WL]), + le16_to_cpu(pcysta->cycle_time.tmaxdiff[CXT_BT])); cycle = le16_to_cpu(pcysta->cycles); if (cycle <= 1) - return; + goto out; /* 1 cycle record 1 wl-slot and 1 bt-slot */ slot_pair = BTC_CYCLE_SLOT_MAX / 2; @@ -9441,51 +9499,56 @@ static void _show_fbtc_cysta_v4(struct rtw89_dev *rtwdev, struct seq_file *m) store_index = ((cycle - 1) % slot_pair) * 2; if (cnt % divide_cnt == 1) - seq_printf(m, " %-15s : ", "[cycle_step]"); + p += scnprintf(p, end - p, " %-15s : ", + "[cycle_step]"); - seq_printf(m, "->b%02d", - le16_to_cpu(pcysta->slot_step_time[store_index])); + p += scnprintf(p, end - p, "->b%02d", + le16_to_cpu(pcysta->slot_step_time[store_index])); if (a2dp->exist) { a2dp_trx = &pcysta->a2dp_trx[store_index]; - seq_printf(m, "(%d/%d/%dM/%d/%d/%d)", - a2dp_trx->empty_cnt, - a2dp_trx->retry_cnt, - a2dp_trx->tx_rate ? 3 : 2, - a2dp_trx->tx_cnt, - a2dp_trx->ack_cnt, - a2dp_trx->nack_cnt); + p += scnprintf(p, end - p, "(%d/%d/%dM/%d/%d/%d)", + a2dp_trx->empty_cnt, + a2dp_trx->retry_cnt, + a2dp_trx->tx_rate ? 3 : 2, + a2dp_trx->tx_cnt, + a2dp_trx->ack_cnt, + a2dp_trx->nack_cnt); } - seq_printf(m, "->w%02d", - le16_to_cpu(pcysta->slot_step_time[store_index + 1])); + p += scnprintf(p, end - p, "->w%02d", + le16_to_cpu(pcysta->slot_step_time[store_index + 1])); if (a2dp->exist) { a2dp_trx = &pcysta->a2dp_trx[store_index + 1]; - seq_printf(m, "(%d/%d/%dM/%d/%d/%d)", - a2dp_trx->empty_cnt, - a2dp_trx->retry_cnt, - a2dp_trx->tx_rate ? 3 : 2, - a2dp_trx->tx_cnt, - a2dp_trx->ack_cnt, - a2dp_trx->nack_cnt); + p += scnprintf(p, end - p, "(%d/%d/%dM/%d/%d/%d)", + a2dp_trx->empty_cnt, + a2dp_trx->retry_cnt, + a2dp_trx->tx_rate ? 3 : 2, + a2dp_trx->tx_cnt, + a2dp_trx->ack_cnt, + a2dp_trx->nack_cnt); } if (cnt % divide_cnt == 0 || cnt == c_end) - seq_puts(m, "\n"); + p += scnprintf(p, end - p, "\n"); } if (a2dp->exist) { - seq_printf(m, " %-15s : a2dp_ept:%d, a2dp_late:%d", - "[a2dp_t_sta]", - le16_to_cpu(pcysta->a2dp_ept.cnt), - le16_to_cpu(pcysta->a2dp_ept.cnt_timeout)); + p += scnprintf(p, end - p, + " %-15s : a2dp_ept:%d, a2dp_late:%d", + "[a2dp_t_sta]", + le16_to_cpu(pcysta->a2dp_ept.cnt), + le16_to_cpu(pcysta->a2dp_ept.cnt_timeout)); - seq_printf(m, ", avg_t:%d, max_t:%d", - le16_to_cpu(pcysta->a2dp_ept.tavg), - le16_to_cpu(pcysta->a2dp_ept.tmax)); + p += scnprintf(p, end - p, ", avg_t:%d, max_t:%d", + le16_to_cpu(pcysta->a2dp_ept.tavg), + le16_to_cpu(pcysta->a2dp_ept.tmax)); - seq_puts(m, "\n"); + p += scnprintf(p, end - p, "\n"); } + +out: + return p - buf; } -static void _show_fbtc_cysta_v5(struct rtw89_dev *rtwdev, struct seq_file *m) +static int _show_fbtc_cysta_v5(struct rtw89_dev *rtwdev, char *buf, size_t bufsz) { struct rtw89_btc *btc = &rtwdev->btc; struct rtw89_btc_bt_a2dp_desc *a2dp = &btc->cx.bt.link_info.a2dp_desc; @@ -9496,58 +9559,60 @@ static void _show_fbtc_cysta_v5(struct rtw89_dev *rtwdev, struct seq_file *m) struct rtw89_btc_rpt_cmn_info *pcinfo; u8 i, cnt = 0, slot_pair, divide_cnt; u16 cycle, c_begin, c_end, store_index; + char *p = buf, *end = buf + bufsz; pcinfo = &pfwinfo->rpt_fbtc_cysta.cinfo; if (!pcinfo->valid) - return; + return 0; pcysta = &pfwinfo->rpt_fbtc_cysta.finfo.v5; - seq_printf(m, - " %-15s : cycle:%d, bcn[all:%d/all_ok:%d/bt:%d/bt_ok:%d]", - "[cycle_cnt]", - le16_to_cpu(pcysta->cycles), - le16_to_cpu(pcysta->bcn_cnt[CXBCN_ALL]), - le16_to_cpu(pcysta->bcn_cnt[CXBCN_ALL_OK]), - le16_to_cpu(pcysta->bcn_cnt[CXBCN_BT_SLOT]), - le16_to_cpu(pcysta->bcn_cnt[CXBCN_BT_OK])); + p += scnprintf(p, end - p, + " %-15s : cycle:%d, bcn[all:%d/all_ok:%d/bt:%d/bt_ok:%d]", + "[cycle_cnt]", + le16_to_cpu(pcysta->cycles), + le16_to_cpu(pcysta->bcn_cnt[CXBCN_ALL]), + le16_to_cpu(pcysta->bcn_cnt[CXBCN_ALL_OK]), + le16_to_cpu(pcysta->bcn_cnt[CXBCN_BT_SLOT]), + le16_to_cpu(pcysta->bcn_cnt[CXBCN_BT_OK])); for (i = 0; i < CXST_MAX; i++) { if (!le16_to_cpu(pcysta->slot_cnt[i])) continue; - seq_printf(m, ", %s:%d", id_to_slot(i), - le16_to_cpu(pcysta->slot_cnt[i])); + p += scnprintf(p, end - p, ", %s:%d", id_to_slot(i), + le16_to_cpu(pcysta->slot_cnt[i])); } if (dm->tdma_now.rxflctrl) - seq_printf(m, ", leak_rx:%d", - le32_to_cpu(pcysta->leak_slot.cnt_rximr)); + p += scnprintf(p, end - p, ", leak_rx:%d", + le32_to_cpu(pcysta->leak_slot.cnt_rximr)); if (pcysta->collision_cnt) - seq_printf(m, ", collision:%d", pcysta->collision_cnt); + p += scnprintf(p, end - p, ", collision:%d", + pcysta->collision_cnt); if (le16_to_cpu(pcysta->skip_cnt)) - seq_printf(m, ", skip:%d", - le16_to_cpu(pcysta->skip_cnt)); - - seq_puts(m, "\n"); - - seq_printf(m, " %-15s : avg_t[wl:%d/bt:%d/lk:%d.%03d]", - "[cycle_time]", - le16_to_cpu(pcysta->cycle_time.tavg[CXT_WL]), - le16_to_cpu(pcysta->cycle_time.tavg[CXT_BT]), - le16_to_cpu(pcysta->leak_slot.tavg) / 1000, - le16_to_cpu(pcysta->leak_slot.tavg) % 1000); - seq_printf(m, - ", max_t[wl:%d/bt:%d/lk:%d.%03d]\n", - le16_to_cpu(pcysta->cycle_time.tmax[CXT_WL]), - le16_to_cpu(pcysta->cycle_time.tmax[CXT_BT]), - le16_to_cpu(pcysta->leak_slot.tmax) / 1000, - le16_to_cpu(pcysta->leak_slot.tmax) % 1000); + p += scnprintf(p, end - p, ", skip:%d", + le16_to_cpu(pcysta->skip_cnt)); + + p += scnprintf(p, end - p, "\n"); + + p += scnprintf(p, end - p, " %-15s : avg_t[wl:%d/bt:%d/lk:%d.%03d]", + "[cycle_time]", + le16_to_cpu(pcysta->cycle_time.tavg[CXT_WL]), + le16_to_cpu(pcysta->cycle_time.tavg[CXT_BT]), + le16_to_cpu(pcysta->leak_slot.tavg) / 1000, + le16_to_cpu(pcysta->leak_slot.tavg) % 1000); + p += scnprintf(p, end - p, + ", max_t[wl:%d/bt:%d/lk:%d.%03d]\n", + le16_to_cpu(pcysta->cycle_time.tmax[CXT_WL]), + le16_to_cpu(pcysta->cycle_time.tmax[CXT_BT]), + le16_to_cpu(pcysta->leak_slot.tmax) / 1000, + le16_to_cpu(pcysta->leak_slot.tmax) % 1000); cycle = le16_to_cpu(pcysta->cycles); if (cycle <= 1) - return; + goto out; /* 1 cycle record 1 wl-slot and 1 bt-slot */ slot_pair = BTC_CYCLE_SLOT_MAX / 2; @@ -9565,58 +9630,63 @@ static void _show_fbtc_cysta_v5(struct rtw89_dev *rtwdev, struct seq_file *m) divide_cnt = BTC_CYCLE_SLOT_MAX / 4; if (c_begin > c_end) - return; + goto out; for (cycle = c_begin; cycle <= c_end; cycle++) { cnt++; store_index = ((cycle - 1) % slot_pair) * 2; if (cnt % divide_cnt == 1) - seq_printf(m, " %-15s : ", "[cycle_step]"); + p += scnprintf(p, end - p, " %-15s : ", + "[cycle_step]"); - seq_printf(m, "->b%02d", - le16_to_cpu(pcysta->slot_step_time[store_index])); + p += scnprintf(p, end - p, "->b%02d", + le16_to_cpu(pcysta->slot_step_time[store_index])); if (a2dp->exist) { a2dp_trx = &pcysta->a2dp_trx[store_index]; - seq_printf(m, "(%d/%d/%dM/%d/%d/%d)", - a2dp_trx->empty_cnt, - a2dp_trx->retry_cnt, - a2dp_trx->tx_rate ? 3 : 2, - a2dp_trx->tx_cnt, - a2dp_trx->ack_cnt, - a2dp_trx->nack_cnt); + p += scnprintf(p, end - p, "(%d/%d/%dM/%d/%d/%d)", + a2dp_trx->empty_cnt, + a2dp_trx->retry_cnt, + a2dp_trx->tx_rate ? 3 : 2, + a2dp_trx->tx_cnt, + a2dp_trx->ack_cnt, + a2dp_trx->nack_cnt); } - seq_printf(m, "->w%02d", - le16_to_cpu(pcysta->slot_step_time[store_index + 1])); + p += scnprintf(p, end - p, "->w%02d", + le16_to_cpu(pcysta->slot_step_time[store_index + 1])); if (a2dp->exist) { a2dp_trx = &pcysta->a2dp_trx[store_index + 1]; - seq_printf(m, "(%d/%d/%dM/%d/%d/%d)", - a2dp_trx->empty_cnt, - a2dp_trx->retry_cnt, - a2dp_trx->tx_rate ? 3 : 2, - a2dp_trx->tx_cnt, - a2dp_trx->ack_cnt, - a2dp_trx->nack_cnt); + p += scnprintf(p, end - p, "(%d/%d/%dM/%d/%d/%d)", + a2dp_trx->empty_cnt, + a2dp_trx->retry_cnt, + a2dp_trx->tx_rate ? 3 : 2, + a2dp_trx->tx_cnt, + a2dp_trx->ack_cnt, + a2dp_trx->nack_cnt); } if (cnt % divide_cnt == 0 || cnt == c_end) - seq_puts(m, "\n"); + p += scnprintf(p, end - p, "\n"); } if (a2dp->exist) { - seq_printf(m, " %-15s : a2dp_ept:%d, a2dp_late:%d", - "[a2dp_t_sta]", - le16_to_cpu(pcysta->a2dp_ept.cnt), - le16_to_cpu(pcysta->a2dp_ept.cnt_timeout)); + p += scnprintf(p, end - p, + " %-15s : a2dp_ept:%d, a2dp_late:%d", + "[a2dp_t_sta]", + le16_to_cpu(pcysta->a2dp_ept.cnt), + le16_to_cpu(pcysta->a2dp_ept.cnt_timeout)); - seq_printf(m, ", avg_t:%d, max_t:%d", - le16_to_cpu(pcysta->a2dp_ept.tavg), - le16_to_cpu(pcysta->a2dp_ept.tmax)); + p += scnprintf(p, end - p, ", avg_t:%d, max_t:%d", + le16_to_cpu(pcysta->a2dp_ept.tavg), + le16_to_cpu(pcysta->a2dp_ept.tmax)); - seq_puts(m, "\n"); + p += scnprintf(p, end - p, "\n"); } + +out: + return p - buf; } -static void _show_fbtc_cysta_v7(struct rtw89_dev *rtwdev, struct seq_file *m) +static int _show_fbtc_cysta_v7(struct rtw89_dev *rtwdev, char *buf, size_t bufsz) { struct rtw89_btc_bt_info *bt = &rtwdev->btc.cx.bt; struct rtw89_btc_bt_a2dp_desc *a2dp = &bt->link_info.a2dp_desc; @@ -9624,68 +9694,75 @@ static void _show_fbtc_cysta_v7(struct rtw89_dev *rtwdev, struct seq_file *m) struct rtw89_btc_fbtc_cysta_v7 *pcysta = NULL; struct rtw89_btc_dm *dm = &rtwdev->btc.dm; struct rtw89_btc_rpt_cmn_info *pcinfo; + char *p = buf, *end = buf + bufsz; u16 cycle, c_begin, c_end, s_id; u8 i, cnt = 0, divide_cnt; u8 slot_pair; pcinfo = &pfwinfo->rpt_fbtc_cysta.cinfo; if (!pcinfo->valid) - return; + return 0; pcysta = &pfwinfo->rpt_fbtc_cysta.finfo.v7; - seq_printf(m, "\n\r %-15s : cycle:%d", "[slot_stat]", - le16_to_cpu(pcysta->cycles)); + p += scnprintf(p, end - p, "\n\r %-15s : cycle:%d", "[slot_stat]", + le16_to_cpu(pcysta->cycles)); for (i = 0; i < CXST_MAX; i++) { if (!le16_to_cpu(pcysta->slot_cnt[i])) continue; - seq_printf(m, ", %s:%d", - id_to_slot(i), le16_to_cpu(pcysta->slot_cnt[i])); + p += scnprintf(p, end - p, ", %s:%d", + id_to_slot(i), + le16_to_cpu(pcysta->slot_cnt[i])); } if (dm->tdma_now.rxflctrl) - seq_printf(m, ", leak_rx:%d", - le32_to_cpu(pcysta->leak_slot.cnt_rximr)); + p += scnprintf(p, end - p, ", leak_rx:%d", + le32_to_cpu(pcysta->leak_slot.cnt_rximr)); if (pcysta->collision_cnt) - seq_printf(m, ", collision:%d", pcysta->collision_cnt); + p += scnprintf(p, end - p, ", collision:%d", + pcysta->collision_cnt); if (pcysta->skip_cnt) - seq_printf(m, ", skip:%d", le16_to_cpu(pcysta->skip_cnt)); - - seq_printf(m, "\n\r %-15s : avg_t[wl:%d/bt:%d/lk:%d.%03d]", - "[cycle_stat]", - le16_to_cpu(pcysta->cycle_time.tavg[CXT_WL]), - le16_to_cpu(pcysta->cycle_time.tavg[CXT_BT]), - le16_to_cpu(pcysta->leak_slot.tavg) / 1000, - le16_to_cpu(pcysta->leak_slot.tavg) % 1000); - seq_printf(m, ", max_t[wl:%d/bt:%d(>%dms:%d)/lk:%d.%03d]", - le16_to_cpu(pcysta->cycle_time.tmax[CXT_WL]), - le16_to_cpu(pcysta->cycle_time.tmax[CXT_BT]), - dm->bt_slot_flood, dm->cnt_dm[BTC_DCNT_BT_SLOT_FLOOD], - le16_to_cpu(pcysta->leak_slot.tamx) / 1000, - le16_to_cpu(pcysta->leak_slot.tamx) % 1000); - seq_printf(m, ", bcn[all:%d/ok:%d/in_bt:%d/in_bt_ok:%d]", - le16_to_cpu(pcysta->bcn_cnt[CXBCN_ALL]), - le16_to_cpu(pcysta->bcn_cnt[CXBCN_ALL_OK]), - le16_to_cpu(pcysta->bcn_cnt[CXBCN_BT_SLOT]), - le16_to_cpu(pcysta->bcn_cnt[CXBCN_BT_OK])); + p += scnprintf(p, end - p, ", skip:%d", + le16_to_cpu(pcysta->skip_cnt)); + + p += scnprintf(p, end - p, + "\n\r %-15s : avg_t[wl:%d/bt:%d/lk:%d.%03d]", + "[cycle_stat]", + le16_to_cpu(pcysta->cycle_time.tavg[CXT_WL]), + le16_to_cpu(pcysta->cycle_time.tavg[CXT_BT]), + le16_to_cpu(pcysta->leak_slot.tavg) / 1000, + le16_to_cpu(pcysta->leak_slot.tavg) % 1000); + p += scnprintf(p, end - p, + ", max_t[wl:%d/bt:%d(>%dms:%d)/lk:%d.%03d]", + le16_to_cpu(pcysta->cycle_time.tmax[CXT_WL]), + le16_to_cpu(pcysta->cycle_time.tmax[CXT_BT]), + dm->bt_slot_flood, dm->cnt_dm[BTC_DCNT_BT_SLOT_FLOOD], + le16_to_cpu(pcysta->leak_slot.tamx) / 1000, + le16_to_cpu(pcysta->leak_slot.tamx) % 1000); + p += scnprintf(p, end - p, ", bcn[all:%d/ok:%d/in_bt:%d/in_bt_ok:%d]", + le16_to_cpu(pcysta->bcn_cnt[CXBCN_ALL]), + le16_to_cpu(pcysta->bcn_cnt[CXBCN_ALL_OK]), + le16_to_cpu(pcysta->bcn_cnt[CXBCN_BT_SLOT]), + le16_to_cpu(pcysta->bcn_cnt[CXBCN_BT_OK])); if (a2dp->exist) { - seq_printf(m, - "\n\r %-15s : a2dp_ept:%d, a2dp_late:%d(streak 2S:%d/max:%d)", - "[a2dp_stat]", - le16_to_cpu(pcysta->a2dp_ept.cnt), - le16_to_cpu(pcysta->a2dp_ept.cnt_timeout), - a2dp->no_empty_streak_2s, a2dp->no_empty_streak_max); + p += scnprintf(p, end - p, + "\n\r %-15s : a2dp_ept:%d, a2dp_late:%d(streak 2S:%d/max:%d)", + "[a2dp_stat]", + le16_to_cpu(pcysta->a2dp_ept.cnt), + le16_to_cpu(pcysta->a2dp_ept.cnt_timeout), + a2dp->no_empty_streak_2s, + a2dp->no_empty_streak_max); - seq_printf(m, ", avg_t:%d, max_t:%d", - le16_to_cpu(pcysta->a2dp_ept.tavg), - le16_to_cpu(pcysta->a2dp_ept.tmax)); + p += scnprintf(p, end - p, ", avg_t:%d, max_t:%d", + le16_to_cpu(pcysta->a2dp_ept.tavg), + le16_to_cpu(pcysta->a2dp_ept.tmax)); } if (le16_to_cpu(pcysta->cycles) <= 1) - return; + goto out; /* 1 cycle = 1 wl-slot + 1 bt-slot */ slot_pair = BTC_CYCLE_SLOT_MAX / 2; @@ -9703,7 +9780,7 @@ static void _show_fbtc_cysta_v7(struct rtw89_dev *rtwdev, struct seq_file *m) divide_cnt = 6; if (c_begin > c_end) - return; + goto out; for (cycle = c_begin; cycle <= c_end; cycle++) { cnt++; @@ -9711,129 +9788,142 @@ static void _show_fbtc_cysta_v7(struct rtw89_dev *rtwdev, struct seq_file *m) if (cnt % divide_cnt == 1) { if (a2dp->exist) - seq_printf(m, "\n\r %-15s : ", "[slotT_wermtan]"); + p += scnprintf(p, end - p, "\n\r %-15s : ", + "[slotT_wermtan]"); else - seq_printf(m, "\n\r %-15s : ", "[slotT_rxerr]"); + p += scnprintf(p, end - p, "\n\r %-15s : ", + "[slotT_rxerr]"); } - seq_printf(m, "->b%d", le16_to_cpu(pcysta->slot_step_time[s_id])); + p += scnprintf(p, end - p, "->b%d", + le16_to_cpu(pcysta->slot_step_time[s_id])); if (a2dp->exist) - seq_printf(m, "(%d/%d/%d/%dM/%d/%d/%d)", - pcysta->wl_rx_err_ratio[s_id], - pcysta->a2dp_trx[s_id].empty_cnt, - pcysta->a2dp_trx[s_id].retry_cnt, - (pcysta->a2dp_trx[s_id].tx_rate ? 3 : 2), - pcysta->a2dp_trx[s_id].tx_cnt, - pcysta->a2dp_trx[s_id].ack_cnt, - pcysta->a2dp_trx[s_id].nack_cnt); + p += scnprintf(p, end - p, "(%d/%d/%d/%dM/%d/%d/%d)", + pcysta->wl_rx_err_ratio[s_id], + pcysta->a2dp_trx[s_id].empty_cnt, + pcysta->a2dp_trx[s_id].retry_cnt, + (pcysta->a2dp_trx[s_id].tx_rate ? 3 : 2), + pcysta->a2dp_trx[s_id].tx_cnt, + pcysta->a2dp_trx[s_id].ack_cnt, + pcysta->a2dp_trx[s_id].nack_cnt); else - seq_printf(m, "(%d)", pcysta->wl_rx_err_ratio[s_id]); + p += scnprintf(p, end - p, "(%d)", + pcysta->wl_rx_err_ratio[s_id]); - seq_printf(m, "->w%d", le16_to_cpu(pcysta->slot_step_time[s_id + 1])); + p += scnprintf(p, end - p, "->w%d", + le16_to_cpu(pcysta->slot_step_time[s_id + 1])); if (a2dp->exist) - seq_printf(m, "(%d/%d/%d/%dM/%d/%d/%d)", - pcysta->wl_rx_err_ratio[s_id + 1], - pcysta->a2dp_trx[s_id + 1].empty_cnt, - pcysta->a2dp_trx[s_id + 1].retry_cnt, - (pcysta->a2dp_trx[s_id + 1].tx_rate ? 3 : 2), - pcysta->a2dp_trx[s_id + 1].tx_cnt, - pcysta->a2dp_trx[s_id + 1].ack_cnt, - pcysta->a2dp_trx[s_id + 1].nack_cnt); + p += scnprintf(p, end - p, "(%d/%d/%d/%dM/%d/%d/%d)", + pcysta->wl_rx_err_ratio[s_id + 1], + pcysta->a2dp_trx[s_id + 1].empty_cnt, + pcysta->a2dp_trx[s_id + 1].retry_cnt, + (pcysta->a2dp_trx[s_id + 1].tx_rate ? 3 : 2), + pcysta->a2dp_trx[s_id + 1].tx_cnt, + pcysta->a2dp_trx[s_id + 1].ack_cnt, + pcysta->a2dp_trx[s_id + 1].nack_cnt); else - seq_printf(m, "(%d)", pcysta->wl_rx_err_ratio[s_id + 1]); + p += scnprintf(p, end - p, "(%d)", + pcysta->wl_rx_err_ratio[s_id + 1]); } + +out: + return p - buf; } -static void _show_fbtc_nullsta(struct rtw89_dev *rtwdev, struct seq_file *m) +static int _show_fbtc_nullsta(struct rtw89_dev *rtwdev, char *buf, size_t bufsz) { struct rtw89_btc *btc = &rtwdev->btc; const struct rtw89_btc_ver *ver = btc->ver; struct rtw89_btc_btf_fwinfo *pfwinfo = &btc->fwinfo; struct rtw89_btc_rpt_cmn_info *pcinfo; union rtw89_btc_fbtc_cynullsta_info *ns; + char *p = buf, *end = buf + bufsz; u8 i = 0; if (!btc->dm.tdma_now.rxflctrl) - return; + return 0; pcinfo = &pfwinfo->rpt_fbtc_nullsta.cinfo; if (!pcinfo->valid) - return; + return 0; ns = &pfwinfo->rpt_fbtc_nullsta.finfo; if (ver->fcxnullsta == 1) { for (i = 0; i < 2; i++) { - seq_printf(m, " %-15s : ", "[NULL-STA]"); - seq_printf(m, "null-%d", i); - seq_printf(m, "[ok:%d/", - le32_to_cpu(ns->v1.result[i][1])); - seq_printf(m, "fail:%d/", - le32_to_cpu(ns->v1.result[i][0])); - seq_printf(m, "on_time:%d/", - le32_to_cpu(ns->v1.result[i][2])); - seq_printf(m, "retry:%d/", - le32_to_cpu(ns->v1.result[i][3])); - seq_printf(m, "avg_t:%d.%03d/", - le32_to_cpu(ns->v1.avg_t[i]) / 1000, - le32_to_cpu(ns->v1.avg_t[i]) % 1000); - seq_printf(m, "max_t:%d.%03d]\n", - le32_to_cpu(ns->v1.max_t[i]) / 1000, - le32_to_cpu(ns->v1.max_t[i]) % 1000); + p += scnprintf(p, end - p, " %-15s : ", "[NULL-STA]"); + p += scnprintf(p, end - p, "null-%d", i); + p += scnprintf(p, end - p, "[ok:%d/", + le32_to_cpu(ns->v1.result[i][1])); + p += scnprintf(p, end - p, "fail:%d/", + le32_to_cpu(ns->v1.result[i][0])); + p += scnprintf(p, end - p, "on_time:%d/", + le32_to_cpu(ns->v1.result[i][2])); + p += scnprintf(p, end - p, "retry:%d/", + le32_to_cpu(ns->v1.result[i][3])); + p += scnprintf(p, end - p, "avg_t:%d.%03d/", + le32_to_cpu(ns->v1.avg_t[i]) / 1000, + le32_to_cpu(ns->v1.avg_t[i]) % 1000); + p += scnprintf(p, end - p, "max_t:%d.%03d]\n", + le32_to_cpu(ns->v1.max_t[i]) / 1000, + le32_to_cpu(ns->v1.max_t[i]) % 1000); } } else if (ver->fcxnullsta == 7) { for (i = 0; i < 2; i++) { - seq_printf(m, " %-15s : ", "[NULL-STA]"); - seq_printf(m, "null-%d", i); - seq_printf(m, "[Tx:%d/", - le32_to_cpu(ns->v7.result[i][4])); - seq_printf(m, "[ok:%d/", - le32_to_cpu(ns->v7.result[i][1])); - seq_printf(m, "fail:%d/", - le32_to_cpu(ns->v7.result[i][0])); - seq_printf(m, "on_time:%d/", - le32_to_cpu(ns->v7.result[i][2])); - seq_printf(m, "retry:%d/", - le32_to_cpu(ns->v7.result[i][3])); - seq_printf(m, "avg_t:%d.%03d/", - le32_to_cpu(ns->v7.tavg[i]) / 1000, - le32_to_cpu(ns->v7.tavg[i]) % 1000); - seq_printf(m, "max_t:%d.%03d]\n", - le32_to_cpu(ns->v7.tmax[i]) / 1000, - le32_to_cpu(ns->v7.tmax[i]) % 1000); + p += scnprintf(p, end - p, " %-15s : ", "[NULL-STA]"); + p += scnprintf(p, end - p, "null-%d", i); + p += scnprintf(p, end - p, "[Tx:%d/", + le32_to_cpu(ns->v7.result[i][4])); + p += scnprintf(p, end - p, "[ok:%d/", + le32_to_cpu(ns->v7.result[i][1])); + p += scnprintf(p, end - p, "fail:%d/", + le32_to_cpu(ns->v7.result[i][0])); + p += scnprintf(p, end - p, "on_time:%d/", + le32_to_cpu(ns->v7.result[i][2])); + p += scnprintf(p, end - p, "retry:%d/", + le32_to_cpu(ns->v7.result[i][3])); + p += scnprintf(p, end - p, "avg_t:%d.%03d/", + le32_to_cpu(ns->v7.tavg[i]) / 1000, + le32_to_cpu(ns->v7.tavg[i]) % 1000); + p += scnprintf(p, end - p, "max_t:%d.%03d]\n", + le32_to_cpu(ns->v7.tmax[i]) / 1000, + le32_to_cpu(ns->v7.tmax[i]) % 1000); } } else { for (i = 0; i < 2; i++) { - seq_printf(m, " %-15s : ", "[NULL-STA]"); - seq_printf(m, "null-%d", i); - seq_printf(m, "[Tx:%d/", - le32_to_cpu(ns->v2.result[i][4])); - seq_printf(m, "[ok:%d/", - le32_to_cpu(ns->v2.result[i][1])); - seq_printf(m, "fail:%d/", - le32_to_cpu(ns->v2.result[i][0])); - seq_printf(m, "on_time:%d/", - le32_to_cpu(ns->v2.result[i][2])); - seq_printf(m, "retry:%d/", - le32_to_cpu(ns->v2.result[i][3])); - seq_printf(m, "avg_t:%d.%03d/", - le32_to_cpu(ns->v2.avg_t[i]) / 1000, - le32_to_cpu(ns->v2.avg_t[i]) % 1000); - seq_printf(m, "max_t:%d.%03d]\n", - le32_to_cpu(ns->v2.max_t[i]) / 1000, - le32_to_cpu(ns->v2.max_t[i]) % 1000); + p += scnprintf(p, end - p, " %-15s : ", "[NULL-STA]"); + p += scnprintf(p, end - p, "null-%d", i); + p += scnprintf(p, end - p, "[Tx:%d/", + le32_to_cpu(ns->v2.result[i][4])); + p += scnprintf(p, end - p, "[ok:%d/", + le32_to_cpu(ns->v2.result[i][1])); + p += scnprintf(p, end - p, "fail:%d/", + le32_to_cpu(ns->v2.result[i][0])); + p += scnprintf(p, end - p, "on_time:%d/", + le32_to_cpu(ns->v2.result[i][2])); + p += scnprintf(p, end - p, "retry:%d/", + le32_to_cpu(ns->v2.result[i][3])); + p += scnprintf(p, end - p, "avg_t:%d.%03d/", + le32_to_cpu(ns->v2.avg_t[i]) / 1000, + le32_to_cpu(ns->v2.avg_t[i]) % 1000); + p += scnprintf(p, end - p, "max_t:%d.%03d]\n", + le32_to_cpu(ns->v2.max_t[i]) / 1000, + le32_to_cpu(ns->v2.max_t[i]) % 1000); } } + + return p - buf; } -static void _show_fbtc_step_v2(struct rtw89_dev *rtwdev, struct seq_file *m) +static int _show_fbtc_step_v2(struct rtw89_dev *rtwdev, char *buf, size_t bufsz) { struct rtw89_btc *btc = &rtwdev->btc; struct rtw89_btc_btf_fwinfo *pfwinfo = &btc->fwinfo; struct rtw89_btc_rpt_cmn_info *pcinfo = NULL; struct rtw89_btc_fbtc_steps_v2 *pstep = NULL; const struct rtw89_btc_ver *ver = btc->ver; + char *p = buf, *end = buf + bufsz; u8 type, val, cnt = 0, state = 0; bool outloop = false; u16 i, diff_t, n_start = 0, n_stop = 0; @@ -9841,14 +9931,14 @@ static void _show_fbtc_step_v2(struct rtw89_dev *rtwdev, struct seq_file *m) pcinfo = &pfwinfo->rpt_fbtc_step.cinfo; if (!pcinfo->valid) - return; + return 0; pstep = &pfwinfo->rpt_fbtc_step.finfo.v2; pos_old = le16_to_cpu(pstep->pos_old); pos_new = le16_to_cpu(pstep->pos_new); if (pcinfo->req_fver != pstep->fver) - return; + return 0; /* store step info by using ring instead of FIFO*/ do { @@ -9877,13 +9967,15 @@ static void _show_fbtc_step_v2(struct rtw89_dev *rtwdev, struct seq_file *m) continue; if (cnt % 10 == 0) - seq_printf(m, " %-15s : ", "[steps]"); + p += scnprintf(p, end - p, + " %-15s : ", "[steps]"); - seq_printf(m, "-> %s(%02d)(%02d)", - (type == CXSTEP_SLOT ? "SLT" : - "EVT"), (u32)val, diff_t); + p += scnprintf(p, end - p, + "-> %s(%02d)(%02d)", + (type == CXSTEP_SLOT ? "SLT" : + "EVT"), (u32)val, diff_t); if (cnt % 10 == 9) - seq_puts(m, "\n"); + p += scnprintf(p, end - p, "\n"); cnt++; } @@ -9900,29 +9992,32 @@ static void _show_fbtc_step_v2(struct rtw89_dev *rtwdev, struct seq_file *m) break; } } while (!outloop); + + return p - buf; } -static void _show_fbtc_step_v3(struct rtw89_dev *rtwdev, struct seq_file *m) +static int _show_fbtc_step_v3(struct rtw89_dev *rtwdev, char *buf, size_t bufsz) { struct rtw89_btc *btc = &rtwdev->btc; struct rtw89_btc_btf_fwinfo *pfwinfo = &btc->fwinfo; struct rtw89_btc_rpt_cmn_info *pcinfo; struct rtw89_btc_fbtc_steps_v3 *pstep; u32 i, n_begin, n_end, array_idx, cnt = 0; + char *p = buf, *end = buf + bufsz; u8 type, val; u16 diff_t; if ((pfwinfo->rpt_en_map & rtw89_btc_fw_rpt_ver(rtwdev, RPT_EN_FW_STEP_INFO)) == 0) - return; + return 0; pcinfo = &pfwinfo->rpt_fbtc_step.cinfo; if (!pcinfo->valid) - return; + return 0; pstep = &pfwinfo->rpt_fbtc_step.finfo.v3; if (pcinfo->req_fver != pstep->fver) - return; + return 0; if (le32_to_cpu(pstep->cnt) <= FCXDEF_STEP) n_begin = 1; @@ -9932,7 +10027,7 @@ static void _show_fbtc_step_v3(struct rtw89_dev *rtwdev, struct seq_file *m) n_end = le32_to_cpu(pstep->cnt); if (n_begin > n_end) - return; + return 0; /* restore step info by using ring instead of FIFO */ for (i = n_begin; i <= n_end; i++) { @@ -9945,50 +10040,55 @@ static void _show_fbtc_step_v3(struct rtw89_dev *rtwdev, struct seq_file *m) continue; if (cnt % 10 == 0) - seq_printf(m, " %-15s : ", "[steps]"); + p += scnprintf(p, end - p, " %-15s : ", "[steps]"); - seq_printf(m, "-> %s(%02d)", - (type == CXSTEP_SLOT ? - id_to_slot((u32)val) : - id_to_evt((u32)val)), diff_t); + p += scnprintf(p, end - p, "-> %s(%02d)", + (type == CXSTEP_SLOT ? + id_to_slot((u32)val) : + id_to_evt((u32)val)), diff_t); if (cnt % 10 == 9) - seq_puts(m, "\n"); + p += scnprintf(p, end - p, "\n"); cnt++; } + + return p - buf; } -static void _show_fw_dm_msg(struct rtw89_dev *rtwdev, struct seq_file *m) +static int _show_fw_dm_msg(struct rtw89_dev *rtwdev, char *buf, size_t bufsz) { struct rtw89_btc *btc = &rtwdev->btc; const struct rtw89_btc_ver *ver = btc->ver; + char *p = buf, *end = buf + bufsz; if (!(btc->dm.coex_info_map & BTC_COEX_INFO_DM)) - return; + goto out; - _show_error(rtwdev, m); - _show_fbtc_tdma(rtwdev, m); - _show_fbtc_slots(rtwdev, m); + p += _show_error(rtwdev, p, end - p); + p += _show_fbtc_tdma(rtwdev, p, end - p); + p += _show_fbtc_slots(rtwdev, p, end - p); if (ver->fcxcysta == 2) - _show_fbtc_cysta_v2(rtwdev, m); + p += _show_fbtc_cysta_v2(rtwdev, p, end - p); else if (ver->fcxcysta == 3) - _show_fbtc_cysta_v3(rtwdev, m); + p += _show_fbtc_cysta_v3(rtwdev, p, end - p); else if (ver->fcxcysta == 4) - _show_fbtc_cysta_v4(rtwdev, m); + p += _show_fbtc_cysta_v4(rtwdev, p, end - p); else if (ver->fcxcysta == 5) - _show_fbtc_cysta_v5(rtwdev, m); + p += _show_fbtc_cysta_v5(rtwdev, p, end - p); else if (ver->fcxcysta == 7) - _show_fbtc_cysta_v7(rtwdev, m); + p += _show_fbtc_cysta_v7(rtwdev, p, end - p); - _show_fbtc_nullsta(rtwdev, m); + p += _show_fbtc_nullsta(rtwdev, p, end - p); if (ver->fcxstep == 2) - _show_fbtc_step_v2(rtwdev, m); + p += _show_fbtc_step_v2(rtwdev, p, end - p); else if (ver->fcxstep == 3) - _show_fbtc_step_v3(rtwdev, m); + p += _show_fbtc_step_v3(rtwdev, p, end - p); +out: + return p - buf; } static void _get_gnt(struct rtw89_dev *rtwdev, struct rtw89_mac_ax_coex_gnt *gnt_cfg) @@ -10033,12 +10133,13 @@ static void _get_gnt(struct rtw89_dev *rtwdev, struct rtw89_mac_ax_coex_gnt *gnt } } -static void _show_gpio_dbg(struct rtw89_dev *rtwdev, struct seq_file *m) +static int _show_gpio_dbg(struct rtw89_dev *rtwdev, char *buf, size_t bufsz) { struct rtw89_btc_btf_fwinfo *pfwinfo = &rtwdev->btc.fwinfo; const struct rtw89_btc_ver *ver = rtwdev->btc.ver; struct rtw89_btc_rpt_cmn_info *pcinfo = NULL; union rtw89_btc_fbtc_gpio_dbg *gdbg = NULL; + char *p = buf, *end = buf + bufsz; u8 *gpio_map, i; u32 en_map; @@ -10048,8 +10149,8 @@ static void _show_gpio_dbg(struct rtw89_dev *rtwdev, struct seq_file *m) rtw89_debug(rtwdev, RTW89_DBG_BTC, "[BTC], %s(): stop due rpt_fbtc_gpio_dbg.cinfo\n", __func__); - seq_puts(m, "\n"); - return; + p += scnprintf(p, end - p, "\n"); + goto out; } if (ver->fcxgpiodbg == 7) { @@ -10061,20 +10162,24 @@ static void _show_gpio_dbg(struct rtw89_dev *rtwdev, struct seq_file *m) } if (!en_map) - return; + goto out; - seq_printf(m, " %-15s : enable_map:0x%08x", - "[gpio_dbg]", en_map); + p += scnprintf(p, end - p, " %-15s : enable_map:0x%08x", + "[gpio_dbg]", en_map); for (i = 0; i < BTC_DBG_MAX1; i++) { if (!(en_map & BIT(i))) continue; - seq_printf(m, ", %s->GPIO%d", id_to_gdbg(i), gpio_map[i]); + p += scnprintf(p, end - p, ", %s->GPIO%d", id_to_gdbg(i), + gpio_map[i]); } - seq_puts(m, "\n"); + p += scnprintf(p, end - p, "\n"); + +out: + return p - buf; } -static void _show_mreg_v1(struct rtw89_dev *rtwdev, struct seq_file *m) +static int _show_mreg_v1(struct rtw89_dev *rtwdev, char *buf, size_t bufsz) { const struct rtw89_chip_info *chip = rtwdev->chip; struct rtw89_btc *btc = &rtwdev->btc; @@ -10086,45 +10191,47 @@ static void _show_mreg_v1(struct rtw89_dev *rtwdev, struct seq_file *m) struct rtw89_btc_bt_info *bt = &btc->cx.bt; struct rtw89_mac_ax_coex_gnt gnt_cfg = {}; struct rtw89_mac_ax_gnt gnt; + char *p = buf, *end = buf + bufsz; u8 i = 0, type = 0, cnt = 0; u32 val, offset; if (!(btc->dm.coex_info_map & BTC_COEX_INFO_MREG)) - return; + return 0; - seq_puts(m, "========== [HW Status] ==========\n"); + p += scnprintf(p, end - p, "========== [HW Status] ==========\n"); - seq_printf(m, - " %-15s : WL->BT:0x%08x(cnt:%d), BT->WL:0x%08x(total:%d, bt_update:%d)\n", - "[scoreboard]", wl->scbd, cx->cnt_wl[BTC_WCNT_SCBDUPDATE], - bt->scbd, cx->cnt_bt[BTC_BCNT_SCBDREAD], - cx->cnt_bt[BTC_BCNT_SCBDUPDATE]); + p += scnprintf(p, end - p, + " %-15s : WL->BT:0x%08x(cnt:%d), BT->WL:0x%08x(total:%d, bt_update:%d)\n", + "[scoreboard]", wl->scbd, + cx->cnt_wl[BTC_WCNT_SCBDUPDATE], + bt->scbd, cx->cnt_bt[BTC_BCNT_SCBDREAD], + cx->cnt_bt[BTC_BCNT_SCBDUPDATE]); btc->dm.pta_owner = rtw89_mac_get_ctrl_path(rtwdev); _get_gnt(rtwdev, &gnt_cfg); gnt = gnt_cfg.band[0]; - seq_printf(m, - " %-15s : pta_owner:%s, phy-0[gnt_wl:%s-%d/gnt_bt:%s-%d], ", - "[gnt_status]", - chip->chip_id == RTL8852C ? "HW" : - btc->dm.pta_owner == BTC_CTRL_BY_WL ? "WL" : "BT", - gnt.gnt_wl_sw_en ? "SW" : "HW", gnt.gnt_wl, - gnt.gnt_bt_sw_en ? "SW" : "HW", gnt.gnt_bt); + p += scnprintf(p, end - p, + " %-15s : pta_owner:%s, phy-0[gnt_wl:%s-%d/gnt_bt:%s-%d], ", + "[gnt_status]", + chip->chip_id == RTL8852C ? "HW" : + btc->dm.pta_owner == BTC_CTRL_BY_WL ? "WL" : "BT", + gnt.gnt_wl_sw_en ? "SW" : "HW", gnt.gnt_wl, + gnt.gnt_bt_sw_en ? "SW" : "HW", gnt.gnt_bt); gnt = gnt_cfg.band[1]; - seq_printf(m, "phy-1[gnt_wl:%s-%d/gnt_bt:%s-%d]\n", - gnt.gnt_wl_sw_en ? "SW" : "HW", - gnt.gnt_wl, - gnt.gnt_bt_sw_en ? "SW" : "HW", - gnt.gnt_bt); + p += scnprintf(p, end - p, "phy-1[gnt_wl:%s-%d/gnt_bt:%s-%d]\n", + gnt.gnt_wl_sw_en ? "SW" : "HW", + gnt.gnt_wl, + gnt.gnt_bt_sw_en ? "SW" : "HW", + gnt.gnt_bt); pcinfo = &pfwinfo->rpt_fbtc_mregval.cinfo; if (!pcinfo->valid) { rtw89_debug(rtwdev, RTW89_DBG_BTC, "[BTC], %s(): stop due rpt_fbtc_mregval.cinfo\n", __func__); - return; + goto out; } pmreg = &pfwinfo->rpt_fbtc_mregval.finfo.v1; @@ -10138,21 +10245,26 @@ static void _show_mreg_v1(struct rtw89_dev *rtwdev, struct seq_file *m) val = le32_to_cpu(pmreg->mreg_val[i]); if (cnt % 6 == 0) - seq_printf(m, " %-15s : %d_0x%04x=0x%08x", - "[reg]", (u32)type, offset, val); + p += scnprintf(p, end - p, + " %-15s : %d_0x%04x=0x%08x", + "[reg]", (u32)type, offset, val); else - seq_printf(m, ", %d_0x%04x=0x%08x", (u32)type, - offset, val); + p += scnprintf(p, end - p, ", %d_0x%04x=0x%08x", + (u32)type, + offset, val); if (cnt % 6 == 5) - seq_puts(m, "\n"); + p += scnprintf(p, end - p, "\n"); cnt++; if (i >= pmreg->reg_num) - seq_puts(m, "\n"); + p += scnprintf(p, end - p, "\n"); } + +out: + return p - buf; } -static void _show_mreg_v2(struct rtw89_dev *rtwdev, struct seq_file *m) +static int _show_mreg_v2(struct rtw89_dev *rtwdev, char *buf, size_t bufsz) { const struct rtw89_chip_info *chip = rtwdev->chip; struct rtw89_btc *btc = &rtwdev->btc; @@ -10164,46 +10276,48 @@ static void _show_mreg_v2(struct rtw89_dev *rtwdev, struct seq_file *m) struct rtw89_btc_bt_info *bt = &btc->cx.bt; struct rtw89_mac_ax_coex_gnt gnt_cfg = {}; struct rtw89_mac_ax_gnt gnt; + char *p = buf, *end = buf + bufsz; u8 i = 0, type = 0, cnt = 0; u32 val, offset; if (!(btc->dm.coex_info_map & BTC_COEX_INFO_MREG)) - return; + return 0; - seq_puts(m, "========== [HW Status] ==========\n"); + p += scnprintf(p, end - p, "========== [HW Status] ==========\n"); - seq_printf(m, - " %-15s : WL->BT:0x%08x(cnt:%d), BT->WL:0x%08x(total:%d, bt_update:%d)\n", - "[scoreboard]", wl->scbd, cx->cnt_wl[BTC_WCNT_SCBDUPDATE], - bt->scbd, cx->cnt_bt[BTC_BCNT_SCBDREAD], - cx->cnt_bt[BTC_BCNT_SCBDUPDATE]); + p += scnprintf(p, end - p, + " %-15s : WL->BT:0x%08x(cnt:%d), BT->WL:0x%08x(total:%d, bt_update:%d)\n", + "[scoreboard]", wl->scbd, + cx->cnt_wl[BTC_WCNT_SCBDUPDATE], + bt->scbd, cx->cnt_bt[BTC_BCNT_SCBDREAD], + cx->cnt_bt[BTC_BCNT_SCBDUPDATE]); btc->dm.pta_owner = rtw89_mac_get_ctrl_path(rtwdev); _get_gnt(rtwdev, &gnt_cfg); gnt = gnt_cfg.band[0]; - seq_printf(m, - " %-15s : pta_owner:%s, phy-0[gnt_wl:%s-%d/gnt_bt:%s-%d], polut_type:%s", - "[gnt_status]", - chip->chip_id == RTL8852C ? "HW" : - btc->dm.pta_owner == BTC_CTRL_BY_WL ? "WL" : "BT", - gnt.gnt_wl_sw_en ? "SW" : "HW", gnt.gnt_wl, - gnt.gnt_bt_sw_en ? "SW" : "HW", gnt.gnt_bt, - id_to_polut(wl->bt_polut_type[wl->pta_req_mac])); + p += scnprintf(p, end - p, + " %-15s : pta_owner:%s, phy-0[gnt_wl:%s-%d/gnt_bt:%s-%d], polut_type:%s", + "[gnt_status]", + chip->chip_id == RTL8852C ? "HW" : + btc->dm.pta_owner == BTC_CTRL_BY_WL ? "WL" : "BT", + gnt.gnt_wl_sw_en ? "SW" : "HW", gnt.gnt_wl, + gnt.gnt_bt_sw_en ? "SW" : "HW", gnt.gnt_bt, + id_to_polut(wl->bt_polut_type[wl->pta_req_mac])); gnt = gnt_cfg.band[1]; - seq_printf(m, "phy-1[gnt_wl:%s-%d/gnt_bt:%s-%d]\n", - gnt.gnt_wl_sw_en ? "SW" : "HW", - gnt.gnt_wl, - gnt.gnt_bt_sw_en ? "SW" : "HW", - gnt.gnt_bt); + p += scnprintf(p, end - p, "phy-1[gnt_wl:%s-%d/gnt_bt:%s-%d]\n", + gnt.gnt_wl_sw_en ? "SW" : "HW", + gnt.gnt_wl, + gnt.gnt_bt_sw_en ? "SW" : "HW", + gnt.gnt_bt); pcinfo = &pfwinfo->rpt_fbtc_mregval.cinfo; if (!pcinfo->valid) { rtw89_debug(rtwdev, RTW89_DBG_BTC, "[BTC], %s(): stop due rpt_fbtc_mregval.cinfo\n", __func__); - return; + goto out; } pmreg = &pfwinfo->rpt_fbtc_mregval.finfo.v2; @@ -10217,21 +10331,26 @@ static void _show_mreg_v2(struct rtw89_dev *rtwdev, struct seq_file *m) val = le32_to_cpu(pmreg->mreg_val[i]); if (cnt % 6 == 0) - seq_printf(m, " %-15s : %d_0x%04x=0x%08x", - "[reg]", (u32)type, offset, val); + p += scnprintf(p, end - p, + " %-15s : %d_0x%04x=0x%08x", + "[reg]", (u32)type, offset, val); else - seq_printf(m, ", %d_0x%04x=0x%08x", (u32)type, - offset, val); + p += scnprintf(p, end - p, ", %d_0x%04x=0x%08x", + (u32)type, + offset, val); if (cnt % 6 == 5) - seq_puts(m, "\n"); + p += scnprintf(p, end - p, "\n"); cnt++; if (i >= pmreg->reg_num) - seq_puts(m, "\n"); + p += scnprintf(p, end - p, "\n"); } + +out: + return p - buf; } -static void _show_mreg_v7(struct rtw89_dev *rtwdev, struct seq_file *m) +static int _show_mreg_v7(struct rtw89_dev *rtwdev, char *buf, size_t bufsz) { struct rtw89_btc *btc = &rtwdev->btc; struct rtw89_btc_btf_fwinfo *pfwinfo = &btc->fwinfo; @@ -10242,46 +10361,50 @@ static void _show_mreg_v7(struct rtw89_dev *rtwdev, struct seq_file *m) struct rtw89_btc_bt_info *bt = &cx->bt; struct rtw89_mac_ax_gnt *gnt = NULL; struct rtw89_btc_dm *dm = &btc->dm; + char *p = buf, *end = buf + bufsz; u8 i, type, cnt = 0; u32 val, offset; if (!(dm->coex_info_map & BTC_COEX_INFO_MREG)) - return; + return 0; - seq_puts(m, "\n\r========== [HW Status] =========="); + p += scnprintf(p, end - p, "\n\r========== [HW Status] =========="); - seq_printf(m, - "\n\r %-15s : WL->BT:0x%08x(cnt:%d), BT->WL:0x%08x(total:%d, bt_update:%d)", - "[scoreboard]", wl->scbd, cx->cnt_wl[BTC_WCNT_SCBDUPDATE], - bt->scbd, cx->cnt_bt[BTC_BCNT_SCBDREAD], - cx->cnt_bt[BTC_BCNT_SCBDUPDATE]); + p += scnprintf(p, end - p, + "\n\r %-15s : WL->BT:0x%08x(cnt:%d), BT->WL:0x%08x(total:%d, bt_update:%d)", + "[scoreboard]", wl->scbd, + cx->cnt_wl[BTC_WCNT_SCBDUPDATE], + bt->scbd, cx->cnt_bt[BTC_BCNT_SCBDREAD], + cx->cnt_bt[BTC_BCNT_SCBDUPDATE]); /* To avoid I/O if WL LPS or power-off */ dm->pta_owner = rtw89_mac_get_ctrl_path(rtwdev); - seq_printf(m, - "\n\r %-15s : pta_owner:%s, pta_req_mac:MAC%d, rf_gnt_source: polut_type:%s", - "[gnt_status]", - rtwdev->chip->para_ver & BTC_FEAT_PTA_ONOFF_CTRL ? "HW" : - dm->pta_owner == BTC_CTRL_BY_WL ? "WL" : "BT", - wl->pta_req_mac, id_to_polut(wl->bt_polut_type[wl->pta_req_mac])); + p += scnprintf(p, end - p, + "\n\r %-15s : pta_owner:%s, pta_req_mac:MAC%d, rf_gnt_source: polut_type:%s", + "[gnt_status]", + rtwdev->chip->para_ver & BTC_FEAT_PTA_ONOFF_CTRL ? "HW" : + dm->pta_owner == BTC_CTRL_BY_WL ? "WL" : "BT", + wl->pta_req_mac, + id_to_polut(wl->bt_polut_type[wl->pta_req_mac])); gnt = &dm->gnt.band[RTW89_PHY_0]; - seq_printf(m, ", phy-0[gnt_wl:%s-%d/gnt_bt:%s-%d]", - gnt->gnt_wl_sw_en ? "SW" : "HW", gnt->gnt_wl, - gnt->gnt_bt_sw_en ? "SW" : "HW", gnt->gnt_bt); + p += scnprintf(p, end - p, ", phy-0[gnt_wl:%s-%d/gnt_bt:%s-%d]", + gnt->gnt_wl_sw_en ? "SW" : "HW", gnt->gnt_wl, + gnt->gnt_bt_sw_en ? "SW" : "HW", gnt->gnt_bt); if (rtwdev->dbcc_en) { gnt = &dm->gnt.band[RTW89_PHY_1]; - seq_printf(m, ", phy-1[gnt_wl:%s-%d/gnt_bt:%s-%d]", - gnt->gnt_wl_sw_en ? "SW" : "HW", gnt->gnt_wl, - gnt->gnt_bt_sw_en ? "SW" : "HW", gnt->gnt_bt); + p += scnprintf(p, end - p, + ", phy-1[gnt_wl:%s-%d/gnt_bt:%s-%d]", + gnt->gnt_wl_sw_en ? "SW" : "HW", gnt->gnt_wl, + gnt->gnt_bt_sw_en ? "SW" : "HW", gnt->gnt_bt); } pcinfo = &pfwinfo->rpt_fbtc_mregval.cinfo; if (!pcinfo->valid) - return; + goto out; pmreg = &pfwinfo->rpt_fbtc_mregval.finfo.v7; @@ -10291,17 +10414,21 @@ static void _show_mreg_v7(struct rtw89_dev *rtwdev, struct seq_file *m) val = le32_to_cpu(pmreg->mreg_val[i]); if (cnt % 6 == 0) - seq_printf(m, "\n\r %-15s : %s_0x%x=0x%x", "[reg]", - id_to_regtype(type), offset, val); + p += scnprintf(p, end - p, + "\n\r %-15s : %s_0x%x=0x%x", "[reg]", + id_to_regtype(type), offset, val); else - seq_printf(m, ", %s_0x%x=0x%x", - id_to_regtype(type), offset, val); + p += scnprintf(p, end - p, ", %s_0x%x=0x%x", + id_to_regtype(type), offset, val); cnt++; } - seq_puts(m, "\n"); + p += scnprintf(p, end - p, "\n"); + +out: + return p - buf; } -static void _show_summary_v1(struct rtw89_dev *rtwdev, struct seq_file *m) +static int _show_summary_v1(struct rtw89_dev *rtwdev, char *buf, size_t bufsz) { struct rtw89_btc *btc = &rtwdev->btc; struct rtw89_btc_btf_fwinfo *pfwinfo = &btc->fwinfo; @@ -10312,56 +10439,59 @@ static void _show_summary_v1(struct rtw89_dev *rtwdev, struct seq_file *m) struct rtw89_btc_wl_info *wl = &cx->wl; struct rtw89_btc_bt_info *bt = &cx->bt; u32 cnt_sum = 0, *cnt = btc->dm.cnt_notify; + char *p = buf, *end = buf + bufsz; u8 i; if (!(dm->coex_info_map & BTC_COEX_INFO_SUMMARY)) - return; + return 0; - seq_puts(m, "========== [Statistics] ==========\n"); + p += scnprintf(p, end - p, "========== [Statistics] ==========\n"); pcinfo = &pfwinfo->rpt_ctrl.cinfo; if (pcinfo->valid && !wl->status.map.lps && !wl->status.map.rf_off) { prptctrl = &pfwinfo->rpt_ctrl.finfo.v1; - seq_printf(m, - " %-15s : h2c_cnt=%d(fail:%d, fw_recv:%d), c2h_cnt=%d(fw_send:%d), ", - "[summary]", pfwinfo->cnt_h2c, - pfwinfo->cnt_h2c_fail, prptctrl->h2c_cnt, - pfwinfo->cnt_c2h, prptctrl->c2h_cnt); + p += scnprintf(p, end - p, + " %-15s : h2c_cnt=%d(fail:%d, fw_recv:%d), c2h_cnt=%d(fw_send:%d), ", + "[summary]", pfwinfo->cnt_h2c, + pfwinfo->cnt_h2c_fail, prptctrl->h2c_cnt, + pfwinfo->cnt_c2h, prptctrl->c2h_cnt); - seq_printf(m, - "rpt_cnt=%d(fw_send:%d), rpt_map=0x%x, dm_error_map:0x%x", - pfwinfo->event[BTF_EVNT_RPT], prptctrl->rpt_cnt, - prptctrl->rpt_enable, dm->error.val); + p += scnprintf(p, end - p, + "rpt_cnt=%d(fw_send:%d), rpt_map=0x%x, dm_error_map:0x%x", + pfwinfo->event[BTF_EVNT_RPT], + prptctrl->rpt_cnt, + prptctrl->rpt_enable, dm->error.val); if (dm->error.map.wl_fw_hang) - seq_puts(m, " (WL FW Hang!!)"); - seq_puts(m, "\n"); - seq_printf(m, - " %-15s : send_ok:%d, send_fail:%d, recv:%d", - "[mailbox]", prptctrl->mb_send_ok_cnt, - prptctrl->mb_send_fail_cnt, prptctrl->mb_recv_cnt); - - seq_printf(m, - "(A2DP_empty:%d, A2DP_flowstop:%d, A2DP_full:%d)\n", - prptctrl->mb_a2dp_empty_cnt, - prptctrl->mb_a2dp_flct_cnt, - prptctrl->mb_a2dp_full_cnt); - - seq_printf(m, - " %-15s : wl_rfk[req:%d/go:%d/reject:%d/timeout:%d]", - "[RFK]", cx->cnt_wl[BTC_WCNT_RFK_REQ], - cx->cnt_wl[BTC_WCNT_RFK_GO], - cx->cnt_wl[BTC_WCNT_RFK_REJECT], - cx->cnt_wl[BTC_WCNT_RFK_TIMEOUT]); - - seq_printf(m, - ", bt_rfk[req:%d/go:%d/reject:%d/timeout:%d/fail:%d]\n", - prptctrl->bt_rfk_cnt[BTC_BCNT_RFK_REQ], - prptctrl->bt_rfk_cnt[BTC_BCNT_RFK_GO], - prptctrl->bt_rfk_cnt[BTC_BCNT_RFK_REJECT], - prptctrl->bt_rfk_cnt[BTC_BCNT_RFK_TIMEOUT], - prptctrl->bt_rfk_cnt[BTC_BCNT_RFK_FAIL]); + p += scnprintf(p, end - p, " (WL FW Hang!!)"); + p += scnprintf(p, end - p, "\n"); + p += scnprintf(p, end - p, + " %-15s : send_ok:%d, send_fail:%d, recv:%d", + "[mailbox]", prptctrl->mb_send_ok_cnt, + prptctrl->mb_send_fail_cnt, + prptctrl->mb_recv_cnt); + + p += scnprintf(p, end - p, + "(A2DP_empty:%d, A2DP_flowstop:%d, A2DP_full:%d)\n", + prptctrl->mb_a2dp_empty_cnt, + prptctrl->mb_a2dp_flct_cnt, + prptctrl->mb_a2dp_full_cnt); + + p += scnprintf(p, end - p, + " %-15s : wl_rfk[req:%d/go:%d/reject:%d/timeout:%d]", + "[RFK]", cx->cnt_wl[BTC_WCNT_RFK_REQ], + cx->cnt_wl[BTC_WCNT_RFK_GO], + cx->cnt_wl[BTC_WCNT_RFK_REJECT], + cx->cnt_wl[BTC_WCNT_RFK_TIMEOUT]); + + p += scnprintf(p, end - p, + ", bt_rfk[req:%d/go:%d/reject:%d/timeout:%d/fail:%d]\n", + prptctrl->bt_rfk_cnt[BTC_BCNT_RFK_REQ], + prptctrl->bt_rfk_cnt[BTC_BCNT_RFK_GO], + prptctrl->bt_rfk_cnt[BTC_BCNT_RFK_REJECT], + prptctrl->bt_rfk_cnt[BTC_BCNT_RFK_TIMEOUT], + prptctrl->bt_rfk_cnt[BTC_BCNT_RFK_FAIL]); if (prptctrl->bt_rfk_cnt[BTC_BCNT_RFK_TIMEOUT] > 0) bt->rfk_info.map.timeout = 1; @@ -10370,42 +10500,44 @@ static void _show_summary_v1(struct rtw89_dev *rtwdev, struct seq_file *m) dm->error.map.wl_rfk_timeout = bt->rfk_info.map.timeout; } else { - seq_printf(m, - " %-15s : h2c_cnt=%d(fail:%d), c2h_cnt=%d, rpt_cnt=%d, rpt_map=0x%x", - "[summary]", pfwinfo->cnt_h2c, - pfwinfo->cnt_h2c_fail, pfwinfo->cnt_c2h, - pfwinfo->event[BTF_EVNT_RPT], - btc->fwinfo.rpt_en_map); - seq_puts(m, " (WL FW report invalid!!)\n"); + p += scnprintf(p, end - p, + " %-15s : h2c_cnt=%d(fail:%d), c2h_cnt=%d, rpt_cnt=%d, rpt_map=0x%x", + "[summary]", pfwinfo->cnt_h2c, + pfwinfo->cnt_h2c_fail, pfwinfo->cnt_c2h, + pfwinfo->event[BTF_EVNT_RPT], + btc->fwinfo.rpt_en_map); + p += scnprintf(p, end - p, " (WL FW report invalid!!)\n"); } for (i = 0; i < BTC_NCNT_NUM; i++) cnt_sum += dm->cnt_notify[i]; - seq_printf(m, - " %-15s : total=%d, show_coex_info=%d, power_on=%d, init_coex=%d, ", - "[notify_cnt]", cnt_sum, cnt[BTC_NCNT_SHOW_COEX_INFO], - cnt[BTC_NCNT_POWER_ON], cnt[BTC_NCNT_INIT_COEX]); + p += scnprintf(p, end - p, + " %-15s : total=%d, show_coex_info=%d, power_on=%d, init_coex=%d, ", + "[notify_cnt]", cnt_sum, cnt[BTC_NCNT_SHOW_COEX_INFO], + cnt[BTC_NCNT_POWER_ON], cnt[BTC_NCNT_INIT_COEX]); + + p += scnprintf(p, end - p, + "power_off=%d, radio_state=%d, role_info=%d, wl_rfk=%d, wl_sta=%d\n", + cnt[BTC_NCNT_POWER_OFF], cnt[BTC_NCNT_RADIO_STATE], + cnt[BTC_NCNT_ROLE_INFO], cnt[BTC_NCNT_WL_RFK], + cnt[BTC_NCNT_WL_STA]); - seq_printf(m, - "power_off=%d, radio_state=%d, role_info=%d, wl_rfk=%d, wl_sta=%d\n", - cnt[BTC_NCNT_POWER_OFF], cnt[BTC_NCNT_RADIO_STATE], - cnt[BTC_NCNT_ROLE_INFO], cnt[BTC_NCNT_WL_RFK], - cnt[BTC_NCNT_WL_STA]); + p += scnprintf(p, end - p, + " %-15s : scan_start=%d, scan_finish=%d, switch_band=%d, special_pkt=%d, ", + "[notify_cnt]", cnt[BTC_NCNT_SCAN_START], + cnt[BTC_NCNT_SCAN_FINISH], cnt[BTC_NCNT_SWITCH_BAND], + cnt[BTC_NCNT_SPECIAL_PACKET]); - seq_printf(m, - " %-15s : scan_start=%d, scan_finish=%d, switch_band=%d, special_pkt=%d, ", - "[notify_cnt]", cnt[BTC_NCNT_SCAN_START], - cnt[BTC_NCNT_SCAN_FINISH], cnt[BTC_NCNT_SWITCH_BAND], - cnt[BTC_NCNT_SPECIAL_PACKET]); + p += scnprintf(p, end - p, + "timer=%d, control=%d, customerize=%d\n", + cnt[BTC_NCNT_TIMER], cnt[BTC_NCNT_CONTROL], + cnt[BTC_NCNT_CUSTOMERIZE]); - seq_printf(m, - "timer=%d, control=%d, customerize=%d\n", - cnt[BTC_NCNT_TIMER], cnt[BTC_NCNT_CONTROL], - cnt[BTC_NCNT_CUSTOMERIZE]); + return p - buf; } -static void _show_summary_v4(struct rtw89_dev *rtwdev, struct seq_file *m) +static int _show_summary_v4(struct rtw89_dev *rtwdev, char *buf, size_t bufsz) { struct rtw89_btc *btc = &rtwdev->btc; struct rtw89_btc_btf_fwinfo *pfwinfo = &btc->fwinfo; @@ -10416,64 +10548,65 @@ static void _show_summary_v4(struct rtw89_dev *rtwdev, struct seq_file *m) struct rtw89_btc_wl_info *wl = &cx->wl; struct rtw89_btc_bt_info *bt = &cx->bt; u32 cnt_sum = 0, *cnt = btc->dm.cnt_notify; + char *p = buf, *end = buf + bufsz; u8 i; if (!(dm->coex_info_map & BTC_COEX_INFO_SUMMARY)) - return; + return 0; - seq_puts(m, "========== [Statistics] ==========\n"); + p += scnprintf(p, end - p, "========== [Statistics] ==========\n"); pcinfo = &pfwinfo->rpt_ctrl.cinfo; if (pcinfo->valid && !wl->status.map.lps && !wl->status.map.rf_off) { prptctrl = &pfwinfo->rpt_ctrl.finfo.v4; - seq_printf(m, - " %-15s : h2c_cnt=%d(fail:%d, fw_recv:%d), c2h_cnt=%d(fw_send:%d), ", - "[summary]", pfwinfo->cnt_h2c, - pfwinfo->cnt_h2c_fail, - le32_to_cpu(prptctrl->rpt_info.cnt_h2c), - pfwinfo->cnt_c2h, - le32_to_cpu(prptctrl->rpt_info.cnt_c2h)); - - seq_printf(m, - "rpt_cnt=%d(fw_send:%d), rpt_map=0x%x, dm_error_map:0x%x", - pfwinfo->event[BTF_EVNT_RPT], - le32_to_cpu(prptctrl->rpt_info.cnt), - le32_to_cpu(prptctrl->rpt_info.en), - dm->error.val); + p += scnprintf(p, end - p, + " %-15s : h2c_cnt=%d(fail:%d, fw_recv:%d), c2h_cnt=%d(fw_send:%d), ", + "[summary]", pfwinfo->cnt_h2c, + pfwinfo->cnt_h2c_fail, + le32_to_cpu(prptctrl->rpt_info.cnt_h2c), + pfwinfo->cnt_c2h, + le32_to_cpu(prptctrl->rpt_info.cnt_c2h)); + + p += scnprintf(p, end - p, + "rpt_cnt=%d(fw_send:%d), rpt_map=0x%x, dm_error_map:0x%x", + pfwinfo->event[BTF_EVNT_RPT], + le32_to_cpu(prptctrl->rpt_info.cnt), + le32_to_cpu(prptctrl->rpt_info.en), + dm->error.val); if (dm->error.map.wl_fw_hang) - seq_puts(m, " (WL FW Hang!!)"); - seq_puts(m, "\n"); - seq_printf(m, - " %-15s : send_ok:%d, send_fail:%d, recv:%d, ", - "[mailbox]", - le32_to_cpu(prptctrl->bt_mbx_info.cnt_send_ok), - le32_to_cpu(prptctrl->bt_mbx_info.cnt_send_fail), - le32_to_cpu(prptctrl->bt_mbx_info.cnt_recv)); - - seq_printf(m, - "A2DP_empty:%d(stop:%d, tx:%d, ack:%d, nack:%d)\n", - le32_to_cpu(prptctrl->bt_mbx_info.a2dp.cnt_empty), - le32_to_cpu(prptctrl->bt_mbx_info.a2dp.cnt_flowctrl), - le32_to_cpu(prptctrl->bt_mbx_info.a2dp.cnt_tx), - le32_to_cpu(prptctrl->bt_mbx_info.a2dp.cnt_ack), - le32_to_cpu(prptctrl->bt_mbx_info.a2dp.cnt_nack)); - - seq_printf(m, - " %-15s : wl_rfk[req:%d/go:%d/reject:%d/timeout:%d]", - "[RFK]", cx->cnt_wl[BTC_WCNT_RFK_REQ], - cx->cnt_wl[BTC_WCNT_RFK_GO], - cx->cnt_wl[BTC_WCNT_RFK_REJECT], - cx->cnt_wl[BTC_WCNT_RFK_TIMEOUT]); - - seq_printf(m, - ", bt_rfk[req:%d/go:%d/reject:%d/timeout:%d/fail:%d]\n", - le32_to_cpu(prptctrl->bt_cnt[BTC_BCNT_RFK_REQ]), - le32_to_cpu(prptctrl->bt_cnt[BTC_BCNT_RFK_GO]), - le32_to_cpu(prptctrl->bt_cnt[BTC_BCNT_RFK_REJECT]), - le32_to_cpu(prptctrl->bt_cnt[BTC_BCNT_RFK_TIMEOUT]), - le32_to_cpu(prptctrl->bt_cnt[BTC_BCNT_RFK_FAIL])); + p += scnprintf(p, end - p, " (WL FW Hang!!)"); + p += scnprintf(p, end - p, "\n"); + p += scnprintf(p, end - p, + " %-15s : send_ok:%d, send_fail:%d, recv:%d, ", + "[mailbox]", + le32_to_cpu(prptctrl->bt_mbx_info.cnt_send_ok), + le32_to_cpu(prptctrl->bt_mbx_info.cnt_send_fail), + le32_to_cpu(prptctrl->bt_mbx_info.cnt_recv)); + + p += scnprintf(p, end - p, + "A2DP_empty:%d(stop:%d, tx:%d, ack:%d, nack:%d)\n", + le32_to_cpu(prptctrl->bt_mbx_info.a2dp.cnt_empty), + le32_to_cpu(prptctrl->bt_mbx_info.a2dp.cnt_flowctrl), + le32_to_cpu(prptctrl->bt_mbx_info.a2dp.cnt_tx), + le32_to_cpu(prptctrl->bt_mbx_info.a2dp.cnt_ack), + le32_to_cpu(prptctrl->bt_mbx_info.a2dp.cnt_nack)); + + p += scnprintf(p, end - p, + " %-15s : wl_rfk[req:%d/go:%d/reject:%d/timeout:%d]", + "[RFK]", cx->cnt_wl[BTC_WCNT_RFK_REQ], + cx->cnt_wl[BTC_WCNT_RFK_GO], + cx->cnt_wl[BTC_WCNT_RFK_REJECT], + cx->cnt_wl[BTC_WCNT_RFK_TIMEOUT]); + + p += scnprintf(p, end - p, + ", bt_rfk[req:%d/go:%d/reject:%d/timeout:%d/fail:%d]\n", + le32_to_cpu(prptctrl->bt_cnt[BTC_BCNT_RFK_REQ]), + le32_to_cpu(prptctrl->bt_cnt[BTC_BCNT_RFK_GO]), + le32_to_cpu(prptctrl->bt_cnt[BTC_BCNT_RFK_REJECT]), + le32_to_cpu(prptctrl->bt_cnt[BTC_BCNT_RFK_TIMEOUT]), + le32_to_cpu(prptctrl->bt_cnt[BTC_BCNT_RFK_FAIL])); if (le32_to_cpu(prptctrl->bt_cnt[BTC_BCNT_RFK_TIMEOUT]) > 0) bt->rfk_info.map.timeout = 1; @@ -10482,42 +10615,44 @@ static void _show_summary_v4(struct rtw89_dev *rtwdev, struct seq_file *m) dm->error.map.wl_rfk_timeout = bt->rfk_info.map.timeout; } else { - seq_printf(m, - " %-15s : h2c_cnt=%d(fail:%d), c2h_cnt=%d, rpt_cnt=%d, rpt_map=0x%x", - "[summary]", pfwinfo->cnt_h2c, - pfwinfo->cnt_h2c_fail, pfwinfo->cnt_c2h, - pfwinfo->event[BTF_EVNT_RPT], - btc->fwinfo.rpt_en_map); - seq_puts(m, " (WL FW report invalid!!)\n"); + p += scnprintf(p, end - p, + " %-15s : h2c_cnt=%d(fail:%d), c2h_cnt=%d, rpt_cnt=%d, rpt_map=0x%x", + "[summary]", pfwinfo->cnt_h2c, + pfwinfo->cnt_h2c_fail, pfwinfo->cnt_c2h, + pfwinfo->event[BTF_EVNT_RPT], + btc->fwinfo.rpt_en_map); + p += scnprintf(p, end - p, " (WL FW report invalid!!)\n"); } for (i = 0; i < BTC_NCNT_NUM; i++) cnt_sum += dm->cnt_notify[i]; - seq_printf(m, - " %-15s : total=%d, show_coex_info=%d, power_on=%d, init_coex=%d, ", - "[notify_cnt]", cnt_sum, cnt[BTC_NCNT_SHOW_COEX_INFO], - cnt[BTC_NCNT_POWER_ON], cnt[BTC_NCNT_INIT_COEX]); + p += scnprintf(p, end - p, + " %-15s : total=%d, show_coex_info=%d, power_on=%d, init_coex=%d, ", + "[notify_cnt]", cnt_sum, cnt[BTC_NCNT_SHOW_COEX_INFO], + cnt[BTC_NCNT_POWER_ON], cnt[BTC_NCNT_INIT_COEX]); + + p += scnprintf(p, end - p, + "power_off=%d, radio_state=%d, role_info=%d, wl_rfk=%d, wl_sta=%d\n", + cnt[BTC_NCNT_POWER_OFF], cnt[BTC_NCNT_RADIO_STATE], + cnt[BTC_NCNT_ROLE_INFO], cnt[BTC_NCNT_WL_RFK], + cnt[BTC_NCNT_WL_STA]); - seq_printf(m, - "power_off=%d, radio_state=%d, role_info=%d, wl_rfk=%d, wl_sta=%d\n", - cnt[BTC_NCNT_POWER_OFF], cnt[BTC_NCNT_RADIO_STATE], - cnt[BTC_NCNT_ROLE_INFO], cnt[BTC_NCNT_WL_RFK], - cnt[BTC_NCNT_WL_STA]); + p += scnprintf(p, end - p, + " %-15s : scan_start=%d, scan_finish=%d, switch_band=%d, special_pkt=%d, ", + "[notify_cnt]", cnt[BTC_NCNT_SCAN_START], + cnt[BTC_NCNT_SCAN_FINISH], cnt[BTC_NCNT_SWITCH_BAND], + cnt[BTC_NCNT_SPECIAL_PACKET]); - seq_printf(m, - " %-15s : scan_start=%d, scan_finish=%d, switch_band=%d, special_pkt=%d, ", - "[notify_cnt]", cnt[BTC_NCNT_SCAN_START], - cnt[BTC_NCNT_SCAN_FINISH], cnt[BTC_NCNT_SWITCH_BAND], - cnt[BTC_NCNT_SPECIAL_PACKET]); + p += scnprintf(p, end - p, + "timer=%d, control=%d, customerize=%d\n", + cnt[BTC_NCNT_TIMER], cnt[BTC_NCNT_CONTROL], + cnt[BTC_NCNT_CUSTOMERIZE]); - seq_printf(m, - "timer=%d, control=%d, customerize=%d\n", - cnt[BTC_NCNT_TIMER], cnt[BTC_NCNT_CONTROL], - cnt[BTC_NCNT_CUSTOMERIZE]); + return p - buf; } -static void _show_summary_v5(struct rtw89_dev *rtwdev, struct seq_file *m) +static int _show_summary_v5(struct rtw89_dev *rtwdev, char *buf, size_t bufsz) { struct rtw89_btc *btc = &rtwdev->btc; struct rtw89_btc_btf_fwinfo *pfwinfo = &btc->fwinfo; @@ -10527,112 +10662,118 @@ static void _show_summary_v5(struct rtw89_dev *rtwdev, struct seq_file *m) struct rtw89_btc_dm *dm = &btc->dm; struct rtw89_btc_wl_info *wl = &cx->wl; u32 cnt_sum = 0, *cnt = btc->dm.cnt_notify; + char *p = buf, *end = buf + bufsz; u8 i; if (!(dm->coex_info_map & BTC_COEX_INFO_SUMMARY)) - return; + return 0; - seq_puts(m, "========== [Statistics] ==========\n"); + p += scnprintf(p, end - p, "========== [Statistics] ==========\n"); pcinfo = &pfwinfo->rpt_ctrl.cinfo; if (pcinfo->valid && !wl->status.map.lps && !wl->status.map.rf_off) { prptctrl = &pfwinfo->rpt_ctrl.finfo.v5; - seq_printf(m, - " %-15s : h2c_cnt=%d(fail:%d, fw_recv:%d), c2h_cnt=%d(fw_send:%d, len:%d), ", - "[summary]", pfwinfo->cnt_h2c, pfwinfo->cnt_h2c_fail, - le16_to_cpu(prptctrl->rpt_info.cnt_h2c), - pfwinfo->cnt_c2h, - le16_to_cpu(prptctrl->rpt_info.cnt_c2h), - le16_to_cpu(prptctrl->rpt_info.len_c2h)); - - seq_printf(m, - "rpt_cnt=%d(fw_send:%d), rpt_map=0x%x", - pfwinfo->event[BTF_EVNT_RPT], - le16_to_cpu(prptctrl->rpt_info.cnt), - le32_to_cpu(prptctrl->rpt_info.en)); + p += scnprintf(p, end - p, + " %-15s : h2c_cnt=%d(fail:%d, fw_recv:%d), c2h_cnt=%d(fw_send:%d, len:%d), ", + "[summary]", pfwinfo->cnt_h2c, + pfwinfo->cnt_h2c_fail, + le16_to_cpu(prptctrl->rpt_info.cnt_h2c), + pfwinfo->cnt_c2h, + le16_to_cpu(prptctrl->rpt_info.cnt_c2h), + le16_to_cpu(prptctrl->rpt_info.len_c2h)); + + p += scnprintf(p, end - p, + "rpt_cnt=%d(fw_send:%d), rpt_map=0x%x", + pfwinfo->event[BTF_EVNT_RPT], + le16_to_cpu(prptctrl->rpt_info.cnt), + le32_to_cpu(prptctrl->rpt_info.en)); if (dm->error.map.wl_fw_hang) - seq_puts(m, " (WL FW Hang!!)"); - seq_puts(m, "\n"); - seq_printf(m, - " %-15s : send_ok:%d, send_fail:%d, recv:%d, ", - "[mailbox]", - le32_to_cpu(prptctrl->bt_mbx_info.cnt_send_ok), - le32_to_cpu(prptctrl->bt_mbx_info.cnt_send_fail), - le32_to_cpu(prptctrl->bt_mbx_info.cnt_recv)); - - seq_printf(m, - "A2DP_empty:%d(stop:%d, tx:%d, ack:%d, nack:%d)\n", - le32_to_cpu(prptctrl->bt_mbx_info.a2dp.cnt_empty), - le32_to_cpu(prptctrl->bt_mbx_info.a2dp.cnt_flowctrl), - le32_to_cpu(prptctrl->bt_mbx_info.a2dp.cnt_tx), - le32_to_cpu(prptctrl->bt_mbx_info.a2dp.cnt_ack), - le32_to_cpu(prptctrl->bt_mbx_info.a2dp.cnt_nack)); - - seq_printf(m, - " %-15s : wl_rfk[req:%d/go:%d/reject:%d/tout:%d]", - "[RFK/LPS]", cx->cnt_wl[BTC_WCNT_RFK_REQ], - cx->cnt_wl[BTC_WCNT_RFK_GO], - cx->cnt_wl[BTC_WCNT_RFK_REJECT], - cx->cnt_wl[BTC_WCNT_RFK_TIMEOUT]); - - seq_printf(m, - ", bt_rfk[req:%d]", - le16_to_cpu(prptctrl->bt_cnt[BTC_BCNT_RFK_REQ])); - - seq_printf(m, - ", AOAC[RF_on:%d/RF_off:%d]", - le16_to_cpu(prptctrl->rpt_info.cnt_aoac_rf_on), - le16_to_cpu(prptctrl->rpt_info.cnt_aoac_rf_off)); + p += scnprintf(p, end - p, " (WL FW Hang!!)"); + p += scnprintf(p, end - p, "\n"); + p += scnprintf(p, end - p, + " %-15s : send_ok:%d, send_fail:%d, recv:%d, ", + "[mailbox]", + le32_to_cpu(prptctrl->bt_mbx_info.cnt_send_ok), + le32_to_cpu(prptctrl->bt_mbx_info.cnt_send_fail), + le32_to_cpu(prptctrl->bt_mbx_info.cnt_recv)); + + p += scnprintf(p, end - p, + "A2DP_empty:%d(stop:%d, tx:%d, ack:%d, nack:%d)\n", + le32_to_cpu(prptctrl->bt_mbx_info.a2dp.cnt_empty), + le32_to_cpu(prptctrl->bt_mbx_info.a2dp.cnt_flowctrl), + le32_to_cpu(prptctrl->bt_mbx_info.a2dp.cnt_tx), + le32_to_cpu(prptctrl->bt_mbx_info.a2dp.cnt_ack), + le32_to_cpu(prptctrl->bt_mbx_info.a2dp.cnt_nack)); + + p += scnprintf(p, end - p, + " %-15s : wl_rfk[req:%d/go:%d/reject:%d/tout:%d]", + "[RFK/LPS]", cx->cnt_wl[BTC_WCNT_RFK_REQ], + cx->cnt_wl[BTC_WCNT_RFK_GO], + cx->cnt_wl[BTC_WCNT_RFK_REJECT], + cx->cnt_wl[BTC_WCNT_RFK_TIMEOUT]); + + p += scnprintf(p, end - p, + ", bt_rfk[req:%d]", + le16_to_cpu(prptctrl->bt_cnt[BTC_BCNT_RFK_REQ])); + + p += scnprintf(p, end - p, + ", AOAC[RF_on:%d/RF_off:%d]", + le16_to_cpu(prptctrl->rpt_info.cnt_aoac_rf_on), + le16_to_cpu(prptctrl->rpt_info.cnt_aoac_rf_off)); } else { - seq_printf(m, - " %-15s : h2c_cnt=%d(fail:%d), c2h_cnt=%d", - "[summary]", pfwinfo->cnt_h2c, - pfwinfo->cnt_h2c_fail, pfwinfo->cnt_c2h); + p += scnprintf(p, end - p, + " %-15s : h2c_cnt=%d(fail:%d), c2h_cnt=%d", + "[summary]", pfwinfo->cnt_h2c, + pfwinfo->cnt_h2c_fail, pfwinfo->cnt_c2h); } if (!pcinfo->valid || pfwinfo->len_mismch || pfwinfo->fver_mismch || pfwinfo->err[BTFRE_EXCEPTION]) { - seq_puts(m, "\n"); - seq_printf(m, - " %-15s : WL FW rpt error!![rpt_ctrl_valid:%d/len:" - "0x%x/ver:0x%x/ex:%d/lps=%d/rf_off=%d]", - "[ERROR]", pcinfo->valid, pfwinfo->len_mismch, - pfwinfo->fver_mismch, pfwinfo->err[BTFRE_EXCEPTION], - wl->status.map.lps, wl->status.map.rf_off); + p += scnprintf(p, end - p, "\n"); + p += scnprintf(p, end - p, + " %-15s : WL FW rpt error!![rpt_ctrl_valid:%d/len:" + "0x%x/ver:0x%x/ex:%d/lps=%d/rf_off=%d]", + "[ERROR]", pcinfo->valid, pfwinfo->len_mismch, + pfwinfo->fver_mismch, + pfwinfo->err[BTFRE_EXCEPTION], + wl->status.map.lps, wl->status.map.rf_off); } for (i = 0; i < BTC_NCNT_NUM; i++) cnt_sum += dm->cnt_notify[i]; - seq_puts(m, "\n"); - seq_printf(m, - " %-15s : total=%d, show_coex_info=%d, power_on=%d, init_coex=%d, ", - "[notify_cnt]", - cnt_sum, cnt[BTC_NCNT_SHOW_COEX_INFO], - cnt[BTC_NCNT_POWER_ON], cnt[BTC_NCNT_INIT_COEX]); + p += scnprintf(p, end - p, "\n"); + p += scnprintf(p, end - p, + " %-15s : total=%d, show_coex_info=%d, power_on=%d, init_coex=%d, ", + "[notify_cnt]", + cnt_sum, cnt[BTC_NCNT_SHOW_COEX_INFO], + cnt[BTC_NCNT_POWER_ON], cnt[BTC_NCNT_INIT_COEX]); - seq_printf(m, - "power_off=%d, radio_state=%d, role_info=%d, wl_rfk=%d, wl_sta=%d", - cnt[BTC_NCNT_POWER_OFF], cnt[BTC_NCNT_RADIO_STATE], - cnt[BTC_NCNT_ROLE_INFO], cnt[BTC_NCNT_WL_RFK], - cnt[BTC_NCNT_WL_STA]); + p += scnprintf(p, end - p, + "power_off=%d, radio_state=%d, role_info=%d, wl_rfk=%d, wl_sta=%d", + cnt[BTC_NCNT_POWER_OFF], cnt[BTC_NCNT_RADIO_STATE], + cnt[BTC_NCNT_ROLE_INFO], cnt[BTC_NCNT_WL_RFK], + cnt[BTC_NCNT_WL_STA]); - seq_puts(m, "\n"); - seq_printf(m, - " %-15s : scan_start=%d, scan_finish=%d, switch_band=%d, special_pkt=%d, ", - "[notify_cnt]", - cnt[BTC_NCNT_SCAN_START], cnt[BTC_NCNT_SCAN_FINISH], - cnt[BTC_NCNT_SWITCH_BAND], cnt[BTC_NCNT_SPECIAL_PACKET]); + p += scnprintf(p, end - p, "\n"); + p += scnprintf(p, end - p, + " %-15s : scan_start=%d, scan_finish=%d, switch_band=%d, special_pkt=%d, ", + "[notify_cnt]", + cnt[BTC_NCNT_SCAN_START], cnt[BTC_NCNT_SCAN_FINISH], + cnt[BTC_NCNT_SWITCH_BAND], + cnt[BTC_NCNT_SPECIAL_PACKET]); - seq_printf(m, - "timer=%d, control=%d, customerize=%d", - cnt[BTC_NCNT_TIMER], cnt[BTC_NCNT_CONTROL], - cnt[BTC_NCNT_CUSTOMERIZE]); + p += scnprintf(p, end - p, + "timer=%d, control=%d, customerize=%d", + cnt[BTC_NCNT_TIMER], cnt[BTC_NCNT_CONTROL], + cnt[BTC_NCNT_CUSTOMERIZE]); + + return p - buf; } -static void _show_summary_v105(struct rtw89_dev *rtwdev, struct seq_file *m) +static int _show_summary_v105(struct rtw89_dev *rtwdev, char *buf, size_t bufsz) { struct rtw89_btc *btc = &rtwdev->btc; struct rtw89_btc_btf_fwinfo *pfwinfo = &btc->fwinfo; @@ -10642,112 +10783,118 @@ static void _show_summary_v105(struct rtw89_dev *rtwdev, struct seq_file *m) struct rtw89_btc_dm *dm = &btc->dm; struct rtw89_btc_wl_info *wl = &cx->wl; u32 cnt_sum = 0, *cnt = btc->dm.cnt_notify; + char *p = buf, *end = buf + bufsz; u8 i; if (!(dm->coex_info_map & BTC_COEX_INFO_SUMMARY)) - return; + return 0; - seq_puts(m, "========== [Statistics] ==========\n"); + p += scnprintf(p, end - p, "========== [Statistics] ==========\n"); pcinfo = &pfwinfo->rpt_ctrl.cinfo; if (pcinfo->valid && !wl->status.map.lps && !wl->status.map.rf_off) { prptctrl = &pfwinfo->rpt_ctrl.finfo.v105; - seq_printf(m, - " %-15s : h2c_cnt=%d(fail:%d, fw_recv:%d), c2h_cnt=%d(fw_send:%d, len:%d), ", - "[summary]", pfwinfo->cnt_h2c, pfwinfo->cnt_h2c_fail, - le16_to_cpu(prptctrl->rpt_info.cnt_h2c), - pfwinfo->cnt_c2h, - le16_to_cpu(prptctrl->rpt_info.cnt_c2h), - le16_to_cpu(prptctrl->rpt_info.len_c2h)); - - seq_printf(m, - "rpt_cnt=%d(fw_send:%d), rpt_map=0x%x", - pfwinfo->event[BTF_EVNT_RPT], - le16_to_cpu(prptctrl->rpt_info.cnt), - le32_to_cpu(prptctrl->rpt_info.en)); + p += scnprintf(p, end - p, + " %-15s : h2c_cnt=%d(fail:%d, fw_recv:%d), c2h_cnt=%d(fw_send:%d, len:%d), ", + "[summary]", pfwinfo->cnt_h2c, + pfwinfo->cnt_h2c_fail, + le16_to_cpu(prptctrl->rpt_info.cnt_h2c), + pfwinfo->cnt_c2h, + le16_to_cpu(prptctrl->rpt_info.cnt_c2h), + le16_to_cpu(prptctrl->rpt_info.len_c2h)); + + p += scnprintf(p, end - p, + "rpt_cnt=%d(fw_send:%d), rpt_map=0x%x", + pfwinfo->event[BTF_EVNT_RPT], + le16_to_cpu(prptctrl->rpt_info.cnt), + le32_to_cpu(prptctrl->rpt_info.en)); if (dm->error.map.wl_fw_hang) - seq_puts(m, " (WL FW Hang!!)"); - seq_puts(m, "\n"); - seq_printf(m, - " %-15s : send_ok:%d, send_fail:%d, recv:%d, ", - "[mailbox]", - le32_to_cpu(prptctrl->bt_mbx_info.cnt_send_ok), - le32_to_cpu(prptctrl->bt_mbx_info.cnt_send_fail), - le32_to_cpu(prptctrl->bt_mbx_info.cnt_recv)); - - seq_printf(m, - "A2DP_empty:%d(stop:%d, tx:%d, ack:%d, nack:%d)\n", - le32_to_cpu(prptctrl->bt_mbx_info.a2dp.cnt_empty), - le32_to_cpu(prptctrl->bt_mbx_info.a2dp.cnt_flowctrl), - le32_to_cpu(prptctrl->bt_mbx_info.a2dp.cnt_tx), - le32_to_cpu(prptctrl->bt_mbx_info.a2dp.cnt_ack), - le32_to_cpu(prptctrl->bt_mbx_info.a2dp.cnt_nack)); - - seq_printf(m, - " %-15s : wl_rfk[req:%d/go:%d/reject:%d/tout:%d]", - "[RFK/LPS]", cx->cnt_wl[BTC_WCNT_RFK_REQ], - cx->cnt_wl[BTC_WCNT_RFK_GO], - cx->cnt_wl[BTC_WCNT_RFK_REJECT], - cx->cnt_wl[BTC_WCNT_RFK_TIMEOUT]); - - seq_printf(m, - ", bt_rfk[req:%d]", - le16_to_cpu(prptctrl->bt_cnt[BTC_BCNT_RFK_REQ])); - - seq_printf(m, - ", AOAC[RF_on:%d/RF_off:%d]", - le16_to_cpu(prptctrl->rpt_info.cnt_aoac_rf_on), - le16_to_cpu(prptctrl->rpt_info.cnt_aoac_rf_off)); + p += scnprintf(p, end - p, " (WL FW Hang!!)"); + p += scnprintf(p, end - p, "\n"); + p += scnprintf(p, end - p, + " %-15s : send_ok:%d, send_fail:%d, recv:%d, ", + "[mailbox]", + le32_to_cpu(prptctrl->bt_mbx_info.cnt_send_ok), + le32_to_cpu(prptctrl->bt_mbx_info.cnt_send_fail), + le32_to_cpu(prptctrl->bt_mbx_info.cnt_recv)); + + p += scnprintf(p, end - p, + "A2DP_empty:%d(stop:%d, tx:%d, ack:%d, nack:%d)\n", + le32_to_cpu(prptctrl->bt_mbx_info.a2dp.cnt_empty), + le32_to_cpu(prptctrl->bt_mbx_info.a2dp.cnt_flowctrl), + le32_to_cpu(prptctrl->bt_mbx_info.a2dp.cnt_tx), + le32_to_cpu(prptctrl->bt_mbx_info.a2dp.cnt_ack), + le32_to_cpu(prptctrl->bt_mbx_info.a2dp.cnt_nack)); + + p += scnprintf(p, end - p, + " %-15s : wl_rfk[req:%d/go:%d/reject:%d/tout:%d]", + "[RFK/LPS]", cx->cnt_wl[BTC_WCNT_RFK_REQ], + cx->cnt_wl[BTC_WCNT_RFK_GO], + cx->cnt_wl[BTC_WCNT_RFK_REJECT], + cx->cnt_wl[BTC_WCNT_RFK_TIMEOUT]); + + p += scnprintf(p, end - p, + ", bt_rfk[req:%d]", + le16_to_cpu(prptctrl->bt_cnt[BTC_BCNT_RFK_REQ])); + + p += scnprintf(p, end - p, + ", AOAC[RF_on:%d/RF_off:%d]", + le16_to_cpu(prptctrl->rpt_info.cnt_aoac_rf_on), + le16_to_cpu(prptctrl->rpt_info.cnt_aoac_rf_off)); } else { - seq_printf(m, - " %-15s : h2c_cnt=%d(fail:%d), c2h_cnt=%d", - "[summary]", pfwinfo->cnt_h2c, - pfwinfo->cnt_h2c_fail, pfwinfo->cnt_c2h); + p += scnprintf(p, end - p, + " %-15s : h2c_cnt=%d(fail:%d), c2h_cnt=%d", + "[summary]", pfwinfo->cnt_h2c, + pfwinfo->cnt_h2c_fail, pfwinfo->cnt_c2h); } if (!pcinfo->valid || pfwinfo->len_mismch || pfwinfo->fver_mismch || pfwinfo->err[BTFRE_EXCEPTION]) { - seq_puts(m, "\n"); - seq_printf(m, - " %-15s : WL FW rpt error!![rpt_ctrl_valid:%d/len:" - "0x%x/ver:0x%x/ex:%d/lps=%d/rf_off=%d]", - "[ERROR]", pcinfo->valid, pfwinfo->len_mismch, - pfwinfo->fver_mismch, pfwinfo->err[BTFRE_EXCEPTION], - wl->status.map.lps, wl->status.map.rf_off); + p += scnprintf(p, end - p, "\n"); + p += scnprintf(p, end - p, + " %-15s : WL FW rpt error!![rpt_ctrl_valid:%d/len:" + "0x%x/ver:0x%x/ex:%d/lps=%d/rf_off=%d]", + "[ERROR]", pcinfo->valid, pfwinfo->len_mismch, + pfwinfo->fver_mismch, + pfwinfo->err[BTFRE_EXCEPTION], + wl->status.map.lps, wl->status.map.rf_off); } for (i = 0; i < BTC_NCNT_NUM; i++) cnt_sum += dm->cnt_notify[i]; - seq_puts(m, "\n"); - seq_printf(m, - " %-15s : total=%d, show_coex_info=%d, power_on=%d, init_coex=%d, ", - "[notify_cnt]", - cnt_sum, cnt[BTC_NCNT_SHOW_COEX_INFO], - cnt[BTC_NCNT_POWER_ON], cnt[BTC_NCNT_INIT_COEX]); + p += scnprintf(p, end - p, "\n"); + p += scnprintf(p, end - p, + " %-15s : total=%d, show_coex_info=%d, power_on=%d, init_coex=%d, ", + "[notify_cnt]", + cnt_sum, cnt[BTC_NCNT_SHOW_COEX_INFO], + cnt[BTC_NCNT_POWER_ON], cnt[BTC_NCNT_INIT_COEX]); + + p += scnprintf(p, end - p, + "power_off=%d, radio_state=%d, role_info=%d, wl_rfk=%d, wl_sta=%d", + cnt[BTC_NCNT_POWER_OFF], cnt[BTC_NCNT_RADIO_STATE], + cnt[BTC_NCNT_ROLE_INFO], cnt[BTC_NCNT_WL_RFK], + cnt[BTC_NCNT_WL_STA]); - seq_printf(m, - "power_off=%d, radio_state=%d, role_info=%d, wl_rfk=%d, wl_sta=%d", - cnt[BTC_NCNT_POWER_OFF], cnt[BTC_NCNT_RADIO_STATE], - cnt[BTC_NCNT_ROLE_INFO], cnt[BTC_NCNT_WL_RFK], - cnt[BTC_NCNT_WL_STA]); + p += scnprintf(p, end - p, "\n"); + p += scnprintf(p, end - p, + " %-15s : scan_start=%d, scan_finish=%d, switch_band=%d, special_pkt=%d, ", + "[notify_cnt]", + cnt[BTC_NCNT_SCAN_START], cnt[BTC_NCNT_SCAN_FINISH], + cnt[BTC_NCNT_SWITCH_BAND], + cnt[BTC_NCNT_SPECIAL_PACKET]); - seq_puts(m, "\n"); - seq_printf(m, - " %-15s : scan_start=%d, scan_finish=%d, switch_band=%d, special_pkt=%d, ", - "[notify_cnt]", - cnt[BTC_NCNT_SCAN_START], cnt[BTC_NCNT_SCAN_FINISH], - cnt[BTC_NCNT_SWITCH_BAND], cnt[BTC_NCNT_SPECIAL_PACKET]); + p += scnprintf(p, end - p, + "timer=%d, control=%d, customerize=%d", + cnt[BTC_NCNT_TIMER], cnt[BTC_NCNT_CONTROL], + cnt[BTC_NCNT_CUSTOMERIZE]); - seq_printf(m, - "timer=%d, control=%d, customerize=%d", - cnt[BTC_NCNT_TIMER], cnt[BTC_NCNT_CONTROL], - cnt[BTC_NCNT_CUSTOMERIZE]); + return p - buf; } -static void _show_summary_v7(struct rtw89_dev *rtwdev, struct seq_file *m) +static int _show_summary_v7(struct rtw89_dev *rtwdev, char *buf, size_t bufsz) { struct rtw89_btc_btf_fwinfo *pfwinfo = &rtwdev->btc.fwinfo; struct rtw89_btc_fbtc_rpt_ctrl_v7 *prptctrl = NULL; @@ -10756,100 +10903,111 @@ static void _show_summary_v7(struct rtw89_dev *rtwdev, struct seq_file *m) struct rtw89_btc_dm *dm = &rtwdev->btc.dm; struct rtw89_btc_wl_info *wl = &cx->wl; u32 *cnt = rtwdev->btc.dm.cnt_notify; + char *p = buf, *end = buf + bufsz; u32 cnt_sum = 0; u8 i; if (!(dm->coex_info_map & BTC_COEX_INFO_SUMMARY)) - return; + return 0; - seq_printf(m, "%s", "\n\r========== [Statistics] =========="); + p += scnprintf(p, end - p, "%s", + "\n\r========== [Statistics] =========="); pcinfo = &pfwinfo->rpt_ctrl.cinfo; if (pcinfo->valid && wl->status.map.lps != BTC_LPS_RF_OFF && !wl->status.map.rf_off) { prptctrl = &pfwinfo->rpt_ctrl.finfo.v7; - seq_printf(m, - "\n\r %-15s : h2c_cnt=%d(fail:%d, fw_recv:%d)," - "c2h_cnt=%d(fw_send:%d, len:%d, max:%d), ", - "[summary]", pfwinfo->cnt_h2c, pfwinfo->cnt_h2c_fail, - le16_to_cpu(prptctrl->rpt_info.cnt_h2c), pfwinfo->cnt_c2h, - le16_to_cpu(prptctrl->rpt_info.cnt_c2h), - le16_to_cpu(prptctrl->rpt_info.len_c2h), - rtwdev->btc.ver->info_buf); - - seq_printf(m, "rpt_cnt=%d(fw_send:%d), rpt_map=0x%x", - pfwinfo->event[BTF_EVNT_RPT], - le16_to_cpu(prptctrl->rpt_info.cnt), - le32_to_cpu(prptctrl->rpt_info.en)); + p += scnprintf(p, end - p, + "\n\r %-15s : h2c_cnt=%d(fail:%d, fw_recv:%d)," + "c2h_cnt=%d(fw_send:%d, len:%d, max:%d), ", + "[summary]", pfwinfo->cnt_h2c, + pfwinfo->cnt_h2c_fail, + le16_to_cpu(prptctrl->rpt_info.cnt_h2c), + pfwinfo->cnt_c2h, + le16_to_cpu(prptctrl->rpt_info.cnt_c2h), + le16_to_cpu(prptctrl->rpt_info.len_c2h), + rtwdev->btc.ver->info_buf); + + p += scnprintf(p, end - p, + "rpt_cnt=%d(fw_send:%d), rpt_map=0x%x", + pfwinfo->event[BTF_EVNT_RPT], + le16_to_cpu(prptctrl->rpt_info.cnt), + le32_to_cpu(prptctrl->rpt_info.en)); if (dm->error.map.wl_fw_hang) - seq_puts(m, " (WL FW Hang!!)"); - - seq_printf(m, "\n\r %-15s : send_ok:%d, send_fail:%d, recv:%d, ", - "[mailbox]", le32_to_cpu(prptctrl->bt_mbx_info.cnt_send_ok), - le32_to_cpu(prptctrl->bt_mbx_info.cnt_send_fail), - le32_to_cpu(prptctrl->bt_mbx_info.cnt_recv)); - - seq_printf(m, "A2DP_empty:%d(stop:%d/tx:%d/ack:%d/nack:%d)", - le32_to_cpu(prptctrl->bt_mbx_info.a2dp.cnt_empty), - le32_to_cpu(prptctrl->bt_mbx_info.a2dp.cnt_flowctrl), - le32_to_cpu(prptctrl->bt_mbx_info.a2dp.cnt_tx), - le32_to_cpu(prptctrl->bt_mbx_info.a2dp.cnt_ack), - le32_to_cpu(prptctrl->bt_mbx_info.a2dp.cnt_nack)); - - seq_printf(m, - "\n\r %-15s : wl_rfk[req:%d/go:%d/reject:%d/tout:%d/time:%dms]", - "[RFK/LPS]", cx->cnt_wl[BTC_WCNT_RFK_REQ], - cx->cnt_wl[BTC_WCNT_RFK_GO], - cx->cnt_wl[BTC_WCNT_RFK_REJECT], - cx->cnt_wl[BTC_WCNT_RFK_TIMEOUT], - wl->rfk_info.proc_time); - - seq_printf(m, ", bt_rfk[req:%d]", - le16_to_cpu(prptctrl->bt_cnt[BTC_BCNT_RFK_REQ])); - - seq_printf(m, ", AOAC[RF_on:%d/RF_off:%d]", - le16_to_cpu(prptctrl->rpt_info.cnt_aoac_rf_on), - le16_to_cpu(prptctrl->rpt_info.cnt_aoac_rf_off)); + p += scnprintf(p, end - p, " (WL FW Hang!!)"); + + p += scnprintf(p, end - p, + "\n\r %-15s : send_ok:%d, send_fail:%d, recv:%d, ", + "[mailbox]", + le32_to_cpu(prptctrl->bt_mbx_info.cnt_send_ok), + le32_to_cpu(prptctrl->bt_mbx_info.cnt_send_fail), + le32_to_cpu(prptctrl->bt_mbx_info.cnt_recv)); + + p += scnprintf(p, end - p, + "A2DP_empty:%d(stop:%d/tx:%d/ack:%d/nack:%d)", + le32_to_cpu(prptctrl->bt_mbx_info.a2dp.cnt_empty), + le32_to_cpu(prptctrl->bt_mbx_info.a2dp.cnt_flowctrl), + le32_to_cpu(prptctrl->bt_mbx_info.a2dp.cnt_tx), + le32_to_cpu(prptctrl->bt_mbx_info.a2dp.cnt_ack), + le32_to_cpu(prptctrl->bt_mbx_info.a2dp.cnt_nack)); + + p += scnprintf(p, end - p, + "\n\r %-15s : wl_rfk[req:%d/go:%d/reject:%d/tout:%d/time:%dms]", + "[RFK/LPS]", cx->cnt_wl[BTC_WCNT_RFK_REQ], + cx->cnt_wl[BTC_WCNT_RFK_GO], + cx->cnt_wl[BTC_WCNT_RFK_REJECT], + cx->cnt_wl[BTC_WCNT_RFK_TIMEOUT], + wl->rfk_info.proc_time); + + p += scnprintf(p, end - p, ", bt_rfk[req:%d]", + le16_to_cpu(prptctrl->bt_cnt[BTC_BCNT_RFK_REQ])); + + p += scnprintf(p, end - p, ", AOAC[RF_on:%d/RF_off:%d]", + le16_to_cpu(prptctrl->rpt_info.cnt_aoac_rf_on), + le16_to_cpu(prptctrl->rpt_info.cnt_aoac_rf_off)); } else { - seq_printf(m, - "\n\r %-15s : h2c_cnt=%d(fail:%d), c2h_cnt=%d (lps=%d/rf_off=%d)", - "[summary]", - pfwinfo->cnt_h2c, pfwinfo->cnt_h2c_fail, - pfwinfo->cnt_c2h, - wl->status.map.lps, wl->status.map.rf_off); + p += scnprintf(p, end - p, + "\n\r %-15s : h2c_cnt=%d(fail:%d), c2h_cnt=%d (lps=%d/rf_off=%d)", + "[summary]", + pfwinfo->cnt_h2c, pfwinfo->cnt_h2c_fail, + pfwinfo->cnt_c2h, + wl->status.map.lps, wl->status.map.rf_off); } for (i = 0; i < BTC_NCNT_NUM; i++) cnt_sum += dm->cnt_notify[i]; - seq_printf(m, - "\n\r %-15s : total=%d, show_coex_info=%d, power_on=%d, init_coex=%d, ", - "[notify_cnt]", - cnt_sum, cnt[BTC_NCNT_SHOW_COEX_INFO], - cnt[BTC_NCNT_POWER_ON], cnt[BTC_NCNT_INIT_COEX]); + p += scnprintf(p, end - p, + "\n\r %-15s : total=%d, show_coex_info=%d, power_on=%d, init_coex=%d, ", + "[notify_cnt]", + cnt_sum, cnt[BTC_NCNT_SHOW_COEX_INFO], + cnt[BTC_NCNT_POWER_ON], cnt[BTC_NCNT_INIT_COEX]); - seq_printf(m, - "power_off=%d, radio_state=%d, role_info=%d, wl_rfk=%d, wl_sta=%d", - cnt[BTC_NCNT_POWER_OFF], cnt[BTC_NCNT_RADIO_STATE], - cnt[BTC_NCNT_ROLE_INFO], cnt[BTC_NCNT_WL_RFK], - cnt[BTC_NCNT_WL_STA]); + p += scnprintf(p, end - p, + "power_off=%d, radio_state=%d, role_info=%d, wl_rfk=%d, wl_sta=%d", + cnt[BTC_NCNT_POWER_OFF], cnt[BTC_NCNT_RADIO_STATE], + cnt[BTC_NCNT_ROLE_INFO], cnt[BTC_NCNT_WL_RFK], + cnt[BTC_NCNT_WL_STA]); - seq_printf(m, - "\n\r %-15s : scan_start=%d, scan_finish=%d, switch_band=%d, switch_chbw=%d, special_pkt=%d, ", - "[notify_cnt]", - cnt[BTC_NCNT_SCAN_START], cnt[BTC_NCNT_SCAN_FINISH], - cnt[BTC_NCNT_SWITCH_BAND], cnt[BTC_NCNT_SWITCH_CHBW], - cnt[BTC_NCNT_SPECIAL_PACKET]); + p += scnprintf(p, end - p, + "\n\r %-15s : scan_start=%d, scan_finish=%d, switch_band=%d, switch_chbw=%d, special_pkt=%d, ", + "[notify_cnt]", + cnt[BTC_NCNT_SCAN_START], cnt[BTC_NCNT_SCAN_FINISH], + cnt[BTC_NCNT_SWITCH_BAND], cnt[BTC_NCNT_SWITCH_CHBW], + cnt[BTC_NCNT_SPECIAL_PACKET]); - seq_printf(m, "timer=%d, customerize=%d, hub_msg=%d, chg_fw=%d, send_cc=%d", - cnt[BTC_NCNT_TIMER], cnt[BTC_NCNT_CUSTOMERIZE], - rtwdev->btc.hubmsg_cnt, cnt[BTC_NCNT_RESUME_DL_FW], - cnt[BTC_NCNT_COUNTRYCODE]); + p += scnprintf(p, end - p, + "timer=%d, customerize=%d, hub_msg=%d, chg_fw=%d, send_cc=%d", + cnt[BTC_NCNT_TIMER], cnt[BTC_NCNT_CUSTOMERIZE], + rtwdev->btc.hubmsg_cnt, cnt[BTC_NCNT_RESUME_DL_FW], + cnt[BTC_NCNT_COUNTRYCODE]); + + return p - buf; } -static void _show_summary_v8(struct rtw89_dev *rtwdev, struct seq_file *m) +static int _show_summary_v8(struct rtw89_dev *rtwdev, char *buf, size_t bufsz) { struct rtw89_btc_btf_fwinfo *pfwinfo = &rtwdev->btc.fwinfo; struct rtw89_btc_rpt_cmn_info *pcinfo = NULL; @@ -10858,153 +11016,173 @@ static void _show_summary_v8(struct rtw89_dev *rtwdev, struct seq_file *m) struct rtw89_btc_dm *dm = &rtwdev->btc.dm; struct rtw89_btc_wl_info *wl = &cx->wl; u32 *cnt = rtwdev->btc.dm.cnt_notify; + char *p = buf, *end = buf + bufsz; u32 cnt_sum = 0; u8 i; if (!(dm->coex_info_map & BTC_COEX_INFO_SUMMARY)) - return; + return 0; - seq_printf(m, "%s", "\n\r========== [Statistics] =========="); + p += scnprintf(p, end - p, "%s", + "\n\r========== [Statistics] =========="); pcinfo = &pfwinfo->rpt_ctrl.cinfo; if (pcinfo->valid && wl->status.map.lps != BTC_LPS_RF_OFF && !wl->status.map.rf_off) { prptctrl = &pfwinfo->rpt_ctrl.finfo.v8; - seq_printf(m, - "\n\r %-15s : h2c_cnt=%d(fail:%d, fw_recv:%d), c2h_cnt=%d(fw_send:%d, len:%d, max:fw-%d/drv-%d), ", - "[summary]", pfwinfo->cnt_h2c, pfwinfo->cnt_h2c_fail, - le16_to_cpu(prptctrl->rpt_info.cnt_h2c), pfwinfo->cnt_c2h, - le16_to_cpu(prptctrl->rpt_info.cnt_c2h), - le16_to_cpu(prptctrl->rpt_info.len_c2h), - (prptctrl->rpt_len_max_h << 8) + prptctrl->rpt_len_max_l, - rtwdev->btc.ver->info_buf); - - seq_printf(m, "rpt_cnt=%d(fw_send:%d), rpt_map=0x%x", - pfwinfo->event[BTF_EVNT_RPT], - le16_to_cpu(prptctrl->rpt_info.cnt), - le32_to_cpu(prptctrl->rpt_info.en)); + p += scnprintf(p, end - p, + "\n\r %-15s : h2c_cnt=%d(fail:%d, fw_recv:%d), c2h_cnt=%d(fw_send:%d, len:%d, max:fw-%d/drv-%d), ", + "[summary]", pfwinfo->cnt_h2c, + pfwinfo->cnt_h2c_fail, + le16_to_cpu(prptctrl->rpt_info.cnt_h2c), + pfwinfo->cnt_c2h, + le16_to_cpu(prptctrl->rpt_info.cnt_c2h), + le16_to_cpu(prptctrl->rpt_info.len_c2h), + (prptctrl->rpt_len_max_h << 8) + prptctrl->rpt_len_max_l, + rtwdev->btc.ver->info_buf); + + p += scnprintf(p, end - p, + "rpt_cnt=%d(fw_send:%d), rpt_map=0x%x", + pfwinfo->event[BTF_EVNT_RPT], + le16_to_cpu(prptctrl->rpt_info.cnt), + le32_to_cpu(prptctrl->rpt_info.en)); if (dm->error.map.wl_fw_hang) - seq_puts(m, " (WL FW Hang!!)"); - - seq_printf(m, "\n\r %-15s : send_ok:%d, send_fail:%d, recv:%d, ", - "[mailbox]", le32_to_cpu(prptctrl->bt_mbx_info.cnt_send_ok), - le32_to_cpu(prptctrl->bt_mbx_info.cnt_send_fail), - le32_to_cpu(prptctrl->bt_mbx_info.cnt_recv)); - - seq_printf(m, "A2DP_empty:%d(stop:%d/tx:%d/ack:%d/nack:%d)", - le32_to_cpu(prptctrl->bt_mbx_info.a2dp.cnt_empty), - le32_to_cpu(prptctrl->bt_mbx_info.a2dp.cnt_flowctrl), - le32_to_cpu(prptctrl->bt_mbx_info.a2dp.cnt_tx), - le32_to_cpu(prptctrl->bt_mbx_info.a2dp.cnt_ack), - le32_to_cpu(prptctrl->bt_mbx_info.a2dp.cnt_nack)); - - seq_printf(m, - "\n\r %-15s : wl_rfk[req:%d/go:%d/reject:%d/tout:%d/time:%dms]", - "[RFK/LPS]", cx->cnt_wl[BTC_WCNT_RFK_REQ], - cx->cnt_wl[BTC_WCNT_RFK_GO], - cx->cnt_wl[BTC_WCNT_RFK_REJECT], - cx->cnt_wl[BTC_WCNT_RFK_TIMEOUT], - wl->rfk_info.proc_time); - - seq_printf(m, ", bt_rfk[req:%d]", - le16_to_cpu(prptctrl->bt_cnt[BTC_BCNT_RFK_REQ])); - - seq_printf(m, ", AOAC[RF_on:%d/RF_off:%d]", - le16_to_cpu(prptctrl->rpt_info.cnt_aoac_rf_on), - le16_to_cpu(prptctrl->rpt_info.cnt_aoac_rf_off)); + p += scnprintf(p, end - p, " (WL FW Hang!!)"); + + p += scnprintf(p, end - p, + "\n\r %-15s : send_ok:%d, send_fail:%d, recv:%d, ", + "[mailbox]", + le32_to_cpu(prptctrl->bt_mbx_info.cnt_send_ok), + le32_to_cpu(prptctrl->bt_mbx_info.cnt_send_fail), + le32_to_cpu(prptctrl->bt_mbx_info.cnt_recv)); + + p += scnprintf(p, end - p, + "A2DP_empty:%d(stop:%d/tx:%d/ack:%d/nack:%d)", + le32_to_cpu(prptctrl->bt_mbx_info.a2dp.cnt_empty), + le32_to_cpu(prptctrl->bt_mbx_info.a2dp.cnt_flowctrl), + le32_to_cpu(prptctrl->bt_mbx_info.a2dp.cnt_tx), + le32_to_cpu(prptctrl->bt_mbx_info.a2dp.cnt_ack), + le32_to_cpu(prptctrl->bt_mbx_info.a2dp.cnt_nack)); + + p += scnprintf(p, end - p, + "\n\r %-15s : wl_rfk[req:%d/go:%d/reject:%d/tout:%d/time:%dms]", + "[RFK/LPS]", cx->cnt_wl[BTC_WCNT_RFK_REQ], + cx->cnt_wl[BTC_WCNT_RFK_GO], + cx->cnt_wl[BTC_WCNT_RFK_REJECT], + cx->cnt_wl[BTC_WCNT_RFK_TIMEOUT], + wl->rfk_info.proc_time); + + p += scnprintf(p, end - p, ", bt_rfk[req:%d]", + le16_to_cpu(prptctrl->bt_cnt[BTC_BCNT_RFK_REQ])); + + p += scnprintf(p, end - p, ", AOAC[RF_on:%d/RF_off:%d]", + le16_to_cpu(prptctrl->rpt_info.cnt_aoac_rf_on), + le16_to_cpu(prptctrl->rpt_info.cnt_aoac_rf_off)); } else { - seq_printf(m, - "\n\r %-15s : h2c_cnt=%d(fail:%d), c2h_cnt=%d (lps=%d/rf_off=%d)", - "[summary]", - pfwinfo->cnt_h2c, pfwinfo->cnt_h2c_fail, - pfwinfo->cnt_c2h, - wl->status.map.lps, wl->status.map.rf_off); + p += scnprintf(p, end - p, + "\n\r %-15s : h2c_cnt=%d(fail:%d), c2h_cnt=%d (lps=%d/rf_off=%d)", + "[summary]", + pfwinfo->cnt_h2c, pfwinfo->cnt_h2c_fail, + pfwinfo->cnt_c2h, + wl->status.map.lps, wl->status.map.rf_off); } for (i = 0; i < BTC_NCNT_NUM; i++) cnt_sum += dm->cnt_notify[i]; - seq_printf(m, - "\n\r %-15s : total=%d, show_coex_info=%d, power_on=%d, init_coex=%d, ", - "[notify_cnt]", - cnt_sum, cnt[BTC_NCNT_SHOW_COEX_INFO], - cnt[BTC_NCNT_POWER_ON], cnt[BTC_NCNT_INIT_COEX]); + p += scnprintf(p, end - p, + "\n\r %-15s : total=%d, show_coex_info=%d, power_on=%d, init_coex=%d, ", + "[notify_cnt]", + cnt_sum, cnt[BTC_NCNT_SHOW_COEX_INFO], + cnt[BTC_NCNT_POWER_ON], cnt[BTC_NCNT_INIT_COEX]); + + p += scnprintf(p, end - p, + "power_off=%d, radio_state=%d, role_info=%d, wl_rfk=%d, wl_sta=%d", + cnt[BTC_NCNT_POWER_OFF], cnt[BTC_NCNT_RADIO_STATE], + cnt[BTC_NCNT_ROLE_INFO], cnt[BTC_NCNT_WL_RFK], + cnt[BTC_NCNT_WL_STA]); - seq_printf(m, - "power_off=%d, radio_state=%d, role_info=%d, wl_rfk=%d, wl_sta=%d", - cnt[BTC_NCNT_POWER_OFF], cnt[BTC_NCNT_RADIO_STATE], - cnt[BTC_NCNT_ROLE_INFO], cnt[BTC_NCNT_WL_RFK], - cnt[BTC_NCNT_WL_STA]); + p += scnprintf(p, end - p, + "\n\r %-15s : scan_start=%d, scan_finish=%d, switch_band=%d, switch_chbw=%d, special_pkt=%d, ", + "[notify_cnt]", + cnt[BTC_NCNT_SCAN_START], cnt[BTC_NCNT_SCAN_FINISH], + cnt[BTC_NCNT_SWITCH_BAND], cnt[BTC_NCNT_SWITCH_CHBW], + cnt[BTC_NCNT_SPECIAL_PACKET]); - seq_printf(m, - "\n\r %-15s : scan_start=%d, scan_finish=%d, switch_band=%d, switch_chbw=%d, special_pkt=%d, ", - "[notify_cnt]", - cnt[BTC_NCNT_SCAN_START], cnt[BTC_NCNT_SCAN_FINISH], - cnt[BTC_NCNT_SWITCH_BAND], cnt[BTC_NCNT_SWITCH_CHBW], - cnt[BTC_NCNT_SPECIAL_PACKET]); + p += scnprintf(p, end - p, + "timer=%d, customerize=%d, hub_msg=%d, chg_fw=%d, send_cc=%d", + cnt[BTC_NCNT_TIMER], cnt[BTC_NCNT_CUSTOMERIZE], + rtwdev->btc.hubmsg_cnt, cnt[BTC_NCNT_RESUME_DL_FW], + cnt[BTC_NCNT_COUNTRYCODE]); - seq_printf(m, "timer=%d, customerize=%d, hub_msg=%d, chg_fw=%d, send_cc=%d", - cnt[BTC_NCNT_TIMER], cnt[BTC_NCNT_CUSTOMERIZE], - rtwdev->btc.hubmsg_cnt, cnt[BTC_NCNT_RESUME_DL_FW], - cnt[BTC_NCNT_COUNTRYCODE]); + return p - buf; } -void rtw89_btc_dump_info(struct rtw89_dev *rtwdev, struct seq_file *m) +ssize_t rtw89_btc_dump_info(struct rtw89_dev *rtwdev, char *buf, size_t bufsz) { struct rtw89_fw_suit *fw_suit = &rtwdev->fw.normal; struct rtw89_btc *btc = &rtwdev->btc; const struct rtw89_btc_ver *ver = btc->ver; struct rtw89_btc_cx *cx = &btc->cx; struct rtw89_btc_bt_info *bt = &cx->bt; - - seq_puts(m, "=========================================\n"); - seq_printf(m, "WL FW / BT FW %d.%d.%d.%d / NA\n", - fw_suit->major_ver, fw_suit->minor_ver, - fw_suit->sub_ver, fw_suit->sub_idex); - seq_printf(m, "manual %d\n", btc->manual_ctrl); - - seq_puts(m, "=========================================\n"); - - seq_printf(m, "\n\r %-15s : raw_data[%02x %02x %02x %02x %02x %02x] (type:%s/cnt:%d/same:%d)", - "[bt_info]", - bt->raw_info[2], bt->raw_info[3], - bt->raw_info[4], bt->raw_info[5], - bt->raw_info[6], bt->raw_info[7], - bt->raw_info[0] == BTC_BTINFO_AUTO ? "auto" : "reply", - cx->cnt_bt[BTC_BCNT_INFOUPDATE], - cx->cnt_bt[BTC_BCNT_INFOSAME]); - - seq_puts(m, "\n=========================================\n"); - - _show_cx_info(rtwdev, m); - _show_wl_info(rtwdev, m); - _show_bt_info(rtwdev, m); - _show_dm_info(rtwdev, m); - _show_fw_dm_msg(rtwdev, m); + char *p = buf, *end = buf + bufsz; + + p += scnprintf(p, end - p, + "=========================================\n"); + p += scnprintf(p, end - p, + "WL FW / BT FW %d.%d.%d.%d / NA\n", + fw_suit->major_ver, fw_suit->minor_ver, + fw_suit->sub_ver, fw_suit->sub_idex); + p += scnprintf(p, end - p, "manual %d\n", + btc->manual_ctrl); + + p += scnprintf(p, end - p, + "=========================================\n"); + + p += scnprintf(p, end - p, + "\n\r %-15s : raw_data[%02x %02x %02x %02x %02x %02x] (type:%s/cnt:%d/same:%d)", + "[bt_info]", + bt->raw_info[2], bt->raw_info[3], + bt->raw_info[4], bt->raw_info[5], + bt->raw_info[6], bt->raw_info[7], + bt->raw_info[0] == BTC_BTINFO_AUTO ? "auto" : "reply", + cx->cnt_bt[BTC_BCNT_INFOUPDATE], + cx->cnt_bt[BTC_BCNT_INFOSAME]); + + p += scnprintf(p, end - p, + "\n=========================================\n"); + + p += _show_cx_info(rtwdev, p, end - p); + p += _show_wl_info(rtwdev, p, end - p); + p += _show_bt_info(rtwdev, p, end - p); + p += _show_dm_info(rtwdev, p, end - p); + p += _show_fw_dm_msg(rtwdev, p, end - p); if (ver->fcxmreg == 1) - _show_mreg_v1(rtwdev, m); + p += _show_mreg_v1(rtwdev, p, end - p); else if (ver->fcxmreg == 2) - _show_mreg_v2(rtwdev, m); + p += _show_mreg_v2(rtwdev, p, end - p); else if (ver->fcxmreg == 7) - _show_mreg_v7(rtwdev, m); + p += _show_mreg_v7(rtwdev, p, end - p); - _show_gpio_dbg(rtwdev, m); + p += _show_gpio_dbg(rtwdev, p, end - p); if (ver->fcxbtcrpt == 1) - _show_summary_v1(rtwdev, m); + p += _show_summary_v1(rtwdev, p, end - p); else if (ver->fcxbtcrpt == 4) - _show_summary_v4(rtwdev, m); + p += _show_summary_v4(rtwdev, p, end - p); else if (ver->fcxbtcrpt == 5) - _show_summary_v5(rtwdev, m); + p += _show_summary_v5(rtwdev, p, end - p); else if (ver->fcxbtcrpt == 105) - _show_summary_v105(rtwdev, m); + p += _show_summary_v105(rtwdev, p, end - p); else if (ver->fcxbtcrpt == 7) - _show_summary_v7(rtwdev, m); + p += _show_summary_v7(rtwdev, p, end - p); else if (ver->fcxbtcrpt == 8) - _show_summary_v8(rtwdev, m); + p += _show_summary_v8(rtwdev, p, end - p); + + return p - buf; } void rtw89_coex_recognize_ver(struct rtw89_dev *rtwdev) @@ -11037,3 +11215,24 @@ out: rtw89_debug(rtwdev, RTW89_DBG_BTC, "[BTC] use version def[%d] = 0x%08x\n", (int)(btc->ver - rtw89_btc_ver_defs), btc->ver->fw_ver_code); } + +void rtw89_btc_ntfy_preserve_bt_time(struct rtw89_dev *rtwdev, u32 ms) +{ + struct rtw89_btc_bt_link_info *bt_linfo = &rtwdev->btc.cx.bt.link_info; + struct rtw89_btc_bt_a2dp_desc a2dp = bt_linfo->a2dp_desc; + + if (test_bit(RTW89_FLAG_SER_HANDLING, rtwdev->flags)) + return; + + if (!a2dp.exist) + return; + + fsleep(ms * 1000); +} +EXPORT_SYMBOL(rtw89_btc_ntfy_preserve_bt_time); + +void rtw89_btc_ntfy_conn_rfk(struct rtw89_dev *rtwdev, bool state) +{ + rtwdev->btc.cx.wl.rfk_info.con_rfk = state; +} +EXPORT_SYMBOL(rtw89_btc_ntfy_conn_rfk); diff --git a/drivers/net/wireless/realtek/rtw89/coex.h b/drivers/net/wireless/realtek/rtw89/coex.h index dbdb56e063ef..e3a1fcd79620 100644 --- a/drivers/net/wireless/realtek/rtw89/coex.h +++ b/drivers/net/wireless/realtek/rtw89/coex.h @@ -267,10 +267,10 @@ void rtw89_btc_ntfy_scan_finish(struct rtw89_dev *rtwdev, u8 phy_idx); void rtw89_btc_ntfy_switch_band(struct rtw89_dev *rtwdev, u8 phy_idx, u8 band); void rtw89_btc_ntfy_specific_packet(struct rtw89_dev *rtwdev, enum btc_pkt_type pkt_type); -void rtw89_btc_ntfy_eapol_packet_work(struct work_struct *work); -void rtw89_btc_ntfy_arp_packet_work(struct work_struct *work); -void rtw89_btc_ntfy_dhcp_packet_work(struct work_struct *work); -void rtw89_btc_ntfy_icmp_packet_work(struct work_struct *work); +void rtw89_btc_ntfy_eapol_packet_work(struct wiphy *wiphy, struct wiphy_work *work); +void rtw89_btc_ntfy_arp_packet_work(struct wiphy *wiphy, struct wiphy_work *work); +void rtw89_btc_ntfy_dhcp_packet_work(struct wiphy *wiphy, struct wiphy_work *work); +void rtw89_btc_ntfy_icmp_packet_work(struct wiphy *wiphy, struct wiphy_work *work); void rtw89_btc_ntfy_role_info(struct rtw89_dev *rtwdev, struct rtw89_vif_link *rtwvif_link, struct rtw89_sta_link *rtwsta_link, @@ -282,14 +282,16 @@ void rtw89_btc_ntfy_wl_rfk(struct rtw89_dev *rtwdev, u8 phy_map, void rtw89_btc_ntfy_wl_sta(struct rtw89_dev *rtwdev); void rtw89_btc_c2h_handle(struct rtw89_dev *rtwdev, struct sk_buff *skb, u32 len, u8 class, u8 func); -void rtw89_btc_dump_info(struct rtw89_dev *rtwdev, struct seq_file *m); -void rtw89_coex_act1_work(struct work_struct *work); -void rtw89_coex_bt_devinfo_work(struct work_struct *work); -void rtw89_coex_rfk_chk_work(struct work_struct *work); +ssize_t rtw89_btc_dump_info(struct rtw89_dev *rtwdev, char *buf, size_t bufsz); +void rtw89_coex_act1_work(struct wiphy *wiphy, struct wiphy_work *work); +void rtw89_coex_bt_devinfo_work(struct wiphy *wiphy, struct wiphy_work *work); +void rtw89_coex_rfk_chk_work(struct wiphy *wiphy, struct wiphy_work *work); void rtw89_coex_power_on(struct rtw89_dev *rtwdev); void rtw89_btc_set_policy(struct rtw89_dev *rtwdev, u16 policy_type); void rtw89_btc_set_policy_v1(struct rtw89_dev *rtwdev, u16 policy_type); void rtw89_coex_recognize_ver(struct rtw89_dev *rtwdev); +void rtw89_btc_ntfy_preserve_bt_time(struct rtw89_dev *rtwdev, u32 ms); +void rtw89_btc_ntfy_conn_rfk(struct rtw89_dev *rtwdev, bool state); static inline u8 rtw89_btc_phymap(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy_idx, diff --git a/drivers/net/wireless/realtek/rtw89/core.c b/drivers/net/wireless/realtek/rtw89/core.c index 85f739f1173d..8d5dc22fb508 100644 --- a/drivers/net/wireless/realtek/rtw89/core.c +++ b/drivers/net/wireless/realtek/rtw89/core.c @@ -913,16 +913,17 @@ static enum btc_pkt_type rtw89_core_tx_btc_spec_pkt_notify(struct rtw89_dev *rtwdev, struct rtw89_core_tx_request *tx_req) { + struct wiphy *wiphy = rtwdev->hw->wiphy; struct sk_buff *skb = tx_req->skb; struct udphdr *udphdr; if (IEEE80211_SKB_CB(skb)->control.flags & IEEE80211_TX_CTRL_PORT_CTRL_PROTO) { - ieee80211_queue_work(rtwdev->hw, &rtwdev->btc.eapol_notify_work); + wiphy_work_queue(wiphy, &rtwdev->btc.eapol_notify_work); return PACKET_EAPOL; } if (skb->protocol == htons(ETH_P_ARP)) { - ieee80211_queue_work(rtwdev->hw, &rtwdev->btc.arp_notify_work); + wiphy_work_queue(wiphy, &rtwdev->btc.arp_notify_work); return PACKET_ARP; } @@ -932,14 +933,14 @@ rtw89_core_tx_btc_spec_pkt_notify(struct rtw89_dev *rtwdev, if (((udphdr->source == htons(67) && udphdr->dest == htons(68)) || (udphdr->source == htons(68) && udphdr->dest == htons(67))) && skb->len > 282) { - ieee80211_queue_work(rtwdev->hw, &rtwdev->btc.dhcp_notify_work); + wiphy_work_queue(wiphy, &rtwdev->btc.dhcp_notify_work); return PACKET_DHCP; } } if (skb->protocol == htons(ETH_P_IP) && ip_hdr(skb)->protocol == IPPROTO_ICMP) { - ieee80211_queue_work(rtwdev->hw, &rtwdev->btc.icmp_notify_work); + wiphy_work_queue(wiphy, &rtwdev->btc.icmp_notify_work); return PACKET_ICMP; } @@ -2071,17 +2072,17 @@ static void rtw89_stats_trigger_frame(struct rtw89_dev *rtwdev, } } -static void rtw89_cancel_6ghz_probe_work(struct work_struct *work) +static void rtw89_cancel_6ghz_probe_work(struct wiphy *wiphy, struct wiphy_work *work) { struct rtw89_dev *rtwdev = container_of(work, struct rtw89_dev, cancel_6ghz_probe_work); struct list_head *pkt_list = rtwdev->scan_info.pkt_list; struct rtw89_pktofld_info *info; - mutex_lock(&rtwdev->mutex); + lockdep_assert_wiphy(wiphy); if (!rtwdev->scanning) - goto out; + return; list_for_each_entry(info, &pkt_list[NL80211_BAND_6GHZ], list) { if (!info->cancel || !test_bit(info->id, rtwdev->pkt_offload)) @@ -2094,9 +2095,6 @@ static void rtw89_cancel_6ghz_probe_work(struct work_struct *work) * since if during scanning, pkt_list is accessed in bottom half. */ } - -out: - mutex_unlock(&rtwdev->mutex); } static void rtw89_core_cancel_6ghz_probe_tx(struct rtw89_dev *rtwdev, @@ -2131,7 +2129,7 @@ static void rtw89_core_cancel_6ghz_probe_tx(struct rtw89_dev *rtwdev, } if (queue_work) - ieee80211_queue_work(rtwdev->hw, &rtwdev->cancel_6ghz_probe_work); + wiphy_work_queue(rtwdev->hw->wiphy, &rtwdev->cancel_6ghz_probe_work); } static void rtw89_vif_sync_bcn_tsf(struct rtw89_vif_link *rtwvif_link, @@ -2194,8 +2192,11 @@ static void rtw89_vif_rx_stats_iter(void *data, u8 *mac, } pkt_stat->beacon_nr++; - if (phy_ppdu) + if (phy_ppdu) { ewma_rssi_add(&rtwdev->phystat.bcn_rssi, phy_ppdu->rssi_avg); + if (!test_bit(RTW89_FLAG_LOW_POWER_MODE, rtwdev->flags)) + rtwvif_link->bcn_bw_idx = phy_ppdu->bw_idx; + } pkt_stat->beacon_rate = desc_info->data_rate; } @@ -3143,13 +3144,14 @@ static void rtw89_core_txq_schedule(struct rtw89_dev *rtwdev, u8 ac, bool *reinv ieee80211_txq_schedule_end(hw, ac); } -static void rtw89_ips_work(struct work_struct *work) +static void rtw89_ips_work(struct wiphy *wiphy, struct wiphy_work *work) { struct rtw89_dev *rtwdev = container_of(work, struct rtw89_dev, ips_work); - mutex_lock(&rtwdev->mutex); + + lockdep_assert_wiphy(wiphy); + rtw89_enter_ips_by_hwflags(rtwdev); - mutex_unlock(&rtwdev->mutex); } static void rtw89_core_txq_work(struct work_struct *w) @@ -3291,7 +3293,7 @@ void rtw89_roc_start(struct rtw89_dev *rtwdev, struct rtw89_vif *rtwvif) u32 reg; int ret; - lockdep_assert_held(&rtwdev->mutex); + lockdep_assert_wiphy(hw->wiphy); rtw89_leave_ips_by_hwflags(rtwdev); rtw89_leave_lps(rtwdev); @@ -3330,9 +3332,9 @@ void rtw89_roc_start(struct rtw89_dev *rtwdev, struct rtw89_vif *rtwvif) rtw89_write32_clr(rtwdev, reg, B_AX_A_UC_CAM_MATCH | B_AX_A_BC_CAM_MATCH); ieee80211_ready_on_channel(hw); - cancel_delayed_work(&rtwvif->roc.roc_work); - ieee80211_queue_delayed_work(hw, &rtwvif->roc.roc_work, - msecs_to_jiffies(rtwvif->roc.duration)); + wiphy_delayed_work_cancel(hw->wiphy, &rtwvif->roc.roc_work); + wiphy_delayed_work_queue(hw->wiphy, &rtwvif->roc.roc_work, + msecs_to_jiffies(rtwvif->roc.duration)); } void rtw89_roc_end(struct rtw89_dev *rtwdev, struct rtw89_vif *rtwvif) @@ -3345,7 +3347,7 @@ void rtw89_roc_end(struct rtw89_dev *rtwdev, struct rtw89_vif *rtwvif) u32 reg; int ret; - lockdep_assert_held(&rtwdev->mutex); + lockdep_assert_wiphy(hw->wiphy); ieee80211_remain_on_channel_expired(hw); @@ -3377,18 +3379,18 @@ void rtw89_roc_end(struct rtw89_dev *rtwdev, struct rtw89_vif *rtwvif) queue_work(rtwdev->txq_wq, &rtwdev->txq_work); if (hw->conf.flags & IEEE80211_CONF_IDLE) - ieee80211_queue_delayed_work(hw, &roc->roc_work, - msecs_to_jiffies(RTW89_ROC_IDLE_TIMEOUT)); + wiphy_delayed_work_queue(hw->wiphy, &roc->roc_work, + msecs_to_jiffies(RTW89_ROC_IDLE_TIMEOUT)); } -void rtw89_roc_work(struct work_struct *work) +void rtw89_roc_work(struct wiphy *wiphy, struct wiphy_work *work) { struct rtw89_vif *rtwvif = container_of(work, struct rtw89_vif, roc.roc_work.work); struct rtw89_dev *rtwdev = rtwvif->rtwdev; struct rtw89_roc *roc = &rtwvif->roc; - mutex_lock(&rtwdev->mutex); + lockdep_assert_wiphy(wiphy); switch (roc->state) { case RTW89_ROC_IDLE: @@ -3401,8 +3403,6 @@ void rtw89_roc_work(struct work_struct *work) default: break; } - - mutex_unlock(&rtwdev->mutex); } static enum rtw89_tfc_lv rtw89_get_traffic_level(struct rtw89_dev *rtwdev, @@ -3533,26 +3533,26 @@ void rtw89_traffic_stats_init(struct rtw89_dev *rtwdev, ewma_tp_init(&stats->rx_ewma_tp); } -static void rtw89_track_work(struct work_struct *work) +static void rtw89_track_work(struct wiphy *wiphy, struct wiphy_work *work) { struct rtw89_dev *rtwdev = container_of(work, struct rtw89_dev, track_work.work); bool tfc_changed; + lockdep_assert_wiphy(wiphy); + if (test_bit(RTW89_FLAG_FORBIDDEN_TRACK_WROK, rtwdev->flags)) return; - mutex_lock(&rtwdev->mutex); - if (!test_bit(RTW89_FLAG_RUNNING, rtwdev->flags)) - goto out; + return; - ieee80211_queue_delayed_work(rtwdev->hw, &rtwdev->track_work, - RTW89_TRACK_WORK_PERIOD); + wiphy_delayed_work_queue(wiphy, &rtwdev->track_work, + RTW89_TRACK_WORK_PERIOD); tfc_changed = rtw89_traffic_stats_track(rtwdev); if (rtwdev->scanning) - goto out; + return; rtw89_leave_lps(rtwdev); @@ -3577,9 +3577,6 @@ static void rtw89_track_work(struct work_struct *work) if (rtwdev->lps_enabled && !rtwdev->btc.lps) rtw89_enter_lps_track(rtwdev); - -out: - mutex_unlock(&rtwdev->mutex); } u8 rtw89_core_acquire_bit_map(unsigned long *addr, unsigned long size) @@ -3613,7 +3610,7 @@ int rtw89_core_acquire_sta_ba_entry(struct rtw89_dev *rtwdev, u8 idx; int i; - lockdep_assert_held(&rtwdev->mutex); + lockdep_assert_wiphy(rtwdev->hw->wiphy); idx = rtw89_core_acquire_bit_map(cam_info->ba_cam_map, chip->bacam_num); if (idx == chip->bacam_num) { @@ -3657,7 +3654,7 @@ int rtw89_core_release_sta_ba_entry(struct rtw89_dev *rtwdev, struct rtw89_ba_cam_entry *entry = NULL, *tmp; u8 idx; - lockdep_assert_held(&rtwdev->mutex); + lockdep_assert_wiphy(rtwdev->hw->wiphy); list_for_each_entry_safe(entry, tmp, &rtwsta_link->ba_cam_list, list) { if (entry->tid != tid) @@ -4432,26 +4429,26 @@ static void rtw89_core_ppdu_sts_init(struct rtw89_dev *rtwdev) { int i; - for (i = 0; i < RTW89_PHY_MAX; i++) + for (i = 0; i < RTW89_PHY_NUM; i++) skb_queue_head_init(&rtwdev->ppdu_sts.rx_queue[i]); - for (i = 0; i < RTW89_PHY_MAX; i++) + for (i = 0; i < RTW89_PHY_NUM; i++) rtwdev->ppdu_sts.curr_rx_ppdu_cnt[i] = U8_MAX; } -void rtw89_core_update_beacon_work(struct work_struct *work) +void rtw89_core_update_beacon_work(struct wiphy *wiphy, struct wiphy_work *work) { struct rtw89_dev *rtwdev; struct rtw89_vif_link *rtwvif_link = container_of(work, struct rtw89_vif_link, update_beacon_work); + lockdep_assert_wiphy(wiphy); + if (rtwvif_link->net_type != RTW89_NET_TYPE_AP_MODE) return; rtwdev = rtwvif_link->rtwvif->rtwdev; - mutex_lock(&rtwdev->mutex); rtw89_chip_h2c_update_beacon(rtwdev, rtwvif_link); - mutex_unlock(&rtwdev->mutex); } int rtw89_wait_for_cond(struct rtw89_wait_info *wait, unsigned int cond) @@ -4568,8 +4565,8 @@ int rtw89_core_start(struct rtw89_dev *rtwdev) return ret; } - ieee80211_queue_delayed_work(rtwdev->hw, &rtwdev->track_work, - RTW89_TRACK_WORK_PERIOD); + wiphy_delayed_work_queue(rtwdev->hw->wiphy, &rtwdev->track_work, + RTW89_TRACK_WORK_PERIOD); set_bit(RTW89_FLAG_RUNNING, rtwdev->flags); @@ -4583,8 +4580,11 @@ int rtw89_core_start(struct rtw89_dev *rtwdev) void rtw89_core_stop(struct rtw89_dev *rtwdev) { + struct wiphy *wiphy = rtwdev->hw->wiphy; struct rtw89_btc *btc = &rtwdev->btc; + lockdep_assert_wiphy(wiphy); + /* Prvent to stop twice; enter_ips and ops_stop */ if (!test_bit(RTW89_FLAG_RUNNING, rtwdev->flags)) return; @@ -4593,25 +4593,21 @@ void rtw89_core_stop(struct rtw89_dev *rtwdev) clear_bit(RTW89_FLAG_RUNNING, rtwdev->flags); - mutex_unlock(&rtwdev->mutex); - - cancel_work_sync(&rtwdev->c2h_work); - cancel_work_sync(&rtwdev->cancel_6ghz_probe_work); - cancel_work_sync(&btc->eapol_notify_work); - cancel_work_sync(&btc->arp_notify_work); - cancel_work_sync(&btc->dhcp_notify_work); - cancel_work_sync(&btc->icmp_notify_work); + wiphy_work_cancel(wiphy, &rtwdev->c2h_work); + wiphy_work_cancel(wiphy, &rtwdev->cancel_6ghz_probe_work); + wiphy_work_cancel(wiphy, &btc->eapol_notify_work); + wiphy_work_cancel(wiphy, &btc->arp_notify_work); + wiphy_work_cancel(wiphy, &btc->dhcp_notify_work); + wiphy_work_cancel(wiphy, &btc->icmp_notify_work); cancel_delayed_work_sync(&rtwdev->txq_reinvoke_work); - cancel_delayed_work_sync(&rtwdev->track_work); - cancel_delayed_work_sync(&rtwdev->chanctx_work); - cancel_delayed_work_sync(&rtwdev->coex_act1_work); - cancel_delayed_work_sync(&rtwdev->coex_bt_devinfo_work); - cancel_delayed_work_sync(&rtwdev->coex_rfk_chk_work); - cancel_delayed_work_sync(&rtwdev->cfo_track_work); + wiphy_delayed_work_cancel(wiphy, &rtwdev->track_work); + wiphy_delayed_work_cancel(wiphy, &rtwdev->chanctx_work); + wiphy_delayed_work_cancel(wiphy, &rtwdev->coex_act1_work); + wiphy_delayed_work_cancel(wiphy, &rtwdev->coex_bt_devinfo_work); + wiphy_delayed_work_cancel(wiphy, &rtwdev->coex_rfk_chk_work); + wiphy_delayed_work_cancel(wiphy, &rtwdev->cfo_track_work); cancel_delayed_work_sync(&rtwdev->forbid_ba_work); - cancel_delayed_work_sync(&rtwdev->antdiv_work); - - mutex_lock(&rtwdev->mutex); + wiphy_delayed_work_cancel(wiphy, &rtwdev->antdiv_work); rtw89_btc_ntfy_poweroff(rtwdev); rtw89_hci_flush_queues(rtwdev, BIT(rtwdev->hw->queues) - 1, true); @@ -4825,20 +4821,19 @@ int rtw89_core_init(struct rtw89_dev *rtwdev) INIT_WORK(&rtwdev->ba_work, rtw89_core_ba_work); INIT_WORK(&rtwdev->txq_work, rtw89_core_txq_work); INIT_DELAYED_WORK(&rtwdev->txq_reinvoke_work, rtw89_core_txq_reinvoke_work); - INIT_DELAYED_WORK(&rtwdev->track_work, rtw89_track_work); - INIT_DELAYED_WORK(&rtwdev->chanctx_work, rtw89_chanctx_work); - INIT_DELAYED_WORK(&rtwdev->coex_act1_work, rtw89_coex_act1_work); - INIT_DELAYED_WORK(&rtwdev->coex_bt_devinfo_work, rtw89_coex_bt_devinfo_work); - INIT_DELAYED_WORK(&rtwdev->coex_rfk_chk_work, rtw89_coex_rfk_chk_work); - INIT_DELAYED_WORK(&rtwdev->cfo_track_work, rtw89_phy_cfo_track_work); + wiphy_delayed_work_init(&rtwdev->track_work, rtw89_track_work); + wiphy_delayed_work_init(&rtwdev->chanctx_work, rtw89_chanctx_work); + wiphy_delayed_work_init(&rtwdev->coex_act1_work, rtw89_coex_act1_work); + wiphy_delayed_work_init(&rtwdev->coex_bt_devinfo_work, rtw89_coex_bt_devinfo_work); + wiphy_delayed_work_init(&rtwdev->coex_rfk_chk_work, rtw89_coex_rfk_chk_work); + wiphy_delayed_work_init(&rtwdev->cfo_track_work, rtw89_phy_cfo_track_work); INIT_DELAYED_WORK(&rtwdev->forbid_ba_work, rtw89_forbid_ba_work); - INIT_DELAYED_WORK(&rtwdev->antdiv_work, rtw89_phy_antdiv_work); + wiphy_delayed_work_init(&rtwdev->antdiv_work, rtw89_phy_antdiv_work); rtwdev->txq_wq = alloc_workqueue("rtw89_tx_wq", WQ_UNBOUND | WQ_HIGHPRI, 0); if (!rtwdev->txq_wq) return -ENOMEM; spin_lock_init(&rtwdev->ba_lock); spin_lock_init(&rtwdev->rpwm_lock); - mutex_init(&rtwdev->mutex); mutex_init(&rtwdev->rf_mutex); rtwdev->total_sta_assoc = 0; @@ -4847,10 +4842,10 @@ int rtw89_core_init(struct rtw89_dev *rtwdev) rtw89_init_wait(&rtwdev->wow.wait); rtw89_init_wait(&rtwdev->mac.ps_wait); - INIT_WORK(&rtwdev->c2h_work, rtw89_fw_c2h_work); - INIT_WORK(&rtwdev->ips_work, rtw89_ips_work); + wiphy_work_init(&rtwdev->c2h_work, rtw89_fw_c2h_work); + wiphy_work_init(&rtwdev->ips_work, rtw89_ips_work); + wiphy_work_init(&rtwdev->cancel_6ghz_probe_work, rtw89_cancel_6ghz_probe_work); INIT_WORK(&rtwdev->load_firmware_work, rtw89_load_firmware_work); - INIT_WORK(&rtwdev->cancel_6ghz_probe_work, rtw89_cancel_6ghz_probe_work); skb_queue_head_init(&rtwdev->c2h_queue); rtw89_core_ppdu_sts_init(rtwdev); @@ -4867,10 +4862,13 @@ int rtw89_core_init(struct rtw89_dev *rtwdev) rtwdev->mlo_dbcc_mode = MLO_2_PLUS_0_1RF; } - INIT_WORK(&btc->eapol_notify_work, rtw89_btc_ntfy_eapol_packet_work); - INIT_WORK(&btc->arp_notify_work, rtw89_btc_ntfy_arp_packet_work); - INIT_WORK(&btc->dhcp_notify_work, rtw89_btc_ntfy_dhcp_packet_work); - INIT_WORK(&btc->icmp_notify_work, rtw89_btc_ntfy_icmp_packet_work); + rtwdev->bbs[RTW89_PHY_0].phy_idx = RTW89_PHY_0; + rtwdev->bbs[RTW89_PHY_1].phy_idx = RTW89_PHY_1; + + wiphy_work_init(&btc->eapol_notify_work, rtw89_btc_ntfy_eapol_packet_work); + wiphy_work_init(&btc->arp_notify_work, rtw89_btc_ntfy_arp_packet_work); + wiphy_work_init(&btc->dhcp_notify_work, rtw89_btc_ntfy_dhcp_packet_work); + wiphy_work_init(&btc->icmp_notify_work, rtw89_btc_ntfy_icmp_packet_work); init_completion(&rtwdev->fw.req.completion); init_completion(&rtwdev->rfk_wait.completion); @@ -4890,11 +4888,10 @@ void rtw89_core_deinit(struct rtw89_dev *rtwdev) { rtw89_ser_deinit(rtwdev); rtw89_unload_firmware(rtwdev); - rtw89_fw_free_all_early_h2c(rtwdev); + __rtw89_fw_free_all_early_h2c(rtwdev); destroy_workqueue(rtwdev->txq_wq); mutex_destroy(&rtwdev->rf_mutex); - mutex_destroy(&rtwdev->mutex); } EXPORT_SYMBOL(rtw89_core_deinit); @@ -4903,6 +4900,7 @@ void rtw89_core_scan_start(struct rtw89_dev *rtwdev, struct rtw89_vif_link *rtwv { const struct rtw89_chan *chan = rtw89_chan_get(rtwdev, rtwvif_link->chanctx_idx); + struct rtw89_bb_ctx *bb = rtw89_get_bb_ctx(rtwdev, rtwvif_link->phy_idx); rtwdev->scanning = true; rtw89_leave_lps(rtwdev); @@ -4913,7 +4911,7 @@ void rtw89_core_scan_start(struct rtw89_dev *rtwdev, struct rtw89_vif_link *rtwv rtw89_btc_ntfy_scan_start(rtwdev, rtwvif_link->phy_idx, chan->band_type); rtw89_chip_rfk_scan(rtwdev, rtwvif_link, true); rtw89_hci_recalc_int_mit(rtwdev); - rtw89_phy_config_edcca(rtwdev, true); + rtw89_phy_config_edcca(rtwdev, bb, true); rtw89_fw_h2c_cam(rtwdev, rtwvif_link, NULL, mac_addr); } @@ -4922,6 +4920,7 @@ void rtw89_core_scan_complete(struct rtw89_dev *rtwdev, struct rtw89_vif_link *rtwvif_link, bool hw_scan) { struct ieee80211_bss_conf *bss_conf; + struct rtw89_bb_ctx *bb; if (!rtwvif_link) return; @@ -4937,12 +4936,14 @@ void rtw89_core_scan_complete(struct rtw89_dev *rtwdev, rtw89_chip_rfk_scan(rtwdev, rtwvif_link, false); rtw89_btc_ntfy_scan_finish(rtwdev, rtwvif_link->phy_idx); - rtw89_phy_config_edcca(rtwdev, false); + bb = rtw89_get_bb_ctx(rtwdev, rtwvif_link->phy_idx); + rtw89_phy_config_edcca(rtwdev, bb, false); rtwdev->scanning = false; - rtwdev->dig.bypass_dig = true; + rtw89_for_each_active_bb(rtwdev, bb) + bb->dig.bypass_dig = true; if (hw_scan && (rtwdev->hw->conf.flags & IEEE80211_CONF_IDLE)) - ieee80211_queue_work(rtwdev->hw, &rtwdev->ips_work); + wiphy_work_queue(rtwdev->hw->wiphy, &rtwdev->ips_work); } static void rtw89_read_chip_ver(struct rtw89_dev *rtwdev) @@ -5042,8 +5043,6 @@ static int rtw89_chip_efuse_info_setup(struct rtw89_dev *rtwdev) rtw89_hci_mac_pre_deinit(rtwdev); - rtw89_mac_pwr_off(rtwdev); - return 0; } @@ -5124,36 +5123,45 @@ int rtw89_chip_info_setup(struct rtw89_dev *rtwdev) rtw89_read_chip_ver(rtwdev); + ret = rtw89_mac_pwr_on(rtwdev); + if (ret) { + rtw89_err(rtwdev, "failed to power on\n"); + return ret; + } + ret = rtw89_wait_firmware_completion(rtwdev); if (ret) { rtw89_err(rtwdev, "failed to wait firmware completion\n"); - return ret; + goto out; } ret = rtw89_fw_recognize(rtwdev); if (ret) { rtw89_err(rtwdev, "failed to recognize firmware\n"); - return ret; + goto out; } ret = rtw89_chip_efuse_info_setup(rtwdev); if (ret) - return ret; + goto out; ret = rtw89_fw_recognize_elements(rtwdev); if (ret) { rtw89_err(rtwdev, "failed to recognize firmware elements\n"); - return ret; + goto out; } ret = rtw89_chip_board_info_setup(rtwdev); if (ret) - return ret; + goto out; rtw89_core_setup_rfe_parms(rtwdev); rtwdev->ps_mode = rtw89_update_ps_mode(rtwdev); - return 0; +out: + rtw89_mac_pwr_off(rtwdev); + + return ret; } EXPORT_SYMBOL(rtw89_chip_info_setup); @@ -5296,7 +5304,7 @@ static int rtw89_core_register_hw(struct rtw89_dev *rtwdev) goto err_free_supported_band; } - ret = rtw89_regd_init(rtwdev, rtw89_regd_notifier); + ret = rtw89_regd_init_hint(rtwdev); if (ret) { rtw89_err(rtwdev, "failed to init regd\n"); goto err_unregister_hw; diff --git a/drivers/net/wireless/realtek/rtw89/core.h b/drivers/net/wireless/realtek/rtw89/core.h index ff4894c7fa8a..b3fdd8eded21 100644 --- a/drivers/net/wireless/realtek/rtw89/core.h +++ b/drivers/net/wireless/realtek/rtw89/core.h @@ -22,6 +22,7 @@ struct rtw89_h2c_rf_tssi; struct rtw89_fw_txpwr_track_cfg; struct rtw89_phy_rfk_log_fmt; struct rtw89_debugfs; +struct rtw89_regd_data; extern const struct ieee80211_ops rtw89_ops; @@ -718,6 +719,7 @@ enum rtw89_ofdma_type { RTW89_OFDMA_NUM, }; +/* neither insert new in the middle, nor change any given definition */ enum rtw89_regulation_type { RTW89_WW = 0, RTW89_ETSI = 1, @@ -826,7 +828,7 @@ enum rtw89_mac_idx { enum rtw89_phy_idx { RTW89_PHY_0 = 0, RTW89_PHY_1 = 1, - RTW89_PHY_MAX + RTW89_PHY_NUM, }; #define __RTW89_MLD_MAX_LINK_NUM 2 @@ -1540,16 +1542,16 @@ struct rtw89_btc_u8_sta_chg { }; struct rtw89_btc_wl_scan_info { - u8 band[RTW89_PHY_MAX]; + u8 band[RTW89_PHY_NUM]; u8 phy_map; u8 rsvd; }; struct rtw89_btc_wl_dbcc_info { - u8 op_band[RTW89_PHY_MAX]; /* op band in each phy */ - u8 scan_band[RTW89_PHY_MAX]; /* scan band in each phy */ - u8 real_band[RTW89_PHY_MAX]; - u8 role[RTW89_PHY_MAX]; /* role in each phy */ + u8 op_band[RTW89_PHY_NUM]; /* op band in each phy */ + u8 scan_band[RTW89_PHY_NUM]; /* scan band in each phy */ + u8 real_band[RTW89_PHY_NUM]; + u8 role[RTW89_PHY_NUM]; /* role in each phy */ }; struct rtw89_btc_wl_active_role { @@ -1761,7 +1763,8 @@ struct rtw89_btc_wl_rfk_info { u32 phy_map: 2; u32 band: 2; u32 type: 8; - u32 rsvd: 14; + u32 con_rfk: 1; + u32 rsvd: 13; u32 start_time; u32 proc_time; @@ -1898,7 +1901,7 @@ struct rtw89_btc_wl_info { u8 cn_report; u8 coex_mode; u8 pta_req_mac; - u8 bt_polut_type[RTW89_PHY_MAX]; /* BT polluted WL-Tx type for phy0/1 */ + u8 bt_polut_type[RTW89_PHY_NUM]; /* BT polluted WL-Tx type for phy0/1 */ bool is_5g_hi_channel; bool pta_reg_mac_chg; @@ -2230,7 +2233,7 @@ struct rtw89_btc_fbtc_rpt_ctrl_v4 { struct rtw89_btc_fbtc_rpt_ctrl_wl_fw_info wl_fw_info; struct rtw89_btc_fbtc_rpt_ctrl_bt_mailbox bt_mbx_info; __le32 bt_cnt[BTC_BCNT_STA_MAX]; - struct rtw89_mac_ax_gnt gnt_val[RTW89_PHY_MAX]; + struct rtw89_mac_ax_gnt gnt_val[RTW89_PHY_NUM]; } __packed; struct rtw89_btc_fbtc_rpt_ctrl_v5 { @@ -2238,7 +2241,7 @@ struct rtw89_btc_fbtc_rpt_ctrl_v5 { u8 rsvd; __le16 rsvd1; - u8 gnt_val[RTW89_PHY_MAX][4]; + u8 gnt_val[RTW89_PHY_NUM][4]; __le16 bt_cnt[BTC_BCNT_STA_MAX]; struct rtw89_btc_fbtc_rpt_ctrl_info_v5 rpt_info; @@ -2250,7 +2253,7 @@ struct rtw89_btc_fbtc_rpt_ctrl_v105 { u8 rsvd; __le16 rsvd1; - u8 gnt_val[RTW89_PHY_MAX][4]; + u8 gnt_val[RTW89_PHY_NUM][4]; __le16 bt_cnt[BTC_BCNT_STA_MAX_V105]; struct rtw89_btc_fbtc_rpt_ctrl_info_v5 rpt_info; @@ -2263,7 +2266,7 @@ struct rtw89_btc_fbtc_rpt_ctrl_v7 { u8 rsvd1; u8 rsvd2; - u8 gnt_val[RTW89_PHY_MAX][4]; + u8 gnt_val[RTW89_PHY_NUM][4]; __le16 bt_cnt[BTC_BCNT_STA_MAX_V105]; struct rtw89_btc_fbtc_rpt_ctrl_info_v8 rpt_info; @@ -2276,7 +2279,7 @@ struct rtw89_btc_fbtc_rpt_ctrl_v8 { u8 rpt_len_max_l; /* BTC_RPT_MAX bit0~7 */ u8 rpt_len_max_h; /* BTC_RPT_MAX bit8~15 */ - u8 gnt_val[RTW89_PHY_MAX][4]; + u8 gnt_val[RTW89_PHY_NUM][4]; __le16 bt_cnt[BTC_BCNT_STA_MAX_V105]; struct rtw89_btc_fbtc_rpt_ctrl_info_v8 rpt_info; @@ -3174,10 +3177,10 @@ struct rtw89_btc { struct rtw89_btc_btf_fwinfo fwinfo; struct rtw89_btc_dbg dbg; - struct work_struct eapol_notify_work; - struct work_struct arp_notify_work; - struct work_struct dhcp_notify_work; - struct work_struct icmp_notify_work; + struct wiphy_work eapol_notify_work; + struct wiphy_work arp_notify_work; + struct wiphy_work dhcp_notify_work; + struct wiphy_work icmp_notify_work; u32 bt_req_len; @@ -3444,7 +3447,7 @@ enum rtw89_roc_state { struct rtw89_roc { struct ieee80211_channel chan; - struct delayed_work roc_work; + struct wiphy_delayed_work roc_work; enum ieee80211_roc_type type; enum rtw89_roc_state state; int duration; @@ -3498,6 +3501,7 @@ struct rtw89_vif_link { u8 self_role; u8 wmm; u8 bcn_hit_cond; + u8 bcn_bw_idx; u8 hit_rule; u8 last_noa_nr; u64 sync_bcn_tsf; @@ -3514,7 +3518,7 @@ struct rtw89_vif_link { bool pre_pwr_diff_en; bool pwr_diff_en; u8 def_tri_idx; - struct work_struct update_beacon_work; + struct wiphy_work update_beacon_work; struct rtw89_addr_cam_entry addr_cam; struct rtw89_bssid_cam_entry bssid_cam; struct ieee80211_tx_queue_params tx_params[IEEE80211_NUM_ACS]; @@ -4189,10 +4193,12 @@ struct rtw89_edcca_regs { u32 edcca_p_mask; u32 ppdu_level; u32 ppdu_mask; - u32 rpt_a; - u32 rpt_b; - u32 rpt_sel; - u32 rpt_sel_mask; + struct rtw89_edcca_p_regs { + u32 rpt_a; + u32 rpt_b; + u32 rpt_sel; + u32 rpt_sel_mask; + } p[RTW89_PHY_NUM]; u32 rpt_sel_be; u32 rpt_sel_be_mask; u32 tx_collision_t2r_st; @@ -4536,6 +4542,7 @@ struct rtw89_fw_elm_info { struct rtw89_phy_table *rf_nctl; struct rtw89_fw_txpwr_track_cfg *txpwr_trk; struct rtw89_phy_rfk_log_fmt *rfk_log_fmt; + const struct rtw89_regd_data *regd; }; enum rtw89_fw_mss_dev_type { @@ -4762,12 +4769,11 @@ struct rtw89_hal { struct rtw89_chanctx chanctx[NUM_OF_RTW89_CHANCTX]; struct cfg80211_chan_def roc_chandef; - bool entity_active[RTW89_PHY_MAX]; + bool entity_active[RTW89_PHY_NUM]; bool entity_pause; enum rtw89_entity_mode entity_mode; struct rtw89_entity_mgnt entity_mgnt; - struct rtw89_edcca_bak edcca_bak; u32 disabled_dm_bitmap; /* bitmap of enum rtw89_dm_type */ u8 thermal_prot_th; @@ -4973,7 +4979,7 @@ struct rtw89_dpk_bkup_para { struct rtw89_dpk_info { bool is_dpk_enable; bool is_dpk_reload_en; - u8 dpk_gs[RTW89_PHY_MAX]; + u8 dpk_gs[RTW89_PHY_NUM]; u16 dc_i[RTW89_DPK_RF_PATH][RTW89_DPK_BKUP_NUM]; u16 dc_q[RTW89_DPK_RF_PATH][RTW89_DPK_BKUP_NUM]; u8 corr_val[RTW89_DPK_RF_PATH][RTW89_DPK_BKUP_NUM]; @@ -5146,9 +5152,27 @@ struct rtw89_power_trim_info { u8 pad_bias_trim[RF_PATH_MAX]; }; +enum rtw89_regd_func { + RTW89_REGD_FUNC_TAS = 0, /* TAS (Time Average SAR) */ + RTW89_REGD_FUNC_DAG = 1, /* DAG (Dynamic Antenna Gain) */ + + NUM_OF_RTW89_REGD_FUNC, +}; + struct rtw89_regd { char alpha2[3]; u8 txpwr_regd[RTW89_BAND_NUM]; + DECLARE_BITMAP(func_bitmap, NUM_OF_RTW89_REGD_FUNC); +}; + +struct rtw89_regd_data { + unsigned int nr; + struct rtw89_regd map[] __counted_by(nr); +}; + +struct rtw89_regd_ctrl { + unsigned int nr; + const struct rtw89_regd *map; }; #define RTW89_REGD_MAX_COUNTRY_NUM U8_MAX @@ -5156,6 +5180,7 @@ struct rtw89_regd { #define RTW89_5GHZ_UNII4_START_INDEX 25 struct rtw89_regulatory_info { + struct rtw89_regd_ctrl ctrl; const struct rtw89_regd *regd; enum rtw89_reg_6ghz_power reg_6ghz_power; struct rtw89_reg_6ghz_tpe reg_6ghz_tpe; @@ -5299,8 +5324,8 @@ struct rtw89_lps_parm { }; struct rtw89_ppdu_sts_info { - struct sk_buff_head rx_queue[RTW89_PHY_MAX]; - u8 curr_rx_ppdu_cnt[RTW89_PHY_MAX]; + struct sk_buff_head rx_queue[RTW89_PHY_NUM]; + u8 curr_rx_ppdu_cnt[RTW89_PHY_NUM]; }; struct rtw89_early_h2c { @@ -5419,8 +5444,8 @@ struct rtw89_phy_efuse_gain { bool offset_valid; bool comp_valid; s8 offset[RF_PATH_MAX][RTW89_GAIN_OFFSET_NR]; /* S(8, 0) */ - s8 offset_base[RTW89_PHY_MAX]; /* S(8, 4) */ - s8 rssi_base[RTW89_PHY_MAX]; /* S(8, 4) */ + s8 offset_base[RTW89_PHY_NUM]; /* S(8, 4) */ + s8 rssi_base[RTW89_PHY_NUM]; /* S(8, 4) */ s8 comp[RF_PATH_MAX][RTW89_SUBBAND_NR]; /* S(8, 0) */ }; @@ -5629,8 +5654,6 @@ struct rtw89_dev { struct rtw89_sta_link __rcu *assoc_link_on_macid[RTW89_MAX_MAC_ID_NUM]; refcount_t refcount_ap_info; - /* ensures exclusive access from mac80211 callbacks */ - struct mutex mutex; struct list_head rtwvifs_list; /* used to protect rf read write */ struct mutex rf_mutex; @@ -5650,10 +5673,10 @@ struct rtw89_dev { struct rtw89_cam_info cam_info; struct sk_buff_head c2h_queue; - struct work_struct c2h_work; - struct work_struct ips_work; + struct wiphy_work c2h_work; + struct wiphy_work ips_work; + struct wiphy_work cancel_6ghz_probe_work; struct work_struct load_firmware_work; - struct work_struct cancel_6ghz_probe_work; struct list_head early_h2c_list; @@ -5682,9 +5705,6 @@ struct rtw89_dev { struct rtw89_power_trim_info pwr_trim; struct rtw89_cfo_tracking_info cfo_tracking; - struct rtw89_env_monitor_info env_monitor; - struct rtw89_dig_info dig; - struct rtw89_phy_ch_info ch_info; union { struct rtw89_phy_bb_gain_info ax; struct rtw89_phy_bb_gain_info_be be; @@ -5693,15 +5713,22 @@ struct rtw89_dev { struct rtw89_phy_ul_tb_info ul_tb_info; struct rtw89_antdiv_info antdiv; - struct delayed_work track_work; - struct delayed_work chanctx_work; - struct delayed_work coex_act1_work; - struct delayed_work coex_bt_devinfo_work; - struct delayed_work coex_rfk_chk_work; - struct delayed_work cfo_track_work; + struct rtw89_bb_ctx { + enum rtw89_phy_idx phy_idx; + struct rtw89_env_monitor_info env_monitor; + struct rtw89_dig_info dig; + struct rtw89_phy_ch_info ch_info; + struct rtw89_edcca_bak edcca_bak; + } bbs[RTW89_PHY_NUM]; + + struct wiphy_delayed_work track_work; + struct wiphy_delayed_work chanctx_work; + struct wiphy_delayed_work coex_act1_work; + struct wiphy_delayed_work coex_bt_devinfo_work; + struct wiphy_delayed_work coex_rfk_chk_work; + struct wiphy_delayed_work cfo_track_work; struct delayed_work forbid_ba_work; - struct delayed_work roc_work; - struct delayed_work antdiv_work; + struct wiphy_delayed_work antdiv_work; struct rtw89_ppdu_sts_info ppdu_sts; u8 total_sta_assoc; bool scanning; @@ -6978,6 +7005,48 @@ static inline bool rtw89_is_mlo_1_1(struct rtw89_dev *rtwdev) } } +static inline u8 rtw89_get_active_phy_bitmap(struct rtw89_dev *rtwdev) +{ + if (!rtwdev->dbcc_en) + return BIT(RTW89_PHY_0); + + switch (rtwdev->mlo_dbcc_mode) { + case MLO_0_PLUS_2_1RF: + case MLO_0_PLUS_2_2RF: + return BIT(RTW89_PHY_1); + case MLO_1_PLUS_1_1RF: + case MLO_1_PLUS_1_2RF: + case MLO_2_PLUS_2_2RF: + case DBCC_LEGACY: + return BIT(RTW89_PHY_0) | BIT(RTW89_PHY_1); + case MLO_2_PLUS_0_1RF: + case MLO_2_PLUS_0_2RF: + default: + return BIT(RTW89_PHY_0); + } +} + +#define rtw89_for_each_active_bb(rtwdev, bb) \ + for (u8 __active_bb_bitmap = rtw89_get_active_phy_bitmap(rtwdev), \ + __phy_idx = 0; __phy_idx < RTW89_PHY_NUM; __phy_idx++) \ + if (__active_bb_bitmap & BIT(__phy_idx) && \ + (bb = &rtwdev->bbs[__phy_idx])) + +#define rtw89_for_each_capab_bb(rtwdev, bb) \ + for (u8 __phy_idx_max = rtwdev->dbcc_en ? RTW89_PHY_1 : RTW89_PHY_0, \ + __phy_idx = 0; __phy_idx <= __phy_idx_max; __phy_idx++) \ + if ((bb = &rtwdev->bbs[__phy_idx])) + +static inline +struct rtw89_bb_ctx *rtw89_get_bb_ctx(struct rtw89_dev *rtwdev, + enum rtw89_phy_idx phy_idx) +{ + if (phy_idx >= RTW89_PHY_NUM) + return &rtwdev->bbs[RTW89_PHY_0]; + + return &rtwdev->bbs[phy_idx]; +} + static inline bool rtw89_is_rtl885xb(struct rtw89_dev *rtwdev) { enum rtw89_core_chip_id chip_id = rtwdev->chip->chip_id; @@ -7092,9 +7161,7 @@ void rtw89_chip_cfg_txpwr_ul_tb_offset(struct rtw89_dev *rtwdev, struct rtw89_vif_link *rtwvif_link); bool rtw89_ra_report_to_bitrate(struct rtw89_dev *rtwdev, u8 rpt_rate, u16 *bitrate); int rtw89_regd_setup(struct rtw89_dev *rtwdev); -int rtw89_regd_init(struct rtw89_dev *rtwdev, - void (*reg_notifier)(struct wiphy *wiphy, struct regulatory_request *request)); -void rtw89_regd_notifier(struct wiphy *wiphy, struct regulatory_request *request); +int rtw89_regd_init_hint(struct rtw89_dev *rtwdev); void rtw89_traffic_stats_init(struct rtw89_dev *rtwdev, struct rtw89_traffic_stats *stats); int rtw89_wait_for_cond(struct rtw89_wait_info *wait, unsigned int cond); @@ -7102,8 +7169,8 @@ void rtw89_complete_cond(struct rtw89_wait_info *wait, unsigned int cond, const struct rtw89_completion_data *data); int rtw89_core_start(struct rtw89_dev *rtwdev); void rtw89_core_stop(struct rtw89_dev *rtwdev); -void rtw89_core_update_beacon_work(struct work_struct *work); -void rtw89_roc_work(struct work_struct *work); +void rtw89_core_update_beacon_work(struct wiphy *wiphy, struct wiphy_work *work); +void rtw89_roc_work(struct wiphy *wiphy, struct wiphy_work *work); void rtw89_roc_start(struct rtw89_dev *rtwdev, struct rtw89_vif *rtwvif); void rtw89_roc_end(struct rtw89_dev *rtwdev, struct rtw89_vif *rtwvif); void rtw89_core_scan_start(struct rtw89_dev *rtwdev, struct rtw89_vif_link *rtwvif_link, diff --git a/drivers/net/wireless/realtek/rtw89/debug.c b/drivers/net/wireless/realtek/rtw89/debug.c index 09fa977a6e6d..885a5ebeb6cd 100644 --- a/drivers/net/wireless/realtek/rtw89/debug.c +++ b/drivers/net/wireless/realtek/rtw89/debug.c @@ -13,6 +13,7 @@ #include "ps.h" #include "reg.h" #include "sar.h" +#include "util.h" #ifdef CONFIG_RTW89_DEBUGMSG unsigned int rtw89_debug_mask; @@ -22,11 +23,21 @@ MODULE_PARM_DESC(debug_mask, "Debugging mask"); #endif #ifdef CONFIG_RTW89_DEBUGFS +struct rtw89_debugfs_priv_opt { + bool rlock:1; + bool wlock:1; + size_t rsize; +}; + struct rtw89_debugfs_priv { struct rtw89_dev *rtwdev; - int (*cb_read)(struct seq_file *m, void *v); - ssize_t (*cb_write)(struct file *filp, const char __user *buffer, - size_t count, loff_t *loff); + ssize_t (*cb_read)(struct rtw89_dev *rtwdev, + struct rtw89_debugfs_priv *debugfs_priv, + char *buf, size_t bufsz); + ssize_t (*cb_write)(struct rtw89_dev *rtwdev, + struct rtw89_debugfs_priv *debugfs_priv, + const char *buf, size_t count); + struct rtw89_debugfs_priv_opt opt; union { u32 cb_data; struct { @@ -51,6 +62,8 @@ struct rtw89_debugfs_priv { u8 sel; } mac_mem; }; + ssize_t rused; + char *rbuf; }; struct rtw89_debugfs { @@ -74,6 +87,28 @@ struct rtw89_debugfs { struct rtw89_debugfs_priv disable_dm; }; +struct rtw89_debugfs_iter_data { + char *buf; + size_t bufsz; + int written_sz; +}; + +static void rtw89_debugfs_iter_data_setup(struct rtw89_debugfs_iter_data *iter_data, + char *buf, size_t bufsz) +{ + iter_data->buf = buf; + iter_data->bufsz = bufsz; + iter_data->written_sz = 0; +} + +static void rtw89_debugfs_iter_data_next(struct rtw89_debugfs_iter_data *iter_data, + char *buf, size_t bufsz, int written_sz) +{ + iter_data->buf = buf; + iter_data->bufsz = bufsz; + iter_data->written_sz += written_sz; +} + static const u16 rtw89_rate_info_bw_to_mhz_map[] = { [RATE_INFO_BW_20] = 20, [RATE_INFO_BW_40] = 40, @@ -90,84 +125,122 @@ static u16 rtw89_rate_info_bw_to_mhz(enum rate_info_bw bw) return 0; } -static int rtw89_debugfs_single_show(struct seq_file *m, void *v) +static ssize_t rtw89_debugfs_file_read_helper(struct wiphy *wiphy, struct file *file, + char *buf, size_t bufsz, void *data) { - struct rtw89_debugfs_priv *debugfs_priv = m->private; + struct rtw89_debugfs_priv *debugfs_priv = data; + struct rtw89_dev *rtwdev = debugfs_priv->rtwdev; + ssize_t n; - return debugfs_priv->cb_read(m, v); + n = debugfs_priv->cb_read(rtwdev, debugfs_priv, buf, bufsz); + rtw89_might_trailing_ellipsis(buf, bufsz, n); + + return n; } -static ssize_t rtw89_debugfs_single_write(struct file *filp, - const char __user *buffer, - size_t count, loff_t *loff) +static ssize_t rtw89_debugfs_file_read(struct file *file, char __user *userbuf, + size_t count, loff_t *ppos) { - struct rtw89_debugfs_priv *debugfs_priv = filp->private_data; + struct rtw89_debugfs_priv *debugfs_priv = file->private_data; + struct rtw89_debugfs_priv_opt *opt = &debugfs_priv->opt; + struct rtw89_dev *rtwdev = debugfs_priv->rtwdev; + size_t bufsz = opt->rsize ? opt->rsize : PAGE_SIZE; + char *buf; + ssize_t n; - return debugfs_priv->cb_write(filp, buffer, count, loff); -} + if (!debugfs_priv->rbuf) + debugfs_priv->rbuf = devm_kzalloc(rtwdev->dev, bufsz, GFP_KERNEL); -static ssize_t rtw89_debugfs_seq_file_write(struct file *filp, - const char __user *buffer, - size_t count, loff_t *loff) -{ - struct seq_file *seqpriv = (struct seq_file *)filp->private_data; - struct rtw89_debugfs_priv *debugfs_priv = seqpriv->private; + buf = debugfs_priv->rbuf; + if (!buf) + return -ENOMEM; + + if (*ppos) { + n = debugfs_priv->rused; + goto out; + } + + if (opt->rlock) { + n = wiphy_locked_debugfs_read(rtwdev->hw->wiphy, file, buf, bufsz, + userbuf, count, ppos, + rtw89_debugfs_file_read_helper, + debugfs_priv); + debugfs_priv->rused = n; - return debugfs_priv->cb_write(filp, buffer, count, loff); + return n; + } + + n = rtw89_debugfs_file_read_helper(rtwdev->hw->wiphy, file, buf, bufsz, + debugfs_priv); + debugfs_priv->rused = n; + +out: + return simple_read_from_buffer(userbuf, count, ppos, buf, n); } -static int rtw89_debugfs_single_open(struct inode *inode, struct file *filp) +static ssize_t rtw89_debugfs_file_write_helper(struct wiphy *wiphy, struct file *file, + char *buf, size_t count, void *data) { - return single_open(filp, rtw89_debugfs_single_show, inode->i_private); + struct rtw89_debugfs_priv *debugfs_priv = data; + struct rtw89_dev *rtwdev = debugfs_priv->rtwdev; + + return debugfs_priv->cb_write(rtwdev, debugfs_priv, buf, count); } -static int rtw89_debugfs_close(struct inode *inode, struct file *filp) +static ssize_t rtw89_debugfs_file_write(struct file *file, + const char __user *userbuf, + size_t count, loff_t *loff) { - return 0; + struct rtw89_debugfs_priv *debugfs_priv = file->private_data; + struct rtw89_debugfs_priv_opt *opt = &debugfs_priv->opt; + struct rtw89_dev *rtwdev = debugfs_priv->rtwdev; + char *buf __free(kfree) = kmalloc(count + 1, GFP_KERNEL); + ssize_t n; + + if (!buf) + return -ENOMEM; + + if (opt->wlock) { + n = wiphy_locked_debugfs_write(rtwdev->hw->wiphy, + file, buf, count + 1, + userbuf, count, + rtw89_debugfs_file_write_helper, + debugfs_priv); + return n; + } + + if (copy_from_user(buf, userbuf, count)) + return -EFAULT; + + buf[count] = '\0'; + + return debugfs_priv->cb_write(rtwdev, debugfs_priv, buf, count); } -static const struct file_operations file_ops_single_r = { - .owner = THIS_MODULE, - .open = rtw89_debugfs_single_open, - .read = seq_read, - .llseek = seq_lseek, - .release = single_release, +static const struct debugfs_short_fops file_ops_single_r = { + .read = rtw89_debugfs_file_read, + .llseek = generic_file_llseek, }; -static const struct file_operations file_ops_common_rw = { - .owner = THIS_MODULE, - .open = rtw89_debugfs_single_open, - .release = single_release, - .read = seq_read, - .llseek = seq_lseek, - .write = rtw89_debugfs_seq_file_write, +static const struct debugfs_short_fops file_ops_common_rw = { + .read = rtw89_debugfs_file_read, + .write = rtw89_debugfs_file_write, + .llseek = generic_file_llseek, }; -static const struct file_operations file_ops_single_w = { - .owner = THIS_MODULE, - .write = rtw89_debugfs_single_write, - .open = simple_open, - .release = rtw89_debugfs_close, +static const struct debugfs_short_fops file_ops_single_w = { + .write = rtw89_debugfs_file_write, + .llseek = generic_file_llseek, }; static ssize_t -rtw89_debug_priv_read_reg_select(struct file *filp, - const char __user *user_buf, - size_t count, loff_t *loff) +rtw89_debug_priv_read_reg_select(struct rtw89_dev *rtwdev, + struct rtw89_debugfs_priv *debugfs_priv, + const char *buf, size_t count) { - struct seq_file *m = (struct seq_file *)filp->private_data; - struct rtw89_debugfs_priv *debugfs_priv = m->private; - struct rtw89_dev *rtwdev = debugfs_priv->rtwdev; - char buf[32]; - size_t buf_size; u32 addr, len; int num; - buf_size = min(count, sizeof(buf) - 1); - if (copy_from_user(buf, user_buf, buf_size)) - return -EFAULT; - - buf[buf_size] = '\0'; num = sscanf(buf, "%x %x", &addr, &len); if (num != 2) { rtw89_info(rtwdev, "invalid format: <addr> <len>\n"); @@ -182,11 +255,13 @@ rtw89_debug_priv_read_reg_select(struct file *filp, return count; } -static int rtw89_debug_priv_read_reg_get(struct seq_file *m, void *v) +static +ssize_t rtw89_debug_priv_read_reg_get(struct rtw89_dev *rtwdev, + struct rtw89_debugfs_priv *debugfs_priv, + char *buf, size_t bufsz) { - struct rtw89_debugfs_priv *debugfs_priv = m->private; - struct rtw89_dev *rtwdev = debugfs_priv->rtwdev; - u32 addr, end, data, k; + char *p = buf, *end = buf + bufsz; + u32 addr, addr_end, data, k; u32 len; len = debugfs_priv->read_reg.len; @@ -210,41 +285,34 @@ static int rtw89_debug_priv_read_reg_get(struct seq_file *m, void *v) return -EINVAL; } - seq_printf(m, "get %d bytes at 0x%08x=0x%08x\n", len, addr, data); + p += scnprintf(p, end - p, "get %d bytes at 0x%08x=0x%08x\n", len, + addr, data); - return 0; + return p - buf; ndata: - end = addr + len; + addr_end = addr + len; - for (; addr < end; addr += 16) { - seq_printf(m, "%08xh : ", 0x18600000 + addr); + for (; addr < addr_end; addr += 16) { + p += scnprintf(p, end - p, "%08xh : ", 0x18600000 + addr); for (k = 0; k < 16; k += 4) { data = rtw89_read32(rtwdev, addr + k); - seq_printf(m, "%08x ", data); + p += scnprintf(p, end - p, "%08x ", data); } - seq_puts(m, "\n"); + p += scnprintf(p, end - p, "\n"); } - return 0; + return p - buf; } -static ssize_t rtw89_debug_priv_write_reg_set(struct file *filp, - const char __user *user_buf, - size_t count, loff_t *loff) +static +ssize_t rtw89_debug_priv_write_reg_set(struct rtw89_dev *rtwdev, + struct rtw89_debugfs_priv *debugfs_priv, + const char *buf, size_t count) { - struct rtw89_debugfs_priv *debugfs_priv = filp->private_data; - struct rtw89_dev *rtwdev = debugfs_priv->rtwdev; - char buf[32]; - size_t buf_size; u32 addr, val, len; int num; - buf_size = min(count, sizeof(buf) - 1); - if (copy_from_user(buf, user_buf, buf_size)) - return -EFAULT; - - buf[buf_size] = '\0'; num = sscanf(buf, "%x %x %x", &addr, &val, &len); if (num != 3) { rtw89_info(rtwdev, "invalid format: <addr> <val> <len>\n"); @@ -273,24 +341,14 @@ static ssize_t rtw89_debug_priv_write_reg_set(struct file *filp, } static ssize_t -rtw89_debug_priv_read_rf_select(struct file *filp, - const char __user *user_buf, - size_t count, loff_t *loff) +rtw89_debug_priv_read_rf_select(struct rtw89_dev *rtwdev, + struct rtw89_debugfs_priv *debugfs_priv, + const char *buf, size_t count) { - struct seq_file *m = (struct seq_file *)filp->private_data; - struct rtw89_debugfs_priv *debugfs_priv = m->private; - struct rtw89_dev *rtwdev = debugfs_priv->rtwdev; - char buf[32]; - size_t buf_size; u32 addr, mask; u8 path; int num; - buf_size = min(count, sizeof(buf) - 1); - if (copy_from_user(buf, user_buf, buf_size)) - return -EFAULT; - - buf[buf_size] = '\0'; num = sscanf(buf, "%hhd %x %x", &path, &addr, &mask); if (num != 3) { rtw89_info(rtwdev, "invalid format: <path> <addr> <mask>\n"); @@ -310,10 +368,12 @@ rtw89_debug_priv_read_rf_select(struct file *filp, return count; } -static int rtw89_debug_priv_read_rf_get(struct seq_file *m, void *v) +static +ssize_t rtw89_debug_priv_read_rf_get(struct rtw89_dev *rtwdev, + struct rtw89_debugfs_priv *debugfs_priv, + char *buf, size_t bufsz) { - struct rtw89_debugfs_priv *debugfs_priv = m->private; - struct rtw89_dev *rtwdev = debugfs_priv->rtwdev; + char *p = buf, *end = buf + bufsz; u32 addr, data, mask; u8 path; @@ -323,28 +383,21 @@ static int rtw89_debug_priv_read_rf_get(struct seq_file *m, void *v) data = rtw89_read_rf(rtwdev, path, addr, mask); - seq_printf(m, "path %d, rf register 0x%08x=0x%08x\n", path, addr, data); + p += scnprintf(p, end - p, "path %d, rf register 0x%08x=0x%08x\n", + path, addr, data); - return 0; + return p - buf; } -static ssize_t rtw89_debug_priv_write_rf_set(struct file *filp, - const char __user *user_buf, - size_t count, loff_t *loff) +static +ssize_t rtw89_debug_priv_write_rf_set(struct rtw89_dev *rtwdev, + struct rtw89_debugfs_priv *debugfs_priv, + const char *buf, size_t count) { - struct rtw89_debugfs_priv *debugfs_priv = filp->private_data; - struct rtw89_dev *rtwdev = debugfs_priv->rtwdev; - char buf[32]; - size_t buf_size; u32 addr, val, mask; u8 path; int num; - buf_size = min(count, sizeof(buf) - 1); - if (copy_from_user(buf, user_buf, buf_size)) - return -EFAULT; - - buf[buf_size] = '\0'; num = sscanf(buf, "%hhd %x %x %x", &path, &addr, &mask, &val); if (num != 4) { rtw89_info(rtwdev, "invalid format: <path> <addr> <mask> <val>\n"); @@ -363,29 +416,31 @@ static ssize_t rtw89_debug_priv_write_rf_set(struct file *filp, return count; } -static int rtw89_debug_priv_rf_reg_dump_get(struct seq_file *m, void *v) +static +ssize_t rtw89_debug_priv_rf_reg_dump_get(struct rtw89_dev *rtwdev, + struct rtw89_debugfs_priv *debugfs_priv, + char *buf, size_t bufsz) { - struct rtw89_debugfs_priv *debugfs_priv = m->private; - struct rtw89_dev *rtwdev = debugfs_priv->rtwdev; const struct rtw89_chip_info *chip = rtwdev->chip; + char *p = buf, *end = buf + bufsz; u32 addr, offset, data; u8 path; for (path = 0; path < chip->rf_path_num; path++) { - seq_printf(m, "RF path %d:\n\n", path); + p += scnprintf(p, end - p, "RF path %d:\n\n", path); for (addr = 0; addr < 0x100; addr += 4) { - seq_printf(m, "0x%08x: ", addr); + p += scnprintf(p, end - p, "0x%08x: ", addr); for (offset = 0; offset < 4; offset++) { data = rtw89_read_rf(rtwdev, path, addr + offset, RFREG_MASK); - seq_printf(m, "0x%05x ", data); + p += scnprintf(p, end - p, "0x%05x ", data); } - seq_puts(m, "\n"); + p += scnprintf(p, end - p, "\n"); } - seq_puts(m, "\n"); + p += scnprintf(p, end - p, "\n"); } - return 0; + return p - buf; } struct txpwr_ent { @@ -704,56 +759,71 @@ static const struct txpwr_map __txpwr_map_lmt_ru_be = { }; static unsigned int -__print_txpwr_ent(struct seq_file *m, const struct txpwr_ent *ent, - const s8 *buf, const unsigned int cur) +__print_txpwr_ent(char *buf, size_t bufsz, const struct txpwr_ent *ent, + const s8 *bufp, const unsigned int cur, unsigned int *ate) { + char *p = buf, *end = buf + bufsz; unsigned int cnt, i; + unsigned int eaten; char *fmt; if (ent->nested) { - for (cnt = 0, i = 0; i < ent->len; i++) - cnt += __print_txpwr_ent(m, ent->ptr + i, buf, - cur + cnt); - return cnt; + for (cnt = 0, i = 0; i < ent->len; i++, cnt += eaten) + p += __print_txpwr_ent(p, end - p, ent->ptr + i, bufp, + cur + cnt, &eaten); + *ate = cnt; + goto out; } switch (ent->len) { case 0: - seq_printf(m, "\t<< %s >>\n", ent->txt); - return 0; + p += scnprintf(p, end - p, "\t<< %s >>\n", ent->txt); + *ate = 0; + goto out; case 2: fmt = "%s\t| %3d, %3d,\t\tdBm\n"; - seq_printf(m, fmt, ent->txt, buf[cur], buf[cur + 1]); - return 2; + p += scnprintf(p, end - p, fmt, ent->txt, bufp[cur], + bufp[cur + 1]); + *ate = 2; + goto out; case 4: fmt = "%s\t| %3d, %3d, %3d, %3d,\tdBm\n"; - seq_printf(m, fmt, ent->txt, buf[cur], buf[cur + 1], - buf[cur + 2], buf[cur + 3]); - return 4; + p += scnprintf(p, end - p, fmt, ent->txt, bufp[cur], + bufp[cur + 1], + bufp[cur + 2], bufp[cur + 3]); + *ate = 4; + goto out; case 8: fmt = "%s\t| %3d, %3d, %3d, %3d, %3d, %3d, %3d, %3d,\tdBm\n"; - seq_printf(m, fmt, ent->txt, buf[cur], buf[cur + 1], - buf[cur + 2], buf[cur + 3], buf[cur + 4], - buf[cur + 5], buf[cur + 6], buf[cur + 7]); - return 8; + p += scnprintf(p, end - p, fmt, ent->txt, bufp[cur], + bufp[cur + 1], + bufp[cur + 2], bufp[cur + 3], bufp[cur + 4], + bufp[cur + 5], bufp[cur + 6], bufp[cur + 7]); + *ate = 8; + goto out; default: return 0; } + +out: + return p - buf; } -static int __print_txpwr_map(struct seq_file *m, struct rtw89_dev *rtwdev, - const struct txpwr_map *map) +static ssize_t __print_txpwr_map(struct rtw89_dev *rtwdev, char *buf, size_t bufsz, + const struct txpwr_map *map) { u8 fct = rtwdev->chip->txpwr_factor_mac; u8 path_num = rtwdev->chip->rf_path_num; + char *p = buf, *end = buf + bufsz; unsigned int cur, i; + unsigned int eaten; u32 max_valid_addr; u32 val, addr; - s8 *buf, tmp; + s8 *bufp, tmp; int ret; - buf = vzalloc(map->addr_to - map->addr_from + 4); - if (!buf) + bufp = vzalloc(map->addr_to - map->addr_from + 4); + if (!bufp) return -ENOMEM; if (path_num == 1) @@ -773,31 +843,32 @@ static int __print_txpwr_map(struct seq_file *m, struct rtw89_dev *rtwdev, for (i = 0; i < 4; i++, val >>= 8) { /* signed 7 bits, and reserved BIT(7) */ tmp = sign_extend32(val, 6); - buf[cur + i] = tmp >> fct; + bufp[cur + i] = tmp >> fct; } } - for (cur = 0, i = 0; i < map->size; i++) - cur += __print_txpwr_ent(m, &map->ent[i], buf, cur); + for (cur = 0, i = 0; i < map->size; i++, cur += eaten) + p += __print_txpwr_ent(p, end - p, &map->ent[i], bufp, cur, &eaten); - vfree(buf); - return 0; + vfree(bufp); + return p - buf; } #define case_REGD(_regd) \ case RTW89_ ## _regd: \ - seq_puts(m, #_regd "\n"); \ + p += scnprintf(p, end - p, #_regd "\n"); \ break -static void __print_regd(struct seq_file *m, struct rtw89_dev *rtwdev, - const struct rtw89_chan *chan) +static int __print_regd(struct rtw89_dev *rtwdev, char *buf, size_t bufsz, + const struct rtw89_chan *chan) { + char *p = buf, *end = buf + bufsz; u8 band = chan->band_type; u8 regd = rtw89_regd_get(rtwdev, band); switch (regd) { default: - seq_printf(m, "UNKNOWN: %d\n", regd); + p += scnprintf(p, end - p, "UNKNOWN: %d\n", regd); break; case_REGD(WW); case_REGD(ETSI); @@ -816,6 +887,8 @@ static void __print_regd(struct seq_file *m, struct rtw89_dev *rtwdev, case_REGD(UK); case_REGD(THAILAND); } + + return p - buf; } #undef case_REGD @@ -844,96 +917,93 @@ static const struct dbgfs_txpwr_table *dbgfs_txpwr_tables[RTW89_CHIP_GEN_NUM] = }; static -void rtw89_debug_priv_txpwr_table_get_regd(struct seq_file *m, - struct rtw89_dev *rtwdev, - const struct rtw89_chan *chan) +int rtw89_debug_priv_txpwr_table_get_regd(struct rtw89_dev *rtwdev, + char *buf, size_t bufsz, + const struct rtw89_chan *chan) { const struct rtw89_regulatory_info *regulatory = &rtwdev->regulatory; const struct rtw89_reg_6ghz_tpe *tpe6 = ®ulatory->reg_6ghz_tpe; + char *p = buf, *end = buf + bufsz; - seq_printf(m, "[Chanctx] band %u, ch %u, bw %u\n", - chan->band_type, chan->channel, chan->band_width); + p += scnprintf(p, end - p, "[Chanctx] band %u, ch %u, bw %u\n", + chan->band_type, chan->channel, chan->band_width); - seq_puts(m, "[Regulatory] "); - __print_regd(m, rtwdev, chan); + p += scnprintf(p, end - p, "[Regulatory] "); + p += __print_regd(rtwdev, p, end - p, chan); if (chan->band_type == RTW89_BAND_6G) { - seq_printf(m, "[reg6_pwr_type] %u\n", regulatory->reg_6ghz_power); + p += scnprintf(p, end - p, "[reg6_pwr_type] %u\n", + regulatory->reg_6ghz_power); if (tpe6->valid) - seq_printf(m, "[TPE] %d dBm\n", tpe6->constraint); + p += scnprintf(p, end - p, "[TPE] %d dBm\n", + tpe6->constraint); } + + return p - buf; } -static int rtw89_debug_priv_txpwr_table_get(struct seq_file *m, void *v) +static +ssize_t rtw89_debug_priv_txpwr_table_get(struct rtw89_dev *rtwdev, + struct rtw89_debugfs_priv *debugfs_priv, + char *buf, size_t bufsz) { - struct rtw89_debugfs_priv *debugfs_priv = m->private; - struct rtw89_dev *rtwdev = debugfs_priv->rtwdev; enum rtw89_chip_gen chip_gen = rtwdev->chip->chip_gen; const struct dbgfs_txpwr_table *tbl; const struct rtw89_chan *chan; - int ret = 0; + char *p = buf, *end = buf + bufsz; + ssize_t n; + + lockdep_assert_wiphy(rtwdev->hw->wiphy); - mutex_lock(&rtwdev->mutex); rtw89_leave_ps_mode(rtwdev); chan = rtw89_chan_get(rtwdev, RTW89_CHANCTX_0); - rtw89_debug_priv_txpwr_table_get_regd(m, rtwdev, chan); + p += rtw89_debug_priv_txpwr_table_get_regd(rtwdev, p, end - p, chan); - seq_puts(m, "[SAR]\n"); - rtw89_print_sar(m, rtwdev, chan->freq); + p += scnprintf(p, end - p, "[SAR]\n"); + p += rtw89_print_sar(rtwdev, p, end - p, chan->freq); - seq_puts(m, "[TAS]\n"); - rtw89_print_tas(m, rtwdev); + p += scnprintf(p, end - p, "[TAS]\n"); + p += rtw89_print_tas(rtwdev, p, end - p); - seq_puts(m, "[DAG]\n"); - rtw89_print_ant_gain(m, rtwdev, chan); + p += scnprintf(p, end - p, "[DAG]\n"); + p += rtw89_print_ant_gain(rtwdev, p, end - p, chan); tbl = dbgfs_txpwr_tables[chip_gen]; - if (!tbl) { - ret = -EOPNOTSUPP; - goto err; - } - - seq_puts(m, "\n[TX power byrate]\n"); - ret = __print_txpwr_map(m, rtwdev, tbl->byr); - if (ret) - goto err; - - seq_puts(m, "\n[TX power limit]\n"); - ret = __print_txpwr_map(m, rtwdev, tbl->lmt); - if (ret) - goto err; - - seq_puts(m, "\n[TX power limit_ru]\n"); - ret = __print_txpwr_map(m, rtwdev, tbl->lmt_ru); - if (ret) - goto err; + if (!tbl) + return -EOPNOTSUPP; -err: - mutex_unlock(&rtwdev->mutex); - return ret; + p += scnprintf(p, end - p, "\n[TX power byrate]\n"); + n = __print_txpwr_map(rtwdev, p, end - p, tbl->byr); + if (n < 0) + return n; + p += n; + + p += scnprintf(p, end - p, "\n[TX power limit]\n"); + n = __print_txpwr_map(rtwdev, p, end - p, tbl->lmt); + if (n < 0) + return n; + p += n; + + p += scnprintf(p, end - p, "\n[TX power limit_ru]\n"); + n = __print_txpwr_map(rtwdev, p, end - p, tbl->lmt_ru); + if (n < 0) + return n; + p += n; + + return p - buf; } static ssize_t -rtw89_debug_priv_mac_reg_dump_select(struct file *filp, - const char __user *user_buf, - size_t count, loff_t *loff) +rtw89_debug_priv_mac_reg_dump_select(struct rtw89_dev *rtwdev, + struct rtw89_debugfs_priv *debugfs_priv, + const char *buf, size_t count) { - struct seq_file *m = (struct seq_file *)filp->private_data; - struct rtw89_debugfs_priv *debugfs_priv = m->private; - struct rtw89_dev *rtwdev = debugfs_priv->rtwdev; const struct rtw89_chip_info *chip = rtwdev->chip; - char buf[32]; - size_t buf_size; int sel; int ret; - buf_size = min(count, sizeof(buf) - 1); - if (copy_from_user(buf, user_buf, buf_size)) - return -EFAULT; - - buf[buf_size] = '\0'; ret = kstrtoint(buf, 0, &sel); if (ret) return ret; @@ -957,99 +1027,91 @@ rtw89_debug_priv_mac_reg_dump_select(struct file *filp, #define RTW89_MAC_PAGE_SIZE 0x100 -static int rtw89_debug_priv_mac_reg_dump_get(struct seq_file *m, void *v) +static +ssize_t rtw89_debug_priv_mac_reg_dump_get(struct rtw89_dev *rtwdev, + struct rtw89_debugfs_priv *debugfs_priv, + char *buf, size_t bufsz) { - struct rtw89_debugfs_priv *debugfs_priv = m->private; - struct rtw89_dev *rtwdev = debugfs_priv->rtwdev; enum rtw89_debug_mac_reg_sel reg_sel = debugfs_priv->cb_data; - u32 start, end; + char *p = buf, *end = buf + bufsz; + u32 start, end_addr; u32 i, j, k, page; u32 val; switch (reg_sel) { case RTW89_DBG_SEL_MAC_00: - seq_puts(m, "Debug selected MAC page 0x00\n"); + p += scnprintf(p, end - p, "Debug selected MAC page 0x00\n"); start = 0x000; - end = 0x014; + end_addr = 0x014; break; case RTW89_DBG_SEL_MAC_30: - seq_puts(m, "Debug selected MAC page 0x30\n"); + p += scnprintf(p, end - p, "Debug selected MAC page 0x30\n"); start = 0x030; - end = 0x033; + end_addr = 0x033; break; case RTW89_DBG_SEL_MAC_40: - seq_puts(m, "Debug selected MAC page 0x40\n"); + p += scnprintf(p, end - p, "Debug selected MAC page 0x40\n"); start = 0x040; - end = 0x07f; + end_addr = 0x07f; break; case RTW89_DBG_SEL_MAC_80: - seq_puts(m, "Debug selected MAC page 0x80\n"); + p += scnprintf(p, end - p, "Debug selected MAC page 0x80\n"); start = 0x080; - end = 0x09f; + end_addr = 0x09f; break; case RTW89_DBG_SEL_MAC_C0: - seq_puts(m, "Debug selected MAC page 0xc0\n"); + p += scnprintf(p, end - p, "Debug selected MAC page 0xc0\n"); start = 0x0c0; - end = 0x0df; + end_addr = 0x0df; break; case RTW89_DBG_SEL_MAC_E0: - seq_puts(m, "Debug selected MAC page 0xe0\n"); + p += scnprintf(p, end - p, "Debug selected MAC page 0xe0\n"); start = 0x0e0; - end = 0x0ff; + end_addr = 0x0ff; break; case RTW89_DBG_SEL_BB: - seq_puts(m, "Debug selected BB register\n"); + p += scnprintf(p, end - p, "Debug selected BB register\n"); start = 0x100; - end = 0x17f; + end_addr = 0x17f; break; case RTW89_DBG_SEL_IQK: - seq_puts(m, "Debug selected IQK register\n"); + p += scnprintf(p, end - p, "Debug selected IQK register\n"); start = 0x180; - end = 0x1bf; + end_addr = 0x1bf; break; case RTW89_DBG_SEL_RFC: - seq_puts(m, "Debug selected RFC register\n"); + p += scnprintf(p, end - p, "Debug selected RFC register\n"); start = 0x1c0; - end = 0x1ff; + end_addr = 0x1ff; break; default: - seq_puts(m, "Selected invalid register page\n"); + p += scnprintf(p, end - p, "Selected invalid register page\n"); return -EINVAL; } - for (i = start; i <= end; i++) { + for (i = start; i <= end_addr; i++) { page = i << 8; for (j = page; j < page + RTW89_MAC_PAGE_SIZE; j += 16) { - seq_printf(m, "%08xh : ", 0x18600000 + j); + p += scnprintf(p, end - p, "%08xh : ", 0x18600000 + j); for (k = 0; k < 4; k++) { val = rtw89_read32(rtwdev, j + (k << 2)); - seq_printf(m, "%08x ", val); + p += scnprintf(p, end - p, "%08x ", val); } - seq_puts(m, "\n"); + p += scnprintf(p, end - p, "\n"); } } - return 0; + return p - buf; } static ssize_t -rtw89_debug_priv_mac_mem_dump_select(struct file *filp, - const char __user *user_buf, - size_t count, loff_t *loff) +rtw89_debug_priv_mac_mem_dump_select(struct rtw89_dev *rtwdev, + struct rtw89_debugfs_priv *debugfs_priv, + const char *buf, size_t count) { - struct seq_file *m = (struct seq_file *)filp->private_data; - struct rtw89_debugfs_priv *debugfs_priv = m->private; - struct rtw89_dev *rtwdev = debugfs_priv->rtwdev; - char buf[32]; - size_t buf_size; u32 sel, start_addr, len; int num; - buf_size = min(count, sizeof(buf) - 1); - if (copy_from_user(buf, user_buf, buf_size)) - return -EFAULT; - - buf[buf_size] = '\0'; num = sscanf(buf, "%x %x %x", &sel, &start_addr, &len); if (num != 3) { rtw89_info(rtwdev, "invalid format: <sel> <start> <len>\n"); @@ -1066,15 +1128,16 @@ rtw89_debug_priv_mac_mem_dump_select(struct file *filp, return count; } -static void rtw89_debug_dump_mac_mem(struct seq_file *m, - struct rtw89_dev *rtwdev, - u8 sel, u32 start_addr, u32 len) +static int rtw89_debug_dump_mac_mem(struct rtw89_dev *rtwdev, + char *buf, size_t bufsz, + u8 sel, u32 start_addr, u32 len) { const struct rtw89_mac_gen_def *mac = rtwdev->chip->mac_def; u32 filter_model_addr = mac->filter_model_addr; u32 indir_access_addr = mac->indir_access_addr; u32 base_addr, start_page, residue; - u32 i, j, p, pages; + char *p = buf, *end = buf + bufsz; + u32 i, j, pp, pages; u32 dump_len, remain; u32 val; @@ -1085,32 +1148,37 @@ static void rtw89_debug_dump_mac_mem(struct seq_file *m, base_addr = mac->mem_base_addrs[sel]; base_addr += start_page * MAC_MEM_DUMP_PAGE_SIZE; - for (p = 0; p < pages; p++) { + for (pp = 0; pp < pages; pp++) { dump_len = min_t(u32, remain, MAC_MEM_DUMP_PAGE_SIZE); rtw89_write32(rtwdev, filter_model_addr, base_addr); for (i = indir_access_addr + residue; i < indir_access_addr + dump_len;) { - seq_printf(m, "%08xh:", i); + p += scnprintf(p, end - p, "%08xh:", i); for (j = 0; j < 4 && i < indir_access_addr + dump_len; j++, i += 4) { val = rtw89_read32(rtwdev, i); - seq_printf(m, " %08x", val); + p += scnprintf(p, end - p, " %08x", val); remain -= 4; } - seq_puts(m, "\n"); + p += scnprintf(p, end - p, "\n"); } base_addr += MAC_MEM_DUMP_PAGE_SIZE; } + + return p - buf; } -static int -rtw89_debug_priv_mac_mem_dump_get(struct seq_file *m, void *v) +static ssize_t +rtw89_debug_priv_mac_mem_dump_get(struct rtw89_dev *rtwdev, + struct rtw89_debugfs_priv *debugfs_priv, + char *buf, size_t bufsz) { - struct rtw89_debugfs_priv *debugfs_priv = m->private; - struct rtw89_dev *rtwdev = debugfs_priv->rtwdev; + char *p = buf, *end = buf + bufsz; bool grant_read = false; + lockdep_assert_wiphy(rtwdev->hw->wiphy); + if (debugfs_priv->mac_mem.sel >= RTW89_MAC_MEM_NUM) return -ENOENT; @@ -1127,40 +1195,28 @@ rtw89_debug_priv_mac_mem_dump_get(struct seq_file *m, void *v) } } - mutex_lock(&rtwdev->mutex); rtw89_leave_ps_mode(rtwdev); if (grant_read) rtw89_write32_set(rtwdev, R_AX_TCR1, B_AX_TCR_FORCE_READ_TXDFIFO); - rtw89_debug_dump_mac_mem(m, rtwdev, - debugfs_priv->mac_mem.sel, - debugfs_priv->mac_mem.start, - debugfs_priv->mac_mem.len); + p += rtw89_debug_dump_mac_mem(rtwdev, p, end - p, + debugfs_priv->mac_mem.sel, + debugfs_priv->mac_mem.start, + debugfs_priv->mac_mem.len); if (grant_read) rtw89_write32_clr(rtwdev, R_AX_TCR1, B_AX_TCR_FORCE_READ_TXDFIFO); - mutex_unlock(&rtwdev->mutex); - return 0; + return p - buf; } static ssize_t -rtw89_debug_priv_mac_dbg_port_dump_select(struct file *filp, - const char __user *user_buf, - size_t count, loff_t *loff) +rtw89_debug_priv_mac_dbg_port_dump_select(struct rtw89_dev *rtwdev, + struct rtw89_debugfs_priv *debugfs_priv, + const char *buf, size_t count) { - struct seq_file *m = (struct seq_file *)filp->private_data; - struct rtw89_debugfs_priv *debugfs_priv = m->private; - struct rtw89_dev *rtwdev = debugfs_priv->rtwdev; - char buf[32]; - size_t buf_size; int sel, set; int num; bool enable; - buf_size = min(count, sizeof(buf) - 1); - if (copy_from_user(buf, user_buf, buf_size)) - return -EFAULT; - - buf[buf_size] = '\0'; num = sscanf(buf, "%d %d", &sel, &set); if (num != 2) { rtw89_info(rtwdev, "invalid format: <sel> <set>\n"); @@ -1196,13 +1252,13 @@ rtw89_debug_priv_mac_dbg_port_dump_select(struct file *filp, } static int rtw89_debug_mac_dump_ss_dbg(struct rtw89_dev *rtwdev, - struct seq_file *m) + char *buf, size_t bufsz) { return 0; } static int rtw89_debug_mac_dump_dle_dbg(struct rtw89_dev *rtwdev, - struct seq_file *m) + char *buf, size_t bufsz) { #define DLE_DFI_DUMP(__type, __target, __sel) \ ({ \ @@ -1231,7 +1287,7 @@ static int rtw89_debug_mac_dump_dle_dbg(struct rtw89_dev *rtwdev, __data; \ }) -#define DLE_DFI_FREE_PAGE_DUMP(__m, __type) \ +#define DLE_DFI_FREE_PAGE_DUMP(__p, __end, __type) \ ({ \ u32 __freepg, __pubpg; \ u32 __freepg_head, __freepg_tail, __pubpg_num; \ @@ -1241,24 +1297,25 @@ static int rtw89_debug_mac_dump_dle_dbg(struct rtw89_dev *rtwdev, __freepg_head = FIELD_GET(B_AX_DLE_FREE_HEADPG, __freepg); \ __freepg_tail = FIELD_GET(B_AX_DLE_FREE_TAILPG, __freepg); \ __pubpg_num = FIELD_GET(B_AX_DLE_PUB_PGNUM, __pubpg); \ - seq_printf(__m, "[%s] freepg head: %d\n", \ - #__type, __freepg_head); \ - seq_printf(__m, "[%s] freepg tail: %d\n", \ - #__type, __freepg_tail); \ - seq_printf(__m, "[%s] pubpg num : %d\n", \ - #__type, __pubpg_num); \ + __p += scnprintf(__p, __end - __p, "[%s] freepg head: %d\n", \ + #__type, __freepg_head); \ + __p += scnprintf(__p, __end - __p, "[%s] freepg tail: %d\n", \ + #__type, __freepg_tail); \ + __p += scnprintf(__p, __end - __p, "[%s] pubpg num : %d\n", \ + #__type, __pubpg_num); \ }) -#define case_QUOTA(__m, __type, __id) \ +#define case_QUOTA(__p, __end, __type, __id) \ case __type##_QTAID_##__id: \ - val32 = DLE_DFI_DUMP(__type, QUOTA, __type##_QTAID_##__id); \ + val32 = DLE_DFI_DUMP(__type, QUOTA, __type##_QTAID_##__id); \ rsv_pgnum = FIELD_GET(B_AX_DLE_RSV_PGNUM, val32); \ use_pgnum = FIELD_GET(B_AX_DLE_USE_PGNUM, val32); \ - seq_printf(__m, "[%s][%s] rsv_pgnum: %d\n", \ - #__type, #__id, rsv_pgnum); \ - seq_printf(__m, "[%s][%s] use_pgnum: %d\n", \ - #__type, #__id, use_pgnum); \ + __p += scnprintf(__p, __end - __p, "[%s][%s] rsv_pgnum: %d\n", \ + #__type, #__id, rsv_pgnum); \ + __p += scnprintf(__p, __end - __p, "[%s][%s] use_pgnum: %d\n", \ + #__type, #__id, use_pgnum); \ break + char *p = buf, *end = buf + bufsz; u32 quota_id; u32 val32; u16 rsv_pgnum, use_pgnum; @@ -1266,38 +1323,39 @@ static int rtw89_debug_mac_dump_dle_dbg(struct rtw89_dev *rtwdev, ret = rtw89_mac_check_mac_en(rtwdev, 0, RTW89_DMAC_SEL); if (ret) { - seq_puts(m, "[DLE] : DMAC not enabled\n"); - return ret; + p += scnprintf(p, end - p, "[DLE] : DMAC not enabled\n"); + goto out; } - DLE_DFI_FREE_PAGE_DUMP(m, WDE); - DLE_DFI_FREE_PAGE_DUMP(m, PLE); + DLE_DFI_FREE_PAGE_DUMP(p, end, WDE); + DLE_DFI_FREE_PAGE_DUMP(p, end, PLE); for (quota_id = 0; quota_id <= WDE_QTAID_CPUIO; quota_id++) { switch (quota_id) { - case_QUOTA(m, WDE, HOST_IF); - case_QUOTA(m, WDE, WLAN_CPU); - case_QUOTA(m, WDE, DATA_CPU); - case_QUOTA(m, WDE, PKTIN); - case_QUOTA(m, WDE, CPUIO); + case_QUOTA(p, end, WDE, HOST_IF); + case_QUOTA(p, end, WDE, WLAN_CPU); + case_QUOTA(p, end, WDE, DATA_CPU); + case_QUOTA(p, end, WDE, PKTIN); + case_QUOTA(p, end, WDE, CPUIO); } } for (quota_id = 0; quota_id <= PLE_QTAID_CPUIO; quota_id++) { switch (quota_id) { - case_QUOTA(m, PLE, B0_TXPL); - case_QUOTA(m, PLE, B1_TXPL); - case_QUOTA(m, PLE, C2H); - case_QUOTA(m, PLE, H2C); - case_QUOTA(m, PLE, WLAN_CPU); - case_QUOTA(m, PLE, MPDU); - case_QUOTA(m, PLE, CMAC0_RX); - case_QUOTA(m, PLE, CMAC1_RX); - case_QUOTA(m, PLE, CMAC1_BBRPT); - case_QUOTA(m, PLE, WDRLS); - case_QUOTA(m, PLE, CPUIO); + case_QUOTA(p, end, PLE, B0_TXPL); + case_QUOTA(p, end, PLE, B1_TXPL); + case_QUOTA(p, end, PLE, C2H); + case_QUOTA(p, end, PLE, H2C); + case_QUOTA(p, end, PLE, WLAN_CPU); + case_QUOTA(p, end, PLE, MPDU); + case_QUOTA(p, end, PLE, CMAC0_RX); + case_QUOTA(p, end, PLE, CMAC1_RX); + case_QUOTA(p, end, PLE, CMAC1_BBRPT); + case_QUOTA(p, end, PLE, WDRLS); + case_QUOTA(p, end, PLE, CPUIO); } } - return 0; +out: + return p - buf; #undef case_QUOTA #undef DLE_DFI_DUMP @@ -1305,73 +1363,88 @@ static int rtw89_debug_mac_dump_dle_dbg(struct rtw89_dev *rtwdev, } static int rtw89_debug_mac_dump_dmac_dbg(struct rtw89_dev *rtwdev, - struct seq_file *m) + char *buf, size_t bufsz) { const struct rtw89_chip_info *chip = rtwdev->chip; + char *p = buf, *end = buf + bufsz; u32 dmac_err; int i, ret; ret = rtw89_mac_check_mac_en(rtwdev, 0, RTW89_DMAC_SEL); if (ret) { - seq_puts(m, "[DMAC] : DMAC not enabled\n"); - return ret; + p += scnprintf(p, end - p, "[DMAC] : DMAC not enabled\n"); + goto out; } dmac_err = rtw89_read32(rtwdev, R_AX_DMAC_ERR_ISR); - seq_printf(m, "R_AX_DMAC_ERR_ISR=0x%08x\n", dmac_err); - seq_printf(m, "R_AX_DMAC_ERR_IMR=0x%08x\n", - rtw89_read32(rtwdev, R_AX_DMAC_ERR_IMR)); + p += scnprintf(p, end - p, "R_AX_DMAC_ERR_ISR=0x%08x\n", dmac_err); + p += scnprintf(p, end - p, "R_AX_DMAC_ERR_IMR=0x%08x\n", + rtw89_read32(rtwdev, R_AX_DMAC_ERR_IMR)); if (dmac_err) { - seq_printf(m, "R_AX_WDE_ERR_FLAG_CFG=0x%08x\n", - rtw89_read32(rtwdev, R_AX_WDE_ERR_FLAG_CFG_NUM1)); - seq_printf(m, "R_AX_PLE_ERR_FLAG_CFG=0x%08x\n", - rtw89_read32(rtwdev, R_AX_PLE_ERR_FLAG_CFG_NUM1)); + p += scnprintf(p, end - p, "R_AX_WDE_ERR_FLAG_CFG=0x%08x\n", + rtw89_read32(rtwdev, R_AX_WDE_ERR_FLAG_CFG_NUM1)); + p += scnprintf(p, end - p, "R_AX_PLE_ERR_FLAG_CFG=0x%08x\n", + rtw89_read32(rtwdev, R_AX_PLE_ERR_FLAG_CFG_NUM1)); if (chip->chip_id == RTL8852C) { - seq_printf(m, "R_AX_PLE_ERRFLAG_MSG=0x%08x\n", - rtw89_read32(rtwdev, R_AX_PLE_ERRFLAG_MSG)); - seq_printf(m, "R_AX_WDE_ERRFLAG_MSG=0x%08x\n", - rtw89_read32(rtwdev, R_AX_WDE_ERRFLAG_MSG)); - seq_printf(m, "R_AX_PLE_DBGERR_LOCKEN=0x%08x\n", - rtw89_read32(rtwdev, R_AX_PLE_DBGERR_LOCKEN)); - seq_printf(m, "R_AX_PLE_DBGERR_STS=0x%08x\n", - rtw89_read32(rtwdev, R_AX_PLE_DBGERR_STS)); + p += scnprintf(p, end - p, + "R_AX_PLE_ERRFLAG_MSG=0x%08x\n", + rtw89_read32(rtwdev, R_AX_PLE_ERRFLAG_MSG)); + p += scnprintf(p, end - p, + "R_AX_WDE_ERRFLAG_MSG=0x%08x\n", + rtw89_read32(rtwdev, R_AX_WDE_ERRFLAG_MSG)); + p += scnprintf(p, end - p, + "R_AX_PLE_DBGERR_LOCKEN=0x%08x\n", + rtw89_read32(rtwdev, R_AX_PLE_DBGERR_LOCKEN)); + p += scnprintf(p, end - p, + "R_AX_PLE_DBGERR_STS=0x%08x\n", + rtw89_read32(rtwdev, R_AX_PLE_DBGERR_STS)); } } if (dmac_err & B_AX_WDRLS_ERR_FLAG) { - seq_printf(m, "R_AX_WDRLS_ERR_IMR=0x%08x\n", - rtw89_read32(rtwdev, R_AX_WDRLS_ERR_IMR)); - seq_printf(m, "R_AX_WDRLS_ERR_ISR=0x%08x\n", - rtw89_read32(rtwdev, R_AX_WDRLS_ERR_ISR)); + p += scnprintf(p, end - p, "R_AX_WDRLS_ERR_IMR=0x%08x\n", + rtw89_read32(rtwdev, R_AX_WDRLS_ERR_IMR)); + p += scnprintf(p, end - p, "R_AX_WDRLS_ERR_ISR=0x%08x\n", + rtw89_read32(rtwdev, R_AX_WDRLS_ERR_ISR)); if (chip->chip_id == RTL8852C) - seq_printf(m, "R_AX_RPQ_RXBD_IDX=0x%08x\n", - rtw89_read32(rtwdev, R_AX_RPQ_RXBD_IDX_V1)); + p += scnprintf(p, end - p, + "R_AX_RPQ_RXBD_IDX=0x%08x\n", + rtw89_read32(rtwdev, R_AX_RPQ_RXBD_IDX_V1)); else - seq_printf(m, "R_AX_RPQ_RXBD_IDX=0x%08x\n", - rtw89_read32(rtwdev, R_AX_RPQ_RXBD_IDX)); + p += scnprintf(p, end - p, + "R_AX_RPQ_RXBD_IDX=0x%08x\n", + rtw89_read32(rtwdev, R_AX_RPQ_RXBD_IDX)); } if (dmac_err & B_AX_WSEC_ERR_FLAG) { if (chip->chip_id == RTL8852C) { - seq_printf(m, "R_AX_SEC_ERR_IMR=0x%08x\n", - rtw89_read32(rtwdev, R_AX_SEC_ERROR_FLAG_IMR)); - seq_printf(m, "R_AX_SEC_ERR_ISR=0x%08x\n", - rtw89_read32(rtwdev, R_AX_SEC_ERROR_FLAG)); - seq_printf(m, "R_AX_SEC_ENG_CTRL=0x%08x\n", - rtw89_read32(rtwdev, R_AX_SEC_ENG_CTRL)); - seq_printf(m, "R_AX_SEC_MPDU_PROC=0x%08x\n", - rtw89_read32(rtwdev, R_AX_SEC_MPDU_PROC)); - seq_printf(m, "R_AX_SEC_CAM_ACCESS=0x%08x\n", - rtw89_read32(rtwdev, R_AX_SEC_CAM_ACCESS)); - seq_printf(m, "R_AX_SEC_CAM_RDATA=0x%08x\n", - rtw89_read32(rtwdev, R_AX_SEC_CAM_RDATA)); - seq_printf(m, "R_AX_SEC_DEBUG1=0x%08x\n", - rtw89_read32(rtwdev, R_AX_SEC_DEBUG1)); - seq_printf(m, "R_AX_SEC_TX_DEBUG=0x%08x\n", - rtw89_read32(rtwdev, R_AX_SEC_TX_DEBUG)); - seq_printf(m, "R_AX_SEC_RX_DEBUG=0x%08x\n", - rtw89_read32(rtwdev, R_AX_SEC_RX_DEBUG)); + p += scnprintf(p, end - p, + "R_AX_SEC_ERR_IMR=0x%08x\n", + rtw89_read32(rtwdev, R_AX_SEC_ERROR_FLAG_IMR)); + p += scnprintf(p, end - p, + "R_AX_SEC_ERR_ISR=0x%08x\n", + rtw89_read32(rtwdev, R_AX_SEC_ERROR_FLAG)); + p += scnprintf(p, end - p, + "R_AX_SEC_ENG_CTRL=0x%08x\n", + rtw89_read32(rtwdev, R_AX_SEC_ENG_CTRL)); + p += scnprintf(p, end - p, + "R_AX_SEC_MPDU_PROC=0x%08x\n", + rtw89_read32(rtwdev, R_AX_SEC_MPDU_PROC)); + p += scnprintf(p, end - p, + "R_AX_SEC_CAM_ACCESS=0x%08x\n", + rtw89_read32(rtwdev, R_AX_SEC_CAM_ACCESS)); + p += scnprintf(p, end - p, + "R_AX_SEC_CAM_RDATA=0x%08x\n", + rtw89_read32(rtwdev, R_AX_SEC_CAM_RDATA)); + p += scnprintf(p, end - p, "R_AX_SEC_DEBUG1=0x%08x\n", + rtw89_read32(rtwdev, R_AX_SEC_DEBUG1)); + p += scnprintf(p, end - p, + "R_AX_SEC_TX_DEBUG=0x%08x\n", + rtw89_read32(rtwdev, R_AX_SEC_TX_DEBUG)); + p += scnprintf(p, end - p, + "R_AX_SEC_RX_DEBUG=0x%08x\n", + rtw89_read32(rtwdev, R_AX_SEC_RX_DEBUG)); rtw89_write32_mask(rtwdev, R_AX_DBG_CTRL, B_AX_DBG_SEL0, 0x8B); @@ -1382,187 +1455,229 @@ static int rtw89_debug_mac_dump_dmac_dbg(struct rtw89_dev *rtwdev, for (i = 0; i < 0x10; i++) { rtw89_write32_mask(rtwdev, R_AX_SEC_ENG_CTRL, B_AX_SEC_DBG_PORT_FIELD_MASK, i); - seq_printf(m, "sel=%x,R_AX_SEC_DEBUG2=0x%08x\n", - i, rtw89_read32(rtwdev, R_AX_SEC_DEBUG2)); + p += scnprintf(p, end - p, + "sel=%x,R_AX_SEC_DEBUG2=0x%08x\n", + i, + rtw89_read32(rtwdev, R_AX_SEC_DEBUG2)); } } else { - seq_printf(m, "R_AX_SEC_ERR_IMR_ISR=0x%08x\n", - rtw89_read32(rtwdev, R_AX_SEC_DEBUG)); - seq_printf(m, "R_AX_SEC_ENG_CTRL=0x%08x\n", - rtw89_read32(rtwdev, R_AX_SEC_ENG_CTRL)); - seq_printf(m, "R_AX_SEC_MPDU_PROC=0x%08x\n", - rtw89_read32(rtwdev, R_AX_SEC_MPDU_PROC)); - seq_printf(m, "R_AX_SEC_CAM_ACCESS=0x%08x\n", - rtw89_read32(rtwdev, R_AX_SEC_CAM_ACCESS)); - seq_printf(m, "R_AX_SEC_CAM_RDATA=0x%08x\n", - rtw89_read32(rtwdev, R_AX_SEC_CAM_RDATA)); - seq_printf(m, "R_AX_SEC_CAM_WDATA=0x%08x\n", - rtw89_read32(rtwdev, R_AX_SEC_CAM_WDATA)); - seq_printf(m, "R_AX_SEC_TX_DEBUG=0x%08x\n", - rtw89_read32(rtwdev, R_AX_SEC_TX_DEBUG)); - seq_printf(m, "R_AX_SEC_RX_DEBUG=0x%08x\n", - rtw89_read32(rtwdev, R_AX_SEC_RX_DEBUG)); - seq_printf(m, "R_AX_SEC_TRX_PKT_CNT=0x%08x\n", - rtw89_read32(rtwdev, R_AX_SEC_TRX_PKT_CNT)); - seq_printf(m, "R_AX_SEC_TRX_BLK_CNT=0x%08x\n", - rtw89_read32(rtwdev, R_AX_SEC_TRX_BLK_CNT)); + p += scnprintf(p, end - p, + "R_AX_SEC_ERR_IMR_ISR=0x%08x\n", + rtw89_read32(rtwdev, R_AX_SEC_DEBUG)); + p += scnprintf(p, end - p, + "R_AX_SEC_ENG_CTRL=0x%08x\n", + rtw89_read32(rtwdev, R_AX_SEC_ENG_CTRL)); + p += scnprintf(p, end - p, + "R_AX_SEC_MPDU_PROC=0x%08x\n", + rtw89_read32(rtwdev, R_AX_SEC_MPDU_PROC)); + p += scnprintf(p, end - p, + "R_AX_SEC_CAM_ACCESS=0x%08x\n", + rtw89_read32(rtwdev, R_AX_SEC_CAM_ACCESS)); + p += scnprintf(p, end - p, + "R_AX_SEC_CAM_RDATA=0x%08x\n", + rtw89_read32(rtwdev, R_AX_SEC_CAM_RDATA)); + p += scnprintf(p, end - p, + "R_AX_SEC_CAM_WDATA=0x%08x\n", + rtw89_read32(rtwdev, R_AX_SEC_CAM_WDATA)); + p += scnprintf(p, end - p, + "R_AX_SEC_TX_DEBUG=0x%08x\n", + rtw89_read32(rtwdev, R_AX_SEC_TX_DEBUG)); + p += scnprintf(p, end - p, + "R_AX_SEC_RX_DEBUG=0x%08x\n", + rtw89_read32(rtwdev, R_AX_SEC_RX_DEBUG)); + p += scnprintf(p, end - p, + "R_AX_SEC_TRX_PKT_CNT=0x%08x\n", + rtw89_read32(rtwdev, R_AX_SEC_TRX_PKT_CNT)); + p += scnprintf(p, end - p, + "R_AX_SEC_TRX_BLK_CNT=0x%08x\n", + rtw89_read32(rtwdev, R_AX_SEC_TRX_BLK_CNT)); } } if (dmac_err & B_AX_MPDU_ERR_FLAG) { - seq_printf(m, "R_AX_MPDU_TX_ERR_IMR=0x%08x\n", - rtw89_read32(rtwdev, R_AX_MPDU_TX_ERR_IMR)); - seq_printf(m, "R_AX_MPDU_TX_ERR_ISR=0x%08x\n", - rtw89_read32(rtwdev, R_AX_MPDU_TX_ERR_ISR)); - seq_printf(m, "R_AX_MPDU_RX_ERR_IMR=0x%08x\n", - rtw89_read32(rtwdev, R_AX_MPDU_RX_ERR_IMR)); - seq_printf(m, "R_AX_MPDU_RX_ERR_ISR=0x%08x\n", - rtw89_read32(rtwdev, R_AX_MPDU_RX_ERR_ISR)); + p += scnprintf(p, end - p, "R_AX_MPDU_TX_ERR_IMR=0x%08x\n", + rtw89_read32(rtwdev, R_AX_MPDU_TX_ERR_IMR)); + p += scnprintf(p, end - p, "R_AX_MPDU_TX_ERR_ISR=0x%08x\n", + rtw89_read32(rtwdev, R_AX_MPDU_TX_ERR_ISR)); + p += scnprintf(p, end - p, "R_AX_MPDU_RX_ERR_IMR=0x%08x\n", + rtw89_read32(rtwdev, R_AX_MPDU_RX_ERR_IMR)); + p += scnprintf(p, end - p, "R_AX_MPDU_RX_ERR_ISR=0x%08x\n", + rtw89_read32(rtwdev, R_AX_MPDU_RX_ERR_ISR)); } if (dmac_err & B_AX_STA_SCHEDULER_ERR_FLAG) { - seq_printf(m, "R_AX_STA_SCHEDULER_ERR_IMR=0x%08x\n", - rtw89_read32(rtwdev, R_AX_STA_SCHEDULER_ERR_IMR)); - seq_printf(m, "R_AX_STA_SCHEDULER_ERR_ISR=0x%08x\n", - rtw89_read32(rtwdev, R_AX_STA_SCHEDULER_ERR_ISR)); + p += scnprintf(p, end - p, + "R_AX_STA_SCHEDULER_ERR_IMR=0x%08x\n", + rtw89_read32(rtwdev, R_AX_STA_SCHEDULER_ERR_IMR)); + p += scnprintf(p, end - p, + "R_AX_STA_SCHEDULER_ERR_ISR=0x%08x\n", + rtw89_read32(rtwdev, R_AX_STA_SCHEDULER_ERR_ISR)); } if (dmac_err & B_AX_WDE_DLE_ERR_FLAG) { - seq_printf(m, "R_AX_WDE_ERR_IMR=0x%08x\n", - rtw89_read32(rtwdev, R_AX_WDE_ERR_IMR)); - seq_printf(m, "R_AX_WDE_ERR_ISR=0x%08x\n", - rtw89_read32(rtwdev, R_AX_WDE_ERR_ISR)); - seq_printf(m, "R_AX_PLE_ERR_IMR=0x%08x\n", - rtw89_read32(rtwdev, R_AX_PLE_ERR_IMR)); - seq_printf(m, "R_AX_PLE_ERR_FLAG_ISR=0x%08x\n", - rtw89_read32(rtwdev, R_AX_PLE_ERR_FLAG_ISR)); + p += scnprintf(p, end - p, "R_AX_WDE_ERR_IMR=0x%08x\n", + rtw89_read32(rtwdev, R_AX_WDE_ERR_IMR)); + p += scnprintf(p, end - p, "R_AX_WDE_ERR_ISR=0x%08x\n", + rtw89_read32(rtwdev, R_AX_WDE_ERR_ISR)); + p += scnprintf(p, end - p, "R_AX_PLE_ERR_IMR=0x%08x\n", + rtw89_read32(rtwdev, R_AX_PLE_ERR_IMR)); + p += scnprintf(p, end - p, "R_AX_PLE_ERR_FLAG_ISR=0x%08x\n", + rtw89_read32(rtwdev, R_AX_PLE_ERR_FLAG_ISR)); } if (dmac_err & B_AX_TXPKTCTRL_ERR_FLAG) { if (chip->chip_id == RTL8852C) { - seq_printf(m, "R_AX_TXPKTCTL_B0_ERRFLAG_IMR=0x%08x\n", - rtw89_read32(rtwdev, R_AX_TXPKTCTL_B0_ERRFLAG_IMR)); - seq_printf(m, "R_AX_TXPKTCTL_B0_ERRFLAG_ISR=0x%08x\n", - rtw89_read32(rtwdev, R_AX_TXPKTCTL_B0_ERRFLAG_ISR)); - seq_printf(m, "R_AX_TXPKTCTL_B1_ERRFLAG_IMR=0x%08x\n", - rtw89_read32(rtwdev, R_AX_TXPKTCTL_B1_ERRFLAG_IMR)); - seq_printf(m, "R_AX_TXPKTCTL_B1_ERRFLAG_ISR=0x%08x\n", - rtw89_read32(rtwdev, R_AX_TXPKTCTL_B1_ERRFLAG_ISR)); + p += scnprintf(p, end - p, + "R_AX_TXPKTCTL_B0_ERRFLAG_IMR=0x%08x\n", + rtw89_read32(rtwdev, R_AX_TXPKTCTL_B0_ERRFLAG_IMR)); + p += scnprintf(p, end - p, + "R_AX_TXPKTCTL_B0_ERRFLAG_ISR=0x%08x\n", + rtw89_read32(rtwdev, R_AX_TXPKTCTL_B0_ERRFLAG_ISR)); + p += scnprintf(p, end - p, + "R_AX_TXPKTCTL_B1_ERRFLAG_IMR=0x%08x\n", + rtw89_read32(rtwdev, R_AX_TXPKTCTL_B1_ERRFLAG_IMR)); + p += scnprintf(p, end - p, + "R_AX_TXPKTCTL_B1_ERRFLAG_ISR=0x%08x\n", + rtw89_read32(rtwdev, R_AX_TXPKTCTL_B1_ERRFLAG_ISR)); } else { - seq_printf(m, "R_AX_TXPKTCTL_ERR_IMR_ISR=0x%08x\n", - rtw89_read32(rtwdev, R_AX_TXPKTCTL_ERR_IMR_ISR)); - seq_printf(m, "R_AX_TXPKTCTL_ERR_IMR_ISR_B1=0x%08x\n", - rtw89_read32(rtwdev, R_AX_TXPKTCTL_ERR_IMR_ISR_B1)); + p += scnprintf(p, end - p, + "R_AX_TXPKTCTL_ERR_IMR_ISR=0x%08x\n", + rtw89_read32(rtwdev, R_AX_TXPKTCTL_ERR_IMR_ISR)); + p += scnprintf(p, end - p, + "R_AX_TXPKTCTL_ERR_IMR_ISR_B1=0x%08x\n", + rtw89_read32(rtwdev, R_AX_TXPKTCTL_ERR_IMR_ISR_B1)); } } if (dmac_err & B_AX_PLE_DLE_ERR_FLAG) { - seq_printf(m, "R_AX_WDE_ERR_IMR=0x%08x\n", - rtw89_read32(rtwdev, R_AX_WDE_ERR_IMR)); - seq_printf(m, "R_AX_WDE_ERR_ISR=0x%08x\n", - rtw89_read32(rtwdev, R_AX_WDE_ERR_ISR)); - seq_printf(m, "R_AX_PLE_ERR_IMR=0x%08x\n", - rtw89_read32(rtwdev, R_AX_PLE_ERR_IMR)); - seq_printf(m, "R_AX_PLE_ERR_FLAG_ISR=0x%08x\n", - rtw89_read32(rtwdev, R_AX_PLE_ERR_FLAG_ISR)); - seq_printf(m, "R_AX_WD_CPUQ_OP_0=0x%08x\n", - rtw89_read32(rtwdev, R_AX_WD_CPUQ_OP_0)); - seq_printf(m, "R_AX_WD_CPUQ_OP_1=0x%08x\n", - rtw89_read32(rtwdev, R_AX_WD_CPUQ_OP_1)); - seq_printf(m, "R_AX_WD_CPUQ_OP_2=0x%08x\n", - rtw89_read32(rtwdev, R_AX_WD_CPUQ_OP_2)); - seq_printf(m, "R_AX_WD_CPUQ_OP_STATUS=0x%08x\n", - rtw89_read32(rtwdev, R_AX_WD_CPUQ_OP_STATUS)); - seq_printf(m, "R_AX_PL_CPUQ_OP_0=0x%08x\n", - rtw89_read32(rtwdev, R_AX_PL_CPUQ_OP_0)); - seq_printf(m, "R_AX_PL_CPUQ_OP_1=0x%08x\n", - rtw89_read32(rtwdev, R_AX_PL_CPUQ_OP_1)); - seq_printf(m, "R_AX_PL_CPUQ_OP_2=0x%08x\n", - rtw89_read32(rtwdev, R_AX_PL_CPUQ_OP_2)); - seq_printf(m, "R_AX_PL_CPUQ_OP_STATUS=0x%08x\n", - rtw89_read32(rtwdev, R_AX_PL_CPUQ_OP_STATUS)); + p += scnprintf(p, end - p, "R_AX_WDE_ERR_IMR=0x%08x\n", + rtw89_read32(rtwdev, R_AX_WDE_ERR_IMR)); + p += scnprintf(p, end - p, "R_AX_WDE_ERR_ISR=0x%08x\n", + rtw89_read32(rtwdev, R_AX_WDE_ERR_ISR)); + p += scnprintf(p, end - p, "R_AX_PLE_ERR_IMR=0x%08x\n", + rtw89_read32(rtwdev, R_AX_PLE_ERR_IMR)); + p += scnprintf(p, end - p, "R_AX_PLE_ERR_FLAG_ISR=0x%08x\n", + rtw89_read32(rtwdev, R_AX_PLE_ERR_FLAG_ISR)); + p += scnprintf(p, end - p, "R_AX_WD_CPUQ_OP_0=0x%08x\n", + rtw89_read32(rtwdev, R_AX_WD_CPUQ_OP_0)); + p += scnprintf(p, end - p, "R_AX_WD_CPUQ_OP_1=0x%08x\n", + rtw89_read32(rtwdev, R_AX_WD_CPUQ_OP_1)); + p += scnprintf(p, end - p, "R_AX_WD_CPUQ_OP_2=0x%08x\n", + rtw89_read32(rtwdev, R_AX_WD_CPUQ_OP_2)); + p += scnprintf(p, end - p, "R_AX_WD_CPUQ_OP_STATUS=0x%08x\n", + rtw89_read32(rtwdev, R_AX_WD_CPUQ_OP_STATUS)); + p += scnprintf(p, end - p, "R_AX_PL_CPUQ_OP_0=0x%08x\n", + rtw89_read32(rtwdev, R_AX_PL_CPUQ_OP_0)); + p += scnprintf(p, end - p, "R_AX_PL_CPUQ_OP_1=0x%08x\n", + rtw89_read32(rtwdev, R_AX_PL_CPUQ_OP_1)); + p += scnprintf(p, end - p, "R_AX_PL_CPUQ_OP_2=0x%08x\n", + rtw89_read32(rtwdev, R_AX_PL_CPUQ_OP_2)); + p += scnprintf(p, end - p, "R_AX_PL_CPUQ_OP_STATUS=0x%08x\n", + rtw89_read32(rtwdev, R_AX_PL_CPUQ_OP_STATUS)); if (chip->chip_id == RTL8852C) { - seq_printf(m, "R_AX_RX_CTRL0=0x%08x\n", - rtw89_read32(rtwdev, R_AX_RX_CTRL0)); - seq_printf(m, "R_AX_RX_CTRL1=0x%08x\n", - rtw89_read32(rtwdev, R_AX_RX_CTRL1)); - seq_printf(m, "R_AX_RX_CTRL2=0x%08x\n", - rtw89_read32(rtwdev, R_AX_RX_CTRL2)); + p += scnprintf(p, end - p, "R_AX_RX_CTRL0=0x%08x\n", + rtw89_read32(rtwdev, R_AX_RX_CTRL0)); + p += scnprintf(p, end - p, "R_AX_RX_CTRL1=0x%08x\n", + rtw89_read32(rtwdev, R_AX_RX_CTRL1)); + p += scnprintf(p, end - p, "R_AX_RX_CTRL2=0x%08x\n", + rtw89_read32(rtwdev, R_AX_RX_CTRL2)); } else { - seq_printf(m, "R_AX_RXDMA_PKT_INFO_0=0x%08x\n", - rtw89_read32(rtwdev, R_AX_RXDMA_PKT_INFO_0)); - seq_printf(m, "R_AX_RXDMA_PKT_INFO_1=0x%08x\n", - rtw89_read32(rtwdev, R_AX_RXDMA_PKT_INFO_1)); - seq_printf(m, "R_AX_RXDMA_PKT_INFO_2=0x%08x\n", - rtw89_read32(rtwdev, R_AX_RXDMA_PKT_INFO_2)); + p += scnprintf(p, end - p, + "R_AX_RXDMA_PKT_INFO_0=0x%08x\n", + rtw89_read32(rtwdev, R_AX_RXDMA_PKT_INFO_0)); + p += scnprintf(p, end - p, + "R_AX_RXDMA_PKT_INFO_1=0x%08x\n", + rtw89_read32(rtwdev, R_AX_RXDMA_PKT_INFO_1)); + p += scnprintf(p, end - p, + "R_AX_RXDMA_PKT_INFO_2=0x%08x\n", + rtw89_read32(rtwdev, R_AX_RXDMA_PKT_INFO_2)); } } if (dmac_err & B_AX_PKTIN_ERR_FLAG) { - seq_printf(m, "R_AX_PKTIN_ERR_IMR=0x%08x\n", - rtw89_read32(rtwdev, R_AX_PKTIN_ERR_IMR)); - seq_printf(m, "R_AX_PKTIN_ERR_ISR=0x%08x\n", - rtw89_read32(rtwdev, R_AX_PKTIN_ERR_ISR)); + p += scnprintf(p, end - p, "R_AX_PKTIN_ERR_IMR=0x%08x\n", + rtw89_read32(rtwdev, R_AX_PKTIN_ERR_IMR)); + p += scnprintf(p, end - p, "R_AX_PKTIN_ERR_ISR=0x%08x\n", + rtw89_read32(rtwdev, R_AX_PKTIN_ERR_ISR)); } if (dmac_err & B_AX_DISPATCH_ERR_FLAG) { - seq_printf(m, "R_AX_HOST_DISPATCHER_ERR_IMR=0x%08x\n", - rtw89_read32(rtwdev, R_AX_HOST_DISPATCHER_ERR_IMR)); - seq_printf(m, "R_AX_HOST_DISPATCHER_ERR_ISR=0x%08x\n", - rtw89_read32(rtwdev, R_AX_HOST_DISPATCHER_ERR_ISR)); - seq_printf(m, "R_AX_CPU_DISPATCHER_ERR_IMR=0x%08x\n", - rtw89_read32(rtwdev, R_AX_CPU_DISPATCHER_ERR_IMR)); - seq_printf(m, "R_AX_CPU_DISPATCHER_ERR_ISR=0x%08x\n", - rtw89_read32(rtwdev, R_AX_CPU_DISPATCHER_ERR_ISR)); - seq_printf(m, "R_AX_OTHER_DISPATCHER_ERR_IMR=0x%08x\n", - rtw89_read32(rtwdev, R_AX_OTHER_DISPATCHER_ERR_IMR)); - seq_printf(m, "R_AX_OTHER_DISPATCHER_ERR_ISR=0x%08x\n", - rtw89_read32(rtwdev, R_AX_OTHER_DISPATCHER_ERR_ISR)); + p += scnprintf(p, end - p, + "R_AX_HOST_DISPATCHER_ERR_IMR=0x%08x\n", + rtw89_read32(rtwdev, R_AX_HOST_DISPATCHER_ERR_IMR)); + p += scnprintf(p, end - p, + "R_AX_HOST_DISPATCHER_ERR_ISR=0x%08x\n", + rtw89_read32(rtwdev, R_AX_HOST_DISPATCHER_ERR_ISR)); + p += scnprintf(p, end - p, + "R_AX_CPU_DISPATCHER_ERR_IMR=0x%08x\n", + rtw89_read32(rtwdev, R_AX_CPU_DISPATCHER_ERR_IMR)); + p += scnprintf(p, end - p, + "R_AX_CPU_DISPATCHER_ERR_ISR=0x%08x\n", + rtw89_read32(rtwdev, R_AX_CPU_DISPATCHER_ERR_ISR)); + p += scnprintf(p, end - p, + "R_AX_OTHER_DISPATCHER_ERR_IMR=0x%08x\n", + rtw89_read32(rtwdev, R_AX_OTHER_DISPATCHER_ERR_IMR)); + p += scnprintf(p, end - p, + "R_AX_OTHER_DISPATCHER_ERR_ISR=0x%08x\n", + rtw89_read32(rtwdev, R_AX_OTHER_DISPATCHER_ERR_ISR)); } if (dmac_err & B_AX_BBRPT_ERR_FLAG) { if (chip->chip_id == RTL8852C) { - seq_printf(m, "R_AX_BBRPT_COM_ERR_IMR=0x%08x\n", - rtw89_read32(rtwdev, R_AX_BBRPT_COM_ERR_IMR)); - seq_printf(m, "R_AX_BBRPT_COM_ERR_ISR=0x%08x\n", - rtw89_read32(rtwdev, R_AX_BBRPT_COM_ERR_ISR)); - seq_printf(m, "R_AX_BBRPT_CHINFO_ERR_ISR=0x%08x\n", - rtw89_read32(rtwdev, R_AX_BBRPT_CHINFO_ERR_ISR)); - seq_printf(m, "R_AX_BBRPT_CHINFO_ERR_IMR=0x%08x\n", - rtw89_read32(rtwdev, R_AX_BBRPT_CHINFO_ERR_IMR)); - seq_printf(m, "R_AX_BBRPT_DFS_ERR_IMR=0x%08x\n", - rtw89_read32(rtwdev, R_AX_BBRPT_DFS_ERR_IMR)); - seq_printf(m, "R_AX_BBRPT_DFS_ERR_ISR=0x%08x\n", - rtw89_read32(rtwdev, R_AX_BBRPT_DFS_ERR_ISR)); + p += scnprintf(p, end - p, + "R_AX_BBRPT_COM_ERR_IMR=0x%08x\n", + rtw89_read32(rtwdev, R_AX_BBRPT_COM_ERR_IMR)); + p += scnprintf(p, end - p, + "R_AX_BBRPT_COM_ERR_ISR=0x%08x\n", + rtw89_read32(rtwdev, R_AX_BBRPT_COM_ERR_ISR)); + p += scnprintf(p, end - p, + "R_AX_BBRPT_CHINFO_ERR_ISR=0x%08x\n", + rtw89_read32(rtwdev, R_AX_BBRPT_CHINFO_ERR_ISR)); + p += scnprintf(p, end - p, + "R_AX_BBRPT_CHINFO_ERR_IMR=0x%08x\n", + rtw89_read32(rtwdev, R_AX_BBRPT_CHINFO_ERR_IMR)); + p += scnprintf(p, end - p, + "R_AX_BBRPT_DFS_ERR_IMR=0x%08x\n", + rtw89_read32(rtwdev, R_AX_BBRPT_DFS_ERR_IMR)); + p += scnprintf(p, end - p, + "R_AX_BBRPT_DFS_ERR_ISR=0x%08x\n", + rtw89_read32(rtwdev, R_AX_BBRPT_DFS_ERR_ISR)); } else { - seq_printf(m, "R_AX_BBRPT_COM_ERR_IMR_ISR=0x%08x\n", - rtw89_read32(rtwdev, R_AX_BBRPT_COM_ERR_IMR_ISR)); - seq_printf(m, "R_AX_BBRPT_CHINFO_ERR_ISR=0x%08x\n", - rtw89_read32(rtwdev, R_AX_BBRPT_CHINFO_ERR_ISR)); - seq_printf(m, "R_AX_BBRPT_CHINFO_ERR_IMR=0x%08x\n", - rtw89_read32(rtwdev, R_AX_BBRPT_CHINFO_ERR_IMR)); - seq_printf(m, "R_AX_BBRPT_DFS_ERR_IMR=0x%08x\n", - rtw89_read32(rtwdev, R_AX_BBRPT_DFS_ERR_IMR)); - seq_printf(m, "R_AX_BBRPT_DFS_ERR_ISR=0x%08x\n", - rtw89_read32(rtwdev, R_AX_BBRPT_DFS_ERR_ISR)); + p += scnprintf(p, end - p, + "R_AX_BBRPT_COM_ERR_IMR_ISR=0x%08x\n", + rtw89_read32(rtwdev, R_AX_BBRPT_COM_ERR_IMR_ISR)); + p += scnprintf(p, end - p, + "R_AX_BBRPT_CHINFO_ERR_ISR=0x%08x\n", + rtw89_read32(rtwdev, R_AX_BBRPT_CHINFO_ERR_ISR)); + p += scnprintf(p, end - p, + "R_AX_BBRPT_CHINFO_ERR_IMR=0x%08x\n", + rtw89_read32(rtwdev, R_AX_BBRPT_CHINFO_ERR_IMR)); + p += scnprintf(p, end - p, + "R_AX_BBRPT_DFS_ERR_IMR=0x%08x\n", + rtw89_read32(rtwdev, R_AX_BBRPT_DFS_ERR_IMR)); + p += scnprintf(p, end - p, + "R_AX_BBRPT_DFS_ERR_ISR=0x%08x\n", + rtw89_read32(rtwdev, R_AX_BBRPT_DFS_ERR_ISR)); } } if (dmac_err & B_AX_HAXIDMA_ERR_FLAG && chip->chip_id == RTL8852C) { - seq_printf(m, "R_AX_HAXIDMA_ERR_IMR=0x%08x\n", - rtw89_read32(rtwdev, R_AX_HAXI_IDCT_MSK)); - seq_printf(m, "R_AX_HAXIDMA_ERR_ISR=0x%08x\n", - rtw89_read32(rtwdev, R_AX_HAXI_IDCT)); + p += scnprintf(p, end - p, "R_AX_HAXIDMA_ERR_IMR=0x%08x\n", + rtw89_read32(rtwdev, R_AX_HAXI_IDCT_MSK)); + p += scnprintf(p, end - p, "R_AX_HAXIDMA_ERR_ISR=0x%08x\n", + rtw89_read32(rtwdev, R_AX_HAXI_IDCT)); } - return 0; +out: + return p - buf; } static int rtw89_debug_mac_dump_cmac_err(struct rtw89_dev *rtwdev, - struct seq_file *m, + char *buf, size_t bufsz, enum rtw89_mac_idx band) { const struct rtw89_chip_info *chip = rtwdev->chip; + char *p = buf, *end = buf + bufsz; u32 offset = 0; u32 cmac_err; int ret; @@ -1570,96 +1685,127 @@ static int rtw89_debug_mac_dump_cmac_err(struct rtw89_dev *rtwdev, ret = rtw89_mac_check_mac_en(rtwdev, band, RTW89_CMAC_SEL); if (ret) { if (band) - seq_puts(m, "[CMAC] : CMAC1 not enabled\n"); + p += scnprintf(p, end - p, + "[CMAC] : CMAC1 not enabled\n"); else - seq_puts(m, "[CMAC] : CMAC0 not enabled\n"); - return ret; + p += scnprintf(p, end - p, + "[CMAC] : CMAC0 not enabled\n"); + goto out; } if (band) offset = RTW89_MAC_AX_BAND_REG_OFFSET; cmac_err = rtw89_read32(rtwdev, R_AX_CMAC_ERR_ISR + offset); - seq_printf(m, "R_AX_CMAC_ERR_ISR [%d]=0x%08x\n", band, - rtw89_read32(rtwdev, R_AX_CMAC_ERR_ISR + offset)); - seq_printf(m, "R_AX_CMAC_FUNC_EN [%d]=0x%08x\n", band, - rtw89_read32(rtwdev, R_AX_CMAC_FUNC_EN + offset)); - seq_printf(m, "R_AX_CK_EN [%d]=0x%08x\n", band, - rtw89_read32(rtwdev, R_AX_CK_EN + offset)); + p += scnprintf(p, end - p, "R_AX_CMAC_ERR_ISR [%d]=0x%08x\n", band, + rtw89_read32(rtwdev, R_AX_CMAC_ERR_ISR + offset)); + p += scnprintf(p, end - p, "R_AX_CMAC_FUNC_EN [%d]=0x%08x\n", band, + rtw89_read32(rtwdev, R_AX_CMAC_FUNC_EN + offset)); + p += scnprintf(p, end - p, "R_AX_CK_EN [%d]=0x%08x\n", band, + rtw89_read32(rtwdev, R_AX_CK_EN + offset)); if (cmac_err & B_AX_SCHEDULE_TOP_ERR_IND) { - seq_printf(m, "R_AX_SCHEDULE_ERR_IMR [%d]=0x%08x\n", band, - rtw89_read32(rtwdev, R_AX_SCHEDULE_ERR_IMR + offset)); - seq_printf(m, "R_AX_SCHEDULE_ERR_ISR [%d]=0x%08x\n", band, - rtw89_read32(rtwdev, R_AX_SCHEDULE_ERR_ISR + offset)); + p += scnprintf(p, end - p, + "R_AX_SCHEDULE_ERR_IMR [%d]=0x%08x\n", band, + rtw89_read32(rtwdev, R_AX_SCHEDULE_ERR_IMR + offset)); + p += scnprintf(p, end - p, + "R_AX_SCHEDULE_ERR_ISR [%d]=0x%08x\n", band, + rtw89_read32(rtwdev, R_AX_SCHEDULE_ERR_ISR + offset)); } if (cmac_err & B_AX_PTCL_TOP_ERR_IND) { - seq_printf(m, "R_AX_PTCL_IMR0 [%d]=0x%08x\n", band, - rtw89_read32(rtwdev, R_AX_PTCL_IMR0 + offset)); - seq_printf(m, "R_AX_PTCL_ISR0 [%d]=0x%08x\n", band, - rtw89_read32(rtwdev, R_AX_PTCL_ISR0 + offset)); + p += scnprintf(p, end - p, "R_AX_PTCL_IMR0 [%d]=0x%08x\n", + band, + rtw89_read32(rtwdev, R_AX_PTCL_IMR0 + offset)); + p += scnprintf(p, end - p, "R_AX_PTCL_ISR0 [%d]=0x%08x\n", + band, + rtw89_read32(rtwdev, R_AX_PTCL_ISR0 + offset)); } if (cmac_err & B_AX_DMA_TOP_ERR_IND) { if (chip->chip_id == RTL8852C) { - seq_printf(m, "R_AX_RX_ERR_FLAG [%d]=0x%08x\n", band, - rtw89_read32(rtwdev, R_AX_RX_ERR_FLAG + offset)); - seq_printf(m, "R_AX_RX_ERR_FLAG_IMR [%d]=0x%08x\n", band, - rtw89_read32(rtwdev, R_AX_RX_ERR_FLAG_IMR + offset)); + p += scnprintf(p, end - p, + "R_AX_RX_ERR_FLAG [%d]=0x%08x\n", band, + rtw89_read32(rtwdev, R_AX_RX_ERR_FLAG + offset)); + p += scnprintf(p, end - p, + "R_AX_RX_ERR_FLAG_IMR [%d]=0x%08x\n", + band, + rtw89_read32(rtwdev, R_AX_RX_ERR_FLAG_IMR + offset)); } else { - seq_printf(m, "R_AX_DLE_CTRL [%d]=0x%08x\n", band, - rtw89_read32(rtwdev, R_AX_DLE_CTRL + offset)); + p += scnprintf(p, end - p, + "R_AX_DLE_CTRL [%d]=0x%08x\n", band, + rtw89_read32(rtwdev, R_AX_DLE_CTRL + offset)); } } if (cmac_err & B_AX_DMA_TOP_ERR_IND || cmac_err & B_AX_WMAC_RX_ERR_IND) { if (chip->chip_id == RTL8852C) { - seq_printf(m, "R_AX_PHYINFO_ERR_ISR [%d]=0x%08x\n", band, - rtw89_read32(rtwdev, R_AX_PHYINFO_ERR_ISR + offset)); - seq_printf(m, "R_AX_PHYINFO_ERR_IMR [%d]=0x%08x\n", band, - rtw89_read32(rtwdev, R_AX_PHYINFO_ERR_IMR + offset)); + p += scnprintf(p, end - p, + "R_AX_PHYINFO_ERR_ISR [%d]=0x%08x\n", + band, + rtw89_read32(rtwdev, R_AX_PHYINFO_ERR_ISR + offset)); + p += scnprintf(p, end - p, + "R_AX_PHYINFO_ERR_IMR [%d]=0x%08x\n", + band, + rtw89_read32(rtwdev, R_AX_PHYINFO_ERR_IMR + offset)); } else { - seq_printf(m, "R_AX_PHYINFO_ERR_IMR [%d]=0x%08x\n", band, - rtw89_read32(rtwdev, R_AX_PHYINFO_ERR_IMR + offset)); + p += scnprintf(p, end - p, + "R_AX_PHYINFO_ERR_IMR [%d]=0x%08x\n", + band, + rtw89_read32(rtwdev, R_AX_PHYINFO_ERR_IMR + offset)); } } if (cmac_err & B_AX_TXPWR_CTRL_ERR_IND) { - seq_printf(m, "R_AX_TXPWR_IMR [%d]=0x%08x\n", band, - rtw89_read32(rtwdev, R_AX_TXPWR_IMR + offset)); - seq_printf(m, "R_AX_TXPWR_ISR [%d]=0x%08x\n", band, - rtw89_read32(rtwdev, R_AX_TXPWR_ISR + offset)); + p += scnprintf(p, end - p, "R_AX_TXPWR_IMR [%d]=0x%08x\n", + band, + rtw89_read32(rtwdev, R_AX_TXPWR_IMR + offset)); + p += scnprintf(p, end - p, "R_AX_TXPWR_ISR [%d]=0x%08x\n", + band, + rtw89_read32(rtwdev, R_AX_TXPWR_ISR + offset)); } if (cmac_err & B_AX_WMAC_TX_ERR_IND) { if (chip->chip_id == RTL8852C) { - seq_printf(m, "R_AX_TRXPTCL_ERROR_INDICA [%d]=0x%08x\n", band, - rtw89_read32(rtwdev, R_AX_TRXPTCL_ERROR_INDICA + offset)); - seq_printf(m, "R_AX_TRXPTCL_ERROR_INDICA_MASK [%d]=0x%08x\n", band, - rtw89_read32(rtwdev, R_AX_TRXPTCL_ERROR_INDICA_MASK + offset)); + p += scnprintf(p, end - p, + "R_AX_TRXPTCL_ERROR_INDICA [%d]=0x%08x\n", + band, + rtw89_read32(rtwdev, + R_AX_TRXPTCL_ERROR_INDICA + offset)); + p += scnprintf(p, end - p, + "R_AX_TRXPTCL_ERROR_INDICA_MASK [%d]=0x%08x\n", + band, + rtw89_read32(rtwdev, + R_AX_TRXPTCL_ERROR_INDICA_MASK + offset)); } else { - seq_printf(m, "R_AX_TMAC_ERR_IMR_ISR [%d]=0x%08x\n", band, - rtw89_read32(rtwdev, R_AX_TMAC_ERR_IMR_ISR + offset)); + p += scnprintf(p, end - p, + "R_AX_TMAC_ERR_IMR_ISR [%d]=0x%08x\n", + band, + rtw89_read32(rtwdev, + R_AX_TMAC_ERR_IMR_ISR + offset)); } - seq_printf(m, "R_AX_DBGSEL_TRXPTCL [%d]=0x%08x\n", band, - rtw89_read32(rtwdev, R_AX_DBGSEL_TRXPTCL + offset)); + p += scnprintf(p, end - p, + "R_AX_DBGSEL_TRXPTCL [%d]=0x%08x\n", band, + rtw89_read32(rtwdev, R_AX_DBGSEL_TRXPTCL + offset)); } - seq_printf(m, "R_AX_CMAC_ERR_IMR [%d]=0x%08x\n", band, - rtw89_read32(rtwdev, R_AX_CMAC_ERR_IMR + offset)); + p += scnprintf(p, end - p, "R_AX_CMAC_ERR_IMR [%d]=0x%08x\n", band, + rtw89_read32(rtwdev, R_AX_CMAC_ERR_IMR + offset)); - return 0; +out: + return p - buf; } static int rtw89_debug_mac_dump_cmac_dbg(struct rtw89_dev *rtwdev, - struct seq_file *m) + char *buf, size_t bufsz) { - rtw89_debug_mac_dump_cmac_err(rtwdev, m, RTW89_MAC_0); + char *p = buf, *end = buf + bufsz; + + p += rtw89_debug_mac_dump_cmac_err(rtwdev, p, end - p, RTW89_MAC_0); if (rtwdev->dbcc_en) - rtw89_debug_mac_dump_cmac_err(rtwdev, m, RTW89_MAC_1); + p += rtw89_debug_mac_dump_cmac_err(rtwdev, p, end - p, RTW89_MAC_1); - return 0; + return p - buf; } static const struct rtw89_mac_dbg_port_info dbg_port_ptcl_c0 = { @@ -2465,11 +2611,12 @@ static const struct rtw89_mac_dbg_port_info dbg_port_pcie_misc2 = { .rd_msk = B_AX_DEBUG_ST_MASK }; -static const struct rtw89_mac_dbg_port_info * -rtw89_debug_mac_dbg_port_sel(struct seq_file *m, - struct rtw89_dev *rtwdev, u32 sel) +static int +rtw89_debug_mac_dbg_port_sel(struct rtw89_dev *rtwdev, char *buf, size_t bufsz, + u32 sel, const struct rtw89_mac_dbg_port_info **ppinfo) { - const struct rtw89_mac_dbg_port_info *info; + const struct rtw89_mac_dbg_port_info *info = NULL; + char *p = buf, *end = buf + bufsz; u32 index; u32 val32; u16 val16; @@ -2481,28 +2628,28 @@ rtw89_debug_mac_dbg_port_sel(struct seq_file *m, val16 = rtw89_read16(rtwdev, R_AX_PTCL_DBG); val16 |= B_AX_PTCL_DBG_EN; rtw89_write16(rtwdev, R_AX_PTCL_DBG, val16); - seq_puts(m, "Enable PTCL C0 dbgport.\n"); + p += scnprintf(p, end - p, "Enable PTCL C0 dbgport.\n"); break; case RTW89_DBG_PORT_SEL_PTCL_C1: info = &dbg_port_ptcl_c1; val16 = rtw89_read16(rtwdev, R_AX_PTCL_DBG_C1); val16 |= B_AX_PTCL_DBG_EN; rtw89_write16(rtwdev, R_AX_PTCL_DBG_C1, val16); - seq_puts(m, "Enable PTCL C1 dbgport.\n"); + p += scnprintf(p, end - p, "Enable PTCL C1 dbgport.\n"); break; case RTW89_DBG_PORT_SEL_SCH_C0: info = &dbg_port_sch_c0; val32 = rtw89_read32(rtwdev, R_AX_SCH_DBG_SEL); val32 |= B_AX_SCH_DBG_EN; rtw89_write32(rtwdev, R_AX_SCH_DBG_SEL, val32); - seq_puts(m, "Enable SCH C0 dbgport.\n"); + p += scnprintf(p, end - p, "Enable SCH C0 dbgport.\n"); break; case RTW89_DBG_PORT_SEL_SCH_C1: info = &dbg_port_sch_c1; val32 = rtw89_read32(rtwdev, R_AX_SCH_DBG_SEL_C1); val32 |= B_AX_SCH_DBG_EN; rtw89_write32(rtwdev, R_AX_SCH_DBG_SEL_C1, val32); - seq_puts(m, "Enable SCH C1 dbgport.\n"); + p += scnprintf(p, end - p, "Enable SCH C1 dbgport.\n"); break; case RTW89_DBG_PORT_SEL_TMAC_C0: info = &dbg_port_tmac_c0; @@ -2519,7 +2666,7 @@ rtw89_debug_mac_dbg_port_sel(struct seq_file *m, val32 = rtw89_read32(rtwdev, R_AX_SYS_STATUS1); val32 = u32_replace_bits(val32, MAC_DBG_SEL, B_AX_SEL_0XC0_MASK); rtw89_write32(rtwdev, R_AX_SYS_STATUS1, val32); - seq_puts(m, "Enable TMAC C0 dbgport.\n"); + p += scnprintf(p, end - p, "Enable TMAC C0 dbgport.\n"); break; case RTW89_DBG_PORT_SEL_TMAC_C1: info = &dbg_port_tmac_c1; @@ -2536,7 +2683,7 @@ rtw89_debug_mac_dbg_port_sel(struct seq_file *m, val32 = rtw89_read32(rtwdev, R_AX_SYS_STATUS1); val32 = u32_replace_bits(val32, MAC_DBG_SEL, B_AX_SEL_0XC0_MASK); rtw89_write32(rtwdev, R_AX_SYS_STATUS1, val32); - seq_puts(m, "Enable TMAC C1 dbgport.\n"); + p += scnprintf(p, end - p, "Enable TMAC C1 dbgport.\n"); break; case RTW89_DBG_PORT_SEL_RMAC_C0: info = &dbg_port_rmac_c0; @@ -2558,7 +2705,7 @@ rtw89_debug_mac_dbg_port_sel(struct seq_file *m, val8 = u8_replace_bits(val8, RMAC_CMAC_DBG_SEL, B_AX_DBGSEL_TRXPTCL_MASK); rtw89_write8(rtwdev, R_AX_DBGSEL_TRXPTCL, val8); - seq_puts(m, "Enable RMAC C0 dbgport.\n"); + p += scnprintf(p, end - p, "Enable RMAC C0 dbgport.\n"); break; case RTW89_DBG_PORT_SEL_RMAC_C1: info = &dbg_port_rmac_c1; @@ -2580,23 +2727,23 @@ rtw89_debug_mac_dbg_port_sel(struct seq_file *m, val8 = u8_replace_bits(val8, RMAC_CMAC_DBG_SEL, B_AX_DBGSEL_TRXPTCL_MASK); rtw89_write8(rtwdev, R_AX_DBGSEL_TRXPTCL_C1, val8); - seq_puts(m, "Enable RMAC C1 dbgport.\n"); + p += scnprintf(p, end - p, "Enable RMAC C1 dbgport.\n"); break; case RTW89_DBG_PORT_SEL_RMACST_C0: info = &dbg_port_rmacst_c0; - seq_puts(m, "Enable RMAC state C0 dbgport.\n"); + p += scnprintf(p, end - p, "Enable RMAC state C0 dbgport.\n"); break; case RTW89_DBG_PORT_SEL_RMACST_C1: info = &dbg_port_rmacst_c1; - seq_puts(m, "Enable RMAC state C1 dbgport.\n"); + p += scnprintf(p, end - p, "Enable RMAC state C1 dbgport.\n"); break; case RTW89_DBG_PORT_SEL_RMAC_PLCP_C0: info = &dbg_port_rmac_plcp_c0; - seq_puts(m, "Enable RMAC PLCP C0 dbgport.\n"); + p += scnprintf(p, end - p, "Enable RMAC PLCP C0 dbgport.\n"); break; case RTW89_DBG_PORT_SEL_RMAC_PLCP_C1: info = &dbg_port_rmac_plcp_c1; - seq_puts(m, "Enable RMAC PLCP C1 dbgport.\n"); + p += scnprintf(p, end - p, "Enable RMAC PLCP C1 dbgport.\n"); break; case RTW89_DBG_PORT_SEL_TRXPTCL_C0: info = &dbg_port_trxptcl_c0; @@ -2608,7 +2755,7 @@ rtw89_debug_mac_dbg_port_sel(struct seq_file *m, val32 = rtw89_read32(rtwdev, R_AX_SYS_STATUS1); val32 = u32_replace_bits(val32, MAC_DBG_SEL, B_AX_SEL_0XC0_MASK); rtw89_write32(rtwdev, R_AX_SYS_STATUS1, val32); - seq_puts(m, "Enable TRXPTCL C0 dbgport.\n"); + p += scnprintf(p, end - p, "Enable TRXPTCL C0 dbgport.\n"); break; case RTW89_DBG_PORT_SEL_TRXPTCL_C1: info = &dbg_port_trxptcl_c1; @@ -2620,131 +2767,137 @@ rtw89_debug_mac_dbg_port_sel(struct seq_file *m, val32 = rtw89_read32(rtwdev, R_AX_SYS_STATUS1); val32 = u32_replace_bits(val32, MAC_DBG_SEL, B_AX_SEL_0XC0_MASK); rtw89_write32(rtwdev, R_AX_SYS_STATUS1, val32); - seq_puts(m, "Enable TRXPTCL C1 dbgport.\n"); + p += scnprintf(p, end - p, "Enable TRXPTCL C1 dbgport.\n"); break; case RTW89_DBG_PORT_SEL_TX_INFOL_C0: info = &dbg_port_tx_infol_c0; val32 = rtw89_read32(rtwdev, R_AX_TCR1); val32 |= B_AX_TCR_FORCE_READ_TXDFIFO; rtw89_write32(rtwdev, R_AX_TCR1, val32); - seq_puts(m, "Enable tx infol dump.\n"); + p += scnprintf(p, end - p, "Enable tx infol dump.\n"); break; case RTW89_DBG_PORT_SEL_TX_INFOH_C0: info = &dbg_port_tx_infoh_c0; val32 = rtw89_read32(rtwdev, R_AX_TCR1); val32 |= B_AX_TCR_FORCE_READ_TXDFIFO; rtw89_write32(rtwdev, R_AX_TCR1, val32); - seq_puts(m, "Enable tx infoh dump.\n"); + p += scnprintf(p, end - p, "Enable tx infoh dump.\n"); break; case RTW89_DBG_PORT_SEL_TX_INFOL_C1: info = &dbg_port_tx_infol_c1; val32 = rtw89_read32(rtwdev, R_AX_TCR1_C1); val32 |= B_AX_TCR_FORCE_READ_TXDFIFO; rtw89_write32(rtwdev, R_AX_TCR1_C1, val32); - seq_puts(m, "Enable tx infol dump.\n"); + p += scnprintf(p, end - p, "Enable tx infol dump.\n"); break; case RTW89_DBG_PORT_SEL_TX_INFOH_C1: info = &dbg_port_tx_infoh_c1; val32 = rtw89_read32(rtwdev, R_AX_TCR1_C1); val32 |= B_AX_TCR_FORCE_READ_TXDFIFO; rtw89_write32(rtwdev, R_AX_TCR1_C1, val32); - seq_puts(m, "Enable tx infoh dump.\n"); + p += scnprintf(p, end - p, "Enable tx infoh dump.\n"); break; case RTW89_DBG_PORT_SEL_TXTF_INFOL_C0: info = &dbg_port_txtf_infol_c0; val32 = rtw89_read32(rtwdev, R_AX_TCR1); val32 |= B_AX_TCR_FORCE_READ_TXDFIFO; rtw89_write32(rtwdev, R_AX_TCR1, val32); - seq_puts(m, "Enable tx tf infol dump.\n"); + p += scnprintf(p, end - p, "Enable tx tf infol dump.\n"); break; case RTW89_DBG_PORT_SEL_TXTF_INFOH_C0: info = &dbg_port_txtf_infoh_c0; val32 = rtw89_read32(rtwdev, R_AX_TCR1); val32 |= B_AX_TCR_FORCE_READ_TXDFIFO; rtw89_write32(rtwdev, R_AX_TCR1, val32); - seq_puts(m, "Enable tx tf infoh dump.\n"); + p += scnprintf(p, end - p, "Enable tx tf infoh dump.\n"); break; case RTW89_DBG_PORT_SEL_TXTF_INFOL_C1: info = &dbg_port_txtf_infol_c1; val32 = rtw89_read32(rtwdev, R_AX_TCR1_C1); val32 |= B_AX_TCR_FORCE_READ_TXDFIFO; rtw89_write32(rtwdev, R_AX_TCR1_C1, val32); - seq_puts(m, "Enable tx tf infol dump.\n"); + p += scnprintf(p, end - p, "Enable tx tf infol dump.\n"); break; case RTW89_DBG_PORT_SEL_TXTF_INFOH_C1: info = &dbg_port_txtf_infoh_c1; val32 = rtw89_read32(rtwdev, R_AX_TCR1_C1); val32 |= B_AX_TCR_FORCE_READ_TXDFIFO; rtw89_write32(rtwdev, R_AX_TCR1_C1, val32); - seq_puts(m, "Enable tx tf infoh dump.\n"); + p += scnprintf(p, end - p, "Enable tx tf infoh dump.\n"); break; case RTW89_DBG_PORT_SEL_WDE_BUFMGN_FREEPG: info = &dbg_port_wde_bufmgn_freepg; - seq_puts(m, "Enable wde bufmgn freepg dump.\n"); + p += scnprintf(p, end - p, "Enable wde bufmgn freepg dump.\n"); break; case RTW89_DBG_PORT_SEL_WDE_BUFMGN_QUOTA: info = &dbg_port_wde_bufmgn_quota; - seq_puts(m, "Enable wde bufmgn quota dump.\n"); + p += scnprintf(p, end - p, "Enable wde bufmgn quota dump.\n"); break; case RTW89_DBG_PORT_SEL_WDE_BUFMGN_PAGELLT: info = &dbg_port_wde_bufmgn_pagellt; - seq_puts(m, "Enable wde bufmgn pagellt dump.\n"); + p += scnprintf(p, end - p, + "Enable wde bufmgn pagellt dump.\n"); break; case RTW89_DBG_PORT_SEL_WDE_BUFMGN_PKTINFO: info = &dbg_port_wde_bufmgn_pktinfo; - seq_puts(m, "Enable wde bufmgn pktinfo dump.\n"); + p += scnprintf(p, end - p, + "Enable wde bufmgn pktinfo dump.\n"); break; case RTW89_DBG_PORT_SEL_WDE_QUEMGN_PREPKT: info = &dbg_port_wde_quemgn_prepkt; - seq_puts(m, "Enable wde quemgn prepkt dump.\n"); + p += scnprintf(p, end - p, "Enable wde quemgn prepkt dump.\n"); break; case RTW89_DBG_PORT_SEL_WDE_QUEMGN_NXTPKT: info = &dbg_port_wde_quemgn_nxtpkt; - seq_puts(m, "Enable wde quemgn nxtpkt dump.\n"); + p += scnprintf(p, end - p, "Enable wde quemgn nxtpkt dump.\n"); break; case RTW89_DBG_PORT_SEL_WDE_QUEMGN_QLNKTBL: info = &dbg_port_wde_quemgn_qlnktbl; - seq_puts(m, "Enable wde quemgn qlnktbl dump.\n"); + p += scnprintf(p, end - p, + "Enable wde quemgn qlnktbl dump.\n"); break; case RTW89_DBG_PORT_SEL_WDE_QUEMGN_QEMPTY: info = &dbg_port_wde_quemgn_qempty; - seq_puts(m, "Enable wde quemgn qempty dump.\n"); + p += scnprintf(p, end - p, "Enable wde quemgn qempty dump.\n"); break; case RTW89_DBG_PORT_SEL_PLE_BUFMGN_FREEPG: info = &dbg_port_ple_bufmgn_freepg; - seq_puts(m, "Enable ple bufmgn freepg dump.\n"); + p += scnprintf(p, end - p, "Enable ple bufmgn freepg dump.\n"); break; case RTW89_DBG_PORT_SEL_PLE_BUFMGN_QUOTA: info = &dbg_port_ple_bufmgn_quota; - seq_puts(m, "Enable ple bufmgn quota dump.\n"); + p += scnprintf(p, end - p, "Enable ple bufmgn quota dump.\n"); break; case RTW89_DBG_PORT_SEL_PLE_BUFMGN_PAGELLT: info = &dbg_port_ple_bufmgn_pagellt; - seq_puts(m, "Enable ple bufmgn pagellt dump.\n"); + p += scnprintf(p, end - p, + "Enable ple bufmgn pagellt dump.\n"); break; case RTW89_DBG_PORT_SEL_PLE_BUFMGN_PKTINFO: info = &dbg_port_ple_bufmgn_pktinfo; - seq_puts(m, "Enable ple bufmgn pktinfo dump.\n"); + p += scnprintf(p, end - p, + "Enable ple bufmgn pktinfo dump.\n"); break; case RTW89_DBG_PORT_SEL_PLE_QUEMGN_PREPKT: info = &dbg_port_ple_quemgn_prepkt; - seq_puts(m, "Enable ple quemgn prepkt dump.\n"); + p += scnprintf(p, end - p, "Enable ple quemgn prepkt dump.\n"); break; case RTW89_DBG_PORT_SEL_PLE_QUEMGN_NXTPKT: info = &dbg_port_ple_quemgn_nxtpkt; - seq_puts(m, "Enable ple quemgn nxtpkt dump.\n"); + p += scnprintf(p, end - p, "Enable ple quemgn nxtpkt dump.\n"); break; case RTW89_DBG_PORT_SEL_PLE_QUEMGN_QLNKTBL: info = &dbg_port_ple_quemgn_qlnktbl; - seq_puts(m, "Enable ple quemgn qlnktbl dump.\n"); + p += scnprintf(p, end - p, + "Enable ple quemgn qlnktbl dump.\n"); break; case RTW89_DBG_PORT_SEL_PLE_QUEMGN_QEMPTY: info = &dbg_port_ple_quemgn_qempty; - seq_puts(m, "Enable ple quemgn qempty dump.\n"); + p += scnprintf(p, end - p, "Enable ple quemgn qempty dump.\n"); break; case RTW89_DBG_PORT_SEL_PKTINFO: info = &dbg_port_pktinfo; - seq_puts(m, "Enable pktinfo dump.\n"); + p += scnprintf(p, end - p, "Enable pktinfo dump.\n"); break; case RTW89_DBG_PORT_SEL_DSPT_HDT_TX0: rtw89_write32_mask(rtwdev, R_AX_DBG_CTRL, @@ -2763,7 +2916,8 @@ rtw89_debug_mac_dbg_port_sel(struct seq_file *m, B_AX_DISPATCHER_INTN_SEL_MASK, 0); rtw89_write16_mask(rtwdev, info->sel_addr, B_AX_DISPATCHER_CH_SEL_MASK, index); - seq_printf(m, "Enable Dispatcher hdt tx%x dump.\n", index); + p += scnprintf(p, end - p, + "Enable Dispatcher hdt tx%x dump.\n", index); break; case RTW89_DBG_PORT_SEL_DSPT_HDT_TX6: info = &dbg_port_dspt_hdt_tx6; @@ -2771,7 +2925,8 @@ rtw89_debug_mac_dbg_port_sel(struct seq_file *m, B_AX_DISPATCHER_INTN_SEL_MASK, 0); rtw89_write16_mask(rtwdev, info->sel_addr, B_AX_DISPATCHER_CH_SEL_MASK, 6); - seq_puts(m, "Enable Dispatcher hdt tx6 dump.\n"); + p += scnprintf(p, end - p, + "Enable Dispatcher hdt tx6 dump.\n"); break; case RTW89_DBG_PORT_SEL_DSPT_HDT_TX7: info = &dbg_port_dspt_hdt_tx7; @@ -2779,7 +2934,8 @@ rtw89_debug_mac_dbg_port_sel(struct seq_file *m, B_AX_DISPATCHER_INTN_SEL_MASK, 0); rtw89_write16_mask(rtwdev, info->sel_addr, B_AX_DISPATCHER_CH_SEL_MASK, 7); - seq_puts(m, "Enable Dispatcher hdt tx7 dump.\n"); + p += scnprintf(p, end - p, + "Enable Dispatcher hdt tx7 dump.\n"); break; case RTW89_DBG_PORT_SEL_DSPT_HDT_TX8: info = &dbg_port_dspt_hdt_tx8; @@ -2787,7 +2943,8 @@ rtw89_debug_mac_dbg_port_sel(struct seq_file *m, B_AX_DISPATCHER_INTN_SEL_MASK, 0); rtw89_write16_mask(rtwdev, info->sel_addr, B_AX_DISPATCHER_CH_SEL_MASK, 8); - seq_puts(m, "Enable Dispatcher hdt tx8 dump.\n"); + p += scnprintf(p, end - p, + "Enable Dispatcher hdt tx8 dump.\n"); break; case RTW89_DBG_PORT_SEL_DSPT_HDT_TX9: case RTW89_DBG_PORT_SEL_DSPT_HDT_TXA: @@ -2799,7 +2956,8 @@ rtw89_debug_mac_dbg_port_sel(struct seq_file *m, B_AX_DISPATCHER_INTN_SEL_MASK, 0); rtw89_write16_mask(rtwdev, info->sel_addr, B_AX_DISPATCHER_CH_SEL_MASK, index); - seq_printf(m, "Enable Dispatcher hdt tx%x dump.\n", index); + p += scnprintf(p, end - p, + "Enable Dispatcher hdt tx%x dump.\n", index); break; case RTW89_DBG_PORT_SEL_DSPT_HDT_TXD: info = &dbg_port_dspt_hdt_txD; @@ -2807,7 +2965,8 @@ rtw89_debug_mac_dbg_port_sel(struct seq_file *m, B_AX_DISPATCHER_INTN_SEL_MASK, 0); rtw89_write16_mask(rtwdev, info->sel_addr, B_AX_DISPATCHER_CH_SEL_MASK, 0xD); - seq_puts(m, "Enable Dispatcher hdt txD dump.\n"); + p += scnprintf(p, end - p, + "Enable Dispatcher hdt txD dump.\n"); break; case RTW89_DBG_PORT_SEL_DSPT_CDT_TX0: info = &dbg_port_dspt_cdt_tx0; @@ -2815,7 +2974,8 @@ rtw89_debug_mac_dbg_port_sel(struct seq_file *m, B_AX_DISPATCHER_INTN_SEL_MASK, 1); rtw89_write16_mask(rtwdev, info->sel_addr, B_AX_DISPATCHER_CH_SEL_MASK, 0); - seq_puts(m, "Enable Dispatcher cdt tx0 dump.\n"); + p += scnprintf(p, end - p, + "Enable Dispatcher cdt tx0 dump.\n"); break; case RTW89_DBG_PORT_SEL_DSPT_CDT_TX1: info = &dbg_port_dspt_cdt_tx1; @@ -2823,7 +2983,8 @@ rtw89_debug_mac_dbg_port_sel(struct seq_file *m, B_AX_DISPATCHER_INTN_SEL_MASK, 1); rtw89_write16_mask(rtwdev, info->sel_addr, B_AX_DISPATCHER_CH_SEL_MASK, 1); - seq_puts(m, "Enable Dispatcher cdt tx1 dump.\n"); + p += scnprintf(p, end - p, + "Enable Dispatcher cdt tx1 dump.\n"); break; case RTW89_DBG_PORT_SEL_DSPT_CDT_TX3: info = &dbg_port_dspt_cdt_tx3; @@ -2831,7 +2992,8 @@ rtw89_debug_mac_dbg_port_sel(struct seq_file *m, B_AX_DISPATCHER_INTN_SEL_MASK, 1); rtw89_write16_mask(rtwdev, info->sel_addr, B_AX_DISPATCHER_CH_SEL_MASK, 3); - seq_puts(m, "Enable Dispatcher cdt tx3 dump.\n"); + p += scnprintf(p, end - p, + "Enable Dispatcher cdt tx3 dump.\n"); break; case RTW89_DBG_PORT_SEL_DSPT_CDT_TX4: info = &dbg_port_dspt_cdt_tx4; @@ -2839,7 +3001,8 @@ rtw89_debug_mac_dbg_port_sel(struct seq_file *m, B_AX_DISPATCHER_INTN_SEL_MASK, 1); rtw89_write16_mask(rtwdev, info->sel_addr, B_AX_DISPATCHER_CH_SEL_MASK, 4); - seq_puts(m, "Enable Dispatcher cdt tx4 dump.\n"); + p += scnprintf(p, end - p, + "Enable Dispatcher cdt tx4 dump.\n"); break; case RTW89_DBG_PORT_SEL_DSPT_CDT_TX5: case RTW89_DBG_PORT_SEL_DSPT_CDT_TX6: @@ -2851,7 +3014,8 @@ rtw89_debug_mac_dbg_port_sel(struct seq_file *m, B_AX_DISPATCHER_INTN_SEL_MASK, 1); rtw89_write16_mask(rtwdev, info->sel_addr, B_AX_DISPATCHER_CH_SEL_MASK, index); - seq_printf(m, "Enable Dispatcher cdt tx%x dump.\n", index); + p += scnprintf(p, end - p, + "Enable Dispatcher cdt tx%x dump.\n", index); break; case RTW89_DBG_PORT_SEL_DSPT_CDT_TX9: info = &dbg_port_dspt_cdt_tx9; @@ -2859,7 +3023,8 @@ rtw89_debug_mac_dbg_port_sel(struct seq_file *m, B_AX_DISPATCHER_INTN_SEL_MASK, 1); rtw89_write16_mask(rtwdev, info->sel_addr, B_AX_DISPATCHER_CH_SEL_MASK, 9); - seq_puts(m, "Enable Dispatcher cdt tx9 dump.\n"); + p += scnprintf(p, end - p, + "Enable Dispatcher cdt tx9 dump.\n"); break; case RTW89_DBG_PORT_SEL_DSPT_CDT_TXA: case RTW89_DBG_PORT_SEL_DSPT_CDT_TXB: @@ -2870,7 +3035,8 @@ rtw89_debug_mac_dbg_port_sel(struct seq_file *m, B_AX_DISPATCHER_INTN_SEL_MASK, 1); rtw89_write16_mask(rtwdev, info->sel_addr, B_AX_DISPATCHER_CH_SEL_MASK, index); - seq_printf(m, "Enable Dispatcher cdt tx%x dump.\n", index); + p += scnprintf(p, end - p, + "Enable Dispatcher cdt tx%x dump.\n", index); break; case RTW89_DBG_PORT_SEL_DSPT_HDT_RX0: info = &dbg_port_dspt_hdt_rx0; @@ -2878,7 +3044,8 @@ rtw89_debug_mac_dbg_port_sel(struct seq_file *m, B_AX_DISPATCHER_INTN_SEL_MASK, 2); rtw89_write16_mask(rtwdev, info->sel_addr, B_AX_DISPATCHER_CH_SEL_MASK, 0); - seq_puts(m, "Enable Dispatcher hdt rx0 dump.\n"); + p += scnprintf(p, end - p, + "Enable Dispatcher hdt rx0 dump.\n"); break; case RTW89_DBG_PORT_SEL_DSPT_HDT_RX1: case RTW89_DBG_PORT_SEL_DSPT_HDT_RX2: @@ -2888,7 +3055,8 @@ rtw89_debug_mac_dbg_port_sel(struct seq_file *m, B_AX_DISPATCHER_INTN_SEL_MASK, 2); rtw89_write16_mask(rtwdev, info->sel_addr, B_AX_DISPATCHER_CH_SEL_MASK, index); - seq_printf(m, "Enable Dispatcher hdt rx%x dump.\n", index); + p += scnprintf(p, end - p, + "Enable Dispatcher hdt rx%x dump.\n", index); break; case RTW89_DBG_PORT_SEL_DSPT_HDT_RX3: info = &dbg_port_dspt_hdt_rx3; @@ -2896,7 +3064,8 @@ rtw89_debug_mac_dbg_port_sel(struct seq_file *m, B_AX_DISPATCHER_INTN_SEL_MASK, 2); rtw89_write16_mask(rtwdev, info->sel_addr, B_AX_DISPATCHER_CH_SEL_MASK, 3); - seq_puts(m, "Enable Dispatcher hdt rx3 dump.\n"); + p += scnprintf(p, end - p, + "Enable Dispatcher hdt rx3 dump.\n"); break; case RTW89_DBG_PORT_SEL_DSPT_HDT_RX4: info = &dbg_port_dspt_hdt_rx4; @@ -2904,7 +3073,8 @@ rtw89_debug_mac_dbg_port_sel(struct seq_file *m, B_AX_DISPATCHER_INTN_SEL_MASK, 2); rtw89_write16_mask(rtwdev, info->sel_addr, B_AX_DISPATCHER_CH_SEL_MASK, 4); - seq_puts(m, "Enable Dispatcher hdt rx4 dump.\n"); + p += scnprintf(p, end - p, + "Enable Dispatcher hdt rx4 dump.\n"); break; case RTW89_DBG_PORT_SEL_DSPT_HDT_RX5: info = &dbg_port_dspt_hdt_rx5; @@ -2912,7 +3082,8 @@ rtw89_debug_mac_dbg_port_sel(struct seq_file *m, B_AX_DISPATCHER_INTN_SEL_MASK, 2); rtw89_write16_mask(rtwdev, info->sel_addr, B_AX_DISPATCHER_CH_SEL_MASK, 5); - seq_puts(m, "Enable Dispatcher hdt rx5 dump.\n"); + p += scnprintf(p, end - p, + "Enable Dispatcher hdt rx5 dump.\n"); break; case RTW89_DBG_PORT_SEL_DSPT_CDT_RX_P0_0: info = &dbg_port_dspt_cdt_rx_p0_0; @@ -2920,7 +3091,8 @@ rtw89_debug_mac_dbg_port_sel(struct seq_file *m, B_AX_DISPATCHER_INTN_SEL_MASK, 3); rtw89_write16_mask(rtwdev, info->sel_addr, B_AX_DISPATCHER_CH_SEL_MASK, 0); - seq_puts(m, "Enable Dispatcher cdt rx part0 0 dump.\n"); + p += scnprintf(p, end - p, + "Enable Dispatcher cdt rx part0 0 dump.\n"); break; case RTW89_DBG_PORT_SEL_DSPT_CDT_RX_P0: case RTW89_DBG_PORT_SEL_DSPT_CDT_RX_P0_1: @@ -2929,7 +3101,8 @@ rtw89_debug_mac_dbg_port_sel(struct seq_file *m, B_AX_DISPATCHER_INTN_SEL_MASK, 3); rtw89_write16_mask(rtwdev, info->sel_addr, B_AX_DISPATCHER_CH_SEL_MASK, 1); - seq_puts(m, "Enable Dispatcher cdt rx part0 1 dump.\n"); + p += scnprintf(p, end - p, + "Enable Dispatcher cdt rx part0 1 dump.\n"); break; case RTW89_DBG_PORT_SEL_DSPT_CDT_RX_P0_2: info = &dbg_port_dspt_cdt_rx_p0_2; @@ -2937,43 +3110,50 @@ rtw89_debug_mac_dbg_port_sel(struct seq_file *m, B_AX_DISPATCHER_INTN_SEL_MASK, 3); rtw89_write16_mask(rtwdev, info->sel_addr, B_AX_DISPATCHER_CH_SEL_MASK, 2); - seq_puts(m, "Enable Dispatcher cdt rx part0 2 dump.\n"); + p += scnprintf(p, end - p, + "Enable Dispatcher cdt rx part0 2 dump.\n"); break; case RTW89_DBG_PORT_SEL_DSPT_CDT_RX_P1: info = &dbg_port_dspt_cdt_rx_p1; rtw89_write8_mask(rtwdev, info->sel_addr, B_AX_DISPATCHER_INTN_SEL_MASK, 3); - seq_puts(m, "Enable Dispatcher cdt rx part1 dump.\n"); + p += scnprintf(p, end - p, + "Enable Dispatcher cdt rx part1 dump.\n"); break; case RTW89_DBG_PORT_SEL_DSPT_STF_CTRL: info = &dbg_port_dspt_stf_ctrl; rtw89_write8_mask(rtwdev, info->sel_addr, B_AX_DISPATCHER_INTN_SEL_MASK, 4); - seq_puts(m, "Enable Dispatcher stf control dump.\n"); + p += scnprintf(p, end - p, + "Enable Dispatcher stf control dump.\n"); break; case RTW89_DBG_PORT_SEL_DSPT_ADDR_CTRL: info = &dbg_port_dspt_addr_ctrl; rtw89_write8_mask(rtwdev, info->sel_addr, B_AX_DISPATCHER_INTN_SEL_MASK, 5); - seq_puts(m, "Enable Dispatcher addr control dump.\n"); + p += scnprintf(p, end - p, + "Enable Dispatcher addr control dump.\n"); break; case RTW89_DBG_PORT_SEL_DSPT_WDE_INTF: info = &dbg_port_dspt_wde_intf; rtw89_write8_mask(rtwdev, info->sel_addr, B_AX_DISPATCHER_INTN_SEL_MASK, 6); - seq_puts(m, "Enable Dispatcher wde interface dump.\n"); + p += scnprintf(p, end - p, + "Enable Dispatcher wde interface dump.\n"); break; case RTW89_DBG_PORT_SEL_DSPT_PLE_INTF: info = &dbg_port_dspt_ple_intf; rtw89_write8_mask(rtwdev, info->sel_addr, B_AX_DISPATCHER_INTN_SEL_MASK, 7); - seq_puts(m, "Enable Dispatcher ple interface dump.\n"); + p += scnprintf(p, end - p, + "Enable Dispatcher ple interface dump.\n"); break; case RTW89_DBG_PORT_SEL_DSPT_FLOW_CTRL: info = &dbg_port_dspt_flow_ctrl; rtw89_write8_mask(rtwdev, info->sel_addr, B_AX_DISPATCHER_INTN_SEL_MASK, 8); - seq_puts(m, "Enable Dispatcher flow control dump.\n"); + p += scnprintf(p, end - p, + "Enable Dispatcher flow control dump.\n"); break; case RTW89_DBG_PORT_SEL_PCIE_TXDMA: info = &dbg_port_pcie_txdma; @@ -2981,7 +3161,7 @@ rtw89_debug_mac_dbg_port_sel(struct seq_file *m, val32 = u32_replace_bits(val32, PCIE_TXDMA_DBG_SEL, B_AX_DBG_SEL0); val32 = u32_replace_bits(val32, PCIE_TXDMA_DBG_SEL, B_AX_DBG_SEL1); rtw89_write32(rtwdev, R_AX_DBG_CTRL, val32); - seq_puts(m, "Enable pcie txdma dump.\n"); + p += scnprintf(p, end - p, "Enable pcie txdma dump.\n"); break; case RTW89_DBG_PORT_SEL_PCIE_RXDMA: info = &dbg_port_pcie_rxdma; @@ -2989,7 +3169,7 @@ rtw89_debug_mac_dbg_port_sel(struct seq_file *m, val32 = u32_replace_bits(val32, PCIE_RXDMA_DBG_SEL, B_AX_DBG_SEL0); val32 = u32_replace_bits(val32, PCIE_RXDMA_DBG_SEL, B_AX_DBG_SEL1); rtw89_write32(rtwdev, R_AX_DBG_CTRL, val32); - seq_puts(m, "Enable pcie rxdma dump.\n"); + p += scnprintf(p, end - p, "Enable pcie rxdma dump.\n"); break; case RTW89_DBG_PORT_SEL_PCIE_CVT: info = &dbg_port_pcie_cvt; @@ -2997,7 +3177,7 @@ rtw89_debug_mac_dbg_port_sel(struct seq_file *m, val32 = u32_replace_bits(val32, PCIE_CVT_DBG_SEL, B_AX_DBG_SEL0); val32 = u32_replace_bits(val32, PCIE_CVT_DBG_SEL, B_AX_DBG_SEL1); rtw89_write32(rtwdev, R_AX_DBG_CTRL, val32); - seq_puts(m, "Enable pcie cvt dump.\n"); + p += scnprintf(p, end - p, "Enable pcie cvt dump.\n"); break; case RTW89_DBG_PORT_SEL_PCIE_CXPL: info = &dbg_port_pcie_cxpl; @@ -3005,7 +3185,7 @@ rtw89_debug_mac_dbg_port_sel(struct seq_file *m, val32 = u32_replace_bits(val32, PCIE_CXPL_DBG_SEL, B_AX_DBG_SEL0); val32 = u32_replace_bits(val32, PCIE_CXPL_DBG_SEL, B_AX_DBG_SEL1); rtw89_write32(rtwdev, R_AX_DBG_CTRL, val32); - seq_puts(m, "Enable pcie cxpl dump.\n"); + p += scnprintf(p, end - p, "Enable pcie cxpl dump.\n"); break; case RTW89_DBG_PORT_SEL_PCIE_IO: info = &dbg_port_pcie_io; @@ -3013,7 +3193,7 @@ rtw89_debug_mac_dbg_port_sel(struct seq_file *m, val32 = u32_replace_bits(val32, PCIE_IO_DBG_SEL, B_AX_DBG_SEL0); val32 = u32_replace_bits(val32, PCIE_IO_DBG_SEL, B_AX_DBG_SEL1); rtw89_write32(rtwdev, R_AX_DBG_CTRL, val32); - seq_puts(m, "Enable pcie io dump.\n"); + p += scnprintf(p, end - p, "Enable pcie io dump.\n"); break; case RTW89_DBG_PORT_SEL_PCIE_MISC: info = &dbg_port_pcie_misc; @@ -3021,7 +3201,7 @@ rtw89_debug_mac_dbg_port_sel(struct seq_file *m, val32 = u32_replace_bits(val32, PCIE_MISC_DBG_SEL, B_AX_DBG_SEL0); val32 = u32_replace_bits(val32, PCIE_MISC_DBG_SEL, B_AX_DBG_SEL1); rtw89_write32(rtwdev, R_AX_DBG_CTRL, val32); - seq_puts(m, "Enable pcie misc dump.\n"); + p += scnprintf(p, end - p, "Enable pcie misc dump.\n"); break; case RTW89_DBG_PORT_SEL_PCIE_MISC2: info = &dbg_port_pcie_misc2; @@ -3029,14 +3209,16 @@ rtw89_debug_mac_dbg_port_sel(struct seq_file *m, val16 = u16_replace_bits(val16, PCIE_MISC2_DBG_SEL, B_AX_PCIE_DBG_SEL_MASK); rtw89_write16(rtwdev, R_AX_PCIE_DBG_CTRL, val16); - seq_puts(m, "Enable pcie misc2 dump.\n"); + p += scnprintf(p, end - p, "Enable pcie misc2 dump.\n"); break; default: - seq_puts(m, "Dbg port select err\n"); - return NULL; + p += scnprintf(p, end - p, "Dbg port select err\n"); + break; } - return info; + *ppinfo = info; + + return p - buf; } static bool is_dbg_port_valid(struct rtw89_dev *rtwdev, u32 sel) @@ -3070,23 +3252,25 @@ static bool is_dbg_port_valid(struct rtw89_dev *rtwdev, u32 sel) } static int rtw89_debug_mac_dbg_port_dump(struct rtw89_dev *rtwdev, - struct seq_file *m, u32 sel) + char *buf, size_t bufsz, u32 sel) { - const struct rtw89_mac_dbg_port_info *info; - u8 val8; - u16 val16; + const struct rtw89_mac_dbg_port_info *info = NULL; + char *p = buf, *end = buf + bufsz; u32 val32; + u16 val16; + u8 val8; u32 i; - info = rtw89_debug_mac_dbg_port_sel(m, rtwdev, sel); + p += rtw89_debug_mac_dbg_port_sel(rtwdev, p, end - p, sel, &info); + if (!info) { rtw89_err(rtwdev, "failed to select debug port %d\n", sel); - return -EINVAL; + goto out; } #define case_DBG_SEL(__sel) \ case RTW89_DBG_PORT_SEL_##__sel: \ - seq_puts(m, "Dump debug port " #__sel ":\n"); \ + p += scnprintf(p, end - p, "Dump debug port " #__sel ":\n"); \ break switch (sel) { @@ -3182,8 +3366,8 @@ static int rtw89_debug_mac_dbg_port_dump(struct rtw89_dev *rtwdev, #undef case_DBG_SEL - seq_printf(m, "Sel addr = 0x%X\n", info->sel_addr); - seq_printf(m, "Read addr = 0x%X\n", info->rd_addr); + p += scnprintf(p, end - p, "Sel addr = 0x%X\n", info->sel_addr); + p += scnprintf(p, end - p, "Read addr = 0x%X\n", info->rd_addr); for (i = info->srt; i <= info->end; i++) { switch (info->sel_byte) { @@ -3191,17 +3375,17 @@ static int rtw89_debug_mac_dbg_port_dump(struct rtw89_dev *rtwdev, default: rtw89_write8_mask(rtwdev, info->sel_addr, info->sel_msk, i); - seq_printf(m, "0x%02X: ", i); + p += scnprintf(p, end - p, "0x%02X: ", i); break; case 2: rtw89_write16_mask(rtwdev, info->sel_addr, info->sel_msk, i); - seq_printf(m, "0x%04X: ", i); + p += scnprintf(p, end - p, "0x%04X: ", i); break; case 4: rtw89_write32_mask(rtwdev, info->sel_addr, info->sel_msk, i); - seq_printf(m, "0x%04X: ", i); + p += scnprintf(p, end - p, "0x%04X: ", i); break; } @@ -3212,77 +3396,75 @@ static int rtw89_debug_mac_dbg_port_dump(struct rtw89_dev *rtwdev, default: val8 = rtw89_read8_mask(rtwdev, info->rd_addr, info->rd_msk); - seq_printf(m, "0x%02X\n", val8); + p += scnprintf(p, end - p, "0x%02X\n", val8); break; case 2: val16 = rtw89_read16_mask(rtwdev, info->rd_addr, info->rd_msk); - seq_printf(m, "0x%04X\n", val16); + p += scnprintf(p, end - p, "0x%04X\n", val16); break; case 4: val32 = rtw89_read32_mask(rtwdev, info->rd_addr, info->rd_msk); - seq_printf(m, "0x%08X\n", val32); + p += scnprintf(p, end - p, "0x%08X\n", val32); break; } } - return 0; +out: + return p - buf; } static int rtw89_debug_mac_dump_dbg_port(struct rtw89_dev *rtwdev, - struct seq_file *m) + char *buf, size_t bufsz) { + char *p = buf, *end = buf + bufsz; + ssize_t n; u32 sel; - int ret = 0; for (sel = RTW89_DBG_PORT_SEL_PTCL_C0; sel < RTW89_DBG_PORT_SEL_LAST; sel++) { if (!is_dbg_port_valid(rtwdev, sel)) continue; - ret = rtw89_debug_mac_dbg_port_dump(rtwdev, m, sel); - if (ret) { + n = rtw89_debug_mac_dbg_port_dump(rtwdev, p, end - p, sel); + if (n < 0) { rtw89_err(rtwdev, "failed to dump debug port %d\n", sel); break; } + p += n; } - return ret; + return p - buf; } -static int -rtw89_debug_priv_mac_dbg_port_dump_get(struct seq_file *m, void *v) +static ssize_t +rtw89_debug_priv_mac_dbg_port_dump_get(struct rtw89_dev *rtwdev, + struct rtw89_debugfs_priv *debugfs_priv, + char *buf, size_t bufsz) { - struct rtw89_debugfs_priv *debugfs_priv = m->private; - struct rtw89_dev *rtwdev = debugfs_priv->rtwdev; + char *p = buf, *end = buf + bufsz; if (debugfs_priv->dbgpkg_en.ss_dbg) - rtw89_debug_mac_dump_ss_dbg(rtwdev, m); + p += rtw89_debug_mac_dump_ss_dbg(rtwdev, p, end - p); if (debugfs_priv->dbgpkg_en.dle_dbg) - rtw89_debug_mac_dump_dle_dbg(rtwdev, m); + p += rtw89_debug_mac_dump_dle_dbg(rtwdev, p, end - p); if (debugfs_priv->dbgpkg_en.dmac_dbg) - rtw89_debug_mac_dump_dmac_dbg(rtwdev, m); + p += rtw89_debug_mac_dump_dmac_dbg(rtwdev, p, end - p); if (debugfs_priv->dbgpkg_en.cmac_dbg) - rtw89_debug_mac_dump_cmac_dbg(rtwdev, m); + p += rtw89_debug_mac_dump_cmac_dbg(rtwdev, p, end - p); if (debugfs_priv->dbgpkg_en.dbg_port) - rtw89_debug_mac_dump_dbg_port(rtwdev, m); + p += rtw89_debug_mac_dump_dbg_port(rtwdev, p, end - p); - return 0; + return p - buf; }; -static u8 *rtw89_hex2bin_user(struct rtw89_dev *rtwdev, - const char __user *user_buf, size_t count) +static u8 *rtw89_hex2bin(struct rtw89_dev *rtwdev, const char *buf, size_t count) { - char *buf; u8 *bin; int num; int err = 0; - buf = memdup_user(user_buf, count); - if (IS_ERR(buf)) - return buf; - num = count / 2; bin = kmalloc(num, GFP_KERNEL); if (!bin) { @@ -3297,22 +3479,18 @@ static u8 *rtw89_hex2bin_user(struct rtw89_dev *rtwdev, } out: - kfree(buf); - return err ? ERR_PTR(err) : bin; } -static ssize_t rtw89_debug_priv_send_h2c_set(struct file *filp, - const char __user *user_buf, - size_t count, loff_t *loff) +static ssize_t rtw89_debug_priv_send_h2c_set(struct rtw89_dev *rtwdev, + struct rtw89_debugfs_priv *debugfs_priv, + const char *buf, size_t count) { - struct rtw89_debugfs_priv *debugfs_priv = filp->private_data; - struct rtw89_dev *rtwdev = debugfs_priv->rtwdev; u8 *h2c; int ret; u16 h2c_len = count / 2; - h2c = rtw89_hex2bin_user(rtwdev, user_buf, count); + h2c = rtw89_hex2bin(rtwdev, buf, count); if (IS_ERR(h2c)) return -EFAULT; @@ -3323,34 +3501,36 @@ static ssize_t rtw89_debug_priv_send_h2c_set(struct file *filp, return ret ? ret : count; } -static int -rtw89_debug_priv_early_h2c_get(struct seq_file *m, void *v) +static ssize_t +rtw89_debug_priv_early_h2c_get(struct rtw89_dev *rtwdev, + struct rtw89_debugfs_priv *debugfs_priv, + char *buf, size_t bufsz) { - struct rtw89_debugfs_priv *debugfs_priv = m->private; - struct rtw89_dev *rtwdev = debugfs_priv->rtwdev; struct rtw89_early_h2c *early_h2c; + char *p = buf, *end = buf + bufsz; int seq = 0; - mutex_lock(&rtwdev->mutex); + lockdep_assert_wiphy(rtwdev->hw->wiphy); + list_for_each_entry(early_h2c, &rtwdev->early_h2c_list, list) - seq_printf(m, "%d: %*ph\n", ++seq, early_h2c->h2c_len, early_h2c->h2c); - mutex_unlock(&rtwdev->mutex); + p += scnprintf(p, end - p, "%d: %*ph\n", ++seq, + early_h2c->h2c_len, early_h2c->h2c); - return 0; + return p - buf; } static ssize_t -rtw89_debug_priv_early_h2c_set(struct file *filp, const char __user *user_buf, - size_t count, loff_t *loff) +rtw89_debug_priv_early_h2c_set(struct rtw89_dev *rtwdev, + struct rtw89_debugfs_priv *debugfs_priv, + const char *buf, size_t count) { - struct seq_file *m = (struct seq_file *)filp->private_data; - struct rtw89_debugfs_priv *debugfs_priv = m->private; - struct rtw89_dev *rtwdev = debugfs_priv->rtwdev; struct rtw89_early_h2c *early_h2c; u8 *h2c; u16 h2c_len = count / 2; - h2c = rtw89_hex2bin_user(rtwdev, user_buf, count); + lockdep_assert_wiphy(rtwdev->hw->wiphy); + + h2c = rtw89_hex2bin(rtwdev, buf, count); if (IS_ERR(h2c)) return -EFAULT; @@ -3369,9 +3549,7 @@ rtw89_debug_priv_early_h2c_set(struct file *filp, const char __user *user_buf, early_h2c->h2c = h2c; early_h2c->h2c_len = h2c_len; - mutex_lock(&rtwdev->mutex); list_add_tail(&early_h2c->list, &rtwdev->early_h2c_list); - mutex_unlock(&rtwdev->mutex); out: return count; @@ -3404,15 +3582,16 @@ static int rtw89_dbg_trigger_ctrl_error(struct rtw89_dev *rtwdev) return 0; } -static int -rtw89_debug_priv_fw_crash_get(struct seq_file *m, void *v) +static ssize_t +rtw89_debug_priv_fw_crash_get(struct rtw89_dev *rtwdev, + struct rtw89_debugfs_priv *debugfs_priv, + char *buf, size_t bufsz) { - struct rtw89_debugfs_priv *debugfs_priv = m->private; - struct rtw89_dev *rtwdev = debugfs_priv->rtwdev; + char *p = buf, *end = buf + bufsz; - seq_printf(m, "%d\n", - test_bit(RTW89_FLAG_CRASH_SIMULATING, rtwdev->flags)); - return 0; + p += scnprintf(p, end - p, "%d\n", + test_bit(RTW89_FLAG_CRASH_SIMULATING, rtwdev->flags)); + return p - buf; } enum rtw89_dbg_crash_simulation_type { @@ -3421,17 +3600,17 @@ enum rtw89_dbg_crash_simulation_type { }; static ssize_t -rtw89_debug_priv_fw_crash_set(struct file *filp, const char __user *user_buf, - size_t count, loff_t *loff) +rtw89_debug_priv_fw_crash_set(struct rtw89_dev *rtwdev, + struct rtw89_debugfs_priv *debugfs_priv, + const char *buf, size_t count) { - struct seq_file *m = (struct seq_file *)filp->private_data; - struct rtw89_debugfs_priv *debugfs_priv = m->private; - struct rtw89_dev *rtwdev = debugfs_priv->rtwdev; int (*sim)(struct rtw89_dev *rtwdev); u8 crash_type; int ret; - ret = kstrtou8_from_user(user_buf, count, 0, &crash_type); + lockdep_assert_wiphy(rtwdev->hw->wiphy); + + ret = kstrtou8(buf, 0, &crash_type); if (ret) return -EINVAL; @@ -3448,10 +3627,8 @@ rtw89_debug_priv_fw_crash_set(struct file *filp, const char __user *user_buf, return -EINVAL; } - mutex_lock(&rtwdev->mutex); set_bit(RTW89_FLAG_CRASH_SIMULATING, rtwdev->flags); ret = sim(rtwdev); - mutex_unlock(&rtwdev->mutex); if (ret) return ret; @@ -3459,27 +3636,22 @@ rtw89_debug_priv_fw_crash_set(struct file *filp, const char __user *user_buf, return count; } -static int rtw89_debug_priv_btc_info_get(struct seq_file *m, void *v) +static ssize_t rtw89_debug_priv_btc_info_get(struct rtw89_dev *rtwdev, + struct rtw89_debugfs_priv *debugfs_priv, + char *buf, size_t bufsz) { - struct rtw89_debugfs_priv *debugfs_priv = m->private; - struct rtw89_dev *rtwdev = debugfs_priv->rtwdev; - - rtw89_btc_dump_info(rtwdev, m); - - return 0; + return rtw89_btc_dump_info(rtwdev, buf, bufsz); } -static ssize_t rtw89_debug_priv_btc_manual_set(struct file *filp, - const char __user *user_buf, - size_t count, loff_t *loff) +static ssize_t rtw89_debug_priv_btc_manual_set(struct rtw89_dev *rtwdev, + struct rtw89_debugfs_priv *debugfs_priv, + const char *buf, size_t count) { - struct rtw89_debugfs_priv *debugfs_priv = filp->private_data; - struct rtw89_dev *rtwdev = debugfs_priv->rtwdev; struct rtw89_btc *btc = &rtwdev->btc; const struct rtw89_btc_ver *ver = btc->ver; int ret; - ret = kstrtobool_from_user(user_buf, count, &btc->manual_ctrl); + ret = kstrtobool(buf, &btc->manual_ctrl); if (ret) return ret; @@ -3491,31 +3663,29 @@ static ssize_t rtw89_debug_priv_btc_manual_set(struct file *filp, return count; } -static ssize_t rtw89_debug_priv_fw_log_manual_set(struct file *filp, - const char __user *user_buf, - size_t count, loff_t *loff) +static ssize_t rtw89_debug_priv_fw_log_manual_set(struct rtw89_dev *rtwdev, + struct rtw89_debugfs_priv *debugfs_priv, + const char *buf, size_t count) { - struct rtw89_debugfs_priv *debugfs_priv = filp->private_data; - struct rtw89_dev *rtwdev = debugfs_priv->rtwdev; struct rtw89_fw_log *log = &rtwdev->fw.log; bool fw_log_manual; - if (kstrtobool_from_user(user_buf, count, &fw_log_manual)) + lockdep_assert_wiphy(rtwdev->hw->wiphy); + + if (kstrtobool(buf, &fw_log_manual)) goto out; - mutex_lock(&rtwdev->mutex); log->enable = fw_log_manual; if (log->enable) rtw89_fw_log_prepare(rtwdev); rtw89_fw_h2c_fw_log(rtwdev, fw_log_manual); - mutex_unlock(&rtwdev->mutex); out: return count; } -static void rtw89_sta_link_info_get_iter(struct seq_file *m, - struct rtw89_dev *rtwdev, - struct rtw89_sta_link *rtwsta_link) +static int rtw89_sta_link_info_get_iter(struct rtw89_dev *rtwdev, + char *buf, size_t bufsz, + struct rtw89_sta_link *rtwsta_link) { static const char * const he_gi_str[] = { [NL80211_RATE_INFO_HE_GI_0_8] = "0.8", @@ -3533,6 +3703,7 @@ static void rtw89_sta_link_info_get_iter(struct seq_file *m, u8 ant_num = hal->ant_diversity ? 2 : rtwdev->chip->rf_path_num; bool ant_asterisk = hal->tx_path_diversity || hal->ant_diversity; struct ieee80211_link_sta *link_sta; + char *p = buf, *end = buf + bufsz; u8 evm_min, evm_max, evm_1ss; u16 max_rc_amsdu_len; u8 rssi; @@ -3546,107 +3717,136 @@ static void rtw89_sta_link_info_get_iter(struct seq_file *m, rcu_read_unlock(); - seq_printf(m, "TX rate [%u, %u]: ", rtwsta_link->mac_id, rtwsta_link->link_id); + p += scnprintf(p, end - p, "TX rate [%u, %u]: ", rtwsta_link->mac_id, + rtwsta_link->link_id); if (rate->flags & RATE_INFO_FLAGS_MCS) - seq_printf(m, "HT MCS-%d%s", rate->mcs, - rate->flags & RATE_INFO_FLAGS_SHORT_GI ? " SGI" : ""); + p += scnprintf(p, end - p, "HT MCS-%d%s", rate->mcs, + rate->flags & RATE_INFO_FLAGS_SHORT_GI ? " SGI" : ""); else if (rate->flags & RATE_INFO_FLAGS_VHT_MCS) - seq_printf(m, "VHT %dSS MCS-%d%s", rate->nss, rate->mcs, - rate->flags & RATE_INFO_FLAGS_SHORT_GI ? " SGI" : ""); + p += scnprintf(p, end - p, "VHT %dSS MCS-%d%s", rate->nss, + rate->mcs, + rate->flags & RATE_INFO_FLAGS_SHORT_GI ? " SGI" : ""); else if (rate->flags & RATE_INFO_FLAGS_HE_MCS) - seq_printf(m, "HE %dSS MCS-%d GI:%s", rate->nss, rate->mcs, - rate->he_gi <= NL80211_RATE_INFO_HE_GI_3_2 ? - he_gi_str[rate->he_gi] : "N/A"); + p += scnprintf(p, end - p, "HE %dSS MCS-%d GI:%s", rate->nss, + rate->mcs, + rate->he_gi <= NL80211_RATE_INFO_HE_GI_3_2 ? + he_gi_str[rate->he_gi] : "N/A"); else if (rate->flags & RATE_INFO_FLAGS_EHT_MCS) - seq_printf(m, "EHT %dSS MCS-%d GI:%s", rate->nss, rate->mcs, - rate->eht_gi < ARRAY_SIZE(eht_gi_str) ? - eht_gi_str[rate->eht_gi] : "N/A"); + p += scnprintf(p, end - p, "EHT %dSS MCS-%d GI:%s", rate->nss, + rate->mcs, + rate->eht_gi < ARRAY_SIZE(eht_gi_str) ? + eht_gi_str[rate->eht_gi] : "N/A"); else - seq_printf(m, "Legacy %d", rate->legacy); - seq_printf(m, "%s", rtwsta_link->ra_report.might_fallback_legacy ? " FB_G" : ""); - seq_printf(m, " BW:%u", rtw89_rate_info_bw_to_mhz(rate->bw)); - seq_printf(m, " (hw_rate=0x%x)", rtwsta_link->ra_report.hw_rate); - seq_printf(m, " ==> agg_wait=%d (%d)\n", rtwsta_link->max_agg_wait, - max_rc_amsdu_len); - - seq_printf(m, "RX rate [%u, %u]: ", rtwsta_link->mac_id, rtwsta_link->link_id); + p += scnprintf(p, end - p, "Legacy %d", rate->legacy); + p += scnprintf(p, end - p, "%s", + rtwsta_link->ra_report.might_fallback_legacy ? " FB_G" : ""); + p += scnprintf(p, end - p, " BW:%u", + rtw89_rate_info_bw_to_mhz(rate->bw)); + p += scnprintf(p, end - p, " (hw_rate=0x%x)", + rtwsta_link->ra_report.hw_rate); + p += scnprintf(p, end - p, " ==> agg_wait=%d (%d)\n", + rtwsta_link->max_agg_wait, + max_rc_amsdu_len); + + p += scnprintf(p, end - p, "RX rate [%u, %u]: ", rtwsta_link->mac_id, + rtwsta_link->link_id); switch (status->encoding) { case RX_ENC_LEGACY: - seq_printf(m, "Legacy %d", status->rate_idx + - (status->band != NL80211_BAND_2GHZ ? 4 : 0)); + p += scnprintf(p, end - p, "Legacy %d", status->rate_idx + + (status->band != NL80211_BAND_2GHZ ? 4 : 0)); break; case RX_ENC_HT: - seq_printf(m, "HT MCS-%d%s", status->rate_idx, - status->enc_flags & RX_ENC_FLAG_SHORT_GI ? " SGI" : ""); + p += scnprintf(p, end - p, "HT MCS-%d%s", status->rate_idx, + status->enc_flags & RX_ENC_FLAG_SHORT_GI ? " SGI" : ""); break; case RX_ENC_VHT: - seq_printf(m, "VHT %dSS MCS-%d%s", status->nss, status->rate_idx, - status->enc_flags & RX_ENC_FLAG_SHORT_GI ? " SGI" : ""); + p += scnprintf(p, end - p, "VHT %dSS MCS-%d%s", status->nss, + status->rate_idx, + status->enc_flags & RX_ENC_FLAG_SHORT_GI ? " SGI" : ""); break; case RX_ENC_HE: - seq_printf(m, "HE %dSS MCS-%d GI:%s", status->nss, status->rate_idx, - status->he_gi <= NL80211_RATE_INFO_HE_GI_3_2 ? - he_gi_str[status->he_gi] : "N/A"); + p += scnprintf(p, end - p, "HE %dSS MCS-%d GI:%s", + status->nss, status->rate_idx, + status->he_gi <= NL80211_RATE_INFO_HE_GI_3_2 ? + he_gi_str[status->he_gi] : "N/A"); break; case RX_ENC_EHT: - seq_printf(m, "EHT %dSS MCS-%d GI:%s", status->nss, status->rate_idx, - status->eht.gi < ARRAY_SIZE(eht_gi_str) ? - eht_gi_str[status->eht.gi] : "N/A"); + p += scnprintf(p, end - p, "EHT %dSS MCS-%d GI:%s", + status->nss, status->rate_idx, + status->eht.gi < ARRAY_SIZE(eht_gi_str) ? + eht_gi_str[status->eht.gi] : "N/A"); break; } - seq_printf(m, " BW:%u", rtw89_rate_info_bw_to_mhz(status->bw)); - seq_printf(m, " (hw_rate=0x%x)\n", rtwsta_link->rx_hw_rate); + p += scnprintf(p, end - p, " BW:%u", + rtw89_rate_info_bw_to_mhz(status->bw)); + p += scnprintf(p, end - p, " (hw_rate=0x%x)\n", + rtwsta_link->rx_hw_rate); rssi = ewma_rssi_read(&rtwsta_link->avg_rssi); - seq_printf(m, "RSSI: %d dBm (raw=%d, prev=%d) [", - RTW89_RSSI_RAW_TO_DBM(rssi), rssi, rtwsta_link->prev_rssi); + p += scnprintf(p, end - p, "RSSI: %d dBm (raw=%d, prev=%d) [", + RTW89_RSSI_RAW_TO_DBM(rssi), rssi, + rtwsta_link->prev_rssi); for (i = 0; i < ant_num; i++) { rssi = ewma_rssi_read(&rtwsta_link->rssi[i]); - seq_printf(m, "%d%s%s", RTW89_RSSI_RAW_TO_DBM(rssi), - ant_asterisk && (hal->antenna_tx & BIT(i)) ? "*" : "", - i + 1 == ant_num ? "" : ", "); + p += scnprintf(p, end - p, "%d%s%s", + RTW89_RSSI_RAW_TO_DBM(rssi), + ant_asterisk && (hal->antenna_tx & BIT(i)) ? "*" : "", + i + 1 == ant_num ? "" : ", "); } - seq_puts(m, "]\n"); + p += scnprintf(p, end - p, "]\n"); evm_1ss = ewma_evm_read(&rtwsta_link->evm_1ss); - seq_printf(m, "EVM: [%2u.%02u, ", evm_1ss >> 2, (evm_1ss & 0x3) * 25); + p += scnprintf(p, end - p, "EVM: [%2u.%02u, ", evm_1ss >> 2, + (evm_1ss & 0x3) * 25); for (i = 0; i < (hal->ant_diversity ? 2 : 1); i++) { evm_min = ewma_evm_read(&rtwsta_link->evm_min[i]); evm_max = ewma_evm_read(&rtwsta_link->evm_max[i]); - seq_printf(m, "%s(%2u.%02u, %2u.%02u)", i == 0 ? "" : " ", - evm_min >> 2, (evm_min & 0x3) * 25, - evm_max >> 2, (evm_max & 0x3) * 25); + p += scnprintf(p, end - p, "%s(%2u.%02u, %2u.%02u)", + i == 0 ? "" : " ", + evm_min >> 2, (evm_min & 0x3) * 25, + evm_max >> 2, (evm_max & 0x3) * 25); } - seq_puts(m, "]\t"); + p += scnprintf(p, end - p, "]\t"); snr = ewma_snr_read(&rtwsta_link->avg_snr); - seq_printf(m, "SNR: %u\n", snr); + p += scnprintf(p, end - p, "SNR: %u\n", snr); + + return p - buf; } static void rtw89_sta_info_get_iter(void *data, struct ieee80211_sta *sta) { - struct seq_file *m = (struct seq_file *)data; + struct rtw89_debugfs_iter_data *iter_data = + (struct rtw89_debugfs_iter_data *)data; struct rtw89_sta *rtwsta = sta_to_rtwsta(sta); struct rtw89_dev *rtwdev = rtwsta->rtwdev; struct rtw89_sta_link *rtwsta_link; + size_t bufsz = iter_data->bufsz; + char *buf = iter_data->buf; + char *p = buf, *end = buf + bufsz; unsigned int link_id; rtw89_sta_for_each_link(rtwsta, rtwsta_link, link_id) - rtw89_sta_link_info_get_iter(m, rtwdev, rtwsta_link); + p += rtw89_sta_link_info_get_iter(rtwdev, p, end - p, rtwsta_link); + + rtw89_debugfs_iter_data_next(iter_data, p, end - p, p - buf); } -static void -rtw89_debug_append_rx_rate(struct seq_file *m, struct rtw89_pkt_stat *pkt_stat, +static int +rtw89_debug_append_rx_rate(char *buf, size_t bufsz, struct rtw89_pkt_stat *pkt_stat, enum rtw89_hw_rate first_rate, int len) { + char *p = buf, *end = buf + bufsz; int i; for (i = 0; i < len; i++) - seq_printf(m, "%s%u", i == 0 ? "" : ", ", - pkt_stat->rx_rate_cnt[first_rate + i]); + p += scnprintf(p, end - p, "%s%u", i == 0 ? "" : ", ", + pkt_stat->rx_rate_cnt[first_rate + i]); + + return p - buf; } #define FIRST_RATE_SAME(rate) {RTW89_HW_RATE_ ## rate, RTW89_HW_RATE_ ## rate} @@ -3671,34 +3871,40 @@ static const struct rtw89_rx_rate_cnt_info { {FIRST_RATE_GEV1(EHT_NSS2_MCS0), 14, 0, "EHT 2SS:"}, }; -static int rtw89_debug_priv_phy_info_get(struct seq_file *m, void *v) +static ssize_t rtw89_debug_priv_phy_info_get(struct rtw89_dev *rtwdev, + struct rtw89_debugfs_priv *debugfs_priv, + char *buf, size_t bufsz) { - struct rtw89_debugfs_priv *debugfs_priv = m->private; - struct rtw89_dev *rtwdev = debugfs_priv->rtwdev; struct rtw89_traffic_stats *stats = &rtwdev->stats; struct rtw89_pkt_stat *pkt_stat = &rtwdev->phystat.last_pkt_stat; const struct rtw89_chip_info *chip = rtwdev->chip; + struct rtw89_debugfs_iter_data iter_data; const struct rtw89_rx_rate_cnt_info *info; struct rtw89_hal *hal = &rtwdev->hal; + char *p = buf, *end = buf + bufsz; enum rtw89_hw_rate first_rate; u8 rssi; int i; rssi = ewma_rssi_read(&rtwdev->phystat.bcn_rssi); - seq_printf(m, "TP TX: %u [%u] Mbps (lv: %d", - stats->tx_throughput, stats->tx_throughput_raw, stats->tx_tfc_lv); + p += scnprintf(p, end - p, "TP TX: %u [%u] Mbps (lv: %d", + stats->tx_throughput, stats->tx_throughput_raw, + stats->tx_tfc_lv); if (hal->thermal_prot_lv) - seq_printf(m, ", duty: %d%%", - 100 - hal->thermal_prot_lv * RTW89_THERMAL_PROT_STEP); - seq_printf(m, "), RX: %u [%u] Mbps (lv: %d)\n", - stats->rx_throughput, stats->rx_throughput_raw, stats->rx_tfc_lv); - seq_printf(m, "Beacon: %u (%d dBm), TF: %u\n", pkt_stat->beacon_nr, - RTW89_RSSI_RAW_TO_DBM(rssi), stats->rx_tf_periodic); - seq_printf(m, "Avg packet length: TX=%u, RX=%u\n", stats->tx_avg_len, - stats->rx_avg_len); - - seq_puts(m, "RX count:\n"); + p += scnprintf(p, end - p, ", duty: %d%%", + 100 - hal->thermal_prot_lv * RTW89_THERMAL_PROT_STEP); + p += scnprintf(p, end - p, "), RX: %u [%u] Mbps (lv: %d)\n", + stats->rx_throughput, stats->rx_throughput_raw, + stats->rx_tfc_lv); + p += scnprintf(p, end - p, "Beacon: %u (%d dBm), TF: %u\n", + pkt_stat->beacon_nr, + RTW89_RSSI_RAW_TO_DBM(rssi), stats->rx_tf_periodic); + p += scnprintf(p, end - p, "Avg packet length: TX=%u, RX=%u\n", + stats->tx_avg_len, + stats->rx_avg_len); + + p += scnprintf(p, end - p, "RX count:\n"); for (i = 0; i < ARRAY_SIZE(rtw89_rx_rate_cnt_infos); i++) { info = &rtw89_rx_rate_cnt_infos[i]; @@ -3706,189 +3912,238 @@ static int rtw89_debug_priv_phy_info_get(struct seq_file *m, void *v) if (first_rate >= RTW89_HW_RATE_NR) continue; - seq_printf(m, "%10s [", info->rate_mode); - rtw89_debug_append_rx_rate(m, pkt_stat, - first_rate, info->len); + p += scnprintf(p, end - p, "%10s [", info->rate_mode); + p += rtw89_debug_append_rx_rate(p, end - p, pkt_stat, + first_rate, info->len); if (info->ext) { - seq_puts(m, "]["); - rtw89_debug_append_rx_rate(m, pkt_stat, - first_rate + info->len, info->ext); + p += scnprintf(p, end - p, "]["); + p += rtw89_debug_append_rx_rate(p, end - p, pkt_stat, + first_rate + info->len, info->ext); } - seq_puts(m, "]\n"); + p += scnprintf(p, end - p, "]\n"); } - ieee80211_iterate_stations_atomic(rtwdev->hw, rtw89_sta_info_get_iter, m); + rtw89_debugfs_iter_data_setup(&iter_data, p, end - p); + ieee80211_iterate_stations_atomic(rtwdev->hw, rtw89_sta_info_get_iter, &iter_data); + p += iter_data.written_sz; - return 0; + return p - buf; } -static void rtw89_dump_addr_cam(struct seq_file *m, - struct rtw89_dev *rtwdev, - struct rtw89_addr_cam_entry *addr_cam) +static int rtw89_dump_addr_cam(struct rtw89_dev *rtwdev, + char *buf, size_t bufsz, + struct rtw89_addr_cam_entry *addr_cam) { struct rtw89_cam_info *cam_info = &rtwdev->cam_info; const struct rtw89_sec_cam_entry *sec_entry; + char *p = buf, *end = buf + bufsz; u8 sec_cam_idx; int i; - seq_printf(m, "\taddr_cam_idx=%u\n", addr_cam->addr_cam_idx); - seq_printf(m, "\t-> bssid_cam_idx=%u\n", addr_cam->bssid_cam_idx); - seq_printf(m, "\tsec_cam_bitmap=%*ph\n", (int)sizeof(addr_cam->sec_cam_map), - addr_cam->sec_cam_map); + p += scnprintf(p, end - p, "\taddr_cam_idx=%u\n", + addr_cam->addr_cam_idx); + p += scnprintf(p, end - p, "\t-> bssid_cam_idx=%u\n", + addr_cam->bssid_cam_idx); + p += scnprintf(p, end - p, "\tsec_cam_bitmap=%*ph\n", + (int)sizeof(addr_cam->sec_cam_map), + addr_cam->sec_cam_map); for_each_set_bit(i, addr_cam->sec_cam_map, RTW89_SEC_CAM_IN_ADDR_CAM) { sec_cam_idx = addr_cam->sec_ent[i]; sec_entry = cam_info->sec_entries[sec_cam_idx]; if (!sec_entry) continue; - seq_printf(m, "\tsec[%d]: sec_cam_idx %u", i, sec_entry->sec_cam_idx); + p += scnprintf(p, end - p, "\tsec[%d]: sec_cam_idx %u", i, + sec_entry->sec_cam_idx); if (sec_entry->ext_key) - seq_printf(m, ", %u", sec_entry->sec_cam_idx + 1); - seq_puts(m, "\n"); + p += scnprintf(p, end - p, ", %u", + sec_entry->sec_cam_idx + 1); + p += scnprintf(p, end - p, "\n"); } + + return p - buf; } -__printf(3, 4) -static void rtw89_dump_pkt_offload(struct seq_file *m, struct list_head *pkt_list, - const char *fmt, ...) +__printf(4, 5) +static int rtw89_dump_pkt_offload(char *buf, size_t bufsz, struct list_head *pkt_list, + const char *fmt, ...) { + char *p = buf, *end = buf + bufsz; struct rtw89_pktofld_info *info; struct va_format vaf; va_list args; if (list_empty(pkt_list)) - return; + return 0; va_start(args, fmt); vaf.va = &args; vaf.fmt = fmt; - seq_printf(m, "%pV", &vaf); + p += scnprintf(p, end - p, "%pV", &vaf); va_end(args); list_for_each_entry(info, pkt_list, list) - seq_printf(m, "%d ", info->id); + p += scnprintf(p, end - p, "%d ", info->id); + + p += scnprintf(p, end - p, "\n"); - seq_puts(m, "\n"); + return p - buf; } -static void rtw89_vif_link_ids_get(struct seq_file *m, u8 *mac, - struct rtw89_dev *rtwdev, - struct rtw89_vif_link *rtwvif_link) +static int rtw89_vif_link_ids_get(struct rtw89_dev *rtwdev, + char *buf, size_t bufsz, u8 *mac, + struct rtw89_vif_link *rtwvif_link) { struct rtw89_bssid_cam_entry *bssid_cam = &rtwvif_link->bssid_cam; - - seq_printf(m, " [%u] %pM\n", rtwvif_link->mac_id, rtwvif_link->mac_addr); - seq_printf(m, "\tlink_id=%u\n", rtwvif_link->link_id); - seq_printf(m, "\tbssid_cam_idx=%u\n", bssid_cam->bssid_cam_idx); - rtw89_dump_addr_cam(m, rtwdev, &rtwvif_link->addr_cam); - rtw89_dump_pkt_offload(m, &rtwvif_link->general_pkt_list, - "\tpkt_ofld[GENERAL]: "); + char *p = buf, *end = buf + bufsz; + + p += scnprintf(p, end - p, " [%u] %pM\n", rtwvif_link->mac_id, + rtwvif_link->mac_addr); + p += scnprintf(p, end - p, "\tlink_id=%u\n", rtwvif_link->link_id); + p += scnprintf(p, end - p, "\tbssid_cam_idx=%u\n", + bssid_cam->bssid_cam_idx); + p += rtw89_dump_addr_cam(rtwdev, p, end - p, &rtwvif_link->addr_cam); + p += rtw89_dump_pkt_offload(p, end - p, &rtwvif_link->general_pkt_list, + "\tpkt_ofld[GENERAL]: "); + + return p - buf; } static void rtw89_vif_ids_get_iter(void *data, u8 *mac, struct ieee80211_vif *vif) { - struct seq_file *m = (struct seq_file *)data; + struct rtw89_debugfs_iter_data *iter_data = + (struct rtw89_debugfs_iter_data *)data; struct rtw89_vif *rtwvif = vif_to_rtwvif(vif); struct rtw89_dev *rtwdev = rtwvif->rtwdev; struct rtw89_vif_link *rtwvif_link; + size_t bufsz = iter_data->bufsz; + char *buf = iter_data->buf; + char *p = buf, *end = buf + bufsz; unsigned int link_id; - seq_printf(m, "VIF %pM\n", rtwvif->mac_addr); + p += scnprintf(p, end - p, "VIF %pM\n", rtwvif->mac_addr); rtw89_vif_for_each_link(rtwvif, rtwvif_link, link_id) - rtw89_vif_link_ids_get(m, mac, rtwdev, rtwvif_link); + p += rtw89_vif_link_ids_get(rtwdev, p, end - p, mac, rtwvif_link); + + rtw89_debugfs_iter_data_next(iter_data, p, end - p, p - buf); } -static void rtw89_dump_ba_cam(struct seq_file *m, struct rtw89_dev *rtwdev, - struct rtw89_sta_link *rtwsta_link) +static int rtw89_dump_ba_cam(struct rtw89_dev *rtwdev, + char *buf, size_t bufsz, + struct rtw89_sta_link *rtwsta_link) { struct rtw89_ba_cam_entry *entry; + char *p = buf, *end = buf + bufsz; bool first = true; list_for_each_entry(entry, &rtwsta_link->ba_cam_list, list) { if (first) { - seq_puts(m, "\tba_cam "); + p += scnprintf(p, end - p, "\tba_cam "); first = false; } else { - seq_puts(m, ", "); + p += scnprintf(p, end - p, ", "); } - seq_printf(m, "tid[%u]=%d", entry->tid, - (int)(entry - rtwdev->cam_info.ba_cam_entry)); + p += scnprintf(p, end - p, "tid[%u]=%d", entry->tid, + (int)(entry - rtwdev->cam_info.ba_cam_entry)); } - seq_puts(m, "\n"); + p += scnprintf(p, end - p, "\n"); + + return p - buf; } -static void rtw89_sta_link_ids_get(struct seq_file *m, - struct rtw89_dev *rtwdev, - struct rtw89_sta_link *rtwsta_link) +static int rtw89_sta_link_ids_get(struct rtw89_dev *rtwdev, + char *buf, size_t bufsz, + struct rtw89_sta_link *rtwsta_link) { struct ieee80211_link_sta *link_sta; + char *p = buf, *end = buf + bufsz; rcu_read_lock(); link_sta = rtw89_sta_rcu_dereference_link(rtwsta_link, true); - seq_printf(m, " [%u] %pM\n", rtwsta_link->mac_id, link_sta->addr); + p += scnprintf(p, end - p, " [%u] %pM\n", rtwsta_link->mac_id, + link_sta->addr); rcu_read_unlock(); - seq_printf(m, "\tlink_id=%u\n", rtwsta_link->link_id); - rtw89_dump_addr_cam(m, rtwdev, &rtwsta_link->addr_cam); - rtw89_dump_ba_cam(m, rtwdev, rtwsta_link); + p += scnprintf(p, end - p, "\tlink_id=%u\n", rtwsta_link->link_id); + p += rtw89_dump_addr_cam(rtwdev, p, end - p, &rtwsta_link->addr_cam); + p += rtw89_dump_ba_cam(rtwdev, p, end - p, rtwsta_link); + + return p - buf; } static void rtw89_sta_ids_get_iter(void *data, struct ieee80211_sta *sta) { - struct seq_file *m = (struct seq_file *)data; + struct rtw89_debugfs_iter_data *iter_data = + (struct rtw89_debugfs_iter_data *)data; struct rtw89_sta *rtwsta = sta_to_rtwsta(sta); struct rtw89_dev *rtwdev = rtwsta->rtwdev; struct rtw89_sta_link *rtwsta_link; + size_t bufsz = iter_data->bufsz; + char *buf = iter_data->buf; + char *p = buf, *end = buf + bufsz; unsigned int link_id; - seq_printf(m, "STA %pM %s\n", sta->addr, sta->tdls ? "(TDLS)" : ""); + p += scnprintf(p, end - p, "STA %pM %s\n", sta->addr, + sta->tdls ? "(TDLS)" : ""); rtw89_sta_for_each_link(rtwsta, rtwsta_link, link_id) - rtw89_sta_link_ids_get(m, rtwdev, rtwsta_link); + p += rtw89_sta_link_ids_get(rtwdev, p, end - p, rtwsta_link); + + rtw89_debugfs_iter_data_next(iter_data, p, end - p, p - buf); } -static int rtw89_debug_priv_stations_get(struct seq_file *m, void *v) +static ssize_t rtw89_debug_priv_stations_get(struct rtw89_dev *rtwdev, + struct rtw89_debugfs_priv *debugfs_priv, + char *buf, size_t bufsz) { - struct rtw89_debugfs_priv *debugfs_priv = m->private; - struct rtw89_dev *rtwdev = debugfs_priv->rtwdev; struct rtw89_cam_info *cam_info = &rtwdev->cam_info; + struct rtw89_debugfs_iter_data iter_data; + char *p = buf, *end = buf + bufsz; u8 idx; - mutex_lock(&rtwdev->mutex); - - seq_puts(m, "map:\n"); - seq_printf(m, "\tmac_id: %*ph\n", (int)sizeof(rtwdev->mac_id_map), - rtwdev->mac_id_map); - seq_printf(m, "\taddr_cam: %*ph\n", (int)sizeof(cam_info->addr_cam_map), - cam_info->addr_cam_map); - seq_printf(m, "\tbssid_cam: %*ph\n", (int)sizeof(cam_info->bssid_cam_map), - cam_info->bssid_cam_map); - seq_printf(m, "\tsec_cam: %*ph\n", (int)sizeof(cam_info->sec_cam_map), - cam_info->sec_cam_map); - seq_printf(m, "\tba_cam: %*ph\n", (int)sizeof(cam_info->ba_cam_map), - cam_info->ba_cam_map); - seq_printf(m, "\tpkt_ofld: %*ph\n", (int)sizeof(rtwdev->pkt_offload), - rtwdev->pkt_offload); + lockdep_assert_wiphy(rtwdev->hw->wiphy); + + p += scnprintf(p, end - p, "map:\n"); + p += scnprintf(p, end - p, "\tmac_id: %*ph\n", + (int)sizeof(rtwdev->mac_id_map), + rtwdev->mac_id_map); + p += scnprintf(p, end - p, "\taddr_cam: %*ph\n", + (int)sizeof(cam_info->addr_cam_map), + cam_info->addr_cam_map); + p += scnprintf(p, end - p, "\tbssid_cam: %*ph\n", + (int)sizeof(cam_info->bssid_cam_map), + cam_info->bssid_cam_map); + p += scnprintf(p, end - p, "\tsec_cam: %*ph\n", + (int)sizeof(cam_info->sec_cam_map), + cam_info->sec_cam_map); + p += scnprintf(p, end - p, "\tba_cam: %*ph\n", + (int)sizeof(cam_info->ba_cam_map), + cam_info->ba_cam_map); + p += scnprintf(p, end - p, "\tpkt_ofld: %*ph\n", + (int)sizeof(rtwdev->pkt_offload), + rtwdev->pkt_offload); for (idx = NL80211_BAND_2GHZ; idx < NUM_NL80211_BANDS; idx++) { if (!(rtwdev->chip->support_bands & BIT(idx))) continue; - rtw89_dump_pkt_offload(m, &rtwdev->scan_info.pkt_list[idx], - "\t\t[SCAN %u]: ", idx); + p += rtw89_dump_pkt_offload(p, end - p, &rtwdev->scan_info.pkt_list[idx], + "\t\t[SCAN %u]: ", idx); } + rtw89_debugfs_iter_data_setup(&iter_data, p, end - p); ieee80211_iterate_active_interfaces_atomic(rtwdev->hw, - IEEE80211_IFACE_ITER_NORMAL, rtw89_vif_ids_get_iter, m); + IEEE80211_IFACE_ITER_NORMAL, rtw89_vif_ids_get_iter, &iter_data); + p += iter_data.written_sz; - ieee80211_iterate_stations_atomic(rtwdev->hw, rtw89_sta_ids_get_iter, m); + rtw89_debugfs_iter_data_setup(&iter_data, p, end - p); + ieee80211_iterate_stations_atomic(rtwdev->hw, rtw89_sta_ids_get_iter, &iter_data); + p += iter_data.written_sz; - mutex_unlock(&rtwdev->mutex); - - return 0; + return p - buf; } #define DM_INFO(type) {RTW89_DM_ ## type, #type} @@ -3901,41 +4156,42 @@ static const struct rtw89_disabled_dm_info { DM_INFO(THERMAL_PROTECT), }; -static int -rtw89_debug_priv_disable_dm_get(struct seq_file *m, void *v) +static ssize_t +rtw89_debug_priv_disable_dm_get(struct rtw89_dev *rtwdev, + struct rtw89_debugfs_priv *debugfs_priv, + char *buf, size_t bufsz) { - struct rtw89_debugfs_priv *debugfs_priv = m->private; - struct rtw89_dev *rtwdev = debugfs_priv->rtwdev; const struct rtw89_disabled_dm_info *info; struct rtw89_hal *hal = &rtwdev->hal; + char *p = buf, *end = buf + bufsz; u32 disabled; int i; - seq_printf(m, "Disabled DM: 0x%x\n", hal->disabled_dm_bitmap); + p += scnprintf(p, end - p, "Disabled DM: 0x%x\n", + hal->disabled_dm_bitmap); for (i = 0; i < ARRAY_SIZE(rtw89_disabled_dm_infos); i++) { info = &rtw89_disabled_dm_infos[i]; disabled = BIT(info->type) & hal->disabled_dm_bitmap; - seq_printf(m, "[%d] %s: %c\n", info->type, info->name, - disabled ? 'X' : 'O'); + p += scnprintf(p, end - p, "[%d] %s: %c\n", info->type, + info->name, + disabled ? 'X' : 'O'); } - return 0; + return p - buf; } static ssize_t -rtw89_debug_priv_disable_dm_set(struct file *filp, const char __user *user_buf, - size_t count, loff_t *loff) +rtw89_debug_priv_disable_dm_set(struct rtw89_dev *rtwdev, + struct rtw89_debugfs_priv *debugfs_priv, + const char *buf, size_t count) { - struct seq_file *m = (struct seq_file *)filp->private_data; - struct rtw89_debugfs_priv *debugfs_priv = m->private; - struct rtw89_dev *rtwdev = debugfs_priv->rtwdev; struct rtw89_hal *hal = &rtwdev->hal; u32 conf; int ret; - ret = kstrtou32_from_user(user_buf, count, 0, &conf); + ret = kstrtou32(buf, 0, &conf); if (ret) return -EINVAL; @@ -3944,46 +4200,62 @@ rtw89_debug_priv_disable_dm_set(struct file *filp, const char __user *user_buf, return count; } -#define rtw89_debug_priv_get(name) \ +#define rtw89_debug_priv_get(name, opts...) \ { \ .cb_read = rtw89_debug_priv_ ##name## _get, \ + .opt = { opts }, \ } -#define rtw89_debug_priv_set(name) \ +#define rtw89_debug_priv_set(name, opts...) \ { \ .cb_write = rtw89_debug_priv_ ##name## _set, \ + .opt = { opts }, \ } -#define rtw89_debug_priv_select_and_get(name) \ +#define rtw89_debug_priv_select_and_get(name, opts...) \ { \ .cb_write = rtw89_debug_priv_ ##name## _select, \ .cb_read = rtw89_debug_priv_ ##name## _get, \ + .opt = { opts }, \ } -#define rtw89_debug_priv_set_and_get(name) \ +#define rtw89_debug_priv_set_and_get(name, opts...) \ { \ .cb_write = rtw89_debug_priv_ ##name## _set, \ .cb_read = rtw89_debug_priv_ ##name## _get, \ + .opt = { opts }, \ } +#define RSIZE_8K .rsize = 0x2000 +#define RSIZE_12K .rsize = 0x3000 +#define RSIZE_16K .rsize = 0x4000 +#define RSIZE_20K .rsize = 0x5000 +#define RSIZE_32K .rsize = 0x8000 +#define RSIZE_64K .rsize = 0x10000 +#define RSIZE_128K .rsize = 0x20000 +#define RSIZE_1M .rsize = 0x100000 +#define RLOCK .rlock = 1 +#define WLOCK .wlock = 1 +#define RWLOCK RLOCK, WLOCK + static const struct rtw89_debugfs rtw89_debugfs_templ = { .read_reg = rtw89_debug_priv_select_and_get(read_reg), .write_reg = rtw89_debug_priv_set(write_reg), .read_rf = rtw89_debug_priv_select_and_get(read_rf), .write_rf = rtw89_debug_priv_set(write_rf), - .rf_reg_dump = rtw89_debug_priv_get(rf_reg_dump), - .txpwr_table = rtw89_debug_priv_get(txpwr_table), - .mac_reg_dump = rtw89_debug_priv_select_and_get(mac_reg_dump), - .mac_mem_dump = rtw89_debug_priv_select_and_get(mac_mem_dump), - .mac_dbg_port_dump = rtw89_debug_priv_select_and_get(mac_dbg_port_dump), + .rf_reg_dump = rtw89_debug_priv_get(rf_reg_dump, RSIZE_8K), + .txpwr_table = rtw89_debug_priv_get(txpwr_table, RSIZE_20K, RLOCK), + .mac_reg_dump = rtw89_debug_priv_select_and_get(mac_reg_dump, RSIZE_128K), + .mac_mem_dump = rtw89_debug_priv_select_and_get(mac_mem_dump, RSIZE_16K, RLOCK), + .mac_dbg_port_dump = rtw89_debug_priv_select_and_get(mac_dbg_port_dump, RSIZE_1M), .send_h2c = rtw89_debug_priv_set(send_h2c), - .early_h2c = rtw89_debug_priv_set_and_get(early_h2c), - .fw_crash = rtw89_debug_priv_set_and_get(fw_crash), - .btc_info = rtw89_debug_priv_get(btc_info), + .early_h2c = rtw89_debug_priv_set_and_get(early_h2c, RWLOCK), + .fw_crash = rtw89_debug_priv_set_and_get(fw_crash, WLOCK), + .btc_info = rtw89_debug_priv_get(btc_info, RSIZE_12K), .btc_manual = rtw89_debug_priv_set(btc_manual), - .fw_log_manual = rtw89_debug_priv_set(fw_log_manual), + .fw_log_manual = rtw89_debug_priv_set(fw_log_manual, WLOCK), .phy_info = rtw89_debug_priv_get(phy_info), - .stations = rtw89_debug_priv_get(stations), + .stations = rtw89_debug_priv_get(stations, RLOCK), .disable_dm = rtw89_debug_priv_set_and_get(disable_dm), }; diff --git a/drivers/net/wireless/realtek/rtw89/fw.c b/drivers/net/wireless/realtek/rtw89/fw.c index 5d4ad23cc3bd..35b86970db2a 100644 --- a/drivers/net/wireless/realtek/rtw89/fw.c +++ b/drivers/net/wireless/realtek/rtw89/fw.c @@ -489,6 +489,30 @@ static int rtw89_fw_hdr_parser(struct rtw89_dev *rtwdev, } } +static int rtw89_mfw_validate_hdr(struct rtw89_dev *rtwdev, + const struct firmware *firmware, + const struct rtw89_mfw_hdr *mfw_hdr) +{ + const void *mfw = firmware->data; + u32 mfw_len = firmware->size; + u8 fw_nr = mfw_hdr->fw_nr; + const void *ptr; + + if (fw_nr == 0) { + rtw89_err(rtwdev, "mfw header has no fw entry\n"); + return -ENOENT; + } + + ptr = &mfw_hdr->info[fw_nr]; + + if (ptr > mfw + mfw_len) { + rtw89_err(rtwdev, "mfw header out of address\n"); + return -EFAULT; + } + + return 0; +} + static int rtw89_mfw_recognize(struct rtw89_dev *rtwdev, enum rtw89_fw_type type, struct rtw89_fw_suit *fw_suit, bool nowarn) @@ -499,6 +523,7 @@ int rtw89_mfw_recognize(struct rtw89_dev *rtwdev, enum rtw89_fw_type type, u32 mfw_len = firmware->size; const struct rtw89_mfw_hdr *mfw_hdr = (const struct rtw89_mfw_hdr *)mfw; const struct rtw89_mfw_info *mfw_info = NULL, *tmp; + int ret; int i; if (mfw_hdr->sig != RTW89_MFW_SIG) { @@ -511,6 +536,10 @@ int rtw89_mfw_recognize(struct rtw89_dev *rtwdev, enum rtw89_fw_type type, return 0; } + ret = rtw89_mfw_validate_hdr(rtwdev, firmware, mfw_hdr); + if (ret) + return ret; + for (i = 0; i < mfw_hdr->fw_nr; i++) { tmp = &mfw_hdr->info[i]; if (tmp->type != type) @@ -540,6 +569,12 @@ int rtw89_mfw_recognize(struct rtw89_dev *rtwdev, enum rtw89_fw_type type, found: fw_suit->data = mfw + le32_to_cpu(mfw_info->shift); fw_suit->size = le32_to_cpu(mfw_info->size); + + if (fw_suit->data + fw_suit->size > mfw + mfw_len) { + rtw89_err(rtwdev, "fw_suit %d out of address\n", type); + return -EFAULT; + } + return 0; } @@ -551,12 +586,17 @@ static u32 rtw89_mfw_get_size(struct rtw89_dev *rtwdev) (const struct rtw89_mfw_hdr *)firmware->data; const struct rtw89_mfw_info *mfw_info; u32 size; + int ret; if (mfw_hdr->sig != RTW89_MFW_SIG) { rtw89_warn(rtwdev, "not mfw format\n"); return 0; } + ret = rtw89_mfw_validate_hdr(rtwdev, firmware, mfw_hdr); + if (ret) + return ret; + mfw_info = &mfw_hdr->info[mfw_hdr->fw_nr - 1]; size = le32_to_cpu(mfw_info->shift) + le32_to_cpu(mfw_info->size); @@ -1056,6 +1096,101 @@ allocated: return 0; } +static bool rtw89_regd_entcpy(struct rtw89_regd *regd, const void *cursor, + u8 cursor_size) +{ + /* fill default values if needed for backward compatibility */ + struct rtw89_fw_regd_entry entry = { + .rule_2ghz = RTW89_NA, + .rule_5ghz = RTW89_NA, + .rule_6ghz = RTW89_NA, + .fmap = cpu_to_le32(0x0), + }; + u8 valid_size = min_t(u8, sizeof(entry), cursor_size); + unsigned int i; + u32 fmap; + + memcpy(&entry, cursor, valid_size); + memset(regd, 0, sizeof(*regd)); + + regd->alpha2[0] = entry.alpha2_0; + regd->alpha2[1] = entry.alpha2_1; + regd->alpha2[2] = '\0'; + + /* also need to consider forward compatibility */ + regd->txpwr_regd[RTW89_BAND_2G] = entry.rule_2ghz < RTW89_REGD_NUM ? + entry.rule_2ghz : RTW89_NA; + regd->txpwr_regd[RTW89_BAND_5G] = entry.rule_5ghz < RTW89_REGD_NUM ? + entry.rule_5ghz : RTW89_NA; + regd->txpwr_regd[RTW89_BAND_6G] = entry.rule_6ghz < RTW89_REGD_NUM ? + entry.rule_6ghz : RTW89_NA; + + BUILD_BUG_ON(sizeof(fmap) != sizeof(entry.fmap)); + BUILD_BUG_ON(sizeof(fmap) * 8 < NUM_OF_RTW89_REGD_FUNC); + + fmap = le32_to_cpu(entry.fmap); + for (i = 0; i < NUM_OF_RTW89_REGD_FUNC; i++) { + if (fmap & BIT(i)) + set_bit(i, regd->func_bitmap); + } + + return true; +} + +#define rtw89_for_each_in_regd_element(regd, element) \ + for (const void *cursor = (element)->content, \ + *end = (element)->content + \ + le32_to_cpu((element)->num_ents) * (element)->ent_sz; \ + cursor < end; cursor += (element)->ent_sz) \ + if (rtw89_regd_entcpy(regd, cursor, (element)->ent_sz)) + +static +int rtw89_recognize_regd_from_elm(struct rtw89_dev *rtwdev, + const struct rtw89_fw_element_hdr *elm, + const union rtw89_fw_element_arg arg) +{ + const struct __rtw89_fw_regd_element *regd_elm = &elm->u.regd; + struct rtw89_fw_elm_info *elm_info = &rtwdev->fw.elm_info; + u32 num_ents = le32_to_cpu(regd_elm->num_ents); + struct rtw89_regd_data *p; + struct rtw89_regd regd; + u32 i = 0; + + if (num_ents > RTW89_REGD_MAX_COUNTRY_NUM) { + rtw89_warn(rtwdev, + "regd element ents (%d) are over max num (%d)\n", + num_ents, RTW89_REGD_MAX_COUNTRY_NUM); + rtw89_warn(rtwdev, + "regd element ignore and take another/common\n"); + return 1; + } + + if (elm_info->regd) { + rtw89_debug(rtwdev, RTW89_DBG_REGD, + "regd element take the latter\n"); + devm_kfree(rtwdev->dev, elm_info->regd); + elm_info->regd = NULL; + } + + p = devm_kzalloc(rtwdev->dev, struct_size(p, map, num_ents), GFP_KERNEL); + if (!p) + return -ENOMEM; + + p->nr = num_ents; + rtw89_for_each_in_regd_element(®d, regd_elm) + p->map[i++] = regd; + + if (i != num_ents) { + rtw89_err(rtwdev, "regd element has %d invalid ents\n", + num_ents - i); + devm_kfree(rtwdev->dev, p); + return -EINVAL; + } + + elm_info->regd = p; + return 0; +} + static const struct rtw89_fw_element_handler __fw_element_handlers[] = { [RTW89_FW_ELEMENT_ID_BBMCU0] = {__rtw89_fw_recognize_from_elm, { .fw_type = RTW89_FW_BBMCU0 }, NULL}, @@ -1114,6 +1249,9 @@ static const struct rtw89_fw_element_handler __fw_element_handlers[] = { [RTW89_FW_ELEMENT_ID_RFKLOG_FMT] = { rtw89_build_rfk_log_fmt_from_elm, {}, NULL, }, + [RTW89_FW_ELEMENT_ID_REGD] = { + rtw89_recognize_regd_from_elm, {}, "REGD", + }, }; int rtw89_fw_recognize_elements(struct rtw89_dev *rtwdev) @@ -2697,7 +2835,9 @@ int rtw89_fw_h2c_lps_ml_cmn_info(struct rtw89_dev *rtwdev, { const struct rtw89_phy_bb_gain_info_be *gain = &rtwdev->bb_gain.be; struct rtw89_pkt_stat *pkt_stat = &rtwdev->phystat.cur_pkt_stat; + static const u8 bcn_bw_ofst[] = {0, 0, 0, 3, 6, 9, 0, 12}; const struct rtw89_chip_info *chip = rtwdev->chip; + struct rtw89_efuse *efuse = &rtwdev->efuse; struct rtw89_h2c_lps_ml_cmn_info *h2c; struct rtw89_vif_link *rtwvif_link; const struct rtw89_chan *chan; @@ -2705,6 +2845,7 @@ int rtw89_fw_h2c_lps_ml_cmn_info(struct rtw89_dev *rtwdev, u32 len = sizeof(*h2c); unsigned int link_id; struct sk_buff *skb; + u8 beacon_bw_ofst; u8 gain_band; u32 done; u8 path; @@ -2722,9 +2863,10 @@ int rtw89_fw_h2c_lps_ml_cmn_info(struct rtw89_dev *rtwdev, skb_put(skb, len); h2c = (struct rtw89_h2c_lps_ml_cmn_info *)skb->data; - h2c->fmt_id = 0x1; + h2c->fmt_id = 0x3; h2c->mlo_dbcc_mode = cpu_to_le32(rtwdev->mlo_dbcc_mode); + h2c->rfe_type = efuse->rfe_type; rtw89_vif_for_each_link(rtwvif, rtwvif_link, link_id) { path = rtwvif_link->phy_idx == RTW89_PHY_1 ? RF_PATH_B : RF_PATH_A; @@ -2745,9 +2887,21 @@ int rtw89_fw_h2c_lps_ml_cmn_info(struct rtw89_dev *rtwdev, h2c->tia_gain[rtwvif_link->phy_idx][i] = cpu_to_le16(gain->tia_gain[gain_band][bw_idx][path][i]); } + + if (rtwvif_link->bcn_bw_idx < ARRAY_SIZE(bcn_bw_ofst)) { + beacon_bw_ofst = bcn_bw_ofst[rtwvif_link->bcn_bw_idx]; + h2c->dup_bcn_ofst[rtwvif_link->phy_idx] = beacon_bw_ofst; + } + memcpy(h2c->lna_gain[rtwvif_link->phy_idx], gain->lna_gain[gain_band][bw_idx][path], LNA_GAIN_NUM); + memcpy(h2c->tia_lna_op1db[rtwvif_link->phy_idx], + gain->tia_lna_op1db[gain_band][bw_idx][path], + LNA_GAIN_NUM + 1); + memcpy(h2c->lna_op1db[rtwvif_link->phy_idx], + gain->lna_op1db[gain_band][bw_idx][path], + LNA_GAIN_NUM); } rtw89_h2c_pkt_set_hdr(rtwdev, skb, FWCMD_TYPE_H2C, @@ -5311,6 +5465,7 @@ int rtw89_fw_h2c_scan_offload_be(struct rtw89_dev *rtwdev, u8 macc_role_size = sizeof(*macc_role) * option->num_macc_role; u8 opch_size = sizeof(*opch) * option->num_opch; u8 probe_id[NUM_NL80211_BANDS]; + u8 scan_offload_ver = U8_MAX; u8 cfg_len = sizeof(*h2c); unsigned int cond; u8 ver = U8_MAX; @@ -5321,6 +5476,11 @@ int rtw89_fw_h2c_scan_offload_be(struct rtw89_dev *rtwdev, rtw89_scan_get_6g_disabled_chan(rtwdev, option); + if (RTW89_CHK_FW_FEATURE(SCAN_OFFLOAD_BE_V0, &rtwdev->fw)) { + cfg_len = offsetofend(typeof(*h2c), w8); + scan_offload_ver = 0; + } + len = cfg_len + macc_role_size + opch_size; skb = rtw89_fw_h2c_alloc_skb_with_hdr(rtwdev, len); if (!skb) { @@ -5392,10 +5552,8 @@ int rtw89_fw_h2c_scan_offload_be(struct rtw89_dev *rtwdev, RTW89_H2C_SCANOFLD_BE_W8_PROBE_RATE_6GHZ); } - if (RTW89_CHK_FW_FEATURE(SCAN_OFFLOAD_BE_V0, &rtwdev->fw)) { - cfg_len = offsetofend(typeof(*h2c), w8); + if (scan_offload_ver == 0) goto flex_member; - } h2c->w9 = le32_encode_bits(sizeof(*h2c) / sizeof(h2c->w0), RTW89_H2C_SCANOFLD_BE_W9_SIZE_CFG) | @@ -5994,24 +6152,29 @@ void rtw89_fw_send_all_early_h2c(struct rtw89_dev *rtwdev) { struct rtw89_early_h2c *early_h2c; - lockdep_assert_held(&rtwdev->mutex); + lockdep_assert_wiphy(rtwdev->hw->wiphy); list_for_each_entry(early_h2c, &rtwdev->early_h2c_list, list) { rtw89_fw_h2c_raw(rtwdev, early_h2c->h2c, early_h2c->h2c_len); } } -void rtw89_fw_free_all_early_h2c(struct rtw89_dev *rtwdev) +void __rtw89_fw_free_all_early_h2c(struct rtw89_dev *rtwdev) { struct rtw89_early_h2c *early_h2c, *tmp; - mutex_lock(&rtwdev->mutex); list_for_each_entry_safe(early_h2c, tmp, &rtwdev->early_h2c_list, list) { list_del(&early_h2c->list); kfree(early_h2c->h2c); kfree(early_h2c); } - mutex_unlock(&rtwdev->mutex); +} + +void rtw89_fw_free_all_early_h2c(struct rtw89_dev *rtwdev) +{ + lockdep_assert_wiphy(rtwdev->hw->wiphy); + + __rtw89_fw_free_all_early_h2c(rtwdev); } static void rtw89_fw_c2h_parse_attr(struct sk_buff *c2h) @@ -6055,7 +6218,7 @@ void rtw89_fw_c2h_irqsafe(struct rtw89_dev *rtwdev, struct sk_buff *c2h) enqueue: skb_queue_tail(&rtwdev->c2h_queue, c2h); - ieee80211_queue_work(rtwdev->hw, &rtwdev->c2h_work); + wiphy_work_queue(rtwdev->hw->wiphy, &rtwdev->c2h_work); } static void rtw89_fw_c2h_cmd_handle(struct rtw89_dev *rtwdev, @@ -6093,17 +6256,17 @@ static void rtw89_fw_c2h_cmd_handle(struct rtw89_dev *rtwdev, rtw89_hex_dump(rtwdev, RTW89_DBG_FW, "C2H: ", skb->data, skb->len); } -void rtw89_fw_c2h_work(struct work_struct *work) +void rtw89_fw_c2h_work(struct wiphy *wiphy, struct wiphy_work *work) { struct rtw89_dev *rtwdev = container_of(work, struct rtw89_dev, c2h_work); struct sk_buff *skb, *tmp; + lockdep_assert_wiphy(rtwdev->hw->wiphy); + skb_queue_walk_safe(&rtwdev->c2h_queue, skb, tmp) { skb_unlink(skb, &rtwdev->c2h_queue); - mutex_lock(&rtwdev->mutex); rtw89_fw_c2h_cmd_handle(rtwdev, skb); - mutex_unlock(&rtwdev->mutex); dev_kfree_skb_any(skb); } } @@ -6184,7 +6347,7 @@ int rtw89_fw_msg_reg(struct rtw89_dev *rtwdev, u32 ret; if (h2c_info && h2c_info->id != RTW89_FWCMD_H2CREG_FUNC_GET_FEATURE) - lockdep_assert_held(&rtwdev->mutex); + lockdep_assert_wiphy(rtwdev->hw->wiphy); if (!h2c_info && !c2h_info) return -EINVAL; diff --git a/drivers/net/wireless/realtek/rtw89/fw.h b/drivers/net/wireless/realtek/rtw89/fw.h index 2026bc2fd2ac..994d109a9c3c 100644 --- a/drivers/net/wireless/realtek/rtw89/fw.h +++ b/drivers/net/wireless/realtek/rtw89/fw.h @@ -1801,17 +1801,21 @@ struct rtw89_h2c_lps_ch_info { struct rtw89_h2c_lps_ml_cmn_info { u8 fmt_id; - u8 rsvd0[3]; + u8 rfe_type; + u8 rsvd0[2]; __le32 mlo_dbcc_mode; - u8 central_ch[RTW89_PHY_MAX]; - u8 pri_ch[RTW89_PHY_MAX]; - u8 bw[RTW89_PHY_MAX]; - u8 band[RTW89_PHY_MAX]; - u8 bcn_rate_type[RTW89_PHY_MAX]; + u8 central_ch[RTW89_PHY_NUM]; + u8 pri_ch[RTW89_PHY_NUM]; + u8 bw[RTW89_PHY_NUM]; + u8 band[RTW89_PHY_NUM]; + u8 bcn_rate_type[RTW89_PHY_NUM]; u8 rsvd1[2]; - __le16 tia_gain[RTW89_PHY_MAX][TIA_GAIN_NUM]; - u8 lna_gain[RTW89_PHY_MAX][LNA_GAIN_NUM]; + __le16 tia_gain[RTW89_PHY_NUM][TIA_GAIN_NUM]; + u8 lna_gain[RTW89_PHY_NUM][LNA_GAIN_NUM]; u8 rsvd2[2]; + u8 tia_lna_op1db[RTW89_PHY_NUM][LNA_GAIN_NUM + 1]; + u8 lna_op1db[RTW89_PHY_NUM][LNA_GAIN_NUM]; + u8 dup_bcn_ofst[RTW89_PHY_NUM]; } __packed; static inline void RTW89_SET_FWCMD_CPU_EXCEPTION_TYPE(void *cmd, u32 val) @@ -3882,6 +3886,7 @@ enum rtw89_fw_element_id { RTW89_FW_ELEMENT_ID_TX_SHAPE_LMT_RU = 17, RTW89_FW_ELEMENT_ID_TXPWR_TRK = 18, RTW89_FW_ELEMENT_ID_RFKLOG_FMT = 19, + RTW89_FW_ELEMENT_ID_REGD = 20, RTW89_FW_ELEMENT_ID_NUM, }; @@ -3925,6 +3930,15 @@ struct __rtw89_fw_txpwr_element { u8 content[]; } __packed; +struct __rtw89_fw_regd_element { + u8 rsvd0; + u8 rsvd1; + u8 rsvd2; + u8 ent_sz; + __le32 num_ents; + u8 content[]; +} __packed; + enum rtw89_fw_txpwr_trk_type { __RTW89_FW_TXPWR_TRK_TYPE_6GHZ_START = 0, RTW89_FW_TXPWR_TRK_TYPE_6GB_N = 0, @@ -4016,6 +4030,7 @@ struct rtw89_fw_element_hdr { __le16 offset[]; } __packed rfk_log_fmt; struct __rtw89_fw_txpwr_element txpwr; + struct __rtw89_fw_regd_element regd; } __packed u; } __packed; @@ -4588,7 +4603,7 @@ int rtw89_fw_h2c_dctl_sec_cam_v2(struct rtw89_dev *rtwdev, struct rtw89_vif_link *rtwvif_link, struct rtw89_sta_link *rtwsta_link); void rtw89_fw_c2h_irqsafe(struct rtw89_dev *rtwdev, struct sk_buff *c2h); -void rtw89_fw_c2h_work(struct work_struct *work); +void rtw89_fw_c2h_work(struct wiphy *wiphy, struct wiphy_work *work); int rtw89_fw_h2c_role_maintain(struct rtw89_dev *rtwdev, struct rtw89_vif_link *rtwvif_link, struct rtw89_sta_link *rtwsta_link, @@ -4654,6 +4669,7 @@ int rtw89_fw_h2c_raw_with_hdr(struct rtw89_dev *rtwdev, bool rack, bool dack); int rtw89_fw_h2c_raw(struct rtw89_dev *rtwdev, const u8 *buf, u16 len); void rtw89_fw_send_all_early_h2c(struct rtw89_dev *rtwdev); +void __rtw89_fw_free_all_early_h2c(struct rtw89_dev *rtwdev); void rtw89_fw_free_all_early_h2c(struct rtw89_dev *rtwdev); int rtw89_fw_h2c_general_pkt(struct rtw89_dev *rtwdev, struct rtw89_vif_link *rtwvif_link, u8 macid); @@ -4874,6 +4890,18 @@ int rtw89_chip_h2c_ba_cam(struct rtw89_dev *rtwdev, struct rtw89_sta *rtwsta, return 0; } +/* Must consider compatibility; don't insert new in the mid. + * Fill each field's default value in rtw89_regd_entcpy(). + */ +struct rtw89_fw_regd_entry { + u8 alpha2_0; + u8 alpha2_1; + u8 rule_2ghz; + u8 rule_5ghz; + u8 rule_6ghz; + __le32 fmap; +} __packed; + /* must consider compatibility; don't insert new in the mid */ struct rtw89_fw_txpwr_byrate_entry { u8 band; diff --git a/drivers/net/wireless/realtek/rtw89/mac.c b/drivers/net/wireless/realtek/rtw89/mac.c index a37c6d525d6f..3f38f8ed6876 100644 --- a/drivers/net/wireless/realtek/rtw89/mac.c +++ b/drivers/net/wireless/realtek/rtw89/mac.c @@ -1495,6 +1495,21 @@ static int rtw89_mac_power_switch(struct rtw89_dev *rtwdev, bool on) #undef PWR_ACT } +int rtw89_mac_pwr_on(struct rtw89_dev *rtwdev) +{ + int ret; + + ret = rtw89_mac_power_switch(rtwdev, true); + if (ret) { + rtw89_mac_power_switch(rtwdev, false); + ret = rtw89_mac_power_switch(rtwdev, true); + if (ret) + return ret; + } + + return 0; +} + void rtw89_mac_pwr_off(struct rtw89_dev *rtwdev) { rtw89_mac_power_switch(rtwdev, false); @@ -3996,14 +4011,6 @@ int rtw89_mac_partial_init(struct rtw89_dev *rtwdev, bool include_bb) { int ret; - ret = rtw89_mac_power_switch(rtwdev, true); - if (ret) { - rtw89_mac_power_switch(rtwdev, false); - ret = rtw89_mac_power_switch(rtwdev, true); - if (ret) - return ret; - } - rtw89_mac_ctrl_hci_dma_trx(rtwdev, true); if (include_bb) { @@ -4036,6 +4043,10 @@ int rtw89_mac_init(struct rtw89_dev *rtwdev) bool include_bb = !!chip->bbmcu_nr; int ret; + ret = rtw89_mac_pwr_on(rtwdev); + if (ret) + return ret; + ret = rtw89_mac_partial_init(rtwdev, include_bb); if (ret) goto fail; @@ -4067,7 +4078,7 @@ int rtw89_mac_init(struct rtw89_dev *rtwdev) return ret; fail: - rtw89_mac_power_switch(rtwdev, false); + rtw89_mac_pwr_off(rtwdev); return ret; } @@ -6031,7 +6042,7 @@ int rtw89_mac_cfg_ctrl_path_v1(struct rtw89_dev *rtwdev, bool wl) if (wl) return 0; - for (i = 0; i < RTW89_PHY_MAX; i++) { + for (i = 0; i < RTW89_PHY_NUM; i++) { g[i].gnt_bt_sw_en = 1; g[i].gnt_bt = 1; g[i].gnt_wl_sw_en = 1; diff --git a/drivers/net/wireless/realtek/rtw89/mac.h b/drivers/net/wireless/realtek/rtw89/mac.h index 8edea96d037f..6389f54264e5 100644 --- a/drivers/net/wireless/realtek/rtw89/mac.h +++ b/drivers/net/wireless/realtek/rtw89/mac.h @@ -1145,6 +1145,7 @@ rtw89_write32_port_set(struct rtw89_dev *rtwdev, struct rtw89_vif_link *rtwvif_l rtw89_write32_set(rtwdev, reg, bit); } +int rtw89_mac_pwr_on(struct rtw89_dev *rtwdev); void rtw89_mac_pwr_off(struct rtw89_dev *rtwdev); int rtw89_mac_partial_init(struct rtw89_dev *rtwdev, bool include_bb); int rtw89_mac_init(struct rtw89_dev *rtwdev); diff --git a/drivers/net/wireless/realtek/rtw89/mac80211.c b/drivers/net/wireless/realtek/rtw89/mac80211.c index b3669e0074df..778ca8589284 100644 --- a/drivers/net/wireless/realtek/rtw89/mac80211.c +++ b/drivers/net/wireless/realtek/rtw89/mac80211.c @@ -57,32 +57,30 @@ static void rtw89_ops_wake_tx_queue(struct ieee80211_hw *hw, static int rtw89_ops_start(struct ieee80211_hw *hw) { struct rtw89_dev *rtwdev = hw->priv; - int ret; - mutex_lock(&rtwdev->mutex); - ret = rtw89_core_start(rtwdev); - mutex_unlock(&rtwdev->mutex); + lockdep_assert_wiphy(hw->wiphy); - return ret; + return rtw89_core_start(rtwdev); } static void rtw89_ops_stop(struct ieee80211_hw *hw, bool suspend) { struct rtw89_dev *rtwdev = hw->priv; - mutex_lock(&rtwdev->mutex); + lockdep_assert_wiphy(hw->wiphy); + rtw89_core_stop(rtwdev); - mutex_unlock(&rtwdev->mutex); } static int rtw89_ops_config(struct ieee80211_hw *hw, u32 changed) { struct rtw89_dev *rtwdev = hw->priv; + lockdep_assert_wiphy(hw->wiphy); + /* let previous ips work finish to ensure we don't leave ips twice */ - cancel_work_sync(&rtwdev->ips_work); + wiphy_work_cancel(hw->wiphy, &rtwdev->ips_work); - mutex_lock(&rtwdev->mutex); rtw89_leave_ps_mode(rtwdev); if ((changed & IEEE80211_CONF_CHANGE_IDLE) && @@ -100,8 +98,6 @@ static int rtw89_ops_config(struct ieee80211_hw *hw, u32 changed) !rtwdev->scanning) rtw89_enter_ips(rtwdev); - mutex_unlock(&rtwdev->mutex); - return 0; } @@ -115,7 +111,7 @@ static int __rtw89_ops_add_iface_link(struct rtw89_dev *rtwdev, rtw89_vif_type_mapping(rtwvif_link, false); - INIT_WORK(&rtwvif_link->update_beacon_work, rtw89_core_update_beacon_work); + wiphy_work_init(&rtwvif_link->update_beacon_work, rtw89_core_update_beacon_work); INIT_LIST_HEAD(&rtwvif_link->general_pkt_list); rtwvif_link->hit_rule = 0; @@ -142,9 +138,9 @@ static int __rtw89_ops_add_iface_link(struct rtw89_dev *rtwdev, static void __rtw89_ops_remove_iface_link(struct rtw89_dev *rtwdev, struct rtw89_vif_link *rtwvif_link) { - mutex_unlock(&rtwdev->mutex); - cancel_work_sync(&rtwvif_link->update_beacon_work); - mutex_lock(&rtwdev->mutex); + lockdep_assert_wiphy(rtwdev->hw->wiphy); + + wiphy_work_cancel(rtwdev->hw->wiphy, &rtwvif_link->update_beacon_work); rtw89_leave_ps_mode(rtwdev); @@ -162,11 +158,11 @@ static int rtw89_ops_add_interface(struct ieee80211_hw *hw, u8 mac_id, port; int ret = 0; + lockdep_assert_wiphy(hw->wiphy); + rtw89_debug(rtwdev, RTW89_DBG_STATE, "add vif %pM type %d, p2p %d\n", vif->addr, vif->type, vif->p2p); - mutex_lock(&rtwdev->mutex); - rtw89_leave_ips_by_hwflags(rtwdev); if (RTW89_CHK_FW_FEATURE(BEACON_FILTER, &rtwdev->fw)) @@ -174,10 +170,8 @@ static int rtw89_ops_add_interface(struct ieee80211_hw *hw, IEEE80211_VIF_SUPPORTS_CQM_RSSI; mac_id = rtw89_acquire_mac_id(rtwdev); - if (mac_id == RTW89_MAX_MAC_ID_NUM) { - ret = -ENOSPC; - goto err; - } + if (mac_id == RTW89_MAX_MAC_ID_NUM) + return -ENOSPC; port = rtw89_core_acquire_bit_map(rtwdev->hw_port, RTW89_PORT_NUM); if (port == RTW89_PORT_NUM) { @@ -198,7 +192,7 @@ static int rtw89_ops_add_interface(struct ieee80211_hw *hw, rtwvif->offchan = false; rtwvif->roc.state = RTW89_ROC_IDLE; - INIT_DELAYED_WORK(&rtwvif->roc.roc_work, rtw89_roc_work); + wiphy_delayed_work_init(&rtwvif->roc.roc_work, rtw89_roc_work); rtw89_traffic_stats_init(rtwdev, &rtwvif->stats); @@ -213,8 +207,6 @@ static int rtw89_ops_add_interface(struct ieee80211_hw *hw, goto unset_link; rtw89_recalc_lps(rtwdev); - - mutex_unlock(&rtwdev->mutex); return 0; unset_link: @@ -224,8 +216,6 @@ release_port: rtw89_core_release_bit_map(rtwdev->hw_port, port); release_macid: rtw89_release_mac_id(rtwdev, mac_id); -err: - mutex_unlock(&rtwdev->mutex); return ret; } @@ -239,12 +229,12 @@ static void rtw89_ops_remove_interface(struct ieee80211_hw *hw, u8 port = rtw89_vif_get_main_port(rtwvif); struct rtw89_vif_link *rtwvif_link; + lockdep_assert_wiphy(hw->wiphy); + rtw89_debug(rtwdev, RTW89_DBG_STATE, "remove vif %pM type %d p2p %d\n", vif->addr, vif->type, vif->p2p); - cancel_delayed_work_sync(&rtwvif->roc.roc_work); - - mutex_lock(&rtwdev->mutex); + wiphy_delayed_work_cancel(hw->wiphy, &rtwvif->roc.roc_work); rtwvif_link = rtwvif->links[RTW89_VIF_IDLE_LINK_ID]; if (unlikely(!rtwvif_link)) { @@ -265,8 +255,6 @@ bottom: rtw89_recalc_lps(rtwdev); rtw89_enter_ips_by_hwflags(rtwdev); - - mutex_unlock(&rtwdev->mutex); } static int rtw89_ops_change_interface(struct ieee80211_hw *hw, @@ -304,7 +292,8 @@ static void rtw89_ops_configure_filter(struct ieee80211_hw *hw, const struct rtw89_mac_gen_def *mac = rtwdev->chip->mac_def; u32 rx_fltr; - mutex_lock(&rtwdev->mutex); + lockdep_assert_wiphy(hw->wiphy); + rtw89_leave_ps_mode(rtwdev); *new_flags &= FIF_ALLMULTI | FIF_OTHER_BSS | FIF_FCSFAIL | @@ -367,14 +356,11 @@ static void rtw89_ops_configure_filter(struct ieee80211_hw *hw, B_AX_RX_FLTR_CFG_MASK, rx_fltr); if (!rtwdev->dbcc_en) - goto out; + return; rtw89_write32_mask(rtwdev, rtw89_mac_reg_by_idx(rtwdev, mac->rx_fltr, RTW89_MAC_1), B_AX_RX_FLTR_CFG_MASK, rx_fltr); - -out: - mutex_unlock(&rtwdev->mutex); } static const u8 ac_to_fw_idx[IEEE80211_NUM_ACS] = { @@ -689,7 +675,8 @@ static void rtw89_ops_vif_cfg_changed(struct ieee80211_hw *hw, struct rtw89_dev *rtwdev = hw->priv; struct rtw89_vif *rtwvif = vif_to_rtwvif(vif); - mutex_lock(&rtwdev->mutex); + lockdep_assert_wiphy(hw->wiphy); + rtw89_leave_ps_mode(rtwdev); if (changed & BSS_CHANGED_ASSOC) { @@ -712,8 +699,6 @@ static void rtw89_ops_vif_cfg_changed(struct ieee80211_hw *hw, if (changed & BSS_CHANGED_ARP_FILTER) rtwvif->ip_addr = vif->cfg.arp_addr_list[0]; - - mutex_unlock(&rtwdev->mutex); } static void rtw89_ops_link_info_changed(struct ieee80211_hw *hw, @@ -725,7 +710,8 @@ static void rtw89_ops_link_info_changed(struct ieee80211_hw *hw, struct rtw89_vif *rtwvif = vif_to_rtwvif(vif); struct rtw89_vif_link *rtwvif_link; - mutex_lock(&rtwdev->mutex); + lockdep_assert_wiphy(hw->wiphy); + rtw89_leave_ps_mode(rtwdev); rtwvif_link = rtwvif->links[conf->link_id]; @@ -733,7 +719,7 @@ static void rtw89_ops_link_info_changed(struct ieee80211_hw *hw, rtw89_err(rtwdev, "%s: rtwvif link (link_id %u) is not active\n", __func__, conf->link_id); - goto out; + return; } if (changed & BSS_CHANGED_BSSID) { @@ -763,9 +749,6 @@ static void rtw89_ops_link_info_changed(struct ieee80211_hw *hw, if (changed & BSS_CHANGED_TPE) rtw89_reg_6ghz_recalc(rtwdev, rtwvif_link, true); - -out: - mutex_unlock(&rtwdev->mutex); } static int rtw89_ops_start_ap(struct ieee80211_hw *hw, @@ -778,22 +761,19 @@ static int rtw89_ops_start_ap(struct ieee80211_hw *hw, const struct rtw89_chan *chan; int ret = 0; - mutex_lock(&rtwdev->mutex); + lockdep_assert_wiphy(hw->wiphy); rtwvif_link = rtwvif->links[link_conf->link_id]; if (unlikely(!rtwvif_link)) { rtw89_err(rtwdev, "%s: rtwvif link (link_id %u) is not active\n", __func__, link_conf->link_id); - ret = -ENOLINK; - goto out; + return -ENOLINK; } chan = rtw89_chan_get(rtwdev, rtwvif_link->chanctx_idx); - if (chan->band_type == RTW89_BAND_6G) { - mutex_unlock(&rtwdev->mutex); + if (chan->band_type == RTW89_BAND_6G) return -EOPNOTSUPP; - } if (rtwdev->scanning) rtw89_hw_scan_abort(rtwdev, rtwdev->scan_info.scanning_vif); @@ -810,15 +790,12 @@ static int rtw89_ops_start_ap(struct ieee80211_hw *hw, if (RTW89_CHK_FW_FEATURE(NOTIFY_AP_INFO, &rtwdev->fw)) { ret = rtw89_fw_h2c_ap_info_refcount(rtwdev, true); if (ret) - goto out; + return ret; } rtw89_queue_chanctx_work(rtwdev); -out: - mutex_unlock(&rtwdev->mutex); - - return ret; + return 0; } static @@ -829,14 +806,14 @@ void rtw89_ops_stop_ap(struct ieee80211_hw *hw, struct ieee80211_vif *vif, struct rtw89_vif *rtwvif = vif_to_rtwvif(vif); struct rtw89_vif_link *rtwvif_link; - mutex_lock(&rtwdev->mutex); + lockdep_assert_wiphy(hw->wiphy); rtwvif_link = rtwvif->links[link_conf->link_id]; if (unlikely(!rtwvif_link)) { rtw89_err(rtwdev, "%s: rtwvif link (link_id %u) is not active\n", __func__, link_conf->link_id); - goto out; + return; } if (RTW89_CHK_FW_FEATURE(NOTIFY_AP_INFO, &rtwdev->fw)) @@ -845,22 +822,18 @@ void rtw89_ops_stop_ap(struct ieee80211_hw *hw, struct ieee80211_vif *vif, rtw89_mac_stop_ap(rtwdev, rtwvif_link); rtw89_chip_h2c_assoc_cmac_tbl(rtwdev, rtwvif_link, NULL); rtw89_fw_h2c_join_info(rtwdev, rtwvif_link, NULL, true); - -out: - mutex_unlock(&rtwdev->mutex); } static int rtw89_ops_set_tim(struct ieee80211_hw *hw, struct ieee80211_sta *sta, bool set) { - struct rtw89_dev *rtwdev = hw->priv; struct rtw89_sta *rtwsta = sta_to_rtwsta(sta); struct rtw89_vif *rtwvif = rtwsta->rtwvif; struct rtw89_vif_link *rtwvif_link; unsigned int link_id; rtw89_vif_for_each_link(rtwvif, rtwvif_link, link_id) - ieee80211_queue_work(rtwdev->hw, &rtwvif_link->update_beacon_work); + wiphy_work_queue(hw->wiphy, &rtwvif_link->update_beacon_work); return 0; } @@ -873,9 +846,9 @@ static int rtw89_ops_conf_tx(struct ieee80211_hw *hw, struct rtw89_dev *rtwdev = hw->priv; struct rtw89_vif *rtwvif = vif_to_rtwvif(vif); struct rtw89_vif_link *rtwvif_link; - int ret = 0; - mutex_lock(&rtwdev->mutex); + lockdep_assert_wiphy(hw->wiphy); + rtw89_leave_ps_mode(rtwdev); rtwvif_link = rtwvif->links[link_id]; @@ -883,17 +856,13 @@ static int rtw89_ops_conf_tx(struct ieee80211_hw *hw, rtw89_err(rtwdev, "%s: rtwvif link (link_id %u) is not active\n", __func__, link_id); - ret = -ENOLINK; - goto out; + return -ENOLINK; } rtwvif_link->tx_params[ac] = *params; __rtw89_conf_tx(rtwdev, rtwvif_link, ac); -out: - mutex_unlock(&rtwdev->mutex); - - return ret; + return 0; } static int __rtw89_ops_sta_state(struct ieee80211_hw *hw, @@ -937,14 +906,11 @@ static int rtw89_ops_sta_state(struct ieee80211_hw *hw, enum ieee80211_sta_state new_state) { struct rtw89_dev *rtwdev = hw->priv; - int ret; - mutex_lock(&rtwdev->mutex); - rtw89_leave_ps_mode(rtwdev); - ret = __rtw89_ops_sta_state(hw, vif, sta, old_state, new_state); - mutex_unlock(&rtwdev->mutex); + lockdep_assert_wiphy(hw->wiphy); - return ret; + rtw89_leave_ps_mode(rtwdev); + return __rtw89_ops_sta_state(hw, vif, sta, old_state, new_state); } static int rtw89_ops_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd, @@ -953,9 +919,10 @@ static int rtw89_ops_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd, struct ieee80211_key_conf *key) { struct rtw89_dev *rtwdev = hw->priv; - int ret = 0; + int ret; + + lockdep_assert_wiphy(hw->wiphy); - mutex_lock(&rtwdev->mutex); rtw89_leave_ps_mode(rtwdev); switch (cmd) { @@ -964,7 +931,7 @@ static int rtw89_ops_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd, ret = rtw89_cam_sec_key_add(rtwdev, vif, sta, key); if (ret && ret != -EOPNOTSUPP) { rtw89_err(rtwdev, "failed to add key to sec cam\n"); - goto out; + return ret; } break; case DISABLE_KEY: @@ -974,14 +941,11 @@ static int rtw89_ops_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd, ret = rtw89_cam_sec_key_del(rtwdev, vif, sta, key, true); if (ret) { rtw89_err(rtwdev, "failed to remove key from sec cam\n"); - goto out; + return ret; } break; } -out: - mutex_unlock(&rtwdev->mutex); - return ret; } @@ -997,38 +961,32 @@ static int rtw89_ops_ampdu_action(struct ieee80211_hw *hw, struct ieee80211_txq *txq = sta->txq[tid]; struct rtw89_txq *rtwtxq = (struct rtw89_txq *)txq->drv_priv; + lockdep_assert_wiphy(rtwdev->hw->wiphy); + switch (params->action) { case IEEE80211_AMPDU_TX_START: return IEEE80211_AMPDU_TX_START_IMMEDIATE; case IEEE80211_AMPDU_TX_STOP_CONT: case IEEE80211_AMPDU_TX_STOP_FLUSH: case IEEE80211_AMPDU_TX_STOP_FLUSH_CONT: - mutex_lock(&rtwdev->mutex); clear_bit(RTW89_TXQ_F_AMPDU, &rtwtxq->flags); clear_bit(tid, rtwsta->ampdu_map); rtw89_chip_h2c_ampdu_cmac_tbl(rtwdev, rtwvif, rtwsta); - mutex_unlock(&rtwdev->mutex); ieee80211_stop_tx_ba_cb_irqsafe(vif, sta->addr, tid); break; case IEEE80211_AMPDU_TX_OPERATIONAL: - mutex_lock(&rtwdev->mutex); set_bit(RTW89_TXQ_F_AMPDU, &rtwtxq->flags); rtwsta->ampdu_params[tid].agg_num = params->buf_size; rtwsta->ampdu_params[tid].amsdu = params->amsdu; set_bit(tid, rtwsta->ampdu_map); rtw89_leave_ps_mode(rtwdev); rtw89_chip_h2c_ampdu_cmac_tbl(rtwdev, rtwvif, rtwsta); - mutex_unlock(&rtwdev->mutex); break; case IEEE80211_AMPDU_RX_START: - mutex_lock(&rtwdev->mutex); rtw89_chip_h2c_ba_cam(rtwdev, rtwsta, true, params); - mutex_unlock(&rtwdev->mutex); break; case IEEE80211_AMPDU_RX_STOP: - mutex_lock(&rtwdev->mutex); rtw89_chip_h2c_ba_cam(rtwdev, rtwsta, false, params); - mutex_unlock(&rtwdev->mutex); break; default: WARN_ON(1); @@ -1042,11 +1000,11 @@ static int rtw89_ops_set_rts_threshold(struct ieee80211_hw *hw, u32 value) { struct rtw89_dev *rtwdev = hw->priv; - mutex_lock(&rtwdev->mutex); + lockdep_assert_wiphy(hw->wiphy); + rtw89_leave_ps_mode(rtwdev); if (test_bit(RTW89_FLAG_POWERON, rtwdev->flags)) rtw89_mac_update_rts_threshold(rtwdev); - mutex_unlock(&rtwdev->mutex); return 0; } @@ -1086,7 +1044,8 @@ static void rtw89_ops_flush(struct ieee80211_hw *hw, struct ieee80211_vif *vif, { struct rtw89_dev *rtwdev = hw->priv; - mutex_lock(&rtwdev->mutex); + lockdep_assert_wiphy(hw->wiphy); + rtw89_leave_lps(rtwdev); rtw89_hci_flush_queues(rtwdev, queues, drop); @@ -1094,8 +1053,6 @@ static void rtw89_ops_flush(struct ieee80211_hw *hw, struct ieee80211_vif *vif, __rtw89_drop_packets(rtwdev, vif); else rtw89_mac_flush_txq(rtwdev, queues, drop); - - mutex_unlock(&rtwdev->mutex); } struct rtw89_iter_bitrate_mask_data { @@ -1142,10 +1099,10 @@ static int rtw89_ops_set_bitrate_mask(struct ieee80211_hw *hw, { struct rtw89_dev *rtwdev = hw->priv; - mutex_lock(&rtwdev->mutex); + lockdep_assert_wiphy(hw->wiphy); + rtw89_phy_rate_pattern_vif(rtwdev, vif, mask); rtw89_ra_mask_info_update(rtwdev, vif, mask); - mutex_unlock(&rtwdev->mutex); return 0; } @@ -1156,6 +1113,8 @@ int rtw89_ops_set_antenna(struct ieee80211_hw *hw, u32 tx_ant, u32 rx_ant) struct rtw89_dev *rtwdev = hw->priv; struct rtw89_hal *hal = &rtwdev->hal; + lockdep_assert_wiphy(hw->wiphy); + if (hal->ant_diversity) { if (tx_ant != rx_ant || hweight32(tx_ant) != 1) return -EINVAL; @@ -1163,12 +1122,10 @@ int rtw89_ops_set_antenna(struct ieee80211_hw *hw, u32 tx_ant, u32 rx_ant) return -EINVAL; } - mutex_lock(&rtwdev->mutex); hal->antenna_tx = tx_ant; hal->antenna_rx = rx_ant; hal->tx_path_diversity = false; hal->ant_diversity_fixed = true; - mutex_unlock(&rtwdev->mutex); return 0; } @@ -1193,18 +1150,15 @@ static void rtw89_ops_sw_scan_start(struct ieee80211_hw *hw, struct rtw89_vif *rtwvif = vif_to_rtwvif(vif); struct rtw89_vif_link *rtwvif_link; - mutex_lock(&rtwdev->mutex); + lockdep_assert_wiphy(hw->wiphy); rtwvif_link = rtw89_vif_get_link_inst(rtwvif, 0); if (unlikely(!rtwvif_link)) { rtw89_err(rtwdev, "sw scan start: find no link on HW-0\n"); - goto out; + return; } rtw89_core_scan_start(rtwdev, rtwvif_link, mac_addr, false); - -out: - mutex_unlock(&rtwdev->mutex); } static void rtw89_ops_sw_scan_complete(struct ieee80211_hw *hw, @@ -1214,18 +1168,15 @@ static void rtw89_ops_sw_scan_complete(struct ieee80211_hw *hw, struct rtw89_vif *rtwvif = vif_to_rtwvif(vif); struct rtw89_vif_link *rtwvif_link; - mutex_lock(&rtwdev->mutex); + lockdep_assert_wiphy(hw->wiphy); rtwvif_link = rtw89_vif_get_link_inst(rtwvif, 0); if (unlikely(!rtwvif_link)) { rtw89_err(rtwdev, "sw scan complete: find no link on HW-0\n"); - goto out; + return; } rtw89_core_scan_complete(rtwdev, rtwvif_link, false); - -out: - mutex_unlock(&rtwdev->mutex); } static void rtw89_ops_reconfig_complete(struct ieee80211_hw *hw, @@ -1245,21 +1196,18 @@ static int rtw89_ops_hw_scan(struct ieee80211_hw *hw, struct ieee80211_vif *vif, struct rtw89_vif_link *rtwvif_link; int ret; + lockdep_assert_wiphy(hw->wiphy); + if (!RTW89_CHK_FW_FEATURE(SCAN_OFFLOAD, &rtwdev->fw)) return 1; - mutex_lock(&rtwdev->mutex); - - if (rtwdev->scanning || rtwvif->offchan) { - ret = -EBUSY; - goto out; - } + if (rtwdev->scanning || rtwvif->offchan) + return -EBUSY; rtwvif_link = rtw89_vif_get_link_inst(rtwvif, 0); if (unlikely(!rtwvif_link)) { rtw89_err(rtwdev, "hw scan: find no link on HW-0\n"); - ret = -ENOLINK; - goto out; + return -ENOLINK; } rtw89_hw_scan_start(rtwdev, rtwvif_link, req); @@ -1269,9 +1217,6 @@ static int rtw89_ops_hw_scan(struct ieee80211_hw *hw, struct ieee80211_vif *vif, rtw89_err(rtwdev, "HW scan failed with status: %d\n", ret); } -out: - mutex_unlock(&rtwdev->mutex); - return ret; } @@ -1282,24 +1227,21 @@ static void rtw89_ops_cancel_hw_scan(struct ieee80211_hw *hw, struct rtw89_vif *rtwvif = vif_to_rtwvif(vif); struct rtw89_vif_link *rtwvif_link; + lockdep_assert_wiphy(hw->wiphy); + if (!RTW89_CHK_FW_FEATURE(SCAN_OFFLOAD, &rtwdev->fw)) return; - mutex_lock(&rtwdev->mutex); - if (!rtwdev->scanning) - goto out; + return; rtwvif_link = rtw89_vif_get_link_inst(rtwvif, 0); if (unlikely(!rtwvif_link)) { rtw89_err(rtwdev, "cancel hw scan: find no link on HW-0\n"); - goto out; + return; } rtw89_hw_scan_abort(rtwdev, rtwvif_link); - -out: - mutex_unlock(&rtwdev->mutex); } static void rtw89_ops_sta_rc_update(struct ieee80211_hw *hw, @@ -1322,13 +1264,10 @@ static int rtw89_ops_add_chanctx(struct ieee80211_hw *hw, struct ieee80211_chanctx_conf *ctx) { struct rtw89_dev *rtwdev = hw->priv; - int ret; - mutex_lock(&rtwdev->mutex); - ret = rtw89_chanctx_ops_add(rtwdev, ctx); - mutex_unlock(&rtwdev->mutex); + lockdep_assert_wiphy(hw->wiphy); - return ret; + return rtw89_chanctx_ops_add(rtwdev, ctx); } static void rtw89_ops_remove_chanctx(struct ieee80211_hw *hw, @@ -1336,9 +1275,9 @@ static void rtw89_ops_remove_chanctx(struct ieee80211_hw *hw, { struct rtw89_dev *rtwdev = hw->priv; - mutex_lock(&rtwdev->mutex); + lockdep_assert_wiphy(hw->wiphy); + rtw89_chanctx_ops_remove(rtwdev, ctx); - mutex_unlock(&rtwdev->mutex); } static void rtw89_ops_change_chanctx(struct ieee80211_hw *hw, @@ -1347,9 +1286,9 @@ static void rtw89_ops_change_chanctx(struct ieee80211_hw *hw, { struct rtw89_dev *rtwdev = hw->priv; - mutex_lock(&rtwdev->mutex); + lockdep_assert_wiphy(hw->wiphy); + rtw89_chanctx_ops_change(rtwdev, ctx, changed); - mutex_unlock(&rtwdev->mutex); } static int rtw89_ops_assign_vif_chanctx(struct ieee80211_hw *hw, @@ -1360,25 +1299,18 @@ static int rtw89_ops_assign_vif_chanctx(struct ieee80211_hw *hw, struct rtw89_dev *rtwdev = hw->priv; struct rtw89_vif *rtwvif = vif_to_rtwvif(vif); struct rtw89_vif_link *rtwvif_link; - int ret; - mutex_lock(&rtwdev->mutex); + lockdep_assert_wiphy(hw->wiphy); rtwvif_link = rtwvif->links[link_conf->link_id]; if (unlikely(!rtwvif_link)) { rtw89_err(rtwdev, "%s: rtwvif link (link_id %u) is not active\n", __func__, link_conf->link_id); - ret = -ENOLINK; - goto out; + return -ENOLINK; } - ret = rtw89_chanctx_ops_assign_vif(rtwdev, rtwvif_link, ctx); - -out: - mutex_unlock(&rtwdev->mutex); - - return ret; + return rtw89_chanctx_ops_assign_vif(rtwdev, rtwvif_link, ctx); } static void rtw89_ops_unassign_vif_chanctx(struct ieee80211_hw *hw, @@ -1390,11 +1322,10 @@ static void rtw89_ops_unassign_vif_chanctx(struct ieee80211_hw *hw, struct rtw89_vif *rtwvif = vif_to_rtwvif(vif); struct rtw89_vif_link *rtwvif_link; - mutex_lock(&rtwdev->mutex); + lockdep_assert_wiphy(hw->wiphy); rtwvif_link = rtwvif->links[link_conf->link_id]; if (unlikely(!rtwvif_link)) { - mutex_unlock(&rtwdev->mutex); rtw89_err(rtwdev, "%s: rtwvif link (link_id %u) is not active\n", __func__, link_conf->link_id); @@ -1402,7 +1333,6 @@ static void rtw89_ops_unassign_vif_chanctx(struct ieee80211_hw *hw, } rtw89_chanctx_ops_unassign_vif(rtwdev, rtwvif_link, ctx); - mutex_unlock(&rtwdev->mutex); } static int rtw89_ops_remain_on_channel(struct ieee80211_hw *hw, @@ -1415,13 +1345,12 @@ static int rtw89_ops_remain_on_channel(struct ieee80211_hw *hw, struct rtw89_vif *rtwvif = vif_to_rtwvif_safe(vif); struct rtw89_roc *roc = &rtwvif->roc; + lockdep_assert_wiphy(hw->wiphy); + if (!rtwvif) return -EINVAL; - mutex_lock(&rtwdev->mutex); - if (roc->state != RTW89_ROC_IDLE) { - mutex_unlock(&rtwdev->mutex); return -EBUSY; } @@ -1439,8 +1368,6 @@ static int rtw89_ops_remain_on_channel(struct ieee80211_hw *hw, rtw89_roc_start(rtwdev, rtwvif); - mutex_unlock(&rtwdev->mutex); - return 0; } @@ -1450,14 +1377,14 @@ static int rtw89_ops_cancel_remain_on_channel(struct ieee80211_hw *hw, struct rtw89_dev *rtwdev = hw->priv; struct rtw89_vif *rtwvif = vif_to_rtwvif_safe(vif); + lockdep_assert_wiphy(hw->wiphy); + if (!rtwvif) return -EINVAL; - cancel_delayed_work_sync(&rtwvif->roc.roc_work); + wiphy_delayed_work_cancel(hw->wiphy, &rtwvif->roc.roc_work); - mutex_lock(&rtwdev->mutex); rtw89_roc_end(rtwdev, rtwvif); - mutex_unlock(&rtwdev->mutex); return 0; } @@ -1478,14 +1405,14 @@ static int rtw89_ops_set_tid_config(struct ieee80211_hw *hw, { struct rtw89_dev *rtwdev = hw->priv; - mutex_lock(&rtwdev->mutex); + lockdep_assert_wiphy(hw->wiphy); + if (sta) rtw89_core_set_tid_config(rtwdev, sta, tid_config); else ieee80211_iterate_stations_atomic(rtwdev->hw, rtw89_set_tid_config_iter, tid_config); - mutex_unlock(&rtwdev->mutex); return 0; } @@ -1509,7 +1436,7 @@ static bool rtw89_ops_can_activate_links(struct ieee80211_hw *hw, { struct rtw89_dev *rtwdev = hw->priv; - guard(mutex)(&rtwdev->mutex); + lockdep_assert_wiphy(hw->wiphy); return rtw89_can_work_on_links(rtwdev, vif, active_links); } @@ -1571,7 +1498,7 @@ int rtw89_ops_change_vif_links(struct ieee80211_hw *hw, int ret = 0; int i; - guard(mutex)(&rtwdev->mutex); + lockdep_assert_wiphy(hw->wiphy); rtw89_debug(rtwdev, RTW89_DBG_STATE, "%s: old_links (0x%08x) -> new_links (0x%08x)\n", @@ -1720,7 +1647,7 @@ int rtw89_ops_change_sta_links(struct ieee80211_hw *hw, unsigned long set_links = new_links & ~old_links; int ret = 0; - guard(mutex)(&rtwdev->mutex); + lockdep_assert_wiphy(hw->wiphy); rtw89_debug(rtwdev, RTW89_DBG_STATE, "%s: old_links (0x%08x) -> new_links (0x%08x)\n", @@ -1750,13 +1677,12 @@ static int rtw89_ops_suspend(struct ieee80211_hw *hw, struct rtw89_dev *rtwdev = hw->priv; int ret; + lockdep_assert_wiphy(hw->wiphy); + set_bit(RTW89_FLAG_FORBIDDEN_TRACK_WROK, rtwdev->flags); - cancel_delayed_work_sync(&rtwdev->track_work); + wiphy_delayed_work_cancel(hw->wiphy, &rtwdev->track_work); - mutex_lock(&rtwdev->mutex); ret = rtw89_wow_suspend(rtwdev, wowlan); - mutex_unlock(&rtwdev->mutex); - if (ret) { rtw89_warn(rtwdev, "failed to suspend for wow %d\n", ret); clear_bit(RTW89_FLAG_FORBIDDEN_TRACK_WROK, rtwdev->flags); @@ -1771,15 +1697,15 @@ static int rtw89_ops_resume(struct ieee80211_hw *hw) struct rtw89_dev *rtwdev = hw->priv; int ret; - mutex_lock(&rtwdev->mutex); + lockdep_assert_wiphy(hw->wiphy); + ret = rtw89_wow_resume(rtwdev); if (ret) rtw89_warn(rtwdev, "failed to resume for wow %d\n", ret); - mutex_unlock(&rtwdev->mutex); clear_bit(RTW89_FLAG_FORBIDDEN_TRACK_WROK, rtwdev->flags); - ieee80211_queue_delayed_work(rtwdev->hw, &rtwdev->track_work, - RTW89_TRACK_WORK_PERIOD); + wiphy_delayed_work_queue(hw->wiphy, &rtwdev->track_work, + RTW89_TRACK_WORK_PERIOD); return ret ? 1 : 0; } @@ -1799,18 +1725,16 @@ static void rtw89_set_rekey_data(struct ieee80211_hw *hw, struct rtw89_wow_param *rtw_wow = &rtwdev->wow; struct rtw89_wow_gtk_info *gtk_info = &rtw_wow->gtk_info; + lockdep_assert_wiphy(hw->wiphy); + if (data->kek_len > sizeof(gtk_info->kek) || data->kck_len > sizeof(gtk_info->kck)) { rtw89_warn(rtwdev, "kek or kck length over fw limit\n"); return; } - mutex_lock(&rtwdev->mutex); - memcpy(gtk_info->kek, data->kek, data->kek_len); memcpy(gtk_info->kck, data->kck, data->kck_len); - - mutex_unlock(&rtwdev->mutex); } #endif @@ -1818,16 +1742,13 @@ static void rtw89_ops_rfkill_poll(struct ieee80211_hw *hw) { struct rtw89_dev *rtwdev = hw->priv; - mutex_lock(&rtwdev->mutex); + lockdep_assert_wiphy(hw->wiphy); /* wl_disable GPIO get floating when entering LPS */ if (test_bit(RTW89_FLAG_RUNNING, rtwdev->flags)) - goto out; + return; rtw89_core_rfkill_poll(rtwdev, false); - -out: - mutex_unlock(&rtwdev->mutex); } const struct ieee80211_ops rtw89_ops = { diff --git a/drivers/net/wireless/realtek/rtw89/mac_be.c b/drivers/net/wireless/realtek/rtw89/mac_be.c index 2dbdeae904ad..16ee378c5418 100644 --- a/drivers/net/wireless/realtek/rtw89/mac_be.c +++ b/drivers/net/wireless/realtek/rtw89/mac_be.c @@ -1865,7 +1865,7 @@ int rtw89_mac_cfg_ctrl_path_v2(struct rtw89_dev *rtwdev, bool wl) if (wl) return 0; - for (i = 0; i < RTW89_PHY_MAX; i++) { + for (i = 0; i < RTW89_PHY_NUM; i++) { g[i].gnt_bt_sw_en = 1; g[i].gnt_bt = 1; g[i].gnt_wl_sw_en = 1; diff --git a/drivers/net/wireless/realtek/rtw89/phy.c b/drivers/net/wireless/realtek/rtw89/phy.c index c7c05f7fda1d..e4b690a5febc 100644 --- a/drivers/net/wireless/realtek/rtw89/phy.c +++ b/drivers/net/wireless/realtek/rtw89/phy.c @@ -2070,24 +2070,28 @@ s16 rtw89_phy_ant_gain_pwr_offset(struct rtw89_dev *rtwdev, } EXPORT_SYMBOL(rtw89_phy_ant_gain_pwr_offset); -void rtw89_print_ant_gain(struct seq_file *m, struct rtw89_dev *rtwdev, - const struct rtw89_chan *chan) +int rtw89_print_ant_gain(struct rtw89_dev *rtwdev, char *buf, size_t bufsz, + const struct rtw89_chan *chan) { struct rtw89_ant_gain_info *ant_gain = &rtwdev->ant_gain; const struct rtw89_chip_info *chip = rtwdev->chip; u8 regd = rtw89_regd_get(rtwdev, chan->band_type); + char *p = buf, *end = buf + bufsz; s8 offset_patha, offset_pathb; if (!chip->support_ant_gain || !(ant_gain->regd_enabled & BIT(regd))) { - seq_puts(m, "no DAG is applied\n"); - return; + p += scnprintf(p, end - p, "no DAG is applied\n"); + goto out; } offset_patha = rtw89_phy_ant_gain_query(rtwdev, RF_PATH_A, chan->freq); offset_pathb = rtw89_phy_ant_gain_query(rtwdev, RF_PATH_B, chan->freq); - seq_printf(m, "ChainA offset: %d dBm\n", offset_patha); - seq_printf(m, "ChainB offset: %d dBm\n", offset_pathb); + p += scnprintf(p, end - p, "ChainA offset: %d dBm\n", offset_patha); + p += scnprintf(p, end - p, "ChainB offset: %d dBm\n", offset_pathb); + +out: + return p - buf; } static const u8 rtw89_rs_idx_num_ax[] = { @@ -4600,7 +4604,7 @@ static void rtw89_phy_cfo_dm(struct rtw89_dev *rtwdev) cfo->dcfo_avg = 0; rtw89_debug(rtwdev, RTW89_DBG_CFO, "CFO:total_sta_assoc=%d\n", rtwdev->total_sta_assoc); - if (rtwdev->total_sta_assoc == 0) { + if (rtwdev->total_sta_assoc == 0 || rtw89_is_mlo_1_1(rtwdev)) { rtw89_phy_cfo_reset(rtwdev); return; } @@ -4651,29 +4655,28 @@ static void rtw89_phy_cfo_dm(struct rtw89_dev *rtwdev) rtw89_phy_cfo_statistics_reset(rtwdev); } -void rtw89_phy_cfo_track_work(struct work_struct *work) +void rtw89_phy_cfo_track_work(struct wiphy *wiphy, struct wiphy_work *work) { struct rtw89_dev *rtwdev = container_of(work, struct rtw89_dev, cfo_track_work.work); struct rtw89_cfo_tracking_info *cfo = &rtwdev->cfo_tracking; - mutex_lock(&rtwdev->mutex); + lockdep_assert_wiphy(wiphy); + if (!cfo->cfo_trig_by_timer_en) - goto out; + return; rtw89_leave_ps_mode(rtwdev); rtw89_phy_cfo_dm(rtwdev); - ieee80211_queue_delayed_work(rtwdev->hw, &rtwdev->cfo_track_work, - msecs_to_jiffies(cfo->cfo_timer_ms)); -out: - mutex_unlock(&rtwdev->mutex); + wiphy_delayed_work_queue(wiphy, &rtwdev->cfo_track_work, + msecs_to_jiffies(cfo->cfo_timer_ms)); } static void rtw89_phy_cfo_start_work(struct rtw89_dev *rtwdev) { struct rtw89_cfo_tracking_info *cfo = &rtwdev->cfo_tracking; - ieee80211_queue_delayed_work(rtwdev->hw, &rtwdev->cfo_track_work, - msecs_to_jiffies(cfo->cfo_timer_ms)); + wiphy_delayed_work_queue(rtwdev->hw->wiphy, &rtwdev->cfo_track_work, + msecs_to_jiffies(cfo->cfo_timer_ms)); } void rtw89_phy_cfo_track(struct rtw89_dev *rtwdev) @@ -5115,7 +5118,6 @@ static void rtw89_phy_stat_thermal_update(struct rtw89_dev *rtwdev) struct rtw89_phy_iter_rssi_data { struct rtw89_dev *rtwdev; - struct rtw89_phy_ch_info *ch_info; bool rssi_changed; }; @@ -5123,10 +5125,15 @@ static void __rtw89_phy_stat_rssi_update_iter(struct rtw89_sta_link *rtwsta_link, struct rtw89_phy_iter_rssi_data *rssi_data) { - struct rtw89_phy_ch_info *ch_info = rssi_data->ch_info; + struct rtw89_vif_link *rtwvif_link = rtwsta_link->rtwvif_link; + struct rtw89_dev *rtwdev = rssi_data->rtwdev; + struct rtw89_phy_ch_info *ch_info; + struct rtw89_bb_ctx *bb; unsigned long rssi_curr; rssi_curr = ewma_rssi_read(&rtwsta_link->avg_rssi); + bb = rtw89_get_bb_ctx(rtwdev, rtwvif_link->phy_idx); + ch_info = &bb->ch_info; if (rssi_curr < ch_info->rssi_min) { ch_info->rssi_min = rssi_curr; @@ -5157,11 +5164,13 @@ static void rtw89_phy_stat_rssi_update_iter(void *data, static void rtw89_phy_stat_rssi_update(struct rtw89_dev *rtwdev) { - struct rtw89_phy_iter_rssi_data rssi_data = {0}; + struct rtw89_phy_iter_rssi_data rssi_data = {}; + struct rtw89_bb_ctx *bb; rssi_data.rtwdev = rtwdev; - rssi_data.ch_info = &rtwdev->ch_info; - rssi_data.ch_info->rssi_min = U8_MAX; + rtw89_for_each_active_bb(rtwdev, bb) + bb->ch_info.rssi_min = U8_MAX; + ieee80211_iterate_stations_atomic(rtwdev->hw, rtw89_phy_stat_rssi_update_iter, &rssi_data); @@ -5199,24 +5208,27 @@ void rtw89_phy_stat_track(struct rtw89_dev *rtwdev) memset(&phystat->cur_pkt_stat, 0, sizeof(phystat->cur_pkt_stat)); } -static u16 rtw89_phy_ccx_us_to_idx(struct rtw89_dev *rtwdev, u32 time_us) +static u16 rtw89_phy_ccx_us_to_idx(struct rtw89_dev *rtwdev, + struct rtw89_bb_ctx *bb, u32 time_us) { - struct rtw89_env_monitor_info *env = &rtwdev->env_monitor; + struct rtw89_env_monitor_info *env = &bb->env_monitor; return time_us >> (ilog2(CCX_US_BASE_RATIO) + env->ccx_unit_idx); } -static u32 rtw89_phy_ccx_idx_to_us(struct rtw89_dev *rtwdev, u16 idx) +static u32 rtw89_phy_ccx_idx_to_us(struct rtw89_dev *rtwdev, + struct rtw89_bb_ctx *bb, u16 idx) { - struct rtw89_env_monitor_info *env = &rtwdev->env_monitor; + struct rtw89_env_monitor_info *env = &bb->env_monitor; return idx << (ilog2(CCX_US_BASE_RATIO) + env->ccx_unit_idx); } -static void rtw89_phy_ccx_top_setting_init(struct rtw89_dev *rtwdev) +static void rtw89_phy_ccx_top_setting_init(struct rtw89_dev *rtwdev, + struct rtw89_bb_ctx *bb) { const struct rtw89_phy_gen_def *phy = rtwdev->chip->phy_def; - struct rtw89_env_monitor_info *env = &rtwdev->env_monitor; + struct rtw89_env_monitor_info *env = &bb->env_monitor; const struct rtw89_ccx_regs *ccx = phy->ccx; env->ccx_manual_ctrl = false; @@ -5225,17 +5237,20 @@ static void rtw89_phy_ccx_top_setting_init(struct rtw89_dev *rtwdev) env->ccx_period = 0; env->ccx_unit_idx = RTW89_CCX_32_US; - rtw89_phy_set_phy_regs(rtwdev, ccx->setting_addr, ccx->en_mask, 1); - rtw89_phy_set_phy_regs(rtwdev, ccx->setting_addr, ccx->trig_opt_mask, 1); - rtw89_phy_set_phy_regs(rtwdev, ccx->setting_addr, ccx->measurement_trig_mask, 1); - rtw89_phy_set_phy_regs(rtwdev, ccx->setting_addr, ccx->edcca_opt_mask, - RTW89_CCX_EDCCA_BW20_0); + rtw89_phy_write32_idx(rtwdev, ccx->setting_addr, ccx->en_mask, 1, bb->phy_idx); + rtw89_phy_write32_idx(rtwdev, ccx->setting_addr, ccx->trig_opt_mask, 1, + bb->phy_idx); + rtw89_phy_write32_idx(rtwdev, ccx->setting_addr, ccx->measurement_trig_mask, 1, + bb->phy_idx); + rtw89_phy_write32_idx(rtwdev, ccx->setting_addr, ccx->edcca_opt_mask, + RTW89_CCX_EDCCA_BW20_0, bb->phy_idx); } -static u16 rtw89_phy_ccx_get_report(struct rtw89_dev *rtwdev, u16 report, - u16 score) +static u16 rtw89_phy_ccx_get_report(struct rtw89_dev *rtwdev, + struct rtw89_bb_ctx *bb, + u16 report, u16 score) { - struct rtw89_env_monitor_info *env = &rtwdev->env_monitor; + struct rtw89_env_monitor_info *env = &bb->env_monitor; u32 numer = 0; u16 ret = 0; @@ -5275,9 +5290,10 @@ static void rtw89_phy_ccx_ms_to_period_unit(struct rtw89_dev *rtwdev, *period, *unit_idx); } -static void rtw89_phy_ccx_racing_release(struct rtw89_dev *rtwdev) +static void rtw89_phy_ccx_racing_release(struct rtw89_dev *rtwdev, + struct rtw89_bb_ctx *bb) { - struct rtw89_env_monitor_info *env = &rtwdev->env_monitor; + struct rtw89_env_monitor_info *env = &bb->env_monitor; rtw89_debug(rtwdev, RTW89_DBG_PHY_TRACK, "lv:(%d)->(0)\n", env->ccx_rac_lv); @@ -5288,9 +5304,10 @@ static void rtw89_phy_ccx_racing_release(struct rtw89_dev *rtwdev) } static bool rtw89_phy_ifs_clm_th_update_check(struct rtw89_dev *rtwdev, + struct rtw89_bb_ctx *bb, struct rtw89_ccx_para_info *para) { - struct rtw89_env_monitor_info *env = &rtwdev->env_monitor; + struct rtw89_env_monitor_info *env = &bb->env_monitor; bool is_update = env->ifs_clm_app != para->ifs_clm_app; u8 i = 0; u16 *ifs_th_l = env->ifs_clm_th_l; @@ -5325,12 +5342,12 @@ static bool rtw89_phy_ifs_clm_th_update_check(struct rtw89_dev *rtwdev, */ ifs_th_l[IFS_CLM_TH_START_IDX] = 0; ifs_th_h_us[IFS_CLM_TH_START_IDX] = ifs_th0_us; - ifs_th_h[IFS_CLM_TH_START_IDX] = rtw89_phy_ccx_us_to_idx(rtwdev, + ifs_th_h[IFS_CLM_TH_START_IDX] = rtw89_phy_ccx_us_to_idx(rtwdev, bb, ifs_th0_us); for (i = 1; i < RTW89_IFS_CLM_NUM; i++) { ifs_th_l[i] = ifs_th_h[i - 1] + 1; ifs_th_h_us[i] = ifs_th_h_us[i - 1] * ifs_th_times; - ifs_th_h[i] = rtw89_phy_ccx_us_to_idx(rtwdev, ifs_th_h_us[i]); + ifs_th_h[i] = rtw89_phy_ccx_us_to_idx(rtwdev, bb, ifs_th_h_us[i]); } ifs_update_finished: @@ -5341,30 +5358,31 @@ ifs_update_finished: return is_update; } -static void rtw89_phy_ifs_clm_set_th_reg(struct rtw89_dev *rtwdev) +static void rtw89_phy_ifs_clm_set_th_reg(struct rtw89_dev *rtwdev, + struct rtw89_bb_ctx *bb) { const struct rtw89_phy_gen_def *phy = rtwdev->chip->phy_def; - struct rtw89_env_monitor_info *env = &rtwdev->env_monitor; + struct rtw89_env_monitor_info *env = &bb->env_monitor; const struct rtw89_ccx_regs *ccx = phy->ccx; u8 i = 0; - rtw89_phy_set_phy_regs(rtwdev, ccx->ifs_t1_addr, ccx->ifs_t1_th_l_mask, - env->ifs_clm_th_l[0]); - rtw89_phy_set_phy_regs(rtwdev, ccx->ifs_t2_addr, ccx->ifs_t2_th_l_mask, - env->ifs_clm_th_l[1]); - rtw89_phy_set_phy_regs(rtwdev, ccx->ifs_t3_addr, ccx->ifs_t3_th_l_mask, - env->ifs_clm_th_l[2]); - rtw89_phy_set_phy_regs(rtwdev, ccx->ifs_t4_addr, ccx->ifs_t4_th_l_mask, - env->ifs_clm_th_l[3]); - - rtw89_phy_set_phy_regs(rtwdev, ccx->ifs_t1_addr, ccx->ifs_t1_th_h_mask, - env->ifs_clm_th_h[0]); - rtw89_phy_set_phy_regs(rtwdev, ccx->ifs_t2_addr, ccx->ifs_t2_th_h_mask, - env->ifs_clm_th_h[1]); - rtw89_phy_set_phy_regs(rtwdev, ccx->ifs_t3_addr, ccx->ifs_t3_th_h_mask, - env->ifs_clm_th_h[2]); - rtw89_phy_set_phy_regs(rtwdev, ccx->ifs_t4_addr, ccx->ifs_t4_th_h_mask, - env->ifs_clm_th_h[3]); + rtw89_phy_write32_idx(rtwdev, ccx->ifs_t1_addr, ccx->ifs_t1_th_l_mask, + env->ifs_clm_th_l[0], bb->phy_idx); + rtw89_phy_write32_idx(rtwdev, ccx->ifs_t2_addr, ccx->ifs_t2_th_l_mask, + env->ifs_clm_th_l[1], bb->phy_idx); + rtw89_phy_write32_idx(rtwdev, ccx->ifs_t3_addr, ccx->ifs_t3_th_l_mask, + env->ifs_clm_th_l[2], bb->phy_idx); + rtw89_phy_write32_idx(rtwdev, ccx->ifs_t4_addr, ccx->ifs_t4_th_l_mask, + env->ifs_clm_th_l[3], bb->phy_idx); + + rtw89_phy_write32_idx(rtwdev, ccx->ifs_t1_addr, ccx->ifs_t1_th_h_mask, + env->ifs_clm_th_h[0], bb->phy_idx); + rtw89_phy_write32_idx(rtwdev, ccx->ifs_t2_addr, ccx->ifs_t2_th_h_mask, + env->ifs_clm_th_h[1], bb->phy_idx); + rtw89_phy_write32_idx(rtwdev, ccx->ifs_t3_addr, ccx->ifs_t3_th_h_mask, + env->ifs_clm_th_h[2], bb->phy_idx); + rtw89_phy_write32_idx(rtwdev, ccx->ifs_t4_addr, ccx->ifs_t4_th_h_mask, + env->ifs_clm_th_h[3], bb->phy_idx); for (i = 0; i < RTW89_IFS_CLM_NUM; i++) rtw89_debug(rtwdev, RTW89_DBG_PHY_TRACK, @@ -5372,31 +5390,38 @@ static void rtw89_phy_ifs_clm_set_th_reg(struct rtw89_dev *rtwdev) i + 1, env->ifs_clm_th_l[i], env->ifs_clm_th_h[i]); } -static void rtw89_phy_ifs_clm_setting_init(struct rtw89_dev *rtwdev) +static void rtw89_phy_ifs_clm_setting_init(struct rtw89_dev *rtwdev, + struct rtw89_bb_ctx *bb) { const struct rtw89_phy_gen_def *phy = rtwdev->chip->phy_def; - struct rtw89_env_monitor_info *env = &rtwdev->env_monitor; + struct rtw89_env_monitor_info *env = &bb->env_monitor; const struct rtw89_ccx_regs *ccx = phy->ccx; - struct rtw89_ccx_para_info para = {0}; + struct rtw89_ccx_para_info para = {}; env->ifs_clm_app = RTW89_IFS_CLM_BACKGROUND; env->ifs_clm_mntr_time = 0; para.ifs_clm_app = RTW89_IFS_CLM_INIT; - if (rtw89_phy_ifs_clm_th_update_check(rtwdev, ¶)) - rtw89_phy_ifs_clm_set_th_reg(rtwdev); + if (rtw89_phy_ifs_clm_th_update_check(rtwdev, bb, ¶)) + rtw89_phy_ifs_clm_set_th_reg(rtwdev, bb); - rtw89_phy_set_phy_regs(rtwdev, ccx->ifs_cnt_addr, ccx->ifs_collect_en_mask, true); - rtw89_phy_set_phy_regs(rtwdev, ccx->ifs_t1_addr, ccx->ifs_t1_en_mask, true); - rtw89_phy_set_phy_regs(rtwdev, ccx->ifs_t2_addr, ccx->ifs_t2_en_mask, true); - rtw89_phy_set_phy_regs(rtwdev, ccx->ifs_t3_addr, ccx->ifs_t3_en_mask, true); - rtw89_phy_set_phy_regs(rtwdev, ccx->ifs_t4_addr, ccx->ifs_t4_en_mask, true); + rtw89_phy_write32_idx(rtwdev, ccx->ifs_cnt_addr, ccx->ifs_collect_en_mask, true, + bb->phy_idx); + rtw89_phy_write32_idx(rtwdev, ccx->ifs_t1_addr, ccx->ifs_t1_en_mask, true, + bb->phy_idx); + rtw89_phy_write32_idx(rtwdev, ccx->ifs_t2_addr, ccx->ifs_t2_en_mask, true, + bb->phy_idx); + rtw89_phy_write32_idx(rtwdev, ccx->ifs_t3_addr, ccx->ifs_t3_en_mask, true, + bb->phy_idx); + rtw89_phy_write32_idx(rtwdev, ccx->ifs_t4_addr, ccx->ifs_t4_en_mask, true, + bb->phy_idx); } static int rtw89_phy_ccx_racing_ctrl(struct rtw89_dev *rtwdev, + struct rtw89_bb_ctx *bb, enum rtw89_env_racing_lv level) { - struct rtw89_env_monitor_info *env = &rtwdev->env_monitor; + struct rtw89_env_monitor_info *env = &bb->env_monitor; int ret = 0; if (level >= RTW89_RAC_MAX_NUM) { @@ -5425,56 +5450,62 @@ static int rtw89_phy_ccx_racing_ctrl(struct rtw89_dev *rtwdev, return ret; } -static void rtw89_phy_ccx_trigger(struct rtw89_dev *rtwdev) +static void rtw89_phy_ccx_trigger(struct rtw89_dev *rtwdev, + struct rtw89_bb_ctx *bb) { const struct rtw89_phy_gen_def *phy = rtwdev->chip->phy_def; - struct rtw89_env_monitor_info *env = &rtwdev->env_monitor; + struct rtw89_env_monitor_info *env = &bb->env_monitor; const struct rtw89_ccx_regs *ccx = phy->ccx; - rtw89_phy_set_phy_regs(rtwdev, ccx->ifs_cnt_addr, ccx->ifs_clm_cnt_clear_mask, 0); - rtw89_phy_set_phy_regs(rtwdev, ccx->setting_addr, ccx->measurement_trig_mask, 0); - rtw89_phy_set_phy_regs(rtwdev, ccx->ifs_cnt_addr, ccx->ifs_clm_cnt_clear_mask, 1); - rtw89_phy_set_phy_regs(rtwdev, ccx->setting_addr, ccx->measurement_trig_mask, 1); + rtw89_phy_write32_idx(rtwdev, ccx->ifs_cnt_addr, ccx->ifs_clm_cnt_clear_mask, 0, + bb->phy_idx); + rtw89_phy_write32_idx(rtwdev, ccx->setting_addr, ccx->measurement_trig_mask, 0, + bb->phy_idx); + rtw89_phy_write32_idx(rtwdev, ccx->ifs_cnt_addr, ccx->ifs_clm_cnt_clear_mask, 1, + bb->phy_idx); + rtw89_phy_write32_idx(rtwdev, ccx->setting_addr, ccx->measurement_trig_mask, 1, + bb->phy_idx); env->ccx_ongoing = true; } -static void rtw89_phy_ifs_clm_get_utility(struct rtw89_dev *rtwdev) +static void rtw89_phy_ifs_clm_get_utility(struct rtw89_dev *rtwdev, + struct rtw89_bb_ctx *bb) { - struct rtw89_env_monitor_info *env = &rtwdev->env_monitor; + struct rtw89_env_monitor_info *env = &bb->env_monitor; u8 i = 0; u32 res = 0; env->ifs_clm_tx_ratio = - rtw89_phy_ccx_get_report(rtwdev, env->ifs_clm_tx, PERCENT); + rtw89_phy_ccx_get_report(rtwdev, bb, env->ifs_clm_tx, PERCENT); env->ifs_clm_edcca_excl_cca_ratio = - rtw89_phy_ccx_get_report(rtwdev, env->ifs_clm_edcca_excl_cca, + rtw89_phy_ccx_get_report(rtwdev, bb, env->ifs_clm_edcca_excl_cca, PERCENT); env->ifs_clm_cck_fa_ratio = - rtw89_phy_ccx_get_report(rtwdev, env->ifs_clm_cckfa, PERCENT); + rtw89_phy_ccx_get_report(rtwdev, bb, env->ifs_clm_cckfa, PERCENT); env->ifs_clm_ofdm_fa_ratio = - rtw89_phy_ccx_get_report(rtwdev, env->ifs_clm_ofdmfa, PERCENT); + rtw89_phy_ccx_get_report(rtwdev, bb, env->ifs_clm_ofdmfa, PERCENT); env->ifs_clm_cck_cca_excl_fa_ratio = - rtw89_phy_ccx_get_report(rtwdev, env->ifs_clm_cckcca_excl_fa, + rtw89_phy_ccx_get_report(rtwdev, bb, env->ifs_clm_cckcca_excl_fa, PERCENT); env->ifs_clm_ofdm_cca_excl_fa_ratio = - rtw89_phy_ccx_get_report(rtwdev, env->ifs_clm_ofdmcca_excl_fa, + rtw89_phy_ccx_get_report(rtwdev, bb, env->ifs_clm_ofdmcca_excl_fa, PERCENT); env->ifs_clm_cck_fa_permil = - rtw89_phy_ccx_get_report(rtwdev, env->ifs_clm_cckfa, PERMIL); + rtw89_phy_ccx_get_report(rtwdev, bb, env->ifs_clm_cckfa, PERMIL); env->ifs_clm_ofdm_fa_permil = - rtw89_phy_ccx_get_report(rtwdev, env->ifs_clm_ofdmfa, PERMIL); + rtw89_phy_ccx_get_report(rtwdev, bb, env->ifs_clm_ofdmfa, PERMIL); for (i = 0; i < RTW89_IFS_CLM_NUM; i++) { if (env->ifs_clm_his[i] > ENV_MNTR_IFSCLM_HIS_MAX) { env->ifs_clm_ifs_avg[i] = ENV_MNTR_FAIL_DWORD; } else { env->ifs_clm_ifs_avg[i] = - rtw89_phy_ccx_idx_to_us(rtwdev, + rtw89_phy_ccx_idx_to_us(rtwdev, bb, env->ifs_clm_avg[i]); } - res = rtw89_phy_ccx_idx_to_us(rtwdev, env->ifs_clm_cca[i]); + res = rtw89_phy_ccx_idx_to_us(rtwdev, bb, env->ifs_clm_cca[i]); res += env->ifs_clm_his[i] >> 1; if (env->ifs_clm_his[i]) res /= env->ifs_clm_his[i]; @@ -5504,81 +5535,82 @@ static void rtw89_phy_ifs_clm_get_utility(struct rtw89_dev *rtwdev) env->ifs_clm_cca_avg[i]); } -static bool rtw89_phy_ifs_clm_get_result(struct rtw89_dev *rtwdev) +static bool rtw89_phy_ifs_clm_get_result(struct rtw89_dev *rtwdev, + struct rtw89_bb_ctx *bb) { const struct rtw89_phy_gen_def *phy = rtwdev->chip->phy_def; - struct rtw89_env_monitor_info *env = &rtwdev->env_monitor; + struct rtw89_env_monitor_info *env = &bb->env_monitor; const struct rtw89_ccx_regs *ccx = phy->ccx; u8 i = 0; - if (rtw89_phy_read32_mask(rtwdev, ccx->ifs_total_addr, - ccx->ifs_cnt_done_mask) == 0) { + if (rtw89_phy_read32_idx(rtwdev, ccx->ifs_total_addr, + ccx->ifs_cnt_done_mask, bb->phy_idx) == 0) { rtw89_debug(rtwdev, RTW89_DBG_PHY_TRACK, "Get IFS_CLM report Fail\n"); return false; } env->ifs_clm_tx = - rtw89_phy_read32_mask(rtwdev, ccx->ifs_clm_tx_cnt_addr, - ccx->ifs_clm_tx_cnt_msk); + rtw89_phy_read32_idx(rtwdev, ccx->ifs_clm_tx_cnt_addr, + ccx->ifs_clm_tx_cnt_msk, bb->phy_idx); env->ifs_clm_edcca_excl_cca = - rtw89_phy_read32_mask(rtwdev, ccx->ifs_clm_tx_cnt_addr, - ccx->ifs_clm_edcca_excl_cca_fa_mask); + rtw89_phy_read32_idx(rtwdev, ccx->ifs_clm_tx_cnt_addr, + ccx->ifs_clm_edcca_excl_cca_fa_mask, bb->phy_idx); env->ifs_clm_cckcca_excl_fa = - rtw89_phy_read32_mask(rtwdev, ccx->ifs_clm_cca_addr, - ccx->ifs_clm_cckcca_excl_fa_mask); + rtw89_phy_read32_idx(rtwdev, ccx->ifs_clm_cca_addr, + ccx->ifs_clm_cckcca_excl_fa_mask, bb->phy_idx); env->ifs_clm_ofdmcca_excl_fa = - rtw89_phy_read32_mask(rtwdev, ccx->ifs_clm_cca_addr, - ccx->ifs_clm_ofdmcca_excl_fa_mask); + rtw89_phy_read32_idx(rtwdev, ccx->ifs_clm_cca_addr, + ccx->ifs_clm_ofdmcca_excl_fa_mask, bb->phy_idx); env->ifs_clm_cckfa = - rtw89_phy_read32_mask(rtwdev, ccx->ifs_clm_fa_addr, - ccx->ifs_clm_cck_fa_mask); + rtw89_phy_read32_idx(rtwdev, ccx->ifs_clm_fa_addr, + ccx->ifs_clm_cck_fa_mask, bb->phy_idx); env->ifs_clm_ofdmfa = - rtw89_phy_read32_mask(rtwdev, ccx->ifs_clm_fa_addr, - ccx->ifs_clm_ofdm_fa_mask); + rtw89_phy_read32_idx(rtwdev, ccx->ifs_clm_fa_addr, + ccx->ifs_clm_ofdm_fa_mask, bb->phy_idx); env->ifs_clm_his[0] = - rtw89_phy_read32_mask(rtwdev, ccx->ifs_his_addr, - ccx->ifs_t1_his_mask); + rtw89_phy_read32_idx(rtwdev, ccx->ifs_his_addr, + ccx->ifs_t1_his_mask, bb->phy_idx); env->ifs_clm_his[1] = - rtw89_phy_read32_mask(rtwdev, ccx->ifs_his_addr, - ccx->ifs_t2_his_mask); + rtw89_phy_read32_idx(rtwdev, ccx->ifs_his_addr, + ccx->ifs_t2_his_mask, bb->phy_idx); env->ifs_clm_his[2] = - rtw89_phy_read32_mask(rtwdev, ccx->ifs_his_addr, - ccx->ifs_t3_his_mask); + rtw89_phy_read32_idx(rtwdev, ccx->ifs_his_addr, + ccx->ifs_t3_his_mask, bb->phy_idx); env->ifs_clm_his[3] = - rtw89_phy_read32_mask(rtwdev, ccx->ifs_his_addr, - ccx->ifs_t4_his_mask); + rtw89_phy_read32_idx(rtwdev, ccx->ifs_his_addr, + ccx->ifs_t4_his_mask, bb->phy_idx); env->ifs_clm_avg[0] = - rtw89_phy_read32_mask(rtwdev, ccx->ifs_avg_l_addr, - ccx->ifs_t1_avg_mask); + rtw89_phy_read32_idx(rtwdev, ccx->ifs_avg_l_addr, + ccx->ifs_t1_avg_mask, bb->phy_idx); env->ifs_clm_avg[1] = - rtw89_phy_read32_mask(rtwdev, ccx->ifs_avg_l_addr, - ccx->ifs_t2_avg_mask); + rtw89_phy_read32_idx(rtwdev, ccx->ifs_avg_l_addr, + ccx->ifs_t2_avg_mask, bb->phy_idx); env->ifs_clm_avg[2] = - rtw89_phy_read32_mask(rtwdev, ccx->ifs_avg_h_addr, - ccx->ifs_t3_avg_mask); + rtw89_phy_read32_idx(rtwdev, ccx->ifs_avg_h_addr, + ccx->ifs_t3_avg_mask, bb->phy_idx); env->ifs_clm_avg[3] = - rtw89_phy_read32_mask(rtwdev, ccx->ifs_avg_h_addr, - ccx->ifs_t4_avg_mask); + rtw89_phy_read32_idx(rtwdev, ccx->ifs_avg_h_addr, + ccx->ifs_t4_avg_mask, bb->phy_idx); env->ifs_clm_cca[0] = - rtw89_phy_read32_mask(rtwdev, ccx->ifs_cca_l_addr, - ccx->ifs_t1_cca_mask); + rtw89_phy_read32_idx(rtwdev, ccx->ifs_cca_l_addr, + ccx->ifs_t1_cca_mask, bb->phy_idx); env->ifs_clm_cca[1] = - rtw89_phy_read32_mask(rtwdev, ccx->ifs_cca_l_addr, - ccx->ifs_t2_cca_mask); + rtw89_phy_read32_idx(rtwdev, ccx->ifs_cca_l_addr, + ccx->ifs_t2_cca_mask, bb->phy_idx); env->ifs_clm_cca[2] = - rtw89_phy_read32_mask(rtwdev, ccx->ifs_cca_h_addr, - ccx->ifs_t3_cca_mask); + rtw89_phy_read32_idx(rtwdev, ccx->ifs_cca_h_addr, + ccx->ifs_t3_cca_mask, bb->phy_idx); env->ifs_clm_cca[3] = - rtw89_phy_read32_mask(rtwdev, ccx->ifs_cca_h_addr, - ccx->ifs_t4_cca_mask); + rtw89_phy_read32_idx(rtwdev, ccx->ifs_cca_h_addr, + ccx->ifs_t4_cca_mask, bb->phy_idx); env->ifs_clm_total_ifs = - rtw89_phy_read32_mask(rtwdev, ccx->ifs_total_addr, - ccx->ifs_total_mask); + rtw89_phy_read32_idx(rtwdev, ccx->ifs_total_addr, + ccx->ifs_total_mask, bb->phy_idx); rtw89_debug(rtwdev, RTW89_DBG_PHY_TRACK, "IFS-CLM total_ifs = %d\n", env->ifs_clm_total_ifs); @@ -5598,16 +5630,17 @@ static bool rtw89_phy_ifs_clm_get_result(struct rtw89_dev *rtwdev) "T%d:[%d, %d, %d]\n", i + 1, env->ifs_clm_his[i], env->ifs_clm_avg[i], env->ifs_clm_cca[i]); - rtw89_phy_ifs_clm_get_utility(rtwdev); + rtw89_phy_ifs_clm_get_utility(rtwdev, bb); return true; } static int rtw89_phy_ifs_clm_set(struct rtw89_dev *rtwdev, + struct rtw89_bb_ctx *bb, struct rtw89_ccx_para_info *para) { const struct rtw89_phy_gen_def *phy = rtwdev->chip->phy_def; - struct rtw89_env_monitor_info *env = &rtwdev->env_monitor; + struct rtw89_env_monitor_info *env = &bb->env_monitor; const struct rtw89_ccx_regs *ccx = phy->ccx; u32 period = 0; u32 unit_idx = 0; @@ -5618,17 +5651,17 @@ static int rtw89_phy_ifs_clm_set(struct rtw89_dev *rtwdev, return -EINVAL; } - if (rtw89_phy_ccx_racing_ctrl(rtwdev, para->rac_lv)) + if (rtw89_phy_ccx_racing_ctrl(rtwdev, bb, para->rac_lv)) return -EINVAL; if (para->mntr_time != env->ifs_clm_mntr_time) { rtw89_phy_ccx_ms_to_period_unit(rtwdev, para->mntr_time, &period, &unit_idx); - rtw89_phy_set_phy_regs(rtwdev, ccx->ifs_cnt_addr, - ccx->ifs_clm_period_mask, period); - rtw89_phy_set_phy_regs(rtwdev, ccx->ifs_cnt_addr, - ccx->ifs_clm_cnt_unit_mask, - unit_idx); + rtw89_phy_write32_idx(rtwdev, ccx->ifs_cnt_addr, + ccx->ifs_clm_period_mask, period, bb->phy_idx); + rtw89_phy_write32_idx(rtwdev, ccx->ifs_cnt_addr, + ccx->ifs_clm_cnt_unit_mask, + unit_idx, bb->phy_idx); rtw89_debug(rtwdev, RTW89_DBG_PHY_TRACK, "Update IFS-CLM time ((%d)) -> ((%d))\n", @@ -5639,18 +5672,19 @@ static int rtw89_phy_ifs_clm_set(struct rtw89_dev *rtwdev, env->ccx_unit_idx = (u8)unit_idx; } - if (rtw89_phy_ifs_clm_th_update_check(rtwdev, para)) { + if (rtw89_phy_ifs_clm_th_update_check(rtwdev, bb, para)) { env->ifs_clm_app = para->ifs_clm_app; - rtw89_phy_ifs_clm_set_th_reg(rtwdev); + rtw89_phy_ifs_clm_set_th_reg(rtwdev, bb); } return 0; } -void rtw89_phy_env_monitor_track(struct rtw89_dev *rtwdev) +static void __rtw89_phy_env_monitor_track(struct rtw89_dev *rtwdev, + struct rtw89_bb_ctx *bb) { - struct rtw89_env_monitor_info *env = &rtwdev->env_monitor; - struct rtw89_ccx_para_info para = {0}; + struct rtw89_env_monitor_info *env = &bb->env_monitor; + struct rtw89_ccx_para_info para = {}; u8 chk_result = RTW89_PHY_ENV_MON_CCX_FAIL; env->ccx_watchdog_result = RTW89_PHY_ENV_MON_CCX_FAIL; @@ -5660,25 +5694,36 @@ void rtw89_phy_env_monitor_track(struct rtw89_dev *rtwdev) return; } + rtw89_debug(rtwdev, RTW89_DBG_PHY_TRACK, + "BB-%d env_monitor track\n", bb->phy_idx); + /* only ifs_clm for now */ - if (rtw89_phy_ifs_clm_get_result(rtwdev)) + if (rtw89_phy_ifs_clm_get_result(rtwdev, bb)) env->ccx_watchdog_result |= RTW89_PHY_ENV_MON_IFS_CLM; - rtw89_phy_ccx_racing_release(rtwdev); + rtw89_phy_ccx_racing_release(rtwdev, bb); para.mntr_time = 1900; para.rac_lv = RTW89_RAC_LV_1; para.ifs_clm_app = RTW89_IFS_CLM_BACKGROUND; - if (rtw89_phy_ifs_clm_set(rtwdev, ¶) == 0) + if (rtw89_phy_ifs_clm_set(rtwdev, bb, ¶) == 0) chk_result |= RTW89_PHY_ENV_MON_IFS_CLM; if (chk_result) - rtw89_phy_ccx_trigger(rtwdev); + rtw89_phy_ccx_trigger(rtwdev, bb); rtw89_debug(rtwdev, RTW89_DBG_PHY_TRACK, "get_result=0x%x, chk_result:0x%x\n", env->ccx_watchdog_result, chk_result); } +void rtw89_phy_env_monitor_track(struct rtw89_dev *rtwdev) +{ + struct rtw89_bb_ctx *bb; + + rtw89_for_each_active_bb(rtwdev, bb) + __rtw89_phy_env_monitor_track(rtwdev, bb); +} + static bool rtw89_physts_ie_page_valid(enum rtw89_phy_status_bitmap *ie_page) { if (*ie_page >= RTW89_PHYSTS_BITMAP_NUM || @@ -5799,11 +5844,12 @@ static void rtw89_physts_parsing_init(struct rtw89_dev *rtwdev) __rtw89_physts_parsing_init(rtwdev, RTW89_PHY_1); } -static void rtw89_phy_dig_read_gain_table(struct rtw89_dev *rtwdev, int type) +static void rtw89_phy_dig_read_gain_table(struct rtw89_dev *rtwdev, + struct rtw89_bb_ctx *bb, int type) { const struct rtw89_chip_info *chip = rtwdev->chip; - struct rtw89_dig_info *dig = &rtwdev->dig; const struct rtw89_phy_dig_gain_cfg *cfg; + struct rtw89_dig_info *dig = &bb->dig; const char *msg; u8 i; s8 gain_base; @@ -5840,8 +5886,8 @@ static void rtw89_phy_dig_read_gain_table(struct rtw89_dev *rtwdev, int type) } for (i = 0; i < cfg->size; i++) { - tmp = rtw89_phy_read32_mask(rtwdev, cfg->table[i].addr, - cfg->table[i].mask); + tmp = rtw89_phy_read32_idx(rtwdev, cfg->table[i].addr, + cfg->table[i].mask, bb->phy_idx); tmp >>= DIG_GAIN_SHIFT; gain_arr[i] = sign_extend32(tmp, U4_MAX_BIT) + gain_base; gain_base += DIG_GAIN; @@ -5851,25 +5897,26 @@ static void rtw89_phy_dig_read_gain_table(struct rtw89_dev *rtwdev, int type) } } -static void rtw89_phy_dig_update_gain_para(struct rtw89_dev *rtwdev) +static void rtw89_phy_dig_update_gain_para(struct rtw89_dev *rtwdev, + struct rtw89_bb_ctx *bb) { - struct rtw89_dig_info *dig = &rtwdev->dig; + struct rtw89_dig_info *dig = &bb->dig; u32 tmp; u8 i; if (!rtwdev->hal.support_igi) return; - tmp = rtw89_phy_read32_mask(rtwdev, R_PATH0_IB_PKPW, - B_PATH0_IB_PKPW_MSK); + tmp = rtw89_phy_read32_idx(rtwdev, R_PATH0_IB_PKPW, + B_PATH0_IB_PKPW_MSK, bb->phy_idx); dig->ib_pkpwr = sign_extend32(tmp >> DIG_GAIN_SHIFT, U8_MAX_BIT); - dig->ib_pbk = rtw89_phy_read32_mask(rtwdev, R_PATH0_IB_PBK, - B_PATH0_IB_PBK_MSK); + dig->ib_pbk = rtw89_phy_read32_idx(rtwdev, R_PATH0_IB_PBK, + B_PATH0_IB_PBK_MSK, bb->phy_idx); rtw89_debug(rtwdev, RTW89_DBG_DIG, "ib_pkpwr=%d, ib_pbk=%d\n", dig->ib_pkpwr, dig->ib_pbk); for (i = RTW89_DIG_GAIN_LNA_G; i < RTW89_DIG_GAIN_MAX; i++) - rtw89_phy_dig_read_gain_table(rtwdev, i); + rtw89_phy_dig_read_gain_table(rtwdev, bb, i); } static const u8 rssi_nolink = 22; @@ -5878,10 +5925,11 @@ static const u16 fa_th_2g[FA_TH_NUM] = {22, 44, 66, 88}; static const u16 fa_th_5g[FA_TH_NUM] = {4, 8, 12, 16}; static const u16 fa_th_nolink[FA_TH_NUM] = {196, 352, 440, 528}; -static void rtw89_phy_dig_update_rssi_info(struct rtw89_dev *rtwdev) +static void rtw89_phy_dig_update_rssi_info(struct rtw89_dev *rtwdev, + struct rtw89_bb_ctx *bb) { - struct rtw89_phy_ch_info *ch_info = &rtwdev->ch_info; - struct rtw89_dig_info *dig = &rtwdev->dig; + struct rtw89_phy_ch_info *ch_info = &bb->ch_info; + struct rtw89_dig_info *dig = &bb->dig; bool is_linked = rtwdev->total_sta_assoc > 0; if (is_linked) { @@ -5892,10 +5940,11 @@ static void rtw89_phy_dig_update_rssi_info(struct rtw89_dev *rtwdev) } } -static void rtw89_phy_dig_update_para(struct rtw89_dev *rtwdev) +static void rtw89_phy_dig_update_para(struct rtw89_dev *rtwdev, + struct rtw89_bb_ctx *bb) { - struct rtw89_dig_info *dig = &rtwdev->dig; - const struct rtw89_chan *chan = rtw89_chan_get(rtwdev, RTW89_CHANCTX_0); + const struct rtw89_chan *chan = rtw89_mgnt_chan_get(rtwdev, bb->phy_idx); + struct rtw89_dig_info *dig = &bb->dig; bool is_linked = rtwdev->total_sta_assoc > 0; const u16 *fa_th_src = NULL; @@ -5924,9 +5973,10 @@ static const u8 pd_low_th_offset = 16, dynamic_igi_min = 0x20; static const u8 igi_max_performance_mode = 0x5a; static const u8 dynamic_pd_threshold_max; -static void rtw89_phy_dig_para_reset(struct rtw89_dev *rtwdev) +static void rtw89_phy_dig_para_reset(struct rtw89_dev *rtwdev, + struct rtw89_bb_ctx *bb) { - struct rtw89_dig_info *dig = &rtwdev->dig; + struct rtw89_dig_info *dig = &bb->dig; dig->cur_gaincode.lna_idx = LNA_IDX_MAX; dig->cur_gaincode.tia_idx = TIA_IDX_MAX; @@ -5942,15 +5992,27 @@ static void rtw89_phy_dig_para_reset(struct rtw89_dev *rtwdev) dig->is_linked_pre = false; } +static void __rtw89_phy_dig_init(struct rtw89_dev *rtwdev, + struct rtw89_bb_ctx *bb) +{ + rtw89_debug(rtwdev, RTW89_DBG_DIG, "BB-%d dig_init\n", bb->phy_idx); + + rtw89_phy_dig_update_gain_para(rtwdev, bb); + rtw89_phy_dig_reset(rtwdev, bb); +} + static void rtw89_phy_dig_init(struct rtw89_dev *rtwdev) { - rtw89_phy_dig_update_gain_para(rtwdev); - rtw89_phy_dig_reset(rtwdev); + struct rtw89_bb_ctx *bb; + + rtw89_for_each_capab_bb(rtwdev, bb) + __rtw89_phy_dig_init(rtwdev, bb); } -static u8 rtw89_phy_dig_lna_idx_by_rssi(struct rtw89_dev *rtwdev, u8 rssi) +static u8 rtw89_phy_dig_lna_idx_by_rssi(struct rtw89_dev *rtwdev, + struct rtw89_bb_ctx *bb, u8 rssi) { - struct rtw89_dig_info *dig = &rtwdev->dig; + struct rtw89_dig_info *dig = &bb->dig; u8 lna_idx; if (rssi < dig->igi_rssi_th[0]) @@ -5969,9 +6031,10 @@ static u8 rtw89_phy_dig_lna_idx_by_rssi(struct rtw89_dev *rtwdev, u8 rssi) return lna_idx; } -static u8 rtw89_phy_dig_tia_idx_by_rssi(struct rtw89_dev *rtwdev, u8 rssi) +static u8 rtw89_phy_dig_tia_idx_by_rssi(struct rtw89_dev *rtwdev, + struct rtw89_bb_ctx *bb, u8 rssi) { - struct rtw89_dig_info *dig = &rtwdev->dig; + struct rtw89_dig_info *dig = &bb->dig; u8 tia_idx; if (rssi < dig->igi_rssi_th[0]) @@ -5984,10 +6047,11 @@ static u8 rtw89_phy_dig_tia_idx_by_rssi(struct rtw89_dev *rtwdev, u8 rssi) #define IB_PBK_BASE 110 #define WB_RSSI_BASE 10 -static u8 rtw89_phy_dig_rxb_idx_by_rssi(struct rtw89_dev *rtwdev, u8 rssi, +static u8 rtw89_phy_dig_rxb_idx_by_rssi(struct rtw89_dev *rtwdev, + struct rtw89_bb_ctx *bb, u8 rssi, struct rtw89_agc_gaincode_set *set) { - struct rtw89_dig_info *dig = &rtwdev->dig; + struct rtw89_dig_info *dig = &bb->dig; s8 lna_gain = dig->lna_gain[set->lna_idx]; s8 tia_gain = dig->tia_gain[set->tia_idx]; s32 wb_rssi = rssi + lna_gain + tia_gain; @@ -6003,12 +6067,13 @@ static u8 rtw89_phy_dig_rxb_idx_by_rssi(struct rtw89_dev *rtwdev, u8 rssi, return rxb_idx; } -static void rtw89_phy_dig_gaincode_by_rssi(struct rtw89_dev *rtwdev, u8 rssi, +static void rtw89_phy_dig_gaincode_by_rssi(struct rtw89_dev *rtwdev, + struct rtw89_bb_ctx *bb, u8 rssi, struct rtw89_agc_gaincode_set *set) { - set->lna_idx = rtw89_phy_dig_lna_idx_by_rssi(rtwdev, rssi); - set->tia_idx = rtw89_phy_dig_tia_idx_by_rssi(rtwdev, rssi); - set->rxb_idx = rtw89_phy_dig_rxb_idx_by_rssi(rtwdev, rssi, set); + set->lna_idx = rtw89_phy_dig_lna_idx_by_rssi(rtwdev, bb, rssi); + set->tia_idx = rtw89_phy_dig_tia_idx_by_rssi(rtwdev, bb, rssi); + set->rxb_idx = rtw89_phy_dig_rxb_idx_by_rssi(rtwdev, bb, rssi, set); rtw89_debug(rtwdev, RTW89_DBG_DIG, "final_rssi=%03d, (lna,tia,rab)=(%d,%d,%02d)\n", @@ -6017,10 +6082,11 @@ static void rtw89_phy_dig_gaincode_by_rssi(struct rtw89_dev *rtwdev, u8 rssi, #define IGI_OFFSET_MAX 25 #define IGI_OFFSET_MUL 2 -static void rtw89_phy_dig_igi_offset_by_env(struct rtw89_dev *rtwdev) +static void rtw89_phy_dig_igi_offset_by_env(struct rtw89_dev *rtwdev, + struct rtw89_bb_ctx *bb) { - struct rtw89_dig_info *dig = &rtwdev->dig; - struct rtw89_env_monitor_info *env = &rtwdev->env_monitor; + struct rtw89_dig_info *dig = &bb->dig; + struct rtw89_env_monitor_info *env = &bb->env_monitor; enum rtw89_dig_noisy_level noisy_lv; u8 igi_offset = dig->fa_rssi_ofst; u16 fa_ratio = 0; @@ -6057,92 +6123,99 @@ static void rtw89_phy_dig_igi_offset_by_env(struct rtw89_dev *rtwdev) noisy_lv, igi_offset); } -static void rtw89_phy_dig_set_lna_idx(struct rtw89_dev *rtwdev, u8 lna_idx) +static void rtw89_phy_dig_set_lna_idx(struct rtw89_dev *rtwdev, + struct rtw89_bb_ctx *bb, u8 lna_idx) { const struct rtw89_dig_regs *dig_regs = rtwdev->chip->dig_regs; - rtw89_phy_write32_mask(rtwdev, dig_regs->p0_lna_init.addr, - dig_regs->p0_lna_init.mask, lna_idx); - rtw89_phy_write32_mask(rtwdev, dig_regs->p1_lna_init.addr, - dig_regs->p1_lna_init.mask, lna_idx); + rtw89_phy_write32_idx(rtwdev, dig_regs->p0_lna_init.addr, + dig_regs->p0_lna_init.mask, lna_idx, bb->phy_idx); + rtw89_phy_write32_idx(rtwdev, dig_regs->p1_lna_init.addr, + dig_regs->p1_lna_init.mask, lna_idx, bb->phy_idx); } -static void rtw89_phy_dig_set_tia_idx(struct rtw89_dev *rtwdev, u8 tia_idx) +static void rtw89_phy_dig_set_tia_idx(struct rtw89_dev *rtwdev, + struct rtw89_bb_ctx *bb, u8 tia_idx) { const struct rtw89_dig_regs *dig_regs = rtwdev->chip->dig_regs; - rtw89_phy_write32_mask(rtwdev, dig_regs->p0_tia_init.addr, - dig_regs->p0_tia_init.mask, tia_idx); - rtw89_phy_write32_mask(rtwdev, dig_regs->p1_tia_init.addr, - dig_regs->p1_tia_init.mask, tia_idx); + rtw89_phy_write32_idx(rtwdev, dig_regs->p0_tia_init.addr, + dig_regs->p0_tia_init.mask, tia_idx, bb->phy_idx); + rtw89_phy_write32_idx(rtwdev, dig_regs->p1_tia_init.addr, + dig_regs->p1_tia_init.mask, tia_idx, bb->phy_idx); } -static void rtw89_phy_dig_set_rxb_idx(struct rtw89_dev *rtwdev, u8 rxb_idx) +static void rtw89_phy_dig_set_rxb_idx(struct rtw89_dev *rtwdev, + struct rtw89_bb_ctx *bb, u8 rxb_idx) { const struct rtw89_dig_regs *dig_regs = rtwdev->chip->dig_regs; - rtw89_phy_write32_mask(rtwdev, dig_regs->p0_rxb_init.addr, - dig_regs->p0_rxb_init.mask, rxb_idx); - rtw89_phy_write32_mask(rtwdev, dig_regs->p1_rxb_init.addr, - dig_regs->p1_rxb_init.mask, rxb_idx); + rtw89_phy_write32_idx(rtwdev, dig_regs->p0_rxb_init.addr, + dig_regs->p0_rxb_init.mask, rxb_idx, bb->phy_idx); + rtw89_phy_write32_idx(rtwdev, dig_regs->p1_rxb_init.addr, + dig_regs->p1_rxb_init.mask, rxb_idx, bb->phy_idx); } static void rtw89_phy_dig_set_igi_cr(struct rtw89_dev *rtwdev, + struct rtw89_bb_ctx *bb, const struct rtw89_agc_gaincode_set set) { if (!rtwdev->hal.support_igi) return; - rtw89_phy_dig_set_lna_idx(rtwdev, set.lna_idx); - rtw89_phy_dig_set_tia_idx(rtwdev, set.tia_idx); - rtw89_phy_dig_set_rxb_idx(rtwdev, set.rxb_idx); + rtw89_phy_dig_set_lna_idx(rtwdev, bb, set.lna_idx); + rtw89_phy_dig_set_tia_idx(rtwdev, bb, set.tia_idx); + rtw89_phy_dig_set_rxb_idx(rtwdev, bb, set.rxb_idx); rtw89_debug(rtwdev, RTW89_DBG_DIG, "Set (lna,tia,rxb)=((%d,%d,%02d))\n", set.lna_idx, set.tia_idx, set.rxb_idx); } static void rtw89_phy_dig_sdagc_follow_pagc_config(struct rtw89_dev *rtwdev, + struct rtw89_bb_ctx *bb, bool enable) { const struct rtw89_dig_regs *dig_regs = rtwdev->chip->dig_regs; - rtw89_phy_write32_mask(rtwdev, dig_regs->p0_p20_pagcugc_en.addr, - dig_regs->p0_p20_pagcugc_en.mask, enable); - rtw89_phy_write32_mask(rtwdev, dig_regs->p0_s20_pagcugc_en.addr, - dig_regs->p0_s20_pagcugc_en.mask, enable); - rtw89_phy_write32_mask(rtwdev, dig_regs->p1_p20_pagcugc_en.addr, - dig_regs->p1_p20_pagcugc_en.mask, enable); - rtw89_phy_write32_mask(rtwdev, dig_regs->p1_s20_pagcugc_en.addr, - dig_regs->p1_s20_pagcugc_en.mask, enable); + rtw89_phy_write32_idx(rtwdev, dig_regs->p0_p20_pagcugc_en.addr, + dig_regs->p0_p20_pagcugc_en.mask, enable, bb->phy_idx); + rtw89_phy_write32_idx(rtwdev, dig_regs->p0_s20_pagcugc_en.addr, + dig_regs->p0_s20_pagcugc_en.mask, enable, bb->phy_idx); + rtw89_phy_write32_idx(rtwdev, dig_regs->p1_p20_pagcugc_en.addr, + dig_regs->p1_p20_pagcugc_en.mask, enable, bb->phy_idx); + rtw89_phy_write32_idx(rtwdev, dig_regs->p1_s20_pagcugc_en.addr, + dig_regs->p1_s20_pagcugc_en.mask, enable, bb->phy_idx); rtw89_debug(rtwdev, RTW89_DBG_DIG, "sdagc_follow_pagc=%d\n", enable); } -static void rtw89_phy_dig_config_igi(struct rtw89_dev *rtwdev) +static void rtw89_phy_dig_config_igi(struct rtw89_dev *rtwdev, + struct rtw89_bb_ctx *bb) { - struct rtw89_dig_info *dig = &rtwdev->dig; + struct rtw89_dig_info *dig = &bb->dig; if (!rtwdev->hal.support_igi) return; if (dig->force_gaincode_idx_en) { - rtw89_phy_dig_set_igi_cr(rtwdev, dig->force_gaincode); + rtw89_phy_dig_set_igi_cr(rtwdev, bb, dig->force_gaincode); rtw89_debug(rtwdev, RTW89_DBG_DIG, "Force gaincode index enabled.\n"); } else { - rtw89_phy_dig_gaincode_by_rssi(rtwdev, dig->igi_fa_rssi, + rtw89_phy_dig_gaincode_by_rssi(rtwdev, bb, dig->igi_fa_rssi, &dig->cur_gaincode); - rtw89_phy_dig_set_igi_cr(rtwdev, dig->cur_gaincode); + rtw89_phy_dig_set_igi_cr(rtwdev, bb, dig->cur_gaincode); } } -static void rtw89_phy_dig_dyn_pd_th(struct rtw89_dev *rtwdev, u8 rssi, - bool enable) +static void rtw89_phy_dig_dyn_pd_th(struct rtw89_dev *rtwdev, + struct rtw89_bb_ctx *bb, + u8 rssi, bool enable) { - const struct rtw89_chan *chan = rtw89_chan_get(rtwdev, RTW89_CHANCTX_0); + const struct rtw89_chan *chan = rtw89_mgnt_chan_get(rtwdev, bb->phy_idx); const struct rtw89_dig_regs *dig_regs = rtwdev->chip->dig_regs; enum rtw89_bandwidth cbw = chan->band_width; - struct rtw89_dig_info *dig = &rtwdev->dig; + struct rtw89_dig_info *dig = &bb->dig; u8 final_rssi = 0, under_region = dig->pd_low_th_ofst; u8 ofdm_cca_th; s8 cck_cca_th; @@ -6184,10 +6257,10 @@ static void rtw89_phy_dig_dyn_pd_th(struct rtw89_dev *rtwdev, u8 rssi, "Dynamic PD th disabled, Set PD_low_bd=0\n"); } - rtw89_phy_write32_mask(rtwdev, dig_regs->seg0_pd_reg, - dig_regs->pd_lower_bound_mask, pd_val); - rtw89_phy_write32_mask(rtwdev, dig_regs->seg0_pd_reg, - dig_regs->pd_spatial_reuse_en, enable); + rtw89_phy_write32_idx(rtwdev, dig_regs->seg0_pd_reg, + dig_regs->pd_lower_bound_mask, pd_val, bb->phy_idx); + rtw89_phy_write32_idx(rtwdev, dig_regs->seg0_pd_reg, + dig_regs->pd_spatial_reuse_en, enable, bb->phy_idx); if (!rtwdev->hal.support_cckpd) return; @@ -6199,29 +6272,29 @@ static void rtw89_phy_dig_dyn_pd_th(struct rtw89_dev *rtwdev, u8 rssi, "igi=%d, cck_ccaTH=%d, backoff=%d, cck_PD_low=((%d))dB\n", final_rssi, cck_cca_th, under_region, pd_val); - rtw89_phy_write32_mask(rtwdev, dig_regs->bmode_pd_reg, - dig_regs->bmode_cca_rssi_limit_en, enable); - rtw89_phy_write32_mask(rtwdev, dig_regs->bmode_pd_lower_bound_reg, - dig_regs->bmode_rssi_nocca_low_th_mask, pd_val); + rtw89_phy_write32_idx(rtwdev, dig_regs->bmode_pd_reg, + dig_regs->bmode_cca_rssi_limit_en, enable, bb->phy_idx); + rtw89_phy_write32_idx(rtwdev, dig_regs->bmode_pd_lower_bound_reg, + dig_regs->bmode_rssi_nocca_low_th_mask, pd_val, bb->phy_idx); } -void rtw89_phy_dig_reset(struct rtw89_dev *rtwdev) +void rtw89_phy_dig_reset(struct rtw89_dev *rtwdev, struct rtw89_bb_ctx *bb) { - struct rtw89_dig_info *dig = &rtwdev->dig; + struct rtw89_dig_info *dig = &bb->dig; dig->bypass_dig = false; - rtw89_phy_dig_para_reset(rtwdev); - rtw89_phy_dig_set_igi_cr(rtwdev, dig->force_gaincode); - rtw89_phy_dig_dyn_pd_th(rtwdev, rssi_nolink, false); - rtw89_phy_dig_sdagc_follow_pagc_config(rtwdev, false); - rtw89_phy_dig_update_para(rtwdev); + rtw89_phy_dig_para_reset(rtwdev, bb); + rtw89_phy_dig_set_igi_cr(rtwdev, bb, dig->force_gaincode); + rtw89_phy_dig_dyn_pd_th(rtwdev, bb, rssi_nolink, false); + rtw89_phy_dig_sdagc_follow_pagc_config(rtwdev, bb, false); + rtw89_phy_dig_update_para(rtwdev, bb); } #define IGI_RSSI_MIN 10 #define ABS_IGI_MIN 0xc -void rtw89_phy_dig(struct rtw89_dev *rtwdev) +static void __rtw89_phy_dig(struct rtw89_dev *rtwdev, struct rtw89_bb_ctx *bb) { - struct rtw89_dig_info *dig = &rtwdev->dig; + struct rtw89_dig_info *dig = &bb->dig; bool is_linked = rtwdev->total_sta_assoc > 0; u8 igi_min; @@ -6230,20 +6303,22 @@ void rtw89_phy_dig(struct rtw89_dev *rtwdev) return; } - rtw89_phy_dig_update_rssi_info(rtwdev); + rtw89_debug(rtwdev, RTW89_DBG_DIG, "BB-%d dig track\n", bb->phy_idx); + + rtw89_phy_dig_update_rssi_info(rtwdev, bb); if (!dig->is_linked_pre && is_linked) { rtw89_debug(rtwdev, RTW89_DBG_DIG, "First connected\n"); - rtw89_phy_dig_update_para(rtwdev); + rtw89_phy_dig_update_para(rtwdev, bb); dig->igi_fa_rssi = dig->igi_rssi; } else if (dig->is_linked_pre && !is_linked) { rtw89_debug(rtwdev, RTW89_DBG_DIG, "First disconnected\n"); - rtw89_phy_dig_update_para(rtwdev); + rtw89_phy_dig_update_para(rtwdev, bb); dig->igi_fa_rssi = dig->igi_rssi; } dig->is_linked_pre = is_linked; - rtw89_phy_dig_igi_offset_by_env(rtwdev); + rtw89_phy_dig_igi_offset_by_env(rtwdev, bb); igi_min = max_t(int, dig->igi_rssi - IGI_RSSI_MIN, 0); dig->dyn_igi_max = min(igi_min + IGI_OFFSET_MAX, igi_max_performance_mode); @@ -6262,14 +6337,22 @@ void rtw89_phy_dig(struct rtw89_dev *rtwdev) dig->igi_rssi, dig->dyn_igi_max, dig->dyn_igi_min, dig->igi_fa_rssi); - rtw89_phy_dig_config_igi(rtwdev); + rtw89_phy_dig_config_igi(rtwdev, bb); - rtw89_phy_dig_dyn_pd_th(rtwdev, dig->igi_fa_rssi, dig->dyn_pd_th_en); + rtw89_phy_dig_dyn_pd_th(rtwdev, bb, dig->igi_fa_rssi, dig->dyn_pd_th_en); if (dig->dyn_pd_th_en && dig->igi_fa_rssi > dig->dyn_pd_th_max) - rtw89_phy_dig_sdagc_follow_pagc_config(rtwdev, true); + rtw89_phy_dig_sdagc_follow_pagc_config(rtwdev, bb, true); else - rtw89_phy_dig_sdagc_follow_pagc_config(rtwdev, false); + rtw89_phy_dig_sdagc_follow_pagc_config(rtwdev, bb, false); +} + +void rtw89_phy_dig(struct rtw89_dev *rtwdev) +{ + struct rtw89_bb_ctx *bb; + + rtw89_for_each_active_bb(rtwdev, bb) + __rtw89_phy_dig(rtwdev, bb); } static void __rtw89_phy_tx_path_div_sta_iter(struct rtw89_dev *rtwdev, @@ -6443,17 +6526,17 @@ static void rtw89_phy_antdiv_training_state(struct rtw89_dev *rtwdev) } antdiv->training_count++; - ieee80211_queue_delayed_work(rtwdev->hw, &rtwdev->antdiv_work, - state_period); + wiphy_delayed_work_queue(rtwdev->hw->wiphy, &rtwdev->antdiv_work, + state_period); } -void rtw89_phy_antdiv_work(struct work_struct *work) +void rtw89_phy_antdiv_work(struct wiphy *wiphy, struct wiphy_work *work) { struct rtw89_dev *rtwdev = container_of(work, struct rtw89_dev, antdiv_work.work); struct rtw89_antdiv_info *antdiv = &rtwdev->antdiv; - mutex_lock(&rtwdev->mutex); + lockdep_assert_wiphy(wiphy); if (antdiv->training_count <= ANTDIV_TRAINNING_CNT) { rtw89_phy_antdiv_training_state(rtwdev); @@ -6461,8 +6544,6 @@ void rtw89_phy_antdiv_work(struct work_struct *work) rtw89_phy_antdiv_decision_state(rtwdev); rtw89_phy_antdiv_set_ant(rtwdev); } - - mutex_unlock(&rtwdev->mutex); } void rtw89_phy_antdiv_track(struct rtw89_dev *rtwdev) @@ -6483,19 +6564,34 @@ void rtw89_phy_antdiv_track(struct rtw89_dev *rtwdev) return; antdiv->training_count = 0; - ieee80211_queue_delayed_work(rtwdev->hw, &rtwdev->antdiv_work, 0); + wiphy_delayed_work_queue(rtwdev->hw->wiphy, &rtwdev->antdiv_work, 0); +} + +static void __rtw89_phy_env_monitor_init(struct rtw89_dev *rtwdev, + struct rtw89_bb_ctx *bb) +{ + rtw89_debug(rtwdev, RTW89_DBG_PHY_TRACK, + "BB-%d env_monitor init\n", bb->phy_idx); + + rtw89_phy_ccx_top_setting_init(rtwdev, bb); + rtw89_phy_ifs_clm_setting_init(rtwdev, bb); } static void rtw89_phy_env_monitor_init(struct rtw89_dev *rtwdev) { - rtw89_phy_ccx_top_setting_init(rtwdev); - rtw89_phy_ifs_clm_setting_init(rtwdev); + struct rtw89_bb_ctx *bb; + + rtw89_for_each_capab_bb(rtwdev, bb) + __rtw89_phy_env_monitor_init(rtwdev, bb); } -static void rtw89_phy_edcca_init(struct rtw89_dev *rtwdev) +static void __rtw89_phy_edcca_init(struct rtw89_dev *rtwdev, + struct rtw89_bb_ctx *bb) { const struct rtw89_edcca_regs *edcca_regs = rtwdev->chip->edcca_regs; - struct rtw89_edcca_bak *edcca_bak = &rtwdev->hal.edcca_bak; + struct rtw89_edcca_bak *edcca_bak = &bb->edcca_bak; + + rtw89_debug(rtwdev, RTW89_DBG_EDCCA, "BB-%d edcca init\n", bb->phy_idx); memset(edcca_bak, 0, sizeof(*edcca_bak)); @@ -6511,8 +6607,16 @@ static void rtw89_phy_edcca_init(struct rtw89_dev *rtwdev) rtw89_phy_set_phy_regs(rtwdev, R_DFS_FFT_CG, B_DFS_FFT_EN, 1); } - rtw89_phy_write32_mask(rtwdev, edcca_regs->tx_collision_t2r_st, - edcca_regs->tx_collision_t2r_st_mask, 0x29); + rtw89_phy_write32_idx(rtwdev, edcca_regs->tx_collision_t2r_st, + edcca_regs->tx_collision_t2r_st_mask, 0x29, bb->phy_idx); +} + +static void rtw89_phy_edcca_init(struct rtw89_dev *rtwdev) +{ + struct rtw89_bb_ctx *bb; + + rtw89_for_each_capab_bb(rtwdev, bb) + __rtw89_phy_edcca_init(rtwdev, bb); } void rtw89_phy_dm_init(struct rtw89_dev *rtwdev) @@ -6875,44 +6979,46 @@ void rtw89_decode_chan_idx(struct rtw89_dev *rtwdev, u8 chan_idx, } EXPORT_SYMBOL(rtw89_decode_chan_idx); -void rtw89_phy_config_edcca(struct rtw89_dev *rtwdev, bool scan) +void rtw89_phy_config_edcca(struct rtw89_dev *rtwdev, + struct rtw89_bb_ctx *bb, bool scan) { const struct rtw89_edcca_regs *edcca_regs = rtwdev->chip->edcca_regs; - struct rtw89_edcca_bak *edcca_bak = &rtwdev->hal.edcca_bak; + struct rtw89_edcca_bak *edcca_bak = &bb->edcca_bak; if (scan) { edcca_bak->a = - rtw89_phy_read32_mask(rtwdev, edcca_regs->edcca_level, - edcca_regs->edcca_mask); + rtw89_phy_read32_idx(rtwdev, edcca_regs->edcca_level, + edcca_regs->edcca_mask, bb->phy_idx); edcca_bak->p = - rtw89_phy_read32_mask(rtwdev, edcca_regs->edcca_level, - edcca_regs->edcca_p_mask); + rtw89_phy_read32_idx(rtwdev, edcca_regs->edcca_level, + edcca_regs->edcca_p_mask, bb->phy_idx); edcca_bak->ppdu = - rtw89_phy_read32_mask(rtwdev, edcca_regs->ppdu_level, - edcca_regs->ppdu_mask); - - rtw89_phy_write32_mask(rtwdev, edcca_regs->edcca_level, - edcca_regs->edcca_mask, EDCCA_MAX); - rtw89_phy_write32_mask(rtwdev, edcca_regs->edcca_level, - edcca_regs->edcca_p_mask, EDCCA_MAX); - rtw89_phy_write32_mask(rtwdev, edcca_regs->ppdu_level, - edcca_regs->ppdu_mask, EDCCA_MAX); + rtw89_phy_read32_idx(rtwdev, edcca_regs->ppdu_level, + edcca_regs->ppdu_mask, bb->phy_idx); + + rtw89_phy_write32_idx(rtwdev, edcca_regs->edcca_level, + edcca_regs->edcca_mask, EDCCA_MAX, bb->phy_idx); + rtw89_phy_write32_idx(rtwdev, edcca_regs->edcca_level, + edcca_regs->edcca_p_mask, EDCCA_MAX, bb->phy_idx); + rtw89_phy_write32_idx(rtwdev, edcca_regs->ppdu_level, + edcca_regs->ppdu_mask, EDCCA_MAX, bb->phy_idx); } else { - rtw89_phy_write32_mask(rtwdev, edcca_regs->edcca_level, - edcca_regs->edcca_mask, - edcca_bak->a); - rtw89_phy_write32_mask(rtwdev, edcca_regs->edcca_level, - edcca_regs->edcca_p_mask, - edcca_bak->p); - rtw89_phy_write32_mask(rtwdev, edcca_regs->ppdu_level, - edcca_regs->ppdu_mask, - edcca_bak->ppdu); + rtw89_phy_write32_idx(rtwdev, edcca_regs->edcca_level, + edcca_regs->edcca_mask, + edcca_bak->a, bb->phy_idx); + rtw89_phy_write32_idx(rtwdev, edcca_regs->edcca_level, + edcca_regs->edcca_p_mask, + edcca_bak->p, bb->phy_idx); + rtw89_phy_write32_idx(rtwdev, edcca_regs->ppdu_level, + edcca_regs->ppdu_mask, + edcca_bak->ppdu, bb->phy_idx); } } -static void rtw89_phy_edcca_log(struct rtw89_dev *rtwdev) +static void rtw89_phy_edcca_log(struct rtw89_dev *rtwdev, struct rtw89_bb_ctx *bb) { const struct rtw89_edcca_regs *edcca_regs = rtwdev->chip->edcca_regs; + const struct rtw89_edcca_p_regs *edcca_p_regs; bool flag_fb, flag_p20, flag_s20, flag_s40, flag_s80; s8 pwdb_fb, pwdb_p20, pwdb_s20, pwdb_s40, pwdb_s80; u8 path, per20_bitmap; @@ -6922,13 +7028,18 @@ static void rtw89_phy_edcca_log(struct rtw89_dev *rtwdev) if (!rtw89_debug_is_enabled(rtwdev, RTW89_DBG_EDCCA)) return; + if (bb->phy_idx == RTW89_PHY_1) + edcca_p_regs = &edcca_regs->p[RTW89_PHY_1]; + else + edcca_p_regs = &edcca_regs->p[RTW89_PHY_0]; + if (rtwdev->chip->chip_id == RTL8922A) rtw89_phy_write32_mask(rtwdev, edcca_regs->rpt_sel_be, edcca_regs->rpt_sel_be_mask, 0); - rtw89_phy_write32_mask(rtwdev, edcca_regs->rpt_sel, - edcca_regs->rpt_sel_mask, 0); - tmp = rtw89_phy_read32(rtwdev, edcca_regs->rpt_b); + rtw89_phy_write32_mask(rtwdev, edcca_p_regs->rpt_sel, + edcca_p_regs->rpt_sel_mask, 0); + tmp = rtw89_phy_read32(rtwdev, edcca_p_regs->rpt_b); path = u32_get_bits(tmp, B_EDCCA_RPT_B_PATH_MASK); flag_s80 = u32_get_bits(tmp, B_EDCCA_RPT_B_S80); flag_s40 = u32_get_bits(tmp, B_EDCCA_RPT_B_S40); @@ -6939,19 +7050,19 @@ static void rtw89_phy_edcca_log(struct rtw89_dev *rtwdev) pwdb_p20 = u32_get_bits(tmp, MASKBYTE2); pwdb_fb = u32_get_bits(tmp, MASKBYTE3); - rtw89_phy_write32_mask(rtwdev, edcca_regs->rpt_sel, - edcca_regs->rpt_sel_mask, 4); - tmp = rtw89_phy_read32(rtwdev, edcca_regs->rpt_b); + rtw89_phy_write32_mask(rtwdev, edcca_p_regs->rpt_sel, + edcca_p_regs->rpt_sel_mask, 4); + tmp = rtw89_phy_read32(rtwdev, edcca_p_regs->rpt_b); pwdb_s80 = u32_get_bits(tmp, MASKBYTE1); pwdb_s40 = u32_get_bits(tmp, MASKBYTE2); - per20_bitmap = rtw89_phy_read32_mask(rtwdev, edcca_regs->rpt_a, + per20_bitmap = rtw89_phy_read32_mask(rtwdev, edcca_p_regs->rpt_a, MASKBYTE0); if (rtwdev->chip->chip_id == RTL8922A) { rtw89_phy_write32_mask(rtwdev, edcca_regs->rpt_sel_be, edcca_regs->rpt_sel_be_mask, 4); - tmp = rtw89_phy_read32(rtwdev, edcca_regs->rpt_b); + tmp = rtw89_phy_read32(rtwdev, edcca_p_regs->rpt_b); pwdb[0] = u32_get_bits(tmp, MASKBYTE3); pwdb[1] = u32_get_bits(tmp, MASKBYTE2); pwdb[2] = u32_get_bits(tmp, MASKBYTE1); @@ -6959,33 +7070,33 @@ static void rtw89_phy_edcca_log(struct rtw89_dev *rtwdev) rtw89_phy_write32_mask(rtwdev, edcca_regs->rpt_sel_be, edcca_regs->rpt_sel_be_mask, 5); - tmp = rtw89_phy_read32(rtwdev, edcca_regs->rpt_b); + tmp = rtw89_phy_read32(rtwdev, edcca_p_regs->rpt_b); pwdb[4] = u32_get_bits(tmp, MASKBYTE3); pwdb[5] = u32_get_bits(tmp, MASKBYTE2); pwdb[6] = u32_get_bits(tmp, MASKBYTE1); pwdb[7] = u32_get_bits(tmp, MASKBYTE0); } else { - rtw89_phy_write32_mask(rtwdev, edcca_regs->rpt_sel, - edcca_regs->rpt_sel_mask, 0); - tmp = rtw89_phy_read32(rtwdev, edcca_regs->rpt_a); + rtw89_phy_write32_mask(rtwdev, edcca_p_regs->rpt_sel, + edcca_p_regs->rpt_sel_mask, 0); + tmp = rtw89_phy_read32(rtwdev, edcca_p_regs->rpt_a); pwdb[0] = u32_get_bits(tmp, MASKBYTE3); pwdb[1] = u32_get_bits(tmp, MASKBYTE2); - rtw89_phy_write32_mask(rtwdev, edcca_regs->rpt_sel, - edcca_regs->rpt_sel_mask, 1); - tmp = rtw89_phy_read32(rtwdev, edcca_regs->rpt_a); + rtw89_phy_write32_mask(rtwdev, edcca_p_regs->rpt_sel, + edcca_p_regs->rpt_sel_mask, 1); + tmp = rtw89_phy_read32(rtwdev, edcca_p_regs->rpt_a); pwdb[2] = u32_get_bits(tmp, MASKBYTE3); pwdb[3] = u32_get_bits(tmp, MASKBYTE2); - rtw89_phy_write32_mask(rtwdev, edcca_regs->rpt_sel, - edcca_regs->rpt_sel_mask, 2); - tmp = rtw89_phy_read32(rtwdev, edcca_regs->rpt_a); + rtw89_phy_write32_mask(rtwdev, edcca_p_regs->rpt_sel, + edcca_p_regs->rpt_sel_mask, 2); + tmp = rtw89_phy_read32(rtwdev, edcca_p_regs->rpt_a); pwdb[4] = u32_get_bits(tmp, MASKBYTE3); pwdb[5] = u32_get_bits(tmp, MASKBYTE2); - rtw89_phy_write32_mask(rtwdev, edcca_regs->rpt_sel, - edcca_regs->rpt_sel_mask, 3); - tmp = rtw89_phy_read32(rtwdev, edcca_regs->rpt_a); + rtw89_phy_write32_mask(rtwdev, edcca_p_regs->rpt_sel, + edcca_p_regs->rpt_sel_mask, 3); + tmp = rtw89_phy_read32(rtwdev, edcca_p_regs->rpt_a); pwdb[6] = u32_get_bits(tmp, MASKBYTE3); pwdb[7] = u32_get_bits(tmp, MASKBYTE2); } @@ -7007,9 +7118,10 @@ static void rtw89_phy_edcca_log(struct rtw89_dev *rtwdev) pwdb_fb, pwdb_p20, pwdb_s20, pwdb_s40, pwdb_s80); } -static u8 rtw89_phy_edcca_get_thre_by_rssi(struct rtw89_dev *rtwdev) +static u8 rtw89_phy_edcca_get_thre_by_rssi(struct rtw89_dev *rtwdev, + struct rtw89_bb_ctx *bb) { - struct rtw89_phy_ch_info *ch_info = &rtwdev->ch_info; + struct rtw89_phy_ch_info *ch_info = &bb->ch_info; bool is_linked = rtwdev->total_sta_assoc > 0; u8 rssi_min = ch_info->rssi_min >> 1; u8 edcca_thre; @@ -7025,13 +7137,13 @@ static u8 rtw89_phy_edcca_get_thre_by_rssi(struct rtw89_dev *rtwdev) return edcca_thre; } -void rtw89_phy_edcca_thre_calc(struct rtw89_dev *rtwdev) +void rtw89_phy_edcca_thre_calc(struct rtw89_dev *rtwdev, struct rtw89_bb_ctx *bb) { const struct rtw89_edcca_regs *edcca_regs = rtwdev->chip->edcca_regs; - struct rtw89_edcca_bak *edcca_bak = &rtwdev->hal.edcca_bak; + struct rtw89_edcca_bak *edcca_bak = &bb->edcca_bak; u8 th; - th = rtw89_phy_edcca_get_thre_by_rssi(rtwdev); + th = rtw89_phy_edcca_get_thre_by_rssi(rtwdev, bb); if (th == edcca_bak->th_old) return; @@ -7040,23 +7152,33 @@ void rtw89_phy_edcca_thre_calc(struct rtw89_dev *rtwdev) rtw89_debug(rtwdev, RTW89_DBG_EDCCA, "[EDCCA]: Normal Mode, EDCCA_th = %d\n", th); - rtw89_phy_write32_mask(rtwdev, edcca_regs->edcca_level, - edcca_regs->edcca_mask, th); - rtw89_phy_write32_mask(rtwdev, edcca_regs->edcca_level, - edcca_regs->edcca_p_mask, th); - rtw89_phy_write32_mask(rtwdev, edcca_regs->ppdu_level, - edcca_regs->ppdu_mask, th); + rtw89_phy_write32_idx(rtwdev, edcca_regs->edcca_level, + edcca_regs->edcca_mask, th, bb->phy_idx); + rtw89_phy_write32_idx(rtwdev, edcca_regs->edcca_level, + edcca_regs->edcca_p_mask, th, bb->phy_idx); + rtw89_phy_write32_idx(rtwdev, edcca_regs->ppdu_level, + edcca_regs->ppdu_mask, th, bb->phy_idx); +} + +static +void __rtw89_phy_edcca_track(struct rtw89_dev *rtwdev, struct rtw89_bb_ctx *bb) +{ + rtw89_debug(rtwdev, RTW89_DBG_EDCCA, "BB-%d edcca track\n", bb->phy_idx); + + rtw89_phy_edcca_thre_calc(rtwdev, bb); + rtw89_phy_edcca_log(rtwdev, bb); } void rtw89_phy_edcca_track(struct rtw89_dev *rtwdev) { struct rtw89_hal *hal = &rtwdev->hal; + struct rtw89_bb_ctx *bb; if (hal->disabled_dm_bitmap & BIT(RTW89_DM_DYNAMIC_EDCCA)) return; - rtw89_phy_edcca_thre_calc(rtwdev); - rtw89_phy_edcca_log(rtwdev); + rtw89_for_each_active_bb(rtwdev, bb) + __rtw89_phy_edcca_track(rtwdev, bb); } enum rtw89_rf_path_bit rtw89_phy_get_kpath(struct rtw89_dev *rtwdev, diff --git a/drivers/net/wireless/realtek/rtw89/phy.h b/drivers/net/wireless/realtek/rtw89/phy.h index 08b635c93ac3..e20fff9bac3e 100644 --- a/drivers/net/wireless/realtek/rtw89/phy.h +++ b/drivers/net/wireless/realtek/rtw89/phy.h @@ -835,8 +835,8 @@ s8 rtw89_phy_read_txpwr_byrate(struct rtw89_dev *rtwdev, u8 band, u8 bw, void rtw89_phy_ant_gain_init(struct rtw89_dev *rtwdev); s16 rtw89_phy_ant_gain_pwr_offset(struct rtw89_dev *rtwdev, const struct rtw89_chan *chan); -void rtw89_print_ant_gain(struct seq_file *m, struct rtw89_dev *rtwdev, - const struct rtw89_chan *chan); +int rtw89_print_ant_gain(struct rtw89_dev *rtwdev, char *buf, size_t bufsz, + const struct rtw89_chan *chan); void rtw89_phy_load_txpwr_byrate(struct rtw89_dev *rtwdev, const struct rtw89_txpwr_table *tbl); s8 rtw89_phy_read_txpwr_limit(struct rtw89_dev *rtwdev, u8 band, @@ -978,20 +978,20 @@ void rtw89_phy_rfk_tssi_fill_fwcmd_tmeter_tbl(struct rtw89_dev *rtwdev, const struct rtw89_chan *chan, struct rtw89_h2c_rf_tssi *h2c); void rtw89_phy_cfo_track(struct rtw89_dev *rtwdev); -void rtw89_phy_cfo_track_work(struct work_struct *work); +void rtw89_phy_cfo_track_work(struct wiphy *wiphy, struct wiphy_work *work); void rtw89_phy_cfo_parse(struct rtw89_dev *rtwdev, s16 cfo_val, struct rtw89_rx_phy_ppdu *phy_ppdu); void rtw89_phy_stat_track(struct rtw89_dev *rtwdev); void rtw89_phy_env_monitor_track(struct rtw89_dev *rtwdev); void rtw89_phy_set_phy_regs(struct rtw89_dev *rtwdev, u32 addr, u32 mask, u32 val); -void rtw89_phy_dig_reset(struct rtw89_dev *rtwdev); +void rtw89_phy_dig_reset(struct rtw89_dev *rtwdev, struct rtw89_bb_ctx *bb); void rtw89_phy_dig(struct rtw89_dev *rtwdev); void rtw89_phy_tx_path_div_track(struct rtw89_dev *rtwdev); void rtw89_phy_antdiv_parse(struct rtw89_dev *rtwdev, struct rtw89_rx_phy_ppdu *phy_ppdu); void rtw89_phy_antdiv_track(struct rtw89_dev *rtwdev); -void rtw89_phy_antdiv_work(struct work_struct *work); +void rtw89_phy_antdiv_work(struct wiphy *wiphy, struct wiphy_work *work); void rtw89_phy_set_bss_color(struct rtw89_dev *rtwdev, struct rtw89_vif_link *rtwvif_link); void rtw89_phy_tssi_ctrl_set_bandedge_cfg(struct rtw89_dev *rtwdev, @@ -1002,9 +1002,10 @@ void rtw89_phy_ul_tb_ctrl_track(struct rtw89_dev *rtwdev); u8 rtw89_encode_chan_idx(struct rtw89_dev *rtwdev, u8 central_ch, u8 band); void rtw89_decode_chan_idx(struct rtw89_dev *rtwdev, u8 chan_idx, u8 *ch, enum nl80211_band *band); -void rtw89_phy_config_edcca(struct rtw89_dev *rtwdev, bool scan); +void rtw89_phy_config_edcca(struct rtw89_dev *rtwdev, + struct rtw89_bb_ctx *bb, bool scan); void rtw89_phy_edcca_track(struct rtw89_dev *rtwdev); -void rtw89_phy_edcca_thre_calc(struct rtw89_dev *rtwdev); +void rtw89_phy_edcca_thre_calc(struct rtw89_dev *rtwdev, struct rtw89_bb_ctx *bb); enum rtw89_rf_path_bit rtw89_phy_get_kpath(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy_idx); enum rtw89_rf_path rtw89_phy_get_syn_sel(struct rtw89_dev *rtwdev, diff --git a/drivers/net/wireless/realtek/rtw89/ps.c b/drivers/net/wireless/realtek/rtw89/ps.c index 96ea04d90cd3..ac46a7baa00d 100644 --- a/drivers/net/wireless/realtek/rtw89/ps.c +++ b/drivers/net/wireless/realtek/rtw89/ps.c @@ -113,7 +113,7 @@ static void __rtw89_leave_lps(struct rtw89_dev *rtwdev, void rtw89_leave_ps_mode(struct rtw89_dev *rtwdev) { - lockdep_assert_held(&rtwdev->mutex); + lockdep_assert_wiphy(rtwdev->hw->wiphy); __rtw89_leave_ps_mode(rtwdev); } @@ -125,7 +125,7 @@ void rtw89_enter_lps(struct rtw89_dev *rtwdev, struct rtw89_vif *rtwvif, bool can_ps_mode = true; unsigned int link_id; - lockdep_assert_held(&rtwdev->mutex); + lockdep_assert_wiphy(rtwdev->hw->wiphy); if (test_and_set_bit(RTW89_FLAG_LEISURE_PS, rtwdev->flags)) return; @@ -162,7 +162,7 @@ void rtw89_leave_lps(struct rtw89_dev *rtwdev) struct rtw89_vif *rtwvif; unsigned int link_id; - lockdep_assert_held(&rtwdev->mutex); + lockdep_assert_wiphy(rtwdev->hw->wiphy); if (!test_and_clear_bit(RTW89_FLAG_LEISURE_PS, rtwdev->flags)) return; diff --git a/drivers/net/wireless/realtek/rtw89/reg.h b/drivers/net/wireless/realtek/rtw89/reg.h index 10d0efa7a58e..c992835d4b63 100644 --- a/drivers/net/wireless/realtek/rtw89/reg.h +++ b/drivers/net/wireless/realtek/rtw89/reg.h @@ -8157,6 +8157,8 @@ #define B_EDCCA_RPT_B_S40 BIT(4) #define B_EDCCA_RPT_B_S80 BIT(3) #define B_EDCCA_RPT_B_PATH_MASK GENMASK(2, 1) +#define R_EDCCA_RPT_P1_A 0x1740 +#define R_EDCCA_RPT_P1_B 0x1744 #define R_SWSI_V1 0x174C #define B_SWSI_W_BUSY_V1 BIT(24) #define B_SWSI_R_BUSY_V1 BIT(25) @@ -8222,6 +8224,7 @@ #define B_TXCKEN_FORCE_ALL GENMASK(24, 0) #define R_EDCCA_RPT_SEL 0x20CC #define B_EDCCA_RPT_SEL_MSK GENMASK(2, 0) +#define B_EDCCA_RPT_SEL_P1_MSK GENMASK(5, 3) #define R_ADC_FIFO 0x20fc #define B_ADC_FIFO_RST GENMASK(31, 24) #define B_ADC_FIFO_RXK GENMASK(31, 16) @@ -8291,6 +8294,8 @@ #define B_P1_EN_SOUND_WO_NDP BIT(1) #define R_EDCCA_RPT_A_BE 0x2E38 #define R_EDCCA_RPT_B_BE 0x2E3C +#define R_EDCCA_RPT_P1_A_BE 0x2E40 +#define R_EDCCA_RPT_P1_B_BE 0x2E44 #define R_S1_HW_SI_DIS 0x3200 #define B_S1_HW_SI_DIS_W_R_TRIG GENMASK(30, 28) #define R_P1_RXCK 0x32A0 diff --git a/drivers/net/wireless/realtek/rtw89/regd.c b/drivers/net/wireless/realtek/rtw89/regd.c index 80b2f74589eb..0e67d0f128dd 100644 --- a/drivers/net/wireless/realtek/rtw89/regd.c +++ b/drivers/net/wireless/realtek/rtw89/regd.c @@ -7,257 +7,266 @@ #include "ps.h" #include "util.h" -#define COUNTRY_REGD(_alpha2, _txpwr_regd...) \ - {.alpha2 = (_alpha2), \ - .txpwr_regd = {_txpwr_regd}, \ +static +void rtw89_regd_notifier(struct wiphy *wiphy, struct regulatory_request *request); + +#define COUNTRY_REGD(_alpha2, _rule_2ghz, _rule_5ghz, _rule_6ghz, _fmap) \ + { \ + .alpha2 = _alpha2, \ + .txpwr_regd[RTW89_BAND_2G] = _rule_2ghz, \ + .txpwr_regd[RTW89_BAND_5G] = _rule_5ghz, \ + .txpwr_regd[RTW89_BAND_6G] = _rule_6ghz, \ + .func_bitmap = { _fmap, }, \ } +static_assert(BITS_PER_TYPE(unsigned long) >= NUM_OF_RTW89_REGD_FUNC); + static const struct rtw89_regd rtw89_ww_regd = - COUNTRY_REGD("00", RTW89_WW, RTW89_WW, RTW89_WW); + COUNTRY_REGD("00", RTW89_WW, RTW89_WW, RTW89_WW, 0x0); static const struct rtw89_regd rtw89_regd_map[] = { - COUNTRY_REGD("AR", RTW89_MEXICO, RTW89_MEXICO, RTW89_FCC), - COUNTRY_REGD("BO", RTW89_FCC, RTW89_FCC, RTW89_NA), - COUNTRY_REGD("BR", RTW89_FCC, RTW89_FCC, RTW89_FCC), - COUNTRY_REGD("CL", RTW89_CHILE, RTW89_CHILE, RTW89_CHILE), - COUNTRY_REGD("CO", RTW89_FCC, RTW89_FCC, RTW89_FCC), - COUNTRY_REGD("CR", RTW89_FCC, RTW89_FCC, RTW89_FCC), - COUNTRY_REGD("EC", RTW89_FCC, RTW89_FCC, RTW89_NA), - COUNTRY_REGD("SV", RTW89_FCC, RTW89_FCC, RTW89_FCC), - COUNTRY_REGD("GT", RTW89_FCC, RTW89_FCC, RTW89_FCC), - COUNTRY_REGD("HN", RTW89_FCC, RTW89_FCC, RTW89_FCC), - COUNTRY_REGD("MX", RTW89_MEXICO, RTW89_MEXICO, RTW89_FCC), - COUNTRY_REGD("NI", RTW89_FCC, RTW89_FCC, RTW89_NA), - COUNTRY_REGD("PA", RTW89_FCC, RTW89_FCC, RTW89_NA), - COUNTRY_REGD("PY", RTW89_FCC, RTW89_FCC, RTW89_NA), - COUNTRY_REGD("PE", RTW89_FCC, RTW89_FCC, RTW89_FCC), - COUNTRY_REGD("US", RTW89_FCC, RTW89_FCC, RTW89_FCC), - COUNTRY_REGD("UY", RTW89_FCC, RTW89_FCC, RTW89_NA), - COUNTRY_REGD("VE", RTW89_FCC, RTW89_FCC, RTW89_NA), - COUNTRY_REGD("PR", RTW89_FCC, RTW89_FCC, RTW89_NA), - COUNTRY_REGD("DO", RTW89_FCC, RTW89_FCC, RTW89_FCC), - COUNTRY_REGD("AT", RTW89_ETSI, RTW89_ETSI, RTW89_ETSI), - COUNTRY_REGD("BE", RTW89_ETSI, RTW89_ETSI, RTW89_ETSI), - COUNTRY_REGD("CY", RTW89_ETSI, RTW89_ETSI, RTW89_ETSI), - COUNTRY_REGD("CZ", RTW89_ETSI, RTW89_ETSI, RTW89_ETSI), - COUNTRY_REGD("DK", RTW89_ETSI, RTW89_ETSI, RTW89_ETSI), - COUNTRY_REGD("EE", RTW89_ETSI, RTW89_ETSI, RTW89_ETSI), - COUNTRY_REGD("FI", RTW89_ETSI, RTW89_ETSI, RTW89_ETSI), - COUNTRY_REGD("FR", RTW89_ETSI, RTW89_ETSI, RTW89_ETSI), - COUNTRY_REGD("DE", RTW89_ETSI, RTW89_ETSI, RTW89_ETSI), - COUNTRY_REGD("GR", RTW89_ETSI, RTW89_ETSI, RTW89_ETSI), - COUNTRY_REGD("HU", RTW89_ETSI, RTW89_ETSI, RTW89_ETSI), - COUNTRY_REGD("IS", RTW89_ETSI, RTW89_ETSI, RTW89_ETSI), - COUNTRY_REGD("IE", RTW89_ETSI, RTW89_ETSI, RTW89_ETSI), - COUNTRY_REGD("IT", RTW89_ETSI, RTW89_ETSI, RTW89_ETSI), - COUNTRY_REGD("LV", RTW89_ETSI, RTW89_ETSI, RTW89_ETSI), - COUNTRY_REGD("LI", RTW89_ETSI, RTW89_ETSI, RTW89_ETSI), - COUNTRY_REGD("LT", RTW89_ETSI, RTW89_ETSI, RTW89_ETSI), - COUNTRY_REGD("LU", RTW89_ETSI, RTW89_ETSI, RTW89_ETSI), - COUNTRY_REGD("MT", RTW89_ETSI, RTW89_ETSI, RTW89_ETSI), - COUNTRY_REGD("MC", RTW89_ETSI, RTW89_ETSI, RTW89_ETSI), - COUNTRY_REGD("NL", RTW89_ETSI, RTW89_ETSI, RTW89_ETSI), - COUNTRY_REGD("NO", RTW89_ETSI, RTW89_ETSI, RTW89_ETSI), - COUNTRY_REGD("PL", RTW89_ETSI, RTW89_ETSI, RTW89_ETSI), - COUNTRY_REGD("PT", RTW89_ETSI, RTW89_ETSI, RTW89_ETSI), - COUNTRY_REGD("SK", RTW89_ETSI, RTW89_ETSI, RTW89_ETSI), - COUNTRY_REGD("SI", RTW89_ETSI, RTW89_ETSI, RTW89_ETSI), - COUNTRY_REGD("ES", RTW89_ETSI, RTW89_ETSI, RTW89_ETSI), - COUNTRY_REGD("SE", RTW89_ETSI, RTW89_ETSI, RTW89_ETSI), - COUNTRY_REGD("CH", RTW89_ETSI, RTW89_ETSI, RTW89_ETSI), - COUNTRY_REGD("GB", RTW89_UK, RTW89_UK, RTW89_UK), - COUNTRY_REGD("AL", RTW89_ETSI, RTW89_ETSI, RTW89_NA), - COUNTRY_REGD("AZ", RTW89_ETSI, RTW89_ETSI, RTW89_ETSI), - COUNTRY_REGD("BH", RTW89_ETSI, RTW89_ETSI, RTW89_ETSI), - COUNTRY_REGD("BA", RTW89_ETSI, RTW89_ETSI, RTW89_NA), - COUNTRY_REGD("BG", RTW89_ETSI, RTW89_ETSI, RTW89_ETSI), - COUNTRY_REGD("HR", RTW89_ETSI, RTW89_ETSI, RTW89_ETSI), - COUNTRY_REGD("EG", RTW89_ETSI, RTW89_ETSI, RTW89_ETSI), - COUNTRY_REGD("GH", RTW89_ETSI, RTW89_ETSI, RTW89_ETSI), - COUNTRY_REGD("IQ", RTW89_ETSI, RTW89_ETSI, RTW89_NA), - COUNTRY_REGD("IL", RTW89_ETSI, RTW89_ETSI, RTW89_ETSI), - COUNTRY_REGD("JO", RTW89_ETSI, RTW89_ETSI, RTW89_ETSI), - COUNTRY_REGD("KZ", RTW89_ETSI, RTW89_ETSI, RTW89_NA), - COUNTRY_REGD("KE", RTW89_ETSI, RTW89_ETSI, RTW89_ETSI), - COUNTRY_REGD("KW", RTW89_ETSI, RTW89_ETSI, RTW89_ETSI), - COUNTRY_REGD("KG", RTW89_ETSI, RTW89_ETSI, RTW89_ETSI), - COUNTRY_REGD("LB", RTW89_ETSI, RTW89_ETSI, RTW89_ETSI), - COUNTRY_REGD("LS", RTW89_ETSI, RTW89_ETSI, RTW89_ETSI), - COUNTRY_REGD("MK", RTW89_ETSI, RTW89_ETSI, RTW89_NA), - COUNTRY_REGD("MA", RTW89_ETSI, RTW89_ETSI, RTW89_ETSI), - COUNTRY_REGD("MZ", RTW89_ETSI, RTW89_ETSI, RTW89_ETSI), - COUNTRY_REGD("NA", RTW89_ETSI, RTW89_ETSI, RTW89_NA), - COUNTRY_REGD("NG", RTW89_ETSI, RTW89_ETSI, RTW89_ETSI), - COUNTRY_REGD("OM", RTW89_ETSI, RTW89_ETSI, RTW89_ETSI), - COUNTRY_REGD("QA", RTW89_QATAR, RTW89_QATAR, RTW89_QATAR), - COUNTRY_REGD("RO", RTW89_ETSI, RTW89_ETSI, RTW89_ETSI), - COUNTRY_REGD("RU", RTW89_ETSI, RTW89_ETSI, RTW89_NA), - COUNTRY_REGD("SA", RTW89_ETSI, RTW89_ETSI, RTW89_ETSI), - COUNTRY_REGD("SN", RTW89_ETSI, RTW89_ETSI, RTW89_NA), - COUNTRY_REGD("RS", RTW89_ETSI, RTW89_ETSI, RTW89_ETSI), - COUNTRY_REGD("ME", RTW89_ETSI, RTW89_ETSI, RTW89_NA), - COUNTRY_REGD("ZA", RTW89_ETSI, RTW89_ETSI, RTW89_ETSI), - COUNTRY_REGD("TR", RTW89_ETSI, RTW89_ETSI, RTW89_ETSI), - COUNTRY_REGD("UA", RTW89_UKRAINE, RTW89_UKRAINE, RTW89_UKRAINE), - COUNTRY_REGD("AE", RTW89_ETSI, RTW89_ETSI, RTW89_ETSI), - COUNTRY_REGD("YE", RTW89_ETSI, RTW89_ETSI, RTW89_NA), - COUNTRY_REGD("ZW", RTW89_ETSI, RTW89_ETSI, RTW89_ETSI), - COUNTRY_REGD("BD", RTW89_ETSI, RTW89_ETSI, RTW89_NA), - COUNTRY_REGD("KH", RTW89_ETSI, RTW89_ETSI, RTW89_NA), - COUNTRY_REGD("CN", RTW89_CN, RTW89_CN, RTW89_CN), - COUNTRY_REGD("HK", RTW89_ETSI, RTW89_ETSI, RTW89_ETSI), - COUNTRY_REGD("IN", RTW89_ETSI, RTW89_ETSI, RTW89_NA), - COUNTRY_REGD("ID", RTW89_ETSI, RTW89_ETSI, RTW89_NA), - COUNTRY_REGD("KR", RTW89_KCC, RTW89_KCC, RTW89_KCC), - COUNTRY_REGD("MY", RTW89_ETSI, RTW89_ETSI, RTW89_ETSI), - COUNTRY_REGD("PK", RTW89_ETSI, RTW89_ETSI, RTW89_ETSI), - COUNTRY_REGD("PH", RTW89_ETSI, RTW89_ETSI, RTW89_ETSI), - COUNTRY_REGD("SG", RTW89_ETSI, RTW89_ETSI, RTW89_ETSI), - COUNTRY_REGD("LK", RTW89_ETSI, RTW89_ETSI, RTW89_NA), - COUNTRY_REGD("TW", RTW89_FCC, RTW89_FCC, RTW89_ETSI), - COUNTRY_REGD("TH", RTW89_THAILAND, RTW89_THAILAND, RTW89_THAILAND), - COUNTRY_REGD("VN", RTW89_ETSI, RTW89_ETSI, RTW89_NA), - COUNTRY_REGD("AU", RTW89_ACMA, RTW89_ACMA, RTW89_ACMA), - COUNTRY_REGD("NZ", RTW89_ACMA, RTW89_ACMA, RTW89_ACMA), - COUNTRY_REGD("PG", RTW89_ETSI, RTW89_ETSI, RTW89_ETSI), - COUNTRY_REGD("CA", RTW89_IC, RTW89_IC, RTW89_IC), - COUNTRY_REGD("JP", RTW89_MKK, RTW89_MKK, RTW89_MKK), - COUNTRY_REGD("JM", RTW89_FCC, RTW89_FCC, RTW89_FCC), - COUNTRY_REGD("AN", RTW89_FCC, RTW89_FCC, RTW89_FCC), - COUNTRY_REGD("TT", RTW89_FCC, RTW89_FCC, RTW89_NA), - COUNTRY_REGD("TN", RTW89_ETSI, RTW89_ETSI, RTW89_NA), - COUNTRY_REGD("AF", RTW89_ETSI, RTW89_ETSI, RTW89_NA), - COUNTRY_REGD("DZ", RTW89_ETSI, RTW89_ETSI, RTW89_ETSI), - COUNTRY_REGD("AS", RTW89_FCC, RTW89_FCC, RTW89_NA), - COUNTRY_REGD("AD", RTW89_ETSI, RTW89_ETSI, RTW89_NA), - COUNTRY_REGD("AO", RTW89_ETSI, RTW89_ETSI, RTW89_NA), - COUNTRY_REGD("AI", RTW89_ETSI, RTW89_ETSI, RTW89_ETSI), - COUNTRY_REGD("AQ", RTW89_ETSI, RTW89_ETSI, RTW89_NA), - COUNTRY_REGD("AG", RTW89_FCC, RTW89_FCC, RTW89_FCC), - COUNTRY_REGD("AM", RTW89_ETSI, RTW89_ETSI, RTW89_ETSI), - COUNTRY_REGD("AW", RTW89_FCC, RTW89_FCC, RTW89_FCC), - COUNTRY_REGD("BS", RTW89_FCC, RTW89_FCC, RTW89_FCC), - COUNTRY_REGD("BB", RTW89_FCC, RTW89_FCC, RTW89_FCC), - COUNTRY_REGD("BY", RTW89_ETSI, RTW89_ETSI, RTW89_NA), - COUNTRY_REGD("BZ", RTW89_FCC, RTW89_FCC, RTW89_NA), - COUNTRY_REGD("BJ", RTW89_ETSI, RTW89_ETSI, RTW89_NA), - COUNTRY_REGD("BM", RTW89_FCC, RTW89_FCC, RTW89_FCC), - COUNTRY_REGD("BT", RTW89_ETSI, RTW89_ETSI, RTW89_NA), - COUNTRY_REGD("BW", RTW89_ETSI, RTW89_ETSI, RTW89_ETSI), - COUNTRY_REGD("BV", RTW89_ETSI, RTW89_ETSI, RTW89_NA), - COUNTRY_REGD("IO", RTW89_ETSI, RTW89_ETSI, RTW89_NA), - COUNTRY_REGD("VG", RTW89_FCC, RTW89_FCC, RTW89_FCC), - COUNTRY_REGD("BN", RTW89_ETSI, RTW89_ETSI, RTW89_NA), - COUNTRY_REGD("BF", RTW89_ETSI, RTW89_ETSI, RTW89_ETSI), - COUNTRY_REGD("MM", RTW89_ETSI, RTW89_ETSI, RTW89_NA), - COUNTRY_REGD("BI", RTW89_ETSI, RTW89_ETSI, RTW89_ETSI), - COUNTRY_REGD("CM", RTW89_ETSI, RTW89_ETSI, RTW89_NA), - COUNTRY_REGD("CV", RTW89_ETSI, RTW89_ETSI, RTW89_NA), - COUNTRY_REGD("KY", RTW89_FCC, RTW89_FCC, RTW89_FCC), - COUNTRY_REGD("CF", RTW89_ETSI, RTW89_ETSI, RTW89_NA), - COUNTRY_REGD("TD", RTW89_ETSI, RTW89_ETSI, RTW89_ETSI), - COUNTRY_REGD("CX", RTW89_ACMA, RTW89_ACMA, RTW89_NA), - COUNTRY_REGD("CC", RTW89_ACMA, RTW89_ACMA, RTW89_NA), - COUNTRY_REGD("KM", RTW89_ETSI, RTW89_ETSI, RTW89_NA), - COUNTRY_REGD("CG", RTW89_ETSI, RTW89_ETSI, RTW89_ETSI), - COUNTRY_REGD("CD", RTW89_ETSI, RTW89_ETSI, RTW89_ETSI), - COUNTRY_REGD("CK", RTW89_ETSI, RTW89_ETSI, RTW89_NA), - COUNTRY_REGD("CI", RTW89_ETSI, RTW89_ETSI, RTW89_NA), - COUNTRY_REGD("DJ", RTW89_ETSI, RTW89_ETSI, RTW89_ETSI), - COUNTRY_REGD("DM", RTW89_FCC, RTW89_FCC, RTW89_NA), - COUNTRY_REGD("GQ", RTW89_ETSI, RTW89_ETSI, RTW89_ETSI), - COUNTRY_REGD("ER", RTW89_ETSI, RTW89_ETSI, RTW89_NA), - COUNTRY_REGD("ET", RTW89_ETSI, RTW89_ETSI, RTW89_NA), - COUNTRY_REGD("FK", RTW89_ETSI, RTW89_ETSI, RTW89_NA), - COUNTRY_REGD("FO", RTW89_ETSI, RTW89_ETSI, RTW89_NA), - COUNTRY_REGD("FJ", RTW89_FCC, RTW89_FCC, RTW89_NA), - COUNTRY_REGD("GF", RTW89_ETSI, RTW89_ETSI, RTW89_NA), - COUNTRY_REGD("PF", RTW89_ETSI, RTW89_ETSI, RTW89_NA), - COUNTRY_REGD("TF", RTW89_ETSI, RTW89_ETSI, RTW89_NA), - COUNTRY_REGD("GA", RTW89_ETSI, RTW89_ETSI, RTW89_NA), - COUNTRY_REGD("GM", RTW89_ETSI, RTW89_ETSI, RTW89_ETSI), - COUNTRY_REGD("GE", RTW89_ETSI, RTW89_ETSI, RTW89_ETSI), - COUNTRY_REGD("GI", RTW89_ETSI, RTW89_ETSI, RTW89_ETSI), - COUNTRY_REGD("GL", RTW89_ETSI, RTW89_ETSI, RTW89_NA), - COUNTRY_REGD("GD", RTW89_FCC, RTW89_FCC, RTW89_FCC), - COUNTRY_REGD("GP", RTW89_ETSI, RTW89_ETSI, RTW89_NA), - COUNTRY_REGD("GU", RTW89_FCC, RTW89_FCC, RTW89_FCC), - COUNTRY_REGD("GG", RTW89_ETSI, RTW89_ETSI, RTW89_NA), - COUNTRY_REGD("GN", RTW89_ETSI, RTW89_ETSI, RTW89_ETSI), - COUNTRY_REGD("GW", RTW89_ETSI, RTW89_ETSI, RTW89_NA), - COUNTRY_REGD("GY", RTW89_FCC, RTW89_FCC, RTW89_NA), - COUNTRY_REGD("HT", RTW89_FCC, RTW89_FCC, RTW89_FCC), - COUNTRY_REGD("HM", RTW89_ACMA, RTW89_ACMA, RTW89_NA), - COUNTRY_REGD("VA", RTW89_ETSI, RTW89_ETSI, RTW89_NA), - COUNTRY_REGD("IM", RTW89_ETSI, RTW89_ETSI, RTW89_NA), - COUNTRY_REGD("JE", RTW89_ETSI, RTW89_ETSI, RTW89_NA), - COUNTRY_REGD("KI", RTW89_ETSI, RTW89_ETSI, RTW89_NA), - COUNTRY_REGD("XK", RTW89_ETSI, RTW89_ETSI, RTW89_ETSI), - COUNTRY_REGD("LA", RTW89_ETSI, RTW89_ETSI, RTW89_ETSI), - COUNTRY_REGD("LR", RTW89_ETSI, RTW89_ETSI, RTW89_ETSI), - COUNTRY_REGD("LY", RTW89_ETSI, RTW89_ETSI, RTW89_NA), - COUNTRY_REGD("MO", RTW89_ETSI, RTW89_ETSI, RTW89_NA), - COUNTRY_REGD("MG", RTW89_ETSI, RTW89_ETSI, RTW89_ETSI), - COUNTRY_REGD("MW", RTW89_ETSI, RTW89_ETSI, RTW89_NA), - COUNTRY_REGD("MV", RTW89_ETSI, RTW89_ETSI, RTW89_NA), - COUNTRY_REGD("ML", RTW89_ETSI, RTW89_ETSI, RTW89_NA), - COUNTRY_REGD("MH", RTW89_FCC, RTW89_FCC, RTW89_FCC), - COUNTRY_REGD("MQ", RTW89_ETSI, RTW89_ETSI, RTW89_NA), - COUNTRY_REGD("MR", RTW89_ETSI, RTW89_ETSI, RTW89_NA), - COUNTRY_REGD("MU", RTW89_ETSI, RTW89_ETSI, RTW89_ETSI), - COUNTRY_REGD("YT", RTW89_ETSI, RTW89_ETSI, RTW89_NA), - COUNTRY_REGD("FM", RTW89_FCC, RTW89_FCC, RTW89_FCC), - COUNTRY_REGD("MD", RTW89_ETSI, RTW89_ETSI, RTW89_ETSI), - COUNTRY_REGD("MN", RTW89_ETSI, RTW89_ETSI, RTW89_ETSI), - COUNTRY_REGD("MS", RTW89_ETSI, RTW89_ETSI, RTW89_NA), - COUNTRY_REGD("NR", RTW89_ETSI, RTW89_ETSI, RTW89_NA), - COUNTRY_REGD("NP", RTW89_ETSI, RTW89_ETSI, RTW89_NA), - COUNTRY_REGD("NC", RTW89_ETSI, RTW89_ETSI, RTW89_NA), - COUNTRY_REGD("NE", RTW89_ETSI, RTW89_ETSI, RTW89_NA), - COUNTRY_REGD("NU", RTW89_ACMA, RTW89_ACMA, RTW89_NA), - COUNTRY_REGD("NF", RTW89_ACMA, RTW89_ACMA, RTW89_NA), - COUNTRY_REGD("MP", RTW89_FCC, RTW89_FCC, RTW89_FCC), - COUNTRY_REGD("PW", RTW89_FCC, RTW89_FCC, RTW89_FCC), - COUNTRY_REGD("RE", RTW89_ETSI, RTW89_ETSI, RTW89_NA), - COUNTRY_REGD("RW", RTW89_ETSI, RTW89_ETSI, RTW89_NA), - COUNTRY_REGD("SH", RTW89_ETSI, RTW89_ETSI, RTW89_NA), - COUNTRY_REGD("KN", RTW89_FCC, RTW89_FCC, RTW89_FCC), - COUNTRY_REGD("LC", RTW89_FCC, RTW89_FCC, RTW89_FCC), - COUNTRY_REGD("MF", RTW89_FCC, RTW89_FCC, RTW89_FCC), - COUNTRY_REGD("SX", RTW89_FCC, RTW89_FCC, RTW89_FCC), - COUNTRY_REGD("PM", RTW89_ETSI, RTW89_ETSI, RTW89_NA), - COUNTRY_REGD("VC", RTW89_FCC, RTW89_FCC, RTW89_NA), - COUNTRY_REGD("WS", RTW89_FCC, RTW89_FCC, RTW89_NA), - COUNTRY_REGD("SM", RTW89_ETSI, RTW89_ETSI, RTW89_NA), - COUNTRY_REGD("ST", RTW89_ETSI, RTW89_ETSI, RTW89_NA), - COUNTRY_REGD("SC", RTW89_FCC, RTW89_FCC, RTW89_NA), - COUNTRY_REGD("SL", RTW89_ETSI, RTW89_ETSI, RTW89_ETSI), - COUNTRY_REGD("SB", RTW89_ETSI, RTW89_ETSI, RTW89_NA), - COUNTRY_REGD("SO", RTW89_ETSI, RTW89_ETSI, RTW89_NA), - COUNTRY_REGD("GS", RTW89_ETSI, RTW89_ETSI, RTW89_NA), - COUNTRY_REGD("SR", RTW89_FCC, RTW89_FCC, RTW89_FCC), - COUNTRY_REGD("SJ", RTW89_ETSI, RTW89_ETSI, RTW89_NA), - COUNTRY_REGD("SZ", RTW89_ETSI, RTW89_ETSI, RTW89_ETSI), - COUNTRY_REGD("TJ", RTW89_ETSI, RTW89_ETSI, RTW89_ETSI), - COUNTRY_REGD("TZ", RTW89_ETSI, RTW89_ETSI, RTW89_ETSI), - COUNTRY_REGD("TG", RTW89_ETSI, RTW89_ETSI, RTW89_ETSI), - COUNTRY_REGD("TK", RTW89_ACMA, RTW89_ACMA, RTW89_NA), - COUNTRY_REGD("TO", RTW89_ETSI, RTW89_ETSI, RTW89_NA), - COUNTRY_REGD("TM", RTW89_ETSI, RTW89_ETSI, RTW89_NA), - COUNTRY_REGD("TC", RTW89_ETSI, RTW89_ETSI, RTW89_NA), - COUNTRY_REGD("TV", RTW89_ETSI, RTW89_NA, RTW89_NA), - COUNTRY_REGD("UG", RTW89_ETSI, RTW89_ETSI, RTW89_NA), - COUNTRY_REGD("VI", RTW89_FCC, RTW89_FCC, RTW89_FCC), - COUNTRY_REGD("UZ", RTW89_ETSI, RTW89_ETSI, RTW89_ETSI), - COUNTRY_REGD("VU", RTW89_ETSI, RTW89_ETSI, RTW89_NA), - COUNTRY_REGD("WF", RTW89_ETSI, RTW89_ETSI, RTW89_NA), - COUNTRY_REGD("EH", RTW89_ETSI, RTW89_ETSI, RTW89_NA), - COUNTRY_REGD("ZM", RTW89_ETSI, RTW89_ETSI, RTW89_NA), - COUNTRY_REGD("CU", RTW89_ETSI, RTW89_ETSI, RTW89_NA), - COUNTRY_REGD("IR", RTW89_ETSI, RTW89_ETSI, RTW89_NA), - COUNTRY_REGD("SY", RTW89_ETSI, RTW89_NA, RTW89_NA), - COUNTRY_REGD("SD", RTW89_ETSI, RTW89_ETSI, RTW89_NA), - COUNTRY_REGD("PS", RTW89_ETSI, RTW89_ETSI, RTW89_NA), + COUNTRY_REGD("AR", RTW89_MEXICO, RTW89_MEXICO, RTW89_FCC, 0x0), + COUNTRY_REGD("BO", RTW89_FCC, RTW89_FCC, RTW89_NA, 0x0), + COUNTRY_REGD("BR", RTW89_FCC, RTW89_FCC, RTW89_FCC, 0x0), + COUNTRY_REGD("CL", RTW89_CHILE, RTW89_CHILE, RTW89_CHILE, 0x0), + COUNTRY_REGD("CO", RTW89_FCC, RTW89_FCC, RTW89_FCC, 0x0), + COUNTRY_REGD("CR", RTW89_FCC, RTW89_FCC, RTW89_FCC, 0x0), + COUNTRY_REGD("EC", RTW89_FCC, RTW89_FCC, RTW89_NA, 0x0), + COUNTRY_REGD("SV", RTW89_FCC, RTW89_FCC, RTW89_FCC, 0x0), + COUNTRY_REGD("GT", RTW89_FCC, RTW89_FCC, RTW89_FCC, 0x0), + COUNTRY_REGD("HN", RTW89_FCC, RTW89_FCC, RTW89_FCC, 0x0), + COUNTRY_REGD("MX", RTW89_MEXICO, RTW89_MEXICO, RTW89_FCC, 0x0), + COUNTRY_REGD("NI", RTW89_FCC, RTW89_FCC, RTW89_NA, 0x0), + COUNTRY_REGD("PA", RTW89_FCC, RTW89_FCC, RTW89_NA, 0x0), + COUNTRY_REGD("PY", RTW89_FCC, RTW89_FCC, RTW89_NA, 0x0), + COUNTRY_REGD("PE", RTW89_FCC, RTW89_FCC, RTW89_FCC, 0x0), + COUNTRY_REGD("US", RTW89_FCC, RTW89_FCC, RTW89_FCC, 0x1), + COUNTRY_REGD("UY", RTW89_FCC, RTW89_FCC, RTW89_NA, 0x0), + COUNTRY_REGD("VE", RTW89_FCC, RTW89_FCC, RTW89_NA, 0x0), + COUNTRY_REGD("PR", RTW89_FCC, RTW89_FCC, RTW89_NA, 0x0), + COUNTRY_REGD("DO", RTW89_FCC, RTW89_FCC, RTW89_FCC, 0x0), + COUNTRY_REGD("AT", RTW89_ETSI, RTW89_ETSI, RTW89_ETSI, 0x2), + COUNTRY_REGD("BE", RTW89_ETSI, RTW89_ETSI, RTW89_ETSI, 0x2), + COUNTRY_REGD("CY", RTW89_ETSI, RTW89_ETSI, RTW89_ETSI, 0x2), + COUNTRY_REGD("CZ", RTW89_ETSI, RTW89_ETSI, RTW89_ETSI, 0x2), + COUNTRY_REGD("DK", RTW89_ETSI, RTW89_ETSI, RTW89_ETSI, 0x2), + COUNTRY_REGD("EE", RTW89_ETSI, RTW89_ETSI, RTW89_ETSI, 0x2), + COUNTRY_REGD("FI", RTW89_ETSI, RTW89_ETSI, RTW89_ETSI, 0x2), + COUNTRY_REGD("FR", RTW89_ETSI, RTW89_ETSI, RTW89_ETSI, 0x2), + COUNTRY_REGD("DE", RTW89_ETSI, RTW89_ETSI, RTW89_ETSI, 0x2), + COUNTRY_REGD("GR", RTW89_ETSI, RTW89_ETSI, RTW89_ETSI, 0x2), + COUNTRY_REGD("HU", RTW89_ETSI, RTW89_ETSI, RTW89_ETSI, 0x2), + COUNTRY_REGD("IS", RTW89_ETSI, RTW89_ETSI, RTW89_ETSI, 0x2), + COUNTRY_REGD("IE", RTW89_ETSI, RTW89_ETSI, RTW89_ETSI, 0x2), + COUNTRY_REGD("IT", RTW89_ETSI, RTW89_ETSI, RTW89_ETSI, 0x2), + COUNTRY_REGD("LV", RTW89_ETSI, RTW89_ETSI, RTW89_ETSI, 0x2), + COUNTRY_REGD("LI", RTW89_ETSI, RTW89_ETSI, RTW89_ETSI, 0x2), + COUNTRY_REGD("LT", RTW89_ETSI, RTW89_ETSI, RTW89_ETSI, 0x2), + COUNTRY_REGD("LU", RTW89_ETSI, RTW89_ETSI, RTW89_ETSI, 0x2), + COUNTRY_REGD("MT", RTW89_ETSI, RTW89_ETSI, RTW89_ETSI, 0x2), + COUNTRY_REGD("MC", RTW89_ETSI, RTW89_ETSI, RTW89_ETSI, 0x2), + COUNTRY_REGD("NL", RTW89_ETSI, RTW89_ETSI, RTW89_ETSI, 0x2), + COUNTRY_REGD("NO", RTW89_ETSI, RTW89_ETSI, RTW89_ETSI, 0x2), + COUNTRY_REGD("PL", RTW89_ETSI, RTW89_ETSI, RTW89_ETSI, 0x2), + COUNTRY_REGD("PT", RTW89_ETSI, RTW89_ETSI, RTW89_ETSI, 0x2), + COUNTRY_REGD("SK", RTW89_ETSI, RTW89_ETSI, RTW89_ETSI, 0x2), + COUNTRY_REGD("SI", RTW89_ETSI, RTW89_ETSI, RTW89_ETSI, 0x2), + COUNTRY_REGD("ES", RTW89_ETSI, RTW89_ETSI, RTW89_ETSI, 0x2), + COUNTRY_REGD("SE", RTW89_ETSI, RTW89_ETSI, RTW89_ETSI, 0x2), + COUNTRY_REGD("CH", RTW89_ETSI, RTW89_ETSI, RTW89_ETSI, 0x2), + COUNTRY_REGD("GB", RTW89_UK, RTW89_UK, RTW89_UK, 0x0), + COUNTRY_REGD("AL", RTW89_ETSI, RTW89_ETSI, RTW89_NA, 0x0), + COUNTRY_REGD("AZ", RTW89_ETSI, RTW89_ETSI, RTW89_ETSI, 0x0), + COUNTRY_REGD("BH", RTW89_ETSI, RTW89_ETSI, RTW89_ETSI, 0x0), + COUNTRY_REGD("BA", RTW89_ETSI, RTW89_ETSI, RTW89_NA, 0x0), + COUNTRY_REGD("BG", RTW89_ETSI, RTW89_ETSI, RTW89_ETSI, 0x2), + COUNTRY_REGD("HR", RTW89_ETSI, RTW89_ETSI, RTW89_ETSI, 0x2), + COUNTRY_REGD("EG", RTW89_ETSI, RTW89_ETSI, RTW89_ETSI, 0x0), + COUNTRY_REGD("GH", RTW89_ETSI, RTW89_ETSI, RTW89_ETSI, 0x0), + COUNTRY_REGD("IQ", RTW89_ETSI, RTW89_ETSI, RTW89_NA, 0x0), + COUNTRY_REGD("IL", RTW89_ETSI, RTW89_ETSI, RTW89_ETSI, 0x0), + COUNTRY_REGD("JO", RTW89_ETSI, RTW89_ETSI, RTW89_ETSI, 0x0), + COUNTRY_REGD("KZ", RTW89_ETSI, RTW89_ETSI, RTW89_NA, 0x0), + COUNTRY_REGD("KE", RTW89_ETSI, RTW89_ETSI, RTW89_ETSI, 0x0), + COUNTRY_REGD("KW", RTW89_ETSI, RTW89_ETSI, RTW89_ETSI, 0x0), + COUNTRY_REGD("KG", RTW89_ETSI, RTW89_ETSI, RTW89_ETSI, 0x0), + COUNTRY_REGD("LB", RTW89_ETSI, RTW89_ETSI, RTW89_ETSI, 0x0), + COUNTRY_REGD("LS", RTW89_ETSI, RTW89_ETSI, RTW89_ETSI, 0x0), + COUNTRY_REGD("MK", RTW89_ETSI, RTW89_ETSI, RTW89_NA, 0x0), + COUNTRY_REGD("MA", RTW89_ETSI, RTW89_ETSI, RTW89_ETSI, 0x0), + COUNTRY_REGD("MZ", RTW89_ETSI, RTW89_ETSI, RTW89_ETSI, 0x0), + COUNTRY_REGD("NA", RTW89_ETSI, RTW89_ETSI, RTW89_NA, 0x0), + COUNTRY_REGD("NG", RTW89_ETSI, RTW89_ETSI, RTW89_ETSI, 0x0), + COUNTRY_REGD("OM", RTW89_ETSI, RTW89_ETSI, RTW89_ETSI, 0x0), + COUNTRY_REGD("QA", RTW89_QATAR, RTW89_QATAR, RTW89_QATAR, 0x0), + COUNTRY_REGD("RO", RTW89_ETSI, RTW89_ETSI, RTW89_ETSI, 0x2), + COUNTRY_REGD("RU", RTW89_ETSI, RTW89_ETSI, RTW89_NA, 0x0), + COUNTRY_REGD("SA", RTW89_ETSI, RTW89_ETSI, RTW89_ETSI, 0x0), + COUNTRY_REGD("SN", RTW89_ETSI, RTW89_ETSI, RTW89_NA, 0x0), + COUNTRY_REGD("RS", RTW89_ETSI, RTW89_ETSI, RTW89_ETSI, 0x0), + COUNTRY_REGD("ME", RTW89_ETSI, RTW89_ETSI, RTW89_NA, 0x0), + COUNTRY_REGD("ZA", RTW89_ETSI, RTW89_ETSI, RTW89_ETSI, 0x0), + COUNTRY_REGD("TR", RTW89_ETSI, RTW89_ETSI, RTW89_ETSI, 0x0), + COUNTRY_REGD("UA", RTW89_UKRAINE, RTW89_UKRAINE, RTW89_UKRAINE, 0x0), + COUNTRY_REGD("AE", RTW89_ETSI, RTW89_ETSI, RTW89_ETSI, 0x0), + COUNTRY_REGD("YE", RTW89_ETSI, RTW89_ETSI, RTW89_NA, 0x0), + COUNTRY_REGD("ZW", RTW89_ETSI, RTW89_ETSI, RTW89_ETSI, 0x0), + COUNTRY_REGD("BD", RTW89_ETSI, RTW89_ETSI, RTW89_NA, 0x0), + COUNTRY_REGD("KH", RTW89_ETSI, RTW89_ETSI, RTW89_NA, 0x0), + COUNTRY_REGD("CN", RTW89_CN, RTW89_CN, RTW89_CN, 0x0), + COUNTRY_REGD("HK", RTW89_ETSI, RTW89_ETSI, RTW89_ETSI, 0x0), + COUNTRY_REGD("IN", RTW89_ETSI, RTW89_ETSI, RTW89_NA, 0x0), + COUNTRY_REGD("ID", RTW89_ETSI, RTW89_ETSI, RTW89_NA, 0x0), + COUNTRY_REGD("KR", RTW89_KCC, RTW89_KCC, RTW89_KCC, 0x1), + COUNTRY_REGD("MY", RTW89_ETSI, RTW89_ETSI, RTW89_ETSI, 0x0), + COUNTRY_REGD("PK", RTW89_ETSI, RTW89_ETSI, RTW89_ETSI, 0x0), + COUNTRY_REGD("PH", RTW89_ETSI, RTW89_ETSI, RTW89_ETSI, 0x0), + COUNTRY_REGD("SG", RTW89_ETSI, RTW89_ETSI, RTW89_ETSI, 0x0), + COUNTRY_REGD("LK", RTW89_ETSI, RTW89_ETSI, RTW89_NA, 0x0), + COUNTRY_REGD("TW", RTW89_FCC, RTW89_FCC, RTW89_ETSI, 0x0), + COUNTRY_REGD("TH", RTW89_THAILAND, RTW89_THAILAND, RTW89_THAILAND, 0x0), + COUNTRY_REGD("VN", RTW89_ETSI, RTW89_ETSI, RTW89_NA, 0x0), + COUNTRY_REGD("AU", RTW89_ACMA, RTW89_ACMA, RTW89_ACMA, 0x0), + COUNTRY_REGD("NZ", RTW89_ACMA, RTW89_ACMA, RTW89_ACMA, 0x0), + COUNTRY_REGD("PG", RTW89_ETSI, RTW89_ETSI, RTW89_ETSI, 0x0), + COUNTRY_REGD("CA", RTW89_IC, RTW89_IC, RTW89_IC, 0x1), + COUNTRY_REGD("JP", RTW89_MKK, RTW89_MKK, RTW89_MKK, 0x0), + COUNTRY_REGD("JM", RTW89_FCC, RTW89_FCC, RTW89_FCC, 0x0), + COUNTRY_REGD("AN", RTW89_FCC, RTW89_FCC, RTW89_FCC, 0x0), + COUNTRY_REGD("TT", RTW89_FCC, RTW89_FCC, RTW89_NA, 0x0), + COUNTRY_REGD("TN", RTW89_ETSI, RTW89_ETSI, RTW89_NA, 0x0), + COUNTRY_REGD("AF", RTW89_ETSI, RTW89_ETSI, RTW89_NA, 0x0), + COUNTRY_REGD("DZ", RTW89_ETSI, RTW89_ETSI, RTW89_ETSI, 0x0), + COUNTRY_REGD("AS", RTW89_FCC, RTW89_FCC, RTW89_NA, 0x0), + COUNTRY_REGD("AD", RTW89_ETSI, RTW89_ETSI, RTW89_NA, 0x0), + COUNTRY_REGD("AO", RTW89_ETSI, RTW89_ETSI, RTW89_NA, 0x0), + COUNTRY_REGD("AI", RTW89_ETSI, RTW89_ETSI, RTW89_ETSI, 0x0), + COUNTRY_REGD("AQ", RTW89_ETSI, RTW89_ETSI, RTW89_NA, 0x0), + COUNTRY_REGD("AG", RTW89_FCC, RTW89_FCC, RTW89_FCC, 0x0), + COUNTRY_REGD("AM", RTW89_ETSI, RTW89_ETSI, RTW89_ETSI, 0x0), + COUNTRY_REGD("AW", RTW89_FCC, RTW89_FCC, RTW89_FCC, 0x0), + COUNTRY_REGD("BS", RTW89_FCC, RTW89_FCC, RTW89_FCC, 0x0), + COUNTRY_REGD("BB", RTW89_FCC, RTW89_FCC, RTW89_FCC, 0x0), + COUNTRY_REGD("BY", RTW89_ETSI, RTW89_ETSI, RTW89_NA, 0x0), + COUNTRY_REGD("BZ", RTW89_FCC, RTW89_FCC, RTW89_NA, 0x0), + COUNTRY_REGD("BJ", RTW89_ETSI, RTW89_ETSI, RTW89_NA, 0x0), + COUNTRY_REGD("BM", RTW89_FCC, RTW89_FCC, RTW89_FCC, 0x0), + COUNTRY_REGD("BT", RTW89_ETSI, RTW89_ETSI, RTW89_NA, 0x0), + COUNTRY_REGD("BW", RTW89_ETSI, RTW89_ETSI, RTW89_ETSI, 0x0), + COUNTRY_REGD("BV", RTW89_ETSI, RTW89_ETSI, RTW89_NA, 0x0), + COUNTRY_REGD("IO", RTW89_ETSI, RTW89_ETSI, RTW89_NA, 0x0), + COUNTRY_REGD("VG", RTW89_FCC, RTW89_FCC, RTW89_FCC, 0x0), + COUNTRY_REGD("BN", RTW89_ETSI, RTW89_ETSI, RTW89_NA, 0x0), + COUNTRY_REGD("BF", RTW89_ETSI, RTW89_ETSI, RTW89_ETSI, 0x0), + COUNTRY_REGD("MM", RTW89_ETSI, RTW89_ETSI, RTW89_NA, 0x0), + COUNTRY_REGD("BI", RTW89_ETSI, RTW89_ETSI, RTW89_ETSI, 0x0), + COUNTRY_REGD("CM", RTW89_ETSI, RTW89_ETSI, RTW89_NA, 0x0), + COUNTRY_REGD("CV", RTW89_ETSI, RTW89_ETSI, RTW89_NA, 0x0), + COUNTRY_REGD("KY", RTW89_FCC, RTW89_FCC, RTW89_FCC, 0x0), + COUNTRY_REGD("CF", RTW89_ETSI, RTW89_ETSI, RTW89_NA, 0x0), + COUNTRY_REGD("TD", RTW89_ETSI, RTW89_ETSI, RTW89_ETSI, 0x0), + COUNTRY_REGD("CX", RTW89_ACMA, RTW89_ACMA, RTW89_NA, 0x0), + COUNTRY_REGD("CC", RTW89_ACMA, RTW89_ACMA, RTW89_NA, 0x0), + COUNTRY_REGD("KM", RTW89_ETSI, RTW89_ETSI, RTW89_NA, 0x0), + COUNTRY_REGD("CG", RTW89_ETSI, RTW89_ETSI, RTW89_ETSI, 0x0), + COUNTRY_REGD("CD", RTW89_ETSI, RTW89_ETSI, RTW89_ETSI, 0x0), + COUNTRY_REGD("CK", RTW89_ETSI, RTW89_ETSI, RTW89_NA, 0x0), + COUNTRY_REGD("CI", RTW89_ETSI, RTW89_ETSI, RTW89_NA, 0x0), + COUNTRY_REGD("DJ", RTW89_ETSI, RTW89_ETSI, RTW89_ETSI, 0x0), + COUNTRY_REGD("DM", RTW89_FCC, RTW89_FCC, RTW89_NA, 0x0), + COUNTRY_REGD("GQ", RTW89_ETSI, RTW89_ETSI, RTW89_ETSI, 0x0), + COUNTRY_REGD("ER", RTW89_ETSI, RTW89_ETSI, RTW89_NA, 0x0), + COUNTRY_REGD("ET", RTW89_ETSI, RTW89_ETSI, RTW89_NA, 0x0), + COUNTRY_REGD("FK", RTW89_ETSI, RTW89_ETSI, RTW89_NA, 0x0), + COUNTRY_REGD("FO", RTW89_ETSI, RTW89_ETSI, RTW89_NA, 0x0), + COUNTRY_REGD("FJ", RTW89_FCC, RTW89_FCC, RTW89_NA, 0x0), + COUNTRY_REGD("GF", RTW89_ETSI, RTW89_ETSI, RTW89_NA, 0x0), + COUNTRY_REGD("PF", RTW89_ETSI, RTW89_ETSI, RTW89_NA, 0x0), + COUNTRY_REGD("TF", RTW89_ETSI, RTW89_ETSI, RTW89_NA, 0x0), + COUNTRY_REGD("GA", RTW89_ETSI, RTW89_ETSI, RTW89_NA, 0x0), + COUNTRY_REGD("GM", RTW89_ETSI, RTW89_ETSI, RTW89_ETSI, 0x0), + COUNTRY_REGD("GE", RTW89_ETSI, RTW89_ETSI, RTW89_ETSI, 0x0), + COUNTRY_REGD("GI", RTW89_ETSI, RTW89_ETSI, RTW89_ETSI, 0x0), + COUNTRY_REGD("GL", RTW89_ETSI, RTW89_ETSI, RTW89_NA, 0x0), + COUNTRY_REGD("GD", RTW89_FCC, RTW89_FCC, RTW89_FCC, 0x0), + COUNTRY_REGD("GP", RTW89_ETSI, RTW89_ETSI, RTW89_NA, 0x0), + COUNTRY_REGD("GU", RTW89_FCC, RTW89_FCC, RTW89_FCC, 0x0), + COUNTRY_REGD("GG", RTW89_ETSI, RTW89_ETSI, RTW89_NA, 0x0), + COUNTRY_REGD("GN", RTW89_ETSI, RTW89_ETSI, RTW89_ETSI, 0x0), + COUNTRY_REGD("GW", RTW89_ETSI, RTW89_ETSI, RTW89_NA, 0x0), + COUNTRY_REGD("GY", RTW89_FCC, RTW89_FCC, RTW89_NA, 0x0), + COUNTRY_REGD("HT", RTW89_FCC, RTW89_FCC, RTW89_FCC, 0x0), + COUNTRY_REGD("HM", RTW89_ACMA, RTW89_ACMA, RTW89_NA, 0x0), + COUNTRY_REGD("VA", RTW89_ETSI, RTW89_ETSI, RTW89_NA, 0x0), + COUNTRY_REGD("IM", RTW89_ETSI, RTW89_ETSI, RTW89_NA, 0x0), + COUNTRY_REGD("JE", RTW89_ETSI, RTW89_ETSI, RTW89_NA, 0x0), + COUNTRY_REGD("KI", RTW89_ETSI, RTW89_ETSI, RTW89_NA, 0x0), + COUNTRY_REGD("XK", RTW89_ETSI, RTW89_ETSI, RTW89_ETSI, 0x0), + COUNTRY_REGD("LA", RTW89_ETSI, RTW89_ETSI, RTW89_ETSI, 0x0), + COUNTRY_REGD("LR", RTW89_ETSI, RTW89_ETSI, RTW89_ETSI, 0x0), + COUNTRY_REGD("LY", RTW89_ETSI, RTW89_ETSI, RTW89_NA, 0x0), + COUNTRY_REGD("MO", RTW89_ETSI, RTW89_ETSI, RTW89_NA, 0x0), + COUNTRY_REGD("MG", RTW89_ETSI, RTW89_ETSI, RTW89_ETSI, 0x0), + COUNTRY_REGD("MW", RTW89_ETSI, RTW89_ETSI, RTW89_NA, 0x0), + COUNTRY_REGD("MV", RTW89_ETSI, RTW89_ETSI, RTW89_NA, 0x0), + COUNTRY_REGD("ML", RTW89_ETSI, RTW89_ETSI, RTW89_NA, 0x0), + COUNTRY_REGD("MH", RTW89_FCC, RTW89_FCC, RTW89_FCC, 0x0), + COUNTRY_REGD("MQ", RTW89_ETSI, RTW89_ETSI, RTW89_NA, 0x0), + COUNTRY_REGD("MR", RTW89_ETSI, RTW89_ETSI, RTW89_NA, 0x0), + COUNTRY_REGD("MU", RTW89_ETSI, RTW89_ETSI, RTW89_ETSI, 0x0), + COUNTRY_REGD("YT", RTW89_ETSI, RTW89_ETSI, RTW89_NA, 0x0), + COUNTRY_REGD("FM", RTW89_FCC, RTW89_FCC, RTW89_FCC, 0x0), + COUNTRY_REGD("MD", RTW89_ETSI, RTW89_ETSI, RTW89_ETSI, 0x0), + COUNTRY_REGD("MN", RTW89_ETSI, RTW89_ETSI, RTW89_ETSI, 0x0), + COUNTRY_REGD("MS", RTW89_ETSI, RTW89_ETSI, RTW89_NA, 0x0), + COUNTRY_REGD("NR", RTW89_ETSI, RTW89_ETSI, RTW89_NA, 0x0), + COUNTRY_REGD("NP", RTW89_ETSI, RTW89_ETSI, RTW89_NA, 0x0), + COUNTRY_REGD("NC", RTW89_ETSI, RTW89_ETSI, RTW89_NA, 0x0), + COUNTRY_REGD("NE", RTW89_ETSI, RTW89_ETSI, RTW89_NA, 0x0), + COUNTRY_REGD("NU", RTW89_ACMA, RTW89_ACMA, RTW89_NA, 0x0), + COUNTRY_REGD("NF", RTW89_ACMA, RTW89_ACMA, RTW89_NA, 0x0), + COUNTRY_REGD("MP", RTW89_FCC, RTW89_FCC, RTW89_FCC, 0x0), + COUNTRY_REGD("PW", RTW89_FCC, RTW89_FCC, RTW89_FCC, 0x0), + COUNTRY_REGD("RE", RTW89_ETSI, RTW89_ETSI, RTW89_NA, 0x0), + COUNTRY_REGD("RW", RTW89_ETSI, RTW89_ETSI, RTW89_NA, 0x0), + COUNTRY_REGD("SH", RTW89_ETSI, RTW89_ETSI, RTW89_NA, 0x0), + COUNTRY_REGD("KN", RTW89_FCC, RTW89_FCC, RTW89_FCC, 0x0), + COUNTRY_REGD("LC", RTW89_FCC, RTW89_FCC, RTW89_FCC, 0x0), + COUNTRY_REGD("MF", RTW89_FCC, RTW89_FCC, RTW89_FCC, 0x0), + COUNTRY_REGD("SX", RTW89_FCC, RTW89_FCC, RTW89_FCC, 0x0), + COUNTRY_REGD("PM", RTW89_ETSI, RTW89_ETSI, RTW89_NA, 0x0), + COUNTRY_REGD("VC", RTW89_FCC, RTW89_FCC, RTW89_NA, 0x0), + COUNTRY_REGD("WS", RTW89_FCC, RTW89_FCC, RTW89_NA, 0x0), + COUNTRY_REGD("SM", RTW89_ETSI, RTW89_ETSI, RTW89_NA, 0x0), + COUNTRY_REGD("ST", RTW89_ETSI, RTW89_ETSI, RTW89_NA, 0x0), + COUNTRY_REGD("SC", RTW89_FCC, RTW89_FCC, RTW89_NA, 0x0), + COUNTRY_REGD("SL", RTW89_ETSI, RTW89_ETSI, RTW89_ETSI, 0x0), + COUNTRY_REGD("SB", RTW89_ETSI, RTW89_ETSI, RTW89_NA, 0x0), + COUNTRY_REGD("SO", RTW89_ETSI, RTW89_ETSI, RTW89_NA, 0x0), + COUNTRY_REGD("GS", RTW89_ETSI, RTW89_ETSI, RTW89_NA, 0x0), + COUNTRY_REGD("SR", RTW89_FCC, RTW89_FCC, RTW89_FCC, 0x0), + COUNTRY_REGD("SJ", RTW89_ETSI, RTW89_ETSI, RTW89_NA, 0x0), + COUNTRY_REGD("SZ", RTW89_ETSI, RTW89_ETSI, RTW89_ETSI, 0x0), + COUNTRY_REGD("TJ", RTW89_ETSI, RTW89_ETSI, RTW89_ETSI, 0x0), + COUNTRY_REGD("TZ", RTW89_ETSI, RTW89_ETSI, RTW89_ETSI, 0x0), + COUNTRY_REGD("TG", RTW89_ETSI, RTW89_ETSI, RTW89_ETSI, 0x0), + COUNTRY_REGD("TK", RTW89_ACMA, RTW89_ACMA, RTW89_NA, 0x0), + COUNTRY_REGD("TO", RTW89_ETSI, RTW89_ETSI, RTW89_NA, 0x0), + COUNTRY_REGD("TM", RTW89_ETSI, RTW89_ETSI, RTW89_NA, 0x0), + COUNTRY_REGD("TC", RTW89_ETSI, RTW89_ETSI, RTW89_NA, 0x0), + COUNTRY_REGD("TV", RTW89_ETSI, RTW89_NA, RTW89_NA, 0x0), + COUNTRY_REGD("UG", RTW89_ETSI, RTW89_ETSI, RTW89_NA, 0x0), + COUNTRY_REGD("VI", RTW89_FCC, RTW89_FCC, RTW89_FCC, 0x0), + COUNTRY_REGD("UZ", RTW89_ETSI, RTW89_ETSI, RTW89_ETSI, 0x0), + COUNTRY_REGD("VU", RTW89_ETSI, RTW89_ETSI, RTW89_NA, 0x0), + COUNTRY_REGD("WF", RTW89_ETSI, RTW89_ETSI, RTW89_NA, 0x0), + COUNTRY_REGD("EH", RTW89_ETSI, RTW89_ETSI, RTW89_NA, 0x0), + COUNTRY_REGD("ZM", RTW89_ETSI, RTW89_ETSI, RTW89_NA, 0x0), + COUNTRY_REGD("CU", RTW89_ETSI, RTW89_ETSI, RTW89_NA, 0x0), + COUNTRY_REGD("IR", RTW89_ETSI, RTW89_ETSI, RTW89_NA, 0x0), + COUNTRY_REGD("SY", RTW89_ETSI, RTW89_NA, RTW89_NA, 0x0), + COUNTRY_REGD("SD", RTW89_ETSI, RTW89_ETSI, RTW89_NA, 0x0), + COUNTRY_REGD("PS", RTW89_ETSI, RTW89_ETSI, RTW89_NA, 0x0), }; static const char rtw89_alpha2_list_eu[][3] = { @@ -295,13 +304,16 @@ static const char rtw89_alpha2_list_eu[][3] = { "RO", }; -static const struct rtw89_regd *rtw89_regd_find_reg_by_name(const char *alpha2) +static const struct rtw89_regd *rtw89_regd_find_reg_by_name(struct rtw89_dev *rtwdev, + const char *alpha2) { + struct rtw89_regulatory_info *regulatory = &rtwdev->regulatory; + const struct rtw89_regd_ctrl *regd_ctrl = ®ulatory->ctrl; u32 i; - for (i = 0; i < ARRAY_SIZE(rtw89_regd_map); i++) { - if (!memcmp(rtw89_regd_map[i].alpha2, alpha2, 2)) - return &rtw89_regd_map[i]; + for (i = 0; i < regd_ctrl->nr; i++) { + if (!memcmp(regd_ctrl->map[i].alpha2, alpha2, 2)) + return ®d_ctrl->map[i]; } return &rtw89_ww_regd; @@ -312,22 +324,25 @@ static bool rtw89_regd_is_ww(const struct rtw89_regd *regd) return regd == &rtw89_ww_regd; } -static u8 rtw89_regd_get_index(const struct rtw89_regd *regd) +static u8 rtw89_regd_get_index(struct rtw89_dev *rtwdev, const struct rtw89_regd *regd) { + struct rtw89_regulatory_info *regulatory = &rtwdev->regulatory; + const struct rtw89_regd_ctrl *regd_ctrl = ®ulatory->ctrl; + BUILD_BUG_ON(ARRAY_SIZE(rtw89_regd_map) > RTW89_REGD_MAX_COUNTRY_NUM); if (rtw89_regd_is_ww(regd)) return RTW89_REGD_MAX_COUNTRY_NUM; - return regd - rtw89_regd_map; + return regd - regd_ctrl->map; } -static u8 rtw89_regd_get_index_by_name(const char *alpha2) +static u8 rtw89_regd_get_index_by_name(struct rtw89_dev *rtwdev, const char *alpha2) { const struct rtw89_regd *regd; - regd = rtw89_regd_find_reg_by_name(alpha2); - return rtw89_regd_get_index(regd); + regd = rtw89_regd_find_reg_by_name(rtwdev, alpha2); + return rtw89_regd_get_index(rtwdev, regd); } #define rtw89_debug_regd(_dev, _regd, _desc, _argv...) \ @@ -345,6 +360,7 @@ static void rtw89_regd_setup_unii4(struct rtw89_dev *rtwdev, struct wiphy *wiphy) { struct rtw89_regulatory_info *regulatory = &rtwdev->regulatory; + const struct rtw89_regd_ctrl *regd_ctrl = ®ulatory->ctrl; const struct rtw89_chip_info *chip = rtwdev->chip; struct ieee80211_supported_band *sband; struct rtw89_acpi_dsm_result res = {}; @@ -382,8 +398,8 @@ static void rtw89_regd_setup_unii4(struct rtw89_dev *rtwdev, "acpi: eval if allow unii-4: 0x%x\n", val); bottom: - for (i = 0; i < ARRAY_SIZE(rtw89_regd_map); i++) { - const struct rtw89_regd *regd = &rtw89_regd_map[i]; + for (i = 0; i < regd_ctrl->nr; i++) { + const struct rtw89_regd *regd = ®d_ctrl->map[i]; switch (regd->txpwr_regd[RTW89_BAND_5G]) { case RTW89_FCC: @@ -406,7 +422,7 @@ static void __rtw89_regd_setup_policy_6ghz(struct rtw89_dev *rtwdev, bool block, struct rtw89_regulatory_info *regulatory = &rtwdev->regulatory; u8 index; - index = rtw89_regd_get_index_by_name(alpha2); + index = rtw89_regd_get_index_by_name(rtwdev, alpha2); if (index == RTW89_REGD_MAX_COUNTRY_NUM) { rtw89_debug(rtwdev, RTW89_DBG_REGD, "%s: unknown alpha2 %c%c\n", __func__, alpha2[0], alpha2[1]); @@ -474,6 +490,7 @@ out: static void rtw89_regd_setup_policy_6ghz_sp(struct rtw89_dev *rtwdev) { struct rtw89_regulatory_info *regulatory = &rtwdev->regulatory; + const struct rtw89_regd_ctrl *regd_ctrl = ®ulatory->ctrl; const struct rtw89_acpi_policy_6ghz_sp *ptr; struct rtw89_acpi_dsm_result res = {}; bool enable_by_us; @@ -505,8 +522,8 @@ static void rtw89_regd_setup_policy_6ghz_sp(struct rtw89_dev *rtwdev) enable_by_us = u8_get_bits(ptr->conf, RTW89_ACPI_CONF_6GHZ_SP_US); - for (i = 0; i < ARRAY_SIZE(rtw89_regd_map); i++) { - const struct rtw89_regd *tmp = &rtw89_regd_map[i]; + for (i = 0; i < regd_ctrl->nr; i++) { + const struct rtw89_regd *tmp = ®d_ctrl->map[i]; if (enable_by_us && memcmp(tmp->alpha2, "US", 2) == 0) clear_bit(i, regulatory->block_6ghz_sp); @@ -573,8 +590,21 @@ bottom: int rtw89_regd_setup(struct rtw89_dev *rtwdev) { + struct rtw89_regulatory_info *regulatory = &rtwdev->regulatory; + struct rtw89_fw_elm_info *elm_info = &rtwdev->fw.elm_info; + const struct rtw89_regd_data *regd_data = elm_info->regd; struct wiphy *wiphy = rtwdev->hw->wiphy; + if (regd_data) { + regulatory->ctrl.nr = regd_data->nr; + regulatory->ctrl.map = regd_data->map; + } else { + regulatory->ctrl.nr = ARRAY_SIZE(rtw89_regd_map); + regulatory->ctrl.map = rtw89_regd_map; + } + + regulatory->reg_6ghz_power = RTW89_REG_6GHZ_POWER_DFLT; + if (!wiphy) return -EINVAL; @@ -585,21 +615,16 @@ int rtw89_regd_setup(struct rtw89_dev *rtwdev) return 0; } -int rtw89_regd_init(struct rtw89_dev *rtwdev, - void (*reg_notifier)(struct wiphy *wiphy, - struct regulatory_request *request)) +int rtw89_regd_init_hint(struct rtw89_dev *rtwdev) { - struct rtw89_regulatory_info *regulatory = &rtwdev->regulatory; const struct rtw89_regd *chip_regd; struct wiphy *wiphy = rtwdev->hw->wiphy; int ret; - regulatory->reg_6ghz_power = RTW89_REG_6GHZ_POWER_DFLT; - if (!wiphy) return -EINVAL; - chip_regd = rtw89_regd_find_reg_by_name(rtwdev->efuse.country_code); + chip_regd = rtw89_regd_find_reg_by_name(rtwdev, rtwdev->efuse.country_code); if (!rtw89_regd_is_ww(chip_regd)) { rtwdev->regulatory.regd = chip_regd; /* Ignore country ie if there is a country domain programmed in chip */ @@ -637,7 +662,7 @@ static void rtw89_regd_apply_policy_unii4(struct rtw89_dev *rtwdev, if (!chip->support_unii4) return; - index = rtw89_regd_get_index(regd); + index = rtw89_regd_get_index(rtwdev, regd); if (index != RTW89_REGD_MAX_COUNTRY_NUM && !test_bit(index, regulatory->block_unii4)) return; @@ -655,7 +680,7 @@ static bool regd_is_6ghz_blocked(struct rtw89_dev *rtwdev) const struct rtw89_regd *regd = regulatory->regd; u8 index; - index = rtw89_regd_get_index(regd); + index = rtw89_regd_get_index(rtwdev, regd); if (index != RTW89_REGD_MAX_COUNTRY_NUM && !test_bit(index, regulatory->block_6ghz)) return false; @@ -700,7 +725,7 @@ static void rtw89_regd_notifier_apply(struct rtw89_dev *rtwdev, struct wiphy *wiphy, struct regulatory_request *request) { - rtwdev->regulatory.regd = rtw89_regd_find_reg_by_name(request->alpha2); + rtwdev->regulatory.regd = rtw89_regd_find_reg_by_name(rtwdev, request->alpha2); /* This notification might be set from the system of distros, * and it does not expect the regulatory will be modified by * connecting to an AP (i.e. country ie). @@ -715,12 +740,13 @@ static void rtw89_regd_notifier_apply(struct rtw89_dev *rtwdev, rtw89_regd_apply_policy_6ghz(rtwdev, wiphy); } +static void rtw89_regd_notifier(struct wiphy *wiphy, struct regulatory_request *request) { struct ieee80211_hw *hw = wiphy_to_ieee80211_hw(wiphy); struct rtw89_dev *rtwdev = hw->priv; - mutex_lock(&rtwdev->mutex); + wiphy_lock(wiphy); rtw89_leave_ps_mode(rtwdev); if (wiphy->regd) { @@ -736,7 +762,7 @@ void rtw89_regd_notifier(struct wiphy *wiphy, struct regulatory_request *request rtw89_core_set_chip_txpwr(rtwdev); exit: - mutex_unlock(&rtwdev->mutex); + wiphy_unlock(wiphy); } /* Maximum Transmit Power field (@raw) can be EIRP or PSD. @@ -925,7 +951,7 @@ static bool __rtw89_reg_6ghz_power_recalc(struct rtw89_dev *rtwdev) sel = RTW89_REG_6GHZ_POWER_DFLT; if (sel == RTW89_REG_6GHZ_POWER_STD) { - index = rtw89_regd_get_index(regd); + index = rtw89_regd_get_index(rtwdev, regd); if (index == RTW89_REGD_MAX_COUNTRY_NUM || test_bit(index, regulatory->block_6ghz_sp)) { rtw89_debug(rtwdev, RTW89_DBG_REGD, @@ -986,7 +1012,7 @@ int rtw89_reg_6ghz_recalc(struct rtw89_dev *rtwdev, struct rtw89_vif_link *rtwvi unsigned int changed = 0; int ret; - lockdep_assert_held(&rtwdev->mutex); + lockdep_assert_wiphy(rtwdev->hw->wiphy); /* The result of reg_6ghz_tpe may depend on reg_6ghz_power type, * so must do reg_6ghz_tpe_recalc() after reg_6ghz_power_recalc(). diff --git a/drivers/net/wireless/realtek/rtw89/rtw8851b.c b/drivers/net/wireless/realtek/rtw89/rtw8851b.c index c56f70267882..82289dbad1f4 100644 --- a/drivers/net/wireless/realtek/rtw89/rtw8851b.c +++ b/drivers/net/wireless/realtek/rtw89/rtw8851b.c @@ -224,10 +224,17 @@ static const struct rtw89_edcca_regs rtw8851b_edcca_regs = { .edcca_p_mask = B_EDCCA_LVL_MSK1, .ppdu_level = R_SEG0R_EDCCA_LVL_V1, .ppdu_mask = B_EDCCA_LVL_MSK3, - .rpt_a = R_EDCCA_RPT_A, - .rpt_b = R_EDCCA_RPT_B, - .rpt_sel = R_EDCCA_RPT_SEL, - .rpt_sel_mask = B_EDCCA_RPT_SEL_MSK, + .p = {{ + .rpt_a = R_EDCCA_RPT_A, + .rpt_b = R_EDCCA_RPT_B, + .rpt_sel = R_EDCCA_RPT_SEL, + .rpt_sel_mask = B_EDCCA_RPT_SEL_MSK, + }, { + .rpt_a = R_EDCCA_RPT_P1_A, + .rpt_b = R_EDCCA_RPT_P1_B, + .rpt_sel = R_EDCCA_RPT_SEL, + .rpt_sel_mask = B_EDCCA_RPT_SEL_P1_MSK, + }}, .tx_collision_t2r_st = R_TX_COLLISION_T2R_ST, .tx_collision_t2r_st_mask = B_TX_COLLISION_T2R_ST_M, }; @@ -1596,10 +1603,16 @@ static void rtw8851b_rfk_channel(struct rtw89_dev *rtwdev, enum rtw89_chanctx_idx chanctx_idx = rtwvif_link->chanctx_idx; enum rtw89_phy_idx phy_idx = rtwvif_link->phy_idx; + rtw89_btc_ntfy_conn_rfk(rtwdev, true); + rtw8851b_rx_dck(rtwdev, phy_idx, chanctx_idx); rtw8851b_iqk(rtwdev, phy_idx, chanctx_idx); + rtw89_btc_ntfy_preserve_bt_time(rtwdev, 30); rtw8851b_tssi(rtwdev, phy_idx, true, chanctx_idx); + rtw89_btc_ntfy_preserve_bt_time(rtwdev, 30); rtw8851b_dpk(rtwdev, phy_idx, chanctx_idx); + + rtw89_btc_ntfy_conn_rfk(rtwdev, false); } static void rtw8851b_rfk_band_changed(struct rtw89_dev *rtwdev, diff --git a/drivers/net/wireless/realtek/rtw89/rtw8852a.c b/drivers/net/wireless/realtek/rtw89/rtw8852a.c index 9bd2842c27d5..2046832d021f 100644 --- a/drivers/net/wireless/realtek/rtw89/rtw8852a.c +++ b/drivers/net/wireless/realtek/rtw89/rtw8852a.c @@ -522,10 +522,17 @@ static const struct rtw89_edcca_regs rtw8852a_edcca_regs = { .edcca_p_mask = B_EDCCA_LVL_MSK1, .ppdu_level = R_SEG0R_EDCCA_LVL, .ppdu_mask = B_EDCCA_LVL_MSK3, - .rpt_a = R_EDCCA_RPT_A, - .rpt_b = R_EDCCA_RPT_B, - .rpt_sel = R_EDCCA_RPT_SEL, - .rpt_sel_mask = B_EDCCA_RPT_SEL_MSK, + .p = {{ + .rpt_a = R_EDCCA_RPT_A, + .rpt_b = R_EDCCA_RPT_B, + .rpt_sel = R_EDCCA_RPT_SEL, + .rpt_sel_mask = B_EDCCA_RPT_SEL_MSK, + }, { + .rpt_a = R_EDCCA_RPT_P1_A, + .rpt_b = R_EDCCA_RPT_P1_B, + .rpt_sel = R_EDCCA_RPT_SEL, + .rpt_sel_mask = B_EDCCA_RPT_SEL_P1_MSK, + }}, .tx_collision_t2r_st = R_TX_COLLISION_T2R_ST, .tx_collision_t2r_st_mask = B_TX_COLLISION_T2R_ST_M, }; @@ -1356,10 +1363,16 @@ static void rtw8852a_rfk_channel(struct rtw89_dev *rtwdev, enum rtw89_chanctx_idx chanctx_idx = rtwvif_link->chanctx_idx; enum rtw89_phy_idx phy_idx = rtwvif_link->phy_idx; + rtw89_btc_ntfy_conn_rfk(rtwdev, true); + rtw8852a_rx_dck(rtwdev, phy_idx, true, chanctx_idx); rtw8852a_iqk(rtwdev, phy_idx, chanctx_idx); + rtw89_btc_ntfy_preserve_bt_time(rtwdev, 30); rtw8852a_tssi(rtwdev, phy_idx, chanctx_idx); + rtw89_btc_ntfy_preserve_bt_time(rtwdev, 30); rtw8852a_dpk(rtwdev, phy_idx, chanctx_idx); + + rtw89_btc_ntfy_conn_rfk(rtwdev, false); } static void rtw8852a_rfk_band_changed(struct rtw89_dev *rtwdev, diff --git a/drivers/net/wireless/realtek/rtw89/rtw8852b.c b/drivers/net/wireless/realtek/rtw89/rtw8852b.c index dfb2bf61b0b8..652914a36245 100644 --- a/drivers/net/wireless/realtek/rtw89/rtw8852b.c +++ b/drivers/net/wireless/realtek/rtw89/rtw8852b.c @@ -189,10 +189,17 @@ static const struct rtw89_edcca_regs rtw8852b_edcca_regs = { .edcca_p_mask = B_EDCCA_LVL_MSK1, .ppdu_level = R_SEG0R_EDCCA_LVL_V1, .ppdu_mask = B_EDCCA_LVL_MSK3, - .rpt_a = R_EDCCA_RPT_A, - .rpt_b = R_EDCCA_RPT_B, - .rpt_sel = R_EDCCA_RPT_SEL, - .rpt_sel_mask = B_EDCCA_RPT_SEL_MSK, + .p = {{ + .rpt_a = R_EDCCA_RPT_A, + .rpt_b = R_EDCCA_RPT_B, + .rpt_sel = R_EDCCA_RPT_SEL, + .rpt_sel_mask = B_EDCCA_RPT_SEL_MSK, + }, { + .rpt_a = R_EDCCA_RPT_P1_A, + .rpt_b = R_EDCCA_RPT_P1_B, + .rpt_sel = R_EDCCA_RPT_SEL, + .rpt_sel_mask = B_EDCCA_RPT_SEL_P1_MSK, + }}, .tx_collision_t2r_st = R_TX_COLLISION_T2R_ST, .tx_collision_t2r_st_mask = B_TX_COLLISION_T2R_ST_M, }; @@ -568,10 +575,16 @@ static void rtw8852b_rfk_channel(struct rtw89_dev *rtwdev, enum rtw89_chanctx_idx chanctx_idx = rtwvif_link->chanctx_idx; enum rtw89_phy_idx phy_idx = rtwvif_link->phy_idx; + rtw89_btc_ntfy_conn_rfk(rtwdev, true); + rtw8852b_rx_dck(rtwdev, phy_idx, chanctx_idx); rtw8852b_iqk(rtwdev, phy_idx, chanctx_idx); + rtw89_btc_ntfy_preserve_bt_time(rtwdev, 30); rtw8852b_tssi(rtwdev, phy_idx, true, chanctx_idx); + rtw89_btc_ntfy_preserve_bt_time(rtwdev, 30); rtw8852b_dpk(rtwdev, phy_idx, chanctx_idx); + + rtw89_btc_ntfy_conn_rfk(rtwdev, false); } static void rtw8852b_rfk_band_changed(struct rtw89_dev *rtwdev, diff --git a/drivers/net/wireless/realtek/rtw89/rtw8852bt.c b/drivers/net/wireless/realtek/rtw89/rtw8852bt.c index bde3e1fb7ca6..6f15245b2f74 100644 --- a/drivers/net/wireless/realtek/rtw89/rtw8852bt.c +++ b/drivers/net/wireless/realtek/rtw89/rtw8852bt.c @@ -187,10 +187,17 @@ static const struct rtw89_edcca_regs rtw8852bt_edcca_regs = { .edcca_p_mask = B_EDCCA_LVL_MSK1, .ppdu_level = R_SEG0R_EDCCA_LVL_V1, .ppdu_mask = B_EDCCA_LVL_MSK3, - .rpt_a = R_EDCCA_RPT_A, - .rpt_b = R_EDCCA_RPT_B, - .rpt_sel = R_EDCCA_RPT_SEL, - .rpt_sel_mask = B_EDCCA_RPT_SEL_MSK, + .p = {{ + .rpt_a = R_EDCCA_RPT_A, + .rpt_b = R_EDCCA_RPT_B, + .rpt_sel = R_EDCCA_RPT_SEL, + .rpt_sel_mask = B_EDCCA_RPT_SEL_MSK, + }, { + .rpt_a = R_EDCCA_RPT_P1_A, + .rpt_b = R_EDCCA_RPT_P1_B, + .rpt_sel = R_EDCCA_RPT_SEL, + .rpt_sel_mask = B_EDCCA_RPT_SEL_P1_MSK, + }}, .tx_collision_t2r_st = R_TX_COLLISION_T2R_ST, .tx_collision_t2r_st_mask = B_TX_COLLISION_T2R_ST_M, }; @@ -541,10 +548,16 @@ static void rtw8852bt_rfk_channel(struct rtw89_dev *rtwdev, enum rtw89_chanctx_idx chanctx_idx = rtwvif_link->chanctx_idx; enum rtw89_phy_idx phy_idx = rtwvif_link->phy_idx; + rtw89_btc_ntfy_conn_rfk(rtwdev, true); + rtw8852bt_rx_dck(rtwdev, phy_idx, chanctx_idx); rtw8852bt_iqk(rtwdev, phy_idx, chanctx_idx); + rtw89_btc_ntfy_preserve_bt_time(rtwdev, 30); rtw8852bt_tssi(rtwdev, phy_idx, true, chanctx_idx); + rtw89_btc_ntfy_preserve_bt_time(rtwdev, 30); rtw8852bt_dpk(rtwdev, phy_idx, chanctx_idx); + + rtw89_btc_ntfy_conn_rfk(rtwdev, false); } static void rtw8852bt_rfk_band_changed(struct rtw89_dev *rtwdev, diff --git a/drivers/net/wireless/realtek/rtw89/rtw8852c.c b/drivers/net/wireless/realtek/rtw89/rtw8852c.c index bc84b15e7826..ecc1ff358583 100644 --- a/drivers/net/wireless/realtek/rtw89/rtw8852c.c +++ b/drivers/net/wireless/realtek/rtw89/rtw8852c.c @@ -186,10 +186,17 @@ static const struct rtw89_edcca_regs rtw8852c_edcca_regs = { .edcca_p_mask = B_EDCCA_LVL_MSK1, .ppdu_level = R_SEG0R_EDCCA_LVL, .ppdu_mask = B_EDCCA_LVL_MSK3, - .rpt_a = R_EDCCA_RPT_A, - .rpt_b = R_EDCCA_RPT_B, - .rpt_sel = R_EDCCA_RPT_SEL, - .rpt_sel_mask = B_EDCCA_RPT_SEL_MSK, + .p = {{ + .rpt_a = R_EDCCA_RPT_A, + .rpt_b = R_EDCCA_RPT_B, + .rpt_sel = R_EDCCA_RPT_SEL, + .rpt_sel_mask = B_EDCCA_RPT_SEL_MSK, + }, { + .rpt_a = R_EDCCA_RPT_P1_A, + .rpt_b = R_EDCCA_RPT_P1_B, + .rpt_sel = R_EDCCA_RPT_SEL, + .rpt_sel_mask = B_EDCCA_RPT_SEL_P1_MSK, + }}, .tx_collision_t2r_st = R_TX_COLLISION_T2R_ST, .tx_collision_t2r_st_mask = B_TX_COLLISION_T2R_ST_M, }; @@ -1853,10 +1860,16 @@ static void rtw8852c_rfk_channel(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy_idx = rtwvif_link->phy_idx; rtw8852c_mcc_get_ch_info(rtwdev, phy_idx); + rtw89_btc_ntfy_conn_rfk(rtwdev, true); + rtw8852c_rx_dck(rtwdev, phy_idx, false); rtw8852c_iqk(rtwdev, phy_idx, chanctx_idx); + rtw89_btc_ntfy_preserve_bt_time(rtwdev, 30); rtw8852c_tssi(rtwdev, phy_idx, chanctx_idx); + rtw89_btc_ntfy_preserve_bt_time(rtwdev, 30); rtw8852c_dpk(rtwdev, phy_idx, chanctx_idx); + + rtw89_btc_ntfy_conn_rfk(rtwdev, false); rtw89_fw_h2c_rf_ntfy_mcc(rtwdev); } diff --git a/drivers/net/wireless/realtek/rtw89/rtw8922a.c b/drivers/net/wireless/realtek/rtw89/rtw8922a.c index 11d66bfceb15..898a65a721dc 100644 --- a/drivers/net/wireless/realtek/rtw89/rtw8922a.c +++ b/drivers/net/wireless/realtek/rtw89/rtw8922a.c @@ -205,10 +205,17 @@ static const struct rtw89_edcca_regs rtw8922a_edcca_regs = { .edcca_p_mask = B_EDCCA_LVL_MSK1, .ppdu_level = R_SEG0R_PPDU_LVL_BE, .ppdu_mask = B_EDCCA_LVL_MSK1, - .rpt_a = R_EDCCA_RPT_A_BE, - .rpt_b = R_EDCCA_RPT_B_BE, - .rpt_sel = R_EDCCA_RPT_SEL_BE, - .rpt_sel_mask = B_EDCCA_RPT_SEL_MSK, + .p = {{ + .rpt_a = R_EDCCA_RPT_A_BE, + .rpt_b = R_EDCCA_RPT_B_BE, + .rpt_sel = R_EDCCA_RPT_SEL_BE, + .rpt_sel_mask = B_EDCCA_RPT_SEL_MSK, + }, { + .rpt_a = R_EDCCA_RPT_P1_A_BE, + .rpt_b = R_EDCCA_RPT_P1_B_BE, + .rpt_sel = R_EDCCA_RPT_SEL_BE, + .rpt_sel_mask = B_EDCCA_RPT_SEL_P1_MSK, + }}, .rpt_sel_be = R_EDCCA_RPTREG_SEL_BE, .rpt_sel_be_mask = B_EDCCA_RPTREG_SEL_BE_MSK, .tx_collision_t2r_st = R_TX_COLLISION_T2R_ST_BE, diff --git a/drivers/net/wireless/realtek/rtw89/sar.c b/drivers/net/wireless/realtek/rtw89/sar.c index 871f45a6508c..24a32dc4e67d 100644 --- a/drivers/net/wireless/realtek/rtw89/sar.c +++ b/drivers/net/wireless/realtek/rtw89/sar.c @@ -99,7 +99,7 @@ struct rtw89_sar_handler rtw89_sar_handlers[RTW89_SAR_SOURCE_NR] = { typeof(_dev) _d = (_dev); \ BUILD_BUG_ON(!rtw89_sar_handlers[_s].descr_sar_source); \ BUILD_BUG_ON(!rtw89_sar_handlers[_s].query_sar_config); \ - lockdep_assert_held(&_d->mutex); \ + lockdep_assert_wiphy(_d->hw->wiphy); \ _d->sar._cfg_name = *(_cfg_data); \ _d->sar.src = _s; \ } while (0) @@ -150,7 +150,7 @@ s8 rtw89_query_sar(struct rtw89_dev *rtwdev, u32 center_freq) s32 cfg; u8 fct; - lockdep_assert_held(&rtwdev->mutex); + lockdep_assert_wiphy(rtwdev->hw->wiphy); if (src == RTW89_SAR_SOURCE_NONE) return RTW89_SAR_TXPWR_MAC_MAX; @@ -178,72 +178,80 @@ s8 rtw89_query_sar(struct rtw89_dev *rtwdev, u32 center_freq) return rtw89_txpwr_sar_to_mac(rtwdev, fct, cfg); } -void rtw89_print_sar(struct seq_file *m, struct rtw89_dev *rtwdev, u32 center_freq) +int rtw89_print_sar(struct rtw89_dev *rtwdev, char *buf, size_t bufsz, + u32 center_freq) { const enum rtw89_sar_sources src = rtwdev->sar.src; /* its members are protected by rtw89_sar_set_src() */ const struct rtw89_sar_handler *sar_hdl = &rtw89_sar_handlers[src]; const u8 fct_mac = rtwdev->chip->txpwr_factor_mac; + char *p = buf, *end = buf + bufsz; int ret; s32 cfg; u8 fct; - lockdep_assert_held(&rtwdev->mutex); + lockdep_assert_wiphy(rtwdev->hw->wiphy); if (src == RTW89_SAR_SOURCE_NONE) { - seq_puts(m, "no SAR is applied\n"); - return; + p += scnprintf(p, end - p, "no SAR is applied\n"); + goto out; } - seq_printf(m, "source: %d (%s)\n", src, sar_hdl->descr_sar_source); + p += scnprintf(p, end - p, "source: %d (%s)\n", src, + sar_hdl->descr_sar_source); ret = sar_hdl->query_sar_config(rtwdev, center_freq, &cfg); if (ret) { - seq_printf(m, "config: return code: %d\n", ret); - seq_printf(m, "assign: max setting: %d (unit: 1/%lu dBm)\n", - RTW89_SAR_TXPWR_MAC_MAX, BIT(fct_mac)); - return; + p += scnprintf(p, end - p, "config: return code: %d\n", ret); + p += scnprintf(p, end - p, + "assign: max setting: %d (unit: 1/%lu dBm)\n", + RTW89_SAR_TXPWR_MAC_MAX, BIT(fct_mac)); + goto out; } fct = sar_hdl->txpwr_factor_sar; - seq_printf(m, "config: %d (unit: 1/%lu dBm)\n", cfg, BIT(fct)); + p += scnprintf(p, end - p, "config: %d (unit: 1/%lu dBm)\n", cfg, + BIT(fct)); + +out: + return p - buf; } -void rtw89_print_tas(struct seq_file *m, struct rtw89_dev *rtwdev) +int rtw89_print_tas(struct rtw89_dev *rtwdev, char *buf, size_t bufsz) { struct rtw89_tas_info *tas = &rtwdev->tas; + char *p = buf, *end = buf + bufsz; if (!tas->enable) { - seq_puts(m, "no TAS is applied\n"); - return; + p += scnprintf(p, end - p, "no TAS is applied\n"); + goto out; } - seq_printf(m, "DPR gap: %d\n", tas->dpr_gap); - seq_printf(m, "TAS delta: %d\n", tas->delta); + p += scnprintf(p, end - p, "DPR gap: %d\n", tas->dpr_gap); + p += scnprintf(p, end - p, "TAS delta: %d\n", tas->delta); + +out: + return p - buf; } static int rtw89_apply_sar_common(struct rtw89_dev *rtwdev, const struct rtw89_sar_cfg_common *sar) { enum rtw89_sar_sources src; - int ret = 0; - mutex_lock(&rtwdev->mutex); + lockdep_assert_wiphy(rtwdev->hw->wiphy); src = rtwdev->sar.src; if (src != RTW89_SAR_SOURCE_NONE && src != RTW89_SAR_SOURCE_COMMON) { rtw89_warn(rtwdev, "SAR source: %d is in use", src); - ret = -EBUSY; - goto exit; + return -EBUSY; } rtw89_sar_set_src(rtwdev, RTW89_SAR_SOURCE_COMMON, cfg_common, sar); rtw89_core_set_chip_txpwr(rtwdev); -exit: - mutex_unlock(&rtwdev->mutex); - return ret; + return 0; } static const struct cfg80211_sar_freq_ranges rtw89_common_sar_freq_ranges[] = { @@ -279,6 +287,8 @@ int rtw89_ops_set_sar_specs(struct ieee80211_hw *hw, s32 power; u32 i, idx; + lockdep_assert_wiphy(rtwdev->hw->wiphy); + if (sar->type != NL80211_SAR_TYPE_POWER) return -EINVAL; @@ -316,7 +326,7 @@ static void rtw89_tas_state_update(struct rtw89_dev *rtwdev) const struct rtw89_chan *chan; int ret; - lockdep_assert_held(&rtwdev->mutex); + lockdep_assert_wiphy(rtwdev->hw->wiphy); if (src == RTW89_SAR_SOURCE_NONE) return; @@ -411,7 +421,8 @@ static const struct rtw89_reg_def txpwr_regs[] = { void rtw89_tas_track(struct rtw89_dev *rtwdev) { - struct rtw89_env_monitor_info *env = &rtwdev->env_monitor; + struct rtw89_bb_ctx *bb = rtw89_get_bb_ctx(rtwdev, RTW89_PHY_0); + struct rtw89_env_monitor_info *env = &bb->env_monitor; const enum rtw89_sar_sources src = rtwdev->sar.src; u8 max_nss_num = rtwdev->chip->rf_path_num; struct rtw89_tas_info *tas = &rtwdev->tas; diff --git a/drivers/net/wireless/realtek/rtw89/sar.h b/drivers/net/wireless/realtek/rtw89/sar.h index 4ae081d2d3b4..095277df5a71 100644 --- a/drivers/net/wireless/realtek/rtw89/sar.h +++ b/drivers/net/wireless/realtek/rtw89/sar.h @@ -19,8 +19,9 @@ struct rtw89_sar_handler { extern const struct cfg80211_sar_capa rtw89_sar_capa; s8 rtw89_query_sar(struct rtw89_dev *rtwdev, u32 center_freq); -void rtw89_print_sar(struct seq_file *m, struct rtw89_dev *rtwdev, u32 center_freq); -void rtw89_print_tas(struct seq_file *m, struct rtw89_dev *rtwdev); +int rtw89_print_sar(struct rtw89_dev *rtwdev, char *buf, size_t bufsz, + u32 center_freq); +int rtw89_print_tas(struct rtw89_dev *rtwdev, char *buf, size_t bufsz); int rtw89_ops_set_sar_specs(struct ieee80211_hw *hw, const struct cfg80211_sar_specs *sar); void rtw89_tas_init(struct rtw89_dev *rtwdev); diff --git a/drivers/net/wireless/realtek/rtw89/ser.c b/drivers/net/wireless/realtek/rtw89/ser.c index 26a944d3b672..0740e303680c 100644 --- a/drivers/net/wireless/realtek/rtw89/ser.c +++ b/drivers/net/wireless/realtek/rtw89/ser.c @@ -156,9 +156,9 @@ static void ser_state_run(struct rtw89_ser *ser, u8 evt) rtw89_debug(rtwdev, RTW89_DBG_SER, "ser: %s receive %s\n", ser_st_name(ser), ser_ev_name(ser, evt)); - mutex_lock(&rtwdev->mutex); + wiphy_lock(rtwdev->hw->wiphy); rtw89_leave_lps(rtwdev); - mutex_unlock(&rtwdev->mutex); + wiphy_unlock(rtwdev->hw->wiphy); ser->st_tbl[ser->state].st_func(ser, evt); } @@ -483,10 +483,13 @@ static void ser_l1_reset_pre_st_hdl(struct rtw89_ser *ser, u8 evt) static void ser_reset_trx_st_hdl(struct rtw89_ser *ser, u8 evt) { struct rtw89_dev *rtwdev = container_of(ser, struct rtw89_dev, ser); + struct wiphy *wiphy = rtwdev->hw->wiphy; switch (evt) { case SER_EV_STATE_IN: - cancel_delayed_work_sync(&rtwdev->track_work); + wiphy_lock(wiphy); + wiphy_delayed_work_cancel(wiphy, &rtwdev->track_work); + wiphy_unlock(wiphy); drv_stop_tx(ser); if (hal_stop_dma(ser)) { @@ -517,8 +520,8 @@ static void ser_reset_trx_st_hdl(struct rtw89_ser *ser, u8 evt) hal_enable_dma(ser); drv_resume_rx(ser); drv_resume_tx(ser); - ieee80211_queue_delayed_work(rtwdev->hw, &rtwdev->track_work, - RTW89_TRACK_WORK_PERIOD); + wiphy_delayed_work_queue(wiphy, &rtwdev->track_work, + RTW89_TRACK_WORK_PERIOD); break; default: @@ -708,9 +711,9 @@ static void ser_l2_reset_st_hdl(struct rtw89_ser *ser, u8 evt) switch (evt) { case SER_EV_STATE_IN: - mutex_lock(&rtwdev->mutex); + wiphy_lock(rtwdev->hw->wiphy); ser_l2_reset_st_pre_hdl(ser); - mutex_unlock(&rtwdev->mutex); + wiphy_unlock(rtwdev->hw->wiphy); ieee80211_restart_hw(rtwdev->hw); ser_set_alarm(ser, SER_RECFG_TIMEOUT, SER_EV_L2_RECFG_TIMEOUT); diff --git a/drivers/net/wireless/realtek/rtw89/util.c b/drivers/net/wireless/realtek/rtw89/util.c index e71956ce9853..33be26873473 100644 --- a/drivers/net/wireless/realtek/rtw89/util.c +++ b/drivers/net/wireless/realtek/rtw89/util.c @@ -104,3 +104,14 @@ u64 rtw89_db_2_linear(u32 db) return linear; } EXPORT_SYMBOL(rtw89_db_2_linear); + +void rtw89_might_trailing_ellipsis(char *buf, size_t size, ssize_t used) +{ + static const char ellipsis[] = "..."; + + /* length of null terminiator isn't included in 'used' */ + if (used + 1 < size || size < sizeof(ellipsis)) + return; + + memcpy(buf + size - sizeof(ellipsis), ellipsis, sizeof(ellipsis)); +} diff --git a/drivers/net/wireless/realtek/rtw89/util.h b/drivers/net/wireless/realtek/rtw89/util.h index e669544cafd3..80441e8da60b 100644 --- a/drivers/net/wireless/realtek/rtw89/util.h +++ b/drivers/net/wireless/realtek/rtw89/util.h @@ -12,7 +12,7 @@ ieee80211_iterate_active_interfaces_atomic((rtwdev)->hw, \ IEEE80211_IFACE_ITER_NORMAL, iterator, data) -/* call this function with rtwdev->mutex is held */ +/* call this function with wiphy mutex is held */ #define rtw89_for_each_rtwvif(rtwdev, rtwvif) \ list_for_each_entry(rtwvif, &(rtwdev)->rtwvifs_list, list) @@ -25,7 +25,7 @@ static inline bool rtw89_rtwvif_in_list(struct rtw89_dev *rtwdev, { struct rtw89_vif *rtwvif; - lockdep_assert_held(&rtwdev->mutex); + lockdep_assert_wiphy(rtwdev->hw->wiphy); rtw89_for_each_rtwvif(rtwdev, rtwvif) if (rtwvif == new) @@ -77,5 +77,6 @@ static inline void ether_addr_copy_mask(u8 *dst, const u8 *src, u8 mask) u32 rtw89_linear_2_db(u64 linear); u64 rtw89_db_2_linear(u32 db); +void rtw89_might_trailing_ellipsis(char *buf, size_t size, ssize_t used); #endif diff --git a/drivers/net/wireless/realtek/rtw89/wow.c b/drivers/net/wireless/realtek/rtw89/wow.c index 01754d031bb4..17eee58503cb 100644 --- a/drivers/net/wireless/realtek/rtw89/wow.c +++ b/drivers/net/wireless/realtek/rtw89/wow.c @@ -604,6 +604,8 @@ static struct ieee80211_key_conf *rtw89_wow_gtk_rekey(struct rtw89_dev *rtwdev, struct ieee80211_key_conf *key; u8 sz; + lockdep_assert_wiphy(rtwdev->hw->wiphy); + cipher_info = rtw89_cipher_alg_recognize(cipher); sz = struct_size(rekey_conf, key, cipher_info->len); rekey_conf = kmalloc(sz, GFP_KERNEL); @@ -616,15 +618,10 @@ static struct ieee80211_key_conf *rtw89_wow_gtk_rekey(struct rtw89_dev *rtwdev, memcpy(rekey_conf->key, gtk, flex_array_size(rekey_conf, key, cipher_info->len)); - /* ieee80211_gtk_rekey_add() will call set_key(), therefore we - * need to unlock mutex - */ - mutex_unlock(&rtwdev->mutex); if (ieee80211_vif_is_mld(wow_vif)) key = ieee80211_gtk_rekey_add(wow_vif, rekey_conf, rtwvif_link->link_id); else key = ieee80211_gtk_rekey_add(wow_vif, rekey_conf, -1); - mutex_lock(&rtwdev->mutex); kfree(rekey_conf); if (IS_ERR(key)) { diff --git a/drivers/net/wireless/virtual/mac80211_hwsim.c b/drivers/net/wireless/virtual/mac80211_hwsim.c index cf6a331d4042..d0d9dab7f11f 100644 --- a/drivers/net/wireless/virtual/mac80211_hwsim.c +++ b/drivers/net/wireless/virtual/mac80211_hwsim.c @@ -5345,6 +5345,7 @@ static int mac80211_hwsim_new_radio(struct genl_info *info, ieee80211_hw_set(hw, REPORTS_TX_ACK_STATUS); ieee80211_hw_set(hw, TDLS_WIDER_BW); ieee80211_hw_set(hw, SUPPORTS_MULTI_BSSID); + ieee80211_hw_set(hw, STRICT); if (param->mlo) { hw->wiphy->flags |= WIPHY_FLAG_SUPPORTS_MLO; |