From ba9177fcef21fa98406e73c472b5ac2eb4ec5f31 Mon Sep 17 00:00:00 2001 From: Carl Huang Date: Mon, 14 Mar 2022 07:18:15 +0200 Subject: [PATCH 001/228] ath11k: Add basic WoW functionalities Implement basic WoW functionalities such as magic-packet, disconnect and pattern. The logic is very similar to ath10k. When WoW is configured, ath11k_core_suspend and ath11k_core_resume are skipped as WoW configuration and hif suspend/resume are done in ath11k_wow_op_suspend() and ath11k_wow_op_resume(). Tested-on: QCA6390 hw2.0 PCI WLAN.HST.1.0.1-01740-QCAHSTSWPLZ_V2_TO_X86-1 Signed-off-by: Carl Huang Signed-off-by: Baochen Qiang Signed-off-by: Wen Gong Signed-off-by: Kalle Valo Link: https://lore.kernel.org/r/1644308006-22784-2-git-send-email-quic_cjhuang@quicinc.com --- drivers/net/wireless/ath/ath11k/Makefile | 4 +- drivers/net/wireless/ath/ath11k/core.c | 33 ++ drivers/net/wireless/ath/ath11k/core.h | 4 + drivers/net/wireless/ath/ath11k/htc.c | 6 + drivers/net/wireless/ath/ath11k/mac.c | 59 +++- drivers/net/wireless/ath/ath11k/mac.h | 1 + drivers/net/wireless/ath/ath11k/wmi.c | 158 +++++++++ drivers/net/wireless/ath/ath11k/wmi.h | 76 ++++- drivers/net/wireless/ath/ath11k/wow.c | 414 +++++++++++++++++++++++ drivers/net/wireless/ath/ath11k/wow.h | 45 +++ 10 files changed, 781 insertions(+), 19 deletions(-) diff --git a/drivers/net/wireless/ath/ath11k/Makefile b/drivers/net/wireless/ath/ath11k/Makefile index c1fce4159f1f6..444c00c2bce20 100644 --- a/drivers/net/wireless/ath/ath11k/Makefile +++ b/drivers/net/wireless/ath/ath11k/Makefile @@ -16,14 +16,14 @@ ath11k-y += core.o \ ce.o \ peer.o \ dbring.o \ - hw.o \ - wow.o + hw.o ath11k-$(CONFIG_ATH11K_DEBUGFS) += debugfs.o debugfs_htt_stats.o debugfs_sta.o ath11k-$(CONFIG_NL80211_TESTMODE) += testmode.o ath11k-$(CONFIG_ATH11K_TRACING) += trace.o ath11k-$(CONFIG_THERMAL) += thermal.o ath11k-$(CONFIG_ATH11K_SPECTRAL) += spectral.o +ath11k-$(CONFIG_PM) += wow.o obj-$(CONFIG_ATH11K_AHB) += ath11k_ahb.o ath11k_ahb-y += ahb.o diff --git a/drivers/net/wireless/ath/ath11k/core.c b/drivers/net/wireless/ath/ath11k/core.c index 71eb7d04c3bf2..1041490502053 100644 --- a/drivers/net/wireless/ath/ath11k/core.c +++ b/drivers/net/wireless/ath/ath11k/core.c @@ -428,13 +428,30 @@ static const struct ath11k_hw_params ath11k_hw_params[] = { }, }; +static inline struct ath11k_pdev *ath11k_core_get_single_pdev(struct ath11k_base *ab) +{ + WARN_ON(!ab->hw_params.single_pdev_only); + + return &ab->pdevs[0]; +} + int ath11k_core_suspend(struct ath11k_base *ab) { int ret; + struct ath11k_pdev *pdev; + struct ath11k *ar; if (!ab->hw_params.supports_suspend) return -EOPNOTSUPP; + /* so far single_pdev_only chips have supports_suspend as true + * and only the first pdev is valid. + */ + pdev = ath11k_core_get_single_pdev(ab); + ar = pdev->ar; + if (!ar || ar->state != ATH11K_STATE_OFF) + return 0; + /* TODO: there can frames in queues so for now add delay as a hack. * Need to implement to handle and remove this delay. */ @@ -447,6 +464,12 @@ int ath11k_core_suspend(struct ath11k_base *ab) return ret; } + ret = ath11k_mac_wait_tx_complete(ar); + if (ret) { + ath11k_warn(ab, "failed to wait tx complete: %d\n", ret); + return ret; + } + ret = ath11k_wow_enable(ab); if (ret) { ath11k_warn(ab, "failed to enable wow during suspend: %d\n", ret); @@ -479,10 +502,20 @@ EXPORT_SYMBOL(ath11k_core_suspend); int ath11k_core_resume(struct ath11k_base *ab) { int ret; + struct ath11k_pdev *pdev; + struct ath11k *ar; if (!ab->hw_params.supports_suspend) return -EOPNOTSUPP; + /* so far signle_pdev_only chips have supports_suspend as true + * and only the first pdev is valid. + */ + pdev = ath11k_core_get_single_pdev(ab); + ar = pdev->ar; + if (!ar || ar->state != ATH11K_STATE_OFF) + return 0; + ret = ath11k_hif_resume(ab); if (ret) { ath11k_warn(ab, "failed to resume hif during resume: %d\n", ret); diff --git a/drivers/net/wireless/ath/ath11k/core.h b/drivers/net/wireless/ath/ath11k/core.h index c0228e91a596b..7b658d4c7d192 100644 --- a/drivers/net/wireless/ath/ath11k/core.h +++ b/drivers/net/wireless/ath/ath11k/core.h @@ -23,6 +23,7 @@ #include "thermal.h" #include "dbring.h" #include "spectral.h" +#include "wow.h" #define SM(_v, _f) (((_v) << _f##_LSB) & _f##_MASK) @@ -590,6 +591,9 @@ struct ath11k { struct work_struct wmi_mgmt_tx_work; struct sk_buff_head wmi_mgmt_tx_queue; + struct ath11k_wow wow; + struct completion target_suspend; + bool target_suspend_ack; struct ath11k_per_peer_tx_stats peer_tx_stats; struct list_head ppdu_stats_info; u32 ppdu_stat_list_depth; diff --git a/drivers/net/wireless/ath/ath11k/htc.c b/drivers/net/wireless/ath/ath11k/htc.c index 6913b7494b9bf..069c29a4fac70 100644 --- a/drivers/net/wireless/ath/ath11k/htc.c +++ b/drivers/net/wireless/ath/ath11k/htc.c @@ -272,6 +272,11 @@ void ath11k_htc_tx_completion_handler(struct ath11k_base *ab, ep_tx_complete(htc->ab, skb); } +static void ath11k_htc_wakeup_from_suspend(struct ath11k_base *ab) +{ + ath11k_dbg(ab, ATH11K_DBG_BOOT, "boot wakeup from suspend is received\n"); +} + void ath11k_htc_rx_completion_handler(struct ath11k_base *ab, struct sk_buff *skb) { @@ -376,6 +381,7 @@ void ath11k_htc_rx_completion_handler(struct ath11k_base *ab, ath11k_htc_suspend_complete(ab, false); break; case ATH11K_HTC_MSG_WAKEUP_FROM_SUSPEND_ID: + ath11k_htc_wakeup_from_suspend(ab); break; default: ath11k_warn(ab, "ignoring unsolicited htc ep0 event %ld\n", diff --git a/drivers/net/wireless/ath/ath11k/mac.c b/drivers/net/wireless/ath/ath11k/mac.c index d5b83f90d27a1..a58e56ca9a99d 100644 --- a/drivers/net/wireless/ath/ath11k/mac.c +++ b/drivers/net/wireless/ath/ath11k/mac.c @@ -16,6 +16,8 @@ #include "testmode.h" #include "peer.h" #include "debugfs_sta.h" +#include "hif.h" +#include "wow.h" #define CHAN2G(_channel, _freq, _flags) { \ .band = NL80211_BAND_2GHZ, \ @@ -7258,31 +7260,47 @@ static int ath11k_mac_op_set_frag_threshold(struct ieee80211_hw *hw, u32 value) return -EOPNOTSUPP; } -static void ath11k_mac_op_flush(struct ieee80211_hw *hw, struct ieee80211_vif *vif, - u32 queues, bool drop) +static int ath11k_mac_flush_tx_complete(struct ath11k *ar) { - struct ath11k *ar = hw->priv; long time_left; - - if (drop) - return; + int ret = 0; time_left = wait_event_timeout(ar->dp.tx_empty_waitq, (atomic_read(&ar->dp.num_tx_pending) == 0), ATH11K_FLUSH_TIMEOUT); - if (time_left == 0) - ath11k_warn(ar->ab, "failed to flush transmit queue %ld\n", time_left); + if (time_left == 0) { + ath11k_warn(ar->ab, "failed to flush transmit queue, data pkts pending %d\n", + atomic_read(&ar->dp.num_tx_pending)); + ret = -ETIMEDOUT; + } time_left = wait_event_timeout(ar->txmgmt_empty_waitq, (atomic_read(&ar->num_pending_mgmt_tx) == 0), ATH11K_FLUSH_TIMEOUT); - if (time_left == 0) - ath11k_warn(ar->ab, "failed to flush mgmt transmit queue %ld\n", - time_left); + if (time_left == 0) { + ath11k_warn(ar->ab, "failed to flush mgmt transmit queue, mgmt pkts pending %d\n", + atomic_read(&ar->num_pending_mgmt_tx)); + ret = -ETIMEDOUT; + } - ath11k_dbg(ar->ab, ATH11K_DBG_MAC, - "mac mgmt tx flush mgmt pending %d\n", - atomic_read(&ar->num_pending_mgmt_tx)); + return ret; +} + +int ath11k_mac_wait_tx_complete(struct ath11k *ar) +{ + ath11k_mac_drain_tx(ar); + return ath11k_mac_flush_tx_complete(ar); +} + +static void ath11k_mac_op_flush(struct ieee80211_hw *hw, struct ieee80211_vif *vif, + u32 queues, bool drop) +{ + struct ath11k *ar = hw->priv; + + if (drop) + return; + + ath11k_mac_flush_tx_complete(ar); } static int @@ -8104,6 +8122,13 @@ static const struct ieee80211_ops ath11k_ops = { .flush = ath11k_mac_op_flush, .sta_statistics = ath11k_mac_op_sta_statistics, CFG80211_TESTMODE_CMD(ath11k_tm_cmd) + +#ifdef CONFIG_PM + .suspend = ath11k_wow_op_suspend, + .resume = ath11k_wow_op_resume, + .set_wakeup = ath11k_wow_op_set_wakeup, +#endif + #ifdef CONFIG_ATH11K_DEBUGFS .sta_add_debugfs = ath11k_debugfs_sta_op_add, #endif @@ -8473,6 +8498,12 @@ static int __ath11k_mac_register(struct ath11k *ar) NL80211_FEATURE_SCAN_RANDOM_MAC_ADDR; } + ret = ath11k_wow_init(ar); + if (ret) { + ath11k_warn(ar->ab, "failed to init wow: %d\n", ret); + goto err_free_if_combs; + } + ar->hw->queues = ATH11K_HW_MAX_QUEUES; ar->hw->wiphy->tx_queue_len = ATH11K_QUEUE_LEN; ar->hw->offchannel_tx_hw_queue = ATH11K_HW_MAX_QUEUES - 1; diff --git a/drivers/net/wireless/ath/ath11k/mac.h b/drivers/net/wireless/ath/ath11k/mac.h index 0e6c870b09c88..045bf4fe17069 100644 --- a/drivers/net/wireless/ath/ath11k/mac.h +++ b/drivers/net/wireless/ath/ath11k/mac.h @@ -172,4 +172,5 @@ enum hal_encrypt_type ath11k_dp_tx_get_encrypt_type(u32 cipher); void ath11k_mac_handle_beacon(struct ath11k *ar, struct sk_buff *skb); void ath11k_mac_handle_beacon_miss(struct ath11k *ar, u32 vdev_id); void ath11k_mac_bcn_tx_event(struct ath11k_vif *arvif); +int ath11k_mac_wait_tx_complete(struct ath11k *ar); #endif diff --git a/drivers/net/wireless/ath/ath11k/wmi.c b/drivers/net/wireless/ath/ath11k/wmi.c index b4f86c45d81f8..25222293f162e 100644 --- a/drivers/net/wireless/ath/ath11k/wmi.c +++ b/drivers/net/wireless/ath/ath11k/wmi.c @@ -8235,3 +8235,161 @@ int ath11k_wmi_scan_prob_req_oui(struct ath11k *ar, return ath11k_wmi_cmd_send(ar->wmi, skb, WMI_SCAN_PROB_REQ_OUI_CMDID); } + +int ath11k_wmi_wow_add_wakeup_event(struct ath11k *ar, u32 vdev_id, + enum wmi_wow_wakeup_event event, + u32 enable) +{ + struct wmi_wow_add_del_event_cmd *cmd; + struct sk_buff *skb; + size_t len; + + len = sizeof(*cmd); + skb = ath11k_wmi_alloc_skb(ar->wmi->wmi_ab, len); + if (!skb) + return -ENOMEM; + + cmd = (struct wmi_wow_add_del_event_cmd *)skb->data; + cmd->tlv_header = FIELD_PREP(WMI_TLV_TAG, WMI_TAG_WOW_ADD_DEL_EVT_CMD) | + FIELD_PREP(WMI_TLV_LEN, sizeof(*cmd) - TLV_HDR_SIZE); + + cmd->vdev_id = vdev_id; + cmd->is_add = enable; + cmd->event_bitmap = (1 << event); + + ath11k_dbg(ar->ab, ATH11K_DBG_WMI, "wmi tlv wow add wakeup event %s enable %d vdev_id %d\n", + wow_wakeup_event(event), enable, vdev_id); + + return ath11k_wmi_cmd_send(ar->wmi, skb, WMI_WOW_ENABLE_DISABLE_WAKE_EVENT_CMDID); +} + +int ath11k_wmi_wow_add_pattern(struct ath11k *ar, u32 vdev_id, u32 pattern_id, + const u8 *pattern, const u8 *mask, + int pattern_len, int pattern_offset) +{ + struct wmi_wow_add_pattern_cmd *cmd; + struct wmi_wow_bitmap_pattern *bitmap; + struct wmi_tlv *tlv; + struct sk_buff *skb; + u8 *ptr; + size_t len; + + len = sizeof(*cmd) + + sizeof(*tlv) + /* array struct */ + sizeof(*bitmap) + /* bitmap */ + sizeof(*tlv) + /* empty ipv4 sync */ + sizeof(*tlv) + /* empty ipv6 sync */ + sizeof(*tlv) + /* empty magic */ + sizeof(*tlv) + /* empty info timeout */ + sizeof(*tlv) + sizeof(u32); /* ratelimit interval */ + + skb = ath11k_wmi_alloc_skb(ar->wmi->wmi_ab, len); + if (!skb) + return -ENOMEM; + + /* cmd */ + ptr = (u8 *)skb->data; + cmd = (struct wmi_wow_add_pattern_cmd *)ptr; + cmd->tlv_header = FIELD_PREP(WMI_TLV_TAG, + WMI_TAG_WOW_ADD_PATTERN_CMD) | + FIELD_PREP(WMI_TLV_LEN, sizeof(*cmd) - TLV_HDR_SIZE); + + cmd->vdev_id = vdev_id; + cmd->pattern_id = pattern_id; + cmd->pattern_type = WOW_BITMAP_PATTERN; + + ptr += sizeof(*cmd); + + /* bitmap */ + tlv = (struct wmi_tlv *)ptr; + tlv->header = FIELD_PREP(WMI_TLV_TAG, + WMI_TAG_ARRAY_STRUCT) | + FIELD_PREP(WMI_TLV_LEN, sizeof(*bitmap)); + + ptr += sizeof(*tlv); + + bitmap = (struct wmi_wow_bitmap_pattern *)ptr; + bitmap->tlv_header = FIELD_PREP(WMI_TLV_TAG, + WMI_TAG_WOW_BITMAP_PATTERN_T) | + FIELD_PREP(WMI_TLV_LEN, sizeof(*bitmap) - TLV_HDR_SIZE); + + memcpy(bitmap->patternbuf, pattern, pattern_len); + ath11k_ce_byte_swap(bitmap->patternbuf, roundup(pattern_len, 4)); + memcpy(bitmap->bitmaskbuf, mask, pattern_len); + ath11k_ce_byte_swap(bitmap->bitmaskbuf, roundup(pattern_len, 4)); + bitmap->pattern_offset = pattern_offset; + bitmap->pattern_len = pattern_len; + bitmap->bitmask_len = pattern_len; + bitmap->pattern_id = pattern_id; + + ptr += sizeof(*bitmap); + + /* ipv4 sync */ + tlv = (struct wmi_tlv *)ptr; + tlv->header = FIELD_PREP(WMI_TLV_TAG, + WMI_TAG_ARRAY_STRUCT) | + FIELD_PREP(WMI_TLV_LEN, 0); + + ptr += sizeof(*tlv); + + /* ipv6 sync */ + tlv = (struct wmi_tlv *)ptr; + tlv->header = FIELD_PREP(WMI_TLV_TAG, + WMI_TAG_ARRAY_STRUCT) | + FIELD_PREP(WMI_TLV_LEN, 0); + + ptr += sizeof(*tlv); + + /* magic */ + tlv = (struct wmi_tlv *)ptr; + tlv->header = FIELD_PREP(WMI_TLV_TAG, + WMI_TAG_ARRAY_STRUCT) | + FIELD_PREP(WMI_TLV_LEN, 0); + + ptr += sizeof(*tlv); + + /* pattern info timeout */ + tlv = (struct wmi_tlv *)ptr; + tlv->header = FIELD_PREP(WMI_TLV_TAG, + WMI_TAG_ARRAY_UINT32) | + FIELD_PREP(WMI_TLV_LEN, 0); + + ptr += sizeof(*tlv); + + /* ratelimit interval */ + tlv = (struct wmi_tlv *)ptr; + tlv->header = FIELD_PREP(WMI_TLV_TAG, + WMI_TAG_ARRAY_UINT32) | + FIELD_PREP(WMI_TLV_LEN, sizeof(u32)); + + ath11k_dbg(ar->ab, ATH11K_DBG_WMI, "wmi tlv wow add pattern vdev_id %d pattern_id %d pattern_offset %d\n", + vdev_id, pattern_id, pattern_offset); + + return ath11k_wmi_cmd_send(ar->wmi, skb, WMI_WOW_ADD_WAKE_PATTERN_CMDID); +} + +int ath11k_wmi_wow_del_pattern(struct ath11k *ar, u32 vdev_id, u32 pattern_id) +{ + struct wmi_wow_del_pattern_cmd *cmd; + struct sk_buff *skb; + size_t len; + + len = sizeof(*cmd); + skb = ath11k_wmi_alloc_skb(ar->wmi->wmi_ab, len); + if (!skb) + return -ENOMEM; + + cmd = (struct wmi_wow_del_pattern_cmd *)skb->data; + cmd->tlv_header = FIELD_PREP(WMI_TLV_TAG, + WMI_TAG_WOW_DEL_PATTERN_CMD) | + FIELD_PREP(WMI_TLV_LEN, sizeof(*cmd) - TLV_HDR_SIZE); + + cmd->vdev_id = vdev_id; + cmd->pattern_id = pattern_id; + cmd->pattern_type = WOW_BITMAP_PATTERN; + + ath11k_dbg(ar->ab, ATH11K_DBG_WMI, "wmi tlv wow del pattern vdev_id %d pattern_id %d\n", + vdev_id, pattern_id); + + return ath11k_wmi_cmd_send(ar->wmi, skb, WMI_WOW_DEL_WAKE_PATTERN_CMDID); +} diff --git a/drivers/net/wireless/ath/ath11k/wmi.h b/drivers/net/wireless/ath/ath11k/wmi.h index 587f423072508..b82f432a3d951 100644 --- a/drivers/net/wireless/ath/ath11k/wmi.h +++ b/drivers/net/wireless/ath/ath11k/wmi.h @@ -5534,6 +5534,45 @@ static inline const char *wow_reason(enum wmi_wow_wake_reason reason) #undef C2S +struct wmi_wow_ev_arg { + u32 vdev_id; + u32 flag; + enum wmi_wow_wake_reason wake_reason; + u32 data_len; +}; + +enum wmi_tlv_pattern_type { + WOW_PATTERN_MIN = 0, + WOW_BITMAP_PATTERN = WOW_PATTERN_MIN, + WOW_IPV4_SYNC_PATTERN, + WOW_IPV6_SYNC_PATTERN, + WOW_WILD_CARD_PATTERN, + WOW_TIMER_PATTERN, + WOW_MAGIC_PATTERN, + WOW_IPV6_RA_PATTERN, + WOW_IOAC_PKT_PATTERN, + WOW_IOAC_TMR_PATTERN, + WOW_PATTERN_MAX +}; + +#define WOW_DEFAULT_BITMAP_PATTERN_SIZE 148 +#define WOW_DEFAULT_BITMASK_SIZE 148 + +#define WOW_MIN_PATTERN_SIZE 1 +#define WOW_MAX_PATTERN_SIZE 148 +#define WOW_MAX_PKT_OFFSET 128 +#define WOW_HDR_LEN (sizeof(struct ieee80211_hdr_3addr) + \ + sizeof(struct rfc1042_hdr)) +#define WOW_MAX_REDUCE (WOW_HDR_LEN - sizeof(struct ethhdr) - \ + offsetof(struct ieee80211_hdr_3addr, addr1)) + +struct wmi_wow_add_del_event_cmd { + u32 tlv_header; + u32 vdev_id; + u32 is_add; + u32 event_bitmap; +} __packed; + struct wmi_wow_enable_cmd { u32 tlv_header; u32 enable; @@ -5546,12 +5585,36 @@ struct wmi_wow_host_wakeup_ind { u32 reserved; } __packed; -struct wmi_wow_ev_arg { +struct wmi_tlv_wow_event_info { u32 vdev_id; u32 flag; - enum wmi_wow_wake_reason wake_reason; + u32 wake_reason; u32 data_len; -}; +} __packed; + +struct wmi_wow_bitmap_pattern { + u32 tlv_header; + u8 patternbuf[WOW_DEFAULT_BITMAP_PATTERN_SIZE]; + u8 bitmaskbuf[WOW_DEFAULT_BITMASK_SIZE]; + u32 pattern_offset; + u32 pattern_len; + u32 bitmask_len; + u32 pattern_id; +} __packed; + +struct wmi_wow_add_pattern_cmd { + u32 tlv_header; + u32 vdev_id; + u32 pattern_id; + u32 pattern_type; +} __packed; + +struct wmi_wow_del_pattern_cmd { + u32 tlv_header; + u32 vdev_id; + u32 pattern_id; + u32 pattern_type; +} __packed; int ath11k_wmi_cmd_send(struct ath11k_pdev_wmi *wmi, struct sk_buff *skb, u32 cmd_id); @@ -5714,4 +5777,11 @@ int ath11k_wmi_scan_prob_req_oui(struct ath11k *ar, const u8 mac_addr[ETH_ALEN]); int ath11k_wmi_fw_dbglog_cfg(struct ath11k *ar, u32 *module_id_bitmap, struct ath11k_fw_dbglog *dbglog); +int ath11k_wmi_wow_del_pattern(struct ath11k *ar, u32 vdev_id, u32 pattern_id); +int ath11k_wmi_wow_add_pattern(struct ath11k *ar, u32 vdev_id, u32 pattern_id, + const u8 *pattern, const u8 *mask, + int pattern_len, int pattern_offset); +int ath11k_wmi_wow_add_wakeup_event(struct ath11k *ar, u32 vdev_id, + enum wmi_wow_wakeup_event event, + u32 enable); #endif diff --git a/drivers/net/wireless/ath/ath11k/wow.c b/drivers/net/wireless/ath/ath11k/wow.c index 43c62e99dd0e8..837dab469ab29 100644 --- a/drivers/net/wireless/ath/ath11k/wow.c +++ b/drivers/net/wireless/ath/ath11k/wow.c @@ -6,12 +6,22 @@ #include #include "mac.h" + +#include #include "core.h" #include "hif.h" #include "debug.h" #include "wmi.h" #include "wow.h" +static const struct wiphy_wowlan_support ath11k_wowlan_support = { + .flags = WIPHY_WOWLAN_DISCONNECT | + WIPHY_WOWLAN_MAGIC_PKT, + .pattern_min_len = WOW_MIN_PATTERN_SIZE, + .pattern_max_len = WOW_MAX_PATTERN_SIZE, + .max_pkt_offset = WOW_MAX_PKT_OFFSET, +}; + int ath11k_wow_enable(struct ath11k_base *ab) { struct ath11k *ar = ath11k_ab_to_ar(ab, 0); @@ -71,3 +81,407 @@ int ath11k_wow_wakeup(struct ath11k_base *ab) return 0; } + +static int ath11k_wow_vif_cleanup(struct ath11k_vif *arvif) +{ + struct ath11k *ar = arvif->ar; + int i, ret; + + for (i = 0; i < WOW_EVENT_MAX; i++) { + ret = ath11k_wmi_wow_add_wakeup_event(ar, arvif->vdev_id, i, 0); + if (ret) { + ath11k_warn(ar->ab, "failed to issue wow wakeup for event %s on vdev %i: %d\n", + wow_wakeup_event(i), arvif->vdev_id, ret); + return ret; + } + } + + for (i = 0; i < ar->wow.max_num_patterns; i++) { + ret = ath11k_wmi_wow_del_pattern(ar, arvif->vdev_id, i); + if (ret) { + ath11k_warn(ar->ab, "failed to delete wow pattern %d for vdev %i: %d\n", + i, arvif->vdev_id, ret); + return ret; + } + } + + return 0; +} + +static int ath11k_wow_cleanup(struct ath11k *ar) +{ + struct ath11k_vif *arvif; + int ret; + + lockdep_assert_held(&ar->conf_mutex); + + list_for_each_entry(arvif, &ar->arvifs, list) { + ret = ath11k_wow_vif_cleanup(arvif); + if (ret) { + ath11k_warn(ar->ab, "failed to clean wow wakeups on vdev %i: %d\n", + arvif->vdev_id, ret); + return ret; + } + } + + return 0; +} + +/* Convert a 802.3 format to a 802.11 format. + * +------------+-----------+--------+----------------+ + * 802.3: |dest mac(6B)|src mac(6B)|type(2B)| body... | + * +------------+-----------+--------+----------------+ + * |__ |_______ |____________ |________ + * | | | | + * +--+------------+----+-----------+---------------+-----------+ + * 802.11: |4B|dest mac(6B)| 6B |src mac(6B)| 8B |type(2B)| body... | + * +--+------------+----+-----------+---------------+-----------+ + */ +static void ath11k_wow_convert_8023_to_80211(struct cfg80211_pkt_pattern *new, + const struct cfg80211_pkt_pattern *old) +{ + u8 hdr_8023_pattern[ETH_HLEN] = {}; + u8 hdr_8023_bit_mask[ETH_HLEN] = {}; + u8 hdr_80211_pattern[WOW_HDR_LEN] = {}; + u8 hdr_80211_bit_mask[WOW_HDR_LEN] = {}; + + int total_len = old->pkt_offset + old->pattern_len; + int hdr_80211_end_offset; + + struct ieee80211_hdr_3addr *new_hdr_pattern = + (struct ieee80211_hdr_3addr *)hdr_80211_pattern; + struct ieee80211_hdr_3addr *new_hdr_mask = + (struct ieee80211_hdr_3addr *)hdr_80211_bit_mask; + struct ethhdr *old_hdr_pattern = (struct ethhdr *)hdr_8023_pattern; + struct ethhdr *old_hdr_mask = (struct ethhdr *)hdr_8023_bit_mask; + int hdr_len = sizeof(*new_hdr_pattern); + + struct rfc1042_hdr *new_rfc_pattern = + (struct rfc1042_hdr *)(hdr_80211_pattern + hdr_len); + struct rfc1042_hdr *new_rfc_mask = + (struct rfc1042_hdr *)(hdr_80211_bit_mask + hdr_len); + int rfc_len = sizeof(*new_rfc_pattern); + + memcpy(hdr_8023_pattern + old->pkt_offset, + old->pattern, ETH_HLEN - old->pkt_offset); + memcpy(hdr_8023_bit_mask + old->pkt_offset, + old->mask, ETH_HLEN - old->pkt_offset); + + /* Copy destination address */ + memcpy(new_hdr_pattern->addr1, old_hdr_pattern->h_dest, ETH_ALEN); + memcpy(new_hdr_mask->addr1, old_hdr_mask->h_dest, ETH_ALEN); + + /* Copy source address */ + memcpy(new_hdr_pattern->addr3, old_hdr_pattern->h_source, ETH_ALEN); + memcpy(new_hdr_mask->addr3, old_hdr_mask->h_source, ETH_ALEN); + + /* Copy logic link type */ + memcpy(&new_rfc_pattern->snap_type, + &old_hdr_pattern->h_proto, + sizeof(old_hdr_pattern->h_proto)); + memcpy(&new_rfc_mask->snap_type, + &old_hdr_mask->h_proto, + sizeof(old_hdr_mask->h_proto)); + + /* Compute new pkt_offset */ + if (old->pkt_offset < ETH_ALEN) + new->pkt_offset = old->pkt_offset + + offsetof(struct ieee80211_hdr_3addr, addr1); + else if (old->pkt_offset < offsetof(struct ethhdr, h_proto)) + new->pkt_offset = old->pkt_offset + + offsetof(struct ieee80211_hdr_3addr, addr3) - + offsetof(struct ethhdr, h_source); + else + new->pkt_offset = old->pkt_offset + hdr_len + rfc_len - ETH_HLEN; + + /* Compute new hdr end offset */ + if (total_len > ETH_HLEN) + hdr_80211_end_offset = hdr_len + rfc_len; + else if (total_len > offsetof(struct ethhdr, h_proto)) + hdr_80211_end_offset = hdr_len + rfc_len + total_len - ETH_HLEN; + else if (total_len > ETH_ALEN) + hdr_80211_end_offset = total_len - ETH_ALEN + + offsetof(struct ieee80211_hdr_3addr, addr3); + else + hdr_80211_end_offset = total_len + + offsetof(struct ieee80211_hdr_3addr, addr1); + + new->pattern_len = hdr_80211_end_offset - new->pkt_offset; + + memcpy((u8 *)new->pattern, + hdr_80211_pattern + new->pkt_offset, + new->pattern_len); + memcpy((u8 *)new->mask, + hdr_80211_bit_mask + new->pkt_offset, + new->pattern_len); + + if (total_len > ETH_HLEN) { + /* Copy frame body */ + memcpy((u8 *)new->pattern + new->pattern_len, + (void *)old->pattern + ETH_HLEN - old->pkt_offset, + total_len - ETH_HLEN); + memcpy((u8 *)new->mask + new->pattern_len, + (void *)old->mask + ETH_HLEN - old->pkt_offset, + total_len - ETH_HLEN); + + new->pattern_len += total_len - ETH_HLEN; + } +} + +static int ath11k_vif_wow_set_wakeups(struct ath11k_vif *arvif, + struct cfg80211_wowlan *wowlan) +{ + int ret, i; + unsigned long wow_mask = 0; + struct ath11k *ar = arvif->ar; + const struct cfg80211_pkt_pattern *patterns = wowlan->patterns; + int pattern_id = 0; + + /* Setup requested WOW features */ + switch (arvif->vdev_type) { + case WMI_VDEV_TYPE_IBSS: + __set_bit(WOW_BEACON_EVENT, &wow_mask); + fallthrough; + case WMI_VDEV_TYPE_AP: + __set_bit(WOW_DEAUTH_RECVD_EVENT, &wow_mask); + __set_bit(WOW_DISASSOC_RECVD_EVENT, &wow_mask); + __set_bit(WOW_PROBE_REQ_WPS_IE_EVENT, &wow_mask); + __set_bit(WOW_AUTH_REQ_EVENT, &wow_mask); + __set_bit(WOW_ASSOC_REQ_EVENT, &wow_mask); + __set_bit(WOW_HTT_EVENT, &wow_mask); + __set_bit(WOW_RA_MATCH_EVENT, &wow_mask); + break; + case WMI_VDEV_TYPE_STA: + if (wowlan->disconnect) { + __set_bit(WOW_DEAUTH_RECVD_EVENT, &wow_mask); + __set_bit(WOW_DISASSOC_RECVD_EVENT, &wow_mask); + __set_bit(WOW_BMISS_EVENT, &wow_mask); + __set_bit(WOW_CSA_IE_EVENT, &wow_mask); + } + + if (wowlan->magic_pkt) + __set_bit(WOW_MAGIC_PKT_RECVD_EVENT, &wow_mask); + break; + default: + break; + } + + for (i = 0; i < wowlan->n_patterns; i++) { + u8 bitmask[WOW_MAX_PATTERN_SIZE] = {}; + u8 ath_pattern[WOW_MAX_PATTERN_SIZE] = {}; + u8 ath_bitmask[WOW_MAX_PATTERN_SIZE] = {}; + struct cfg80211_pkt_pattern new_pattern = {}; + struct cfg80211_pkt_pattern old_pattern = patterns[i]; + int j; + + new_pattern.pattern = ath_pattern; + new_pattern.mask = ath_bitmask; + if (patterns[i].pattern_len > WOW_MAX_PATTERN_SIZE) + continue; + /* convert bytemask to bitmask */ + for (j = 0; j < patterns[i].pattern_len; j++) + if (patterns[i].mask[j / 8] & BIT(j % 8)) + bitmask[j] = 0xff; + old_pattern.mask = bitmask; + + if (ar->wmi->wmi_ab->wlan_resource_config.rx_decap_mode == + ATH11K_HW_TXRX_NATIVE_WIFI) { + if (patterns[i].pkt_offset < ETH_HLEN) { + u8 pattern_ext[WOW_MAX_PATTERN_SIZE] = {}; + + memcpy(pattern_ext, old_pattern.pattern, + old_pattern.pattern_len); + old_pattern.pattern = pattern_ext; + ath11k_wow_convert_8023_to_80211(&new_pattern, + &old_pattern); + } else { + new_pattern = old_pattern; + new_pattern.pkt_offset += WOW_HDR_LEN - ETH_HLEN; + } + } + + if (WARN_ON(new_pattern.pattern_len > WOW_MAX_PATTERN_SIZE)) + return -EINVAL; + + ret = ath11k_wmi_wow_add_pattern(ar, arvif->vdev_id, + pattern_id, + new_pattern.pattern, + new_pattern.mask, + new_pattern.pattern_len, + new_pattern.pkt_offset); + if (ret) { + ath11k_warn(ar->ab, "failed to add pattern %i to vdev %i: %d\n", + pattern_id, + arvif->vdev_id, ret); + return ret; + } + + pattern_id++; + __set_bit(WOW_PATTERN_MATCH_EVENT, &wow_mask); + } + + for (i = 0; i < WOW_EVENT_MAX; i++) { + if (!test_bit(i, &wow_mask)) + continue; + ret = ath11k_wmi_wow_add_wakeup_event(ar, arvif->vdev_id, i, 1); + if (ret) { + ath11k_warn(ar->ab, "failed to enable wakeup event %s on vdev %i: %d\n", + wow_wakeup_event(i), arvif->vdev_id, ret); + return ret; + } + } + + return 0; +} + +static int ath11k_wow_set_wakeups(struct ath11k *ar, + struct cfg80211_wowlan *wowlan) +{ + struct ath11k_vif *arvif; + int ret; + + lockdep_assert_held(&ar->conf_mutex); + + list_for_each_entry(arvif, &ar->arvifs, list) { + ret = ath11k_vif_wow_set_wakeups(arvif, wowlan); + if (ret) { + ath11k_warn(ar->ab, "failed to set wow wakeups on vdev %i: %d\n", + arvif->vdev_id, ret); + return ret; + } + } + + return 0; +} + +int ath11k_wow_op_suspend(struct ieee80211_hw *hw, + struct cfg80211_wowlan *wowlan) +{ + struct ath11k *ar = hw->priv; + int ret; + + mutex_lock(&ar->conf_mutex); + + ret = ath11k_wow_cleanup(ar); + if (ret) { + ath11k_warn(ar->ab, "failed to clear wow wakeup events: %d\n", + ret); + goto exit; + } + + ret = ath11k_wow_set_wakeups(ar, wowlan); + if (ret) { + ath11k_warn(ar->ab, "failed to set wow wakeup events: %d\n", + ret); + goto cleanup; + } + + ret = ath11k_mac_wait_tx_complete(ar); + if (ret) { + ath11k_warn(ar->ab, "failed to wait tx complete: %d\n", ret); + goto cleanup; + } + + ret = ath11k_wow_enable(ar->ab); + if (ret) { + ath11k_warn(ar->ab, "failed to start wow: %d\n", ret); + goto cleanup; + } + + ath11k_ce_stop_shadow_timers(ar->ab); + ath11k_dp_stop_shadow_timers(ar->ab); + + ath11k_hif_irq_disable(ar->ab); + ath11k_hif_ce_irq_disable(ar->ab); + + ret = ath11k_hif_suspend(ar->ab); + if (ret) { + ath11k_warn(ar->ab, "failed to suspend hif: %d\n", ret); + goto wakeup; + } + + goto exit; + +wakeup: + ath11k_wow_wakeup(ar->ab); + +cleanup: + ath11k_wow_cleanup(ar); + +exit: + mutex_unlock(&ar->conf_mutex); + return ret ? 1 : 0; +} + +void ath11k_wow_op_set_wakeup(struct ieee80211_hw *hw, bool enabled) +{ + struct ath11k *ar = hw->priv; + + mutex_lock(&ar->conf_mutex); + device_set_wakeup_enable(ar->ab->dev, enabled); + mutex_unlock(&ar->conf_mutex); +} + +int ath11k_wow_op_resume(struct ieee80211_hw *hw) +{ + struct ath11k *ar = hw->priv; + int ret; + + mutex_lock(&ar->conf_mutex); + + ret = ath11k_hif_resume(ar->ab); + if (ret) { + ath11k_warn(ar->ab, "failed to resume hif: %d\n", ret); + goto exit; + } + + ath11k_hif_ce_irq_enable(ar->ab); + ath11k_hif_irq_enable(ar->ab); + + ret = ath11k_wow_wakeup(ar->ab); + if (ret) + ath11k_warn(ar->ab, "failed to wakeup from wow: %d\n", ret); + +exit: + if (ret) { + switch (ar->state) { + case ATH11K_STATE_ON: + ar->state = ATH11K_STATE_RESTARTING; + ret = 1; + break; + case ATH11K_STATE_OFF: + case ATH11K_STATE_RESTARTING: + case ATH11K_STATE_RESTARTED: + case ATH11K_STATE_WEDGED: + ath11k_warn(ar->ab, "encountered unexpected device state %d on resume, cannot recover\n", + ar->state); + ret = -EIO; + break; + } + } + + mutex_unlock(&ar->conf_mutex); + return ret; +} + +int ath11k_wow_init(struct ath11k *ar) +{ + if (WARN_ON(!test_bit(WMI_TLV_SERVICE_WOW, ar->wmi->wmi_ab->svc_map))) + return -EINVAL; + + ar->wow.wowlan_support = ath11k_wowlan_support; + + if (ar->wmi->wmi_ab->wlan_resource_config.rx_decap_mode == + ATH11K_HW_TXRX_NATIVE_WIFI) { + ar->wow.wowlan_support.pattern_max_len -= WOW_MAX_REDUCE; + ar->wow.wowlan_support.max_pkt_offset -= WOW_MAX_REDUCE; + } + + ar->wow.max_num_patterns = ATH11K_WOW_PATTERNS; + ar->wow.wowlan_support.n_patterns = ar->wow.max_num_patterns; + ar->hw->wiphy->wowlan = &ar->wow.wowlan_support; + + device_set_wakeup_capable(ar->ab->dev, true); + + return 0; +} diff --git a/drivers/net/wireless/ath/ath11k/wow.h b/drivers/net/wireless/ath/ath11k/wow.h index dabc4ee63cf6f..553ba850d910b 100644 --- a/drivers/net/wireless/ath/ath11k/wow.h +++ b/drivers/net/wireless/ath/ath11k/wow.h @@ -3,8 +3,53 @@ * Copyright (c) 2020 The Linux Foundation. All rights reserved. */ +#ifndef _WOW_H_ +#define _WOW_H_ + +struct ath11k_wow { + u32 max_num_patterns; + struct completion wakeup_completed; + struct wiphy_wowlan_support wowlan_support; +}; + +struct rfc1042_hdr { + u8 llc_dsap; + u8 llc_ssap; + u8 llc_ctrl; + u8 snap_oui[3]; + __be16 snap_type; +} __packed; + #define ATH11K_WOW_RETRY_NUM 3 #define ATH11K_WOW_RETRY_WAIT_MS 200 +#define ATH11K_WOW_PATTERNS 22 +#ifdef CONFIG_PM + +int ath11k_wow_init(struct ath11k *ar); +int ath11k_wow_op_suspend(struct ieee80211_hw *hw, + struct cfg80211_wowlan *wowlan); +int ath11k_wow_op_resume(struct ieee80211_hw *hw); +void ath11k_wow_op_set_wakeup(struct ieee80211_hw *hw, bool enabled); int ath11k_wow_enable(struct ath11k_base *ab); int ath11k_wow_wakeup(struct ath11k_base *ab); + +#else + +static inline int ath11k_wow_init(struct ath11k *ar) +{ + return 0; +} + +static inline int ath11k_wow_enable(struct ath11k_base *ab) +{ + return 0; +} + +static inline int ath11k_wow_wakeup(struct ath11k_base *ab) +{ + return 0; +} + +#endif /* CONFIG_PM */ +#endif /* _WOW_H_ */ From fec4b898f369a9b9d516f7bfc459eb4a8c5ceb2c Mon Sep 17 00:00:00 2001 From: Carl Huang Date: Mon, 14 Mar 2022 07:18:16 +0200 Subject: [PATCH 002/228] ath11k: Add WoW net-detect functionality Implement net-detect feature by setting flag WIPHY_WOWLAN_NET_DETECT if firmware supports this feature. Driver sets the related PNO configuration to firmware before entering WoW and firmware then scans periodically and wakes up host if a specific SSID is found. Tested-on: QCA6390 hw2.0 PCI WLAN.HST.1.0.1-01740-QCAHSTSWPLZ_V2_TO_X86-1 Signed-off-by: Carl Huang Signed-off-by: Kalle Valo Link: https://lore.kernel.org/r/1644308006-22784-3-git-send-email-quic_cjhuang@quicinc.com --- drivers/net/wireless/ath/ath11k/core.h | 1 + drivers/net/wireless/ath/ath11k/mac.c | 12 ++ drivers/net/wireless/ath/ath11k/wmi.c | 154 ++++++++++++++++++++++ drivers/net/wireless/ath/ath11k/wmi.h | 169 ++++++++++++++++++++++++ drivers/net/wireless/ath/ath11k/wow.c | 175 ++++++++++++++++++++++++- 5 files changed, 510 insertions(+), 1 deletion(-) diff --git a/drivers/net/wireless/ath/ath11k/core.h b/drivers/net/wireless/ath/ath11k/core.h index 7b658d4c7d192..1f5e977aa9769 100644 --- a/drivers/net/wireless/ath/ath11k/core.h +++ b/drivers/net/wireless/ath/ath11k/core.h @@ -617,6 +617,7 @@ struct ath11k { bool regdom_set_by_user; int hw_rate_code; u8 twt_enabled; + bool nlo_enabled; }; struct ath11k_band_cap { diff --git a/drivers/net/wireless/ath/ath11k/mac.c b/drivers/net/wireless/ath/ath11k/mac.c index a58e56ca9a99d..7a6c758b8e459 100644 --- a/drivers/net/wireless/ath/ath11k/mac.c +++ b/drivers/net/wireless/ath/ath11k/mac.c @@ -8498,6 +8498,18 @@ static int __ath11k_mac_register(struct ath11k *ar) NL80211_FEATURE_SCAN_RANDOM_MAC_ADDR; } + if (test_bit(WMI_TLV_SERVICE_NLO, ar->wmi->wmi_ab->svc_map)) { + ar->hw->wiphy->max_sched_scan_ssids = WMI_PNO_MAX_SUPP_NETWORKS; + ar->hw->wiphy->max_match_sets = WMI_PNO_MAX_SUPP_NETWORKS; + ar->hw->wiphy->max_sched_scan_ie_len = WMI_PNO_MAX_IE_LENGTH; + ar->hw->wiphy->max_sched_scan_plans = WMI_PNO_MAX_SCHED_SCAN_PLANS; + ar->hw->wiphy->max_sched_scan_plan_interval = + WMI_PNO_MAX_SCHED_SCAN_PLAN_INT; + ar->hw->wiphy->max_sched_scan_plan_iterations = + WMI_PNO_MAX_SCHED_SCAN_PLAN_ITRNS; + ar->hw->wiphy->features |= NL80211_FEATURE_ND_RANDOM_MAC_ADDR; + } + ret = ath11k_wow_init(ar); if (ret) { ath11k_warn(ar->ab, "failed to init wow: %d\n", ret); diff --git a/drivers/net/wireless/ath/ath11k/wmi.c b/drivers/net/wireless/ath/ath11k/wmi.c index 25222293f162e..d4d34b932e0bb 100644 --- a/drivers/net/wireless/ath/ath11k/wmi.c +++ b/drivers/net/wireless/ath/ath11k/wmi.c @@ -8393,3 +8393,157 @@ int ath11k_wmi_wow_del_pattern(struct ath11k *ar, u32 vdev_id, u32 pattern_id) return ath11k_wmi_cmd_send(ar->wmi, skb, WMI_WOW_DEL_WAKE_PATTERN_CMDID); } + +static struct sk_buff * +ath11k_wmi_op_gen_config_pno_start(struct ath11k *ar, + u32 vdev_id, + struct wmi_pno_scan_req *pno) +{ + struct nlo_configured_parameters *nlo_list; + struct wmi_wow_nlo_config_cmd *cmd; + struct wmi_tlv *tlv; + struct sk_buff *skb; + u32 *channel_list; + size_t len, nlo_list_len, channel_list_len; + u8 *ptr; + u32 i; + + len = sizeof(*cmd) + + sizeof(*tlv) + + /* TLV place holder for array of structures + * nlo_configured_parameters(nlo_list) + */ + sizeof(*tlv); + /* TLV place holder for array of uint32 channel_list */ + + channel_list_len = sizeof(u32) * pno->a_networks[0].channel_count; + len += channel_list_len; + + nlo_list_len = sizeof(*nlo_list) * pno->uc_networks_count; + len += nlo_list_len; + + skb = ath11k_wmi_alloc_skb(ar->wmi->wmi_ab, len); + if (!skb) + return ERR_PTR(-ENOMEM); + + ptr = (u8 *)skb->data; + cmd = (struct wmi_wow_nlo_config_cmd *)ptr; + cmd->tlv_header = FIELD_PREP(WMI_TLV_TAG, WMI_TAG_NLO_CONFIG_CMD) | + FIELD_PREP(WMI_TLV_LEN, sizeof(*cmd) - TLV_HDR_SIZE); + + cmd->vdev_id = pno->vdev_id; + cmd->flags = WMI_NLO_CONFIG_START | WMI_NLO_CONFIG_SSID_HIDE_EN; + + /* current FW does not support min-max range for dwell time */ + cmd->active_dwell_time = pno->active_max_time; + cmd->passive_dwell_time = pno->passive_max_time; + + if (pno->do_passive_scan) + cmd->flags |= WMI_NLO_CONFIG_SCAN_PASSIVE; + + cmd->fast_scan_period = pno->fast_scan_period; + cmd->slow_scan_period = pno->slow_scan_period; + cmd->fast_scan_max_cycles = pno->fast_scan_max_cycles; + cmd->delay_start_time = pno->delay_start_time; + + if (pno->enable_pno_scan_randomization) { + cmd->flags |= WMI_NLO_CONFIG_SPOOFED_MAC_IN_PROBE_REQ | + WMI_NLO_CONFIG_RANDOM_SEQ_NO_IN_PROBE_REQ; + ether_addr_copy(cmd->mac_addr.addr, pno->mac_addr); + ether_addr_copy(cmd->mac_mask.addr, pno->mac_addr_mask); + ath11k_ce_byte_swap(cmd->mac_addr.addr, 8); + ath11k_ce_byte_swap(cmd->mac_mask.addr, 8); + } + + ptr += sizeof(*cmd); + + /* nlo_configured_parameters(nlo_list) */ + cmd->no_of_ssids = pno->uc_networks_count; + tlv = (struct wmi_tlv *)ptr; + tlv->header = FIELD_PREP(WMI_TLV_TAG, + WMI_TAG_ARRAY_STRUCT) | + FIELD_PREP(WMI_TLV_LEN, nlo_list_len); + + ptr += sizeof(*tlv); + nlo_list = (struct nlo_configured_parameters *)ptr; + for (i = 0; i < cmd->no_of_ssids; i++) { + tlv = (struct wmi_tlv *)(&nlo_list[i].tlv_header); + tlv->header = FIELD_PREP(WMI_TLV_TAG, WMI_TAG_ARRAY_BYTE) | + FIELD_PREP(WMI_TLV_LEN, sizeof(*nlo_list) - sizeof(*tlv)); + + nlo_list[i].ssid.valid = true; + nlo_list[i].ssid.ssid.ssid_len = pno->a_networks[i].ssid.ssid_len; + memcpy(nlo_list[i].ssid.ssid.ssid, + pno->a_networks[i].ssid.ssid, + nlo_list[i].ssid.ssid.ssid_len); + ath11k_ce_byte_swap(nlo_list[i].ssid.ssid.ssid, + roundup(nlo_list[i].ssid.ssid.ssid_len, 4)); + + if (pno->a_networks[i].rssi_threshold && + pno->a_networks[i].rssi_threshold > -300) { + nlo_list[i].rssi_cond.valid = true; + nlo_list[i].rssi_cond.rssi = + pno->a_networks[i].rssi_threshold; + } + + nlo_list[i].bcast_nw_type.valid = true; + nlo_list[i].bcast_nw_type.bcast_nw_type = + pno->a_networks[i].bcast_nw_type; + } + + ptr += nlo_list_len; + cmd->num_of_channels = pno->a_networks[0].channel_count; + tlv = (struct wmi_tlv *)ptr; + tlv->header = FIELD_PREP(WMI_TLV_TAG, WMI_TAG_ARRAY_UINT32) | + FIELD_PREP(WMI_TLV_LEN, channel_list_len); + ptr += sizeof(*tlv); + channel_list = (u32 *)ptr; + for (i = 0; i < cmd->num_of_channels; i++) + channel_list[i] = pno->a_networks[0].channels[i]; + + ath11k_dbg(ar->ab, ATH11K_DBG_WMI, "wmi tlv start pno config vdev_id %d\n", + vdev_id); + + return skb; +} + +static struct sk_buff *ath11k_wmi_op_gen_config_pno_stop(struct ath11k *ar, + u32 vdev_id) +{ + struct wmi_wow_nlo_config_cmd *cmd; + struct sk_buff *skb; + size_t len; + + len = sizeof(*cmd); + skb = ath11k_wmi_alloc_skb(ar->wmi->wmi_ab, len); + if (!skb) + return ERR_PTR(-ENOMEM); + + cmd = (struct wmi_wow_nlo_config_cmd *)skb->data; + cmd->tlv_header = FIELD_PREP(WMI_TLV_TAG, WMI_TAG_NLO_CONFIG_CMD) | + FIELD_PREP(WMI_TLV_LEN, len - TLV_HDR_SIZE); + + cmd->vdev_id = vdev_id; + cmd->flags = WMI_NLO_CONFIG_STOP; + + ath11k_dbg(ar->ab, ATH11K_DBG_WMI, + "wmi tlv stop pno config vdev_id %d\n", vdev_id); + return skb; +} + +int ath11k_wmi_wow_config_pno(struct ath11k *ar, u32 vdev_id, + struct wmi_pno_scan_req *pno_scan) +{ + struct sk_buff *skb; + + if (pno_scan->enable) + skb = ath11k_wmi_op_gen_config_pno_start(ar, vdev_id, pno_scan); + else + skb = ath11k_wmi_op_gen_config_pno_stop(ar, vdev_id); + + if (IS_ERR_OR_NULL(skb)) + return -ENOMEM; + + return ath11k_wmi_cmd_send(ar->wmi, skb, WMI_NETWORK_LIST_OFFLOAD_CONFIG_CMDID); +} + diff --git a/drivers/net/wireless/ath/ath11k/wmi.h b/drivers/net/wireless/ath/ath11k/wmi.h index b82f432a3d951..9150e0555c6d9 100644 --- a/drivers/net/wireless/ath/ath11k/wmi.h +++ b/drivers/net/wireless/ath/ath11k/wmi.h @@ -5616,6 +5616,173 @@ struct wmi_wow_del_pattern_cmd { u32 pattern_type; } __packed; +#define WMI_PNO_MAX_SCHED_SCAN_PLANS 2 +#define WMI_PNO_MAX_SCHED_SCAN_PLAN_INT 7200 +#define WMI_PNO_MAX_SCHED_SCAN_PLAN_ITRNS 100 +#define WMI_PNO_MAX_NETW_CHANNELS 26 +#define WMI_PNO_MAX_NETW_CHANNELS_EX 60 +#define WMI_PNO_MAX_SUPP_NETWORKS WLAN_SCAN_PARAMS_MAX_SSID +#define WMI_PNO_MAX_IE_LENGTH WLAN_SCAN_PARAMS_MAX_IE_LEN + +/* size based of dot11 declaration without extra IEs as we will not carry those for PNO */ +#define WMI_PNO_MAX_PB_REQ_SIZE 450 + +#define WMI_PNO_24G_DEFAULT_CH 1 +#define WMI_PNO_5G_DEFAULT_CH 36 + +#define WMI_ACTIVE_MAX_CHANNEL_TIME 40 +#define WMI_PASSIVE_MAX_CHANNEL_TIME 110 + +/* SSID broadcast type */ +enum wmi_ssid_bcast_type { + BCAST_UNKNOWN = 0, + BCAST_NORMAL = 1, + BCAST_HIDDEN = 2, +}; + +#define WMI_NLO_MAX_SSIDS 16 +#define WMI_NLO_MAX_CHAN 48 + +#define WMI_NLO_CONFIG_STOP BIT(0) +#define WMI_NLO_CONFIG_START BIT(1) +#define WMI_NLO_CONFIG_RESET BIT(2) +#define WMI_NLO_CONFIG_SLOW_SCAN BIT(4) +#define WMI_NLO_CONFIG_FAST_SCAN BIT(5) +#define WMI_NLO_CONFIG_SSID_HIDE_EN BIT(6) + +/* This bit is used to indicate if EPNO or supplicant PNO is enabled. + * Only one of them can be enabled at a given time + */ +#define WMI_NLO_CONFIG_ENLO BIT(7) +#define WMI_NLO_CONFIG_SCAN_PASSIVE BIT(8) +#define WMI_NLO_CONFIG_ENLO_RESET BIT(9) +#define WMI_NLO_CONFIG_SPOOFED_MAC_IN_PROBE_REQ BIT(10) +#define WMI_NLO_CONFIG_RANDOM_SEQ_NO_IN_PROBE_REQ BIT(11) +#define WMI_NLO_CONFIG_ENABLE_IE_WHITELIST_IN_PROBE_REQ BIT(12) +#define WMI_NLO_CONFIG_ENABLE_CNLO_RSSI_CONFIG BIT(13) + +struct wmi_nlo_ssid_param { + u32 valid; + struct wmi_ssid ssid; +} __packed; + +struct wmi_nlo_enc_param { + u32 valid; + u32 enc_type; +} __packed; + +struct wmi_nlo_auth_param { + u32 valid; + u32 auth_type; +} __packed; + +struct wmi_nlo_bcast_nw_param { + u32 valid; + u32 bcast_nw_type; +} __packed; + +struct wmi_nlo_rssi_param { + u32 valid; + s32 rssi; +} __packed; + +struct nlo_configured_parameters { + /* TLV tag and len;*/ + u32 tlv_header; + struct wmi_nlo_ssid_param ssid; + struct wmi_nlo_enc_param enc_type; + struct wmi_nlo_auth_param auth_type; + struct wmi_nlo_rssi_param rssi_cond; + + /* indicates if the SSID is hidden or not */ + struct wmi_nlo_bcast_nw_param bcast_nw_type; +} __packed; + +struct wmi_network_type { + struct wmi_ssid ssid; + u32 authentication; + u32 encryption; + u32 bcast_nw_type; + u8 channel_count; + u16 channels[WMI_PNO_MAX_NETW_CHANNELS_EX]; + s32 rssi_threshold; +}; + +struct wmi_pno_scan_req { + u8 enable; + u8 vdev_id; + u8 uc_networks_count; + struct wmi_network_type a_networks[WMI_PNO_MAX_SUPP_NETWORKS]; + u32 fast_scan_period; + u32 slow_scan_period; + u8 fast_scan_max_cycles; + + bool do_passive_scan; + + u32 delay_start_time; + u32 active_min_time; + u32 active_max_time; + u32 passive_min_time; + u32 passive_max_time; + + /* mac address randomization attributes */ + u32 enable_pno_scan_randomization; + u8 mac_addr[ETH_ALEN]; + u8 mac_addr_mask[ETH_ALEN]; +}; + +struct wmi_wow_nlo_config_cmd { + u32 tlv_header; + u32 flags; + u32 vdev_id; + u32 fast_scan_max_cycles; + u32 active_dwell_time; + u32 passive_dwell_time; + u32 probe_bundle_size; + + /* ART = IRT */ + u32 rest_time; + + /* Max value that can be reached after SBM */ + u32 max_rest_time; + + /* SBM */ + u32 scan_backoff_multiplier; + + /* SCBM */ + u32 fast_scan_period; + + /* specific to windows */ + u32 slow_scan_period; + + u32 no_of_ssids; + + u32 num_of_channels; + + /* NLO scan start delay time in milliseconds */ + u32 delay_start_time; + + /* MAC Address to use in Probe Req as SA */ + struct wmi_mac_addr mac_addr; + + /* Mask on which MAC has to be randomized */ + struct wmi_mac_addr mac_mask; + + /* IE bitmap to use in Probe Req */ + u32 ie_bitmap[8]; + + /* Number of vendor OUIs. In the TLV vendor_oui[] */ + u32 num_vendor_oui; + + /* Number of connected NLO band preferences */ + u32 num_cnlo_band_pref; + + /* The TLVs will follow. + * nlo_configured_parameters nlo_list[]; + * u32 channel_list[num_of_channels]; + */ +} __packed; + int ath11k_wmi_cmd_send(struct ath11k_pdev_wmi *wmi, struct sk_buff *skb, u32 cmd_id); struct sk_buff *ath11k_wmi_alloc_skb(struct ath11k_wmi_base *wmi_sc, u32 len); @@ -5777,6 +5944,8 @@ int ath11k_wmi_scan_prob_req_oui(struct ath11k *ar, const u8 mac_addr[ETH_ALEN]); int ath11k_wmi_fw_dbglog_cfg(struct ath11k *ar, u32 *module_id_bitmap, struct ath11k_fw_dbglog *dbglog); +int ath11k_wmi_wow_config_pno(struct ath11k *ar, u32 vdev_id, + struct wmi_pno_scan_req *pno_scan); int ath11k_wmi_wow_del_pattern(struct ath11k *ar, u32 vdev_id, u32 pattern_id); int ath11k_wmi_wow_add_pattern(struct ath11k *ar, u32 vdev_id, u32 pattern_id, const u8 *pattern, const u8 *mask, diff --git a/drivers/net/wireless/ath/ath11k/wow.c b/drivers/net/wireless/ath/ath11k/wow.c index 837dab469ab29..5f3aa0b7eb9bd 100644 --- a/drivers/net/wireless/ath/ath11k/wow.c +++ b/drivers/net/wireless/ath/ath11k/wow.c @@ -228,6 +228,101 @@ static void ath11k_wow_convert_8023_to_80211(struct cfg80211_pkt_pattern *new, } } +static int ath11k_wmi_pno_check_and_convert(struct ath11k *ar, u32 vdev_id, + struct cfg80211_sched_scan_request *nd_config, + struct wmi_pno_scan_req *pno) +{ + int i, j; + u8 ssid_len; + + pno->enable = 1; + pno->vdev_id = vdev_id; + pno->uc_networks_count = nd_config->n_match_sets; + + if (!pno->uc_networks_count || + pno->uc_networks_count > WMI_PNO_MAX_SUPP_NETWORKS) + return -EINVAL; + + if (nd_config->n_channels > WMI_PNO_MAX_NETW_CHANNELS_EX) + return -EINVAL; + + /* Filling per profile params */ + for (i = 0; i < pno->uc_networks_count; i++) { + ssid_len = nd_config->match_sets[i].ssid.ssid_len; + + if (ssid_len == 0 || ssid_len > 32) + return -EINVAL; + + pno->a_networks[i].ssid.ssid_len = ssid_len; + + memcpy(pno->a_networks[i].ssid.ssid, + nd_config->match_sets[i].ssid.ssid, + nd_config->match_sets[i].ssid.ssid_len); + pno->a_networks[i].authentication = 0; + pno->a_networks[i].encryption = 0; + pno->a_networks[i].bcast_nw_type = 0; + + /* Copying list of valid channel into request */ + pno->a_networks[i].channel_count = nd_config->n_channels; + pno->a_networks[i].rssi_threshold = nd_config->match_sets[i].rssi_thold; + + for (j = 0; j < nd_config->n_channels; j++) { + pno->a_networks[i].channels[j] = + nd_config->channels[j]->center_freq; + } + } + + /* set scan to passive if no SSIDs are specified in the request */ + if (nd_config->n_ssids == 0) + pno->do_passive_scan = true; + else + pno->do_passive_scan = false; + + for (i = 0; i < nd_config->n_ssids; i++) { + j = 0; + while (j < pno->uc_networks_count) { + if (pno->a_networks[j].ssid.ssid_len == + nd_config->ssids[i].ssid_len && + (memcmp(pno->a_networks[j].ssid.ssid, + nd_config->ssids[i].ssid, + pno->a_networks[j].ssid.ssid_len) == 0)) { + pno->a_networks[j].bcast_nw_type = BCAST_HIDDEN; + break; + } + j++; + } + } + + if (nd_config->n_scan_plans == 2) { + pno->fast_scan_period = nd_config->scan_plans[0].interval * MSEC_PER_SEC; + pno->fast_scan_max_cycles = nd_config->scan_plans[0].iterations; + pno->slow_scan_period = + nd_config->scan_plans[1].interval * MSEC_PER_SEC; + } else if (nd_config->n_scan_plans == 1) { + pno->fast_scan_period = nd_config->scan_plans[0].interval * MSEC_PER_SEC; + pno->fast_scan_max_cycles = 1; + pno->slow_scan_period = nd_config->scan_plans[0].interval * MSEC_PER_SEC; + } else { + ath11k_warn(ar->ab, "Invalid number of scan plans %d !!", + nd_config->n_scan_plans); + } + + if (nd_config->flags & NL80211_SCAN_FLAG_RANDOM_ADDR) { + /* enable mac randomization */ + pno->enable_pno_scan_randomization = 1; + memcpy(pno->mac_addr, nd_config->mac_addr, ETH_ALEN); + memcpy(pno->mac_addr_mask, nd_config->mac_addr_mask, ETH_ALEN); + } + + pno->delay_start_time = nd_config->delay; + + /* Current FW does not support min-max range for dwell time */ + pno->active_max_time = WMI_ACTIVE_MAX_CHANNEL_TIME; + pno->passive_max_time = WMI_PASSIVE_MAX_CHANNEL_TIME; + + return 0; +} + static int ath11k_vif_wow_set_wakeups(struct ath11k_vif *arvif, struct cfg80211_wowlan *wowlan) { @@ -261,6 +356,26 @@ static int ath11k_vif_wow_set_wakeups(struct ath11k_vif *arvif, if (wowlan->magic_pkt) __set_bit(WOW_MAGIC_PKT_RECVD_EVENT, &wow_mask); + + if (wowlan->nd_config) { + struct wmi_pno_scan_req *pno; + int ret; + + pno = kzalloc(sizeof(*pno), GFP_KERNEL); + if (!pno) + return -ENOMEM; + + ar->nlo_enabled = true; + + ret = ath11k_wmi_pno_check_and_convert(ar, arvif->vdev_id, + wowlan->nd_config, pno); + if (!ret) { + ath11k_wmi_wow_config_pno(ar, arvif->vdev_id, pno); + __set_bit(WOW_NLO_DETECTED_EVENT, &wow_mask); + } + + kfree(pno); + } break; default: break; @@ -354,6 +469,51 @@ static int ath11k_wow_set_wakeups(struct ath11k *ar, return 0; } +static int ath11k_vif_wow_clean_nlo(struct ath11k_vif *arvif) +{ + int ret = 0; + struct ath11k *ar = arvif->ar; + + switch (arvif->vdev_type) { + case WMI_VDEV_TYPE_STA: + if (ar->nlo_enabled) { + struct wmi_pno_scan_req *pno; + + pno = kzalloc(sizeof(*pno), GFP_KERNEL); + if (!pno) + return -ENOMEM; + + pno->enable = 0; + ar->nlo_enabled = false; + ret = ath11k_wmi_wow_config_pno(ar, arvif->vdev_id, pno); + kfree(pno); + } + break; + default: + break; + } + return ret; +} + +static int ath11k_wow_nlo_cleanup(struct ath11k *ar) +{ + struct ath11k_vif *arvif; + int ret; + + lockdep_assert_held(&ar->conf_mutex); + + list_for_each_entry(arvif, &ar->arvifs, list) { + ret = ath11k_vif_wow_clean_nlo(arvif); + if (ret) { + ath11k_warn(ar->ab, "failed to clean nlo settings on vdev %i: %d\n", + arvif->vdev_id, ret); + return ret; + } + } + + return 0; +} + int ath11k_wow_op_suspend(struct ieee80211_hw *hw, struct cfg80211_wowlan *wowlan) { @@ -439,8 +599,16 @@ int ath11k_wow_op_resume(struct ieee80211_hw *hw) ath11k_hif_irq_enable(ar->ab); ret = ath11k_wow_wakeup(ar->ab); - if (ret) + if (ret) { ath11k_warn(ar->ab, "failed to wakeup from wow: %d\n", ret); + goto exit; + } + + ret = ath11k_wow_nlo_cleanup(ar); + if (ret) { + ath11k_warn(ar->ab, "failed to cleanup nlo: %d\n", ret); + goto exit; + } exit: if (ret) { @@ -477,6 +645,11 @@ int ath11k_wow_init(struct ath11k *ar) ar->wow.wowlan_support.max_pkt_offset -= WOW_MAX_REDUCE; } + if (test_bit(WMI_TLV_SERVICE_NLO, ar->wmi->wmi_ab->svc_map)) { + ar->wow.wowlan_support.flags |= WIPHY_WOWLAN_NET_DETECT; + ar->wow.wowlan_support.max_nd_match_sets = WMI_PNO_MAX_SUPP_NETWORKS; + } + ar->wow.max_num_patterns = ATH11K_WOW_PATTERNS; ar->wow.wowlan_support.n_patterns = ar->wow.max_num_patterns; ar->hw->wiphy->wowlan = &ar->wow.wowlan_support; From c417b247ba042161ddfb34f26a42ec67edc5c378 Mon Sep 17 00:00:00 2001 From: Carl Huang Date: Mon, 14 Mar 2022 07:18:16 +0200 Subject: [PATCH 003/228] ath11k: implement hardware data filter Host needs to set hardware data filter before entering WoW to let firmware drop needless broadcast/mulitcast frames to avoid frequent wakeup. Host clears hardware data filter when leaving WoW. Tested-on: QCA6390 hw2.0 PCI WLAN.HST.1.0.1-01740-QCAHSTSWPLZ_V2_TO_X86-1 Signed-off-by: Carl Huang Signed-off-by: Kalle Valo Link: https://lore.kernel.org/r/1644308006-22784-4-git-send-email-quic_cjhuang@quicinc.com --- drivers/net/wireless/ath/ath11k/wmi.c | 33 ++++++++++++++++ drivers/net/wireless/ath/ath11k/wmi.h | 15 +++++++ drivers/net/wireless/ath/ath11k/wow.c | 57 +++++++++++++++++++++++++++ 3 files changed, 105 insertions(+) diff --git a/drivers/net/wireless/ath/ath11k/wmi.c b/drivers/net/wireless/ath/ath11k/wmi.c index d4d34b932e0bb..62b13f5cb8b45 100644 --- a/drivers/net/wireless/ath/ath11k/wmi.c +++ b/drivers/net/wireless/ath/ath11k/wmi.c @@ -8165,6 +8165,39 @@ void ath11k_wmi_detach(struct ath11k_base *ab) ath11k_wmi_free_dbring_caps(ab); } +int ath11k_wmi_hw_data_filter_cmd(struct ath11k *ar, u32 vdev_id, + u32 filter_bitmap, bool enable) +{ + struct wmi_hw_data_filter_cmd *cmd; + struct sk_buff *skb; + int len; + + len = sizeof(*cmd); + skb = ath11k_wmi_alloc_skb(ar->wmi->wmi_ab, len); + + if (!skb) + return -ENOMEM; + + cmd = (struct wmi_hw_data_filter_cmd *)skb->data; + cmd->tlv_header = FIELD_PREP(WMI_TLV_TAG, WMI_TAG_HW_DATA_FILTER_CMD) | + FIELD_PREP(WMI_TLV_LEN, sizeof(*cmd) - TLV_HDR_SIZE); + + cmd->vdev_id = vdev_id; + cmd->enable = enable; + + /* Set all modes in case of disable */ + if (cmd->enable) + cmd->hw_filter_bitmap = filter_bitmap; + else + cmd->hw_filter_bitmap = ((u32)~0U); + + ath11k_dbg(ar->ab, ATH11K_DBG_WMI, + "wmi hw data filter enable %d filter_bitmap 0x%x\n", + enable, filter_bitmap); + + return ath11k_wmi_cmd_send(ar->wmi, skb, WMI_HW_DATA_FILTER_CMDID); +} + int ath11k_wmi_wow_host_wakeup_ind(struct ath11k *ar) { struct wmi_wow_host_wakeup_ind *cmd; diff --git a/drivers/net/wireless/ath/ath11k/wmi.h b/drivers/net/wireless/ath/ath11k/wmi.h index 9150e0555c6d9..17e50987e115c 100644 --- a/drivers/net/wireless/ath/ath11k/wmi.h +++ b/drivers/net/wireless/ath/ath11k/wmi.h @@ -5390,6 +5390,19 @@ struct ath11k_wmi_base { struct ath11k_targ_cap *targ_cap; }; +/* Definition of HW data filtering */ +enum hw_data_filter_type { + WMI_HW_DATA_FILTER_DROP_NON_ARP_BC = BIT(0), + WMI_HW_DATA_FILTER_DROP_NON_ICMPV6_MC = BIT(1), +}; + +struct wmi_hw_data_filter_cmd { + u32 tlv_header; + u32 vdev_id; + u32 enable; + u32 hw_filter_bitmap; +} __packed; + /* WOW structures */ enum wmi_wow_wakeup_event { WOW_BMISS_EVENT = 0, @@ -5953,4 +5966,6 @@ int ath11k_wmi_wow_add_pattern(struct ath11k *ar, u32 vdev_id, u32 pattern_id, int ath11k_wmi_wow_add_wakeup_event(struct ath11k *ar, u32 vdev_id, enum wmi_wow_wakeup_event event, u32 enable); +int ath11k_wmi_hw_data_filter_cmd(struct ath11k *ar, u32 vdev_id, + u32 filter_bitmap, bool enable); #endif diff --git a/drivers/net/wireless/ath/ath11k/wow.c b/drivers/net/wireless/ath/ath11k/wow.c index 5f3aa0b7eb9bd..50dd50944eddf 100644 --- a/drivers/net/wireless/ath/ath11k/wow.c +++ b/drivers/net/wireless/ath/ath11k/wow.c @@ -514,6 +514,50 @@ static int ath11k_wow_nlo_cleanup(struct ath11k *ar) return 0; } +static int ath11k_wow_set_hw_filter(struct ath11k *ar) +{ + struct ath11k_vif *arvif; + u32 bitmap; + int ret; + + lockdep_assert_held(&ar->conf_mutex); + + list_for_each_entry(arvif, &ar->arvifs, list) { + bitmap = WMI_HW_DATA_FILTER_DROP_NON_ICMPV6_MC | + WMI_HW_DATA_FILTER_DROP_NON_ARP_BC; + ret = ath11k_wmi_hw_data_filter_cmd(ar, arvif->vdev_id, + bitmap, + true); + if (ret) { + ath11k_warn(ar->ab, "failed to set hw data filter on vdev %i: %d\n", + arvif->vdev_id, ret); + return ret; + } + } + + return 0; +} + +static int ath11k_wow_clear_hw_filter(struct ath11k *ar) +{ + struct ath11k_vif *arvif; + int ret; + + lockdep_assert_held(&ar->conf_mutex); + + list_for_each_entry(arvif, &ar->arvifs, list) { + ret = ath11k_wmi_hw_data_filter_cmd(ar, arvif->vdev_id, 0, false); + + if (ret) { + ath11k_warn(ar->ab, "failed to clear hw data filter on vdev %i: %d\n", + arvif->vdev_id, ret); + return ret; + } + } + + return 0; +} + int ath11k_wow_op_suspend(struct ieee80211_hw *hw, struct cfg80211_wowlan *wowlan) { @@ -542,6 +586,13 @@ int ath11k_wow_op_suspend(struct ieee80211_hw *hw, goto cleanup; } + ret = ath11k_wow_set_hw_filter(ar); + if (ret) { + ath11k_warn(ar->ab, "failed to set hw filter: %d\n", + ret); + goto cleanup; + } + ret = ath11k_wow_enable(ar->ab); if (ret) { ath11k_warn(ar->ab, "failed to start wow: %d\n", ret); @@ -610,6 +661,12 @@ int ath11k_wow_op_resume(struct ieee80211_hw *hw) goto exit; } + ret = ath11k_wow_clear_hw_filter(ar); + if (ret) { + ath11k_warn(ar->ab, "failed to clear hw filter: %d\n", ret); + goto exit; + } + exit: if (ret) { switch (ar->state) { From 90bf5c8d0f7ecddf96fc1cd9434af4e157b51970 Mon Sep 17 00:00:00 2001 From: Carl Huang Date: Mon, 14 Mar 2022 07:18:16 +0200 Subject: [PATCH 004/228] ath11k: purge rx pktlog when entering WoW This change is to purge rx pktlog when entering WoW and reap the mon_status buffer to keep it empty. When leaving WoW, host restarts the reap timer. In WoW state, it's not allowed to feed into mon_status rings per firmware team's recommendation. Tested-on: QCA6390 hw2.0 PCI WLAN.HST.1.0.1-01740-QCAHSTSWPLZ_V2_TO_X86-1 Signed-off-by: Carl Huang Signed-off-by: Kalle Valo Link: https://lore.kernel.org/r/1644308006-22784-5-git-send-email-quic_cjhuang@quicinc.com --- drivers/net/wireless/ath/ath11k/wow.c | 23 +++++++++++++++++++++++ 1 file changed, 23 insertions(+) diff --git a/drivers/net/wireless/ath/ath11k/wow.c b/drivers/net/wireless/ath/ath11k/wow.c index 50dd50944eddf..602b8f4c59851 100644 --- a/drivers/net/wireless/ath/ath11k/wow.c +++ b/drivers/net/wireless/ath/ath11k/wow.c @@ -13,6 +13,7 @@ #include "debug.h" #include "wmi.h" #include "wow.h" +#include "dp_rx.h" static const struct wiphy_wowlan_support ath11k_wowlan_support = { .flags = WIPHY_WOWLAN_DISCONNECT | @@ -566,6 +567,14 @@ int ath11k_wow_op_suspend(struct ieee80211_hw *hw, mutex_lock(&ar->conf_mutex); + ret = ath11k_dp_rx_pktlog_stop(ar->ab, true); + if (ret) { + ath11k_warn(ar->ab, + "failed to stop dp rx (and timer) pktlog during wow suspend: %d\n", + ret); + goto exit; + } + ret = ath11k_wow_cleanup(ar); if (ret) { ath11k_warn(ar->ab, "failed to clear wow wakeup events: %d\n", @@ -599,6 +608,14 @@ int ath11k_wow_op_suspend(struct ieee80211_hw *hw, goto cleanup; } + ret = ath11k_dp_rx_pktlog_stop(ar->ab, false); + if (ret) { + ath11k_warn(ar->ab, + "failed to stop dp rx pktlog during wow suspend: %d\n", + ret); + goto cleanup; + } + ath11k_ce_stop_shadow_timers(ar->ab); ath11k_dp_stop_shadow_timers(ar->ab); @@ -649,6 +666,12 @@ int ath11k_wow_op_resume(struct ieee80211_hw *hw) ath11k_hif_ce_irq_enable(ar->ab); ath11k_hif_irq_enable(ar->ab); + ret = ath11k_dp_rx_pktlog_start(ar->ab); + if (ret) { + ath11k_warn(ar->ab, "failed to start rx pktlog from wow: %d\n", ret); + return ret; + } + ret = ath11k_wow_wakeup(ar->ab); if (ret) { ath11k_warn(ar->ab, "failed to wakeup from wow: %d\n", ret); From c3c36bfe998b3ad14aa87a57037a05d861889ac8 Mon Sep 17 00:00:00 2001 From: Carl Huang Date: Mon, 14 Mar 2022 07:18:16 +0200 Subject: [PATCH 005/228] ath11k: support ARP and NS offload Support ARP and NS offload in WoW state. Tested this way: put machine A with QCA6390 to WoW state, ping/ping6 machine A from another machine B, check sniffer to see any ARP response and Neighbour advertisement from machine A. Tested-on: QCA6390 hw2.0 PCI WLAN.HST.1.0.1-01740-QCAHSTSWPLZ_V2_TO_X86-1 Signed-off-by: Carl Huang Signed-off-by: Baochen Qiang Signed-off-by: Kalle Valo Link: https://lore.kernel.org/r/1644308006-22784-6-git-send-email-quic_cjhuang@quicinc.com --- drivers/net/wireless/ath/ath11k/core.h | 19 +++ drivers/net/wireless/ath/ath11k/mac.c | 118 +++++++++++++++++++ drivers/net/wireless/ath/ath11k/wmi.c | 155 +++++++++++++++++++++++++ drivers/net/wireless/ath/ath11k/wmi.h | 47 ++++++++ drivers/net/wireless/ath/ath11k/wow.c | 52 +++++++++ 5 files changed, 391 insertions(+) diff --git a/drivers/net/wireless/ath/ath11k/core.h b/drivers/net/wireless/ath/ath11k/core.h index 1f5e977aa9769..4ba12de444155 100644 --- a/drivers/net/wireless/ath/ath11k/core.h +++ b/drivers/net/wireless/ath/ath11k/core.h @@ -213,6 +213,23 @@ enum ath11k_monitor_flags { ATH11K_FLAG_MONITOR_VDEV_CREATED, }; +#define ATH11K_IPV6_UC_TYPE 0 +#define ATH11K_IPV6_AC_TYPE 1 + +#define ATH11K_IPV6_MAX_COUNT 16 +#define ATH11K_IPV4_MAX_COUNT 2 + +struct ath11k_arp_ns_offload { + u8 ipv4_addr[ATH11K_IPV4_MAX_COUNT][4]; + u32 ipv4_count; + u32 ipv6_count; + u8 ipv6_addr[ATH11K_IPV6_MAX_COUNT][16]; + u8 self_ipv6_addr[ATH11K_IPV6_MAX_COUNT][16]; + u8 ipv6_type[ATH11K_IPV6_MAX_COUNT]; + bool ipv6_valid[ATH11K_IPV6_MAX_COUNT]; + u8 mac_addr[ETH_ALEN]; +}; + struct ath11k_vif { u32 vdev_id; enum wmi_vdev_type vdev_type; @@ -264,6 +281,8 @@ struct ath11k_vif { bool bcca_zero_sent; bool do_not_send_tmpl; struct ieee80211_chanctx_conf chanctx; + struct ath11k_arp_ns_offload arp_ns_offload; + #ifdef CONFIG_ATH11K_DEBUGFS struct dentry *debugfs_twt; #endif /* CONFIG_ATH11K_DEBUGFS */ diff --git a/drivers/net/wireless/ath/ath11k/mac.c b/drivers/net/wireless/ath/ath11k/mac.c index 7a6c758b8e459..dee1cb4121f88 100644 --- a/drivers/net/wireless/ath/ath11k/mac.c +++ b/drivers/net/wireless/ath/ath11k/mac.c @@ -6,6 +6,11 @@ #include #include +#include +#include +#include +#include + #include "mac.h" #include "core.h" #include "debug.h" @@ -3095,6 +3100,7 @@ static void ath11k_mac_op_bss_info_changed(struct ieee80211_hw *hw, int ret = 0; u8 rateidx; u32 rate; + u32 ipv4_cnt; mutex_lock(&ar->conf_mutex); @@ -3387,6 +3393,18 @@ static void ath11k_mac_op_bss_info_changed(struct ieee80211_hw *hw, changed & BSS_CHANGED_UNSOL_BCAST_PROBE_RESP) ath11k_mac_fils_discovery(arvif, info); + if (changed & BSS_CHANGED_ARP_FILTER) { + ipv4_cnt = min(info->arp_addr_cnt, ATH11K_IPV4_MAX_COUNT); + memcpy(arvif->arp_ns_offload.ipv4_addr, info->arp_addr_list, + ipv4_cnt * sizeof(u32)); + memcpy(arvif->arp_ns_offload.mac_addr, vif->addr, ETH_ALEN); + arvif->arp_ns_offload.ipv4_count = ipv4_cnt; + + ath11k_dbg(ar->ab, ATH11K_DBG_MAC, "mac arp_addr_cnt %d vif->addr %pM, offload_addr %pI4\n", + info->arp_addr_cnt, + vif->addr, arvif->arp_ns_offload.ipv4_addr); + } + mutex_unlock(&ar->conf_mutex); } @@ -8087,6 +8105,101 @@ static void ath11k_mac_op_sta_statistics(struct ieee80211_hw *hw, } } +static void ath11k_generate_ns_mc_addr(struct ath11k *ar, + struct ath11k_arp_ns_offload *offload) +{ + int i; + + for (i = 0; i < offload->ipv6_count; i++) { + offload->self_ipv6_addr[i][0] = 0xff; + offload->self_ipv6_addr[i][1] = 0x02; + offload->self_ipv6_addr[i][11] = 0x01; + offload->self_ipv6_addr[i][12] = 0xff; + offload->self_ipv6_addr[i][13] = + offload->ipv6_addr[i][13]; + offload->self_ipv6_addr[i][14] = + offload->ipv6_addr[i][14]; + offload->self_ipv6_addr[i][15] = + offload->ipv6_addr[i][15]; + ath11k_dbg(ar->ab, ATH11K_DBG_MAC, "NS solicited addr %pI6\n", + offload->self_ipv6_addr[i]); + } +} + +static void ath11k_mac_op_ipv6_changed(struct ieee80211_hw *hw, + struct ieee80211_vif *vif, + struct inet6_dev *idev) +{ + struct ath11k *ar = hw->priv; + struct ath11k_arp_ns_offload *offload; + struct ath11k_vif *arvif = ath11k_vif_to_arvif(vif); + struct inet6_ifaddr *ifa6; + struct ifacaddr6 *ifaca6; + struct list_head *p; + u32 count, scope; + + ath11k_dbg(ar->ab, ATH11K_DBG_MAC, "mac op ipv6 changed\n"); + + offload = &arvif->arp_ns_offload; + count = 0; + + read_lock_bh(&idev->lock); + + memset(offload->ipv6_addr, 0, sizeof(offload->ipv6_addr)); + memset(offload->self_ipv6_addr, 0, sizeof(offload->self_ipv6_addr)); + memcpy(offload->mac_addr, vif->addr, ETH_ALEN); + + /* get unicast address */ + list_for_each(p, &idev->addr_list) { + if (count >= ATH11K_IPV6_MAX_COUNT) + goto generate; + + ifa6 = list_entry(p, struct inet6_ifaddr, if_list); + if (ifa6->flags & IFA_F_DADFAILED) + continue; + scope = ipv6_addr_src_scope(&ifa6->addr); + if (scope == IPV6_ADDR_SCOPE_LINKLOCAL || + scope == IPV6_ADDR_SCOPE_GLOBAL) { + memcpy(offload->ipv6_addr[count], &ifa6->addr.s6_addr, + sizeof(ifa6->addr.s6_addr)); + offload->ipv6_type[count] = ATH11K_IPV6_UC_TYPE; + ath11k_dbg(ar->ab, ATH11K_DBG_MAC, "mac count %d ipv6 uc %pI6 scope %d\n", + count, offload->ipv6_addr[count], + scope); + count++; + } else { + ath11k_warn(ar->ab, "Unsupported ipv6 scope: %d\n", scope); + } + } + + /* get anycast address */ + for (ifaca6 = idev->ac_list; ifaca6; ifaca6 = ifaca6->aca_next) { + if (count >= ATH11K_IPV6_MAX_COUNT) + goto generate; + + scope = ipv6_addr_src_scope(&ifaca6->aca_addr); + if (scope == IPV6_ADDR_SCOPE_LINKLOCAL || + scope == IPV6_ADDR_SCOPE_GLOBAL) { + memcpy(offload->ipv6_addr[count], &ifaca6->aca_addr, + sizeof(ifaca6->aca_addr)); + offload->ipv6_type[count] = ATH11K_IPV6_AC_TYPE; + ath11k_dbg(ar->ab, ATH11K_DBG_MAC, "mac count %d ipv6 ac %pI6 scope %d\n", + count, offload->ipv6_addr[count], + scope); + count++; + } else { + ath11k_warn(ar->ab, "Unsupported ipv scope: %d\n", scope); + } + } + +generate: + offload->ipv6_count = count; + read_unlock_bh(&idev->lock); + + /* generate ns multicast address */ + ath11k_generate_ns_mc_addr(ar, offload); +} + static const struct ieee80211_ops ath11k_ops = { .tx = ath11k_mac_op_tx, .start = ath11k_mac_op_start, @@ -8132,6 +8245,11 @@ static const struct ieee80211_ops ath11k_ops = { #ifdef CONFIG_ATH11K_DEBUGFS .sta_add_debugfs = ath11k_debugfs_sta_op_add, #endif + +#if IS_ENABLED(CONFIG_IPV6) + .ipv6_addr_change = ath11k_mac_op_ipv6_changed, +#endif + }; static void ath11k_mac_update_ch_list(struct ath11k *ar, diff --git a/drivers/net/wireless/ath/ath11k/wmi.c b/drivers/net/wireless/ath/ath11k/wmi.c index 62b13f5cb8b45..828f9cacbe570 100644 --- a/drivers/net/wireless/ath/ath11k/wmi.c +++ b/drivers/net/wireless/ath/ath11k/wmi.c @@ -8580,3 +8580,158 @@ int ath11k_wmi_wow_config_pno(struct ath11k *ar, u32 vdev_id, return ath11k_wmi_cmd_send(ar->wmi, skb, WMI_NETWORK_LIST_OFFLOAD_CONFIG_CMDID); } +static void ath11k_wmi_fill_ns_offload(struct ath11k *ar, + struct ath11k_arp_ns_offload *offload, + u8 **ptr, + bool enable, + bool ext) +{ + struct wmi_ns_offload_tuple *ns; + struct wmi_tlv *tlv; + u8 *buf_ptr = *ptr; + u32 ns_cnt, ns_ext_tuples; + int i, max_offloads; + + ns_cnt = offload->ipv6_count; + + tlv = (struct wmi_tlv *)buf_ptr; + + if (ext) { + ns_ext_tuples = offload->ipv6_count - WMI_MAX_NS_OFFLOADS; + tlv->header = FIELD_PREP(WMI_TLV_TAG, WMI_TAG_ARRAY_STRUCT) | + FIELD_PREP(WMI_TLV_LEN, ns_ext_tuples * sizeof(*ns)); + i = WMI_MAX_NS_OFFLOADS; + max_offloads = offload->ipv6_count; + } else { + tlv->header = FIELD_PREP(WMI_TLV_TAG, WMI_TAG_ARRAY_STRUCT) | + FIELD_PREP(WMI_TLV_LEN, WMI_MAX_NS_OFFLOADS * sizeof(*ns)); + i = 0; + max_offloads = WMI_MAX_NS_OFFLOADS; + } + + buf_ptr += sizeof(*tlv); + + for (; i < max_offloads; i++) { + ns = (struct wmi_ns_offload_tuple *)buf_ptr; + ns->tlv_header = FIELD_PREP(WMI_TLV_TAG, WMI_TAG_NS_OFFLOAD_TUPLE) | + FIELD_PREP(WMI_TLV_LEN, sizeof(*ns) - TLV_HDR_SIZE); + + if (enable) { + if (i < ns_cnt) + ns->flags |= WMI_NSOL_FLAGS_VALID; + + memcpy(ns->target_ipaddr[0], offload->ipv6_addr[i], 16); + memcpy(ns->solicitation_ipaddr, offload->self_ipv6_addr[i], 16); + ath11k_ce_byte_swap(ns->target_ipaddr[0], 16); + ath11k_ce_byte_swap(ns->solicitation_ipaddr, 16); + + if (offload->ipv6_type[i]) + ns->flags |= WMI_NSOL_FLAGS_IS_IPV6_ANYCAST; + + memcpy(ns->target_mac.addr, offload->mac_addr, ETH_ALEN); + ath11k_ce_byte_swap(ns->target_mac.addr, 8); + + if (ns->target_mac.word0 != 0 || + ns->target_mac.word1 != 0) { + ns->flags |= WMI_NSOL_FLAGS_MAC_VALID; + } + + ath11k_dbg(ar->ab, ATH11K_DBG_WMI, + "wmi index %d ns_solicited %pI6 target %pI6", + i, ns->solicitation_ipaddr, + ns->target_ipaddr[0]); + } + + buf_ptr += sizeof(*ns); + } + + *ptr = buf_ptr; +} + +static void ath11k_wmi_fill_arp_offload(struct ath11k *ar, + struct ath11k_arp_ns_offload *offload, + u8 **ptr, + bool enable) +{ + struct wmi_arp_offload_tuple *arp; + struct wmi_tlv *tlv; + u8 *buf_ptr = *ptr; + int i; + + /* fill arp tuple */ + tlv = (struct wmi_tlv *)buf_ptr; + tlv->header = FIELD_PREP(WMI_TLV_TAG, WMI_TAG_ARRAY_STRUCT) | + FIELD_PREP(WMI_TLV_LEN, WMI_MAX_ARP_OFFLOADS * sizeof(*arp)); + buf_ptr += sizeof(*tlv); + + for (i = 0; i < WMI_MAX_ARP_OFFLOADS; i++) { + arp = (struct wmi_arp_offload_tuple *)buf_ptr; + arp->tlv_header = FIELD_PREP(WMI_TLV_TAG, WMI_TAG_ARP_OFFLOAD_TUPLE) | + FIELD_PREP(WMI_TLV_LEN, sizeof(*arp) - TLV_HDR_SIZE); + + if (enable && i < offload->ipv4_count) { + /* Copy the target ip addr and flags */ + arp->flags = WMI_ARPOL_FLAGS_VALID; + memcpy(arp->target_ipaddr, offload->ipv4_addr[i], 4); + ath11k_ce_byte_swap(arp->target_ipaddr, 4); + + ath11k_dbg(ar->ab, ATH11K_DBG_WMI, "wmi arp offload address %pI4", + arp->target_ipaddr); + } + + buf_ptr += sizeof(*arp); + } + + *ptr = buf_ptr; +} + +int ath11k_wmi_arp_ns_offload(struct ath11k *ar, + struct ath11k_vif *arvif, bool enable) +{ + struct ath11k_arp_ns_offload *offload; + struct wmi_set_arp_ns_offload_cmd *cmd; + struct wmi_tlv *tlv; + struct sk_buff *skb; + u8 *buf_ptr; + size_t len; + u8 ns_cnt, ns_ext_tuples = 0; + + offload = &arvif->arp_ns_offload; + ns_cnt = offload->ipv6_count; + + len = sizeof(*cmd) + + sizeof(*tlv) + + WMI_MAX_NS_OFFLOADS * sizeof(struct wmi_ns_offload_tuple) + + sizeof(*tlv) + + WMI_MAX_ARP_OFFLOADS * sizeof(struct wmi_arp_offload_tuple); + + if (ns_cnt > WMI_MAX_NS_OFFLOADS) { + ns_ext_tuples = ns_cnt - WMI_MAX_NS_OFFLOADS; + len += sizeof(*tlv) + + ns_ext_tuples * sizeof(struct wmi_ns_offload_tuple); + } + + skb = ath11k_wmi_alloc_skb(ar->wmi->wmi_ab, len); + if (!skb) + return -ENOMEM; + + buf_ptr = skb->data; + cmd = (struct wmi_set_arp_ns_offload_cmd *)buf_ptr; + cmd->tlv_header = FIELD_PREP(WMI_TLV_TAG, + WMI_TAG_SET_ARP_NS_OFFLOAD_CMD) | + FIELD_PREP(WMI_TLV_LEN, sizeof(*cmd) - TLV_HDR_SIZE); + + cmd->flags = 0; + cmd->vdev_id = arvif->vdev_id; + cmd->num_ns_ext_tuples = ns_ext_tuples; + + buf_ptr += sizeof(*cmd); + + ath11k_wmi_fill_ns_offload(ar, offload, &buf_ptr, enable, 0); + ath11k_wmi_fill_arp_offload(ar, offload, &buf_ptr, enable); + + if (ns_ext_tuples) + ath11k_wmi_fill_ns_offload(ar, offload, &buf_ptr, enable, 1); + + return ath11k_wmi_cmd_send(ar->wmi, skb, WMI_SET_ARP_NS_OFFLOAD_CMDID); +} diff --git a/drivers/net/wireless/ath/ath11k/wmi.h b/drivers/net/wireless/ath/ath11k/wmi.h index 17e50987e115c..e2d03c3b422ce 100644 --- a/drivers/net/wireless/ath/ath11k/wmi.h +++ b/drivers/net/wireless/ath/ath11k/wmi.h @@ -13,6 +13,7 @@ struct ath11k_base; struct ath11k; struct ath11k_fw_stats; struct ath11k_fw_dbglog; +struct ath11k_vif; #define PSOC_HOST_MAX_NUM_SS (8) @@ -5796,6 +5797,49 @@ struct wmi_wow_nlo_config_cmd { */ } __packed; +#define WMI_MAX_NS_OFFLOADS 2 +#define WMI_MAX_ARP_OFFLOADS 2 + +#define WMI_ARPOL_FLAGS_VALID BIT(0) +#define WMI_ARPOL_FLAGS_MAC_VALID BIT(1) +#define WMI_ARPOL_FLAGS_REMOTE_IP_VALID BIT(2) + +struct wmi_arp_offload_tuple { + u32 tlv_header; + u32 flags; + u8 target_ipaddr[4]; + u8 remote_ipaddr[4]; + struct wmi_mac_addr target_mac; +} __packed; + +#define WMI_NSOL_FLAGS_VALID BIT(0) +#define WMI_NSOL_FLAGS_MAC_VALID BIT(1) +#define WMI_NSOL_FLAGS_REMOTE_IP_VALID BIT(2) +#define WMI_NSOL_FLAGS_IS_IPV6_ANYCAST BIT(3) + +#define WMI_NSOL_MAX_TARGET_IPS 2 + +struct wmi_ns_offload_tuple { + u32 tlv_header; + u32 flags; + u8 target_ipaddr[WMI_NSOL_MAX_TARGET_IPS][16]; + u8 solicitation_ipaddr[16]; + u8 remote_ipaddr[16]; + struct wmi_mac_addr target_mac; +} __packed; + +struct wmi_set_arp_ns_offload_cmd { + u32 tlv_header; + u32 flags; + u32 vdev_id; + u32 num_ns_ext_tuples; + /* The TLVs follow: + * wmi_ns_offload_tuple ns_tuples[WMI_MAX_NS_OFFLOADS]; + * wmi_arp_offload_tuple arp_tuples[WMI_MAX_ARP_OFFLOADS]; + * wmi_ns_offload_tuple ns_ext_tuples[num_ns_ext_tuples]; + */ +} __packed; + int ath11k_wmi_cmd_send(struct ath11k_pdev_wmi *wmi, struct sk_buff *skb, u32 cmd_id); struct sk_buff *ath11k_wmi_alloc_skb(struct ath11k_wmi_base *wmi_sc, u32 len); @@ -5968,4 +6012,7 @@ int ath11k_wmi_wow_add_wakeup_event(struct ath11k *ar, u32 vdev_id, u32 enable); int ath11k_wmi_hw_data_filter_cmd(struct ath11k *ar, u32 vdev_id, u32 filter_bitmap, bool enable); +int ath11k_wmi_arp_ns_offload(struct ath11k *ar, + struct ath11k_vif *arvif, bool enable); + #endif diff --git a/drivers/net/wireless/ath/ath11k/wow.c b/drivers/net/wireless/ath/ath11k/wow.c index 602b8f4c59851..bc6a4d3d6d7c9 100644 --- a/drivers/net/wireless/ath/ath11k/wow.c +++ b/drivers/net/wireless/ath/ath11k/wow.c @@ -559,6 +559,43 @@ static int ath11k_wow_clear_hw_filter(struct ath11k *ar) return 0; } +static int ath11k_wow_arp_ns_offload(struct ath11k *ar, bool enable) +{ + struct ath11k_vif *arvif; + int ret; + + lockdep_assert_held(&ar->conf_mutex); + + list_for_each_entry(arvif, &ar->arvifs, list) { + if (arvif->vdev_type != WMI_VDEV_TYPE_STA) + continue; + + ret = ath11k_wmi_arp_ns_offload(ar, arvif, enable); + + if (ret) { + ath11k_warn(ar->ab, "failed to set arp ns offload vdev %i: enable %d, ret %d\n", + arvif->vdev_id, enable, ret); + return ret; + } + } + + return 0; +} + +static int ath11k_wow_protocol_offload(struct ath11k *ar, bool enable) +{ + int ret; + + ret = ath11k_wow_arp_ns_offload(ar, enable); + if (ret) { + ath11k_warn(ar->ab, "failed to offload ARP and NS %d %d\n", + enable, ret); + return ret; + } + + return 0; +} + int ath11k_wow_op_suspend(struct ieee80211_hw *hw, struct cfg80211_wowlan *wowlan) { @@ -589,6 +626,14 @@ int ath11k_wow_op_suspend(struct ieee80211_hw *hw, goto cleanup; } + ret = ath11k_wow_protocol_offload(ar, true); + if (ret) { + ath11k_warn(ar->ab, "failed to set wow protocol offload events: %d\n", + ret); + goto cleanup; + } + + ath11k_mac_drain_tx(ar); ret = ath11k_mac_wait_tx_complete(ar); if (ret) { ath11k_warn(ar->ab, "failed to wait tx complete: %d\n", ret); @@ -690,6 +735,13 @@ int ath11k_wow_op_resume(struct ieee80211_hw *hw) goto exit; } + ret = ath11k_wow_protocol_offload(ar, false); + if (ret) { + ath11k_warn(ar->ab, "failed to clear wow protocol offload events: %d\n", + ret); + goto exit; + } + exit: if (ret) { switch (ar->state) { From a16d9b50cfbaf112401b8e5ccfa852709f498cd4 Mon Sep 17 00:00:00 2001 From: Carl Huang Date: Mon, 14 Mar 2022 07:18:16 +0200 Subject: [PATCH 006/228] ath11k: support GTK rekey offload Host sets GTK related info to firmware before WoW is enabled, and gets rekey replay_count and then disables GTK rekey when WoW quits. Tested-on: QCA6390 hw2.0 PCI WLAN.HST.1.0.1-01740-QCAHSTSWPLZ_V2_TO_X86-1 Signed-off-by: Carl Huang Signed-off-by: Kalle Valo Link: https://lore.kernel.org/r/1644308006-22784-7-git-send-email-quic_cjhuang@quicinc.com --- drivers/net/wireless/ath/ath11k/core.h | 8 ++ drivers/net/wireless/ath/ath11k/mac.c | 37 ++++++++ drivers/net/wireless/ath/ath11k/wmi.c | 119 +++++++++++++++++++++++++ drivers/net/wireless/ath/ath11k/wmi.h | 49 ++++++++++ drivers/net/wireless/ath/ath11k/wow.c | 46 +++++++++- 5 files changed, 258 insertions(+), 1 deletion(-) diff --git a/drivers/net/wireless/ath/ath11k/core.h b/drivers/net/wireless/ath/ath11k/core.h index 4ba12de444155..e556beb945ac8 100644 --- a/drivers/net/wireless/ath/ath11k/core.h +++ b/drivers/net/wireless/ath/ath11k/core.h @@ -230,6 +230,13 @@ struct ath11k_arp_ns_offload { u8 mac_addr[ETH_ALEN]; }; +struct ath11k_rekey_data { + u8 kck[NL80211_KCK_LEN]; + u8 kek[NL80211_KCK_LEN]; + u64 replay_ctr; + bool enable_offload; +}; + struct ath11k_vif { u32 vdev_id; enum wmi_vdev_type vdev_type; @@ -282,6 +289,7 @@ struct ath11k_vif { bool do_not_send_tmpl; struct ieee80211_chanctx_conf chanctx; struct ath11k_arp_ns_offload arp_ns_offload; + struct ath11k_rekey_data rekey_data; #ifdef CONFIG_ATH11K_DEBUGFS struct dentry *debugfs_twt; diff --git a/drivers/net/wireless/ath/ath11k/mac.c b/drivers/net/wireless/ath/ath11k/mac.c index dee1cb4121f88..e0e31605e0b0b 100644 --- a/drivers/net/wireless/ath/ath11k/mac.c +++ b/drivers/net/wireless/ath/ath11k/mac.c @@ -2757,6 +2757,7 @@ static void ath11k_bss_assoc(struct ieee80211_hw *hw, } arvif->is_up = true; + arvif->rekey_data.enable_offload = false; ath11k_dbg(ar->ab, ATH11K_DBG_MAC, "mac vdev %d up (associated) bssid %pM aid %d\n", @@ -2814,6 +2815,8 @@ static void ath11k_bss_disassoc(struct ieee80211_hw *hw, arvif->is_up = false; + memset(&arvif->rekey_data, 0, sizeof(arvif->rekey_data)); + cancel_delayed_work_sync(&arvif->connection_loss_work); } @@ -8200,6 +8203,39 @@ static void ath11k_mac_op_ipv6_changed(struct ieee80211_hw *hw, ath11k_generate_ns_mc_addr(ar, offload); } +static void ath11k_mac_op_set_rekey_data(struct ieee80211_hw *hw, + struct ieee80211_vif *vif, + struct cfg80211_gtk_rekey_data *data) +{ + struct ath11k *ar = hw->priv; + struct ath11k_vif *arvif = ath11k_vif_to_arvif(vif); + struct ath11k_rekey_data *rekey_data = &arvif->rekey_data; + + ath11k_dbg(ar->ab, ATH11K_DBG_MAC, "mac set rekey data vdev %d\n", + arvif->vdev_id); + + mutex_lock(&ar->conf_mutex); + + memcpy(rekey_data->kck, data->kck, NL80211_KCK_LEN); + memcpy(rekey_data->kek, data->kek, NL80211_KEK_LEN); + + /* The supplicant works on big-endian, the firmware expects it on + * little endian. + */ + rekey_data->replay_ctr = get_unaligned_be64(data->replay_ctr); + + arvif->rekey_data.enable_offload = true; + + ath11k_dbg_dump(ar->ab, ATH11K_DBG_MAC, "kck", NULL, + rekey_data->kck, NL80211_KCK_LEN); + ath11k_dbg_dump(ar->ab, ATH11K_DBG_MAC, "kek", NULL, + rekey_data->kck, NL80211_KEK_LEN); + ath11k_dbg_dump(ar->ab, ATH11K_DBG_MAC, "replay ctr", NULL, + &rekey_data->replay_ctr, sizeof(rekey_data->replay_ctr)); + + mutex_unlock(&ar->conf_mutex); +} + static const struct ieee80211_ops ath11k_ops = { .tx = ath11k_mac_op_tx, .start = ath11k_mac_op_start, @@ -8214,6 +8250,7 @@ static const struct ieee80211_ops ath11k_ops = { .hw_scan = ath11k_mac_op_hw_scan, .cancel_hw_scan = ath11k_mac_op_cancel_hw_scan, .set_key = ath11k_mac_op_set_key, + .set_rekey_data = ath11k_mac_op_set_rekey_data, .sta_state = ath11k_mac_op_sta_state, .sta_set_4addr = ath11k_mac_op_sta_set_4addr, .sta_set_txpwr = ath11k_mac_op_sta_set_txpwr, diff --git a/drivers/net/wireless/ath/ath11k/wmi.c b/drivers/net/wireless/ath/ath11k/wmi.c index 828f9cacbe570..7f97c26bffd9b 100644 --- a/drivers/net/wireless/ath/ath11k/wmi.c +++ b/drivers/net/wireless/ath/ath11k/wmi.c @@ -7765,6 +7765,56 @@ static void ath11k_wmi_twt_add_dialog_event(struct ath11k_base *ab, kfree(tb); } +static void ath11k_wmi_gtk_offload_status_event(struct ath11k_base *ab, + struct sk_buff *skb) +{ + const void **tb; + const struct wmi_gtk_offload_status_event *ev; + struct ath11k_vif *arvif; + __be64 replay_ctr_be; + u64 replay_ctr; + int ret; + + tb = ath11k_wmi_tlv_parse_alloc(ab, skb->data, skb->len, GFP_ATOMIC); + if (IS_ERR(tb)) { + ret = PTR_ERR(tb); + ath11k_warn(ab, "failed to parse tlv: %d\n", ret); + return; + } + + ev = tb[WMI_TAG_GTK_OFFLOAD_STATUS_EVENT]; + if (!ev) { + ath11k_warn(ab, "failed to fetch gtk offload status ev"); + kfree(tb); + return; + } + + arvif = ath11k_mac_get_arvif_by_vdev_id(ab, ev->vdev_id); + if (!arvif) { + ath11k_warn(ab, "failed to get arvif for vdev_id:%d\n", + ev->vdev_id); + kfree(tb); + return; + } + + ath11k_dbg(ab, ATH11K_DBG_WMI, "wmi gtk offload event refresh_cnt %d\n", + ev->refresh_cnt); + ath11k_dbg_dump(ab, ATH11K_DBG_WMI, "replay_cnt", + NULL, ev->replay_ctr.counter, GTK_REPLAY_COUNTER_BYTES); + + replay_ctr = ev->replay_ctr.word1; + replay_ctr = (replay_ctr << 32) | ev->replay_ctr.word0; + arvif->rekey_data.replay_ctr = replay_ctr; + + /* supplicant expects big-endian replay counter */ + replay_ctr_be = cpu_to_be64(replay_ctr); + + ieee80211_gtk_rekey_notify(arvif->vif, arvif->bssid, + (void *)&replay_ctr_be, GFP_KERNEL); + + kfree(tb); +} + static void ath11k_wmi_tlv_op_rx(struct ath11k_base *ab, struct sk_buff *skb) { struct wmi_cmd_hdr *cmd_hdr; @@ -7896,6 +7946,9 @@ static void ath11k_wmi_tlv_op_rx(struct ath11k_base *ab, struct sk_buff *skb) case WMI_DIAG_EVENTID: ath11k_wmi_diag_event(ab, skb); break; + case WMI_GTK_OFFLOAD_STATUS_EVENTID: + ath11k_wmi_gtk_offload_status_event(ab, skb); + break; /* TODO: Add remaining events */ default: ath11k_dbg(ab, ATH11K_DBG_WMI, "Unknown eventid: 0x%x\n", id); @@ -8735,3 +8788,69 @@ int ath11k_wmi_arp_ns_offload(struct ath11k *ar, return ath11k_wmi_cmd_send(ar->wmi, skb, WMI_SET_ARP_NS_OFFLOAD_CMDID); } + +int ath11k_wmi_gtk_rekey_offload(struct ath11k *ar, + struct ath11k_vif *arvif, bool enable) +{ + struct wmi_gtk_rekey_offload_cmd *cmd; + struct ath11k_rekey_data *rekey_data = &arvif->rekey_data; + int len; + struct sk_buff *skb; + __le64 replay_ctr; + + len = sizeof(*cmd); + skb = ath11k_wmi_alloc_skb(ar->wmi->wmi_ab, len); + if (!skb) + return -ENOMEM; + + cmd = (struct wmi_gtk_rekey_offload_cmd *)skb->data; + cmd->tlv_header = FIELD_PREP(WMI_TLV_TAG, WMI_TAG_GTK_OFFLOAD_CMD) | + FIELD_PREP(WMI_TLV_LEN, sizeof(*cmd) - TLV_HDR_SIZE); + + cmd->vdev_id = arvif->vdev_id; + + if (enable) { + cmd->flags = GTK_OFFLOAD_ENABLE_OPCODE; + + /* the length in rekey_data and cmd is equal */ + memcpy(cmd->kck, rekey_data->kck, sizeof(cmd->kck)); + ath11k_ce_byte_swap(cmd->kck, GTK_OFFLOAD_KEK_BYTES); + memcpy(cmd->kek, rekey_data->kek, sizeof(cmd->kek)); + ath11k_ce_byte_swap(cmd->kek, GTK_OFFLOAD_KEK_BYTES); + + replay_ctr = cpu_to_le64(rekey_data->replay_ctr); + memcpy(cmd->replay_ctr, &replay_ctr, + sizeof(replay_ctr)); + ath11k_ce_byte_swap(cmd->replay_ctr, GTK_REPLAY_COUNTER_BYTES); + } else { + cmd->flags = GTK_OFFLOAD_DISABLE_OPCODE; + } + + ath11k_dbg(ar->ab, ATH11K_DBG_WMI, "offload gtk rekey vdev: %d %d\n", + arvif->vdev_id, enable); + return ath11k_wmi_cmd_send(ar->wmi, skb, WMI_GTK_OFFLOAD_CMDID); +} + +int ath11k_wmi_gtk_rekey_getinfo(struct ath11k *ar, + struct ath11k_vif *arvif) +{ + struct wmi_gtk_rekey_offload_cmd *cmd; + int len; + struct sk_buff *skb; + + len = sizeof(*cmd); + skb = ath11k_wmi_alloc_skb(ar->wmi->wmi_ab, len); + if (!skb) + return -ENOMEM; + + cmd = (struct wmi_gtk_rekey_offload_cmd *)skb->data; + cmd->tlv_header = FIELD_PREP(WMI_TLV_TAG, WMI_TAG_GTK_OFFLOAD_CMD) | + FIELD_PREP(WMI_TLV_LEN, sizeof(*cmd) - TLV_HDR_SIZE); + + cmd->vdev_id = arvif->vdev_id; + cmd->flags = GTK_OFFLOAD_REQUEST_STATUS_OPCODE; + + ath11k_dbg(ar->ab, ATH11K_DBG_WMI, "get gtk rekey vdev_id: %d\n", + arvif->vdev_id); + return ath11k_wmi_cmd_send(ar->wmi, skb, WMI_GTK_OFFLOAD_CMDID); +} diff --git a/drivers/net/wireless/ath/ath11k/wmi.h b/drivers/net/wireless/ath/ath11k/wmi.h index e2d03c3b422ce..925b8003feae9 100644 --- a/drivers/net/wireless/ath/ath11k/wmi.h +++ b/drivers/net/wireless/ath/ath11k/wmi.h @@ -5840,6 +5840,51 @@ struct wmi_set_arp_ns_offload_cmd { */ } __packed; +#define GTK_OFFLOAD_OPCODE_MASK 0xFF000000 +#define GTK_OFFLOAD_ENABLE_OPCODE 0x01000000 +#define GTK_OFFLOAD_DISABLE_OPCODE 0x02000000 +#define GTK_OFFLOAD_REQUEST_STATUS_OPCODE 0x04000000 + +#define GTK_OFFLOAD_KEK_BYTES 16 +#define GTK_OFFLOAD_KCK_BYTES 16 +#define GTK_REPLAY_COUNTER_BYTES 8 +#define WMI_MAX_KEY_LEN 32 +#define IGTK_PN_SIZE 6 + +struct wmi_replayc_cnt { + union { + u8 counter[GTK_REPLAY_COUNTER_BYTES]; + struct { + u32 word0; + u32 word1; + } __packed; + } __packed; +} __packed; + +struct wmi_gtk_offload_status_event { + u32 vdev_id; + u32 flags; + u32 refresh_cnt; + struct wmi_replayc_cnt replay_ctr; + u8 igtk_key_index; + u8 igtk_key_length; + u8 igtk_key_rsc[IGTK_PN_SIZE]; + u8 igtk_key[WMI_MAX_KEY_LEN]; + u8 gtk_key_index; + u8 gtk_key_length; + u8 gtk_key_rsc[GTK_REPLAY_COUNTER_BYTES]; + u8 gtk_key[WMI_MAX_KEY_LEN]; +} __packed; + +struct wmi_gtk_rekey_offload_cmd { + u32 tlv_header; + u32 vdev_id; + u32 flags; + u8 kek[GTK_OFFLOAD_KEK_BYTES]; + u8 kck[GTK_OFFLOAD_KCK_BYTES]; + u8 replay_ctr[GTK_REPLAY_COUNTER_BYTES]; +} __packed; + int ath11k_wmi_cmd_send(struct ath11k_pdev_wmi *wmi, struct sk_buff *skb, u32 cmd_id); struct sk_buff *ath11k_wmi_alloc_skb(struct ath11k_wmi_base *wmi_sc, u32 len); @@ -6014,5 +6059,9 @@ int ath11k_wmi_hw_data_filter_cmd(struct ath11k *ar, u32 vdev_id, u32 filter_bitmap, bool enable); int ath11k_wmi_arp_ns_offload(struct ath11k *ar, struct ath11k_vif *arvif, bool enable); +int ath11k_wmi_gtk_rekey_offload(struct ath11k *ar, + struct ath11k_vif *arvif, bool enable); +int ath11k_wmi_gtk_rekey_getinfo(struct ath11k *ar, + struct ath11k_vif *arvif); #endif diff --git a/drivers/net/wireless/ath/ath11k/wow.c b/drivers/net/wireless/ath/ath11k/wow.c index bc6a4d3d6d7c9..93714df834b2c 100644 --- a/drivers/net/wireless/ath/ath11k/wow.c +++ b/drivers/net/wireless/ath/ath11k/wow.c @@ -17,7 +17,9 @@ static const struct wiphy_wowlan_support ath11k_wowlan_support = { .flags = WIPHY_WOWLAN_DISCONNECT | - WIPHY_WOWLAN_MAGIC_PKT, + WIPHY_WOWLAN_MAGIC_PKT | + WIPHY_WOWLAN_SUPPORTS_GTK_REKEY | + WIPHY_WOWLAN_GTK_REKEY_FAILURE, .pattern_min_len = WOW_MIN_PATTERN_SIZE, .pattern_max_len = WOW_MAX_PATTERN_SIZE, .max_pkt_offset = WOW_MAX_PKT_OFFSET, @@ -582,6 +584,41 @@ static int ath11k_wow_arp_ns_offload(struct ath11k *ar, bool enable) return 0; } +static int ath11k_gtk_rekey_offload(struct ath11k *ar, bool enable) +{ + struct ath11k_vif *arvif; + int ret; + + lockdep_assert_held(&ar->conf_mutex); + + list_for_each_entry(arvif, &ar->arvifs, list) { + if (arvif->vdev_type != WMI_VDEV_TYPE_STA || + !arvif->is_up || + !arvif->rekey_data.enable_offload) + continue; + + /* get rekey info before disable rekey offload */ + if (!enable) { + ret = ath11k_wmi_gtk_rekey_getinfo(ar, arvif); + if (ret) { + ath11k_warn(ar->ab, "failed to request rekey info vdev %i, ret %d\n", + arvif->vdev_id, ret); + return ret; + } + } + + ret = ath11k_wmi_gtk_rekey_offload(ar, arvif, enable); + + if (ret) { + ath11k_warn(ar->ab, "failed to offload gtk reky vdev %i: enable %d, ret %d\n", + arvif->vdev_id, enable, ret); + return ret; + } + } + + return 0; +} + static int ath11k_wow_protocol_offload(struct ath11k *ar, bool enable) { int ret; @@ -593,6 +630,13 @@ static int ath11k_wow_protocol_offload(struct ath11k *ar, bool enable) return ret; } + ret = ath11k_gtk_rekey_offload(ar, enable); + if (ret) { + ath11k_warn(ar->ab, "failed to offload gtk rekey %d %d\n", + enable, ret); + return ret; + } + return 0; } From 9503a1fc123d9c9c502a7e518634296874a7b8cc Mon Sep 17 00:00:00 2001 From: Minghao Chi Date: Mon, 14 Mar 2022 06:45:01 +0000 Subject: [PATCH 007/228] ath9k: Use platform_get_irq() to get the interrupt MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit It is not recommened to use platform_get_resource(pdev, IORESOURCE_IRQ) for requesting IRQ's resources any more, as they can be not ready yet in case of DT-booting. platform_get_irq() instead is a recommended way for getting IRQ even if it was not retrieved earlier. It also makes code simpler because we're getting "int" value right away and no conversion from resource to int is required. Reported-by: Zeal Robot Signed-off-by: Minghao Chi Acked-by: Toke Høiland-Jørgensen Signed-off-by: Kalle Valo Link: https://lore.kernel.org/r/20220314064501.2114002-1-chi.minghao@zte.com.cn --- drivers/net/wireless/ath/ath9k/ahb.c | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/drivers/net/wireless/ath/ath9k/ahb.c b/drivers/net/wireless/ath/ath9k/ahb.c index cdefb8e2daf14..c9b853af41d1d 100644 --- a/drivers/net/wireless/ath/ath9k/ahb.c +++ b/drivers/net/wireless/ath/ath9k/ahb.c @@ -98,14 +98,12 @@ static int ath_ahb_probe(struct platform_device *pdev) return -ENOMEM; } - res = platform_get_resource(pdev, IORESOURCE_IRQ, 0); - if (res == NULL) { + irq = platform_get_irq(pdev, 0); + if (irq < 0) { dev_err(&pdev->dev, "no IRQ resource found\n"); - return -ENXIO; + return irq; } - irq = res->start; - ath9k_fill_chanctx_ops(); hw = ieee80211_alloc_hw(sizeof(struct ath_softc), &ath9k_ops); if (hw == NULL) { From b7d174479c8ac365828d474b385da2da858f2089 Mon Sep 17 00:00:00 2001 From: Julia Lawall Date: Mon, 14 Mar 2022 12:53:27 +0100 Subject: [PATCH 008/228] ath6kl: fix typos in comments Various spelling mistakes in comments. Detected with the help of Coccinelle. Signed-off-by: Julia Lawall Signed-off-by: Kalle Valo Link: https://lore.kernel.org/r/20220314115354.144023-4-Julia.Lawall@inria.fr --- drivers/net/wireless/ath/ath6kl/htc_mbox.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/net/wireless/ath/ath6kl/htc_mbox.c b/drivers/net/wireless/ath/ath6kl/htc_mbox.c index e3874421c4c0c..1963d3145481d 100644 --- a/drivers/net/wireless/ath/ath6kl/htc_mbox.c +++ b/drivers/net/wireless/ath/ath6kl/htc_mbox.c @@ -1538,7 +1538,7 @@ static int ath6kl_htc_rx_alloc(struct htc_target *target, queue, n_msg); /* - * This is due to unavailabilty of buffers to rx entire data. + * This is due to unavailability of buffers to rx entire data. * Return no error so that free buffers from queue can be used * to receive partial data. */ From 2c3fc50591ff3b7c90afb39c6f4ac67a0ffeeb76 Mon Sep 17 00:00:00 2001 From: Youghandhar Chintala Date: Tue, 15 Mar 2022 13:59:44 +0530 Subject: [PATCH 009/228] ath10k: Trigger sta disconnect on hardware restart Currently after the hardware restart triggered from the driver, the station interface connection remains intact, since a disconnect trigger is not sent to userspace. This can lead to a problem in targets where the wifi mac sequence is added by the firmware. After the target restart, its wifi mac sequence number gets reset to zero. Hence AP to which our device is connected will receive frames with a wifi mac sequence number jump to the past, thereby resulting in the AP dropping all these frames, until the frame arrives with a wifi mac sequence number which AP was expecting. To avoid such frame drops, its better to trigger a station disconnect upon target hardware restart which can be done with API ieee80211_reconfig_disconnect exposed to mac80211. The other targets are not affected by this change, since the hardware params flag is not set. Tested-on: WCN3990 hw1.0 SNOC WLAN.HL.3.1-01040-QCAHLSWMTPLZ-1 Tested-on: QCA6174 hw3.2 PCI WLAN.RM.4.4.1-00110-QCARMSWP-1 Tested-on: QCA6174 hw3.2 SDIO WLAN.RMH.4.4.1-00048 Signed-off-by: Youghandhar Chintala Signed-off-by: Kalle Valo Link: https://lore.kernel.org/r/20220315082944.12406-3-youghand@codeaurora.org --- drivers/net/wireless/ath/ath10k/core.c | 25 +++++++++++++++++++++++++ drivers/net/wireless/ath/ath10k/hw.h | 2 ++ 2 files changed, 27 insertions(+) diff --git a/drivers/net/wireless/ath/ath10k/core.c b/drivers/net/wireless/ath/ath10k/core.c index 9e1f483e1362a..2092bfd02cd1c 100644 --- a/drivers/net/wireless/ath/ath10k/core.c +++ b/drivers/net/wireless/ath/ath10k/core.c @@ -94,6 +94,7 @@ static const struct ath10k_hw_params ath10k_hw_params_list[] = { .credit_size_workaround = false, .tx_stats_over_pktlog = true, .dynamic_sar_support = false, + .hw_restart_disconnect = false, }, { .id = QCA988X_HW_2_0_VERSION, @@ -131,6 +132,7 @@ static const struct ath10k_hw_params ath10k_hw_params_list[] = { .credit_size_workaround = false, .tx_stats_over_pktlog = true, .dynamic_sar_support = false, + .hw_restart_disconnect = false, }, { .id = QCA9887_HW_1_0_VERSION, @@ -169,6 +171,7 @@ static const struct ath10k_hw_params ath10k_hw_params_list[] = { .credit_size_workaround = false, .tx_stats_over_pktlog = false, .dynamic_sar_support = false, + .hw_restart_disconnect = false, }, { .id = QCA6174_HW_3_2_VERSION, @@ -202,6 +205,7 @@ static const struct ath10k_hw_params ath10k_hw_params_list[] = { .bmi_large_size_download = true, .supports_peer_stats_info = true, .dynamic_sar_support = true, + .hw_restart_disconnect = false, }, { .id = QCA6174_HW_2_1_VERSION, @@ -239,6 +243,7 @@ static const struct ath10k_hw_params ath10k_hw_params_list[] = { .credit_size_workaround = false, .tx_stats_over_pktlog = false, .dynamic_sar_support = false, + .hw_restart_disconnect = false, }, { .id = QCA6174_HW_2_1_VERSION, @@ -276,6 +281,7 @@ static const struct ath10k_hw_params ath10k_hw_params_list[] = { .credit_size_workaround = false, .tx_stats_over_pktlog = false, .dynamic_sar_support = false, + .hw_restart_disconnect = false, }, { .id = QCA6174_HW_3_0_VERSION, @@ -313,6 +319,7 @@ static const struct ath10k_hw_params ath10k_hw_params_list[] = { .credit_size_workaround = false, .tx_stats_over_pktlog = false, .dynamic_sar_support = false, + .hw_restart_disconnect = false, }, { .id = QCA6174_HW_3_2_VERSION, @@ -354,6 +361,7 @@ static const struct ath10k_hw_params ath10k_hw_params_list[] = { .tx_stats_over_pktlog = false, .supports_peer_stats_info = true, .dynamic_sar_support = true, + .hw_restart_disconnect = false, }, { .id = QCA99X0_HW_2_0_DEV_VERSION, @@ -397,6 +405,7 @@ static const struct ath10k_hw_params ath10k_hw_params_list[] = { .credit_size_workaround = false, .tx_stats_over_pktlog = false, .dynamic_sar_support = false, + .hw_restart_disconnect = false, }, { .id = QCA9984_HW_1_0_DEV_VERSION, @@ -447,6 +456,7 @@ static const struct ath10k_hw_params ath10k_hw_params_list[] = { .credit_size_workaround = false, .tx_stats_over_pktlog = false, .dynamic_sar_support = false, + .hw_restart_disconnect = false, }, { .id = QCA9888_HW_2_0_DEV_VERSION, @@ -494,6 +504,7 @@ static const struct ath10k_hw_params ath10k_hw_params_list[] = { .credit_size_workaround = false, .tx_stats_over_pktlog = false, .dynamic_sar_support = false, + .hw_restart_disconnect = false, }, { .id = QCA9377_HW_1_0_DEV_VERSION, @@ -531,6 +542,7 @@ static const struct ath10k_hw_params ath10k_hw_params_list[] = { .credit_size_workaround = false, .tx_stats_over_pktlog = false, .dynamic_sar_support = false, + .hw_restart_disconnect = false, }, { .id = QCA9377_HW_1_1_DEV_VERSION, @@ -570,6 +582,7 @@ static const struct ath10k_hw_params ath10k_hw_params_list[] = { .credit_size_workaround = false, .tx_stats_over_pktlog = false, .dynamic_sar_support = false, + .hw_restart_disconnect = false, }, { .id = QCA9377_HW_1_1_DEV_VERSION, @@ -600,6 +613,7 @@ static const struct ath10k_hw_params ath10k_hw_params_list[] = { .uart_pin_workaround = true, .credit_size_workaround = true, .dynamic_sar_support = false, + .hw_restart_disconnect = false, }, { .id = QCA4019_HW_1_0_DEV_VERSION, @@ -644,6 +658,7 @@ static const struct ath10k_hw_params ath10k_hw_params_list[] = { .credit_size_workaround = false, .tx_stats_over_pktlog = false, .dynamic_sar_support = false, + .hw_restart_disconnect = false, }, { .id = WCN3990_HW_1_0_DEV_VERSION, @@ -674,6 +689,7 @@ static const struct ath10k_hw_params ath10k_hw_params_list[] = { .credit_size_workaround = false, .tx_stats_over_pktlog = false, .dynamic_sar_support = true, + .hw_restart_disconnect = true, }, }; @@ -2442,6 +2458,7 @@ EXPORT_SYMBOL(ath10k_core_napi_sync_disable); static void ath10k_core_restart(struct work_struct *work) { struct ath10k *ar = container_of(work, struct ath10k, restart_work); + struct ath10k_vif *arvif; int ret; set_bit(ATH10K_FLAG_CRASH_FLUSH, &ar->dev_flags); @@ -2480,6 +2497,14 @@ static void ath10k_core_restart(struct work_struct *work) ar->state = ATH10K_STATE_RESTARTING; ath10k_halt(ar); ath10k_scan_finish(ar); + if (ar->hw_params.hw_restart_disconnect) { + list_for_each_entry(arvif, &ar->arvifs, list) { + if (arvif->is_up && + arvif->vdev_type == WMI_VDEV_TYPE_STA) + ieee80211_hw_restart_disconnect(arvif->vif); + } + } + ieee80211_restart_hw(ar->hw); break; case ATH10K_STATE_OFF: diff --git a/drivers/net/wireless/ath/ath10k/hw.h b/drivers/net/wireless/ath/ath10k/hw.h index 5215a6816d718..93acf0dd580a6 100644 --- a/drivers/net/wireless/ath/ath10k/hw.h +++ b/drivers/net/wireless/ath/ath10k/hw.h @@ -633,6 +633,8 @@ struct ath10k_hw_params { bool supports_peer_stats_info; bool dynamic_sar_support; + + bool hw_restart_disconnect; }; struct htt_resp; From c4e9705c50121771e7582830359894431f24db73 Mon Sep 17 00:00:00 2001 From: Meng Tang Date: Fri, 18 Mar 2022 10:53:31 +0800 Subject: [PATCH 010/228] ath10k: Use of_device_get_match_data() helper Only the device data is needed, not the entire struct of_device_id. Use of_device_get_match_data() instead of of_match_device(). Signed-off-by: Meng Tang Signed-off-by: Kalle Valo Link: https://lore.kernel.org/r/20220318025331.23030-1-tangmeng@uniontech.com --- drivers/net/wireless/ath/ath10k/ahb.c | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-) diff --git a/drivers/net/wireless/ath/ath10k/ahb.c b/drivers/net/wireless/ath/ath10k/ahb.c index ab8f77ae5e667..f0c615fa56143 100644 --- a/drivers/net/wireless/ath/ath10k/ahb.c +++ b/drivers/net/wireless/ath/ath10k/ahb.c @@ -728,20 +728,17 @@ static int ath10k_ahb_probe(struct platform_device *pdev) struct ath10k *ar; struct ath10k_ahb *ar_ahb; struct ath10k_pci *ar_pci; - const struct of_device_id *of_id; enum ath10k_hw_rev hw_rev; size_t size; int ret; struct ath10k_bus_params bus_params = {}; - of_id = of_match_device(ath10k_ahb_of_match, &pdev->dev); - if (!of_id) { - dev_err(&pdev->dev, "failed to find matching device tree id\n"); + hw_rev = (enum ath10k_hw_rev)of_device_get_match_data(&pdev->dev); + if (!hw_rev) { + dev_err(&pdev->dev, "OF data missing\n"); return -EINVAL; } - hw_rev = (enum ath10k_hw_rev)of_id->data; - size = sizeof(*ar_pci) + sizeof(*ar_ahb); ar = ath10k_core_create(size, &pdev->dev, ATH10K_BUS_AHB, hw_rev, &ath10k_ahb_hif_ops); From 997dc60f0855b39aec0400511b37d65781da9255 Mon Sep 17 00:00:00 2001 From: Karthikeyan Periyasamy Date: Mon, 28 Feb 2022 10:24:39 +0530 Subject: [PATCH 011/228] ath11k: Refactor the peer delete Introduce new helper function for peer delete to reuse this logic in all peer cleanup procedures. Found this in code review. Also this change is applicable for all the platform. Tested-on: QCN9074 hw1.0 PCI WLAN.HK.2.5.0.1-01067-QCAHKSWPL_SILICONZ-1 Signed-off-by: Karthikeyan Periyasamy Signed-off-by: Kalle Valo Link: https://lore.kernel.org/r/1646024079-26391-1-git-send-email-quic_periyasa@quicinc.com --- drivers/net/wireless/ath/ath11k/mac.c | 16 +++---------- drivers/net/wireless/ath/ath11k/peer.c | 31 +++++++++++++------------- 2 files changed, 19 insertions(+), 28 deletions(-) diff --git a/drivers/net/wireless/ath/ath11k/mac.c b/drivers/net/wireless/ath/ath11k/mac.c index e0e31605e0b0b..7cf1ea276e245 100644 --- a/drivers/net/wireless/ath/ath11k/mac.c +++ b/drivers/net/wireless/ath/ath11k/mac.c @@ -6387,22 +6387,12 @@ static int ath11k_mac_op_add_interface(struct ieee80211_hw *hw, err_peer_del: if (arvif->vdev_type == WMI_VDEV_TYPE_AP) { - reinit_completion(&ar->peer_delete_done); - - fbret = ath11k_wmi_send_peer_delete_cmd(ar, vif->addr, - arvif->vdev_id); + fbret = ath11k_peer_delete(ar, arvif->vdev_id, vif->addr); if (fbret) { - ath11k_warn(ar->ab, "failed to delete peer vdev_id %d addr %pM\n", - arvif->vdev_id, vif->addr); + ath11k_warn(ar->ab, "fallback fail to delete peer addr %pM vdev_id %d ret %d\n", + vif->addr, arvif->vdev_id, fbret); goto err; } - - fbret = ath11k_wait_for_peer_delete_done(ar, arvif->vdev_id, - vif->addr); - if (fbret) - goto err; - - ar->num_peers--; } err_vdev_del: diff --git a/drivers/net/wireless/ath/ath11k/peer.c b/drivers/net/wireless/ath/ath11k/peer.c index 332886bc6b331..392985b873bfd 100644 --- a/drivers/net/wireless/ath/ath11k/peer.c +++ b/drivers/net/wireless/ath/ath11k/peer.c @@ -217,7 +217,7 @@ int ath11k_wait_for_peer_delete_done(struct ath11k *ar, u32 vdev_id, return 0; } -int ath11k_peer_delete(struct ath11k *ar, u32 vdev_id, u8 *addr) +static int __ath11k_peer_delete(struct ath11k *ar, u32 vdev_id, const u8 *addr) { int ret; @@ -237,6 +237,19 @@ int ath11k_peer_delete(struct ath11k *ar, u32 vdev_id, u8 *addr) if (ret) return ret; + return 0; +} + +int ath11k_peer_delete(struct ath11k *ar, u32 vdev_id, u8 *addr) +{ + int ret; + + lockdep_assert_held(&ar->conf_mutex); + + ret = __ath11k_peer_delete(ar, vdev_id, addr); + if (ret) + return ret; + ar->num_peers--; return 0; @@ -323,22 +336,10 @@ int ath11k_peer_create(struct ath11k *ar, struct ath11k_vif *arvif, return 0; cleanup: - reinit_completion(&ar->peer_delete_done); - - fbret = ath11k_wmi_send_peer_delete_cmd(ar, param->peer_addr, - param->vdev_id); - if (fbret) { - ath11k_warn(ar->ab, "failed to delete peer vdev_id %d addr %pM\n", - param->vdev_id, param->peer_addr); - goto exit; - } - - fbret = ath11k_wait_for_peer_delete_done(ar, param->vdev_id, - param->peer_addr); + fbret = __ath11k_peer_delete(ar, param->vdev_id, param->peer_addr); if (fbret) - ath11k_warn(ar->ab, "failed wait for peer %pM delete done id %d fallback ret %d\n", + ath11k_warn(ar->ab, "failed peer %pM delete vdev_id %d fallback ret %d\n", param->peer_addr, param->vdev_id, fbret); -exit: return ret; } From 72a9bff386545d3f8e9c432cb8e036272ad4e1fa Mon Sep 17 00:00:00 2001 From: Hari Chandrakanthan Date: Wed, 9 Mar 2022 16:54:25 +0530 Subject: [PATCH 012/228] ath11k: change fw build id format in driver init log Currently fw build id is printed during init as follows. fw_version 0x250684a5 fw_build_timestamp 2021-07-13 10:57 fw_build_id QC_IMAGE_VERSION_STRING=WLAN.HK.2.5.0.1-01100-QCAHKSWPL_SILICONZ-1 The string "QC_IMAGE_VERSION_STRING=" is removed from the log to improve readability. With this patch the fw build id is printed during init as follows. fw_version 0x250684a5 fw_build_timestamp 2021-07-13 10:57 fw_build_id WLAN.HK.2.5.0.1-01100-QCAHKSWPL_SILICONZ-1 Signed-off-by: Hari Chandrakanthan Signed-off-by: Kalle Valo Link: https://lore.kernel.org/r/1646825065-7736-1-git-send-email-quic_haric@quicinc.com --- drivers/net/wireless/ath/ath11k/qmi.c | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/drivers/net/wireless/ath/ath11k/qmi.c b/drivers/net/wireless/ath/ath11k/qmi.c index 04e966830c188..ec110fe81378a 100644 --- a/drivers/net/wireless/ath/ath11k/qmi.c +++ b/drivers/net/wireless/ath/ath11k/qmi.c @@ -16,6 +16,8 @@ #define SLEEP_CLOCK_SELECT_INTERNAL_BIT 0x02 #define HOST_CSTATE_BIT 0x04 +#define FW_BUILD_ID_MASK "QC_IMAGE_VERSION_STRING=" + bool ath11k_cold_boot_cal = 1; EXPORT_SYMBOL(ath11k_cold_boot_cal); module_param_named(cold_boot_cal, ath11k_cold_boot_cal, bool, 0644); @@ -2008,6 +2010,8 @@ static int ath11k_qmi_request_target_cap(struct ath11k_base *ab) struct qmi_txn txn; int ret = 0; int r; + char *fw_build_id; + int fw_build_id_mask_len; memset(&req, 0, sizeof(req)); memset(&resp, 0, sizeof(resp)); @@ -2073,6 +2077,11 @@ static int ath11k_qmi_request_target_cap(struct ath11k_base *ab) ath11k_dbg(ab, ATH11K_DBG_QMI, "qmi cal data supported from eeprom\n"); } + fw_build_id = ab->qmi.target.fw_build_id; + fw_build_id_mask_len = strlen(FW_BUILD_ID_MASK); + if (!strncmp(fw_build_id, FW_BUILD_ID_MASK, fw_build_id_mask_len)) + fw_build_id = fw_build_id + fw_build_id_mask_len; + ath11k_info(ab, "chip_id 0x%x chip_family 0x%x board_id 0x%x soc_id 0x%x\n", ab->qmi.target.chip_id, ab->qmi.target.chip_family, ab->qmi.target.board_id, ab->qmi.target.soc_id); @@ -2080,7 +2089,7 @@ static int ath11k_qmi_request_target_cap(struct ath11k_base *ab) ath11k_info(ab, "fw_version 0x%x fw_build_timestamp %s fw_build_id %s", ab->qmi.target.fw_version, ab->qmi.target.fw_build_timestamp, - ab->qmi.target.fw_build_id); + fw_build_id); r = ath11k_core_check_dt(ab); if (r) From 2db80f93869d491be57cbc2b36f30d0d3a0e5bde Mon Sep 17 00:00:00 2001 From: Niels Dossche Date: Mon, 21 Mar 2022 12:58:23 +0200 Subject: [PATCH 013/228] ath11k: acquire ab->base_lock in unassign when finding the peer by addr ath11k_peer_find_by_addr states via lockdep that ab->base_lock must be held when calling that function in order to protect the list. All callers except ath11k_mac_op_unassign_vif_chanctx have that lock acquired when calling ath11k_peer_find_by_addr. That lock is also not transitively held by a path towards ath11k_mac_op_unassign_vif_chanctx. The solution is to acquire the lock when calling ath11k_peer_find_by_addr inside ath11k_mac_op_unassign_vif_chanctx. I am currently working on a static analyser to detect missing locks and this was a reported case. I manually verified the report by looking at the code, but I do not have real hardware so this is compile tested only. Fixes: 701e48a43e15 ("ath11k: add packet log support for QCA6390") Signed-off-by: Niels Dossche Signed-off-by: Kalle Valo Link: https://lore.kernel.org/r/20220314215253.92658-1-dossche.niels@gmail.com --- drivers/net/wireless/ath/ath11k/mac.c | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/drivers/net/wireless/ath/ath11k/mac.c b/drivers/net/wireless/ath/ath11k/mac.c index 7cf1ea276e245..62d9558a8e85f 100644 --- a/drivers/net/wireless/ath/ath11k/mac.c +++ b/drivers/net/wireless/ath/ath11k/mac.c @@ -7133,6 +7133,7 @@ ath11k_mac_op_unassign_vif_chanctx(struct ieee80211_hw *hw, struct ath11k *ar = hw->priv; struct ath11k_base *ab = ar->ab; struct ath11k_vif *arvif = (void *)vif->drv_priv; + struct ath11k_peer *peer; int ret; mutex_lock(&ar->conf_mutex); @@ -7144,9 +7145,13 @@ ath11k_mac_op_unassign_vif_chanctx(struct ieee80211_hw *hw, WARN_ON(!arvif->is_started); if (ab->hw_params.vdev_start_delay && - arvif->vdev_type == WMI_VDEV_TYPE_MONITOR && - ath11k_peer_find_by_addr(ab, ar->mac_addr)) - ath11k_peer_delete(ar, arvif->vdev_id, ar->mac_addr); + arvif->vdev_type == WMI_VDEV_TYPE_MONITOR) { + spin_lock_bh(&ab->base_lock); + peer = ath11k_peer_find_by_addr(ab, ar->mac_addr); + spin_unlock_bh(&ab->base_lock); + if (peer) + ath11k_peer_delete(ar, arvif->vdev_id, ar->mac_addr); + } if (arvif->vdev_type == WMI_VDEV_TYPE_MONITOR) { ret = ath11k_mac_monitor_stop(ar); From 7fb376ad7d3f200575b9f9374e21b39d30b57267 Mon Sep 17 00:00:00 2001 From: Wen Gong Date: Mon, 21 Mar 2022 13:03:23 +0200 Subject: [PATCH 014/228] ath11k: remove unused ATH11K_BD_IE_BOARD_EXT Currently ATH11K_BD_IE_BOARD_EXT is not used, so remove it. Tested-on: WCN6855 hw2.0 PCI WLAN.HSP.1.1-03125-QCAHSPSWPL_V1_V2_SILICONZ_LITE-3 Signed-off-by: Wen Gong Signed-off-by: Kalle Valo Link: https://lore.kernel.org/r/20220319023543.14288-2-quic_wgong@quicinc.com --- drivers/net/wireless/ath/ath11k/hw.h | 1 - 1 file changed, 1 deletion(-) diff --git a/drivers/net/wireless/ath/ath11k/hw.h b/drivers/net/wireless/ath/ath11k/hw.h index 27ca4a9c20fcf..1c701e16a3b55 100644 --- a/drivers/net/wireless/ath/ath11k/hw.h +++ b/drivers/net/wireless/ath/ath11k/hw.h @@ -293,7 +293,6 @@ enum ath11k_bd_ie_board_type { enum ath11k_bd_ie_type { /* contains sub IEs of enum ath11k_bd_ie_board_type */ ATH11K_BD_IE_BOARD = 0, - ATH11K_BD_IE_BOARD_EXT = 1, }; struct ath11k_hw_regs { From 0c104b6163e344e972dbbd255ca2441c171a8a87 Mon Sep 17 00:00:00 2001 From: Wen Gong Date: Mon, 21 Mar 2022 13:03:29 +0200 Subject: [PATCH 015/228] ath11k: disable regdb support for QCA6390 Currently it does not have regdb files for QCA6390, so disable its regdb support feature now. Tested-on: QCA6390 hw2.0 PCI WLAN.HST.1.0.1-05266-QCAHSTSWPLZ_V2_TO_X86-1 Signed-off-by: Wen Gong Signed-off-by: Kalle Valo Link: https://lore.kernel.org/r/20220319023543.14288-3-quic_wgong@quicinc.com --- drivers/net/wireless/ath/ath11k/core.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/net/wireless/ath/ath11k/core.c b/drivers/net/wireless/ath/ath11k/core.c index 1041490502053..700fd4ff62e48 100644 --- a/drivers/net/wireless/ath/ath11k/core.c +++ b/drivers/net/wireless/ath/ath11k/core.c @@ -219,7 +219,7 @@ static const struct ath11k_hw_params ath11k_hw_params[] = { .num_peers = 512, .supports_suspend = true, .hal_desc_sz = sizeof(struct hal_rx_desc_ipq8074), - .supports_regdb = true, + .supports_regdb = false, .fix_l1ss = true, .credit_flow = true, .max_tx_ring = DP_TCL_NUM_RING_MAX_QCA6390, From 13da397f884d9c9a3fb6616206eeb6c6ab097287 Mon Sep 17 00:00:00 2001 From: Wen Gong Date: Mon, 28 Feb 2022 01:46:03 -0500 Subject: [PATCH 016/228] ath11k: add support for device recovery for QCA6390/WCN6855 Currently ath11k has device recovery logic, it is introduced by this patch "ath11k: Add support for subsystem recovery" which is upstream by https://git.kernel.org/pub/scm/linux/kernel/git/kvalo/ath.git/commit/?h=ath11k-bringup&id=3a7b4838b6f6f234239f263ef3dc02e612a083ad. The patch is for AHB devices such as IPQ8074, it has remote proc module which is used to download the firmware and boots the processor which firmware is running on. If firmware crashed, remote proc module will detect it and download and boot firmware again. Below command will trigger a firmware crash, and then user can test feature of device recovery. Test command: echo assert > /sys/kernel/debug/ath11k/qca6390\ hw2.0/simulate_fw_crash echo assert > /sys/kernel/debug/ath11k/wcn6855\ hw2.0/simulate_fw_crash Unfortunately, QCA6390 is PCIe bus, it does not have the remote proc module, it use mhi module to communicate between firmware and ath11k. So ath11k does not support device recovery for QCA6390 currently. This patch is to add the extra logic which is different for QCA6390. When firmware crashed, MHI_CB_EE_RDDM event will be indicate by firmware and then ath11k_mhi_op_status_cb which is the callback of mhi_controller will receive the MHI_CB_EE_RDDM event, then ath11k will start to do recovery process, ath11k_core_reset() calls ath11k_hif_power_down()/ath11k_hif_power_up(), then the mhi/ath11k will start to download and boot firmware. There are some logic to avoid deadloop recovery and two simultaneous recovery operations. And because it has muti-radios for the soc, so it add some logic in ath11k_mac_op_reconfig_complete() to make sure all radios has reconfig complete and then complete the device recovery. Also it add workqueue_aux, because ab->workqueue is used when receive ATH11K_QMI_EVENT_FW_READY in recovery process(queue_work(ab->workqueue, &ab->restart_work)), and ath11k_core_reset will wait for max ATH11K_RESET_TIMEOUT_HZ for the previous restart_work finished, if ath11k_core_reset also queued in ab->workqueue, then it will delay restart_work of previous recovery and lead previous recovery fail. ath11k recovery success for QCA6390/WCN6855 after apply this patch. Tested-on: QCA6390 hw2.0 PCI WLAN.HST.1.0.1-01740-QCAHSTSWPLZ_V2_TO_X86-1 Tested-on: WCN6855 hw2.0 PCI WLAN.HSP.1.1-03003-QCAHSPSWPL_V1_V2_SILICONZ_LITE-2 Signed-off-by: Wen Gong Signed-off-by: Kalle Valo Link: https://lore.kernel.org/r/20220228064606.8981-2-quic_wgong@quicinc.com --- drivers/net/wireless/ath/ath11k/core.c | 68 ++++++++++++++++++++++++++ drivers/net/wireless/ath/ath11k/core.h | 13 +++++ drivers/net/wireless/ath/ath11k/mac.c | 18 +++++++ drivers/net/wireless/ath/ath11k/mhi.c | 33 +++++++++++++ 4 files changed, 132 insertions(+) diff --git a/drivers/net/wireless/ath/ath11k/core.c b/drivers/net/wireless/ath/ath11k/core.c index 700fd4ff62e48..97ee3dd230ed1 100644 --- a/drivers/net/wireless/ath/ath11k/core.c +++ b/drivers/net/wireless/ath/ath11k/core.c @@ -1381,6 +1381,65 @@ static void ath11k_core_restart(struct work_struct *work) complete(&ab->driver_recovery); } +static void ath11k_core_reset(struct work_struct *work) +{ + struct ath11k_base *ab = container_of(work, struct ath11k_base, reset_work); + int reset_count, fail_cont_count; + long time_left; + + if (!(test_bit(ATH11K_FLAG_REGISTERED, &ab->dev_flags))) { + ath11k_warn(ab, "ignore reset dev flags 0x%lx\n", ab->dev_flags); + return; + } + + /* Sometimes the recovery will fail and then the next all recovery fail, + * this is to avoid infinite recovery since it can not recovery success. + */ + fail_cont_count = atomic_read(&ab->fail_cont_count); + + if (fail_cont_count >= ATH11K_RESET_MAX_FAIL_COUNT_FINAL) + return; + + if (fail_cont_count >= ATH11K_RESET_MAX_FAIL_COUNT_FIRST && + time_before(jiffies, ab->reset_fail_timeout)) + return; + + reset_count = atomic_inc_return(&ab->reset_count); + + if (reset_count > 1) { + /* Sometimes it happened another reset worker before the previous one + * completed, then the second reset worker will destroy the previous one, + * thus below is to avoid that. + */ + ath11k_warn(ab, "already reseting count %d\n", reset_count); + + reinit_completion(&ab->reset_complete); + time_left = wait_for_completion_timeout(&ab->reset_complete, + ATH11K_RESET_TIMEOUT_HZ); + + if (time_left) { + ath11k_dbg(ab, ATH11K_DBG_BOOT, "to skip reset\n"); + atomic_dec(&ab->reset_count); + return; + } + + ab->reset_fail_timeout = jiffies + ATH11K_RESET_FAIL_TIMEOUT_HZ; + /* Record the continuous recovery fail count when recovery failed*/ + atomic_inc(&ab->fail_cont_count); + } + + ath11k_dbg(ab, ATH11K_DBG_BOOT, "reset starting\n"); + + ab->is_reset = true; + atomic_set(&ab->recovery_count, 0); + + ath11k_hif_power_down(ab); + ath11k_qmi_free_resource(ab); + ath11k_hif_power_up(ab); + + ath11k_dbg(ab, ATH11K_DBG_BOOT, "reset started\n"); +} + static int ath11k_init_hw_params(struct ath11k_base *ab) { const struct ath11k_hw_params *hw_params = NULL; @@ -1450,6 +1509,7 @@ EXPORT_SYMBOL(ath11k_core_deinit); void ath11k_core_free(struct ath11k_base *ab) { + destroy_workqueue(ab->workqueue_aux); destroy_workqueue(ab->workqueue); kfree(ab); @@ -1472,9 +1532,14 @@ struct ath11k_base *ath11k_core_alloc(struct device *dev, size_t priv_size, if (!ab->workqueue) goto err_sc_free; + ab->workqueue_aux = create_singlethread_workqueue("ath11k_aux_wq"); + if (!ab->workqueue_aux) + goto err_free_wq; + mutex_init(&ab->core_lock); spin_lock_init(&ab->base_lock); mutex_init(&ab->vdev_id_11d_lock); + init_completion(&ab->reset_complete); INIT_LIST_HEAD(&ab->peers); init_waitqueue_head(&ab->peer_mapping_wq); @@ -1483,6 +1548,7 @@ struct ath11k_base *ath11k_core_alloc(struct device *dev, size_t priv_size, INIT_WORK(&ab->restart_work, ath11k_core_restart); INIT_WORK(&ab->update_11d_work, ath11k_update_11d); INIT_WORK(&ab->rfkill_work, ath11k_rfkill_work); + INIT_WORK(&ab->reset_work, ath11k_core_reset); timer_setup(&ab->rx_replenish_retry, ath11k_ce_rx_replenish_retry, 0); init_completion(&ab->htc_suspend); init_completion(&ab->wow.wakeup_completed); @@ -1493,6 +1559,8 @@ struct ath11k_base *ath11k_core_alloc(struct device *dev, size_t priv_size, return ab; +err_free_wq: + destroy_workqueue(ab->workqueue); err_sc_free: kfree(ab); return NULL; diff --git a/drivers/net/wireless/ath/ath11k/core.h b/drivers/net/wireless/ath/ath11k/core.h index e556beb945ac8..bd31413d84ca3 100644 --- a/drivers/net/wireless/ath/ath11k/core.h +++ b/drivers/net/wireless/ath/ath11k/core.h @@ -40,6 +40,10 @@ extern unsigned int ath11k_frame_mode; #define ATH11K_MON_TIMER_INTERVAL 10 +#define ATH11K_RESET_TIMEOUT_HZ (20 * HZ) +#define ATH11K_RESET_MAX_FAIL_COUNT_FIRST 3 +#define ATH11K_RESET_MAX_FAIL_COUNT_FINAL 5 +#define ATH11K_RESET_FAIL_TIMEOUT_HZ (20 * HZ) enum ath11k_supported_bw { ATH11K_BW_20 = 0, @@ -820,6 +824,15 @@ struct ath11k_base { struct work_struct restart_work; struct work_struct update_11d_work; u8 new_alpha2[3]; + struct workqueue_struct *workqueue_aux; + struct work_struct reset_work; + atomic_t reset_count; + atomic_t recovery_count; + bool is_reset; + struct completion reset_complete; + /* continuous recovery fail count */ + atomic_t fail_cont_count; + unsigned long reset_fail_timeout; struct { /* protected by data_lock */ u32 fw_crash_counter; diff --git a/drivers/net/wireless/ath/ath11k/mac.c b/drivers/net/wireless/ath/ath11k/mac.c index 62d9558a8e85f..f2979dc00fdb3 100644 --- a/drivers/net/wireless/ath/ath11k/mac.c +++ b/drivers/net/wireless/ath/ath11k/mac.c @@ -7915,6 +7915,8 @@ ath11k_mac_op_reconfig_complete(struct ieee80211_hw *hw, enum ieee80211_reconfig_type reconfig_type) { struct ath11k *ar = hw->priv; + struct ath11k_base *ab = ar->ab; + int recovery_count; if (reconfig_type != IEEE80211_RECONFIG_TYPE_RESTART) return; @@ -7926,6 +7928,22 @@ ath11k_mac_op_reconfig_complete(struct ieee80211_hw *hw, ar->pdev->pdev_id); ar->state = ATH11K_STATE_ON; ieee80211_wake_queues(ar->hw); + + if (ab->is_reset) { + recovery_count = atomic_inc_return(&ab->recovery_count); + ath11k_dbg(ab, ATH11K_DBG_BOOT, + "recovery count %d\n", recovery_count); + /* When there are multiple radios in an SOC, + * the recovery has to be done for each radio + */ + if (recovery_count == ab->num_radios) { + atomic_dec(&ab->reset_count); + complete(&ab->reset_complete); + ab->is_reset = false; + atomic_set(&ab->fail_cont_count, 0); + ath11k_dbg(ab, ATH11K_DBG_BOOT, "reset success\n"); + } + } } mutex_unlock(&ar->conf_mutex); diff --git a/drivers/net/wireless/ath/ath11k/mhi.c b/drivers/net/wireless/ath/ath11k/mhi.c index fc3524e83e52c..61d83be4841f9 100644 --- a/drivers/net/wireless/ath/ath11k/mhi.c +++ b/drivers/net/wireless/ath/ath11k/mhi.c @@ -292,15 +292,48 @@ static void ath11k_mhi_op_runtime_put(struct mhi_controller *mhi_cntrl) { } +static char *ath11k_mhi_op_callback_to_str(enum mhi_callback reason) +{ + switch (reason) { + case MHI_CB_IDLE: + return "MHI_CB_IDLE"; + case MHI_CB_PENDING_DATA: + return "MHI_CB_PENDING_DATA"; + case MHI_CB_LPM_ENTER: + return "MHI_CB_LPM_ENTER"; + case MHI_CB_LPM_EXIT: + return "MHI_CB_LPM_EXIT"; + case MHI_CB_EE_RDDM: + return "MHI_CB_EE_RDDM"; + case MHI_CB_EE_MISSION_MODE: + return "MHI_CB_EE_MISSION_MODE"; + case MHI_CB_SYS_ERROR: + return "MHI_CB_SYS_ERROR"; + case MHI_CB_FATAL_ERROR: + return "MHI_CB_FATAL_ERROR"; + case MHI_CB_BW_REQ: + return "MHI_CB_BW_REQ"; + default: + return "UNKNOWN"; + } +}; + static void ath11k_mhi_op_status_cb(struct mhi_controller *mhi_cntrl, enum mhi_callback cb) { struct ath11k_base *ab = dev_get_drvdata(mhi_cntrl->cntrl_dev); + ath11k_dbg(ab, ATH11K_DBG_BOOT, "mhi notify status reason %s\n", + ath11k_mhi_op_callback_to_str(cb)); + switch (cb) { case MHI_CB_SYS_ERROR: ath11k_warn(ab, "firmware crashed: MHI_CB_SYS_ERROR\n"); break; + case MHI_CB_EE_RDDM: + if (!(test_bit(ATH11K_FLAG_UNREGISTERING, &ab->dev_flags))) + queue_work(ab->workqueue_aux, &ab->reset_work); + break; default: break; } From 38194f3a605e4a961f28bc38a73a4f4d43123968 Mon Sep 17 00:00:00 2001 From: Wen Gong Date: Mon, 21 Mar 2022 13:16:57 +0200 Subject: [PATCH 017/228] ath11k: add synchronization operation between reconfigure of mac80211 and ath11k_base ieee80211_reconfig() of mac80211 is the main function for recovery of each ieee80211_hw and ath11k, and ath11k_core_reconfigure_on_crash() is the main function for recovery of ath11k_base, it has more than one ieee80211_hw and ath11k for each ath11k_base, so it need to add synchronization between them, otherwise it has many issue. For example, when ath11k_core_reconfigure_on_crash() is not complete, mac80211 send a hw scan request to ath11k, it leads firmware crash, because firmware has not been initialized at that moment, firmware is only finished downloaded and loaded, it can not receive scan command. Tested-on: WCN6855 hw2.0 PCI WLAN.HSP.1.1-03003-QCAHSPSWPL_V1_V2_SILICONZ_LITE-2 Signed-off-by: Wen Gong Signed-off-by: Kalle Valo Link: https://lore.kernel.org/r/20220228064606.8981-3-quic_wgong@quicinc.com --- drivers/net/wireless/ath/ath11k/core.c | 51 ++++++++++++++++++++++---- drivers/net/wireless/ath/ath11k/core.h | 5 +++ drivers/net/wireless/ath/ath11k/mac.c | 22 +++++++++++ 3 files changed, 70 insertions(+), 8 deletions(-) diff --git a/drivers/net/wireless/ath/ath11k/core.c b/drivers/net/wireless/ath/ath11k/core.c index 97ee3dd230ed1..612efaeabcf4a 100644 --- a/drivers/net/wireless/ath/ath11k/core.c +++ b/drivers/net/wireless/ath/ath11k/core.c @@ -1302,12 +1302,11 @@ static void ath11k_update_11d(struct work_struct *work) } } -static void ath11k_core_restart(struct work_struct *work) +static void ath11k_core_pre_reconfigure_recovery(struct ath11k_base *ab) { - struct ath11k_base *ab = container_of(work, struct ath11k_base, restart_work); struct ath11k *ar; struct ath11k_pdev *pdev; - int i, ret = 0; + int i; spin_lock_bh(&ab->base_lock); ab->stats.fw_crash_counter++; @@ -1340,12 +1339,13 @@ static void ath11k_core_restart(struct work_struct *work) wake_up(&ab->wmi_ab.tx_credits_wq); wake_up(&ab->peer_mapping_wq); +} - ret = ath11k_core_reconfigure_on_crash(ab); - if (ret) { - ath11k_err(ab, "failed to reconfigure driver on crash recovery\n"); - return; - } +static void ath11k_core_post_reconfigure_recovery(struct ath11k_base *ab) +{ + struct ath11k *ar; + struct ath11k_pdev *pdev; + int i; for (i = 0; i < ab->num_radios; i++) { pdev = &ab->pdevs[i]; @@ -1381,6 +1381,27 @@ static void ath11k_core_restart(struct work_struct *work) complete(&ab->driver_recovery); } +static void ath11k_core_restart(struct work_struct *work) +{ + struct ath11k_base *ab = container_of(work, struct ath11k_base, restart_work); + int ret; + + if (!ab->is_reset) + ath11k_core_pre_reconfigure_recovery(ab); + + ret = ath11k_core_reconfigure_on_crash(ab); + if (ret) { + ath11k_err(ab, "failed to reconfigure driver on crash recovery\n"); + return; + } + + if (ab->is_reset) + complete_all(&ab->reconfigure_complete); + + if (!ab->is_reset) + ath11k_core_post_reconfigure_recovery(ab); +} + static void ath11k_core_reset(struct work_struct *work) { struct ath11k_base *ab = container_of(work, struct ath11k_base, reset_work); @@ -1432,6 +1453,18 @@ static void ath11k_core_reset(struct work_struct *work) ab->is_reset = true; atomic_set(&ab->recovery_count, 0); + reinit_completion(&ab->recovery_start); + atomic_set(&ab->recovery_start_count, 0); + + ath11k_core_pre_reconfigure_recovery(ab); + + reinit_completion(&ab->reconfigure_complete); + ath11k_core_post_reconfigure_recovery(ab); + + ath11k_dbg(ab, ATH11K_DBG_BOOT, "waiting recovery start...\n"); + + time_left = wait_for_completion_timeout(&ab->recovery_start, + ATH11K_RECOVER_START_TIMEOUT_HZ); ath11k_hif_power_down(ab); ath11k_qmi_free_resource(ab); @@ -1540,6 +1573,8 @@ struct ath11k_base *ath11k_core_alloc(struct device *dev, size_t priv_size, spin_lock_init(&ab->base_lock); mutex_init(&ab->vdev_id_11d_lock); init_completion(&ab->reset_complete); + init_completion(&ab->reconfigure_complete); + init_completion(&ab->recovery_start); INIT_LIST_HEAD(&ab->peers); init_waitqueue_head(&ab->peer_mapping_wq); diff --git a/drivers/net/wireless/ath/ath11k/core.h b/drivers/net/wireless/ath/ath11k/core.h index bd31413d84ca3..70eb6e418422c 100644 --- a/drivers/net/wireless/ath/ath11k/core.h +++ b/drivers/net/wireless/ath/ath11k/core.h @@ -44,6 +44,8 @@ extern unsigned int ath11k_frame_mode; #define ATH11K_RESET_MAX_FAIL_COUNT_FIRST 3 #define ATH11K_RESET_MAX_FAIL_COUNT_FINAL 5 #define ATH11K_RESET_FAIL_TIMEOUT_HZ (20 * HZ) +#define ATH11K_RECONFIGURE_TIMEOUT_HZ (10 * HZ) +#define ATH11K_RECOVER_START_TIMEOUT_HZ (20 * HZ) enum ath11k_supported_bw { ATH11K_BW_20 = 0, @@ -828,8 +830,11 @@ struct ath11k_base { struct work_struct reset_work; atomic_t reset_count; atomic_t recovery_count; + atomic_t recovery_start_count; bool is_reset; struct completion reset_complete; + struct completion reconfigure_complete; + struct completion recovery_start; /* continuous recovery fail count */ atomic_t fail_cont_count; unsigned long reset_fail_timeout; diff --git a/drivers/net/wireless/ath/ath11k/mac.c b/drivers/net/wireless/ath/ath11k/mac.c index f2979dc00fdb3..34a62933ccd27 100644 --- a/drivers/net/wireless/ath/ath11k/mac.c +++ b/drivers/net/wireless/ath/ath11k/mac.c @@ -5749,6 +5749,27 @@ static int ath11k_mac_config_mon_status_default(struct ath11k *ar, bool enable) return ret; } +static void ath11k_mac_wait_reconfigure(struct ath11k_base *ab) +{ + int recovery_start_count; + + if (!ab->is_reset) + return; + + recovery_start_count = atomic_inc_return(&ab->recovery_start_count); + ath11k_dbg(ab, ATH11K_DBG_MAC, "recovery start count %d\n", recovery_start_count); + + if (recovery_start_count == ab->num_radios) { + complete(&ab->recovery_start); + ath11k_dbg(ab, ATH11K_DBG_MAC, "recovery started success\n"); + } + + ath11k_dbg(ab, ATH11K_DBG_MAC, "waiting reconfigure...\n"); + + wait_for_completion_timeout(&ab->reconfigure_complete, + ATH11K_RECONFIGURE_TIMEOUT_HZ); +} + static int ath11k_mac_op_start(struct ieee80211_hw *hw) { struct ath11k *ar = hw->priv; @@ -5765,6 +5786,7 @@ static int ath11k_mac_op_start(struct ieee80211_hw *hw) break; case ATH11K_STATE_RESTARTING: ar->state = ATH11K_STATE_RESTARTED; + ath11k_mac_wait_reconfigure(ab); break; case ATH11K_STATE_RESTARTED: case ATH11K_STATE_WEDGED: From 78e3e6094220a71504e7136c42b49fc8ed3a72b4 Mon Sep 17 00:00:00 2001 From: Wen Gong Date: Mon, 21 Mar 2022 13:17:03 +0200 Subject: [PATCH 018/228] ath11k: Add hw-restart option to simulate_fw_crash Add hw-restart to directly restart wlan. Like UTF mode start it will restart hardware and download firmware again. Usage: 1. Run command: echo hw-restart > /sys/kernel/debug/ath11k/qca6390\ hw2.0/simulate_fw_crash echo hw-restart > /sys/kernel/debug/ath11k/wcn6855\ hw2.0/simulate_fw_crash 2. wlan will be restart and do recovery process and success. Tested-on: WCN6855 hw2.0 PCI WLAN.HSP.1.1-03003-QCAHSPSWPL_V1_V2_SILICONZ_LITE-2 Signed-off-by: Wen Gong Signed-off-by: Kalle Valo Link: https://lore.kernel.org/r/20220228064606.8981-4-quic_wgong@quicinc.com --- drivers/net/wireless/ath/ath11k/debugfs.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/drivers/net/wireless/ath/ath11k/debugfs.c b/drivers/net/wireless/ath/ath11k/debugfs.c index a82266c8befc9..9648e00173936 100644 --- a/drivers/net/wireless/ath/ath11k/debugfs.c +++ b/drivers/net/wireless/ath/ath11k/debugfs.c @@ -596,6 +596,10 @@ static ssize_t ath11k_write_simulate_fw_crash(struct file *file, ret = ath11k_wmi_force_fw_hang_cmd(ar, ATH11K_WMI_FW_HANG_ASSERT_TYPE, ATH11K_WMI_FW_HANG_DELAY); + } else if (!strcmp(buf, "hw-restart")) { + ath11k_info(ab, "user requested hw restart\n"); + queue_work(ab->workqueue_aux, &ab->reset_work); + ret = 0; } else { ret = -EINVAL; goto exit; From 0d7a8a6204ea9271f1d0a8c66a9fd2f54d2e3cbc Mon Sep 17 00:00:00 2001 From: Wen Gong Date: Mon, 21 Mar 2022 13:17:08 +0200 Subject: [PATCH 019/228] ath11k: fix the warning of dev_wake in mhi_pm_disable_transition() When test device recovery with below command, it has warning in message as below. echo assert > /sys/kernel/debug/ath11k/wcn6855\ hw2.0/simulate_fw_crash echo assert > /sys/kernel/debug/ath11k/qca6390\ hw2.0/simulate_fw_crash warning message: [ 1965.642121] ath11k_pci 0000:06:00.0: simulating firmware assert crash [ 1968.471364] ieee80211 phy0: Hardware restart was requested [ 1968.511305] ------------[ cut here ]------------ [ 1968.511368] WARNING: CPU: 3 PID: 1546 at drivers/bus/mhi/core/pm.c:505 mhi_pm_disable_transition+0xb37/0xda0 [mhi] [ 1968.511443] Modules linked in: ath11k_pci ath11k mac80211 libarc4 cfg80211 qmi_helpers qrtr_mhi mhi qrtr nvme nvme_core [ 1968.511563] CPU: 3 PID: 1546 Comm: kworker/u17:0 Kdump: loaded Tainted: G W 5.17.0-rc3-wt-ath+ #579 [ 1968.511629] Hardware name: Intel(R) Client Systems NUC8i7HVK/NUC8i7HVB, BIOS HNKBLi70.86A.0067.2021.0528.1339 05/28/2021 [ 1968.511704] Workqueue: mhi_hiprio_wq mhi_pm_st_worker [mhi] [ 1968.511787] RIP: 0010:mhi_pm_disable_transition+0xb37/0xda0 [mhi] [ 1968.511870] Code: a9 fe ff ff 4c 89 ff 44 89 04 24 e8 03 46 f6 e5 44 8b 04 24 41 83 f8 01 0f 84 21 fe ff ff e9 4c fd ff ff 0f 0b e9 af f8 ff ff <0f> 0b e9 5c f8 ff ff 48 89 df e8 da 9e ee e3 e9 12 fd ff ff 4c 89 [ 1968.511923] RSP: 0018:ffffc900024efbf0 EFLAGS: 00010286 [ 1968.511969] RAX: 00000000ffffffff RBX: ffff88811d241250 RCX: ffffffffc0176922 [ 1968.512014] RDX: 0000000000000000 RSI: 0000000000000004 RDI: ffff888118a90a24 [ 1968.512059] RBP: ffff888118a90800 R08: 0000000000000000 R09: ffff888118a90a27 [ 1968.512102] R10: ffffed1023152144 R11: 0000000000000001 R12: ffff888118a908ac [ 1968.512229] R13: ffff888118a90928 R14: dffffc0000000000 R15: ffff888118a90a24 [ 1968.512310] FS: 0000000000000000(0000) GS:ffff888234200000(0000) knlGS:0000000000000000 [ 1968.512405] CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033 [ 1968.512493] CR2: 00007f5538f443a8 CR3: 000000016dc28001 CR4: 00000000003706e0 [ 1968.512587] Call Trace: [ 1968.512672] [ 1968.512751] ? _raw_spin_unlock_irq+0x1f/0x40 [ 1968.512859] mhi_pm_st_worker+0x3ac/0x790 [mhi] [ 1968.512959] ? mhi_pm_mission_mode_transition.isra.0+0x7d0/0x7d0 [mhi] [ 1968.513063] process_one_work+0x86a/0x1400 [ 1968.513184] ? pwq_dec_nr_in_flight+0x230/0x230 [ 1968.513312] ? move_linked_works+0x125/0x290 [ 1968.513416] worker_thread+0x6db/0xf60 [ 1968.513536] ? process_one_work+0x1400/0x1400 [ 1968.513627] kthread+0x241/0x2d0 [ 1968.513733] ? kthread_complete_and_exit+0x20/0x20 [ 1968.513821] ret_from_fork+0x22/0x30 [ 1968.513924] Reason is mhi_deassert_dev_wake() from mhi_device_put() is called but mhi_assert_dev_wake() from __mhi_device_get_sync() is not called in progress of recovery. Commit 8e0559921f9a ("bus: mhi: core: Skip device wake in error or shutdown state") add check for the pm_state of mhi in __mhi_device_get_sync(), and the pm_state is not the normal state untill recovery is completed, so it leads the dev_wake is not 0 and above warning print in mhi_pm_disable_transition() while checking mhi_cntrl->dev_wake. Add check in ath11k_pci_write32()/ath11k_pci_read32() to skip call mhi_device_put() if mhi_device_get_sync() does not really do wake, then the warning gone. Tested-on: WCN6855 hw2.0 PCI WLAN.HSP.1.1-03003-QCAHSPSWPL_V1_V2_SILICONZ_LITE-2 Signed-off-by: Wen Gong Signed-off-by: Kalle Valo Link: https://lore.kernel.org/r/20220228064606.8981-5-quic_wgong@quicinc.com --- drivers/net/wireless/ath/ath11k/pci.c | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/drivers/net/wireless/ath/ath11k/pci.c b/drivers/net/wireless/ath/ath11k/pci.c index 903758751c99a..8a3ff12057e89 100644 --- a/drivers/net/wireless/ath/ath11k/pci.c +++ b/drivers/net/wireless/ath/ath11k/pci.c @@ -191,6 +191,7 @@ void ath11k_pci_write32(struct ath11k_base *ab, u32 offset, u32 value) { struct ath11k_pci *ab_pci = ath11k_pci_priv(ab); u32 window_start; + int ret = 0; /* for offset beyond BAR + 4K - 32, may * need to wakeup MHI to access. @@ -198,7 +199,7 @@ void ath11k_pci_write32(struct ath11k_base *ab, u32 offset, u32 value) if (ab->hw_params.wakeup_mhi && test_bit(ATH11K_PCI_FLAG_INIT_DONE, &ab_pci->flags) && offset >= ACCESS_ALWAYS_OFF) - mhi_device_get_sync(ab_pci->mhi_ctrl->mhi_dev); + ret = mhi_device_get_sync(ab_pci->mhi_ctrl->mhi_dev); if (offset < WINDOW_START) { iowrite32(value, ab->mem + offset); @@ -222,7 +223,8 @@ void ath11k_pci_write32(struct ath11k_base *ab, u32 offset, u32 value) if (ab->hw_params.wakeup_mhi && test_bit(ATH11K_PCI_FLAG_INIT_DONE, &ab_pci->flags) && - offset >= ACCESS_ALWAYS_OFF) + offset >= ACCESS_ALWAYS_OFF && + !ret) mhi_device_put(ab_pci->mhi_ctrl->mhi_dev); } @@ -230,6 +232,7 @@ u32 ath11k_pci_read32(struct ath11k_base *ab, u32 offset) { struct ath11k_pci *ab_pci = ath11k_pci_priv(ab); u32 val, window_start; + int ret = 0; /* for offset beyond BAR + 4K - 32, may * need to wakeup MHI to access. @@ -237,7 +240,7 @@ u32 ath11k_pci_read32(struct ath11k_base *ab, u32 offset) if (ab->hw_params.wakeup_mhi && test_bit(ATH11K_PCI_FLAG_INIT_DONE, &ab_pci->flags) && offset >= ACCESS_ALWAYS_OFF) - mhi_device_get_sync(ab_pci->mhi_ctrl->mhi_dev); + ret = mhi_device_get_sync(ab_pci->mhi_ctrl->mhi_dev); if (offset < WINDOW_START) { val = ioread32(ab->mem + offset); @@ -261,7 +264,8 @@ u32 ath11k_pci_read32(struct ath11k_base *ab, u32 offset) if (ab->hw_params.wakeup_mhi && test_bit(ATH11K_PCI_FLAG_INIT_DONE, &ab_pci->flags) && - offset >= ACCESS_ALWAYS_OFF) + offset >= ACCESS_ALWAYS_OFF && + !ret) mhi_device_put(ab_pci->mhi_ctrl->mhi_dev); return val; From 1e4ac7173c9394de7f54a4a861377ac3f030c614 Mon Sep 17 00:00:00 2001 From: Baochen Qiang Date: Mon, 11 Oct 2021 13:56:02 +0800 Subject: [PATCH 020/228] ath11k: enable PLATFORM_CAP_PCIE_GLOBAL_RESET QMI host capability In Qualcomm ARM platforms there is WL_EN pin and other power regulators which can be controlled at platform side to completely reset the chip. For most of x86 and other platforms, the chip is connected via PCIe M.2 interface, and there is no way to control WL_EN pin. Instead the host driver needs to reset the chip via PCIE_SOC_GLOBAL_RESET hardware register, just like ath11k does currently. But when using PCIE_SOC_GLOBAL_RESET there are some hardware registers which are not cleared/restored. To handle those cases we can enable PLATFORM_CAP_PCIE_GLOBAL_RESET QMI host capability to tell the firmware to do some platform specific operations after firmware download. This does not fix any known issues, but is recommended by the firmware team, so enable the capability on QCA6390 and WCN6855 PCI devices. It is currently unclear if this should be enabled also on QCN9074, so leave it disabled for now. On AHB devices this is not needed as they don't use PCIE_SOC_GLOBAL_RESET. Tested-on: WCN6855 hw2.0 PCI WLAN.HSP.1.1-01720.1-QCAHSPSWPL_V1_V2_SILICONZ_LITE-1 Signed-off-by: Baochen Qiang Signed-off-by: Kalle Valo Link: https://lore.kernel.org/r/20211011055602.77342-1-bqiang@codeaurora.org --- drivers/net/wireless/ath/ath11k/core.c | 6 ++++++ drivers/net/wireless/ath/ath11k/hw.h | 1 + drivers/net/wireless/ath/ath11k/qmi.c | 4 ++++ 3 files changed, 11 insertions(+) diff --git a/drivers/net/wireless/ath/ath11k/core.c b/drivers/net/wireless/ath/ath11k/core.c index 612efaeabcf4a..9cfba73b9e221 100644 --- a/drivers/net/wireless/ath/ath11k/core.c +++ b/drivers/net/wireless/ath/ath11k/core.c @@ -100,6 +100,7 @@ static const struct ath11k_hw_params ath11k_hw_params[] = { .fw_wmi_diag_event = false, .current_cc_support = false, .dbr_debug_support = true, + .global_reset = false, }, { .hw_rev = ATH11K_HW_IPQ6018_HW10, @@ -166,6 +167,7 @@ static const struct ath11k_hw_params ath11k_hw_params[] = { .fw_wmi_diag_event = false, .current_cc_support = false, .dbr_debug_support = true, + .global_reset = false, }, { .name = "qca6390 hw2.0", @@ -231,6 +233,7 @@ static const struct ath11k_hw_params ath11k_hw_params[] = { .fw_wmi_diag_event = true, .current_cc_support = true, .dbr_debug_support = false, + .global_reset = true, }, { .name = "qcn9074 hw1.0", @@ -296,6 +299,7 @@ static const struct ath11k_hw_params ath11k_hw_params[] = { .fw_wmi_diag_event = false, .current_cc_support = false, .dbr_debug_support = true, + .global_reset = false, }, { .name = "wcn6855 hw2.0", @@ -361,6 +365,7 @@ static const struct ath11k_hw_params ath11k_hw_params[] = { .fw_wmi_diag_event = true, .current_cc_support = true, .dbr_debug_support = false, + .global_reset = true, }, { .name = "wcn6855 hw2.1", @@ -425,6 +430,7 @@ static const struct ath11k_hw_params ath11k_hw_params[] = { .fw_wmi_diag_event = true, .current_cc_support = true, .dbr_debug_support = false, + .global_reset = true, }, }; diff --git a/drivers/net/wireless/ath/ath11k/hw.h b/drivers/net/wireless/ath/ath11k/hw.h index 1c701e16a3b55..5955c6f5da245 100644 --- a/drivers/net/wireless/ath/ath11k/hw.h +++ b/drivers/net/wireless/ath/ath11k/hw.h @@ -194,6 +194,7 @@ struct ath11k_hw_params { bool fw_wmi_diag_event; bool current_cc_support; bool dbr_debug_support; + bool global_reset; }; struct ath11k_hw_ops { diff --git a/drivers/net/wireless/ath/ath11k/qmi.c b/drivers/net/wireless/ath/ath11k/qmi.c index ec110fe81378a..ffb8aa7dfb02d 100644 --- a/drivers/net/wireless/ath/ath11k/qmi.c +++ b/drivers/net/wireless/ath/ath11k/qmi.c @@ -15,6 +15,7 @@ #define SLEEP_CLOCK_SELECT_INTERNAL_BIT 0x02 #define HOST_CSTATE_BIT 0x04 +#define PLATFORM_CAP_PCIE_GLOBAL_RESET 0x08 #define FW_BUILD_ID_MASK "QC_IMAGE_VERSION_STRING=" @@ -1676,6 +1677,9 @@ static int ath11k_qmi_host_cap_send(struct ath11k_base *ab) req.nm_modem |= SLEEP_CLOCK_SELECT_INTERNAL_BIT; } + if (ab->hw_params.global_reset) + req.nm_modem |= PLATFORM_CAP_PCIE_GLOBAL_RESET; + ath11k_dbg(ab, ATH11K_DBG_QMI, "qmi host cap request\n"); ret = qmi_txn_init(&ab->qmi.handle, &txn, From 62abdc06c50eb18e3fa62f7136e66842a96f6b58 Mon Sep 17 00:00:00 2001 From: Wen Gong Date: Wed, 23 Mar 2022 11:14:16 +0200 Subject: [PATCH 021/228] ath11k: add fallback board name without variant while searching board-2.bin Sometimes it has a variant value which read from DT or SMBIOS by ath11k, and meanwhile it does not have the matched board name in board-2.bin, then it will failed at boot up phase. Add fallback board name which removed variant value and search again in board-2.bin when failed with variant and try to load the board data again to increase boot up success rate. dmesg log after this patch: [169547.248472] ath11k_pci 0000:05:00.0: boot using board name 'bus=pci,vendor=17cb,device=1103,subsystem-vendor=17cb,subsystem-device=3374,qmi-chip-id=2,qmi-board-id=262,variant=test' [169547.248565] ath11k_pci 0000:05:00.0: boot firmware request ath11k/WCN6855/hw2.0/board-2.bin size 180324 [169547.248568] ath11k_pci 0000:05:00.0: board name [169547.248570] ath11k_pci 0000:05:00.0: 00000000: 62 75 73 3d 70 63 69 2c 76 65 6e 64 6f 72 3d 31 bus=pci,vendor=1 [169547.248571] ath11k_pci 0000:05:00.0: 00000010: 37 63 62 2c 64 65 76 69 63 65 3d 31 31 30 33 2c 7cb,device=1103, [169547.248572] ath11k_pci 0000:05:00.0: 00000020: 73 75 62 73 79 73 74 65 6d 2d 76 65 6e 64 6f 72 subsystem-vendor [169547.248574] ath11k_pci 0000:05:00.0: 00000030: 3d 31 37 63 62 2c 73 75 62 73 79 73 74 65 6d 2d =17cb,subsystem- [169547.248575] ath11k_pci 0000:05:00.0: 00000040: 64 65 76 69 63 65 3d 33 33 37 34 2c 71 6d 69 2d device=3374,qmi- [169547.248576] ath11k_pci 0000:05:00.0: 00000050: 63 68 69 70 2d 69 64 3d 32 2c 71 6d 69 2d 62 6f chip-id=2,qmi-bo [169547.248577] ath11k_pci 0000:05:00.0: 00000060: 61 72 64 2d 69 64 3d 32 36 32 ard-id=262 [169547.248578] ath11k_pci 0000:05:00.0: board name [169547.248579] ath11k_pci 0000:05:00.0: 00000000: 62 75 73 3d 70 63 69 2c 76 65 6e 64 6f 72 3d 31 bus=pci,vendor=1 [169547.248581] ath11k_pci 0000:05:00.0: 00000010: 37 63 62 2c 64 65 76 69 63 65 3d 31 31 30 33 2c 7cb,device=1103, [169547.248582] ath11k_pci 0000:05:00.0: 00000020: 73 75 62 73 79 73 74 65 6d 2d 76 65 6e 64 6f 72 subsystem-vendor [169547.248583] ath11k_pci 0000:05:00.0: 00000030: 3d 31 37 63 62 2c 73 75 62 73 79 73 74 65 6d 2d =17cb,subsystem- [169547.248584] ath11k_pci 0000:05:00.0: 00000040: 64 65 76 69 63 65 3d 33 33 37 34 2c 71 6d 69 2d device=3374,qmi- [169547.248585] ath11k_pci 0000:05:00.0: 00000050: 63 68 69 70 2d 69 64 3d 32 2c 71 6d 69 2d 62 6f chip-id=2,qmi-bo [169547.248587] ath11k_pci 0000:05:00.0: 00000060: 61 72 64 2d 69 64 3d 32 36 36 ard-id=266 [169547.248588] ath11k_pci 0000:05:00.0: board name [169547.248589] ath11k_pci 0000:05:00.0: 00000000: 62 75 73 3d 70 63 69 2c 76 65 6e 64 6f 72 3d 31 bus=pci,vendor=1 [169547.248590] ath11k_pci 0000:05:00.0: 00000010: 37 63 62 2c 64 65 76 69 63 65 3d 31 31 30 33 2c 7cb,device=1103, [169547.248591] ath11k_pci 0000:05:00.0: 00000020: 73 75 62 73 79 73 74 65 6d 2d 76 65 6e 64 6f 72 subsystem-vendor [169547.248592] ath11k_pci 0000:05:00.0: 00000030: 3d 31 37 63 62 2c 73 75 62 73 79 73 74 65 6d 2d =17cb,subsystem- [169547.248594] ath11k_pci 0000:05:00.0: 00000040: 64 65 76 69 63 65 3d 33 33 37 34 2c 71 6d 69 2d device=3374,qmi- [169547.248595] ath11k_pci 0000:05:00.0: 00000050: 63 68 69 70 2d 69 64 3d 31 38 2c 71 6d 69 2d 62 chip-id=18,qmi-b [169547.248596] ath11k_pci 0000:05:00.0: 00000060: 6f 61 72 64 2d 69 64 3d 32 36 36 oard-id=266 [169547.248597] ath11k_pci 0000:05:00.0: failed to fetch board data for bus=pci,vendor=17cb,device=1103,subsystem-vendor=17cb,subsystem-device=3374,qmi-chip-id=2,qmi-board-id=262,variant=test from ath11k/WCN6855/hw2.0/board-2.bin [169547.248476] ath11k_pci 0000:05:00.0: boot using board name 'bus=pci,vendor=17cb,device=1103,subsystem-vendor=17cb,subsystem-device=3374,qmi-chip-id=2,qmi-board-id=262' [169547.248634] ath11k_pci 0000:05:00.0: boot firmware request ath11k/WCN6855/hw2.0/board-2.bin size 180324 [169547.248636] ath11k_pci 0000:05:00.0: board name [169547.248637] ath11k_pci 0000:05:00.0: 00000000: 62 75 73 3d 70 63 69 2c 76 65 6e 64 6f 72 3d 31 bus=pci,vendor=1 [169547.248638] ath11k_pci 0000:05:00.0: 00000010: 37 63 62 2c 64 65 76 69 63 65 3d 31 31 30 33 2c 7cb,device=1103, [169547.248639] ath11k_pci 0000:05:00.0: 00000020: 73 75 62 73 79 73 74 65 6d 2d 76 65 6e 64 6f 72 subsystem-vendor [169547.248641] ath11k_pci 0000:05:00.0: 00000030: 3d 31 37 63 62 2c 73 75 62 73 79 73 74 65 6d 2d =17cb,subsystem- [169547.248642] ath11k_pci 0000:05:00.0: 00000040: 64 65 76 69 63 65 3d 33 33 37 34 2c 71 6d 69 2d device=3374,qmi- [169547.248643] ath11k_pci 0000:05:00.0: 00000050: 63 68 69 70 2d 69 64 3d 32 2c 71 6d 69 2d 62 6f chip-id=2,qmi-bo [169547.248645] ath11k_pci 0000:05:00.0: 00000060: 61 72 64 2d 69 64 3d 32 36 32 ard-id=262 [169547.248646] ath11k_pci 0000:05:00.0: boot found match for name 'bus=pci,vendor=17cb,device=1103,subsystem-vendor=17cb,subsystem-device=3374,qmi-chip-id=2,qmi-board-id=262' [169547.248647] ath11k_pci 0000:05:00.0: boot found board data for 'bus=pci,vendor=17cb,device=1103,subsystem-vendor=17cb,subsystem-device=3374,qmi-chip-id=2,qmi-board-id=262' [169547.248649] ath11k_pci 0000:05:00.0: using board api 2 Tested-on: WCN6855 hw2.0 PCI WLAN.HSP.1.1-03125-QCAHSPSWPL_V1_V2_SILICONZ_LITE-3 Signed-off-by: Wen Gong Signed-off-by: Kalle Valo Link: https://lore.kernel.org/r/20220315104721.26649-2-quic_wgong@quicinc.com --- drivers/net/wireless/ath/ath11k/core.c | 48 ++++++++++++++++++++++---- 1 file changed, 41 insertions(+), 7 deletions(-) diff --git a/drivers/net/wireless/ath/ath11k/core.c b/drivers/net/wireless/ath/ath11k/core.c index 9cfba73b9e221..6e7f952b315d1 100644 --- a/drivers/net/wireless/ath/ath11k/core.c +++ b/drivers/net/wireless/ath/ath11k/core.c @@ -571,13 +571,13 @@ int ath11k_core_check_dt(struct ath11k_base *ab) return 0; } -static int ath11k_core_create_board_name(struct ath11k_base *ab, char *name, - size_t name_len) +static int __ath11k_core_create_board_name(struct ath11k_base *ab, char *name, + size_t name_len, bool with_variant) { /* strlen(',variant=') + strlen(ab->qmi.target.bdf_ext) */ char variant[9 + ATH11K_QMI_BDF_EXT_STR_LENGTH] = { 0 }; - if (ab->qmi.target.bdf_ext[0] != '\0') + if (with_variant && ab->qmi.target.bdf_ext[0] != '\0') scnprintf(variant, sizeof(variant), ",variant=%s", ab->qmi.target.bdf_ext); @@ -607,6 +607,18 @@ static int ath11k_core_create_board_name(struct ath11k_base *ab, char *name, return 0; } +static int ath11k_core_create_board_name(struct ath11k_base *ab, char *name, + size_t name_len) +{ + return __ath11k_core_create_board_name(ab, name, name_len, true); +} + +static int ath11k_core_create_fallback_board_name(struct ath11k_base *ab, char *name, + size_t name_len) +{ + return __ath11k_core_create_board_name(ab, name, name_len, false); +} + const struct firmware *ath11k_core_firmware_request(struct ath11k_base *ab, const char *file) { @@ -810,7 +822,7 @@ static int ath11k_core_fetch_board_data_api_n(struct ath11k_base *ab, out: if (!bd->data || !bd->len) { - ath11k_err(ab, + ath11k_dbg(ab, ATH11K_DBG_BOOT, "failed to fetch board data for %s from %s\n", boardname, filepath); ret = -ENODATA; @@ -842,10 +854,13 @@ int ath11k_core_fetch_board_data_api_1(struct ath11k_base *ab, #define BOARD_NAME_SIZE 200 int ath11k_core_fetch_bdf(struct ath11k_base *ab, struct ath11k_board_data *bd) { - char boardname[BOARD_NAME_SIZE]; + char boardname[BOARD_NAME_SIZE], fallback_boardname[BOARD_NAME_SIZE]; + char *filename, filepath[100]; int ret; - ret = ath11k_core_create_board_name(ab, boardname, BOARD_NAME_SIZE); + filename = ATH11K_BOARD_API2_FILE; + + ret = ath11k_core_create_board_name(ab, boardname, sizeof(boardname)); if (ret) { ath11k_err(ab, "failed to create board name: %d", ret); return ret; @@ -856,10 +871,29 @@ int ath11k_core_fetch_bdf(struct ath11k_base *ab, struct ath11k_board_data *bd) if (!ret) goto success; + ret = ath11k_core_create_fallback_board_name(ab, fallback_boardname, + sizeof(fallback_boardname)); + if (ret) { + ath11k_err(ab, "failed to create fallback board name: %d", ret); + return ret; + } + + ret = ath11k_core_fetch_board_data_api_n(ab, bd, fallback_boardname); + if (!ret) + goto success; + ab->bd_api = 1; ret = ath11k_core_fetch_board_data_api_1(ab, bd, ATH11K_DEFAULT_BOARD_FILE); if (ret) { - ath11k_err(ab, "failed to fetch board-2.bin or board.bin from %s\n", + ath11k_core_create_firmware_path(ab, filename, + filepath, sizeof(filepath)); + ath11k_err(ab, "failed to fetch board data for %s from %s\n", + boardname, filepath); + if (memcmp(boardname, fallback_boardname, strlen(boardname))) + ath11k_err(ab, "failed to fetch board data for %s from %s\n", + fallback_boardname, filepath); + + ath11k_err(ab, "failed to fetch board.bin from %s\n", ab->hw_params.fw.dir); return ret; } From 9d97114d222047c0699bbdbf8f128907f423bbe6 Mon Sep 17 00:00:00 2001 From: Wen Gong Date: Wed, 23 Mar 2022 11:14:17 +0200 Subject: [PATCH 022/228] ath11k: add read variant from SMBIOS for download board data This is to read variant from SMBIOS such as read from DT, the variant string will be used to one part of string which used to search board data from board-2.bin. Tested-on: WCN6855 hw2.0 PCI WLAN.HSP.1.1-03125-QCAHSPSWPL_V1_V2_SILICONZ_LITE-3 Signed-off-by: Wen Gong Signed-off-by: Kalle Valo Link: https://lore.kernel.org/r/20220315104721.26649-3-quic_wgong@quicinc.com --- drivers/net/wireless/ath/ath11k/core.c | 70 ++++++++++++++++++++++++++ drivers/net/wireless/ath/ath11k/core.h | 20 +++++++- drivers/net/wireless/ath/ath11k/qmi.c | 4 ++ 3 files changed, 93 insertions(+), 1 deletion(-) diff --git a/drivers/net/wireless/ath/ath11k/core.c b/drivers/net/wireless/ath/ath11k/core.c index 6e7f952b315d1..7b91b029074f8 100644 --- a/drivers/net/wireless/ath/ath11k/core.c +++ b/drivers/net/wireless/ath/ath11k/core.c @@ -9,6 +9,7 @@ #include #include #include + #include "core.h" #include "dp_tx.h" #include "dp_rx.h" @@ -548,6 +549,75 @@ int ath11k_core_resume(struct ath11k_base *ab) } EXPORT_SYMBOL(ath11k_core_resume); +static void ath11k_core_check_bdfext(const struct dmi_header *hdr, void *data) +{ + struct ath11k_base *ab = data; + const char *magic = ATH11K_SMBIOS_BDF_EXT_MAGIC; + struct ath11k_smbios_bdf *smbios = (struct ath11k_smbios_bdf *)hdr; + ssize_t copied; + size_t len; + int i; + + if (ab->qmi.target.bdf_ext[0] != '\0') + return; + + if (hdr->type != ATH11K_SMBIOS_BDF_EXT_TYPE) + return; + + if (hdr->length != ATH11K_SMBIOS_BDF_EXT_LENGTH) { + ath11k_dbg(ab, ATH11K_DBG_BOOT, + "wrong smbios bdf ext type length (%d).\n", + hdr->length); + return; + } + + if (!smbios->bdf_enabled) { + ath11k_dbg(ab, ATH11K_DBG_BOOT, "bdf variant name not found.\n"); + return; + } + + /* Only one string exists (per spec) */ + if (memcmp(smbios->bdf_ext, magic, strlen(magic)) != 0) { + ath11k_dbg(ab, ATH11K_DBG_BOOT, + "bdf variant magic does not match.\n"); + return; + } + + len = min_t(size_t, + strlen(smbios->bdf_ext), sizeof(ab->qmi.target.bdf_ext)); + for (i = 0; i < len; i++) { + if (!isascii(smbios->bdf_ext[i]) || !isprint(smbios->bdf_ext[i])) { + ath11k_dbg(ab, ATH11K_DBG_BOOT, + "bdf variant name contains non ascii chars.\n"); + return; + } + } + + /* Copy extension name without magic prefix */ + copied = strscpy(ab->qmi.target.bdf_ext, smbios->bdf_ext + strlen(magic), + sizeof(ab->qmi.target.bdf_ext)); + if (copied < 0) { + ath11k_dbg(ab, ATH11K_DBG_BOOT, + "bdf variant string is longer than the buffer can accommodate\n"); + return; + } + + ath11k_dbg(ab, ATH11K_DBG_BOOT, + "found and validated bdf variant smbios_type 0x%x bdf %s\n", + ATH11K_SMBIOS_BDF_EXT_TYPE, ab->qmi.target.bdf_ext); +} + +int ath11k_core_check_smbios(struct ath11k_base *ab) +{ + ab->qmi.target.bdf_ext[0] = '\0'; + dmi_walk(ath11k_core_check_bdfext, ab); + + if (ab->qmi.target.bdf_ext[0] == '\0') + return -ENODATA; + + return 0; +} + int ath11k_core_check_dt(struct ath11k_base *ab) { size_t max_len = sizeof(ab->qmi.target.bdf_ext); diff --git a/drivers/net/wireless/ath/ath11k/core.h b/drivers/net/wireless/ath/ath11k/core.h index 70eb6e418422c..6b272eb8bb4a3 100644 --- a/drivers/net/wireless/ath/ath11k/core.h +++ b/drivers/net/wireless/ath/ath11k/core.h @@ -10,6 +10,8 @@ #include #include #include +#include +#include #include "qmi.h" #include "htc.h" #include "wmi.h" @@ -37,6 +39,15 @@ #define ATH11K_INVALID_HW_MAC_ID 0xFF #define ATH11K_CONNECTION_LOSS_HZ (3 * HZ) +/* SMBIOS type containing Board Data File Name Extension */ +#define ATH11K_SMBIOS_BDF_EXT_TYPE 0xF8 + +/* SMBIOS type structure length (excluding strings-set) */ +#define ATH11K_SMBIOS_BDF_EXT_LENGTH 0x9 + +/* The magic used by QCA spec */ +#define ATH11K_SMBIOS_BDF_EXT_MAGIC "BDF_" + extern unsigned int ath11k_frame_mode; #define ATH11K_MON_TIMER_INTERVAL 10 @@ -154,6 +165,13 @@ struct ath11k_ext_irq_grp { struct net_device napi_ndev; }; +struct ath11k_smbios_bdf { + struct dmi_header hdr; + u32 padding; + u8 bdf_enabled; + u8 bdf_ext[]; +}; + #define HEHANDLE_CAP_PHYINFO_SIZE 3 #define HECAP_PHYINFO_SIZE 9 #define HECAP_MACINFO_SIZE 5 @@ -1046,7 +1064,7 @@ int ath11k_core_fetch_board_data_api_1(struct ath11k_base *ab, const char *name); void ath11k_core_free_bdf(struct ath11k_base *ab, struct ath11k_board_data *bd); int ath11k_core_check_dt(struct ath11k_base *ath11k); - +int ath11k_core_check_smbios(struct ath11k_base *ab); void ath11k_core_halt(struct ath11k *ar); int ath11k_core_resume(struct ath11k_base *ab); int ath11k_core_suspend(struct ath11k_base *ab); diff --git a/drivers/net/wireless/ath/ath11k/qmi.c b/drivers/net/wireless/ath/ath11k/qmi.c index ffb8aa7dfb02d..0442faa3b7afb 100644 --- a/drivers/net/wireless/ath/ath11k/qmi.c +++ b/drivers/net/wireless/ath/ath11k/qmi.c @@ -2095,6 +2095,10 @@ static int ath11k_qmi_request_target_cap(struct ath11k_base *ab) ab->qmi.target.fw_build_timestamp, fw_build_id); + r = ath11k_core_check_smbios(ab); + if (r) + ath11k_dbg(ab, ATH11K_DBG_QMI, "SMBIOS bdf variant name not set.\n"); + r = ath11k_core_check_dt(ab); if (r) ath11k_dbg(ab, ATH11K_DBG_QMI, "DT bdf variant name not set.\n"); From 7b0c70d92a435913f6e11d6a248b935697e8a3eb Mon Sep 17 00:00:00 2001 From: Karthikeyan Periyasamy Date: Wed, 23 Mar 2022 11:14:17 +0200 Subject: [PATCH 023/228] ath11k: Add peer rhash table support When more clients (128) are connected, the UL data traffic KPI measurement is low compared to single client. This issue is due to more CPU cycles spent on the peer lookup operation with more clients. So reduce the peer lookup operation by modifying the linear based lookup operation into the rhash based lookup operation. This improve the peak throughput measurement. Since this is a software algorithm change, it is applicable for all the platforms. TCP UL 128 Clients test case Observation (64bit system): Previous: ~550 Mbps Now : ~860 Mbps Tested-on: QCN9074 hw1.0 PCI WLAN.HK.2.5.0.1-01067-QCAHKSWPL_SILICONZ-1 Signed-off-by: Karthikeyan Periyasamy Signed-off-by: Kalle Valo Link: https://lore.kernel.org/r/1644036628-5334-1-git-send-email-quic_periyasa@quicinc.com --- drivers/net/wireless/ath/ath11k/core.c | 3 +- drivers/net/wireless/ath/ath11k/core.h | 14 + drivers/net/wireless/ath/ath11k/mac.c | 16 +- drivers/net/wireless/ath/ath11k/peer.c | 344 +++++++++++++++++++++++-- drivers/net/wireless/ath/ath11k/peer.h | 10 +- 5 files changed, 363 insertions(+), 24 deletions(-) diff --git a/drivers/net/wireless/ath/ath11k/core.c b/drivers/net/wireless/ath/ath11k/core.c index 7b91b029074f8..2a867237e8179 100644 --- a/drivers/net/wireless/ath/ath11k/core.c +++ b/drivers/net/wireless/ath/ath11k/core.c @@ -1,7 +1,7 @@ // SPDX-License-Identifier: BSD-3-Clause-Clear /* * Copyright (c) 2018-2019 The Linux Foundation. All rights reserved. - * Copyright (c) 2021 Qualcomm Innovation Center, Inc. All rights reserved. + * Copyright (c) 2021-2022 Qualcomm Innovation Center, Inc. All rights reserved. */ #include @@ -1680,6 +1680,7 @@ struct ath11k_base *ath11k_core_alloc(struct device *dev, size_t priv_size, goto err_free_wq; mutex_init(&ab->core_lock); + mutex_init(&ab->tbl_mtx_lock); spin_lock_init(&ab->base_lock); mutex_init(&ab->vdev_id_11d_lock); init_completion(&ab->reset_complete); diff --git a/drivers/net/wireless/ath/ath11k/core.h b/drivers/net/wireless/ath/ath11k/core.h index 6b272eb8bb4a3..41001ec174e2b 100644 --- a/drivers/net/wireless/ath/ath11k/core.h +++ b/drivers/net/wireless/ath/ath11k/core.h @@ -1,6 +1,7 @@ /* SPDX-License-Identifier: BSD-3-Clause-Clear */ /* * Copyright (c) 2018-2019 The Linux Foundation. All rights reserved. + * Copyright (c) 2021-2022 Qualcomm Innovation Center, Inc. All rights reserved. */ #ifndef ATH11K_CORE_H @@ -12,6 +13,7 @@ #include #include #include +#include #include "qmi.h" #include "htc.h" #include "wmi.h" @@ -803,6 +805,18 @@ struct ath11k_base { struct ath11k_pdev __rcu *pdevs_active[MAX_RADIOS]; struct ath11k_hal_reg_capabilities_ext hal_reg_cap[MAX_RADIOS]; unsigned long long free_vdev_map; + + /* To synchronize rhash tbl write operation */ + struct mutex tbl_mtx_lock; + + /* The rhashtable containing struct ath11k_peer keyed by mac addr */ + struct rhashtable *rhead_peer_addr; + struct rhashtable_params rhash_peer_addr_param; + + /* The rhashtable containing struct ath11k_peer keyed by id */ + struct rhashtable *rhead_peer_id; + struct rhashtable_params rhash_peer_id_param; + struct list_head peers; wait_queue_head_t peer_mapping_wq; u8 mac_addr[ETH_ALEN]; diff --git a/drivers/net/wireless/ath/ath11k/mac.c b/drivers/net/wireless/ath/ath11k/mac.c index 34a62933ccd27..7a7641e8e3259 100644 --- a/drivers/net/wireless/ath/ath11k/mac.c +++ b/drivers/net/wireless/ath/ath11k/mac.c @@ -1,7 +1,7 @@ // SPDX-License-Identifier: BSD-3-Clause-Clear /* * Copyright (c) 2018-2019 The Linux Foundation. All rights reserved. - * Copyright (c) 2021 Qualcomm Innovation Center, Inc. All rights reserved. + * Copyright (c) 2021-2022 Qualcomm Innovation Center, Inc. All rights reserved. */ #include @@ -875,13 +875,16 @@ void ath11k_mac_peer_cleanup_all(struct ath11k *ar) lockdep_assert_held(&ar->conf_mutex); + mutex_lock(&ab->tbl_mtx_lock); spin_lock_bh(&ab->base_lock); list_for_each_entry_safe(peer, tmp, &ab->peers, list) { ath11k_peer_rx_tid_cleanup(ar, peer); + ath11k_peer_rhash_delete(ab, peer); list_del(&peer->list); kfree(peer); } spin_unlock_bh(&ab->base_lock); + mutex_unlock(&ab->tbl_mtx_lock); ar->num_peers = 0; ar->num_stations = 0; @@ -4554,6 +4557,7 @@ static int ath11k_mac_op_sta_state(struct ieee80211_hw *hw, } ath11k_mac_dec_num_stations(arvif, sta); + mutex_lock(&ar->ab->tbl_mtx_lock); spin_lock_bh(&ar->ab->base_lock); peer = ath11k_peer_find(ar->ab, arvif->vdev_id, sta->addr); if (skip_peer_delete && peer) { @@ -4561,12 +4565,14 @@ static int ath11k_mac_op_sta_state(struct ieee80211_hw *hw, } else if (peer && peer->sta == sta) { ath11k_warn(ar->ab, "Found peer entry %pM n vdev %i after it was supposedly removed\n", vif->addr, arvif->vdev_id); + ath11k_peer_rhash_delete(ar->ab, peer); peer->sta = NULL; list_del(&peer->list); kfree(peer); ar->num_peers--; } spin_unlock_bh(&ar->ab->base_lock); + mutex_unlock(&ar->ab->tbl_mtx_lock); kfree(arsta->tx_stats); arsta->tx_stats = NULL; @@ -8574,6 +8580,8 @@ void ath11k_mac_unregister(struct ath11k_base *ab) __ath11k_mac_unregister(ar); } + + ath11k_peer_rhash_tbl_destroy(ab); } static int __ath11k_mac_register(struct ath11k *ar) @@ -8802,6 +8810,10 @@ int ath11k_mac_register(struct ath11k_base *ab) ab->cc_freq_hz = IPQ8074_CC_FREQ_HERTZ; ab->free_vdev_map = (1LL << (ab->num_radios * TARGET_NUM_VDEVS(ab))) - 1; + ret = ath11k_peer_rhash_tbl_init(ab); + if (ret) + return ret; + for (i = 0; i < ab->num_radios; i++) { pdev = &ab->pdevs[i]; ar = pdev->ar; @@ -8831,6 +8843,8 @@ int ath11k_mac_register(struct ath11k_base *ab) __ath11k_mac_unregister(ar); } + ath11k_peer_rhash_tbl_destroy(ab); + return ret; } diff --git a/drivers/net/wireless/ath/ath11k/peer.c b/drivers/net/wireless/ath/ath11k/peer.c index 392985b873bfd..9e22aaf34b88c 100644 --- a/drivers/net/wireless/ath/ath11k/peer.c +++ b/drivers/net/wireless/ath/ath11k/peer.c @@ -1,23 +1,22 @@ // SPDX-License-Identifier: BSD-3-Clause-Clear /* * Copyright (c) 2018-2019 The Linux Foundation. All rights reserved. + * Copyright (c) 2021-2022 Qualcomm Innovation Center, Inc. All rights reserved. */ #include "core.h" #include "peer.h" #include "debug.h" -struct ath11k_peer *ath11k_peer_find(struct ath11k_base *ab, int vdev_id, - const u8 *addr) +static struct ath11k_peer *ath11k_peer_find_list_by_id(struct ath11k_base *ab, + int peer_id) { struct ath11k_peer *peer; lockdep_assert_held(&ab->base_lock); list_for_each_entry(peer, &ab->peers, list) { - if (peer->vdev_id != vdev_id) - continue; - if (!ether_addr_equal(peer->addr, addr)) + if (peer->peer_id != peer_id) continue; return peer; @@ -26,15 +25,15 @@ struct ath11k_peer *ath11k_peer_find(struct ath11k_base *ab, int vdev_id, return NULL; } -static struct ath11k_peer *ath11k_peer_find_by_pdev_idx(struct ath11k_base *ab, - u8 pdev_idx, const u8 *addr) +struct ath11k_peer *ath11k_peer_find(struct ath11k_base *ab, int vdev_id, + const u8 *addr) { struct ath11k_peer *peer; lockdep_assert_held(&ab->base_lock); list_for_each_entry(peer, &ab->peers, list) { - if (peer->pdev_idx != pdev_idx) + if (peer->vdev_id != vdev_id) continue; if (!ether_addr_equal(peer->addr, addr)) continue; @@ -52,14 +51,13 @@ struct ath11k_peer *ath11k_peer_find_by_addr(struct ath11k_base *ab, lockdep_assert_held(&ab->base_lock); - list_for_each_entry(peer, &ab->peers, list) { - if (!ether_addr_equal(peer->addr, addr)) - continue; + if (!ab->rhead_peer_addr) + return NULL; - return peer; - } + peer = rhashtable_lookup_fast(ab->rhead_peer_addr, addr, + ab->rhash_peer_addr_param); - return NULL; + return peer; } struct ath11k_peer *ath11k_peer_find_by_id(struct ath11k_base *ab, @@ -69,11 +67,13 @@ struct ath11k_peer *ath11k_peer_find_by_id(struct ath11k_base *ab, lockdep_assert_held(&ab->base_lock); - list_for_each_entry(peer, &ab->peers, list) - if (peer_id == peer->peer_id) - return peer; + if (!ab->rhead_peer_id) + return NULL; - return NULL; + peer = rhashtable_lookup_fast(ab->rhead_peer_id, &peer_id, + ab->rhash_peer_id_param); + + return peer; } struct ath11k_peer *ath11k_peer_find_by_vdev_id(struct ath11k_base *ab, @@ -99,7 +99,7 @@ void ath11k_peer_unmap_event(struct ath11k_base *ab, u16 peer_id) spin_lock_bh(&ab->base_lock); - peer = ath11k_peer_find_by_id(ab, peer_id); + peer = ath11k_peer_find_list_by_id(ab, peer_id); if (!peer) { ath11k_warn(ab, "peer-unmap-event: unknown peer id %d\n", peer_id); @@ -167,6 +167,76 @@ static int ath11k_wait_for_peer_common(struct ath11k_base *ab, int vdev_id, return 0; } +static inline int ath11k_peer_rhash_insert(struct ath11k_base *ab, + struct rhashtable *rtbl, + struct rhash_head *rhead, + struct rhashtable_params *params, + void *key) +{ + struct ath11k_peer *tmp; + + lockdep_assert_held(&ab->tbl_mtx_lock); + + tmp = rhashtable_lookup_get_insert_fast(rtbl, rhead, *params); + + if (!tmp) + return 0; + else if (IS_ERR(tmp)) + return PTR_ERR(tmp); + else + return -EEXIST; +} + +static inline int ath11k_peer_rhash_remove(struct ath11k_base *ab, + struct rhashtable *rtbl, + struct rhash_head *rhead, + struct rhashtable_params *params) +{ + int ret; + + lockdep_assert_held(&ab->tbl_mtx_lock); + + ret = rhashtable_remove_fast(rtbl, rhead, *params); + if (ret && ret != -ENOENT) + return ret; + + return 0; +} + +static int ath11k_peer_rhash_add(struct ath11k_base *ab, struct ath11k_peer *peer) +{ + int ret; + + lockdep_assert_held(&ab->base_lock); + lockdep_assert_held(&ab->tbl_mtx_lock); + + if (!ab->rhead_peer_id || !ab->rhead_peer_addr) + return -EPERM; + + ret = ath11k_peer_rhash_insert(ab, ab->rhead_peer_id, &peer->rhash_id, + &ab->rhash_peer_id_param, &peer->peer_id); + if (ret) { + ath11k_warn(ab, "failed to add peer %pM with id %d in rhash_id ret %d\n", + peer->addr, peer->peer_id, ret); + return ret; + } + + ret = ath11k_peer_rhash_insert(ab, ab->rhead_peer_addr, &peer->rhash_addr, + &ab->rhash_peer_addr_param, &peer->addr); + if (ret) { + ath11k_warn(ab, "failed to add peer %pM with id %d in rhash_addr ret %d\n", + peer->addr, peer->peer_id, ret); + goto err_clean; + } + + return 0; + +err_clean: + ath11k_peer_rhash_remove(ab, ab->rhead_peer_id, &peer->rhash_id, + &ab->rhash_peer_id_param); + return ret; +} + void ath11k_peer_cleanup(struct ath11k *ar, u32 vdev_id) { struct ath11k_peer *peer, *tmp; @@ -174,6 +244,7 @@ void ath11k_peer_cleanup(struct ath11k *ar, u32 vdev_id) lockdep_assert_held(&ar->conf_mutex); + mutex_lock(&ab->tbl_mtx_lock); spin_lock_bh(&ab->base_lock); list_for_each_entry_safe(peer, tmp, &ab->peers, list) { if (peer->vdev_id != vdev_id) @@ -182,12 +253,14 @@ void ath11k_peer_cleanup(struct ath11k *ar, u32 vdev_id) ath11k_warn(ab, "removing stale peer %pM from vdev_id %d\n", peer->addr, vdev_id); + ath11k_peer_rhash_delete(ab, peer); list_del(&peer->list); kfree(peer); ar->num_peers--; } spin_unlock_bh(&ab->base_lock); + mutex_unlock(&ab->tbl_mtx_lock); } static int ath11k_wait_for_peer_deleted(struct ath11k *ar, int vdev_id, const u8 *addr) @@ -220,14 +293,35 @@ int ath11k_wait_for_peer_delete_done(struct ath11k *ar, u32 vdev_id, static int __ath11k_peer_delete(struct ath11k *ar, u32 vdev_id, const u8 *addr) { int ret; + struct ath11k_peer *peer; + struct ath11k_base *ab = ar->ab; lockdep_assert_held(&ar->conf_mutex); + mutex_lock(&ab->tbl_mtx_lock); + spin_lock_bh(&ab->base_lock); + + peer = ath11k_peer_find_by_addr(ab, addr); + if (!peer) { + spin_unlock_bh(&ab->base_lock); + mutex_unlock(&ab->tbl_mtx_lock); + + ath11k_warn(ab, + "failed to find peer vdev_id %d addr %pM in delete\n", + vdev_id, addr); + return -EINVAL; + } + + ath11k_peer_rhash_delete(ab, peer); + + spin_unlock_bh(&ab->base_lock); + mutex_unlock(&ab->tbl_mtx_lock); + reinit_completion(&ar->peer_delete_done); ret = ath11k_wmi_send_peer_delete_cmd(ar, addr, vdev_id); if (ret) { - ath11k_warn(ar->ab, + ath11k_warn(ab, "failed to delete peer vdev_id %d addr %pM ret %d\n", vdev_id, addr, ret); return ret; @@ -276,7 +370,7 @@ int ath11k_peer_create(struct ath11k *ar, struct ath11k_vif *arvif, } spin_lock_bh(&ar->ab->base_lock); - peer = ath11k_peer_find_by_pdev_idx(ar->ab, ar->pdev_idx, param->peer_addr); + peer = ath11k_peer_find_by_addr(ar->ab, param->peer_addr); if (peer) { spin_unlock_bh(&ar->ab->base_lock); return -EINVAL; @@ -296,11 +390,13 @@ int ath11k_peer_create(struct ath11k *ar, struct ath11k_vif *arvif, if (ret) return ret; + mutex_lock(&ar->ab->tbl_mtx_lock); spin_lock_bh(&ar->ab->base_lock); peer = ath11k_peer_find(ar->ab, param->vdev_id, param->peer_addr); if (!peer) { spin_unlock_bh(&ar->ab->base_lock); + mutex_unlock(&ar->ab->tbl_mtx_lock); ath11k_warn(ar->ab, "failed to find peer %pM on vdev %i after creation\n", param->peer_addr, param->vdev_id); @@ -308,6 +404,13 @@ int ath11k_peer_create(struct ath11k *ar, struct ath11k_vif *arvif, goto cleanup; } + ret = ath11k_peer_rhash_add(ar->ab, peer); + if (ret) { + spin_unlock_bh(&ar->ab->base_lock); + mutex_unlock(&ar->ab->tbl_mtx_lock); + goto cleanup; + } + peer->pdev_idx = ar->pdev_idx; peer->sta = sta; @@ -332,6 +435,7 @@ int ath11k_peer_create(struct ath11k *ar, struct ath11k_vif *arvif, ar->num_peers++; spin_unlock_bh(&ar->ab->base_lock); + mutex_unlock(&ar->ab->tbl_mtx_lock); return 0; @@ -343,3 +447,201 @@ int ath11k_peer_create(struct ath11k *ar, struct ath11k_vif *arvif, return ret; } + +int ath11k_peer_rhash_delete(struct ath11k_base *ab, struct ath11k_peer *peer) +{ + int ret; + + lockdep_assert_held(&ab->base_lock); + lockdep_assert_held(&ab->tbl_mtx_lock); + + if (!ab->rhead_peer_id || !ab->rhead_peer_addr) + return -EPERM; + + ret = ath11k_peer_rhash_remove(ab, ab->rhead_peer_addr, &peer->rhash_addr, + &ab->rhash_peer_addr_param); + if (ret) { + ath11k_warn(ab, "failed to remove peer %pM id %d in rhash_addr ret %d\n", + peer->addr, peer->peer_id, ret); + return ret; + } + + ret = ath11k_peer_rhash_remove(ab, ab->rhead_peer_id, &peer->rhash_id, + &ab->rhash_peer_id_param); + if (ret) { + ath11k_warn(ab, "failed to remove peer %pM id %d in rhash_id ret %d\n", + peer->addr, peer->peer_id, ret); + return ret; + } + + return 0; +} + +static int ath11k_peer_rhash_id_tbl_init(struct ath11k_base *ab) +{ + struct rhashtable_params *param; + struct rhashtable *rhash_id_tbl; + int ret; + size_t size; + + lockdep_assert_held(&ab->tbl_mtx_lock); + + if (ab->rhead_peer_id) + return 0; + + size = sizeof(*ab->rhead_peer_id); + rhash_id_tbl = kzalloc(size, GFP_KERNEL); + if (!rhash_id_tbl) { + ath11k_warn(ab, "failed to init rhash id table due to no mem (size %zu)\n", + size); + return -ENOMEM; + } + + param = &ab->rhash_peer_id_param; + + param->key_offset = offsetof(struct ath11k_peer, peer_id); + param->head_offset = offsetof(struct ath11k_peer, rhash_id); + param->key_len = sizeof_field(struct ath11k_peer, peer_id); + param->automatic_shrinking = true; + param->nelem_hint = ab->num_radios * TARGET_NUM_PEERS_PDEV(ab); + + ret = rhashtable_init(rhash_id_tbl, param); + if (ret) { + ath11k_warn(ab, "failed to init peer id rhash table %d\n", ret); + goto err_free; + } + + spin_lock_bh(&ab->base_lock); + + if (!ab->rhead_peer_id) { + ab->rhead_peer_id = rhash_id_tbl; + } else { + spin_unlock_bh(&ab->base_lock); + goto cleanup_tbl; + } + + spin_unlock_bh(&ab->base_lock); + + return 0; + +cleanup_tbl: + rhashtable_destroy(rhash_id_tbl); +err_free: + kfree(rhash_id_tbl); + + return ret; +} + +static int ath11k_peer_rhash_addr_tbl_init(struct ath11k_base *ab) +{ + struct rhashtable_params *param; + struct rhashtable *rhash_addr_tbl; + int ret; + size_t size; + + lockdep_assert_held(&ab->tbl_mtx_lock); + + if (ab->rhead_peer_addr) + return 0; + + size = sizeof(*ab->rhead_peer_addr); + rhash_addr_tbl = kzalloc(size, GFP_KERNEL); + if (!rhash_addr_tbl) { + ath11k_warn(ab, "failed to init rhash addr table due to no mem (size %zu)\n", + size); + return -ENOMEM; + } + + param = &ab->rhash_peer_addr_param; + + param->key_offset = offsetof(struct ath11k_peer, addr); + param->head_offset = offsetof(struct ath11k_peer, rhash_addr); + param->key_len = sizeof_field(struct ath11k_peer, addr); + param->automatic_shrinking = true; + param->nelem_hint = ab->num_radios * TARGET_NUM_PEERS_PDEV(ab); + + ret = rhashtable_init(rhash_addr_tbl, param); + if (ret) { + ath11k_warn(ab, "failed to init peer addr rhash table %d\n", ret); + goto err_free; + } + + spin_lock_bh(&ab->base_lock); + + if (!ab->rhead_peer_addr) { + ab->rhead_peer_addr = rhash_addr_tbl; + } else { + spin_unlock_bh(&ab->base_lock); + goto cleanup_tbl; + } + + spin_unlock_bh(&ab->base_lock); + + return 0; + +cleanup_tbl: + rhashtable_destroy(rhash_addr_tbl); +err_free: + kfree(rhash_addr_tbl); + + return ret; +} + +static inline void ath11k_peer_rhash_id_tbl_destroy(struct ath11k_base *ab) +{ + lockdep_assert_held(&ab->tbl_mtx_lock); + + if (!ab->rhead_peer_id) + return; + + rhashtable_destroy(ab->rhead_peer_id); + kfree(ab->rhead_peer_id); + ab->rhead_peer_id = NULL; +} + +static inline void ath11k_peer_rhash_addr_tbl_destroy(struct ath11k_base *ab) +{ + lockdep_assert_held(&ab->tbl_mtx_lock); + + if (!ab->rhead_peer_addr) + return; + + rhashtable_destroy(ab->rhead_peer_addr); + kfree(ab->rhead_peer_addr); + ab->rhead_peer_addr = NULL; +} + +int ath11k_peer_rhash_tbl_init(struct ath11k_base *ab) +{ + int ret; + + mutex_lock(&ab->tbl_mtx_lock); + + ret = ath11k_peer_rhash_id_tbl_init(ab); + if (ret) + goto out; + + ret = ath11k_peer_rhash_addr_tbl_init(ab); + if (ret) + goto cleanup_tbl; + + mutex_unlock(&ab->tbl_mtx_lock); + + return 0; + +cleanup_tbl: + ath11k_peer_rhash_id_tbl_destroy(ab); +out: + mutex_unlock(&ab->tbl_mtx_lock); + return ret; +} + +void ath11k_peer_rhash_tbl_destroy(struct ath11k_base *ab) +{ + mutex_lock(&ab->tbl_mtx_lock); + + ath11k_peer_rhash_addr_tbl_destroy(ab); + ath11k_peer_rhash_id_tbl_destroy(ab); + + mutex_unlock(&ab->tbl_mtx_lock); +} diff --git a/drivers/net/wireless/ath/ath11k/peer.h b/drivers/net/wireless/ath/ath11k/peer.h index 63fe5665badf3..6dd17bafe3a0c 100644 --- a/drivers/net/wireless/ath/ath11k/peer.h +++ b/drivers/net/wireless/ath/ath11k/peer.h @@ -1,6 +1,7 @@ /* SPDX-License-Identifier: BSD-3-Clause-Clear */ /* * Copyright (c) 2018-2019 The Linux Foundation. All rights reserved. + * Copyright (c) 2021-2022 Qualcomm Innovation Center, Inc. All rights reserved. */ #ifndef ATH11K_PEER_H @@ -20,6 +21,11 @@ struct ath11k_peer { struct ieee80211_key_conf *keys[WMI_MAX_KEY_INDEX + 1]; struct dp_rx_tid rx_tid[IEEE80211_NUM_TIDS + 1]; + /* peer id based rhashtable list pointer */ + struct rhash_head rhash_id; + /* peer addr based rhashtable list pointer */ + struct rhash_head rhash_addr; + /* Info used in MMIC verification of * RX fragments */ @@ -47,5 +53,7 @@ int ath11k_wait_for_peer_delete_done(struct ath11k *ar, u32 vdev_id, const u8 *addr); struct ath11k_peer *ath11k_peer_find_by_vdev_id(struct ath11k_base *ab, int vdev_id); - +int ath11k_peer_rhash_tbl_init(struct ath11k_base *ab); +void ath11k_peer_rhash_tbl_destroy(struct ath11k_base *ab); +int ath11k_peer_rhash_delete(struct ath11k_base *ab, struct ath11k_peer *peer); #endif /* _PEER_H_ */ From 26c31016fe7eb1911e9ffa50dbaac6f2c42c799c Mon Sep 17 00:00:00 2001 From: Wenli Looi Date: Sun, 20 Mar 2022 17:30:05 -0600 Subject: [PATCH 024/228] ath9k: make ATH_SREV macros more consistent MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This makes the macros more consistent and removes hidden dependencies on ah for macros that take _ah as a parameter. This change does not appear to affect the final binary. Signed-off-by: Wenli Looi Acked-by: Toke Høiland-Jørgensen Signed-off-by: Kalle Valo Link: https://lore.kernel.org/r/20220320233010.123106-2-wlooi@ucalgary.ca --- drivers/net/wireless/ath/ath9k/reg.h | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/drivers/net/wireless/ath/ath9k/reg.h b/drivers/net/wireless/ath/ath9k/reg.h index 653e796118306..8983ea6fc7270 100644 --- a/drivers/net/wireless/ath/ath9k/reg.h +++ b/drivers/net/wireless/ath/ath9k/reg.h @@ -834,8 +834,8 @@ ((_ah)->hw_version.macRev >= AR_SREV_REVISION_5416_22)) || \ ((_ah)->hw_version.macVersion >= AR_SREV_VERSION_9100)) -#define AR_SREV_9100(ah) \ - ((ah->hw_version.macVersion) == AR_SREV_VERSION_9100) +#define AR_SREV_9100(_ah) \ + (((_ah)->hw_version.macVersion == AR_SREV_VERSION_9100)) #define AR_SREV_9100_OR_LATER(_ah) \ (((_ah)->hw_version.macVersion >= AR_SREV_VERSION_9100)) @@ -891,7 +891,7 @@ #define AR_SREV_9300_20_OR_LATER(_ah) \ ((_ah)->hw_version.macVersion >= AR_SREV_VERSION_9300) #define AR_SREV_9300_22(_ah) \ - (AR_SREV_9300(ah) && \ + (AR_SREV_9300((_ah)) && \ ((_ah)->hw_version.macRev == AR_SREV_REVISION_9300_22)) #define AR_SREV_9330(_ah) \ @@ -994,8 +994,8 @@ (((_ah)->hw_version.macVersion == AR_SREV_VERSION_9561)) #define AR_SREV_SOC(_ah) \ - (AR_SREV_9340(_ah) || AR_SREV_9531(_ah) || AR_SREV_9550(ah) || \ - AR_SREV_9561(ah)) + (AR_SREV_9340(_ah) || AR_SREV_9531(_ah) || AR_SREV_9550(_ah) || \ + AR_SREV_9561(_ah)) /* NOTE: When adding chips newer than Peacock, add chip check here */ #define AR_SREV_9580_10_OR_LATER(_ah) \ From a96474a794e11eda2c96b06270178ac1ccd6e1c0 Mon Sep 17 00:00:00 2001 From: Wenli Looi Date: Sun, 20 Mar 2022 17:30:06 -0600 Subject: [PATCH 025/228] ath9k: split set11nRateFlags and set11nChainSel MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This makes the code clearer since set11nRateFlags currently sets both the rate flags and chain sel. This may also be required for QCN550x support, where the rate flags and chain sel are in separate fields. This change does not appear to affect the final binary. Signed-off-by: Wenli Looi Acked-by: Toke Høiland-Jørgensen Signed-off-by: Kalle Valo Link: https://lore.kernel.org/r/20220320233010.123106-3-wlooi@ucalgary.ca --- drivers/net/wireless/ath/ath9k/ar9002_mac.c | 9 +++++---- drivers/net/wireless/ath/ath9k/ar9003_mac.c | 9 +++++---- drivers/net/wireless/ath/ath9k/mac.h | 6 ++++-- 3 files changed, 14 insertions(+), 10 deletions(-) diff --git a/drivers/net/wireless/ath/ath9k/ar9002_mac.c b/drivers/net/wireless/ath/ath9k/ar9002_mac.c index fba5a847c3bb7..a8c0e8e2d78c1 100644 --- a/drivers/net/wireless/ath/ath9k/ar9002_mac.c +++ b/drivers/net/wireless/ath/ath9k/ar9002_mac.c @@ -301,10 +301,11 @@ ar9002_set_txdesc(struct ath_hw *ah, void *ds, struct ath_tx_info *i) WRITE_ONCE(ads->ds_ctl5, set11nPktDurRTSCTS(i->rates, 2) | set11nPktDurRTSCTS(i->rates, 3)); - WRITE_ONCE(ads->ds_ctl7, set11nRateFlags(i->rates, 0) - | set11nRateFlags(i->rates, 1) - | set11nRateFlags(i->rates, 2) - | set11nRateFlags(i->rates, 3) + WRITE_ONCE(ads->ds_ctl7, + set11nRateFlags(i->rates, 0) | set11nChainSel(i->rates, 0) + | set11nRateFlags(i->rates, 1) | set11nChainSel(i->rates, 1) + | set11nRateFlags(i->rates, 2) | set11nChainSel(i->rates, 2) + | set11nRateFlags(i->rates, 3) | set11nChainSel(i->rates, 3) | SM(i->rtscts_rate, AR_RTSCTSRate)); WRITE_ONCE(ads->ds_ctl9, SM(i->txpower[1], AR_XmitPower1)); diff --git a/drivers/net/wireless/ath/ath9k/ar9003_mac.c b/drivers/net/wireless/ath/ath9k/ar9003_mac.c index 5184a0aacfe26..ff8ab58e67d94 100644 --- a/drivers/net/wireless/ath/ath9k/ar9003_mac.c +++ b/drivers/net/wireless/ath/ath9k/ar9003_mac.c @@ -144,10 +144,11 @@ ar9003_set_txdesc(struct ath_hw *ah, void *ds, struct ath_tx_info *i) WRITE_ONCE(ads->ctl16, set11nPktDurRTSCTS(i->rates, 2) | set11nPktDurRTSCTS(i->rates, 3)); - WRITE_ONCE(ads->ctl18, set11nRateFlags(i->rates, 0) - | set11nRateFlags(i->rates, 1) - | set11nRateFlags(i->rates, 2) - | set11nRateFlags(i->rates, 3) + WRITE_ONCE(ads->ctl18, + set11nRateFlags(i->rates, 0) | set11nChainSel(i->rates, 0) + | set11nRateFlags(i->rates, 1) | set11nChainSel(i->rates, 1) + | set11nRateFlags(i->rates, 2) | set11nChainSel(i->rates, 2) + | set11nRateFlags(i->rates, 3) | set11nChainSel(i->rates, 3) | SM(i->rtscts_rate, AR_RTSCTSRate)); WRITE_ONCE(ads->ctl19, AR_Not_Sounding); diff --git a/drivers/net/wireless/ath/ath9k/mac.h b/drivers/net/wireless/ath/ath9k/mac.h index fd6aa49adadfe..af44b33814ddc 100644 --- a/drivers/net/wireless/ath/ath9k/mac.h +++ b/drivers/net/wireless/ath/ath9k/mac.h @@ -35,8 +35,10 @@ |((_series)[_index].RateFlags & ATH9K_RATESERIES_HALFGI ? \ AR_GI##_index : 0) \ |((_series)[_index].RateFlags & ATH9K_RATESERIES_STBC ? \ - AR_STBC##_index : 0) \ - |SM((_series)[_index].ChSel, AR_ChainSel##_index)) + AR_STBC##_index : 0)) + +#define set11nChainSel(_series, _index) \ + (SM((_series)[_index].ChSel, AR_ChainSel##_index)) #define CCK_SIFS_TIME 10 #define CCK_PREAMBLE_BITS 144 From 3096a4d9eb9bf8a0975c222bd7013d2db323d749 Mon Sep 17 00:00:00 2001 From: Wenli Looi Date: Sun, 20 Mar 2022 17:30:07 -0600 Subject: [PATCH 026/228] ath9k: use AR9300_MAX_CHAINS when appropriate MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Replace other constants with AR9300_MAX_CHAINS when appropriate. This change does not appear to affect the final binary. Signed-off-by: Wenli Looi Acked-by: Toke Høiland-Jørgensen Signed-off-by: Kalle Valo Link: https://lore.kernel.org/r/20220320233010.123106-4-wlooi@ucalgary.ca --- drivers/net/wireless/ath/ath9k/ar9003_calib.c | 2 +- drivers/net/wireless/ath/ath9k/ar9003_eeprom.c | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/drivers/net/wireless/ath/ath9k/ar9003_calib.c b/drivers/net/wireless/ath/ath9k/ar9003_calib.c index dc24da1ff00b1..6ca089f15629c 100644 --- a/drivers/net/wireless/ath/ath9k/ar9003_calib.c +++ b/drivers/net/wireless/ath/ath9k/ar9003_calib.c @@ -177,7 +177,7 @@ static void ar9003_hw_iqcal_collect(struct ath_hw *ah) int i; /* Accumulate IQ cal measures for active chains */ - for (i = 0; i < AR5416_MAX_CHAINS; i++) { + for (i = 0; i < AR9300_MAX_CHAINS; i++) { if (ah->txchainmask & BIT(i)) { ah->totalPowerMeasI[i] += REG_READ(ah, AR_PHY_CAL_MEAS_0(i)); diff --git a/drivers/net/wireless/ath/ath9k/ar9003_eeprom.c b/drivers/net/wireless/ath/ath9k/ar9003_eeprom.c index b0a4ca3559fd8..669b49b560a11 100644 --- a/drivers/net/wireless/ath/ath9k/ar9003_eeprom.c +++ b/drivers/net/wireless/ath/ath9k/ar9003_eeprom.c @@ -3911,7 +3911,7 @@ static void ar9003_hw_atten_apply(struct ath_hw *ah, struct ath9k_channel *chan) } /* Test value. if 0 then attenuation is unused. Don't load anything. */ - for (i = 0; i < 3; i++) { + for (i = 0; i < AR9300_MAX_CHAINS; i++) { if (ah->txchainmask & BIT(i)) { value = ar9003_hw_atten_chain_get(ah, i, chan); REG_RMW_FIELD(ah, ext_atten_reg[i], @@ -5126,7 +5126,7 @@ static int ar9003_hw_calibration_apply(struct ath_hw *ah, int frequency) frequency, correction[0], correction[1], correction[2]); /* Store calibrated noise floor values */ - for (ichain = 0; ichain < AR5416_MAX_CHAINS; ichain++) + for (ichain = 0; ichain < AR9300_MAX_CHAINS; ichain++) if (mode) { ah->nf_5g.cal[ichain] = nf_cal[ichain]; ah->nf_5g.pwr[ichain] = nf_pwr[ichain]; From 9aaff3864b603408c02c629957ae8d8ff5d5a4f2 Mon Sep 17 00:00:00 2001 From: Wenli Looi Date: Sun, 20 Mar 2022 17:30:08 -0600 Subject: [PATCH 027/228] ath9k: fix ar9003_get_eepmisc MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The current implementation is reading the wrong eeprom type. Fixes: d8ec2e2a63e8 ("ath9k: Add an eeprom_ops callback for retrieving the eepmisc value") Signed-off-by: Wenli Looi Acked-by: Toke Høiland-Jørgensen Signed-off-by: Kalle Valo Link: https://lore.kernel.org/r/20220320233010.123106-5-wlooi@ucalgary.ca --- drivers/net/wireless/ath/ath9k/ar9003_eeprom.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/net/wireless/ath/ath9k/ar9003_eeprom.c b/drivers/net/wireless/ath/ath9k/ar9003_eeprom.c index 669b49b560a11..a109a44a19999 100644 --- a/drivers/net/wireless/ath/ath9k/ar9003_eeprom.c +++ b/drivers/net/wireless/ath/ath9k/ar9003_eeprom.c @@ -5615,7 +5615,7 @@ unsigned int ar9003_get_paprd_scale_factor(struct ath_hw *ah, static u8 ar9003_get_eepmisc(struct ath_hw *ah) { - return ah->eeprom.map4k.baseEepHeader.eepMisc; + return ah->eeprom.ar9300_eep.baseEepHeader.opCapFlags.eepMisc; } const struct eeprom_ops eep_ar9300_ops = { From 193025378c446d53fa36bfefc33c170f1ec374c8 Mon Sep 17 00:00:00 2001 From: Wenli Looi Date: Sun, 20 Mar 2022 17:30:09 -0600 Subject: [PATCH 028/228] ath9k: refactor ar9003_hw_spur_mitigate_ofdm MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Similar to ar9003_hw_spur_mitigate_mrc_cck, simplify the code by using ar9003_get_spur_chan_ptr. This may also be required for QCN550x support, to provide an abstraction over the underlying EEPROM format. Signed-off-by: Wenli Looi Acked-by: Toke Høiland-Jørgensen Signed-off-by: Kalle Valo Link: https://lore.kernel.org/r/20220320233010.123106-6-wlooi@ucalgary.ca --- drivers/net/wireless/ath/ath9k/ar9003_phy.c | 25 +++++++-------------- 1 file changed, 8 insertions(+), 17 deletions(-) diff --git a/drivers/net/wireless/ath/ath9k/ar9003_phy.c b/drivers/net/wireless/ath/ath9k/ar9003_phy.c index daf30f9946b48..dc0e5ea256737 100644 --- a/drivers/net/wireless/ath/ath9k/ar9003_phy.c +++ b/drivers/net/wireless/ath/ath9k/ar9003_phy.c @@ -523,21 +523,10 @@ static void ar9003_hw_spur_mitigate_ofdm(struct ath_hw *ah, int synth_freq; int range = 10; int freq_offset = 0; - int mode; - u8* spurChansPtr; + u8 *spur_fbin_ptr = ar9003_get_spur_chan_ptr(ah, IS_CHAN_2GHZ(chan)); unsigned int i; - struct ar9300_eeprom *eep = &ah->eeprom.ar9300_eep; - - if (IS_CHAN_5GHZ(chan)) { - spurChansPtr = &(eep->modalHeader5G.spurChans[0]); - mode = 0; - } - else { - spurChansPtr = &(eep->modalHeader2G.spurChans[0]); - mode = 1; - } - if (spurChansPtr[0] == 0) + if (spur_fbin_ptr[0] == 0) return; /* No spur in the mode */ if (IS_CHAN_HT40(chan)) { @@ -554,16 +543,18 @@ static void ar9003_hw_spur_mitigate_ofdm(struct ath_hw *ah, ar9003_hw_spur_ofdm_clear(ah); - for (i = 0; i < AR_EEPROM_MODAL_SPURS && spurChansPtr[i]; i++) { - freq_offset = ath9k_hw_fbin2freq(spurChansPtr[i], mode); + for (i = 0; i < AR_EEPROM_MODAL_SPURS && spur_fbin_ptr[i]; i++) { + freq_offset = ath9k_hw_fbin2freq(spur_fbin_ptr[i], + IS_CHAN_2GHZ(chan)); freq_offset -= synth_freq; if (abs(freq_offset) < range) { ar9003_hw_spur_ofdm_work(ah, chan, freq_offset, range, synth_freq); if (AR_SREV_9565(ah) && (i < 4)) { - freq_offset = ath9k_hw_fbin2freq(spurChansPtr[i + 1], - mode); + freq_offset = + ath9k_hw_fbin2freq(spur_fbin_ptr[i + 1], + IS_CHAN_2GHZ(chan)); freq_offset -= synth_freq; if (abs(freq_offset) < range) ar9003_hw_spur_ofdm_9565(ah, freq_offset); From 673424ce0e77450c24b300153387e271f470fc7c Mon Sep 17 00:00:00 2001 From: Wenli Looi Date: Sun, 20 Mar 2022 17:30:10 -0600 Subject: [PATCH 029/228] ath9k: add functions to get paprd rate mask MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This removes some code duplication with le32_to_cpu. This may also be required for QCN550x support, to provide an abstraction over the underlying EEPROM format. Signed-off-by: Wenli Looi Acked-by: Toke Høiland-Jørgensen Signed-off-by: Kalle Valo Link: https://lore.kernel.org/r/20220320233010.123106-7-wlooi@ucalgary.ca --- .../net/wireless/ath/ath9k/ar9003_eeprom.c | 33 ++++++++++--------- .../net/wireless/ath/ath9k/ar9003_eeprom.h | 2 ++ drivers/net/wireless/ath/ath9k/ar9003_paprd.c | 10 +++--- 3 files changed, 25 insertions(+), 20 deletions(-) diff --git a/drivers/net/wireless/ath/ath9k/ar9003_eeprom.c b/drivers/net/wireless/ath/ath9k/ar9003_eeprom.c index a109a44a19999..abf12de0e3814 100644 --- a/drivers/net/wireless/ath/ath9k/ar9003_eeprom.c +++ b/drivers/net/wireless/ath/ath9k/ar9003_eeprom.c @@ -5449,8 +5449,6 @@ static void ath9k_hw_ar9300_set_txpower(struct ath_hw *ah, { struct ath_regulatory *regulatory = ath9k_hw_regulatory(ah); struct ath_common *common = ath9k_hw_common(ah); - struct ar9300_eeprom *eep = &ah->eeprom.ar9300_eep; - struct ar9300_modal_eep_header *modal_hdr; u8 targetPowerValT2[ar9300RateSize]; u8 target_power_val_t2_eep[ar9300RateSize]; u8 targetPowerValT2_tpc[ar9300RateSize]; @@ -5465,17 +5463,12 @@ static void ath9k_hw_ar9300_set_txpower(struct ath_hw *ah, ar9003_hw_get_target_power_eeprom(ah, chan, targetPowerValT2); if (ar9003_is_paprd_enabled(ah)) { - if (IS_CHAN_2GHZ(chan)) - modal_hdr = &eep->modalHeader2G; - else - modal_hdr = &eep->modalHeader5G; - ah->paprd_ratemask = - le32_to_cpu(modal_hdr->papdRateMaskHt20) & + ar9003_get_paprd_rate_mask_ht20(ah, IS_CHAN_2GHZ(chan)) & AR9300_PAPRD_RATE_MASK; ah->paprd_ratemask_ht40 = - le32_to_cpu(modal_hdr->papdRateMaskHt40) & + ar9003_get_paprd_rate_mask_ht40(ah, IS_CHAN_2GHZ(chan)) & AR9300_PAPRD_RATE_MASK; paprd_scale_factor = ar9003_get_paprd_scale_factor(ah, chan); @@ -5592,23 +5585,33 @@ u8 *ar9003_get_spur_chan_ptr(struct ath_hw *ah, bool is2ghz) return ar9003_modal_header(ah, is2ghz)->spurChans; } +u32 ar9003_get_paprd_rate_mask_ht20(struct ath_hw *ah, bool is2ghz) +{ + return le32_to_cpu(ar9003_modal_header(ah, is2ghz)->papdRateMaskHt20); +} + +u32 ar9003_get_paprd_rate_mask_ht40(struct ath_hw *ah, bool is2ghz) +{ + return le32_to_cpu(ar9003_modal_header(ah, is2ghz)->papdRateMaskHt40); +} + unsigned int ar9003_get_paprd_scale_factor(struct ath_hw *ah, struct ath9k_channel *chan) { - struct ar9300_eeprom *eep = &ah->eeprom.ar9300_eep; + bool is2ghz = IS_CHAN_2GHZ(chan); - if (IS_CHAN_2GHZ(chan)) - return MS(le32_to_cpu(eep->modalHeader2G.papdRateMaskHt20), + if (is2ghz) + return MS(ar9003_get_paprd_rate_mask_ht20(ah, is2ghz), AR9300_PAPRD_SCALE_1); else { if (chan->channel >= 5700) - return MS(le32_to_cpu(eep->modalHeader5G.papdRateMaskHt20), + return MS(ar9003_get_paprd_rate_mask_ht20(ah, is2ghz), AR9300_PAPRD_SCALE_1); else if (chan->channel >= 5400) - return MS(le32_to_cpu(eep->modalHeader5G.papdRateMaskHt40), + return MS(ar9003_get_paprd_rate_mask_ht40(ah, is2ghz), AR9300_PAPRD_SCALE_2); else - return MS(le32_to_cpu(eep->modalHeader5G.papdRateMaskHt40), + return MS(ar9003_get_paprd_rate_mask_ht40(ah, is2ghz), AR9300_PAPRD_SCALE_1); } } diff --git a/drivers/net/wireless/ath/ath9k/ar9003_eeprom.h b/drivers/net/wireless/ath/ath9k/ar9003_eeprom.h index e8fda54acfe38..f8ae20318302f 100644 --- a/drivers/net/wireless/ath/ath9k/ar9003_eeprom.h +++ b/drivers/net/wireless/ath/ath9k/ar9003_eeprom.h @@ -363,6 +363,8 @@ u32 ar9003_hw_ant_ctrl_common_2_get(struct ath_hw *ah, bool is2ghz); u8 *ar9003_get_spur_chan_ptr(struct ath_hw *ah, bool is_2ghz); +u32 ar9003_get_paprd_rate_mask_ht20(struct ath_hw *ah, bool is2ghz); +u32 ar9003_get_paprd_rate_mask_ht40(struct ath_hw *ah, bool is2ghz); unsigned int ar9003_get_paprd_scale_factor(struct ath_hw *ah, struct ath9k_channel *chan); diff --git a/drivers/net/wireless/ath/ath9k/ar9003_paprd.c b/drivers/net/wireless/ath/ath9k/ar9003_paprd.c index 34e1009402846..b2d53b6c0ffd2 100644 --- a/drivers/net/wireless/ath/ath9k/ar9003_paprd.c +++ b/drivers/net/wireless/ath/ath9k/ar9003_paprd.c @@ -21,7 +21,7 @@ void ar9003_paprd_enable(struct ath_hw *ah, bool val) { struct ath9k_channel *chan = ah->curchan; - struct ar9300_eeprom *eep = &ah->eeprom.ar9300_eep; + bool is2ghz = IS_CHAN_2GHZ(chan); /* * 3 bits for modalHeader5G.papdRateMaskHt20 @@ -36,17 +36,17 @@ void ar9003_paprd_enable(struct ath_hw *ah, bool val) * -- disable PAPRD for lower band 5GHz */ - if (IS_CHAN_5GHZ(chan)) { + if (!is2ghz) { if (chan->channel >= UPPER_5G_SUB_BAND_START) { - if (le32_to_cpu(eep->modalHeader5G.papdRateMaskHt20) + if (ar9003_get_paprd_rate_mask_ht20(ah, is2ghz) & BIT(30)) val = false; } else if (chan->channel >= MID_5G_SUB_BAND_START) { - if (le32_to_cpu(eep->modalHeader5G.papdRateMaskHt20) + if (ar9003_get_paprd_rate_mask_ht20(ah, is2ghz) & BIT(29)) val = false; } else { - if (le32_to_cpu(eep->modalHeader5G.papdRateMaskHt20) + if (ar9003_get_paprd_rate_mask_ht20(ah, is2ghz) & BIT(28)) val = false; } From b2beae327e039736299f3c6559f3467323fe68c5 Mon Sep 17 00:00:00 2001 From: Wen Gong Date: Wed, 23 Mar 2022 21:18:56 -0400 Subject: [PATCH 030/228] ath11k: store and send country code to firmware after recovery Currently ath11k does not send the country code to firmware after device recovery, as a result the regdomain info is reported from firmware by default. Regdomain info is important, so ath11k also need to restore it to the value which was used before recovery. Tested-on: WCN6855 hw2.0 PCI WLAN.HSP.1.1-03125-QCAHSPSWPL_V1_V2_SILICONZ_LITE-3 Signed-off-by: Wen Gong Signed-off-by: Kalle Valo Link: https://lore.kernel.org/r/20220324011856.11014-1-quic_wgong@quicinc.com --- drivers/net/wireless/ath/ath11k/core.c | 1 + drivers/net/wireless/ath/ath11k/core.h | 1 + drivers/net/wireless/ath/ath11k/mac.c | 8 ++++++++ drivers/net/wireless/ath/ath11k/reg.c | 1 + 4 files changed, 11 insertions(+) diff --git a/drivers/net/wireless/ath/ath11k/core.c b/drivers/net/wireless/ath/ath11k/core.c index 2a867237e8179..9395a5a271f10 100644 --- a/drivers/net/wireless/ath/ath11k/core.c +++ b/drivers/net/wireless/ath/ath11k/core.c @@ -1404,6 +1404,7 @@ static void ath11k_update_11d(struct work_struct *work) pdev = &ab->pdevs[i]; ar = pdev->ar; + memcpy(&ar->alpha2, &set_current_param.alpha2, 2); ret = ath11k_wmi_send_set_current_country_cmd(ar, &set_current_param); if (ret) ath11k_warn(ar->ab, diff --git a/drivers/net/wireless/ath/ath11k/core.h b/drivers/net/wireless/ath/ath11k/core.h index 41001ec174e2b..b4d58e01fffaa 100644 --- a/drivers/net/wireless/ath/ath11k/core.h +++ b/drivers/net/wireless/ath/ath11k/core.h @@ -671,6 +671,7 @@ struct ath11k { int hw_rate_code; u8 twt_enabled; bool nlo_enabled; + u8 alpha2[REG_ALPHA2_LEN + 1]; }; struct ath11k_band_cap { diff --git a/drivers/net/wireless/ath/ath11k/mac.c b/drivers/net/wireless/ath/ath11k/mac.c index 7a7641e8e3259..9caa8b87c3139 100644 --- a/drivers/net/wireless/ath/ath11k/mac.c +++ b/drivers/net/wireless/ath/ath11k/mac.c @@ -7957,6 +7957,14 @@ ath11k_mac_op_reconfig_complete(struct ieee80211_hw *hw, ar->state = ATH11K_STATE_ON; ieee80211_wake_queues(ar->hw); + if (ar->ab->hw_params.current_cc_support && + ar->alpha2[0] != 0 && ar->alpha2[1] != 0) { + struct wmi_set_current_country_params set_current_param = {}; + + memcpy(&set_current_param.alpha2, ar->alpha2, 2); + ath11k_wmi_send_set_current_country_cmd(ar, &set_current_param); + } + if (ab->is_reset) { recovery_count = atomic_inc_return(&ab->recovery_count); ath11k_dbg(ab, ATH11K_DBG_BOOT, diff --git a/drivers/net/wireless/ath/ath11k/reg.c b/drivers/net/wireless/ath/ath11k/reg.c index 81e11cde31d7b..35eb1a0c04dcb 100644 --- a/drivers/net/wireless/ath/ath11k/reg.c +++ b/drivers/net/wireless/ath/ath11k/reg.c @@ -83,6 +83,7 @@ ath11k_reg_notifier(struct wiphy *wiphy, struct regulatory_request *request) */ if (ar->ab->hw_params.current_cc_support) { memcpy(&set_current_param.alpha2, request->alpha2, 2); + memcpy(&ar->alpha2, &set_current_param.alpha2, 2); ret = ath11k_wmi_send_set_current_country_cmd(ar, &set_current_param); if (ret) ath11k_warn(ar->ab, From 1216c4d30723f5ed5b7576a2b96dafc4c5a8cbf9 Mon Sep 17 00:00:00 2001 From: Edmond Gagnon Date: Fri, 25 Mar 2022 17:42:12 -0500 Subject: [PATCH 031/228] wcn36xx: Implement tx_rate reporting Currently, the driver reports a tx_rate of 6.0 MBit/s no matter the true rate: root@linaro-developer:~# iw wlan0 link Connected to 6c:f3:7f:eb:9b:92 (on wlan0) SSID: SQ-DEVICETEST freq: 5200 RX: 4141 bytes (32 packets) TX: 2082 bytes (15 packets) signal: -77 dBm rx bitrate: 135.0 MBit/s MCS 6 40MHz short GI tx bitrate: 6.0 MBit/s bss flags: short-slot-time dtim period: 1 beacon int: 100 This patch requests HAL_GLOBAL_CLASS_A_STATS_INFO via a hal_get_stats firmware message and reports it via ieee80211_ops::sta_statistics. root@linaro-developer:~# iw wlan0 link Connected to 6c:f3:7f:eb:73:b2 (on wlan0) SSID: SQ-DEVICETEST freq: 5700 RX: 26788094 bytes (19859 packets) TX: 1101376 bytes (12119 packets) signal: -75 dBm rx bitrate: 135.0 MBit/s MCS 6 40MHz short GI tx bitrate: 108.0 MBit/s VHT-MCS 5 40MHz VHT-NSS 1 bss flags: short-slot-time dtim period: 1 beacon int: 100 Tested on MSM8939 with WCN3680B running firmware CNSS-PR-2-0-1-2-c1-00083, and verified by sniffing frames over the air with Wireshark to ensure the MCS indices match. Signed-off-by: Edmond Gagnon Reviewed-by: Benjamin Li Signed-off-by: Kalle Valo Link: https://lore.kernel.org/r/20220325224212.159690-1-egagnon@squareup.com --- drivers/net/wireless/ath/wcn36xx/hal.h | 7 ++- drivers/net/wireless/ath/wcn36xx/main.c | 16 +++++++ drivers/net/wireless/ath/wcn36xx/smd.c | 57 +++++++++++++++++++++++++ drivers/net/wireless/ath/wcn36xx/smd.h | 2 + drivers/net/wireless/ath/wcn36xx/txrx.c | 29 +++++++++++++ drivers/net/wireless/ath/wcn36xx/txrx.h | 1 + 6 files changed, 111 insertions(+), 1 deletion(-) diff --git a/drivers/net/wireless/ath/wcn36xx/hal.h b/drivers/net/wireless/ath/wcn36xx/hal.h index 2a1db9756fd5f..46a49f0a51b34 100644 --- a/drivers/net/wireless/ath/wcn36xx/hal.h +++ b/drivers/net/wireless/ath/wcn36xx/hal.h @@ -2626,7 +2626,12 @@ enum tx_rate_info { HAL_TX_RATE_SGI = 0x8, /* Rate with Long guard interval */ - HAL_TX_RATE_LGI = 0x10 + HAL_TX_RATE_LGI = 0x10, + + /* VHT rates */ + HAL_TX_RATE_VHT20 = 0x20, + HAL_TX_RATE_VHT40 = 0x40, + HAL_TX_RATE_VHT80 = 0x80, }; struct ani_global_class_a_stats_info { diff --git a/drivers/net/wireless/ath/wcn36xx/main.c b/drivers/net/wireless/ath/wcn36xx/main.c index 95ea7d040d8cc..864d1547e6f83 100644 --- a/drivers/net/wireless/ath/wcn36xx/main.c +++ b/drivers/net/wireless/ath/wcn36xx/main.c @@ -1400,6 +1400,21 @@ static int wcn36xx_get_survey(struct ieee80211_hw *hw, int idx, return 0; } +static void wcn36xx_sta_statistics(struct ieee80211_hw *hw, struct ieee80211_vif *vif, + struct ieee80211_sta *sta, struct station_info *sinfo) +{ + struct wcn36xx *wcn; + u8 sta_index; + int status; + + wcn = hw->priv; + sta_index = get_sta_index(vif, wcn36xx_sta_to_priv(sta)); + status = wcn36xx_smd_get_stats(wcn, sta_index, HAL_GLOBAL_CLASS_A_STATS_INFO, sinfo); + + if (status) + wcn36xx_err("wcn36xx_smd_get_stats failed\n"); +} + static const struct ieee80211_ops wcn36xx_ops = { .start = wcn36xx_start, .stop = wcn36xx_stop, @@ -1423,6 +1438,7 @@ static const struct ieee80211_ops wcn36xx_ops = { .set_rts_threshold = wcn36xx_set_rts_threshold, .sta_add = wcn36xx_sta_add, .sta_remove = wcn36xx_sta_remove, + .sta_statistics = wcn36xx_sta_statistics, .ampdu_action = wcn36xx_ampdu_action, #if IS_ENABLED(CONFIG_IPV6) .ipv6_addr_change = wcn36xx_ipv6_addr_change, diff --git a/drivers/net/wireless/ath/wcn36xx/smd.c b/drivers/net/wireless/ath/wcn36xx/smd.c index 59ad332156aed..872b37875c574 100644 --- a/drivers/net/wireless/ath/wcn36xx/smd.c +++ b/drivers/net/wireless/ath/wcn36xx/smd.c @@ -2627,6 +2627,62 @@ int wcn36xx_smd_del_ba(struct wcn36xx *wcn, u16 tid, u8 direction, u8 sta_index) return ret; } +int wcn36xx_smd_get_stats(struct wcn36xx *wcn, u8 sta_index, u32 stats_mask, + struct station_info *sinfo) +{ + struct wcn36xx_hal_stats_req_msg msg_body; + struct wcn36xx_hal_stats_rsp_msg *rsp; + void *rsp_body; + int ret; + + if (stats_mask & ~HAL_GLOBAL_CLASS_A_STATS_INFO) { + wcn36xx_err("stats_mask 0x%x contains unimplemented types\n", + stats_mask); + return -EINVAL; + } + + mutex_lock(&wcn->hal_mutex); + INIT_HAL_MSG(msg_body, WCN36XX_HAL_GET_STATS_REQ); + + msg_body.sta_id = sta_index; + msg_body.stats_mask = stats_mask; + + PREPARE_HAL_BUF(wcn->hal_buf, msg_body); + + ret = wcn36xx_smd_send_and_wait(wcn, msg_body.header.len); + if (ret) { + wcn36xx_err("sending hal_get_stats failed\n"); + goto out; + } + + ret = wcn36xx_smd_rsp_status_check(wcn->hal_buf, wcn->hal_rsp_len); + if (ret) { + wcn36xx_err("hal_get_stats response failed err=%d\n", ret); + goto out; + } + + rsp = (struct wcn36xx_hal_stats_rsp_msg *)wcn->hal_buf; + rsp_body = (wcn->hal_buf + sizeof(struct wcn36xx_hal_stats_rsp_msg)); + + if (rsp->stats_mask != stats_mask) { + wcn36xx_err("stats_mask 0x%x differs from requested 0x%x\n", + rsp->stats_mask, stats_mask); + goto out; + } + + if (rsp->stats_mask & HAL_GLOBAL_CLASS_A_STATS_INFO) { + struct ani_global_class_a_stats_info *stats_info = rsp_body; + + wcn36xx_process_tx_rate(stats_info, &sinfo->txrate); + sinfo->filled |= BIT_ULL(NL80211_STA_INFO_TX_BITRATE); + rsp_body += sizeof(struct ani_global_class_a_stats_info); + } +out: + mutex_unlock(&wcn->hal_mutex); + + return ret; +} + static int wcn36xx_smd_trigger_ba_rsp(void *buf, int len, struct add_ba_info *ba_info) { struct wcn36xx_hal_trigger_ba_rsp_candidate *candidate; @@ -3316,6 +3372,7 @@ int wcn36xx_smd_rsp_process(struct rpmsg_device *rpdev, case WCN36XX_HAL_ADD_BA_SESSION_RSP: case WCN36XX_HAL_ADD_BA_RSP: case WCN36XX_HAL_DEL_BA_RSP: + case WCN36XX_HAL_GET_STATS_RSP: case WCN36XX_HAL_TRIGGER_BA_RSP: case WCN36XX_HAL_UPDATE_CFG_RSP: case WCN36XX_HAL_JOIN_RSP: diff --git a/drivers/net/wireless/ath/wcn36xx/smd.h b/drivers/net/wireless/ath/wcn36xx/smd.h index 957cfa87fbdea..3fd598ac2a27e 100644 --- a/drivers/net/wireless/ath/wcn36xx/smd.h +++ b/drivers/net/wireless/ath/wcn36xx/smd.h @@ -138,6 +138,8 @@ int wcn36xx_smd_add_ba_session(struct wcn36xx *wcn, int wcn36xx_smd_add_ba(struct wcn36xx *wcn, u8 session_id); int wcn36xx_smd_del_ba(struct wcn36xx *wcn, u16 tid, u8 direction, u8 sta_index); int wcn36xx_smd_trigger_ba(struct wcn36xx *wcn, u8 sta_index, u16 tid, u16 *ssn); +int wcn36xx_smd_get_stats(struct wcn36xx *wcn, u8 sta_index, u32 stats_mask, + struct station_info *sinfo); int wcn36xx_smd_update_cfg(struct wcn36xx *wcn, u32 cfg_id, u32 value); diff --git a/drivers/net/wireless/ath/wcn36xx/txrx.c b/drivers/net/wireless/ath/wcn36xx/txrx.c index df749b1145687..8da3955995b6e 100644 --- a/drivers/net/wireless/ath/wcn36xx/txrx.c +++ b/drivers/net/wireless/ath/wcn36xx/txrx.c @@ -699,3 +699,32 @@ int wcn36xx_start_tx(struct wcn36xx *wcn, return ret; } + +void wcn36xx_process_tx_rate(struct ani_global_class_a_stats_info *stats, struct rate_info *info) +{ + /* tx_rate is in units of 500kbps; mac80211 wants them in 100kbps */ + if (stats->tx_rate_flags & HAL_TX_RATE_LEGACY) + info->legacy = stats->tx_rate * 5; + + info->flags = 0; + info->mcs = stats->mcs_index; + info->nss = 1; + + if (stats->tx_rate_flags & (HAL_TX_RATE_HT20 | HAL_TX_RATE_HT40)) + info->flags |= RATE_INFO_FLAGS_MCS; + + if (stats->tx_rate_flags & (HAL_TX_RATE_VHT20 | HAL_TX_RATE_VHT40 | HAL_TX_RATE_VHT80)) + info->flags |= RATE_INFO_FLAGS_VHT_MCS; + + if (stats->tx_rate_flags & HAL_TX_RATE_SGI) + info->flags |= RATE_INFO_FLAGS_SHORT_GI; + + if (stats->tx_rate_flags & (HAL_TX_RATE_HT20 | HAL_TX_RATE_VHT20)) + info->bw = RATE_INFO_BW_20; + + if (stats->tx_rate_flags & (HAL_TX_RATE_HT40 | HAL_TX_RATE_VHT40)) + info->bw = RATE_INFO_BW_40; + + if (stats->tx_rate_flags & HAL_TX_RATE_VHT80) + info->bw = RATE_INFO_BW_80; +} diff --git a/drivers/net/wireless/ath/wcn36xx/txrx.h b/drivers/net/wireless/ath/wcn36xx/txrx.h index b54311ffde9c5..fb0d6cabd52b6 100644 --- a/drivers/net/wireless/ath/wcn36xx/txrx.h +++ b/drivers/net/wireless/ath/wcn36xx/txrx.h @@ -164,5 +164,6 @@ int wcn36xx_rx_skb(struct wcn36xx *wcn, struct sk_buff *skb); int wcn36xx_start_tx(struct wcn36xx *wcn, struct wcn36xx_sta *sta_priv, struct sk_buff *skb); +void wcn36xx_process_tx_rate(struct ani_global_class_a_stats_info *stats, struct rate_info *info); #endif /* _TXRX_H_ */ From 801cb1d234288d9bc2afeaa98c7e98f8038b7a6c Mon Sep 17 00:00:00 2001 From: Wen Gong Date: Mon, 28 Mar 2022 14:57:19 +0300 Subject: [PATCH 032/228] ath11k: add support to search regdb data in board-2.bin for WCN6855 Currently ath11k only download the same regdb.bin file for all WCN6855 chips, actually ath11k needs to distinguish all different WCN6855 chips. This is to re-use the string type which include bus, chip id, board id, vendor, device, subsystem-vendor, subsystem-device and variant for WCN6855 to distinguish different regdb in board-2.bin. ath11k will first load board-2.bin and search in it for the regdb data with the above parameters, if matched one regdb data, then download it to firmware, if not matched any one, then ath11k will download the file regdb.bin to firmware. Add enum value ATH11K_BD_IE_REGDB and enum type ath11k_bd_ie_regdb_type to distinguish regdb data and board data since they are in the same file board-2.bin. This only take effect for WCN6855 which supports regdb in hardware parameters. Test log: [ 3833.091948] ath11k_pci 0000:05:00.0: boot using board name 'bus=pci,vendor=17cb,device=1103,subsystem-vendor=17cb,subsystem-device=3374,qmi-chip-id=2,qmi-board-id=262' [ 3833.092072] ath11k_pci 0000:05:00.0: boot firmware request ath11k/WCN6855/hw2.0/board-2.bin size 205316 [ 3833.092079] ath11k_pci 0000:05:00.0: board name [ 3833.092083] ath11k_pci 0000:05:00.0: 00000000: 62 75 73 3d 70 63 69 2c 71 6d 69 2d 63 68 69 70 bus=pci,qmi-chip [ 3833.092088] ath11k_pci 0000:05:00.0: 00000010: 2d 69 64 3d 31 -id=1 [ 3833.092091] ath11k_pci 0000:05:00.0: board name [ 3833.092095] ath11k_pci 0000:05:00.0: 00000000: 62 75 73 3d 70 63 69 2c 71 6d 69 2d 63 68 69 70 bus=pci,qmi-chip [ 3833.092099] ath11k_pci 0000:05:00.0: 00000010: 2d 69 64 3d 32 -id=2 [ 3833.092102] ath11k_pci 0000:05:00.0: board name [ 3833.092105] ath11k_pci 0000:05:00.0: 00000000: 62 75 73 3d 70 63 69 2c 71 6d 69 2d 63 68 69 70 bus=pci,qmi-chip [ 3833.092109] ath11k_pci 0000:05:00.0: 00000010: 2d 69 64 3d 33 -id=3 [ 3833.092112] ath11k_pci 0000:05:00.0: board name [ 3833.092116] ath11k_pci 0000:05:00.0: 00000000: 62 75 73 3d 70 63 69 2c 76 65 6e 64 6f 72 3d 31 bus=pci,vendor=1 [ 3833.092119] ath11k_pci 0000:05:00.0: 00000010: 37 63 62 2c 64 65 76 69 63 65 3d 31 31 30 33 2c 7cb,device=1103, [ 3833.092123] ath11k_pci 0000:05:00.0: 00000020: 73 75 62 73 79 73 74 65 6d 2d 76 65 6e 64 6f 72 subsystem-vendor [ 3833.092126] ath11k_pci 0000:05:00.0: 00000030: 3d 31 37 63 62 2c 73 75 62 73 79 73 74 65 6d 2d =17cb,subsystem- [ 3833.092130] ath11k_pci 0000:05:00.0: 00000040: 64 65 76 69 63 65 3d 33 33 37 34 2c 71 6d 69 2d device=3374,qmi- [ 3833.092133] ath11k_pci 0000:05:00.0: 00000050: 63 68 69 70 2d 69 64 3d 32 2c 71 6d 69 2d 62 6f chip-id=2,qmi-bo [ 3833.092137] ath11k_pci 0000:05:00.0: 00000060: 61 72 64 2d 69 64 3d 32 36 36 2c 76 61 72 69 61 ard-id=266,varia [ 3833.092140] ath11k_pci 0000:05:00.0: 00000070: 6e 74 3d 48 50 5f 47 38 5f 4c 61 6e 63 69 61 31 nt=HP_G8_Lancia1 [ 3833.092144] ath11k_pci 0000:05:00.0: 00000080: 35 5 [ 3833.092147] ath11k_pci 0000:05:00.0: board name [ 3833.092150] ath11k_pci 0000:05:00.0: 00000000: 62 75 73 3d 70 63 69 2c 76 65 6e 64 6f 72 3d 31 bus=pci,vendor=1 [ 3833.092154] ath11k_pci 0000:05:00.0: 00000010: 37 63 62 2c 64 65 76 69 63 65 3d 31 31 30 33 2c 7cb,device=1103, [ 3833.092157] ath11k_pci 0000:05:00.0: 00000020: 73 75 62 73 79 73 74 65 6d 2d 76 65 6e 64 6f 72 subsystem-vendor [ 3833.092161] ath11k_pci 0000:05:00.0: 00000030: 3d 31 37 63 62 2c 73 75 62 73 79 73 74 65 6d 2d =17cb,subsystem- [ 3833.092165] ath11k_pci 0000:05:00.0: 00000040: 64 65 76 69 63 65 3d 33 33 37 34 2c 71 6d 69 2d device=3374,qmi- [ 3833.092168] ath11k_pci 0000:05:00.0: 00000050: 63 68 69 70 2d 69 64 3d 32 2c 71 6d 69 2d 62 6f chip-id=2,qmi-bo [ 3833.092172] ath11k_pci 0000:05:00.0: 00000060: 61 72 64 2d 69 64 3d 32 36 36 ard-id=266 [ 3833.092206] ath11k_pci 0000:05:00.0: board name [ 3833.092209] ath11k_pci 0000:05:00.0: 00000000: 62 75 73 3d 70 63 69 2c 76 65 6e 64 6f 72 3d 31 bus=pci,vendor=1 [ 3833.092213] ath11k_pci 0000:05:00.0: 00000010: 37 63 62 2c 64 65 76 69 63 65 3d 31 31 30 33 2c 7cb,device=1103, [ 3833.092216] ath11k_pci 0000:05:00.0: 00000020: 73 75 62 73 79 73 74 65 6d 2d 76 65 6e 64 6f 72 subsystem-vendor [ 3833.092220] ath11k_pci 0000:05:00.0: 00000030: 3d 31 37 63 62 2c 73 75 62 73 79 73 74 65 6d 2d =17cb,subsystem- [ 3833.092223] ath11k_pci 0000:05:00.0: 00000040: 64 65 76 69 63 65 3d 33 33 37 34 2c 71 6d 69 2d device=3374,qmi- [ 3833.092227] ath11k_pci 0000:05:00.0: 00000050: 63 68 69 70 2d 69 64 3d 32 2c 71 6d 69 2d 62 6f chip-id=2,qmi-bo [ 3833.092230] ath11k_pci 0000:05:00.0: 00000060: 61 72 64 2d 69 64 3d 32 36 32 ard-id=262 [ 3833.092234] ath11k_pci 0000:05:00.0: boot found match regdb data for name 'bus=pci,vendor=17cb,device=1103,subsystem-vendor=17cb,subsystem-device=3374,qmi-chip-id=2,qmi-board-id=262' [ 3833.092238] ath11k_pci 0000:05:00.0: board name [ 3833.092241] ath11k_pci 0000:05:00.0: 00000000: 62 75 73 3d 70 63 69 2c 71 6d 69 2d 63 68 69 70 bus=pci,qmi-chip [ 3833.092245] ath11k_pci 0000:05:00.0: 00000010: 2d 69 64 3d 31 31 -id=11 [ 3833.092248] ath11k_pci 0000:05:00.0: board name [ 3833.092251] ath11k_pci 0000:05:00.0: 00000000: 62 75 73 3d 70 63 69 2c 71 6d 69 2d 63 68 69 70 bus=pci,qmi-chip [ 3833.092255] ath11k_pci 0000:05:00.0: 00000010: 2d 69 64 3d 32 32 -id=22 [ 3833.092258] ath11k_pci 0000:05:00.0: board name [ 3833.092261] ath11k_pci 0000:05:00.0: 00000000: 62 75 73 3d 70 63 69 2c 71 6d 69 2d 63 68 69 70 bus=pci,qmi-chip [ 3833.092265] ath11k_pci 0000:05:00.0: 00000010: 2d 69 64 3d 33 33 -id=33 [ 3833.092268] ath11k_pci 0000:05:00.0: boot found regdb data for 'bus=pci,vendor=17cb,device=1103,subsystem-vendor=17cb,subsystem-device=3374,qmi-chip-id=2,qmi-board-id=262' [ 3833.092272] ath11k_pci 0000:05:00.0: fetched regdb Tested-on: WCN6855 hw2.0 PCI WLAN.HSP.1.1-03125-QCAHSPSWPL_V1_V2_SILICONZ_LITE-3 Signed-off-by: Wen Gong Signed-off-by: Kalle Valo Link: https://lore.kernel.org/r/20220319023543.14288-4-quic_wgong@quicinc.com --- drivers/net/wireless/ath/ath11k/core.c | 84 ++++++++++++++++++-------- drivers/net/wireless/ath/ath11k/hw.h | 19 ++++++ 2 files changed, 78 insertions(+), 25 deletions(-) diff --git a/drivers/net/wireless/ath/ath11k/core.c b/drivers/net/wireless/ath/ath11k/core.c index 9395a5a271f10..d1d8a2f99196c 100644 --- a/drivers/net/wireless/ath/ath11k/core.c +++ b/drivers/net/wireless/ath/ath11k/core.c @@ -723,7 +723,9 @@ static int ath11k_core_parse_bd_ie_board(struct ath11k_base *ab, struct ath11k_board_data *bd, const void *buf, size_t buf_len, const char *boardname, - int bd_ie_type) + int ie_id, + int name_id, + int data_id) { const struct ath11k_fw_ie *hdr; bool name_match_found; @@ -733,7 +735,7 @@ static int ath11k_core_parse_bd_ie_board(struct ath11k_base *ab, name_match_found = false; - /* go through ATH11K_BD_IE_BOARD_ elements */ + /* go through ATH11K_BD_IE_BOARD_/ATH11K_BD_IE_REGDB_ elements */ while (buf_len > sizeof(struct ath11k_fw_ie)) { hdr = buf; board_ie_id = le32_to_cpu(hdr->id); @@ -744,48 +746,50 @@ static int ath11k_core_parse_bd_ie_board(struct ath11k_base *ab, buf += sizeof(*hdr); if (buf_len < ALIGN(board_ie_len, 4)) { - ath11k_err(ab, "invalid ATH11K_BD_IE_BOARD length: %zu < %zu\n", + ath11k_err(ab, "invalid %s length: %zu < %zu\n", + ath11k_bd_ie_type_str(ie_id), buf_len, ALIGN(board_ie_len, 4)); ret = -EINVAL; goto out; } - switch (board_ie_id) { - case ATH11K_BD_IE_BOARD_NAME: + if (board_ie_id == name_id) { ath11k_dbg_dump(ab, ATH11K_DBG_BOOT, "board name", "", board_ie_data, board_ie_len); if (board_ie_len != strlen(boardname)) - break; + goto next; ret = memcmp(board_ie_data, boardname, strlen(boardname)); if (ret) - break; + goto next; name_match_found = true; ath11k_dbg(ab, ATH11K_DBG_BOOT, - "boot found match for name '%s'", + "boot found match %s for name '%s'", + ath11k_bd_ie_type_str(ie_id), boardname); - break; - case ATH11K_BD_IE_BOARD_DATA: + } else if (board_ie_id == data_id) { if (!name_match_found) /* no match found */ - break; + goto next; ath11k_dbg(ab, ATH11K_DBG_BOOT, - "boot found board data for '%s'", boardname); + "boot found %s for '%s'", + ath11k_bd_ie_type_str(ie_id), + boardname); bd->data = board_ie_data; bd->len = board_ie_len; ret = 0; goto out; - default: - ath11k_warn(ab, "unknown ATH11K_BD_IE_BOARD found: %d\n", + } else { + ath11k_warn(ab, "unknown %s id found: %d\n", + ath11k_bd_ie_type_str(ie_id), board_ie_id); - break; } - +next: /* jump over the padding */ board_ie_len = ALIGN(board_ie_len, 4); @@ -802,7 +806,10 @@ static int ath11k_core_parse_bd_ie_board(struct ath11k_base *ab, static int ath11k_core_fetch_board_data_api_n(struct ath11k_base *ab, struct ath11k_board_data *bd, - const char *boardname) + const char *boardname, + int ie_id_match, + int name_id, + int data_id) { size_t len, magic_len; const u8 *data; @@ -867,22 +874,23 @@ static int ath11k_core_fetch_board_data_api_n(struct ath11k_base *ab, goto err; } - switch (ie_id) { - case ATH11K_BD_IE_BOARD: + if (ie_id == ie_id_match) { ret = ath11k_core_parse_bd_ie_board(ab, bd, data, ie_len, boardname, - ATH11K_BD_IE_BOARD); + ie_id_match, + name_id, + data_id); if (ret == -ENOENT) /* no match found, continue */ - break; + goto next; else if (ret) /* there was an error, bail out */ goto err; /* either found or error, so stop searching */ goto out; } - +next: /* jump over the padding */ ie_len = ALIGN(ie_len, 4); @@ -893,7 +901,8 @@ static int ath11k_core_fetch_board_data_api_n(struct ath11k_base *ab, out: if (!bd->data || !bd->len) { ath11k_dbg(ab, ATH11K_DBG_BOOT, - "failed to fetch board data for %s from %s\n", + "failed to fetch %s for %s from %s\n", + ath11k_bd_ie_type_str(ie_id_match), boardname, filepath); ret = -ENODATA; goto err; @@ -937,7 +946,10 @@ int ath11k_core_fetch_bdf(struct ath11k_base *ab, struct ath11k_board_data *bd) } ab->bd_api = 2; - ret = ath11k_core_fetch_board_data_api_n(ab, bd, boardname); + ret = ath11k_core_fetch_board_data_api_n(ab, bd, boardname, + ATH11K_BD_IE_BOARD, + ATH11K_BD_IE_BOARD_NAME, + ATH11K_BD_IE_BOARD_DATA); if (!ret) goto success; @@ -948,7 +960,10 @@ int ath11k_core_fetch_bdf(struct ath11k_base *ab, struct ath11k_board_data *bd) return ret; } - ret = ath11k_core_fetch_board_data_api_n(ab, bd, fallback_boardname); + ret = ath11k_core_fetch_board_data_api_n(ab, bd, fallback_boardname, + ATH11K_BD_IE_BOARD, + ATH11K_BD_IE_BOARD_NAME, + ATH11K_BD_IE_BOARD_DATA); if (!ret) goto success; @@ -975,13 +990,32 @@ int ath11k_core_fetch_bdf(struct ath11k_base *ab, struct ath11k_board_data *bd) int ath11k_core_fetch_regdb(struct ath11k_base *ab, struct ath11k_board_data *bd) { + char boardname[BOARD_NAME_SIZE]; int ret; + ret = ath11k_core_create_board_name(ab, boardname, BOARD_NAME_SIZE); + if (ret) { + ath11k_dbg(ab, ATH11K_DBG_BOOT, + "failed to create board name for regdb: %d", ret); + goto exit; + } + + ret = ath11k_core_fetch_board_data_api_n(ab, bd, boardname, + ATH11K_BD_IE_REGDB, + ATH11K_BD_IE_REGDB_NAME, + ATH11K_BD_IE_REGDB_DATA); + if (!ret) + goto exit; + ret = ath11k_core_fetch_board_data_api_1(ab, bd, ATH11K_REGDB_FILE_NAME); if (ret) ath11k_dbg(ab, ATH11K_DBG_BOOT, "failed to fetch %s from %s\n", ATH11K_REGDB_FILE_NAME, ab->hw_params.fw.dir); +exit: + if (!ret) + ath11k_dbg(ab, ATH11K_DBG_BOOT, "fetched regdb\n"); + return ret; } diff --git a/drivers/net/wireless/ath/ath11k/hw.h b/drivers/net/wireless/ath/ath11k/hw.h index 5955c6f5da245..44025bc5d0824 100644 --- a/drivers/net/wireless/ath/ath11k/hw.h +++ b/drivers/net/wireless/ath/ath11k/hw.h @@ -291,9 +291,16 @@ enum ath11k_bd_ie_board_type { ATH11K_BD_IE_BOARD_DATA = 1, }; +enum ath11k_bd_ie_regdb_type { + ATH11K_BD_IE_REGDB_NAME = 0, + ATH11K_BD_IE_REGDB_DATA = 1, +}; + enum ath11k_bd_ie_type { /* contains sub IEs of enum ath11k_bd_ie_board_type */ ATH11K_BD_IE_BOARD = 0, + /* contains sub IEs of enum ath11k_bd_ie_regdb_type */ + ATH11K_BD_IE_REGDB = 1, }; struct ath11k_hw_regs { @@ -361,4 +368,16 @@ extern const struct ath11k_hw_regs qca6390_regs; extern const struct ath11k_hw_regs qcn9074_regs; extern const struct ath11k_hw_regs wcn6855_regs; +static inline const char *ath11k_bd_ie_type_str(enum ath11k_bd_ie_type type) +{ + switch (type) { + case ATH11K_BD_IE_BOARD: + return "board data"; + case ATH11K_BD_IE_REGDB: + return "regdb data"; + } + + return "unknown"; +} + #endif From 1f682dc9fb3790aa7ec27d3d122ff32b1eda1365 Mon Sep 17 00:00:00 2001 From: Wen Gong Date: Sun, 27 Mar 2022 23:58:32 -0400 Subject: [PATCH 033/228] ath11k: reduce the wait time of 11d scan and hw scan while add interface Currently ath11k will wait 11d scan complete while add interface in ath11k_mac_op_add_interface(), when system resume without enable wowlan, ath11k_mac_op_add_interface() is called for each resume, thus it increase the resume time of system. And ath11k_mac_op_hw_scan() after ath11k_mac_op_add_interface() also needs some time cost because the previous 11d scan need more than 5 seconds when 6 GHz is enabled, then the scan started event will indicated to ath11k after the 11d scan completed. While 11d scan/hw scan is running in firmware, if ath11k update channel list to firmware by WMI_SCAN_CHAN_LIST_CMDID, then firmware will cancel the current scan which is running, it lead the scan failed. The patch commit 9dcf6808b253 ("ath11k: add 11d scan offload support") used finish_11d_scan/finish_11d_ch_list/pending_11d to synchronize the 11d scan/hw scan/channel list between ath11k/firmware/mac80211 and to avoid the scan fail. Add wait operation before ath11k update channel list, function ath11k_reg_update_chan_list() will wait until the current 11d scan/hw scan completed. And remove the wait operation of start 11d scan and waiting channel list complete in hw scan. After these changes, resume time cost reduce about 5 seconds and also hw scan time cost reduced obviously, and scan failed not seen. The 11d scan is sent to firmware only one time for each interface added in mac.c, and it is moved after the 1st hw scan because 11d scan will cost some time and thus leads the AP scan result update to UI delay. Currently priority of ath11k's hw scan is WMI_SCAN_PRIORITY_LOW, and priority of 11d scan in firmware is WMI_SCAN_PRIORITY_MEDIUM, then the 11d scan which sent after hw scan will cancel the hw scan in firmware, so change the priority to WMI_SCAN_PRIORITY_MEDIUM for the hw scan which is in front of the 11d scan, thus it will not happen scan cancel in firmware. Tested-on: WCN6855 hw2.0 PCI WLAN.HSP.1.1-03125-QCAHSPSWPL_V1_V2_SILICONZ_LITE-3 Fixes: 9dcf6808b253 ("ath11k: add 11d scan offload support") Signed-off-by: Wen Gong Signed-off-by: Kalle Valo Link: https://lore.kernel.org/r/20220328035832.14122-1-quic_wgong@quicinc.com --- drivers/net/wireless/ath/ath11k/core.c | 1 + drivers/net/wireless/ath/ath11k/core.h | 13 +++-- drivers/net/wireless/ath/ath11k/mac.c | 71 +++++++++++--------------- drivers/net/wireless/ath/ath11k/mac.h | 2 +- drivers/net/wireless/ath/ath11k/reg.c | 43 ++++++++++------ drivers/net/wireless/ath/ath11k/reg.h | 2 +- drivers/net/wireless/ath/ath11k/wmi.c | 16 +++++- 7 files changed, 84 insertions(+), 64 deletions(-) diff --git a/drivers/net/wireless/ath/ath11k/core.c b/drivers/net/wireless/ath/ath11k/core.c index d1d8a2f99196c..7f4462cf5787d 100644 --- a/drivers/net/wireless/ath/ath11k/core.c +++ b/drivers/net/wireless/ath/ath11k/core.c @@ -1465,6 +1465,7 @@ static void ath11k_core_pre_reconfigure_recovery(struct ath11k_base *ab) ieee80211_stop_queues(ar->hw); ath11k_mac_drain_tx(ar); + complete(&ar->completed_11d_scan); complete(&ar->scan.started); complete(&ar->scan.completed); complete(&ar->peer_assoc_done); diff --git a/drivers/net/wireless/ath/ath11k/core.h b/drivers/net/wireless/ath/ath11k/core.h index b4d58e01fffaa..17a61d0d684e8 100644 --- a/drivers/net/wireless/ath/ath11k/core.h +++ b/drivers/net/wireless/ath/ath11k/core.h @@ -52,6 +52,8 @@ extern unsigned int ath11k_frame_mode; +#define ATH11K_SCAN_TIMEOUT_HZ (20 * HZ) + #define ATH11K_MON_TIMER_INTERVAL 10 #define ATH11K_RESET_TIMEOUT_HZ (20 * HZ) #define ATH11K_RESET_MAX_FAIL_COUNT_FIRST 3 @@ -216,6 +218,12 @@ enum ath11k_scan_state { ATH11K_SCAN_ABORTING, }; +enum ath11k_11d_state { + ATH11K_11D_IDLE, + ATH11K_11D_PREPARING, + ATH11K_11D_RUNNING, +}; + enum ath11k_dev_flags { ATH11K_CAC_RUNNING, ATH11K_FLAG_CORE_REGISTERED, @@ -664,9 +672,8 @@ struct ath11k { bool dfs_block_radar_events; struct ath11k_thermal thermal; u32 vdev_id_11d_scan; - struct completion finish_11d_scan; - struct completion finish_11d_ch_list; - bool pending_11d; + struct completion completed_11d_scan; + enum ath11k_11d_state state_11d; bool regdom_set_by_user; int hw_rate_code; u8 twt_enabled; diff --git a/drivers/net/wireless/ath/ath11k/mac.c b/drivers/net/wireless/ath/ath11k/mac.c index 9caa8b87c3139..175a4ae752f3a 100644 --- a/drivers/net/wireless/ath/ath11k/mac.c +++ b/drivers/net/wireless/ath/ath11k/mac.c @@ -3621,26 +3621,6 @@ static int ath11k_mac_op_hw_scan(struct ieee80211_hw *hw, if (ret) goto exit; - /* Currently the pending_11d=true only happened 1 time while - * wlan interface up in ath11k_mac_11d_scan_start(), it is called by - * ath11k_mac_op_add_interface(), after wlan interface up, - * pending_11d=false always. - * If remove below wait, it always happened scan fail and lead connect - * fail while wlan interface up, because it has a 11d scan which is running - * in firmware, and lead this scan failed. - */ - if (ar->pending_11d) { - long time_left; - unsigned long timeout = 5 * HZ; - - if (ar->supports_6ghz) - timeout += 5 * HZ; - - time_left = wait_for_completion_timeout(&ar->finish_11d_ch_list, timeout); - ath11k_dbg(ar->ab, ATH11K_DBG_MAC, - "mac wait 11d channel list time left %ld\n", time_left); - } - memset(&arg, 0, sizeof(arg)); ath11k_wmi_start_scan_init(ar, &arg); arg.vdev_id = arvif->vdev_id; @@ -3706,6 +3686,10 @@ static int ath11k_mac_op_hw_scan(struct ieee80211_hw *hw, kfree(arg.extraie.ptr); mutex_unlock(&ar->conf_mutex); + + if (ar->state_11d == ATH11K_11D_PREPARING) + ath11k_mac_11d_scan_start(ar, arvif->vdev_id); + return ret; } @@ -5859,7 +5843,7 @@ static int ath11k_mac_op_start(struct ieee80211_hw *hw) /* TODO: Do we need to enable ANI? */ - ath11k_reg_update_chan_list(ar); + ath11k_reg_update_chan_list(ar, false); ar->num_started_vdevs = 0; ar->num_created_vdevs = 0; @@ -5926,6 +5910,11 @@ static void ath11k_mac_op_stop(struct ieee80211_hw *hw) cancel_work_sync(&ar->ab->update_11d_work); cancel_work_sync(&ar->ab->rfkill_work); + if (ar->state_11d == ATH11K_11D_PREPARING) { + ar->state_11d = ATH11K_11D_IDLE; + complete(&ar->completed_11d_scan); + } + spin_lock_bh(&ar->data_lock); list_for_each_entry_safe(ppdu_stats, tmp, &ar->ppdu_stats_info, list) { list_del(&ppdu_stats->list); @@ -6096,7 +6085,7 @@ static bool ath11k_mac_vif_ap_active_any(struct ath11k_base *ab) return false; } -void ath11k_mac_11d_scan_start(struct ath11k *ar, u32 vdev_id, bool wait) +void ath11k_mac_11d_scan_start(struct ath11k *ar, u32 vdev_id) { struct wmi_11d_scan_start_params param; int ret; @@ -6124,28 +6113,22 @@ void ath11k_mac_11d_scan_start(struct ath11k *ar, u32 vdev_id, bool wait) ath11k_dbg(ar->ab, ATH11K_DBG_MAC, "mac start 11d scan\n"); - if (wait) - reinit_completion(&ar->finish_11d_scan); - ret = ath11k_wmi_send_11d_scan_start_cmd(ar, ¶m); if (ret) { ath11k_warn(ar->ab, "failed to start 11d scan vdev %d ret: %d\n", vdev_id, ret); } else { ar->vdev_id_11d_scan = vdev_id; - if (wait) { - ar->pending_11d = true; - ret = wait_for_completion_timeout(&ar->finish_11d_scan, - 5 * HZ); - ath11k_dbg(ar->ab, ATH11K_DBG_MAC, - "mac 11d scan left time %d\n", ret); - - if (!ret) - ar->pending_11d = false; - } + if (ar->state_11d == ATH11K_11D_PREPARING) + ar->state_11d = ATH11K_11D_RUNNING; } fin: + if (ar->state_11d == ATH11K_11D_PREPARING) { + ar->state_11d = ATH11K_11D_IDLE; + complete(&ar->completed_11d_scan); + } + mutex_unlock(&ar->ab->vdev_id_11d_lock); } @@ -6168,12 +6151,15 @@ void ath11k_mac_11d_scan_stop(struct ath11k *ar) vdev_id = ar->vdev_id_11d_scan; ret = ath11k_wmi_send_11d_scan_stop_cmd(ar, vdev_id); - if (ret) + if (ret) { ath11k_warn(ar->ab, "failed to stopt 11d scan vdev %d ret: %d\n", vdev_id, ret); - else + } else { ar->vdev_id_11d_scan = ATH11K_11D_INVALID_VDEV_ID; + ar->state_11d = ATH11K_11D_IDLE; + complete(&ar->completed_11d_scan); + } } mutex_unlock(&ar->ab->vdev_id_11d_lock); } @@ -6369,8 +6355,10 @@ static int ath11k_mac_op_add_interface(struct ieee80211_hw *hw, goto err_peer_del; } - ath11k_mac_11d_scan_start(ar, arvif->vdev_id, true); - + if (test_bit(WMI_TLV_SERVICE_11D_OFFLOAD, ab->wmi_ab.svc_map)) { + reinit_completion(&ar->completed_11d_scan); + ar->state_11d = ATH11K_11D_PREPARING; + } break; case WMI_VDEV_TYPE_MONITOR: set_bit(ATH11K_FLAG_MONITOR_VDEV_CREATED, &ar->monitor_flags); @@ -7230,7 +7218,7 @@ ath11k_mac_op_unassign_vif_chanctx(struct ieee80211_hw *hw, } if (arvif->vdev_type == WMI_VDEV_TYPE_STA) - ath11k_mac_11d_scan_start(ar, arvif->vdev_id, false); + ath11k_mac_11d_scan_start(ar, arvif->vdev_id); mutex_unlock(&ar->conf_mutex); } @@ -8920,8 +8908,7 @@ int ath11k_mac_allocate(struct ath11k_base *ab) ar->monitor_vdev_id = -1; clear_bit(ATH11K_FLAG_MONITOR_VDEV_CREATED, &ar->monitor_flags); ar->vdev_id_11d_scan = ATH11K_11D_INVALID_VDEV_ID; - init_completion(&ar->finish_11d_scan); - init_completion(&ar->finish_11d_ch_list); + init_completion(&ar->completed_11d_scan); } return 0; diff --git a/drivers/net/wireless/ath/ath11k/mac.h b/drivers/net/wireless/ath/ath11k/mac.h index 045bf4fe17069..7f93e3a9ca233 100644 --- a/drivers/net/wireless/ath/ath11k/mac.h +++ b/drivers/net/wireless/ath/ath11k/mac.h @@ -130,7 +130,7 @@ extern const struct htt_rx_ring_tlv_filter ath11k_mac_mon_status_filter_default; #define ATH11K_SCAN_11D_INTERVAL 600000 #define ATH11K_11D_INVALID_VDEV_ID 0xFFFF -void ath11k_mac_11d_scan_start(struct ath11k *ar, u32 vdev_id, bool wait); +void ath11k_mac_11d_scan_start(struct ath11k *ar, u32 vdev_id); void ath11k_mac_11d_scan_stop(struct ath11k *ar); void ath11k_mac_11d_scan_stop_all(struct ath11k_base *ab); diff --git a/drivers/net/wireless/ath/ath11k/reg.c b/drivers/net/wireless/ath/ath11k/reg.c index 35eb1a0c04dcb..79ac2142317a3 100644 --- a/drivers/net/wireless/ath/ath11k/reg.c +++ b/drivers/net/wireless/ath/ath11k/reg.c @@ -103,7 +103,7 @@ ath11k_reg_notifier(struct wiphy *wiphy, struct regulatory_request *request) ar->regdom_set_by_user = true; } -int ath11k_reg_update_chan_list(struct ath11k *ar) +int ath11k_reg_update_chan_list(struct ath11k *ar, bool wait) { struct ieee80211_supported_band **bands; struct scan_chan_list_params *params; @@ -112,7 +112,32 @@ int ath11k_reg_update_chan_list(struct ath11k *ar) struct channel_param *ch; enum nl80211_band band; int num_channels = 0; - int i, ret; + int i, ret, left; + + if (wait && ar->state_11d != ATH11K_11D_IDLE) { + left = wait_for_completion_timeout(&ar->completed_11d_scan, + ATH11K_SCAN_TIMEOUT_HZ); + if (!left) { + ath11k_dbg(ar->ab, ATH11K_DBG_REG, + "failed to receive 11d scan complete: timed out\n"); + ar->state_11d = ATH11K_11D_IDLE; + } + ath11k_dbg(ar->ab, ATH11K_DBG_REG, + "reg 11d scan wait left time %d\n", left); + } + + if (wait && + (ar->scan.state == ATH11K_SCAN_STARTING || + ar->scan.state == ATH11K_SCAN_RUNNING)) { + left = wait_for_completion_timeout(&ar->scan.completed, + ATH11K_SCAN_TIMEOUT_HZ); + if (!left) + ath11k_dbg(ar->ab, ATH11K_DBG_REG, + "failed to receive hw scan complete: timed out\n"); + + ath11k_dbg(ar->ab, ATH11K_DBG_REG, + "reg hw scan wait left time %d\n", left); + } bands = hw->wiphy->bands; for (band = 0; band < NUM_NL80211_BANDS; band++) { @@ -194,11 +219,6 @@ int ath11k_reg_update_chan_list(struct ath11k *ar) ret = ath11k_wmi_send_scan_chan_list_cmd(ar, params); kfree(params); - if (ar->pending_11d) { - complete(&ar->finish_11d_ch_list); - ar->pending_11d = false; - } - return ret; } @@ -264,15 +284,8 @@ int ath11k_regd_update(struct ath11k *ar) goto err; } - if (ar->pending_11d) - complete(&ar->finish_11d_scan); - rtnl_lock(); wiphy_lock(ar->hw->wiphy); - - if (ar->pending_11d) - reinit_completion(&ar->finish_11d_ch_list); - ret = regulatory_set_wiphy_regd_sync(ar->hw->wiphy, regd_copy); wiphy_unlock(ar->hw->wiphy); rtnl_unlock(); @@ -283,7 +296,7 @@ int ath11k_regd_update(struct ath11k *ar) goto err; if (ar->state == ATH11K_STATE_ON) { - ret = ath11k_reg_update_chan_list(ar); + ret = ath11k_reg_update_chan_list(ar, true); if (ret) goto err; } diff --git a/drivers/net/wireless/ath/ath11k/reg.h b/drivers/net/wireless/ath/ath11k/reg.h index 5fb9dc03a74e8..2f284f26378d1 100644 --- a/drivers/net/wireless/ath/ath11k/reg.h +++ b/drivers/net/wireless/ath/ath11k/reg.h @@ -32,5 +32,5 @@ struct ieee80211_regdomain * ath11k_reg_build_regd(struct ath11k_base *ab, struct cur_regulatory_info *reg_info, bool intersect); int ath11k_regd_update(struct ath11k *ar); -int ath11k_reg_update_chan_list(struct ath11k *ar); +int ath11k_reg_update_chan_list(struct ath11k *ar, bool wait); #endif diff --git a/drivers/net/wireless/ath/ath11k/wmi.c b/drivers/net/wireless/ath/ath11k/wmi.c index 7f97c26bffd9b..3af24b18204ef 100644 --- a/drivers/net/wireless/ath/ath11k/wmi.c +++ b/drivers/net/wireless/ath/ath11k/wmi.c @@ -2015,7 +2015,10 @@ void ath11k_wmi_start_scan_init(struct ath11k *ar, { /* setup commonly used values */ arg->scan_req_id = 1; - arg->scan_priority = WMI_SCAN_PRIORITY_LOW; + if (ar->state_11d == ATH11K_11D_PREPARING) + arg->scan_priority = WMI_SCAN_PRIORITY_MEDIUM; + else + arg->scan_priority = WMI_SCAN_PRIORITY_LOW; arg->dwell_time_active = 50; arg->dwell_time_active_2g = 0; arg->dwell_time_passive = 150; @@ -6350,8 +6353,10 @@ static void ath11k_wmi_op_ep_tx_credits(struct ath11k_base *ab) static int ath11k_reg_11d_new_cc_event(struct ath11k_base *ab, struct sk_buff *skb) { const struct wmi_11d_new_cc_ev *ev; + struct ath11k *ar; + struct ath11k_pdev *pdev; const void **tb; - int ret; + int ret, i; tb = ath11k_wmi_tlv_parse_alloc(ab, skb->data, skb->len, GFP_ATOMIC); if (IS_ERR(tb)) { @@ -6377,6 +6382,13 @@ static int ath11k_reg_11d_new_cc_event(struct ath11k_base *ab, struct sk_buff *s kfree(tb); + for (i = 0; i < ab->num_radios; i++) { + pdev = &ab->pdevs[i]; + ar = pdev->ar; + ar->state_11d = ATH11K_11D_IDLE; + complete(&ar->completed_11d_scan); + } + queue_work(ab->workqueue, &ab->update_11d_work); return 0; From 2c977be2cc5cd4743d2f223360e685d91f0cdffc Mon Sep 17 00:00:00 2001 From: Erik Stromdahl Date: Wed, 30 Mar 2022 11:11:49 +0300 Subject: [PATCH 034/228] ath10k: add support for MSDU IDs for USB devices commit 93bbdec6683e1c8ba2cc4e6 ("ath10k: htt: support MSDU ids with SDIO") introduced MSDU ID allocation in the htt TX path for high latency devices. This feature needs to be enabled for USB as well in order to have a functional TX path. Tested-on: QCA9377 hw1.0 USB 1.0.0.299 Signed-off-by: Erik Stromdahl Signed-off-by: Kalle Valo Link: https://lore.kernel.org/r/20220327171340.7893-1-erik.stromdahl@gmail.com --- drivers/net/wireless/ath/ath10k/usb.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/net/wireless/ath/ath10k/usb.c b/drivers/net/wireless/ath/ath10k/usb.c index 3d98f19c6ec8a..7ed2022ac3c22 100644 --- a/drivers/net/wireless/ath/ath10k/usb.c +++ b/drivers/net/wireless/ath/ath10k/usb.c @@ -1013,6 +1013,7 @@ static int ath10k_usb_probe(struct usb_interface *interface, bus_params.dev_type = ATH10K_DEV_TYPE_HL; /* TODO: don't know yet how to get chip_id with USB */ bus_params.chip_id = 0; + bus_params.hl_msdu_ids = true; ret = ath10k_core_register(ar, &bus_params); if (ret) { ath10k_warn(ar, "failed to register driver core: %d\n", ret); From d930e2560ebee73411cfa5d5b0de4e82254c33e9 Mon Sep 17 00:00:00 2001 From: Erik Stromdahl Date: Wed, 30 Mar 2022 11:11:49 +0300 Subject: [PATCH 035/228] ath10k: enable napi on RX path for usb commit cfee8793a74dc3afabb08fc9 ("ath10k: enable napi on RX path for sdio") introduced napi for SDIO and updated the htt interface for high latency devices. These changes breaks USB, so USB code must be updated to use napi as well in order to have a working RX path. Tested-on: QCA9377 hw1.0 USB 1.0.0.299 Signed-off-by: Erik Stromdahl Signed-off-by: Kalle Valo Link: https://lore.kernel.org/r/20220327171340.7893-2-erik.stromdahl@gmail.com --- drivers/net/wireless/ath/ath10k/usb.c | 26 ++++++++++++++++++++++++++ 1 file changed, 26 insertions(+) diff --git a/drivers/net/wireless/ath/ath10k/usb.c b/drivers/net/wireless/ath/ath10k/usb.c index 7ed2022ac3c22..10df6ca303a1c 100644 --- a/drivers/net/wireless/ath/ath10k/usb.c +++ b/drivers/net/wireless/ath/ath10k/usb.c @@ -345,6 +345,12 @@ static void ath10k_usb_rx_complete(struct ath10k *ar, struct sk_buff *skb) ep->ep_ops.ep_rx_complete(ar, skb); /* The RX complete handler now owns the skb... */ + if (test_bit(ATH10K_FLAG_CORE_REGISTERED, &ar->dev_flags)) { + local_bh_disable(); + napi_schedule(&ar->napi); + local_bh_enable(); + } + return; out_free_skb: @@ -387,6 +393,7 @@ static int ath10k_usb_hif_start(struct ath10k *ar) int i; struct ath10k_usb *ar_usb = ath10k_usb_priv(ar); + ath10k_core_napi_enable(ar); ath10k_usb_start_recv_pipes(ar); /* set the TX resource avail threshold for each TX pipe */ @@ -462,6 +469,7 @@ static int ath10k_usb_hif_tx_sg(struct ath10k *ar, u8 pipe_id, static void ath10k_usb_hif_stop(struct ath10k *ar) { ath10k_usb_flush_all(ar); + ath10k_core_napi_sync_disable(ar); } static u16 ath10k_usb_hif_get_free_queue_number(struct ath10k *ar, u8 pipe_id) @@ -966,6 +974,20 @@ static int ath10k_usb_create(struct ath10k *ar, return ret; } +static int ath10k_usb_napi_poll(struct napi_struct *ctx, int budget) +{ + struct ath10k *ar = container_of(ctx, struct ath10k, napi); + int done; + + done = ath10k_htt_rx_hl_indication(ar, budget); + ath10k_dbg(ar, ATH10K_DBG_USB, "napi poll: done: %d, budget:%d\n", done, budget); + + if (done < budget) + napi_complete_done(ctx, done); + + return done; +} + /* ath10k usb driver registered functions */ static int ath10k_usb_probe(struct usb_interface *interface, const struct usb_device_id *id) @@ -992,6 +1014,9 @@ static int ath10k_usb_probe(struct usb_interface *interface, return -ENOMEM; } + netif_napi_add(&ar->napi_dev, &ar->napi, ath10k_usb_napi_poll, + ATH10K_NAPI_BUDGET); + usb_get_dev(dev); vendor_id = le16_to_cpu(dev->descriptor.idVendor); product_id = le16_to_cpu(dev->descriptor.idProduct); @@ -1045,6 +1070,7 @@ static void ath10k_usb_remove(struct usb_interface *interface) return; ath10k_core_unregister(ar_usb->ar); + netif_napi_del(&ar_usb->ar->napi); ath10k_usb_destroy(ar_usb->ar); usb_put_dev(interface_to_usbdev(interface)); ath10k_core_destroy(ar_usb->ar); From 7c45823064122e8bdc97972e9861ea03b086d0ab Mon Sep 17 00:00:00 2001 From: Wenli Looi Date: Fri, 25 Mar 2022 23:47:55 -0600 Subject: [PATCH 036/228] ath9k: make is2ghz consistent in ar9003_eeprom MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Replace a "mode" variable indicating "is 5ghz" with an "is2ghz" variable to make it consistent with other functions in the file. Signed-off-by: Wenli Looi Acked-by: Toke Høiland-Jørgensen Signed-off-by: Kalle Valo Link: https://lore.kernel.org/r/20220326054754.27812-1-wlooi@ucalgary.ca --- .../net/wireless/ath/ath9k/ar9003_eeprom.c | 46 +++++++++---------- 1 file changed, 21 insertions(+), 25 deletions(-) diff --git a/drivers/net/wireless/ath/ath9k/ar9003_eeprom.c b/drivers/net/wireless/ath/ath9k/ar9003_eeprom.c index abf12de0e3814..16bfcd0a1f6e0 100644 --- a/drivers/net/wireless/ath/ath9k/ar9003_eeprom.c +++ b/drivers/net/wireless/ath/ath9k/ar9003_eeprom.c @@ -4747,7 +4747,7 @@ static void ar9003_hw_get_target_power_eeprom(struct ath_hw *ah, } static int ar9003_hw_cal_pier_get(struct ath_hw *ah, - int mode, + bool is2ghz, int ipier, int ichain, int *pfrequency, @@ -4757,7 +4757,6 @@ static int ar9003_hw_cal_pier_get(struct ath_hw *ah, { u8 *pCalPier; struct ar9300_cal_data_per_freq_op_loop *pCalPierStruct; - int is2GHz; struct ar9300_eeprom *eep = &ah->eeprom.ar9300_eep; struct ath_common *common = ath9k_hw_common(ah); @@ -4768,17 +4767,7 @@ static int ar9003_hw_cal_pier_get(struct ath_hw *ah, return -1; } - if (mode) { /* 5GHz */ - if (ipier >= AR9300_NUM_5G_CAL_PIERS) { - ath_dbg(common, EEPROM, - "Invalid 5GHz cal pier index, must be less than %d\n", - AR9300_NUM_5G_CAL_PIERS); - return -1; - } - pCalPier = &(eep->calFreqPier5G[ipier]); - pCalPierStruct = &(eep->calPierData5G[ichain][ipier]); - is2GHz = 0; - } else { + if (is2ghz) { if (ipier >= AR9300_NUM_2G_CAL_PIERS) { ath_dbg(common, EEPROM, "Invalid 2GHz cal pier index, must be less than %d\n", @@ -4788,10 +4777,18 @@ static int ar9003_hw_cal_pier_get(struct ath_hw *ah, pCalPier = &(eep->calFreqPier2G[ipier]); pCalPierStruct = &(eep->calPierData2G[ichain][ipier]); - is2GHz = 1; + } else { + if (ipier >= AR9300_NUM_5G_CAL_PIERS) { + ath_dbg(common, EEPROM, + "Invalid 5GHz cal pier index, must be less than %d\n", + AR9300_NUM_5G_CAL_PIERS); + return -1; + } + pCalPier = &(eep->calFreqPier5G[ipier]); + pCalPierStruct = &(eep->calPierData5G[ichain][ipier]); } - *pfrequency = ath9k_hw_fbin2freq(*pCalPier, is2GHz); + *pfrequency = ath9k_hw_fbin2freq(*pCalPier, is2ghz); *pcorrection = pCalPierStruct->refPower; *ptemperature = pCalPierStruct->tempMeas; *pvoltage = pCalPierStruct->voltMeas; @@ -4960,7 +4957,6 @@ static void ar9003_hw_power_control_override(struct ath_hw *ah, static int ar9003_hw_calibration_apply(struct ath_hw *ah, int frequency) { int ichain, ipier, npier; - int mode; int lfrequency[AR9300_MAX_CHAINS], lcorrection[AR9300_MAX_CHAINS], ltemperature[AR9300_MAX_CHAINS], lvoltage[AR9300_MAX_CHAINS], @@ -4976,12 +4972,12 @@ static int ar9003_hw_calibration_apply(struct ath_hw *ah, int frequency) int pfrequency, pcorrection, ptemperature, pvoltage, pnf_cal, pnf_pwr; struct ath_common *common = ath9k_hw_common(ah); + bool is2ghz = frequency < 4000; - mode = (frequency >= 4000); - if (mode) - npier = AR9300_NUM_5G_CAL_PIERS; - else + if (is2ghz) npier = AR9300_NUM_2G_CAL_PIERS; + else + npier = AR9300_NUM_5G_CAL_PIERS; for (ichain = 0; ichain < AR9300_MAX_CHAINS; ichain++) { lfrequency[ichain] = 0; @@ -4990,7 +4986,7 @@ static int ar9003_hw_calibration_apply(struct ath_hw *ah, int frequency) /* identify best lower and higher frequency calibration measurement */ for (ichain = 0; ichain < AR9300_MAX_CHAINS; ichain++) { for (ipier = 0; ipier < npier; ipier++) { - if (!ar9003_hw_cal_pier_get(ah, mode, ipier, ichain, + if (!ar9003_hw_cal_pier_get(ah, is2ghz, ipier, ichain, &pfrequency, &pcorrection, &ptemperature, &pvoltage, &pnf_cal, &pnf_pwr)) { @@ -5127,12 +5123,12 @@ static int ar9003_hw_calibration_apply(struct ath_hw *ah, int frequency) /* Store calibrated noise floor values */ for (ichain = 0; ichain < AR9300_MAX_CHAINS; ichain++) - if (mode) { - ah->nf_5g.cal[ichain] = nf_cal[ichain]; - ah->nf_5g.pwr[ichain] = nf_pwr[ichain]; - } else { + if (is2ghz) { ah->nf_2g.cal[ichain] = nf_cal[ichain]; ah->nf_2g.pwr[ichain] = nf_pwr[ichain]; + } else { + ah->nf_5g.cal[ichain] = nf_cal[ichain]; + ah->nf_5g.pwr[ichain] = nf_pwr[ichain]; } return 0; From 9149a94adad204a1301b55bd49ea1c12c179d144 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Benjamin=20St=C3=BCrz?= Date: Mon, 28 Mar 2022 23:29:12 +0200 Subject: [PATCH 037/228] wcn36xx: Improve readability of wcn36xx_caps_name MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Use macros to force strict ordering of the elements. Signed-off-by: Benjamin Stürz Reviewed-by: Jeff Johnson Signed-off-by: Kalle Valo Link: https://lore.kernel.org/r/20220328212912.283393-1-benni@stuerz.xyz --- drivers/net/wireless/ath/wcn36xx/main.c | 126 ++++++++++++------------ 1 file changed, 65 insertions(+), 61 deletions(-) diff --git a/drivers/net/wireless/ath/wcn36xx/main.c b/drivers/net/wireless/ath/wcn36xx/main.c index 864d1547e6f83..61c47f958e4af 100644 --- a/drivers/net/wireless/ath/wcn36xx/main.c +++ b/drivers/net/wireless/ath/wcn36xx/main.c @@ -192,70 +192,74 @@ static inline u8 get_sta_index(struct ieee80211_vif *vif, sta_priv->sta_index; } +#define DEFINE(s) [s] = #s + static const char * const wcn36xx_caps_names[] = { - "MCC", /* 0 */ - "P2P", /* 1 */ - "DOT11AC", /* 2 */ - "SLM_SESSIONIZATION", /* 3 */ - "DOT11AC_OPMODE", /* 4 */ - "SAP32STA", /* 5 */ - "TDLS", /* 6 */ - "P2P_GO_NOA_DECOUPLE_INIT_SCAN",/* 7 */ - "WLANACTIVE_OFFLOAD", /* 8 */ - "BEACON_OFFLOAD", /* 9 */ - "SCAN_OFFLOAD", /* 10 */ - "ROAM_OFFLOAD", /* 11 */ - "BCN_MISS_OFFLOAD", /* 12 */ - "STA_POWERSAVE", /* 13 */ - "STA_ADVANCED_PWRSAVE", /* 14 */ - "AP_UAPSD", /* 15 */ - "AP_DFS", /* 16 */ - "BLOCKACK", /* 17 */ - "PHY_ERR", /* 18 */ - "BCN_FILTER", /* 19 */ - "RTT", /* 20 */ - "RATECTRL", /* 21 */ - "WOW", /* 22 */ - "WLAN_ROAM_SCAN_OFFLOAD", /* 23 */ - "SPECULATIVE_PS_POLL", /* 24 */ - "SCAN_SCH", /* 25 */ - "IBSS_HEARTBEAT_OFFLOAD", /* 26 */ - "WLAN_SCAN_OFFLOAD", /* 27 */ - "WLAN_PERIODIC_TX_PTRN", /* 28 */ - "ADVANCE_TDLS", /* 29 */ - "BATCH_SCAN", /* 30 */ - "FW_IN_TX_PATH", /* 31 */ - "EXTENDED_NSOFFLOAD_SLOT", /* 32 */ - "CH_SWITCH_V1", /* 33 */ - "HT40_OBSS_SCAN", /* 34 */ - "UPDATE_CHANNEL_LIST", /* 35 */ - "WLAN_MCADDR_FLT", /* 36 */ - "WLAN_CH144", /* 37 */ - "NAN", /* 38 */ - "TDLS_SCAN_COEXISTENCE", /* 39 */ - "LINK_LAYER_STATS_MEAS", /* 40 */ - "MU_MIMO", /* 41 */ - "EXTENDED_SCAN", /* 42 */ - "DYNAMIC_WMM_PS", /* 43 */ - "MAC_SPOOFED_SCAN", /* 44 */ - "BMU_ERROR_GENERIC_RECOVERY", /* 45 */ - "DISA", /* 46 */ - "FW_STATS", /* 47 */ - "WPS_PRBRSP_TMPL", /* 48 */ - "BCN_IE_FLT_DELTA", /* 49 */ - "TDLS_OFF_CHANNEL", /* 51 */ - "RTT3", /* 52 */ - "MGMT_FRAME_LOGGING", /* 53 */ - "ENHANCED_TXBD_COMPLETION", /* 54 */ - "LOGGING_ENHANCEMENT", /* 55 */ - "EXT_SCAN_ENHANCED", /* 56 */ - "MEMORY_DUMP_SUPPORTED", /* 57 */ - "PER_PKT_STATS_SUPPORTED", /* 58 */ - "EXT_LL_STAT", /* 60 */ - "WIFI_CONFIG", /* 61 */ - "ANTENNA_DIVERSITY_SELECTION", /* 62 */ + DEFINE(MCC), + DEFINE(P2P), + DEFINE(DOT11AC), + DEFINE(SLM_SESSIONIZATION), + DEFINE(DOT11AC_OPMODE), + DEFINE(SAP32STA), + DEFINE(TDLS), + DEFINE(P2P_GO_NOA_DECOUPLE_INIT_SCAN), + DEFINE(WLANACTIVE_OFFLOAD), + DEFINE(BEACON_OFFLOAD), + DEFINE(SCAN_OFFLOAD), + DEFINE(ROAM_OFFLOAD), + DEFINE(BCN_MISS_OFFLOAD), + DEFINE(STA_POWERSAVE), + DEFINE(STA_ADVANCED_PWRSAVE), + DEFINE(AP_UAPSD), + DEFINE(AP_DFS), + DEFINE(BLOCKACK), + DEFINE(PHY_ERR), + DEFINE(BCN_FILTER), + DEFINE(RTT), + DEFINE(RATECTRL), + DEFINE(WOW), + DEFINE(WLAN_ROAM_SCAN_OFFLOAD), + DEFINE(SPECULATIVE_PS_POLL), + DEFINE(SCAN_SCH), + DEFINE(IBSS_HEARTBEAT_OFFLOAD), + DEFINE(WLAN_SCAN_OFFLOAD), + DEFINE(WLAN_PERIODIC_TX_PTRN), + DEFINE(ADVANCE_TDLS), + DEFINE(BATCH_SCAN), + DEFINE(FW_IN_TX_PATH), + DEFINE(EXTENDED_NSOFFLOAD_SLOT), + DEFINE(CH_SWITCH_V1), + DEFINE(HT40_OBSS_SCAN), + DEFINE(UPDATE_CHANNEL_LIST), + DEFINE(WLAN_MCADDR_FLT), + DEFINE(WLAN_CH144), + DEFINE(NAN), + DEFINE(TDLS_SCAN_COEXISTENCE), + DEFINE(LINK_LAYER_STATS_MEAS), + DEFINE(MU_MIMO), + DEFINE(EXTENDED_SCAN), + DEFINE(DYNAMIC_WMM_PS), + DEFINE(MAC_SPOOFED_SCAN), + DEFINE(BMU_ERROR_GENERIC_RECOVERY), + DEFINE(DISA), + DEFINE(FW_STATS), + DEFINE(WPS_PRBRSP_TMPL), + DEFINE(BCN_IE_FLT_DELTA), + DEFINE(TDLS_OFF_CHANNEL), + DEFINE(RTT3), + DEFINE(MGMT_FRAME_LOGGING), + DEFINE(ENHANCED_TXBD_COMPLETION), + DEFINE(LOGGING_ENHANCEMENT), + DEFINE(EXT_SCAN_ENHANCED), + DEFINE(MEMORY_DUMP_SUPPORTED), + DEFINE(PER_PKT_STATS_SUPPORTED), + DEFINE(EXT_LL_STAT), + DEFINE(WIFI_CONFIG), + DEFINE(ANTENNA_DIVERSITY_SELECTION), }; +#undef DEFINE + static const char *wcn36xx_get_cap_name(enum place_holder_in_cap_bitmap x) { if (x >= ARRAY_SIZE(wcn36xx_caps_names)) From 948171b5f6fcf11253355bd836e6e8b613bea12f Mon Sep 17 00:00:00 2001 From: Manikanta Pubbisetty Date: Fri, 1 Apr 2022 14:53:08 +0300 Subject: [PATCH 038/228] ath11k: PCI changes to support WCN6750 In order to add the support for WCN6750 in ATH11K , it is required to move certain PCI definitions to the header file. As a result, add ATH11K_PCI_* prefix to these definitions. Also, change the scope of certain PCI APIs that are required to enable WCN6750 from static to global. Tested-on: WCN6855 hw2.0 PCI WLAN.HSP.1.1-01720.1-QCAHSPSWPL_V1_V2_SILICONZ_LITE-1 Tested-on: QCN9074 hw1.0 PCI WLAN.HK.2.5.0.1-01100-QCAHKSWPL_SILICONZ-1 Tested-on: IPQ8074 hw2.0 AHB WLAN.HK.2.4.0.1-00192-QCAHKSWPL_SILICONZ-1 Signed-off-by: Manikanta Pubbisetty Signed-off-by: Kalle Valo Link: https://lore.kernel.org/r/20220328055714.6449-2-quic_mpubbise@quicinc.com --- drivers/net/wireless/ath/ath11k/pci.c | 110 ++++++++++++-------------- drivers/net/wireless/ath/ath11k/pci.h | 35 ++++++++ 2 files changed, 84 insertions(+), 61 deletions(-) diff --git a/drivers/net/wireless/ath/ath11k/pci.c b/drivers/net/wireless/ath/ath11k/pci.c index 8a3ff12057e89..5e71eafdf9a36 100644 --- a/drivers/net/wireless/ath/ath11k/pci.c +++ b/drivers/net/wireless/ath/ath11k/pci.c @@ -1,6 +1,7 @@ // SPDX-License-Identifier: BSD-3-Clause-Clear /* * Copyright (c) 2019-2020 The Linux Foundation. All rights reserved. + * Copyright (c) 2021-2022, Qualcomm Innovation Center, Inc. All rights reserved. */ #include @@ -17,25 +18,10 @@ #define ATH11K_PCI_BAR_NUM 0 #define ATH11K_PCI_DMA_MASK 32 -#define ATH11K_PCI_IRQ_CE0_OFFSET 3 -#define ATH11K_PCI_IRQ_DP_OFFSET 14 - -#define WINDOW_ENABLE_BIT 0x40000000 -#define WINDOW_REG_ADDRESS 0x310c -#define WINDOW_VALUE_MASK GENMASK(24, 19) -#define WINDOW_START 0x80000 -#define WINDOW_RANGE_MASK GENMASK(18, 0) - #define TCSR_SOC_HW_VERSION 0x0224 #define TCSR_SOC_HW_VERSION_MAJOR_MASK GENMASK(11, 8) #define TCSR_SOC_HW_VERSION_MINOR_MASK GENMASK(7, 0) -/* BAR0 + 4k is always accessible, and no - * need to force wakeup. - * 4K - 32 = 0xFE0 - */ -#define ACCESS_ALWAYS_OFF 0xFE0 - #define QCA6390_DEVICE_ID 0x1101 #define QCN9074_DEVICE_ID 0x1104 #define WCN6855_DEVICE_ID 0x1103 @@ -147,27 +133,30 @@ static inline void ath11k_pci_select_window(struct ath11k_pci *ab_pci, u32 offse { struct ath11k_base *ab = ab_pci->ab; - u32 window = FIELD_GET(WINDOW_VALUE_MASK, offset); + u32 window = FIELD_GET(ATH11K_PCI_WINDOW_VALUE_MASK, offset); lockdep_assert_held(&ab_pci->window_lock); if (window != ab_pci->register_window) { - iowrite32(WINDOW_ENABLE_BIT | window, - ab->mem + WINDOW_REG_ADDRESS); - ioread32(ab->mem + WINDOW_REG_ADDRESS); + iowrite32(ATH11K_PCI_WINDOW_ENABLE_BIT | window, + ab->mem + ATH11K_PCI_WINDOW_REG_ADDRESS); + ioread32(ab->mem + ATH11K_PCI_WINDOW_REG_ADDRESS); ab_pci->register_window = window; } } static inline void ath11k_pci_select_static_window(struct ath11k_pci *ab_pci) { - u32 umac_window = FIELD_GET(WINDOW_VALUE_MASK, HAL_SEQ_WCSS_UMAC_OFFSET); - u32 ce_window = FIELD_GET(WINDOW_VALUE_MASK, HAL_CE_WFSS_CE_REG_BASE); + u32 umac_window; + u32 ce_window; u32 window; + umac_window = FIELD_GET(ATH11K_PCI_WINDOW_VALUE_MASK, HAL_SEQ_WCSS_UMAC_OFFSET); + ce_window = FIELD_GET(ATH11K_PCI_WINDOW_VALUE_MASK, HAL_CE_WFSS_CE_REG_BASE); window = (umac_window << 12) | (ce_window << 6); - iowrite32(WINDOW_ENABLE_BIT | window, ab_pci->ab->mem + WINDOW_REG_ADDRESS); + iowrite32(ATH11K_PCI_WINDOW_ENABLE_BIT | window, + ab_pci->ab->mem + ATH11K_PCI_WINDOW_REG_ADDRESS); } static inline u32 ath11k_pci_get_window_start(struct ath11k_base *ab, @@ -176,13 +165,13 @@ static inline u32 ath11k_pci_get_window_start(struct ath11k_base *ab, u32 window_start; /* If offset lies within DP register range, use 3rd window */ - if ((offset ^ HAL_SEQ_WCSS_UMAC_OFFSET) < WINDOW_RANGE_MASK) - window_start = 3 * WINDOW_START; + if ((offset ^ HAL_SEQ_WCSS_UMAC_OFFSET) < ATH11K_PCI_WINDOW_RANGE_MASK) + window_start = 3 * ATH11K_PCI_WINDOW_START; /* If offset lies within CE register range, use 2nd window */ - else if ((offset ^ HAL_CE_WFSS_CE_REG_BASE) < WINDOW_RANGE_MASK) - window_start = 2 * WINDOW_START; + else if ((offset ^ HAL_CE_WFSS_CE_REG_BASE) < ATH11K_PCI_WINDOW_RANGE_MASK) + window_start = 2 * ATH11K_PCI_WINDOW_START; else - window_start = WINDOW_START; + window_start = ATH11K_PCI_WINDOW_START; return window_start; } @@ -198,32 +187,32 @@ void ath11k_pci_write32(struct ath11k_base *ab, u32 offset, u32 value) */ if (ab->hw_params.wakeup_mhi && test_bit(ATH11K_PCI_FLAG_INIT_DONE, &ab_pci->flags) && - offset >= ACCESS_ALWAYS_OFF) + offset >= ATH11K_PCI_ACCESS_ALWAYS_OFF) ret = mhi_device_get_sync(ab_pci->mhi_ctrl->mhi_dev); - if (offset < WINDOW_START) { + if (offset < ATH11K_PCI_WINDOW_START) { iowrite32(value, ab->mem + offset); } else { if (ab->bus_params.static_window_map) window_start = ath11k_pci_get_window_start(ab, offset); else - window_start = WINDOW_START; + window_start = ATH11K_PCI_WINDOW_START; - if (window_start == WINDOW_START) { + if (window_start == ATH11K_PCI_WINDOW_START) { spin_lock_bh(&ab_pci->window_lock); ath11k_pci_select_window(ab_pci, offset); iowrite32(value, ab->mem + window_start + - (offset & WINDOW_RANGE_MASK)); + (offset & ATH11K_PCI_WINDOW_RANGE_MASK)); spin_unlock_bh(&ab_pci->window_lock); } else { iowrite32(value, ab->mem + window_start + - (offset & WINDOW_RANGE_MASK)); + (offset & ATH11K_PCI_WINDOW_RANGE_MASK)); } } if (ab->hw_params.wakeup_mhi && test_bit(ATH11K_PCI_FLAG_INIT_DONE, &ab_pci->flags) && - offset >= ACCESS_ALWAYS_OFF && + offset >= ATH11K_PCI_ACCESS_ALWAYS_OFF && !ret) mhi_device_put(ab_pci->mhi_ctrl->mhi_dev); } @@ -239,32 +228,32 @@ u32 ath11k_pci_read32(struct ath11k_base *ab, u32 offset) */ if (ab->hw_params.wakeup_mhi && test_bit(ATH11K_PCI_FLAG_INIT_DONE, &ab_pci->flags) && - offset >= ACCESS_ALWAYS_OFF) + offset >= ATH11K_PCI_ACCESS_ALWAYS_OFF) ret = mhi_device_get_sync(ab_pci->mhi_ctrl->mhi_dev); - if (offset < WINDOW_START) { + if (offset < ATH11K_PCI_WINDOW_START) { val = ioread32(ab->mem + offset); } else { if (ab->bus_params.static_window_map) window_start = ath11k_pci_get_window_start(ab, offset); else - window_start = WINDOW_START; + window_start = ATH11K_PCI_WINDOW_START; - if (window_start == WINDOW_START) { + if (window_start == ATH11K_PCI_WINDOW_START) { spin_lock_bh(&ab_pci->window_lock); ath11k_pci_select_window(ab_pci, offset); val = ioread32(ab->mem + window_start + - (offset & WINDOW_RANGE_MASK)); + (offset & ATH11K_PCI_WINDOW_RANGE_MASK)); spin_unlock_bh(&ab_pci->window_lock); } else { val = ioread32(ab->mem + window_start + - (offset & WINDOW_RANGE_MASK)); + (offset & ATH11K_PCI_WINDOW_RANGE_MASK)); } } if (ab->hw_params.wakeup_mhi && test_bit(ATH11K_PCI_FLAG_INIT_DONE, &ab_pci->flags) && - offset >= ACCESS_ALWAYS_OFF && + offset >= ATH11K_PCI_ACCESS_ALWAYS_OFF && !ret) mhi_device_put(ab_pci->mhi_ctrl->mhi_dev); @@ -474,8 +463,8 @@ int ath11k_pci_get_msi_irq(struct device *dev, unsigned int vector) return pci_irq_vector(pci_dev, vector); } -static void ath11k_pci_get_msi_address(struct ath11k_base *ab, u32 *msi_addr_lo, - u32 *msi_addr_hi) +void ath11k_pci_get_msi_address(struct ath11k_base *ab, u32 *msi_addr_lo, + u32 *msi_addr_hi) { struct ath11k_pci *ab_pci = ath11k_pci_priv(ab); struct pci_dev *pci_dev = to_pci_dev(ab->dev); @@ -519,8 +508,7 @@ int ath11k_pci_get_user_msi_assignment(struct ath11k_pci *ab_pci, char *user_nam return -EINVAL; } -static void ath11k_pci_get_ce_msi_idx(struct ath11k_base *ab, u32 ce_id, - u32 *msi_idx) +void ath11k_pci_get_ce_msi_idx(struct ath11k_base *ab, u32 ce_id, u32 *msi_idx) { u32 i, msi_data_idx; @@ -536,9 +524,9 @@ static void ath11k_pci_get_ce_msi_idx(struct ath11k_base *ab, u32 ce_id, *msi_idx = msi_data_idx; } -static int ath11k_get_user_msi_assignment(struct ath11k_base *ab, char *user_name, - int *num_vectors, u32 *user_base_data, - u32 *base_vector) +int ath11k_get_user_msi_assignment(struct ath11k_base *ab, char *user_name, + int *num_vectors, u32 *user_base_data, + u32 *base_vector) { struct ath11k_pci *ab_pci = ath11k_pci_priv(ab); @@ -561,7 +549,7 @@ static void ath11k_pci_free_ext_irq(struct ath11k_base *ab) } } -static void ath11k_pci_free_irq(struct ath11k_base *ab) +void ath11k_pci_free_irq(struct ath11k_base *ab) { int i, irq_idx; @@ -710,7 +698,7 @@ static void ath11k_pci_ext_grp_enable(struct ath11k_ext_irq_grp *irq_grp) enable_irq(irq_grp->ab->irq_num[irq_grp->irqs[i]]); } -static void ath11k_pci_ext_irq_enable(struct ath11k_base *ab) +void ath11k_pci_ext_irq_enable(struct ath11k_base *ab) { int i; @@ -741,7 +729,7 @@ static void ath11k_pci_sync_ext_irqs(struct ath11k_base *ab) } } -static void ath11k_pci_ext_irq_disable(struct ath11k_base *ab) +void ath11k_pci_ext_irq_disable(struct ath11k_base *ab) { __ath11k_pci_ext_irq_disable(ab); ath11k_pci_sync_ext_irqs(ab); @@ -854,8 +842,8 @@ static int ath11k_pci_ext_irq_config(struct ath11k_base *ab) return 0; } -static int ath11k_pci_set_irq_affinity_hint(struct ath11k_pci *ab_pci, - const struct cpumask *m) +int ath11k_pci_set_irq_affinity_hint(struct ath11k_pci *ab_pci, + const struct cpumask *m) { if (test_bit(ATH11K_PCI_FLAG_MULTI_MSI_VECTORS, &ab_pci->flags)) return 0; @@ -863,7 +851,7 @@ static int ath11k_pci_set_irq_affinity_hint(struct ath11k_pci *ab_pci, return irq_set_affinity_hint(ab_pci->pdev->irq, m); } -static int ath11k_pci_config_irq(struct ath11k_base *ab) +int ath11k_pci_config_irq(struct ath11k_base *ab) { struct ath11k_pci *ab_pci = ath11k_pci_priv(ab); struct ath11k_ce_pipe *ce_pipe; @@ -939,7 +927,7 @@ static void ath11k_pci_init_qmi_ce_config(struct ath11k_base *ab) &cfg->shadow_reg_v2_len); } -static void ath11k_pci_ce_irqs_enable(struct ath11k_base *ab) +void ath11k_pci_ce_irqs_enable(struct ath11k_base *ab) { int i; @@ -1151,7 +1139,7 @@ static void ath11k_pci_aspm_disable(struct ath11k_pci *ab_pci) set_bit(ATH11K_PCI_ASPM_RESTORE, &ab_pci->flags); } -static void ath11k_pci_aspm_restore(struct ath11k_pci *ab_pci) +void ath11k_pci_aspm_restore(struct ath11k_pci *ab_pci) { if (test_and_clear_bit(ATH11K_PCI_ASPM_RESTORE, &ab_pci->flags)) pcie_capability_write_word(ab_pci->pdev, PCI_EXP_LNKCTL, @@ -1234,20 +1222,20 @@ static void ath11k_pci_kill_tasklets(struct ath11k_base *ab) } } -static void ath11k_pci_ce_irq_disable_sync(struct ath11k_base *ab) +void ath11k_pci_ce_irq_disable_sync(struct ath11k_base *ab) { ath11k_pci_ce_irqs_disable(ab); ath11k_pci_sync_ce_irqs(ab); ath11k_pci_kill_tasklets(ab); } -static void ath11k_pci_stop(struct ath11k_base *ab) +void ath11k_pci_stop(struct ath11k_base *ab) { ath11k_pci_ce_irq_disable_sync(ab); ath11k_ce_cleanup_pipes(ab); } -static int ath11k_pci_start(struct ath11k_base *ab) +int ath11k_pci_start(struct ath11k_base *ab) { struct ath11k_pci *ab_pci = ath11k_pci_priv(ab); @@ -1277,8 +1265,8 @@ static void ath11k_pci_hif_ce_irq_disable(struct ath11k_base *ab) ath11k_pci_ce_irq_disable_sync(ab); } -static int ath11k_pci_map_service_to_pipe(struct ath11k_base *ab, u16 service_id, - u8 *ul_pipe, u8 *dl_pipe) +int ath11k_pci_map_service_to_pipe(struct ath11k_base *ab, u16 service_id, + u8 *ul_pipe, u8 *dl_pipe) { const struct service_to_pipe *entry; bool ul_set = false, dl_set = false; diff --git a/drivers/net/wireless/ath/ath11k/pci.h b/drivers/net/wireless/ath/ath11k/pci.h index 61d67b20a0eb4..31ee843c1cabc 100644 --- a/drivers/net/wireless/ath/ath11k/pci.h +++ b/drivers/net/wireless/ath/ath11k/pci.h @@ -1,6 +1,7 @@ /* SPDX-License-Identifier: BSD-3-Clause-Clear */ /* * Copyright (c) 2019-2020 The Linux Foundation. All rights reserved. + * Copyright (c) 2021-2022, Qualcomm Innovation Center, Inc. All rights reserved. */ #ifndef _ATH11K_PCI_H #define _ATH11K_PCI_H @@ -52,6 +53,21 @@ #define WLAON_QFPROM_PWR_CTRL_REG 0x01f8031c #define QFPROM_PWR_CTRL_VDD4BLOW_MASK 0x4 +#define ATH11K_PCI_IRQ_CE0_OFFSET 3 +#define ATH11K_PCI_IRQ_DP_OFFSET 14 + +#define ATH11K_PCI_WINDOW_ENABLE_BIT 0x40000000 +#define ATH11K_PCI_WINDOW_REG_ADDRESS 0x310c +#define ATH11K_PCI_WINDOW_VALUE_MASK GENMASK(24, 19) +#define ATH11K_PCI_WINDOW_START 0x80000 +#define ATH11K_PCI_WINDOW_RANGE_MASK GENMASK(18, 0) + +/* BAR0 + 4k is always accessible, and no + * need to force wakeup. + * 4K - 32 = 0xFE0 + */ +#define ATH11K_PCI_ACCESS_ALWAYS_OFF 0xFE0 + struct ath11k_msi_user { char *name; int num_vectors; @@ -103,5 +119,24 @@ int ath11k_pci_get_user_msi_assignment(struct ath11k_pci *ar_pci, char *user_nam int ath11k_pci_get_msi_irq(struct device *dev, unsigned int vector); void ath11k_pci_write32(struct ath11k_base *ab, u32 offset, u32 value); u32 ath11k_pci_read32(struct ath11k_base *ab, u32 offset); +void ath11k_pci_get_msi_address(struct ath11k_base *ab, u32 *msi_addr_lo, + u32 *msi_addr_hi); +void ath11k_pci_get_ce_msi_idx(struct ath11k_base *ab, u32 ce_id, u32 *msi_idx); +void ath11k_pci_free_irq(struct ath11k_base *ab); +int ath11k_pci_config_irq(struct ath11k_base *ab); +void ath11k_pci_ext_irq_enable(struct ath11k_base *ab); +void ath11k_pci_ext_irq_disable(struct ath11k_base *ab); +void ath11k_pci_stop(struct ath11k_base *ab); +int ath11k_pci_start(struct ath11k_base *ab); +int ath11k_pci_map_service_to_pipe(struct ath11k_base *ab, u16 service_id, + u8 *ul_pipe, u8 *dl_pipe); +void ath11k_pci_ce_irqs_enable(struct ath11k_base *ab); +void ath11k_pci_ce_irq_disable_sync(struct ath11k_base *ab); +int ath11k_get_user_msi_assignment(struct ath11k_base *ab, char *user_name, + int *num_vectors, u32 *user_base_data, + u32 *base_vector); +void ath11k_pci_aspm_restore(struct ath11k_pci *ab_pci); +int ath11k_pci_set_irq_affinity_hint(struct ath11k_pci *ab_pci, + const struct cpumask *m); #endif From bbfdc5a751a634fcdaae669cc98b3d0e1dc0eedf Mon Sep 17 00:00:00 2001 From: Manikanta Pubbisetty Date: Fri, 1 Apr 2022 14:53:08 +0300 Subject: [PATCH 039/228] ath11k: Refactor PCI code to support WCN6750 Unlike other ATH11K PCIe devices which are enumerated by APSS processor (Application Processor SubSystem), WCN6750 gets enumerated by the WPSS Q6 processor (Wireless Processor SubSystem); In simple terms, though WCN6750 is PCIe device, it is not attached to the APSS processor, APSS will not know of such a device being present in the system and therefore WCN6750 will be registered as a platform device to the kernel core like other supported AHB devices. WCN6750 needs both AHB and PCI APIs for it's operation, it uses AHB APIs for device probe/boot and PCI APIs for device setup and register accesses. Because of this nature, it is referred as a hybrid bus device. Refactor PCI code to support hybrid bus devices like WCN6750. Tested-on: WCN6855 hw2.0 PCI WLAN.HSP.1.1-01720.1-QCAHSPSWPL_V1_V2_SILICONZ_LITE-1 Tested-on: QCN9074 hw1.0 PCI WLAN.HK.2.5.0.1-01100-QCAHKSWPL_SILICONZ-1 Tested-on: IPQ8074 hw2.0 AHB WLAN.HK.2.4.0.1-00192-QCAHKSWPL_SILICONZ-1 Signed-off-by: Manikanta Pubbisetty Signed-off-by: Kalle Valo Link: https://lore.kernel.org/r/20220328055714.6449-3-quic_mpubbise@quicinc.com --- drivers/net/wireless/ath/ath11k/Makefile | 2 +- drivers/net/wireless/ath/ath11k/mhi.c | 27 +- drivers/net/wireless/ath/ath11k/pci.c | 816 ++--------------------- drivers/net/wireless/ath/ath11k/pci.h | 41 -- drivers/net/wireless/ath/ath11k/pcic.c | 747 +++++++++++++++++++++ drivers/net/wireless/ath/ath11k/pcic.h | 53 ++ 6 files changed, 856 insertions(+), 830 deletions(-) create mode 100644 drivers/net/wireless/ath/ath11k/pcic.c create mode 100644 drivers/net/wireless/ath/ath11k/pcic.h diff --git a/drivers/net/wireless/ath/ath11k/Makefile b/drivers/net/wireless/ath/ath11k/Makefile index 444c00c2bce20..0ebfe41d61436 100644 --- a/drivers/net/wireless/ath/ath11k/Makefile +++ b/drivers/net/wireless/ath/ath11k/Makefile @@ -29,7 +29,7 @@ obj-$(CONFIG_ATH11K_AHB) += ath11k_ahb.o ath11k_ahb-y += ahb.o obj-$(CONFIG_ATH11K_PCI) += ath11k_pci.o -ath11k_pci-y += mhi.o pci.o +ath11k_pci-y += mhi.o pci.o pcic.o # for tracing framework to find trace.h CFLAGS_trace.o := -I$(src) diff --git a/drivers/net/wireless/ath/ath11k/mhi.c b/drivers/net/wireless/ath/ath11k/mhi.c index 61d83be4841f9..3724eebba4a26 100644 --- a/drivers/net/wireless/ath/ath11k/mhi.c +++ b/drivers/net/wireless/ath/ath11k/mhi.c @@ -1,5 +1,8 @@ // SPDX-License-Identifier: BSD-3-Clause-Clear -/* Copyright (c) 2020 The Linux Foundation. All rights reserved. */ +/* + * Copyright (c) 2020 The Linux Foundation. All rights reserved. + * Copyright (c) 2021-2022, Qualcomm Innovation Center, Inc. All rights reserved. + */ #include #include @@ -11,6 +14,7 @@ #include "debug.h" #include "mhi.h" #include "pci.h" +#include "pcic.h" #define MHI_TIMEOUT_DEFAULT_MS 90000 #define RDDM_DUMP_SIZE 0x420000 @@ -205,7 +209,7 @@ void ath11k_mhi_set_mhictrl_reset(struct ath11k_base *ab) { u32 val; - val = ath11k_pci_read32(ab, MHISTATUS); + val = ath11k_pcic_read32(ab, MHISTATUS); ath11k_dbg(ab, ATH11K_DBG_PCI, "MHISTATUS 0x%x\n", val); @@ -213,29 +217,29 @@ void ath11k_mhi_set_mhictrl_reset(struct ath11k_base *ab) * has SYSERR bit set and thus need to set MHICTRL_RESET * to clear SYSERR. */ - ath11k_pci_write32(ab, MHICTRL, MHICTRL_RESET_MASK); + ath11k_pcic_write32(ab, MHICTRL, MHICTRL_RESET_MASK); mdelay(10); } static void ath11k_mhi_reset_txvecdb(struct ath11k_base *ab) { - ath11k_pci_write32(ab, PCIE_TXVECDB, 0); + ath11k_pcic_write32(ab, PCIE_TXVECDB, 0); } static void ath11k_mhi_reset_txvecstatus(struct ath11k_base *ab) { - ath11k_pci_write32(ab, PCIE_TXVECSTATUS, 0); + ath11k_pcic_write32(ab, PCIE_TXVECSTATUS, 0); } static void ath11k_mhi_reset_rxvecdb(struct ath11k_base *ab) { - ath11k_pci_write32(ab, PCIE_RXVECDB, 0); + ath11k_pcic_write32(ab, PCIE_RXVECDB, 0); } static void ath11k_mhi_reset_rxvecstatus(struct ath11k_base *ab) { - ath11k_pci_write32(ab, PCIE_RXVECSTATUS, 0); + ath11k_pcic_write32(ab, PCIE_RXVECSTATUS, 0); } void ath11k_mhi_clear_vector(struct ath11k_base *ab) @@ -254,9 +258,9 @@ static int ath11k_mhi_get_msi(struct ath11k_pci *ab_pci) int *irq; unsigned int msi_data; - ret = ath11k_pci_get_user_msi_assignment(ab_pci, - "MHI", &num_vectors, - &user_base_data, &base_vector); + ret = ath11k_pcic_get_user_msi_assignment(ab_pci, + "MHI", &num_vectors, + &user_base_data, &base_vector); if (ret) return ret; @@ -273,8 +277,7 @@ static int ath11k_mhi_get_msi(struct ath11k_pci *ab_pci) if (test_bit(ATH11K_PCI_FLAG_MULTI_MSI_VECTORS, &ab_pci->flags)) msi_data += i; - irq[i] = ath11k_pci_get_msi_irq(ab->dev, - msi_data); + irq[i] = ath11k_pcic_get_msi_irq(ab->dev, msi_data); } ab_pci->mhi_ctrl->irq = irq; diff --git a/drivers/net/wireless/ath/ath11k/pci.c b/drivers/net/wireless/ath/ath11k/pci.c index 5e71eafdf9a36..bffbcace63aec 100644 --- a/drivers/net/wireless/ath/ath11k/pci.c +++ b/drivers/net/wireless/ath/ath11k/pci.c @@ -14,6 +14,7 @@ #include "hif.h" #include "mhi.h" #include "debug.h" +#include "pcic.h" #define ATH11K_PCI_BAR_NUM 0 #define ATH11K_PCI_DMA_MASK 32 @@ -75,76 +76,6 @@ static const struct ath11k_msi_config msi_config_one_msi = { }, }; -static const char *irq_name[ATH11K_IRQ_NUM_MAX] = { - "bhi", - "mhi-er0", - "mhi-er1", - "ce0", - "ce1", - "ce2", - "ce3", - "ce4", - "ce5", - "ce6", - "ce7", - "ce8", - "ce9", - "ce10", - "ce11", - "host2wbm-desc-feed", - "host2reo-re-injection", - "host2reo-command", - "host2rxdma-monitor-ring3", - "host2rxdma-monitor-ring2", - "host2rxdma-monitor-ring1", - "reo2ost-exception", - "wbm2host-rx-release", - "reo2host-status", - "reo2host-destination-ring4", - "reo2host-destination-ring3", - "reo2host-destination-ring2", - "reo2host-destination-ring1", - "rxdma2host-monitor-destination-mac3", - "rxdma2host-monitor-destination-mac2", - "rxdma2host-monitor-destination-mac1", - "ppdu-end-interrupts-mac3", - "ppdu-end-interrupts-mac2", - "ppdu-end-interrupts-mac1", - "rxdma2host-monitor-status-ring-mac3", - "rxdma2host-monitor-status-ring-mac2", - "rxdma2host-monitor-status-ring-mac1", - "host2rxdma-host-buf-ring-mac3", - "host2rxdma-host-buf-ring-mac2", - "host2rxdma-host-buf-ring-mac1", - "rxdma2host-destination-ring-mac3", - "rxdma2host-destination-ring-mac2", - "rxdma2host-destination-ring-mac1", - "host2tcl-input-ring4", - "host2tcl-input-ring3", - "host2tcl-input-ring2", - "host2tcl-input-ring1", - "wbm2host-tx-completions-ring3", - "wbm2host-tx-completions-ring2", - "wbm2host-tx-completions-ring1", - "tcl2host-status-ring", -}; - -static inline void ath11k_pci_select_window(struct ath11k_pci *ab_pci, u32 offset) -{ - struct ath11k_base *ab = ab_pci->ab; - - u32 window = FIELD_GET(ATH11K_PCI_WINDOW_VALUE_MASK, offset); - - lockdep_assert_held(&ab_pci->window_lock); - - if (window != ab_pci->register_window) { - iowrite32(ATH11K_PCI_WINDOW_ENABLE_BIT | window, - ab->mem + ATH11K_PCI_WINDOW_REG_ADDRESS); - ioread32(ab->mem + ATH11K_PCI_WINDOW_REG_ADDRESS); - ab_pci->register_window = window; - } -} - static inline void ath11k_pci_select_static_window(struct ath11k_pci *ab_pci) { u32 umac_window; @@ -159,116 +90,15 @@ static inline void ath11k_pci_select_static_window(struct ath11k_pci *ab_pci) ab_pci->ab->mem + ATH11K_PCI_WINDOW_REG_ADDRESS); } -static inline u32 ath11k_pci_get_window_start(struct ath11k_base *ab, - u32 offset) -{ - u32 window_start; - - /* If offset lies within DP register range, use 3rd window */ - if ((offset ^ HAL_SEQ_WCSS_UMAC_OFFSET) < ATH11K_PCI_WINDOW_RANGE_MASK) - window_start = 3 * ATH11K_PCI_WINDOW_START; - /* If offset lies within CE register range, use 2nd window */ - else if ((offset ^ HAL_CE_WFSS_CE_REG_BASE) < ATH11K_PCI_WINDOW_RANGE_MASK) - window_start = 2 * ATH11K_PCI_WINDOW_START; - else - window_start = ATH11K_PCI_WINDOW_START; - - return window_start; -} - -void ath11k_pci_write32(struct ath11k_base *ab, u32 offset, u32 value) -{ - struct ath11k_pci *ab_pci = ath11k_pci_priv(ab); - u32 window_start; - int ret = 0; - - /* for offset beyond BAR + 4K - 32, may - * need to wakeup MHI to access. - */ - if (ab->hw_params.wakeup_mhi && - test_bit(ATH11K_PCI_FLAG_INIT_DONE, &ab_pci->flags) && - offset >= ATH11K_PCI_ACCESS_ALWAYS_OFF) - ret = mhi_device_get_sync(ab_pci->mhi_ctrl->mhi_dev); - - if (offset < ATH11K_PCI_WINDOW_START) { - iowrite32(value, ab->mem + offset); - } else { - if (ab->bus_params.static_window_map) - window_start = ath11k_pci_get_window_start(ab, offset); - else - window_start = ATH11K_PCI_WINDOW_START; - - if (window_start == ATH11K_PCI_WINDOW_START) { - spin_lock_bh(&ab_pci->window_lock); - ath11k_pci_select_window(ab_pci, offset); - iowrite32(value, ab->mem + window_start + - (offset & ATH11K_PCI_WINDOW_RANGE_MASK)); - spin_unlock_bh(&ab_pci->window_lock); - } else { - iowrite32(value, ab->mem + window_start + - (offset & ATH11K_PCI_WINDOW_RANGE_MASK)); - } - } - - if (ab->hw_params.wakeup_mhi && - test_bit(ATH11K_PCI_FLAG_INIT_DONE, &ab_pci->flags) && - offset >= ATH11K_PCI_ACCESS_ALWAYS_OFF && - !ret) - mhi_device_put(ab_pci->mhi_ctrl->mhi_dev); -} - -u32 ath11k_pci_read32(struct ath11k_base *ab, u32 offset) -{ - struct ath11k_pci *ab_pci = ath11k_pci_priv(ab); - u32 val, window_start; - int ret = 0; - - /* for offset beyond BAR + 4K - 32, may - * need to wakeup MHI to access. - */ - if (ab->hw_params.wakeup_mhi && - test_bit(ATH11K_PCI_FLAG_INIT_DONE, &ab_pci->flags) && - offset >= ATH11K_PCI_ACCESS_ALWAYS_OFF) - ret = mhi_device_get_sync(ab_pci->mhi_ctrl->mhi_dev); - - if (offset < ATH11K_PCI_WINDOW_START) { - val = ioread32(ab->mem + offset); - } else { - if (ab->bus_params.static_window_map) - window_start = ath11k_pci_get_window_start(ab, offset); - else - window_start = ATH11K_PCI_WINDOW_START; - - if (window_start == ATH11K_PCI_WINDOW_START) { - spin_lock_bh(&ab_pci->window_lock); - ath11k_pci_select_window(ab_pci, offset); - val = ioread32(ab->mem + window_start + - (offset & ATH11K_PCI_WINDOW_RANGE_MASK)); - spin_unlock_bh(&ab_pci->window_lock); - } else { - val = ioread32(ab->mem + window_start + - (offset & ATH11K_PCI_WINDOW_RANGE_MASK)); - } - } - - if (ab->hw_params.wakeup_mhi && - test_bit(ATH11K_PCI_FLAG_INIT_DONE, &ab_pci->flags) && - offset >= ATH11K_PCI_ACCESS_ALWAYS_OFF && - !ret) - mhi_device_put(ab_pci->mhi_ctrl->mhi_dev); - - return val; -} - static void ath11k_pci_soc_global_reset(struct ath11k_base *ab) { u32 val, delay; - val = ath11k_pci_read32(ab, PCIE_SOC_GLOBAL_RESET); + val = ath11k_pcic_read32(ab, PCIE_SOC_GLOBAL_RESET); val |= PCIE_SOC_GLOBAL_RESET_V; - ath11k_pci_write32(ab, PCIE_SOC_GLOBAL_RESET, val); + ath11k_pcic_write32(ab, PCIE_SOC_GLOBAL_RESET, val); /* TODO: exact time to sleep is uncertain */ delay = 10; @@ -277,11 +107,11 @@ static void ath11k_pci_soc_global_reset(struct ath11k_base *ab) /* Need to toggle V bit back otherwise stuck in reset status */ val &= ~PCIE_SOC_GLOBAL_RESET_V; - ath11k_pci_write32(ab, PCIE_SOC_GLOBAL_RESET, val); + ath11k_pcic_write32(ab, PCIE_SOC_GLOBAL_RESET, val); mdelay(delay); - val = ath11k_pci_read32(ab, PCIE_SOC_GLOBAL_RESET); + val = ath11k_pcic_read32(ab, PCIE_SOC_GLOBAL_RESET); if (val == 0xffffffff) ath11k_warn(ab, "link down error during global reset\n"); } @@ -291,10 +121,10 @@ static void ath11k_pci_clear_dbg_registers(struct ath11k_base *ab) u32 val; /* read cookie */ - val = ath11k_pci_read32(ab, PCIE_Q6_COOKIE_ADDR); + val = ath11k_pcic_read32(ab, PCIE_Q6_COOKIE_ADDR); ath11k_dbg(ab, ATH11K_DBG_PCI, "cookie:0x%x\n", val); - val = ath11k_pci_read32(ab, WLAON_WARM_SW_ENTRY); + val = ath11k_pcic_read32(ab, WLAON_WARM_SW_ENTRY); ath11k_dbg(ab, ATH11K_DBG_PCI, "WLAON_WARM_SW_ENTRY 0x%x\n", val); /* TODO: exact time to sleep is uncertain */ @@ -303,16 +133,16 @@ static void ath11k_pci_clear_dbg_registers(struct ath11k_base *ab) /* write 0 to WLAON_WARM_SW_ENTRY to prevent Q6 from * continuing warm path and entering dead loop. */ - ath11k_pci_write32(ab, WLAON_WARM_SW_ENTRY, 0); + ath11k_pcic_write32(ab, WLAON_WARM_SW_ENTRY, 0); mdelay(10); - val = ath11k_pci_read32(ab, WLAON_WARM_SW_ENTRY); + val = ath11k_pcic_read32(ab, WLAON_WARM_SW_ENTRY); ath11k_dbg(ab, ATH11K_DBG_PCI, "WLAON_WARM_SW_ENTRY 0x%x\n", val); /* A read clear register. clear the register to prevent * Q6 from entering wrong code path. */ - val = ath11k_pci_read32(ab, WLAON_SOC_RESET_CAUSE_REG); + val = ath11k_pcic_read32(ab, WLAON_SOC_RESET_CAUSE_REG); ath11k_dbg(ab, ATH11K_DBG_PCI, "soc reset cause:%d\n", val); } @@ -322,14 +152,14 @@ static int ath11k_pci_set_link_reg(struct ath11k_base *ab, u32 v; int i; - v = ath11k_pci_read32(ab, offset); + v = ath11k_pcic_read32(ab, offset); if ((v & mask) == value) return 0; for (i = 0; i < 10; i++) { - ath11k_pci_write32(ab, offset, (v & ~mask) | value); + ath11k_pcic_write32(ab, offset, (v & ~mask) | value); - v = ath11k_pci_read32(ab, offset); + v = ath11k_pcic_read32(ab, offset); if ((v & mask) == value) return 0; @@ -390,23 +220,23 @@ static void ath11k_pci_enable_ltssm(struct ath11k_base *ab) u32 val; int i; - val = ath11k_pci_read32(ab, PCIE_PCIE_PARF_LTSSM); + val = ath11k_pcic_read32(ab, PCIE_PCIE_PARF_LTSSM); /* PCIE link seems very unstable after the Hot Reset*/ for (i = 0; val != PARM_LTSSM_VALUE && i < 5; i++) { if (val == 0xffffffff) mdelay(5); - ath11k_pci_write32(ab, PCIE_PCIE_PARF_LTSSM, PARM_LTSSM_VALUE); - val = ath11k_pci_read32(ab, PCIE_PCIE_PARF_LTSSM); + ath11k_pcic_write32(ab, PCIE_PCIE_PARF_LTSSM, PARM_LTSSM_VALUE); + val = ath11k_pcic_read32(ab, PCIE_PCIE_PARF_LTSSM); } ath11k_dbg(ab, ATH11K_DBG_PCI, "pci ltssm 0x%x\n", val); - val = ath11k_pci_read32(ab, GCC_GCC_PCIE_HOT_RST); + val = ath11k_pcic_read32(ab, GCC_GCC_PCIE_HOT_RST); val |= GCC_GCC_PCIE_HOT_RST_VAL; - ath11k_pci_write32(ab, GCC_GCC_PCIE_HOT_RST, val); - val = ath11k_pci_read32(ab, GCC_GCC_PCIE_HOT_RST); + ath11k_pcic_write32(ab, GCC_GCC_PCIE_HOT_RST, val); + val = ath11k_pcic_read32(ab, GCC_GCC_PCIE_HOT_RST); ath11k_dbg(ab, ATH11K_DBG_PCI, "pci pcie_hot_rst 0x%x\n", val); @@ -420,21 +250,21 @@ static void ath11k_pci_clear_all_intrs(struct ath11k_base *ab) * So when download SBL again, SBL will open Interrupt and * receive it, and crash immediately. */ - ath11k_pci_write32(ab, PCIE_PCIE_INT_ALL_CLEAR, PCIE_INT_CLEAR_ALL); + ath11k_pcic_write32(ab, PCIE_PCIE_INT_ALL_CLEAR, PCIE_INT_CLEAR_ALL); } static void ath11k_pci_set_wlaon_pwr_ctrl(struct ath11k_base *ab) { u32 val; - val = ath11k_pci_read32(ab, WLAON_QFPROM_PWR_CTRL_REG); + val = ath11k_pcic_read32(ab, WLAON_QFPROM_PWR_CTRL_REG); val &= ~QFPROM_PWR_CTRL_VDD4BLOW_MASK; - ath11k_pci_write32(ab, WLAON_QFPROM_PWR_CTRL_REG, val); + ath11k_pcic_write32(ab, WLAON_QFPROM_PWR_CTRL_REG, val); } static void ath11k_pci_force_wake(struct ath11k_base *ab) { - ath11k_pci_write32(ab, PCIE_SOC_WAKE_PCIE_LOCAL_REG, 1); + ath11k_pcic_write32(ab, PCIE_SOC_WAKE_PCIE_LOCAL_REG, 1); mdelay(5); } @@ -456,462 +286,6 @@ static void ath11k_pci_sw_reset(struct ath11k_base *ab, bool power_on) ath11k_mhi_set_mhictrl_reset(ab); } -int ath11k_pci_get_msi_irq(struct device *dev, unsigned int vector) -{ - struct pci_dev *pci_dev = to_pci_dev(dev); - - return pci_irq_vector(pci_dev, vector); -} - -void ath11k_pci_get_msi_address(struct ath11k_base *ab, u32 *msi_addr_lo, - u32 *msi_addr_hi) -{ - struct ath11k_pci *ab_pci = ath11k_pci_priv(ab); - struct pci_dev *pci_dev = to_pci_dev(ab->dev); - - pci_read_config_dword(pci_dev, pci_dev->msi_cap + PCI_MSI_ADDRESS_LO, - msi_addr_lo); - - if (test_bit(ATH11K_PCI_FLAG_IS_MSI_64, &ab_pci->flags)) { - pci_read_config_dword(pci_dev, pci_dev->msi_cap + PCI_MSI_ADDRESS_HI, - msi_addr_hi); - } else { - *msi_addr_hi = 0; - } -} - -int ath11k_pci_get_user_msi_assignment(struct ath11k_pci *ab_pci, char *user_name, - int *num_vectors, u32 *user_base_data, - u32 *base_vector) -{ - struct ath11k_base *ab = ab_pci->ab; - const struct ath11k_msi_config *msi_config = ab_pci->msi_config; - int idx; - - for (idx = 0; idx < msi_config->total_users; idx++) { - if (strcmp(user_name, msi_config->users[idx].name) == 0) { - *num_vectors = msi_config->users[idx].num_vectors; - *base_vector = msi_config->users[idx].base_vector; - *user_base_data = *base_vector + ab_pci->msi_ep_base_data; - - ath11k_dbg(ab, ATH11K_DBG_PCI, - "Assign MSI to user: %s, num_vectors: %d, user_base_data: %u, base_vector: %u\n", - user_name, *num_vectors, *user_base_data, - *base_vector); - - return 0; - } - } - - ath11k_err(ab, "Failed to find MSI assignment for %s!\n", user_name); - - return -EINVAL; -} - -void ath11k_pci_get_ce_msi_idx(struct ath11k_base *ab, u32 ce_id, u32 *msi_idx) -{ - u32 i, msi_data_idx; - - for (i = 0, msi_data_idx = 0; i < ab->hw_params.ce_count; i++) { - if (ath11k_ce_get_attr_flags(ab, i) & CE_ATTR_DIS_INTR) - continue; - - if (ce_id == i) - break; - - msi_data_idx++; - } - *msi_idx = msi_data_idx; -} - -int ath11k_get_user_msi_assignment(struct ath11k_base *ab, char *user_name, - int *num_vectors, u32 *user_base_data, - u32 *base_vector) -{ - struct ath11k_pci *ab_pci = ath11k_pci_priv(ab); - - return ath11k_pci_get_user_msi_assignment(ab_pci, user_name, - num_vectors, user_base_data, - base_vector); -} - -static void ath11k_pci_free_ext_irq(struct ath11k_base *ab) -{ - int i, j; - - for (i = 0; i < ATH11K_EXT_IRQ_GRP_NUM_MAX; i++) { - struct ath11k_ext_irq_grp *irq_grp = &ab->ext_irq_grp[i]; - - for (j = 0; j < irq_grp->num_irq; j++) - free_irq(ab->irq_num[irq_grp->irqs[j]], irq_grp); - - netif_napi_del(&irq_grp->napi); - } -} - -void ath11k_pci_free_irq(struct ath11k_base *ab) -{ - int i, irq_idx; - - for (i = 0; i < ab->hw_params.ce_count; i++) { - if (ath11k_ce_get_attr_flags(ab, i) & CE_ATTR_DIS_INTR) - continue; - irq_idx = ATH11K_PCI_IRQ_CE0_OFFSET + i; - free_irq(ab->irq_num[irq_idx], &ab->ce.ce_pipe[i]); - } - - ath11k_pci_free_ext_irq(ab); -} - -static void ath11k_pci_ce_irq_enable(struct ath11k_base *ab, u16 ce_id) -{ - struct ath11k_pci *ab_pci = ath11k_pci_priv(ab); - u32 irq_idx; - - /* In case of one MSI vector, we handle irq enable/disable in a - * uniform way since we only have one irq - */ - if (!test_bit(ATH11K_PCI_FLAG_MULTI_MSI_VECTORS, &ab_pci->flags)) - return; - - irq_idx = ATH11K_PCI_IRQ_CE0_OFFSET + ce_id; - enable_irq(ab->irq_num[irq_idx]); -} - -static void ath11k_pci_ce_irq_disable(struct ath11k_base *ab, u16 ce_id) -{ - struct ath11k_pci *ab_pci = ath11k_pci_priv(ab); - u32 irq_idx; - - /* In case of one MSI vector, we handle irq enable/disable in a - * uniform way since we only have one irq - */ - if (!test_bit(ATH11K_PCI_FLAG_MULTI_MSI_VECTORS, &ab_pci->flags)) - return; - - irq_idx = ATH11K_PCI_IRQ_CE0_OFFSET + ce_id; - disable_irq_nosync(ab->irq_num[irq_idx]); -} - -static void ath11k_pci_ce_irqs_disable(struct ath11k_base *ab) -{ - int i; - - clear_bit(ATH11K_FLAG_CE_IRQ_ENABLED, &ab->dev_flags); - - for (i = 0; i < ab->hw_params.ce_count; i++) { - if (ath11k_ce_get_attr_flags(ab, i) & CE_ATTR_DIS_INTR) - continue; - ath11k_pci_ce_irq_disable(ab, i); - } -} - -static void ath11k_pci_sync_ce_irqs(struct ath11k_base *ab) -{ - int i; - int irq_idx; - - for (i = 0; i < ab->hw_params.ce_count; i++) { - if (ath11k_ce_get_attr_flags(ab, i) & CE_ATTR_DIS_INTR) - continue; - - irq_idx = ATH11K_PCI_IRQ_CE0_OFFSET + i; - synchronize_irq(ab->irq_num[irq_idx]); - } -} - -static void ath11k_pci_ce_tasklet(struct tasklet_struct *t) -{ - struct ath11k_ce_pipe *ce_pipe = from_tasklet(ce_pipe, t, intr_tq); - int irq_idx = ATH11K_PCI_IRQ_CE0_OFFSET + ce_pipe->pipe_num; - - ath11k_ce_per_engine_service(ce_pipe->ab, ce_pipe->pipe_num); - - enable_irq(ce_pipe->ab->irq_num[irq_idx]); -} - -static irqreturn_t ath11k_pci_ce_interrupt_handler(int irq, void *arg) -{ - struct ath11k_ce_pipe *ce_pipe = arg; - struct ath11k_base *ab = ce_pipe->ab; - int irq_idx = ATH11K_PCI_IRQ_CE0_OFFSET + ce_pipe->pipe_num; - - if (!test_bit(ATH11K_FLAG_CE_IRQ_ENABLED, &ab->dev_flags)) - return IRQ_HANDLED; - - /* last interrupt received for this CE */ - ce_pipe->timestamp = jiffies; - - disable_irq_nosync(ab->irq_num[irq_idx]); - - tasklet_schedule(&ce_pipe->intr_tq); - - return IRQ_HANDLED; -} - -static void ath11k_pci_ext_grp_disable(struct ath11k_ext_irq_grp *irq_grp) -{ - struct ath11k_pci *ab_pci = ath11k_pci_priv(irq_grp->ab); - int i; - - /* In case of one MSI vector, we handle irq enable/disable - * in a uniform way since we only have one irq - */ - if (!test_bit(ATH11K_PCI_FLAG_MULTI_MSI_VECTORS, &ab_pci->flags)) - return; - - for (i = 0; i < irq_grp->num_irq; i++) - disable_irq_nosync(irq_grp->ab->irq_num[irq_grp->irqs[i]]); -} - -static void __ath11k_pci_ext_irq_disable(struct ath11k_base *sc) -{ - int i; - - clear_bit(ATH11K_FLAG_EXT_IRQ_ENABLED, &sc->dev_flags); - - for (i = 0; i < ATH11K_EXT_IRQ_GRP_NUM_MAX; i++) { - struct ath11k_ext_irq_grp *irq_grp = &sc->ext_irq_grp[i]; - - ath11k_pci_ext_grp_disable(irq_grp); - - if (irq_grp->napi_enabled) { - napi_synchronize(&irq_grp->napi); - napi_disable(&irq_grp->napi); - irq_grp->napi_enabled = false; - } - } -} - -static void ath11k_pci_ext_grp_enable(struct ath11k_ext_irq_grp *irq_grp) -{ - struct ath11k_pci *ab_pci = ath11k_pci_priv(irq_grp->ab); - int i; - - /* In case of one MSI vector, we handle irq enable/disable in a - * uniform way since we only have one irq - */ - if (!test_bit(ATH11K_PCI_FLAG_MULTI_MSI_VECTORS, &ab_pci->flags)) - return; - - for (i = 0; i < irq_grp->num_irq; i++) - enable_irq(irq_grp->ab->irq_num[irq_grp->irqs[i]]); -} - -void ath11k_pci_ext_irq_enable(struct ath11k_base *ab) -{ - int i; - - set_bit(ATH11K_FLAG_EXT_IRQ_ENABLED, &ab->dev_flags); - - for (i = 0; i < ATH11K_EXT_IRQ_GRP_NUM_MAX; i++) { - struct ath11k_ext_irq_grp *irq_grp = &ab->ext_irq_grp[i]; - - if (!irq_grp->napi_enabled) { - napi_enable(&irq_grp->napi); - irq_grp->napi_enabled = true; - } - ath11k_pci_ext_grp_enable(irq_grp); - } -} - -static void ath11k_pci_sync_ext_irqs(struct ath11k_base *ab) -{ - int i, j, irq_idx; - - for (i = 0; i < ATH11K_EXT_IRQ_GRP_NUM_MAX; i++) { - struct ath11k_ext_irq_grp *irq_grp = &ab->ext_irq_grp[i]; - - for (j = 0; j < irq_grp->num_irq; j++) { - irq_idx = irq_grp->irqs[j]; - synchronize_irq(ab->irq_num[irq_idx]); - } - } -} - -void ath11k_pci_ext_irq_disable(struct ath11k_base *ab) -{ - __ath11k_pci_ext_irq_disable(ab); - ath11k_pci_sync_ext_irqs(ab); -} - -static int ath11k_pci_ext_grp_napi_poll(struct napi_struct *napi, int budget) -{ - struct ath11k_ext_irq_grp *irq_grp = container_of(napi, - struct ath11k_ext_irq_grp, - napi); - struct ath11k_base *ab = irq_grp->ab; - int work_done; - int i; - - work_done = ath11k_dp_service_srng(ab, irq_grp, budget); - if (work_done < budget) { - napi_complete_done(napi, work_done); - for (i = 0; i < irq_grp->num_irq; i++) - enable_irq(irq_grp->ab->irq_num[irq_grp->irqs[i]]); - } - - if (work_done > budget) - work_done = budget; - - return work_done; -} - -static irqreturn_t ath11k_pci_ext_interrupt_handler(int irq, void *arg) -{ - struct ath11k_ext_irq_grp *irq_grp = arg; - struct ath11k_base *ab = irq_grp->ab; - int i; - - if (!test_bit(ATH11K_FLAG_EXT_IRQ_ENABLED, &ab->dev_flags)) - return IRQ_HANDLED; - - ath11k_dbg(irq_grp->ab, ATH11K_DBG_PCI, "ext irq:%d\n", irq); - - /* last interrupt received for this group */ - irq_grp->timestamp = jiffies; - - for (i = 0; i < irq_grp->num_irq; i++) - disable_irq_nosync(irq_grp->ab->irq_num[irq_grp->irqs[i]]); - - napi_schedule(&irq_grp->napi); - - return IRQ_HANDLED; -} - -static int ath11k_pci_ext_irq_config(struct ath11k_base *ab) -{ - struct ath11k_pci *ab_pci = ath11k_pci_priv(ab); - int i, j, ret, num_vectors = 0; - u32 user_base_data = 0, base_vector = 0; - - ret = ath11k_pci_get_user_msi_assignment(ath11k_pci_priv(ab), "DP", - &num_vectors, - &user_base_data, - &base_vector); - if (ret < 0) - return ret; - - for (i = 0; i < ATH11K_EXT_IRQ_GRP_NUM_MAX; i++) { - struct ath11k_ext_irq_grp *irq_grp = &ab->ext_irq_grp[i]; - u32 num_irq = 0; - - irq_grp->ab = ab; - irq_grp->grp_id = i; - init_dummy_netdev(&irq_grp->napi_ndev); - netif_napi_add(&irq_grp->napi_ndev, &irq_grp->napi, - ath11k_pci_ext_grp_napi_poll, NAPI_POLL_WEIGHT); - - if (ab->hw_params.ring_mask->tx[i] || - ab->hw_params.ring_mask->rx[i] || - ab->hw_params.ring_mask->rx_err[i] || - ab->hw_params.ring_mask->rx_wbm_rel[i] || - ab->hw_params.ring_mask->reo_status[i] || - ab->hw_params.ring_mask->rxdma2host[i] || - ab->hw_params.ring_mask->host2rxdma[i] || - ab->hw_params.ring_mask->rx_mon_status[i]) { - num_irq = 1; - } - - irq_grp->num_irq = num_irq; - irq_grp->irqs[0] = ATH11K_PCI_IRQ_DP_OFFSET + i; - - for (j = 0; j < irq_grp->num_irq; j++) { - int irq_idx = irq_grp->irqs[j]; - int vector = (i % num_vectors) + base_vector; - int irq = ath11k_pci_get_msi_irq(ab->dev, vector); - - ab->irq_num[irq_idx] = irq; - - ath11k_dbg(ab, ATH11K_DBG_PCI, - "irq:%d group:%d\n", irq, i); - - irq_set_status_flags(irq, IRQ_DISABLE_UNLAZY); - ret = request_irq(irq, ath11k_pci_ext_interrupt_handler, - ab_pci->irq_flags, - "DP_EXT_IRQ", irq_grp); - if (ret) { - ath11k_err(ab, "failed request irq %d: %d\n", - vector, ret); - return ret; - } - } - ath11k_pci_ext_grp_disable(irq_grp); - } - - return 0; -} - -int ath11k_pci_set_irq_affinity_hint(struct ath11k_pci *ab_pci, - const struct cpumask *m) -{ - if (test_bit(ATH11K_PCI_FLAG_MULTI_MSI_VECTORS, &ab_pci->flags)) - return 0; - - return irq_set_affinity_hint(ab_pci->pdev->irq, m); -} - -int ath11k_pci_config_irq(struct ath11k_base *ab) -{ - struct ath11k_pci *ab_pci = ath11k_pci_priv(ab); - struct ath11k_ce_pipe *ce_pipe; - u32 msi_data_start; - u32 msi_data_count, msi_data_idx; - u32 msi_irq_start; - unsigned int msi_data; - int irq, i, ret, irq_idx; - - ret = ath11k_pci_get_user_msi_assignment(ath11k_pci_priv(ab), - "CE", &msi_data_count, - &msi_data_start, &msi_irq_start); - if (ret) - return ret; - - ret = ath11k_pci_set_irq_affinity_hint(ab_pci, cpumask_of(0)); - if (ret) { - ath11k_err(ab, "failed to set irq affinity %d\n", ret); - return ret; - } - - /* Configure CE irqs */ - for (i = 0, msi_data_idx = 0; i < ab->hw_params.ce_count; i++) { - if (ath11k_ce_get_attr_flags(ab, i) & CE_ATTR_DIS_INTR) - continue; - - msi_data = (msi_data_idx % msi_data_count) + msi_irq_start; - irq = ath11k_pci_get_msi_irq(ab->dev, msi_data); - ce_pipe = &ab->ce.ce_pipe[i]; - - irq_idx = ATH11K_PCI_IRQ_CE0_OFFSET + i; - - tasklet_setup(&ce_pipe->intr_tq, ath11k_pci_ce_tasklet); - - ret = request_irq(irq, ath11k_pci_ce_interrupt_handler, - ab_pci->irq_flags, irq_name[irq_idx], - ce_pipe); - if (ret) { - ath11k_err(ab, "failed to request irq %d: %d\n", - irq_idx, ret); - goto err_irq_affinity_cleanup; - } - - ab->irq_num[irq_idx] = irq; - msi_data_idx++; - - ath11k_pci_ce_irq_disable(ab, i); - } - - ret = ath11k_pci_ext_irq_config(ab); - if (ret) - goto err_irq_affinity_cleanup; - - return 0; - -err_irq_affinity_cleanup: - ath11k_pci_set_irq_affinity_hint(ab_pci, NULL); - return ret; -} - static void ath11k_pci_init_qmi_ce_config(struct ath11k_base *ab) { struct ath11k_qmi_ce_cfg *cfg = &ab->qmi.ce_cfg; @@ -927,19 +301,6 @@ static void ath11k_pci_init_qmi_ce_config(struct ath11k_base *ab) &cfg->shadow_reg_v2_len); } -void ath11k_pci_ce_irqs_enable(struct ath11k_base *ab) -{ - int i; - - set_bit(ATH11K_FLAG_CE_IRQ_ENABLED, &ab->dev_flags); - - for (i = 0; i < ab->hw_params.ce_count; i++) { - if (ath11k_ce_get_attr_flags(ab, i) & CE_ATTR_DIS_INTR) - continue; - ath11k_pci_ce_irq_enable(ab, i); - } -} - static void ath11k_pci_msi_config(struct ath11k_pci *ab_pci, bool enable) { struct pci_dev *dev = ab_pci->pdev; @@ -1139,13 +500,6 @@ static void ath11k_pci_aspm_disable(struct ath11k_pci *ab_pci) set_bit(ATH11K_PCI_ASPM_RESTORE, &ab_pci->flags); } -void ath11k_pci_aspm_restore(struct ath11k_pci *ab_pci) -{ - if (test_and_clear_bit(ATH11K_PCI_ASPM_RESTORE, &ab_pci->flags)) - pcie_capability_write_word(ab_pci->pdev, PCI_EXP_LNKCTL, - ab_pci->link_ctl); -} - static int ath11k_pci_power_up(struct ath11k_base *ab) { struct ath11k_pci *ab_pci = ath11k_pci_priv(ab); @@ -1179,7 +533,7 @@ static void ath11k_pci_power_down(struct ath11k_base *ab) struct ath11k_pci *ab_pci = ath11k_pci_priv(ab); /* restore aspm in case firmware bootup fails */ - ath11k_pci_aspm_restore(ab_pci); + ath11k_pcic_aspm_restore(ab_pci); ath11k_pci_force_wake(ab_pci->ab); @@ -1208,130 +562,40 @@ static int ath11k_pci_hif_resume(struct ath11k_base *ab) return 0; } -static void ath11k_pci_kill_tasklets(struct ath11k_base *ab) -{ - int i; - - for (i = 0; i < ab->hw_params.ce_count; i++) { - struct ath11k_ce_pipe *ce_pipe = &ab->ce.ce_pipe[i]; - - if (ath11k_ce_get_attr_flags(ab, i) & CE_ATTR_DIS_INTR) - continue; - - tasklet_kill(&ce_pipe->intr_tq); - } -} - -void ath11k_pci_ce_irq_disable_sync(struct ath11k_base *ab) -{ - ath11k_pci_ce_irqs_disable(ab); - ath11k_pci_sync_ce_irqs(ab); - ath11k_pci_kill_tasklets(ab); -} - -void ath11k_pci_stop(struct ath11k_base *ab) -{ - ath11k_pci_ce_irq_disable_sync(ab); - ath11k_ce_cleanup_pipes(ab); -} - -int ath11k_pci_start(struct ath11k_base *ab) -{ - struct ath11k_pci *ab_pci = ath11k_pci_priv(ab); - - set_bit(ATH11K_PCI_FLAG_INIT_DONE, &ab_pci->flags); - - /* TODO: for now don't restore ASPM in case of single MSI - * vector as MHI register reading in M2 causes system hang. - */ - if (test_bit(ATH11K_PCI_FLAG_MULTI_MSI_VECTORS, &ab_pci->flags)) - ath11k_pci_aspm_restore(ab_pci); - else - ath11k_info(ab, "leaving PCI ASPM disabled to avoid MHI M2 problems\n"); - - ath11k_pci_ce_irqs_enable(ab); - ath11k_ce_rx_post_buf(ab); - - return 0; -} - static void ath11k_pci_hif_ce_irq_enable(struct ath11k_base *ab) { - ath11k_pci_ce_irqs_enable(ab); + ath11k_pcic_ce_irqs_enable(ab); } static void ath11k_pci_hif_ce_irq_disable(struct ath11k_base *ab) { - ath11k_pci_ce_irq_disable_sync(ab); -} - -int ath11k_pci_map_service_to_pipe(struct ath11k_base *ab, u16 service_id, - u8 *ul_pipe, u8 *dl_pipe) -{ - const struct service_to_pipe *entry; - bool ul_set = false, dl_set = false; - int i; - - for (i = 0; i < ab->hw_params.svc_to_ce_map_len; i++) { - entry = &ab->hw_params.svc_to_ce_map[i]; - - if (__le32_to_cpu(entry->service_id) != service_id) - continue; - - switch (__le32_to_cpu(entry->pipedir)) { - case PIPEDIR_NONE: - break; - case PIPEDIR_IN: - WARN_ON(dl_set); - *dl_pipe = __le32_to_cpu(entry->pipenum); - dl_set = true; - break; - case PIPEDIR_OUT: - WARN_ON(ul_set); - *ul_pipe = __le32_to_cpu(entry->pipenum); - ul_set = true; - break; - case PIPEDIR_INOUT: - WARN_ON(dl_set); - WARN_ON(ul_set); - *dl_pipe = __le32_to_cpu(entry->pipenum); - *ul_pipe = __le32_to_cpu(entry->pipenum); - dl_set = true; - ul_set = true; - break; - } - } - - if (WARN_ON(!ul_set || !dl_set)) - return -ENOENT; - - return 0; + ath11k_pcic_ce_irq_disable_sync(ab); } static const struct ath11k_hif_ops ath11k_pci_hif_ops = { - .start = ath11k_pci_start, - .stop = ath11k_pci_stop, - .read32 = ath11k_pci_read32, - .write32 = ath11k_pci_write32, + .start = ath11k_pcic_start, + .stop = ath11k_pcic_stop, + .read32 = ath11k_pcic_read32, + .write32 = ath11k_pcic_write32, .power_down = ath11k_pci_power_down, .power_up = ath11k_pci_power_up, .suspend = ath11k_pci_hif_suspend, .resume = ath11k_pci_hif_resume, - .irq_enable = ath11k_pci_ext_irq_enable, - .irq_disable = ath11k_pci_ext_irq_disable, - .get_msi_address = ath11k_pci_get_msi_address, + .irq_enable = ath11k_pcic_ext_irq_enable, + .irq_disable = ath11k_pcic_ext_irq_disable, + .get_msi_address = ath11k_pcic_get_msi_address, .get_user_msi_vector = ath11k_get_user_msi_assignment, - .map_service_to_pipe = ath11k_pci_map_service_to_pipe, + .map_service_to_pipe = ath11k_pcic_map_service_to_pipe, .ce_irq_enable = ath11k_pci_hif_ce_irq_enable, .ce_irq_disable = ath11k_pci_hif_ce_irq_disable, - .get_ce_msi_idx = ath11k_pci_get_ce_msi_idx, + .get_ce_msi_idx = ath11k_pcic_get_ce_msi_idx, }; static void ath11k_pci_read_hw_version(struct ath11k_base *ab, u32 *major, u32 *minor) { u32 soc_hw_version; - soc_hw_version = ath11k_pci_read32(ab, TCSR_SOC_HW_VERSION); + soc_hw_version = ath11k_pcic_read32(ab, TCSR_SOC_HW_VERSION); *major = FIELD_GET(TCSR_SOC_HW_VERSION_MAJOR_MASK, soc_hw_version); *minor = FIELD_GET(TCSR_SOC_HW_VERSION_MINOR_MASK, @@ -1473,7 +737,7 @@ static int ath11k_pci_probe(struct pci_dev *pdev, ath11k_pci_init_qmi_ce_config(ab); - ret = ath11k_pci_config_irq(ab); + ret = ath11k_pcic_config_irq(ab); if (ret) { ath11k_err(ab, "failed to config irq: %d\n", ret); goto err_ce_free; @@ -1498,7 +762,7 @@ static int ath11k_pci_probe(struct pci_dev *pdev, return 0; err_free_irq: - ath11k_pci_free_irq(ab); + ath11k_pcic_free_irq(ab); err_ce_free: ath11k_ce_free_pipes(ab); @@ -1526,7 +790,7 @@ static void ath11k_pci_remove(struct pci_dev *pdev) struct ath11k_base *ab = pci_get_drvdata(pdev); struct ath11k_pci *ab_pci = ath11k_pci_priv(ab); - ath11k_pci_set_irq_affinity_hint(ab_pci, NULL); + ath11k_pcic_set_irq_affinity_hint(ab_pci, NULL); if (test_bit(ATH11K_FLAG_QMI_FAIL, &ab->dev_flags)) { ath11k_pci_power_down(ab); @@ -1542,7 +806,7 @@ static void ath11k_pci_remove(struct pci_dev *pdev) qmi_fail: ath11k_mhi_unregister(ab_pci); - ath11k_pci_free_irq(ab); + ath11k_pcic_free_irq(ab); ath11k_pci_free_msi(ab_pci); ath11k_pci_free_region(ab_pci); diff --git a/drivers/net/wireless/ath/ath11k/pci.h b/drivers/net/wireless/ath/ath11k/pci.h index 31ee843c1cabc..038e4152987c7 100644 --- a/drivers/net/wireless/ath/ath11k/pci.h +++ b/drivers/net/wireless/ath/ath11k/pci.h @@ -53,21 +53,6 @@ #define WLAON_QFPROM_PWR_CTRL_REG 0x01f8031c #define QFPROM_PWR_CTRL_VDD4BLOW_MASK 0x4 -#define ATH11K_PCI_IRQ_CE0_OFFSET 3 -#define ATH11K_PCI_IRQ_DP_OFFSET 14 - -#define ATH11K_PCI_WINDOW_ENABLE_BIT 0x40000000 -#define ATH11K_PCI_WINDOW_REG_ADDRESS 0x310c -#define ATH11K_PCI_WINDOW_VALUE_MASK GENMASK(24, 19) -#define ATH11K_PCI_WINDOW_START 0x80000 -#define ATH11K_PCI_WINDOW_RANGE_MASK GENMASK(18, 0) - -/* BAR0 + 4k is always accessible, and no - * need to force wakeup. - * 4K - 32 = 0xFE0 - */ -#define ATH11K_PCI_ACCESS_ALWAYS_OFF 0xFE0 - struct ath11k_msi_user { char *name; int num_vectors; @@ -113,30 +98,4 @@ static inline struct ath11k_pci *ath11k_pci_priv(struct ath11k_base *ab) return (struct ath11k_pci *)ab->drv_priv; } -int ath11k_pci_get_user_msi_assignment(struct ath11k_pci *ar_pci, char *user_name, - int *num_vectors, u32 *user_base_data, - u32 *base_vector); -int ath11k_pci_get_msi_irq(struct device *dev, unsigned int vector); -void ath11k_pci_write32(struct ath11k_base *ab, u32 offset, u32 value); -u32 ath11k_pci_read32(struct ath11k_base *ab, u32 offset); -void ath11k_pci_get_msi_address(struct ath11k_base *ab, u32 *msi_addr_lo, - u32 *msi_addr_hi); -void ath11k_pci_get_ce_msi_idx(struct ath11k_base *ab, u32 ce_id, u32 *msi_idx); -void ath11k_pci_free_irq(struct ath11k_base *ab); -int ath11k_pci_config_irq(struct ath11k_base *ab); -void ath11k_pci_ext_irq_enable(struct ath11k_base *ab); -void ath11k_pci_ext_irq_disable(struct ath11k_base *ab); -void ath11k_pci_stop(struct ath11k_base *ab); -int ath11k_pci_start(struct ath11k_base *ab); -int ath11k_pci_map_service_to_pipe(struct ath11k_base *ab, u16 service_id, - u8 *ul_pipe, u8 *dl_pipe); -void ath11k_pci_ce_irqs_enable(struct ath11k_base *ab); -void ath11k_pci_ce_irq_disable_sync(struct ath11k_base *ab); -int ath11k_get_user_msi_assignment(struct ath11k_base *ab, char *user_name, - int *num_vectors, u32 *user_base_data, - u32 *base_vector); -void ath11k_pci_aspm_restore(struct ath11k_pci *ab_pci); -int ath11k_pci_set_irq_affinity_hint(struct ath11k_pci *ab_pci, - const struct cpumask *m); - #endif diff --git a/drivers/net/wireless/ath/ath11k/pcic.c b/drivers/net/wireless/ath/ath11k/pcic.c new file mode 100644 index 0000000000000..391c308455e55 --- /dev/null +++ b/drivers/net/wireless/ath/ath11k/pcic.c @@ -0,0 +1,747 @@ +// SPDX-License-Identifier: BSD-3-Clause-Clear +/* + * Copyright (c) 2019-2021 The Linux Foundation. All rights reserved. + * Copyright (c) 2021-2022, Qualcomm Innovation Center, Inc. All rights reserved. + */ + +#include +#include "core.h" +#include "pcic.h" +#include "debug.h" + +static const char *irq_name[ATH11K_IRQ_NUM_MAX] = { + "bhi", + "mhi-er0", + "mhi-er1", + "ce0", + "ce1", + "ce2", + "ce3", + "ce4", + "ce5", + "ce6", + "ce7", + "ce8", + "ce9", + "ce10", + "ce11", + "host2wbm-desc-feed", + "host2reo-re-injection", + "host2reo-command", + "host2rxdma-monitor-ring3", + "host2rxdma-monitor-ring2", + "host2rxdma-monitor-ring1", + "reo2ost-exception", + "wbm2host-rx-release", + "reo2host-status", + "reo2host-destination-ring4", + "reo2host-destination-ring3", + "reo2host-destination-ring2", + "reo2host-destination-ring1", + "rxdma2host-monitor-destination-mac3", + "rxdma2host-monitor-destination-mac2", + "rxdma2host-monitor-destination-mac1", + "ppdu-end-interrupts-mac3", + "ppdu-end-interrupts-mac2", + "ppdu-end-interrupts-mac1", + "rxdma2host-monitor-status-ring-mac3", + "rxdma2host-monitor-status-ring-mac2", + "rxdma2host-monitor-status-ring-mac1", + "host2rxdma-host-buf-ring-mac3", + "host2rxdma-host-buf-ring-mac2", + "host2rxdma-host-buf-ring-mac1", + "rxdma2host-destination-ring-mac3", + "rxdma2host-destination-ring-mac2", + "rxdma2host-destination-ring-mac1", + "host2tcl-input-ring4", + "host2tcl-input-ring3", + "host2tcl-input-ring2", + "host2tcl-input-ring1", + "wbm2host-tx-completions-ring3", + "wbm2host-tx-completions-ring2", + "wbm2host-tx-completions-ring1", + "tcl2host-status-ring", +}; + +void ath11k_pcic_aspm_restore(struct ath11k_pci *ab_pci) +{ + if (test_and_clear_bit(ATH11K_PCI_ASPM_RESTORE, &ab_pci->flags)) + pcie_capability_write_word(ab_pci->pdev, PCI_EXP_LNKCTL, + ab_pci->link_ctl); +} + +static inline void ath11k_pcic_select_window(struct ath11k_pci *ab_pci, u32 offset) +{ + struct ath11k_base *ab = ab_pci->ab; + + u32 window = FIELD_GET(ATH11K_PCI_WINDOW_VALUE_MASK, offset); + + lockdep_assert_held(&ab_pci->window_lock); + + if (window != ab_pci->register_window) { + iowrite32(ATH11K_PCI_WINDOW_ENABLE_BIT | window, + ab->mem + ATH11K_PCI_WINDOW_REG_ADDRESS); + ioread32(ab->mem + ATH11K_PCI_WINDOW_REG_ADDRESS); + ab_pci->register_window = window; + } +} + +static inline u32 ath11k_pcic_get_window_start(struct ath11k_base *ab, + u32 offset) +{ + u32 window_start; + + /* If offset lies within DP register range, use 3rd window */ + if ((offset ^ HAL_SEQ_WCSS_UMAC_OFFSET) < ATH11K_PCI_WINDOW_RANGE_MASK) + window_start = 3 * ATH11K_PCI_WINDOW_START; + /* If offset lies within CE register range, use 2nd window */ + else if ((offset ^ HAL_CE_WFSS_CE_REG_BASE) < ATH11K_PCI_WINDOW_RANGE_MASK) + window_start = 2 * ATH11K_PCI_WINDOW_START; + else + window_start = ATH11K_PCI_WINDOW_START; + + return window_start; +} + +void ath11k_pcic_write32(struct ath11k_base *ab, u32 offset, u32 value) +{ + struct ath11k_pci *ab_pci = ath11k_pci_priv(ab); + u32 window_start; + int ret = 0; + + /* for offset beyond BAR + 4K - 32, may + * need to wakeup MHI to access. + */ + if (ab->hw_params.wakeup_mhi && + test_bit(ATH11K_PCI_FLAG_INIT_DONE, &ab_pci->flags) && + offset >= ATH11K_PCI_ACCESS_ALWAYS_OFF) + ret = mhi_device_get_sync(ab_pci->mhi_ctrl->mhi_dev); + + if (offset < ATH11K_PCI_WINDOW_START) { + iowrite32(value, ab->mem + offset); + } else { + if (ab->bus_params.static_window_map) + window_start = ath11k_pcic_get_window_start(ab, offset); + else + window_start = ATH11K_PCI_WINDOW_START; + + if (window_start == ATH11K_PCI_WINDOW_START) { + spin_lock_bh(&ab_pci->window_lock); + ath11k_pcic_select_window(ab_pci, offset); + iowrite32(value, ab->mem + window_start + + (offset & ATH11K_PCI_WINDOW_RANGE_MASK)); + spin_unlock_bh(&ab_pci->window_lock); + } else { + iowrite32(value, ab->mem + window_start + + (offset & ATH11K_PCI_WINDOW_RANGE_MASK)); + } + } + + if (ab->hw_params.wakeup_mhi && + test_bit(ATH11K_PCI_FLAG_INIT_DONE, &ab_pci->flags) && + offset >= ATH11K_PCI_ACCESS_ALWAYS_OFF && + !ret) + mhi_device_put(ab_pci->mhi_ctrl->mhi_dev); +} + +u32 ath11k_pcic_read32(struct ath11k_base *ab, u32 offset) +{ + struct ath11k_pci *ab_pci = ath11k_pci_priv(ab); + u32 val, window_start; + int ret = 0; + + /* for offset beyond BAR + 4K - 32, may + * need to wakeup MHI to access. + */ + if (ab->hw_params.wakeup_mhi && + test_bit(ATH11K_PCI_FLAG_INIT_DONE, &ab_pci->flags) && + offset >= ATH11K_PCI_ACCESS_ALWAYS_OFF) + ret = mhi_device_get_sync(ab_pci->mhi_ctrl->mhi_dev); + + if (offset < ATH11K_PCI_WINDOW_START) { + val = ioread32(ab->mem + offset); + } else { + if (ab->bus_params.static_window_map) + window_start = ath11k_pcic_get_window_start(ab, offset); + else + window_start = ATH11K_PCI_WINDOW_START; + + if (window_start == ATH11K_PCI_WINDOW_START) { + spin_lock_bh(&ab_pci->window_lock); + ath11k_pcic_select_window(ab_pci, offset); + val = ioread32(ab->mem + window_start + + (offset & ATH11K_PCI_WINDOW_RANGE_MASK)); + spin_unlock_bh(&ab_pci->window_lock); + } else { + val = ioread32(ab->mem + window_start + + (offset & ATH11K_PCI_WINDOW_RANGE_MASK)); + } + } + + if (ab->hw_params.wakeup_mhi && + test_bit(ATH11K_PCI_FLAG_INIT_DONE, &ab_pci->flags) && + offset >= ATH11K_PCI_ACCESS_ALWAYS_OFF && + !ret) + mhi_device_put(ab_pci->mhi_ctrl->mhi_dev); + + return val; +} + +int ath11k_pcic_get_msi_irq(struct device *dev, unsigned int vector) +{ + struct pci_dev *pci_dev = to_pci_dev(dev); + + return pci_irq_vector(pci_dev, vector); +} + +void ath11k_pcic_get_msi_address(struct ath11k_base *ab, u32 *msi_addr_lo, + u32 *msi_addr_hi) +{ + struct ath11k_pci *ab_pci = ath11k_pci_priv(ab); + struct pci_dev *pci_dev = to_pci_dev(ab->dev); + + pci_read_config_dword(pci_dev, pci_dev->msi_cap + PCI_MSI_ADDRESS_LO, + msi_addr_lo); + + if (test_bit(ATH11K_PCI_FLAG_IS_MSI_64, &ab_pci->flags)) { + pci_read_config_dword(pci_dev, pci_dev->msi_cap + PCI_MSI_ADDRESS_HI, + msi_addr_hi); + } else { + *msi_addr_hi = 0; + } +} + +int ath11k_pcic_get_user_msi_assignment(struct ath11k_pci *ab_pci, char *user_name, + int *num_vectors, u32 *user_base_data, + u32 *base_vector) +{ + struct ath11k_base *ab = ab_pci->ab; + const struct ath11k_msi_config *msi_config = ab_pci->msi_config; + int idx; + + for (idx = 0; idx < msi_config->total_users; idx++) { + if (strcmp(user_name, msi_config->users[idx].name) == 0) { + *num_vectors = msi_config->users[idx].num_vectors; + *base_vector = msi_config->users[idx].base_vector; + *user_base_data = *base_vector + ab_pci->msi_ep_base_data; + + ath11k_dbg(ab, ATH11K_DBG_PCI, + "Assign MSI to user: %s, num_vectors: %d, user_base_data: %u, base_vector: %u\n", + user_name, *num_vectors, *user_base_data, + *base_vector); + + return 0; + } + } + + ath11k_err(ab, "Failed to find MSI assignment for %s!\n", user_name); + + return -EINVAL; +} + +void ath11k_pcic_get_ce_msi_idx(struct ath11k_base *ab, u32 ce_id, u32 *msi_idx) +{ + u32 i, msi_data_idx; + + for (i = 0, msi_data_idx = 0; i < ab->hw_params.ce_count; i++) { + if (ath11k_ce_get_attr_flags(ab, i) & CE_ATTR_DIS_INTR) + continue; + + if (ce_id == i) + break; + + msi_data_idx++; + } + *msi_idx = msi_data_idx; +} + +int ath11k_get_user_msi_assignment(struct ath11k_base *ab, char *user_name, + int *num_vectors, u32 *user_base_data, + u32 *base_vector) +{ + struct ath11k_pci *ab_pci = ath11k_pci_priv(ab); + + return ath11k_pcic_get_user_msi_assignment(ab_pci, user_name, + num_vectors, user_base_data, + base_vector); +} + +static void ath11k_pcic_free_ext_irq(struct ath11k_base *ab) +{ + int i, j; + + for (i = 0; i < ATH11K_EXT_IRQ_GRP_NUM_MAX; i++) { + struct ath11k_ext_irq_grp *irq_grp = &ab->ext_irq_grp[i]; + + for (j = 0; j < irq_grp->num_irq; j++) + free_irq(ab->irq_num[irq_grp->irqs[j]], irq_grp); + + netif_napi_del(&irq_grp->napi); + } +} + +void ath11k_pcic_free_irq(struct ath11k_base *ab) +{ + int i, irq_idx; + + for (i = 0; i < ab->hw_params.ce_count; i++) { + if (ath11k_ce_get_attr_flags(ab, i) & CE_ATTR_DIS_INTR) + continue; + irq_idx = ATH11K_PCI_IRQ_CE0_OFFSET + i; + free_irq(ab->irq_num[irq_idx], &ab->ce.ce_pipe[i]); + } + + ath11k_pcic_free_ext_irq(ab); +} + +static void ath11k_pcic_ce_irq_enable(struct ath11k_base *ab, u16 ce_id) +{ + struct ath11k_pci *ab_pci = ath11k_pci_priv(ab); + u32 irq_idx; + + /* In case of one MSI vector, we handle irq enable/disable in a + * uniform way since we only have one irq + */ + if (!test_bit(ATH11K_PCI_FLAG_MULTI_MSI_VECTORS, &ab_pci->flags)) + return; + + irq_idx = ATH11K_PCI_IRQ_CE0_OFFSET + ce_id; + enable_irq(ab->irq_num[irq_idx]); +} + +static void ath11k_pcic_ce_irq_disable(struct ath11k_base *ab, u16 ce_id) +{ + struct ath11k_pci *ab_pci = ath11k_pci_priv(ab); + u32 irq_idx; + + /* In case of one MSI vector, we handle irq enable/disable in a + * uniform way since we only have one irq + */ + if (!test_bit(ATH11K_PCI_FLAG_MULTI_MSI_VECTORS, &ab_pci->flags)) + return; + + irq_idx = ATH11K_PCI_IRQ_CE0_OFFSET + ce_id; + disable_irq_nosync(ab->irq_num[irq_idx]); +} + +static void ath11k_pcic_ce_irqs_disable(struct ath11k_base *ab) +{ + int i; + + clear_bit(ATH11K_FLAG_CE_IRQ_ENABLED, &ab->dev_flags); + + for (i = 0; i < ab->hw_params.ce_count; i++) { + if (ath11k_ce_get_attr_flags(ab, i) & CE_ATTR_DIS_INTR) + continue; + ath11k_pcic_ce_irq_disable(ab, i); + } +} + +static void ath11k_pcic_sync_ce_irqs(struct ath11k_base *ab) +{ + int i; + int irq_idx; + + for (i = 0; i < ab->hw_params.ce_count; i++) { + if (ath11k_ce_get_attr_flags(ab, i) & CE_ATTR_DIS_INTR) + continue; + + irq_idx = ATH11K_PCI_IRQ_CE0_OFFSET + i; + synchronize_irq(ab->irq_num[irq_idx]); + } +} + +static void ath11k_pcic_ce_tasklet(struct tasklet_struct *t) +{ + struct ath11k_ce_pipe *ce_pipe = from_tasklet(ce_pipe, t, intr_tq); + int irq_idx = ATH11K_PCI_IRQ_CE0_OFFSET + ce_pipe->pipe_num; + + ath11k_ce_per_engine_service(ce_pipe->ab, ce_pipe->pipe_num); + + enable_irq(ce_pipe->ab->irq_num[irq_idx]); +} + +static irqreturn_t ath11k_pcic_ce_interrupt_handler(int irq, void *arg) +{ + struct ath11k_ce_pipe *ce_pipe = arg; + struct ath11k_base *ab = ce_pipe->ab; + int irq_idx = ATH11K_PCI_IRQ_CE0_OFFSET + ce_pipe->pipe_num; + + if (!test_bit(ATH11K_FLAG_CE_IRQ_ENABLED, &ab->dev_flags)) + return IRQ_HANDLED; + + /* last interrupt received for this CE */ + ce_pipe->timestamp = jiffies; + + disable_irq_nosync(ab->irq_num[irq_idx]); + + tasklet_schedule(&ce_pipe->intr_tq); + + return IRQ_HANDLED; +} + +static void ath11k_pcic_ext_grp_disable(struct ath11k_ext_irq_grp *irq_grp) +{ + struct ath11k_pci *ab_pci = ath11k_pci_priv(irq_grp->ab); + int i; + + /* In case of one MSI vector, we handle irq enable/disable + * in a uniform way since we only have one irq + */ + if (!test_bit(ATH11K_PCI_FLAG_MULTI_MSI_VECTORS, &ab_pci->flags)) + return; + + for (i = 0; i < irq_grp->num_irq; i++) + disable_irq_nosync(irq_grp->ab->irq_num[irq_grp->irqs[i]]); +} + +static void __ath11k_pcic_ext_irq_disable(struct ath11k_base *sc) +{ + int i; + + clear_bit(ATH11K_FLAG_EXT_IRQ_ENABLED, &sc->dev_flags); + + for (i = 0; i < ATH11K_EXT_IRQ_GRP_NUM_MAX; i++) { + struct ath11k_ext_irq_grp *irq_grp = &sc->ext_irq_grp[i]; + + ath11k_pcic_ext_grp_disable(irq_grp); + + if (irq_grp->napi_enabled) { + napi_synchronize(&irq_grp->napi); + napi_disable(&irq_grp->napi); + irq_grp->napi_enabled = false; + } + } +} + +static void ath11k_pcic_ext_grp_enable(struct ath11k_ext_irq_grp *irq_grp) +{ + struct ath11k_pci *ab_pci = ath11k_pci_priv(irq_grp->ab); + int i; + + /* In case of one MSI vector, we handle irq enable/disable in a + * uniform way since we only have one irq + */ + if (!test_bit(ATH11K_PCI_FLAG_MULTI_MSI_VECTORS, &ab_pci->flags)) + return; + + for (i = 0; i < irq_grp->num_irq; i++) + enable_irq(irq_grp->ab->irq_num[irq_grp->irqs[i]]); +} + +void ath11k_pcic_ext_irq_enable(struct ath11k_base *ab) +{ + int i; + + set_bit(ATH11K_FLAG_EXT_IRQ_ENABLED, &ab->dev_flags); + + for (i = 0; i < ATH11K_EXT_IRQ_GRP_NUM_MAX; i++) { + struct ath11k_ext_irq_grp *irq_grp = &ab->ext_irq_grp[i]; + + if (!irq_grp->napi_enabled) { + napi_enable(&irq_grp->napi); + irq_grp->napi_enabled = true; + } + ath11k_pcic_ext_grp_enable(irq_grp); + } +} + +static void ath11k_pcic_sync_ext_irqs(struct ath11k_base *ab) +{ + int i, j, irq_idx; + + for (i = 0; i < ATH11K_EXT_IRQ_GRP_NUM_MAX; i++) { + struct ath11k_ext_irq_grp *irq_grp = &ab->ext_irq_grp[i]; + + for (j = 0; j < irq_grp->num_irq; j++) { + irq_idx = irq_grp->irqs[j]; + synchronize_irq(ab->irq_num[irq_idx]); + } + } +} + +void ath11k_pcic_ext_irq_disable(struct ath11k_base *ab) +{ + __ath11k_pcic_ext_irq_disable(ab); + ath11k_pcic_sync_ext_irqs(ab); +} + +static int ath11k_pcic_ext_grp_napi_poll(struct napi_struct *napi, int budget) +{ + struct ath11k_ext_irq_grp *irq_grp = container_of(napi, + struct ath11k_ext_irq_grp, + napi); + struct ath11k_base *ab = irq_grp->ab; + int work_done; + int i; + + work_done = ath11k_dp_service_srng(ab, irq_grp, budget); + if (work_done < budget) { + napi_complete_done(napi, work_done); + for (i = 0; i < irq_grp->num_irq; i++) + enable_irq(irq_grp->ab->irq_num[irq_grp->irqs[i]]); + } + + if (work_done > budget) + work_done = budget; + + return work_done; +} + +static irqreturn_t ath11k_pcic_ext_interrupt_handler(int irq, void *arg) +{ + struct ath11k_ext_irq_grp *irq_grp = arg; + struct ath11k_base *ab = irq_grp->ab; + int i; + + if (!test_bit(ATH11K_FLAG_EXT_IRQ_ENABLED, &ab->dev_flags)) + return IRQ_HANDLED; + + ath11k_dbg(irq_grp->ab, ATH11K_DBG_PCI, "ext irq:%d\n", irq); + + /* last interrupt received for this group */ + irq_grp->timestamp = jiffies; + + for (i = 0; i < irq_grp->num_irq; i++) + disable_irq_nosync(irq_grp->ab->irq_num[irq_grp->irqs[i]]); + + napi_schedule(&irq_grp->napi); + + return IRQ_HANDLED; +} + +static int ath11k_pcic_ext_irq_config(struct ath11k_base *ab) +{ + struct ath11k_pci *ab_pci = ath11k_pci_priv(ab); + int i, j, ret, num_vectors = 0; + u32 user_base_data = 0, base_vector = 0; + + ret = ath11k_pcic_get_user_msi_assignment(ath11k_pci_priv(ab), "DP", + &num_vectors, + &user_base_data, + &base_vector); + if (ret < 0) + return ret; + + for (i = 0; i < ATH11K_EXT_IRQ_GRP_NUM_MAX; i++) { + struct ath11k_ext_irq_grp *irq_grp = &ab->ext_irq_grp[i]; + u32 num_irq = 0; + + irq_grp->ab = ab; + irq_grp->grp_id = i; + init_dummy_netdev(&irq_grp->napi_ndev); + netif_napi_add(&irq_grp->napi_ndev, &irq_grp->napi, + ath11k_pcic_ext_grp_napi_poll, NAPI_POLL_WEIGHT); + + if (ab->hw_params.ring_mask->tx[i] || + ab->hw_params.ring_mask->rx[i] || + ab->hw_params.ring_mask->rx_err[i] || + ab->hw_params.ring_mask->rx_wbm_rel[i] || + ab->hw_params.ring_mask->reo_status[i] || + ab->hw_params.ring_mask->rxdma2host[i] || + ab->hw_params.ring_mask->host2rxdma[i] || + ab->hw_params.ring_mask->rx_mon_status[i]) { + num_irq = 1; + } + + irq_grp->num_irq = num_irq; + irq_grp->irqs[0] = ATH11K_PCI_IRQ_DP_OFFSET + i; + + for (j = 0; j < irq_grp->num_irq; j++) { + int irq_idx = irq_grp->irqs[j]; + int vector = (i % num_vectors) + base_vector; + int irq = ath11k_pcic_get_msi_irq(ab->dev, vector); + + ab->irq_num[irq_idx] = irq; + + ath11k_dbg(ab, ATH11K_DBG_PCI, + "irq:%d group:%d\n", irq, i); + + irq_set_status_flags(irq, IRQ_DISABLE_UNLAZY); + ret = request_irq(irq, ath11k_pcic_ext_interrupt_handler, + ab_pci->irq_flags, + "DP_EXT_IRQ", irq_grp); + if (ret) { + ath11k_err(ab, "failed request irq %d: %d\n", + vector, ret); + return ret; + } + } + ath11k_pcic_ext_grp_disable(irq_grp); + } + + return 0; +} + +int ath11k_pcic_set_irq_affinity_hint(struct ath11k_pci *ab_pci, + const struct cpumask *m) +{ + if (test_bit(ATH11K_PCI_FLAG_MULTI_MSI_VECTORS, &ab_pci->flags)) + return 0; + + return irq_set_affinity_hint(ab_pci->pdev->irq, m); +} + +int ath11k_pcic_config_irq(struct ath11k_base *ab) +{ + struct ath11k_pci *ab_pci = ath11k_pci_priv(ab); + struct ath11k_ce_pipe *ce_pipe; + u32 msi_data_start; + u32 msi_data_count, msi_data_idx; + u32 msi_irq_start; + unsigned int msi_data; + int irq, i, ret, irq_idx; + + ret = ath11k_pcic_get_user_msi_assignment(ath11k_pci_priv(ab), + "CE", &msi_data_count, + &msi_data_start, &msi_irq_start); + if (ret) + return ret; + + ret = ath11k_pcic_set_irq_affinity_hint(ab_pci, cpumask_of(0)); + if (ret) { + ath11k_err(ab, "failed to set irq affinity %d\n", ret); + return ret; + } + + /* Configure CE irqs */ + for (i = 0, msi_data_idx = 0; i < ab->hw_params.ce_count; i++) { + if (ath11k_ce_get_attr_flags(ab, i) & CE_ATTR_DIS_INTR) + continue; + + msi_data = (msi_data_idx % msi_data_count) + msi_irq_start; + irq = ath11k_pcic_get_msi_irq(ab->dev, msi_data); + ce_pipe = &ab->ce.ce_pipe[i]; + + irq_idx = ATH11K_PCI_IRQ_CE0_OFFSET + i; + + tasklet_setup(&ce_pipe->intr_tq, ath11k_pcic_ce_tasklet); + + ret = request_irq(irq, ath11k_pcic_ce_interrupt_handler, + ab_pci->irq_flags, irq_name[irq_idx], + ce_pipe); + if (ret) { + ath11k_err(ab, "failed to request irq %d: %d\n", + irq_idx, ret); + goto err_irq_affinity_cleanup; + } + + ab->irq_num[irq_idx] = irq; + msi_data_idx++; + + ath11k_pcic_ce_irq_disable(ab, i); + } + + ret = ath11k_pcic_ext_irq_config(ab); + if (ret) + goto err_irq_affinity_cleanup; + + return 0; + +err_irq_affinity_cleanup: + ath11k_pcic_set_irq_affinity_hint(ab_pci, NULL); + return ret; +} + +void ath11k_pcic_ce_irqs_enable(struct ath11k_base *ab) +{ + int i; + + set_bit(ATH11K_FLAG_CE_IRQ_ENABLED, &ab->dev_flags); + + for (i = 0; i < ab->hw_params.ce_count; i++) { + if (ath11k_ce_get_attr_flags(ab, i) & CE_ATTR_DIS_INTR) + continue; + ath11k_pcic_ce_irq_enable(ab, i); + } +} + +static void ath11k_pcic_kill_tasklets(struct ath11k_base *ab) +{ + int i; + + for (i = 0; i < ab->hw_params.ce_count; i++) { + struct ath11k_ce_pipe *ce_pipe = &ab->ce.ce_pipe[i]; + + if (ath11k_ce_get_attr_flags(ab, i) & CE_ATTR_DIS_INTR) + continue; + + tasklet_kill(&ce_pipe->intr_tq); + } +} + +void ath11k_pcic_ce_irq_disable_sync(struct ath11k_base *ab) +{ + ath11k_pcic_ce_irqs_disable(ab); + ath11k_pcic_sync_ce_irqs(ab); + ath11k_pcic_kill_tasklets(ab); +} + +void ath11k_pcic_stop(struct ath11k_base *ab) +{ + ath11k_pcic_ce_irq_disable_sync(ab); + ath11k_ce_cleanup_pipes(ab); +} + +int ath11k_pcic_start(struct ath11k_base *ab) +{ + struct ath11k_pci *ab_pci = ath11k_pci_priv(ab); + + set_bit(ATH11K_PCI_FLAG_INIT_DONE, &ab_pci->flags); + + /* TODO: for now don't restore ASPM in case of single MSI + * vector as MHI register reading in M2 causes system hang. + */ + if (test_bit(ATH11K_PCI_FLAG_MULTI_MSI_VECTORS, &ab_pci->flags)) + ath11k_pcic_aspm_restore(ab_pci); + else + ath11k_info(ab, "leaving PCI ASPM disabled to avoid MHI M2 problems\n"); + + ath11k_pcic_ce_irqs_enable(ab); + ath11k_ce_rx_post_buf(ab); + + return 0; +} + +int ath11k_pcic_map_service_to_pipe(struct ath11k_base *ab, u16 service_id, + u8 *ul_pipe, u8 *dl_pipe) +{ + const struct service_to_pipe *entry; + bool ul_set = false, dl_set = false; + int i; + + for (i = 0; i < ab->hw_params.svc_to_ce_map_len; i++) { + entry = &ab->hw_params.svc_to_ce_map[i]; + + if (__le32_to_cpu(entry->service_id) != service_id) + continue; + + switch (__le32_to_cpu(entry->pipedir)) { + case PIPEDIR_NONE: + break; + case PIPEDIR_IN: + WARN_ON(dl_set); + *dl_pipe = __le32_to_cpu(entry->pipenum); + dl_set = true; + break; + case PIPEDIR_OUT: + WARN_ON(ul_set); + *ul_pipe = __le32_to_cpu(entry->pipenum); + ul_set = true; + break; + case PIPEDIR_INOUT: + WARN_ON(dl_set); + WARN_ON(ul_set); + *dl_pipe = __le32_to_cpu(entry->pipenum); + *ul_pipe = __le32_to_cpu(entry->pipenum); + dl_set = true; + ul_set = true; + break; + } + } + + if (WARN_ON(!ul_set || !dl_set)) + return -ENOENT; + + return 0; +} diff --git a/drivers/net/wireless/ath/ath11k/pcic.h b/drivers/net/wireless/ath/ath11k/pcic.h new file mode 100644 index 0000000000000..6780f7e8bc64b --- /dev/null +++ b/drivers/net/wireless/ath/ath11k/pcic.h @@ -0,0 +1,53 @@ +/* SPDX-License-Identifier: BSD-3-Clause-Clear */ +/* + * Copyright (c) 2019-2021 The Linux Foundation. All rights reserved. + * Copyright (c) 2021-2022, Qualcomm Innovation Center, Inc. All rights reserved. + */ + +#ifndef _ATH11K_PCI_CMN_H +#define _ATH11K_PCI_CMN_H + +#include "core.h" +#include "pci.h" + +#define ATH11K_PCI_IRQ_CE0_OFFSET 3 +#define ATH11K_PCI_IRQ_DP_OFFSET 14 + +#define ATH11K_PCI_WINDOW_ENABLE_BIT 0x40000000 +#define ATH11K_PCI_WINDOW_REG_ADDRESS 0x310c +#define ATH11K_PCI_WINDOW_VALUE_MASK GENMASK(24, 19) +#define ATH11K_PCI_WINDOW_START 0x80000 +#define ATH11K_PCI_WINDOW_RANGE_MASK GENMASK(18, 0) + +/* BAR0 + 4k is always accessible, and no + * need to force wakeup. + * 4K - 32 = 0xFE0 + */ +#define ATH11K_PCI_ACCESS_ALWAYS_OFF 0xFE0 + +int ath11k_pcic_get_user_msi_assignment(struct ath11k_pci *ar_pci, char *user_name, + int *num_vectors, u32 *user_base_data, + u32 *base_vector); +int ath11k_pcic_get_msi_irq(struct device *dev, unsigned int vector); +void ath11k_pcic_write32(struct ath11k_base *ab, u32 offset, u32 value); +u32 ath11k_pcic_read32(struct ath11k_base *ab, u32 offset); +void ath11k_pcic_get_msi_address(struct ath11k_base *ab, u32 *msi_addr_lo, + u32 *msi_addr_hi); +void ath11k_pcic_get_ce_msi_idx(struct ath11k_base *ab, u32 ce_id, u32 *msi_idx); +void ath11k_pcic_free_irq(struct ath11k_base *ab); +int ath11k_pcic_config_irq(struct ath11k_base *ab); +void ath11k_pcic_ext_irq_enable(struct ath11k_base *ab); +void ath11k_pcic_ext_irq_disable(struct ath11k_base *ab); +void ath11k_pcic_stop(struct ath11k_base *ab); +int ath11k_pcic_start(struct ath11k_base *ab); +int ath11k_pcic_map_service_to_pipe(struct ath11k_base *ab, u16 service_id, + u8 *ul_pipe, u8 *dl_pipe); +void ath11k_pcic_ce_irqs_enable(struct ath11k_base *ab); +void ath11k_pcic_ce_irq_disable_sync(struct ath11k_base *ab); +int ath11k_get_user_msi_assignment(struct ath11k_base *ab, char *user_name, + int *num_vectors, u32 *user_base_data, + u32 *base_vector); +void ath11k_pcic_aspm_restore(struct ath11k_pci *ab_pci); +int ath11k_pcic_set_irq_affinity_hint(struct ath11k_pci *ab_pci, + const struct cpumask *m); +#endif From 8d06b8023ace027dc31a9cb3c85c3c8fe83289c5 Mon Sep 17 00:00:00 2001 From: Manikanta Pubbisetty Date: Fri, 1 Apr 2022 14:53:08 +0300 Subject: [PATCH 040/228] ath11k: Choose MSI config based on HW revision Instead of selecting MSI config based on magic numbers, make the assignment based on HW revision. The logic is similar to the selection of HW params. This improves readability of the code and also simplifies new additions. Tested-on: WCN6855 hw2.0 PCI WLAN.HSP.1.1-01720.1-QCAHSPSWPL_V1_V2_SILICONZ_LITE-1 Tested-on: QCN9074 hw1.0 PCI WLAN.HK.2.5.0.1-01100-QCAHKSWPL_SILICONZ-1 Tested-on: IPQ8074 hw2.0 AHB WLAN.HK.2.4.0.1-00192-QCAHKSWPL_SILICONZ-1 Signed-off-by: Manikanta Pubbisetty Signed-off-by: Kalle Valo Link: https://lore.kernel.org/r/20220328055714.6449-4-quic_mpubbise@quicinc.com --- drivers/net/wireless/ath/ath11k/pci.c | 31 +++--------- drivers/net/wireless/ath/ath11k/pci.h | 1 + drivers/net/wireless/ath/ath11k/pcic.c | 70 ++++++++++++++++++++++++++ drivers/net/wireless/ath/ath11k/pcic.h | 1 + 4 files changed, 78 insertions(+), 25 deletions(-) diff --git a/drivers/net/wireless/ath/ath11k/pci.c b/drivers/net/wireless/ath/ath11k/pci.c index bffbcace63aec..ab6572b14937c 100644 --- a/drivers/net/wireless/ath/ath11k/pci.c +++ b/drivers/net/wireless/ath/ath11k/pci.c @@ -43,28 +43,6 @@ static const struct ath11k_bus_params ath11k_pci_bus_params = { .fixed_mem_region = false, }; -static const struct ath11k_msi_config ath11k_msi_config[] = { - { - .total_vectors = 32, - .total_users = 4, - .users = (struct ath11k_msi_user[]) { - { .name = "MHI", .num_vectors = 3, .base_vector = 0 }, - { .name = "CE", .num_vectors = 10, .base_vector = 3 }, - { .name = "WAKE", .num_vectors = 1, .base_vector = 13 }, - { .name = "DP", .num_vectors = 18, .base_vector = 14 }, - }, - }, - { - .total_vectors = 16, - .total_users = 3, - .users = (struct ath11k_msi_user[]) { - { .name = "MHI", .num_vectors = 3, .base_vector = 0 }, - { .name = "CE", .num_vectors = 5, .base_vector = 3 }, - { .name = "DP", .num_vectors = 8, .base_vector = 8 }, - }, - }, -}; - static const struct ath11k_msi_config msi_config_one_msi = { .total_vectors = 1, .total_users = 4, @@ -667,10 +645,8 @@ static int ath11k_pci_probe(struct pci_dev *pdev, ret = -EOPNOTSUPP; goto err_pci_free_region; } - ab_pci->msi_config = &ath11k_msi_config[0]; break; case QCN9074_DEVICE_ID: - ab_pci->msi_config = &ath11k_msi_config[1]; ab->bus_params.static_window_map = true; ab->hw_rev = ATH11K_HW_QCN9074_HW10; break; @@ -700,7 +676,6 @@ static int ath11k_pci_probe(struct pci_dev *pdev, ret = -EOPNOTSUPP; goto err_pci_free_region; } - ab_pci->msi_config = &ath11k_msi_config[0]; break; default: dev_err(&pdev->dev, "Unknown PCI device found: 0x%x\n", @@ -709,6 +684,12 @@ static int ath11k_pci_probe(struct pci_dev *pdev, goto err_pci_free_region; } + ret = ath11k_pcic_init_msi_config(ab); + if (ret) { + ath11k_err(ab, "failed to init msi config: %d\n", ret); + goto err_pci_free_region; + } + ret = ath11k_pci_alloc_msi(ab_pci); if (ret) { ath11k_err(ab, "failed to enable msi: %d\n", ret); diff --git a/drivers/net/wireless/ath/ath11k/pci.h b/drivers/net/wireless/ath/ath11k/pci.h index 038e4152987c7..7e225de6eb6ec 100644 --- a/drivers/net/wireless/ath/ath11k/pci.h +++ b/drivers/net/wireless/ath/ath11k/pci.h @@ -63,6 +63,7 @@ struct ath11k_msi_config { int total_vectors; int total_users; struct ath11k_msi_user *users; + u16 hw_rev; }; enum ath11k_pci_flags { diff --git a/drivers/net/wireless/ath/ath11k/pcic.c b/drivers/net/wireless/ath/ath11k/pcic.c index 391c308455e55..eab1534531064 100644 --- a/drivers/net/wireless/ath/ath11k/pcic.c +++ b/drivers/net/wireless/ath/ath11k/pcic.c @@ -63,6 +63,76 @@ static const char *irq_name[ATH11K_IRQ_NUM_MAX] = { "tcl2host-status-ring", }; +static const struct ath11k_msi_config ath11k_msi_config[] = { + { + .total_vectors = 32, + .total_users = 4, + .users = (struct ath11k_msi_user[]) { + { .name = "MHI", .num_vectors = 3, .base_vector = 0 }, + { .name = "CE", .num_vectors = 10, .base_vector = 3 }, + { .name = "WAKE", .num_vectors = 1, .base_vector = 13 }, + { .name = "DP", .num_vectors = 18, .base_vector = 14 }, + }, + .hw_rev = ATH11K_HW_QCA6390_HW20, + }, + { + .total_vectors = 16, + .total_users = 3, + .users = (struct ath11k_msi_user[]) { + { .name = "MHI", .num_vectors = 3, .base_vector = 0 }, + { .name = "CE", .num_vectors = 5, .base_vector = 3 }, + { .name = "DP", .num_vectors = 8, .base_vector = 8 }, + }, + .hw_rev = ATH11K_HW_QCN9074_HW10, + }, + { + .total_vectors = 32, + .total_users = 4, + .users = (struct ath11k_msi_user[]) { + { .name = "MHI", .num_vectors = 3, .base_vector = 0 }, + { .name = "CE", .num_vectors = 10, .base_vector = 3 }, + { .name = "WAKE", .num_vectors = 1, .base_vector = 13 }, + { .name = "DP", .num_vectors = 18, .base_vector = 14 }, + }, + .hw_rev = ATH11K_HW_WCN6855_HW20, + }, + { + .total_vectors = 32, + .total_users = 4, + .users = (struct ath11k_msi_user[]) { + { .name = "MHI", .num_vectors = 3, .base_vector = 0 }, + { .name = "CE", .num_vectors = 10, .base_vector = 3 }, + { .name = "WAKE", .num_vectors = 1, .base_vector = 13 }, + { .name = "DP", .num_vectors = 18, .base_vector = 14 }, + }, + .hw_rev = ATH11K_HW_WCN6855_HW21, + }, +}; + +int ath11k_pcic_init_msi_config(struct ath11k_base *ab) +{ + struct ath11k_pci *ab_pci = ath11k_pci_priv(ab); + const struct ath11k_msi_config *msi_config; + int i; + + for (i = 0; i < ARRAY_SIZE(ath11k_msi_config); i++) { + msi_config = &ath11k_msi_config[i]; + + if (msi_config->hw_rev == ab->hw_rev) + break; + } + + if (i == ARRAY_SIZE(ath11k_msi_config)) { + ath11k_err(ab, "failed to fetch msi config, unsupported hw version: 0x%x\n", + ab->hw_rev); + return -EINVAL; + } + + ab_pci->msi_config = msi_config; + return 0; +} +EXPORT_SYMBOL(ath11k_pcic_init_msi_config); + void ath11k_pcic_aspm_restore(struct ath11k_pci *ab_pci) { if (test_and_clear_bit(ATH11K_PCI_ASPM_RESTORE, &ab_pci->flags)) diff --git a/drivers/net/wireless/ath/ath11k/pcic.h b/drivers/net/wireless/ath/ath11k/pcic.h index 6780f7e8bc64b..d5fe315ccc61c 100644 --- a/drivers/net/wireless/ath/ath11k/pcic.h +++ b/drivers/net/wireless/ath/ath11k/pcic.h @@ -50,4 +50,5 @@ int ath11k_get_user_msi_assignment(struct ath11k_base *ab, char *user_name, void ath11k_pcic_aspm_restore(struct ath11k_pci *ab_pci); int ath11k_pcic_set_irq_affinity_hint(struct ath11k_pci *ab_pci, const struct cpumask *m); +int ath11k_pcic_init_msi_config(struct ath11k_base *ab); #endif From 0cfaf2243e9eef8ed32cdde6467a7e123a9f915f Mon Sep 17 00:00:00 2001 From: Manikanta Pubbisetty Date: Fri, 1 Apr 2022 14:53:08 +0300 Subject: [PATCH 041/228] ath11k: Refactor MSI logic to support WCN6750 Refactor MSI logic in order to support hybrid bus devices like WCN6750. Tested-on: WCN6855 hw2.0 PCI WLAN.HSP.1.1-01720.1-QCAHSPSWPL_V1_V2_SILICONZ_LITE-1 Tested-on: QCN9074 hw1.0 PCI WLAN.HK.2.5.0.1-01100-QCAHKSWPL_SILICONZ-1 Tested-on: IPQ8074 hw2.0 AHB WLAN.HK.2.4.0.1-00192-QCAHKSWPL_SILICONZ-1 Signed-off-by: Manikanta Pubbisetty Signed-off-by: Kalle Valo Link: https://lore.kernel.org/r/20220328055714.6449-5-quic_mpubbise@quicinc.com --- drivers/net/wireless/ath/ath11k/core.h | 22 ++++++++++++++ drivers/net/wireless/ath/ath11k/mhi.c | 3 +- drivers/net/wireless/ath/ath11k/pci.c | 29 +++++++++++------- drivers/net/wireless/ath/ath11k/pci.h | 16 ---------- drivers/net/wireless/ath/ath11k/pcic.c | 41 +++++--------------------- drivers/net/wireless/ath/ath11k/pcic.h | 5 +--- 6 files changed, 51 insertions(+), 65 deletions(-) diff --git a/drivers/net/wireless/ath/ath11k/core.h b/drivers/net/wireless/ath/ath11k/core.h index 17a61d0d684e8..4e0861a94a148 100644 --- a/drivers/net/wireless/ath/ath11k/core.h +++ b/drivers/net/wireless/ath/ath11k/core.h @@ -769,6 +769,19 @@ struct ath11k_soc_dp_stats { struct ath11k_dp_ring_bp_stats bp_stats; }; +struct ath11k_msi_user { + char *name; + int num_vectors; + u32 base_vector; +}; + +struct ath11k_msi_config { + int total_vectors; + int total_users; + struct ath11k_msi_user *users; + u16 hw_rev; +}; + /* Master structure to hold the hw data which may be used in core module */ struct ath11k_base { enum ath11k_hw_rev hw_rev; @@ -905,6 +918,15 @@ struct ath11k_base { u32 subsystem_device; } id; + struct { + struct { + const struct ath11k_msi_config *config; + u32 ep_base_data; + u32 addr_lo; + u32 addr_hi; + } msi; + } pci; + /* must be last */ u8 drv_priv[] __aligned(sizeof(void *)); }; diff --git a/drivers/net/wireless/ath/ath11k/mhi.c b/drivers/net/wireless/ath/ath11k/mhi.c index 3724eebba4a26..5de255969364c 100644 --- a/drivers/net/wireless/ath/ath11k/mhi.c +++ b/drivers/net/wireless/ath/ath11k/mhi.c @@ -258,8 +258,7 @@ static int ath11k_mhi_get_msi(struct ath11k_pci *ab_pci) int *irq; unsigned int msi_data; - ret = ath11k_pcic_get_user_msi_assignment(ab_pci, - "MHI", &num_vectors, + ret = ath11k_pcic_get_user_msi_assignment(ab, "MHI", &num_vectors, &user_base_data, &base_vector); if (ret) return ret; diff --git a/drivers/net/wireless/ath/ath11k/pci.c b/drivers/net/wireless/ath/ath11k/pci.c index ab6572b14937c..fd5487d7045ef 100644 --- a/drivers/net/wireless/ath/ath11k/pci.c +++ b/drivers/net/wireless/ath/ath11k/pci.c @@ -307,12 +307,13 @@ static void ath11k_pci_msi_disable(struct ath11k_pci *ab_pci) static int ath11k_pci_alloc_msi(struct ath11k_pci *ab_pci) { struct ath11k_base *ab = ab_pci->ab; - const struct ath11k_msi_config *msi_config = ab_pci->msi_config; + const struct ath11k_msi_config *msi_config = ab->pci.msi.config; + struct pci_dev *pci_dev = ab_pci->pdev; struct msi_desc *msi_desc; int num_vectors; int ret; - num_vectors = pci_alloc_irq_vectors(ab_pci->pdev, + num_vectors = pci_alloc_irq_vectors(pci_dev, msi_config->total_vectors, msi_config->total_vectors, PCI_IRQ_MSI); @@ -329,7 +330,7 @@ static int ath11k_pci_alloc_msi(struct ath11k_pci *ab_pci) goto reset_msi_config; } clear_bit(ATH11K_PCI_FLAG_MULTI_MSI_VECTORS, &ab_pci->flags); - ab_pci->msi_config = &msi_config_one_msi; + ab->pci.msi.config = &msi_config_one_msi; ab_pci->irq_flags = IRQF_SHARED | IRQF_NOBALANCING; ath11k_dbg(ab, ATH11K_DBG_PCI, "request MSI one vector\n"); } @@ -344,11 +345,19 @@ static int ath11k_pci_alloc_msi(struct ath11k_pci *ab_pci) goto free_msi_vector; } - ab_pci->msi_ep_base_data = msi_desc->msg.data; - if (msi_desc->pci.msi_attrib.is_64) - set_bit(ATH11K_PCI_FLAG_IS_MSI_64, &ab_pci->flags); + ab->pci.msi.ep_base_data = msi_desc->msg.data; + + pci_read_config_dword(pci_dev, pci_dev->msi_cap + PCI_MSI_ADDRESS_LO, + &ab->pci.msi.addr_lo); + + if (msi_desc->pci.msi_attrib.is_64) { + pci_read_config_dword(pci_dev, pci_dev->msi_cap + PCI_MSI_ADDRESS_HI, + &ab->pci.msi.addr_hi); + } else { + ab->pci.msi.addr_hi = 0; + } - ath11k_dbg(ab, ATH11K_DBG_PCI, "msi base data is %d\n", ab_pci->msi_ep_base_data); + ath11k_dbg(ab, ATH11K_DBG_PCI, "msi base data is %d\n", ab->pci.msi.ep_base_data); return 0; @@ -375,10 +384,10 @@ static int ath11k_pci_config_msi_data(struct ath11k_pci *ab_pci) return -EINVAL; } - ab_pci->msi_ep_base_data = msi_desc->msg.data; + ab_pci->ab->pci.msi.ep_base_data = msi_desc->msg.data; ath11k_dbg(ab_pci->ab, ATH11K_DBG_PCI, "pci after request_irq msi_ep_base_data %d\n", - ab_pci->msi_ep_base_data); + ab_pci->ab->pci.msi.ep_base_data); return 0; } @@ -562,7 +571,7 @@ static const struct ath11k_hif_ops ath11k_pci_hif_ops = { .irq_enable = ath11k_pcic_ext_irq_enable, .irq_disable = ath11k_pcic_ext_irq_disable, .get_msi_address = ath11k_pcic_get_msi_address, - .get_user_msi_vector = ath11k_get_user_msi_assignment, + .get_user_msi_vector = ath11k_pcic_get_user_msi_assignment, .map_service_to_pipe = ath11k_pcic_map_service_to_pipe, .ce_irq_enable = ath11k_pci_hif_ce_irq_enable, .ce_irq_disable = ath11k_pci_hif_ce_irq_disable, diff --git a/drivers/net/wireless/ath/ath11k/pci.h b/drivers/net/wireless/ath/ath11k/pci.h index 7e225de6eb6ec..c9cae48d784e7 100644 --- a/drivers/net/wireless/ath/ath11k/pci.h +++ b/drivers/net/wireless/ath/ath11k/pci.h @@ -53,22 +53,8 @@ #define WLAON_QFPROM_PWR_CTRL_REG 0x01f8031c #define QFPROM_PWR_CTRL_VDD4BLOW_MASK 0x4 -struct ath11k_msi_user { - char *name; - int num_vectors; - u32 base_vector; -}; - -struct ath11k_msi_config { - int total_vectors; - int total_users; - struct ath11k_msi_user *users; - u16 hw_rev; -}; - enum ath11k_pci_flags { ATH11K_PCI_FLAG_INIT_DONE, - ATH11K_PCI_FLAG_IS_MSI_64, ATH11K_PCI_ASPM_RESTORE, ATH11K_PCI_FLAG_MULTI_MSI_VECTORS, }; @@ -78,9 +64,7 @@ struct ath11k_pci { struct ath11k_base *ab; u16 dev_id; char amss_path[100]; - u32 msi_ep_base_data; struct mhi_controller *mhi_ctrl; - const struct ath11k_msi_config *msi_config; unsigned long mhi_state; u32 register_window; diff --git a/drivers/net/wireless/ath/ath11k/pcic.c b/drivers/net/wireless/ath/ath11k/pcic.c index eab1534531064..c743095387f1a 100644 --- a/drivers/net/wireless/ath/ath11k/pcic.c +++ b/drivers/net/wireless/ath/ath11k/pcic.c @@ -111,7 +111,6 @@ static const struct ath11k_msi_config ath11k_msi_config[] = { int ath11k_pcic_init_msi_config(struct ath11k_base *ab) { - struct ath11k_pci *ab_pci = ath11k_pci_priv(ab); const struct ath11k_msi_config *msi_config; int i; @@ -128,7 +127,7 @@ int ath11k_pcic_init_msi_config(struct ath11k_base *ab) return -EINVAL; } - ab_pci->msi_config = msi_config; + ab->pci.msi.config = msi_config; return 0; } EXPORT_SYMBOL(ath11k_pcic_init_msi_config); @@ -267,33 +266,22 @@ int ath11k_pcic_get_msi_irq(struct device *dev, unsigned int vector) void ath11k_pcic_get_msi_address(struct ath11k_base *ab, u32 *msi_addr_lo, u32 *msi_addr_hi) { - struct ath11k_pci *ab_pci = ath11k_pci_priv(ab); - struct pci_dev *pci_dev = to_pci_dev(ab->dev); - - pci_read_config_dword(pci_dev, pci_dev->msi_cap + PCI_MSI_ADDRESS_LO, - msi_addr_lo); - - if (test_bit(ATH11K_PCI_FLAG_IS_MSI_64, &ab_pci->flags)) { - pci_read_config_dword(pci_dev, pci_dev->msi_cap + PCI_MSI_ADDRESS_HI, - msi_addr_hi); - } else { - *msi_addr_hi = 0; - } + *msi_addr_lo = ab->pci.msi.addr_lo; + *msi_addr_hi = ab->pci.msi.addr_hi; } -int ath11k_pcic_get_user_msi_assignment(struct ath11k_pci *ab_pci, char *user_name, +int ath11k_pcic_get_user_msi_assignment(struct ath11k_base *ab, char *user_name, int *num_vectors, u32 *user_base_data, u32 *base_vector) { - struct ath11k_base *ab = ab_pci->ab; - const struct ath11k_msi_config *msi_config = ab_pci->msi_config; + const struct ath11k_msi_config *msi_config = ab->pci.msi.config; int idx; for (idx = 0; idx < msi_config->total_users; idx++) { if (strcmp(user_name, msi_config->users[idx].name) == 0) { *num_vectors = msi_config->users[idx].num_vectors; *base_vector = msi_config->users[idx].base_vector; - *user_base_data = *base_vector + ab_pci->msi_ep_base_data; + *user_base_data = *base_vector + ab->pci.msi.ep_base_data; ath11k_dbg(ab, ATH11K_DBG_PCI, "Assign MSI to user: %s, num_vectors: %d, user_base_data: %u, base_vector: %u\n", @@ -325,17 +313,6 @@ void ath11k_pcic_get_ce_msi_idx(struct ath11k_base *ab, u32 ce_id, u32 *msi_idx) *msi_idx = msi_data_idx; } -int ath11k_get_user_msi_assignment(struct ath11k_base *ab, char *user_name, - int *num_vectors, u32 *user_base_data, - u32 *base_vector) -{ - struct ath11k_pci *ab_pci = ath11k_pci_priv(ab); - - return ath11k_pcic_get_user_msi_assignment(ab_pci, user_name, - num_vectors, user_base_data, - base_vector); -} - static void ath11k_pcic_free_ext_irq(struct ath11k_base *ab) { int i, j; @@ -586,8 +563,7 @@ static int ath11k_pcic_ext_irq_config(struct ath11k_base *ab) int i, j, ret, num_vectors = 0; u32 user_base_data = 0, base_vector = 0; - ret = ath11k_pcic_get_user_msi_assignment(ath11k_pci_priv(ab), "DP", - &num_vectors, + ret = ath11k_pcic_get_user_msi_assignment(ab, "DP", &num_vectors, &user_base_data, &base_vector); if (ret < 0) @@ -662,8 +638,7 @@ int ath11k_pcic_config_irq(struct ath11k_base *ab) unsigned int msi_data; int irq, i, ret, irq_idx; - ret = ath11k_pcic_get_user_msi_assignment(ath11k_pci_priv(ab), - "CE", &msi_data_count, + ret = ath11k_pcic_get_user_msi_assignment(ab, "CE", &msi_data_count, &msi_data_start, &msi_irq_start); if (ret) return ret; diff --git a/drivers/net/wireless/ath/ath11k/pcic.h b/drivers/net/wireless/ath/ath11k/pcic.h index d5fe315ccc61c..34e8c069d6e40 100644 --- a/drivers/net/wireless/ath/ath11k/pcic.h +++ b/drivers/net/wireless/ath/ath11k/pcic.h @@ -25,7 +25,7 @@ */ #define ATH11K_PCI_ACCESS_ALWAYS_OFF 0xFE0 -int ath11k_pcic_get_user_msi_assignment(struct ath11k_pci *ar_pci, char *user_name, +int ath11k_pcic_get_user_msi_assignment(struct ath11k_base *ab, char *user_name, int *num_vectors, u32 *user_base_data, u32 *base_vector); int ath11k_pcic_get_msi_irq(struct device *dev, unsigned int vector); @@ -44,9 +44,6 @@ int ath11k_pcic_map_service_to_pipe(struct ath11k_base *ab, u16 service_id, u8 *ul_pipe, u8 *dl_pipe); void ath11k_pcic_ce_irqs_enable(struct ath11k_base *ab); void ath11k_pcic_ce_irq_disable_sync(struct ath11k_base *ab); -int ath11k_get_user_msi_assignment(struct ath11k_base *ab, char *user_name, - int *num_vectors, u32 *user_base_data, - u32 *base_vector); void ath11k_pcic_aspm_restore(struct ath11k_pci *ab_pci); int ath11k_pcic_set_irq_affinity_hint(struct ath11k_pci *ab_pci, const struct cpumask *m); From 5b32b6dd966338005671780c1df02327582c4be4 Mon Sep 17 00:00:00 2001 From: Manikanta Pubbisetty Date: Fri, 1 Apr 2022 14:53:08 +0300 Subject: [PATCH 042/228] ath11k: Remove core PCI references from PCI common code Remove core PCI and ath11k PCI references(struct ath11k_pci) from PCI common code. Since, PCI common code will be used by hybrid bus devices, this code should be independent from ATH11K PCI references and Linux core PCI references like struct pci_dev. Since this change introduces function callbacks for bus wakeup and bus release operations, wakeup_mhi HW param is no longer needed and hence it is removed completely. Alternatively, bus wakeup/release ops for QCA9074 are initialized to NULL as QCA9704 does not need bus wakeup/release for register accesses. Tested-on: WCN6855 hw2.0 PCI WLAN.HSP.1.1-01720.1-QCAHSPSWPL_V1_V2_SILICONZ_LITE-1 Tested-on: QCN9074 hw1.0 PCI WLAN.HK.2.5.0.1-01100-QCAHKSWPL_SILICONZ-1 Tested-on: IPQ8074 hw2.0 AHB WLAN.HK.2.4.0.1-00192-QCAHKSWPL_SILICONZ-1 Signed-off-by: Manikanta Pubbisetty Signed-off-by: Kalle Valo Link: https://lore.kernel.org/r/20220328055714.6449-6-quic_mpubbise@quicinc.com --- drivers/net/wireless/ath/ath11k/core.c | 6 - drivers/net/wireless/ath/ath11k/core.h | 12 ++ drivers/net/wireless/ath/ath11k/hw.h | 2 +- drivers/net/wireless/ath/ath11k/mhi.c | 6 +- drivers/net/wireless/ath/ath11k/pci.c | 146 +++++++++++++++++++-- drivers/net/wireless/ath/ath11k/pci.h | 5 +- drivers/net/wireless/ath/ath11k/pcic.c | 169 +++++++++---------------- drivers/net/wireless/ath/ath11k/pcic.h | 5 - 8 files changed, 211 insertions(+), 140 deletions(-) diff --git a/drivers/net/wireless/ath/ath11k/core.c b/drivers/net/wireless/ath/ath11k/core.c index 7f4462cf5787d..3e8d4eabbe624 100644 --- a/drivers/net/wireless/ath/ath11k/core.c +++ b/drivers/net/wireless/ath/ath11k/core.c @@ -96,7 +96,6 @@ static const struct ath11k_hw_params ath11k_hw_params[] = { .hal_params = &ath11k_hw_hal_params_ipq8074, .supports_dynamic_smps_6ghz = false, .alloc_cacheable_memory = true, - .wakeup_mhi = false, .supports_rssi_stats = false, .fw_wmi_diag_event = false, .current_cc_support = false, @@ -163,7 +162,6 @@ static const struct ath11k_hw_params ath11k_hw_params[] = { .hal_params = &ath11k_hw_hal_params_ipq8074, .supports_dynamic_smps_6ghz = false, .alloc_cacheable_memory = true, - .wakeup_mhi = false, .supports_rssi_stats = false, .fw_wmi_diag_event = false, .current_cc_support = false, @@ -229,7 +227,6 @@ static const struct ath11k_hw_params ath11k_hw_params[] = { .hal_params = &ath11k_hw_hal_params_qca6390, .supports_dynamic_smps_6ghz = false, .alloc_cacheable_memory = false, - .wakeup_mhi = true, .supports_rssi_stats = true, .fw_wmi_diag_event = true, .current_cc_support = true, @@ -295,7 +292,6 @@ static const struct ath11k_hw_params ath11k_hw_params[] = { .hal_params = &ath11k_hw_hal_params_ipq8074, .supports_dynamic_smps_6ghz = true, .alloc_cacheable_memory = true, - .wakeup_mhi = false, .supports_rssi_stats = false, .fw_wmi_diag_event = false, .current_cc_support = false, @@ -361,7 +357,6 @@ static const struct ath11k_hw_params ath11k_hw_params[] = { .hal_params = &ath11k_hw_hal_params_qca6390, .supports_dynamic_smps_6ghz = false, .alloc_cacheable_memory = false, - .wakeup_mhi = true, .supports_rssi_stats = true, .fw_wmi_diag_event = true, .current_cc_support = true, @@ -426,7 +421,6 @@ static const struct ath11k_hw_params ath11k_hw_params[] = { .hal_params = &ath11k_hw_hal_params_qca6390, .supports_dynamic_smps_6ghz = false, .alloc_cacheable_memory = false, - .wakeup_mhi = true, .supports_rssi_stats = true, .fw_wmi_diag_event = true, .current_cc_support = true, diff --git a/drivers/net/wireless/ath/ath11k/core.h b/drivers/net/wireless/ath/ath11k/core.h index 4e0861a94a148..fa299bfb4efcd 100644 --- a/drivers/net/wireless/ath/ath11k/core.h +++ b/drivers/net/wireless/ath/ath11k/core.h @@ -239,6 +239,8 @@ enum ath11k_dev_flags { ATH11K_FLAG_CE_IRQ_ENABLED, ATH11K_FLAG_EXT_IRQ_ENABLED, ATH11K_FLAG_FIXED_MEM_RGN, + ATH11K_FLAG_DEVICE_INIT_DONE, + ATH11K_FLAG_MULTI_MSI_VECTORS, }; enum ath11k_monitor_flags { @@ -728,6 +730,14 @@ struct ath11k_bus_params { bool static_window_map; }; +struct ath11k_pci_ops { + int (*wakeup)(struct ath11k_base *ab); + void (*release)(struct ath11k_base *ab); + int (*get_msi_irq)(struct ath11k_base *ab, unsigned int vector); + void (*window_write32)(struct ath11k_base *ab, u32 offset, u32 value); + u32 (*window_read32)(struct ath11k_base *ab, u32 offset); +}; + /* IPQ8074 HW channel counters frequency value in hertz */ #define IPQ8074_CC_FREQ_HERTZ 320000 @@ -925,6 +935,8 @@ struct ath11k_base { u32 addr_lo; u32 addr_hi; } msi; + + const struct ath11k_pci_ops *ops; } pci; /* must be last */ diff --git a/drivers/net/wireless/ath/ath11k/hw.h b/drivers/net/wireless/ath/ath11k/hw.h index 44025bc5d0824..08f958c03ec45 100644 --- a/drivers/net/wireless/ath/ath11k/hw.h +++ b/drivers/net/wireless/ath/ath11k/hw.h @@ -1,6 +1,7 @@ /* SPDX-License-Identifier: BSD-3-Clause-Clear */ /* * Copyright (c) 2018-2019 The Linux Foundation. All rights reserved. + * Copyright (c) 2021-2022, Qualcomm Innovation Center, Inc. All rights reserved. */ #ifndef ATH11K_HW_H @@ -189,7 +190,6 @@ struct ath11k_hw_params { const struct ath11k_hw_hal_params *hal_params; bool supports_dynamic_smps_6ghz; bool alloc_cacheable_memory; - bool wakeup_mhi; bool supports_rssi_stats; bool fw_wmi_diag_event; bool current_cc_support; diff --git a/drivers/net/wireless/ath/ath11k/mhi.c b/drivers/net/wireless/ath/ath11k/mhi.c index 5de255969364c..1aa1e0f01b85d 100644 --- a/drivers/net/wireless/ath/ath11k/mhi.c +++ b/drivers/net/wireless/ath/ath11k/mhi.c @@ -273,10 +273,10 @@ static int ath11k_mhi_get_msi(struct ath11k_pci *ab_pci) for (i = 0; i < num_vectors; i++) { msi_data = base_vector; - if (test_bit(ATH11K_PCI_FLAG_MULTI_MSI_VECTORS, &ab_pci->flags)) + if (test_bit(ATH11K_FLAG_MULTI_MSI_VECTORS, &ab->dev_flags)) msi_data += i; - irq[i] = ath11k_pcic_get_msi_irq(ab->dev, msi_data); + irq[i] = ath11k_pci_get_msi_irq(ab, msi_data); } ab_pci->mhi_ctrl->irq = irq; @@ -406,7 +406,7 @@ int ath11k_mhi_register(struct ath11k_pci *ab_pci) return ret; } - if (!test_bit(ATH11K_PCI_FLAG_MULTI_MSI_VECTORS, &ab_pci->flags)) + if (!test_bit(ATH11K_FLAG_MULTI_MSI_VECTORS, &ab->dev_flags)) mhi_ctrl->irq_flags = IRQF_SHARED | IRQF_NOBALANCING; if (test_bit(ATH11K_FLAG_FIXED_MEM_RGN, &ab->dev_flags)) { diff --git a/drivers/net/wireless/ath/ath11k/pci.c b/drivers/net/wireless/ath/ath11k/pci.c index fd5487d7045ef..3fd5b416a5644 100644 --- a/drivers/net/wireless/ath/ath11k/pci.c +++ b/drivers/net/wireless/ath/ath11k/pci.c @@ -36,6 +36,85 @@ static const struct pci_device_id ath11k_pci_id_table[] = { MODULE_DEVICE_TABLE(pci, ath11k_pci_id_table); +static int ath11k_pci_bus_wake_up(struct ath11k_base *ab) +{ + struct ath11k_pci *ab_pci = ath11k_pci_priv(ab); + + return mhi_device_get_sync(ab_pci->mhi_ctrl->mhi_dev); +} + +static void ath11k_pci_bus_release(struct ath11k_base *ab) +{ + struct ath11k_pci *ab_pci = ath11k_pci_priv(ab); + + mhi_device_put(ab_pci->mhi_ctrl->mhi_dev); +} + +static inline void ath11k_pci_select_window(struct ath11k_pci *ab_pci, u32 offset) +{ + struct ath11k_base *ab = ab_pci->ab; + + u32 window = FIELD_GET(ATH11K_PCI_WINDOW_VALUE_MASK, offset); + + lockdep_assert_held(&ab_pci->window_lock); + + if (window != ab_pci->register_window) { + iowrite32(ATH11K_PCI_WINDOW_ENABLE_BIT | window, + ab->mem + ATH11K_PCI_WINDOW_REG_ADDRESS); + ioread32(ab->mem + ATH11K_PCI_WINDOW_REG_ADDRESS); + ab_pci->register_window = window; + } +} + +static void +ath11k_pci_window_write32(struct ath11k_base *ab, u32 offset, u32 value) +{ + struct ath11k_pci *ab_pci = ath11k_pci_priv(ab); + u32 window_start = ATH11K_PCI_WINDOW_START; + + spin_lock_bh(&ab_pci->window_lock); + ath11k_pci_select_window(ab_pci, offset); + iowrite32(value, ab->mem + window_start + + (offset & ATH11K_PCI_WINDOW_RANGE_MASK)); + spin_unlock_bh(&ab_pci->window_lock); +} + +static u32 ath11k_pci_window_read32(struct ath11k_base *ab, u32 offset) +{ + struct ath11k_pci *ab_pci = ath11k_pci_priv(ab); + u32 window_start = ATH11K_PCI_WINDOW_START; + u32 val; + + spin_lock_bh(&ab_pci->window_lock); + ath11k_pci_select_window(ab_pci, offset); + val = ioread32(ab->mem + window_start + + (offset & ATH11K_PCI_WINDOW_RANGE_MASK)); + spin_unlock_bh(&ab_pci->window_lock); + + return val; +} + +int ath11k_pci_get_msi_irq(struct ath11k_base *ab, unsigned int vector) +{ + struct pci_dev *pci_dev = to_pci_dev(ab->dev); + + return pci_irq_vector(pci_dev, vector); +} + +static const struct ath11k_pci_ops ath11k_pci_ops_qca6390 = { + .wakeup = ath11k_pci_bus_wake_up, + .release = ath11k_pci_bus_release, + .get_msi_irq = ath11k_pci_get_msi_irq, + .window_write32 = ath11k_pci_window_write32, + .window_read32 = ath11k_pci_window_read32, +}; + +static const struct ath11k_pci_ops ath11k_pci_ops_qcn9074 = { + .get_msi_irq = ath11k_pci_get_msi_irq, + .window_write32 = ath11k_pci_window_write32, + .window_read32 = ath11k_pci_window_read32, +}; + static const struct ath11k_bus_params ath11k_pci_bus_params = { .mhi_support = true, .m3_fw_support = true, @@ -318,8 +397,7 @@ static int ath11k_pci_alloc_msi(struct ath11k_pci *ab_pci) msi_config->total_vectors, PCI_IRQ_MSI); if (num_vectors == msi_config->total_vectors) { - set_bit(ATH11K_PCI_FLAG_MULTI_MSI_VECTORS, &ab_pci->flags); - ab_pci->irq_flags = IRQF_SHARED; + set_bit(ATH11K_FLAG_MULTI_MSI_VECTORS, &ab->dev_flags); } else { num_vectors = pci_alloc_irq_vectors(ab_pci->pdev, 1, @@ -329,9 +407,8 @@ static int ath11k_pci_alloc_msi(struct ath11k_pci *ab_pci) ret = -EINVAL; goto reset_msi_config; } - clear_bit(ATH11K_PCI_FLAG_MULTI_MSI_VECTORS, &ab_pci->flags); + clear_bit(ATH11K_FLAG_MULTI_MSI_VECTORS, &ab->dev_flags); ab->pci.msi.config = &msi_config_one_msi; - ab_pci->irq_flags = IRQF_SHARED | IRQF_NOBALANCING; ath11k_dbg(ab, ATH11K_DBG_PCI, "request MSI one vector\n"); } ath11k_info(ab, "MSI vectors: %d\n", num_vectors); @@ -487,13 +564,20 @@ static void ath11k_pci_aspm_disable(struct ath11k_pci *ab_pci) set_bit(ATH11K_PCI_ASPM_RESTORE, &ab_pci->flags); } +static void ath11k_pci_aspm_restore(struct ath11k_pci *ab_pci) +{ + if (test_and_clear_bit(ATH11K_PCI_ASPM_RESTORE, &ab_pci->flags)) + pcie_capability_write_word(ab_pci->pdev, PCI_EXP_LNKCTL, + ab_pci->link_ctl); +} + static int ath11k_pci_power_up(struct ath11k_base *ab) { struct ath11k_pci *ab_pci = ath11k_pci_priv(ab); int ret; ab_pci->register_window = 0; - clear_bit(ATH11K_PCI_FLAG_INIT_DONE, &ab_pci->flags); + clear_bit(ATH11K_FLAG_DEVICE_INIT_DONE, &ab->dev_flags); ath11k_pci_sw_reset(ab_pci->ab, true); /* Disable ASPM during firmware download due to problems switching @@ -520,14 +604,14 @@ static void ath11k_pci_power_down(struct ath11k_base *ab) struct ath11k_pci *ab_pci = ath11k_pci_priv(ab); /* restore aspm in case firmware bootup fails */ - ath11k_pcic_aspm_restore(ab_pci); + ath11k_pci_aspm_restore(ab_pci); ath11k_pci_force_wake(ab_pci->ab); ath11k_pci_msi_disable(ab_pci); ath11k_mhi_stop(ab_pci); - clear_bit(ATH11K_PCI_FLAG_INIT_DONE, &ab_pci->flags); + clear_bit(ATH11K_FLAG_DEVICE_INIT_DONE, &ab->dev_flags); ath11k_pci_sw_reset(ab_pci->ab, false); } @@ -559,8 +643,25 @@ static void ath11k_pci_hif_ce_irq_disable(struct ath11k_base *ab) ath11k_pcic_ce_irq_disable_sync(ab); } +static int ath11k_pci_start(struct ath11k_base *ab) +{ + struct ath11k_pci *ab_pci = ath11k_pci_priv(ab); + + /* TODO: for now don't restore ASPM in case of single MSI + * vector as MHI register reading in M2 causes system hang. + */ + if (test_bit(ATH11K_FLAG_MULTI_MSI_VECTORS, &ab->dev_flags)) + ath11k_pci_aspm_restore(ab_pci); + else + ath11k_info(ab, "leaving PCI ASPM disabled to avoid MHI M2 problems\n"); + + ath11k_pcic_start(ab); + + return 0; +} + static const struct ath11k_hif_ops ath11k_pci_hif_ops = { - .start = ath11k_pcic_start, + .start = ath11k_pci_start, .stop = ath11k_pcic_stop, .read32 = ath11k_pcic_read32, .write32 = ath11k_pcic_write32, @@ -592,6 +693,15 @@ static void ath11k_pci_read_hw_version(struct ath11k_base *ab, u32 *major, u32 * *major, *minor); } +static int ath11k_pci_set_irq_affinity_hint(struct ath11k_pci *ab_pci, + const struct cpumask *m) +{ + if (test_bit(ATH11K_FLAG_MULTI_MSI_VECTORS, &ab_pci->ab->dev_flags)) + return 0; + + return irq_set_affinity_hint(ab_pci->pdev->irq, m); +} + static int ath11k_pci_probe(struct pci_dev *pdev, const struct pci_device_id *pci_dev) { @@ -654,9 +764,12 @@ static int ath11k_pci_probe(struct pci_dev *pdev, ret = -EOPNOTSUPP; goto err_pci_free_region; } + + ab->pci.ops = &ath11k_pci_ops_qca6390; break; case QCN9074_DEVICE_ID: ab->bus_params.static_window_map = true; + ab->pci.ops = &ath11k_pci_ops_qcn9074; ab->hw_rev = ATH11K_HW_QCN9074_HW10; break; case WCN6855_DEVICE_ID: @@ -685,6 +798,8 @@ static int ath11k_pci_probe(struct pci_dev *pdev, ret = -EOPNOTSUPP; goto err_pci_free_region; } + + ab->pci.ops = &ath11k_pci_ops_qca6390; break; default: dev_err(&pdev->dev, "Unknown PCI device found: 0x%x\n", @@ -733,6 +848,12 @@ static int ath11k_pci_probe(struct pci_dev *pdev, goto err_ce_free; } + ret = ath11k_pci_set_irq_affinity_hint(ab_pci, cpumask_of(0)); + if (ret) { + ath11k_err(ab, "failed to set irq affinity %d\n", ret); + goto err_free_irq; + } + /* kernel may allocate a dummy vector before request_irq and * then allocate a real vector when request_irq is called. * So get msi_data here again to avoid spurious interrupt @@ -741,16 +862,19 @@ static int ath11k_pci_probe(struct pci_dev *pdev, ret = ath11k_pci_config_msi_data(ab_pci); if (ret) { ath11k_err(ab, "failed to config msi_data: %d\n", ret); - goto err_free_irq; + goto err_irq_affinity_cleanup; } ret = ath11k_core_init(ab); if (ret) { ath11k_err(ab, "failed to init core: %d\n", ret); - goto err_free_irq; + goto err_irq_affinity_cleanup; } return 0; +err_irq_affinity_cleanup: + ath11k_pci_set_irq_affinity_hint(ab_pci, NULL); + err_free_irq: ath11k_pcic_free_irq(ab); @@ -780,7 +904,7 @@ static void ath11k_pci_remove(struct pci_dev *pdev) struct ath11k_base *ab = pci_get_drvdata(pdev); struct ath11k_pci *ab_pci = ath11k_pci_priv(ab); - ath11k_pcic_set_irq_affinity_hint(ab_pci, NULL); + ath11k_pci_set_irq_affinity_hint(ab_pci, NULL); if (test_bit(ATH11K_FLAG_QMI_FAIL, &ab->dev_flags)) { ath11k_pci_power_down(ab); diff --git a/drivers/net/wireless/ath/ath11k/pci.h b/drivers/net/wireless/ath/ath11k/pci.h index c9cae48d784e7..16a000b9cc5e2 100644 --- a/drivers/net/wireless/ath/ath11k/pci.h +++ b/drivers/net/wireless/ath/ath11k/pci.h @@ -54,9 +54,7 @@ #define QFPROM_PWR_CTRL_VDD4BLOW_MASK 0x4 enum ath11k_pci_flags { - ATH11K_PCI_FLAG_INIT_DONE, ATH11K_PCI_ASPM_RESTORE, - ATH11K_PCI_FLAG_MULTI_MSI_VECTORS, }; struct ath11k_pci { @@ -74,8 +72,6 @@ struct ath11k_pci { /* enum ath11k_pci_flags */ unsigned long flags; u16 link_ctl; - - unsigned long irq_flags; }; static inline struct ath11k_pci *ath11k_pci_priv(struct ath11k_base *ab) @@ -83,4 +79,5 @@ static inline struct ath11k_pci *ath11k_pci_priv(struct ath11k_base *ab) return (struct ath11k_pci *)ab->drv_priv; } +int ath11k_pci_get_msi_irq(struct ath11k_base *ab, unsigned int vector); #endif diff --git a/drivers/net/wireless/ath/ath11k/pcic.c b/drivers/net/wireless/ath/ath11k/pcic.c index c743095387f1a..63c678aea29e0 100644 --- a/drivers/net/wireless/ath/ath11k/pcic.c +++ b/drivers/net/wireless/ath/ath11k/pcic.c @@ -4,7 +4,6 @@ * Copyright (c) 2021-2022, Qualcomm Innovation Center, Inc. All rights reserved. */ -#include #include "core.h" #include "pcic.h" #include "debug.h" @@ -132,29 +131,6 @@ int ath11k_pcic_init_msi_config(struct ath11k_base *ab) } EXPORT_SYMBOL(ath11k_pcic_init_msi_config); -void ath11k_pcic_aspm_restore(struct ath11k_pci *ab_pci) -{ - if (test_and_clear_bit(ATH11K_PCI_ASPM_RESTORE, &ab_pci->flags)) - pcie_capability_write_word(ab_pci->pdev, PCI_EXP_LNKCTL, - ab_pci->link_ctl); -} - -static inline void ath11k_pcic_select_window(struct ath11k_pci *ab_pci, u32 offset) -{ - struct ath11k_base *ab = ab_pci->ab; - - u32 window = FIELD_GET(ATH11K_PCI_WINDOW_VALUE_MASK, offset); - - lockdep_assert_held(&ab_pci->window_lock); - - if (window != ab_pci->register_window) { - iowrite32(ATH11K_PCI_WINDOW_ENABLE_BIT | window, - ab->mem + ATH11K_PCI_WINDOW_REG_ADDRESS); - ioread32(ab->mem + ATH11K_PCI_WINDOW_REG_ADDRESS); - ab_pci->register_window = window; - } -} - static inline u32 ath11k_pcic_get_window_start(struct ath11k_base *ab, u32 offset) { @@ -174,17 +150,15 @@ static inline u32 ath11k_pcic_get_window_start(struct ath11k_base *ab, void ath11k_pcic_write32(struct ath11k_base *ab, u32 offset, u32 value) { - struct ath11k_pci *ab_pci = ath11k_pci_priv(ab); u32 window_start; int ret = 0; /* for offset beyond BAR + 4K - 32, may - * need to wakeup MHI to access. + * need to wakeup the device to access. */ - if (ab->hw_params.wakeup_mhi && - test_bit(ATH11K_PCI_FLAG_INIT_DONE, &ab_pci->flags) && - offset >= ATH11K_PCI_ACCESS_ALWAYS_OFF) - ret = mhi_device_get_sync(ab_pci->mhi_ctrl->mhi_dev); + if (test_bit(ATH11K_FLAG_DEVICE_INIT_DONE, &ab->dev_flags) && + offset >= ATH11K_PCI_ACCESS_ALWAYS_OFF && ab->pci.ops->wakeup) + ret = ab->pci.ops->wakeup(ab); if (offset < ATH11K_PCI_WINDOW_START) { iowrite32(value, ab->mem + offset); @@ -194,38 +168,32 @@ void ath11k_pcic_write32(struct ath11k_base *ab, u32 offset, u32 value) else window_start = ATH11K_PCI_WINDOW_START; - if (window_start == ATH11K_PCI_WINDOW_START) { - spin_lock_bh(&ab_pci->window_lock); - ath11k_pcic_select_window(ab_pci, offset); - iowrite32(value, ab->mem + window_start + - (offset & ATH11K_PCI_WINDOW_RANGE_MASK)); - spin_unlock_bh(&ab_pci->window_lock); + if (window_start == ATH11K_PCI_WINDOW_START && + ab->pci.ops->window_write32) { + ab->pci.ops->window_write32(ab, offset, value); } else { iowrite32(value, ab->mem + window_start + (offset & ATH11K_PCI_WINDOW_RANGE_MASK)); } } - if (ab->hw_params.wakeup_mhi && - test_bit(ATH11K_PCI_FLAG_INIT_DONE, &ab_pci->flags) && - offset >= ATH11K_PCI_ACCESS_ALWAYS_OFF && + if (test_bit(ATH11K_FLAG_DEVICE_INIT_DONE, &ab->dev_flags) && + offset >= ATH11K_PCI_ACCESS_ALWAYS_OFF && ab->pci.ops->release && !ret) - mhi_device_put(ab_pci->mhi_ctrl->mhi_dev); + ab->pci.ops->release(ab); } u32 ath11k_pcic_read32(struct ath11k_base *ab, u32 offset) { - struct ath11k_pci *ab_pci = ath11k_pci_priv(ab); u32 val, window_start; int ret = 0; /* for offset beyond BAR + 4K - 32, may - * need to wakeup MHI to access. + * need to wakeup the device to access. */ - if (ab->hw_params.wakeup_mhi && - test_bit(ATH11K_PCI_FLAG_INIT_DONE, &ab_pci->flags) && - offset >= ATH11K_PCI_ACCESS_ALWAYS_OFF) - ret = mhi_device_get_sync(ab_pci->mhi_ctrl->mhi_dev); + if (test_bit(ATH11K_FLAG_DEVICE_INIT_DONE, &ab->dev_flags) && + offset >= ATH11K_PCI_ACCESS_ALWAYS_OFF && ab->pci.ops->wakeup) + ret = ab->pci.ops->wakeup(ab); if (offset < ATH11K_PCI_WINDOW_START) { val = ioread32(ab->mem + offset); @@ -235,34 +203,23 @@ u32 ath11k_pcic_read32(struct ath11k_base *ab, u32 offset) else window_start = ATH11K_PCI_WINDOW_START; - if (window_start == ATH11K_PCI_WINDOW_START) { - spin_lock_bh(&ab_pci->window_lock); - ath11k_pcic_select_window(ab_pci, offset); - val = ioread32(ab->mem + window_start + - (offset & ATH11K_PCI_WINDOW_RANGE_MASK)); - spin_unlock_bh(&ab_pci->window_lock); + if (window_start == ATH11K_PCI_WINDOW_START && + ab->pci.ops->window_read32) { + val = ab->pci.ops->window_read32(ab, offset); } else { val = ioread32(ab->mem + window_start + (offset & ATH11K_PCI_WINDOW_RANGE_MASK)); } } - if (ab->hw_params.wakeup_mhi && - test_bit(ATH11K_PCI_FLAG_INIT_DONE, &ab_pci->flags) && - offset >= ATH11K_PCI_ACCESS_ALWAYS_OFF && + if (test_bit(ATH11K_FLAG_DEVICE_INIT_DONE, &ab->dev_flags) && + offset >= ATH11K_PCI_ACCESS_ALWAYS_OFF && ab->pci.ops->release && !ret) - mhi_device_put(ab_pci->mhi_ctrl->mhi_dev); + ab->pci.ops->release(ab); return val; } -int ath11k_pcic_get_msi_irq(struct device *dev, unsigned int vector) -{ - struct pci_dev *pci_dev = to_pci_dev(dev); - - return pci_irq_vector(pci_dev, vector); -} - void ath11k_pcic_get_msi_address(struct ath11k_base *ab, u32 *msi_addr_lo, u32 *msi_addr_hi) { @@ -343,13 +300,12 @@ void ath11k_pcic_free_irq(struct ath11k_base *ab) static void ath11k_pcic_ce_irq_enable(struct ath11k_base *ab, u16 ce_id) { - struct ath11k_pci *ab_pci = ath11k_pci_priv(ab); u32 irq_idx; /* In case of one MSI vector, we handle irq enable/disable in a * uniform way since we only have one irq */ - if (!test_bit(ATH11K_PCI_FLAG_MULTI_MSI_VECTORS, &ab_pci->flags)) + if (!test_bit(ATH11K_FLAG_MULTI_MSI_VECTORS, &ab->dev_flags)) return; irq_idx = ATH11K_PCI_IRQ_CE0_OFFSET + ce_id; @@ -358,13 +314,12 @@ static void ath11k_pcic_ce_irq_enable(struct ath11k_base *ab, u16 ce_id) static void ath11k_pcic_ce_irq_disable(struct ath11k_base *ab, u16 ce_id) { - struct ath11k_pci *ab_pci = ath11k_pci_priv(ab); u32 irq_idx; /* In case of one MSI vector, we handle irq enable/disable in a * uniform way since we only have one irq */ - if (!test_bit(ATH11K_PCI_FLAG_MULTI_MSI_VECTORS, &ab_pci->flags)) + if (!test_bit(ATH11K_FLAG_MULTI_MSI_VECTORS, &ab->dev_flags)) return; irq_idx = ATH11K_PCI_IRQ_CE0_OFFSET + ce_id; @@ -429,13 +384,13 @@ static irqreturn_t ath11k_pcic_ce_interrupt_handler(int irq, void *arg) static void ath11k_pcic_ext_grp_disable(struct ath11k_ext_irq_grp *irq_grp) { - struct ath11k_pci *ab_pci = ath11k_pci_priv(irq_grp->ab); + struct ath11k_base *ab = irq_grp->ab; int i; /* In case of one MSI vector, we handle irq enable/disable * in a uniform way since we only have one irq */ - if (!test_bit(ATH11K_PCI_FLAG_MULTI_MSI_VECTORS, &ab_pci->flags)) + if (!test_bit(ATH11K_FLAG_MULTI_MSI_VECTORS, &ab->dev_flags)) return; for (i = 0; i < irq_grp->num_irq; i++) @@ -463,13 +418,13 @@ static void __ath11k_pcic_ext_irq_disable(struct ath11k_base *sc) static void ath11k_pcic_ext_grp_enable(struct ath11k_ext_irq_grp *irq_grp) { - struct ath11k_pci *ab_pci = ath11k_pci_priv(irq_grp->ab); + struct ath11k_base *ab = irq_grp->ab; int i; /* In case of one MSI vector, we handle irq enable/disable in a * uniform way since we only have one irq */ - if (!test_bit(ATH11K_PCI_FLAG_MULTI_MSI_VECTORS, &ab_pci->flags)) + if (!test_bit(ATH11K_FLAG_MULTI_MSI_VECTORS, &ab->dev_flags)) return; for (i = 0; i < irq_grp->num_irq; i++) @@ -557,11 +512,22 @@ static irqreturn_t ath11k_pcic_ext_interrupt_handler(int irq, void *arg) return IRQ_HANDLED; } +static int +ath11k_pcic_get_msi_irq(struct ath11k_base *ab, unsigned int vector) +{ + if (!ab->pci.ops->get_msi_irq) { + WARN_ONCE(1, "get_msi_irq pci op not defined"); + return -EOPNOTSUPP; + } + + return ab->pci.ops->get_msi_irq(ab, vector); +} + static int ath11k_pcic_ext_irq_config(struct ath11k_base *ab) { - struct ath11k_pci *ab_pci = ath11k_pci_priv(ab); int i, j, ret, num_vectors = 0; u32 user_base_data = 0, base_vector = 0; + unsigned long irq_flags; ret = ath11k_pcic_get_user_msi_assignment(ab, "DP", &num_vectors, &user_base_data, @@ -569,6 +535,10 @@ static int ath11k_pcic_ext_irq_config(struct ath11k_base *ab) if (ret < 0) return ret; + irq_flags = IRQF_SHARED; + if (!test_bit(ATH11K_FLAG_MULTI_MSI_VECTORS, &ab->dev_flags)) + irq_flags |= IRQF_NOBALANCING; + for (i = 0; i < ATH11K_EXT_IRQ_GRP_NUM_MAX; i++) { struct ath11k_ext_irq_grp *irq_grp = &ab->ext_irq_grp[i]; u32 num_irq = 0; @@ -596,7 +566,10 @@ static int ath11k_pcic_ext_irq_config(struct ath11k_base *ab) for (j = 0; j < irq_grp->num_irq; j++) { int irq_idx = irq_grp->irqs[j]; int vector = (i % num_vectors) + base_vector; - int irq = ath11k_pcic_get_msi_irq(ab->dev, vector); + int irq = ath11k_pcic_get_msi_irq(ab, vector); + + if (irq < 0) + return irq; ab->irq_num[irq_idx] = irq; @@ -605,8 +578,7 @@ static int ath11k_pcic_ext_irq_config(struct ath11k_base *ab) irq_set_status_flags(irq, IRQ_DISABLE_UNLAZY); ret = request_irq(irq, ath11k_pcic_ext_interrupt_handler, - ab_pci->irq_flags, - "DP_EXT_IRQ", irq_grp); + irq_flags, "DP_EXT_IRQ", irq_grp); if (ret) { ath11k_err(ab, "failed request irq %d: %d\n", vector, ret); @@ -619,35 +591,24 @@ static int ath11k_pcic_ext_irq_config(struct ath11k_base *ab) return 0; } -int ath11k_pcic_set_irq_affinity_hint(struct ath11k_pci *ab_pci, - const struct cpumask *m) -{ - if (test_bit(ATH11K_PCI_FLAG_MULTI_MSI_VECTORS, &ab_pci->flags)) - return 0; - - return irq_set_affinity_hint(ab_pci->pdev->irq, m); -} - int ath11k_pcic_config_irq(struct ath11k_base *ab) { - struct ath11k_pci *ab_pci = ath11k_pci_priv(ab); struct ath11k_ce_pipe *ce_pipe; u32 msi_data_start; u32 msi_data_count, msi_data_idx; u32 msi_irq_start; unsigned int msi_data; int irq, i, ret, irq_idx; + unsigned long irq_flags; ret = ath11k_pcic_get_user_msi_assignment(ab, "CE", &msi_data_count, &msi_data_start, &msi_irq_start); if (ret) return ret; - ret = ath11k_pcic_set_irq_affinity_hint(ab_pci, cpumask_of(0)); - if (ret) { - ath11k_err(ab, "failed to set irq affinity %d\n", ret); - return ret; - } + irq_flags = IRQF_SHARED; + if (!test_bit(ATH11K_FLAG_MULTI_MSI_VECTORS, &ab->dev_flags)) + irq_flags |= IRQF_NOBALANCING; /* Configure CE irqs */ for (i = 0, msi_data_idx = 0; i < ab->hw_params.ce_count; i++) { @@ -655,7 +616,10 @@ int ath11k_pcic_config_irq(struct ath11k_base *ab) continue; msi_data = (msi_data_idx % msi_data_count) + msi_irq_start; - irq = ath11k_pcic_get_msi_irq(ab->dev, msi_data); + irq = ath11k_pcic_get_msi_irq(ab, msi_data); + if (irq < 0) + return irq; + ce_pipe = &ab->ce.ce_pipe[i]; irq_idx = ATH11K_PCI_IRQ_CE0_OFFSET + i; @@ -663,12 +627,11 @@ int ath11k_pcic_config_irq(struct ath11k_base *ab) tasklet_setup(&ce_pipe->intr_tq, ath11k_pcic_ce_tasklet); ret = request_irq(irq, ath11k_pcic_ce_interrupt_handler, - ab_pci->irq_flags, irq_name[irq_idx], - ce_pipe); + irq_flags, irq_name[irq_idx], ce_pipe); if (ret) { ath11k_err(ab, "failed to request irq %d: %d\n", irq_idx, ret); - goto err_irq_affinity_cleanup; + return ret; } ab->irq_num[irq_idx] = irq; @@ -679,13 +642,9 @@ int ath11k_pcic_config_irq(struct ath11k_base *ab) ret = ath11k_pcic_ext_irq_config(ab); if (ret) - goto err_irq_affinity_cleanup; + return ret; return 0; - -err_irq_affinity_cleanup: - ath11k_pcic_set_irq_affinity_hint(ab_pci, NULL); - return ret; } void ath11k_pcic_ce_irqs_enable(struct ath11k_base *ab) @@ -730,17 +689,7 @@ void ath11k_pcic_stop(struct ath11k_base *ab) int ath11k_pcic_start(struct ath11k_base *ab) { - struct ath11k_pci *ab_pci = ath11k_pci_priv(ab); - - set_bit(ATH11K_PCI_FLAG_INIT_DONE, &ab_pci->flags); - - /* TODO: for now don't restore ASPM in case of single MSI - * vector as MHI register reading in M2 causes system hang. - */ - if (test_bit(ATH11K_PCI_FLAG_MULTI_MSI_VECTORS, &ab_pci->flags)) - ath11k_pcic_aspm_restore(ab_pci); - else - ath11k_info(ab, "leaving PCI ASPM disabled to avoid MHI M2 problems\n"); + set_bit(ATH11K_FLAG_DEVICE_INIT_DONE, &ab->dev_flags); ath11k_pcic_ce_irqs_enable(ab); ath11k_ce_rx_post_buf(ab); diff --git a/drivers/net/wireless/ath/ath11k/pcic.h b/drivers/net/wireless/ath/ath11k/pcic.h index 34e8c069d6e40..c53d86289a8eb 100644 --- a/drivers/net/wireless/ath/ath11k/pcic.h +++ b/drivers/net/wireless/ath/ath11k/pcic.h @@ -8,7 +8,6 @@ #define _ATH11K_PCI_CMN_H #include "core.h" -#include "pci.h" #define ATH11K_PCI_IRQ_CE0_OFFSET 3 #define ATH11K_PCI_IRQ_DP_OFFSET 14 @@ -28,7 +27,6 @@ int ath11k_pcic_get_user_msi_assignment(struct ath11k_base *ab, char *user_name, int *num_vectors, u32 *user_base_data, u32 *base_vector); -int ath11k_pcic_get_msi_irq(struct device *dev, unsigned int vector); void ath11k_pcic_write32(struct ath11k_base *ab, u32 offset, u32 value); u32 ath11k_pcic_read32(struct ath11k_base *ab, u32 offset); void ath11k_pcic_get_msi_address(struct ath11k_base *ab, u32 *msi_addr_lo, @@ -44,8 +42,5 @@ int ath11k_pcic_map_service_to_pipe(struct ath11k_base *ab, u16 service_id, u8 *ul_pipe, u8 *dl_pipe); void ath11k_pcic_ce_irqs_enable(struct ath11k_base *ab); void ath11k_pcic_ce_irq_disable_sync(struct ath11k_base *ab); -void ath11k_pcic_aspm_restore(struct ath11k_pci *ab_pci); -int ath11k_pcic_set_irq_affinity_hint(struct ath11k_pci *ab_pci, - const struct cpumask *m); int ath11k_pcic_init_msi_config(struct ath11k_base *ab); #endif From 50dc9ce9f80554a88e33b73c30851acf2be36ed3 Mon Sep 17 00:00:00 2001 From: Karthikeyan Kathirvel Date: Fri, 1 Apr 2022 14:53:09 +0300 Subject: [PATCH 043/228] ath11k: Change max no of active probe SSID and BSSID to fw capability The maximum number of SSIDs in a for active probe requests is currently reported as 16 (WLAN_SCAN_PARAMS_MAX_SSID) when registering the driver. The scan_req_params structure only has the capacity to hold 10 SSIDs. This leads to a buffer overflow which can be triggered from wpa_supplicant in userspace. When copying the SSIDs into the scan_req_params structure in the ath11k_mac_op_hw_scan route, it can overwrite the extraie pointer. Firmware supports 16 ssid * 4 bssid, for each ssid 4 bssid combo probe request will be sent, so totally 64 probe requests supported. So set both max ssid and bssid to 16 and 4 respectively. Remove the redundant macros of ssid and bssid. Tested-on: IPQ8074 hw2.0 AHB WLAN.HK.2.7.0.1-01300-QCAHKSWPL_SILICONZ-1 Signed-off-by: Karthikeyan Kathirvel Signed-off-by: Kalle Valo Link: https://lore.kernel.org/r/20220329150221.21907-1-quic_kathirve@quicinc.com --- drivers/net/wireless/ath/ath11k/wmi.h | 12 ++---------- 1 file changed, 2 insertions(+), 10 deletions(-) diff --git a/drivers/net/wireless/ath/ath11k/wmi.h b/drivers/net/wireless/ath/ath11k/wmi.h index 925b8003feae9..c9ffefea549cd 100644 --- a/drivers/net/wireless/ath/ath11k/wmi.h +++ b/drivers/net/wireless/ath/ath11k/wmi.h @@ -3089,9 +3089,6 @@ enum scan_dwelltime_adaptive_mode { SCAN_DWELL_MODE_STATIC = 4 }; -#define WLAN_SCAN_MAX_NUM_SSID 10 -#define WLAN_SCAN_MAX_NUM_BSSID 10 - #define WLAN_SSID_MAX_LEN 32 struct element_info { @@ -3106,7 +3103,6 @@ struct wlan_ssid { #define WMI_IE_BITMAP_SIZE 8 -#define WMI_SCAN_MAX_NUM_SSID 0x0A /* prefix used by scan requestor ids on the host */ #define WMI_HOST_SCAN_REQUESTOR_ID_PREFIX 0xA000 @@ -3114,10 +3110,6 @@ struct wlan_ssid { /* host cycles through the lower 12 bits to generate ids */ #define WMI_HOST_SCAN_REQ_ID_PREFIX 0xA000 -#define WLAN_SCAN_PARAMS_MAX_SSID 16 -#define WLAN_SCAN_PARAMS_MAX_BSSID 4 -#define WLAN_SCAN_PARAMS_MAX_IE_LEN 256 - /* Values lower than this may be refused by some firmware revisions with a scan * completion with a timedout reason. */ @@ -3313,8 +3305,8 @@ struct scan_req_params { u32 n_probes; u32 *chan_list; u32 notify_scan_events; - struct wlan_ssid ssid[WLAN_SCAN_MAX_NUM_SSID]; - struct wmi_mac_addr bssid_list[WLAN_SCAN_MAX_NUM_BSSID]; + struct wlan_ssid ssid[WLAN_SCAN_PARAMS_MAX_SSID]; + struct wmi_mac_addr bssid_list[WLAN_SCAN_PARAMS_MAX_BSSID]; struct element_info extraie; struct element_info htcap; struct element_info vhtcap; From 2dd398dee7aa5ec6b296d9915bbb1c1a76199b4a Mon Sep 17 00:00:00 2001 From: Baochen Qiang Date: Fri, 1 Apr 2022 14:53:10 +0300 Subject: [PATCH 044/228] ath11k: Remove unnecessary delay in ath11k_core_suspend The intended delay in ath11k_core_suspend is introduced in commit d1b0c33850d2 ("ath11k: implement suspend for QCA6390 PCI devices"), now with ath11k_mac_wait_tx_complete added in commit ba9177fcef21 ("ath11k: Add basic WoW functionalities"), that delay is not necessary now, so remove it. This is found in code review. Tested-on: WCN6855 hw2.0 PCI WLAN.HSP.1.1-02431-QCAHSPSWPL_V1_V2_SILICONZ_LITE-1 Signed-off-by: Baochen Qiang Signed-off-by: Kalle Valo Link: https://lore.kernel.org/r/20220331002105.1162099-1-quic_bqiang@quicinc.com --- drivers/net/wireless/ath/ath11k/core.c | 5 ----- 1 file changed, 5 deletions(-) diff --git a/drivers/net/wireless/ath/ath11k/core.c b/drivers/net/wireless/ath/ath11k/core.c index 3e8d4eabbe624..cbac1919867f7 100644 --- a/drivers/net/wireless/ath/ath11k/core.c +++ b/drivers/net/wireless/ath/ath11k/core.c @@ -453,11 +453,6 @@ int ath11k_core_suspend(struct ath11k_base *ab) if (!ar || ar->state != ATH11K_STATE_OFF) return 0; - /* TODO: there can frames in queues so for now add delay as a hack. - * Need to implement to handle and remove this delay. - */ - msleep(500); - ret = ath11k_dp_rx_pktlog_stop(ab, true); if (ret) { ath11k_warn(ab, "failed to stop dp rx (and timer) pktlog during suspend: %d\n", From 633469e3bac10650ecff421ba6b9603d67da884b Mon Sep 17 00:00:00 2001 From: Nagarajan Maran Date: Fri, 1 Apr 2022 14:53:10 +0300 Subject: [PATCH 045/228] ath11k: fix driver initialization failure with WoW unsupported hw In the "ath11k_wow_init", error value "EINVAL" is returned when the check for firmware support of WoW feature fails, which in turn stops the driver initialization. Warning message: [ 31.040144] ------------[ cut here ]------------ [ 31.040185] WARNING: CPU: 1 PID: 51 at drivers/net/wireless/ath/ath11k/wow.c:813 ath11k_wow_init+0xc8/0x13a8 [ath11k] [ 31.043846] Modules linked in: ath11k_pci ath11k qmi_helpers [ 31.054341] CPU: 1 PID: 51 Comm: kworker/u8:1 Tainted: G W 5.17.0-wt-ath-594817-ga7f6aa925cf8-dirty #17 [ 31.060078] Hardware name: Qualcomm Technologies, Inc. IPQ8074/AP-HK10-C2 (DT) [ 31.070578] Workqueue: ath11k_qmi_driver_event ath11k_qmi_driver_event_work [ath11k] [ 31.077782] pstate: 80000005 (Nzcv daif -PAN -UAO -TCO -DIT -SSBS BTYPE=--) [ 31.085676] pc : ath11k_wow_init+0xc8/0x13a8 [ath11k] [ 31.092359] lr : ath11k_mac_register+0x548/0xb98 [ath11k] [ 31.097567] sp : ffff80000aa13c40 [ 31.102944] x29: ffff80000aa13c40 x28: ffff800009184390 x27: ffff000002959f20 [ 31.106251] x26: ffff000002828000 x25: ffff000002830000 x24: ffff000002830000 [ 31.113369] x23: ffff000002820000 x22: ffff00000282854c x21: 0000000000000000 [ 31.120487] x20: ffff00000295cf20 x19: ffff000002828540 x18: 0000000000000031 [ 31.127605] x17: 0000000000000004 x16: ffff0000028285fc x15: ffff00000295b040 [ 31.134723] x14: 0000000000000067 x13: ffff00000282859c x12: 000000000000000d [ 31.141840] x11: 0000000000000018 x10: 0000000000000004 x9 : 0000000000000000 [ 31.148959] x8 : ffff00000289d680 x7 : 0000000000000000 x6 : 000000000000003f [ 31.156077] x5 : 0000000000000040 x4 : 0000000000000000 x3 : ffff000002820968 [ 31.163196] x2 : 0000000000000080 x1 : 0080008af9981779 x0 : ffff000002959f20 [ 31.170314] Call trace: [ 31.177421] ath11k_wow_init+0xc8/0x13a8 [ath11k] [ 31.179684] ath11k_core_qmi_firmware_ready+0x430/0x5e0 [ath11k] [ 31.184548] ath11k_qmi_driver_event_work+0x16c/0x4f8 [ath11k] [ 31.190623] process_one_work+0x134/0x350 [ 31.196262] worker_thread+0x12c/0x450 [ 31.200340] kthread+0xf4/0x110 [ 31.203986] ret_from_fork+0x10/0x20 [ 31.207026] ---[ end trace 0000000000000000 ]--- [ 31.210894] ath11k_pci 0000:01:00.0: failed to init wow: -22 [ 31.215467] ath11k_pci 0000:01:00.0: failed register the radio with mac80211: -22 [ 31.221117] ath11k_pci 0000:01:00.0: failed to create pdev core: -22 Fix this by returning value "0" when FW doesn't support WoW to allow driver to proceed with initialize sequence and also remove the unnecessary "WARN_ON". Tested-on: QCN9074 hw1.0 PCI WLAN.HK.2.5.0.1-01100-QCAHKSWPL_SILICONZ-1 Fixes: ba9177fcef21 ("ath11k: Add basic WoW functionalities") Signed-off-by: Nagarajan Maran Signed-off-by: Kalle Valo Link: https://lore.kernel.org/r/20220331073110.3846-1-quic_nmaran@quicinc.com --- drivers/net/wireless/ath/ath11k/wow.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/net/wireless/ath/ath11k/wow.c b/drivers/net/wireless/ath/ath11k/wow.c index 93714df834b2c..6c2611f937396 100644 --- a/drivers/net/wireless/ath/ath11k/wow.c +++ b/drivers/net/wireless/ath/ath11k/wow.c @@ -810,8 +810,8 @@ int ath11k_wow_op_resume(struct ieee80211_hw *hw) int ath11k_wow_init(struct ath11k *ar) { - if (WARN_ON(!test_bit(WMI_TLV_SERVICE_WOW, ar->wmi->wmi_ab->svc_map))) - return -EINVAL; + if (!test_bit(WMI_TLV_SERVICE_WOW, ar->wmi->wmi_ab->svc_map)) + return 0; ar->wow.wowlan_support = ath11k_wowlan_support; From 4a5fb1bbcdf1cccae1f6b9c0277b3796b2a468ef Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A9r=C3=B4me=20Pouiller?= Date: Sat, 26 Feb 2022 10:21:42 +0100 Subject: [PATCH 046/228] wfx: get out from the staging area MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The wfx driver is now mature enough to leave the staging area. Signed-off-by: Jérôme Pouiller Signed-off-by: Kalle Valo --- .../{staging => }/net/wireless/silabs,wfx.yaml | 2 +- MAINTAINERS | 4 ++-- drivers/net/wireless/Kconfig | 1 + drivers/net/wireless/Makefile | 1 + drivers/net/wireless/silabs/Kconfig | 18 ++++++++++++++++++ drivers/net/wireless/silabs/Makefile | 3 +++ .../wireless/silabs}/wfx/Kconfig | 0 .../wireless/silabs}/wfx/Makefile | 0 .../{staging => net/wireless/silabs}/wfx/bh.c | 0 .../{staging => net/wireless/silabs}/wfx/bh.h | 0 .../{staging => net/wireless/silabs}/wfx/bus.h | 0 .../wireless/silabs}/wfx/bus_sdio.c | 0 .../wireless/silabs}/wfx/bus_spi.c | 0 .../wireless/silabs}/wfx/data_rx.c | 0 .../wireless/silabs}/wfx/data_rx.h | 0 .../wireless/silabs}/wfx/data_tx.c | 0 .../wireless/silabs}/wfx/data_tx.h | 0 .../wireless/silabs}/wfx/debug.c | 0 .../wireless/silabs}/wfx/debug.h | 0 .../wireless/silabs}/wfx/fwio.c | 0 .../wireless/silabs}/wfx/fwio.h | 0 .../wireless/silabs}/wfx/hif_api_cmd.h | 0 .../wireless/silabs}/wfx/hif_api_general.h | 0 .../wireless/silabs}/wfx/hif_api_mib.h | 0 .../wireless/silabs}/wfx/hif_rx.c | 0 .../wireless/silabs}/wfx/hif_rx.h | 0 .../wireless/silabs}/wfx/hif_tx.c | 0 .../wireless/silabs}/wfx/hif_tx.h | 0 .../wireless/silabs}/wfx/hif_tx_mib.c | 0 .../wireless/silabs}/wfx/hif_tx_mib.h | 0 .../wireless/silabs}/wfx/hwio.c | 0 .../wireless/silabs}/wfx/hwio.h | 0 .../{staging => net/wireless/silabs}/wfx/key.c | 0 .../{staging => net/wireless/silabs}/wfx/key.h | 0 .../wireless/silabs}/wfx/main.c | 0 .../wireless/silabs}/wfx/main.h | 0 .../wireless/silabs}/wfx/queue.c | 0 .../wireless/silabs}/wfx/queue.h | 0 .../wireless/silabs}/wfx/scan.c | 0 .../wireless/silabs}/wfx/scan.h | 0 .../{staging => net/wireless/silabs}/wfx/sta.c | 0 .../{staging => net/wireless/silabs}/wfx/sta.h | 0 .../wireless/silabs}/wfx/traces.h | 0 .../{staging => net/wireless/silabs}/wfx/wfx.h | 0 drivers/staging/Kconfig | 1 - drivers/staging/Makefile | 1 - drivers/staging/wfx/TODO | 6 ------ 47 files changed, 26 insertions(+), 11 deletions(-) rename Documentation/devicetree/bindings/{staging => }/net/wireless/silabs,wfx.yaml (98%) create mode 100644 drivers/net/wireless/silabs/Kconfig create mode 100644 drivers/net/wireless/silabs/Makefile rename drivers/{staging => net/wireless/silabs}/wfx/Kconfig (100%) rename drivers/{staging => net/wireless/silabs}/wfx/Makefile (100%) rename drivers/{staging => net/wireless/silabs}/wfx/bh.c (100%) rename drivers/{staging => net/wireless/silabs}/wfx/bh.h (100%) rename drivers/{staging => net/wireless/silabs}/wfx/bus.h (100%) rename drivers/{staging => net/wireless/silabs}/wfx/bus_sdio.c (100%) rename drivers/{staging => net/wireless/silabs}/wfx/bus_spi.c (100%) rename drivers/{staging => net/wireless/silabs}/wfx/data_rx.c (100%) rename drivers/{staging => net/wireless/silabs}/wfx/data_rx.h (100%) rename drivers/{staging => net/wireless/silabs}/wfx/data_tx.c (100%) rename drivers/{staging => net/wireless/silabs}/wfx/data_tx.h (100%) rename drivers/{staging => net/wireless/silabs}/wfx/debug.c (100%) rename drivers/{staging => net/wireless/silabs}/wfx/debug.h (100%) rename drivers/{staging => net/wireless/silabs}/wfx/fwio.c (100%) rename drivers/{staging => net/wireless/silabs}/wfx/fwio.h (100%) rename drivers/{staging => net/wireless/silabs}/wfx/hif_api_cmd.h (100%) rename drivers/{staging => net/wireless/silabs}/wfx/hif_api_general.h (100%) rename drivers/{staging => net/wireless/silabs}/wfx/hif_api_mib.h (100%) rename drivers/{staging => net/wireless/silabs}/wfx/hif_rx.c (100%) rename drivers/{staging => net/wireless/silabs}/wfx/hif_rx.h (100%) rename drivers/{staging => net/wireless/silabs}/wfx/hif_tx.c (100%) rename drivers/{staging => net/wireless/silabs}/wfx/hif_tx.h (100%) rename drivers/{staging => net/wireless/silabs}/wfx/hif_tx_mib.c (100%) rename drivers/{staging => net/wireless/silabs}/wfx/hif_tx_mib.h (100%) rename drivers/{staging => net/wireless/silabs}/wfx/hwio.c (100%) rename drivers/{staging => net/wireless/silabs}/wfx/hwio.h (100%) rename drivers/{staging => net/wireless/silabs}/wfx/key.c (100%) rename drivers/{staging => net/wireless/silabs}/wfx/key.h (100%) rename drivers/{staging => net/wireless/silabs}/wfx/main.c (100%) rename drivers/{staging => net/wireless/silabs}/wfx/main.h (100%) rename drivers/{staging => net/wireless/silabs}/wfx/queue.c (100%) rename drivers/{staging => net/wireless/silabs}/wfx/queue.h (100%) rename drivers/{staging => net/wireless/silabs}/wfx/scan.c (100%) rename drivers/{staging => net/wireless/silabs}/wfx/scan.h (100%) rename drivers/{staging => net/wireless/silabs}/wfx/sta.c (100%) rename drivers/{staging => net/wireless/silabs}/wfx/sta.h (100%) rename drivers/{staging => net/wireless/silabs}/wfx/traces.h (100%) rename drivers/{staging => net/wireless/silabs}/wfx/wfx.h (100%) delete mode 100644 drivers/staging/wfx/TODO diff --git a/Documentation/devicetree/bindings/staging/net/wireless/silabs,wfx.yaml b/Documentation/devicetree/bindings/net/wireless/silabs,wfx.yaml similarity index 98% rename from Documentation/devicetree/bindings/staging/net/wireless/silabs,wfx.yaml rename to Documentation/devicetree/bindings/net/wireless/silabs,wfx.yaml index 105725a127ab2..f5a531738d935 100644 --- a/Documentation/devicetree/bindings/staging/net/wireless/silabs,wfx.yaml +++ b/Documentation/devicetree/bindings/net/wireless/silabs,wfx.yaml @@ -3,7 +3,7 @@ %YAML 1.2 --- -$id: http://devicetree.org/schemas/staging/net/wireless/silabs,wfx.yaml# +$id: http://devicetree.org/schemas/net/wireless/silabs,wfx.yaml# $schema: http://devicetree.org/meta-schemas/core.yaml# title: Silicon Labs WFxxx devicetree bindings diff --git a/MAINTAINERS b/MAINTAINERS index fd768d43e0482..ba405f6ec31a9 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -17982,8 +17982,8 @@ F: drivers/platform/x86/touchscreen_dmi.c SILICON LABS WIRELESS DRIVERS (for WFxxx series) M: Jérôme Pouiller S: Supported -F: Documentation/devicetree/bindings/staging/net/wireless/silabs,wfx.yaml -F: drivers/staging/wfx/ +F: Documentation/devicetree/bindings/net/wireless/silabs,wfx.yaml +F: drivers/net/wireless/silabs/wfx/ SILICON MOTION SM712 FRAME BUFFER DRIVER M: Sudip Mukherjee diff --git a/drivers/net/wireless/Kconfig b/drivers/net/wireless/Kconfig index 7add2002ff4ce..e78ff7af6517a 100644 --- a/drivers/net/wireless/Kconfig +++ b/drivers/net/wireless/Kconfig @@ -31,6 +31,7 @@ source "drivers/net/wireless/microchip/Kconfig" source "drivers/net/wireless/ralink/Kconfig" source "drivers/net/wireless/realtek/Kconfig" source "drivers/net/wireless/rsi/Kconfig" +source "drivers/net/wireless/silabs/Kconfig" source "drivers/net/wireless/st/Kconfig" source "drivers/net/wireless/ti/Kconfig" source "drivers/net/wireless/zydas/Kconfig" diff --git a/drivers/net/wireless/Makefile b/drivers/net/wireless/Makefile index 80b3244997866..76885e5f0ea7a 100644 --- a/drivers/net/wireless/Makefile +++ b/drivers/net/wireless/Makefile @@ -16,6 +16,7 @@ obj-$(CONFIG_WLAN_VENDOR_MICROCHIP) += microchip/ obj-$(CONFIG_WLAN_VENDOR_RALINK) += ralink/ obj-$(CONFIG_WLAN_VENDOR_REALTEK) += realtek/ obj-$(CONFIG_WLAN_VENDOR_RSI) += rsi/ +obj-$(CONFIG_WLAN_VENDOR_SILABS) += silabs/ obj-$(CONFIG_WLAN_VENDOR_ST) += st/ obj-$(CONFIG_WLAN_VENDOR_TI) += ti/ obj-$(CONFIG_WLAN_VENDOR_ZYDAS) += zydas/ diff --git a/drivers/net/wireless/silabs/Kconfig b/drivers/net/wireless/silabs/Kconfig new file mode 100644 index 0000000000000..6262a799bf36d --- /dev/null +++ b/drivers/net/wireless/silabs/Kconfig @@ -0,0 +1,18 @@ +# SPDX-License-Identifier: GPL-2.0 + +config WLAN_VENDOR_SILABS + bool "Silicon Laboratories devices" + default y + help + If you have a wireless card belonging to this class, say Y. + + Note that the answer to this question doesn't directly affect the + kernel: saying N will just cause the configurator to skip all the + questions about these cards. If you say Y, you will be asked for + your specific card in the following questions. + +if WLAN_VENDOR_SILABS + +source "drivers/net/wireless/silabs/wfx/Kconfig" + +endif # WLAN_VENDOR_SILABS diff --git a/drivers/net/wireless/silabs/Makefile b/drivers/net/wireless/silabs/Makefile new file mode 100644 index 0000000000000..c2263ee210061 --- /dev/null +++ b/drivers/net/wireless/silabs/Makefile @@ -0,0 +1,3 @@ +# SPDX-License-Identifier: GPL-2.0 + +obj-$(CONFIG_WFX) += wfx/ diff --git a/drivers/staging/wfx/Kconfig b/drivers/net/wireless/silabs/wfx/Kconfig similarity index 100% rename from drivers/staging/wfx/Kconfig rename to drivers/net/wireless/silabs/wfx/Kconfig diff --git a/drivers/staging/wfx/Makefile b/drivers/net/wireless/silabs/wfx/Makefile similarity index 100% rename from drivers/staging/wfx/Makefile rename to drivers/net/wireless/silabs/wfx/Makefile diff --git a/drivers/staging/wfx/bh.c b/drivers/net/wireless/silabs/wfx/bh.c similarity index 100% rename from drivers/staging/wfx/bh.c rename to drivers/net/wireless/silabs/wfx/bh.c diff --git a/drivers/staging/wfx/bh.h b/drivers/net/wireless/silabs/wfx/bh.h similarity index 100% rename from drivers/staging/wfx/bh.h rename to drivers/net/wireless/silabs/wfx/bh.h diff --git a/drivers/staging/wfx/bus.h b/drivers/net/wireless/silabs/wfx/bus.h similarity index 100% rename from drivers/staging/wfx/bus.h rename to drivers/net/wireless/silabs/wfx/bus.h diff --git a/drivers/staging/wfx/bus_sdio.c b/drivers/net/wireless/silabs/wfx/bus_sdio.c similarity index 100% rename from drivers/staging/wfx/bus_sdio.c rename to drivers/net/wireless/silabs/wfx/bus_sdio.c diff --git a/drivers/staging/wfx/bus_spi.c b/drivers/net/wireless/silabs/wfx/bus_spi.c similarity index 100% rename from drivers/staging/wfx/bus_spi.c rename to drivers/net/wireless/silabs/wfx/bus_spi.c diff --git a/drivers/staging/wfx/data_rx.c b/drivers/net/wireless/silabs/wfx/data_rx.c similarity index 100% rename from drivers/staging/wfx/data_rx.c rename to drivers/net/wireless/silabs/wfx/data_rx.c diff --git a/drivers/staging/wfx/data_rx.h b/drivers/net/wireless/silabs/wfx/data_rx.h similarity index 100% rename from drivers/staging/wfx/data_rx.h rename to drivers/net/wireless/silabs/wfx/data_rx.h diff --git a/drivers/staging/wfx/data_tx.c b/drivers/net/wireless/silabs/wfx/data_tx.c similarity index 100% rename from drivers/staging/wfx/data_tx.c rename to drivers/net/wireless/silabs/wfx/data_tx.c diff --git a/drivers/staging/wfx/data_tx.h b/drivers/net/wireless/silabs/wfx/data_tx.h similarity index 100% rename from drivers/staging/wfx/data_tx.h rename to drivers/net/wireless/silabs/wfx/data_tx.h diff --git a/drivers/staging/wfx/debug.c b/drivers/net/wireless/silabs/wfx/debug.c similarity index 100% rename from drivers/staging/wfx/debug.c rename to drivers/net/wireless/silabs/wfx/debug.c diff --git a/drivers/staging/wfx/debug.h b/drivers/net/wireless/silabs/wfx/debug.h similarity index 100% rename from drivers/staging/wfx/debug.h rename to drivers/net/wireless/silabs/wfx/debug.h diff --git a/drivers/staging/wfx/fwio.c b/drivers/net/wireless/silabs/wfx/fwio.c similarity index 100% rename from drivers/staging/wfx/fwio.c rename to drivers/net/wireless/silabs/wfx/fwio.c diff --git a/drivers/staging/wfx/fwio.h b/drivers/net/wireless/silabs/wfx/fwio.h similarity index 100% rename from drivers/staging/wfx/fwio.h rename to drivers/net/wireless/silabs/wfx/fwio.h diff --git a/drivers/staging/wfx/hif_api_cmd.h b/drivers/net/wireless/silabs/wfx/hif_api_cmd.h similarity index 100% rename from drivers/staging/wfx/hif_api_cmd.h rename to drivers/net/wireless/silabs/wfx/hif_api_cmd.h diff --git a/drivers/staging/wfx/hif_api_general.h b/drivers/net/wireless/silabs/wfx/hif_api_general.h similarity index 100% rename from drivers/staging/wfx/hif_api_general.h rename to drivers/net/wireless/silabs/wfx/hif_api_general.h diff --git a/drivers/staging/wfx/hif_api_mib.h b/drivers/net/wireless/silabs/wfx/hif_api_mib.h similarity index 100% rename from drivers/staging/wfx/hif_api_mib.h rename to drivers/net/wireless/silabs/wfx/hif_api_mib.h diff --git a/drivers/staging/wfx/hif_rx.c b/drivers/net/wireless/silabs/wfx/hif_rx.c similarity index 100% rename from drivers/staging/wfx/hif_rx.c rename to drivers/net/wireless/silabs/wfx/hif_rx.c diff --git a/drivers/staging/wfx/hif_rx.h b/drivers/net/wireless/silabs/wfx/hif_rx.h similarity index 100% rename from drivers/staging/wfx/hif_rx.h rename to drivers/net/wireless/silabs/wfx/hif_rx.h diff --git a/drivers/staging/wfx/hif_tx.c b/drivers/net/wireless/silabs/wfx/hif_tx.c similarity index 100% rename from drivers/staging/wfx/hif_tx.c rename to drivers/net/wireless/silabs/wfx/hif_tx.c diff --git a/drivers/staging/wfx/hif_tx.h b/drivers/net/wireless/silabs/wfx/hif_tx.h similarity index 100% rename from drivers/staging/wfx/hif_tx.h rename to drivers/net/wireless/silabs/wfx/hif_tx.h diff --git a/drivers/staging/wfx/hif_tx_mib.c b/drivers/net/wireless/silabs/wfx/hif_tx_mib.c similarity index 100% rename from drivers/staging/wfx/hif_tx_mib.c rename to drivers/net/wireless/silabs/wfx/hif_tx_mib.c diff --git a/drivers/staging/wfx/hif_tx_mib.h b/drivers/net/wireless/silabs/wfx/hif_tx_mib.h similarity index 100% rename from drivers/staging/wfx/hif_tx_mib.h rename to drivers/net/wireless/silabs/wfx/hif_tx_mib.h diff --git a/drivers/staging/wfx/hwio.c b/drivers/net/wireless/silabs/wfx/hwio.c similarity index 100% rename from drivers/staging/wfx/hwio.c rename to drivers/net/wireless/silabs/wfx/hwio.c diff --git a/drivers/staging/wfx/hwio.h b/drivers/net/wireless/silabs/wfx/hwio.h similarity index 100% rename from drivers/staging/wfx/hwio.h rename to drivers/net/wireless/silabs/wfx/hwio.h diff --git a/drivers/staging/wfx/key.c b/drivers/net/wireless/silabs/wfx/key.c similarity index 100% rename from drivers/staging/wfx/key.c rename to drivers/net/wireless/silabs/wfx/key.c diff --git a/drivers/staging/wfx/key.h b/drivers/net/wireless/silabs/wfx/key.h similarity index 100% rename from drivers/staging/wfx/key.h rename to drivers/net/wireless/silabs/wfx/key.h diff --git a/drivers/staging/wfx/main.c b/drivers/net/wireless/silabs/wfx/main.c similarity index 100% rename from drivers/staging/wfx/main.c rename to drivers/net/wireless/silabs/wfx/main.c diff --git a/drivers/staging/wfx/main.h b/drivers/net/wireless/silabs/wfx/main.h similarity index 100% rename from drivers/staging/wfx/main.h rename to drivers/net/wireless/silabs/wfx/main.h diff --git a/drivers/staging/wfx/queue.c b/drivers/net/wireless/silabs/wfx/queue.c similarity index 100% rename from drivers/staging/wfx/queue.c rename to drivers/net/wireless/silabs/wfx/queue.c diff --git a/drivers/staging/wfx/queue.h b/drivers/net/wireless/silabs/wfx/queue.h similarity index 100% rename from drivers/staging/wfx/queue.h rename to drivers/net/wireless/silabs/wfx/queue.h diff --git a/drivers/staging/wfx/scan.c b/drivers/net/wireless/silabs/wfx/scan.c similarity index 100% rename from drivers/staging/wfx/scan.c rename to drivers/net/wireless/silabs/wfx/scan.c diff --git a/drivers/staging/wfx/scan.h b/drivers/net/wireless/silabs/wfx/scan.h similarity index 100% rename from drivers/staging/wfx/scan.h rename to drivers/net/wireless/silabs/wfx/scan.h diff --git a/drivers/staging/wfx/sta.c b/drivers/net/wireless/silabs/wfx/sta.c similarity index 100% rename from drivers/staging/wfx/sta.c rename to drivers/net/wireless/silabs/wfx/sta.c diff --git a/drivers/staging/wfx/sta.h b/drivers/net/wireless/silabs/wfx/sta.h similarity index 100% rename from drivers/staging/wfx/sta.h rename to drivers/net/wireless/silabs/wfx/sta.h diff --git a/drivers/staging/wfx/traces.h b/drivers/net/wireless/silabs/wfx/traces.h similarity index 100% rename from drivers/staging/wfx/traces.h rename to drivers/net/wireless/silabs/wfx/traces.h diff --git a/drivers/staging/wfx/wfx.h b/drivers/net/wireless/silabs/wfx/wfx.h similarity index 100% rename from drivers/staging/wfx/wfx.h rename to drivers/net/wireless/silabs/wfx/wfx.h diff --git a/drivers/staging/Kconfig b/drivers/staging/Kconfig index 932acb4e8cbc0..fc274737053dc 100644 --- a/drivers/staging/Kconfig +++ b/drivers/staging/Kconfig @@ -86,6 +86,5 @@ source "drivers/staging/fieldbus/Kconfig" source "drivers/staging/qlge/Kconfig" -source "drivers/staging/wfx/Kconfig" endif # STAGING diff --git a/drivers/staging/Makefile b/drivers/staging/Makefile index 3ffb35ccfae22..65e317922e3f1 100644 --- a/drivers/staging/Makefile +++ b/drivers/staging/Makefile @@ -33,4 +33,3 @@ obj-$(CONFIG_PI433) += pi433/ obj-$(CONFIG_XIL_AXIS_FIFO) += axis-fifo/ obj-$(CONFIG_FIELDBUS_DEV) += fieldbus/ obj-$(CONFIG_QLGE) += qlge/ -obj-$(CONFIG_WFX) += wfx/ diff --git a/drivers/staging/wfx/TODO b/drivers/staging/wfx/TODO deleted file mode 100644 index 1b4bc2af94b6d..0000000000000 --- a/drivers/staging/wfx/TODO +++ /dev/null @@ -1,6 +0,0 @@ -This is a list of things that need to be done to get this driver out of the -staging directory. - - - As suggested by Felix, rate control could be improved following this idea: - https://lore.kernel.org/lkml/3099559.gv3Q75KnN1@pc-42/ - From 34e63cd5ba29fb832f3fe31e37cea28027979c1d Mon Sep 17 00:00:00 2001 From: "Gustavo A. R. Silva" Date: Wed, 16 Feb 2022 13:50:15 -0600 Subject: [PATCH 047/228] iwlwifi: fw: Replace zero-length arrays with flexible-array members MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit There is a regular need in the kernel to provide a way to declare having a dynamically sized set of trailing elements in a structure. Kernel code should always use “flexible array members”[1] for these cases. The older style of one-element or zero-length arrays should no longer be used[2]. [1] https://en.wikipedia.org/wiki/Flexible_array_member [2] https://www.kernel.org/doc/html/v5.16/process/deprecated.html#zero-length-and-one-element-arrays Link: https://github.com/KSPP/linux/issues/78 Signed-off-by: Gustavo A. R. Silva Reviewed-by: Kees Cook Acked-by: Luca Coelho Signed-off-by: Kalle Valo Link: https://lore.kernel.org/r/20220216195015.GA904148@embeddedor --- drivers/net/wireless/intel/iwlwifi/fw/api/dbg-tlv.h | 4 ++-- drivers/net/wireless/intel/iwlwifi/fw/api/debug.h | 4 ++-- drivers/net/wireless/intel/iwlwifi/fw/api/filter.h | 2 +- drivers/net/wireless/intel/iwlwifi/fw/api/scan.h | 4 ++-- drivers/net/wireless/intel/iwlwifi/fw/api/sta.h | 2 +- drivers/net/wireless/intel/iwlwifi/fw/api/tdls.h | 2 +- drivers/net/wireless/intel/iwlwifi/fw/error-dump.h | 2 +- drivers/net/wireless/intel/iwlwifi/fw/file.h | 10 +++++----- 8 files changed, 15 insertions(+), 15 deletions(-) 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 52bf96585fc6c..ba538d70985f4 100644 --- a/drivers/net/wireless/intel/iwlwifi/fw/api/dbg-tlv.h +++ b/drivers/net/wireless/intel/iwlwifi/fw/api/dbg-tlv.h @@ -26,7 +26,7 @@ struct iwl_fw_ini_hcmd { u8 id; u8 group; __le16 reserved; - u8 data[0]; + u8 data[]; } __packed; /* FW_DEBUG_TLV_HCMD_DATA_API_S_VER_1 */ /** @@ -275,7 +275,7 @@ struct iwl_fw_ini_conf_set_tlv { __le32 time_point; __le32 set_type; __le32 addr_offset; - struct iwl_fw_ini_addr_val addr_val[0]; + struct iwl_fw_ini_addr_val addr_val[]; } __packed; /* FW_TLV_DEBUG_CONFIG_SET_API_S_VER_1 */ /** diff --git a/drivers/net/wireless/intel/iwlwifi/fw/api/debug.h b/drivers/net/wireless/intel/iwlwifi/fw/api/debug.h index 6255257ddebe3..0c555089e05fc 100644 --- a/drivers/net/wireless/intel/iwlwifi/fw/api/debug.h +++ b/drivers/net/wireless/intel/iwlwifi/fw/api/debug.h @@ -240,7 +240,7 @@ struct iwl_mfu_assert_dump_notif { __le16 index_num; __le16 parts_num; __le32 data_size; - __le32 data[0]; + __le32 data[]; } __packed; /* MFU_DUMP_ASSERT_API_S_VER_1 */ /** @@ -276,7 +276,7 @@ struct iwl_mvm_marker { u8 marker_id; __le16 reserved; __le64 timestamp; - __le32 metadata[0]; + __le32 metadata[]; } __packed; /* MARKER_API_S_VER_1 */ /** diff --git a/drivers/net/wireless/intel/iwlwifi/fw/api/filter.h b/drivers/net/wireless/intel/iwlwifi/fw/api/filter.h index e44c70b7c7907..88fe61d144d42 100644 --- a/drivers/net/wireless/intel/iwlwifi/fw/api/filter.h +++ b/drivers/net/wireless/intel/iwlwifi/fw/api/filter.h @@ -33,7 +33,7 @@ struct iwl_mcast_filter_cmd { u8 pass_all; u8 bssid[6]; u8 reserved[2]; - u8 addr_list[0]; + u8 addr_list[]; } __packed; /* MCAST_FILTERING_CMD_API_S_VER_1 */ #endif /* __iwl_fw_api_filter_h__ */ diff --git a/drivers/net/wireless/intel/iwlwifi/fw/api/scan.h b/drivers/net/wireless/intel/iwlwifi/fw/api/scan.h index 5413087ae909d..5543d9cb74c81 100644 --- a/drivers/net/wireless/intel/iwlwifi/fw/api/scan.h +++ b/drivers/net/wireless/intel/iwlwifi/fw/api/scan.h @@ -1165,7 +1165,7 @@ struct iwl_scan_offload_profiles_query_v1 { u8 resume_while_scanning; u8 self_recovery; __le16 reserved; - struct iwl_scan_offload_profile_match_v1 matches[0]; + struct iwl_scan_offload_profile_match_v1 matches[]; } __packed; /* SCAN_OFFLOAD_PROFILES_QUERY_RSP_S_VER_2 */ /** @@ -1209,7 +1209,7 @@ struct iwl_scan_offload_profiles_query { u8 resume_while_scanning; u8 self_recovery; __le16 reserved; - struct iwl_scan_offload_profile_match matches[0]; + struct iwl_scan_offload_profile_match matches[]; } __packed; /* SCAN_OFFLOAD_PROFILES_QUERY_RSP_S_VER_3 */ /** diff --git a/drivers/net/wireless/intel/iwlwifi/fw/api/sta.h b/drivers/net/wireless/intel/iwlwifi/fw/api/sta.h index 5edbe27c09227..d62fed5432768 100644 --- a/drivers/net/wireless/intel/iwlwifi/fw/api/sta.h +++ b/drivers/net/wireless/intel/iwlwifi/fw/api/sta.h @@ -477,7 +477,7 @@ struct iwl_mvm_wep_key_cmd { u8 decryption_type; u8 flags; u8 reserved; - struct iwl_mvm_wep_key wep_key[0]; + struct iwl_mvm_wep_key wep_key[]; } __packed; /* SEC_CURR_WEP_KEY_CMD_API_S_VER_2 */ /** diff --git a/drivers/net/wireless/intel/iwlwifi/fw/api/tdls.h b/drivers/net/wireless/intel/iwlwifi/fw/api/tdls.h index 14d35000abed2..893438aadab00 100644 --- a/drivers/net/wireless/intel/iwlwifi/fw/api/tdls.h +++ b/drivers/net/wireless/intel/iwlwifi/fw/api/tdls.h @@ -132,7 +132,7 @@ struct iwl_tdls_config_cmd { __le32 pti_req_data_offset; struct iwl_tx_cmd pti_req_tx_cmd; - u8 pti_req_template[0]; + u8 pti_req_template[]; } __packed; /* TDLS_CONFIG_CMD_API_S_VER_1 */ /** diff --git a/drivers/net/wireless/intel/iwlwifi/fw/error-dump.h b/drivers/net/wireless/intel/iwlwifi/fw/error-dump.h index 079fa0023bd8e..c62576e442bdf 100644 --- a/drivers/net/wireless/intel/iwlwifi/fw/error-dump.h +++ b/drivers/net/wireless/intel/iwlwifi/fw/error-dump.h @@ -84,7 +84,7 @@ struct iwl_fw_error_dump_data { struct iwl_fw_error_dump_file { __le32 barker; __le32 file_len; - u8 data[0]; + u8 data[]; } __packed; /** diff --git a/drivers/net/wireless/intel/iwlwifi/fw/file.h b/drivers/net/wireless/intel/iwlwifi/fw/file.h index 5679a78758be3..a7817d9520223 100644 --- a/drivers/net/wireless/intel/iwlwifi/fw/file.h +++ b/drivers/net/wireless/intel/iwlwifi/fw/file.h @@ -145,7 +145,7 @@ struct iwl_tlv_ucode_header { * Note that each TLV is padded to a length * that is a multiple of 4 for alignment. */ - u8 data[0]; + u8 data[]; }; /* @@ -603,7 +603,7 @@ struct iwl_fw_dbg_dest_tlv_v1 { __le32 wrap_count; u8 base_shift; u8 end_shift; - struct iwl_fw_dbg_reg_op reg_ops[0]; + struct iwl_fw_dbg_reg_op reg_ops[]; } __packed; /* Mask of the register for defining the LDBG MAC2SMEM buffer SMEM size */ @@ -623,14 +623,14 @@ struct iwl_fw_dbg_dest_tlv { __le32 wrap_count; u8 base_shift; u8 size_shift; - struct iwl_fw_dbg_reg_op reg_ops[0]; + struct iwl_fw_dbg_reg_op reg_ops[]; } __packed; struct iwl_fw_dbg_conf_hcmd { u8 id; u8 reserved; __le16 len; - u8 data[0]; + u8 data[]; } __packed; /** @@ -705,7 +705,7 @@ struct iwl_fw_dbg_trigger_tlv { u8 flags; u8 reserved[5]; - u8 data[0]; + u8 data[]; } __packed; #define FW_DBG_START_FROM_ALIVE 0 From c5f675748cf0e1db5ba5514e1f34360dfb95a6ba Mon Sep 17 00:00:00 2001 From: "Gustavo A. R. Silva" Date: Wed, 16 Feb 2022 13:50:30 -0600 Subject: [PATCH 048/228] iwlwifi: mei: Replace zero-length array with flexible-array member MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit There is a regular need in the kernel to provide a way to declare having a dynamically sized set of trailing elements in a structure. Kernel code should always use “flexible array members”[1] for these cases. The older style of one-element or zero-length arrays should no longer be used[2]. [1] https://en.wikipedia.org/wiki/Flexible_array_member [2] https://www.kernel.org/doc/html/v5.16/process/deprecated.html#zero-length-and-one-element-arrays Link: https://github.com/KSPP/linux/issues/78 Signed-off-by: Gustavo A. R. Silva Reviewed-by: Kees Cook Acked-by: Luca Coelho Signed-off-by: Kalle Valo Link: https://lore.kernel.org/r/20220216195030.GA904170@embeddedor --- drivers/net/wireless/intel/iwlwifi/mei/sap.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/net/wireless/intel/iwlwifi/mei/sap.h b/drivers/net/wireless/intel/iwlwifi/mei/sap.h index 11e3009121ccf..be1456dea4848 100644 --- a/drivers/net/wireless/intel/iwlwifi/mei/sap.h +++ b/drivers/net/wireless/intel/iwlwifi/mei/sap.h @@ -298,7 +298,7 @@ struct iwl_sap_hdr { __le16 type; __le16 len; __le32 seq_num; - u8 payload[0]; + u8 payload[]; }; /** From 29ed2d7606bb674c9ee38f59ca5b155aaea72df3 Mon Sep 17 00:00:00 2001 From: Po-Hao Huang Date: Fri, 18 Mar 2022 11:43:16 +0800 Subject: [PATCH 049/228] rtw88: change idle mode condition during hw_scan Previously we only consider single interface's status, idle mode behavior could be unexpected when multiple interfaces is active. Change to enter/leave idle mode by mac80211's configuration state. Signed-off-by: Po-Hao Huang Signed-off-by: Ping-Ke Shih Signed-off-by: Kalle Valo Link: https://lore.kernel.org/r/20220318034316.40720-1-pkshih@realtek.com --- drivers/net/wireless/realtek/rtw88/main.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/drivers/net/wireless/realtek/rtw88/main.c b/drivers/net/wireless/realtek/rtw88/main.c index 8b9899e41b0bb..b57f9262f5909 100644 --- a/drivers/net/wireless/realtek/rtw88/main.c +++ b/drivers/net/wireless/realtek/rtw88/main.c @@ -280,7 +280,8 @@ static void rtw_ips_work(struct work_struct *work) struct rtw_dev *rtwdev = container_of(work, struct rtw_dev, ips_work); mutex_lock(&rtwdev->mutex); - rtw_enter_ips(rtwdev); + if (rtwdev->hw->conf.flags & IEEE80211_CONF_IDLE) + rtw_enter_ips(rtwdev); mutex_unlock(&rtwdev->mutex); } @@ -1353,7 +1354,7 @@ void rtw_core_scan_start(struct rtw_dev *rtwdev, struct rtw_vif *rtwvif, rtw_leave_lps(rtwdev); - if (hw_scan && rtwvif->net_type == RTW_NET_NO_LINK) { + if (hw_scan && (rtwdev->hw->conf.flags & IEEE80211_CONF_IDLE)) { ret = rtw_leave_ips(rtwdev); if (ret) { rtw_err(rtwdev, "failed to leave idle state\n"); @@ -1389,7 +1390,7 @@ void rtw_core_scan_complete(struct rtw_dev *rtwdev, struct ieee80211_vif *vif, rtw_coex_scan_notify(rtwdev, COEX_SCAN_FINISH); - if (rtwvif->net_type == RTW_NET_NO_LINK && hw_scan) + if (hw_scan && (rtwdev->hw->conf.flags & IEEE80211_CONF_IDLE)) ieee80211_queue_work(rtwdev->hw, &rtwdev->ips_work); } From b169f877f001a474fb89939842c390518160bcc5 Mon Sep 17 00:00:00 2001 From: Zong-Zhe Yang Date: Mon, 14 Mar 2022 15:12:43 +0800 Subject: [PATCH 050/228] rtw89: ser: fix CAM leaks occurring in L2 reset The CAM, meaning address CAM and bssid CAM here, will get leaks during SER (system error recover) L2 reset process and ieee80211_restart_hw() which is called by L2 reset process eventually. The normal flow would be like -> add interface (acquire 1) -> enter ips (release 1) -> leave ips (acquire 1) -> connection (occupy 1) <(A) 1 leak after L2 reset if non-sec connection> The ieee80211_restart_hw() flow (under connection) -> ieee80211 reconfig -> add interface (acquire 1) -> leave ips (acquire 1) -> connection (occupy (A) + 2) <(B) 1 more leak> Originally, CAM is released before HW restart only if connection is under security. Now, release CAM whatever connection it is to fix leak in (A). OTOH, check if CAM is already valid to avoid acquiring multiple times to fix (B). Besides, if AP mode, release address CAM of all stations before HW restart. Signed-off-by: Zong-Zhe Yang Signed-off-by: Ping-Ke Shih Signed-off-by: Kalle Valo Link: https://lore.kernel.org/r/20220314071250.40292-2-pkshih@realtek.com --- drivers/net/wireless/realtek/rtw89/cam.c | 14 ++++++++++++-- drivers/net/wireless/realtek/rtw89/ser.c | 21 +++++++++++++++++++++ 2 files changed, 33 insertions(+), 2 deletions(-) diff --git a/drivers/net/wireless/realtek/rtw89/cam.c b/drivers/net/wireless/realtek/rtw89/cam.c index 305dbbebff6bb..26bef9fdd2053 100644 --- a/drivers/net/wireless/realtek/rtw89/cam.c +++ b/drivers/net/wireless/realtek/rtw89/cam.c @@ -421,10 +421,8 @@ static void rtw89_cam_reset_key_iter(struct ieee80211_hw *hw, void *data) { struct rtw89_dev *rtwdev = (struct rtw89_dev *)data; - struct rtw89_vif *rtwvif = (struct rtw89_vif *)vif->drv_priv; rtw89_cam_sec_key_del(rtwdev, vif, sta, key, false); - rtw89_cam_deinit(rtwdev, rtwvif); } void rtw89_cam_deinit_addr_cam(struct rtw89_dev *rtwdev, @@ -480,6 +478,12 @@ int rtw89_cam_init_addr_cam(struct rtw89_dev *rtwdev, int i; int ret; + if (unlikely(addr_cam->valid)) { + rtw89_debug(rtwdev, RTW89_DBG_FW, + "addr cam is already valid; skip init\n"); + return 0; + } + ret = rtw89_cam_get_avail_addr_cam(rtwdev, &addr_cam_idx); if (ret) { rtw89_err(rtwdev, "failed to get available addr cam\n"); @@ -531,6 +535,12 @@ static int rtw89_cam_init_bssid_cam(struct rtw89_dev *rtwdev, u8 bssid_cam_idx; int ret; + if (unlikely(bssid_cam->valid)) { + rtw89_debug(rtwdev, RTW89_DBG_FW, + "bssid cam is already valid; skip init\n"); + return 0; + } + ret = rtw89_cam_get_avail_bssid_cam(rtwdev, &bssid_cam_idx); if (ret) { rtw89_err(rtwdev, "failed to get available bssid cam\n"); diff --git a/drivers/net/wireless/realtek/rtw89/ser.c b/drivers/net/wireless/realtek/rtw89/ser.c index 837cdc366a61a..e86f3d89ef1bf 100644 --- a/drivers/net/wireless/realtek/rtw89/ser.c +++ b/drivers/net/wireless/realtek/rtw89/ser.c @@ -220,11 +220,32 @@ static void ser_reset_vif(struct rtw89_dev *rtwdev, struct rtw89_vif *rtwvif) rtwvif->trigger = false; } +static void ser_sta_deinit_addr_cam_iter(void *data, struct ieee80211_sta *sta) +{ + struct rtw89_dev *rtwdev = (struct rtw89_dev *)data; + struct rtw89_sta *rtwsta = (struct rtw89_sta *)sta->drv_priv; + + rtw89_cam_deinit_addr_cam(rtwdev, &rtwsta->addr_cam); +} + +static void ser_deinit_cam(struct rtw89_dev *rtwdev, struct rtw89_vif *rtwvif) +{ + if (rtwvif->net_type == RTW89_NET_TYPE_AP_MODE) + ieee80211_iterate_stations_atomic(rtwdev->hw, + ser_sta_deinit_addr_cam_iter, + rtwdev); + + rtw89_cam_deinit(rtwdev, rtwvif); +} + static void ser_reset_mac_binding(struct rtw89_dev *rtwdev) { struct rtw89_vif *rtwvif; rtw89_cam_reset_keys(rtwdev); + rtw89_for_each_rtwvif(rtwdev, rtwvif) + ser_deinit_cam(rtwdev, rtwvif); + rtw89_core_release_all_bits_map(rtwdev->mac_id_map, RTW89_MAX_MAC_ID_NUM); rtw89_for_each_rtwvif(rtwdev, rtwvif) ser_reset_vif(rtwdev, rtwvif); From e1400b115cace4528dbe0f2b72103241d0d11892 Mon Sep 17 00:00:00 2001 From: Zong-Zhe Yang Date: Mon, 14 Mar 2022 15:12:44 +0800 Subject: [PATCH 051/228] rtw89: mac: move table of mem base addr to common Previously, mac_mem_base_addr_table was declared in debug.c locally because it's only used via debugfs to dump mac memory. Now, we plan to refine SER (system error recover) flow which will also need to dump mac memory to somewhere as information for error which is catched. So, we move mac_mem_base_addr_table to mac.c rtw89_mac_mem_base_addrs earlier as common code. (no logic is changed) Signed-off-by: Zong-Zhe Yang Signed-off-by: Ping-Ke Shih Signed-off-by: Kalle Valo Link: https://lore.kernel.org/r/20220314071250.40292-3-pkshih@realtek.com --- drivers/net/wireless/realtek/rtw89/debug.c | 22 +--------------------- drivers/net/wireless/realtek/rtw89/mac.c | 20 ++++++++++++++++++++ drivers/net/wireless/realtek/rtw89/mac.h | 2 ++ 3 files changed, 23 insertions(+), 21 deletions(-) diff --git a/drivers/net/wireless/realtek/rtw89/debug.c b/drivers/net/wireless/realtek/rtw89/debug.c index b73cc03cecfd7..09c545497ec5c 100644 --- a/drivers/net/wireless/realtek/rtw89/debug.c +++ b/drivers/net/wireless/realtek/rtw89/debug.c @@ -724,26 +724,6 @@ rtw89_debug_priv_mac_mem_dump_select(struct file *filp, return count; } -static const u32 mac_mem_base_addr_table[RTW89_MAC_MEM_MAX] = { - [RTW89_MAC_MEM_AXIDMA] = AXIDMA_BASE_ADDR, - [RTW89_MAC_MEM_SHARED_BUF] = SHARED_BUF_BASE_ADDR, - [RTW89_MAC_MEM_DMAC_TBL] = DMAC_TBL_BASE_ADDR, - [RTW89_MAC_MEM_SHCUT_MACHDR] = SHCUT_MACHDR_BASE_ADDR, - [RTW89_MAC_MEM_STA_SCHED] = STA_SCHED_BASE_ADDR, - [RTW89_MAC_MEM_RXPLD_FLTR_CAM] = RXPLD_FLTR_CAM_BASE_ADDR, - [RTW89_MAC_MEM_SECURITY_CAM] = SECURITY_CAM_BASE_ADDR, - [RTW89_MAC_MEM_WOW_CAM] = WOW_CAM_BASE_ADDR, - [RTW89_MAC_MEM_CMAC_TBL] = CMAC_TBL_BASE_ADDR, - [RTW89_MAC_MEM_ADDR_CAM] = ADDR_CAM_BASE_ADDR, - [RTW89_MAC_MEM_BA_CAM] = BA_CAM_BASE_ADDR, - [RTW89_MAC_MEM_BCN_IE_CAM0] = BCN_IE_CAM0_BASE_ADDR, - [RTW89_MAC_MEM_BCN_IE_CAM1] = BCN_IE_CAM1_BASE_ADDR, - [RTW89_MAC_MEM_TXD_FIFO_0] = TXD_FIFO_0_BASE_ADDR, - [RTW89_MAC_MEM_TXD_FIFO_1] = TXD_FIFO_1_BASE_ADDR, - [RTW89_MAC_MEM_TXDATA_FIFO_0] = TXDATA_FIFO_0_BASE_ADDR, - [RTW89_MAC_MEM_TXDATA_FIFO_1] = TXDATA_FIFO_1_BASE_ADDR, -}; - static void rtw89_debug_dump_mac_mem(struct seq_file *m, struct rtw89_dev *rtwdev, u8 sel, u32 start_addr, u32 len) @@ -757,7 +737,7 @@ static void rtw89_debug_dump_mac_mem(struct seq_file *m, pages = len / MAC_MEM_DUMP_PAGE_SIZE + 1; start_page = start_addr / MAC_MEM_DUMP_PAGE_SIZE; residue = start_addr % MAC_MEM_DUMP_PAGE_SIZE; - base_addr = mac_mem_base_addr_table[sel]; + base_addr = rtw89_mac_mem_base_addrs[sel]; base_addr += start_page * MAC_MEM_DUMP_PAGE_SIZE; for (p = 0; p < pages; p++) { diff --git a/drivers/net/wireless/realtek/rtw89/mac.c b/drivers/net/wireless/realtek/rtw89/mac.c index 5e554bd9f0368..580757bb52cf7 100644 --- a/drivers/net/wireless/realtek/rtw89/mac.c +++ b/drivers/net/wireless/realtek/rtw89/mac.c @@ -10,6 +10,26 @@ #include "reg.h" #include "util.h" +const u32 rtw89_mac_mem_base_addrs[RTW89_MAC_MEM_MAX] = { + [RTW89_MAC_MEM_AXIDMA] = AXIDMA_BASE_ADDR, + [RTW89_MAC_MEM_SHARED_BUF] = SHARED_BUF_BASE_ADDR, + [RTW89_MAC_MEM_DMAC_TBL] = DMAC_TBL_BASE_ADDR, + [RTW89_MAC_MEM_SHCUT_MACHDR] = SHCUT_MACHDR_BASE_ADDR, + [RTW89_MAC_MEM_STA_SCHED] = STA_SCHED_BASE_ADDR, + [RTW89_MAC_MEM_RXPLD_FLTR_CAM] = RXPLD_FLTR_CAM_BASE_ADDR, + [RTW89_MAC_MEM_SECURITY_CAM] = SECURITY_CAM_BASE_ADDR, + [RTW89_MAC_MEM_WOW_CAM] = WOW_CAM_BASE_ADDR, + [RTW89_MAC_MEM_CMAC_TBL] = CMAC_TBL_BASE_ADDR, + [RTW89_MAC_MEM_ADDR_CAM] = ADDR_CAM_BASE_ADDR, + [RTW89_MAC_MEM_BA_CAM] = BA_CAM_BASE_ADDR, + [RTW89_MAC_MEM_BCN_IE_CAM0] = BCN_IE_CAM0_BASE_ADDR, + [RTW89_MAC_MEM_BCN_IE_CAM1] = BCN_IE_CAM1_BASE_ADDR, + [RTW89_MAC_MEM_TXD_FIFO_0] = TXD_FIFO_0_BASE_ADDR, + [RTW89_MAC_MEM_TXD_FIFO_1] = TXD_FIFO_1_BASE_ADDR, + [RTW89_MAC_MEM_TXDATA_FIFO_0] = TXDATA_FIFO_0_BASE_ADDR, + [RTW89_MAC_MEM_TXDATA_FIFO_1] = TXDATA_FIFO_1_BASE_ADDR, +}; + int rtw89_mac_check_mac_en(struct rtw89_dev *rtwdev, u8 mac_idx, enum rtw89_mac_hwmod_sel sel) { diff --git a/drivers/net/wireless/realtek/rtw89/mac.h b/drivers/net/wireless/realtek/rtw89/mac.h index b797667c78c6f..fdc5ded23fde3 100644 --- a/drivers/net/wireless/realtek/rtw89/mac.h +++ b/drivers/net/wireless/realtek/rtw89/mac.h @@ -273,6 +273,8 @@ enum rtw89_mac_mem_sel { RTW89_MAC_MEM_INVALID = RTW89_MAC_MEM_LAST, }; +extern const u32 rtw89_mac_mem_base_addrs[]; + enum rtw89_rpwm_req_pwr_state { RTW89_MAC_RPWM_REQ_PWR_STATE_ACTIVE = 0, RTW89_MAC_RPWM_REQ_PWR_STATE_BAND0_RFON = 1, From 198b6cf70146ca6b575efe35c123e4951f9724f1 Mon Sep 17 00:00:00 2001 From: Zong-Zhe Yang Date: Mon, 14 Mar 2022 15:12:45 +0800 Subject: [PATCH 052/228] rtw89: mac: correct decision on error status by scenario The raw error code might combine error scenario and error status. But, the error scenario isn't parsed previously. It makes us mishandle cpu exception and assertion. Now, we correct the error status for them. Besides, a few uses of error status are refined. Signed-off-by: Zong-Zhe Yang Signed-off-by: Ping-Ke Shih Signed-off-by: Kalle Valo Link: https://lore.kernel.org/r/20220314071250.40292-4-pkshih@realtek.com --- drivers/net/wireless/realtek/rtw89/mac.c | 12 ++++++++++-- drivers/net/wireless/realtek/rtw89/mac.h | 8 ++++++++ drivers/net/wireless/realtek/rtw89/ser.c | 6 ++++-- 3 files changed, 22 insertions(+), 4 deletions(-) diff --git a/drivers/net/wireless/realtek/rtw89/mac.c b/drivers/net/wireless/realtek/rtw89/mac.c index 580757bb52cf7..87adaa08fdb93 100644 --- a/drivers/net/wireless/realtek/rtw89/mac.c +++ b/drivers/net/wireless/realtek/rtw89/mac.c @@ -257,7 +257,9 @@ static void rtw89_mac_dump_err_status(struct rtw89_dev *rtwdev, u32 dmac_err, cmac_err; if (err != MAC_AX_ERR_L1_ERR_DMAC && - err != MAC_AX_ERR_L0_PROMOTE_TO_L1) + err != MAC_AX_ERR_L0_PROMOTE_TO_L1 && + err != MAC_AX_ERR_L0_ERR_CMAC0 && + err != MAC_AX_ERR_L0_ERR_CMAC1) return; rtw89_info(rtwdev, "--->\nerr=0x%x\n", err); @@ -458,7 +460,7 @@ static void rtw89_mac_dump_err_status(struct rtw89_dev *rtwdev, u32 rtw89_mac_get_err_status(struct rtw89_dev *rtwdev) { - u32 err; + u32 err, err_scnr; int ret; ret = read_poll_timeout(rtw89_read32, err, (err != 0), 1000, 100000, @@ -471,6 +473,12 @@ u32 rtw89_mac_get_err_status(struct rtw89_dev *rtwdev) err = rtw89_read32(rtwdev, R_AX_HALT_C2H); rtw89_write32(rtwdev, R_AX_HALT_C2H_CTRL, 0); + err_scnr = RTW89_ERROR_SCENARIO(err); + if (err_scnr == RTW89_WCPU_CPU_EXCEPTION) + err = MAC_AX_ERR_CPU_EXCEPTION; + else if (err_scnr == RTW89_WCPU_ASSERTION) + err = MAC_AX_ERR_ASSERTION; + rtw89_fw_st_dbg_dump(rtwdev); rtw89_mac_dump_err_status(rtwdev, err); diff --git a/drivers/net/wireless/realtek/rtw89/mac.h b/drivers/net/wireless/realtek/rtw89/mac.h index fdc5ded23fde3..a05c504505d82 100644 --- a/drivers/net/wireless/realtek/rtw89/mac.h +++ b/drivers/net/wireless/realtek/rtw89/mac.h @@ -521,6 +521,13 @@ struct rtw89_mac_dle_dfi_qempty { u32 qempty; }; +enum rtw89_mac_error_scenario { + RTW89_WCPU_CPU_EXCEPTION = 2, + RTW89_WCPU_ASSERTION = 3, +}; + +#define RTW89_ERROR_SCENARIO(__err) ((__err) >> 28) + /* Define DBG and recovery enum */ enum mac_ax_err_info { /* Get error info */ @@ -659,6 +666,7 @@ enum mac_ax_err_info { MAC_AX_ERR_L2_ERR_APB_BBRF_TO_OTHERS = 0x2370, MAC_AX_ERR_L2_RESET_DONE = 0x2400, MAC_AX_ERR_CPU_EXCEPTION = 0x3000, + MAC_AX_ERR_ASSERTION = 0x4000, MAC_AX_GET_ERR_MAX, MAC_AX_DUMP_SHAREBUFF_INDICATOR = 0x80000000, diff --git a/drivers/net/wireless/realtek/rtw89/ser.c b/drivers/net/wireless/realtek/rtw89/ser.c index e86f3d89ef1bf..5327b97b9c728 100644 --- a/drivers/net/wireless/realtek/rtw89/ser.c +++ b/drivers/net/wireless/realtek/rtw89/ser.c @@ -477,7 +477,7 @@ int rtw89_ser_notify(struct rtw89_dev *rtwdev, u32 err) { u8 event = SER_EV_NONE; - rtw89_info(rtwdev, "ser event = 0x%04x\n", err); + rtw89_info(rtwdev, "SER catches error: 0x%x\n", err); switch (err) { case MAC_AX_ERR_L1_ERR_DMAC: @@ -503,8 +503,10 @@ int rtw89_ser_notify(struct rtw89_dev *rtwdev, u32 err) break; } - if (event == SER_EV_NONE) + if (event == SER_EV_NONE) { + rtw89_warn(rtwdev, "SER cannot recognize error: 0x%x\n", err); return -EINVAL; + } ser_send_msg(&rtwdev->ser, event); return 0; From 14f9f4790048f684c2b151c899895feae0b5731a Mon Sep 17 00:00:00 2001 From: Zong-Zhe Yang Date: Mon, 14 Mar 2022 15:12:46 +0800 Subject: [PATCH 053/228] rtw89: ser: control hci interrupts on/off by state While SER (system error recover) is processing, it's supposed to mean something is under recovery. So, disable interrupts (excluding the one of halt which could be used during SER) to avoid unexpected behavior. And then, enable interrupts after SER is done. Signed-off-by: Zong-Zhe Yang Signed-off-by: Ping-Ke Shih Signed-off-by: Kalle Valo Link: https://lore.kernel.org/r/20220314071250.40292-5-pkshih@realtek.com --- drivers/net/wireless/realtek/rtw89/core.h | 19 +++++++++++++++ drivers/net/wireless/realtek/rtw89/pci.c | 29 +++++++++++++++++++++++ drivers/net/wireless/realtek/rtw89/pci.h | 1 + drivers/net/wireless/realtek/rtw89/ser.c | 4 ++++ 4 files changed, 53 insertions(+) diff --git a/drivers/net/wireless/realtek/rtw89/core.h b/drivers/net/wireless/realtek/rtw89/core.h index 771722132c53b..5efa5ca372c66 100644 --- a/drivers/net/wireless/realtek/rtw89/core.h +++ b/drivers/net/wireless/realtek/rtw89/core.h @@ -2025,6 +2025,13 @@ struct rtw89_hci_ops { int (*mac_lv1_rcvy)(struct rtw89_dev *rtwdev, enum rtw89_lv1_rcvy_step step); void (*dump_err_status)(struct rtw89_dev *rtwdev); int (*napi_poll)(struct napi_struct *napi, int budget); + + /* Deal with locks inside recovery_start and recovery_complete callbacks + * by hci instance, and handle things which need to consider under SER. + * e.g. turn on/off interrupts except for the one for halt notification. + */ + void (*recovery_start)(struct rtw89_dev *rtwdev); + void (*recovery_complete)(struct rtw89_dev *rtwdev); }; struct rtw89_hci_info { @@ -3033,6 +3040,18 @@ static inline void rtw89_hci_flush_queues(struct rtw89_dev *rtwdev, u32 queues, return rtwdev->hci.ops->flush_queues(rtwdev, queues, drop); } +static inline void rtw89_hci_recovery_start(struct rtw89_dev *rtwdev) +{ + if (rtwdev->hci.ops->recovery_start) + rtwdev->hci.ops->recovery_start(rtwdev); +} + +static inline void rtw89_hci_recovery_complete(struct rtw89_dev *rtwdev) +{ + if (rtwdev->hci.ops->recovery_complete) + rtwdev->hci.ops->recovery_complete(rtwdev); +} + static inline u8 rtw89_read8(struct rtw89_dev *rtwdev, u32 addr) { return rtwdev->hci.ops->read8(rtwdev, addr); diff --git a/drivers/net/wireless/realtek/rtw89/pci.c b/drivers/net/wireless/realtek/rtw89/pci.c index e79bfc335b446..32e8283e22f3b 100644 --- a/drivers/net/wireless/realtek/rtw89/pci.c +++ b/drivers/net/wireless/realtek/rtw89/pci.c @@ -647,6 +647,29 @@ static void rtw89_pci_disable_intr(struct rtw89_dev *rtwdev, rtw89_write32(rtwdev, R_AX_PCIE_HIMR10, 0); } +static void rtw89_pci_ops_recovery_start(struct rtw89_dev *rtwdev) +{ + struct rtw89_pci *rtwpci = (struct rtw89_pci *)rtwdev->priv; + unsigned long flags; + + spin_lock_irqsave(&rtwpci->irq_lock, flags); + rtwpci->under_recovery = true; + rtw89_write32(rtwdev, R_AX_PCIE_HIMR00, 0); + rtw89_write32(rtwdev, R_AX_PCIE_HIMR10, 0); + spin_unlock_irqrestore(&rtwpci->irq_lock, flags); +} + +static void rtw89_pci_ops_recovery_complete(struct rtw89_dev *rtwdev) +{ + struct rtw89_pci *rtwpci = (struct rtw89_pci *)rtwdev->priv; + unsigned long flags; + + spin_lock_irqsave(&rtwpci->irq_lock, flags); + rtwpci->under_recovery = false; + rtw89_pci_enable_intr(rtwdev, rtwpci); + spin_unlock_irqrestore(&rtwpci->irq_lock, flags); +} + static irqreturn_t rtw89_pci_interrupt_threadfn(int irq, void *dev) { struct rtw89_dev *rtwdev = dev; @@ -664,6 +687,9 @@ static irqreturn_t rtw89_pci_interrupt_threadfn(int irq, void *dev) if (unlikely(isrs.halt_c2h_isrs & B_AX_HALT_C2H_INT_EN)) rtw89_ser_notify(rtwdev, rtw89_mac_get_err_status(rtwdev)); + if (unlikely(rtwpci->under_recovery)) + return IRQ_HANDLED; + if (likely(rtwpci->running)) { local_bh_disable(); napi_schedule(&rtwdev->napi); @@ -2931,6 +2957,9 @@ static const struct rtw89_hci_ops rtw89_pci_ops = { .mac_lv1_rcvy = rtw89_pci_ops_mac_lv1_recovery, .dump_err_status = rtw89_pci_ops_dump_err_status, .napi_poll = rtw89_pci_napi_poll, + + .recovery_start = rtw89_pci_ops_recovery_start, + .recovery_complete = rtw89_pci_ops_recovery_complete, }; int rtw89_pci_probe(struct pci_dev *pdev, const struct pci_device_id *id) diff --git a/drivers/net/wireless/realtek/rtw89/pci.h b/drivers/net/wireless/realtek/rtw89/pci.h index b84acd0d0582a..2c8030af3e72f 100644 --- a/drivers/net/wireless/realtek/rtw89/pci.h +++ b/drivers/net/wireless/realtek/rtw89/pci.h @@ -594,6 +594,7 @@ struct rtw89_pci { /* protect TRX resources (exclude RXQ) */ spinlock_t trx_lock; bool running; + bool under_recovery; struct rtw89_pci_tx_ring tx_rings[RTW89_TXCH_NUM]; struct rtw89_pci_rx_ring rx_rings[RTW89_RXCH_NUM]; struct sk_buff_head h2c_queue; diff --git a/drivers/net/wireless/realtek/rtw89/ser.c b/drivers/net/wireless/realtek/rtw89/ser.c index 5327b97b9c728..a20389cde7e23 100644 --- a/drivers/net/wireless/realtek/rtw89/ser.c +++ b/drivers/net/wireless/realtek/rtw89/ser.c @@ -302,8 +302,11 @@ static void hal_send_m4_event(struct rtw89_ser *ser) /* state handler */ static void ser_idle_st_hdl(struct rtw89_ser *ser, u8 evt) { + struct rtw89_dev *rtwdev = container_of(ser, struct rtw89_dev, ser); + switch (evt) { case SER_EV_STATE_IN: + rtw89_hci_recovery_complete(rtwdev); break; case SER_EV_L1_RESET: ser_state_goto(ser, SER_RESET_TRX_ST); @@ -312,6 +315,7 @@ static void ser_idle_st_hdl(struct rtw89_ser *ser, u8 evt) ser_state_goto(ser, SER_L2_RESET_ST); break; case SER_EV_STATE_OUT: + rtw89_hci_recovery_start(rtwdev); default: break; } From 9f8004bfed038ae22661f483c358ffc4c076739f Mon Sep 17 00:00:00 2001 From: Zong-Zhe Yang Date: Mon, 14 Mar 2022 15:12:47 +0800 Subject: [PATCH 054/228] rtw89: ser: dump memory for fw payload engine while L2 reset When FW encounters exception or assertion, SER L2 reset process will start. It will dump some error information and re-download FW eventually. Since such errors are usually critical, we would like to keep more information about error to increase possibility of analysis and debugging FW. We first add FW payload engine (fw reserved playoad engine, fw_rsvd_ple) memory dump. FW will record things like CPU registers, backtrace entry, etc. in it for debugging. Moreover, device core dump framework is used and wrapped to collect kinds of dumps during SER L2 reset process. Signed-off-by: Zong-Zhe Yang Signed-off-by: Ping-Ke Shih Signed-off-by: Kalle Valo Link: https://lore.kernel.org/r/20220314071250.40292-6-pkshih@realtek.com --- drivers/net/wireless/realtek/rtw89/core.h | 1 + drivers/net/wireless/realtek/rtw89/fw.h | 2 + drivers/net/wireless/realtek/rtw89/rtw8852a.c | 1 + drivers/net/wireless/realtek/rtw89/ser.c | 118 +++++++++++++++++- 4 files changed, 120 insertions(+), 2 deletions(-) diff --git a/drivers/net/wireless/realtek/rtw89/core.h b/drivers/net/wireless/realtek/rtw89/core.h index 5efa5ca372c66..17ba5b85e5004 100644 --- a/drivers/net/wireless/realtek/rtw89/core.h +++ b/drivers/net/wireless/realtek/rtw89/core.h @@ -2275,6 +2275,7 @@ struct rtw89_chip_info { u32 fifo_size; u16 max_amsdu_limit; bool dis_2g_40m_ul_ofdma; + u32 rsvd_ple_ofst; const struct rtw89_hfc_param_ini *hfc_param_ini; const struct rtw89_dle_mem *dle_mem; u32 rf_base_addr[2]; diff --git a/drivers/net/wireless/realtek/rtw89/fw.h b/drivers/net/wireless/realtek/rtw89/fw.h index ed8609b204e09..d0b93a0b406df 100644 --- a/drivers/net/wireless/realtek/rtw89/fw.h +++ b/drivers/net/wireless/realtek/rtw89/fw.h @@ -2194,6 +2194,8 @@ struct rtw89_fw_h2c_rf_reg_info { #define H2C_CL_OUTSRC_RF_REG_A 0x8 #define H2C_CL_OUTSRC_RF_REG_B 0x9 +#define RTW89_FW_RSVD_PLE_SIZE 0x800 + int rtw89_fw_check_rdy(struct rtw89_dev *rtwdev); int rtw89_fw_recognize(struct rtw89_dev *rtwdev); int rtw89_fw_download(struct rtw89_dev *rtwdev, enum rtw89_fw_type type); diff --git a/drivers/net/wireless/realtek/rtw89/rtw8852a.c b/drivers/net/wireless/realtek/rtw89/rtw8852a.c index 41fc8db311ecf..348ad08090b8d 100644 --- a/drivers/net/wireless/realtek/rtw89/rtw8852a.c +++ b/drivers/net/wireless/realtek/rtw89/rtw8852a.c @@ -2041,6 +2041,7 @@ const struct rtw89_chip_info rtw8852a_chip_info = { .fifo_size = 458752, .max_amsdu_limit = 3500, .dis_2g_40m_ul_ofdma = true, + .rsvd_ple_ofst = 0x6f800, .hfc_param_ini = rtw8852a_hfc_param_ini_pcie, .dle_mem = rtw8852a_dle_mem_pcie, .rf_base_addr = {0xc000, 0xd000}, diff --git a/drivers/net/wireless/realtek/rtw89/ser.c b/drivers/net/wireless/realtek/rtw89/ser.c index a20389cde7e23..bf2f97a146ece 100644 --- a/drivers/net/wireless/realtek/rtw89/ser.c +++ b/drivers/net/wireless/realtek/rtw89/ser.c @@ -2,10 +2,14 @@ /* Copyright(c) 2019-2020 Realtek Corporation */ +#include + #include "cam.h" #include "debug.h" +#include "fw.h" #include "mac.h" #include "ps.h" +#include "reg.h" #include "ser.h" #include "util.h" @@ -67,6 +71,58 @@ static char *ser_st_name(struct rtw89_ser *ser) return "err_st_name"; } +#define RTW89_DEF_SER_CD_TYPE(_name, _type, _size) \ +struct ser_cd_ ## _name { \ + u32 type; \ + u32 type_size; \ + u64 padding; \ + u8 data[_size]; \ +} __packed; \ +static void ser_cd_ ## _name ## _init(struct ser_cd_ ## _name *p) \ +{ \ + p->type = _type; \ + p->type_size = sizeof(p->data); \ + p->padding = 0x0123456789abcdef; \ +} + +enum rtw89_ser_cd_type { + RTW89_SER_CD_FW_RSVD_PLE = 0, +}; + +RTW89_DEF_SER_CD_TYPE(fw_rsvd_ple, + RTW89_SER_CD_FW_RSVD_PLE, + RTW89_FW_RSVD_PLE_SIZE); + +struct rtw89_ser_cd_buffer { + struct ser_cd_fw_rsvd_ple fwple; +} __packed; + +static struct rtw89_ser_cd_buffer *rtw89_ser_cd_prep(struct rtw89_dev *rtwdev) +{ + struct rtw89_ser_cd_buffer *buf; + + buf = vzalloc(sizeof(*buf)); + if (!buf) + return NULL; + + ser_cd_fw_rsvd_ple_init(&buf->fwple); + + return buf; +} + +static void rtw89_ser_cd_send(struct rtw89_dev *rtwdev, + struct rtw89_ser_cd_buffer *buf) +{ + rtw89_debug(rtwdev, RTW89_DBG_SER, "SER sends core dump\n"); + + /* After calling dev_coredump, buf's lifetime is supposed to be + * handled by the device coredump framework. Note that a new dump + * will be discarded if a previous one hasn't been released by + * framework yet. + */ + dev_coredumpv(rtwdev->dev, buf, sizeof(*buf), GFP_KERNEL); +} + static void ser_state_run(struct rtw89_ser *ser, u8 evt) { struct rtw89_dev *rtwdev = container_of(ser, struct rtw89_dev, ser); @@ -390,6 +446,65 @@ static void ser_do_hci_st_hdl(struct rtw89_ser *ser, u8 evt) } } +static void ser_mac_mem_dump(struct rtw89_dev *rtwdev, u8 *buf, + u8 sel, u32 start_addr, u32 len) +{ + u32 *ptr = (u32 *)buf; + u32 base_addr, start_page, residue; + u32 cnt = 0; + u32 i; + + start_page = start_addr / MAC_MEM_DUMP_PAGE_SIZE; + residue = start_addr % MAC_MEM_DUMP_PAGE_SIZE; + base_addr = rtw89_mac_mem_base_addrs[sel]; + base_addr += start_page * MAC_MEM_DUMP_PAGE_SIZE; + + while (cnt < len) { + rtw89_write32(rtwdev, R_AX_FILTER_MODEL_ADDR, base_addr); + + for (i = R_AX_INDIR_ACCESS_ENTRY + residue; + i < R_AX_INDIR_ACCESS_ENTRY + MAC_MEM_DUMP_PAGE_SIZE; + i += 4, ptr++) { + *ptr = rtw89_read32(rtwdev, i); + cnt += 4; + if (cnt >= len) + break; + } + + residue = 0; + base_addr += MAC_MEM_DUMP_PAGE_SIZE; + } +} + +static void rtw89_ser_fw_rsvd_ple_dump(struct rtw89_dev *rtwdev, u8 *buf) +{ + u32 start_addr = rtwdev->chip->rsvd_ple_ofst; + + rtw89_debug(rtwdev, RTW89_DBG_SER, + "dump mem for fw rsvd payload engine (start addr: 0x%x)\n", + start_addr); + ser_mac_mem_dump(rtwdev, buf, RTW89_MAC_MEM_SHARED_BUF, start_addr, + RTW89_FW_RSVD_PLE_SIZE); +} + +static void ser_l2_reset_st_pre_hdl(struct rtw89_ser *ser) +{ + struct rtw89_dev *rtwdev = container_of(ser, struct rtw89_dev, ser); + struct rtw89_ser_cd_buffer *buf; + + buf = rtw89_ser_cd_prep(rtwdev); + if (!buf) + goto bottom; + + rtw89_ser_fw_rsvd_ple_dump(rtwdev, buf->fwple.data); + rtw89_ser_cd_send(rtwdev, buf); + +bottom: + ser_reset_mac_binding(rtwdev); + rtw89_core_stop(rtwdev); + INIT_LIST_HEAD(&rtwdev->rtwvifs_list); +} + static void ser_l2_reset_st_hdl(struct rtw89_ser *ser, u8 evt) { struct rtw89_dev *rtwdev = container_of(ser, struct rtw89_dev, ser); @@ -397,8 +512,7 @@ static void ser_l2_reset_st_hdl(struct rtw89_ser *ser, u8 evt) switch (evt) { case SER_EV_STATE_IN: mutex_lock(&rtwdev->mutex); - ser_reset_mac_binding(rtwdev); - rtw89_core_stop(rtwdev); + ser_l2_reset_st_pre_hdl(ser); mutex_unlock(&rtwdev->mutex); ieee80211_restart_hw(rtwdev->hw); From f5e246846412175f38f830d9082fae0f72470843 Mon Sep 17 00:00:00 2001 From: Zong-Zhe Yang Date: Mon, 14 Mar 2022 15:12:48 +0800 Subject: [PATCH 055/228] rtw89: ser: dump fw backtrace while L2 reset Read FW backtrace entry through FW reserved payload engine, and then add FW backtrace dump during SER (system error recover) L2 reset process. It contains a list of RA (return address) and SP (stack pointer) which gives us a chance to trace back the call stack of FW. Moreover, if core dump might have wrong content due to error during dumping, we won't invoke device core dump framework. For this case, rtw89_ser_cd_free() is added to free buffer by ourselves. Signed-off-by: Zong-Zhe Yang Signed-off-by: Ping-Ke Shih Signed-off-by: Kalle Valo Link: https://lore.kernel.org/r/20220314071250.40292-7-pkshih@realtek.com --- drivers/net/wireless/realtek/rtw89/fw.h | 9 +++ drivers/net/wireless/realtek/rtw89/ser.c | 97 +++++++++++++++++++++++- 2 files changed, 105 insertions(+), 1 deletion(-) diff --git a/drivers/net/wireless/realtek/rtw89/fw.h b/drivers/net/wireless/realtek/rtw89/fw.h index d0b93a0b406df..1aaec26722377 100644 --- a/drivers/net/wireless/realtek/rtw89/fw.h +++ b/drivers/net/wireless/realtek/rtw89/fw.h @@ -2196,6 +2196,15 @@ struct rtw89_fw_h2c_rf_reg_info { #define RTW89_FW_RSVD_PLE_SIZE 0x800 +#define RTW89_WCPU_BASE_ADDR 0xA0000000 + +#define RTW89_FW_BACKTRACE_INFO_SIZE 8 +#define RTW89_VALID_FW_BACKTRACE_SIZE(_size) \ + ((_size) % RTW89_FW_BACKTRACE_INFO_SIZE == 0) + +#define RTW89_FW_BACKTRACE_MAX_SIZE 512 /* 8 * 64 (entries) */ +#define RTW89_FW_BACKTRACE_KEY 0xBACEBACE + int rtw89_fw_check_rdy(struct rtw89_dev *rtwdev); int rtw89_fw_recognize(struct rtw89_dev *rtwdev); int rtw89_fw_download(struct rtw89_dev *rtwdev, enum rtw89_fw_type type); diff --git a/drivers/net/wireless/realtek/rtw89/ser.c b/drivers/net/wireless/realtek/rtw89/ser.c index bf2f97a146ece..f28cd0645ad92 100644 --- a/drivers/net/wireless/realtek/rtw89/ser.c +++ b/drivers/net/wireless/realtek/rtw89/ser.c @@ -87,14 +87,20 @@ static void ser_cd_ ## _name ## _init(struct ser_cd_ ## _name *p) \ enum rtw89_ser_cd_type { RTW89_SER_CD_FW_RSVD_PLE = 0, + RTW89_SER_CD_FW_BACKTRACE = 1, }; RTW89_DEF_SER_CD_TYPE(fw_rsvd_ple, RTW89_SER_CD_FW_RSVD_PLE, RTW89_FW_RSVD_PLE_SIZE); +RTW89_DEF_SER_CD_TYPE(fw_backtrace, + RTW89_SER_CD_FW_BACKTRACE, + RTW89_FW_BACKTRACE_MAX_SIZE); + struct rtw89_ser_cd_buffer { struct ser_cd_fw_rsvd_ple fwple; + struct ser_cd_fw_backtrace fwbt; } __packed; static struct rtw89_ser_cd_buffer *rtw89_ser_cd_prep(struct rtw89_dev *rtwdev) @@ -106,6 +112,7 @@ static struct rtw89_ser_cd_buffer *rtw89_ser_cd_prep(struct rtw89_dev *rtwdev) return NULL; ser_cd_fw_rsvd_ple_init(&buf->fwple); + ser_cd_fw_backtrace_init(&buf->fwbt); return buf; } @@ -123,6 +130,21 @@ static void rtw89_ser_cd_send(struct rtw89_dev *rtwdev, dev_coredumpv(rtwdev->dev, buf, sizeof(*buf), GFP_KERNEL); } +static void rtw89_ser_cd_free(struct rtw89_dev *rtwdev, + struct rtw89_ser_cd_buffer *buf, bool free_self) +{ + if (!free_self) + return; + + rtw89_debug(rtwdev, RTW89_DBG_SER, "SER frees core dump by self\n"); + + /* When some problems happen during filling data of core dump, + * we won't send it to device coredump framework. Instead, we + * free buf by ourselves. + */ + vfree(buf); +} + static void ser_state_run(struct rtw89_ser *ser, u8 evt) { struct rtw89_dev *rtwdev = container_of(ser, struct rtw89_dev, ser); @@ -487,19 +509,92 @@ static void rtw89_ser_fw_rsvd_ple_dump(struct rtw89_dev *rtwdev, u8 *buf) RTW89_FW_RSVD_PLE_SIZE); } +struct __fw_backtrace_entry { + u32 wcpu_addr; + u32 size; + u32 key; +} __packed; + +struct __fw_backtrace_info { + u32 ra; + u32 sp; +} __packed; + +static_assert(RTW89_FW_BACKTRACE_INFO_SIZE == + sizeof(struct __fw_backtrace_info)); + +static int rtw89_ser_fw_backtrace_dump(struct rtw89_dev *rtwdev, u8 *buf, + const struct __fw_backtrace_entry *ent) +{ + struct __fw_backtrace_info *ptr = (struct __fw_backtrace_info *)buf; + u32 fwbt_addr = ent->wcpu_addr - RTW89_WCPU_BASE_ADDR; + u32 fwbt_size = ent->size; + u32 fwbt_key = ent->key; + u32 i; + + if (fwbt_addr == 0) { + rtw89_warn(rtwdev, "FW backtrace invalid address: 0x%x\n", + fwbt_addr); + return -EINVAL; + } + + if (fwbt_key != RTW89_FW_BACKTRACE_KEY) { + rtw89_warn(rtwdev, "FW backtrace invalid key: 0x%x\n", + fwbt_key); + return -EINVAL; + } + + if (fwbt_size == 0 || !RTW89_VALID_FW_BACKTRACE_SIZE(fwbt_size) || + fwbt_size > RTW89_FW_BACKTRACE_MAX_SIZE) { + rtw89_warn(rtwdev, "FW backtrace invalid size: 0x%x\n", + fwbt_size); + return -EINVAL; + } + + rtw89_debug(rtwdev, RTW89_DBG_SER, "dump fw backtrace start\n"); + rtw89_write32(rtwdev, R_AX_FILTER_MODEL_ADDR, fwbt_addr); + + for (i = R_AX_INDIR_ACCESS_ENTRY; + i < R_AX_INDIR_ACCESS_ENTRY + fwbt_size; + i += RTW89_FW_BACKTRACE_INFO_SIZE, ptr++) { + *ptr = (struct __fw_backtrace_info){ + .ra = rtw89_read32(rtwdev, i), + .sp = rtw89_read32(rtwdev, i + 4), + }; + rtw89_debug(rtwdev, RTW89_DBG_SER, + "next sp: 0x%x, next ra: 0x%x\n", + ptr->sp, ptr->ra); + } + + rtw89_debug(rtwdev, RTW89_DBG_SER, "dump fw backtrace end\n"); + return 0; +} + static void ser_l2_reset_st_pre_hdl(struct rtw89_ser *ser) { struct rtw89_dev *rtwdev = container_of(ser, struct rtw89_dev, ser); struct rtw89_ser_cd_buffer *buf; + struct __fw_backtrace_entry fwbt_ent; + int ret = 0; buf = rtw89_ser_cd_prep(rtwdev); - if (!buf) + if (!buf) { + ret = -ENOMEM; goto bottom; + } rtw89_ser_fw_rsvd_ple_dump(rtwdev, buf->fwple.data); + + fwbt_ent = *(struct __fw_backtrace_entry *)buf->fwple.data; + ret = rtw89_ser_fw_backtrace_dump(rtwdev, buf->fwbt.data, &fwbt_ent); + if (ret) + goto bottom; + rtw89_ser_cd_send(rtwdev, buf); bottom: + rtw89_ser_cd_free(rtwdev, buf, !!ret); + ser_reset_mac_binding(rtwdev); rtw89_core_stop(rtwdev); INIT_LIST_HEAD(&rtwdev->rtwvifs_list); From 11fe4ccda8672db5375f8bfcb209756a31c89a82 Mon Sep 17 00:00:00 2001 From: Zong-Zhe Yang Date: Mon, 14 Mar 2022 15:12:49 +0800 Subject: [PATCH 056/228] rtw89: reconstruct fw feature As the fw features gradually increase, it would be better that we have a set of methods to maintain fw features instead of using scattered bool variables. We reconstruct the way fw recognize features, and introduce RTW89_CHK_FW_FEATURE() / RTW89_SET_FW_FEATURE() to check / set fw features for uses. Signed-off-by: Zong-Zhe Yang Signed-off-by: Ping-Ke Shih Signed-off-by: Kalle Valo Link: https://lore.kernel.org/r/20220314071250.40292-8-pkshih@realtek.com --- drivers/net/wireless/realtek/rtw89/core.c | 5 +- drivers/net/wireless/realtek/rtw89/core.h | 16 ++++-- drivers/net/wireless/realtek/rtw89/fw.c | 53 +++++++++++++++---- drivers/net/wireless/realtek/rtw89/mac80211.c | 4 +- drivers/net/wireless/realtek/rtw89/phy.c | 2 +- 5 files changed, 62 insertions(+), 18 deletions(-) diff --git a/drivers/net/wireless/realtek/rtw89/core.c b/drivers/net/wireless/realtek/rtw89/core.c index bcefc968576e0..c61061358980b 100644 --- a/drivers/net/wireless/realtek/rtw89/core.c +++ b/drivers/net/wireless/realtek/rtw89/core.c @@ -759,7 +759,7 @@ static void rtw89_core_tx_wake(struct rtw89_dev *rtwdev, struct rtw89_core_tx_request *tx_req) { - if (!rtwdev->fw.tx_wake) + if (!RTW89_CHK_FW_FEATURE(TX_WAKE, &rtwdev->fw)) return; if (!test_bit(RTW89_FLAG_LOW_POWER_MODE, rtwdev->flags)) @@ -1454,7 +1454,8 @@ static void rtw89_core_update_rx_status(struct rtw89_dev *rtwdev, rx_status->freq = hw->conf.chandef.chan->center_freq; rx_status->band = hw->conf.chandef.chan->band; - if (rtwdev->scanning && rtwdev->fw.scan_offload) { + if (rtwdev->scanning && + RTW89_CHK_FW_FEATURE(SCAN_OFFLOAD, &rtwdev->fw)) { rx_status->freq = ieee80211_channel_to_frequency(hal->current_channel, hal->current_band_type); diff --git a/drivers/net/wireless/realtek/rtw89/core.h b/drivers/net/wireless/realtek/rtw89/core.h index 17ba5b85e5004..395d3bacdd3f7 100644 --- a/drivers/net/wireless/realtek/rtw89/core.h +++ b/drivers/net/wireless/realtek/rtw89/core.h @@ -2396,6 +2396,12 @@ enum rtw89_fw_type { RTW89_FW_WOWLAN = 3, }; +enum rtw89_fw_feature { + RTW89_FW_FEATURE_OLD_HT_RA_FORMAT, + RTW89_FW_FEATURE_SCAN_OFFLOAD, + RTW89_FW_FEATURE_TX_WAKE, +}; + struct rtw89_fw_suit { const u8 *data; u32 size; @@ -2425,11 +2431,15 @@ struct rtw89_fw_info { struct rtw89_fw_suit normal; struct rtw89_fw_suit wowlan; bool fw_log_enable; - bool old_ht_ra_format; - bool scan_offload; - bool tx_wake; + u32 feature_map; }; +#define RTW89_CHK_FW_FEATURE(_feat, _fw) \ + (!!((_fw)->feature_map & BIT(RTW89_FW_FEATURE_ ## _feat))) + +#define RTW89_SET_FW_FEATURE(_fw_feature, _fw) \ + ((_fw)->feature_map |= BIT(_fw_feature)) + struct rtw89_cam_info { DECLARE_BITMAP(addr_cam_map, RTW89_MAX_ADDR_CAM_NUM); DECLARE_BITMAP(bssid_cam_map, RTW89_MAX_BSSID_CAM_NUM); diff --git a/drivers/net/wireless/realtek/rtw89/fw.c b/drivers/net/wireless/realtek/rtw89/fw.c index 6deaf8eec6b47..76a2900905075 100644 --- a/drivers/net/wireless/realtek/rtw89/fw.c +++ b/drivers/net/wireless/realtek/rtw89/fw.c @@ -193,22 +193,55 @@ int __rtw89_fw_recognize(struct rtw89_dev *rtwdev, enum rtw89_fw_type type) return 0; } +#define __DEF_FW_FEAT_COND(__cond, __op) \ +static bool __fw_feat_cond_ ## __cond(u32 suit_ver_code, u32 comp_ver_code) \ +{ \ + return suit_ver_code __op comp_ver_code; \ +} + +__DEF_FW_FEAT_COND(ge, >=); /* greater or equal */ +__DEF_FW_FEAT_COND(le, <=); /* less or equal */ + +struct __fw_feat_cfg { + enum rtw89_core_chip_id chip_id; + enum rtw89_fw_feature feature; + u32 ver_code; + bool (*cond)(u32 suit_ver_code, u32 comp_ver_code); +}; + +#define __CFG_FW_FEAT(_chip, _cond, _maj, _min, _sub, _idx, _feat) \ + { \ + .chip_id = _chip, \ + .feature = RTW89_FW_FEATURE_ ## _feat, \ + .ver_code = RTW89_FW_VER_CODE(_maj, _min, _sub, _idx), \ + .cond = __fw_feat_cond_ ## _cond, \ + } + +static const struct __fw_feat_cfg fw_feat_tbl[] = { + __CFG_FW_FEAT(RTL8852A, le, 0, 13, 29, 0, OLD_HT_RA_FORMAT), + __CFG_FW_FEAT(RTL8852A, ge, 0, 13, 35, 0, SCAN_OFFLOAD), + __CFG_FW_FEAT(RTL8852A, ge, 0, 13, 35, 0, TX_WAKE), +}; + static void rtw89_fw_recognize_features(struct rtw89_dev *rtwdev) { const struct rtw89_chip_info *chip = rtwdev->chip; - struct rtw89_fw_suit *fw_suit = rtw89_fw_suit_get(rtwdev, RTW89_FW_NORMAL); + const struct __fw_feat_cfg *ent; + const struct rtw89_fw_suit *fw_suit; + u32 suit_ver_code; + int i; - if (chip->chip_id == RTL8852A && - RTW89_FW_SUIT_VER_CODE(fw_suit) <= RTW89_FW_VER_CODE(0, 13, 29, 0)) - rtwdev->fw.old_ht_ra_format = true; + fw_suit = rtw89_fw_suit_get(rtwdev, RTW89_FW_NORMAL); + suit_ver_code = RTW89_FW_SUIT_VER_CODE(fw_suit); - if (chip->chip_id == RTL8852A && - RTW89_FW_SUIT_VER_CODE(fw_suit) >= RTW89_FW_VER_CODE(0, 13, 35, 0)) - rtwdev->fw.scan_offload = true; + for (i = 0; i < ARRAY_SIZE(fw_feat_tbl); i++) { + ent = &fw_feat_tbl[i]; + if (chip->chip_id != ent->chip_id) + continue; - if (chip->chip_id == RTL8852A && - RTW89_FW_SUIT_VER_CODE(fw_suit) >= RTW89_FW_VER_CODE(0, 13, 35, 0)) - rtwdev->fw.tx_wake = true; + if (ent->cond(suit_ver_code, ent->ver_code)) + RTW89_SET_FW_FEATURE(ent->feature, &rtwdev->fw); + } } int rtw89_fw_recognize(struct rtw89_dev *rtwdev) diff --git a/drivers/net/wireless/realtek/rtw89/mac80211.c b/drivers/net/wireless/realtek/rtw89/mac80211.c index fca9f82bb462f..8da3e117ad382 100644 --- a/drivers/net/wireless/realtek/rtw89/mac80211.c +++ b/drivers/net/wireless/realtek/rtw89/mac80211.c @@ -725,7 +725,7 @@ static int rtw89_ops_hw_scan(struct ieee80211_hw *hw, struct ieee80211_vif *vif, struct rtw89_dev *rtwdev = hw->priv; int ret = 0; - if (!rtwdev->fw.scan_offload) + if (!RTW89_CHK_FW_FEATURE(SCAN_OFFLOAD, &rtwdev->fw)) return 1; if (rtwdev->scanning) @@ -748,7 +748,7 @@ static void rtw89_ops_cancel_hw_scan(struct ieee80211_hw *hw, { struct rtw89_dev *rtwdev = hw->priv; - if (!rtwdev->fw.scan_offload) + if (!RTW89_CHK_FW_FEATURE(SCAN_OFFLOAD, &rtwdev->fw)) return; if (!rtwdev->scanning) diff --git a/drivers/net/wireless/realtek/rtw89/phy.c b/drivers/net/wireless/realtek/rtw89/phy.c index ac211d8973118..c9a04ca0b1f21 100644 --- a/drivers/net/wireless/realtek/rtw89/phy.c +++ b/drivers/net/wireless/realtek/rtw89/phy.c @@ -1686,7 +1686,7 @@ static void rtw89_phy_c2h_ra_rpt_iter(void *data, struct ieee80211_sta *sta) break; case RTW89_RA_RPT_MODE_HT: ra_report->txrate.flags |= RATE_INFO_FLAGS_MCS; - if (rtwdev->fw.old_ht_ra_format) + if (RTW89_CHK_FW_FEATURE(OLD_HT_RA_FORMAT, &rtwdev->fw)) rate = RTW89_MK_HT_RATE(FIELD_GET(RTW89_RA_RATE_MASK_NSS, rate), FIELD_GET(RTW89_RA_RATE_MASK_MCS, rate)); else From edb896297abeef8c95c150247607b09517469a9a Mon Sep 17 00:00:00 2001 From: Zong-Zhe Yang Date: Mon, 14 Mar 2022 15:12:50 +0800 Subject: [PATCH 057/228] rtw89: support FW crash simulation Originally, there is already a mechanism, SER (system error recover), to deal with HW/FW recovery. After FW v0.13.36.0, FW supports a H2C (host to chip) command to make a CPU exception. Then, SER is supposed to catch this FW crash and do L2 reset. This feature is a simulation to verify if flow of recovering from FW crash works. Usage of fw_crash debugfs is as the following. $ echo 1 > fw_crash // trigger FW crash and wait SER handling $ cat fw_crash // return 0 if restart has been done Signed-off-by: Zong-Zhe Yang Signed-off-by: Ping-Ke Shih Signed-off-by: Kalle Valo Link: https://lore.kernel.org/r/20220314071250.40292-9-pkshih@realtek.com --- drivers/net/wireless/realtek/rtw89/core.h | 2 + drivers/net/wireless/realtek/rtw89/debug.c | 48 ++++++++++++++++++++++ drivers/net/wireless/realtek/rtw89/fw.c | 36 ++++++++++++++++ drivers/net/wireless/realtek/rtw89/fw.h | 12 ++++++ drivers/net/wireless/realtek/rtw89/ser.c | 1 + 5 files changed, 99 insertions(+) diff --git a/drivers/net/wireless/realtek/rtw89/core.h b/drivers/net/wireless/realtek/rtw89/core.h index 395d3bacdd3f7..7d8140cc25a75 100644 --- a/drivers/net/wireless/realtek/rtw89/core.h +++ b/drivers/net/wireless/realtek/rtw89/core.h @@ -2400,6 +2400,7 @@ enum rtw89_fw_feature { RTW89_FW_FEATURE_OLD_HT_RA_FORMAT, RTW89_FW_FEATURE_SCAN_OFFLOAD, RTW89_FW_FEATURE_TX_WAKE, + RTW89_FW_FEATURE_CRASH_TRIGGER, }; struct rtw89_fw_suit { @@ -2502,6 +2503,7 @@ enum rtw89_flags { RTW89_FLAG_LEISURE_PS, RTW89_FLAG_LOW_POWER_MODE, RTW89_FLAG_INACTIVE_PS, + RTW89_FLAG_RESTART_TRIGGER, NUM_OF_RTW89_FLAGS, }; diff --git a/drivers/net/wireless/realtek/rtw89/debug.c b/drivers/net/wireless/realtek/rtw89/debug.c index 09c545497ec5c..f93f3fee15058 100644 --- a/drivers/net/wireless/realtek/rtw89/debug.c +++ b/drivers/net/wireless/realtek/rtw89/debug.c @@ -2184,6 +2184,48 @@ rtw89_debug_priv_early_h2c_set(struct file *filp, const char __user *user_buf, return count; } +static int +rtw89_debug_priv_fw_crash_get(struct seq_file *m, void *v) +{ + struct rtw89_debugfs_priv *debugfs_priv = m->private; + struct rtw89_dev *rtwdev = debugfs_priv->rtwdev; + + seq_printf(m, "%d\n", + test_bit(RTW89_FLAG_RESTART_TRIGGER, rtwdev->flags)); + return 0; +} + +static ssize_t +rtw89_debug_priv_fw_crash_set(struct file *filp, const char __user *user_buf, + size_t count, loff_t *loff) +{ + 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; + bool fw_crash; + int ret; + + if (!RTW89_CHK_FW_FEATURE(CRASH_TRIGGER, &rtwdev->fw)) + return -EOPNOTSUPP; + + ret = kstrtobool_from_user(user_buf, count, &fw_crash); + if (ret) + return -EINVAL; + + if (!fw_crash) + return -EINVAL; + + mutex_lock(&rtwdev->mutex); + set_bit(RTW89_FLAG_RESTART_TRIGGER, rtwdev->flags); + ret = rtw89_fw_h2c_trigger_cpu_exception(rtwdev); + mutex_unlock(&rtwdev->mutex); + + if (ret) + return ret; + + return count; +} + static int rtw89_debug_priv_btc_info_get(struct seq_file *m, void *v) { struct rtw89_debugfs_priv *debugfs_priv = m->private; @@ -2468,6 +2510,11 @@ static struct rtw89_debugfs_priv rtw89_debug_priv_early_h2c = { .cb_write = rtw89_debug_priv_early_h2c_set, }; +static struct rtw89_debugfs_priv rtw89_debug_priv_fw_crash = { + .cb_read = rtw89_debug_priv_fw_crash_get, + .cb_write = rtw89_debug_priv_fw_crash_set, +}; + static struct rtw89_debugfs_priv rtw89_debug_priv_btc_info = { .cb_read = rtw89_debug_priv_btc_info_get, }; @@ -2522,6 +2569,7 @@ void rtw89_debugfs_init(struct rtw89_dev *rtwdev) rtw89_debugfs_add_rw(mac_dbg_port_dump); rtw89_debugfs_add_w(send_h2c); rtw89_debugfs_add_rw(early_h2c); + rtw89_debugfs_add_rw(fw_crash); rtw89_debugfs_add_r(btc_info); rtw89_debugfs_add_w(btc_manual); rtw89_debugfs_add_w(fw_log_manual); diff --git a/drivers/net/wireless/realtek/rtw89/fw.c b/drivers/net/wireless/realtek/rtw89/fw.c index 76a2900905075..2c9470616a1b2 100644 --- a/drivers/net/wireless/realtek/rtw89/fw.c +++ b/drivers/net/wireless/realtek/rtw89/fw.c @@ -221,6 +221,7 @@ static const struct __fw_feat_cfg fw_feat_tbl[] = { __CFG_FW_FEAT(RTL8852A, le, 0, 13, 29, 0, OLD_HT_RA_FORMAT), __CFG_FW_FEAT(RTL8852A, ge, 0, 13, 35, 0, SCAN_OFFLOAD), __CFG_FW_FEAT(RTL8852A, ge, 0, 13, 35, 0, TX_WAKE), + __CFG_FW_FEAT(RTL8852A, ge, 0, 13, 36, 0, CRASH_TRIGGER), }; static void rtw89_fw_recognize_features(struct rtw89_dev *rtwdev) @@ -2287,3 +2288,38 @@ void rtw89_store_op_chan(struct rtw89_dev *rtwdev) scan_info->op_bw = hal->current_band_width; scan_info->op_band = hal->current_band_type; } + +#define H2C_FW_CPU_EXCEPTION_LEN 4 +#define H2C_FW_CPU_EXCEPTION_TYPE_DEF 0x5566 +int rtw89_fw_h2c_trigger_cpu_exception(struct rtw89_dev *rtwdev) +{ + struct sk_buff *skb; + + skb = rtw89_fw_h2c_alloc_skb_with_hdr(H2C_FW_CPU_EXCEPTION_LEN); + if (!skb) { + rtw89_err(rtwdev, + "failed to alloc skb for fw cpu exception\n"); + return -ENOMEM; + } + + skb_put(skb, H2C_FW_CPU_EXCEPTION_LEN); + RTW89_SET_FWCMD_CPU_EXCEPTION_TYPE(skb->data, + H2C_FW_CPU_EXCEPTION_TYPE_DEF); + + rtw89_h2c_pkt_set_hdr(rtwdev, skb, FWCMD_TYPE_H2C, + H2C_CAT_TEST, + H2C_CL_FW_STATUS_TEST, + H2C_FUNC_CPU_EXCEPTION, 0, 0, + H2C_FW_CPU_EXCEPTION_LEN); + + if (rtw89_h2c_tx(rtwdev, skb, false)) { + rtw89_err(rtwdev, "failed to send h2c\n"); + goto fail; + } + + return 0; + +fail: + dev_kfree_skb_any(skb); + return -EBUSY; +} diff --git a/drivers/net/wireless/realtek/rtw89/fw.h b/drivers/net/wireless/realtek/rtw89/fw.h index 1aaec26722377..24ab249a8ecec 100644 --- a/drivers/net/wireless/realtek/rtw89/fw.h +++ b/drivers/net/wireless/realtek/rtw89/fw.h @@ -1461,6 +1461,11 @@ static inline void SET_LPS_PARM_LASTRPWM(void *h2c, u32 val) le32p_replace_bits((__le32 *)(h2c) + 1, val, GENMASK(15, 8)); } +static inline void RTW89_SET_FWCMD_CPU_EXCEPTION_TYPE(void *cmd, u32 val) +{ + le32p_replace_bits((__le32 *)cmd, val, GENMASK(31, 0)); +} + enum rtw89_btc_btf_h2c_class { BTFC_SET = 0x10, BTFC_GET = 0x11, @@ -2140,6 +2145,12 @@ struct rtw89_fw_h2c_rf_reg_info { #define FWCMD_TYPE_H2C 0 +#define H2C_CAT_TEST 0x0 + +/* CLASS 5 - FW STATUS TEST */ +#define H2C_CL_FW_STATUS_TEST 0x5 +#define H2C_FUNC_CPU_EXCEPTION 0x1 + #define H2C_CAT_MAC 0x1 /* CLASS 0 - FW INFO */ @@ -2284,5 +2295,6 @@ void rtw89_hw_scan_status_report(struct rtw89_dev *rtwdev, struct sk_buff *skb); void rtw89_hw_scan_chan_switch(struct rtw89_dev *rtwdev, struct sk_buff *skb); void rtw89_hw_scan_abort(struct rtw89_dev *rtwdev, struct ieee80211_vif *vif); void rtw89_store_op_chan(struct rtw89_dev *rtwdev); +int rtw89_fw_h2c_trigger_cpu_exception(struct rtw89_dev *rtwdev); #endif diff --git a/drivers/net/wireless/realtek/rtw89/ser.c b/drivers/net/wireless/realtek/rtw89/ser.c index f28cd0645ad92..25d1df10f2262 100644 --- a/drivers/net/wireless/realtek/rtw89/ser.c +++ b/drivers/net/wireless/realtek/rtw89/ser.c @@ -619,6 +619,7 @@ static void ser_l2_reset_st_hdl(struct rtw89_ser *ser, u8 evt) fallthrough; case SER_EV_L2_RECFG_DONE: ser_state_goto(ser, SER_IDLE_ST); + clear_bit(RTW89_FLAG_RESTART_TRIGGER, rtwdev->flags); break; case SER_EV_STATE_OUT: From 306451188062a788c59d6b708acd1f2ba2274bd9 Mon Sep 17 00:00:00 2001 From: Ping-Ke Shih Date: Tue, 15 Mar 2022 09:55:22 +0800 Subject: [PATCH 058/228] rtw89: reduce export symbol number of mac size and quota An export symbol costs about 40 bytes (in x86 with gcc), so use a structure containing these small arrays to reduce code size. text data bss dec hex filename 34932 1410 0 36342 8df6 mac.o (before) 34276 1258 0 35534 8ace mac.o (after) Signed-off-by: Ping-Ke Shih Signed-off-by: Kalle Valo Link: https://lore.kernel.org/r/20220315015522.11366-1-pkshih@realtek.com --- drivers/net/wireless/realtek/rtw89/mac.c | 158 +++++------------- drivers/net/wireless/realtek/rtw89/mac.h | 44 ++--- drivers/net/wireless/realtek/rtw89/rtw8852a.c | 18 +- drivers/net/wireless/realtek/rtw89/rtw8852c.c | 14 +- 4 files changed, 83 insertions(+), 151 deletions(-) diff --git a/drivers/net/wireless/realtek/rtw89/mac.c b/drivers/net/wireless/realtek/rtw89/mac.c index 87adaa08fdb93..d751054413727 100644 --- a/drivers/net/wireless/realtek/rtw89/mac.c +++ b/drivers/net/wireless/realtek/rtw89/mac.c @@ -510,11 +510,6 @@ int rtw89_mac_set_err_status(struct rtw89_dev *rtwdev, u32 err) } EXPORT_SYMBOL(rtw89_mac_set_err_status); -const struct rtw89_hfc_prec_cfg rtw89_hfc_preccfg_pcie = { - 2, 40, 0, 0, 1, 0, 0, 0 -}; -EXPORT_SYMBOL(rtw89_hfc_preccfg_pcie); - static int hfc_reset_param(struct rtw89_dev *rtwdev) { struct rtw89_hfc_param *param = &rtwdev->mac.hfc_param; @@ -1216,119 +1211,48 @@ static int rtw89_mac_sys_init(struct rtw89_dev *rtwdev) return ret; } -/* PCIE 64 */ -const struct rtw89_dle_size rtw89_wde_size0 = { - RTW89_WDE_PG_64, 4095, 1, -}; -EXPORT_SYMBOL(rtw89_wde_size0); - -/* DLFW */ -const struct rtw89_dle_size rtw89_wde_size4 = { - RTW89_WDE_PG_64, 0, 4096, -}; -EXPORT_SYMBOL(rtw89_wde_size4); - -/* 8852C DLFW */ -const struct rtw89_dle_size rtw89_wde_size18 = { - RTW89_WDE_PG_64, 0, 2048, -}; -EXPORT_SYMBOL(rtw89_wde_size18); - -/* 8852C PCIE SCC */ -const struct rtw89_dle_size rtw89_wde_size19 = { - RTW89_WDE_PG_64, 3328, 0, -}; -EXPORT_SYMBOL(rtw89_wde_size19); - -/* PCIE */ -const struct rtw89_dle_size rtw89_ple_size0 = { - RTW89_PLE_PG_128, 1520, 16, -}; -EXPORT_SYMBOL(rtw89_ple_size0); - -/* DLFW */ -const struct rtw89_dle_size rtw89_ple_size4 = { - RTW89_PLE_PG_128, 64, 1472, -}; -EXPORT_SYMBOL(rtw89_ple_size4); - -/* 8852C DLFW */ -const struct rtw89_dle_size rtw89_ple_size18 = { - RTW89_PLE_PG_128, 2544, 16, -}; -EXPORT_SYMBOL(rtw89_ple_size18); - -/* 8852C PCIE SCC */ -const struct rtw89_dle_size rtw89_ple_size19 = { - RTW89_PLE_PG_128, 1904, 16, -}; -EXPORT_SYMBOL(rtw89_ple_size19); - -/* PCIE 64 */ -const struct rtw89_wde_quota rtw89_wde_qt0 = { - 3792, 196, 0, 107, -}; -EXPORT_SYMBOL(rtw89_wde_qt0); - -/* DLFW */ -const struct rtw89_wde_quota rtw89_wde_qt4 = { - 0, 0, 0, 0, -}; -EXPORT_SYMBOL(rtw89_wde_qt4); - -/* 8852C DLFW */ -const struct rtw89_wde_quota rtw89_wde_qt17 = { - 0, 0, 0, 0, -}; -EXPORT_SYMBOL(rtw89_wde_qt17); - -/* 8852C PCIE SCC */ -const struct rtw89_wde_quota rtw89_wde_qt18 = { - 3228, 60, 0, 40, -}; -EXPORT_SYMBOL(rtw89_wde_qt18); - -/* PCIE SCC */ -const struct rtw89_ple_quota rtw89_ple_qt4 = { - 264, 0, 16, 20, 26, 13, 356, 0, 32, 40, 8, -}; -EXPORT_SYMBOL(rtw89_ple_qt4); - -/* PCIE SCC */ -const struct rtw89_ple_quota rtw89_ple_qt5 = { - 264, 0, 32, 20, 64, 13, 1101, 0, 64, 128, 120, -}; -EXPORT_SYMBOL(rtw89_ple_qt5); - -/* DLFW */ -const struct rtw89_ple_quota rtw89_ple_qt13 = { - 0, 0, 16, 48, 0, 0, 0, 0, 0, 0, 0 -}; -EXPORT_SYMBOL(rtw89_ple_qt13); - -/* DLFW 52C */ -const struct rtw89_ple_quota rtw89_ple_qt44 = { - 0, 0, 16, 256, 0, 0, 0, 0, 0, 0, 0, 0, -}; -EXPORT_SYMBOL(rtw89_ple_qt44); - -/* DLFW 52C */ -const struct rtw89_ple_quota rtw89_ple_qt45 = { - 0, 0, 32, 256, 0, 0, 0, 0, 0, 0, 0, 0, -}; -EXPORT_SYMBOL(rtw89_ple_qt45); - -/* 8852C PCIE SCC */ -const struct rtw89_ple_quota rtw89_ple_qt46 = { - 525, 0, 16, 20, 13, 13, 178, 0, 32, 62, 8, 16, -}; -EXPORT_SYMBOL(rtw89_ple_qt46); - -/* 8852C PCIE SCC */ -const struct rtw89_ple_quota rtw89_ple_qt47 = { - 525, 0, 32, 20, 1034, 13, 1199, 0, 1053, 62, 160, 1037, +const struct rtw89_mac_size_set rtw89_mac_size = { + .hfc_preccfg_pcie = {2, 40, 0, 0, 1, 0, 0, 0}, + /* PCIE 64 */ + .wde_size0 = {RTW89_WDE_PG_64, 4095, 1,}, + /* DLFW */ + .wde_size4 = {RTW89_WDE_PG_64, 0, 4096,}, + /* 8852C DLFW */ + .wde_size18 = {RTW89_WDE_PG_64, 0, 2048,}, + /* 8852C PCIE SCC */ + .wde_size19 = {RTW89_WDE_PG_64, 3328, 0,}, + /* PCIE */ + .ple_size0 = {RTW89_PLE_PG_128, 1520, 16,}, + /* DLFW */ + .ple_size4 = {RTW89_PLE_PG_128, 64, 1472,}, + /* 8852C DLFW */ + .ple_size18 = {RTW89_PLE_PG_128, 2544, 16,}, + /* 8852C PCIE SCC */ + .ple_size19 = {RTW89_PLE_PG_128, 1904, 16,}, + /* PCIE 64 */ + .wde_qt0 = {3792, 196, 0, 107,}, + /* DLFW */ + .wde_qt4 = {0, 0, 0, 0,}, + /* 8852C DLFW */ + .wde_qt17 = {0, 0, 0, 0,}, + /* 8852C PCIE SCC */ + .wde_qt18 = {3228, 60, 0, 40,}, + /* PCIE SCC */ + .ple_qt4 = {264, 0, 16, 20, 26, 13, 356, 0, 32, 40, 8,}, + /* PCIE SCC */ + .ple_qt5 = {264, 0, 32, 20, 64, 13, 1101, 0, 64, 128, 120,}, + /* DLFW */ + .ple_qt13 = {0, 0, 16, 48, 0, 0, 0, 0, 0, 0, 0,}, + /* DLFW 52C */ + .ple_qt44 = {0, 0, 16, 256, 0, 0, 0, 0, 0, 0, 0, 0,}, + /* DLFW 52C */ + .ple_qt45 = {0, 0, 32, 256, 0, 0, 0, 0, 0, 0, 0, 0,}, + /* 8852C PCIE SCC */ + .ple_qt46 = {525, 0, 16, 20, 13, 13, 178, 0, 32, 62, 8, 16,}, + /* 8852C PCIE SCC */ + .ple_qt47 = {525, 0, 32, 20, 1034, 13, 1199, 0, 1053, 62, 160, 1037,}, }; -EXPORT_SYMBOL(rtw89_ple_qt47); +EXPORT_SYMBOL(rtw89_mac_size); static const struct rtw89_dle_mem *get_dle_mem_cfg(struct rtw89_dev *rtwdev, enum rtw89_qta_mode mode) diff --git a/drivers/net/wireless/realtek/rtw89/mac.h b/drivers/net/wireless/realtek/rtw89/mac.h index a05c504505d82..6edeb1aafaf7d 100644 --- a/drivers/net/wireless/realtek/rtw89/mac.h +++ b/drivers/net/wireless/realtek/rtw89/mac.h @@ -682,26 +682,30 @@ enum mac_ax_err_info { MAC_AX_SET_ERR_MAX, }; -extern const struct rtw89_hfc_prec_cfg rtw89_hfc_preccfg_pcie; -extern const struct rtw89_dle_size rtw89_wde_size0; -extern const struct rtw89_dle_size rtw89_wde_size4; -extern const struct rtw89_dle_size rtw89_wde_size18; -extern const struct rtw89_dle_size rtw89_wde_size19; -extern const struct rtw89_dle_size rtw89_ple_size0; -extern const struct rtw89_dle_size rtw89_ple_size4; -extern const struct rtw89_dle_size rtw89_ple_size18; -extern const struct rtw89_dle_size rtw89_ple_size19; -extern const struct rtw89_wde_quota rtw89_wde_qt0; -extern const struct rtw89_wde_quota rtw89_wde_qt4; -extern const struct rtw89_wde_quota rtw89_wde_qt17; -extern const struct rtw89_wde_quota rtw89_wde_qt18; -extern const struct rtw89_ple_quota rtw89_ple_qt4; -extern const struct rtw89_ple_quota rtw89_ple_qt5; -extern const struct rtw89_ple_quota rtw89_ple_qt13; -extern const struct rtw89_ple_quota rtw89_ple_qt44; -extern const struct rtw89_ple_quota rtw89_ple_qt45; -extern const struct rtw89_ple_quota rtw89_ple_qt46; -extern const struct rtw89_ple_quota rtw89_ple_qt47; +struct rtw89_mac_size_set { + const struct rtw89_hfc_prec_cfg hfc_preccfg_pcie; + const struct rtw89_dle_size wde_size0; + const struct rtw89_dle_size wde_size4; + const struct rtw89_dle_size wde_size18; + const struct rtw89_dle_size wde_size19; + const struct rtw89_dle_size ple_size0; + const struct rtw89_dle_size ple_size4; + const struct rtw89_dle_size ple_size18; + const struct rtw89_dle_size ple_size19; + const struct rtw89_wde_quota wde_qt0; + const struct rtw89_wde_quota wde_qt4; + const struct rtw89_wde_quota wde_qt17; + const struct rtw89_wde_quota wde_qt18; + const struct rtw89_ple_quota ple_qt4; + const struct rtw89_ple_quota ple_qt5; + const struct rtw89_ple_quota ple_qt13; + const struct rtw89_ple_quota ple_qt44; + const struct rtw89_ple_quota ple_qt45; + const struct rtw89_ple_quota ple_qt46; + const struct rtw89_ple_quota ple_qt47; +}; + +extern const struct rtw89_mac_size_set rtw89_mac_size; static inline u32 rtw89_mac_reg_by_idx(u32 reg_base, u8 band) { diff --git a/drivers/net/wireless/realtek/rtw89/rtw8852a.c b/drivers/net/wireless/realtek/rtw89/rtw8852a.c index 348ad08090b8d..67aaa05cb7511 100644 --- a/drivers/net/wireless/realtek/rtw89/rtw8852a.c +++ b/drivers/net/wireless/realtek/rtw89/rtw8852a.c @@ -37,19 +37,21 @@ static const struct rtw89_hfc_pub_cfg rtw8852a_hfc_pubcfg_pcie = { static const struct rtw89_hfc_param_ini rtw8852a_hfc_param_ini_pcie[] = { [RTW89_QTA_SCC] = {rtw8852a_hfc_chcfg_pcie, &rtw8852a_hfc_pubcfg_pcie, - &rtw89_hfc_preccfg_pcie, RTW89_HCIFC_POH}, - [RTW89_QTA_DLFW] = {NULL, NULL, &rtw89_hfc_preccfg_pcie, + &rtw89_mac_size.hfc_preccfg_pcie, RTW89_HCIFC_POH}, + [RTW89_QTA_DLFW] = {NULL, NULL, &rtw89_mac_size.hfc_preccfg_pcie, RTW89_HCIFC_POH}, [RTW89_QTA_INVALID] = {NULL}, }; static const struct rtw89_dle_mem rtw8852a_dle_mem_pcie[] = { - [RTW89_QTA_SCC] = {RTW89_QTA_SCC, &rtw89_wde_size0, &rtw89_ple_size0, - &rtw89_wde_qt0, &rtw89_wde_qt0, &rtw89_ple_qt4, - &rtw89_ple_qt5}, - [RTW89_QTA_DLFW] = {RTW89_QTA_DLFW, &rtw89_wde_size4, &rtw89_ple_size4, - &rtw89_wde_qt4, &rtw89_wde_qt4, &rtw89_ple_qt13, - &rtw89_ple_qt13}, + [RTW89_QTA_SCC] = {RTW89_QTA_SCC, &rtw89_mac_size.wde_size0, + &rtw89_mac_size.ple_size0, &rtw89_mac_size.wde_qt0, + &rtw89_mac_size.wde_qt0, &rtw89_mac_size.ple_qt4, + &rtw89_mac_size.ple_qt5}, + [RTW89_QTA_DLFW] = {RTW89_QTA_DLFW, &rtw89_mac_size.wde_size4, + &rtw89_mac_size.ple_size4, &rtw89_mac_size.wde_qt4, + &rtw89_mac_size.wde_qt4, &rtw89_mac_size.ple_qt13, + &rtw89_mac_size.ple_qt13}, [RTW89_QTA_INVALID] = {RTW89_QTA_INVALID, NULL, NULL, NULL, NULL, NULL, NULL}, }; diff --git a/drivers/net/wireless/realtek/rtw89/rtw8852c.c b/drivers/net/wireless/realtek/rtw89/rtw8852c.c index 58920e91765e8..123cc3c4318d2 100644 --- a/drivers/net/wireless/realtek/rtw89/rtw8852c.c +++ b/drivers/net/wireless/realtek/rtw89/rtw8852c.c @@ -10,12 +10,14 @@ #include "rtw8852c.h" static const struct rtw89_dle_mem rtw8852c_dle_mem_pcie[] = { - [RTW89_QTA_SCC] = {RTW89_QTA_SCC, &rtw89_wde_size19, &rtw89_ple_size19, - &rtw89_wde_qt18, &rtw89_wde_qt18, &rtw89_ple_qt46, - &rtw89_ple_qt47}, - [RTW89_QTA_DLFW] = {RTW89_QTA_DLFW, &rtw89_wde_size18, - &rtw89_ple_size18, &rtw89_wde_qt17, &rtw89_wde_qt17, - &rtw89_ple_qt44, &rtw89_ple_qt45}, + [RTW89_QTA_SCC] = {RTW89_QTA_SCC, &rtw89_mac_size.wde_size19, + &rtw89_mac_size.ple_size19, &rtw89_mac_size.wde_qt18, + &rtw89_mac_size.wde_qt18, &rtw89_mac_size.ple_qt46, + &rtw89_mac_size.ple_qt47}, + [RTW89_QTA_DLFW] = {RTW89_QTA_DLFW, &rtw89_mac_size.wde_size18, + &rtw89_mac_size.ple_size18, &rtw89_mac_size.wde_qt17, + &rtw89_mac_size.wde_qt17, &rtw89_mac_size.ple_qt44, + &rtw89_mac_size.ple_qt45}, [RTW89_QTA_INVALID] = {RTW89_QTA_INVALID, NULL, NULL, NULL, NULL, NULL, NULL}, }; From 5a0e776bec96e373940731875f9e58f9a747a6e4 Mon Sep 17 00:00:00 2001 From: Zong-Zhe Yang Date: Fri, 18 Mar 2022 10:32:04 +0800 Subject: [PATCH 059/228] rtw89: add UK to regulation type Add RTW89_UK to enum rtw89_regulation_type. The follow-up commit will configure the corresponding values for it to TX power tables. Signed-off-by: Zong-Zhe Yang Signed-off-by: Ping-Ke Shih Signed-off-by: Kalle Valo Link: https://lore.kernel.org/r/20220318023214.32411-2-pkshih@realtek.com --- drivers/net/wireless/realtek/rtw89/core.h | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/net/wireless/realtek/rtw89/core.h b/drivers/net/wireless/realtek/rtw89/core.h index 7d8140cc25a75..5900cbc0efd9e 100644 --- a/drivers/net/wireless/realtek/rtw89/core.h +++ b/drivers/net/wireless/realtek/rtw89/core.h @@ -446,6 +446,7 @@ enum rtw89_regulation_type { RTW89_UKRAINE = 11, RTW89_CN = 12, RTW89_QATAR = 13, + RTW89_UK = 14, RTW89_REGD_NUM, }; From c504bf23290c980588a19f228ffe6b37097dc460 Mon Sep 17 00:00:00 2001 From: Zong-Zhe Yang Date: Fri, 18 Mar 2022 10:32:05 +0800 Subject: [PATCH 060/228] rtw89: 8852a: update txpwr tables to HALRF_027_00_038 Update notes: TX power by rate table is not changed. TX power limit table configures values for UK. TX power limit RU table configures values for UK. Signed-off-by: Zong-Zhe Yang Signed-off-by: Ping-Ke Shih Signed-off-by: Kalle Valo Link: https://lore.kernel.org/r/20220318023214.32411-3-pkshih@realtek.com --- .../wireless/realtek/rtw89/rtw8852a_table.c | 581 ++++++++++++++++++ 1 file changed, 581 insertions(+) diff --git a/drivers/net/wireless/realtek/rtw89/rtw8852a_table.c b/drivers/net/wireless/realtek/rtw89/rtw8852a_table.c index 253b5f8fc4f93..8c4749f106411 100644 --- a/drivers/net/wireless/realtek/rtw89/rtw8852a_table.c +++ b/drivers/net/wireless/realtek/rtw89/rtw8852a_table.c @@ -43563,6 +43563,7 @@ const s8 rtw89_8852a_txpwr_lmt_2g[RTW89_2G_BW_NUM][RTW89_NTX_NUM] [0][0][0][0][RTW89_MEXICO][0] = 76, [0][0][0][0][RTW89_CN][0] = 56, [0][0][0][0][RTW89_QATAR][0] = 56, + [0][0][0][0][RTW89_UK][0] = 56, [0][0][0][0][RTW89_FCC][1] = 76, [0][0][0][0][RTW89_ETSI][1] = 56, [0][0][0][0][RTW89_MKK][1] = 68, @@ -43574,6 +43575,7 @@ const s8 rtw89_8852a_txpwr_lmt_2g[RTW89_2G_BW_NUM][RTW89_NTX_NUM] [0][0][0][0][RTW89_MEXICO][1] = 76, [0][0][0][0][RTW89_CN][1] = 56, [0][0][0][0][RTW89_QATAR][1] = 56, + [0][0][0][0][RTW89_UK][1] = 56, [0][0][0][0][RTW89_FCC][2] = 76, [0][0][0][0][RTW89_ETSI][2] = 56, [0][0][0][0][RTW89_MKK][2] = 68, @@ -43585,6 +43587,7 @@ const s8 rtw89_8852a_txpwr_lmt_2g[RTW89_2G_BW_NUM][RTW89_NTX_NUM] [0][0][0][0][RTW89_MEXICO][2] = 76, [0][0][0][0][RTW89_CN][2] = 56, [0][0][0][0][RTW89_QATAR][2] = 56, + [0][0][0][0][RTW89_UK][2] = 56, [0][0][0][0][RTW89_FCC][3] = 76, [0][0][0][0][RTW89_ETSI][3] = 56, [0][0][0][0][RTW89_MKK][3] = 68, @@ -43596,6 +43599,7 @@ const s8 rtw89_8852a_txpwr_lmt_2g[RTW89_2G_BW_NUM][RTW89_NTX_NUM] [0][0][0][0][RTW89_MEXICO][3] = 76, [0][0][0][0][RTW89_CN][3] = 56, [0][0][0][0][RTW89_QATAR][3] = 56, + [0][0][0][0][RTW89_UK][3] = 56, [0][0][0][0][RTW89_FCC][4] = 76, [0][0][0][0][RTW89_ETSI][4] = 56, [0][0][0][0][RTW89_MKK][4] = 68, @@ -43607,6 +43611,7 @@ const s8 rtw89_8852a_txpwr_lmt_2g[RTW89_2G_BW_NUM][RTW89_NTX_NUM] [0][0][0][0][RTW89_MEXICO][4] = 76, [0][0][0][0][RTW89_CN][4] = 56, [0][0][0][0][RTW89_QATAR][4] = 56, + [0][0][0][0][RTW89_UK][4] = 56, [0][0][0][0][RTW89_FCC][5] = 76, [0][0][0][0][RTW89_ETSI][5] = 56, [0][0][0][0][RTW89_MKK][5] = 68, @@ -43618,6 +43623,7 @@ const s8 rtw89_8852a_txpwr_lmt_2g[RTW89_2G_BW_NUM][RTW89_NTX_NUM] [0][0][0][0][RTW89_MEXICO][5] = 76, [0][0][0][0][RTW89_CN][5] = 56, [0][0][0][0][RTW89_QATAR][5] = 56, + [0][0][0][0][RTW89_UK][5] = 56, [0][0][0][0][RTW89_FCC][6] = 76, [0][0][0][0][RTW89_ETSI][6] = 56, [0][0][0][0][RTW89_MKK][6] = 68, @@ -43629,6 +43635,7 @@ const s8 rtw89_8852a_txpwr_lmt_2g[RTW89_2G_BW_NUM][RTW89_NTX_NUM] [0][0][0][0][RTW89_MEXICO][6] = 76, [0][0][0][0][RTW89_CN][6] = 56, [0][0][0][0][RTW89_QATAR][6] = 56, + [0][0][0][0][RTW89_UK][6] = 56, [0][0][0][0][RTW89_FCC][7] = 76, [0][0][0][0][RTW89_ETSI][7] = 56, [0][0][0][0][RTW89_MKK][7] = 68, @@ -43640,6 +43647,7 @@ const s8 rtw89_8852a_txpwr_lmt_2g[RTW89_2G_BW_NUM][RTW89_NTX_NUM] [0][0][0][0][RTW89_MEXICO][7] = 76, [0][0][0][0][RTW89_CN][7] = 56, [0][0][0][0][RTW89_QATAR][7] = 56, + [0][0][0][0][RTW89_UK][7] = 56, [0][0][0][0][RTW89_FCC][8] = 76, [0][0][0][0][RTW89_ETSI][8] = 56, [0][0][0][0][RTW89_MKK][8] = 68, @@ -43651,6 +43659,7 @@ const s8 rtw89_8852a_txpwr_lmt_2g[RTW89_2G_BW_NUM][RTW89_NTX_NUM] [0][0][0][0][RTW89_MEXICO][8] = 76, [0][0][0][0][RTW89_CN][8] = 56, [0][0][0][0][RTW89_QATAR][8] = 56, + [0][0][0][0][RTW89_UK][8] = 56, [0][0][0][0][RTW89_FCC][9] = 76, [0][0][0][0][RTW89_ETSI][9] = 56, [0][0][0][0][RTW89_MKK][9] = 68, @@ -43662,6 +43671,7 @@ const s8 rtw89_8852a_txpwr_lmt_2g[RTW89_2G_BW_NUM][RTW89_NTX_NUM] [0][0][0][0][RTW89_MEXICO][9] = 76, [0][0][0][0][RTW89_CN][9] = 56, [0][0][0][0][RTW89_QATAR][9] = 56, + [0][0][0][0][RTW89_UK][9] = 56, [0][0][0][0][RTW89_FCC][10] = 76, [0][0][0][0][RTW89_ETSI][10] = 56, [0][0][0][0][RTW89_MKK][10] = 68, @@ -43673,6 +43683,7 @@ const s8 rtw89_8852a_txpwr_lmt_2g[RTW89_2G_BW_NUM][RTW89_NTX_NUM] [0][0][0][0][RTW89_MEXICO][10] = 76, [0][0][0][0][RTW89_CN][10] = 56, [0][0][0][0][RTW89_QATAR][10] = 56, + [0][0][0][0][RTW89_UK][10] = 56, [0][0][0][0][RTW89_FCC][11] = 68, [0][0][0][0][RTW89_ETSI][11] = 56, [0][0][0][0][RTW89_MKK][11] = 68, @@ -43684,6 +43695,7 @@ const s8 rtw89_8852a_txpwr_lmt_2g[RTW89_2G_BW_NUM][RTW89_NTX_NUM] [0][0][0][0][RTW89_MEXICO][11] = 68, [0][0][0][0][RTW89_CN][11] = 56, [0][0][0][0][RTW89_QATAR][11] = 56, + [0][0][0][0][RTW89_UK][11] = 56, [0][0][0][0][RTW89_FCC][12] = 48, [0][0][0][0][RTW89_ETSI][12] = 56, [0][0][0][0][RTW89_MKK][12] = 68, @@ -43695,6 +43707,7 @@ const s8 rtw89_8852a_txpwr_lmt_2g[RTW89_2G_BW_NUM][RTW89_NTX_NUM] [0][0][0][0][RTW89_MEXICO][12] = 48, [0][0][0][0][RTW89_CN][12] = 56, [0][0][0][0][RTW89_QATAR][12] = 56, + [0][0][0][0][RTW89_UK][12] = 56, [0][0][0][0][RTW89_FCC][13] = 127, [0][0][0][0][RTW89_ETSI][13] = 127, [0][0][0][0][RTW89_MKK][13] = 76, @@ -43706,6 +43719,7 @@ const s8 rtw89_8852a_txpwr_lmt_2g[RTW89_2G_BW_NUM][RTW89_NTX_NUM] [0][0][0][0][RTW89_MEXICO][13] = 127, [0][0][0][0][RTW89_CN][13] = 127, [0][0][0][0][RTW89_QATAR][13] = 127, + [0][0][0][0][RTW89_UK][13] = 127, [0][1][0][0][RTW89_FCC][0] = 74, [0][1][0][0][RTW89_ETSI][0] = 44, [0][1][0][0][RTW89_MKK][0] = 56, @@ -43717,6 +43731,7 @@ const s8 rtw89_8852a_txpwr_lmt_2g[RTW89_2G_BW_NUM][RTW89_NTX_NUM] [0][1][0][0][RTW89_MEXICO][0] = 74, [0][1][0][0][RTW89_CN][0] = 44, [0][1][0][0][RTW89_QATAR][0] = 44, + [0][1][0][0][RTW89_UK][0] = 44, [0][1][0][0][RTW89_FCC][1] = 76, [0][1][0][0][RTW89_ETSI][1] = 44, [0][1][0][0][RTW89_MKK][1] = 56, @@ -43728,6 +43743,7 @@ const s8 rtw89_8852a_txpwr_lmt_2g[RTW89_2G_BW_NUM][RTW89_NTX_NUM] [0][1][0][0][RTW89_MEXICO][1] = 76, [0][1][0][0][RTW89_CN][1] = 44, [0][1][0][0][RTW89_QATAR][1] = 44, + [0][1][0][0][RTW89_UK][1] = 44, [0][1][0][0][RTW89_FCC][2] = 76, [0][1][0][0][RTW89_ETSI][2] = 44, [0][1][0][0][RTW89_MKK][2] = 56, @@ -43739,6 +43755,7 @@ const s8 rtw89_8852a_txpwr_lmt_2g[RTW89_2G_BW_NUM][RTW89_NTX_NUM] [0][1][0][0][RTW89_MEXICO][2] = 76, [0][1][0][0][RTW89_CN][2] = 44, [0][1][0][0][RTW89_QATAR][2] = 44, + [0][1][0][0][RTW89_UK][2] = 44, [0][1][0][0][RTW89_FCC][3] = 76, [0][1][0][0][RTW89_ETSI][3] = 44, [0][1][0][0][RTW89_MKK][3] = 56, @@ -43750,6 +43767,7 @@ const s8 rtw89_8852a_txpwr_lmt_2g[RTW89_2G_BW_NUM][RTW89_NTX_NUM] [0][1][0][0][RTW89_MEXICO][3] = 76, [0][1][0][0][RTW89_CN][3] = 44, [0][1][0][0][RTW89_QATAR][3] = 44, + [0][1][0][0][RTW89_UK][3] = 44, [0][1][0][0][RTW89_FCC][4] = 76, [0][1][0][0][RTW89_ETSI][4] = 44, [0][1][0][0][RTW89_MKK][4] = 56, @@ -43761,6 +43779,7 @@ const s8 rtw89_8852a_txpwr_lmt_2g[RTW89_2G_BW_NUM][RTW89_NTX_NUM] [0][1][0][0][RTW89_MEXICO][4] = 76, [0][1][0][0][RTW89_CN][4] = 44, [0][1][0][0][RTW89_QATAR][4] = 44, + [0][1][0][0][RTW89_UK][4] = 44, [0][1][0][0][RTW89_FCC][5] = 76, [0][1][0][0][RTW89_ETSI][5] = 44, [0][1][0][0][RTW89_MKK][5] = 56, @@ -43772,6 +43791,7 @@ const s8 rtw89_8852a_txpwr_lmt_2g[RTW89_2G_BW_NUM][RTW89_NTX_NUM] [0][1][0][0][RTW89_MEXICO][5] = 76, [0][1][0][0][RTW89_CN][5] = 44, [0][1][0][0][RTW89_QATAR][5] = 44, + [0][1][0][0][RTW89_UK][5] = 44, [0][1][0][0][RTW89_FCC][6] = 76, [0][1][0][0][RTW89_ETSI][6] = 44, [0][1][0][0][RTW89_MKK][6] = 56, @@ -43783,6 +43803,7 @@ const s8 rtw89_8852a_txpwr_lmt_2g[RTW89_2G_BW_NUM][RTW89_NTX_NUM] [0][1][0][0][RTW89_MEXICO][6] = 76, [0][1][0][0][RTW89_CN][6] = 44, [0][1][0][0][RTW89_QATAR][6] = 44, + [0][1][0][0][RTW89_UK][6] = 44, [0][1][0][0][RTW89_FCC][7] = 76, [0][1][0][0][RTW89_ETSI][7] = 44, [0][1][0][0][RTW89_MKK][7] = 56, @@ -43794,6 +43815,7 @@ const s8 rtw89_8852a_txpwr_lmt_2g[RTW89_2G_BW_NUM][RTW89_NTX_NUM] [0][1][0][0][RTW89_MEXICO][7] = 76, [0][1][0][0][RTW89_CN][7] = 44, [0][1][0][0][RTW89_QATAR][7] = 44, + [0][1][0][0][RTW89_UK][7] = 44, [0][1][0][0][RTW89_FCC][8] = 76, [0][1][0][0][RTW89_ETSI][8] = 44, [0][1][0][0][RTW89_MKK][8] = 56, @@ -43805,6 +43827,7 @@ const s8 rtw89_8852a_txpwr_lmt_2g[RTW89_2G_BW_NUM][RTW89_NTX_NUM] [0][1][0][0][RTW89_MEXICO][8] = 76, [0][1][0][0][RTW89_CN][8] = 44, [0][1][0][0][RTW89_QATAR][8] = 44, + [0][1][0][0][RTW89_UK][8] = 44, [0][1][0][0][RTW89_FCC][9] = 76, [0][1][0][0][RTW89_ETSI][9] = 44, [0][1][0][0][RTW89_MKK][9] = 56, @@ -43816,6 +43839,7 @@ const s8 rtw89_8852a_txpwr_lmt_2g[RTW89_2G_BW_NUM][RTW89_NTX_NUM] [0][1][0][0][RTW89_MEXICO][9] = 76, [0][1][0][0][RTW89_CN][9] = 44, [0][1][0][0][RTW89_QATAR][9] = 44, + [0][1][0][0][RTW89_UK][9] = 44, [0][1][0][0][RTW89_FCC][10] = 62, [0][1][0][0][RTW89_ETSI][10] = 44, [0][1][0][0][RTW89_MKK][10] = 56, @@ -43827,6 +43851,7 @@ const s8 rtw89_8852a_txpwr_lmt_2g[RTW89_2G_BW_NUM][RTW89_NTX_NUM] [0][1][0][0][RTW89_MEXICO][10] = 62, [0][1][0][0][RTW89_CN][10] = 44, [0][1][0][0][RTW89_QATAR][10] = 44, + [0][1][0][0][RTW89_UK][10] = 44, [0][1][0][0][RTW89_FCC][11] = 52, [0][1][0][0][RTW89_ETSI][11] = 44, [0][1][0][0][RTW89_MKK][11] = 56, @@ -43838,6 +43863,7 @@ const s8 rtw89_8852a_txpwr_lmt_2g[RTW89_2G_BW_NUM][RTW89_NTX_NUM] [0][1][0][0][RTW89_MEXICO][11] = 52, [0][1][0][0][RTW89_CN][11] = 44, [0][1][0][0][RTW89_QATAR][11] = 44, + [0][1][0][0][RTW89_UK][11] = 44, [0][1][0][0][RTW89_FCC][12] = 38, [0][1][0][0][RTW89_ETSI][12] = 44, [0][1][0][0][RTW89_MKK][12] = 56, @@ -43849,6 +43875,7 @@ const s8 rtw89_8852a_txpwr_lmt_2g[RTW89_2G_BW_NUM][RTW89_NTX_NUM] [0][1][0][0][RTW89_MEXICO][12] = 38, [0][1][0][0][RTW89_CN][12] = 44, [0][1][0][0][RTW89_QATAR][12] = 44, + [0][1][0][0][RTW89_UK][12] = 44, [0][1][0][0][RTW89_FCC][13] = 127, [0][1][0][0][RTW89_ETSI][13] = 127, [0][1][0][0][RTW89_MKK][13] = 64, @@ -43860,6 +43887,7 @@ const s8 rtw89_8852a_txpwr_lmt_2g[RTW89_2G_BW_NUM][RTW89_NTX_NUM] [0][1][0][0][RTW89_MEXICO][13] = 127, [0][1][0][0][RTW89_CN][13] = 127, [0][1][0][0][RTW89_QATAR][13] = 127, + [0][1][0][0][RTW89_UK][13] = 127, [1][0][0][0][RTW89_FCC][0] = 127, [1][0][0][0][RTW89_ETSI][0] = 127, [1][0][0][0][RTW89_MKK][0] = 127, @@ -43871,6 +43899,7 @@ const s8 rtw89_8852a_txpwr_lmt_2g[RTW89_2G_BW_NUM][RTW89_NTX_NUM] [1][0][0][0][RTW89_MEXICO][0] = 127, [1][0][0][0][RTW89_CN][0] = 127, [1][0][0][0][RTW89_QATAR][0] = 127, + [1][0][0][0][RTW89_UK][0] = 127, [1][0][0][0][RTW89_FCC][1] = 127, [1][0][0][0][RTW89_ETSI][1] = 127, [1][0][0][0][RTW89_MKK][1] = 127, @@ -43882,6 +43911,7 @@ const s8 rtw89_8852a_txpwr_lmt_2g[RTW89_2G_BW_NUM][RTW89_NTX_NUM] [1][0][0][0][RTW89_MEXICO][1] = 127, [1][0][0][0][RTW89_CN][1] = 127, [1][0][0][0][RTW89_QATAR][1] = 127, + [1][0][0][0][RTW89_UK][1] = 127, [1][0][0][0][RTW89_FCC][2] = 60, [1][0][0][0][RTW89_ETSI][2] = 58, [1][0][0][0][RTW89_MKK][2] = 68, @@ -43893,6 +43923,7 @@ const s8 rtw89_8852a_txpwr_lmt_2g[RTW89_2G_BW_NUM][RTW89_NTX_NUM] [1][0][0][0][RTW89_MEXICO][2] = 60, [1][0][0][0][RTW89_CN][2] = 58, [1][0][0][0][RTW89_QATAR][2] = 58, + [1][0][0][0][RTW89_UK][2] = 58, [1][0][0][0][RTW89_FCC][3] = 60, [1][0][0][0][RTW89_ETSI][3] = 58, [1][0][0][0][RTW89_MKK][3] = 68, @@ -43904,6 +43935,7 @@ const s8 rtw89_8852a_txpwr_lmt_2g[RTW89_2G_BW_NUM][RTW89_NTX_NUM] [1][0][0][0][RTW89_MEXICO][3] = 60, [1][0][0][0][RTW89_CN][3] = 58, [1][0][0][0][RTW89_QATAR][3] = 58, + [1][0][0][0][RTW89_UK][3] = 58, [1][0][0][0][RTW89_FCC][4] = 60, [1][0][0][0][RTW89_ETSI][4] = 58, [1][0][0][0][RTW89_MKK][4] = 68, @@ -43915,6 +43947,7 @@ const s8 rtw89_8852a_txpwr_lmt_2g[RTW89_2G_BW_NUM][RTW89_NTX_NUM] [1][0][0][0][RTW89_MEXICO][4] = 60, [1][0][0][0][RTW89_CN][4] = 58, [1][0][0][0][RTW89_QATAR][4] = 58, + [1][0][0][0][RTW89_UK][4] = 58, [1][0][0][0][RTW89_FCC][5] = 60, [1][0][0][0][RTW89_ETSI][5] = 58, [1][0][0][0][RTW89_MKK][5] = 68, @@ -43926,6 +43959,7 @@ const s8 rtw89_8852a_txpwr_lmt_2g[RTW89_2G_BW_NUM][RTW89_NTX_NUM] [1][0][0][0][RTW89_MEXICO][5] = 60, [1][0][0][0][RTW89_CN][5] = 58, [1][0][0][0][RTW89_QATAR][5] = 58, + [1][0][0][0][RTW89_UK][5] = 58, [1][0][0][0][RTW89_FCC][6] = 46, [1][0][0][0][RTW89_ETSI][6] = 58, [1][0][0][0][RTW89_MKK][6] = 68, @@ -43937,6 +43971,7 @@ const s8 rtw89_8852a_txpwr_lmt_2g[RTW89_2G_BW_NUM][RTW89_NTX_NUM] [1][0][0][0][RTW89_MEXICO][6] = 46, [1][0][0][0][RTW89_CN][6] = 58, [1][0][0][0][RTW89_QATAR][6] = 58, + [1][0][0][0][RTW89_UK][6] = 58, [1][0][0][0][RTW89_FCC][7] = 46, [1][0][0][0][RTW89_ETSI][7] = 58, [1][0][0][0][RTW89_MKK][7] = 68, @@ -43948,6 +43983,7 @@ const s8 rtw89_8852a_txpwr_lmt_2g[RTW89_2G_BW_NUM][RTW89_NTX_NUM] [1][0][0][0][RTW89_MEXICO][7] = 46, [1][0][0][0][RTW89_CN][7] = 58, [1][0][0][0][RTW89_QATAR][7] = 58, + [1][0][0][0][RTW89_UK][7] = 58, [1][0][0][0][RTW89_FCC][8] = 46, [1][0][0][0][RTW89_ETSI][8] = 58, [1][0][0][0][RTW89_MKK][8] = 68, @@ -43959,6 +43995,7 @@ const s8 rtw89_8852a_txpwr_lmt_2g[RTW89_2G_BW_NUM][RTW89_NTX_NUM] [1][0][0][0][RTW89_MEXICO][8] = 46, [1][0][0][0][RTW89_CN][8] = 58, [1][0][0][0][RTW89_QATAR][8] = 58, + [1][0][0][0][RTW89_UK][8] = 58, [1][0][0][0][RTW89_FCC][9] = 32, [1][0][0][0][RTW89_ETSI][9] = 58, [1][0][0][0][RTW89_MKK][9] = 68, @@ -43970,6 +44007,7 @@ const s8 rtw89_8852a_txpwr_lmt_2g[RTW89_2G_BW_NUM][RTW89_NTX_NUM] [1][0][0][0][RTW89_MEXICO][9] = 32, [1][0][0][0][RTW89_CN][9] = 58, [1][0][0][0][RTW89_QATAR][9] = 58, + [1][0][0][0][RTW89_UK][9] = 58, [1][0][0][0][RTW89_FCC][10] = 32, [1][0][0][0][RTW89_ETSI][10] = 58, [1][0][0][0][RTW89_MKK][10] = 68, @@ -43981,6 +44019,7 @@ const s8 rtw89_8852a_txpwr_lmt_2g[RTW89_2G_BW_NUM][RTW89_NTX_NUM] [1][0][0][0][RTW89_MEXICO][10] = 32, [1][0][0][0][RTW89_CN][10] = 58, [1][0][0][0][RTW89_QATAR][10] = 58, + [1][0][0][0][RTW89_UK][10] = 58, [1][0][0][0][RTW89_FCC][11] = 127, [1][0][0][0][RTW89_ETSI][11] = 127, [1][0][0][0][RTW89_MKK][11] = 127, @@ -43992,6 +44031,7 @@ const s8 rtw89_8852a_txpwr_lmt_2g[RTW89_2G_BW_NUM][RTW89_NTX_NUM] [1][0][0][0][RTW89_MEXICO][11] = 127, [1][0][0][0][RTW89_CN][11] = 127, [1][0][0][0][RTW89_QATAR][11] = 127, + [1][0][0][0][RTW89_UK][11] = 127, [1][0][0][0][RTW89_FCC][12] = 127, [1][0][0][0][RTW89_ETSI][12] = 127, [1][0][0][0][RTW89_MKK][12] = 127, @@ -44003,6 +44043,7 @@ const s8 rtw89_8852a_txpwr_lmt_2g[RTW89_2G_BW_NUM][RTW89_NTX_NUM] [1][0][0][0][RTW89_MEXICO][12] = 127, [1][0][0][0][RTW89_CN][12] = 127, [1][0][0][0][RTW89_QATAR][12] = 127, + [1][0][0][0][RTW89_UK][12] = 127, [1][0][0][0][RTW89_FCC][13] = 127, [1][0][0][0][RTW89_ETSI][13] = 127, [1][0][0][0][RTW89_MKK][13] = 127, @@ -44014,6 +44055,7 @@ const s8 rtw89_8852a_txpwr_lmt_2g[RTW89_2G_BW_NUM][RTW89_NTX_NUM] [1][0][0][0][RTW89_MEXICO][13] = 127, [1][0][0][0][RTW89_CN][13] = 127, [1][0][0][0][RTW89_QATAR][13] = 127, + [1][0][0][0][RTW89_UK][13] = 127, [1][1][0][0][RTW89_FCC][0] = 127, [1][1][0][0][RTW89_ETSI][0] = 127, [1][1][0][0][RTW89_MKK][0] = 127, @@ -44025,6 +44067,7 @@ const s8 rtw89_8852a_txpwr_lmt_2g[RTW89_2G_BW_NUM][RTW89_NTX_NUM] [1][1][0][0][RTW89_MEXICO][0] = 127, [1][1][0][0][RTW89_CN][0] = 127, [1][1][0][0][RTW89_QATAR][0] = 127, + [1][1][0][0][RTW89_UK][0] = 127, [1][1][0][0][RTW89_FCC][1] = 127, [1][1][0][0][RTW89_ETSI][1] = 127, [1][1][0][0][RTW89_MKK][1] = 127, @@ -44036,6 +44079,7 @@ const s8 rtw89_8852a_txpwr_lmt_2g[RTW89_2G_BW_NUM][RTW89_NTX_NUM] [1][1][0][0][RTW89_MEXICO][1] = 127, [1][1][0][0][RTW89_CN][1] = 127, [1][1][0][0][RTW89_QATAR][1] = 127, + [1][1][0][0][RTW89_UK][1] = 127, [1][1][0][0][RTW89_FCC][2] = 48, [1][1][0][0][RTW89_ETSI][2] = 46, [1][1][0][0][RTW89_MKK][2] = 56, @@ -44047,6 +44091,7 @@ const s8 rtw89_8852a_txpwr_lmt_2g[RTW89_2G_BW_NUM][RTW89_NTX_NUM] [1][1][0][0][RTW89_MEXICO][2] = 48, [1][1][0][0][RTW89_CN][2] = 46, [1][1][0][0][RTW89_QATAR][2] = 46, + [1][1][0][0][RTW89_UK][2] = 46, [1][1][0][0][RTW89_FCC][3] = 48, [1][1][0][0][RTW89_ETSI][3] = 46, [1][1][0][0][RTW89_MKK][3] = 56, @@ -44058,6 +44103,7 @@ const s8 rtw89_8852a_txpwr_lmt_2g[RTW89_2G_BW_NUM][RTW89_NTX_NUM] [1][1][0][0][RTW89_MEXICO][3] = 48, [1][1][0][0][RTW89_CN][3] = 46, [1][1][0][0][RTW89_QATAR][3] = 46, + [1][1][0][0][RTW89_UK][3] = 46, [1][1][0][0][RTW89_FCC][4] = 48, [1][1][0][0][RTW89_ETSI][4] = 46, [1][1][0][0][RTW89_MKK][4] = 56, @@ -44069,6 +44115,7 @@ const s8 rtw89_8852a_txpwr_lmt_2g[RTW89_2G_BW_NUM][RTW89_NTX_NUM] [1][1][0][0][RTW89_MEXICO][4] = 48, [1][1][0][0][RTW89_CN][4] = 46, [1][1][0][0][RTW89_QATAR][4] = 46, + [1][1][0][0][RTW89_UK][4] = 46, [1][1][0][0][RTW89_FCC][5] = 58, [1][1][0][0][RTW89_ETSI][5] = 46, [1][1][0][0][RTW89_MKK][5] = 56, @@ -44080,6 +44127,7 @@ const s8 rtw89_8852a_txpwr_lmt_2g[RTW89_2G_BW_NUM][RTW89_NTX_NUM] [1][1][0][0][RTW89_MEXICO][5] = 58, [1][1][0][0][RTW89_CN][5] = 46, [1][1][0][0][RTW89_QATAR][5] = 46, + [1][1][0][0][RTW89_UK][5] = 46, [1][1][0][0][RTW89_FCC][6] = 46, [1][1][0][0][RTW89_ETSI][6] = 46, [1][1][0][0][RTW89_MKK][6] = 56, @@ -44091,6 +44139,7 @@ const s8 rtw89_8852a_txpwr_lmt_2g[RTW89_2G_BW_NUM][RTW89_NTX_NUM] [1][1][0][0][RTW89_MEXICO][6] = 46, [1][1][0][0][RTW89_CN][6] = 46, [1][1][0][0][RTW89_QATAR][6] = 46, + [1][1][0][0][RTW89_UK][6] = 46, [1][1][0][0][RTW89_FCC][7] = 46, [1][1][0][0][RTW89_ETSI][7] = 46, [1][1][0][0][RTW89_MKK][7] = 56, @@ -44102,6 +44151,7 @@ const s8 rtw89_8852a_txpwr_lmt_2g[RTW89_2G_BW_NUM][RTW89_NTX_NUM] [1][1][0][0][RTW89_MEXICO][7] = 46, [1][1][0][0][RTW89_CN][7] = 46, [1][1][0][0][RTW89_QATAR][7] = 46, + [1][1][0][0][RTW89_UK][7] = 46, [1][1][0][0][RTW89_FCC][8] = 46, [1][1][0][0][RTW89_ETSI][8] = 46, [1][1][0][0][RTW89_MKK][8] = 56, @@ -44113,6 +44163,7 @@ const s8 rtw89_8852a_txpwr_lmt_2g[RTW89_2G_BW_NUM][RTW89_NTX_NUM] [1][1][0][0][RTW89_MEXICO][8] = 46, [1][1][0][0][RTW89_CN][8] = 46, [1][1][0][0][RTW89_QATAR][8] = 46, + [1][1][0][0][RTW89_UK][8] = 46, [1][1][0][0][RTW89_FCC][9] = 24, [1][1][0][0][RTW89_ETSI][9] = 46, [1][1][0][0][RTW89_MKK][9] = 56, @@ -44124,6 +44175,7 @@ const s8 rtw89_8852a_txpwr_lmt_2g[RTW89_2G_BW_NUM][RTW89_NTX_NUM] [1][1][0][0][RTW89_MEXICO][9] = 24, [1][1][0][0][RTW89_CN][9] = 46, [1][1][0][0][RTW89_QATAR][9] = 46, + [1][1][0][0][RTW89_UK][9] = 46, [1][1][0][0][RTW89_FCC][10] = 24, [1][1][0][0][RTW89_ETSI][10] = 46, [1][1][0][0][RTW89_MKK][10] = 56, @@ -44135,6 +44187,7 @@ const s8 rtw89_8852a_txpwr_lmt_2g[RTW89_2G_BW_NUM][RTW89_NTX_NUM] [1][1][0][0][RTW89_MEXICO][10] = 24, [1][1][0][0][RTW89_CN][10] = 46, [1][1][0][0][RTW89_QATAR][10] = 46, + [1][1][0][0][RTW89_UK][10] = 46, [1][1][0][0][RTW89_FCC][11] = 127, [1][1][0][0][RTW89_ETSI][11] = 127, [1][1][0][0][RTW89_MKK][11] = 127, @@ -44146,6 +44199,7 @@ const s8 rtw89_8852a_txpwr_lmt_2g[RTW89_2G_BW_NUM][RTW89_NTX_NUM] [1][1][0][0][RTW89_MEXICO][11] = 127, [1][1][0][0][RTW89_CN][11] = 127, [1][1][0][0][RTW89_QATAR][11] = 127, + [1][1][0][0][RTW89_UK][11] = 127, [1][1][0][0][RTW89_FCC][12] = 127, [1][1][0][0][RTW89_ETSI][12] = 127, [1][1][0][0][RTW89_MKK][12] = 127, @@ -44157,6 +44211,7 @@ const s8 rtw89_8852a_txpwr_lmt_2g[RTW89_2G_BW_NUM][RTW89_NTX_NUM] [1][1][0][0][RTW89_MEXICO][12] = 127, [1][1][0][0][RTW89_CN][12] = 127, [1][1][0][0][RTW89_QATAR][12] = 127, + [1][1][0][0][RTW89_UK][12] = 127, [1][1][0][0][RTW89_FCC][13] = 127, [1][1][0][0][RTW89_ETSI][13] = 127, [1][1][0][0][RTW89_MKK][13] = 127, @@ -44168,6 +44223,7 @@ const s8 rtw89_8852a_txpwr_lmt_2g[RTW89_2G_BW_NUM][RTW89_NTX_NUM] [1][1][0][0][RTW89_MEXICO][13] = 127, [1][1][0][0][RTW89_CN][13] = 127, [1][1][0][0][RTW89_QATAR][13] = 127, + [1][1][0][0][RTW89_UK][13] = 127, [0][0][1][0][RTW89_FCC][0] = 66, [0][0][1][0][RTW89_ETSI][0] = 58, [0][0][1][0][RTW89_MKK][0] = 76, @@ -44179,6 +44235,7 @@ const s8 rtw89_8852a_txpwr_lmt_2g[RTW89_2G_BW_NUM][RTW89_NTX_NUM] [0][0][1][0][RTW89_MEXICO][0] = 66, [0][0][1][0][RTW89_CN][0] = 58, [0][0][1][0][RTW89_QATAR][0] = 58, + [0][0][1][0][RTW89_UK][0] = 58, [0][0][1][0][RTW89_FCC][1] = 66, [0][0][1][0][RTW89_ETSI][1] = 58, [0][0][1][0][RTW89_MKK][1] = 76, @@ -44190,6 +44247,7 @@ const s8 rtw89_8852a_txpwr_lmt_2g[RTW89_2G_BW_NUM][RTW89_NTX_NUM] [0][0][1][0][RTW89_MEXICO][1] = 66, [0][0][1][0][RTW89_CN][1] = 58, [0][0][1][0][RTW89_QATAR][1] = 58, + [0][0][1][0][RTW89_UK][1] = 58, [0][0][1][0][RTW89_FCC][2] = 70, [0][0][1][0][RTW89_ETSI][2] = 58, [0][0][1][0][RTW89_MKK][2] = 76, @@ -44201,6 +44259,7 @@ const s8 rtw89_8852a_txpwr_lmt_2g[RTW89_2G_BW_NUM][RTW89_NTX_NUM] [0][0][1][0][RTW89_MEXICO][2] = 70, [0][0][1][0][RTW89_CN][2] = 58, [0][0][1][0][RTW89_QATAR][2] = 58, + [0][0][1][0][RTW89_UK][2] = 58, [0][0][1][0][RTW89_FCC][3] = 74, [0][0][1][0][RTW89_ETSI][3] = 58, [0][0][1][0][RTW89_MKK][3] = 76, @@ -44212,6 +44271,7 @@ const s8 rtw89_8852a_txpwr_lmt_2g[RTW89_2G_BW_NUM][RTW89_NTX_NUM] [0][0][1][0][RTW89_MEXICO][3] = 74, [0][0][1][0][RTW89_CN][3] = 58, [0][0][1][0][RTW89_QATAR][3] = 58, + [0][0][1][0][RTW89_UK][3] = 58, [0][0][1][0][RTW89_FCC][4] = 78, [0][0][1][0][RTW89_ETSI][4] = 58, [0][0][1][0][RTW89_MKK][4] = 76, @@ -44223,6 +44283,7 @@ const s8 rtw89_8852a_txpwr_lmt_2g[RTW89_2G_BW_NUM][RTW89_NTX_NUM] [0][0][1][0][RTW89_MEXICO][4] = 78, [0][0][1][0][RTW89_CN][4] = 58, [0][0][1][0][RTW89_QATAR][4] = 58, + [0][0][1][0][RTW89_UK][4] = 58, [0][0][1][0][RTW89_FCC][5] = 78, [0][0][1][0][RTW89_ETSI][5] = 58, [0][0][1][0][RTW89_MKK][5] = 76, @@ -44234,6 +44295,7 @@ const s8 rtw89_8852a_txpwr_lmt_2g[RTW89_2G_BW_NUM][RTW89_NTX_NUM] [0][0][1][0][RTW89_MEXICO][5] = 78, [0][0][1][0][RTW89_CN][5] = 58, [0][0][1][0][RTW89_QATAR][5] = 58, + [0][0][1][0][RTW89_UK][5] = 58, [0][0][1][0][RTW89_FCC][6] = 78, [0][0][1][0][RTW89_ETSI][6] = 58, [0][0][1][0][RTW89_MKK][6] = 76, @@ -44245,6 +44307,7 @@ const s8 rtw89_8852a_txpwr_lmt_2g[RTW89_2G_BW_NUM][RTW89_NTX_NUM] [0][0][1][0][RTW89_MEXICO][6] = 78, [0][0][1][0][RTW89_CN][6] = 58, [0][0][1][0][RTW89_QATAR][6] = 58, + [0][0][1][0][RTW89_UK][6] = 58, [0][0][1][0][RTW89_FCC][7] = 74, [0][0][1][0][RTW89_ETSI][7] = 58, [0][0][1][0][RTW89_MKK][7] = 76, @@ -44256,6 +44319,7 @@ const s8 rtw89_8852a_txpwr_lmt_2g[RTW89_2G_BW_NUM][RTW89_NTX_NUM] [0][0][1][0][RTW89_MEXICO][7] = 74, [0][0][1][0][RTW89_CN][7] = 58, [0][0][1][0][RTW89_QATAR][7] = 58, + [0][0][1][0][RTW89_UK][7] = 58, [0][0][1][0][RTW89_FCC][8] = 70, [0][0][1][0][RTW89_ETSI][8] = 58, [0][0][1][0][RTW89_MKK][8] = 76, @@ -44267,6 +44331,7 @@ const s8 rtw89_8852a_txpwr_lmt_2g[RTW89_2G_BW_NUM][RTW89_NTX_NUM] [0][0][1][0][RTW89_MEXICO][8] = 70, [0][0][1][0][RTW89_CN][8] = 58, [0][0][1][0][RTW89_QATAR][8] = 58, + [0][0][1][0][RTW89_UK][8] = 58, [0][0][1][0][RTW89_FCC][9] = 66, [0][0][1][0][RTW89_ETSI][9] = 58, [0][0][1][0][RTW89_MKK][9] = 76, @@ -44278,6 +44343,7 @@ const s8 rtw89_8852a_txpwr_lmt_2g[RTW89_2G_BW_NUM][RTW89_NTX_NUM] [0][0][1][0][RTW89_MEXICO][9] = 66, [0][0][1][0][RTW89_CN][9] = 58, [0][0][1][0][RTW89_QATAR][9] = 58, + [0][0][1][0][RTW89_UK][9] = 58, [0][0][1][0][RTW89_FCC][10] = 66, [0][0][1][0][RTW89_ETSI][10] = 58, [0][0][1][0][RTW89_MKK][10] = 76, @@ -44289,6 +44355,7 @@ const s8 rtw89_8852a_txpwr_lmt_2g[RTW89_2G_BW_NUM][RTW89_NTX_NUM] [0][0][1][0][RTW89_MEXICO][10] = 66, [0][0][1][0][RTW89_CN][10] = 58, [0][0][1][0][RTW89_QATAR][10] = 58, + [0][0][1][0][RTW89_UK][10] = 58, [0][0][1][0][RTW89_FCC][11] = 56, [0][0][1][0][RTW89_ETSI][11] = 58, [0][0][1][0][RTW89_MKK][11] = 76, @@ -44300,6 +44367,7 @@ const s8 rtw89_8852a_txpwr_lmt_2g[RTW89_2G_BW_NUM][RTW89_NTX_NUM] [0][0][1][0][RTW89_MEXICO][11] = 56, [0][0][1][0][RTW89_CN][11] = 58, [0][0][1][0][RTW89_QATAR][11] = 58, + [0][0][1][0][RTW89_UK][11] = 58, [0][0][1][0][RTW89_FCC][12] = 52, [0][0][1][0][RTW89_ETSI][12] = 58, [0][0][1][0][RTW89_MKK][12] = 76, @@ -44311,6 +44379,7 @@ const s8 rtw89_8852a_txpwr_lmt_2g[RTW89_2G_BW_NUM][RTW89_NTX_NUM] [0][0][1][0][RTW89_MEXICO][12] = 52, [0][0][1][0][RTW89_CN][12] = 58, [0][0][1][0][RTW89_QATAR][12] = 58, + [0][0][1][0][RTW89_UK][12] = 58, [0][0][1][0][RTW89_FCC][13] = 127, [0][0][1][0][RTW89_ETSI][13] = 127, [0][0][1][0][RTW89_MKK][13] = 127, @@ -44322,6 +44391,7 @@ const s8 rtw89_8852a_txpwr_lmt_2g[RTW89_2G_BW_NUM][RTW89_NTX_NUM] [0][0][1][0][RTW89_MEXICO][13] = 127, [0][0][1][0][RTW89_CN][13] = 127, [0][0][1][0][RTW89_QATAR][13] = 127, + [0][0][1][0][RTW89_UK][13] = 127, [0][1][1][0][RTW89_FCC][0] = 62, [0][1][1][0][RTW89_ETSI][0] = 46, [0][1][1][0][RTW89_MKK][0] = 64, @@ -44333,6 +44403,7 @@ const s8 rtw89_8852a_txpwr_lmt_2g[RTW89_2G_BW_NUM][RTW89_NTX_NUM] [0][1][1][0][RTW89_MEXICO][0] = 62, [0][1][1][0][RTW89_CN][0] = 46, [0][1][1][0][RTW89_QATAR][0] = 46, + [0][1][1][0][RTW89_UK][0] = 46, [0][1][1][0][RTW89_FCC][1] = 62, [0][1][1][0][RTW89_ETSI][1] = 46, [0][1][1][0][RTW89_MKK][1] = 64, @@ -44344,6 +44415,7 @@ const s8 rtw89_8852a_txpwr_lmt_2g[RTW89_2G_BW_NUM][RTW89_NTX_NUM] [0][1][1][0][RTW89_MEXICO][1] = 62, [0][1][1][0][RTW89_CN][1] = 46, [0][1][1][0][RTW89_QATAR][1] = 46, + [0][1][1][0][RTW89_UK][1] = 46, [0][1][1][0][RTW89_FCC][2] = 66, [0][1][1][0][RTW89_ETSI][2] = 46, [0][1][1][0][RTW89_MKK][2] = 64, @@ -44355,6 +44427,7 @@ const s8 rtw89_8852a_txpwr_lmt_2g[RTW89_2G_BW_NUM][RTW89_NTX_NUM] [0][1][1][0][RTW89_MEXICO][2] = 66, [0][1][1][0][RTW89_CN][2] = 46, [0][1][1][0][RTW89_QATAR][2] = 46, + [0][1][1][0][RTW89_UK][2] = 46, [0][1][1][0][RTW89_FCC][3] = 70, [0][1][1][0][RTW89_ETSI][3] = 46, [0][1][1][0][RTW89_MKK][3] = 64, @@ -44366,6 +44439,7 @@ const s8 rtw89_8852a_txpwr_lmt_2g[RTW89_2G_BW_NUM][RTW89_NTX_NUM] [0][1][1][0][RTW89_MEXICO][3] = 70, [0][1][1][0][RTW89_CN][3] = 46, [0][1][1][0][RTW89_QATAR][3] = 46, + [0][1][1][0][RTW89_UK][3] = 46, [0][1][1][0][RTW89_FCC][4] = 78, [0][1][1][0][RTW89_ETSI][4] = 46, [0][1][1][0][RTW89_MKK][4] = 64, @@ -44377,6 +44451,7 @@ const s8 rtw89_8852a_txpwr_lmt_2g[RTW89_2G_BW_NUM][RTW89_NTX_NUM] [0][1][1][0][RTW89_MEXICO][4] = 78, [0][1][1][0][RTW89_CN][4] = 46, [0][1][1][0][RTW89_QATAR][4] = 46, + [0][1][1][0][RTW89_UK][4] = 46, [0][1][1][0][RTW89_FCC][5] = 78, [0][1][1][0][RTW89_ETSI][5] = 46, [0][1][1][0][RTW89_MKK][5] = 64, @@ -44388,6 +44463,7 @@ const s8 rtw89_8852a_txpwr_lmt_2g[RTW89_2G_BW_NUM][RTW89_NTX_NUM] [0][1][1][0][RTW89_MEXICO][5] = 78, [0][1][1][0][RTW89_CN][5] = 46, [0][1][1][0][RTW89_QATAR][5] = 46, + [0][1][1][0][RTW89_UK][5] = 46, [0][1][1][0][RTW89_FCC][6] = 78, [0][1][1][0][RTW89_ETSI][6] = 46, [0][1][1][0][RTW89_MKK][6] = 64, @@ -44399,6 +44475,7 @@ const s8 rtw89_8852a_txpwr_lmt_2g[RTW89_2G_BW_NUM][RTW89_NTX_NUM] [0][1][1][0][RTW89_MEXICO][6] = 78, [0][1][1][0][RTW89_CN][6] = 46, [0][1][1][0][RTW89_QATAR][6] = 46, + [0][1][1][0][RTW89_UK][6] = 46, [0][1][1][0][RTW89_FCC][7] = 70, [0][1][1][0][RTW89_ETSI][7] = 46, [0][1][1][0][RTW89_MKK][7] = 64, @@ -44410,6 +44487,7 @@ const s8 rtw89_8852a_txpwr_lmt_2g[RTW89_2G_BW_NUM][RTW89_NTX_NUM] [0][1][1][0][RTW89_MEXICO][7] = 70, [0][1][1][0][RTW89_CN][7] = 46, [0][1][1][0][RTW89_QATAR][7] = 46, + [0][1][1][0][RTW89_UK][7] = 46, [0][1][1][0][RTW89_FCC][8] = 66, [0][1][1][0][RTW89_ETSI][8] = 46, [0][1][1][0][RTW89_MKK][8] = 64, @@ -44421,6 +44499,7 @@ const s8 rtw89_8852a_txpwr_lmt_2g[RTW89_2G_BW_NUM][RTW89_NTX_NUM] [0][1][1][0][RTW89_MEXICO][8] = 66, [0][1][1][0][RTW89_CN][8] = 46, [0][1][1][0][RTW89_QATAR][8] = 46, + [0][1][1][0][RTW89_UK][8] = 46, [0][1][1][0][RTW89_FCC][9] = 62, [0][1][1][0][RTW89_ETSI][9] = 46, [0][1][1][0][RTW89_MKK][9] = 64, @@ -44432,6 +44511,7 @@ const s8 rtw89_8852a_txpwr_lmt_2g[RTW89_2G_BW_NUM][RTW89_NTX_NUM] [0][1][1][0][RTW89_MEXICO][9] = 62, [0][1][1][0][RTW89_CN][9] = 46, [0][1][1][0][RTW89_QATAR][9] = 46, + [0][1][1][0][RTW89_UK][9] = 46, [0][1][1][0][RTW89_FCC][10] = 62, [0][1][1][0][RTW89_ETSI][10] = 46, [0][1][1][0][RTW89_MKK][10] = 64, @@ -44443,6 +44523,7 @@ const s8 rtw89_8852a_txpwr_lmt_2g[RTW89_2G_BW_NUM][RTW89_NTX_NUM] [0][1][1][0][RTW89_MEXICO][10] = 62, [0][1][1][0][RTW89_CN][10] = 46, [0][1][1][0][RTW89_QATAR][10] = 46, + [0][1][1][0][RTW89_UK][10] = 46, [0][1][1][0][RTW89_FCC][11] = 42, [0][1][1][0][RTW89_ETSI][11] = 46, [0][1][1][0][RTW89_MKK][11] = 64, @@ -44454,6 +44535,7 @@ const s8 rtw89_8852a_txpwr_lmt_2g[RTW89_2G_BW_NUM][RTW89_NTX_NUM] [0][1][1][0][RTW89_MEXICO][11] = 42, [0][1][1][0][RTW89_CN][11] = 46, [0][1][1][0][RTW89_QATAR][11] = 46, + [0][1][1][0][RTW89_UK][11] = 46, [0][1][1][0][RTW89_FCC][12] = 40, [0][1][1][0][RTW89_ETSI][12] = 46, [0][1][1][0][RTW89_MKK][12] = 64, @@ -44465,6 +44547,7 @@ const s8 rtw89_8852a_txpwr_lmt_2g[RTW89_2G_BW_NUM][RTW89_NTX_NUM] [0][1][1][0][RTW89_MEXICO][12] = 40, [0][1][1][0][RTW89_CN][12] = 46, [0][1][1][0][RTW89_QATAR][12] = 46, + [0][1][1][0][RTW89_UK][12] = 46, [0][1][1][0][RTW89_FCC][13] = 127, [0][1][1][0][RTW89_ETSI][13] = 127, [0][1][1][0][RTW89_MKK][13] = 127, @@ -44476,6 +44559,7 @@ const s8 rtw89_8852a_txpwr_lmt_2g[RTW89_2G_BW_NUM][RTW89_NTX_NUM] [0][1][1][0][RTW89_MEXICO][13] = 127, [0][1][1][0][RTW89_CN][13] = 127, [0][1][1][0][RTW89_QATAR][13] = 127, + [0][1][1][0][RTW89_UK][13] = 127, [0][0][2][0][RTW89_FCC][0] = 66, [0][0][2][0][RTW89_ETSI][0] = 58, [0][0][2][0][RTW89_MKK][0] = 76, @@ -44487,6 +44571,7 @@ const s8 rtw89_8852a_txpwr_lmt_2g[RTW89_2G_BW_NUM][RTW89_NTX_NUM] [0][0][2][0][RTW89_MEXICO][0] = 66, [0][0][2][0][RTW89_CN][0] = 58, [0][0][2][0][RTW89_QATAR][0] = 58, + [0][0][2][0][RTW89_UK][0] = 58, [0][0][2][0][RTW89_FCC][1] = 66, [0][0][2][0][RTW89_ETSI][1] = 58, [0][0][2][0][RTW89_MKK][1] = 76, @@ -44498,6 +44583,7 @@ const s8 rtw89_8852a_txpwr_lmt_2g[RTW89_2G_BW_NUM][RTW89_NTX_NUM] [0][0][2][0][RTW89_MEXICO][1] = 66, [0][0][2][0][RTW89_CN][1] = 58, [0][0][2][0][RTW89_QATAR][1] = 58, + [0][0][2][0][RTW89_UK][1] = 58, [0][0][2][0][RTW89_FCC][2] = 70, [0][0][2][0][RTW89_ETSI][2] = 58, [0][0][2][0][RTW89_MKK][2] = 76, @@ -44509,6 +44595,7 @@ const s8 rtw89_8852a_txpwr_lmt_2g[RTW89_2G_BW_NUM][RTW89_NTX_NUM] [0][0][2][0][RTW89_MEXICO][2] = 70, [0][0][2][0][RTW89_CN][2] = 58, [0][0][2][0][RTW89_QATAR][2] = 58, + [0][0][2][0][RTW89_UK][2] = 58, [0][0][2][0][RTW89_FCC][3] = 74, [0][0][2][0][RTW89_ETSI][3] = 58, [0][0][2][0][RTW89_MKK][3] = 76, @@ -44520,6 +44607,7 @@ const s8 rtw89_8852a_txpwr_lmt_2g[RTW89_2G_BW_NUM][RTW89_NTX_NUM] [0][0][2][0][RTW89_MEXICO][3] = 74, [0][0][2][0][RTW89_CN][3] = 58, [0][0][2][0][RTW89_QATAR][3] = 58, + [0][0][2][0][RTW89_UK][3] = 58, [0][0][2][0][RTW89_FCC][4] = 76, [0][0][2][0][RTW89_ETSI][4] = 58, [0][0][2][0][RTW89_MKK][4] = 76, @@ -44531,6 +44619,7 @@ const s8 rtw89_8852a_txpwr_lmt_2g[RTW89_2G_BW_NUM][RTW89_NTX_NUM] [0][0][2][0][RTW89_MEXICO][4] = 76, [0][0][2][0][RTW89_CN][4] = 58, [0][0][2][0][RTW89_QATAR][4] = 58, + [0][0][2][0][RTW89_UK][4] = 58, [0][0][2][0][RTW89_FCC][5] = 76, [0][0][2][0][RTW89_ETSI][5] = 58, [0][0][2][0][RTW89_MKK][5] = 76, @@ -44542,6 +44631,7 @@ const s8 rtw89_8852a_txpwr_lmt_2g[RTW89_2G_BW_NUM][RTW89_NTX_NUM] [0][0][2][0][RTW89_MEXICO][5] = 76, [0][0][2][0][RTW89_CN][5] = 58, [0][0][2][0][RTW89_QATAR][5] = 58, + [0][0][2][0][RTW89_UK][5] = 58, [0][0][2][0][RTW89_FCC][6] = 76, [0][0][2][0][RTW89_ETSI][6] = 58, [0][0][2][0][RTW89_MKK][6] = 76, @@ -44553,6 +44643,7 @@ const s8 rtw89_8852a_txpwr_lmt_2g[RTW89_2G_BW_NUM][RTW89_NTX_NUM] [0][0][2][0][RTW89_MEXICO][6] = 76, [0][0][2][0][RTW89_CN][6] = 58, [0][0][2][0][RTW89_QATAR][6] = 58, + [0][0][2][0][RTW89_UK][6] = 58, [0][0][2][0][RTW89_FCC][7] = 74, [0][0][2][0][RTW89_ETSI][7] = 58, [0][0][2][0][RTW89_MKK][7] = 76, @@ -44564,6 +44655,7 @@ const s8 rtw89_8852a_txpwr_lmt_2g[RTW89_2G_BW_NUM][RTW89_NTX_NUM] [0][0][2][0][RTW89_MEXICO][7] = 74, [0][0][2][0][RTW89_CN][7] = 58, [0][0][2][0][RTW89_QATAR][7] = 58, + [0][0][2][0][RTW89_UK][7] = 58, [0][0][2][0][RTW89_FCC][8] = 70, [0][0][2][0][RTW89_ETSI][8] = 58, [0][0][2][0][RTW89_MKK][8] = 76, @@ -44575,6 +44667,7 @@ const s8 rtw89_8852a_txpwr_lmt_2g[RTW89_2G_BW_NUM][RTW89_NTX_NUM] [0][0][2][0][RTW89_MEXICO][8] = 70, [0][0][2][0][RTW89_CN][8] = 58, [0][0][2][0][RTW89_QATAR][8] = 58, + [0][0][2][0][RTW89_UK][8] = 58, [0][0][2][0][RTW89_FCC][9] = 66, [0][0][2][0][RTW89_ETSI][9] = 58, [0][0][2][0][RTW89_MKK][9] = 76, @@ -44586,6 +44679,7 @@ const s8 rtw89_8852a_txpwr_lmt_2g[RTW89_2G_BW_NUM][RTW89_NTX_NUM] [0][0][2][0][RTW89_MEXICO][9] = 66, [0][0][2][0][RTW89_CN][9] = 58, [0][0][2][0][RTW89_QATAR][9] = 58, + [0][0][2][0][RTW89_UK][9] = 58, [0][0][2][0][RTW89_FCC][10] = 66, [0][0][2][0][RTW89_ETSI][10] = 58, [0][0][2][0][RTW89_MKK][10] = 76, @@ -44597,6 +44691,7 @@ const s8 rtw89_8852a_txpwr_lmt_2g[RTW89_2G_BW_NUM][RTW89_NTX_NUM] [0][0][2][0][RTW89_MEXICO][10] = 66, [0][0][2][0][RTW89_CN][10] = 58, [0][0][2][0][RTW89_QATAR][10] = 58, + [0][0][2][0][RTW89_UK][10] = 58, [0][0][2][0][RTW89_FCC][11] = 54, [0][0][2][0][RTW89_ETSI][11] = 58, [0][0][2][0][RTW89_MKK][11] = 76, @@ -44608,6 +44703,7 @@ const s8 rtw89_8852a_txpwr_lmt_2g[RTW89_2G_BW_NUM][RTW89_NTX_NUM] [0][0][2][0][RTW89_MEXICO][11] = 54, [0][0][2][0][RTW89_CN][11] = 58, [0][0][2][0][RTW89_QATAR][11] = 58, + [0][0][2][0][RTW89_UK][11] = 58, [0][0][2][0][RTW89_FCC][12] = 50, [0][0][2][0][RTW89_ETSI][12] = 58, [0][0][2][0][RTW89_MKK][12] = 76, @@ -44619,6 +44715,7 @@ const s8 rtw89_8852a_txpwr_lmt_2g[RTW89_2G_BW_NUM][RTW89_NTX_NUM] [0][0][2][0][RTW89_MEXICO][12] = 50, [0][0][2][0][RTW89_CN][12] = 58, [0][0][2][0][RTW89_QATAR][12] = 58, + [0][0][2][0][RTW89_UK][12] = 58, [0][0][2][0][RTW89_FCC][13] = 127, [0][0][2][0][RTW89_ETSI][13] = 127, [0][0][2][0][RTW89_MKK][13] = 127, @@ -44630,6 +44727,7 @@ const s8 rtw89_8852a_txpwr_lmt_2g[RTW89_2G_BW_NUM][RTW89_NTX_NUM] [0][0][2][0][RTW89_MEXICO][13] = 127, [0][0][2][0][RTW89_CN][13] = 127, [0][0][2][0][RTW89_QATAR][13] = 127, + [0][0][2][0][RTW89_UK][13] = 127, [0][1][2][0][RTW89_FCC][0] = 62, [0][1][2][0][RTW89_ETSI][0] = 46, [0][1][2][0][RTW89_MKK][0] = 64, @@ -44641,6 +44739,7 @@ const s8 rtw89_8852a_txpwr_lmt_2g[RTW89_2G_BW_NUM][RTW89_NTX_NUM] [0][1][2][0][RTW89_MEXICO][0] = 62, [0][1][2][0][RTW89_CN][0] = 46, [0][1][2][0][RTW89_QATAR][0] = 46, + [0][1][2][0][RTW89_UK][0] = 46, [0][1][2][0][RTW89_FCC][1] = 62, [0][1][2][0][RTW89_ETSI][1] = 46, [0][1][2][0][RTW89_MKK][1] = 64, @@ -44652,6 +44751,7 @@ const s8 rtw89_8852a_txpwr_lmt_2g[RTW89_2G_BW_NUM][RTW89_NTX_NUM] [0][1][2][0][RTW89_MEXICO][1] = 62, [0][1][2][0][RTW89_CN][1] = 46, [0][1][2][0][RTW89_QATAR][1] = 46, + [0][1][2][0][RTW89_UK][1] = 46, [0][1][2][0][RTW89_FCC][2] = 66, [0][1][2][0][RTW89_ETSI][2] = 46, [0][1][2][0][RTW89_MKK][2] = 64, @@ -44663,6 +44763,7 @@ const s8 rtw89_8852a_txpwr_lmt_2g[RTW89_2G_BW_NUM][RTW89_NTX_NUM] [0][1][2][0][RTW89_MEXICO][2] = 66, [0][1][2][0][RTW89_CN][2] = 46, [0][1][2][0][RTW89_QATAR][2] = 46, + [0][1][2][0][RTW89_UK][2] = 46, [0][1][2][0][RTW89_FCC][3] = 70, [0][1][2][0][RTW89_ETSI][3] = 46, [0][1][2][0][RTW89_MKK][3] = 64, @@ -44674,6 +44775,7 @@ const s8 rtw89_8852a_txpwr_lmt_2g[RTW89_2G_BW_NUM][RTW89_NTX_NUM] [0][1][2][0][RTW89_MEXICO][3] = 70, [0][1][2][0][RTW89_CN][3] = 46, [0][1][2][0][RTW89_QATAR][3] = 46, + [0][1][2][0][RTW89_UK][3] = 46, [0][1][2][0][RTW89_FCC][4] = 76, [0][1][2][0][RTW89_ETSI][4] = 46, [0][1][2][0][RTW89_MKK][4] = 64, @@ -44685,6 +44787,7 @@ const s8 rtw89_8852a_txpwr_lmt_2g[RTW89_2G_BW_NUM][RTW89_NTX_NUM] [0][1][2][0][RTW89_MEXICO][4] = 76, [0][1][2][0][RTW89_CN][4] = 46, [0][1][2][0][RTW89_QATAR][4] = 46, + [0][1][2][0][RTW89_UK][4] = 46, [0][1][2][0][RTW89_FCC][5] = 76, [0][1][2][0][RTW89_ETSI][5] = 46, [0][1][2][0][RTW89_MKK][5] = 64, @@ -44696,6 +44799,7 @@ const s8 rtw89_8852a_txpwr_lmt_2g[RTW89_2G_BW_NUM][RTW89_NTX_NUM] [0][1][2][0][RTW89_MEXICO][5] = 76, [0][1][2][0][RTW89_CN][5] = 46, [0][1][2][0][RTW89_QATAR][5] = 46, + [0][1][2][0][RTW89_UK][5] = 46, [0][1][2][0][RTW89_FCC][6] = 76, [0][1][2][0][RTW89_ETSI][6] = 46, [0][1][2][0][RTW89_MKK][6] = 64, @@ -44707,6 +44811,7 @@ const s8 rtw89_8852a_txpwr_lmt_2g[RTW89_2G_BW_NUM][RTW89_NTX_NUM] [0][1][2][0][RTW89_MEXICO][6] = 76, [0][1][2][0][RTW89_CN][6] = 46, [0][1][2][0][RTW89_QATAR][6] = 46, + [0][1][2][0][RTW89_UK][6] = 46, [0][1][2][0][RTW89_FCC][7] = 68, [0][1][2][0][RTW89_ETSI][7] = 46, [0][1][2][0][RTW89_MKK][7] = 64, @@ -44718,6 +44823,7 @@ const s8 rtw89_8852a_txpwr_lmt_2g[RTW89_2G_BW_NUM][RTW89_NTX_NUM] [0][1][2][0][RTW89_MEXICO][7] = 68, [0][1][2][0][RTW89_CN][7] = 46, [0][1][2][0][RTW89_QATAR][7] = 46, + [0][1][2][0][RTW89_UK][7] = 46, [0][1][2][0][RTW89_FCC][8] = 64, [0][1][2][0][RTW89_ETSI][8] = 46, [0][1][2][0][RTW89_MKK][8] = 64, @@ -44729,6 +44835,7 @@ const s8 rtw89_8852a_txpwr_lmt_2g[RTW89_2G_BW_NUM][RTW89_NTX_NUM] [0][1][2][0][RTW89_MEXICO][8] = 64, [0][1][2][0][RTW89_CN][8] = 46, [0][1][2][0][RTW89_QATAR][8] = 46, + [0][1][2][0][RTW89_UK][8] = 46, [0][1][2][0][RTW89_FCC][9] = 60, [0][1][2][0][RTW89_ETSI][9] = 46, [0][1][2][0][RTW89_MKK][9] = 64, @@ -44740,6 +44847,7 @@ const s8 rtw89_8852a_txpwr_lmt_2g[RTW89_2G_BW_NUM][RTW89_NTX_NUM] [0][1][2][0][RTW89_MEXICO][9] = 60, [0][1][2][0][RTW89_CN][9] = 46, [0][1][2][0][RTW89_QATAR][9] = 46, + [0][1][2][0][RTW89_UK][9] = 46, [0][1][2][0][RTW89_FCC][10] = 60, [0][1][2][0][RTW89_ETSI][10] = 46, [0][1][2][0][RTW89_MKK][10] = 64, @@ -44751,6 +44859,7 @@ const s8 rtw89_8852a_txpwr_lmt_2g[RTW89_2G_BW_NUM][RTW89_NTX_NUM] [0][1][2][0][RTW89_MEXICO][10] = 60, [0][1][2][0][RTW89_CN][10] = 46, [0][1][2][0][RTW89_QATAR][10] = 46, + [0][1][2][0][RTW89_UK][10] = 46, [0][1][2][0][RTW89_FCC][11] = 42, [0][1][2][0][RTW89_ETSI][11] = 46, [0][1][2][0][RTW89_MKK][11] = 64, @@ -44762,6 +44871,7 @@ const s8 rtw89_8852a_txpwr_lmt_2g[RTW89_2G_BW_NUM][RTW89_NTX_NUM] [0][1][2][0][RTW89_MEXICO][11] = 42, [0][1][2][0][RTW89_CN][11] = 46, [0][1][2][0][RTW89_QATAR][11] = 46, + [0][1][2][0][RTW89_UK][11] = 46, [0][1][2][0][RTW89_FCC][12] = 40, [0][1][2][0][RTW89_ETSI][12] = 46, [0][1][2][0][RTW89_MKK][12] = 64, @@ -44773,6 +44883,7 @@ const s8 rtw89_8852a_txpwr_lmt_2g[RTW89_2G_BW_NUM][RTW89_NTX_NUM] [0][1][2][0][RTW89_MEXICO][12] = 40, [0][1][2][0][RTW89_CN][12] = 46, [0][1][2][0][RTW89_QATAR][12] = 46, + [0][1][2][0][RTW89_UK][12] = 46, [0][1][2][0][RTW89_FCC][13] = 127, [0][1][2][0][RTW89_ETSI][13] = 127, [0][1][2][0][RTW89_MKK][13] = 127, @@ -44784,6 +44895,7 @@ const s8 rtw89_8852a_txpwr_lmt_2g[RTW89_2G_BW_NUM][RTW89_NTX_NUM] [0][1][2][0][RTW89_MEXICO][13] = 127, [0][1][2][0][RTW89_CN][13] = 127, [0][1][2][0][RTW89_QATAR][13] = 127, + [0][1][2][0][RTW89_UK][13] = 127, [0][1][2][1][RTW89_FCC][0] = 62, [0][1][2][1][RTW89_ETSI][0] = 34, [0][1][2][1][RTW89_MKK][0] = 64, @@ -44795,6 +44907,7 @@ const s8 rtw89_8852a_txpwr_lmt_2g[RTW89_2G_BW_NUM][RTW89_NTX_NUM] [0][1][2][1][RTW89_MEXICO][0] = 62, [0][1][2][1][RTW89_CN][0] = 34, [0][1][2][1][RTW89_QATAR][0] = 34, + [0][1][2][1][RTW89_UK][0] = 34, [0][1][2][1][RTW89_FCC][1] = 62, [0][1][2][1][RTW89_ETSI][1] = 34, [0][1][2][1][RTW89_MKK][1] = 64, @@ -44806,6 +44919,7 @@ const s8 rtw89_8852a_txpwr_lmt_2g[RTW89_2G_BW_NUM][RTW89_NTX_NUM] [0][1][2][1][RTW89_MEXICO][1] = 62, [0][1][2][1][RTW89_CN][1] = 34, [0][1][2][1][RTW89_QATAR][1] = 34, + [0][1][2][1][RTW89_UK][1] = 34, [0][1][2][1][RTW89_FCC][2] = 66, [0][1][2][1][RTW89_ETSI][2] = 34, [0][1][2][1][RTW89_MKK][2] = 64, @@ -44817,6 +44931,7 @@ const s8 rtw89_8852a_txpwr_lmt_2g[RTW89_2G_BW_NUM][RTW89_NTX_NUM] [0][1][2][1][RTW89_MEXICO][2] = 66, [0][1][2][1][RTW89_CN][2] = 34, [0][1][2][1][RTW89_QATAR][2] = 34, + [0][1][2][1][RTW89_UK][2] = 34, [0][1][2][1][RTW89_FCC][3] = 70, [0][1][2][1][RTW89_ETSI][3] = 34, [0][1][2][1][RTW89_MKK][3] = 64, @@ -44828,6 +44943,7 @@ const s8 rtw89_8852a_txpwr_lmt_2g[RTW89_2G_BW_NUM][RTW89_NTX_NUM] [0][1][2][1][RTW89_MEXICO][3] = 70, [0][1][2][1][RTW89_CN][3] = 34, [0][1][2][1][RTW89_QATAR][3] = 34, + [0][1][2][1][RTW89_UK][3] = 34, [0][1][2][1][RTW89_FCC][4] = 76, [0][1][2][1][RTW89_ETSI][4] = 34, [0][1][2][1][RTW89_MKK][4] = 64, @@ -44839,6 +44955,7 @@ const s8 rtw89_8852a_txpwr_lmt_2g[RTW89_2G_BW_NUM][RTW89_NTX_NUM] [0][1][2][1][RTW89_MEXICO][4] = 76, [0][1][2][1][RTW89_CN][4] = 34, [0][1][2][1][RTW89_QATAR][4] = 34, + [0][1][2][1][RTW89_UK][4] = 34, [0][1][2][1][RTW89_FCC][5] = 76, [0][1][2][1][RTW89_ETSI][5] = 34, [0][1][2][1][RTW89_MKK][5] = 64, @@ -44850,6 +44967,7 @@ const s8 rtw89_8852a_txpwr_lmt_2g[RTW89_2G_BW_NUM][RTW89_NTX_NUM] [0][1][2][1][RTW89_MEXICO][5] = 76, [0][1][2][1][RTW89_CN][5] = 34, [0][1][2][1][RTW89_QATAR][5] = 34, + [0][1][2][1][RTW89_UK][5] = 34, [0][1][2][1][RTW89_FCC][6] = 76, [0][1][2][1][RTW89_ETSI][6] = 34, [0][1][2][1][RTW89_MKK][6] = 64, @@ -44861,6 +44979,7 @@ const s8 rtw89_8852a_txpwr_lmt_2g[RTW89_2G_BW_NUM][RTW89_NTX_NUM] [0][1][2][1][RTW89_MEXICO][6] = 76, [0][1][2][1][RTW89_CN][6] = 34, [0][1][2][1][RTW89_QATAR][6] = 34, + [0][1][2][1][RTW89_UK][6] = 34, [0][1][2][1][RTW89_FCC][7] = 68, [0][1][2][1][RTW89_ETSI][7] = 34, [0][1][2][1][RTW89_MKK][7] = 64, @@ -44872,6 +44991,7 @@ const s8 rtw89_8852a_txpwr_lmt_2g[RTW89_2G_BW_NUM][RTW89_NTX_NUM] [0][1][2][1][RTW89_MEXICO][7] = 68, [0][1][2][1][RTW89_CN][7] = 34, [0][1][2][1][RTW89_QATAR][7] = 34, + [0][1][2][1][RTW89_UK][7] = 34, [0][1][2][1][RTW89_FCC][8] = 64, [0][1][2][1][RTW89_ETSI][8] = 34, [0][1][2][1][RTW89_MKK][8] = 64, @@ -44883,6 +45003,7 @@ const s8 rtw89_8852a_txpwr_lmt_2g[RTW89_2G_BW_NUM][RTW89_NTX_NUM] [0][1][2][1][RTW89_MEXICO][8] = 64, [0][1][2][1][RTW89_CN][8] = 34, [0][1][2][1][RTW89_QATAR][8] = 34, + [0][1][2][1][RTW89_UK][8] = 34, [0][1][2][1][RTW89_FCC][9] = 60, [0][1][2][1][RTW89_ETSI][9] = 34, [0][1][2][1][RTW89_MKK][9] = 64, @@ -44894,6 +45015,7 @@ const s8 rtw89_8852a_txpwr_lmt_2g[RTW89_2G_BW_NUM][RTW89_NTX_NUM] [0][1][2][1][RTW89_MEXICO][9] = 60, [0][1][2][1][RTW89_CN][9] = 34, [0][1][2][1][RTW89_QATAR][9] = 34, + [0][1][2][1][RTW89_UK][9] = 34, [0][1][2][1][RTW89_FCC][10] = 60, [0][1][2][1][RTW89_ETSI][10] = 34, [0][1][2][1][RTW89_MKK][10] = 64, @@ -44905,6 +45027,7 @@ const s8 rtw89_8852a_txpwr_lmt_2g[RTW89_2G_BW_NUM][RTW89_NTX_NUM] [0][1][2][1][RTW89_MEXICO][10] = 60, [0][1][2][1][RTW89_CN][10] = 34, [0][1][2][1][RTW89_QATAR][10] = 34, + [0][1][2][1][RTW89_UK][10] = 34, [0][1][2][1][RTW89_FCC][11] = 42, [0][1][2][1][RTW89_ETSI][11] = 34, [0][1][2][1][RTW89_MKK][11] = 64, @@ -44916,6 +45039,7 @@ const s8 rtw89_8852a_txpwr_lmt_2g[RTW89_2G_BW_NUM][RTW89_NTX_NUM] [0][1][2][1][RTW89_MEXICO][11] = 42, [0][1][2][1][RTW89_CN][11] = 34, [0][1][2][1][RTW89_QATAR][11] = 34, + [0][1][2][1][RTW89_UK][11] = 34, [0][1][2][1][RTW89_FCC][12] = 40, [0][1][2][1][RTW89_ETSI][12] = 34, [0][1][2][1][RTW89_MKK][12] = 64, @@ -44927,6 +45051,7 @@ const s8 rtw89_8852a_txpwr_lmt_2g[RTW89_2G_BW_NUM][RTW89_NTX_NUM] [0][1][2][1][RTW89_MEXICO][12] = 40, [0][1][2][1][RTW89_CN][12] = 34, [0][1][2][1][RTW89_QATAR][12] = 34, + [0][1][2][1][RTW89_UK][12] = 34, [0][1][2][1][RTW89_FCC][13] = 127, [0][1][2][1][RTW89_ETSI][13] = 127, [0][1][2][1][RTW89_MKK][13] = 127, @@ -44938,6 +45063,7 @@ const s8 rtw89_8852a_txpwr_lmt_2g[RTW89_2G_BW_NUM][RTW89_NTX_NUM] [0][1][2][1][RTW89_MEXICO][13] = 127, [0][1][2][1][RTW89_CN][13] = 127, [0][1][2][1][RTW89_QATAR][13] = 127, + [0][1][2][1][RTW89_UK][13] = 127, [1][0][2][0][RTW89_FCC][0] = 127, [1][0][2][0][RTW89_ETSI][0] = 127, [1][0][2][0][RTW89_MKK][0] = 127, @@ -44949,6 +45075,7 @@ const s8 rtw89_8852a_txpwr_lmt_2g[RTW89_2G_BW_NUM][RTW89_NTX_NUM] [1][0][2][0][RTW89_MEXICO][0] = 127, [1][0][2][0][RTW89_CN][0] = 127, [1][0][2][0][RTW89_QATAR][0] = 127, + [1][0][2][0][RTW89_UK][0] = 127, [1][0][2][0][RTW89_FCC][1] = 127, [1][0][2][0][RTW89_ETSI][1] = 127, [1][0][2][0][RTW89_MKK][1] = 127, @@ -44960,6 +45087,7 @@ const s8 rtw89_8852a_txpwr_lmt_2g[RTW89_2G_BW_NUM][RTW89_NTX_NUM] [1][0][2][0][RTW89_MEXICO][1] = 127, [1][0][2][0][RTW89_CN][1] = 127, [1][0][2][0][RTW89_QATAR][1] = 127, + [1][0][2][0][RTW89_UK][1] = 127, [1][0][2][0][RTW89_FCC][2] = 56, [1][0][2][0][RTW89_ETSI][2] = 58, [1][0][2][0][RTW89_MKK][2] = 68, @@ -44971,6 +45099,7 @@ const s8 rtw89_8852a_txpwr_lmt_2g[RTW89_2G_BW_NUM][RTW89_NTX_NUM] [1][0][2][0][RTW89_MEXICO][2] = 56, [1][0][2][0][RTW89_CN][2] = 58, [1][0][2][0][RTW89_QATAR][2] = 58, + [1][0][2][0][RTW89_UK][2] = 58, [1][0][2][0][RTW89_FCC][3] = 56, [1][0][2][0][RTW89_ETSI][3] = 58, [1][0][2][0][RTW89_MKK][3] = 68, @@ -44982,6 +45111,7 @@ const s8 rtw89_8852a_txpwr_lmt_2g[RTW89_2G_BW_NUM][RTW89_NTX_NUM] [1][0][2][0][RTW89_MEXICO][3] = 56, [1][0][2][0][RTW89_CN][3] = 58, [1][0][2][0][RTW89_QATAR][3] = 58, + [1][0][2][0][RTW89_UK][3] = 58, [1][0][2][0][RTW89_FCC][4] = 60, [1][0][2][0][RTW89_ETSI][4] = 58, [1][0][2][0][RTW89_MKK][4] = 68, @@ -44993,6 +45123,7 @@ const s8 rtw89_8852a_txpwr_lmt_2g[RTW89_2G_BW_NUM][RTW89_NTX_NUM] [1][0][2][0][RTW89_MEXICO][4] = 60, [1][0][2][0][RTW89_CN][4] = 58, [1][0][2][0][RTW89_QATAR][4] = 58, + [1][0][2][0][RTW89_UK][4] = 58, [1][0][2][0][RTW89_FCC][5] = 64, [1][0][2][0][RTW89_ETSI][5] = 58, [1][0][2][0][RTW89_MKK][5] = 68, @@ -45004,6 +45135,7 @@ const s8 rtw89_8852a_txpwr_lmt_2g[RTW89_2G_BW_NUM][RTW89_NTX_NUM] [1][0][2][0][RTW89_MEXICO][5] = 64, [1][0][2][0][RTW89_CN][5] = 58, [1][0][2][0][RTW89_QATAR][5] = 58, + [1][0][2][0][RTW89_UK][5] = 58, [1][0][2][0][RTW89_FCC][6] = 54, [1][0][2][0][RTW89_ETSI][6] = 58, [1][0][2][0][RTW89_MKK][6] = 68, @@ -45015,6 +45147,7 @@ const s8 rtw89_8852a_txpwr_lmt_2g[RTW89_2G_BW_NUM][RTW89_NTX_NUM] [1][0][2][0][RTW89_MEXICO][6] = 54, [1][0][2][0][RTW89_CN][6] = 58, [1][0][2][0][RTW89_QATAR][6] = 58, + [1][0][2][0][RTW89_UK][6] = 58, [1][0][2][0][RTW89_FCC][7] = 50, [1][0][2][0][RTW89_ETSI][7] = 58, [1][0][2][0][RTW89_MKK][7] = 68, @@ -45026,6 +45159,7 @@ const s8 rtw89_8852a_txpwr_lmt_2g[RTW89_2G_BW_NUM][RTW89_NTX_NUM] [1][0][2][0][RTW89_MEXICO][7] = 50, [1][0][2][0][RTW89_CN][7] = 58, [1][0][2][0][RTW89_QATAR][7] = 58, + [1][0][2][0][RTW89_UK][7] = 58, [1][0][2][0][RTW89_FCC][8] = 50, [1][0][2][0][RTW89_ETSI][8] = 58, [1][0][2][0][RTW89_MKK][8] = 68, @@ -45037,6 +45171,7 @@ const s8 rtw89_8852a_txpwr_lmt_2g[RTW89_2G_BW_NUM][RTW89_NTX_NUM] [1][0][2][0][RTW89_MEXICO][8] = 50, [1][0][2][0][RTW89_CN][8] = 58, [1][0][2][0][RTW89_QATAR][8] = 58, + [1][0][2][0][RTW89_UK][8] = 58, [1][0][2][0][RTW89_FCC][9] = 42, [1][0][2][0][RTW89_ETSI][9] = 58, [1][0][2][0][RTW89_MKK][9] = 68, @@ -45048,6 +45183,7 @@ const s8 rtw89_8852a_txpwr_lmt_2g[RTW89_2G_BW_NUM][RTW89_NTX_NUM] [1][0][2][0][RTW89_MEXICO][9] = 42, [1][0][2][0][RTW89_CN][9] = 58, [1][0][2][0][RTW89_QATAR][9] = 58, + [1][0][2][0][RTW89_UK][9] = 58, [1][0][2][0][RTW89_FCC][10] = 40, [1][0][2][0][RTW89_ETSI][10] = 58, [1][0][2][0][RTW89_MKK][10] = 68, @@ -45059,6 +45195,7 @@ const s8 rtw89_8852a_txpwr_lmt_2g[RTW89_2G_BW_NUM][RTW89_NTX_NUM] [1][0][2][0][RTW89_MEXICO][10] = 40, [1][0][2][0][RTW89_CN][10] = 58, [1][0][2][0][RTW89_QATAR][10] = 58, + [1][0][2][0][RTW89_UK][10] = 58, [1][0][2][0][RTW89_FCC][11] = 127, [1][0][2][0][RTW89_ETSI][11] = 127, [1][0][2][0][RTW89_MKK][11] = 127, @@ -45070,6 +45207,7 @@ const s8 rtw89_8852a_txpwr_lmt_2g[RTW89_2G_BW_NUM][RTW89_NTX_NUM] [1][0][2][0][RTW89_MEXICO][11] = 127, [1][0][2][0][RTW89_CN][11] = 127, [1][0][2][0][RTW89_QATAR][11] = 127, + [1][0][2][0][RTW89_UK][11] = 127, [1][0][2][0][RTW89_FCC][12] = 127, [1][0][2][0][RTW89_ETSI][12] = 127, [1][0][2][0][RTW89_MKK][12] = 127, @@ -45081,6 +45219,7 @@ const s8 rtw89_8852a_txpwr_lmt_2g[RTW89_2G_BW_NUM][RTW89_NTX_NUM] [1][0][2][0][RTW89_MEXICO][12] = 127, [1][0][2][0][RTW89_CN][12] = 127, [1][0][2][0][RTW89_QATAR][12] = 127, + [1][0][2][0][RTW89_UK][12] = 127, [1][0][2][0][RTW89_FCC][13] = 127, [1][0][2][0][RTW89_ETSI][13] = 127, [1][0][2][0][RTW89_MKK][13] = 127, @@ -45092,6 +45231,7 @@ const s8 rtw89_8852a_txpwr_lmt_2g[RTW89_2G_BW_NUM][RTW89_NTX_NUM] [1][0][2][0][RTW89_MEXICO][13] = 127, [1][0][2][0][RTW89_CN][13] = 127, [1][0][2][0][RTW89_QATAR][13] = 127, + [1][0][2][0][RTW89_UK][13] = 127, [1][1][2][0][RTW89_FCC][0] = 127, [1][1][2][0][RTW89_ETSI][0] = 127, [1][1][2][0][RTW89_MKK][0] = 127, @@ -45103,6 +45243,7 @@ const s8 rtw89_8852a_txpwr_lmt_2g[RTW89_2G_BW_NUM][RTW89_NTX_NUM] [1][1][2][0][RTW89_MEXICO][0] = 127, [1][1][2][0][RTW89_CN][0] = 127, [1][1][2][0][RTW89_QATAR][0] = 127, + [1][1][2][0][RTW89_UK][0] = 127, [1][1][2][0][RTW89_FCC][1] = 127, [1][1][2][0][RTW89_ETSI][1] = 127, [1][1][2][0][RTW89_MKK][1] = 127, @@ -45114,6 +45255,7 @@ const s8 rtw89_8852a_txpwr_lmt_2g[RTW89_2G_BW_NUM][RTW89_NTX_NUM] [1][1][2][0][RTW89_MEXICO][1] = 127, [1][1][2][0][RTW89_CN][1] = 127, [1][1][2][0][RTW89_QATAR][1] = 127, + [1][1][2][0][RTW89_UK][1] = 127, [1][1][2][0][RTW89_FCC][2] = 52, [1][1][2][0][RTW89_ETSI][2] = 46, [1][1][2][0][RTW89_MKK][2] = 64, @@ -45125,6 +45267,7 @@ const s8 rtw89_8852a_txpwr_lmt_2g[RTW89_2G_BW_NUM][RTW89_NTX_NUM] [1][1][2][0][RTW89_MEXICO][2] = 52, [1][1][2][0][RTW89_CN][2] = 46, [1][1][2][0][RTW89_QATAR][2] = 46, + [1][1][2][0][RTW89_UK][2] = 46, [1][1][2][0][RTW89_FCC][3] = 52, [1][1][2][0][RTW89_ETSI][3] = 46, [1][1][2][0][RTW89_MKK][3] = 64, @@ -45136,6 +45279,7 @@ const s8 rtw89_8852a_txpwr_lmt_2g[RTW89_2G_BW_NUM][RTW89_NTX_NUM] [1][1][2][0][RTW89_MEXICO][3] = 52, [1][1][2][0][RTW89_CN][3] = 46, [1][1][2][0][RTW89_QATAR][3] = 46, + [1][1][2][0][RTW89_UK][3] = 46, [1][1][2][0][RTW89_FCC][4] = 56, [1][1][2][0][RTW89_ETSI][4] = 46, [1][1][2][0][RTW89_MKK][4] = 64, @@ -45147,6 +45291,7 @@ const s8 rtw89_8852a_txpwr_lmt_2g[RTW89_2G_BW_NUM][RTW89_NTX_NUM] [1][1][2][0][RTW89_MEXICO][4] = 56, [1][1][2][0][RTW89_CN][4] = 46, [1][1][2][0][RTW89_QATAR][4] = 46, + [1][1][2][0][RTW89_UK][4] = 46, [1][1][2][0][RTW89_FCC][5] = 60, [1][1][2][0][RTW89_ETSI][5] = 46, [1][1][2][0][RTW89_MKK][5] = 64, @@ -45158,6 +45303,7 @@ const s8 rtw89_8852a_txpwr_lmt_2g[RTW89_2G_BW_NUM][RTW89_NTX_NUM] [1][1][2][0][RTW89_MEXICO][5] = 60, [1][1][2][0][RTW89_CN][5] = 46, [1][1][2][0][RTW89_QATAR][5] = 46, + [1][1][2][0][RTW89_UK][5] = 46, [1][1][2][0][RTW89_FCC][6] = 54, [1][1][2][0][RTW89_ETSI][6] = 46, [1][1][2][0][RTW89_MKK][6] = 64, @@ -45169,6 +45315,7 @@ const s8 rtw89_8852a_txpwr_lmt_2g[RTW89_2G_BW_NUM][RTW89_NTX_NUM] [1][1][2][0][RTW89_MEXICO][6] = 54, [1][1][2][0][RTW89_CN][6] = 46, [1][1][2][0][RTW89_QATAR][6] = 46, + [1][1][2][0][RTW89_UK][6] = 46, [1][1][2][0][RTW89_FCC][7] = 50, [1][1][2][0][RTW89_ETSI][7] = 46, [1][1][2][0][RTW89_MKK][7] = 64, @@ -45180,6 +45327,7 @@ const s8 rtw89_8852a_txpwr_lmt_2g[RTW89_2G_BW_NUM][RTW89_NTX_NUM] [1][1][2][0][RTW89_MEXICO][7] = 50, [1][1][2][0][RTW89_CN][7] = 46, [1][1][2][0][RTW89_QATAR][7] = 46, + [1][1][2][0][RTW89_UK][7] = 46, [1][1][2][0][RTW89_FCC][8] = 50, [1][1][2][0][RTW89_ETSI][8] = 46, [1][1][2][0][RTW89_MKK][8] = 64, @@ -45191,6 +45339,7 @@ const s8 rtw89_8852a_txpwr_lmt_2g[RTW89_2G_BW_NUM][RTW89_NTX_NUM] [1][1][2][0][RTW89_MEXICO][8] = 50, [1][1][2][0][RTW89_CN][8] = 46, [1][1][2][0][RTW89_QATAR][8] = 46, + [1][1][2][0][RTW89_UK][8] = 46, [1][1][2][0][RTW89_FCC][9] = 38, [1][1][2][0][RTW89_ETSI][9] = 46, [1][1][2][0][RTW89_MKK][9] = 64, @@ -45202,6 +45351,7 @@ const s8 rtw89_8852a_txpwr_lmt_2g[RTW89_2G_BW_NUM][RTW89_NTX_NUM] [1][1][2][0][RTW89_MEXICO][9] = 38, [1][1][2][0][RTW89_CN][9] = 46, [1][1][2][0][RTW89_QATAR][9] = 46, + [1][1][2][0][RTW89_UK][9] = 46, [1][1][2][0][RTW89_FCC][10] = 36, [1][1][2][0][RTW89_ETSI][10] = 46, [1][1][2][0][RTW89_MKK][10] = 64, @@ -45213,6 +45363,7 @@ const s8 rtw89_8852a_txpwr_lmt_2g[RTW89_2G_BW_NUM][RTW89_NTX_NUM] [1][1][2][0][RTW89_MEXICO][10] = 36, [1][1][2][0][RTW89_CN][10] = 46, [1][1][2][0][RTW89_QATAR][10] = 46, + [1][1][2][0][RTW89_UK][10] = 46, [1][1][2][0][RTW89_FCC][11] = 127, [1][1][2][0][RTW89_ETSI][11] = 127, [1][1][2][0][RTW89_MKK][11] = 127, @@ -45224,6 +45375,7 @@ const s8 rtw89_8852a_txpwr_lmt_2g[RTW89_2G_BW_NUM][RTW89_NTX_NUM] [1][1][2][0][RTW89_MEXICO][11] = 127, [1][1][2][0][RTW89_CN][11] = 127, [1][1][2][0][RTW89_QATAR][11] = 127, + [1][1][2][0][RTW89_UK][11] = 127, [1][1][2][0][RTW89_FCC][12] = 127, [1][1][2][0][RTW89_ETSI][12] = 127, [1][1][2][0][RTW89_MKK][12] = 127, @@ -45235,6 +45387,7 @@ const s8 rtw89_8852a_txpwr_lmt_2g[RTW89_2G_BW_NUM][RTW89_NTX_NUM] [1][1][2][0][RTW89_MEXICO][12] = 127, [1][1][2][0][RTW89_CN][12] = 127, [1][1][2][0][RTW89_QATAR][12] = 127, + [1][1][2][0][RTW89_UK][12] = 127, [1][1][2][0][RTW89_FCC][13] = 127, [1][1][2][0][RTW89_ETSI][13] = 127, [1][1][2][0][RTW89_MKK][13] = 127, @@ -45246,6 +45399,7 @@ const s8 rtw89_8852a_txpwr_lmt_2g[RTW89_2G_BW_NUM][RTW89_NTX_NUM] [1][1][2][0][RTW89_MEXICO][13] = 127, [1][1][2][0][RTW89_CN][13] = 127, [1][1][2][0][RTW89_QATAR][13] = 127, + [1][1][2][0][RTW89_UK][13] = 127, [1][1][2][1][RTW89_FCC][0] = 127, [1][1][2][1][RTW89_ETSI][0] = 127, [1][1][2][1][RTW89_MKK][0] = 127, @@ -45257,6 +45411,7 @@ const s8 rtw89_8852a_txpwr_lmt_2g[RTW89_2G_BW_NUM][RTW89_NTX_NUM] [1][1][2][1][RTW89_MEXICO][0] = 127, [1][1][2][1][RTW89_CN][0] = 127, [1][1][2][1][RTW89_QATAR][0] = 127, + [1][1][2][1][RTW89_UK][0] = 127, [1][1][2][1][RTW89_FCC][1] = 127, [1][1][2][1][RTW89_ETSI][1] = 127, [1][1][2][1][RTW89_MKK][1] = 127, @@ -45268,6 +45423,7 @@ const s8 rtw89_8852a_txpwr_lmt_2g[RTW89_2G_BW_NUM][RTW89_NTX_NUM] [1][1][2][1][RTW89_MEXICO][1] = 127, [1][1][2][1][RTW89_CN][1] = 127, [1][1][2][1][RTW89_QATAR][1] = 127, + [1][1][2][1][RTW89_UK][1] = 127, [1][1][2][1][RTW89_FCC][2] = 52, [1][1][2][1][RTW89_ETSI][2] = 34, [1][1][2][1][RTW89_MKK][2] = 64, @@ -45279,6 +45435,7 @@ const s8 rtw89_8852a_txpwr_lmt_2g[RTW89_2G_BW_NUM][RTW89_NTX_NUM] [1][1][2][1][RTW89_MEXICO][2] = 52, [1][1][2][1][RTW89_CN][2] = 34, [1][1][2][1][RTW89_QATAR][2] = 34, + [1][1][2][1][RTW89_UK][2] = 34, [1][1][2][1][RTW89_FCC][3] = 52, [1][1][2][1][RTW89_ETSI][3] = 34, [1][1][2][1][RTW89_MKK][3] = 64, @@ -45290,6 +45447,7 @@ const s8 rtw89_8852a_txpwr_lmt_2g[RTW89_2G_BW_NUM][RTW89_NTX_NUM] [1][1][2][1][RTW89_MEXICO][3] = 52, [1][1][2][1][RTW89_CN][3] = 34, [1][1][2][1][RTW89_QATAR][3] = 34, + [1][1][2][1][RTW89_UK][3] = 34, [1][1][2][1][RTW89_FCC][4] = 56, [1][1][2][1][RTW89_ETSI][4] = 34, [1][1][2][1][RTW89_MKK][4] = 64, @@ -45301,6 +45459,7 @@ const s8 rtw89_8852a_txpwr_lmt_2g[RTW89_2G_BW_NUM][RTW89_NTX_NUM] [1][1][2][1][RTW89_MEXICO][4] = 56, [1][1][2][1][RTW89_CN][4] = 34, [1][1][2][1][RTW89_QATAR][4] = 34, + [1][1][2][1][RTW89_UK][4] = 34, [1][1][2][1][RTW89_FCC][5] = 60, [1][1][2][1][RTW89_ETSI][5] = 34, [1][1][2][1][RTW89_MKK][5] = 64, @@ -45312,6 +45471,7 @@ const s8 rtw89_8852a_txpwr_lmt_2g[RTW89_2G_BW_NUM][RTW89_NTX_NUM] [1][1][2][1][RTW89_MEXICO][5] = 60, [1][1][2][1][RTW89_CN][5] = 34, [1][1][2][1][RTW89_QATAR][5] = 34, + [1][1][2][1][RTW89_UK][5] = 34, [1][1][2][1][RTW89_FCC][6] = 54, [1][1][2][1][RTW89_ETSI][6] = 34, [1][1][2][1][RTW89_MKK][6] = 64, @@ -45323,6 +45483,7 @@ const s8 rtw89_8852a_txpwr_lmt_2g[RTW89_2G_BW_NUM][RTW89_NTX_NUM] [1][1][2][1][RTW89_MEXICO][6] = 54, [1][1][2][1][RTW89_CN][6] = 34, [1][1][2][1][RTW89_QATAR][6] = 34, + [1][1][2][1][RTW89_UK][6] = 34, [1][1][2][1][RTW89_FCC][7] = 50, [1][1][2][1][RTW89_ETSI][7] = 34, [1][1][2][1][RTW89_MKK][7] = 64, @@ -45334,6 +45495,7 @@ const s8 rtw89_8852a_txpwr_lmt_2g[RTW89_2G_BW_NUM][RTW89_NTX_NUM] [1][1][2][1][RTW89_MEXICO][7] = 50, [1][1][2][1][RTW89_CN][7] = 34, [1][1][2][1][RTW89_QATAR][7] = 34, + [1][1][2][1][RTW89_UK][7] = 34, [1][1][2][1][RTW89_FCC][8] = 50, [1][1][2][1][RTW89_ETSI][8] = 34, [1][1][2][1][RTW89_MKK][8] = 64, @@ -45345,6 +45507,7 @@ const s8 rtw89_8852a_txpwr_lmt_2g[RTW89_2G_BW_NUM][RTW89_NTX_NUM] [1][1][2][1][RTW89_MEXICO][8] = 50, [1][1][2][1][RTW89_CN][8] = 34, [1][1][2][1][RTW89_QATAR][8] = 34, + [1][1][2][1][RTW89_UK][8] = 34, [1][1][2][1][RTW89_FCC][9] = 38, [1][1][2][1][RTW89_ETSI][9] = 34, [1][1][2][1][RTW89_MKK][9] = 64, @@ -45356,6 +45519,7 @@ const s8 rtw89_8852a_txpwr_lmt_2g[RTW89_2G_BW_NUM][RTW89_NTX_NUM] [1][1][2][1][RTW89_MEXICO][9] = 38, [1][1][2][1][RTW89_CN][9] = 34, [1][1][2][1][RTW89_QATAR][9] = 34, + [1][1][2][1][RTW89_UK][9] = 34, [1][1][2][1][RTW89_FCC][10] = 36, [1][1][2][1][RTW89_ETSI][10] = 34, [1][1][2][1][RTW89_MKK][10] = 64, @@ -45367,6 +45531,7 @@ const s8 rtw89_8852a_txpwr_lmt_2g[RTW89_2G_BW_NUM][RTW89_NTX_NUM] [1][1][2][1][RTW89_MEXICO][10] = 36, [1][1][2][1][RTW89_CN][10] = 34, [1][1][2][1][RTW89_QATAR][10] = 34, + [1][1][2][1][RTW89_UK][10] = 34, [1][1][2][1][RTW89_FCC][11] = 127, [1][1][2][1][RTW89_ETSI][11] = 127, [1][1][2][1][RTW89_MKK][11] = 127, @@ -45378,6 +45543,7 @@ const s8 rtw89_8852a_txpwr_lmt_2g[RTW89_2G_BW_NUM][RTW89_NTX_NUM] [1][1][2][1][RTW89_MEXICO][11] = 127, [1][1][2][1][RTW89_CN][11] = 127, [1][1][2][1][RTW89_QATAR][11] = 127, + [1][1][2][1][RTW89_UK][11] = 127, [1][1][2][1][RTW89_FCC][12] = 127, [1][1][2][1][RTW89_ETSI][12] = 127, [1][1][2][1][RTW89_MKK][12] = 127, @@ -45389,6 +45555,7 @@ const s8 rtw89_8852a_txpwr_lmt_2g[RTW89_2G_BW_NUM][RTW89_NTX_NUM] [1][1][2][1][RTW89_MEXICO][12] = 127, [1][1][2][1][RTW89_CN][12] = 127, [1][1][2][1][RTW89_QATAR][12] = 127, + [1][1][2][1][RTW89_UK][12] = 127, [1][1][2][1][RTW89_FCC][13] = 127, [1][1][2][1][RTW89_ETSI][13] = 127, [1][1][2][1][RTW89_MKK][13] = 127, @@ -45400,6 +45567,7 @@ const s8 rtw89_8852a_txpwr_lmt_2g[RTW89_2G_BW_NUM][RTW89_NTX_NUM] [1][1][2][1][RTW89_MEXICO][13] = 127, [1][1][2][1][RTW89_CN][13] = 127, [1][1][2][1][RTW89_QATAR][13] = 127, + [1][1][2][1][RTW89_UK][13] = 127, }; const s8 rtw89_8852a_txpwr_lmt_5g[RTW89_5G_BW_NUM][RTW89_NTX_NUM] @@ -45595,6 +45763,7 @@ const s8 rtw89_8852a_txpwr_lmt_5g[RTW89_5G_BW_NUM][RTW89_NTX_NUM] [0][0][1][0][RTW89_MEXICO][0] = 62, [0][0][1][0][RTW89_CN][0] = 58, [0][0][1][0][RTW89_QATAR][0] = 58, + [0][0][1][0][RTW89_UK][0] = 58, [0][0][1][0][RTW89_FCC][2] = 76, [0][0][1][0][RTW89_ETSI][2] = 58, [0][0][1][0][RTW89_MKK][2] = 62, @@ -45606,6 +45775,7 @@ const s8 rtw89_8852a_txpwr_lmt_5g[RTW89_5G_BW_NUM][RTW89_NTX_NUM] [0][0][1][0][RTW89_MEXICO][2] = 62, [0][0][1][0][RTW89_CN][2] = 58, [0][0][1][0][RTW89_QATAR][2] = 58, + [0][0][1][0][RTW89_UK][2] = 58, [0][0][1][0][RTW89_FCC][4] = 76, [0][0][1][0][RTW89_ETSI][4] = 58, [0][0][1][0][RTW89_MKK][4] = 62, @@ -45617,6 +45787,7 @@ const s8 rtw89_8852a_txpwr_lmt_5g[RTW89_5G_BW_NUM][RTW89_NTX_NUM] [0][0][1][0][RTW89_MEXICO][4] = 62, [0][0][1][0][RTW89_CN][4] = 58, [0][0][1][0][RTW89_QATAR][4] = 58, + [0][0][1][0][RTW89_UK][4] = 58, [0][0][1][0][RTW89_FCC][6] = 76, [0][0][1][0][RTW89_ETSI][6] = 58, [0][0][1][0][RTW89_MKK][6] = 62, @@ -45628,6 +45799,7 @@ const s8 rtw89_8852a_txpwr_lmt_5g[RTW89_5G_BW_NUM][RTW89_NTX_NUM] [0][0][1][0][RTW89_MEXICO][6] = 62, [0][0][1][0][RTW89_CN][6] = 58, [0][0][1][0][RTW89_QATAR][6] = 58, + [0][0][1][0][RTW89_UK][6] = 58, [0][0][1][0][RTW89_FCC][8] = 76, [0][0][1][0][RTW89_ETSI][8] = 58, [0][0][1][0][RTW89_MKK][8] = 62, @@ -45639,6 +45811,7 @@ const s8 rtw89_8852a_txpwr_lmt_5g[RTW89_5G_BW_NUM][RTW89_NTX_NUM] [0][0][1][0][RTW89_MEXICO][8] = 76, [0][0][1][0][RTW89_CN][8] = 58, [0][0][1][0][RTW89_QATAR][8] = 58, + [0][0][1][0][RTW89_UK][8] = 58, [0][0][1][0][RTW89_FCC][10] = 76, [0][0][1][0][RTW89_ETSI][10] = 58, [0][0][1][0][RTW89_MKK][10] = 62, @@ -45650,6 +45823,7 @@ const s8 rtw89_8852a_txpwr_lmt_5g[RTW89_5G_BW_NUM][RTW89_NTX_NUM] [0][0][1][0][RTW89_MEXICO][10] = 76, [0][0][1][0][RTW89_CN][10] = 58, [0][0][1][0][RTW89_QATAR][10] = 58, + [0][0][1][0][RTW89_UK][10] = 58, [0][0][1][0][RTW89_FCC][12] = 76, [0][0][1][0][RTW89_ETSI][12] = 58, [0][0][1][0][RTW89_MKK][12] = 62, @@ -45661,6 +45835,7 @@ const s8 rtw89_8852a_txpwr_lmt_5g[RTW89_5G_BW_NUM][RTW89_NTX_NUM] [0][0][1][0][RTW89_MEXICO][12] = 76, [0][0][1][0][RTW89_CN][12] = 58, [0][0][1][0][RTW89_QATAR][12] = 58, + [0][0][1][0][RTW89_UK][12] = 58, [0][0][1][0][RTW89_FCC][14] = 76, [0][0][1][0][RTW89_ETSI][14] = 58, [0][0][1][0][RTW89_MKK][14] = 62, @@ -45672,6 +45847,7 @@ const s8 rtw89_8852a_txpwr_lmt_5g[RTW89_5G_BW_NUM][RTW89_NTX_NUM] [0][0][1][0][RTW89_MEXICO][14] = 76, [0][0][1][0][RTW89_CN][14] = 58, [0][0][1][0][RTW89_QATAR][14] = 58, + [0][0][1][0][RTW89_UK][14] = 58, [0][0][1][0][RTW89_FCC][15] = 76, [0][0][1][0][RTW89_ETSI][15] = 58, [0][0][1][0][RTW89_MKK][15] = 76, @@ -45683,6 +45859,7 @@ const s8 rtw89_8852a_txpwr_lmt_5g[RTW89_5G_BW_NUM][RTW89_NTX_NUM] [0][0][1][0][RTW89_MEXICO][15] = 76, [0][0][1][0][RTW89_CN][15] = 127, [0][0][1][0][RTW89_QATAR][15] = 52, + [0][0][1][0][RTW89_UK][15] = 58, [0][0][1][0][RTW89_FCC][17] = 76, [0][0][1][0][RTW89_ETSI][17] = 58, [0][0][1][0][RTW89_MKK][17] = 76, @@ -45694,6 +45871,7 @@ const s8 rtw89_8852a_txpwr_lmt_5g[RTW89_5G_BW_NUM][RTW89_NTX_NUM] [0][0][1][0][RTW89_MEXICO][17] = 76, [0][0][1][0][RTW89_CN][17] = 127, [0][0][1][0][RTW89_QATAR][17] = 52, + [0][0][1][0][RTW89_UK][17] = 58, [0][0][1][0][RTW89_FCC][19] = 76, [0][0][1][0][RTW89_ETSI][19] = 58, [0][0][1][0][RTW89_MKK][19] = 76, @@ -45705,6 +45883,7 @@ const s8 rtw89_8852a_txpwr_lmt_5g[RTW89_5G_BW_NUM][RTW89_NTX_NUM] [0][0][1][0][RTW89_MEXICO][19] = 76, [0][0][1][0][RTW89_CN][19] = 127, [0][0][1][0][RTW89_QATAR][19] = 52, + [0][0][1][0][RTW89_UK][19] = 58, [0][0][1][0][RTW89_FCC][21] = 76, [0][0][1][0][RTW89_ETSI][21] = 58, [0][0][1][0][RTW89_MKK][21] = 76, @@ -45716,6 +45895,7 @@ const s8 rtw89_8852a_txpwr_lmt_5g[RTW89_5G_BW_NUM][RTW89_NTX_NUM] [0][0][1][0][RTW89_MEXICO][21] = 76, [0][0][1][0][RTW89_CN][21] = 127, [0][0][1][0][RTW89_QATAR][21] = 52, + [0][0][1][0][RTW89_UK][21] = 58, [0][0][1][0][RTW89_FCC][23] = 76, [0][0][1][0][RTW89_ETSI][23] = 58, [0][0][1][0][RTW89_MKK][23] = 76, @@ -45727,6 +45907,7 @@ const s8 rtw89_8852a_txpwr_lmt_5g[RTW89_5G_BW_NUM][RTW89_NTX_NUM] [0][0][1][0][RTW89_MEXICO][23] = 76, [0][0][1][0][RTW89_CN][23] = 127, [0][0][1][0][RTW89_QATAR][23] = 52, + [0][0][1][0][RTW89_UK][23] = 58, [0][0][1][0][RTW89_FCC][25] = 76, [0][0][1][0][RTW89_ETSI][25] = 58, [0][0][1][0][RTW89_MKK][25] = 76, @@ -45738,6 +45919,7 @@ const s8 rtw89_8852a_txpwr_lmt_5g[RTW89_5G_BW_NUM][RTW89_NTX_NUM] [0][0][1][0][RTW89_MEXICO][25] = 76, [0][0][1][0][RTW89_CN][25] = 127, [0][0][1][0][RTW89_QATAR][25] = 52, + [0][0][1][0][RTW89_UK][25] = 58, [0][0][1][0][RTW89_FCC][27] = 76, [0][0][1][0][RTW89_ETSI][27] = 58, [0][0][1][0][RTW89_MKK][27] = 76, @@ -45749,6 +45931,7 @@ const s8 rtw89_8852a_txpwr_lmt_5g[RTW89_5G_BW_NUM][RTW89_NTX_NUM] [0][0][1][0][RTW89_MEXICO][27] = 76, [0][0][1][0][RTW89_CN][27] = 127, [0][0][1][0][RTW89_QATAR][27] = 52, + [0][0][1][0][RTW89_UK][27] = 58, [0][0][1][0][RTW89_FCC][29] = 76, [0][0][1][0][RTW89_ETSI][29] = 58, [0][0][1][0][RTW89_MKK][29] = 76, @@ -45760,6 +45943,7 @@ const s8 rtw89_8852a_txpwr_lmt_5g[RTW89_5G_BW_NUM][RTW89_NTX_NUM] [0][0][1][0][RTW89_MEXICO][29] = 76, [0][0][1][0][RTW89_CN][29] = 127, [0][0][1][0][RTW89_QATAR][29] = 52, + [0][0][1][0][RTW89_UK][29] = 58, [0][0][1][0][RTW89_FCC][31] = 76, [0][0][1][0][RTW89_ETSI][31] = 58, [0][0][1][0][RTW89_MKK][31] = 76, @@ -45771,6 +45955,7 @@ const s8 rtw89_8852a_txpwr_lmt_5g[RTW89_5G_BW_NUM][RTW89_NTX_NUM] [0][0][1][0][RTW89_MEXICO][31] = 76, [0][0][1][0][RTW89_CN][31] = 127, [0][0][1][0][RTW89_QATAR][31] = 52, + [0][0][1][0][RTW89_UK][31] = 58, [0][0][1][0][RTW89_FCC][33] = 76, [0][0][1][0][RTW89_ETSI][33] = 58, [0][0][1][0][RTW89_MKK][33] = 76, @@ -45782,6 +45967,7 @@ const s8 rtw89_8852a_txpwr_lmt_5g[RTW89_5G_BW_NUM][RTW89_NTX_NUM] [0][0][1][0][RTW89_MEXICO][33] = 76, [0][0][1][0][RTW89_CN][33] = 127, [0][0][1][0][RTW89_QATAR][33] = 52, + [0][0][1][0][RTW89_UK][33] = 58, [0][0][1][0][RTW89_FCC][35] = 74, [0][0][1][0][RTW89_ETSI][35] = 58, [0][0][1][0][RTW89_MKK][35] = 76, @@ -45793,6 +45979,7 @@ const s8 rtw89_8852a_txpwr_lmt_5g[RTW89_5G_BW_NUM][RTW89_NTX_NUM] [0][0][1][0][RTW89_MEXICO][35] = 74, [0][0][1][0][RTW89_CN][35] = 127, [0][0][1][0][RTW89_QATAR][35] = 52, + [0][0][1][0][RTW89_UK][35] = 58, [0][0][1][0][RTW89_FCC][37] = 76, [0][0][1][0][RTW89_ETSI][37] = 127, [0][0][1][0][RTW89_MKK][37] = 76, @@ -45804,6 +45991,7 @@ const s8 rtw89_8852a_txpwr_lmt_5g[RTW89_5G_BW_NUM][RTW89_NTX_NUM] [0][0][1][0][RTW89_MEXICO][37] = 76, [0][0][1][0][RTW89_CN][37] = 127, [0][0][1][0][RTW89_QATAR][37] = 127, + [0][0][1][0][RTW89_UK][37] = 76, [0][0][1][0][RTW89_FCC][38] = 76, [0][0][1][0][RTW89_ETSI][38] = 28, [0][0][1][0][RTW89_MKK][38] = 127, @@ -45815,6 +46003,7 @@ const s8 rtw89_8852a_txpwr_lmt_5g[RTW89_5G_BW_NUM][RTW89_NTX_NUM] [0][0][1][0][RTW89_MEXICO][38] = 76, [0][0][1][0][RTW89_CN][38] = 72, [0][0][1][0][RTW89_QATAR][38] = 28, + [0][0][1][0][RTW89_UK][38] = 56, [0][0][1][0][RTW89_FCC][40] = 76, [0][0][1][0][RTW89_ETSI][40] = 28, [0][0][1][0][RTW89_MKK][40] = 127, @@ -45826,6 +46015,7 @@ const s8 rtw89_8852a_txpwr_lmt_5g[RTW89_5G_BW_NUM][RTW89_NTX_NUM] [0][0][1][0][RTW89_MEXICO][40] = 76, [0][0][1][0][RTW89_CN][40] = 76, [0][0][1][0][RTW89_QATAR][40] = 28, + [0][0][1][0][RTW89_UK][40] = 56, [0][0][1][0][RTW89_FCC][42] = 76, [0][0][1][0][RTW89_ETSI][42] = 28, [0][0][1][0][RTW89_MKK][42] = 127, @@ -45837,6 +46027,7 @@ const s8 rtw89_8852a_txpwr_lmt_5g[RTW89_5G_BW_NUM][RTW89_NTX_NUM] [0][0][1][0][RTW89_MEXICO][42] = 76, [0][0][1][0][RTW89_CN][42] = 76, [0][0][1][0][RTW89_QATAR][42] = 28, + [0][0][1][0][RTW89_UK][42] = 56, [0][0][1][0][RTW89_FCC][44] = 76, [0][0][1][0][RTW89_ETSI][44] = 28, [0][0][1][0][RTW89_MKK][44] = 127, @@ -45848,6 +46039,7 @@ const s8 rtw89_8852a_txpwr_lmt_5g[RTW89_5G_BW_NUM][RTW89_NTX_NUM] [0][0][1][0][RTW89_MEXICO][44] = 76, [0][0][1][0][RTW89_CN][44] = 76, [0][0][1][0][RTW89_QATAR][44] = 28, + [0][0][1][0][RTW89_UK][44] = 56, [0][0][1][0][RTW89_FCC][46] = 76, [0][0][1][0][RTW89_ETSI][46] = 28, [0][0][1][0][RTW89_MKK][46] = 127, @@ -45859,6 +46051,7 @@ const s8 rtw89_8852a_txpwr_lmt_5g[RTW89_5G_BW_NUM][RTW89_NTX_NUM] [0][0][1][0][RTW89_MEXICO][46] = 76, [0][0][1][0][RTW89_CN][46] = 76, [0][0][1][0][RTW89_QATAR][46] = 28, + [0][0][1][0][RTW89_UK][46] = 56, [0][1][1][0][RTW89_FCC][0] = 68, [0][1][1][0][RTW89_ETSI][0] = 46, [0][1][1][0][RTW89_MKK][0] = 50, @@ -45870,6 +46063,7 @@ const s8 rtw89_8852a_txpwr_lmt_5g[RTW89_5G_BW_NUM][RTW89_NTX_NUM] [0][1][1][0][RTW89_MEXICO][0] = 50, [0][1][1][0][RTW89_CN][0] = 46, [0][1][1][0][RTW89_QATAR][0] = 46, + [0][1][1][0][RTW89_UK][0] = 46, [0][1][1][0][RTW89_FCC][2] = 68, [0][1][1][0][RTW89_ETSI][2] = 46, [0][1][1][0][RTW89_MKK][2] = 50, @@ -45881,6 +46075,7 @@ const s8 rtw89_8852a_txpwr_lmt_5g[RTW89_5G_BW_NUM][RTW89_NTX_NUM] [0][1][1][0][RTW89_MEXICO][2] = 50, [0][1][1][0][RTW89_CN][2] = 46, [0][1][1][0][RTW89_QATAR][2] = 46, + [0][1][1][0][RTW89_UK][2] = 46, [0][1][1][0][RTW89_FCC][4] = 68, [0][1][1][0][RTW89_ETSI][4] = 46, [0][1][1][0][RTW89_MKK][4] = 50, @@ -45892,6 +46087,7 @@ const s8 rtw89_8852a_txpwr_lmt_5g[RTW89_5G_BW_NUM][RTW89_NTX_NUM] [0][1][1][0][RTW89_MEXICO][4] = 50, [0][1][1][0][RTW89_CN][4] = 46, [0][1][1][0][RTW89_QATAR][4] = 46, + [0][1][1][0][RTW89_UK][4] = 46, [0][1][1][0][RTW89_FCC][6] = 68, [0][1][1][0][RTW89_ETSI][6] = 46, [0][1][1][0][RTW89_MKK][6] = 50, @@ -45903,6 +46099,7 @@ const s8 rtw89_8852a_txpwr_lmt_5g[RTW89_5G_BW_NUM][RTW89_NTX_NUM] [0][1][1][0][RTW89_MEXICO][6] = 50, [0][1][1][0][RTW89_CN][6] = 46, [0][1][1][0][RTW89_QATAR][6] = 46, + [0][1][1][0][RTW89_UK][6] = 46, [0][1][1][0][RTW89_FCC][8] = 68, [0][1][1][0][RTW89_ETSI][8] = 46, [0][1][1][0][RTW89_MKK][8] = 50, @@ -45914,6 +46111,7 @@ const s8 rtw89_8852a_txpwr_lmt_5g[RTW89_5G_BW_NUM][RTW89_NTX_NUM] [0][1][1][0][RTW89_MEXICO][8] = 68, [0][1][1][0][RTW89_CN][8] = 46, [0][1][1][0][RTW89_QATAR][8] = 46, + [0][1][1][0][RTW89_UK][8] = 46, [0][1][1][0][RTW89_FCC][10] = 68, [0][1][1][0][RTW89_ETSI][10] = 46, [0][1][1][0][RTW89_MKK][10] = 50, @@ -45925,6 +46123,7 @@ const s8 rtw89_8852a_txpwr_lmt_5g[RTW89_5G_BW_NUM][RTW89_NTX_NUM] [0][1][1][0][RTW89_MEXICO][10] = 68, [0][1][1][0][RTW89_CN][10] = 46, [0][1][1][0][RTW89_QATAR][10] = 46, + [0][1][1][0][RTW89_UK][10] = 46, [0][1][1][0][RTW89_FCC][12] = 68, [0][1][1][0][RTW89_ETSI][12] = 46, [0][1][1][0][RTW89_MKK][12] = 50, @@ -45936,6 +46135,7 @@ const s8 rtw89_8852a_txpwr_lmt_5g[RTW89_5G_BW_NUM][RTW89_NTX_NUM] [0][1][1][0][RTW89_MEXICO][12] = 68, [0][1][1][0][RTW89_CN][12] = 46, [0][1][1][0][RTW89_QATAR][12] = 46, + [0][1][1][0][RTW89_UK][12] = 46, [0][1][1][0][RTW89_FCC][14] = 68, [0][1][1][0][RTW89_ETSI][14] = 46, [0][1][1][0][RTW89_MKK][14] = 50, @@ -45947,6 +46147,7 @@ const s8 rtw89_8852a_txpwr_lmt_5g[RTW89_5G_BW_NUM][RTW89_NTX_NUM] [0][1][1][0][RTW89_MEXICO][14] = 68, [0][1][1][0][RTW89_CN][14] = 46, [0][1][1][0][RTW89_QATAR][14] = 46, + [0][1][1][0][RTW89_UK][14] = 46, [0][1][1][0][RTW89_FCC][15] = 68, [0][1][1][0][RTW89_ETSI][15] = 46, [0][1][1][0][RTW89_MKK][15] = 70, @@ -45958,6 +46159,7 @@ const s8 rtw89_8852a_txpwr_lmt_5g[RTW89_5G_BW_NUM][RTW89_NTX_NUM] [0][1][1][0][RTW89_MEXICO][15] = 68, [0][1][1][0][RTW89_CN][15] = 127, [0][1][1][0][RTW89_QATAR][15] = 40, + [0][1][1][0][RTW89_UK][15] = 46, [0][1][1][0][RTW89_FCC][17] = 68, [0][1][1][0][RTW89_ETSI][17] = 46, [0][1][1][0][RTW89_MKK][17] = 70, @@ -45969,6 +46171,7 @@ const s8 rtw89_8852a_txpwr_lmt_5g[RTW89_5G_BW_NUM][RTW89_NTX_NUM] [0][1][1][0][RTW89_MEXICO][17] = 68, [0][1][1][0][RTW89_CN][17] = 127, [0][1][1][0][RTW89_QATAR][17] = 40, + [0][1][1][0][RTW89_UK][17] = 46, [0][1][1][0][RTW89_FCC][19] = 68, [0][1][1][0][RTW89_ETSI][19] = 46, [0][1][1][0][RTW89_MKK][19] = 70, @@ -45980,6 +46183,7 @@ const s8 rtw89_8852a_txpwr_lmt_5g[RTW89_5G_BW_NUM][RTW89_NTX_NUM] [0][1][1][0][RTW89_MEXICO][19] = 68, [0][1][1][0][RTW89_CN][19] = 127, [0][1][1][0][RTW89_QATAR][19] = 40, + [0][1][1][0][RTW89_UK][19] = 46, [0][1][1][0][RTW89_FCC][21] = 68, [0][1][1][0][RTW89_ETSI][21] = 46, [0][1][1][0][RTW89_MKK][21] = 70, @@ -45991,6 +46195,7 @@ const s8 rtw89_8852a_txpwr_lmt_5g[RTW89_5G_BW_NUM][RTW89_NTX_NUM] [0][1][1][0][RTW89_MEXICO][21] = 68, [0][1][1][0][RTW89_CN][21] = 127, [0][1][1][0][RTW89_QATAR][21] = 40, + [0][1][1][0][RTW89_UK][21] = 46, [0][1][1][0][RTW89_FCC][23] = 68, [0][1][1][0][RTW89_ETSI][23] = 46, [0][1][1][0][RTW89_MKK][23] = 70, @@ -46002,6 +46207,7 @@ const s8 rtw89_8852a_txpwr_lmt_5g[RTW89_5G_BW_NUM][RTW89_NTX_NUM] [0][1][1][0][RTW89_MEXICO][23] = 68, [0][1][1][0][RTW89_CN][23] = 127, [0][1][1][0][RTW89_QATAR][23] = 40, + [0][1][1][0][RTW89_UK][23] = 46, [0][1][1][0][RTW89_FCC][25] = 68, [0][1][1][0][RTW89_ETSI][25] = 46, [0][1][1][0][RTW89_MKK][25] = 70, @@ -46013,6 +46219,7 @@ const s8 rtw89_8852a_txpwr_lmt_5g[RTW89_5G_BW_NUM][RTW89_NTX_NUM] [0][1][1][0][RTW89_MEXICO][25] = 68, [0][1][1][0][RTW89_CN][25] = 127, [0][1][1][0][RTW89_QATAR][25] = 40, + [0][1][1][0][RTW89_UK][25] = 46, [0][1][1][0][RTW89_FCC][27] = 68, [0][1][1][0][RTW89_ETSI][27] = 46, [0][1][1][0][RTW89_MKK][27] = 70, @@ -46024,6 +46231,7 @@ const s8 rtw89_8852a_txpwr_lmt_5g[RTW89_5G_BW_NUM][RTW89_NTX_NUM] [0][1][1][0][RTW89_MEXICO][27] = 68, [0][1][1][0][RTW89_CN][27] = 127, [0][1][1][0][RTW89_QATAR][27] = 40, + [0][1][1][0][RTW89_UK][27] = 46, [0][1][1][0][RTW89_FCC][29] = 68, [0][1][1][0][RTW89_ETSI][29] = 46, [0][1][1][0][RTW89_MKK][29] = 70, @@ -46035,6 +46243,7 @@ const s8 rtw89_8852a_txpwr_lmt_5g[RTW89_5G_BW_NUM][RTW89_NTX_NUM] [0][1][1][0][RTW89_MEXICO][29] = 68, [0][1][1][0][RTW89_CN][29] = 127, [0][1][1][0][RTW89_QATAR][29] = 40, + [0][1][1][0][RTW89_UK][29] = 46, [0][1][1][0][RTW89_FCC][31] = 68, [0][1][1][0][RTW89_ETSI][31] = 46, [0][1][1][0][RTW89_MKK][31] = 70, @@ -46046,6 +46255,7 @@ const s8 rtw89_8852a_txpwr_lmt_5g[RTW89_5G_BW_NUM][RTW89_NTX_NUM] [0][1][1][0][RTW89_MEXICO][31] = 68, [0][1][1][0][RTW89_CN][31] = 127, [0][1][1][0][RTW89_QATAR][31] = 40, + [0][1][1][0][RTW89_UK][31] = 46, [0][1][1][0][RTW89_FCC][33] = 68, [0][1][1][0][RTW89_ETSI][33] = 46, [0][1][1][0][RTW89_MKK][33] = 70, @@ -46057,6 +46267,7 @@ const s8 rtw89_8852a_txpwr_lmt_5g[RTW89_5G_BW_NUM][RTW89_NTX_NUM] [0][1][1][0][RTW89_MEXICO][33] = 68, [0][1][1][0][RTW89_CN][33] = 127, [0][1][1][0][RTW89_QATAR][33] = 40, + [0][1][1][0][RTW89_UK][33] = 46, [0][1][1][0][RTW89_FCC][35] = 66, [0][1][1][0][RTW89_ETSI][35] = 46, [0][1][1][0][RTW89_MKK][35] = 70, @@ -46068,6 +46279,7 @@ const s8 rtw89_8852a_txpwr_lmt_5g[RTW89_5G_BW_NUM][RTW89_NTX_NUM] [0][1][1][0][RTW89_MEXICO][35] = 66, [0][1][1][0][RTW89_CN][35] = 127, [0][1][1][0][RTW89_QATAR][35] = 40, + [0][1][1][0][RTW89_UK][35] = 46, [0][1][1][0][RTW89_FCC][37] = 68, [0][1][1][0][RTW89_ETSI][37] = 127, [0][1][1][0][RTW89_MKK][37] = 70, @@ -46079,6 +46291,7 @@ const s8 rtw89_8852a_txpwr_lmt_5g[RTW89_5G_BW_NUM][RTW89_NTX_NUM] [0][1][1][0][RTW89_MEXICO][37] = 68, [0][1][1][0][RTW89_CN][37] = 127, [0][1][1][0][RTW89_QATAR][37] = 127, + [0][1][1][0][RTW89_UK][37] = 74, [0][1][1][0][RTW89_FCC][38] = 76, [0][1][1][0][RTW89_ETSI][38] = 16, [0][1][1][0][RTW89_MKK][38] = 127, @@ -46090,6 +46303,7 @@ const s8 rtw89_8852a_txpwr_lmt_5g[RTW89_5G_BW_NUM][RTW89_NTX_NUM] [0][1][1][0][RTW89_MEXICO][38] = 76, [0][1][1][0][RTW89_CN][38] = 72, [0][1][1][0][RTW89_QATAR][38] = 16, + [0][1][1][0][RTW89_UK][38] = 44, [0][1][1][0][RTW89_FCC][40] = 76, [0][1][1][0][RTW89_ETSI][40] = 16, [0][1][1][0][RTW89_MKK][40] = 127, @@ -46101,6 +46315,7 @@ const s8 rtw89_8852a_txpwr_lmt_5g[RTW89_5G_BW_NUM][RTW89_NTX_NUM] [0][1][1][0][RTW89_MEXICO][40] = 76, [0][1][1][0][RTW89_CN][40] = 76, [0][1][1][0][RTW89_QATAR][40] = 16, + [0][1][1][0][RTW89_UK][40] = 44, [0][1][1][0][RTW89_FCC][42] = 76, [0][1][1][0][RTW89_ETSI][42] = 16, [0][1][1][0][RTW89_MKK][42] = 127, @@ -46112,6 +46327,7 @@ const s8 rtw89_8852a_txpwr_lmt_5g[RTW89_5G_BW_NUM][RTW89_NTX_NUM] [0][1][1][0][RTW89_MEXICO][42] = 76, [0][1][1][0][RTW89_CN][42] = 76, [0][1][1][0][RTW89_QATAR][42] = 16, + [0][1][1][0][RTW89_UK][42] = 44, [0][1][1][0][RTW89_FCC][44] = 76, [0][1][1][0][RTW89_ETSI][44] = 16, [0][1][1][0][RTW89_MKK][44] = 127, @@ -46123,6 +46339,7 @@ const s8 rtw89_8852a_txpwr_lmt_5g[RTW89_5G_BW_NUM][RTW89_NTX_NUM] [0][1][1][0][RTW89_MEXICO][44] = 76, [0][1][1][0][RTW89_CN][44] = 76, [0][1][1][0][RTW89_QATAR][44] = 16, + [0][1][1][0][RTW89_UK][44] = 44, [0][1][1][0][RTW89_FCC][46] = 76, [0][1][1][0][RTW89_ETSI][46] = 16, [0][1][1][0][RTW89_MKK][46] = 127, @@ -46134,6 +46351,7 @@ const s8 rtw89_8852a_txpwr_lmt_5g[RTW89_5G_BW_NUM][RTW89_NTX_NUM] [0][1][1][0][RTW89_MEXICO][46] = 76, [0][1][1][0][RTW89_CN][46] = 76, [0][1][1][0][RTW89_QATAR][46] = 16, + [0][1][1][0][RTW89_UK][46] = 44, [0][0][2][0][RTW89_FCC][0] = 76, [0][0][2][0][RTW89_ETSI][0] = 58, [0][0][2][0][RTW89_MKK][0] = 62, @@ -46145,6 +46363,7 @@ const s8 rtw89_8852a_txpwr_lmt_5g[RTW89_5G_BW_NUM][RTW89_NTX_NUM] [0][0][2][0][RTW89_MEXICO][0] = 62, [0][0][2][0][RTW89_CN][0] = 58, [0][0][2][0][RTW89_QATAR][0] = 58, + [0][0][2][0][RTW89_UK][0] = 58, [0][0][2][0][RTW89_FCC][2] = 76, [0][0][2][0][RTW89_ETSI][2] = 58, [0][0][2][0][RTW89_MKK][2] = 62, @@ -46156,6 +46375,7 @@ const s8 rtw89_8852a_txpwr_lmt_5g[RTW89_5G_BW_NUM][RTW89_NTX_NUM] [0][0][2][0][RTW89_MEXICO][2] = 62, [0][0][2][0][RTW89_CN][2] = 58, [0][0][2][0][RTW89_QATAR][2] = 58, + [0][0][2][0][RTW89_UK][2] = 58, [0][0][2][0][RTW89_FCC][4] = 76, [0][0][2][0][RTW89_ETSI][4] = 58, [0][0][2][0][RTW89_MKK][4] = 62, @@ -46167,6 +46387,7 @@ const s8 rtw89_8852a_txpwr_lmt_5g[RTW89_5G_BW_NUM][RTW89_NTX_NUM] [0][0][2][0][RTW89_MEXICO][4] = 62, [0][0][2][0][RTW89_CN][4] = 58, [0][0][2][0][RTW89_QATAR][4] = 58, + [0][0][2][0][RTW89_UK][4] = 58, [0][0][2][0][RTW89_FCC][6] = 76, [0][0][2][0][RTW89_ETSI][6] = 58, [0][0][2][0][RTW89_MKK][6] = 62, @@ -46178,6 +46399,7 @@ const s8 rtw89_8852a_txpwr_lmt_5g[RTW89_5G_BW_NUM][RTW89_NTX_NUM] [0][0][2][0][RTW89_MEXICO][6] = 62, [0][0][2][0][RTW89_CN][6] = 58, [0][0][2][0][RTW89_QATAR][6] = 58, + [0][0][2][0][RTW89_UK][6] = 58, [0][0][2][0][RTW89_FCC][8] = 76, [0][0][2][0][RTW89_ETSI][8] = 58, [0][0][2][0][RTW89_MKK][8] = 62, @@ -46189,6 +46411,7 @@ const s8 rtw89_8852a_txpwr_lmt_5g[RTW89_5G_BW_NUM][RTW89_NTX_NUM] [0][0][2][0][RTW89_MEXICO][8] = 76, [0][0][2][0][RTW89_CN][8] = 58, [0][0][2][0][RTW89_QATAR][8] = 58, + [0][0][2][0][RTW89_UK][8] = 58, [0][0][2][0][RTW89_FCC][10] = 76, [0][0][2][0][RTW89_ETSI][10] = 58, [0][0][2][0][RTW89_MKK][10] = 62, @@ -46200,6 +46423,7 @@ const s8 rtw89_8852a_txpwr_lmt_5g[RTW89_5G_BW_NUM][RTW89_NTX_NUM] [0][0][2][0][RTW89_MEXICO][10] = 76, [0][0][2][0][RTW89_CN][10] = 58, [0][0][2][0][RTW89_QATAR][10] = 58, + [0][0][2][0][RTW89_UK][10] = 58, [0][0][2][0][RTW89_FCC][12] = 76, [0][0][2][0][RTW89_ETSI][12] = 58, [0][0][2][0][RTW89_MKK][12] = 62, @@ -46211,6 +46435,7 @@ const s8 rtw89_8852a_txpwr_lmt_5g[RTW89_5G_BW_NUM][RTW89_NTX_NUM] [0][0][2][0][RTW89_MEXICO][12] = 76, [0][0][2][0][RTW89_CN][12] = 58, [0][0][2][0][RTW89_QATAR][12] = 58, + [0][0][2][0][RTW89_UK][12] = 58, [0][0][2][0][RTW89_FCC][14] = 76, [0][0][2][0][RTW89_ETSI][14] = 58, [0][0][2][0][RTW89_MKK][14] = 62, @@ -46222,6 +46447,7 @@ const s8 rtw89_8852a_txpwr_lmt_5g[RTW89_5G_BW_NUM][RTW89_NTX_NUM] [0][0][2][0][RTW89_MEXICO][14] = 76, [0][0][2][0][RTW89_CN][14] = 58, [0][0][2][0][RTW89_QATAR][14] = 58, + [0][0][2][0][RTW89_UK][14] = 58, [0][0][2][0][RTW89_FCC][15] = 74, [0][0][2][0][RTW89_ETSI][15] = 58, [0][0][2][0][RTW89_MKK][15] = 76, @@ -46233,6 +46459,7 @@ const s8 rtw89_8852a_txpwr_lmt_5g[RTW89_5G_BW_NUM][RTW89_NTX_NUM] [0][0][2][0][RTW89_MEXICO][15] = 74, [0][0][2][0][RTW89_CN][15] = 127, [0][0][2][0][RTW89_QATAR][15] = 52, + [0][0][2][0][RTW89_UK][15] = 58, [0][0][2][0][RTW89_FCC][17] = 76, [0][0][2][0][RTW89_ETSI][17] = 58, [0][0][2][0][RTW89_MKK][17] = 76, @@ -46244,6 +46471,7 @@ const s8 rtw89_8852a_txpwr_lmt_5g[RTW89_5G_BW_NUM][RTW89_NTX_NUM] [0][0][2][0][RTW89_MEXICO][17] = 76, [0][0][2][0][RTW89_CN][17] = 127, [0][0][2][0][RTW89_QATAR][17] = 52, + [0][0][2][0][RTW89_UK][17] = 58, [0][0][2][0][RTW89_FCC][19] = 76, [0][0][2][0][RTW89_ETSI][19] = 58, [0][0][2][0][RTW89_MKK][19] = 76, @@ -46255,6 +46483,7 @@ const s8 rtw89_8852a_txpwr_lmt_5g[RTW89_5G_BW_NUM][RTW89_NTX_NUM] [0][0][2][0][RTW89_MEXICO][19] = 76, [0][0][2][0][RTW89_CN][19] = 127, [0][0][2][0][RTW89_QATAR][19] = 52, + [0][0][2][0][RTW89_UK][19] = 58, [0][0][2][0][RTW89_FCC][21] = 76, [0][0][2][0][RTW89_ETSI][21] = 58, [0][0][2][0][RTW89_MKK][21] = 76, @@ -46266,6 +46495,7 @@ const s8 rtw89_8852a_txpwr_lmt_5g[RTW89_5G_BW_NUM][RTW89_NTX_NUM] [0][0][2][0][RTW89_MEXICO][21] = 76, [0][0][2][0][RTW89_CN][21] = 127, [0][0][2][0][RTW89_QATAR][21] = 52, + [0][0][2][0][RTW89_UK][21] = 58, [0][0][2][0][RTW89_FCC][23] = 76, [0][0][2][0][RTW89_ETSI][23] = 58, [0][0][2][0][RTW89_MKK][23] = 76, @@ -46277,6 +46507,7 @@ const s8 rtw89_8852a_txpwr_lmt_5g[RTW89_5G_BW_NUM][RTW89_NTX_NUM] [0][0][2][0][RTW89_MEXICO][23] = 76, [0][0][2][0][RTW89_CN][23] = 127, [0][0][2][0][RTW89_QATAR][23] = 52, + [0][0][2][0][RTW89_UK][23] = 58, [0][0][2][0][RTW89_FCC][25] = 76, [0][0][2][0][RTW89_ETSI][25] = 58, [0][0][2][0][RTW89_MKK][25] = 76, @@ -46288,6 +46519,7 @@ const s8 rtw89_8852a_txpwr_lmt_5g[RTW89_5G_BW_NUM][RTW89_NTX_NUM] [0][0][2][0][RTW89_MEXICO][25] = 76, [0][0][2][0][RTW89_CN][25] = 127, [0][0][2][0][RTW89_QATAR][25] = 52, + [0][0][2][0][RTW89_UK][25] = 58, [0][0][2][0][RTW89_FCC][27] = 76, [0][0][2][0][RTW89_ETSI][27] = 58, [0][0][2][0][RTW89_MKK][27] = 76, @@ -46299,6 +46531,7 @@ const s8 rtw89_8852a_txpwr_lmt_5g[RTW89_5G_BW_NUM][RTW89_NTX_NUM] [0][0][2][0][RTW89_MEXICO][27] = 76, [0][0][2][0][RTW89_CN][27] = 127, [0][0][2][0][RTW89_QATAR][27] = 52, + [0][0][2][0][RTW89_UK][27] = 58, [0][0][2][0][RTW89_FCC][29] = 76, [0][0][2][0][RTW89_ETSI][29] = 58, [0][0][2][0][RTW89_MKK][29] = 76, @@ -46310,6 +46543,7 @@ const s8 rtw89_8852a_txpwr_lmt_5g[RTW89_5G_BW_NUM][RTW89_NTX_NUM] [0][0][2][0][RTW89_MEXICO][29] = 76, [0][0][2][0][RTW89_CN][29] = 127, [0][0][2][0][RTW89_QATAR][29] = 52, + [0][0][2][0][RTW89_UK][29] = 58, [0][0][2][0][RTW89_FCC][31] = 76, [0][0][2][0][RTW89_ETSI][31] = 58, [0][0][2][0][RTW89_MKK][31] = 76, @@ -46321,6 +46555,7 @@ const s8 rtw89_8852a_txpwr_lmt_5g[RTW89_5G_BW_NUM][RTW89_NTX_NUM] [0][0][2][0][RTW89_MEXICO][31] = 76, [0][0][2][0][RTW89_CN][31] = 127, [0][0][2][0][RTW89_QATAR][31] = 52, + [0][0][2][0][RTW89_UK][31] = 58, [0][0][2][0][RTW89_FCC][33] = 76, [0][0][2][0][RTW89_ETSI][33] = 58, [0][0][2][0][RTW89_MKK][33] = 76, @@ -46332,6 +46567,7 @@ const s8 rtw89_8852a_txpwr_lmt_5g[RTW89_5G_BW_NUM][RTW89_NTX_NUM] [0][0][2][0][RTW89_MEXICO][33] = 76, [0][0][2][0][RTW89_CN][33] = 127, [0][0][2][0][RTW89_QATAR][33] = 52, + [0][0][2][0][RTW89_UK][33] = 58, [0][0][2][0][RTW89_FCC][35] = 70, [0][0][2][0][RTW89_ETSI][35] = 58, [0][0][2][0][RTW89_MKK][35] = 76, @@ -46343,6 +46579,7 @@ const s8 rtw89_8852a_txpwr_lmt_5g[RTW89_5G_BW_NUM][RTW89_NTX_NUM] [0][0][2][0][RTW89_MEXICO][35] = 70, [0][0][2][0][RTW89_CN][35] = 127, [0][0][2][0][RTW89_QATAR][35] = 52, + [0][0][2][0][RTW89_UK][35] = 58, [0][0][2][0][RTW89_FCC][37] = 76, [0][0][2][0][RTW89_ETSI][37] = 127, [0][0][2][0][RTW89_MKK][37] = 76, @@ -46354,6 +46591,7 @@ const s8 rtw89_8852a_txpwr_lmt_5g[RTW89_5G_BW_NUM][RTW89_NTX_NUM] [0][0][2][0][RTW89_MEXICO][37] = 76, [0][0][2][0][RTW89_CN][37] = 127, [0][0][2][0][RTW89_QATAR][37] = 127, + [0][0][2][0][RTW89_UK][37] = 76, [0][0][2][0][RTW89_FCC][38] = 76, [0][0][2][0][RTW89_ETSI][38] = 28, [0][0][2][0][RTW89_MKK][38] = 127, @@ -46365,6 +46603,7 @@ const s8 rtw89_8852a_txpwr_lmt_5g[RTW89_5G_BW_NUM][RTW89_NTX_NUM] [0][0][2][0][RTW89_MEXICO][38] = 76, [0][0][2][0][RTW89_CN][38] = 68, [0][0][2][0][RTW89_QATAR][38] = 28, + [0][0][2][0][RTW89_UK][38] = 58, [0][0][2][0][RTW89_FCC][40] = 76, [0][0][2][0][RTW89_ETSI][40] = 28, [0][0][2][0][RTW89_MKK][40] = 127, @@ -46376,6 +46615,7 @@ const s8 rtw89_8852a_txpwr_lmt_5g[RTW89_5G_BW_NUM][RTW89_NTX_NUM] [0][0][2][0][RTW89_MEXICO][40] = 76, [0][0][2][0][RTW89_CN][40] = 76, [0][0][2][0][RTW89_QATAR][40] = 28, + [0][0][2][0][RTW89_UK][40] = 58, [0][0][2][0][RTW89_FCC][42] = 76, [0][0][2][0][RTW89_ETSI][42] = 28, [0][0][2][0][RTW89_MKK][42] = 127, @@ -46387,6 +46627,7 @@ const s8 rtw89_8852a_txpwr_lmt_5g[RTW89_5G_BW_NUM][RTW89_NTX_NUM] [0][0][2][0][RTW89_MEXICO][42] = 76, [0][0][2][0][RTW89_CN][42] = 76, [0][0][2][0][RTW89_QATAR][42] = 28, + [0][0][2][0][RTW89_UK][42] = 58, [0][0][2][0][RTW89_FCC][44] = 76, [0][0][2][0][RTW89_ETSI][44] = 28, [0][0][2][0][RTW89_MKK][44] = 127, @@ -46398,6 +46639,7 @@ const s8 rtw89_8852a_txpwr_lmt_5g[RTW89_5G_BW_NUM][RTW89_NTX_NUM] [0][0][2][0][RTW89_MEXICO][44] = 76, [0][0][2][0][RTW89_CN][44] = 76, [0][0][2][0][RTW89_QATAR][44] = 28, + [0][0][2][0][RTW89_UK][44] = 58, [0][0][2][0][RTW89_FCC][46] = 76, [0][0][2][0][RTW89_ETSI][46] = 28, [0][0][2][0][RTW89_MKK][46] = 127, @@ -46409,6 +46651,7 @@ const s8 rtw89_8852a_txpwr_lmt_5g[RTW89_5G_BW_NUM][RTW89_NTX_NUM] [0][0][2][0][RTW89_MEXICO][46] = 76, [0][0][2][0][RTW89_CN][46] = 76, [0][0][2][0][RTW89_QATAR][46] = 28, + [0][0][2][0][RTW89_UK][46] = 58, [0][1][2][0][RTW89_FCC][0] = 68, [0][1][2][0][RTW89_ETSI][0] = 46, [0][1][2][0][RTW89_MKK][0] = 50, @@ -46420,6 +46663,7 @@ const s8 rtw89_8852a_txpwr_lmt_5g[RTW89_5G_BW_NUM][RTW89_NTX_NUM] [0][1][2][0][RTW89_MEXICO][0] = 50, [0][1][2][0][RTW89_CN][0] = 46, [0][1][2][0][RTW89_QATAR][0] = 46, + [0][1][2][0][RTW89_UK][0] = 46, [0][1][2][0][RTW89_FCC][2] = 68, [0][1][2][0][RTW89_ETSI][2] = 46, [0][1][2][0][RTW89_MKK][2] = 50, @@ -46431,6 +46675,7 @@ const s8 rtw89_8852a_txpwr_lmt_5g[RTW89_5G_BW_NUM][RTW89_NTX_NUM] [0][1][2][0][RTW89_MEXICO][2] = 50, [0][1][2][0][RTW89_CN][2] = 46, [0][1][2][0][RTW89_QATAR][2] = 46, + [0][1][2][0][RTW89_UK][2] = 46, [0][1][2][0][RTW89_FCC][4] = 68, [0][1][2][0][RTW89_ETSI][4] = 46, [0][1][2][0][RTW89_MKK][4] = 50, @@ -46442,6 +46687,7 @@ const s8 rtw89_8852a_txpwr_lmt_5g[RTW89_5G_BW_NUM][RTW89_NTX_NUM] [0][1][2][0][RTW89_MEXICO][4] = 50, [0][1][2][0][RTW89_CN][4] = 46, [0][1][2][0][RTW89_QATAR][4] = 46, + [0][1][2][0][RTW89_UK][4] = 46, [0][1][2][0][RTW89_FCC][6] = 68, [0][1][2][0][RTW89_ETSI][6] = 46, [0][1][2][0][RTW89_MKK][6] = 50, @@ -46453,6 +46699,7 @@ const s8 rtw89_8852a_txpwr_lmt_5g[RTW89_5G_BW_NUM][RTW89_NTX_NUM] [0][1][2][0][RTW89_MEXICO][6] = 50, [0][1][2][0][RTW89_CN][6] = 46, [0][1][2][0][RTW89_QATAR][6] = 46, + [0][1][2][0][RTW89_UK][6] = 46, [0][1][2][0][RTW89_FCC][8] = 68, [0][1][2][0][RTW89_ETSI][8] = 46, [0][1][2][0][RTW89_MKK][8] = 50, @@ -46464,6 +46711,7 @@ const s8 rtw89_8852a_txpwr_lmt_5g[RTW89_5G_BW_NUM][RTW89_NTX_NUM] [0][1][2][0][RTW89_MEXICO][8] = 68, [0][1][2][0][RTW89_CN][8] = 46, [0][1][2][0][RTW89_QATAR][8] = 46, + [0][1][2][0][RTW89_UK][8] = 46, [0][1][2][0][RTW89_FCC][10] = 68, [0][1][2][0][RTW89_ETSI][10] = 46, [0][1][2][0][RTW89_MKK][10] = 50, @@ -46475,6 +46723,7 @@ const s8 rtw89_8852a_txpwr_lmt_5g[RTW89_5G_BW_NUM][RTW89_NTX_NUM] [0][1][2][0][RTW89_MEXICO][10] = 68, [0][1][2][0][RTW89_CN][10] = 46, [0][1][2][0][RTW89_QATAR][10] = 46, + [0][1][2][0][RTW89_UK][10] = 46, [0][1][2][0][RTW89_FCC][12] = 68, [0][1][2][0][RTW89_ETSI][12] = 46, [0][1][2][0][RTW89_MKK][12] = 50, @@ -46486,6 +46735,7 @@ const s8 rtw89_8852a_txpwr_lmt_5g[RTW89_5G_BW_NUM][RTW89_NTX_NUM] [0][1][2][0][RTW89_MEXICO][12] = 68, [0][1][2][0][RTW89_CN][12] = 46, [0][1][2][0][RTW89_QATAR][12] = 46, + [0][1][2][0][RTW89_UK][12] = 46, [0][1][2][0][RTW89_FCC][14] = 68, [0][1][2][0][RTW89_ETSI][14] = 46, [0][1][2][0][RTW89_MKK][14] = 50, @@ -46497,6 +46747,7 @@ const s8 rtw89_8852a_txpwr_lmt_5g[RTW89_5G_BW_NUM][RTW89_NTX_NUM] [0][1][2][0][RTW89_MEXICO][14] = 68, [0][1][2][0][RTW89_CN][14] = 46, [0][1][2][0][RTW89_QATAR][14] = 46, + [0][1][2][0][RTW89_UK][14] = 46, [0][1][2][0][RTW89_FCC][15] = 68, [0][1][2][0][RTW89_ETSI][15] = 46, [0][1][2][0][RTW89_MKK][15] = 70, @@ -46508,6 +46759,7 @@ const s8 rtw89_8852a_txpwr_lmt_5g[RTW89_5G_BW_NUM][RTW89_NTX_NUM] [0][1][2][0][RTW89_MEXICO][15] = 68, [0][1][2][0][RTW89_CN][15] = 127, [0][1][2][0][RTW89_QATAR][15] = 40, + [0][1][2][0][RTW89_UK][15] = 46, [0][1][2][0][RTW89_FCC][17] = 68, [0][1][2][0][RTW89_ETSI][17] = 46, [0][1][2][0][RTW89_MKK][17] = 70, @@ -46519,6 +46771,7 @@ const s8 rtw89_8852a_txpwr_lmt_5g[RTW89_5G_BW_NUM][RTW89_NTX_NUM] [0][1][2][0][RTW89_MEXICO][17] = 68, [0][1][2][0][RTW89_CN][17] = 127, [0][1][2][0][RTW89_QATAR][17] = 40, + [0][1][2][0][RTW89_UK][17] = 46, [0][1][2][0][RTW89_FCC][19] = 68, [0][1][2][0][RTW89_ETSI][19] = 46, [0][1][2][0][RTW89_MKK][19] = 70, @@ -46530,6 +46783,7 @@ const s8 rtw89_8852a_txpwr_lmt_5g[RTW89_5G_BW_NUM][RTW89_NTX_NUM] [0][1][2][0][RTW89_MEXICO][19] = 68, [0][1][2][0][RTW89_CN][19] = 127, [0][1][2][0][RTW89_QATAR][19] = 40, + [0][1][2][0][RTW89_UK][19] = 46, [0][1][2][0][RTW89_FCC][21] = 68, [0][1][2][0][RTW89_ETSI][21] = 46, [0][1][2][0][RTW89_MKK][21] = 70, @@ -46541,6 +46795,7 @@ const s8 rtw89_8852a_txpwr_lmt_5g[RTW89_5G_BW_NUM][RTW89_NTX_NUM] [0][1][2][0][RTW89_MEXICO][21] = 68, [0][1][2][0][RTW89_CN][21] = 127, [0][1][2][0][RTW89_QATAR][21] = 40, + [0][1][2][0][RTW89_UK][21] = 46, [0][1][2][0][RTW89_FCC][23] = 68, [0][1][2][0][RTW89_ETSI][23] = 46, [0][1][2][0][RTW89_MKK][23] = 70, @@ -46552,6 +46807,7 @@ const s8 rtw89_8852a_txpwr_lmt_5g[RTW89_5G_BW_NUM][RTW89_NTX_NUM] [0][1][2][0][RTW89_MEXICO][23] = 68, [0][1][2][0][RTW89_CN][23] = 127, [0][1][2][0][RTW89_QATAR][23] = 40, + [0][1][2][0][RTW89_UK][23] = 46, [0][1][2][0][RTW89_FCC][25] = 68, [0][1][2][0][RTW89_ETSI][25] = 46, [0][1][2][0][RTW89_MKK][25] = 70, @@ -46563,6 +46819,7 @@ const s8 rtw89_8852a_txpwr_lmt_5g[RTW89_5G_BW_NUM][RTW89_NTX_NUM] [0][1][2][0][RTW89_MEXICO][25] = 68, [0][1][2][0][RTW89_CN][25] = 127, [0][1][2][0][RTW89_QATAR][25] = 40, + [0][1][2][0][RTW89_UK][25] = 46, [0][1][2][0][RTW89_FCC][27] = 68, [0][1][2][0][RTW89_ETSI][27] = 46, [0][1][2][0][RTW89_MKK][27] = 70, @@ -46574,6 +46831,7 @@ const s8 rtw89_8852a_txpwr_lmt_5g[RTW89_5G_BW_NUM][RTW89_NTX_NUM] [0][1][2][0][RTW89_MEXICO][27] = 68, [0][1][2][0][RTW89_CN][27] = 127, [0][1][2][0][RTW89_QATAR][27] = 40, + [0][1][2][0][RTW89_UK][27] = 46, [0][1][2][0][RTW89_FCC][29] = 68, [0][1][2][0][RTW89_ETSI][29] = 46, [0][1][2][0][RTW89_MKK][29] = 70, @@ -46585,6 +46843,7 @@ const s8 rtw89_8852a_txpwr_lmt_5g[RTW89_5G_BW_NUM][RTW89_NTX_NUM] [0][1][2][0][RTW89_MEXICO][29] = 68, [0][1][2][0][RTW89_CN][29] = 127, [0][1][2][0][RTW89_QATAR][29] = 40, + [0][1][2][0][RTW89_UK][29] = 46, [0][1][2][0][RTW89_FCC][31] = 68, [0][1][2][0][RTW89_ETSI][31] = 46, [0][1][2][0][RTW89_MKK][31] = 70, @@ -46596,6 +46855,7 @@ const s8 rtw89_8852a_txpwr_lmt_5g[RTW89_5G_BW_NUM][RTW89_NTX_NUM] [0][1][2][0][RTW89_MEXICO][31] = 68, [0][1][2][0][RTW89_CN][31] = 127, [0][1][2][0][RTW89_QATAR][31] = 40, + [0][1][2][0][RTW89_UK][31] = 46, [0][1][2][0][RTW89_FCC][33] = 68, [0][1][2][0][RTW89_ETSI][33] = 46, [0][1][2][0][RTW89_MKK][33] = 70, @@ -46607,6 +46867,7 @@ const s8 rtw89_8852a_txpwr_lmt_5g[RTW89_5G_BW_NUM][RTW89_NTX_NUM] [0][1][2][0][RTW89_MEXICO][33] = 68, [0][1][2][0][RTW89_CN][33] = 127, [0][1][2][0][RTW89_QATAR][33] = 40, + [0][1][2][0][RTW89_UK][33] = 46, [0][1][2][0][RTW89_FCC][35] = 64, [0][1][2][0][RTW89_ETSI][35] = 46, [0][1][2][0][RTW89_MKK][35] = 70, @@ -46618,6 +46879,7 @@ const s8 rtw89_8852a_txpwr_lmt_5g[RTW89_5G_BW_NUM][RTW89_NTX_NUM] [0][1][2][0][RTW89_MEXICO][35] = 64, [0][1][2][0][RTW89_CN][35] = 127, [0][1][2][0][RTW89_QATAR][35] = 40, + [0][1][2][0][RTW89_UK][35] = 46, [0][1][2][0][RTW89_FCC][37] = 68, [0][1][2][0][RTW89_ETSI][37] = 127, [0][1][2][0][RTW89_MKK][37] = 70, @@ -46629,6 +46891,7 @@ const s8 rtw89_8852a_txpwr_lmt_5g[RTW89_5G_BW_NUM][RTW89_NTX_NUM] [0][1][2][0][RTW89_MEXICO][37] = 68, [0][1][2][0][RTW89_CN][37] = 127, [0][1][2][0][RTW89_QATAR][37] = 127, + [0][1][2][0][RTW89_UK][37] = 74, [0][1][2][0][RTW89_FCC][38] = 76, [0][1][2][0][RTW89_ETSI][38] = 16, [0][1][2][0][RTW89_MKK][38] = 127, @@ -46640,6 +46903,7 @@ const s8 rtw89_8852a_txpwr_lmt_5g[RTW89_5G_BW_NUM][RTW89_NTX_NUM] [0][1][2][0][RTW89_MEXICO][38] = 76, [0][1][2][0][RTW89_CN][38] = 68, [0][1][2][0][RTW89_QATAR][38] = 16, + [0][1][2][0][RTW89_UK][38] = 46, [0][1][2][0][RTW89_FCC][40] = 76, [0][1][2][0][RTW89_ETSI][40] = 16, [0][1][2][0][RTW89_MKK][40] = 127, @@ -46651,6 +46915,7 @@ const s8 rtw89_8852a_txpwr_lmt_5g[RTW89_5G_BW_NUM][RTW89_NTX_NUM] [0][1][2][0][RTW89_MEXICO][40] = 76, [0][1][2][0][RTW89_CN][40] = 76, [0][1][2][0][RTW89_QATAR][40] = 16, + [0][1][2][0][RTW89_UK][40] = 46, [0][1][2][0][RTW89_FCC][42] = 76, [0][1][2][0][RTW89_ETSI][42] = 16, [0][1][2][0][RTW89_MKK][42] = 127, @@ -46662,6 +46927,7 @@ const s8 rtw89_8852a_txpwr_lmt_5g[RTW89_5G_BW_NUM][RTW89_NTX_NUM] [0][1][2][0][RTW89_MEXICO][42] = 76, [0][1][2][0][RTW89_CN][42] = 76, [0][1][2][0][RTW89_QATAR][42] = 16, + [0][1][2][0][RTW89_UK][42] = 46, [0][1][2][0][RTW89_FCC][44] = 76, [0][1][2][0][RTW89_ETSI][44] = 16, [0][1][2][0][RTW89_MKK][44] = 127, @@ -46673,6 +46939,7 @@ const s8 rtw89_8852a_txpwr_lmt_5g[RTW89_5G_BW_NUM][RTW89_NTX_NUM] [0][1][2][0][RTW89_MEXICO][44] = 76, [0][1][2][0][RTW89_CN][44] = 76, [0][1][2][0][RTW89_QATAR][44] = 16, + [0][1][2][0][RTW89_UK][44] = 46, [0][1][2][0][RTW89_FCC][46] = 76, [0][1][2][0][RTW89_ETSI][46] = 16, [0][1][2][0][RTW89_MKK][46] = 127, @@ -46684,6 +46951,7 @@ const s8 rtw89_8852a_txpwr_lmt_5g[RTW89_5G_BW_NUM][RTW89_NTX_NUM] [0][1][2][0][RTW89_MEXICO][46] = 76, [0][1][2][0][RTW89_CN][46] = 76, [0][1][2][0][RTW89_QATAR][46] = 16, + [0][1][2][0][RTW89_UK][46] = 46, [0][1][2][1][RTW89_FCC][0] = 68, [0][1][2][1][RTW89_ETSI][0] = 34, [0][1][2][1][RTW89_MKK][0] = 50, @@ -46695,6 +46963,7 @@ const s8 rtw89_8852a_txpwr_lmt_5g[RTW89_5G_BW_NUM][RTW89_NTX_NUM] [0][1][2][1][RTW89_MEXICO][0] = 50, [0][1][2][1][RTW89_CN][0] = 34, [0][1][2][1][RTW89_QATAR][0] = 34, + [0][1][2][1][RTW89_UK][0] = 34, [0][1][2][1][RTW89_FCC][2] = 68, [0][1][2][1][RTW89_ETSI][2] = 34, [0][1][2][1][RTW89_MKK][2] = 50, @@ -46706,6 +46975,7 @@ const s8 rtw89_8852a_txpwr_lmt_5g[RTW89_5G_BW_NUM][RTW89_NTX_NUM] [0][1][2][1][RTW89_MEXICO][2] = 50, [0][1][2][1][RTW89_CN][2] = 34, [0][1][2][1][RTW89_QATAR][2] = 34, + [0][1][2][1][RTW89_UK][2] = 34, [0][1][2][1][RTW89_FCC][4] = 68, [0][1][2][1][RTW89_ETSI][4] = 34, [0][1][2][1][RTW89_MKK][4] = 50, @@ -46717,6 +46987,7 @@ const s8 rtw89_8852a_txpwr_lmt_5g[RTW89_5G_BW_NUM][RTW89_NTX_NUM] [0][1][2][1][RTW89_MEXICO][4] = 50, [0][1][2][1][RTW89_CN][4] = 34, [0][1][2][1][RTW89_QATAR][4] = 34, + [0][1][2][1][RTW89_UK][4] = 34, [0][1][2][1][RTW89_FCC][6] = 68, [0][1][2][1][RTW89_ETSI][6] = 34, [0][1][2][1][RTW89_MKK][6] = 50, @@ -46728,6 +46999,7 @@ const s8 rtw89_8852a_txpwr_lmt_5g[RTW89_5G_BW_NUM][RTW89_NTX_NUM] [0][1][2][1][RTW89_MEXICO][6] = 50, [0][1][2][1][RTW89_CN][6] = 34, [0][1][2][1][RTW89_QATAR][6] = 34, + [0][1][2][1][RTW89_UK][6] = 34, [0][1][2][1][RTW89_FCC][8] = 68, [0][1][2][1][RTW89_ETSI][8] = 34, [0][1][2][1][RTW89_MKK][8] = 50, @@ -46739,6 +47011,7 @@ const s8 rtw89_8852a_txpwr_lmt_5g[RTW89_5G_BW_NUM][RTW89_NTX_NUM] [0][1][2][1][RTW89_MEXICO][8] = 68, [0][1][2][1][RTW89_CN][8] = 34, [0][1][2][1][RTW89_QATAR][8] = 34, + [0][1][2][1][RTW89_UK][8] = 34, [0][1][2][1][RTW89_FCC][10] = 68, [0][1][2][1][RTW89_ETSI][10] = 34, [0][1][2][1][RTW89_MKK][10] = 50, @@ -46750,6 +47023,7 @@ const s8 rtw89_8852a_txpwr_lmt_5g[RTW89_5G_BW_NUM][RTW89_NTX_NUM] [0][1][2][1][RTW89_MEXICO][10] = 68, [0][1][2][1][RTW89_CN][10] = 34, [0][1][2][1][RTW89_QATAR][10] = 34, + [0][1][2][1][RTW89_UK][10] = 34, [0][1][2][1][RTW89_FCC][12] = 68, [0][1][2][1][RTW89_ETSI][12] = 34, [0][1][2][1][RTW89_MKK][12] = 50, @@ -46761,6 +47035,7 @@ const s8 rtw89_8852a_txpwr_lmt_5g[RTW89_5G_BW_NUM][RTW89_NTX_NUM] [0][1][2][1][RTW89_MEXICO][12] = 68, [0][1][2][1][RTW89_CN][12] = 34, [0][1][2][1][RTW89_QATAR][12] = 34, + [0][1][2][1][RTW89_UK][12] = 34, [0][1][2][1][RTW89_FCC][14] = 68, [0][1][2][1][RTW89_ETSI][14] = 34, [0][1][2][1][RTW89_MKK][14] = 50, @@ -46772,6 +47047,7 @@ const s8 rtw89_8852a_txpwr_lmt_5g[RTW89_5G_BW_NUM][RTW89_NTX_NUM] [0][1][2][1][RTW89_MEXICO][14] = 68, [0][1][2][1][RTW89_CN][14] = 34, [0][1][2][1][RTW89_QATAR][14] = 34, + [0][1][2][1][RTW89_UK][14] = 34, [0][1][2][1][RTW89_FCC][15] = 68, [0][1][2][1][RTW89_ETSI][15] = 34, [0][1][2][1][RTW89_MKK][15] = 70, @@ -46783,6 +47059,7 @@ const s8 rtw89_8852a_txpwr_lmt_5g[RTW89_5G_BW_NUM][RTW89_NTX_NUM] [0][1][2][1][RTW89_MEXICO][15] = 68, [0][1][2][1][RTW89_CN][15] = 127, [0][1][2][1][RTW89_QATAR][15] = 28, + [0][1][2][1][RTW89_UK][15] = 34, [0][1][2][1][RTW89_FCC][17] = 68, [0][1][2][1][RTW89_ETSI][17] = 34, [0][1][2][1][RTW89_MKK][17] = 70, @@ -46794,6 +47071,7 @@ const s8 rtw89_8852a_txpwr_lmt_5g[RTW89_5G_BW_NUM][RTW89_NTX_NUM] [0][1][2][1][RTW89_MEXICO][17] = 68, [0][1][2][1][RTW89_CN][17] = 127, [0][1][2][1][RTW89_QATAR][17] = 28, + [0][1][2][1][RTW89_UK][17] = 34, [0][1][2][1][RTW89_FCC][19] = 68, [0][1][2][1][RTW89_ETSI][19] = 34, [0][1][2][1][RTW89_MKK][19] = 70, @@ -46805,6 +47083,7 @@ const s8 rtw89_8852a_txpwr_lmt_5g[RTW89_5G_BW_NUM][RTW89_NTX_NUM] [0][1][2][1][RTW89_MEXICO][19] = 68, [0][1][2][1][RTW89_CN][19] = 127, [0][1][2][1][RTW89_QATAR][19] = 28, + [0][1][2][1][RTW89_UK][19] = 34, [0][1][2][1][RTW89_FCC][21] = 68, [0][1][2][1][RTW89_ETSI][21] = 34, [0][1][2][1][RTW89_MKK][21] = 70, @@ -46816,6 +47095,7 @@ const s8 rtw89_8852a_txpwr_lmt_5g[RTW89_5G_BW_NUM][RTW89_NTX_NUM] [0][1][2][1][RTW89_MEXICO][21] = 68, [0][1][2][1][RTW89_CN][21] = 127, [0][1][2][1][RTW89_QATAR][21] = 28, + [0][1][2][1][RTW89_UK][21] = 34, [0][1][2][1][RTW89_FCC][23] = 68, [0][1][2][1][RTW89_ETSI][23] = 34, [0][1][2][1][RTW89_MKK][23] = 70, @@ -46827,6 +47107,7 @@ const s8 rtw89_8852a_txpwr_lmt_5g[RTW89_5G_BW_NUM][RTW89_NTX_NUM] [0][1][2][1][RTW89_MEXICO][23] = 68, [0][1][2][1][RTW89_CN][23] = 127, [0][1][2][1][RTW89_QATAR][23] = 28, + [0][1][2][1][RTW89_UK][23] = 34, [0][1][2][1][RTW89_FCC][25] = 68, [0][1][2][1][RTW89_ETSI][25] = 34, [0][1][2][1][RTW89_MKK][25] = 70, @@ -46838,6 +47119,7 @@ const s8 rtw89_8852a_txpwr_lmt_5g[RTW89_5G_BW_NUM][RTW89_NTX_NUM] [0][1][2][1][RTW89_MEXICO][25] = 68, [0][1][2][1][RTW89_CN][25] = 127, [0][1][2][1][RTW89_QATAR][25] = 28, + [0][1][2][1][RTW89_UK][25] = 34, [0][1][2][1][RTW89_FCC][27] = 68, [0][1][2][1][RTW89_ETSI][27] = 34, [0][1][2][1][RTW89_MKK][27] = 70, @@ -46849,6 +47131,7 @@ const s8 rtw89_8852a_txpwr_lmt_5g[RTW89_5G_BW_NUM][RTW89_NTX_NUM] [0][1][2][1][RTW89_MEXICO][27] = 68, [0][1][2][1][RTW89_CN][27] = 127, [0][1][2][1][RTW89_QATAR][27] = 28, + [0][1][2][1][RTW89_UK][27] = 34, [0][1][2][1][RTW89_FCC][29] = 68, [0][1][2][1][RTW89_ETSI][29] = 34, [0][1][2][1][RTW89_MKK][29] = 70, @@ -46860,6 +47143,7 @@ const s8 rtw89_8852a_txpwr_lmt_5g[RTW89_5G_BW_NUM][RTW89_NTX_NUM] [0][1][2][1][RTW89_MEXICO][29] = 68, [0][1][2][1][RTW89_CN][29] = 127, [0][1][2][1][RTW89_QATAR][29] = 28, + [0][1][2][1][RTW89_UK][29] = 34, [0][1][2][1][RTW89_FCC][31] = 68, [0][1][2][1][RTW89_ETSI][31] = 34, [0][1][2][1][RTW89_MKK][31] = 70, @@ -46871,6 +47155,7 @@ const s8 rtw89_8852a_txpwr_lmt_5g[RTW89_5G_BW_NUM][RTW89_NTX_NUM] [0][1][2][1][RTW89_MEXICO][31] = 68, [0][1][2][1][RTW89_CN][31] = 127, [0][1][2][1][RTW89_QATAR][31] = 28, + [0][1][2][1][RTW89_UK][31] = 34, [0][1][2][1][RTW89_FCC][33] = 68, [0][1][2][1][RTW89_ETSI][33] = 34, [0][1][2][1][RTW89_MKK][33] = 70, @@ -46882,6 +47167,7 @@ const s8 rtw89_8852a_txpwr_lmt_5g[RTW89_5G_BW_NUM][RTW89_NTX_NUM] [0][1][2][1][RTW89_MEXICO][33] = 68, [0][1][2][1][RTW89_CN][33] = 127, [0][1][2][1][RTW89_QATAR][33] = 28, + [0][1][2][1][RTW89_UK][33] = 34, [0][1][2][1][RTW89_FCC][35] = 64, [0][1][2][1][RTW89_ETSI][35] = 34, [0][1][2][1][RTW89_MKK][35] = 70, @@ -46893,6 +47179,7 @@ const s8 rtw89_8852a_txpwr_lmt_5g[RTW89_5G_BW_NUM][RTW89_NTX_NUM] [0][1][2][1][RTW89_MEXICO][35] = 64, [0][1][2][1][RTW89_CN][35] = 127, [0][1][2][1][RTW89_QATAR][35] = 28, + [0][1][2][1][RTW89_UK][35] = 34, [0][1][2][1][RTW89_FCC][37] = 68, [0][1][2][1][RTW89_ETSI][37] = 127, [0][1][2][1][RTW89_MKK][37] = 70, @@ -46904,6 +47191,7 @@ const s8 rtw89_8852a_txpwr_lmt_5g[RTW89_5G_BW_NUM][RTW89_NTX_NUM] [0][1][2][1][RTW89_MEXICO][37] = 68, [0][1][2][1][RTW89_CN][37] = 127, [0][1][2][1][RTW89_QATAR][37] = 127, + [0][1][2][1][RTW89_UK][37] = 62, [0][1][2][1][RTW89_FCC][38] = 76, [0][1][2][1][RTW89_ETSI][38] = 4, [0][1][2][1][RTW89_MKK][38] = 127, @@ -46915,6 +47203,7 @@ const s8 rtw89_8852a_txpwr_lmt_5g[RTW89_5G_BW_NUM][RTW89_NTX_NUM] [0][1][2][1][RTW89_MEXICO][38] = 76, [0][1][2][1][RTW89_CN][38] = 68, [0][1][2][1][RTW89_QATAR][38] = 4, + [0][1][2][1][RTW89_UK][38] = 34, [0][1][2][1][RTW89_FCC][40] = 76, [0][1][2][1][RTW89_ETSI][40] = 4, [0][1][2][1][RTW89_MKK][40] = 127, @@ -46926,6 +47215,7 @@ const s8 rtw89_8852a_txpwr_lmt_5g[RTW89_5G_BW_NUM][RTW89_NTX_NUM] [0][1][2][1][RTW89_MEXICO][40] = 76, [0][1][2][1][RTW89_CN][40] = 70, [0][1][2][1][RTW89_QATAR][40] = 4, + [0][1][2][1][RTW89_UK][40] = 34, [0][1][2][1][RTW89_FCC][42] = 76, [0][1][2][1][RTW89_ETSI][42] = 4, [0][1][2][1][RTW89_MKK][42] = 127, @@ -46937,6 +47227,7 @@ const s8 rtw89_8852a_txpwr_lmt_5g[RTW89_5G_BW_NUM][RTW89_NTX_NUM] [0][1][2][1][RTW89_MEXICO][42] = 76, [0][1][2][1][RTW89_CN][42] = 70, [0][1][2][1][RTW89_QATAR][42] = 4, + [0][1][2][1][RTW89_UK][42] = 34, [0][1][2][1][RTW89_FCC][44] = 76, [0][1][2][1][RTW89_ETSI][44] = 4, [0][1][2][1][RTW89_MKK][44] = 127, @@ -46948,6 +47239,7 @@ const s8 rtw89_8852a_txpwr_lmt_5g[RTW89_5G_BW_NUM][RTW89_NTX_NUM] [0][1][2][1][RTW89_MEXICO][44] = 76, [0][1][2][1][RTW89_CN][44] = 70, [0][1][2][1][RTW89_QATAR][44] = 4, + [0][1][2][1][RTW89_UK][44] = 34, [0][1][2][1][RTW89_FCC][46] = 76, [0][1][2][1][RTW89_ETSI][46] = 4, [0][1][2][1][RTW89_MKK][46] = 127, @@ -46959,6 +47251,7 @@ const s8 rtw89_8852a_txpwr_lmt_5g[RTW89_5G_BW_NUM][RTW89_NTX_NUM] [0][1][2][1][RTW89_MEXICO][46] = 76, [0][1][2][1][RTW89_CN][46] = 70, [0][1][2][1][RTW89_QATAR][46] = 4, + [0][1][2][1][RTW89_UK][46] = 34, [1][0][2][0][RTW89_FCC][1] = 68, [1][0][2][0][RTW89_ETSI][1] = 64, [1][0][2][0][RTW89_MKK][1] = 62, @@ -46970,6 +47263,7 @@ const s8 rtw89_8852a_txpwr_lmt_5g[RTW89_5G_BW_NUM][RTW89_NTX_NUM] [1][0][2][0][RTW89_MEXICO][1] = 62, [1][0][2][0][RTW89_CN][1] = 64, [1][0][2][0][RTW89_QATAR][1] = 64, + [1][0][2][0][RTW89_UK][1] = 64, [1][0][2][0][RTW89_FCC][5] = 72, [1][0][2][0][RTW89_ETSI][5] = 64, [1][0][2][0][RTW89_MKK][5] = 62, @@ -46981,6 +47275,7 @@ const s8 rtw89_8852a_txpwr_lmt_5g[RTW89_5G_BW_NUM][RTW89_NTX_NUM] [1][0][2][0][RTW89_MEXICO][5] = 62, [1][0][2][0][RTW89_CN][5] = 64, [1][0][2][0][RTW89_QATAR][5] = 64, + [1][0][2][0][RTW89_UK][5] = 64, [1][0][2][0][RTW89_FCC][9] = 72, [1][0][2][0][RTW89_ETSI][9] = 64, [1][0][2][0][RTW89_MKK][9] = 62, @@ -46992,6 +47287,7 @@ const s8 rtw89_8852a_txpwr_lmt_5g[RTW89_5G_BW_NUM][RTW89_NTX_NUM] [1][0][2][0][RTW89_MEXICO][9] = 72, [1][0][2][0][RTW89_CN][9] = 64, [1][0][2][0][RTW89_QATAR][9] = 64, + [1][0][2][0][RTW89_UK][9] = 64, [1][0][2][0][RTW89_FCC][13] = 66, [1][0][2][0][RTW89_ETSI][13] = 64, [1][0][2][0][RTW89_MKK][13] = 62, @@ -47003,6 +47299,7 @@ const s8 rtw89_8852a_txpwr_lmt_5g[RTW89_5G_BW_NUM][RTW89_NTX_NUM] [1][0][2][0][RTW89_MEXICO][13] = 66, [1][0][2][0][RTW89_CN][13] = 64, [1][0][2][0][RTW89_QATAR][13] = 64, + [1][0][2][0][RTW89_UK][13] = 64, [1][0][2][0][RTW89_FCC][16] = 62, [1][0][2][0][RTW89_ETSI][16] = 64, [1][0][2][0][RTW89_MKK][16] = 72, @@ -47014,6 +47311,7 @@ const s8 rtw89_8852a_txpwr_lmt_5g[RTW89_5G_BW_NUM][RTW89_NTX_NUM] [1][0][2][0][RTW89_MEXICO][16] = 62, [1][0][2][0][RTW89_CN][16] = 127, [1][0][2][0][RTW89_QATAR][16] = 52, + [1][0][2][0][RTW89_UK][16] = 64, [1][0][2][0][RTW89_FCC][20] = 72, [1][0][2][0][RTW89_ETSI][20] = 64, [1][0][2][0][RTW89_MKK][20] = 72, @@ -47025,6 +47323,7 @@ const s8 rtw89_8852a_txpwr_lmt_5g[RTW89_5G_BW_NUM][RTW89_NTX_NUM] [1][0][2][0][RTW89_MEXICO][20] = 72, [1][0][2][0][RTW89_CN][20] = 127, [1][0][2][0][RTW89_QATAR][20] = 52, + [1][0][2][0][RTW89_UK][20] = 64, [1][0][2][0][RTW89_FCC][24] = 72, [1][0][2][0][RTW89_ETSI][24] = 64, [1][0][2][0][RTW89_MKK][24] = 72, @@ -47036,6 +47335,7 @@ const s8 rtw89_8852a_txpwr_lmt_5g[RTW89_5G_BW_NUM][RTW89_NTX_NUM] [1][0][2][0][RTW89_MEXICO][24] = 72, [1][0][2][0][RTW89_CN][24] = 127, [1][0][2][0][RTW89_QATAR][24] = 52, + [1][0][2][0][RTW89_UK][24] = 64, [1][0][2][0][RTW89_FCC][28] = 72, [1][0][2][0][RTW89_ETSI][28] = 64, [1][0][2][0][RTW89_MKK][28] = 72, @@ -47047,6 +47347,7 @@ const s8 rtw89_8852a_txpwr_lmt_5g[RTW89_5G_BW_NUM][RTW89_NTX_NUM] [1][0][2][0][RTW89_MEXICO][28] = 72, [1][0][2][0][RTW89_CN][28] = 127, [1][0][2][0][RTW89_QATAR][28] = 52, + [1][0][2][0][RTW89_UK][28] = 64, [1][0][2][0][RTW89_FCC][32] = 72, [1][0][2][0][RTW89_ETSI][32] = 64, [1][0][2][0][RTW89_MKK][32] = 72, @@ -47058,6 +47359,7 @@ const s8 rtw89_8852a_txpwr_lmt_5g[RTW89_5G_BW_NUM][RTW89_NTX_NUM] [1][0][2][0][RTW89_MEXICO][32] = 72, [1][0][2][0][RTW89_CN][32] = 127, [1][0][2][0][RTW89_QATAR][32] = 52, + [1][0][2][0][RTW89_UK][32] = 64, [1][0][2][0][RTW89_FCC][36] = 72, [1][0][2][0][RTW89_ETSI][36] = 127, [1][0][2][0][RTW89_MKK][36] = 72, @@ -47069,6 +47371,7 @@ const s8 rtw89_8852a_txpwr_lmt_5g[RTW89_5G_BW_NUM][RTW89_NTX_NUM] [1][0][2][0][RTW89_MEXICO][36] = 72, [1][0][2][0][RTW89_CN][36] = 127, [1][0][2][0][RTW89_QATAR][36] = 127, + [1][0][2][0][RTW89_UK][36] = 72, [1][0][2][0][RTW89_FCC][39] = 72, [1][0][2][0][RTW89_ETSI][39] = 28, [1][0][2][0][RTW89_MKK][39] = 127, @@ -47080,6 +47383,7 @@ const s8 rtw89_8852a_txpwr_lmt_5g[RTW89_5G_BW_NUM][RTW89_NTX_NUM] [1][0][2][0][RTW89_MEXICO][39] = 72, [1][0][2][0][RTW89_CN][39] = 68, [1][0][2][0][RTW89_QATAR][39] = 28, + [1][0][2][0][RTW89_UK][39] = 64, [1][0][2][0][RTW89_FCC][43] = 72, [1][0][2][0][RTW89_ETSI][43] = 28, [1][0][2][0][RTW89_MKK][43] = 127, @@ -47091,6 +47395,7 @@ const s8 rtw89_8852a_txpwr_lmt_5g[RTW89_5G_BW_NUM][RTW89_NTX_NUM] [1][0][2][0][RTW89_MEXICO][43] = 72, [1][0][2][0][RTW89_CN][43] = 72, [1][0][2][0][RTW89_QATAR][43] = 28, + [1][0][2][0][RTW89_UK][43] = 64, [1][1][2][0][RTW89_FCC][1] = 58, [1][1][2][0][RTW89_ETSI][1] = 52, [1][1][2][0][RTW89_MKK][1] = 50, @@ -47102,6 +47407,7 @@ const s8 rtw89_8852a_txpwr_lmt_5g[RTW89_5G_BW_NUM][RTW89_NTX_NUM] [1][1][2][0][RTW89_MEXICO][1] = 50, [1][1][2][0][RTW89_CN][1] = 52, [1][1][2][0][RTW89_QATAR][1] = 52, + [1][1][2][0][RTW89_UK][1] = 52, [1][1][2][0][RTW89_FCC][5] = 72, [1][1][2][0][RTW89_ETSI][5] = 52, [1][1][2][0][RTW89_MKK][5] = 50, @@ -47113,6 +47419,7 @@ const s8 rtw89_8852a_txpwr_lmt_5g[RTW89_5G_BW_NUM][RTW89_NTX_NUM] [1][1][2][0][RTW89_MEXICO][5] = 50, [1][1][2][0][RTW89_CN][5] = 52, [1][1][2][0][RTW89_QATAR][5] = 52, + [1][1][2][0][RTW89_UK][5] = 52, [1][1][2][0][RTW89_FCC][9] = 72, [1][1][2][0][RTW89_ETSI][9] = 52, [1][1][2][0][RTW89_MKK][9] = 50, @@ -47124,6 +47431,7 @@ const s8 rtw89_8852a_txpwr_lmt_5g[RTW89_5G_BW_NUM][RTW89_NTX_NUM] [1][1][2][0][RTW89_MEXICO][9] = 72, [1][1][2][0][RTW89_CN][9] = 52, [1][1][2][0][RTW89_QATAR][9] = 52, + [1][1][2][0][RTW89_UK][9] = 52, [1][1][2][0][RTW89_FCC][13] = 58, [1][1][2][0][RTW89_ETSI][13] = 52, [1][1][2][0][RTW89_MKK][13] = 50, @@ -47135,6 +47443,7 @@ const s8 rtw89_8852a_txpwr_lmt_5g[RTW89_5G_BW_NUM][RTW89_NTX_NUM] [1][1][2][0][RTW89_MEXICO][13] = 58, [1][1][2][0][RTW89_CN][13] = 52, [1][1][2][0][RTW89_QATAR][13] = 52, + [1][1][2][0][RTW89_UK][13] = 52, [1][1][2][0][RTW89_FCC][16] = 56, [1][1][2][0][RTW89_ETSI][16] = 52, [1][1][2][0][RTW89_MKK][16] = 72, @@ -47146,6 +47455,7 @@ const s8 rtw89_8852a_txpwr_lmt_5g[RTW89_5G_BW_NUM][RTW89_NTX_NUM] [1][1][2][0][RTW89_MEXICO][16] = 56, [1][1][2][0][RTW89_CN][16] = 127, [1][1][2][0][RTW89_QATAR][16] = 40, + [1][1][2][0][RTW89_UK][16] = 52, [1][1][2][0][RTW89_FCC][20] = 72, [1][1][2][0][RTW89_ETSI][20] = 52, [1][1][2][0][RTW89_MKK][20] = 72, @@ -47157,6 +47467,7 @@ const s8 rtw89_8852a_txpwr_lmt_5g[RTW89_5G_BW_NUM][RTW89_NTX_NUM] [1][1][2][0][RTW89_MEXICO][20] = 72, [1][1][2][0][RTW89_CN][20] = 127, [1][1][2][0][RTW89_QATAR][20] = 40, + [1][1][2][0][RTW89_UK][20] = 52, [1][1][2][0][RTW89_FCC][24] = 72, [1][1][2][0][RTW89_ETSI][24] = 52, [1][1][2][0][RTW89_MKK][24] = 72, @@ -47168,6 +47479,7 @@ const s8 rtw89_8852a_txpwr_lmt_5g[RTW89_5G_BW_NUM][RTW89_NTX_NUM] [1][1][2][0][RTW89_MEXICO][24] = 72, [1][1][2][0][RTW89_CN][24] = 127, [1][1][2][0][RTW89_QATAR][24] = 40, + [1][1][2][0][RTW89_UK][24] = 52, [1][1][2][0][RTW89_FCC][28] = 72, [1][1][2][0][RTW89_ETSI][28] = 52, [1][1][2][0][RTW89_MKK][28] = 72, @@ -47179,6 +47491,7 @@ const s8 rtw89_8852a_txpwr_lmt_5g[RTW89_5G_BW_NUM][RTW89_NTX_NUM] [1][1][2][0][RTW89_MEXICO][28] = 72, [1][1][2][0][RTW89_CN][28] = 127, [1][1][2][0][RTW89_QATAR][28] = 40, + [1][1][2][0][RTW89_UK][28] = 52, [1][1][2][0][RTW89_FCC][32] = 68, [1][1][2][0][RTW89_ETSI][32] = 52, [1][1][2][0][RTW89_MKK][32] = 72, @@ -47190,6 +47503,7 @@ const s8 rtw89_8852a_txpwr_lmt_5g[RTW89_5G_BW_NUM][RTW89_NTX_NUM] [1][1][2][0][RTW89_MEXICO][32] = 68, [1][1][2][0][RTW89_CN][32] = 127, [1][1][2][0][RTW89_QATAR][32] = 40, + [1][1][2][0][RTW89_UK][32] = 52, [1][1][2][0][RTW89_FCC][36] = 72, [1][1][2][0][RTW89_ETSI][36] = 127, [1][1][2][0][RTW89_MKK][36] = 72, @@ -47201,6 +47515,7 @@ const s8 rtw89_8852a_txpwr_lmt_5g[RTW89_5G_BW_NUM][RTW89_NTX_NUM] [1][1][2][0][RTW89_MEXICO][36] = 72, [1][1][2][0][RTW89_CN][36] = 127, [1][1][2][0][RTW89_QATAR][36] = 127, + [1][1][2][0][RTW89_UK][36] = 72, [1][1][2][0][RTW89_FCC][39] = 72, [1][1][2][0][RTW89_ETSI][39] = 16, [1][1][2][0][RTW89_MKK][39] = 127, @@ -47212,6 +47527,7 @@ const s8 rtw89_8852a_txpwr_lmt_5g[RTW89_5G_BW_NUM][RTW89_NTX_NUM] [1][1][2][0][RTW89_MEXICO][39] = 72, [1][1][2][0][RTW89_CN][39] = 68, [1][1][2][0][RTW89_QATAR][39] = 16, + [1][1][2][0][RTW89_UK][39] = 52, [1][1][2][0][RTW89_FCC][43] = 72, [1][1][2][0][RTW89_ETSI][43] = 16, [1][1][2][0][RTW89_MKK][43] = 127, @@ -47223,6 +47539,7 @@ const s8 rtw89_8852a_txpwr_lmt_5g[RTW89_5G_BW_NUM][RTW89_NTX_NUM] [1][1][2][0][RTW89_MEXICO][43] = 72, [1][1][2][0][RTW89_CN][43] = 72, [1][1][2][0][RTW89_QATAR][43] = 16, + [1][1][2][0][RTW89_UK][43] = 52, [1][1][2][1][RTW89_FCC][1] = 58, [1][1][2][1][RTW89_ETSI][1] = 40, [1][1][2][1][RTW89_MKK][1] = 50, @@ -47234,6 +47551,7 @@ const s8 rtw89_8852a_txpwr_lmt_5g[RTW89_5G_BW_NUM][RTW89_NTX_NUM] [1][1][2][1][RTW89_MEXICO][1] = 50, [1][1][2][1][RTW89_CN][1] = 40, [1][1][2][1][RTW89_QATAR][1] = 40, + [1][1][2][1][RTW89_UK][1] = 40, [1][1][2][1][RTW89_FCC][5] = 68, [1][1][2][1][RTW89_ETSI][5] = 40, [1][1][2][1][RTW89_MKK][5] = 50, @@ -47245,6 +47563,7 @@ const s8 rtw89_8852a_txpwr_lmt_5g[RTW89_5G_BW_NUM][RTW89_NTX_NUM] [1][1][2][1][RTW89_MEXICO][5] = 50, [1][1][2][1][RTW89_CN][5] = 40, [1][1][2][1][RTW89_QATAR][5] = 40, + [1][1][2][1][RTW89_UK][5] = 40, [1][1][2][1][RTW89_FCC][9] = 68, [1][1][2][1][RTW89_ETSI][9] = 40, [1][1][2][1][RTW89_MKK][9] = 50, @@ -47256,6 +47575,7 @@ const s8 rtw89_8852a_txpwr_lmt_5g[RTW89_5G_BW_NUM][RTW89_NTX_NUM] [1][1][2][1][RTW89_MEXICO][9] = 68, [1][1][2][1][RTW89_CN][9] = 40, [1][1][2][1][RTW89_QATAR][9] = 40, + [1][1][2][1][RTW89_UK][9] = 40, [1][1][2][1][RTW89_FCC][13] = 58, [1][1][2][1][RTW89_ETSI][13] = 40, [1][1][2][1][RTW89_MKK][13] = 50, @@ -47267,6 +47587,7 @@ const s8 rtw89_8852a_txpwr_lmt_5g[RTW89_5G_BW_NUM][RTW89_NTX_NUM] [1][1][2][1][RTW89_MEXICO][13] = 58, [1][1][2][1][RTW89_CN][13] = 40, [1][1][2][1][RTW89_QATAR][13] = 40, + [1][1][2][1][RTW89_UK][13] = 40, [1][1][2][1][RTW89_FCC][16] = 56, [1][1][2][1][RTW89_ETSI][16] = 40, [1][1][2][1][RTW89_MKK][16] = 72, @@ -47278,6 +47599,7 @@ const s8 rtw89_8852a_txpwr_lmt_5g[RTW89_5G_BW_NUM][RTW89_NTX_NUM] [1][1][2][1][RTW89_MEXICO][16] = 56, [1][1][2][1][RTW89_CN][16] = 127, [1][1][2][1][RTW89_QATAR][16] = 28, + [1][1][2][1][RTW89_UK][16] = 40, [1][1][2][1][RTW89_FCC][20] = 68, [1][1][2][1][RTW89_ETSI][20] = 40, [1][1][2][1][RTW89_MKK][20] = 72, @@ -47289,6 +47611,7 @@ const s8 rtw89_8852a_txpwr_lmt_5g[RTW89_5G_BW_NUM][RTW89_NTX_NUM] [1][1][2][1][RTW89_MEXICO][20] = 68, [1][1][2][1][RTW89_CN][20] = 127, [1][1][2][1][RTW89_QATAR][20] = 28, + [1][1][2][1][RTW89_UK][20] = 40, [1][1][2][1][RTW89_FCC][24] = 68, [1][1][2][1][RTW89_ETSI][24] = 40, [1][1][2][1][RTW89_MKK][24] = 72, @@ -47300,6 +47623,7 @@ const s8 rtw89_8852a_txpwr_lmt_5g[RTW89_5G_BW_NUM][RTW89_NTX_NUM] [1][1][2][1][RTW89_MEXICO][24] = 68, [1][1][2][1][RTW89_CN][24] = 127, [1][1][2][1][RTW89_QATAR][24] = 28, + [1][1][2][1][RTW89_UK][24] = 40, [1][1][2][1][RTW89_FCC][28] = 68, [1][1][2][1][RTW89_ETSI][28] = 40, [1][1][2][1][RTW89_MKK][28] = 72, @@ -47311,6 +47635,7 @@ const s8 rtw89_8852a_txpwr_lmt_5g[RTW89_5G_BW_NUM][RTW89_NTX_NUM] [1][1][2][1][RTW89_MEXICO][28] = 68, [1][1][2][1][RTW89_CN][28] = 127, [1][1][2][1][RTW89_QATAR][28] = 28, + [1][1][2][1][RTW89_UK][28] = 40, [1][1][2][1][RTW89_FCC][32] = 68, [1][1][2][1][RTW89_ETSI][32] = 40, [1][1][2][1][RTW89_MKK][32] = 72, @@ -47322,6 +47647,7 @@ const s8 rtw89_8852a_txpwr_lmt_5g[RTW89_5G_BW_NUM][RTW89_NTX_NUM] [1][1][2][1][RTW89_MEXICO][32] = 68, [1][1][2][1][RTW89_CN][32] = 127, [1][1][2][1][RTW89_QATAR][32] = 28, + [1][1][2][1][RTW89_UK][32] = 40, [1][1][2][1][RTW89_FCC][36] = 68, [1][1][2][1][RTW89_ETSI][36] = 127, [1][1][2][1][RTW89_MKK][36] = 72, @@ -47333,6 +47659,7 @@ const s8 rtw89_8852a_txpwr_lmt_5g[RTW89_5G_BW_NUM][RTW89_NTX_NUM] [1][1][2][1][RTW89_MEXICO][36] = 68, [1][1][2][1][RTW89_CN][36] = 127, [1][1][2][1][RTW89_QATAR][36] = 127, + [1][1][2][1][RTW89_UK][36] = 66, [1][1][2][1][RTW89_FCC][39] = 72, [1][1][2][1][RTW89_ETSI][39] = 4, [1][1][2][1][RTW89_MKK][39] = 127, @@ -47344,6 +47671,7 @@ const s8 rtw89_8852a_txpwr_lmt_5g[RTW89_5G_BW_NUM][RTW89_NTX_NUM] [1][1][2][1][RTW89_MEXICO][39] = 72, [1][1][2][1][RTW89_CN][39] = 62, [1][1][2][1][RTW89_QATAR][39] = 4, + [1][1][2][1][RTW89_UK][39] = 40, [1][1][2][1][RTW89_FCC][43] = 72, [1][1][2][1][RTW89_ETSI][43] = 4, [1][1][2][1][RTW89_MKK][43] = 127, @@ -47355,6 +47683,7 @@ const s8 rtw89_8852a_txpwr_lmt_5g[RTW89_5G_BW_NUM][RTW89_NTX_NUM] [1][1][2][1][RTW89_MEXICO][43] = 72, [1][1][2][1][RTW89_CN][43] = 72, [1][1][2][1][RTW89_QATAR][43] = 4, + [1][1][2][1][RTW89_UK][43] = 40, [2][0][2][0][RTW89_FCC][3] = 64, [2][0][2][0][RTW89_ETSI][3] = 64, [2][0][2][0][RTW89_MKK][3] = 64, @@ -47366,6 +47695,7 @@ const s8 rtw89_8852a_txpwr_lmt_5g[RTW89_5G_BW_NUM][RTW89_NTX_NUM] [2][0][2][0][RTW89_MEXICO][3] = 62, [2][0][2][0][RTW89_CN][3] = 64, [2][0][2][0][RTW89_QATAR][3] = 64, + [2][0][2][0][RTW89_UK][3] = 64, [2][0][2][0][RTW89_FCC][11] = 64, [2][0][2][0][RTW89_ETSI][11] = 64, [2][0][2][0][RTW89_MKK][11] = 64, @@ -47377,6 +47707,7 @@ const s8 rtw89_8852a_txpwr_lmt_5g[RTW89_5G_BW_NUM][RTW89_NTX_NUM] [2][0][2][0][RTW89_MEXICO][11] = 64, [2][0][2][0][RTW89_CN][11] = 64, [2][0][2][0][RTW89_QATAR][11] = 64, + [2][0][2][0][RTW89_UK][11] = 64, [2][0][2][0][RTW89_FCC][18] = 62, [2][0][2][0][RTW89_ETSI][18] = 64, [2][0][2][0][RTW89_MKK][18] = 72, @@ -47388,6 +47719,7 @@ const s8 rtw89_8852a_txpwr_lmt_5g[RTW89_5G_BW_NUM][RTW89_NTX_NUM] [2][0][2][0][RTW89_MEXICO][18] = 62, [2][0][2][0][RTW89_CN][18] = 127, [2][0][2][0][RTW89_QATAR][18] = 52, + [2][0][2][0][RTW89_UK][18] = 64, [2][0][2][0][RTW89_FCC][26] = 72, [2][0][2][0][RTW89_ETSI][26] = 64, [2][0][2][0][RTW89_MKK][26] = 72, @@ -47399,6 +47731,7 @@ const s8 rtw89_8852a_txpwr_lmt_5g[RTW89_5G_BW_NUM][RTW89_NTX_NUM] [2][0][2][0][RTW89_MEXICO][26] = 72, [2][0][2][0][RTW89_CN][26] = 127, [2][0][2][0][RTW89_QATAR][26] = 52, + [2][0][2][0][RTW89_UK][26] = 64, [2][0][2][0][RTW89_FCC][34] = 72, [2][0][2][0][RTW89_ETSI][34] = 127, [2][0][2][0][RTW89_MKK][34] = 72, @@ -47410,6 +47743,7 @@ const s8 rtw89_8852a_txpwr_lmt_5g[RTW89_5G_BW_NUM][RTW89_NTX_NUM] [2][0][2][0][RTW89_MEXICO][34] = 72, [2][0][2][0][RTW89_CN][34] = 127, [2][0][2][0][RTW89_QATAR][34] = 127, + [2][0][2][0][RTW89_UK][34] = 72, [2][0][2][0][RTW89_FCC][41] = 72, [2][0][2][0][RTW89_ETSI][41] = 28, [2][0][2][0][RTW89_MKK][41] = 127, @@ -47421,6 +47755,7 @@ const s8 rtw89_8852a_txpwr_lmt_5g[RTW89_5G_BW_NUM][RTW89_NTX_NUM] [2][0][2][0][RTW89_MEXICO][41] = 72, [2][0][2][0][RTW89_CN][41] = 68, [2][0][2][0][RTW89_QATAR][41] = 28, + [2][0][2][0][RTW89_UK][41] = 64, [2][1][2][0][RTW89_FCC][3] = 56, [2][1][2][0][RTW89_ETSI][3] = 52, [2][1][2][0][RTW89_MKK][3] = 52, @@ -47432,6 +47767,7 @@ const s8 rtw89_8852a_txpwr_lmt_5g[RTW89_5G_BW_NUM][RTW89_NTX_NUM] [2][1][2][0][RTW89_MEXICO][3] = 50, [2][1][2][0][RTW89_CN][3] = 52, [2][1][2][0][RTW89_QATAR][3] = 52, + [2][1][2][0][RTW89_UK][3] = 52, [2][1][2][0][RTW89_FCC][11] = 56, [2][1][2][0][RTW89_ETSI][11] = 52, [2][1][2][0][RTW89_MKK][11] = 52, @@ -47443,6 +47779,7 @@ const s8 rtw89_8852a_txpwr_lmt_5g[RTW89_5G_BW_NUM][RTW89_NTX_NUM] [2][1][2][0][RTW89_MEXICO][11] = 56, [2][1][2][0][RTW89_CN][11] = 52, [2][1][2][0][RTW89_QATAR][11] = 52, + [2][1][2][0][RTW89_UK][11] = 52, [2][1][2][0][RTW89_FCC][18] = 56, [2][1][2][0][RTW89_ETSI][18] = 52, [2][1][2][0][RTW89_MKK][18] = 72, @@ -47454,6 +47791,7 @@ const s8 rtw89_8852a_txpwr_lmt_5g[RTW89_5G_BW_NUM][RTW89_NTX_NUM] [2][1][2][0][RTW89_MEXICO][18] = 56, [2][1][2][0][RTW89_CN][18] = 127, [2][1][2][0][RTW89_QATAR][18] = 40, + [2][1][2][0][RTW89_UK][18] = 52, [2][1][2][0][RTW89_FCC][26] = 72, [2][1][2][0][RTW89_ETSI][26] = 52, [2][1][2][0][RTW89_MKK][26] = 72, @@ -47465,6 +47803,7 @@ const s8 rtw89_8852a_txpwr_lmt_5g[RTW89_5G_BW_NUM][RTW89_NTX_NUM] [2][1][2][0][RTW89_MEXICO][26] = 72, [2][1][2][0][RTW89_CN][26] = 127, [2][1][2][0][RTW89_QATAR][26] = 40, + [2][1][2][0][RTW89_UK][26] = 52, [2][1][2][0][RTW89_FCC][34] = 72, [2][1][2][0][RTW89_ETSI][34] = 127, [2][1][2][0][RTW89_MKK][34] = 72, @@ -47476,6 +47815,7 @@ const s8 rtw89_8852a_txpwr_lmt_5g[RTW89_5G_BW_NUM][RTW89_NTX_NUM] [2][1][2][0][RTW89_MEXICO][34] = 72, [2][1][2][0][RTW89_CN][34] = 127, [2][1][2][0][RTW89_QATAR][34] = 127, + [2][1][2][0][RTW89_UK][34] = 72, [2][1][2][0][RTW89_FCC][41] = 72, [2][1][2][0][RTW89_ETSI][41] = 16, [2][1][2][0][RTW89_MKK][41] = 127, @@ -47487,6 +47827,7 @@ const s8 rtw89_8852a_txpwr_lmt_5g[RTW89_5G_BW_NUM][RTW89_NTX_NUM] [2][1][2][0][RTW89_MEXICO][41] = 72, [2][1][2][0][RTW89_CN][41] = 68, [2][1][2][0][RTW89_QATAR][41] = 16, + [2][1][2][0][RTW89_UK][41] = 52, [2][1][2][1][RTW89_FCC][3] = 56, [2][1][2][1][RTW89_ETSI][3] = 40, [2][1][2][1][RTW89_MKK][3] = 52, @@ -47498,6 +47839,7 @@ const s8 rtw89_8852a_txpwr_lmt_5g[RTW89_5G_BW_NUM][RTW89_NTX_NUM] [2][1][2][1][RTW89_MEXICO][3] = 50, [2][1][2][1][RTW89_CN][3] = 40, [2][1][2][1][RTW89_QATAR][3] = 40, + [2][1][2][1][RTW89_UK][3] = 40, [2][1][2][1][RTW89_FCC][11] = 56, [2][1][2][1][RTW89_ETSI][11] = 40, [2][1][2][1][RTW89_MKK][11] = 52, @@ -47509,6 +47851,7 @@ const s8 rtw89_8852a_txpwr_lmt_5g[RTW89_5G_BW_NUM][RTW89_NTX_NUM] [2][1][2][1][RTW89_MEXICO][11] = 56, [2][1][2][1][RTW89_CN][11] = 40, [2][1][2][1][RTW89_QATAR][11] = 40, + [2][1][2][1][RTW89_UK][11] = 40, [2][1][2][1][RTW89_FCC][18] = 56, [2][1][2][1][RTW89_ETSI][18] = 40, [2][1][2][1][RTW89_MKK][18] = 72, @@ -47520,6 +47863,7 @@ const s8 rtw89_8852a_txpwr_lmt_5g[RTW89_5G_BW_NUM][RTW89_NTX_NUM] [2][1][2][1][RTW89_MEXICO][18] = 56, [2][1][2][1][RTW89_CN][18] = 127, [2][1][2][1][RTW89_QATAR][18] = 28, + [2][1][2][1][RTW89_UK][18] = 40, [2][1][2][1][RTW89_FCC][26] = 68, [2][1][2][1][RTW89_ETSI][26] = 40, [2][1][2][1][RTW89_MKK][26] = 72, @@ -47531,6 +47875,7 @@ const s8 rtw89_8852a_txpwr_lmt_5g[RTW89_5G_BW_NUM][RTW89_NTX_NUM] [2][1][2][1][RTW89_MEXICO][26] = 68, [2][1][2][1][RTW89_CN][26] = 127, [2][1][2][1][RTW89_QATAR][26] = 28, + [2][1][2][1][RTW89_UK][26] = 40, [2][1][2][1][RTW89_FCC][34] = 68, [2][1][2][1][RTW89_ETSI][34] = 127, [2][1][2][1][RTW89_MKK][34] = 72, @@ -47542,6 +47887,7 @@ const s8 rtw89_8852a_txpwr_lmt_5g[RTW89_5G_BW_NUM][RTW89_NTX_NUM] [2][1][2][1][RTW89_MEXICO][34] = 68, [2][1][2][1][RTW89_CN][34] = 127, [2][1][2][1][RTW89_QATAR][34] = 127, + [2][1][2][1][RTW89_UK][34] = 66, [2][1][2][1][RTW89_FCC][41] = 72, [2][1][2][1][RTW89_ETSI][41] = 4, [2][1][2][1][RTW89_MKK][41] = 127, @@ -47553,6 +47899,7 @@ const s8 rtw89_8852a_txpwr_lmt_5g[RTW89_5G_BW_NUM][RTW89_NTX_NUM] [2][1][2][1][RTW89_MEXICO][41] = 72, [2][1][2][1][RTW89_CN][41] = 64, [2][1][2][1][RTW89_QATAR][41] = 4, + [2][1][2][1][RTW89_UK][41] = 40, }; const s8 rtw89_8852a_txpwr_lmt_ru_2g[RTW89_RU_NUM][RTW89_NTX_NUM] @@ -47652,6 +47999,7 @@ const s8 rtw89_8852a_txpwr_lmt_ru_2g[RTW89_RU_NUM][RTW89_NTX_NUM] [0][0][RTW89_MEXICO][0] = 70, [0][0][RTW89_CN][0] = 32, [0][0][RTW89_QATAR][0] = 32, + [0][0][RTW89_UK][0] = 32, [0][0][RTW89_FCC][1] = 70, [0][0][RTW89_ETSI][1] = 32, [0][0][RTW89_MKK][1] = 40, @@ -47663,6 +48011,7 @@ const s8 rtw89_8852a_txpwr_lmt_ru_2g[RTW89_RU_NUM][RTW89_NTX_NUM] [0][0][RTW89_MEXICO][1] = 70, [0][0][RTW89_CN][1] = 32, [0][0][RTW89_QATAR][1] = 32, + [0][0][RTW89_UK][1] = 32, [0][0][RTW89_FCC][2] = 74, [0][0][RTW89_ETSI][2] = 32, [0][0][RTW89_MKK][2] = 40, @@ -47674,6 +48023,7 @@ const s8 rtw89_8852a_txpwr_lmt_ru_2g[RTW89_RU_NUM][RTW89_NTX_NUM] [0][0][RTW89_MEXICO][2] = 74, [0][0][RTW89_CN][2] = 32, [0][0][RTW89_QATAR][2] = 32, + [0][0][RTW89_UK][2] = 32, [0][0][RTW89_FCC][3] = 78, [0][0][RTW89_ETSI][3] = 32, [0][0][RTW89_MKK][3] = 40, @@ -47685,6 +48035,7 @@ const s8 rtw89_8852a_txpwr_lmt_ru_2g[RTW89_RU_NUM][RTW89_NTX_NUM] [0][0][RTW89_MEXICO][3] = 78, [0][0][RTW89_CN][3] = 32, [0][0][RTW89_QATAR][3] = 32, + [0][0][RTW89_UK][3] = 32, [0][0][RTW89_FCC][4] = 78, [0][0][RTW89_ETSI][4] = 32, [0][0][RTW89_MKK][4] = 40, @@ -47696,6 +48047,7 @@ const s8 rtw89_8852a_txpwr_lmt_ru_2g[RTW89_RU_NUM][RTW89_NTX_NUM] [0][0][RTW89_MEXICO][4] = 78, [0][0][RTW89_CN][4] = 32, [0][0][RTW89_QATAR][4] = 32, + [0][0][RTW89_UK][4] = 32, [0][0][RTW89_FCC][5] = 78, [0][0][RTW89_ETSI][5] = 32, [0][0][RTW89_MKK][5] = 40, @@ -47707,6 +48059,7 @@ const s8 rtw89_8852a_txpwr_lmt_ru_2g[RTW89_RU_NUM][RTW89_NTX_NUM] [0][0][RTW89_MEXICO][5] = 78, [0][0][RTW89_CN][5] = 32, [0][0][RTW89_QATAR][5] = 32, + [0][0][RTW89_UK][5] = 32, [0][0][RTW89_FCC][6] = 78, [0][0][RTW89_ETSI][6] = 32, [0][0][RTW89_MKK][6] = 40, @@ -47718,6 +48071,7 @@ const s8 rtw89_8852a_txpwr_lmt_ru_2g[RTW89_RU_NUM][RTW89_NTX_NUM] [0][0][RTW89_MEXICO][6] = 78, [0][0][RTW89_CN][6] = 32, [0][0][RTW89_QATAR][6] = 32, + [0][0][RTW89_UK][6] = 32, [0][0][RTW89_FCC][7] = 78, [0][0][RTW89_ETSI][7] = 32, [0][0][RTW89_MKK][7] = 40, @@ -47729,6 +48083,7 @@ const s8 rtw89_8852a_txpwr_lmt_ru_2g[RTW89_RU_NUM][RTW89_NTX_NUM] [0][0][RTW89_MEXICO][7] = 78, [0][0][RTW89_CN][7] = 32, [0][0][RTW89_QATAR][7] = 32, + [0][0][RTW89_UK][7] = 32, [0][0][RTW89_FCC][8] = 74, [0][0][RTW89_ETSI][8] = 32, [0][0][RTW89_MKK][8] = 40, @@ -47740,6 +48095,7 @@ const s8 rtw89_8852a_txpwr_lmt_ru_2g[RTW89_RU_NUM][RTW89_NTX_NUM] [0][0][RTW89_MEXICO][8] = 74, [0][0][RTW89_CN][8] = 32, [0][0][RTW89_QATAR][8] = 32, + [0][0][RTW89_UK][8] = 32, [0][0][RTW89_FCC][9] = 70, [0][0][RTW89_ETSI][9] = 32, [0][0][RTW89_MKK][9] = 40, @@ -47751,6 +48107,7 @@ const s8 rtw89_8852a_txpwr_lmt_ru_2g[RTW89_RU_NUM][RTW89_NTX_NUM] [0][0][RTW89_MEXICO][9] = 70, [0][0][RTW89_CN][9] = 32, [0][0][RTW89_QATAR][9] = 32, + [0][0][RTW89_UK][9] = 32, [0][0][RTW89_FCC][10] = 70, [0][0][RTW89_ETSI][10] = 32, [0][0][RTW89_MKK][10] = 40, @@ -47762,6 +48119,7 @@ const s8 rtw89_8852a_txpwr_lmt_ru_2g[RTW89_RU_NUM][RTW89_NTX_NUM] [0][0][RTW89_MEXICO][10] = 70, [0][0][RTW89_CN][10] = 32, [0][0][RTW89_QATAR][10] = 32, + [0][0][RTW89_UK][10] = 32, [0][0][RTW89_FCC][11] = 58, [0][0][RTW89_ETSI][11] = 32, [0][0][RTW89_MKK][11] = 40, @@ -47773,6 +48131,7 @@ const s8 rtw89_8852a_txpwr_lmt_ru_2g[RTW89_RU_NUM][RTW89_NTX_NUM] [0][0][RTW89_MEXICO][11] = 58, [0][0][RTW89_CN][11] = 32, [0][0][RTW89_QATAR][11] = 32, + [0][0][RTW89_UK][11] = 32, [0][0][RTW89_FCC][12] = 34, [0][0][RTW89_ETSI][12] = 32, [0][0][RTW89_MKK][12] = 40, @@ -47784,6 +48143,7 @@ const s8 rtw89_8852a_txpwr_lmt_ru_2g[RTW89_RU_NUM][RTW89_NTX_NUM] [0][0][RTW89_MEXICO][12] = 34, [0][0][RTW89_CN][12] = 32, [0][0][RTW89_QATAR][12] = 32, + [0][0][RTW89_UK][12] = 32, [0][0][RTW89_FCC][13] = 127, [0][0][RTW89_ETSI][13] = 127, [0][0][RTW89_MKK][13] = 127, @@ -47795,6 +48155,7 @@ const s8 rtw89_8852a_txpwr_lmt_ru_2g[RTW89_RU_NUM][RTW89_NTX_NUM] [0][0][RTW89_MEXICO][13] = 127, [0][0][RTW89_CN][13] = 127, [0][0][RTW89_QATAR][13] = 127, + [0][0][RTW89_UK][13] = 127, [0][1][RTW89_FCC][0] = 64, [0][1][RTW89_ETSI][0] = 20, [0][1][RTW89_MKK][0] = 28, @@ -47806,6 +48167,7 @@ const s8 rtw89_8852a_txpwr_lmt_ru_2g[RTW89_RU_NUM][RTW89_NTX_NUM] [0][1][RTW89_MEXICO][0] = 64, [0][1][RTW89_CN][0] = 20, [0][1][RTW89_QATAR][0] = 20, + [0][1][RTW89_UK][0] = 20, [0][1][RTW89_FCC][1] = 64, [0][1][RTW89_ETSI][1] = 20, [0][1][RTW89_MKK][1] = 28, @@ -47817,6 +48179,7 @@ const s8 rtw89_8852a_txpwr_lmt_ru_2g[RTW89_RU_NUM][RTW89_NTX_NUM] [0][1][RTW89_MEXICO][1] = 64, [0][1][RTW89_CN][1] = 20, [0][1][RTW89_QATAR][1] = 20, + [0][1][RTW89_UK][1] = 20, [0][1][RTW89_FCC][2] = 68, [0][1][RTW89_ETSI][2] = 20, [0][1][RTW89_MKK][2] = 28, @@ -47828,6 +48191,7 @@ const s8 rtw89_8852a_txpwr_lmt_ru_2g[RTW89_RU_NUM][RTW89_NTX_NUM] [0][1][RTW89_MEXICO][2] = 68, [0][1][RTW89_CN][2] = 20, [0][1][RTW89_QATAR][2] = 20, + [0][1][RTW89_UK][2] = 20, [0][1][RTW89_FCC][3] = 72, [0][1][RTW89_ETSI][3] = 20, [0][1][RTW89_MKK][3] = 28, @@ -47839,6 +48203,7 @@ const s8 rtw89_8852a_txpwr_lmt_ru_2g[RTW89_RU_NUM][RTW89_NTX_NUM] [0][1][RTW89_MEXICO][3] = 72, [0][1][RTW89_CN][3] = 20, [0][1][RTW89_QATAR][3] = 20, + [0][1][RTW89_UK][3] = 20, [0][1][RTW89_FCC][4] = 76, [0][1][RTW89_ETSI][4] = 20, [0][1][RTW89_MKK][4] = 28, @@ -47850,6 +48215,7 @@ const s8 rtw89_8852a_txpwr_lmt_ru_2g[RTW89_RU_NUM][RTW89_NTX_NUM] [0][1][RTW89_MEXICO][4] = 76, [0][1][RTW89_CN][4] = 20, [0][1][RTW89_QATAR][4] = 20, + [0][1][RTW89_UK][4] = 20, [0][1][RTW89_FCC][5] = 78, [0][1][RTW89_ETSI][5] = 20, [0][1][RTW89_MKK][5] = 28, @@ -47861,6 +48227,7 @@ const s8 rtw89_8852a_txpwr_lmt_ru_2g[RTW89_RU_NUM][RTW89_NTX_NUM] [0][1][RTW89_MEXICO][5] = 78, [0][1][RTW89_CN][5] = 20, [0][1][RTW89_QATAR][5] = 20, + [0][1][RTW89_UK][5] = 20, [0][1][RTW89_FCC][6] = 76, [0][1][RTW89_ETSI][6] = 20, [0][1][RTW89_MKK][6] = 28, @@ -47872,6 +48239,7 @@ const s8 rtw89_8852a_txpwr_lmt_ru_2g[RTW89_RU_NUM][RTW89_NTX_NUM] [0][1][RTW89_MEXICO][6] = 76, [0][1][RTW89_CN][6] = 20, [0][1][RTW89_QATAR][6] = 20, + [0][1][RTW89_UK][6] = 20, [0][1][RTW89_FCC][7] = 72, [0][1][RTW89_ETSI][7] = 20, [0][1][RTW89_MKK][7] = 28, @@ -47883,6 +48251,7 @@ const s8 rtw89_8852a_txpwr_lmt_ru_2g[RTW89_RU_NUM][RTW89_NTX_NUM] [0][1][RTW89_MEXICO][7] = 72, [0][1][RTW89_CN][7] = 20, [0][1][RTW89_QATAR][7] = 20, + [0][1][RTW89_UK][7] = 20, [0][1][RTW89_FCC][8] = 68, [0][1][RTW89_ETSI][8] = 20, [0][1][RTW89_MKK][8] = 28, @@ -47894,6 +48263,7 @@ const s8 rtw89_8852a_txpwr_lmt_ru_2g[RTW89_RU_NUM][RTW89_NTX_NUM] [0][1][RTW89_MEXICO][8] = 68, [0][1][RTW89_CN][8] = 20, [0][1][RTW89_QATAR][8] = 20, + [0][1][RTW89_UK][8] = 20, [0][1][RTW89_FCC][9] = 64, [0][1][RTW89_ETSI][9] = 20, [0][1][RTW89_MKK][9] = 28, @@ -47905,6 +48275,7 @@ const s8 rtw89_8852a_txpwr_lmt_ru_2g[RTW89_RU_NUM][RTW89_NTX_NUM] [0][1][RTW89_MEXICO][9] = 64, [0][1][RTW89_CN][9] = 20, [0][1][RTW89_QATAR][9] = 20, + [0][1][RTW89_UK][9] = 20, [0][1][RTW89_FCC][10] = 64, [0][1][RTW89_ETSI][10] = 20, [0][1][RTW89_MKK][10] = 28, @@ -47916,6 +48287,7 @@ const s8 rtw89_8852a_txpwr_lmt_ru_2g[RTW89_RU_NUM][RTW89_NTX_NUM] [0][1][RTW89_MEXICO][10] = 64, [0][1][RTW89_CN][10] = 20, [0][1][RTW89_QATAR][10] = 20, + [0][1][RTW89_UK][10] = 20, [0][1][RTW89_FCC][11] = 54, [0][1][RTW89_ETSI][11] = 20, [0][1][RTW89_MKK][11] = 28, @@ -47927,6 +48299,7 @@ const s8 rtw89_8852a_txpwr_lmt_ru_2g[RTW89_RU_NUM][RTW89_NTX_NUM] [0][1][RTW89_MEXICO][11] = 54, [0][1][RTW89_CN][11] = 20, [0][1][RTW89_QATAR][11] = 20, + [0][1][RTW89_UK][11] = 20, [0][1][RTW89_FCC][12] = 32, [0][1][RTW89_ETSI][12] = 20, [0][1][RTW89_MKK][12] = 28, @@ -47938,6 +48311,7 @@ const s8 rtw89_8852a_txpwr_lmt_ru_2g[RTW89_RU_NUM][RTW89_NTX_NUM] [0][1][RTW89_MEXICO][12] = 32, [0][1][RTW89_CN][12] = 20, [0][1][RTW89_QATAR][12] = 20, + [0][1][RTW89_UK][12] = 20, [0][1][RTW89_FCC][13] = 127, [0][1][RTW89_ETSI][13] = 127, [0][1][RTW89_MKK][13] = 127, @@ -47949,6 +48323,7 @@ const s8 rtw89_8852a_txpwr_lmt_ru_2g[RTW89_RU_NUM][RTW89_NTX_NUM] [0][1][RTW89_MEXICO][13] = 127, [0][1][RTW89_CN][13] = 127, [0][1][RTW89_QATAR][13] = 127, + [0][1][RTW89_UK][13] = 127, [1][0][RTW89_FCC][0] = 72, [1][0][RTW89_ETSI][0] = 42, [1][0][RTW89_MKK][0] = 50, @@ -47960,6 +48335,7 @@ const s8 rtw89_8852a_txpwr_lmt_ru_2g[RTW89_RU_NUM][RTW89_NTX_NUM] [1][0][RTW89_MEXICO][0] = 72, [1][0][RTW89_CN][0] = 42, [1][0][RTW89_QATAR][0] = 42, + [1][0][RTW89_UK][0] = 42, [1][0][RTW89_FCC][1] = 72, [1][0][RTW89_ETSI][1] = 42, [1][0][RTW89_MKK][1] = 50, @@ -47971,6 +48347,7 @@ const s8 rtw89_8852a_txpwr_lmt_ru_2g[RTW89_RU_NUM][RTW89_NTX_NUM] [1][0][RTW89_MEXICO][1] = 72, [1][0][RTW89_CN][1] = 42, [1][0][RTW89_QATAR][1] = 42, + [1][0][RTW89_UK][1] = 42, [1][0][RTW89_FCC][2] = 76, [1][0][RTW89_ETSI][2] = 42, [1][0][RTW89_MKK][2] = 50, @@ -47982,6 +48359,7 @@ const s8 rtw89_8852a_txpwr_lmt_ru_2g[RTW89_RU_NUM][RTW89_NTX_NUM] [1][0][RTW89_MEXICO][2] = 76, [1][0][RTW89_CN][2] = 42, [1][0][RTW89_QATAR][2] = 42, + [1][0][RTW89_UK][2] = 42, [1][0][RTW89_FCC][3] = 78, [1][0][RTW89_ETSI][3] = 42, [1][0][RTW89_MKK][3] = 50, @@ -47993,6 +48371,7 @@ const s8 rtw89_8852a_txpwr_lmt_ru_2g[RTW89_RU_NUM][RTW89_NTX_NUM] [1][0][RTW89_MEXICO][3] = 78, [1][0][RTW89_CN][3] = 42, [1][0][RTW89_QATAR][3] = 42, + [1][0][RTW89_UK][3] = 42, [1][0][RTW89_FCC][4] = 78, [1][0][RTW89_ETSI][4] = 42, [1][0][RTW89_MKK][4] = 50, @@ -48004,6 +48383,7 @@ const s8 rtw89_8852a_txpwr_lmt_ru_2g[RTW89_RU_NUM][RTW89_NTX_NUM] [1][0][RTW89_MEXICO][4] = 78, [1][0][RTW89_CN][4] = 42, [1][0][RTW89_QATAR][4] = 42, + [1][0][RTW89_UK][4] = 42, [1][0][RTW89_FCC][5] = 78, [1][0][RTW89_ETSI][5] = 42, [1][0][RTW89_MKK][5] = 50, @@ -48015,6 +48395,7 @@ const s8 rtw89_8852a_txpwr_lmt_ru_2g[RTW89_RU_NUM][RTW89_NTX_NUM] [1][0][RTW89_MEXICO][5] = 78, [1][0][RTW89_CN][5] = 42, [1][0][RTW89_QATAR][5] = 42, + [1][0][RTW89_UK][5] = 42, [1][0][RTW89_FCC][6] = 78, [1][0][RTW89_ETSI][6] = 42, [1][0][RTW89_MKK][6] = 50, @@ -48026,6 +48407,7 @@ const s8 rtw89_8852a_txpwr_lmt_ru_2g[RTW89_RU_NUM][RTW89_NTX_NUM] [1][0][RTW89_MEXICO][6] = 78, [1][0][RTW89_CN][6] = 42, [1][0][RTW89_QATAR][6] = 42, + [1][0][RTW89_UK][6] = 42, [1][0][RTW89_FCC][7] = 78, [1][0][RTW89_ETSI][7] = 42, [1][0][RTW89_MKK][7] = 50, @@ -48037,6 +48419,7 @@ const s8 rtw89_8852a_txpwr_lmt_ru_2g[RTW89_RU_NUM][RTW89_NTX_NUM] [1][0][RTW89_MEXICO][7] = 78, [1][0][RTW89_CN][7] = 42, [1][0][RTW89_QATAR][7] = 42, + [1][0][RTW89_UK][7] = 42, [1][0][RTW89_FCC][8] = 78, [1][0][RTW89_ETSI][8] = 42, [1][0][RTW89_MKK][8] = 50, @@ -48048,6 +48431,7 @@ const s8 rtw89_8852a_txpwr_lmt_ru_2g[RTW89_RU_NUM][RTW89_NTX_NUM] [1][0][RTW89_MEXICO][8] = 78, [1][0][RTW89_CN][8] = 42, [1][0][RTW89_QATAR][8] = 42, + [1][0][RTW89_UK][8] = 42, [1][0][RTW89_FCC][9] = 74, [1][0][RTW89_ETSI][9] = 42, [1][0][RTW89_MKK][9] = 50, @@ -48059,6 +48443,7 @@ const s8 rtw89_8852a_txpwr_lmt_ru_2g[RTW89_RU_NUM][RTW89_NTX_NUM] [1][0][RTW89_MEXICO][9] = 74, [1][0][RTW89_CN][9] = 42, [1][0][RTW89_QATAR][9] = 42, + [1][0][RTW89_UK][9] = 42, [1][0][RTW89_FCC][10] = 74, [1][0][RTW89_ETSI][10] = 42, [1][0][RTW89_MKK][10] = 50, @@ -48070,6 +48455,7 @@ const s8 rtw89_8852a_txpwr_lmt_ru_2g[RTW89_RU_NUM][RTW89_NTX_NUM] [1][0][RTW89_MEXICO][10] = 74, [1][0][RTW89_CN][10] = 42, [1][0][RTW89_QATAR][10] = 42, + [1][0][RTW89_UK][10] = 42, [1][0][RTW89_FCC][11] = 64, [1][0][RTW89_ETSI][11] = 42, [1][0][RTW89_MKK][11] = 50, @@ -48081,6 +48467,7 @@ const s8 rtw89_8852a_txpwr_lmt_ru_2g[RTW89_RU_NUM][RTW89_NTX_NUM] [1][0][RTW89_MEXICO][11] = 64, [1][0][RTW89_CN][11] = 42, [1][0][RTW89_QATAR][11] = 42, + [1][0][RTW89_UK][11] = 42, [1][0][RTW89_FCC][12] = 36, [1][0][RTW89_ETSI][12] = 42, [1][0][RTW89_MKK][12] = 50, @@ -48092,6 +48479,7 @@ const s8 rtw89_8852a_txpwr_lmt_ru_2g[RTW89_RU_NUM][RTW89_NTX_NUM] [1][0][RTW89_MEXICO][12] = 36, [1][0][RTW89_CN][12] = 42, [1][0][RTW89_QATAR][12] = 42, + [1][0][RTW89_UK][12] = 42, [1][0][RTW89_FCC][13] = 127, [1][0][RTW89_ETSI][13] = 127, [1][0][RTW89_MKK][13] = 127, @@ -48103,6 +48491,7 @@ const s8 rtw89_8852a_txpwr_lmt_ru_2g[RTW89_RU_NUM][RTW89_NTX_NUM] [1][0][RTW89_MEXICO][13] = 127, [1][0][RTW89_CN][13] = 127, [1][0][RTW89_QATAR][13] = 127, + [1][0][RTW89_UK][13] = 127, [1][1][RTW89_FCC][0] = 66, [1][1][RTW89_ETSI][0] = 30, [1][1][RTW89_MKK][0] = 38, @@ -48114,6 +48503,7 @@ const s8 rtw89_8852a_txpwr_lmt_ru_2g[RTW89_RU_NUM][RTW89_NTX_NUM] [1][1][RTW89_MEXICO][0] = 66, [1][1][RTW89_CN][0] = 30, [1][1][RTW89_QATAR][0] = 30, + [1][1][RTW89_UK][0] = 30, [1][1][RTW89_FCC][1] = 66, [1][1][RTW89_ETSI][1] = 30, [1][1][RTW89_MKK][1] = 38, @@ -48125,6 +48515,7 @@ const s8 rtw89_8852a_txpwr_lmt_ru_2g[RTW89_RU_NUM][RTW89_NTX_NUM] [1][1][RTW89_MEXICO][1] = 66, [1][1][RTW89_CN][1] = 30, [1][1][RTW89_QATAR][1] = 30, + [1][1][RTW89_UK][1] = 30, [1][1][RTW89_FCC][2] = 70, [1][1][RTW89_ETSI][2] = 30, [1][1][RTW89_MKK][2] = 38, @@ -48136,6 +48527,7 @@ const s8 rtw89_8852a_txpwr_lmt_ru_2g[RTW89_RU_NUM][RTW89_NTX_NUM] [1][1][RTW89_MEXICO][2] = 70, [1][1][RTW89_CN][2] = 30, [1][1][RTW89_QATAR][2] = 30, + [1][1][RTW89_UK][2] = 30, [1][1][RTW89_FCC][3] = 74, [1][1][RTW89_ETSI][3] = 30, [1][1][RTW89_MKK][3] = 38, @@ -48147,6 +48539,7 @@ const s8 rtw89_8852a_txpwr_lmt_ru_2g[RTW89_RU_NUM][RTW89_NTX_NUM] [1][1][RTW89_MEXICO][3] = 74, [1][1][RTW89_CN][3] = 30, [1][1][RTW89_QATAR][3] = 30, + [1][1][RTW89_UK][3] = 30, [1][1][RTW89_FCC][4] = 78, [1][1][RTW89_ETSI][4] = 30, [1][1][RTW89_MKK][4] = 38, @@ -48158,6 +48551,7 @@ const s8 rtw89_8852a_txpwr_lmt_ru_2g[RTW89_RU_NUM][RTW89_NTX_NUM] [1][1][RTW89_MEXICO][4] = 78, [1][1][RTW89_CN][4] = 30, [1][1][RTW89_QATAR][4] = 30, + [1][1][RTW89_UK][4] = 30, [1][1][RTW89_FCC][5] = 78, [1][1][RTW89_ETSI][5] = 30, [1][1][RTW89_MKK][5] = 38, @@ -48169,6 +48563,7 @@ const s8 rtw89_8852a_txpwr_lmt_ru_2g[RTW89_RU_NUM][RTW89_NTX_NUM] [1][1][RTW89_MEXICO][5] = 78, [1][1][RTW89_CN][5] = 30, [1][1][RTW89_QATAR][5] = 30, + [1][1][RTW89_UK][5] = 30, [1][1][RTW89_FCC][6] = 78, [1][1][RTW89_ETSI][6] = 30, [1][1][RTW89_MKK][6] = 38, @@ -48180,6 +48575,7 @@ const s8 rtw89_8852a_txpwr_lmt_ru_2g[RTW89_RU_NUM][RTW89_NTX_NUM] [1][1][RTW89_MEXICO][6] = 78, [1][1][RTW89_CN][6] = 30, [1][1][RTW89_QATAR][6] = 30, + [1][1][RTW89_UK][6] = 30, [1][1][RTW89_FCC][7] = 74, [1][1][RTW89_ETSI][7] = 30, [1][1][RTW89_MKK][7] = 38, @@ -48191,6 +48587,7 @@ const s8 rtw89_8852a_txpwr_lmt_ru_2g[RTW89_RU_NUM][RTW89_NTX_NUM] [1][1][RTW89_MEXICO][7] = 74, [1][1][RTW89_CN][7] = 30, [1][1][RTW89_QATAR][7] = 30, + [1][1][RTW89_UK][7] = 30, [1][1][RTW89_FCC][8] = 70, [1][1][RTW89_ETSI][8] = 30, [1][1][RTW89_MKK][8] = 38, @@ -48202,6 +48599,7 @@ const s8 rtw89_8852a_txpwr_lmt_ru_2g[RTW89_RU_NUM][RTW89_NTX_NUM] [1][1][RTW89_MEXICO][8] = 70, [1][1][RTW89_CN][8] = 30, [1][1][RTW89_QATAR][8] = 30, + [1][1][RTW89_UK][8] = 30, [1][1][RTW89_FCC][9] = 66, [1][1][RTW89_ETSI][9] = 30, [1][1][RTW89_MKK][9] = 38, @@ -48213,6 +48611,7 @@ const s8 rtw89_8852a_txpwr_lmt_ru_2g[RTW89_RU_NUM][RTW89_NTX_NUM] [1][1][RTW89_MEXICO][9] = 66, [1][1][RTW89_CN][9] = 30, [1][1][RTW89_QATAR][9] = 30, + [1][1][RTW89_UK][9] = 30, [1][1][RTW89_FCC][10] = 66, [1][1][RTW89_ETSI][10] = 30, [1][1][RTW89_MKK][10] = 38, @@ -48224,6 +48623,7 @@ const s8 rtw89_8852a_txpwr_lmt_ru_2g[RTW89_RU_NUM][RTW89_NTX_NUM] [1][1][RTW89_MEXICO][10] = 66, [1][1][RTW89_CN][10] = 30, [1][1][RTW89_QATAR][10] = 30, + [1][1][RTW89_UK][10] = 30, [1][1][RTW89_FCC][11] = 60, [1][1][RTW89_ETSI][11] = 30, [1][1][RTW89_MKK][11] = 38, @@ -48235,6 +48635,7 @@ const s8 rtw89_8852a_txpwr_lmt_ru_2g[RTW89_RU_NUM][RTW89_NTX_NUM] [1][1][RTW89_MEXICO][11] = 60, [1][1][RTW89_CN][11] = 30, [1][1][RTW89_QATAR][11] = 30, + [1][1][RTW89_UK][11] = 30, [1][1][RTW89_FCC][12] = 32, [1][1][RTW89_ETSI][12] = 30, [1][1][RTW89_MKK][12] = 38, @@ -48246,6 +48647,7 @@ const s8 rtw89_8852a_txpwr_lmt_ru_2g[RTW89_RU_NUM][RTW89_NTX_NUM] [1][1][RTW89_MEXICO][12] = 32, [1][1][RTW89_CN][12] = 30, [1][1][RTW89_QATAR][12] = 30, + [1][1][RTW89_UK][12] = 30, [1][1][RTW89_FCC][13] = 127, [1][1][RTW89_ETSI][13] = 127, [1][1][RTW89_MKK][13] = 127, @@ -48257,6 +48659,7 @@ const s8 rtw89_8852a_txpwr_lmt_ru_2g[RTW89_RU_NUM][RTW89_NTX_NUM] [1][1][RTW89_MEXICO][13] = 127, [1][1][RTW89_CN][13] = 127, [1][1][RTW89_QATAR][13] = 127, + [1][1][RTW89_UK][13] = 127, [2][0][RTW89_FCC][0] = 76, [2][0][RTW89_ETSI][0] = 52, [2][0][RTW89_MKK][0] = 64, @@ -48268,6 +48671,7 @@ const s8 rtw89_8852a_txpwr_lmt_ru_2g[RTW89_RU_NUM][RTW89_NTX_NUM] [2][0][RTW89_MEXICO][0] = 76, [2][0][RTW89_CN][0] = 52, [2][0][RTW89_QATAR][0] = 52, + [2][0][RTW89_UK][0] = 52, [2][0][RTW89_FCC][1] = 76, [2][0][RTW89_ETSI][1] = 52, [2][0][RTW89_MKK][1] = 64, @@ -48279,6 +48683,7 @@ const s8 rtw89_8852a_txpwr_lmt_ru_2g[RTW89_RU_NUM][RTW89_NTX_NUM] [2][0][RTW89_MEXICO][1] = 76, [2][0][RTW89_CN][1] = 52, [2][0][RTW89_QATAR][1] = 52, + [2][0][RTW89_UK][1] = 52, [2][0][RTW89_FCC][2] = 78, [2][0][RTW89_ETSI][2] = 52, [2][0][RTW89_MKK][2] = 64, @@ -48290,6 +48695,7 @@ const s8 rtw89_8852a_txpwr_lmt_ru_2g[RTW89_RU_NUM][RTW89_NTX_NUM] [2][0][RTW89_MEXICO][2] = 78, [2][0][RTW89_CN][2] = 52, [2][0][RTW89_QATAR][2] = 52, + [2][0][RTW89_UK][2] = 52, [2][0][RTW89_FCC][3] = 78, [2][0][RTW89_ETSI][3] = 52, [2][0][RTW89_MKK][3] = 64, @@ -48301,6 +48707,7 @@ const s8 rtw89_8852a_txpwr_lmt_ru_2g[RTW89_RU_NUM][RTW89_NTX_NUM] [2][0][RTW89_MEXICO][3] = 78, [2][0][RTW89_CN][3] = 52, [2][0][RTW89_QATAR][3] = 52, + [2][0][RTW89_UK][3] = 52, [2][0][RTW89_FCC][4] = 78, [2][0][RTW89_ETSI][4] = 52, [2][0][RTW89_MKK][4] = 64, @@ -48312,6 +48719,7 @@ const s8 rtw89_8852a_txpwr_lmt_ru_2g[RTW89_RU_NUM][RTW89_NTX_NUM] [2][0][RTW89_MEXICO][4] = 78, [2][0][RTW89_CN][4] = 52, [2][0][RTW89_QATAR][4] = 52, + [2][0][RTW89_UK][4] = 52, [2][0][RTW89_FCC][5] = 78, [2][0][RTW89_ETSI][5] = 52, [2][0][RTW89_MKK][5] = 64, @@ -48323,6 +48731,7 @@ const s8 rtw89_8852a_txpwr_lmt_ru_2g[RTW89_RU_NUM][RTW89_NTX_NUM] [2][0][RTW89_MEXICO][5] = 78, [2][0][RTW89_CN][5] = 52, [2][0][RTW89_QATAR][5] = 52, + [2][0][RTW89_UK][5] = 52, [2][0][RTW89_FCC][6] = 78, [2][0][RTW89_ETSI][6] = 52, [2][0][RTW89_MKK][6] = 64, @@ -48334,6 +48743,7 @@ const s8 rtw89_8852a_txpwr_lmt_ru_2g[RTW89_RU_NUM][RTW89_NTX_NUM] [2][0][RTW89_MEXICO][6] = 78, [2][0][RTW89_CN][6] = 52, [2][0][RTW89_QATAR][6] = 52, + [2][0][RTW89_UK][6] = 52, [2][0][RTW89_FCC][7] = 78, [2][0][RTW89_ETSI][7] = 52, [2][0][RTW89_MKK][7] = 64, @@ -48345,6 +48755,7 @@ const s8 rtw89_8852a_txpwr_lmt_ru_2g[RTW89_RU_NUM][RTW89_NTX_NUM] [2][0][RTW89_MEXICO][7] = 78, [2][0][RTW89_CN][7] = 52, [2][0][RTW89_QATAR][7] = 52, + [2][0][RTW89_UK][7] = 52, [2][0][RTW89_FCC][8] = 78, [2][0][RTW89_ETSI][8] = 52, [2][0][RTW89_MKK][8] = 64, @@ -48356,6 +48767,7 @@ const s8 rtw89_8852a_txpwr_lmt_ru_2g[RTW89_RU_NUM][RTW89_NTX_NUM] [2][0][RTW89_MEXICO][8] = 78, [2][0][RTW89_CN][8] = 52, [2][0][RTW89_QATAR][8] = 52, + [2][0][RTW89_UK][8] = 52, [2][0][RTW89_FCC][9] = 76, [2][0][RTW89_ETSI][9] = 52, [2][0][RTW89_MKK][9] = 64, @@ -48367,6 +48779,7 @@ const s8 rtw89_8852a_txpwr_lmt_ru_2g[RTW89_RU_NUM][RTW89_NTX_NUM] [2][0][RTW89_MEXICO][9] = 76, [2][0][RTW89_CN][9] = 52, [2][0][RTW89_QATAR][9] = 52, + [2][0][RTW89_UK][9] = 52, [2][0][RTW89_FCC][10] = 76, [2][0][RTW89_ETSI][10] = 52, [2][0][RTW89_MKK][10] = 64, @@ -48378,6 +48791,7 @@ const s8 rtw89_8852a_txpwr_lmt_ru_2g[RTW89_RU_NUM][RTW89_NTX_NUM] [2][0][RTW89_MEXICO][10] = 76, [2][0][RTW89_CN][10] = 52, [2][0][RTW89_QATAR][10] = 52, + [2][0][RTW89_UK][10] = 52, [2][0][RTW89_FCC][11] = 68, [2][0][RTW89_ETSI][11] = 52, [2][0][RTW89_MKK][11] = 64, @@ -48389,6 +48803,7 @@ const s8 rtw89_8852a_txpwr_lmt_ru_2g[RTW89_RU_NUM][RTW89_NTX_NUM] [2][0][RTW89_MEXICO][11] = 68, [2][0][RTW89_CN][11] = 52, [2][0][RTW89_QATAR][11] = 52, + [2][0][RTW89_UK][11] = 52, [2][0][RTW89_FCC][12] = 40, [2][0][RTW89_ETSI][12] = 52, [2][0][RTW89_MKK][12] = 64, @@ -48400,6 +48815,7 @@ const s8 rtw89_8852a_txpwr_lmt_ru_2g[RTW89_RU_NUM][RTW89_NTX_NUM] [2][0][RTW89_MEXICO][12] = 40, [2][0][RTW89_CN][12] = 52, [2][0][RTW89_QATAR][12] = 52, + [2][0][RTW89_UK][12] = 52, [2][0][RTW89_FCC][13] = 127, [2][0][RTW89_ETSI][13] = 127, [2][0][RTW89_MKK][13] = 127, @@ -48411,6 +48827,7 @@ const s8 rtw89_8852a_txpwr_lmt_ru_2g[RTW89_RU_NUM][RTW89_NTX_NUM] [2][0][RTW89_MEXICO][13] = 127, [2][0][RTW89_CN][13] = 127, [2][0][RTW89_QATAR][13] = 127, + [2][0][RTW89_UK][13] = 127, [2][1][RTW89_FCC][0] = 68, [2][1][RTW89_ETSI][0] = 40, [2][1][RTW89_MKK][0] = 52, @@ -48422,6 +48839,7 @@ const s8 rtw89_8852a_txpwr_lmt_ru_2g[RTW89_RU_NUM][RTW89_NTX_NUM] [2][1][RTW89_MEXICO][0] = 68, [2][1][RTW89_CN][0] = 40, [2][1][RTW89_QATAR][0] = 40, + [2][1][RTW89_UK][0] = 40, [2][1][RTW89_FCC][1] = 68, [2][1][RTW89_ETSI][1] = 40, [2][1][RTW89_MKK][1] = 52, @@ -48433,6 +48851,7 @@ const s8 rtw89_8852a_txpwr_lmt_ru_2g[RTW89_RU_NUM][RTW89_NTX_NUM] [2][1][RTW89_MEXICO][1] = 68, [2][1][RTW89_CN][1] = 40, [2][1][RTW89_QATAR][1] = 40, + [2][1][RTW89_UK][1] = 40, [2][1][RTW89_FCC][2] = 72, [2][1][RTW89_ETSI][2] = 40, [2][1][RTW89_MKK][2] = 52, @@ -48444,6 +48863,7 @@ const s8 rtw89_8852a_txpwr_lmt_ru_2g[RTW89_RU_NUM][RTW89_NTX_NUM] [2][1][RTW89_MEXICO][2] = 72, [2][1][RTW89_CN][2] = 40, [2][1][RTW89_QATAR][2] = 40, + [2][1][RTW89_UK][2] = 40, [2][1][RTW89_FCC][3] = 76, [2][1][RTW89_ETSI][3] = 40, [2][1][RTW89_MKK][3] = 52, @@ -48455,6 +48875,7 @@ const s8 rtw89_8852a_txpwr_lmt_ru_2g[RTW89_RU_NUM][RTW89_NTX_NUM] [2][1][RTW89_MEXICO][3] = 76, [2][1][RTW89_CN][3] = 40, [2][1][RTW89_QATAR][3] = 40, + [2][1][RTW89_UK][3] = 40, [2][1][RTW89_FCC][4] = 78, [2][1][RTW89_ETSI][4] = 40, [2][1][RTW89_MKK][4] = 52, @@ -48466,6 +48887,7 @@ const s8 rtw89_8852a_txpwr_lmt_ru_2g[RTW89_RU_NUM][RTW89_NTX_NUM] [2][1][RTW89_MEXICO][4] = 78, [2][1][RTW89_CN][4] = 40, [2][1][RTW89_QATAR][4] = 40, + [2][1][RTW89_UK][4] = 40, [2][1][RTW89_FCC][5] = 78, [2][1][RTW89_ETSI][5] = 40, [2][1][RTW89_MKK][5] = 52, @@ -48477,6 +48899,7 @@ const s8 rtw89_8852a_txpwr_lmt_ru_2g[RTW89_RU_NUM][RTW89_NTX_NUM] [2][1][RTW89_MEXICO][5] = 78, [2][1][RTW89_CN][5] = 40, [2][1][RTW89_QATAR][5] = 40, + [2][1][RTW89_UK][5] = 40, [2][1][RTW89_FCC][6] = 78, [2][1][RTW89_ETSI][6] = 40, [2][1][RTW89_MKK][6] = 52, @@ -48488,6 +48911,7 @@ const s8 rtw89_8852a_txpwr_lmt_ru_2g[RTW89_RU_NUM][RTW89_NTX_NUM] [2][1][RTW89_MEXICO][6] = 78, [2][1][RTW89_CN][6] = 40, [2][1][RTW89_QATAR][6] = 40, + [2][1][RTW89_UK][6] = 40, [2][1][RTW89_FCC][7] = 78, [2][1][RTW89_ETSI][7] = 40, [2][1][RTW89_MKK][7] = 52, @@ -48499,6 +48923,7 @@ const s8 rtw89_8852a_txpwr_lmt_ru_2g[RTW89_RU_NUM][RTW89_NTX_NUM] [2][1][RTW89_MEXICO][7] = 78, [2][1][RTW89_CN][7] = 40, [2][1][RTW89_QATAR][7] = 40, + [2][1][RTW89_UK][7] = 40, [2][1][RTW89_FCC][8] = 74, [2][1][RTW89_ETSI][8] = 40, [2][1][RTW89_MKK][8] = 52, @@ -48510,6 +48935,7 @@ const s8 rtw89_8852a_txpwr_lmt_ru_2g[RTW89_RU_NUM][RTW89_NTX_NUM] [2][1][RTW89_MEXICO][8] = 74, [2][1][RTW89_CN][8] = 40, [2][1][RTW89_QATAR][8] = 40, + [2][1][RTW89_UK][8] = 40, [2][1][RTW89_FCC][9] = 70, [2][1][RTW89_ETSI][9] = 40, [2][1][RTW89_MKK][9] = 52, @@ -48521,6 +48947,7 @@ const s8 rtw89_8852a_txpwr_lmt_ru_2g[RTW89_RU_NUM][RTW89_NTX_NUM] [2][1][RTW89_MEXICO][9] = 70, [2][1][RTW89_CN][9] = 40, [2][1][RTW89_QATAR][9] = 40, + [2][1][RTW89_UK][9] = 40, [2][1][RTW89_FCC][10] = 70, [2][1][RTW89_ETSI][10] = 40, [2][1][RTW89_MKK][10] = 52, @@ -48532,6 +48959,7 @@ const s8 rtw89_8852a_txpwr_lmt_ru_2g[RTW89_RU_NUM][RTW89_NTX_NUM] [2][1][RTW89_MEXICO][10] = 70, [2][1][RTW89_CN][10] = 40, [2][1][RTW89_QATAR][10] = 40, + [2][1][RTW89_UK][10] = 40, [2][1][RTW89_FCC][11] = 48, [2][1][RTW89_ETSI][11] = 40, [2][1][RTW89_MKK][11] = 52, @@ -48543,6 +48971,7 @@ const s8 rtw89_8852a_txpwr_lmt_ru_2g[RTW89_RU_NUM][RTW89_NTX_NUM] [2][1][RTW89_MEXICO][11] = 48, [2][1][RTW89_CN][11] = 40, [2][1][RTW89_QATAR][11] = 40, + [2][1][RTW89_UK][11] = 40, [2][1][RTW89_FCC][12] = 26, [2][1][RTW89_ETSI][12] = 40, [2][1][RTW89_MKK][12] = 52, @@ -48554,6 +48983,7 @@ const s8 rtw89_8852a_txpwr_lmt_ru_2g[RTW89_RU_NUM][RTW89_NTX_NUM] [2][1][RTW89_MEXICO][12] = 26, [2][1][RTW89_CN][12] = 40, [2][1][RTW89_QATAR][12] = 40, + [2][1][RTW89_UK][12] = 40, [2][1][RTW89_FCC][13] = 127, [2][1][RTW89_ETSI][13] = 127, [2][1][RTW89_MKK][13] = 127, @@ -48565,6 +48995,7 @@ const s8 rtw89_8852a_txpwr_lmt_ru_2g[RTW89_RU_NUM][RTW89_NTX_NUM] [2][1][RTW89_MEXICO][13] = 127, [2][1][RTW89_CN][13] = 127, [2][1][RTW89_QATAR][13] = 127, + [2][1][RTW89_UK][13] = 127, }; const s8 rtw89_8852a_txpwr_lmt_ru_5g[RTW89_RU_NUM][RTW89_NTX_NUM] @@ -48730,6 +49161,7 @@ const s8 rtw89_8852a_txpwr_lmt_ru_5g[RTW89_RU_NUM][RTW89_NTX_NUM] [0][0][RTW89_MEXICO][0] = 48, [0][0][RTW89_CN][0] = 24, [0][0][RTW89_QATAR][0] = 24, + [0][0][RTW89_UK][0] = 24, [0][0][RTW89_FCC][2] = 48, [0][0][RTW89_ETSI][2] = 24, [0][0][RTW89_MKK][2] = 26, @@ -48741,6 +49173,7 @@ const s8 rtw89_8852a_txpwr_lmt_ru_5g[RTW89_RU_NUM][RTW89_NTX_NUM] [0][0][RTW89_MEXICO][2] = 48, [0][0][RTW89_CN][2] = 24, [0][0][RTW89_QATAR][2] = 24, + [0][0][RTW89_UK][2] = 24, [0][0][RTW89_FCC][4] = 48, [0][0][RTW89_ETSI][4] = 24, [0][0][RTW89_MKK][4] = 26, @@ -48752,6 +49185,7 @@ const s8 rtw89_8852a_txpwr_lmt_ru_5g[RTW89_RU_NUM][RTW89_NTX_NUM] [0][0][RTW89_MEXICO][4] = 48, [0][0][RTW89_CN][4] = 24, [0][0][RTW89_QATAR][4] = 24, + [0][0][RTW89_UK][4] = 24, [0][0][RTW89_FCC][6] = 48, [0][0][RTW89_ETSI][6] = 24, [0][0][RTW89_MKK][6] = 26, @@ -48763,6 +49197,7 @@ const s8 rtw89_8852a_txpwr_lmt_ru_5g[RTW89_RU_NUM][RTW89_NTX_NUM] [0][0][RTW89_MEXICO][6] = 48, [0][0][RTW89_CN][6] = 24, [0][0][RTW89_QATAR][6] = 24, + [0][0][RTW89_UK][6] = 24, [0][0][RTW89_FCC][8] = 48, [0][0][RTW89_ETSI][8] = 24, [0][0][RTW89_MKK][8] = 26, @@ -48774,6 +49209,7 @@ const s8 rtw89_8852a_txpwr_lmt_ru_5g[RTW89_RU_NUM][RTW89_NTX_NUM] [0][0][RTW89_MEXICO][8] = 48, [0][0][RTW89_CN][8] = 24, [0][0][RTW89_QATAR][8] = 24, + [0][0][RTW89_UK][8] = 24, [0][0][RTW89_FCC][10] = 48, [0][0][RTW89_ETSI][10] = 24, [0][0][RTW89_MKK][10] = 26, @@ -48785,6 +49221,7 @@ const s8 rtw89_8852a_txpwr_lmt_ru_5g[RTW89_RU_NUM][RTW89_NTX_NUM] [0][0][RTW89_MEXICO][10] = 48, [0][0][RTW89_CN][10] = 24, [0][0][RTW89_QATAR][10] = 24, + [0][0][RTW89_UK][10] = 24, [0][0][RTW89_FCC][12] = 48, [0][0][RTW89_ETSI][12] = 24, [0][0][RTW89_MKK][12] = 26, @@ -48796,6 +49233,7 @@ const s8 rtw89_8852a_txpwr_lmt_ru_5g[RTW89_RU_NUM][RTW89_NTX_NUM] [0][0][RTW89_MEXICO][12] = 48, [0][0][RTW89_CN][12] = 24, [0][0][RTW89_QATAR][12] = 24, + [0][0][RTW89_UK][12] = 24, [0][0][RTW89_FCC][14] = 48, [0][0][RTW89_ETSI][14] = 24, [0][0][RTW89_MKK][14] = 26, @@ -48807,6 +49245,7 @@ const s8 rtw89_8852a_txpwr_lmt_ru_5g[RTW89_RU_NUM][RTW89_NTX_NUM] [0][0][RTW89_MEXICO][14] = 48, [0][0][RTW89_CN][14] = 24, [0][0][RTW89_QATAR][14] = 24, + [0][0][RTW89_UK][14] = 24, [0][0][RTW89_FCC][15] = 48, [0][0][RTW89_ETSI][15] = 24, [0][0][RTW89_MKK][15] = 44, @@ -48818,6 +49257,7 @@ const s8 rtw89_8852a_txpwr_lmt_ru_5g[RTW89_RU_NUM][RTW89_NTX_NUM] [0][0][RTW89_MEXICO][15] = 48, [0][0][RTW89_CN][15] = 127, [0][0][RTW89_QATAR][15] = 24, + [0][0][RTW89_UK][15] = 24, [0][0][RTW89_FCC][17] = 48, [0][0][RTW89_ETSI][17] = 24, [0][0][RTW89_MKK][17] = 44, @@ -48829,6 +49269,7 @@ const s8 rtw89_8852a_txpwr_lmt_ru_5g[RTW89_RU_NUM][RTW89_NTX_NUM] [0][0][RTW89_MEXICO][17] = 48, [0][0][RTW89_CN][17] = 127, [0][0][RTW89_QATAR][17] = 24, + [0][0][RTW89_UK][17] = 24, [0][0][RTW89_FCC][19] = 48, [0][0][RTW89_ETSI][19] = 24, [0][0][RTW89_MKK][19] = 44, @@ -48840,6 +49281,7 @@ const s8 rtw89_8852a_txpwr_lmt_ru_5g[RTW89_RU_NUM][RTW89_NTX_NUM] [0][0][RTW89_MEXICO][19] = 48, [0][0][RTW89_CN][19] = 127, [0][0][RTW89_QATAR][19] = 24, + [0][0][RTW89_UK][19] = 24, [0][0][RTW89_FCC][21] = 48, [0][0][RTW89_ETSI][21] = 24, [0][0][RTW89_MKK][21] = 44, @@ -48851,6 +49293,7 @@ const s8 rtw89_8852a_txpwr_lmt_ru_5g[RTW89_RU_NUM][RTW89_NTX_NUM] [0][0][RTW89_MEXICO][21] = 48, [0][0][RTW89_CN][21] = 127, [0][0][RTW89_QATAR][21] = 24, + [0][0][RTW89_UK][21] = 24, [0][0][RTW89_FCC][23] = 48, [0][0][RTW89_ETSI][23] = 24, [0][0][RTW89_MKK][23] = 44, @@ -48862,6 +49305,7 @@ const s8 rtw89_8852a_txpwr_lmt_ru_5g[RTW89_RU_NUM][RTW89_NTX_NUM] [0][0][RTW89_MEXICO][23] = 48, [0][0][RTW89_CN][23] = 127, [0][0][RTW89_QATAR][23] = 24, + [0][0][RTW89_UK][23] = 24, [0][0][RTW89_FCC][25] = 48, [0][0][RTW89_ETSI][25] = 24, [0][0][RTW89_MKK][25] = 44, @@ -48873,6 +49317,7 @@ const s8 rtw89_8852a_txpwr_lmt_ru_5g[RTW89_RU_NUM][RTW89_NTX_NUM] [0][0][RTW89_MEXICO][25] = 48, [0][0][RTW89_CN][25] = 127, [0][0][RTW89_QATAR][25] = 24, + [0][0][RTW89_UK][25] = 24, [0][0][RTW89_FCC][27] = 48, [0][0][RTW89_ETSI][27] = 24, [0][0][RTW89_MKK][27] = 44, @@ -48884,6 +49329,7 @@ const s8 rtw89_8852a_txpwr_lmt_ru_5g[RTW89_RU_NUM][RTW89_NTX_NUM] [0][0][RTW89_MEXICO][27] = 48, [0][0][RTW89_CN][27] = 127, [0][0][RTW89_QATAR][27] = 24, + [0][0][RTW89_UK][27] = 24, [0][0][RTW89_FCC][29] = 48, [0][0][RTW89_ETSI][29] = 24, [0][0][RTW89_MKK][29] = 44, @@ -48895,6 +49341,7 @@ const s8 rtw89_8852a_txpwr_lmt_ru_5g[RTW89_RU_NUM][RTW89_NTX_NUM] [0][0][RTW89_MEXICO][29] = 48, [0][0][RTW89_CN][29] = 127, [0][0][RTW89_QATAR][29] = 24, + [0][0][RTW89_UK][29] = 24, [0][0][RTW89_FCC][31] = 48, [0][0][RTW89_ETSI][31] = 24, [0][0][RTW89_MKK][31] = 44, @@ -48906,6 +49353,7 @@ const s8 rtw89_8852a_txpwr_lmt_ru_5g[RTW89_RU_NUM][RTW89_NTX_NUM] [0][0][RTW89_MEXICO][31] = 48, [0][0][RTW89_CN][31] = 127, [0][0][RTW89_QATAR][31] = 24, + [0][0][RTW89_UK][31] = 24, [0][0][RTW89_FCC][33] = 48, [0][0][RTW89_ETSI][33] = 24, [0][0][RTW89_MKK][33] = 44, @@ -48917,6 +49365,7 @@ const s8 rtw89_8852a_txpwr_lmt_ru_5g[RTW89_RU_NUM][RTW89_NTX_NUM] [0][0][RTW89_MEXICO][33] = 48, [0][0][RTW89_CN][33] = 127, [0][0][RTW89_QATAR][33] = 24, + [0][0][RTW89_UK][33] = 24, [0][0][RTW89_FCC][35] = 48, [0][0][RTW89_ETSI][35] = 24, [0][0][RTW89_MKK][35] = 44, @@ -48928,6 +49377,7 @@ const s8 rtw89_8852a_txpwr_lmt_ru_5g[RTW89_RU_NUM][RTW89_NTX_NUM] [0][0][RTW89_MEXICO][35] = 48, [0][0][RTW89_CN][35] = 127, [0][0][RTW89_QATAR][35] = 24, + [0][0][RTW89_UK][35] = 24, [0][0][RTW89_FCC][37] = 48, [0][0][RTW89_ETSI][37] = 127, [0][0][RTW89_MKK][37] = 44, @@ -48939,6 +49389,7 @@ const s8 rtw89_8852a_txpwr_lmt_ru_5g[RTW89_RU_NUM][RTW89_NTX_NUM] [0][0][RTW89_MEXICO][37] = 48, [0][0][RTW89_CN][37] = 127, [0][0][RTW89_QATAR][37] = 127, + [0][0][RTW89_UK][37] = 58, [0][0][RTW89_FCC][38] = 76, [0][0][RTW89_ETSI][38] = 28, [0][0][RTW89_MKK][38] = 127, @@ -48950,6 +49401,7 @@ const s8 rtw89_8852a_txpwr_lmt_ru_5g[RTW89_RU_NUM][RTW89_NTX_NUM] [0][0][RTW89_MEXICO][38] = 76, [0][0][RTW89_CN][38] = 62, [0][0][RTW89_QATAR][38] = 28, + [0][0][RTW89_UK][38] = 28, [0][0][RTW89_FCC][40] = 76, [0][0][RTW89_ETSI][40] = 28, [0][0][RTW89_MKK][40] = 127, @@ -48961,6 +49413,7 @@ const s8 rtw89_8852a_txpwr_lmt_ru_5g[RTW89_RU_NUM][RTW89_NTX_NUM] [0][0][RTW89_MEXICO][40] = 76, [0][0][RTW89_CN][40] = 62, [0][0][RTW89_QATAR][40] = 28, + [0][0][RTW89_UK][40] = 28, [0][0][RTW89_FCC][42] = 76, [0][0][RTW89_ETSI][42] = 28, [0][0][RTW89_MKK][42] = 127, @@ -48972,6 +49425,7 @@ const s8 rtw89_8852a_txpwr_lmt_ru_5g[RTW89_RU_NUM][RTW89_NTX_NUM] [0][0][RTW89_MEXICO][42] = 76, [0][0][RTW89_CN][42] = 62, [0][0][RTW89_QATAR][42] = 28, + [0][0][RTW89_UK][42] = 28, [0][0][RTW89_FCC][44] = 76, [0][0][RTW89_ETSI][44] = 28, [0][0][RTW89_MKK][44] = 127, @@ -48983,6 +49437,7 @@ const s8 rtw89_8852a_txpwr_lmt_ru_5g[RTW89_RU_NUM][RTW89_NTX_NUM] [0][0][RTW89_MEXICO][44] = 76, [0][0][RTW89_CN][44] = 62, [0][0][RTW89_QATAR][44] = 28, + [0][0][RTW89_UK][44] = 28, [0][0][RTW89_FCC][46] = 76, [0][0][RTW89_ETSI][46] = 28, [0][0][RTW89_MKK][46] = 127, @@ -48994,6 +49449,7 @@ const s8 rtw89_8852a_txpwr_lmt_ru_5g[RTW89_RU_NUM][RTW89_NTX_NUM] [0][0][RTW89_MEXICO][46] = 76, [0][0][RTW89_CN][46] = 62, [0][0][RTW89_QATAR][46] = 28, + [0][0][RTW89_UK][46] = 28, [0][1][RTW89_FCC][0] = 36, [0][1][RTW89_ETSI][0] = 12, [0][1][RTW89_MKK][0] = 14, @@ -49005,6 +49461,7 @@ const s8 rtw89_8852a_txpwr_lmt_ru_5g[RTW89_RU_NUM][RTW89_NTX_NUM] [0][1][RTW89_MEXICO][0] = 36, [0][1][RTW89_CN][0] = 12, [0][1][RTW89_QATAR][0] = 12, + [0][1][RTW89_UK][0] = 12, [0][1][RTW89_FCC][2] = 36, [0][1][RTW89_ETSI][2] = 12, [0][1][RTW89_MKK][2] = 14, @@ -49016,6 +49473,7 @@ const s8 rtw89_8852a_txpwr_lmt_ru_5g[RTW89_RU_NUM][RTW89_NTX_NUM] [0][1][RTW89_MEXICO][2] = 36, [0][1][RTW89_CN][2] = 12, [0][1][RTW89_QATAR][2] = 12, + [0][1][RTW89_UK][2] = 12, [0][1][RTW89_FCC][4] = 36, [0][1][RTW89_ETSI][4] = 12, [0][1][RTW89_MKK][4] = 14, @@ -49027,6 +49485,7 @@ const s8 rtw89_8852a_txpwr_lmt_ru_5g[RTW89_RU_NUM][RTW89_NTX_NUM] [0][1][RTW89_MEXICO][4] = 36, [0][1][RTW89_CN][4] = 12, [0][1][RTW89_QATAR][4] = 12, + [0][1][RTW89_UK][4] = 12, [0][1][RTW89_FCC][6] = 36, [0][1][RTW89_ETSI][6] = 12, [0][1][RTW89_MKK][6] = 14, @@ -49038,6 +49497,7 @@ const s8 rtw89_8852a_txpwr_lmt_ru_5g[RTW89_RU_NUM][RTW89_NTX_NUM] [0][1][RTW89_MEXICO][6] = 36, [0][1][RTW89_CN][6] = 12, [0][1][RTW89_QATAR][6] = 12, + [0][1][RTW89_UK][6] = 12, [0][1][RTW89_FCC][8] = 36, [0][1][RTW89_ETSI][8] = 12, [0][1][RTW89_MKK][8] = 14, @@ -49049,6 +49509,7 @@ const s8 rtw89_8852a_txpwr_lmt_ru_5g[RTW89_RU_NUM][RTW89_NTX_NUM] [0][1][RTW89_MEXICO][8] = 36, [0][1][RTW89_CN][8] = 12, [0][1][RTW89_QATAR][8] = 12, + [0][1][RTW89_UK][8] = 12, [0][1][RTW89_FCC][10] = 36, [0][1][RTW89_ETSI][10] = 12, [0][1][RTW89_MKK][10] = 14, @@ -49060,6 +49521,7 @@ const s8 rtw89_8852a_txpwr_lmt_ru_5g[RTW89_RU_NUM][RTW89_NTX_NUM] [0][1][RTW89_MEXICO][10] = 36, [0][1][RTW89_CN][10] = 12, [0][1][RTW89_QATAR][10] = 12, + [0][1][RTW89_UK][10] = 12, [0][1][RTW89_FCC][12] = 36, [0][1][RTW89_ETSI][12] = 12, [0][1][RTW89_MKK][12] = 14, @@ -49071,6 +49533,7 @@ const s8 rtw89_8852a_txpwr_lmt_ru_5g[RTW89_RU_NUM][RTW89_NTX_NUM] [0][1][RTW89_MEXICO][12] = 36, [0][1][RTW89_CN][12] = 12, [0][1][RTW89_QATAR][12] = 12, + [0][1][RTW89_UK][12] = 12, [0][1][RTW89_FCC][14] = 36, [0][1][RTW89_ETSI][14] = 12, [0][1][RTW89_MKK][14] = 14, @@ -49082,6 +49545,7 @@ const s8 rtw89_8852a_txpwr_lmt_ru_5g[RTW89_RU_NUM][RTW89_NTX_NUM] [0][1][RTW89_MEXICO][14] = 36, [0][1][RTW89_CN][14] = 12, [0][1][RTW89_QATAR][14] = 12, + [0][1][RTW89_UK][14] = 12, [0][1][RTW89_FCC][15] = 36, [0][1][RTW89_ETSI][15] = 12, [0][1][RTW89_MKK][15] = 32, @@ -49093,6 +49557,7 @@ const s8 rtw89_8852a_txpwr_lmt_ru_5g[RTW89_RU_NUM][RTW89_NTX_NUM] [0][1][RTW89_MEXICO][15] = 36, [0][1][RTW89_CN][15] = 127, [0][1][RTW89_QATAR][15] = 12, + [0][1][RTW89_UK][15] = 12, [0][1][RTW89_FCC][17] = 36, [0][1][RTW89_ETSI][17] = 12, [0][1][RTW89_MKK][17] = 32, @@ -49104,6 +49569,7 @@ const s8 rtw89_8852a_txpwr_lmt_ru_5g[RTW89_RU_NUM][RTW89_NTX_NUM] [0][1][RTW89_MEXICO][17] = 36, [0][1][RTW89_CN][17] = 127, [0][1][RTW89_QATAR][17] = 12, + [0][1][RTW89_UK][17] = 12, [0][1][RTW89_FCC][19] = 36, [0][1][RTW89_ETSI][19] = 12, [0][1][RTW89_MKK][19] = 32, @@ -49115,6 +49581,7 @@ const s8 rtw89_8852a_txpwr_lmt_ru_5g[RTW89_RU_NUM][RTW89_NTX_NUM] [0][1][RTW89_MEXICO][19] = 36, [0][1][RTW89_CN][19] = 127, [0][1][RTW89_QATAR][19] = 12, + [0][1][RTW89_UK][19] = 12, [0][1][RTW89_FCC][21] = 36, [0][1][RTW89_ETSI][21] = 12, [0][1][RTW89_MKK][21] = 32, @@ -49126,6 +49593,7 @@ const s8 rtw89_8852a_txpwr_lmt_ru_5g[RTW89_RU_NUM][RTW89_NTX_NUM] [0][1][RTW89_MEXICO][21] = 36, [0][1][RTW89_CN][21] = 127, [0][1][RTW89_QATAR][21] = 12, + [0][1][RTW89_UK][21] = 12, [0][1][RTW89_FCC][23] = 36, [0][1][RTW89_ETSI][23] = 12, [0][1][RTW89_MKK][23] = 32, @@ -49137,6 +49605,7 @@ const s8 rtw89_8852a_txpwr_lmt_ru_5g[RTW89_RU_NUM][RTW89_NTX_NUM] [0][1][RTW89_MEXICO][23] = 36, [0][1][RTW89_CN][23] = 127, [0][1][RTW89_QATAR][23] = 12, + [0][1][RTW89_UK][23] = 12, [0][1][RTW89_FCC][25] = 36, [0][1][RTW89_ETSI][25] = 12, [0][1][RTW89_MKK][25] = 32, @@ -49148,6 +49617,7 @@ const s8 rtw89_8852a_txpwr_lmt_ru_5g[RTW89_RU_NUM][RTW89_NTX_NUM] [0][1][RTW89_MEXICO][25] = 36, [0][1][RTW89_CN][25] = 127, [0][1][RTW89_QATAR][25] = 12, + [0][1][RTW89_UK][25] = 12, [0][1][RTW89_FCC][27] = 36, [0][1][RTW89_ETSI][27] = 12, [0][1][RTW89_MKK][27] = 32, @@ -49159,6 +49629,7 @@ const s8 rtw89_8852a_txpwr_lmt_ru_5g[RTW89_RU_NUM][RTW89_NTX_NUM] [0][1][RTW89_MEXICO][27] = 36, [0][1][RTW89_CN][27] = 127, [0][1][RTW89_QATAR][27] = 12, + [0][1][RTW89_UK][27] = 12, [0][1][RTW89_FCC][29] = 36, [0][1][RTW89_ETSI][29] = 12, [0][1][RTW89_MKK][29] = 32, @@ -49170,6 +49641,7 @@ const s8 rtw89_8852a_txpwr_lmt_ru_5g[RTW89_RU_NUM][RTW89_NTX_NUM] [0][1][RTW89_MEXICO][29] = 36, [0][1][RTW89_CN][29] = 127, [0][1][RTW89_QATAR][29] = 12, + [0][1][RTW89_UK][29] = 12, [0][1][RTW89_FCC][31] = 36, [0][1][RTW89_ETSI][31] = 12, [0][1][RTW89_MKK][31] = 32, @@ -49181,6 +49653,7 @@ const s8 rtw89_8852a_txpwr_lmt_ru_5g[RTW89_RU_NUM][RTW89_NTX_NUM] [0][1][RTW89_MEXICO][31] = 36, [0][1][RTW89_CN][31] = 127, [0][1][RTW89_QATAR][31] = 12, + [0][1][RTW89_UK][31] = 12, [0][1][RTW89_FCC][33] = 36, [0][1][RTW89_ETSI][33] = 12, [0][1][RTW89_MKK][33] = 32, @@ -49192,6 +49665,7 @@ const s8 rtw89_8852a_txpwr_lmt_ru_5g[RTW89_RU_NUM][RTW89_NTX_NUM] [0][1][RTW89_MEXICO][33] = 36, [0][1][RTW89_CN][33] = 127, [0][1][RTW89_QATAR][33] = 12, + [0][1][RTW89_UK][33] = 12, [0][1][RTW89_FCC][35] = 36, [0][1][RTW89_ETSI][35] = 12, [0][1][RTW89_MKK][35] = 32, @@ -49203,6 +49677,7 @@ const s8 rtw89_8852a_txpwr_lmt_ru_5g[RTW89_RU_NUM][RTW89_NTX_NUM] [0][1][RTW89_MEXICO][35] = 36, [0][1][RTW89_CN][35] = 127, [0][1][RTW89_QATAR][35] = 12, + [0][1][RTW89_UK][35] = 12, [0][1][RTW89_FCC][37] = 36, [0][1][RTW89_ETSI][37] = 127, [0][1][RTW89_MKK][37] = 32, @@ -49214,6 +49689,7 @@ const s8 rtw89_8852a_txpwr_lmt_ru_5g[RTW89_RU_NUM][RTW89_NTX_NUM] [0][1][RTW89_MEXICO][37] = 36, [0][1][RTW89_CN][37] = 127, [0][1][RTW89_QATAR][37] = 127, + [0][1][RTW89_UK][37] = 46, [0][1][RTW89_FCC][38] = 72, [0][1][RTW89_ETSI][38] = 16, [0][1][RTW89_MKK][38] = 127, @@ -49225,6 +49701,7 @@ const s8 rtw89_8852a_txpwr_lmt_ru_5g[RTW89_RU_NUM][RTW89_NTX_NUM] [0][1][RTW89_MEXICO][38] = 72, [0][1][RTW89_CN][38] = 50, [0][1][RTW89_QATAR][38] = 16, + [0][1][RTW89_UK][38] = 16, [0][1][RTW89_FCC][40] = 76, [0][1][RTW89_ETSI][40] = 16, [0][1][RTW89_MKK][40] = 127, @@ -49236,6 +49713,7 @@ const s8 rtw89_8852a_txpwr_lmt_ru_5g[RTW89_RU_NUM][RTW89_NTX_NUM] [0][1][RTW89_MEXICO][40] = 76, [0][1][RTW89_CN][40] = 50, [0][1][RTW89_QATAR][40] = 16, + [0][1][RTW89_UK][40] = 16, [0][1][RTW89_FCC][42] = 76, [0][1][RTW89_ETSI][42] = 16, [0][1][RTW89_MKK][42] = 127, @@ -49247,6 +49725,7 @@ const s8 rtw89_8852a_txpwr_lmt_ru_5g[RTW89_RU_NUM][RTW89_NTX_NUM] [0][1][RTW89_MEXICO][42] = 76, [0][1][RTW89_CN][42] = 50, [0][1][RTW89_QATAR][42] = 16, + [0][1][RTW89_UK][42] = 16, [0][1][RTW89_FCC][44] = 76, [0][1][RTW89_ETSI][44] = 16, [0][1][RTW89_MKK][44] = 127, @@ -49258,6 +49737,7 @@ const s8 rtw89_8852a_txpwr_lmt_ru_5g[RTW89_RU_NUM][RTW89_NTX_NUM] [0][1][RTW89_MEXICO][44] = 76, [0][1][RTW89_CN][44] = 50, [0][1][RTW89_QATAR][44] = 16, + [0][1][RTW89_UK][44] = 16, [0][1][RTW89_FCC][46] = 76, [0][1][RTW89_ETSI][46] = 16, [0][1][RTW89_MKK][46] = 127, @@ -49269,6 +49749,7 @@ const s8 rtw89_8852a_txpwr_lmt_ru_5g[RTW89_RU_NUM][RTW89_NTX_NUM] [0][1][RTW89_MEXICO][46] = 76, [0][1][RTW89_CN][46] = 50, [0][1][RTW89_QATAR][46] = 16, + [0][1][RTW89_UK][46] = 16, [1][0][RTW89_FCC][0] = 62, [1][0][RTW89_ETSI][0] = 36, [1][0][RTW89_MKK][0] = 36, @@ -49280,6 +49761,7 @@ const s8 rtw89_8852a_txpwr_lmt_ru_5g[RTW89_RU_NUM][RTW89_NTX_NUM] [1][0][RTW89_MEXICO][0] = 62, [1][0][RTW89_CN][0] = 36, [1][0][RTW89_QATAR][0] = 36, + [1][0][RTW89_UK][0] = 36, [1][0][RTW89_FCC][2] = 62, [1][0][RTW89_ETSI][2] = 36, [1][0][RTW89_MKK][2] = 36, @@ -49291,6 +49773,7 @@ const s8 rtw89_8852a_txpwr_lmt_ru_5g[RTW89_RU_NUM][RTW89_NTX_NUM] [1][0][RTW89_MEXICO][2] = 62, [1][0][RTW89_CN][2] = 36, [1][0][RTW89_QATAR][2] = 36, + [1][0][RTW89_UK][2] = 36, [1][0][RTW89_FCC][4] = 62, [1][0][RTW89_ETSI][4] = 36, [1][0][RTW89_MKK][4] = 36, @@ -49302,6 +49785,7 @@ const s8 rtw89_8852a_txpwr_lmt_ru_5g[RTW89_RU_NUM][RTW89_NTX_NUM] [1][0][RTW89_MEXICO][4] = 62, [1][0][RTW89_CN][4] = 36, [1][0][RTW89_QATAR][4] = 36, + [1][0][RTW89_UK][4] = 36, [1][0][RTW89_FCC][6] = 62, [1][0][RTW89_ETSI][6] = 36, [1][0][RTW89_MKK][6] = 36, @@ -49313,6 +49797,7 @@ const s8 rtw89_8852a_txpwr_lmt_ru_5g[RTW89_RU_NUM][RTW89_NTX_NUM] [1][0][RTW89_MEXICO][6] = 62, [1][0][RTW89_CN][6] = 36, [1][0][RTW89_QATAR][6] = 36, + [1][0][RTW89_UK][6] = 36, [1][0][RTW89_FCC][8] = 62, [1][0][RTW89_ETSI][8] = 36, [1][0][RTW89_MKK][8] = 36, @@ -49324,6 +49809,7 @@ const s8 rtw89_8852a_txpwr_lmt_ru_5g[RTW89_RU_NUM][RTW89_NTX_NUM] [1][0][RTW89_MEXICO][8] = 62, [1][0][RTW89_CN][8] = 36, [1][0][RTW89_QATAR][8] = 36, + [1][0][RTW89_UK][8] = 36, [1][0][RTW89_FCC][10] = 62, [1][0][RTW89_ETSI][10] = 36, [1][0][RTW89_MKK][10] = 36, @@ -49335,6 +49821,7 @@ const s8 rtw89_8852a_txpwr_lmt_ru_5g[RTW89_RU_NUM][RTW89_NTX_NUM] [1][0][RTW89_MEXICO][10] = 62, [1][0][RTW89_CN][10] = 36, [1][0][RTW89_QATAR][10] = 36, + [1][0][RTW89_UK][10] = 36, [1][0][RTW89_FCC][12] = 62, [1][0][RTW89_ETSI][12] = 36, [1][0][RTW89_MKK][12] = 36, @@ -49346,6 +49833,7 @@ const s8 rtw89_8852a_txpwr_lmt_ru_5g[RTW89_RU_NUM][RTW89_NTX_NUM] [1][0][RTW89_MEXICO][12] = 62, [1][0][RTW89_CN][12] = 36, [1][0][RTW89_QATAR][12] = 36, + [1][0][RTW89_UK][12] = 36, [1][0][RTW89_FCC][14] = 62, [1][0][RTW89_ETSI][14] = 36, [1][0][RTW89_MKK][14] = 36, @@ -49357,6 +49845,7 @@ const s8 rtw89_8852a_txpwr_lmt_ru_5g[RTW89_RU_NUM][RTW89_NTX_NUM] [1][0][RTW89_MEXICO][14] = 62, [1][0][RTW89_CN][14] = 36, [1][0][RTW89_QATAR][14] = 36, + [1][0][RTW89_UK][14] = 36, [1][0][RTW89_FCC][15] = 62, [1][0][RTW89_ETSI][15] = 36, [1][0][RTW89_MKK][15] = 58, @@ -49368,6 +49857,7 @@ const s8 rtw89_8852a_txpwr_lmt_ru_5g[RTW89_RU_NUM][RTW89_NTX_NUM] [1][0][RTW89_MEXICO][15] = 62, [1][0][RTW89_CN][15] = 127, [1][0][RTW89_QATAR][15] = 36, + [1][0][RTW89_UK][15] = 36, [1][0][RTW89_FCC][17] = 62, [1][0][RTW89_ETSI][17] = 36, [1][0][RTW89_MKK][17] = 58, @@ -49379,6 +49869,7 @@ const s8 rtw89_8852a_txpwr_lmt_ru_5g[RTW89_RU_NUM][RTW89_NTX_NUM] [1][0][RTW89_MEXICO][17] = 62, [1][0][RTW89_CN][17] = 127, [1][0][RTW89_QATAR][17] = 36, + [1][0][RTW89_UK][17] = 36, [1][0][RTW89_FCC][19] = 62, [1][0][RTW89_ETSI][19] = 36, [1][0][RTW89_MKK][19] = 58, @@ -49390,6 +49881,7 @@ const s8 rtw89_8852a_txpwr_lmt_ru_5g[RTW89_RU_NUM][RTW89_NTX_NUM] [1][0][RTW89_MEXICO][19] = 62, [1][0][RTW89_CN][19] = 127, [1][0][RTW89_QATAR][19] = 36, + [1][0][RTW89_UK][19] = 36, [1][0][RTW89_FCC][21] = 62, [1][0][RTW89_ETSI][21] = 36, [1][0][RTW89_MKK][21] = 58, @@ -49401,6 +49893,7 @@ const s8 rtw89_8852a_txpwr_lmt_ru_5g[RTW89_RU_NUM][RTW89_NTX_NUM] [1][0][RTW89_MEXICO][21] = 62, [1][0][RTW89_CN][21] = 127, [1][0][RTW89_QATAR][21] = 36, + [1][0][RTW89_UK][21] = 36, [1][0][RTW89_FCC][23] = 62, [1][0][RTW89_ETSI][23] = 36, [1][0][RTW89_MKK][23] = 58, @@ -49412,6 +49905,7 @@ const s8 rtw89_8852a_txpwr_lmt_ru_5g[RTW89_RU_NUM][RTW89_NTX_NUM] [1][0][RTW89_MEXICO][23] = 62, [1][0][RTW89_CN][23] = 127, [1][0][RTW89_QATAR][23] = 36, + [1][0][RTW89_UK][23] = 36, [1][0][RTW89_FCC][25] = 62, [1][0][RTW89_ETSI][25] = 36, [1][0][RTW89_MKK][25] = 58, @@ -49423,6 +49917,7 @@ const s8 rtw89_8852a_txpwr_lmt_ru_5g[RTW89_RU_NUM][RTW89_NTX_NUM] [1][0][RTW89_MEXICO][25] = 62, [1][0][RTW89_CN][25] = 127, [1][0][RTW89_QATAR][25] = 36, + [1][0][RTW89_UK][25] = 36, [1][0][RTW89_FCC][27] = 62, [1][0][RTW89_ETSI][27] = 36, [1][0][RTW89_MKK][27] = 58, @@ -49434,6 +49929,7 @@ const s8 rtw89_8852a_txpwr_lmt_ru_5g[RTW89_RU_NUM][RTW89_NTX_NUM] [1][0][RTW89_MEXICO][27] = 62, [1][0][RTW89_CN][27] = 127, [1][0][RTW89_QATAR][27] = 36, + [1][0][RTW89_UK][27] = 36, [1][0][RTW89_FCC][29] = 62, [1][0][RTW89_ETSI][29] = 36, [1][0][RTW89_MKK][29] = 58, @@ -49445,6 +49941,7 @@ const s8 rtw89_8852a_txpwr_lmt_ru_5g[RTW89_RU_NUM][RTW89_NTX_NUM] [1][0][RTW89_MEXICO][29] = 62, [1][0][RTW89_CN][29] = 127, [1][0][RTW89_QATAR][29] = 36, + [1][0][RTW89_UK][29] = 36, [1][0][RTW89_FCC][31] = 62, [1][0][RTW89_ETSI][31] = 36, [1][0][RTW89_MKK][31] = 58, @@ -49456,6 +49953,7 @@ const s8 rtw89_8852a_txpwr_lmt_ru_5g[RTW89_RU_NUM][RTW89_NTX_NUM] [1][0][RTW89_MEXICO][31] = 62, [1][0][RTW89_CN][31] = 127, [1][0][RTW89_QATAR][31] = 36, + [1][0][RTW89_UK][31] = 36, [1][0][RTW89_FCC][33] = 62, [1][0][RTW89_ETSI][33] = 36, [1][0][RTW89_MKK][33] = 58, @@ -49467,6 +49965,7 @@ const s8 rtw89_8852a_txpwr_lmt_ru_5g[RTW89_RU_NUM][RTW89_NTX_NUM] [1][0][RTW89_MEXICO][33] = 62, [1][0][RTW89_CN][33] = 127, [1][0][RTW89_QATAR][33] = 36, + [1][0][RTW89_UK][33] = 36, [1][0][RTW89_FCC][35] = 62, [1][0][RTW89_ETSI][35] = 36, [1][0][RTW89_MKK][35] = 58, @@ -49478,6 +49977,7 @@ const s8 rtw89_8852a_txpwr_lmt_ru_5g[RTW89_RU_NUM][RTW89_NTX_NUM] [1][0][RTW89_MEXICO][35] = 62, [1][0][RTW89_CN][35] = 127, [1][0][RTW89_QATAR][35] = 36, + [1][0][RTW89_UK][35] = 36, [1][0][RTW89_FCC][37] = 62, [1][0][RTW89_ETSI][37] = 127, [1][0][RTW89_MKK][37] = 58, @@ -49489,6 +49989,7 @@ const s8 rtw89_8852a_txpwr_lmt_ru_5g[RTW89_RU_NUM][RTW89_NTX_NUM] [1][0][RTW89_MEXICO][37] = 62, [1][0][RTW89_CN][37] = 127, [1][0][RTW89_QATAR][37] = 127, + [1][0][RTW89_UK][37] = 64, [1][0][RTW89_FCC][38] = 76, [1][0][RTW89_ETSI][38] = 28, [1][0][RTW89_MKK][38] = 127, @@ -49500,6 +50001,7 @@ const s8 rtw89_8852a_txpwr_lmt_ru_5g[RTW89_RU_NUM][RTW89_NTX_NUM] [1][0][RTW89_MEXICO][38] = 76, [1][0][RTW89_CN][38] = 74, [1][0][RTW89_QATAR][38] = 28, + [1][0][RTW89_UK][38] = 34, [1][0][RTW89_FCC][40] = 76, [1][0][RTW89_ETSI][40] = 28, [1][0][RTW89_MKK][40] = 127, @@ -49511,6 +50013,7 @@ const s8 rtw89_8852a_txpwr_lmt_ru_5g[RTW89_RU_NUM][RTW89_NTX_NUM] [1][0][RTW89_MEXICO][40] = 76, [1][0][RTW89_CN][40] = 74, [1][0][RTW89_QATAR][40] = 28, + [1][0][RTW89_UK][40] = 34, [1][0][RTW89_FCC][42] = 76, [1][0][RTW89_ETSI][42] = 28, [1][0][RTW89_MKK][42] = 127, @@ -49522,6 +50025,7 @@ const s8 rtw89_8852a_txpwr_lmt_ru_5g[RTW89_RU_NUM][RTW89_NTX_NUM] [1][0][RTW89_MEXICO][42] = 76, [1][0][RTW89_CN][42] = 74, [1][0][RTW89_QATAR][42] = 28, + [1][0][RTW89_UK][42] = 34, [1][0][RTW89_FCC][44] = 76, [1][0][RTW89_ETSI][44] = 28, [1][0][RTW89_MKK][44] = 127, @@ -49533,6 +50037,7 @@ const s8 rtw89_8852a_txpwr_lmt_ru_5g[RTW89_RU_NUM][RTW89_NTX_NUM] [1][0][RTW89_MEXICO][44] = 76, [1][0][RTW89_CN][44] = 74, [1][0][RTW89_QATAR][44] = 28, + [1][0][RTW89_UK][44] = 34, [1][0][RTW89_FCC][46] = 76, [1][0][RTW89_ETSI][46] = 28, [1][0][RTW89_MKK][46] = 127, @@ -49544,6 +50049,7 @@ const s8 rtw89_8852a_txpwr_lmt_ru_5g[RTW89_RU_NUM][RTW89_NTX_NUM] [1][0][RTW89_MEXICO][46] = 76, [1][0][RTW89_CN][46] = 74, [1][0][RTW89_QATAR][46] = 28, + [1][0][RTW89_UK][46] = 34, [1][1][RTW89_FCC][0] = 46, [1][1][RTW89_ETSI][0] = 22, [1][1][RTW89_MKK][0] = 24, @@ -49555,6 +50061,7 @@ const s8 rtw89_8852a_txpwr_lmt_ru_5g[RTW89_RU_NUM][RTW89_NTX_NUM] [1][1][RTW89_MEXICO][0] = 46, [1][1][RTW89_CN][0] = 22, [1][1][RTW89_QATAR][0] = 22, + [1][1][RTW89_UK][0] = 22, [1][1][RTW89_FCC][2] = 46, [1][1][RTW89_ETSI][2] = 22, [1][1][RTW89_MKK][2] = 24, @@ -49566,6 +50073,7 @@ const s8 rtw89_8852a_txpwr_lmt_ru_5g[RTW89_RU_NUM][RTW89_NTX_NUM] [1][1][RTW89_MEXICO][2] = 46, [1][1][RTW89_CN][2] = 22, [1][1][RTW89_QATAR][2] = 22, + [1][1][RTW89_UK][2] = 22, [1][1][RTW89_FCC][4] = 46, [1][1][RTW89_ETSI][4] = 22, [1][1][RTW89_MKK][4] = 24, @@ -49577,6 +50085,7 @@ const s8 rtw89_8852a_txpwr_lmt_ru_5g[RTW89_RU_NUM][RTW89_NTX_NUM] [1][1][RTW89_MEXICO][4] = 46, [1][1][RTW89_CN][4] = 22, [1][1][RTW89_QATAR][4] = 22, + [1][1][RTW89_UK][4] = 22, [1][1][RTW89_FCC][6] = 46, [1][1][RTW89_ETSI][6] = 22, [1][1][RTW89_MKK][6] = 24, @@ -49588,6 +50097,7 @@ const s8 rtw89_8852a_txpwr_lmt_ru_5g[RTW89_RU_NUM][RTW89_NTX_NUM] [1][1][RTW89_MEXICO][6] = 46, [1][1][RTW89_CN][6] = 22, [1][1][RTW89_QATAR][6] = 22, + [1][1][RTW89_UK][6] = 22, [1][1][RTW89_FCC][8] = 46, [1][1][RTW89_ETSI][8] = 22, [1][1][RTW89_MKK][8] = 24, @@ -49599,6 +50109,7 @@ const s8 rtw89_8852a_txpwr_lmt_ru_5g[RTW89_RU_NUM][RTW89_NTX_NUM] [1][1][RTW89_MEXICO][8] = 46, [1][1][RTW89_CN][8] = 22, [1][1][RTW89_QATAR][8] = 22, + [1][1][RTW89_UK][8] = 22, [1][1][RTW89_FCC][10] = 46, [1][1][RTW89_ETSI][10] = 22, [1][1][RTW89_MKK][10] = 24, @@ -49610,6 +50121,7 @@ const s8 rtw89_8852a_txpwr_lmt_ru_5g[RTW89_RU_NUM][RTW89_NTX_NUM] [1][1][RTW89_MEXICO][10] = 46, [1][1][RTW89_CN][10] = 22, [1][1][RTW89_QATAR][10] = 22, + [1][1][RTW89_UK][10] = 22, [1][1][RTW89_FCC][12] = 46, [1][1][RTW89_ETSI][12] = 22, [1][1][RTW89_MKK][12] = 24, @@ -49621,6 +50133,7 @@ const s8 rtw89_8852a_txpwr_lmt_ru_5g[RTW89_RU_NUM][RTW89_NTX_NUM] [1][1][RTW89_MEXICO][12] = 46, [1][1][RTW89_CN][12] = 22, [1][1][RTW89_QATAR][12] = 22, + [1][1][RTW89_UK][12] = 22, [1][1][RTW89_FCC][14] = 46, [1][1][RTW89_ETSI][14] = 22, [1][1][RTW89_MKK][14] = 24, @@ -49632,6 +50145,7 @@ const s8 rtw89_8852a_txpwr_lmt_ru_5g[RTW89_RU_NUM][RTW89_NTX_NUM] [1][1][RTW89_MEXICO][14] = 46, [1][1][RTW89_CN][14] = 22, [1][1][RTW89_QATAR][14] = 22, + [1][1][RTW89_UK][14] = 22, [1][1][RTW89_FCC][15] = 46, [1][1][RTW89_ETSI][15] = 22, [1][1][RTW89_MKK][15] = 46, @@ -49643,6 +50157,7 @@ const s8 rtw89_8852a_txpwr_lmt_ru_5g[RTW89_RU_NUM][RTW89_NTX_NUM] [1][1][RTW89_MEXICO][15] = 46, [1][1][RTW89_CN][15] = 127, [1][1][RTW89_QATAR][15] = 22, + [1][1][RTW89_UK][15] = 22, [1][1][RTW89_FCC][17] = 46, [1][1][RTW89_ETSI][17] = 22, [1][1][RTW89_MKK][17] = 46, @@ -49654,6 +50169,7 @@ const s8 rtw89_8852a_txpwr_lmt_ru_5g[RTW89_RU_NUM][RTW89_NTX_NUM] [1][1][RTW89_MEXICO][17] = 46, [1][1][RTW89_CN][17] = 127, [1][1][RTW89_QATAR][17] = 22, + [1][1][RTW89_UK][17] = 22, [1][1][RTW89_FCC][19] = 46, [1][1][RTW89_ETSI][19] = 22, [1][1][RTW89_MKK][19] = 46, @@ -49665,6 +50181,7 @@ const s8 rtw89_8852a_txpwr_lmt_ru_5g[RTW89_RU_NUM][RTW89_NTX_NUM] [1][1][RTW89_MEXICO][19] = 46, [1][1][RTW89_CN][19] = 127, [1][1][RTW89_QATAR][19] = 22, + [1][1][RTW89_UK][19] = 22, [1][1][RTW89_FCC][21] = 46, [1][1][RTW89_ETSI][21] = 22, [1][1][RTW89_MKK][21] = 46, @@ -49676,6 +50193,7 @@ const s8 rtw89_8852a_txpwr_lmt_ru_5g[RTW89_RU_NUM][RTW89_NTX_NUM] [1][1][RTW89_MEXICO][21] = 46, [1][1][RTW89_CN][21] = 127, [1][1][RTW89_QATAR][21] = 22, + [1][1][RTW89_UK][21] = 22, [1][1][RTW89_FCC][23] = 46, [1][1][RTW89_ETSI][23] = 22, [1][1][RTW89_MKK][23] = 46, @@ -49687,6 +50205,7 @@ const s8 rtw89_8852a_txpwr_lmt_ru_5g[RTW89_RU_NUM][RTW89_NTX_NUM] [1][1][RTW89_MEXICO][23] = 46, [1][1][RTW89_CN][23] = 127, [1][1][RTW89_QATAR][23] = 22, + [1][1][RTW89_UK][23] = 22, [1][1][RTW89_FCC][25] = 46, [1][1][RTW89_ETSI][25] = 22, [1][1][RTW89_MKK][25] = 46, @@ -49698,6 +50217,7 @@ const s8 rtw89_8852a_txpwr_lmt_ru_5g[RTW89_RU_NUM][RTW89_NTX_NUM] [1][1][RTW89_MEXICO][25] = 46, [1][1][RTW89_CN][25] = 127, [1][1][RTW89_QATAR][25] = 22, + [1][1][RTW89_UK][25] = 22, [1][1][RTW89_FCC][27] = 46, [1][1][RTW89_ETSI][27] = 22, [1][1][RTW89_MKK][27] = 46, @@ -49709,6 +50229,7 @@ const s8 rtw89_8852a_txpwr_lmt_ru_5g[RTW89_RU_NUM][RTW89_NTX_NUM] [1][1][RTW89_MEXICO][27] = 46, [1][1][RTW89_CN][27] = 127, [1][1][RTW89_QATAR][27] = 22, + [1][1][RTW89_UK][27] = 22, [1][1][RTW89_FCC][29] = 46, [1][1][RTW89_ETSI][29] = 22, [1][1][RTW89_MKK][29] = 46, @@ -49720,6 +50241,7 @@ const s8 rtw89_8852a_txpwr_lmt_ru_5g[RTW89_RU_NUM][RTW89_NTX_NUM] [1][1][RTW89_MEXICO][29] = 46, [1][1][RTW89_CN][29] = 127, [1][1][RTW89_QATAR][29] = 22, + [1][1][RTW89_UK][29] = 22, [1][1][RTW89_FCC][31] = 46, [1][1][RTW89_ETSI][31] = 22, [1][1][RTW89_MKK][31] = 46, @@ -49731,6 +50253,7 @@ const s8 rtw89_8852a_txpwr_lmt_ru_5g[RTW89_RU_NUM][RTW89_NTX_NUM] [1][1][RTW89_MEXICO][31] = 46, [1][1][RTW89_CN][31] = 127, [1][1][RTW89_QATAR][31] = 22, + [1][1][RTW89_UK][31] = 22, [1][1][RTW89_FCC][33] = 46, [1][1][RTW89_ETSI][33] = 22, [1][1][RTW89_MKK][33] = 46, @@ -49742,6 +50265,7 @@ const s8 rtw89_8852a_txpwr_lmt_ru_5g[RTW89_RU_NUM][RTW89_NTX_NUM] [1][1][RTW89_MEXICO][33] = 46, [1][1][RTW89_CN][33] = 127, [1][1][RTW89_QATAR][33] = 22, + [1][1][RTW89_UK][33] = 22, [1][1][RTW89_FCC][35] = 46, [1][1][RTW89_ETSI][35] = 22, [1][1][RTW89_MKK][35] = 46, @@ -49753,6 +50277,7 @@ const s8 rtw89_8852a_txpwr_lmt_ru_5g[RTW89_RU_NUM][RTW89_NTX_NUM] [1][1][RTW89_MEXICO][35] = 46, [1][1][RTW89_CN][35] = 127, [1][1][RTW89_QATAR][35] = 22, + [1][1][RTW89_UK][35] = 22, [1][1][RTW89_FCC][37] = 46, [1][1][RTW89_ETSI][37] = 127, [1][1][RTW89_MKK][37] = 46, @@ -49764,6 +50289,7 @@ const s8 rtw89_8852a_txpwr_lmt_ru_5g[RTW89_RU_NUM][RTW89_NTX_NUM] [1][1][RTW89_MEXICO][37] = 46, [1][1][RTW89_CN][37] = 127, [1][1][RTW89_QATAR][37] = 127, + [1][1][RTW89_UK][37] = 52, [1][1][RTW89_FCC][38] = 74, [1][1][RTW89_ETSI][38] = 16, [1][1][RTW89_MKK][38] = 127, @@ -49775,6 +50301,7 @@ const s8 rtw89_8852a_txpwr_lmt_ru_5g[RTW89_RU_NUM][RTW89_NTX_NUM] [1][1][RTW89_MEXICO][38] = 74, [1][1][RTW89_CN][38] = 62, [1][1][RTW89_QATAR][38] = 16, + [1][1][RTW89_UK][38] = 22, [1][1][RTW89_FCC][40] = 76, [1][1][RTW89_ETSI][40] = 16, [1][1][RTW89_MKK][40] = 127, @@ -49786,6 +50313,7 @@ const s8 rtw89_8852a_txpwr_lmt_ru_5g[RTW89_RU_NUM][RTW89_NTX_NUM] [1][1][RTW89_MEXICO][40] = 76, [1][1][RTW89_CN][40] = 62, [1][1][RTW89_QATAR][40] = 16, + [1][1][RTW89_UK][40] = 22, [1][1][RTW89_FCC][42] = 76, [1][1][RTW89_ETSI][42] = 16, [1][1][RTW89_MKK][42] = 127, @@ -49797,6 +50325,7 @@ const s8 rtw89_8852a_txpwr_lmt_ru_5g[RTW89_RU_NUM][RTW89_NTX_NUM] [1][1][RTW89_MEXICO][42] = 76, [1][1][RTW89_CN][42] = 62, [1][1][RTW89_QATAR][42] = 16, + [1][1][RTW89_UK][42] = 22, [1][1][RTW89_FCC][44] = 76, [1][1][RTW89_ETSI][44] = 16, [1][1][RTW89_MKK][44] = 127, @@ -49808,6 +50337,7 @@ const s8 rtw89_8852a_txpwr_lmt_ru_5g[RTW89_RU_NUM][RTW89_NTX_NUM] [1][1][RTW89_MEXICO][44] = 76, [1][1][RTW89_CN][44] = 62, [1][1][RTW89_QATAR][44] = 16, + [1][1][RTW89_UK][44] = 22, [1][1][RTW89_FCC][46] = 76, [1][1][RTW89_ETSI][46] = 16, [1][1][RTW89_MKK][46] = 127, @@ -49819,6 +50349,7 @@ const s8 rtw89_8852a_txpwr_lmt_ru_5g[RTW89_RU_NUM][RTW89_NTX_NUM] [1][1][RTW89_MEXICO][46] = 76, [1][1][RTW89_CN][46] = 62, [1][1][RTW89_QATAR][46] = 16, + [1][1][RTW89_UK][46] = 22, [2][0][RTW89_FCC][0] = 74, [2][0][RTW89_ETSI][0] = 46, [2][0][RTW89_MKK][0] = 50, @@ -49830,6 +50361,7 @@ const s8 rtw89_8852a_txpwr_lmt_ru_5g[RTW89_RU_NUM][RTW89_NTX_NUM] [2][0][RTW89_MEXICO][0] = 62, [2][0][RTW89_CN][0] = 46, [2][0][RTW89_QATAR][0] = 46, + [2][0][RTW89_UK][0] = 46, [2][0][RTW89_FCC][2] = 74, [2][0][RTW89_ETSI][2] = 46, [2][0][RTW89_MKK][2] = 50, @@ -49841,6 +50373,7 @@ const s8 rtw89_8852a_txpwr_lmt_ru_5g[RTW89_RU_NUM][RTW89_NTX_NUM] [2][0][RTW89_MEXICO][2] = 62, [2][0][RTW89_CN][2] = 46, [2][0][RTW89_QATAR][2] = 46, + [2][0][RTW89_UK][2] = 46, [2][0][RTW89_FCC][4] = 74, [2][0][RTW89_ETSI][4] = 46, [2][0][RTW89_MKK][4] = 50, @@ -49852,6 +50385,7 @@ const s8 rtw89_8852a_txpwr_lmt_ru_5g[RTW89_RU_NUM][RTW89_NTX_NUM] [2][0][RTW89_MEXICO][4] = 62, [2][0][RTW89_CN][4] = 46, [2][0][RTW89_QATAR][4] = 46, + [2][0][RTW89_UK][4] = 46, [2][0][RTW89_FCC][6] = 74, [2][0][RTW89_ETSI][6] = 46, [2][0][RTW89_MKK][6] = 50, @@ -49863,6 +50397,7 @@ const s8 rtw89_8852a_txpwr_lmt_ru_5g[RTW89_RU_NUM][RTW89_NTX_NUM] [2][0][RTW89_MEXICO][6] = 62, [2][0][RTW89_CN][6] = 46, [2][0][RTW89_QATAR][6] = 46, + [2][0][RTW89_UK][6] = 46, [2][0][RTW89_FCC][8] = 74, [2][0][RTW89_ETSI][8] = 46, [2][0][RTW89_MKK][8] = 50, @@ -49874,6 +50409,7 @@ const s8 rtw89_8852a_txpwr_lmt_ru_5g[RTW89_RU_NUM][RTW89_NTX_NUM] [2][0][RTW89_MEXICO][8] = 74, [2][0][RTW89_CN][8] = 46, [2][0][RTW89_QATAR][8] = 46, + [2][0][RTW89_UK][8] = 46, [2][0][RTW89_FCC][10] = 74, [2][0][RTW89_ETSI][10] = 46, [2][0][RTW89_MKK][10] = 50, @@ -49885,6 +50421,7 @@ const s8 rtw89_8852a_txpwr_lmt_ru_5g[RTW89_RU_NUM][RTW89_NTX_NUM] [2][0][RTW89_MEXICO][10] = 74, [2][0][RTW89_CN][10] = 46, [2][0][RTW89_QATAR][10] = 46, + [2][0][RTW89_UK][10] = 46, [2][0][RTW89_FCC][12] = 74, [2][0][RTW89_ETSI][12] = 46, [2][0][RTW89_MKK][12] = 50, @@ -49896,6 +50433,7 @@ const s8 rtw89_8852a_txpwr_lmt_ru_5g[RTW89_RU_NUM][RTW89_NTX_NUM] [2][0][RTW89_MEXICO][12] = 74, [2][0][RTW89_CN][12] = 46, [2][0][RTW89_QATAR][12] = 46, + [2][0][RTW89_UK][12] = 46, [2][0][RTW89_FCC][14] = 74, [2][0][RTW89_ETSI][14] = 46, [2][0][RTW89_MKK][14] = 50, @@ -49907,6 +50445,7 @@ const s8 rtw89_8852a_txpwr_lmt_ru_5g[RTW89_RU_NUM][RTW89_NTX_NUM] [2][0][RTW89_MEXICO][14] = 74, [2][0][RTW89_CN][14] = 46, [2][0][RTW89_QATAR][14] = 46, + [2][0][RTW89_UK][14] = 46, [2][0][RTW89_FCC][15] = 74, [2][0][RTW89_ETSI][15] = 46, [2][0][RTW89_MKK][15] = 70, @@ -49918,6 +50457,7 @@ const s8 rtw89_8852a_txpwr_lmt_ru_5g[RTW89_RU_NUM][RTW89_NTX_NUM] [2][0][RTW89_MEXICO][15] = 74, [2][0][RTW89_CN][15] = 127, [2][0][RTW89_QATAR][15] = 46, + [2][0][RTW89_UK][15] = 46, [2][0][RTW89_FCC][17] = 74, [2][0][RTW89_ETSI][17] = 46, [2][0][RTW89_MKK][17] = 70, @@ -49929,6 +50469,7 @@ const s8 rtw89_8852a_txpwr_lmt_ru_5g[RTW89_RU_NUM][RTW89_NTX_NUM] [2][0][RTW89_MEXICO][17] = 74, [2][0][RTW89_CN][17] = 127, [2][0][RTW89_QATAR][17] = 46, + [2][0][RTW89_UK][17] = 46, [2][0][RTW89_FCC][19] = 74, [2][0][RTW89_ETSI][19] = 46, [2][0][RTW89_MKK][19] = 70, @@ -49940,6 +50481,7 @@ const s8 rtw89_8852a_txpwr_lmt_ru_5g[RTW89_RU_NUM][RTW89_NTX_NUM] [2][0][RTW89_MEXICO][19] = 74, [2][0][RTW89_CN][19] = 127, [2][0][RTW89_QATAR][19] = 46, + [2][0][RTW89_UK][19] = 46, [2][0][RTW89_FCC][21] = 74, [2][0][RTW89_ETSI][21] = 46, [2][0][RTW89_MKK][21] = 70, @@ -49951,6 +50493,7 @@ const s8 rtw89_8852a_txpwr_lmt_ru_5g[RTW89_RU_NUM][RTW89_NTX_NUM] [2][0][RTW89_MEXICO][21] = 74, [2][0][RTW89_CN][21] = 127, [2][0][RTW89_QATAR][21] = 46, + [2][0][RTW89_UK][21] = 46, [2][0][RTW89_FCC][23] = 74, [2][0][RTW89_ETSI][23] = 46, [2][0][RTW89_MKK][23] = 70, @@ -49962,6 +50505,7 @@ const s8 rtw89_8852a_txpwr_lmt_ru_5g[RTW89_RU_NUM][RTW89_NTX_NUM] [2][0][RTW89_MEXICO][23] = 74, [2][0][RTW89_CN][23] = 127, [2][0][RTW89_QATAR][23] = 46, + [2][0][RTW89_UK][23] = 46, [2][0][RTW89_FCC][25] = 74, [2][0][RTW89_ETSI][25] = 46, [2][0][RTW89_MKK][25] = 70, @@ -49973,6 +50517,7 @@ const s8 rtw89_8852a_txpwr_lmt_ru_5g[RTW89_RU_NUM][RTW89_NTX_NUM] [2][0][RTW89_MEXICO][25] = 74, [2][0][RTW89_CN][25] = 127, [2][0][RTW89_QATAR][25] = 46, + [2][0][RTW89_UK][25] = 46, [2][0][RTW89_FCC][27] = 74, [2][0][RTW89_ETSI][27] = 46, [2][0][RTW89_MKK][27] = 70, @@ -49984,6 +50529,7 @@ const s8 rtw89_8852a_txpwr_lmt_ru_5g[RTW89_RU_NUM][RTW89_NTX_NUM] [2][0][RTW89_MEXICO][27] = 74, [2][0][RTW89_CN][27] = 127, [2][0][RTW89_QATAR][27] = 46, + [2][0][RTW89_UK][27] = 46, [2][0][RTW89_FCC][29] = 74, [2][0][RTW89_ETSI][29] = 46, [2][0][RTW89_MKK][29] = 70, @@ -49995,6 +50541,7 @@ const s8 rtw89_8852a_txpwr_lmt_ru_5g[RTW89_RU_NUM][RTW89_NTX_NUM] [2][0][RTW89_MEXICO][29] = 74, [2][0][RTW89_CN][29] = 127, [2][0][RTW89_QATAR][29] = 46, + [2][0][RTW89_UK][29] = 46, [2][0][RTW89_FCC][31] = 74, [2][0][RTW89_ETSI][31] = 46, [2][0][RTW89_MKK][31] = 70, @@ -50006,6 +50553,7 @@ const s8 rtw89_8852a_txpwr_lmt_ru_5g[RTW89_RU_NUM][RTW89_NTX_NUM] [2][0][RTW89_MEXICO][31] = 74, [2][0][RTW89_CN][31] = 127, [2][0][RTW89_QATAR][31] = 46, + [2][0][RTW89_UK][31] = 46, [2][0][RTW89_FCC][33] = 74, [2][0][RTW89_ETSI][33] = 46, [2][0][RTW89_MKK][33] = 70, @@ -50017,6 +50565,7 @@ const s8 rtw89_8852a_txpwr_lmt_ru_5g[RTW89_RU_NUM][RTW89_NTX_NUM] [2][0][RTW89_MEXICO][33] = 74, [2][0][RTW89_CN][33] = 127, [2][0][RTW89_QATAR][33] = 46, + [2][0][RTW89_UK][33] = 46, [2][0][RTW89_FCC][35] = 74, [2][0][RTW89_ETSI][35] = 46, [2][0][RTW89_MKK][35] = 70, @@ -50028,6 +50577,7 @@ const s8 rtw89_8852a_txpwr_lmt_ru_5g[RTW89_RU_NUM][RTW89_NTX_NUM] [2][0][RTW89_MEXICO][35] = 74, [2][0][RTW89_CN][35] = 127, [2][0][RTW89_QATAR][35] = 46, + [2][0][RTW89_UK][35] = 46, [2][0][RTW89_FCC][37] = 74, [2][0][RTW89_ETSI][37] = 127, [2][0][RTW89_MKK][37] = 70, @@ -50039,6 +50589,7 @@ const s8 rtw89_8852a_txpwr_lmt_ru_5g[RTW89_RU_NUM][RTW89_NTX_NUM] [2][0][RTW89_MEXICO][37] = 74, [2][0][RTW89_CN][37] = 127, [2][0][RTW89_QATAR][37] = 127, + [2][0][RTW89_UK][37] = 74, [2][0][RTW89_FCC][38] = 76, [2][0][RTW89_ETSI][38] = 28, [2][0][RTW89_MKK][38] = 127, @@ -50050,6 +50601,7 @@ const s8 rtw89_8852a_txpwr_lmt_ru_5g[RTW89_RU_NUM][RTW89_NTX_NUM] [2][0][RTW89_MEXICO][38] = 76, [2][0][RTW89_CN][38] = 76, [2][0][RTW89_QATAR][38] = 28, + [2][0][RTW89_UK][38] = 44, [2][0][RTW89_FCC][40] = 76, [2][0][RTW89_ETSI][40] = 28, [2][0][RTW89_MKK][40] = 127, @@ -50061,6 +50613,7 @@ const s8 rtw89_8852a_txpwr_lmt_ru_5g[RTW89_RU_NUM][RTW89_NTX_NUM] [2][0][RTW89_MEXICO][40] = 76, [2][0][RTW89_CN][40] = 76, [2][0][RTW89_QATAR][40] = 28, + [2][0][RTW89_UK][40] = 44, [2][0][RTW89_FCC][42] = 76, [2][0][RTW89_ETSI][42] = 28, [2][0][RTW89_MKK][42] = 127, @@ -50072,6 +50625,7 @@ const s8 rtw89_8852a_txpwr_lmt_ru_5g[RTW89_RU_NUM][RTW89_NTX_NUM] [2][0][RTW89_MEXICO][42] = 76, [2][0][RTW89_CN][42] = 76, [2][0][RTW89_QATAR][42] = 28, + [2][0][RTW89_UK][42] = 44, [2][0][RTW89_FCC][44] = 76, [2][0][RTW89_ETSI][44] = 28, [2][0][RTW89_MKK][44] = 127, @@ -50083,6 +50637,7 @@ const s8 rtw89_8852a_txpwr_lmt_ru_5g[RTW89_RU_NUM][RTW89_NTX_NUM] [2][0][RTW89_MEXICO][44] = 76, [2][0][RTW89_CN][44] = 76, [2][0][RTW89_QATAR][44] = 28, + [2][0][RTW89_UK][44] = 44, [2][0][RTW89_FCC][46] = 76, [2][0][RTW89_ETSI][46] = 28, [2][0][RTW89_MKK][46] = 127, @@ -50094,6 +50649,7 @@ const s8 rtw89_8852a_txpwr_lmt_ru_5g[RTW89_RU_NUM][RTW89_NTX_NUM] [2][0][RTW89_MEXICO][46] = 76, [2][0][RTW89_CN][46] = 76, [2][0][RTW89_QATAR][46] = 28, + [2][0][RTW89_UK][46] = 44, [2][1][RTW89_FCC][0] = 58, [2][1][RTW89_ETSI][0] = 32, [2][1][RTW89_MKK][0] = 38, @@ -50105,6 +50661,7 @@ const s8 rtw89_8852a_txpwr_lmt_ru_5g[RTW89_RU_NUM][RTW89_NTX_NUM] [2][1][RTW89_MEXICO][0] = 50, [2][1][RTW89_CN][0] = 32, [2][1][RTW89_QATAR][0] = 32, + [2][1][RTW89_UK][0] = 32, [2][1][RTW89_FCC][2] = 58, [2][1][RTW89_ETSI][2] = 32, [2][1][RTW89_MKK][2] = 38, @@ -50116,6 +50673,7 @@ const s8 rtw89_8852a_txpwr_lmt_ru_5g[RTW89_RU_NUM][RTW89_NTX_NUM] [2][1][RTW89_MEXICO][2] = 50, [2][1][RTW89_CN][2] = 32, [2][1][RTW89_QATAR][2] = 32, + [2][1][RTW89_UK][2] = 32, [2][1][RTW89_FCC][4] = 58, [2][1][RTW89_ETSI][4] = 32, [2][1][RTW89_MKK][4] = 38, @@ -50127,6 +50685,7 @@ const s8 rtw89_8852a_txpwr_lmt_ru_5g[RTW89_RU_NUM][RTW89_NTX_NUM] [2][1][RTW89_MEXICO][4] = 50, [2][1][RTW89_CN][4] = 32, [2][1][RTW89_QATAR][4] = 32, + [2][1][RTW89_UK][4] = 32, [2][1][RTW89_FCC][6] = 58, [2][1][RTW89_ETSI][6] = 32, [2][1][RTW89_MKK][6] = 38, @@ -50138,6 +50697,7 @@ const s8 rtw89_8852a_txpwr_lmt_ru_5g[RTW89_RU_NUM][RTW89_NTX_NUM] [2][1][RTW89_MEXICO][6] = 50, [2][1][RTW89_CN][6] = 32, [2][1][RTW89_QATAR][6] = 32, + [2][1][RTW89_UK][6] = 32, [2][1][RTW89_FCC][8] = 58, [2][1][RTW89_ETSI][8] = 32, [2][1][RTW89_MKK][8] = 38, @@ -50149,6 +50709,7 @@ const s8 rtw89_8852a_txpwr_lmt_ru_5g[RTW89_RU_NUM][RTW89_NTX_NUM] [2][1][RTW89_MEXICO][8] = 58, [2][1][RTW89_CN][8] = 32, [2][1][RTW89_QATAR][8] = 32, + [2][1][RTW89_UK][8] = 32, [2][1][RTW89_FCC][10] = 58, [2][1][RTW89_ETSI][10] = 32, [2][1][RTW89_MKK][10] = 38, @@ -50160,6 +50721,7 @@ const s8 rtw89_8852a_txpwr_lmt_ru_5g[RTW89_RU_NUM][RTW89_NTX_NUM] [2][1][RTW89_MEXICO][10] = 58, [2][1][RTW89_CN][10] = 32, [2][1][RTW89_QATAR][10] = 32, + [2][1][RTW89_UK][10] = 32, [2][1][RTW89_FCC][12] = 58, [2][1][RTW89_ETSI][12] = 32, [2][1][RTW89_MKK][12] = 38, @@ -50171,6 +50733,7 @@ const s8 rtw89_8852a_txpwr_lmt_ru_5g[RTW89_RU_NUM][RTW89_NTX_NUM] [2][1][RTW89_MEXICO][12] = 58, [2][1][RTW89_CN][12] = 32, [2][1][RTW89_QATAR][12] = 32, + [2][1][RTW89_UK][12] = 32, [2][1][RTW89_FCC][14] = 58, [2][1][RTW89_ETSI][14] = 32, [2][1][RTW89_MKK][14] = 38, @@ -50182,6 +50745,7 @@ const s8 rtw89_8852a_txpwr_lmt_ru_5g[RTW89_RU_NUM][RTW89_NTX_NUM] [2][1][RTW89_MEXICO][14] = 58, [2][1][RTW89_CN][14] = 32, [2][1][RTW89_QATAR][14] = 32, + [2][1][RTW89_UK][14] = 32, [2][1][RTW89_FCC][15] = 58, [2][1][RTW89_ETSI][15] = 32, [2][1][RTW89_MKK][15] = 58, @@ -50193,6 +50757,7 @@ const s8 rtw89_8852a_txpwr_lmt_ru_5g[RTW89_RU_NUM][RTW89_NTX_NUM] [2][1][RTW89_MEXICO][15] = 58, [2][1][RTW89_CN][15] = 127, [2][1][RTW89_QATAR][15] = 32, + [2][1][RTW89_UK][15] = 32, [2][1][RTW89_FCC][17] = 58, [2][1][RTW89_ETSI][17] = 32, [2][1][RTW89_MKK][17] = 58, @@ -50204,6 +50769,7 @@ const s8 rtw89_8852a_txpwr_lmt_ru_5g[RTW89_RU_NUM][RTW89_NTX_NUM] [2][1][RTW89_MEXICO][17] = 58, [2][1][RTW89_CN][17] = 127, [2][1][RTW89_QATAR][17] = 32, + [2][1][RTW89_UK][17] = 32, [2][1][RTW89_FCC][19] = 58, [2][1][RTW89_ETSI][19] = 32, [2][1][RTW89_MKK][19] = 58, @@ -50215,6 +50781,7 @@ const s8 rtw89_8852a_txpwr_lmt_ru_5g[RTW89_RU_NUM][RTW89_NTX_NUM] [2][1][RTW89_MEXICO][19] = 58, [2][1][RTW89_CN][19] = 127, [2][1][RTW89_QATAR][19] = 32, + [2][1][RTW89_UK][19] = 32, [2][1][RTW89_FCC][21] = 58, [2][1][RTW89_ETSI][21] = 32, [2][1][RTW89_MKK][21] = 58, @@ -50226,6 +50793,7 @@ const s8 rtw89_8852a_txpwr_lmt_ru_5g[RTW89_RU_NUM][RTW89_NTX_NUM] [2][1][RTW89_MEXICO][21] = 58, [2][1][RTW89_CN][21] = 127, [2][1][RTW89_QATAR][21] = 32, + [2][1][RTW89_UK][21] = 32, [2][1][RTW89_FCC][23] = 58, [2][1][RTW89_ETSI][23] = 32, [2][1][RTW89_MKK][23] = 58, @@ -50237,6 +50805,7 @@ const s8 rtw89_8852a_txpwr_lmt_ru_5g[RTW89_RU_NUM][RTW89_NTX_NUM] [2][1][RTW89_MEXICO][23] = 58, [2][1][RTW89_CN][23] = 127, [2][1][RTW89_QATAR][23] = 32, + [2][1][RTW89_UK][23] = 32, [2][1][RTW89_FCC][25] = 58, [2][1][RTW89_ETSI][25] = 32, [2][1][RTW89_MKK][25] = 58, @@ -50248,6 +50817,7 @@ const s8 rtw89_8852a_txpwr_lmt_ru_5g[RTW89_RU_NUM][RTW89_NTX_NUM] [2][1][RTW89_MEXICO][25] = 58, [2][1][RTW89_CN][25] = 127, [2][1][RTW89_QATAR][25] = 32, + [2][1][RTW89_UK][25] = 32, [2][1][RTW89_FCC][27] = 58, [2][1][RTW89_ETSI][27] = 32, [2][1][RTW89_MKK][27] = 58, @@ -50259,6 +50829,7 @@ const s8 rtw89_8852a_txpwr_lmt_ru_5g[RTW89_RU_NUM][RTW89_NTX_NUM] [2][1][RTW89_MEXICO][27] = 58, [2][1][RTW89_CN][27] = 127, [2][1][RTW89_QATAR][27] = 32, + [2][1][RTW89_UK][27] = 32, [2][1][RTW89_FCC][29] = 58, [2][1][RTW89_ETSI][29] = 32, [2][1][RTW89_MKK][29] = 58, @@ -50270,6 +50841,7 @@ const s8 rtw89_8852a_txpwr_lmt_ru_5g[RTW89_RU_NUM][RTW89_NTX_NUM] [2][1][RTW89_MEXICO][29] = 58, [2][1][RTW89_CN][29] = 127, [2][1][RTW89_QATAR][29] = 32, + [2][1][RTW89_UK][29] = 32, [2][1][RTW89_FCC][31] = 58, [2][1][RTW89_ETSI][31] = 32, [2][1][RTW89_MKK][31] = 58, @@ -50281,6 +50853,7 @@ const s8 rtw89_8852a_txpwr_lmt_ru_5g[RTW89_RU_NUM][RTW89_NTX_NUM] [2][1][RTW89_MEXICO][31] = 58, [2][1][RTW89_CN][31] = 127, [2][1][RTW89_QATAR][31] = 32, + [2][1][RTW89_UK][31] = 32, [2][1][RTW89_FCC][33] = 58, [2][1][RTW89_ETSI][33] = 32, [2][1][RTW89_MKK][33] = 58, @@ -50292,6 +50865,7 @@ const s8 rtw89_8852a_txpwr_lmt_ru_5g[RTW89_RU_NUM][RTW89_NTX_NUM] [2][1][RTW89_MEXICO][33] = 58, [2][1][RTW89_CN][33] = 127, [2][1][RTW89_QATAR][33] = 32, + [2][1][RTW89_UK][33] = 32, [2][1][RTW89_FCC][35] = 58, [2][1][RTW89_ETSI][35] = 32, [2][1][RTW89_MKK][35] = 58, @@ -50303,6 +50877,7 @@ const s8 rtw89_8852a_txpwr_lmt_ru_5g[RTW89_RU_NUM][RTW89_NTX_NUM] [2][1][RTW89_MEXICO][35] = 58, [2][1][RTW89_CN][35] = 127, [2][1][RTW89_QATAR][35] = 32, + [2][1][RTW89_UK][35] = 32, [2][1][RTW89_FCC][37] = 58, [2][1][RTW89_ETSI][37] = 127, [2][1][RTW89_MKK][37] = 58, @@ -50314,6 +50889,7 @@ const s8 rtw89_8852a_txpwr_lmt_ru_5g[RTW89_RU_NUM][RTW89_NTX_NUM] [2][1][RTW89_MEXICO][37] = 58, [2][1][RTW89_CN][37] = 127, [2][1][RTW89_QATAR][37] = 127, + [2][1][RTW89_UK][37] = 62, [2][1][RTW89_FCC][38] = 76, [2][1][RTW89_ETSI][38] = 16, [2][1][RTW89_MKK][38] = 127, @@ -50325,6 +50901,7 @@ const s8 rtw89_8852a_txpwr_lmt_ru_5g[RTW89_RU_NUM][RTW89_NTX_NUM] [2][1][RTW89_MEXICO][38] = 76, [2][1][RTW89_CN][38] = 64, [2][1][RTW89_QATAR][38] = 16, + [2][1][RTW89_UK][38] = 32, [2][1][RTW89_FCC][40] = 76, [2][1][RTW89_ETSI][40] = 16, [2][1][RTW89_MKK][40] = 127, @@ -50336,6 +50913,7 @@ const s8 rtw89_8852a_txpwr_lmt_ru_5g[RTW89_RU_NUM][RTW89_NTX_NUM] [2][1][RTW89_MEXICO][40] = 76, [2][1][RTW89_CN][40] = 64, [2][1][RTW89_QATAR][40] = 16, + [2][1][RTW89_UK][40] = 32, [2][1][RTW89_FCC][42] = 76, [2][1][RTW89_ETSI][42] = 16, [2][1][RTW89_MKK][42] = 127, @@ -50347,6 +50925,7 @@ const s8 rtw89_8852a_txpwr_lmt_ru_5g[RTW89_RU_NUM][RTW89_NTX_NUM] [2][1][RTW89_MEXICO][42] = 76, [2][1][RTW89_CN][42] = 64, [2][1][RTW89_QATAR][42] = 16, + [2][1][RTW89_UK][42] = 32, [2][1][RTW89_FCC][44] = 76, [2][1][RTW89_ETSI][44] = 16, [2][1][RTW89_MKK][44] = 127, @@ -50358,6 +50937,7 @@ const s8 rtw89_8852a_txpwr_lmt_ru_5g[RTW89_RU_NUM][RTW89_NTX_NUM] [2][1][RTW89_MEXICO][44] = 76, [2][1][RTW89_CN][44] = 64, [2][1][RTW89_QATAR][44] = 16, + [2][1][RTW89_UK][44] = 32, [2][1][RTW89_FCC][46] = 76, [2][1][RTW89_ETSI][46] = 16, [2][1][RTW89_MKK][46] = 127, @@ -50369,6 +50949,7 @@ const s8 rtw89_8852a_txpwr_lmt_ru_5g[RTW89_RU_NUM][RTW89_NTX_NUM] [2][1][RTW89_MEXICO][46] = 76, [2][1][RTW89_CN][46] = 64, [2][1][RTW89_QATAR][46] = 16, + [2][1][RTW89_UK][46] = 32, }; #define DECLARE_DIG_TABLE(name) \ From 034307088cb2bdf9b2f79cdc3ddc2be22c89bbfd Mon Sep 17 00:00:00 2001 From: Zong-Zhe Yang Date: Fri, 18 Mar 2022 10:32:06 +0800 Subject: [PATCH 061/228] rtw89: regd: consider 6G band Wrap regd debug dump into a macro and add dump for 6G band field. Extend the macro used to configure regd table to account for multiple bands beyond 2G and 5G. And the follow-up commit will configure the corresponding values for 6G band into regd table. Signed-off-by: Zong-Zhe Yang Signed-off-by: Ping-Ke Shih Signed-off-by: Kalle Valo Link: https://lore.kernel.org/r/20220318023214.32411-4-pkshih@realtek.com --- drivers/net/wireless/realtek/rtw89/regd.c | 37 +++++++++++------------ 1 file changed, 18 insertions(+), 19 deletions(-) diff --git a/drivers/net/wireless/realtek/rtw89/regd.c b/drivers/net/wireless/realtek/rtw89/regd.c index 4c37e590e43c3..4d4bc201485b4 100644 --- a/drivers/net/wireless/realtek/rtw89/regd.c +++ b/drivers/net/wireless/realtek/rtw89/regd.c @@ -5,10 +5,9 @@ #include "debug.h" #include "ps.h" -#define COUNTRY_REGD(_alpha2, _txpwr_regd_2g, _txpwr_regd_5g) \ +#define COUNTRY_REGD(_alpha2, _txpwr_regd...) \ {.alpha2 = (_alpha2), \ - .txpwr_regd[RTW89_BAND_2G] = (_txpwr_regd_2g), \ - .txpwr_regd[RTW89_BAND_5G] = (_txpwr_regd_5g) \ + .txpwr_regd = {_txpwr_regd}, \ } static const struct rtw89_regulatory rtw89_ww_regd = @@ -272,6 +271,17 @@ static bool rtw89_regd_is_ww(const struct rtw89_regulatory *regd) return regd == &rtw89_ww_regd; } +#define rtw89_debug_regd(_dev, _regd, _desc, _argv...) \ +do { \ + typeof(_regd) __r = _regd; \ + rtw89_debug(_dev, RTW89_DBG_REGD, _desc \ + ": %c%c: mapping txregd to {2g: %d, 5g: %d, 6g: %d}\n", \ + ##_argv, __r->alpha2[0], __r->alpha2[1], \ + __r->txpwr_regd[RTW89_BAND_2G], \ + __r->txpwr_regd[RTW89_BAND_5G], \ + __r->txpwr_regd[RTW89_BAND_6G]); \ +} while (0) + int rtw89_regd_init(struct rtw89_dev *rtwdev, void (*reg_notifier)(struct wiphy *wiphy, struct regulatory_request *request)) @@ -294,20 +304,12 @@ int rtw89_regd_init(struct rtw89_dev *rtwdev, if (ret) rtw89_warn(rtwdev, "failed to hint regulatory:%d\n", ret); - rtw89_debug(rtwdev, RTW89_DBG_REGD, - "efuse country code %c%c, mapping to 2g txregd %d, 5g txregd %d\n", - rtwdev->efuse.country_code[0], rtwdev->efuse.country_code[1], - rtwdev->regd->txpwr_regd[RTW89_BAND_2G], - rtwdev->regd->txpwr_regd[RTW89_BAND_5G]); - + rtw89_debug_regd(rtwdev, chip_regd, "efuse country code"); return 0; } - rtw89_debug(rtwdev, RTW89_DBG_REGD, - "worldwide roaming chip, follow the setting of stack(%c%c), mapping to 2g txregd %d, 5g txregd %d\n", - rtwdev->regd->alpha2[0], rtwdev->regd->alpha2[1], - rtwdev->regd->txpwr_regd[RTW89_BAND_2G], - rtwdev->regd->txpwr_regd[RTW89_BAND_5G]); + rtw89_debug_regd(rtwdev, rtwdev->regd, + "worldwide roaming chip, follow the setting of stack"); return 0; } @@ -341,11 +343,8 @@ void rtw89_regd_notifier(struct wiphy *wiphy, struct regulatory_request *request goto exit; } rtw89_regd_notifier_apply(rtwdev, wiphy, request); - rtw89_debug(rtwdev, RTW89_DBG_REGD, - "get alpha2 %c%c from initiator %d, mapping to 2g txregd %d, 5g txregd %d\n", - request->alpha2[0], request->alpha2[1], request->initiator, - rtwdev->regd->txpwr_regd[RTW89_BAND_2G], - rtwdev->regd->txpwr_regd[RTW89_BAND_5G]); + rtw89_debug_regd(rtwdev, rtwdev->regd, "get from initiator %d, alpha2", + request->initiator); rtw89_chip_set_txpwr(rtwdev); From 1ae30c37ecf11781efea733e84927f4480e12ebd Mon Sep 17 00:00:00 2001 From: Zong-Zhe Yang Date: Fri, 18 Mar 2022 10:32:07 +0800 Subject: [PATCH 062/228] rtw89: regd: update mapping table to R59-R32 Update notes: Configure rtw89_regulatory for 6G band according to country. Adjust country GB to use RTW89_UK entry on all bands. Signed-off-by: Zong-Zhe Yang Signed-off-by: Ping-Ke Shih Signed-off-by: Kalle Valo Link: https://lore.kernel.org/r/20220318023214.32411-5-pkshih@realtek.com --- drivers/net/wireless/realtek/rtw89/regd.c | 476 +++++++++++----------- 1 file changed, 238 insertions(+), 238 deletions(-) diff --git a/drivers/net/wireless/realtek/rtw89/regd.c b/drivers/net/wireless/realtek/rtw89/regd.c index 4d4bc201485b4..20c7afd3e70fe 100644 --- a/drivers/net/wireless/realtek/rtw89/regd.c +++ b/drivers/net/wireless/realtek/rtw89/regd.c @@ -14,244 +14,244 @@ static const struct rtw89_regulatory rtw89_ww_regd = COUNTRY_REGD("00", RTW89_WW, RTW89_WW); static const struct rtw89_regulatory rtw89_regd_map[] = { - COUNTRY_REGD("AR", RTW89_MEXICO, RTW89_MEXICO), - COUNTRY_REGD("BO", RTW89_FCC, RTW89_FCC), - COUNTRY_REGD("BR", RTW89_FCC, RTW89_FCC), - COUNTRY_REGD("CL", RTW89_CHILE, RTW89_CHILE), - COUNTRY_REGD("CO", RTW89_FCC, RTW89_FCC), - COUNTRY_REGD("CR", RTW89_FCC, RTW89_FCC), - COUNTRY_REGD("EC", RTW89_FCC, RTW89_FCC), - COUNTRY_REGD("SV", RTW89_FCC, RTW89_FCC), - COUNTRY_REGD("GT", RTW89_FCC, RTW89_FCC), - COUNTRY_REGD("HN", RTW89_FCC, RTW89_FCC), - COUNTRY_REGD("MX", RTW89_MEXICO, RTW89_MEXICO), - COUNTRY_REGD("NI", RTW89_FCC, RTW89_FCC), - COUNTRY_REGD("PA", RTW89_FCC, RTW89_FCC), - COUNTRY_REGD("PY", RTW89_FCC, RTW89_FCC), - COUNTRY_REGD("PE", RTW89_FCC, RTW89_FCC), - COUNTRY_REGD("US", RTW89_FCC, RTW89_FCC), - COUNTRY_REGD("UY", RTW89_FCC, RTW89_FCC), - COUNTRY_REGD("VE", RTW89_FCC, RTW89_FCC), - COUNTRY_REGD("PR", RTW89_FCC, RTW89_FCC), - COUNTRY_REGD("DO", RTW89_FCC, RTW89_FCC), - COUNTRY_REGD("AT", RTW89_ETSI, RTW89_ETSI), - COUNTRY_REGD("BE", RTW89_ETSI, RTW89_ETSI), - COUNTRY_REGD("CY", RTW89_ETSI, RTW89_ETSI), - COUNTRY_REGD("CZ", RTW89_ETSI, RTW89_ETSI), - COUNTRY_REGD("DK", RTW89_ETSI, RTW89_ETSI), - COUNTRY_REGD("EE", RTW89_ETSI, RTW89_ETSI), - COUNTRY_REGD("FI", RTW89_ETSI, RTW89_ETSI), - COUNTRY_REGD("FR", RTW89_ETSI, RTW89_ETSI), - COUNTRY_REGD("DE", RTW89_ETSI, RTW89_ETSI), - COUNTRY_REGD("GR", RTW89_ETSI, RTW89_ETSI), - COUNTRY_REGD("HU", RTW89_ETSI, RTW89_ETSI), - COUNTRY_REGD("IS", RTW89_ETSI, RTW89_ETSI), - COUNTRY_REGD("IE", RTW89_ETSI, RTW89_ETSI), - COUNTRY_REGD("IT", RTW89_ETSI, RTW89_ETSI), - COUNTRY_REGD("LV", RTW89_ETSI, RTW89_ETSI), - COUNTRY_REGD("LI", RTW89_ETSI, RTW89_ETSI), - COUNTRY_REGD("LT", RTW89_ETSI, RTW89_ETSI), - COUNTRY_REGD("LU", RTW89_ETSI, RTW89_ETSI), - COUNTRY_REGD("MT", RTW89_ETSI, RTW89_ETSI), - COUNTRY_REGD("MC", RTW89_ETSI, RTW89_ETSI), - COUNTRY_REGD("NL", RTW89_ETSI, RTW89_ETSI), - COUNTRY_REGD("NO", RTW89_ETSI, RTW89_ETSI), - COUNTRY_REGD("PL", RTW89_ETSI, RTW89_ETSI), - COUNTRY_REGD("PT", RTW89_ETSI, RTW89_ETSI), - COUNTRY_REGD("SK", RTW89_ETSI, RTW89_ETSI), - COUNTRY_REGD("SI", RTW89_ETSI, RTW89_ETSI), - COUNTRY_REGD("ES", RTW89_ETSI, RTW89_ETSI), - COUNTRY_REGD("SE", RTW89_ETSI, RTW89_ETSI), - COUNTRY_REGD("CH", RTW89_ETSI, RTW89_ETSI), - COUNTRY_REGD("GB", RTW89_ETSI, RTW89_ETSI), - COUNTRY_REGD("AL", RTW89_ETSI, RTW89_ETSI), - COUNTRY_REGD("AZ", RTW89_ETSI, RTW89_ETSI), - COUNTRY_REGD("BH", RTW89_ETSI, RTW89_ETSI), - COUNTRY_REGD("BA", RTW89_ETSI, RTW89_ETSI), - COUNTRY_REGD("BG", RTW89_ETSI, RTW89_ETSI), - COUNTRY_REGD("HR", RTW89_ETSI, RTW89_ETSI), - COUNTRY_REGD("EG", RTW89_ETSI, RTW89_ETSI), - COUNTRY_REGD("GH", RTW89_ETSI, RTW89_ETSI), - COUNTRY_REGD("IQ", RTW89_ETSI, RTW89_ETSI), - COUNTRY_REGD("IL", RTW89_ETSI, RTW89_ETSI), - COUNTRY_REGD("JO", RTW89_ETSI, RTW89_ETSI), - COUNTRY_REGD("KZ", RTW89_ETSI, RTW89_ETSI), - COUNTRY_REGD("KE", RTW89_ETSI, RTW89_ETSI), - COUNTRY_REGD("KW", RTW89_ETSI, RTW89_ETSI), - COUNTRY_REGD("KG", RTW89_ETSI, RTW89_ETSI), - COUNTRY_REGD("LB", RTW89_ETSI, RTW89_ETSI), - COUNTRY_REGD("LS", RTW89_ETSI, RTW89_ETSI), - COUNTRY_REGD("MK", RTW89_ETSI, RTW89_ETSI), - COUNTRY_REGD("MA", RTW89_ETSI, RTW89_ETSI), - COUNTRY_REGD("MZ", RTW89_ETSI, RTW89_ETSI), - COUNTRY_REGD("NA", RTW89_ETSI, RTW89_ETSI), - COUNTRY_REGD("NG", RTW89_ETSI, RTW89_ETSI), - COUNTRY_REGD("OM", RTW89_ETSI, RTW89_ETSI), - COUNTRY_REGD("QA", RTW89_QATAR, RTW89_QATAR), - COUNTRY_REGD("RO", RTW89_ETSI, RTW89_ETSI), - COUNTRY_REGD("RU", RTW89_ETSI, RTW89_ETSI), - COUNTRY_REGD("SA", RTW89_ETSI, RTW89_ETSI), - COUNTRY_REGD("SN", RTW89_ETSI, RTW89_ETSI), - COUNTRY_REGD("RS", RTW89_ETSI, RTW89_ETSI), - COUNTRY_REGD("ME", RTW89_ETSI, RTW89_ETSI), - COUNTRY_REGD("ZA", RTW89_ETSI, RTW89_ETSI), - COUNTRY_REGD("TR", RTW89_ETSI, RTW89_ETSI), - COUNTRY_REGD("UA", RTW89_UKRAINE, RTW89_UKRAINE), - COUNTRY_REGD("AE", RTW89_ETSI, RTW89_ETSI), - COUNTRY_REGD("YE", RTW89_ETSI, RTW89_ETSI), - COUNTRY_REGD("ZW", RTW89_ETSI, RTW89_ETSI), - COUNTRY_REGD("BD", RTW89_ETSI, RTW89_ETSI), - COUNTRY_REGD("KH", RTW89_ETSI, RTW89_ETSI), - COUNTRY_REGD("CN", RTW89_CN, RTW89_CN), - COUNTRY_REGD("HK", RTW89_ETSI, RTW89_ETSI), - COUNTRY_REGD("IN", RTW89_ETSI, RTW89_ETSI), - COUNTRY_REGD("ID", RTW89_ETSI, RTW89_ETSI), - COUNTRY_REGD("KR", RTW89_KCC, RTW89_KCC), - COUNTRY_REGD("MY", RTW89_ETSI, RTW89_ETSI), - COUNTRY_REGD("PK", RTW89_ETSI, RTW89_ETSI), - COUNTRY_REGD("PH", RTW89_ETSI, RTW89_ETSI), - COUNTRY_REGD("SG", RTW89_ETSI, RTW89_ETSI), - COUNTRY_REGD("LK", RTW89_ETSI, RTW89_ETSI), - COUNTRY_REGD("TW", RTW89_FCC, RTW89_FCC), - COUNTRY_REGD("TH", RTW89_ETSI, RTW89_ETSI), - COUNTRY_REGD("VN", RTW89_ETSI, RTW89_ETSI), - COUNTRY_REGD("AU", RTW89_ACMA, RTW89_ACMA), - COUNTRY_REGD("NZ", RTW89_ACMA, RTW89_ACMA), - COUNTRY_REGD("PG", RTW89_ETSI, RTW89_ETSI), - COUNTRY_REGD("CA", RTW89_IC, RTW89_IC), - COUNTRY_REGD("JP", RTW89_MKK, RTW89_MKK), - COUNTRY_REGD("JM", RTW89_FCC, RTW89_FCC), - COUNTRY_REGD("AN", RTW89_FCC, RTW89_FCC), - COUNTRY_REGD("TT", RTW89_FCC, RTW89_FCC), - COUNTRY_REGD("TN", RTW89_ETSI, RTW89_ETSI), - COUNTRY_REGD("AF", RTW89_ETSI, RTW89_ETSI), - COUNTRY_REGD("DZ", RTW89_ETSI, RTW89_ETSI), - COUNTRY_REGD("AS", RTW89_FCC, RTW89_FCC), - COUNTRY_REGD("AD", RTW89_ETSI, RTW89_ETSI), - COUNTRY_REGD("AO", RTW89_ETSI, RTW89_ETSI), - COUNTRY_REGD("AI", RTW89_ETSI, RTW89_ETSI), - COUNTRY_REGD("AQ", RTW89_ETSI, RTW89_ETSI), - COUNTRY_REGD("AG", RTW89_FCC, RTW89_FCC), - COUNTRY_REGD("AM", RTW89_ETSI, RTW89_ETSI), - COUNTRY_REGD("AW", RTW89_FCC, RTW89_FCC), - COUNTRY_REGD("BS", RTW89_FCC, RTW89_FCC), - COUNTRY_REGD("BB", RTW89_FCC, RTW89_FCC), - COUNTRY_REGD("BY", RTW89_ETSI, RTW89_ETSI), - COUNTRY_REGD("BZ", RTW89_FCC, RTW89_FCC), - COUNTRY_REGD("BJ", RTW89_ETSI, RTW89_ETSI), - COUNTRY_REGD("BM", RTW89_FCC, RTW89_FCC), - COUNTRY_REGD("BT", RTW89_ETSI, RTW89_ETSI), - COUNTRY_REGD("BW", RTW89_ETSI, RTW89_ETSI), - COUNTRY_REGD("BV", RTW89_ETSI, RTW89_ETSI), - COUNTRY_REGD("IO", RTW89_ETSI, RTW89_ETSI), - COUNTRY_REGD("VG", RTW89_FCC, RTW89_FCC), - COUNTRY_REGD("BN", RTW89_ETSI, RTW89_ETSI), - COUNTRY_REGD("BF", RTW89_ETSI, RTW89_ETSI), - COUNTRY_REGD("MM", RTW89_ETSI, RTW89_ETSI), - COUNTRY_REGD("BI", RTW89_ETSI, RTW89_ETSI), - COUNTRY_REGD("CM", RTW89_ETSI, RTW89_ETSI), - COUNTRY_REGD("CV", RTW89_ETSI, RTW89_ETSI), - COUNTRY_REGD("KY", RTW89_FCC, RTW89_FCC), - COUNTRY_REGD("CF", RTW89_ETSI, RTW89_ETSI), - COUNTRY_REGD("TD", RTW89_ETSI, RTW89_ETSI), - COUNTRY_REGD("CX", RTW89_ACMA, RTW89_ACMA), - COUNTRY_REGD("CC", RTW89_ETSI, RTW89_ETSI), - COUNTRY_REGD("KM", RTW89_ETSI, RTW89_ETSI), - COUNTRY_REGD("CG", RTW89_ETSI, RTW89_ETSI), - COUNTRY_REGD("CD", RTW89_ETSI, RTW89_ETSI), - COUNTRY_REGD("CK", RTW89_ETSI, RTW89_ETSI), - COUNTRY_REGD("CI", RTW89_ETSI, RTW89_ETSI), - COUNTRY_REGD("DJ", RTW89_ETSI, RTW89_ETSI), - COUNTRY_REGD("DM", RTW89_FCC, RTW89_FCC), - COUNTRY_REGD("GQ", RTW89_ETSI, RTW89_ETSI), - COUNTRY_REGD("ER", RTW89_ETSI, RTW89_ETSI), - COUNTRY_REGD("ET", RTW89_ETSI, RTW89_ETSI), - COUNTRY_REGD("FK", RTW89_ETSI, RTW89_ETSI), - COUNTRY_REGD("FO", RTW89_ETSI, RTW89_ETSI), - COUNTRY_REGD("FJ", RTW89_FCC, RTW89_FCC), - COUNTRY_REGD("GF", RTW89_ETSI, RTW89_ETSI), - COUNTRY_REGD("PF", RTW89_ETSI, RTW89_ETSI), - COUNTRY_REGD("TF", RTW89_ETSI, RTW89_ETSI), - COUNTRY_REGD("GA", RTW89_ETSI, RTW89_ETSI), - COUNTRY_REGD("GM", RTW89_ETSI, RTW89_ETSI), - COUNTRY_REGD("GE", RTW89_ETSI, RTW89_ETSI), - COUNTRY_REGD("GI", RTW89_ETSI, RTW89_ETSI), - COUNTRY_REGD("GL", RTW89_ETSI, RTW89_ETSI), - COUNTRY_REGD("GD", RTW89_FCC, RTW89_FCC), - COUNTRY_REGD("GP", RTW89_ETSI, RTW89_ETSI), - COUNTRY_REGD("GU", RTW89_FCC, RTW89_FCC), - COUNTRY_REGD("GG", RTW89_ETSI, RTW89_ETSI), - COUNTRY_REGD("GN", RTW89_ETSI, RTW89_ETSI), - COUNTRY_REGD("GW", RTW89_ETSI, RTW89_ETSI), - COUNTRY_REGD("GY", RTW89_NCC, RTW89_NCC), - COUNTRY_REGD("HT", RTW89_FCC, RTW89_FCC), - COUNTRY_REGD("HM", RTW89_ACMA, RTW89_ACMA), - COUNTRY_REGD("VA", RTW89_ETSI, RTW89_ETSI), - COUNTRY_REGD("IM", RTW89_ETSI, RTW89_ETSI), - COUNTRY_REGD("JE", RTW89_ETSI, RTW89_ETSI), - COUNTRY_REGD("KI", RTW89_ETSI, RTW89_ETSI), - COUNTRY_REGD("LA", RTW89_ETSI, RTW89_ETSI), - COUNTRY_REGD("LR", RTW89_ETSI, RTW89_ETSI), - COUNTRY_REGD("LY", RTW89_ETSI, RTW89_ETSI), - COUNTRY_REGD("MO", RTW89_ETSI, RTW89_ETSI), - COUNTRY_REGD("MG", RTW89_ETSI, RTW89_ETSI), - COUNTRY_REGD("MW", RTW89_ETSI, RTW89_ETSI), - COUNTRY_REGD("MV", RTW89_ETSI, RTW89_ETSI), - COUNTRY_REGD("ML", RTW89_ETSI, RTW89_ETSI), - COUNTRY_REGD("MH", RTW89_FCC, RTW89_FCC), - COUNTRY_REGD("MQ", RTW89_ETSI, RTW89_ETSI), - COUNTRY_REGD("MR", RTW89_ETSI, RTW89_ETSI), - COUNTRY_REGD("MU", RTW89_ETSI, RTW89_ETSI), - COUNTRY_REGD("YT", RTW89_ETSI, RTW89_ETSI), - COUNTRY_REGD("FM", RTW89_FCC, RTW89_FCC), - COUNTRY_REGD("MD", RTW89_ETSI, RTW89_ETSI), - COUNTRY_REGD("MN", RTW89_ETSI, RTW89_ETSI), - COUNTRY_REGD("MS", RTW89_ETSI, RTW89_ETSI), - COUNTRY_REGD("NR", RTW89_ETSI, RTW89_ETSI), - COUNTRY_REGD("NP", RTW89_ETSI, RTW89_ETSI), - COUNTRY_REGD("NC", RTW89_ETSI, RTW89_ETSI), - COUNTRY_REGD("NE", RTW89_ETSI, RTW89_ETSI), - COUNTRY_REGD("NU", RTW89_ACMA, RTW89_ACMA), - COUNTRY_REGD("NF", RTW89_ACMA, RTW89_ACMA), - COUNTRY_REGD("MP", RTW89_FCC, RTW89_FCC), - COUNTRY_REGD("PW", RTW89_FCC, RTW89_FCC), - COUNTRY_REGD("RE", RTW89_ETSI, RTW89_ETSI), - COUNTRY_REGD("RW", RTW89_ETSI, RTW89_ETSI), - COUNTRY_REGD("SH", RTW89_ETSI, RTW89_ETSI), - COUNTRY_REGD("KN", RTW89_FCC, RTW89_FCC), - COUNTRY_REGD("LC", RTW89_FCC, RTW89_FCC), - COUNTRY_REGD("MF", RTW89_FCC, RTW89_FCC), - COUNTRY_REGD("SX", RTW89_FCC, RTW89_FCC), - COUNTRY_REGD("PM", RTW89_ETSI, RTW89_ETSI), - COUNTRY_REGD("VC", RTW89_FCC, RTW89_FCC), - COUNTRY_REGD("WS", RTW89_FCC, RTW89_FCC), - COUNTRY_REGD("SM", RTW89_ETSI, RTW89_ETSI), - COUNTRY_REGD("ST", RTW89_FCC, RTW89_FCC), - COUNTRY_REGD("SC", RTW89_FCC, RTW89_FCC), - COUNTRY_REGD("SL", RTW89_ETSI, RTW89_ETSI), - COUNTRY_REGD("SB", RTW89_ETSI, RTW89_ETSI), - COUNTRY_REGD("SO", RTW89_ETSI, RTW89_ETSI), - COUNTRY_REGD("GS", RTW89_ETSI, RTW89_ETSI), - COUNTRY_REGD("SR", RTW89_FCC, RTW89_FCC), - COUNTRY_REGD("SJ", RTW89_ETSI, RTW89_ETSI), - COUNTRY_REGD("SZ", RTW89_ETSI, RTW89_ETSI), - COUNTRY_REGD("TJ", RTW89_ETSI, RTW89_ETSI), - COUNTRY_REGD("TZ", RTW89_ETSI, RTW89_ETSI), - COUNTRY_REGD("TG", RTW89_ETSI, RTW89_ETSI), - COUNTRY_REGD("TK", RTW89_ACMA, RTW89_ACMA), - COUNTRY_REGD("TO", RTW89_ETSI, RTW89_ETSI), - COUNTRY_REGD("TM", RTW89_ETSI, RTW89_ETSI), - COUNTRY_REGD("TC", RTW89_ETSI, RTW89_ETSI), - COUNTRY_REGD("TV", RTW89_ETSI, RTW89_NA), - COUNTRY_REGD("UG", RTW89_ETSI, RTW89_ETSI), - COUNTRY_REGD("VI", RTW89_FCC, RTW89_FCC), - COUNTRY_REGD("UZ", RTW89_ETSI, RTW89_ETSI), - COUNTRY_REGD("VU", RTW89_ETSI, RTW89_ETSI), - COUNTRY_REGD("WF", RTW89_ETSI, RTW89_ETSI), - COUNTRY_REGD("EH", RTW89_ETSI, RTW89_ETSI), - COUNTRY_REGD("ZM", RTW89_ETSI, RTW89_ETSI), - COUNTRY_REGD("IR", RTW89_ETSI, RTW89_ETSI), - COUNTRY_REGD("PS", RTW89_ETSI, RTW89_ETSI), + COUNTRY_REGD("AR", RTW89_MEXICO, RTW89_MEXICO, RTW89_NA), + 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_NA), + 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_NA), + COUNTRY_REGD("GT", RTW89_FCC, RTW89_FCC, RTW89_NA), + COUNTRY_REGD("HN", RTW89_FCC, RTW89_FCC, RTW89_FCC), + COUNTRY_REGD("MX", RTW89_MEXICO, RTW89_MEXICO, RTW89_NA), + 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_NA), + 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_NA), + 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_NA), + COUNTRY_REGD("BH", RTW89_ETSI, RTW89_ETSI, RTW89_NA), + COUNTRY_REGD("BA", RTW89_ETSI, RTW89_ETSI, RTW89_NA), + COUNTRY_REGD("BG", RTW89_ETSI, RTW89_ETSI, RTW89_NA), + COUNTRY_REGD("HR", RTW89_ETSI, RTW89_ETSI, RTW89_NA), + COUNTRY_REGD("EG", RTW89_ETSI, RTW89_ETSI, RTW89_NA), + COUNTRY_REGD("GH", RTW89_ETSI, RTW89_ETSI, RTW89_NA), + COUNTRY_REGD("IQ", RTW89_ETSI, RTW89_ETSI, RTW89_NA), + COUNTRY_REGD("IL", RTW89_ETSI, RTW89_ETSI, RTW89_NA), + COUNTRY_REGD("JO", RTW89_ETSI, RTW89_ETSI, RTW89_NA), + COUNTRY_REGD("KZ", RTW89_ETSI, RTW89_ETSI, RTW89_NA), + COUNTRY_REGD("KE", RTW89_ETSI, RTW89_ETSI, RTW89_NA), + COUNTRY_REGD("KW", RTW89_ETSI, RTW89_ETSI, RTW89_NA), + COUNTRY_REGD("KG", RTW89_ETSI, RTW89_ETSI, RTW89_NA), + COUNTRY_REGD("LB", RTW89_ETSI, RTW89_ETSI, RTW89_NA), + COUNTRY_REGD("LS", RTW89_ETSI, RTW89_ETSI, RTW89_NA), + COUNTRY_REGD("MK", RTW89_ETSI, RTW89_ETSI, RTW89_NA), + COUNTRY_REGD("MA", RTW89_ETSI, RTW89_ETSI, RTW89_NA), + COUNTRY_REGD("MZ", RTW89_ETSI, RTW89_ETSI, RTW89_NA), + COUNTRY_REGD("NA", RTW89_ETSI, RTW89_ETSI, RTW89_NA), + COUNTRY_REGD("NG", RTW89_ETSI, RTW89_ETSI, RTW89_NA), + COUNTRY_REGD("OM", RTW89_ETSI, RTW89_ETSI, RTW89_NA), + COUNTRY_REGD("QA", RTW89_QATAR, RTW89_QATAR, RTW89_QATAR), + COUNTRY_REGD("RO", RTW89_ETSI, RTW89_ETSI, RTW89_NA), + COUNTRY_REGD("RU", RTW89_ETSI, RTW89_ETSI, RTW89_NA), + COUNTRY_REGD("SA", RTW89_ETSI, RTW89_ETSI, RTW89_NA), + COUNTRY_REGD("SN", RTW89_ETSI, RTW89_ETSI, RTW89_NA), + COUNTRY_REGD("RS", RTW89_ETSI, RTW89_ETSI, RTW89_NA), + COUNTRY_REGD("ME", RTW89_ETSI, RTW89_ETSI, RTW89_NA), + COUNTRY_REGD("ZA", RTW89_ETSI, RTW89_ETSI, RTW89_NA), + COUNTRY_REGD("TR", RTW89_ETSI, RTW89_ETSI, RTW89_NA), + 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_NA), + 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_NA), + 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_NA), + COUNTRY_REGD("PK", RTW89_ETSI, RTW89_ETSI, RTW89_NA), + COUNTRY_REGD("PH", RTW89_ETSI, RTW89_ETSI, RTW89_NA), + COUNTRY_REGD("SG", RTW89_ETSI, RTW89_ETSI, RTW89_NA), + COUNTRY_REGD("LK", RTW89_ETSI, RTW89_ETSI, RTW89_NA), + COUNTRY_REGD("TW", RTW89_FCC, RTW89_FCC, RTW89_NA), + COUNTRY_REGD("TH", RTW89_ETSI, RTW89_ETSI, RTW89_NA), + COUNTRY_REGD("VN", RTW89_ETSI, RTW89_ETSI, RTW89_NA), + COUNTRY_REGD("AU", RTW89_ACMA, RTW89_ACMA, RTW89_NA), + COUNTRY_REGD("NZ", RTW89_ACMA, RTW89_ACMA, RTW89_NA), + COUNTRY_REGD("PG", RTW89_ETSI, RTW89_ETSI, RTW89_NA), + COUNTRY_REGD("CA", RTW89_IC, RTW89_IC, RTW89_IC), + COUNTRY_REGD("JP", RTW89_MKK, RTW89_MKK, RTW89_NA), + COUNTRY_REGD("JM", RTW89_FCC, RTW89_FCC, RTW89_NA), + COUNTRY_REGD("AN", RTW89_FCC, RTW89_FCC, RTW89_NA), + 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_NA), + 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_NA), + COUNTRY_REGD("AQ", RTW89_ETSI, RTW89_ETSI, RTW89_NA), + COUNTRY_REGD("AG", RTW89_FCC, RTW89_FCC, RTW89_NA), + COUNTRY_REGD("AM", RTW89_ETSI, RTW89_ETSI, RTW89_NA), + COUNTRY_REGD("AW", RTW89_FCC, RTW89_FCC, RTW89_NA), + COUNTRY_REGD("BS", RTW89_FCC, RTW89_FCC, RTW89_NA), + COUNTRY_REGD("BB", RTW89_FCC, RTW89_FCC, RTW89_NA), + 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_NA), + COUNTRY_REGD("BT", RTW89_ETSI, RTW89_ETSI, RTW89_NA), + COUNTRY_REGD("BW", RTW89_ETSI, RTW89_ETSI, RTW89_NA), + 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_NA), + COUNTRY_REGD("BN", RTW89_ETSI, RTW89_ETSI, RTW89_NA), + COUNTRY_REGD("BF", RTW89_ETSI, RTW89_ETSI, RTW89_NA), + COUNTRY_REGD("MM", RTW89_ETSI, RTW89_ETSI, RTW89_NA), + COUNTRY_REGD("BI", RTW89_ETSI, RTW89_ETSI, RTW89_NA), + 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_NA), + COUNTRY_REGD("CF", RTW89_ETSI, RTW89_ETSI, RTW89_NA), + COUNTRY_REGD("TD", RTW89_ETSI, RTW89_ETSI, RTW89_NA), + COUNTRY_REGD("CX", RTW89_ACMA, RTW89_ACMA, RTW89_NA), + COUNTRY_REGD("CC", RTW89_ETSI, RTW89_ETSI, RTW89_NA), + COUNTRY_REGD("KM", RTW89_ETSI, RTW89_ETSI, RTW89_NA), + COUNTRY_REGD("CG", RTW89_ETSI, RTW89_ETSI, RTW89_NA), + COUNTRY_REGD("CD", RTW89_ETSI, RTW89_ETSI, RTW89_NA), + 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_NA), + COUNTRY_REGD("DM", RTW89_FCC, RTW89_FCC, RTW89_NA), + COUNTRY_REGD("GQ", RTW89_ETSI, RTW89_ETSI, RTW89_NA), + 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_NA), + COUNTRY_REGD("GE", RTW89_ETSI, RTW89_ETSI, RTW89_NA), + COUNTRY_REGD("GI", RTW89_ETSI, RTW89_ETSI, RTW89_NA), + COUNTRY_REGD("GL", RTW89_ETSI, RTW89_ETSI, RTW89_NA), + COUNTRY_REGD("GD", RTW89_FCC, RTW89_FCC, RTW89_NA), + COUNTRY_REGD("GP", RTW89_ETSI, RTW89_ETSI, RTW89_NA), + COUNTRY_REGD("GU", RTW89_FCC, RTW89_FCC, RTW89_NA), + COUNTRY_REGD("GG", RTW89_ETSI, RTW89_ETSI, RTW89_NA), + COUNTRY_REGD("GN", RTW89_ETSI, RTW89_ETSI, RTW89_NA), + COUNTRY_REGD("GW", RTW89_ETSI, RTW89_ETSI, RTW89_NA), + COUNTRY_REGD("GY", RTW89_NCC, RTW89_NCC, RTW89_NA), + COUNTRY_REGD("HT", RTW89_FCC, RTW89_FCC, RTW89_NA), + 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("LA", RTW89_ETSI, RTW89_ETSI, RTW89_NA), + COUNTRY_REGD("LR", RTW89_ETSI, RTW89_ETSI, RTW89_NA), + 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_NA), + 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_NA), + 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_NA), + COUNTRY_REGD("YT", RTW89_ETSI, RTW89_ETSI, RTW89_NA), + COUNTRY_REGD("FM", RTW89_FCC, RTW89_FCC, RTW89_NA), + COUNTRY_REGD("MD", RTW89_ETSI, RTW89_ETSI, RTW89_NA), + COUNTRY_REGD("MN", RTW89_ETSI, RTW89_ETSI, RTW89_NA), + 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_NA), + COUNTRY_REGD("PW", RTW89_FCC, RTW89_FCC, RTW89_NA), + 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_NA), + COUNTRY_REGD("LC", RTW89_FCC, RTW89_FCC, RTW89_NA), + COUNTRY_REGD("MF", RTW89_FCC, RTW89_FCC, RTW89_NA), + COUNTRY_REGD("SX", RTW89_FCC, RTW89_FCC, RTW89_NA), + 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_FCC, RTW89_FCC, RTW89_NA), + COUNTRY_REGD("SC", RTW89_FCC, RTW89_FCC, RTW89_NA), + COUNTRY_REGD("SL", RTW89_ETSI, RTW89_ETSI, RTW89_NA), + 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_NA), + COUNTRY_REGD("SJ", RTW89_ETSI, RTW89_ETSI, RTW89_NA), + COUNTRY_REGD("SZ", RTW89_ETSI, RTW89_ETSI, RTW89_NA), + COUNTRY_REGD("TJ", RTW89_ETSI, RTW89_ETSI, RTW89_NA), + COUNTRY_REGD("TZ", RTW89_ETSI, RTW89_ETSI, RTW89_NA), + COUNTRY_REGD("TG", RTW89_ETSI, RTW89_ETSI, RTW89_NA), + 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_NA), + COUNTRY_REGD("UZ", RTW89_ETSI, RTW89_ETSI, RTW89_NA), + 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("IR", RTW89_ETSI, RTW89_ETSI, RTW89_NA), + COUNTRY_REGD("PS", RTW89_ETSI, RTW89_ETSI, RTW89_NA), }; static const struct rtw89_regulatory *rtw89_regd_find_reg_by_name(char *alpha2) From bed4045ffb9c7453d2b6627f5d29b27973f1f653 Mon Sep 17 00:00:00 2001 From: Johnson Lin Date: Fri, 18 Mar 2022 10:32:08 +0800 Subject: [PATCH 063/228] rtw89: packed IGI configuration flow into function for DIG feature Refinement of DIG flow, a mechanism to adjust Rx gain for better Rx performance, by packing IGI(initial gain index) configuration flow into one function. Signed-off-by: Johnson Lin Signed-off-by: Ping-Ke Shih Signed-off-by: Kalle Valo Link: https://lore.kernel.org/r/20220318023214.32411-6-pkshih@realtek.com --- drivers/net/wireless/realtek/rtw89/phy.c | 25 +++++++++++++++--------- 1 file changed, 16 insertions(+), 9 deletions(-) diff --git a/drivers/net/wireless/realtek/rtw89/phy.c b/drivers/net/wireless/realtek/rtw89/phy.c index c9a04ca0b1f21..c27148acfa048 100644 --- a/drivers/net/wireless/realtek/rtw89/phy.c +++ b/drivers/net/wireless/realtek/rtw89/phy.c @@ -3180,6 +3180,21 @@ static void rtw89_phy_dig_sdagc_follow_pagc_config(struct rtw89_dev *rtwdev, rtw89_debug(rtwdev, RTW89_DBG_DIG, "sdagc_follow_pagc=%d\n", enable); } +static void rtw89_phy_dig_config_igi(struct rtw89_dev *rtwdev) +{ + struct rtw89_dig_info *dig = &rtwdev->dig; + + if (dig->force_gaincode_idx_en) { + rtw89_phy_dig_set_igi_cr(rtwdev, 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, + &dig->cur_gaincode); + rtw89_phy_dig_set_igi_cr(rtwdev, dig->cur_gaincode); + } +} + static void rtw89_phy_dig_dyn_pd_th(struct rtw89_dev *rtwdev, u8 rssi, bool enable) { @@ -3294,15 +3309,7 @@ void rtw89_phy_dig(struct rtw89_dev *rtwdev) dig->igi_rssi, dig->dyn_igi_max, dig->dyn_igi_min, dig->igi_fa_rssi); - if (dig->force_gaincode_idx_en) { - rtw89_phy_dig_set_igi_cr(rtwdev, 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, - &dig->cur_gaincode); - rtw89_phy_dig_set_igi_cr(rtwdev, dig->cur_gaincode); - } + rtw89_phy_dig_config_igi(rtwdev); rtw89_phy_dig_dyn_pd_th(rtwdev, dig->igi_fa_rssi, dig->dyn_pd_th_en); From 1e6f0d2a677a6bd0f719158f9a1453ce7b11bb0c Mon Sep 17 00:00:00 2001 From: Johnson Lin Date: Fri, 18 Mar 2022 10:32:09 +0800 Subject: [PATCH 064/228] rtw89: disabled IGI configuration for unsupported hardware Bypass IGI, known as Rx gain, adjustment flow for incompatible hardware architectures. Signed-off-by: Johnson Lin Signed-off-by: Ping-Ke Shih Signed-off-by: Kalle Valo Link: https://lore.kernel.org/r/20220318023214.32411-7-pkshih@realtek.com --- drivers/net/wireless/realtek/rtw89/core.c | 2 ++ drivers/net/wireless/realtek/rtw89/core.h | 1 + drivers/net/wireless/realtek/rtw89/phy.c | 3 ++- 3 files changed, 5 insertions(+), 1 deletion(-) diff --git a/drivers/net/wireless/realtek/rtw89/core.c b/drivers/net/wireless/realtek/rtw89/core.c index c61061358980b..bce4834f18ec0 100644 --- a/drivers/net/wireless/realtek/rtw89/core.c +++ b/drivers/net/wireless/realtek/rtw89/core.c @@ -2752,6 +2752,8 @@ static void rtw89_core_setup_phycap(struct rtw89_dev *rtwdev) rtwdev->hal.support_cckpd = !(rtwdev->chip->chip_id == RTL8852A && rtwdev->hal.cv <= CHIP_CBV) && !(rtwdev->chip->chip_id == RTL8852B && rtwdev->hal.cv <= CHIP_CAV); + rtwdev->hal.support_igi = + rtwdev->chip->chip_id == RTL8852A && rtwdev->hal.cv <= CHIP_CBV; } static int rtw89_chip_efuse_info_setup(struct rtw89_dev *rtwdev) diff --git a/drivers/net/wireless/realtek/rtw89/core.h b/drivers/net/wireless/realtek/rtw89/core.h index 5900cbc0efd9e..725484be2b622 100644 --- a/drivers/net/wireless/realtek/rtw89/core.h +++ b/drivers/net/wireless/realtek/rtw89/core.h @@ -2489,6 +2489,7 @@ struct rtw89_hal { u8 tx_nss; u8 rx_nss; bool support_cckpd; + bool support_igi; }; #define RTW89_MAX_MAC_ID_NUM 128 diff --git a/drivers/net/wireless/realtek/rtw89/phy.c b/drivers/net/wireless/realtek/rtw89/phy.c index c27148acfa048..193afb1f53f5a 100644 --- a/drivers/net/wireless/realtek/rtw89/phy.c +++ b/drivers/net/wireless/realtek/rtw89/phy.c @@ -3309,7 +3309,8 @@ 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); + if (rtwdev->hal.support_igi) + rtw89_phy_dig_config_igi(rtwdev); rtw89_phy_dig_dyn_pd_th(rtwdev, dig->igi_fa_rssi, dig->dyn_pd_th_en); From a95bd62ec01df487b18f57eacc4c38d6d73a059a Mon Sep 17 00:00:00 2001 From: Ping-Ke Shih Date: Fri, 18 Mar 2022 10:32:10 +0800 Subject: [PATCH 065/228] rtw89: add chip_info::h2c_desc_size/fill_txdesc_fwcmd to support new chips 8852A and 8852C use different H2C header and size, so add h2c_desc_size to allocate different header size and fill content by fill_txdesc_fwcmd. Signed-off-by: Ping-Ke Shih Signed-off-by: Kalle Valo Link: https://lore.kernel.org/r/20220318023214.32411-8-pkshih@realtek.com --- drivers/net/wireless/realtek/rtw89/cam.c | 2 +- drivers/net/wireless/realtek/rtw89/core.c | 20 +++++ drivers/net/wireless/realtek/rtw89/core.h | 19 ++++ drivers/net/wireless/realtek/rtw89/fw.c | 74 ++++++++-------- drivers/net/wireless/realtek/rtw89/fw.h | 4 +- drivers/net/wireless/realtek/rtw89/pci.c | 10 ++- drivers/net/wireless/realtek/rtw89/rtw8852a.c | 2 + drivers/net/wireless/realtek/rtw89/rtw8852c.c | 2 + drivers/net/wireless/realtek/rtw89/txrx.h | 86 +++++++++++++++++++ 9 files changed, 176 insertions(+), 43 deletions(-) diff --git a/drivers/net/wireless/realtek/rtw89/cam.c b/drivers/net/wireless/realtek/rtw89/cam.c index 26bef9fdd2053..34df3c07c55c5 100644 --- a/drivers/net/wireless/realtek/rtw89/cam.c +++ b/drivers/net/wireless/realtek/rtw89/cam.c @@ -18,7 +18,7 @@ rtw89_cam_get_sec_key_cmd(struct rtw89_dev *rtwdev, u8 *cmd; int i, j; - skb = rtw89_fw_h2c_alloc_skb_with_hdr(cmd_len); + skb = rtw89_fw_h2c_alloc_skb_with_hdr(rtwdev, cmd_len); if (!skb) return NULL; diff --git a/drivers/net/wireless/realtek/rtw89/core.c b/drivers/net/wireless/realtek/rtw89/core.c index bce4834f18ec0..a5c13fd7d8a04 100644 --- a/drivers/net/wireless/realtek/rtw89/core.c +++ b/drivers/net/wireless/realtek/rtw89/core.c @@ -977,6 +977,26 @@ void rtw89_core_fill_txdesc(struct rtw89_dev *rtwdev, } EXPORT_SYMBOL(rtw89_core_fill_txdesc); +static __le32 rtw89_build_txwd_fwcmd0_v1(struct rtw89_tx_desc_info *desc_info) +{ + u32 dword = FIELD_PREP(AX_RXD_RPKT_LEN_MASK, desc_info->pkt_size) | + FIELD_PREP(AX_RXD_RPKT_TYPE_MASK, desc_info->fw_dl ? + RTW89_CORE_RX_TYPE_FWDL : + RTW89_CORE_RX_TYPE_H2C); + + return cpu_to_le32(dword); +} + +void rtw89_core_fill_txdesc_fwcmd_v1(struct rtw89_dev *rtwdev, + struct rtw89_tx_desc_info *desc_info, + void *txdesc) +{ + struct rtw89_rxdesc_short *txwd_v1 = (struct rtw89_rxdesc_short *)txdesc; + + txwd_v1->dword0 = rtw89_build_txwd_fwcmd0_v1(desc_info); +} +EXPORT_SYMBOL(rtw89_core_fill_txdesc_fwcmd_v1); + static int rtw89_core_rx_process_mac_ppdu(struct rtw89_dev *rtwdev, struct sk_buff *skb, struct rtw89_rx_phy_ppdu *phy_ppdu) diff --git a/drivers/net/wireless/realtek/rtw89/core.h b/drivers/net/wireless/realtek/rtw89/core.h index 725484be2b622..c17756ff54762 100644 --- a/drivers/net/wireless/realtek/rtw89/core.h +++ b/drivers/net/wireless/realtek/rtw89/core.h @@ -117,6 +117,8 @@ enum rtw89_core_rx_type { RTW89_CORE_RX_TYPE_C2H = 10, RTW89_CORE_RX_TYPE_CSI = 11, RTW89_CORE_RX_TYPE_CQI = 12, + RTW89_CORE_RX_TYPE_H2C = 13, + RTW89_CORE_RX_TYPE_FWDL = 14, }; enum rtw89_txq_flags { @@ -2076,6 +2078,9 @@ struct rtw89_chip_ops { s8 pw_ofst, enum rtw89_mac_idx mac_idx); int (*pwr_on_func)(struct rtw89_dev *rtwdev); int (*pwr_off_func)(struct rtw89_dev *rtwdev); + void (*fill_txdesc_fwcmd)(struct rtw89_dev *rtwdev, + struct rtw89_tx_desc_info *desc_info, + void *txdesc); int (*cfg_ctrl_path)(struct rtw89_dev *rtwdev, bool wl); int (*mac_cfg_gnt)(struct rtw89_dev *rtwdev, const struct rtw89_mac_ax_coex_gnt *gnt_cfg); @@ -2344,6 +2349,7 @@ struct rtw89_chip_info { u8 ps_mode_supported; u32 hci_func_en_addr; + u32 h2c_desc_size; u32 h2c_ctrl_reg; const u32 *h2c_regs; u32 c2h_ctrl_reg; @@ -3507,6 +3513,16 @@ static inline void rtw89_ctrl_btg(struct rtw89_dev *rtwdev, bool btg) chip->ops->ctrl_btg(rtwdev, btg); } +static inline +void rtw89_chip_fill_txdesc_fwcmd(struct rtw89_dev *rtwdev, + struct rtw89_tx_desc_info *desc_info, + void *txdesc) +{ + const struct rtw89_chip_info *chip = rtwdev->chip; + + chip->ops->fill_txdesc_fwcmd(rtwdev, desc_info, txdesc); +} + static inline void rtw89_chip_mac_cfg_gnt(struct rtw89_dev *rtwdev, const struct rtw89_mac_ax_coex_gnt *gnt_cfg) @@ -3580,6 +3596,9 @@ void rtw89_core_tx_kick_off(struct rtw89_dev *rtwdev, u8 qsel); void rtw89_core_fill_txdesc(struct rtw89_dev *rtwdev, struct rtw89_tx_desc_info *desc_info, void *txdesc); +void rtw89_core_fill_txdesc_fwcmd_v1(struct rtw89_dev *rtwdev, + struct rtw89_tx_desc_info *desc_info, + void *txdesc); void rtw89_core_rx(struct rtw89_dev *rtwdev, struct rtw89_rx_desc_info *desc_info, struct sk_buff *skb); diff --git a/drivers/net/wireless/realtek/rtw89/fw.c b/drivers/net/wireless/realtek/rtw89/fw.c index 2c9470616a1b2..5985b40950bc1 100644 --- a/drivers/net/wireless/realtek/rtw89/fw.c +++ b/drivers/net/wireless/realtek/rtw89/fw.c @@ -10,31 +10,33 @@ #include "phy.h" #include "reg.h" -static struct sk_buff *rtw89_fw_h2c_alloc_skb(u32 len, bool header) +static struct sk_buff *rtw89_fw_h2c_alloc_skb(struct rtw89_dev *rtwdev, u32 len, + bool header) { struct sk_buff *skb; u32 header_len = 0; + u32 h2c_desc_size = rtwdev->chip->h2c_desc_size; if (header) header_len = H2C_HEADER_LEN; - skb = dev_alloc_skb(len + header_len + 24); + skb = dev_alloc_skb(len + header_len + h2c_desc_size); if (!skb) return NULL; - skb_reserve(skb, header_len + 24); + skb_reserve(skb, header_len + h2c_desc_size); memset(skb->data, 0, len); return skb; } -struct sk_buff *rtw89_fw_h2c_alloc_skb_with_hdr(u32 len) +struct sk_buff *rtw89_fw_h2c_alloc_skb_with_hdr(struct rtw89_dev *rtwdev, u32 len) { - return rtw89_fw_h2c_alloc_skb(len, true); + return rtw89_fw_h2c_alloc_skb(rtwdev, len, true); } -struct sk_buff *rtw89_fw_h2c_alloc_skb_no_hdr(u32 len) +struct sk_buff *rtw89_fw_h2c_alloc_skb_no_hdr(struct rtw89_dev *rtwdev, u32 len) { - return rtw89_fw_h2c_alloc_skb(len, false); + return rtw89_fw_h2c_alloc_skb(rtwdev, len, false); } static u8 _fw_get_rdy(struct rtw89_dev *rtwdev) @@ -309,7 +311,7 @@ static int __rtw89_fw_download_hdr(struct rtw89_dev *rtwdev, const u8 *fw, u32 l struct sk_buff *skb; u32 ret = 0; - skb = rtw89_fw_h2c_alloc_skb_with_hdr(len); + skb = rtw89_fw_h2c_alloc_skb_with_hdr(rtwdev, len); if (!skb) { rtw89_err(rtwdev, "failed to alloc skb for fw hdr dl\n"); return -ENOMEM; @@ -375,7 +377,7 @@ static int __rtw89_fw_download_main(struct rtw89_dev *rtwdev, else pkt_len = residue_len; - skb = rtw89_fw_h2c_alloc_skb_no_hdr(pkt_len); + skb = rtw89_fw_h2c_alloc_skb_no_hdr(rtwdev, pkt_len); if (!skb) { rtw89_err(rtwdev, "failed to alloc skb for fw dl\n"); return -ENOMEM; @@ -570,7 +572,7 @@ int rtw89_fw_h2c_cam(struct rtw89_dev *rtwdev, struct rtw89_vif *rtwvif, { struct sk_buff *skb; - skb = rtw89_fw_h2c_alloc_skb_with_hdr(H2C_CAM_LEN); + skb = rtw89_fw_h2c_alloc_skb_with_hdr(rtwdev, H2C_CAM_LEN); if (!skb) { rtw89_err(rtwdev, "failed to alloc skb for fw dl\n"); return -ENOMEM; @@ -619,7 +621,7 @@ int rtw89_fw_h2c_ba_cam(struct rtw89_dev *rtwdev, struct rtw89_sta *rtwsta, return 0; } - skb = rtw89_fw_h2c_alloc_skb_with_hdr(H2C_BA_CAM_LEN); + skb = rtw89_fw_h2c_alloc_skb_with_hdr(rtwdev, H2C_BA_CAM_LEN); if (!skb) { rtw89_err(rtwdev, "failed to alloc skb for h2c ba cam\n"); return -ENOMEM; @@ -665,7 +667,7 @@ int rtw89_fw_h2c_fw_log(struct rtw89_dev *rtwdev, bool enable) u32 comp = enable ? BIT(RTW89_FW_LOG_COMP_INIT) | BIT(RTW89_FW_LOG_COMP_TASK) | BIT(RTW89_FW_LOG_COMP_PS) | BIT(RTW89_FW_LOG_COMP_ERROR) : 0; - skb = rtw89_fw_h2c_alloc_skb_with_hdr(H2C_LOG_CFG_LEN); + skb = rtw89_fw_h2c_alloc_skb_with_hdr(rtwdev, H2C_LOG_CFG_LEN); if (!skb) { rtw89_err(rtwdev, "failed to alloc skb for fw log cfg\n"); return -ENOMEM; @@ -701,7 +703,7 @@ int rtw89_fw_h2c_general_pkt(struct rtw89_dev *rtwdev, u8 macid) { struct sk_buff *skb; - skb = rtw89_fw_h2c_alloc_skb_with_hdr(H2C_GENERAL_PKT_LEN); + skb = rtw89_fw_h2c_alloc_skb_with_hdr(rtwdev, H2C_GENERAL_PKT_LEN); if (!skb) { rtw89_err(rtwdev, "failed to alloc skb for fw dl\n"); return -ENOMEM; @@ -738,7 +740,7 @@ int rtw89_fw_h2c_lps_parm(struct rtw89_dev *rtwdev, { struct sk_buff *skb; - skb = rtw89_fw_h2c_alloc_skb_with_hdr(H2C_LPS_PARM_LEN); + skb = rtw89_fw_h2c_alloc_skb_with_hdr(rtwdev, H2C_LPS_PARM_LEN); if (!skb) { rtw89_err(rtwdev, "failed to alloc skb for fw dl\n"); return -ENOMEM; @@ -784,7 +786,7 @@ int rtw89_fw_h2c_default_cmac_tbl(struct rtw89_dev *rtwdev, u8 map_b = hal->antenna_tx == RF_AB ? 1 : 0; u8 macid = rtwvif->mac_id; - skb = rtw89_fw_h2c_alloc_skb_with_hdr(H2C_CMC_TBL_LEN); + skb = rtw89_fw_h2c_alloc_skb_with_hdr(rtwdev, H2C_CMC_TBL_LEN); if (!skb) { rtw89_err(rtwdev, "failed to alloc skb for fw dl\n"); return -ENOMEM; @@ -894,7 +896,7 @@ int rtw89_fw_h2c_assoc_cmac_tbl(struct rtw89_dev *rtwdev, if (sta) __get_sta_he_pkt_padding(rtwdev, sta, pads); - skb = rtw89_fw_h2c_alloc_skb_with_hdr(H2C_CMC_TBL_LEN); + skb = rtw89_fw_h2c_alloc_skb_with_hdr(rtwdev, H2C_CMC_TBL_LEN); if (!skb) { rtw89_err(rtwdev, "failed to alloc skb for fw dl\n"); return -ENOMEM; @@ -945,7 +947,7 @@ int rtw89_fw_h2c_txtime_cmac_tbl(struct rtw89_dev *rtwdev, { struct sk_buff *skb; - skb = rtw89_fw_h2c_alloc_skb_with_hdr(H2C_CMC_TBL_LEN); + skb = rtw89_fw_h2c_alloc_skb_with_hdr(rtwdev, H2C_CMC_TBL_LEN); if (!skb) { rtw89_err(rtwdev, "failed to alloc skb for fw dl\n"); return -ENOMEM; @@ -997,7 +999,7 @@ int rtw89_fw_h2c_update_beacon(struct rtw89_dev *rtwdev, } bcn_total_len = H2C_BCN_BASE_LEN + skb_beacon->len; - skb = rtw89_fw_h2c_alloc_skb_with_hdr(bcn_total_len); + skb = rtw89_fw_h2c_alloc_skb_with_hdr(rtwdev, bcn_total_len); if (!skb) { rtw89_err(rtwdev, "failed to alloc skb for fw dl\n"); dev_kfree_skb_any(skb_beacon); @@ -1051,7 +1053,7 @@ int rtw89_fw_h2c_role_maintain(struct rtw89_dev *rtwdev, self_role = rtwvif->self_role; } - skb = rtw89_fw_h2c_alloc_skb_with_hdr(H2C_ROLE_MAINTAIN_LEN); + skb = rtw89_fw_h2c_alloc_skb_with_hdr(rtwdev, H2C_ROLE_MAINTAIN_LEN); if (!skb) { rtw89_err(rtwdev, "failed to alloc skb for h2c join\n"); return -ENOMEM; @@ -1093,7 +1095,7 @@ int rtw89_fw_h2c_join_info(struct rtw89_dev *rtwdev, struct rtw89_vif *rtwvif, net_type = dis_conn ? RTW89_NET_TYPE_NO_LINK : net_type; } - skb = rtw89_fw_h2c_alloc_skb_with_hdr(H2C_JOIN_INFO_LEN); + skb = rtw89_fw_h2c_alloc_skb_with_hdr(rtwdev, H2C_JOIN_INFO_LEN); if (!skb) { rtw89_err(rtwdev, "failed to alloc skb for h2c join\n"); return -ENOMEM; @@ -1137,7 +1139,7 @@ int rtw89_fw_h2c_macid_pause(struct rtw89_dev *rtwdev, u8 sh, u8 grp, u8 len = sizeof(struct rtw89_fw_macid_pause_grp); struct sk_buff *skb; - skb = rtw89_fw_h2c_alloc_skb_with_hdr(H2C_JOIN_INFO_LEN); + skb = rtw89_fw_h2c_alloc_skb_with_hdr(rtwdev, H2C_JOIN_INFO_LEN); if (!skb) { rtw89_err(rtwdev, "failed to alloc skb for h2c join\n"); return -ENOMEM; @@ -1170,7 +1172,7 @@ int rtw89_fw_h2c_set_edca(struct rtw89_dev *rtwdev, struct rtw89_vif *rtwvif, { struct sk_buff *skb; - skb = rtw89_fw_h2c_alloc_skb_with_hdr(H2C_EDCA_LEN); + skb = rtw89_fw_h2c_alloc_skb_with_hdr(rtwdev, H2C_EDCA_LEN); if (!skb) { rtw89_err(rtwdev, "failed to alloc skb for h2c edca\n"); return -ENOMEM; @@ -1205,7 +1207,7 @@ int rtw89_fw_h2c_set_ofld_cfg(struct rtw89_dev *rtwdev) static const u8 cfg[] = {0x09, 0x00, 0x00, 0x00, 0x5e, 0x00, 0x00, 0x00}; struct sk_buff *skb; - skb = rtw89_fw_h2c_alloc_skb_with_hdr(H2C_OFLD_CFG_LEN); + skb = rtw89_fw_h2c_alloc_skb_with_hdr(rtwdev, H2C_OFLD_CFG_LEN); if (!skb) { rtw89_err(rtwdev, "failed to alloc skb for h2c ofld\n"); return -ENOMEM; @@ -1235,7 +1237,7 @@ int rtw89_fw_h2c_ra(struct rtw89_dev *rtwdev, struct rtw89_ra_info *ra, bool csi struct sk_buff *skb; u8 *cmd; - skb = rtw89_fw_h2c_alloc_skb_with_hdr(H2C_RA_LEN); + skb = rtw89_fw_h2c_alloc_skb_with_hdr(rtwdev, H2C_RA_LEN); if (!skb) { rtw89_err(rtwdev, "failed to alloc skb for h2c join\n"); return -ENOMEM; @@ -1306,7 +1308,7 @@ int rtw89_fw_h2c_cxdrv_init(struct rtw89_dev *rtwdev) struct sk_buff *skb; u8 *cmd; - skb = rtw89_fw_h2c_alloc_skb_with_hdr(H2C_LEN_CXDRVINFO_INIT); + skb = rtw89_fw_h2c_alloc_skb_with_hdr(rtwdev, H2C_LEN_CXDRVINFO_INIT); if (!skb) { rtw89_err(rtwdev, "failed to alloc skb for h2c cxdrv_init\n"); return -ENOMEM; @@ -1365,7 +1367,7 @@ int rtw89_fw_h2c_cxdrv_role(struct rtw89_dev *rtwdev) u8 *cmd; int i; - skb = rtw89_fw_h2c_alloc_skb_with_hdr(H2C_LEN_CXDRVINFO_ROLE); + skb = rtw89_fw_h2c_alloc_skb_with_hdr(rtwdev, H2C_LEN_CXDRVINFO_ROLE); if (!skb) { rtw89_err(rtwdev, "failed to alloc skb for h2c cxdrv_role\n"); return -ENOMEM; @@ -1433,7 +1435,7 @@ int rtw89_fw_h2c_cxdrv_ctrl(struct rtw89_dev *rtwdev) struct sk_buff *skb; u8 *cmd; - skb = rtw89_fw_h2c_alloc_skb_with_hdr(H2C_LEN_CXDRVINFO_CTRL); + skb = rtw89_fw_h2c_alloc_skb_with_hdr(rtwdev, H2C_LEN_CXDRVINFO_CTRL); if (!skb) { rtw89_err(rtwdev, "failed to alloc skb for h2c cxdrv_ctrl\n"); return -ENOMEM; @@ -1475,7 +1477,7 @@ int rtw89_fw_h2c_cxdrv_rfk(struct rtw89_dev *rtwdev) struct sk_buff *skb; u8 *cmd; - skb = rtw89_fw_h2c_alloc_skb_with_hdr(H2C_LEN_CXDRVINFO_RFK); + skb = rtw89_fw_h2c_alloc_skb_with_hdr(rtwdev, H2C_LEN_CXDRVINFO_RFK); if (!skb) { rtw89_err(rtwdev, "failed to alloc skb for h2c cxdrv_ctrl\n"); return -ENOMEM; @@ -1515,7 +1517,7 @@ int rtw89_fw_h2c_del_pkt_offload(struct rtw89_dev *rtwdev, u8 id) struct sk_buff *skb; u8 *cmd; - skb = rtw89_fw_h2c_alloc_skb_with_hdr(H2C_LEN_PKT_OFLD); + skb = rtw89_fw_h2c_alloc_skb_with_hdr(rtwdev, H2C_LEN_PKT_OFLD); if (!skb) { rtw89_err(rtwdev, "failed to alloc skb for h2c pkt offload\n"); return -ENOMEM; @@ -1557,7 +1559,7 @@ int rtw89_fw_h2c_add_pkt_offload(struct rtw89_dev *rtwdev, u8 *id, *id = alloc_id; - skb = rtw89_fw_h2c_alloc_skb_with_hdr(H2C_LEN_PKT_OFLD + skb_ofld->len); + skb = rtw89_fw_h2c_alloc_skb_with_hdr(rtwdev, H2C_LEN_PKT_OFLD + skb_ofld->len); if (!skb) { rtw89_err(rtwdev, "failed to alloc skb for h2c pkt offload\n"); return -ENOMEM; @@ -1596,7 +1598,7 @@ int rtw89_fw_h2c_scan_list_offload(struct rtw89_dev *rtwdev, int len, int skb_len = H2C_LEN_SCAN_LIST_OFFLOAD + len * RTW89_MAC_CHINFO_SIZE; u8 *cmd; - skb = rtw89_fw_h2c_alloc_skb_with_hdr(skb_len); + skb = rtw89_fw_h2c_alloc_skb_with_hdr(rtwdev, skb_len); if (!skb) { rtw89_err(rtwdev, "failed to alloc skb for h2c scan list\n"); return -ENOMEM; @@ -1660,7 +1662,7 @@ int rtw89_fw_h2c_scan_offload(struct rtw89_dev *rtwdev, struct sk_buff *skb; u8 *cmd; - skb = rtw89_fw_h2c_alloc_skb_with_hdr(H2C_LEN_SCAN_OFFLOAD); + skb = rtw89_fw_h2c_alloc_skb_with_hdr(rtwdev, H2C_LEN_SCAN_OFFLOAD); if (!skb) { rtw89_err(rtwdev, "failed to alloc skb for h2c scan offload\n"); return -ENOMEM; @@ -1709,7 +1711,7 @@ int rtw89_fw_h2c_rf_reg(struct rtw89_dev *rtwdev, u8 class = info->rf_path == RF_PATH_A ? H2C_CL_OUTSRC_RF_REG_A : H2C_CL_OUTSRC_RF_REG_B; - skb = rtw89_fw_h2c_alloc_skb_with_hdr(len); + skb = rtw89_fw_h2c_alloc_skb_with_hdr(rtwdev, len); if (!skb) { rtw89_err(rtwdev, "failed to alloc skb for h2c rf reg\n"); return -ENOMEM; @@ -1738,7 +1740,7 @@ int rtw89_fw_h2c_raw_with_hdr(struct rtw89_dev *rtwdev, { struct sk_buff *skb; - skb = rtw89_fw_h2c_alloc_skb_with_hdr(len); + skb = rtw89_fw_h2c_alloc_skb_with_hdr(rtwdev, len); if (!skb) { rtw89_err(rtwdev, "failed to alloc skb for raw with hdr\n"); return -ENOMEM; @@ -1765,7 +1767,7 @@ int rtw89_fw_h2c_raw(struct rtw89_dev *rtwdev, const u8 *buf, u16 len) { struct sk_buff *skb; - skb = rtw89_fw_h2c_alloc_skb_no_hdr(len); + skb = rtw89_fw_h2c_alloc_skb_no_hdr(rtwdev, len); if (!skb) { rtw89_err(rtwdev, "failed to alloc skb for h2c raw\n"); return -ENOMEM; @@ -2295,7 +2297,7 @@ int rtw89_fw_h2c_trigger_cpu_exception(struct rtw89_dev *rtwdev) { struct sk_buff *skb; - skb = rtw89_fw_h2c_alloc_skb_with_hdr(H2C_FW_CPU_EXCEPTION_LEN); + skb = rtw89_fw_h2c_alloc_skb_with_hdr(rtwdev, H2C_FW_CPU_EXCEPTION_LEN); if (!skb) { rtw89_err(rtwdev, "failed to alloc skb for fw cpu exception\n"); diff --git a/drivers/net/wireless/realtek/rtw89/fw.h b/drivers/net/wireless/realtek/rtw89/fw.h index 24ab249a8ecec..2a010154a8e88 100644 --- a/drivers/net/wireless/realtek/rtw89/fw.h +++ b/drivers/net/wireless/realtek/rtw89/fw.h @@ -2277,8 +2277,8 @@ int rtw89_fw_h2c_ba_cam(struct rtw89_dev *rtwdev, struct rtw89_sta *rtwsta, int rtw89_fw_h2c_lps_parm(struct rtw89_dev *rtwdev, struct rtw89_lps_parm *lps_param); -struct sk_buff *rtw89_fw_h2c_alloc_skb_with_hdr(u32 len); -struct sk_buff *rtw89_fw_h2c_alloc_skb_no_hdr(u32 len); +struct sk_buff *rtw89_fw_h2c_alloc_skb_with_hdr(struct rtw89_dev *rtwdev, u32 len); +struct sk_buff *rtw89_fw_h2c_alloc_skb_no_hdr(struct rtw89_dev *rtwdev, u32 len); int rtw89_fw_msg_reg(struct rtw89_dev *rtwdev, struct rtw89_mac_h2c_info *h2c_info, struct rtw89_mac_c2h_info *c2h_info); diff --git a/drivers/net/wireless/realtek/rtw89/pci.c b/drivers/net/wireless/realtek/rtw89/pci.c index 32e8283e22f3b..9335fba28fc1e 100644 --- a/drivers/net/wireless/realtek/rtw89/pci.c +++ b/drivers/net/wireless/realtek/rtw89/pci.c @@ -1043,16 +1043,18 @@ static int rtw89_pci_fwcmd_submit(struct rtw89_dev *rtwdev, struct rtw89_core_tx_request *tx_req) { struct rtw89_pci *rtwpci = (struct rtw89_pci *)rtwdev->priv; + const struct rtw89_chip_info *chip = rtwdev->chip; struct rtw89_tx_desc_info *desc_info = &tx_req->desc_info; - struct rtw89_txwd_body *txwd_body; + void *txdesc; + int txdesc_size = chip->h2c_desc_size; struct pci_dev *pdev = rtwpci->pdev; struct sk_buff *skb = tx_req->skb; struct rtw89_pci_tx_data *tx_data = RTW89_PCI_TX_SKB_CB(skb); dma_addr_t dma; - txwd_body = (struct rtw89_txwd_body *)skb_push(skb, sizeof(*txwd_body)); - memset(txwd_body, 0, sizeof(*txwd_body)); - rtw89_core_fill_txdesc(rtwdev, desc_info, txwd_body); + txdesc = skb_push(skb, txdesc_size); + memset(txdesc, 0, txdesc_size); + rtw89_chip_fill_txdesc_fwcmd(rtwdev, desc_info, txdesc); dma = dma_map_single(&pdev->dev, skb->data, skb->len, DMA_TO_DEVICE); if (dma_mapping_error(&pdev->dev, dma)) { diff --git a/drivers/net/wireless/realtek/rtw89/rtw8852a.c b/drivers/net/wireless/realtek/rtw89/rtw8852a.c index 67aaa05cb7511..6aa3d19a74644 100644 --- a/drivers/net/wireless/realtek/rtw89/rtw8852a.c +++ b/drivers/net/wireless/realtek/rtw89/rtw8852a.c @@ -2021,6 +2021,7 @@ static const struct rtw89_chip_ops rtw8852a_chip_ops = { .set_txpwr_ul_tb_offset = rtw8852a_set_txpwr_ul_tb_offset, .pwr_on_func = NULL, .pwr_off_func = NULL, + .fill_txdesc_fwcmd = rtw89_core_fill_txdesc, .cfg_ctrl_path = rtw89_mac_cfg_ctrl_path, .mac_cfg_gnt = rtw89_mac_cfg_gnt, .stop_sch_tx = rtw89_mac_stop_sch_tx, @@ -2097,6 +2098,7 @@ const struct rtw89_chip_info rtw8852a_chip_info = { BIT(RTW89_PS_MODE_CLK_GATED) | BIT(RTW89_PS_MODE_PWR_GATED), .hci_func_en_addr = R_AX_HCI_FUNC_EN, + .h2c_desc_size = sizeof(struct rtw89_txwd_body), .h2c_ctrl_reg = R_AX_H2CREG_CTRL, .h2c_regs = rtw8852a_h2c_regs, .c2h_ctrl_reg = R_AX_C2HREG_CTRL, diff --git a/drivers/net/wireless/realtek/rtw89/rtw8852c.c b/drivers/net/wireless/realtek/rtw89/rtw8852c.c index 123cc3c4318d2..08a9c01a359e0 100644 --- a/drivers/net/wireless/realtek/rtw89/rtw8852c.c +++ b/drivers/net/wireless/realtek/rtw89/rtw8852c.c @@ -492,6 +492,7 @@ static const struct rtw89_chip_ops rtw8852c_chip_ops = { .set_txpwr_ul_tb_offset = rtw8852c_set_txpwr_ul_tb_offset, .pwr_on_func = rtw8852c_pwr_on_func, .pwr_off_func = rtw8852c_pwr_off_func, + .fill_txdesc_fwcmd = rtw89_core_fill_txdesc_fwcmd_v1, .cfg_ctrl_path = rtw89_mac_cfg_ctrl_path_v1, .mac_cfg_gnt = rtw89_mac_cfg_gnt_v1, .stop_sch_tx = rtw89_mac_stop_sch_tx_v1, @@ -515,6 +516,7 @@ const struct rtw89_chip_info rtw8852c_chip_info = { .phycap_addr = 0x590, .phycap_size = 0x60, .hci_func_en_addr = R_AX_HCI_FUNC_EN_V1, + .h2c_desc_size = sizeof(struct rtw89_rxdesc_short), .h2c_ctrl_reg = R_AX_H2CREG_CTRL_V1, .h2c_regs = rtw8852c_h2c_regs, .c2h_ctrl_reg = R_AX_C2HREG_CTRL_V1, diff --git a/drivers/net/wireless/realtek/rtw89/txrx.h b/drivers/net/wireless/realtek/rtw89/txrx.h index 86e3d8b400d6c..4e81d6df93688 100644 --- a/drivers/net/wireless/realtek/rtw89/txrx.h +++ b/drivers/net/wireless/realtek/rtw89/txrx.h @@ -79,6 +79,92 @@ /* TX WD INFO DWORD 5 */ +/* RX WD dword0 */ +#define AX_RXD_RPKT_LEN_MASK GENMASK(13, 0) +#define AX_RXD_SHIFT_MASK GENMASK(15, 14) +#define AX_RXD_WL_HD_IV_LEN_MASK GENMASK(21, 16) +#define AX_RXD_BB_SEL BIT(22) +#define AX_RXD_MAC_INFO_VLD BIT(23) +#define AX_RXD_RPKT_TYPE_MASK GENMASK(27, 24) +#define AX_RXD_DRV_INFO_SIZE_MASK GENMASK(30, 28) +#define AX_RXD_LONG_RXD BIT(31) + +/* RX WD dword1 */ +#define AX_RXD_PPDU_TYPE_MASK GENMASK(3, 0) +#define AX_RXD_PPDU_CNT_MASK GENMASK(6, 4) +#define AX_RXD_SR_EN BIT(7) +#define AX_RXD_USER_ID_MASK GENMASK(15, 8) +#define AX_RXD_USER_ID_v1_MASK GENMASK(13, 8) +#define AX_RXD_RX_DATARATE_MASK GENMASK(24, 16) +#define AX_RXD_RX_GI_LTF_MASK GENMASK(27, 25) +#define AX_RXD_NON_SRG_PPDU BIT(28) +#define AX_RXD_INTER_PPDU BIT(29) +#define AX_RXD_NON_SRG_PPDU_v1 BIT(14) +#define AX_RXD_INTER_PPDU_v1 BIT(15) +#define AX_RXD_BW_MASK GENMASK(31, 30) +#define AX_RXD_BW_v1_MASK GENMASK(31, 29) + +/* RX WD dword2 */ +#define AX_RXD_FREERUN_CNT_MASK GENMASK(31, 0) + +/* RX WD dword3 */ +#define AX_RXD_A1_MATCH BIT(0) +#define AX_RXD_SW_DEC BIT(1) +#define AX_RXD_HW_DEC BIT(2) +#define AX_RXD_AMPDU BIT(3) +#define AX_RXD_AMPDU_END_PKT BIT(4) +#define AX_RXD_AMSDU BIT(5) +#define AX_RXD_AMSDU_CUT BIT(6) +#define AX_RXD_LAST_MSDU BIT(7) +#define AX_RXD_BYPASS BIT(8) +#define AX_RXD_CRC32_ERR BIT(9) +#define AX_RXD_ICV_ERR BIT(10) +#define AX_RXD_MAGIC_WAKE BIT(11) +#define AX_RXD_UNICAST_WAKE BIT(12) +#define AX_RXD_PATTERN_WAKE BIT(13) +#define AX_RXD_GET_CH_INFO_MASK GENMASK(15, 14) +#define AX_RXD_PATTERN_IDX_MASK GENMASK(20, 16) +#define AX_RXD_TARGET_IDC_MASK GENMASK(23, 21) +#define AX_RXD_CHKSUM_OFFLOAD_EN BIT(24) +#define AX_RXD_WITH_LLC BIT(25) +#define AX_RXD_RX_STATISTICS BIT(26) + +/* RX WD dword4 */ +#define AX_RXD_TYPE_MASK GENMASK(1, 0) +#define AX_RXD_MC BIT(2) +#define AX_RXD_BC BIT(3) +#define AX_RXD_MD BIT(4) +#define AX_RXD_MF BIT(5) +#define AX_RXD_PWR BIT(6) +#define AX_RXD_QOS BIT(7) +#define AX_RXD_TID_MASK GENMASK(11, 8) +#define AX_RXD_EOSP BIT(12) +#define AX_RXD_HTC BIT(13) +#define AX_RXD_QNULL BIT(14) +#define AX_RXD_SEQ_MASK GENMASK(27, 16) +#define AX_RXD_FRAG_MASK GENMASK(31, 28) + +/* RX WD dword5 */ +#define AX_RXD_SEC_CAM_IDX_MASK GENMASK(7, 0) +#define AX_RXD_ADDR_CAM_MASK GENMASK(15, 8) +#define AX_RXD_MAC_ID_MASK GENMASK(23, 16) +#define AX_RXD_RX_PL_ID_MASK GENMASK(27, 24) +#define AX_RXD_ADDR_CAM_VLD BIT(28) +#define AX_RXD_ADDR_FWD_EN BIT(29) +#define AX_RXD_RX_PL_MATCH BIT(30) + +/* RX WD dword6 */ +#define AX_RXD_MAC_ADDR_MASK GENMASK(31, 0) + +/* RX WD dword7 */ +#define AX_RXD_MAC_ADDR_H_MASK GENMASK(15, 0) +#define AX_RXD_SMART_ANT BIT(16) +#define AX_RXD_SEC_TYPE_MASK GENMASK(20, 17) +#define AX_RXD_HDR_CNV BIT(21) +#define AX_RXD_HDR_OFFSET_MASK GENMASK(26, 22) +#define AX_RXD_BIP_KEYID BIT(27) +#define AX_RXD_BIP_ENC BIT(28) + /* RX DESC helpers */ /* Short Descriptor */ #define RTW89_GET_RXWD_LONG_RXD(rxdesc) \ From 6d5b5d6290ece7fd3652546ebc1ba98236327b5f Mon Sep 17 00:00:00 2001 From: Ping-Ke Shih Date: Fri, 18 Mar 2022 10:32:11 +0800 Subject: [PATCH 066/228] rtw89: pci: support variant of fill_txaddr_info The txaddr_info is used to fill the DMA address of skb->data. The v1 version can support up to 10 entries, but the maximum size of each entry is 2047, so it fill more than one entry for large packet, like 3000 bytes. Signed-off-by: Ping-Ke Shih Signed-off-by: Kalle Valo Link: https://lore.kernel.org/r/20220318023214.32411-9-pkshih@realtek.com --- drivers/net/wireless/realtek/rtw89/core.h | 1 + drivers/net/wireless/realtek/rtw89/pci.c | 64 +++++++++++++++++-- drivers/net/wireless/realtek/rtw89/pci.h | 33 ++++++++++ .../net/wireless/realtek/rtw89/rtw8852ae.c | 2 + .../net/wireless/realtek/rtw89/rtw8852ce.c | 2 + 5 files changed, 95 insertions(+), 7 deletions(-) diff --git a/drivers/net/wireless/realtek/rtw89/core.h b/drivers/net/wireless/realtek/rtw89/core.h index c17756ff54762..501381bb74adf 100644 --- a/drivers/net/wireless/realtek/rtw89/core.h +++ b/drivers/net/wireless/realtek/rtw89/core.h @@ -721,6 +721,7 @@ struct rtw89_tx_desc_info { u8 ampdu_density; u8 ampdu_num; bool sec_en; + u8 addr_info_nr; u8 sec_type; u8 sec_cam_idx; u16 data_rate; diff --git a/drivers/net/wireless/realtek/rtw89/pci.c b/drivers/net/wireless/realtek/rtw89/pci.c index 9335fba28fc1e..48a5feaf27222 100644 --- a/drivers/net/wireless/realtek/rtw89/pci.c +++ b/drivers/net/wireless/realtek/rtw89/pci.c @@ -977,6 +977,58 @@ static void rtw89_pci_ops_flush_queues(struct rtw89_dev *rtwdev, u32 queues, __rtw89_pci_ops_flush_txchs(rtwdev, BIT(RTW89_TXCH_NUM) - 1, drop); } +u32 rtw89_pci_fill_txaddr_info(struct rtw89_dev *rtwdev, + void *txaddr_info_addr, u32 total_len, + dma_addr_t dma, u8 *add_info_nr) +{ + struct rtw89_pci_tx_addr_info_32 *txaddr_info = txaddr_info_addr; + + txaddr_info->length = cpu_to_le16(total_len); + txaddr_info->option = cpu_to_le16(RTW89_PCI_ADDR_MSDU_LS | + RTW89_PCI_ADDR_NUM(1)); + txaddr_info->dma = cpu_to_le32(dma); + + *add_info_nr = 1; + + return sizeof(*txaddr_info); +} +EXPORT_SYMBOL(rtw89_pci_fill_txaddr_info); + +u32 rtw89_pci_fill_txaddr_info_v1(struct rtw89_dev *rtwdev, + void *txaddr_info_addr, u32 total_len, + dma_addr_t dma, u8 *add_info_nr) +{ + struct rtw89_pci_tx_addr_info_32_v1 *txaddr_info = txaddr_info_addr; + u32 remain = total_len; + u32 len; + u16 length_option; + int n; + + for (n = 0; n < RTW89_TXADDR_INFO_NR_V1 && remain; n++) { + len = remain >= TXADDR_INFO_LENTHG_V1_MAX ? + TXADDR_INFO_LENTHG_V1_MAX : remain; + remain -= len; + + length_option = FIELD_PREP(B_PCIADDR_LEN_V1_MASK, len) | + FIELD_PREP(B_PCIADDR_HIGH_SEL_V1_MASK, 0) | + FIELD_PREP(B_PCIADDR_LS_V1_MASK, remain == 0); + txaddr_info->length_opt = cpu_to_le16(length_option); + txaddr_info->dma_low_lsb = cpu_to_le16(FIELD_GET(GENMASK(15, 0), dma)); + txaddr_info->dma_low_msb = cpu_to_le16(FIELD_GET(GENMASK(31, 16), dma)); + + dma += len; + txaddr_info++; + } + + WARN_ONCE(remain, "length overflow remain=%u total_len=%u", + remain, total_len); + + *add_info_nr = n; + + return n * sizeof(*txaddr_info); +} +EXPORT_SYMBOL(rtw89_pci_fill_txaddr_info_v1); + static int rtw89_pci_txwd_submit(struct rtw89_dev *rtwdev, struct rtw89_pci_tx_ring *tx_ring, struct rtw89_pci_tx_wd *txwd, @@ -987,7 +1039,7 @@ static int rtw89_pci_txwd_submit(struct rtw89_dev *rtwdev, struct rtw89_txwd_body *txwd_body; struct rtw89_txwd_info *txwd_info; struct rtw89_pci_tx_wp_info *txwp_info; - struct rtw89_pci_tx_addr_info_32 *txaddr_info; + void *txaddr_info_addr; struct pci_dev *pdev = rtwpci->pdev; struct sk_buff *skb = tx_req->skb; struct rtw89_pci_tx_data *tx_data = RTW89_PCI_TX_SKB_CB(skb); @@ -1009,7 +1061,6 @@ static int rtw89_pci_txwd_submit(struct rtw89_dev *rtwdev, tx_data->dma = dma; - txaddr_info_len = sizeof(*txaddr_info); txwp_len = sizeof(*txwp_info); txwd_len = sizeof(*txwd_body); txwd_len += en_wd_info ? sizeof(*txwd_info) : 0; @@ -1021,11 +1072,10 @@ static int rtw89_pci_txwd_submit(struct rtw89_dev *rtwdev, txwp_info->seq3 = 0; tx_ring->tx_cnt++; - txaddr_info = txwd->vaddr + txwd_len + txwp_len; - txaddr_info->length = cpu_to_le16(skb->len); - txaddr_info->option = cpu_to_le16(RTW89_PCI_ADDR_MSDU_LS | - RTW89_PCI_ADDR_NUM(1)); - txaddr_info->dma = cpu_to_le32(dma); + txaddr_info_addr = txwd->vaddr + txwd_len + txwp_len; + txaddr_info_len = + rtw89_chip_fill_txaddr_info(rtwdev, txaddr_info_addr, skb->len, + dma, &desc_info->addr_info_nr); txwd->len = txwd_len + txwp_len + txaddr_info_len; diff --git a/drivers/net/wireless/realtek/rtw89/pci.h b/drivers/net/wireless/realtek/rtw89/pci.h index 2c8030af3e72f..a67595b211853 100644 --- a/drivers/net/wireless/realtek/rtw89/pci.h +++ b/drivers/net/wireless/realtek/rtw89/pci.h @@ -448,6 +448,10 @@ struct rtw89_pci_ch_dma_addr_set { struct rtw89_pci_info { const struct rtw89_pci_ch_dma_addr_set *dma_addr_set; + + u32 (*fill_txaddr_info)(struct rtw89_dev *rtwdev, + void *txaddr_info_addr, u32 total_len, + dma_addr_t dma, u8 *add_info_nr); }; struct rtw89_pci_bd_ram { @@ -493,6 +497,18 @@ struct rtw89_pci_tx_addr_info_32 { __le32 dma; } __packed; +#define RTW89_TXADDR_INFO_NR_V1 10 + +struct rtw89_pci_tx_addr_info_32_v1 { + __le16 length_opt; +#define B_PCIADDR_LEN_V1_MASK GENMASK(10, 0) +#define B_PCIADDR_HIGH_SEL_V1_MASK GENMASK(14, 11) +#define B_PCIADDR_LS_V1_MASK BIT(15) +#define TXADDR_INFO_LENTHG_V1_MAX ALIGN_DOWN(BIT(11) - 1, 4) + __le16 dma_low_lsb; + __le16 dma_low_msb; +} __packed; + #define RTW89_PCI_RPP_POLLUTED BIT(31) #define RTW89_PCI_RPP_SEQ GENMASK(30, 16) #define RTW89_PCI_RPP_TX_STATUS GENMASK(15, 13) @@ -698,5 +714,22 @@ struct pci_device_id; int rtw89_pci_probe(struct pci_dev *pdev, const struct pci_device_id *id); void rtw89_pci_remove(struct pci_dev *pdev); +u32 rtw89_pci_fill_txaddr_info(struct rtw89_dev *rtwdev, + void *txaddr_info_addr, u32 total_len, + dma_addr_t dma, u8 *add_info_nr); +u32 rtw89_pci_fill_txaddr_info_v1(struct rtw89_dev *rtwdev, + void *txaddr_info_addr, u32 total_len, + dma_addr_t dma, u8 *add_info_nr); + +static inline +u32 rtw89_chip_fill_txaddr_info(struct rtw89_dev *rtwdev, + void *txaddr_info_addr, u32 total_len, + dma_addr_t dma, u8 *add_info_nr) +{ + const struct rtw89_pci_info *info = rtwdev->pci_info; + + return info->fill_txaddr_info(rtwdev, txaddr_info_addr, total_len, + dma, add_info_nr); +} #endif diff --git a/drivers/net/wireless/realtek/rtw89/rtw8852ae.c b/drivers/net/wireless/realtek/rtw89/rtw8852ae.c index 48459aba441df..8ffc0dd90d41c 100644 --- a/drivers/net/wireless/realtek/rtw89/rtw8852ae.c +++ b/drivers/net/wireless/realtek/rtw89/rtw8852ae.c @@ -10,6 +10,8 @@ static const struct rtw89_pci_info rtw8852a_pci_info = { .dma_addr_set = &rtw89_pci_ch_dma_addr_set, + + .fill_txaddr_info = rtw89_pci_fill_txaddr_info, }; static const struct rtw89_driver_info rtw89_8852ae_info = { diff --git a/drivers/net/wireless/realtek/rtw89/rtw8852ce.c b/drivers/net/wireless/realtek/rtw89/rtw8852ce.c index e71370585b4da..09794836d5c0f 100644 --- a/drivers/net/wireless/realtek/rtw89/rtw8852ce.c +++ b/drivers/net/wireless/realtek/rtw89/rtw8852ce.c @@ -11,6 +11,8 @@ static const struct rtw89_pci_info rtw8852c_pci_info = { .dma_addr_set = &rtw89_pci_ch_dma_addr_set_v1, + + .fill_txaddr_info = rtw89_pci_fill_txaddr_info_v1, }; static const struct rtw89_driver_info rtw89_8852ce_info = { From f59acdde5197f3ea96ebf3d6bd95741d210dab9b Mon Sep 17 00:00:00 2001 From: Ping-Ke Shih Date: Fri, 18 Mar 2022 10:32:12 +0800 Subject: [PATCH 067/228] rtw89: support variant of fill_txdesc The txdesc is descriptor related to skb->data. The v1 version contains 8 dwords txwd_body and 6 dwords txwd_info, and the format is also different from original one. Signed-off-by: Ping-Ke Shih Signed-off-by: Kalle Valo Link: https://lore.kernel.org/r/20220318023214.32411-10-pkshih@realtek.com --- drivers/net/wireless/realtek/rtw89/core.c | 68 +++++++++++++++++++ drivers/net/wireless/realtek/rtw89/core.h | 28 ++++++++ drivers/net/wireless/realtek/rtw89/pci.c | 8 +-- drivers/net/wireless/realtek/rtw89/rtw8852a.c | 2 + drivers/net/wireless/realtek/rtw89/rtw8852c.c | 2 + drivers/net/wireless/realtek/rtw89/txrx.h | 12 ++++ 6 files changed, 116 insertions(+), 4 deletions(-) diff --git a/drivers/net/wireless/realtek/rtw89/core.c b/drivers/net/wireless/realtek/rtw89/core.c index a5c13fd7d8a04..3c2cbe479197d 100644 --- a/drivers/net/wireless/realtek/rtw89/core.c +++ b/drivers/net/wireless/realtek/rtw89/core.c @@ -897,6 +897,26 @@ static __le32 rtw89_build_txwd_body0(struct rtw89_tx_desc_info *desc_info) return cpu_to_le32(dword); } +static __le32 rtw89_build_txwd_body0_v1(struct rtw89_tx_desc_info *desc_info) +{ + u32 dword = FIELD_PREP(RTW89_TXWD_BODY0_WP_OFFSET_V1, desc_info->wp_offset) | + FIELD_PREP(RTW89_TXWD_BODY0_WD_INFO_EN, desc_info->en_wd_info) | + FIELD_PREP(RTW89_TXWD_BODY0_CHANNEL_DMA, desc_info->ch_dma) | + FIELD_PREP(RTW89_TXWD_BODY0_HDR_LLC_LEN, desc_info->hdr_llc_len) | + FIELD_PREP(RTW89_TXWD_BODY0_WD_PAGE, desc_info->wd_page) | + FIELD_PREP(RTW89_TXWD_BODY0_FW_DL, desc_info->fw_dl); + + return cpu_to_le32(dword); +} + +static __le32 rtw89_build_txwd_body1_v1(struct rtw89_tx_desc_info *desc_info) +{ + u32 dword = FIELD_PREP(RTW89_TXWD_BODY1_ADDR_INFO_NUM, desc_info->addr_info_nr) | + FIELD_PREP(RTW89_TXWD_BODY1_SEC_TYPE, desc_info->sec_type); + + return cpu_to_le32(dword); +} + static __le32 rtw89_build_txwd_body2(struct rtw89_tx_desc_info *desc_info) { u32 dword = FIELD_PREP(RTW89_TXWD_BODY2_TID_INDICATE, desc_info->tid_indicate) | @@ -916,6 +936,14 @@ static __le32 rtw89_build_txwd_body3(struct rtw89_tx_desc_info *desc_info) return cpu_to_le32(dword); } +static __le32 rtw89_build_txwd_body7_v1(struct rtw89_tx_desc_info *desc_info) +{ + u32 dword = FIELD_PREP(RTW89_TXWD_BODY7_USE_RATE_V1, desc_info->use_rate) | + FIELD_PREP(RTW89_TXWD_BODY7_DATA_RATE, desc_info->data_rate); + + return cpu_to_le32(dword); +} + static __le32 rtw89_build_txwd_info0(struct rtw89_tx_desc_info *desc_info) { u32 dword = FIELD_PREP(RTW89_TXWD_INFO0_USE_RATE, desc_info->use_rate) | @@ -926,6 +954,13 @@ static __le32 rtw89_build_txwd_info0(struct rtw89_tx_desc_info *desc_info) return cpu_to_le32(dword); } +static __le32 rtw89_build_txwd_info0_v1(struct rtw89_tx_desc_info *desc_info) +{ + u32 dword = FIELD_PREP(RTW89_TXWD_INFO0_DISDATAFB, desc_info->dis_data_fb); + + return cpu_to_le32(dword); +} + static __le32 rtw89_build_txwd_info1(struct rtw89_tx_desc_info *desc_info) { u32 dword = FIELD_PREP(RTW89_TXWD_INFO1_MAX_AGGNUM, desc_info->ampdu_num) | @@ -946,6 +981,15 @@ static __le32 rtw89_build_txwd_info2(struct rtw89_tx_desc_info *desc_info) return cpu_to_le32(dword); } +static __le32 rtw89_build_txwd_info2_v1(struct rtw89_tx_desc_info *desc_info) +{ + u32 dword = FIELD_PREP(RTW89_TXWD_INFO2_AMPDU_DENSITY, desc_info->ampdu_density) | + FIELD_PREP(RTW89_TXWD_INFO2_FORCE_KEY_EN, desc_info->sec_en) | + FIELD_PREP(RTW89_TXWD_INFO2_SEC_CAM_IDX, desc_info->sec_cam_idx); + + return cpu_to_le32(dword); +} + static __le32 rtw89_build_txwd_info4(struct rtw89_tx_desc_info *desc_info) { u32 dword = FIELD_PREP(RTW89_TXWD_INFO4_RTS_EN, 1) | @@ -977,6 +1021,30 @@ void rtw89_core_fill_txdesc(struct rtw89_dev *rtwdev, } EXPORT_SYMBOL(rtw89_core_fill_txdesc); +void rtw89_core_fill_txdesc_v1(struct rtw89_dev *rtwdev, + struct rtw89_tx_desc_info *desc_info, + void *txdesc) +{ + struct rtw89_txwd_body_v1 *txwd_body = (struct rtw89_txwd_body_v1 *)txdesc; + struct rtw89_txwd_info *txwd_info; + + txwd_body->dword0 = rtw89_build_txwd_body0_v1(desc_info); + txwd_body->dword1 = rtw89_build_txwd_body1_v1(desc_info); + txwd_body->dword2 = rtw89_build_txwd_body2(desc_info); + txwd_body->dword3 = rtw89_build_txwd_body3(desc_info); + txwd_body->dword7 = rtw89_build_txwd_body7_v1(desc_info); + + if (!desc_info->en_wd_info) + return; + + txwd_info = (struct rtw89_txwd_info *)(txwd_body + 1); + txwd_info->dword0 = rtw89_build_txwd_info0_v1(desc_info); + txwd_info->dword1 = rtw89_build_txwd_info1(desc_info); + txwd_info->dword2 = rtw89_build_txwd_info2_v1(desc_info); + txwd_info->dword4 = rtw89_build_txwd_info4(desc_info); +} +EXPORT_SYMBOL(rtw89_core_fill_txdesc_v1); + static __le32 rtw89_build_txwd_fwcmd0_v1(struct rtw89_tx_desc_info *desc_info) { u32 dword = FIELD_PREP(AX_RXD_RPKT_LEN_MASK, desc_info->pkt_size) | diff --git a/drivers/net/wireless/realtek/rtw89/core.h b/drivers/net/wireless/realtek/rtw89/core.h index 501381bb74adf..b5587d799bd83 100644 --- a/drivers/net/wireless/realtek/rtw89/core.h +++ b/drivers/net/wireless/realtek/rtw89/core.h @@ -642,6 +642,17 @@ struct rtw89_txwd_body { __le32 dword5; } __packed; +struct rtw89_txwd_body_v1 { + __le32 dword0; + __le32 dword1; + __le32 dword2; + __le32 dword3; + __le32 dword4; + __le32 dword5; + __le32 dword6; + __le32 dword7; +} __packed; + struct rtw89_txwd_info { __le32 dword0; __le32 dword1; @@ -2079,6 +2090,9 @@ struct rtw89_chip_ops { s8 pw_ofst, enum rtw89_mac_idx mac_idx); int (*pwr_on_func)(struct rtw89_dev *rtwdev); int (*pwr_off_func)(struct rtw89_dev *rtwdev); + void (*fill_txdesc)(struct rtw89_dev *rtwdev, + struct rtw89_tx_desc_info *desc_info, + void *txdesc); void (*fill_txdesc_fwcmd)(struct rtw89_dev *rtwdev, struct rtw89_tx_desc_info *desc_info, void *txdesc); @@ -2351,6 +2365,7 @@ struct rtw89_chip_info { u32 hci_func_en_addr; u32 h2c_desc_size; + u32 txwd_body_size; u32 h2c_ctrl_reg; const u32 *h2c_regs; u32 c2h_ctrl_reg; @@ -3514,6 +3529,16 @@ static inline void rtw89_ctrl_btg(struct rtw89_dev *rtwdev, bool btg) chip->ops->ctrl_btg(rtwdev, btg); } +static inline +void rtw89_chip_fill_txdesc(struct rtw89_dev *rtwdev, + struct rtw89_tx_desc_info *desc_info, + void *txdesc) +{ + const struct rtw89_chip_info *chip = rtwdev->chip; + + chip->ops->fill_txdesc(rtwdev, desc_info, txdesc); +} + static inline void rtw89_chip_fill_txdesc_fwcmd(struct rtw89_dev *rtwdev, struct rtw89_tx_desc_info *desc_info, @@ -3597,6 +3622,9 @@ void rtw89_core_tx_kick_off(struct rtw89_dev *rtwdev, u8 qsel); void rtw89_core_fill_txdesc(struct rtw89_dev *rtwdev, struct rtw89_tx_desc_info *desc_info, void *txdesc); +void rtw89_core_fill_txdesc_v1(struct rtw89_dev *rtwdev, + struct rtw89_tx_desc_info *desc_info, + void *txdesc); void rtw89_core_fill_txdesc_fwcmd_v1(struct rtw89_dev *rtwdev, struct rtw89_tx_desc_info *desc_info, void *txdesc); diff --git a/drivers/net/wireless/realtek/rtw89/pci.c b/drivers/net/wireless/realtek/rtw89/pci.c index 48a5feaf27222..3a27d6f8c6305 100644 --- a/drivers/net/wireless/realtek/rtw89/pci.c +++ b/drivers/net/wireless/realtek/rtw89/pci.c @@ -1035,8 +1035,8 @@ static int rtw89_pci_txwd_submit(struct rtw89_dev *rtwdev, struct rtw89_core_tx_request *tx_req) { struct rtw89_pci *rtwpci = (struct rtw89_pci *)rtwdev->priv; + const struct rtw89_chip_info *chip = rtwdev->chip; struct rtw89_tx_desc_info *desc_info = &tx_req->desc_info; - struct rtw89_txwd_body *txwd_body; struct rtw89_txwd_info *txwd_info; struct rtw89_pci_tx_wp_info *txwp_info; void *txaddr_info_addr; @@ -1050,8 +1050,6 @@ static int rtw89_pci_txwd_submit(struct rtw89_dev *rtwdev, dma_addr_t dma; int ret; - rtw89_core_fill_txdesc(rtwdev, desc_info, txwd->vaddr); - dma = dma_map_single(&pdev->dev, skb->data, skb->len, DMA_TO_DEVICE); if (dma_mapping_error(&pdev->dev, dma)) { rtw89_err(rtwdev, "failed to map skb dma data\n"); @@ -1062,7 +1060,7 @@ static int rtw89_pci_txwd_submit(struct rtw89_dev *rtwdev, tx_data->dma = dma; txwp_len = sizeof(*txwp_info); - txwd_len = sizeof(*txwd_body); + txwd_len = chip->txwd_body_size; txwd_len += en_wd_info ? sizeof(*txwd_info) : 0; txwp_info = txwd->vaddr + txwd_len; @@ -1079,6 +1077,8 @@ static int rtw89_pci_txwd_submit(struct rtw89_dev *rtwdev, txwd->len = txwd_len + txwp_len + txaddr_info_len; + rtw89_chip_fill_txdesc(rtwdev, desc_info, txwd->vaddr); + skb_queue_tail(&txwd->queue, skb); return 0; diff --git a/drivers/net/wireless/realtek/rtw89/rtw8852a.c b/drivers/net/wireless/realtek/rtw89/rtw8852a.c index 6aa3d19a74644..a0dd4db384c63 100644 --- a/drivers/net/wireless/realtek/rtw89/rtw8852a.c +++ b/drivers/net/wireless/realtek/rtw89/rtw8852a.c @@ -2021,6 +2021,7 @@ static const struct rtw89_chip_ops rtw8852a_chip_ops = { .set_txpwr_ul_tb_offset = rtw8852a_set_txpwr_ul_tb_offset, .pwr_on_func = NULL, .pwr_off_func = NULL, + .fill_txdesc = rtw89_core_fill_txdesc, .fill_txdesc_fwcmd = rtw89_core_fill_txdesc, .cfg_ctrl_path = rtw89_mac_cfg_ctrl_path, .mac_cfg_gnt = rtw89_mac_cfg_gnt, @@ -2099,6 +2100,7 @@ const struct rtw89_chip_info rtw8852a_chip_info = { BIT(RTW89_PS_MODE_PWR_GATED), .hci_func_en_addr = R_AX_HCI_FUNC_EN, .h2c_desc_size = sizeof(struct rtw89_txwd_body), + .txwd_body_size = sizeof(struct rtw89_txwd_body), .h2c_ctrl_reg = R_AX_H2CREG_CTRL, .h2c_regs = rtw8852a_h2c_regs, .c2h_ctrl_reg = R_AX_C2HREG_CTRL, diff --git a/drivers/net/wireless/realtek/rtw89/rtw8852c.c b/drivers/net/wireless/realtek/rtw89/rtw8852c.c index 08a9c01a359e0..df0c67c7322fe 100644 --- a/drivers/net/wireless/realtek/rtw89/rtw8852c.c +++ b/drivers/net/wireless/realtek/rtw89/rtw8852c.c @@ -492,6 +492,7 @@ static const struct rtw89_chip_ops rtw8852c_chip_ops = { .set_txpwr_ul_tb_offset = rtw8852c_set_txpwr_ul_tb_offset, .pwr_on_func = rtw8852c_pwr_on_func, .pwr_off_func = rtw8852c_pwr_off_func, + .fill_txdesc = rtw89_core_fill_txdesc_v1, .fill_txdesc_fwcmd = rtw89_core_fill_txdesc_fwcmd_v1, .cfg_ctrl_path = rtw89_mac_cfg_ctrl_path_v1, .mac_cfg_gnt = rtw89_mac_cfg_gnt_v1, @@ -517,6 +518,7 @@ const struct rtw89_chip_info rtw8852c_chip_info = { .phycap_size = 0x60, .hci_func_en_addr = R_AX_HCI_FUNC_EN_V1, .h2c_desc_size = sizeof(struct rtw89_rxdesc_short), + .txwd_body_size = sizeof(struct rtw89_txwd_body_v1), .h2c_ctrl_reg = R_AX_H2CREG_CTRL_V1, .h2c_regs = rtw8852c_h2c_regs, .c2h_ctrl_reg = R_AX_C2HREG_CTRL_V1, diff --git a/drivers/net/wireless/realtek/rtw89/txrx.h b/drivers/net/wireless/realtek/rtw89/txrx.h index 4e81d6df93688..c943e4e95721e 100644 --- a/drivers/net/wireless/realtek/rtw89/txrx.h +++ b/drivers/net/wireless/realtek/rtw89/txrx.h @@ -24,6 +24,7 @@ /* TX WD BODY DWORD 0 */ #define RTW89_TXWD_BODY0_WP_OFFSET GENMASK(31, 24) +#define RTW89_TXWD_BODY0_WP_OFFSET_V1 GENMASK(28, 24) #define RTW89_TXWD_BODY0_MORE_DATA BIT(23) #define RTW89_TXWD_BODY0_WD_INFO_EN BIT(22) #define RTW89_TXWD_BODY0_FW_DL BIT(20) @@ -35,7 +36,9 @@ #define RTW89_TXWD_BODY0_HW_SSN_MODE GENMASK(1, 0) /* TX WD BODY DWORD 1 */ +#define RTW89_TXWD_BODY1_ADDR_INFO_NUM GENMASK(31, 26) #define RTW89_TXWD_BODY1_PAYLOAD_ID GENMASK(31, 16) +#define RTW89_TXWD_BODY1_SEC_TYPE GENMASK(3, 0) /* TX WD BODY DWORD 2 */ #define RTW89_TXWD_BODY2_MACID GENMASK(30, 24) @@ -52,6 +55,14 @@ /* TX WD BODY DWORD 5 */ +/* TX WD BODY DWORD 6 (V1) */ + +/* TX WD BODY DWORD 7 (V1) */ +#define RTW89_TXWD_BODY7_USE_RATE_V1 BIT(31) +#define RTW89_TXWD_BODY7_DATA_BW GENMASK(29, 28) +#define RTW89_TXWD_BODY7_GI_LTF GENMASK(27, 25) +#define RTW89_TXWD_BODY7_DATA_RATE GENMASK(24, 16) + /* TX WD INFO DWORD 0 */ #define RTW89_TXWD_INFO0_USE_RATE BIT(30) #define RTW89_TXWD_INFO0_DATA_BW GENMASK(29, 28) @@ -69,6 +80,7 @@ #define RTW89_TXWD_INFO2_AMPDU_DENSITY GENMASK(20, 18) #define RTW89_TXWD_INFO2_SEC_TYPE GENMASK(12, 9) #define RTW89_TXWD_INFO2_SEC_HW_ENC BIT(8) +#define RTW89_TXWD_INFO2_FORCE_KEY_EN BIT(8) #define RTW89_TXWD_INFO2_SEC_CAM_IDX GENMASK(7, 0) /* TX WD INFO DWORD 3 */ From 79a6c9a4f3c4473dd508a7384ae328bf683b7382 Mon Sep 17 00:00:00 2001 From: Ping-Ke Shih Date: Fri, 18 Mar 2022 10:32:13 +0800 Subject: [PATCH 068/228] rtw89: support hardware generate security header The newer chip will generate security header itself, so don't set IEEE80211_KEY_FLAG_GENERATE_IV in this kind of chip. But, it needs to fill key_index, PN and 802.11 header length to TX descriptor, and then hardware uses these to generate security header. Signed-off-by: Ping-Ke Shih Signed-off-by: Kalle Valo Link: https://lore.kernel.org/r/20220318023214.32411-11-pkshih@realtek.com --- drivers/net/wireless/realtek/rtw89/cam.c | 4 +- drivers/net/wireless/realtek/rtw89/core.c | 50 +++++++++++++++++++ drivers/net/wireless/realtek/rtw89/core.h | 3 ++ drivers/net/wireless/realtek/rtw89/rtw8852a.c | 1 + drivers/net/wireless/realtek/rtw89/rtw8852c.c | 1 + drivers/net/wireless/realtek/rtw89/txrx.h | 7 +++ 6 files changed, 65 insertions(+), 1 deletion(-) diff --git a/drivers/net/wireless/realtek/rtw89/cam.c b/drivers/net/wireless/realtek/rtw89/cam.c index 34df3c07c55c5..34827f174ba1e 100644 --- a/drivers/net/wireless/realtek/rtw89/cam.c +++ b/drivers/net/wireless/realtek/rtw89/cam.c @@ -320,6 +320,7 @@ int rtw89_cam_sec_key_add(struct rtw89_dev *rtwdev, struct ieee80211_sta *sta, struct ieee80211_key_conf *key) { + const struct rtw89_chip_info *chip = rtwdev->chip; u8 hw_key_type; bool ext_key = false; int ret; @@ -353,7 +354,8 @@ int rtw89_cam_sec_key_add(struct rtw89_dev *rtwdev, return -EOPNOTSUPP; } - key->flags |= IEEE80211_KEY_FLAG_GENERATE_IV; + if (!chip->hw_sec_hdr) + key->flags |= IEEE80211_KEY_FLAG_GENERATE_IV; ret = rtw89_cam_sec_key_install(rtwdev, vif, sta, key, hw_key_type, ext_key); diff --git a/drivers/net/wireless/realtek/rtw89/core.c b/drivers/net/wireless/realtek/rtw89/core.c index 3c2cbe479197d..245d8514961e8 100644 --- a/drivers/net/wireless/realtek/rtw89/core.c +++ b/drivers/net/wireless/realtek/rtw89/core.c @@ -435,6 +435,7 @@ static void rtw89_core_tx_update_sec_key(struct rtw89_dev *rtwdev, struct rtw89_core_tx_request *tx_req) { + const struct rtw89_chip_info *chip = rtwdev->chip; struct ieee80211_vif *vif = tx_req->vif; struct ieee80211_sta *sta = tx_req->sta; struct ieee80211_tx_info *info; @@ -446,6 +447,7 @@ rtw89_core_tx_update_sec_key(struct rtw89_dev *rtwdev, struct rtw89_tx_desc_info *desc_info = &tx_req->desc_info; struct sk_buff *skb = tx_req->skb; u8 sec_type = RTW89_SEC_KEY_TYPE_NONE; + u64 pn64; if (!vif) { rtw89_warn(rtwdev, "cannot set sec key without vif\n"); @@ -491,8 +493,21 @@ rtw89_core_tx_update_sec_key(struct rtw89_dev *rtwdev, } desc_info->sec_en = true; + desc_info->sec_keyid = key->keyidx; desc_info->sec_type = sec_type; desc_info->sec_cam_idx = sec_cam->sec_cam_idx; + + if (!chip->hw_sec_hdr) + return; + + pn64 = atomic64_inc_return(&key->tx_pn); + desc_info->sec_seq[0] = pn64; + desc_info->sec_seq[1] = pn64 >> 8; + desc_info->sec_seq[2] = pn64 >> 16; + desc_info->sec_seq[3] = pn64 >> 24; + desc_info->sec_seq[4] = pn64 >> 32; + desc_info->sec_seq[5] = pn64 >> 40; + desc_info->wp_offset = 1; /* in unit of 8 bytes for security header */ } static u16 rtw89_core_get_mgmt_rate(struct rtw89_dev *rtwdev, @@ -755,6 +770,17 @@ rtw89_core_tx_btc_spec_pkt_notify(struct rtw89_dev *rtwdev, return PACKET_MAX; } +static void rtw89_core_tx_update_llc_hdr(struct rtw89_dev *rtwdev, + struct rtw89_tx_desc_info *desc_info, + struct sk_buff *skb) +{ + struct ieee80211_hdr *hdr = (void *)skb->data; + __le16 fc = hdr->frame_control; + + desc_info->hdr_llc_len = ieee80211_hdrlen(fc); + desc_info->hdr_llc_len >>= 1; /* in unit of 2 bytes */ +} + static void rtw89_core_tx_wake(struct rtw89_dev *rtwdev, struct rtw89_core_tx_request *tx_req) @@ -806,6 +832,7 @@ rtw89_core_tx_update_desc_info(struct rtw89_dev *rtwdev, rtw89_core_tx_update_data_info(rtwdev, tx_req); pkt_type = rtw89_core_tx_btc_spec_pkt_notify(rtwdev, tx_req); rtw89_core_tx_update_he_qos_htc(rtwdev, tx_req, pkt_type); + rtw89_core_tx_update_llc_hdr(rtwdev, desc_info, skb); break; case RTW89_CORE_TX_TYPE_FWCMD: rtw89_core_tx_update_h2c_info(rtwdev, tx_req); @@ -912,6 +939,7 @@ static __le32 rtw89_build_txwd_body0_v1(struct rtw89_tx_desc_info *desc_info) static __le32 rtw89_build_txwd_body1_v1(struct rtw89_tx_desc_info *desc_info) { u32 dword = FIELD_PREP(RTW89_TXWD_BODY1_ADDR_INFO_NUM, desc_info->addr_info_nr) | + FIELD_PREP(RTW89_TXWD_BODY1_SEC_KEYID, desc_info->sec_keyid) | FIELD_PREP(RTW89_TXWD_BODY1_SEC_TYPE, desc_info->sec_type); return cpu_to_le32(dword); @@ -936,6 +964,24 @@ static __le32 rtw89_build_txwd_body3(struct rtw89_tx_desc_info *desc_info) return cpu_to_le32(dword); } +static __le32 rtw89_build_txwd_body4(struct rtw89_tx_desc_info *desc_info) +{ + u32 dword = FIELD_PREP(RTW89_TXWD_BODY4_SEC_IV_L0, desc_info->sec_seq[0]) | + FIELD_PREP(RTW89_TXWD_BODY4_SEC_IV_L1, desc_info->sec_seq[1]); + + return cpu_to_le32(dword); +} + +static __le32 rtw89_build_txwd_body5(struct rtw89_tx_desc_info *desc_info) +{ + u32 dword = FIELD_PREP(RTW89_TXWD_BODY5_SEC_IV_H2, desc_info->sec_seq[2]) | + FIELD_PREP(RTW89_TXWD_BODY5_SEC_IV_H3, desc_info->sec_seq[3]) | + FIELD_PREP(RTW89_TXWD_BODY5_SEC_IV_H4, desc_info->sec_seq[4]) | + FIELD_PREP(RTW89_TXWD_BODY5_SEC_IV_H5, desc_info->sec_seq[5]); + + return cpu_to_le32(dword); +} + static __le32 rtw89_build_txwd_body7_v1(struct rtw89_tx_desc_info *desc_info) { u32 dword = FIELD_PREP(RTW89_TXWD_BODY7_USE_RATE_V1, desc_info->use_rate) | @@ -1032,6 +1078,10 @@ void rtw89_core_fill_txdesc_v1(struct rtw89_dev *rtwdev, txwd_body->dword1 = rtw89_build_txwd_body1_v1(desc_info); txwd_body->dword2 = rtw89_build_txwd_body2(desc_info); txwd_body->dword3 = rtw89_build_txwd_body3(desc_info); + if (desc_info->sec_en) { + txwd_body->dword4 = rtw89_build_txwd_body4(desc_info); + txwd_body->dword5 = rtw89_build_txwd_body5(desc_info); + } txwd_body->dword7 = rtw89_build_txwd_body7_v1(desc_info); if (!desc_info->en_wd_info) diff --git a/drivers/net/wireless/realtek/rtw89/core.h b/drivers/net/wireless/realtek/rtw89/core.h index b5587d799bd83..9f53d581a48f9 100644 --- a/drivers/net/wireless/realtek/rtw89/core.h +++ b/drivers/net/wireless/realtek/rtw89/core.h @@ -733,8 +733,10 @@ struct rtw89_tx_desc_info { u8 ampdu_num; bool sec_en; u8 addr_info_nr; + u8 sec_keyid; u8 sec_type; u8 sec_cam_idx; + u8 sec_seq[6]; u16 data_rate; u16 data_retry_lowest_rate; bool fw_dl; @@ -2302,6 +2304,7 @@ struct rtw89_chip_info { u32 rf_base_addr[2]; u8 support_bands; bool support_bw160; + bool hw_sec_hdr; u8 rf_path_num; u8 tx_nss; u8 rx_nss; diff --git a/drivers/net/wireless/realtek/rtw89/rtw8852a.c b/drivers/net/wireless/realtek/rtw89/rtw8852a.c index a0dd4db384c63..0ab1c57c845b4 100644 --- a/drivers/net/wireless/realtek/rtw89/rtw8852a.c +++ b/drivers/net/wireless/realtek/rtw89/rtw8852a.c @@ -2066,6 +2066,7 @@ const struct rtw89_chip_info rtw8852a_chip_info = { .support_bands = BIT(NL80211_BAND_2GHZ) | BIT(NL80211_BAND_5GHZ), .support_bw160 = false, + .hw_sec_hdr = false, .rf_path_num = 2, .tx_nss = 2, .rx_nss = 2, diff --git a/drivers/net/wireless/realtek/rtw89/rtw8852c.c b/drivers/net/wireless/realtek/rtw89/rtw8852c.c index df0c67c7322fe..4773f6c739dc0 100644 --- a/drivers/net/wireless/realtek/rtw89/rtw8852c.c +++ b/drivers/net/wireless/realtek/rtw89/rtw8852c.c @@ -508,6 +508,7 @@ const struct rtw89_chip_info rtw8852c_chip_info = { .rf_base_addr = {0xe000, 0xf000}, .pwr_on_seq = NULL, .pwr_off_seq = NULL, + .hw_sec_hdr = true, .sec_ctrl_efuse_size = 4, .physical_efuse_size = 1216, .logical_efuse_size = 2048, diff --git a/drivers/net/wireless/realtek/rtw89/txrx.h b/drivers/net/wireless/realtek/rtw89/txrx.h index c943e4e95721e..1250e26ade406 100644 --- a/drivers/net/wireless/realtek/rtw89/txrx.h +++ b/drivers/net/wireless/realtek/rtw89/txrx.h @@ -38,6 +38,7 @@ /* TX WD BODY DWORD 1 */ #define RTW89_TXWD_BODY1_ADDR_INFO_NUM GENMASK(31, 26) #define RTW89_TXWD_BODY1_PAYLOAD_ID GENMASK(31, 16) +#define RTW89_TXWD_BODY1_SEC_KEYID GENMASK(5, 4) #define RTW89_TXWD_BODY1_SEC_TYPE GENMASK(3, 0) /* TX WD BODY DWORD 2 */ @@ -52,8 +53,14 @@ #define RTW89_TXWD_BODY3_SW_SEQ GENMASK(11, 0) /* TX WD BODY DWORD 4 */ +#define RTW89_TXWD_BODY4_SEC_IV_L1 GENMASK(31, 24) +#define RTW89_TXWD_BODY4_SEC_IV_L0 GENMASK(23, 16) /* TX WD BODY DWORD 5 */ +#define RTW89_TXWD_BODY5_SEC_IV_H5 GENMASK(31, 24) +#define RTW89_TXWD_BODY5_SEC_IV_H4 GENMASK(23, 16) +#define RTW89_TXWD_BODY5_SEC_IV_H3 GENMASK(15, 8) +#define RTW89_TXWD_BODY5_SEC_IV_H2 GENMASK(7, 0) /* TX WD BODY DWORD 6 (V1) */ From 84fc6999f0d01920687d8555e3f1bb87625a66ed Mon Sep 17 00:00:00 2001 From: Ping-Ke Shih Date: Fri, 18 Mar 2022 10:32:14 +0800 Subject: [PATCH 069/228] rtw89: read RX bandwidth from v1 type RX descriptor 8852C uses different fields to represent RX bandwidth. Since other fields are the same, I check chip_id to get bandwidth instead of creating another v1 function. Signed-off-by: Ping-Ke Shih Signed-off-by: Kalle Valo Link: https://lore.kernel.org/r/20220318023214.32411-12-pkshih@realtek.com --- drivers/net/wireless/realtek/rtw89/core.c | 6 +++++- drivers/net/wireless/realtek/rtw89/txrx.h | 2 ++ 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/drivers/net/wireless/realtek/rtw89/core.c b/drivers/net/wireless/realtek/rtw89/core.c index 245d8514961e8..d923e4a0f963b 100644 --- a/drivers/net/wireless/realtek/rtw89/core.c +++ b/drivers/net/wireless/realtek/rtw89/core.c @@ -1492,6 +1492,7 @@ void rtw89_core_query_rxdesc(struct rtw89_dev *rtwdev, struct rtw89_rx_desc_info *desc_info, u8 *data, u32 data_offset) { + const struct rtw89_chip_info *chip = rtwdev->chip; struct rtw89_rxdesc_short *rxd_s; struct rtw89_rxdesc_long *rxd_l; u8 shift_len, drv_info_len; @@ -1502,7 +1503,10 @@ void rtw89_core_query_rxdesc(struct rtw89_dev *rtwdev, desc_info->long_rxdesc = RTW89_GET_RXWD_LONG_RXD(rxd_s); desc_info->pkt_type = RTW89_GET_RXWD_RPKT_TYPE(rxd_s); desc_info->mac_info_valid = RTW89_GET_RXWD_MAC_INFO_VALID(rxd_s); - desc_info->bw = RTW89_GET_RXWD_BW(rxd_s); + if (chip->chip_id == RTL8852C) + desc_info->bw = RTW89_GET_RXWD_BW_V1(rxd_s); + else + desc_info->bw = RTW89_GET_RXWD_BW(rxd_s); desc_info->data_rate = RTW89_GET_RXWD_DATA_RATE(rxd_s); desc_info->gi_ltf = RTW89_GET_RXWD_GI_LTF(rxd_s); desc_info->user_id = RTW89_GET_RXWD_USER_ID(rxd_s); diff --git a/drivers/net/wireless/realtek/rtw89/txrx.h b/drivers/net/wireless/realtek/rtw89/txrx.h index 1250e26ade406..b889e7bf34c0c 100644 --- a/drivers/net/wireless/realtek/rtw89/txrx.h +++ b/drivers/net/wireless/realtek/rtw89/txrx.h @@ -204,6 +204,8 @@ le32_get_bits((rxdesc)->dword0, GENMASK(13, 0)) #define RTW89_GET_RXWD_BW(rxdesc) \ le32_get_bits((rxdesc)->dword1, GENMASK(31, 30)) +#define RTW89_GET_RXWD_BW_V1(rxdesc) \ + le32_get_bits((rxdesc)->dword1, GENMASK(31, 29)) #define RTW89_GET_RXWD_GI_LTF(rxdesc) \ le32_get_bits((rxdesc)->dword1, GENMASK(27, 25)) #define RTW89_GET_RXWD_DATA_RATE(rxdesc) \ From 26bb93407c748d731f25581ccae196e1016072bf Mon Sep 17 00:00:00 2001 From: Ping-Ke Shih Date: Fri, 18 Mar 2022 11:52:02 +0800 Subject: [PATCH 070/228] rtw89: handle potential uninitialized variable The smatch reports: rtw8852a.c:1857 rtw8852a_btc_set_wl_txpwr_ctrl() error: uninitialized symbol '_cur'. rtw8852a.c:1858 rtw8852a_btc_set_wl_txpwr_ctrl() error: uninitialized symbol '_cur'. This is because rtw89_mac_txpwr_read32() can possibly return before setting argument _cur, and the caller will use the uninitialized value. To fix this problem, check the return value of rtw89_mac_txpwr_read32(). Signed-off-by: Ping-Ke Shih Signed-off-by: Kalle Valo Link: https://lore.kernel.org/r/20220318035202.42437-1-pkshih@realtek.com --- drivers/net/wireless/realtek/rtw89/rtw8852a.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/drivers/net/wireless/realtek/rtw89/rtw8852a.c b/drivers/net/wireless/realtek/rtw89/rtw8852a.c index 0ab1c57c845b4..a8b972d4bee8a 100644 --- a/drivers/net/wireless/realtek/rtw89/rtw8852a.c +++ b/drivers/net/wireless/realtek/rtw89/rtw8852a.c @@ -1843,7 +1843,8 @@ rtw8852a_btc_set_wl_txpwr_ctrl(struct rtw89_dev *rtwdev, u32 txpwr_val) u32 _cur, _wrt; \ rtw89_debug(rtwdev, RTW89_DBG_TXPWR, \ "btc ctrl %s: 0x%x\n", #_case, _val); \ - rtw89_mac_txpwr_read32(rtwdev, RTW89_PHY_0, _reg, &_cur);\ + if (rtw89_mac_txpwr_read32(rtwdev, RTW89_PHY_0, _reg, &_cur))\ + break; \ rtw89_debug(rtwdev, RTW89_DBG_TXPWR, \ "btc ctrl ori 0x%x: 0x%x\n", _reg, _cur); \ _wrt = __do_clr(_val) ? \ From 121210ec935c47b076709974d95360f5e9c9b869 Mon Sep 17 00:00:00 2001 From: Kalle Valo Date: Fri, 1 Apr 2022 20:30:40 +0300 Subject: [PATCH 071/228] ath11k: mhi: remove state machine State machines are difficult to understand and in this case it's just useless, which is shown by the diffstat. So remove it entirely to make the code simpler. No functional changes. Tested-on: WCN6855 hw2.0 PCI WLAN.HSP.1.1-03003-QCAHSPSWPL_V1_V2_SILICONZ_LITE-2 Signed-off-by: Kalle Valo Link: https://lore.kernel.org/r/20220401173042.17467-2-kvalo@kernel.org --- drivers/net/wireless/ath/ath11k/mhi.c | 194 ++------------------------ drivers/net/wireless/ath/ath11k/mhi.h | 13 -- drivers/net/wireless/ath/ath11k/pci.h | 2 +- 3 files changed, 11 insertions(+), 198 deletions(-) diff --git a/drivers/net/wireless/ath/ath11k/mhi.c b/drivers/net/wireless/ath/ath11k/mhi.c index 1aa1e0f01b85d..6ad91c600d0e0 100644 --- a/drivers/net/wireless/ath/ath11k/mhi.c +++ b/drivers/net/wireless/ath/ath11k/mhi.c @@ -463,195 +463,17 @@ void ath11k_mhi_unregister(struct ath11k_pci *ab_pci) mhi_free_controller(mhi_ctrl); } -static char *ath11k_mhi_state_to_str(enum ath11k_mhi_state mhi_state) -{ - switch (mhi_state) { - case ATH11K_MHI_INIT: - return "INIT"; - case ATH11K_MHI_DEINIT: - return "DEINIT"; - case ATH11K_MHI_POWER_ON: - return "POWER_ON"; - case ATH11K_MHI_POWER_OFF: - return "POWER_OFF"; - case ATH11K_MHI_FORCE_POWER_OFF: - return "FORCE_POWER_OFF"; - case ATH11K_MHI_SUSPEND: - return "SUSPEND"; - case ATH11K_MHI_RESUME: - return "RESUME"; - case ATH11K_MHI_TRIGGER_RDDM: - return "TRIGGER_RDDM"; - case ATH11K_MHI_RDDM_DONE: - return "RDDM_DONE"; - default: - return "UNKNOWN"; - } -}; - -static void ath11k_mhi_set_state_bit(struct ath11k_pci *ab_pci, - enum ath11k_mhi_state mhi_state) -{ - struct ath11k_base *ab = ab_pci->ab; - - switch (mhi_state) { - case ATH11K_MHI_INIT: - set_bit(ATH11K_MHI_INIT, &ab_pci->mhi_state); - break; - case ATH11K_MHI_DEINIT: - clear_bit(ATH11K_MHI_INIT, &ab_pci->mhi_state); - break; - case ATH11K_MHI_POWER_ON: - set_bit(ATH11K_MHI_POWER_ON, &ab_pci->mhi_state); - break; - case ATH11K_MHI_POWER_OFF: - case ATH11K_MHI_FORCE_POWER_OFF: - clear_bit(ATH11K_MHI_POWER_ON, &ab_pci->mhi_state); - clear_bit(ATH11K_MHI_TRIGGER_RDDM, &ab_pci->mhi_state); - clear_bit(ATH11K_MHI_RDDM_DONE, &ab_pci->mhi_state); - break; - case ATH11K_MHI_SUSPEND: - set_bit(ATH11K_MHI_SUSPEND, &ab_pci->mhi_state); - break; - case ATH11K_MHI_RESUME: - clear_bit(ATH11K_MHI_SUSPEND, &ab_pci->mhi_state); - break; - case ATH11K_MHI_TRIGGER_RDDM: - set_bit(ATH11K_MHI_TRIGGER_RDDM, &ab_pci->mhi_state); - break; - case ATH11K_MHI_RDDM_DONE: - set_bit(ATH11K_MHI_RDDM_DONE, &ab_pci->mhi_state); - break; - default: - ath11k_err(ab, "unhandled mhi state (%d)\n", mhi_state); - } -} - -static int ath11k_mhi_check_state_bit(struct ath11k_pci *ab_pci, - enum ath11k_mhi_state mhi_state) -{ - struct ath11k_base *ab = ab_pci->ab; - - switch (mhi_state) { - case ATH11K_MHI_INIT: - if (!test_bit(ATH11K_MHI_INIT, &ab_pci->mhi_state)) - return 0; - break; - case ATH11K_MHI_DEINIT: - case ATH11K_MHI_POWER_ON: - if (test_bit(ATH11K_MHI_INIT, &ab_pci->mhi_state) && - !test_bit(ATH11K_MHI_POWER_ON, &ab_pci->mhi_state)) - return 0; - break; - case ATH11K_MHI_FORCE_POWER_OFF: - if (test_bit(ATH11K_MHI_POWER_ON, &ab_pci->mhi_state)) - return 0; - break; - case ATH11K_MHI_POWER_OFF: - case ATH11K_MHI_SUSPEND: - if (test_bit(ATH11K_MHI_POWER_ON, &ab_pci->mhi_state) && - !test_bit(ATH11K_MHI_SUSPEND, &ab_pci->mhi_state)) - return 0; - break; - case ATH11K_MHI_RESUME: - if (test_bit(ATH11K_MHI_SUSPEND, &ab_pci->mhi_state)) - return 0; - break; - case ATH11K_MHI_TRIGGER_RDDM: - if (test_bit(ATH11K_MHI_POWER_ON, &ab_pci->mhi_state) && - !test_bit(ATH11K_MHI_TRIGGER_RDDM, &ab_pci->mhi_state)) - return 0; - break; - case ATH11K_MHI_RDDM_DONE: - return 0; - default: - ath11k_err(ab, "unhandled mhi state: %s(%d)\n", - ath11k_mhi_state_to_str(mhi_state), mhi_state); - } - - ath11k_err(ab, "failed to set mhi state %s(%d) in current mhi state (0x%lx)\n", - ath11k_mhi_state_to_str(mhi_state), mhi_state, - ab_pci->mhi_state); - - return -EINVAL; -} - -static int ath11k_mhi_set_state(struct ath11k_pci *ab_pci, - enum ath11k_mhi_state mhi_state) -{ - struct ath11k_base *ab = ab_pci->ab; - int ret; - - ret = ath11k_mhi_check_state_bit(ab_pci, mhi_state); - if (ret) - goto out; - - ath11k_dbg(ab, ATH11K_DBG_PCI, "setting mhi state: %s(%d)\n", - ath11k_mhi_state_to_str(mhi_state), mhi_state); - - switch (mhi_state) { - case ATH11K_MHI_INIT: - ret = mhi_prepare_for_power_up(ab_pci->mhi_ctrl); - break; - case ATH11K_MHI_DEINIT: - mhi_unprepare_after_power_down(ab_pci->mhi_ctrl); - ret = 0; - break; - case ATH11K_MHI_POWER_ON: - ret = mhi_sync_power_up(ab_pci->mhi_ctrl); - break; - case ATH11K_MHI_POWER_OFF: - mhi_power_down(ab_pci->mhi_ctrl, true); - ret = 0; - break; - case ATH11K_MHI_FORCE_POWER_OFF: - mhi_power_down(ab_pci->mhi_ctrl, false); - ret = 0; - break; - case ATH11K_MHI_SUSPEND: - ret = mhi_pm_suspend(ab_pci->mhi_ctrl); - break; - case ATH11K_MHI_RESUME: - /* Do force MHI resume as some devices like QCA6390, WCN6855 - * are not in M3 state but they are functional. So just ignore - * the MHI state while resuming. - */ - ret = mhi_pm_resume_force(ab_pci->mhi_ctrl); - break; - case ATH11K_MHI_TRIGGER_RDDM: - ret = mhi_force_rddm_mode(ab_pci->mhi_ctrl); - break; - case ATH11K_MHI_RDDM_DONE: - break; - default: - ath11k_err(ab, "unhandled MHI state (%d)\n", mhi_state); - ret = -EINVAL; - } - - if (ret) - goto out; - - ath11k_mhi_set_state_bit(ab_pci, mhi_state); - - return 0; - -out: - ath11k_err(ab, "failed to set mhi state: %s(%d)\n", - ath11k_mhi_state_to_str(mhi_state), mhi_state); - return ret; -} - int ath11k_mhi_start(struct ath11k_pci *ab_pci) { int ret; ab_pci->mhi_ctrl->timeout_ms = MHI_TIMEOUT_DEFAULT_MS; - ret = ath11k_mhi_set_state(ab_pci, ATH11K_MHI_INIT); + ret = mhi_prepare_for_power_up(ab_pci->mhi_ctrl); if (ret) goto out; - ret = ath11k_mhi_set_state(ab_pci, ATH11K_MHI_POWER_ON); + ret = mhi_sync_power_up(ab_pci->mhi_ctrl); if (ret) goto out; @@ -663,16 +485,20 @@ int ath11k_mhi_start(struct ath11k_pci *ab_pci) void ath11k_mhi_stop(struct ath11k_pci *ab_pci) { - ath11k_mhi_set_state(ab_pci, ATH11K_MHI_POWER_OFF); - ath11k_mhi_set_state(ab_pci, ATH11K_MHI_DEINIT); + mhi_power_down(ab_pci->mhi_ctrl, true); + mhi_unprepare_after_power_down(ab_pci->mhi_ctrl); } void ath11k_mhi_suspend(struct ath11k_pci *ab_pci) { - ath11k_mhi_set_state(ab_pci, ATH11K_MHI_SUSPEND); + mhi_pm_suspend(ab_pci->mhi_ctrl); } void ath11k_mhi_resume(struct ath11k_pci *ab_pci) { - ath11k_mhi_set_state(ab_pci, ATH11K_MHI_RESUME); + /* Do force MHI resume as some devices like QCA6390, WCN6855 + * are not in M3 state but they are functional. So just ignore + * the MHI state while resuming. + */ + mhi_pm_resume_force(ab_pci->mhi_ctrl); } diff --git a/drivers/net/wireless/ath/ath11k/mhi.h b/drivers/net/wireless/ath/ath11k/mhi.h index 488dada5d31c1..5dd024f879c41 100644 --- a/drivers/net/wireless/ath/ath11k/mhi.h +++ b/drivers/net/wireless/ath/ath11k/mhi.h @@ -16,19 +16,6 @@ #define MHICTRL 0x38 #define MHICTRL_RESET_MASK 0x2 -enum ath11k_mhi_state { - ATH11K_MHI_INIT, - ATH11K_MHI_DEINIT, - ATH11K_MHI_POWER_ON, - ATH11K_MHI_POWER_OFF, - ATH11K_MHI_FORCE_POWER_OFF, - ATH11K_MHI_SUSPEND, - ATH11K_MHI_RESUME, - ATH11K_MHI_TRIGGER_RDDM, - ATH11K_MHI_RDDM, - ATH11K_MHI_RDDM_DONE, -}; - int ath11k_mhi_start(struct ath11k_pci *ar_pci); void ath11k_mhi_stop(struct ath11k_pci *ar_pci); int ath11k_mhi_register(struct ath11k_pci *ar_pci); diff --git a/drivers/net/wireless/ath/ath11k/pci.h b/drivers/net/wireless/ath/ath11k/pci.h index 16a000b9cc5e2..e9a01f344ec6c 100644 --- a/drivers/net/wireless/ath/ath11k/pci.h +++ b/drivers/net/wireless/ath/ath11k/pci.h @@ -63,7 +63,7 @@ struct ath11k_pci { u16 dev_id; char amss_path[100]; struct mhi_controller *mhi_ctrl; - unsigned long mhi_state; + const struct ath11k_msi_config *msi_config; u32 register_window; /* protects register_window above */ From 3e80fcbca37221cd1e5a33eea4b0f215f66a7a00 Mon Sep 17 00:00:00 2001 From: Kalle Valo Date: Tue, 5 Apr 2022 11:26:39 +0300 Subject: [PATCH 072/228] ath11k: mhi: add error handling for suspend and resume While reviewing the mhi.c I noticed we were just ignoring the errors coming from MHI subsystem during suspend and resume. Add proper checks and warning messages. Also pass the error value to callers. Tested-on: WCN6855 hw2.0 PCI WLAN.HSP.1.1-03003-QCAHSPSWPL_V1_V2_SILICONZ_LITE-2 Signed-off-by: Kalle Valo Link: https://lore.kernel.org/r/20220401173042.17467-3-kvalo@kernel.org --- drivers/net/wireless/ath/ath11k/mhi.c | 26 ++++++++++++++++++++++---- drivers/net/wireless/ath/ath11k/mhi.h | 4 ++-- drivers/net/wireless/ath/ath11k/pci.c | 8 ++------ 3 files changed, 26 insertions(+), 12 deletions(-) diff --git a/drivers/net/wireless/ath/ath11k/mhi.c b/drivers/net/wireless/ath/ath11k/mhi.c index 6ad91c600d0e0..defdf641df0b1 100644 --- a/drivers/net/wireless/ath/ath11k/mhi.c +++ b/drivers/net/wireless/ath/ath11k/mhi.c @@ -489,16 +489,34 @@ void ath11k_mhi_stop(struct ath11k_pci *ab_pci) mhi_unprepare_after_power_down(ab_pci->mhi_ctrl); } -void ath11k_mhi_suspend(struct ath11k_pci *ab_pci) +int ath11k_mhi_suspend(struct ath11k_pci *ab_pci) { - mhi_pm_suspend(ab_pci->mhi_ctrl); + struct ath11k_base *ab = ab_pci->ab; + int ret; + + ret = mhi_pm_suspend(ab_pci->mhi_ctrl); + if (ret) { + ath11k_warn(ab, "failed to suspend mhi: %d", ret); + return ret; + } + + return 0; } -void ath11k_mhi_resume(struct ath11k_pci *ab_pci) +int ath11k_mhi_resume(struct ath11k_pci *ab_pci) { + struct ath11k_base *ab = ab_pci->ab; + int ret; + /* Do force MHI resume as some devices like QCA6390, WCN6855 * are not in M3 state but they are functional. So just ignore * the MHI state while resuming. */ - mhi_pm_resume_force(ab_pci->mhi_ctrl); + ret = mhi_pm_resume_force(ab_pci->mhi_ctrl); + if (ret) { + ath11k_warn(ab, "failed to resume mhi: %d", ret); + return ret; + } + + return 0; } diff --git a/drivers/net/wireless/ath/ath11k/mhi.h b/drivers/net/wireless/ath/ath11k/mhi.h index 5dd024f879c41..8d9f852da6952 100644 --- a/drivers/net/wireless/ath/ath11k/mhi.h +++ b/drivers/net/wireless/ath/ath11k/mhi.h @@ -23,7 +23,7 @@ void ath11k_mhi_unregister(struct ath11k_pci *ar_pci); void ath11k_mhi_set_mhictrl_reset(struct ath11k_base *ab); void ath11k_mhi_clear_vector(struct ath11k_base *ab); -void ath11k_mhi_suspend(struct ath11k_pci *ar_pci); -void ath11k_mhi_resume(struct ath11k_pci *ar_pci); +int ath11k_mhi_suspend(struct ath11k_pci *ar_pci); +int ath11k_mhi_resume(struct ath11k_pci *ar_pci); #endif diff --git a/drivers/net/wireless/ath/ath11k/pci.c b/drivers/net/wireless/ath/ath11k/pci.c index 3fd5b416a5644..024661a170085 100644 --- a/drivers/net/wireless/ath/ath11k/pci.c +++ b/drivers/net/wireless/ath/ath11k/pci.c @@ -619,18 +619,14 @@ static int ath11k_pci_hif_suspend(struct ath11k_base *ab) { struct ath11k_pci *ar_pci = ath11k_pci_priv(ab); - ath11k_mhi_suspend(ar_pci); - - return 0; + return ath11k_mhi_suspend(ar_pci); } static int ath11k_pci_hif_resume(struct ath11k_base *ab) { struct ath11k_pci *ar_pci = ath11k_pci_priv(ab); - ath11k_mhi_resume(ar_pci); - - return 0; + return ath11k_mhi_resume(ar_pci); } static void ath11k_pci_hif_ce_irq_enable(struct ath11k_base *ab) From b9e34ba6b314780a47ac40f450ec04f18be85b5e Mon Sep 17 00:00:00 2001 From: Kalle Valo Date: Tue, 5 Apr 2022 11:26:44 +0300 Subject: [PATCH 073/228] ath11k: mhi: remove unnecessary goto from ath11k_mhi_start() No need to have goto for a return statement, so simplify the code. While at it, print warning messages if power up calls fail. No functional changes. Tested-on: WCN6855 hw2.0 PCI WLAN.HSP.1.1-03003-QCAHSPSWPL_V1_V2_SILICONZ_LITE-2 Signed-off-by: Kalle Valo Link: https://lore.kernel.org/r/20220401173042.17467-4-kvalo@kernel.org --- drivers/net/wireless/ath/ath11k/mhi.c | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-) diff --git a/drivers/net/wireless/ath/ath11k/mhi.c b/drivers/net/wireless/ath/ath11k/mhi.c index defdf641df0b1..c44df17719f64 100644 --- a/drivers/net/wireless/ath/ath11k/mhi.c +++ b/drivers/net/wireless/ath/ath11k/mhi.c @@ -465,22 +465,24 @@ void ath11k_mhi_unregister(struct ath11k_pci *ab_pci) int ath11k_mhi_start(struct ath11k_pci *ab_pci) { + struct ath11k_base *ab = ab_pci->ab; int ret; ab_pci->mhi_ctrl->timeout_ms = MHI_TIMEOUT_DEFAULT_MS; ret = mhi_prepare_for_power_up(ab_pci->mhi_ctrl); - if (ret) - goto out; + if (ret) { + ath11k_warn(ab, "failed to prepare mhi: %d", ret); + return ret; + } ret = mhi_sync_power_up(ab_pci->mhi_ctrl); - if (ret) - goto out; + if (ret) { + ath11k_warn(ab, "failed to power up mhi: %d", ret); + return ret; + } return 0; - -out: - return ret; } void ath11k_mhi_stop(struct ath11k_pci *ab_pci) From 740c431c22fedc2425c9cd263654745b806b6fc7 Mon Sep 17 00:00:00 2001 From: Ping-Ke Shih Date: Fri, 25 Mar 2022 14:00:40 +0800 Subject: [PATCH 074/228] rtw89: pci: add register definition to rtw89_pci_info to generalize pci code The PCI code of 8852AE and 8852CE are different, but the flow and register names are similar. To reuse the code, add a struct to define register or value accordingly. We also use chip id to control the slightly different flow. Signed-off-by: Ping-Ke Shih Signed-off-by: Kalle Valo Link: https://lore.kernel.org/r/20220325060055.58482-2-pkshih@realtek.com --- drivers/net/wireless/realtek/rtw89/pci.c | 138 ++++++++++++++---- drivers/net/wireless/realtek/rtw89/pci.h | 68 +++++++++ drivers/net/wireless/realtek/rtw89/reg.h | 40 +++++ .../net/wireless/realtek/rtw89/rtw8852ae.c | 11 ++ .../net/wireless/realtek/rtw89/rtw8852ce.c | 11 ++ 5 files changed, 238 insertions(+), 30 deletions(-) diff --git a/drivers/net/wireless/realtek/rtw89/pci.c b/drivers/net/wireless/realtek/rtw89/pci.c index 3a27d6f8c6305..2395a29c176f5 100644 --- a/drivers/net/wireless/realtek/rtw89/pci.c +++ b/drivers/net/wireless/realtek/rtw89/pci.c @@ -1426,16 +1426,23 @@ static void rtw89_pci_ops_write32(struct rtw89_dev *rtwdev, u32 addr, u32 data) static void rtw89_pci_ctrl_dma_all(struct rtw89_dev *rtwdev, bool enable) { + enum rtw89_core_chip_id chip_id = rtwdev->chip->chip_id; + const struct rtw89_pci_info *info = rtwdev->pci_info; + u32 txhci_en = info->txhci_en_bit; + u32 rxhci_en = info->rxhci_en_bit; + if (enable) { + if (chip_id != RTL8852C) + rtw89_write32_clr(rtwdev, info->dma_stop1_reg, + B_AX_STOP_PCIEIO); rtw89_write32_set(rtwdev, R_AX_PCIE_INIT_CFG1, - B_AX_TXHCI_EN | B_AX_RXHCI_EN); - rtw89_write32_clr(rtwdev, R_AX_PCIE_DMA_STOP1, - B_AX_STOP_PCIEIO); + txhci_en | rxhci_en); } else { - rtw89_write32_set(rtwdev, R_AX_PCIE_DMA_STOP1, - B_AX_STOP_PCIEIO); + if (chip_id != RTL8852C) + rtw89_write32_set(rtwdev, info->dma_stop1_reg, + B_AX_STOP_PCIEIO); rtw89_write32_clr(rtwdev, R_AX_PCIE_INIT_CFG1, - B_AX_TXHCI_EN | B_AX_RXHCI_EN); + txhci_en | rxhci_en); } } @@ -1500,6 +1507,28 @@ rtw89_write16_mdio(struct rtw89_dev *rtwdev, u8 addr, u16 data, u8 speed) return 0; } +static int +rtw89_write16_mdio_mask(struct rtw89_dev *rtwdev, u8 addr, u16 mask, u16 data, u8 speed) +{ + u32 shift; + int ret; + u16 val; + + ret = rtw89_read16_mdio(rtwdev, addr, speed, &val); + if (!ret) + return ret; + + shift = __ffs(mask); + val &= ~mask; + val |= ((data << shift) & mask); + + ret = rtw89_write16_mdio(rtwdev, addr, val, speed); + if (!ret) + return ret; + + return 0; +} + static int rtw89_write16_mdio_set(struct rtw89_dev *rtwdev, u8 addr, u16 mask, u8 speed) { int ret; @@ -1628,8 +1657,7 @@ static int rtw89_pci_auto_refclk_cal(struct rtw89_dev *rtwdev, bool autook_en) bool l1_flag = false; int ret = 0; - if ((rtwdev->chip->chip_id == RTL8852A && rtwdev->hal.cv == CHIP_CBV) || - rtwdev->chip->chip_id == RTL8852C) + if (rtwdev->chip->chip_id != RTL8852B) return 0; ret = rtw89_pci_read_config_byte(rtwdev, RTW89_PCIE_PHY_RATE, &val8); @@ -1793,12 +1821,15 @@ static int rtw89_pci_deglitch_setting(struct rtw89_dev *rtwdev) static void rtw89_pci_rxdma_prefth(struct rtw89_dev *rtwdev) { + if (rtwdev->chip->chip_id != RTL8852A) + return; + rtw89_write32_set(rtwdev, R_AX_PCIE_INIT_CFG1, B_AX_DIS_RXDMA_PRE); } static void rtw89_pci_l1off_pwroff(struct rtw89_dev *rtwdev) { - if (rtwdev->chip->chip_id == RTL8852C) + if (rtwdev->chip->chip_id != RTL8852A && rtwdev->chip->chip_id != RTL8852B) return; rtw89_write32_clr(rtwdev, R_AX_PCIE_PS_CTRL, B_AX_L1OFF_PWR_OFF_EN); @@ -1808,7 +1839,7 @@ static u32 rtw89_pci_l2_rxen_lat(struct rtw89_dev *rtwdev) { int ret; - if (rtwdev->chip->chip_id == RTL8852C) + if (rtwdev->chip->chip_id != RTL8852A) return 0; ret = rtw89_write16_mdio_clr(rtwdev, RAC_ANA26, B_AX_RXEN, @@ -1843,6 +1874,40 @@ static void rtw89_pci_hci_ldo(struct rtw89_dev *rtwdev) B_AX_PCIE_DIS_WLSUS_AFT_PDN); } +static int rtw89_pci_dphy_delay(struct rtw89_dev *rtwdev) +{ + if (rtwdev->chip->chip_id != RTL8852B) + return 0; + + return rtw89_write16_mdio_mask(rtwdev, RAC_REG_REV2, BAC_CMU_EN_DLY_MASK, + PCIE_DPHY_DLY_25US, PCIE_PHY_GEN1); +} + +static void rtw89_pci_power_wake(struct rtw89_dev *rtwdev, bool pwr_up) +{ + if (pwr_up) + rtw89_write32_set(rtwdev, R_AX_HCI_OPT_CTRL, BIT_WAKE_CTRL); + else + rtw89_write32_clr(rtwdev, R_AX_HCI_OPT_CTRL, BIT_WAKE_CTRL); +} + +static void rtw89_pci_autoload_hang(struct rtw89_dev *rtwdev) +{ + if (rtwdev->chip->chip_id != RTL8852C) + return; + + rtw89_write32_set(rtwdev, R_AX_PCIE_BG_CLR, B_AX_BG_CLR_ASYNC_M3); + rtw89_write32_clr(rtwdev, R_AX_PCIE_BG_CLR, B_AX_BG_CLR_ASYNC_M3); +} + +static void rtw89_pci_l12_vmain(struct rtw89_dev *rtwdev) +{ + if (rtwdev->chip->chip_id != RTL8852C && rtwdev->hal.cv == CHIP_CAV) + return; + + rtw89_write32_set(rtwdev, R_AX_SYS_SDIO_CTRL, B_AX_PCIE_FORCE_PWR_NGAT); +} + static void rtw89_pci_set_sic(struct rtw89_dev *rtwdev) { if (rtwdev->chip->chip_id == RTL8852C) @@ -1867,19 +1932,23 @@ static void rtw89_pci_set_dbg(struct rtw89_dev *rtwdev) static void rtw89_pci_clr_idx_all(struct rtw89_dev *rtwdev) { + const struct rtw89_pci_info *info = rtwdev->pci_info; + enum rtw89_core_chip_id chip_id = rtwdev->chip->chip_id; u32 val = B_AX_CLR_ACH0_IDX | B_AX_CLR_ACH1_IDX | B_AX_CLR_ACH2_IDX | B_AX_CLR_ACH3_IDX | B_AX_CLR_CH8_IDX | B_AX_CLR_CH9_IDX | B_AX_CLR_CH12_IDX; + u32 rxbd_rwptr_clr = info->rxbd_rwptr_clr_reg; + u32 txbd_rwptr_clr2 = info->txbd_rwptr_clr2_reg; - if (rtwdev->chip->chip_id == RTL8852A) + if (chip_id == RTL8852A || chip_id == RTL8852C) val |= B_AX_CLR_ACH4_IDX | B_AX_CLR_ACH5_IDX | B_AX_CLR_ACH6_IDX | B_AX_CLR_ACH7_IDX; /* clear DMA indexes */ rtw89_write32_set(rtwdev, R_AX_TXBD_RWPTR_CLR1, val); - if (rtwdev->chip->chip_id == RTL8852A) - rtw89_write32_set(rtwdev, R_AX_TXBD_RWPTR_CLR2, + if (chip_id == RTL8852A || chip_id == RTL8852C) + rtw89_write32_set(rtwdev, txbd_rwptr_clr2, B_AX_CLR_CH10_IDX | B_AX_CLR_CH11_IDX); - rtw89_write32_set(rtwdev, R_AX_RXBD_RWPTR_CLR, + rtw89_write32_set(rtwdev, rxbd_rwptr_clr, B_AX_CLR_RXQ_IDX | B_AX_CLR_RPQ_IDX); } @@ -1897,6 +1966,7 @@ static int rtw89_pci_ops_deinit(struct rtw89_dev *rtwdev) static int rtw89_pci_ops_mac_pre_init(struct rtw89_dev *rtwdev) { + const struct rtw89_pci_info *info = rtwdev->pci_info; u32 dma_busy; u32 check; u32 lbc; @@ -1913,6 +1983,7 @@ static int rtw89_pci_ops_mac_pre_init(struct rtw89_dev *rtwdev) rtw89_pci_aphy_pwrcut(rtwdev); rtw89_pci_hci_ldo(rtwdev); + rtw89_pci_dphy_delay(rtwdev); ret = rtw89_pci_auto_refclk_cal(rtwdev, false); if (ret) { @@ -1920,21 +1991,26 @@ static int rtw89_pci_ops_mac_pre_init(struct rtw89_dev *rtwdev) return ret; } + rtw89_pci_power_wake(rtwdev, true); + rtw89_pci_autoload_hang(rtwdev); + rtw89_pci_l12_vmain(rtwdev); rtw89_pci_set_sic(rtwdev); rtw89_pci_set_dbg(rtwdev); - if (rtwdev->chip->chip_id == RTL8852A) + if (rtwdev->chip->chip_id == RTL8852A) { rtw89_write32_clr(rtwdev, R_AX_SYS_SDIO_CTRL, B_AX_PCIE_AUXCLK_GATE); - lbc = rtw89_read32(rtwdev, R_AX_LBC_WATCHDOG); - lbc = u32_replace_bits(lbc, RTW89_MAC_LBC_TMR_128US, B_AX_LBC_TIMER); - lbc |= B_AX_LBC_FLAG | B_AX_LBC_EN; - rtw89_write32(rtwdev, R_AX_LBC_WATCHDOG, lbc); + lbc = rtw89_read32(rtwdev, R_AX_LBC_WATCHDOG); + lbc = u32_replace_bits(lbc, RTW89_MAC_LBC_TMR_128US, B_AX_LBC_TIMER); + lbc |= B_AX_LBC_FLAG | B_AX_LBC_EN; + rtw89_write32(rtwdev, R_AX_LBC_WATCHDOG, lbc); - rtw89_write32_set(rtwdev, R_AX_PCIE_INIT_CFG1, - B_AX_PCIE_TXRST_KEEP_REG | B_AX_PCIE_RXRST_KEEP_REG); - rtw89_write32_set(rtwdev, R_AX_PCIE_DMA_STOP1, B_AX_STOP_WPDMA); + rtw89_write32_set(rtwdev, R_AX_PCIE_INIT_CFG1, + B_AX_PCIE_TXRST_KEEP_REG | B_AX_PCIE_RXRST_KEEP_REG); + } + + rtw89_write32_set(rtwdev, info->dma_stop1_reg, B_AX_STOP_WPDMA); /* stop DMA activities */ rtw89_pci_ctrl_dma_all(rtwdev, false); @@ -1975,9 +2051,9 @@ static int rtw89_pci_ops_mac_pre_init(struct rtw89_dev *rtwdev) } /* enable FW CMD queue to download firmware */ - rtw89_write32_set(rtwdev, R_AX_PCIE_DMA_STOP1, B_AX_TX_STOP1_ALL); - rtw89_write32_clr(rtwdev, R_AX_PCIE_DMA_STOP1, B_AX_STOP_CH12); - rtw89_write32_set(rtwdev, R_AX_PCIE_DMA_STOP2, B_AX_TX_STOP2_ALL); + rtw89_write32_set(rtwdev, info->dma_stop1_reg, B_AX_TX_STOP1_ALL); + rtw89_write32_clr(rtwdev, info->dma_stop1_reg, B_AX_STOP_CH12); + rtw89_write32_set(rtwdev, info->dma_stop2_reg, B_AX_TX_STOP2_ALL); /* start DMA activities */ rtw89_pci_ctrl_dma_all(rtwdev, true); @@ -2018,6 +2094,7 @@ static int rtw89_pci_ltr_set(struct rtw89_dev *rtwdev) static int rtw89_pci_ops_mac_post_init(struct rtw89_dev *rtwdev) { + const struct rtw89_pci_info *info = rtwdev->pci_info; int ret; ret = rtw89_pci_ltr_set(rtwdev); @@ -2035,11 +2112,11 @@ static int rtw89_pci_ops_mac_post_init(struct rtw89_dev *rtwdev) rtw89_write32_clr(rtwdev, R_AX_PKTIN_SETTING, B_AX_WD_ADDR_INFO_LENGTH); /* enable DMA for all queues */ - rtw89_write32_clr(rtwdev, R_AX_PCIE_DMA_STOP1, B_AX_TX_STOP1_ALL); - rtw89_write32_clr(rtwdev, R_AX_PCIE_DMA_STOP2, B_AX_TX_STOP2_ALL); + rtw89_write32_clr(rtwdev, info->dma_stop1_reg, B_AX_TX_STOP1_ALL); + rtw89_write32_clr(rtwdev, info->dma_stop2_reg, B_AX_TX_STOP2_ALL); /* Release PCI IO */ - rtw89_write32_clr(rtwdev, R_AX_PCIE_DMA_STOP1, + rtw89_write32_clr(rtwdev, info->dma_stop1_reg, B_AX_STOP_WPDMA | B_AX_STOP_PCIEIO); return 0; @@ -2767,17 +2844,18 @@ static void rtw89_pci_l1ss_cfg(struct rtw89_dev *rtwdev) static void rtw89_pci_ctrl_dma_all_pcie(struct rtw89_dev *rtwdev, u8 en) { + const struct rtw89_pci_info *info = rtwdev->pci_info; u32 val32; if (en == MAC_AX_FUNC_EN) { val32 = B_AX_STOP_PCIEIO; - rtw89_write32_clr(rtwdev, R_AX_PCIE_DMA_STOP1, val32); + rtw89_write32_clr(rtwdev, info->dma_stop1_reg, val32); val32 = B_AX_TXHCI_EN | B_AX_RXHCI_EN; rtw89_write32_set(rtwdev, R_AX_PCIE_INIT_CFG1, val32); } else { val32 = B_AX_STOP_PCIEIO; - rtw89_write32_set(rtwdev, R_AX_PCIE_DMA_STOP1, val32); + rtw89_write32_set(rtwdev, info->dma_stop1_reg, val32); val32 = B_AX_TXHCI_EN | B_AX_RXHCI_EN; rtw89_write32_clr(rtwdev, R_AX_PCIE_INIT_CFG1, val32); diff --git a/drivers/net/wireless/realtek/rtw89/pci.h b/drivers/net/wireless/realtek/rtw89/pci.h index a67595b211853..8eabeaeec045f 100644 --- a/drivers/net/wireless/realtek/rtw89/pci.h +++ b/drivers/net/wireless/realtek/rtw89/pci.h @@ -12,6 +12,9 @@ #define MDIO_PG0_G2 2 #define MDIO_PG1_G2 3 #define RAC_ANA10 0x10 +#define RAC_REG_REV2 0x1B +#define BAC_CMU_EN_DLY_MASK GENMASK(15, 12) +#define PCIE_DPHY_DLY_25US 0x1 #define RAC_ANA19 0x19 #define RAC_ANA1F 0x1F #define RAC_ANA24 0x24 @@ -35,6 +38,48 @@ #define R_AX_MDIO_WDATA 0x10A4 #define R_AX_MDIO_RDATA 0x10A6 +#define R_AX_PCIE_BG_CLR 0x303C +#define B_AX_BG_CLR_ASYNC_M3 BIT(4) + +#define R_AX_PCIE_IO_RCY_M1 0x3100 +#define B_AX_PCIE_IO_RCY_P_M1 BIT(5) +#define B_AX_PCIE_IO_RCY_WDT_P_M1 BIT(4) +#define B_AX_PCIE_IO_RCY_WDT_MODE_M1 BIT(3) +#define B_AX_PCIE_IO_RCY_TRIG_M1 BIT(0) + +#define R_AX_PCIE_WDT_TIMER_M1 0x3104 +#define B_AX_PCIE_WDT_TIMER_M1_MASK GENMASK(31, 0) + +#define R_AX_PCIE_IO_RCY_M2 0x310C +#define B_AX_PCIE_IO_RCY_P_M2 BIT(5) +#define B_AX_PCIE_IO_RCY_WDT_P_M2 BIT(4) +#define B_AX_PCIE_IO_RCY_WDT_MODE_M2 BIT(3) +#define B_AX_PCIE_IO_RCY_TRIG_M2 BIT(0) + +#define R_AX_PCIE_WDT_TIMER_M2 0x3110 +#define B_AX_PCIE_WDT_TIMER_M2_MASK GENMASK(31, 0) + +#define R_AX_PCIE_IO_RCY_E0 0x3118 +#define B_AX_PCIE_IO_RCY_P_E0 BIT(5) +#define B_AX_PCIE_IO_RCY_WDT_P_E0 BIT(4) +#define B_AX_PCIE_IO_RCY_WDT_MODE_E0 BIT(3) +#define B_AX_PCIE_IO_RCY_TRIG_E0 BIT(0) + +#define R_AX_PCIE_WDT_TIMER_E0 0x311C +#define B_AX_PCIE_WDT_TIMER_E0_MASK GENMASK(31, 0) + +#define R_AX_PCIE_IO_RCY_S1 0x3124 +#define B_AX_PCIE_IO_RCY_RP_S1 BIT(7) +#define B_AX_PCIE_IO_RCY_WP_S1 BIT(6) +#define B_AX_PCIE_IO_RCY_WDT_RP_S1 BIT(5) +#define B_AX_PCIE_IO_RCY_WDT_WP_S1 BIT(4) +#define B_AX_PCIE_IO_RCY_WDT_MODE_S1 BIT(3) +#define B_AX_PCIE_IO_RCY_RTRIG_S1 BIT(1) +#define B_AX_PCIE_IO_RCY_WTRIG_S1 BIT(0) + +#define R_AX_PCIE_WDT_TIMER_S1 0x3128 +#define B_AX_PCIE_WDT_TIMER_S1_MASK GENMASK(31, 0) + #define RTW89_PCI_WR_RETRY_CNT 20 /* Interrupts */ @@ -330,6 +375,7 @@ #define R_AX_PCIE_INIT_CFG2 0x1004 #define B_AX_WD_ITVL_IDLE GENMASK(27, 24) #define B_AX_WD_ITVL_ACT GENMASK(19, 16) +#define B_AX_PCIE_RX_APPLEN_MASK GENMASK(13, 0) #define R_AX_PCIE_PS_CTRL 0x1008 #define B_AX_L1OFF_PWR_OFF_EN BIT(5) @@ -356,11 +402,22 @@ #define B_AX_PCIE_TXBD_LEN0 BIT(1) #define B_AX_PCIE_TXBD_4KBOUD_LENERR BIT(0) +#define R_AX_TXBD_RWPTR_CLR2_V1 0x11C4 +#define B_AX_CLR_CH11_IDX BIT(1) +#define B_AX_CLR_CH10_IDX BIT(0) + #define R_AX_LBC_WATCHDOG 0x11D8 #define B_AX_LBC_TIMER GENMASK(7, 4) #define B_AX_LBC_FLAG BIT(1) #define B_AX_LBC_EN BIT(0) +#define R_AX_RXBD_RWPTR_CLR_V1 0x1200 +#define B_AX_CLR_RPQ_IDX BIT(1) +#define B_AX_CLR_RXQ_IDX BIT(0) + +#define R_AX_HAXI_EXP_CTRL 0x1204 +#define B_AX_MAX_TAG_NUM_V1_MASK GENMASK(2, 0) + #define R_AX_PCIE_EXP_CTRL 0x13F0 #define B_AX_EN_CHKDSC_NO_RX_STUCK BIT(20) #define B_AX_MAX_TAG_NUM GENMASK(18, 16) @@ -447,6 +504,17 @@ struct rtw89_pci_ch_dma_addr_set { }; struct rtw89_pci_info { + u32 init_cfg_reg; + u32 txhci_en_bit; + u32 rxhci_en_bit; + u32 rxbd_mode_bit; + u32 exp_ctrl_reg; + u32 max_tag_num_mask; + u32 rxbd_rwptr_clr_reg; + u32 txbd_rwptr_clr2_reg; + u32 dma_stop1_reg; + u32 dma_stop2_reg; + const struct rtw89_pci_ch_dma_addr_set *dma_addr_set; u32 (*fill_txaddr_info)(struct rtw89_dev *rtwdev, diff --git a/drivers/net/wireless/realtek/rtw89/reg.h b/drivers/net/wireless/realtek/rtw89/reg.h index 25b1067881188..f67584efeea9a 100644 --- a/drivers/net/wireless/realtek/rtw89/reg.h +++ b/drivers/net/wireless/realtek/rtw89/reg.h @@ -103,10 +103,14 @@ #define R_AX_SYS_SDIO_CTRL 0x0070 #define B_AX_PCIE_DIS_L2_CTRL_LDO_HCI BIT(15) #define B_AX_PCIE_DIS_WLSUS_AFT_PDN BIT(14) +#define B_AX_PCIE_FORCE_PWR_NGAT BIT(13) #define B_AX_PCIE_CALIB_EN_V1 BIT(12) #define B_AX_PCIE_AUXCLK_GATE BIT(11) #define B_AX_LTE_MUX_CTRL_PATH BIT(26) +#define R_AX_HCI_OPT_CTRL 0x0074 +#define BIT_WAKE_CTRL BIT(5) + #define R_AX_PLATFORM_ENABLE 0x0088 #define B_AX_WCPU_EN BIT(1) #define B_AX_PLATFORM_EN BIT(0) @@ -220,6 +224,38 @@ #define R_AX_FILTER_MODEL_ADDR 0x0C04 +#define R_AX_HAXI_INIT_CFG1 0x1000 +#define B_AX_WD_ITVL_IDLE_V1_MASK GENMASK(31, 28) +#define B_AX_WD_ITVL_ACT_V1_MASK GENMASK(27, 24) +#define B_AX_DMA_MODE_MASK GENMASK(19, 18) +#define DMA_MOD_PCIE_1B 0x0 +#define DMA_MOD_PCIE_4B 0x1 +#define DMA_MOD_USB 0x2 +#define DMA_MOD_SDIO 0x3 +#define B_AX_STOP_AXI_MST BIT(17) +#define B_AX_HAXI_RST_KEEP_REG BIT(16) +#define B_AX_RXHCI_EN_V1 BIT(15) +#define B_AX_RXBD_MODE_V1 BIT(14) +#define B_AX_HAXI_MAX_RXDMA_MASK GENMASK(9, 8) +#define B_AX_TXHCI_EN_V1 BIT(7) +#define B_AX_FLUSH_AXI_MST BIT(4) +#define B_AX_RST_BDRAM BIT(3) +#define B_AX_HAXI_MAX_TXDMA_MASK GENMASK(1, 0) + +#define R_AX_HAXI_DMA_STOP1 0x1010 +#define B_AX_STOP_WPDMA BIT(19) +#define B_AX_STOP_CH12 BIT(18) +#define B_AX_STOP_CH9 BIT(17) +#define B_AX_STOP_CH8 BIT(16) +#define B_AX_STOP_ACH7 BIT(15) +#define B_AX_STOP_ACH6 BIT(14) +#define B_AX_STOP_ACH5 BIT(13) +#define B_AX_STOP_ACH4 BIT(12) +#define B_AX_STOP_ACH3 BIT(11) +#define B_AX_STOP_ACH2 BIT(10) +#define B_AX_STOP_ACH1 BIT(9) +#define B_AX_STOP_ACH0 BIT(8) + #define R_AX_PCIE_DBG_CTRL 0x11C0 #define B_AX_DBG_DUMMY_MASK GENMASK(23, 16) #define B_AX_DBG_SEL_MASK GENMASK(15, 13) @@ -228,6 +264,10 @@ #define B_AX_ASFF_FULL_NO_STK BIT(1) #define B_AX_EN_STUCK_DBG BIT(0) +#define R_AX_HAXI_DMA_STOP2 0x11C0 +#define B_AX_STOP_CH11 BIT(1) +#define B_AX_STOP_CH10 BIT(0) + #define R_AX_HCI_FC_CTRL_V1 0x1700 #define R_AX_CH_PAGE_CTRL_V1 0x1704 diff --git a/drivers/net/wireless/realtek/rtw89/rtw8852ae.c b/drivers/net/wireless/realtek/rtw89/rtw8852ae.c index 8ffc0dd90d41c..b9047ac6b86db 100644 --- a/drivers/net/wireless/realtek/rtw89/rtw8852ae.c +++ b/drivers/net/wireless/realtek/rtw89/rtw8852ae.c @@ -9,6 +9,17 @@ #include "rtw8852a.h" static const struct rtw89_pci_info rtw8852a_pci_info = { + .init_cfg_reg = R_AX_PCIE_INIT_CFG1, + .txhci_en_bit = B_AX_TXHCI_EN, + .rxhci_en_bit = B_AX_RXHCI_EN, + .rxbd_mode_bit = B_AX_RXBD_MODE, + .exp_ctrl_reg = R_AX_PCIE_EXP_CTRL, + .max_tag_num_mask = B_AX_MAX_TAG_NUM, + .rxbd_rwptr_clr_reg = R_AX_RXBD_RWPTR_CLR, + .txbd_rwptr_clr2_reg = R_AX_TXBD_RWPTR_CLR2, + .dma_stop1_reg = R_AX_PCIE_DMA_STOP1, + .dma_stop2_reg = R_AX_PCIE_DMA_STOP2, + .dma_addr_set = &rtw89_pci_ch_dma_addr_set, .fill_txaddr_info = rtw89_pci_fill_txaddr_info, diff --git a/drivers/net/wireless/realtek/rtw89/rtw8852ce.c b/drivers/net/wireless/realtek/rtw89/rtw8852ce.c index 09794836d5c0f..33e69e34e385c 100644 --- a/drivers/net/wireless/realtek/rtw89/rtw8852ce.c +++ b/drivers/net/wireless/realtek/rtw89/rtw8852ce.c @@ -10,6 +10,17 @@ #include "rtw8852c.h" static const struct rtw89_pci_info rtw8852c_pci_info = { + .init_cfg_reg = R_AX_HAXI_INIT_CFG1, + .txhci_en_bit = B_AX_TXHCI_EN_V1, + .rxhci_en_bit = B_AX_RXHCI_EN_V1, + .rxbd_mode_bit = B_AX_RXBD_MODE_V1, + .exp_ctrl_reg = R_AX_HAXI_EXP_CTRL, + .max_tag_num_mask = B_AX_MAX_TAG_NUM_V1_MASK, + .rxbd_rwptr_clr_reg = R_AX_RXBD_RWPTR_CLR_V1, + .txbd_rwptr_clr2_reg = R_AX_TXBD_RWPTR_CLR2_V1, + .dma_stop1_reg = R_AX_HAXI_DMA_STOP1, + .dma_stop2_reg = R_AX_HAXI_DMA_STOP2, + .dma_addr_set = &rtw89_pci_ch_dma_addr_set_v1, .fill_txaddr_info = rtw89_pci_fill_txaddr_info_v1, From b9467e94b1f2c0ade913ad3767cffa310787de5b Mon Sep 17 00:00:00 2001 From: Ping-Ke Shih Date: Fri, 25 Mar 2022 14:00:41 +0800 Subject: [PATCH 075/228] rtw89: pci: add pci attributes to configure operating mode Refine operating mode function to support variant chips. Signed-off-by: Ping-Ke Shih Signed-off-by: Kalle Valo Link: https://lore.kernel.org/r/20220325060055.58482-3-pkshih@realtek.com --- drivers/net/wireless/realtek/rtw89/pci.c | 133 ++++++++++++++++-- drivers/net/wireless/realtek/rtw89/pci.h | 114 +++++++++++++++ .../net/wireless/realtek/rtw89/rtw8852ae.c | 15 ++ .../net/wireless/realtek/rtw89/rtw8852ce.c | 15 ++ 4 files changed, 262 insertions(+), 15 deletions(-) diff --git a/drivers/net/wireless/realtek/rtw89/pci.c b/drivers/net/wireless/realtek/rtw89/pci.c index 2395a29c176f5..e064d355250ce 100644 --- a/drivers/net/wireless/realtek/rtw89/pci.c +++ b/drivers/net/wireless/realtek/rtw89/pci.c @@ -1917,6 +1917,33 @@ static void rtw89_pci_set_sic(struct rtw89_dev *rtwdev) B_AX_SIC_EN_FORCE_CLKREQ); } +static void rtw89_pci_set_io_rcy(struct rtw89_dev *rtwdev) +{ + const struct rtw89_pci_info *info = rtwdev->pci_info; + u32 val32; + + if (rtwdev->chip->chip_id != RTL8852C) + return; + + if (info->io_rcy_en == MAC_AX_PCIE_ENABLE) { + val32 = FIELD_PREP(B_AX_PCIE_WDT_TIMER_M1_MASK, + info->io_rcy_tmr); + rtw89_write32(rtwdev, R_AX_PCIE_WDT_TIMER_M1, val32); + rtw89_write32(rtwdev, R_AX_PCIE_WDT_TIMER_M2, val32); + rtw89_write32(rtwdev, R_AX_PCIE_WDT_TIMER_E0, val32); + + rtw89_write32_set(rtwdev, R_AX_PCIE_IO_RCY_M1, B_AX_PCIE_IO_RCY_WDT_MODE_M1); + rtw89_write32_set(rtwdev, R_AX_PCIE_IO_RCY_M2, B_AX_PCIE_IO_RCY_WDT_MODE_M2); + rtw89_write32_set(rtwdev, R_AX_PCIE_IO_RCY_E0, B_AX_PCIE_IO_RCY_WDT_MODE_E0); + } else { + rtw89_write32_clr(rtwdev, R_AX_PCIE_IO_RCY_M1, B_AX_PCIE_IO_RCY_WDT_MODE_M1); + rtw89_write32_clr(rtwdev, R_AX_PCIE_IO_RCY_M2, B_AX_PCIE_IO_RCY_WDT_MODE_M2); + rtw89_write32_clr(rtwdev, R_AX_PCIE_IO_RCY_E0, B_AX_PCIE_IO_RCY_WDT_MODE_E0); + } + + rtw89_write32_clr(rtwdev, R_AX_PCIE_IO_RCY_S1, B_AX_PCIE_IO_RCY_WDT_MODE_S1); +} + static void rtw89_pci_set_dbg(struct rtw89_dev *rtwdev) { if (rtwdev->chip->chip_id == RTL8852C) @@ -1952,6 +1979,95 @@ static void rtw89_pci_clr_idx_all(struct rtw89_dev *rtwdev) B_AX_CLR_RXQ_IDX | B_AX_CLR_RPQ_IDX); } +static int rtw89_pci_mode_op(struct rtw89_dev *rtwdev) +{ + const struct rtw89_pci_info *info = rtwdev->pci_info; + enum mac_ax_bd_trunc_mode txbd_trunc_mode = info->txbd_trunc_mode; + enum mac_ax_bd_trunc_mode rxbd_trunc_mode = info->rxbd_trunc_mode; + enum mac_ax_rxbd_mode rxbd_mode = info->rxbd_mode; + enum mac_ax_tag_mode tag_mode = info->tag_mode; + enum mac_ax_wd_dma_intvl wd_dma_idle_intvl = info->wd_dma_idle_intvl; + enum mac_ax_wd_dma_intvl wd_dma_act_intvl = info->wd_dma_act_intvl; + enum mac_ax_tx_burst tx_burst = info->tx_burst; + enum mac_ax_rx_burst rx_burst = info->rx_burst; + enum rtw89_core_chip_id chip_id = rtwdev->chip->chip_id; + u8 cv = rtwdev->hal.cv; + u32 val32; + + if (txbd_trunc_mode == MAC_AX_BD_TRUNC) { + if (chip_id == RTL8852A && cv == CHIP_CBV) + rtw89_write32_set(rtwdev, R_AX_PCIE_INIT_CFG1, B_AX_TX_TRUNC_MODE); + } else if (txbd_trunc_mode == MAC_AX_BD_NORM) { + if (chip_id == RTL8852A || chip_id == RTL8852B) + rtw89_write32_clr(rtwdev, R_AX_PCIE_INIT_CFG1, B_AX_TX_TRUNC_MODE); + } + + if (rxbd_trunc_mode == MAC_AX_BD_TRUNC) { + if (chip_id == RTL8852A && cv == CHIP_CBV) + rtw89_write32_set(rtwdev, R_AX_PCIE_INIT_CFG1, B_AX_RX_TRUNC_MODE); + } else if (rxbd_trunc_mode == MAC_AX_BD_NORM) { + if (chip_id == RTL8852A || chip_id == RTL8852B) + rtw89_write32_clr(rtwdev, R_AX_PCIE_INIT_CFG1, B_AX_RX_TRUNC_MODE); + } + + if (rxbd_mode == MAC_AX_RXBD_PKT) { + rtw89_write32_clr(rtwdev, info->init_cfg_reg, info->rxbd_mode_bit); + } else if (rxbd_mode == MAC_AX_RXBD_SEP) { + rtw89_write32_set(rtwdev, info->init_cfg_reg, info->rxbd_mode_bit); + + if (chip_id == RTL8852A || chip_id == RTL8852B) + rtw89_write32_mask(rtwdev, R_AX_PCIE_INIT_CFG2, + B_AX_PCIE_RX_APPLEN_MASK, 0); + } + + if (chip_id == RTL8852A || chip_id == RTL8852B) { + rtw89_write32_mask(rtwdev, R_AX_PCIE_INIT_CFG1, B_AX_PCIE_MAX_TXDMA_MASK, tx_burst); + rtw89_write32_mask(rtwdev, R_AX_PCIE_INIT_CFG1, B_AX_PCIE_MAX_RXDMA_MASK, rx_burst); + } else if (chip_id == RTL8852C) { + rtw89_write32_mask(rtwdev, R_AX_HAXI_INIT_CFG1, B_AX_HAXI_MAX_TXDMA_MASK, tx_burst); + rtw89_write32_mask(rtwdev, R_AX_HAXI_INIT_CFG1, B_AX_HAXI_MAX_RXDMA_MASK, rx_burst); + } + + if (chip_id == RTL8852A || chip_id == RTL8852B) { + if (tag_mode == MAC_AX_TAG_SGL) { + val32 = rtw89_read32(rtwdev, R_AX_PCIE_INIT_CFG1) & + ~B_AX_LATENCY_CONTROL; + rtw89_write32(rtwdev, R_AX_PCIE_INIT_CFG1, val32); + } else if (tag_mode == MAC_AX_TAG_MULTI) { + val32 = rtw89_read32(rtwdev, R_AX_PCIE_INIT_CFG1) | + B_AX_LATENCY_CONTROL; + rtw89_write32(rtwdev, R_AX_PCIE_INIT_CFG1, val32); + } + } + + rtw89_write32_mask(rtwdev, info->exp_ctrl_reg, info->max_tag_num_mask, + info->multi_tag_num); + + if (chip_id == RTL8852A || chip_id == RTL8852B) { + rtw89_write32_mask(rtwdev, R_AX_PCIE_INIT_CFG2, B_AX_WD_ITVL_IDLE, + wd_dma_idle_intvl); + rtw89_write32_mask(rtwdev, R_AX_PCIE_INIT_CFG2, B_AX_WD_ITVL_ACT, + wd_dma_act_intvl); + } else if (chip_id == RTL8852C) { + rtw89_write32_mask(rtwdev, R_AX_HAXI_INIT_CFG1, B_AX_WD_ITVL_IDLE_V1_MASK, + wd_dma_idle_intvl); + rtw89_write32_mask(rtwdev, R_AX_HAXI_INIT_CFG1, B_AX_WD_ITVL_ACT_V1_MASK, + wd_dma_act_intvl); + } + + if (txbd_trunc_mode == MAC_AX_BD_TRUNC) { + rtw89_write32_set(rtwdev, R_AX_TX_ADDRESS_INFO_MODE_SETTING, + B_AX_HOST_ADDR_INFO_8B_SEL); + rtw89_write32_clr(rtwdev, R_AX_PKTIN_SETTING, B_AX_WD_ADDR_INFO_LENGTH); + } else if (txbd_trunc_mode == MAC_AX_BD_NORM) { + rtw89_write32_clr(rtwdev, R_AX_TX_ADDRESS_INFO_MODE_SETTING, + B_AX_HOST_ADDR_INFO_8B_SEL); + rtw89_write32_set(rtwdev, R_AX_PKTIN_SETTING, B_AX_WD_ADDR_INFO_LENGTH); + } + + return 0; +} + static int rtw89_pci_ops_deinit(struct rtw89_dev *rtwdev) { if (rtwdev->chip->chip_id == RTL8852A) { @@ -1995,6 +2111,7 @@ static int rtw89_pci_ops_mac_pre_init(struct rtw89_dev *rtwdev) rtw89_pci_autoload_hang(rtwdev); rtw89_pci_l12_vmain(rtwdev); rtw89_pci_set_sic(rtwdev); + rtw89_pci_set_io_rcy(rtwdev); rtw89_pci_set_dbg(rtwdev); if (rtwdev->chip->chip_id == RTL8852A) { @@ -2025,21 +2142,7 @@ static int rtw89_pci_ops_mac_pre_init(struct rtw89_dev *rtwdev) } rtw89_pci_clr_idx_all(rtwdev); - - /* configure TX/RX op modes */ - rtw89_write32_set(rtwdev, R_AX_PCIE_INIT_CFG1, B_AX_TX_TRUNC_MODE | - B_AX_RX_TRUNC_MODE); - rtw89_write32_clr(rtwdev, R_AX_PCIE_INIT_CFG1, B_AX_RXBD_MODE); - rtw89_write32_mask(rtwdev, R_AX_PCIE_INIT_CFG1, B_AX_PCIE_MAX_TXDMA_MASK, 7); - rtw89_write32_mask(rtwdev, R_AX_PCIE_INIT_CFG1, B_AX_PCIE_MAX_RXDMA_MASK, 3); - /* multi-tag mode */ - rtw89_write32_set(rtwdev, R_AX_PCIE_INIT_CFG1, B_AX_LATENCY_CONTROL); - rtw89_write32_mask(rtwdev, R_AX_PCIE_EXP_CTRL, B_AX_MAX_TAG_NUM, - RTW89_MAC_TAG_NUM_8); - rtw89_write32_mask(rtwdev, R_AX_PCIE_INIT_CFG2, B_AX_WD_ITVL_IDLE, - RTW89_MAC_WD_DMA_INTVL_256NS); - rtw89_write32_mask(rtwdev, R_AX_PCIE_INIT_CFG2, B_AX_WD_ITVL_ACT, - RTW89_MAC_WD_DMA_INTVL_256NS); + rtw89_pci_mode_op(rtwdev); /* fill TRX BD indexes */ rtw89_pci_ops_reset(rtwdev); diff --git a/drivers/net/wireless/realtek/rtw89/pci.h b/drivers/net/wireless/realtek/rtw89/pci.h index 8eabeaeec045f..8d49033fa270e 100644 --- a/drivers/net/wireless/realtek/rtw89/pci.h +++ b/drivers/net/wireless/realtek/rtw89/pci.h @@ -490,6 +490,105 @@ enum rtw89_pcie_clkdly_hw { PCIE_CLKDLY_HW_200US = 0x5, }; +enum mac_ax_bd_trunc_mode { + MAC_AX_BD_NORM, + MAC_AX_BD_TRUNC, + MAC_AX_BD_DEF = 0xFE +}; + +enum mac_ax_rxbd_mode { + MAC_AX_RXBD_PKT, + MAC_AX_RXBD_SEP, + MAC_AX_RXBD_DEF = 0xFE +}; + +enum mac_ax_tag_mode { + MAC_AX_TAG_SGL, + MAC_AX_TAG_MULTI, + MAC_AX_TAG_DEF = 0xFE +}; + +enum mac_ax_tx_burst { + MAC_AX_TX_BURST_16B = 0, + MAC_AX_TX_BURST_32B = 1, + MAC_AX_TX_BURST_64B = 2, + MAC_AX_TX_BURST_V1_64B = 0, + MAC_AX_TX_BURST_128B = 3, + MAC_AX_TX_BURST_V1_128B = 1, + MAC_AX_TX_BURST_256B = 4, + MAC_AX_TX_BURST_V1_256B = 2, + MAC_AX_TX_BURST_512B = 5, + MAC_AX_TX_BURST_1024B = 6, + MAC_AX_TX_BURST_2048B = 7, + MAC_AX_TX_BURST_DEF = 0xFE +}; + +enum mac_ax_rx_burst { + MAC_AX_RX_BURST_16B = 0, + MAC_AX_RX_BURST_32B = 1, + MAC_AX_RX_BURST_64B = 2, + MAC_AX_RX_BURST_V1_64B = 0, + MAC_AX_RX_BURST_128B = 3, + MAC_AX_RX_BURST_V1_128B = 1, + MAC_AX_RX_BURST_V1_256B = 0, + MAC_AX_RX_BURST_DEF = 0xFE +}; + +enum mac_ax_wd_dma_intvl { + MAC_AX_WD_DMA_INTVL_0S, + MAC_AX_WD_DMA_INTVL_256NS, + MAC_AX_WD_DMA_INTVL_512NS, + MAC_AX_WD_DMA_INTVL_768NS, + MAC_AX_WD_DMA_INTVL_1US, + MAC_AX_WD_DMA_INTVL_1_5US, + MAC_AX_WD_DMA_INTVL_2US, + MAC_AX_WD_DMA_INTVL_4US, + MAC_AX_WD_DMA_INTVL_8US, + MAC_AX_WD_DMA_INTVL_16US, + MAC_AX_WD_DMA_INTVL_DEF = 0xFE +}; + +enum mac_ax_multi_tag_num { + MAC_AX_TAG_NUM_1, + MAC_AX_TAG_NUM_2, + MAC_AX_TAG_NUM_3, + MAC_AX_TAG_NUM_4, + MAC_AX_TAG_NUM_5, + MAC_AX_TAG_NUM_6, + MAC_AX_TAG_NUM_7, + MAC_AX_TAG_NUM_8, + MAC_AX_TAG_NUM_DEF = 0xFE +}; + +enum mac_ax_lbc_tmr { + MAC_AX_LBC_TMR_8US = 0, + MAC_AX_LBC_TMR_16US, + MAC_AX_LBC_TMR_32US, + MAC_AX_LBC_TMR_64US, + MAC_AX_LBC_TMR_128US, + MAC_AX_LBC_TMR_256US, + MAC_AX_LBC_TMR_512US, + MAC_AX_LBC_TMR_1MS, + MAC_AX_LBC_TMR_2MS, + MAC_AX_LBC_TMR_4MS, + MAC_AX_LBC_TMR_8MS, + MAC_AX_LBC_TMR_DEF = 0xFE +}; + +enum mac_ax_pcie_func_ctrl { + MAC_AX_PCIE_DISABLE = 0, + MAC_AX_PCIE_ENABLE = 1, + MAC_AX_PCIE_DEFAULT = 0xFE, + MAC_AX_PCIE_IGNORE = 0xFF +}; + +enum mac_ax_io_rcy_tmr { + MAC_AX_IO_RCY_ANA_TMR_2MS = 24000, + MAC_AX_IO_RCY_ANA_TMR_4MS = 48000, + MAC_AX_IO_RCY_ANA_TMR_6MS = 72000, + MAC_AX_IO_RCY_ANA_TMR_DEF = 0xFE +}; + struct rtw89_pci_ch_dma_addr { u32 num; u32 idx; @@ -504,6 +603,21 @@ struct rtw89_pci_ch_dma_addr_set { }; struct rtw89_pci_info { + enum mac_ax_bd_trunc_mode txbd_trunc_mode; + enum mac_ax_bd_trunc_mode rxbd_trunc_mode; + enum mac_ax_rxbd_mode rxbd_mode; + enum mac_ax_tag_mode tag_mode; + enum mac_ax_tx_burst tx_burst; + enum mac_ax_rx_burst rx_burst; + enum mac_ax_wd_dma_intvl wd_dma_idle_intvl; + enum mac_ax_wd_dma_intvl wd_dma_act_intvl; + enum mac_ax_multi_tag_num multi_tag_num; + enum mac_ax_pcie_func_ctrl lbc_en; + enum mac_ax_lbc_tmr lbc_tmr; + enum mac_ax_pcie_func_ctrl autok_en; + enum mac_ax_pcie_func_ctrl io_rcy_en; + enum mac_ax_io_rcy_tmr io_rcy_tmr; + u32 init_cfg_reg; u32 txhci_en_bit; u32 rxhci_en_bit; diff --git a/drivers/net/wireless/realtek/rtw89/rtw8852ae.c b/drivers/net/wireless/realtek/rtw89/rtw8852ae.c index b9047ac6b86db..42dfafb3d7f58 100644 --- a/drivers/net/wireless/realtek/rtw89/rtw8852ae.c +++ b/drivers/net/wireless/realtek/rtw89/rtw8852ae.c @@ -9,6 +9,21 @@ #include "rtw8852a.h" static const struct rtw89_pci_info rtw8852a_pci_info = { + .txbd_trunc_mode = MAC_AX_BD_TRUNC, + .rxbd_trunc_mode = MAC_AX_BD_TRUNC, + .rxbd_mode = MAC_AX_RXBD_PKT, + .tag_mode = MAC_AX_TAG_MULTI, + .tx_burst = MAC_AX_TX_BURST_2048B, + .rx_burst = MAC_AX_RX_BURST_128B, + .wd_dma_idle_intvl = MAC_AX_WD_DMA_INTVL_256NS, + .wd_dma_act_intvl = MAC_AX_WD_DMA_INTVL_256NS, + .multi_tag_num = MAC_AX_TAG_NUM_8, + .lbc_en = MAC_AX_PCIE_ENABLE, + .lbc_tmr = MAC_AX_LBC_TMR_2MS, + .autok_en = MAC_AX_PCIE_DISABLE, + .io_rcy_en = MAC_AX_PCIE_DISABLE, + .io_rcy_tmr = MAC_AX_IO_RCY_ANA_TMR_6MS, + .init_cfg_reg = R_AX_PCIE_INIT_CFG1, .txhci_en_bit = B_AX_TXHCI_EN, .rxhci_en_bit = B_AX_RXHCI_EN, diff --git a/drivers/net/wireless/realtek/rtw89/rtw8852ce.c b/drivers/net/wireless/realtek/rtw89/rtw8852ce.c index 33e69e34e385c..621918465c47f 100644 --- a/drivers/net/wireless/realtek/rtw89/rtw8852ce.c +++ b/drivers/net/wireless/realtek/rtw89/rtw8852ce.c @@ -10,6 +10,21 @@ #include "rtw8852c.h" static const struct rtw89_pci_info rtw8852c_pci_info = { + .txbd_trunc_mode = MAC_AX_BD_TRUNC, + .rxbd_trunc_mode = MAC_AX_BD_TRUNC, + .rxbd_mode = MAC_AX_RXBD_PKT, + .tag_mode = MAC_AX_TAG_MULTI, + .tx_burst = MAC_AX_TX_BURST_V1_256B, + .rx_burst = MAC_AX_RX_BURST_V1_128B, + .wd_dma_idle_intvl = MAC_AX_WD_DMA_INTVL_256NS, + .wd_dma_act_intvl = MAC_AX_WD_DMA_INTVL_256NS, + .multi_tag_num = MAC_AX_TAG_NUM_8, + .lbc_en = MAC_AX_PCIE_ENABLE, + .lbc_tmr = MAC_AX_LBC_TMR_2MS, + .autok_en = MAC_AX_PCIE_DISABLE, + .io_rcy_en = MAC_AX_PCIE_ENABLE, + .io_rcy_tmr = MAC_AX_IO_RCY_ANA_TMR_6MS, + .init_cfg_reg = R_AX_HAXI_INIT_CFG1, .txhci_en_bit = B_AX_TXHCI_EN_V1, .rxhci_en_bit = B_AX_RXHCI_EN_V1, From 1e3f205548155af7df781bb23bed15af17aa8ace Mon Sep 17 00:00:00 2001 From: Chia-Yuan Li Date: Fri, 25 Mar 2022 14:00:42 +0800 Subject: [PATCH 076/228] rtw89: pci: refine pci pre_init function The pre_init is used to initialize partial PCI function during PCI probe. It doesn't need to initialize all functions, so probe can be faster. Signed-off-by: Chia-Yuan Li Signed-off-by: Ping-Ke Shih Signed-off-by: Kalle Valo Link: https://lore.kernel.org/r/20220325060055.58482-4-pkshih@realtek.com --- drivers/net/wireless/realtek/rtw89/pci.c | 158 ++++++++++++++---- drivers/net/wireless/realtek/rtw89/pci.h | 16 ++ drivers/net/wireless/realtek/rtw89/reg.h | 31 ++++ .../net/wireless/realtek/rtw89/rtw8852ae.c | 3 + .../net/wireless/realtek/rtw89/rtw8852ce.c | 3 + 5 files changed, 180 insertions(+), 31 deletions(-) diff --git a/drivers/net/wireless/realtek/rtw89/pci.c b/drivers/net/wireless/realtek/rtw89/pci.c index e064d355250ce..43bb4490380d8 100644 --- a/drivers/net/wireless/realtek/rtw89/pci.c +++ b/drivers/net/wireless/realtek/rtw89/pci.c @@ -1437,12 +1437,19 @@ static void rtw89_pci_ctrl_dma_all(struct rtw89_dev *rtwdev, bool enable) B_AX_STOP_PCIEIO); rtw89_write32_set(rtwdev, R_AX_PCIE_INIT_CFG1, txhci_en | rxhci_en); + if (chip_id == RTL8852C) + rtw89_write32_clr(rtwdev, R_AX_PCIE_INIT_CFG1, + B_AX_STOP_AXI_MST); } else { if (chip_id != RTL8852C) rtw89_write32_set(rtwdev, info->dma_stop1_reg, B_AX_STOP_PCIEIO); - rtw89_write32_clr(rtwdev, R_AX_PCIE_INIT_CFG1, - txhci_en | rxhci_en); + else + rtw89_write32_clr(rtwdev, R_AX_PCIE_INIT_CFG1, + B_AX_STOP_AXI_MST); + if (chip_id == RTL8852C) + rtw89_write32_set(rtwdev, R_AX_PCIE_INIT_CFG1, + B_AX_STOP_AXI_MST); } } @@ -1865,13 +1872,16 @@ static void rtw89_pci_aphy_pwrcut(struct rtw89_dev *rtwdev) static void rtw89_pci_hci_ldo(struct rtw89_dev *rtwdev) { - if (rtwdev->chip->chip_id != RTL8852A) - return; - - rtw89_write32_set(rtwdev, R_AX_SYS_SDIO_CTRL, - B_AX_PCIE_DIS_L2_CTRL_LDO_HCI); - rtw89_write32_clr(rtwdev, R_AX_SYS_SDIO_CTRL, - B_AX_PCIE_DIS_WLSUS_AFT_PDN); + if (rtwdev->chip->chip_id == RTL8852A || + rtwdev->chip->chip_id == RTL8852B) { + rtw89_write32_set(rtwdev, R_AX_SYS_SDIO_CTRL, + B_AX_PCIE_DIS_L2_CTRL_LDO_HCI); + rtw89_write32_clr(rtwdev, R_AX_SYS_SDIO_CTRL, + B_AX_PCIE_DIS_WLSUS_AFT_PDN); + } else if (rtwdev->chip->chip_id == RTL8852C) { + rtw89_write32_clr(rtwdev, R_AX_SYS_SDIO_CTRL, + B_AX_PCIE_DIS_L2_CTRL_LDO_HCI); + } } static int rtw89_pci_dphy_delay(struct rtw89_dev *rtwdev) @@ -1902,12 +1912,24 @@ static void rtw89_pci_autoload_hang(struct rtw89_dev *rtwdev) static void rtw89_pci_l12_vmain(struct rtw89_dev *rtwdev) { - if (rtwdev->chip->chip_id != RTL8852C && rtwdev->hal.cv == CHIP_CAV) + if (!(rtwdev->chip->chip_id == RTL8852C && rtwdev->hal.cv == CHIP_CAV)) return; rtw89_write32_set(rtwdev, R_AX_SYS_SDIO_CTRL, B_AX_PCIE_FORCE_PWR_NGAT); } +static void rtw89_pci_gen2_force_ib(struct rtw89_dev *rtwdev) +{ + if (!(rtwdev->chip->chip_id == RTL8852C && rtwdev->hal.cv == CHIP_CAV)) + return; + + rtw89_write32_set(rtwdev, R_AX_PMC_DBG_CTRL2, + B_AX_SYSON_DIS_PMCR_AX_WRMSK); + rtw89_write32_set(rtwdev, R_AX_HCI_BG_CTRL, B_AX_BG_CLR_ASYNC_M3); + rtw89_write32_clr(rtwdev, R_AX_PMC_DBG_CTRL2, + B_AX_SYSON_DIS_PMCR_AX_WRMSK); +} + static void rtw89_pci_set_sic(struct rtw89_dev *rtwdev) { if (rtwdev->chip->chip_id == RTL8852C) @@ -1917,6 +1939,25 @@ static void rtw89_pci_set_sic(struct rtw89_dev *rtwdev) B_AX_SIC_EN_FORCE_CLKREQ); } +static void rtw89_pci_set_lbc(struct rtw89_dev *rtwdev) +{ + const struct rtw89_pci_info *info = rtwdev->pci_info; + u32 lbc; + + if (rtwdev->chip->chip_id == RTL8852C) + return; + + lbc = rtw89_read32(rtwdev, R_AX_LBC_WATCHDOG); + if (info->lbc_en == MAC_AX_PCIE_ENABLE) { + lbc = u32_replace_bits(lbc, info->lbc_tmr, B_AX_LBC_TIMER); + lbc |= B_AX_LBC_FLAG | B_AX_LBC_EN; + rtw89_write32(rtwdev, R_AX_LBC_WATCHDOG, lbc); + } else { + lbc &= ~B_AX_LBC_EN; + } + rtw89_write32_set(rtwdev, R_AX_LBC_WATCHDOG, lbc); +} + static void rtw89_pci_set_io_rcy(struct rtw89_dev *rtwdev) { const struct rtw89_pci_info *info = rtwdev->pci_info; @@ -1957,6 +1998,15 @@ static void rtw89_pci_set_dbg(struct rtw89_dev *rtwdev) B_AX_EN_CHKDSC_NO_RX_STUCK); } +static void rtw89_pci_set_keep_reg(struct rtw89_dev *rtwdev) +{ + if (rtwdev->chip->chip_id == RTL8852C) + return; + + rtw89_write32_set(rtwdev, R_AX_PCIE_INIT_CFG1, + B_AX_PCIE_TXRST_KEEP_REG | B_AX_PCIE_RXRST_KEEP_REG); +} + static void rtw89_pci_clr_idx_all(struct rtw89_dev *rtwdev) { const struct rtw89_pci_info *info = rtwdev->pci_info; @@ -1979,6 +2029,68 @@ static void rtw89_pci_clr_idx_all(struct rtw89_dev *rtwdev) B_AX_CLR_RXQ_IDX | B_AX_CLR_RPQ_IDX); } +static int rtw89_poll_txdma_ch_idle_pcie(struct rtw89_dev *rtwdev) +{ + const struct rtw89_pci_info *info = rtwdev->pci_info; + u32 ret, check, dma_busy; + u32 dma_busy1 = info->dma_busy1_reg; + u32 dma_busy2 = info->dma_busy2_reg; + + check = B_AX_ACH0_BUSY | B_AX_ACH1_BUSY | B_AX_ACH2_BUSY | + B_AX_ACH3_BUSY | B_AX_ACH4_BUSY | B_AX_ACH5_BUSY | + B_AX_ACH6_BUSY | B_AX_ACH7_BUSY | B_AX_CH8_BUSY | + B_AX_CH9_BUSY | B_AX_CH12_BUSY; + + ret = read_poll_timeout(rtw89_read32, dma_busy, (dma_busy & check) == 0, + 10, 100, false, rtwdev, dma_busy1); + if (ret) + return ret; + + check = B_AX_CH10_BUSY | B_AX_CH11_BUSY; + + ret = read_poll_timeout(rtw89_read32, dma_busy, (dma_busy & check) == 0, + 10, 100, false, rtwdev, dma_busy2); + if (ret) + return ret; + + return 0; +} + +static int rtw89_poll_rxdma_ch_idle_pcie(struct rtw89_dev *rtwdev) +{ + const struct rtw89_pci_info *info = rtwdev->pci_info; + u32 ret, check, dma_busy; + u32 dma_busy3 = info->dma_busy3_reg; + + check = B_AX_RXQ_BUSY | B_AX_RPQ_BUSY; + + ret = read_poll_timeout(rtw89_read32, dma_busy, (dma_busy & check) == 0, + 10, 100, false, rtwdev, dma_busy3); + if (ret) + return ret; + + return 0; +} + +static int rtw89_pci_poll_dma_all_idle(struct rtw89_dev *rtwdev) +{ + u32 ret; + + ret = rtw89_poll_txdma_ch_idle_pcie(rtwdev); + if (ret) { + rtw89_err(rtwdev, "txdma ch busy\n"); + return ret; + } + + ret = rtw89_poll_rxdma_ch_idle_pcie(rtwdev); + if (ret) { + rtw89_err(rtwdev, "rxdma ch busy\n"); + return ret; + } + + return 0; +} + static int rtw89_pci_mode_op(struct rtw89_dev *rtwdev) { const struct rtw89_pci_info *info = rtwdev->pci_info; @@ -2083,9 +2195,6 @@ static int rtw89_pci_ops_deinit(struct rtw89_dev *rtwdev) static int rtw89_pci_ops_mac_pre_init(struct rtw89_dev *rtwdev) { const struct rtw89_pci_info *info = rtwdev->pci_info; - u32 dma_busy; - u32 check; - u32 lbc; int ret; rtw89_pci_rxdma_prefth(rtwdev); @@ -2110,34 +2219,21 @@ static int rtw89_pci_ops_mac_pre_init(struct rtw89_dev *rtwdev) rtw89_pci_power_wake(rtwdev, true); rtw89_pci_autoload_hang(rtwdev); rtw89_pci_l12_vmain(rtwdev); + rtw89_pci_gen2_force_ib(rtwdev); rtw89_pci_set_sic(rtwdev); + rtw89_pci_set_lbc(rtwdev); rtw89_pci_set_io_rcy(rtwdev); rtw89_pci_set_dbg(rtwdev); - - if (rtwdev->chip->chip_id == RTL8852A) { - rtw89_write32_clr(rtwdev, R_AX_SYS_SDIO_CTRL, - B_AX_PCIE_AUXCLK_GATE); - - lbc = rtw89_read32(rtwdev, R_AX_LBC_WATCHDOG); - lbc = u32_replace_bits(lbc, RTW89_MAC_LBC_TMR_128US, B_AX_LBC_TIMER); - lbc |= B_AX_LBC_FLAG | B_AX_LBC_EN; - rtw89_write32(rtwdev, R_AX_LBC_WATCHDOG, lbc); - - rtw89_write32_set(rtwdev, R_AX_PCIE_INIT_CFG1, - B_AX_PCIE_TXRST_KEEP_REG | B_AX_PCIE_RXRST_KEEP_REG); - } + rtw89_pci_set_keep_reg(rtwdev); rtw89_write32_set(rtwdev, info->dma_stop1_reg, B_AX_STOP_WPDMA); /* stop DMA activities */ rtw89_pci_ctrl_dma_all(rtwdev, false); - /* check PCI at idle state */ - check = B_AX_PCIEIO_BUSY | B_AX_PCIEIO_TX_BUSY | B_AX_PCIEIO_RX_BUSY; - ret = read_poll_timeout(rtw89_read32, dma_busy, (dma_busy & check) == 0, - 100, 3000, false, rtwdev, R_AX_PCIE_DMA_BUSY1); + ret = rtw89_pci_poll_dma_all_idle(rtwdev); if (ret) { - rtw89_err(rtwdev, "failed to poll io busy\n"); + rtw89_err(rtwdev, "[ERR] poll pcie dma all idle\n"); return ret; } diff --git a/drivers/net/wireless/realtek/rtw89/pci.h b/drivers/net/wireless/realtek/rtw89/pci.h index 8d49033fa270e..2e8695208fccb 100644 --- a/drivers/net/wireless/realtek/rtw89/pci.h +++ b/drivers/net/wireless/realtek/rtw89/pci.h @@ -366,6 +366,19 @@ #define B_AX_PCIEIO_TX_BUSY BIT(21) #define B_AX_PCIEIO_BUSY BIT(20) #define B_AX_WPDMA_BUSY BIT(19) +#define B_AX_CH12_BUSY BIT(18) +#define B_AX_CH9_BUSY BIT(17) +#define B_AX_CH8_BUSY BIT(16) +#define B_AX_ACH7_BUSY BIT(15) +#define B_AX_ACH6_BUSY BIT(14) +#define B_AX_ACH5_BUSY BIT(13) +#define B_AX_ACH4_BUSY BIT(12) +#define B_AX_ACH3_BUSY BIT(11) +#define B_AX_ACH2_BUSY BIT(10) +#define B_AX_ACH1_BUSY BIT(9) +#define B_AX_ACH0_BUSY BIT(8) +#define B_AX_RPQ_BUSY BIT(1) +#define B_AX_RXQ_BUSY BIT(0) #define R_AX_PCIE_DMA_BUSY2 0x131C #define B_AX_CH11_BUSY BIT(1) @@ -628,6 +641,9 @@ struct rtw89_pci_info { u32 txbd_rwptr_clr2_reg; u32 dma_stop1_reg; u32 dma_stop2_reg; + u32 dma_busy1_reg; + u32 dma_busy2_reg; + u32 dma_busy3_reg; const struct rtw89_pci_ch_dma_addr_set *dma_addr_set; diff --git a/drivers/net/wireless/realtek/rtw89/reg.h b/drivers/net/wireless/realtek/rtw89/reg.h index f67584efeea9a..6cda6dcb5d867 100644 --- a/drivers/net/wireless/realtek/rtw89/reg.h +++ b/drivers/net/wireless/realtek/rtw89/reg.h @@ -111,6 +111,14 @@ #define R_AX_HCI_OPT_CTRL 0x0074 #define BIT_WAKE_CTRL BIT(5) +#define R_AX_HCI_BG_CTRL 0x0078 +#define B_AX_IBX_EN_VALUE BIT(15) +#define B_AX_IB_EN_VALUE BIT(14) +#define B_AX_FORCED_IB_EN BIT(4) +#define B_AX_EN_REGBG BIT(3) +#define B_AX_R_AX_BG_LPF BIT(2) +#define B_AX_R_AX_BG GENMASK(1, 0) + #define R_AX_PLATFORM_ENABLE 0x0088 #define B_AX_WCPU_EN BIT(1) #define B_AX_PLATFORM_EN BIT(0) @@ -256,6 +264,21 @@ #define B_AX_STOP_ACH1 BIT(9) #define B_AX_STOP_ACH0 BIT(8) +#define R_AX_HAXI_DMA_BUSY1 0x101C +#define B_AX_HAXIIO_BUSY BIT(20) +#define B_AX_WPDMA_BUSY BIT(19) +#define B_AX_CH12_BUSY BIT(18) +#define B_AX_CH9_BUSY BIT(17) +#define B_AX_CH8_BUSY BIT(16) +#define B_AX_ACH7_BUSY BIT(15) +#define B_AX_ACH6_BUSY BIT(14) +#define B_AX_ACH5_BUSY BIT(13) +#define B_AX_ACH4_BUSY BIT(12) +#define B_AX_ACH3_BUSY BIT(11) +#define B_AX_ACH2_BUSY BIT(10) +#define B_AX_ACH1_BUSY BIT(9) +#define B_AX_ACH0_BUSY BIT(8) + #define R_AX_PCIE_DBG_CTRL 0x11C0 #define B_AX_DBG_DUMMY_MASK GENMASK(23, 16) #define B_AX_DBG_SEL_MASK GENMASK(15, 13) @@ -268,6 +291,14 @@ #define B_AX_STOP_CH11 BIT(1) #define B_AX_STOP_CH10 BIT(0) +#define R_AX_HAXI_DMA_BUSY2 0x11C8 +#define B_AX_CH11_BUSY BIT(1) +#define B_AX_CH10_BUSY BIT(0) + +#define R_AX_HAXI_DMA_BUSY3 0x1208 +#define B_AX_RPQ_BUSY BIT(1) +#define B_AX_RXQ_BUSY BIT(0) + #define R_AX_HCI_FC_CTRL_V1 0x1700 #define R_AX_CH_PAGE_CTRL_V1 0x1704 diff --git a/drivers/net/wireless/realtek/rtw89/rtw8852ae.c b/drivers/net/wireless/realtek/rtw89/rtw8852ae.c index 42dfafb3d7f58..6055e8b9887f5 100644 --- a/drivers/net/wireless/realtek/rtw89/rtw8852ae.c +++ b/drivers/net/wireless/realtek/rtw89/rtw8852ae.c @@ -34,6 +34,9 @@ static const struct rtw89_pci_info rtw8852a_pci_info = { .txbd_rwptr_clr2_reg = R_AX_TXBD_RWPTR_CLR2, .dma_stop1_reg = R_AX_PCIE_DMA_STOP1, .dma_stop2_reg = R_AX_PCIE_DMA_STOP2, + .dma_busy1_reg = R_AX_PCIE_DMA_BUSY1, + .dma_busy2_reg = R_AX_PCIE_DMA_BUSY2, + .dma_busy3_reg = R_AX_PCIE_DMA_BUSY1, .dma_addr_set = &rtw89_pci_ch_dma_addr_set, diff --git a/drivers/net/wireless/realtek/rtw89/rtw8852ce.c b/drivers/net/wireless/realtek/rtw89/rtw8852ce.c index 621918465c47f..dca023e791016 100644 --- a/drivers/net/wireless/realtek/rtw89/rtw8852ce.c +++ b/drivers/net/wireless/realtek/rtw89/rtw8852ce.c @@ -35,6 +35,9 @@ static const struct rtw89_pci_info rtw8852c_pci_info = { .txbd_rwptr_clr2_reg = R_AX_TXBD_RWPTR_CLR2_V1, .dma_stop1_reg = R_AX_HAXI_DMA_STOP1, .dma_stop2_reg = R_AX_HAXI_DMA_STOP2, + .dma_busy1_reg = R_AX_HAXI_DMA_BUSY1, + .dma_busy2_reg = R_AX_HAXI_DMA_BUSY2, + .dma_busy3_reg = R_AX_HAXI_DMA_BUSY3, .dma_addr_set = &rtw89_pci_ch_dma_addr_set_v1, From 0db862fb025c933675e3efb388eb96da781d6365 Mon Sep 17 00:00:00 2001 From: Ping-Ke Shih Date: Fri, 25 Mar 2022 14:00:43 +0800 Subject: [PATCH 077/228] rtw89: pci: add LTR setting for v1 chip Add LTR handle to PCI deinit as well. Signed-off-by: Ping-Ke Shih Signed-off-by: Kalle Valo Link: https://lore.kernel.org/r/20220325060055.58482-5-pkshih@realtek.com --- drivers/net/wireless/realtek/rtw89/pci.c | 58 ++++++++++++++++++- drivers/net/wireless/realtek/rtw89/pci.h | 3 + drivers/net/wireless/realtek/rtw89/reg.h | 22 +++++++ .../net/wireless/realtek/rtw89/rtw8852ae.c | 1 + .../net/wireless/realtek/rtw89/rtw8852ce.c | 1 + 5 files changed, 83 insertions(+), 2 deletions(-) diff --git a/drivers/net/wireless/realtek/rtw89/pci.c b/drivers/net/wireless/realtek/rtw89/pci.c index 43bb4490380d8..2fd746d6987c1 100644 --- a/drivers/net/wireless/realtek/rtw89/pci.c +++ b/drivers/net/wireless/realtek/rtw89/pci.c @@ -2182,10 +2182,13 @@ static int rtw89_pci_mode_op(struct rtw89_dev *rtwdev) static int rtw89_pci_ops_deinit(struct rtw89_dev *rtwdev) { + const struct rtw89_pci_info *info = rtwdev->pci_info; + if (rtwdev->chip->chip_id == RTL8852A) { /* ltr sw trigger */ rtw89_write32_set(rtwdev, R_AX_LTR_CTRL_0, B_AX_APP_LTR_IDLE); } + info->ltr_set(rtwdev, false); rtw89_pci_ctrl_dma_all(rtwdev, false); rtw89_pci_clr_idx_all(rtwdev); @@ -2260,10 +2263,13 @@ static int rtw89_pci_ops_mac_pre_init(struct rtw89_dev *rtwdev) return 0; } -static int rtw89_pci_ltr_set(struct rtw89_dev *rtwdev) +int rtw89_pci_ltr_set(struct rtw89_dev *rtwdev, bool en) { u32 val; + if (!en) + return 0; + val = rtw89_read32(rtwdev, R_AX_LTR_CTRL_0); if (rtw89_pci_ltr_is_err_reg_val(val)) return -EINVAL; @@ -2290,13 +2296,61 @@ static int rtw89_pci_ltr_set(struct rtw89_dev *rtwdev) return 0; } +EXPORT_SYMBOL(rtw89_pci_ltr_set); + +int rtw89_pci_ltr_set_v1(struct rtw89_dev *rtwdev, bool en) +{ + u32 dec_ctrl; + u32 val32; + + val32 = rtw89_read32(rtwdev, R_AX_LTR_CTRL_0); + if (rtw89_pci_ltr_is_err_reg_val(val32)) + return -EINVAL; + val32 = rtw89_read32(rtwdev, R_AX_LTR_CTRL_1); + if (rtw89_pci_ltr_is_err_reg_val(val32)) + return -EINVAL; + dec_ctrl = rtw89_read32(rtwdev, R_AX_LTR_DEC_CTRL); + if (rtw89_pci_ltr_is_err_reg_val(dec_ctrl)) + return -EINVAL; + val32 = rtw89_read32(rtwdev, R_AX_LTR_LATENCY_IDX3); + if (rtw89_pci_ltr_is_err_reg_val(val32)) + return -EINVAL; + val32 = rtw89_read32(rtwdev, R_AX_LTR_LATENCY_IDX0); + if (rtw89_pci_ltr_is_err_reg_val(val32)) + return -EINVAL; + + if (!en) { + dec_ctrl &= ~(LTR_EN_BITS | B_AX_LTR_IDX_DRV_MASK | B_AX_LTR_HW_DEC_EN); + dec_ctrl |= FIELD_PREP(B_AX_LTR_IDX_DRV_MASK, PCIE_LTR_IDX_IDLE) | + B_AX_LTR_REQ_DRV; + } else { + dec_ctrl |= B_AX_LTR_HW_DEC_EN; + } + + dec_ctrl &= ~B_AX_LTR_SPACE_IDX_V1_MASK; + dec_ctrl |= FIELD_PREP(B_AX_LTR_SPACE_IDX_V1_MASK, PCI_LTR_SPC_500US); + + if (en) + rtw89_write32_set(rtwdev, R_AX_LTR_CTRL_0, + B_AX_LTR_WD_NOEMP_CHK_V1 | B_AX_LTR_HW_EN); + rtw89_write32_mask(rtwdev, R_AX_LTR_CTRL_0, B_AX_LTR_IDLE_TIMER_IDX_MASK, + PCI_LTR_IDLE_TIMER_3_2MS); + rtw89_write32_mask(rtwdev, R_AX_LTR_CTRL_1, B_AX_LTR_RX0_TH_MASK, 0x28); + rtw89_write32_mask(rtwdev, R_AX_LTR_CTRL_1, B_AX_LTR_RX1_TH_MASK, 0x28); + rtw89_write32(rtwdev, R_AX_LTR_DEC_CTRL, dec_ctrl); + rtw89_write32(rtwdev, R_AX_LTR_LATENCY_IDX3, 0x90039003); + rtw89_write32(rtwdev, R_AX_LTR_LATENCY_IDX0, 0x880b880b); + + return 0; +} +EXPORT_SYMBOL(rtw89_pci_ltr_set_v1); static int rtw89_pci_ops_mac_post_init(struct rtw89_dev *rtwdev) { const struct rtw89_pci_info *info = rtwdev->pci_info; int ret; - ret = rtw89_pci_ltr_set(rtwdev); + ret = info->ltr_set(rtwdev, true); if (ret) { rtw89_err(rtwdev, "pci ltr set fail\n"); return ret; diff --git a/drivers/net/wireless/realtek/rtw89/pci.h b/drivers/net/wireless/realtek/rtw89/pci.h index 2e8695208fccb..99f0cd2f47da2 100644 --- a/drivers/net/wireless/realtek/rtw89/pci.h +++ b/drivers/net/wireless/realtek/rtw89/pci.h @@ -647,6 +647,7 @@ struct rtw89_pci_info { const struct rtw89_pci_ch_dma_addr_set *dma_addr_set; + int (*ltr_set)(struct rtw89_dev *rtwdev, bool en); u32 (*fill_txaddr_info)(struct rtw89_dev *rtwdev, void *txaddr_info_addr, u32 total_len, dma_addr_t dma, u8 *add_info_nr); @@ -912,6 +913,8 @@ struct pci_device_id; int rtw89_pci_probe(struct pci_dev *pdev, const struct pci_device_id *id); void rtw89_pci_remove(struct pci_dev *pdev); +int rtw89_pci_ltr_set(struct rtw89_dev *rtwdev, bool en); +int rtw89_pci_ltr_set_v1(struct rtw89_dev *rtwdev, bool en); u32 rtw89_pci_fill_txaddr_info(struct rtw89_dev *rtwdev, void *txaddr_info_addr, u32 total_len, dma_addr_t dma, u8 *add_info_nr); diff --git a/drivers/net/wireless/realtek/rtw89/reg.h b/drivers/net/wireless/realtek/rtw89/reg.h index 6cda6dcb5d867..21a451264e504 100644 --- a/drivers/net/wireless/realtek/rtw89/reg.h +++ b/drivers/net/wireless/realtek/rtw89/reg.h @@ -299,6 +299,27 @@ #define B_AX_RPQ_BUSY BIT(1) #define B_AX_RXQ_BUSY BIT(0) +#define R_AX_LTR_DEC_CTRL 0x1600 +#define B_AX_LTR_IDX_DRV_VLD BIT(16) +#define B_AX_LTR_CURR_IDX_DRV_MASK GENMASK(15, 14) +#define B_AX_LTR_IDX_FW_VLD BIT(13) +#define B_AX_LTR_CURR_IDX_FW_MASK GENMASK(12, 11) +#define B_AX_LTR_IDX_HW_VLD BIT(10) +#define B_AX_LTR_CURR_IDX_HW_MASK GENMASK(9, 8) +#define B_AX_LTR_REQ_DRV BIT(7) +#define B_AX_LTR_IDX_DRV_MASK GENMASK(6, 5) +#define PCIE_LTR_IDX_IDLE 3 +#define B_AX_LTR_DRV_DEC_EN BIT(4) +#define B_AX_LTR_FW_DEC_EN BIT(3) +#define B_AX_LTR_HW_DEC_EN BIT(2) +#define B_AX_LTR_SPACE_IDX_V1_MASK GENMASK(1, 0) +#define LTR_EN_BITS (B_AX_LTR_HW_DEC_EN | B_AX_LTR_FW_DEC_EN | B_AX_LTR_DRV_DEC_EN) + +#define R_AX_LTR_LATENCY_IDX0 0x1604 +#define R_AX_LTR_LATENCY_IDX1 0x1608 +#define R_AX_LTR_LATENCY_IDX2 0x160C +#define R_AX_LTR_LATENCY_IDX3 0x1610 + #define R_AX_HCI_FC_CTRL_V1 0x1700 #define R_AX_CH_PAGE_CTRL_V1 0x1704 @@ -440,6 +461,7 @@ #define B_AX_APP_LTR_ACT BIT(5) #define B_AX_APP_LTR_IDLE BIT(4) #define B_AX_LTR_EN BIT(1) +#define B_AX_LTR_WD_NOEMP_CHK_V1 BIT(1) #define B_AX_LTR_HW_EN BIT(0) #define R_AX_LTR_CTRL_1 0x8414 diff --git a/drivers/net/wireless/realtek/rtw89/rtw8852ae.c b/drivers/net/wireless/realtek/rtw89/rtw8852ae.c index 6055e8b9887f5..61a1693535d8a 100644 --- a/drivers/net/wireless/realtek/rtw89/rtw8852ae.c +++ b/drivers/net/wireless/realtek/rtw89/rtw8852ae.c @@ -40,6 +40,7 @@ static const struct rtw89_pci_info rtw8852a_pci_info = { .dma_addr_set = &rtw89_pci_ch_dma_addr_set, + .ltr_set = rtw89_pci_ltr_set, .fill_txaddr_info = rtw89_pci_fill_txaddr_info, }; diff --git a/drivers/net/wireless/realtek/rtw89/rtw8852ce.c b/drivers/net/wireless/realtek/rtw89/rtw8852ce.c index dca023e791016..aeafac553f404 100644 --- a/drivers/net/wireless/realtek/rtw89/rtw8852ce.c +++ b/drivers/net/wireless/realtek/rtw89/rtw8852ce.c @@ -41,6 +41,7 @@ static const struct rtw89_pci_info rtw8852c_pci_info = { .dma_addr_set = &rtw89_pci_ch_dma_addr_set_v1, + .ltr_set = rtw89_pci_ltr_set_v1, .fill_txaddr_info = rtw89_pci_fill_txaddr_info_v1, }; From bab9e239178679db33d0cca8e14ce448419a3078 Mon Sep 17 00:00:00 2001 From: Ping-Ke Shih Date: Fri, 25 Mar 2022 14:00:44 +0800 Subject: [PATCH 078/228] rtw89: pci: set address info registers depends on chips Address info registers are used to configure size of DMA address info to point skb->data. With different size, it can support different number of scatters. Signed-off-by: Ping-Ke Shih Signed-off-by: Kalle Valo Link: https://lore.kernel.org/r/20220325060055.58482-6-pkshih@realtek.com --- drivers/net/wireless/realtek/rtw89/pci.c | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/drivers/net/wireless/realtek/rtw89/pci.c b/drivers/net/wireless/realtek/rtw89/pci.c index 2fd746d6987c1..25d385be6e862 100644 --- a/drivers/net/wireless/realtek/rtw89/pci.c +++ b/drivers/net/wireless/realtek/rtw89/pci.c @@ -2348,6 +2348,7 @@ EXPORT_SYMBOL(rtw89_pci_ltr_set_v1); static int rtw89_pci_ops_mac_post_init(struct rtw89_dev *rtwdev) { const struct rtw89_pci_info *info = rtwdev->pci_info; + enum rtw89_core_chip_id chip_id = rtwdev->chip->chip_id; int ret; ret = info->ltr_set(rtwdev, true); @@ -2355,14 +2356,16 @@ static int rtw89_pci_ops_mac_post_init(struct rtw89_dev *rtwdev) rtw89_err(rtwdev, "pci ltr set fail\n"); return ret; } - if (rtwdev->chip->chip_id == RTL8852A) { + if (chip_id == RTL8852A) { /* ltr sw trigger */ rtw89_write32_set(rtwdev, R_AX_LTR_CTRL_0, B_AX_APP_LTR_ACT); } - /* ADDR info 8-byte mode */ - rtw89_write32_set(rtwdev, R_AX_TX_ADDRESS_INFO_MODE_SETTING, - B_AX_HOST_ADDR_INFO_8B_SEL); - rtw89_write32_clr(rtwdev, R_AX_PKTIN_SETTING, B_AX_WD_ADDR_INFO_LENGTH); + if (chip_id == RTL8852A || chip_id == RTL8852B) { + /* ADDR info 8-byte mode */ + rtw89_write32_set(rtwdev, R_AX_TX_ADDRESS_INFO_MODE_SETTING, + B_AX_HOST_ADDR_INFO_8B_SEL); + rtw89_write32_clr(rtwdev, R_AX_PKTIN_SETTING, B_AX_WD_ADDR_INFO_LENGTH); + } /* enable DMA for all queues */ rtw89_write32_clr(rtwdev, info->dma_stop1_reg, B_AX_TX_STOP1_ALL); From 22a66e7c3abe48237853239b2184751cf97aca07 Mon Sep 17 00:00:00 2001 From: Ping-Ke Shih Date: Fri, 25 Mar 2022 14:00:45 +0800 Subject: [PATCH 079/228] rtw89: pci: add deglitch setting Add setting to support 8852ce. Signed-off-by: Ping-Ke Shih Signed-off-by: Kalle Valo Link: https://lore.kernel.org/r/20220325060055.58482-7-pkshih@realtek.com --- drivers/net/wireless/realtek/rtw89/pci.c | 27 ++++++++++++++---------- drivers/net/wireless/realtek/rtw89/pci.h | 3 +++ 2 files changed, 19 insertions(+), 11 deletions(-) diff --git a/drivers/net/wireless/realtek/rtw89/pci.c b/drivers/net/wireless/realtek/rtw89/pci.c index 25d385be6e862..5112b2d443c3e 100644 --- a/drivers/net/wireless/realtek/rtw89/pci.c +++ b/drivers/net/wireless/realtek/rtw89/pci.c @@ -1809,19 +1809,24 @@ static int rtw89_pci_auto_refclk_cal(struct rtw89_dev *rtwdev, bool autook_en) static int rtw89_pci_deglitch_setting(struct rtw89_dev *rtwdev) { + enum rtw89_core_chip_id chip_id = rtwdev->chip->chip_id; int ret; - if (rtwdev->chip->chip_id != RTL8852A) - return 0; - - ret = rtw89_write16_mdio_clr(rtwdev, RAC_ANA24, B_AX_DEGLITCH, - PCIE_PHY_GEN1); - if (ret) - return ret; - ret = rtw89_write16_mdio_clr(rtwdev, RAC_ANA24, B_AX_DEGLITCH, - PCIE_PHY_GEN2); - if (ret) - return ret; + if (chip_id == RTL8852A) { + ret = rtw89_write16_mdio_clr(rtwdev, RAC_ANA24, B_AX_DEGLITCH, + PCIE_PHY_GEN1); + if (ret) + return ret; + ret = rtw89_write16_mdio_clr(rtwdev, RAC_ANA24, B_AX_DEGLITCH, + PCIE_PHY_GEN2); + if (ret) + return ret; + } else if (chip_id == RTL8852C) { + rtw89_write16_clr(rtwdev, R_RAC_DIRECT_OFFSET_G1 + RAC_ANA24 * 2, + B_AX_DEGLITCH); + rtw89_write16_clr(rtwdev, R_RAC_DIRECT_OFFSET_G2 + RAC_ANA24 * 2, + B_AX_DEGLITCH); + } return 0; } diff --git a/drivers/net/wireless/realtek/rtw89/pci.h b/drivers/net/wireless/realtek/rtw89/pci.h index 99f0cd2f47da2..805fc3e8c1a4a 100644 --- a/drivers/net/wireless/realtek/rtw89/pci.h +++ b/drivers/net/wireless/realtek/rtw89/pci.h @@ -80,6 +80,9 @@ #define R_AX_PCIE_WDT_TIMER_S1 0x3128 #define B_AX_PCIE_WDT_TIMER_S1_MASK GENMASK(31, 0) +#define R_RAC_DIRECT_OFFSET_G1 0x3800 +#define R_RAC_DIRECT_OFFSET_G2 0x3880 + #define RTW89_PCI_WR_RETRY_CNT 20 /* Interrupts */ From e1e7a574b20ff3ce474c67ef6dfbc715d0870e9a Mon Sep 17 00:00:00 2001 From: Ping-Ke Shih Date: Fri, 25 Mar 2022 14:00:46 +0800 Subject: [PATCH 080/228] rtw89: pci: add L1 settings Configure L1 settings of enter and exit. Signed-off-by: Ping-Ke Shih Signed-off-by: Kalle Valo Link: https://lore.kernel.org/r/20220325060055.58482-8-pkshih@realtek.com --- drivers/net/wireless/realtek/rtw89/pci.c | 18 ++++++++++++++++++ drivers/net/wireless/realtek/rtw89/pci.h | 7 +++++++ 2 files changed, 25 insertions(+) diff --git a/drivers/net/wireless/realtek/rtw89/pci.c b/drivers/net/wireless/realtek/rtw89/pci.c index 5112b2d443c3e..dcf907b81cffa 100644 --- a/drivers/net/wireless/realtek/rtw89/pci.c +++ b/drivers/net/wireless/realtek/rtw89/pci.c @@ -1935,6 +1935,22 @@ static void rtw89_pci_gen2_force_ib(struct rtw89_dev *rtwdev) B_AX_SYSON_DIS_PMCR_AX_WRMSK); } +static void rtw89_pci_l1_ent_lat(struct rtw89_dev *rtwdev) +{ + if (rtwdev->chip->chip_id != RTL8852C) + return; + + rtw89_write32_clr(rtwdev, R_AX_PCIE_PS_CTRL_V1, B_AX_SEL_REQ_ENTR_L1); +} + +static void rtw89_pci_wd_exit_l1(struct rtw89_dev *rtwdev) +{ + if (rtwdev->chip->chip_id != RTL8852C) + return; + + rtw89_write32_set(rtwdev, R_AX_PCIE_PS_CTRL_V1, B_AX_DMAC0_EXIT_L1_EN); +} + static void rtw89_pci_set_sic(struct rtw89_dev *rtwdev) { if (rtwdev->chip->chip_id == RTL8852C) @@ -2228,6 +2244,8 @@ static int rtw89_pci_ops_mac_pre_init(struct rtw89_dev *rtwdev) rtw89_pci_autoload_hang(rtwdev); rtw89_pci_l12_vmain(rtwdev); rtw89_pci_gen2_force_ib(rtwdev); + rtw89_pci_l1_ent_lat(rtwdev); + rtw89_pci_wd_exit_l1(rtwdev); rtw89_pci_set_sic(rtwdev); rtw89_pci_set_lbc(rtwdev); rtw89_pci_set_io_rcy(rtwdev); diff --git a/drivers/net/wireless/realtek/rtw89/pci.h b/drivers/net/wireless/realtek/rtw89/pci.h index 805fc3e8c1a4a..a085d1f27a120 100644 --- a/drivers/net/wireless/realtek/rtw89/pci.h +++ b/drivers/net/wireless/realtek/rtw89/pci.h @@ -38,6 +38,13 @@ #define R_AX_MDIO_WDATA 0x10A4 #define R_AX_MDIO_RDATA 0x10A6 +#define R_AX_PCIE_PS_CTRL_V1 0x3008 +#define B_AX_CMAC_EXIT_L1_EN BIT(7) +#define B_AX_DMAC0_EXIT_L1_EN BIT(6) +#define B_AX_SEL_XFER_PENDING BIT(3) +#define B_AX_SEL_REQ_ENTR_L1 BIT(2) +#define B_AX_SEL_REQ_EXIT_L1 BIT(0) + #define R_AX_PCIE_BG_CLR 0x303C #define B_AX_BG_CLR_ASYNC_M3 BIT(4) From a7d82a7aae656089c478b5ccf83ede38d49ac223 Mon Sep 17 00:00:00 2001 From: Ping-Ke Shih Date: Fri, 25 Mar 2022 14:00:47 +0800 Subject: [PATCH 081/228] rtw89: extend dmac_pre_init to support 8852C DMAC is short for data MAC. 8852C has more settings than 8852A, so add them. Signed-off-by: Ping-Ke Shih Signed-off-by: Kalle Valo Link: https://lore.kernel.org/r/20220325060055.58482-9-pkshih@realtek.com --- drivers/net/wireless/realtek/rtw89/mac.c | 37 +++++++++++++++++++----- drivers/net/wireless/realtek/rtw89/reg.h | 1 + 2 files changed, 31 insertions(+), 7 deletions(-) diff --git a/drivers/net/wireless/realtek/rtw89/mac.c b/drivers/net/wireless/realtek/rtw89/mac.c index d751054413727..66122d6961512 100644 --- a/drivers/net/wireless/realtek/rtw89/mac.c +++ b/drivers/net/wireless/realtek/rtw89/mac.c @@ -2756,18 +2756,41 @@ static int rtw89_mac_enable_cpu(struct rtw89_dev *rtwdev, u8 boot_reason, return 0; } -static int rtw89_mac_fw_dl_pre_init(struct rtw89_dev *rtwdev) +static int rtw89_mac_dmac_pre_init(struct rtw89_dev *rtwdev) { + enum rtw89_core_chip_id chip_id = rtwdev->chip->chip_id; u32 val; int ret; - val = B_AX_MAC_FUNC_EN | B_AX_DMAC_FUNC_EN | B_AX_DISPATCHER_EN | - B_AX_PKT_BUF_EN; + if (chip_id == RTL8852C) + val = B_AX_MAC_FUNC_EN | B_AX_DMAC_FUNC_EN | B_AX_DISPATCHER_EN | + B_AX_PKT_BUF_EN | B_AX_H_AXIDMA_EN; + else + val = B_AX_MAC_FUNC_EN | B_AX_DMAC_FUNC_EN | B_AX_DISPATCHER_EN | + B_AX_PKT_BUF_EN; rtw89_write32(rtwdev, R_AX_DMAC_FUNC_EN, val); val = B_AX_DISPATCHER_CLK_EN; rtw89_write32(rtwdev, R_AX_DMAC_CLK_EN, val); + if (chip_id != RTL8852C) + goto dle; + + val = rtw89_read32(rtwdev, R_AX_HAXI_INIT_CFG1); + val &= ~(B_AX_DMA_MODE_MASK | B_AX_STOP_AXI_MST); + val |= FIELD_PREP(B_AX_DMA_MODE_MASK, DMA_MOD_PCIE_1B) | + B_AX_TXHCI_EN_V1 | B_AX_RXHCI_EN_V1; + rtw89_write32(rtwdev, R_AX_HAXI_INIT_CFG1, val); + + rtw89_write32_clr(rtwdev, R_AX_HAXI_DMA_STOP1, + B_AX_STOP_ACH0 | B_AX_STOP_ACH1 | B_AX_STOP_ACH3 | + B_AX_STOP_ACH4 | B_AX_STOP_ACH5 | B_AX_STOP_ACH6 | + B_AX_STOP_ACH7 | B_AX_STOP_CH8 | B_AX_STOP_CH9 | + B_AX_STOP_CH12 | B_AX_STOP_ACH2); + rtw89_write32_clr(rtwdev, R_AX_HAXI_DMA_STOP2, B_AX_STOP_CH10 | B_AX_STOP_CH11); + rtw89_write32_set(rtwdev, R_AX_PLATFORM_ENABLE, B_AX_AXIDMA_EN); + +dle: ret = dle_init(rtwdev, RTW89_QTA_DLFW, rtwdev->mac.qta_mode); if (ret) { rtw89_err(rtwdev, "[ERR]DLE pre init %d\n", ret); @@ -2825,16 +2848,16 @@ int rtw89_mac_partial_init(struct rtw89_dev *rtwdev) rtw89_mac_hci_func_en(rtwdev); + ret = rtw89_mac_dmac_pre_init(rtwdev); + if (ret) + return ret; + if (rtwdev->hci.ops->mac_pre_init) { ret = rtwdev->hci.ops->mac_pre_init(rtwdev); if (ret) return ret; } - ret = rtw89_mac_fw_dl_pre_init(rtwdev); - if (ret) - return ret; - rtw89_mac_disable_cpu(rtwdev); ret = rtw89_mac_enable_cpu(rtwdev, 0, true); if (ret) diff --git a/drivers/net/wireless/realtek/rtw89/reg.h b/drivers/net/wireless/realtek/rtw89/reg.h index 21a451264e504..9d9554d28ab6a 100644 --- a/drivers/net/wireless/realtek/rtw89/reg.h +++ b/drivers/net/wireless/realtek/rtw89/reg.h @@ -120,6 +120,7 @@ #define B_AX_R_AX_BG GENMASK(1, 0) #define R_AX_PLATFORM_ENABLE 0x0088 +#define B_AX_AXIDMA_EN BIT(3) #define B_AX_WCPU_EN BIT(1) #define B_AX_PLATFORM_EN BIT(0) From cf7b8b8088111d32a16c31f01be2438e8d411c7a Mon Sep 17 00:00:00 2001 From: Ping-Ke Shih Date: Fri, 25 Mar 2022 14:00:48 +0800 Subject: [PATCH 082/228] rtw89: update STA scheduler parameters for v1 chip The v1 chip has additional setting of STA scheduler, so add it. Signed-off-by: Ping-Ke Shih Signed-off-by: Kalle Valo Link: https://lore.kernel.org/r/20220325060055.58482-10-pkshih@realtek.com --- drivers/net/wireless/realtek/rtw89/mac.c | 16 +++++++++++++++- drivers/net/wireless/realtek/rtw89/reg.h | 9 +++++++++ 2 files changed, 24 insertions(+), 1 deletion(-) diff --git a/drivers/net/wireless/realtek/rtw89/mac.c b/drivers/net/wireless/realtek/rtw89/mac.c index 66122d6961512..b43c947afa611 100644 --- a/drivers/net/wireless/realtek/rtw89/mac.c +++ b/drivers/net/wireless/realtek/rtw89/mac.c @@ -1560,6 +1560,17 @@ static bool dle_is_txq_empty(struct rtw89_dev *rtwdev) return false; } +static void _patch_ss2f_path(struct rtw89_dev *rtwdev) +{ + const struct rtw89_chip_info *chip = rtwdev->chip; + + if (chip->chip_id == RTL8852A || chip->chip_id == RTL8852B) + return; + + rtw89_write32_mask(rtwdev, R_AX_SS2FINFO_PATH, B_AX_SS_DEST_QUEUE_MASK, + SS2F_PATH_WLCPU); +} + static int sta_sch_init(struct rtw89_dev *rtwdev) { u32 p_val; @@ -1581,7 +1592,10 @@ static int sta_sch_init(struct rtw89_dev *rtwdev) return ret; } - rtw89_write32_set(rtwdev, R_AX_SS_CTRL, B_AX_SS_WARM_INIT_FLG); + rtw89_write32_set(rtwdev, R_AX_SS_CTRL, B_AX_SS_WARM_INIT_FLG | + B_AX_SS_NONEMPTY_SS2FINFO_EN); + + _patch_ss2f_path(rtwdev); return 0; } diff --git a/drivers/net/wireless/realtek/rtw89/reg.h b/drivers/net/wireless/realtek/rtw89/reg.h index 9d9554d28ab6a..fd9874137af72 100644 --- a/drivers/net/wireless/realtek/rtw89/reg.h +++ b/drivers/net/wireless/realtek/rtw89/reg.h @@ -801,8 +801,17 @@ #define R_AX_SS_CTRL 0x9E10 #define B_AX_SS_INIT_DONE_1 BIT(31) #define B_AX_SS_WARM_INIT_FLG BIT(29) +#define B_AX_SS_NONEMPTY_SS2FINFO_EN BIT(28) #define B_AX_SS_EN BIT(0) +#define R_AX_SS2FINFO_PATH 0x9E50 +#define B_AX_SS_UL_REL BIT(31) +#define B_AX_SS_REL_QUEUE_MASK GENMASK(29, 24) +#define B_AX_SS_REL_PORT_MASK GENMASK(18, 16) +#define B_AX_SS_DEST_QUEUE_MASK GENMASK(13, 8) +#define SS2F_PATH_WLCPU 0x0A +#define B_AX_SS_DEST_PORT_MASK GENMASK(2, 0) + #define R_AX_SS_MACID_PAUSE_0 0x9EB0 #define B_AX_SS_MACID31_0_PAUSE_SH 0 #define B_AX_SS_MACID31_0_PAUSE_MASK GENMASK(31, 0) From 61ebeecb3d670f1e37e20095ff2504960404538f Mon Sep 17 00:00:00 2001 From: Ping-Ke Shih Date: Fri, 25 Mar 2022 14:00:49 +0800 Subject: [PATCH 083/228] rtw89: add chip_ops::{enable,disable}_bb_rf to support v1 chip The v1 chip use specific functions to enable and disable BB/RF. Signed-off-by: Ping-Ke Shih Signed-off-by: Kalle Valo Link: https://lore.kernel.org/r/20220325060055.58482-11-pkshih@realtek.com --- drivers/net/wireless/realtek/rtw89/core.c | 7 ++- drivers/net/wireless/realtek/rtw89/core.h | 2 + drivers/net/wireless/realtek/rtw89/mac.c | 10 ++++- drivers/net/wireless/realtek/rtw89/mac.h | 19 +++++++- drivers/net/wireless/realtek/rtw89/reg.h | 6 +++ drivers/net/wireless/realtek/rtw89/rtw8852a.c | 2 + drivers/net/wireless/realtek/rtw89/rtw8852c.c | 45 +++++++++++++++++++ 7 files changed, 86 insertions(+), 5 deletions(-) diff --git a/drivers/net/wireless/realtek/rtw89/core.c b/drivers/net/wireless/realtek/rtw89/core.c index d923e4a0f963b..f540ee34fc2c0 100644 --- a/drivers/net/wireless/realtek/rtw89/core.c +++ b/drivers/net/wireless/realtek/rtw89/core.c @@ -2706,8 +2706,11 @@ int rtw89_core_start(struct rtw89_dev *rtwdev) /* efuse process */ /* pre-config BB/RF, BB reset/RFC reset */ - rtw89_mac_disable_bb_rf(rtwdev); - rtw89_mac_enable_bb_rf(rtwdev); + rtw89_chip_disable_bb_rf(rtwdev); + ret = rtw89_chip_enable_bb_rf(rtwdev); + if (ret) + return ret; + rtw89_phy_init_bb_reg(rtwdev); rtw89_phy_init_rf_reg(rtwdev); diff --git a/drivers/net/wireless/realtek/rtw89/core.h b/drivers/net/wireless/realtek/rtw89/core.h index 9f53d581a48f9..ee2edd9e9173a 100644 --- a/drivers/net/wireless/realtek/rtw89/core.h +++ b/drivers/net/wireless/realtek/rtw89/core.h @@ -2059,6 +2059,8 @@ struct rtw89_hci_info { }; struct rtw89_chip_ops { + int (*enable_bb_rf)(struct rtw89_dev *rtwdev); + void (*disable_bb_rf)(struct rtw89_dev *rtwdev); void (*bb_reset)(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy_idx); void (*bb_sethw)(struct rtw89_dev *rtwdev); diff --git a/drivers/net/wireless/realtek/rtw89/mac.c b/drivers/net/wireless/realtek/rtw89/mac.c index b43c947afa611..280db2f3f89b0 100644 --- a/drivers/net/wireless/realtek/rtw89/mac.c +++ b/drivers/net/wireless/realtek/rtw89/mac.c @@ -2828,7 +2828,7 @@ static void rtw89_mac_hci_func_en(struct rtw89_dev *rtwdev) B_AX_HCI_TXDMA_EN | B_AX_HCI_RXDMA_EN); } -void rtw89_mac_enable_bb_rf(struct rtw89_dev *rtwdev) +int rtw89_mac_enable_bb_rf(struct rtw89_dev *rtwdev) { rtw89_write8_set(rtwdev, R_AX_SYS_FUNC_EN, B_AX_FEN_BBRSTB | B_AX_FEN_BB_GLB_RSTN); @@ -2836,7 +2836,10 @@ void rtw89_mac_enable_bb_rf(struct rtw89_dev *rtwdev) B_AX_WLRF1_CTRL_7 | B_AX_WLRF1_CTRL_1 | B_AX_WLRF_CTRL_7 | B_AX_WLRF_CTRL_1); rtw89_write8_set(rtwdev, R_AX_PHYREG_SET, PHYREG_SET_ALL_CYCLE); + + return 0; } +EXPORT_SYMBOL(rtw89_mac_enable_bb_rf); void rtw89_mac_disable_bb_rf(struct rtw89_dev *rtwdev) { @@ -2847,6 +2850,7 @@ void rtw89_mac_disable_bb_rf(struct rtw89_dev *rtwdev) B_AX_WLRF_CTRL_7 | B_AX_WLRF_CTRL_1); rtw89_write8_clr(rtwdev, R_AX_PHYREG_SET, PHYREG_SET_ALL_CYCLE); } +EXPORT_SYMBOL(rtw89_mac_disable_bb_rf); int rtw89_mac_partial_init(struct rtw89_dev *rtwdev) { @@ -2892,7 +2896,9 @@ int rtw89_mac_init(struct rtw89_dev *rtwdev) if (ret) goto fail; - rtw89_mac_enable_bb_rf(rtwdev); + ret = rtw89_chip_enable_bb_rf(rtwdev); + if (ret) + goto fail; ret = rtw89_mac_sys_init(rtwdev); if (ret) diff --git a/drivers/net/wireless/realtek/rtw89/mac.h b/drivers/net/wireless/realtek/rtw89/mac.h index 6edeb1aafaf7d..de65d9becb056 100644 --- a/drivers/net/wireless/realtek/rtw89/mac.h +++ b/drivers/net/wireless/realtek/rtw89/mac.h @@ -797,8 +797,23 @@ int rtw89_mac_read_lte(struct rtw89_dev *rtwdev, const u32 offset, u32 *val); int rtw89_mac_add_vif(struct rtw89_dev *rtwdev, struct rtw89_vif *vif); int rtw89_mac_port_update(struct rtw89_dev *rtwdev, struct rtw89_vif *rtwvif); int rtw89_mac_remove_vif(struct rtw89_dev *rtwdev, struct rtw89_vif *vif); -void rtw89_mac_enable_bb_rf(struct rtw89_dev *rtwdev); +int rtw89_mac_enable_bb_rf(struct rtw89_dev *rtwdev); void rtw89_mac_disable_bb_rf(struct rtw89_dev *rtwdev); + +static inline int rtw89_chip_enable_bb_rf(struct rtw89_dev *rtwdev) +{ + const struct rtw89_chip_info *chip = rtwdev->chip; + + return chip->ops->enable_bb_rf(rtwdev); +} + +static inline void rtw89_chip_disable_bb_rf(struct rtw89_dev *rtwdev) +{ + const struct rtw89_chip_info *chip = rtwdev->chip; + + chip->ops->disable_bb_rf(rtwdev); +} + u32 rtw89_mac_get_err_status(struct rtw89_dev *rtwdev); int rtw89_mac_set_err_status(struct rtw89_dev *rtwdev, u32 err); void rtw89_mac_c2h_handle(struct rtw89_dev *rtwdev, struct sk_buff *skb, @@ -903,6 +918,8 @@ int rtw89_mac_get_tx_retry_limit(struct rtw89_dev *rtwdev, struct rtw89_sta *rtwsta, u8 *tx_retry); enum rtw89_mac_xtal_si_offset { + XTAL0 = 0x0, + XTAL3 = 0x3, XTAL_SI_XTAL_SC_XI = 0x04, #define XTAL_SC_XI_MASK GENMASK(7, 0) XTAL_SI_XTAL_SC_XO = 0x05, diff --git a/drivers/net/wireless/realtek/rtw89/reg.h b/drivers/net/wireless/realtek/rtw89/reg.h index fd9874137af72..1f4cf30f3822b 100644 --- a/drivers/net/wireless/realtek/rtw89/reg.h +++ b/drivers/net/wireless/realtek/rtw89/reg.h @@ -218,6 +218,7 @@ #define B_AX_EECS_PULL_LOW_EN BIT(16) #define R_AX_WLRF_CTRL 0x02F0 +#define B_AX_AFC_AFEDIG BIT(17) #define B_AX_WLRF1_CTRL_7 BIT(15) #define B_AX_WLRF1_CTRL_1 BIT(9) #define B_AX_WLRF_CTRL_7 BIT(7) @@ -231,6 +232,11 @@ #define B_AX_USB_HCISYS_PWR_STE_MASK GENMASK(3, 2) #define B_AX_PCIE_HCISYS_PWR_STE_MASK GENMASK(1, 0) +#define R_AX_AFE_OFF_CTRL1 0x0444 +#define B_AX_S1_LDO_VSEL_F_MASK GENMASK(25, 24) +#define B_AX_S1_LDO2PWRCUT_F BIT(23) +#define B_AX_S0_LDO_VSEL_F_MASK GENMASK(22, 21) + #define R_AX_FILTER_MODEL_ADDR 0x0C04 #define R_AX_HAXI_INIT_CFG1 0x1000 diff --git a/drivers/net/wireless/realtek/rtw89/rtw8852a.c b/drivers/net/wireless/realtek/rtw89/rtw8852a.c index a8b972d4bee8a..501631b1f0416 100644 --- a/drivers/net/wireless/realtek/rtw89/rtw8852a.c +++ b/drivers/net/wireless/realtek/rtw89/rtw8852a.c @@ -1997,6 +1997,8 @@ static void rtw8852a_query_ppdu(struct rtw89_dev *rtwdev, } static const struct rtw89_chip_ops rtw8852a_chip_ops = { + .enable_bb_rf = rtw89_mac_enable_bb_rf, + .disable_bb_rf = rtw89_mac_disable_bb_rf, .bb_reset = rtw8852a_bb_reset, .bb_sethw = rtw8852a_bb_sethw, .read_rf = rtw89_phy_read_rf, diff --git a/drivers/net/wireless/realtek/rtw89/rtw8852c.c b/drivers/net/wireless/realtek/rtw89/rtw8852c.c index 4773f6c739dc0..5dbb711defc40 100644 --- a/drivers/net/wireless/realtek/rtw89/rtw8852c.c +++ b/drivers/net/wireless/realtek/rtw89/rtw8852c.c @@ -483,7 +483,52 @@ void rtw8852c_set_txpwr_ul_tb_offset(struct rtw89_dev *rtwdev, } } +static int rtw8852c_mac_enable_bb_rf(struct rtw89_dev *rtwdev) +{ + int ret; + + rtw89_write8_set(rtwdev, R_AX_SYS_FUNC_EN, + B_AX_FEN_BBRSTB | B_AX_FEN_BB_GLB_RSTN); + + rtw89_write32_set(rtwdev, R_AX_WLRF_CTRL, B_AX_AFC_AFEDIG); + rtw89_write32_clr(rtwdev, R_AX_WLRF_CTRL, B_AX_AFC_AFEDIG); + rtw89_write32_set(rtwdev, R_AX_WLRF_CTRL, B_AX_AFC_AFEDIG); + + rtw89_write32_mask(rtwdev, R_AX_AFE_OFF_CTRL1, B_AX_S0_LDO_VSEL_F_MASK, 0x1); + rtw89_write32_mask(rtwdev, R_AX_AFE_OFF_CTRL1, B_AX_S1_LDO_VSEL_F_MASK, 0x1); + + ret = rtw89_mac_write_xtal_si(rtwdev, XTAL0, 0x7, FULL_BIT_MASK); + if (ret) + return ret; + + ret = rtw89_mac_write_xtal_si(rtwdev, XTAL_SI_ANAPAR_WL, 0x6c, FULL_BIT_MASK); + if (ret) + return ret; + + ret = rtw89_mac_write_xtal_si(rtwdev, XTAL_SI_WL_RFC_S0, 0xc7, FULL_BIT_MASK); + if (ret) + return ret; + + ret = rtw89_mac_write_xtal_si(rtwdev, XTAL_SI_WL_RFC_S1, 0xc7, FULL_BIT_MASK); + if (ret) + return ret; + + ret = rtw89_mac_write_xtal_si(rtwdev, XTAL3, 0xd, FULL_BIT_MASK); + if (ret) + return ret; + + return 0; +} + +static void rtw8852c_mac_disable_bb_rf(struct rtw89_dev *rtwdev) +{ + rtw89_write8_clr(rtwdev, R_AX_SYS_FUNC_EN, + B_AX_FEN_BBRSTB | B_AX_FEN_BB_GLB_RSTN); +} + static const struct rtw89_chip_ops rtw8852c_chip_ops = { + .enable_bb_rf = rtw8852c_mac_enable_bb_rf, + .disable_bb_rf = rtw8852c_mac_disable_bb_rf, .read_efuse = rtw8852c_read_efuse, .read_phycap = rtw8852c_read_phycap, .power_trim = rtw8852c_power_trim, From 5cb5562d2a21637d1aa23791bec1e45368494ba4 Mon Sep 17 00:00:00 2001 From: Ping-Ke Shih Date: Fri, 25 Mar 2022 14:00:50 +0800 Subject: [PATCH 084/228] rtw89: Turn on CR protection of CMAC CMAC is Control MAC, and this patch is to turn on CR (control registers) protection. Signed-off-by: Ping-Ke Shih Signed-off-by: Kalle Valo Link: https://lore.kernel.org/r/20220325060055.58482-12-pkshih@realtek.com --- drivers/net/wireless/realtek/rtw89/mac.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/drivers/net/wireless/realtek/rtw89/mac.c b/drivers/net/wireless/realtek/rtw89/mac.c index 280db2f3f89b0..6498df52ace9d 100644 --- a/drivers/net/wireless/realtek/rtw89/mac.c +++ b/drivers/net/wireless/realtek/rtw89/mac.c @@ -1114,7 +1114,8 @@ static int cmac_func_en(struct rtw89_dev *rtwdev, u8 mac_idx, bool en) func_en = B_AX_CMAC_EN | B_AX_CMAC_TXEN | B_AX_CMAC_RXEN | B_AX_PHYINTF_EN | B_AX_CMAC_DMA_EN | B_AX_PTCLTOP_EN | - B_AX_SCHEDULER_EN | B_AX_TMAC_EN | B_AX_RMAC_EN; + B_AX_SCHEDULER_EN | B_AX_TMAC_EN | B_AX_RMAC_EN | + B_AX_CMAC_CRPRT; ck_en = B_AX_CMAC_CKEN | B_AX_PHYINTF_CKEN | B_AX_CMAC_DMA_CKEN | B_AX_PTCLTOP_CKEN | B_AX_SCHEDULER_CKEN | B_AX_TMAC_CKEN | B_AX_RMAC_CKEN; From b61adeed5409380479b3a9b43113348c26881342 Mon Sep 17 00:00:00 2001 From: Ping-Ke Shih Date: Fri, 25 Mar 2022 14:00:51 +0800 Subject: [PATCH 085/228] rtw89: 8852c: update security engine setting The security setting of 8852A and 8852C are different, so change the settings accordingly. Signed-off-by: Ping-Ke Shih Signed-off-by: Kalle Valo Link: https://lore.kernel.org/r/20220325060055.58482-13-pkshih@realtek.com --- drivers/net/wireless/realtek/rtw89/mac.c | 8 +++++++- drivers/net/wireless/realtek/rtw89/reg.h | 3 +++ 2 files changed, 10 insertions(+), 1 deletion(-) diff --git a/drivers/net/wireless/realtek/rtw89/mac.c b/drivers/net/wireless/realtek/rtw89/mac.c index 6498df52ace9d..8e6d45979fde3 100644 --- a/drivers/net/wireless/realtek/rtw89/mac.c +++ b/drivers/net/wireless/realtek/rtw89/mac.c @@ -1620,6 +1620,7 @@ static int mpdu_proc_init(struct rtw89_dev *rtwdev) static int sec_eng_init(struct rtw89_dev *rtwdev) { + const struct rtw89_chip_info *chip = rtwdev->chip; u32 val = 0; int ret; @@ -1633,7 +1634,8 @@ static int sec_eng_init(struct rtw89_dev *rtwdev) /* init TX encryption */ val |= (B_AX_SEC_TX_ENC | B_AX_SEC_RX_DEC); val |= (B_AX_MC_DEC | B_AX_BC_DEC); - val &= ~B_AX_TX_PARTIAL_MODE; + if (chip->chip_id == RTL8852A || chip->chip_id == RTL8852B) + val &= ~B_AX_TX_PARTIAL_MODE; rtw89_write32(rtwdev, R_AX_SEC_ENG_CTRL, val); /* init MIC ICV append */ @@ -1643,6 +1645,10 @@ static int sec_eng_init(struct rtw89_dev *rtwdev) /* option init */ rtw89_write32(rtwdev, R_AX_SEC_MPDU_PROC, val); + if (chip->chip_id == RTL8852C) + rtw89_write32_mask(rtwdev, R_AX_SEC_DEBUG1, + B_AX_TX_TIMEOUT_SEL_MASK, AX_TX_TO_VAL); + return 0; } diff --git a/drivers/net/wireless/realtek/rtw89/reg.h b/drivers/net/wireless/realtek/rtw89/reg.h index 1f4cf30f3822b..3505c9dd8a793 100644 --- a/drivers/net/wireless/realtek/rtw89/reg.h +++ b/drivers/net/wireless/realtek/rtw89/reg.h @@ -799,6 +799,9 @@ #define R_AX_SEC_CAM_RDATA 0x9D14 #define R_AX_SEC_CAM_WDATA 0x9D18 #define R_AX_SEC_DEBUG 0x9D1C +#define R_AX_SEC_DEBUG1 0x9D1C +#define B_AX_TX_TIMEOUT_SEL_MASK GENMASK(31, 30) +#define AX_TX_TO_VAL 0x2 #define R_AX_SEC_TX_DEBUG 0x9D20 #define R_AX_SEC_RX_DEBUG 0x9D24 #define R_AX_SEC_TRX_PKT_CNT 0x9D28 From c49154ff8bcb995467b23c50afcee74c11265547 Mon Sep 17 00:00:00 2001 From: Ping-Ke Shih Date: Fri, 25 Mar 2022 14:00:52 +0800 Subject: [PATCH 086/228] rtw89: update scheduler setting Update IC specific settings accordingly. Signed-off-by: Ping-Ke Shih Signed-off-by: Kalle Valo Link: https://lore.kernel.org/r/20220325060055.58482-14-pkshih@realtek.com --- drivers/net/wireless/realtek/rtw89/mac.c | 11 +++++++++++ drivers/net/wireless/realtek/rtw89/reg.h | 12 ++++++++++++ 2 files changed, 23 insertions(+) diff --git a/drivers/net/wireless/realtek/rtw89/mac.c b/drivers/net/wireless/realtek/rtw89/mac.c index 8e6d45979fde3..16a97bcb8d480 100644 --- a/drivers/net/wireless/realtek/rtw89/mac.c +++ b/drivers/net/wireless/realtek/rtw89/mac.c @@ -1731,6 +1731,17 @@ static int scheduler_init(struct rtw89_dev *rtwdev, u8 mac_idx) if (ret) return ret; + reg = rtw89_mac_reg_by_idx(R_AX_PREBKF_CFG_1, mac_idx); + rtw89_write32_mask(rtwdev, reg, B_AX_SIFS_MACTXEN_T1_MASK, SIFS_MACTXEN_T1); + + if (rtwdev->chip->chip_id == RTL8852B) { + reg = rtw89_mac_reg_by_idx(R_AX_SCH_EXT_CTRL, mac_idx); + rtw89_write32_set(rtwdev, reg, B_AX_PORT_RST_TSF_ADV); + } + + reg = rtw89_mac_reg_by_idx(R_AX_CCA_CFG_0, mac_idx); + rtw89_write32_clr(rtwdev, reg, B_AX_BTCCA_EN); + reg = rtw89_mac_reg_by_idx(R_AX_PREBKF_CFG_0, mac_idx); rtw89_write32_mask(rtwdev, reg, B_AX_PREBKF_TIME_MASK, SCH_PREBKF_24US); diff --git a/drivers/net/wireless/realtek/rtw89/reg.h b/drivers/net/wireless/realtek/rtw89/reg.h index 3505c9dd8a793..dea7d2c8547be 100644 --- a/drivers/net/wireless/realtek/rtw89/reg.h +++ b/drivers/net/wireless/realtek/rtw89/reg.h @@ -977,6 +977,14 @@ #define R_AX_PREBKF_CFG_0_C1 0xE338 #define B_AX_PREBKF_TIME_MASK GENMASK(4, 0) +#define R_AX_PREBKF_CFG_1 0xC33C +#define R_AX_PREBKF_CFG_1_C1 0xE33C +#define B_AX_SIFS_TIMEOUT_TB_AGGR_MASK GENMASK(30, 24) +#define B_AX_SIFS_PREBKF_MASK GENMASK(23, 16) +#define B_AX_SIFS_TIMEOUT_T2_MASK GENMASK(14, 8) +#define B_AX_SIFS_MACTXEN_T1_MASK GENMASK(6, 0) +#define SIFS_MACTXEN_T1 0x47 + #define R_AX_CCA_CFG_0 0xC340 #define R_AX_CCA_CFG_0_C1 0xE340 #define B_AX_BTCCA_BRK_TXOP_EN BIT(9) @@ -1076,6 +1084,10 @@ #define R_AX_SCH_DBG_C1 0xE3F8 #define B_AX_SCHEDULER_DBG_MASK GENMASK(31, 0) +#define R_AX_SCH_EXT_CTRL 0xC3FC +#define R_AX_SCH_EXT_CTRL_C1 0xE3FC +#define B_AX_PORT_RST_TSF_ADV BIT(1) + #define R_AX_PORT_CFG_P0 0xC400 #define R_AX_PORT_CFG_P1 0xC440 #define R_AX_PORT_CFG_P2 0xC480 From 19cb94273f40b08dbb5677619d05a4c594226ac9 Mon Sep 17 00:00:00 2001 From: Ping-Ke Shih Date: Fri, 25 Mar 2022 14:00:53 +0800 Subject: [PATCH 087/228] rtw89: initialize NAV control Configure NAV function and its parameters. Signed-off-by: Ping-Ke Shih Signed-off-by: Kalle Valo Link: https://lore.kernel.org/r/20220325060055.58482-15-pkshih@realtek.com --- drivers/net/wireless/realtek/rtw89/mac.c | 17 +++++++++++++++++ drivers/net/wireless/realtek/rtw89/reg.h | 10 ++++++++++ 2 files changed, 27 insertions(+) diff --git a/drivers/net/wireless/realtek/rtw89/mac.c b/drivers/net/wireless/realtek/rtw89/mac.c index 16a97bcb8d480..c0e35143a9046 100644 --- a/drivers/net/wireless/realtek/rtw89/mac.c +++ b/drivers/net/wireless/realtek/rtw89/mac.c @@ -1883,6 +1883,16 @@ static int cca_ctrl_init(struct rtw89_dev *rtwdev, u8 mac_idx) return 0; } +static int nav_ctrl_init(struct rtw89_dev *rtwdev) +{ + rtw89_write32_set(rtwdev, R_AX_WMAC_NAV_CTL, B_AX_WMAC_PLCP_UP_NAV_EN | + B_AX_WMAC_TF_UP_NAV_EN | + B_AX_WMAC_NAV_UPPER_EN); + rtw89_write32_mask(rtwdev, R_AX_WMAC_NAV_CTL, B_AX_WMAC_NAV_UPPER_MASK, NAV_12MS); + + return 0; +} + static int spatial_reuse_init(struct rtw89_dev *rtwdev, u8 mac_idx) { u32 reg; @@ -2098,6 +2108,13 @@ static int cmac_init(struct rtw89_dev *rtwdev, u8 mac_idx) return ret; } + ret = nav_ctrl_init(rtwdev); + if (ret) { + rtw89_err(rtwdev, "[ERR]CMAC%d NAV CTRL init %d\n", mac_idx, + ret); + return ret; + } + ret = spatial_reuse_init(rtwdev, mac_idx); if (ret) { rtw89_err(rtwdev, "[ERR]CMAC%d Spatial Reuse init %d\n", diff --git a/drivers/net/wireless/realtek/rtw89/reg.h b/drivers/net/wireless/realtek/rtw89/reg.h index dea7d2c8547be..aca9fc3ac09ed 100644 --- a/drivers/net/wireless/realtek/rtw89/reg.h +++ b/drivers/net/wireless/realtek/rtw89/reg.h @@ -1435,6 +1435,16 @@ #define R_AX_MAC_LOOPBACK_C1 0xEC20 #define B_AX_MACLBK_EN BIT(0) +#define R_AX_WMAC_NAV_CTL 0xCC80 +#define R_AX_WMAC_NAV_CTL_C1 0xEC80 +#define B_AX_WMAC_NAV_UPPER_EN BIT(26) +#define B_AX_WMAC_0P125US_TIMER_MASK GENMASK(25, 18) +#define B_AX_WMAC_PLCP_UP_NAV_EN BIT(17) +#define B_AX_WMAC_TF_UP_NAV_EN BIT(16) +#define B_AX_WMAC_NAV_UPPER_MASK GENMASK(15, 8) +#define NAV_12MS 0xBC +#define B_AX_WMAC_RTS_RST_DUR_MASK GENMASK(7, 0) + #define R_AX_RXTRIG_TEST_USER_2 0xCCB0 #define R_AX_RXTRIG_TEST_USER_2_C1 0xECB0 #define B_AX_RXTRIG_MACID_MASK GENMASK(31, 24) From 75fd91aa92f91a441b115368f07b381b47130fb8 Mon Sep 17 00:00:00 2001 From: Ping-Ke Shih Date: Fri, 25 Mar 2022 14:00:54 +0800 Subject: [PATCH 088/228] rtw89: update TMAC parameters TMAC is short for TX MAC, and this patch is to configure FIFO thresholds. Signed-off-by: Ping-Ke Shih Signed-off-by: Kalle Valo Link: https://lore.kernel.org/r/20220325060055.58482-16-pkshih@realtek.com --- drivers/net/wireless/realtek/rtw89/mac.c | 7 ++++++ drivers/net/wireless/realtek/rtw89/reg.h | 29 ++++++++++++++++++++++++ 2 files changed, 36 insertions(+) diff --git a/drivers/net/wireless/realtek/rtw89/mac.c b/drivers/net/wireless/realtek/rtw89/mac.c index c0e35143a9046..0292ec560562f 100644 --- a/drivers/net/wireless/realtek/rtw89/mac.c +++ b/drivers/net/wireless/realtek/rtw89/mac.c @@ -1919,6 +1919,13 @@ static int tmac_init(struct rtw89_dev *rtwdev, u8 mac_idx) reg = rtw89_mac_reg_by_idx(R_AX_MAC_LOOPBACK, mac_idx); rtw89_write32_clr(rtwdev, reg, B_AX_MACLBK_EN); + reg = rtw89_mac_reg_by_idx(R_AX_TCR0, mac_idx); + rtw89_write32_mask(rtwdev, reg, B_AX_TCR_UDF_THSD_MASK, TCR_UDF_THSD); + + reg = rtw89_mac_reg_by_idx(R_AX_TXD_FIFO_CTRL, mac_idx); + rtw89_write32_mask(rtwdev, reg, B_AX_TXDFIFO_HIGH_MCS_THRE_MASK, TXDFIFO_HIGH_MCS_THRE); + rtw89_write32_mask(rtwdev, reg, B_AX_TXDFIFO_LOW_MCS_THRE_MASK, TXDFIFO_LOW_MCS_THRE); + return 0; } diff --git a/drivers/net/wireless/realtek/rtw89/reg.h b/drivers/net/wireless/realtek/rtw89/reg.h index aca9fc3ac09ed..3822cf0daef0a 100644 --- a/drivers/net/wireless/realtek/rtw89/reg.h +++ b/drivers/net/wireless/realtek/rtw89/reg.h @@ -1351,6 +1351,24 @@ #define R_AX_RXDMA_PKT_INFO_1 0xC818 #define R_AX_RXDMA_PKT_INFO_2 0xC81C +#define R_AX_TCR0 0xCA00 +#define R_AX_TCR0_C1 0xEA00 +#define B_AX_TCR_ZLD_NUM_MASK GENMASK(31, 24) +#define B_AX_TCR_UDF_EN BIT(23) +#define B_AX_TCR_UDF_THSD_MASK GENMASK(22, 16) +#define TCR_UDF_THSD 0x6 +#define B_AX_TCR_ERRSTEN_MASK GENMASK(15, 10) +#define B_AX_TCR_VHTSIGA1_TXPS BIT(9) +#define B_AX_TCR_PLCP_ERRHDL_EN BIT(8) +#define B_AX_TCR_PADSEL BIT(7) +#define B_AX_TCR_MASK_SIGBCRC BIT(6) +#define B_AX_TCR_SR_VAL15_ALLOW BIT(5) +#define B_AX_TCR_EN_EOF BIT(4) +#define B_AX_TCR_EN_SCRAM_INC BIT(3) +#define B_AX_TCR_EN_20MST BIT(2) +#define B_AX_TCR_CRC BIT(1) +#define B_AX_TCR_DISGCLK BIT(0) + #define R_AX_TCR1 0xCA04 #define R_AX_TCR1_C1 0xEA04 #define B_AX_TXDFIFO_THRESHOLD GENMASK(31, 28) @@ -1374,6 +1392,17 @@ #define R_AX_PPWRBIT_SETTING 0xCA0C #define R_AX_PPWRBIT_SETTING_C1 0xEA0C +#define R_AX_TXD_FIFO_CTRL 0xCA1C +#define R_AX_TXD_FIFO_CTRL_C1 0xEA1C +#define B_AX_NON_LEGACY_PPDU_ZLD_USTIMER_MASK GENMASK(28, 24) +#define B_AX_LEGACY_PPDU_ZLD_USTIMER_MASK GENMASK(20, 16) +#define B_AX_TXDFIFO_HIGH_MCS_THRE_MASK GENMASK(15, 12) +#define TXDFIFO_HIGH_MCS_THRE 0x7 +#define B_AX_TXDFIFO_LOW_MCS_THRE_MASK GENMASK(11, 8) +#define TXDFIFO_LOW_MCS_THRE 0x7 +#define B_AX_HIGH_MCS_PHY_RATE_MASK GENMASK(7, 4) +#define B_AX_BW_PHY_RATE_MASK GENMASK(1, 0) + #define R_AX_MACTX_DBG_SEL_CNT 0xCA20 #define R_AX_MACTX_DBG_SEL_CNT_C1 0xEA20 #define B_AX_MACTX_MPDU_CNT GENMASK(31, 24) From 9fb4862e913ceb5f6e668033c214e07eca7ee18a Mon Sep 17 00:00:00 2001 From: Ping-Ke Shih Date: Fri, 25 Mar 2022 14:00:55 +0800 Subject: [PATCH 089/228] rtw89: update ptcl_init ptcl_init, standing for protocol initialization, is updated to the latest version. Signed-off-by: Ping-Ke Shih Signed-off-by: Kalle Valo Link: https://lore.kernel.org/r/20220325060055.58482-17-pkshih@realtek.com --- drivers/net/wireless/realtek/rtw89/mac.c | 20 +++++++++++++++----- drivers/net/wireless/realtek/rtw89/reg.h | 24 ++++++++++++++++++++++++ 2 files changed, 39 insertions(+), 5 deletions(-) diff --git a/drivers/net/wireless/realtek/rtw89/mac.c b/drivers/net/wireless/realtek/rtw89/mac.c index 0292ec560562f..6a2ba975d8a00 100644 --- a/drivers/net/wireless/realtek/rtw89/mac.c +++ b/drivers/net/wireless/realtek/rtw89/mac.c @@ -2065,6 +2065,8 @@ static int ptcl_init(struct rtw89_dev *rtwdev, u8 mac_idx) val = rtw89_read32(rtwdev, reg); val = u32_replace_bits(val, S_AX_CTS2S_TH_1K, B_AX_HW_CTS2SELF_PKT_LEN_TH_MASK); + val = u32_replace_bits(val, S_AX_CTS2S_TH_SEC_256B, + B_AX_HW_CTS2SELF_PKT_LEN_TH_TWW_MASK); val |= B_AX_HW_CTS2SELF_EN; rtw89_write32(rtwdev, reg, val); @@ -2075,11 +2077,19 @@ static int ptcl_init(struct rtw89_dev *rtwdev, u8 mac_idx) rtw89_write32(rtwdev, reg, val); } - reg = rtw89_mac_reg_by_idx(R_AX_SIFS_SETTING, mac_idx); - val = rtw89_read32(rtwdev, reg); - val = u32_replace_bits(val, S_AX_CTS2S_TH_SEC_256B, B_AX_HW_CTS2SELF_PKT_LEN_TH_TWW_MASK); - val |= B_AX_HW_CTS2SELF_EN; - rtw89_write32(rtwdev, reg, val); + if (mac_idx == RTW89_MAC_0) { + rtw89_write8_set(rtwdev, R_AX_PTCL_COMMON_SETTING_0, + B_AX_CMAC_TX_MODE_0 | B_AX_CMAC_TX_MODE_1); + rtw89_write8_clr(rtwdev, R_AX_PTCL_COMMON_SETTING_0, + B_AX_PTCL_TRIGGER_SS_EN_0 | + B_AX_PTCL_TRIGGER_SS_EN_1 | + B_AX_PTCL_TRIGGER_SS_EN_UL); + rtw89_write8_mask(rtwdev, R_AX_PTCLRPT_FULL_HDL, + B_AX_SPE_RPT_PATH_MASK, FWD_TO_WLCPU); + } else if (mac_idx == RTW89_MAC_1) { + rtw89_write8_mask(rtwdev, R_AX_PTCLRPT_FULL_HDL_C1, + B_AX_SPE_RPT_PATH_MASK, FWD_TO_WLCPU); + } return 0; } diff --git a/drivers/net/wireless/realtek/rtw89/reg.h b/drivers/net/wireless/realtek/rtw89/reg.h index 3822cf0daef0a..a0c60528b5780 100644 --- a/drivers/net/wireless/realtek/rtw89/reg.h +++ b/drivers/net/wireless/realtek/rtw89/reg.h @@ -1248,6 +1248,18 @@ #define R_AX_PORT_HGQ_WINDOW_CFG 0xC5A0 #define R_AX_PORT_HGQ_WINDOW_CFG_C1 0xE5A0 +#define R_AX_PTCL_COMMON_SETTING_0 0xC600 +#define R_AX_PTCL_COMMON_SETTING_0_C1 0xE600 +#define B_AX_PCIE_MODE_MASK GENMASK(15, 14) +#define B_AX_CPUMGQ_LIFETIME_EN BIT(8) +#define B_AX_MGQ_LIFETIME_EN BIT(7) +#define B_AX_LIFETIME_EN BIT(6) +#define B_AX_PTCL_TRIGGER_SS_EN_UL BIT(4) +#define B_AX_PTCL_TRIGGER_SS_EN_1 BIT(3) +#define B_AX_PTCL_TRIGGER_SS_EN_0 BIT(2) +#define B_AX_CMAC_TX_MODE_1 BIT(1) +#define B_AX_CMAC_TX_MODE_0 BIT(0) + #define R_AX_AMPDU_AGG_LIMIT 0xC610 #define B_AX_AMPDU_MAX_TIME_MASK GENMASK(31, 24) #define B_AX_RA_TRY_RATE_AGG_LMT_MASK GENMASK(23, 16) @@ -1292,6 +1304,18 @@ #define B_AX_PORT_DROP_4_0_MASK GENMASK(20, 16) #define B_AX_MBSSID_DROP_15_0_MASK GENMASK(15, 0) +#define R_AX_PTCLRPT_FULL_HDL 0xC660 +#define R_AX_PTCLRPT_FULL_HDL_C1 0xE660 +#define B_AX_RPT_LATCH_PHY_TIME_MASK GENMASK(15, 12) +#define B_AX_F2PCMD_FWWD_RLS_MODE BIT(9) +#define B_AX_F2PCMD_RPT_EN BIT(8) +#define B_AX_BCN_RPT_PATH_MASK GENMASK(7, 6) +#define B_AX_SPE_RPT_PATH_MASK GENMASK(5, 4) +#define FWD_TO_WLCPU 1 +#define B_AX_TX_RPT_PATH_MASK GENMASK(3, 2) +#define B_AX_F2PCMDRPT_FULL_DROP BIT(1) +#define B_AX_NON_F2PCMDRPT_FULL_DROP BIT(0) + #define R_AX_BT_PLT 0xC67C #define R_AX_BT_PLT_C1 0xE67C #define B_AX_BT_PLT_PKT_CNT_MASK GENMASK(31, 16) From ee20d538c4989daddd383b6a89129a2b514580e6 Mon Sep 17 00:00:00 2001 From: Po Hao Huang Date: Fri, 1 Apr 2022 13:50:40 +0800 Subject: [PATCH 090/228] rtw89: change idle mode condition during hw_scan Previously we only consider single interface's status, idle mode behavior could be unexpected when multiple interfaces is active. Change to enter/leave idle mode by mac80211's configuration state. Signed-off-by: Po Hao Huang Signed-off-by: Ping-Ke Shih Signed-off-by: Kalle Valo Link: https://lore.kernel.org/r/20220401055043.12512-2-pkshih@realtek.com --- drivers/net/wireless/realtek/rtw89/core.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/drivers/net/wireless/realtek/rtw89/core.c b/drivers/net/wireless/realtek/rtw89/core.c index f540ee34fc2c0..89506daa54cc2 100644 --- a/drivers/net/wireless/realtek/rtw89/core.c +++ b/drivers/net/wireless/realtek/rtw89/core.c @@ -1940,9 +1940,9 @@ static void rtw89_ips_work(struct work_struct *work) { struct rtw89_dev *rtwdev = container_of(work, struct rtw89_dev, ips_work); - mutex_lock(&rtwdev->mutex); - rtw89_enter_ips(rtwdev); + if (rtwdev->hw->conf.flags & IEEE80211_CONF_IDLE) + rtw89_enter_ips(rtwdev); mutex_unlock(&rtwdev->mutex); } @@ -2848,7 +2848,7 @@ void rtw89_core_scan_start(struct rtw89_dev *rtwdev, struct rtw89_vif *rtwvif, rtwdev->scanning = true; rtw89_leave_lps(rtwdev); - if (hw_scan && rtwvif->net_type == RTW89_NET_TYPE_NO_LINK) + if (hw_scan && (rtwdev->hw->conf.flags & IEEE80211_CONF_IDLE)) rtw89_leave_ips(rtwdev); ether_addr_copy(rtwvif->mac_addr, mac_addr); @@ -2872,7 +2872,7 @@ void rtw89_core_scan_complete(struct rtw89_dev *rtwdev, rtwdev->scanning = false; rtwdev->dig.bypass_dig = true; - if (hw_scan && rtwvif->net_type == RTW89_NET_TYPE_NO_LINK) + if (hw_scan && (rtwdev->hw->conf.flags & IEEE80211_CONF_IDLE)) ieee80211_queue_work(rtwdev->hw, &rtwdev->ips_work); } From 2b8219e9b746ee3090baa1daa192b16e5bc72f9d Mon Sep 17 00:00:00 2001 From: Po Hao Huang Date: Fri, 1 Apr 2022 13:50:41 +0800 Subject: [PATCH 091/228] rtw89: packet offload handler to avoid warning Add a dummy function for packet offload to eliminate warning message "c2h class 1 func 2 not support". This c2h is for debug purpose and its presence itself can do the work, so further parsing won't be required for now. Signed-off-by: Po Hao Huang Signed-off-by: Ping-Ke Shih Signed-off-by: Kalle Valo Link: https://lore.kernel.org/r/20220401055043.12512-3-pkshih@realtek.com --- drivers/net/wireless/realtek/rtw89/mac.c | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/drivers/net/wireless/realtek/rtw89/mac.c b/drivers/net/wireless/realtek/rtw89/mac.c index 6a2ba975d8a00..34e14a53a5851 100644 --- a/drivers/net/wireless/realtek/rtw89/mac.c +++ b/drivers/net/wireless/realtek/rtw89/mac.c @@ -3498,12 +3498,18 @@ rtw89_mac_c2h_bcn_cnt(struct rtw89_dev *rtwdev, struct sk_buff *c2h, u32 len) { } +static void +rtw89_mac_c2h_pkt_ofld_rsp(struct rtw89_dev *rtwdev, struct sk_buff *c2h, + u32 len) +{ +} + static void (* const rtw89_mac_c2h_ofld_handler[])(struct rtw89_dev *rtwdev, struct sk_buff *c2h, u32 len) = { [RTW89_MAC_C2H_FUNC_EFUSE_DUMP] = NULL, [RTW89_MAC_C2H_FUNC_READ_RSP] = NULL, - [RTW89_MAC_C2H_FUNC_PKT_OFLD_RSP] = NULL, + [RTW89_MAC_C2H_FUNC_PKT_OFLD_RSP] = rtw89_mac_c2h_pkt_ofld_rsp, [RTW89_MAC_C2H_FUNC_BCN_RESEND] = NULL, [RTW89_MAC_C2H_FUNC_MACID_PAUSE] = rtw89_mac_c2h_macid_pause, [RTW89_MAC_C2H_FUNC_SCANOFLD_RSP] = rtw89_mac_c2h_scanofld_rsp, From 841f2633840ea2eb1ecea4a7efab9d19d9abaf62 Mon Sep 17 00:00:00 2001 From: Ching-Te Ku Date: Fri, 1 Apr 2022 13:50:42 +0800 Subject: [PATCH 092/228] rtw89: coex: Add case for scan offload Turn off coexistence driver control, let firmware can control the traffic during scan. This prevents potential unexpected behavior of the BT driver. Signed-off-by: Ching-Te Ku Signed-off-by: Ping-Ke Shih Signed-off-by: Kalle Valo Link: https://lore.kernel.org/r/20220401055043.12512-4-pkshih@realtek.com --- drivers/net/wireless/realtek/rtw89/coex.c | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/drivers/net/wireless/realtek/rtw89/coex.c b/drivers/net/wireless/realtek/rtw89/coex.c index 6845839555112..3d5664cc3a203 100644 --- a/drivers/net/wireless/realtek/rtw89/coex.c +++ b/drivers/net/wireless/realtek/rtw89/coex.c @@ -3068,7 +3068,17 @@ 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 (rtwdev->dbcc_en) { + if (RTW89_CHK_FW_FEATURE(SCAN_OFFLOAD, &rtwdev->fw)) { + _set_ant(rtwdev, NM_EXEC, BTC_PHY_ALL, BTC_ANT_W25G); + if (btc->mdinfo.ant.type == BTC_ANT_SHARED) + _set_policy(rtwdev, BTC_CXP_OFFE_DEF, + BTC_RSN_NTFY_SCAN_START); + else + _set_policy(rtwdev, BTC_CXP_OFF_EQ0, + BTC_RSN_NTFY_SCAN_START); + + rtw89_debug(rtwdev, RTW89_DBG_BTC, "[BTC], Scan offload!\n"); + } else if (rtwdev->dbcc_en) { if (wl_dinfo->real_band[RTW89_PHY_0] != RTW89_BAND_2G && wl_dinfo->real_band[RTW89_PHY_1] != RTW89_BAND_2G) _action_wl_5g(rtwdev); From 65ee4971a262a024e239e5d2b7f4dee1b3dff40e Mon Sep 17 00:00:00 2001 From: Po Hao Huang Date: Fri, 1 Apr 2022 13:50:43 +0800 Subject: [PATCH 093/228] rtw89: fix misconfiguration on hw_scan channel time Without this patch, hw scan won't stay long enough on DFS/passive channels. Found previous logic error and fix it. Signed-off-by: Po Hao Huang Signed-off-by: Ping-Ke Shih Signed-off-by: Kalle Valo Link: https://lore.kernel.org/r/20220401055043.12512-5-pkshih@realtek.com --- drivers/net/wireless/realtek/rtw89/fw.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/net/wireless/realtek/rtw89/fw.c b/drivers/net/wireless/realtek/rtw89/fw.c index 5985b40950bc1..fc77d9bfd6260 100644 --- a/drivers/net/wireless/realtek/rtw89/fw.c +++ b/drivers/net/wireless/realtek/rtw89/fw.c @@ -2101,7 +2101,7 @@ static void rtw89_hw_scan_add_chan(struct rtw89_dev *rtwdev, int chan_type, ch_info->num_pkt = 0; break; case RTW89_CHAN_DFS: - ch_info->period = min_t(u8, ch_info->period, + ch_info->period = max_t(u8, ch_info->period, RTW89_DFS_CHAN_TIME); ch_info->dwell_time = RTW89_DWELL_TIME; break; From 3e12968f6d12a34b540c39cbd696a760cc4616f0 Mon Sep 17 00:00:00 2001 From: Niels Dossche Date: Mon, 21 Mar 2022 23:55:16 +0100 Subject: [PATCH 094/228] mwifiex: add mutex lock for call in mwifiex_dfs_chan_sw_work_queue cfg80211_ch_switch_notify uses ASSERT_WDEV_LOCK to assert that net_device->ieee80211_ptr->mtx (which is the same as priv->wdev.mtx) is held during the function's execution. mwifiex_dfs_chan_sw_work_queue is one of its callers, which does not hold that lock, therefore violating the assertion. Add a lock around the call. Disclaimer: I am currently working on a static analyser to detect missing locks. This was a reported case. I manually verified the report by looking at the code, so that I do not send wrong information or patches. After concluding that this seems to be a true positive, I created this patch. However, as I do not in fact have this particular hardware, I was unable to test it. Reviewed-by: Brian Norris Signed-off-by: Niels Dossche Signed-off-by: Kalle Valo Link: https://lore.kernel.org/r/20220321225515.32113-1-dossche.niels@gmail.com --- drivers/net/wireless/marvell/mwifiex/11h.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/drivers/net/wireless/marvell/mwifiex/11h.c b/drivers/net/wireless/marvell/mwifiex/11h.c index d2ee6469e67bb..3fa25cd64cda0 100644 --- a/drivers/net/wireless/marvell/mwifiex/11h.c +++ b/drivers/net/wireless/marvell/mwifiex/11h.c @@ -303,5 +303,7 @@ void mwifiex_dfs_chan_sw_work_queue(struct work_struct *work) mwifiex_dbg(priv->adapter, MSG, "indicating channel switch completion to kernel\n"); + mutex_lock(&priv->wdev.mtx); cfg80211_ch_switch_notify(priv->netdev, &priv->dfs_chandef); + mutex_unlock(&priv->wdev.mtx); } From 92cadedd9d5f4355d8ca2765f2259708f0e5592c Mon Sep 17 00:00:00 2001 From: Ulf Hansson Date: Wed, 23 Mar 2022 09:39:50 +0100 Subject: [PATCH 095/228] brcmfmac: Avoid keeping power to SDIO card unless WOWL is used Keeping the power to the SDIO card during system wide suspend, consumes energy. Especially on battery driven embedded systems, this can be a problem. Therefore, let's change the behaviour into allowing the SDIO card to be powered off, unless WOWL is supported and enabled. Note that, the downside from this change, is that during system resume the SDIO card needs to be re-initialized and the FW must be re-programmed. Even if this may take some time to complete, it should we worth it, rather than draining the battery. Signed-off-by: Ulf Hansson Tested-by: Christophe Roullier Reviewed-by: Yann Gautier Signed-off-by: Kalle Valo Link: https://lore.kernel.org/r/20220323083950.414783-1-ulf.hansson@linaro.org --- .../broadcom/brcm80211/brcmfmac/bcmsdh.c | 39 +++++++++++-------- 1 file changed, 22 insertions(+), 17 deletions(-) diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/bcmsdh.c b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/bcmsdh.c index ac02244a6fdf1..9c598ea97499f 100644 --- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/bcmsdh.c +++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/bcmsdh.c @@ -1119,9 +1119,21 @@ void brcmf_sdio_wowl_config(struct device *dev, bool enabled) { struct brcmf_bus *bus_if = dev_get_drvdata(dev); struct brcmf_sdio_dev *sdiodev = bus_if->bus_priv.sdio; + mmc_pm_flag_t pm_caps = sdio_get_host_pm_caps(sdiodev->func1); - brcmf_dbg(SDIO, "Configuring WOWL, enabled=%d\n", enabled); - sdiodev->wowl_enabled = enabled; + /* Power must be preserved to be able to support WOWL. */ + if (!(pm_caps & MMC_PM_KEEP_POWER)) + goto notsup; + + if (sdiodev->settings->bus.sdio.oob_irq_supported || + pm_caps & MMC_PM_WAKE_SDIO_IRQ) { + sdiodev->wowl_enabled = enabled; + brcmf_dbg(SDIO, "Configuring WOWL, enabled=%d\n", enabled); + return; + } + +notsup: + brcmf_dbg(SDIO, "WOWL not supported\n"); } #ifdef CONFIG_PM_SLEEP @@ -1130,7 +1142,7 @@ static int brcmf_ops_sdio_suspend(struct device *dev) struct sdio_func *func; struct brcmf_bus *bus_if; struct brcmf_sdio_dev *sdiodev; - mmc_pm_flag_t pm_caps, sdio_flags; + mmc_pm_flag_t sdio_flags; int ret = 0; func = container_of(dev, struct sdio_func, dev); @@ -1142,20 +1154,15 @@ static int brcmf_ops_sdio_suspend(struct device *dev) bus_if = dev_get_drvdata(dev); sdiodev = bus_if->bus_priv.sdio; - pm_caps = sdio_get_host_pm_caps(func); - - if (pm_caps & MMC_PM_KEEP_POWER) { - /* preserve card power during suspend */ + if (sdiodev->wowl_enabled) { brcmf_sdiod_freezer_on(sdiodev); brcmf_sdio_wd_timer(sdiodev->bus, 0); sdio_flags = MMC_PM_KEEP_POWER; - if (sdiodev->wowl_enabled) { - if (sdiodev->settings->bus.sdio.oob_irq_supported) - enable_irq_wake(sdiodev->settings->bus.sdio.oob_irq_nr); - else - sdio_flags |= MMC_PM_WAKE_SDIO_IRQ; - } + if (sdiodev->settings->bus.sdio.oob_irq_supported) + enable_irq_wake(sdiodev->settings->bus.sdio.oob_irq_nr); + else + sdio_flags |= MMC_PM_WAKE_SDIO_IRQ; if (sdio_set_host_pm_flags(sdiodev->func1, sdio_flags)) brcmf_err("Failed to set pm_flags %x\n", sdio_flags); @@ -1176,21 +1183,19 @@ static int brcmf_ops_sdio_resume(struct device *dev) struct brcmf_bus *bus_if = dev_get_drvdata(dev); struct brcmf_sdio_dev *sdiodev = bus_if->bus_priv.sdio; struct sdio_func *func = container_of(dev, struct sdio_func, dev); - mmc_pm_flag_t pm_caps = sdio_get_host_pm_caps(func); int ret = 0; brcmf_dbg(SDIO, "Enter: F%d\n", func->num); if (func->num != 2) return 0; - if (!(pm_caps & MMC_PM_KEEP_POWER)) { + if (!sdiodev->wowl_enabled) { /* bus was powered off and device removed, probe again */ ret = brcmf_sdiod_probe(sdiodev); if (ret) brcmf_err("Failed to probe device on resume\n"); } else { - if (sdiodev->wowl_enabled && - sdiodev->settings->bus.sdio.oob_irq_supported) + if (sdiodev->settings->bus.sdio.oob_irq_supported) disable_irq_wake(sdiodev->settings->bus.sdio.oob_irq_nr); brcmf_sdiod_freezer_off(sdiodev); From a0ff2a87194a968b9547fd4d824a09092171d1ea Mon Sep 17 00:00:00 2001 From: Jakob Koschel Date: Thu, 24 Mar 2022 08:21:24 +0100 Subject: [PATCH 096/228] rtlwifi: replace usage of found with dedicated list iterator variable To move the list iterator variable into the list_for_each_entry_*() macro in the future it should be avoided to use the list iterator variable after the loop body. To *never* use the list iterator variable after the loop it was concluded to use a separate iterator variable instead of a found boolean [1]. This removes the need to use a found variable and simply checking if the variable was set, can determine if the break/goto was hit. Link: https://lore.kernel.org/all/CAHk-=wgRr_D8CB-D9Kg-c=EHreAsk5SqXPwr9Y7k9sA6cWXJ6w@mail.gmail.com/ Signed-off-by: Jakob Koschel Acked-by: Ping-Ke Shih Signed-off-by: Kalle Valo Link: https://lore.kernel.org/r/20220324072124.62458-1-jakobkoschel@gmail.com --- drivers/net/wireless/realtek/rtlwifi/base.c | 13 ++++++------- drivers/net/wireless/realtek/rtlwifi/pci.c | 15 +++++++-------- 2 files changed, 13 insertions(+), 15 deletions(-) diff --git a/drivers/net/wireless/realtek/rtlwifi/base.c b/drivers/net/wireless/realtek/rtlwifi/base.c index ffd150ec181fa..a7ef84f559399 100644 --- a/drivers/net/wireless/realtek/rtlwifi/base.c +++ b/drivers/net/wireless/realtek/rtlwifi/base.c @@ -1994,8 +1994,7 @@ void rtl_collect_scan_list(struct ieee80211_hw *hw, struct sk_buff *skb) struct rtl_mac *mac = rtl_mac(rtl_priv(hw)); unsigned long flags; - struct rtl_bssid_entry *entry; - bool entry_found = false; + struct rtl_bssid_entry *entry = NULL, *iter; /* check if it is scanning */ if (!mac->act_scanning) @@ -2008,10 +2007,10 @@ void rtl_collect_scan_list(struct ieee80211_hw *hw, struct sk_buff *skb) spin_lock_irqsave(&rtlpriv->locks.scan_list_lock, flags); - list_for_each_entry(entry, &rtlpriv->scan_list.list, list) { - if (memcmp(entry->bssid, hdr->addr3, ETH_ALEN) == 0) { - list_del_init(&entry->list); - entry_found = true; + list_for_each_entry(iter, &rtlpriv->scan_list.list, list) { + if (memcmp(iter->bssid, hdr->addr3, ETH_ALEN) == 0) { + list_del_init(&iter->list); + entry = iter; rtl_dbg(rtlpriv, COMP_SCAN, DBG_LOUD, "Update BSSID=%pM to scan list (total=%d)\n", hdr->addr3, rtlpriv->scan_list.num); @@ -2019,7 +2018,7 @@ void rtl_collect_scan_list(struct ieee80211_hw *hw, struct sk_buff *skb) } } - if (!entry_found) { + if (!entry) { entry = kmalloc(sizeof(*entry), GFP_ATOMIC); if (!entry) diff --git a/drivers/net/wireless/realtek/rtlwifi/pci.c b/drivers/net/wireless/realtek/rtlwifi/pci.c index ad327bae754be..8e4c156547464 100644 --- a/drivers/net/wireless/realtek/rtlwifi/pci.c +++ b/drivers/net/wireless/realtek/rtlwifi/pci.c @@ -323,14 +323,13 @@ static bool rtl_pci_check_buddy_priv(struct ieee80211_hw *hw, { struct rtl_priv *rtlpriv = rtl_priv(hw); struct rtl_pci_priv *pcipriv = rtl_pcipriv(hw); - bool find_buddy_priv = false; - struct rtl_priv *tpriv; + struct rtl_priv *tpriv = NULL, *iter; struct rtl_pci_priv *tpcipriv = NULL; if (!list_empty(&rtlpriv->glb_var->glb_priv_list)) { - list_for_each_entry(tpriv, &rtlpriv->glb_var->glb_priv_list, + list_for_each_entry(iter, &rtlpriv->glb_var->glb_priv_list, list) { - tpcipriv = (struct rtl_pci_priv *)tpriv->priv; + tpcipriv = (struct rtl_pci_priv *)iter->priv; rtl_dbg(rtlpriv, COMP_INIT, DBG_LOUD, "pcipriv->ndis_adapter.funcnumber %x\n", pcipriv->ndis_adapter.funcnumber); @@ -344,19 +343,19 @@ static bool rtl_pci_check_buddy_priv(struct ieee80211_hw *hw, tpcipriv->ndis_adapter.devnumber && pcipriv->ndis_adapter.funcnumber != tpcipriv->ndis_adapter.funcnumber) { - find_buddy_priv = true; + tpriv = iter; break; } } } rtl_dbg(rtlpriv, COMP_INIT, DBG_LOUD, - "find_buddy_priv %d\n", find_buddy_priv); + "find_buddy_priv %d\n", tpriv != NULL); - if (find_buddy_priv) + if (tpriv) *buddy_priv = tpriv; - return find_buddy_priv; + return tpriv != NULL; } static void rtl_pci_get_linkcontrol_field(struct ieee80211_hw *hw) From 21338c5bdeb969bfb2d78bd06a71a40b9a82a51e Mon Sep 17 00:00:00 2001 From: Chris Chiu Date: Fri, 25 Mar 2022 11:57:34 +0800 Subject: [PATCH 097/228] rtl8xxxu: feed antenna information for cfg80211 Fill up the available TX/RX antenna so the iw commands can show correct antenna information for different chips. Signed-off-by: Chris Chiu Signed-off-by: Kalle Valo Link: https://lore.kernel.org/r/20220325035735.4745-2-chris.chiu@canonical.com --- .../wireless/realtek/rtl8xxxu/rtl8xxxu_core.c | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/drivers/net/wireless/realtek/rtl8xxxu/rtl8xxxu_core.c b/drivers/net/wireless/realtek/rtl8xxxu/rtl8xxxu_core.c index 06d59ffb7444f..d225a1257530e 100644 --- a/drivers/net/wireless/realtek/rtl8xxxu/rtl8xxxu_core.c +++ b/drivers/net/wireless/realtek/rtl8xxxu/rtl8xxxu_core.c @@ -1607,6 +1607,7 @@ static void rtl8xxxu_print_chipinfo(struct rtl8xxxu_priv *priv) static int rtl8xxxu_identify_chip(struct rtl8xxxu_priv *priv) { struct device *dev = &priv->udev->dev; + struct ieee80211_hw *hw = priv->hw; u32 val32, bonding; u16 val16; @@ -1684,6 +1685,9 @@ static int rtl8xxxu_identify_chip(struct rtl8xxxu_priv *priv) priv->has_wifi = 1; } + hw->wiphy->available_antennas_tx = BIT(priv->tx_paths) - 1; + hw->wiphy->available_antennas_rx = BIT(priv->rx_paths) - 1; + switch (priv->rtl_chip) { case RTL8188E: case RTL8192E: @@ -4282,6 +4286,17 @@ static void rtl8xxxu_cam_write(struct rtl8xxxu_priv *priv, rtl8xxxu_debug = tmp_debug; } +static +int rtl8xxxu_get_antenna(struct ieee80211_hw *hw, u32 *tx_ant, u32 *rx_ant) +{ + struct rtl8xxxu_priv *priv = hw->priv; + + *tx_ant = BIT(priv->tx_paths) - 1; + *rx_ant = BIT(priv->rx_paths) - 1; + + return 0; +} + static void rtl8xxxu_sw_scan_start(struct ieee80211_hw *hw, struct ieee80211_vif *vif, const u8 *mac) { @@ -6472,6 +6487,7 @@ static const struct ieee80211_ops rtl8xxxu_ops = { .set_key = rtl8xxxu_set_key, .ampdu_action = rtl8xxxu_ampdu_action, .sta_statistics = rtl8xxxu_sta_statistics, + .get_antenna = rtl8xxxu_get_antenna, }; static int rtl8xxxu_parse_usb(struct rtl8xxxu_priv *priv, From bd917b3d28c9815e2c55b9ff16680fdc2ba28d68 Mon Sep 17 00:00:00 2001 From: Chris Chiu Date: Fri, 25 Mar 2022 11:57:35 +0800 Subject: [PATCH 098/228] rtl8xxxu: fill up txrate info for gen1 chips RTL8188CUS/RTL8192CU(gen1) don't support rate adaptive report hence no real txrate info can be retrieved. The vendor driver reports the highest rate in HT capabilities from the IEs to avoid empty txrate. This commit initiates the txrate information with the highest supported rate negotiated with AP. The gen2 chip keeps update the txrate from the rate adaptive reports, and gen1 chips at least have non-NULL txrate after associated. Signed-off-by: Chris Chiu Signed-off-by: Kalle Valo Link: https://lore.kernel.org/r/20220325035735.4745-3-chris.chiu@canonical.com --- .../wireless/realtek/rtl8xxxu/rtl8xxxu_core.c | 88 +++++++++++++------ 1 file changed, 59 insertions(+), 29 deletions(-) diff --git a/drivers/net/wireless/realtek/rtl8xxxu/rtl8xxxu_core.c b/drivers/net/wireless/realtek/rtl8xxxu/rtl8xxxu_core.c index d225a1257530e..6d9b5cf01b110 100644 --- a/drivers/net/wireless/realtek/rtl8xxxu/rtl8xxxu_core.c +++ b/drivers/net/wireless/realtek/rtl8xxxu/rtl8xxxu_core.c @@ -4473,6 +4473,35 @@ void rtl8xxxu_gen1_init_aggregation(struct rtl8xxxu_priv *priv) priv->rx_buf_aggregation = 1; } +static const struct ieee80211_rate rtl8xxxu_legacy_ratetable[] = { + {.bitrate = 10, .hw_value = 0x00,}, + {.bitrate = 20, .hw_value = 0x01,}, + {.bitrate = 55, .hw_value = 0x02,}, + {.bitrate = 110, .hw_value = 0x03,}, + {.bitrate = 60, .hw_value = 0x04,}, + {.bitrate = 90, .hw_value = 0x05,}, + {.bitrate = 120, .hw_value = 0x06,}, + {.bitrate = 180, .hw_value = 0x07,}, + {.bitrate = 240, .hw_value = 0x08,}, + {.bitrate = 360, .hw_value = 0x09,}, + {.bitrate = 480, .hw_value = 0x0a,}, + {.bitrate = 540, .hw_value = 0x0b,}, +}; + +static void rtl8xxxu_desc_to_mcsrate(u16 rate, u8 *mcs, u8 *nss) +{ + if (rate <= DESC_RATE_54M) + return; + + if (rate >= DESC_RATE_MCS0 && rate <= DESC_RATE_MCS15) { + if (rate < DESC_RATE_MCS8) + *nss = 1; + else + *nss = 2; + *mcs = rate - DESC_RATE_MCS0; + } +} + static void rtl8xxxu_set_basic_rates(struct rtl8xxxu_priv *priv, u32 rate_cfg) { struct ieee80211_hw *hw = priv->hw; @@ -4534,9 +4563,12 @@ rtl8xxxu_bss_info_changed(struct ieee80211_hw *hw, struct ieee80211_vif *vif, struct rtl8xxxu_priv *priv = hw->priv; struct device *dev = &priv->udev->dev; struct ieee80211_sta *sta; + struct rtl8xxxu_ra_report *rarpt; u32 val32; u8 val8; + rarpt = &priv->ra_report; + if (changed & BSS_CHANGED_ASSOC) { dev_dbg(dev, "Changed ASSOC: %i!\n", bss_conf->assoc); @@ -4545,6 +4577,10 @@ rtl8xxxu_bss_info_changed(struct ieee80211_hw *hw, struct ieee80211_vif *vif, if (bss_conf->assoc) { u32 ramask; int sgi = 0; + u8 highest_rate; + u8 mcs = 0, nss = 0; + u32 bit_rate; + rcu_read_lock(); sta = ieee80211_find_sta(vif, bss_conf->bssid); @@ -4569,6 +4605,29 @@ rtl8xxxu_bss_info_changed(struct ieee80211_hw *hw, struct ieee80211_vif *vif, sgi = 1; rcu_read_unlock(); + highest_rate = fls(ramask) - 1; + if (highest_rate < DESC_RATE_MCS0) { + rarpt->txrate.legacy = + rtl8xxxu_legacy_ratetable[highest_rate].bitrate; + } else { + rtl8xxxu_desc_to_mcsrate(highest_rate, + &mcs, &nss); + rarpt->txrate.flags |= RATE_INFO_FLAGS_MCS; + + rarpt->txrate.mcs = mcs; + rarpt->txrate.nss = nss; + + if (sgi) { + rarpt->txrate.flags |= + RATE_INFO_FLAGS_SHORT_GI; + } + + rarpt->txrate.bw |= RATE_INFO_BW_20; + } + bit_rate = cfg80211_calculate_bitrate(&rarpt->txrate); + rarpt->bit_rate = bit_rate; + rarpt->desc_rate = highest_rate; + priv->vif = vif; priv->rssi_level = RTL8XXXU_RATR_STA_INIT; @@ -5419,35 +5478,6 @@ void rtl8723bu_handle_bt_info(struct rtl8xxxu_priv *priv) } } -static struct ieee80211_rate rtl8xxxu_legacy_ratetable[] = { - {.bitrate = 10, .hw_value = 0x00,}, - {.bitrate = 20, .hw_value = 0x01,}, - {.bitrate = 55, .hw_value = 0x02,}, - {.bitrate = 110, .hw_value = 0x03,}, - {.bitrate = 60, .hw_value = 0x04,}, - {.bitrate = 90, .hw_value = 0x05,}, - {.bitrate = 120, .hw_value = 0x06,}, - {.bitrate = 180, .hw_value = 0x07,}, - {.bitrate = 240, .hw_value = 0x08,}, - {.bitrate = 360, .hw_value = 0x09,}, - {.bitrate = 480, .hw_value = 0x0a,}, - {.bitrate = 540, .hw_value = 0x0b,}, -}; - -static void rtl8xxxu_desc_to_mcsrate(u16 rate, u8 *mcs, u8 *nss) -{ - if (rate <= DESC_RATE_54M) - return; - - if (rate >= DESC_RATE_MCS0 && rate <= DESC_RATE_MCS15) { - if (rate < DESC_RATE_MCS8) - *nss = 1; - else - *nss = 2; - *mcs = rate - DESC_RATE_MCS0; - } -} - static void rtl8xxxu_c2hcmd_callback(struct work_struct *work) { struct rtl8xxxu_priv *priv; From 3f6b867559b3d43a7ce1b4799b755e812fc0d503 Mon Sep 17 00:00:00 2001 From: Haowen Bai Date: Fri, 25 Mar 2022 18:17:13 +0800 Subject: [PATCH 099/228] b43legacy: Fix assigning negative value to unsigned variable fix warning reported by smatch: drivers/net/wireless/broadcom/b43legacy/phy.c:1181 b43legacy_phy_lo_b_measure() warn: assigning (-772) to unsigned variable 'fval' Signed-off-by: Haowen Bai Signed-off-by: Kalle Valo Link: https://lore.kernel.org/r/1648203433-8736-1-git-send-email-baihaowen@meizu.com --- drivers/net/wireless/broadcom/b43legacy/phy.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/net/wireless/broadcom/b43legacy/phy.c b/drivers/net/wireless/broadcom/b43legacy/phy.c index 05404fbd1e70b..c1395e622759e 100644 --- a/drivers/net/wireless/broadcom/b43legacy/phy.c +++ b/drivers/net/wireless/broadcom/b43legacy/phy.c @@ -1123,7 +1123,7 @@ void b43legacy_phy_lo_b_measure(struct b43legacy_wldev *dev) struct b43legacy_phy *phy = &dev->phy; u16 regstack[12] = { 0 }; u16 mls; - u16 fval; + s16 fval; int i; int j; From 11800d893b38e0e12d636c170c1abc19c43c730c Mon Sep 17 00:00:00 2001 From: Haowen Bai Date: Fri, 25 Mar 2022 18:15:15 +0800 Subject: [PATCH 100/228] b43: Fix assigning negative value to unsigned variable fix warning reported by smatch: drivers/net/wireless/broadcom/b43/phy_n.c:585 b43_nphy_adjust_lna_gain_table() warn: assigning (-2) to unsigned variable '*(lna_gain[0])' Signed-off-by: Haowen Bai Signed-off-by: Kalle Valo Link: https://lore.kernel.org/r/1648203315-28093-1-git-send-email-baihaowen@meizu.com --- drivers/net/wireless/broadcom/b43/phy_n.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/net/wireless/broadcom/b43/phy_n.c b/drivers/net/wireless/broadcom/b43/phy_n.c index cf3ccf4ddfe72..aa5c994656749 100644 --- a/drivers/net/wireless/broadcom/b43/phy_n.c +++ b/drivers/net/wireless/broadcom/b43/phy_n.c @@ -582,7 +582,7 @@ static void b43_nphy_adjust_lna_gain_table(struct b43_wldev *dev) u16 data[4]; s16 gain[2]; u16 minmax[2]; - static const u16 lna_gain[4] = { -2, 10, 19, 25 }; + static const s16 lna_gain[4] = { -2, 10, 19, 25 }; if (nphy->hang_avoid) b43_nphy_stay_in_carrier_search(dev, 1); From e8366bbabe1d207cf7c5b11ae50e223ae6fc278b Mon Sep 17 00:00:00 2001 From: Haowen Bai Date: Fri, 1 Apr 2022 15:10:54 +0800 Subject: [PATCH 101/228] ipw2x00: Fix potential NULL dereference in libipw_xmit() crypt and crypt->ops could be null, so we need to checking null before dereference Signed-off-by: Haowen Bai Signed-off-by: Kalle Valo Link: https://lore.kernel.org/r/1648797055-25730-1-git-send-email-baihaowen@meizu.com --- drivers/net/wireless/intel/ipw2x00/libipw_tx.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/net/wireless/intel/ipw2x00/libipw_tx.c b/drivers/net/wireless/intel/ipw2x00/libipw_tx.c index 36d1e6b2568db..4aec1fce1ae29 100644 --- a/drivers/net/wireless/intel/ipw2x00/libipw_tx.c +++ b/drivers/net/wireless/intel/ipw2x00/libipw_tx.c @@ -383,7 +383,7 @@ netdev_tx_t libipw_xmit(struct sk_buff *skb, struct net_device *dev) /* Each fragment may need to have room for encryption * pre/postfix */ - if (host_encrypt) + if (host_encrypt && crypt && crypt->ops) bytes_per_frag -= crypt->ops->extra_mpdu_prefix_len + crypt->ops->extra_mpdu_postfix_len; From 3223e922ccf8b5c3dd0b05faeaba407655ee0774 Mon Sep 17 00:00:00 2001 From: Christophe Leroy Date: Sat, 2 Apr 2022 12:10:37 +0200 Subject: [PATCH 102/228] orinoco: Prepare cleanup of powerpc's asm/prom.h powerpc's asm/prom.h brings some headers that it doesn't need itself. In order to clean it up, first add missing headers in users of asm/prom.h Signed-off-by: Christophe Leroy Signed-off-by: Kalle Valo Link: https://lore.kernel.org/r/4e3bfd4ffe2ed6b713ddd99b69dcc3d96adffe34.1648833427.git.christophe.leroy@csgroup.eu --- drivers/net/wireless/intersil/orinoco/airport.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/net/wireless/intersil/orinoco/airport.c b/drivers/net/wireless/intersil/orinoco/airport.c index 77e6c53040a35..a890bfa0d5cc4 100644 --- a/drivers/net/wireless/intersil/orinoco/airport.c +++ b/drivers/net/wireless/intersil/orinoco/airport.c @@ -18,6 +18,7 @@ #include #include #include +#include #include #include "orinoco.h" From 92bbf95df7683d3ab1ab1aa3aaa029c5c5870591 Mon Sep 17 00:00:00 2001 From: Meng Tang Date: Wed, 6 Apr 2022 09:54:44 +0800 Subject: [PATCH 103/228] ipw2x00: use DEVICE_ATTR_*() macro Use DEVICE_ATTR_*() helper instead of plain DEVICE_ATTR, which makes the code a bit shorter and easier to read. Signed-off-by: Meng Tang Signed-off-by: Kalle Valo Link: https://lore.kernel.org/r/20220406015444.14408-1-tangmeng@uniontech.com --- drivers/net/wireless/intel/ipw2x00/ipw2100.c | 64 +++++----- drivers/net/wireless/intel/ipw2x00/ipw2200.c | 119 +++++++++---------- 2 files changed, 90 insertions(+), 93 deletions(-) diff --git a/drivers/net/wireless/intel/ipw2x00/ipw2100.c b/drivers/net/wireless/intel/ipw2x00/ipw2100.c index 2ace2b27ecad2..5234511dac78a 100644 --- a/drivers/net/wireless/intel/ipw2x00/ipw2100.c +++ b/drivers/net/wireless/intel/ipw2x00/ipw2100.c @@ -3501,7 +3501,7 @@ static void ipw2100_msg_free(struct ipw2100_priv *priv) priv->msg_buffers = NULL; } -static ssize_t show_pci(struct device *d, struct device_attribute *attr, +static ssize_t pci_show(struct device *d, struct device_attribute *attr, char *buf) { struct pci_dev *pci_dev = to_pci_dev(d); @@ -3521,34 +3521,34 @@ static ssize_t show_pci(struct device *d, struct device_attribute *attr, return out - buf; } -static DEVICE_ATTR(pci, 0444, show_pci, NULL); +static DEVICE_ATTR_RO(pci); -static ssize_t show_cfg(struct device *d, struct device_attribute *attr, +static ssize_t cfg_show(struct device *d, struct device_attribute *attr, char *buf) { struct ipw2100_priv *p = dev_get_drvdata(d); return sprintf(buf, "0x%08x\n", (int)p->config); } -static DEVICE_ATTR(cfg, 0444, show_cfg, NULL); +static DEVICE_ATTR_RO(cfg); -static ssize_t show_status(struct device *d, struct device_attribute *attr, +static ssize_t status_show(struct device *d, struct device_attribute *attr, char *buf) { struct ipw2100_priv *p = dev_get_drvdata(d); return sprintf(buf, "0x%08x\n", (int)p->status); } -static DEVICE_ATTR(status, 0444, show_status, NULL); +static DEVICE_ATTR_RO(status); -static ssize_t show_capability(struct device *d, struct device_attribute *attr, +static ssize_t capability_show(struct device *d, struct device_attribute *attr, char *buf) { struct ipw2100_priv *p = dev_get_drvdata(d); return sprintf(buf, "0x%08x\n", (int)p->capability); } -static DEVICE_ATTR(capability, 0444, show_capability, NULL); +static DEVICE_ATTR_RO(capability); #define IPW2100_REG(x) { IPW_ ##x, #x } static const struct { @@ -3785,7 +3785,7 @@ IPW2100_ORD(STAT_TX_HOST_REQUESTS, "requested Host Tx's (MSDU)"), IPW2100_ORD(NIC_MANF_DATE_TIME, "MANF Date/Time STAMP"), IPW2100_ORD(UCODE_VERSION, "Ucode Version"),}; -static ssize_t show_registers(struct device *d, struct device_attribute *attr, +static ssize_t registers_show(struct device *d, struct device_attribute *attr, char *buf) { int i; @@ -3805,9 +3805,9 @@ static ssize_t show_registers(struct device *d, struct device_attribute *attr, return out - buf; } -static DEVICE_ATTR(registers, 0444, show_registers, NULL); +static DEVICE_ATTR_RO(registers); -static ssize_t show_hardware(struct device *d, struct device_attribute *attr, +static ssize_t hardware_show(struct device *d, struct device_attribute *attr, char *buf) { struct ipw2100_priv *priv = dev_get_drvdata(d); @@ -3846,9 +3846,9 @@ static ssize_t show_hardware(struct device *d, struct device_attribute *attr, return out - buf; } -static DEVICE_ATTR(hardware, 0444, show_hardware, NULL); +static DEVICE_ATTR_RO(hardware); -static ssize_t show_memory(struct device *d, struct device_attribute *attr, +static ssize_t memory_show(struct device *d, struct device_attribute *attr, char *buf) { struct ipw2100_priv *priv = dev_get_drvdata(d); @@ -3905,7 +3905,7 @@ static ssize_t show_memory(struct device *d, struct device_attribute *attr, return len; } -static ssize_t store_memory(struct device *d, struct device_attribute *attr, +static ssize_t memory_store(struct device *d, struct device_attribute *attr, const char *buf, size_t count) { struct ipw2100_priv *priv = dev_get_drvdata(d); @@ -3940,9 +3940,9 @@ static ssize_t store_memory(struct device *d, struct device_attribute *attr, return count; } -static DEVICE_ATTR(memory, 0644, show_memory, store_memory); +static DEVICE_ATTR_RW(memory); -static ssize_t show_ordinals(struct device *d, struct device_attribute *attr, +static ssize_t ordinals_show(struct device *d, struct device_attribute *attr, char *buf) { struct ipw2100_priv *priv = dev_get_drvdata(d); @@ -3976,9 +3976,9 @@ static ssize_t show_ordinals(struct device *d, struct device_attribute *attr, return len; } -static DEVICE_ATTR(ordinals, 0444, show_ordinals, NULL); +static DEVICE_ATTR_RO(ordinals); -static ssize_t show_stats(struct device *d, struct device_attribute *attr, +static ssize_t stats_show(struct device *d, struct device_attribute *attr, char *buf) { struct ipw2100_priv *priv = dev_get_drvdata(d); @@ -3997,7 +3997,7 @@ static ssize_t show_stats(struct device *d, struct device_attribute *attr, return out - buf; } -static DEVICE_ATTR(stats, 0444, show_stats, NULL); +static DEVICE_ATTR_RO(stats); static int ipw2100_switch_mode(struct ipw2100_priv *priv, u32 mode) { @@ -4043,7 +4043,7 @@ static int ipw2100_switch_mode(struct ipw2100_priv *priv, u32 mode) return 0; } -static ssize_t show_internals(struct device *d, struct device_attribute *attr, +static ssize_t internals_show(struct device *d, struct device_attribute *attr, char *buf) { struct ipw2100_priv *priv = dev_get_drvdata(d); @@ -4095,9 +4095,9 @@ static ssize_t show_internals(struct device *d, struct device_attribute *attr, return len; } -static DEVICE_ATTR(internals, 0444, show_internals, NULL); +static DEVICE_ATTR_RO(internals); -static ssize_t show_bssinfo(struct device *d, struct device_attribute *attr, +static ssize_t bssinfo_show(struct device *d, struct device_attribute *attr, char *buf) { struct ipw2100_priv *priv = dev_get_drvdata(d); @@ -4140,7 +4140,7 @@ static ssize_t show_bssinfo(struct device *d, struct device_attribute *attr, return out - buf; } -static DEVICE_ATTR(bssinfo, 0444, show_bssinfo, NULL); +static DEVICE_ATTR_RO(bssinfo); #ifdef CONFIG_IPW2100_DEBUG static ssize_t debug_level_show(struct device_driver *d, char *buf) @@ -4165,7 +4165,7 @@ static ssize_t debug_level_store(struct device_driver *d, static DRIVER_ATTR_RW(debug_level); #endif /* CONFIG_IPW2100_DEBUG */ -static ssize_t show_fatal_error(struct device *d, +static ssize_t fatal_error_show(struct device *d, struct device_attribute *attr, char *buf) { struct ipw2100_priv *priv = dev_get_drvdata(d); @@ -4190,7 +4190,7 @@ static ssize_t show_fatal_error(struct device *d, return out - buf; } -static ssize_t store_fatal_error(struct device *d, +static ssize_t fatal_error_store(struct device *d, struct device_attribute *attr, const char *buf, size_t count) { @@ -4199,16 +4199,16 @@ static ssize_t store_fatal_error(struct device *d, return count; } -static DEVICE_ATTR(fatal_error, 0644, show_fatal_error, store_fatal_error); +static DEVICE_ATTR_RW(fatal_error); -static ssize_t show_scan_age(struct device *d, struct device_attribute *attr, +static ssize_t scan_age_show(struct device *d, struct device_attribute *attr, char *buf) { struct ipw2100_priv *priv = dev_get_drvdata(d); return sprintf(buf, "%d\n", priv->ieee->scan_age); } -static ssize_t store_scan_age(struct device *d, struct device_attribute *attr, +static ssize_t scan_age_store(struct device *d, struct device_attribute *attr, const char *buf, size_t count) { struct ipw2100_priv *priv = dev_get_drvdata(d); @@ -4232,9 +4232,9 @@ static ssize_t store_scan_age(struct device *d, struct device_attribute *attr, return strnlen(buf, count); } -static DEVICE_ATTR(scan_age, 0644, show_scan_age, store_scan_age); +static DEVICE_ATTR_RW(scan_age); -static ssize_t show_rf_kill(struct device *d, struct device_attribute *attr, +static ssize_t rf_kill_show(struct device *d, struct device_attribute *attr, char *buf) { /* 0 - RF kill not enabled @@ -4278,7 +4278,7 @@ static int ipw_radio_kill_sw(struct ipw2100_priv *priv, int disable_radio) return 1; } -static ssize_t store_rf_kill(struct device *d, struct device_attribute *attr, +static ssize_t rf_kill_store(struct device *d, struct device_attribute *attr, const char *buf, size_t count) { struct ipw2100_priv *priv = dev_get_drvdata(d); @@ -4286,7 +4286,7 @@ static ssize_t store_rf_kill(struct device *d, struct device_attribute *attr, return count; } -static DEVICE_ATTR(rf_kill, 0644, show_rf_kill, store_rf_kill); +static DEVICE_ATTR_RW(rf_kill); static struct attribute *ipw2100_sysfs_entries[] = { &dev_attr_hardware.attr, diff --git a/drivers/net/wireless/intel/ipw2x00/ipw2200.c b/drivers/net/wireless/intel/ipw2x00/ipw2200.c index 5727c7c00a281..ed343d4fb9d56 100644 --- a/drivers/net/wireless/intel/ipw2x00/ipw2200.c +++ b/drivers/net/wireless/intel/ipw2x00/ipw2200.c @@ -1259,7 +1259,7 @@ static struct ipw_fw_error *ipw_alloc_error_log(struct ipw_priv *priv) return error; } -static ssize_t show_event_log(struct device *d, +static ssize_t event_log_show(struct device *d, struct device_attribute *attr, char *buf) { struct ipw_priv *priv = dev_get_drvdata(d); @@ -1289,9 +1289,9 @@ static ssize_t show_event_log(struct device *d, return len; } -static DEVICE_ATTR(event_log, 0444, show_event_log, NULL); +static DEVICE_ATTR_RO(event_log); -static ssize_t show_error(struct device *d, +static ssize_t error_show(struct device *d, struct device_attribute *attr, char *buf) { struct ipw_priv *priv = dev_get_drvdata(d); @@ -1326,7 +1326,7 @@ static ssize_t show_error(struct device *d, return len; } -static ssize_t clear_error(struct device *d, +static ssize_t error_store(struct device *d, struct device_attribute *attr, const char *buf, size_t count) { @@ -1337,9 +1337,9 @@ static ssize_t clear_error(struct device *d, return count; } -static DEVICE_ATTR(error, 0644, show_error, clear_error); +static DEVICE_ATTR_RW(error); -static ssize_t show_cmd_log(struct device *d, +static ssize_t cmd_log_show(struct device *d, struct device_attribute *attr, char *buf) { struct ipw_priv *priv = dev_get_drvdata(d); @@ -1364,12 +1364,12 @@ static ssize_t show_cmd_log(struct device *d, return len; } -static DEVICE_ATTR(cmd_log, 0444, show_cmd_log, NULL); +static DEVICE_ATTR_RO(cmd_log); #ifdef CONFIG_IPW2200_PROMISCUOUS static void ipw_prom_free(struct ipw_priv *priv); static int ipw_prom_alloc(struct ipw_priv *priv); -static ssize_t store_rtap_iface(struct device *d, +static ssize_t rtap_iface_store(struct device *d, struct device_attribute *attr, const char *buf, size_t count) { @@ -1414,7 +1414,7 @@ static ssize_t store_rtap_iface(struct device *d, return count; } -static ssize_t show_rtap_iface(struct device *d, +static ssize_t rtap_iface_show(struct device *d, struct device_attribute *attr, char *buf) { @@ -1429,9 +1429,9 @@ static ssize_t show_rtap_iface(struct device *d, } } -static DEVICE_ATTR(rtap_iface, 0600, show_rtap_iface, store_rtap_iface); +static DEVICE_ATTR_ADMIN_RW(rtap_iface); -static ssize_t store_rtap_filter(struct device *d, +static ssize_t rtap_filter_store(struct device *d, struct device_attribute *attr, const char *buf, size_t count) { @@ -1451,7 +1451,7 @@ static ssize_t store_rtap_filter(struct device *d, return count; } -static ssize_t show_rtap_filter(struct device *d, +static ssize_t rtap_filter_show(struct device *d, struct device_attribute *attr, char *buf) { @@ -1460,17 +1460,17 @@ static ssize_t show_rtap_filter(struct device *d, priv->prom_priv ? priv->prom_priv->filter : 0); } -static DEVICE_ATTR(rtap_filter, 0600, show_rtap_filter, store_rtap_filter); +static DEVICE_ATTR_ADMIN_RW(rtap_filter); #endif -static ssize_t show_scan_age(struct device *d, struct device_attribute *attr, +static ssize_t scan_age_show(struct device *d, struct device_attribute *attr, char *buf) { struct ipw_priv *priv = dev_get_drvdata(d); return sprintf(buf, "%d\n", priv->ieee->scan_age); } -static ssize_t store_scan_age(struct device *d, struct device_attribute *attr, +static ssize_t scan_age_store(struct device *d, struct device_attribute *attr, const char *buf, size_t count) { struct ipw_priv *priv = dev_get_drvdata(d); @@ -1504,16 +1504,16 @@ static ssize_t store_scan_age(struct device *d, struct device_attribute *attr, return len; } -static DEVICE_ATTR(scan_age, 0644, show_scan_age, store_scan_age); +static DEVICE_ATTR_RW(scan_age); -static ssize_t show_led(struct device *d, struct device_attribute *attr, +static ssize_t led_show(struct device *d, struct device_attribute *attr, char *buf) { struct ipw_priv *priv = dev_get_drvdata(d); return sprintf(buf, "%d\n", (priv->config & CFG_NO_LED) ? 0 : 1); } -static ssize_t store_led(struct device *d, struct device_attribute *attr, +static ssize_t led_store(struct device *d, struct device_attribute *attr, const char *buf, size_t count) { struct ipw_priv *priv = dev_get_drvdata(d); @@ -1537,36 +1537,36 @@ static ssize_t store_led(struct device *d, struct device_attribute *attr, return count; } -static DEVICE_ATTR(led, 0644, show_led, store_led); +static DEVICE_ATTR_RW(led); -static ssize_t show_status(struct device *d, +static ssize_t status_show(struct device *d, struct device_attribute *attr, char *buf) { struct ipw_priv *p = dev_get_drvdata(d); return sprintf(buf, "0x%08x\n", (int)p->status); } -static DEVICE_ATTR(status, 0444, show_status, NULL); +static DEVICE_ATTR_RO(status); -static ssize_t show_cfg(struct device *d, struct device_attribute *attr, +static ssize_t cfg_show(struct device *d, struct device_attribute *attr, char *buf) { struct ipw_priv *p = dev_get_drvdata(d); return sprintf(buf, "0x%08x\n", (int)p->config); } -static DEVICE_ATTR(cfg, 0444, show_cfg, NULL); +static DEVICE_ATTR_RO(cfg); -static ssize_t show_nic_type(struct device *d, +static ssize_t nic_type_show(struct device *d, struct device_attribute *attr, char *buf) { struct ipw_priv *priv = dev_get_drvdata(d); return sprintf(buf, "TYPE: %d\n", priv->nic_type); } -static DEVICE_ATTR(nic_type, 0444, show_nic_type, NULL); +static DEVICE_ATTR_RO(nic_type); -static ssize_t show_ucode_version(struct device *d, +static ssize_t ucode_version_show(struct device *d, struct device_attribute *attr, char *buf) { u32 len = sizeof(u32), tmp = 0; @@ -1578,9 +1578,9 @@ static ssize_t show_ucode_version(struct device *d, return sprintf(buf, "0x%08x\n", tmp); } -static DEVICE_ATTR(ucode_version, 0644, show_ucode_version, NULL); +static DEVICE_ATTR_RO(ucode_version); -static ssize_t show_rtc(struct device *d, struct device_attribute *attr, +static ssize_t rtc_show(struct device *d, struct device_attribute *attr, char *buf) { u32 len = sizeof(u32), tmp = 0; @@ -1592,20 +1592,20 @@ static ssize_t show_rtc(struct device *d, struct device_attribute *attr, return sprintf(buf, "0x%08x\n", tmp); } -static DEVICE_ATTR(rtc, 0644, show_rtc, NULL); +static DEVICE_ATTR_RO(rtc); /* * Add a device attribute to view/control the delay between eeprom * operations. */ -static ssize_t show_eeprom_delay(struct device *d, +static ssize_t eeprom_delay_show(struct device *d, struct device_attribute *attr, char *buf) { struct ipw_priv *p = dev_get_drvdata(d); int n = p->eeprom_delay; return sprintf(buf, "%i\n", n); } -static ssize_t store_eeprom_delay(struct device *d, +static ssize_t eeprom_delay_store(struct device *d, struct device_attribute *attr, const char *buf, size_t count) { @@ -1614,9 +1614,9 @@ static ssize_t store_eeprom_delay(struct device *d, return strnlen(buf, count); } -static DEVICE_ATTR(eeprom_delay, 0644, show_eeprom_delay, store_eeprom_delay); +static DEVICE_ATTR_RW(eeprom_delay); -static ssize_t show_command_event_reg(struct device *d, +static ssize_t command_event_reg_show(struct device *d, struct device_attribute *attr, char *buf) { u32 reg = 0; @@ -1625,7 +1625,7 @@ static ssize_t show_command_event_reg(struct device *d, reg = ipw_read_reg32(p, IPW_INTERNAL_CMD_EVENT); return sprintf(buf, "0x%08x\n", reg); } -static ssize_t store_command_event_reg(struct device *d, +static ssize_t command_event_reg_store(struct device *d, struct device_attribute *attr, const char *buf, size_t count) { @@ -1637,10 +1637,9 @@ static ssize_t store_command_event_reg(struct device *d, return strnlen(buf, count); } -static DEVICE_ATTR(command_event_reg, 0644, - show_command_event_reg, store_command_event_reg); +static DEVICE_ATTR_RW(command_event_reg); -static ssize_t show_mem_gpio_reg(struct device *d, +static ssize_t mem_gpio_reg_show(struct device *d, struct device_attribute *attr, char *buf) { u32 reg = 0; @@ -1649,7 +1648,7 @@ static ssize_t show_mem_gpio_reg(struct device *d, reg = ipw_read_reg32(p, 0x301100); return sprintf(buf, "0x%08x\n", reg); } -static ssize_t store_mem_gpio_reg(struct device *d, +static ssize_t mem_gpio_reg_store(struct device *d, struct device_attribute *attr, const char *buf, size_t count) { @@ -1661,9 +1660,9 @@ static ssize_t store_mem_gpio_reg(struct device *d, return strnlen(buf, count); } -static DEVICE_ATTR(mem_gpio_reg, 0644, show_mem_gpio_reg, store_mem_gpio_reg); +static DEVICE_ATTR_RW(mem_gpio_reg); -static ssize_t show_indirect_dword(struct device *d, +static ssize_t indirect_dword_show(struct device *d, struct device_attribute *attr, char *buf) { u32 reg = 0; @@ -1676,7 +1675,7 @@ static ssize_t show_indirect_dword(struct device *d, return sprintf(buf, "0x%08x\n", reg); } -static ssize_t store_indirect_dword(struct device *d, +static ssize_t indirect_dword_store(struct device *d, struct device_attribute *attr, const char *buf, size_t count) { @@ -1687,10 +1686,9 @@ static ssize_t store_indirect_dword(struct device *d, return strnlen(buf, count); } -static DEVICE_ATTR(indirect_dword, 0644, - show_indirect_dword, store_indirect_dword); +static DEVICE_ATTR_RW(indirect_dword); -static ssize_t show_indirect_byte(struct device *d, +static ssize_t indirect_byte_show(struct device *d, struct device_attribute *attr, char *buf) { u8 reg = 0; @@ -1703,7 +1701,7 @@ static ssize_t show_indirect_byte(struct device *d, return sprintf(buf, "0x%02x\n", reg); } -static ssize_t store_indirect_byte(struct device *d, +static ssize_t indirect_byte_store(struct device *d, struct device_attribute *attr, const char *buf, size_t count) { @@ -1714,10 +1712,9 @@ static ssize_t store_indirect_byte(struct device *d, return strnlen(buf, count); } -static DEVICE_ATTR(indirect_byte, 0644, - show_indirect_byte, store_indirect_byte); +static DEVICE_ATTR_RW(indirect_byte); -static ssize_t show_direct_dword(struct device *d, +static ssize_t direct_dword_show(struct device *d, struct device_attribute *attr, char *buf) { u32 reg = 0; @@ -1730,7 +1727,7 @@ static ssize_t show_direct_dword(struct device *d, return sprintf(buf, "0x%08x\n", reg); } -static ssize_t store_direct_dword(struct device *d, +static ssize_t direct_dword_store(struct device *d, struct device_attribute *attr, const char *buf, size_t count) { @@ -1741,7 +1738,7 @@ static ssize_t store_direct_dword(struct device *d, return strnlen(buf, count); } -static DEVICE_ATTR(direct_dword, 0644, show_direct_dword, store_direct_dword); +static DEVICE_ATTR_RW(direct_dword); static int rf_kill_active(struct ipw_priv *priv) { @@ -1756,7 +1753,7 @@ static int rf_kill_active(struct ipw_priv *priv) return (priv->status & STATUS_RF_KILL_HW) ? 1 : 0; } -static ssize_t show_rf_kill(struct device *d, struct device_attribute *attr, +static ssize_t rf_kill_show(struct device *d, struct device_attribute *attr, char *buf) { /* 0 - RF kill not enabled @@ -1802,7 +1799,7 @@ static int ipw_radio_kill_sw(struct ipw_priv *priv, int disable_radio) return 1; } -static ssize_t store_rf_kill(struct device *d, struct device_attribute *attr, +static ssize_t rf_kill_store(struct device *d, struct device_attribute *attr, const char *buf, size_t count) { struct ipw_priv *priv = dev_get_drvdata(d); @@ -1812,9 +1809,9 @@ static ssize_t store_rf_kill(struct device *d, struct device_attribute *attr, return count; } -static DEVICE_ATTR(rf_kill, 0644, show_rf_kill, store_rf_kill); +static DEVICE_ATTR_RW(rf_kill); -static ssize_t show_speed_scan(struct device *d, struct device_attribute *attr, +static ssize_t speed_scan_show(struct device *d, struct device_attribute *attr, char *buf) { struct ipw_priv *priv = dev_get_drvdata(d); @@ -1829,7 +1826,7 @@ static ssize_t show_speed_scan(struct device *d, struct device_attribute *attr, return sprintf(buf, "0\n"); } -static ssize_t store_speed_scan(struct device *d, struct device_attribute *attr, +static ssize_t speed_scan_store(struct device *d, struct device_attribute *attr, const char *buf, size_t count) { struct ipw_priv *priv = dev_get_drvdata(d); @@ -1865,16 +1862,16 @@ static ssize_t store_speed_scan(struct device *d, struct device_attribute *attr, return count; } -static DEVICE_ATTR(speed_scan, 0644, show_speed_scan, store_speed_scan); +static DEVICE_ATTR_RW(speed_scan); -static ssize_t show_net_stats(struct device *d, struct device_attribute *attr, +static ssize_t net_stats_show(struct device *d, struct device_attribute *attr, char *buf) { struct ipw_priv *priv = dev_get_drvdata(d); return sprintf(buf, "%c\n", (priv->config & CFG_NET_STATS) ? '1' : '0'); } -static ssize_t store_net_stats(struct device *d, struct device_attribute *attr, +static ssize_t net_stats_store(struct device *d, struct device_attribute *attr, const char *buf, size_t count) { struct ipw_priv *priv = dev_get_drvdata(d); @@ -1886,9 +1883,9 @@ static ssize_t store_net_stats(struct device *d, struct device_attribute *attr, return count; } -static DEVICE_ATTR(net_stats, 0644, show_net_stats, store_net_stats); +static DEVICE_ATTR_RW(net_stats); -static ssize_t show_channels(struct device *d, +static ssize_t channels_show(struct device *d, struct device_attribute *attr, char *buf) { @@ -1932,7 +1929,7 @@ static ssize_t show_channels(struct device *d, return len; } -static DEVICE_ATTR(channels, 0400, show_channels, NULL); +static DEVICE_ATTR_ADMIN_RO(channels); static void notify_wx_assoc_event(struct ipw_priv *priv) { From 450c271d508f47577cce509582f1041eeb947e6e Mon Sep 17 00:00:00 2001 From: Lorenzo Bianconi Date: Thu, 7 Apr 2022 12:36:58 +0200 Subject: [PATCH 104/228] mac80211: protect ieee80211_assign_beacon with next_beacon check Even if it is not a real issue since ieee80211_set_after_csa_beacon() or ieee80211_set_after_color_change_beacon() are run only when csa or bcc is active, move next_beacon check before running ieee80211_assign_beacon routine. Signed-off-by: Lorenzo Bianconi Link: https://lore.kernel.org/r/041764ed7e9781bcee66c33b41f1365aa4205932.1649327683.git.lorenzo@kernel.org Signed-off-by: Johannes Berg --- net/mac80211/cfg.c | 22 ++++++++++++---------- 1 file changed, 12 insertions(+), 10 deletions(-) diff --git a/net/mac80211/cfg.c b/net/mac80211/cfg.c index ba752539d1d9f..8e14ff53e4bd3 100644 --- a/net/mac80211/cfg.c +++ b/net/mac80211/cfg.c @@ -3306,13 +3306,14 @@ static int ieee80211_set_after_csa_beacon(struct ieee80211_sub_if_data *sdata, switch (sdata->vif.type) { case NL80211_IFTYPE_AP: + if (!sdata->u.ap.next_beacon) + return -EINVAL; + err = ieee80211_assign_beacon(sdata, sdata->u.ap.next_beacon, NULL, NULL); - if (sdata->u.ap.next_beacon) { - kfree(sdata->u.ap.next_beacon->mbssid_ies); - kfree(sdata->u.ap.next_beacon); - sdata->u.ap.next_beacon = NULL; - } + kfree(sdata->u.ap.next_beacon->mbssid_ies); + kfree(sdata->u.ap.next_beacon); + sdata->u.ap.next_beacon = NULL; if (err < 0) return err; @@ -4314,13 +4315,14 @@ ieee80211_set_after_color_change_beacon(struct ieee80211_sub_if_data *sdata, case NL80211_IFTYPE_AP: { int ret; + if (!sdata->u.ap.next_beacon) + return -EINVAL; + ret = ieee80211_assign_beacon(sdata, sdata->u.ap.next_beacon, NULL, NULL); - if (sdata->u.ap.next_beacon) { - kfree(sdata->u.ap.next_beacon->mbssid_ies); - kfree(sdata->u.ap.next_beacon); - sdata->u.ap.next_beacon = NULL; - } + kfree(sdata->u.ap.next_beacon->mbssid_ies); + kfree(sdata->u.ap.next_beacon); + sdata->u.ap.next_beacon = NULL; if (ret < 0) return ret; From e5c95ca094cfe59a4013d711f87ff034cba30f80 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Toke=20H=C3=B8iland-J=C3=B8rgensen?= Date: Mon, 4 Apr 2022 23:01:08 +0200 Subject: [PATCH 105/228] mac80211: Improve confusing comment around tx_info clearing MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The comment above the ieee80211_tx_info_clear_status() helper was somewhat confusing as to which fields it was or wasn't clearing. So replace it by something that is hopefully more, well, clear. Signed-off-by: Toke Høiland-Jørgensen Link: https://lore.kernel.org/r/20220404210108.2684907-1-toke@toke.dk Signed-off-by: Johannes Berg --- include/net/mac80211.h | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/include/net/mac80211.h b/include/net/mac80211.h index 382ebb862ea8f..db992f71604d9 100644 --- a/include/net/mac80211.h +++ b/include/net/mac80211.h @@ -1201,9 +1201,9 @@ static inline struct ieee80211_rx_status *IEEE80211_SKB_RXCB(struct sk_buff *skb * in the TX status but the rate control information (it does clear * the count since you need to fill that in anyway). * - * NOTE: You can only use this function if you do NOT use - * info->driver_data! Use info->rate_driver_data - * instead if you need only the less space that allows. + * NOTE: While the rates array is kept intact, this will wipe all of the + * driver_data fields in info, so it's up to the driver to restore + * any fields it needs after calling this helper. */ static inline void ieee80211_tx_info_clear_status(struct ieee80211_tx_info *info) From 6d945a33f2b0aa24fc210dadaa0af3e8218e7002 Mon Sep 17 00:00:00 2001 From: Lorenzo Bianconi Date: Fri, 25 Mar 2022 11:42:41 +0100 Subject: [PATCH 106/228] mac80211: introduce BSS color collision detection Add ieee80211_rx_check_bss_color_collision routine in order to introduce BSS color collision detection in mac80211 if it is not supported in HW/FW (e.g. for mt7915 chipset). Add IEEE80211_HW_DETECTS_COLOR_COLLISION flag to let the driver notify BSS color collision detection is supported in HW/FW. Set this for ath11k which apparently didn't need this code. Tested-by: Peter Chiu Co-developed-by: Ryder Lee Signed-off-by: Ryder Lee Signed-off-by: Lorenzo Bianconi Link: https://lore.kernel.org/r/a05eeeb1841a84560dc5aaec77894fcb69a54f27.1648204871.git.lorenzo@kernel.org [clarify commit message a bit, move flag to mac80211] Signed-off-by: Johannes Berg --- drivers/net/wireless/ath/ath11k/mac.c | 5 ++- include/net/mac80211.h | 4 +++ net/mac80211/debugfs.c | 1 + net/mac80211/rx.c | 46 +++++++++++++++++++++++++++ 4 files changed, 55 insertions(+), 1 deletion(-) diff --git a/drivers/net/wireless/ath/ath11k/mac.c b/drivers/net/wireless/ath/ath11k/mac.c index 175a4ae752f3a..49421d91d39c7 100644 --- a/drivers/net/wireless/ath/ath11k/mac.c +++ b/drivers/net/wireless/ath/ath11k/mac.c @@ -8720,9 +8720,12 @@ static int __ath11k_mac_register(struct ath11k *ar) wiphy_ext_feature_set(ar->hw->wiphy, NL80211_EXT_FEATURE_CQM_RSSI_LIST); wiphy_ext_feature_set(ar->hw->wiphy, NL80211_EXT_FEATURE_STA_TX_PWR); - if (test_bit(WMI_TLV_SERVICE_BSS_COLOR_OFFLOAD, ar->ab->wmi_ab.svc_map)) + if (test_bit(WMI_TLV_SERVICE_BSS_COLOR_OFFLOAD, + ar->ab->wmi_ab.svc_map)) { wiphy_ext_feature_set(ar->hw->wiphy, NL80211_EXT_FEATURE_BSS_COLOR); + ieee80211_hw_set(ar->hw, DETECTS_COLOR_COLLISION); + } ar->hw->wiphy->cipher_suites = cipher_suites; ar->hw->wiphy->n_cipher_suites = ARRAY_SIZE(cipher_suites); diff --git a/include/net/mac80211.h b/include/net/mac80211.h index db992f71604d9..0943b2626f4dc 100644 --- a/include/net/mac80211.h +++ b/include/net/mac80211.h @@ -2434,6 +2434,9 @@ struct ieee80211_txq { * usage and 802.11 frames with %RX_FLAG_ONLY_MONITOR set for monitor to * the stack. * + * @IEEE80211_HW_DETECTS_COLOR_COLLISION: HW/driver has support for BSS color + * collision detection and doesn't need it in software. + * * @NUM_IEEE80211_HW_FLAGS: number of hardware flags, used for sizing arrays */ enum ieee80211_hw_flags { @@ -2489,6 +2492,7 @@ enum ieee80211_hw_flags { IEEE80211_HW_SUPPORTS_TX_ENCAP_OFFLOAD, IEEE80211_HW_SUPPORTS_RX_DECAP_OFFLOAD, IEEE80211_HW_SUPPORTS_CONC_MON_RX_DECAP, + IEEE80211_HW_DETECTS_COLOR_COLLISION, /* keep last, obviously */ NUM_IEEE80211_HW_FLAGS diff --git a/net/mac80211/debugfs.c b/net/mac80211/debugfs.c index f4c9a92f50f95..1fe43b264d757 100644 --- a/net/mac80211/debugfs.c +++ b/net/mac80211/debugfs.c @@ -504,6 +504,7 @@ static const char *hw_flag_names[] = { FLAG(SUPPORTS_TX_ENCAP_OFFLOAD), FLAG(SUPPORTS_RX_DECAP_OFFLOAD), FLAG(SUPPORTS_CONC_MON_RX_DECAP), + FLAG(DETECTS_COLOR_COLLISION), #undef FLAG }; diff --git a/net/mac80211/rx.c b/net/mac80211/rx.c index beb6b92eb7804..03ee1d9b6d086 100644 --- a/net/mac80211/rx.c +++ b/net/mac80211/rx.c @@ -3178,6 +3178,49 @@ static void ieee80211_process_sa_query_req(struct ieee80211_sub_if_data *sdata, ieee80211_tx_skb(sdata, skb); } +static void +ieee80211_rx_check_bss_color_collision(struct ieee80211_rx_data *rx) +{ + struct ieee80211_mgmt *mgmt = (void *)rx->skb->data; + const struct element *ie; + size_t baselen; + + if (!wiphy_ext_feature_isset(rx->local->hw.wiphy, + NL80211_EXT_FEATURE_BSS_COLOR)) + return; + + if (ieee80211_hw_check(&rx->local->hw, DETECTS_COLOR_COLLISION)) + return; + + if (rx->sdata->vif.csa_active) + return; + + baselen = mgmt->u.beacon.variable - rx->skb->data; + if (baselen > rx->skb->len) + return; + + ie = cfg80211_find_ext_elem(WLAN_EID_EXT_HE_OPERATION, + mgmt->u.beacon.variable, + rx->skb->len - baselen); + if (ie && ie->datalen >= sizeof(struct ieee80211_he_operation) && + ie->datalen >= ieee80211_he_oper_size(ie->data + 1)) { + struct ieee80211_bss_conf *bss_conf = &rx->sdata->vif.bss_conf; + const struct ieee80211_he_operation *he_oper; + u8 color; + + he_oper = (void *)(ie->data + 1); + if (le32_get_bits(he_oper->he_oper_params, + IEEE80211_HE_OPERATION_BSS_COLOR_DISABLED)) + return; + + color = le32_get_bits(he_oper->he_oper_params, + IEEE80211_HE_OPERATION_BSS_COLOR_MASK); + if (color == bss_conf->he_bss_color.color) + ieeee80211_obss_color_collision_notify(&rx->sdata->vif, + BIT_ULL(color)); + } +} + static ieee80211_rx_result debug_noinline ieee80211_rx_h_mgmt_check(struct ieee80211_rx_data *rx) { @@ -3203,6 +3246,9 @@ ieee80211_rx_h_mgmt_check(struct ieee80211_rx_data *rx) !(rx->flags & IEEE80211_RX_BEACON_REPORTED)) { int sig = 0; + /* sw bss color collision detection */ + ieee80211_rx_check_bss_color_collision(rx); + if (ieee80211_hw_check(&rx->local->hw, SIGNAL_DBM) && !(status->flag & RX_FLAG_NO_SIGNAL_VAL)) sig = status->signal; From a75971bc2b8453630e9f85e0beaa4da8db8277a3 Mon Sep 17 00:00:00 2001 From: Johannes Berg Date: Fri, 18 Mar 2022 13:46:57 +0100 Subject: [PATCH 107/228] nl80211: show SSID for P2P_GO interfaces There's no real reason not to send the SSID to userspace when it requests information about P2P_GO, it is, in that respect, exactly the same as AP interfaces. Fix that. Fixes: 44905265bc15 ("nl80211: don't expose wdev->ssid for most interfaces") Signed-off-by: Johannes Berg Link: https://lore.kernel.org/r/20220318134656.14354ae223f0.Ia25e85a512281b92e1645d4160766a4b1a471597@changeid Signed-off-by: Johannes Berg --- net/wireless/nl80211.c | 1 + 1 file changed, 1 insertion(+) diff --git a/net/wireless/nl80211.c b/net/wireless/nl80211.c index ee1c2b6b69711..711061cd02d1f 100644 --- a/net/wireless/nl80211.c +++ b/net/wireless/nl80211.c @@ -3709,6 +3709,7 @@ static int nl80211_send_iface(struct sk_buff *msg, u32 portid, u32 seq, int flag wdev_lock(wdev); switch (wdev->iftype) { case NL80211_IFTYPE_AP: + case NL80211_IFTYPE_P2P_GO: if (wdev->ssid_len && nla_put(msg, NL80211_ATTR_SSID, wdev->ssid_len, wdev->ssid)) goto nla_put_failure_locked; From 5c6dd7bd569b54c0d2904125d7366aa93f077f67 Mon Sep 17 00:00:00 2001 From: Peter Seiderer Date: Mon, 4 Apr 2022 18:54:14 +0200 Subject: [PATCH 108/228] mac80211: minstrel_ht: fix where rate stats are stored (fixes debugfs output) Using an ath9k card the debugfs output of minstrel_ht looks like the following (note the zero values for the first four rates sum-of success/attempts): best ____________rate__________ ____statistics___ _____last____ ______sum-of________ mode guard # rate [name idx airtime max_tp] [avg(tp) avg(prob)] [retry|suc|att] [#success | #attempts] OFDM 1 DP 6.0M 272 1640 5.2 3.1 53.8 3 0 0 0 0 OFDM 1 C 9.0M 273 1104 7.7 4.6 53.8 4 0 0 0 0 OFDM 1 B 12.0M 274 836 10.0 6.0 53.8 4 0 0 0 0 OFDM 1 A S 18.0M 275 568 14.3 8.5 53.8 5 0 0 0 0 OFDM 1 S 24.0M 276 436 18.1 0.0 0.0 5 0 1 80 1778 OFDM 1 36.0M 277 300 24.9 0.0 0.0 0 0 1 0 107 OFDM 1 S 48.0M 278 236 30.4 0.0 0.0 0 0 0 0 75 OFDM 1 54.0M 279 212 33.0 0.0 0.0 0 0 0 0 72 Total packet count:: ideal 16582 lookaround 885 Average # of aggregated frames per A-MPDU: 1.0 Debugging showed that the rate statistics for the first four rates where stored in the MINSTREL_CCK_GROUP instead of the MINSTREL_OFDM_GROUP because in minstrel_ht_get_stats() the supported check was not honoured as done in various other places, e.g net/mac80211/rc80211_minstrel_ht_debugfs.c: 74 if (!(mi->supported[i] & BIT(j))) 75 continue; With the patch applied the output looks good: best ____________rate__________ ____statistics___ _____last____ ______sum-of________ mode guard # rate [name idx airtime max_tp] [avg(tp) avg(prob)] [retry|suc|att] [#success | #attempts] OFDM 1 D 6.0M 272 1640 5.2 5.2 100.0 3 0 0 1 1 OFDM 1 C 9.0M 273 1104 7.7 7.7 100.0 4 0 0 38 38 OFDM 1 B 12.0M 274 836 10.0 9.9 89.5 4 2 2 372 395 OFDM 1 A P 18.0M 275 568 14.3 14.3 97.2 5 52 53 6956 7181 OFDM 1 S 24.0M 276 436 18.1 0.0 0.0 0 0 1 6 163 OFDM 1 36.0M 277 300 24.9 0.0 0.0 0 0 1 0 35 OFDM 1 S 48.0M 278 236 30.4 0.0 0.0 0 0 0 0 38 OFDM 1 S 54.0M 279 212 33.0 0.0 0.0 0 0 0 0 38 Total packet count:: ideal 7097 lookaround 287 Average # of aggregated frames per A-MPDU: 1.0 Signed-off-by: Peter Seiderer Link: https://lore.kernel.org/r/20220404165414.1036-1-ps.report@gmx.net Signed-off-by: Johannes Berg --- net/mac80211/rc80211_minstrel_ht.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/net/mac80211/rc80211_minstrel_ht.c b/net/mac80211/rc80211_minstrel_ht.c index 9c6ace858107a..5a6bf46a42483 100644 --- a/net/mac80211/rc80211_minstrel_ht.c +++ b/net/mac80211/rc80211_minstrel_ht.c @@ -362,6 +362,9 @@ minstrel_ht_get_stats(struct minstrel_priv *mp, struct minstrel_ht_sta *mi, group = MINSTREL_CCK_GROUP; for (idx = 0; idx < ARRAY_SIZE(mp->cck_rates); idx++) { + if (!(mi->supported[group] & BIT(idx))) + continue; + if (rate->idx != mp->cck_rates[idx]) continue; From 046d2e7c50e3087a32a85fd384c21f896dbccf83 Mon Sep 17 00:00:00 2001 From: Sriram R Date: Mon, 4 Apr 2022 21:11:23 +0530 Subject: [PATCH 109/228] mac80211: prepare sta handling for MLO support Currently in mac80211 each STA object is represented using sta_info datastructure with the associated STA specific information and drivers access ieee80211_sta part of it. With MLO (Multi Link Operation) support being added in 802.11be standard, though the association is logically with a single Multi Link capable STA, at the physical level communication can happen via different advertised links (uniquely identified by Channel, operating class, BSSID) and hence the need to handle multiple link STA parameters within a composite sta_info object called the MLD STA. The different link STA part of MLD STA are identified using the link address which can be same or different as the MLD STA address and unique link id based on the link vif. To support extension of such a model, the sta_info datastructure is modified to hold multiple link STA objects with link specific params currently within sta_info moved to this new structure. Similarly this is done for ieee80211_sta as well which will be accessed within mac80211 as well as by drivers, hence trivial driver changes are expected to support this. For current non MLO supported drivers, only one link STA is present and link information is accessed via 'deflink' member. For MLO drivers, we still need to define the APIs etc. to get the correct link ID and access the correct part of the station info. Currently in mac80211, all link STA info are accessed directly via deflink. These will be updated to access via link pointers indexed by link id with MLO support patches, with link id being 0 for non MLO supported cases. Except for couple of macro related changes, below spatch takes care of updating mac80211 and driver code to access to the link STA info via deflink. @ieee80211_sta@ struct ieee80211_sta *s; struct sta_info *si; identifier var = {supp_rates, ht_cap, vht_cap, he_cap, he_6ghz_capa, eht_cap, rx_nss, bandwidth, txpwr}; @@ ( s-> - var + deflink.var | si->sta. - var + deflink.var ) @sta_info@ struct sta_info *si; identifier var = {gtk, pcpu_rx_stats, rx_stats, rx_stats_avg, status_stats, tx_stats, cur_max_bandwidth}; @@ ( si-> - var + deflink.var ) Signed-off-by: Sriram R Link: https://lore.kernel.org/r/1649086883-13246-1-git-send-email-quic_srirrama@quicinc.com [remove MLO-drivers notes from commit message, not clear yet; run spatch] Signed-off-by: Johannes Berg --- drivers/net/wireless/ath/ar5523/ar5523.c | 4 +- drivers/net/wireless/ath/ath10k/mac.c | 76 ++++----- drivers/net/wireless/ath/ath11k/mac.c | 154 ++++++++--------- drivers/net/wireless/ath/ath9k/debug_sta.c | 4 +- drivers/net/wireless/ath/ath9k/htc_drv_main.c | 20 +-- drivers/net/wireless/ath/ath9k/main.c | 2 +- drivers/net/wireless/ath/ath9k/xmit.c | 6 +- drivers/net/wireless/ath/carl9170/main.c | 8 +- drivers/net/wireless/ath/carl9170/tx.c | 5 +- drivers/net/wireless/ath/wcn36xx/main.c | 18 +- drivers/net/wireless/ath/wcn36xx/smd.c | 35 ++-- .../broadcom/brcm80211/brcmsmac/mac80211_if.c | 2 +- drivers/net/wireless/intel/iwlegacy/3945-rs.c | 6 +- drivers/net/wireless/intel/iwlegacy/4965-rs.c | 22 +-- drivers/net/wireless/intel/iwlegacy/common.c | 6 +- drivers/net/wireless/intel/iwlwifi/dvm/rs.c | 22 +-- drivers/net/wireless/intel/iwlwifi/dvm/rxon.c | 2 +- drivers/net/wireless/intel/iwlwifi/dvm/sta.c | 4 +- drivers/net/wireless/intel/iwlwifi/mvm/d3.c | 2 +- .../net/wireless/intel/iwlwifi/mvm/mac80211.c | 38 ++--- .../net/wireless/intel/iwlwifi/mvm/rs-fw.c | 38 ++--- drivers/net/wireless/intel/iwlwifi/mvm/rs.c | 35 ++-- drivers/net/wireless/intel/iwlwifi/mvm/sf.c | 8 +- drivers/net/wireless/intel/iwlwifi/mvm/sta.c | 31 ++-- drivers/net/wireless/intel/iwlwifi/mvm/tx.c | 6 +- drivers/net/wireless/mac80211_hwsim.c | 4 +- drivers/net/wireless/marvell/mwl8k.c | 48 +++--- .../net/wireless/mediatek/mt76/mt7603/mac.c | 16 +- .../wireless/mediatek/mt76/mt76_connac_mcu.c | 83 +++++----- .../net/wireless/mediatek/mt76/mt76x02_mac.c | 4 +- .../wireless/mediatek/mt76/mt7915/debugfs.c | 4 +- .../net/wireless/mediatek/mt76/mt7915/mac.c | 2 +- .../net/wireless/mediatek/mt76/mt7915/mcu.c | 140 ++++++++-------- .../net/wireless/mediatek/mt76/mt7921/mac.c | 2 +- drivers/net/wireless/mediatek/mt7601u/mac.c | 2 +- drivers/net/wireless/mediatek/mt7601u/tx.c | 4 +- .../net/wireless/ralink/rt2x00/rt2800lib.c | 8 +- .../net/wireless/ralink/rt2x00/rt2x00queue.c | 2 +- .../wireless/realtek/rtl8xxxu/rtl8xxxu_core.c | 42 ++--- drivers/net/wireless/realtek/rtlwifi/base.c | 31 ++-- drivers/net/wireless/realtek/rtlwifi/core.c | 40 ++--- drivers/net/wireless/realtek/rtlwifi/rc.c | 20 +-- .../wireless/realtek/rtlwifi/rtl8188ee/hw.c | 26 +-- .../wireless/realtek/rtlwifi/rtl8188ee/trx.c | 4 +- .../wireless/realtek/rtlwifi/rtl8192ce/hw.c | 26 +-- .../wireless/realtek/rtlwifi/rtl8192ce/trx.c | 4 +- .../wireless/realtek/rtlwifi/rtl8192cu/hw.c | 26 +-- .../wireless/realtek/rtlwifi/rtl8192cu/trx.c | 2 +- .../wireless/realtek/rtlwifi/rtl8192de/hw.c | 26 +-- .../wireless/realtek/rtlwifi/rtl8192de/trx.c | 4 +- .../wireless/realtek/rtlwifi/rtl8192ee/hw.c | 12 +- .../wireless/realtek/rtlwifi/rtl8192ee/trx.c | 4 +- .../wireless/realtek/rtlwifi/rtl8192se/hw.c | 26 +-- .../wireless/realtek/rtlwifi/rtl8192se/trx.c | 2 +- .../wireless/realtek/rtlwifi/rtl8723ae/hw.c | 26 +-- .../wireless/realtek/rtlwifi/rtl8723ae/trx.c | 4 +- .../wireless/realtek/rtlwifi/rtl8723be/hw.c | 12 +- .../wireless/realtek/rtlwifi/rtl8723be/trx.c | 4 +- .../wireless/realtek/rtlwifi/rtl8821ae/hw.c | 30 ++-- .../wireless/realtek/rtlwifi/rtl8821ae/trx.c | 2 +- drivers/net/wireless/realtek/rtw88/bf.c | 2 +- drivers/net/wireless/realtek/rtw88/main.c | 50 +++--- drivers/net/wireless/realtek/rtw88/tx.c | 14 +- drivers/net/wireless/realtek/rtw89/coex.c | 12 +- drivers/net/wireless/realtek/rtw89/core.c | 6 +- drivers/net/wireless/realtek/rtw89/core.h | 10 +- drivers/net/wireless/realtek/rtw89/fw.c | 15 +- drivers/net/wireless/realtek/rtw89/mac.c | 18 +- drivers/net/wireless/realtek/rtw89/phy.c | 68 ++++---- drivers/net/wireless/rsi/rsi_91x_mac80211.c | 12 +- drivers/net/wireless/rsi/rsi_91x_mgmt.c | 8 +- drivers/net/wireless/st/cw1200/sta.c | 4 +- drivers/net/wireless/ti/wlcore/cmd.c | 8 +- drivers/net/wireless/ti/wlcore/main.c | 16 +- drivers/staging/wfx/sta.c | 8 +- include/net/mac80211.h | 80 ++++++--- net/mac80211/agg-rx.c | 12 +- net/mac80211/agg-tx.c | 6 +- net/mac80211/airtime.c | 4 +- net/mac80211/cfg.c | 11 +- net/mac80211/chan.c | 8 +- net/mac80211/debugfs_sta.c | 12 +- net/mac80211/eht.c | 6 +- net/mac80211/ethtool.c | 4 +- net/mac80211/he.c | 8 +- net/mac80211/ht.c | 8 +- net/mac80211/ibss.c | 26 +-- net/mac80211/key.c | 9 +- net/mac80211/mesh_hwmp.c | 2 +- net/mac80211/mesh_plink.c | 24 +-- net/mac80211/mlme.c | 18 +- net/mac80211/ocb.c | 2 +- net/mac80211/rate.c | 8 +- net/mac80211/rc80211_minstrel_ht.c | 20 +-- net/mac80211/rx.c | 85 +++++----- net/mac80211/s1g.c | 4 +- net/mac80211/sta_info.c | 110 +++++++------ net/mac80211/sta_info.h | 155 +++++++++++------- net/mac80211/status.c | 41 ++--- net/mac80211/tdls.c | 26 +-- net/mac80211/trace.h | 4 +- net/mac80211/tx.c | 26 +-- net/mac80211/vht.c | 78 ++++----- 103 files changed, 1200 insertions(+), 1094 deletions(-) diff --git a/drivers/net/wireless/ath/ar5523/ar5523.c b/drivers/net/wireless/ath/ar5523/ar5523.c index 9cabd342d156a..00ddeee123c22 100644 --- a/drivers/net/wireless/ath/ar5523/ar5523.c +++ b/drivers/net/wireless/ath/ar5523/ar5523.c @@ -1160,7 +1160,7 @@ static int ar5523_get_wlan_mode(struct ar5523 *ar, ar5523_info(ar, "STA not found!\n"); return WLAN_MODE_11b; } - sta_rate_set = sta->supp_rates[ar->hw->conf.chandef.chan->band]; + sta_rate_set = sta->deflink.supp_rates[ar->hw->conf.chandef.chan->band]; for (bit = 0; bit < band->n_bitrates; bit++) { if (sta_rate_set & 1) { @@ -1198,7 +1198,7 @@ static void ar5523_create_rateset(struct ar5523 *ar, ar5523_info(ar, "STA not found. Cannot set rates\n"); sta_rate_set = bss_conf->basic_rates; } else - sta_rate_set = sta->supp_rates[ar->hw->conf.chandef.chan->band]; + sta_rate_set = sta->deflink.supp_rates[ar->hw->conf.chandef.chan->band]; ar5523_dbg(ar, "sta rate_set = %08x\n", sta_rate_set); diff --git a/drivers/net/wireless/ath/ath10k/mac.c b/drivers/net/wireless/ath/ath10k/mac.c index b11aaee8b8c03..d804e19a742a7 100644 --- a/drivers/net/wireless/ath/ath10k/mac.c +++ b/drivers/net/wireless/ath/ath10k/mac.c @@ -2251,7 +2251,7 @@ static void ath10k_peer_assoc_h_rates(struct ath10k *ar, band = def.chan->band; sband = ar->hw->wiphy->bands[band]; - ratemask = sta->supp_rates[band]; + ratemask = sta->deflink.supp_rates[band]; ratemask &= arvif->bitrate_mask.control[band].legacy; rates = sband->bitrates; @@ -2296,7 +2296,7 @@ static void ath10k_peer_assoc_h_ht(struct ath10k *ar, struct ieee80211_sta *sta, struct wmi_peer_assoc_complete_arg *arg) { - const struct ieee80211_sta_ht_cap *ht_cap = &sta->ht_cap; + const struct ieee80211_sta_ht_cap *ht_cap = &sta->deflink.ht_cap; struct ath10k_vif *arvif = (void *)vif->drv_priv; struct cfg80211_chan_def def; enum nl80211_band band; @@ -2335,7 +2335,7 @@ static void ath10k_peer_assoc_h_ht(struct ath10k *ar, if (ht_cap->cap & IEEE80211_HT_CAP_LDPC_CODING) arg->peer_flags |= ar->wmi.peer_flags->ldbc; - if (sta->bandwidth >= IEEE80211_STA_RX_BW_40) { + if (sta->deflink.bandwidth >= IEEE80211_STA_RX_BW_40) { arg->peer_flags |= ar->wmi.peer_flags->bw40; arg->peer_rate_caps |= WMI_RC_CW40_FLAG; } @@ -2388,7 +2388,8 @@ static void ath10k_peer_assoc_h_ht(struct ath10k *ar, arg->peer_ht_rates.rates[i] = i; } else { arg->peer_ht_rates.num_rates = n; - arg->peer_num_spatial_streams = min(sta->rx_nss, max_nss); + arg->peer_num_spatial_streams = min(sta->deflink.rx_nss, + max_nss); } ath10k_dbg(ar, ATH10K_DBG_MAC, "mac ht peer %pM mcs cnt %d nss %d\n", @@ -2545,7 +2546,7 @@ static void ath10k_peer_assoc_h_vht(struct ath10k *ar, struct ieee80211_sta *sta, struct wmi_peer_assoc_complete_arg *arg) { - const struct ieee80211_sta_vht_cap *vht_cap = &sta->vht_cap; + const struct ieee80211_sta_vht_cap *vht_cap = &sta->deflink.vht_cap; struct ath10k_vif *arvif = (void *)vif->drv_priv; struct ath10k_hw_params *hw = &ar->hw_params; struct cfg80211_chan_def def; @@ -2587,10 +2588,10 @@ static void ath10k_peer_assoc_h_vht(struct ath10k *ar, (1U << (IEEE80211_HT_MAX_AMPDU_FACTOR + ampdu_factor)) - 1); - if (sta->bandwidth == IEEE80211_STA_RX_BW_80) + if (sta->deflink.bandwidth == IEEE80211_STA_RX_BW_80) arg->peer_flags |= ar->wmi.peer_flags->bw80; - if (sta->bandwidth == IEEE80211_STA_RX_BW_160) + if (sta->deflink.bandwidth == IEEE80211_STA_RX_BW_160) arg->peer_flags |= ar->wmi.peer_flags->bw160; /* Calculate peer NSS capability from VHT capabilities if STA @@ -2604,7 +2605,7 @@ static void ath10k_peer_assoc_h_vht(struct ath10k *ar, vht_mcs_mask[i]) max_nss = i + 1; } - arg->peer_num_spatial_streams = min(sta->rx_nss, max_nss); + arg->peer_num_spatial_streams = min(sta->deflink.rx_nss, max_nss); arg->peer_vht_rates.rx_max_rate = __le16_to_cpu(vht_cap->vht_mcs.rx_highest); arg->peer_vht_rates.rx_mcs_set = @@ -2684,15 +2685,15 @@ static void ath10k_peer_assoc_h_qos(struct ath10k *ar, static bool ath10k_mac_sta_has_ofdm_only(struct ieee80211_sta *sta) { - return sta->supp_rates[NL80211_BAND_2GHZ] >> + return sta->deflink.supp_rates[NL80211_BAND_2GHZ] >> ATH10K_MAC_FIRST_OFDM_RATE_IDX; } static enum wmi_phy_mode ath10k_mac_get_phymode_vht(struct ath10k *ar, struct ieee80211_sta *sta) { - if (sta->bandwidth == IEEE80211_STA_RX_BW_160) { - switch (sta->vht_cap.cap & IEEE80211_VHT_CAP_SUPP_CHAN_WIDTH_MASK) { + if (sta->deflink.bandwidth == IEEE80211_STA_RX_BW_160) { + switch (sta->deflink.vht_cap.cap & IEEE80211_VHT_CAP_SUPP_CHAN_WIDTH_MASK) { case IEEE80211_VHT_CAP_SUPP_CHAN_WIDTH_160MHZ: return MODE_11AC_VHT160; case IEEE80211_VHT_CAP_SUPP_CHAN_WIDTH_160_80PLUS80MHZ: @@ -2703,13 +2704,13 @@ static enum wmi_phy_mode ath10k_mac_get_phymode_vht(struct ath10k *ar, } } - if (sta->bandwidth == IEEE80211_STA_RX_BW_80) + if (sta->deflink.bandwidth == IEEE80211_STA_RX_BW_80) return MODE_11AC_VHT80; - if (sta->bandwidth == IEEE80211_STA_RX_BW_40) + if (sta->deflink.bandwidth == IEEE80211_STA_RX_BW_40) return MODE_11AC_VHT40; - if (sta->bandwidth == IEEE80211_STA_RX_BW_20) + if (sta->deflink.bandwidth == IEEE80211_STA_RX_BW_20) return MODE_11AC_VHT20; return MODE_UNKNOWN; @@ -2736,15 +2737,15 @@ static void ath10k_peer_assoc_h_phymode(struct ath10k *ar, switch (band) { case NL80211_BAND_2GHZ: - if (sta->vht_cap.vht_supported && + if (sta->deflink.vht_cap.vht_supported && !ath10k_peer_assoc_h_vht_masked(vht_mcs_mask)) { - if (sta->bandwidth == IEEE80211_STA_RX_BW_40) + if (sta->deflink.bandwidth == IEEE80211_STA_RX_BW_40) phymode = MODE_11AC_VHT40; else phymode = MODE_11AC_VHT20; - } else if (sta->ht_cap.ht_supported && + } else if (sta->deflink.ht_cap.ht_supported && !ath10k_peer_assoc_h_ht_masked(ht_mcs_mask)) { - if (sta->bandwidth == IEEE80211_STA_RX_BW_40) + if (sta->deflink.bandwidth == IEEE80211_STA_RX_BW_40) phymode = MODE_11NG_HT40; else phymode = MODE_11NG_HT20; @@ -2759,12 +2760,12 @@ static void ath10k_peer_assoc_h_phymode(struct ath10k *ar, /* * Check VHT first. */ - if (sta->vht_cap.vht_supported && + if (sta->deflink.vht_cap.vht_supported && !ath10k_peer_assoc_h_vht_masked(vht_mcs_mask)) { phymode = ath10k_mac_get_phymode_vht(ar, sta); - } else if (sta->ht_cap.ht_supported && + } else if (sta->deflink.ht_cap.ht_supported && !ath10k_peer_assoc_h_ht_masked(ht_mcs_mask)) { - if (sta->bandwidth >= IEEE80211_STA_RX_BW_40) + if (sta->deflink.bandwidth >= IEEE80211_STA_RX_BW_40) phymode = MODE_11NA_HT40; else phymode = MODE_11NA_HT20; @@ -3079,8 +3080,8 @@ static void ath10k_bss_assoc(struct ieee80211_hw *hw, /* ap_sta must be accessed only within rcu section which must be left * before calling ath10k_setup_peer_smps() which might sleep. */ - ht_cap = ap_sta->ht_cap; - vht_cap = ap_sta->vht_cap; + ht_cap = ap_sta->deflink.ht_cap; + vht_cap = ap_sta->deflink.vht_cap; ret = ath10k_peer_assoc_prepare(ar, vif, ap_sta, &peer_arg); if (ret) { @@ -3278,7 +3279,7 @@ static int ath10k_station_assoc(struct ath10k *ar, */ if (!reassoc) { ret = ath10k_setup_peer_smps(ar, arvif, sta->addr, - &sta->ht_cap); + &sta->deflink.ht_cap); if (ret) { ath10k_warn(ar, "failed to setup peer SMPS for vdev %d: %d\n", arvif->vdev_id, ret); @@ -6787,10 +6788,10 @@ static int ath10k_sta_set_txpwr(struct ieee80211_hw *hw, int ret = 0; s16 txpwr; - if (sta->txpwr.type == NL80211_TX_POWER_AUTOMATIC) { + if (sta->deflink.txpwr.type == NL80211_TX_POWER_AUTOMATIC) { txpwr = 0; } else { - txpwr = sta->txpwr.power; + txpwr = sta->deflink.txpwr.power; if (!txpwr) return -EINVAL; } @@ -6910,26 +6911,26 @@ static int ath10k_mac_validate_rate_mask(struct ath10k *ar, struct ieee80211_sta *sta, u32 rate_ctrl_flag, u8 nss) { - if (nss > sta->rx_nss) { + if (nss > sta->deflink.rx_nss) { ath10k_warn(ar, "Invalid nss field, configured %u limit %u\n", - nss, sta->rx_nss); + nss, sta->deflink.rx_nss); return -EINVAL; } if (ATH10K_HW_PREAMBLE(rate_ctrl_flag) == WMI_RATE_PREAMBLE_VHT) { - if (!sta->vht_cap.vht_supported) { + if (!sta->deflink.vht_cap.vht_supported) { ath10k_warn(ar, "Invalid VHT rate for sta %pM\n", sta->addr); return -EINVAL; } } else if (ATH10K_HW_PREAMBLE(rate_ctrl_flag) == WMI_RATE_PREAMBLE_HT) { - if (!sta->ht_cap.ht_supported || sta->vht_cap.vht_supported) { + if (!sta->deflink.ht_cap.ht_supported || sta->deflink.vht_cap.vht_supported) { ath10k_warn(ar, "Invalid HT rate for sta %pM\n", sta->addr); return -EINVAL; } } else { - if (sta->ht_cap.ht_supported || sta->vht_cap.vht_supported) + if (sta->deflink.ht_cap.ht_supported || sta->deflink.vht_cap.vht_supported) return -EINVAL; } @@ -8272,7 +8273,7 @@ static bool ath10k_mac_set_vht_bitrate_mask_fixup(struct ath10k *ar, u8 rate = arvif->vht_pfr; /* skip non vht and multiple rate peers */ - if (!sta->vht_cap.vht_supported || arvif->vht_num_rates != 1) + if (!sta->deflink.vht_cap.vht_supported || arvif->vht_num_rates != 1) return false; err = ath10k_wmi_peer_set_param(ar, arvif->vdev_id, sta->addr, @@ -8313,7 +8314,7 @@ static void ath10k_mac_clr_bitrate_mask_iter(void *data, int err; /* clear vht peers only */ - if (arsta->arvif != arvif || !sta->vht_cap.vht_supported) + if (arsta->arvif != arvif || !sta->deflink.vht_cap.vht_supported) return; err = ath10k_wmi_peer_set_param(ar, arvif->vdev_id, sta->addr, @@ -8457,13 +8458,14 @@ static void ath10k_sta_rc_update(struct ieee80211_hw *hw, ath10k_dbg(ar, ATH10K_DBG_STA, "mac sta rc update for %pM changed %08x bw %d nss %d smps %d\n", - sta->addr, changed, sta->bandwidth, sta->rx_nss, + sta->addr, changed, sta->deflink.bandwidth, + sta->deflink.rx_nss, sta->smps_mode); if (changed & IEEE80211_RC_BW_CHANGED) { bw = WMI_PEER_CHWIDTH_20MHZ; - switch (sta->bandwidth) { + switch (sta->deflink.bandwidth) { case IEEE80211_STA_RX_BW_20: bw = WMI_PEER_CHWIDTH_20MHZ; break; @@ -8478,7 +8480,7 @@ static void ath10k_sta_rc_update(struct ieee80211_hw *hw, break; default: ath10k_warn(ar, "Invalid bandwidth %d in rc update for %pM\n", - sta->bandwidth, sta->addr); + sta->deflink.bandwidth, sta->addr); bw = WMI_PEER_CHWIDTH_20MHZ; break; } @@ -8487,7 +8489,7 @@ static void ath10k_sta_rc_update(struct ieee80211_hw *hw, } if (changed & IEEE80211_RC_NSS_CHANGED) - arsta->nss = sta->rx_nss; + arsta->nss = sta->deflink.rx_nss; if (changed & IEEE80211_RC_SMPS_CHANGED) { smps = WMI_PEER_SMPS_PS_NONE; diff --git a/drivers/net/wireless/ath/ath11k/mac.c b/drivers/net/wireless/ath/ath11k/mac.c index 49421d91d39c7..a7ee570c1e9c7 100644 --- a/drivers/net/wireless/ath/ath11k/mac.c +++ b/drivers/net/wireless/ath/ath11k/mac.c @@ -1636,7 +1636,7 @@ static void ath11k_peer_assoc_h_rates(struct ath11k *ar, band = def.chan->band; sband = ar->hw->wiphy->bands[band]; - ratemask = sta->supp_rates[band]; + ratemask = sta->deflink.supp_rates[band]; ratemask &= arvif->bitrate_mask.control[band].legacy; rates = sband->bitrates; @@ -1681,7 +1681,7 @@ static void ath11k_peer_assoc_h_ht(struct ath11k *ar, struct ieee80211_sta *sta, struct peer_assoc_params *arg) { - const struct ieee80211_sta_ht_cap *ht_cap = &sta->ht_cap; + const struct ieee80211_sta_ht_cap *ht_cap = &sta->deflink.ht_cap; struct ath11k_vif *arvif = (void *)vif->drv_priv; struct cfg80211_chan_def def; enum nl80211_band band; @@ -1718,7 +1718,7 @@ static void ath11k_peer_assoc_h_ht(struct ath11k *ar, if (ht_cap->cap & IEEE80211_HT_CAP_LDPC_CODING) arg->ldpc_flag = true; - if (sta->bandwidth >= IEEE80211_STA_RX_BW_40) { + if (sta->deflink.bandwidth >= IEEE80211_STA_RX_BW_40) { arg->bw_40 = true; arg->peer_rate_caps |= WMI_HOST_RC_CW40_FLAG; } @@ -1776,7 +1776,7 @@ static void ath11k_peer_assoc_h_ht(struct ath11k *ar, arg->peer_ht_rates.rates[i] = i; } else { arg->peer_ht_rates.num_rates = n; - arg->peer_nss = min(sta->rx_nss, max_nss); + arg->peer_nss = min(sta->deflink.rx_nss, max_nss); } ath11k_dbg(ar->ab, ATH11K_DBG_MAC, "mac ht peer %pM mcs cnt %d nss %d\n", @@ -1878,7 +1878,7 @@ static void ath11k_peer_assoc_h_vht(struct ath11k *ar, struct ieee80211_sta *sta, struct peer_assoc_params *arg) { - const struct ieee80211_sta_vht_cap *vht_cap = &sta->vht_cap; + const struct ieee80211_sta_vht_cap *vht_cap = &sta->deflink.vht_cap; struct ath11k_vif *arvif = (void *)vif->drv_priv; struct cfg80211_chan_def def; enum nl80211_band band; @@ -1924,17 +1924,17 @@ static void ath11k_peer_assoc_h_vht(struct ath11k *ar, (1U << (IEEE80211_HT_MAX_AMPDU_FACTOR + ampdu_factor)) - 1); - if (sta->bandwidth == IEEE80211_STA_RX_BW_80) + if (sta->deflink.bandwidth == IEEE80211_STA_RX_BW_80) arg->bw_80 = true; - if (sta->bandwidth == IEEE80211_STA_RX_BW_160) + if (sta->deflink.bandwidth == IEEE80211_STA_RX_BW_160) arg->bw_160 = true; vht_nss = ath11k_mac_max_vht_nss(vht_mcs_mask); - if (vht_nss > sta->rx_nss) { + if (vht_nss > sta->deflink.rx_nss) { user_rate_valid = false; - for (nss_idx = sta->rx_nss - 1; nss_idx >= 0; nss_idx--) { + for (nss_idx = sta->deflink.rx_nss - 1; nss_idx >= 0; nss_idx--) { if (vht_mcs_mask[nss_idx]) { user_rate_valid = true; break; @@ -1944,8 +1944,8 @@ static void ath11k_peer_assoc_h_vht(struct ath11k *ar, if (!user_rate_valid) { ath11k_dbg(ar->ab, ATH11K_DBG_MAC, "mac setting vht range mcs value to peer supported nss %d for peer %pM\n", - sta->rx_nss, sta->addr); - vht_mcs_mask[sta->rx_nss - 1] = vht_mcs_mask[vht_nss - 1]; + sta->deflink.rx_nss, sta->addr); + vht_mcs_mask[sta->deflink.rx_nss - 1] = vht_mcs_mask[vht_nss - 1]; } /* Calculate peer NSS capability from VHT capabilities if STA @@ -1959,7 +1959,7 @@ static void ath11k_peer_assoc_h_vht(struct ath11k *ar, vht_mcs_mask[i]) max_nss = i + 1; } - arg->peer_nss = min(sta->rx_nss, max_nss); + arg->peer_nss = min(sta->deflink.rx_nss, max_nss); arg->rx_max_rate = __le16_to_cpu(vht_cap->vht_mcs.rx_highest); arg->rx_mcs_set = __le16_to_cpu(vht_cap->vht_mcs.rx_mcs_map); arg->tx_max_rate = __le16_to_cpu(vht_cap->vht_mcs.tx_highest); @@ -2078,7 +2078,7 @@ static void ath11k_peer_assoc_h_he(struct ath11k *ar, { struct ath11k_vif *arvif = (void *)vif->drv_priv; struct cfg80211_chan_def def; - const struct ieee80211_sta_he_cap *he_cap = &sta->he_cap; + const struct ieee80211_sta_he_cap *he_cap = &sta->deflink.he_cap; enum nl80211_band band; u16 *he_mcs_mask; u8 max_nss, he_mcs; @@ -2135,7 +2135,7 @@ static void ath11k_peer_assoc_h_he(struct ath11k *ar, else max_nss = rx_mcs_80; - arg->peer_nss = min(sta->rx_nss, max_nss); + arg->peer_nss = min(sta->deflink.rx_nss, max_nss); memcpy_and_pad(&arg->peer_he_cap_macinfo, sizeof(arg->peer_he_cap_macinfo), @@ -2167,10 +2167,10 @@ static void ath11k_peer_assoc_h_he(struct ath11k *ar, IEEE80211_HE_MAC_CAP3_MAX_AMPDU_LEN_EXP_MASK); if (ampdu_factor) { - if (sta->vht_cap.vht_supported) + if (sta->deflink.vht_cap.vht_supported) arg->peer_max_mpdu = (1 << (IEEE80211_HE_VHT_MAX_AMPDU_FACTOR + ampdu_factor)) - 1; - else if (sta->ht_cap.ht_supported) + else if (sta->deflink.ht_cap.ht_supported) arg->peer_max_mpdu = (1 << (IEEE80211_HE_HT_MAX_AMPDU_FACTOR + ampdu_factor)) - 1; } @@ -2213,9 +2213,9 @@ static void ath11k_peer_assoc_h_he(struct ath11k *ar, he_nss = ath11k_mac_max_he_nss(he_mcs_mask); - if (he_nss > sta->rx_nss) { + if (he_nss > sta->deflink.rx_nss) { user_rate_valid = false; - for (nss_idx = sta->rx_nss - 1; nss_idx >= 0; nss_idx--) { + for (nss_idx = sta->deflink.rx_nss - 1; nss_idx >= 0; nss_idx--) { if (he_mcs_mask[nss_idx]) { user_rate_valid = true; break; @@ -2225,11 +2225,11 @@ static void ath11k_peer_assoc_h_he(struct ath11k *ar, if (!user_rate_valid) { ath11k_dbg(ar->ab, ATH11K_DBG_MAC, "mac setting he range mcs value to peer supported nss %d for peer %pM\n", - sta->rx_nss, sta->addr); - he_mcs_mask[sta->rx_nss - 1] = he_mcs_mask[he_nss - 1]; + sta->deflink.rx_nss, sta->addr); + he_mcs_mask[sta->deflink.rx_nss - 1] = he_mcs_mask[he_nss - 1]; } - switch (sta->bandwidth) { + switch (sta->deflink.bandwidth) { case IEEE80211_STA_RX_BW_160: if (he_cap->he_cap_elem.phy_cap_info[0] & IEEE80211_HE_PHY_CAP0_CHANNEL_WIDTH_SET_80PLUS80_MHZ_IN_5G) { @@ -2283,7 +2283,7 @@ static void ath11k_peer_assoc_h_he(struct ath11k *ar, he_mcs_mask[i]) max_nss = i + 1; } - arg->peer_nss = min(sta->rx_nss, max_nss); + arg->peer_nss = min(sta->deflink.rx_nss, max_nss); if (arg->peer_phymode == MODE_11AX_HE160 || arg->peer_phymode == MODE_11AX_HE80_80) { @@ -2316,7 +2316,7 @@ static void ath11k_peer_assoc_h_he_6ghz(struct ath11k *ar, struct ieee80211_sta *sta, struct peer_assoc_params *arg) { - const struct ieee80211_sta_he_cap *he_cap = &sta->he_cap; + const struct ieee80211_sta_he_cap *he_cap = &sta->deflink.he_cap; struct cfg80211_chan_def def; enum nl80211_band band; u8 ampdu_factor; @@ -2326,19 +2326,19 @@ static void ath11k_peer_assoc_h_he_6ghz(struct ath11k *ar, band = def.chan->band; - if (!arg->he_flag || band != NL80211_BAND_6GHZ || !sta->he_6ghz_capa.capa) + if (!arg->he_flag || band != NL80211_BAND_6GHZ || !sta->deflink.he_6ghz_capa.capa) return; - if (sta->bandwidth == IEEE80211_STA_RX_BW_40) + if (sta->deflink.bandwidth == IEEE80211_STA_RX_BW_40) arg->bw_40 = true; - if (sta->bandwidth == IEEE80211_STA_RX_BW_80) + if (sta->deflink.bandwidth == IEEE80211_STA_RX_BW_80) arg->bw_80 = true; - if (sta->bandwidth == IEEE80211_STA_RX_BW_160) + if (sta->deflink.bandwidth == IEEE80211_STA_RX_BW_160) arg->bw_160 = true; - arg->peer_he_caps_6ghz = le16_to_cpu(sta->he_6ghz_capa.capa); + arg->peer_he_caps_6ghz = le16_to_cpu(sta->deflink.he_6ghz_capa.capa); arg->peer_mpdu_density = ath11k_parse_mpdudensity(FIELD_GET(IEEE80211_HE_6GHZ_CAP_MIN_MPDU_START, arg->peer_he_caps_6ghz)); @@ -2364,17 +2364,17 @@ static void ath11k_peer_assoc_h_he_6ghz(struct ath11k *ar, static void ath11k_peer_assoc_h_smps(struct ieee80211_sta *sta, struct peer_assoc_params *arg) { - const struct ieee80211_sta_ht_cap *ht_cap = &sta->ht_cap; + const struct ieee80211_sta_ht_cap *ht_cap = &sta->deflink.ht_cap; int smps; - if (!ht_cap->ht_supported && !sta->he_6ghz_capa.capa) + if (!ht_cap->ht_supported && !sta->deflink.he_6ghz_capa.capa) return; if (ht_cap->ht_supported) { smps = ht_cap->cap & IEEE80211_HT_CAP_SM_PS; smps >>= IEEE80211_HT_CAP_SM_PS_SHIFT; } else { - smps = le16_get_bits(sta->he_6ghz_capa.capa, + smps = le16_get_bits(sta->deflink.he_6ghz_capa.capa, IEEE80211_HE_6GHZ_CAP_SM_PS); } @@ -2498,15 +2498,15 @@ static int ath11k_peer_assoc_qos_ap(struct ath11k *ar, static bool ath11k_mac_sta_has_ofdm_only(struct ieee80211_sta *sta) { - return sta->supp_rates[NL80211_BAND_2GHZ] >> + return sta->deflink.supp_rates[NL80211_BAND_2GHZ] >> ATH11K_MAC_FIRST_OFDM_RATE_IDX; } static enum wmi_phy_mode ath11k_mac_get_phymode_vht(struct ath11k *ar, struct ieee80211_sta *sta) { - if (sta->bandwidth == IEEE80211_STA_RX_BW_160) { - switch (sta->vht_cap.cap & + if (sta->deflink.bandwidth == IEEE80211_STA_RX_BW_160) { + switch (sta->deflink.vht_cap.cap & IEEE80211_VHT_CAP_SUPP_CHAN_WIDTH_MASK) { case IEEE80211_VHT_CAP_SUPP_CHAN_WIDTH_160MHZ: return MODE_11AC_VHT160; @@ -2518,13 +2518,13 @@ static enum wmi_phy_mode ath11k_mac_get_phymode_vht(struct ath11k *ar, } } - if (sta->bandwidth == IEEE80211_STA_RX_BW_80) + if (sta->deflink.bandwidth == IEEE80211_STA_RX_BW_80) return MODE_11AC_VHT80; - if (sta->bandwidth == IEEE80211_STA_RX_BW_40) + if (sta->deflink.bandwidth == IEEE80211_STA_RX_BW_40) return MODE_11AC_VHT40; - if (sta->bandwidth == IEEE80211_STA_RX_BW_20) + if (sta->deflink.bandwidth == IEEE80211_STA_RX_BW_20) return MODE_11AC_VHT20; return MODE_UNKNOWN; @@ -2533,24 +2533,24 @@ static enum wmi_phy_mode ath11k_mac_get_phymode_vht(struct ath11k *ar, static enum wmi_phy_mode ath11k_mac_get_phymode_he(struct ath11k *ar, struct ieee80211_sta *sta) { - if (sta->bandwidth == IEEE80211_STA_RX_BW_160) { - if (sta->he_cap.he_cap_elem.phy_cap_info[0] & + if (sta->deflink.bandwidth == IEEE80211_STA_RX_BW_160) { + if (sta->deflink.he_cap.he_cap_elem.phy_cap_info[0] & IEEE80211_HE_PHY_CAP0_CHANNEL_WIDTH_SET_160MHZ_IN_5G) return MODE_11AX_HE160; - else if (sta->he_cap.he_cap_elem.phy_cap_info[0] & - IEEE80211_HE_PHY_CAP0_CHANNEL_WIDTH_SET_80PLUS80_MHZ_IN_5G) + else if (sta->deflink.he_cap.he_cap_elem.phy_cap_info[0] & + IEEE80211_HE_PHY_CAP0_CHANNEL_WIDTH_SET_80PLUS80_MHZ_IN_5G) return MODE_11AX_HE80_80; /* not sure if this is a valid case? */ return MODE_11AX_HE160; } - if (sta->bandwidth == IEEE80211_STA_RX_BW_80) + if (sta->deflink.bandwidth == IEEE80211_STA_RX_BW_80) return MODE_11AX_HE80; - if (sta->bandwidth == IEEE80211_STA_RX_BW_40) + if (sta->deflink.bandwidth == IEEE80211_STA_RX_BW_40) return MODE_11AX_HE40; - if (sta->bandwidth == IEEE80211_STA_RX_BW_20) + if (sta->deflink.bandwidth == IEEE80211_STA_RX_BW_20) return MODE_11AX_HE20; return MODE_UNKNOWN; @@ -2579,23 +2579,23 @@ static void ath11k_peer_assoc_h_phymode(struct ath11k *ar, switch (band) { case NL80211_BAND_2GHZ: - if (sta->he_cap.has_he && + if (sta->deflink.he_cap.has_he && !ath11k_peer_assoc_h_he_masked(he_mcs_mask)) { - if (sta->bandwidth == IEEE80211_STA_RX_BW_80) + if (sta->deflink.bandwidth == IEEE80211_STA_RX_BW_80) phymode = MODE_11AX_HE80_2G; - else if (sta->bandwidth == IEEE80211_STA_RX_BW_40) + else if (sta->deflink.bandwidth == IEEE80211_STA_RX_BW_40) phymode = MODE_11AX_HE40_2G; else phymode = MODE_11AX_HE20_2G; - } else if (sta->vht_cap.vht_supported && - !ath11k_peer_assoc_h_vht_masked(vht_mcs_mask)) { - if (sta->bandwidth == IEEE80211_STA_RX_BW_40) + } else if (sta->deflink.vht_cap.vht_supported && + !ath11k_peer_assoc_h_vht_masked(vht_mcs_mask)) { + if (sta->deflink.bandwidth == IEEE80211_STA_RX_BW_40) phymode = MODE_11AC_VHT40; else phymode = MODE_11AC_VHT20; - } else if (sta->ht_cap.ht_supported && + } else if (sta->deflink.ht_cap.ht_supported && !ath11k_peer_assoc_h_ht_masked(ht_mcs_mask)) { - if (sta->bandwidth == IEEE80211_STA_RX_BW_40) + if (sta->deflink.bandwidth == IEEE80211_STA_RX_BW_40) phymode = MODE_11NG_HT40; else phymode = MODE_11NG_HT20; @@ -2608,15 +2608,15 @@ static void ath11k_peer_assoc_h_phymode(struct ath11k *ar, case NL80211_BAND_5GHZ: case NL80211_BAND_6GHZ: /* Check HE first */ - if (sta->he_cap.has_he && + if (sta->deflink.he_cap.has_he && !ath11k_peer_assoc_h_he_masked(he_mcs_mask)) { phymode = ath11k_mac_get_phymode_he(ar, sta); - } else if (sta->vht_cap.vht_supported && - !ath11k_peer_assoc_h_vht_masked(vht_mcs_mask)) { + } else if (sta->deflink.vht_cap.vht_supported && + !ath11k_peer_assoc_h_vht_masked(vht_mcs_mask)) { phymode = ath11k_mac_get_phymode_vht(ar, sta); - } else if (sta->ht_cap.ht_supported && + } else if (sta->deflink.ht_cap.ht_supported && !ath11k_peer_assoc_h_ht_masked(ht_mcs_mask)) { - if (sta->bandwidth >= IEEE80211_STA_RX_BW_40) + if (sta->deflink.bandwidth >= IEEE80211_STA_RX_BW_40) phymode = MODE_11NA_HT40; else phymode = MODE_11NA_HT20; @@ -2739,8 +2739,8 @@ static void ath11k_bss_assoc(struct ieee80211_hw *hw, } ret = ath11k_setup_peer_smps(ar, arvif, bss_conf->bssid, - &ap_sta->ht_cap, - le16_to_cpu(ap_sta->he_6ghz_capa.capa)); + &ap_sta->deflink.ht_cap, + le16_to_cpu(ap_sta->deflink.he_6ghz_capa.capa)); if (ret) { ath11k_warn(ar->ab, "failed to setup peer SMPS for vdev %d: %d\n", arvif->vdev_id, ret); @@ -4001,7 +4001,7 @@ ath11k_mac_set_peer_vht_fixed_rate(struct ath11k_vif *arvif, } /* Avoid updating invalid nss as fixed rate*/ - if (nss > sta->rx_nss) + if (nss > sta->deflink.rx_nss) return -EINVAL; ath11k_dbg(ar->ab, ATH11K_DBG_MAC, @@ -4051,7 +4051,7 @@ ath11k_mac_set_peer_he_fixed_rate(struct ath11k_vif *arvif, } /* Avoid updating invalid nss as fixed rate */ - if (nss > sta->rx_nss) + if (nss > sta->deflink.rx_nss) return -EINVAL; ath11k_dbg(ar->ab, ATH11K_DBG_MAC, @@ -4118,12 +4118,12 @@ static int ath11k_station_assoc(struct ath11k *ar, * fixed param. * Note that all other rates and NSS will be disabled for this peer. */ - if (sta->vht_cap.vht_supported && num_vht_rates == 1) { + if (sta->deflink.vht_cap.vht_supported && num_vht_rates == 1) { ret = ath11k_mac_set_peer_vht_fixed_rate(arvif, sta, mask, band); if (ret) return ret; - } else if (sta->he_cap.has_he && num_he_rates == 1) { + } else if (sta->deflink.he_cap.has_he && num_he_rates == 1) { ret = ath11k_mac_set_peer_he_fixed_rate(arvif, sta, mask, band); if (ret) @@ -4137,7 +4137,8 @@ static int ath11k_station_assoc(struct ath11k *ar, return 0; ret = ath11k_setup_peer_smps(ar, arvif, sta->addr, - &sta->ht_cap, le16_to_cpu(sta->he_6ghz_capa.capa)); + &sta->deflink.ht_cap, + le16_to_cpu(sta->deflink.he_6ghz_capa.capa)); if (ret) { ath11k_warn(ar->ab, "failed to setup peer SMPS for vdev %d: %d\n", arvif->vdev_id, ret); @@ -4299,10 +4300,10 @@ static void ath11k_sta_rc_update_wk(struct work_struct *wk) * TODO: Check RATEMASK_CMDID to support auto rates selection * across HT/VHT and for multiple VHT MCS support. */ - if (sta->vht_cap.vht_supported && num_vht_rates == 1) { + if (sta->deflink.vht_cap.vht_supported && num_vht_rates == 1) { ath11k_mac_set_peer_vht_fixed_rate(arvif, sta, mask, band); - } else if (sta->he_cap.has_he && num_he_rates == 1) { + } else if (sta->deflink.he_cap.has_he && num_he_rates == 1) { ath11k_mac_set_peer_he_fixed_rate(arvif, sta, mask, band); } else { @@ -4624,10 +4625,10 @@ static int ath11k_mac_op_sta_set_txpwr(struct ieee80211_hw *hw, int ret = 0; s16 txpwr; - if (sta->txpwr.type == NL80211_TX_POWER_AUTOMATIC) { + if (sta->deflink.txpwr.type == NL80211_TX_POWER_AUTOMATIC) { txpwr = 0; } else { - txpwr = sta->txpwr.power; + txpwr = sta->deflink.txpwr.power; if (!txpwr) return -EINVAL; } @@ -4688,7 +4689,8 @@ static void ath11k_mac_op_sta_rc_update(struct ieee80211_hw *hw, ath11k_dbg(ar->ab, ATH11K_DBG_MAC, "mac sta rc update for %pM changed %08x bw %d nss %d smps %d\n", - sta->addr, changed, sta->bandwidth, sta->rx_nss, + sta->addr, changed, sta->deflink.bandwidth, + sta->deflink.rx_nss, sta->smps_mode); spin_lock_bh(&ar->data_lock); @@ -4696,7 +4698,7 @@ static void ath11k_mac_op_sta_rc_update(struct ieee80211_hw *hw, if (changed & IEEE80211_RC_BW_CHANGED) { bw = WMI_PEER_CHWIDTH_20MHZ; - switch (sta->bandwidth) { + switch (sta->deflink.bandwidth) { case IEEE80211_STA_RX_BW_20: bw = WMI_PEER_CHWIDTH_20MHZ; break; @@ -4711,7 +4713,7 @@ static void ath11k_mac_op_sta_rc_update(struct ieee80211_hw *hw, break; default: ath11k_warn(ar->ab, "Invalid bandwidth %d in rc update for %pM\n", - sta->bandwidth, sta->addr); + sta->deflink.bandwidth, sta->addr); bw = WMI_PEER_CHWIDTH_20MHZ; break; } @@ -4720,7 +4722,7 @@ static void ath11k_mac_op_sta_rc_update(struct ieee80211_hw *hw, } if (changed & IEEE80211_RC_NSS_CHANGED) - arsta->nss = sta->rx_nss; + arsta->nss = sta->deflink.rx_nss; if (changed & IEEE80211_RC_SMPS_CHANGED) { smps = WMI_PEER_SMPS_PS_NONE; @@ -7755,13 +7757,13 @@ ath11k_mac_validate_vht_he_fixed_rate_settings(struct ath11k *ar, enum nl80211_b spin_lock_bh(&ar->ab->base_lock); list_for_each_entry_safe(peer, tmp, &ar->ab->peers, list) { if (peer->sta) { - if (vht_fixed_rate && (!peer->sta->vht_cap.vht_supported || - peer->sta->rx_nss < vht_nss)) { + if (vht_fixed_rate && (!peer->sta->deflink.vht_cap.vht_supported || + peer->sta->deflink.rx_nss < vht_nss)) { ret = false; goto out; } - if (he_fixed_rate && (!peer->sta->he_cap.has_he || - peer->sta->rx_nss < he_nss)) { + if (he_fixed_rate && (!peer->sta->deflink.he_cap.has_he || + peer->sta->deflink.rx_nss < he_nss)) { ret = false; goto out; } diff --git a/drivers/net/wireless/ath/ath9k/debug_sta.c b/drivers/net/wireless/ath/ath9k/debug_sta.c index d95cabddce33d..1e2a30019fb63 100644 --- a/drivers/net/wireless/ath/ath9k/debug_sta.c +++ b/drivers/net/wireless/ath/ath9k/debug_sta.c @@ -36,7 +36,7 @@ static ssize_t read_file_node_aggr(struct file *file, char __user *user_buf, if (buf == NULL) return -ENOMEM; - if (!an->sta->ht_cap.ht_supported) { + if (!an->sta->deflink.ht_cap.ht_supported) { len = scnprintf(buf, size, "%s\n", "HT not supported"); goto exit; @@ -186,7 +186,7 @@ static ssize_t read_file_node_recv(struct file *file, char __user *user_buf, band = ah->curchan->chan->band; rstats = &an->rx_rate_stats; - if (!sta->ht_cap.ht_supported) + if (!sta->deflink.ht_cap.ht_supported) goto legacy; len += scnprintf(buf + len, size - len, diff --git a/drivers/net/wireless/ath/ath9k/htc_drv_main.c b/drivers/net/wireless/ath/ath9k/htc_drv_main.c index 72ef319feeda7..cfee732a89b12 100644 --- a/drivers/net/wireless/ath/ath9k/htc_drv_main.c +++ b/drivers/net/wireless/ath/ath9k/htc_drv_main.c @@ -491,7 +491,7 @@ static int ath9k_htc_add_station(struct ath9k_htc_priv *priv, ista->index = sta_idx; tsta.is_vif_sta = 0; maxampdu = 1 << (IEEE80211_HT_MAX_AMPDU_FACTOR + - sta->ht_cap.ampdu_factor); + sta->deflink.ht_cap.ampdu_factor); tsta.maxampdu = cpu_to_be16(maxampdu); } else { memcpy(&tsta.macaddr, vif->addr, ETH_ALEN); @@ -602,7 +602,7 @@ static void ath9k_htc_setup_rate(struct ath9k_htc_priv *priv, sband = priv->hw->wiphy->bands[priv->hw->conf.chandef.chan->band]; for (i = 0, j = 0; i < sband->n_bitrates; i++) { - if (sta->supp_rates[sband->band] & BIT(i)) { + if (sta->deflink.supp_rates[sband->band] & BIT(i)) { trate->rates.legacy_rates.rs_rates[j] = (sband->bitrates[i].bitrate * 2) / 10; j++; @@ -610,9 +610,9 @@ static void ath9k_htc_setup_rate(struct ath9k_htc_priv *priv, } trate->rates.legacy_rates.rs_nrates = j; - if (sta->ht_cap.ht_supported) { + if (sta->deflink.ht_cap.ht_supported) { for (i = 0, j = 0; i < 77; i++) { - if (sta->ht_cap.mcs.rx_mask[i/8] & (1<<(i%8))) + if (sta->deflink.ht_cap.mcs.rx_mask[i/8] & (1<<(i%8))) trate->rates.ht_rates.rs_rates[j++] = i; if (j == ATH_HTC_RATE_MAX) break; @@ -620,18 +620,18 @@ static void ath9k_htc_setup_rate(struct ath9k_htc_priv *priv, trate->rates.ht_rates.rs_nrates = j; caps = WLAN_RC_HT_FLAG; - if (sta->ht_cap.cap & IEEE80211_HT_CAP_RX_STBC) + if (sta->deflink.ht_cap.cap & IEEE80211_HT_CAP_RX_STBC) caps |= ATH_RC_TX_STBC_FLAG; - if (sta->ht_cap.mcs.rx_mask[1]) + if (sta->deflink.ht_cap.mcs.rx_mask[1]) caps |= WLAN_RC_DS_FLAG; - if ((sta->ht_cap.cap & IEEE80211_HT_CAP_SUP_WIDTH_20_40) && - (conf_is_ht40(&priv->hw->conf))) + if ((sta->deflink.ht_cap.cap & IEEE80211_HT_CAP_SUP_WIDTH_20_40) && + (conf_is_ht40(&priv->hw->conf))) caps |= WLAN_RC_40_FLAG; if (conf_is_ht40(&priv->hw->conf) && - (sta->ht_cap.cap & IEEE80211_HT_CAP_SGI_40)) + (sta->deflink.ht_cap.cap & IEEE80211_HT_CAP_SGI_40)) caps |= WLAN_RC_SGI_FLAG; else if (conf_is_ht20(&priv->hw->conf) && - (sta->ht_cap.cap & IEEE80211_HT_CAP_SGI_20)) + (sta->deflink.ht_cap.cap & IEEE80211_HT_CAP_SGI_20)) caps |= WLAN_RC_SGI_FLAG; } diff --git a/drivers/net/wireless/ath/ath9k/main.c b/drivers/net/wireless/ath/ath9k/main.c index 98090e40e1cf4..eac34063af5a0 100644 --- a/drivers/net/wireless/ath/ath9k/main.c +++ b/drivers/net/wireless/ath/ath9k/main.c @@ -2048,7 +2048,7 @@ static int ath9k_ampdu_action(struct ieee80211_hw *hw, case IEEE80211_AMPDU_TX_OPERATIONAL: atid = ath_node_to_tid(an, tid); atid->baw_size = IEEE80211_MIN_AMPDU_BUF << - sta->ht_cap.ampdu_factor; + sta->deflink.ht_cap.ampdu_factor; break; default: ath_err(ath9k_hw_common(sc->sc_ah), "Unknown AMPDU action\n"); diff --git a/drivers/net/wireless/ath/ath9k/xmit.c b/drivers/net/wireless/ath/ath9k/xmit.c index d0caf1de2bdec..09516a86ef9c7 100644 --- a/drivers/net/wireless/ath/ath9k/xmit.c +++ b/drivers/net/wireless/ath/ath9k/xmit.c @@ -1574,10 +1574,10 @@ int ath_tx_aggr_start(struct ath_softc *sc, struct ieee80211_sta *sta, * in HT IBSS when a beacon with HT-info is received after the station * has already been added. */ - if (sta->ht_cap.ht_supported) { + if (sta->deflink.ht_cap.ht_supported) { an->maxampdu = (1 << (IEEE80211_HT_MAX_AMPDU_FACTOR + - sta->ht_cap.ampdu_factor)) - 1; - density = ath9k_parse_mpdudensity(sta->ht_cap.ampdu_density); + sta->deflink.ht_cap.ampdu_factor)) - 1; + density = ath9k_parse_mpdudensity(sta->deflink.ht_cap.ampdu_density); an->mpdudensity = density; } diff --git a/drivers/net/wireless/ath/carl9170/main.c b/drivers/net/wireless/ath/carl9170/main.c index 76e84adf57c17..101295162967e 100644 --- a/drivers/net/wireless/ath/carl9170/main.c +++ b/drivers/net/wireless/ath/carl9170/main.c @@ -1306,8 +1306,8 @@ static int carl9170_op_sta_add(struct ieee80211_hw *hw, atomic_set(&sta_info->pending_frames, 0); - if (sta->ht_cap.ht_supported) { - if (sta->ht_cap.ampdu_density > 6) { + if (sta->deflink.ht_cap.ht_supported) { + if (sta->deflink.ht_cap.ampdu_density > 6) { /* * HW does support 16us AMPDU density. * No HT-Xmit for station. @@ -1319,7 +1319,7 @@ static int carl9170_op_sta_add(struct ieee80211_hw *hw, for (i = 0; i < ARRAY_SIZE(sta_info->agg); i++) RCU_INIT_POINTER(sta_info->agg[i], NULL); - sta_info->ampdu_max_len = 1 << (3 + sta->ht_cap.ampdu_factor); + sta_info->ampdu_max_len = 1 << (3 + sta->deflink.ht_cap.ampdu_factor); sta_info->ht_sta = true; } @@ -1335,7 +1335,7 @@ static int carl9170_op_sta_remove(struct ieee80211_hw *hw, unsigned int i; bool cleanup = false; - if (sta->ht_cap.ht_supported) { + if (sta->deflink.ht_cap.ht_supported) { sta_info->ht_sta = false; diff --git a/drivers/net/wireless/ath/carl9170/tx.c b/drivers/net/wireless/ath/carl9170/tx.c index 1b76f4434c069..39b3c1d9c9da9 100644 --- a/drivers/net/wireless/ath/carl9170/tx.c +++ b/drivers/net/wireless/ath/carl9170/tx.c @@ -1044,8 +1044,9 @@ static int carl9170_tx_prepare(struct ar9170 *ar, if (unlikely(!sta || !cvif)) goto err_out; - factor = min_t(unsigned int, 1u, sta->ht_cap.ampdu_factor); - density = sta->ht_cap.ampdu_density; + factor = min_t(unsigned int, 1u, + sta->deflink.ht_cap.ampdu_factor); + density = sta->deflink.ht_cap.ampdu_density; if (density) { /* diff --git a/drivers/net/wireless/ath/wcn36xx/main.c b/drivers/net/wireless/ath/wcn36xx/main.c index 61c47f958e4af..e34d3d0b70820 100644 --- a/drivers/net/wireless/ath/wcn36xx/main.c +++ b/drivers/net/wireless/ath/wcn36xx/main.c @@ -792,7 +792,7 @@ static void wcn36xx_update_allowed_rates(struct ieee80211_sta *sta, int i, size; u16 *rates_table; struct wcn36xx_sta *sta_priv = wcn36xx_sta_to_priv(sta); - u32 rates = sta->supp_rates[band]; + u32 rates = sta->deflink.supp_rates[band]; memset(&sta_priv->supported_rates, 0, sizeof(sta_priv->supported_rates)); @@ -818,20 +818,20 @@ static void wcn36xx_update_allowed_rates(struct ieee80211_sta *sta, } } - if (sta->ht_cap.ht_supported) { - BUILD_BUG_ON(sizeof(sta->ht_cap.mcs.rx_mask) > - sizeof(sta_priv->supported_rates.supported_mcs_set)); + if (sta->deflink.ht_cap.ht_supported) { + BUILD_BUG_ON(sizeof(sta->deflink.ht_cap.mcs.rx_mask) > + sizeof(sta_priv->supported_rates.supported_mcs_set)); memcpy(sta_priv->supported_rates.supported_mcs_set, - sta->ht_cap.mcs.rx_mask, - sizeof(sta->ht_cap.mcs.rx_mask)); + sta->deflink.ht_cap.mcs.rx_mask, + sizeof(sta->deflink.ht_cap.mcs.rx_mask)); } - if (sta->vht_cap.vht_supported) { + if (sta->deflink.vht_cap.vht_supported) { sta_priv->supported_rates.op_rate_mode = STA_11ac; sta_priv->supported_rates.vht_rx_mcs_map = - sta->vht_cap.vht_mcs.rx_mcs_map; + sta->deflink.vht_cap.vht_mcs.rx_mcs_map; sta_priv->supported_rates.vht_tx_mcs_map = - sta->vht_cap.vht_mcs.tx_mcs_map; + sta->deflink.vht_cap.vht_mcs.tx_mcs_map; } } diff --git a/drivers/net/wireless/ath/wcn36xx/smd.c b/drivers/net/wireless/ath/wcn36xx/smd.c index 872b37875c574..dc38056092843 100644 --- a/drivers/net/wireless/ath/wcn36xx/smd.c +++ b/drivers/net/wireless/ath/wcn36xx/smd.c @@ -208,9 +208,9 @@ static void wcn36xx_smd_set_bss_nw_type(struct wcn36xx *wcn, { if (NL80211_BAND_5GHZ == WCN36XX_BAND(wcn)) bss_params->nw_type = WCN36XX_HAL_11A_NW_TYPE; - else if (sta && sta->ht_cap.ht_supported) + else if (sta && sta->deflink.ht_cap.ht_supported) bss_params->nw_type = WCN36XX_HAL_11N_NW_TYPE; - else if (sta && (sta->supp_rates[NL80211_BAND_2GHZ] & 0x7f)) + else if (sta && (sta->deflink.supp_rates[NL80211_BAND_2GHZ] & 0x7f)) bss_params->nw_type = WCN36XX_HAL_11G_NW_TYPE; else bss_params->nw_type = WCN36XX_HAL_11B_NW_TYPE; @@ -225,9 +225,10 @@ static void wcn36xx_smd_set_bss_ht_params(struct ieee80211_vif *vif, struct ieee80211_sta *sta, struct wcn36xx_hal_config_bss_params *bss_params) { - if (sta && sta->ht_cap.ht_supported) { - unsigned long caps = sta->ht_cap.cap; - bss_params->ht = sta->ht_cap.ht_supported; + if (sta && sta->deflink.ht_cap.ht_supported) { + unsigned long caps = sta->deflink.ht_cap.cap; + + bss_params->ht = sta->deflink.ht_cap.ht_supported; bss_params->tx_channel_width_set = is_cap_supported(caps, IEEE80211_HT_CAP_SUP_WIDTH_20_40); bss_params->lsig_tx_op_protection_full_support = @@ -250,23 +251,24 @@ wcn36xx_smd_set_bss_vht_params(struct ieee80211_vif *vif, struct ieee80211_sta *sta, struct wcn36xx_hal_config_bss_params_v1 *bss) { - if (sta && sta->vht_cap.vht_supported) + if (sta && sta->deflink.vht_cap.vht_supported) bss->vht_capable = 1; } static void wcn36xx_smd_set_sta_ht_params(struct ieee80211_sta *sta, struct wcn36xx_hal_config_sta_params *sta_params) { - if (sta->ht_cap.ht_supported) { - unsigned long caps = sta->ht_cap.cap; - sta_params->ht_capable = sta->ht_cap.ht_supported; + if (sta->deflink.ht_cap.ht_supported) { + unsigned long caps = sta->deflink.ht_cap.cap; + + sta_params->ht_capable = sta->deflink.ht_cap.ht_supported; sta_params->tx_channel_width_set = is_cap_supported(caps, IEEE80211_HT_CAP_SUP_WIDTH_20_40); sta_params->lsig_txop_protection = is_cap_supported(caps, IEEE80211_HT_CAP_LSIG_TXOP_PROT); - sta_params->max_ampdu_size = sta->ht_cap.ampdu_factor; - sta_params->max_ampdu_density = sta->ht_cap.ampdu_density; + sta_params->max_ampdu_size = sta->deflink.ht_cap.ampdu_factor; + sta_params->max_ampdu_density = sta->deflink.ht_cap.ampdu_density; /* max_amsdu_size: 1 : 3839 bytes, 0 : 7935 bytes (max) */ sta_params->max_amsdu_size = !is_cap_supported(caps, IEEE80211_HT_CAP_MAX_AMSDU); @@ -287,10 +289,10 @@ static void wcn36xx_smd_set_sta_vht_params(struct wcn36xx *wcn, struct ieee80211_sta *sta, struct wcn36xx_hal_config_sta_params_v1 *sta_params) { - if (sta->vht_cap.vht_supported) { - unsigned long caps = sta->vht_cap.cap; + if (sta->deflink.vht_cap.vht_supported) { + unsigned long caps = sta->deflink.vht_cap.cap; - sta_params->vht_capable = sta->vht_cap.vht_supported; + sta_params->vht_capable = sta->deflink.vht_cap.vht_supported; sta_params->vht_ldpc_enabled = is_cap_supported(caps, IEEE80211_VHT_CAP_RXLDPC); if (get_feat_caps(wcn->fw_feat_caps, MU_MIMO)) { @@ -308,9 +310,10 @@ static void wcn36xx_smd_set_sta_vht_params(struct wcn36xx *wcn, static void wcn36xx_smd_set_sta_ht_ldpc_params(struct ieee80211_sta *sta, struct wcn36xx_hal_config_sta_params_v1 *sta_params) { - if (sta->ht_cap.ht_supported) { + if (sta->deflink.ht_cap.ht_supported) { sta_params->ht_ldpc_enabled = - is_cap_supported(sta->ht_cap.cap, IEEE80211_HT_CAP_LDPC_CODING); + is_cap_supported(sta->deflink.ht_cap.cap, + IEEE80211_HT_CAP_LDPC_CODING); } } diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmsmac/mac80211_if.c b/drivers/net/wireless/broadcom/brcm80211/brcmsmac/mac80211_if.c index eadac0f5590fc..8c741b98d8e5e 100644 --- a/drivers/net/wireless/broadcom/brcm80211/brcmsmac/mac80211_if.c +++ b/drivers/net/wireless/broadcom/brcm80211/brcmsmac/mac80211_if.c @@ -868,7 +868,7 @@ brcms_ops_ampdu_action(struct ieee80211_hw *hw, spin_lock_bh(&wl->lock); brcms_c_ampdu_tx_operational(wl->wlc, tid, buf_size, (1 << (IEEE80211_HT_MAX_AMPDU_FACTOR + - sta->ht_cap.ampdu_factor)) - 1); + sta->deflink.ht_cap.ampdu_factor)) - 1); spin_unlock_bh(&wl->lock); /* Power save wakeup */ break; diff --git a/drivers/net/wireless/intel/iwlegacy/3945-rs.c b/drivers/net/wireless/intel/iwlegacy/3945-rs.c index b2478cbe558e6..0eaad980c85c5 100644 --- a/drivers/net/wireless/intel/iwlegacy/3945-rs.c +++ b/drivers/net/wireless/intel/iwlegacy/3945-rs.c @@ -354,13 +354,13 @@ il3945_rs_rate_init(struct il_priv *il, struct ieee80211_sta *sta, u8 sta_id) * after assoc.. */ for (i = sband->n_bitrates - 1; i >= 0; i--) { - if (sta->supp_rates[sband->band] & (1 << i)) { + if (sta->deflink.supp_rates[sband->band] & (1 << i)) { rs_sta->last_txrate_idx = i; break; } } - il->_3945.sta_supp_rates = sta->supp_rates[sband->band]; + il->_3945.sta_supp_rates = sta->deflink.supp_rates[sband->band]; /* For 5 GHz band it start at IL_FIRST_OFDM_RATE */ if (sband->band == NL80211_BAND_5GHZ) { rs_sta->last_txrate_idx += IL_FIRST_OFDM_RATE; @@ -631,7 +631,7 @@ il3945_rs_get_rate(void *il_r, struct ieee80211_sta *sta, void *il_sta, il_sta = NULL; } - rate_mask = sta->supp_rates[sband->band]; + rate_mask = sta->deflink.supp_rates[sband->band]; /* get user max rate if set */ max_rate_idx = fls(txrc->rate_idx_mask) - 1; diff --git a/drivers/net/wireless/intel/iwlegacy/4965-rs.c b/drivers/net/wireless/intel/iwlegacy/4965-rs.c index 9a491e5db75bd..9dd2d890e35fe 100644 --- a/drivers/net/wireless/intel/iwlegacy/4965-rs.c +++ b/drivers/net/wireless/intel/iwlegacy/4965-rs.c @@ -627,7 +627,7 @@ il4965_rs_toggle_antenna(u32 valid_ant, u32 *rate_n_flags, static bool il4965_rs_use_green(struct il_priv *il, struct ieee80211_sta *sta) { - return (sta->ht_cap.cap & IEEE80211_HT_CAP_GRN_FLD) && + return (sta->deflink.ht_cap.cap & IEEE80211_HT_CAP_GRN_FLD) && !il->ht.non_gf_sta_present; } @@ -970,7 +970,7 @@ il4965_rs_tx_status(void *il_r, struct ieee80211_supported_band *sband, lq_sta->last_rate_n_flags = tx_rate; done: /* See if there's a better rate or modulation mode to try. */ - if (sta->supp_rates[sband->band]) + if (sta->deflink.supp_rates[sband->band]) il4965_rs_rate_scale_perform(il, skb, sta, lq_sta); } @@ -1164,7 +1164,7 @@ il4965_rs_switch_to_mimo2(struct il_priv *il, struct il_lq_sta *lq_sta, s32 rate; s8 is_green = lq_sta->is_green; - if (!conf_is_ht(conf) || !sta->ht_cap.ht_supported) + if (!conf_is_ht(conf) || !sta->deflink.ht_cap.ht_supported) return -1; if (sta->smps_mode == IEEE80211_SMPS_STATIC) @@ -1182,7 +1182,7 @@ il4965_rs_switch_to_mimo2(struct il_priv *il, struct il_lq_sta *lq_sta, tbl->max_search = IL_MAX_SEARCH; rate_mask = lq_sta->active_mimo2_rate; - if (il_is_ht40_tx_allowed(il, &sta->ht_cap)) + if (il_is_ht40_tx_allowed(il, &sta->deflink.ht_cap)) tbl->is_ht40 = 1; else tbl->is_ht40 = 0; @@ -1217,7 +1217,7 @@ il4965_rs_switch_to_siso(struct il_priv *il, struct il_lq_sta *lq_sta, u8 is_green = lq_sta->is_green; s32 rate; - if (!conf_is_ht(conf) || !sta->ht_cap.ht_supported) + if (!conf_is_ht(conf) || !sta->deflink.ht_cap.ht_supported) return -1; D_RATE("LQ: try to switch to SISO\n"); @@ -1228,7 +1228,7 @@ il4965_rs_switch_to_siso(struct il_priv *il, struct il_lq_sta *lq_sta, tbl->max_search = IL_MAX_SEARCH; rate_mask = lq_sta->active_siso_rate; - if (il_is_ht40_tx_allowed(il, &sta->ht_cap)) + if (il_is_ht40_tx_allowed(il, &sta->deflink.ht_cap)) tbl->is_ht40 = 1; else tbl->is_ht40 = 0; @@ -1384,7 +1384,7 @@ il4965_rs_move_siso_to_other(struct il_priv *il, struct il_lq_sta *lq_sta, struct il_scale_tbl_info *search_tbl = &(lq_sta->lq_info[(1 - lq_sta->active_tbl)]); struct il_rate_scale_data *win = &(tbl->win[idx]); - struct ieee80211_sta_ht_cap *ht_cap = &sta->ht_cap; + struct ieee80211_sta_ht_cap *ht_cap = &sta->deflink.ht_cap; u32 sz = (sizeof(struct il_scale_tbl_info) - (sizeof(struct il_rate_scale_data) * RATE_COUNT)); @@ -1507,7 +1507,7 @@ il4965_rs_move_mimo2_to_other(struct il_priv *il, struct il_lq_sta *lq_sta, struct il_scale_tbl_info *search_tbl = &(lq_sta->lq_info[(1 - lq_sta->active_tbl)]); struct il_rate_scale_data *win = &(tbl->win[idx]); - struct ieee80211_sta_ht_cap *ht_cap = &sta->ht_cap; + struct ieee80211_sta_ht_cap *ht_cap = &sta->deflink.ht_cap; u32 sz = (sizeof(struct il_scale_tbl_info) - (sizeof(struct il_rate_scale_data) * RATE_COUNT)); @@ -1760,7 +1760,7 @@ il4965_rs_rate_scale_perform(struct il_priv *il, struct sk_buff *skb, (info->flags & IEEE80211_TX_CTL_NO_ACK)) return; - lq_sta->supp_rates = sta->supp_rates[lq_sta->band]; + lq_sta->supp_rates = sta->deflink.supp_rates[lq_sta->band]; tid = il4965_rs_tl_add_packet(lq_sta, hdr); if (tid != MAX_TID_COUNT && (lq_sta->tx_agg_tid_en & (1 << tid))) { @@ -2271,7 +2271,7 @@ il4965_rs_rate_init(struct il_priv *il, struct ieee80211_sta *sta, u8 sta_id) int i, j; struct ieee80211_hw *hw = il->hw; struct ieee80211_conf *conf = &il->hw->conf; - struct ieee80211_sta_ht_cap *ht_cap = &sta->ht_cap; + struct ieee80211_sta_ht_cap *ht_cap = &sta->deflink.ht_cap; struct il_station_priv *sta_priv; struct il_lq_sta *lq_sta; struct ieee80211_supported_band *sband; @@ -2288,7 +2288,7 @@ il4965_rs_rate_init(struct il_priv *il, struct ieee80211_sta *sta, u8 sta_id) win[i]); lq_sta->flush_timer = 0; - lq_sta->supp_rates = sta->supp_rates[sband->band]; + lq_sta->supp_rates = sta->deflink.supp_rates[sband->band]; for (j = 0; j < LQ_SIZE; j++) for (i = 0; i < RATE_COUNT; i++) il4965_rs_rate_scale_clear_win(&lq_sta->lq_info[j]. diff --git a/drivers/net/wireless/intel/iwlegacy/common.c b/drivers/net/wireless/intel/iwlegacy/common.c index 683b632981ed3..8299d89e7505c 100644 --- a/drivers/net/wireless/intel/iwlegacy/common.c +++ b/drivers/net/wireless/intel/iwlegacy/common.c @@ -1863,7 +1863,7 @@ EXPORT_SYMBOL(il_send_add_sta); static void il_set_ht_add_station(struct il_priv *il, u8 idx, struct ieee80211_sta *sta) { - struct ieee80211_sta_ht_cap *sta_ht_inf = &sta->ht_cap; + struct ieee80211_sta_ht_cap *sta_ht_inf = &sta->deflink.ht_cap; __le32 sta_flags; if (!sta || !sta_ht_inf->ht_supported) @@ -1900,7 +1900,7 @@ il_set_ht_add_station(struct il_priv *il, u8 idx, struct ieee80211_sta *sta) cpu_to_le32((u32) sta_ht_inf-> ampdu_density << STA_FLG_AGG_MPDU_DENSITY_POS); - if (il_is_ht40_tx_allowed(il, &sta->ht_cap)) + if (il_is_ht40_tx_allowed(il, &sta->deflink.ht_cap)) sta_flags |= STA_FLG_HT40_EN_MSK; else sta_flags &= ~STA_FLG_HT40_EN_MSK; @@ -5222,7 +5222,7 @@ il_ht_conf(struct il_priv *il, struct ieee80211_vif *vif) rcu_read_lock(); sta = ieee80211_find_sta(vif, bss_conf->bssid); if (sta) { - struct ieee80211_sta_ht_cap *ht_cap = &sta->ht_cap; + struct ieee80211_sta_ht_cap *ht_cap = &sta->deflink.ht_cap; int maxstreams; maxstreams = diff --git a/drivers/net/wireless/intel/iwlwifi/dvm/rs.c b/drivers/net/wireless/intel/iwlwifi/dvm/rs.c index b7c8b209bfea4..baffa1cbe8fc4 100644 --- a/drivers/net/wireless/intel/iwlwifi/dvm/rs.c +++ b/drivers/net/wireless/intel/iwlwifi/dvm/rs.c @@ -1039,7 +1039,7 @@ static void rs_tx_status(void *priv_r, struct ieee80211_supported_band *sband, lq_sta->last_rate_n_flags = tx_rate; done: /* See if there's a better rate or modulation mode to try. */ - if (sta && sta->supp_rates[sband->band]) + if (sta && sta->deflink.supp_rates[sband->band]) rs_rate_scale_perform(priv, skb, sta, lq_sta); if (priv->lib->bt_params && priv->lib->bt_params->advanced_bt_coexist) @@ -1239,7 +1239,7 @@ static int rs_switch_to_mimo2(struct iwl_priv *priv, struct iwl_station_priv *sta_priv = (void *)sta->drv_priv; struct iwl_rxon_context *ctx = sta_priv->ctx; - if (!conf_is_ht(conf) || !sta->ht_cap.ht_supported) + if (!conf_is_ht(conf) || !sta->deflink.ht_cap.ht_supported) return -1; if (sta->smps_mode == IEEE80211_SMPS_STATIC) @@ -1294,7 +1294,7 @@ static int rs_switch_to_mimo3(struct iwl_priv *priv, struct iwl_station_priv *sta_priv = (void *)sta->drv_priv; struct iwl_rxon_context *ctx = sta_priv->ctx; - if (!conf_is_ht(conf) || !sta->ht_cap.ht_supported) + if (!conf_is_ht(conf) || !sta->deflink.ht_cap.ht_supported) return -1; if (sta->smps_mode == IEEE80211_SMPS_STATIC) @@ -1350,7 +1350,7 @@ static int rs_switch_to_siso(struct iwl_priv *priv, struct iwl_station_priv *sta_priv = (void *)sta->drv_priv; struct iwl_rxon_context *ctx = sta_priv->ctx; - if (!conf_is_ht(conf) || !sta->ht_cap.ht_supported) + if (!conf_is_ht(conf) || !sta->deflink.ht_cap.ht_supported) return -1; IWL_DEBUG_RATE(priv, "LQ: try to switch to SISO\n"); @@ -1570,7 +1570,7 @@ static void rs_move_siso_to_other(struct iwl_priv *priv, struct iwl_scale_tbl_info *search_tbl = &(lq_sta->lq_info[(1 - lq_sta->active_tbl)]); struct iwl_rate_scale_data *window = &(tbl->win[index]); - struct ieee80211_sta_ht_cap *ht_cap = &sta->ht_cap; + struct ieee80211_sta_ht_cap *ht_cap = &sta->deflink.ht_cap; u32 sz = (sizeof(struct iwl_scale_tbl_info) - (sizeof(struct iwl_rate_scale_data) * IWL_RATE_COUNT)); u8 start_action; @@ -1740,7 +1740,7 @@ static void rs_move_mimo2_to_other(struct iwl_priv *priv, struct iwl_scale_tbl_info *search_tbl = &(lq_sta->lq_info[(1 - lq_sta->active_tbl)]); struct iwl_rate_scale_data *window = &(tbl->win[index]); - struct ieee80211_sta_ht_cap *ht_cap = &sta->ht_cap; + struct ieee80211_sta_ht_cap *ht_cap = &sta->deflink.ht_cap; u32 sz = (sizeof(struct iwl_scale_tbl_info) - (sizeof(struct iwl_rate_scale_data) * IWL_RATE_COUNT)); u8 start_action; @@ -1908,7 +1908,7 @@ static void rs_move_mimo3_to_other(struct iwl_priv *priv, struct iwl_scale_tbl_info *search_tbl = &(lq_sta->lq_info[(1 - lq_sta->active_tbl)]); struct iwl_rate_scale_data *window = &(tbl->win[index]); - struct ieee80211_sta_ht_cap *ht_cap = &sta->ht_cap; + struct ieee80211_sta_ht_cap *ht_cap = &sta->deflink.ht_cap; u32 sz = (sizeof(struct iwl_scale_tbl_info) - (sizeof(struct iwl_rate_scale_data) * IWL_RATE_COUNT)); u8 start_action; @@ -2212,7 +2212,7 @@ static void rs_rate_scale_perform(struct iwl_priv *priv, info->flags & IEEE80211_TX_CTL_NO_ACK) return; - lq_sta->supp_rates = sta->supp_rates[lq_sta->band]; + lq_sta->supp_rates = sta->deflink.supp_rates[lq_sta->band]; tid = rs_tl_add_packet(lq_sta, hdr); if ((tid != IWL_MAX_TID_COUNT) && @@ -2763,7 +2763,7 @@ void iwl_rs_rate_init(struct iwl_priv *priv, struct ieee80211_sta *sta, u8 sta_i int i, j; struct ieee80211_hw *hw = priv->hw; struct ieee80211_conf *conf = &priv->hw->conf; - struct ieee80211_sta_ht_cap *ht_cap = &sta->ht_cap; + struct ieee80211_sta_ht_cap *ht_cap = &sta->deflink.ht_cap; struct iwl_station_priv *sta_priv; struct iwl_lq_sta *lq_sta; struct ieee80211_supported_band *sband; @@ -2781,7 +2781,7 @@ void iwl_rs_rate_init(struct iwl_priv *priv, struct ieee80211_sta *sta, u8 sta_i rs_rate_scale_clear_window(&lq_sta->lq_info[j].win[i]); lq_sta->flush_timer = 0; - lq_sta->supp_rates = sta->supp_rates[sband->band]; + lq_sta->supp_rates = sta->deflink.supp_rates[sband->band]; IWL_DEBUG_RATE(priv, "LQ: *** rate scale station global init for station %d ***\n", sta_id); @@ -2798,7 +2798,7 @@ void iwl_rs_rate_init(struct iwl_priv *priv, struct ieee80211_sta *sta, u8 sta_i /* * active legacy rates as per supported rates bitmap */ - supp = sta->supp_rates[sband->band]; + supp = sta->deflink.supp_rates[sband->band]; lq_sta->active_legacy_rate = 0; for_each_set_bit(i, &supp, BITS_PER_LONG) lq_sta->active_legacy_rate |= BIT(sband->bitrates[i].hw_value); diff --git a/drivers/net/wireless/intel/iwlwifi/dvm/rxon.c b/drivers/net/wireless/intel/iwlwifi/dvm/rxon.c index 70338bc7bb540..5dd2d43a01d88 100644 --- a/drivers/net/wireless/intel/iwlwifi/dvm/rxon.c +++ b/drivers/net/wireless/intel/iwlwifi/dvm/rxon.c @@ -1280,7 +1280,7 @@ static void iwlagn_check_needed_chains(struct iwl_priv *priv, break; } - ht_cap = &sta->ht_cap; + ht_cap = &sta->deflink.ht_cap; need_multiple = true; diff --git a/drivers/net/wireless/intel/iwlwifi/dvm/sta.c b/drivers/net/wireless/intel/iwlwifi/dvm/sta.c index 8f7a0f36c276b..476068c0abb7f 100644 --- a/drivers/net/wireless/intel/iwlwifi/dvm/sta.c +++ b/drivers/net/wireless/intel/iwlwifi/dvm/sta.c @@ -139,7 +139,7 @@ bool iwl_is_ht40_tx_allowed(struct iwl_priv *priv, if (!sta) return true; - return sta->bandwidth >= IEEE80211_STA_RX_BW_40; + return sta->deflink.bandwidth >= IEEE80211_STA_RX_BW_40; } static void iwl_sta_calc_ht_flags(struct iwl_priv *priv, @@ -147,7 +147,7 @@ static void iwl_sta_calc_ht_flags(struct iwl_priv *priv, struct iwl_rxon_context *ctx, __le32 *flags, __le32 *mask) { - struct ieee80211_sta_ht_cap *sta_ht_inf = &sta->ht_cap; + struct ieee80211_sta_ht_cap *sta_ht_inf = &sta->deflink.ht_cap; *mask = STA_FLG_RTS_MIMO_PROT_MSK | STA_FLG_MIMO_DIS_MSK | diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/d3.c b/drivers/net/wireless/intel/iwlwifi/mvm/d3.c index a995bba0ba81b..bcc4ed20fe5b7 100644 --- a/drivers/net/wireless/intel/iwlwifi/mvm/d3.c +++ b/drivers/net/wireless/intel/iwlwifi/mvm/d3.c @@ -915,7 +915,7 @@ iwl_mvm_get_wowlan_config(struct iwl_mvm *mvm, /* TODO: wowlan_config_cmd->wowlan_ba_teardown_tids */ wowlan_config_cmd->is_11n_connection = - ap_sta->ht_cap.ht_supported; + ap_sta->deflink.ht_cap.ht_supported; wowlan_config_cmd->flags = ENABLE_L3_FILTERING | ENABLE_NBNS_FILTERING | ENABLE_DHCP_FILTERING; diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/mac80211.c b/drivers/net/wireless/intel/iwlwifi/mvm/mac80211.c index 784d91281c029..4fda6c3ba9f33 100644 --- a/drivers/net/wireless/intel/iwlwifi/mvm/mac80211.c +++ b/drivers/net/wireless/intel/iwlwifi/mvm/mac80211.c @@ -1877,8 +1877,8 @@ static void iwl_mvm_set_pkt_ext_from_he_ppe(struct iwl_mvm *mvm, struct ieee80211_sta *sta, struct iwl_he_pkt_ext_v2 *pkt_ext) { - u8 nss = (sta->he_cap.ppe_thres[0] & IEEE80211_PPE_THRES_NSS_MASK) + 1; - u8 *ppe = &sta->he_cap.ppe_thres[0]; + u8 nss = (sta->deflink.he_cap.ppe_thres[0] & IEEE80211_PPE_THRES_NSS_MASK) + 1; + u8 *ppe = &sta->deflink.he_cap.ppe_thres[0]; u8 ru_index_bitmap = u8_get_bits(*ppe, IEEE80211_PPE_THRES_RU_INDEX_BITMASK_MASK); @@ -1993,7 +1993,7 @@ static void iwl_mvm_cfg_he_sta(struct iwl_mvm *mvm, return; } - if (!sta->he_cap.has_he) { + if (!sta->deflink.he_cap.has_he) { rcu_read_unlock(); return; } @@ -2005,17 +2005,17 @@ static void iwl_mvm_cfg_he_sta(struct iwl_mvm *mvm, flags |= STA_CTXT_HE_RU_2MHZ_BLOCK; /* HTC flags */ - if (sta->he_cap.he_cap_elem.mac_cap_info[0] & + if (sta->deflink.he_cap.he_cap_elem.mac_cap_info[0] & IEEE80211_HE_MAC_CAP0_HTC_HE) sta_ctxt_cmd.htc_flags |= cpu_to_le32(IWL_HE_HTC_SUPPORT); - if ((sta->he_cap.he_cap_elem.mac_cap_info[1] & + if ((sta->deflink.he_cap.he_cap_elem.mac_cap_info[1] & IEEE80211_HE_MAC_CAP1_LINK_ADAPTATION) || - (sta->he_cap.he_cap_elem.mac_cap_info[2] & + (sta->deflink.he_cap.he_cap_elem.mac_cap_info[2] & IEEE80211_HE_MAC_CAP2_LINK_ADAPTATION)) { u8 link_adap = - ((sta->he_cap.he_cap_elem.mac_cap_info[2] & + ((sta->deflink.he_cap.he_cap_elem.mac_cap_info[2] & IEEE80211_HE_MAC_CAP2_LINK_ADAPTATION) << 1) + - (sta->he_cap.he_cap_elem.mac_cap_info[1] & + (sta->deflink.he_cap.he_cap_elem.mac_cap_info[1] & IEEE80211_HE_MAC_CAP1_LINK_ADAPTATION); if (link_adap == 2) @@ -2025,12 +2025,12 @@ static void iwl_mvm_cfg_he_sta(struct iwl_mvm *mvm, sta_ctxt_cmd.htc_flags |= cpu_to_le32(IWL_HE_HTC_LINK_ADAP_BOTH); } - if (sta->he_cap.he_cap_elem.mac_cap_info[2] & IEEE80211_HE_MAC_CAP2_BSR) + if (sta->deflink.he_cap.he_cap_elem.mac_cap_info[2] & IEEE80211_HE_MAC_CAP2_BSR) sta_ctxt_cmd.htc_flags |= cpu_to_le32(IWL_HE_HTC_BSR_SUPP); - if (sta->he_cap.he_cap_elem.mac_cap_info[3] & + if (sta->deflink.he_cap.he_cap_elem.mac_cap_info[3] & IEEE80211_HE_MAC_CAP3_OMI_CONTROL) sta_ctxt_cmd.htc_flags |= cpu_to_le32(IWL_HE_HTC_OMI_SUPP); - if (sta->he_cap.he_cap_elem.mac_cap_info[4] & IEEE80211_HE_MAC_CAP4_BQR) + if (sta->deflink.he_cap.he_cap_elem.mac_cap_info[4] & IEEE80211_HE_MAC_CAP4_BQR) sta_ctxt_cmd.htc_flags |= cpu_to_le32(IWL_HE_HTC_BQR_SUPP); /* @@ -2041,7 +2041,7 @@ static void iwl_mvm_cfg_he_sta(struct iwl_mvm *mvm, sizeof(sta_ctxt_cmd.pkt_ext)); /* If PPE Thresholds exist, parse them into a FW-familiar format. */ - if (sta->he_cap.he_cap_elem.phy_cap_info[6] & + if (sta->deflink.he_cap.he_cap_elem.phy_cap_info[6] & IEEE80211_HE_PHY_CAP6_PPE_THRESHOLD_PRESENT) { iwl_mvm_set_pkt_ext_from_he_ppe(mvm, sta, &sta_ctxt_cmd.pkt_ext); @@ -2050,7 +2050,7 @@ static void iwl_mvm_cfg_he_sta(struct iwl_mvm *mvm, * according to Common Nominal Packet Padding fiels. */ } else { u8 nominal_padding = - u8_get_bits(sta->he_cap.he_cap_elem.phy_cap_info[9], + u8_get_bits(sta->deflink.he_cap.he_cap_elem.phy_cap_info[9], IEEE80211_HE_PHY_CAP9_NOMINAL_PKT_PADDING_MASK); if (nominal_padding != IEEE80211_HE_PHY_CAP9_NOMINAL_PKT_PADDING_RESERVED) iwl_mvm_set_pkt_ext_from_nominal_padding(&sta_ctxt_cmd.pkt_ext, @@ -2058,11 +2058,11 @@ static void iwl_mvm_cfg_he_sta(struct iwl_mvm *mvm, &flags); } - if (sta->he_cap.he_cap_elem.mac_cap_info[2] & + if (sta->deflink.he_cap.he_cap_elem.mac_cap_info[2] & IEEE80211_HE_MAC_CAP2_32BIT_BA_BITMAP) flags |= STA_CTXT_HE_32BIT_BA_BITMAP; - if (sta->he_cap.he_cap_elem.mac_cap_info[2] & + if (sta->deflink.he_cap.he_cap_elem.mac_cap_info[2] & IEEE80211_HE_MAC_CAP2_ACK_EN) flags |= STA_CTXT_HE_ACK_ENABLED; @@ -3157,7 +3157,7 @@ static int iwl_mvm_mac_sta_state(struct ieee80211_hw *hw, } if (vif->type == NL80211_IFTYPE_STATION) - vif->bss_conf.he_support = sta->he_cap.has_he; + vif->bss_conf.he_support = sta->deflink.he_cap.has_he; if (sta->tdls && (vif->p2p || @@ -3189,17 +3189,17 @@ static int iwl_mvm_mac_sta_state(struct ieee80211_hw *hw, } else if (old_state == IEEE80211_STA_AUTH && new_state == IEEE80211_STA_ASSOC) { if (vif->type == NL80211_IFTYPE_AP) { - vif->bss_conf.he_support = sta->he_cap.has_he; + vif->bss_conf.he_support = sta->deflink.he_cap.has_he; mvmvif->ap_assoc_sta_count++; iwl_mvm_mac_ctxt_changed(mvm, vif, false, NULL); if (vif->bss_conf.he_support && !iwlwifi_mod_params.disable_11ax) iwl_mvm_cfg_he_sta(mvm, vif, mvm_sta->sta_id); } else if (vif->type == NL80211_IFTYPE_STATION) { - vif->bss_conf.he_support = sta->he_cap.has_he; + vif->bss_conf.he_support = sta->deflink.he_cap.has_he; mvmvif->he_ru_2mhz_block = false; - if (sta->he_cap.has_he) + if (sta->deflink.he_cap.has_he) iwl_mvm_check_he_obss_narrow_bw_ru(hw, vif); iwl_mvm_mac_ctxt_changed(mvm, vif, false, NULL); diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/rs-fw.c b/drivers/net/wireless/intel/iwlwifi/mvm/rs-fw.c index 9830d26636898..d8c3d7ff4f44b 100644 --- a/drivers/net/wireless/intel/iwlwifi/mvm/rs-fw.c +++ b/drivers/net/wireless/intel/iwlwifi/mvm/rs-fw.c @@ -11,7 +11,7 @@ static u8 rs_fw_bw_from_sta_bw(struct ieee80211_sta *sta) { - switch (sta->bandwidth) { + switch (sta->deflink.bandwidth) { case IEEE80211_STA_RX_BW_160: return IWL_TLC_MNG_CH_WIDTH_160MHZ; case IEEE80211_STA_RX_BW_80: @@ -38,9 +38,9 @@ static u8 rs_fw_set_active_chains(u8 chains) static u8 rs_fw_sgi_cw_support(struct ieee80211_sta *sta) { - struct ieee80211_sta_ht_cap *ht_cap = &sta->ht_cap; - struct ieee80211_sta_vht_cap *vht_cap = &sta->vht_cap; - struct ieee80211_sta_he_cap *he_cap = &sta->he_cap; + struct ieee80211_sta_ht_cap *ht_cap = &sta->deflink.ht_cap; + struct ieee80211_sta_vht_cap *vht_cap = &sta->deflink.vht_cap; + struct ieee80211_sta_he_cap *he_cap = &sta->deflink.he_cap; u8 supp = 0; if (he_cap->has_he) @@ -62,9 +62,9 @@ static u16 rs_fw_get_config_flags(struct iwl_mvm *mvm, struct ieee80211_sta *sta, struct ieee80211_supported_band *sband) { - struct ieee80211_sta_ht_cap *ht_cap = &sta->ht_cap; - struct ieee80211_sta_vht_cap *vht_cap = &sta->vht_cap; - struct ieee80211_sta_he_cap *he_cap = &sta->he_cap; + struct ieee80211_sta_ht_cap *ht_cap = &sta->deflink.ht_cap; + struct ieee80211_sta_vht_cap *vht_cap = &sta->deflink.vht_cap; + struct ieee80211_sta_he_cap *he_cap = &sta->deflink.he_cap; bool vht_ena = vht_cap->vht_supported; u16 flags = 0; @@ -136,7 +136,7 @@ rs_fw_vht_set_enabled_rates(const struct ieee80211_sta *sta, { u16 supp; int i, highest_mcs; - u8 max_nss = sta->rx_nss; + u8 max_nss = sta->deflink.rx_nss; struct ieee80211_vht_cap ieee_vht_cap = { .vht_cap_info = cpu_to_le32(vht_cap->cap), .supp_mcs = vht_cap->vht_mcs, @@ -154,7 +154,7 @@ rs_fw_vht_set_enabled_rates(const struct ieee80211_sta *sta, continue; supp = BIT(highest_mcs + 1) - 1; - if (sta->bandwidth == IEEE80211_STA_RX_BW_20) + if (sta->deflink.bandwidth == IEEE80211_STA_RX_BW_20) supp &= ~BIT(IWL_TLC_MNG_HT_RATE_MCS9); cmd->ht_rates[i][IWL_TLC_MCS_PER_BW_80] = cpu_to_le16(supp); @@ -163,7 +163,7 @@ rs_fw_vht_set_enabled_rates(const struct ieee80211_sta *sta, * configuration is supported - only for MCS 0 since we already * decoded the MCS bits anyway ourselves. */ - if (sta->bandwidth == IEEE80211_STA_RX_BW_160 && + if (sta->deflink.bandwidth == IEEE80211_STA_RX_BW_160 && ieee80211_get_vht_max_nss(&ieee_vht_cap, IEEE80211_VHT_CHANWIDTH_160MHZ, 0, true, nss) >= nss) @@ -194,7 +194,7 @@ rs_fw_he_set_enabled_rates(const struct ieee80211_sta *sta, struct ieee80211_supported_band *sband, struct iwl_tlc_config_cmd_v4 *cmd) { - const struct ieee80211_sta_he_cap *he_cap = &sta->he_cap; + const struct ieee80211_sta_he_cap *he_cap = &sta->deflink.he_cap; u16 mcs_160 = le16_to_cpu(he_cap->he_mcs_nss_supp.rx_mcs_160); u16 mcs_80 = le16_to_cpu(he_cap->he_mcs_nss_supp.rx_mcs_80); u16 tx_mcs_80 = @@ -202,7 +202,7 @@ rs_fw_he_set_enabled_rates(const struct ieee80211_sta *sta, u16 tx_mcs_160 = le16_to_cpu(sband->iftype_data->he_cap.he_mcs_nss_supp.tx_mcs_160); int i; - u8 nss = sta->rx_nss; + u8 nss = sta->deflink.rx_nss; /* the station support only a single receive chain */ if (sta->smps_mode == IEEE80211_SMPS_STATIC) @@ -245,12 +245,12 @@ static void rs_fw_set_supp_rates(struct ieee80211_sta *sta, int i; u16 supp = 0; unsigned long tmp; /* must be unsigned long for for_each_set_bit */ - const struct ieee80211_sta_ht_cap *ht_cap = &sta->ht_cap; - const struct ieee80211_sta_vht_cap *vht_cap = &sta->vht_cap; - const struct ieee80211_sta_he_cap *he_cap = &sta->he_cap; + const struct ieee80211_sta_ht_cap *ht_cap = &sta->deflink.ht_cap; + const struct ieee80211_sta_vht_cap *vht_cap = &sta->deflink.vht_cap; + const struct ieee80211_sta_he_cap *he_cap = &sta->deflink.he_cap; /* non HT rates */ - tmp = sta->supp_rates[sband->band]; + tmp = sta->deflink.supp_rates[sband->band]; for_each_set_bit(i, &tmp, BITS_PER_LONG) supp |= BIT(sband->bitrates[i].hw_value); @@ -378,11 +378,11 @@ void iwl_mvm_tlc_update_notif(struct iwl_mvm *mvm, u16 rs_fw_get_max_amsdu_len(struct ieee80211_sta *sta) { struct iwl_mvm_sta *mvmsta = iwl_mvm_sta_from_mac80211(sta); - const struct ieee80211_sta_vht_cap *vht_cap = &sta->vht_cap; - const struct ieee80211_sta_ht_cap *ht_cap = &sta->ht_cap; + const struct ieee80211_sta_vht_cap *vht_cap = &sta->deflink.vht_cap; + const struct ieee80211_sta_ht_cap *ht_cap = &sta->deflink.ht_cap; if (mvmsta->vif->bss_conf.chandef.chan->band == NL80211_BAND_6GHZ) { - switch (le16_get_bits(sta->he_6ghz_capa.capa, + switch (le16_get_bits(sta->deflink.he_6ghz_capa.capa, IEEE80211_HE_6GHZ_CAP_MAX_MPDU_LEN)) { case IEEE80211_VHT_CAP_MAX_MPDU_LENGTH_11454: return IEEE80211_MAX_MPDU_LEN_VHT_11454; diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/rs.c b/drivers/net/wireless/intel/iwlwifi/mvm/rs.c index 62114616317cf..974eeecc91537 100644 --- a/drivers/net/wireless/intel/iwlwifi/mvm/rs.c +++ b/drivers/net/wireless/intel/iwlwifi/mvm/rs.c @@ -135,7 +135,7 @@ static bool rs_mimo_allow(struct iwl_mvm *mvm, struct ieee80211_sta *sta, struct rs_rate *rate, const struct rs_tx_column *next_col) { - if (!sta->ht_cap.ht_supported) + if (!sta->deflink.ht_cap.ht_supported) return false; if (sta->smps_mode == IEEE80211_SMPS_STATIC) @@ -157,7 +157,7 @@ static bool rs_siso_allow(struct iwl_mvm *mvm, struct ieee80211_sta *sta, struct rs_rate *rate, const struct rs_tx_column *next_col) { - if (!sta->ht_cap.ht_supported) + if (!sta->deflink.ht_cap.ht_supported) return false; return true; @@ -167,8 +167,8 @@ static bool rs_sgi_allow(struct iwl_mvm *mvm, struct ieee80211_sta *sta, struct rs_rate *rate, const struct rs_tx_column *next_col) { - struct ieee80211_sta_ht_cap *ht_cap = &sta->ht_cap; - struct ieee80211_sta_vht_cap *vht_cap = &sta->vht_cap; + struct ieee80211_sta_ht_cap *ht_cap = &sta->deflink.ht_cap; + struct ieee80211_sta_vht_cap *vht_cap = &sta->deflink.vht_cap; if (is_ht20(rate) && (ht_cap->cap & IEEE80211_HT_CAP_SGI_20)) @@ -1369,13 +1369,13 @@ static s32 rs_get_best_rate(struct iwl_mvm *mvm, static u32 rs_bw_from_sta_bw(struct ieee80211_sta *sta) { - struct ieee80211_sta_vht_cap *sta_vht_cap = &sta->vht_cap; + struct ieee80211_sta_vht_cap *sta_vht_cap = &sta->deflink.vht_cap; struct ieee80211_vht_cap vht_cap = { .vht_cap_info = cpu_to_le32(sta_vht_cap->cap), .supp_mcs = sta_vht_cap->vht_mcs, }; - switch (sta->bandwidth) { + switch (sta->deflink.bandwidth) { case IEEE80211_STA_RX_BW_160: /* * Don't use 160 MHz if VHT extended NSS support @@ -1388,7 +1388,7 @@ static u32 rs_bw_from_sta_bw(struct ieee80211_sta *sta) if (ieee80211_get_vht_max_nss(&vht_cap, IEEE80211_VHT_CHANWIDTH_160MHZ, 0, true, - sta->rx_nss) < sta->rx_nss) + sta->deflink.rx_nss) < sta->deflink.rx_nss) return RATE_MCS_CHAN_WIDTH_80; return RATE_MCS_CHAN_WIDTH_160; case IEEE80211_STA_RX_BW_80: @@ -2537,7 +2537,7 @@ static void rs_get_initial_rate(struct iwl_mvm *mvm, * In case of VHT/HT when the rssi is low fallback to the case of * legacy rates. */ - if (sta->vht_cap.vht_supported && + if (sta->deflink.vht_cap.vht_supported && best_rssi > IWL_RS_LOW_RSSI_THRESHOLD) { /* * In AP mode, when a new station associates, rs is initialized @@ -2563,14 +2563,15 @@ static void rs_get_initial_rate(struct iwl_mvm *mvm, nentries = ARRAY_SIZE(rs_optimal_rates_vht_20mhz); break; default: - IWL_ERR(mvm, "Invalid BW %d\n", sta->bandwidth); + IWL_ERR(mvm, "Invalid BW %d\n", + sta->deflink.bandwidth); goto out; } active_rate = lq_sta->active_siso_rate; rate->type = LQ_VHT_SISO; rate->bw = bw; - } else if (sta->ht_cap.ht_supported && + } else if (sta->deflink.ht_cap.ht_supported && best_rssi > IWL_RS_LOW_RSSI_THRESHOLD) { initial_rates = rs_optimal_rates_ht; nentries = ARRAY_SIZE(rs_optimal_rates_ht); @@ -2761,14 +2762,14 @@ static void rs_vht_set_enabled_rates(struct ieee80211_sta *sta, /* VHT MCS9 isn't valid for 20Mhz for NSS=1,2 */ if (i == IWL_RATE_MCS_9_INDEX && - sta->bandwidth == IEEE80211_STA_RX_BW_20) + sta->deflink.bandwidth == IEEE80211_STA_RX_BW_20) continue; lq_sta->active_siso_rate |= BIT(i); } } - if (sta->rx_nss < 2) + if (sta->deflink.rx_nss < 2) return; highest_mcs = rs_vht_highest_rx_mcs_index(vht_cap, 2); @@ -2779,7 +2780,7 @@ static void rs_vht_set_enabled_rates(struct ieee80211_sta *sta, /* VHT MCS9 isn't valid for 20Mhz for NSS=1,2 */ if (i == IWL_RATE_MCS_9_INDEX && - sta->bandwidth == IEEE80211_STA_RX_BW_20) + sta->deflink.bandwidth == IEEE80211_STA_RX_BW_20) continue; lq_sta->active_mimo2_rate |= BIT(i); @@ -2916,8 +2917,8 @@ static void rs_drv_rate_init(struct iwl_mvm *mvm, struct ieee80211_sta *sta, { int i, j; struct ieee80211_hw *hw = mvm->hw; - struct ieee80211_sta_ht_cap *ht_cap = &sta->ht_cap; - struct ieee80211_sta_vht_cap *vht_cap = &sta->vht_cap; + struct ieee80211_sta_ht_cap *ht_cap = &sta->deflink.ht_cap; + struct ieee80211_sta_vht_cap *vht_cap = &sta->deflink.vht_cap; struct iwl_mvm_sta *mvmsta = iwl_mvm_sta_from_mac80211(sta); struct iwl_lq_sta *lq_sta = &mvmsta->lq_sta.rs_drv; struct ieee80211_supported_band *sband; @@ -2953,7 +2954,7 @@ static void rs_drv_rate_init(struct iwl_mvm *mvm, struct ieee80211_sta *sta, /* * active legacy rates as per supported rates bitmap */ - supp = sta->supp_rates[sband->band]; + supp = sta->deflink.supp_rates[sband->band]; lq_sta->active_legacy_rate = 0; for_each_set_bit(i, &supp, BITS_PER_LONG) lq_sta->active_legacy_rate |= BIT(sband->bitrates[i].hw_value); @@ -3246,7 +3247,7 @@ static void __iwl_mvm_rs_tx_status(struct iwl_mvm *mvm, IWL_DEBUG_RATE(mvm, "reduced txpower: %d\n", reduced_txp); done: /* See if there's a better rate or modulation mode to try. */ - if (sta->supp_rates[info->band]) + if (sta->deflink.supp_rates[info->band]) rs_rate_scale_perform(mvm, sta, lq_sta, tid, ndp); } diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/sf.c b/drivers/net/wireless/intel/iwlwifi/mvm/sf.c index 655da8856c752..693752d8f65b5 100644 --- a/drivers/net/wireless/intel/iwlwifi/mvm/sf.c +++ b/drivers/net/wireless/intel/iwlwifi/mvm/sf.c @@ -106,10 +106,10 @@ static void iwl_mvm_fill_sf_command(struct iwl_mvm *mvm, * capabilities of the AP station, and choose the watermark accordingly. */ if (sta) { - if (sta->ht_cap.ht_supported || - sta->vht_cap.vht_supported || - sta->he_cap.has_he) { - switch (sta->rx_nss) { + if (sta->deflink.ht_cap.ht_supported || + sta->deflink.vht_cap.vht_supported || + sta->deflink.he_cap.has_he) { + switch (sta->deflink.rx_nss) { case 1: watermark = SF_W_MARK_SISO; break; diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/sta.c b/drivers/net/wireless/intel/iwlwifi/mvm/sta.c index c7f9d3870f218..406f0a50a5bf2 100644 --- a/drivers/net/wireless/intel/iwlwifi/mvm/sta.c +++ b/drivers/net/wireless/intel/iwlwifi/mvm/sta.c @@ -86,7 +86,7 @@ int iwl_mvm_sta_send_to_fw(struct iwl_mvm *mvm, struct ieee80211_sta *sta, } } - switch (sta->bandwidth) { + switch (sta->deflink.bandwidth) { case IEEE80211_STA_RX_BW_320: case IEEE80211_STA_RX_BW_160: add_sta_cmd.station_flags |= cpu_to_le32(STA_FLG_FAT_EN_160MHZ); @@ -98,13 +98,13 @@ int iwl_mvm_sta_send_to_fw(struct iwl_mvm *mvm, struct ieee80211_sta *sta, add_sta_cmd.station_flags |= cpu_to_le32(STA_FLG_FAT_EN_40MHZ); fallthrough; case IEEE80211_STA_RX_BW_20: - if (sta->ht_cap.ht_supported) + if (sta->deflink.ht_cap.ht_supported) add_sta_cmd.station_flags |= cpu_to_le32(STA_FLG_FAT_EN_20MHZ); break; } - switch (sta->rx_nss) { + switch (sta->deflink.rx_nss) { case 1: add_sta_cmd.station_flags |= cpu_to_le32(STA_FLG_MIMO_EN_SISO); break; @@ -134,12 +134,12 @@ int iwl_mvm_sta_send_to_fw(struct iwl_mvm *mvm, struct ieee80211_sta *sta, break; } - if (sta->ht_cap.ht_supported) { + if (sta->deflink.ht_cap.ht_supported) { add_sta_cmd.station_flags_msk |= cpu_to_le32(STA_FLG_MAX_AGG_SIZE_MSK | STA_FLG_AGG_MPDU_DENS_MSK); - mpdu_dens = sta->ht_cap.ampdu_density; + mpdu_dens = sta->deflink.ht_cap.ampdu_density; } if (mvm_sta->vif->bss_conf.chandef.chan->band == NL80211_BAND_6GHZ) { @@ -147,18 +147,17 @@ int iwl_mvm_sta_send_to_fw(struct iwl_mvm *mvm, struct ieee80211_sta *sta, cpu_to_le32(STA_FLG_MAX_AGG_SIZE_MSK | STA_FLG_AGG_MPDU_DENS_MSK); - mpdu_dens = le16_get_bits(sta->he_6ghz_capa.capa, + mpdu_dens = le16_get_bits(sta->deflink.he_6ghz_capa.capa, IEEE80211_HE_6GHZ_CAP_MIN_MPDU_START); - agg_size = le16_get_bits(sta->he_6ghz_capa.capa, - IEEE80211_HE_6GHZ_CAP_MAX_AMPDU_LEN_EXP); - } else - if (sta->vht_cap.vht_supported) { - agg_size = sta->vht_cap.cap & + agg_size = le16_get_bits(sta->deflink.he_6ghz_capa.capa, + IEEE80211_HE_6GHZ_CAP_MAX_AMPDU_LEN_EXP); + } else if (sta->deflink.vht_cap.vht_supported) { + agg_size = sta->deflink.vht_cap.cap & IEEE80211_VHT_CAP_MAX_A_MPDU_LENGTH_EXPONENT_MASK; agg_size >>= IEEE80211_VHT_CAP_MAX_A_MPDU_LENGTH_EXPONENT_SHIFT; - } else if (sta->ht_cap.ht_supported) { - agg_size = sta->ht_cap.ampdu_factor; + } else if (sta->deflink.ht_cap.ht_supported) { + agg_size = sta->deflink.ht_cap.ampdu_factor; } /* D6.0 10.12.2 A-MPDU length limit rules @@ -169,8 +168,8 @@ int iwl_mvm_sta_send_to_fw(struct iwl_mvm *mvm, struct ieee80211_sta *sta, * Maximum AMPDU Length Exponent Extension field in its HE * Capabilities element */ - if (sta->he_cap.has_he) - agg_size += u8_get_bits(sta->he_cap.he_cap_elem.mac_cap_info[3], + if (sta->deflink.he_cap.has_he) + agg_size += u8_get_bits(sta->deflink.he_cap.he_cap_elem.mac_cap_info[3], IEEE80211_HE_MAC_CAP3_MAX_AMPDU_LEN_EXP_MASK); /* Limit to max A-MPDU supported by FW */ @@ -782,7 +781,7 @@ static int iwl_mvm_tvqm_enable_txq(struct iwl_mvm *mvm, /* this queue isn't used for traffic (cab_queue) */ if (IS_ERR_OR_NULL(sta)) { size = IWL_MGMT_QUEUE_SIZE; - } else if (sta->he_cap.has_he) { + } else if (sta->deflink.he_cap.has_he) { /* support for 256 ba size */ size = IWL_DEFAULT_QUEUE_SIZE_HE; } else { diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/tx.c b/drivers/net/wireless/intel/iwlwifi/mvm/tx.c index 7763037b93edb..8125bb76f59e8 100644 --- a/drivers/net/wireless/intel/iwlwifi/mvm/tx.c +++ b/drivers/net/wireless/intel/iwlwifi/mvm/tx.c @@ -794,7 +794,7 @@ unsigned int iwl_mvm_max_amsdu_size(struct iwl_mvm *mvm, int lmac = iwl_mvm_get_lmac_id(mvm->fw, band); /* For HE redirect to trigger based fifos */ - if (sta->he_cap.has_he && !WARN_ON(!iwl_mvm_has_new_tx_api(mvm))) + if (sta->deflink.he_cap.has_he && !WARN_ON(!iwl_mvm_has_new_tx_api(mvm))) ac += 4; txf = iwl_mvm_mac_ac_to_tx_fifo(mvm, ac); @@ -935,7 +935,7 @@ static int iwl_mvm_tx_tso(struct iwl_mvm *mvm, struct sk_buff *skb, * section 8.7.3 NOTE 3). */ if (info->flags & IEEE80211_TX_CTL_AMPDU && - !sta->vht_cap.vht_supported) + !sta->deflink.vht_cap.vht_supported) max_amsdu_len = min_t(unsigned int, max_amsdu_len, 4095); /* Sub frame header + SNAP + IP header + TCP header + MSS */ @@ -1083,7 +1083,7 @@ static int iwl_mvm_tx_mpdu(struct iwl_mvm *mvm, struct sk_buff *skb, if (WARN_ON_ONCE(mvmsta->sta_id == IWL_MVM_INVALID_STA)) return -1; - if (unlikely(ieee80211_is_any_nullfunc(fc)) && sta->he_cap.has_he) + if (unlikely(ieee80211_is_any_nullfunc(fc)) && sta->deflink.he_cap.has_he) return -1; if (unlikely(ieee80211_is_probe_resp(fc))) diff --git a/drivers/net/wireless/mac80211_hwsim.c b/drivers/net/wireless/mac80211_hwsim.c index 28bfa7b7b73c0..afdf485505887 100644 --- a/drivers/net/wireless/mac80211_hwsim.c +++ b/drivers/net/wireless/mac80211_hwsim.c @@ -2189,7 +2189,7 @@ mac80211_hwsim_sta_rc_update(struct ieee80211_hw *hw, u32 bw = U32_MAX; enum nl80211_chan_width confbw = NL80211_CHAN_WIDTH_20_NOHT; - switch (sta->bandwidth) { + switch (sta->deflink.bandwidth) { #define C(_bw) case IEEE80211_STA_RX_BW_##_bw: bw = _bw; break C(20); C(40); @@ -2211,7 +2211,7 @@ mac80211_hwsim_sta_rc_update(struct ieee80211_hw *hw, WARN(bw > hwsim_get_chanwidth(confbw), "intf %pM: bad STA %pM bandwidth %d MHz (%d) > channel config %d MHz (%d)\n", - vif->addr, sta->addr, bw, sta->bandwidth, + vif->addr, sta->addr, bw, sta->deflink.bandwidth, hwsim_get_chanwidth(data->bw), data->bw); } diff --git a/drivers/net/wireless/marvell/mwl8k.c b/drivers/net/wireless/marvell/mwl8k.c index 864a2ba9efeeb..36c24d17136ce 100644 --- a/drivers/net/wireless/marvell/mwl8k.c +++ b/drivers/net/wireless/marvell/mwl8k.c @@ -1985,7 +1985,7 @@ mwl8k_txq_xmit(struct ieee80211_hw *hw, txpriority = index; - if (priv->ap_fw && sta && sta->ht_cap.ht_supported && !eapol_frame && + if (priv->ap_fw && sta && sta->deflink.ht_cap.ht_supported && !eapol_frame && ieee80211_is_data_qos(wh->frame_control)) { tid = qos & 0xf; mwl8k_tx_count_packet(sta, tid); @@ -4027,9 +4027,9 @@ mwl8k_create_ba(struct ieee80211_hw *hw, struct mwl8k_ampdu_stream *stream, cmd->create_params.reset_seq_no_flag = 1; cmd->create_params.param_info = - (stream->sta->ht_cap.ampdu_factor & + (stream->sta->deflink.ht_cap.ampdu_factor & IEEE80211_HT_AMPDU_PARM_FACTOR) | - ((stream->sta->ht_cap.ampdu_density << 2) & + ((stream->sta->deflink.ht_cap.ampdu_density << 2) & IEEE80211_HT_AMPDU_PARM_DENSITY); cmd->create_params.flags = @@ -4113,18 +4113,18 @@ static int mwl8k_cmd_set_new_stn_add(struct ieee80211_hw *hw, cmd->stn_id = cpu_to_le16(sta->aid); cmd->action = cpu_to_le16(MWL8K_STA_ACTION_ADD); if (hw->conf.chandef.chan->band == NL80211_BAND_2GHZ) - rates = sta->supp_rates[NL80211_BAND_2GHZ]; + rates = sta->deflink.supp_rates[NL80211_BAND_2GHZ]; else - rates = sta->supp_rates[NL80211_BAND_5GHZ] << 5; + rates = sta->deflink.supp_rates[NL80211_BAND_5GHZ] << 5; cmd->legacy_rates = cpu_to_le32(rates); - if (sta->ht_cap.ht_supported) { - cmd->ht_rates[0] = sta->ht_cap.mcs.rx_mask[0]; - cmd->ht_rates[1] = sta->ht_cap.mcs.rx_mask[1]; - cmd->ht_rates[2] = sta->ht_cap.mcs.rx_mask[2]; - cmd->ht_rates[3] = sta->ht_cap.mcs.rx_mask[3]; - cmd->ht_capabilities_info = cpu_to_le16(sta->ht_cap.cap); - cmd->mac_ht_param_info = (sta->ht_cap.ampdu_factor & 3) | - ((sta->ht_cap.ampdu_density & 7) << 2); + if (sta->deflink.ht_cap.ht_supported) { + cmd->ht_rates[0] = sta->deflink.ht_cap.mcs.rx_mask[0]; + cmd->ht_rates[1] = sta->deflink.ht_cap.mcs.rx_mask[1]; + cmd->ht_rates[2] = sta->deflink.ht_cap.mcs.rx_mask[2]; + cmd->ht_rates[3] = sta->deflink.ht_cap.mcs.rx_mask[3]; + cmd->ht_capabilities_info = cpu_to_le16(sta->deflink.ht_cap.cap); + cmd->mac_ht_param_info = (sta->deflink.ht_cap.ampdu_factor & 3) | + ((sta->deflink.ht_cap.ampdu_density & 7) << 2); cmd->is_qos_sta = 1; } @@ -4545,16 +4545,16 @@ static int mwl8k_cmd_update_stadb_add(struct ieee80211_hw *hw, p = &cmd->peer_info; p->peer_type = MWL8K_PEER_TYPE_ACCESSPOINT; p->basic_caps = cpu_to_le16(vif->bss_conf.assoc_capability); - p->ht_support = sta->ht_cap.ht_supported; - p->ht_caps = cpu_to_le16(sta->ht_cap.cap); - p->extended_ht_caps = (sta->ht_cap.ampdu_factor & 3) | - ((sta->ht_cap.ampdu_density & 7) << 2); + p->ht_support = sta->deflink.ht_cap.ht_supported; + p->ht_caps = cpu_to_le16(sta->deflink.ht_cap.cap); + p->extended_ht_caps = (sta->deflink.ht_cap.ampdu_factor & 3) | + ((sta->deflink.ht_cap.ampdu_density & 7) << 2); if (hw->conf.chandef.chan->band == NL80211_BAND_2GHZ) - rates = sta->supp_rates[NL80211_BAND_2GHZ]; + rates = sta->deflink.supp_rates[NL80211_BAND_2GHZ]; else - rates = sta->supp_rates[NL80211_BAND_5GHZ] << 5; + rates = sta->deflink.supp_rates[NL80211_BAND_5GHZ] << 5; legacy_rate_mask_to_array(p->legacy_rates, rates); - memcpy(p->ht_rates, &sta->ht_cap.mcs, 16); + memcpy(p->ht_rates, &sta->deflink.ht_cap.mcs, 16); p->interop = 1; p->amsdu_enabled = 0; @@ -5031,12 +5031,12 @@ mwl8k_bss_info_changed_sta(struct ieee80211_hw *hw, struct ieee80211_vif *vif, } if (hw->conf.chandef.chan->band == NL80211_BAND_2GHZ) { - ap_legacy_rates = ap->supp_rates[NL80211_BAND_2GHZ]; + ap_legacy_rates = ap->deflink.supp_rates[NL80211_BAND_2GHZ]; } else { ap_legacy_rates = - ap->supp_rates[NL80211_BAND_5GHZ] << 5; + ap->deflink.supp_rates[NL80211_BAND_5GHZ] << 5; } - memcpy(ap_mcs_rates, &ap->ht_cap.mcs, 16); + memcpy(ap_mcs_rates, &ap->deflink.ht_cap.mcs, 16); rcu_read_unlock(); @@ -5347,7 +5347,7 @@ static int mwl8k_sta_add(struct ieee80211_hw *hw, ret = mwl8k_cmd_update_stadb_add(hw, vif, sta); if (ret >= 0) { MWL8K_STA(sta)->peer_id = ret; - if (sta->ht_cap.ht_supported) + if (sta->deflink.ht_cap.ht_supported) MWL8K_STA(sta)->is_ampdu_allowed = true; ret = 0; } diff --git a/drivers/net/wireless/mediatek/mt76/mt7603/mac.c b/drivers/net/wireless/mediatek/mt76/mt7603/mac.c index 17713c821d808..49a511ae8161d 100644 --- a/drivers/net/wireless/mediatek/mt76/mt7603/mac.c +++ b/drivers/net/wireless/mediatek/mt76/mt7603/mac.c @@ -326,19 +326,21 @@ void mt7603_wtbl_update_cap(struct mt7603_dev *dev, struct ieee80211_sta *sta) addr = mt7603_wtbl1_addr(idx); - ampdu_density = sta->ht_cap.ampdu_density; + ampdu_density = sta->deflink.ht_cap.ampdu_density; if (ampdu_density < IEEE80211_HT_MPDU_DENSITY_4) ampdu_density = IEEE80211_HT_MPDU_DENSITY_4; val = mt76_rr(dev, addr + 2 * 4); val &= MT_WTBL1_W2_KEY_TYPE | MT_WTBL1_W2_ADMISSION_CONTROL; - val |= FIELD_PREP(MT_WTBL1_W2_AMPDU_FACTOR, sta->ht_cap.ampdu_factor) | - FIELD_PREP(MT_WTBL1_W2_MPDU_DENSITY, sta->ht_cap.ampdu_density) | + val |= FIELD_PREP(MT_WTBL1_W2_AMPDU_FACTOR, + sta->deflink.ht_cap.ampdu_factor) | + FIELD_PREP(MT_WTBL1_W2_MPDU_DENSITY, + sta->deflink.ht_cap.ampdu_density) | MT_WTBL1_W2_TXS_BAF_REPORT; - if (sta->ht_cap.cap) + if (sta->deflink.ht_cap.cap) val |= MT_WTBL1_W2_HT; - if (sta->vht_cap.cap) + if (sta->deflink.vht_cap.cap) val |= MT_WTBL1_W2_VHT; mt76_wr(dev, addr + 2 * 4, val); @@ -347,9 +349,9 @@ void mt7603_wtbl_update_cap(struct mt7603_dev *dev, struct ieee80211_sta *sta) val = mt76_rr(dev, addr + 9 * 4); val &= ~(MT_WTBL2_W9_SHORT_GI_20 | MT_WTBL2_W9_SHORT_GI_40 | MT_WTBL2_W9_SHORT_GI_80); - if (sta->ht_cap.cap & IEEE80211_HT_CAP_SGI_20) + if (sta->deflink.ht_cap.cap & IEEE80211_HT_CAP_SGI_20) val |= MT_WTBL2_W9_SHORT_GI_20; - if (sta->ht_cap.cap & IEEE80211_HT_CAP_SGI_40) + if (sta->deflink.ht_cap.cap & IEEE80211_HT_CAP_SGI_40) val |= MT_WTBL2_W9_SHORT_GI_40; mt76_wr(dev, addr + 9 * 4, val); } diff --git a/drivers/net/wireless/mediatek/mt76/mt76_connac_mcu.c b/drivers/net/wireless/mediatek/mt76/mt76_connac_mcu.c index 7cb17bf40e35a..51a9b5d60c7a8 100644 --- a/drivers/net/wireless/mediatek/mt76/mt76_connac_mcu.c +++ b/drivers/net/wireless/mediatek/mt76/mt76_connac_mcu.c @@ -610,7 +610,7 @@ mt76_connac_mcu_sta_amsdu_tlv(struct sk_buff *skb, struct ieee80211_sta *sta, static void mt76_connac_mcu_sta_he_tlv(struct sk_buff *skb, struct ieee80211_sta *sta) { - struct ieee80211_sta_he_cap *he_cap = &sta->he_cap; + struct ieee80211_sta_he_cap *he_cap = &sta->deflink.he_cap; struct ieee80211_he_cap_elem *elem = &he_cap->he_cap_elem; struct sta_rec_he *he; struct tlv *tlv; @@ -698,7 +698,7 @@ mt76_connac_mcu_sta_he_tlv(struct sk_buff *skb, struct ieee80211_sta *sta) he->he_cap = cpu_to_le32(cap); - switch (sta->bandwidth) { + switch (sta->deflink.bandwidth) { case IEEE80211_STA_RX_BW_160: if (elem->phy_cap_info[0] & IEEE80211_HE_PHY_CAP0_CHANNEL_WIDTH_SET_80PLUS80_MHZ_IN_5G) @@ -750,9 +750,9 @@ mt76_connac_get_phy_mode_v2(struct mt76_phy *mphy, struct ieee80211_vif *vif, u8 mode = 0; if (sta) { - ht_cap = &sta->ht_cap; - vht_cap = &sta->vht_cap; - he_cap = &sta->he_cap; + ht_cap = &sta->deflink.ht_cap; + vht_cap = &sta->deflink.vht_cap; + he_cap = &sta->deflink.he_cap; } else { struct ieee80211_supported_band *sband; @@ -801,25 +801,25 @@ void mt76_connac_mcu_sta_tlv(struct mt76_phy *mphy, struct sk_buff *skb, u16 supp_rates; /* starec ht */ - if (sta->ht_cap.ht_supported) { + if (sta->deflink.ht_cap.ht_supported) { struct sta_rec_ht *ht; tlv = mt76_connac_mcu_add_tlv(skb, STA_REC_HT, sizeof(*ht)); ht = (struct sta_rec_ht *)tlv; - ht->ht_cap = cpu_to_le16(sta->ht_cap.cap); + ht->ht_cap = cpu_to_le16(sta->deflink.ht_cap.cap); } /* starec vht */ - if (sta->vht_cap.vht_supported) { + if (sta->deflink.vht_cap.vht_supported) { struct sta_rec_vht *vht; int len; len = is_mt7921(dev) ? sizeof(*vht) : sizeof(*vht) - 4; tlv = mt76_connac_mcu_add_tlv(skb, STA_REC_VHT, len); vht = (struct sta_rec_vht *)tlv; - vht->vht_cap = cpu_to_le32(sta->vht_cap.cap); - vht->vht_rx_mcs_map = sta->vht_cap.vht_mcs.rx_mcs_map; - vht->vht_tx_mcs_map = sta->vht_cap.vht_mcs.tx_mcs_map; + vht->vht_cap = cpu_to_le32(sta->deflink.vht_cap.cap); + vht->vht_rx_mcs_map = sta->deflink.vht_cap.vht_mcs.rx_mcs_map; + vht->vht_tx_mcs_map = sta->deflink.vht_cap.vht_mcs.tx_mcs_map; } /* starec uapsd */ @@ -828,11 +828,11 @@ void mt76_connac_mcu_sta_tlv(struct mt76_phy *mphy, struct sk_buff *skb, if (!is_mt7921(dev)) return; - if (sta->ht_cap.ht_supported || sta->he_cap.has_he) + if (sta->deflink.ht_cap.ht_supported || sta->deflink.he_cap.has_he) mt76_connac_mcu_sta_amsdu_tlv(skb, sta, vif); /* starec he */ - if (sta->he_cap.has_he) { + if (sta->deflink.he_cap.has_he) { mt76_connac_mcu_sta_he_tlv(skb, sta); if (band == NL80211_BAND_6GHZ && sta_state == MT76_STA_INFO_STATE_ASSOC) { @@ -841,7 +841,7 @@ void mt76_connac_mcu_sta_tlv(struct mt76_phy *mphy, struct sk_buff *skb, tlv = mt76_connac_mcu_add_tlv(skb, STA_REC_HE_6G, sizeof(*he_6g_capa)); he_6g_capa = (struct sta_rec_he_6g_capa *)tlv; - he_6g_capa->capa = sta->he_6ghz_capa.capa; + he_6g_capa->capa = sta->deflink.he_6ghz_capa.capa; } } @@ -851,14 +851,14 @@ void mt76_connac_mcu_sta_tlv(struct mt76_phy *mphy, struct sk_buff *skb, phy->basic_rate = cpu_to_le16((u16)vif->bss_conf.basic_rates); phy->rcpi = rcpi; phy->ampdu = FIELD_PREP(IEEE80211_HT_AMPDU_PARM_FACTOR, - sta->ht_cap.ampdu_factor) | + sta->deflink.ht_cap.ampdu_factor) | FIELD_PREP(IEEE80211_HT_AMPDU_PARM_DENSITY, - sta->ht_cap.ampdu_density); + sta->deflink.ht_cap.ampdu_density); tlv = mt76_connac_mcu_add_tlv(skb, STA_REC_RA, sizeof(*ra_info)); ra_info = (struct sta_rec_ra_info *)tlv; - supp_rates = sta->supp_rates[band]; + supp_rates = sta->deflink.supp_rates[band]; if (band == NL80211_BAND_2GHZ) supp_rates = FIELD_PREP(RA_LEGACY_OFDM, supp_rates >> 4) | FIELD_PREP(RA_LEGACY_CCK, supp_rates & 0xf); @@ -867,17 +867,18 @@ void mt76_connac_mcu_sta_tlv(struct mt76_phy *mphy, struct sk_buff *skb, ra_info->legacy = cpu_to_le16(supp_rates); - if (sta->ht_cap.ht_supported) - memcpy(ra_info->rx_mcs_bitmask, sta->ht_cap.mcs.rx_mask, + if (sta->deflink.ht_cap.ht_supported) + memcpy(ra_info->rx_mcs_bitmask, + sta->deflink.ht_cap.mcs.rx_mask, HT_MCS_MASK_NUM); tlv = mt76_connac_mcu_add_tlv(skb, STA_REC_STATE, sizeof(*state)); state = (struct sta_rec_state *)tlv; state->state = sta_state; - if (sta->vht_cap.vht_supported) { - state->vht_opmode = sta->bandwidth; - state->vht_opmode |= (sta->rx_nss - 1) << + if (sta->deflink.vht_cap.vht_supported) { + state->vht_opmode = sta->deflink.bandwidth; + state->vht_opmode |= (sta->deflink.rx_nss - 1) << IEEE80211_OPMODE_NOTIF_RX_NSS_SHIFT; } } @@ -905,27 +906,27 @@ void mt76_connac_mcu_wtbl_ht_tlv(struct mt76_dev *dev, struct sk_buff *skb, struct tlv *tlv; u32 flags = 0; - if (sta->ht_cap.ht_supported || sta->he_6ghz_capa.capa) { + if (sta->deflink.ht_cap.ht_supported || sta->deflink.he_6ghz_capa.capa) { tlv = mt76_connac_mcu_add_nested_tlv(skb, WTBL_HT, sizeof(*ht), wtbl_tlv, sta_wtbl); ht = (struct wtbl_ht *)tlv; ht->ldpc = ht_ldpc && - !!(sta->ht_cap.cap & IEEE80211_HT_CAP_LDPC_CODING); + !!(sta->deflink.ht_cap.cap & IEEE80211_HT_CAP_LDPC_CODING); - if (sta->ht_cap.ht_supported) { - ht->af = sta->ht_cap.ampdu_factor; - ht->mm = sta->ht_cap.ampdu_density; + if (sta->deflink.ht_cap.ht_supported) { + ht->af = sta->deflink.ht_cap.ampdu_factor; + ht->mm = sta->deflink.ht_cap.ampdu_density; } else { - ht->af = le16_get_bits(sta->he_6ghz_capa.capa, + ht->af = le16_get_bits(sta->deflink.he_6ghz_capa.capa, IEEE80211_HE_6GHZ_CAP_MAX_AMPDU_LEN_EXP); - ht->mm = le16_get_bits(sta->he_6ghz_capa.capa, + ht->mm = le16_get_bits(sta->deflink.he_6ghz_capa.capa, IEEE80211_HE_6GHZ_CAP_MIN_MPDU_START); } ht->ht = true; } - if (sta->vht_cap.vht_supported || sta->he_6ghz_capa.capa) { + if (sta->deflink.vht_cap.vht_supported || sta->deflink.he_6ghz_capa.capa) { struct wtbl_vht *vht; u8 af; @@ -934,18 +935,18 @@ void mt76_connac_mcu_wtbl_ht_tlv(struct mt76_dev *dev, struct sk_buff *skb, sta_wtbl); vht = (struct wtbl_vht *)tlv; vht->ldpc = vht_ldpc && - !!(sta->vht_cap.cap & IEEE80211_VHT_CAP_RXLDPC); + !!(sta->deflink.vht_cap.cap & IEEE80211_VHT_CAP_RXLDPC); vht->vht = true; af = FIELD_GET(IEEE80211_VHT_CAP_MAX_A_MPDU_LENGTH_EXPONENT_MASK, - sta->vht_cap.cap); + sta->deflink.vht_cap.cap); if (ht) ht->af = max(ht->af, af); } mt76_connac_mcu_wtbl_smps_tlv(skb, sta, sta_wtbl, wtbl_tlv); - if (is_connac_v1(dev) && sta->ht_cap.ht_supported) { + if (is_connac_v1(dev) && sta->deflink.ht_cap.ht_supported) { /* sgi */ u32 msk = MT_WTBL_W5_SHORT_GI_20 | MT_WTBL_W5_SHORT_GI_40 | MT_WTBL_W5_SHORT_GI_80 | MT_WTBL_W5_SHORT_GI_160; @@ -955,15 +956,15 @@ void mt76_connac_mcu_wtbl_ht_tlv(struct mt76_dev *dev, struct sk_buff *skb, sizeof(*raw), wtbl_tlv, sta_wtbl); - if (sta->ht_cap.cap & IEEE80211_HT_CAP_SGI_20) + if (sta->deflink.ht_cap.cap & IEEE80211_HT_CAP_SGI_20) flags |= MT_WTBL_W5_SHORT_GI_20; - if (sta->ht_cap.cap & IEEE80211_HT_CAP_SGI_40) + if (sta->deflink.ht_cap.cap & IEEE80211_HT_CAP_SGI_40) flags |= MT_WTBL_W5_SHORT_GI_40; - if (sta->vht_cap.vht_supported) { - if (sta->vht_cap.cap & IEEE80211_VHT_CAP_SHORT_GI_80) + if (sta->deflink.vht_cap.vht_supported) { + if (sta->deflink.vht_cap.cap & IEEE80211_VHT_CAP_SHORT_GI_80) flags |= MT_WTBL_W5_SHORT_GI_80; - if (sta->vht_cap.cap & IEEE80211_VHT_CAP_SHORT_GI_160) + if (sta->deflink.vht_cap.cap & IEEE80211_VHT_CAP_SHORT_GI_160) flags |= MT_WTBL_W5_SHORT_GI_160; } raw = (struct wtbl_raw *)tlv; @@ -1231,9 +1232,9 @@ u8 mt76_connac_get_phy_mode(struct mt76_phy *phy, struct ieee80211_vif *vif, return 0x38; if (sta) { - ht_cap = &sta->ht_cap; - vht_cap = &sta->vht_cap; - he_cap = &sta->he_cap; + ht_cap = &sta->deflink.ht_cap; + vht_cap = &sta->deflink.vht_cap; + he_cap = &sta->deflink.he_cap; } else { struct ieee80211_supported_band *sband; diff --git a/drivers/net/wireless/mediatek/mt76/mt76x02_mac.c b/drivers/net/wireless/mediatek/mt76/mt76x02_mac.c index 2afad8c76ca6b..cf4d4110cc99b 100644 --- a/drivers/net/wireless/mediatek/mt76/mt76x02_mac.c +++ b/drivers/net/wireless/mediatek/mt76/mt76x02_mac.c @@ -412,9 +412,9 @@ void mt76x02_mac_write_txwi(struct mt76x02_dev *dev, struct mt76x02_txwi *txwi, txwi->ack_ctl |= MT_TXWI_ACK_CTL_NSEQ; if ((info->flags & IEEE80211_TX_CTL_AMPDU) && sta) { u8 ba_size = IEEE80211_MIN_AMPDU_BUF; - u8 ampdu_density = sta->ht_cap.ampdu_density; + u8 ampdu_density = sta->deflink.ht_cap.ampdu_density; - ba_size <<= sta->ht_cap.ampdu_factor; + ba_size <<= sta->deflink.ht_cap.ampdu_factor; ba_size = min_t(int, 63, ba_size - 1); if (info->flags & IEEE80211_TX_CTL_RATE_CTRL_PROBE) ba_size = 0; diff --git a/drivers/net/wireless/mediatek/mt76/mt7915/debugfs.c b/drivers/net/wireless/mediatek/mt76/mt7915/debugfs.c index 4e1ecaec8f4fb..e9cab1165f38e 100644 --- a/drivers/net/wireless/mediatek/mt76/mt7915/debugfs.c +++ b/drivers/net/wireless/mediatek/mt76/mt7915/debugfs.c @@ -1017,8 +1017,8 @@ static ssize_t mt7915_sta_fixed_rate_set(struct file *file, phy.ldpc = (phy.bw || phy.ldpc) * GENMASK(2, 0); for (i = 0; i <= phy.bw; i++) { - phy.sgi |= gi << (i << sta->he_cap.has_he); - phy.he_ltf |= he_ltf << (i << sta->he_cap.has_he); + phy.sgi |= gi << (i << sta->deflink.he_cap.has_he); + phy.he_ltf |= he_ltf << (i << sta->deflink.he_cap.has_he); } field = RATE_PARAM_FIXED; diff --git a/drivers/net/wireless/mediatek/mt76/mt7915/mac.c b/drivers/net/wireless/mediatek/mt76/mt7915/mac.c index e9e7efbf350d5..bab70cf981bb2 100644 --- a/drivers/net/wireless/mediatek/mt76/mt7915/mac.c +++ b/drivers/net/wireless/mediatek/mt76/mt7915/mac.c @@ -1354,7 +1354,7 @@ mt7915_tx_check_aggr(struct ieee80211_sta *sta, __le32 *txwi) u16 fc, tid; u32 val; - if (!sta || !(sta->ht_cap.ht_supported || sta->he_cap.has_he)) + if (!sta || !(sta->deflink.ht_cap.ht_supported || sta->deflink.he_cap.has_he)) return; tid = le32_get_bits(txwi[1], MT_TXD1_TID); diff --git a/drivers/net/wireless/mediatek/mt76/mt7915/mcu.c b/drivers/net/wireless/mediatek/mt76/mt7915/mcu.c index e7a6f80e77551..df31084e860f4 100644 --- a/drivers/net/wireless/mediatek/mt76/mt7915/mcu.c +++ b/drivers/net/wireless/mediatek/mt76/mt7915/mcu.c @@ -112,7 +112,7 @@ mt7915_mcu_set_sta_he_mcs(struct ieee80211_sta *sta, __le16 *he_mcs, struct mt7915_dev *dev = msta->vif->phy->dev; enum nl80211_band band = msta->vif->phy->mt76->chandef.chan->band; const u16 *mask = msta->vif->bitrate_mask.control[band].he_mcs; - int nss, max_nss = sta->rx_nss > 3 ? 4 : sta->rx_nss; + int nss, max_nss = sta->deflink.rx_nss > 3 ? 4 : sta->deflink.rx_nss; for (nss = 0; nss < max_nss; nss++) { int mcs; @@ -152,7 +152,7 @@ mt7915_mcu_set_sta_he_mcs(struct ieee80211_sta *sta, __le16 *he_mcs, /* only support 2ss on 160MHz for mt7915 */ if (is_mt7915(&dev->mt76) && nss > 1 && - sta->bandwidth == IEEE80211_STA_RX_BW_160) + sta->deflink.bandwidth == IEEE80211_STA_RX_BW_160) break; } @@ -165,8 +165,8 @@ mt7915_mcu_set_sta_vht_mcs(struct ieee80211_sta *sta, __le16 *vht_mcs, { struct mt7915_sta *msta = (struct mt7915_sta *)sta->drv_priv; struct mt7915_dev *dev = msta->vif->phy->dev; - u16 mcs_map = le16_to_cpu(sta->vht_cap.vht_mcs.rx_mcs_map); - int nss, max_nss = sta->rx_nss > 3 ? 4 : sta->rx_nss; + u16 mcs_map = le16_to_cpu(sta->deflink.vht_cap.vht_mcs.rx_mcs_map); + int nss, max_nss = sta->deflink.rx_nss > 3 ? 4 : sta->deflink.rx_nss; u16 mcs; for (nss = 0; nss < max_nss; nss++, mcs_map >>= 2) { @@ -188,7 +188,7 @@ mt7915_mcu_set_sta_vht_mcs(struct ieee80211_sta *sta, __le16 *vht_mcs, /* only support 2ss on 160MHz for mt7915 */ if (is_mt7915(&dev->mt76) && nss > 1 && - sta->bandwidth == IEEE80211_STA_RX_BW_160) + sta->deflink.bandwidth == IEEE80211_STA_RX_BW_160) break; } } @@ -197,10 +197,10 @@ static void mt7915_mcu_set_sta_ht_mcs(struct ieee80211_sta *sta, u8 *ht_mcs, const u8 *mask) { - int nss, max_nss = sta->rx_nss > 3 ? 4 : sta->rx_nss; + int nss, max_nss = sta->deflink.rx_nss > 3 ? 4 : sta->deflink.rx_nss; for (nss = 0; nss < max_nss; nss++) - ht_mcs[nss] = sta->ht_cap.mcs.rx_mask[nss] & mask[nss]; + ht_mcs[nss] = sta->deflink.ht_cap.mcs.rx_mask[nss] & mask[nss]; } static int @@ -788,13 +788,13 @@ mt7915_mcu_sta_he_tlv(struct sk_buff *skb, struct ieee80211_sta *sta, struct ieee80211_vif *vif) { struct mt7915_vif *mvif = (struct mt7915_vif *)vif->drv_priv; - struct ieee80211_he_cap_elem *elem = &sta->he_cap.he_cap_elem; + struct ieee80211_he_cap_elem *elem = &sta->deflink.he_cap.he_cap_elem; struct ieee80211_he_mcs_nss_supp mcs_map; struct sta_rec_he *he; struct tlv *tlv; u32 cap = 0; - if (!sta->he_cap.has_he) + if (!sta->deflink.he_cap.has_he) return; tlv = mt76_connac_mcu_add_tlv(skb, STA_REC_HE, sizeof(*he)); @@ -880,8 +880,8 @@ mt7915_mcu_sta_he_tlv(struct sk_buff *skb, struct ieee80211_sta *sta, he->he_cap = cpu_to_le32(cap); - mcs_map = sta->he_cap.he_mcs_nss_supp; - switch (sta->bandwidth) { + mcs_map = sta->deflink.he_cap.he_mcs_nss_supp; + switch (sta->deflink.bandwidth) { case IEEE80211_STA_RX_BW_160: if (elem->phy_cap_info[0] & IEEE80211_HE_PHY_CAP0_CHANNEL_WIDTH_SET_80PLUS80_MHZ_IN_5G) @@ -931,7 +931,7 @@ mt7915_mcu_sta_muru_tlv(struct sk_buff *skb, struct ieee80211_sta *sta, struct ieee80211_vif *vif) { struct mt7915_vif *mvif = (struct mt7915_vif *)vif->drv_priv; - struct ieee80211_he_cap_elem *elem = &sta->he_cap.he_cap_elem; + struct ieee80211_he_cap_elem *elem = &sta->deflink.he_cap.he_cap_elem; struct sta_rec_muru *muru; struct tlv *tlv; @@ -949,11 +949,11 @@ mt7915_mcu_sta_muru_tlv(struct sk_buff *skb, struct ieee80211_sta *sta, muru->cfg.mimo_ul_en = true; muru->cfg.ofdma_dl_en = true; - if (sta->vht_cap.vht_supported) + if (sta->deflink.vht_cap.vht_supported) muru->mimo_dl.vht_mu_bfee = - !!(sta->vht_cap.cap & IEEE80211_VHT_CAP_MU_BEAMFORMEE_CAPABLE); + !!(sta->deflink.vht_cap.cap & IEEE80211_VHT_CAP_MU_BEAMFORMEE_CAPABLE); - if (!sta->he_cap.has_he) + if (!sta->deflink.he_cap.has_he) return; muru->mimo_dl.partial_bw_dl_mimo = @@ -987,13 +987,13 @@ mt7915_mcu_sta_ht_tlv(struct sk_buff *skb, struct ieee80211_sta *sta) struct sta_rec_ht *ht; struct tlv *tlv; - if (!sta->ht_cap.ht_supported) + if (!sta->deflink.ht_cap.ht_supported) return; tlv = mt76_connac_mcu_add_tlv(skb, STA_REC_HT, sizeof(*ht)); ht = (struct sta_rec_ht *)tlv; - ht->ht_cap = cpu_to_le16(sta->ht_cap.cap); + ht->ht_cap = cpu_to_le16(sta->deflink.ht_cap.cap); } static void @@ -1002,15 +1002,15 @@ mt7915_mcu_sta_vht_tlv(struct sk_buff *skb, struct ieee80211_sta *sta) struct sta_rec_vht *vht; struct tlv *tlv; - if (!sta->vht_cap.vht_supported) + if (!sta->deflink.vht_cap.vht_supported) return; tlv = mt76_connac_mcu_add_tlv(skb, STA_REC_VHT, sizeof(*vht)); vht = (struct sta_rec_vht *)tlv; - vht->vht_cap = cpu_to_le32(sta->vht_cap.cap); - vht->vht_rx_mcs_map = sta->vht_cap.vht_mcs.rx_mcs_map; - vht->vht_tx_mcs_map = sta->vht_cap.vht_mcs.tx_mcs_map; + vht->vht_cap = cpu_to_le32(sta->deflink.vht_cap.cap); + vht->vht_rx_mcs_map = sta->deflink.vht_cap.vht_mcs.rx_mcs_map; + vht->vht_tx_mcs_map = sta->deflink.vht_cap.vht_mcs.tx_mcs_map; } static void @@ -1097,8 +1097,8 @@ mt7915_is_ebf_supported(struct mt7915_phy *phy, struct ieee80211_vif *vif, if (!bfee && tx_ant < 2) return false; - if (sta->he_cap.has_he) { - struct ieee80211_he_cap_elem *pe = &sta->he_cap.he_cap_elem; + if (sta->deflink.he_cap.has_he) { + struct ieee80211_he_cap_elem *pe = &sta->deflink.he_cap.he_cap_elem; if (bfee) return mvif->cap.he_su_ebfee && @@ -1108,8 +1108,8 @@ mt7915_is_ebf_supported(struct mt7915_phy *phy, struct ieee80211_vif *vif, HE_PHY(CAP4_SU_BEAMFORMEE, pe->phy_cap_info[4]); } - if (sta->vht_cap.vht_supported) { - u32 cap = sta->vht_cap.cap; + if (sta->deflink.vht_cap.vht_supported) { + u32 cap = sta->deflink.vht_cap.cap; if (bfee) return mvif->cap.vht_su_ebfee && @@ -1135,7 +1135,7 @@ static void mt7915_mcu_sta_bfer_ht(struct ieee80211_sta *sta, struct mt7915_phy *phy, struct sta_rec_bf *bf) { - struct ieee80211_mcs_info *mcs = &sta->ht_cap.mcs; + struct ieee80211_mcs_info *mcs = &sta->deflink.ht_cap.mcs; u8 n = 0; bf->tx_mode = MT_PHY_TYPE_HT; @@ -1160,7 +1160,7 @@ static void mt7915_mcu_sta_bfer_vht(struct ieee80211_sta *sta, struct mt7915_phy *phy, struct sta_rec_bf *bf, bool explicit) { - struct ieee80211_sta_vht_cap *pc = &sta->vht_cap; + struct ieee80211_sta_vht_cap *pc = &sta->deflink.vht_cap; struct ieee80211_sta_vht_cap *vc = &phy->mt76->sband_5g.sband.vht_cap; u16 mcs_map = le16_to_cpu(pc->vht_mcs.rx_mcs_map); u8 nss_mcs = mt7915_mcu_get_sta_nss(mcs_map); @@ -1181,14 +1181,14 @@ mt7915_mcu_sta_bfer_vht(struct ieee80211_sta *sta, struct mt7915_phy *phy, bf->ncol = min_t(u8, nss_mcs, bf->nrow); bf->ibf_ncol = bf->ncol; - if (sta->bandwidth == IEEE80211_STA_RX_BW_160) + if (sta->deflink.bandwidth == IEEE80211_STA_RX_BW_160) bf->nrow = 1; } else { bf->nrow = tx_ant; bf->ncol = min_t(u8, nss_mcs, bf->nrow); bf->ibf_ncol = nss_mcs; - if (sta->bandwidth == IEEE80211_STA_RX_BW_160) + if (sta->deflink.bandwidth == IEEE80211_STA_RX_BW_160) bf->ibf_nrow = 1; } } @@ -1197,7 +1197,7 @@ static void mt7915_mcu_sta_bfer_he(struct ieee80211_sta *sta, struct ieee80211_vif *vif, struct mt7915_phy *phy, struct sta_rec_bf *bf) { - struct ieee80211_sta_he_cap *pc = &sta->he_cap; + struct ieee80211_sta_he_cap *pc = &sta->deflink.he_cap; struct ieee80211_he_cap_elem *pe = &pc->he_cap_elem; const struct ieee80211_sta_he_cap *vc = mt76_connac_get_he_phy_cap(phy->mt76, vif); @@ -1222,7 +1222,7 @@ mt7915_mcu_sta_bfer_he(struct ieee80211_sta *sta, struct ieee80211_vif *vif, bf->ncol = min_t(u8, nss_mcs, bf->nrow); bf->ibf_ncol = bf->ncol; - if (sta->bandwidth != IEEE80211_STA_RX_BW_160) + if (sta->deflink.bandwidth != IEEE80211_STA_RX_BW_160) return; /* go over for 160MHz and 80p80 */ @@ -1270,7 +1270,7 @@ mt7915_mcu_sta_bfer_tlv(struct mt7915_dev *dev, struct sk_buff *skb, }; bool ebf; - if (!(sta->ht_cap.ht_supported || sta->he_cap.has_he)) + if (!(sta->deflink.ht_cap.ht_supported || sta->deflink.he_cap.has_he)) return; ebf = mt7915_is_ebf_supported(phy, vif, sta, false); @@ -1284,21 +1284,21 @@ mt7915_mcu_sta_bfer_tlv(struct mt7915_dev *dev, struct sk_buff *skb, * vht: support eBF and iBF * ht: iBF only, since mac80211 lacks of eBF support */ - if (sta->he_cap.has_he && ebf) + if (sta->deflink.he_cap.has_he && ebf) mt7915_mcu_sta_bfer_he(sta, vif, phy, bf); - else if (sta->vht_cap.vht_supported) + else if (sta->deflink.vht_cap.vht_supported) mt7915_mcu_sta_bfer_vht(sta, phy, bf, ebf); - else if (sta->ht_cap.ht_supported) + else if (sta->deflink.ht_cap.ht_supported) mt7915_mcu_sta_bfer_ht(sta, phy, bf); else return; bf->bf_cap = ebf ? ebf : dev->ibf << 1; - bf->bw = sta->bandwidth; - bf->ibf_dbw = sta->bandwidth; + bf->bw = sta->deflink.bandwidth; + bf->ibf_dbw = sta->deflink.bandwidth; bf->ibf_nrow = tx_ant; - if (!ebf && sta->bandwidth <= IEEE80211_STA_RX_BW_40 && !bf->ncol) + if (!ebf && sta->deflink.bandwidth <= IEEE80211_STA_RX_BW_40 && !bf->ncol) bf->ibf_timeout = 0x48; else bf->ibf_timeout = 0x18; @@ -1308,7 +1308,7 @@ mt7915_mcu_sta_bfer_tlv(struct mt7915_dev *dev, struct sk_buff *skb, else bf->mem_20m = matrix[bf->nrow][bf->ncol]; - switch (sta->bandwidth) { + switch (sta->deflink.bandwidth) { case IEEE80211_STA_RX_BW_160: case IEEE80211_STA_RX_BW_80: bf->mem_total = bf->mem_20m * 2; @@ -1333,7 +1333,7 @@ mt7915_mcu_sta_bfee_tlv(struct mt7915_dev *dev, struct sk_buff *skb, struct tlv *tlv; u8 nrow = 0; - if (!(sta->vht_cap.vht_supported || sta->he_cap.has_he)) + if (!(sta->deflink.vht_cap.vht_supported || sta->deflink.he_cap.has_he)) return; if (!mt7915_is_ebf_supported(phy, vif, sta, true)) @@ -1342,13 +1342,13 @@ mt7915_mcu_sta_bfee_tlv(struct mt7915_dev *dev, struct sk_buff *skb, tlv = mt76_connac_mcu_add_tlv(skb, STA_REC_BFEE, sizeof(*bfee)); bfee = (struct sta_rec_bfee *)tlv; - if (sta->he_cap.has_he) { - struct ieee80211_he_cap_elem *pe = &sta->he_cap.he_cap_elem; + if (sta->deflink.he_cap.has_he) { + struct ieee80211_he_cap_elem *pe = &sta->deflink.he_cap.he_cap_elem; nrow = HE_PHY(CAP5_BEAMFORMEE_NUM_SND_DIM_UNDER_80MHZ_MASK, pe->phy_cap_info[5]); - } else if (sta->vht_cap.vht_supported) { - struct ieee80211_sta_vht_cap *pc = &sta->vht_cap; + } else if (sta->deflink.vht_cap.vht_supported) { + struct ieee80211_sta_vht_cap *pc = &sta->deflink.vht_cap; nrow = FIELD_GET(IEEE80211_VHT_CAP_SOUNDING_DIMENSIONS_MASK, pc->cap); @@ -1464,7 +1464,7 @@ mt7915_mcu_add_rate_ctrl_fixed(struct mt7915_dev *dev, do { \ u8 i, gi = mask->control[band]._gi; \ gi = (_he) ? gi : gi == NL80211_TXRATE_FORCE_SGI; \ - for (i = 0; i <= sta->bandwidth; i++) { \ + for (i = 0; i <= sta->deflink.bandwidth; i++) { \ phy.sgi |= gi << (i << (_he)); \ phy.he_ltf |= mask->control[band].he_ltf << (i << (_he));\ } \ @@ -1476,11 +1476,11 @@ mt7915_mcu_add_rate_ctrl_fixed(struct mt7915_dev *dev, } \ } while (0) - if (sta->he_cap.has_he) { + if (sta->deflink.he_cap.has_he) { __sta_phy_bitrate_mask_check(he_mcs, he_gi, 1); - } else if (sta->vht_cap.vht_supported) { + } else if (sta->deflink.vht_cap.vht_supported) { __sta_phy_bitrate_mask_check(vht_mcs, gi, 0); - } else if (sta->ht_cap.ht_supported) { + } else if (sta->deflink.ht_cap.ht_supported) { __sta_phy_bitrate_mask_check(ht_mcs, gi, 0); } else { nrates = hweight32(mask->control[band].legacy); @@ -1514,7 +1514,7 @@ mt7915_mcu_add_rate_ctrl_fixed(struct mt7915_dev *dev, * actual txrate hardware sends out. */ addr = mt7915_mac_wtbl_lmac_addr(dev, msta->wcid.idx, 7); - if (sta->he_cap.has_he) + if (sta->deflink.he_cap.has_he) mt76_rmw_field(dev, addr, GENMASK(31, 24), phy.sgi); else mt76_rmw_field(dev, addr, GENMASK(15, 12), phy.sgi); @@ -1547,7 +1547,7 @@ mt7915_mcu_sta_rate_ctrl_tlv(struct sk_buff *skb, struct mt7915_dev *dev, enum nl80211_band band = chandef->chan->band; struct sta_rec_ra *ra; struct tlv *tlv; - u32 supp_rate = sta->supp_rates[band]; + u32 supp_rate = sta->deflink.supp_rates[band]; u32 cap = sta->wme ? STA_CAP_WMM : 0; tlv = mt76_connac_mcu_add_tlv(skb, STA_REC_RA, sizeof(*ra)); @@ -1557,8 +1557,8 @@ mt7915_mcu_sta_rate_ctrl_tlv(struct sk_buff *skb, struct mt7915_dev *dev, ra->auto_rate = true; ra->phy_mode = mt76_connac_get_phy_mode(mphy, vif, band, sta); ra->channel = chandef->chan->hw_value; - ra->bw = sta->bandwidth; - ra->phy.bw = sta->bandwidth; + ra->bw = sta->deflink.bandwidth; + ra->phy.bw = sta->deflink.bandwidth; ra->mmps_mode = mt7915_mcu_get_mmps_mode(sta->smps_mode); if (supp_rate) { @@ -1579,22 +1579,22 @@ mt7915_mcu_sta_rate_ctrl_tlv(struct sk_buff *skb, struct mt7915_dev *dev, } } - if (sta->ht_cap.ht_supported) { + if (sta->deflink.ht_cap.ht_supported) { ra->supp_mode |= MODE_HT; - ra->af = sta->ht_cap.ampdu_factor; - ra->ht_gf = !!(sta->ht_cap.cap & IEEE80211_HT_CAP_GRN_FLD); + ra->af = sta->deflink.ht_cap.ampdu_factor; + ra->ht_gf = !!(sta->deflink.ht_cap.cap & IEEE80211_HT_CAP_GRN_FLD); cap |= STA_CAP_HT; - if (sta->ht_cap.cap & IEEE80211_HT_CAP_SGI_20) + if (sta->deflink.ht_cap.cap & IEEE80211_HT_CAP_SGI_20) cap |= STA_CAP_SGI_20; - if (sta->ht_cap.cap & IEEE80211_HT_CAP_SGI_40) + if (sta->deflink.ht_cap.cap & IEEE80211_HT_CAP_SGI_40) cap |= STA_CAP_SGI_40; - if (sta->ht_cap.cap & IEEE80211_HT_CAP_TX_STBC) + if (sta->deflink.ht_cap.cap & IEEE80211_HT_CAP_TX_STBC) cap |= STA_CAP_TX_STBC; - if (sta->ht_cap.cap & IEEE80211_HT_CAP_RX_STBC) + if (sta->deflink.ht_cap.cap & IEEE80211_HT_CAP_RX_STBC) cap |= STA_CAP_RX_STBC; if (mvif->cap.ht_ldpc && - (sta->ht_cap.cap & IEEE80211_HT_CAP_LDPC_CODING)) + (sta->deflink.ht_cap.cap & IEEE80211_HT_CAP_LDPC_CODING)) cap |= STA_CAP_LDPC; mt7915_mcu_set_sta_ht_mcs(sta, ra->ht_mcs, @@ -1602,37 +1602,37 @@ mt7915_mcu_sta_rate_ctrl_tlv(struct sk_buff *skb, struct mt7915_dev *dev, ra->supp_ht_mcs = *(__le32 *)ra->ht_mcs; } - if (sta->vht_cap.vht_supported) { + if (sta->deflink.vht_cap.vht_supported) { u8 af; ra->supp_mode |= MODE_VHT; af = FIELD_GET(IEEE80211_VHT_CAP_MAX_A_MPDU_LENGTH_EXPONENT_MASK, - sta->vht_cap.cap); + sta->deflink.vht_cap.cap); ra->af = max_t(u8, ra->af, af); cap |= STA_CAP_VHT; - if (sta->vht_cap.cap & IEEE80211_VHT_CAP_SHORT_GI_80) + if (sta->deflink.vht_cap.cap & IEEE80211_VHT_CAP_SHORT_GI_80) cap |= STA_CAP_VHT_SGI_80; - if (sta->vht_cap.cap & IEEE80211_VHT_CAP_SHORT_GI_160) + if (sta->deflink.vht_cap.cap & IEEE80211_VHT_CAP_SHORT_GI_160) cap |= STA_CAP_VHT_SGI_160; - if (sta->vht_cap.cap & IEEE80211_VHT_CAP_TXSTBC) + if (sta->deflink.vht_cap.cap & IEEE80211_VHT_CAP_TXSTBC) cap |= STA_CAP_VHT_TX_STBC; - if (sta->vht_cap.cap & IEEE80211_VHT_CAP_RXSTBC_1) + if (sta->deflink.vht_cap.cap & IEEE80211_VHT_CAP_RXSTBC_1) cap |= STA_CAP_VHT_RX_STBC; if (mvif->cap.vht_ldpc && - (sta->vht_cap.cap & IEEE80211_VHT_CAP_RXLDPC)) + (sta->deflink.vht_cap.cap & IEEE80211_VHT_CAP_RXLDPC)) cap |= STA_CAP_VHT_LDPC; mt7915_mcu_set_sta_vht_mcs(sta, ra->supp_vht_mcs, mask->control[band].vht_mcs); } - if (sta->he_cap.has_he) { + if (sta->deflink.he_cap.has_he) { ra->supp_mode |= MODE_HE; cap |= STA_CAP_HE; - if (sta->he_6ghz_capa.capa) - ra->af = le16_get_bits(sta->he_6ghz_capa.capa, + if (sta->deflink.he_6ghz_capa.capa) + ra->af = le16_get_bits(sta->deflink.he_6ghz_capa.capa, IEEE80211_HE_6GHZ_CAP_MAX_AMPDU_LEN_EXP); } diff --git a/drivers/net/wireless/mediatek/mt76/mt7921/mac.c b/drivers/net/wireless/mediatek/mt76/mt7921/mac.c index 233998ca48573..b67615487910e 100644 --- a/drivers/net/wireless/mediatek/mt76/mt7921/mac.c +++ b/drivers/net/wireless/mediatek/mt76/mt7921/mac.c @@ -1023,7 +1023,7 @@ void mt7921_tx_check_aggr(struct ieee80211_sta *sta, __le32 *txwi) u16 fc, tid; u32 val; - if (!sta || !(sta->ht_cap.ht_supported || sta->he_cap.has_he)) + if (!sta || !(sta->deflink.ht_cap.ht_supported || sta->deflink.he_cap.has_he)) return; tid = le32_get_bits(txwi[1], MT_TXD1_TID); diff --git a/drivers/net/wireless/mediatek/mt7601u/mac.c b/drivers/net/wireless/mediatek/mt7601u/mac.c index d2ee1aaa3c810..ca9cf628eb10d 100644 --- a/drivers/net/wireless/mediatek/mt7601u/mac.c +++ b/drivers/net/wireless/mediatek/mt7601u/mac.c @@ -385,7 +385,7 @@ void mt7601u_mac_set_ampdu_factor(struct mt7601u_dev *dev) msta = container_of(wcid, struct mt76_sta, wcid); sta = container_of(msta, struct ieee80211_sta, drv_priv); - min_factor = min(min_factor, sta->ht_cap.ampdu_factor); + min_factor = min(min_factor, sta->deflink.ht_cap.ampdu_factor); } rcu_read_unlock(); diff --git a/drivers/net/wireless/mediatek/mt7601u/tx.c b/drivers/net/wireless/mediatek/mt7601u/tx.c index f3dff8319a4c1..f1fa0442a57f1 100644 --- a/drivers/net/wireless/mediatek/mt7601u/tx.c +++ b/drivers/net/wireless/mediatek/mt7601u/tx.c @@ -163,7 +163,7 @@ mt7601u_push_txwi(struct mt7601u_dev *dev, struct sk_buff *skb, if ((info->flags & IEEE80211_TX_CTL_AMPDU) && sta) { u8 ba_size = IEEE80211_MIN_AMPDU_BUF; - ba_size <<= sta->ht_cap.ampdu_factor; + ba_size <<= sta->deflink.ht_cap.ampdu_factor; ba_size = min_t(int, 63, ba_size); if (info->flags & IEEE80211_TX_CTL_RATE_CTRL_PROBE) ba_size = 0; @@ -172,7 +172,7 @@ mt7601u_push_txwi(struct mt7601u_dev *dev, struct sk_buff *skb, txwi->flags = cpu_to_le16(MT_TXWI_FLAGS_AMPDU | FIELD_PREP(MT_TXWI_FLAGS_MPDU_DENSITY, - sta->ht_cap.ampdu_density)); + sta->deflink.ht_cap.ampdu_density)); if (info->flags & IEEE80211_TX_CTL_RATE_CTRL_PROBE) txwi->flags = 0; } diff --git a/drivers/net/wireless/ralink/rt2x00/rt2800lib.c b/drivers/net/wireless/ralink/rt2x00/rt2800lib.c index deddb0afd3128..cbdaf7992f98a 100644 --- a/drivers/net/wireless/ralink/rt2x00/rt2800lib.c +++ b/drivers/net/wireless/ralink/rt2x00/rt2800lib.c @@ -1801,8 +1801,8 @@ int rt2800_sta_add(struct ieee80211_hw *hw, struct ieee80211_vif *vif, * do not have a choice if some connected STA is not capable to * receive the same amount of data like the others. */ - if (sta->ht_cap.ht_supported) { - drv_data->ampdu_factor_cnt[sta->ht_cap.ampdu_factor & 3]++; + if (sta->deflink.ht_cap.ht_supported) { + drv_data->ampdu_factor_cnt[sta->deflink.ht_cap.ampdu_factor & 3]++; rt2800_set_max_psdu_len(rt2x00dev); } @@ -1847,8 +1847,8 @@ int rt2800_sta_remove(struct ieee80211_hw *hw, struct ieee80211_vif *vif, struct rt2x00_sta *sta_priv = sta_to_rt2x00_sta(sta); int wcid = sta_priv->wcid; - if (sta->ht_cap.ht_supported) { - drv_data->ampdu_factor_cnt[sta->ht_cap.ampdu_factor & 3]--; + if (sta->deflink.ht_cap.ht_supported) { + drv_data->ampdu_factor_cnt[sta->deflink.ht_cap.ampdu_factor & 3]--; rt2800_set_max_psdu_len(rt2x00dev); } diff --git a/drivers/net/wireless/ralink/rt2x00/rt2x00queue.c b/drivers/net/wireless/ralink/rt2x00/rt2x00queue.c index fb1d31b2d52ae..aa6b2f3d2eff5 100644 --- a/drivers/net/wireless/ralink/rt2x00/rt2x00queue.c +++ b/drivers/net/wireless/ralink/rt2x00/rt2x00queue.c @@ -303,7 +303,7 @@ static void rt2x00queue_create_tx_descriptor_ht(struct rt2x00_dev *rt2x00dev, if (sta) { sta_priv = sta_to_rt2x00_sta(sta); txdesc->u.ht.wcid = sta_priv->wcid; - density = sta->ht_cap.ampdu_density; + density = sta->deflink.ht_cap.ampdu_density; } /* diff --git a/drivers/net/wireless/realtek/rtl8xxxu/rtl8xxxu_core.c b/drivers/net/wireless/realtek/rtl8xxxu/rtl8xxxu_core.c index 6d9b5cf01b110..8b2ca9e8eac6b 100644 --- a/drivers/net/wireless/realtek/rtl8xxxu/rtl8xxxu_core.c +++ b/drivers/net/wireless/realtek/rtl8xxxu/rtl8xxxu_core.c @@ -4533,21 +4533,21 @@ rtl8xxxu_wireless_mode(struct ieee80211_hw *hw, struct ieee80211_sta *sta) u16 network_type = WIRELESS_MODE_UNKNOWN; if (hw->conf.chandef.chan->band == NL80211_BAND_5GHZ) { - if (sta->vht_cap.vht_supported) + if (sta->deflink.vht_cap.vht_supported) network_type = WIRELESS_MODE_AC; - else if (sta->ht_cap.ht_supported) + else if (sta->deflink.ht_cap.ht_supported) network_type = WIRELESS_MODE_N_5G; network_type |= WIRELESS_MODE_A; } else { - if (sta->vht_cap.vht_supported) + if (sta->deflink.vht_cap.vht_supported) network_type = WIRELESS_MODE_AC; - else if (sta->ht_cap.ht_supported) + else if (sta->deflink.ht_cap.ht_supported) network_type = WIRELESS_MODE_N_24G; - if (sta->supp_rates[0] <= 0xf) + if (sta->deflink.supp_rates[0] <= 0xf) network_type |= WIRELESS_MODE_B; - else if (sta->supp_rates[0] & 0xf) + else if (sta->deflink.supp_rates[0] & 0xf) network_type |= (WIRELESS_MODE_B | WIRELESS_MODE_G); else network_type |= WIRELESS_MODE_G; @@ -4591,16 +4591,16 @@ rtl8xxxu_bss_info_changed(struct ieee80211_hw *hw, struct ieee80211_vif *vif, goto error; } - if (sta->ht_cap.ht_supported) + if (sta->deflink.ht_cap.ht_supported) dev_info(dev, "%s: HT supported\n", __func__); - if (sta->vht_cap.vht_supported) + if (sta->deflink.vht_cap.vht_supported) dev_info(dev, "%s: VHT supported\n", __func__); /* TODO: Set bits 28-31 for rate adaptive id */ - ramask = (sta->supp_rates[0] & 0xfff) | - sta->ht_cap.mcs.rx_mask[0] << 12 | - sta->ht_cap.mcs.rx_mask[1] << 20; - if (sta->ht_cap.cap & + ramask = (sta->deflink.supp_rates[0] & 0xfff) | + sta->deflink.ht_cap.mcs.rx_mask[0] << 12 | + sta->deflink.ht_cap.mcs.rx_mask[1] << 20; + if (sta->deflink.ht_cap.cap & (IEEE80211_HT_CAP_SGI_40 | IEEE80211_HT_CAP_SGI_20)) sgi = 1; rcu_read_unlock(); @@ -5095,12 +5095,12 @@ static void rtl8xxxu_tx(struct ieee80211_hw *hw, /* (tx_info->flags & IEEE80211_TX_CTL_AMPDU) && */ ampdu_enable = false; if (ieee80211_is_data_qos(hdr->frame_control) && sta) { - if (sta->ht_cap.ht_supported) { + if (sta->deflink.ht_cap.ht_supported) { u32 ampdu, val32; u8 *qc = ieee80211_get_qos_ctl(hdr); u8 tid = qc[0] & IEEE80211_QOS_CTL_TID_MASK; - ampdu = (u32)sta->ht_cap.ampdu_density; + ampdu = (u32)sta->deflink.ht_cap.ampdu_density; val32 = ampdu << TXDESC_AMPDU_DENSITY_SHIFT; tx_desc->txdw2 |= cpu_to_le32(val32); @@ -5115,7 +5115,7 @@ static void rtl8xxxu_tx(struct ieee80211_hw *hw, if (rate_flag & IEEE80211_TX_RC_SHORT_GI || (ieee80211_is_data_qos(hdr->frame_control) && - sta && sta->ht_cap.cap & + sta && sta->deflink.ht_cap.cap & (IEEE80211_HT_CAP_SGI_40 | IEEE80211_HT_CAP_SGI_20))) sgi = true; @@ -6162,8 +6162,8 @@ rtl8xxxu_ampdu_action(struct ieee80211_hw *hw, struct ieee80211_vif *vif, switch (action) { case IEEE80211_AMPDU_TX_START: dev_dbg(dev, "%s: IEEE80211_AMPDU_TX_START\n", __func__); - ampdu_factor = sta->ht_cap.ampdu_factor; - ampdu_density = sta->ht_cap.ampdu_density; + ampdu_factor = sta->deflink.ht_cap.ampdu_factor; + ampdu_density = sta->deflink.ht_cap.ampdu_density; rtl8xxxu_set_ampdu_factor(priv, ampdu_factor); rtl8xxxu_set_ampdu_min_space(priv, ampdu_density); dev_dbg(dev, @@ -6255,10 +6255,10 @@ static void rtl8xxxu_refresh_rate_mask(struct rtl8xxxu_priv *priv, u32 rate_bitmap = 0; rcu_read_lock(); - rate_bitmap = (sta->supp_rates[0] & 0xfff) | - (sta->ht_cap.mcs.rx_mask[0] << 12) | - (sta->ht_cap.mcs.rx_mask[1] << 20); - if (sta->ht_cap.cap & + rate_bitmap = (sta->deflink.supp_rates[0] & 0xfff) | + (sta->deflink.ht_cap.mcs.rx_mask[0] << 12) | + (sta->deflink.ht_cap.mcs.rx_mask[1] << 20); + if (sta->deflink.ht_cap.cap & (IEEE80211_HT_CAP_SGI_40 | IEEE80211_HT_CAP_SGI_20)) sgi = 1; rcu_read_unlock(); diff --git a/drivers/net/wireless/realtek/rtlwifi/base.c b/drivers/net/wireless/realtek/rtlwifi/base.c index a7ef84f559399..9e7e98b55eff8 100644 --- a/drivers/net/wireless/realtek/rtlwifi/base.c +++ b/drivers/net/wireless/realtek/rtlwifi/base.c @@ -629,11 +629,12 @@ static void _rtl_query_shortgi(struct ieee80211_hw *hw, if (sta == NULL) return; - sgi_40 = sta->ht_cap.cap & IEEE80211_HT_CAP_SGI_40; - sgi_20 = sta->ht_cap.cap & IEEE80211_HT_CAP_SGI_20; - sgi_80 = sta->vht_cap.cap & IEEE80211_VHT_CAP_SHORT_GI_80; + sgi_40 = sta->deflink.ht_cap.cap & IEEE80211_HT_CAP_SGI_40; + sgi_20 = sta->deflink.ht_cap.cap & IEEE80211_HT_CAP_SGI_20; + sgi_80 = sta->deflink.vht_cap.cap & IEEE80211_VHT_CAP_SHORT_GI_80; - if ((!sta->ht_cap.ht_supported) && (!sta->vht_cap.vht_supported)) + if (!sta->deflink.ht_cap.ht_supported && + !sta->deflink.vht_cap.vht_supported) return; if (!sgi_40 && !sgi_20) @@ -645,8 +646,8 @@ static void _rtl_query_shortgi(struct ieee80211_hw *hw, } else if (mac->opmode == NL80211_IFTYPE_AP || mac->opmode == NL80211_IFTYPE_ADHOC || mac->opmode == NL80211_IFTYPE_MESH_POINT) { - bw_40 = sta->ht_cap.cap & IEEE80211_HT_CAP_SUP_WIDTH_20_40; - bw_80 = sta->vht_cap.vht_supported; + bw_40 = sta->deflink.ht_cap.cap & IEEE80211_HT_CAP_SUP_WIDTH_20_40; + bw_80 = sta->deflink.vht_cap.vht_supported; } if (bw_80) { @@ -864,11 +865,11 @@ static void _rtl_query_bandwidth_mode(struct ieee80211_hw *hw, if (mac->opmode == NL80211_IFTYPE_AP || mac->opmode == NL80211_IFTYPE_ADHOC || mac->opmode == NL80211_IFTYPE_MESH_POINT) { - if (!(sta->ht_cap.ht_supported) || - !(sta->ht_cap.cap & IEEE80211_HT_CAP_SUP_WIDTH_20_40)) + if (!(sta->deflink.ht_cap.ht_supported) || + !(sta->deflink.ht_cap.cap & IEEE80211_HT_CAP_SUP_WIDTH_20_40)) return; } else if (mac->opmode == NL80211_IFTYPE_STATION) { - if (!mac->bw_40 || !(sta->ht_cap.ht_supported)) + if (!mac->bw_40 || !(sta->deflink.ht_cap.ht_supported)) return; } if (tcb_desc->multicast || tcb_desc->broadcast) @@ -884,11 +885,11 @@ static void _rtl_query_bandwidth_mode(struct ieee80211_hw *hw, if (mac->opmode == NL80211_IFTYPE_AP || mac->opmode == NL80211_IFTYPE_ADHOC || mac->opmode == NL80211_IFTYPE_MESH_POINT) { - if (!(sta->vht_cap.vht_supported)) + if (!(sta->deflink.vht_cap.vht_supported)) return; } else if (mac->opmode == NL80211_IFTYPE_STATION) { if (!mac->bw_80 || - !(sta->vht_cap.vht_supported)) + !(sta->deflink.vht_cap.vht_supported)) return; } if (tcb_desc->hw_rate <= @@ -904,7 +905,7 @@ static u8 _rtl_get_vht_highest_n_rate(struct ieee80211_hw *hw, struct rtl_priv *rtlpriv = rtl_priv(hw); struct rtl_phy *rtlphy = &(rtlpriv->phy); u8 hw_rate; - u16 tx_mcs_map = le16_to_cpu(sta->vht_cap.vht_mcs.tx_mcs_map); + u16 tx_mcs_map = le16_to_cpu(sta->deflink.vht_cap.vht_mcs.tx_mcs_map); if ((get_rf_type(rtlphy) == RF_2T2R) && (tx_mcs_map & 0x000c) != 0x000c) { @@ -944,7 +945,7 @@ static u8 _rtl_get_highest_n_rate(struct ieee80211_hw *hw, u8 hw_rate; if (get_rf_type(rtlphy) == RF_2T2R && - sta->ht_cap.mcs.rx_mask[1] != 0) + sta->deflink.ht_cap.mcs.rx_mask[1] != 0) hw_rate = rtlpriv->cfg->maps[RTL_RC_HT_RATEMCS15]; else hw_rate = rtlpriv->cfg->maps[RTL_RC_HT_RATEMCS7]; @@ -1271,11 +1272,11 @@ void rtl_get_tcb_desc(struct ieee80211_hw *hw, *and N rate will all be controlled by FW *when tcb_desc->use_driver_rate = false */ - if (sta && sta->vht_cap.vht_supported) { + if (sta && sta->deflink.vht_cap.vht_supported) { tcb_desc->hw_rate = _rtl_get_vht_highest_n_rate(hw, sta); } else { - if (sta && sta->ht_cap.ht_supported) { + if (sta && sta->deflink.ht_cap.ht_supported) { tcb_desc->hw_rate = _rtl_get_highest_n_rate(hw, sta); } else { diff --git a/drivers/net/wireless/realtek/rtlwifi/core.c b/drivers/net/wireless/realtek/rtlwifi/core.c index 8efe2f5e5b9f3..99a1d91ced5af 100644 --- a/drivers/net/wireless/realtek/rtlwifi/core.c +++ b/drivers/net/wireless/realtek/rtlwifi/core.c @@ -903,18 +903,18 @@ static int rtl_op_sta_add(struct ieee80211_hw *hw, spin_unlock_bh(&rtlpriv->locks.entry_list_lock); if (rtlhal->current_bandtype == BAND_ON_2_4G) { sta_entry->wireless_mode = WIRELESS_MODE_G; - if (sta->supp_rates[0] <= 0xf) + if (sta->deflink.supp_rates[0] <= 0xf) sta_entry->wireless_mode = WIRELESS_MODE_B; - if (sta->ht_cap.ht_supported) + if (sta->deflink.ht_cap.ht_supported) sta_entry->wireless_mode = WIRELESS_MODE_N_24G; if (vif->type == NL80211_IFTYPE_ADHOC) sta_entry->wireless_mode = WIRELESS_MODE_G; } else if (rtlhal->current_bandtype == BAND_ON_5G) { sta_entry->wireless_mode = WIRELESS_MODE_A; - if (sta->ht_cap.ht_supported) + if (sta->deflink.ht_cap.ht_supported) sta_entry->wireless_mode = WIRELESS_MODE_N_5G; - if (sta->vht_cap.vht_supported) + if (sta->deflink.vht_cap.vht_supported) sta_entry->wireless_mode = WIRELESS_MODE_AC_5G; if (vif->type == NL80211_IFTYPE_ADHOC) @@ -922,7 +922,7 @@ static int rtl_op_sta_add(struct ieee80211_hw *hw, } /*disable cck rate for p2p*/ if (mac->p2p) - sta->supp_rates[0] &= 0xfffffff0; + sta->deflink.supp_rates[0] &= 0xfffffff0; memcpy(sta_entry->mac_addr, sta->addr, ETH_ALEN); rtl_dbg(rtlpriv, COMP_MAC80211, DBG_DMESG, @@ -1126,7 +1126,7 @@ static void rtl_op_bss_info_changed(struct ieee80211_hw *hw, rtl_dbg(rtlpriv, COMP_EASY_CONCURRENT, DBG_LOUD, "send PS STATIC frame\n"); if (rtlpriv->dm.supp_phymode_switch) { - if (sta->ht_cap.ht_supported) + if (sta->deflink.ht_cap.ht_supported) rtl_send_smps_action(hw, sta, IEEE80211_SMPS_STATIC); } @@ -1134,20 +1134,20 @@ static void rtl_op_bss_info_changed(struct ieee80211_hw *hw, if (rtlhal->current_bandtype == BAND_ON_5G) { mac->mode = WIRELESS_MODE_A; } else { - if (sta->supp_rates[0] <= 0xf) + if (sta->deflink.supp_rates[0] <= 0xf) mac->mode = WIRELESS_MODE_B; else mac->mode = WIRELESS_MODE_G; } - if (sta->ht_cap.ht_supported) { + if (sta->deflink.ht_cap.ht_supported) { if (rtlhal->current_bandtype == BAND_ON_2_4G) mac->mode = WIRELESS_MODE_N_24G; else mac->mode = WIRELESS_MODE_N_5G; } - if (sta->vht_cap.vht_supported) { + if (sta->deflink.vht_cap.vht_supported) { if (rtlhal->current_bandtype == BAND_ON_5G) mac->mode = WIRELESS_MODE_AC_5G; else @@ -1256,14 +1256,14 @@ static void rtl_op_bss_info_changed(struct ieee80211_hw *hw, rcu_read_lock(); sta = ieee80211_find_sta(vif, (u8 *)bss_conf->bssid); if (sta) { - if (sta->ht_cap.ampdu_density > + if (sta->deflink.ht_cap.ampdu_density > mac->current_ampdu_density) mac->current_ampdu_density = - sta->ht_cap.ampdu_density; - if (sta->ht_cap.ampdu_factor < + sta->deflink.ht_cap.ampdu_density; + if (sta->deflink.ht_cap.ampdu_factor < mac->current_ampdu_factor) mac->current_ampdu_factor = - sta->ht_cap.ampdu_factor; + sta->deflink.ht_cap.ampdu_factor; } rcu_read_unlock(); @@ -1298,20 +1298,20 @@ static void rtl_op_bss_info_changed(struct ieee80211_hw *hw, if (rtlhal->current_bandtype == BAND_ON_5G) { mac->mode = WIRELESS_MODE_A; } else { - if (sta->supp_rates[0] <= 0xf) + if (sta->deflink.supp_rates[0] <= 0xf) mac->mode = WIRELESS_MODE_B; else mac->mode = WIRELESS_MODE_G; } - if (sta->ht_cap.ht_supported) { + if (sta->deflink.ht_cap.ht_supported) { if (rtlhal->current_bandtype == BAND_ON_2_4G) mac->mode = WIRELESS_MODE_N_24G; else mac->mode = WIRELESS_MODE_N_5G; } - if (sta->vht_cap.vht_supported) { + if (sta->deflink.vht_cap.vht_supported) { if (rtlhal->current_bandtype == BAND_ON_5G) mac->mode = WIRELESS_MODE_AC_5G; else @@ -1327,7 +1327,7 @@ static void rtl_op_bss_info_changed(struct ieee80211_hw *hw, sta_entry->wireless_mode = mac->mode; } - if (sta->ht_cap.ht_supported) { + if (sta->deflink.ht_cap.ht_supported) { mac->ht_enable = true; /* @@ -1338,16 +1338,16 @@ static void rtl_op_bss_info_changed(struct ieee80211_hw *hw, * */ } - if (sta->vht_cap.vht_supported) + if (sta->deflink.vht_cap.vht_supported) mac->vht_enable = true; if (changed & BSS_CHANGED_BASIC_RATES) { /* for 5G must << RATE_6M_INDEX = 4, * because 5G have no cck rate*/ if (rtlhal->current_bandtype == BAND_ON_5G) - basic_rates = sta->supp_rates[1] << 4; + basic_rates = sta->deflink.supp_rates[1] << 4; else - basic_rates = sta->supp_rates[0]; + basic_rates = sta->deflink.supp_rates[0]; mac->basic_rates = basic_rates; rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_BASIC_RATE, diff --git a/drivers/net/wireless/realtek/rtlwifi/rc.c b/drivers/net/wireless/realtek/rtlwifi/rc.c index 4b5ea0ec91093..a164364109ba7 100644 --- a/drivers/net/wireless/realtek/rtlwifi/rc.c +++ b/drivers/net/wireless/realtek/rtlwifi/rc.c @@ -66,7 +66,7 @@ static u8 _rtl_rc_get_highest_rix(struct rtl_priv *rtlpriv, else return N_MODE_MCS15_RIX; } else if (wireless_mode == WIRELESS_MODE_AC_24G) { - if (sta->bandwidth == IEEE80211_STA_RX_BW_20) { + if (sta->deflink.bandwidth == IEEE80211_STA_RX_BW_20) { ieee80211_rate_set_vht(&rate, AC_MODE_MCS8_RIX, nss); @@ -88,7 +88,7 @@ static u8 _rtl_rc_get_highest_rix(struct rtl_priv *rtlpriv, else return N_MODE_MCS15_RIX; } else if (wireless_mode == WIRELESS_MODE_AC_5G) { - if (sta->bandwidth == IEEE80211_STA_RX_BW_20) { + if (sta->deflink.bandwidth == IEEE80211_STA_RX_BW_20) { ieee80211_rate_set_vht(&rate, AC_MODE_MCS8_RIX, nss); @@ -121,9 +121,9 @@ static void _rtl_rc_rate_set_series(struct rtl_priv *rtlpriv, u8 sgi_20 = 0, sgi_40 = 0, sgi_80 = 0; if (sta) { - sgi_20 = sta->ht_cap.cap & IEEE80211_HT_CAP_SGI_20; - sgi_40 = sta->ht_cap.cap & IEEE80211_HT_CAP_SGI_40; - sgi_80 = sta->vht_cap.cap & IEEE80211_VHT_CAP_SHORT_GI_80; + sgi_20 = sta->deflink.ht_cap.cap & IEEE80211_HT_CAP_SGI_20; + sgi_40 = sta->deflink.ht_cap.cap & IEEE80211_HT_CAP_SGI_40; + sgi_80 = sta->deflink.vht_cap.cap & IEEE80211_VHT_CAP_SHORT_GI_80; sta_entry = (struct rtl_sta_info *)sta->drv_priv; wireless_mode = sta_entry->wireless_mode; } @@ -135,10 +135,10 @@ static void _rtl_rc_rate_set_series(struct rtl_priv *rtlpriv, rate->flags |= IEEE80211_TX_RC_USE_SHORT_PREAMBLE; if (mac->opmode == NL80211_IFTYPE_AP || mac->opmode == NL80211_IFTYPE_ADHOC) { - if (sta && (sta->ht_cap.cap & + if (sta && (sta->deflink.ht_cap.cap & IEEE80211_HT_CAP_SUP_WIDTH_20_40)) rate->flags |= IEEE80211_TX_RC_40_MHZ_WIDTH; - if (sta && sta->vht_cap.vht_supported) + if (sta && sta->deflink.vht_cap.vht_supported) rate->flags |= IEEE80211_TX_RC_80_MHZ_WIDTH; } else { if (mac->bw_80) @@ -149,11 +149,11 @@ static void _rtl_rc_rate_set_series(struct rtl_priv *rtlpriv, if (sgi_20 || sgi_40 || sgi_80) rate->flags |= IEEE80211_TX_RC_SHORT_GI; - if (sta && sta->ht_cap.ht_supported && + if (sta && sta->deflink.ht_cap.ht_supported && (wireless_mode == WIRELESS_MODE_N_5G || wireless_mode == WIRELESS_MODE_N_24G)) rate->flags |= IEEE80211_TX_RC_MCS; - if (sta && sta->vht_cap.vht_supported && + if (sta && sta->deflink.vht_cap.vht_supported && (wireless_mode == WIRELESS_MODE_AC_5G || wireless_mode == WIRELESS_MODE_AC_24G || wireless_mode == WIRELESS_MODE_AC_ONLY)) @@ -229,7 +229,7 @@ static void rtl_tx_status(void *ppriv, if (sta) { /* Check if aggregation has to be enabled for this tid */ sta_entry = (struct rtl_sta_info *)sta->drv_priv; - if (sta->ht_cap.ht_supported && + if (sta->deflink.ht_cap.ht_supported && !(skb->protocol == cpu_to_be16(ETH_P_PAE))) { if (ieee80211_is_data_qos(fc)) { u8 tid = rtl_get_tid(skb); diff --git a/drivers/net/wireless/realtek/rtlwifi/rtl8188ee/hw.c b/drivers/net/wireless/realtek/rtlwifi/rtl8188ee/hw.c index bf686a916acb8..58c2ab3d44bef 100644 --- a/drivers/net/wireless/realtek/rtlwifi/rtl8188ee/hw.c +++ b/drivers/net/wireless/realtek/rtlwifi/rtl8188ee/hw.c @@ -1975,21 +1975,21 @@ static void rtl88ee_update_hal_rate_table(struct ieee80211_hw *hw, u16 shortgi_rate; u32 tmp_ratr_value; u8 curtxbw_40mhz = mac->bw_40; - u8 curshortgi_40mhz = (sta->ht_cap.cap & IEEE80211_HT_CAP_SGI_40) ? + u8 curshortgi_40mhz = (sta->deflink.ht_cap.cap & IEEE80211_HT_CAP_SGI_40) ? 1 : 0; - u8 curshortgi_20mhz = (sta->ht_cap.cap & IEEE80211_HT_CAP_SGI_20) ? + u8 curshortgi_20mhz = (sta->deflink.ht_cap.cap & IEEE80211_HT_CAP_SGI_20) ? 1 : 0; enum wireless_mode wirelessmode = mac->mode; u32 ratr_mask; if (rtlhal->current_bandtype == BAND_ON_5G) - ratr_value = sta->supp_rates[1] << 4; + ratr_value = sta->deflink.supp_rates[1] << 4; else - ratr_value = sta->supp_rates[0]; + ratr_value = sta->deflink.supp_rates[0]; if (mac->opmode == NL80211_IFTYPE_ADHOC) ratr_value = 0xfff; - ratr_value |= (sta->ht_cap.mcs.rx_mask[1] << 20 | - sta->ht_cap.mcs.rx_mask[0] << 12); + ratr_value |= (sta->deflink.ht_cap.mcs.rx_mask[1] << 20 | + sta->deflink.ht_cap.mcs.rx_mask[0] << 12); switch (wirelessmode) { case WIRELESS_MODE_B: if (ratr_value & 0x0000000c) @@ -2061,11 +2061,11 @@ static void rtl88ee_update_hal_rate_mask(struct ieee80211_hw *hw, struct rtl_sta_info *sta_entry = NULL; u32 ratr_bitmap; u8 ratr_index; - u8 curtxbw_40mhz = (sta->ht_cap.cap & IEEE80211_HT_CAP_SUP_WIDTH_20_40) + u8 curtxbw_40mhz = (sta->deflink.ht_cap.cap & IEEE80211_HT_CAP_SUP_WIDTH_20_40) ? 1 : 0; - u8 curshortgi_40mhz = (sta->ht_cap.cap & IEEE80211_HT_CAP_SGI_40) ? + u8 curshortgi_40mhz = (sta->deflink.ht_cap.cap & IEEE80211_HT_CAP_SGI_40) ? 1 : 0; - u8 curshortgi_20mhz = (sta->ht_cap.cap & IEEE80211_HT_CAP_SGI_20) ? + u8 curshortgi_20mhz = (sta->deflink.ht_cap.cap & IEEE80211_HT_CAP_SGI_20) ? 1 : 0; enum wireless_mode wirelessmode = 0; bool b_shortgi = false; @@ -2083,13 +2083,13 @@ static void rtl88ee_update_hal_rate_mask(struct ieee80211_hw *hw, macid = sta->aid + 1; if (rtlhal->current_bandtype == BAND_ON_5G) - ratr_bitmap = sta->supp_rates[1] << 4; + ratr_bitmap = sta->deflink.supp_rates[1] << 4; else - ratr_bitmap = sta->supp_rates[0]; + ratr_bitmap = sta->deflink.supp_rates[0]; if (mac->opmode == NL80211_IFTYPE_ADHOC) ratr_bitmap = 0xfff; - ratr_bitmap |= (sta->ht_cap.mcs.rx_mask[1] << 20 | - sta->ht_cap.mcs.rx_mask[0] << 12); + ratr_bitmap |= (sta->deflink.ht_cap.mcs.rx_mask[1] << 20 | + sta->deflink.ht_cap.mcs.rx_mask[0] << 12); switch (wirelessmode) { case WIRELESS_MODE_B: ratr_index = RATR_INX_WIRELESS_B; diff --git a/drivers/net/wireless/realtek/rtlwifi/rtl8188ee/trx.c b/drivers/net/wireless/realtek/rtlwifi/rtl8188ee/trx.c index c948dafa0c80a..257816563fa0e 100644 --- a/drivers/net/wireless/realtek/rtlwifi/rtl8188ee/trx.c +++ b/drivers/net/wireless/realtek/rtlwifi/rtl8188ee/trx.c @@ -504,7 +504,7 @@ void rtl88ee_tx_fill_desc(struct ieee80211_hw *hw, } else if (mac->opmode == NL80211_IFTYPE_AP || mac->opmode == NL80211_IFTYPE_ADHOC) { if (sta) - bw_40 = sta->ht_cap.cap & + bw_40 = sta->deflink.ht_cap.cap & IEEE80211_HT_CAP_SUP_WIDTH_20_40; } seq_number = (le16_to_cpu(hdr->seq_ctrl) & IEEE80211_SCTL_SEQ) >> 4; @@ -591,7 +591,7 @@ void rtl88ee_tx_fill_desc(struct ieee80211_hw *hw, set_tx_desc_linip(pdesc, 0); set_tx_desc_pkt_size(pdesc, (u16)skb_len); if (sta) { - u8 ampdu_density = sta->ht_cap.ampdu_density; + u8 ampdu_density = sta->deflink.ht_cap.ampdu_density; set_tx_desc_ampdu_density(pdesc, ampdu_density); } if (info->control.hw_key) { diff --git a/drivers/net/wireless/realtek/rtlwifi/rtl8192ce/hw.c b/drivers/net/wireless/realtek/rtlwifi/rtl8192ce/hw.c index bb5a0c4aec935..b9c62640d2cbd 100644 --- a/drivers/net/wireless/realtek/rtlwifi/rtl8192ce/hw.c +++ b/drivers/net/wireless/realtek/rtlwifi/rtl8192ce/hw.c @@ -1765,22 +1765,22 @@ static void rtl92ce_update_hal_rate_table(struct ieee80211_hw *hw, u16 shortgi_rate; u32 tmp_ratr_value; u8 curtxbw_40mhz = mac->bw_40; - u8 curshortgi_40mhz = (sta->ht_cap.cap & IEEE80211_HT_CAP_SGI_40) ? + u8 curshortgi_40mhz = (sta->deflink.ht_cap.cap & IEEE80211_HT_CAP_SGI_40) ? 1 : 0; - u8 curshortgi_20mhz = (sta->ht_cap.cap & IEEE80211_HT_CAP_SGI_20) ? + u8 curshortgi_20mhz = (sta->deflink.ht_cap.cap & IEEE80211_HT_CAP_SGI_20) ? 1 : 0; enum wireless_mode wirelessmode = mac->mode; u32 ratr_mask; if (rtlhal->current_bandtype == BAND_ON_5G) - ratr_value = sta->supp_rates[1] << 4; + ratr_value = sta->deflink.supp_rates[1] << 4; else - ratr_value = sta->supp_rates[0]; + ratr_value = sta->deflink.supp_rates[0]; if (mac->opmode == NL80211_IFTYPE_ADHOC) ratr_value = 0xfff; - ratr_value |= (sta->ht_cap.mcs.rx_mask[1] << 20 | - sta->ht_cap.mcs.rx_mask[0] << 12); + ratr_value |= (sta->deflink.ht_cap.mcs.rx_mask[1] << 20 | + sta->deflink.ht_cap.mcs.rx_mask[0] << 12); switch (wirelessmode) { case WIRELESS_MODE_B: if (ratr_value & 0x0000000c) @@ -1853,11 +1853,11 @@ static void rtl92ce_update_hal_rate_mask(struct ieee80211_hw *hw, struct rtl_sta_info *sta_entry = NULL; u32 ratr_bitmap; u8 ratr_index; - u8 curtxbw_40mhz = (sta->ht_cap.cap & + u8 curtxbw_40mhz = (sta->deflink.ht_cap.cap & IEEE80211_HT_CAP_SUP_WIDTH_20_40) ? 1 : 0; - u8 curshortgi_40mhz = (sta->ht_cap.cap & + u8 curshortgi_40mhz = (sta->deflink.ht_cap.cap & IEEE80211_HT_CAP_SGI_40) ? 1 : 0; - u8 curshortgi_20mhz = (sta->ht_cap.cap & IEEE80211_HT_CAP_SGI_20) ? + u8 curshortgi_20mhz = (sta->deflink.ht_cap.cap & IEEE80211_HT_CAP_SGI_20) ? 1 : 0; enum wireless_mode wirelessmode = 0; bool shortgi = false; @@ -1874,13 +1874,13 @@ static void rtl92ce_update_hal_rate_mask(struct ieee80211_hw *hw, macid = sta->aid + 1; if (rtlhal->current_bandtype == BAND_ON_5G) - ratr_bitmap = sta->supp_rates[1] << 4; + ratr_bitmap = sta->deflink.supp_rates[1] << 4; else - ratr_bitmap = sta->supp_rates[0]; + ratr_bitmap = sta->deflink.supp_rates[0]; if (mac->opmode == NL80211_IFTYPE_ADHOC) ratr_bitmap = 0xfff; - ratr_bitmap |= (sta->ht_cap.mcs.rx_mask[1] << 20 | - sta->ht_cap.mcs.rx_mask[0] << 12); + ratr_bitmap |= (sta->deflink.ht_cap.mcs.rx_mask[1] << 20 | + sta->deflink.ht_cap.mcs.rx_mask[0] << 12); switch (wirelessmode) { case WIRELESS_MODE_B: ratr_index = RATR_INX_WIRELESS_B; diff --git a/drivers/net/wireless/realtek/rtlwifi/rtl8192ce/trx.c b/drivers/net/wireless/realtek/rtlwifi/rtl8192ce/trx.c index 4165175cf5c0a..fdbd3758cde18 100644 --- a/drivers/net/wireless/realtek/rtlwifi/rtl8192ce/trx.c +++ b/drivers/net/wireless/realtek/rtlwifi/rtl8192ce/trx.c @@ -379,7 +379,7 @@ void rtl92ce_tx_fill_desc(struct ieee80211_hw *hw, mac->opmode == NL80211_IFTYPE_ADHOC || mac->opmode == NL80211_IFTYPE_MESH_POINT) { if (sta) - bw_40 = sta->bandwidth >= IEEE80211_STA_RX_BW_40; + bw_40 = sta->deflink.bandwidth >= IEEE80211_STA_RX_BW_40; } seq_number = (le16_to_cpu(hdr->seq_ctrl) & IEEE80211_SCTL_SEQ) >> 4; @@ -441,7 +441,7 @@ void rtl92ce_tx_fill_desc(struct ieee80211_hw *hw, set_tx_desc_pkt_size(pdesc, (u16)skb->len); if (sta) { - u8 ampdu_density = sta->ht_cap.ampdu_density; + u8 ampdu_density = sta->deflink.ht_cap.ampdu_density; set_tx_desc_ampdu_density(pdesc, ampdu_density); } diff --git a/drivers/net/wireless/realtek/rtlwifi/rtl8192cu/hw.c b/drivers/net/wireless/realtek/rtlwifi/rtl8192cu/hw.c index eaba661133280..9bd02c3c3adcd 100644 --- a/drivers/net/wireless/realtek/rtlwifi/rtl8192cu/hw.c +++ b/drivers/net/wireless/realtek/rtlwifi/rtl8192cu/hw.c @@ -1918,21 +1918,21 @@ static void rtl92cu_update_hal_rate_table(struct ieee80211_hw *hw, u16 shortgi_rate; u32 tmp_ratr_value; u8 curtxbw_40mhz = mac->bw_40; - u8 curshortgi_40mhz = (sta->ht_cap.cap & IEEE80211_HT_CAP_SGI_40) ? + u8 curshortgi_40mhz = (sta->deflink.ht_cap.cap & IEEE80211_HT_CAP_SGI_40) ? 1 : 0; - u8 curshortgi_20mhz = (sta->ht_cap.cap & IEEE80211_HT_CAP_SGI_20) ? + u8 curshortgi_20mhz = (sta->deflink.ht_cap.cap & IEEE80211_HT_CAP_SGI_20) ? 1 : 0; enum wireless_mode wirelessmode = mac->mode; if (rtlhal->current_bandtype == BAND_ON_5G) - ratr_value = sta->supp_rates[1] << 4; + ratr_value = sta->deflink.supp_rates[1] << 4; else - ratr_value = sta->supp_rates[0]; + ratr_value = sta->deflink.supp_rates[0]; if (mac->opmode == NL80211_IFTYPE_ADHOC) ratr_value = 0xfff; - ratr_value |= (sta->ht_cap.mcs.rx_mask[1] << 20 | - sta->ht_cap.mcs.rx_mask[0] << 12); + ratr_value |= (sta->deflink.ht_cap.mcs.rx_mask[1] << 20 | + sta->deflink.ht_cap.mcs.rx_mask[0] << 12); switch (wirelessmode) { case WIRELESS_MODE_B: if (ratr_value & 0x0000000c) @@ -2003,11 +2003,11 @@ static void rtl92cu_update_hal_rate_mask(struct ieee80211_hw *hw, struct rtl_sta_info *sta_entry = NULL; u32 ratr_bitmap; u8 ratr_index; - u8 curtxbw_40mhz = (sta->bandwidth >= IEEE80211_STA_RX_BW_40) ? 1 : 0; + u8 curtxbw_40mhz = (sta->deflink.bandwidth >= IEEE80211_STA_RX_BW_40) ? 1 : 0; u8 curshortgi_40mhz = curtxbw_40mhz && - (sta->ht_cap.cap & IEEE80211_HT_CAP_SGI_40) ? + (sta->deflink.ht_cap.cap & IEEE80211_HT_CAP_SGI_40) ? 1 : 0; - u8 curshortgi_20mhz = (sta->ht_cap.cap & IEEE80211_HT_CAP_SGI_20) ? + u8 curshortgi_20mhz = (sta->deflink.ht_cap.cap & IEEE80211_HT_CAP_SGI_20) ? 1 : 0; enum wireless_mode wirelessmode = 0; bool shortgi = false; @@ -2025,13 +2025,13 @@ static void rtl92cu_update_hal_rate_mask(struct ieee80211_hw *hw, macid = sta->aid + 1; if (rtlhal->current_bandtype == BAND_ON_5G) - ratr_bitmap = sta->supp_rates[1] << 4; + ratr_bitmap = sta->deflink.supp_rates[1] << 4; else - ratr_bitmap = sta->supp_rates[0]; + ratr_bitmap = sta->deflink.supp_rates[0]; if (mac->opmode == NL80211_IFTYPE_ADHOC) ratr_bitmap = 0xfff; - ratr_bitmap |= (sta->ht_cap.mcs.rx_mask[1] << 20 | - sta->ht_cap.mcs.rx_mask[0] << 12); + ratr_bitmap |= (sta->deflink.ht_cap.mcs.rx_mask[1] << 20 | + sta->deflink.ht_cap.mcs.rx_mask[0] << 12); switch (wirelessmode) { case WIRELESS_MODE_B: ratr_index = RATR_INX_WIRELESS_B; diff --git a/drivers/net/wireless/realtek/rtlwifi/rtl8192cu/trx.c b/drivers/net/wireless/realtek/rtlwifi/rtl8192cu/trx.c index 87f959d5d861d..ae3c4f97637eb 100644 --- a/drivers/net/wireless/realtek/rtlwifi/rtl8192cu/trx.c +++ b/drivers/net/wireless/realtek/rtlwifi/rtl8192cu/trx.c @@ -540,7 +540,7 @@ void rtl92cu_tx_fill_desc(struct ieee80211_hw *hw, rcu_read_lock(); sta = ieee80211_find_sta(mac->vif, mac->bssid); if (sta) { - u8 ampdu_density = sta->ht_cap.ampdu_density; + u8 ampdu_density = sta->deflink.ht_cap.ampdu_density; set_tx_desc_ampdu_density(txdesc, ampdu_density); } diff --git a/drivers/net/wireless/realtek/rtlwifi/rtl8192de/hw.c b/drivers/net/wireless/realtek/rtlwifi/rtl8192de/hw.c index f849291cc5875..2aecb2583f75e 100644 --- a/drivers/net/wireless/realtek/rtlwifi/rtl8192de/hw.c +++ b/drivers/net/wireless/realtek/rtlwifi/rtl8192de/hw.c @@ -1802,18 +1802,18 @@ static void rtl92de_update_hal_rate_table(struct ieee80211_hw *hw, u16 shortgi_rate; u32 tmp_ratr_value; u8 curtxbw_40mhz = mac->bw_40; - u8 curshortgi_40mhz = (sta->ht_cap.cap & IEEE80211_HT_CAP_SGI_40) ? + u8 curshortgi_40mhz = (sta->deflink.ht_cap.cap & IEEE80211_HT_CAP_SGI_40) ? 1 : 0; - u8 curshortgi_20mhz = (sta->ht_cap.cap & IEEE80211_HT_CAP_SGI_20) ? + u8 curshortgi_20mhz = (sta->deflink.ht_cap.cap & IEEE80211_HT_CAP_SGI_20) ? 1 : 0; enum wireless_mode wirelessmode = mac->mode; if (rtlhal->current_bandtype == BAND_ON_5G) - ratr_value = sta->supp_rates[1] << 4; + ratr_value = sta->deflink.supp_rates[1] << 4; else - ratr_value = sta->supp_rates[0]; - ratr_value |= (sta->ht_cap.mcs.rx_mask[1] << 20 | - sta->ht_cap.mcs.rx_mask[0] << 12); + ratr_value = sta->deflink.supp_rates[0]; + ratr_value |= (sta->deflink.ht_cap.mcs.rx_mask[1] << 20 | + sta->deflink.ht_cap.mcs.rx_mask[0] << 12); switch (wirelessmode) { case WIRELESS_MODE_A: ratr_value &= 0x00000FF0; @@ -1880,10 +1880,10 @@ static void rtl92de_update_hal_rate_mask(struct ieee80211_hw *hw, struct rtl_sta_info *sta_entry = NULL; u32 ratr_bitmap; u8 ratr_index; - u8 curtxbw_40mhz = (sta->bandwidth >= IEEE80211_STA_RX_BW_40) ? 1 : 0; - u8 curshortgi_40mhz = (sta->ht_cap.cap & IEEE80211_HT_CAP_SGI_40) ? + u8 curtxbw_40mhz = (sta->deflink.bandwidth >= IEEE80211_STA_RX_BW_40) ? 1 : 0; + u8 curshortgi_40mhz = (sta->deflink.ht_cap.cap & IEEE80211_HT_CAP_SGI_40) ? 1 : 0; - u8 curshortgi_20mhz = (sta->ht_cap.cap & IEEE80211_HT_CAP_SGI_20) ? + u8 curshortgi_20mhz = (sta->deflink.ht_cap.cap & IEEE80211_HT_CAP_SGI_20) ? 1 : 0; enum wireless_mode wirelessmode = 0; bool shortgi = false; @@ -1901,11 +1901,11 @@ static void rtl92de_update_hal_rate_mask(struct ieee80211_hw *hw, macid = sta->aid + 1; if (rtlhal->current_bandtype == BAND_ON_5G) - ratr_bitmap = sta->supp_rates[1] << 4; + ratr_bitmap = sta->deflink.supp_rates[1] << 4; else - ratr_bitmap = sta->supp_rates[0]; - ratr_bitmap |= (sta->ht_cap.mcs.rx_mask[1] << 20 | - sta->ht_cap.mcs.rx_mask[0] << 12); + ratr_bitmap = sta->deflink.supp_rates[0]; + ratr_bitmap |= (sta->deflink.ht_cap.mcs.rx_mask[1] << 20 | + sta->deflink.ht_cap.mcs.rx_mask[0] << 12); switch (wirelessmode) { case WIRELESS_MODE_B: ratr_index = RATR_INX_WIRELESS_B; diff --git a/drivers/net/wireless/realtek/rtlwifi/rtl8192de/trx.c b/drivers/net/wireless/realtek/rtlwifi/rtl8192de/trx.c index c02813fba9344..807b66c16e111 100644 --- a/drivers/net/wireless/realtek/rtlwifi/rtl8192de/trx.c +++ b/drivers/net/wireless/realtek/rtlwifi/rtl8192de/trx.c @@ -498,7 +498,7 @@ void rtl92de_tx_fill_desc(struct ieee80211_hw *hw, } else if (mac->opmode == NL80211_IFTYPE_AP || mac->opmode == NL80211_IFTYPE_ADHOC) { if (sta) - bw_40 = sta->bandwidth >= IEEE80211_STA_RX_BW_40; + bw_40 = sta->deflink.bandwidth >= IEEE80211_STA_RX_BW_40; } seq_number = (le16_to_cpu(hdr->seq_ctrl) & IEEE80211_SCTL_SEQ) >> 4; rtl_get_tcb_desc(hw, info, sta, skb, ptcb_desc); @@ -586,7 +586,7 @@ void rtl92de_tx_fill_desc(struct ieee80211_hw *hw, set_tx_desc_linip(pdesc, 0); set_tx_desc_pkt_size(pdesc, (u16)skb_len); if (sta) { - u8 ampdu_density = sta->ht_cap.ampdu_density; + u8 ampdu_density = sta->deflink.ht_cap.ampdu_density; set_tx_desc_ampdu_density(pdesc, ampdu_density); } if (info->control.hw_key) { diff --git a/drivers/net/wireless/realtek/rtlwifi/rtl8192ee/hw.c b/drivers/net/wireless/realtek/rtlwifi/rtl8192ee/hw.c index 76189283104c9..47d8999e31c00 100644 --- a/drivers/net/wireless/realtek/rtlwifi/rtl8192ee/hw.c +++ b/drivers/net/wireless/realtek/rtlwifi/rtl8192ee/hw.c @@ -2256,11 +2256,11 @@ static void rtl92ee_update_hal_rate_mask(struct ieee80211_hw *hw, struct rtl_sta_info *sta_entry = NULL; u32 ratr_bitmap; u8 ratr_index; - u8 curtxbw_40mhz = (sta->ht_cap.cap & IEEE80211_HT_CAP_SUP_WIDTH_20_40) + u8 curtxbw_40mhz = (sta->deflink.ht_cap.cap & IEEE80211_HT_CAP_SUP_WIDTH_20_40) ? 1 : 0; - u8 b_curshortgi_40mhz = (sta->ht_cap.cap & IEEE80211_HT_CAP_SGI_40) ? + u8 b_curshortgi_40mhz = (sta->deflink.ht_cap.cap & IEEE80211_HT_CAP_SGI_40) ? 1 : 0; - u8 b_curshortgi_20mhz = (sta->ht_cap.cap & IEEE80211_HT_CAP_SGI_20) ? + u8 b_curshortgi_20mhz = (sta->deflink.ht_cap.cap & IEEE80211_HT_CAP_SGI_20) ? 1 : 0; enum wireless_mode wirelessmode = 0; bool b_shortgi = false; @@ -2276,12 +2276,12 @@ static void rtl92ee_update_hal_rate_mask(struct ieee80211_hw *hw, mac->opmode == NL80211_IFTYPE_ADHOC) macid = sta->aid + 1; - ratr_bitmap = sta->supp_rates[0]; + ratr_bitmap = sta->deflink.supp_rates[0]; if (mac->opmode == NL80211_IFTYPE_ADHOC) ratr_bitmap = 0xfff; - ratr_bitmap |= (sta->ht_cap.mcs.rx_mask[1] << 20 | - sta->ht_cap.mcs.rx_mask[0] << 12); + ratr_bitmap |= (sta->deflink.ht_cap.mcs.rx_mask[1] << 20 | + sta->deflink.ht_cap.mcs.rx_mask[0] << 12); switch (wirelessmode) { case WIRELESS_MODE_B: diff --git a/drivers/net/wireless/realtek/rtlwifi/rtl8192ee/trx.c b/drivers/net/wireless/realtek/rtlwifi/rtl8192ee/trx.c index eef7a041e80d8..272750612abf4 100644 --- a/drivers/net/wireless/realtek/rtlwifi/rtl8192ee/trx.c +++ b/drivers/net/wireless/realtek/rtlwifi/rtl8192ee/trx.c @@ -665,7 +665,7 @@ void rtl92ee_tx_fill_desc(struct ieee80211_hw *hw, } else if (mac->opmode == NL80211_IFTYPE_AP || mac->opmode == NL80211_IFTYPE_ADHOC) { if (sta) - bw_40 = sta->ht_cap.cap & + bw_40 = sta->deflink.ht_cap.cap & IEEE80211_HT_CAP_SUP_WIDTH_20_40; } seq_number = (le16_to_cpu(hdr->seq_ctrl) & IEEE80211_SCTL_SEQ) >> 4; @@ -759,7 +759,7 @@ void rtl92ee_tx_fill_desc(struct ieee80211_hw *hw, set_tx_desc_linip(pdesc, 0); if (sta) { - u8 ampdu_density = sta->ht_cap.ampdu_density; + u8 ampdu_density = sta->deflink.ht_cap.ampdu_density; set_tx_desc_ampdu_density(pdesc, ampdu_density); } diff --git a/drivers/net/wireless/realtek/rtlwifi/rtl8192se/hw.c b/drivers/net/wireless/realtek/rtlwifi/rtl8192se/hw.c index 91199262aacaf..4ca299c9de77c 100644 --- a/drivers/net/wireless/realtek/rtlwifi/rtl8192se/hw.c +++ b/drivers/net/wireless/realtek/rtlwifi/rtl8192se/hw.c @@ -2017,20 +2017,20 @@ static void rtl92se_update_hal_rate_table(struct ieee80211_hw *hw, u16 shortgi_rate = 0; u32 tmp_ratr_value = 0; u8 curtxbw_40mhz = mac->bw_40; - u8 curshortgi_40mhz = (sta->ht_cap.cap & IEEE80211_HT_CAP_SGI_40) ? + u8 curshortgi_40mhz = (sta->deflink.ht_cap.cap & IEEE80211_HT_CAP_SGI_40) ? 1 : 0; - u8 curshortgi_20mhz = (sta->ht_cap.cap & IEEE80211_HT_CAP_SGI_20) ? + u8 curshortgi_20mhz = (sta->deflink.ht_cap.cap & IEEE80211_HT_CAP_SGI_20) ? 1 : 0; enum wireless_mode wirelessmode = mac->mode; if (rtlhal->current_bandtype == BAND_ON_5G) - ratr_value = sta->supp_rates[1] << 4; + ratr_value = sta->deflink.supp_rates[1] << 4; else - ratr_value = sta->supp_rates[0]; + ratr_value = sta->deflink.supp_rates[0]; if (mac->opmode == NL80211_IFTYPE_ADHOC) ratr_value = 0xfff; - ratr_value |= (sta->ht_cap.mcs.rx_mask[1] << 20 | - sta->ht_cap.mcs.rx_mask[0] << 12); + ratr_value |= (sta->deflink.ht_cap.mcs.rx_mask[1] << 20 | + sta->deflink.ht_cap.mcs.rx_mask[0] << 12); switch (wirelessmode) { case WIRELESS_MODE_B: ratr_value &= 0x0000000D; @@ -2115,10 +2115,10 @@ static void rtl92se_update_hal_rate_mask(struct ieee80211_hw *hw, struct rtl_sta_info *sta_entry = NULL; u32 ratr_bitmap; u8 ratr_index = 0; - u8 curtxbw_40mhz = (sta->bandwidth >= IEEE80211_STA_RX_BW_40) ? 1 : 0; - u8 curshortgi_40mhz = (sta->ht_cap.cap & IEEE80211_HT_CAP_SGI_40) ? + u8 curtxbw_40mhz = (sta->deflink.bandwidth >= IEEE80211_STA_RX_BW_40) ? 1 : 0; + u8 curshortgi_40mhz = (sta->deflink.ht_cap.cap & IEEE80211_HT_CAP_SGI_40) ? 1 : 0; - u8 curshortgi_20mhz = (sta->ht_cap.cap & IEEE80211_HT_CAP_SGI_20) ? + u8 curshortgi_20mhz = (sta->deflink.ht_cap.cap & IEEE80211_HT_CAP_SGI_20) ? 1 : 0; enum wireless_mode wirelessmode = 0; bool shortgi = false; @@ -2139,13 +2139,13 @@ static void rtl92se_update_hal_rate_mask(struct ieee80211_hw *hw, macid = sta->aid + 1; if (rtlhal->current_bandtype == BAND_ON_5G) - ratr_bitmap = sta->supp_rates[1] << 4; + ratr_bitmap = sta->deflink.supp_rates[1] << 4; else - ratr_bitmap = sta->supp_rates[0]; + ratr_bitmap = sta->deflink.supp_rates[0]; if (mac->opmode == NL80211_IFTYPE_ADHOC) ratr_bitmap = 0xfff; - ratr_bitmap |= (sta->ht_cap.mcs.rx_mask[1] << 20 | - sta->ht_cap.mcs.rx_mask[0] << 12); + ratr_bitmap |= (sta->deflink.ht_cap.mcs.rx_mask[1] << 20 | + sta->deflink.ht_cap.mcs.rx_mask[0] << 12); switch (wirelessmode) { case WIRELESS_MODE_B: band |= WIRELESS_11B; diff --git a/drivers/net/wireless/realtek/rtlwifi/rtl8192se/trx.c b/drivers/net/wireless/realtek/rtlwifi/rtl8192se/trx.c index e474b4ec17f37..a5853a170b583 100644 --- a/drivers/net/wireless/realtek/rtlwifi/rtl8192se/trx.c +++ b/drivers/net/wireless/realtek/rtlwifi/rtl8192se/trx.c @@ -342,7 +342,7 @@ void rtl92se_tx_fill_desc(struct ieee80211_hw *hw, } else if (mac->opmode == NL80211_IFTYPE_AP || mac->opmode == NL80211_IFTYPE_ADHOC) { if (sta) - bw_40 = sta->bandwidth >= IEEE80211_STA_RX_BW_40; + bw_40 = sta->deflink.bandwidth >= IEEE80211_STA_RX_BW_40; } seq_number = (le16_to_cpu(hdr->seq_ctrl) & IEEE80211_SCTL_SEQ) >> 4; diff --git a/drivers/net/wireless/realtek/rtlwifi/rtl8723ae/hw.c b/drivers/net/wireless/realtek/rtlwifi/rtl8723ae/hw.c index c98f2216734f4..965d98b9b09f7 100644 --- a/drivers/net/wireless/realtek/rtlwifi/rtl8723ae/hw.c +++ b/drivers/net/wireless/realtek/rtlwifi/rtl8723ae/hw.c @@ -1841,21 +1841,21 @@ static void rtl8723e_update_hal_rate_table(struct ieee80211_hw *hw, u16 shortgi_rate; u32 tmp_ratr_value; u8 curtxbw_40mhz = mac->bw_40; - u8 curshortgi_40mhz = (sta->ht_cap.cap & IEEE80211_HT_CAP_SGI_40) ? + u8 curshortgi_40mhz = (sta->deflink.ht_cap.cap & IEEE80211_HT_CAP_SGI_40) ? 1 : 0; - u8 curshortgi_20mhz = (sta->ht_cap.cap & IEEE80211_HT_CAP_SGI_20) ? + u8 curshortgi_20mhz = (sta->deflink.ht_cap.cap & IEEE80211_HT_CAP_SGI_20) ? 1 : 0; enum wireless_mode wirelessmode = mac->mode; u32 ratr_mask; if (rtlhal->current_bandtype == BAND_ON_5G) - ratr_value = sta->supp_rates[1] << 4; + ratr_value = sta->deflink.supp_rates[1] << 4; else - ratr_value = sta->supp_rates[0]; + ratr_value = sta->deflink.supp_rates[0]; if (mac->opmode == NL80211_IFTYPE_ADHOC) ratr_value = 0xfff; - ratr_value |= (sta->ht_cap.mcs.rx_mask[1] << 20 | - sta->ht_cap.mcs.rx_mask[0] << 12); + ratr_value |= (sta->deflink.ht_cap.mcs.rx_mask[1] << 20 | + sta->deflink.ht_cap.mcs.rx_mask[0] << 12); switch (wirelessmode) { case WIRELESS_MODE_B: if (ratr_value & 0x0000000c) @@ -1928,11 +1928,11 @@ static void rtl8723e_update_hal_rate_mask(struct ieee80211_hw *hw, struct rtl_sta_info *sta_entry = NULL; u32 ratr_bitmap; u8 ratr_index; - u8 curtxbw_40mhz = (sta->ht_cap.cap & IEEE80211_HT_CAP_SUP_WIDTH_20_40) + u8 curtxbw_40mhz = (sta->deflink.ht_cap.cap & IEEE80211_HT_CAP_SUP_WIDTH_20_40) ? 1 : 0; - u8 curshortgi_40mhz = (sta->ht_cap.cap & IEEE80211_HT_CAP_SGI_40) ? + u8 curshortgi_40mhz = (sta->deflink.ht_cap.cap & IEEE80211_HT_CAP_SGI_40) ? 1 : 0; - u8 curshortgi_20mhz = (sta->ht_cap.cap & IEEE80211_HT_CAP_SGI_20) ? + u8 curshortgi_20mhz = (sta->deflink.ht_cap.cap & IEEE80211_HT_CAP_SGI_20) ? 1 : 0; enum wireless_mode wirelessmode = 0; bool shortgi = false; @@ -1949,13 +1949,13 @@ static void rtl8723e_update_hal_rate_mask(struct ieee80211_hw *hw, macid = sta->aid + 1; if (rtlhal->current_bandtype == BAND_ON_5G) - ratr_bitmap = sta->supp_rates[1] << 4; + ratr_bitmap = sta->deflink.supp_rates[1] << 4; else - ratr_bitmap = sta->supp_rates[0]; + ratr_bitmap = sta->deflink.supp_rates[0]; if (mac->opmode == NL80211_IFTYPE_ADHOC) ratr_bitmap = 0xfff; - ratr_bitmap |= (sta->ht_cap.mcs.rx_mask[1] << 20 | - sta->ht_cap.mcs.rx_mask[0] << 12); + ratr_bitmap |= (sta->deflink.ht_cap.mcs.rx_mask[1] << 20 | + sta->deflink.ht_cap.mcs.rx_mask[0] << 12); switch (wirelessmode) { case WIRELESS_MODE_B: ratr_index = RATR_INX_WIRELESS_B; diff --git a/drivers/net/wireless/realtek/rtlwifi/rtl8723ae/trx.c b/drivers/net/wireless/realtek/rtlwifi/rtl8723ae/trx.c index 340b3d68a54ec..3797a1e2af826 100644 --- a/drivers/net/wireless/realtek/rtlwifi/rtl8723ae/trx.c +++ b/drivers/net/wireless/realtek/rtlwifi/rtl8723ae/trx.c @@ -376,7 +376,7 @@ void rtl8723e_tx_fill_desc(struct ieee80211_hw *hw, } else if (mac->opmode == NL80211_IFTYPE_AP || mac->opmode == NL80211_IFTYPE_ADHOC) { if (sta) - bw_40 = sta->ht_cap.cap & + bw_40 = sta->deflink.ht_cap.cap & IEEE80211_HT_CAP_SUP_WIDTH_20_40; } @@ -442,7 +442,7 @@ void rtl8723e_tx_fill_desc(struct ieee80211_hw *hw, set_tx_desc_pkt_size(pdesc, (u16)skb->len); if (sta) { - u8 ampdu_density = sta->ht_cap.ampdu_density; + u8 ampdu_density = sta->deflink.ht_cap.ampdu_density; set_tx_desc_ampdu_density(pdesc, ampdu_density); } diff --git a/drivers/net/wireless/realtek/rtlwifi/rtl8723be/hw.c b/drivers/net/wireless/realtek/rtlwifi/rtl8723be/hw.c index 0748aedce2adb..189cc6437600f 100644 --- a/drivers/net/wireless/realtek/rtlwifi/rtl8723be/hw.c +++ b/drivers/net/wireless/realtek/rtlwifi/rtl8723be/hw.c @@ -2315,11 +2315,11 @@ static void rtl8723be_update_hal_rate_mask(struct ieee80211_hw *hw, struct rtl_sta_info *sta_entry = NULL; u32 ratr_bitmap; u8 ratr_index; - u8 curtxbw_40mhz = (sta->ht_cap.cap & + u8 curtxbw_40mhz = (sta->deflink.ht_cap.cap & IEEE80211_HT_CAP_SUP_WIDTH_20_40) ? 1 : 0; - u8 curshortgi_40mhz = (sta->ht_cap.cap & IEEE80211_HT_CAP_SGI_40) ? + u8 curshortgi_40mhz = (sta->deflink.ht_cap.cap & IEEE80211_HT_CAP_SGI_40) ? 1 : 0; - u8 curshortgi_20mhz = (sta->ht_cap.cap & IEEE80211_HT_CAP_SGI_20) ? + u8 curshortgi_20mhz = (sta->deflink.ht_cap.cap & IEEE80211_HT_CAP_SGI_20) ? 1 : 0; enum wireless_mode wirelessmode = 0; bool shortgi = false; @@ -2335,13 +2335,13 @@ static void rtl8723be_update_hal_rate_mask(struct ieee80211_hw *hw, mac->opmode == NL80211_IFTYPE_ADHOC) macid = sta->aid + 1; - ratr_bitmap = sta->supp_rates[0]; + ratr_bitmap = sta->deflink.supp_rates[0]; if (mac->opmode == NL80211_IFTYPE_ADHOC) ratr_bitmap = 0xfff; - ratr_bitmap |= (sta->ht_cap.mcs.rx_mask[1] << 20 | - sta->ht_cap.mcs.rx_mask[0] << 12); + ratr_bitmap |= (sta->deflink.ht_cap.mcs.rx_mask[1] << 20 | + sta->deflink.ht_cap.mcs.rx_mask[0] << 12); switch (wirelessmode) { case WIRELESS_MODE_B: ratr_index = RATR_INX_WIRELESS_B; diff --git a/drivers/net/wireless/realtek/rtlwifi/rtl8723be/trx.c b/drivers/net/wireless/realtek/rtlwifi/rtl8723be/trx.c index 5a7cd270575a2..c08f57e487e50 100644 --- a/drivers/net/wireless/realtek/rtlwifi/rtl8723be/trx.c +++ b/drivers/net/wireless/realtek/rtlwifi/rtl8723be/trx.c @@ -429,7 +429,7 @@ void rtl8723be_tx_fill_desc(struct ieee80211_hw *hw, } else if (mac->opmode == NL80211_IFTYPE_AP || mac->opmode == NL80211_IFTYPE_ADHOC) { if (sta) - bw_40 = sta->ht_cap.cap & + bw_40 = sta->deflink.ht_cap.cap & IEEE80211_HT_CAP_SUP_WIDTH_20_40; } seq_number = (le16_to_cpu(hdr->seq_ctrl) & IEEE80211_SCTL_SEQ) >> 4; @@ -516,7 +516,7 @@ void rtl8723be_tx_fill_desc(struct ieee80211_hw *hw, set_tx_desc_linip(pdesc, 0); set_tx_desc_pkt_size(pdesc, (u16)skb_len); if (sta) { - u8 ampdu_density = sta->ht_cap.ampdu_density; + u8 ampdu_density = sta->deflink.ht_cap.ampdu_density; set_tx_desc_ampdu_density(pdesc, ampdu_density); } if (info->control.hw_key) { diff --git a/drivers/net/wireless/realtek/rtlwifi/rtl8821ae/hw.c b/drivers/net/wireless/realtek/rtlwifi/rtl8821ae/hw.c index 33ffc24d36759..7e0f62d59fe17 100644 --- a/drivers/net/wireless/realtek/rtlwifi/rtl8821ae/hw.c +++ b/drivers/net/wireless/realtek/rtlwifi/rtl8821ae/hw.c @@ -3300,20 +3300,20 @@ static void rtl8821ae_update_hal_rate_table(struct ieee80211_hw *hw, u16 shortgi_rate; u32 tmp_ratr_value; u8 curtxbw_40mhz = mac->bw_40; - u8 b_curshortgi_40mhz = (sta->ht_cap.cap & IEEE80211_HT_CAP_SGI_40) ? + u8 b_curshortgi_40mhz = (sta->deflink.ht_cap.cap & IEEE80211_HT_CAP_SGI_40) ? 1 : 0; - u8 b_curshortgi_20mhz = (sta->ht_cap.cap & IEEE80211_HT_CAP_SGI_20) ? + u8 b_curshortgi_20mhz = (sta->deflink.ht_cap.cap & IEEE80211_HT_CAP_SGI_20) ? 1 : 0; enum wireless_mode wirelessmode = mac->mode; if (rtlhal->current_bandtype == BAND_ON_5G) - ratr_value = sta->supp_rates[1] << 4; + ratr_value = sta->deflink.supp_rates[1] << 4; else - ratr_value = sta->supp_rates[0]; + ratr_value = sta->deflink.supp_rates[0]; if (mac->opmode == NL80211_IFTYPE_ADHOC) ratr_value = 0xfff; - ratr_value |= (sta->ht_cap.mcs.rx_mask[1] << 20 | - sta->ht_cap.mcs.rx_mask[0] << 12); + ratr_value |= (sta->deflink.ht_cap.mcs.rx_mask[1] << 20 | + sta->deflink.ht_cap.mcs.rx_mask[0] << 12); switch (wirelessmode) { case WIRELESS_MODE_B: if (ratr_value & 0x0000000c) @@ -3484,12 +3484,12 @@ static bool _rtl8821ae_get_ra_shortgi(struct ieee80211_hw *hw, struct ieee80211_ u8 mac_id) { bool b_short_gi = false; - u8 b_curshortgi_40mhz = (sta->ht_cap.cap & IEEE80211_HT_CAP_SGI_40) ? + u8 b_curshortgi_40mhz = (sta->deflink.ht_cap.cap & IEEE80211_HT_CAP_SGI_40) ? 1 : 0; - u8 b_curshortgi_20mhz = (sta->ht_cap.cap & IEEE80211_HT_CAP_SGI_20) ? + u8 b_curshortgi_20mhz = (sta->deflink.ht_cap.cap & IEEE80211_HT_CAP_SGI_20) ? 1 : 0; u8 b_curshortgi_80mhz = 0; - b_curshortgi_80mhz = (sta->vht_cap.cap & + b_curshortgi_80mhz = (sta->deflink.vht_cap.cap & IEEE80211_VHT_CAP_SHORT_GI_80) ? 1 : 0; if (mac_id == MAC_ID_STATIC_FOR_BROADCAST_MULTICAST) @@ -3512,7 +3512,7 @@ static void rtl8821ae_update_hal_rate_mask(struct ieee80211_hw *hw, u32 ratr_bitmap; u8 ratr_index; enum wireless_mode wirelessmode = 0; - u8 curtxbw_40mhz = (sta->ht_cap.cap & IEEE80211_HT_CAP_SUP_WIDTH_20_40) + u8 curtxbw_40mhz = (sta->deflink.ht_cap.cap & IEEE80211_HT_CAP_SUP_WIDTH_20_40) ? 1 : 0; bool b_shortgi = false; u8 rate_mask[7]; @@ -3534,22 +3534,22 @@ static void rtl8821ae_update_hal_rate_mask(struct ieee80211_hw *hw, if (wirelessmode == WIRELESS_MODE_N_5G || wirelessmode == WIRELESS_MODE_AC_5G || wirelessmode == WIRELESS_MODE_A) - ratr_bitmap = sta->supp_rates[NL80211_BAND_5GHZ] << 4; + ratr_bitmap = sta->deflink.supp_rates[NL80211_BAND_5GHZ] << 4; else - ratr_bitmap = sta->supp_rates[NL80211_BAND_2GHZ]; + ratr_bitmap = sta->deflink.supp_rates[NL80211_BAND_2GHZ]; if (mac->opmode == NL80211_IFTYPE_ADHOC) ratr_bitmap = 0xfff; if (wirelessmode == WIRELESS_MODE_N_24G || wirelessmode == WIRELESS_MODE_N_5G) - ratr_bitmap |= (sta->ht_cap.mcs.rx_mask[1] << 20 | - sta->ht_cap.mcs.rx_mask[0] << 12); + ratr_bitmap |= (sta->deflink.ht_cap.mcs.rx_mask[1] << 20 | + sta->deflink.ht_cap.mcs.rx_mask[0] << 12); else if (wirelessmode == WIRELESS_MODE_AC_24G || wirelessmode == WIRELESS_MODE_AC_5G || wirelessmode == WIRELESS_MODE_AC_ONLY) ratr_bitmap |= _rtl8821ae_rate_to_bitmap_2ssvht( - sta->vht_cap.vht_mcs.rx_mcs_map) << 12; + sta->deflink.vht_cap.vht_mcs.rx_mcs_map) << 12; b_shortgi = _rtl8821ae_get_ra_shortgi(hw, sta, macid); rf_type = _rtl8821ae_get_ra_rftype(hw, wirelessmode, ratr_bitmap); diff --git a/drivers/net/wireless/realtek/rtlwifi/rtl8821ae/trx.c b/drivers/net/wireless/realtek/rtlwifi/rtl8821ae/trx.c index 9d6f8dcbf2d63..8c48108960b9c 100644 --- a/drivers/net/wireless/realtek/rtlwifi/rtl8821ae/trx.c +++ b/drivers/net/wireless/realtek/rtlwifi/rtl8821ae/trx.c @@ -761,7 +761,7 @@ void rtl8821ae_tx_fill_desc(struct ieee80211_hw *hw, set_tx_desc_linip(pdesc, 0); set_tx_desc_pkt_size(pdesc, (u16)skb_len); if (sta) { - u8 ampdu_density = sta->ht_cap.ampdu_density; + u8 ampdu_density = sta->deflink.ht_cap.ampdu_density; set_tx_desc_ampdu_density(pdesc, ampdu_density); } diff --git a/drivers/net/wireless/realtek/rtw88/bf.c b/drivers/net/wireless/realtek/rtw88/bf.c index df750b3a35e9d..e76841d3417b0 100644 --- a/drivers/net/wireless/realtek/rtw88/bf.c +++ b/drivers/net/wireless/realtek/rtw88/bf.c @@ -55,7 +55,7 @@ void rtw_bf_assoc(struct rtw_dev *rtwdev, struct ieee80211_vif *vif, } ic_vht_cap = &hw->wiphy->bands[NL80211_BAND_5GHZ]->vht_cap; - vht_cap = &sta->vht_cap; + vht_cap = &sta->deflink.vht_cap; if ((ic_vht_cap->cap & IEEE80211_VHT_CAP_MU_BEAMFORMEE_CAPABLE) && (vht_cap->cap & IEEE80211_VHT_CAP_MU_BEAMFORMER_CAPABLE)) { diff --git a/drivers/net/wireless/realtek/rtw88/main.c b/drivers/net/wireless/realtek/rtw88/main.c index b57f9262f5909..1a4c8c989ce93 100644 --- a/drivers/net/wireless/realtek/rtw88/main.c +++ b/drivers/net/wireless/realtek/rtw88/main.c @@ -904,7 +904,7 @@ static void rtw_hw_config_rf_ant_num(struct rtw_dev *rtwdev, u8 hw_ant_num) static u64 get_vht_ra_mask(struct ieee80211_sta *sta) { u64 ra_mask = 0; - u16 mcs_map = le16_to_cpu(sta->vht_cap.vht_mcs.rx_mcs_map); + u16 mcs_map = le16_to_cpu(sta->deflink.vht_cap.vht_mcs.rx_mcs_map); u8 vht_mcs_cap; int i, nss; @@ -1123,19 +1123,19 @@ void rtw_update_sta_info(struct rtw_dev *rtwdev, struct rtw_sta_info *si) bool is_vht_enable = false; bool is_support_sgi = false; - if (sta->vht_cap.vht_supported) { + if (sta->deflink.vht_cap.vht_supported) { is_vht_enable = true; ra_mask |= get_vht_ra_mask(sta); - if (sta->vht_cap.cap & IEEE80211_VHT_CAP_RXSTBC_MASK) + if (sta->deflink.vht_cap.cap & IEEE80211_VHT_CAP_RXSTBC_MASK) stbc_en = VHT_STBC_EN; - if (sta->vht_cap.cap & IEEE80211_VHT_CAP_RXLDPC) + if (sta->deflink.vht_cap.cap & IEEE80211_VHT_CAP_RXLDPC) ldpc_en = VHT_LDPC_EN; - } else if (sta->ht_cap.ht_supported) { - ra_mask |= (sta->ht_cap.mcs.rx_mask[1] << 20) | - (sta->ht_cap.mcs.rx_mask[0] << 12); - if (sta->ht_cap.cap & IEEE80211_HT_CAP_RX_STBC) + } else if (sta->deflink.ht_cap.ht_supported) { + ra_mask |= (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; - if (sta->ht_cap.cap & IEEE80211_HT_CAP_LDPC_CODING) + if (sta->deflink.ht_cap.cap & IEEE80211_HT_CAP_LDPC_CODING) ldpc_en = HT_LDPC_EN; } @@ -1143,12 +1143,12 @@ void rtw_update_sta_info(struct rtw_dev *rtwdev, struct rtw_sta_info *si) ra_mask &= RA_MASK_VHT_RATES_1SS | RA_MASK_HT_RATES_1SS; if (hal->current_band_type == RTW_BAND_5G) { - ra_mask |= (u64)sta->supp_rates[NL80211_BAND_5GHZ] << 4; + ra_mask |= (u64)sta->deflink.supp_rates[NL80211_BAND_5GHZ] << 4; ra_mask_bak = ra_mask; - if (sta->vht_cap.vht_supported) { + if (sta->deflink.vht_cap.vht_supported) { ra_mask &= RA_MASK_VHT_RATES | RA_MASK_OFDM_IN_VHT; wireless_set = WIRELESS_OFDM | WIRELESS_VHT; - } else if (sta->ht_cap.ht_supported) { + } else if (sta->deflink.ht_cap.ht_supported) { ra_mask &= RA_MASK_HT_RATES | RA_MASK_OFDM_IN_HT_5G; wireless_set = WIRELESS_OFDM | WIRELESS_HT; } else { @@ -1156,19 +1156,19 @@ void rtw_update_sta_info(struct rtw_dev *rtwdev, struct rtw_sta_info *si) } dm_info->rrsr_val_init = RRSR_INIT_5G; } else if (hal->current_band_type == RTW_BAND_2G) { - ra_mask |= sta->supp_rates[NL80211_BAND_2GHZ]; + ra_mask |= sta->deflink.supp_rates[NL80211_BAND_2GHZ]; ra_mask_bak = ra_mask; - if (sta->vht_cap.vht_supported) { + if (sta->deflink.vht_cap.vht_supported) { ra_mask &= RA_MASK_VHT_RATES | RA_MASK_CCK_IN_VHT | RA_MASK_OFDM_IN_VHT; wireless_set = WIRELESS_CCK | WIRELESS_OFDM | WIRELESS_HT | WIRELESS_VHT; - } else if (sta->ht_cap.ht_supported) { + } else if (sta->deflink.ht_cap.ht_supported) { ra_mask &= RA_MASK_HT_RATES | RA_MASK_CCK_IN_HT | RA_MASK_OFDM_IN_HT_2G; wireless_set = WIRELESS_CCK | WIRELESS_OFDM | WIRELESS_HT; - } else if (sta->supp_rates[0] <= 0xf) { + } else if (sta->deflink.supp_rates[0] <= 0xf) { wireless_set = WIRELESS_CCK; } else { ra_mask &= RA_MASK_OFDM_RATES | RA_MASK_CCK_IN_BG; @@ -1181,28 +1181,28 @@ void rtw_update_sta_info(struct rtw_dev *rtwdev, struct rtw_sta_info *si) wireless_set = 0; } - switch (sta->bandwidth) { + switch (sta->deflink.bandwidth) { case IEEE80211_STA_RX_BW_80: bw_mode = RTW_CHANNEL_WIDTH_80; - is_support_sgi = sta->vht_cap.vht_supported && - (sta->vht_cap.cap & IEEE80211_VHT_CAP_SHORT_GI_80); + is_support_sgi = sta->deflink.vht_cap.vht_supported && + (sta->deflink.vht_cap.cap & IEEE80211_VHT_CAP_SHORT_GI_80); break; case IEEE80211_STA_RX_BW_40: bw_mode = RTW_CHANNEL_WIDTH_40; - is_support_sgi = sta->ht_cap.ht_supported && - (sta->ht_cap.cap & IEEE80211_HT_CAP_SGI_40); + is_support_sgi = sta->deflink.ht_cap.ht_supported && + (sta->deflink.ht_cap.cap & IEEE80211_HT_CAP_SGI_40); break; default: bw_mode = RTW_CHANNEL_WIDTH_20; - is_support_sgi = sta->ht_cap.ht_supported && - (sta->ht_cap.cap & IEEE80211_HT_CAP_SGI_20); + is_support_sgi = sta->deflink.ht_cap.ht_supported && + (sta->deflink.ht_cap.cap & IEEE80211_HT_CAP_SGI_20); break; } - if (sta->vht_cap.vht_supported && ra_mask & 0xffc00000) { + if (sta->deflink.vht_cap.vht_supported && ra_mask & 0xffc00000) { tx_num = 2; rf_type = RF_2T2R; - } else if (sta->ht_cap.ht_supported && ra_mask & 0xfff00000) { + } else if (sta->deflink.ht_cap.ht_supported && ra_mask & 0xfff00000) { tx_num = 2; rf_type = RF_2T2R; } diff --git a/drivers/net/wireless/realtek/rtw88/tx.c b/drivers/net/wireless/realtek/rtw88/tx.c index 94d1089f40220..83248da0237f6 100644 --- a/drivers/net/wireless/realtek/rtw88/tx.c +++ b/drivers/net/wireless/realtek/rtw88/tx.c @@ -72,7 +72,7 @@ EXPORT_SYMBOL(rtw_tx_fill_tx_desc); static u8 get_tx_ampdu_factor(struct ieee80211_sta *sta) { - u8 exp = sta->ht_cap.ampdu_factor; + u8 exp = sta->deflink.ht_cap.ampdu_factor; /* the least ampdu factor is 8K, and the value in the tx desc is the * max aggregation num, which represents val * 2 packets can be @@ -83,7 +83,7 @@ static u8 get_tx_ampdu_factor(struct ieee80211_sta *sta) static u8 get_tx_ampdu_density(struct ieee80211_sta *sta) { - return sta->ht_cap.ampdu_density; + return sta->deflink.ht_cap.ampdu_density; } static u8 get_highest_ht_tx_rate(struct rtw_dev *rtwdev, @@ -91,7 +91,7 @@ static u8 get_highest_ht_tx_rate(struct rtw_dev *rtwdev, { u8 rate; - if (rtwdev->hal.rf_type == RF_2T2R && sta->ht_cap.mcs.rx_mask[1] != 0) + if (rtwdev->hal.rf_type == RF_2T2R && sta->deflink.ht_cap.mcs.rx_mask[1] != 0) rate = DESC_RATEMCS15; else rate = DESC_RATEMCS7; @@ -106,7 +106,7 @@ static u8 get_highest_vht_tx_rate(struct rtw_dev *rtwdev, u8 rate; u16 tx_mcs_map; - tx_mcs_map = le16_to_cpu(sta->vht_cap.vht_mcs.tx_mcs_map); + tx_mcs_map = le16_to_cpu(sta->deflink.vht_cap.vht_mcs.tx_mcs_map); if (efuse->hw_cap.nss == 1) { switch (tx_mcs_map & 0x3) { case IEEE80211_VHT_MCS_SUPPORT_0_7: @@ -340,11 +340,11 @@ static void rtw_tx_data_pkt_info_update(struct rtw_dev *rtwdev, if (info->control.use_rts || skb->len > hw->wiphy->rts_threshold) pkt_info->rts = true; - if (sta->vht_cap.vht_supported) + if (sta->deflink.vht_cap.vht_supported) rate = get_highest_vht_tx_rate(rtwdev, sta); - else if (sta->ht_cap.ht_supported) + else if (sta->deflink.ht_cap.ht_supported) rate = get_highest_ht_tx_rate(rtwdev, sta); - else if (sta->supp_rates[0] <= 0xf) + else if (sta->deflink.supp_rates[0] <= 0xf) rate = DESC_RATE11M; else rate = DESC_RATE54M; diff --git a/drivers/net/wireless/realtek/rtw89/coex.c b/drivers/net/wireless/realtek/rtw89/coex.c index 3d5664cc3a203..683854bba217b 100644 --- a/drivers/net/wireless/realtek/rtw89/coex.c +++ b/drivers/net/wireless/realtek/rtw89/coex.c @@ -4179,14 +4179,14 @@ void rtw89_btc_ntfy_role_info(struct rtw89_dev *rtwdev, struct rtw89_vif *rtwvif rtw89_debug(rtwdev, RTW89_DBG_BTC, "[BTC], STA support HE=%d VHT=%d HT=%d\n", - sta->he_cap.has_he, - sta->vht_cap.vht_supported, - sta->ht_cap.ht_supported); - if (sta->he_cap.has_he) + sta->deflink.he_cap.has_he, + sta->deflink.vht_cap.vht_supported, + sta->deflink.ht_cap.ht_supported); + if (sta->deflink.he_cap.has_he) mode |= BIT(BTC_WL_MODE_HE); - if (sta->vht_cap.vht_supported) + if (sta->deflink.vht_cap.vht_supported) mode |= BIT(BTC_WL_MODE_VHT); - if (sta->ht_cap.ht_supported) + if (sta->deflink.ht_cap.ht_supported) mode |= BIT(BTC_WL_MODE_HT); r.mode = mode; diff --git a/drivers/net/wireless/realtek/rtw89/core.c b/drivers/net/wireless/realtek/rtw89/core.c index 89506daa54cc2..6e8a65b021ce4 100644 --- a/drivers/net/wireless/realtek/rtw89/core.c +++ b/drivers/net/wireless/realtek/rtw89/core.c @@ -424,10 +424,10 @@ rtw89_core_tx_update_ampdu_info(struct rtw89_dev *rtwdev, ampdu_num = (u8)((rtwsta->ampdu_params[tid].agg_num ? rtwsta->ampdu_params[tid].agg_num : - 4 << sta->ht_cap.ampdu_factor) - 1); + 4 << sta->deflink.ht_cap.ampdu_factor) - 1); desc_info->agg_en = true; - desc_info->ampdu_density = sta->ht_cap.ampdu_density; + desc_info->ampdu_density = sta->deflink.ht_cap.ampdu_density; desc_info->ampdu_num = ampdu_num; } @@ -612,7 +612,7 @@ __rtw89_core_tx_check_he_qos_htc(struct rtw89_dev *rtwdev, if (pkt_type < PACKET_MAX) return false; - if (!sta || !sta->he_cap.has_he) + if (!sta || !sta->deflink.he_cap.has_he) return false; if (!ieee80211_is_data_qos(fc)) diff --git a/drivers/net/wireless/realtek/rtw89/core.h b/drivers/net/wireless/realtek/rtw89/core.h index ee2edd9e9173a..fdf593e686609 100644 --- a/drivers/net/wireless/realtek/rtw89/core.h +++ b/drivers/net/wireless/realtek/rtw89/core.h @@ -3601,10 +3601,12 @@ static inline u8 *get_hdr_bssid(struct ieee80211_hdr *hdr) static inline bool rtw89_sta_has_beamformer_cap(struct ieee80211_sta *sta) { - if ((sta->vht_cap.cap & IEEE80211_VHT_CAP_MU_BEAMFORMER_CAPABLE) || - (sta->vht_cap.cap & IEEE80211_VHT_CAP_SU_BEAMFORMER_CAPABLE) || - (sta->he_cap.he_cap_elem.phy_cap_info[3] & IEEE80211_HE_PHY_CAP3_SU_BEAMFORMER) || - (sta->he_cap.he_cap_elem.phy_cap_info[4] & IEEE80211_HE_PHY_CAP4_MU_BEAMFORMER)) + if ((sta->deflink.vht_cap.cap & IEEE80211_VHT_CAP_MU_BEAMFORMER_CAPABLE) || + (sta->deflink.vht_cap.cap & IEEE80211_VHT_CAP_SU_BEAMFORMER_CAPABLE) || + (sta->deflink.he_cap.he_cap_elem.phy_cap_info[3] & + IEEE80211_HE_PHY_CAP3_SU_BEAMFORMER) || + (sta->deflink.he_cap.he_cap_elem.phy_cap_info[4] & + IEEE80211_HE_PHY_CAP4_MU_BEAMFORMER)) return true; return false; } diff --git a/drivers/net/wireless/realtek/rtw89/fw.c b/drivers/net/wireless/realtek/rtw89/fw.c index fc77d9bfd6260..986d6249c1084 100644 --- a/drivers/net/wireless/realtek/rtw89/fw.c +++ b/drivers/net/wireless/realtek/rtw89/fw.c @@ -831,23 +831,23 @@ static void __get_sta_he_pkt_padding(struct rtw89_dev *rtwdev, { bool ppe_th; u8 ppe16, ppe8; - u8 nss = min(sta->rx_nss, rtwdev->hal.tx_nss) - 1; - u8 ppe_thres_hdr = sta->he_cap.ppe_thres[0]; + u8 nss = min(sta->deflink.rx_nss, rtwdev->hal.tx_nss) - 1; + u8 ppe_thres_hdr = sta->deflink.he_cap.ppe_thres[0]; u8 ru_bitmap; u8 n, idx, sh; u16 ppe; int i; - if (!sta->he_cap.has_he) + if (!sta->deflink.he_cap.has_he) return; ppe_th = FIELD_GET(IEEE80211_HE_PHY_CAP6_PPE_THRESHOLD_PRESENT, - sta->he_cap.he_cap_elem.phy_cap_info[6]); + sta->deflink.he_cap.he_cap_elem.phy_cap_info[6]); if (!ppe_th) { u8 pad; pad = FIELD_GET(IEEE80211_HE_PHY_CAP9_NOMINAL_PKT_PADDING_MASK, - sta->he_cap.he_cap_elem.phy_cap_info[9]); + sta->deflink.he_cap.he_cap_elem.phy_cap_info[9]); for (i = 0; i < RTW89_PPE_BW_NUM; i++) pads[i] = pad; @@ -867,7 +867,7 @@ static void __get_sta_he_pkt_padding(struct rtw89_dev *rtwdev, sh = n & 7; n += IEEE80211_PPE_THRES_INFO_PPET_SIZE * 2; - ppe = le16_to_cpu(*((__le16 *)&sta->he_cap.ppe_thres[idx])); + ppe = le16_to_cpu(*((__le16 *)&sta->deflink.he_cap.ppe_thres[idx])); ppe16 = (ppe >> sh) & IEEE80211_PPE_THRES_NSS_MASK; sh += IEEE80211_PPE_THRES_INFO_PPET_SIZE; ppe8 = (ppe >> sh) & IEEE80211_PPE_THRES_NSS_MASK; @@ -921,7 +921,8 @@ int rtw89_fw_h2c_assoc_cmac_tbl(struct rtw89_dev *rtwdev, SET_CMC_TBL_NOMINAL_PKT_PADDING40(skb->data, pads[RTW89_CHANNEL_WIDTH_40]); SET_CMC_TBL_NOMINAL_PKT_PADDING80(skb->data, pads[RTW89_CHANNEL_WIDTH_80]); if (sta) - SET_CMC_TBL_BSR_QUEUE_SIZE_FORMAT(skb->data, sta->he_cap.has_he); + SET_CMC_TBL_BSR_QUEUE_SIZE_FORMAT(skb->data, + sta->deflink.he_cap.has_he); if (rtwvif->net_type == RTW89_NET_TYPE_AP_MODE) SET_CMC_TBL_DATA_DCM(skb->data, 0); diff --git a/drivers/net/wireless/realtek/rtw89/mac.c b/drivers/net/wireless/realtek/rtw89/mac.c index 34e14a53a5851..c28f5a7c23b5e 100644 --- a/drivers/net/wireless/realtek/rtw89/mac.c +++ b/drivers/net/wireless/realtek/rtw89/mac.c @@ -3995,7 +3995,7 @@ static int rtw89_mac_set_csi_para_reg(struct rtw89_dev *rtwdev, u8 nc = 1, nr = 3, ng = 0, cb = 1, cs = 1, ldpc_en = 1, stbc_en = 1; u8 port_sel = rtwvif->port; u8 sound_dim = 3, t; - u8 *phy_cap = sta->he_cap.he_cap_elem.phy_cap_info; + u8 *phy_cap = sta->deflink.he_cap.he_cap_elem.phy_cap_info; u32 reg; u16 val; int ret; @@ -4012,12 +4012,12 @@ static int rtw89_mac_set_csi_para_reg(struct rtw89_dev *rtwdev, phy_cap[5]); sound_dim = min(sound_dim, t); } - if ((sta->vht_cap.cap & IEEE80211_VHT_CAP_MU_BEAMFORMER_CAPABLE) || - (sta->vht_cap.cap & IEEE80211_VHT_CAP_SU_BEAMFORMER_CAPABLE)) { - ldpc_en &= !!(sta->vht_cap.cap & IEEE80211_VHT_CAP_RXLDPC); - stbc_en &= !!(sta->vht_cap.cap & IEEE80211_VHT_CAP_RXSTBC_MASK); + if ((sta->deflink.vht_cap.cap & IEEE80211_VHT_CAP_MU_BEAMFORMER_CAPABLE) || + (sta->deflink.vht_cap.cap & IEEE80211_VHT_CAP_SU_BEAMFORMER_CAPABLE)) { + ldpc_en &= !!(sta->deflink.vht_cap.cap & IEEE80211_VHT_CAP_RXLDPC); + stbc_en &= !!(sta->deflink.vht_cap.cap & IEEE80211_VHT_CAP_RXSTBC_MASK); t = FIELD_GET(IEEE80211_VHT_CAP_SOUNDING_DIMENSIONS_MASK, - sta->vht_cap.cap); + sta->deflink.vht_cap.cap); sound_dim = min(sound_dim, t); } nc = min(nc, sound_dim); @@ -4058,17 +4058,17 @@ static int rtw89_mac_csi_rrsc(struct rtw89_dev *rtwdev, if (ret) return ret; - if (sta->he_cap.has_he) { + if (sta->deflink.he_cap.has_he) { rrsc |= (BIT(RTW89_MAC_BF_RRSC_HE_MSC0) | BIT(RTW89_MAC_BF_RRSC_HE_MSC3) | BIT(RTW89_MAC_BF_RRSC_HE_MSC5)); } - if (sta->vht_cap.vht_supported) { + if (sta->deflink.vht_cap.vht_supported) { rrsc |= (BIT(RTW89_MAC_BF_RRSC_VHT_MSC0) | BIT(RTW89_MAC_BF_RRSC_VHT_MSC3) | BIT(RTW89_MAC_BF_RRSC_VHT_MSC5)); } - if (sta->ht_cap.ht_supported) { + if (sta->deflink.ht_cap.ht_supported) { rrsc |= (BIT(RTW89_MAC_BF_RRSC_HT_MSC0) | BIT(RTW89_MAC_BF_RRSC_HT_MSC3) | BIT(RTW89_MAC_BF_RRSC_HT_MSC5)); diff --git a/drivers/net/wireless/realtek/rtw89/phy.c b/drivers/net/wireless/realtek/rtw89/phy.c index 193afb1f53f5a..994869f720806 100644 --- a/drivers/net/wireless/realtek/rtw89/phy.c +++ b/drivers/net/wireless/realtek/rtw89/phy.c @@ -76,10 +76,10 @@ static u64 get_mcs_ra_mask(u16 mcs_map, u8 highest_mcs, u8 gap) static u64 get_he_ra_mask(struct ieee80211_sta *sta) { - struct ieee80211_sta_he_cap cap = sta->he_cap; + struct ieee80211_sta_he_cap cap = sta->deflink.he_cap; u16 mcs_map; - switch (sta->bandwidth) { + switch (sta->deflink.bandwidth) { case IEEE80211_STA_RX_BW_160: if (cap.he_cap_elem.phy_cap_info[0] & IEEE80211_HE_PHY_CAP0_CHANNEL_WIDTH_SET_80PLUS80_MHZ_IN_5G) @@ -172,17 +172,17 @@ static u64 rtw89_phy_ra_mask_cfg(struct rtw89_dev *rtwdev, struct rtw89_sta *rtw return -1; } - if (sta->he_cap.has_he) { + if (sta->deflink.he_cap.has_he) { cfg_mask |= u64_encode_bits(mask->control[band].he_mcs[0], RA_MASK_HE_1SS_RATES); cfg_mask |= u64_encode_bits(mask->control[band].he_mcs[1], RA_MASK_HE_2SS_RATES); - } else if (sta->vht_cap.vht_supported) { + } else if (sta->deflink.vht_cap.vht_supported) { cfg_mask |= u64_encode_bits(mask->control[band].vht_mcs[0], RA_MASK_VHT_1SS_RATES); cfg_mask |= u64_encode_bits(mask->control[band].vht_mcs[1], RA_MASK_VHT_2SS_RATES); - } else if (sta->ht_cap.ht_supported) { + } else if (sta->deflink.ht_cap.ht_supported) { cfg_mask |= u64_encode_bits(mask->control[band].ht_mcs[0], RA_MASK_HT_1SS_RATES); cfg_mask |= u64_encode_bits(mask->control[band].ht_mcs[1], @@ -223,57 +223,57 @@ static void rtw89_phy_ra_sta_update(struct rtw89_dev *rtwdev, memset(ra, 0, sizeof(*ra)); /* Set the ra mask from sta's capability */ - if (sta->he_cap.has_he) { + if (sta->deflink.he_cap.has_he) { mode |= RTW89_RA_MODE_HE; csi_mode = RTW89_RA_RPT_MODE_HE; ra_mask |= get_he_ra_mask(sta); high_rate_masks = rtw89_ra_mask_he_rates; - if (sta->he_cap.he_cap_elem.phy_cap_info[2] & + if (sta->deflink.he_cap.he_cap_elem.phy_cap_info[2] & IEEE80211_HE_PHY_CAP2_STBC_RX_UNDER_80MHZ) stbc_en = 1; - if (sta->he_cap.he_cap_elem.phy_cap_info[1] & + if (sta->deflink.he_cap.he_cap_elem.phy_cap_info[1] & IEEE80211_HE_PHY_CAP1_LDPC_CODING_IN_PAYLOAD) ldpc_en = 1; - } else if (sta->vht_cap.vht_supported) { - u16 mcs_map = le16_to_cpu(sta->vht_cap.vht_mcs.rx_mcs_map); + } else if (sta->deflink.vht_cap.vht_supported) { + u16 mcs_map = le16_to_cpu(sta->deflink.vht_cap.vht_mcs.rx_mcs_map); mode |= RTW89_RA_MODE_VHT; csi_mode = RTW89_RA_RPT_MODE_VHT; /* MCS9, MCS8, MCS7 */ ra_mask |= get_mcs_ra_mask(mcs_map, 9, 1); high_rate_masks = rtw89_ra_mask_vht_rates; - if (sta->vht_cap.cap & IEEE80211_VHT_CAP_RXSTBC_MASK) + if (sta->deflink.vht_cap.cap & IEEE80211_VHT_CAP_RXSTBC_MASK) stbc_en = 1; - if (sta->vht_cap.cap & IEEE80211_VHT_CAP_RXLDPC) + if (sta->deflink.vht_cap.cap & IEEE80211_VHT_CAP_RXLDPC) ldpc_en = 1; - } else if (sta->ht_cap.ht_supported) { + } else if (sta->deflink.ht_cap.ht_supported) { mode |= RTW89_RA_MODE_HT; csi_mode = RTW89_RA_RPT_MODE_HT; - ra_mask |= ((u64)sta->ht_cap.mcs.rx_mask[3] << 48) | - ((u64)sta->ht_cap.mcs.rx_mask[2] << 36) | - (sta->ht_cap.mcs.rx_mask[1] << 24) | - (sta->ht_cap.mcs.rx_mask[0] << 12); + ra_mask |= ((u64)sta->deflink.ht_cap.mcs.rx_mask[3] << 48) | + ((u64)sta->deflink.ht_cap.mcs.rx_mask[2] << 36) | + (sta->deflink.ht_cap.mcs.rx_mask[1] << 24) | + (sta->deflink.ht_cap.mcs.rx_mask[0] << 12); high_rate_masks = rtw89_ra_mask_ht_rates; - if (sta->ht_cap.cap & IEEE80211_HT_CAP_RX_STBC) + if (sta->deflink.ht_cap.cap & IEEE80211_HT_CAP_RX_STBC) stbc_en = 1; - if (sta->ht_cap.cap & IEEE80211_HT_CAP_LDPC_CODING) + if (sta->deflink.ht_cap.cap & IEEE80211_HT_CAP_LDPC_CODING) ldpc_en = 1; } switch (rtwdev->hal.current_band_type) { case RTW89_BAND_2G: - ra_mask |= sta->supp_rates[NL80211_BAND_2GHZ]; - if (sta->supp_rates[NL80211_BAND_2GHZ] <= 0xf) + ra_mask |= sta->deflink.supp_rates[NL80211_BAND_2GHZ]; + if (sta->deflink.supp_rates[NL80211_BAND_2GHZ] <= 0xf) mode |= RTW89_RA_MODE_CCK; else mode |= RTW89_RA_MODE_CCK | RTW89_RA_MODE_OFDM; break; case RTW89_BAND_5G: - ra_mask |= (u64)sta->supp_rates[NL80211_BAND_5GHZ] << 4; + ra_mask |= (u64)sta->deflink.supp_rates[NL80211_BAND_5GHZ] << 4; mode |= RTW89_RA_MODE_OFDM; break; case RTW89_BAND_6G: - ra_mask |= (u64)sta->supp_rates[NL80211_BAND_6GHZ] << 4; + ra_mask |= (u64)sta->deflink.supp_rates[NL80211_BAND_6GHZ] << 4; mode |= RTW89_RA_MODE_OFDM; break; default: @@ -302,30 +302,30 @@ static void rtw89_phy_ra_sta_update(struct rtw89_dev *rtwdev, ra_mask = rtw89_phy_ra_mask_recover(ra_mask, ra_mask_bak); ra_mask &= rtw89_phy_ra_mask_cfg(rtwdev, rtwsta); - switch (sta->bandwidth) { + switch (sta->deflink.bandwidth) { case IEEE80211_STA_RX_BW_160: bw_mode = RTW89_CHANNEL_WIDTH_160; - sgi = sta->vht_cap.vht_supported && - (sta->vht_cap.cap & IEEE80211_VHT_CAP_SHORT_GI_160); + sgi = sta->deflink.vht_cap.vht_supported && + (sta->deflink.vht_cap.cap & IEEE80211_VHT_CAP_SHORT_GI_160); break; case IEEE80211_STA_RX_BW_80: bw_mode = RTW89_CHANNEL_WIDTH_80; - sgi = sta->vht_cap.vht_supported && - (sta->vht_cap.cap & IEEE80211_VHT_CAP_SHORT_GI_80); + sgi = sta->deflink.vht_cap.vht_supported && + (sta->deflink.vht_cap.cap & IEEE80211_VHT_CAP_SHORT_GI_80); break; case IEEE80211_STA_RX_BW_40: bw_mode = RTW89_CHANNEL_WIDTH_40; - sgi = sta->ht_cap.ht_supported && - (sta->ht_cap.cap & IEEE80211_HT_CAP_SGI_40); + sgi = sta->deflink.ht_cap.ht_supported && + (sta->deflink.ht_cap.cap & IEEE80211_HT_CAP_SGI_40); break; default: bw_mode = RTW89_CHANNEL_WIDTH_20; - sgi = sta->ht_cap.ht_supported && - (sta->ht_cap.cap & IEEE80211_HT_CAP_SGI_20); + sgi = sta->deflink.ht_cap.ht_supported && + (sta->deflink.ht_cap.cap & IEEE80211_HT_CAP_SGI_20); break; } - if (sta->he_cap.he_cap_elem.phy_cap_info[3] & + if (sta->deflink.he_cap.he_cap_elem.phy_cap_info[3] & IEEE80211_HE_PHY_CAP3_DCM_MAX_CONST_RX_16_QAM) ra->dcm_cap = 1; @@ -340,7 +340,7 @@ static void rtw89_phy_ra_sta_update(struct rtw89_dev *rtwdev, ra->macid = rtwsta->mac_id; ra->stbc_cap = stbc_en; ra->ldpc_cap = ldpc_en; - ra->ss_num = min(sta->rx_nss, rtwdev->hal.tx_nss) - 1; + ra->ss_num = min(sta->deflink.rx_nss, rtwdev->hal.tx_nss) - 1; ra->en_sgi = sgi; ra->ra_mask = ra_mask; diff --git a/drivers/net/wireless/rsi/rsi_91x_mac80211.c b/drivers/net/wireless/rsi/rsi_91x_mac80211.c index 913e11fb38072..f01e82b90c07a 100644 --- a/drivers/net/wireless/rsi/rsi_91x_mac80211.c +++ b/drivers/net/wireless/rsi/rsi_91x_mac80211.c @@ -1490,13 +1490,13 @@ static int rsi_mac80211_sta_add(struct ieee80211_hw *hw, if ((vif->type == NL80211_IFTYPE_STATION) || (vif->type == NL80211_IFTYPE_P2P_CLIENT)) { - common->bitrate_mask[common->band] = sta->supp_rates[common->band]; - common->vif_info[0].is_ht = sta->ht_cap.ht_supported; - if (sta->ht_cap.ht_supported) { + common->bitrate_mask[common->band] = sta->deflink.supp_rates[common->band]; + common->vif_info[0].is_ht = sta->deflink.ht_cap.ht_supported; + if (sta->deflink.ht_cap.ht_supported) { common->bitrate_mask[NL80211_BAND_2GHZ] = - sta->supp_rates[NL80211_BAND_2GHZ]; - if ((sta->ht_cap.cap & IEEE80211_HT_CAP_SGI_20) || - (sta->ht_cap.cap & IEEE80211_HT_CAP_SGI_40)) + sta->deflink.supp_rates[NL80211_BAND_2GHZ]; + if ((sta->deflink.ht_cap.cap & IEEE80211_HT_CAP_SGI_20) || + (sta->deflink.ht_cap.cap & IEEE80211_HT_CAP_SGI_40)) common->vif_info[0].sgi = true; ieee80211_start_tx_ba_session(sta, 0, 0); } diff --git a/drivers/net/wireless/rsi/rsi_91x_mgmt.c b/drivers/net/wireless/rsi/rsi_91x_mgmt.c index 0848f7a7e76c6..c14689266fec7 100644 --- a/drivers/net/wireless/rsi/rsi_91x_mgmt.c +++ b/drivers/net/wireless/rsi/rsi_91x_mgmt.c @@ -1357,10 +1357,10 @@ static int rsi_send_auto_rate_request(struct rsi_common *common, is_ht = common->vif_info[0].is_ht; is_sgi = common->vif_info[0].sgi; } else { - rate_bitmap = sta->supp_rates[band]; - is_ht = sta->ht_cap.ht_supported; - if ((sta->ht_cap.cap & IEEE80211_HT_CAP_SGI_20) || - (sta->ht_cap.cap & IEEE80211_HT_CAP_SGI_40)) + rate_bitmap = sta->deflink.supp_rates[band]; + is_ht = sta->deflink.ht_cap.ht_supported; + if ((sta->deflink.ht_cap.cap & IEEE80211_HT_CAP_SGI_20) || + (sta->deflink.ht_cap.cap & IEEE80211_HT_CAP_SGI_40)) is_sgi = true; } diff --git a/drivers/net/wireless/st/cw1200/sta.c b/drivers/net/wireless/st/cw1200/sta.c index 236022d4ae2a3..321df124d449d 100644 --- a/drivers/net/wireless/st/cw1200/sta.c +++ b/drivers/net/wireless/st/cw1200/sta.c @@ -1907,10 +1907,10 @@ void cw1200_bss_info_changed(struct ieee80211_hw *dev, if (info->bssid && !info->ibss_joined) sta = ieee80211_find_sta(vif, info->bssid); if (sta) { - priv->ht_info.ht_cap = sta->ht_cap; + priv->ht_info.ht_cap = sta->deflink.ht_cap; priv->bss_params.operational_rate_set = cw1200_rate_mask_to_wsm(priv, - sta->supp_rates[priv->channel->band]); + sta->deflink.supp_rates[priv->channel->band]); priv->ht_info.channel_type = cfg80211_get_chandef_type(&dev->conf.chandef); priv->ht_info.operation_mode = info->ht_operation_mode; } else { diff --git a/drivers/net/wireless/ti/wlcore/cmd.c b/drivers/net/wireless/ti/wlcore/cmd.c index 8b798b5fcaf51..09eb1116be0ee 100644 --- a/drivers/net/wireless/ti/wlcore/cmd.c +++ b/drivers/net/wireless/ti/wlcore/cmd.c @@ -1558,11 +1558,11 @@ int wl12xx_cmd_add_peer(struct wl1271 *wl, struct wl12xx_vif *wlvif, WL1271_PSD_LEGACY; - sta_rates = sta->supp_rates[wlvif->band]; - if (sta->ht_cap.ht_supported) + sta_rates = sta->deflink.supp_rates[wlvif->band]; + if (sta->deflink.ht_cap.ht_supported) sta_rates |= - (sta->ht_cap.mcs.rx_mask[0] << HW_HT_RATES_OFFSET) | - (sta->ht_cap.mcs.rx_mask[1] << HW_MIMO_RATES_OFFSET); + (sta->deflink.ht_cap.mcs.rx_mask[0] << HW_HT_RATES_OFFSET) | + (sta->deflink.ht_cap.mcs.rx_mask[1] << HW_MIMO_RATES_OFFSET); cmd->supported_rates = cpu_to_le32(wl1271_tx_enabled_rates_get(wl, sta_rates, diff --git a/drivers/net/wireless/ti/wlcore/main.c b/drivers/net/wireless/ti/wlcore/main.c index 5669f17b395f3..8440e09426744 100644 --- a/drivers/net/wireless/ti/wlcore/main.c +++ b/drivers/net/wireless/ti/wlcore/main.c @@ -4439,15 +4439,15 @@ static void wl1271_bss_info_changed_sta(struct wl1271 *wl, rcu_read_lock(); sta = ieee80211_find_sta(vif, bss_conf->bssid); if (sta) { - u8 *rx_mask = sta->ht_cap.mcs.rx_mask; + u8 *rx_mask = sta->deflink.ht_cap.mcs.rx_mask; /* save the supp_rates of the ap */ - sta_rate_set = sta->supp_rates[wlvif->band]; - if (sta->ht_cap.ht_supported) + sta_rate_set = sta->deflink.supp_rates[wlvif->band]; + if (sta->deflink.ht_cap.ht_supported) sta_rate_set |= (rx_mask[0] << HW_HT_RATES_OFFSET) | (rx_mask[1] << HW_MIMO_RATES_OFFSET); - sta_ht_cap = sta->ht_cap; + sta_ht_cap = sta->deflink.ht_cap; sta_exists = true; } @@ -5225,7 +5225,8 @@ static int wl12xx_update_sta_state(struct wl1271 *wl, if (ret < 0) return ret; - ret = wl1271_acx_set_ht_capabilities(wl, &sta->ht_cap, true, + ret = wl1271_acx_set_ht_capabilities(wl, &sta->deflink.ht_cap, + true, wl_sta->hlid); if (ret) return ret; @@ -5786,8 +5787,9 @@ static void wlcore_op_sta_rc_update(struct ieee80211_hw *hw, return; /* this callback is atomic, so schedule a new work */ - wlvif->rc_update_bw = sta->bandwidth; - memcpy(&wlvif->rc_ht_cap, &sta->ht_cap, sizeof(sta->ht_cap)); + wlvif->rc_update_bw = sta->deflink.bandwidth; + memcpy(&wlvif->rc_ht_cap, &sta->deflink.ht_cap, + sizeof(sta->deflink.ht_cap)); ieee80211_queue_work(hw, &wlvif->rc_update_work); } diff --git a/drivers/staging/wfx/sta.c b/drivers/staging/wfx/sta.c index b1e9fb14d2b41..3297d73c327a0 100644 --- a/drivers/staging/wfx/sta.c +++ b/drivers/staging/wfx/sta.c @@ -441,11 +441,11 @@ static void wfx_join_finalize(struct wfx_vif *wvif, struct ieee80211_bss_conf *i rcu_read_lock(); /* protect sta */ if (info->bssid && !info->ibss_joined) sta = ieee80211_find_sta(wvif->vif, info->bssid); - if (sta && sta->ht_cap.ht_supported) - ampdu_density = sta->ht_cap.ampdu_density; - if (sta && sta->ht_cap.ht_supported && + if (sta && sta->deflink.ht_cap.ht_supported) + ampdu_density = sta->deflink.ht_cap.ampdu_density; + if (sta && sta->deflink.ht_cap.ht_supported && !(info->ht_operation_mode & IEEE80211_HT_OP_MODE_NON_GF_STA_PRSNT)) - greenfield = !!(sta->ht_cap.cap & IEEE80211_HT_CAP_GRN_FLD); + greenfield = !!(sta->deflink.ht_cap.cap & IEEE80211_HT_CAP_GRN_FLD); rcu_read_unlock(); wvif->join_in_progress = false; diff --git a/include/net/mac80211.h b/include/net/mac80211.h index 0943b2626f4dc..75880fc70700b 100644 --- a/include/net/mac80211.h +++ b/include/net/mac80211.h @@ -2056,6 +2056,45 @@ struct ieee80211_sta_txpwr { enum nl80211_tx_power_setting type; }; +#define MAX_STA_LINKS 15 + +/** + * struct ieee80211_link_sta - station Link specific info + * All link specific info for a STA link for a non MLD STA(single) + * or a MLD STA(multiple entries) are stored here. + * + * @addr: MAC address of the Link STA. For non-MLO STA this is same as the addr + * in ieee80211_sta. For MLO Link STA this addr can be same or different + * from addr in ieee80211_sta (representing MLD STA addr) + * @supp_rates: Bitmap of supported rates + * @ht_cap: HT capabilities of this STA; restricted to our own capabilities + * @vht_cap: VHT capabilities of this STA; restricted to our own capabilities + * @he_cap: HE capabilities of this STA + * @he_6ghz_capa: on 6 GHz, holds the HE 6 GHz band capabilities + * @eht_cap: EHT capabilities of this STA + * @bandwidth: current bandwidth the station can receive with + * @rx_nss: in HT/VHT, the maximum number of spatial streams the + * station can receive at the moment, changed by operating mode + * notifications and capabilities. The value is only valid after + * the station moves to associated state. + * @txpwr: the station tx power configuration + * + */ +struct ieee80211_link_sta { + u8 addr[ETH_ALEN]; + + u32 supp_rates[NUM_NL80211_BANDS]; + struct ieee80211_sta_ht_cap ht_cap; + struct ieee80211_sta_vht_cap vht_cap; + struct ieee80211_sta_he_cap he_cap; + struct ieee80211_he_6ghz_capa he_6ghz_capa; + struct ieee80211_sta_eht_cap eht_cap; + + u8 rx_nss; + enum ieee80211_sta_rx_bandwidth bandwidth; + struct ieee80211_sta_txpwr txpwr; +}; + /** * struct ieee80211_sta - station table entry * @@ -2065,15 +2104,11 @@ struct ieee80211_sta_txpwr { * either be protected by rcu_read_lock() explicitly or implicitly, * or you must take good care to not use such a pointer after a * call to your sta_remove callback that removed it. + * This also represents the MLD STA in case of MLO association + * and holds pointers to various link STA's * * @addr: MAC address * @aid: AID we assigned to the station if we're an AP - * @supp_rates: Bitmap of supported rates (per band) - * @ht_cap: HT capabilities of this STA; restricted to our own capabilities - * @vht_cap: VHT capabilities of this STA; restricted to our own capabilities - * @he_cap: HE capabilities of this STA - * @he_6ghz_capa: on 6 GHz, holds the HE 6 GHz band capabilities - * @eht_cap: EHT capabilities of this STA * @max_rx_aggregation_subframes: maximal amount of frames in a single AMPDU * that this station is allowed to transmit to us. * Can be modified by driver. @@ -2085,11 +2120,6 @@ struct ieee80211_sta_txpwr { * if wme is supported. The bits order is like in * IEEE80211_WMM_IE_STA_QOSINFO_AC_*. * @max_sp: max Service Period. Only valid if wme is supported. - * @bandwidth: current bandwidth the station can receive with - * @rx_nss: in HT/VHT, the maximum number of spatial streams the - * station can receive at the moment, changed by operating mode - * notifications and capabilities. The value is only valid after - * the station moves to associated state. * @smps_mode: current SMPS mode (off, static or dynamic) * @rates: rate control selection table * @tdls: indicates whether the STA is a TDLS peer @@ -2102,25 +2132,28 @@ struct ieee80211_sta_txpwr { * @support_p2p_ps: indicates whether the STA supports P2P PS mechanism or not. * @max_rc_amsdu_len: Maximum A-MSDU size in bytes recommended by rate control. * @max_tid_amsdu_len: Maximum A-MSDU size in bytes for this TID - * @txpwr: the station tx power configuration * @txq: per-TID data TX queues (if driver uses the TXQ abstraction); note that * the last entry (%IEEE80211_NUM_TIDS) is used for non-data frames + * @multi_link_sta: Identifies if this sta is a MLD STA + * @deflink: This holds the default link STA information, for non MLO STA all link + * specific STA information is accessed through @deflink or through + * link[0] which points to address of @deflink. For MLO Link STA + * the first added link STA will point to deflink. + * @link: reference to Link Sta entries. For Non MLO STA, except 1st link, + * i.e link[0] all links would be assigned to NULL by default and + * would access link information via @deflink or link[0]. For MLO + * STA, first link STA being added will point its link pointer to + * @deflink address and remaining would be allocated and the address + * would be assigned to link[link_id] where link_id is the id assigned + * by the AP. */ struct ieee80211_sta { - u32 supp_rates[NUM_NL80211_BANDS]; u8 addr[ETH_ALEN]; u16 aid; - struct ieee80211_sta_ht_cap ht_cap; - struct ieee80211_sta_vht_cap vht_cap; - struct ieee80211_sta_he_cap he_cap; - struct ieee80211_he_6ghz_capa he_6ghz_capa; - struct ieee80211_sta_eht_cap eht_cap; u16 max_rx_aggregation_subframes; bool wme; u8 uapsd_queues; u8 max_sp; - u8 rx_nss; - enum ieee80211_sta_rx_bandwidth bandwidth; enum ieee80211_smps_mode smps_mode; struct ieee80211_sta_rates __rcu *rates; bool tdls; @@ -2147,10 +2180,13 @@ struct ieee80211_sta { bool support_p2p_ps; u16 max_rc_amsdu_len; u16 max_tid_amsdu_len[IEEE80211_NUM_TIDS]; - struct ieee80211_sta_txpwr txpwr; struct ieee80211_txq *txq[IEEE80211_NUM_TIDS + 1]; + bool multi_link_sta; + struct ieee80211_link_sta deflink; + struct ieee80211_link_sta *link[MAX_STA_LINKS]; + /* must be last */ u8 drv_priv[] __aligned(sizeof(void *)); }; @@ -6371,7 +6407,7 @@ static inline int rate_supported(struct ieee80211_sta *sta, enum nl80211_band band, int index) { - return (sta == NULL || sta->supp_rates[band] & BIT(index)); + return (sta == NULL || sta->deflink.supp_rates[band] & BIT(index)); } static inline s8 diff --git a/net/mac80211/agg-rx.c b/net/mac80211/agg-rx.c index 218cdc554d71c..bfab39320004d 100644 --- a/net/mac80211/agg-rx.c +++ b/net/mac80211/agg-rx.c @@ -263,7 +263,7 @@ static void ieee80211_send_addba_resp(struct sta_info *sta, u8 *da, u16 tid, mgmt->u.action.u.addba_resp.timeout = cpu_to_le16(timeout); mgmt->u.action.u.addba_resp.status = cpu_to_le16(status); - if (sta->sta.he_cap.has_he && addbaext) + if (sta->sta.deflink.he_cap.has_he && addbaext) ieee80211_add_addbaext(sdata, skb, addbaext, buf_size); ieee80211_tx_skb(sdata, skb); @@ -296,7 +296,7 @@ void ___ieee80211_start_rx_ba_session(struct sta_info *sta, goto end; } - if (!sta->sta.ht_cap.ht_supported && + if (!sta->sta.deflink.ht_cap.ht_supported && sta->sdata->vif.bss_conf.chandef.chan->band != NL80211_BAND_6GHZ) { ht_dbg(sta->sdata, "STA %pM erroneously requests BA session on tid %d w/o QoS\n", @@ -312,9 +312,9 @@ void ___ieee80211_start_rx_ba_session(struct sta_info *sta, goto end; } - if (sta->sta.eht_cap.has_eht) + if (sta->sta.deflink.eht_cap.has_eht) max_buf_size = IEEE80211_MAX_AMPDU_BUF_EHT; - else if (sta->sta.he_cap.has_he) + else if (sta->sta.deflink.he_cap.has_he) max_buf_size = IEEE80211_MAX_AMPDU_BUF_HE; else max_buf_size = IEEE80211_MAX_AMPDU_BUF_HT; @@ -324,7 +324,7 @@ void ___ieee80211_start_rx_ba_session(struct sta_info *sta, * and if buffer size does not exceeds max value */ /* XXX: check own ht delayed BA capability?? */ if (((ba_policy != 1) && - (!(sta->sta.ht_cap.cap & IEEE80211_HT_CAP_DELAY_BA))) || + (!(sta->sta.deflink.ht_cap.cap & IEEE80211_HT_CAP_DELAY_BA))) || (buf_size > max_buf_size)) { status = WLAN_STATUS_INVALID_QOS_PARAM; ht_dbg_ratelimited(sta->sdata, @@ -507,7 +507,7 @@ void ieee80211_process_addba_request(struct ieee80211_local *local, goto free; } - if (sta->sta.eht_cap.has_eht && elems && elems->addba_ext_ie) { + if (sta->sta.deflink.eht_cap.has_eht && elems && elems->addba_ext_ie) { u8 buf_size_1k = u8_get_bits(elems->addba_ext_ie->data, IEEE80211_ADDBA_EXT_BUF_SIZE_MASK); diff --git a/net/mac80211/agg-tx.c b/net/mac80211/agg-tx.c index 1deb3d874a4b9..91878ed5ec467 100644 --- a/net/mac80211/agg-tx.c +++ b/net/mac80211/agg-tx.c @@ -467,7 +467,7 @@ static void ieee80211_send_addba_with_timeout(struct sta_info *sta, sta->ampdu_mlme.addba_req_num[tid]++; spin_unlock_bh(&sta->lock); - if (sta->sta.he_cap.has_he) { + if (sta->sta.deflink.he_cap.has_he) { buf_size = local->hw.max_tx_aggregation_subframes; } else { /* @@ -594,7 +594,7 @@ int ieee80211_start_tx_ba_session(struct ieee80211_sta *pubsta, u16 tid, "Requested to start BA session on reserved tid=%d", tid)) return -EINVAL; - if (!pubsta->ht_cap.ht_supported && + if (!pubsta->deflink.ht_cap.ht_supported && sta->sdata->vif.bss_conf.chandef.chan->band != NL80211_BAND_6GHZ) return -EINVAL; @@ -647,7 +647,7 @@ int ieee80211_start_tx_ba_session(struct ieee80211_sta *pubsta, u16 tid, * is set when we receive a bss info from a probe response or a beacon. */ if (sta->sdata->vif.type == NL80211_IFTYPE_ADHOC && - !sta->sta.ht_cap.ht_supported) { + !sta->sta.deflink.ht_cap.ht_supported) { ht_dbg(sdata, "BA request denied - IBSS STA %pM does not advertise HT support\n", pubsta->addr); diff --git a/net/mac80211/airtime.c b/net/mac80211/airtime.c index 2619e12c8bdac..4bab1683652d7 100644 --- a/net/mac80211/airtime.c +++ b/net/mac80211/airtime.c @@ -647,8 +647,8 @@ u32 ieee80211_calc_expected_tx_airtime(struct ieee80211_hw *hw, struct sta_info *sta = container_of(pubsta, struct sta_info, sta); struct ieee80211_rx_status stat; - struct ieee80211_tx_rate *tx_rate = &sta->tx_stats.last_rate; - struct rate_info *ri = &sta->tx_stats.last_rate_info; + struct ieee80211_tx_rate *tx_rate = &sta->deflink.tx_stats.last_rate; + struct rate_info *ri = &sta->deflink.tx_stats.last_rate_info; u32 duration, overhead; u8 agg_shift; diff --git a/net/mac80211/cfg.c b/net/mac80211/cfg.c index 8e14ff53e4bd3..f1d211e61e49a 100644 --- a/net/mac80211/cfg.c +++ b/net/mac80211/cfg.c @@ -570,7 +570,8 @@ static int ieee80211_del_key(struct wiphy *wiphy, struct net_device *dev, if (pairwise) key = key_mtx_dereference(local, sta->ptk[key_idx]); else - key = key_mtx_dereference(local, sta->gtk[key_idx]); + key = key_mtx_dereference(local, + sta->deflink.gtk[key_idx]); } else key = key_mtx_dereference(local, sdata->keys[key_idx]); @@ -620,7 +621,7 @@ static int ieee80211_get_key(struct wiphy *wiphy, struct net_device *dev, else if (!pairwise && key_idx < NUM_DEFAULT_KEYS + NUM_DEFAULT_MGMT_KEYS + NUM_DEFAULT_BEACON_KEYS) - key = rcu_dereference(sta->gtk[key_idx]); + key = rcu_dereference(sta->deflink.gtk[key_idx]); } else key = rcu_dereference(sdata->keys[key_idx]); @@ -1728,9 +1729,9 @@ static int sta_apply_parameters(struct ieee80211_local *local, sta->listen_interval = params->listen_interval; if (params->sta_modify_mask & STATION_PARAM_APPLY_STA_TXPOWER) { - sta->sta.txpwr.type = params->txpwr.type; + sta->sta.deflink.txpwr.type = params->txpwr.type; if (params->txpwr.type == NL80211_TX_POWER_LIMITED) - sta->sta.txpwr.power = params->txpwr.power; + sta->sta.deflink.txpwr.power = params->txpwr.power; ret = drv_sta_set_txpwr(local, sdata, sta); if (ret) return ret; @@ -1740,7 +1741,7 @@ static int sta_apply_parameters(struct ieee80211_local *local, ieee80211_parse_bitrates(&sdata->vif.bss_conf.chandef, sband, params->supported_rates, params->supported_rates_len, - &sta->sta.supp_rates[sband->band]); + &sta->sta.deflink.supp_rates[sband->band]); } if (params->ht_capa) diff --git a/net/mac80211/chan.c b/net/mac80211/chan.c index e26d42de14ec2..e3452445b3635 100644 --- a/net/mac80211/chan.c +++ b/net/mac80211/chan.c @@ -199,7 +199,7 @@ static enum nl80211_chan_width ieee80211_get_sta_bw(struct sta_info *sta) switch (width) { case IEEE80211_STA_RX_BW_20: - if (sta->sta.ht_cap.ht_supported) + if (sta->sta.deflink.ht_cap.ht_supported) return NL80211_CHAN_WIDTH_20; else return NL80211_CHAN_WIDTH_20_NOHT; @@ -375,15 +375,15 @@ static void ieee80211_chan_bw_change(struct ieee80211_local *local, new_sta_bw = ieee80211_sta_cur_vht_bw(sta); /* nothing change */ - if (new_sta_bw == sta->sta.bandwidth) + if (new_sta_bw == sta->sta.deflink.bandwidth) continue; /* vif changed to narrow BW and narrow BW for station wasn't * requested or vise versa */ - if ((new_sta_bw < sta->sta.bandwidth) == !narrowed) + if ((new_sta_bw < sta->sta.deflink.bandwidth) == !narrowed) continue; - sta->sta.bandwidth = new_sta_bw; + sta->sta.deflink.bandwidth = new_sta_bw; rate_control_rate_update(local, sband, sta, IEEE80211_RC_BW_CHANGED); } diff --git a/net/mac80211/debugfs_sta.c b/net/mac80211/debugfs_sta.c index 9479f2787ea79..46d08861ca65e 100644 --- a/net/mac80211/debugfs_sta.c +++ b/net/mac80211/debugfs_sta.c @@ -447,7 +447,7 @@ static ssize_t sta_ht_capa_read(struct file *file, char __user *userbuf, int i; ssize_t bufsz = 512; struct sta_info *sta = file->private_data; - struct ieee80211_sta_ht_cap *htc = &sta->sta.ht_cap; + struct ieee80211_sta_ht_cap *htc = &sta->sta.deflink.ht_cap; ssize_t ret; buf = kzalloc(bufsz, GFP_KERNEL); @@ -531,7 +531,7 @@ static ssize_t sta_vht_capa_read(struct file *file, char __user *userbuf, { char *buf, *p; struct sta_info *sta = file->private_data; - struct ieee80211_sta_vht_cap *vhtc = &sta->sta.vht_cap; + struct ieee80211_sta_vht_cap *vhtc = &sta->sta.deflink.vht_cap; ssize_t ret; ssize_t bufsz = 512; @@ -646,7 +646,7 @@ static ssize_t sta_he_capa_read(struct file *file, char __user *userbuf, char *buf, *p; size_t buf_sz = PAGE_SIZE; struct sta_info *sta = file->private_data; - struct ieee80211_sta_he_cap *hec = &sta->sta.he_cap; + struct ieee80211_sta_he_cap *hec = &sta->sta.deflink.he_cap; struct ieee80211_he_mcs_nss_supp *nss = &hec->he_mcs_nss_supp; u8 ppe_size; u8 *cap; @@ -1052,9 +1052,9 @@ void ieee80211_sta_debugfs_add(struct sta_info *sta) DEBUGFS_ADD(vht_capa); DEBUGFS_ADD(he_capa); - DEBUGFS_ADD_COUNTER(rx_duplicates, rx_stats.num_duplicates); - DEBUGFS_ADD_COUNTER(rx_fragments, rx_stats.fragments); - DEBUGFS_ADD_COUNTER(tx_filtered, status_stats.filtered); + DEBUGFS_ADD_COUNTER(rx_duplicates, deflink.rx_stats.num_duplicates); + DEBUGFS_ADD_COUNTER(rx_fragments, deflink.rx_stats.fragments); + DEBUGFS_ADD_COUNTER(tx_filtered, deflink.status_stats.filtered); if (local->ops->wake_tx_queue) { DEBUGFS_ADD(aqm); diff --git a/net/mac80211/eht.c b/net/mac80211/eht.c index 364ad0ef76925..96c9486bf2fed 100644 --- a/net/mac80211/eht.c +++ b/net/mac80211/eht.c @@ -14,7 +14,7 @@ ieee80211_eht_cap_ie_to_sta_eht_cap(struct ieee80211_sub_if_data *sdata, const struct ieee80211_eht_cap_elem *eht_cap_ie_elem, u8 eht_cap_len, struct sta_info *sta) { - struct ieee80211_sta_eht_cap *eht_cap = &sta->sta.eht_cap; + struct ieee80211_sta_eht_cap *eht_cap = &sta->sta.deflink.eht_cap; struct ieee80211_he_cap_elem *he_cap_ie_elem = (void *)he_cap_ie; u8 eht_ppe_size = 0; u8 mcs_nss_size; @@ -71,6 +71,6 @@ ieee80211_eht_cap_ie_to_sta_eht_cap(struct ieee80211_sub_if_data *sdata, eht_cap->has_eht = true; - sta->cur_max_bandwidth = ieee80211_sta_cap_rx_bw(sta); - sta->sta.bandwidth = ieee80211_sta_cur_vht_bw(sta); + sta->deflink.cur_max_bandwidth = ieee80211_sta_cap_rx_bw(sta); + sta->sta.deflink.bandwidth = ieee80211_sta_cur_vht_bw(sta); } diff --git a/net/mac80211/ethtool.c b/net/mac80211/ethtool.c index b2253df54413f..31cd3c1ac07f6 100644 --- a/net/mac80211/ethtool.c +++ b/net/mac80211/ethtool.c @@ -114,7 +114,7 @@ static void ieee80211_get_stats(struct net_device *dev, sta_set_sinfo(sta, &sinfo, false); i = 0; - ADD_STA_STATS(sta); + ADD_STA_STATS(sta->link[0]); data[i++] = sta->sta_state; @@ -140,7 +140,7 @@ static void ieee80211_get_stats(struct net_device *dev, memset(&sinfo, 0, sizeof(sinfo)); sta_set_sinfo(sta, &sinfo, false); i = 0; - ADD_STA_STATS(sta); + ADD_STA_STATS(sta->link[0]); } } diff --git a/net/mac80211/he.c b/net/mac80211/he.c index c05af7018f79f..1a61f7552edd3 100644 --- a/net/mac80211/he.c +++ b/net/mac80211/he.c @@ -49,7 +49,7 @@ ieee80211_update_from_he_6ghz_capa(const struct ieee80211_he_6ghz_capa *he_6ghz_ break; } - sta->sta.he_6ghz_capa = *he_6ghz_capa; + sta->sta.deflink.he_6ghz_capa = *he_6ghz_capa; } static void ieee80211_he_mcs_disable(__le16 *he_mcs) @@ -110,7 +110,7 @@ ieee80211_he_cap_ie_to_sta_he_cap(struct ieee80211_sub_if_data *sdata, const struct ieee80211_he_6ghz_capa *he_6ghz_capa, struct sta_info *sta) { - struct ieee80211_sta_he_cap *he_cap = &sta->sta.he_cap; + struct ieee80211_sta_he_cap *he_cap = &sta->sta.deflink.he_cap; struct ieee80211_sta_he_cap own_he_cap; struct ieee80211_he_cap_elem *he_cap_ie_elem = (void *)he_cap_ie; u8 he_ppe_size; @@ -153,8 +153,8 @@ ieee80211_he_cap_ie_to_sta_he_cap(struct ieee80211_sub_if_data *sdata, he_cap->has_he = true; - sta->cur_max_bandwidth = ieee80211_sta_cap_rx_bw(sta); - sta->sta.bandwidth = ieee80211_sta_cur_vht_bw(sta); + sta->deflink.cur_max_bandwidth = ieee80211_sta_cap_rx_bw(sta); + sta->sta.deflink.bandwidth = ieee80211_sta_cur_vht_bw(sta); if (sband->band == NL80211_BAND_6GHZ && he_6ghz_capa) ieee80211_update_from_he_6ghz_capa(he_6ghz_capa, sta); diff --git a/net/mac80211/ht.c b/net/mac80211/ht.c index 2eb7641f5556a..171bd16b13f34 100644 --- a/net/mac80211/ht.c +++ b/net/mac80211/ht.c @@ -243,9 +243,9 @@ bool ieee80211_ht_cap_ie_to_sta_ht_cap(struct ieee80211_sub_if_data *sdata, sta->sta.max_amsdu_len = IEEE80211_MAX_MPDU_LEN_HT_3839; apply: - changed = memcmp(&sta->sta.ht_cap, &ht_cap, sizeof(ht_cap)); + changed = memcmp(&sta->sta.deflink.ht_cap, &ht_cap, sizeof(ht_cap)); - memcpy(&sta->sta.ht_cap, &ht_cap, sizeof(ht_cap)); + memcpy(&sta->sta.deflink.ht_cap, &ht_cap, sizeof(ht_cap)); switch (sdata->vif.bss_conf.chandef.width) { default: @@ -264,9 +264,9 @@ bool ieee80211_ht_cap_ie_to_sta_ht_cap(struct ieee80211_sub_if_data *sdata, break; } - sta->sta.bandwidth = bw; + sta->sta.deflink.bandwidth = bw; - sta->cur_max_bandwidth = + sta->deflink.cur_max_bandwidth = ht_cap.cap & IEEE80211_HT_CAP_SUP_WIDTH_20_40 ? IEEE80211_STA_RX_BW_40 : IEEE80211_STA_RX_BW_20; diff --git a/net/mac80211/ibss.c b/net/mac80211/ibss.c index 0416c4d222929..14c04fd48b7a1 100644 --- a/net/mac80211/ibss.c +++ b/net/mac80211/ibss.c @@ -637,7 +637,7 @@ ieee80211_ibss_add_sta(struct ieee80211_sub_if_data *sdata, const u8 *bssid, /* make sure mandatory rates are always added */ sband = local->hw.wiphy->bands[band]; - sta->sta.supp_rates[band] = supp_rates | + sta->sta.deflink.supp_rates[band] = supp_rates | ieee80211_mandatory_rates(sband, scan_width); return ieee80211_ibss_finish_sta(sta); @@ -1005,7 +1005,7 @@ static void ieee80211_update_sta_info(struct ieee80211_sub_if_data *sdata, if (sta) { u32 prev_rates; - prev_rates = sta->sta.supp_rates[band]; + prev_rates = sta->sta.deflink.supp_rates[band]; /* make sure mandatory rates are always added */ scan_width = NL80211_BSS_CHAN_WIDTH_20; if (rx_status->bw == RATE_INFO_BW_5) @@ -1013,13 +1013,13 @@ static void ieee80211_update_sta_info(struct ieee80211_sub_if_data *sdata, else if (rx_status->bw == RATE_INFO_BW_10) scan_width = NL80211_BSS_CHAN_WIDTH_10; - sta->sta.supp_rates[band] = supp_rates | + sta->sta.deflink.supp_rates[band] = supp_rates | ieee80211_mandatory_rates(sband, scan_width); - if (sta->sta.supp_rates[band] != prev_rates) { + if (sta->sta.deflink.supp_rates[band] != prev_rates) { ibss_dbg(sdata, "updated supp_rates set for %pM based on beacon/probe_resp (0x%x -> 0x%x)\n", sta->sta.addr, prev_rates, - sta->sta.supp_rates[band]); + sta->sta.deflink.supp_rates[band]); rates_updated = true; } } else { @@ -1043,7 +1043,7 @@ static void ieee80211_update_sta_info(struct ieee80211_sub_if_data *sdata, /* we both use HT */ struct ieee80211_ht_cap htcap_ie; struct cfg80211_chan_def chandef; - enum ieee80211_sta_rx_bandwidth bw = sta->sta.bandwidth; + enum ieee80211_sta_rx_bandwidth bw = sta->sta.deflink.bandwidth; cfg80211_chandef_create(&chandef, channel, NL80211_CHAN_NO_HT); ieee80211_chandef_ht_oper(elems->ht_operation, &chandef); @@ -1058,7 +1058,7 @@ static void ieee80211_update_sta_info(struct ieee80211_sub_if_data *sdata, sdata->u.ibss.chandef.width != NL80211_CHAN_WIDTH_40) { /* we both use VHT */ struct ieee80211_vht_cap cap_ie; - struct ieee80211_sta_vht_cap cap = sta->sta.vht_cap; + struct ieee80211_sta_vht_cap cap = sta->sta.deflink.vht_cap; u32 vht_cap_info = le32_to_cpu(elems->vht_cap_elem->vht_cap_info); @@ -1069,11 +1069,11 @@ static void ieee80211_update_sta_info(struct ieee80211_sub_if_data *sdata, memcpy(&cap_ie, elems->vht_cap_elem, sizeof(cap_ie)); ieee80211_vht_cap_ie_to_sta_vht_cap(sdata, sband, &cap_ie, sta); - if (memcmp(&cap, &sta->sta.vht_cap, sizeof(cap))) + if (memcmp(&cap, &sta->sta.deflink.vht_cap, sizeof(cap))) rates_updated |= true; } - if (bw != sta->sta.bandwidth) + if (bw != sta->sta.deflink.bandwidth) rates_updated |= true; if (!cfg80211_chandef_compatible(&sdata->u.ibss.chandef, @@ -1083,12 +1083,12 @@ static void ieee80211_update_sta_info(struct ieee80211_sub_if_data *sdata, if (sta && rates_updated) { u32 changed = IEEE80211_RC_SUPP_RATES_CHANGED; - u8 rx_nss = sta->sta.rx_nss; + u8 rx_nss = sta->sta.deflink.rx_nss; /* Force rx_nss recalculation */ - sta->sta.rx_nss = 0; + sta->sta.deflink.rx_nss = 0; rate_control_rate_init(sta); - if (sta->sta.rx_nss != rx_nss) + if (sta->sta.deflink.rx_nss != rx_nss) changed |= IEEE80211_RC_NSS_CHANGED; drv_sta_rc_update(local, sdata, &sta->sta, changed); @@ -1235,7 +1235,7 @@ void ieee80211_ibss_rx_no_sta(struct ieee80211_sub_if_data *sdata, /* make sure mandatory rates are always added */ sband = local->hw.wiphy->bands[band]; - sta->sta.supp_rates[band] = supp_rates | + sta->sta.deflink.supp_rates[band] = supp_rates | ieee80211_mandatory_rates(sband, scan_width); spin_lock(&ifibss->incomplete_lock); diff --git a/net/mac80211/key.c b/net/mac80211/key.c index f695fc80088bc..0fcf8aebedc4e 100644 --- a/net/mac80211/key.c +++ b/net/mac80211/key.c @@ -476,7 +476,7 @@ static int ieee80211_key_replace(struct ieee80211_sub_if_data *sdata, !(new->conf.flags & IEEE80211_KEY_FLAG_NO_AUTO_TX)) _ieee80211_set_tx_key(new, true); } else { - rcu_assign_pointer(sta->gtk[idx], new); + rcu_assign_pointer(sta->deflink.gtk[idx], new); } /* Only needed for transition from no key -> key. * Still triggers unnecessary when using Extended Key ID @@ -826,7 +826,8 @@ int ieee80211_key_link(struct ieee80211_key *key, (old_key && old_key->conf.cipher != key->conf.cipher)) goto out; } else if (sta) { - old_key = key_mtx_dereference(sdata->local, sta->gtk[idx]); + old_key = key_mtx_dereference(sdata->local, + sta->deflink.gtk[idx]); } else { old_key = key_mtx_dereference(sdata->local, sdata->keys[idx]); } @@ -1076,8 +1077,8 @@ void ieee80211_free_sta_keys(struct ieee80211_local *local, int i; mutex_lock(&local->key_mtx); - for (i = 0; i < ARRAY_SIZE(sta->gtk); i++) { - key = key_mtx_dereference(local, sta->gtk[i]); + for (i = 0; i < ARRAY_SIZE(sta->deflink.gtk); i++) { + key = key_mtx_dereference(local, sta->deflink.gtk[i]); if (!key) continue; ieee80211_key_replace(key->sdata, key->sta, diff --git a/net/mac80211/mesh_hwmp.c b/net/mac80211/mesh_hwmp.c index 44a6fdb6efbd4..58ebdcd69d055 100644 --- a/net/mac80211/mesh_hwmp.c +++ b/net/mac80211/mesh_hwmp.c @@ -310,7 +310,7 @@ void ieee80211s_update_metric(struct ieee80211_local *local, LINK_FAIL_THRESH) mesh_plink_broken(sta); - sta_set_rate_info_tx(sta, &sta->tx_stats.last_rate, &rinfo); + sta_set_rate_info_tx(sta, &sta->deflink.tx_stats.last_rate, &rinfo); ewma_mesh_tx_rate_avg_add(&sta->mesh->tx_rate_avg, cfg80211_calculate_bitrate(&rinfo)); } diff --git a/net/mac80211/mesh_plink.c b/net/mac80211/mesh_plink.c index a829470dd59ed..42ba7424589ed 100644 --- a/net/mac80211/mesh_plink.c +++ b/net/mac80211/mesh_plink.c @@ -61,8 +61,8 @@ static bool rssi_threshold_check(struct ieee80211_sub_if_data *sdata, s32 rssi_threshold = sdata->u.mesh.mshcfg.rssi_threshold; return rssi_threshold == 0 || (sta && - (s8)-ewma_signal_read(&sta->rx_stats_avg.signal) > - rssi_threshold); + (s8)-ewma_signal_read(&sta->deflink.rx_stats_avg.signal) > + rssi_threshold); } /** @@ -125,7 +125,7 @@ static u32 mesh_set_short_slot_time(struct ieee80211_sub_if_data *sdata) continue; short_slot = false; - if (erp_rates & sta->sta.supp_rates[sband->band]) + if (erp_rates & sta->sta.deflink.supp_rates[sband->band]) short_slot = true; else break; @@ -175,10 +175,10 @@ static u32 mesh_set_ht_prot_mode(struct ieee80211_sub_if_data *sdata) sta->mesh->plink_state != NL80211_PLINK_ESTAB) continue; - if (sta->sta.bandwidth > IEEE80211_STA_RX_BW_20) + if (sta->sta.deflink.bandwidth > IEEE80211_STA_RX_BW_20) continue; - if (!sta->sta.ht_cap.ht_supported) { + if (!sta->sta.deflink.ht_cap.ht_supported) { mpl_dbg(sdata, "nonHT sta (%pM) is present\n", sta->sta.addr); non_ht_sta = true; @@ -415,7 +415,7 @@ static void mesh_sta_info_init(struct ieee80211_sub_if_data *sdata, struct ieee80211_local *local = sdata->local; struct ieee80211_supported_band *sband; u32 rates, basic_rates = 0, changed = 0; - enum ieee80211_sta_rx_bandwidth bw = sta->sta.bandwidth; + enum ieee80211_sta_rx_bandwidth bw = sta->sta.deflink.bandwidth; sband = ieee80211_get_sband(sdata); if (!sband) @@ -425,7 +425,7 @@ static void mesh_sta_info_init(struct ieee80211_sub_if_data *sdata, &basic_rates); spin_lock_bh(&sta->mesh->plink_lock); - sta->rx_stats.last_rx = jiffies; + sta->deflink.rx_stats.last_rx = jiffies; /* rates and capabilities don't change during peering */ if (sta->mesh->plink_state == NL80211_PLINK_ESTAB && @@ -433,9 +433,9 @@ static void mesh_sta_info_init(struct ieee80211_sub_if_data *sdata, goto out; sta->mesh->processed_beacon = true; - if (sta->sta.supp_rates[sband->band] != rates) + if (sta->sta.deflink.supp_rates[sband->band] != rates) changed |= IEEE80211_RC_SUPP_RATES_CHANGED; - sta->sta.supp_rates[sband->band] = rates; + sta->sta.deflink.supp_rates[sband->band] = rates; if (ieee80211_ht_cap_ie_to_sta_ht_cap(sdata, sband, elems->ht_cap_elem, sta)) @@ -449,16 +449,16 @@ static void mesh_sta_info_init(struct ieee80211_sub_if_data *sdata, elems->he_6ghz_capa, sta); - if (bw != sta->sta.bandwidth) + if (bw != sta->sta.deflink.bandwidth) changed |= IEEE80211_RC_BW_CHANGED; /* HT peer is operating 20MHz-only */ if (elems->ht_operation && !(elems->ht_operation->ht_param & IEEE80211_HT_PARAM_CHAN_WIDTH_ANY)) { - if (sta->sta.bandwidth != IEEE80211_STA_RX_BW_20) + if (sta->sta.deflink.bandwidth != IEEE80211_STA_RX_BW_20) changed |= IEEE80211_RC_BW_CHANGED; - sta->sta.bandwidth = IEEE80211_STA_RX_BW_20; + sta->sta.deflink.bandwidth = IEEE80211_STA_RX_BW_20; } if (!test_sta_flag(sta, WLAN_STA_RATE_CONTROL)) diff --git a/net/mac80211/mlme.c b/net/mac80211/mlme.c index 1b30c724ca8d1..b857915881e09 100644 --- a/net/mac80211/mlme.c +++ b/net/mac80211/mlme.c @@ -3342,7 +3342,7 @@ static bool ieee80211_twt_req_supported(const struct sta_info *sta, if (!(elems->ext_capab[9] & WLAN_EXT_CAPA10_TWT_RESPONDER_SUPPORT)) return false; - return sta->sta.he_cap.he_cap_elem.mac_cap_info[0] & + return sta->sta.deflink.he_cap.he_cap_elem.mac_cap_info[0] & IEEE80211_HE_MAC_CAP0_TWT_RES; } @@ -3369,7 +3369,7 @@ static bool ieee80211_twt_bcast_support(struct ieee80211_sub_if_data *sdata, ieee80211_vif_type_p2p(&sdata->vif)); return bss_conf->he_support && - (sta->sta.he_cap.he_cap_elem.mac_cap_info[2] & + (sta->sta.deflink.he_cap.he_cap_elem.mac_cap_info[2] & IEEE80211_HE_MAC_CAP2_BCAST_TWT) && own_he_cap && (own_he_cap->he_cap_elem.mac_cap_info[2] & @@ -3587,7 +3587,7 @@ static bool ieee80211_assoc_success(struct ieee80211_sub_if_data *sdata, elems->he_6ghz_capa, sta); - bss_conf->he_support = sta->sta.he_cap.has_he; + bss_conf->he_support = sta->sta.deflink.he_cap.has_he; if (elems->rsnx && elems->rsnx_len && (elems->rsnx[0] & WLAN_RSNX_CAPA_PROTECTED_TWT) && wiphy_ext_feature_isset(local->hw.wiphy, @@ -3607,7 +3607,7 @@ static bool ieee80211_assoc_success(struct ieee80211_sub_if_data *sdata, elems->eht_cap_len, sta); - bss_conf->eht_support = sta->sta.eht_cap.has_eht; + bss_conf->eht_support = sta->sta.deflink.eht_cap.has_eht; } else { bss_conf->eht_support = false; } @@ -3678,7 +3678,7 @@ static bool ieee80211_assoc_success(struct ieee80211_sub_if_data *sdata, nss = *elems->opmode_notif & IEEE80211_OPMODE_NOTIF_RX_NSS_MASK; nss >>= IEEE80211_OPMODE_NOTIF_RX_NSS_SHIFT; nss += 1; - sta->sta.rx_nss = nss; + sta->sta.deflink.rx_nss = nss; } rate_control_rate_init(sta); @@ -4836,9 +4836,9 @@ static void ieee80211_sta_conn_mon_timer(struct timer_list *t) if (!sta) return; - timeout = sta->status_stats.last_ack; - if (time_before(sta->status_stats.last_ack, sta->rx_stats.last_rx)) - timeout = sta->rx_stats.last_rx; + timeout = sta->deflink.status_stats.last_ack; + if (time_before(sta->deflink.status_stats.last_ack, sta->deflink.rx_stats.last_rx)) + timeout = sta->deflink.rx_stats.last_rx; timeout += IEEE80211_CONNECTION_IDLE_TIME; /* If timeout is after now, then update timer to fire at @@ -5638,7 +5638,7 @@ static int ieee80211_prep_connection(struct ieee80211_sub_if_data *sdata, } if (rates) - new_sta->sta.supp_rates[cbss->channel->band] = rates; + new_sta->sta.deflink.supp_rates[cbss->channel->band] = rates; else sdata_info(sdata, "No rates found, keeping mandatory only\n"); diff --git a/net/mac80211/ocb.c b/net/mac80211/ocb.c index 7c1a735b9eee3..f97cb4c453d3f 100644 --- a/net/mac80211/ocb.c +++ b/net/mac80211/ocb.c @@ -74,7 +74,7 @@ void ieee80211_ocb_rx_no_sta(struct ieee80211_sub_if_data *sdata, /* Add only mandatory rates for now */ sband = local->hw.wiphy->bands[band]; - sta->sta.supp_rates[band] = + sta->sta.deflink.supp_rates[band] = ieee80211_mandatory_rates(sband, scan_width); spin_lock(&ifocb->incomplete_lock); diff --git a/net/mac80211/rate.c b/net/mac80211/rate.c index 8c6416129d5be..ae9700e0a1a5b 100644 --- a/net/mac80211/rate.c +++ b/net/mac80211/rate.c @@ -371,7 +371,7 @@ static void __rate_control_send_low(struct ieee80211_hw *hw, WARN_ONCE(i == sband->n_bitrates, "no supported rates for sta %pM (0x%x, band %d) in rate_mask 0x%x with flags 0x%x\n", sta ? sta->addr : NULL, - sta ? sta->supp_rates[sband->band] : -1, + sta ? sta->deflink.supp_rates[sband->band] : -1, sband->band, rate_mask, rate_flags); @@ -781,11 +781,11 @@ static bool rate_control_cap_mask(struct ieee80211_sub_if_data *sdata, u16 sta_vht_mask[NL80211_VHT_NSS_MAX]; /* Filter out rates that the STA does not support */ - *mask &= sta->supp_rates[sband->band]; + *mask &= sta->deflink.supp_rates[sband->band]; for (i = 0; i < IEEE80211_HT_MCS_MASK_LEN; i++) - mcs_mask[i] &= sta->ht_cap.mcs.rx_mask[i]; + mcs_mask[i] &= sta->deflink.ht_cap.mcs.rx_mask[i]; - sta_vht_cap = sta->vht_cap.vht_mcs.rx_mcs_map; + sta_vht_cap = sta->deflink.vht_cap.vht_mcs.rx_mcs_map; ieee80211_get_vht_mask_from_cap(sta_vht_cap, sta_vht_mask); for (i = 0; i < NL80211_VHT_NSS_MAX; i++) vht_mask[i] &= sta_vht_mask[i]; diff --git a/net/mac80211/rc80211_minstrel_ht.c b/net/mac80211/rc80211_minstrel_ht.c index 5a6bf46a42483..7b1f5c045e064 100644 --- a/net/mac80211/rc80211_minstrel_ht.c +++ b/net/mac80211/rc80211_minstrel_ht.c @@ -606,7 +606,7 @@ minstrel_ht_prob_rate_reduce_streams(struct minstrel_ht_sta *mi) int tmp_max_streams, group, tmp_idx, tmp_prob; int tmp_tp = 0; - if (!mi->sta->ht_cap.ht_supported) + if (!mi->sta->deflink.ht_cap.ht_supported) return; group = MI_RATE_GROUP(mi->max_tp_rate[0]); @@ -996,7 +996,7 @@ minstrel_ht_update_stats(struct minstrel_priv *mp, struct minstrel_ht_sta *mi) u16 tmp_mcs_tp_rate[MAX_THR_RATES], tmp_group_tp_rate[MAX_THR_RATES]; u16 tmp_legacy_tp_rate[MAX_THR_RATES], tmp_max_prob_rate; u16 index; - bool ht_supported = mi->sta->ht_cap.ht_supported; + bool ht_supported = mi->sta->deflink.ht_cap.ht_supported; if (mi->ampdu_packets > 0) { if (!ieee80211_hw_check(mp->hw, TX_STATUS_NO_AMPDU_LEN)) @@ -1419,7 +1419,7 @@ minstrel_ht_get_max_amsdu_len(struct minstrel_ht_sta *mi) * the limit here to avoid the complexity of having to de-aggregate * packets in the queue. */ - if (!mi->sta->vht_cap.vht_supported) + if (!mi->sta->deflink.vht_cap.vht_supported) return IEEE80211_MAX_MPDU_LEN_HT_BA; /* unlimited */ @@ -1536,7 +1536,7 @@ minstrel_ht_update_cck(struct minstrel_priv *mp, struct minstrel_ht_sta *mi, if (sband->band != NL80211_BAND_2GHZ) return; - if (sta->ht_cap.ht_supported && + if (sta->deflink.ht_cap.ht_supported && !ieee80211_hw_check(mp->hw, SUPPORTS_HT_CCK_RATES)) return; @@ -1559,7 +1559,7 @@ minstrel_ht_update_ofdm(struct minstrel_priv *mp, struct minstrel_ht_sta *mi, const u8 *rates; int i; - if (sta->ht_cap.ht_supported) + if (sta->deflink.ht_cap.ht_supported) return; rates = mp->ofdm_rates[sband->band]; @@ -1579,9 +1579,9 @@ minstrel_ht_update_caps(void *priv, struct ieee80211_supported_band *sband, { struct minstrel_priv *mp = priv; struct minstrel_ht_sta *mi = priv_sta; - struct ieee80211_mcs_info *mcs = &sta->ht_cap.mcs; - u16 ht_cap = sta->ht_cap.cap; - struct ieee80211_sta_vht_cap *vht_cap = &sta->vht_cap; + struct ieee80211_mcs_info *mcs = &sta->deflink.ht_cap.mcs; + u16 ht_cap = sta->deflink.ht_cap.cap; + struct ieee80211_sta_vht_cap *vht_cap = &sta->deflink.vht_cap; const struct ieee80211_rate *ctl_rate; bool ldpc, erp; int use_vht; @@ -1653,7 +1653,7 @@ minstrel_ht_update_caps(void *priv, struct ieee80211_supported_band *sband, } if (gflags & IEEE80211_TX_RC_40_MHZ_WIDTH && - sta->bandwidth < IEEE80211_STA_RX_BW_40) + sta->deflink.bandwidth < IEEE80211_STA_RX_BW_40) continue; nss = minstrel_mcs_groups[i].streams; @@ -1680,7 +1680,7 @@ minstrel_ht_update_caps(void *priv, struct ieee80211_supported_band *sband, continue; if (gflags & IEEE80211_TX_RC_80_MHZ_WIDTH) { - if (sta->bandwidth < IEEE80211_STA_RX_BW_80 || + if (sta->deflink.bandwidth < IEEE80211_STA_RX_BW_80 || ((gflags & IEEE80211_TX_RC_SHORT_GI) && !(vht_cap->cap & IEEE80211_VHT_CAP_SHORT_GI_80))) { continue; diff --git a/net/mac80211/rx.c b/net/mac80211/rx.c index 03ee1d9b6d086..959a36fd658b8 100644 --- a/net/mac80211/rx.c +++ b/net/mac80211/rx.c @@ -221,7 +221,7 @@ static void __ieee80211_queue_skb_to_iface(struct ieee80211_sub_if_data *sdata, skb_queue_tail(&sdata->skb_queue, skb); ieee80211_queue_work(&sdata->local->hw, &sdata->work); if (sta) - sta->rx_stats.packets++; + sta->deflink.rx_stats.packets++; } static void ieee80211_queue_skb_to_iface(struct ieee80211_sub_if_data *sdata, @@ -1465,7 +1465,7 @@ ieee80211_rx_h_check_dup(struct ieee80211_rx_data *rx) if (unlikely(ieee80211_has_retry(hdr->frame_control) && rx->sta->last_seq_ctrl[rx->seqno_idx] == hdr->seq_ctrl)) { I802_DEBUG_INC(rx->local->dot11FrameDuplicateCount); - rx->sta->rx_stats.num_duplicates++; + rx->sta->deflink.rx_stats.num_duplicates++; return RX_DROP_UNUSABLE; } else if (!(status->flag & RX_FLAG_AMSDU_MORE)) { rx->sta->last_seq_ctrl[rx->seqno_idx] = hdr->seq_ctrl; @@ -1761,46 +1761,47 @@ ieee80211_rx_h_sta_process(struct ieee80211_rx_data *rx) NL80211_IFTYPE_ADHOC); if (ether_addr_equal(bssid, rx->sdata->u.ibss.bssid) && test_sta_flag(sta, WLAN_STA_AUTHORIZED)) { - sta->rx_stats.last_rx = jiffies; + sta->deflink.rx_stats.last_rx = jiffies; if (ieee80211_is_data(hdr->frame_control) && !is_multicast_ether_addr(hdr->addr1)) - sta->rx_stats.last_rate = + sta->deflink.rx_stats.last_rate = sta_stats_encode_rate(status); } } else if (rx->sdata->vif.type == NL80211_IFTYPE_OCB) { - sta->rx_stats.last_rx = jiffies; + sta->deflink.rx_stats.last_rx = jiffies; } else if (!ieee80211_is_s1g_beacon(hdr->frame_control) && !is_multicast_ether_addr(hdr->addr1)) { /* * Mesh beacons will update last_rx when if they are found to * match the current local configuration when processed. */ - sta->rx_stats.last_rx = jiffies; + sta->deflink.rx_stats.last_rx = jiffies; if (ieee80211_is_data(hdr->frame_control)) - sta->rx_stats.last_rate = sta_stats_encode_rate(status); + sta->deflink.rx_stats.last_rate = sta_stats_encode_rate(status); } - sta->rx_stats.fragments++; + sta->deflink.rx_stats.fragments++; - u64_stats_update_begin(&rx->sta->rx_stats.syncp); - sta->rx_stats.bytes += rx->skb->len; - u64_stats_update_end(&rx->sta->rx_stats.syncp); + u64_stats_update_begin(&rx->sta->deflink.rx_stats.syncp); + sta->deflink.rx_stats.bytes += rx->skb->len; + u64_stats_update_end(&rx->sta->deflink.rx_stats.syncp); if (!(status->flag & RX_FLAG_NO_SIGNAL_VAL)) { - sta->rx_stats.last_signal = status->signal; - ewma_signal_add(&sta->rx_stats_avg.signal, -status->signal); + sta->deflink.rx_stats.last_signal = status->signal; + ewma_signal_add(&sta->deflink.rx_stats_avg.signal, + -status->signal); } if (status->chains) { - sta->rx_stats.chains = status->chains; + sta->deflink.rx_stats.chains = status->chains; for (i = 0; i < ARRAY_SIZE(status->chain_signal); i++) { int signal = status->chain_signal[i]; if (!(status->chains & BIT(i))) continue; - sta->rx_stats.chain_signal_last[i] = signal; - ewma_signal_add(&sta->rx_stats_avg.chain_signal[i], + sta->deflink.rx_stats.chain_signal_last[i] = signal; + ewma_signal_add(&sta->deflink.rx_stats_avg.chain_signal[i], -signal); } } @@ -1861,7 +1862,7 @@ ieee80211_rx_h_sta_process(struct ieee80211_rx_data *rx) * Update counter and free packet here to avoid * counting this as a dropped packed. */ - sta->rx_stats.packets++; + sta->deflink.rx_stats.packets++; dev_kfree_skb(rx->skb); return RX_QUEUED; } @@ -1893,11 +1894,11 @@ ieee80211_rx_get_bigtk(struct ieee80211_rx_data *rx, int idx) } if (rx->sta) - key = rcu_dereference(rx->sta->gtk[idx]); + key = rcu_dereference(rx->sta->deflink.gtk[idx]); if (!key) key = rcu_dereference(sdata->keys[idx]); if (!key && rx->sta) - key = rcu_dereference(rx->sta->gtk[idx2]); + key = rcu_dereference(rx->sta->deflink.gtk[idx2]); if (!key) key = rcu_dereference(sdata->keys[idx2]); @@ -2012,7 +2013,7 @@ ieee80211_rx_h_decrypt(struct ieee80211_rx_data *rx) test_sta_flag(rx->sta, WLAN_STA_MFP)) return RX_DROP_MONITOR; - rx->key = rcu_dereference(rx->sta->gtk[mmie_keyidx]); + rx->key = rcu_dereference(rx->sta->deflink.gtk[mmie_keyidx]); } if (!rx->key) rx->key = rcu_dereference(rx->sdata->keys[mmie_keyidx]); @@ -2035,7 +2036,7 @@ ieee80211_rx_h_decrypt(struct ieee80211_rx_data *rx) } else { if (rx->sta) { for (i = 0; i < NUM_DEFAULT_KEYS; i++) { - key = rcu_dereference(rx->sta->gtk[i]); + key = rcu_dereference(rx->sta->deflink.gtk[i]); if (key) break; } @@ -2072,7 +2073,7 @@ ieee80211_rx_h_decrypt(struct ieee80211_rx_data *rx) /* check per-station GTK first, if multicast packet */ if (is_multicast_ether_addr(hdr->addr1) && rx->sta) - rx->key = rcu_dereference(rx->sta->gtk[keyidx]); + rx->key = rcu_dereference(rx->sta->deflink.gtk[keyidx]); /* if not found, try default key */ if (!rx->key) { @@ -2398,7 +2399,7 @@ ieee80211_rx_h_defragment(struct ieee80211_rx_data *rx) out: ieee80211_led_rx(rx->local); if (rx->sta) - rx->sta->rx_stats.packets++; + rx->sta->deflink.rx_stats.packets++; return RX_CONTINUE; } @@ -2645,9 +2646,9 @@ ieee80211_deliver_skb(struct ieee80211_rx_data *rx) * for non-QoS-data frames. Here we know it's a data * frame, so count MSDUs. */ - u64_stats_update_begin(&rx->sta->rx_stats.syncp); - rx->sta->rx_stats.msdu[rx->seqno_idx]++; - u64_stats_update_end(&rx->sta->rx_stats.syncp); + u64_stats_update_begin(&rx->sta->deflink.rx_stats.syncp); + rx->sta->deflink.rx_stats.msdu[rx->seqno_idx]++; + u64_stats_update_end(&rx->sta->deflink.rx_stats.syncp); } if ((sdata->vif.type == NL80211_IFTYPE_AP || @@ -3342,7 +3343,7 @@ ieee80211_rx_h_action(struct ieee80211_rx_data *rx) switch (mgmt->u.action.category) { case WLAN_CATEGORY_HT: /* reject HT action frames from stations not supporting HT */ - if (!rx->sta->sta.ht_cap.ht_supported) + if (!rx->sta->sta.deflink.ht_cap.ht_supported) goto invalid; if (sdata->vif.type != NL80211_IFTYPE_STATION && @@ -3406,7 +3407,7 @@ ieee80211_rx_h_action(struct ieee80211_rx_data *rx) struct sta_opmode_info sta_opmode = {}; /* If it doesn't support 40 MHz it can't change ... */ - if (!(rx->sta->sta.ht_cap.cap & + if (!(rx->sta->sta.deflink.ht_cap.cap & IEEE80211_HT_CAP_SUP_WIDTH_20_40)) goto handled; @@ -3416,13 +3417,13 @@ ieee80211_rx_h_action(struct ieee80211_rx_data *rx) max_bw = ieee80211_sta_cap_rx_bw(rx->sta); /* set cur_max_bandwidth and recalc sta bw */ - rx->sta->cur_max_bandwidth = max_bw; + rx->sta->deflink.cur_max_bandwidth = max_bw; new_bw = ieee80211_sta_cur_vht_bw(rx->sta); - if (rx->sta->sta.bandwidth == new_bw) + if (rx->sta->sta.deflink.bandwidth == new_bw) goto handled; - rx->sta->sta.bandwidth = new_bw; + rx->sta->sta.deflink.bandwidth = new_bw; sband = rx->local->hw.wiphy->bands[status->band]; sta_opmode.bw = ieee80211_sta_rx_bw_to_chan_width(rx->sta); @@ -3619,7 +3620,7 @@ ieee80211_rx_h_action(struct ieee80211_rx_data *rx) handled: if (rx->sta) - rx->sta->rx_stats.packets++; + rx->sta->deflink.rx_stats.packets++; dev_kfree_skb(rx->skb); return RX_QUEUED; @@ -3653,7 +3654,7 @@ ieee80211_rx_h_userspace_mgmt(struct ieee80211_rx_data *rx) ieee80211_rx_status_to_khz(status), sig, rx->skb->data, rx->skb->len, 0)) { if (rx->sta) - rx->sta->rx_stats.packets++; + rx->sta->deflink.rx_stats.packets++; dev_kfree_skb(rx->skb); return RX_QUEUED; } @@ -3691,7 +3692,7 @@ ieee80211_rx_h_action_post_userspace(struct ieee80211_rx_data *rx) handled: if (rx->sta) - rx->sta->rx_stats.packets++; + rx->sta->deflink.rx_stats.packets++; dev_kfree_skb(rx->skb); return RX_QUEUED; } @@ -3911,7 +3912,7 @@ static void ieee80211_rx_handlers_result(struct ieee80211_rx_data *rx, case RX_DROP_MONITOR: I802_DEBUG_INC(rx->sdata->local->rx_handlers_drop); if (rx->sta) - rx->sta->rx_stats.dropped++; + rx->sta->deflink.rx_stats.dropped++; fallthrough; case RX_CONTINUE: { struct ieee80211_rate *rate = NULL; @@ -3930,7 +3931,7 @@ static void ieee80211_rx_handlers_result(struct ieee80211_rx_data *rx, case RX_DROP_UNUSABLE: I802_DEBUG_INC(rx->sdata->local->rx_handlers_drop); if (rx->sta) - rx->sta->rx_stats.dropped++; + rx->sta->deflink.rx_stats.dropped++; dev_kfree_skb(rx->skb); break; case RX_QUEUED: @@ -4482,15 +4483,15 @@ static void ieee80211_rx_8023(struct ieee80211_rx_data *rx, void *sa = skb->data + ETH_ALEN; void *da = skb->data; - stats = &sta->rx_stats; + stats = &sta->deflink.rx_stats; if (fast_rx->uses_rss) - stats = this_cpu_ptr(sta->pcpu_rx_stats); + stats = this_cpu_ptr(sta->deflink.pcpu_rx_stats); /* statistics part of ieee80211_rx_h_sta_process() */ if (!(status->flag & RX_FLAG_NO_SIGNAL_VAL)) { stats->last_signal = status->signal; if (!fast_rx->uses_rss) - ewma_signal_add(&sta->rx_stats_avg.signal, + ewma_signal_add(&sta->deflink.rx_stats_avg.signal, -status->signal); } @@ -4506,7 +4507,7 @@ static void ieee80211_rx_8023(struct ieee80211_rx_data *rx, stats->chain_signal_last[i] = signal; if (!fast_rx->uses_rss) - ewma_signal_add(&sta->rx_stats_avg.chain_signal[i], + ewma_signal_add(&sta->deflink.rx_stats_avg.chain_signal[i], -signal); } } @@ -4582,7 +4583,7 @@ static bool ieee80211_invoke_fast_rx(struct ieee80211_rx_data *rx, u8 da[ETH_ALEN]; u8 sa[ETH_ALEN]; } addrs __aligned(2); - struct ieee80211_sta_rx_stats *stats = &sta->rx_stats; + struct ieee80211_sta_rx_stats *stats = &sta->deflink.rx_stats; /* for parallel-rx, we need to have DUP_VALIDATED, otherwise we write * to a common data structure; drivers can implement that per queue @@ -4684,7 +4685,7 @@ static bool ieee80211_invoke_fast_rx(struct ieee80211_rx_data *rx, drop: dev_kfree_skb(skb); if (fast_rx->uses_rss) - stats = this_cpu_ptr(sta->pcpu_rx_stats); + stats = this_cpu_ptr(sta->deflink.pcpu_rx_stats); stats->dropped++; return true; diff --git a/net/mac80211/s1g.c b/net/mac80211/s1g.c index 4141bc80cdfd6..8ca7d45d6daae 100644 --- a/net/mac80211/s1g.c +++ b/net/mac80211/s1g.c @@ -11,8 +11,8 @@ void ieee80211_s1g_sta_rate_init(struct sta_info *sta) { /* avoid indicating legacy bitrates for S1G STAs */ - sta->tx_stats.last_rate.flags |= IEEE80211_TX_RC_S1G_MCS; - sta->rx_stats.last_rate = + sta->deflink.tx_stats.last_rate.flags |= IEEE80211_TX_RC_S1G_MCS; + sta->deflink.rx_stats.last_rate = STA_STATS_FIELD(TYPE, STA_STATS_RATE_TYPE_S1G); } diff --git a/net/mac80211/sta_info.c b/net/mac80211/sta_info.c index 91fbb1ee5c388..e04a0905e9418 100644 --- a/net/mac80211/sta_info.c +++ b/net/mac80211/sta_info.c @@ -287,7 +287,7 @@ void sta_info_free(struct ieee80211_local *local, struct sta_info *sta) #ifdef CONFIG_MAC80211_MESH kfree(sta->mesh); #endif - free_percpu(sta->pcpu_rx_stats); + free_percpu(sta->deflink.pcpu_rx_stats); kfree(sta); } @@ -346,9 +346,9 @@ struct sta_info *sta_info_alloc(struct ieee80211_sub_if_data *sdata, return NULL; if (ieee80211_hw_check(hw, USES_RSS)) { - sta->pcpu_rx_stats = + sta->deflink.pcpu_rx_stats = alloc_percpu_gfp(struct ieee80211_sta_rx_stats, gfp); - if (!sta->pcpu_rx_stats) + if (!sta->deflink.pcpu_rx_stats) goto free; } @@ -376,6 +376,14 @@ struct sta_info *sta_info_alloc(struct ieee80211_sub_if_data *sdata, sta->sta.max_rx_aggregation_subframes = local->hw.max_rx_aggregation_subframes; + /* TODO link specific alloc and assignments for MLO Link STA */ + + /* For non MLO STA, link info can be accessed either via deflink + * or link[0] + */ + sta->link[0] = &sta->deflink; + sta->sta.link[0] = &sta->sta.deflink; + /* Extended Key ID needs to install keys for keyid 0 and 1 Rx-only. * The Tx path starts to use a key as soon as the key slot ptk_idx * references to is not NULL. To not use the initial Rx-only key @@ -387,9 +395,9 @@ struct sta_info *sta_info_alloc(struct ieee80211_sub_if_data *sdata, sta->local = local; sta->sdata = sdata; - sta->rx_stats.last_rx = jiffies; + sta->deflink.rx_stats.last_rx = jiffies; - u64_stats_init(&sta->rx_stats.syncp); + u64_stats_init(&sta->deflink.rx_stats.syncp); ieee80211_init_frag_cache(&sta->frags); @@ -399,10 +407,10 @@ struct sta_info *sta_info_alloc(struct ieee80211_sub_if_data *sdata, sta->reserved_tid = IEEE80211_TID_UNRESERVED; sta->last_connected = ktime_get_seconds(); - ewma_signal_init(&sta->rx_stats_avg.signal); - ewma_avg_signal_init(&sta->status_stats.avg_ack_signal); - for (i = 0; i < ARRAY_SIZE(sta->rx_stats_avg.chain_signal); i++) - ewma_signal_init(&sta->rx_stats_avg.chain_signal[i]); + ewma_signal_init(&sta->deflink.rx_stats_avg.signal); + ewma_avg_signal_init(&sta->deflink.status_stats.avg_ack_signal); + for (i = 0; i < ARRAY_SIZE(sta->deflink.rx_stats_avg.chain_signal); i++) + ewma_signal_init(&sta->deflink.rx_stats_avg.chain_signal[i]); if (local->ops->wake_tx_queue) { void *txq_data; @@ -472,7 +480,7 @@ struct sta_info *sta_info_alloc(struct ieee80211_sub_if_data *sdata, if (!(rate->flags & mandatory)) continue; - sta->sta.supp_rates[i] |= BIT(r); + sta->sta.deflink.supp_rates[i] |= BIT(r); } } @@ -524,7 +532,7 @@ struct sta_info *sta_info_alloc(struct ieee80211_sub_if_data *sdata, if (sta->sta.txq[0]) kfree(to_txq_info(sta->sta.txq[0])); free: - free_percpu(sta->pcpu_rx_stats); + free_percpu(sta->deflink.pcpu_rx_stats); #ifdef CONFIG_MAC80211_MESH kfree(sta->mesh); #endif @@ -2087,16 +2095,16 @@ int sta_info_move_state(struct sta_info *sta, u8 sta_info_tx_streams(struct sta_info *sta) { - struct ieee80211_sta_ht_cap *ht_cap = &sta->sta.ht_cap; + struct ieee80211_sta_ht_cap *ht_cap = &sta->sta.deflink.ht_cap; u8 rx_streams; - if (!sta->sta.ht_cap.ht_supported) + if (!sta->sta.deflink.ht_cap.ht_supported) return 1; - if (sta->sta.vht_cap.vht_supported) { + if (sta->sta.deflink.vht_cap.vht_supported) { int i; u16 tx_mcs_map = - le16_to_cpu(sta->sta.vht_cap.vht_mcs.tx_mcs_map); + le16_to_cpu(sta->sta.deflink.vht_cap.vht_mcs.tx_mcs_map); for (i = 7; i >= 0; i--) if ((tx_mcs_map & (0x3 << (i * 2))) != @@ -2123,16 +2131,16 @@ u8 sta_info_tx_streams(struct sta_info *sta) static struct ieee80211_sta_rx_stats * sta_get_last_rx_stats(struct sta_info *sta) { - struct ieee80211_sta_rx_stats *stats = &sta->rx_stats; + struct ieee80211_sta_rx_stats *stats = &sta->deflink.rx_stats; int cpu; - if (!sta->pcpu_rx_stats) + if (!sta->deflink.pcpu_rx_stats) return stats; for_each_possible_cpu(cpu) { struct ieee80211_sta_rx_stats *cpustats; - cpustats = per_cpu_ptr(sta->pcpu_rx_stats, cpu); + cpustats = per_cpu_ptr(sta->deflink.pcpu_rx_stats, cpu); if (time_after(cpustats->last_rx, stats->last_rx)) stats = cpustats; @@ -2226,13 +2234,15 @@ static void sta_set_tidstats(struct sta_info *sta, int cpu; if (!(tidstats->filled & BIT(NL80211_TID_STATS_RX_MSDU))) { - tidstats->rx_msdu += sta_get_tidstats_msdu(&sta->rx_stats, tid); + tidstats->rx_msdu += sta_get_tidstats_msdu(&sta->deflink.rx_stats, + tid); - if (sta->pcpu_rx_stats) { + if (sta->deflink.pcpu_rx_stats) { for_each_possible_cpu(cpu) { struct ieee80211_sta_rx_stats *cpurxs; - cpurxs = per_cpu_ptr(sta->pcpu_rx_stats, cpu); + cpurxs = per_cpu_ptr(sta->deflink.pcpu_rx_stats, + cpu); tidstats->rx_msdu += sta_get_tidstats_msdu(cpurxs, tid); } @@ -2243,19 +2253,19 @@ static void sta_set_tidstats(struct sta_info *sta, if (!(tidstats->filled & BIT(NL80211_TID_STATS_TX_MSDU))) { tidstats->filled |= BIT(NL80211_TID_STATS_TX_MSDU); - tidstats->tx_msdu = sta->tx_stats.msdu[tid]; + tidstats->tx_msdu = sta->deflink.tx_stats.msdu[tid]; } if (!(tidstats->filled & BIT(NL80211_TID_STATS_TX_MSDU_RETRIES)) && ieee80211_hw_check(&local->hw, REPORTS_TX_ACK_STATUS)) { tidstats->filled |= BIT(NL80211_TID_STATS_TX_MSDU_RETRIES); - tidstats->tx_msdu_retries = sta->status_stats.msdu_retries[tid]; + tidstats->tx_msdu_retries = sta->deflink.status_stats.msdu_retries[tid]; } if (!(tidstats->filled & BIT(NL80211_TID_STATS_TX_MSDU_FAILED)) && ieee80211_hw_check(&local->hw, REPORTS_TX_ACK_STATUS)) { tidstats->filled |= BIT(NL80211_TID_STATS_TX_MSDU_FAILED); - tidstats->tx_msdu_failed = sta->status_stats.msdu_failed[tid]; + tidstats->tx_msdu_failed = sta->deflink.status_stats.msdu_failed[tid]; } if (local->ops->wake_tx_queue && tid < IEEE80211_NUM_TIDS) { @@ -2326,26 +2336,27 @@ void sta_set_sinfo(struct sta_info *sta, struct station_info *sinfo, BIT_ULL(NL80211_STA_INFO_TX_BYTES)))) { sinfo->tx_bytes = 0; for (ac = 0; ac < IEEE80211_NUM_ACS; ac++) - sinfo->tx_bytes += sta->tx_stats.bytes[ac]; + sinfo->tx_bytes += sta->deflink.tx_stats.bytes[ac]; sinfo->filled |= BIT_ULL(NL80211_STA_INFO_TX_BYTES64); } if (!(sinfo->filled & BIT_ULL(NL80211_STA_INFO_TX_PACKETS))) { sinfo->tx_packets = 0; for (ac = 0; ac < IEEE80211_NUM_ACS; ac++) - sinfo->tx_packets += sta->tx_stats.packets[ac]; + sinfo->tx_packets += sta->deflink.tx_stats.packets[ac]; sinfo->filled |= BIT_ULL(NL80211_STA_INFO_TX_PACKETS); } if (!(sinfo->filled & (BIT_ULL(NL80211_STA_INFO_RX_BYTES64) | BIT_ULL(NL80211_STA_INFO_RX_BYTES)))) { - sinfo->rx_bytes += sta_get_stats_bytes(&sta->rx_stats); + sinfo->rx_bytes += sta_get_stats_bytes(&sta->deflink.rx_stats); - if (sta->pcpu_rx_stats) { + if (sta->deflink.pcpu_rx_stats) { for_each_possible_cpu(cpu) { struct ieee80211_sta_rx_stats *cpurxs; - cpurxs = per_cpu_ptr(sta->pcpu_rx_stats, cpu); + cpurxs = per_cpu_ptr(sta->deflink.pcpu_rx_stats, + cpu); sinfo->rx_bytes += sta_get_stats_bytes(cpurxs); } } @@ -2354,12 +2365,13 @@ void sta_set_sinfo(struct sta_info *sta, struct station_info *sinfo, } if (!(sinfo->filled & BIT_ULL(NL80211_STA_INFO_RX_PACKETS))) { - sinfo->rx_packets = sta->rx_stats.packets; - if (sta->pcpu_rx_stats) { + sinfo->rx_packets = sta->deflink.rx_stats.packets; + if (sta->deflink.pcpu_rx_stats) { for_each_possible_cpu(cpu) { struct ieee80211_sta_rx_stats *cpurxs; - cpurxs = per_cpu_ptr(sta->pcpu_rx_stats, cpu); + cpurxs = per_cpu_ptr(sta->deflink.pcpu_rx_stats, + cpu); sinfo->rx_packets += cpurxs->packets; } } @@ -2367,12 +2379,12 @@ void sta_set_sinfo(struct sta_info *sta, struct station_info *sinfo, } if (!(sinfo->filled & BIT_ULL(NL80211_STA_INFO_TX_RETRIES))) { - sinfo->tx_retries = sta->status_stats.retry_count; + sinfo->tx_retries = sta->deflink.status_stats.retry_count; sinfo->filled |= BIT_ULL(NL80211_STA_INFO_TX_RETRIES); } if (!(sinfo->filled & BIT_ULL(NL80211_STA_INFO_TX_FAILED))) { - sinfo->tx_failed = sta->status_stats.retry_failed; + sinfo->tx_failed = sta->deflink.status_stats.retry_failed; sinfo->filled |= BIT_ULL(NL80211_STA_INFO_TX_FAILED); } @@ -2393,12 +2405,12 @@ void sta_set_sinfo(struct sta_info *sta, struct station_info *sinfo, sinfo->filled |= BIT_ULL(NL80211_STA_INFO_AIRTIME_WEIGHT); } - sinfo->rx_dropped_misc = sta->rx_stats.dropped; - if (sta->pcpu_rx_stats) { + sinfo->rx_dropped_misc = sta->deflink.rx_stats.dropped; + if (sta->deflink.pcpu_rx_stats) { for_each_possible_cpu(cpu) { struct ieee80211_sta_rx_stats *cpurxs; - cpurxs = per_cpu_ptr(sta->pcpu_rx_stats, cpu); + cpurxs = per_cpu_ptr(sta->deflink.pcpu_rx_stats, cpu); sinfo->rx_dropped_misc += cpurxs->dropped; } } @@ -2417,10 +2429,10 @@ void sta_set_sinfo(struct sta_info *sta, struct station_info *sinfo, sinfo->filled |= BIT_ULL(NL80211_STA_INFO_SIGNAL); } - if (!sta->pcpu_rx_stats && + if (!sta->deflink.pcpu_rx_stats && !(sinfo->filled & BIT_ULL(NL80211_STA_INFO_SIGNAL_AVG))) { sinfo->signal_avg = - -ewma_signal_read(&sta->rx_stats_avg.signal); + -ewma_signal_read(&sta->deflink.rx_stats_avg.signal); sinfo->filled |= BIT_ULL(NL80211_STA_INFO_SIGNAL_AVG); } } @@ -2433,7 +2445,7 @@ void sta_set_sinfo(struct sta_info *sta, struct station_info *sinfo, !(sinfo->filled & (BIT_ULL(NL80211_STA_INFO_CHAIN_SIGNAL) | BIT_ULL(NL80211_STA_INFO_CHAIN_SIGNAL_AVG)))) { sinfo->filled |= BIT_ULL(NL80211_STA_INFO_CHAIN_SIGNAL); - if (!sta->pcpu_rx_stats) + if (!sta->deflink.pcpu_rx_stats) sinfo->filled |= BIT_ULL(NL80211_STA_INFO_CHAIN_SIGNAL_AVG); sinfo->chains = last_rxstats->chains; @@ -2442,12 +2454,12 @@ void sta_set_sinfo(struct sta_info *sta, struct station_info *sinfo, sinfo->chain_signal[i] = last_rxstats->chain_signal_last[i]; sinfo->chain_signal_avg[i] = - -ewma_signal_read(&sta->rx_stats_avg.chain_signal[i]); + -ewma_signal_read(&sta->deflink.rx_stats_avg.chain_signal[i]); } } if (!(sinfo->filled & BIT_ULL(NL80211_STA_INFO_TX_BITRATE))) { - sta_set_rate_info_tx(sta, &sta->tx_stats.last_rate, + sta_set_rate_info_tx(sta, &sta->deflink.tx_stats.last_rate, &sinfo->txrate); sinfo->filled |= BIT_ULL(NL80211_STA_INFO_TX_BITRATE); } @@ -2529,16 +2541,16 @@ void sta_set_sinfo(struct sta_info *sta, struct station_info *sinfo, } if (!(sinfo->filled & BIT_ULL(NL80211_STA_INFO_ACK_SIGNAL)) && - sta->status_stats.ack_signal_filled) { - sinfo->ack_signal = sta->status_stats.last_ack_signal; + sta->deflink.status_stats.ack_signal_filled) { + sinfo->ack_signal = sta->deflink.status_stats.last_ack_signal; sinfo->filled |= BIT_ULL(NL80211_STA_INFO_ACK_SIGNAL); } if (!(sinfo->filled & BIT_ULL(NL80211_STA_INFO_ACK_SIGNAL_AVG)) && - sta->status_stats.ack_signal_filled) { + sta->deflink.status_stats.ack_signal_filled) { sinfo->avg_ack_signal = -(s8)ewma_avg_signal_read( - &sta->status_stats.avg_ack_signal); + &sta->deflink.status_stats.avg_ack_signal); sinfo->filled |= BIT_ULL(NL80211_STA_INFO_ACK_SIGNAL_AVG); } @@ -2573,10 +2585,10 @@ unsigned long ieee80211_sta_last_active(struct sta_info *sta) { struct ieee80211_sta_rx_stats *stats = sta_get_last_rx_stats(sta); - if (!sta->status_stats.last_ack || - time_after(stats->last_rx, sta->status_stats.last_ack)) + if (!sta->deflink.status_stats.last_ack || + time_after(stats->last_rx, sta->deflink.status_stats.last_ack)) return stats->last_rx; - return sta->status_stats.last_ack; + return sta->deflink.status_stats.last_ack; } static void sta_update_codel_params(struct sta_info *sta, u32 thr) diff --git a/net/mac80211/sta_info.h b/net/mac80211/sta_info.h index 379fd367197f9..35c390bedfba2 100644 --- a/net/mac80211/sta_info.h +++ b/net/mac80211/sta_info.h @@ -483,6 +483,86 @@ struct ieee80211_fragment_cache { */ #define STA_SLOW_THRESHOLD 6000 /* 6 Mbps */ +/** + * struct link_sta_info - Link STA information + * All link specific sta info are stored here for reference. This can be + * a single entry for non-MLD STA or multiple entries for MLD STA + * @addr: Link MAC address - Can be same as MLD STA mac address and is always + * same for non-MLD STA. This is used as key for searching link STA + * @link_id: Link ID uniquely identifying the link STA. This is 0 for non-MLD + * and set to the corresponding vif LinkId for MLD STA + * @sta: Points to the STA info + * @gtk: group keys negotiated with this station, if any + * @tx_stats: TX statistics + * @tx_stats.packets: # of packets transmitted + * @tx_stats.bytes: # of bytes in all packets transmitted + * @tx_stats.last_rate: last TX rate + * @tx_stats.msdu: # of transmitted MSDUs per TID + * @rx_stats: RX statistics + * @rx_stats_avg: averaged RX statistics + * @rx_stats_avg.signal: averaged signal + * @rx_stats_avg.chain_signal: averaged per-chain signal + * @pcpu_rx_stats: per-CPU RX statistics, assigned only if the driver needs + * this (by advertising the USES_RSS hw flag) + * @status_stats: TX status statistics + * @status_stats.filtered: # of filtered frames + * @status_stats.retry_failed: # of frames that failed after retry + * @status_stats.retry_count: # of retries attempted + * @status_stats.lost_packets: # of lost packets + * @status_stats.last_pkt_time: timestamp of last ACKed packet + * @status_stats.msdu_retries: # of MSDU retries + * @status_stats.msdu_failed: # of failed MSDUs + * @status_stats.last_ack: last ack timestamp (jiffies) + * @status_stats.last_ack_signal: last ACK signal + * @status_stats.ack_signal_filled: last ACK signal validity + * @status_stats.avg_ack_signal: average ACK signal + * TODO Move other link params from sta_info as required for MLD operation + */ +struct link_sta_info { + u8 addr[ETH_ALEN]; + u8 link_id; + + /* TODO rhash head/node for finding link_sta based on addr */ + + struct sta_info *sta; + struct ieee80211_key __rcu *gtk[NUM_DEFAULT_KEYS + + NUM_DEFAULT_MGMT_KEYS + + NUM_DEFAULT_BEACON_KEYS]; + struct ieee80211_sta_rx_stats __percpu *pcpu_rx_stats; + + /* Updated from RX path only, no locking requirements */ + struct ieee80211_sta_rx_stats rx_stats; + struct { + struct ewma_signal signal; + struct ewma_signal chain_signal[IEEE80211_MAX_CHAINS]; + } rx_stats_avg; + + /* Updated from TX status path only, no locking requirements */ + struct { + unsigned long filtered; + unsigned long retry_failed, retry_count; + unsigned int lost_packets; + unsigned long last_pkt_time; + u64 msdu_retries[IEEE80211_NUM_TIDS + 1]; + u64 msdu_failed[IEEE80211_NUM_TIDS + 1]; + unsigned long last_ack; + s8 last_ack_signal; + bool ack_signal_filled; + struct ewma_avg_signal avg_ack_signal; + } status_stats; + + /* Updated from TX path only, no locking requirements */ + struct { + u64 packets[IEEE80211_NUM_ACS]; + u64 bytes[IEEE80211_NUM_ACS]; + struct ieee80211_tx_rate last_rate; + struct rate_info last_rate_info; + u64 msdu[IEEE80211_NUM_TIDS + 1]; + } tx_stats; + + enum ieee80211_sta_rx_bandwidth cur_max_bandwidth; +}; + /** * struct sta_info - STA information * @@ -498,7 +578,6 @@ struct ieee80211_fragment_cache { * @sdata: virtual interface this station belongs to * @ptk: peer keys negotiated with this station, if any * @ptk_idx: last installed peer key index - * @gtk: group keys negotiated with this station, if any * @rate_ctrl: rate control algorithm reference * @rate_ctrl_lock: spinlock used to protect rate control data * (data inside the algorithm, so serializes calls there) @@ -544,30 +623,19 @@ struct ieee80211_fragment_cache { * @fast_rx: RX fastpath information * @tdls_chandef: a TDLS peer can have a wider chandef that is compatible to * the BSS one. - * @tx_stats: TX statistics - * @tx_stats.packets: # of packets transmitted - * @tx_stats.bytes: # of bytes in all packets transmitted - * @tx_stats.last_rate: last TX rate - * @tx_stats.msdu: # of transmitted MSDUs per TID - * @rx_stats: RX statistics - * @rx_stats_avg: averaged RX statistics - * @rx_stats_avg.signal: averaged signal - * @rx_stats_avg.chain_signal: averaged per-chain signal - * @pcpu_rx_stats: per-CPU RX statistics, assigned only if the driver needs - * this (by advertising the USES_RSS hw flag) - * @status_stats: TX status statistics - * @status_stats.filtered: # of filtered frames - * @status_stats.retry_failed: # of frames that failed after retry - * @status_stats.retry_count: # of retries attempted - * @status_stats.lost_packets: # of lost packets - * @status_stats.last_pkt_time: timestamp of last ACKed packet - * @status_stats.msdu_retries: # of MSDU retries - * @status_stats.msdu_failed: # of failed MSDUs - * @status_stats.last_ack: last ack timestamp (jiffies) - * @status_stats.last_ack_signal: last ACK signal - * @status_stats.ack_signal_filled: last ACK signal validity - * @status_stats.avg_ack_signal: average ACK signal * @frags: fragment cache + * @multi_link_sta: Identifies if this sta is a MLD STA or regular STA + * @deflink: This is the default link STA information, for non MLO STA all link + * specific STA information is accessed through @deflink or through + * link[0] which points to address of @deflink. For MLO Link STA + * the first added link STA will point to deflink. + * @link: reference to Link Sta entries. For Non MLO STA, except 1st link, + * i.e link[0] all links would be assigned to NULL by default and + * would access link information via @deflink or link[0]. For MLO + * STA, first link STA being added will point its link pointer to + * @deflink address and remaining would be allocated and the address + * would be assigned to link[link_id] where link_id is the id assigned + * by the AP. */ struct sta_info { /* General information, mostly static */ @@ -577,9 +645,6 @@ struct sta_info { u8 addr[ETH_ALEN]; struct ieee80211_local *local; struct ieee80211_sub_if_data *sdata; - struct ieee80211_key __rcu *gtk[NUM_DEFAULT_KEYS + - NUM_DEFAULT_MGMT_KEYS + - NUM_DEFAULT_BEACON_KEYS]; struct ieee80211_key __rcu *ptk[NUM_DEFAULT_KEYS]; u8 ptk_idx; struct rate_control_ref *rate_ctrl; @@ -589,7 +654,6 @@ struct sta_info { struct ieee80211_fast_tx __rcu *fast_tx; struct ieee80211_fast_rx __rcu *fast_rx; - struct ieee80211_sta_rx_stats __percpu *pcpu_rx_stats; #ifdef CONFIG_MAC80211_MESH struct mesh_sta *mesh; @@ -619,38 +683,9 @@ struct sta_info { u64 assoc_at; long last_connected; - /* Updated from RX path only, no locking requirements */ - struct ieee80211_sta_rx_stats rx_stats; - struct { - struct ewma_signal signal; - struct ewma_signal chain_signal[IEEE80211_MAX_CHAINS]; - } rx_stats_avg; - /* Plus 1 for non-QoS frames */ __le16 last_seq_ctrl[IEEE80211_NUM_TIDS + 1]; - /* Updated from TX status path only, no locking requirements */ - struct { - unsigned long filtered; - unsigned long retry_failed, retry_count; - unsigned int lost_packets; - unsigned long last_pkt_time; - u64 msdu_retries[IEEE80211_NUM_TIDS + 1]; - u64 msdu_failed[IEEE80211_NUM_TIDS + 1]; - unsigned long last_ack; - s8 last_ack_signal; - bool ack_signal_filled; - struct ewma_avg_signal avg_ack_signal; - } status_stats; - - /* Updated from TX path only, no locking requirements */ - struct { - u64 packets[IEEE80211_NUM_ACS]; - u64 bytes[IEEE80211_NUM_ACS]; - struct ieee80211_tx_rate last_rate; - struct rate_info last_rate_info; - u64 msdu[IEEE80211_NUM_TIDS + 1]; - } tx_stats; u16 tid_seq[IEEE80211_QOS_CTL_TID_MASK + 1]; struct airtime_info airtime[IEEE80211_NUM_ACS]; @@ -664,8 +699,6 @@ struct sta_info { struct dentry *debugfs_dir; #endif - enum ieee80211_sta_rx_bandwidth cur_max_bandwidth; - enum ieee80211_smps_mode known_smps_mode; const struct ieee80211_cipher_scheme *cipher_scheme; @@ -677,6 +710,10 @@ struct sta_info { struct ieee80211_fragment_cache frags; + bool multi_link_sta; + struct link_sta_info deflink; + struct link_sta_info *link[MAX_STA_LINKS]; + /* keep last! */ struct ieee80211_sta sta; }; diff --git a/net/mac80211/status.c b/net/mac80211/status.c index e81e8a5bb7742..c563fa718d848 100644 --- a/net/mac80211/status.c +++ b/net/mac80211/status.c @@ -72,7 +72,7 @@ static void ieee80211_handle_filtered_frame(struct ieee80211_local *local, info->flags |= IEEE80211_TX_INTFL_RETRANSMISSION; info->flags &= ~IEEE80211_TX_TEMPORARY_FLAGS; - sta->status_stats.filtered++; + sta->deflink.status_stats.filtered++; /* * Clear more-data bit on filtered frames, it might be set @@ -776,7 +776,7 @@ static void ieee80211_lost_packet(struct sta_info *sta, !(info->flags & IEEE80211_TX_STAT_AMPDU)) return; - sta->status_stats.lost_packets++; + sta->deflink.status_stats.lost_packets++; if (sta->sta.tdls) { pkt_time = STA_LOST_TDLS_PKT_TIME; pkt_thr = STA_LOST_PKT_THRESHOLD; @@ -789,13 +789,14 @@ static void ieee80211_lost_packet(struct sta_info *sta, * mechanism. * For non-TDLS, use STA_LOST_PKT_THRESHOLD and STA_LOST_PKT_TIME */ - if (sta->status_stats.lost_packets < pkt_thr || - !time_after(jiffies, sta->status_stats.last_pkt_time + pkt_time)) + if (sta->deflink.status_stats.lost_packets < pkt_thr || + !time_after(jiffies, sta->deflink.status_stats.last_pkt_time + pkt_time)) return; cfg80211_cqm_pktloss_notify(sta->sdata->dev, sta->sta.addr, - sta->status_stats.lost_packets, GFP_ATOMIC); - sta->status_stats.lost_packets = 0; + sta->deflink.status_stats.lost_packets, + GFP_ATOMIC); + sta->deflink.status_stats.lost_packets = 0; } static int ieee80211_tx_get_rates(struct ieee80211_hw *hw, @@ -930,7 +931,7 @@ static void __ieee80211_tx_status(struct ieee80211_hw *hw, if (ieee80211_hw_check(&local->hw, HAS_RATE_CONTROL) && (ieee80211_is_data(hdr->frame_control)) && (rates_idx != -1)) - sta->tx_stats.last_rate = + sta->deflink.tx_stats.last_rate = info->status.rates[rates_idx]; if ((info->flags & IEEE80211_TX_STAT_AMPDU_NO_BACK) && @@ -976,9 +977,9 @@ static void __ieee80211_tx_status(struct ieee80211_hw *hw, return; } else if (ieee80211_is_data_present(fc)) { if (!acked && !noack_success) - sta->status_stats.msdu_failed[tid]++; + sta->deflink.status_stats.msdu_failed[tid]++; - sta->status_stats.msdu_retries[tid] += + sta->deflink.status_stats.msdu_retries[tid] += retry_count; } @@ -1111,7 +1112,7 @@ void ieee80211_tx_status_ext(struct ieee80211_hw *hw, sta = container_of(pubsta, struct sta_info, sta); if (status->rate) - sta->tx_stats.last_rate_info = *status->rate; + sta->deflink.tx_stats.last_rate_info = *status->rate; } if (skb && (tx_time_est = @@ -1142,8 +1143,8 @@ void ieee80211_tx_status_ext(struct ieee80211_hw *hw, struct ieee80211_sub_if_data *sdata = sta->sdata; if (!acked && !noack_success) - sta->status_stats.retry_failed++; - sta->status_stats.retry_count += retry_count; + sta->deflink.status_stats.retry_failed++; + sta->deflink.status_stats.retry_count += retry_count; if (ieee80211_hw_check(&local->hw, REPORTS_TX_ACK_STATUS)) { if (sdata->vif.type == NL80211_IFTYPE_STATION && @@ -1152,13 +1153,13 @@ void ieee80211_tx_status_ext(struct ieee80211_hw *hw, acked, info->status.tx_time); if (acked) { - sta->status_stats.last_ack = jiffies; + sta->deflink.status_stats.last_ack = jiffies; - if (sta->status_stats.lost_packets) - sta->status_stats.lost_packets = 0; + if (sta->deflink.status_stats.lost_packets) + sta->deflink.status_stats.lost_packets = 0; /* Track when last packet was ACKed */ - sta->status_stats.last_pkt_time = jiffies; + sta->deflink.status_stats.last_pkt_time = jiffies; /* Reset connection monitor */ if (sdata->vif.type == NL80211_IFTYPE_STATION && @@ -1166,10 +1167,10 @@ void ieee80211_tx_status_ext(struct ieee80211_hw *hw, sdata->u.mgd.probe_send_count = 0; if (ack_signal_valid) { - sta->status_stats.last_ack_signal = + sta->deflink.status_stats.last_ack_signal = (s8)info->status.ack_signal; - sta->status_stats.ack_signal_filled = true; - ewma_avg_signal_add(&sta->status_stats.avg_ack_signal, + sta->deflink.status_stats.ack_signal_filled = true; + ewma_avg_signal_add(&sta->deflink.status_stats.avg_ack_signal, -info->status.ack_signal); } } else if (test_sta_flag(sta, WLAN_STA_PS_STA)) { @@ -1235,7 +1236,7 @@ void ieee80211_tx_rate_update(struct ieee80211_hw *hw, rate_control_tx_status(local, sband, &status); if (ieee80211_hw_check(&local->hw, HAS_RATE_CONTROL)) - sta->tx_stats.last_rate = info->status.rates[0]; + sta->deflink.tx_stats.last_rate = info->status.rates[0]; } EXPORT_SYMBOL(ieee80211_tx_rate_update); diff --git a/net/mac80211/tdls.c b/net/mac80211/tdls.c index 137be9ec94af1..4e2d22e47429a 100644 --- a/net/mac80211/tdls.c +++ b/net/mac80211/tdls.c @@ -459,9 +459,9 @@ ieee80211_tdls_add_setup_start_ies(struct ieee80211_sub_if_data *sdata, pos = skb_put(skb, sizeof(struct ieee80211_ht_cap) + 2); ieee80211_ie_build_ht_cap(pos, &ht_cap, ht_cap.cap); } else if (action_code == WLAN_TDLS_SETUP_RESPONSE && - ht_cap.ht_supported && sta->sta.ht_cap.ht_supported) { + ht_cap.ht_supported && sta->sta.deflink.ht_cap.ht_supported) { /* the peer caps are already intersected with our own */ - memcpy(&ht_cap, &sta->sta.ht_cap, sizeof(ht_cap)); + memcpy(&ht_cap, &sta->sta.deflink.ht_cap, sizeof(ht_cap)); pos = skb_put(skb, sizeof(struct ieee80211_ht_cap) + 2); ieee80211_ie_build_ht_cap(pos, &ht_cap, ht_cap.cap); @@ -510,9 +510,9 @@ ieee80211_tdls_add_setup_start_ies(struct ieee80211_sub_if_data *sdata, pos = skb_put(skb, sizeof(struct ieee80211_vht_cap) + 2); ieee80211_ie_build_vht_cap(pos, &vht_cap, vht_cap.cap); } else if (action_code == WLAN_TDLS_SETUP_RESPONSE && - vht_cap.vht_supported && sta->sta.vht_cap.vht_supported) { + vht_cap.vht_supported && sta->sta.deflink.vht_cap.vht_supported) { /* the peer caps are already intersected with our own */ - memcpy(&vht_cap, &sta->sta.vht_cap, sizeof(vht_cap)); + memcpy(&vht_cap, &sta->sta.deflink.vht_cap, sizeof(vht_cap)); /* the AID is present only when VHT is implemented */ ieee80211_tdls_add_aid(sdata, skb); @@ -603,13 +603,13 @@ ieee80211_tdls_add_setup_cfm_ies(struct ieee80211_sub_if_data *sdata, * if HT support is only added in TDLS, we need an HT-operation IE. * add the IE as required by IEEE802.11-2012 9.23.3.2. */ - if (!ap_sta->sta.ht_cap.ht_supported && sta->sta.ht_cap.ht_supported) { + if (!ap_sta->sta.deflink.ht_cap.ht_supported && sta->sta.deflink.ht_cap.ht_supported) { u16 prot = IEEE80211_HT_OP_MODE_PROTECTION_NONHT_MIXED | IEEE80211_HT_OP_MODE_NON_GF_STA_PRSNT | IEEE80211_HT_OP_MODE_NON_HT_STA_PRSNT; pos = skb_put(skb, 2 + sizeof(struct ieee80211_ht_operation)); - ieee80211_ie_build_ht_oper(pos, &sta->sta.ht_cap, + ieee80211_ie_build_ht_oper(pos, &sta->sta.deflink.ht_cap, &sdata->vif.bss_conf.chandef, prot, true); } @@ -618,7 +618,7 @@ ieee80211_tdls_add_setup_cfm_ies(struct ieee80211_sub_if_data *sdata, /* only include VHT-operation if not on the 2.4GHz band */ if (sband->band != NL80211_BAND_2GHZ && - sta->sta.vht_cap.vht_supported) { + sta->sta.deflink.vht_cap.vht_supported) { /* * if both peers support WIDER_BW, we can expand the chandef to * a wider compatible one, up to 80MHz @@ -627,7 +627,7 @@ ieee80211_tdls_add_setup_cfm_ies(struct ieee80211_sub_if_data *sdata, ieee80211_tdls_chandef_vht_upgrade(sdata, sta); pos = skb_put(skb, 2 + sizeof(struct ieee80211_vht_operation)); - ieee80211_ie_build_vht_oper(pos, &sta->sta.vht_cap, + ieee80211_ie_build_vht_oper(pos, &sta->sta.deflink.vht_cap, &sta->tdls_chandef); } @@ -1269,8 +1269,8 @@ static void iee80211_tdls_recalc_chanctx(struct ieee80211_sub_if_data *sdata, bw = ieee80211_chan_width_to_rx_bw(conf->def.width); bw = min(bw, ieee80211_sta_cap_rx_bw(sta)); - if (bw != sta->sta.bandwidth) { - sta->sta.bandwidth = bw; + if (bw != sta->sta.deflink.bandwidth) { + sta->sta.deflink.bandwidth = bw; rate_control_rate_update(local, sband, sta, IEEE80211_RC_BW_CHANGED); /* @@ -1296,7 +1296,7 @@ static int iee80211_tdls_have_ht_peers(struct ieee80211_sub_if_data *sdata) if (!sta->sta.tdls || sta->sdata != sdata || !sta->uploaded || !test_sta_flag(sta, WLAN_STA_AUTHORIZED) || !test_sta_flag(sta, WLAN_STA_TDLS_PEER_AUTH) || - !sta->sta.ht_cap.ht_supported) + !sta->sta.deflink.ht_cap.ht_supported) continue; result = true; break; @@ -1321,7 +1321,7 @@ iee80211_tdls_recalc_ht_protection(struct ieee80211_sub_if_data *sdata, if (!(ifmgd->flags & IEEE80211_STA_DISABLE_HT)) return; - tdls_ht = (sta && sta->sta.ht_cap.ht_supported) || + tdls_ht = (sta && sta->sta.deflink.ht_cap.ht_supported) || iee80211_tdls_have_ht_peers(sdata); opmode = sdata->vif.bss_conf.ht_operation_mode; @@ -1900,7 +1900,7 @@ ieee80211_process_tdls_channel_switch_req(struct ieee80211_sub_if_data *sdata, } /* peer should have known better */ - if (!sta->sta.ht_cap.ht_supported && elems->sec_chan_offs && + if (!sta->sta.deflink.ht_cap.ht_supported && elems->sec_chan_offs && elems->sec_chan_offs->sec_chan_offs) { tdls_dbg(sdata, "TDLS chan switch - wide chan unsupported\n"); ret = -ENOTSUPP; diff --git a/net/mac80211/trace.h b/net/mac80211/trace.h index d91498f777964..743adfbb9b157 100644 --- a/net/mac80211/trace.h +++ b/net/mac80211/trace.h @@ -860,8 +860,8 @@ TRACE_EVENT(drv_sta_set_txpwr, LOCAL_ASSIGN; VIF_ASSIGN; STA_ASSIGN; - __entry->txpwr = sta->txpwr.power; - __entry->type = sta->txpwr.type; + __entry->txpwr = sta->deflink.txpwr.power; + __entry->type = sta->deflink.txpwr.type; ), TP_printk( diff --git a/net/mac80211/tx.c b/net/mac80211/tx.c index b6b20f38de0ec..13253eb39d093 100644 --- a/net/mac80211/tx.c +++ b/net/mac80211/tx.c @@ -768,9 +768,9 @@ ieee80211_tx_h_rate_ctrl(struct ieee80211_tx_data *tx) if (txrc.reported_rate.idx < 0) { txrc.reported_rate = tx->rate; if (tx->sta && ieee80211_is_tx_data(tx->skb)) - tx->sta->tx_stats.last_rate = txrc.reported_rate; + tx->sta->deflink.tx_stats.last_rate = txrc.reported_rate; } else if (tx->sta) - tx->sta->tx_stats.last_rate = txrc.reported_rate; + tx->sta->deflink.tx_stats.last_rate = txrc.reported_rate; if (ratetbl) return TX_CONTINUE; @@ -837,7 +837,7 @@ ieee80211_tx_h_sequence(struct ieee80211_tx_data *tx) hdr->seq_ctrl = cpu_to_le16(tx->sdata->sequence_number); tx->sdata->sequence_number += 0x10; if (tx->sta) - tx->sta->tx_stats.msdu[IEEE80211_NUM_TIDS]++; + tx->sta->deflink.tx_stats.msdu[IEEE80211_NUM_TIDS]++; return TX_CONTINUE; } @@ -851,7 +851,7 @@ ieee80211_tx_h_sequence(struct ieee80211_tx_data *tx) /* include per-STA, per-TID sequence counter */ tid = ieee80211_get_tid(hdr); - tx->sta->tx_stats.msdu[tid]++; + tx->sta->deflink.tx_stats.msdu[tid]++; hdr->seq_ctrl = ieee80211_tx_next_seq(tx->sta, tid); @@ -1004,10 +1004,10 @@ ieee80211_tx_h_stats(struct ieee80211_tx_data *tx) skb_queue_walk(&tx->skbs, skb) { ac = skb_get_queue_mapping(skb); - tx->sta->tx_stats.bytes[ac] += skb->len; + tx->sta->deflink.tx_stats.bytes[ac] += skb->len; } if (ac >= 0) - tx->sta->tx_stats.packets[ac]++; + tx->sta->deflink.tx_stats.packets[ac]++; return TX_CONTINUE; } @@ -1159,7 +1159,7 @@ ieee80211_aggr_check(struct ieee80211_sub_if_data *sdata, if (!ref || !(ref->ops->capa & RATE_CTRL_CAPA_AMPDU_TRIGGER)) return; - if (!sta || !sta->sta.ht_cap.ht_supported || + if (!sta || !sta->sta.deflink.ht_cap.ht_supported || !sta->sta.wme || skb_get_queue_mapping(skb) == IEEE80211_AC_VO || skb->protocol == sdata->control_port_protocol) return; @@ -3462,18 +3462,18 @@ ieee80211_xmit_fast_finish(struct ieee80211_sub_if_data *sdata, } if (skb_shinfo(skb)->gso_size) - sta->tx_stats.msdu[tid] += + sta->deflink.tx_stats.msdu[tid] += DIV_ROUND_UP(skb->len, skb_shinfo(skb)->gso_size); else - sta->tx_stats.msdu[tid]++; + sta->deflink.tx_stats.msdu[tid]++; info->hw_queue = sdata->vif.hw_queue[skb_get_queue_mapping(skb)]; /* statistics normally done by ieee80211_tx_h_stats (but that * has to consider fragmentation, so is more complex) */ - sta->tx_stats.bytes[skb_get_queue_mapping(skb)] += skb->len; - sta->tx_stats.packets[skb_get_queue_mapping(skb)]++; + sta->deflink.tx_stats.bytes[skb_get_queue_mapping(skb)] += skb->len; + sta->deflink.tx_stats.packets[skb_get_queue_mapping(skb)]++; if (pn_offs) { u64 pn; @@ -4481,8 +4481,8 @@ static void ieee80211_8023_xmit(struct ieee80211_sub_if_data *sdata, dev_sw_netstats_tx_add(dev, 1, skb->len); - sta->tx_stats.bytes[skb_get_queue_mapping(skb)] += skb->len; - sta->tx_stats.packets[skb_get_queue_mapping(skb)]++; + sta->deflink.tx_stats.bytes[skb_get_queue_mapping(skb)] += skb->len; + sta->deflink.tx_stats.packets[skb_get_queue_mapping(skb)]++; if (sdata->vif.type == NL80211_IFTYPE_AP_VLAN) sdata = container_of(sdata->bss, diff --git a/net/mac80211/vht.c b/net/mac80211/vht.c index 8f16aa9c725d9..ff26e0c4787b0 100644 --- a/net/mac80211/vht.c +++ b/net/mac80211/vht.c @@ -118,14 +118,14 @@ ieee80211_vht_cap_ie_to_sta_vht_cap(struct ieee80211_sub_if_data *sdata, const struct ieee80211_vht_cap *vht_cap_ie, struct sta_info *sta) { - struct ieee80211_sta_vht_cap *vht_cap = &sta->sta.vht_cap; + struct ieee80211_sta_vht_cap *vht_cap = &sta->sta.deflink.vht_cap; struct ieee80211_sta_vht_cap own_cap; u32 cap_info, i; bool have_80mhz; memset(vht_cap, 0, sizeof(*vht_cap)); - if (!sta->sta.ht_cap.ht_supported) + if (!sta->sta.deflink.ht_cap.ht_supported) return; if (!vht_cap_ie || !sband->vht_cap.vht_supported) @@ -295,10 +295,10 @@ ieee80211_vht_cap_ie_to_sta_vht_cap(struct ieee80211_sub_if_data *sdata, switch (vht_cap->cap & IEEE80211_VHT_CAP_SUPP_CHAN_WIDTH_MASK) { case IEEE80211_VHT_CAP_SUPP_CHAN_WIDTH_160MHZ: case IEEE80211_VHT_CAP_SUPP_CHAN_WIDTH_160_80PLUS80MHZ: - sta->cur_max_bandwidth = IEEE80211_STA_RX_BW_160; + sta->deflink.cur_max_bandwidth = IEEE80211_STA_RX_BW_160; break; default: - sta->cur_max_bandwidth = IEEE80211_STA_RX_BW_80; + sta->deflink.cur_max_bandwidth = IEEE80211_STA_RX_BW_80; if (!(vht_cap->vht_mcs.tx_highest & cpu_to_le16(IEEE80211_VHT_EXT_NSS_BW_CAPABLE))) @@ -310,10 +310,10 @@ ieee80211_vht_cap_ie_to_sta_vht_cap(struct ieee80211_sub_if_data *sdata, * above) between 160 and 80+80 yet. */ if (cap_info & IEEE80211_VHT_CAP_EXT_NSS_BW_MASK) - sta->cur_max_bandwidth = IEEE80211_STA_RX_BW_160; + sta->deflink.cur_max_bandwidth = IEEE80211_STA_RX_BW_160; } - sta->sta.bandwidth = ieee80211_sta_cur_vht_bw(sta); + sta->sta.deflink.bandwidth = ieee80211_sta_cur_vht_bw(sta); switch (vht_cap->cap & IEEE80211_VHT_CAP_MAX_MPDU_MASK) { case IEEE80211_VHT_CAP_MAX_MPDU_LENGTH_11454: @@ -332,9 +332,9 @@ ieee80211_vht_cap_ie_to_sta_vht_cap(struct ieee80211_sub_if_data *sdata, /* FIXME: move this to some better location - parses HE/EHT now */ enum ieee80211_sta_rx_bandwidth ieee80211_sta_cap_rx_bw(struct sta_info *sta) { - struct ieee80211_sta_vht_cap *vht_cap = &sta->sta.vht_cap; - struct ieee80211_sta_he_cap *he_cap = &sta->sta.he_cap; - struct ieee80211_sta_eht_cap *eht_cap = &sta->sta.eht_cap; + struct ieee80211_sta_vht_cap *vht_cap = &sta->sta.deflink.vht_cap; + struct ieee80211_sta_he_cap *he_cap = &sta->sta.deflink.he_cap; + struct ieee80211_sta_eht_cap *eht_cap = &sta->sta.deflink.eht_cap; u32 cap_width; if (he_cap->has_he) { @@ -369,7 +369,7 @@ enum ieee80211_sta_rx_bandwidth ieee80211_sta_cap_rx_bw(struct sta_info *sta) } if (!vht_cap->vht_supported) - return sta->sta.ht_cap.cap & IEEE80211_HT_CAP_SUP_WIDTH_20_40 ? + return sta->sta.deflink.ht_cap.cap & IEEE80211_HT_CAP_SUP_WIDTH_20_40 ? IEEE80211_STA_RX_BW_40 : IEEE80211_STA_RX_BW_20; @@ -392,14 +392,14 @@ enum ieee80211_sta_rx_bandwidth ieee80211_sta_cap_rx_bw(struct sta_info *sta) enum nl80211_chan_width ieee80211_sta_cap_chan_bw(struct sta_info *sta) { - struct ieee80211_sta_vht_cap *vht_cap = &sta->sta.vht_cap; + struct ieee80211_sta_vht_cap *vht_cap = &sta->sta.deflink.vht_cap; u32 cap_width; if (!vht_cap->vht_supported) { - if (!sta->sta.ht_cap.ht_supported) + if (!sta->sta.deflink.ht_cap.ht_supported) return NL80211_CHAN_WIDTH_20_NOHT; - return sta->sta.ht_cap.cap & IEEE80211_HT_CAP_SUP_WIDTH_20_40 ? + return sta->sta.deflink.ht_cap.cap & IEEE80211_HT_CAP_SUP_WIDTH_20_40 ? NL80211_CHAN_WIDTH_40 : NL80211_CHAN_WIDTH_20; } @@ -416,13 +416,13 @@ enum nl80211_chan_width ieee80211_sta_cap_chan_bw(struct sta_info *sta) enum nl80211_chan_width ieee80211_sta_rx_bw_to_chan_width(struct sta_info *sta) { - enum ieee80211_sta_rx_bandwidth cur_bw = sta->sta.bandwidth; - struct ieee80211_sta_vht_cap *vht_cap = &sta->sta.vht_cap; + enum ieee80211_sta_rx_bandwidth cur_bw = sta->sta.deflink.bandwidth; + struct ieee80211_sta_vht_cap *vht_cap = &sta->sta.deflink.vht_cap; u32 cap_width; switch (cur_bw) { case IEEE80211_STA_RX_BW_20: - if (!sta->sta.ht_cap.ht_supported) + if (!sta->sta.deflink.ht_cap.ht_supported) return NL80211_CHAN_WIDTH_20_NOHT; else return NL80211_CHAN_WIDTH_20; @@ -473,7 +473,7 @@ enum ieee80211_sta_rx_bandwidth ieee80211_sta_cur_vht_bw(struct sta_info *sta) enum nl80211_chan_width bss_width = sdata->vif.bss_conf.chandef.width; bw = ieee80211_sta_cap_rx_bw(sta); - bw = min(bw, sta->cur_max_bandwidth); + bw = min(bw, sta->deflink.cur_max_bandwidth); /* Don't consider AP's bandwidth for TDLS peers, section 11.23.1 of * IEEE80211-2016 specification makes higher bandwidth operation @@ -501,12 +501,12 @@ void ieee80211_sta_set_rx_nss(struct sta_info *sta) bool support_160; /* if we received a notification already don't overwrite it */ - if (sta->sta.rx_nss) + if (sta->sta.deflink.rx_nss) return; - if (sta->sta.eht_cap.has_eht) { + if (sta->sta.deflink.eht_cap.has_eht) { int i; - const u8 *rx_nss_mcs = (void *)&sta->sta.eht_cap.eht_mcs_nss_supp; + const u8 *rx_nss_mcs = (void *)&sta->sta.deflink.eht_cap.eht_mcs_nss_supp; /* get the max nss for EHT over all possible bandwidths and mcs */ for (i = 0; i < sizeof(struct ieee80211_eht_mcs_nss_supp); i++) @@ -515,10 +515,10 @@ void ieee80211_sta_set_rx_nss(struct sta_info *sta) IEEE80211_EHT_MCS_NSS_RX)); } - if (sta->sta.he_cap.has_he) { + if (sta->sta.deflink.he_cap.has_he) { int i; u8 rx_mcs_80 = 0, rx_mcs_160 = 0; - const struct ieee80211_sta_he_cap *he_cap = &sta->sta.he_cap; + const struct ieee80211_sta_he_cap *he_cap = &sta->sta.deflink.he_cap; u16 mcs_160_map = le16_to_cpu(he_cap->he_mcs_nss_supp.rx_mcs_160); u16 mcs_80_map = le16_to_cpu(he_cap->he_mcs_nss_supp.rx_mcs_80); @@ -549,23 +549,23 @@ void ieee80211_sta_set_rx_nss(struct sta_info *sta) he_rx_nss = rx_mcs_80; } - if (sta->sta.ht_cap.ht_supported) { - if (sta->sta.ht_cap.mcs.rx_mask[0]) + if (sta->sta.deflink.ht_cap.ht_supported) { + if (sta->sta.deflink.ht_cap.mcs.rx_mask[0]) ht_rx_nss++; - if (sta->sta.ht_cap.mcs.rx_mask[1]) + if (sta->sta.deflink.ht_cap.mcs.rx_mask[1]) ht_rx_nss++; - if (sta->sta.ht_cap.mcs.rx_mask[2]) + if (sta->sta.deflink.ht_cap.mcs.rx_mask[2]) ht_rx_nss++; - if (sta->sta.ht_cap.mcs.rx_mask[3]) + if (sta->sta.deflink.ht_cap.mcs.rx_mask[3]) ht_rx_nss++; /* FIXME: consider rx_highest? */ } - if (sta->sta.vht_cap.vht_supported) { + if (sta->sta.deflink.vht_cap.vht_supported) { int i; u16 rx_mcs_map; - rx_mcs_map = le16_to_cpu(sta->sta.vht_cap.vht_mcs.rx_mcs_map); + rx_mcs_map = le16_to_cpu(sta->sta.deflink.vht_cap.vht_mcs.rx_mcs_map); for (i = 7; i >= 0; i--) { u8 mcs = (rx_mcs_map >> (2 * i)) & 3; @@ -581,7 +581,7 @@ void ieee80211_sta_set_rx_nss(struct sta_info *sta) rx_nss = max(vht_rx_nss, ht_rx_nss); rx_nss = max(he_rx_nss, rx_nss); rx_nss = max(eht_rx_nss, rx_nss); - sta->sta.rx_nss = max_t(u8, 1, rx_nss); + sta->sta.deflink.rx_nss = max_t(u8, 1, rx_nss); } u32 __ieee80211_vht_handle_opmode(struct ieee80211_sub_if_data *sdata, @@ -601,8 +601,8 @@ u32 __ieee80211_vht_handle_opmode(struct ieee80211_sub_if_data *sdata, nss >>= IEEE80211_OPMODE_NOTIF_RX_NSS_SHIFT; nss += 1; - if (sta->sta.rx_nss != nss) { - sta->sta.rx_nss = nss; + if (sta->sta.deflink.rx_nss != nss) { + sta->sta.deflink.rx_nss = nss; sta_opmode.rx_nss = nss; changed |= IEEE80211_RC_NSS_CHANGED; sta_opmode.changed |= STA_OPMODE_N_SS_CHANGED; @@ -611,27 +611,27 @@ u32 __ieee80211_vht_handle_opmode(struct ieee80211_sub_if_data *sdata, switch (opmode & IEEE80211_OPMODE_NOTIF_CHANWIDTH_MASK) { case IEEE80211_OPMODE_NOTIF_CHANWIDTH_20MHZ: /* ignore IEEE80211_OPMODE_NOTIF_BW_160_80P80 must not be set */ - sta->cur_max_bandwidth = IEEE80211_STA_RX_BW_20; + sta->deflink.cur_max_bandwidth = IEEE80211_STA_RX_BW_20; break; case IEEE80211_OPMODE_NOTIF_CHANWIDTH_40MHZ: /* ignore IEEE80211_OPMODE_NOTIF_BW_160_80P80 must not be set */ - sta->cur_max_bandwidth = IEEE80211_STA_RX_BW_40; + sta->deflink.cur_max_bandwidth = IEEE80211_STA_RX_BW_40; break; case IEEE80211_OPMODE_NOTIF_CHANWIDTH_80MHZ: if (opmode & IEEE80211_OPMODE_NOTIF_BW_160_80P80) - sta->cur_max_bandwidth = IEEE80211_STA_RX_BW_160; + sta->deflink.cur_max_bandwidth = IEEE80211_STA_RX_BW_160; else - sta->cur_max_bandwidth = IEEE80211_STA_RX_BW_80; + sta->deflink.cur_max_bandwidth = IEEE80211_STA_RX_BW_80; break; case IEEE80211_OPMODE_NOTIF_CHANWIDTH_160MHZ: /* legacy only, no longer used by newer spec */ - sta->cur_max_bandwidth = IEEE80211_STA_RX_BW_160; + sta->deflink.cur_max_bandwidth = IEEE80211_STA_RX_BW_160; break; } new_bw = ieee80211_sta_cur_vht_bw(sta); - if (new_bw != sta->sta.bandwidth) { - sta->sta.bandwidth = new_bw; + if (new_bw != sta->sta.deflink.bandwidth) { + sta->sta.deflink.bandwidth = new_bw; sta_opmode.bw = ieee80211_sta_rx_bw_to_chan_width(sta); changed |= IEEE80211_RC_BW_CHANGED; sta_opmode.changed |= STA_OPMODE_MAX_BW_CHANGED; From 24584d4f0afc75faa57883dd694e0df61af0ad40 Mon Sep 17 00:00:00 2001 From: Peter Seiderer Date: Sat, 2 Apr 2022 17:30:13 +0200 Subject: [PATCH 110/228] ath9k: fix ath_get_rate_txpower() to respect the rate list end tag MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Stop reading (and copying) from ieee80211_tx_rate to ath_tx_info.rates after list end tag (count == 0, idx < 0), prevents copying of garbage to card registers. Note: no need to write to the remaining ath_tx_info.rates entries as the complete ath_tx_info struct is already initialized to zero from both call sites. Signed-off-by: Peter Seiderer Acked-by: Toke Høiland-Jørgensen Signed-off-by: Kalle Valo Link: https://lore.kernel.org/r/20220402153014.31332-1-ps.report@gmx.net --- drivers/net/wireless/ath/ath9k/xmit.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/net/wireless/ath/ath9k/xmit.c b/drivers/net/wireless/ath/ath9k/xmit.c index d0caf1de2bdec..ec9bad2d95100 100644 --- a/drivers/net/wireless/ath/ath9k/xmit.c +++ b/drivers/net/wireless/ath/ath9k/xmit.c @@ -1271,7 +1271,7 @@ static void ath_buf_set_rate(struct ath_softc *sc, struct ath_buf *bf, int phy; if (!rates[i].count || (rates[i].idx < 0)) - continue; + break; rix = rates[i].idx; info->rates[i].Tries = rates[i].count; From 405342ebea2ab776df070ee54c308f1f59723844 Mon Sep 17 00:00:00 2001 From: Colin Ian King Date: Thu, 7 Apr 2022 11:28:20 +0100 Subject: [PATCH 111/228] ath11k: Fix spelling mistake "reseting" -> "resetting" There is a spelling mistake in an ath11k_warn message. Fix it. Signed-off-by: Colin Ian King Signed-off-by: Kalle Valo Link: https://lore.kernel.org/r/20220407102820.613881-1-colin.i.king@gmail.com --- drivers/net/wireless/ath/ath11k/core.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/net/wireless/ath/ath11k/core.c b/drivers/net/wireless/ath/ath11k/core.c index cbac1919867f7..1537ec0ae2e7e 100644 --- a/drivers/net/wireless/ath/ath11k/core.c +++ b/drivers/net/wireless/ath/ath11k/core.c @@ -1567,7 +1567,7 @@ static void ath11k_core_reset(struct work_struct *work) * completed, then the second reset worker will destroy the previous one, * thus below is to avoid that. */ - ath11k_warn(ab, "already reseting count %d\n", reset_count); + ath11k_warn(ab, "already resetting count %d\n", reset_count); reinit_completion(&ab->reset_complete); time_left = wait_for_completion_timeout(&ab->reset_complete, From 2578171ff85ed71d2575cd6abcd9c37c4b642b52 Mon Sep 17 00:00:00 2001 From: Yang Li Date: Fri, 8 Apr 2022 08:01:12 +0800 Subject: [PATCH 112/228] wcn36xx: clean up some inconsistent indenting Eliminate the follow smatch warning: drivers/net/wireless/ath/wcn36xx/smd.c:3151 wcn36xx_smd_gtk_offload_get_info_rsp() warn: inconsistent indenting Reported-by: Abaci Robot Signed-off-by: Yang Li Acked-by: Loic Poulain Signed-off-by: Kalle Valo Link: https://lore.kernel.org/r/20220408000113.129906-1-yang.lee@linux.alibaba.com --- drivers/net/wireless/ath/wcn36xx/smd.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/drivers/net/wireless/ath/wcn36xx/smd.c b/drivers/net/wireless/ath/wcn36xx/smd.c index 872b37875c574..691e637b94f18 100644 --- a/drivers/net/wireless/ath/wcn36xx/smd.c +++ b/drivers/net/wireless/ath/wcn36xx/smd.c @@ -3148,9 +3148,9 @@ static int wcn36xx_smd_gtk_offload_get_info_rsp(struct wcn36xx *wcn, cpu_to_le64(rsp->key_replay_counter); ieee80211_gtk_rekey_notify(vif, vif->bss_conf.bssid, (void *)&replay_ctr, GFP_KERNEL); - wcn36xx_dbg(WCN36XX_DBG_HAL, - "GTK replay counter increment %llu\n", - rsp->key_replay_counter); + wcn36xx_dbg(WCN36XX_DBG_HAL, + "GTK replay counter increment %llu\n", + rsp->key_replay_counter); } wcn36xx_dbg(WCN36XX_DBG_HAL, From d7ceee8051ba226f1a481edadd06e34e200fcbab Mon Sep 17 00:00:00 2001 From: Yang Li Date: Fri, 8 Apr 2022 08:01:13 +0800 Subject: [PATCH 113/228] ath9k: Remove unnecessary print function dev_err() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The print function dev_err() is redundant because platform_get_irq_byname() already prints an error. Eliminate the follow coccicheck warning: ./drivers/net/wireless/ath/ath9k/ahb.c:103:2-9: line 103 is redundant because platform_get_irq() already prints an error Reported-by: Abaci Robot Signed-off-by: Yang Li Acked-by: Toke Høiland-Jørgensen Signed-off-by: Kalle Valo Link: https://lore.kernel.org/r/20220408000113.129906-2-yang.lee@linux.alibaba.com --- drivers/net/wireless/ath/ath9k/ahb.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/drivers/net/wireless/ath/ath9k/ahb.c b/drivers/net/wireless/ath/ath9k/ahb.c index c9b853af41d1d..9cd12b20b18d8 100644 --- a/drivers/net/wireless/ath/ath9k/ahb.c +++ b/drivers/net/wireless/ath/ath9k/ahb.c @@ -99,10 +99,8 @@ static int ath_ahb_probe(struct platform_device *pdev) } irq = platform_get_irq(pdev, 0); - if (irq < 0) { - dev_err(&pdev->dev, "no IRQ resource found\n"); + if (irq < 0) return irq; - } ath9k_fill_chanctx_ops(); hw = ieee80211_alloc_hw(sizeof(struct ath_softc), &ath9k_ops); From 5ddfffd6da9b94e5f6397843ad1a54d6a211f652 Mon Sep 17 00:00:00 2001 From: Zong-Zhe Yang Date: Fri, 8 Apr 2022 08:13:41 +0800 Subject: [PATCH 114/228] rtw89: ser: fix unannotated fall-through add `break` to fix warning of unannotated fall-through between switch labels. Fixes: 14f9f4790048 ("rtw89: ser: control hci interrupts on/off by state") Signed-off-by: Zong-Zhe Yang Signed-off-by: Ping-Ke Shih Signed-off-by: Kalle Valo Link: https://lore.kernel.org/r/20220408001353.17188-2-pkshih@realtek.com --- drivers/net/wireless/realtek/rtw89/ser.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/net/wireless/realtek/rtw89/ser.c b/drivers/net/wireless/realtek/rtw89/ser.c index 25d1df10f2262..5aebd6839d299 100644 --- a/drivers/net/wireless/realtek/rtw89/ser.c +++ b/drivers/net/wireless/realtek/rtw89/ser.c @@ -394,6 +394,7 @@ static void ser_idle_st_hdl(struct rtw89_ser *ser, u8 evt) break; case SER_EV_STATE_OUT: rtw89_hci_recovery_start(rtwdev); + break; default: break; } From eeadcd2a47f855d14ba85f46a8b9206182ea110c Mon Sep 17 00:00:00 2001 From: Chia-Yuan Li Date: Fri, 8 Apr 2022 08:13:42 +0800 Subject: [PATCH 115/228] rtw89: ser: configure D-MAC interrupt mask These interrupts are used by firmware to recover hardware. Create functions to set specific D-MAC masks to replace plain register settings. Signed-off-by: Chia-Yuan Li Signed-off-by: Ping-Ke Shih Signed-off-by: Kalle Valo Link: https://lore.kernel.org/r/20220408001353.17188-3-pkshih@realtek.com --- drivers/net/wireless/realtek/rtw89/core.h | 29 + drivers/net/wireless/realtek/rtw89/mac.c | 160 +++- drivers/net/wireless/realtek/rtw89/reg.h | 863 ++++++++++++++++++ drivers/net/wireless/realtek/rtw89/rtw8852a.c | 29 + drivers/net/wireless/realtek/rtw89/rtw8852c.c | 29 + 5 files changed, 1091 insertions(+), 19 deletions(-) diff --git a/drivers/net/wireless/realtek/rtw89/core.h b/drivers/net/wireless/realtek/rtw89/core.h index fdf593e686609..63aa88b705bc2 100644 --- a/drivers/net/wireless/realtek/rtw89/core.h +++ b/drivers/net/wireless/realtek/rtw89/core.h @@ -2293,6 +2293,34 @@ struct rtw89_page_regs { u32 wp_page_info1; }; +struct rtw89_imr_info { + u32 wdrls_imr_set; + u32 wsec_imr_reg; + u32 wsec_imr_set; + u32 mpdu_tx_imr_set; + u32 mpdu_rx_imr_set; + u32 sta_sch_imr_set; + u32 txpktctl_imr_b0_reg; + u32 txpktctl_imr_b0_clr; + u32 txpktctl_imr_b0_set; + u32 txpktctl_imr_b1_reg; + u32 txpktctl_imr_b1_clr; + u32 txpktctl_imr_b1_set; + u32 wde_imr_clr; + u32 wde_imr_set; + u32 ple_imr_clr; + u32 ple_imr_set; + u32 host_disp_imr_clr; + u32 host_disp_imr_set; + u32 cpu_disp_imr_clr; + u32 cpu_disp_imr_set; + u32 other_disp_imr_clr; + u32 other_disp_imr_set; + u32 bbrpt_chinfo_err_imr_reg; + u32 bbrpt_err_imr_set; + u32 bbrpt_dfs_err_imr_reg; +}; + struct rtw89_chip_info { enum rtw89_core_chip_id chip_id; const struct rtw89_chip_ops *ops; @@ -2378,6 +2406,7 @@ struct rtw89_chip_info { const struct rtw89_page_regs *page_regs; const struct rtw89_reg_def *dcfo_comp; u8 dcfo_comp_sft; + const struct rtw89_imr_info *imr_info; }; union rtw89_bus_info { diff --git a/drivers/net/wireless/realtek/rtw89/mac.c b/drivers/net/wireless/realtek/rtw89/mac.c index c28f5a7c23b5e..77fb9b74019e4 100644 --- a/drivers/net/wireless/realtek/rtw89/mac.c +++ b/drivers/net/wireless/realtek/rtw89/mac.c @@ -2607,6 +2607,136 @@ static int band1_enable(struct rtw89_dev *rtwdev) return 0; } +static void rtw89_wdrls_imr_enable(struct rtw89_dev *rtwdev) +{ + const struct rtw89_imr_info *imr = rtwdev->chip->imr_info; + + rtw89_write32_clr(rtwdev, R_AX_WDRLS_ERR_IMR, B_AX_WDRLS_IMR_EN_CLR); + rtw89_write32_set(rtwdev, R_AX_WDRLS_ERR_IMR, imr->wdrls_imr_set); +} + +static void rtw89_wsec_imr_enable(struct rtw89_dev *rtwdev) +{ + const struct rtw89_imr_info *imr = rtwdev->chip->imr_info; + + rtw89_write32_set(rtwdev, imr->wsec_imr_reg, imr->wsec_imr_set); +} + +static void rtw89_mpdu_trx_imr_enable(struct rtw89_dev *rtwdev) +{ + enum rtw89_core_chip_id chip_id = rtwdev->chip->chip_id; + const struct rtw89_imr_info *imr = rtwdev->chip->imr_info; + + rtw89_write32_clr(rtwdev, R_AX_MPDU_TX_ERR_IMR, + B_AX_TX_GET_ERRPKTID_INT_EN | + B_AX_TX_NXT_ERRPKTID_INT_EN | + B_AX_TX_MPDU_SIZE_ZERO_INT_EN | + B_AX_TX_OFFSET_ERR_INT_EN | + B_AX_TX_HDR3_SIZE_ERR_INT_EN); + if (chip_id == RTL8852C) + rtw89_write32_clr(rtwdev, R_AX_MPDU_TX_ERR_IMR, + B_AX_TX_ETH_TYPE_ERR_EN | + B_AX_TX_LLC_PRE_ERR_EN | + B_AX_TX_NW_TYPE_ERR_EN | + B_AX_TX_KSRCH_ERR_EN); + rtw89_write32_set(rtwdev, R_AX_MPDU_TX_ERR_IMR, + imr->mpdu_tx_imr_set); + + rtw89_write32_clr(rtwdev, R_AX_MPDU_RX_ERR_IMR, + B_AX_GETPKTID_ERR_INT_EN | + B_AX_MHDRLEN_ERR_INT_EN | + B_AX_RPT_ERR_INT_EN); + rtw89_write32_set(rtwdev, R_AX_MPDU_RX_ERR_IMR, + imr->mpdu_rx_imr_set); +} + +static void rtw89_sta_sch_imr_enable(struct rtw89_dev *rtwdev) +{ + const struct rtw89_imr_info *imr = rtwdev->chip->imr_info; + + rtw89_write32_clr(rtwdev, R_AX_STA_SCHEDULER_ERR_IMR, + B_AX_SEARCH_HANG_TIMEOUT_INT_EN | + B_AX_RPT_HANG_TIMEOUT_INT_EN | + B_AX_PLE_B_PKTID_ERR_INT_EN); + rtw89_write32_set(rtwdev, R_AX_STA_SCHEDULER_ERR_IMR, + imr->sta_sch_imr_set); +} + +static void rtw89_txpktctl_imr_enable(struct rtw89_dev *rtwdev) +{ + const struct rtw89_imr_info *imr = rtwdev->chip->imr_info; + + rtw89_write32_clr(rtwdev, imr->txpktctl_imr_b0_reg, + imr->txpktctl_imr_b0_clr); + rtw89_write32_set(rtwdev, imr->txpktctl_imr_b0_reg, + imr->txpktctl_imr_b0_set); + rtw89_write32_clr(rtwdev, imr->txpktctl_imr_b1_reg, + imr->txpktctl_imr_b1_clr); + rtw89_write32_set(rtwdev, imr->txpktctl_imr_b1_reg, + imr->txpktctl_imr_b1_set); +} + +static void rtw89_wde_imr_enable(struct rtw89_dev *rtwdev) +{ + const struct rtw89_imr_info *imr = rtwdev->chip->imr_info; + + rtw89_write32_clr(rtwdev, R_AX_WDE_ERR_IMR, imr->wde_imr_clr); + rtw89_write32_set(rtwdev, R_AX_WDE_ERR_IMR, imr->wde_imr_set); +} + +static void rtw89_ple_imr_enable(struct rtw89_dev *rtwdev) +{ + const struct rtw89_imr_info *imr = rtwdev->chip->imr_info; + + rtw89_write32_clr(rtwdev, R_AX_PLE_ERR_IMR, imr->ple_imr_clr); + rtw89_write32_set(rtwdev, R_AX_PLE_ERR_IMR, imr->ple_imr_set); +} + +static void rtw89_pktin_imr_enable(struct rtw89_dev *rtwdev) +{ + rtw89_write32_set(rtwdev, R_AX_PKTIN_ERR_IMR, + B_AX_PKTIN_GETPKTID_ERR_INT_EN); +} + +static void rtw89_dispatcher_imr_enable(struct rtw89_dev *rtwdev) +{ + const struct rtw89_imr_info *imr = rtwdev->chip->imr_info; + + rtw89_write32_clr(rtwdev, R_AX_HOST_DISPATCHER_ERR_IMR, + imr->host_disp_imr_clr); + rtw89_write32_set(rtwdev, R_AX_HOST_DISPATCHER_ERR_IMR, + imr->host_disp_imr_set); + rtw89_write32_clr(rtwdev, R_AX_CPU_DISPATCHER_ERR_IMR, + imr->cpu_disp_imr_clr); + rtw89_write32_set(rtwdev, R_AX_CPU_DISPATCHER_ERR_IMR, + imr->cpu_disp_imr_set); + rtw89_write32_clr(rtwdev, R_AX_OTHER_DISPATCHER_ERR_IMR, + imr->other_disp_imr_clr); + rtw89_write32_set(rtwdev, R_AX_OTHER_DISPATCHER_ERR_IMR, + imr->other_disp_imr_set); +} + +static void rtw89_cpuio_imr_enable(struct rtw89_dev *rtwdev) +{ + rtw89_write32_clr(rtwdev, R_AX_CPUIO_ERR_IMR, B_AX_CPUIO_IMR_CLR); + rtw89_write32_set(rtwdev, R_AX_CPUIO_ERR_IMR, B_AX_CPUIO_IMR_SET); +} + +static void rtw89_bbrpt_imr_enable(struct rtw89_dev *rtwdev) +{ + const struct rtw89_imr_info *imr = rtwdev->chip->imr_info; + + rtw89_write32_set(rtwdev, R_AX_BBRPT_COM_ERR_IMR, + B_AX_BBRPT_COM_NULL_PLPKTID_ERR_INT_EN); + rtw89_write32_clr(rtwdev, imr->bbrpt_chinfo_err_imr_reg, + B_AX_BBRPT_CHINFO_IMR_CLR); + rtw89_write32_set(rtwdev, imr->bbrpt_chinfo_err_imr_reg, + imr->bbrpt_err_imr_set); + rtw89_write32_set(rtwdev, imr->bbrpt_dfs_err_imr_reg, + B_AX_BBRPT_DFS_TO_ERR_INT_EN); + rtw89_write32_set(rtwdev, R_AX_LA_ERRFLAG, B_AX_LA_IMR_DATA_LOSS_ERR); +} + static int rtw89_mac_enable_imr(struct rtw89_dev *rtwdev, u8 mac_idx, enum rtw89_mac_hwmod_sel sel) { @@ -2621,25 +2751,17 @@ static int rtw89_mac_enable_imr(struct rtw89_dev *rtwdev, u8 mac_idx, } if (sel == RTW89_DMAC_SEL) { - rtw89_write32_clr(rtwdev, R_AX_TXPKTCTL_ERR_IMR_ISR, - B_AX_TXPKTCTL_USRCTL_RLSBMPLEN_ERR_INT_EN | - B_AX_TXPKTCTL_USRCTL_RDNRLSCMD_ERR_INT_EN | - B_AX_TXPKTCTL_CMDPSR_FRZTO_ERR_INT_EN); - rtw89_write32_clr(rtwdev, R_AX_TXPKTCTL_ERR_IMR_ISR_B1, - B_AX_TXPKTCTL_USRCTL_RLSBMPLEN_ERR_INT_EN | - B_AX_TXPKTCTL_USRCTL_RDNRLSCMD_ERR_INT_EN); - rtw89_write32_clr(rtwdev, R_AX_HOST_DISPATCHER_ERR_IMR, - B_AX_HDT_PKT_FAIL_DBG_INT_EN | - B_AX_HDT_OFFSET_UNMATCH_INT_EN); - rtw89_write32_clr(rtwdev, R_AX_CPU_DISPATCHER_ERR_IMR, - B_AX_CPU_SHIFT_EN_ERR_INT_EN); - rtw89_write32_clr(rtwdev, R_AX_PLE_ERR_IMR, - B_AX_PLE_GETNPG_STRPG_ERR_INT_EN); - rtw89_write32_clr(rtwdev, R_AX_WDRLS_ERR_IMR, - B_AX_WDRLS_PLEBREQ_TO_ERR_INT_EN); - rtw89_write32_set(rtwdev, R_AX_HD0IMR, B_AX_WDT_PTFM_INT_EN); - rtw89_write32_clr(rtwdev, R_AX_TXPKTCTL_ERR_IMR_ISR, - B_AX_TXPKTCTL_USRCTL_NOINIT_ERR_INT_EN); + rtw89_wdrls_imr_enable(rtwdev); + rtw89_wsec_imr_enable(rtwdev); + rtw89_mpdu_trx_imr_enable(rtwdev); + rtw89_sta_sch_imr_enable(rtwdev); + rtw89_txpktctl_imr_enable(rtwdev); + rtw89_wde_imr_enable(rtwdev); + rtw89_ple_imr_enable(rtwdev); + rtw89_pktin_imr_enable(rtwdev); + rtw89_dispatcher_imr_enable(rtwdev); + rtw89_cpuio_imr_enable(rtwdev); + rtw89_bbrpt_imr_enable(rtwdev); } else if (sel == RTW89_CMAC_SEL) { reg = rtw89_mac_reg_by_idx(R_AX_SCHEDULE_ERR_IMR, mac_idx); rtw89_write32_clr(rtwdev, reg, diff --git a/drivers/net/wireless/realtek/rtw89/reg.h b/drivers/net/wireless/realtek/rtw89/reg.h index a0c60528b5780..9e445bf9b9d49 100644 --- a/drivers/net/wireless/realtek/rtw89/reg.h +++ b/drivers/net/wireless/realtek/rtw89/reg.h @@ -527,13 +527,361 @@ #define B_AX_HOST_ADDR_INFO_8B_SEL BIT(0) #define R_AX_HOST_DISPATCHER_ERR_IMR 0x8850 +#define B_AX_HDT_RX_WRITE_UNDERFLOW_INT_EN BIT(31) +#define B_AX_HDT_RX_WRITE_OVERFLOW_INT_EN BIT(30) +#define B_AX_HDT_CHKSUM_FSM_ERR_INT_EN BIT(29) +#define B_AX_HDT_SHIFT_DMA_CFG_ERR_INT_EN BIT(28) +#define B_AX_HDT_DMA_PROCESS_ERR_INT_EN BIT(27) +#define B_AX_HDT_TOTAL_LEN_ERR_INT_EN BIT(26) +#define B_AX_HDT_SHIFT_EN_ERR_INT_EN BIT(25) +#define B_AX_HDT_RXAGG_CFG_ERR_INT_EN BIT(24) +#define B_AX_HDT_OUTPUT_ERR_INT_EN BIT(21) +#define B_AX_HDT_RES_ERR_INT_EN BIT(20) +#define B_AX_HDT_BURST_NUM_ERR_INT_EN BIT(19) +#define B_AX_HDT_NULLPKT_ERR_INT_EN BIT(18) +#define B_AX_HDT_FLOW_CTRL_ERR_INT_EN BIT(17) +#define B_AX_HDT_PLD_CMD_UNDERFLOW_INT_EN BIT(16) +#define B_AX_HDT_PLD_CMD_OVERLOW_INT_EN BIT(15) +#define B_AX_HDT_TX_WRITE_UNDERFLOW_INT_EN BIT(14) +#define B_AX_HDT_TX_WRITE_OVERFLOW_INT_EN BIT(13) +#define B_AX_HDT_TCP_CHK_ERR_INT_EN BIT(12) +#define B_AX_HDT_TXPKTSIZE_ERR_INT_EN BIT(11) +#define B_AX_HDT_PRE_COST_ERR_INT_EN BIT(10) +#define B_AX_HDT_WD_CHK_ERR_INT_EN BIT(9) +#define B_AX_HDT_CHANNEL_DMA_ERR_INT_EN BIT(8) #define B_AX_HDT_OFFSET_UNMATCH_INT_EN BIT(7) +#define B_AX_HDT_PAYLOAD_UNDERFLOW_INT_EN BIT(6) +#define B_AX_HDT_PAYLOAD_OVERFLOW_INT_EN BIT(5) +#define B_AX_HDT_PERMU_UNDERFLOW_INT_EN BIT(4) +#define B_AX_HDT_PERMU_OVERFLOW_INT_EN BIT(3) #define B_AX_HDT_PKT_FAIL_DBG_INT_EN BIT(2) +#define B_AX_HDT_CHANNEL_ID_ERR_INT_EN BIT(1) +#define B_AX_HDT_CHANNEL_DIFF_ERR_INT_EN BIT(0) +#define B_AX_HOST_DISP_IMR_CLR (B_AX_HDT_CHANNEL_DIFF_ERR_INT_EN | \ + B_AX_HDT_CHANNEL_ID_ERR_INT_EN | \ + B_AX_HDT_PKT_FAIL_DBG_INT_EN | \ + B_AX_HDT_PERMU_OVERFLOW_INT_EN | \ + B_AX_HDT_PERMU_UNDERFLOW_INT_EN | \ + B_AX_HDT_PAYLOAD_OVERFLOW_INT_EN | \ + B_AX_HDT_PAYLOAD_UNDERFLOW_INT_EN | \ + B_AX_HDT_OFFSET_UNMATCH_INT_EN | \ + B_AX_HDT_CHANNEL_DMA_ERR_INT_EN | \ + B_AX_HDT_WD_CHK_ERR_INT_EN | \ + B_AX_HDT_PRE_COST_ERR_INT_EN | \ + B_AX_HDT_TXPKTSIZE_ERR_INT_EN | \ + B_AX_HDT_TCP_CHK_ERR_INT_EN | \ + B_AX_HDT_TX_WRITE_OVERFLOW_INT_EN | \ + B_AX_HDT_TX_WRITE_UNDERFLOW_INT_EN | \ + B_AX_HDT_PLD_CMD_OVERLOW_INT_EN | \ + B_AX_HDT_PLD_CMD_UNDERFLOW_INT_EN | \ + B_AX_HDT_FLOW_CTRL_ERR_INT_EN | \ + B_AX_HDT_NULLPKT_ERR_INT_EN | \ + B_AX_HDT_BURST_NUM_ERR_INT_EN | \ + B_AX_HDT_RXAGG_CFG_ERR_INT_EN | \ + B_AX_HDT_SHIFT_EN_ERR_INT_EN | \ + B_AX_HDT_TOTAL_LEN_ERR_INT_EN | \ + B_AX_HDT_DMA_PROCESS_ERR_INT_EN | \ + B_AX_HDT_SHIFT_DMA_CFG_ERR_INT_EN | \ + B_AX_HDT_CHKSUM_FSM_ERR_INT_EN | \ + B_AX_HDT_RX_WRITE_OVERFLOW_INT_EN | \ + B_AX_HDT_RX_WRITE_UNDERFLOW_INT_EN) +#define B_AX_HOST_DISP_IMR_SET (B_AX_HDT_CHANNEL_DIFF_ERR_INT_EN | \ + B_AX_HDT_PAYLOAD_OVERFLOW_INT_EN | \ + B_AX_HDT_PAYLOAD_UNDERFLOW_INT_EN | \ + B_AX_HDT_CHANNEL_DMA_ERR_INT_EN | \ + B_AX_HDT_TOTAL_LEN_ERR_INT_EN | \ + B_AX_HDT_DMA_PROCESS_ERR_INT_EN) + +#define B_AX_HR_WRFF_UNDERFLOW_ERR_INT_EN BIT(31) +#define B_AX_HR_WRFF_OVERFLOW_ERR_INT_EN BIT(30) +#define B_AX_HR_CHKSUM_FSM_ERR_INT_EN BIT(29) +#define B_AX_HR_SHIFT_DMA_CFG_ERR_INT_EN BIT(28) +#define B_AX_HR_DMA_PROCESS_ERR_INT_EN BIT(27) +#define B_AX_HR_TOTAL_LEN_UNDER_ERR_INT_EN BIT(26) +#define B_AX_HR_SHIFT_EN_ERR_INT_EN BIT(25) +#define B_AX_HR_AGG_CFG_ERR_INT_EN BIT(24) +#define B_AX_HR_DMA_RD_CNT_DEQ_ERR_INT_EN BIT(23) +#define B_AX_HR_PLD_LEN_ZERO_ERR_INT_EN BIT(22) +#define B_AX_HT_ILL_CH_ERR_INT_EN BIT(20) +#define B_AX_HT_ADDR_INFO_LEN_ERR_INT_EN BIT(18) +#define B_AX_HT_WD_LEN_OVER_ERR_INT_EN BIT(17) +#define B_AX_HT_PLD_CMD_UNDERFLOW_ERR_INT_EN BIT(16) +#define B_AX_HT_PLD_CMD_OVERFLOW_ERR_INT_EN BIT(15) +#define B_AX_HT_WRFF_UNDERFLOW_ERR_INT_EN BIT(14) +#define B_AX_HT_WRFF_OVERFLOW_ERR_INT_EN BIT(13) +#define B_AX_HT_CHKSUM_FSM_ERR_INT_EN BIT(12) +#define B_AX_HT_TXPKTSIZE_ERR_INT_EN BIT(11) +#define B_AX_HT_PRE_SUB_ERR_INT_EN BIT(10) +#define B_AX_HT_WD_CHKSUM_ERR_INT_EN BIT(9) +#define B_AX_HT_CHANNEL_DMA_ERR_INT_EN BIT(8) +#define B_AX_HT_OFFSET_UNMATCH_ERR_INT_EN BIT(7) +#define B_AX_HT_PAYLOAD_UNDER_ERR_INT_EN BIT(6) +#define B_AX_HT_PAYLOAD_OVER_ERR_INT_EN BIT(5) +#define B_AX_HT_PERMU_FF_UNDERFLOW_ERR_INT_EN BIT(4) +#define B_AX_HT_PERMU_FF_OVERFLOW_ERR_INT_EN BIT(3) +#define B_AX_HT_PKT_FAIL_ERR_INT_EN BIT(2) +#define B_AX_HT_CH_ID_ERR_INT_EN BIT(1) +#define B_AX_HT_EP_CH_DIFF_ERR_INT_EN BIT(0) +#define B_AX_HOST_DISP_IMR_CLR_V1 (B_AX_HT_EP_CH_DIFF_ERR_INT_EN | \ + B_AX_HT_CH_ID_ERR_INT_EN | \ + B_AX_HT_PKT_FAIL_ERR_INT_EN | \ + B_AX_HT_PERMU_FF_OVERFLOW_ERR_INT_EN | \ + B_AX_HT_PERMU_FF_UNDERFLOW_ERR_INT_EN | \ + B_AX_HT_PAYLOAD_OVER_ERR_INT_EN | \ + B_AX_HT_PAYLOAD_UNDER_ERR_INT_EN | \ + B_AX_HT_OFFSET_UNMATCH_ERR_INT_EN | \ + B_AX_HT_CHANNEL_DMA_ERR_INT_EN | \ + B_AX_HT_WD_CHKSUM_ERR_INT_EN | \ + B_AX_HT_PRE_SUB_ERR_INT_EN | \ + B_AX_HT_TXPKTSIZE_ERR_INT_EN | \ + B_AX_HT_CHKSUM_FSM_ERR_INT_EN | \ + B_AX_HT_WRFF_OVERFLOW_ERR_INT_EN | \ + B_AX_HT_WRFF_UNDERFLOW_ERR_INT_EN | \ + B_AX_HT_PLD_CMD_OVERFLOW_ERR_INT_EN | \ + B_AX_HT_PLD_CMD_UNDERFLOW_ERR_INT_EN | \ + B_AX_HT_WD_LEN_OVER_ERR_INT_EN | \ + B_AX_HT_ADDR_INFO_LEN_ERR_INT_EN | \ + B_AX_HT_ILL_CH_ERR_INT_EN | \ + B_AX_HR_PLD_LEN_ZERO_ERR_INT_EN | \ + B_AX_HR_DMA_RD_CNT_DEQ_ERR_INT_EN | \ + B_AX_HR_AGG_CFG_ERR_INT_EN | \ + B_AX_HR_SHIFT_EN_ERR_INT_EN | \ + B_AX_HR_TOTAL_LEN_UNDER_ERR_INT_EN | \ + B_AX_HR_DMA_PROCESS_ERR_INT_EN | \ + B_AX_HR_SHIFT_DMA_CFG_ERR_INT_EN | \ + B_AX_HR_CHKSUM_FSM_ERR_INT_EN | \ + B_AX_HR_WRFF_OVERFLOW_ERR_INT_EN | \ + B_AX_HR_WRFF_UNDERFLOW_ERR_INT_EN) +#define B_AX_HOST_DISP_IMR_SET_V1 (B_AX_HT_PAYLOAD_OVER_ERR_INT_EN | \ + B_AX_HT_PAYLOAD_UNDER_ERR_INT_EN | \ + B_AX_HT_ILL_CH_ERR_INT_EN | \ + B_AX_HR_TOTAL_LEN_UNDER_ERR_INT_EN | \ + B_AX_HR_DMA_PROCESS_ERR_INT_EN) #define R_AX_CPU_DISPATCHER_ERR_IMR 0x8854 +#define B_AX_CPU_RX_WRITE_UNDERFLOW_INT_EN BIT(31) +#define B_AX_CPU_RX_WRITE_OVERFLOW_INT_EN BIT(30) +#define B_AX_CPU_CHKSUM_FSM_ERR_INT_EN BIT(29) +#define B_AX_CPU_SHIFT_DMA_CFG_ERR_INT_EN BIT(28) +#define B_AX_CPU_DMA_PROCESS_ERR_INT_EN BIT(27) +#define B_AX_CPU_TOTAL_LEN_ERR_INT_EN BIT(26) #define B_AX_CPU_SHIFT_EN_ERR_INT_EN BIT(25) +#define B_AX_CPU_RXAGG_CFG_ERR_INT_EN BIT(24) +#define B_AX_CPU_OUTPUT_ERR_INT_EN BIT(20) +#define B_AX_CPU_RESP_ERR_INT_EN BIT(19) +#define B_AX_CPU_BURST_NUM_ERR_INT_EN BIT(18) +#define B_AX_CPU_NULLPKT_ERR_INT_EN BIT(17) +#define B_AX_CPU_FLOW_CTRL_ERR_INT_EN BIT(16) +#define B_AX_CPU_F2P_SEQ_ERR_INT_EN BIT(15) +#define B_AX_CPU_F2P_QSEL_ERR_INT_EN BIT(14) +#define B_AX_CPU_PLD_CMD_UNDERFLOW_INT_EN BIT(13) +#define B_AX_CPU_PLD_CMD_OVERLOW_INT_EN BIT(12) +#define B_AX_CPU_PRE_COST_ERR_INT_EN BIT(11) +#define B_AX_CPU_WD_CHK_ERR_INT_EN BIT(10) +#define B_AX_CPU_CHANNEL_DMA_ERR_INT_EN BIT(9) +#define B_AX_CPU_OFFSET_UNMATCH_INT_EN BIT(8) +#define B_AX_CPU_PAYLOAD_CHKSUM_ERR_INT_EN BIT(7) +#define B_AX_CPU_PAYLOAD_UNDERFLOW_INT_EN BIT(6) +#define B_AX_CPU_PAYLOAD_OVERFLOW_INT_EN BIT(5) +#define B_AX_CPU_PERMU_UNDERFLOW_INT_EN BIT(4) +#define B_AX_CPU_PERMU_OVERFLOW_INT_EN BIT(3) +#define B_AX_CPU_CHANNEL_ID_ERR_INT_EN BIT(2) +#define B_AX_CPU_PKT_FAIL_DBG_INT_EN BIT(1) +#define B_AX_CPU_CHANNEL_DIFF_ERR_INT_EN BIT(0) +#define B_AX_CPU_DISP_IMR_CLR (B_AX_CPU_CHANNEL_DIFF_ERR_INT_EN | \ + B_AX_CPU_PKT_FAIL_DBG_INT_EN | \ + B_AX_CPU_CHANNEL_ID_ERR_INT_EN | \ + B_AX_CPU_PERMU_OVERFLOW_INT_EN | \ + B_AX_CPU_PERMU_UNDERFLOW_INT_EN | \ + B_AX_CPU_PAYLOAD_OVERFLOW_INT_EN | \ + B_AX_CPU_PAYLOAD_UNDERFLOW_INT_EN | \ + B_AX_CPU_PAYLOAD_CHKSUM_ERR_INT_EN | \ + B_AX_CPU_OFFSET_UNMATCH_INT_EN | \ + B_AX_CPU_CHANNEL_DMA_ERR_INT_EN | \ + B_AX_CPU_WD_CHK_ERR_INT_EN | \ + B_AX_CPU_PRE_COST_ERR_INT_EN | \ + B_AX_CPU_PLD_CMD_OVERLOW_INT_EN | \ + B_AX_CPU_PLD_CMD_UNDERFLOW_INT_EN | \ + B_AX_CPU_F2P_QSEL_ERR_INT_EN | \ + B_AX_CPU_F2P_SEQ_ERR_INT_EN | \ + B_AX_CPU_FLOW_CTRL_ERR_INT_EN | \ + B_AX_CPU_NULLPKT_ERR_INT_EN | \ + B_AX_CPU_BURST_NUM_ERR_INT_EN | \ + B_AX_CPU_RXAGG_CFG_ERR_INT_EN | \ + B_AX_CPU_SHIFT_EN_ERR_INT_EN | \ + B_AX_CPU_TOTAL_LEN_ERR_INT_EN | \ + B_AX_CPU_DMA_PROCESS_ERR_INT_EN | \ + B_AX_CPU_SHIFT_DMA_CFG_ERR_INT_EN | \ + B_AX_CPU_CHKSUM_FSM_ERR_INT_EN | \ + B_AX_CPU_RX_WRITE_OVERFLOW_INT_EN | \ + B_AX_CPU_RX_WRITE_UNDERFLOW_INT_EN) +#define B_AX_CPU_DISP_IMR_SET (B_AX_CPU_PKT_FAIL_DBG_INT_EN | \ + B_AX_CPU_PAYLOAD_OVERFLOW_INT_EN | \ + B_AX_CPU_PAYLOAD_UNDERFLOW_INT_EN | \ + B_AX_CPU_TOTAL_LEN_ERR_INT_EN) + +#define B_AX_CR_PLD_LEN_ERR_INT_EN BIT(30) +#define B_AX_CR_WRFF_UNDERFLOW_ERR_INT_EN BIT(29) +#define B_AX_CR_WRFF_OVERFLOW_ERR_INT_EN BIT(28) +#define B_AX_CR_SHIFT_DMA_CFG_ERR_INT_EN BIT(27) +#define B_AX_CR_DMA_PROCESS_ERR_INT_EN BIT(26) +#define B_AX_CR_TOTAL_LEN_UNDER_ERR_INT_EN BIT(25) +#define B_AX_CR_SHIFT_EN_ERR_INT_EN BIT(24) +#define B_AX_REUSE_FIFO_B_UNDER_ERR_INT_EN BIT(22) +#define B_AX_REUSE_FIFO_B_OVER_ERR_INT_EN BIT(21) +#define B_AX_REUSE_FIFO_A_UNDER_ERR_INT_EN BIT(20) +#define B_AX_REUSE_FIFO_A_OVER_ERR_INT_EN BIT(19) +#define B_AX_CT_ADDR_INFO_LEN_MISS_ERR_INT_EN BIT(17) +#define B_AX_CT_WD_LEN_OVER_ERR_INT_EN BIT(16) +#define B_AX_CT_F2P_SEQ_ERR_INT_EN BIT(15) +#define B_AX_CT_F2P_QSEL_ERR_INT_EN BIT(14) +#define B_AX_CT_PLD_CMD_UNDERFLOW_ERR_INT_EN BIT(13) +#define B_AX_CT_PLD_CMD_OVERFLOW_ERR_INT_EN BIT(12) +#define B_AX_CT_PRE_SUB_ERR_INT_EN BIT(11) +#define B_AX_CT_WD_CHKSUM_ERR_INT_EN BIT(10) +#define B_AX_CT_CHANNEL_DMA_ERR_INT_EN BIT(9) +#define B_AX_CT_OFFSET_UNMATCH_ERR_INT_EN BIT(8) +#define B_AX_CT_PAYLOAD_CHKSUM_ERR_INT_EN BIT(7) +#define B_AX_CT_PAYLOAD_UNDER_ERR_INT_EN BIT(6) +#define B_AX_CT_PAYLOAD_OVER_ERR_INT_EN BIT(5) +#define B_AX_CT_PERMU_FF_UNDERFLOW_ERR_INT_EN BIT(4) +#define B_AX_CT_PERMU_FF_OVERFLOW_ERR_INT_EN BIT(3) +#define B_AX_CT_CH_ID_ERR_INT_EN BIT(2) +#define B_AX_CT_EP_CH_DIFF_ERR_INT_EN BIT(0) +#define B_AX_CPU_DISP_IMR_CLR_V1 (B_AX_CT_EP_CH_DIFF_ERR_INT_EN | \ + B_AX_CT_CH_ID_ERR_INT_EN | \ + B_AX_CT_PERMU_FF_OVERFLOW_ERR_INT_EN | \ + B_AX_CT_PERMU_FF_UNDERFLOW_ERR_INT_EN | \ + B_AX_CT_PAYLOAD_OVER_ERR_INT_EN | \ + B_AX_CT_PAYLOAD_UNDER_ERR_INT_EN | \ + B_AX_CT_PAYLOAD_CHKSUM_ERR_INT_EN | \ + B_AX_CT_OFFSET_UNMATCH_ERR_INT_EN | \ + B_AX_CT_CHANNEL_DMA_ERR_INT_EN | \ + B_AX_CT_WD_CHKSUM_ERR_INT_EN | \ + B_AX_CT_PRE_SUB_ERR_INT_EN | \ + B_AX_CT_PLD_CMD_OVERFLOW_ERR_INT_EN | \ + B_AX_CT_PLD_CMD_UNDERFLOW_ERR_INT_EN | \ + B_AX_CT_F2P_QSEL_ERR_INT_EN | \ + B_AX_CT_F2P_SEQ_ERR_INT_EN | \ + B_AX_CT_WD_LEN_OVER_ERR_INT_EN | \ + B_AX_CT_ADDR_INFO_LEN_MISS_ERR_INT_EN | \ + B_AX_REUSE_FIFO_A_OVER_ERR_INT_EN | \ + B_AX_REUSE_FIFO_A_UNDER_ERR_INT_EN | \ + B_AX_REUSE_FIFO_B_OVER_ERR_INT_EN | \ + B_AX_REUSE_FIFO_B_UNDER_ERR_INT_EN | \ + B_AX_CR_SHIFT_EN_ERR_INT_EN | \ + B_AX_CR_TOTAL_LEN_UNDER_ERR_INT_EN | \ + B_AX_CR_DMA_PROCESS_ERR_INT_EN | \ + B_AX_CR_SHIFT_DMA_CFG_ERR_INT_EN | \ + B_AX_CR_WRFF_OVERFLOW_ERR_INT_EN | \ + B_AX_CR_WRFF_UNDERFLOW_ERR_INT_EN | \ + B_AX_CR_PLD_LEN_ERR_INT_EN) +#define B_AX_CPU_DISP_IMR_SET_V1 (B_AX_CT_PAYLOAD_OVER_ERR_INT_EN | \ + B_AX_CT_PAYLOAD_UNDER_ERR_INT_EN | \ + B_AX_CR_TOTAL_LEN_UNDER_ERR_INT_EN | \ + B_AX_CR_DMA_PROCESS_ERR_INT_EN | \ + B_AX_CR_WRFF_OVERFLOW_ERR_INT_EN | \ + B_AX_CR_WRFF_UNDERFLOW_ERR_INT_EN) #define R_AX_OTHER_DISPATCHER_ERR_IMR 0x8858 +#define B_AX_OTHER_STF_WROQT_UNDERFLOW_INT_EN BIT(29) +#define B_AX_OTHER_STF_WROQT_OVERFLOW_INT_EN BIT(28) +#define B_AX_OTHER_STF_WRFF_UNDERFLOW_INT_EN BIT(27) +#define B_AX_OTHER_STF_WRFF_OVERFLOW_INT_EN BIT(26) +#define B_AX_OTHER_STF_CMD_UNDERFLOW_INT_EN BIT(25) +#define B_AX_OTHER_STF_CMD_OVERFLOW_INT_EN BIT(24) +#define B_AX_HOST_ADDR_INFO_LEN_ZERO_ERR_INT_EN BIT(17) +#define B_AX_CPU_ADDR_INFO_LEN_ZERO_ERR_INT_EN BIT(16) +#define B_AX_PLE_OUTPUT_ERR_INT_EN BIT(12) +#define B_AX_PLE_RESP_ERR_INT_EN BIT(11) +#define B_AX_PLE_BURST_NUM_ERR_INT_EN BIT(10) +#define B_AX_PLE_NULL_PKT_ERR_INT_EN BIT(9) +#define B_AX_PLE_FLOW_CTRL_ERR_INT_EN BIT(8) +#define B_AX_WDE_OUTPUT_ERR_INT_EN BIT(4) +#define B_AX_WDE_RESP_ERR_INT_EN BIT(3) +#define B_AX_WDE_BURST_NUM_ERR_INT_EN BIT(2) +#define B_AX_WDE_NULL_PKT_ERR_INT_EN BIT(1) +#define B_AX_WDE_FLOW_CTRL_ERR_INT_EN BIT(0) +#define B_AX_OTHER_DISP_IMR_CLR (B_AX_OTHER_STF_WROQT_UNDERFLOW_INT_EN | \ + B_AX_OTHER_STF_WROQT_OVERFLOW_INT_EN | \ + B_AX_OTHER_STF_WRFF_UNDERFLOW_INT_EN | \ + B_AX_OTHER_STF_WRFF_OVERFLOW_INT_EN | \ + B_AX_OTHER_STF_CMD_UNDERFLOW_INT_EN | \ + B_AX_OTHER_STF_CMD_OVERFLOW_INT_EN | \ + B_AX_HOST_ADDR_INFO_LEN_ZERO_ERR_INT_EN | \ + B_AX_CPU_ADDR_INFO_LEN_ZERO_ERR_INT_EN | \ + B_AX_PLE_OUTPUT_ERR_INT_EN | \ + B_AX_PLE_RESP_ERR_INT_EN | \ + B_AX_PLE_BURST_NUM_ERR_INT_EN | \ + B_AX_PLE_NULL_PKT_ERR_INT_EN | \ + B_AX_PLE_FLOW_CTRL_ERR_INT_EN | \ + B_AX_WDE_OUTPUT_ERR_INT_EN | \ + B_AX_WDE_RESP_ERR_INT_EN | \ + B_AX_WDE_BURST_NUM_ERR_INT_EN | \ + B_AX_WDE_NULL_PKT_ERR_INT_EN | \ + B_AX_WDE_FLOW_CTRL_ERR_INT_EN) + +#define B_AX_REUSE_SIZE_ERR_INT_EN BIT(31) +#define B_AX_REUSE_EN_ERR_INT_EN BIT(30) +#define B_AX_STF_OQT_UNDERFLOW_ERR_INT_EN BIT(29) +#define B_AX_STF_OQT_OVERFLOW_ERR_INT_EN BIT(28) +#define B_AX_STF_WRFF_UNDERFLOW_ERR_INT_EN BIT(27) +#define B_AX_STF_WRFF_OVERFLOW_ERR_INT_EN BIT(26) +#define B_AX_STF_CMD_UNDERFLOW_ERR_INT_EN BIT(25) +#define B_AX_STF_CMD_OVERFLOW_ERR_INT_EN BIT(24) +#define B_AX_REUSE_SIZE_ZERO_ERR_INT_EN BIT(23) +#define B_AX_REUSE_PKT_CNT_ERR_INT_EN BIT(22) +#define B_AX_CDT_PTR_TIMEOUT_ERR_INT_EN BIT(21) +#define B_AX_CDT_HCI_TIMEOUT_ERR_INT_EN BIT(20) +#define B_AX_HDT_PTR_TIMEOUT_ERR_INT_EN BIT(19) +#define B_AX_HDT_HCI_TIMEOUT_ERR_INT_EN BIT(18) +#define B_AX_CDT_ADDR_INFO_LEN_ERR_INT_EN BIT(17) +#define B_AX_HDT_ADDR_INFO_LEN_ERR_INT_EN BIT(16) +#define B_AX_CDR_DMA_TIMEOUT_ERR_INT_EN BIT(15) +#define B_AX_CDR_RX_TIMEOUT_ERR_INT_EN BIT(14) +#define B_AX_PLE_RESPOSE_ERR_INT_EN BIT(11) +#define B_AX_HDR_DMA_TIMEOUT_ERR_INT_EN BIT(7) +#define B_AX_HDR_RX_TIMEOUT_ERR_INT_EN BIT(6) +#define B_AX_WDE_RESPONSE_ERR_INT_EN BIT(3) +#define B_AX_OTHER_DISP_IMR_CLR_V1 (B_AX_CT_EP_CH_DIFF_ERR_INT_EN | \ + B_AX_WDE_FLOW_CTRL_ERR_INT_EN | \ + B_AX_WDE_NULL_PKT_ERR_INT_EN | \ + B_AX_WDE_BURST_NUM_ERR_INT_EN | \ + B_AX_WDE_RESPONSE_ERR_INT_EN | \ + B_AX_WDE_OUTPUT_ERR_INT_EN | \ + B_AX_HDR_RX_TIMEOUT_ERR_INT_EN | \ + B_AX_HDR_DMA_TIMEOUT_ERR_INT_EN | \ + B_AX_PLE_FLOW_CTRL_ERR_INT_EN | \ + B_AX_PLE_NULL_PKT_ERR_INT_EN | \ + B_AX_PLE_BURST_NUM_ERR_INT_EN | \ + B_AX_PLE_RESPOSE_ERR_INT_EN | \ + B_AX_PLE_OUTPUT_ERR_INT_EN | \ + B_AX_CDR_RX_TIMEOUT_ERR_INT_EN | \ + B_AX_CDR_DMA_TIMEOUT_ERR_INT_EN | \ + B_AX_HDT_ADDR_INFO_LEN_ERR_INT_EN | \ + B_AX_CDT_ADDR_INFO_LEN_ERR_INT_EN | \ + B_AX_HDT_HCI_TIMEOUT_ERR_INT_EN | \ + B_AX_HDT_PTR_TIMEOUT_ERR_INT_EN | \ + B_AX_CDT_HCI_TIMEOUT_ERR_INT_EN | \ + B_AX_CDT_PTR_TIMEOUT_ERR_INT_EN | \ + B_AX_REUSE_PKT_CNT_ERR_INT_EN | \ + B_AX_REUSE_SIZE_ZERO_ERR_INT_EN | \ + B_AX_STF_CMD_OVERFLOW_ERR_INT_EN | \ + B_AX_STF_CMD_UNDERFLOW_ERR_INT_EN | \ + B_AX_STF_WRFF_OVERFLOW_ERR_INT_EN | \ + B_AX_STF_WRFF_UNDERFLOW_ERR_INT_EN | \ + B_AX_STF_OQT_OVERFLOW_ERR_INT_EN | \ + B_AX_STF_OQT_UNDERFLOW_ERR_INT_EN | \ + B_AX_REUSE_EN_ERR_INT_EN | \ + B_AX_REUSE_SIZE_ERR_INT_EN) +#define B_AX_OTHER_DISP_IMR_SET_V1 (B_AX_CDR_RX_TIMEOUT_ERR_INT_EN | \ + B_AX_CDR_DMA_TIMEOUT_ERR_INT_EN | \ + B_AX_HDT_HCI_TIMEOUT_ERR_INT_EN | \ + B_AX_HDT_PTR_TIMEOUT_ERR_INT_EN | \ + B_AX_CDT_HCI_TIMEOUT_ERR_INT_EN | \ + B_AX_CDT_PTR_TIMEOUT_ERR_INT_EN | \ + B_AX_STF_OQT_OVERFLOW_ERR_INT_EN | \ + B_AX_STF_OQT_UNDERFLOW_ERR_INT_EN) #define R_AX_HCI_FC_CTRL 0x8A00 #define B_AX_HCI_FC_CH12_FULL_COND_MASK GENMASK(11, 10) @@ -612,9 +960,168 @@ #define B_AX_WDE_START_BOUND_MASK GENMASK(13, 8) #define B_AX_WDE_PAGE_SEL_MASK GENMASK(1, 0) #define B_AX_WDE_FREE_PAGE_NUM_MASK GENMASK(28, 16) + +#define R_AX_WDE_ERRFLAG_MSG 0x8C30 +#define B_AX_WDE_ERR_FLAG_MSG_MASK GENMASK(31, 0) + #define R_AX_WDE_ERR_FLAG_CFG 0x8C34 + #define R_AX_WDE_ERR_IMR 0x8C38 +#define B_AX_WDE_DATCHN_RRDY_ERR_INT_EN BIT(27) +#define B_AX_WDE_DATCHN_FRZTO_ERR_INT_EN BIT(26) +#define B_AX_WDE_DATCHN_NULLPG_ERR_INT_EN BIT(25) +#define B_AX_WDE_DATCHN_ARBT_ERR_INT_EN BIT(24) +#define B_AX_WDE_QUEMGN_FRZTO_ERR_INT_EN BIT(19) +#define B_AX_WDE_NXTPKTLL_AD_ERR_INT_EN BIT(18) +#define B_AX_WDE_PREPKTLLT_AD_ERR_INT_EN BIT(17) +#define B_AX_WDE_ENQ_PKTCNT_NVAL_ERR_INT_EN BIT(16) +#define B_AX_WDE_ENQ_PKTCNT_OVRF_ERR_INT_EN BIT(15) +#define B_AX_WDE_QUE_SRCQUEID_ERR_INT_EN BIT(14) +#define B_AX_WDE_QUE_DSTQUEID_ERR_INT_EN BIT(13) +#define B_AX_WDE_QUE_CMDTYPE_ERR_INT_EN BIT(12) +#define B_AX_WDE_BUFMGN_FRZTO_ERR_INT_EN BIT(7) +#define B_AX_WDE_GETNPG_PGOFST_ERR_INT_EN BIT(6) +#define B_AX_WDE_GETNPG_STRPG_ERR_INT_EN BIT(5) +#define B_AX_WDE_BUFREQ_SRCHTAILPG_ERR_INT_EN BIT(4) +#define B_AX_WDE_BUFRTN_SIZE_ERR_INT_EN BIT(3) +#define B_AX_WDE_BUFRTN_INVLD_PKTID_ERR_INT_EN BIT(2) +#define B_AX_WDE_BUFREQ_UNAVAL_ERR_INT_EN BIT(1) +#define B_AX_WDE_BUFREQ_QTAID_ERR_INT_EN BIT(0) +#define B_AX_WDE_IMR_CLR (B_AX_WDE_BUFREQ_QTAID_ERR_INT_EN | \ + B_AX_WDE_BUFREQ_UNAVAL_ERR_INT_EN | \ + B_AX_WDE_BUFRTN_INVLD_PKTID_ERR_INT_EN | \ + B_AX_WDE_BUFRTN_SIZE_ERR_INT_EN | \ + B_AX_WDE_BUFREQ_SRCHTAILPG_ERR_INT_EN | \ + B_AX_WDE_GETNPG_STRPG_ERR_INT_EN | \ + B_AX_WDE_GETNPG_PGOFST_ERR_INT_EN | \ + B_AX_WDE_BUFMGN_FRZTO_ERR_INT_EN | \ + B_AX_WDE_QUE_CMDTYPE_ERR_INT_EN | \ + B_AX_WDE_QUE_DSTQUEID_ERR_INT_EN | \ + B_AX_WDE_QUE_SRCQUEID_ERR_INT_EN | \ + B_AX_WDE_ENQ_PKTCNT_OVRF_ERR_INT_EN | \ + B_AX_WDE_ENQ_PKTCNT_NVAL_ERR_INT_EN | \ + B_AX_WDE_PREPKTLLT_AD_ERR_INT_EN | \ + B_AX_WDE_NXTPKTLL_AD_ERR_INT_EN | \ + B_AX_WDE_QUEMGN_FRZTO_ERR_INT_EN | \ + B_AX_WDE_DATCHN_ARBT_ERR_INT_EN | \ + B_AX_WDE_DATCHN_NULLPG_ERR_INT_EN | \ + B_AX_WDE_DATCHN_FRZTO_ERR_INT_EN) +#define B_AX_WDE_IMR_SET (B_AX_WDE_BUFREQ_QTAID_ERR_INT_EN | \ + B_AX_WDE_BUFREQ_SIZE0_INT_EN | \ + B_AX_WDE_BUFREQ_SIZELMT_INT_EN | \ + B_AX_WDE_BUFREQ_UNAVAL_ERR_INT_EN_V1 | \ + B_AX_WDE_BUFRTN_INVLD_PKTID_ERR_INT_EN_V1 | \ + B_AX_WDE_BUFRTN_SIZE_ERR_INT_EN_V1 | \ + B_AX_WDE_BUFREQ_SRCHTAILPG_ERR_INT_EN_V1 | \ + B_AX_WDE_GETNPG_STRPG_ERR_INT_EN_V1 | \ + B_AX_WDE_GETNPG_PGOFST_ERR_INT_EN_V1 | \ + B_AX_WDE_BUFMGN_FRZTO_ERR_INT_EN_V1 | \ + B_AX_WDE_QUE_CMDTYPE_ERR_INT_EN | \ + B_AX_WDE_QUE_DSTQUEID_ERR_INT_EN | \ + B_AX_WDE_QUE_SRCQUEID_ERR_INT_EN | \ + B_AX_WDE_ENQ_PKTCNT_OVRF_ERR_INT_EN | \ + B_AX_WDE_ENQ_PKTCNT_NVAL_ERR_INT_EN | \ + B_AX_WDE_PREPKTLLT_AD_ERR_INT_EN | \ + B_AX_WDE_NXTPKTLL_AD_ERR_INT_EN | \ + B_AX_WDE_QUEMGN_FRZTO_ERR_INT_EN | \ + B_AX_WDE_DATCHN_ARBT_ERR_INT_EN | \ + B_AX_WDE_DATCHN_NULLPG_ERR_INT_EN | \ + B_AX_WDE_DATCHN_FRZTO_ERR_INT_EN | \ + B_AX_WDE_DATCHN_RRDY_ERR_INT_EN | \ + B_AX_WDE_DATCHN_ADRERR_ERR_INT_EN | \ + B_AX_WDE_DATCHN_CAMREQ_ERR_INT_EN) + +#define B_AX_WDE_DATCHN_CAMREQ_ERR_INT_EN BIT(29) +#define B_AX_WDE_DATCHN_ADRERR_ERR_INT_EN BIT(28) +#define B_AX_WDE_DATCHN_RRDY_ERR_INT_EN BIT(27) +#define B_AX_WDE_DATCHN_FRZTO_ERR_INT_EN BIT(26) +#define B_AX_WDE_DATCHN_NULLPG_ERR_INT_EN BIT(25) +#define B_AX_WDE_DATCHN_ARBT_ERR_INT_EN BIT(24) +#define B_AX_WDE_QUEMGN_FRZTO_ERR_INT_EN BIT(19) +#define B_AX_WDE_NXTPKTLL_AD_ERR_INT_EN BIT(18) +#define B_AX_WDE_PREPKTLLT_AD_ERR_INT_EN BIT(17) +#define B_AX_WDE_ENQ_PKTCNT_NVAL_ERR_INT_EN BIT(16) +#define B_AX_WDE_ENQ_PKTCNT_OVRF_ERR_INT_EN BIT(15) +#define B_AX_WDE_QUE_SRCQUEID_ERR_INT_EN BIT(14) +#define B_AX_WDE_BUFMGN_FRZTO_ERR_INT_EN_V1 BIT(9) +#define B_AX_WDE_GETNPG_PGOFST_ERR_INT_EN_V1 BIT(8) +#define B_AX_WDE_GETNPG_STRPG_ERR_INT_EN_V1 BIT(7) +#define B_AX_WDE_BUFREQ_SRCHTAILPG_ERR_INT_EN_V1 BIT(6) +#define B_AX_WDE_BUFRTN_SIZE_ERR_INT_EN_V1 BIT(5) +#define B_AX_WDE_BUFRTN_INVLD_PKTID_ERR_INT_EN_V1 BIT(4) +#define B_AX_WDE_BUFREQ_UNAVAL_ERR_INT_EN_V1 BIT(3) +#define B_AX_WDE_BUFREQ_SIZELMT_INT_EN BIT(2) +#define B_AX_WDE_BUFREQ_SIZE0_INT_EN BIT(1) +#define B_AX_WDE_IMR_CLR_V1 (B_AX_WDE_BUFREQ_QTAID_ERR_INT_EN | \ + B_AX_WDE_BUFREQ_SIZE0_INT_EN | \ + B_AX_WDE_BUFREQ_SIZELMT_INT_EN | \ + B_AX_WDE_BUFREQ_UNAVAL_ERR_INT_EN_V1 | \ + B_AX_WDE_BUFRTN_INVLD_PKTID_ERR_INT_EN_V1 | \ + B_AX_WDE_BUFRTN_SIZE_ERR_INT_EN_V1 | \ + B_AX_WDE_BUFREQ_SRCHTAILPG_ERR_INT_EN_V1 | \ + B_AX_WDE_GETNPG_STRPG_ERR_INT_EN_V1 | \ + B_AX_WDE_GETNPG_PGOFST_ERR_INT_EN_V1 | \ + B_AX_WDE_BUFMGN_FRZTO_ERR_INT_EN_V1 | \ + B_AX_WDE_QUE_CMDTYPE_ERR_INT_EN | \ + B_AX_WDE_QUE_DSTQUEID_ERR_INT_EN | \ + B_AX_WDE_QUE_SRCQUEID_ERR_INT_EN | \ + B_AX_WDE_ENQ_PKTCNT_OVRF_ERR_INT_EN | \ + B_AX_WDE_ENQ_PKTCNT_NVAL_ERR_INT_EN | \ + B_AX_WDE_PREPKTLLT_AD_ERR_INT_EN | \ + B_AX_WDE_NXTPKTLL_AD_ERR_INT_EN | \ + B_AX_WDE_QUEMGN_FRZTO_ERR_INT_EN | \ + B_AX_WDE_DATCHN_ARBT_ERR_INT_EN | \ + B_AX_WDE_DATCHN_NULLPG_ERR_INT_EN | \ + B_AX_WDE_DATCHN_FRZTO_ERR_INT_EN | \ + B_AX_WDE_DATCHN_RRDY_ERR_INT_EN | \ + B_AX_WDE_DATCHN_ADRERR_ERR_INT_EN | \ + B_AX_WDE_DATCHN_CAMREQ_ERR_INT_EN) +#define B_AX_WDE_IMR_SET_V1 (B_AX_WDE_BUFREQ_QTAID_ERR_INT_EN | \ + B_AX_WDE_BUFREQ_SIZE0_INT_EN | \ + B_AX_WDE_BUFREQ_SIZELMT_INT_EN | \ + B_AX_WDE_BUFREQ_UNAVAL_ERR_INT_EN_V1 | \ + B_AX_WDE_BUFRTN_INVLD_PKTID_ERR_INT_EN_V1 | \ + B_AX_WDE_BUFRTN_SIZE_ERR_INT_EN_V1 | \ + B_AX_WDE_BUFREQ_SRCHTAILPG_ERR_INT_EN_V1 | \ + B_AX_WDE_GETNPG_STRPG_ERR_INT_EN_V1 | \ + B_AX_WDE_GETNPG_PGOFST_ERR_INT_EN_V1 | \ + B_AX_WDE_BUFMGN_FRZTO_ERR_INT_EN_V1 | \ + B_AX_WDE_QUE_CMDTYPE_ERR_INT_EN | \ + B_AX_WDE_QUE_DSTQUEID_ERR_INT_EN | \ + B_AX_WDE_QUE_SRCQUEID_ERR_INT_EN | \ + B_AX_WDE_ENQ_PKTCNT_OVRF_ERR_INT_EN | \ + B_AX_WDE_ENQ_PKTCNT_NVAL_ERR_INT_EN | \ + B_AX_WDE_PREPKTLLT_AD_ERR_INT_EN | \ + B_AX_WDE_NXTPKTLL_AD_ERR_INT_EN | \ + B_AX_WDE_QUEMGN_FRZTO_ERR_INT_EN | \ + B_AX_WDE_DATCHN_ARBT_ERR_INT_EN | \ + B_AX_WDE_DATCHN_NULLPG_ERR_INT_EN | \ + B_AX_WDE_DATCHN_FRZTO_ERR_INT_EN | \ + B_AX_WDE_DATCHN_RRDY_ERR_INT_EN | \ + B_AX_WDE_DATCHN_ADRERR_ERR_INT_EN | \ + B_AX_WDE_DATCHN_CAMREQ_ERR_INT_EN) + #define R_AX_WDE_ERR_ISR 0x8C3C +#define B_AX_WDE_DATCHN_RRDY_ERR BIT(27) +#define B_AX_WDE_DATCHN_FRZTO_ERR BIT(26) +#define B_AX_WDE_DATCHN_NULLPG_ERR BIT(25) +#define B_AX_WDE_DATCHN_ARBT_ERR BIT(24) +#define B_AX_WDE_QUEMGN_FRZTO_ERR BIT(19) +#define B_AX_WDE_NXTPKTLL_AD_ERR BIT(18) +#define B_AX_WDE_PREPKTLLT_AD_ERR BIT(17) +#define B_AX_WDE_ENQ_PKTCNT_NVAL_ERR BIT(16) +#define B_AX_WDE_ENQ_PKTCNT_OVRF_ERR BIT(15) +#define B_AX_WDE_QUE_SRCQUEID_ERR BIT(14) +#define B_AX_WDE_QUE_DSTQUEID_ERR BIT(13) +#define B_AX_WDE_QUE_CMDTYPE_ERR BIT(12) +#define B_AX_WDE_BUFMGN_FRZTO_ERR BIT(7) +#define B_AX_WDE_GETNPG_PGOFST_ERR BIT(6) +#define B_AX_WDE_GETNPG_STRPG_ERR BIT(5) +#define B_AX_WDE_BUFREQ_SRCHTAILPG_ERR BIT(4) +#define B_AX_WDE_BUFRTN_SIZE_ERR BIT(3) +#define B_AX_WDE_BUFRTN_INVLD_PKTID_ERR BIT(2) +#define B_AX_WDE_BUFREQ_UNAVAL_ERR BIT(1) +#define B_AX_WDE_BUFREQ_QTAID_ERR BIT(0) #define B_AX_WDE_MAX_SIZE_MASK GENMASK(27, 16) #define B_AX_WDE_MIN_SIZE_MASK GENMASK(11, 0) @@ -649,7 +1156,123 @@ #define R_AX_PLE_ERR_FLAG_CFG 0x9034 #define R_AX_PLE_ERR_IMR 0x9038 +#define B_AX_PLE_DATCHN_RRDY_ERR_INT_EN BIT(27) +#define B_AX_PLE_DATCHN_FRZTO_ERR_INT_EN BIT(26) +#define B_AX_PLE_DATCHN_NULLPG_ERR_INT_EN BIT(25) +#define B_AX_PLE_DATCHN_ARBT_ERR_INT_EN BIT(24) +#define B_AX_PLE_QUEMGN_FRZTO_ERR_INT_EN BIT(19) +#define B_AX_PLE_NXTPKTLL_AD_ERR_INT_EN BIT(18) +#define B_AX_PLE_PREPKTLLT_AD_ERR_INT_EN BIT(17) +#define B_AX_PLE_ENQ_PKTCNT_NVAL_ERR_INT_EN BIT(16) +#define B_AX_PLE_ENQ_PKTCNT_OVRF_ERR_INT_EN BIT(15) +#define B_AX_PLE_QUE_SRCQUEID_ERR_INT_EN BIT(14) +#define B_AX_PLE_QUE_DSTQUEID_ERR_INT_EN BIT(13) +#define B_AX_PLE_QUE_CMDTYPE_ERR_INT_EN BIT(12) +#define B_AX_PLE_BUFMGN_FRZTO_ERR_INT_EN BIT(7) +#define B_AX_PLE_GETNPG_PGOFST_ERR_INT_EN BIT(6) #define B_AX_PLE_GETNPG_STRPG_ERR_INT_EN BIT(5) +#define B_AX_PLE_BUFREQ_SRCHTAILPG_ERR_INT_EN BIT(4) +#define B_AX_PLE_BUFRTN_SIZE_ERR_INT_EN BIT(3) +#define B_AX_PLE_BUFRTN_INVLD_PKTID_ERR_INT_EN BIT(2) +#define B_AX_PLE_BUFREQ_UNAVAL_ERR_INT_EN BIT(1) +#define B_AX_PLE_BUFREQ_QTAID_ERR_INT_EN BIT(0) +#define B_AX_PLE_IMR_CLR (B_AX_PLE_BUFREQ_QTAID_ERR_INT_EN | \ + B_AX_PLE_BUFREQ_UNAVAL_ERR_INT_EN | \ + B_AX_PLE_BUFRTN_INVLD_PKTID_ERR_INT_EN | \ + B_AX_PLE_BUFRTN_SIZE_ERR_INT_EN | \ + B_AX_PLE_BUFREQ_SRCHTAILPG_ERR_INT_EN | \ + B_AX_PLE_GETNPG_STRPG_ERR_INT_EN | \ + B_AX_PLE_GETNPG_PGOFST_ERR_INT_EN | \ + B_AX_PLE_BUFMGN_FRZTO_ERR_INT_EN | \ + B_AX_PLE_QUE_CMDTYPE_ERR_INT_EN | \ + B_AX_PLE_QUE_DSTQUEID_ERR_INT_EN | \ + B_AX_PLE_QUE_SRCQUEID_ERR_INT_EN | \ + B_AX_PLE_ENQ_PKTCNT_OVRF_ERR_INT_EN | \ + B_AX_PLE_ENQ_PKTCNT_NVAL_ERR_INT_EN | \ + B_AX_PLE_PREPKTLLT_AD_ERR_INT_EN | \ + B_AX_PLE_NXTPKTLL_AD_ERR_INT_EN | \ + B_AX_PLE_QUEMGN_FRZTO_ERR_INT_EN | \ + B_AX_PLE_DATCHN_ARBT_ERR_INT_EN | \ + B_AX_PLE_DATCHN_NULLPG_ERR_INT_EN | \ + B_AX_PLE_DATCHN_FRZTO_ERR_INT_EN) +#define B_AX_PLE_IMR_SET (B_AX_PLE_BUFREQ_QTAID_ERR_INT_EN | \ + B_AX_PLE_BUFREQ_UNAVAL_ERR_INT_EN | \ + B_AX_PLE_BUFRTN_INVLD_PKTID_ERR_INT_EN | \ + B_AX_PLE_BUFRTN_SIZE_ERR_INT_EN | \ + B_AX_PLE_BUFREQ_SRCHTAILPG_ERR_INT_EN | \ + B_AX_PLE_GETNPG_PGOFST_ERR_INT_EN | \ + B_AX_PLE_BUFMGN_FRZTO_ERR_INT_EN | \ + B_AX_PLE_QUE_CMDTYPE_ERR_INT_EN | \ + B_AX_PLE_QUE_DSTQUEID_ERR_INT_EN | \ + B_AX_PLE_QUE_SRCQUEID_ERR_INT_EN | \ + B_AX_PLE_ENQ_PKTCNT_OVRF_ERR_INT_EN | \ + B_AX_PLE_ENQ_PKTCNT_NVAL_ERR_INT_EN | \ + B_AX_PLE_PREPKTLLT_AD_ERR_INT_EN | \ + B_AX_PLE_NXTPKTLL_AD_ERR_INT_EN | \ + B_AX_PLE_QUEMGN_FRZTO_ERR_INT_EN | \ + B_AX_PLE_DATCHN_ARBT_ERR_INT_EN | \ + B_AX_PLE_DATCHN_NULLPG_ERR_INT_EN | \ + B_AX_PLE_DATCHN_FRZTO_ERR_INT_EN) + +#define B_AX_PLE_DATCHN_CAMREQ_ERR_INT_EN BIT(29) +#define B_AX_PLE_DATCHN_ADRERR_ERR_INT_EN BIT(28) +#define B_AX_PLE_BUFMGN_FRZTO_ERR_INT_EN_V1 BIT(9) +#define B_AX_PLE_GETNPG_PGOFST_ERR_INT_EN_V1 BIT(8) +#define B_AX_PLE_GETNPG_STRPG_ERR_INT_EN_V1 BIT(7) +#define B_AX_PLE_BUFREQ_SRCHTAILPG_ERR_INT_EN_V1 BIT(6) +#define B_AX_PLE_BUFRTN_SIZE_ERR_INT_EN_V1 BIT(5) +#define B_AX_PLE_BUFRTN_INVLD_PKTID_ERR_INT_EN_V1 BIT(4) +#define B_AX_PLE_BUFREQ_UNAVAL_ERR_INT_EN_V1 BIT(3) +#define B_AX_PLE_BUFREQ_SIZELMT_INT_EN BIT(2) +#define B_AX_PLE_BUFREQ_SIZE0_INT_EN BIT(1) +#define B_AX_PLE_IMR_CLR_V1 (B_AX_PLE_BUFREQ_QTAID_ERR_INT_EN | \ + B_AX_PLE_BUFREQ_SIZE0_INT_EN | \ + B_AX_PLE_BUFREQ_SIZELMT_INT_EN | \ + B_AX_PLE_BUFREQ_UNAVAL_ERR_INT_EN_V1 | \ + B_AX_PLE_BUFRTN_INVLD_PKTID_ERR_INT_EN_V1 | \ + B_AX_PLE_BUFRTN_SIZE_ERR_INT_EN_V1 | \ + B_AX_PLE_BUFREQ_SRCHTAILPG_ERR_INT_EN_V1 | \ + B_AX_PLE_GETNPG_STRPG_ERR_INT_EN_V1 | \ + B_AX_PLE_GETNPG_PGOFST_ERR_INT_EN_V1 | \ + B_AX_PLE_BUFMGN_FRZTO_ERR_INT_EN_V1 | \ + B_AX_PLE_QUE_CMDTYPE_ERR_INT_EN | \ + B_AX_PLE_QUE_DSTQUEID_ERR_INT_EN | \ + B_AX_PLE_QUE_SRCQUEID_ERR_INT_EN | \ + B_AX_PLE_ENQ_PKTCNT_OVRF_ERR_INT_EN | \ + B_AX_PLE_ENQ_PKTCNT_NVAL_ERR_INT_EN | \ + B_AX_PLE_PREPKTLLT_AD_ERR_INT_EN | \ + B_AX_PLE_NXTPKTLL_AD_ERR_INT_EN | \ + B_AX_PLE_QUEMGN_FRZTO_ERR_INT_EN | \ + B_AX_PLE_DATCHN_ARBT_ERR_INT_EN | \ + B_AX_PLE_DATCHN_NULLPG_ERR_INT_EN | \ + B_AX_PLE_DATCHN_FRZTO_ERR_INT_EN | \ + B_AX_PLE_DATCHN_RRDY_ERR_INT_EN | \ + B_AX_PLE_DATCHN_ADRERR_ERR_INT_EN | \ + B_AX_PLE_DATCHN_CAMREQ_ERR_INT_EN) +#define B_AX_PLE_IMR_SET_V1 (B_AX_PLE_BUFREQ_QTAID_ERR_INT_EN | \ + B_AX_PLE_BUFREQ_SIZE0_INT_EN | \ + B_AX_PLE_BUFREQ_SIZELMT_INT_EN | \ + B_AX_PLE_BUFREQ_UNAVAL_ERR_INT_EN_V1 | \ + B_AX_PLE_BUFRTN_INVLD_PKTID_ERR_INT_EN_V1 | \ + B_AX_PLE_BUFRTN_SIZE_ERR_INT_EN_V1 | \ + B_AX_PLE_BUFREQ_SRCHTAILPG_ERR_INT_EN_V1 | \ + B_AX_PLE_GETNPG_STRPG_ERR_INT_EN_V1 | \ + B_AX_PLE_GETNPG_PGOFST_ERR_INT_EN_V1 | \ + B_AX_PLE_BUFMGN_FRZTO_ERR_INT_EN_V1 | \ + B_AX_PLE_QUE_CMDTYPE_ERR_INT_EN | \ + B_AX_PLE_QUE_DSTQUEID_ERR_INT_EN | \ + B_AX_PLE_QUE_SRCQUEID_ERR_INT_EN | \ + B_AX_PLE_ENQ_PKTCNT_OVRF_ERR_INT_EN | \ + B_AX_PLE_ENQ_PKTCNT_NVAL_ERR_INT_EN | \ + B_AX_PLE_PREPKTLLT_AD_ERR_INT_EN | \ + B_AX_PLE_NXTPKTLL_AD_ERR_INT_EN | \ + B_AX_PLE_QUEMGN_FRZTO_ERR_INT_EN | \ + B_AX_PLE_DATCHN_ARBT_ERR_INT_EN | \ + B_AX_PLE_DATCHN_NULLPG_ERR_INT_EN | \ + B_AX_PLE_DATCHN_FRZTO_ERR_INT_EN | \ + B_AX_PLE_DATCHN_RRDY_ERR_INT_EN | \ + B_AX_PLE_DATCHN_ADRERR_ERR_INT_EN | \ + B_AX_PLE_DATCHN_CAMREQ_ERR_INT_EN) #define R_AX_PLE_ERR_FLAG_ISR 0x903C #define B_AX_PLE_MAX_SIZE_MASK GENMASK(27, 16) @@ -704,12 +1327,97 @@ #define B_AX_WDRLS_CTL_FRZTO_ERR_INT_EN BIT(2) #define B_AX_WDRLS_CTL_PLPKTID_ISNULL_ERR_INT_EN BIT(1) #define B_AX_WDRLS_CTL_WDPKTID_ISNULL_ERR_INT_EN BIT(0) +#define B_AX_WDRLS_IMR_EN_CLR (B_AX_WDRLS_CTL_WDPKTID_ISNULL_ERR_INT_EN | \ + B_AX_WDRLS_CTL_PLPKTID_ISNULL_ERR_INT_EN | \ + B_AX_WDRLS_CTL_FRZTO_ERR_INT_EN | \ + B_AX_WDRLS_PLEBREQ_TO_ERR_INT_EN | \ + B_AX_WDRLS_PLEBREQ_PKTID_ISNULL_ERR_INT_EN | \ + B_AX_WDRLS_RPT0_AGGNUM0_ERR_INT_EN | \ + B_AX_WDRLS_RPT0_FRZTO_ERR_INT_EN | \ + B_AX_WDRLS_RPT1_AGGNUM0_ERR_INT_EN | \ + B_AX_WDRLS_RPT1_FRZTO_ERR_INT_EN) +#define B_AX_WDRLS_IMR_SET (B_AX_WDRLS_CTL_WDPKTID_ISNULL_ERR_INT_EN | \ + B_AX_WDRLS_CTL_PLPKTID_ISNULL_ERR_INT_EN | \ + B_AX_WDRLS_CTL_FRZTO_ERR_INT_EN | \ + B_AX_WDRLS_PLEBREQ_PKTID_ISNULL_ERR_INT_EN | \ + B_AX_WDRLS_RPT0_AGGNUM0_ERR_INT_EN | \ + B_AX_WDRLS_RPT0_FRZTO_ERR_INT_EN | \ + B_AX_WDRLS_RPT1_AGGNUM0_ERR_INT_EN | \ + B_AX_WDRLS_RPT1_FRZTO_ERR_INT_EN) +#define B_AX_WDRLS_IMR_SET_V1 (B_AX_WDRLS_CTL_WDPKTID_ISNULL_ERR_INT_EN | \ + B_AX_WDRLS_CTL_PLPKTID_ISNULL_ERR_INT_EN | \ + B_AX_WDRLS_CTL_FRZTO_ERR_INT_EN | \ + B_AX_WDRLS_PLEBREQ_TO_ERR_INT_EN | \ + B_AX_WDRLS_PLEBREQ_PKTID_ISNULL_ERR_INT_EN | \ + B_AX_WDRLS_RPT0_AGGNUM0_ERR_INT_EN | \ + B_AX_WDRLS_RPT0_FRZTO_ERR_INT_EN | \ + B_AX_WDRLS_RPT1_AGGNUM0_ERR_INT_EN | \ + B_AX_WDRLS_RPT1_FRZTO_ERR_INT_EN) + #define R_AX_WDRLS_ERR_ISR 0x9434 +#define R_AX_BBRPT_COM_ERR_IMR 0x9608 +#define B_AX_BBRPT_COM_HANG_EN BIT(1) +#define B_AX_BBRPT_COM_NULL_PLPKTID_ERR_INT_EN BIT(0) + #define R_AX_BBRPT_COM_ERR_IMR_ISR 0x960C +#define B_AX_BBRPT_COM_NULL_PLPKTID_ERR BIT(16) +#define B_AX_BBRPT_COM_NULL_PLPKTID_ERR_INT_EN BIT(0) + +#define R_AX_BBRPT_CHINFO_ERR_IMR 0x9628 +#define B_AX_BBPRT_CHIF_TO_ERR_INT_EN BIT(7) +#define B_AX_BBPRT_CHIF_NULL_ERR_INT_EN BIT(6) +#define B_AX_BBPRT_CHIF_LEFT2_ERR_INT_EN BIT(5) +#define B_AX_BBPRT_CHIF_LEFT1_ERR_INT_EN BIT(4) +#define B_AX_BBPRT_CHIF_HDRL_ERR_INT_EN BIT(3) +#define B_AX_BBPRT_CHIF_BOVF_ERR_INT_EN BIT(2) +#define B_AX_BBPRT_CHIF_OVF_ERR_INT_EN BIT(1) +#define B_AX_BBPRT_CHIF_BB_TO_ERR_INT_EN BIT(0) +#define R_AX_BBRPT_CHINFO_IMR_SET_V1 (B_AX_BBPRT_CHIF_BB_TO_ERR_INT_EN | \ + B_AX_BBPRT_CHIF_OVF_ERR_INT_EN | \ + B_AX_BBPRT_CHIF_BOVF_ERR_INT_EN | \ + B_AX_BBPRT_CHIF_HDRL_ERR_INT_EN | \ + B_AX_BBPRT_CHIF_LEFT1_ERR_INT_EN | \ + B_AX_BBPRT_CHIF_LEFT2_ERR_INT_EN | \ + B_AX_BBPRT_CHIF_NULL_ERR_INT_EN | \ + B_AX_BBPRT_CHIF_TO_ERR_INT_EN) + #define R_AX_BBRPT_CHINFO_ERR_IMR_ISR 0x962C +#define B_AX_BBPRT_CHIF_TO_ERR BIT(23) +#define B_AX_BBPRT_CHIF_NULL_ERR BIT(22) +#define B_AX_BBPRT_CHIF_LEFT2_ERR BIT(21) +#define B_AX_BBPRT_CHIF_LEFT1_ERR BIT(20) +#define B_AX_BBPRT_CHIF_HDRL_ERR BIT(19) +#define B_AX_BBPRT_CHIF_BOVF_ERR BIT(18) +#define B_AX_BBPRT_CHIF_OVF_ERR BIT(17) +#define B_AX_BBPRT_CHIF_BB_TO_ERR BIT(16) +#define B_AX_BBPRT_CHIF_TO_ERR_INT_EN BIT(7) +#define B_AX_BBPRT_CHIF_NULL_ERR_INT_EN BIT(6) +#define B_AX_BBPRT_CHIF_LEFT2_ERR_INT_EN BIT(5) +#define B_AX_BBPRT_CHIF_LEFT1_ERR_INT_EN BIT(4) +#define B_AX_BBPRT_CHIF_HDRL_ERR_INT_EN BIT(3) +#define B_AX_BBPRT_CHIF_BOVF_ERR_INT_EN BIT(2) +#define B_AX_BBPRT_CHIF_OVF_ERR_INT_EN BIT(1) +#define B_AX_BBPRT_CHIF_BB_TO_ERR_INT_EN BIT(0) +#define B_AX_BBRPT_CHINFO_IMR_CLR (B_AX_BBPRT_CHIF_BB_TO_ERR_INT_EN | \ + B_AX_BBPRT_CHIF_OVF_ERR_INT_EN | \ + B_AX_BBPRT_CHIF_BOVF_ERR_INT_EN | \ + B_AX_BBPRT_CHIF_HDRL_ERR_INT_EN | \ + B_AX_BBPRT_CHIF_LEFT1_ERR_INT_EN | \ + B_AX_BBPRT_CHIF_LEFT2_ERR_INT_EN | \ + B_AX_BBPRT_CHIF_NULL_ERR_INT_EN | \ + B_AX_BBPRT_CHIF_TO_ERR_INT_EN) + +#define R_AX_BBRPT_DFS_ERR_IMR 0x9638 +#define B_AX_BBRPT_DFS_TO_ERR_INT_EN BIT(0) + #define R_AX_BBRPT_DFS_ERR_IMR_ISR 0x963C +#define B_AX_BBRPT_DFS_TO_ERR BIT(16) +#define B_AX_BBRPT_DFS_TO_ERR_INT_EN BIT(0) + #define R_AX_LA_ERRFLAG 0x966C +#define B_AX_LA_ISR_DATA_LOSS_ERR BIT(16) +#define B_AX_LA_IMR_DATA_LOSS_ERR BIT(0) #define R_AX_WD_BUF_REQ 0x9800 #define R_AX_PL_BUF_REQ 0x9820 @@ -745,18 +1453,51 @@ #define R_AX_PL_CPUQ_OP_STATUS 0x983C #define B_AX_WD_CPUQ_OP_STAT_DONE BIT(31) #define B_AX_WD_CPUQ_OP_PKTID_MASK GENMASK(11, 0) + #define R_AX_CPUIO_ERR_IMR 0x9840 +#define B_AX_PLEQUE_OP_ERR_INT_EN BIT(12) +#define B_AX_PLEBUF_OP_ERR_INT_EN BIT(8) +#define B_AX_WDEQUE_OP_ERR_INT_EN BIT(4) +#define B_AX_WDEBUF_OP_ERR_INT_EN BIT(0) +#define B_AX_CPUIO_IMR_CLR (B_AX_WDEBUF_OP_ERR_INT_EN | \ + B_AX_WDEQUE_OP_ERR_INT_EN | \ + B_AX_PLEBUF_OP_ERR_INT_EN | \ + B_AX_PLEQUE_OP_ERR_INT_EN) +#define B_AX_CPUIO_IMR_SET (B_AX_WDEBUF_OP_ERR_INT_EN | \ + B_AX_WDEQUE_OP_ERR_INT_EN | \ + B_AX_PLEBUF_OP_ERR_INT_EN | \ + B_AX_PLEQUE_OP_ERR_INT_EN) + #define R_AX_CPUIO_ERR_ISR 0x9844 #define R_AX_SEC_ERR_IMR_ISR 0x991C #define R_AX_PKTIN_SETTING 0x9A00 #define B_AX_WD_ADDR_INFO_LENGTH BIT(1) + #define R_AX_PKTIN_ERR_IMR 0x9A20 +#define B_AX_PKTIN_GETPKTID_ERR_INT_EN BIT(0) + #define R_AX_PKTIN_ERR_ISR 0x9A24 #define R_AX_MPDU_TX_ERR_ISR 0x9BF0 #define R_AX_MPDU_TX_ERR_IMR 0x9BF4 +#define B_AX_TX_KSRCH_ERR_EN BIT(9) +#define B_AX_TX_NW_TYPE_ERR_EN BIT(8) +#define B_AX_TX_LLC_PRE_ERR_EN BIT(7) +#define B_AX_TX_ETH_TYPE_ERR_EN BIT(6) +#define B_AX_TX_HDR3_SIZE_ERR_INT_EN BIT(5) +#define B_AX_TX_OFFSET_ERR_INT_EN BIT(4) +#define B_AX_TX_MPDU_SIZE_ZERO_INT_EN BIT(3) +#define B_AX_TX_NXT_ERRPKTID_INT_EN BIT(2) +#define B_AX_TX_GET_ERRPKTID_INT_EN BIT(1) +#define B_AX_MPDU_TX_IMR_SET_V1 (B_AX_TX_GET_ERRPKTID_INT_EN | \ + B_AX_TX_NXT_ERRPKTID_INT_EN | \ + B_AX_TX_MPDU_SIZE_ZERO_INT_EN | \ + B_AX_TX_HDR3_SIZE_ERR_INT_EN | \ + B_AX_TX_ETH_TYPE_ERR_EN | \ + B_AX_TX_NW_TYPE_ERR_EN | \ + B_AX_TX_KSRCH_ERR_EN) #define R_AX_MPDU_PROC 0x9C00 #define B_AX_A_ICV_ERR BIT(1) @@ -778,6 +1519,10 @@ #define R_AX_MPDU_RX_ERR_ISR 0x9CF0 #define R_AX_MPDU_RX_ERR_IMR 0x9CF4 +#define B_AX_RPT_ERR_INT_EN BIT(3) +#define B_AX_MHDRLEN_ERR_INT_EN BIT(1) +#define B_AX_GETPKTID_ERR_INT_EN BIT(0) +#define B_AX_MPDU_RX_IMR_SET_V1 B_AX_RPT_ERR_INT_EN #define R_AX_SEC_ENG_CTRL 0x9D00 #define B_AX_TX_PARTIAL_MODE BIT(11) @@ -798,15 +1543,23 @@ #define R_AX_SEC_CAM_ACCESS 0x9D10 #define R_AX_SEC_CAM_RDATA 0x9D14 #define R_AX_SEC_CAM_WDATA 0x9D18 + #define R_AX_SEC_DEBUG 0x9D1C +#define B_AX_IMR_ERROR BIT(3) + #define R_AX_SEC_DEBUG1 0x9D1C #define B_AX_TX_TIMEOUT_SEL_MASK GENMASK(31, 30) #define AX_TX_TO_VAL 0x2 + #define R_AX_SEC_TX_DEBUG 0x9D20 #define R_AX_SEC_RX_DEBUG 0x9D24 #define R_AX_SEC_TRX_PKT_CNT 0x9D28 #define R_AX_SEC_TRX_BLK_CNT 0x9D2C +#define R_AX_SEC_ERROR_FLAG_IMR 0x9D2C +#define B_AX_RX_HANG_IMR BIT(1) +#define B_AX_TX_HANG_IMR BIT(0) + #define R_AX_SS_CTRL 0x9E10 #define B_AX_SS_INIT_DONE_1 BIT(31) #define B_AX_SS_WARM_INIT_FLG BIT(29) @@ -838,9 +1591,47 @@ #define B_AX_SS_MACID127_96_PAUSE_MASK GENMASK(31, 0) #define R_AX_STA_SCHEDULER_ERR_IMR 0x9EF0 +#define B_AX_PLE_B_PKTID_ERR_INT_EN BIT(2) +#define B_AX_RPT_HANG_TIMEOUT_INT_EN BIT(1) +#define B_AX_SEARCH_HANG_TIMEOUT_INT_EN BIT(0) +#define B_AX_STA_SCHEDULER_IMR_SET (B_AX_SEARCH_HANG_TIMEOUT_INT_EN | \ + B_AX_RPT_HANG_TIMEOUT_INT_EN | \ + B_AX_PLE_B_PKTID_ERR_INT_EN) + #define R_AX_STA_SCHEDULER_ERR_ISR 0x9EF4 #define R_AX_TXPKTCTL_ERR_IMR_ISR 0x9F1C +#define B_AX_TXPKTCTL_CMDPSR_FRZTO_ERR BIT(25) +#define B_AX_TXPKTCTL_CMDPSR_CMDTYPE_ERR BIT(24) +#define B_AX_TXPKTCTL_USRCTL_RLSBMPLEN_ERR BIT(19) +#define B_AX_TXPKTCTL_USRCTL_RDNRLSCMD_ERR BIT(18) +#define B_AX_TXPKTCTL_USRCTL_NOINIT_ERR BIT(17) +#define B_AX_TXPKTCTL_USRCTL_REINIT_ERR BIT(16) +#define B_AX_TXPKTCTL_CMDPSR_FRZTO_ERR_INT_EN BIT(9) +#define B_AX_TXPKTCTL_CMDPSR_CMDTYPE_ERR_INT_EN BIT(8) +#define B_AX_TXPKTCTL_USRCTL_RLSBMPLEN_ERR_INT_EN BIT(3) +#define B_AX_TXPKTCTL_USRCTL_RDNRLSCMD_ERR_INT_EN BIT(2) +#define B_AX_TXPKTCTL_USRCTL_NOINIT_ERR_INT_EN BIT(1) +#define B_AX_TXPKTCTL_USRCTL_REINIT_ERR_INT_EN BIT(0) +#define B_AX_TXPKTCTL_IMR_B0_CLR (B_AX_TXPKTCTL_USRCTL_REINIT_ERR_INT_EN | \ + B_AX_TXPKTCTL_USRCTL_NOINIT_ERR_INT_EN | \ + B_AX_TXPKTCTL_USRCTL_RDNRLSCMD_ERR_INT_EN | \ + B_AX_TXPKTCTL_USRCTL_RLSBMPLEN_ERR_INT_EN | \ + B_AX_TXPKTCTL_CMDPSR_CMDTYPE_ERR_INT_EN | \ + B_AX_TXPKTCTL_CMDPSR_FRZTO_ERR_INT_EN) +#define B_AX_TXPKTCTL_IMR_B1_CLR (B_AX_TXPKTCTL_USRCTL_REINIT_ERR_INT_EN | \ + B_AX_TXPKTCTL_USRCTL_NOINIT_ERR_INT_EN | \ + B_AX_TXPKTCTL_USRCTL_RDNRLSCMD_ERR_INT_EN | \ + B_AX_TXPKTCTL_USRCTL_RLSBMPLEN_ERR_INT_EN | \ + B_AX_TXPKTCTL_CMDPSR_CMDTYPE_ERR_INT_EN | \ + B_AX_TXPKTCTL_CMDPSR_FRZTO_ERR_INT_EN) +#define B_AX_TXPKTCTL_IMR_B0_SET (B_AX_TXPKTCTL_USRCTL_REINIT_ERR_INT_EN | \ + B_AX_TXPKTCTL_CMDPSR_CMDTYPE_ERR_INT_EN) +#define B_AX_TXPKTCTL_IMR_B1_SET (B_AX_TXPKTCTL_USRCTL_REINIT_ERR_INT_EN | \ + B_AX_TXPKTCTL_USRCTL_NOINIT_ERR_INT_EN | \ + B_AX_TXPKTCTL_CMDPSR_CMDTYPE_ERR_INT_EN | \ + B_AX_TXPKTCTL_CMDPSR_FRZTO_ERR_INT_EN) + #define R_AX_TXPKTCTL_ERR_IMR_ISR_B1 0x9F2C #define B_AX_TXPKTCTL_CMDPSR_FRZTO_ERR_INT_EN BIT(9) #define B_AX_TXPKTCTL_USRCTL_RLSBMPLEN_ERR_INT_EN BIT(3) @@ -867,6 +1658,42 @@ #define PRELD_NEXT_WND 1 #define B_AX_B0_PRELD_NXT_RSVMINSZ_MASK GENMASK(7, 0) +#define R_AX_TXPKTCTL_B0_ERRFLAG_IMR 0x9F78 +#define B_AX_B0_IMR_ERR_PRELD_ENTNUMCFG BIT(21) +#define B_AX_B0_IMR_ERR_PRELD_RLSPKTSZERR BIT(20) +#define B_AX_B0_IMR_ERR_MPDUIF_DATAERR BIT(18) +#define B_AX_B0_IMR_ERR_MPDUINFO_RECFG BIT(16) +#define B_AX_B0_IMR_ERR_CMDPSR_TBLSZ BIT(11) +#define B_AX_B0_IMR_ERR_CMDPSR_FRZTO BIT(10) +#define B_AX_B0_IMR_ERR_CMDPSR_CMDTYPE BIT(9) +#define B_AX_B0_IMR_ERR_CMDPSR_1STCMDERR BIT(8) +#define B_AX_B0_IMR_ERR_USRCTL_RLSBMPLEN BIT(3) +#define B_AX_B0_IMR_ERR_USRCTL_RDNRLSCMD BIT(2) +#define B_AX_B0_IMR_ERR_USRCTL_NOINIT BIT(1) +#define B_AX_B0_IMR_ERR_USRCTL_REINIT BIT(0) +#define B_AX_TXPKTCTL_IMR_B0_CLR_V1 (B_AX_B0_IMR_ERR_USRCTL_REINIT | \ + B_AX_B0_IMR_ERR_USRCTL_NOINIT | \ + B_AX_B0_IMR_ERR_USRCTL_RDNRLSCMD | \ + B_AX_B0_IMR_ERR_USRCTL_RLSBMPLEN | \ + B_AX_B0_IMR_ERR_CMDPSR_1STCMDERR | \ + B_AX_B0_IMR_ERR_CMDPSR_CMDTYPE | \ + B_AX_B0_IMR_ERR_CMDPSR_FRZTO | \ + B_AX_B0_IMR_ERR_CMDPSR_TBLSZ | \ + B_AX_B0_IMR_ERR_MPDUINFO_RECFG | \ + B_AX_B0_IMR_ERR_MPDUIF_DATAERR | \ + B_AX_B0_IMR_ERR_PRELD_RLSPKTSZERR | \ + B_AX_B0_IMR_ERR_PRELD_ENTNUMCFG) +#define B_AX_TXPKTCTL_IMR_B0_SET_V1 (B_AX_B0_IMR_ERR_USRCTL_REINIT | \ + B_AX_B0_IMR_ERR_USRCTL_NOINIT | \ + B_AX_B0_IMR_ERR_CMDPSR_1STCMDERR | \ + B_AX_B0_IMR_ERR_CMDPSR_CMDTYPE | \ + B_AX_B0_IMR_ERR_CMDPSR_FRZTO | \ + B_AX_B0_IMR_ERR_CMDPSR_TBLSZ | \ + B_AX_B0_IMR_ERR_MPDUINFO_RECFG | \ + B_AX_B0_IMR_ERR_MPDUIF_DATAERR | \ + B_AX_B0_IMR_ERR_PRELD_RLSPKTSZERR | \ + B_AX_B0_IMR_ERR_PRELD_ENTNUMCFG) + #define R_AX_TXPKTCTL_B1_PRELD_CFG0 0x9F88 #define B_AX_B1_PRELD_FEN BIT(31) #define B_AX_B1_PRELD_USEMAXSZ_MASK GENMASK(25, 16) @@ -878,6 +1705,42 @@ #define B_AX_B1_PRELD_NXT_TXENDWIN_MASK GENMASK(11, 8) #define B_AX_B1_PRELD_NXT_RSVMINSZ_MASK GENMASK(7, 0) +#define R_AX_TXPKTCTL_B1_ERRFLAG_IMR 0x9FB8 +#define B_AX_B1_IMR_ERR_PRELD_ENTNUMCFG BIT(21) +#define B_AX_B1_IMR_ERR_PRELD_RLSPKTSZERR BIT(20) +#define B_AX_B1_IMR_ERR_MPDUIF_DATAERR BIT(18) +#define B_AX_B1_IMR_ERR_MPDUINFO_RECFG BIT(16) +#define B_AX_B1_IMR_ERR_CMDPSR_TBLSZ BIT(11) +#define B_AX_B1_IMR_ERR_CMDPSR_FRZTO BIT(10) +#define B_AX_B1_IMR_ERR_CMDPSR_CMDTYPE BIT(9) +#define B_AX_B1_IMR_ERR_CMDPSR_1STCMDERR BIT(8) +#define B_AX_B1_IMR_ERR_USRCTL_RLSBMPLEN BIT(3) +#define B_AX_B1_IMR_ERR_USRCTL_RDNRLSCMD BIT(2) +#define B_AX_B1_IMR_ERR_USRCTL_NOINIT BIT(1) +#define B_AX_B1_IMR_ERR_USRCTL_REINIT BIT(0) +#define B_AX_TXPKTCTL_IMR_B1_CLR_V1 (B_AX_B1_IMR_ERR_USRCTL_REINIT | \ + B_AX_B1_IMR_ERR_USRCTL_NOINIT | \ + B_AX_B1_IMR_ERR_USRCTL_RDNRLSCMD | \ + B_AX_B1_IMR_ERR_USRCTL_RLSBMPLEN | \ + B_AX_B1_IMR_ERR_CMDPSR_1STCMDERR | \ + B_AX_B1_IMR_ERR_CMDPSR_CMDTYPE | \ + B_AX_B1_IMR_ERR_CMDPSR_FRZTO | \ + B_AX_B1_IMR_ERR_CMDPSR_TBLSZ | \ + B_AX_B1_IMR_ERR_MPDUINFO_RECFG | \ + B_AX_B1_IMR_ERR_MPDUIF_DATAERR | \ + B_AX_B1_IMR_ERR_PRELD_RLSPKTSZERR | \ + B_AX_B1_IMR_ERR_PRELD_ENTNUMCFG) +#define B_AX_TXPKTCTL_IMR_B1_SET_V1 (B_AX_B1_IMR_ERR_USRCTL_REINIT | \ + B_AX_B1_IMR_ERR_USRCTL_NOINIT | \ + B_AX_B1_IMR_ERR_CMDPSR_1STCMDERR | \ + B_AX_B1_IMR_ERR_CMDPSR_CMDTYPE | \ + B_AX_B1_IMR_ERR_CMDPSR_FRZTO | \ + B_AX_B1_IMR_ERR_CMDPSR_TBLSZ | \ + B_AX_B1_IMR_ERR_MPDUINFO_RECFG | \ + B_AX_B1_IMR_ERR_MPDUIF_DATAERR | \ + B_AX_B1_IMR_ERR_PRELD_RLSPKTSZERR | \ + B_AX_B1_IMR_ERR_PRELD_ENTNUMCFG) + #define R_AX_AFE_CTRL1 0x0024 #define B_AX_R_SYM_WLCMAC1_P4_PC_EN BIT(4) diff --git a/drivers/net/wireless/realtek/rtw89/rtw8852a.c b/drivers/net/wireless/realtek/rtw89/rtw8852a.c index 501631b1f0416..1af6057487401 100644 --- a/drivers/net/wireless/realtek/rtw89/rtw8852a.c +++ b/drivers/net/wireless/realtek/rtw89/rtw8852a.c @@ -408,6 +408,34 @@ static const struct rtw89_reg_def rtw8852a_dcfo_comp = { R_DCFO_COMP_S0, B_DCFO_COMP_S0_MSK }; +static const struct rtw89_imr_info rtw8852a_imr_info = { + .wdrls_imr_set = B_AX_WDRLS_IMR_SET, + .wsec_imr_reg = R_AX_SEC_DEBUG, + .wsec_imr_set = B_AX_IMR_ERROR, + .mpdu_tx_imr_set = 0, + .mpdu_rx_imr_set = 0, + .sta_sch_imr_set = B_AX_STA_SCHEDULER_IMR_SET, + .txpktctl_imr_b0_reg = R_AX_TXPKTCTL_ERR_IMR_ISR, + .txpktctl_imr_b0_clr = B_AX_TXPKTCTL_IMR_B0_CLR, + .txpktctl_imr_b0_set = B_AX_TXPKTCTL_IMR_B0_SET, + .txpktctl_imr_b1_reg = R_AX_TXPKTCTL_ERR_IMR_ISR_B1, + .txpktctl_imr_b1_clr = B_AX_TXPKTCTL_IMR_B1_CLR, + .txpktctl_imr_b1_set = B_AX_TXPKTCTL_IMR_B1_SET, + .wde_imr_clr = B_AX_WDE_IMR_CLR, + .wde_imr_set = B_AX_WDE_IMR_SET, + .ple_imr_clr = B_AX_PLE_IMR_CLR, + .ple_imr_set = B_AX_PLE_IMR_SET, + .host_disp_imr_clr = B_AX_HOST_DISP_IMR_CLR, + .host_disp_imr_set = B_AX_HOST_DISP_IMR_SET, + .cpu_disp_imr_clr = B_AX_CPU_DISP_IMR_CLR, + .cpu_disp_imr_set = B_AX_CPU_DISP_IMR_SET, + .other_disp_imr_clr = B_AX_OTHER_DISP_IMR_CLR, + .other_disp_imr_set = 0, + .bbrpt_chinfo_err_imr_reg = R_AX_BBRPT_CHINFO_ERR_IMR_ISR, + .bbrpt_err_imr_set = 0, + .bbrpt_dfs_err_imr_reg = R_AX_BBRPT_DFS_ERR_IMR_ISR, +}; + static void rtw8852ae_efuse_parsing(struct rtw89_efuse *efuse, struct rtw8852a_efuse *map) { @@ -2112,6 +2140,7 @@ const struct rtw89_chip_info rtw8852a_chip_info = { .page_regs = &rtw8852a_page_regs, .dcfo_comp = &rtw8852a_dcfo_comp, .dcfo_comp_sft = 3, + .imr_info = &rtw8852a_imr_info }; EXPORT_SYMBOL(rtw8852a_chip_info); diff --git a/drivers/net/wireless/realtek/rtw89/rtw8852c.c b/drivers/net/wireless/realtek/rtw89/rtw8852c.c index 5dbb711defc40..18c17b4bbc181 100644 --- a/drivers/net/wireless/realtek/rtw89/rtw8852c.c +++ b/drivers/net/wireless/realtek/rtw89/rtw8852c.c @@ -51,6 +51,34 @@ static const struct rtw89_reg_def rtw8852c_dcfo_comp = { R_DCFO_COMP_S0_V1, B_DCFO_COMP_S0_V1_MSK }; +static const struct rtw89_imr_info rtw8852c_imr_info = { + .wdrls_imr_set = B_AX_WDRLS_IMR_SET_V1, + .wsec_imr_reg = R_AX_SEC_ERROR_FLAG_IMR, + .wsec_imr_set = B_AX_TX_HANG_IMR | B_AX_RX_HANG_IMR, + .mpdu_tx_imr_set = B_AX_MPDU_TX_IMR_SET_V1, + .mpdu_rx_imr_set = B_AX_MPDU_RX_IMR_SET_V1, + .sta_sch_imr_set = B_AX_STA_SCHEDULER_IMR_SET, + .txpktctl_imr_b0_reg = R_AX_TXPKTCTL_B0_ERRFLAG_IMR, + .txpktctl_imr_b0_clr = B_AX_TXPKTCTL_IMR_B0_CLR_V1, + .txpktctl_imr_b0_set = B_AX_TXPKTCTL_IMR_B0_SET_V1, + .txpktctl_imr_b1_reg = R_AX_TXPKTCTL_B1_ERRFLAG_IMR, + .txpktctl_imr_b1_clr = B_AX_TXPKTCTL_IMR_B1_CLR_V1, + .txpktctl_imr_b1_set = B_AX_TXPKTCTL_IMR_B1_SET_V1, + .wde_imr_clr = B_AX_WDE_IMR_CLR_V1, + .wde_imr_set = B_AX_WDE_IMR_SET_V1, + .ple_imr_clr = B_AX_PLE_IMR_CLR_V1, + .ple_imr_set = B_AX_PLE_IMR_SET_V1, + .host_disp_imr_clr = B_AX_HOST_DISP_IMR_CLR_V1, + .host_disp_imr_set = B_AX_HOST_DISP_IMR_SET_V1, + .cpu_disp_imr_clr = B_AX_CPU_DISP_IMR_CLR_V1, + .cpu_disp_imr_set = B_AX_CPU_DISP_IMR_SET_V1, + .other_disp_imr_clr = B_AX_OTHER_DISP_IMR_CLR_V1, + .other_disp_imr_set = B_AX_OTHER_DISP_IMR_SET_V1, + .bbrpt_chinfo_err_imr_reg = R_AX_BBRPT_CHINFO_ERR_IMR, + .bbrpt_err_imr_set = R_AX_BBRPT_CHINFO_IMR_SET_V1, + .bbrpt_dfs_err_imr_reg = R_AX_BBRPT_DFS_ERR_IMR, +}; + static int rtw8852c_pwr_on_func(struct rtw89_dev *rtwdev) { u32 val32; @@ -572,6 +600,7 @@ const struct rtw89_chip_info rtw8852c_chip_info = { .page_regs = &rtw8852c_page_regs, .dcfo_comp = &rtw8852c_dcfo_comp, .dcfo_comp_sft = 5, + .imr_info = &rtw8852c_imr_info }; EXPORT_SYMBOL(rtw8852c_chip_info); From d86369e937f1ca4f87b9375d055c3ef9a6aa5360 Mon Sep 17 00:00:00 2001 From: Chia-Yuan Li Date: Fri, 8 Apr 2022 08:13:43 +0800 Subject: [PATCH 116/228] rtw89: ser: configure C-MAC interrupt mask Similarly, create functions to set specific C-MAC masks for firmware recovery. Signed-off-by: Chia-Yuan Li Signed-off-by: Ping-Ke Shih Signed-off-by: Kalle Valo Link: https://lore.kernel.org/r/20220408001353.17188-4-pkshih@realtek.com --- drivers/net/wireless/realtek/rtw89/core.h | 17 + drivers/net/wireless/realtek/rtw89/mac.c | 108 +++++-- drivers/net/wireless/realtek/rtw89/reg.h | 300 +++++++++++++++++- drivers/net/wireless/realtek/rtw89/rtw8852a.c | 17 + drivers/net/wireless/realtek/rtw89/rtw8852c.c | 17 + 5 files changed, 423 insertions(+), 36 deletions(-) diff --git a/drivers/net/wireless/realtek/rtw89/core.h b/drivers/net/wireless/realtek/rtw89/core.h index 63aa88b705bc2..a6c075ac67d5d 100644 --- a/drivers/net/wireless/realtek/rtw89/core.h +++ b/drivers/net/wireless/realtek/rtw89/core.h @@ -2319,6 +2319,23 @@ struct rtw89_imr_info { u32 bbrpt_chinfo_err_imr_reg; u32 bbrpt_err_imr_set; u32 bbrpt_dfs_err_imr_reg; + u32 ptcl_imr_clr; + u32 ptcl_imr_set; + u32 cdma_imr_0_reg; + u32 cdma_imr_0_clr; + u32 cdma_imr_0_set; + u32 cdma_imr_1_reg; + u32 cdma_imr_1_clr; + u32 cdma_imr_1_set; + u32 phy_intf_imr_reg; + u32 phy_intf_imr_clr; + u32 phy_intf_imr_set; + u32 rmac_imr_reg; + u32 rmac_imr_clr; + u32 rmac_imr_set; + u32 tmac_imr_reg; + u32 tmac_imr_clr; + u32 tmac_imr_set; }; struct rtw89_chip_info { diff --git a/drivers/net/wireless/realtek/rtw89/mac.c b/drivers/net/wireless/realtek/rtw89/mac.c index 77fb9b74019e4..c10eca44dbe9d 100644 --- a/drivers/net/wireless/realtek/rtw89/mac.c +++ b/drivers/net/wireless/realtek/rtw89/mac.c @@ -2737,10 +2737,76 @@ static void rtw89_bbrpt_imr_enable(struct rtw89_dev *rtwdev) rtw89_write32_set(rtwdev, R_AX_LA_ERRFLAG, B_AX_LA_IMR_DATA_LOSS_ERR); } +static void rtw89_scheduler_imr_enable(struct rtw89_dev *rtwdev, u8 mac_idx) +{ + u32 reg; + + reg = rtw89_mac_reg_by_idx(R_AX_SCHEDULE_ERR_IMR, mac_idx); + rtw89_write32_clr(rtwdev, reg, B_AX_SORT_NON_IDLE_ERR_INT_EN | + B_AX_FSM_TIMEOUT_ERR_INT_EN); + rtw89_write32_set(rtwdev, reg, B_AX_FSM_TIMEOUT_ERR_INT_EN); +} + +static void rtw89_ptcl_imr_enable(struct rtw89_dev *rtwdev, u8 mac_idx) +{ + const struct rtw89_imr_info *imr = rtwdev->chip->imr_info; + u32 reg; + + reg = rtw89_mac_reg_by_idx(R_AX_PTCL_IMR0, mac_idx); + rtw89_write32_clr(rtwdev, reg, imr->ptcl_imr_clr); + rtw89_write32_set(rtwdev, reg, imr->ptcl_imr_set); +} + +static void rtw89_cdma_imr_enable(struct rtw89_dev *rtwdev, u8 mac_idx) +{ + const struct rtw89_imr_info *imr = rtwdev->chip->imr_info; + enum rtw89_core_chip_id chip_id = rtwdev->chip->chip_id; + u32 reg; + + reg = rtw89_mac_reg_by_idx(imr->cdma_imr_0_reg, mac_idx); + rtw89_write32_clr(rtwdev, reg, imr->cdma_imr_0_clr); + rtw89_write32_set(rtwdev, reg, imr->cdma_imr_0_set); + + if (chip_id == RTL8852C) { + reg = rtw89_mac_reg_by_idx(imr->cdma_imr_1_reg, mac_idx); + rtw89_write32_clr(rtwdev, reg, imr->cdma_imr_1_clr); + rtw89_write32_set(rtwdev, reg, imr->cdma_imr_1_set); + } +} + +static void rtw89_phy_intf_imr_enable(struct rtw89_dev *rtwdev, u8 mac_idx) +{ + const struct rtw89_imr_info *imr = rtwdev->chip->imr_info; + u32 reg; + + reg = rtw89_mac_reg_by_idx(imr->phy_intf_imr_reg, mac_idx); + rtw89_write32_clr(rtwdev, reg, imr->phy_intf_imr_clr); + rtw89_write32_set(rtwdev, reg, imr->phy_intf_imr_set); +} + +static void rtw89_rmac_imr_enable(struct rtw89_dev *rtwdev, u8 mac_idx) +{ + const struct rtw89_imr_info *imr = rtwdev->chip->imr_info; + u32 reg; + + reg = rtw89_mac_reg_by_idx(imr->rmac_imr_reg, mac_idx); + rtw89_write32_clr(rtwdev, reg, imr->rmac_imr_clr); + rtw89_write32_set(rtwdev, reg, imr->rmac_imr_set); +} + +static void rtw89_tmac_imr_enable(struct rtw89_dev *rtwdev, u8 mac_idx) +{ + const struct rtw89_imr_info *imr = rtwdev->chip->imr_info; + u32 reg; + + reg = rtw89_mac_reg_by_idx(imr->tmac_imr_reg, mac_idx); + rtw89_write32_clr(rtwdev, reg, imr->tmac_imr_clr); + rtw89_write32_set(rtwdev, reg, imr->tmac_imr_set); +} + static int rtw89_mac_enable_imr(struct rtw89_dev *rtwdev, u8 mac_idx, enum rtw89_mac_hwmod_sel sel) { - u32 reg, val; int ret; ret = rtw89_mac_check_mac_en(rtwdev, mac_idx, sel); @@ -2763,40 +2829,12 @@ static int rtw89_mac_enable_imr(struct rtw89_dev *rtwdev, u8 mac_idx, rtw89_cpuio_imr_enable(rtwdev); rtw89_bbrpt_imr_enable(rtwdev); } else if (sel == RTW89_CMAC_SEL) { - reg = rtw89_mac_reg_by_idx(R_AX_SCHEDULE_ERR_IMR, mac_idx); - rtw89_write32_clr(rtwdev, reg, - B_AX_SORT_NON_IDLE_ERR_INT_EN); - - reg = rtw89_mac_reg_by_idx(R_AX_DLE_CTRL, mac_idx); - rtw89_write32_clr(rtwdev, reg, - B_AX_NO_RESERVE_PAGE_ERR_IMR | - B_AX_RXDATA_FSM_HANG_ERROR_IMR); - - reg = rtw89_mac_reg_by_idx(R_AX_PTCL_IMR0, mac_idx); - val = B_AX_F2PCMD_USER_ALLC_ERR_INT_EN | - B_AX_TX_RECORD_PKTID_ERR_INT_EN | - B_AX_FSM_TIMEOUT_ERR_INT_EN; - rtw89_write32(rtwdev, reg, val); - - reg = rtw89_mac_reg_by_idx(R_AX_PHYINFO_ERR_IMR, mac_idx); - rtw89_write32_set(rtwdev, reg, - B_AX_PHY_TXON_TIMEOUT_INT_EN | - B_AX_CCK_CCA_TIMEOUT_INT_EN | - B_AX_OFDM_CCA_TIMEOUT_INT_EN | - B_AX_DATA_ON_TIMEOUT_INT_EN | - B_AX_STS_ON_TIMEOUT_INT_EN | - B_AX_CSI_ON_TIMEOUT_INT_EN); - - reg = rtw89_mac_reg_by_idx(R_AX_RMAC_ERR_ISR, mac_idx); - val = rtw89_read32(rtwdev, reg); - val |= (B_AX_RMAC_RX_CSI_TIMEOUT_INT_EN | - B_AX_RMAC_RX_TIMEOUT_INT_EN | - B_AX_RMAC_CSI_TIMEOUT_INT_EN); - val &= ~(B_AX_RMAC_CCA_TO_IDLE_TIMEOUT_INT_EN | - B_AX_RMAC_DATA_ON_TO_IDLE_TIMEOUT_INT_EN | - B_AX_RMAC_CCA_TIMEOUT_INT_EN | - B_AX_RMAC_DATA_ON_TIMEOUT_INT_EN); - rtw89_write32(rtwdev, reg, val); + rtw89_scheduler_imr_enable(rtwdev, mac_idx); + rtw89_ptcl_imr_enable(rtwdev, mac_idx); + rtw89_cdma_imr_enable(rtwdev, mac_idx); + rtw89_phy_intf_imr_enable(rtwdev, mac_idx); + rtw89_rmac_imr_enable(rtwdev, mac_idx); + rtw89_tmac_imr_enable(rtwdev, mac_idx); } else { return -EINVAL; } diff --git a/drivers/net/wireless/realtek/rtw89/reg.h b/drivers/net/wireless/realtek/rtw89/reg.h index 9e445bf9b9d49..3d66d3579af4e 100644 --- a/drivers/net/wireless/realtek/rtw89/reg.h +++ b/drivers/net/wireless/realtek/rtw89/reg.h @@ -1932,7 +1932,6 @@ #define R_AX_SCHEDULE_ERR_IMR 0xC3E8 #define R_AX_SCHEDULE_ERR_IMR_C1 0xE3E8 #define B_AX_SORT_NON_IDLE_ERR_INT_EN BIT(1) -#define B_AX_FSM_TIMEOUT_ERR_INT_EN BIT(0) #define R_AX_SCHEDULE_ERR_ISR 0xC3EC #define R_AX_SCHEDULE_ERR_ISR_C1 0xE3EC @@ -2206,8 +2205,48 @@ #define R_AX_PTCL_IMR0 0xC6C0 #define R_AX_PTCL_IMR0_C1 0xE6C0 +#define B_AX_F2PCMD_PKTID_ERR_INT_EN BIT(31) +#define B_AX_F2PCMD_RD_PKTID_ERR_INT_EN BIT(30) +#define B_AX_F2PCMD_ASSIGN_PKTID_ERR_INT_EN BIT(29) #define B_AX_F2PCMD_USER_ALLC_ERR_INT_EN BIT(28) +#define B_AX_RX_SPF_U0_PKTID_ERR_INT_EN BIT(27) +#define B_AX_TX_SPF_U1_PKTID_ERR_INT_EN BIT(26) +#define B_AX_TX_SPF_U2_PKTID_ERR_INT_EN BIT(25) +#define B_AX_TX_SPF_U3_PKTID_ERR_INT_EN BIT(24) #define B_AX_TX_RECORD_PKTID_ERR_INT_EN BIT(23) +#define B_AX_F2PCMD_EMPTY_ERR_INT_EN BIT(15) +#define B_AX_TWTSP_QSEL_ERR_INT_EN BIT(14) +#define B_AX_BCNQ_ORDER_ERR_INT_EN BIT(12) +#define B_AX_Q_PKTID_ERR_INT_EN BIT(11) +#define B_AX_D_PKTID_ERR_INT_EN BIT(10) +#define B_AX_TXPRT_FULL_DROP_ERR_INT_EN BIT(9) +#define B_AX_F2PCMDRPT_FULL_DROP_ERR_INT_EN BIT(8) +#define B_AX_FSM1_TIMEOUT_ERR_INT_EN BIT(1) +#define B_AX_FSM_TIMEOUT_ERR_INT_EN BIT(0) +#define B_AX_PTCL_IMR_CLR (B_AX_FSM_TIMEOUT_ERR_INT_EN | \ + B_AX_F2PCMDRPT_FULL_DROP_ERR_INT_EN | \ + B_AX_TXPRT_FULL_DROP_ERR_INT_EN | \ + B_AX_D_PKTID_ERR_INT_EN | \ + B_AX_Q_PKTID_ERR_INT_EN | \ + B_AX_BCNQ_ORDER_ERR_INT_EN | \ + B_AX_TWTSP_QSEL_ERR_INT_EN | \ + B_AX_F2PCMD_EMPTY_ERR_INT_EN | \ + B_AX_TX_RECORD_PKTID_ERR_INT_EN | \ + B_AX_TX_SPF_U3_PKTID_ERR_INT_EN | \ + B_AX_TX_SPF_U2_PKTID_ERR_INT_EN | \ + B_AX_TX_SPF_U1_PKTID_ERR_INT_EN | \ + B_AX_RX_SPF_U0_PKTID_ERR_INT_EN | \ + B_AX_F2PCMD_USER_ALLC_ERR_INT_EN | \ + B_AX_F2PCMD_ASSIGN_PKTID_ERR_INT_EN | \ + B_AX_F2PCMD_RD_PKTID_ERR_INT_EN | \ + B_AX_F2PCMD_PKTID_ERR_INT_EN) +#define B_AX_PTCL_IMR_SET (B_AX_FSM_TIMEOUT_ERR_INT_EN | \ + B_AX_TX_RECORD_PKTID_ERR_INT_EN | \ + B_AX_F2PCMD_USER_ALLC_ERR_INT_EN) +#define B_AX_PTCL_IMR_CLR_V1 (B_AX_FSM1_TIMEOUT_ERR_INT_EN | \ + B_AX_FSM_TIMEOUT_ERR_INT_EN) +#define B_AX_PTCL_IMR_SET_V1 (B_AX_FSM1_TIMEOUT_ERR_INT_EN | \ + B_AX_FSM_TIMEOUT_ERR_INT_EN) #define R_AX_PTCL_ISR0 0xC6C4 #define R_AX_PTCL_ISR0_C1 0xE6C4 @@ -2234,10 +2273,142 @@ #define R_AX_DLE_CTRL_C1 0xE800 #define B_AX_NO_RESERVE_PAGE_ERR_IMR BIT(23) #define B_AX_RXDATA_FSM_HANG_ERROR_IMR BIT(15) +#define B_AX_RXSTS_FSM_HANG_ERROR_IMR BIT(14) +#define B_AX_DLE_IMR_CLR (B_AX_RXSTS_FSM_HANG_ERROR_IMR | \ + B_AX_RXDATA_FSM_HANG_ERROR_IMR | \ + B_AX_NO_RESERVE_PAGE_ERR_IMR) +#define B_AX_DLE_IMR_SET (B_AX_RXSTS_FSM_HANG_ERROR_IMR | \ + B_AX_RXDATA_FSM_HANG_ERROR_IMR) + #define R_AX_RXDMA_PKT_INFO_0 0xC814 #define R_AX_RXDMA_PKT_INFO_1 0xC818 #define R_AX_RXDMA_PKT_INFO_2 0xC81C +#define R_AX_RX_ERR_FLAG_IMR 0xC804 +#define R_AX_RX_ERR_FLAG_IMR_C1 0xE804 +#define B_AX_RX_GET_NULL_PKT_ERR_MSK BIT(30) +#define B_AX_RX_RU0_FSM_HANG_MSK_ERR_MSK BIT(29) +#define B_AX_RX_RU1_FSM_HANG_MSK_ERR_MSK BIT(28) +#define B_AX_RX_RU2_FSM_HANG_MSK_ERR_MSK BIT(27) +#define B_AX_RX_RU3_FSM_HANG_MSK_ERR_MSK BIT(26) +#define B_AX_RX_RU4_FSM_HANG_MSK_ERR_MSK BIT(25) +#define B_AX_RX_RU5_FSM_HANG_MSK_ERR_MSK BIT(24) +#define B_AX_RX_RU6_FSM_HANG_MSK_ERR_MSK BIT(23) +#define B_AX_RX_RU7_FSM_HANG_MSK_ERR_MSK BIT(22) +#define B_AX_RX_RXSTS_FSM_HANG_MSK_ERR_MSK BIT(21) +#define B_AX_RX_CSI_FSM_HANG_MSK_ERR_MSK BIT(20) +#define B_AX_RX_TXRPT_FSM_HANG_MSK_ERR_MSK BIT(19) +#define B_AX_RX_F2PCMD_FSM_HANG_MSK_ERR_MSK BIT(18) +#define B_AX_RX_RU0_ZERO_LEN_ERR_MSK BIT(17) +#define B_AX_RX_RU1_ZERO_LEN_ERR_MSK BIT(16) +#define B_AX_RX_RU2_ZERO_LEN_ERR_MSK BIT(15) +#define B_AX_RX_RU3_ZERO_LEN_ERR_MSK BIT(14) +#define B_AX_RX_RU4_ZERO_LEN_ERR_MSK BIT(13) +#define B_AX_RX_RU5_ZERO_LEN_ERR_MSK BIT(12) +#define B_AX_RX_RU6_ZERO_LEN_ERR_MSK BIT(11) +#define B_AX_RX_RU7_ZERO_LEN_ERR_MSK BIT(10) +#define B_AX_RX_RXSTS_ZERO_LEN_ERR_MSK BIT(9) +#define B_AX_RX_CSI_ZERO_LEN_ERR_MSK BIT(8) +#define B_AX_PLE_DATA_OPT_FSM_HANG_MSK BIT(7) +#define B_AX_PLE_RXDATA_REQ_BUF_FSM_HANG_MSK BIT(6) +#define B_AX_PLE_TXRPT_REQ_BUF_FSM_HANG_MSK BIT(5) +#define B_AX_PLE_WD_OPT_FSM_HANG_MSK BIT(4) +#define B_AX_PLE_ENQ_FSM_HANG_MSK BIT(3) +#define B_AX_RXDATA_ENQUE_ORDER_ERR_MSK BIT(2) +#define B_AX_RXSTS_ENQUE_ORDER_ERR_MSK BIT(1) +#define B_AX_RX_CSI_PKT_NUM_ERR_MSK BIT(0) +#define B_AX_RX_ERR_IMR_CLR_V1 (B_AX_RXSTS_ENQUE_ORDER_ERR_MSK | \ + B_AX_RXDATA_ENQUE_ORDER_ERR_MSK | \ + B_AX_RX_CSI_ZERO_LEN_ERR_MSK | \ + B_AX_RX_RXSTS_ZERO_LEN_ERR_MSK | \ + B_AX_RX_RU7_ZERO_LEN_ERR_MSK | \ + B_AX_RX_RU6_ZERO_LEN_ERR_MSK | \ + B_AX_RX_RU5_ZERO_LEN_ERR_MSK | \ + B_AX_RX_RU4_ZERO_LEN_ERR_MSK | \ + B_AX_RX_RU3_ZERO_LEN_ERR_MSK | \ + B_AX_RX_RU2_ZERO_LEN_ERR_MSK | \ + B_AX_RX_RU1_ZERO_LEN_ERR_MSK | \ + B_AX_RX_RU0_ZERO_LEN_ERR_MSK | \ + B_AX_RX_F2PCMD_FSM_HANG_MSK_ERR_MSK | \ + B_AX_RX_TXRPT_FSM_HANG_MSK_ERR_MSK | \ + B_AX_RX_CSI_FSM_HANG_MSK_ERR_MSK | \ + B_AX_RX_RXSTS_FSM_HANG_MSK_ERR_MSK | \ + B_AX_RX_RU7_FSM_HANG_MSK_ERR_MSK | \ + B_AX_RX_RU6_FSM_HANG_MSK_ERR_MSK | \ + B_AX_RX_RU5_FSM_HANG_MSK_ERR_MSK | \ + B_AX_RX_RU4_FSM_HANG_MSK_ERR_MSK | \ + B_AX_RX_RU3_FSM_HANG_MSK_ERR_MSK | \ + B_AX_RX_RU2_FSM_HANG_MSK_ERR_MSK | \ + B_AX_RX_RU1_FSM_HANG_MSK_ERR_MSK | \ + B_AX_RX_RU0_FSM_HANG_MSK_ERR_MSK | \ + B_AX_RX_GET_NULL_PKT_ERR_MSK) +#define B_AX_RX_ERR_IMR_SET_V1 (B_AX_RXSTS_ENQUE_ORDER_ERR_MSK | \ + B_AX_RXDATA_ENQUE_ORDER_ERR_MSK | \ + B_AX_RX_CSI_ZERO_LEN_ERR_MSK | \ + B_AX_RX_RXSTS_ZERO_LEN_ERR_MSK | \ + B_AX_RX_RU7_ZERO_LEN_ERR_MSK | \ + B_AX_RX_RU6_ZERO_LEN_ERR_MSK | \ + B_AX_RX_RU5_ZERO_LEN_ERR_MSK | \ + B_AX_RX_RU4_ZERO_LEN_ERR_MSK | \ + B_AX_RX_RU3_ZERO_LEN_ERR_MSK | \ + B_AX_RX_RU2_ZERO_LEN_ERR_MSK | \ + B_AX_RX_RU1_ZERO_LEN_ERR_MSK | \ + B_AX_RX_RU0_ZERO_LEN_ERR_MSK | \ + B_AX_RX_F2PCMD_FSM_HANG_MSK_ERR_MSK | \ + B_AX_RX_TXRPT_FSM_HANG_MSK_ERR_MSK | \ + B_AX_RX_CSI_FSM_HANG_MSK_ERR_MSK | \ + B_AX_RX_RXSTS_FSM_HANG_MSK_ERR_MSK | \ + B_AX_RX_RU7_FSM_HANG_MSK_ERR_MSK | \ + B_AX_RX_RU6_FSM_HANG_MSK_ERR_MSK | \ + B_AX_RX_RU5_FSM_HANG_MSK_ERR_MSK | \ + B_AX_RX_RU4_FSM_HANG_MSK_ERR_MSK | \ + B_AX_RX_RU3_FSM_HANG_MSK_ERR_MSK | \ + B_AX_RX_RU2_FSM_HANG_MSK_ERR_MSK | \ + B_AX_RX_RU1_FSM_HANG_MSK_ERR_MSK | \ + B_AX_RX_RU0_FSM_HANG_MSK_ERR_MSK | \ + B_AX_RX_GET_NULL_PKT_ERR_MSK) + +#define R_AX_TX_ERR_FLAG_IMR 0xC870 +#define R_AX_TX_ERR_FLAG_IMR_C1 0xE870 +#define B_AX_TX_RU0_FSM_HANG_ERR_MSK BIT(31) +#define B_AX_TX_RU1_FSM_HANG_ERR_MSK BIT(30) +#define B_AX_TX_RU2_FSM_HANG_ERR_MSK BIT(29) +#define B_AX_TX_RU3_FSM_HANG_ERR_MSK BIT(28) +#define B_AX_TX_RU4_FSM_HANG_ERR_MSK BIT(27) +#define B_AX_TX_RU5_FSM_HANG_ERR_MSK BIT(26) +#define B_AX_TX_RU6_FSM_HANG_ERR_MSK BIT(25) +#define B_AX_TX_RU7_FSM_HANG_ERR_MSK BIT(24) +#define B_AX_TX_RU8_FSM_HANG_ERR_MSK BIT(23) +#define B_AX_TX_RU9_FSM_HANG_ERR_MSK BIT(22) +#define B_AX_TX_RU10_FSM_HANG_ERR_MSK BIT(21) +#define B_AX_TX_RU11_FSM_HANG_ERR_MSK BIT(20) +#define B_AX_TX_RU12_FSM_HANG_ERR_MSK BIT(19) +#define B_AX_TX_RU13_FSM_HANG_ERR_MSK BIT(18) +#define B_AX_TX_RU14_FSM_HANG_ERR_MSK BIT(17) +#define B_AX_TX_RU15_FSM_HANG_ERR_MSK BIT(16) +#define B_AX_TX_CSI_FSM_HANG_ERR_MSK BIT(15) +#define B_AX_TX_WD_PLD_ID_FSM_HANG_ERR_MSK BIT(14) +#define B_AX_TX_ERR_IMR_CLR_V1 (B_AX_TX_WD_PLD_ID_FSM_HANG_ERR_MSK | \ + B_AX_TX_CSI_FSM_HANG_ERR_MSK | \ + B_AX_TX_RU7_FSM_HANG_ERR_MSK | \ + B_AX_TX_RU6_FSM_HANG_ERR_MSK | \ + B_AX_TX_RU5_FSM_HANG_ERR_MSK | \ + B_AX_TX_RU4_FSM_HANG_ERR_MSK | \ + B_AX_TX_RU3_FSM_HANG_ERR_MSK | \ + B_AX_TX_RU2_FSM_HANG_ERR_MSK | \ + B_AX_TX_RU1_FSM_HANG_ERR_MSK | \ + B_AX_TX_RU0_FSM_HANG_ERR_MSK) +#define B_AX_TX_ERR_IMR_SET_V1 (B_AX_TX_WD_PLD_ID_FSM_HANG_ERR_MSK | \ + B_AX_TX_CSI_FSM_HANG_ERR_MSK | \ + B_AX_TX_RU7_FSM_HANG_ERR_MSK | \ + B_AX_TX_RU6_FSM_HANG_ERR_MSK | \ + B_AX_TX_RU5_FSM_HANG_ERR_MSK | \ + B_AX_TX_RU4_FSM_HANG_ERR_MSK | \ + B_AX_TX_RU3_FSM_HANG_ERR_MSK | \ + B_AX_TX_RU2_FSM_HANG_ERR_MSK | \ + B_AX_TX_RU1_FSM_HANG_ERR_MSK | \ + B_AX_TX_RU0_FSM_HANG_ERR_MSK) + #define R_AX_TCR0 0xCA00 #define R_AX_TCR0_C1 0xEA00 #define B_AX_TCR_ZLD_NUM_MASK GENMASK(31, 24) @@ -2370,6 +2541,38 @@ #define B_AX_RXTRIG_EN BIT(16) #define B_AX_RXTRIG_USERINFO_2_MASK GENMASK(15, 0) +#define R_AX_TRXPTCL_ERROR_INDICA_MASK 0xCCBC +#define R_AX_TRXPTCL_ERROR_INDICA_MASK_C1 0xECBC +#define B_AX_WMAC_MODE BIT(22) +#define B_AX_WMAC_TIMETOUT_THR_MASK GENMASK(21, 16) +#define B_AX_RMAC_FTM BIT(8) +#define B_AX_RMAC_CSI BIT(7) +#define B_AX_TMAC_MIMO_CTRL BIT(6) +#define B_AX_TMAC_RXTB BIT(5) +#define B_AX_TMAC_HWSIGB_GEN BIT(4) +#define B_AX_TMAC_TXPLCP BIT(3) +#define B_AX_TMAC_RESP BIT(2) +#define B_AX_TMAC_TXCTL BIT(1) +#define B_AX_TMAC_MACTX BIT(0) +#define B_AX_TMAC_IMR_CLR_V1 (B_AX_TMAC_MACTX | \ + B_AX_TMAC_TXCTL | \ + B_AX_TMAC_RESP | \ + B_AX_TMAC_TXPLCP | \ + B_AX_TMAC_HWSIGB_GEN | \ + B_AX_TMAC_RXTB | \ + B_AX_TMAC_MIMO_CTRL | \ + B_AX_RMAC_CSI | \ + B_AX_RMAC_FTM) +#define B_AX_TMAC_IMR_SET_V1 (B_AX_TMAC_MACTX | \ + B_AX_TMAC_TXCTL | \ + B_AX_TMAC_RESP | \ + B_AX_TMAC_TXPLCP | \ + B_AX_TMAC_HWSIGB_GEN | \ + B_AX_TMAC_RXTB | \ + B_AX_TMAC_MIMO_CTRL | \ + B_AX_RMAC_CSI | \ + B_AX_RMAC_FTM) + #define R_AX_WMAC_TX_TF_INFO_0 0xCCD0 #define R_AX_WMAC_TX_TF_INFO_0_C1 0xECD0 #define B_AX_WMAC_TX_TF_INFO_SEL_MASK GENMASK(2, 0) @@ -2384,11 +2587,55 @@ #define R_AX_TMAC_ERR_IMR_ISR 0xCCEC #define R_AX_TMAC_ERR_IMR_ISR_C1 0xECEC +#define B_AX_TMAC_TXPLCP_ERR_CLR BIT(19) +#define B_AX_TMAC_RESP_ERR_CLR BIT(18) +#define B_AX_TMAC_TXCTL_ERR_CLR BIT(17) +#define B_AX_TMAC_MACTX_ERR_CLR BIT(16) +#define B_AX_TMAC_TXPLCP_ERR BIT(14) +#define B_AX_TMAC_RESP_ERR BIT(13) +#define B_AX_TMAC_TXCTL_ERR BIT(12) +#define B_AX_TMAC_MACTX_ERR BIT(11) +#define B_AX_TMAC_TXPLCP_INT_EN BIT(10) +#define B_AX_TMAC_RESP_INT_EN BIT(9) +#define B_AX_TMAC_TXCTL_INT_EN BIT(8) +#define B_AX_TMAC_MACTX_INT_EN BIT(7) +#define B_AX_WMAC_INT_MODE BIT(6) +#define B_AX_TMAC_TIMETOUT_THR_MASK GENMASK(5, 0) +#define B_AX_TMAC_IMR_CLR (B_AX_TMAC_MACTX_INT_EN | \ + B_AX_TMAC_TXCTL_INT_EN | \ + B_AX_TMAC_RESP_INT_EN | \ + B_AX_TMAC_TXPLCP_INT_EN) +#define B_AX_TMAC_IMR_SET (B_AX_TMAC_MACTX_INT_EN | \ + B_AX_TMAC_TXCTL_INT_EN | \ + B_AX_TMAC_RESP_INT_EN | \ + B_AX_TMAC_TXPLCP_INT_EN) #define R_AX_DBGSEL_TRXPTCL 0xCCF4 #define R_AX_DBGSEL_TRXPTCL_C1 0xECF4 #define B_AX_DBGSEL_TRXPTCL_MASK GENMASK(7, 0) +#define R_AX_PHYINFO_ERR_IMR_V1 0xCCF8 +#define R_AX_PHYINFO_ERR_IMR_V1_C1 0xECF8 +#define B_AX_PHYINTF_TIMEOUT_THR_MSAK_V1 GENMASK(21, 16) +#define B_AX_CSI_ON_TIMEOUT_EN BIT(5) +#define B_AX_STS_ON_TIMEOUT_EN BIT(4) +#define B_AX_DATA_ON_TIMEOUT_EN BIT(3) +#define B_AX_OFDM_CCA_TIMEOUT_EN BIT(2) +#define B_AX_CCK_CCA_TIMEOUT_EN BIT(1) +#define B_AX_PHY_TXON_TIMEOUT_EN BIT(0) +#define B_AX_PHYINFO_IMR_CLR_V1 (B_AX_PHY_TXON_TIMEOUT_EN | \ + B_AX_CCK_CCA_TIMEOUT_EN | \ + B_AX_OFDM_CCA_TIMEOUT_EN | \ + B_AX_DATA_ON_TIMEOUT_EN | \ + B_AX_STS_ON_TIMEOUT_EN | \ + B_AX_CSI_ON_TIMEOUT_EN) +#define B_AX_PHYINFO_IMR_SET_V1 (B_AX_PHY_TXON_TIMEOUT_EN | \ + B_AX_CCK_CCA_TIMEOUT_EN | \ + B_AX_OFDM_CCA_TIMEOUT_EN | \ + B_AX_DATA_ON_TIMEOUT_EN | \ + B_AX_STS_ON_TIMEOUT_EN | \ + B_AX_CSI_ON_TIMEOUT_EN) + #define R_AX_PHYINFO_ERR_IMR 0xCCFC #define R_AX_PHYINFO_ERR_IMR_C1 0xECFC #define B_AX_CSI_ON_TIMEOUT BIT(29) @@ -2404,6 +2651,12 @@ #define B_AX_CCK_CCA_TIMEOUT_INT_EN BIT(17) #define B_AX_PHY_TXON_TIMEOUT_INT_EN BIT(16) #define B_AX_PHYINTF_TIMEOUT_THR_MSAK GENMASK(5, 0) +#define B_AX_PHYINFO_IMR_EN_ALL (B_AX_PHY_TXON_TIMEOUT_INT_EN | \ + B_AX_CCK_CCA_TIMEOUT_INT_EN | \ + B_AX_OFDM_CCA_TIMEOUT_INT_EN | \ + B_AX_DATA_ON_TIMEOUT_INT_EN | \ + B_AX_STS_ON_TIMEOUT_INT_EN | \ + B_AX_CSI_ON_TIMEOUT_INT_EN) #define R_AX_PHYINFO_ERR_ISR 0xCCFC #define R_AX_PHYINFO_ERR_ISR_C1 0xECFC @@ -2579,6 +2832,51 @@ #define B_AX_BMAC_DMA_TIMEOUT_FLAG BIT(2) #define B_AX_BMAC_DATA_ON_TO_IDLE_TIMEOUT_FLAG BIT(1) #define B_AX_BMAC_CCA_TO_IDLE_TIMEOUT_FLAG BIT(0) +#define B_AX_RMAC_IMR_CLR (B_AX_RMAC_CCA_TO_IDLE_TIMEOUT_INT_EN | \ + B_AX_RMAC_DATA_ON_TO_IDLE_TIMEOUT_INT_EN | \ + B_AX_RMAC_DMA_TIMEOUT_INT_EN | \ + B_AX_RMAC_CCA_TIMEOUT_INT_EN | \ + B_AX_RMAC_DATA_ON_TIMEOUT_INT_EN | \ + B_AX_RMAC_CSI_TIMEOUT_INT_EN | \ + B_AX_RMAC_RX_TIMEOUT_INT_EN | \ + B_AX_RMAC_RX_CSI_TIMEOUT_INT_EN) +#define B_AX_RMAC_IMR_SET (B_AX_RMAC_DMA_TIMEOUT_INT_EN | \ + B_AX_RMAC_CSI_TIMEOUT_INT_EN | \ + B_AX_RMAC_RX_TIMEOUT_INT_EN | \ + B_AX_RMAC_RX_CSI_TIMEOUT_INT_EN) + +#define R_AX_RX_ERR_IMR 0xCEF8 +#define R_AX_RX_ERR_IMR_C1 0xEEF8 +#define B_AX_RX_ERR_TRIG_ACT_TO_MSK BIT(9) +#define B_AX_RX_ERR_STS_ACT_TO_MSK BIT(8) +#define B_AX_RX_ERR_CSI_ACT_TO_MSK BIT(7) +#define B_AX_RX_ERR_ACT_TO_MSK BIT(6) +#define B_AX_CSI_DATAON_ASSERT_TO_MSK BIT(5) +#define B_AX_DATAON_ASSERT_TO_MSK BIT(4) +#define B_AX_CCA_ASSERT_TO_MSK BIT(3) +#define B_AX_RX_ERR_DMA_TO_MSK BIT(2) +#define B_AX_RX_ERR_DATA_TO_MSK BIT(1) +#define B_AX_RX_ERR_CCA_TO_MSK BIT(0) +#define B_AX_RMAC_IMR_CLR_V1 (B_AX_RX_ERR_CCA_TO_MSK | \ + B_AX_RX_ERR_DATA_TO_MSK | \ + B_AX_RX_ERR_DMA_TO_MSK | \ + B_AX_CCA_ASSERT_TO_MSK | \ + B_AX_DATAON_ASSERT_TO_MSK | \ + B_AX_CSI_DATAON_ASSERT_TO_MSK | \ + B_AX_RX_ERR_ACT_TO_MSK | \ + B_AX_RX_ERR_CSI_ACT_TO_MSK | \ + B_AX_RX_ERR_STS_ACT_TO_MSK | \ + B_AX_RX_ERR_TRIG_ACT_TO_MSK) +#define B_AX_RMAC_IMR_SET_V1 (B_AX_RX_ERR_CCA_TO_MSK | \ + B_AX_RX_ERR_DATA_TO_MSK | \ + B_AX_RX_ERR_DMA_TO_MSK | \ + B_AX_CCA_ASSERT_TO_MSK | \ + B_AX_DATAON_ASSERT_TO_MSK | \ + B_AX_CSI_DATAON_ASSERT_TO_MSK | \ + B_AX_RX_ERR_ACT_TO_MSK | \ + B_AX_RX_ERR_CSI_ACT_TO_MSK | \ + B_AX_RX_ERR_STS_ACT_TO_MSK | \ + B_AX_RX_ERR_TRIG_ACT_TO_MSK) #define R_AX_RMAC_PLCP_MON 0xCEF8 #define R_AX_RMAC_PLCP_MON_C1 0xEEF8 diff --git a/drivers/net/wireless/realtek/rtw89/rtw8852a.c b/drivers/net/wireless/realtek/rtw89/rtw8852a.c index 1af6057487401..9871ed78e44ca 100644 --- a/drivers/net/wireless/realtek/rtw89/rtw8852a.c +++ b/drivers/net/wireless/realtek/rtw89/rtw8852a.c @@ -434,6 +434,23 @@ static const struct rtw89_imr_info rtw8852a_imr_info = { .bbrpt_chinfo_err_imr_reg = R_AX_BBRPT_CHINFO_ERR_IMR_ISR, .bbrpt_err_imr_set = 0, .bbrpt_dfs_err_imr_reg = R_AX_BBRPT_DFS_ERR_IMR_ISR, + .ptcl_imr_clr = B_AX_PTCL_IMR_CLR, + .ptcl_imr_set = B_AX_PTCL_IMR_SET, + .cdma_imr_0_reg = R_AX_DLE_CTRL, + .cdma_imr_0_clr = B_AX_DLE_IMR_CLR, + .cdma_imr_0_set = B_AX_DLE_IMR_SET, + .cdma_imr_1_reg = 0, + .cdma_imr_1_clr = 0, + .cdma_imr_1_set = 0, + .phy_intf_imr_reg = R_AX_PHYINFO_ERR_IMR, + .phy_intf_imr_clr = 0, + .phy_intf_imr_set = 0, + .rmac_imr_reg = R_AX_RMAC_ERR_ISR, + .rmac_imr_clr = B_AX_RMAC_IMR_CLR, + .rmac_imr_set = B_AX_RMAC_IMR_SET, + .tmac_imr_reg = R_AX_TMAC_ERR_IMR_ISR, + .tmac_imr_clr = B_AX_TMAC_IMR_CLR, + .tmac_imr_set = B_AX_TMAC_IMR_SET, }; static void rtw8852ae_efuse_parsing(struct rtw89_efuse *efuse, diff --git a/drivers/net/wireless/realtek/rtw89/rtw8852c.c b/drivers/net/wireless/realtek/rtw89/rtw8852c.c index 18c17b4bbc181..9689fc5a63723 100644 --- a/drivers/net/wireless/realtek/rtw89/rtw8852c.c +++ b/drivers/net/wireless/realtek/rtw89/rtw8852c.c @@ -77,6 +77,23 @@ static const struct rtw89_imr_info rtw8852c_imr_info = { .bbrpt_chinfo_err_imr_reg = R_AX_BBRPT_CHINFO_ERR_IMR, .bbrpt_err_imr_set = R_AX_BBRPT_CHINFO_IMR_SET_V1, .bbrpt_dfs_err_imr_reg = R_AX_BBRPT_DFS_ERR_IMR, + .ptcl_imr_clr = B_AX_PTCL_IMR_CLR_V1, + .ptcl_imr_set = B_AX_PTCL_IMR_SET_V1, + .cdma_imr_0_reg = R_AX_RX_ERR_FLAG_IMR, + .cdma_imr_0_clr = B_AX_RX_ERR_IMR_CLR_V1, + .cdma_imr_0_set = B_AX_RX_ERR_IMR_SET_V1, + .cdma_imr_1_reg = R_AX_TX_ERR_FLAG_IMR, + .cdma_imr_1_clr = B_AX_TX_ERR_IMR_CLR_V1, + .cdma_imr_1_set = B_AX_TX_ERR_IMR_SET_V1, + .phy_intf_imr_reg = R_AX_PHYINFO_ERR_IMR_V1, + .phy_intf_imr_clr = B_AX_PHYINFO_IMR_CLR_V1, + .phy_intf_imr_set = B_AX_PHYINFO_IMR_SET_V1, + .rmac_imr_reg = R_AX_RX_ERR_IMR, + .rmac_imr_clr = B_AX_RMAC_IMR_CLR_V1, + .rmac_imr_set = B_AX_RMAC_IMR_SET_V1, + .tmac_imr_reg = R_AX_TRXPTCL_ERROR_INDICA_MASK, + .tmac_imr_clr = B_AX_TMAC_IMR_CLR_V1, + .tmac_imr_set = B_AX_TMAC_IMR_SET_V1, }; static int rtw8852c_pwr_on_func(struct rtw89_dev *rtwdev) From 9f405b0162ba92bf8317ce1329aad96fecc89273 Mon Sep 17 00:00:00 2001 From: Ping-Ke Shih Date: Fri, 8 Apr 2022 08:13:44 +0800 Subject: [PATCH 117/228] rtw89: ser: configure top ERR IMR for firmware to recover Turn on ERR IMR, and then firmware can capture interrupts reflecting errors to recover hardware states. Signed-off-by: Ping-Ke Shih Signed-off-by: Kalle Valo Link: https://lore.kernel.org/r/20220408001353.17188-5-pkshih@realtek.com --- drivers/net/wireless/realtek/rtw89/mac.c | 15 ++++++++++++ drivers/net/wireless/realtek/rtw89/reg.h | 29 ++++++++++++++++++++++++ 2 files changed, 44 insertions(+) diff --git a/drivers/net/wireless/realtek/rtw89/mac.c b/drivers/net/wireless/realtek/rtw89/mac.c index c10eca44dbe9d..234635098a135 100644 --- a/drivers/net/wireless/realtek/rtw89/mac.c +++ b/drivers/net/wireless/realtek/rtw89/mac.c @@ -2842,6 +2842,19 @@ static int rtw89_mac_enable_imr(struct rtw89_dev *rtwdev, u8 mac_idx, return 0; } +static void rtw89_mac_err_imr_ctrl(struct rtw89_dev *rtwdev, bool en) +{ + enum rtw89_core_chip_id chip_id = rtwdev->chip->chip_id; + + rtw89_write32(rtwdev, R_AX_DMAC_ERR_IMR, + en ? DMAC_ERR_IMR_EN : DMAC_ERR_IMR_DIS); + rtw89_write32(rtwdev, R_AX_CMAC_ERR_IMR, + en ? CMAC0_ERR_IMR_EN : CMAC0_ERR_IMR_DIS); + if (chip_id != RTL8852B && rtwdev->mac.dle_info.c1_rx_qta) + rtw89_write32(rtwdev, R_AX_CMAC_ERR_IMR_C1, + en ? CMAC1_ERR_IMR_EN : CMAC1_ERR_IMR_DIS); +} + static int rtw89_mac_dbcc_enable(struct rtw89_dev *rtwdev, bool enable) { int ret = 0; @@ -2923,6 +2936,8 @@ static int rtw89_mac_trx_init(struct rtw89_dev *rtwdev) return ret; } + rtw89_mac_err_imr_ctrl(rtwdev, true); + ret = set_host_rpr(rtwdev); if (ret) { rtw89_err(rtwdev, "[ERR] set host rpr %d\n", ret); diff --git a/drivers/net/wireless/realtek/rtw89/reg.h b/drivers/net/wireless/realtek/rtw89/reg.h index 3d66d3579af4e..e5f8374f49ad5 100644 --- a/drivers/net/wireless/realtek/rtw89/reg.h +++ b/drivers/net/wireless/realtek/rtw89/reg.h @@ -504,6 +504,21 @@ #define B_AX_WDE_EMPTY_QUE_CMAC0_MBH BIT(1) #define B_AX_WDE_EMPTY_QUE_CMAC0_ALL_AC BIT(0) +#define R_AX_DMAC_ERR_IMR 0x8520 +#define B_AX_DLE_CPUIO_ERR_INT_EN BIT(10) +#define B_AX_APB_BRIDGE_ERR_INT_EN BIT(9) +#define B_AX_DISPATCH_ERR_INT_EN BIT(8) +#define B_AX_PKTIN_ERR_INT_EN BIT(7) +#define B_AX_PLE_DLE_ERR_INT_EN BIT(6) +#define B_AX_TXPKTCTRL_ERR_INT_EN BIT(5) +#define B_AX_WDE_DLE_ERR_INT_EN BIT(4) +#define B_AX_STA_SCHEDULER_ERR_INT_EN BIT(3) +#define B_AX_MPDU_ERR_INT_EN BIT(2) +#define B_AX_WSEC_ERR_INT_EN BIT(1) +#define B_AX_WDRLS_ERR_INT_EN BIT(0) +#define DMAC_ERR_IMR_EN GENMASK(31, 0) +#define DMAC_ERR_IMR_DIS 0 + #define R_AX_DMAC_ERR_ISR 0x8524 #define B_AX_DLE_CPUIO_ERR_FLAG BIT(10) #define B_AX_APB_BRIDGE_ERR_FLAG BIT(9) @@ -1805,6 +1820,20 @@ #define B_AX_TXSC_40M_MASK GENMASK(7, 4) #define B_AX_TXSC_20M_MASK GENMASK(3, 0) +#define R_AX_CMAC_ERR_IMR 0xC160 +#define R_AX_CMAC_ERR_IMR_C1 0xE160 +#define B_AX_WMAC_TX_ERR_IND_EN BIT(7) +#define B_AX_WMAC_RX_ERR_IND_EN BIT(6) +#define B_AX_TXPWR_CTRL_ERR_IND_EN BIT(5) +#define B_AX_PHYINTF_ERR_IND_EN BIT(4) +#define B_AX_DMA_TOP_ERR_IND_EN BIT(3) +#define B_AX_PTCL_TOP_ERR_IND_EN BIT(1) +#define B_AX_SCHEDULE_TOP_ERR_IND_EN BIT(0) +#define CMAC0_ERR_IMR_EN GENMASK(31, 0) +#define CMAC1_ERR_IMR_EN GENMASK(31, 0) +#define CMAC0_ERR_IMR_DIS 0 +#define CMAC1_ERR_IMR_DIS 0 + #define R_AX_CMAC_ERR_ISR 0xC164 #define R_AX_CMAC_ERR_ISR_C1 0xE164 #define B_AX_WMAC_TX_ERR_IND BIT(7) From 9a1ab283c709a058593f1bf0d69a05a5e8b90f72 Mon Sep 17 00:00:00 2001 From: Ping-Ke Shih Date: Fri, 8 Apr 2022 08:13:45 +0800 Subject: [PATCH 118/228] rtw89: change station scheduler setting for hardware TX mode The bit B_AX_SS_NONEMPTY_SS2FINFO_EN should be clear, because we configure C-MAC as hardware TX/RX mode. Signed-off-by: Ping-Ke Shih Signed-off-by: Kalle Valo Link: https://lore.kernel.org/r/20220408001353.17188-6-pkshih@realtek.com --- drivers/net/wireless/realtek/rtw89/mac.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/net/wireless/realtek/rtw89/mac.c b/drivers/net/wireless/realtek/rtw89/mac.c index 234635098a135..b60b9255e3fa2 100644 --- a/drivers/net/wireless/realtek/rtw89/mac.c +++ b/drivers/net/wireless/realtek/rtw89/mac.c @@ -1593,8 +1593,8 @@ static int sta_sch_init(struct rtw89_dev *rtwdev) return ret; } - rtw89_write32_set(rtwdev, R_AX_SS_CTRL, B_AX_SS_WARM_INIT_FLG | - B_AX_SS_NONEMPTY_SS2FINFO_EN); + rtw89_write32_set(rtwdev, R_AX_SS_CTRL, B_AX_SS_WARM_INIT_FLG); + rtw89_write32_clr(rtwdev, R_AX_SS_CTRL, B_AX_SS_NONEMPTY_SS2FINFO_EN); _patch_ss2f_path(rtwdev); From 181751970107746c1b4e6870b01d74e4ac0f3fb8 Mon Sep 17 00:00:00 2001 From: Ping-Ke Shih Date: Fri, 8 Apr 2022 08:13:46 +0800 Subject: [PATCH 119/228] rtw89: reset BA CAM BA CAM is used to react receiving AMPDU packets, so reset them to be expected initial state. Signed-off-by: Ping-Ke Shih Signed-off-by: Kalle Valo Link: https://lore.kernel.org/r/20220408001353.17188-7-pkshih@realtek.com --- drivers/net/wireless/realtek/rtw89/mac.c | 18 ++++++++++++++++++ drivers/net/wireless/realtek/rtw89/reg.h | 2 ++ 2 files changed, 20 insertions(+) diff --git a/drivers/net/wireless/realtek/rtw89/mac.c b/drivers/net/wireless/realtek/rtw89/mac.c index b60b9255e3fa2..ba8c7d3e176cc 100644 --- a/drivers/net/wireless/realtek/rtw89/mac.c +++ b/drivers/net/wireless/realtek/rtw89/mac.c @@ -1964,6 +1964,21 @@ static int trxptcl_init(struct rtw89_dev *rtwdev, u8 mac_idx) return 0; } +static void rst_bacam(struct rtw89_dev *rtwdev) +{ + u32 val32; + int ret; + + rtw89_write32_mask(rtwdev, R_AX_RESPBA_CAM_CTRL, B_AX_BACAM_RST_MASK, + S_AX_BACAM_RST_ALL); + + ret = read_poll_timeout_atomic(rtw89_read32_mask, val32, val32 == 0, + 1, 1000, false, + rtwdev, R_AX_RESPBA_CAM_CTRL, B_AX_BACAM_RST_MASK); + if (ret) + rtw89_warn(rtwdev, "failed to reset BA CAM\n"); +} + static int rmac_init(struct rtw89_dev *rtwdev, u8 mac_idx) { #define TRXCFG_RMAC_CCA_TO 32 @@ -1978,6 +1993,9 @@ static int rmac_init(struct rtw89_dev *rtwdev, u8 mac_idx) if (ret) return ret; + if (mac_idx == RTW89_MAC_0) + rst_bacam(rtwdev); + reg = rtw89_mac_reg_by_idx(R_AX_RESPBA_CAM_CTRL, mac_idx); rtw89_write8_set(rtwdev, reg, B_AX_SSN_SEL); diff --git a/drivers/net/wireless/realtek/rtw89/reg.h b/drivers/net/wireless/realtek/rtw89/reg.h index e5f8374f49ad5..bc343e756aad7 100644 --- a/drivers/net/wireless/realtek/rtw89/reg.h +++ b/drivers/net/wireless/realtek/rtw89/reg.h @@ -2819,6 +2819,8 @@ #define R_AX_RESPBA_CAM_CTRL 0xCE3C #define R_AX_RESPBA_CAM_CTRL_C1 0xEE3C #define B_AX_SSN_SEL BIT(2) +#define B_AX_BACAM_RST_MASK GENMASK(1, 0) +#define S_AX_BACAM_RST_ALL 2 #define R_AX_PPDU_STAT 0xCE40 #define R_AX_PPDU_STAT_C1 0xEE40 From ec356ffb2917a29c6cb7c0d9030a072eb125c907 Mon Sep 17 00:00:00 2001 From: Chia-Yuan Li Date: Fri, 8 Apr 2022 08:13:47 +0800 Subject: [PATCH 120/228] rtw89: 8852c: disable firmware watchdog if CPU disabled Disable watchdog timer to prevent it timeout suddenly. Signed-off-by: Chia-Yuan Li Signed-off-by: Ping-Ke Shih Signed-off-by: Kalle Valo Link: https://lore.kernel.org/r/20220408001353.17188-8-pkshih@realtek.com --- drivers/net/wireless/realtek/rtw89/mac.c | 37 +++++++++++++++++++++++- drivers/net/wireless/realtek/rtw89/mac.h | 6 ++-- drivers/net/wireless/realtek/rtw89/reg.h | 16 ++++++++++ 3 files changed, 55 insertions(+), 4 deletions(-) diff --git a/drivers/net/wireless/realtek/rtw89/mac.c b/drivers/net/wireless/realtek/rtw89/mac.c index ba8c7d3e176cc..a990fd845c253 100644 --- a/drivers/net/wireless/realtek/rtw89/mac.c +++ b/drivers/net/wireless/realtek/rtw89/mac.c @@ -10,7 +10,7 @@ #include "reg.h" #include "util.h" -const u32 rtw89_mac_mem_base_addrs[RTW89_MAC_MEM_MAX] = { +const u32 rtw89_mac_mem_base_addrs[RTW89_MAC_MEM_NUM] = { [RTW89_MAC_MEM_AXIDMA] = AXIDMA_BASE_ADDR, [RTW89_MAC_MEM_SHARED_BUF] = SHARED_BUF_BASE_ADDR, [RTW89_MAC_MEM_DMAC_TBL] = DMAC_TBL_BASE_ADDR, @@ -28,8 +28,27 @@ const u32 rtw89_mac_mem_base_addrs[RTW89_MAC_MEM_MAX] = { [RTW89_MAC_MEM_TXD_FIFO_1] = TXD_FIFO_1_BASE_ADDR, [RTW89_MAC_MEM_TXDATA_FIFO_0] = TXDATA_FIFO_0_BASE_ADDR, [RTW89_MAC_MEM_TXDATA_FIFO_1] = TXDATA_FIFO_1_BASE_ADDR, + [RTW89_MAC_MEM_CPU_LOCAL] = CPU_LOCAL_BASE_ADDR, }; +static void rtw89_mac_mem_write(struct rtw89_dev *rtwdev, u32 offset, + u32 val, enum rtw89_mac_mem_sel sel) +{ + u32 addr = rtw89_mac_mem_base_addrs[sel] + offset; + + rtw89_write32(rtwdev, R_AX_FILTER_MODEL_ADDR, addr); + rtw89_write32(rtwdev, R_AX_INDIR_ACCESS_ENTRY, val); +} + +static u32 rtw89_mac_mem_read(struct rtw89_dev *rtwdev, u32 offset, + enum rtw89_mac_mem_sel sel) +{ + u32 addr = rtw89_mac_mem_base_addrs[sel] + offset; + + rtw89_write32(rtwdev, R_AX_FILTER_MODEL_ADDR, addr); + return rtw89_read32(rtwdev, R_AX_INDIR_ACCESS_ENTRY); +} + int rtw89_mac_check_mac_en(struct rtw89_dev *rtwdev, u8 mac_idx, enum rtw89_mac_hwmod_sel sel) { @@ -2965,6 +2984,19 @@ static int rtw89_mac_trx_init(struct rtw89_dev *rtwdev) return 0; } +static void rtw89_disable_fw_watchdog(struct rtw89_dev *rtwdev) +{ + u32 val32; + + rtw89_mac_mem_write(rtwdev, R_AX_WDT_CTRL, + WDT_CTRL_ALL_DIS, RTW89_MAC_MEM_CPU_LOCAL); + + val32 = rtw89_mac_mem_read(rtwdev, R_AX_WDT_STATUS, RTW89_MAC_MEM_CPU_LOCAL); + val32 |= B_AX_FS_WDT_INT; + val32 &= ~B_AX_FS_WDT_INT_MSK; + rtw89_mac_mem_write(rtwdev, R_AX_WDT_STATUS, val32, RTW89_MAC_MEM_CPU_LOCAL); +} + static void rtw89_mac_disable_cpu(struct rtw89_dev *rtwdev) { clear_bit(RTW89_FLAG_FW_RDY, rtwdev->flags); @@ -2973,6 +3005,9 @@ static void rtw89_mac_disable_cpu(struct rtw89_dev *rtwdev) rtw89_write32_clr(rtwdev, R_AX_WCPU_FW_CTRL, B_AX_WCPU_FWDL_EN | B_AX_H2C_PATH_RDY | B_AX_FWDL_PATH_RDY); rtw89_write32_clr(rtwdev, R_AX_SYS_CLK_CTRL, B_AX_CPU_CLK_EN); + + rtw89_disable_fw_watchdog(rtwdev); + rtw89_write32_clr(rtwdev, R_AX_PLATFORM_ENABLE, B_AX_PLATFORM_EN); rtw89_write32_set(rtwdev, R_AX_PLATFORM_ENABLE, B_AX_PLATFORM_EN); } diff --git a/drivers/net/wireless/realtek/rtw89/mac.h b/drivers/net/wireless/realtek/rtw89/mac.h index de65d9becb056..31d53de97cfce 100644 --- a/drivers/net/wireless/realtek/rtw89/mac.h +++ b/drivers/net/wireless/realtek/rtw89/mac.h @@ -245,6 +245,7 @@ enum rtw89_mac_dbg_port_sel { #define TXD_FIFO_1_BASE_ADDR 0x188A1080 #define TXDATA_FIFO_0_BASE_ADDR 0x18856000 #define TXDATA_FIFO_1_BASE_ADDR 0x188A1000 +#define CPU_LOCAL_BASE_ADDR 0x18003000 #define CCTL_INFO_SIZE 32 @@ -266,11 +267,10 @@ enum rtw89_mac_mem_sel { RTW89_MAC_MEM_TXD_FIFO_1, RTW89_MAC_MEM_TXDATA_FIFO_0, RTW89_MAC_MEM_TXDATA_FIFO_1, + RTW89_MAC_MEM_CPU_LOCAL, /* keep last */ - RTW89_MAC_MEM_LAST, - RTW89_MAC_MEM_MAX = RTW89_MAC_MEM_LAST, - RTW89_MAC_MEM_INVALID = RTW89_MAC_MEM_LAST, + RTW89_MAC_MEM_NUM, }; extern const u32 rtw89_mac_mem_base_addrs[]; diff --git a/drivers/net/wireless/realtek/rtw89/reg.h b/drivers/net/wireless/realtek/rtw89/reg.h index bc343e756aad7..15d29c226b0c3 100644 --- a/drivers/net/wireless/realtek/rtw89/reg.h +++ b/drivers/net/wireless/realtek/rtw89/reg.h @@ -3773,4 +3773,20 @@ #define B_IQKINF2_FCNT GENMASK(23, 16) #define B_IQKINF2_KCNT GENMASK(15, 8) #define B_IQKINF2_NCTLV GENMAKS(7, 0) + +/* WiFi CPU local domain */ +#define R_AX_WDT_CTRL 0x0040 +#define B_AX_WDT_EN BIT(31) +#define B_AX_WDT_OPT_RESET_PLATFORM_EN BIT(29) +#define B_AX_IO_HANG_IMR BIT(27) +#define B_AX_IO_HANG_CMAC_RDATA_EN BIT(26) +#define B_AX_IO_HANG_DMAC_EN BIT(25) +#define B_AX_WDT_CLR BIT(16) +#define B_AX_WDT_COUNT_MASK GENMASK(15, 0) +#define WDT_CTRL_ALL_DIS 0 + +#define R_AX_WDT_STATUS 0x0044 +#define B_AX_FS_WDT_INT BIT(8) +#define B_AX_FS_WDT_INT_MSK BIT(0) + #endif From d264edb1cc65df8e0054b275f7eaaddb795c1d18 Mon Sep 17 00:00:00 2001 From: Johnson Lin Date: Fri, 8 Apr 2022 08:13:48 +0800 Subject: [PATCH 121/228] rtw89: Skip useless dig gain and igi related settings for 8852C Separated DIG RX gain, IGI configurations from not supportted HW using "support_igi" capability flag. Signed-off-by: Johnson Lin Signed-off-by: Ping-Ke Shih Signed-off-by: Kalle Valo Link: https://lore.kernel.org/r/20220408001353.17188-9-pkshih@realtek.com --- drivers/net/wireless/realtek/rtw89/phy.c | 9 +++++++-- drivers/net/wireless/realtek/rtw89/rtw8852c.c | 1 + 2 files changed, 8 insertions(+), 2 deletions(-) diff --git a/drivers/net/wireless/realtek/rtw89/phy.c b/drivers/net/wireless/realtek/rtw89/phy.c index 994869f720806..eed6dbd0d5dbc 100644 --- a/drivers/net/wireless/realtek/rtw89/phy.c +++ b/drivers/net/wireless/realtek/rtw89/phy.c @@ -2930,6 +2930,9 @@ static void rtw89_phy_dig_update_gain_para(struct rtw89_dev *rtwdev) 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); dig->ib_pkpwr = sign_extend32(tmp >> DIG_GAIN_SHIFT, U8_MAX_BIT); @@ -3184,6 +3187,9 @@ static void rtw89_phy_dig_config_igi(struct rtw89_dev *rtwdev) { struct rtw89_dig_info *dig = &rtwdev->dig; + if (!rtwdev->hal.support_igi) + return; + if (dig->force_gaincode_idx_en) { rtw89_phy_dig_set_igi_cr(rtwdev, dig->force_gaincode); rtw89_debug(rtwdev, RTW89_DBG_DIG, @@ -3309,8 +3315,7 @@ void rtw89_phy_dig(struct rtw89_dev *rtwdev) dig->igi_rssi, dig->dyn_igi_max, dig->dyn_igi_min, dig->igi_fa_rssi); - if (rtwdev->hal.support_igi) - rtw89_phy_dig_config_igi(rtwdev); + rtw89_phy_dig_config_igi(rtwdev); rtw89_phy_dig_dyn_pd_th(rtwdev, dig->igi_fa_rssi, dig->dyn_pd_th_en); diff --git a/drivers/net/wireless/realtek/rtw89/rtw8852c.c b/drivers/net/wireless/realtek/rtw89/rtw8852c.c index 9689fc5a63723..ca254339ea7a9 100644 --- a/drivers/net/wireless/realtek/rtw89/rtw8852c.c +++ b/drivers/net/wireless/realtek/rtw89/rtw8852c.c @@ -598,6 +598,7 @@ const struct rtw89_chip_info rtw8852c_chip_info = { .rf_base_addr = {0xe000, 0xf000}, .pwr_on_seq = NULL, .pwr_off_seq = NULL, + .dig_table = NULL, .hw_sec_hdr = true, .sec_ctrl_efuse_size = 4, .physical_efuse_size = 1216, From 065cf8f9777f28fcf1115a7e3a6cdc93ed2d30d1 Mon Sep 17 00:00:00 2001 From: Chia-Yuan Li Date: Fri, 8 Apr 2022 08:13:49 +0800 Subject: [PATCH 122/228] rtw89: 8852c: add 8852c specific BT-coexistence initial function Initialize registers to default values, such as PTA and GNT pin, and set pin MUX according to number of antenna on hardware module. Signed-off-by: Chia-Yuan Li Signed-off-by: Ping-Ke Shih Signed-off-by: Kalle Valo Link: https://lore.kernel.org/r/20220408001353.17188-10-pkshih@realtek.com --- drivers/net/wireless/realtek/rtw89/mac.c | 28 +++++++++ drivers/net/wireless/realtek/rtw89/mac.h | 2 + drivers/net/wireless/realtek/rtw89/reg.h | 33 +++++++++++ drivers/net/wireless/realtek/rtw89/rtw8852c.c | 59 +++++++++++++++++++ 4 files changed, 122 insertions(+) diff --git a/drivers/net/wireless/realtek/rtw89/mac.c b/drivers/net/wireless/realtek/rtw89/mac.c index a990fd845c253..127d5d74c426b 100644 --- a/drivers/net/wireless/realtek/rtw89/mac.c +++ b/drivers/net/wireless/realtek/rtw89/mac.c @@ -3973,6 +3973,34 @@ int rtw89_mac_coex_init(struct rtw89_dev *rtwdev, const struct rtw89_mac_ax_coex } EXPORT_SYMBOL(rtw89_mac_coex_init); +int rtw89_mac_coex_init_v1(struct rtw89_dev *rtwdev, + const struct rtw89_mac_ax_coex *coex) +{ + rtw89_write32_set(rtwdev, R_AX_BTC_CFG, + B_AX_BTC_EN | B_AX_BTG_LNA1_GAIN_SEL); + rtw89_write32_set(rtwdev, R_AX_BT_CNT_CFG, B_AX_BT_CNT_EN); + rtw89_write16_set(rtwdev, R_AX_CCA_CFG_0, B_AX_BTCCA_EN); + rtw89_write16_clr(rtwdev, R_AX_CCA_CFG_0, B_AX_BTCCA_BRK_TXOP_EN); + + switch (coex->pta_mode) { + case RTW89_MAC_AX_COEX_RTK_MODE: + rtw89_write32_mask(rtwdev, R_AX_BTC_CFG, B_AX_BTC_MODE_MASK, + MAC_AX_RTK_MODE); + rtw89_write32_mask(rtwdev, R_AX_RTK_MODE_CFG_V1, + B_AX_SAMPLE_CLK_MASK, MAC_AX_RTK_RATE); + break; + case RTW89_MAC_AX_COEX_CSR_MODE: + rtw89_write32_mask(rtwdev, R_AX_BTC_CFG, B_AX_BTC_MODE_MASK, + MAC_AX_CSR_MODE); + break; + default: + return -EINVAL; + } + + return 0; +} +EXPORT_SYMBOL(rtw89_mac_coex_init_v1); + int rtw89_mac_cfg_gnt(struct rtw89_dev *rtwdev, const struct rtw89_mac_ax_coex_gnt *gnt_cfg) { diff --git a/drivers/net/wireless/realtek/rtw89/mac.h b/drivers/net/wireless/realtek/rtw89/mac.h index 31d53de97cfce..9eb4afe348b30 100644 --- a/drivers/net/wireless/realtek/rtw89/mac.h +++ b/drivers/net/wireless/realtek/rtw89/mac.h @@ -829,6 +829,8 @@ int rtw89_mac_cfg_ppdu_status(struct rtw89_dev *rtwdev, u8 mac_ids, bool enable) void rtw89_mac_update_rts_threshold(struct rtw89_dev *rtwdev, u8 mac_idx); void rtw89_mac_flush_txq(struct rtw89_dev *rtwdev, u32 queues, bool drop); int rtw89_mac_coex_init(struct rtw89_dev *rtwdev, const struct rtw89_mac_ax_coex *coex); +int rtw89_mac_coex_init_v1(struct rtw89_dev *rtwdev, + const struct rtw89_mac_ax_coex *coex); int rtw89_mac_cfg_gnt(struct rtw89_dev *rtwdev, const struct rtw89_mac_ax_coex_gnt *gnt_cfg); int rtw89_mac_cfg_gnt_v1(struct rtw89_dev *rtwdev, diff --git a/drivers/net/wireless/realtek/rtw89/reg.h b/drivers/net/wireless/realtek/rtw89/reg.h index 15d29c226b0c3..98465d7469898 100644 --- a/drivers/net/wireless/realtek/rtw89/reg.h +++ b/drivers/net/wireless/realtek/rtw89/reg.h @@ -87,6 +87,8 @@ #define B_AX_BTMODE_MASK GENMASK(7, 6) #define MAC_AX_BT_MODE_0_3 0 #define MAC_AX_BT_MODE_2 2 +#define MAC_AX_RTK_MODE 0 +#define MAC_AX_CSR_MODE 1 #define B_AX_ENBT BIT(5) #define B_AX_EROM_EN BIT(4) #define B_AX_ENUARTRX BIT(2) @@ -2962,11 +2964,40 @@ #define R_AX_TXPWR_ISR_C1 0xF9E4 #define R_AX_BTC_CFG 0xDA00 +#define B_AX_BTC_EN BIT(31) +#define B_AX_EN_EXT_BT_PINMUX BIT(29) +#define B_AX_BTC_RST BIT(28) +#define B_AX_BTC_DBG_SRC_SEL BIT(27) +#define B_AX_BTC_MODE_MASK GENMASK(25, 24) +#define B_AX_INV_WL_ACT2 BIT(17) +#define B_AX_BTG_LNA1_GAIN_SEL BIT(16) +#define B_AX_COEX_DLY_CLK_MASK GENMASK(15, 8) +#define B_AX_IGN_GNT_BT2_RX BIT(7) +#define B_AX_IGN_GNT_BT2_TX BIT(6) +#define B_AX_IGN_GNT_BT2 BIT(5) +#define B_AX_BTC_DBG_SEL_MASK GENMASK(4, 3) #define B_AX_DIS_BTC_CLK_G BIT(2) +#define B_AX_GNT_WL_RX_CTRL BIT(1) +#define B_AX_WL_SRC BIT(0) + +#define R_AX_RTK_MODE_CFG_V1 0xDA04 +#define R_AX_RTK_MODE_CFG_V1_C1 0xFA04 +#define B_AX_BT_BLE_EN_V1 BIT(24) +#define B_AX_BT_ULTRA_EN BIT(16) +#define B_AX_BT_L_RX_ULTRA_MASK GENMASK(15, 14) +#define B_AX_BT_L_TX_ULTRA_MASK GENMASK(13, 12) +#define B_AX_BT_H_RX_ULTRA_MASK GENMASK(11, 10) +#define B_AX_BT_H_TX_ULTRA_MASK GENMASK(9, 8) +#define B_AX_SAMPLE_CLK_MASK GENMASK(7, 0) #define R_AX_WL_PRI_MSK 0xDA10 #define B_AX_PTA_WL_PRI_MASK_BCNQ BIT(8) +#define R_AX_BT_CNT_CFG 0xDA10 +#define R_AX_BT_CNT_CFG_C1 0xFA10 +#define B_AX_BT_CNT_RST_V1 BIT(1) +#define B_AX_BT_CNT_EN BIT(0) + #define R_AX_BTC_FUNC_EN 0xDA20 #define R_AX_BTC_FUNC_EN_C1 0xFA20 #define B_AX_PTA_WL_TX_EN BIT(1) @@ -2999,6 +3030,8 @@ #define B_AX_WL_ACT_MASK_ENABLE BIT(1) #define B_AX_ENHANCED_BT BIT(0) +#define R_AX_BT_BREAK_TABLE 0xDA44 + #define R_AX_BT_STAST_HIGH 0xDA44 #define B_AX_STATIS_BT_HI_RX_MASK GENMASK(31, 16) #define B_AX_STATIS_BT_HI_TX_MASK GENMASK(15, 0) diff --git a/drivers/net/wireless/realtek/rtw89/rtw8852c.c b/drivers/net/wireless/realtek/rtw89/rtw8852c.c index ca254339ea7a9..38b1383307161 100644 --- a/drivers/net/wireless/realtek/rtw89/rtw8852c.c +++ b/drivers/net/wireless/realtek/rtw89/rtw8852c.c @@ -2,6 +2,7 @@ /* Copyright(c) 2019-2022 Realtek Corporation */ +#include "coex.h" #include "debug.h" #include "fw.h" #include "mac.h" @@ -528,6 +529,62 @@ void rtw8852c_set_txpwr_ul_tb_offset(struct rtw89_dev *rtwdev, } } +static +void rtw8852c_set_trx_mask(struct rtw89_dev *rtwdev, u8 path, u8 group, u32 val) +{ + rtw89_write_rf(rtwdev, path, RR_LUTWE, RFREG_MASK, 0x20000); + rtw89_write_rf(rtwdev, path, RR_LUTWA, RFREG_MASK, group); + rtw89_write_rf(rtwdev, path, RR_LUTWD0, RFREG_MASK, val); + rtw89_write_rf(rtwdev, path, RR_LUTWE, RFREG_MASK, 0x0); +} + +static void rtw8852c_btc_init_cfg(struct rtw89_dev *rtwdev) +{ + struct rtw89_btc *btc = &rtwdev->btc; + struct rtw89_btc_module *module = &btc->mdinfo; + const struct rtw89_chip_info *chip = rtwdev->chip; + const struct rtw89_mac_ax_coex coex_params = { + .pta_mode = RTW89_MAC_AX_COEX_RTK_MODE, + .direction = RTW89_MAC_AX_COEX_INNER, + }; + + /* PTA init */ + rtw89_mac_coex_init_v1(rtwdev, &coex_params); + + /* set WL Tx response = Hi-Pri */ + chip->ops->btc_set_wl_pri(rtwdev, BTC_PRI_MASK_TX_RESP, true); + chip->ops->btc_set_wl_pri(rtwdev, BTC_PRI_MASK_BEACON, true); + + /* set rf gnt debug off */ + rtw89_write_rf(rtwdev, RF_PATH_A, RR_WLSEL, RFREG_MASK, 0x0); + rtw89_write_rf(rtwdev, RF_PATH_B, RR_WLSEL, RFREG_MASK, 0x0); + + /* set WL Tx thru in TRX mask table if GNT_WL = 0 && BT_S1 = ss group */ + if (module->ant.type == BTC_ANT_SHARED) { + rtw8852c_set_trx_mask(rtwdev, + RF_PATH_A, BTC_BT_SS_GROUP, 0x5ff); + rtw8852c_set_trx_mask(rtwdev, + RF_PATH_B, BTC_BT_SS_GROUP, 0x5ff); + /* set path-A(S0) Tx/Rx no-mask if GNT_WL=0 && BT_S1=tx group */ + rtw8852c_set_trx_mask(rtwdev, + RF_PATH_A, BTC_BT_TX_GROUP, 0x5ff); + } else { /* set WL Tx stb if GNT_WL = 0 && BT_S1 = ss group for 3-ant */ + rtw8852c_set_trx_mask(rtwdev, + RF_PATH_A, BTC_BT_SS_GROUP, 0x5df); + rtw8852c_set_trx_mask(rtwdev, + RF_PATH_B, BTC_BT_SS_GROUP, 0x5df); + } + + /* set PTA break table */ + rtw89_write32(rtwdev, R_AX_BT_BREAK_TABLE, BTC_BREAK_PARAM); + + /* enable BT counter 0xda10[1:0] = 2b'11 */ + rtw89_write32_set(rtwdev, + R_AX_BT_CNT_CFG, B_AX_BT_CNT_EN | + B_AX_BT_CNT_RST_V1); + btc->cx.wl.status.map.init_ok = true; +} + static int rtw8852c_mac_enable_bb_rf(struct rtw89_dev *rtwdev) { int ret; @@ -588,6 +645,8 @@ static const struct rtw89_chip_ops rtw8852c_chip_ops = { .mac_cfg_gnt = rtw89_mac_cfg_gnt_v1, .stop_sch_tx = rtw89_mac_stop_sch_tx_v1, .resume_sch_tx = rtw89_mac_resume_sch_tx_v1, + + .btc_init_cfg = rtw8852c_btc_init_cfg, }; const struct rtw89_chip_info rtw8852c_chip_info = { From af5175acc8e2fa7990c59a3e4420bbe74e047d40 Mon Sep 17 00:00:00 2001 From: Joe Perches Date: Thu, 7 Apr 2022 13:14:44 -0700 Subject: [PATCH 123/228] rtw89: rtw89_ser: add const to struct state_ent and event_ent Change the struct and the uses to const to reduce data. $ size drivers/net/wireless/realtek/rtw89/ser.o* (x86-64 defconfig w/ rtw89) text data bss dec hex filename 3741 8 0 3749 ea5 drivers/net/wireless/realtek/rtw89/ser.o.new 3437 312 0 3749 ea5 drivers/net/wireless/realtek/rtw89/ser.o.old Signed-off-by: Joe Perches Acked-by: Ping-Ke Shih Signed-off-by: Kalle Valo Link: https://lore.kernel.org/r/2fd88e6119f62b968477ef9781abb1832d399fd6.camel@perches.com --- drivers/net/wireless/realtek/rtw89/core.h | 4 ++-- drivers/net/wireless/realtek/rtw89/ser.c | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/drivers/net/wireless/realtek/rtw89/core.h b/drivers/net/wireless/realtek/rtw89/core.h index a6c075ac67d5d..ec181c1989bc6 100644 --- a/drivers/net/wireless/realtek/rtw89/core.h +++ b/drivers/net/wireless/realtek/rtw89/core.h @@ -2948,8 +2948,8 @@ struct rtw89_ser { struct work_struct ser_hdl_work; struct delayed_work ser_alarm_work; - struct state_ent *st_tbl; - struct event_ent *ev_tbl; + const struct state_ent *st_tbl; + const struct event_ent *ev_tbl; struct list_head msg_q; spinlock_t msg_q_lock; /* lock when read/write ser msg */ DECLARE_BITMAP(flags, RTW89_NUM_OF_SER_FLAGS); diff --git a/drivers/net/wireless/realtek/rtw89/ser.c b/drivers/net/wireless/realtek/rtw89/ser.c index 5aebd6839d299..9e95ed9727108 100644 --- a/drivers/net/wireless/realtek/rtw89/ser.c +++ b/drivers/net/wireless/realtek/rtw89/ser.c @@ -632,7 +632,7 @@ static void ser_l2_reset_st_hdl(struct rtw89_ser *ser, u8 evt) } } -static struct event_ent ser_ev_tbl[] = { +static const struct event_ent ser_ev_tbl[] = { {SER_EV_NONE, "SER_EV_NONE"}, {SER_EV_STATE_IN, "SER_EV_STATE_IN"}, {SER_EV_STATE_OUT, "SER_EV_STATE_OUT"}, @@ -648,7 +648,7 @@ static struct event_ent ser_ev_tbl[] = { {SER_EV_MAXX, "SER_EV_MAX"} }; -static struct state_ent ser_st_tbl[] = { +static const struct state_ent ser_st_tbl[] = { {SER_IDLE_ST, "SER_IDLE_ST", ser_idle_st_hdl}, {SER_RESET_TRX_ST, "SER_RESET_TRX_ST", ser_reset_trx_st_hdl}, {SER_DO_HCI_ST, "SER_DO_HCI_ST", ser_do_hci_st_hdl}, From c1edc86472fc3a5aa3b5c5c53c4e20f6a24992a6 Mon Sep 17 00:00:00 2001 From: Po-Hao Huang Date: Thu, 7 Apr 2022 17:58:53 +0800 Subject: [PATCH 124/228] rtw88: add ieee80211:sta_rc_update ops Adding this allows us to get notification when bitrate configuration of the station changes. Update according parameters to firmware so the rate control algorithm can work properly. Signed-off-by: Po-Hao Huang Signed-off-by: Ping-Ke Shih Signed-off-by: Kalle Valo Link: https://lore.kernel.org/r/20220407095858.46807-2-pkshih@realtek.com --- drivers/net/wireless/realtek/rtw88/fw.c | 7 +++---- drivers/net/wireless/realtek/rtw88/fw.h | 3 ++- drivers/net/wireless/realtek/rtw88/mac80211.c | 14 +++++++++++++- drivers/net/wireless/realtek/rtw88/main.c | 7 ++++--- drivers/net/wireless/realtek/rtw88/main.h | 4 ++-- drivers/net/wireless/realtek/rtw88/phy.c | 2 +- 6 files changed, 25 insertions(+), 12 deletions(-) diff --git a/drivers/net/wireless/realtek/rtw88/fw.c b/drivers/net/wireless/realtek/rtw88/fw.c index aa2aeb5fb2ccd..941df27f0b692 100644 --- a/drivers/net/wireless/realtek/rtw88/fw.c +++ b/drivers/net/wireless/realtek/rtw88/fw.c @@ -585,10 +585,10 @@ void rtw_fw_send_rssi_info(struct rtw_dev *rtwdev, struct rtw_sta_info *si) rtw_fw_send_h2c_command(rtwdev, h2c_pkt); } -void rtw_fw_send_ra_info(struct rtw_dev *rtwdev, struct rtw_sta_info *si) +void rtw_fw_send_ra_info(struct rtw_dev *rtwdev, struct rtw_sta_info *si, + bool reset_ra_mask) { u8 h2c_pkt[H2C_PKT_SIZE] = {0}; - bool no_update = si->updated; bool disable_pt = true; SET_H2C_CMD_ID_CLASS(h2c_pkt, H2C_CMD_RA_INFO); @@ -599,7 +599,7 @@ void rtw_fw_send_ra_info(struct rtw_dev *rtwdev, struct rtw_sta_info *si) SET_RA_INFO_SGI_EN(h2c_pkt, si->sgi_enable); SET_RA_INFO_BW_MODE(h2c_pkt, si->bw_mode); SET_RA_INFO_LDPC(h2c_pkt, !!si->ldpc_en); - SET_RA_INFO_NO_UPDATE(h2c_pkt, no_update); + SET_RA_INFO_NO_UPDATE(h2c_pkt, !reset_ra_mask); SET_RA_INFO_VHT_EN(h2c_pkt, si->vht_enable); SET_RA_INFO_DIS_PT(h2c_pkt, disable_pt); SET_RA_INFO_RA_MASK0(h2c_pkt, (si->ra_mask & 0xff)); @@ -608,7 +608,6 @@ void rtw_fw_send_ra_info(struct rtw_dev *rtwdev, struct rtw_sta_info *si) SET_RA_INFO_RA_MASK3(h2c_pkt, (si->ra_mask & 0xff000000) >> 24); si->init_ra_lv = 0; - si->updated = true; rtw_fw_send_h2c_command(rtwdev, h2c_pkt); } diff --git a/drivers/net/wireless/realtek/rtw88/fw.h b/drivers/net/wireless/realtek/rtw88/fw.h index b59d2cbad5d73..3486eb9585def 100644 --- a/drivers/net/wireless/realtek/rtw88/fw.h +++ b/drivers/net/wireless/realtek/rtw88/fw.h @@ -791,7 +791,8 @@ void rtw_fw_coex_query_hid_info(struct rtw_dev *rtwdev, u8 sub_id, u8 data); void rtw_fw_bt_wifi_control(struct rtw_dev *rtwdev, u8 op_code, u8 *data); void rtw_fw_send_rssi_info(struct rtw_dev *rtwdev, struct rtw_sta_info *si); -void rtw_fw_send_ra_info(struct rtw_dev *rtwdev, struct rtw_sta_info *si); +void rtw_fw_send_ra_info(struct rtw_dev *rtwdev, struct rtw_sta_info *si, + bool reset_ra_mask); void rtw_fw_media_status_report(struct rtw_dev *rtwdev, u8 mac_id, bool conn); void rtw_fw_update_wl_phy_info(struct rtw_dev *rtwdev); void rtw_fw_beacon_filter_config(struct rtw_dev *rtwdev, bool connect, diff --git a/drivers/net/wireless/realtek/rtw88/mac80211.c b/drivers/net/wireless/realtek/rtw88/mac80211.c index 5cdc54c9a9aae..c9341af493645 100644 --- a/drivers/net/wireless/realtek/rtw88/mac80211.c +++ b/drivers/net/wireless/realtek/rtw88/mac80211.c @@ -694,7 +694,7 @@ static void rtw_ra_mask_info_update_iter(void *data, struct ieee80211_sta *sta) } si->use_cfg_mask = true; - rtw_update_sta_info(br_data->rtwdev, si); + rtw_update_sta_info(br_data->rtwdev, si, true); } static void rtw_ra_mask_info_update(struct rtw_dev *rtwdev, @@ -850,6 +850,17 @@ static int rtw_ops_set_sar_specs(struct ieee80211_hw *hw, return 0; } +static void rtw_ops_sta_rc_update(struct ieee80211_hw *hw, + struct ieee80211_vif *vif, + struct ieee80211_sta *sta, u32 changed) +{ + struct rtw_dev *rtwdev = hw->priv; + struct rtw_sta_info *si = (struct rtw_sta_info *)sta->drv_priv; + + if (changed & IEEE80211_RC_BW_CHANGED) + rtw_update_sta_info(rtwdev, si, true); +} + const struct ieee80211_ops rtw_ops = { .tx = rtw_ops_tx, .wake_tx_queue = rtw_ops_wake_tx_queue, @@ -879,6 +890,7 @@ const struct ieee80211_ops rtw_ops = { .reconfig_complete = rtw_reconfig_complete, .hw_scan = rtw_ops_hw_scan, .cancel_hw_scan = rtw_ops_cancel_hw_scan, + .sta_rc_update = rtw_ops_sta_rc_update, .set_sar_specs = rtw_ops_set_sar_specs, #ifdef CONFIG_PM .suspend = rtw_ops_suspend, diff --git a/drivers/net/wireless/realtek/rtw88/main.c b/drivers/net/wireless/realtek/rtw88/main.c index 1a4c8c989ce93..66b6c140e69a9 100644 --- a/drivers/net/wireless/realtek/rtw88/main.c +++ b/drivers/net/wireless/realtek/rtw88/main.c @@ -313,7 +313,7 @@ int rtw_sta_add(struct rtw_dev *rtwdev, struct ieee80211_sta *sta, for (i = 0; i < ARRAY_SIZE(sta->txq); i++) rtw_txq_init(rtwdev, sta->txq[i]); - rtw_update_sta_info(rtwdev, si); + rtw_update_sta_info(rtwdev, si, true); rtw_fw_media_status_report(rtwdev, si->mac_id, true); rtwdev->sta_cnt++; @@ -1105,7 +1105,8 @@ static u64 rtw_rate_mask_cfg(struct rtw_dev *rtwdev, struct rtw_sta_info *si, return ra_mask; } -void rtw_update_sta_info(struct rtw_dev *rtwdev, struct rtw_sta_info *si) +void rtw_update_sta_info(struct rtw_dev *rtwdev, struct rtw_sta_info *si, + bool reset_ra_mask) { struct rtw_dm_info *dm_info = &rtwdev->dm_info; struct ieee80211_sta *sta = si->sta; @@ -1223,7 +1224,7 @@ void rtw_update_sta_info(struct rtw_dev *rtwdev, struct rtw_sta_info *si) si->ra_mask = ra_mask; si->rate_id = rate_id; - rtw_fw_send_ra_info(rtwdev, si); + rtw_fw_send_ra_info(rtwdev, si, reset_ra_mask); } static int rtw_wait_firmware_completion(struct rtw_dev *rtwdev) diff --git a/drivers/net/wireless/realtek/rtw88/main.h b/drivers/net/wireless/realtek/rtw88/main.h index 17815af9dd4ea..f694a2d86e0b2 100644 --- a/drivers/net/wireless/realtek/rtw88/main.h +++ b/drivers/net/wireless/realtek/rtw88/main.h @@ -753,7 +753,6 @@ struct rtw_sta_info { u8 ldpc_en:2; bool sgi_enable; bool vht_enable; - bool updated; u8 init_ra_lv; u64 ra_mask; @@ -2145,7 +2144,8 @@ void rtw_chip_prepare_tx(struct rtw_dev *rtwdev); void rtw_vif_port_config(struct rtw_dev *rtwdev, struct rtw_vif *rtwvif, u32 config); void rtw_tx_report_purge_timer(struct timer_list *t); -void rtw_update_sta_info(struct rtw_dev *rtwdev, struct rtw_sta_info *si); +void rtw_update_sta_info(struct rtw_dev *rtwdev, struct rtw_sta_info *si, + bool reset_ra_mask); void rtw_core_scan_start(struct rtw_dev *rtwdev, struct rtw_vif *rtwvif, const u8 *mac_addr, bool hw_scan); void rtw_core_scan_complete(struct rtw_dev *rtwdev, struct ieee80211_vif *vif, diff --git a/drivers/net/wireless/realtek/rtw88/phy.c b/drivers/net/wireless/realtek/rtw88/phy.c index e505d17f107e4..8982e0c98dac9 100644 --- a/drivers/net/wireless/realtek/rtw88/phy.c +++ b/drivers/net/wireless/realtek/rtw88/phy.c @@ -536,7 +536,7 @@ static void rtw_phy_ra_info_update_iter(void *data, struct ieee80211_sta *sta) struct rtw_dev *rtwdev = data; struct rtw_sta_info *si = (struct rtw_sta_info *)sta->drv_priv; - rtw_update_sta_info(rtwdev, si); + rtw_update_sta_info(rtwdev, si, false); } static void rtw_phy_ra_info_update(struct rtw_dev *rtwdev) From 6723c0cde84fde582a261c186ce84100dcfa0019 Mon Sep 17 00:00:00 2001 From: Po-Hao Huang Date: Thu, 7 Apr 2022 17:58:54 +0800 Subject: [PATCH 125/228] rtw88: fix incorrect frequency reported We should only fill in frequency reported by firmware during scan. Add this so frames won't be dropped by mac80211 due to frequency mismatch. Signed-off-by: Po-Hao Huang Signed-off-by: Ping-Ke Shih Signed-off-by: Kalle Valo Link: https://lore.kernel.org/r/20220407095858.46807-3-pkshih@realtek.com --- drivers/net/wireless/realtek/rtw88/rx.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/drivers/net/wireless/realtek/rtw88/rx.c b/drivers/net/wireless/realtek/rtw88/rx.c index d2d607e22198d..84aedabdf2853 100644 --- a/drivers/net/wireless/realtek/rtw88/rx.c +++ b/drivers/net/wireless/realtek/rtw88/rx.c @@ -158,7 +158,8 @@ void rtw_rx_fill_rx_status(struct rtw_dev *rtwdev, memset(rx_status, 0, sizeof(*rx_status)); rx_status->freq = hw->conf.chandef.chan->center_freq; rx_status->band = hw->conf.chandef.chan->band; - if (rtw_fw_feature_check(&rtwdev->fw, FW_FEATURE_SCAN_OFFLOAD)) + if (rtw_fw_feature_check(&rtwdev->fw, FW_FEATURE_SCAN_OFFLOAD) && + test_bit(RTW_FLAG_SCANNING, rtwdev->flags)) rtw_set_rx_freq_by_pktstat(pkt_stat, rx_status); if (pkt_stat->crc_err) rx_status->flag |= RX_FLAG_FAILED_FCS_CRC; From f2217968ffdae702c21cc00fa804fbbd9ee6bb4b Mon Sep 17 00:00:00 2001 From: Po-Hao Huang Date: Thu, 7 Apr 2022 17:58:55 +0800 Subject: [PATCH 126/228] rtw88: Add update beacon flow for AP mode To support stations in power saving mode, AP should notify stations that there are frames buffered at the AP via TIM during beacons. Driver used to transmit identical beacons that were downloaded to hardware during the initiation phase. This beacon will become obsolete over time. If the beacon does not contain sufficient information, station would not be able to percept that there is data to receive. Hence it won't wake up and start the PS-poll procedure, this could lead to timeout and/or lost data segments. In order to resolve this issue, driver will now download beacon to hardware whenever the content is updated. Enable hardware to update dtim_count for more efficiency, this reduces the overhead of downloading beacon at every beacon interval since most of the time only the dtim_count needs to be updated. Change queue mapping for broadcast/multicast frames to high queue, so these frames can be prioritized and sent when dtim_count is zero. Signed-off-by: Po-Hao Huang Signed-off-by: Ping-Ke Shih Signed-off-by: Kalle Valo Link: https://lore.kernel.org/r/20220407095858.46807-4-pkshih@realtek.com --- drivers/net/wireless/realtek/rtw88/fw.c | 4 +++- drivers/net/wireless/realtek/rtw88/fw.h | 1 + drivers/net/wireless/realtek/rtw88/mac80211.c | 17 ++++++++++++++++- drivers/net/wireless/realtek/rtw88/main.c | 6 ++++++ drivers/net/wireless/realtek/rtw88/main.h | 2 ++ drivers/net/wireless/realtek/rtw88/pci.c | 3 +++ drivers/net/wireless/realtek/rtw88/reg.h | 2 ++ drivers/net/wireless/realtek/rtw88/tx.c | 17 +++++++++++++++++ drivers/net/wireless/realtek/rtw88/tx.h | 4 ++++ 9 files changed, 54 insertions(+), 2 deletions(-) diff --git a/drivers/net/wireless/realtek/rtw88/fw.c b/drivers/net/wireless/realtek/rtw88/fw.c index 941df27f0b692..c1af2704bb866 100644 --- a/drivers/net/wireless/realtek/rtw88/fw.c +++ b/drivers/net/wireless/realtek/rtw88/fw.c @@ -1047,6 +1047,7 @@ static struct sk_buff *rtw_get_rsvd_page_skb(struct ieee80211_hw *hw, struct rtw_vif *rtwvif; struct sk_buff *skb_new; struct cfg80211_ssid *ssid; + u16 tim_offset; if (rsvd_pkt->type == RSVD_DUMMY) { skb_new = alloc_skb(1, GFP_KERNEL); @@ -1065,7 +1066,8 @@ static struct sk_buff *rtw_get_rsvd_page_skb(struct ieee80211_hw *hw, switch (rsvd_pkt->type) { case RSVD_BEACON: - skb_new = ieee80211_beacon_get(hw, vif); + skb_new = ieee80211_beacon_get_tim(hw, vif, &tim_offset, NULL); + rsvd_pkt->tim_offset = tim_offset; break; case RSVD_PS_POLL: skb_new = ieee80211_pspoll_get(hw, vif); diff --git a/drivers/net/wireless/realtek/rtw88/fw.h b/drivers/net/wireless/realtek/rtw88/fw.h index 3486eb9585def..734113fba184e 100644 --- a/drivers/net/wireless/realtek/rtw88/fw.h +++ b/drivers/net/wireless/realtek/rtw88/fw.h @@ -172,6 +172,7 @@ struct rtw_rsvd_page { struct sk_buff *skb; enum rtw_rsvd_packet_type type; u8 page; + u16 tim_offset; bool add_txdesc; struct cfg80211_ssid *ssid; u16 probe_req_size; diff --git a/drivers/net/wireless/realtek/rtw88/mac80211.c b/drivers/net/wireless/realtek/rtw88/mac80211.c index c9341af493645..1ee41dfda5e1b 100644 --- a/drivers/net/wireless/realtek/rtw88/mac80211.c +++ b/drivers/net/wireless/realtek/rtw88/mac80211.c @@ -402,8 +402,10 @@ static void rtw_ops_bss_info_changed(struct ieee80211_hw *hw, coex_stat->wl_beacon_interval = conf->beacon_int; } - if (changed & BSS_CHANGED_BEACON) + if (changed & BSS_CHANGED_BEACON) { + rtw_set_dtim_period(rtwdev, conf->dtim_period); rtw_fw_download_rsvd_page(rtwdev); + } if (changed & BSS_CHANGED_BEACON_ENABLED) { if (conf->enable_beacon) @@ -474,6 +476,18 @@ static int rtw_ops_sta_remove(struct ieee80211_hw *hw, return 0; } +static int rtw_ops_set_tim(struct ieee80211_hw *hw, struct ieee80211_sta *sta, + bool set) +{ + struct rtw_dev *rtwdev = hw->priv; + + mutex_lock(&rtwdev->mutex); + rtw_fw_download_rsvd_page(rtwdev); + mutex_unlock(&rtwdev->mutex); + + return 0; +} + static int rtw_ops_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd, struct ieee80211_vif *vif, struct ieee80211_sta *sta, struct ieee80211_key_conf *key) @@ -875,6 +889,7 @@ const struct ieee80211_ops rtw_ops = { .conf_tx = rtw_ops_conf_tx, .sta_add = rtw_ops_sta_add, .sta_remove = rtw_ops_sta_remove, + .set_tim = rtw_ops_set_tim, .set_key = rtw_ops_set_key, .ampdu_action = rtw_ops_ampdu_action, .can_aggregate_in_amsdu = rtw_ops_can_aggregate_in_amsdu, diff --git a/drivers/net/wireless/realtek/rtw88/main.c b/drivers/net/wireless/realtek/rtw88/main.c index 66b6c140e69a9..7431988b59859 100644 --- a/drivers/net/wireless/realtek/rtw88/main.c +++ b/drivers/net/wireless/realtek/rtw88/main.c @@ -664,6 +664,12 @@ void rtw_set_rx_freq_band(struct rtw_rx_pkt_stat *pkt_stat, u8 channel) } EXPORT_SYMBOL(rtw_set_rx_freq_band); +void rtw_set_dtim_period(struct rtw_dev *rtwdev, int dtim_period) +{ + rtw_write32_set(rtwdev, REG_TCR, BIT_TCR_UPDATE_TIMIE); + rtw_write8(rtwdev, REG_DTIM_COUNTER_ROOT, dtim_period - 1); +} + void rtw_get_channel_params(struct cfg80211_chan_def *chandef, struct rtw_channel_params *chan_params) { diff --git a/drivers/net/wireless/realtek/rtw88/main.h b/drivers/net/wireless/realtek/rtw88/main.h index f694a2d86e0b2..2743074a42560 100644 --- a/drivers/net/wireless/realtek/rtw88/main.h +++ b/drivers/net/wireless/realtek/rtw88/main.h @@ -580,6 +580,7 @@ struct rtw_tx_pkt_info { u32 tx_pkt_size; u8 offset; u8 pkt_offset; + u8 tim_offset; u8 mac_id; u8 rate_id; u8 rate; @@ -2131,6 +2132,7 @@ static inline int rtw_chip_dump_fw_crash(struct rtw_dev *rtwdev) } void rtw_set_rx_freq_band(struct rtw_rx_pkt_stat *pkt_stat, u8 channel); +void rtw_set_dtim_period(struct rtw_dev *rtwdev, int dtim_period); void rtw_get_channel_params(struct cfg80211_chan_def *chandef, struct rtw_channel_params *ch_param); bool check_hw_ready(struct rtw_dev *rtwdev, u32 addr, u32 mask, u32 target); diff --git a/drivers/net/wireless/realtek/rtw88/pci.c b/drivers/net/wireless/realtek/rtw88/pci.c index a0991d3f15c01..8e122e121e854 100644 --- a/drivers/net/wireless/realtek/rtw88/pci.c +++ b/drivers/net/wireless/realtek/rtw88/pci.c @@ -689,6 +689,9 @@ static u8 rtw_hw_queue_mapping(struct sk_buff *skb) queue = RTW_TX_QUEUE_BCN; else if (unlikely(ieee80211_is_mgmt(fc) || ieee80211_is_ctl(fc))) queue = RTW_TX_QUEUE_MGMT; + else if (is_broadcast_ether_addr(hdr->addr1) || + is_multicast_ether_addr(hdr->addr1)) + queue = RTW_TX_QUEUE_HI0; else if (WARN_ON_ONCE(q_mapping >= ARRAY_SIZE(ac_to_hwq))) queue = ac_to_hwq[IEEE80211_AC_BE]; else diff --git a/drivers/net/wireless/realtek/rtw88/reg.h b/drivers/net/wireless/realtek/rtw88/reg.h index 84ba9ec489c37..03bd8dc53f72a 100644 --- a/drivers/net/wireless/realtek/rtw88/reg.h +++ b/drivers/net/wireless/realtek/rtw88/reg.h @@ -389,12 +389,14 @@ #define BIT_EN_FREE_CNT BIT(3) #define BIT_DIS_SECOND_CCA (BIT(0) | BIT(1)) #define REG_HIQ_NO_LMT_EN 0x5A7 +#define REG_DTIM_COUNTER_ROOT 0x5A8 #define BIT_HIQ_NO_LMT_EN_ROOT BIT(0) #define REG_TIMER0_SRC_SEL 0x05B4 #define BIT_TSFT_SEL_TIMER0 (BIT(4) | BIT(5) | BIT(6)) #define REG_TCR 0x0604 #define BIT_PWRMGT_HWDATA_EN BIT(7) +#define BIT_TCR_UPDATE_TIMIE BIT(5) #define REG_RCR 0x0608 #define BIT_APP_FCS BIT(31) #define BIT_APP_MIC BIT(30) diff --git a/drivers/net/wireless/realtek/rtw88/tx.c b/drivers/net/wireless/realtek/rtw88/tx.c index 83248da0237f6..60d40a5c2c6a4 100644 --- a/drivers/net/wireless/realtek/rtw88/tx.c +++ b/drivers/net/wireless/realtek/rtw88/tx.c @@ -67,6 +67,10 @@ void rtw_tx_fill_tx_desc(struct rtw_tx_pkt_info *pkt_info, struct sk_buff *skb) SET_TX_DESC_HW_SSN_SEL(txdesc, pkt_info->hw_ssn_sel); SET_TX_DESC_NAVUSEHDR(txdesc, pkt_info->nav_use_hdr); SET_TX_DESC_BT_NULL(txdesc, pkt_info->bt_null); + if (pkt_info->tim_offset) { + SET_TX_DESC_TIM_EN(txdesc, 1); + SET_TX_DESC_TIM_OFFSET(txdesc, pkt_info->tim_offset); + } } EXPORT_SYMBOL(rtw_tx_fill_tx_desc); @@ -448,6 +452,19 @@ void rtw_tx_rsvd_page_pkt_info_update(struct rtw_dev *rtwdev, if (type == RSVD_QOS_NULL) pkt_info->bt_null = true; + if (type == RSVD_BEACON) { + struct rtw_rsvd_page *rsvd_pkt; + int hdr_len; + + rsvd_pkt = list_first_entry_or_null(&rtwdev->rsvd_page_list, + struct rtw_rsvd_page, + build_list); + if (rsvd_pkt && rsvd_pkt->tim_offset != 0) { + hdr_len = sizeof(struct ieee80211_hdr_3addr); + pkt_info->tim_offset = rsvd_pkt->tim_offset - hdr_len; + } + } + rtw_tx_pkt_info_update_sec(rtwdev, pkt_info, skb); /* TODO: need to change hw port and hw ssn sel for multiple vifs */ diff --git a/drivers/net/wireless/realtek/rtw88/tx.h b/drivers/net/wireless/realtek/rtw88/tx.h index 56371eff9f7ff..8419603adce4a 100644 --- a/drivers/net/wireless/realtek/rtw88/tx.h +++ b/drivers/net/wireless/realtek/rtw88/tx.h @@ -33,6 +33,10 @@ le32p_replace_bits((__le32 *)(txdesc) + 0x05, value, GENMASK(6, 5)) #define SET_TX_DESC_SW_SEQ(txdesc, value) \ le32p_replace_bits((__le32 *)(txdesc) + 0x09, value, GENMASK(23, 12)) +#define SET_TX_DESC_TIM_EN(txdesc, value) \ + le32p_replace_bits((__le32 *)(txdesc) + 0x09, value, BIT(7)) +#define SET_TX_DESC_TIM_OFFSET(txdesc, value) \ + le32p_replace_bits((__le32 *)(txdesc) + 0x09, value, GENMASK(6, 0)) #define SET_TX_DESC_MAX_AGG_NUM(txdesc, value) \ le32p_replace_bits((__le32 *)(txdesc) + 0x03, value, GENMASK(21, 17)) #define SET_TX_DESC_USE_RTS(tx_desc, value) \ From f1c4dabfe68df7321cba0a07a30b2776a303abb2 Mon Sep 17 00:00:00 2001 From: Po-Hao Huang Date: Thu, 7 Apr 2022 17:58:56 +0800 Subject: [PATCH 127/228] rtw88: 8821c: Enable TX report for management frames Without this setting, hardware would not report to driver even if management frames are transmitted successfully. So we fix it. Signed-off-by: Po-Hao Huang Signed-off-by: Ping-Ke Shih Signed-off-by: Kalle Valo Link: https://lore.kernel.org/r/20220407095858.46807-5-pkshih@realtek.com --- drivers/net/wireless/realtek/rtw88/rtw8821c_table.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/net/wireless/realtek/rtw88/rtw8821c_table.c b/drivers/net/wireless/realtek/rtw88/rtw8821c_table.c index 8e8915c5c4988..6c82c43834977 100644 --- a/drivers/net/wireless/realtek/rtw88/rtw8821c_table.c +++ b/drivers/net/wireless/realtek/rtw88/rtw8821c_table.c @@ -13,7 +13,7 @@ static const u32 rtw8821c_mac[] = { 0x04F, 0x00000001, 0x029, 0x000000F9, 0x420, 0x00000080, - 0x421, 0x0000000F, + 0x421, 0x0000001F, 0x428, 0x0000000A, 0x429, 0x00000010, 0x430, 0x00000000, From f5207c122102cac22c78f438610d937a924aee3a Mon Sep 17 00:00:00 2001 From: Ping-Ke Shih Date: Thu, 7 Apr 2022 17:58:57 +0800 Subject: [PATCH 128/228] rtw88: do PHY calibration while starting AP Calling calibration to yield expected PHY performance. We do this in STA mode, so do this in AP mode as well. Signed-off-by: Ping-Ke Shih Signed-off-by: Kalle Valo Link: https://lore.kernel.org/r/20220407095858.46807-6-pkshih@realtek.com --- drivers/net/wireless/realtek/rtw88/mac80211.c | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/drivers/net/wireless/realtek/rtw88/mac80211.c b/drivers/net/wireless/realtek/rtw88/mac80211.c index 1ee41dfda5e1b..30903c567cd9b 100644 --- a/drivers/net/wireless/realtek/rtw88/mac80211.c +++ b/drivers/net/wireless/realtek/rtw88/mac80211.c @@ -429,6 +429,18 @@ static void rtw_ops_bss_info_changed(struct ieee80211_hw *hw, mutex_unlock(&rtwdev->mutex); } +static int rtw_ops_start_ap(struct ieee80211_hw *hw, struct ieee80211_vif *vif) +{ + struct rtw_dev *rtwdev = hw->priv; + struct rtw_chip_info *chip = rtwdev->chip; + + mutex_lock(&rtwdev->mutex); + chip->ops->phy_calibration(rtwdev); + mutex_unlock(&rtwdev->mutex); + + return 0; +} + static int rtw_ops_conf_tx(struct ieee80211_hw *hw, struct ieee80211_vif *vif, u16 ac, const struct ieee80211_tx_queue_params *params) @@ -886,6 +898,7 @@ const struct ieee80211_ops rtw_ops = { .change_interface = rtw_ops_change_interface, .configure_filter = rtw_ops_configure_filter, .bss_info_changed = rtw_ops_bss_info_changed, + .start_ap = rtw_ops_start_ap, .conf_tx = rtw_ops_conf_tx, .sta_add = rtw_ops_sta_add, .sta_remove = rtw_ops_sta_remove, From ece31c93d4d68f7eb8eea4431b052aacdb678de2 Mon Sep 17 00:00:00 2001 From: Po-Hao Huang Date: Thu, 7 Apr 2022 17:58:58 +0800 Subject: [PATCH 129/228] rtw88: 8821c: fix debugfs rssi value RSSI value per frame is reported to mac80211 but not maintained in our own statistics, add it back to help us debug. Signed-off-by: Po-Hao Huang Signed-off-by: Ping-Ke Shih Signed-off-by: Kalle Valo Link: https://lore.kernel.org/r/20220407095858.46807-7-pkshih@realtek.com --- drivers/net/wireless/realtek/rtw88/rtw8821c.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/drivers/net/wireless/realtek/rtw88/rtw8821c.c b/drivers/net/wireless/realtek/rtw88/rtw8821c.c index 99eee128ae945..ec38a7c849517 100644 --- a/drivers/net/wireless/realtek/rtw88/rtw8821c.c +++ b/drivers/net/wireless/realtek/rtw88/rtw8821c.c @@ -512,6 +512,7 @@ static s8 get_cck_rx_pwr(struct rtw_dev *rtwdev, u8 lna_idx, u8 vga_idx) static void query_phy_status_page0(struct rtw_dev *rtwdev, u8 *phy_status, struct rtw_rx_pkt_stat *pkt_stat) { + struct rtw_dm_info *dm_info = &rtwdev->dm_info; s8 rx_power; u8 lna_idx = 0; u8 vga_idx = 0; @@ -523,6 +524,7 @@ static void query_phy_status_page0(struct rtw_dev *rtwdev, u8 *phy_status, pkt_stat->rx_power[RF_PATH_A] = rx_power; pkt_stat->rssi = rtw_phy_rf_power_2_rssi(pkt_stat->rx_power, 1); + dm_info->rssi[RF_PATH_A] = pkt_stat->rssi; pkt_stat->bw = RTW_CHANNEL_WIDTH_20; pkt_stat->signal_power = rx_power; } @@ -530,6 +532,7 @@ static void query_phy_status_page0(struct rtw_dev *rtwdev, u8 *phy_status, static void query_phy_status_page1(struct rtw_dev *rtwdev, u8 *phy_status, struct rtw_rx_pkt_stat *pkt_stat) { + struct rtw_dm_info *dm_info = &rtwdev->dm_info; u8 rxsc, bw; s8 min_rx_power = -120; @@ -549,6 +552,7 @@ static void query_phy_status_page1(struct rtw_dev *rtwdev, u8 *phy_status, pkt_stat->rx_power[RF_PATH_A] = GET_PHY_STAT_P1_PWDB_A(phy_status) - 110; pkt_stat->rssi = rtw_phy_rf_power_2_rssi(pkt_stat->rx_power, 1); + dm_info->rssi[RF_PATH_A] = pkt_stat->rssi; pkt_stat->bw = bw; pkt_stat->signal_power = max(pkt_stat->rx_power[RF_PATH_A], min_rx_power); From d5286826201ec226a683964122e207be60f62fbf Mon Sep 17 00:00:00 2001 From: Jimmy Hon Date: Thu, 7 Apr 2022 02:51:22 -0500 Subject: [PATCH 130/228] rtw88: 8821ce: add support for device ID 0xb821 New device ID 0xb821 found on TP-Link T2E Tested it with c821 driver. 2.4GHz and 5GHz works. PCI id: 05:00.0 Network controller: Realtek Semiconductor Co., Ltd. Device b821 Subsystem: Realtek Semiconductor Co., Ltd. Device b821 Signed-off-by: Jimmy Hon Reviewed-by: Ping-Ke Shih Signed-off-by: Kalle Valo Link: https://lore.kernel.org/r/20220407075123.420696-2-honyuenkwun@gmail.com --- drivers/net/wireless/realtek/rtw88/rtw8821ce.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/drivers/net/wireless/realtek/rtw88/rtw8821ce.c b/drivers/net/wireless/realtek/rtw88/rtw8821ce.c index f34de115e4bc4..56d22f9de9042 100644 --- a/drivers/net/wireless/realtek/rtw88/rtw8821ce.c +++ b/drivers/net/wireless/realtek/rtw88/rtw8821ce.c @@ -8,6 +8,10 @@ #include "rtw8821ce.h" static const struct pci_device_id rtw_8821ce_id_table[] = { + { + PCI_DEVICE(PCI_VENDOR_ID_REALTEK, 0xB821), + .driver_data = (kernel_ulong_t)&rtw8821c_hw_spec + }, { PCI_DEVICE(PCI_VENDOR_ID_REALTEK, 0xC821), .driver_data = (kernel_ulong_t)&rtw8821c_hw_spec From b9eb5f0742d107ca9c0f33da58f61ce83e3ce2fc Mon Sep 17 00:00:00 2001 From: Jimmy Hon Date: Thu, 7 Apr 2022 02:51:23 -0500 Subject: [PATCH 131/228] rtw88: 8821ce: Disable PCIe ASPM L1 for 8821CE using chip ID Make workaround work for other 8821CE devices with different PCI ID Signed-off-by: Jimmy Hon Reviewed-by: Ping-Ke Shih Signed-off-by: Kalle Valo Link: https://lore.kernel.org/r/20220407075123.420696-3-honyuenkwun@gmail.com --- drivers/net/wireless/realtek/rtw88/pci.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/net/wireless/realtek/rtw88/pci.c b/drivers/net/wireless/realtek/rtw88/pci.c index 8e122e121e854..33042b63a151e 100644 --- a/drivers/net/wireless/realtek/rtw88/pci.c +++ b/drivers/net/wireless/realtek/rtw88/pci.c @@ -1773,7 +1773,7 @@ int rtw_pci_probe(struct pci_dev *pdev, } /* Disable PCIe ASPM L1 while doing NAPI poll for 8821CE */ - if (pdev->device == 0xc821 && bridge->vendor == PCI_VENDOR_ID_INTEL) + if (rtwdev->chip->id == RTW_CHIP_TYPE_8821C && bridge->vendor == PCI_VENDOR_ID_INTEL) rtwpci->rx_no_aspm = true; rtw_pci_phy_cfg(rtwdev); From b2268fd81c18302ed3443db09b7f06d52e6dcf03 Mon Sep 17 00:00:00 2001 From: Minghao Chi Date: Fri, 8 Apr 2022 08:12:05 +0000 Subject: [PATCH 132/228] wlcore: debugfs: use pm_runtime_resume_and_get() instead of pm_runtime_get_sync() Using pm_runtime_resume_and_get is more appropriate for simplifing code Reported-by: Zeal Robot Signed-off-by: Minghao Chi Signed-off-by: Kalle Valo Link: https://lore.kernel.org/r/20220408081205.2494512-1-chi.minghao@zte.com.cn --- drivers/net/wireless/ti/wlcore/debugfs.c | 52 ++++++++---------------- 1 file changed, 17 insertions(+), 35 deletions(-) diff --git a/drivers/net/wireless/ti/wlcore/debugfs.c b/drivers/net/wireless/ti/wlcore/debugfs.c index cce8d75d8b815..eb3d3f0e0b4df 100644 --- a/drivers/net/wireless/ti/wlcore/debugfs.c +++ b/drivers/net/wireless/ti/wlcore/debugfs.c @@ -52,11 +52,9 @@ void wl1271_debugfs_update_stats(struct wl1271 *wl) if (unlikely(wl->state != WLCORE_STATE_ON)) goto out; - ret = pm_runtime_get_sync(wl->dev); - if (ret < 0) { - pm_runtime_put_noidle(wl->dev); + ret = pm_runtime_resume_and_get(wl->dev); + if (ret < 0) goto out; - } if (!wl->plt && time_after(jiffies, wl->stats.fw_stats_update + @@ -108,12 +106,9 @@ static void chip_op_handler(struct wl1271 *wl, unsigned long value, return; } - ret = pm_runtime_get_sync(wl->dev); - if (ret < 0) { - pm_runtime_put_noidle(wl->dev); - + ret = pm_runtime_resume_and_get(wl->dev); + if (ret < 0) return; - } chip_op = arg; chip_op(wl); @@ -279,11 +274,9 @@ static ssize_t dynamic_ps_timeout_write(struct file *file, if (unlikely(wl->state != WLCORE_STATE_ON)) goto out; - ret = pm_runtime_get_sync(wl->dev); - if (ret < 0) { - pm_runtime_put_noidle(wl->dev); + ret = pm_runtime_resume_and_get(wl->dev); + if (ret < 0) goto out; - } /* In case we're already in PSM, trigger it again to set new timeout * immediately without waiting for re-association @@ -349,11 +342,9 @@ static ssize_t forced_ps_write(struct file *file, if (unlikely(wl->state != WLCORE_STATE_ON)) goto out; - ret = pm_runtime_get_sync(wl->dev); - if (ret < 0) { - pm_runtime_put_noidle(wl->dev); + ret = pm_runtime_resume_and_get(wl->dev); + if (ret < 0) goto out; - } /* In case we're already in PSM, trigger it again to switch mode * immediately without waiting for re-association @@ -831,11 +822,9 @@ static ssize_t rx_streaming_interval_write(struct file *file, wl->conf.rx_streaming.interval = value; - ret = pm_runtime_get_sync(wl->dev); - if (ret < 0) { - pm_runtime_put_noidle(wl->dev); + ret = pm_runtime_resume_and_get(wl->dev); + if (ret < 0) goto out; - } wl12xx_for_each_wlvif_sta(wl, wlvif) { wl1271_recalc_rx_streaming(wl, wlvif); @@ -889,11 +878,9 @@ static ssize_t rx_streaming_always_write(struct file *file, wl->conf.rx_streaming.always = value; - ret = pm_runtime_get_sync(wl->dev); - if (ret < 0) { - pm_runtime_put_noidle(wl->dev); + ret = pm_runtime_resume_and_get(wl->dev); + if (ret < 0) goto out; - } wl12xx_for_each_wlvif_sta(wl, wlvif) { wl1271_recalc_rx_streaming(wl, wlvif); @@ -939,11 +926,9 @@ static ssize_t beacon_filtering_write(struct file *file, mutex_lock(&wl->mutex); - ret = pm_runtime_get_sync(wl->dev); - if (ret < 0) { - pm_runtime_put_noidle(wl->dev); + ret = pm_runtime_resume_and_get(wl->dev); + if (ret < 0) goto out; - } wl12xx_for_each_wlvif(wl, wlvif) { ret = wl1271_acx_beacon_filter_opt(wl, wlvif, !!value); @@ -1021,11 +1006,9 @@ static ssize_t sleep_auth_write(struct file *file, goto out; } - ret = pm_runtime_get_sync(wl->dev); - if (ret < 0) { - pm_runtime_put_noidle(wl->dev); + ret = pm_runtime_resume_and_get(wl->dev); + if (ret < 0) goto out; - } ret = wl1271_acx_sleep_auth(wl, value); if (ret < 0) @@ -1254,9 +1237,8 @@ static ssize_t fw_logger_write(struct file *file, } mutex_lock(&wl->mutex); - ret = pm_runtime_get_sync(wl->dev); + ret = pm_runtime_resume_and_get(wl->dev); if (ret < 0) { - pm_runtime_put_noidle(wl->dev); count = ret; goto out; } From e8c241d4a7fa07c0a21a69eb68a98efd818f2a77 Mon Sep 17 00:00:00 2001 From: Lv Ruyi Date: Fri, 8 Apr 2022 09:58:03 +0000 Subject: [PATCH 133/228] rtlwifi: Fix spelling mistake "cacluated" -> "calculated" There are some spelling mistakes in the comments. Fix it. Reported-by: Zeal Robot Signed-off-by: Lv Ruyi Acked-by: Ping-Ke Shih Signed-off-by: Kalle Valo Link: https://lore.kernel.org/r/20220408095803.2495336-1-lv.ruyi@zte.com.cn --- drivers/net/wireless/realtek/rtlwifi/rtl8188ee/trx.c | 4 ++-- drivers/net/wireless/realtek/rtlwifi/rtl8192ce/trx.c | 2 +- drivers/net/wireless/realtek/rtlwifi/rtl8192ee/trx.c | 4 ++-- drivers/net/wireless/realtek/rtlwifi/rtl8723ae/trx.c | 4 ++-- drivers/net/wireless/realtek/rtlwifi/rtl8723be/trx.c | 4 ++-- drivers/net/wireless/realtek/rtlwifi/rtl8821ae/trx.c | 4 ++-- 6 files changed, 11 insertions(+), 11 deletions(-) diff --git a/drivers/net/wireless/realtek/rtlwifi/rtl8188ee/trx.c b/drivers/net/wireless/realtek/rtlwifi/rtl8188ee/trx.c index 257816563fa0e..6e4741e9483f6 100644 --- a/drivers/net/wireless/realtek/rtlwifi/rtl8188ee/trx.c +++ b/drivers/net/wireless/realtek/rtlwifi/rtl8188ee/trx.c @@ -58,7 +58,7 @@ static void _rtl88ee_query_rxphystatus(struct ieee80211_hw *hw, cck_agc_rpt = cck_buf->cck_agc_rpt; /* (1)Hardware does not provide RSSI for CCK - * (2)PWDB, Average PWDB cacluated by + * (2)PWDB, Average PWDB calculated by * hardware (for rate adaptive) */ if (ppsc->rfpwr_state == ERFON) @@ -187,7 +187,7 @@ static void _rtl88ee_query_rxphystatus(struct ieee80211_hw *hw, pstatus->rx_mimo_signalstrength[i] = (u8)rssi; } - /* (2)PWDB, Average PWDB cacluated by + /* (2)PWDB, Average PWDB calculated by * hardware (for rate adaptive) */ rx_pwr_all = ((p_drvinfo->pwdb_all >> 1) & 0x7f) - 110; diff --git a/drivers/net/wireless/realtek/rtlwifi/rtl8192ce/trx.c b/drivers/net/wireless/realtek/rtlwifi/rtl8192ce/trx.c index fdbd3758cde18..730c7e939bd2e 100644 --- a/drivers/net/wireless/realtek/rtlwifi/rtl8192ce/trx.c +++ b/drivers/net/wireless/realtek/rtlwifi/rtl8192ce/trx.c @@ -166,7 +166,7 @@ static void _rtl92ce_query_rxphystatus(struct ieee80211_hw *hw, pstats->rx_mimo_signalstrength[i] = (u8) rssi; } - /* (2)PWDB, Average PWDB cacluated by + /* (2)PWDB, Average PWDB calculated by * hardware (for rate adaptive) */ rx_pwr_all = ((p_drvinfo->pwdb_all >> 1) & 0x7f) - 110; diff --git a/drivers/net/wireless/realtek/rtlwifi/rtl8192ee/trx.c b/drivers/net/wireless/realtek/rtlwifi/rtl8192ee/trx.c index 272750612abf4..8043d819fb855 100644 --- a/drivers/net/wireless/realtek/rtlwifi/rtl8192ee/trx.c +++ b/drivers/net/wireless/realtek/rtlwifi/rtl8192ee/trx.c @@ -55,7 +55,7 @@ static void _rtl92ee_query_rxphystatus(struct ieee80211_hw *hw, cck_agc_rpt = p_phystrpt->cck_agc_rpt_ofdm_cfosho_a; /* (1)Hardware does not provide RSSI for CCK - * (2)PWDB, Average PWDB cacluated by + * (2)PWDB, Average PWDB calculated by * hardware (for rate adaptive) */ cck_highpwr = (u8)rtl_get_bbreg(hw, RFPGA0_XA_HSSIPARAMETER2, @@ -153,7 +153,7 @@ static void _rtl92ee_query_rxphystatus(struct ieee80211_hw *hw, pstatus->rx_mimo_signalstrength[i] = (u8)rssi; } - /* (2)PWDB, Average PWDB cacluated by + /* (2)PWDB, Average PWDB calculated by * hardware (for rate adaptive) */ rx_pwr_all = ((p_phystrpt->cck_sig_qual_ofdm_pwdb_all >> 1) diff --git a/drivers/net/wireless/realtek/rtlwifi/rtl8723ae/trx.c b/drivers/net/wireless/realtek/rtlwifi/rtl8723ae/trx.c index 3797a1e2af826..27fddbcade325 100644 --- a/drivers/net/wireless/realtek/rtlwifi/rtl8723ae/trx.c +++ b/drivers/net/wireless/realtek/rtlwifi/rtl8723ae/trx.c @@ -52,7 +52,7 @@ static void _rtl8723e_query_rxphystatus(struct ieee80211_hw *hw, cck_buf = (struct phy_sts_cck_8723e_t *)p_drvinfo; /* (1)Hardware does not provide RSSI for CCK */ - /* (2)PWDB, Average PWDB cacluated by + /* (2)PWDB, Average PWDB calculated by * hardware (for rate adaptive) */ if (ppsc->rfpwr_state == ERFON) @@ -170,7 +170,7 @@ static void _rtl8723e_query_rxphystatus(struct ieee80211_hw *hw, pstatus->rx_mimo_signalstrength[i] = (u8)rssi; } - /* (2)PWDB, Average PWDB cacluated by + /* (2)PWDB, Average PWDB calculated by * hardware (for rate adaptive) */ rx_pwr_all = ((p_drvinfo->pwdb_all >> 1) & 0x7f) - 110; diff --git a/drivers/net/wireless/realtek/rtlwifi/rtl8723be/trx.c b/drivers/net/wireless/realtek/rtlwifi/rtl8723be/trx.c index c08f57e487e50..24ef7cc52e995 100644 --- a/drivers/net/wireless/realtek/rtlwifi/rtl8723be/trx.c +++ b/drivers/net/wireless/realtek/rtlwifi/rtl8723be/trx.c @@ -55,7 +55,7 @@ static void _rtl8723be_query_rxphystatus(struct ieee80211_hw *hw, cck_agc_rpt = p_phystrpt->cck_agc_rpt_ofdm_cfosho_a; /* (1)Hardware does not provide RSSI for CCK */ - /* (2)PWDB, Average PWDB cacluated by + /* (2)PWDB, Average PWDB calculated by * hardware (for rate adaptive) */ rtl_get_bbreg(hw, RFPGA0_XA_HSSIPARAMETER2, BIT(9)); @@ -126,7 +126,7 @@ static void _rtl8723be_query_rxphystatus(struct ieee80211_hw *hw, pstatus->rx_mimo_signalstrength[i] = (u8)rssi; } - /* (2)PWDB, Average PWDB cacluated by + /* (2)PWDB, Average PWDB calculated by * hardware (for rate adaptive) */ rx_pwr_all = ((p_phystrpt->cck_sig_qual_ofdm_pwdb_all >> 1) & diff --git a/drivers/net/wireless/realtek/rtlwifi/rtl8821ae/trx.c b/drivers/net/wireless/realtek/rtlwifi/rtl8821ae/trx.c index 8c48108960b9c..d7cb3319d8851 100644 --- a/drivers/net/wireless/realtek/rtlwifi/rtl8821ae/trx.c +++ b/drivers/net/wireless/realtek/rtlwifi/rtl8821ae/trx.c @@ -86,7 +86,7 @@ static void query_rxphystatus(struct ieee80211_hw *hw, cck_agc_rpt = p_phystrpt->cfosho[0]; /* (1)Hardware does not provide RSSI for CCK - * (2)PWDB, Average PWDB cacluated by + * (2)PWDB, Average PWDB calculated by * hardware (for rate adaptive) */ cck_highpwr = (u8)rtlphy->cck_high_power; @@ -215,7 +215,7 @@ static void query_rxphystatus(struct ieee80211_hw *hw, pstatus->rx_mimo_signalstrength[i] = (u8)rssi; } - /* (2)PWDB, Average PWDB cacluated by + /* (2)PWDB, Average PWDB calculated by * hardware (for rate adaptive) */ rx_pwr_all = ((p_drvinfo->pwdb_all >> 1) & 0x7f) - 110; From 780d9c48a05a2945912a9f7e0f511c8024e38f40 Mon Sep 17 00:00:00 2001 From: Lv Ruyi Date: Mon, 11 Apr 2022 03:24:58 +0000 Subject: [PATCH 134/228] rtlwifi: rtl8192cu: Fix spelling mistake "writting" -> "writing" There are some spelling mistakes in the comments. Fix it. Reported-by: Zeal Robot Signed-off-by: Lv Ruyi Acked-by: Ping-Ke Shih Signed-off-by: Kalle Valo Link: https://lore.kernel.org/r/20220411032458.2517551-1-lv.ruyi@zte.com.cn --- drivers/net/wireless/realtek/rtlwifi/rtl8192cu/hw.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/net/wireless/realtek/rtlwifi/rtl8192cu/hw.c b/drivers/net/wireless/realtek/rtlwifi/rtl8192cu/hw.c index 9bd02c3c3adcd..a040c07791d1b 100644 --- a/drivers/net/wireless/realtek/rtlwifi/rtl8192cu/hw.c +++ b/drivers/net/wireless/realtek/rtlwifi/rtl8192cu/hw.c @@ -520,7 +520,7 @@ static void _rtl92cu_init_queue_reserved_page(struct ieee80211_hw *hw, * 2 out-ep. Remainder pages have assigned to High queue */ if (outepnum > 1 && txqremaininpage) numhq += txqremaininpage; - /* NOTE: This step done before writting REG_RQPN. */ + /* NOTE: This step done before writing REG_RQPN. */ if (ischipn) { if (queue_sel & TX_SELE_NQ) numnq = txqpageunit; @@ -539,7 +539,7 @@ static void _rtl92cu_init_queue_reserved_page(struct ieee80211_hw *hw, numlq = ischipn ? WMM_CHIP_B_PAGE_NUM_LPQ : WMM_CHIP_A_PAGE_NUM_LPQ; } - /* NOTE: This step done before writting REG_RQPN. */ + /* NOTE: This step done before writing REG_RQPN. */ if (ischipn) { if (queue_sel & TX_SELE_NQ) numnq = WMM_CHIP_B_PAGE_NUM_NPQ; From aa7f148bedcaab5b6f6072de6154f36f8876e118 Mon Sep 17 00:00:00 2001 From: Ping-Ke Shih Date: Wed, 13 Apr 2022 09:08:01 +0800 Subject: [PATCH 135/228] rtw89: extend H2C of CMAC control info In order to support new chip that has capability of 160M, we need new format to fill new information, so add a new V1 ID for newer use. Since most fields are the same, fill fields according to the function ID of chip. Signed-off-by: Ping-Ke Shih Signed-off-by: Kalle Valo Link: https://lore.kernel.org/r/20220413010804.8941-2-pkshih@realtek.com --- drivers/net/wireless/realtek/rtw89/core.h | 3 +- drivers/net/wireless/realtek/rtw89/fw.c | 47 ++++++++++++------- drivers/net/wireless/realtek/rtw89/fw.h | 43 ++++++++++++++--- drivers/net/wireless/realtek/rtw89/rtw8852a.c | 1 + drivers/net/wireless/realtek/rtw89/rtw8852c.c | 1 + 5 files changed, 72 insertions(+), 23 deletions(-) diff --git a/drivers/net/wireless/realtek/rtw89/core.h b/drivers/net/wireless/realtek/rtw89/core.h index ec181c1989bc6..2715dc1ff73ff 100644 --- a/drivers/net/wireless/realtek/rtw89/core.h +++ b/drivers/net/wireless/realtek/rtw89/core.h @@ -578,7 +578,7 @@ enum rtw89_ps_mode { #define RTW89_2G_BW_NUM (RTW89_CHANNEL_WIDTH_40 + 1) #define RTW89_5G_BW_NUM (RTW89_CHANNEL_WIDTH_160 + 1) #define RTW89_6G_BW_NUM (RTW89_CHANNEL_WIDTH_160 + 1) -#define RTW89_PPE_BW_NUM (RTW89_CHANNEL_WIDTH_80 + 1) +#define RTW89_PPE_BW_NUM (RTW89_CHANNEL_WIDTH_160 + 1) enum rtw89_ru_bandwidth { RTW89_RU26 = 0, @@ -2413,6 +2413,7 @@ struct rtw89_chip_info { const struct rtw89_btc_rf_trx_para *rf_para_dlink; u8 ps_mode_supported; + u32 h2c_cctl_func_id; u32 hci_func_en_addr; u32 h2c_desc_size; u32 txwd_body_size; diff --git a/drivers/net/wireless/realtek/rtw89/fw.c b/drivers/net/wireless/realtek/rtw89/fw.c index 986d6249c1084..bd07d2b83d077 100644 --- a/drivers/net/wireless/realtek/rtw89/fw.c +++ b/drivers/net/wireless/realtek/rtw89/fw.c @@ -780,6 +780,7 @@ int rtw89_fw_h2c_lps_parm(struct rtw89_dev *rtwdev, int rtw89_fw_h2c_default_cmac_tbl(struct rtw89_dev *rtwdev, struct rtw89_vif *rtwvif) { + const struct rtw89_chip_info *chip = rtwdev->chip; struct rtw89_hal *hal = &rtwdev->hal; struct sk_buff *skb; u8 ntx_path = hal->antenna_tx ? hal->antenna_tx : RF_B; @@ -794,16 +795,18 @@ int rtw89_fw_h2c_default_cmac_tbl(struct rtw89_dev *rtwdev, skb_put(skb, H2C_CMC_TBL_LEN); SET_CTRL_INFO_MACID(skb->data, macid); SET_CTRL_INFO_OPERATION(skb->data, 1); - SET_CMC_TBL_TXPWR_MODE(skb->data, 0); - SET_CMC_TBL_NTX_PATH_EN(skb->data, ntx_path); - SET_CMC_TBL_PATH_MAP_A(skb->data, 0); - SET_CMC_TBL_PATH_MAP_B(skb->data, map_b); - SET_CMC_TBL_PATH_MAP_C(skb->data, 0); - SET_CMC_TBL_PATH_MAP_D(skb->data, 0); - SET_CMC_TBL_ANTSEL_A(skb->data, 0); - SET_CMC_TBL_ANTSEL_B(skb->data, 0); - SET_CMC_TBL_ANTSEL_C(skb->data, 0); - SET_CMC_TBL_ANTSEL_D(skb->data, 0); + if (chip->h2c_cctl_func_id == H2C_FUNC_MAC_CCTLINFO_UD) { + SET_CMC_TBL_TXPWR_MODE(skb->data, 0); + SET_CMC_TBL_NTX_PATH_EN(skb->data, ntx_path); + SET_CMC_TBL_PATH_MAP_A(skb->data, 0); + SET_CMC_TBL_PATH_MAP_B(skb->data, map_b); + SET_CMC_TBL_PATH_MAP_C(skb->data, 0); + SET_CMC_TBL_PATH_MAP_D(skb->data, 0); + SET_CMC_TBL_ANTSEL_A(skb->data, 0); + SET_CMC_TBL_ANTSEL_B(skb->data, 0); + SET_CMC_TBL_ANTSEL_C(skb->data, 0); + SET_CMC_TBL_ANTSEL_D(skb->data, 0); + } SET_CMC_TBL_DOPPLER_CTRL(skb->data, 0); SET_CMC_TBL_TXPWR_TOLERENCE(skb->data, 0); if (rtwvif->net_type == RTW89_NET_TYPE_AP_MODE) @@ -811,7 +814,7 @@ int rtw89_fw_h2c_default_cmac_tbl(struct rtw89_dev *rtwdev, rtw89_h2c_pkt_set_hdr(rtwdev, skb, FWCMD_TYPE_H2C, H2C_CAT_MAC, H2C_CL_MAC_FR_EXCHG, - H2C_FUNC_MAC_CCTLINFO_UD, 0, 1, + chip->h2c_cctl_func_id, 0, 1, H2C_CMC_TBL_LEN); if (rtw89_h2c_tx(rtwdev, skb, false)) { @@ -851,6 +854,8 @@ static void __get_sta_he_pkt_padding(struct rtw89_dev *rtwdev, for (i = 0; i < RTW89_PPE_BW_NUM; i++) pads[i] = pad; + + return; } ru_bitmap = FIELD_GET(IEEE80211_PPE_THRES_RU_INDEX_BITMASK_MASK, ppe_thres_hdr); @@ -885,6 +890,7 @@ int rtw89_fw_h2c_assoc_cmac_tbl(struct rtw89_dev *rtwdev, struct ieee80211_vif *vif, struct ieee80211_sta *sta) { + const struct rtw89_chip_info *chip = rtwdev->chip; struct rtw89_hal *hal = &rtwdev->hal; struct rtw89_sta *rtwsta = sta_to_rtwsta_safe(sta); struct rtw89_vif *rtwvif = (struct rtw89_vif *)vif->drv_priv; @@ -917,9 +923,17 @@ int rtw89_fw_h2c_assoc_cmac_tbl(struct rtw89_dev *rtwdev, else SET_CMC_TBL_ULDL(skb->data, 0); SET_CMC_TBL_MULTI_PORT_ID(skb->data, rtwvif->port); - SET_CMC_TBL_NOMINAL_PKT_PADDING(skb->data, pads[RTW89_CHANNEL_WIDTH_20]); - SET_CMC_TBL_NOMINAL_PKT_PADDING40(skb->data, pads[RTW89_CHANNEL_WIDTH_40]); - SET_CMC_TBL_NOMINAL_PKT_PADDING80(skb->data, pads[RTW89_CHANNEL_WIDTH_80]); + if (chip->h2c_cctl_func_id == H2C_FUNC_MAC_CCTLINFO_UD_V1) { + SET_CMC_TBL_NOMINAL_PKT_PADDING_V1(skb->data, pads[RTW89_CHANNEL_WIDTH_20]); + SET_CMC_TBL_NOMINAL_PKT_PADDING40_V1(skb->data, pads[RTW89_CHANNEL_WIDTH_40]); + SET_CMC_TBL_NOMINAL_PKT_PADDING80_V1(skb->data, pads[RTW89_CHANNEL_WIDTH_80]); + SET_CMC_TBL_NOMINAL_PKT_PADDING160_V1(skb->data, pads[RTW89_CHANNEL_WIDTH_160]); + } else if (chip->h2c_cctl_func_id == H2C_FUNC_MAC_CCTLINFO_UD) { + SET_CMC_TBL_NOMINAL_PKT_PADDING(skb->data, pads[RTW89_CHANNEL_WIDTH_20]); + SET_CMC_TBL_NOMINAL_PKT_PADDING40(skb->data, pads[RTW89_CHANNEL_WIDTH_40]); + SET_CMC_TBL_NOMINAL_PKT_PADDING80(skb->data, pads[RTW89_CHANNEL_WIDTH_80]); + SET_CMC_TBL_NOMINAL_PKT_PADDING160(skb->data, pads[RTW89_CHANNEL_WIDTH_160]); + } if (sta) SET_CMC_TBL_BSR_QUEUE_SIZE_FORMAT(skb->data, sta->deflink.he_cap.has_he); @@ -928,7 +942,7 @@ int rtw89_fw_h2c_assoc_cmac_tbl(struct rtw89_dev *rtwdev, rtw89_h2c_pkt_set_hdr(rtwdev, skb, FWCMD_TYPE_H2C, H2C_CAT_MAC, H2C_CL_MAC_FR_EXCHG, - H2C_FUNC_MAC_CCTLINFO_UD, 0, 1, + chip->h2c_cctl_func_id, 0, 1, H2C_CMC_TBL_LEN); if (rtw89_h2c_tx(rtwdev, skb, false)) { @@ -946,6 +960,7 @@ int rtw89_fw_h2c_assoc_cmac_tbl(struct rtw89_dev *rtwdev, int rtw89_fw_h2c_txtime_cmac_tbl(struct rtw89_dev *rtwdev, struct rtw89_sta *rtwsta) { + const struct rtw89_chip_info *chip = rtwdev->chip; struct sk_buff *skb; skb = rtw89_fw_h2c_alloc_skb_with_hdr(rtwdev, H2C_CMC_TBL_LEN); @@ -967,7 +982,7 @@ int rtw89_fw_h2c_txtime_cmac_tbl(struct rtw89_dev *rtwdev, rtw89_h2c_pkt_set_hdr(rtwdev, skb, FWCMD_TYPE_H2C, H2C_CAT_MAC, H2C_CL_MAC_FR_EXCHG, - H2C_FUNC_MAC_CCTLINFO_UD, 0, 1, + chip->h2c_cctl_func_id, 0, 1, H2C_CMC_TBL_LEN); if (rtw89_h2c_tx(rtwdev, skb, false)) { diff --git a/drivers/net/wireless/realtek/rtw89/fw.h b/drivers/net/wireless/realtek/rtw89/fw.h index 2a010154a8e88..9cba8990b8365 100644 --- a/drivers/net/wireless/realtek/rtw89/fw.h +++ b/drivers/net/wireless/realtek/rtw89/fw.h @@ -973,6 +973,36 @@ static inline void SET_CMC_TBL_ANTSEL_D(void *table, u32 val) le32p_replace_bits((__le32 *)(table) + 14, SET_CMC_TBL_MASK_ANTSEL_D, BIT(31)); } + +#define SET_CMC_TBL_MASK_NOMINAL_PKT_PADDING GENMASK(1, 0) +static inline void SET_CMC_TBL_NOMINAL_PKT_PADDING_V1(void *table, u32 val) +{ + le32p_replace_bits((__le32 *)(table) + 7, val, GENMASK(1, 0)); + le32p_replace_bits((__le32 *)(table) + 15, SET_CMC_TBL_MASK_NOMINAL_PKT_PADDING, + GENMASK(1, 0)); +} + +static inline void SET_CMC_TBL_NOMINAL_PKT_PADDING40_V1(void *table, u32 val) +{ + le32p_replace_bits((__le32 *)(table) + 7, val, GENMASK(3, 2)); + le32p_replace_bits((__le32 *)(table) + 15, SET_CMC_TBL_MASK_NOMINAL_PKT_PADDING, + GENMASK(3, 2)); +} + +static inline void SET_CMC_TBL_NOMINAL_PKT_PADDING80_V1(void *table, u32 val) +{ + le32p_replace_bits((__le32 *)(table) + 7, val, GENMASK(5, 4)); + le32p_replace_bits((__le32 *)(table) + 15, SET_CMC_TBL_MASK_NOMINAL_PKT_PADDING, + GENMASK(5, 4)); +} + +static inline void SET_CMC_TBL_NOMINAL_PKT_PADDING160_V1(void *table, u32 val) +{ + le32p_replace_bits((__le32 *)(table) + 7, val, GENMASK(7, 6)); + le32p_replace_bits((__le32 *)(table) + 15, SET_CMC_TBL_MASK_NOMINAL_PKT_PADDING, + GENMASK(7, 6)); +} + #define SET_CMC_TBL_MASK_ADDR_CAM_INDEX GENMASK(7, 0) static inline void SET_CMC_TBL_ADDR_CAM_INDEX(void *table, u32 val) { @@ -1001,7 +1031,6 @@ static inline void SET_CMC_TBL_DOPPLER_CTRL(void *table, u32 val) le32p_replace_bits((__le32 *)(table) + 15, SET_CMC_TBL_MASK_DOPPLER_CTRL, GENMASK(19, 18)); } -#define SET_CMC_TBL_MASK_NOMINAL_PKT_PADDING GENMASK(1, 0) static inline void SET_CMC_TBL_NOMINAL_PKT_PADDING(void *table, u32 val) { le32p_replace_bits((__le32 *)(table) + 7, val, GENMASK(21, 20)); @@ -1106,13 +1135,14 @@ static inline void SET_CMC_TBL_CSI_GI_LTF(void *table, u32 val) le32p_replace_bits((__le32 *)(table) + 16, SET_CMC_TBL_MASK_CSI_GI_LTF, GENMASK(27, 25)); } -#define SET_CMC_TBL_MASK_CSI_GID_SEL BIT(0) -static inline void SET_CMC_TBL_CSI_GID_SEL(void *table, u32 val) + +static inline void SET_CMC_TBL_NOMINAL_PKT_PADDING160(void *table, u32 val) { - le32p_replace_bits((__le32 *)(table) + 8, val, BIT(29)); - le32p_replace_bits((__le32 *)(table) + 16, SET_CMC_TBL_MASK_CSI_GID_SEL, - BIT(29)); + le32p_replace_bits((__le32 *)(table) + 8, val, GENMASK(29, 28)); + le32p_replace_bits((__le32 *)(table) + 16, SET_CMC_TBL_MASK_NOMINAL_PKT_PADDING, + GENMASK(29, 28)); } + #define SET_CMC_TBL_MASK_CSI_BW GENMASK(1, 0) static inline void SET_CMC_TBL_CSI_BW(void *table, u32 val) { @@ -2170,6 +2200,7 @@ struct rtw89_fw_h2c_rf_reg_info { #define H2C_CL_MAC_FR_EXCHG 0x5 #define H2C_FUNC_MAC_CCTLINFO_UD 0x2 #define H2C_FUNC_MAC_BCN_UPD 0x5 +#define H2C_FUNC_MAC_CCTLINFO_UD_V1 0xa /* CLASS 6 - Address CAM */ #define H2C_CL_MAC_ADDR_CAM_UPDATE 0x6 diff --git a/drivers/net/wireless/realtek/rtw89/rtw8852a.c b/drivers/net/wireless/realtek/rtw89/rtw8852a.c index 9871ed78e44ca..6371bbf7a2fd5 100644 --- a/drivers/net/wireless/realtek/rtw89/rtw8852a.c +++ b/drivers/net/wireless/realtek/rtw89/rtw8852a.c @@ -2147,6 +2147,7 @@ const struct rtw89_chip_info rtw8852a_chip_info = { .ps_mode_supported = BIT(RTW89_PS_MODE_RFOFF) | BIT(RTW89_PS_MODE_CLK_GATED) | BIT(RTW89_PS_MODE_PWR_GATED), + .h2c_cctl_func_id = H2C_FUNC_MAC_CCTLINFO_UD, .hci_func_en_addr = R_AX_HCI_FUNC_EN, .h2c_desc_size = sizeof(struct rtw89_txwd_body), .txwd_body_size = sizeof(struct rtw89_txwd_body), diff --git a/drivers/net/wireless/realtek/rtw89/rtw8852c.c b/drivers/net/wireless/realtek/rtw89/rtw8852c.c index 38b1383307161..d900129c1a7c8 100644 --- a/drivers/net/wireless/realtek/rtw89/rtw8852c.c +++ b/drivers/net/wireless/realtek/rtw89/rtw8852c.c @@ -667,6 +667,7 @@ const struct rtw89_chip_info rtw8852c_chip_info = { .dav_log_efuse_size = 16, .phycap_addr = 0x590, .phycap_size = 0x60, + .h2c_cctl_func_id = H2C_FUNC_MAC_CCTLINFO_UD_V1, .hci_func_en_addr = R_AX_HCI_FUNC_EN_V1, .h2c_desc_size = sizeof(struct rtw89_rxdesc_short), .txwd_body_size = sizeof(struct rtw89_txwd_body_v1), From 04b5983ef700d49cc2b30beee95b7f0ba5693dd3 Mon Sep 17 00:00:00 2001 From: Ping-Ke Shih Date: Wed, 13 Apr 2022 09:08:02 +0800 Subject: [PATCH 136/228] rtw89: add new H2C to configure security CAM via DCTL for V1 chip DCTL is short for D-MAC control that V1 chip uses this H2C to configure security CAM. Implement the callers in next patch. Signed-off-by: Ping-Ke Shih Signed-off-by: Kalle Valo Link: https://lore.kernel.org/r/20220413010804.8941-3-pkshih@realtek.com --- drivers/net/wireless/realtek/rtw89/cam.c | 28 +++ drivers/net/wireless/realtek/rtw89/cam.h | 4 + drivers/net/wireless/realtek/rtw89/fw.c | 35 +++ drivers/net/wireless/realtek/rtw89/fw.h | 306 +++++++++++++++++++++++ 4 files changed, 373 insertions(+) diff --git a/drivers/net/wireless/realtek/rtw89/cam.c b/drivers/net/wireless/realtek/rtw89/cam.c index 34827f174ba1e..08b9779163bb5 100644 --- a/drivers/net/wireless/realtek/rtw89/cam.c +++ b/drivers/net/wireless/realtek/rtw89/cam.c @@ -710,3 +710,31 @@ void rtw89_cam_fill_addr_cam_info(struct rtw89_dev *rtwdev, FWCMD_SET_ADDR_SEC_ENT5(cmd, addr_cam->sec_ent[5]); FWCMD_SET_ADDR_SEC_ENT6(cmd, addr_cam->sec_ent[6]); } + +void rtw89_cam_fill_dctl_sec_cam_info_v1(struct rtw89_dev *rtwdev, + struct rtw89_vif *rtwvif, + struct rtw89_sta *rtwsta, + u8 *cmd) +{ + struct rtw89_addr_cam_entry *addr_cam = rtw89_get_addr_cam_of(rtwvif, rtwsta); + + SET_DCTL_MACID_V1(cmd, rtwsta ? rtwsta->mac_id : rtwvif->mac_id); + SET_DCTL_OPERATION_V1(cmd, 1); + + SET_DCTL_SEC_ENT0_KEYID_V1(cmd, addr_cam->sec_ent_keyid[0]); + SET_DCTL_SEC_ENT1_KEYID_V1(cmd, addr_cam->sec_ent_keyid[1]); + SET_DCTL_SEC_ENT2_KEYID_V1(cmd, addr_cam->sec_ent_keyid[2]); + SET_DCTL_SEC_ENT3_KEYID_V1(cmd, addr_cam->sec_ent_keyid[3]); + SET_DCTL_SEC_ENT4_KEYID_V1(cmd, addr_cam->sec_ent_keyid[4]); + SET_DCTL_SEC_ENT5_KEYID_V1(cmd, addr_cam->sec_ent_keyid[5]); + SET_DCTL_SEC_ENT6_KEYID_V1(cmd, addr_cam->sec_ent_keyid[6]); + + SET_DCTL_SEC_ENT_VALID_V1(cmd, addr_cam->sec_cam_map[0] & 0xff); + SET_DCTL_SEC_ENT0_V1(cmd, addr_cam->sec_ent[0]); + SET_DCTL_SEC_ENT1_V1(cmd, addr_cam->sec_ent[1]); + SET_DCTL_SEC_ENT2_V1(cmd, addr_cam->sec_ent[2]); + SET_DCTL_SEC_ENT3_V1(cmd, addr_cam->sec_ent[3]); + SET_DCTL_SEC_ENT4_V1(cmd, addr_cam->sec_ent[4]); + SET_DCTL_SEC_ENT5_V1(cmd, addr_cam->sec_ent[5]); + SET_DCTL_SEC_ENT6_V1(cmd, addr_cam->sec_ent[6]); +} diff --git a/drivers/net/wireless/realtek/rtw89/cam.h b/drivers/net/wireless/realtek/rtw89/cam.h index 3a6a786530d17..a3931d3e40d26 100644 --- a/drivers/net/wireless/realtek/rtw89/cam.h +++ b/drivers/net/wireless/realtek/rtw89/cam.h @@ -355,6 +355,10 @@ void rtw89_cam_fill_addr_cam_info(struct rtw89_dev *rtwdev, struct rtw89_vif *vif, struct rtw89_sta *rtwsta, const u8 *scan_mac_addr, u8 *cmd); +void rtw89_cam_fill_dctl_sec_cam_info_v1(struct rtw89_dev *rtwdev, + struct rtw89_vif *rtwvif, + struct rtw89_sta *rtwsta, + u8 *cmd); int rtw89_cam_fill_bssid_cam_info(struct rtw89_dev *rtwdev, struct rtw89_vif *vif, u8 *cmd); int rtw89_cam_sec_key_add(struct rtw89_dev *rtwdev, diff --git a/drivers/net/wireless/realtek/rtw89/fw.c b/drivers/net/wireless/realtek/rtw89/fw.c index bd07d2b83d077..7bef8b4288f0c 100644 --- a/drivers/net/wireless/realtek/rtw89/fw.c +++ b/drivers/net/wireless/realtek/rtw89/fw.c @@ -599,6 +599,41 @@ int rtw89_fw_h2c_cam(struct rtw89_dev *rtwdev, struct rtw89_vif *rtwvif, return -EBUSY; } +#define H2C_DCTL_SEC_CAM_LEN 68 +int rtw89_fw_h2c_dctl_sec_cam_v1(struct rtw89_dev *rtwdev, + struct rtw89_vif *rtwvif, + struct rtw89_sta *rtwsta) +{ + struct sk_buff *skb; + + skb = rtw89_fw_h2c_alloc_skb_with_hdr(rtwdev, H2C_DCTL_SEC_CAM_LEN); + if (!skb) { + rtw89_err(rtwdev, "failed to alloc skb for dctl sec cam\n"); + return -ENOMEM; + } + skb_put(skb, H2C_DCTL_SEC_CAM_LEN); + + rtw89_cam_fill_dctl_sec_cam_info_v1(rtwdev, rtwvif, rtwsta, skb->data); + + rtw89_h2c_pkt_set_hdr(rtwdev, skb, FWCMD_TYPE_H2C, + H2C_CAT_MAC, + H2C_CL_MAC_FR_EXCHG, + H2C_FUNC_MAC_DCTLINFO_UD_V1, 0, 0, + H2C_DCTL_SEC_CAM_LEN); + + if (rtw89_h2c_tx(rtwdev, skb, false)) { + rtw89_err(rtwdev, "failed to send h2c\n"); + goto fail; + } + + return 0; +fail: + dev_kfree_skb_any(skb); + + return -EBUSY; +} +EXPORT_SYMBOL(rtw89_fw_h2c_dctl_sec_cam_v1); + #define H2C_BA_CAM_LEN 8 int rtw89_fw_h2c_ba_cam(struct rtw89_dev *rtwdev, struct rtw89_sta *rtwsta, bool valid, struct ieee80211_ampdu_params *params) diff --git a/drivers/net/wireless/realtek/rtw89/fw.h b/drivers/net/wireless/realtek/rtw89/fw.h index 9cba8990b8365..aaabfc0dfd713 100644 --- a/drivers/net/wireless/realtek/rtw89/fw.h +++ b/drivers/net/wireless/realtek/rtw89/fw.h @@ -1151,6 +1151,308 @@ static inline void SET_CMC_TBL_CSI_BW(void *table, u32 val) GENMASK(31, 30)); } +static inline void SET_DCTL_MACID_V1(void *table, u32 val) +{ + le32p_replace_bits((__le32 *)(table) + 0, val, GENMASK(6, 0)); +} + +static inline void SET_DCTL_OPERATION_V1(void *table, u32 val) +{ + le32p_replace_bits((__le32 *)(table) + 0, val, BIT(7)); +} + +#define SET_DCTL_MASK_QOS_FIELD_V1 GENMASK(7, 0) +static inline void SET_DCTL_QOS_FIELD_V1(void *table, u32 val) +{ + le32p_replace_bits((__le32 *)(table) + 1, val, GENMASK(7, 0)); + le32p_replace_bits((__le32 *)(table) + 9, SET_DCTL_MASK_QOS_FIELD_V1, + GENMASK(7, 0)); +} + +#define SET_DCTL_MASK_SET_DCTL_HW_EXSEQ_MACID GENMASK(6, 0) +static inline void SET_DCTL_HW_EXSEQ_MACID_V1(void *table, u32 val) +{ + le32p_replace_bits((__le32 *)(table) + 1, val, GENMASK(14, 8)); + le32p_replace_bits((__le32 *)(table) + 9, SET_DCTL_MASK_SET_DCTL_HW_EXSEQ_MACID, + GENMASK(14, 8)); +} + +#define SET_DCTL_MASK_QOS_DATA BIT(0) +static inline void SET_DCTL_QOS_DATA_V1(void *table, u32 val) +{ + le32p_replace_bits((__le32 *)(table) + 1, val, BIT(15)); + le32p_replace_bits((__le32 *)(table) + 9, SET_DCTL_MASK_QOS_DATA, + BIT(15)); +} + +#define SET_DCTL_MASK_AES_IV_L GENMASK(15, 0) +static inline void SET_DCTL_AES_IV_L_V1(void *table, u32 val) +{ + le32p_replace_bits((__le32 *)(table) + 1, val, GENMASK(31, 16)); + le32p_replace_bits((__le32 *)(table) + 9, SET_DCTL_MASK_AES_IV_L, + GENMASK(31, 16)); +} + +#define SET_DCTL_MASK_AES_IV_H GENMASK(31, 0) +static inline void SET_DCTL_AES_IV_H_V1(void *table, u32 val) +{ + le32p_replace_bits((__le32 *)(table) + 2, val, GENMASK(31, 0)); + le32p_replace_bits((__le32 *)(table) + 10, SET_DCTL_MASK_AES_IV_H, + GENMASK(31, 0)); +} + +#define SET_DCTL_MASK_SEQ0 GENMASK(11, 0) +static inline void SET_DCTL_SEQ0_V1(void *table, u32 val) +{ + le32p_replace_bits((__le32 *)(table) + 3, val, GENMASK(11, 0)); + le32p_replace_bits((__le32 *)(table) + 11, SET_DCTL_MASK_SEQ0, + GENMASK(11, 0)); +} + +#define SET_DCTL_MASK_SEQ1 GENMASK(11, 0) +static inline void SET_DCTL_SEQ1_V1(void *table, u32 val) +{ + le32p_replace_bits((__le32 *)(table) + 3, val, GENMASK(23, 12)); + le32p_replace_bits((__le32 *)(table) + 11, SET_DCTL_MASK_SEQ1, + GENMASK(23, 12)); +} + +#define SET_DCTL_MASK_AMSDU_MAX_LEN GENMASK(2, 0) +static inline void SET_DCTL_AMSDU_MAX_LEN_V1(void *table, u32 val) +{ + le32p_replace_bits((__le32 *)(table) + 3, val, GENMASK(26, 24)); + le32p_replace_bits((__le32 *)(table) + 11, SET_DCTL_MASK_AMSDU_MAX_LEN, + GENMASK(26, 24)); +} + +#define SET_DCTL_MASK_STA_AMSDU_EN BIT(0) +static inline void SET_DCTL_STA_AMSDU_EN_V1(void *table, u32 val) +{ + le32p_replace_bits((__le32 *)(table) + 3, val, BIT(27)); + le32p_replace_bits((__le32 *)(table) + 11, SET_DCTL_MASK_STA_AMSDU_EN, + BIT(27)); +} + +#define SET_DCTL_MASK_CHKSUM_OFLD_EN BIT(0) +static inline void SET_DCTL_CHKSUM_OFLD_EN_V1(void *table, u32 val) +{ + le32p_replace_bits((__le32 *)(table) + 3, val, BIT(28)); + le32p_replace_bits((__le32 *)(table) + 11, SET_DCTL_MASK_CHKSUM_OFLD_EN, + BIT(28)); +} + +#define SET_DCTL_MASK_WITH_LLC BIT(0) +static inline void SET_DCTL_WITH_LLC_V1(void *table, u32 val) +{ + le32p_replace_bits((__le32 *)(table) + 3, val, BIT(29)); + le32p_replace_bits((__le32 *)(table) + 11, SET_DCTL_MASK_WITH_LLC, + BIT(29)); +} + +#define SET_DCTL_MASK_SEQ2 GENMASK(11, 0) +static inline void SET_DCTL_SEQ2_V1(void *table, u32 val) +{ + le32p_replace_bits((__le32 *)(table) + 4, val, GENMASK(11, 0)); + le32p_replace_bits((__le32 *)(table) + 12, SET_DCTL_MASK_SEQ2, + GENMASK(11, 0)); +} + +#define SET_DCTL_MASK_SEQ3 GENMASK(11, 0) +static inline void SET_DCTL_SEQ3_V1(void *table, u32 val) +{ + le32p_replace_bits((__le32 *)(table) + 4, val, GENMASK(23, 12)); + le32p_replace_bits((__le32 *)(table) + 12, SET_DCTL_MASK_SEQ3, + GENMASK(23, 12)); +} + +#define SET_DCTL_MASK_TGT_IND GENMASK(3, 0) +static inline void SET_DCTL_TGT_IND_V1(void *table, u32 val) +{ + le32p_replace_bits((__le32 *)(table) + 4, val, GENMASK(27, 24)); + le32p_replace_bits((__le32 *)(table) + 12, SET_DCTL_MASK_TGT_IND, + GENMASK(27, 24)); +} + +#define SET_DCTL_MASK_TGT_IND_EN BIT(0) +static inline void SET_DCTL_TGT_IND_EN_V1(void *table, u32 val) +{ + le32p_replace_bits((__le32 *)(table) + 4, val, BIT(28)); + le32p_replace_bits((__le32 *)(table) + 12, SET_DCTL_MASK_TGT_IND_EN, + BIT(28)); +} + +#define SET_DCTL_MASK_HTC_LB GENMASK(2, 0) +static inline void SET_DCTL_HTC_LB_V1(void *table, u32 val) +{ + le32p_replace_bits((__le32 *)(table) + 4, val, GENMASK(31, 29)); + le32p_replace_bits((__le32 *)(table) + 12, SET_DCTL_MASK_HTC_LB, + GENMASK(31, 29)); +} + +#define SET_DCTL_MASK_MHDR_LEN GENMASK(4, 0) +static inline void SET_DCTL_MHDR_LEN_V1(void *table, u32 val) +{ + le32p_replace_bits((__le32 *)(table) + 5, val, GENMASK(4, 0)); + le32p_replace_bits((__le32 *)(table) + 13, SET_DCTL_MASK_MHDR_LEN, + GENMASK(4, 0)); +} + +#define SET_DCTL_MASK_VLAN_TAG_VALID BIT(0) +static inline void SET_DCTL_VLAN_TAG_VALID_V1(void *table, u32 val) +{ + le32p_replace_bits((__le32 *)(table) + 5, val, BIT(5)); + le32p_replace_bits((__le32 *)(table) + 13, SET_DCTL_MASK_VLAN_TAG_VALID, + BIT(5)); +} + +#define SET_DCTL_MASK_VLAN_TAG_SEL GENMASK(1, 0) +static inline void SET_DCTL_VLAN_TAG_SEL_V1(void *table, u32 val) +{ + le32p_replace_bits((__le32 *)(table) + 5, val, GENMASK(7, 6)); + le32p_replace_bits((__le32 *)(table) + 13, SET_DCTL_MASK_VLAN_TAG_SEL, + GENMASK(7, 6)); +} + +#define SET_DCTL_MASK_HTC_ORDER BIT(0) +static inline void SET_DCTL_HTC_ORDER_V1(void *table, u32 val) +{ + le32p_replace_bits((__le32 *)(table) + 5, val, BIT(8)); + le32p_replace_bits((__le32 *)(table) + 13, SET_DCTL_MASK_HTC_ORDER, + BIT(8)); +} + +#define SET_DCTL_MASK_SEC_KEY_ID GENMASK(1, 0) +static inline void SET_DCTL_SEC_KEY_ID_V1(void *table, u32 val) +{ + le32p_replace_bits((__le32 *)(table) + 5, val, GENMASK(10, 9)); + le32p_replace_bits((__le32 *)(table) + 13, SET_DCTL_MASK_SEC_KEY_ID, + GENMASK(10, 9)); +} + +#define SET_DCTL_MASK_WAPI BIT(0) +static inline void SET_DCTL_WAPI_V1(void *table, u32 val) +{ + le32p_replace_bits((__le32 *)(table) + 5, val, BIT(15)); + le32p_replace_bits((__le32 *)(table) + 13, SET_DCTL_MASK_WAPI, + BIT(15)); +} + +#define SET_DCTL_MASK_SEC_ENT_MODE GENMASK(1, 0) +static inline void SET_DCTL_SEC_ENT_MODE_V1(void *table, u32 val) +{ + le32p_replace_bits((__le32 *)(table) + 5, val, GENMASK(17, 16)); + le32p_replace_bits((__le32 *)(table) + 13, SET_DCTL_MASK_SEC_ENT_MODE, + GENMASK(17, 16)); +} + +#define SET_DCTL_MASK_SEC_ENTX_KEYID GENMASK(1, 0) +static inline void SET_DCTL_SEC_ENT0_KEYID_V1(void *table, u32 val) +{ + le32p_replace_bits((__le32 *)(table) + 5, val, GENMASK(19, 18)); + le32p_replace_bits((__le32 *)(table) + 13, SET_DCTL_MASK_SEC_ENTX_KEYID, + GENMASK(19, 18)); +} + +static inline void SET_DCTL_SEC_ENT1_KEYID_V1(void *table, u32 val) +{ + le32p_replace_bits((__le32 *)(table) + 5, val, GENMASK(21, 20)); + le32p_replace_bits((__le32 *)(table) + 13, SET_DCTL_MASK_SEC_ENTX_KEYID, + GENMASK(21, 20)); +} + +static inline void SET_DCTL_SEC_ENT2_KEYID_V1(void *table, u32 val) +{ + le32p_replace_bits((__le32 *)(table) + 5, val, GENMASK(23, 22)); + le32p_replace_bits((__le32 *)(table) + 13, SET_DCTL_MASK_SEC_ENTX_KEYID, + GENMASK(23, 22)); +} + +static inline void SET_DCTL_SEC_ENT3_KEYID_V1(void *table, u32 val) +{ + le32p_replace_bits((__le32 *)(table) + 5, val, GENMASK(25, 24)); + le32p_replace_bits((__le32 *)(table) + 13, SET_DCTL_MASK_SEC_ENTX_KEYID, + GENMASK(25, 24)); +} + +static inline void SET_DCTL_SEC_ENT4_KEYID_V1(void *table, u32 val) +{ + le32p_replace_bits((__le32 *)(table) + 5, val, GENMASK(27, 26)); + le32p_replace_bits((__le32 *)(table) + 13, SET_DCTL_MASK_SEC_ENTX_KEYID, + GENMASK(27, 26)); +} + +static inline void SET_DCTL_SEC_ENT5_KEYID_V1(void *table, u32 val) +{ + le32p_replace_bits((__le32 *)(table) + 5, val, GENMASK(29, 28)); + le32p_replace_bits((__le32 *)(table) + 13, SET_DCTL_MASK_SEC_ENTX_KEYID, + GENMASK(29, 28)); +} + +static inline void SET_DCTL_SEC_ENT6_KEYID_V1(void *table, u32 val) +{ + le32p_replace_bits((__le32 *)(table) + 5, val, GENMASK(31, 30)); + le32p_replace_bits((__le32 *)(table) + 13, SET_DCTL_MASK_SEC_ENTX_KEYID, + GENMASK(31, 30)); +} + +#define SET_DCTL_MASK_SEC_ENT_VALID GENMASK(7, 0) +static inline void SET_DCTL_SEC_ENT_VALID_V1(void *table, u32 val) +{ + le32p_replace_bits((__le32 *)(table) + 6, val, GENMASK(7, 0)); + le32p_replace_bits((__le32 *)(table) + 14, SET_DCTL_MASK_SEC_ENT_VALID, + GENMASK(7, 0)); +} + +#define SET_DCTL_MASK_SEC_ENTX GENMASK(7, 0) +static inline void SET_DCTL_SEC_ENT0_V1(void *table, u32 val) +{ + le32p_replace_bits((__le32 *)(table) + 6, val, GENMASK(15, 8)); + le32p_replace_bits((__le32 *)(table) + 14, SET_DCTL_MASK_SEC_ENTX, + GENMASK(15, 8)); +} + +static inline void SET_DCTL_SEC_ENT1_V1(void *table, u32 val) +{ + le32p_replace_bits((__le32 *)(table) + 6, val, GENMASK(23, 16)); + le32p_replace_bits((__le32 *)(table) + 14, SET_DCTL_MASK_SEC_ENTX, + GENMASK(23, 16)); +} + +static inline void SET_DCTL_SEC_ENT2_V1(void *table, u32 val) +{ + le32p_replace_bits((__le32 *)(table) + 6, val, GENMASK(31, 24)); + le32p_replace_bits((__le32 *)(table) + 14, SET_DCTL_MASK_SEC_ENTX, + GENMASK(31, 24)); +} + +static inline void SET_DCTL_SEC_ENT3_V1(void *table, u32 val) +{ + le32p_replace_bits((__le32 *)(table) + 7, val, GENMASK(7, 0)); + le32p_replace_bits((__le32 *)(table) + 15, SET_DCTL_MASK_SEC_ENTX, + GENMASK(7, 0)); +} + +static inline void SET_DCTL_SEC_ENT4_V1(void *table, u32 val) +{ + le32p_replace_bits((__le32 *)(table) + 7, val, GENMASK(15, 8)); + le32p_replace_bits((__le32 *)(table) + 15, SET_DCTL_MASK_SEC_ENTX, + GENMASK(15, 8)); +} + +static inline void SET_DCTL_SEC_ENT5_V1(void *table, u32 val) +{ + le32p_replace_bits((__le32 *)(table) + 7, val, GENMASK(23, 16)); + le32p_replace_bits((__le32 *)(table) + 15, SET_DCTL_MASK_SEC_ENTX, + GENMASK(23, 16)); +} + +static inline void SET_DCTL_SEC_ENT6_V1(void *table, u32 val) +{ + le32p_replace_bits((__le32 *)(table) + 7, val, GENMASK(31, 24)); + le32p_replace_bits((__le32 *)(table) + 15, SET_DCTL_MASK_SEC_ENTX, + GENMASK(31, 24)); +} + static inline void SET_BCN_UPD_PORT(void *h2c, u32 val) { le32p_replace_bits((__le32 *)h2c, val, GENMASK(7, 0)); @@ -2200,6 +2502,7 @@ struct rtw89_fw_h2c_rf_reg_info { #define H2C_CL_MAC_FR_EXCHG 0x5 #define H2C_FUNC_MAC_CCTLINFO_UD 0x2 #define H2C_FUNC_MAC_BCN_UPD 0x5 +#define H2C_FUNC_MAC_DCTLINFO_UD_V1 0x9 #define H2C_FUNC_MAC_CCTLINFO_UD_V1 0xa /* CLASS 6 - Address CAM */ @@ -2267,6 +2570,9 @@ int rtw89_fw_h2c_update_beacon(struct rtw89_dev *rtwdev, struct rtw89_vif *rtwvif); int rtw89_fw_h2c_cam(struct rtw89_dev *rtwdev, struct rtw89_vif *vif, struct rtw89_sta *rtwsta, const u8 *scan_mac_addr); +int rtw89_fw_h2c_dctl_sec_cam_v1(struct rtw89_dev *rtwdev, + struct rtw89_vif *rtwvif, + struct rtw89_sta *rtwsta); void rtw89_fw_c2h_irqsafe(struct rtw89_dev *rtwdev, struct sk_buff *c2h); void rtw89_fw_c2h_work(struct work_struct *work); int rtw89_fw_h2c_role_maintain(struct rtw89_dev *rtwdev, From 0a6f299b6782c522be67074d37e4e0da56389ddc Mon Sep 17 00:00:00 2001 From: Ping-Ke Shih Date: Wed, 13 Apr 2022 09:08:03 +0800 Subject: [PATCH 137/228] rtw89: configure security CAM for V1 chip Add to configure security CAM while mac80211 calls set_key and del_key. Signed-off-by: Ping-Ke Shih Signed-off-by: Kalle Valo Link: https://lore.kernel.org/r/20220413010804.8941-4-pkshih@realtek.com --- drivers/net/wireless/realtek/rtw89/cam.c | 9 +++++++++ drivers/net/wireless/realtek/rtw89/core.h | 15 +++++++++++++++ drivers/net/wireless/realtek/rtw89/rtw8852a.c | 1 + drivers/net/wireless/realtek/rtw89/rtw8852c.c | 1 + 4 files changed, 26 insertions(+) diff --git a/drivers/net/wireless/realtek/rtw89/cam.c b/drivers/net/wireless/realtek/rtw89/cam.c index 08b9779163bb5..8a26adeb23fb2 100644 --- a/drivers/net/wireless/realtek/rtw89/cam.c +++ b/drivers/net/wireless/realtek/rtw89/cam.c @@ -244,6 +244,12 @@ static int rtw89_cam_attach_sec_cam(struct rtw89_dev *rtwdev, addr_cam->sec_ent[key_idx] = sec_cam->sec_cam_idx; addr_cam->sec_entries[key_idx] = sec_cam; set_bit(key_idx, addr_cam->sec_cam_map); + ret = rtw89_chip_h2c_dctl_sec_cam(rtwdev, rtwvif, rtwsta); + if (ret) { + rtw89_err(rtwdev, "failed to update dctl cam sec entry: %d\n", + ret); + return ret; + } ret = rtw89_fw_h2c_cam(rtwdev, rtwvif, rtwsta, NULL); if (ret) { rtw89_err(rtwdev, "failed to update addr cam sec entry: %d\n", @@ -398,6 +404,9 @@ int rtw89_cam_sec_key_del(struct rtw89_dev *rtwdev, clear_bit(key_idx, addr_cam->sec_cam_map); addr_cam->sec_entries[key_idx] = NULL; if (inform_fw) { + ret = rtw89_chip_h2c_dctl_sec_cam(rtwdev, rtwvif, rtwsta); + if (ret) + rtw89_err(rtwdev, "failed to update dctl cam del key: %d\n", ret); ret = rtw89_fw_h2c_cam(rtwdev, rtwvif, rtwsta, NULL); if (ret) rtw89_err(rtwdev, "failed to update cam del key: %d\n", ret); diff --git a/drivers/net/wireless/realtek/rtw89/core.h b/drivers/net/wireless/realtek/rtw89/core.h index 2715dc1ff73ff..090d416569010 100644 --- a/drivers/net/wireless/realtek/rtw89/core.h +++ b/drivers/net/wireless/realtek/rtw89/core.h @@ -2106,6 +2106,9 @@ struct rtw89_chip_ops { int (*stop_sch_tx)(struct rtw89_dev *rtwdev, u8 mac_idx, u32 *tx_en, enum rtw89_sch_tx_sel sel); int (*resume_sch_tx)(struct rtw89_dev *rtwdev, u8 mac_idx, u32 tx_en); + int (*h2c_dctl_sec_cam)(struct rtw89_dev *rtwdev, + struct rtw89_vif *rtwvif, + struct rtw89_sta *rtwsta); void (*btc_set_rfe)(struct rtw89_dev *rtwdev); void (*btc_init_cfg)(struct rtw89_dev *rtwdev); @@ -3634,6 +3637,18 @@ int rtw89_chip_resume_sch_tx(struct rtw89_dev *rtwdev, u8 mac_idx, u32 tx_en) return chip->ops->resume_sch_tx(rtwdev, mac_idx, tx_en); } +static inline +int rtw89_chip_h2c_dctl_sec_cam(struct rtw89_dev *rtwdev, + struct rtw89_vif *rtwvif, + struct rtw89_sta *rtwsta) +{ + const struct rtw89_chip_info *chip = rtwdev->chip; + + if (!chip->ops->h2c_dctl_sec_cam) + return 0; + return chip->ops->h2c_dctl_sec_cam(rtwdev, rtwvif, rtwsta); +} + static inline u8 *get_hdr_bssid(struct ieee80211_hdr *hdr) { __le16 fc = hdr->frame_control; diff --git a/drivers/net/wireless/realtek/rtw89/rtw8852a.c b/drivers/net/wireless/realtek/rtw89/rtw8852a.c index 6371bbf7a2fd5..975c504953049 100644 --- a/drivers/net/wireless/realtek/rtw89/rtw8852a.c +++ b/drivers/net/wireless/realtek/rtw89/rtw8852a.c @@ -2075,6 +2075,7 @@ static const struct rtw89_chip_ops rtw8852a_chip_ops = { .mac_cfg_gnt = rtw89_mac_cfg_gnt, .stop_sch_tx = rtw89_mac_stop_sch_tx, .resume_sch_tx = rtw89_mac_resume_sch_tx, + .h2c_dctl_sec_cam = NULL, .btc_set_rfe = rtw8852a_btc_set_rfe, .btc_init_cfg = rtw8852a_btc_init_cfg, diff --git a/drivers/net/wireless/realtek/rtw89/rtw8852c.c b/drivers/net/wireless/realtek/rtw89/rtw8852c.c index d900129c1a7c8..d56d65661ce08 100644 --- a/drivers/net/wireless/realtek/rtw89/rtw8852c.c +++ b/drivers/net/wireless/realtek/rtw89/rtw8852c.c @@ -645,6 +645,7 @@ static const struct rtw89_chip_ops rtw8852c_chip_ops = { .mac_cfg_gnt = rtw89_mac_cfg_gnt_v1, .stop_sch_tx = rtw89_mac_stop_sch_tx_v1, .resume_sch_tx = rtw89_mac_resume_sch_tx_v1, + .h2c_dctl_sec_cam = rtw89_fw_h2c_dctl_sec_cam_v1, .btc_init_cfg = rtw8852c_btc_init_cfg, }; From dc4246eff026699c48b27d5bae944b664a5c8035 Mon Sep 17 00:00:00 2001 From: Ping-Ke Shih Date: Wed, 13 Apr 2022 09:08:04 +0800 Subject: [PATCH 138/228] rtw89: pci: correct return value handling of rtw89_write16_mdio_mask() Fix wrong checking statement. Fortunately, this wrong code doesn't affect existing chip. Fixes: 740c431c22fe ("rtw89: pci: add register definition to rtw89_pci_info to generalize pci code") Signed-off-by: Ping-Ke Shih Signed-off-by: Kalle Valo Link: https://lore.kernel.org/r/20220413010804.8941-5-pkshih@realtek.com --- drivers/net/wireless/realtek/rtw89/pci.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/net/wireless/realtek/rtw89/pci.c b/drivers/net/wireless/realtek/rtw89/pci.c index dcf907b81cffa..ecb419010f0c2 100644 --- a/drivers/net/wireless/realtek/rtw89/pci.c +++ b/drivers/net/wireless/realtek/rtw89/pci.c @@ -1522,7 +1522,7 @@ rtw89_write16_mdio_mask(struct rtw89_dev *rtwdev, u8 addr, u16 mask, u16 data, u u16 val; ret = rtw89_read16_mdio(rtwdev, addr, speed, &val); - if (!ret) + if (ret) return ret; shift = __ffs(mask); @@ -1530,7 +1530,7 @@ rtw89_write16_mdio_mask(struct rtw89_dev *rtwdev, u8 addr, u16 mask, u16 data, u val |= ((data << shift) & mask); ret = rtw89_write16_mdio(rtwdev, addr, val, speed); - if (!ret) + if (ret) return ret; return 0; From ab589ac24ee1c00be2ae47aba7ef868394b7fa9c Mon Sep 17 00:00:00 2001 From: Minghao Chi Date: Tue, 12 Apr 2022 09:17:42 +0000 Subject: [PATCH 139/228] wlcore: main: use pm_runtime_resume_and_get() instead of pm_runtime_get_sync() Using pm_runtime_resume_and_get is more appropriate for simplifing code Reported-by: Zeal Robot Signed-off-by: Minghao Chi Signed-off-by: Kalle Valo Link: https://lore.kernel.org/r/20220412091742.2533527-1-chi.minghao@zte.com.cn --- drivers/net/wireless/ti/wlcore/main.c | 225 +++++++++----------------- 1 file changed, 75 insertions(+), 150 deletions(-) diff --git a/drivers/net/wireless/ti/wlcore/main.c b/drivers/net/wireless/ti/wlcore/main.c index 8440e09426744..6959efa4bfa9a 100644 --- a/drivers/net/wireless/ti/wlcore/main.c +++ b/drivers/net/wireless/ti/wlcore/main.c @@ -141,11 +141,9 @@ static void wl1271_rx_streaming_enable_work(struct work_struct *work) if (!wl->conf.rx_streaming.interval) goto out; - ret = pm_runtime_get_sync(wl->dev); - if (ret < 0) { - pm_runtime_put_noidle(wl->dev); + ret = pm_runtime_resume_and_get(wl->dev); + if (ret < 0) goto out; - } ret = wl1271_set_rx_streaming(wl, wlvif, true); if (ret < 0) @@ -174,11 +172,9 @@ static void wl1271_rx_streaming_disable_work(struct work_struct *work) if (!test_bit(WLVIF_FLAG_RX_STREAMING_STARTED, &wlvif->flags)) goto out; - ret = pm_runtime_get_sync(wl->dev); - if (ret < 0) { - pm_runtime_put_noidle(wl->dev); + ret = pm_runtime_resume_and_get(wl->dev); + if (ret < 0) goto out; - } ret = wl1271_set_rx_streaming(wl, wlvif, false); if (ret) @@ -223,11 +219,9 @@ static void wlcore_rc_update_work(struct work_struct *work) if (unlikely(wl->state != WLCORE_STATE_ON)) goto out; - ret = pm_runtime_get_sync(wl->dev); - if (ret < 0) { - pm_runtime_put_noidle(wl->dev); + ret = pm_runtime_resume_and_get(wl->dev); + if (ret < 0) goto out; - } if (ieee80211_vif_is_mesh(vif)) { ret = wl1271_acx_set_ht_capabilities(wl, &wlvif->rc_ht_cap, @@ -537,11 +531,9 @@ static int wlcore_irq_locked(struct wl1271 *wl) if (unlikely(wl->state != WLCORE_STATE_ON)) goto out; - ret = pm_runtime_get_sync(wl->dev); - if (ret < 0) { - pm_runtime_put_noidle(wl->dev); + ret = pm_runtime_resume_and_get(wl->dev); + if (ret < 0) goto out; - } while (!done && loopcount--) { smp_mb__after_atomic(); @@ -838,11 +830,9 @@ static void wl12xx_read_fwlog_panic(struct wl1271 *wl) * Do not send a stop fwlog command if the fw is hanged or if * dbgpins are used (due to some fw bug). */ - error = pm_runtime_get_sync(wl->dev); - if (error < 0) { - pm_runtime_put_noidle(wl->dev); + error = pm_runtime_resume_and_get(wl->dev); + if (error < 0) return; - } if (!wl->watchdog_recovery && wl->conf.fwlog.output != WL12XX_FWLOG_OUTPUT_DBG_PINS) wl12xx_cmd_stop_fwlog(wl); @@ -937,11 +927,9 @@ static void wl1271_recovery_work(struct work_struct *work) if (wl->state == WLCORE_STATE_OFF || wl->plt) goto out_unlock; - error = pm_runtime_get_sync(wl->dev); - if (error < 0) { + error = pm_runtime_resume_and_get(wl->dev); + if (error < 0) wl1271_warning("Enable for recovery failed"); - pm_runtime_put_noidle(wl->dev); - } wlcore_disable_interrupts_nosync(wl); if (!test_bit(WL1271_FLAG_INTENDED_FW_RECOVERY, &wl->flags)) { @@ -1741,9 +1729,8 @@ static int __maybe_unused wl1271_op_suspend(struct ieee80211_hw *hw, mutex_lock(&wl->mutex); - ret = pm_runtime_get_sync(wl->dev); + ret = pm_runtime_resume_and_get(wl->dev); if (ret < 0) { - pm_runtime_put_noidle(wl->dev); mutex_unlock(&wl->mutex); return ret; } @@ -1855,11 +1842,9 @@ static int __maybe_unused wl1271_op_resume(struct ieee80211_hw *hw) goto out_sleep; } - ret = pm_runtime_get_sync(wl->dev); - if (ret < 0) { - pm_runtime_put_noidle(wl->dev); + ret = pm_runtime_resume_and_get(wl->dev); + if (ret < 0) goto out; - } wl12xx_for_each_wlvif(wl, wlvif) { if (wlcore_is_p2p_mgmt(wlvif)) @@ -2060,11 +2045,9 @@ static void wlcore_channel_switch_work(struct work_struct *work) vif = wl12xx_wlvif_to_vif(wlvif); ieee80211_chswitch_done(vif, false); - ret = pm_runtime_get_sync(wl->dev); - if (ret < 0) { - pm_runtime_put_noidle(wl->dev); + ret = pm_runtime_resume_and_get(wl->dev); + if (ret < 0) goto out; - } wl12xx_cmd_stop_channel_switch(wl, wlvif); @@ -2131,11 +2114,9 @@ static void wlcore_pending_auth_complete_work(struct work_struct *work) if (!time_after(time_spare, wlvif->pending_auth_reply_time)) goto out; - ret = pm_runtime_get_sync(wl->dev); - if (ret < 0) { - pm_runtime_put_noidle(wl->dev); + ret = pm_runtime_resume_and_get(wl->dev); + if (ret < 0) goto out; - } /* cancel the ROC if active */ wlcore_update_inconn_sta(wl, wlvif, NULL, false); @@ -2591,11 +2572,9 @@ static int wl1271_op_add_interface(struct ieee80211_hw *hw, * Call runtime PM only after possible wl12xx_init_fw() above * is done. Otherwise we do not have interrupts enabled. */ - ret = pm_runtime_get_sync(wl->dev); - if (ret < 0) { - pm_runtime_put_noidle(wl->dev); + ret = pm_runtime_resume_and_get(wl->dev); + if (ret < 0) goto out_unlock; - } if (wl12xx_need_fw_change(wl, vif_count, true)) { wl12xx_force_active_psm(wl); @@ -2691,11 +2670,9 @@ static void __wl1271_op_remove_interface(struct wl1271 *wl, if (!test_bit(WL1271_FLAG_RECOVERY_IN_PROGRESS, &wl->flags)) { /* disable active roles */ - ret = pm_runtime_get_sync(wl->dev); - if (ret < 0) { - pm_runtime_put_noidle(wl->dev); + ret = pm_runtime_resume_and_get(wl->dev); + if (ret < 0) goto deinit; - } if (wlvif->bss_type == BSS_TYPE_STA_BSS || wlvif->bss_type == BSS_TYPE_IBSS) { @@ -3129,11 +3106,9 @@ static int wl1271_op_config(struct ieee80211_hw *hw, u32 changed) if (unlikely(wl->state != WLCORE_STATE_ON)) goto out; - ret = pm_runtime_get_sync(wl->dev); - if (ret < 0) { - pm_runtime_put_noidle(wl->dev); + ret = pm_runtime_resume_and_get(wl->dev); + if (ret < 0) goto out; - } /* configure each interface */ wl12xx_for_each_wlvif(wl, wlvif) { @@ -3213,11 +3188,9 @@ static void wl1271_op_configure_filter(struct ieee80211_hw *hw, if (unlikely(wl->state != WLCORE_STATE_ON)) goto out; - ret = pm_runtime_get_sync(wl->dev); - if (ret < 0) { - pm_runtime_put_noidle(wl->dev); + ret = pm_runtime_resume_and_get(wl->dev); + if (ret < 0) goto out; - } wl12xx_for_each_wlvif(wl, wlvif) { if (wlcore_is_p2p_mgmt(wlvif)) @@ -3470,11 +3443,9 @@ static int wlcore_op_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd, goto out_wake_queues; } - ret = pm_runtime_get_sync(wl->dev); - if (ret < 0) { - pm_runtime_put_noidle(wl->dev); + ret = pm_runtime_resume_and_get(wl->dev); + if (ret < 0) goto out_wake_queues; - } ret = wlcore_hw_set_key(wl, cmd, vif, sta, key_conf); @@ -3622,11 +3593,9 @@ static void wl1271_op_set_default_key_idx(struct ieee80211_hw *hw, goto out_unlock; } - ret = pm_runtime_get_sync(wl->dev); - if (ret < 0) { - pm_runtime_put_noidle(wl->dev); + ret = pm_runtime_resume_and_get(wl->dev); + if (ret < 0) goto out_unlock; - } wlvif->default_key = key_idx; @@ -3659,11 +3628,9 @@ void wlcore_regdomain_config(struct wl1271 *wl) if (unlikely(wl->state != WLCORE_STATE_ON)) goto out; - ret = pm_runtime_get_sync(wl->dev); - if (ret < 0) { - pm_runtime_put_autosuspend(wl->dev); + ret = pm_runtime_resume_and_get(wl->dev); + if (ret < 0) goto out; - } ret = wlcore_cmd_regdomain_config_locked(wl); if (ret < 0) { @@ -3706,11 +3673,9 @@ static int wl1271_op_hw_scan(struct ieee80211_hw *hw, goto out; } - ret = pm_runtime_get_sync(wl->dev); - if (ret < 0) { - pm_runtime_put_noidle(wl->dev); + ret = pm_runtime_resume_and_get(wl->dev); + if (ret < 0) goto out; - } /* fail if there is any role in ROC */ if (find_first_bit(wl->roc_map, WL12XX_MAX_ROLES) < WL12XX_MAX_ROLES) { @@ -3749,11 +3714,9 @@ static void wl1271_op_cancel_hw_scan(struct ieee80211_hw *hw, if (wl->scan.state == WL1271_SCAN_STATE_IDLE) goto out; - ret = pm_runtime_get_sync(wl->dev); - if (ret < 0) { - pm_runtime_put_noidle(wl->dev); + ret = pm_runtime_resume_and_get(wl->dev); + if (ret < 0) goto out; - } if (wl->scan.state != WL1271_SCAN_STATE_DONE) { ret = wl->ops->scan_stop(wl, wlvif); @@ -3800,11 +3763,9 @@ static int wl1271_op_sched_scan_start(struct ieee80211_hw *hw, goto out; } - ret = pm_runtime_get_sync(wl->dev); - if (ret < 0) { - pm_runtime_put_noidle(wl->dev); + ret = pm_runtime_resume_and_get(wl->dev); + if (ret < 0) goto out; - } ret = wl->ops->sched_scan_start(wl, wlvif, req, ies); if (ret < 0) @@ -3834,11 +3795,9 @@ static int wl1271_op_sched_scan_stop(struct ieee80211_hw *hw, if (unlikely(wl->state != WLCORE_STATE_ON)) goto out; - ret = pm_runtime_get_sync(wl->dev); - if (ret < 0) { - pm_runtime_put_noidle(wl->dev); + ret = pm_runtime_resume_and_get(wl->dev); + if (ret < 0) goto out; - } wl->ops->sched_scan_stop(wl, wlvif); @@ -3862,11 +3821,9 @@ static int wl1271_op_set_frag_threshold(struct ieee80211_hw *hw, u32 value) goto out; } - ret = pm_runtime_get_sync(wl->dev); - if (ret < 0) { - pm_runtime_put_noidle(wl->dev); + ret = pm_runtime_resume_and_get(wl->dev); + if (ret < 0) goto out; - } ret = wl1271_acx_frag_threshold(wl, value); if (ret < 0) @@ -3894,11 +3851,9 @@ static int wl1271_op_set_rts_threshold(struct ieee80211_hw *hw, u32 value) goto out; } - ret = pm_runtime_get_sync(wl->dev); - if (ret < 0) { - pm_runtime_put_noidle(wl->dev); + ret = pm_runtime_resume_and_get(wl->dev); + if (ret < 0) goto out; - } wl12xx_for_each_wlvif(wl, wlvif) { ret = wl1271_acx_rts_threshold(wl, wlvif, value); @@ -4653,11 +4608,9 @@ static void wl1271_op_bss_info_changed(struct ieee80211_hw *hw, if (unlikely(!test_bit(WLVIF_FLAG_INITIALIZED, &wlvif->flags))) goto out; - ret = pm_runtime_get_sync(wl->dev); - if (ret < 0) { - pm_runtime_put_noidle(wl->dev); + ret = pm_runtime_resume_and_get(wl->dev); + if (ret < 0) goto out; - } if ((changed & BSS_CHANGED_TXPOWER) && bss_conf->txpower != wlvif->power_level) { @@ -4714,11 +4667,9 @@ static void wlcore_op_change_chanctx(struct ieee80211_hw *hw, mutex_lock(&wl->mutex); - ret = pm_runtime_get_sync(wl->dev); - if (ret < 0) { - pm_runtime_put_noidle(wl->dev); + ret = pm_runtime_resume_and_get(wl->dev); + if (ret < 0) goto out; - } wl12xx_for_each_wlvif(wl, wlvif) { struct ieee80211_vif *vif = wl12xx_wlvif_to_vif(wlvif); @@ -4771,11 +4722,9 @@ static int wlcore_op_assign_vif_chanctx(struct ieee80211_hw *hw, if (unlikely(!test_bit(WLVIF_FLAG_INITIALIZED, &wlvif->flags))) goto out; - ret = pm_runtime_get_sync(wl->dev); - if (ret < 0) { - pm_runtime_put_noidle(wl->dev); + ret = pm_runtime_resume_and_get(wl->dev); + if (ret < 0) goto out; - } wlvif->band = ctx->def.chan->band; wlvif->channel = channel; @@ -4823,11 +4772,9 @@ static void wlcore_op_unassign_vif_chanctx(struct ieee80211_hw *hw, if (unlikely(!test_bit(WLVIF_FLAG_INITIALIZED, &wlvif->flags))) goto out; - ret = pm_runtime_get_sync(wl->dev); - if (ret < 0) { - pm_runtime_put_noidle(wl->dev); + ret = pm_runtime_resume_and_get(wl->dev); + if (ret < 0) goto out; - } if (wlvif->radar_enabled) { wl1271_debug(DEBUG_MAC80211, "Stop radar detection"); @@ -4893,11 +4840,9 @@ wlcore_op_switch_vif_chanctx(struct ieee80211_hw *hw, mutex_lock(&wl->mutex); - ret = pm_runtime_get_sync(wl->dev); - if (ret < 0) { - pm_runtime_put_noidle(wl->dev); + ret = pm_runtime_resume_and_get(wl->dev); + if (ret < 0) goto out; - } for (i = 0; i < n_vifs; i++) { struct wl12xx_vif *wlvif = wl12xx_vif_to_data(vifs[i].vif); @@ -4939,11 +4884,9 @@ static int wl1271_op_conf_tx(struct ieee80211_hw *hw, if (!test_bit(WLVIF_FLAG_INITIALIZED, &wlvif->flags)) goto out; - ret = pm_runtime_get_sync(wl->dev); - if (ret < 0) { - pm_runtime_put_noidle(wl->dev); + ret = pm_runtime_resume_and_get(wl->dev); + if (ret < 0) goto out; - } /* * the txop is confed in units of 32us by the mac80211, @@ -4987,11 +4930,9 @@ static u64 wl1271_op_get_tsf(struct ieee80211_hw *hw, if (unlikely(wl->state != WLCORE_STATE_ON)) goto out; - ret = pm_runtime_get_sync(wl->dev); - if (ret < 0) { - pm_runtime_put_noidle(wl->dev); + ret = pm_runtime_resume_and_get(wl->dev); + if (ret < 0) goto out; - } ret = wl12xx_acx_tsf_info(wl, wlvif, &mactime); if (ret < 0) @@ -5306,11 +5247,9 @@ static int wl12xx_op_sta_state(struct ieee80211_hw *hw, goto out; } - ret = pm_runtime_get_sync(wl->dev); - if (ret < 0) { - pm_runtime_put_noidle(wl->dev); + ret = pm_runtime_resume_and_get(wl->dev); + if (ret < 0) goto out; - } ret = wl12xx_update_sta_state(wl, wlvif, sta, old_state, new_state); @@ -5364,11 +5303,9 @@ static int wl1271_op_ampdu_action(struct ieee80211_hw *hw, ba_bitmap = &wl->links[hlid].ba_bitmap; - ret = pm_runtime_get_sync(wl->dev); - if (ret < 0) { - pm_runtime_put_noidle(wl->dev); + ret = pm_runtime_resume_and_get(wl->dev); + if (ret < 0) goto out; - } wl1271_debug(DEBUG_MAC80211, "mac80211 ampdu: Rx tid %d action %d", tid, action); @@ -5476,11 +5413,9 @@ static int wl12xx_set_bitrate_mask(struct ieee80211_hw *hw, if (wlvif->bss_type == BSS_TYPE_STA_BSS && !test_bit(WLVIF_FLAG_STA_ASSOCIATED, &wlvif->flags)) { - ret = pm_runtime_get_sync(wl->dev); - if (ret < 0) { - pm_runtime_put_noidle(wl->dev); + ret = pm_runtime_resume_and_get(wl->dev); + if (ret < 0) goto out; - } wl1271_set_band_rate(wl, wlvif); wlvif->basic_rate = @@ -5518,11 +5453,9 @@ static void wl12xx_op_channel_switch(struct ieee80211_hw *hw, goto out; } - ret = pm_runtime_get_sync(wl->dev); - if (ret < 0) { - pm_runtime_put_noidle(wl->dev); + ret = pm_runtime_resume_and_get(wl->dev); + if (ret < 0) goto out; - } /* TODO: change mac80211 to pass vif as param */ @@ -5612,11 +5545,9 @@ static void wlcore_op_channel_switch_beacon(struct ieee80211_hw *hw, goto out; } - ret = pm_runtime_get_sync(wl->dev); - if (ret < 0) { - pm_runtime_put_noidle(wl->dev); + ret = pm_runtime_resume_and_get(wl->dev); + if (ret < 0) goto out; - } ret = wl->ops->channel_switch(wl, wlvif, &ch_switch); if (ret) @@ -5667,11 +5598,9 @@ static int wlcore_op_remain_on_channel(struct ieee80211_hw *hw, goto out; } - ret = pm_runtime_get_sync(wl->dev); - if (ret < 0) { - pm_runtime_put_noidle(wl->dev); + ret = pm_runtime_resume_and_get(wl->dev); + if (ret < 0) goto out; - } ret = wl12xx_start_dev(wl, wlvif, chan->band, channel); if (ret < 0) @@ -5724,11 +5653,9 @@ static int wlcore_roc_completed(struct wl1271 *wl) goto out; } - ret = pm_runtime_get_sync(wl->dev); - if (ret < 0) { - pm_runtime_put_noidle(wl->dev); + ret = pm_runtime_resume_and_get(wl->dev); + if (ret < 0) goto out; - } ret = __wlcore_roc_completed(wl); @@ -5810,11 +5737,9 @@ static void wlcore_op_sta_statistics(struct ieee80211_hw *hw, if (unlikely(wl->state != WLCORE_STATE_ON)) goto out; - ret = pm_runtime_get_sync(wl->dev); - if (ret < 0) { - pm_runtime_put_noidle(wl->dev); + ret = pm_runtime_resume_and_get(wl->dev); + if (ret < 0) goto out_sleep; - } ret = wlcore_acx_average_rssi(wl, wlvif, &rssi_dbm); if (ret < 0) From da8e909c99e4525da5ce56814fca5e9cc4a20a63 Mon Sep 17 00:00:00 2001 From: Minghao Chi Date: Wed, 13 Apr 2022 09:34:31 +0000 Subject: [PATCH 140/228] wlcore: sysfs: use pm_runtime_resume_and_get() instead of pm_runtime_get_sync() Using pm_runtime_resume_and_get is more appropriate for simplifing code Reported-by: Zeal Robot Signed-off-by: Minghao Chi Signed-off-by: Kalle Valo Link: https://lore.kernel.org/r/20220413093431.2538254-1-chi.minghao@zte.com.cn --- drivers/net/wireless/ti/wlcore/sysfs.c | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/drivers/net/wireless/ti/wlcore/sysfs.c b/drivers/net/wireless/ti/wlcore/sysfs.c index 35b535c125b67..f0c7e09b314df 100644 --- a/drivers/net/wireless/ti/wlcore/sysfs.c +++ b/drivers/net/wireless/ti/wlcore/sysfs.c @@ -56,11 +56,9 @@ static ssize_t bt_coex_state_store(struct device *dev, if (unlikely(wl->state != WLCORE_STATE_ON)) goto out; - ret = pm_runtime_get_sync(wl->dev); - if (ret < 0) { - pm_runtime_put_noidle(wl->dev); + ret = pm_runtime_resume_and_get(wl->dev); + if (ret < 0) goto out; - } wl1271_acx_sg_enable(wl, wl->sg_enabled); pm_runtime_mark_last_busy(wl->dev); From 3447eebe6084f3d0919e72eafa1b7d19e3f87580 Mon Sep 17 00:00:00 2001 From: Minghao Chi Date: Wed, 13 Apr 2022 09:35:02 +0000 Subject: [PATCH 141/228] wlcore: testmode: use pm_runtime_resume_and_get() instead of pm_runtime_get_sync() Using pm_runtime_resume_and_get is more appropriate for simplifing code Reported-by: Zeal Robot Signed-off-by: Minghao Chi Signed-off-by: Kalle Valo Link: https://lore.kernel.org/r/20220413093502.2538316-1-chi.minghao@zte.com.cn --- drivers/net/wireless/ti/wlcore/testmode.c | 12 ++++-------- 1 file changed, 4 insertions(+), 8 deletions(-) diff --git a/drivers/net/wireless/ti/wlcore/testmode.c b/drivers/net/wireless/ti/wlcore/testmode.c index 3a17b9a8207e2..3f338b8096c77 100644 --- a/drivers/net/wireless/ti/wlcore/testmode.c +++ b/drivers/net/wireless/ti/wlcore/testmode.c @@ -83,11 +83,9 @@ static int wl1271_tm_cmd_test(struct wl1271 *wl, struct nlattr *tb[]) goto out; } - ret = pm_runtime_get_sync(wl->dev); - if (ret < 0) { - pm_runtime_put_noidle(wl->dev); + ret = pm_runtime_resume_and_get(wl->dev); + if (ret < 0) goto out; - } ret = wl1271_cmd_test(wl, buf, buf_len, answer); if (ret < 0) { @@ -158,11 +156,9 @@ static int wl1271_tm_cmd_interrogate(struct wl1271 *wl, struct nlattr *tb[]) goto out; } - ret = pm_runtime_get_sync(wl->dev); - if (ret < 0) { - pm_runtime_put_noidle(wl->dev); + ret = pm_runtime_resume_and_get(wl->dev); + if (ret < 0) goto out; - } cmd = kzalloc(sizeof(*cmd), GFP_KERNEL); if (!cmd) { From d8e11976d8e897ffedca5d1f3b9032156274eceb Mon Sep 17 00:00:00 2001 From: Minghao Chi Date: Wed, 13 Apr 2022 09:39:39 +0000 Subject: [PATCH 142/228] wlcore: vendor_cmd: use pm_runtime_resume_and_get() instead of pm_runtime_get_sync() Using pm_runtime_resume_and_get is more appropriate for simplifing code Reported-by: Zeal Robot Signed-off-by: Minghao Chi Signed-off-by: Kalle Valo Link: https://lore.kernel.org/r/20220413093939.2538825-1-chi.minghao@zte.com.cn --- drivers/net/wireless/ti/wlcore/vendor_cmd.c | 18 ++++++------------ 1 file changed, 6 insertions(+), 12 deletions(-) diff --git a/drivers/net/wireless/ti/wlcore/vendor_cmd.c b/drivers/net/wireless/ti/wlcore/vendor_cmd.c index e1bd344c4ebc8..e4269e2b00981 100644 --- a/drivers/net/wireless/ti/wlcore/vendor_cmd.c +++ b/drivers/net/wireless/ti/wlcore/vendor_cmd.c @@ -53,11 +53,9 @@ wlcore_vendor_cmd_smart_config_start(struct wiphy *wiphy, goto out; } - ret = pm_runtime_get_sync(wl->dev); - if (ret < 0) { - pm_runtime_put_noidle(wl->dev); + ret = pm_runtime_resume_and_get(wl->dev); + if (ret < 0) goto out; - } ret = wlcore_smart_config_start(wl, nla_get_u32(tb[WLCORE_VENDOR_ATTR_GROUP_ID])); @@ -88,11 +86,9 @@ wlcore_vendor_cmd_smart_config_stop(struct wiphy *wiphy, goto out; } - ret = pm_runtime_get_sync(wl->dev); - if (ret < 0) { - pm_runtime_put_noidle(wl->dev); + ret = pm_runtime_resume_and_get(wl->dev); + if (ret < 0) goto out; - } ret = wlcore_smart_config_stop(wl); @@ -135,11 +131,9 @@ wlcore_vendor_cmd_smart_config_set_group_key(struct wiphy *wiphy, goto out; } - ret = pm_runtime_get_sync(wl->dev); - if (ret < 0) { - pm_runtime_put_noidle(wl->dev); + ret = pm_runtime_resume_and_get(wl->dev); + if (ret < 0) goto out; - } ret = wlcore_smart_config_set_group_key(wl, nla_get_u32(tb[WLCORE_VENDOR_ATTR_GROUP_ID]), From 00bfc8964f4349dacc6799fe712de186e9bd8bb8 Mon Sep 17 00:00:00 2001 From: Minghao Chi Date: Tue, 19 Apr 2022 11:04:45 +0000 Subject: [PATCH 143/228] wlcore: sdio: using pm_runtime_resume_and_get() instead of pm_runtime_get_sync() Using pm_runtime_resume_and_get() to replace pm_runtime_get_sync and pm_runtime_put_noidle. This change is just to simplify the code, no actual functional changes. Reported-by: Zeal Robot Signed-off-by: Minghao Chi Signed-off-by: Kalle Valo Link: https://lore.kernel.org/r/20220419110445.2574424-1-chi.minghao@zte.com.cn --- drivers/net/wireless/ti/wlcore/sdio.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/drivers/net/wireless/ti/wlcore/sdio.c b/drivers/net/wireless/ti/wlcore/sdio.c index 72fc41ac83c0d..7b4e8cc36b499 100644 --- a/drivers/net/wireless/ti/wlcore/sdio.c +++ b/drivers/net/wireless/ti/wlcore/sdio.c @@ -132,9 +132,8 @@ static int wl12xx_sdio_power_on(struct wl12xx_sdio_glue *glue) struct sdio_func *func = dev_to_sdio_func(glue->dev); struct mmc_card *card = func->card; - ret = pm_runtime_get_sync(&card->dev); + ret = pm_runtime_resume_and_get(&card->dev); if (ret < 0) { - pm_runtime_put_noidle(&card->dev); dev_err(glue->dev, "%s: failed to get_sync(%d)\n", __func__, ret); From e05c7ddfeb23182421972b9074fb8f5aa356cfee Mon Sep 17 00:00:00 2001 From: Minghao Chi Date: Wed, 20 Apr 2022 09:01:41 +0000 Subject: [PATCH 144/228] wlcore: cmd: using pm_runtime_resume_and_get() instead of pm_runtime_get_sync() Using pm_runtime_resume_and_get() to replace pm_runtime_get_sync and pm_runtime_put_noidle. This change is just to simplify the code, no actual functional changes. Reported-by: Zeal Robot Signed-off-by: Minghao Chi Signed-off-by: Kalle Valo Link: https://lore.kernel.org/r/20220420090141.2588553-1-chi.minghao@zte.com.cn --- drivers/net/wireless/ti/wlcore/cmd.c | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/drivers/net/wireless/ti/wlcore/cmd.c b/drivers/net/wireless/ti/wlcore/cmd.c index 09eb1116be0ee..df6029ef6304d 100644 --- a/drivers/net/wireless/ti/wlcore/cmd.c +++ b/drivers/net/wireless/ti/wlcore/cmd.c @@ -178,11 +178,9 @@ int wlcore_cmd_wait_for_event_or_timeout(struct wl1271 *wl, timeout_time = jiffies + msecs_to_jiffies(WL1271_EVENT_TIMEOUT); - ret = pm_runtime_get_sync(wl->dev); - if (ret < 0) { - pm_runtime_put_noidle(wl->dev); + ret = pm_runtime_resume_and_get(wl->dev); + if (ret < 0) goto free_vector; - } do { if (time_after(jiffies, timeout_time)) { From e2e23a791745a194aa8e6fb4983c2e7b408ab6e1 Mon Sep 17 00:00:00 2001 From: Wen Gong Date: Tue, 12 Apr 2022 16:15:50 +0300 Subject: [PATCH 145/228] ath11k: add support for extended wmi service bit When the WMI service bits are reported from firmware they are divided into multiple segments, with 128 bits in each segment. The first segment is processed by ath11k_wmi_service_bitmap_copy(), the second segment is processed by ath11k_service_available_event() with WMI_TAG_SERVICE_AVAILABLE_EVENT. When the service bit exceed 256 bits, then firmware reports it by tag WMI_TAG_ARRAY_UINT32 in WMI_SERVICE_AVAILABLE_EVENTID. Currently ath11k does not process the third segment. Upcoming features need to know if firmware support is available for the features, so add processing of the third segment. Tested-on: WCN6855 hw2.0 PCI WLAN.HSP.1.1-01720.1-QCAHSPSWPL_V1_V2_SILICONZ_LITE-1 Signed-off-by: Wen Gong Signed-off-by: Baochen Qiang Signed-off-by: Kalle Valo Link: https://lore.kernel.org/r/20220401120948.1312956-2-quic_bqiang@quicinc.com --- drivers/net/wireless/ath/ath11k/wmi.c | 81 ++++++++++++++++----------- drivers/net/wireless/ath/ath11k/wmi.h | 9 ++- 2 files changed, 56 insertions(+), 34 deletions(-) diff --git a/drivers/net/wireless/ath/ath11k/wmi.c b/drivers/net/wireless/ath/ath11k/wmi.c index 3af24b18204ef..a5876e0378fe6 100644 --- a/drivers/net/wireless/ath/ath11k/wmi.c +++ b/drivers/net/wireless/ath/ath11k/wmi.c @@ -7297,47 +7297,64 @@ static void ath11k_vdev_install_key_compl_event(struct ath11k_base *ab, rcu_read_unlock(); } -static void ath11k_service_available_event(struct ath11k_base *ab, struct sk_buff *skb) +static int ath11k_wmi_tlv_services_parser(struct ath11k_base *ab, + u16 tag, u16 len, + const void *ptr, void *data) { - const void **tb; const struct wmi_service_available_event *ev; - int ret; + u32 *wmi_ext2_service_bitmap; int i, j; - tb = ath11k_wmi_tlv_parse_alloc(ab, skb->data, skb->len, GFP_ATOMIC); - if (IS_ERR(tb)) { - ret = PTR_ERR(tb); - ath11k_warn(ab, "failed to parse tlv: %d\n", ret); - return; - } + switch (tag) { + case WMI_TAG_SERVICE_AVAILABLE_EVENT: + ev = (struct wmi_service_available_event *)ptr; + for (i = 0, j = WMI_MAX_SERVICE; + i < WMI_SERVICE_SEGMENT_BM_SIZE32 && j < WMI_MAX_EXT_SERVICE; + i++) { + do { + if (ev->wmi_service_segment_bitmap[i] & + BIT(j % WMI_AVAIL_SERVICE_BITS_IN_SIZE32)) + set_bit(j, ab->wmi_ab.svc_map); + } while (++j % WMI_AVAIL_SERVICE_BITS_IN_SIZE32); + } - ev = tb[WMI_TAG_SERVICE_AVAILABLE_EVENT]; - if (!ev) { - ath11k_warn(ab, "failed to fetch svc available ev"); - kfree(tb); - return; - } + ath11k_dbg(ab, ATH11K_DBG_WMI, + "wmi_ext_service_bitmap 0:0x%04x, 1:0x%04x, 2:0x%04x, 3:0x%04x", + ev->wmi_service_segment_bitmap[0], + ev->wmi_service_segment_bitmap[1], + ev->wmi_service_segment_bitmap[2], + ev->wmi_service_segment_bitmap[3]); + break; + case WMI_TAG_ARRAY_UINT32: + wmi_ext2_service_bitmap = (u32 *)ptr; + for (i = 0, j = WMI_MAX_EXT_SERVICE; + i < WMI_SERVICE_SEGMENT_BM_SIZE32 && j < WMI_MAX_EXT2_SERVICE; + i++) { + do { + if (wmi_ext2_service_bitmap[i] & + BIT(j % WMI_AVAIL_SERVICE_BITS_IN_SIZE32)) + set_bit(j, ab->wmi_ab.svc_map); + } while (++j % WMI_AVAIL_SERVICE_BITS_IN_SIZE32); + } - /* TODO: Use wmi_service_segment_offset information to get the service - * especially when more services are advertised in multiple sevice - * available events. - */ - for (i = 0, j = WMI_MAX_SERVICE; - i < WMI_SERVICE_SEGMENT_BM_SIZE32 && j < WMI_MAX_EXT_SERVICE; - i++) { - do { - if (ev->wmi_service_segment_bitmap[i] & - BIT(j % WMI_AVAIL_SERVICE_BITS_IN_SIZE32)) - set_bit(j, ab->wmi_ab.svc_map); - } while (++j % WMI_AVAIL_SERVICE_BITS_IN_SIZE32); + ath11k_dbg(ab, ATH11K_DBG_WMI, + "wmi_ext2_service__bitmap 0:0x%04x, 1:0x%04x, 2:0x%04x, 3:0x%04x", + wmi_ext2_service_bitmap[0], wmi_ext2_service_bitmap[1], + wmi_ext2_service_bitmap[2], wmi_ext2_service_bitmap[3]); + break; } + return 0; +} - ath11k_dbg(ab, ATH11K_DBG_WMI, - "wmi_ext_service_bitmap 0:0x%x, 1:0x%x, 2:0x%x, 3:0x%x", - ev->wmi_service_segment_bitmap[0], ev->wmi_service_segment_bitmap[1], - ev->wmi_service_segment_bitmap[2], ev->wmi_service_segment_bitmap[3]); +static void ath11k_service_available_event(struct ath11k_base *ab, struct sk_buff *skb) +{ + int ret; - kfree(tb); + ret = ath11k_wmi_tlv_iter(ab, skb->data, skb->len, + ath11k_wmi_tlv_services_parser, + NULL); + if (ret) + ath11k_warn(ab, "failed to parse services available tlv %d\n", ret); } static void ath11k_peer_assoc_conf_event(struct ath11k_base *ab, struct sk_buff *skb) diff --git a/drivers/net/wireless/ath/ath11k/wmi.h b/drivers/net/wireless/ath/ath11k/wmi.h index c9ffefea549cd..4ff7e71409ce8 100644 --- a/drivers/net/wireless/ath/ath11k/wmi.h +++ b/drivers/net/wireless/ath/ath11k/wmi.h @@ -1992,6 +1992,7 @@ enum wmi_tlv_service { WMI_TLV_SERVICE_ACK_TIMEOUT = 126, WMI_TLV_SERVICE_PDEV_BSS_CHANNEL_INFO_64 = 127, + /* The first 128 bits */ WMI_MAX_SERVICE = 128, WMI_TLV_SERVICE_CHAN_LOAD_INFO = 128, @@ -2084,7 +2085,11 @@ enum wmi_tlv_service { WMI_TLV_SERVICE_EXT2_MSG = 220, WMI_TLV_SERVICE_SRG_SRP_SPATIAL_REUSE_SUPPORT = 249, - WMI_MAX_EXT_SERVICE + /* The second 128 bits */ + WMI_MAX_EXT_SERVICE = 256, + + /* The third 128 bits */ + WMI_MAX_EXT2_SERVICE = 384 }; enum { @@ -5370,7 +5375,7 @@ struct ath11k_wmi_base { struct completion service_ready; struct completion unified_ready; - DECLARE_BITMAP(svc_map, WMI_MAX_EXT_SERVICE); + DECLARE_BITMAP(svc_map, WMI_MAX_EXT2_SERVICE); wait_queue_head_t tx_credits_wq; const struct wmi_peer_flags_map *peer_flags; u32 num_mem_chunks; From 652f69ed9c1b4f8ef4ea9d6738f1e6263a5ff26d Mon Sep 17 00:00:00 2001 From: Baochen Qiang Date: Tue, 12 Apr 2022 16:15:50 +0300 Subject: [PATCH 146/228] ath11k: Add support for SAR Add ath11k_mac_op_set_bios_sar_specs() to ath11k_ops, this function is called when user space application calls NL80211_CMD_SET_SAR_SPECS. ath11k also registers SAR type and frequency ranges to wiphy so user space can query SAR capabilities. This feature is currently enabled for WCN6855. Tested-on: WCN6855 hw2.0 PCI WLAN.HSP.1.1-02431-QCAHSPSWPL_V1_V2_SILICONZ_LITE-1 Signed-off-by: Baochen Qiang Signed-off-by: Kalle Valo Link: https://lore.kernel.org/r/20220401120948.1312956-3-quic_bqiang@quicinc.com --- drivers/net/wireless/ath/ath11k/core.c | 6 +++ drivers/net/wireless/ath/ath11k/hw.c | 20 ++++++++ drivers/net/wireless/ath/ath11k/hw.h | 2 + drivers/net/wireless/ath/ath11k/mac.c | 67 ++++++++++++++++++++++++ drivers/net/wireless/ath/ath11k/wmi.c | 70 ++++++++++++++++++++++++++ drivers/net/wireless/ath/ath11k/wmi.h | 27 ++++++++++ 6 files changed, 192 insertions(+) diff --git a/drivers/net/wireless/ath/ath11k/core.c b/drivers/net/wireless/ath/ath11k/core.c index 1537ec0ae2e7e..f011db4bcd2b2 100644 --- a/drivers/net/wireless/ath/ath11k/core.c +++ b/drivers/net/wireless/ath/ath11k/core.c @@ -101,6 +101,7 @@ static const struct ath11k_hw_params ath11k_hw_params[] = { .current_cc_support = false, .dbr_debug_support = true, .global_reset = false, + .bios_sar_capa = NULL, }, { .hw_rev = ATH11K_HW_IPQ6018_HW10, @@ -167,6 +168,7 @@ static const struct ath11k_hw_params ath11k_hw_params[] = { .current_cc_support = false, .dbr_debug_support = true, .global_reset = false, + .bios_sar_capa = NULL, }, { .name = "qca6390 hw2.0", @@ -232,6 +234,7 @@ static const struct ath11k_hw_params ath11k_hw_params[] = { .current_cc_support = true, .dbr_debug_support = false, .global_reset = true, + .bios_sar_capa = NULL, }, { .name = "qcn9074 hw1.0", @@ -297,6 +300,7 @@ static const struct ath11k_hw_params ath11k_hw_params[] = { .current_cc_support = false, .dbr_debug_support = true, .global_reset = false, + .bios_sar_capa = NULL, }, { .name = "wcn6855 hw2.0", @@ -362,6 +366,7 @@ static const struct ath11k_hw_params ath11k_hw_params[] = { .current_cc_support = true, .dbr_debug_support = false, .global_reset = true, + .bios_sar_capa = &ath11k_hw_sar_capa_wcn6855, }, { .name = "wcn6855 hw2.1", @@ -426,6 +431,7 @@ static const struct ath11k_hw_params ath11k_hw_params[] = { .current_cc_support = true, .dbr_debug_support = false, .global_reset = true, + .bios_sar_capa = &ath11k_hw_sar_capa_wcn6855, }, }; diff --git a/drivers/net/wireless/ath/ath11k/hw.c b/drivers/net/wireless/ath/ath11k/hw.c index d1b0e76d9ec29..46449a18b5cb9 100644 --- a/drivers/net/wireless/ath/ath11k/hw.c +++ b/drivers/net/wireless/ath/ath11k/hw.c @@ -2154,3 +2154,23 @@ const struct ath11k_hw_hal_params ath11k_hw_hal_params_ipq8074 = { const struct ath11k_hw_hal_params ath11k_hw_hal_params_qca6390 = { .rx_buf_rbm = HAL_RX_BUF_RBM_SW1_BM, }; + +static const struct cfg80211_sar_freq_ranges ath11k_hw_sar_freq_ranges_wcn6855[] = { + {.start_freq = 2402, .end_freq = 2482 }, /* 2G ch1~ch13 */ + {.start_freq = 5150, .end_freq = 5250 }, /* 5G UNII-1 ch32~ch48 */ + {.start_freq = 5250, .end_freq = 5725 }, /* 5G UNII-2 ch50~ch144 */ + {.start_freq = 5725, .end_freq = 5810 }, /* 5G UNII-3 ch149~ch161 */ + {.start_freq = 5815, .end_freq = 5895 }, /* 5G UNII-4 ch163~ch177 */ + {.start_freq = 5925, .end_freq = 6165 }, /* 6G UNII-5 Ch1, Ch2 ~ Ch41 */ + {.start_freq = 6165, .end_freq = 6425 }, /* 6G UNII-5 ch45~ch93 */ + {.start_freq = 6425, .end_freq = 6525 }, /* 6G UNII-6 ch97~ch113 */ + {.start_freq = 6525, .end_freq = 6705 }, /* 6G UNII-7 ch117~ch149 */ + {.start_freq = 6705, .end_freq = 6875 }, /* 6G UNII-7 ch153~ch185 */ + {.start_freq = 6875, .end_freq = 7125 }, /* 6G UNII-8 ch189~ch233 */ +}; + +const struct cfg80211_sar_capa ath11k_hw_sar_capa_wcn6855 = { + .type = NL80211_SAR_TYPE_POWER, + .num_freq_ranges = (ARRAY_SIZE(ath11k_hw_sar_freq_ranges_wcn6855)), + .freq_ranges = ath11k_hw_sar_freq_ranges_wcn6855, +}; diff --git a/drivers/net/wireless/ath/ath11k/hw.h b/drivers/net/wireless/ath/ath11k/hw.h index 08f958c03ec45..b7ece3d5678c3 100644 --- a/drivers/net/wireless/ath/ath11k/hw.h +++ b/drivers/net/wireless/ath/ath11k/hw.h @@ -195,6 +195,7 @@ struct ath11k_hw_params { bool current_cc_support; bool dbr_debug_support; bool global_reset; + const struct cfg80211_sar_capa *bios_sar_capa; }; struct ath11k_hw_ops { @@ -380,4 +381,5 @@ static inline const char *ath11k_bd_ie_type_str(enum ath11k_bd_ie_type type) return "unknown"; } +extern const struct cfg80211_sar_capa ath11k_hw_sar_capa_wcn6855; #endif diff --git a/drivers/net/wireless/ath/ath11k/mac.c b/drivers/net/wireless/ath/ath11k/mac.c index 175a4ae752f3a..12fd307426646 100644 --- a/drivers/net/wireless/ath/ath11k/mac.c +++ b/drivers/net/wireless/ath/ath11k/mac.c @@ -8273,6 +8273,68 @@ static void ath11k_mac_op_set_rekey_data(struct ieee80211_hw *hw, mutex_unlock(&ar->conf_mutex); } +static int ath11k_mac_op_set_bios_sar_specs(struct ieee80211_hw *hw, + const struct cfg80211_sar_specs *sar) +{ + struct ath11k *ar = hw->priv; + const struct cfg80211_sar_sub_specs *sspec = sar->sub_specs; + int ret, index; + u8 *sar_tbl; + u32 i; + + mutex_lock(&ar->conf_mutex); + + if (!test_bit(WMI_TLV_SERVICE_BIOS_SAR_SUPPORT, ar->ab->wmi_ab.svc_map) || + !ar->ab->hw_params.bios_sar_capa) { + ret = -EOPNOTSUPP; + goto exit; + } + + if (!sar || sar->type != NL80211_SAR_TYPE_POWER || + sar->num_sub_specs == 0) { + ret = -EINVAL; + goto exit; + } + + ret = ath11k_wmi_pdev_set_bios_geo_table_param(ar); + if (ret) { + ath11k_warn(ar->ab, "failed to set geo table: %d\n", ret); + goto exit; + } + + sar_tbl = kzalloc(BIOS_SAR_TABLE_LEN, GFP_KERNEL); + if (!sar_tbl) { + ret = -ENOMEM; + goto exit; + } + + for (i = 0; i < sar->num_sub_specs; i++) { + if (sspec->freq_range_index >= (BIOS_SAR_TABLE_LEN >> 1)) { + ath11k_warn(ar->ab, "Ignore bad frequency index %u, max allowed %u\n", + sspec->freq_range_index, BIOS_SAR_TABLE_LEN >> 1); + continue; + } + + /* chain0 and chain1 share same power setting */ + sar_tbl[sspec->freq_range_index] = sspec->power; + index = sspec->freq_range_index + (BIOS_SAR_TABLE_LEN >> 1); + sar_tbl[index] = sspec->power; + ath11k_dbg(ar->ab, ATH11K_DBG_MAC, "sar tbl[%d] = %d\n", + sspec->freq_range_index, sar_tbl[sspec->freq_range_index]); + sspec++; + } + + ret = ath11k_wmi_pdev_set_bios_sar_table_param(ar, sar_tbl); + if (ret) + ath11k_warn(ar->ab, "failed to set sar power: %d", ret); + + kfree(sar_tbl); +exit: + mutex_unlock(&ar->conf_mutex); + + return ret; +} + static const struct ieee80211_ops ath11k_ops = { .tx = ath11k_mac_op_tx, .start = ath11k_mac_op_start, @@ -8324,6 +8386,7 @@ static const struct ieee80211_ops ath11k_ops = { .ipv6_addr_change = ath11k_mac_op_ipv6_changed, #endif + .set_sar_specs = ath11k_mac_op_set_bios_sar_specs, }; static void ath11k_mac_update_ch_list(struct ath11k *ar, @@ -8746,6 +8809,10 @@ static int __ath11k_mac_register(struct ath11k *ar) ieee80211_hw_set(ar->hw, SUPPORT_FAST_XMIT); } + if (test_bit(WMI_TLV_SERVICE_BIOS_SAR_SUPPORT, ar->ab->wmi_ab.svc_map) && + ab->hw_params.bios_sar_capa) + ar->hw->wiphy->sar_capa = ab->hw_params.bios_sar_capa; + ret = ieee80211_register_hw(ar->hw); if (ret) { ath11k_err(ar->ab, "ieee80211 registration failed: %d\n", ret); diff --git a/drivers/net/wireless/ath/ath11k/wmi.c b/drivers/net/wireless/ath/ath11k/wmi.c index a5876e0378fe6..dcf31bdad47ef 100644 --- a/drivers/net/wireless/ath/ath11k/wmi.c +++ b/drivers/net/wireless/ath/ath11k/wmi.c @@ -8883,3 +8883,73 @@ int ath11k_wmi_gtk_rekey_getinfo(struct ath11k *ar, arvif->vdev_id); return ath11k_wmi_cmd_send(ar->wmi, skb, WMI_GTK_OFFLOAD_CMDID); } + +int ath11k_wmi_pdev_set_bios_sar_table_param(struct ath11k *ar, const u8 *sar_val) +{ struct ath11k_pdev_wmi *wmi = ar->wmi; + struct wmi_pdev_set_sar_table_cmd *cmd; + struct wmi_tlv *tlv; + struct sk_buff *skb; + u8 *buf_ptr; + u32 len, sar_len_aligned, rsvd_len_aligned; + + sar_len_aligned = roundup(BIOS_SAR_TABLE_LEN, sizeof(u32)); + rsvd_len_aligned = roundup(BIOS_SAR_RSVD1_LEN, sizeof(u32)); + len = sizeof(*cmd) + + TLV_HDR_SIZE + sar_len_aligned + + TLV_HDR_SIZE + rsvd_len_aligned; + + skb = ath11k_wmi_alloc_skb(wmi->wmi_ab, len); + if (!skb) + return -ENOMEM; + + cmd = (struct wmi_pdev_set_sar_table_cmd *)skb->data; + cmd->tlv_header = FIELD_PREP(WMI_TLV_TAG, WMI_TAG_PDEV_SET_BIOS_SAR_TABLE_CMD) | + FIELD_PREP(WMI_TLV_LEN, sizeof(*cmd) - TLV_HDR_SIZE); + cmd->pdev_id = ar->pdev->pdev_id; + cmd->sar_len = BIOS_SAR_TABLE_LEN; + cmd->rsvd_len = BIOS_SAR_RSVD1_LEN; + + buf_ptr = skb->data + sizeof(*cmd); + tlv = (struct wmi_tlv *)buf_ptr; + tlv->header = FIELD_PREP(WMI_TLV_TAG, WMI_TAG_ARRAY_BYTE) | + FIELD_PREP(WMI_TLV_LEN, sar_len_aligned); + buf_ptr += TLV_HDR_SIZE; + memcpy(buf_ptr, sar_val, BIOS_SAR_TABLE_LEN); + + buf_ptr += sar_len_aligned; + tlv = (struct wmi_tlv *)buf_ptr; + tlv->header = FIELD_PREP(WMI_TLV_TAG, WMI_TAG_ARRAY_BYTE) | + FIELD_PREP(WMI_TLV_LEN, rsvd_len_aligned); + + return ath11k_wmi_cmd_send(wmi, skb, WMI_PDEV_SET_BIOS_SAR_TABLE_CMDID); +} + +int ath11k_wmi_pdev_set_bios_geo_table_param(struct ath11k *ar) +{ + struct ath11k_pdev_wmi *wmi = ar->wmi; + struct wmi_pdev_set_geo_table_cmd *cmd; + struct wmi_tlv *tlv; + struct sk_buff *skb; + u8 *buf_ptr; + u32 len, rsvd_len_aligned; + + rsvd_len_aligned = roundup(BIOS_SAR_RSVD2_LEN, sizeof(u32)); + len = sizeof(*cmd) + TLV_HDR_SIZE + rsvd_len_aligned; + + skb = ath11k_wmi_alloc_skb(wmi->wmi_ab, len); + if (!skb) + return -ENOMEM; + + cmd = (struct wmi_pdev_set_geo_table_cmd *)skb->data; + cmd->tlv_header = FIELD_PREP(WMI_TLV_TAG, WMI_TAG_PDEV_SET_BIOS_GEO_TABLE_CMD) | + FIELD_PREP(WMI_TLV_LEN, sizeof(*cmd) - TLV_HDR_SIZE); + cmd->pdev_id = ar->pdev->pdev_id; + cmd->rsvd_len = BIOS_SAR_RSVD2_LEN; + + buf_ptr = skb->data + sizeof(*cmd); + tlv = (struct wmi_tlv *)buf_ptr; + tlv->header = FIELD_PREP(WMI_TLV_TAG, WMI_TAG_ARRAY_BYTE) | + FIELD_PREP(WMI_TLV_LEN, rsvd_len_aligned); + + return ath11k_wmi_cmd_send(wmi, skb, WMI_PDEV_SET_BIOS_GEO_TABLE_CMDID); +} diff --git a/drivers/net/wireless/ath/ath11k/wmi.h b/drivers/net/wireless/ath/ath11k/wmi.h index 4ff7e71409ce8..7600e9a52da82 100644 --- a/drivers/net/wireless/ath/ath11k/wmi.h +++ b/drivers/net/wireless/ath/ath11k/wmi.h @@ -285,6 +285,11 @@ enum wmi_tlv_cmd_id { WMI_PDEV_SET_SRG_OBSS_BSSID_ENABLE_BITMAP_CMDID, WMI_PDEV_SET_NON_SRG_OBSS_COLOR_ENABLE_BITMAP_CMDID, WMI_PDEV_SET_NON_SRG_OBSS_BSSID_ENABLE_BITMAP_CMDID, + WMI_PDEV_GET_TPC_STATS_CMDID, + WMI_PDEV_ENABLE_DURATION_BASED_TX_MODE_SELECTION_CMDID, + WMI_PDEV_GET_DPD_STATUS_CMDID, + WMI_PDEV_SET_BIOS_SAR_TABLE_CMDID, + WMI_PDEV_SET_BIOS_GEO_TABLE_CMDID, WMI_VDEV_CREATE_CMDID = WMI_TLV_CMD(WMI_GRP_VDEV), WMI_VDEV_DELETE_CMDID, WMI_VDEV_START_REQUEST_CMDID, @@ -1859,6 +1864,8 @@ enum wmi_tlv_tag { WMI_TAG_PDEV_SRG_OBSS_BSSID_ENABLE_BITMAP_CMD, WMI_TAG_PDEV_NON_SRG_OBSS_COLOR_ENABLE_BITMAP_CMD, WMI_TAG_PDEV_NON_SRG_OBSS_BSSID_ENABLE_BITMAP_CMD, + WMI_TAG_PDEV_SET_BIOS_SAR_TABLE_CMD = 0x3D8, + WMI_TAG_PDEV_SET_BIOS_GEO_TABLE_CMD, WMI_TAG_MAX }; @@ -2087,6 +2094,7 @@ enum wmi_tlv_service { /* The second 128 bits */ WMI_MAX_EXT_SERVICE = 256, + WMI_TLV_SERVICE_BIOS_SAR_SUPPORT = 326, /* The third 128 bits */ WMI_MAX_EXT2_SERVICE = 384 @@ -5882,6 +5890,23 @@ struct wmi_gtk_rekey_offload_cmd { u8 replay_ctr[GTK_REPLAY_COUNTER_BYTES]; } __packed; +#define BIOS_SAR_TABLE_LEN (22) +#define BIOS_SAR_RSVD1_LEN (6) +#define BIOS_SAR_RSVD2_LEN (18) + +struct wmi_pdev_set_sar_table_cmd { + u32 tlv_header; + u32 pdev_id; + u32 sar_len; + u32 rsvd_len; +} __packed; + +struct wmi_pdev_set_geo_table_cmd { + u32 tlv_header; + u32 pdev_id; + u32 rsvd_len; +} __packed; + int ath11k_wmi_cmd_send(struct ath11k_pdev_wmi *wmi, struct sk_buff *skb, u32 cmd_id); struct sk_buff *ath11k_wmi_alloc_skb(struct ath11k_wmi_base *wmi_sc, u32 len); @@ -6060,5 +6085,7 @@ int ath11k_wmi_gtk_rekey_offload(struct ath11k *ar, struct ath11k_vif *arvif, bool enable); int ath11k_wmi_gtk_rekey_getinfo(struct ath11k *ar, struct ath11k_vif *arvif); +int ath11k_wmi_pdev_set_bios_sar_table_param(struct ath11k *ar, const u8 *sar_val); +int ath11k_wmi_pdev_set_bios_geo_table_param(struct ath11k *ar); #endif From 605194411d7379645ed44e447c4b804a0b476109 Mon Sep 17 00:00:00 2001 From: Yang Yingliang Date: Tue, 12 Apr 2022 16:15:53 +0300 Subject: [PATCH 147/228] ath11k: fix missing unlock on error in ath11k_wow_op_resume() Add the missing unlock before return from function ath11k_wow_op_resume() in the error handling case. Fixes: 90bf5c8d0f7e ("ath11k: purge rx pktlog when entering WoW") Reported-by: Hulk Robot Signed-off-by: Yang Yingliang Signed-off-by: Kalle Valo Link: https://lore.kernel.org/r/20220408030912.3087293-1-yangyingliang@huawei.com --- drivers/net/wireless/ath/ath11k/wow.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/net/wireless/ath/ath11k/wow.c b/drivers/net/wireless/ath/ath11k/wow.c index 6c2611f937396..9d088cebef03c 100644 --- a/drivers/net/wireless/ath/ath11k/wow.c +++ b/drivers/net/wireless/ath/ath11k/wow.c @@ -758,7 +758,7 @@ int ath11k_wow_op_resume(struct ieee80211_hw *hw) ret = ath11k_dp_rx_pktlog_start(ar->ab); if (ret) { ath11k_warn(ar->ab, "failed to start rx pktlog from wow: %d\n", ret); - return ret; + goto exit; } ret = ath11k_wow_wakeup(ar->ab); From 67888630addeaa2ae1c04d8d020daccbd26d05d9 Mon Sep 17 00:00:00 2001 From: YueHaibing Date: Mon, 11 Apr 2022 10:08:43 +0800 Subject: [PATCH 148/228] ath11k: Fix build warning without CONFIG_IPV6 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit drivers/net/wireless/ath/ath11k/mac.c:8175:13: error: ‘ath11k_mac_op_ipv6_changed’ defined but not used [-Werror=unused-function] static void ath11k_mac_op_ipv6_changed(struct ieee80211_hw *hw, ^~~~~~~~~~~~~~~~~~~~~~~~~~ Wrap it with #ifdef block to fix this. Fixes: c3c36bfe998b ("ath11k: support ARP and NS offload") Signed-off-by: YueHaibing Signed-off-by: Kalle Valo Link: https://lore.kernel.org/r/20220411020843.10284-1-yuehaibing@huawei.com --- drivers/net/wireless/ath/ath11k/mac.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/drivers/net/wireless/ath/ath11k/mac.c b/drivers/net/wireless/ath/ath11k/mac.c index 12fd307426646..c987f365c63a1 100644 --- a/drivers/net/wireless/ath/ath11k/mac.c +++ b/drivers/net/wireless/ath/ath11k/mac.c @@ -8145,6 +8145,7 @@ static void ath11k_mac_op_sta_statistics(struct ieee80211_hw *hw, } } +#if IS_ENABLED(CONFIG_IPV6) static void ath11k_generate_ns_mc_addr(struct ath11k *ar, struct ath11k_arp_ns_offload *offload) { @@ -8239,6 +8240,7 @@ static void ath11k_mac_op_ipv6_changed(struct ieee80211_hw *hw, /* generate ns multicast address */ ath11k_generate_ns_mc_addr(ar, offload); } +#endif static void ath11k_mac_op_set_rekey_data(struct ieee80211_hw *hw, struct ieee80211_vif *vif, From 45286070e9e782f2f53b5272a227fc879fbda2c8 Mon Sep 17 00:00:00 2001 From: Minghao Chi Date: Mon, 11 Apr 2022 01:36:02 +0000 Subject: [PATCH 149/228] wil6210: use pm_runtime_resume_and_get() instead of pm_runtime_get_sync() Using pm_runtime_resume_and_get() is more appropriate for simplifing code. Reported-by: Zeal Robot Signed-off-by: Minghao Chi Signed-off-by: Kalle Valo Link: https://lore.kernel.org/r/20220411013602.2517086-1-chi.minghao@zte.com.cn --- drivers/net/wireless/ath/wil6210/pm.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/drivers/net/wireless/ath/wil6210/pm.c b/drivers/net/wireless/ath/wil6210/pm.c index ed4df561e5c50..f521af575e9ba 100644 --- a/drivers/net/wireless/ath/wil6210/pm.c +++ b/drivers/net/wireless/ath/wil6210/pm.c @@ -445,10 +445,9 @@ int wil_pm_runtime_get(struct wil6210_priv *wil) int rc; struct device *dev = wil_to_dev(wil); - rc = pm_runtime_get_sync(dev); + rc = pm_runtime_resume_and_get(dev); if (rc < 0) { - wil_err(wil, "pm_runtime_get_sync() failed, rc = %d\n", rc); - pm_runtime_put_noidle(dev); + wil_err(wil, "pm_runtime_resume_and_get() failed, rc = %d\n", rc); return rc; } From 2dc509305cf956381532792cb8dceef2b1504765 Mon Sep 17 00:00:00 2001 From: Dan Carpenter Date: Sat, 9 Apr 2022 09:12:25 +0300 Subject: [PATCH 150/228] ath9k_htc: fix potential out of bounds access with invalid rxstatus->rs_keyix MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The "rxstatus->rs_keyix" eventually gets passed to test_bit() so we need to ensure that it is within the bitmap. drivers/net/wireless/ath/ath9k/common.c:46 ath9k_cmn_rx_accept() error: passing untrusted data 'rx_stats->rs_keyix' to 'test_bit()' Fixes: 4ed1a8d4a257 ("ath9k_htc: use ath9k_cmn_rx_accept") Signed-off-by: Dan Carpenter Acked-by: Toke Høiland-Jørgensen Signed-off-by: Kalle Valo Link: https://lore.kernel.org/r/20220409061225.GA5447@kili --- drivers/net/wireless/ath/ath9k/htc_drv_txrx.c | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/drivers/net/wireless/ath/ath9k/htc_drv_txrx.c b/drivers/net/wireless/ath/ath9k/htc_drv_txrx.c index 6a850a0bfa8ad..a23eaca0326d1 100644 --- a/drivers/net/wireless/ath/ath9k/htc_drv_txrx.c +++ b/drivers/net/wireless/ath/ath9k/htc_drv_txrx.c @@ -1016,6 +1016,14 @@ static bool ath9k_rx_prepare(struct ath9k_htc_priv *priv, goto rx_next; } + if (rxstatus->rs_keyix >= ATH_KEYMAX && + rxstatus->rs_keyix != ATH9K_RXKEYIX_INVALID) { + ath_dbg(common, ANY, + "Invalid keyix, dropping (keyix: %d)\n", + rxstatus->rs_keyix); + goto rx_next; + } + /* Get the RX status information */ memset(rx_status, 0, sizeof(struct ieee80211_rx_status)); From e999a5da28a0e0f7de242d841ef7d5e48f4646ae Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Thibaut=20VAR=C3=88NE?= Date: Sun, 17 Apr 2022 16:51:45 +0200 Subject: [PATCH 151/228] ath9k: fix QCA9561 PA bias level MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This patch fixes an invalid TX PA DC bias level on QCA9561, which results in a very low output power and very low throughput as devices are further away from the AP (compared to other 2.4GHz APs). This patch was suggested by Felix Fietkau, who noted[1]: "The value written to that register is wrong, because while the mask definition AR_CH0_TOP2_XPABIASLVL uses a different value for 9561, the shift definition AR_CH0_TOP2_XPABIASLVL_S is hardcoded to 12, which is wrong for 9561." In real life testing, without this patch the 2.4GHz throughput on Yuncore XD3200 is around 10Mbps sitting next to the AP, and closer to practical maximum with the patch applied. [1] https://lore.kernel.org/all/91c58969-c60e-2f41-00ac-737786d435ae@nbd.name Signed-off-by: Thibaut VARÈNE Acked-by: Felix Fietkau Acked-by: Toke Høiland-Jørgensen Signed-off-by: Kalle Valo Link: https://lore.kernel.org/r/20220417145145.1847-1-hacks+kernel@slashdirt.org --- drivers/net/wireless/ath/ath9k/ar9003_phy.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/net/wireless/ath/ath9k/ar9003_phy.h b/drivers/net/wireless/ath/ath9k/ar9003_phy.h index a171dbb29fbb6..ad949eb02f3d2 100644 --- a/drivers/net/wireless/ath/ath9k/ar9003_phy.h +++ b/drivers/net/wireless/ath/ath9k/ar9003_phy.h @@ -720,7 +720,7 @@ #define AR_CH0_TOP2 (AR_SREV_9300(ah) ? 0x1628c : \ (AR_SREV_9462(ah) ? 0x16290 : 0x16284)) #define AR_CH0_TOP2_XPABIASLVL (AR_SREV_9561(ah) ? 0x1e00 : 0xf000) -#define AR_CH0_TOP2_XPABIASLVL_S 12 +#define AR_CH0_TOP2_XPABIASLVL_S (AR_SREV_9561(ah) ? 9 : 12) #define AR_CH0_XTAL (AR_SREV_9300(ah) ? 0x16294 : \ ((AR_SREV_9462(ah) || AR_SREV_9565(ah)) ? 0x16298 : \ From 8e95061b5b9c519891dbe2e519dc3fc1d5f6f4a4 Mon Sep 17 00:00:00 2001 From: Minghao Chi Date: Wed, 13 Apr 2022 09:33:56 +0000 Subject: [PATCH 152/228] wl18xx: debugfs: use pm_runtime_resume_and_get() instead of pm_runtime_get_sync() Using pm_runtime_resume_and_get is more appropriate for simplifing code Reported-by: Zeal Robot Signed-off-by: Minghao Chi Signed-off-by: Kalle Valo Link: https://lore.kernel.org/r/20220413093356.2538192-1-chi.minghao@zte.com.cn --- drivers/net/wireless/ti/wl18xx/debugfs.c | 18 ++++++------------ 1 file changed, 6 insertions(+), 12 deletions(-) diff --git a/drivers/net/wireless/ti/wl18xx/debugfs.c b/drivers/net/wireless/ti/wl18xx/debugfs.c index 2f921a44f1e2f..80fbf740fe6d7 100644 --- a/drivers/net/wireless/ti/wl18xx/debugfs.c +++ b/drivers/net/wireless/ti/wl18xx/debugfs.c @@ -264,11 +264,9 @@ static ssize_t radar_detection_write(struct file *file, if (unlikely(wl->state != WLCORE_STATE_ON)) goto out; - ret = pm_runtime_get_sync(wl->dev); - if (ret < 0) { - pm_runtime_put_noidle(wl->dev); + ret = pm_runtime_resume_and_get(wl->dev); + if (ret < 0) goto out; - } ret = wl18xx_cmd_radar_detection_debug(wl, channel); if (ret < 0) @@ -306,11 +304,9 @@ static ssize_t dynamic_fw_traces_write(struct file *file, if (unlikely(wl->state != WLCORE_STATE_ON)) goto out; - ret = pm_runtime_get_sync(wl->dev); - if (ret < 0) { - pm_runtime_put_noidle(wl->dev); + ret = pm_runtime_resume_and_get(wl->dev); + if (ret < 0) goto out; - } ret = wl18xx_acx_dynamic_fw_traces(wl); if (ret < 0) @@ -368,11 +364,9 @@ static ssize_t radar_debug_mode_write(struct file *file, if (unlikely(wl->state != WLCORE_STATE_ON)) goto out; - ret = pm_runtime_get_sync(wl->dev); - if (ret < 0) { - pm_runtime_put_noidle(wl->dev); + ret = pm_runtime_resume_and_get(wl->dev); + if (ret < 0) goto out; - } wl12xx_for_each_wlvif_ap(wl, wlvif) { wlcore_cmd_generic_cfg(wl, wlvif, From eefad995c24295138669e5522f9b04c31fef0755 Mon Sep 17 00:00:00 2001 From: Ping-Ke Shih Date: Thu, 14 Apr 2022 14:20:15 +0800 Subject: [PATCH 153/228] rtw89: 8852c: add BB and RF parameters tables These parameters are used to initialize BB and RF hardware when we are going to bring up interface and start to transmit and receive. Signed-off-by: Ping-Ke Shih Signed-off-by: Kalle Valo Link: https://lore.kernel.org/r/20220414062027.62638-2-pkshih@realtek.com --- drivers/net/wireless/realtek/rtw89/core.h | 1 + drivers/net/wireless/realtek/rtw89/rtw8852a.c | 1 + drivers/net/wireless/realtek/rtw89/rtw8852c.c | 6 + .../wireless/realtek/rtw89/rtw8852c_table.c | 13697 ++++++++++++++++ .../wireless/realtek/rtw89/rtw8852c_table.h | 16 + 5 files changed, 13721 insertions(+) create mode 100644 drivers/net/wireless/realtek/rtw89/rtw8852c_table.c create mode 100644 drivers/net/wireless/realtek/rtw89/rtw8852c_table.h diff --git a/drivers/net/wireless/realtek/rtw89/core.h b/drivers/net/wireless/realtek/rtw89/core.h index 090d416569010..e8e31492b3639 100644 --- a/drivers/net/wireless/realtek/rtw89/core.h +++ b/drivers/net/wireless/realtek/rtw89/core.h @@ -2374,6 +2374,7 @@ struct rtw89_chip_info { const struct rtw89_pwr_cfg * const *pwr_on_seq; const struct rtw89_pwr_cfg * const *pwr_off_seq; const struct rtw89_phy_table *bb_table; + const struct rtw89_phy_table *bb_gain_table; const struct rtw89_phy_table *rf_table[RF_PATH_MAX]; const struct rtw89_phy_table *nctl_table; const struct rtw89_txpwr_table *byr_table; diff --git a/drivers/net/wireless/realtek/rtw89/rtw8852a.c b/drivers/net/wireless/realtek/rtw89/rtw8852a.c index 975c504953049..2c5bd381ebf58 100644 --- a/drivers/net/wireless/realtek/rtw89/rtw8852a.c +++ b/drivers/net/wireless/realtek/rtw89/rtw8852a.c @@ -2101,6 +2101,7 @@ const struct rtw89_chip_info rtw8852a_chip_info = { .pwr_on_seq = pwr_on_seq_8852a, .pwr_off_seq = pwr_off_seq_8852a, .bb_table = &rtw89_8852a_phy_bb_table, + .bb_gain_table = NULL, .rf_table = {&rtw89_8852a_phy_radioa_table, &rtw89_8852a_phy_radiob_table,}, .nctl_table = &rtw89_8852a_phy_nctl_table, diff --git a/drivers/net/wireless/realtek/rtw89/rtw8852c.c b/drivers/net/wireless/realtek/rtw89/rtw8852c.c index d56d65661ce08..0855c41e32afb 100644 --- a/drivers/net/wireless/realtek/rtw89/rtw8852c.c +++ b/drivers/net/wireless/realtek/rtw89/rtw8852c.c @@ -9,6 +9,7 @@ #include "phy.h" #include "reg.h" #include "rtw8852c.h" +#include "rtw8852c_table.h" static const struct rtw89_dle_mem rtw8852c_dle_mem_pcie[] = { [RTW89_QTA_SCC] = {RTW89_QTA_SCC, &rtw89_mac_size.wde_size19, @@ -658,6 +659,11 @@ const struct rtw89_chip_info rtw8852c_chip_info = { .rf_base_addr = {0xe000, 0xf000}, .pwr_on_seq = NULL, .pwr_off_seq = NULL, + .bb_table = &rtw89_8852c_phy_bb_table, + .bb_gain_table = &rtw89_8852c_phy_bb_gain_table, + .rf_table = {&rtw89_8852c_phy_radiob_table, + &rtw89_8852c_phy_radioa_table,}, + .nctl_table = &rtw89_8852c_phy_nctl_table, .dig_table = NULL, .hw_sec_hdr = true, .sec_ctrl_efuse_size = 4, diff --git a/drivers/net/wireless/realtek/rtw89/rtw8852c_table.c b/drivers/net/wireless/realtek/rtw89/rtw8852c_table.c new file mode 100644 index 0000000000000..b0431874d7c4c --- /dev/null +++ b/drivers/net/wireless/realtek/rtw89/rtw8852c_table.c @@ -0,0 +1,13697 @@ +// SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause +/* Copyright(c) 2019-2022 Realtek Corporation + */ + +#include "phy.h" +#include "reg.h" +#include "rtw8852c_table.h" + +static const struct rtw89_reg2_def rtw89_8852c_phy_bb_regs[] = { + {0xF0FF0000, 0x00000000}, + {0xF03300FF, 0x00000001}, + {0xF03400FF, 0x00000002}, + {0x70C, 0x00000020}, + {0x704, 0x601E0100}, + {0x4000, 0x00000000}, + {0x4004, 0xCA014000}, + {0x4008, 0xC751D4F0}, + {0x400C, 0x44511475}, + {0x4010, 0x00000000}, + {0x4014, 0x00000000}, + {0x44AC, 0x01F60380}, + {0x4018, 0x4F4C4B4B}, + {0x401C, 0x494A4E52}, + {0x4020, 0x4D504E4B}, + {0x4024, 0x4F4C4949}, + {0x4028, 0x49484C50}, + {0x402C, 0x4C50504C}, + {0x4030, 0x54544D4A}, + {0x4034, 0x504B5654}, + {0x4038, 0x6A6C605A}, + {0x403C, 0x48484848}, + {0x4040, 0x48483D47}, + {0x4044, 0x3D474848}, + {0x4048, 0x51484848}, + {0x404C, 0x4A4A404F}, + {0x4050, 0x514F4C4A}, + {0x4054, 0x524E4A4A}, + {0x4058, 0x4A4A5154}, + {0x405C, 0x53555554}, + {0x4060, 0x45454545}, + {0x4064, 0x45454144}, + {0x4068, 0x40434445}, + {0x406C, 0x44454545}, + {0x4070, 0x44444043}, + {0x4074, 0x42434444}, + {0x4078, 0x46454444}, + {0x407C, 0x44444843}, + {0x4080, 0x4B4E4A47}, + {0x4084, 0x514D4A49}, + {0x4088, 0x4A495454}, + {0x408C, 0x5454514D}, + {0x4090, 0x524E4B4A}, + {0x4094, 0x4C4B5455}, + {0x4098, 0x55565550}, + {0x409C, 0x5959504D}, + {0x40A0, 0x544E5D5A}, + {0x40A4, 0x7975665F}, + {0x40A8, 0x48484848}, + {0x40AC, 0x48483D47}, + {0x40B0, 0x3D474848}, + {0x40B4, 0x48484848}, + {0x40B8, 0x48483E48}, + {0x40BC, 0x3E4A4A49}, + {0x40C0, 0x514E4948}, + {0x40C4, 0x4A49404F}, + {0x40C8, 0x42525555}, + {0x40CC, 0x47474747}, + {0x40D0, 0x47474747}, + {0x40D4, 0x47474747}, + {0x40D8, 0x48484848}, + {0x40DC, 0x48474848}, + {0x40E0, 0x4A484848}, + {0x40E4, 0x49484847}, + {0x40E8, 0x4847524D}, + {0x40EC, 0x55544F4B}, + {0x40F0, 0x00000000}, + {0x4604, 0x4C4C4D4E}, + {0x4608, 0x3D3D6A56}, + {0x460C, 0x53515140}, + {0x4610, 0x42404041}, + {0x4614, 0x54544B48}, + {0x4618, 0x795D5554}, + {0x461C, 0x3E3E3D3D}, + {0x4620, 0x47474240}, + {0x4624, 0x55524A48}, + {0x4ED4, 0x00000000}, + {0x40F4, 0x00000006}, + {0x4628, 0x00000000}, + {0x4E9C, 0x26663333}, + {0x4EA0, 0x6EDA4148}, + {0x4EA4, 0x599A0000}, + {0x4EA8, 0x40000000}, + {0x4ED0, 0x00000001}, + {0x40F8, 0x00000000}, + {0x40FC, 0x8C30C30C}, + {0x4100, 0x4C30C30C}, + {0x4104, 0x0C30C30C}, + {0x4108, 0x0C30C30C}, + {0x410C, 0x0C30C30C}, + {0x4110, 0x0C30C30C}, + {0x4114, 0x28A28A28}, + {0x4118, 0x28A28A28}, + {0x411C, 0x28A28A28}, + {0x4120, 0x28A28A28}, + {0x4124, 0x28A28A28}, + {0x4128, 0x28A28A28}, + {0x412C, 0x06666666}, + {0x4130, 0x33333333}, + {0x4134, 0x33333333}, + {0x4138, 0x33333333}, + {0x413C, 0x00000031}, + {0x462C, 0x0C30C30C}, + {0x4630, 0x0C30C30C}, + {0x4634, 0x28A28A28}, + {0x4638, 0x28A28A28}, + {0x463C, 0x33333333}, + {0x4640, 0x00000033}, + {0x4140, 0x5100600A}, + {0x4144, 0x18363113}, + {0x4148, 0x1D976DDC}, + {0x414C, 0x1C072DD7}, + {0x4150, 0x1127CDF4}, + {0x4154, 0x1E37BDF1}, + {0x4158, 0x1FB7F1D6}, + {0x415C, 0x1EA7DDF9}, + {0x4160, 0x1FE445DD}, + {0x4164, 0x1F97F1FE}, + {0x4168, 0x1FF781ED}, + {0x416C, 0x1FA7F5FE}, + {0x4170, 0x1E07B913}, + {0x4174, 0x1FD7FDFF}, + {0x4178, 0x1E17B9FA}, + {0x417C, 0x19A66914}, + {0x4180, 0x10F65598}, + {0x4184, 0x14A5A111}, + {0x4188, 0x1D3765DB}, + {0x418C, 0x17C685CA}, + {0x4190, 0x1107C5F3}, + {0x4194, 0x1B5785EB}, + {0x4198, 0x1F97ED8F}, + {0x419C, 0x1BC7A5F3}, + {0x41A0, 0x1FE43595}, + {0x41A4, 0x1EB7D9FC}, + {0x41A8, 0x1FE65DBE}, + {0x41AC, 0x1EC7D9FC}, + {0x41B0, 0x1976FCFF}, + {0x41B4, 0x1F77F5FF}, + {0x41B8, 0x1976FDEC}, + {0x41BC, 0x198664EF}, + {0x41C0, 0x11062D93}, + {0x41C4, 0x10C4E910}, + {0x41C8, 0x1CA759DB}, + {0x41CC, 0x1335A9B5}, + {0x41D0, 0x1097B9F3}, + {0x41D4, 0x17B72DE1}, + {0x41D8, 0x1F67ED42}, + {0x41DC, 0x18074DE9}, + {0x41E0, 0x1FD40547}, + {0x41E4, 0x1D57ADF9}, + {0x41E8, 0x1FE52182}, + {0x41EC, 0x1D67B1F9}, + {0x41F0, 0x14860CE1}, + {0x41F4, 0x1EC7E9FE}, + {0x41F8, 0x14860DD6}, + {0x41FC, 0x195664C7}, + {0x4200, 0x0005E58A}, + {0x4204, 0x00000000}, + {0x4208, 0x00000000}, + {0x420C, 0x7A000000}, + {0x4210, 0x0F9F3D7A}, + {0x4214, 0x0040817C}, + {0x4218, 0x00E10204}, + {0x421C, 0x257D94CD}, + {0x4220, 0x0802DB6D}, + {0x4224, 0x00000200}, + {0x4228, 0x04688000}, + {0x4644, 0x00000000}, + {0x4648, 0x00000000}, + {0x464C, 0x00000000}, + {0x4650, 0x00000020}, + {0x4ECC, 0x00000001}, + {0x422C, 0x0060B002}, + {0x4230, 0x9A8249A8}, + {0x4234, 0x26A1469E}, + {0x4238, 0x2099A824}, + {0x423C, 0x2359461C}, + {0x4240, 0x1631A675}, + {0x4244, 0x2C6B1D63}, + {0x4248, 0x0000000E}, + {0x424C, 0x00000001}, + {0x4250, 0x00000001}, + {0x4254, 0x00000000}, + {0x4258, 0x00000000}, + {0x425C, 0x00000000}, + {0x4260, 0x01E0000C}, + {0x4654, 0x00000000}, + {0x4658, 0x00000000}, + {0x465C, 0x0000001E}, + {0x4E74, 0x00000000}, + {0x4264, 0x00000000}, + {0x4268, 0x00000000}, + {0x426C, 0x0418317C}, + {0x46C0, 0x00000001}, + {0x4270, 0x00D6135C}, + {0x46C4, 0x00000033}, + {0x4274, 0x00000000}, + {0x4278, 0x00000000}, + {0x427C, 0x00000000}, + {0x4280, 0x00000000}, + {0x4284, 0x00000000}, + {0x4288, 0x00000000}, + {0x46D8, 0x00000000}, + {0x46DC, 0x00000000}, + {0x46E0, 0x00000000}, + {0x46E4, 0x00000000}, + {0x46E8, 0x00000000}, + {0x428C, 0x00000000}, + {0x4290, 0x00000000}, + {0x4294, 0x00000000}, + {0x4298, 0x84026000}, + {0x429C, 0x0051AC20}, + {0x46EC, 0x1020C040}, + {0x46F0, 0xB8BEBEB8}, + {0x46F4, 0x021102BE}, + {0x46F8, 0x14221142}, + {0x46FC, 0x18C4098C}, + {0x4700, 0x00021084}, + {0x42A0, 0x02024008}, + {0x42A4, 0x00000000}, + {0x42A8, 0x00000000}, + {0x42AC, 0x22CE803C}, + {0x42B0, 0x32000000}, + {0x42B4, 0x996FD67D}, + {0x42B8, 0xBD67D67D}, + {0x42BC, 0x7D67D65B}, + {0x42C0, 0x28029F59}, + {0x42C4, 0x00280280}, + {0x4704, 0x00000000}, + {0x42C8, 0x00000000}, + {0x42CC, 0x00000000}, + {0x42D0, 0x00000003}, + {0x4708, 0x00280000}, + {0x42D4, 0x00000001}, + {0x42D8, 0x61861800}, + {0x42DC, 0x830C30C3}, + {0x42E0, 0xC30C30C3}, + {0x42E4, 0x830C30C3}, + {0x42E8, 0x451450C3}, + {0x42EC, 0x05145145}, + {0x42F0, 0x05145145}, + {0x42F4, 0x05145145}, + {0x42F8, 0x03207145}, + {0x42FC, 0x041C32C6}, + {0x4300, 0x031C5247}, + {0x4304, 0x030C5143}, + {0x4308, 0x030C30C3}, + {0x430C, 0x0F3CF3C3}, + {0x4310, 0x0F3CF3CF}, + {0x4314, 0x0F3CF3CF}, + {0x4318, 0x0F3CF3CF}, + {0x431C, 0x0F3CF3CF}, + {0x4320, 0x030C10C3}, + {0x4324, 0x051430C3}, + {0x4328, 0x051490CB}, + {0x432C, 0x030C70D1}, + {0x4330, 0x050C50C7}, + {0x4334, 0x051492CB}, + {0x4338, 0x05145145}, + {0x433C, 0x05145145}, + {0x4340, 0x05145145}, + {0x4344, 0x05145145}, + {0x4348, 0x090CD243}, + {0x434C, 0x0918A1C5}, + {0x4350, 0x071C3143}, + {0x4354, 0x071431C3}, + {0x4358, 0x0F3CF1C5}, + {0x435C, 0x0F3CF3CF}, + {0x4360, 0x0F3CF3CF}, + {0x4364, 0x0F3CF3CF}, + {0x4368, 0x0F3CF3CF}, + {0x436C, 0x090C91CF}, + {0x4370, 0x11243143}, + {0x4374, 0x9777A777}, + {0x4378, 0xBB7BAC95}, + {0x437C, 0xB667B889}, + {0x4380, 0x7B9B8899}, + {0x4384, 0x7A5567C8}, + {0x4388, 0x2278CCCC}, + {0x438C, 0x7C222222}, + {0x4390, 0x0000049B}, + {0x470C, 0x00000888}, + {0x4EB4, 0x00000002}, + {0x4394, 0x001CCCCC}, + {0x4710, 0xCCCCCAAC}, + {0x4714, 0x0000AACC}, + {0x4398, 0x00000000}, + {0x439C, 0x00000008}, + {0x49A4, 0x00000000}, + {0x43A0, 0x00000000}, + {0x43A4, 0x00000000}, + {0x43A8, 0x00000000}, + {0x43AC, 0x10000000}, + {0x43B0, 0x00401001}, + {0x43B4, 0x00061003}, + {0x4718, 0x00003000}, + {0x43B8, 0x000024D8}, + {0x43BC, 0x00000000}, + {0x43C0, 0x10000020}, + {0x43C4, 0x20000200}, + {0x43C8, 0x00000000}, + {0x43CC, 0x04000000}, + {0x43D0, 0x44000100}, + {0x43D4, 0x60804060}, + {0x43D8, 0x44204210}, + {0x43DC, 0x82108082}, + {0x43E0, 0x82108402}, + {0x43E4, 0xC8082108}, + {0x43E8, 0xC8202084}, + {0x43EC, 0x44208208}, + {0x43F0, 0x84108204}, + {0x43F4, 0xD0108104}, + {0x43F8, 0xF8210108}, + {0x43FC, 0x6431E930}, + {0x4400, 0x02109468}, + {0x4404, 0x10C61C22}, + {0x4408, 0x02109469}, + {0x440C, 0x10C61C22}, + {0x4410, 0x00041049}, + {0x471C, 0x0B02C080}, + {0x4414, 0x00000000}, + {0x4418, 0x00000000}, + {0x441C, 0x80000000}, + {0x4420, 0xB0200000}, + {0x4424, 0x00001FF0}, + {0x4780, 0xEC000000}, + {0x4784, 0x8C400020}, + {0x4964, 0x51089104}, + {0x4968, 0x88448844}, + {0x496C, 0x07000044}, + {0x4E4C, 0x00000000}, + {0x4428, 0x00000000}, + {0x442C, 0x00000000}, + {0x4430, 0x00000000}, + {0x4434, 0x00000000}, + {0x4438, 0x590642D0}, + {0x443C, 0x398668A0}, + {0x4440, 0x6C100808}, + {0x4444, 0x4A145344}, + {0x4448, 0x0C5B008F}, + {0x444C, 0x6E30498A}, + {0x4450, 0x656E371B}, + {0x4454, 0x00000F53}, + {0x49A8, 0x68120000}, + {0x49AC, 0xDA0681E0}, + {0x49BC, 0x14060180}, + {0x49D8, 0x600603FF}, + {0x49DC, 0x3C502000}, + {0x49E0, 0x2C580050}, + {0x49E4, 0x45B055EF}, + {0x49E8, 0x00000290}, + {0x4A0C, 0x00000001}, + {0x4A28, 0x0DAC1B58}, + {0x4A2C, 0x0000001E}, + {0x4E50, 0x16878003}, + {0x4E54, 0x0F00F078}, + {0x4E58, 0x03C1E0B4}, + {0x4E5C, 0x78584830}, + {0x4E60, 0x88C0140C}, + {0x4E64, 0x90302C24}, + {0x4E68, 0x0F84A00A}, + {0x4E6C, 0x00000011}, + {0x4E78, 0x00003039}, + {0x4E7C, 0x0000D431}, + {0x4E80, 0x00008235}, + {0x4E84, 0x00000000}, + {0x4E88, 0x000056CE}, + {0x4E8C, 0x00002B67}, + {0x4E90, 0x00000237}, + {0x4EB8, 0x00004624}, + {0x4A30, 0x00000000}, + {0x4458, 0x00000000}, + {0x445C, 0x4801442E}, + {0x4460, 0x0051A0B8}, + {0x4A34, 0x0000011F}, + {0x4EBC, 0x00000000}, + {0x4A38, 0x0000011F}, + {0x4EC0, 0x00000000}, + {0x4464, 0x00000000}, + {0x4468, 0x00000000}, + {0x446C, 0x00000000}, + {0x4470, 0x00000000}, + {0x4474, 0x00000000}, + {0x4478, 0x00000000}, + {0x447C, 0x00000000}, + {0x4480, 0x2A0AA040}, + {0x4484, 0x0A886926}, + {0x4488, 0x00000004}, + {0x4A3C, 0x00002B1C}, + {0x448C, 0x00000000}, + {0x4490, 0x88000000}, + {0x4494, 0x10000000}, + {0x4498, 0xE0000000}, + {0x4A08, 0x00000FE6}, + {0x4A40, 0x00000000}, + {0x4A44, 0x00000000}, + {0x4A48, 0x00000000}, + {0x4A4C, 0x00000000}, + {0x4A50, 0x00000000}, + {0x4A54, 0x00000000}, + {0x449C, 0x00000019}, + {0x44A0, 0x02B2E394}, + {0x44A4, 0x00000400}, + {0x4A58, 0x14285208}, + {0x4A84, 0x02850A14}, + {0x4A88, 0x048D0A14}, + {0x4A8C, 0x01123401}, + {0x4A90, 0x34011234}, + {0x4A94, 0x23450112}, + {0x4A98, 0x45123451}, + {0x4AAC, 0x12345123}, + {0x4AB0, 0x00000000}, + {0x44A8, 0x00000001}, + {0x44B0, 0x00000000}, + {0x44B4, 0x00000000}, + {0x44B8, 0x00000000}, + {0x44BC, 0x00000000}, + {0x44C0, 0x00000000}, + {0x44C4, 0x00000000}, + {0x44C8, 0x00000000}, + {0x44CC, 0x00000000}, + {0x44D0, 0x00000000}, + {0x44D4, 0x00000000}, + {0x44D8, 0x00000000}, + {0x44DC, 0x00000000}, + {0x44E0, 0x00000000}, + {0x44E4, 0x00000000}, + {0x44E8, 0x00000000}, + {0x44EC, 0x00000000}, + {0x44F0, 0x00000000}, + {0x44F4, 0x00000000}, + {0x44F8, 0x00000000}, + {0x44FC, 0x00000000}, + {0x4500, 0x00000000}, + {0x4504, 0x00000000}, + {0x4508, 0x00000000}, + {0x450C, 0x00000000}, + {0x4510, 0x00000000}, + {0x4514, 0x00000000}, + {0x4518, 0x00000000}, + {0x451C, 0x00000000}, + {0x4520, 0x00000000}, + {0x4524, 0x00000000}, + {0x4528, 0x00000000}, + {0x452C, 0x00000000}, + {0x4530, 0x4ED80C81}, + {0x4534, 0x00001808}, + {0x4538, 0x000000FF}, + {0x453C, 0x00000000}, + {0x4540, 0x00000000}, + {0x4544, 0x00000000}, + {0x4548, 0x00000000}, + {0x454C, 0x00000000}, + {0x4550, 0x00000000}, + {0x4554, 0x00000000}, + {0x4558, 0x00000000}, + {0x455C, 0x00000000}, + {0x4560, 0x40600033}, + {0x4564, 0x40000000}, + {0x4568, 0x00000000}, + {0x456C, 0x20000000}, + {0x4570, 0x04AAA407}, + {0x4574, 0x0001A2B4}, + {0x4578, 0x0002024B}, + {0x457C, 0x00200000}, + {0x4580, 0x00001B40}, + {0x4584, 0x00000000}, + {0x4588, 0x000000C8}, + {0x458C, 0x30000000}, + {0x4590, 0x00000000}, + {0x4594, 0x00000000}, + {0x4598, 0x00000001}, + {0x459C, 0x0003FE00}, + {0x45A0, 0x00000000}, + {0x45A4, 0x00000000}, + {0x45A8, 0xC00002C0}, + {0x45AC, 0x78028000}, + {0x45B0, 0x80000048}, + {0x45B4, 0x00098800}, + {0x45B8, 0x00200002}, + {0x4AB4, 0x00000000}, + {0x4AB8, 0x00000000}, + {0x4ABC, 0x00000000}, + {0x4AC0, 0x00000000}, + {0x4AC4, 0x00000000}, + {0x4AC8, 0x00000000}, + {0x4AF4, 0x00000000}, + {0x4AF8, 0x00000000}, + {0x4AFC, 0x00000000}, + {0x4B00, 0x00000000}, + {0x4B04, 0x00000000}, + {0x4B08, 0x00000000}, + {0x4B0C, 0x00000000}, + {0x4B10, 0x00000000}, + {0x4B14, 0x00000000}, + {0x4B18, 0xB0000000}, + {0x4B1C, 0x00000000}, + {0x4B20, 0x00000000}, + {0x4B24, 0x00000000}, + {0x4B28, 0x00000000}, + {0x4B2C, 0x00000000}, + {0x4B30, 0x00000000}, + {0x4B34, 0x00000000}, + {0x4B38, 0x00000000}, + {0x4B3C, 0x00000000}, + {0x4B40, 0x00000000}, + {0x45BC, 0x06748790}, + {0x45C0, 0x80000000}, + {0x45C4, 0x00000000}, + {0x45C8, 0x00000000}, + {0x45CC, 0x00558670}, + {0x45D0, 0x002883F0}, + {0x45D4, 0x00090120}, + {0x45D8, 0x00000000}, + {0x4B44, 0x00000100}, + {0x4B48, 0xA6DBC4B1}, + {0x4B4C, 0x64F624C3}, + {0x4B50, 0x00D4EF15}, + {0x49B0, 0x11110F0A}, + {0x49B4, 0x00000003}, + {0x49B8, 0x0000000A}, + {0x4B54, 0xBE9007FF}, + {0x4B58, 0x00000001}, + {0x49C0, 0x00000007}, + {0x49C4, 0x000003D9}, + {0x4A10, 0x00000001}, + {0x49C8, 0x002B1CB0}, + {0x4A00, 0xC0000000}, + {0x4A04, 0x00001000}, + {0x4B5C, 0x00000005}, + {0x4A18, 0x00000007}, + {0x4B60, 0x00000024}, + {0x49CC, 0x00000001}, + {0x49D0, 0x00000010}, + {0x49D4, 0x00000001}, + {0x4B64, 0x927FBFBF}, + {0x4B68, 0x1D07BDD0}, + {0x4B6C, 0x318A4DEF}, + {0x4B70, 0x158C5318}, + {0x4B74, 0x18C5318C}, + {0x4B78, 0x4E7394EC}, + {0x4B7C, 0xD9081CE5}, + {0x4B80, 0x00000001}, + {0x49EC, 0x00000001}, + {0x4B84, 0x00000000}, + {0x4B88, 0x00000000}, + {0x4B8C, 0x00000000}, + {0x4B90, 0x00000000}, + {0x4B94, 0x00000000}, + {0x4B98, 0x00000000}, + {0x4B9C, 0x00000000}, + {0x4BA0, 0x00000000}, + {0x4BA4, 0x00EA99A2}, + {0x49F8, 0x0000C4C3}, + {0x4A1C, 0x00020800}, + {0x4A20, 0x0002CC00}, + {0x4BA8, 0x002B6456}, + {0x45E0, 0x00000000}, + {0x45E4, 0x00000000}, + {0x45E8, 0x00E2E1E1}, + {0x45EC, 0xCBCBB6B6}, + {0x45F0, 0x59100FCA}, + {0x4BAC, 0x12CAB6DE}, + {0x4BB0, 0x00001110}, + {0x45F4, 0x08882550}, + {0x45F8, 0x08CC2660}, + {0x45FC, 0x09102660}, + {0x4600, 0x00000154}, + {0x80ff0000, 0x00000000}, {0x40000000, 0x00000000}, + {0x45DC, 0xE1CB38E8}, + {0x4660, 0x4A2E1800}, + {0x4664, 0x6750E462}, + {0x903300ff, 0x00000000}, {0x40000000, 0x00000000}, + {0x45DC, 0xD1B942F4}, + {0x4660, 0x41250EF4}, + {0x4664, 0x6750E458}, + {0x903400ff, 0x00000000}, {0x40000000, 0x00000000}, + {0x45DC, 0xE1CB38E8}, + {0x4660, 0x4A2E1800}, + {0x4664, 0x6750E462}, + {0xA0000000, 0x00000000}, + {0x45DC, 0xE1CB38E8}, + {0x4660, 0x4A2E1800}, + {0x4664, 0x6750E462}, + {0xB0000000, 0x00000000}, + {0x4668, 0x0E0CFB0A}, + {0x466C, 0x30100F06}, + {0x4670, 0x34333333}, + {0x4674, 0x34343434}, + {0x4678, 0xC39D38E8}, + {0x467C, 0x482800E3}, + {0x4680, 0x5836E46A}, + {0x4684, 0xFBEBDA00}, + {0x4688, 0x1A10FF04}, + {0x468C, 0x282A3000}, + {0x4690, 0x2A29292A}, + {0x4694, 0x04FA2A2A}, + {0x4698, 0xEE0F04D1}, + {0x469C, 0x89291436}, + {0x80ff0000, 0x00000000}, {0x40000000, 0x00000000}, + {0x46A0, 0x0701E79E}, + {0x903300ff, 0x00000000}, {0x40000000, 0x00000000}, + {0x46A0, 0x0701E79E}, + {0x903400ff, 0x00000000}, {0x40000000, 0x00000000}, + {0x46A0, 0x0701E79E}, + {0xA0000000, 0x00000000}, + {0x46A0, 0x0701E79E}, + {0xB0000000, 0x00000000}, + {0x46A4, 0x08D07CFF}, + {0x80ff0000, 0x00000000}, {0x40000000, 0x00000000}, + {0x46A8, 0x2212FF14}, + {0x46AC, 0x60423537}, + {0x903300ff, 0x00000000}, {0x40000000, 0x00000000}, + {0x46A8, 0x4D1E7F14}, + {0x46AC, 0x60B37C4E}, + {0x903400ff, 0x00000000}, {0x40000000, 0x00000000}, + {0x46A8, 0x2212FF14}, + {0x46AC, 0x60423537}, + {0xA0000000, 0x00000000}, + {0x46A8, 0x2212FF14}, + {0x46AC, 0x60423537}, + {0xB0000000, 0x00000000}, + {0x46B0, 0x63666666}, + {0x46B4, 0x35374425}, + {0x46B8, 0x25883043}, + {0x80ff0000, 0x00000000}, {0x40000000, 0x00000000}, + {0x46BC, 0x5107C252}, + {0x4720, 0x3FFFFD63}, + {0x4724, 0xB58D11FF}, + {0x903300ff, 0x00000000}, {0x40000000, 0x00000000}, + {0x46BC, 0x5107C252}, + {0x4720, 0x27795843}, + {0x4724, 0xB58D11F5}, + {0x903400ff, 0x00000000}, {0x40000000, 0x00000000}, + {0x46BC, 0x5107C252}, + {0x4720, 0x27795303}, + {0x4724, 0xB58D11F5}, + {0xA0000000, 0x00000000}, + {0x46BC, 0x5107C252}, + {0x4720, 0x3FFFFD63}, + {0x4724, 0xB58D11FF}, + {0xB0000000, 0x00000000}, + {0x4728, 0x07FFFFFF}, + {0x472C, 0x0E7893B6}, + {0x4730, 0xE0399201}, + {0x80ff0000, 0x00000000}, {0x40000000, 0x00000000}, + {0x4734, 0x00000020}, + {0x4738, 0x8325C500}, + {0x903300ff, 0x00000000}, {0x40000000, 0x00000000}, + {0x4734, 0x003D4C20}, + {0x4738, 0x8F25C500}, + {0x903400ff, 0x00000000}, {0x40000000, 0x00000000}, + {0x4734, 0x003D5420}, + {0x4738, 0x8725C500}, + {0xA0000000, 0x00000000}, + {0x4734, 0x00000020}, + {0x4738, 0x8325C500}, + {0xB0000000, 0x00000000}, + {0x473C, 0x00000B7F}, + {0x4ACC, 0x000F7D00}, + {0x4AD0, 0x00000000}, + {0x4AD4, 0x00000040}, + {0x4AE4, 0x5379E99E}, + {0x4AE8, 0x00000744}, + {0x80ff0000, 0x00000000}, {0x40000000, 0x00000000}, + {0x4BB4, 0xFBD5B89F}, + {0x4BB8, 0x99563918}, + {0x903300ff, 0x00000000}, {0x40000000, 0x00000000}, + {0x4BB4, 0x05EBC8AF}, + {0x4BB8, 0x99543D24}, + {0x903400ff, 0x00000000}, {0x40000000, 0x00000000}, + {0x4BB4, 0xFBD5B89F}, + {0x4BB8, 0x99563918}, + {0xA0000000, 0x00000000}, + {0x4BB4, 0xFBD5B89F}, + {0x4BB8, 0x99563918}, + {0xB0000000, 0x00000000}, + {0x4BBC, 0x12EED5B8}, + {0x4BC0, 0x80C4542F}, + {0x4BC4, 0x005A007F}, + {0x4BC8, 0x40000000}, + {0x4BCC, 0x40000000}, + {0x4BD0, 0x00000000}, + {0x4BD4, 0x40000000}, + {0x4BD8, 0xC0000000}, + {0x4BDC, 0x40000000}, + {0x4BE0, 0x80000000}, + {0x4BE4, 0xBAAC8000}, + {0x4BE8, 0x638A88C5}, + {0x4BEC, 0x00900000}, + {0x4EAC, 0x00000000}, + {0x4BF0, 0x00000000}, + {0x4BF4, 0x00000000}, + {0x4BF8, 0x00000219}, + {0x4EC4, 0x00000001}, + {0x4EE8, 0x00002020}, + {0x4BFC, 0x00000000}, + {0x4C00, 0x00000010}, + {0x4C04, 0x00000001}, + {0x4C08, 0x00000001}, + {0x4C0C, 0x00000000}, + {0x4C10, 0x00000000}, + {0x4C14, 0x00000151}, + {0x4C18, 0x00000000}, + {0x4C1C, 0x00000000}, + {0x4C20, 0x00000151}, + {0x4C24, 0x00000498}, + {0x4C28, 0x00000498}, + {0x4C2C, 0x00000498}, + {0x4C30, 0x00000498}, + {0x4C34, 0x00000498}, + {0x4C38, 0x00000498}, + {0x4C3C, 0x00000498}, + {0x4C40, 0x00000498}, + {0x4C44, 0x00000000}, + {0x4C48, 0x00000000}, + {0x4C4C, 0x00001146}, + {0x4C50, 0x00000000}, + {0x4C54, 0x00000000}, + {0x4C58, 0x00001146}, + {0x4C5C, 0x00000000}, + {0x4C60, 0x00000000}, + {0x4C64, 0xE2E1E1DE}, + {0x4C68, 0xB6B600B6}, + {0x4C6C, 0xCACBCBCA}, + {0x4C70, 0x8091010F}, + {0x4C74, 0x00000B11}, + {0x46C8, 0x08882550}, + {0x46CC, 0x08CC2660}, + {0x46D0, 0x09102660}, + {0x46D4, 0x00000154}, + {0x80ff0000, 0x00000000}, {0x40000000, 0x00000000}, + {0x4740, 0xE4CD38E8}, + {0x4744, 0x4C321B04}, + {0x4748, 0x6750E466}, + {0x903300ff, 0x00000000}, {0x40000000, 0x00000000}, + {0x4740, 0xC5AD42F4}, + {0x4744, 0x412504E8}, + {0x4748, 0x6850E459}, + {0x903400ff, 0x00000000}, {0x40000000, 0x00000000}, + {0x4740, 0xE4CD38E8}, + {0x4744, 0x4C321B04}, + {0x4748, 0x6750E466}, + {0xA0000000, 0x00000000}, + {0x4740, 0xE4CD38E8}, + {0x4744, 0x4C321B04}, + {0x4748, 0x6750E466}, + {0xB0000000, 0x00000000}, + {0x474C, 0x0E0CFB0A}, + {0x4750, 0x30100F06}, + {0x4754, 0x34333333}, + {0x4758, 0x34343434}, + {0x475C, 0xC49E38E8}, + {0x4760, 0x482800E2}, + {0x4764, 0x5636E466}, + {0x4768, 0xFBEBDA00}, + {0x476C, 0x1A10FF04}, + {0x4770, 0x282A3000}, + {0x4774, 0x2A29292A}, + {0x4778, 0x04FA2A2A}, + {0x477C, 0xEE0F04D1}, + {0x49F0, 0x89291436}, + {0x80ff0000, 0x00000000}, {0x40000000, 0x00000000}, + {0x49F4, 0x0701E79E}, + {0x903300ff, 0x00000000}, {0x40000000, 0x00000000}, + {0x49F4, 0x0701E79E}, + {0x903400ff, 0x00000000}, {0x40000000, 0x00000000}, + {0x49F4, 0x0701E79E}, + {0xA0000000, 0x00000000}, + {0x49F4, 0x0701E79E}, + {0xB0000000, 0x00000000}, + {0x49FC, 0x08D07CFF}, + {0x80ff0000, 0x00000000}, {0x40000000, 0x00000000}, + {0x4A5C, 0x2212FF14}, + {0x4A60, 0x60423537}, + {0x903300ff, 0x00000000}, {0x40000000, 0x00000000}, + {0x4A5C, 0x4D1E7F14}, + {0x4A60, 0x60B37C4E}, + {0x903400ff, 0x00000000}, {0x40000000, 0x00000000}, + {0x4A5C, 0x2212FF14}, + {0x4A60, 0x60423537}, + {0xA0000000, 0x00000000}, + {0x4A5C, 0x2212FF14}, + {0x4A60, 0x60423537}, + {0xB0000000, 0x00000000}, + {0x4A64, 0x63666666}, + {0x4A68, 0x35374425}, + {0x4A6C, 0x25883043}, + {0x80ff0000, 0x00000000}, {0x40000000, 0x00000000}, + {0x4A70, 0x5107C252}, + {0x4A74, 0x3FFFFD63}, + {0x4A78, 0xB58D11FF}, + {0x903300ff, 0x00000000}, {0x40000000, 0x00000000}, + {0x4A70, 0x5107C252}, + {0x4A74, 0x27795843}, + {0x4A78, 0xB58D11F5}, + {0x903400ff, 0x00000000}, {0x40000000, 0x00000000}, + {0x4A70, 0x5107C252}, + {0x4A74, 0x27795303}, + {0x4A78, 0xB58D11F5}, + {0xA0000000, 0x00000000}, + {0x4A70, 0x5107C252}, + {0x4A74, 0x3FFFFD63}, + {0x4A78, 0xB58D11FF}, + {0xB0000000, 0x00000000}, + {0x4A7C, 0x07FFFFFF}, + {0x4A80, 0x0E7893B6}, + {0x4A9C, 0xE0399201}, + {0x80ff0000, 0x00000000}, {0x40000000, 0x00000000}, + {0x4AA0, 0x00000020}, + {0x4AA4, 0x8325C500}, + {0x903300ff, 0x00000000}, {0x40000000, 0x00000000}, + {0x4AA0, 0x003D4C20}, + {0x4AA4, 0x8F25C500}, + {0x903400ff, 0x00000000}, {0x40000000, 0x00000000}, + {0x4AA0, 0x003D5420}, + {0x4AA4, 0x8725C500}, + {0xA0000000, 0x00000000}, + {0x4AA0, 0x00000020}, + {0x4AA4, 0x8325C500}, + {0xB0000000, 0x00000000}, + {0x4AA8, 0x00000B7F}, + {0x4AD8, 0x000F7D00}, + {0x4ADC, 0x00000000}, + {0x4AE0, 0x00000040}, + {0x4AEC, 0x5379E99E}, + {0x4AF0, 0x00000744}, + {0x80ff0000, 0x00000000}, {0x40000000, 0x00000000}, + {0x4C78, 0xFBD5B89F}, + {0x4C7C, 0x99563918}, + {0x903300ff, 0x00000000}, {0x40000000, 0x00000000}, + {0x4C78, 0x07ECC9B0}, + {0x4C7C, 0x995B4126}, + {0x903400ff, 0x00000000}, {0x40000000, 0x00000000}, + {0x4C78, 0xFBD5B89F}, + {0x4C7C, 0x99563918}, + {0xA0000000, 0x00000000}, + {0x4C78, 0xFBD5B89F}, + {0x4C7C, 0x99563918}, + {0xB0000000, 0x00000000}, + {0x4C80, 0x12EED5B8}, + {0x4C84, 0x80C4542F}, + {0x4C88, 0x005A007F}, + {0x4C8C, 0x40000000}, + {0x4C90, 0x40000000}, + {0x4C94, 0x00000000}, + {0x4C98, 0x40000000}, + {0x4C9C, 0xC0000000}, + {0x4CA0, 0x40000000}, + {0x4CA4, 0x80000000}, + {0x4CA8, 0xBAAC8000}, + {0x4CAC, 0x638A88C5}, + {0x4CB0, 0x00900000}, + {0x4EB0, 0x00000000}, + {0x4CB4, 0x00000000}, + {0x4CB8, 0x00000000}, + {0x4CBC, 0x00000219}, + {0x4EC8, 0x00000001}, + {0x4EEC, 0x00002020}, + {0x4CC0, 0x00000000}, + {0x4CC4, 0x00000010}, + {0x4CC8, 0x00000001}, + {0x4CCC, 0x00000001}, + {0x4CD0, 0x00000000}, + {0x4CD4, 0x00000000}, + {0x4CD8, 0x00000151}, + {0x4CDC, 0x00000000}, + {0x4CE0, 0x00000000}, + {0x4CE4, 0x00000151}, + {0x4CE8, 0x00000498}, + {0x4CEC, 0x00000498}, + {0x4CF0, 0x00000498}, + {0x4CF4, 0x00000498}, + {0x4CF8, 0x00000498}, + {0x4CFC, 0x00000498}, + {0x4D00, 0x00000498}, + {0x4D04, 0x00000498}, + {0x4D08, 0x00000000}, + {0x4D0C, 0x00000000}, + {0x4D10, 0x00001146}, + {0x4D14, 0x00000000}, + {0x4D18, 0x00000000}, + {0x4D1C, 0x00001146}, + {0x4788, 0x00000000}, + {0x478C, 0xA32103FE}, + {0x4790, 0xB20A7B28}, + {0x4794, 0xC6A7B14F}, + {0x4798, 0x000000D3}, + {0x4D20, 0x00000000}, + {0x4D24, 0x0C442416}, + {0x4D28, 0x00000000}, + {0x479C, 0x009B902A}, + {0x47A0, 0x009B902A}, + {0x47A4, 0x98682C18}, + {0x47A8, 0x6318C4C1}, + {0x47AC, 0x6248C631}, + {0x47B0, 0x922A8253}, + {0x47B4, 0x00000005}, + {0x4D2C, 0x0008C0C1}, + {0x47B8, 0x00001759}, + {0x47BC, 0x4B702400}, + {0x47C0, 0x831508BA}, + {0x4A14, 0x000000E9}, + {0x4D30, 0x00000001}, + {0x4E94, 0x000000FC}, + {0x47C4, 0x9ABBCACB}, + {0x47C8, 0x56767578}, + {0x47CC, 0xBBCCBBB3}, + {0x47D0, 0x57889989}, + {0x47D4, 0x00000F45}, + {0x4D34, 0x7BB167AB}, + {0x4D38, 0xBBBBBB05}, + {0x4D3C, 0x777777BB}, + {0x4D40, 0x00015277}, + {0x47D8, 0x27039CE9}, + {0x47DC, 0x41414432}, + {0x47E0, 0x36058342}, + {0x47E4, 0x00000006}, + {0x4D44, 0x00000687}, + {0x47E8, 0x00000001}, + {0x47EC, 0x00000001}, + {0x47F0, 0xC7013016}, + {0x47F4, 0x84413016}, + {0x47F8, 0x84413016}, + {0x47FC, 0x8C413016}, + {0x4800, 0x8C40B028}, + {0x4804, 0x3140B028}, + {0x4808, 0x2940B028}, + {0x480C, 0x8440B028}, + {0x4810, 0x6318C610}, + {0x4814, 0x45334753}, + {0x4818, 0x236A6A88}, + {0x4D48, 0x8C413016}, + {0x4D4C, 0xA140B028}, + {0x4D50, 0x00150A31}, + {0x481C, 0x576DF814}, + {0x4820, 0xA08877AC}, + {0x4824, 0x0000007A}, + {0x4D54, 0x00001184}, + {0x4828, 0xBCEB4A14}, + {0x482C, 0x000A3A4A}, + {0x4830, 0xBCEB4A14}, + {0x4834, 0x000A3A4A}, + {0x4D58, 0x2F63DD3A}, + {0x4838, 0xBCBDBD85}, + {0x483C, 0x0CABB99A}, + {0x4D5C, 0x000000BC}, + {0x4840, 0x38384242}, + {0x4844, 0x0086102E}, + {0x4848, 0xCA24C82A}, + {0x4D60, 0x00000000}, + {0x4D64, 0x0000F49D}, + {0x4ED8, 0x00000001}, + {0x4D68, 0x000001C4}, + {0x4D6C, 0x00000000}, + {0x4D70, 0x38384242}, + {0x4D74, 0x030E902E}, + {0x4D78, 0x994C1502}, + {0x4D7C, 0x00017912}, + {0x4EDC, 0x00000001}, + {0x484C, 0x00008A62}, + {0x4D80, 0x00000002}, + {0x4850, 0x00000008}, + {0x4854, 0x009B902A}, + {0x4858, 0x009B902A}, + {0x485C, 0x98682C18}, + {0x4860, 0x6318C4C1}, + {0x4864, 0x6248C631}, + {0x4868, 0x922A8253}, + {0x486C, 0x00000005}, + {0x4D84, 0x0008C0C1}, + {0x4870, 0x00001759}, + {0x4874, 0x4B702400}, + {0x4878, 0x831508BA}, + {0x4A24, 0x000000E9}, + {0x4D88, 0x00000001}, + {0x4E98, 0x000000FC}, + {0x487C, 0x9898A8BB}, + {0x4880, 0x54535368}, + {0x4884, 0x999999B3}, + {0x4888, 0x35555589}, + {0x488C, 0x00000745}, + {0x4D8C, 0x6AB14487}, + {0x4D90, 0xBBBBBB04}, + {0x4D94, 0x777777BB}, + {0x4D98, 0x00015277}, + {0x4890, 0x27039CE9}, + {0x4894, 0x41414432}, + {0x4898, 0x36058342}, + {0x489C, 0x00000006}, + {0x4D9C, 0x00000687}, + {0x48A0, 0x00000001}, + {0x48A4, 0x00000001}, + {0x48A8, 0xC7013016}, + {0x48AC, 0x84413016}, + {0x48B0, 0x84413016}, + {0x48B4, 0x8C413016}, + {0x48B8, 0x8C40B028}, + {0x48BC, 0x3140B028}, + {0x48C0, 0x2940B028}, + {0x48C4, 0x8440B028}, + {0x48C8, 0x6318C610}, + {0x48CC, 0x45334753}, + {0x48D0, 0x236A6A88}, + {0x4DA0, 0x8C413016}, + {0x4DA4, 0xA140B028}, + {0x4DA8, 0x00150A31}, + {0x48D4, 0x576DF814}, + {0x48D8, 0xA08877AC}, + {0x48DC, 0x0000007A}, + {0x4DAC, 0x00001184}, + {0x48E0, 0xBCEB4A14}, + {0x48E4, 0x000A3A4A}, + {0x48E8, 0xBCEB4A14}, + {0x48EC, 0x000A3A4A}, + {0x4DB0, 0x2F63DD3A}, + {0x48F0, 0x9A8A8A85}, + {0x48F4, 0x0C9BB99A}, + {0x4DB4, 0x0000009A}, + {0x48F8, 0x38384242}, + {0x48FC, 0x0086102E}, + {0x4900, 0xCA24C82A}, + {0x4DB8, 0x00000000}, + {0x4DBC, 0x0000F49D}, + {0x4EE0, 0x00000001}, + {0x4DC0, 0x000001C4}, + {0x4DC4, 0x00000000}, + {0x4DC8, 0x38384242}, + {0x4DCC, 0x030E902E}, + {0x4DD0, 0x994C1502}, + {0x4DD4, 0x00017912}, + {0x4EE4, 0x00000001}, + {0x4904, 0x00008A62}, + {0x4DD8, 0x00000002}, + {0x4908, 0x00000008}, + {0x490C, 0x80040000}, + {0x4910, 0x80040000}, + {0x4914, 0xFE800000}, + {0x4918, 0x834C0000}, + {0x491C, 0x00000000}, + {0x4920, 0x00000000}, + {0x4924, 0x000003FF}, + {0x4928, 0x00000000}, + {0x492C, 0x00000000}, + {0x4930, 0x00000000}, + {0x4934, 0x40000000}, + {0x4938, 0x00000000}, + {0x493C, 0x00000000}, + {0x4940, 0x00000000}, + {0x4944, 0x00000000}, + {0x4948, 0x04065800}, + {0x494C, 0x02010080}, + {0x4950, 0x0E1E3E05}, + {0x4954, 0x0A163068}, + {0x4958, 0x00206040}, + {0x495C, 0x02020202}, + {0x4960, 0x00002020}, + {0x4DDC, 0x18002000}, + {0x4DE0, 0x00004001}, + {0x4DE4, 0x00040004}, + {0x4DE8, 0x00400040}, + {0x4DEC, 0x04000400}, + {0x4DF0, 0x08080618}, + {0x4DF4, 0x08081616}, + {0x4DF8, 0x08080808}, + {0x4DFC, 0x18180808}, + {0x4E00, 0x01020100}, + {0x4E04, 0x05020502}, + {0x4E08, 0x00020E0F}, + {0x4E0C, 0x00000000}, + {0x4E10, 0x16080806}, + {0x4E14, 0x08080816}, + {0x4E18, 0x08080808}, + {0x4E1C, 0x00181808}, + {0x4E20, 0x02010201}, + {0x4E24, 0x0F050205}, + {0x4E28, 0x0000020E}, + {0x4E2C, 0x00000000}, + {0x4E70, 0x00000001}, + {0x4970, 0x00000000}, + {0x4974, 0xC00CD62D}, + {0x4978, 0x00000103}, + {0x4E30, 0x02E416A8}, + {0x497C, 0x00000000}, + {0x4980, 0x00000000}, + {0x4984, 0x00000000}, + {0x4988, 0x00000000}, + {0x498C, 0x00000000}, + {0x4E34, 0x00FC0000}, + {0x4E38, 0x0000F800}, + {0x4E3C, 0x00000001}, + {0x4990, 0x00000000}, + {0x4994, 0x00000000}, + {0x4998, 0x00000000}, + {0x499C, 0x00000000}, + {0x49A0, 0x00000000}, + {0x4E40, 0x00FC0000}, + {0x4E44, 0x0000F800}, + {0x4E48, 0x00000001}, + {0xC54, 0x10014368}, + {0xC58, 0x61000000}, + {0xC5C, 0x805580F0}, + {0xC64, 0x0010A030}, + {0x189C, 0x000003FF}, + {0xC6C, 0x00060020}, + {0xC3C, 0x2840E1BF}, + {0xC40, 0x00000000}, + {0xC44, 0x00000007}, + {0xC48, 0x410E4000}, + {0xC54, 0x1EE1436A}, + {0xC58, 0x61000000}, + {0x730, 0x00000002}, + {0xC60, 0x017FFFF2}, + {0xC64, 0x0010A170}, + {0xC64, 0x0010A170}, + {0xC68, 0x000000FF}, + {0xC64, 0x0010A130}, + {0xC54, 0x1AE1436A}, + {0xC6C, 0x00060020}, + {0xC58, 0x41000000}, + {0x708, 0x00000000}, + {0xC6C, 0x00061020}, + {0x884, 0x0043F01D}, + {0x704, 0x601E0100}, + {0x710, 0xEF810000}, + {0xC54, 0x1AE1436A}, + {0xC58, 0x41000000}, + {0xC68, 0x10000050}, + {0xC6C, 0x20061020}, + {0x704, 0x601E0100}, + {0xC74, 0x00000000}, + {0x90C, 0x00300000}, + {0xC70, 0x071BFC00}, + {0xC74, 0x3FFFFFFF}, + {0xC78, 0x3FFFFFFF}, + {0xC7C, 0x0000BFFF}, + {0xD40, 0xF64FA0F7}, + {0xD44, 0x0400463F}, + {0xD48, 0x0003FFFF}, + {0xD4C, 0x00000000}, + {0xD50, 0xF64FA0F7}, + {0xD54, 0x04100437}, + {0xD58, 0x0000FF7F}, + {0xD5C, 0x00000000}, + {0xD60, 0x00000000}, + {0xD64, 0x00000000}, + {0xD70, 0x00000015}, + {0xD90, 0x000003FF}, + {0xD94, 0x00000000}, + {0xD98, 0x0000003F}, + {0xD9C, 0x00000000}, + {0xDA0, 0x000003FE}, + {0xDA4, 0x00000000}, + {0xDA8, 0x0000003F}, + {0xDAC, 0x00000000}, + {0xD00, 0x77777777}, + {0xD04, 0xBBBBBBBB}, + {0xD08, 0xBBBBBBBB}, + {0xD0C, 0x00000070}, + {0xD10, 0x20110900}, + {0xD10, 0x20110FFF}, + {0xD78, 0x00000001}, + {0xD7C, 0x001C040A}, + {0xD84, 0x00006007}, + {0xD84, 0x00006607}, + {0xD10, 0x28110FFF}, + {0xD18, 0x50209900}, + {0xD80, 0x00804100}, + {0xD80, 0x00804200}, + {0x718, 0x1333233F}, + {0x604, 0x041E1E1E}, + {0x714, 0x00010000}, + {0x586C, 0x000000F0}, + {0x586C, 0x000000E0}, + {0x586C, 0x000000D0}, + {0x586C, 0x000000C0}, + {0x586C, 0x000000B0}, + {0x586C, 0x000000A0}, + {0x586C, 0x00000090}, + {0x586C, 0x00000080}, + {0x586C, 0x00000070}, + {0x586C, 0x00000060}, + {0x586C, 0x00000050}, + {0x586C, 0x00000040}, + {0x586C, 0x00000030}, + {0x586C, 0x00000020}, + {0x586C, 0x00000010}, + {0x586C, 0x00000000}, + {0x786C, 0x000000F0}, + {0x786C, 0x000000E0}, + {0x786C, 0x000000D0}, + {0x786C, 0x000000C0}, + {0x786C, 0x000000B0}, + {0x786C, 0x000000A0}, + {0x786C, 0x00000090}, + {0x786C, 0x00000080}, + {0x786C, 0x00000070}, + {0x786C, 0x00000060}, + {0x786C, 0x00000050}, + {0x786C, 0x00000040}, + {0x786C, 0x00000030}, + {0x786C, 0x00000020}, + {0x786C, 0x00000010}, + {0x786C, 0x00000000}, + {0x304, 0x0CE31333}, + {0x300, 0xF30CE31C}, + {0x304, 0x13EF1F19}, + {0x308, 0x0C13E3F3}, + {0x30C, 0x130C0C0C}, + {0x310, 0x80496000}, + {0x314, 0x0041E000}, + {0x318, 0x20022042}, + {0x31C, 0x20448009}, + {0x320, 0x00490040}, + {0x324, 0xE0000070}, + {0x328, 0xE000E000}, + {0x32C, 0x0041E000}, + {0x35C, 0x000004C4}, + {0xC0D4, 0xA7C41460}, + {0xC0D8, 0xC6BA7F67}, + {0xC0DC, 0x30C52868}, + {0xC0E0, 0x75008128}, + {0xC0E4, 0x0000272B}, + {0xC1D4, 0xA7C41460}, + {0xC1D8, 0xC6BA7F67}, + {0xC1DC, 0x30C52868}, + {0xC1E0, 0x75008128}, + {0xC1E4, 0x0000272B}, + {0xC0EC, 0x00030003}, + {0xC1EC, 0x00030003}, + {0xC004, 0x03020000}, + {0xC024, 0x03020000}, + {0xC104, 0x03020000}, + {0xC124, 0x03020000}, + {0xC0E8, 0x000A0C81}, + {0xC0F0, 0x00000024}, + {0xC1E8, 0x000A0C81}, + {0xC1F0, 0x00000024}, + {0x334, 0xFFFFFFFF}, + {0x33C, 0x55000000}, + {0x340, 0x00005555}, + {0x724, 0x00111201}, + {0x5868, 0xA9550000}, + {0x5870, 0x33221100}, + {0x5874, 0x77665544}, + {0x5878, 0xBBAA9988}, + {0x587C, 0xFFEEDDCC}, + {0x5880, 0x76543210}, + {0x5884, 0xFEDCBA98}, + {0x5888, 0x00000000}, + {0x588C, 0x00000000}, + {0x5894, 0x00000008}, + {0x7868, 0xA9550000}, + {0x7870, 0x33221100}, + {0x7874, 0x77665544}, + {0x7878, 0xBBAA9988}, + {0x787C, 0xFFEEDDCC}, + {0x7880, 0x76543210}, + {0x7884, 0xFEDCBA98}, + {0x7888, 0x00000000}, + {0x788C, 0x00000000}, + {0x7894, 0x00000008}, + {0x650, 0x00200888}, + {0x710, 0xF3810000}, + {0x020, 0x0000F381}, + {0x024, 0x0000F381}, + {0xC0A8, 0x00000080}, + {0xC0AC, 0x00000100}, + {0xC0B8, 0x00020000}, + {0xC1A8, 0x00000080}, + {0xC1AC, 0x00000100}, + {0xC1B8, 0x00020000}, + {0x1038, 0x00003100}, + {0x1038, 0x00003100}, + {0x3038, 0x00003100}, + {0x3038, 0x00003100}, + {0xC14, 0xA5000000}, + {0x908, 0x00000001}, + {0xC54, 0x1EE14368}, + {0xC88, 0xC2AC8000}, + {0xC8C, 0x02F2FC08}, + {0xC70, 0x071BFC00}, + {0x980, 0x10002251}, + {0x988, 0x3C3C4107}, + {0x904, 0x00000005}, + {0x994, 0x00000010}, + {0x000, 0x0580801F}, + {0x240C, 0x00000000}, + {0x010, 0x000C01FF}, + {0x010, 0x001C01FF}, + {0x2424, 0x00000008}, + {0x620, 0x00141A30}, + {0x660, 0x00000004}, + {0x2620, 0x00141A30}, + {0x2660, 0x00000000}, + {0x640, 0x180A141E}, + {0x640, 0x1814141E}, + {0x640, 0x1814141E}, + {0x640, 0x14141414}, + {0x644, 0x3C14283C}, + {0x644, 0x3C29283C}, + {0x644, 0x3C29203C}, + {0x644, 0x3C29201A}, + {0x2640, 0x180A141E}, + {0x2640, 0x1814141E}, + {0x2640, 0x1814141E}, + {0x2640, 0x14141414}, + {0x2644, 0x3C14283C}, + {0x2644, 0x3C29283C}, + {0x2644, 0x3C29203C}, + {0x2644, 0x3C29201A}, + {0x620, 0x00141A40}, + {0x64C, 0x1D0A141E}, + {0x64C, 0x1D1D141E}, + {0x64C, 0x1D1D1D1E}, + {0x2620, 0x00141A40}, + {0x264C, 0x1D0A141E}, + {0x264C, 0x1D1D141E}, + {0x264C, 0x1D1D1D1E}, + {0x2300, 0x03020100}, + {0x2304, 0x07060504}, + {0x2308, 0x0B0A0908}, + {0x230C, 0x0F0E0D0C}, + {0x2310, 0x13121110}, + {0x2314, 0x17161514}, + {0x2318, 0x00000018}, + {0x231C, 0x00C00000}, + {0x2320, 0x00000000}, + {0x2324, 0x0005298F}, + {0x2328, 0x0015296E}, + {0x232C, 0x0D3B5200}, + {0x2330, 0x00000000}, + {0x2334, 0x00000000}, + {0x2338, 0x00000000}, + {0x233C, 0x00000402}, + {0x2340, 0x00020080}, + {0x2344, 0x03C00000}, + {0x2348, 0x0001FFFF}, + {0x234C, 0x00C80064}, + {0x2350, 0x0190012C}, + {0x2354, 0x000032FE}, + {0x2358, 0xF0203C28}, + {0x235C, 0xF027C000}, + {0x2360, 0x01210C00}, + {0x2320, 0x00000001}, + {0x2300, 0x0C811B40}, + {0x2304, 0xF3FC4ED8}, + {0x2308, 0x08FF808F}, + {0x230C, 0xFCBC80C8}, + {0x2310, 0xBC80536C}, + {0x2314, 0x0363A0F3}, + {0x2318, 0x000000BB}, + {0x724, 0x00111200}, + {0x704, 0x601E0D00}, + {0xC78, 0xBFFFFFFF}, + {0x704, 0x601E0D02}, + {0x704, 0x601E0D02}, + {0x5864, 0x080801FF}, + {0x7864, 0x080801FF}, + {0xC60, 0x017FFFF3}, + {0xC6C, 0x20061021}, + {0x58AC, 0x08000000}, + {0x78AC, 0x08000000}, + {0x8088, 0x007F0000}, + {0x81A4, 0x003F3A00}, + {0x81B4, 0x0100007F}, + {0x81C0, 0x0060010B}, + {0x81A0, 0x00000010}, + {0x8138, 0x40000002}, + {0x82A4, 0x003F3A00}, + {0x82B4, 0x0100007F}, + {0x82C0, 0x0060010B}, + {0x82A0, 0x00000010}, + {0x81A0, 0x00000010}, + {0x8238, 0x40000002}, + {0x8088, 0x00000000}, + {0x8020, 0x00000000}, + {0x8120, 0x00000000}, + {0x8220, 0x00000000}, + {0x8124, 0x00000F0F}, + {0x8224, 0x00000F0F}, + {0x5864, 0x180801FF}, + {0x7864, 0x180801FF}, + {0xC60, 0x017FFFF3}, + {0xC70, 0x071BFE00}, + {0xC70, 0x071BFE60}, + {0xC6C, 0x20061021}, + {0x58AC, 0x08000000}, + {0x78AC, 0x08000000}, + {0x8120, 0x10000000}, + {0x8120, 0x10030000}, + {0x8124, 0x00000F0F}, + {0x8124, 0x00000F0F}, + {0x8224, 0x00000F0F}, + {0x8224, 0x00000F0F}, + {0x8220, 0x10000000}, + {0x8220, 0x10030000}, + {0x704, 0x601E0D00}, + {0x5864, 0x100801FF}, + {0x7864, 0x100801FF}, + {0x5864, 0x180801FF}, + {0x7864, 0x180801FF}, + {0xC60, 0x017FFFF3}, + {0x58D4, 0x7401FE00}, + {0x78D4, 0x7401FE00}, + {0x58F0, 0x400401FF}, + {0x78F0, 0x400401FF}, + {0x58F0, 0x400401FF}, + {0x78F0, 0x400401FF}, + {0x704, 0x601E0D02}, + {0xC7C, 0x0020BFFF}, + {0x58C0, 0x00FE0000}, + {0x58FC, 0x00000000}, + {0x566C, 0x00010005}, + {0x566C, 0x00011005}, + {0x700, 0x00000030}, + {0x9D0, 0x00001001}, + {0x704, 0x601E0D02}, + {0x704, 0x601E0D00}, + {0x704, 0x601C0502}, + {0x000, 0x0580801F}, + {0x980, 0x10002250}, + {0x010, 0x001C01FF}, + {0xC3C, 0x2840E1BF}, + {0x12A8, 0x33337824}, + {0x32A8, 0x33337824}, + {0x620, 0x00141A40}, + {0x2320, 0x00000000}, + {0x664, 0x0000000C}, + {0xC0F8, 0x00000001}, + {0xC1F8, 0x00000001}, + {0x2D7C, 0x739C040A}, + {0x1010, 0x00000000}, + {0x3010, 0x00000000}, + {0x2C14, 0x80000005}, + {0x5818, 0x082C1800}, + {0x7818, 0x082C1800}, + {0x624, 0x0101030A}, + {0x028, 0x0000F381}, + {0x02C, 0x0000F381}, + {0x720, 0x20000000}, + {0x1200, 0x00010142}, + {0x12A0, 0x24903056}, + {0x12AC, 0x12333121}, + {0x12B8, 0x30020000}, + {0x2000, 0x18BBBF84}, + {0x2C14, 0x85000005}, + {0x3200, 0x00010142}, + {0x32A0, 0x24903056}, + {0x32AC, 0x12333121}, + {0x32B8, 0x30020000}, + {0x5800, 0x03FF807F}, + {0x5804, 0x04237040}, + {0x5808, 0x04237040}, + {0x7800, 0x03FF807F}, + {0x7804, 0x04237040}, + {0x7808, 0x04237040}, + {0x010, 0x001C61FF}, + {0x56C8, 0x0E800400}, + {0x76C8, 0x0E800400}, + {0x984, 0x000000E0}, + {0x2008, 0x000FFFFF}, + {0x58B0, 0x00000800}, + {0x5A00, 0x00000000}, + {0x5A04, 0x00000000}, + {0x5A08, 0x00000000}, + {0x5A0C, 0x00000000}, + {0x5A10, 0x00000000}, + {0x5A14, 0x00000000}, + {0x5A18, 0x00000000}, + {0x5A1C, 0x00000000}, + {0x5A20, 0x00000000}, + {0x5A24, 0x00050000}, + {0x5A28, 0x00000000}, + {0x5A2C, 0x00000000}, + {0x5A30, 0x00000000}, + {0x5A34, 0x00000000}, + {0x5A38, 0x00000000}, + {0x5A3C, 0x00000000}, + {0x5A40, 0x00000000}, + {0x5A44, 0x00000005}, + {0x5A48, 0x00000000}, + {0x5A4C, 0x00000000}, + {0x5A50, 0x00000000}, + {0x5A54, 0x00000000}, + {0x5A58, 0x00000000}, + {0x5A5C, 0x00000000}, + {0x5A60, 0x00050000}, + {0x5A64, 0x00000000}, + {0x5A68, 0x00000000}, + {0x5A6C, 0x00000000}, + {0x5A70, 0x00000000}, + {0x5A74, 0x00000000}, + {0x5A78, 0x00000000}, + {0x5A7C, 0x00000000}, + {0x5A80, 0x00000000}, + {0x5A84, 0x00000000}, + {0x5A88, 0x00000000}, + {0x5A8C, 0x00000000}, + {0x5A90, 0x00000000}, + {0x5A94, 0x00000000}, + {0x5A98, 0x00000000}, + {0x5A9C, 0x00000000}, + {0x5AA0, 0x00000000}, + {0x5AA4, 0x00000000}, + {0x5AA8, 0x00000000}, + {0x5AAC, 0x00000000}, + {0x5AB0, 0x00050005}, + {0x5AB4, 0x00050005}, + {0x5AB8, 0x00050005}, + {0x5ABC, 0x00050005}, + {0x5AC0, 0x00000005}, + {0x78B0, 0x00000800}, + {0x7A00, 0x00000000}, + {0x7A04, 0x00000000}, + {0x7A08, 0x00000000}, + {0x7A0C, 0x00000000}, + {0x7A10, 0x00000000}, + {0x7A14, 0x00000000}, + {0x7A18, 0x00000000}, + {0x7A1C, 0x00000000}, + {0x7A20, 0x00000000}, + {0x7A24, 0x00050000}, + {0x7A28, 0x00000000}, + {0x7A2C, 0x00000000}, + {0x7A30, 0x00000000}, + {0x7A34, 0x00000000}, + {0x7A38, 0x00000000}, + {0x7A3C, 0x00000000}, + {0x7A40, 0x00000000}, + {0x7A44, 0x00000005}, + {0x7A48, 0x00000000}, + {0x7A4C, 0x00000000}, + {0x7A50, 0x00000000}, + {0x7A54, 0x00000000}, + {0x7A58, 0x00000000}, + {0x7A5C, 0x00000000}, + {0x7A60, 0x00050000}, + {0x7A64, 0x00000000}, + {0x7A68, 0x00000000}, + {0x7A6C, 0x00000000}, + {0x7A70, 0x00000000}, + {0x7A74, 0x00000000}, + {0x7A78, 0x00000000}, + {0x7A7C, 0x00000000}, + {0x7A80, 0x00000000}, + {0x7A84, 0x00000000}, + {0x7A88, 0x00000000}, + {0x7A8C, 0x00000000}, + {0x7A90, 0x00000000}, + {0x7A94, 0x00000000}, + {0x7A98, 0x00000000}, + {0x7A9C, 0x00000000}, + {0x7AA0, 0x00000000}, + {0x7AA4, 0x00000000}, + {0x7AA8, 0x00000000}, + {0x7AAC, 0x00000000}, + {0x7AB0, 0x00050005}, + {0x7AB4, 0x00050005}, + {0x7AB8, 0x00050005}, + {0x7ABC, 0x00050005}, + {0x7AC0, 0x00000005}, + {0x0F0, 0x00010000}, + {0x0F4, 0x00000018}, + {0x0F8, 0x20220120}, +}; + +static const struct rtw89_reg2_def rtw89_8852c_phy_bb_reg_gain[] = { + {0xF0FF0000, 0x00000000}, + {0xF03300FF, 0x00000001}, + {0x000, 0x01E3C39F}, + {0x001, 0x00694727}, + {0x002, 0x00005536}, + {0x100, 0x02E3C39F}, + {0x101, 0x0069472A}, + {0x102, 0x00005536}, + {0x80ff0000, 0x00000000}, {0x40000000, 0x00000000}, + {0x10000, 0x1A02E1C9}, + {0x10001, 0x00644A30}, + {0x10002, 0x00006750}, + {0x903300ff, 0x00000000}, {0x40000000, 0x00000000}, + {0x10000, 0x0EF4D1B9}, + {0x10001, 0x00584125}, + {0x10002, 0x00006750}, + {0xA0000000, 0x00000000}, + {0x10000, 0x1A02E1C9}, + {0x10001, 0x00644A30}, + {0x10002, 0x00006750}, + {0xB0000000, 0x00000000}, + {0x80ff0000, 0x00000000}, {0x40000000, 0x00000000}, + {0x10100, 0x1901E1C8}, + {0x10101, 0x0061482D}, + {0x10102, 0x00006750}, + {0x903300ff, 0x00000000}, {0x40000000, 0x00000000}, + {0x10100, 0x04E8C5AD}, + {0x10101, 0x00594125}, + {0x10102, 0x00006850}, + {0xA0000000, 0x00000000}, + {0x10100, 0x1901E1C8}, + {0x10101, 0x0061482D}, + {0x10102, 0x00006750}, + {0xB0000000, 0x00000000}, + {0x80ff0000, 0x00000000}, {0x40000000, 0x00000000}, + {0x20000, 0x1601E2CA}, + {0x20001, 0x005D452A}, + {0x20002, 0x00006750}, + {0x903300ff, 0x00000000}, {0x40000000, 0x00000000}, + {0x20000, 0x0EF4D3BB}, + {0x20001, 0x00563F25}, + {0x20002, 0x00006850}, + {0xA0000000, 0x00000000}, + {0x20000, 0x1601E2CA}, + {0x20001, 0x005D452A}, + {0x20002, 0x00006750}, + {0xB0000000, 0x00000000}, + {0x80ff0000, 0x00000000}, {0x40000000, 0x00000000}, + {0x20100, 0x1901E1C8}, + {0x20101, 0x0061482D}, + {0x20102, 0x00006750}, + {0x903300ff, 0x00000000}, {0x40000000, 0x00000000}, + {0x20100, 0x0BF1CFB7}, + {0x20101, 0x00574025}, + {0x20102, 0x00006750}, + {0xA0000000, 0x00000000}, + {0x20100, 0x1901E1C8}, + {0x20101, 0x0061482D}, + {0x20102, 0x00006750}, + {0xB0000000, 0x00000000}, + {0x80ff0000, 0x00000000}, {0x40000000, 0x00000000}, + {0x30000, 0x1700E1CA}, + {0x30001, 0x005E472B}, + {0x30002, 0x00006750}, + {0x903300ff, 0x00000000}, {0x40000000, 0x00000000}, + {0x30000, 0x05EFCEB7}, + {0x30001, 0x004B351A}, + {0x30002, 0x00006850}, + {0xA0000000, 0x00000000}, + {0x30000, 0x1700E1CA}, + {0x30001, 0x005E472B}, + {0x30002, 0x00006750}, + {0xB0000000, 0x00000000}, + {0x80ff0000, 0x00000000}, {0x40000000, 0x00000000}, + {0x30100, 0x14FEE0C9}, + {0x30101, 0x00594428}, + {0x30102, 0x00006650}, + {0x903300ff, 0x00000000}, {0x40000000, 0x00000000}, + {0x30100, 0x0CF2D1B9}, + {0x30101, 0x00563F24}, + {0x30102, 0x00006750}, + {0xA0000000, 0x00000000}, + {0x30100, 0x14FEE0C9}, + {0x30101, 0x00594428}, + {0x30102, 0x00006650}, + {0xB0000000, 0x00000000}, + {0x40000, 0x13FCDDC8}, + {0x40001, 0x005D4328}, + {0x40002, 0x00006850}, + {0x40100, 0x14FEE3CF}, + {0x40101, 0x00583E24}, + {0x40102, 0x00006850}, + {0x50000, 0x0DF4D6C6}, + {0x50001, 0x00604227}, + {0x50002, 0x00006850}, + {0x50100, 0x1903E7D5}, + {0x50101, 0x0061462B}, + {0x50102, 0x00006850}, + {0x60000, 0x0FF5D7C6}, + {0x60001, 0x005D4429}, + {0x60002, 0x00006850}, + {0x60100, 0x12FADECF}, + {0x60101, 0x005B4126}, + {0x60102, 0x00006850}, + {0x70000, 0x09F1D2C3}, + {0x70001, 0x00554026}, + {0x70002, 0x00006750}, + {0x70100, 0x0CF5DACC}, + {0x70101, 0x00563E25}, + {0x70102, 0x00006750}, + {0x2000000, 0x02E4C4A0}, + {0x2000001, 0x006A4828}, + {0x2000100, 0x02E4C5A1}, + {0x2000101, 0x00664629}, + {0x2010000, 0x05EBC8AF}, + {0x2010001, 0x00543D24}, + {0x2010100, 0x07ECC9B0}, + {0x2010101, 0x005B4126}, + {0x2020000, 0x05EDCCB2}, + {0x2020001, 0x004D361C}, + {0x2020100, 0x06ECCBB2}, + {0x2020101, 0x00553D22}, + {0x2030000, 0x02ECCCB3}, + {0x2030001, 0x00483118}, + {0x2030100, 0x04ECCCB2}, + {0x2030101, 0x004F381C}, + {0x3000000, 0x00000000}, + {0x3000001, 0x00000000}, + {0x3000002, 0x00000000}, + {0x3000003, 0x00000000}, + {0x3000100, 0x00000000}, + {0x3000101, 0x00000000}, + {0x3000102, 0x00000000}, + {0x3000103, 0x00000000}, + {0x3010000, 0x0E0CFB0A}, + {0x3010001, 0x00100F06}, + {0x3010002, 0x34333333}, + {0x3010003, 0x3434343C}, + {0x3010100, 0x0E0CFB0A}, + {0x3010101, 0x00100F06}, + {0x3010102, 0x34333333}, + {0x3010103, 0x3434343C}, + {0x3020000, 0x0E0CFB0A}, + {0x3020001, 0x00100F06}, + {0x3020002, 0x34333333}, + {0x3020003, 0x3434343C}, + {0x3020100, 0x0E0CFB0A}, + {0x3020101, 0x00100F06}, + {0x3020102, 0x34333333}, + {0x3020103, 0x3434343C}, + {0x3030000, 0x0E0CFB0A}, + {0x3030001, 0x00100F06}, + {0x3030002, 0x34333333}, + {0x3030003, 0x3434343C}, + {0x3030100, 0x0E0CFB0A}, + {0x3030101, 0x00100F06}, + {0x3030102, 0x34333333}, + {0x3030103, 0x3434343C}, + {0x3040000, 0x0E0CFB0A}, + {0x3040001, 0x00100F06}, + {0x3040002, 0x343B3333}, + {0x3040003, 0x34343C3C}, + {0x3040100, 0x0E0CFB0A}, + {0x3040101, 0x00100F06}, + {0x3040102, 0x343B3333}, + {0x3040103, 0x34343C3C}, + {0x3050000, 0x0E0CFB0A}, + {0x3050001, 0x00100F06}, + {0x3050002, 0x343B3333}, + {0x3050003, 0x34343C3C}, + {0x3050100, 0x0E0CFB0A}, + {0x3050101, 0x00100F06}, + {0x3050102, 0x343B3333}, + {0x3050103, 0x34343C3C}, + {0x3060000, 0x0E0CFB0A}, + {0x3060001, 0x00100F06}, + {0x3060002, 0x3C3B3333}, + {0x3060003, 0x34343C3C}, + {0x3060100, 0x0E0CFB0A}, + {0x3060101, 0x00100F06}, + {0x3060102, 0x3C3B3333}, + {0x3060103, 0x34343C3C}, + {0x3070000, 0x0E0CFB0A}, + {0x3070001, 0x00100F06}, + {0x3070002, 0x3C3B3333}, + {0x3070003, 0x34343C3C}, + {0x3070100, 0x0E0CFB0A}, + {0x3070101, 0x00100F06}, + {0x3070102, 0x3C3B3333}, + {0x3070103, 0x34343C3C}, +}; + +static const struct rtw89_reg2_def rtw89_8852c_phy_radioa_regs[] = { + {0xF0010000, 0x00000000}, + {0xF0020000, 0x00000001}, + {0xF0320000, 0x00000002}, + {0xF0330000, 0x00000003}, + {0xF0340000, 0x00000004}, + {0xF0350000, 0x00000005}, + {0xF0360000, 0x00000006}, + {0xF0010001, 0x00000007}, + {0xF0020001, 0x00000008}, + {0xF0320001, 0x00000009}, + {0xF0330001, 0x0000000A}, + {0xF0340001, 0x0000000B}, + {0xF0350001, 0x0000000C}, + {0xF0360001, 0x0000000D}, + {0xF03F0001, 0x0000000E}, + {0xF0400001, 0x0000000F}, + {0x005, 0x00000000}, + {0x10005, 0x00000000}, + {0x000, 0x00030001}, + {0x10000, 0x00030000}, + {0x018, 0x00011124}, + {0x10018, 0x00011124}, + {0x0EF, 0x00080000}, + {0x033, 0x00000001}, + {0x03E, 0x00000620}, + {0x03F, 0x0000020C}, + {0x0EF, 0x00000000}, + {0x05F, 0x00000032}, + {0x097, 0x00043200}, + {0x0A6, 0x00066DB7}, + {0x0EF, 0x00004000}, + {0x033, 0x00000005}, + {0x03E, 0x00000000}, + {0x03F, 0x00010500}, + {0x033, 0x00000003}, + {0x03E, 0x00000000}, + {0x03F, 0x00028B00}, + {0x033, 0x00000002}, + {0x03E, 0x00000000}, + {0x03F, 0x0009AB00}, + {0x033, 0x0000000D}, + {0x03E, 0x00000000}, + {0x03F, 0x00010500}, + {0x033, 0x0000000B}, + {0x03E, 0x00000000}, + {0x03F, 0x00028B00}, + {0x033, 0x0000000A}, + {0x03E, 0x00000000}, + {0x03F, 0x0009AB00}, + {0x0EF, 0x00000000}, + {0x000, 0x00033C01}, + {0x10000, 0x00033C00}, + {0x01A, 0x00040004}, + {0x0FE, 0x00000000}, + {0x096, 0x00015200}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x067, 0x0004D000}, + {0x0DA, 0x000D4009}, + {0x90020000, 0x00000000}, {0x40000000, 0x00000000}, + {0x067, 0x0004D000}, + {0x0DA, 0x000D4009}, + {0x90320000, 0x00000000}, {0x40000000, 0x00000000}, + {0x067, 0x0004D000}, + {0x0DA, 0x000D4009}, + {0x90330000, 0x00000000}, {0x40000000, 0x00000000}, + {0x067, 0x0004D000}, + {0x0DA, 0x000D4009}, + {0x90340000, 0x00000000}, {0x40000000, 0x00000000}, + {0x067, 0x0004D000}, + {0x0DA, 0x000D4009}, + {0x90350000, 0x00000000}, {0x40000000, 0x00000000}, + {0x067, 0x0004D000}, + {0x0DA, 0x000D4009}, + {0x90360000, 0x00000000}, {0x40000000, 0x00000000}, + {0x067, 0x0004D000}, + {0x0DA, 0x000D4009}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x067, 0x0000D300}, + {0x0DA, 0x000D4000}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x067, 0x0000D300}, + {0x0DA, 0x000D4000}, + {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, + {0x067, 0x0000D300}, + {0x0DA, 0x000D4000}, + {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, + {0x067, 0x0000D300}, + {0x0DA, 0x000D4000}, + {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, + {0x067, 0x0000D300}, + {0x0DA, 0x000D4000}, + {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, + {0x067, 0x0000D300}, + {0x0DA, 0x000D4000}, + {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, + {0x067, 0x0000D300}, + {0x0DA, 0x000D4000}, + {0x903f0001, 0x00000000}, {0x40000000, 0x00000000}, + {0x067, 0x0000D300}, + {0x0DA, 0x000D4000}, + {0x90400001, 0x00000000}, {0x40000000, 0x00000000}, + {0x067, 0x0000D300}, + {0x0DA, 0x000D4000}, + {0xA0000000, 0x00000000}, + {0x067, 0x0004D000}, + {0x0DA, 0x000D4009}, + {0xB0000000, 0x00000000}, + {0x057, 0x0000D589}, + {0x05A, 0x0007FFFF}, + {0x043, 0x00005000}, + {0x0B5, 0x00001720}, + {0x0ED, 0x00000080}, + {0x033, 0x00000000}, + {0x03E, 0x00013FAB}, + {0x03F, 0x000FD800}, + {0x033, 0x00000010}, + {0x03E, 0x00013FAB}, + {0x03F, 0x000FD800}, + {0x033, 0x00000020}, + {0x03E, 0x00013FAB}, + {0x03F, 0x000FD800}, + {0x0ED, 0x00000000}, + {0x0ED, 0x00000200}, + {0x033, 0x00000000}, + {0x03F, 0x000000FA}, + {0x033, 0x00000001}, + {0x03F, 0x000000F2}, + {0x033, 0x00000002}, + {0x03F, 0x000000EA}, + {0x033, 0x00000003}, + {0x03F, 0x000000E2}, + {0x033, 0x00000004}, + {0x03F, 0x000000DA}, + {0x033, 0x00000005}, + {0x03F, 0x000000D2}, + {0x033, 0x00000006}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000CA}, + {0x90020000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000CA}, + {0x90320000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000CA}, + {0x90330000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000CA}, + {0x90340000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000CA}, + {0x90350000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000CA}, + {0x90360000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000CA}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000CC}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000CC}, + {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000CC}, + {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000CC}, + {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000CC}, + {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000CC}, + {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000CC}, + {0x903f0001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000CC}, + {0x90400001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000CC}, + {0xA0000000, 0x00000000}, + {0x03F, 0x000000CA}, + {0xB0000000, 0x00000000}, + {0x033, 0x00000007}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000C2}, + {0x90020000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000C2}, + {0x90320000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000C2}, + {0x90330000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000C2}, + {0x90340000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000C2}, + {0x90350000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000C2}, + {0x90360000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000C2}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000C4}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000C4}, + {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000C4}, + {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000C4}, + {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000C4}, + {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000C4}, + {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000C4}, + {0x903f0001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000C4}, + {0x90400001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000C4}, + {0xA0000000, 0x00000000}, + {0x03F, 0x000000C2}, + {0xB0000000, 0x00000000}, + {0x033, 0x00000008}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000B8}, + {0x90020000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000B8}, + {0x90320000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000B8}, + {0x90330000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000B8}, + {0x90340000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000B8}, + {0x90350000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000B8}, + {0x90360000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000B8}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000BC}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000BC}, + {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000BC}, + {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000BC}, + {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000BC}, + {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000BC}, + {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000BC}, + {0x903f0001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000BC}, + {0x90400001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000BC}, + {0xA0000000, 0x00000000}, + {0x03F, 0x000000B8}, + {0xB0000000, 0x00000000}, + {0x033, 0x00000009}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000B0}, + {0x90020000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000B0}, + {0x90320000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000B0}, + {0x90330000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000B0}, + {0x90340000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000B0}, + {0x90350000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000B0}, + {0x90360000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000B0}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000B4}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000B4}, + {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000B4}, + {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000B4}, + {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000B4}, + {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000B4}, + {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000B4}, + {0x903f0001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000B4}, + {0x90400001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000B4}, + {0xA0000000, 0x00000000}, + {0x03F, 0x000000B0}, + {0xB0000000, 0x00000000}, + {0x033, 0x0000000A}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000A8}, + {0x90020000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000A8}, + {0x90320000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000A8}, + {0x90330000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000A8}, + {0x90340000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000A8}, + {0x90350000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000A8}, + {0x90360000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000A8}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000AC}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000AC}, + {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000AC}, + {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000AC}, + {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000AC}, + {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000AC}, + {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000AC}, + {0x903f0001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000AC}, + {0x90400001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000AC}, + {0xA0000000, 0x00000000}, + {0x03F, 0x000000A8}, + {0xB0000000, 0x00000000}, + {0x033, 0x0000000B}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000A0}, + {0x90020000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000A0}, + {0x90320000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000A0}, + {0x90330000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000A0}, + {0x90340000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000A0}, + {0x90350000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000A0}, + {0x90360000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000A0}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000A4}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000A4}, + {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000A4}, + {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000A4}, + {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000A4}, + {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000A4}, + {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000A4}, + {0x903f0001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000A4}, + {0x90400001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000A4}, + {0xA0000000, 0x00000000}, + {0x03F, 0x000000A0}, + {0xB0000000, 0x00000000}, + {0x033, 0x0000000C}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000098}, + {0x90020000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000098}, + {0x90320000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000098}, + {0x90330000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000098}, + {0x90340000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000098}, + {0x90350000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000098}, + {0x90360000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000098}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000009C}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000009C}, + {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000009C}, + {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000009C}, + {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000009C}, + {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000009C}, + {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000009C}, + {0x903f0001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000009C}, + {0x90400001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000009C}, + {0xA0000000, 0x00000000}, + {0x03F, 0x00000098}, + {0xB0000000, 0x00000000}, + {0x033, 0x0000000D}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000098}, + {0x90020000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000098}, + {0x90320000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000098}, + {0x90330000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000098}, + {0x90340000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000098}, + {0x90350000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000098}, + {0x90360000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000098}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000094}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000094}, + {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000094}, + {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000094}, + {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000094}, + {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000094}, + {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000094}, + {0x903f0001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000094}, + {0x90400001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000094}, + {0xA0000000, 0x00000000}, + {0x03F, 0x00000098}, + {0xB0000000, 0x00000000}, + {0x033, 0x0000000E}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000088}, + {0x90020000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000088}, + {0x90320000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000088}, + {0x90330000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000088}, + {0x90340000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000088}, + {0x90350000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000088}, + {0x90360000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000088}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000008C}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000008C}, + {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000008C}, + {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000008C}, + {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000008C}, + {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000008C}, + {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000008C}, + {0x903f0001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000008C}, + {0x90400001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000008C}, + {0xA0000000, 0x00000000}, + {0x03F, 0x00000088}, + {0xB0000000, 0x00000000}, + {0x033, 0x0000000F}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000088}, + {0x90020000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000088}, + {0x90320000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000088}, + {0x90330000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000088}, + {0x90340000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000088}, + {0x90350000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000088}, + {0x90360000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000088}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000084}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000084}, + {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000084}, + {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000084}, + {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000084}, + {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000084}, + {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000084}, + {0x903f0001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000084}, + {0x90400001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000084}, + {0xA0000000, 0x00000000}, + {0x03F, 0x00000088}, + {0xB0000000, 0x00000000}, + {0x033, 0x00000010}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000B8}, + {0x90020000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000B8}, + {0x90320000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000B8}, + {0x90330000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000B8}, + {0x90340000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000B8}, + {0x90350000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000B8}, + {0x90360000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000B8}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000BC}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000BC}, + {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000BC}, + {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000BC}, + {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000BC}, + {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000BC}, + {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000BC}, + {0x903f0001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000BC}, + {0x90400001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000BC}, + {0xA0000000, 0x00000000}, + {0x03F, 0x000000B8}, + {0xB0000000, 0x00000000}, + {0x033, 0x00000011}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000B0}, + {0x90020000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000B0}, + {0x90320000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000B0}, + {0x90330000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000B0}, + {0x90340000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000B0}, + {0x90350000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000B0}, + {0x90360000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000B0}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000B4}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000B4}, + {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000B4}, + {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000B4}, + {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000B4}, + {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000B4}, + {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000B4}, + {0x903f0001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000B4}, + {0x90400001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000B4}, + {0xA0000000, 0x00000000}, + {0x03F, 0x000000B0}, + {0xB0000000, 0x00000000}, + {0x033, 0x00000012}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000A8}, + {0x90020000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000A8}, + {0x90320000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000A8}, + {0x90330000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000A8}, + {0x90340000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000A8}, + {0x90350000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000A8}, + {0x90360000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000A8}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000AC}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000AC}, + {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000AC}, + {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000AC}, + {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000AC}, + {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000AC}, + {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000AC}, + {0x903f0001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000AC}, + {0x90400001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000AC}, + {0xA0000000, 0x00000000}, + {0x03F, 0x000000A8}, + {0xB0000000, 0x00000000}, + {0x033, 0x00000013}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000A0}, + {0x90020000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000A0}, + {0x90320000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000A0}, + {0x90330000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000A0}, + {0x90340000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000A0}, + {0x90350000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000A0}, + {0x90360000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000A0}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000A4}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000A4}, + {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000A4}, + {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000A4}, + {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000A4}, + {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000A4}, + {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000A4}, + {0x903f0001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000A4}, + {0x90400001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000000A4}, + {0xA0000000, 0x00000000}, + {0x03F, 0x000000A0}, + {0xB0000000, 0x00000000}, + {0x033, 0x00000014}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000098}, + {0x90020000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000098}, + {0x90320000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000098}, + {0x90330000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000098}, + {0x90340000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000098}, + {0x90350000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000098}, + {0x90360000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000098}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000009C}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000009C}, + {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000009C}, + {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000009C}, + {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000009C}, + {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000009C}, + {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000009C}, + {0x903f0001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000009C}, + {0x90400001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000009C}, + {0xA0000000, 0x00000000}, + {0x03F, 0x00000098}, + {0xB0000000, 0x00000000}, + {0x033, 0x00000015}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000090}, + {0x90020000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000090}, + {0x90320000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000090}, + {0x90330000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000090}, + {0x90340000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000090}, + {0x90350000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000090}, + {0x90360000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000090}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000094}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000094}, + {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000094}, + {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000094}, + {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000094}, + {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000094}, + {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000094}, + {0x903f0001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000094}, + {0x90400001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000094}, + {0xA0000000, 0x00000000}, + {0x03F, 0x00000090}, + {0xB0000000, 0x00000000}, + {0x033, 0x00000016}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000088}, + {0x90020000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000088}, + {0x90320000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000088}, + {0x90330000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000088}, + {0x90340000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000088}, + {0x90350000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000088}, + {0x90360000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000088}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000008C}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000008C}, + {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000008C}, + {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000008C}, + {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000008C}, + {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000008C}, + {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000008C}, + {0x903f0001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000008C}, + {0x90400001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000008C}, + {0xA0000000, 0x00000000}, + {0x03F, 0x00000088}, + {0xB0000000, 0x00000000}, + {0x033, 0x00000017}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000080}, + {0x90020000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000080}, + {0x90320000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000080}, + {0x90330000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000080}, + {0x90340000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000080}, + {0x90350000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000080}, + {0x90360000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000080}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000084}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000084}, + {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000084}, + {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000084}, + {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000084}, + {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000084}, + {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000084}, + {0x903f0001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000084}, + {0x90400001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000084}, + {0xA0000000, 0x00000000}, + {0x03F, 0x00000080}, + {0xB0000000, 0x00000000}, + {0x033, 0x00000018}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000038}, + {0x90020000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000038}, + {0x90320000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000038}, + {0x90330000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000038}, + {0x90340000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000038}, + {0x90350000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000038}, + {0x90360000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000038}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000003C}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000003C}, + {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000003C}, + {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000003C}, + {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000003C}, + {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000003C}, + {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000003C}, + {0x903f0001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000003C}, + {0x90400001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000003C}, + {0xA0000000, 0x00000000}, + {0x03F, 0x00000038}, + {0xB0000000, 0x00000000}, + {0x033, 0x00000019}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000030}, + {0x90020000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000030}, + {0x90320000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000030}, + {0x90330000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000030}, + {0x90340000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000030}, + {0x90350000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000030}, + {0x90360000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000030}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000034}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000034}, + {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000034}, + {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000034}, + {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000034}, + {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000034}, + {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000034}, + {0x903f0001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000034}, + {0x90400001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000034}, + {0xA0000000, 0x00000000}, + {0x03F, 0x00000030}, + {0xB0000000, 0x00000000}, + {0x033, 0x0000001A}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000028}, + {0x90020000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000028}, + {0x90320000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000028}, + {0x90330000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000028}, + {0x90340000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000028}, + {0x90350000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000028}, + {0x90360000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000028}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000002C}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000002C}, + {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000002C}, + {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000002C}, + {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000002C}, + {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000002C}, + {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000002C}, + {0x903f0001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000002C}, + {0x90400001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000002C}, + {0xA0000000, 0x00000000}, + {0x03F, 0x00000028}, + {0xB0000000, 0x00000000}, + {0x033, 0x0000001B}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000020}, + {0x90020000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000020}, + {0x90320000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000020}, + {0x90330000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000020}, + {0x90340000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000020}, + {0x90350000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000020}, + {0x90360000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000020}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000024}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000024}, + {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000024}, + {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000024}, + {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000024}, + {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000024}, + {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000024}, + {0x903f0001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000024}, + {0x90400001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000024}, + {0xA0000000, 0x00000000}, + {0x03F, 0x00000020}, + {0xB0000000, 0x00000000}, + {0x033, 0x0000001C}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000018}, + {0x90020000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000018}, + {0x90320000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000018}, + {0x90330000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000018}, + {0x90340000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000018}, + {0x90350000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000018}, + {0x90360000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000018}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000001C}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000001C}, + {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000001C}, + {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000001C}, + {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000001C}, + {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000001C}, + {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000001C}, + {0x903f0001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000001C}, + {0x90400001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000001C}, + {0xA0000000, 0x00000000}, + {0x03F, 0x00000018}, + {0xB0000000, 0x00000000}, + {0x033, 0x0000001D}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000010}, + {0x90020000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000010}, + {0x90320000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000010}, + {0x90330000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000010}, + {0x90340000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000010}, + {0x90350000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000010}, + {0x90360000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000010}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000014}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000014}, + {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000014}, + {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000014}, + {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000014}, + {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000014}, + {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000014}, + {0x903f0001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000014}, + {0x90400001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000014}, + {0xA0000000, 0x00000000}, + {0x03F, 0x00000010}, + {0xB0000000, 0x00000000}, + {0x033, 0x0000001E}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000008}, + {0x90020000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000008}, + {0x90320000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000008}, + {0x90330000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000008}, + {0x90340000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000008}, + {0x90350000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000008}, + {0x90360000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000008}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000000C}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000000C}, + {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000000C}, + {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000000C}, + {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000000C}, + {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000000C}, + {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000000C}, + {0x903f0001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000000C}, + {0x90400001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000000C}, + {0xA0000000, 0x00000000}, + {0x03F, 0x00000008}, + {0xB0000000, 0x00000000}, + {0x033, 0x0000001F}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000000}, + {0x90020000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000000}, + {0x90320000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000000}, + {0x90330000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000000}, + {0x90340000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000000}, + {0x90350000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000000}, + {0x90360000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000000}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000004}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000004}, + {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000004}, + {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000004}, + {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000004}, + {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000004}, + {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000004}, + {0x903f0001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000004}, + {0x90400001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000004}, + {0xA0000000, 0x00000000}, + {0x03F, 0x00000000}, + {0xB0000000, 0x00000000}, + {0x0ED, 0x00000000}, + {0x0B9, 0x00020440}, + {0x018, 0x00001001}, + {0x10018, 0x00001001}, + {0x002, 0x0000000D}, + {0x10002, 0x0000000D}, + {0x0EE, 0x00000000}, + {0x033, 0x0000000B}, + {0x03F, 0x0000000B}, + {0x033, 0x0000000C}, + {0x03F, 0x00000012}, + {0x033, 0x0000000D}, + {0x03F, 0x00000019}, + {0x0EE, 0x00000000}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x08F, 0x000D1752}, + {0x90020000, 0x00000000}, {0x40000000, 0x00000000}, + {0x08F, 0x000D1752}, + {0x90320000, 0x00000000}, {0x40000000, 0x00000000}, + {0x08F, 0x000D1752}, + {0x90330000, 0x00000000}, {0x40000000, 0x00000000}, + {0x08F, 0x000D1752}, + {0x90340000, 0x00000000}, {0x40000000, 0x00000000}, + {0x08F, 0x000D1752}, + {0x90350000, 0x00000000}, {0x40000000, 0x00000000}, + {0x08F, 0x000D1752}, + {0x90360000, 0x00000000}, {0x40000000, 0x00000000}, + {0x08F, 0x000D1752}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x08F, 0x000D1352}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x08F, 0x000D1352}, + {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, + {0x08F, 0x000D1352}, + {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, + {0x08F, 0x000D1352}, + {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, + {0x08F, 0x000D1352}, + {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, + {0x08F, 0x000D1352}, + {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, + {0x08F, 0x000D1352}, + {0x903f0001, 0x00000000}, {0x40000000, 0x00000000}, + {0x08F, 0x000D1352}, + {0x90400001, 0x00000000}, {0x40000000, 0x00000000}, + {0x08F, 0x000D1352}, + {0xA0000000, 0x00000000}, + {0x08F, 0x000D1752}, + {0xB0000000, 0x00000000}, + {0x0EB, 0x00000000}, + {0x030, 0x000109B0}, + {0x030, 0x000189B0}, + {0x0EB, 0x00000000}, + {0x0EE, 0x00000010}, + {0x033, 0x00000006}, + {0x03F, 0x00000003}, + {0x033, 0x00000007}, + {0x03F, 0x00000003}, + {0x033, 0x00000008}, + {0x03F, 0x00000001}, + {0x0EE, 0x00000000}, + {0x0EF, 0x00001000}, + {0x033, 0x00000000}, + {0x03F, 0x00000015}, + {0x033, 0x00000001}, + {0x03F, 0x00000017}, + {0x0EF, 0x00000000}, + {0x0EF, 0x00008000}, + {0x033, 0x00000020}, + {0x03F, 0x00060001}, + {0x033, 0x00000021}, + {0x03F, 0x00060032}, + {0x033, 0x00000022}, + {0x03F, 0x00050042}, + {0x033, 0x00000023}, + {0x03F, 0x00040042}, + {0x033, 0x00000024}, + {0x03F, 0x00000001}, + {0x033, 0x00000025}, + {0x03F, 0x00000002}, + {0x033, 0x00000026}, + {0x03F, 0x00000003}, + {0x033, 0x00000027}, + {0x03F, 0x00000003}, + {0x033, 0x00000028}, + {0x03F, 0x00060001}, + {0x033, 0x00000029}, + {0x03F, 0x00060032}, + {0x033, 0x0000002A}, + {0x03F, 0x00050042}, + {0x033, 0x0000002B}, + {0x03F, 0x00040042}, + {0x033, 0x0000002C}, + {0x03F, 0x00000001}, + {0x033, 0x0000002D}, + {0x03F, 0x00000002}, + {0x033, 0x0000002E}, + {0x03F, 0x00000003}, + {0x033, 0x0000002F}, + {0x03F, 0x00000003}, + {0x033, 0x00000030}, + {0x03F, 0x00060001}, + {0x033, 0x00000031}, + {0x03F, 0x00060032}, + {0x033, 0x00000032}, + {0x03F, 0x00050042}, + {0x033, 0x00000033}, + {0x03F, 0x00040042}, + {0x033, 0x00000034}, + {0x03F, 0x00000001}, + {0x033, 0x00000035}, + {0x03F, 0x00000002}, + {0x033, 0x00000036}, + {0x03F, 0x00000003}, + {0x033, 0x00000037}, + {0x03F, 0x00000003}, + {0x033, 0x00000060}, + {0x03F, 0x00060001}, + {0x033, 0x00000061}, + {0x03F, 0x00060032}, + {0x033, 0x00000062}, + {0x03F, 0x00050042}, + {0x033, 0x00000063}, + {0x03F, 0x00040042}, + {0x033, 0x00000064}, + {0x03F, 0x00000001}, + {0x033, 0x00000065}, + {0x03F, 0x00000002}, + {0x033, 0x00000066}, + {0x03F, 0x00000003}, + {0x033, 0x00000067}, + {0x03F, 0x00000003}, + {0x033, 0x00000068}, + {0x03F, 0x00060001}, + {0x033, 0x00000069}, + {0x03F, 0x00060032}, + {0x033, 0x0000006A}, + {0x03F, 0x00050042}, + {0x033, 0x0000006B}, + {0x03F, 0x00040042}, + {0x033, 0x0000006C}, + {0x03F, 0x00000001}, + {0x033, 0x0000006D}, + {0x03F, 0x00000002}, + {0x033, 0x0000006E}, + {0x03F, 0x00000003}, + {0x033, 0x0000006F}, + {0x03F, 0x00000003}, + {0x033, 0x00000070}, + {0x03F, 0x00060001}, + {0x033, 0x00000071}, + {0x03F, 0x00060032}, + {0x033, 0x00000072}, + {0x03F, 0x00050042}, + {0x033, 0x00000073}, + {0x03F, 0x00040042}, + {0x033, 0x00000074}, + {0x03F, 0x00000001}, + {0x033, 0x00000075}, + {0x03F, 0x00000002}, + {0x033, 0x00000076}, + {0x03F, 0x00000003}, + {0x033, 0x00000077}, + {0x03F, 0x00000003}, + {0x033, 0x00000078}, + {0x03F, 0x00060001}, + {0x033, 0x00000079}, + {0x03F, 0x00060032}, + {0x033, 0x0000007A}, + {0x03F, 0x00050042}, + {0x033, 0x0000007B}, + {0x03F, 0x00040042}, + {0x033, 0x0000007C}, + {0x03F, 0x00000001}, + {0x033, 0x0000007D}, + {0x03F, 0x00000002}, + {0x033, 0x0000007E}, + {0x03F, 0x00000003}, + {0x033, 0x0000007F}, + {0x03F, 0x00000003}, + {0x033, 0x000000A0}, + {0x03F, 0x00060001}, + {0x033, 0x000000A1}, + {0x03F, 0x00060032}, + {0x033, 0x000000A2}, + {0x03F, 0x00050042}, + {0x033, 0x000000A3}, + {0x03F, 0x00040042}, + {0x033, 0x000000A4}, + {0x03F, 0x00000001}, + {0x033, 0x000000A5}, + {0x03F, 0x00000002}, + {0x033, 0x000000A6}, + {0x03F, 0x00000003}, + {0x033, 0x000000A7}, + {0x03F, 0x00000003}, + {0x033, 0x000000A8}, + {0x03F, 0x00060001}, + {0x033, 0x000000A9}, + {0x03F, 0x00060032}, + {0x033, 0x000000AA}, + {0x03F, 0x00050042}, + {0x033, 0x000000AB}, + {0x03F, 0x00040042}, + {0x033, 0x000000AC}, + {0x03F, 0x00000001}, + {0x033, 0x000000AD}, + {0x03F, 0x00000002}, + {0x033, 0x000000AE}, + {0x03F, 0x00000003}, + {0x033, 0x000000AF}, + {0x03F, 0x00000003}, + {0x033, 0x000000B0}, + {0x03F, 0x00060001}, + {0x033, 0x000000B1}, + {0x03F, 0x00060032}, + {0x033, 0x000000B2}, + {0x03F, 0x00050042}, + {0x033, 0x000000B3}, + {0x03F, 0x00040042}, + {0x033, 0x000000B4}, + {0x03F, 0x00000001}, + {0x033, 0x000000B5}, + {0x03F, 0x00000002}, + {0x033, 0x000000B6}, + {0x03F, 0x00000003}, + {0x033, 0x000000B7}, + {0x03F, 0x00000003}, + {0x033, 0x000000E0}, + {0x03F, 0x00060001}, + {0x033, 0x000000E1}, + {0x03F, 0x00060032}, + {0x033, 0x000000E2}, + {0x03F, 0x00050042}, + {0x033, 0x000000E3}, + {0x03F, 0x00040042}, + {0x033, 0x000000E4}, + {0x03F, 0x00000001}, + {0x033, 0x000000E5}, + {0x03F, 0x00000002}, + {0x033, 0x000000E6}, + {0x03F, 0x00000003}, + {0x033, 0x000000E7}, + {0x03F, 0x00000003}, + {0x033, 0x000000E8}, + {0x03F, 0x00060001}, + {0x033, 0x000000E9}, + {0x03F, 0x00060032}, + {0x033, 0x000000EA}, + {0x03F, 0x00050042}, + {0x033, 0x000000EB}, + {0x03F, 0x00040042}, + {0x033, 0x000000EC}, + {0x03F, 0x00000001}, + {0x033, 0x000000ED}, + {0x03F, 0x00000002}, + {0x033, 0x000000EE}, + {0x03F, 0x00000003}, + {0x033, 0x000000EF}, + {0x03F, 0x00000003}, + {0x033, 0x000000F0}, + {0x03F, 0x00060001}, + {0x033, 0x000000F1}, + {0x03F, 0x00060032}, + {0x033, 0x000000F2}, + {0x03F, 0x00050042}, + {0x033, 0x000000F3}, + {0x03F, 0x00040042}, + {0x033, 0x000000F4}, + {0x03F, 0x00000001}, + {0x033, 0x000000F5}, + {0x03F, 0x00000002}, + {0x033, 0x000000F6}, + {0x03F, 0x00000003}, + {0x033, 0x000000F7}, + {0x03F, 0x00000003}, + {0x033, 0x000000F8}, + {0x03F, 0x00060001}, + {0x033, 0x000000F9}, + {0x03F, 0x00060032}, + {0x033, 0x000000FA}, + {0x03F, 0x00050042}, + {0x033, 0x000000FB}, + {0x03F, 0x00040042}, + {0x033, 0x000000FC}, + {0x03F, 0x00000001}, + {0x033, 0x000000FD}, + {0x03F, 0x00000002}, + {0x033, 0x000000FE}, + {0x03F, 0x00000003}, + {0x033, 0x000000FF}, + {0x03F, 0x00000003}, + {0x033, 0x00000120}, + {0x03F, 0x00060001}, + {0x033, 0x00000121}, + {0x03F, 0x00060032}, + {0x033, 0x00000122}, + {0x03F, 0x00050042}, + {0x033, 0x00000123}, + {0x03F, 0x00040042}, + {0x033, 0x00000124}, + {0x03F, 0x00000001}, + {0x033, 0x00000125}, + {0x03F, 0x00000002}, + {0x033, 0x00000126}, + {0x03F, 0x00000003}, + {0x033, 0x00000127}, + {0x03F, 0x00000003}, + {0x033, 0x00000128}, + {0x03F, 0x00060001}, + {0x033, 0x00000129}, + {0x03F, 0x00060032}, + {0x033, 0x0000012A}, + {0x03F, 0x00050042}, + {0x033, 0x0000012B}, + {0x03F, 0x00040042}, + {0x033, 0x0000012C}, + {0x03F, 0x00000001}, + {0x033, 0x0000012D}, + {0x03F, 0x00000002}, + {0x033, 0x0000012E}, + {0x03F, 0x00000003}, + {0x033, 0x0000012F}, + {0x03F, 0x00000003}, + {0x033, 0x00000130}, + {0x03F, 0x00060001}, + {0x033, 0x00000131}, + {0x03F, 0x00060032}, + {0x033, 0x00000132}, + {0x03F, 0x00050042}, + {0x033, 0x00000133}, + {0x03F, 0x00040042}, + {0x033, 0x00000134}, + {0x03F, 0x00000001}, + {0x033, 0x00000135}, + {0x03F, 0x00000002}, + {0x033, 0x00000136}, + {0x03F, 0x00000003}, + {0x033, 0x00000137}, + {0x03F, 0x00000003}, + {0x033, 0x00000160}, + {0x03F, 0x00060001}, + {0x033, 0x00000161}, + {0x03F, 0x00060032}, + {0x033, 0x00000162}, + {0x03F, 0x00050042}, + {0x033, 0x00000163}, + {0x03F, 0x00040042}, + {0x033, 0x00000164}, + {0x03F, 0x00000001}, + {0x033, 0x00000165}, + {0x03F, 0x00000002}, + {0x033, 0x00000166}, + {0x03F, 0x00000003}, + {0x033, 0x00000167}, + {0x03F, 0x00000003}, + {0x033, 0x00000168}, + {0x03F, 0x00060001}, + {0x033, 0x00000169}, + {0x03F, 0x00060032}, + {0x033, 0x0000016A}, + {0x03F, 0x00050042}, + {0x033, 0x0000016B}, + {0x03F, 0x00040042}, + {0x033, 0x0000016C}, + {0x03F, 0x00000001}, + {0x033, 0x0000016D}, + {0x03F, 0x00000002}, + {0x033, 0x0000016E}, + {0x03F, 0x00000003}, + {0x033, 0x0000016F}, + {0x03F, 0x00000003}, + {0x033, 0x00000170}, + {0x03F, 0x00060001}, + {0x033, 0x00000171}, + {0x03F, 0x00060032}, + {0x033, 0x00000172}, + {0x03F, 0x00050042}, + {0x033, 0x00000173}, + {0x03F, 0x00040042}, + {0x033, 0x00000174}, + {0x03F, 0x00000001}, + {0x033, 0x00000175}, + {0x03F, 0x00000002}, + {0x033, 0x00000176}, + {0x03F, 0x00000003}, + {0x033, 0x00000177}, + {0x03F, 0x00000003}, + {0x033, 0x00000178}, + {0x03F, 0x00060001}, + {0x033, 0x00000179}, + {0x03F, 0x00060032}, + {0x033, 0x0000017A}, + {0x03F, 0x00050042}, + {0x033, 0x0000017B}, + {0x03F, 0x00040042}, + {0x033, 0x0000017C}, + {0x03F, 0x00000001}, + {0x033, 0x0000017D}, + {0x03F, 0x00000002}, + {0x033, 0x0000017E}, + {0x03F, 0x00000003}, + {0x033, 0x0000017F}, + {0x03F, 0x00000003}, + {0x033, 0x000001A0}, + {0x03F, 0x00060001}, + {0x033, 0x000001A1}, + {0x03F, 0x00060032}, + {0x033, 0x000001A2}, + {0x03F, 0x00050042}, + {0x033, 0x000001A3}, + {0x03F, 0x00040042}, + {0x033, 0x000001A4}, + {0x03F, 0x00000001}, + {0x033, 0x000001A5}, + {0x03F, 0x00000002}, + {0x033, 0x000001A6}, + {0x03F, 0x00000003}, + {0x033, 0x000001A7}, + {0x03F, 0x00000003}, + {0x033, 0x000001A8}, + {0x03F, 0x00060001}, + {0x033, 0x000001A9}, + {0x03F, 0x00060032}, + {0x033, 0x000001AA}, + {0x03F, 0x00050042}, + {0x033, 0x000001AB}, + {0x03F, 0x00040042}, + {0x033, 0x000001AC}, + {0x03F, 0x00000001}, + {0x033, 0x000001AD}, + {0x03F, 0x00000002}, + {0x033, 0x000001AE}, + {0x03F, 0x00000003}, + {0x033, 0x000001AF}, + {0x03F, 0x00000003}, + {0x033, 0x000001B0}, + {0x03F, 0x00060001}, + {0x033, 0x000001B1}, + {0x03F, 0x00060032}, + {0x033, 0x000001B2}, + {0x03F, 0x00050042}, + {0x033, 0x000001B3}, + {0x03F, 0x00040042}, + {0x033, 0x000001B4}, + {0x03F, 0x00000001}, + {0x033, 0x000001B5}, + {0x03F, 0x00000002}, + {0x033, 0x000001B6}, + {0x03F, 0x00000003}, + {0x033, 0x000001B7}, + {0x03F, 0x00000003}, + {0x033, 0x000001E0}, + {0x03F, 0x00060001}, + {0x033, 0x000001E1}, + {0x03F, 0x00060032}, + {0x033, 0x000001E2}, + {0x03F, 0x00050042}, + {0x033, 0x000001E3}, + {0x03F, 0x00040042}, + {0x033, 0x000001E4}, + {0x03F, 0x00000001}, + {0x033, 0x000001E5}, + {0x03F, 0x00000002}, + {0x033, 0x000001E6}, + {0x03F, 0x00000003}, + {0x033, 0x000001E7}, + {0x03F, 0x00000003}, + {0x033, 0x000001E8}, + {0x03F, 0x00060001}, + {0x033, 0x000001E9}, + {0x03F, 0x00060032}, + {0x033, 0x000001EA}, + {0x03F, 0x00050042}, + {0x033, 0x000001EB}, + {0x03F, 0x00040042}, + {0x033, 0x000001EC}, + {0x03F, 0x00000001}, + {0x033, 0x000001ED}, + {0x03F, 0x00000002}, + {0x033, 0x000001EE}, + {0x03F, 0x00000003}, + {0x033, 0x000001EF}, + {0x03F, 0x00000003}, + {0x033, 0x000001F0}, + {0x03F, 0x00060001}, + {0x033, 0x000001F1}, + {0x03F, 0x00060032}, + {0x033, 0x000001F2}, + {0x03F, 0x00050042}, + {0x033, 0x000001F3}, + {0x03F, 0x00040042}, + {0x033, 0x000001F4}, + {0x03F, 0x00000001}, + {0x033, 0x000001F5}, + {0x03F, 0x00000002}, + {0x033, 0x000001F6}, + {0x03F, 0x00000003}, + {0x033, 0x000001F7}, + {0x03F, 0x00000003}, + {0x033, 0x000001F8}, + {0x03F, 0x00060001}, + {0x033, 0x000001F9}, + {0x03F, 0x00060032}, + {0x033, 0x000001FA}, + {0x03F, 0x00050042}, + {0x033, 0x000001FB}, + {0x03F, 0x00040042}, + {0x033, 0x000001FC}, + {0x03F, 0x00000001}, + {0x033, 0x000001FD}, + {0x03F, 0x00000002}, + {0x033, 0x000001FE}, + {0x03F, 0x00000003}, + {0x033, 0x000001FF}, + {0x03F, 0x00000003}, + {0x0EF, 0x00000000}, + {0x0EF, 0x00000100}, + {0x033, 0x00000001}, + {0x03F, 0x0000EFFF}, + {0x033, 0x00000002}, + {0x03F, 0x0000EFFF}, + {0x033, 0x00000003}, + {0x03F, 0x0000EFFF}, + {0x033, 0x00000004}, + {0x03F, 0x0000EFFF}, + {0x033, 0x00000005}, + {0x03F, 0x0000EFFF}, + {0x033, 0x00000006}, + {0x03F, 0x0000EFFF}, + {0x033, 0x00000007}, + {0x03F, 0x0000EFFF}, + {0x033, 0x00000008}, + {0x03F, 0x0000EFFF}, + {0x033, 0x00000009}, + {0x03F, 0x0000EFFF}, + {0x033, 0x0000000A}, + {0x03F, 0x0000EFFF}, + {0x033, 0x0000000B}, + {0x03F, 0x0000AFFF}, + {0x033, 0x0000000C}, + {0x03F, 0x0000EFFF}, + {0x033, 0x0000000D}, + {0x03F, 0x0000EFFF}, + {0x033, 0x0000000E}, + {0x03F, 0x0000EFFF}, + {0x033, 0x0000000F}, + {0x03F, 0x0000EFFF}, + {0x033, 0x00000010}, + {0x03F, 0x0000EFFF}, + {0x033, 0x00000011}, + {0x03F, 0x0000EFFF}, + {0x033, 0x00000012}, + {0x03F, 0x0000EFFF}, + {0x033, 0x00000013}, + {0x03F, 0x0000EFFF}, + {0x033, 0x00000014}, + {0x03F, 0x0000EFFF}, + {0x033, 0x00000015}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000E3FF}, + {0x90020000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000E3FF}, + {0x90320000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000E3FF}, + {0x90330000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000E3FF}, + {0x90340000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000E3FF}, + {0x90350000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000E3FF}, + {0x90360000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000E3FF}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000EFFF}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000EFFF}, + {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000EFFF}, + {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000EFFF}, + {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000EFFF}, + {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000EFFF}, + {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000EFFF}, + {0x903f0001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000EFFF}, + {0x90400001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000EFFF}, + {0xA0000000, 0x00000000}, + {0x03F, 0x0000E3FF}, + {0xB0000000, 0x00000000}, + {0x033, 0x00000016}, + {0x03F, 0x0000EFFF}, + {0x033, 0x00000017}, + {0x03F, 0x0000EFFF}, + {0x033, 0x00000018}, + {0x03F, 0x0000FBFF}, + {0x033, 0x00000019}, + {0x03F, 0x0000EFFF}, + {0x033, 0x0000001A}, + {0x03F, 0x0000EFFF}, + {0x033, 0x0000001B}, + {0x03F, 0x0000EFFF}, + {0x033, 0x0000001C}, + {0x03F, 0x0000EFFF}, + {0x033, 0x0000001D}, + {0x03F, 0x0000EFFF}, + {0x033, 0x0000001E}, + {0x03F, 0x0000EFFF}, + {0x033, 0x0000001F}, + {0x03F, 0x0000EFFF}, + {0x033, 0x00000020}, + {0x03F, 0x0000EFFF}, + {0x033, 0x00000021}, + {0x03F, 0x0000EFFF}, + {0x033, 0x00000022}, + {0x03F, 0x0000EFFF}, + {0x033, 0x00000023}, + {0x03F, 0x0000EFFF}, + {0x033, 0x00000024}, + {0x03F, 0x0000EFFF}, + {0x033, 0x00000025}, + {0x03F, 0x0000EFFF}, + {0x033, 0x00000026}, + {0x03F, 0x0000EFFF}, + {0x033, 0x00000027}, + {0x03F, 0x0000EFFF}, + {0x033, 0x00000028}, + {0x03F, 0x0000EFFF}, + {0x033, 0x00000029}, + {0x03F, 0x0000EFFF}, + {0x033, 0x0000002A}, + {0x03F, 0x0000EFFF}, + {0x033, 0x0000002B}, + {0x03F, 0x0000EFFF}, + {0x033, 0x0000002C}, + {0x03F, 0x0000EFFF}, + {0x033, 0x0000002D}, + {0x03F, 0x0000EFFF}, + {0x033, 0x0000002E}, + {0x03F, 0x0000EFFF}, + {0x033, 0x0000002F}, + {0x03F, 0x0000EFFF}, + {0x033, 0x00000030}, + {0x03F, 0x0000EFFF}, + {0x033, 0x00000031}, + {0x03F, 0x0000EFFF}, + {0x033, 0x00000032}, + {0x03F, 0x0000EFFF}, + {0x033, 0x00000033}, + {0x03F, 0x0000EFFF}, + {0x033, 0x00000034}, + {0x03F, 0x0000EFFF}, + {0x033, 0x00000035}, + {0x03F, 0x0000EFFF}, + {0x033, 0x00000036}, + {0x03F, 0x0000EFFF}, + {0x033, 0x00000037}, + {0x03F, 0x0000EFFF}, + {0x033, 0x00000038}, + {0x03F, 0x0000EFFF}, + {0x033, 0x00000039}, + {0x03F, 0x0000EFFF}, + {0x033, 0x0000003A}, + {0x03F, 0x0000EFFF}, + {0x0EF, 0x00000000}, + {0x0EF, 0x00000040}, + {0x033, 0x00000000}, + {0x03F, 0x00004344}, + {0x033, 0x00000001}, + {0x03F, 0x00004344}, + {0x033, 0x00000002}, + {0x03F, 0x00004344}, + {0x033, 0x00000003}, + {0x03F, 0x00004344}, + {0x033, 0x00000004}, + {0x03F, 0x00004344}, + {0x033, 0x00000005}, + {0x03F, 0x00004344}, + {0x033, 0x00000006}, + {0x03F, 0x00004324}, + {0x033, 0x00000007}, + {0x03F, 0x00004344}, + {0x033, 0x00000008}, + {0x03F, 0x00004344}, + {0x033, 0x00000009}, + {0x03F, 0x00004344}, + {0x033, 0x0000000A}, + {0x03F, 0x00004344}, + {0x033, 0x0000000B}, + {0x03F, 0x00004344}, + {0x033, 0x00000010}, + {0x03F, 0x00004344}, + {0x033, 0x00000011}, + {0x03F, 0x00004344}, + {0x033, 0x00000012}, + {0x03F, 0x00004344}, + {0x033, 0x00000013}, + {0x03F, 0x00004344}, + {0x033, 0x00000014}, + {0x03F, 0x00004344}, + {0x033, 0x00000015}, + {0x03F, 0x00004344}, + {0x033, 0x00000016}, + {0x03F, 0x00004344}, + {0x033, 0x00000017}, + {0x03F, 0x00004344}, + {0x033, 0x00000018}, + {0x03F, 0x00004344}, + {0x033, 0x00000019}, + {0x03F, 0x00004344}, + {0x033, 0x0000001A}, + {0x03F, 0x00004344}, + {0x033, 0x0000001B}, + {0x03F, 0x00004344}, + {0x033, 0x0000001C}, + {0x03F, 0x00004344}, + {0x033, 0x0000001D}, + {0x03F, 0x00004344}, + {0x033, 0x0000001E}, + {0x03F, 0x00004344}, + {0x033, 0x0000001F}, + {0x03F, 0x00004344}, + {0x0EF, 0x00000000}, + {0x0EF, 0x00000020}, + {0x033, 0x00000010}, + {0x03F, 0x00000200}, + {0x033, 0x00000011}, + {0x03F, 0x00000200}, + {0x033, 0x00000012}, + {0x03F, 0x00000200}, + {0x033, 0x00000013}, + {0x03F, 0x00000200}, + {0x033, 0x00000020}, + {0x03F, 0x00000200}, + {0x033, 0x00000021}, + {0x03F, 0x00000200}, + {0x033, 0x00000022}, + {0x03F, 0x00000200}, + {0x033, 0x00000023}, + {0x03F, 0x00000200}, + {0x0EF, 0x00000000}, + {0x0EF, 0x00000010}, + {0x030, 0x000084DC}, + {0x030, 0x000103C9}, + {0x030, 0x00018399}, + {0x030, 0x00020287}, + {0x030, 0x00028277}, + {0x030, 0x00030165}, + {0x030, 0x00038144}, + {0x030, 0x00040044}, + {0x030, 0x00048022}, + {0x030, 0x00050011}, + {0x030, 0x00058000}, + {0x030, 0x00060000}, + {0x030, 0x00068000}, + {0x030, 0x00070000}, + {0x0EF, 0x00000000}, + {0x0EF, 0x00000080}, + {0x033, 0x00000004}, + {0x03E, 0x00000013}, + {0x03F, 0x00023C58}, + {0x033, 0x00000005}, + {0x03E, 0x00000013}, + {0x03F, 0x00023C58}, + {0x033, 0x00000006}, + {0x03E, 0x00000014}, + {0x03F, 0x00021C58}, + {0x033, 0x00000007}, + {0x03E, 0x00000014}, + {0x03F, 0x00022B58}, + {0x033, 0x00000008}, + {0x03E, 0x00000013}, + {0x03F, 0x00023C58}, + {0x033, 0x00000009}, + {0x03E, 0x00000013}, + {0x03F, 0x00023C58}, + {0x033, 0x0000000A}, + {0x03E, 0x00000014}, + {0x03F, 0x00021C58}, + {0x033, 0x0000000B}, + {0x03E, 0x00000014}, + {0x03F, 0x00022B58}, + {0x033, 0x0000000C}, + {0x03E, 0x00000013}, + {0x03F, 0x00023C58}, + {0x033, 0x0000000D}, + {0x03E, 0x00000013}, + {0x03F, 0x00023C58}, + {0x033, 0x0000000E}, + {0x03E, 0x00000014}, + {0x03F, 0x00021C58}, + {0x033, 0x0000000F}, + {0x03E, 0x00000014}, + {0x03F, 0x00022B58}, + {0x033, 0x00000010}, + {0x03E, 0x00000013}, + {0x03F, 0x00023C58}, + {0x033, 0x00000011}, + {0x03E, 0x0000001B}, + {0x03F, 0x00023C58}, + {0x033, 0x00000012}, + {0x03E, 0x00000014}, + {0x03F, 0x00021C58}, + {0x033, 0x00000013}, + {0x03E, 0x00000014}, + {0x03F, 0x00022B58}, + {0x033, 0x00000014}, + {0x03E, 0x00000013}, + {0x03F, 0x00023C58}, + {0x033, 0x00000015}, + {0x03E, 0x0000001B}, + {0x03F, 0x00025A58}, + {0x033, 0x00000016}, + {0x03E, 0x0000001C}, + {0x03F, 0x00021C58}, + {0x033, 0x00000017}, + {0x03E, 0x00000014}, + {0x03F, 0x00022A58}, + {0x033, 0x00000018}, + {0x03E, 0x00000013}, + {0x03F, 0x00025A58}, + {0x033, 0x00000019}, + {0x03E, 0x0000001B}, + {0x03F, 0x00025A58}, + {0x033, 0x0000001A}, + {0x03E, 0x00000014}, + {0x03F, 0x00022A58}, + {0x033, 0x0000001B}, + {0x03E, 0x00000014}, + {0x03F, 0x00022A58}, + {0x033, 0x0000001C}, + {0x03E, 0x00000014}, + {0x03F, 0x0002CD58}, + {0x033, 0x0000001D}, + {0x03E, 0x0000001B}, + {0x03F, 0x00025A58}, + {0x033, 0x0000001E}, + {0x03E, 0x00000013}, + {0x03F, 0x00021E58}, + {0x033, 0x0000001F}, + {0x03E, 0x00000013}, + {0x03F, 0x00022A58}, + {0x033, 0x00000020}, + {0x03E, 0x00000014}, + {0x03F, 0x0002CD58}, + {0x033, 0x00000021}, + {0x03E, 0x0000001C}, + {0x03F, 0x0002CD58}, + {0x033, 0x00000022}, + {0x03E, 0x00000014}, + {0x03F, 0x00021E58}, + {0x033, 0x00000023}, + {0x03E, 0x00000014}, + {0x03F, 0x00022D58}, + {0x033, 0x00000024}, + {0x03E, 0x00000014}, + {0x03F, 0x0002CD58}, + {0x033, 0x00000025}, + {0x03E, 0x00000014}, + {0x03F, 0x0002CD58}, + {0x033, 0x00000026}, + {0x03E, 0x00000014}, + {0x03F, 0x00021E58}, + {0x033, 0x00000027}, + {0x03E, 0x00000014}, + {0x03F, 0x00022D58}, + {0x033, 0x00000028}, + {0x03E, 0x00000014}, + {0x03F, 0x0002CD58}, + {0x033, 0x00000029}, + {0x03E, 0x00000014}, + {0x03F, 0x0002CD58}, + {0x033, 0x0000002A}, + {0x03E, 0x00000014}, + {0x03F, 0x00021E58}, + {0x033, 0x0000002B}, + {0x03E, 0x00000014}, + {0x03F, 0x00022D58}, + {0x033, 0x0000002C}, + {0x03E, 0x00000014}, + {0x03F, 0x0002CD58}, + {0x033, 0x0000002D}, + {0x03E, 0x00000014}, + {0x03F, 0x0002CD58}, + {0x033, 0x0000002E}, + {0x03E, 0x00000014}, + {0x03F, 0x00021E58}, + {0x033, 0x0000002F}, + {0x03E, 0x00000014}, + {0x03F, 0x00022D58}, + {0x033, 0x00000030}, + {0x03E, 0x00000014}, + {0x03F, 0x0002CD58}, + {0x033, 0x00000031}, + {0x03E, 0x00000014}, + {0x03F, 0x0002CD58}, + {0x033, 0x00000032}, + {0x03E, 0x00000014}, + {0x03F, 0x00021E58}, + {0x033, 0x00000033}, + {0x03E, 0x00000014}, + {0x03F, 0x00022D58}, + {0x033, 0x00000034}, + {0x03E, 0x00000014}, + {0x03F, 0x0002CD58}, + {0x033, 0x00000035}, + {0x03E, 0x00000014}, + {0x03F, 0x0002CD58}, + {0x033, 0x00000036}, + {0x03E, 0x00000014}, + {0x03F, 0x00021E58}, + {0x033, 0x00000037}, + {0x03E, 0x00000014}, + {0x03F, 0x00022D58}, + {0x033, 0x00000038}, + {0x03E, 0x00000014}, + {0x03F, 0x0002CD58}, + {0x033, 0x00000039}, + {0x03E, 0x00000014}, + {0x03F, 0x0002CD58}, + {0x033, 0x0000003A}, + {0x03E, 0x00000014}, + {0x03F, 0x00021E58}, + {0x033, 0x0000003B}, + {0x03E, 0x00000014}, + {0x03F, 0x00022D58}, + {0x033, 0x0000003C}, + {0x03E, 0x00000014}, + {0x03F, 0x0002CD58}, + {0x033, 0x0000003D}, + {0x03E, 0x00000014}, + {0x03F, 0x0002CD58}, + {0x033, 0x0000003E}, + {0x03E, 0x00000014}, + {0x03F, 0x00021E58}, + {0x033, 0x0000003F}, + {0x03E, 0x00000014}, + {0x03F, 0x00022D58}, + {0x0EF, 0x00000000}, + {0x0EE, 0x00000800}, + {0x033, 0x00000000}, + {0x03F, 0x00000031}, + {0x033, 0x00000001}, + {0x03F, 0x00000023}, + {0x033, 0x00000002}, + {0x03F, 0x00000015}, + {0x033, 0x00000003}, + {0x03F, 0x00000007}, + {0x0EE, 0x00000000}, + {0x0EC, 0x00000400}, + {0x033, 0x00000003}, + {0x03F, 0x00000030}, + {0x033, 0x00000004}, + {0x03F, 0x00000021}, + {0x0EC, 0x00000000}, + {0x0DE, 0x00000000}, + {0x0EF, 0x00000000}, + {0x033, 0x00000000}, + {0x008, 0x00060280}, + {0x009, 0x00030400}, + {0x0EF, 0x00000000}, + {0x0A7, 0x00080308}, + {0x066, 0x00006000}, + {0x0EF, 0x00000400}, + {0x030, 0x000001FF}, + {0x030, 0x000081FF}, + {0x030, 0x000101FF}, + {0x030, 0x000181FF}, + {0x030, 0x000201FF}, + {0x030, 0x000281FF}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x030, 0x0003017F}, + {0x90020000, 0x00000000}, {0x40000000, 0x00000000}, + {0x030, 0x0003017F}, + {0x90320000, 0x00000000}, {0x40000000, 0x00000000}, + {0x030, 0x0003017F}, + {0x90330000, 0x00000000}, {0x40000000, 0x00000000}, + {0x030, 0x0003017F}, + {0x90340000, 0x00000000}, {0x40000000, 0x00000000}, + {0x030, 0x0003017F}, + {0x90350000, 0x00000000}, {0x40000000, 0x00000000}, + {0x030, 0x0003017F}, + {0x90360000, 0x00000000}, {0x40000000, 0x00000000}, + {0x030, 0x0003017F}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x030, 0x000300FF}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x030, 0x000300FF}, + {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, + {0x030, 0x000300FF}, + {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, + {0x030, 0x000300FF}, + {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, + {0x030, 0x000300FF}, + {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, + {0x030, 0x000300FF}, + {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, + {0x030, 0x000300FF}, + {0x903f0001, 0x00000000}, {0x40000000, 0x00000000}, + {0x030, 0x000300FF}, + {0x90400001, 0x00000000}, {0x40000000, 0x00000000}, + {0x030, 0x000300FF}, + {0xA0000000, 0x00000000}, + {0x030, 0x0003017F}, + {0xB0000000, 0x00000000}, + {0x030, 0x000380FB}, + {0x0EF, 0x00000000}, + {0x06E, 0x00077A18}, + {0x06D, 0x00000C31}, + {0x06A, 0x000E0F8A}, + {0x06B, 0x000018A0}, + {0x06F, 0x000F81FC}, + {0x05E, 0x0000001F}, + {0x0EF, 0x00000200}, + {0x030, 0x0003D407}, + {0x030, 0x00035A87}, + {0x030, 0x0002CF07}, + {0x030, 0x00024F07}, + {0x030, 0x0001CF07}, + {0x030, 0x00014F07}, + {0x030, 0x0000CF07}, + {0x030, 0x00004F07}, + {0x0EF, 0x00000000}, + {0x0EB, 0x00080000}, + {0x030, 0x00008038}, + {0x030, 0x00010038}, + {0x030, 0x00018038}, + {0x030, 0x00020038}, + {0x030, 0x00028038}, + {0x030, 0x00030038}, + {0x030, 0x0003803C}, + {0x030, 0x0004003C}, + {0x030, 0x0004803C}, + {0x030, 0x0005003C}, + {0x030, 0x0005803C}, + {0x030, 0x0006003C}, + {0x030, 0x0006803C}, + {0x030, 0x0007003C}, + {0x0EB, 0x00000000}, + {0x094, 0x000000FC}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x095, 0x00000000}, + {0x90020000, 0x00000000}, {0x40000000, 0x00000000}, + {0x095, 0x00000000}, + {0x90320000, 0x00000000}, {0x40000000, 0x00000000}, + {0x095, 0x00000000}, + {0x90330000, 0x00000000}, {0x40000000, 0x00000000}, + {0x095, 0x00000000}, + {0x90340000, 0x00000000}, {0x40000000, 0x00000000}, + {0x095, 0x00000000}, + {0x90350000, 0x00000000}, {0x40000000, 0x00000000}, + {0x095, 0x00000000}, + {0x90360000, 0x00000000}, {0x40000000, 0x00000000}, + {0x095, 0x00000000}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x095, 0x00000008}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x095, 0x00000008}, + {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, + {0x095, 0x00000008}, + {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, + {0x095, 0x00000008}, + {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, + {0x095, 0x00000008}, + {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, + {0x095, 0x00000008}, + {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, + {0x095, 0x00000008}, + {0x903f0001, 0x00000000}, {0x40000000, 0x00000000}, + {0x095, 0x00000008}, + {0x90400001, 0x00000000}, {0x40000000, 0x00000000}, + {0x095, 0x00000008}, + {0xA0000000, 0x00000000}, + {0x095, 0x00000000}, + {0xB0000000, 0x00000000}, + {0x0EE, 0x00001000}, + {0x033, 0x00000020}, + {0x03F, 0x00000052}, + {0x033, 0x00000024}, + {0x03F, 0x0000005A}, + {0x033, 0x00000028}, + {0x03F, 0x0000009C}, + {0x033, 0x0000002C}, + {0x03F, 0x0000019C}, + {0x033, 0x00000030}, + {0x03F, 0x000001A4}, + {0x033, 0x00000034}, + {0x03F, 0x000001E7}, + {0x033, 0x00000038}, + {0x03F, 0x000002E7}, + {0x033, 0x0000003C}, + {0x03F, 0x000003E7}, + {0x033, 0x00000021}, + {0x03F, 0x00000052}, + {0x033, 0x00000025}, + {0x03F, 0x0000005A}, + {0x033, 0x00000029}, + {0x03F, 0x0000009C}, + {0x033, 0x0000002D}, + {0x03F, 0x0000019C}, + {0x033, 0x00000031}, + {0x03F, 0x000001A4}, + {0x033, 0x00000035}, + {0x03F, 0x000001E6}, + {0x033, 0x00000039}, + {0x03F, 0x000002E6}, + {0x033, 0x0000003D}, + {0x03F, 0x000003E6}, + {0x033, 0x00000022}, + {0x03F, 0x00000052}, + {0x033, 0x00000026}, + {0x03F, 0x0000005A}, + {0x033, 0x0000002A}, + {0x03F, 0x0000009C}, + {0x033, 0x0000002E}, + {0x03F, 0x0000019C}, + {0x033, 0x00000032}, + {0x03F, 0x000001A4}, + {0x033, 0x00000036}, + {0x03F, 0x000001E6}, + {0x033, 0x0000003A}, + {0x03F, 0x000002E6}, + {0x033, 0x0000003E}, + {0x03F, 0x000003E6}, + {0x033, 0x00000060}, + {0x03F, 0x00000052}, + {0x033, 0x00000064}, + {0x03F, 0x0000005A}, + {0x033, 0x00000068}, + {0x03F, 0x0000009C}, + {0x033, 0x0000006C}, + {0x03F, 0x0000019C}, + {0x033, 0x00000070}, + {0x03F, 0x000001A4}, + {0x033, 0x00000074}, + {0x03F, 0x000001E6}, + {0x033, 0x00000078}, + {0x03F, 0x000002E6}, + {0x033, 0x0000007C}, + {0x03F, 0x000003E6}, + {0x033, 0x00000061}, + {0x03F, 0x00000052}, + {0x033, 0x00000065}, + {0x03F, 0x0000005A}, + {0x033, 0x00000069}, + {0x03F, 0x0000009C}, + {0x033, 0x0000006D}, + {0x03F, 0x0000019C}, + {0x033, 0x00000071}, + {0x03F, 0x000001A4}, + {0x033, 0x00000075}, + {0x03F, 0x000001E6}, + {0x033, 0x00000079}, + {0x03F, 0x000002E6}, + {0x033, 0x0000007D}, + {0x03F, 0x000003E6}, + {0x033, 0x00000062}, + {0x03F, 0x00000052}, + {0x033, 0x00000066}, + {0x03F, 0x0000005A}, + {0x033, 0x0000006A}, + {0x03F, 0x0000009C}, + {0x033, 0x0000006E}, + {0x03F, 0x0000019C}, + {0x033, 0x00000072}, + {0x03F, 0x000001A4}, + {0x033, 0x00000076}, + {0x03F, 0x000001E6}, + {0x033, 0x0000007A}, + {0x03F, 0x000002E6}, + {0x033, 0x0000007E}, + {0x03F, 0x000003E6}, + {0x033, 0x00000063}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000052}, + {0x90020000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000052}, + {0x90320000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000052}, + {0x90330000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000052}, + {0x90340000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000052}, + {0x90350000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000052}, + {0x90360000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000052}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000152}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000152}, + {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000152}, + {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000152}, + {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000152}, + {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000152}, + {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000152}, + {0x903f0001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000152}, + {0x90400001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000152}, + {0xA0000000, 0x00000000}, + {0x03F, 0x00000052}, + {0xB0000000, 0x00000000}, + {0x033, 0x00000067}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000005A}, + {0x90020000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000005A}, + {0x90320000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000005A}, + {0x90330000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000005A}, + {0x90340000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000005A}, + {0x90350000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000005A}, + {0x90360000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000005A}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000015A}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000015A}, + {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000015A}, + {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000015A}, + {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000015A}, + {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000015A}, + {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000015A}, + {0x903f0001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000015A}, + {0x90400001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000015A}, + {0xA0000000, 0x00000000}, + {0x03F, 0x0000005A}, + {0xB0000000, 0x00000000}, + {0x033, 0x0000006B}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000009C}, + {0x90020000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000009C}, + {0x90320000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000009C}, + {0x90330000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000009C}, + {0x90340000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000009C}, + {0x90350000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000009C}, + {0x90360000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000009C}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000019C}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000019C}, + {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000019C}, + {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000019C}, + {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000019C}, + {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000019C}, + {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000019C}, + {0x903f0001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000019C}, + {0x90400001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000019C}, + {0xA0000000, 0x00000000}, + {0x03F, 0x0000009C}, + {0xB0000000, 0x00000000}, + {0x033, 0x0000006F}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000019C}, + {0x90020000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000019C}, + {0x90320000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000019C}, + {0x90330000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000019C}, + {0x90340000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000019C}, + {0x90350000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000019C}, + {0x90360000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000019C}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001A4}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001A4}, + {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001A4}, + {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001A4}, + {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001A4}, + {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001A4}, + {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001A4}, + {0x903f0001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001A4}, + {0x90400001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001A4}, + {0xA0000000, 0x00000000}, + {0x03F, 0x0000019C}, + {0xB0000000, 0x00000000}, + {0x033, 0x00000073}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001A4}, + {0x90020000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001A4}, + {0x90320000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001A4}, + {0x90330000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001A4}, + {0x90340000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001A4}, + {0x90350000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001A4}, + {0x90360000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001A4}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001E6}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001E6}, + {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001E6}, + {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001E6}, + {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001E6}, + {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001E6}, + {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001E6}, + {0x903f0001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001E6}, + {0x90400001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001E6}, + {0xA0000000, 0x00000000}, + {0x03F, 0x000001A4}, + {0xB0000000, 0x00000000}, + {0x033, 0x00000077}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001E6}, + {0x90020000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001E6}, + {0x90320000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001E6}, + {0x90330000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001E6}, + {0x90340000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001E6}, + {0x90350000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001E6}, + {0x90360000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001E6}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000002E6}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000002E6}, + {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000002E6}, + {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000002E6}, + {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000002E6}, + {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000002E6}, + {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000002E6}, + {0x903f0001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000002E6}, + {0x90400001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000002E6}, + {0xA0000000, 0x00000000}, + {0x03F, 0x000001E6}, + {0xB0000000, 0x00000000}, + {0x033, 0x0000007B}, + {0x03F, 0x000002E7}, + {0x033, 0x0000007F}, + {0x03F, 0x000003E7}, + {0x0EE, 0x00000000}, + {0x100EE, 0x00004000}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x10030, 0x000001EF}, + {0x10030, 0x000005E9}, + {0x10030, 0x000009E3}, + {0x10030, 0x00000DDD}, + {0x10030, 0x000011D7}, + {0x10030, 0x0000159F}, + {0x10030, 0x00001999}, + {0x10030, 0x00001D5F}, + {0x10030, 0x00002159}, + {0x10030, 0x0000251F}, + {0x10030, 0x00002919}, + {0x10030, 0x00002CDF}, + {0x10030, 0x000030D9}, + {0x10030, 0x0000349F}, + {0x10030, 0x00003899}, + {0x10030, 0x00003C5F}, + {0x10030, 0x00004059}, + {0x10030, 0x00004453}, + {0x10030, 0x000201ED}, + {0x10030, 0x000205AD}, + {0x10030, 0x000209A7}, + {0x10030, 0x00020DA1}, + {0x10030, 0x0002119B}, + {0x10030, 0x00021561}, + {0x10030, 0x0002195B}, + {0x10030, 0x00021D27}, + {0x10030, 0x00022121}, + {0x10030, 0x000224E9}, + {0x10030, 0x000228E3}, + {0x10030, 0x00022CA9}, + {0x10030, 0x000230A3}, + {0x10030, 0x00023469}, + {0x10030, 0x00023863}, + {0x10030, 0x00023C29}, + {0x10030, 0x00024023}, + {0x10030, 0x0002441D}, + {0x10030, 0x000281EF}, + {0x10030, 0x000285AF}, + {0x10030, 0x000289A9}, + {0x10030, 0x00028DA3}, + {0x10030, 0x0002919D}, + {0x10030, 0x00029563}, + {0x10030, 0x0002995D}, + {0x10030, 0x00029D25}, + {0x10030, 0x0002A11F}, + {0x10030, 0x0002A4E7}, + {0x10030, 0x0002A8E1}, + {0x10030, 0x0002ACA7}, + {0x10030, 0x0002B0A1}, + {0x10030, 0x0002B467}, + {0x10030, 0x0002B861}, + {0x10030, 0x0002BC27}, + {0x10030, 0x0002C021}, + {0x10030, 0x0002C41B}, + {0x10030, 0x000301EF}, + {0x10030, 0x000305AF}, + {0x10030, 0x000309A9}, + {0x10030, 0x00030DA3}, + {0x10030, 0x0003119D}, + {0x10030, 0x00031563}, + {0x10030, 0x0003195D}, + {0x10030, 0x00031D25}, + {0x10030, 0x0003211F}, + {0x10030, 0x000324E7}, + {0x10030, 0x000328E1}, + {0x10030, 0x00032CA7}, + {0x10030, 0x000330A1}, + {0x10030, 0x00033467}, + {0x10030, 0x00033861}, + {0x10030, 0x00033C27}, + {0x10030, 0x00034021}, + {0x10030, 0x0003441B}, + {0x10030, 0x000601EB}, + {0x10030, 0x000605AB}, + {0x10030, 0x000609A5}, + {0x10030, 0x00060D9F}, + {0x10030, 0x00061199}, + {0x10030, 0x00061593}, + {0x10030, 0x00061959}, + {0x10030, 0x00061D53}, + {0x10030, 0x0006211B}, + {0x10030, 0x00062515}, + {0x10030, 0x000628DD}, + {0x10030, 0x00062CD7}, + {0x10030, 0x0006309D}, + {0x10030, 0x00063497}, + {0x10030, 0x0006385D}, + {0x10030, 0x00063C57}, + {0x10030, 0x0006401D}, + {0x10030, 0x00064417}, + {0x10030, 0x000681E7}, + {0x10030, 0x000685A7}, + {0x10030, 0x000689A1}, + {0x10030, 0x00068D9B}, + {0x10030, 0x00069195}, + {0x10030, 0x0006955F}, + {0x10030, 0x00069959}, + {0x10030, 0x00069D21}, + {0x10030, 0x0006A11B}, + {0x10030, 0x0006A4E3}, + {0x10030, 0x0006A8DD}, + {0x10030, 0x0006ACA5}, + {0x10030, 0x0006B09F}, + {0x10030, 0x0006B465}, + {0x10030, 0x0006B85F}, + {0x10030, 0x0006BC25}, + {0x10030, 0x0006C01F}, + {0x10030, 0x0006C419}, + {0x10030, 0x000701E7}, + {0x10030, 0x000705A7}, + {0x10030, 0x000709A1}, + {0x10030, 0x00070D9B}, + {0x10030, 0x00071195}, + {0x10030, 0x0007155B}, + {0x10030, 0x00071955}, + {0x10030, 0x00071D1D}, + {0x10030, 0x00072117}, + {0x10030, 0x000724DF}, + {0x10030, 0x000728D9}, + {0x10030, 0x00072CA1}, + {0x10030, 0x0007309B}, + {0x10030, 0x00073461}, + {0x10030, 0x0007385B}, + {0x10030, 0x00073C21}, + {0x10030, 0x0007401B}, + {0x10030, 0x0007441B}, + {0x10030, 0x000781E9}, + {0x10030, 0x000785A9}, + {0x10030, 0x000789A3}, + {0x10030, 0x00078D9D}, + {0x10030, 0x00079197}, + {0x10030, 0x00079591}, + {0x10030, 0x00079957}, + {0x10030, 0x00079D51}, + {0x10030, 0x0007A119}, + {0x10030, 0x0007A513}, + {0x10030, 0x0007A8D9}, + {0x10030, 0x0007ACD3}, + {0x10030, 0x0007B099}, + {0x10030, 0x0007B493}, + {0x10030, 0x0007B859}, + {0x10030, 0x0007BC53}, + {0x10030, 0x0007C019}, + {0x10030, 0x0007C413}, + {0x90020000, 0x00000000}, {0x40000000, 0x00000000}, + {0x10030, 0x000001EF}, + {0x10030, 0x000005E9}, + {0x10030, 0x000009E3}, + {0x10030, 0x00000DDD}, + {0x10030, 0x000011D7}, + {0x10030, 0x0000159F}, + {0x10030, 0x00001999}, + {0x10030, 0x00001D5F}, + {0x10030, 0x00002159}, + {0x10030, 0x0000251F}, + {0x10030, 0x00002919}, + {0x10030, 0x00002CDF}, + {0x10030, 0x000030D9}, + {0x10030, 0x0000349F}, + {0x10030, 0x00003899}, + {0x10030, 0x00003C5F}, + {0x10030, 0x00004059}, + {0x10030, 0x00004453}, + {0x10030, 0x000201ED}, + {0x10030, 0x000205AD}, + {0x10030, 0x000209A7}, + {0x10030, 0x00020DA1}, + {0x10030, 0x0002119B}, + {0x10030, 0x00021561}, + {0x10030, 0x0002195B}, + {0x10030, 0x00021D27}, + {0x10030, 0x00022121}, + {0x10030, 0x000224E9}, + {0x10030, 0x000228E3}, + {0x10030, 0x00022CA9}, + {0x10030, 0x000230A3}, + {0x10030, 0x00023469}, + {0x10030, 0x00023863}, + {0x10030, 0x00023C29}, + {0x10030, 0x00024023}, + {0x10030, 0x0002441D}, + {0x10030, 0x000281EF}, + {0x10030, 0x000285AF}, + {0x10030, 0x000289A9}, + {0x10030, 0x00028DA3}, + {0x10030, 0x0002919D}, + {0x10030, 0x00029563}, + {0x10030, 0x0002995D}, + {0x10030, 0x00029D25}, + {0x10030, 0x0002A11F}, + {0x10030, 0x0002A4E7}, + {0x10030, 0x0002A8E1}, + {0x10030, 0x0002ACA7}, + {0x10030, 0x0002B0A1}, + {0x10030, 0x0002B467}, + {0x10030, 0x0002B861}, + {0x10030, 0x0002BC27}, + {0x10030, 0x0002C021}, + {0x10030, 0x0002C41B}, + {0x10030, 0x000301EF}, + {0x10030, 0x000305AF}, + {0x10030, 0x000309A9}, + {0x10030, 0x00030DA3}, + {0x10030, 0x0003119D}, + {0x10030, 0x00031563}, + {0x10030, 0x0003195D}, + {0x10030, 0x00031D25}, + {0x10030, 0x0003211F}, + {0x10030, 0x000324E7}, + {0x10030, 0x000328E1}, + {0x10030, 0x00032CA7}, + {0x10030, 0x000330A1}, + {0x10030, 0x00033467}, + {0x10030, 0x00033861}, + {0x10030, 0x00033C27}, + {0x10030, 0x00034021}, + {0x10030, 0x0003441B}, + {0x10030, 0x000601EB}, + {0x10030, 0x000605AB}, + {0x10030, 0x000609A5}, + {0x10030, 0x00060D9F}, + {0x10030, 0x00061199}, + {0x10030, 0x00061593}, + {0x10030, 0x00061959}, + {0x10030, 0x00061D53}, + {0x10030, 0x0006211B}, + {0x10030, 0x00062515}, + {0x10030, 0x000628DD}, + {0x10030, 0x00062CD7}, + {0x10030, 0x0006309D}, + {0x10030, 0x00063497}, + {0x10030, 0x0006385D}, + {0x10030, 0x00063C57}, + {0x10030, 0x0006401D}, + {0x10030, 0x00064417}, + {0x10030, 0x000681E7}, + {0x10030, 0x000685A7}, + {0x10030, 0x000689A1}, + {0x10030, 0x00068D9B}, + {0x10030, 0x00069195}, + {0x10030, 0x0006955F}, + {0x10030, 0x00069959}, + {0x10030, 0x00069D21}, + {0x10030, 0x0006A11B}, + {0x10030, 0x0006A4E3}, + {0x10030, 0x0006A8DD}, + {0x10030, 0x0006ACA5}, + {0x10030, 0x0006B09F}, + {0x10030, 0x0006B465}, + {0x10030, 0x0006B85F}, + {0x10030, 0x0006BC25}, + {0x10030, 0x0006C01F}, + {0x10030, 0x0006C419}, + {0x10030, 0x000701E7}, + {0x10030, 0x000705A7}, + {0x10030, 0x000709A1}, + {0x10030, 0x00070D9B}, + {0x10030, 0x00071195}, + {0x10030, 0x0007155B}, + {0x10030, 0x00071955}, + {0x10030, 0x00071D1D}, + {0x10030, 0x00072117}, + {0x10030, 0x000724DF}, + {0x10030, 0x000728D9}, + {0x10030, 0x00072CA1}, + {0x10030, 0x0007309B}, + {0x10030, 0x00073461}, + {0x10030, 0x0007385B}, + {0x10030, 0x00073C21}, + {0x10030, 0x0007401B}, + {0x10030, 0x0007441B}, + {0x10030, 0x000781E9}, + {0x10030, 0x000785A9}, + {0x10030, 0x000789A3}, + {0x10030, 0x00078D9D}, + {0x10030, 0x00079197}, + {0x10030, 0x00079591}, + {0x10030, 0x00079957}, + {0x10030, 0x00079D51}, + {0x10030, 0x0007A119}, + {0x10030, 0x0007A513}, + {0x10030, 0x0007A8D9}, + {0x10030, 0x0007ACD3}, + {0x10030, 0x0007B099}, + {0x10030, 0x0007B493}, + {0x10030, 0x0007B859}, + {0x10030, 0x0007BC53}, + {0x10030, 0x0007C019}, + {0x10030, 0x0007C413}, + {0x90320000, 0x00000000}, {0x40000000, 0x00000000}, + {0x10030, 0x000001EF}, + {0x10030, 0x000005E9}, + {0x10030, 0x000009E3}, + {0x10030, 0x00000DDD}, + {0x10030, 0x000011D7}, + {0x10030, 0x0000159F}, + {0x10030, 0x00001999}, + {0x10030, 0x00001D5F}, + {0x10030, 0x00002159}, + {0x10030, 0x0000251F}, + {0x10030, 0x00002919}, + {0x10030, 0x00002CDF}, + {0x10030, 0x000030D9}, + {0x10030, 0x0000349F}, + {0x10030, 0x00003899}, + {0x10030, 0x00003C5F}, + {0x10030, 0x00004059}, + {0x10030, 0x00004453}, + {0x10030, 0x000201ED}, + {0x10030, 0x000205AD}, + {0x10030, 0x000209A7}, + {0x10030, 0x00020DA1}, + {0x10030, 0x0002119B}, + {0x10030, 0x00021561}, + {0x10030, 0x0002195B}, + {0x10030, 0x00021D27}, + {0x10030, 0x00022121}, + {0x10030, 0x000224E9}, + {0x10030, 0x000228E3}, + {0x10030, 0x00022CA9}, + {0x10030, 0x000230A3}, + {0x10030, 0x00023469}, + {0x10030, 0x00023863}, + {0x10030, 0x00023C29}, + {0x10030, 0x00024023}, + {0x10030, 0x0002441D}, + {0x10030, 0x000281EF}, + {0x10030, 0x000285AF}, + {0x10030, 0x000289A9}, + {0x10030, 0x00028DA3}, + {0x10030, 0x0002919D}, + {0x10030, 0x00029563}, + {0x10030, 0x0002995D}, + {0x10030, 0x00029D25}, + {0x10030, 0x0002A11F}, + {0x10030, 0x0002A4E7}, + {0x10030, 0x0002A8E1}, + {0x10030, 0x0002ACA7}, + {0x10030, 0x0002B0A1}, + {0x10030, 0x0002B467}, + {0x10030, 0x0002B861}, + {0x10030, 0x0002BC27}, + {0x10030, 0x0002C021}, + {0x10030, 0x0002C41B}, + {0x10030, 0x000301EF}, + {0x10030, 0x000305AF}, + {0x10030, 0x000309A9}, + {0x10030, 0x00030DA3}, + {0x10030, 0x0003119D}, + {0x10030, 0x00031563}, + {0x10030, 0x0003195D}, + {0x10030, 0x00031D25}, + {0x10030, 0x0003211F}, + {0x10030, 0x000324E7}, + {0x10030, 0x000328E1}, + {0x10030, 0x00032CA7}, + {0x10030, 0x000330A1}, + {0x10030, 0x00033467}, + {0x10030, 0x00033861}, + {0x10030, 0x00033C27}, + {0x10030, 0x00034021}, + {0x10030, 0x0003441B}, + {0x10030, 0x000601EB}, + {0x10030, 0x000605AB}, + {0x10030, 0x000609A5}, + {0x10030, 0x00060D9F}, + {0x10030, 0x00061199}, + {0x10030, 0x00061593}, + {0x10030, 0x00061959}, + {0x10030, 0x00061D53}, + {0x10030, 0x0006211B}, + {0x10030, 0x00062515}, + {0x10030, 0x000628DD}, + {0x10030, 0x00062CD7}, + {0x10030, 0x0006309D}, + {0x10030, 0x00063497}, + {0x10030, 0x0006385D}, + {0x10030, 0x00063C57}, + {0x10030, 0x0006401D}, + {0x10030, 0x00064417}, + {0x10030, 0x000681E7}, + {0x10030, 0x000685A7}, + {0x10030, 0x000689A1}, + {0x10030, 0x00068D9B}, + {0x10030, 0x00069195}, + {0x10030, 0x0006955F}, + {0x10030, 0x00069959}, + {0x10030, 0x00069D21}, + {0x10030, 0x0006A11B}, + {0x10030, 0x0006A4E3}, + {0x10030, 0x0006A8DD}, + {0x10030, 0x0006ACA5}, + {0x10030, 0x0006B09F}, + {0x10030, 0x0006B465}, + {0x10030, 0x0006B85F}, + {0x10030, 0x0006BC25}, + {0x10030, 0x0006C01F}, + {0x10030, 0x0006C419}, + {0x10030, 0x000701E7}, + {0x10030, 0x000705A7}, + {0x10030, 0x000709A1}, + {0x10030, 0x00070D9B}, + {0x10030, 0x00071195}, + {0x10030, 0x0007155B}, + {0x10030, 0x00071955}, + {0x10030, 0x00071D1D}, + {0x10030, 0x00072117}, + {0x10030, 0x000724DF}, + {0x10030, 0x000728D9}, + {0x10030, 0x00072CA1}, + {0x10030, 0x0007309B}, + {0x10030, 0x00073461}, + {0x10030, 0x0007385B}, + {0x10030, 0x00073C21}, + {0x10030, 0x0007401B}, + {0x10030, 0x0007441B}, + {0x10030, 0x000781E9}, + {0x10030, 0x000785A9}, + {0x10030, 0x000789A3}, + {0x10030, 0x00078D9D}, + {0x10030, 0x00079197}, + {0x10030, 0x00079591}, + {0x10030, 0x00079957}, + {0x10030, 0x00079D51}, + {0x10030, 0x0007A119}, + {0x10030, 0x0007A513}, + {0x10030, 0x0007A8D9}, + {0x10030, 0x0007ACD3}, + {0x10030, 0x0007B099}, + {0x10030, 0x0007B493}, + {0x10030, 0x0007B859}, + {0x10030, 0x0007BC53}, + {0x10030, 0x0007C019}, + {0x10030, 0x0007C413}, + {0x90330000, 0x00000000}, {0x40000000, 0x00000000}, + {0x10030, 0x000201DF}, + {0x10030, 0x000205D9}, + {0x10030, 0x000209D3}, + {0x10030, 0x00020D99}, + {0x10030, 0x00021193}, + {0x10030, 0x0002155F}, + {0x10030, 0x00021959}, + {0x10030, 0x00021D21}, + {0x10030, 0x00022119}, + {0x10030, 0x000224DF}, + {0x10030, 0x000228D9}, + {0x10030, 0x00022C9F}, + {0x10030, 0x00023099}, + {0x10030, 0x0002345F}, + {0x10030, 0x00023859}, + {0x10030, 0x00023C1F}, + {0x10030, 0x00024019}, + {0x10030, 0x00024413}, + {0x10030, 0x000281CD}, + {0x10030, 0x000285DB}, + {0x10030, 0x000289D5}, + {0x10030, 0x00028D9B}, + {0x10030, 0x0002918D}, + {0x10030, 0x00029555}, + {0x10030, 0x00029957}, + {0x10030, 0x00029D1F}, + {0x10030, 0x0002A119}, + {0x10030, 0x0002A4DF}, + {0x10030, 0x0002A8D9}, + {0x10030, 0x0002AC9F}, + {0x10030, 0x0002B099}, + {0x10030, 0x0002B45F}, + {0x10030, 0x0002B859}, + {0x10030, 0x0002BC1F}, + {0x10030, 0x0002C019}, + {0x10030, 0x0002C413}, + {0x10030, 0x000301D9}, + {0x10030, 0x000305DB}, + {0x10030, 0x000309D5}, + {0x10030, 0x00030D9B}, + {0x10030, 0x00031195}, + {0x10030, 0x0003155D}, + {0x10030, 0x00031955}, + {0x10030, 0x00031D1D}, + {0x10030, 0x00032119}, + {0x10030, 0x000324DF}, + {0x10030, 0x000328D9}, + {0x10030, 0x00032C9F}, + {0x10030, 0x00033099}, + {0x10030, 0x0003345F}, + {0x10030, 0x00033859}, + {0x10030, 0x00033C1F}, + {0x10030, 0x00034019}, + {0x10030, 0x00034413}, + {0x10030, 0x000601E1}, + {0x10030, 0x000605DB}, + {0x10030, 0x000609D5}, + {0x10030, 0x00060D9B}, + {0x10030, 0x00061195}, + {0x10030, 0x0006155B}, + {0x10030, 0x00061957}, + {0x10030, 0x00061D1F}, + {0x10030, 0x00062119}, + {0x10030, 0x000624DF}, + {0x10030, 0x000628D9}, + {0x10030, 0x00062C9F}, + {0x10030, 0x00063099}, + {0x10030, 0x0006345F}, + {0x10030, 0x00063859}, + {0x10030, 0x00063C1F}, + {0x10030, 0x00064019}, + {0x10030, 0x00064413}, + {0x10030, 0x000681E1}, + {0x10030, 0x000685DB}, + {0x10030, 0x000689D5}, + {0x10030, 0x00068D9B}, + {0x10030, 0x00069195}, + {0x10030, 0x0006955B}, + {0x10030, 0x00069957}, + {0x10030, 0x00069D1F}, + {0x10030, 0x0006A119}, + {0x10030, 0x0006A4DF}, + {0x10030, 0x0006A8D9}, + {0x10030, 0x0006AC9F}, + {0x10030, 0x0006B099}, + {0x10030, 0x0006B45F}, + {0x10030, 0x0006B859}, + {0x10030, 0x0006BC1F}, + {0x10030, 0x0006C019}, + {0x10030, 0x0006C413}, + {0x10030, 0x000701E1}, + {0x10030, 0x000705DB}, + {0x10030, 0x000709D5}, + {0x10030, 0x00070D9B}, + {0x10030, 0x00071195}, + {0x10030, 0x0007155B}, + {0x10030, 0x00071957}, + {0x10030, 0x00071D1F}, + {0x10030, 0x00072119}, + {0x10030, 0x000724DF}, + {0x10030, 0x000728D9}, + {0x10030, 0x00072C9F}, + {0x10030, 0x00073099}, + {0x10030, 0x0007345F}, + {0x10030, 0x00073859}, + {0x10030, 0x00073C1F}, + {0x10030, 0x00074019}, + {0x10030, 0x00074413}, + {0x10030, 0x000781DF}, + {0x10030, 0x000785D9}, + {0x10030, 0x000789D3}, + {0x10030, 0x00078D99}, + {0x10030, 0x00079193}, + {0x10030, 0x0007955F}, + {0x10030, 0x00079959}, + {0x10030, 0x00079D21}, + {0x10030, 0x0007A115}, + {0x10030, 0x0007A4DF}, + {0x10030, 0x0007A8D9}, + {0x10030, 0x0007AC9F}, + {0x10030, 0x0007B099}, + {0x10030, 0x0007B45F}, + {0x10030, 0x0007B859}, + {0x10030, 0x0007BC1F}, + {0x10030, 0x0007C019}, + {0x10030, 0x0007C413}, + {0x10030, 0x00000000}, + {0x10030, 0x000785A9}, + {0x10030, 0x000789A3}, + {0x10030, 0x00078D9D}, + {0x10030, 0x00079197}, + {0x10030, 0x00079591}, + {0x10030, 0x00079957}, + {0x10030, 0x00079D51}, + {0x10030, 0x0007A119}, + {0x10030, 0x0007A513}, + {0x10030, 0x0007A8D9}, + {0x10030, 0x0007ACD3}, + {0x10030, 0x0007B099}, + {0x10030, 0x0007B493}, + {0x10030, 0x0007B859}, + {0x10030, 0x0007BC53}, + {0x10030, 0x0007C019}, + {0x10030, 0x0007C413}, + {0x90340000, 0x00000000}, {0x40000000, 0x00000000}, + {0x10030, 0x000201DF}, + {0x10030, 0x000205D9}, + {0x10030, 0x000209D3}, + {0x10030, 0x00020D99}, + {0x10030, 0x00021193}, + {0x10030, 0x0002155F}, + {0x10030, 0x00021959}, + {0x10030, 0x00021D21}, + {0x10030, 0x00022119}, + {0x10030, 0x000224DF}, + {0x10030, 0x000228D9}, + {0x10030, 0x00022C9F}, + {0x10030, 0x00023099}, + {0x10030, 0x0002345F}, + {0x10030, 0x00023859}, + {0x10030, 0x00023C1F}, + {0x10030, 0x00024019}, + {0x10030, 0x00024413}, + {0x10030, 0x000281CD}, + {0x10030, 0x000285DB}, + {0x10030, 0x000289D5}, + {0x10030, 0x00028D9B}, + {0x10030, 0x0002918D}, + {0x10030, 0x00029555}, + {0x10030, 0x00029957}, + {0x10030, 0x00029D1F}, + {0x10030, 0x0002A119}, + {0x10030, 0x0002A4DF}, + {0x10030, 0x0002A8D9}, + {0x10030, 0x0002AC9F}, + {0x10030, 0x0002B099}, + {0x10030, 0x0002B45F}, + {0x10030, 0x0002B859}, + {0x10030, 0x0002BC1F}, + {0x10030, 0x0002C019}, + {0x10030, 0x0002C413}, + {0x10030, 0x000301D9}, + {0x10030, 0x000305DB}, + {0x10030, 0x000309D5}, + {0x10030, 0x00030D9B}, + {0x10030, 0x00031195}, + {0x10030, 0x0003155D}, + {0x10030, 0x00031955}, + {0x10030, 0x00031D1D}, + {0x10030, 0x00032119}, + {0x10030, 0x000324DF}, + {0x10030, 0x000328D9}, + {0x10030, 0x00032C9F}, + {0x10030, 0x00033099}, + {0x10030, 0x0003345F}, + {0x10030, 0x00033859}, + {0x10030, 0x00033C1F}, + {0x10030, 0x00034019}, + {0x10030, 0x00034413}, + {0x10030, 0x000601E1}, + {0x10030, 0x000605DB}, + {0x10030, 0x000609D5}, + {0x10030, 0x00060D9B}, + {0x10030, 0x00061195}, + {0x10030, 0x0006155B}, + {0x10030, 0x00061957}, + {0x10030, 0x00061D1F}, + {0x10030, 0x00062119}, + {0x10030, 0x000624DF}, + {0x10030, 0x000628D9}, + {0x10030, 0x00062C9F}, + {0x10030, 0x00063099}, + {0x10030, 0x0006345F}, + {0x10030, 0x00063859}, + {0x10030, 0x00063C1F}, + {0x10030, 0x00064019}, + {0x10030, 0x00064413}, + {0x10030, 0x000681E1}, + {0x10030, 0x000685DB}, + {0x10030, 0x000689D5}, + {0x10030, 0x00068D9B}, + {0x10030, 0x00069195}, + {0x10030, 0x0006955B}, + {0x10030, 0x00069957}, + {0x10030, 0x00069D1F}, + {0x10030, 0x0006A119}, + {0x10030, 0x0006A4DF}, + {0x10030, 0x0006A8D9}, + {0x10030, 0x0006AC9F}, + {0x10030, 0x0006B099}, + {0x10030, 0x0006B45F}, + {0x10030, 0x0006B859}, + {0x10030, 0x0006BC1F}, + {0x10030, 0x0006C019}, + {0x10030, 0x0006C413}, + {0x10030, 0x000701E1}, + {0x10030, 0x000705DB}, + {0x10030, 0x000709D5}, + {0x10030, 0x00070D9B}, + {0x10030, 0x00071195}, + {0x10030, 0x0007155B}, + {0x10030, 0x00071957}, + {0x10030, 0x00071D1F}, + {0x10030, 0x00072119}, + {0x10030, 0x000724DF}, + {0x10030, 0x000728D9}, + {0x10030, 0x00072C9F}, + {0x10030, 0x00073099}, + {0x10030, 0x0007345F}, + {0x10030, 0x00073859}, + {0x10030, 0x00073C1F}, + {0x10030, 0x00074019}, + {0x10030, 0x00074413}, + {0x10030, 0x000781DF}, + {0x10030, 0x000785D9}, + {0x10030, 0x000789D3}, + {0x10030, 0x00078D99}, + {0x10030, 0x00079193}, + {0x10030, 0x0007955F}, + {0x10030, 0x00079959}, + {0x10030, 0x00079D21}, + {0x10030, 0x0007A115}, + {0x10030, 0x0007A4DF}, + {0x10030, 0x0007A8D9}, + {0x10030, 0x0007AC9F}, + {0x10030, 0x0007B099}, + {0x10030, 0x0007B45F}, + {0x10030, 0x0007B859}, + {0x10030, 0x0007BC1F}, + {0x10030, 0x0007C019}, + {0x10030, 0x0007C413}, + {0x10030, 0x00000000}, + {0x10030, 0x000785A9}, + {0x10030, 0x000789A3}, + {0x10030, 0x00078D9D}, + {0x10030, 0x00079197}, + {0x10030, 0x00079591}, + {0x10030, 0x00079957}, + {0x10030, 0x00079D51}, + {0x10030, 0x0007A119}, + {0x10030, 0x0007A513}, + {0x10030, 0x0007A8D9}, + {0x10030, 0x0007ACD3}, + {0x10030, 0x0007B099}, + {0x10030, 0x0007B493}, + {0x10030, 0x0007B859}, + {0x10030, 0x0007BC53}, + {0x10030, 0x0007C019}, + {0x10030, 0x0007C413}, + {0x90350000, 0x00000000}, {0x40000000, 0x00000000}, + {0x10030, 0x000201DF}, + {0x10030, 0x000205D9}, + {0x10030, 0x000209D3}, + {0x10030, 0x00020D99}, + {0x10030, 0x00021193}, + {0x10030, 0x0002155F}, + {0x10030, 0x00021959}, + {0x10030, 0x00021D21}, + {0x10030, 0x00022119}, + {0x10030, 0x000224DF}, + {0x10030, 0x000228D9}, + {0x10030, 0x00022C9F}, + {0x10030, 0x00023099}, + {0x10030, 0x0002345F}, + {0x10030, 0x00023859}, + {0x10030, 0x00023C1F}, + {0x10030, 0x00024019}, + {0x10030, 0x00024413}, + {0x10030, 0x000281CD}, + {0x10030, 0x000285DB}, + {0x10030, 0x000289D5}, + {0x10030, 0x00028D9B}, + {0x10030, 0x0002918D}, + {0x10030, 0x00029555}, + {0x10030, 0x00029957}, + {0x10030, 0x00029D1F}, + {0x10030, 0x0002A119}, + {0x10030, 0x0002A4DF}, + {0x10030, 0x0002A8D9}, + {0x10030, 0x0002AC9F}, + {0x10030, 0x0002B099}, + {0x10030, 0x0002B45F}, + {0x10030, 0x0002B859}, + {0x10030, 0x0002BC1F}, + {0x10030, 0x0002C019}, + {0x10030, 0x0002C413}, + {0x10030, 0x000301D9}, + {0x10030, 0x000305DB}, + {0x10030, 0x000309D5}, + {0x10030, 0x00030D9B}, + {0x10030, 0x00031195}, + {0x10030, 0x0003155D}, + {0x10030, 0x00031955}, + {0x10030, 0x00031D1D}, + {0x10030, 0x00032119}, + {0x10030, 0x000324DF}, + {0x10030, 0x000328D9}, + {0x10030, 0x00032C9F}, + {0x10030, 0x00033099}, + {0x10030, 0x0003345F}, + {0x10030, 0x00033859}, + {0x10030, 0x00033C1F}, + {0x10030, 0x00034019}, + {0x10030, 0x00034413}, + {0x10030, 0x000601E1}, + {0x10030, 0x000605DB}, + {0x10030, 0x000609D5}, + {0x10030, 0x00060D9B}, + {0x10030, 0x00061195}, + {0x10030, 0x0006155B}, + {0x10030, 0x00061957}, + {0x10030, 0x00061D1F}, + {0x10030, 0x00062119}, + {0x10030, 0x000624DF}, + {0x10030, 0x000628D9}, + {0x10030, 0x00062C9F}, + {0x10030, 0x00063099}, + {0x10030, 0x0006345F}, + {0x10030, 0x00063859}, + {0x10030, 0x00063C1F}, + {0x10030, 0x00064019}, + {0x10030, 0x00064413}, + {0x10030, 0x000681E1}, + {0x10030, 0x000685DB}, + {0x10030, 0x000689D5}, + {0x10030, 0x00068D9B}, + {0x10030, 0x00069195}, + {0x10030, 0x0006955B}, + {0x10030, 0x00069957}, + {0x10030, 0x00069D1F}, + {0x10030, 0x0006A119}, + {0x10030, 0x0006A4DF}, + {0x10030, 0x0006A8D9}, + {0x10030, 0x0006AC9F}, + {0x10030, 0x0006B099}, + {0x10030, 0x0006B45F}, + {0x10030, 0x0006B859}, + {0x10030, 0x0006BC1F}, + {0x10030, 0x0006C019}, + {0x10030, 0x0006C413}, + {0x10030, 0x000701E1}, + {0x10030, 0x000705DB}, + {0x10030, 0x000709D5}, + {0x10030, 0x00070D9B}, + {0x10030, 0x00071195}, + {0x10030, 0x0007155B}, + {0x10030, 0x00071957}, + {0x10030, 0x00071D1F}, + {0x10030, 0x00072119}, + {0x10030, 0x000724DF}, + {0x10030, 0x000728D9}, + {0x10030, 0x00072C9F}, + {0x10030, 0x00073099}, + {0x10030, 0x0007345F}, + {0x10030, 0x00073859}, + {0x10030, 0x00073C1F}, + {0x10030, 0x00074019}, + {0x10030, 0x00074413}, + {0x10030, 0x000781DF}, + {0x10030, 0x000785D9}, + {0x10030, 0x000789D3}, + {0x10030, 0x00078D99}, + {0x10030, 0x00079193}, + {0x10030, 0x0007955F}, + {0x10030, 0x00079959}, + {0x10030, 0x00079D21}, + {0x10030, 0x0007A115}, + {0x10030, 0x0007A4DF}, + {0x10030, 0x0007A8D9}, + {0x10030, 0x0007AC9F}, + {0x10030, 0x0007B099}, + {0x10030, 0x0007B45F}, + {0x10030, 0x0007B859}, + {0x10030, 0x0007BC1F}, + {0x10030, 0x0007C019}, + {0x10030, 0x0007C413}, + {0x10030, 0x00000000}, + {0x10030, 0x000785A9}, + {0x10030, 0x000789A3}, + {0x10030, 0x00078D9D}, + {0x10030, 0x00079197}, + {0x10030, 0x00079591}, + {0x10030, 0x00079957}, + {0x10030, 0x00079D51}, + {0x10030, 0x0007A119}, + {0x10030, 0x0007A513}, + {0x10030, 0x0007A8D9}, + {0x10030, 0x0007ACD3}, + {0x10030, 0x0007B099}, + {0x10030, 0x0007B493}, + {0x10030, 0x0007B859}, + {0x10030, 0x0007BC53}, + {0x10030, 0x0007C019}, + {0x10030, 0x0007C413}, + {0x90360000, 0x00000000}, {0x40000000, 0x00000000}, + {0x10030, 0x000201DF}, + {0x10030, 0x000205D9}, + {0x10030, 0x000209D3}, + {0x10030, 0x00020D99}, + {0x10030, 0x00021193}, + {0x10030, 0x0002155F}, + {0x10030, 0x00021959}, + {0x10030, 0x00021D21}, + {0x10030, 0x00022119}, + {0x10030, 0x000224DF}, + {0x10030, 0x000228D9}, + {0x10030, 0x00022C9F}, + {0x10030, 0x00023099}, + {0x10030, 0x0002345F}, + {0x10030, 0x00023859}, + {0x10030, 0x00023C1F}, + {0x10030, 0x00024019}, + {0x10030, 0x00024413}, + {0x10030, 0x000281CD}, + {0x10030, 0x000285DB}, + {0x10030, 0x000289D5}, + {0x10030, 0x00028D9B}, + {0x10030, 0x0002918D}, + {0x10030, 0x00029555}, + {0x10030, 0x00029957}, + {0x10030, 0x00029D1F}, + {0x10030, 0x0002A119}, + {0x10030, 0x0002A4DF}, + {0x10030, 0x0002A8D9}, + {0x10030, 0x0002AC9F}, + {0x10030, 0x0002B099}, + {0x10030, 0x0002B45F}, + {0x10030, 0x0002B859}, + {0x10030, 0x0002BC1F}, + {0x10030, 0x0002C019}, + {0x10030, 0x0002C413}, + {0x10030, 0x000301D9}, + {0x10030, 0x000305DB}, + {0x10030, 0x000309D5}, + {0x10030, 0x00030D9B}, + {0x10030, 0x00031195}, + {0x10030, 0x0003155D}, + {0x10030, 0x00031955}, + {0x10030, 0x00031D1D}, + {0x10030, 0x00032119}, + {0x10030, 0x000324DF}, + {0x10030, 0x000328D9}, + {0x10030, 0x00032C9F}, + {0x10030, 0x00033099}, + {0x10030, 0x0003345F}, + {0x10030, 0x00033859}, + {0x10030, 0x00033C1F}, + {0x10030, 0x00034019}, + {0x10030, 0x00034413}, + {0x10030, 0x000601E1}, + {0x10030, 0x000605DB}, + {0x10030, 0x000609D5}, + {0x10030, 0x00060D9B}, + {0x10030, 0x00061195}, + {0x10030, 0x0006155B}, + {0x10030, 0x00061957}, + {0x10030, 0x00061D1F}, + {0x10030, 0x00062119}, + {0x10030, 0x000624DF}, + {0x10030, 0x000628D9}, + {0x10030, 0x00062C9F}, + {0x10030, 0x00063099}, + {0x10030, 0x0006345F}, + {0x10030, 0x00063859}, + {0x10030, 0x00063C1F}, + {0x10030, 0x00064019}, + {0x10030, 0x00064413}, + {0x10030, 0x000681E1}, + {0x10030, 0x000685DB}, + {0x10030, 0x000689D5}, + {0x10030, 0x00068D9B}, + {0x10030, 0x00069195}, + {0x10030, 0x0006955B}, + {0x10030, 0x00069957}, + {0x10030, 0x00069D1F}, + {0x10030, 0x0006A119}, + {0x10030, 0x0006A4DF}, + {0x10030, 0x0006A8D9}, + {0x10030, 0x0006AC9F}, + {0x10030, 0x0006B099}, + {0x10030, 0x0006B45F}, + {0x10030, 0x0006B859}, + {0x10030, 0x0006BC1F}, + {0x10030, 0x0006C019}, + {0x10030, 0x0006C413}, + {0x10030, 0x000701E1}, + {0x10030, 0x000705DB}, + {0x10030, 0x000709D5}, + {0x10030, 0x00070D9B}, + {0x10030, 0x00071195}, + {0x10030, 0x0007155B}, + {0x10030, 0x00071957}, + {0x10030, 0x00071D1F}, + {0x10030, 0x00072119}, + {0x10030, 0x000724DF}, + {0x10030, 0x000728D9}, + {0x10030, 0x00072C9F}, + {0x10030, 0x00073099}, + {0x10030, 0x0007345F}, + {0x10030, 0x00073859}, + {0x10030, 0x00073C1F}, + {0x10030, 0x00074019}, + {0x10030, 0x00074413}, + {0x10030, 0x000781DF}, + {0x10030, 0x000785D9}, + {0x10030, 0x000789D3}, + {0x10030, 0x00078D99}, + {0x10030, 0x00079193}, + {0x10030, 0x0007955F}, + {0x10030, 0x00079959}, + {0x10030, 0x00079D21}, + {0x10030, 0x0007A115}, + {0x10030, 0x0007A4DF}, + {0x10030, 0x0007A8D9}, + {0x10030, 0x0007AC9F}, + {0x10030, 0x0007B099}, + {0x10030, 0x0007B45F}, + {0x10030, 0x0007B859}, + {0x10030, 0x0007BC1F}, + {0x10030, 0x0007C019}, + {0x10030, 0x0007C413}, + {0x10030, 0x00000000}, + {0x10030, 0x000785A9}, + {0x10030, 0x000789A3}, + {0x10030, 0x00078D9D}, + {0x10030, 0x00079197}, + {0x10030, 0x00079591}, + {0x10030, 0x00079957}, + {0x10030, 0x00079D51}, + {0x10030, 0x0007A119}, + {0x10030, 0x0007A513}, + {0x10030, 0x0007A8D9}, + {0x10030, 0x0007ACD3}, + {0x10030, 0x0007B099}, + {0x10030, 0x0007B493}, + {0x10030, 0x0007B859}, + {0x10030, 0x0007BC53}, + {0x10030, 0x0007C019}, + {0x10030, 0x0007C413}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x10030, 0x000001EF}, + {0x10030, 0x000005E9}, + {0x10030, 0x000009E3}, + {0x10030, 0x00000DDD}, + {0x10030, 0x000011D7}, + {0x10030, 0x0000159F}, + {0x10030, 0x00001999}, + {0x10030, 0x00001D5F}, + {0x10030, 0x00002159}, + {0x10030, 0x0000251F}, + {0x10030, 0x00002919}, + {0x10030, 0x00002CDF}, + {0x10030, 0x000030D9}, + {0x10030, 0x0000349F}, + {0x10030, 0x00003899}, + {0x10030, 0x00003C5F}, + {0x10030, 0x00004059}, + {0x10030, 0x00004453}, + {0x10030, 0x000201ED}, + {0x10030, 0x000205AD}, + {0x10030, 0x000209A7}, + {0x10030, 0x00020DA1}, + {0x10030, 0x0002119B}, + {0x10030, 0x00021561}, + {0x10030, 0x0002195B}, + {0x10030, 0x00021D27}, + {0x10030, 0x00022121}, + {0x10030, 0x000224E9}, + {0x10030, 0x000228E3}, + {0x10030, 0x00022CA9}, + {0x10030, 0x000230A3}, + {0x10030, 0x00023469}, + {0x10030, 0x00023863}, + {0x10030, 0x00023C29}, + {0x10030, 0x00024023}, + {0x10030, 0x0002441D}, + {0x10030, 0x000281EF}, + {0x10030, 0x000285AF}, + {0x10030, 0x000289A9}, + {0x10030, 0x00028DA3}, + {0x10030, 0x0002919D}, + {0x10030, 0x00029563}, + {0x10030, 0x0002995D}, + {0x10030, 0x00029D25}, + {0x10030, 0x0002A11F}, + {0x10030, 0x0002A4E7}, + {0x10030, 0x0002A8E1}, + {0x10030, 0x0002ACA7}, + {0x10030, 0x0002B0A1}, + {0x10030, 0x0002B467}, + {0x10030, 0x0002B861}, + {0x10030, 0x0002BC27}, + {0x10030, 0x0002C021}, + {0x10030, 0x0002C41B}, + {0x10030, 0x000301EF}, + {0x10030, 0x000305AF}, + {0x10030, 0x000309A9}, + {0x10030, 0x00030DA3}, + {0x10030, 0x0003119D}, + {0x10030, 0x00031563}, + {0x10030, 0x0003195D}, + {0x10030, 0x00031D25}, + {0x10030, 0x0003211F}, + {0x10030, 0x000324E7}, + {0x10030, 0x000328E1}, + {0x10030, 0x00032CA7}, + {0x10030, 0x000330A1}, + {0x10030, 0x00033467}, + {0x10030, 0x00033861}, + {0x10030, 0x00033C27}, + {0x10030, 0x00034021}, + {0x10030, 0x0003441B}, + {0x10030, 0x000601EB}, + {0x10030, 0x000605AB}, + {0x10030, 0x000609A5}, + {0x10030, 0x00060D9F}, + {0x10030, 0x00061199}, + {0x10030, 0x00061593}, + {0x10030, 0x00061959}, + {0x10030, 0x00061D53}, + {0x10030, 0x0006211B}, + {0x10030, 0x00062515}, + {0x10030, 0x000628DD}, + {0x10030, 0x00062CD7}, + {0x10030, 0x0006309D}, + {0x10030, 0x00063497}, + {0x10030, 0x0006385D}, + {0x10030, 0x00063C57}, + {0x10030, 0x0006401D}, + {0x10030, 0x00064417}, + {0x10030, 0x000681E7}, + {0x10030, 0x000685A7}, + {0x10030, 0x000689A1}, + {0x10030, 0x00068D9B}, + {0x10030, 0x00069195}, + {0x10030, 0x0006955F}, + {0x10030, 0x00069959}, + {0x10030, 0x00069D21}, + {0x10030, 0x0006A11B}, + {0x10030, 0x0006A4E3}, + {0x10030, 0x0006A8DD}, + {0x10030, 0x0006ACA5}, + {0x10030, 0x0006B09F}, + {0x10030, 0x0006B465}, + {0x10030, 0x0006B85F}, + {0x10030, 0x0006BC25}, + {0x10030, 0x0006C01F}, + {0x10030, 0x0006C419}, + {0x10030, 0x000701E7}, + {0x10030, 0x000705A7}, + {0x10030, 0x000709A1}, + {0x10030, 0x00070D9B}, + {0x10030, 0x00071195}, + {0x10030, 0x0007155B}, + {0x10030, 0x00071955}, + {0x10030, 0x00071D1D}, + {0x10030, 0x00072117}, + {0x10030, 0x000724DF}, + {0x10030, 0x000728D9}, + {0x10030, 0x00072CA1}, + {0x10030, 0x0007309B}, + {0x10030, 0x00073461}, + {0x10030, 0x0007385B}, + {0x10030, 0x00073C21}, + {0x10030, 0x0007401B}, + {0x10030, 0x0007441B}, + {0x10030, 0x000781EF}, + {0x10030, 0x000785E9}, + {0x10030, 0x000789E3}, + {0x10030, 0x00078DA3}, + {0x10030, 0x00079161}, + {0x10030, 0x0007955B}, + {0x10030, 0x00079921}, + {0x10030, 0x00079D1B}, + {0x10030, 0x0007A0E1}, + {0x10030, 0x0007A4DB}, + {0x10030, 0x0007A8A1}, + {0x10030, 0x0007AC9B}, + {0x10030, 0x0007B061}, + {0x10030, 0x0007B45B}, + {0x10030, 0x0007B821}, + {0x10030, 0x0007BC1B}, + {0x10030, 0x0007C015}, + {0x10030, 0x0007C40F}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x10030, 0x000001EF}, + {0x10030, 0x000005E9}, + {0x10030, 0x000009E3}, + {0x10030, 0x00000DDD}, + {0x10030, 0x000011D7}, + {0x10030, 0x0000159F}, + {0x10030, 0x00001999}, + {0x10030, 0x00001D5F}, + {0x10030, 0x00002159}, + {0x10030, 0x0000251F}, + {0x10030, 0x00002919}, + {0x10030, 0x00002CDF}, + {0x10030, 0x000030D9}, + {0x10030, 0x0000349F}, + {0x10030, 0x00003899}, + {0x10030, 0x00003C5F}, + {0x10030, 0x00004059}, + {0x10030, 0x00004453}, + {0x10030, 0x000201ED}, + {0x10030, 0x000205AD}, + {0x10030, 0x000209A7}, + {0x10030, 0x00020DA1}, + {0x10030, 0x0002119B}, + {0x10030, 0x00021561}, + {0x10030, 0x0002195B}, + {0x10030, 0x00021D27}, + {0x10030, 0x00022121}, + {0x10030, 0x000224E9}, + {0x10030, 0x000228E3}, + {0x10030, 0x00022CA9}, + {0x10030, 0x000230A3}, + {0x10030, 0x00023469}, + {0x10030, 0x00023863}, + {0x10030, 0x00023C29}, + {0x10030, 0x00024023}, + {0x10030, 0x0002441D}, + {0x10030, 0x000281EF}, + {0x10030, 0x000285AF}, + {0x10030, 0x000289A9}, + {0x10030, 0x00028DA3}, + {0x10030, 0x0002919D}, + {0x10030, 0x00029563}, + {0x10030, 0x0002995D}, + {0x10030, 0x00029D25}, + {0x10030, 0x0002A11F}, + {0x10030, 0x0002A4E7}, + {0x10030, 0x0002A8E1}, + {0x10030, 0x0002ACA7}, + {0x10030, 0x0002B0A1}, + {0x10030, 0x0002B467}, + {0x10030, 0x0002B861}, + {0x10030, 0x0002BC27}, + {0x10030, 0x0002C021}, + {0x10030, 0x0002C41B}, + {0x10030, 0x000301EF}, + {0x10030, 0x000305AF}, + {0x10030, 0x000309A9}, + {0x10030, 0x00030DA3}, + {0x10030, 0x0003119D}, + {0x10030, 0x00031563}, + {0x10030, 0x0003195D}, + {0x10030, 0x00031D25}, + {0x10030, 0x0003211F}, + {0x10030, 0x000324E7}, + {0x10030, 0x000328E1}, + {0x10030, 0x00032CA7}, + {0x10030, 0x000330A1}, + {0x10030, 0x00033467}, + {0x10030, 0x00033861}, + {0x10030, 0x00033C27}, + {0x10030, 0x00034021}, + {0x10030, 0x0003441B}, + {0x10030, 0x000601EB}, + {0x10030, 0x000605AB}, + {0x10030, 0x000609A5}, + {0x10030, 0x00060D9F}, + {0x10030, 0x00061199}, + {0x10030, 0x00061593}, + {0x10030, 0x00061959}, + {0x10030, 0x00061D53}, + {0x10030, 0x0006211B}, + {0x10030, 0x00062515}, + {0x10030, 0x000628DD}, + {0x10030, 0x00062CD7}, + {0x10030, 0x0006309D}, + {0x10030, 0x00063497}, + {0x10030, 0x0006385D}, + {0x10030, 0x00063C57}, + {0x10030, 0x0006401D}, + {0x10030, 0x00064417}, + {0x10030, 0x000681E7}, + {0x10030, 0x000685A7}, + {0x10030, 0x000689A1}, + {0x10030, 0x00068D9B}, + {0x10030, 0x00069195}, + {0x10030, 0x0006955F}, + {0x10030, 0x00069959}, + {0x10030, 0x00069D21}, + {0x10030, 0x0006A11B}, + {0x10030, 0x0006A4E3}, + {0x10030, 0x0006A8DD}, + {0x10030, 0x0006ACA5}, + {0x10030, 0x0006B09F}, + {0x10030, 0x0006B465}, + {0x10030, 0x0006B85F}, + {0x10030, 0x0006BC25}, + {0x10030, 0x0006C01F}, + {0x10030, 0x0006C419}, + {0x10030, 0x000701E7}, + {0x10030, 0x000705A7}, + {0x10030, 0x000709A1}, + {0x10030, 0x00070D9B}, + {0x10030, 0x00071195}, + {0x10030, 0x0007155B}, + {0x10030, 0x00071955}, + {0x10030, 0x00071D1D}, + {0x10030, 0x00072117}, + {0x10030, 0x000724DF}, + {0x10030, 0x000728D9}, + {0x10030, 0x00072CA1}, + {0x10030, 0x0007309B}, + {0x10030, 0x00073461}, + {0x10030, 0x0007385B}, + {0x10030, 0x00073C21}, + {0x10030, 0x0007401B}, + {0x10030, 0x0007441B}, + {0x10030, 0x000781EF}, + {0x10030, 0x000785E9}, + {0x10030, 0x000789E3}, + {0x10030, 0x00078DA3}, + {0x10030, 0x00079161}, + {0x10030, 0x0007955B}, + {0x10030, 0x00079921}, + {0x10030, 0x00079D1B}, + {0x10030, 0x0007A0E1}, + {0x10030, 0x0007A4DB}, + {0x10030, 0x0007A8A1}, + {0x10030, 0x0007AC9B}, + {0x10030, 0x0007B061}, + {0x10030, 0x0007B45B}, + {0x10030, 0x0007B821}, + {0x10030, 0x0007BC1B}, + {0x10030, 0x0007C015}, + {0x10030, 0x0007C40F}, + {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, + {0x10030, 0x000001EF}, + {0x10030, 0x000005E9}, + {0x10030, 0x000009E3}, + {0x10030, 0x00000DDD}, + {0x10030, 0x000011D7}, + {0x10030, 0x0000159F}, + {0x10030, 0x00001999}, + {0x10030, 0x00001D5F}, + {0x10030, 0x00002159}, + {0x10030, 0x0000251F}, + {0x10030, 0x00002919}, + {0x10030, 0x00002CDF}, + {0x10030, 0x000030D9}, + {0x10030, 0x0000349F}, + {0x10030, 0x00003899}, + {0x10030, 0x00003C5F}, + {0x10030, 0x00004059}, + {0x10030, 0x00004453}, + {0x10030, 0x000201ED}, + {0x10030, 0x000205AD}, + {0x10030, 0x000209A7}, + {0x10030, 0x00020DA1}, + {0x10030, 0x0002119B}, + {0x10030, 0x00021561}, + {0x10030, 0x0002195B}, + {0x10030, 0x00021D27}, + {0x10030, 0x00022121}, + {0x10030, 0x000224E9}, + {0x10030, 0x000228E3}, + {0x10030, 0x00022CA9}, + {0x10030, 0x000230A3}, + {0x10030, 0x00023469}, + {0x10030, 0x00023863}, + {0x10030, 0x00023C29}, + {0x10030, 0x00024023}, + {0x10030, 0x0002441D}, + {0x10030, 0x000281EF}, + {0x10030, 0x000285AF}, + {0x10030, 0x000289A9}, + {0x10030, 0x00028DA3}, + {0x10030, 0x0002919D}, + {0x10030, 0x00029563}, + {0x10030, 0x0002995D}, + {0x10030, 0x00029D25}, + {0x10030, 0x0002A11F}, + {0x10030, 0x0002A4E7}, + {0x10030, 0x0002A8E1}, + {0x10030, 0x0002ACA7}, + {0x10030, 0x0002B0A1}, + {0x10030, 0x0002B467}, + {0x10030, 0x0002B861}, + {0x10030, 0x0002BC27}, + {0x10030, 0x0002C021}, + {0x10030, 0x0002C41B}, + {0x10030, 0x000301EF}, + {0x10030, 0x000305AF}, + {0x10030, 0x000309A9}, + {0x10030, 0x00030DA3}, + {0x10030, 0x0003119D}, + {0x10030, 0x00031563}, + {0x10030, 0x0003195D}, + {0x10030, 0x00031D25}, + {0x10030, 0x0003211F}, + {0x10030, 0x000324E7}, + {0x10030, 0x000328E1}, + {0x10030, 0x00032CA7}, + {0x10030, 0x000330A1}, + {0x10030, 0x00033467}, + {0x10030, 0x00033861}, + {0x10030, 0x00033C27}, + {0x10030, 0x00034021}, + {0x10030, 0x0003441B}, + {0x10030, 0x000601EB}, + {0x10030, 0x000605AB}, + {0x10030, 0x000609A5}, + {0x10030, 0x00060D9F}, + {0x10030, 0x00061199}, + {0x10030, 0x00061593}, + {0x10030, 0x00061959}, + {0x10030, 0x00061D53}, + {0x10030, 0x0006211B}, + {0x10030, 0x00062515}, + {0x10030, 0x000628DD}, + {0x10030, 0x00062CD7}, + {0x10030, 0x0006309D}, + {0x10030, 0x00063497}, + {0x10030, 0x0006385D}, + {0x10030, 0x00063C57}, + {0x10030, 0x0006401D}, + {0x10030, 0x00064417}, + {0x10030, 0x000681E7}, + {0x10030, 0x000685A7}, + {0x10030, 0x000689A1}, + {0x10030, 0x00068D9B}, + {0x10030, 0x00069195}, + {0x10030, 0x0006955F}, + {0x10030, 0x00069959}, + {0x10030, 0x00069D21}, + {0x10030, 0x0006A11B}, + {0x10030, 0x0006A4E3}, + {0x10030, 0x0006A8DD}, + {0x10030, 0x0006ACA5}, + {0x10030, 0x0006B09F}, + {0x10030, 0x0006B465}, + {0x10030, 0x0006B85F}, + {0x10030, 0x0006BC25}, + {0x10030, 0x0006C01F}, + {0x10030, 0x0006C419}, + {0x10030, 0x000701E7}, + {0x10030, 0x000705A7}, + {0x10030, 0x000709A1}, + {0x10030, 0x00070D9B}, + {0x10030, 0x00071195}, + {0x10030, 0x0007155B}, + {0x10030, 0x00071955}, + {0x10030, 0x00071D1D}, + {0x10030, 0x00072117}, + {0x10030, 0x000724DF}, + {0x10030, 0x000728D9}, + {0x10030, 0x00072CA1}, + {0x10030, 0x0007309B}, + {0x10030, 0x00073461}, + {0x10030, 0x0007385B}, + {0x10030, 0x00073C21}, + {0x10030, 0x0007401B}, + {0x10030, 0x0007441B}, + {0x10030, 0x000781EF}, + {0x10030, 0x000785E9}, + {0x10030, 0x000789E3}, + {0x10030, 0x00078DA3}, + {0x10030, 0x00079161}, + {0x10030, 0x0007955B}, + {0x10030, 0x00079921}, + {0x10030, 0x00079D1B}, + {0x10030, 0x0007A0E1}, + {0x10030, 0x0007A4DB}, + {0x10030, 0x0007A8A1}, + {0x10030, 0x0007AC9B}, + {0x10030, 0x0007B061}, + {0x10030, 0x0007B45B}, + {0x10030, 0x0007B821}, + {0x10030, 0x0007BC1B}, + {0x10030, 0x0007C015}, + {0x10030, 0x0007C40F}, + {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, + {0x10030, 0x000201DF}, + {0x10030, 0x000205D9}, + {0x10030, 0x000209D3}, + {0x10030, 0x00020D99}, + {0x10030, 0x00021193}, + {0x10030, 0x0002155F}, + {0x10030, 0x00021959}, + {0x10030, 0x00021D21}, + {0x10030, 0x00022119}, + {0x10030, 0x000224DF}, + {0x10030, 0x000228D9}, + {0x10030, 0x00022C9F}, + {0x10030, 0x00023099}, + {0x10030, 0x0002345F}, + {0x10030, 0x00023859}, + {0x10030, 0x00023C1F}, + {0x10030, 0x00024019}, + {0x10030, 0x00024413}, + {0x10030, 0x000281CD}, + {0x10030, 0x000285DB}, + {0x10030, 0x000289D5}, + {0x10030, 0x00028D9B}, + {0x10030, 0x0002918D}, + {0x10030, 0x00029555}, + {0x10030, 0x00029957}, + {0x10030, 0x00029D1F}, + {0x10030, 0x0002A119}, + {0x10030, 0x0002A4DF}, + {0x10030, 0x0002A8D9}, + {0x10030, 0x0002AC9F}, + {0x10030, 0x0002B099}, + {0x10030, 0x0002B45F}, + {0x10030, 0x0002B859}, + {0x10030, 0x0002BC1F}, + {0x10030, 0x0002C019}, + {0x10030, 0x0002C413}, + {0x10030, 0x000301D9}, + {0x10030, 0x000305DB}, + {0x10030, 0x000309D5}, + {0x10030, 0x00030D9B}, + {0x10030, 0x00031195}, + {0x10030, 0x0003155D}, + {0x10030, 0x00031955}, + {0x10030, 0x00031D1D}, + {0x10030, 0x00032119}, + {0x10030, 0x000324DF}, + {0x10030, 0x000328D9}, + {0x10030, 0x00032C9F}, + {0x10030, 0x00033099}, + {0x10030, 0x0003345F}, + {0x10030, 0x00033859}, + {0x10030, 0x00033C1F}, + {0x10030, 0x00034019}, + {0x10030, 0x00034413}, + {0x10030, 0x000601E1}, + {0x10030, 0x000605DB}, + {0x10030, 0x000609D5}, + {0x10030, 0x00060D9B}, + {0x10030, 0x00061195}, + {0x10030, 0x0006155B}, + {0x10030, 0x00061957}, + {0x10030, 0x00061D1F}, + {0x10030, 0x00062119}, + {0x10030, 0x000624DF}, + {0x10030, 0x000628D9}, + {0x10030, 0x00062C9F}, + {0x10030, 0x00063099}, + {0x10030, 0x0006345F}, + {0x10030, 0x00063859}, + {0x10030, 0x00063C1F}, + {0x10030, 0x00064019}, + {0x10030, 0x00064413}, + {0x10030, 0x000681E1}, + {0x10030, 0x000685DB}, + {0x10030, 0x000689D5}, + {0x10030, 0x00068D9B}, + {0x10030, 0x00069195}, + {0x10030, 0x0006955B}, + {0x10030, 0x00069957}, + {0x10030, 0x00069D1F}, + {0x10030, 0x0006A119}, + {0x10030, 0x0006A4DF}, + {0x10030, 0x0006A8D9}, + {0x10030, 0x0006AC9F}, + {0x10030, 0x0006B099}, + {0x10030, 0x0006B45F}, + {0x10030, 0x0006B859}, + {0x10030, 0x0006BC1F}, + {0x10030, 0x0006C019}, + {0x10030, 0x0006C413}, + {0x10030, 0x000701E1}, + {0x10030, 0x000705DB}, + {0x10030, 0x000709D5}, + {0x10030, 0x00070D9B}, + {0x10030, 0x00071195}, + {0x10030, 0x0007155B}, + {0x10030, 0x00071957}, + {0x10030, 0x00071D1F}, + {0x10030, 0x00072119}, + {0x10030, 0x000724DF}, + {0x10030, 0x000728D9}, + {0x10030, 0x00072C9F}, + {0x10030, 0x00073099}, + {0x10030, 0x0007345F}, + {0x10030, 0x00073859}, + {0x10030, 0x00073C1F}, + {0x10030, 0x00074019}, + {0x10030, 0x00074413}, + {0x10030, 0x000781DF}, + {0x10030, 0x000785D9}, + {0x10030, 0x000789D3}, + {0x10030, 0x00078D99}, + {0x10030, 0x00079193}, + {0x10030, 0x0007955F}, + {0x10030, 0x00079959}, + {0x10030, 0x00079D21}, + {0x10030, 0x0007A115}, + {0x10030, 0x0007A4DF}, + {0x10030, 0x0007A8D9}, + {0x10030, 0x0007AC9F}, + {0x10030, 0x0007B099}, + {0x10030, 0x0007B45F}, + {0x10030, 0x0007B859}, + {0x10030, 0x0007BC1F}, + {0x10030, 0x0007C019}, + {0x10030, 0x0007C413}, + {0x10030, 0x00000000}, + {0x10030, 0x000785A9}, + {0x10030, 0x000789A3}, + {0x10030, 0x00078D9D}, + {0x10030, 0x00079197}, + {0x10030, 0x00079591}, + {0x10030, 0x00079957}, + {0x10030, 0x00079D51}, + {0x10030, 0x0007A119}, + {0x10030, 0x0007A513}, + {0x10030, 0x0007A8D9}, + {0x10030, 0x0007ACD3}, + {0x10030, 0x0007B099}, + {0x10030, 0x0007B493}, + {0x10030, 0x0007B859}, + {0x10030, 0x0007BC53}, + {0x10030, 0x0007C019}, + {0x10030, 0x0007C413}, + {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, + {0x10030, 0x000201DF}, + {0x10030, 0x000205D9}, + {0x10030, 0x000209D3}, + {0x10030, 0x00020D99}, + {0x10030, 0x00021193}, + {0x10030, 0x0002155F}, + {0x10030, 0x00021959}, + {0x10030, 0x00021D21}, + {0x10030, 0x00022119}, + {0x10030, 0x000224DF}, + {0x10030, 0x000228D9}, + {0x10030, 0x00022C9F}, + {0x10030, 0x00023099}, + {0x10030, 0x0002345F}, + {0x10030, 0x00023859}, + {0x10030, 0x00023C1F}, + {0x10030, 0x00024019}, + {0x10030, 0x00024413}, + {0x10030, 0x000281CD}, + {0x10030, 0x000285DB}, + {0x10030, 0x000289D5}, + {0x10030, 0x00028D9B}, + {0x10030, 0x0002918D}, + {0x10030, 0x00029555}, + {0x10030, 0x00029957}, + {0x10030, 0x00029D1F}, + {0x10030, 0x0002A119}, + {0x10030, 0x0002A4DF}, + {0x10030, 0x0002A8D9}, + {0x10030, 0x0002AC9F}, + {0x10030, 0x0002B099}, + {0x10030, 0x0002B45F}, + {0x10030, 0x0002B859}, + {0x10030, 0x0002BC1F}, + {0x10030, 0x0002C019}, + {0x10030, 0x0002C413}, + {0x10030, 0x000301D9}, + {0x10030, 0x000305DB}, + {0x10030, 0x000309D5}, + {0x10030, 0x00030D9B}, + {0x10030, 0x00031195}, + {0x10030, 0x0003155D}, + {0x10030, 0x00031955}, + {0x10030, 0x00031D1D}, + {0x10030, 0x00032119}, + {0x10030, 0x000324DF}, + {0x10030, 0x000328D9}, + {0x10030, 0x00032C9F}, + {0x10030, 0x00033099}, + {0x10030, 0x0003345F}, + {0x10030, 0x00033859}, + {0x10030, 0x00033C1F}, + {0x10030, 0x00034019}, + {0x10030, 0x00034413}, + {0x10030, 0x000601E1}, + {0x10030, 0x000605DB}, + {0x10030, 0x000609D5}, + {0x10030, 0x00060D9B}, + {0x10030, 0x00061195}, + {0x10030, 0x0006155B}, + {0x10030, 0x00061957}, + {0x10030, 0x00061D1F}, + {0x10030, 0x00062119}, + {0x10030, 0x000624DF}, + {0x10030, 0x000628D9}, + {0x10030, 0x00062C9F}, + {0x10030, 0x00063099}, + {0x10030, 0x0006345F}, + {0x10030, 0x00063859}, + {0x10030, 0x00063C1F}, + {0x10030, 0x00064019}, + {0x10030, 0x00064413}, + {0x10030, 0x000681E1}, + {0x10030, 0x000685DB}, + {0x10030, 0x000689D5}, + {0x10030, 0x00068D9B}, + {0x10030, 0x00069195}, + {0x10030, 0x0006955B}, + {0x10030, 0x00069957}, + {0x10030, 0x00069D1F}, + {0x10030, 0x0006A119}, + {0x10030, 0x0006A4DF}, + {0x10030, 0x0006A8D9}, + {0x10030, 0x0006AC9F}, + {0x10030, 0x0006B099}, + {0x10030, 0x0006B45F}, + {0x10030, 0x0006B859}, + {0x10030, 0x0006BC1F}, + {0x10030, 0x0006C019}, + {0x10030, 0x0006C413}, + {0x10030, 0x000701E1}, + {0x10030, 0x000705DB}, + {0x10030, 0x000709D5}, + {0x10030, 0x00070D9B}, + {0x10030, 0x00071195}, + {0x10030, 0x0007155B}, + {0x10030, 0x00071957}, + {0x10030, 0x00071D1F}, + {0x10030, 0x00072119}, + {0x10030, 0x000724DF}, + {0x10030, 0x000728D9}, + {0x10030, 0x00072C9F}, + {0x10030, 0x00073099}, + {0x10030, 0x0007345F}, + {0x10030, 0x00073859}, + {0x10030, 0x00073C1F}, + {0x10030, 0x00074019}, + {0x10030, 0x00074413}, + {0x10030, 0x000781DF}, + {0x10030, 0x000785D9}, + {0x10030, 0x000789D3}, + {0x10030, 0x00078D99}, + {0x10030, 0x00079193}, + {0x10030, 0x0007955F}, + {0x10030, 0x00079959}, + {0x10030, 0x00079D21}, + {0x10030, 0x0007A115}, + {0x10030, 0x0007A4DF}, + {0x10030, 0x0007A8D9}, + {0x10030, 0x0007AC9F}, + {0x10030, 0x0007B099}, + {0x10030, 0x0007B45F}, + {0x10030, 0x0007B859}, + {0x10030, 0x0007BC1F}, + {0x10030, 0x0007C019}, + {0x10030, 0x0007C413}, + {0x10030, 0x00000000}, + {0x10030, 0x000785A9}, + {0x10030, 0x000789A3}, + {0x10030, 0x00078D9D}, + {0x10030, 0x00079197}, + {0x10030, 0x00079591}, + {0x10030, 0x00079957}, + {0x10030, 0x00079D51}, + {0x10030, 0x0007A119}, + {0x10030, 0x0007A513}, + {0x10030, 0x0007A8D9}, + {0x10030, 0x0007ACD3}, + {0x10030, 0x0007B099}, + {0x10030, 0x0007B493}, + {0x10030, 0x0007B859}, + {0x10030, 0x0007BC53}, + {0x10030, 0x0007C019}, + {0x10030, 0x0007C413}, + {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, + {0x10030, 0x000201DF}, + {0x10030, 0x000205D9}, + {0x10030, 0x000209D3}, + {0x10030, 0x00020D99}, + {0x10030, 0x00021193}, + {0x10030, 0x0002155F}, + {0x10030, 0x00021959}, + {0x10030, 0x00021D21}, + {0x10030, 0x00022119}, + {0x10030, 0x000224DF}, + {0x10030, 0x000228D9}, + {0x10030, 0x00022C9F}, + {0x10030, 0x00023099}, + {0x10030, 0x0002345F}, + {0x10030, 0x00023859}, + {0x10030, 0x00023C1F}, + {0x10030, 0x00024019}, + {0x10030, 0x00024413}, + {0x10030, 0x000281CD}, + {0x10030, 0x000285DB}, + {0x10030, 0x000289D5}, + {0x10030, 0x00028D9B}, + {0x10030, 0x0002918D}, + {0x10030, 0x00029555}, + {0x10030, 0x00029957}, + {0x10030, 0x00029D1F}, + {0x10030, 0x0002A119}, + {0x10030, 0x0002A4DF}, + {0x10030, 0x0002A8D9}, + {0x10030, 0x0002AC9F}, + {0x10030, 0x0002B099}, + {0x10030, 0x0002B45F}, + {0x10030, 0x0002B859}, + {0x10030, 0x0002BC1F}, + {0x10030, 0x0002C019}, + {0x10030, 0x0002C413}, + {0x10030, 0x000301D9}, + {0x10030, 0x000305DB}, + {0x10030, 0x000309D5}, + {0x10030, 0x00030D9B}, + {0x10030, 0x00031195}, + {0x10030, 0x0003155D}, + {0x10030, 0x00031955}, + {0x10030, 0x00031D1D}, + {0x10030, 0x00032119}, + {0x10030, 0x000324DF}, + {0x10030, 0x000328D9}, + {0x10030, 0x00032C9F}, + {0x10030, 0x00033099}, + {0x10030, 0x0003345F}, + {0x10030, 0x00033859}, + {0x10030, 0x00033C1F}, + {0x10030, 0x00034019}, + {0x10030, 0x00034413}, + {0x10030, 0x000601E1}, + {0x10030, 0x000605DB}, + {0x10030, 0x000609D5}, + {0x10030, 0x00060D9B}, + {0x10030, 0x00061195}, + {0x10030, 0x0006155B}, + {0x10030, 0x00061957}, + {0x10030, 0x00061D1F}, + {0x10030, 0x00062119}, + {0x10030, 0x000624DF}, + {0x10030, 0x000628D9}, + {0x10030, 0x00062C9F}, + {0x10030, 0x00063099}, + {0x10030, 0x0006345F}, + {0x10030, 0x00063859}, + {0x10030, 0x00063C1F}, + {0x10030, 0x00064019}, + {0x10030, 0x00064413}, + {0x10030, 0x000681E1}, + {0x10030, 0x000685DB}, + {0x10030, 0x000689D5}, + {0x10030, 0x00068D9B}, + {0x10030, 0x00069195}, + {0x10030, 0x0006955B}, + {0x10030, 0x00069957}, + {0x10030, 0x00069D1F}, + {0x10030, 0x0006A119}, + {0x10030, 0x0006A4DF}, + {0x10030, 0x0006A8D9}, + {0x10030, 0x0006AC9F}, + {0x10030, 0x0006B099}, + {0x10030, 0x0006B45F}, + {0x10030, 0x0006B859}, + {0x10030, 0x0006BC1F}, + {0x10030, 0x0006C019}, + {0x10030, 0x0006C413}, + {0x10030, 0x000701E1}, + {0x10030, 0x000705DB}, + {0x10030, 0x000709D5}, + {0x10030, 0x00070D9B}, + {0x10030, 0x00071195}, + {0x10030, 0x0007155B}, + {0x10030, 0x00071957}, + {0x10030, 0x00071D1F}, + {0x10030, 0x00072119}, + {0x10030, 0x000724DF}, + {0x10030, 0x000728D9}, + {0x10030, 0x00072C9F}, + {0x10030, 0x00073099}, + {0x10030, 0x0007345F}, + {0x10030, 0x00073859}, + {0x10030, 0x00073C1F}, + {0x10030, 0x00074019}, + {0x10030, 0x00074413}, + {0x10030, 0x000781DF}, + {0x10030, 0x000785D9}, + {0x10030, 0x000789D3}, + {0x10030, 0x00078D99}, + {0x10030, 0x00079193}, + {0x10030, 0x0007955F}, + {0x10030, 0x00079959}, + {0x10030, 0x00079D21}, + {0x10030, 0x0007A115}, + {0x10030, 0x0007A4DF}, + {0x10030, 0x0007A8D9}, + {0x10030, 0x0007AC9F}, + {0x10030, 0x0007B099}, + {0x10030, 0x0007B45F}, + {0x10030, 0x0007B859}, + {0x10030, 0x0007BC1F}, + {0x10030, 0x0007C019}, + {0x10030, 0x0007C413}, + {0x10030, 0x00000000}, + {0x10030, 0x000785A9}, + {0x10030, 0x000789A3}, + {0x10030, 0x00078D9D}, + {0x10030, 0x00079197}, + {0x10030, 0x00079591}, + {0x10030, 0x00079957}, + {0x10030, 0x00079D51}, + {0x10030, 0x0007A119}, + {0x10030, 0x0007A513}, + {0x10030, 0x0007A8D9}, + {0x10030, 0x0007ACD3}, + {0x10030, 0x0007B099}, + {0x10030, 0x0007B493}, + {0x10030, 0x0007B859}, + {0x10030, 0x0007BC53}, + {0x10030, 0x0007C019}, + {0x10030, 0x0007C413}, + {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, + {0x10030, 0x000201DF}, + {0x10030, 0x000205D9}, + {0x10030, 0x000209D3}, + {0x10030, 0x00020D99}, + {0x10030, 0x00021193}, + {0x10030, 0x0002155F}, + {0x10030, 0x00021959}, + {0x10030, 0x00021D21}, + {0x10030, 0x00022119}, + {0x10030, 0x000224DF}, + {0x10030, 0x000228D9}, + {0x10030, 0x00022C9F}, + {0x10030, 0x00023099}, + {0x10030, 0x0002345F}, + {0x10030, 0x00023859}, + {0x10030, 0x00023C1F}, + {0x10030, 0x00024019}, + {0x10030, 0x00024413}, + {0x10030, 0x000281CD}, + {0x10030, 0x000285DB}, + {0x10030, 0x000289D5}, + {0x10030, 0x00028D9B}, + {0x10030, 0x0002918D}, + {0x10030, 0x00029555}, + {0x10030, 0x00029957}, + {0x10030, 0x00029D1F}, + {0x10030, 0x0002A119}, + {0x10030, 0x0002A4DF}, + {0x10030, 0x0002A8D9}, + {0x10030, 0x0002AC9F}, + {0x10030, 0x0002B099}, + {0x10030, 0x0002B45F}, + {0x10030, 0x0002B859}, + {0x10030, 0x0002BC1F}, + {0x10030, 0x0002C019}, + {0x10030, 0x0002C413}, + {0x10030, 0x000301D9}, + {0x10030, 0x000305DB}, + {0x10030, 0x000309D5}, + {0x10030, 0x00030D9B}, + {0x10030, 0x00031195}, + {0x10030, 0x0003155D}, + {0x10030, 0x00031955}, + {0x10030, 0x00031D1D}, + {0x10030, 0x00032119}, + {0x10030, 0x000324DF}, + {0x10030, 0x000328D9}, + {0x10030, 0x00032C9F}, + {0x10030, 0x00033099}, + {0x10030, 0x0003345F}, + {0x10030, 0x00033859}, + {0x10030, 0x00033C1F}, + {0x10030, 0x00034019}, + {0x10030, 0x00034413}, + {0x10030, 0x000601E1}, + {0x10030, 0x000605DB}, + {0x10030, 0x000609D5}, + {0x10030, 0x00060D9B}, + {0x10030, 0x00061195}, + {0x10030, 0x0006155B}, + {0x10030, 0x00061957}, + {0x10030, 0x00061D1F}, + {0x10030, 0x00062119}, + {0x10030, 0x000624DF}, + {0x10030, 0x000628D9}, + {0x10030, 0x00062C9F}, + {0x10030, 0x00063099}, + {0x10030, 0x0006345F}, + {0x10030, 0x00063859}, + {0x10030, 0x00063C1F}, + {0x10030, 0x00064019}, + {0x10030, 0x00064413}, + {0x10030, 0x000681E1}, + {0x10030, 0x000685DB}, + {0x10030, 0x000689D5}, + {0x10030, 0x00068D9B}, + {0x10030, 0x00069195}, + {0x10030, 0x0006955B}, + {0x10030, 0x00069957}, + {0x10030, 0x00069D1F}, + {0x10030, 0x0006A119}, + {0x10030, 0x0006A4DF}, + {0x10030, 0x0006A8D9}, + {0x10030, 0x0006AC9F}, + {0x10030, 0x0006B099}, + {0x10030, 0x0006B45F}, + {0x10030, 0x0006B859}, + {0x10030, 0x0006BC1F}, + {0x10030, 0x0006C019}, + {0x10030, 0x0006C413}, + {0x10030, 0x000701E1}, + {0x10030, 0x000705DB}, + {0x10030, 0x000709D5}, + {0x10030, 0x00070D9B}, + {0x10030, 0x00071195}, + {0x10030, 0x0007155B}, + {0x10030, 0x00071957}, + {0x10030, 0x00071D1F}, + {0x10030, 0x00072119}, + {0x10030, 0x000724DF}, + {0x10030, 0x000728D9}, + {0x10030, 0x00072C9F}, + {0x10030, 0x00073099}, + {0x10030, 0x0007345F}, + {0x10030, 0x00073859}, + {0x10030, 0x00073C1F}, + {0x10030, 0x00074019}, + {0x10030, 0x00074413}, + {0x10030, 0x000781DF}, + {0x10030, 0x000785D9}, + {0x10030, 0x000789D3}, + {0x10030, 0x00078D99}, + {0x10030, 0x00079193}, + {0x10030, 0x0007955F}, + {0x10030, 0x00079959}, + {0x10030, 0x00079D21}, + {0x10030, 0x0007A115}, + {0x10030, 0x0007A4DF}, + {0x10030, 0x0007A8D9}, + {0x10030, 0x0007AC9F}, + {0x10030, 0x0007B099}, + {0x10030, 0x0007B45F}, + {0x10030, 0x0007B859}, + {0x10030, 0x0007BC1F}, + {0x10030, 0x0007C019}, + {0x10030, 0x0007C413}, + {0x10030, 0x00000000}, + {0x10030, 0x000785A9}, + {0x10030, 0x000789A3}, + {0x10030, 0x00078D9D}, + {0x10030, 0x00079197}, + {0x10030, 0x00079591}, + {0x10030, 0x00079957}, + {0x10030, 0x00079D51}, + {0x10030, 0x0007A119}, + {0x10030, 0x0007A513}, + {0x10030, 0x0007A8D9}, + {0x10030, 0x0007ACD3}, + {0x10030, 0x0007B099}, + {0x10030, 0x0007B493}, + {0x10030, 0x0007B859}, + {0x10030, 0x0007BC53}, + {0x10030, 0x0007C019}, + {0x10030, 0x0007C413}, + {0x903f0001, 0x00000000}, {0x40000000, 0x00000000}, + {0x10030, 0x000201DF}, + {0x10030, 0x000205D9}, + {0x10030, 0x000209D3}, + {0x10030, 0x00020D99}, + {0x10030, 0x00021193}, + {0x10030, 0x0002155F}, + {0x10030, 0x00021959}, + {0x10030, 0x00021D21}, + {0x10030, 0x00022119}, + {0x10030, 0x000224DF}, + {0x10030, 0x000228D9}, + {0x10030, 0x00022C9F}, + {0x10030, 0x00023099}, + {0x10030, 0x0002345F}, + {0x10030, 0x00023859}, + {0x10030, 0x00023C1F}, + {0x10030, 0x00024019}, + {0x10030, 0x00024413}, + {0x10030, 0x000281CD}, + {0x10030, 0x000285DB}, + {0x10030, 0x000289D5}, + {0x10030, 0x00028D9B}, + {0x10030, 0x0002918D}, + {0x10030, 0x00029555}, + {0x10030, 0x00029957}, + {0x10030, 0x00029D1F}, + {0x10030, 0x0002A119}, + {0x10030, 0x0002A4DF}, + {0x10030, 0x0002A8D9}, + {0x10030, 0x0002AC9F}, + {0x10030, 0x0002B099}, + {0x10030, 0x0002B45F}, + {0x10030, 0x0002B859}, + {0x10030, 0x0002BC1F}, + {0x10030, 0x0002C019}, + {0x10030, 0x0002C413}, + {0x10030, 0x000301D9}, + {0x10030, 0x000305DB}, + {0x10030, 0x000309D5}, + {0x10030, 0x00030D9B}, + {0x10030, 0x00031195}, + {0x10030, 0x0003155D}, + {0x10030, 0x00031955}, + {0x10030, 0x00031D1D}, + {0x10030, 0x00032119}, + {0x10030, 0x000324DF}, + {0x10030, 0x000328D9}, + {0x10030, 0x00032C9F}, + {0x10030, 0x00033099}, + {0x10030, 0x0003345F}, + {0x10030, 0x00033859}, + {0x10030, 0x00033C1F}, + {0x10030, 0x00034019}, + {0x10030, 0x00034413}, + {0x10030, 0x000601E1}, + {0x10030, 0x000605DB}, + {0x10030, 0x000609D5}, + {0x10030, 0x00060D9B}, + {0x10030, 0x00061195}, + {0x10030, 0x0006155B}, + {0x10030, 0x00061957}, + {0x10030, 0x00061D1F}, + {0x10030, 0x00062119}, + {0x10030, 0x000624DF}, + {0x10030, 0x000628D9}, + {0x10030, 0x00062C9F}, + {0x10030, 0x00063099}, + {0x10030, 0x0006345F}, + {0x10030, 0x00063859}, + {0x10030, 0x00063C1F}, + {0x10030, 0x00064019}, + {0x10030, 0x00064413}, + {0x10030, 0x000681E1}, + {0x10030, 0x000685DB}, + {0x10030, 0x000689D5}, + {0x10030, 0x00068D9B}, + {0x10030, 0x00069195}, + {0x10030, 0x0006955B}, + {0x10030, 0x00069957}, + {0x10030, 0x00069D1F}, + {0x10030, 0x0006A119}, + {0x10030, 0x0006A4DF}, + {0x10030, 0x0006A8D9}, + {0x10030, 0x0006AC9F}, + {0x10030, 0x0006B099}, + {0x10030, 0x0006B45F}, + {0x10030, 0x0006B859}, + {0x10030, 0x0006BC1F}, + {0x10030, 0x0006C019}, + {0x10030, 0x0006C413}, + {0x10030, 0x000701E1}, + {0x10030, 0x000705DB}, + {0x10030, 0x000709D5}, + {0x10030, 0x00070D9B}, + {0x10030, 0x00071195}, + {0x10030, 0x0007155B}, + {0x10030, 0x00071957}, + {0x10030, 0x00071D1F}, + {0x10030, 0x00072119}, + {0x10030, 0x000724DF}, + {0x10030, 0x000728D9}, + {0x10030, 0x00072C9F}, + {0x10030, 0x00073099}, + {0x10030, 0x0007345F}, + {0x10030, 0x00073859}, + {0x10030, 0x00073C1F}, + {0x10030, 0x00074019}, + {0x10030, 0x00074413}, + {0x10030, 0x000781DF}, + {0x10030, 0x000785D9}, + {0x10030, 0x000789D3}, + {0x10030, 0x00078D99}, + {0x10030, 0x00079193}, + {0x10030, 0x0007955F}, + {0x10030, 0x00079959}, + {0x10030, 0x00079D21}, + {0x10030, 0x0007A115}, + {0x10030, 0x0007A4DF}, + {0x10030, 0x0007A8D9}, + {0x10030, 0x0007AC9F}, + {0x10030, 0x0007B099}, + {0x10030, 0x0007B45F}, + {0x10030, 0x0007B859}, + {0x10030, 0x0007BC1F}, + {0x10030, 0x0007C019}, + {0x10030, 0x0007C413}, + {0x10030, 0x00000000}, + {0x10030, 0x000785A9}, + {0x10030, 0x000789A3}, + {0x10030, 0x00078D9D}, + {0x10030, 0x00079197}, + {0x10030, 0x00079591}, + {0x10030, 0x00079957}, + {0x10030, 0x00079D51}, + {0x10030, 0x0007A119}, + {0x10030, 0x0007A513}, + {0x10030, 0x0007A8D9}, + {0x10030, 0x0007ACD3}, + {0x10030, 0x0007B099}, + {0x10030, 0x0007B493}, + {0x10030, 0x0007B859}, + {0x10030, 0x0007BC53}, + {0x10030, 0x0007C019}, + {0x10030, 0x0007C413}, + {0x90400001, 0x00000000}, {0x40000000, 0x00000000}, + {0x10030, 0x000201DF}, + {0x10030, 0x000205D9}, + {0x10030, 0x000209D3}, + {0x10030, 0x00020D99}, + {0x10030, 0x00021193}, + {0x10030, 0x0002155F}, + {0x10030, 0x00021959}, + {0x10030, 0x00021D21}, + {0x10030, 0x00022119}, + {0x10030, 0x000224DF}, + {0x10030, 0x000228D9}, + {0x10030, 0x00022C9F}, + {0x10030, 0x00023099}, + {0x10030, 0x0002345F}, + {0x10030, 0x00023859}, + {0x10030, 0x00023C1F}, + {0x10030, 0x00024019}, + {0x10030, 0x00024413}, + {0x10030, 0x000281CD}, + {0x10030, 0x000285DB}, + {0x10030, 0x000289D5}, + {0x10030, 0x00028D9B}, + {0x10030, 0x0002918D}, + {0x10030, 0x00029555}, + {0x10030, 0x00029957}, + {0x10030, 0x00029D1F}, + {0x10030, 0x0002A119}, + {0x10030, 0x0002A4DF}, + {0x10030, 0x0002A8D9}, + {0x10030, 0x0002AC9F}, + {0x10030, 0x0002B099}, + {0x10030, 0x0002B45F}, + {0x10030, 0x0002B859}, + {0x10030, 0x0002BC1F}, + {0x10030, 0x0002C019}, + {0x10030, 0x0002C413}, + {0x10030, 0x000301D9}, + {0x10030, 0x000305DB}, + {0x10030, 0x000309D5}, + {0x10030, 0x00030D9B}, + {0x10030, 0x00031195}, + {0x10030, 0x0003155D}, + {0x10030, 0x00031955}, + {0x10030, 0x00031D1D}, + {0x10030, 0x00032119}, + {0x10030, 0x000324DF}, + {0x10030, 0x000328D9}, + {0x10030, 0x00032C9F}, + {0x10030, 0x00033099}, + {0x10030, 0x0003345F}, + {0x10030, 0x00033859}, + {0x10030, 0x00033C1F}, + {0x10030, 0x00034019}, + {0x10030, 0x00034413}, + {0x10030, 0x000601E1}, + {0x10030, 0x000605DB}, + {0x10030, 0x000609D5}, + {0x10030, 0x00060D9B}, + {0x10030, 0x00061195}, + {0x10030, 0x0006155B}, + {0x10030, 0x00061957}, + {0x10030, 0x00061D1F}, + {0x10030, 0x00062119}, + {0x10030, 0x000624DF}, + {0x10030, 0x000628D9}, + {0x10030, 0x00062C9F}, + {0x10030, 0x00063099}, + {0x10030, 0x0006345F}, + {0x10030, 0x00063859}, + {0x10030, 0x00063C1F}, + {0x10030, 0x00064019}, + {0x10030, 0x00064413}, + {0x10030, 0x000681E1}, + {0x10030, 0x000685DB}, + {0x10030, 0x000689D5}, + {0x10030, 0x00068D9B}, + {0x10030, 0x00069195}, + {0x10030, 0x0006955B}, + {0x10030, 0x00069957}, + {0x10030, 0x00069D1F}, + {0x10030, 0x0006A119}, + {0x10030, 0x0006A4DF}, + {0x10030, 0x0006A8D9}, + {0x10030, 0x0006AC9F}, + {0x10030, 0x0006B099}, + {0x10030, 0x0006B45F}, + {0x10030, 0x0006B859}, + {0x10030, 0x0006BC1F}, + {0x10030, 0x0006C019}, + {0x10030, 0x0006C413}, + {0x10030, 0x000701E1}, + {0x10030, 0x000705DB}, + {0x10030, 0x000709D5}, + {0x10030, 0x00070D9B}, + {0x10030, 0x00071195}, + {0x10030, 0x0007155B}, + {0x10030, 0x00071957}, + {0x10030, 0x00071D1F}, + {0x10030, 0x00072119}, + {0x10030, 0x000724DF}, + {0x10030, 0x000728D9}, + {0x10030, 0x00072C9F}, + {0x10030, 0x00073099}, + {0x10030, 0x0007345F}, + {0x10030, 0x00073859}, + {0x10030, 0x00073C1F}, + {0x10030, 0x00074019}, + {0x10030, 0x00074413}, + {0x10030, 0x000781DF}, + {0x10030, 0x000785D9}, + {0x10030, 0x000789D3}, + {0x10030, 0x00078D99}, + {0x10030, 0x00079193}, + {0x10030, 0x0007955F}, + {0x10030, 0x00079959}, + {0x10030, 0x00079D21}, + {0x10030, 0x0007A115}, + {0x10030, 0x0007A4DF}, + {0x10030, 0x0007A8D9}, + {0x10030, 0x0007AC9F}, + {0x10030, 0x0007B099}, + {0x10030, 0x0007B45F}, + {0x10030, 0x0007B859}, + {0x10030, 0x0007BC1F}, + {0x10030, 0x0007C019}, + {0x10030, 0x0007C413}, + {0x10030, 0x00000000}, + {0x10030, 0x000785A9}, + {0x10030, 0x000789A3}, + {0x10030, 0x00078D9D}, + {0x10030, 0x00079197}, + {0x10030, 0x00079591}, + {0x10030, 0x00079957}, + {0x10030, 0x00079D51}, + {0x10030, 0x0007A119}, + {0x10030, 0x0007A513}, + {0x10030, 0x0007A8D9}, + {0x10030, 0x0007ACD3}, + {0x10030, 0x0007B099}, + {0x10030, 0x0007B493}, + {0x10030, 0x0007B859}, + {0x10030, 0x0007BC53}, + {0x10030, 0x0007C019}, + {0x10030, 0x0007C413}, + {0xA0000000, 0x00000000}, + {0x10030, 0x000001EF}, + {0x10030, 0x000005E9}, + {0x10030, 0x000009E3}, + {0x10030, 0x00000DDD}, + {0x10030, 0x000011D7}, + {0x10030, 0x0000159F}, + {0x10030, 0x00001999}, + {0x10030, 0x00001D5F}, + {0x10030, 0x00002159}, + {0x10030, 0x0000251F}, + {0x10030, 0x00002919}, + {0x10030, 0x00002CDF}, + {0x10030, 0x000030D9}, + {0x10030, 0x0000349F}, + {0x10030, 0x00003899}, + {0x10030, 0x00003C5F}, + {0x10030, 0x00004059}, + {0x10030, 0x00004453}, + {0x10030, 0x000201ED}, + {0x10030, 0x000205AD}, + {0x10030, 0x000209A7}, + {0x10030, 0x00020DA1}, + {0x10030, 0x0002119B}, + {0x10030, 0x00021561}, + {0x10030, 0x0002195B}, + {0x10030, 0x00021D27}, + {0x10030, 0x00022121}, + {0x10030, 0x000224E9}, + {0x10030, 0x000228E3}, + {0x10030, 0x00022CA9}, + {0x10030, 0x000230A3}, + {0x10030, 0x00023469}, + {0x10030, 0x00023863}, + {0x10030, 0x00023C29}, + {0x10030, 0x00024023}, + {0x10030, 0x0002441D}, + {0x10030, 0x000281EF}, + {0x10030, 0x000285AF}, + {0x10030, 0x000289A9}, + {0x10030, 0x00028DA3}, + {0x10030, 0x0002919D}, + {0x10030, 0x00029563}, + {0x10030, 0x0002995D}, + {0x10030, 0x00029D25}, + {0x10030, 0x0002A11F}, + {0x10030, 0x0002A4E7}, + {0x10030, 0x0002A8E1}, + {0x10030, 0x0002ACA7}, + {0x10030, 0x0002B0A1}, + {0x10030, 0x0002B467}, + {0x10030, 0x0002B861}, + {0x10030, 0x0002BC27}, + {0x10030, 0x0002C021}, + {0x10030, 0x0002C41B}, + {0x10030, 0x000301EF}, + {0x10030, 0x000305AF}, + {0x10030, 0x000309A9}, + {0x10030, 0x00030DA3}, + {0x10030, 0x0003119D}, + {0x10030, 0x00031563}, + {0x10030, 0x0003195D}, + {0x10030, 0x00031D25}, + {0x10030, 0x0003211F}, + {0x10030, 0x000324E7}, + {0x10030, 0x000328E1}, + {0x10030, 0x00032CA7}, + {0x10030, 0x000330A1}, + {0x10030, 0x00033467}, + {0x10030, 0x00033861}, + {0x10030, 0x00033C27}, + {0x10030, 0x00034021}, + {0x10030, 0x0003441B}, + {0x10030, 0x000601EB}, + {0x10030, 0x000605AB}, + {0x10030, 0x000609A5}, + {0x10030, 0x00060D9F}, + {0x10030, 0x00061199}, + {0x10030, 0x00061593}, + {0x10030, 0x00061959}, + {0x10030, 0x00061D53}, + {0x10030, 0x0006211B}, + {0x10030, 0x00062515}, + {0x10030, 0x000628DD}, + {0x10030, 0x00062CD7}, + {0x10030, 0x0006309D}, + {0x10030, 0x00063497}, + {0x10030, 0x0006385D}, + {0x10030, 0x00063C57}, + {0x10030, 0x0006401D}, + {0x10030, 0x00064417}, + {0x10030, 0x000681E7}, + {0x10030, 0x000685A7}, + {0x10030, 0x000689A1}, + {0x10030, 0x00068D9B}, + {0x10030, 0x00069195}, + {0x10030, 0x0006955F}, + {0x10030, 0x00069959}, + {0x10030, 0x00069D21}, + {0x10030, 0x0006A11B}, + {0x10030, 0x0006A4E3}, + {0x10030, 0x0006A8DD}, + {0x10030, 0x0006ACA5}, + {0x10030, 0x0006B09F}, + {0x10030, 0x0006B465}, + {0x10030, 0x0006B85F}, + {0x10030, 0x0006BC25}, + {0x10030, 0x0006C01F}, + {0x10030, 0x0006C419}, + {0x10030, 0x000701E7}, + {0x10030, 0x000705A7}, + {0x10030, 0x000709A1}, + {0x10030, 0x00070D9B}, + {0x10030, 0x00071195}, + {0x10030, 0x0007155B}, + {0x10030, 0x00071955}, + {0x10030, 0x00071D1D}, + {0x10030, 0x00072117}, + {0x10030, 0x000724DF}, + {0x10030, 0x000728D9}, + {0x10030, 0x00072CA1}, + {0x10030, 0x0007309B}, + {0x10030, 0x00073461}, + {0x10030, 0x0007385B}, + {0x10030, 0x00073C21}, + {0x10030, 0x0007401B}, + {0x10030, 0x0007441B}, + {0x10030, 0x000781E9}, + {0x10030, 0x000785A9}, + {0x10030, 0x000789A3}, + {0x10030, 0x00078D9D}, + {0x10030, 0x00079197}, + {0x10030, 0x00079591}, + {0x10030, 0x00079957}, + {0x10030, 0x00079D51}, + {0x10030, 0x0007A119}, + {0x10030, 0x0007A513}, + {0x10030, 0x0007A8D9}, + {0x10030, 0x0007ACD3}, + {0x10030, 0x0007B099}, + {0x10030, 0x0007B493}, + {0x10030, 0x0007B859}, + {0x10030, 0x0007BC53}, + {0x10030, 0x0007C019}, + {0x10030, 0x0007C413}, + {0xB0000000, 0x00000000}, + {0x100EE, 0x00000000}, + {0x100EE, 0x00002000}, + {0x10030, 0x000000FC}, + {0x10030, 0x000004F9}, + {0x10030, 0x000008F6}, + {0x10030, 0x00000CF3}, + {0x10030, 0x000010F0}, + {0x10030, 0x000014ED}, + {0x10030, 0x000018AC}, + {0x10030, 0x00001CA9}, + {0x10030, 0x00002069}, + {0x10030, 0x00002466}, + {0x10030, 0x00002829}, + {0x10030, 0x00002C26}, + {0x10030, 0x00003023}, + {0x10030, 0x00003420}, + {0x10030, 0x0000381D}, + {0x10030, 0x00003C1A}, + {0x10030, 0x00004017}, + {0x100EE, 0x00000000}, + {0x100EE, 0x00002000}, + {0x10030, 0x000780F4}, + {0x10030, 0x000784F1}, + {0x10030, 0x000788EE}, + {0x10030, 0x00078CEB}, + {0x10030, 0x000790E8}, + {0x10030, 0x000794E5}, + {0x10030, 0x000798E2}, + {0x10030, 0x00079CDF}, + {0x10030, 0x0007A0DC}, + {0x10030, 0x0007A4D9}, + {0x10030, 0x0007A8D6}, + {0x10030, 0x0007ACD3}, + {0x10030, 0x0007B0D0}, + {0x10030, 0x0007B4CD}, + {0x10030, 0x0007B8CA}, + {0x10030, 0x0007BC07}, + {0x10030, 0x0007C004}, + {0x100EE, 0x00000000}, + {0x0EF, 0x00002000}, + {0x033, 0x00000008}, + {0x03F, 0x00000004}, + {0x033, 0x00000009}, + {0x03F, 0x00000003}, + {0x033, 0x0000000A}, + {0x03F, 0x00000003}, + {0x033, 0x0000000B}, + {0x03F, 0x00000002}, + {0x033, 0x0000000C}, + {0x03F, 0x00000002}, + {0x033, 0x0000000D}, + {0x03F, 0x00000002}, + {0x033, 0x0000000E}, + {0x03F, 0x00000002}, + {0x033, 0x0000000F}, + {0x03F, 0x00000002}, + {0x0EF, 0x00000000}, + {0x0EB, 0x00040000}, + {0x030, 0x000109B7}, + {0x0EB, 0x00000000}, + {0x0EF, 0x00008000}, + {0x033, 0x00000020}, + {0x03F, 0x00050002}, + {0x033, 0x00000021}, + {0x03F, 0x00060032}, + {0x033, 0x00000022}, + {0x03F, 0x00050042}, + {0x033, 0x00000023}, + {0x03F, 0x00040042}, + {0x033, 0x00000024}, + {0x03F, 0x00008001}, + {0x033, 0x00000025}, + {0x03F, 0x00008002}, + {0x033, 0x00000026}, + {0x03F, 0x00000003}, + {0x033, 0x00000027}, + {0x03F, 0x00000003}, + {0x033, 0x00000028}, + {0x03F, 0x00050002}, + {0x033, 0x00000029}, + {0x03F, 0x00060032}, + {0x033, 0x0000002A}, + {0x03F, 0x00050042}, + {0x033, 0x0000002B}, + {0x03F, 0x00040042}, + {0x033, 0x0000002C}, + {0x03F, 0x00008001}, + {0x033, 0x0000002D}, + {0x03F, 0x00008002}, + {0x033, 0x0000002E}, + {0x03F, 0x00000003}, + {0x033, 0x0000002F}, + {0x03F, 0x00000003}, + {0x033, 0x00000030}, + {0x03F, 0x00050002}, + {0x033, 0x00000031}, + {0x03F, 0x00060032}, + {0x033, 0x00000032}, + {0x03F, 0x00050042}, + {0x033, 0x00000033}, + {0x03F, 0x00040042}, + {0x033, 0x00000034}, + {0x03F, 0x00008001}, + {0x033, 0x00000035}, + {0x03F, 0x00008002}, + {0x033, 0x00000036}, + {0x03F, 0x00000003}, + {0x033, 0x00000037}, + {0x03F, 0x00000003}, + {0x033, 0x00000060}, + {0x03F, 0x00050002}, + {0x033, 0x00000061}, + {0x03F, 0x00060032}, + {0x033, 0x00000062}, + {0x03F, 0x00050042}, + {0x033, 0x00000063}, + {0x03F, 0x00040042}, + {0x033, 0x00000064}, + {0x03F, 0x00008001}, + {0x033, 0x00000065}, + {0x03F, 0x00008002}, + {0x033, 0x00000066}, + {0x03F, 0x00000003}, + {0x033, 0x00000067}, + {0x03F, 0x00000003}, + {0x033, 0x00000068}, + {0x03F, 0x00050002}, + {0x033, 0x00000069}, + {0x03F, 0x00060032}, + {0x033, 0x0000006A}, + {0x03F, 0x00050042}, + {0x033, 0x0000006B}, + {0x03F, 0x00040042}, + {0x033, 0x0000006C}, + {0x03F, 0x00008001}, + {0x033, 0x0000006D}, + {0x03F, 0x00008002}, + {0x033, 0x0000006E}, + {0x03F, 0x00000003}, + {0x033, 0x0000006F}, + {0x03F, 0x00000003}, + {0x033, 0x00000070}, + {0x03F, 0x00050002}, + {0x033, 0x00000071}, + {0x03F, 0x00060032}, + {0x033, 0x00000072}, + {0x03F, 0x00050042}, + {0x033, 0x00000073}, + {0x03F, 0x00040042}, + {0x033, 0x00000074}, + {0x03F, 0x00008001}, + {0x033, 0x00000075}, + {0x03F, 0x00008002}, + {0x033, 0x00000076}, + {0x03F, 0x00000003}, + {0x033, 0x00000077}, + {0x03F, 0x00000003}, + {0x033, 0x00000078}, + {0x03F, 0x00050002}, + {0x033, 0x00000079}, + {0x03F, 0x00060032}, + {0x033, 0x0000007A}, + {0x03F, 0x00050042}, + {0x033, 0x0000007B}, + {0x03F, 0x00040042}, + {0x033, 0x0000007C}, + {0x03F, 0x00008001}, + {0x033, 0x0000007D}, + {0x03F, 0x00008002}, + {0x033, 0x0000007E}, + {0x03F, 0x00000003}, + {0x033, 0x0000007F}, + {0x03F, 0x00000003}, + {0x033, 0x000000A0}, + {0x03F, 0x00050002}, + {0x033, 0x000000A1}, + {0x03F, 0x00060032}, + {0x033, 0x000000A2}, + {0x03F, 0x00050042}, + {0x033, 0x000000A3}, + {0x03F, 0x00040042}, + {0x033, 0x000000A4}, + {0x03F, 0x00008001}, + {0x033, 0x000000A5}, + {0x03F, 0x00008002}, + {0x033, 0x000000A6}, + {0x03F, 0x00000003}, + {0x033, 0x000000A7}, + {0x03F, 0x00000003}, + {0x033, 0x000000A8}, + {0x03F, 0x00050002}, + {0x033, 0x000000A9}, + {0x03F, 0x00060032}, + {0x033, 0x000000AA}, + {0x03F, 0x00050042}, + {0x033, 0x000000AB}, + {0x03F, 0x00040042}, + {0x033, 0x000000AC}, + {0x03F, 0x00008001}, + {0x033, 0x000000AD}, + {0x03F, 0x00008002}, + {0x033, 0x000000AE}, + {0x03F, 0x00000003}, + {0x033, 0x000000AF}, + {0x03F, 0x00000003}, + {0x033, 0x000000B0}, + {0x03F, 0x00050002}, + {0x033, 0x000000B1}, + {0x03F, 0x00060032}, + {0x033, 0x000000B2}, + {0x03F, 0x00050042}, + {0x033, 0x000000B3}, + {0x03F, 0x00040042}, + {0x033, 0x000000B4}, + {0x03F, 0x00008001}, + {0x033, 0x000000B5}, + {0x03F, 0x00008002}, + {0x033, 0x000000B6}, + {0x03F, 0x00000003}, + {0x033, 0x000000B7}, + {0x03F, 0x00000003}, + {0x033, 0x000000E0}, + {0x03F, 0x00050002}, + {0x033, 0x000000E1}, + {0x03F, 0x00060032}, + {0x033, 0x000000E2}, + {0x03F, 0x00050042}, + {0x033, 0x000000E3}, + {0x03F, 0x00040042}, + {0x033, 0x000000E4}, + {0x03F, 0x00008001}, + {0x033, 0x000000E5}, + {0x03F, 0x00008002}, + {0x033, 0x000000E6}, + {0x03F, 0x00000003}, + {0x033, 0x000000E7}, + {0x03F, 0x00000003}, + {0x033, 0x000000E8}, + {0x03F, 0x00050002}, + {0x033, 0x000000E9}, + {0x03F, 0x00060032}, + {0x033, 0x000000EA}, + {0x03F, 0x00050042}, + {0x033, 0x000000EB}, + {0x03F, 0x00040042}, + {0x033, 0x000000EC}, + {0x03F, 0x00008001}, + {0x033, 0x000000ED}, + {0x03F, 0x00008002}, + {0x033, 0x000000EE}, + {0x03F, 0x00000003}, + {0x033, 0x000000EF}, + {0x03F, 0x00000003}, + {0x033, 0x000000F0}, + {0x03F, 0x00050002}, + {0x033, 0x000000F1}, + {0x03F, 0x00060032}, + {0x033, 0x000000F2}, + {0x03F, 0x00050042}, + {0x033, 0x000000F3}, + {0x03F, 0x00040042}, + {0x033, 0x000000F4}, + {0x03F, 0x00008001}, + {0x033, 0x000000F5}, + {0x03F, 0x00008002}, + {0x033, 0x000000F6}, + {0x03F, 0x00000003}, + {0x033, 0x000000F7}, + {0x03F, 0x00000003}, + {0x033, 0x000000F8}, + {0x03F, 0x00050002}, + {0x033, 0x000000F9}, + {0x03F, 0x00060032}, + {0x033, 0x000000FA}, + {0x03F, 0x00050042}, + {0x033, 0x000000FB}, + {0x03F, 0x00040042}, + {0x033, 0x000000FC}, + {0x03F, 0x00008001}, + {0x033, 0x000000FD}, + {0x03F, 0x00008002}, + {0x033, 0x000000FE}, + {0x03F, 0x00000003}, + {0x033, 0x000000FF}, + {0x03F, 0x00000003}, + {0x033, 0x00000120}, + {0x03F, 0x00050002}, + {0x033, 0x00000121}, + {0x03F, 0x00060032}, + {0x033, 0x00000122}, + {0x03F, 0x00050042}, + {0x033, 0x00000123}, + {0x03F, 0x00040042}, + {0x033, 0x00000124}, + {0x03F, 0x00008001}, + {0x033, 0x00000125}, + {0x03F, 0x00008002}, + {0x033, 0x00000126}, + {0x03F, 0x00000003}, + {0x033, 0x00000127}, + {0x03F, 0x00000003}, + {0x033, 0x00000128}, + {0x03F, 0x00050002}, + {0x033, 0x00000129}, + {0x03F, 0x00060032}, + {0x033, 0x0000012A}, + {0x03F, 0x00050042}, + {0x033, 0x0000012B}, + {0x03F, 0x00040042}, + {0x033, 0x0000012C}, + {0x03F, 0x00008001}, + {0x033, 0x0000012D}, + {0x03F, 0x00008002}, + {0x033, 0x0000012E}, + {0x03F, 0x00000003}, + {0x033, 0x0000012F}, + {0x03F, 0x00000003}, + {0x033, 0x00000130}, + {0x03F, 0x00050002}, + {0x033, 0x00000131}, + {0x03F, 0x00060032}, + {0x033, 0x00000132}, + {0x03F, 0x00050042}, + {0x033, 0x00000133}, + {0x03F, 0x00040042}, + {0x033, 0x00000134}, + {0x03F, 0x00008001}, + {0x033, 0x00000135}, + {0x03F, 0x00008002}, + {0x033, 0x00000136}, + {0x03F, 0x00000003}, + {0x033, 0x00000137}, + {0x03F, 0x00000003}, + {0x033, 0x00000160}, + {0x03F, 0x00050002}, + {0x033, 0x00000161}, + {0x03F, 0x00060032}, + {0x033, 0x00000162}, + {0x03F, 0x00050042}, + {0x033, 0x00000163}, + {0x03F, 0x00040042}, + {0x033, 0x00000164}, + {0x03F, 0x00008001}, + {0x033, 0x00000165}, + {0x03F, 0x00008002}, + {0x033, 0x00000166}, + {0x03F, 0x00000003}, + {0x033, 0x00000167}, + {0x03F, 0x00000003}, + {0x033, 0x00000168}, + {0x03F, 0x00050002}, + {0x033, 0x00000169}, + {0x03F, 0x00060032}, + {0x033, 0x0000016A}, + {0x03F, 0x00050042}, + {0x033, 0x0000016B}, + {0x03F, 0x00040042}, + {0x033, 0x0000016C}, + {0x03F, 0x00008001}, + {0x033, 0x0000016D}, + {0x03F, 0x00008002}, + {0x033, 0x0000016E}, + {0x03F, 0x00000003}, + {0x033, 0x0000016F}, + {0x03F, 0x00000003}, + {0x033, 0x00000170}, + {0x03F, 0x00050002}, + {0x033, 0x00000171}, + {0x03F, 0x00060032}, + {0x033, 0x00000172}, + {0x03F, 0x00050042}, + {0x033, 0x00000173}, + {0x03F, 0x00040042}, + {0x033, 0x00000174}, + {0x03F, 0x00008001}, + {0x033, 0x00000175}, + {0x03F, 0x00008002}, + {0x033, 0x00000176}, + {0x03F, 0x00000003}, + {0x033, 0x00000177}, + {0x03F, 0x00000003}, + {0x033, 0x00000178}, + {0x03F, 0x00050002}, + {0x033, 0x00000179}, + {0x03F, 0x00060032}, + {0x033, 0x0000017A}, + {0x03F, 0x00050042}, + {0x033, 0x0000017B}, + {0x03F, 0x00040042}, + {0x033, 0x0000017C}, + {0x03F, 0x00008001}, + {0x033, 0x0000017D}, + {0x03F, 0x00008002}, + {0x033, 0x0000017E}, + {0x03F, 0x00000003}, + {0x033, 0x0000017F}, + {0x03F, 0x00000003}, + {0x033, 0x000001A0}, + {0x03F, 0x00050002}, + {0x033, 0x000001A1}, + {0x03F, 0x00060032}, + {0x033, 0x000001A2}, + {0x03F, 0x00050042}, + {0x033, 0x000001A3}, + {0x03F, 0x00040042}, + {0x033, 0x000001A4}, + {0x03F, 0x00008001}, + {0x033, 0x000001A5}, + {0x03F, 0x00008002}, + {0x033, 0x000001A6}, + {0x03F, 0x00000003}, + {0x033, 0x000001A7}, + {0x03F, 0x00000003}, + {0x033, 0x000001A8}, + {0x03F, 0x00050002}, + {0x033, 0x000001A9}, + {0x03F, 0x00060032}, + {0x033, 0x000001AA}, + {0x03F, 0x00050042}, + {0x033, 0x000001AB}, + {0x03F, 0x00040042}, + {0x033, 0x000001AC}, + {0x03F, 0x00008001}, + {0x033, 0x000001AD}, + {0x03F, 0x00008002}, + {0x033, 0x000001AE}, + {0x03F, 0x00000003}, + {0x033, 0x000001AF}, + {0x03F, 0x00000003}, + {0x033, 0x000001B0}, + {0x03F, 0x00050002}, + {0x033, 0x000001B1}, + {0x03F, 0x00060032}, + {0x033, 0x000001B2}, + {0x03F, 0x00050042}, + {0x033, 0x000001B3}, + {0x03F, 0x00040042}, + {0x033, 0x000001B4}, + {0x03F, 0x00008001}, + {0x033, 0x000001B5}, + {0x03F, 0x00008002}, + {0x033, 0x000001B6}, + {0x03F, 0x00000003}, + {0x033, 0x000001B7}, + {0x03F, 0x00000003}, + {0x033, 0x000001E0}, + {0x03F, 0x00050002}, + {0x033, 0x000001E1}, + {0x03F, 0x00060032}, + {0x033, 0x000001E2}, + {0x03F, 0x00050042}, + {0x033, 0x000001E3}, + {0x03F, 0x00040042}, + {0x033, 0x000001E4}, + {0x03F, 0x00008001}, + {0x033, 0x000001E5}, + {0x03F, 0x00008002}, + {0x033, 0x000001E6}, + {0x03F, 0x00000003}, + {0x033, 0x000001E7}, + {0x03F, 0x00000003}, + {0x033, 0x000001E8}, + {0x03F, 0x00050002}, + {0x033, 0x000001E9}, + {0x03F, 0x00060032}, + {0x033, 0x000001EA}, + {0x03F, 0x00050042}, + {0x033, 0x000001EB}, + {0x03F, 0x00040042}, + {0x033, 0x000001EC}, + {0x03F, 0x00008001}, + {0x033, 0x000001ED}, + {0x03F, 0x00008002}, + {0x033, 0x000001EE}, + {0x03F, 0x00000003}, + {0x033, 0x000001EF}, + {0x03F, 0x00000003}, + {0x033, 0x000001F0}, + {0x03F, 0x00050002}, + {0x033, 0x000001F1}, + {0x03F, 0x00060032}, + {0x033, 0x000001F2}, + {0x03F, 0x00050042}, + {0x033, 0x000001F3}, + {0x03F, 0x00040042}, + {0x033, 0x000001F4}, + {0x03F, 0x00008001}, + {0x033, 0x000001F5}, + {0x03F, 0x00008002}, + {0x033, 0x000001F6}, + {0x03F, 0x00000003}, + {0x033, 0x000001F7}, + {0x03F, 0x00000003}, + {0x033, 0x000001F8}, + {0x03F, 0x00050002}, + {0x033, 0x000001F9}, + {0x03F, 0x00060032}, + {0x033, 0x000001FA}, + {0x03F, 0x00050042}, + {0x033, 0x000001FB}, + {0x03F, 0x00040042}, + {0x033, 0x000001FC}, + {0x03F, 0x00008001}, + {0x033, 0x000001FD}, + {0x03F, 0x00008002}, + {0x033, 0x000001FE}, + {0x03F, 0x00000003}, + {0x033, 0x000001FF}, + {0x03F, 0x00000003}, + {0x0EF, 0x00000000}, + {0x005, 0x00000001}, + {0x10005, 0x00000001}, + {0x100EE, 0x00000400}, + {0x10030, 0x00000000}, + {0x10030, 0x00001000}, + {0x10030, 0x00002000}, + {0x10030, 0x00003000}, + {0x10030, 0x00004000}, + {0x10030, 0x00005000}, + {0x10030, 0x00006003}, + {0x10030, 0x00007003}, + {0x10030, 0x00008000}, + {0x10030, 0x00009000}, + {0x10030, 0x0000A000}, + {0x10030, 0x0000B000}, + {0x10030, 0x0000C000}, + {0x10030, 0x0000D000}, + {0x10030, 0x0000E003}, + {0x10030, 0x0000F003}, + {0x10030, 0x00010000}, + {0x10030, 0x00011000}, + {0x10030, 0x00012000}, + {0x10030, 0x00013000}, + {0x10030, 0x00014000}, + {0x10030, 0x00015000}, + {0x10030, 0x00016003}, + {0x10030, 0x00017003}, + {0x10030, 0x00018000}, + {0x10030, 0x00019000}, + {0x10030, 0x0001A000}, + {0x10030, 0x0001B000}, + {0x10030, 0x0001C000}, + {0x10030, 0x0001D000}, + {0x10030, 0x0001E003}, + {0x10030, 0x0001F003}, + {0x10030, 0x00020000}, + {0x10030, 0x00021000}, + {0x10030, 0x00022000}, + {0x10030, 0x00023000}, + {0x10030, 0x00024000}, + {0x10030, 0x00025000}, + {0x10030, 0x00026003}, + {0x10030, 0x00027003}, + {0x10030, 0x00028000}, + {0x10030, 0x00029000}, + {0x10030, 0x0002A000}, + {0x10030, 0x0002B000}, + {0x10030, 0x0002C000}, + {0x10030, 0x0002D000}, + {0x10030, 0x0002E003}, + {0x10030, 0x0002F003}, + {0x10030, 0x00030000}, + {0x10030, 0x00031000}, + {0x10030, 0x00032000}, + {0x10030, 0x00033000}, + {0x10030, 0x00034000}, + {0x10030, 0x00035000}, + {0x10030, 0x00036003}, + {0x10030, 0x00037003}, + {0x10030, 0x00038000}, + {0x10030, 0x00039000}, + {0x10030, 0x0003A000}, + {0x10030, 0x0003B000}, + {0x10030, 0x0003C000}, + {0x10030, 0x0003D000}, + {0x10030, 0x0003E003}, + {0x10030, 0x0003F003}, + {0x10030, 0x00060000}, + {0x10030, 0x00061000}, + {0x10030, 0x00062000}, + {0x10030, 0x00063000}, + {0x10030, 0x00064000}, + {0x10030, 0x00065000}, + {0x10030, 0x00066000}, + {0x10030, 0x00067003}, + {0x10030, 0x00068000}, + {0x10030, 0x00069000}, + {0x10030, 0x0006A000}, + {0x10030, 0x0006B000}, + {0x10030, 0x0006C000}, + {0x10030, 0x0006D000}, + {0x10030, 0x0006E000}, + {0x10030, 0x0006F003}, + {0x10030, 0x00070000}, + {0x10030, 0x00071000}, + {0x10030, 0x00072000}, + {0x10030, 0x00073000}, + {0x10030, 0x00074000}, + {0x10030, 0x00075000}, + {0x10030, 0x00076000}, + {0x10030, 0x00077003}, + {0x10030, 0x00078000}, + {0x10030, 0x00079000}, + {0x10030, 0x0007A000}, + {0x10030, 0x0007B000}, + {0x10030, 0x0007C000}, + {0x10030, 0x0007D000}, + {0x10030, 0x0007E000}, + {0x10030, 0x0007F003}, + {0x100EE, 0x00000000}, + {0x0FE, 0x00000031}, +}; + +static const struct rtw89_reg2_def rtw89_8852c_phy_radiob_regs[] = { + {0xF0010000, 0x00000000}, + {0xF0020000, 0x00000001}, + {0xF0320000, 0x00000002}, + {0xF0330000, 0x00000003}, + {0xF0340000, 0x00000004}, + {0xF0350000, 0x00000005}, + {0xF0360000, 0x00000006}, + {0xF0010001, 0x00000007}, + {0xF0020001, 0x00000008}, + {0xF0320001, 0x00000009}, + {0xF0330001, 0x0000000A}, + {0xF0340001, 0x0000000B}, + {0xF0350001, 0x0000000C}, + {0xF0360001, 0x0000000D}, + {0xF03F0001, 0x0000000E}, + {0xF0400001, 0x0000000F}, + {0x005, 0x00000000}, + {0x10005, 0x00000000}, + {0x0B9, 0x00020440}, + {0x000, 0x00030001}, + {0x10000, 0x00030000}, + {0x018, 0x00011124}, + {0x10018, 0x00011124}, + {0x05F, 0x00000032}, + {0x097, 0x00043200}, + {0x0A6, 0x00066DB7}, + {0x0EF, 0x00004000}, + {0x033, 0x00000005}, + {0x03E, 0x00000000}, + {0x03F, 0x00010500}, + {0x033, 0x00000003}, + {0x03E, 0x00000000}, + {0x03F, 0x00028B00}, + {0x033, 0x00000002}, + {0x03E, 0x00000000}, + {0x03F, 0x0009AB00}, + {0x033, 0x0000000D}, + {0x03E, 0x00000000}, + {0x03F, 0x00010500}, + {0x033, 0x0000000B}, + {0x03E, 0x00000000}, + {0x03F, 0x00028B00}, + {0x033, 0x0000000A}, + {0x03E, 0x00000000}, + {0x03F, 0x0009AB00}, + {0x033, 0x00000015}, + {0x03E, 0x00000000}, + {0x03F, 0x00010500}, + {0x033, 0x00000013}, + {0x03E, 0x00000000}, + {0x03F, 0x00028B00}, + {0x033, 0x00000012}, + {0x03E, 0x00000000}, + {0x03F, 0x0009AB00}, + {0x0EF, 0x00000000}, + {0x000, 0x00033C01}, + {0x10000, 0x00033C00}, + {0x01A, 0x00040004}, + {0x0FE, 0x00000000}, + {0x096, 0x00015200}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x067, 0x0004D000}, + {0x0DA, 0x000D4009}, + {0x90020000, 0x00000000}, {0x40000000, 0x00000000}, + {0x067, 0x0004D000}, + {0x0DA, 0x000D4009}, + {0x90320000, 0x00000000}, {0x40000000, 0x00000000}, + {0x067, 0x0004D000}, + {0x0DA, 0x000D4009}, + {0x90330000, 0x00000000}, {0x40000000, 0x00000000}, + {0x067, 0x0004D000}, + {0x0DA, 0x000D4009}, + {0x90340000, 0x00000000}, {0x40000000, 0x00000000}, + {0x067, 0x0004D000}, + {0x0DA, 0x000D4009}, + {0x90350000, 0x00000000}, {0x40000000, 0x00000000}, + {0x067, 0x0004D000}, + {0x0DA, 0x000D4009}, + {0x90360000, 0x00000000}, {0x40000000, 0x00000000}, + {0x067, 0x0004D000}, + {0x0DA, 0x000D4009}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x067, 0x0000D300}, + {0x0DA, 0x000D4000}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x067, 0x0000D300}, + {0x0DA, 0x000D4000}, + {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, + {0x067, 0x0000D300}, + {0x0DA, 0x000D4000}, + {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, + {0x067, 0x0000D300}, + {0x0DA, 0x000D4000}, + {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, + {0x067, 0x0000D300}, + {0x0DA, 0x000D4000}, + {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, + {0x067, 0x0000D300}, + {0x0DA, 0x000D4000}, + {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, + {0x067, 0x0000D300}, + {0x0DA, 0x000D4000}, + {0x903f0001, 0x00000000}, {0x40000000, 0x00000000}, + {0x067, 0x0000D300}, + {0x0DA, 0x000D4000}, + {0x90400001, 0x00000000}, {0x40000000, 0x00000000}, + {0x067, 0x0000D300}, + {0x0DA, 0x000D4000}, + {0xA0000000, 0x00000000}, + {0x067, 0x0004D000}, + {0x0DA, 0x000D4009}, + {0xB0000000, 0x00000000}, + {0x057, 0x0000D589}, + {0x05A, 0x0007FFFF}, + {0x043, 0x00005000}, + {0x018, 0x00001001}, + {0x10018, 0x00001001}, + {0x002, 0x0000000D}, + {0x10002, 0x0000000D}, + {0x0EE, 0x00000000}, + {0x033, 0x0000000B}, + {0x03F, 0x0000000B}, + {0x033, 0x0000000C}, + {0x03F, 0x00000012}, + {0x033, 0x0000000D}, + {0x03F, 0x00000019}, + {0x0EE, 0x00000000}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x08F, 0x000D1752}, + {0x90020000, 0x00000000}, {0x40000000, 0x00000000}, + {0x08F, 0x000D1752}, + {0x90320000, 0x00000000}, {0x40000000, 0x00000000}, + {0x08F, 0x000D1752}, + {0x90330000, 0x00000000}, {0x40000000, 0x00000000}, + {0x08F, 0x000D1752}, + {0x90340000, 0x00000000}, {0x40000000, 0x00000000}, + {0x08F, 0x000D1752}, + {0x90350000, 0x00000000}, {0x40000000, 0x00000000}, + {0x08F, 0x000D1752}, + {0x90360000, 0x00000000}, {0x40000000, 0x00000000}, + {0x08F, 0x000D1752}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x08F, 0x000D1352}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x08F, 0x000D1352}, + {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, + {0x08F, 0x000D1352}, + {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, + {0x08F, 0x000D1352}, + {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, + {0x08F, 0x000D1352}, + {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, + {0x08F, 0x000D1352}, + {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, + {0x08F, 0x000D1352}, + {0x903f0001, 0x00000000}, {0x40000000, 0x00000000}, + {0x08F, 0x000D1352}, + {0x90400001, 0x00000000}, {0x40000000, 0x00000000}, + {0x08F, 0x000D1352}, + {0xA0000000, 0x00000000}, + {0x08F, 0x000D1752}, + {0xB0000000, 0x00000000}, + {0x0EB, 0x00000000}, + {0x030, 0x000109B0}, + {0x030, 0x000189B0}, + {0x0EB, 0x00000000}, + {0x0EE, 0x00000010}, + {0x033, 0x00000006}, + {0x03F, 0x00000003}, + {0x033, 0x00000007}, + {0x03F, 0x00000003}, + {0x033, 0x00000008}, + {0x03F, 0x00000001}, + {0x0EE, 0x00000000}, + {0x0EF, 0x00001000}, + {0x033, 0x00000000}, + {0x03F, 0x00000015}, + {0x033, 0x00000001}, + {0x03F, 0x00000017}, + {0x0EF, 0x00000000}, + {0x0EF, 0x00008000}, + {0x033, 0x00000020}, + {0x03F, 0x00060001}, + {0x033, 0x00000021}, + {0x03F, 0x00060032}, + {0x033, 0x00000022}, + {0x03F, 0x00050042}, + {0x033, 0x00000023}, + {0x03F, 0x00040042}, + {0x033, 0x00000024}, + {0x03F, 0x00000001}, + {0x033, 0x00000025}, + {0x03F, 0x00000002}, + {0x033, 0x00000026}, + {0x03F, 0x00000003}, + {0x033, 0x00000027}, + {0x03F, 0x00000003}, + {0x033, 0x00000028}, + {0x03F, 0x00060001}, + {0x033, 0x00000029}, + {0x03F, 0x00060032}, + {0x033, 0x0000002A}, + {0x03F, 0x00050042}, + {0x033, 0x0000002B}, + {0x03F, 0x00040042}, + {0x033, 0x0000002C}, + {0x03F, 0x00000001}, + {0x033, 0x0000002D}, + {0x03F, 0x00000002}, + {0x033, 0x0000002E}, + {0x03F, 0x00000003}, + {0x033, 0x0000002F}, + {0x03F, 0x00000003}, + {0x033, 0x00000030}, + {0x03F, 0x00060001}, + {0x033, 0x00000031}, + {0x03F, 0x00060032}, + {0x033, 0x00000032}, + {0x03F, 0x00050042}, + {0x033, 0x00000033}, + {0x03F, 0x00040042}, + {0x033, 0x00000034}, + {0x03F, 0x00000001}, + {0x033, 0x00000035}, + {0x03F, 0x00000002}, + {0x033, 0x00000036}, + {0x03F, 0x00000003}, + {0x033, 0x00000037}, + {0x03F, 0x00000003}, + {0x033, 0x00000060}, + {0x03F, 0x00060001}, + {0x033, 0x00000061}, + {0x03F, 0x00060032}, + {0x033, 0x00000062}, + {0x03F, 0x00050042}, + {0x033, 0x00000063}, + {0x03F, 0x00040042}, + {0x033, 0x00000064}, + {0x03F, 0x00000001}, + {0x033, 0x00000065}, + {0x03F, 0x00000002}, + {0x033, 0x00000066}, + {0x03F, 0x00000003}, + {0x033, 0x00000067}, + {0x03F, 0x00000003}, + {0x033, 0x00000068}, + {0x03F, 0x00060001}, + {0x033, 0x00000069}, + {0x03F, 0x00060032}, + {0x033, 0x0000006A}, + {0x03F, 0x00050042}, + {0x033, 0x0000006B}, + {0x03F, 0x00040042}, + {0x033, 0x0000006C}, + {0x03F, 0x00000001}, + {0x033, 0x0000006D}, + {0x03F, 0x00000002}, + {0x033, 0x0000006E}, + {0x03F, 0x00000003}, + {0x033, 0x0000006F}, + {0x03F, 0x00000003}, + {0x033, 0x00000070}, + {0x03F, 0x00060001}, + {0x033, 0x00000071}, + {0x03F, 0x00060032}, + {0x033, 0x00000072}, + {0x03F, 0x00050042}, + {0x033, 0x00000073}, + {0x03F, 0x00040042}, + {0x033, 0x00000074}, + {0x03F, 0x00000001}, + {0x033, 0x00000075}, + {0x03F, 0x00000002}, + {0x033, 0x00000076}, + {0x03F, 0x00000003}, + {0x033, 0x00000077}, + {0x03F, 0x00000003}, + {0x033, 0x00000078}, + {0x03F, 0x00060001}, + {0x033, 0x00000079}, + {0x03F, 0x00060032}, + {0x033, 0x0000007A}, + {0x03F, 0x00050042}, + {0x033, 0x0000007B}, + {0x03F, 0x00040042}, + {0x033, 0x0000007C}, + {0x03F, 0x00000001}, + {0x033, 0x0000007D}, + {0x03F, 0x00000002}, + {0x033, 0x0000007E}, + {0x03F, 0x00000003}, + {0x033, 0x0000007F}, + {0x03F, 0x00000003}, + {0x033, 0x000000A0}, + {0x03F, 0x00060001}, + {0x033, 0x000000A1}, + {0x03F, 0x00060032}, + {0x033, 0x000000A2}, + {0x03F, 0x00050042}, + {0x033, 0x000000A3}, + {0x03F, 0x00040042}, + {0x033, 0x000000A4}, + {0x03F, 0x00000001}, + {0x033, 0x000000A5}, + {0x03F, 0x00000002}, + {0x033, 0x000000A6}, + {0x03F, 0x00000003}, + {0x033, 0x000000A7}, + {0x03F, 0x00000003}, + {0x033, 0x000000A8}, + {0x03F, 0x00060001}, + {0x033, 0x000000A9}, + {0x03F, 0x00060032}, + {0x033, 0x000000AA}, + {0x03F, 0x00050042}, + {0x033, 0x000000AB}, + {0x03F, 0x00040042}, + {0x033, 0x000000AC}, + {0x03F, 0x00000001}, + {0x033, 0x000000AD}, + {0x03F, 0x00000002}, + {0x033, 0x000000AE}, + {0x03F, 0x00000003}, + {0x033, 0x000000AF}, + {0x03F, 0x00000003}, + {0x033, 0x000000B0}, + {0x03F, 0x00060001}, + {0x033, 0x000000B1}, + {0x03F, 0x00060032}, + {0x033, 0x000000B2}, + {0x03F, 0x00050042}, + {0x033, 0x000000B3}, + {0x03F, 0x00040042}, + {0x033, 0x000000B4}, + {0x03F, 0x00000001}, + {0x033, 0x000000B5}, + {0x03F, 0x00000002}, + {0x033, 0x000000B6}, + {0x03F, 0x00000003}, + {0x033, 0x000000B7}, + {0x03F, 0x00000003}, + {0x033, 0x000000E0}, + {0x03F, 0x00060001}, + {0x033, 0x000000E1}, + {0x03F, 0x00060032}, + {0x033, 0x000000E2}, + {0x03F, 0x00050042}, + {0x033, 0x000000E3}, + {0x03F, 0x00040042}, + {0x033, 0x000000E4}, + {0x03F, 0x00000001}, + {0x033, 0x000000E5}, + {0x03F, 0x00000002}, + {0x033, 0x000000E6}, + {0x03F, 0x00000003}, + {0x033, 0x000000E7}, + {0x03F, 0x00000003}, + {0x033, 0x000000E8}, + {0x03F, 0x00060001}, + {0x033, 0x000000E9}, + {0x03F, 0x00060032}, + {0x033, 0x000000EA}, + {0x03F, 0x00050042}, + {0x033, 0x000000EB}, + {0x03F, 0x00040042}, + {0x033, 0x000000EC}, + {0x03F, 0x00000001}, + {0x033, 0x000000ED}, + {0x03F, 0x00000002}, + {0x033, 0x000000EE}, + {0x03F, 0x00000003}, + {0x033, 0x000000EF}, + {0x03F, 0x00000003}, + {0x033, 0x000000F0}, + {0x03F, 0x00060001}, + {0x033, 0x000000F1}, + {0x03F, 0x00060032}, + {0x033, 0x000000F2}, + {0x03F, 0x00050042}, + {0x033, 0x000000F3}, + {0x03F, 0x00040042}, + {0x033, 0x000000F4}, + {0x03F, 0x00000001}, + {0x033, 0x000000F5}, + {0x03F, 0x00000002}, + {0x033, 0x000000F6}, + {0x03F, 0x00000003}, + {0x033, 0x000000F7}, + {0x03F, 0x00000003}, + {0x033, 0x000000F8}, + {0x03F, 0x00060001}, + {0x033, 0x000000F9}, + {0x03F, 0x00060032}, + {0x033, 0x000000FA}, + {0x03F, 0x00050042}, + {0x033, 0x000000FB}, + {0x03F, 0x00040042}, + {0x033, 0x000000FC}, + {0x03F, 0x00000001}, + {0x033, 0x000000FD}, + {0x03F, 0x00000002}, + {0x033, 0x000000FE}, + {0x03F, 0x00000003}, + {0x033, 0x000000FF}, + {0x03F, 0x00000003}, + {0x033, 0x00000120}, + {0x03F, 0x00060001}, + {0x033, 0x00000121}, + {0x03F, 0x00060032}, + {0x033, 0x00000122}, + {0x03F, 0x00050042}, + {0x033, 0x00000123}, + {0x03F, 0x00040042}, + {0x033, 0x00000124}, + {0x03F, 0x00000001}, + {0x033, 0x00000125}, + {0x03F, 0x00000002}, + {0x033, 0x00000126}, + {0x03F, 0x00000003}, + {0x033, 0x00000127}, + {0x03F, 0x00000003}, + {0x033, 0x00000128}, + {0x03F, 0x00060001}, + {0x033, 0x00000129}, + {0x03F, 0x00060032}, + {0x033, 0x0000012A}, + {0x03F, 0x00050042}, + {0x033, 0x0000012B}, + {0x03F, 0x00040042}, + {0x033, 0x0000012C}, + {0x03F, 0x00000001}, + {0x033, 0x0000012D}, + {0x03F, 0x00000002}, + {0x033, 0x0000012E}, + {0x03F, 0x00000003}, + {0x033, 0x0000012F}, + {0x03F, 0x00000003}, + {0x033, 0x00000130}, + {0x03F, 0x00060001}, + {0x033, 0x00000131}, + {0x03F, 0x00060032}, + {0x033, 0x00000132}, + {0x03F, 0x00050042}, + {0x033, 0x00000133}, + {0x03F, 0x00040042}, + {0x033, 0x00000134}, + {0x03F, 0x00000001}, + {0x033, 0x00000135}, + {0x03F, 0x00000002}, + {0x033, 0x00000136}, + {0x03F, 0x00000003}, + {0x033, 0x00000137}, + {0x03F, 0x00000003}, + {0x033, 0x00000160}, + {0x03F, 0x00060001}, + {0x033, 0x00000161}, + {0x03F, 0x00060032}, + {0x033, 0x00000162}, + {0x03F, 0x00050042}, + {0x033, 0x00000163}, + {0x03F, 0x00040042}, + {0x033, 0x00000164}, + {0x03F, 0x00000001}, + {0x033, 0x00000165}, + {0x03F, 0x00000002}, + {0x033, 0x00000166}, + {0x03F, 0x00000003}, + {0x033, 0x00000167}, + {0x03F, 0x00000003}, + {0x033, 0x00000168}, + {0x03F, 0x00060001}, + {0x033, 0x00000169}, + {0x03F, 0x00060032}, + {0x033, 0x0000016A}, + {0x03F, 0x00050042}, + {0x033, 0x0000016B}, + {0x03F, 0x00040042}, + {0x033, 0x0000016C}, + {0x03F, 0x00000001}, + {0x033, 0x0000016D}, + {0x03F, 0x00000002}, + {0x033, 0x0000016E}, + {0x03F, 0x00000003}, + {0x033, 0x0000016F}, + {0x03F, 0x00000003}, + {0x033, 0x00000170}, + {0x03F, 0x00060001}, + {0x033, 0x00000171}, + {0x03F, 0x00060032}, + {0x033, 0x00000172}, + {0x03F, 0x00050042}, + {0x033, 0x00000173}, + {0x03F, 0x00040042}, + {0x033, 0x00000174}, + {0x03F, 0x00000001}, + {0x033, 0x00000175}, + {0x03F, 0x00000002}, + {0x033, 0x00000176}, + {0x03F, 0x00000003}, + {0x033, 0x00000177}, + {0x03F, 0x00000003}, + {0x033, 0x00000178}, + {0x03F, 0x00060001}, + {0x033, 0x00000179}, + {0x03F, 0x00060032}, + {0x033, 0x0000017A}, + {0x03F, 0x00050042}, + {0x033, 0x0000017B}, + {0x03F, 0x00040042}, + {0x033, 0x0000017C}, + {0x03F, 0x00000001}, + {0x033, 0x0000017D}, + {0x03F, 0x00000002}, + {0x033, 0x0000017E}, + {0x03F, 0x00000003}, + {0x033, 0x0000017F}, + {0x03F, 0x00000003}, + {0x033, 0x000001A0}, + {0x03F, 0x00060001}, + {0x033, 0x000001A1}, + {0x03F, 0x00060032}, + {0x033, 0x000001A2}, + {0x03F, 0x00050042}, + {0x033, 0x000001A3}, + {0x03F, 0x00040042}, + {0x033, 0x000001A4}, + {0x03F, 0x00000001}, + {0x033, 0x000001A5}, + {0x03F, 0x00000002}, + {0x033, 0x000001A6}, + {0x03F, 0x00000003}, + {0x033, 0x000001A7}, + {0x03F, 0x00000003}, + {0x033, 0x000001A8}, + {0x03F, 0x00060001}, + {0x033, 0x000001A9}, + {0x03F, 0x00060032}, + {0x033, 0x000001AA}, + {0x03F, 0x00050042}, + {0x033, 0x000001AB}, + {0x03F, 0x00040042}, + {0x033, 0x000001AC}, + {0x03F, 0x00000001}, + {0x033, 0x000001AD}, + {0x03F, 0x00000002}, + {0x033, 0x000001AE}, + {0x03F, 0x00000003}, + {0x033, 0x000001AF}, + {0x03F, 0x00000003}, + {0x033, 0x000001B0}, + {0x03F, 0x00060001}, + {0x033, 0x000001B1}, + {0x03F, 0x00060032}, + {0x033, 0x000001B2}, + {0x03F, 0x00050042}, + {0x033, 0x000001B3}, + {0x03F, 0x00040042}, + {0x033, 0x000001B4}, + {0x03F, 0x00000001}, + {0x033, 0x000001B5}, + {0x03F, 0x00000002}, + {0x033, 0x000001B6}, + {0x03F, 0x00000003}, + {0x033, 0x000001B7}, + {0x03F, 0x00000003}, + {0x033, 0x000001E0}, + {0x03F, 0x00060001}, + {0x033, 0x000001E1}, + {0x03F, 0x00060032}, + {0x033, 0x000001E2}, + {0x03F, 0x00050042}, + {0x033, 0x000001E3}, + {0x03F, 0x00040042}, + {0x033, 0x000001E4}, + {0x03F, 0x00000001}, + {0x033, 0x000001E5}, + {0x03F, 0x00000002}, + {0x033, 0x000001E6}, + {0x03F, 0x00000003}, + {0x033, 0x000001E7}, + {0x03F, 0x00000003}, + {0x033, 0x000001E8}, + {0x03F, 0x00060001}, + {0x033, 0x000001E9}, + {0x03F, 0x00060032}, + {0x033, 0x000001EA}, + {0x03F, 0x00050042}, + {0x033, 0x000001EB}, + {0x03F, 0x00040042}, + {0x033, 0x000001EC}, + {0x03F, 0x00000001}, + {0x033, 0x000001ED}, + {0x03F, 0x00000002}, + {0x033, 0x000001EE}, + {0x03F, 0x00000003}, + {0x033, 0x000001EF}, + {0x03F, 0x00000003}, + {0x033, 0x000001F0}, + {0x03F, 0x00060001}, + {0x033, 0x000001F1}, + {0x03F, 0x00060032}, + {0x033, 0x000001F2}, + {0x03F, 0x00050042}, + {0x033, 0x000001F3}, + {0x03F, 0x00040042}, + {0x033, 0x000001F4}, + {0x03F, 0x00000001}, + {0x033, 0x000001F5}, + {0x03F, 0x00000002}, + {0x033, 0x000001F6}, + {0x03F, 0x00000003}, + {0x033, 0x000001F7}, + {0x03F, 0x00000003}, + {0x033, 0x000001F8}, + {0x03F, 0x00060001}, + {0x033, 0x000001F9}, + {0x03F, 0x00060032}, + {0x033, 0x000001FA}, + {0x03F, 0x00050042}, + {0x033, 0x000001FB}, + {0x03F, 0x00040042}, + {0x033, 0x000001FC}, + {0x03F, 0x00000001}, + {0x033, 0x000001FD}, + {0x03F, 0x00000002}, + {0x033, 0x000001FE}, + {0x03F, 0x00000003}, + {0x033, 0x000001FF}, + {0x03F, 0x00000003}, + {0x0EF, 0x00000000}, + {0x0EF, 0x00000100}, + {0x033, 0x00000001}, + {0x03F, 0x0000EFFF}, + {0x033, 0x00000002}, + {0x03F, 0x0000EFFF}, + {0x033, 0x00000003}, + {0x03F, 0x0000EFFF}, + {0x033, 0x00000004}, + {0x03F, 0x0000EFFF}, + {0x033, 0x00000005}, + {0x03F, 0x0000EFFF}, + {0x033, 0x00000006}, + {0x03F, 0x0000EFFF}, + {0x033, 0x00000007}, + {0x03F, 0x0000EFFF}, + {0x033, 0x00000008}, + {0x03F, 0x0000EFFF}, + {0x033, 0x00000009}, + {0x03F, 0x0000EFFF}, + {0x033, 0x0000000A}, + {0x03F, 0x0000EFFF}, + {0x033, 0x0000000B}, + {0x03F, 0x0000AFFF}, + {0x033, 0x0000000C}, + {0x03F, 0x0000EFFF}, + {0x033, 0x0000000D}, + {0x03F, 0x0000EFFF}, + {0x033, 0x0000000E}, + {0x03F, 0x0000EFFF}, + {0x033, 0x0000000F}, + {0x03F, 0x0000EFFF}, + {0x033, 0x00000010}, + {0x03F, 0x0000EFFF}, + {0x033, 0x00000011}, + {0x03F, 0x0000EFFF}, + {0x033, 0x00000012}, + {0x03F, 0x0000EFFF}, + {0x033, 0x00000013}, + {0x03F, 0x0000EFFF}, + {0x033, 0x00000014}, + {0x03F, 0x0000EFFF}, + {0x033, 0x00000015}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000E3FF}, + {0x90020000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000E3FF}, + {0x90320000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000E3FF}, + {0x90330000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000E3FF}, + {0x90340000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000E3FF}, + {0x90350000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000E3FF}, + {0x90360000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000E3FF}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000EFFF}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000EFFF}, + {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000EFFF}, + {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000EFFF}, + {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000EFFF}, + {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000EFFF}, + {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000EFFF}, + {0x903f0001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000EFFF}, + {0x90400001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000EFFF}, + {0xA0000000, 0x00000000}, + {0x03F, 0x0000E3FF}, + {0xB0000000, 0x00000000}, + {0x033, 0x00000016}, + {0x03F, 0x0000EFFF}, + {0x033, 0x00000017}, + {0x03F, 0x0000EFFF}, + {0x033, 0x00000018}, + {0x03F, 0x0000FBFF}, + {0x033, 0x00000019}, + {0x03F, 0x0000EFFF}, + {0x033, 0x0000001A}, + {0x03F, 0x0000EFFF}, + {0x033, 0x0000001B}, + {0x03F, 0x0000EFFF}, + {0x033, 0x0000001C}, + {0x03F, 0x0000EFFF}, + {0x033, 0x0000001D}, + {0x03F, 0x0000EFFF}, + {0x033, 0x0000001E}, + {0x03F, 0x0000EFFF}, + {0x033, 0x0000001F}, + {0x03F, 0x0000EFFF}, + {0x033, 0x00000020}, + {0x03F, 0x0000EFFF}, + {0x033, 0x00000021}, + {0x03F, 0x0000EFFF}, + {0x033, 0x00000022}, + {0x03F, 0x0000EFFF}, + {0x033, 0x00000023}, + {0x03F, 0x0000EFFF}, + {0x033, 0x00000024}, + {0x03F, 0x0000EFFF}, + {0x033, 0x00000025}, + {0x03F, 0x0000EFFF}, + {0x033, 0x00000026}, + {0x03F, 0x0000EFFF}, + {0x033, 0x00000027}, + {0x03F, 0x0000EFFF}, + {0x033, 0x00000028}, + {0x03F, 0x0000EFFF}, + {0x033, 0x00000029}, + {0x03F, 0x0000EFFF}, + {0x033, 0x0000002A}, + {0x03F, 0x0000EFFF}, + {0x033, 0x0000002B}, + {0x03F, 0x0000EFFF}, + {0x033, 0x0000002C}, + {0x03F, 0x0000EFFF}, + {0x033, 0x0000002D}, + {0x03F, 0x0000EFFF}, + {0x033, 0x0000002E}, + {0x03F, 0x0000EFFF}, + {0x033, 0x0000002F}, + {0x03F, 0x0000EFFF}, + {0x033, 0x00000030}, + {0x03F, 0x0000EFFF}, + {0x033, 0x00000031}, + {0x03F, 0x0000EFFF}, + {0x033, 0x00000032}, + {0x03F, 0x0000EFFF}, + {0x033, 0x00000033}, + {0x03F, 0x0000EFFF}, + {0x033, 0x00000034}, + {0x03F, 0x0000EFFF}, + {0x033, 0x00000035}, + {0x03F, 0x0000EFFF}, + {0x033, 0x00000036}, + {0x03F, 0x0000EFFF}, + {0x033, 0x00000037}, + {0x03F, 0x0000EFFF}, + {0x033, 0x00000038}, + {0x03F, 0x0000EFFF}, + {0x033, 0x00000039}, + {0x03F, 0x0000EFFF}, + {0x033, 0x0000003A}, + {0x03F, 0x0000EFFF}, + {0x0EF, 0x00000000}, + {0x0EF, 0x00000040}, + {0x033, 0x00000000}, + {0x03F, 0x00004344}, + {0x033, 0x00000001}, + {0x03F, 0x00004344}, + {0x033, 0x00000002}, + {0x03F, 0x00004344}, + {0x033, 0x00000003}, + {0x03F, 0x00004344}, + {0x033, 0x00000004}, + {0x03F, 0x00004344}, + {0x033, 0x00000005}, + {0x03F, 0x00004344}, + {0x033, 0x00000006}, + {0x03F, 0x00004324}, + {0x033, 0x00000007}, + {0x03F, 0x00004344}, + {0x033, 0x00000008}, + {0x03F, 0x00004344}, + {0x033, 0x00000009}, + {0x03F, 0x00004344}, + {0x033, 0x0000000A}, + {0x03F, 0x00004344}, + {0x033, 0x0000000B}, + {0x03F, 0x00004344}, + {0x033, 0x00000010}, + {0x03F, 0x00004344}, + {0x033, 0x00000011}, + {0x03F, 0x00004344}, + {0x033, 0x00000012}, + {0x03F, 0x00004344}, + {0x033, 0x00000013}, + {0x03F, 0x00004344}, + {0x033, 0x00000014}, + {0x03F, 0x00004344}, + {0x033, 0x00000015}, + {0x03F, 0x00004344}, + {0x033, 0x00000016}, + {0x03F, 0x00004344}, + {0x033, 0x00000017}, + {0x03F, 0x00004344}, + {0x033, 0x00000018}, + {0x03F, 0x00004344}, + {0x033, 0x00000019}, + {0x03F, 0x00004344}, + {0x033, 0x0000001A}, + {0x03F, 0x00004344}, + {0x033, 0x0000001B}, + {0x03F, 0x00004344}, + {0x033, 0x0000001C}, + {0x03F, 0x00004344}, + {0x033, 0x0000001D}, + {0x03F, 0x00004344}, + {0x033, 0x0000001E}, + {0x03F, 0x00004344}, + {0x033, 0x0000001F}, + {0x03F, 0x00004344}, + {0x0EF, 0x00000000}, + {0x0EF, 0x00000020}, + {0x033, 0x00000010}, + {0x03F, 0x00000200}, + {0x033, 0x00000011}, + {0x03F, 0x00000200}, + {0x033, 0x00000012}, + {0x03F, 0x00000200}, + {0x033, 0x00000013}, + {0x03F, 0x00000200}, + {0x033, 0x00000020}, + {0x03F, 0x00000200}, + {0x033, 0x00000021}, + {0x03F, 0x00000200}, + {0x033, 0x00000022}, + {0x03F, 0x00000200}, + {0x033, 0x00000023}, + {0x03F, 0x00000200}, + {0x0EF, 0x00000000}, + {0x0EF, 0x00000010}, + {0x030, 0x000084DC}, + {0x030, 0x000103C9}, + {0x030, 0x00018399}, + {0x030, 0x00020287}, + {0x030, 0x00028277}, + {0x030, 0x00030165}, + {0x030, 0x00038144}, + {0x030, 0x00040044}, + {0x030, 0x00048022}, + {0x030, 0x00050011}, + {0x030, 0x00058000}, + {0x030, 0x00060000}, + {0x030, 0x00068000}, + {0x030, 0x00070000}, + {0x0EF, 0x00000000}, + {0x0EF, 0x00000080}, + {0x033, 0x00000004}, + {0x03E, 0x00000013}, + {0x03F, 0x00022A58}, + {0x033, 0x00000005}, + {0x03E, 0x00000013}, + {0x03F, 0x00022A58}, + {0x033, 0x00000006}, + {0x03E, 0x00000014}, + {0x03F, 0x00023958}, + {0x033, 0x00000007}, + {0x03E, 0x00000014}, + {0x03F, 0x00023A58}, + {0x033, 0x00000008}, + {0x03E, 0x00000013}, + {0x03F, 0x00022A58}, + {0x033, 0x00000009}, + {0x03E, 0x00000013}, + {0x03F, 0x00022A58}, + {0x033, 0x0000000A}, + {0x03E, 0x00000014}, + {0x03F, 0x00023958}, + {0x033, 0x0000000B}, + {0x03E, 0x00000014}, + {0x03F, 0x00023A58}, + {0x033, 0x0000000C}, + {0x03E, 0x00000013}, + {0x03F, 0x00022A58}, + {0x033, 0x0000000D}, + {0x03E, 0x00000013}, + {0x03F, 0x00022A58}, + {0x033, 0x0000000E}, + {0x03E, 0x00000014}, + {0x03F, 0x00023958}, + {0x033, 0x0000000F}, + {0x03E, 0x00000014}, + {0x03F, 0x00023A58}, + {0x033, 0x00000010}, + {0x03E, 0x00000013}, + {0x03F, 0x00022A58}, + {0x033, 0x00000011}, + {0x03E, 0x0000001B}, + {0x03F, 0x00022A58}, + {0x033, 0x00000012}, + {0x03E, 0x00000014}, + {0x03F, 0x00023958}, + {0x033, 0x00000013}, + {0x03E, 0x00000014}, + {0x03F, 0x00023A58}, + {0x033, 0x00000014}, + {0x03E, 0x00000013}, + {0x03F, 0x00022A58}, + {0x033, 0x00000015}, + {0x03E, 0x0000001B}, + {0x03F, 0x00029858}, + {0x033, 0x00000016}, + {0x03E, 0x0000001C}, + {0x03F, 0x00023958}, + {0x033, 0x00000017}, + {0x03E, 0x00000014}, + {0x03F, 0x00023A58}, + {0x033, 0x00000018}, + {0x03E, 0x00000013}, + {0x03F, 0x00029858}, + {0x033, 0x00000019}, + {0x03E, 0x0000001B}, + {0x03F, 0x00029858}, + {0x033, 0x0000001A}, + {0x03E, 0x00000014}, + {0x03F, 0x00023A58}, + {0x033, 0x0000001B}, + {0x03E, 0x00000014}, + {0x03F, 0x00023A58}, + {0x033, 0x0000001C}, + {0x03E, 0x00000014}, + {0x03F, 0x0002AC58}, + {0x033, 0x0000001D}, + {0x03E, 0x0000001B}, + {0x03F, 0x00029858}, + {0x033, 0x0000001E}, + {0x03E, 0x00000013}, + {0x03F, 0x00023A58}, + {0x033, 0x0000001F}, + {0x03E, 0x00000013}, + {0x03F, 0x00023A58}, + {0x033, 0x00000020}, + {0x03E, 0x00000014}, + {0x03F, 0x0002AC58}, + {0x033, 0x00000021}, + {0x03E, 0x0000001C}, + {0x03F, 0x0002AC58}, + {0x033, 0x00000022}, + {0x03E, 0x00000014}, + {0x03F, 0x00023A58}, + {0x033, 0x00000023}, + {0x03E, 0x00000014}, + {0x03F, 0x00023A58}, + {0x033, 0x00000024}, + {0x03E, 0x00000014}, + {0x03F, 0x0002AC58}, + {0x033, 0x00000025}, + {0x03E, 0x00000014}, + {0x03F, 0x0002AC58}, + {0x033, 0x00000026}, + {0x03E, 0x00000014}, + {0x03F, 0x00023A58}, + {0x033, 0x00000027}, + {0x03E, 0x00000014}, + {0x03F, 0x00023A58}, + {0x033, 0x00000028}, + {0x03E, 0x00000014}, + {0x03F, 0x0002AC58}, + {0x033, 0x00000029}, + {0x03E, 0x00000014}, + {0x03F, 0x0002AC58}, + {0x033, 0x0000002A}, + {0x03E, 0x00000014}, + {0x03F, 0x00023A58}, + {0x033, 0x0000002B}, + {0x03E, 0x00000014}, + {0x03F, 0x00023A58}, + {0x033, 0x0000002C}, + {0x03E, 0x00000014}, + {0x03F, 0x0002AC58}, + {0x033, 0x0000002D}, + {0x03E, 0x00000014}, + {0x03F, 0x0002AC58}, + {0x033, 0x0000002E}, + {0x03E, 0x00000014}, + {0x03F, 0x00023A58}, + {0x033, 0x0000002F}, + {0x03E, 0x00000014}, + {0x03F, 0x00023A58}, + {0x033, 0x00000030}, + {0x03E, 0x00000014}, + {0x03F, 0x0002AC58}, + {0x033, 0x00000031}, + {0x03E, 0x00000014}, + {0x03F, 0x0002AC58}, + {0x033, 0x00000032}, + {0x03E, 0x00000014}, + {0x03F, 0x00023A58}, + {0x033, 0x00000033}, + {0x03E, 0x00000014}, + {0x03F, 0x00023A58}, + {0x033, 0x00000034}, + {0x03E, 0x00000014}, + {0x03F, 0x0002AC58}, + {0x033, 0x00000035}, + {0x03E, 0x00000014}, + {0x03F, 0x0002AC58}, + {0x033, 0x00000036}, + {0x03E, 0x00000014}, + {0x03F, 0x00023A58}, + {0x033, 0x00000037}, + {0x03E, 0x00000014}, + {0x03F, 0x00023A58}, + {0x033, 0x00000038}, + {0x03E, 0x00000014}, + {0x03F, 0x0002AC58}, + {0x033, 0x00000039}, + {0x03E, 0x00000014}, + {0x03F, 0x0002AC58}, + {0x033, 0x0000003A}, + {0x03E, 0x00000014}, + {0x03F, 0x00023A58}, + {0x033, 0x0000003B}, + {0x03E, 0x00000014}, + {0x03F, 0x00023A58}, + {0x033, 0x0000003C}, + {0x03E, 0x00000014}, + {0x03F, 0x0002AC58}, + {0x033, 0x0000003D}, + {0x03E, 0x00000014}, + {0x03F, 0x0002AC58}, + {0x033, 0x0000003E}, + {0x03E, 0x00000014}, + {0x03F, 0x00023A58}, + {0x033, 0x0000003F}, + {0x03E, 0x00000014}, + {0x03F, 0x00023A58}, + {0x0EF, 0x00000000}, + {0x0EE, 0x00000800}, + {0x033, 0x00000000}, + {0x03F, 0x00000031}, + {0x033, 0x00000001}, + {0x03F, 0x00000023}, + {0x033, 0x00000002}, + {0x03F, 0x00000015}, + {0x033, 0x00000003}, + {0x03F, 0x00000007}, + {0x0EE, 0x00000000}, + {0x0EC, 0x00000400}, + {0x033, 0x00000003}, + {0x03F, 0x00000030}, + {0x033, 0x00000004}, + {0x03F, 0x00000021}, + {0x0EC, 0x00000000}, + {0x0DE, 0x00000000}, + {0x0EF, 0x00000000}, + {0x033, 0x00000000}, + {0x008, 0x00060280}, + {0x009, 0x00030400}, + {0x0EF, 0x00000000}, + {0x0A7, 0x00080308}, + {0x066, 0x00006000}, + {0x0EF, 0x00000400}, + {0x030, 0x000001FF}, + {0x030, 0x000081FF}, + {0x030, 0x000101FF}, + {0x030, 0x000181FF}, + {0x030, 0x000201FF}, + {0x030, 0x000281FF}, + {0x030, 0x0003017F}, + {0x030, 0x000380FB}, + {0x0EF, 0x00000000}, + {0x06E, 0x00077A18}, + {0x06D, 0x00000C31}, + {0x06A, 0x000E0F8A}, + {0x06B, 0x000018A0}, + {0x06F, 0x000F81FC}, + {0x05E, 0x0000001F}, + {0x0EF, 0x00000200}, + {0x030, 0x0003D407}, + {0x030, 0x00035A87}, + {0x030, 0x0002CF07}, + {0x030, 0x00024F07}, + {0x030, 0x0001CF07}, + {0x030, 0x00014F07}, + {0x030, 0x0000CF07}, + {0x030, 0x00004F07}, + {0x0EF, 0x00000000}, + {0x0EB, 0x00080000}, + {0x030, 0x00008038}, + {0x030, 0x00010038}, + {0x030, 0x00018038}, + {0x030, 0x00020038}, + {0x030, 0x00028038}, + {0x030, 0x00030038}, + {0x030, 0x0003803C}, + {0x030, 0x0004003C}, + {0x030, 0x0004803C}, + {0x030, 0x0005003C}, + {0x030, 0x0005803C}, + {0x030, 0x0006003C}, + {0x030, 0x0006803C}, + {0x030, 0x0007003C}, + {0x0EB, 0x00000000}, + {0x094, 0x000000FC}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x095, 0x00000000}, + {0x90020000, 0x00000000}, {0x40000000, 0x00000000}, + {0x095, 0x00000000}, + {0x90320000, 0x00000000}, {0x40000000, 0x00000000}, + {0x095, 0x00000000}, + {0x90330000, 0x00000000}, {0x40000000, 0x00000000}, + {0x095, 0x00000000}, + {0x90340000, 0x00000000}, {0x40000000, 0x00000000}, + {0x095, 0x00000000}, + {0x90350000, 0x00000000}, {0x40000000, 0x00000000}, + {0x095, 0x00000000}, + {0x90360000, 0x00000000}, {0x40000000, 0x00000000}, + {0x095, 0x00000000}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x095, 0x00000008}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x095, 0x00000008}, + {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, + {0x095, 0x00000008}, + {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, + {0x095, 0x00000008}, + {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, + {0x095, 0x00000008}, + {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, + {0x095, 0x00000008}, + {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, + {0x095, 0x00000008}, + {0x903f0001, 0x00000000}, {0x40000000, 0x00000000}, + {0x095, 0x00000008}, + {0x90400001, 0x00000000}, {0x40000000, 0x00000000}, + {0x095, 0x00000008}, + {0xA0000000, 0x00000000}, + {0x095, 0x00000000}, + {0xB0000000, 0x00000000}, + {0x0EE, 0x00001000}, + {0x033, 0x00000020}, + {0x03F, 0x00000052}, + {0x033, 0x00000024}, + {0x03F, 0x0000005A}, + {0x033, 0x00000028}, + {0x03F, 0x0000009C}, + {0x033, 0x0000002C}, + {0x03F, 0x0000019C}, + {0x033, 0x00000030}, + {0x03F, 0x000001A4}, + {0x033, 0x00000034}, + {0x03F, 0x000001E7}, + {0x033, 0x00000038}, + {0x03F, 0x000002E7}, + {0x033, 0x0000003C}, + {0x03F, 0x000003E7}, + {0x033, 0x00000021}, + {0x03F, 0x00000052}, + {0x033, 0x00000025}, + {0x03F, 0x0000005A}, + {0x033, 0x00000029}, + {0x03F, 0x0000009C}, + {0x033, 0x0000002D}, + {0x03F, 0x0000019C}, + {0x033, 0x00000031}, + {0x03F, 0x000001A4}, + {0x033, 0x00000035}, + {0x03F, 0x000001E6}, + {0x033, 0x00000039}, + {0x03F, 0x000002E6}, + {0x033, 0x0000003D}, + {0x03F, 0x000003E6}, + {0x033, 0x00000022}, + {0x03F, 0x00000052}, + {0x033, 0x00000026}, + {0x03F, 0x0000005A}, + {0x033, 0x0000002A}, + {0x03F, 0x0000009C}, + {0x033, 0x0000002E}, + {0x03F, 0x0000019C}, + {0x033, 0x00000032}, + {0x03F, 0x000001A4}, + {0x033, 0x00000036}, + {0x03F, 0x000001E6}, + {0x033, 0x0000003A}, + {0x03F, 0x000002E6}, + {0x033, 0x0000003E}, + {0x03F, 0x000003E6}, + {0x033, 0x00000060}, + {0x03F, 0x00000052}, + {0x033, 0x00000064}, + {0x03F, 0x0000005A}, + {0x033, 0x00000068}, + {0x03F, 0x0000009C}, + {0x033, 0x0000006C}, + {0x03F, 0x0000019C}, + {0x033, 0x00000070}, + {0x03F, 0x000001A4}, + {0x033, 0x00000074}, + {0x03F, 0x000001E6}, + {0x033, 0x00000078}, + {0x03F, 0x000002E6}, + {0x033, 0x0000007C}, + {0x03F, 0x000003E6}, + {0x033, 0x00000061}, + {0x03F, 0x00000052}, + {0x033, 0x00000065}, + {0x03F, 0x0000005A}, + {0x033, 0x00000069}, + {0x03F, 0x0000009C}, + {0x033, 0x0000006D}, + {0x03F, 0x0000019C}, + {0x033, 0x00000071}, + {0x03F, 0x000001A4}, + {0x033, 0x00000075}, + {0x03F, 0x000001E6}, + {0x033, 0x00000079}, + {0x03F, 0x000002E6}, + {0x033, 0x0000007D}, + {0x03F, 0x000003E6}, + {0x033, 0x00000062}, + {0x03F, 0x00000052}, + {0x033, 0x00000066}, + {0x03F, 0x0000005A}, + {0x033, 0x0000006A}, + {0x03F, 0x0000009C}, + {0x033, 0x0000006E}, + {0x03F, 0x0000019C}, + {0x033, 0x00000072}, + {0x03F, 0x000001A4}, + {0x033, 0x00000076}, + {0x03F, 0x000001E6}, + {0x033, 0x0000007A}, + {0x03F, 0x000002E6}, + {0x033, 0x0000007E}, + {0x03F, 0x000003E6}, + {0x033, 0x00000063}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000052}, + {0x90020000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000052}, + {0x90320000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000052}, + {0x90330000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000052}, + {0x90340000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000052}, + {0x90350000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000052}, + {0x90360000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000052}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000152}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000152}, + {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000152}, + {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000152}, + {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000152}, + {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000152}, + {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000152}, + {0x903f0001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000152}, + {0x90400001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x00000152}, + {0xA0000000, 0x00000000}, + {0x03F, 0x00000052}, + {0xB0000000, 0x00000000}, + {0x033, 0x00000067}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000005A}, + {0x90020000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000005A}, + {0x90320000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000005A}, + {0x90330000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000005A}, + {0x90340000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000005A}, + {0x90350000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000005A}, + {0x90360000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000005A}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000015A}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000015A}, + {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000015A}, + {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000015A}, + {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000015A}, + {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000015A}, + {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000015A}, + {0x903f0001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000015A}, + {0x90400001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000015A}, + {0xA0000000, 0x00000000}, + {0x03F, 0x0000005A}, + {0xB0000000, 0x00000000}, + {0x033, 0x0000006B}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000009C}, + {0x90020000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000009C}, + {0x90320000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000009C}, + {0x90330000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000009C}, + {0x90340000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000009C}, + {0x90350000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000009C}, + {0x90360000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000009C}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000019C}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000019C}, + {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000019C}, + {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000019C}, + {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000019C}, + {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000019C}, + {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000019C}, + {0x903f0001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000019C}, + {0x90400001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000019C}, + {0xA0000000, 0x00000000}, + {0x03F, 0x0000009C}, + {0xB0000000, 0x00000000}, + {0x033, 0x0000006F}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000019C}, + {0x90020000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000019C}, + {0x90320000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000019C}, + {0x90330000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000019C}, + {0x90340000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000019C}, + {0x90350000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000019C}, + {0x90360000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x0000019C}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001A4}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001A4}, + {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001A4}, + {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001A4}, + {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001A4}, + {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001A4}, + {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001A4}, + {0x903f0001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001A4}, + {0x90400001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001A4}, + {0xA0000000, 0x00000000}, + {0x03F, 0x0000019C}, + {0xB0000000, 0x00000000}, + {0x033, 0x00000073}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001A4}, + {0x90020000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001A4}, + {0x90320000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001A4}, + {0x90330000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001A4}, + {0x90340000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001A4}, + {0x90350000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001A4}, + {0x90360000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001A4}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001E6}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001E6}, + {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001E6}, + {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001E6}, + {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001E6}, + {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001E6}, + {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001E6}, + {0x903f0001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001E6}, + {0x90400001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001E6}, + {0xA0000000, 0x00000000}, + {0x03F, 0x000001A4}, + {0xB0000000, 0x00000000}, + {0x033, 0x00000077}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001E6}, + {0x90020000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001E6}, + {0x90320000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001E6}, + {0x90330000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001E6}, + {0x90340000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001E6}, + {0x90350000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001E6}, + {0x90360000, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000001E6}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000002E6}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000002E6}, + {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000002E6}, + {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000002E6}, + {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000002E6}, + {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000002E6}, + {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000002E6}, + {0x903f0001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000002E6}, + {0x90400001, 0x00000000}, {0x40000000, 0x00000000}, + {0x03F, 0x000002E6}, + {0xA0000000, 0x00000000}, + {0x03F, 0x000001E6}, + {0xB0000000, 0x00000000}, + {0x033, 0x0000007B}, + {0x03F, 0x000002E7}, + {0x033, 0x0000007F}, + {0x03F, 0x000003E7}, + {0x0EE, 0x00000000}, + {0x100EE, 0x00004000}, + {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, + {0x10030, 0x000001EF}, + {0x10030, 0x000005E9}, + {0x10030, 0x000009E3}, + {0x10030, 0x00000DDD}, + {0x10030, 0x000011D7}, + {0x10030, 0x0000159F}, + {0x10030, 0x00001999}, + {0x10030, 0x00001D5F}, + {0x10030, 0x00002159}, + {0x10030, 0x0000251F}, + {0x10030, 0x00002919}, + {0x10030, 0x00002CDF}, + {0x10030, 0x000030D9}, + {0x10030, 0x0000349F}, + {0x10030, 0x00003899}, + {0x10030, 0x00003C5F}, + {0x10030, 0x00004059}, + {0x10030, 0x00004453}, + {0x10030, 0x000201ED}, + {0x10030, 0x000205AD}, + {0x10030, 0x000209A7}, + {0x10030, 0x00020DA1}, + {0x10030, 0x0002119B}, + {0x10030, 0x00021561}, + {0x10030, 0x0002195B}, + {0x10030, 0x00021D27}, + {0x10030, 0x00022121}, + {0x10030, 0x000224E9}, + {0x10030, 0x000228E3}, + {0x10030, 0x00022CA9}, + {0x10030, 0x000230A3}, + {0x10030, 0x00023469}, + {0x10030, 0x00023863}, + {0x10030, 0x00023C29}, + {0x10030, 0x00024023}, + {0x10030, 0x0002441D}, + {0x10030, 0x000281EF}, + {0x10030, 0x000285AF}, + {0x10030, 0x000289A9}, + {0x10030, 0x00028DA3}, + {0x10030, 0x0002919D}, + {0x10030, 0x00029563}, + {0x10030, 0x0002995D}, + {0x10030, 0x00029D25}, + {0x10030, 0x0002A11F}, + {0x10030, 0x0002A4E7}, + {0x10030, 0x0002A8E1}, + {0x10030, 0x0002ACA7}, + {0x10030, 0x0002B0A1}, + {0x10030, 0x0002B467}, + {0x10030, 0x0002B861}, + {0x10030, 0x0002BC27}, + {0x10030, 0x0002C021}, + {0x10030, 0x0002C41B}, + {0x10030, 0x000301EF}, + {0x10030, 0x000305AF}, + {0x10030, 0x000309A9}, + {0x10030, 0x00030DA3}, + {0x10030, 0x0003119D}, + {0x10030, 0x00031563}, + {0x10030, 0x0003195D}, + {0x10030, 0x00031D25}, + {0x10030, 0x0003211F}, + {0x10030, 0x000324E7}, + {0x10030, 0x000328E1}, + {0x10030, 0x00032CA7}, + {0x10030, 0x000330A1}, + {0x10030, 0x00033467}, + {0x10030, 0x00033861}, + {0x10030, 0x00033C27}, + {0x10030, 0x00034021}, + {0x10030, 0x0003441B}, + {0x10030, 0x000601EB}, + {0x10030, 0x000605AB}, + {0x10030, 0x000609A5}, + {0x10030, 0x00060D9F}, + {0x10030, 0x00061199}, + {0x10030, 0x00061593}, + {0x10030, 0x00061959}, + {0x10030, 0x00061D53}, + {0x10030, 0x0006211B}, + {0x10030, 0x00062515}, + {0x10030, 0x000628DD}, + {0x10030, 0x00062CD7}, + {0x10030, 0x0006309D}, + {0x10030, 0x00063497}, + {0x10030, 0x0006385D}, + {0x10030, 0x00063C57}, + {0x10030, 0x0006401D}, + {0x10030, 0x00064417}, + {0x10030, 0x000681E7}, + {0x10030, 0x000685A7}, + {0x10030, 0x000689A1}, + {0x10030, 0x00068D9B}, + {0x10030, 0x00069195}, + {0x10030, 0x0006955F}, + {0x10030, 0x00069959}, + {0x10030, 0x00069D21}, + {0x10030, 0x0006A11B}, + {0x10030, 0x0006A4E3}, + {0x10030, 0x0006A8DD}, + {0x10030, 0x0006ACA5}, + {0x10030, 0x0006B09F}, + {0x10030, 0x0006B465}, + {0x10030, 0x0006B85F}, + {0x10030, 0x0006BC25}, + {0x10030, 0x0006C01F}, + {0x10030, 0x0006C419}, + {0x10030, 0x000701E7}, + {0x10030, 0x000705A7}, + {0x10030, 0x000709A1}, + {0x10030, 0x00070D9B}, + {0x10030, 0x00071195}, + {0x10030, 0x0007155B}, + {0x10030, 0x00071955}, + {0x10030, 0x00071D1D}, + {0x10030, 0x00072117}, + {0x10030, 0x000724DF}, + {0x10030, 0x000728D9}, + {0x10030, 0x00072CA1}, + {0x10030, 0x0007309B}, + {0x10030, 0x00073461}, + {0x10030, 0x0007385B}, + {0x10030, 0x00073C21}, + {0x10030, 0x0007401B}, + {0x10030, 0x0007441B}, + {0x10030, 0x000781E9}, + {0x10030, 0x000785A9}, + {0x10030, 0x000789A3}, + {0x10030, 0x00078D9D}, + {0x10030, 0x00079197}, + {0x10030, 0x00079591}, + {0x10030, 0x00079957}, + {0x10030, 0x00079D51}, + {0x10030, 0x0007A119}, + {0x10030, 0x0007A513}, + {0x10030, 0x0007A8D9}, + {0x10030, 0x0007ACD3}, + {0x10030, 0x0007B099}, + {0x10030, 0x0007B493}, + {0x10030, 0x0007B859}, + {0x10030, 0x0007BC53}, + {0x10030, 0x0007C019}, + {0x10030, 0x0007C413}, + {0x90020000, 0x00000000}, {0x40000000, 0x00000000}, + {0x10030, 0x000001EF}, + {0x10030, 0x000005E9}, + {0x10030, 0x000009E3}, + {0x10030, 0x00000DDD}, + {0x10030, 0x000011D7}, + {0x10030, 0x0000159F}, + {0x10030, 0x00001999}, + {0x10030, 0x00001D5F}, + {0x10030, 0x00002159}, + {0x10030, 0x0000251F}, + {0x10030, 0x00002919}, + {0x10030, 0x00002CDF}, + {0x10030, 0x000030D9}, + {0x10030, 0x0000349F}, + {0x10030, 0x00003899}, + {0x10030, 0x00003C5F}, + {0x10030, 0x00004059}, + {0x10030, 0x00004453}, + {0x10030, 0x000201ED}, + {0x10030, 0x000205AD}, + {0x10030, 0x000209A7}, + {0x10030, 0x00020DA1}, + {0x10030, 0x0002119B}, + {0x10030, 0x00021561}, + {0x10030, 0x0002195B}, + {0x10030, 0x00021D27}, + {0x10030, 0x00022121}, + {0x10030, 0x000224E9}, + {0x10030, 0x000228E3}, + {0x10030, 0x00022CA9}, + {0x10030, 0x000230A3}, + {0x10030, 0x00023469}, + {0x10030, 0x00023863}, + {0x10030, 0x00023C29}, + {0x10030, 0x00024023}, + {0x10030, 0x0002441D}, + {0x10030, 0x000281EF}, + {0x10030, 0x000285AF}, + {0x10030, 0x000289A9}, + {0x10030, 0x00028DA3}, + {0x10030, 0x0002919D}, + {0x10030, 0x00029563}, + {0x10030, 0x0002995D}, + {0x10030, 0x00029D25}, + {0x10030, 0x0002A11F}, + {0x10030, 0x0002A4E7}, + {0x10030, 0x0002A8E1}, + {0x10030, 0x0002ACA7}, + {0x10030, 0x0002B0A1}, + {0x10030, 0x0002B467}, + {0x10030, 0x0002B861}, + {0x10030, 0x0002BC27}, + {0x10030, 0x0002C021}, + {0x10030, 0x0002C41B}, + {0x10030, 0x000301EF}, + {0x10030, 0x000305AF}, + {0x10030, 0x000309A9}, + {0x10030, 0x00030DA3}, + {0x10030, 0x0003119D}, + {0x10030, 0x00031563}, + {0x10030, 0x0003195D}, + {0x10030, 0x00031D25}, + {0x10030, 0x0003211F}, + {0x10030, 0x000324E7}, + {0x10030, 0x000328E1}, + {0x10030, 0x00032CA7}, + {0x10030, 0x000330A1}, + {0x10030, 0x00033467}, + {0x10030, 0x00033861}, + {0x10030, 0x00033C27}, + {0x10030, 0x00034021}, + {0x10030, 0x0003441B}, + {0x10030, 0x000601EB}, + {0x10030, 0x000605AB}, + {0x10030, 0x000609A5}, + {0x10030, 0x00060D9F}, + {0x10030, 0x00061199}, + {0x10030, 0x00061593}, + {0x10030, 0x00061959}, + {0x10030, 0x00061D53}, + {0x10030, 0x0006211B}, + {0x10030, 0x00062515}, + {0x10030, 0x000628DD}, + {0x10030, 0x00062CD7}, + {0x10030, 0x0006309D}, + {0x10030, 0x00063497}, + {0x10030, 0x0006385D}, + {0x10030, 0x00063C57}, + {0x10030, 0x0006401D}, + {0x10030, 0x00064417}, + {0x10030, 0x000681E7}, + {0x10030, 0x000685A7}, + {0x10030, 0x000689A1}, + {0x10030, 0x00068D9B}, + {0x10030, 0x00069195}, + {0x10030, 0x0006955F}, + {0x10030, 0x00069959}, + {0x10030, 0x00069D21}, + {0x10030, 0x0006A11B}, + {0x10030, 0x0006A4E3}, + {0x10030, 0x0006A8DD}, + {0x10030, 0x0006ACA5}, + {0x10030, 0x0006B09F}, + {0x10030, 0x0006B465}, + {0x10030, 0x0006B85F}, + {0x10030, 0x0006BC25}, + {0x10030, 0x0006C01F}, + {0x10030, 0x0006C419}, + {0x10030, 0x000701E7}, + {0x10030, 0x000705A7}, + {0x10030, 0x000709A1}, + {0x10030, 0x00070D9B}, + {0x10030, 0x00071195}, + {0x10030, 0x0007155B}, + {0x10030, 0x00071955}, + {0x10030, 0x00071D1D}, + {0x10030, 0x00072117}, + {0x10030, 0x000724DF}, + {0x10030, 0x000728D9}, + {0x10030, 0x00072CA1}, + {0x10030, 0x0007309B}, + {0x10030, 0x00073461}, + {0x10030, 0x0007385B}, + {0x10030, 0x00073C21}, + {0x10030, 0x0007401B}, + {0x10030, 0x0007441B}, + {0x10030, 0x000781E9}, + {0x10030, 0x000785A9}, + {0x10030, 0x000789A3}, + {0x10030, 0x00078D9D}, + {0x10030, 0x00079197}, + {0x10030, 0x00079591}, + {0x10030, 0x00079957}, + {0x10030, 0x00079D51}, + {0x10030, 0x0007A119}, + {0x10030, 0x0007A513}, + {0x10030, 0x0007A8D9}, + {0x10030, 0x0007ACD3}, + {0x10030, 0x0007B099}, + {0x10030, 0x0007B493}, + {0x10030, 0x0007B859}, + {0x10030, 0x0007BC53}, + {0x10030, 0x0007C019}, + {0x10030, 0x0007C413}, + {0x90320000, 0x00000000}, {0x40000000, 0x00000000}, + {0x10030, 0x000001EF}, + {0x10030, 0x000005E9}, + {0x10030, 0x000009E3}, + {0x10030, 0x00000DDD}, + {0x10030, 0x000011D7}, + {0x10030, 0x0000159F}, + {0x10030, 0x00001999}, + {0x10030, 0x00001D5F}, + {0x10030, 0x00002159}, + {0x10030, 0x0000251F}, + {0x10030, 0x00002919}, + {0x10030, 0x00002CDF}, + {0x10030, 0x000030D9}, + {0x10030, 0x0000349F}, + {0x10030, 0x00003899}, + {0x10030, 0x00003C5F}, + {0x10030, 0x00004059}, + {0x10030, 0x00004453}, + {0x10030, 0x000201ED}, + {0x10030, 0x000205AD}, + {0x10030, 0x000209A7}, + {0x10030, 0x00020DA1}, + {0x10030, 0x0002119B}, + {0x10030, 0x00021561}, + {0x10030, 0x0002195B}, + {0x10030, 0x00021D27}, + {0x10030, 0x00022121}, + {0x10030, 0x000224E9}, + {0x10030, 0x000228E3}, + {0x10030, 0x00022CA9}, + {0x10030, 0x000230A3}, + {0x10030, 0x00023469}, + {0x10030, 0x00023863}, + {0x10030, 0x00023C29}, + {0x10030, 0x00024023}, + {0x10030, 0x0002441D}, + {0x10030, 0x000281EF}, + {0x10030, 0x000285AF}, + {0x10030, 0x000289A9}, + {0x10030, 0x00028DA3}, + {0x10030, 0x0002919D}, + {0x10030, 0x00029563}, + {0x10030, 0x0002995D}, + {0x10030, 0x00029D25}, + {0x10030, 0x0002A11F}, + {0x10030, 0x0002A4E7}, + {0x10030, 0x0002A8E1}, + {0x10030, 0x0002ACA7}, + {0x10030, 0x0002B0A1}, + {0x10030, 0x0002B467}, + {0x10030, 0x0002B861}, + {0x10030, 0x0002BC27}, + {0x10030, 0x0002C021}, + {0x10030, 0x0002C41B}, + {0x10030, 0x000301EF}, + {0x10030, 0x000305AF}, + {0x10030, 0x000309A9}, + {0x10030, 0x00030DA3}, + {0x10030, 0x0003119D}, + {0x10030, 0x00031563}, + {0x10030, 0x0003195D}, + {0x10030, 0x00031D25}, + {0x10030, 0x0003211F}, + {0x10030, 0x000324E7}, + {0x10030, 0x000328E1}, + {0x10030, 0x00032CA7}, + {0x10030, 0x000330A1}, + {0x10030, 0x00033467}, + {0x10030, 0x00033861}, + {0x10030, 0x00033C27}, + {0x10030, 0x00034021}, + {0x10030, 0x0003441B}, + {0x10030, 0x000601EB}, + {0x10030, 0x000605AB}, + {0x10030, 0x000609A5}, + {0x10030, 0x00060D9F}, + {0x10030, 0x00061199}, + {0x10030, 0x00061593}, + {0x10030, 0x00061959}, + {0x10030, 0x00061D53}, + {0x10030, 0x0006211B}, + {0x10030, 0x00062515}, + {0x10030, 0x000628DD}, + {0x10030, 0x00062CD7}, + {0x10030, 0x0006309D}, + {0x10030, 0x00063497}, + {0x10030, 0x0006385D}, + {0x10030, 0x00063C57}, + {0x10030, 0x0006401D}, + {0x10030, 0x00064417}, + {0x10030, 0x000681E7}, + {0x10030, 0x000685A7}, + {0x10030, 0x000689A1}, + {0x10030, 0x00068D9B}, + {0x10030, 0x00069195}, + {0x10030, 0x0006955F}, + {0x10030, 0x00069959}, + {0x10030, 0x00069D21}, + {0x10030, 0x0006A11B}, + {0x10030, 0x0006A4E3}, + {0x10030, 0x0006A8DD}, + {0x10030, 0x0006ACA5}, + {0x10030, 0x0006B09F}, + {0x10030, 0x0006B465}, + {0x10030, 0x0006B85F}, + {0x10030, 0x0006BC25}, + {0x10030, 0x0006C01F}, + {0x10030, 0x0006C419}, + {0x10030, 0x000701E7}, + {0x10030, 0x000705A7}, + {0x10030, 0x000709A1}, + {0x10030, 0x00070D9B}, + {0x10030, 0x00071195}, + {0x10030, 0x0007155B}, + {0x10030, 0x00071955}, + {0x10030, 0x00071D1D}, + {0x10030, 0x00072117}, + {0x10030, 0x000724DF}, + {0x10030, 0x000728D9}, + {0x10030, 0x00072CA1}, + {0x10030, 0x0007309B}, + {0x10030, 0x00073461}, + {0x10030, 0x0007385B}, + {0x10030, 0x00073C21}, + {0x10030, 0x0007401B}, + {0x10030, 0x0007441B}, + {0x10030, 0x000781E9}, + {0x10030, 0x000785A9}, + {0x10030, 0x000789A3}, + {0x10030, 0x00078D9D}, + {0x10030, 0x00079197}, + {0x10030, 0x00079591}, + {0x10030, 0x00079957}, + {0x10030, 0x00079D51}, + {0x10030, 0x0007A119}, + {0x10030, 0x0007A513}, + {0x10030, 0x0007A8D9}, + {0x10030, 0x0007ACD3}, + {0x10030, 0x0007B099}, + {0x10030, 0x0007B493}, + {0x10030, 0x0007B859}, + {0x10030, 0x0007BC53}, + {0x10030, 0x0007C019}, + {0x10030, 0x0007C413}, + {0x90330000, 0x00000000}, {0x40000000, 0x00000000}, + {0x10030, 0x000201DF}, + {0x10030, 0x000205D9}, + {0x10030, 0x000209D3}, + {0x10030, 0x00020D99}, + {0x10030, 0x00021193}, + {0x10030, 0x0002155F}, + {0x10030, 0x00021959}, + {0x10030, 0x00021D21}, + {0x10030, 0x00022119}, + {0x10030, 0x000224DF}, + {0x10030, 0x000228D9}, + {0x10030, 0x00022C9F}, + {0x10030, 0x00023099}, + {0x10030, 0x0002345F}, + {0x10030, 0x00023859}, + {0x10030, 0x00023C1F}, + {0x10030, 0x00024019}, + {0x10030, 0x00024413}, + {0x10030, 0x000281CD}, + {0x10030, 0x000285DB}, + {0x10030, 0x000289D5}, + {0x10030, 0x00028D9B}, + {0x10030, 0x0002918D}, + {0x10030, 0x00029555}, + {0x10030, 0x00029957}, + {0x10030, 0x00029D1F}, + {0x10030, 0x0002A119}, + {0x10030, 0x0002A4DF}, + {0x10030, 0x0002A8D9}, + {0x10030, 0x0002AC9F}, + {0x10030, 0x0002B099}, + {0x10030, 0x0002B45F}, + {0x10030, 0x0002B859}, + {0x10030, 0x0002BC1F}, + {0x10030, 0x0002C019}, + {0x10030, 0x0002C413}, + {0x10030, 0x000301D9}, + {0x10030, 0x000305DB}, + {0x10030, 0x000309D5}, + {0x10030, 0x00030D9B}, + {0x10030, 0x00031195}, + {0x10030, 0x0003155D}, + {0x10030, 0x00031955}, + {0x10030, 0x00031D1D}, + {0x10030, 0x00032119}, + {0x10030, 0x000324DF}, + {0x10030, 0x000328D9}, + {0x10030, 0x00032C9F}, + {0x10030, 0x00033099}, + {0x10030, 0x0003345F}, + {0x10030, 0x00033859}, + {0x10030, 0x00033C1F}, + {0x10030, 0x00034019}, + {0x10030, 0x00034413}, + {0x10030, 0x000601E1}, + {0x10030, 0x000605DB}, + {0x10030, 0x000609D5}, + {0x10030, 0x00060D9B}, + {0x10030, 0x00061195}, + {0x10030, 0x0006155B}, + {0x10030, 0x00061957}, + {0x10030, 0x00061D1F}, + {0x10030, 0x00062119}, + {0x10030, 0x000624DF}, + {0x10030, 0x000628D9}, + {0x10030, 0x00062C9F}, + {0x10030, 0x00063099}, + {0x10030, 0x0006345F}, + {0x10030, 0x00063859}, + {0x10030, 0x00063C1F}, + {0x10030, 0x00064019}, + {0x10030, 0x00064413}, + {0x10030, 0x000681E1}, + {0x10030, 0x000685DB}, + {0x10030, 0x000689D5}, + {0x10030, 0x00068D9B}, + {0x10030, 0x00069195}, + {0x10030, 0x0006955B}, + {0x10030, 0x00069957}, + {0x10030, 0x00069D1F}, + {0x10030, 0x0006A119}, + {0x10030, 0x0006A4DF}, + {0x10030, 0x0006A8D9}, + {0x10030, 0x0006AC9F}, + {0x10030, 0x0006B099}, + {0x10030, 0x0006B45F}, + {0x10030, 0x0006B859}, + {0x10030, 0x0006BC1F}, + {0x10030, 0x0006C019}, + {0x10030, 0x0006C413}, + {0x10030, 0x000701E1}, + {0x10030, 0x000705DB}, + {0x10030, 0x000709D5}, + {0x10030, 0x00070D9B}, + {0x10030, 0x00071195}, + {0x10030, 0x0007155B}, + {0x10030, 0x00071957}, + {0x10030, 0x00071D1F}, + {0x10030, 0x00072119}, + {0x10030, 0x000724DF}, + {0x10030, 0x000728D9}, + {0x10030, 0x00072C9F}, + {0x10030, 0x00073099}, + {0x10030, 0x0007345F}, + {0x10030, 0x00073859}, + {0x10030, 0x00073C1F}, + {0x10030, 0x00074019}, + {0x10030, 0x00074413}, + {0x10030, 0x000781DF}, + {0x10030, 0x000785D9}, + {0x10030, 0x000789D3}, + {0x10030, 0x00078D99}, + {0x10030, 0x00079193}, + {0x10030, 0x0007955F}, + {0x10030, 0x00079959}, + {0x10030, 0x00079D21}, + {0x10030, 0x0007A115}, + {0x10030, 0x0007A4DF}, + {0x10030, 0x0007A8D9}, + {0x10030, 0x0007AC9F}, + {0x10030, 0x0007B099}, + {0x10030, 0x0007B45F}, + {0x10030, 0x0007B859}, + {0x10030, 0x0007BC1F}, + {0x10030, 0x0007C019}, + {0x10030, 0x0007C413}, + {0x10030, 0x00000000}, + {0x10030, 0x000785A9}, + {0x10030, 0x000789A3}, + {0x10030, 0x00078D9D}, + {0x10030, 0x00079197}, + {0x10030, 0x00079591}, + {0x10030, 0x00079957}, + {0x10030, 0x00079D51}, + {0x10030, 0x0007A119}, + {0x10030, 0x0007A513}, + {0x10030, 0x0007A8D9}, + {0x10030, 0x0007ACD3}, + {0x10030, 0x0007B099}, + {0x10030, 0x0007B493}, + {0x10030, 0x0007B859}, + {0x10030, 0x0007BC53}, + {0x10030, 0x0007C019}, + {0x10030, 0x0007C413}, + {0x90340000, 0x00000000}, {0x40000000, 0x00000000}, + {0x10030, 0x000201DF}, + {0x10030, 0x000205D9}, + {0x10030, 0x000209D3}, + {0x10030, 0x00020D99}, + {0x10030, 0x00021193}, + {0x10030, 0x0002155F}, + {0x10030, 0x00021959}, + {0x10030, 0x00021D21}, + {0x10030, 0x00022119}, + {0x10030, 0x000224DF}, + {0x10030, 0x000228D9}, + {0x10030, 0x00022C9F}, + {0x10030, 0x00023099}, + {0x10030, 0x0002345F}, + {0x10030, 0x00023859}, + {0x10030, 0x00023C1F}, + {0x10030, 0x00024019}, + {0x10030, 0x00024413}, + {0x10030, 0x000281CD}, + {0x10030, 0x000285DB}, + {0x10030, 0x000289D5}, + {0x10030, 0x00028D9B}, + {0x10030, 0x0002918D}, + {0x10030, 0x00029555}, + {0x10030, 0x00029957}, + {0x10030, 0x00029D1F}, + {0x10030, 0x0002A119}, + {0x10030, 0x0002A4DF}, + {0x10030, 0x0002A8D9}, + {0x10030, 0x0002AC9F}, + {0x10030, 0x0002B099}, + {0x10030, 0x0002B45F}, + {0x10030, 0x0002B859}, + {0x10030, 0x0002BC1F}, + {0x10030, 0x0002C019}, + {0x10030, 0x0002C413}, + {0x10030, 0x000301D9}, + {0x10030, 0x000305DB}, + {0x10030, 0x000309D5}, + {0x10030, 0x00030D9B}, + {0x10030, 0x00031195}, + {0x10030, 0x0003155D}, + {0x10030, 0x00031955}, + {0x10030, 0x00031D1D}, + {0x10030, 0x00032119}, + {0x10030, 0x000324DF}, + {0x10030, 0x000328D9}, + {0x10030, 0x00032C9F}, + {0x10030, 0x00033099}, + {0x10030, 0x0003345F}, + {0x10030, 0x00033859}, + {0x10030, 0x00033C1F}, + {0x10030, 0x00034019}, + {0x10030, 0x00034413}, + {0x10030, 0x000601E1}, + {0x10030, 0x000605DB}, + {0x10030, 0x000609D5}, + {0x10030, 0x00060D9B}, + {0x10030, 0x00061195}, + {0x10030, 0x0006155B}, + {0x10030, 0x00061957}, + {0x10030, 0x00061D1F}, + {0x10030, 0x00062119}, + {0x10030, 0x000624DF}, + {0x10030, 0x000628D9}, + {0x10030, 0x00062C9F}, + {0x10030, 0x00063099}, + {0x10030, 0x0006345F}, + {0x10030, 0x00063859}, + {0x10030, 0x00063C1F}, + {0x10030, 0x00064019}, + {0x10030, 0x00064413}, + {0x10030, 0x000681E1}, + {0x10030, 0x000685DB}, + {0x10030, 0x000689D5}, + {0x10030, 0x00068D9B}, + {0x10030, 0x00069195}, + {0x10030, 0x0006955B}, + {0x10030, 0x00069957}, + {0x10030, 0x00069D1F}, + {0x10030, 0x0006A119}, + {0x10030, 0x0006A4DF}, + {0x10030, 0x0006A8D9}, + {0x10030, 0x0006AC9F}, + {0x10030, 0x0006B099}, + {0x10030, 0x0006B45F}, + {0x10030, 0x0006B859}, + {0x10030, 0x0006BC1F}, + {0x10030, 0x0006C019}, + {0x10030, 0x0006C413}, + {0x10030, 0x000701E1}, + {0x10030, 0x000705DB}, + {0x10030, 0x000709D5}, + {0x10030, 0x00070D9B}, + {0x10030, 0x00071195}, + {0x10030, 0x0007155B}, + {0x10030, 0x00071957}, + {0x10030, 0x00071D1F}, + {0x10030, 0x00072119}, + {0x10030, 0x000724DF}, + {0x10030, 0x000728D9}, + {0x10030, 0x00072C9F}, + {0x10030, 0x00073099}, + {0x10030, 0x0007345F}, + {0x10030, 0x00073859}, + {0x10030, 0x00073C1F}, + {0x10030, 0x00074019}, + {0x10030, 0x00074413}, + {0x10030, 0x000781DF}, + {0x10030, 0x000785D9}, + {0x10030, 0x000789D3}, + {0x10030, 0x00078D99}, + {0x10030, 0x00079193}, + {0x10030, 0x0007955F}, + {0x10030, 0x00079959}, + {0x10030, 0x00079D21}, + {0x10030, 0x0007A115}, + {0x10030, 0x0007A4DF}, + {0x10030, 0x0007A8D9}, + {0x10030, 0x0007AC9F}, + {0x10030, 0x0007B099}, + {0x10030, 0x0007B45F}, + {0x10030, 0x0007B859}, + {0x10030, 0x0007BC1F}, + {0x10030, 0x0007C019}, + {0x10030, 0x0007C413}, + {0x10030, 0x00000000}, + {0x10030, 0x000785A9}, + {0x10030, 0x000789A3}, + {0x10030, 0x00078D9D}, + {0x10030, 0x00079197}, + {0x10030, 0x00079591}, + {0x10030, 0x00079957}, + {0x10030, 0x00079D51}, + {0x10030, 0x0007A119}, + {0x10030, 0x0007A513}, + {0x10030, 0x0007A8D9}, + {0x10030, 0x0007ACD3}, + {0x10030, 0x0007B099}, + {0x10030, 0x0007B493}, + {0x10030, 0x0007B859}, + {0x10030, 0x0007BC53}, + {0x10030, 0x0007C019}, + {0x10030, 0x0007C413}, + {0x90350000, 0x00000000}, {0x40000000, 0x00000000}, + {0x10030, 0x000201DF}, + {0x10030, 0x000205D9}, + {0x10030, 0x000209D3}, + {0x10030, 0x00020D99}, + {0x10030, 0x00021193}, + {0x10030, 0x0002155F}, + {0x10030, 0x00021959}, + {0x10030, 0x00021D21}, + {0x10030, 0x00022119}, + {0x10030, 0x000224DF}, + {0x10030, 0x000228D9}, + {0x10030, 0x00022C9F}, + {0x10030, 0x00023099}, + {0x10030, 0x0002345F}, + {0x10030, 0x00023859}, + {0x10030, 0x00023C1F}, + {0x10030, 0x00024019}, + {0x10030, 0x00024413}, + {0x10030, 0x000281CD}, + {0x10030, 0x000285DB}, + {0x10030, 0x000289D5}, + {0x10030, 0x00028D9B}, + {0x10030, 0x0002918D}, + {0x10030, 0x00029555}, + {0x10030, 0x00029957}, + {0x10030, 0x00029D1F}, + {0x10030, 0x0002A119}, + {0x10030, 0x0002A4DF}, + {0x10030, 0x0002A8D9}, + {0x10030, 0x0002AC9F}, + {0x10030, 0x0002B099}, + {0x10030, 0x0002B45F}, + {0x10030, 0x0002B859}, + {0x10030, 0x0002BC1F}, + {0x10030, 0x0002C019}, + {0x10030, 0x0002C413}, + {0x10030, 0x000301D9}, + {0x10030, 0x000305DB}, + {0x10030, 0x000309D5}, + {0x10030, 0x00030D9B}, + {0x10030, 0x00031195}, + {0x10030, 0x0003155D}, + {0x10030, 0x00031955}, + {0x10030, 0x00031D1D}, + {0x10030, 0x00032119}, + {0x10030, 0x000324DF}, + {0x10030, 0x000328D9}, + {0x10030, 0x00032C9F}, + {0x10030, 0x00033099}, + {0x10030, 0x0003345F}, + {0x10030, 0x00033859}, + {0x10030, 0x00033C1F}, + {0x10030, 0x00034019}, + {0x10030, 0x00034413}, + {0x10030, 0x000601E1}, + {0x10030, 0x000605DB}, + {0x10030, 0x000609D5}, + {0x10030, 0x00060D9B}, + {0x10030, 0x00061195}, + {0x10030, 0x0006155B}, + {0x10030, 0x00061957}, + {0x10030, 0x00061D1F}, + {0x10030, 0x00062119}, + {0x10030, 0x000624DF}, + {0x10030, 0x000628D9}, + {0x10030, 0x00062C9F}, + {0x10030, 0x00063099}, + {0x10030, 0x0006345F}, + {0x10030, 0x00063859}, + {0x10030, 0x00063C1F}, + {0x10030, 0x00064019}, + {0x10030, 0x00064413}, + {0x10030, 0x000681E1}, + {0x10030, 0x000685DB}, + {0x10030, 0x000689D5}, + {0x10030, 0x00068D9B}, + {0x10030, 0x00069195}, + {0x10030, 0x0006955B}, + {0x10030, 0x00069957}, + {0x10030, 0x00069D1F}, + {0x10030, 0x0006A119}, + {0x10030, 0x0006A4DF}, + {0x10030, 0x0006A8D9}, + {0x10030, 0x0006AC9F}, + {0x10030, 0x0006B099}, + {0x10030, 0x0006B45F}, + {0x10030, 0x0006B859}, + {0x10030, 0x0006BC1F}, + {0x10030, 0x0006C019}, + {0x10030, 0x0006C413}, + {0x10030, 0x000701E1}, + {0x10030, 0x000705DB}, + {0x10030, 0x000709D5}, + {0x10030, 0x00070D9B}, + {0x10030, 0x00071195}, + {0x10030, 0x0007155B}, + {0x10030, 0x00071957}, + {0x10030, 0x00071D1F}, + {0x10030, 0x00072119}, + {0x10030, 0x000724DF}, + {0x10030, 0x000728D9}, + {0x10030, 0x00072C9F}, + {0x10030, 0x00073099}, + {0x10030, 0x0007345F}, + {0x10030, 0x00073859}, + {0x10030, 0x00073C1F}, + {0x10030, 0x00074019}, + {0x10030, 0x00074413}, + {0x10030, 0x000781DF}, + {0x10030, 0x000785D9}, + {0x10030, 0x000789D3}, + {0x10030, 0x00078D99}, + {0x10030, 0x00079193}, + {0x10030, 0x0007955F}, + {0x10030, 0x00079959}, + {0x10030, 0x00079D21}, + {0x10030, 0x0007A115}, + {0x10030, 0x0007A4DF}, + {0x10030, 0x0007A8D9}, + {0x10030, 0x0007AC9F}, + {0x10030, 0x0007B099}, + {0x10030, 0x0007B45F}, + {0x10030, 0x0007B859}, + {0x10030, 0x0007BC1F}, + {0x10030, 0x0007C019}, + {0x10030, 0x0007C413}, + {0x10030, 0x00000000}, + {0x10030, 0x000785A9}, + {0x10030, 0x000789A3}, + {0x10030, 0x00078D9D}, + {0x10030, 0x00079197}, + {0x10030, 0x00079591}, + {0x10030, 0x00079957}, + {0x10030, 0x00079D51}, + {0x10030, 0x0007A119}, + {0x10030, 0x0007A513}, + {0x10030, 0x0007A8D9}, + {0x10030, 0x0007ACD3}, + {0x10030, 0x0007B099}, + {0x10030, 0x0007B493}, + {0x10030, 0x0007B859}, + {0x10030, 0x0007BC53}, + {0x10030, 0x0007C019}, + {0x10030, 0x0007C413}, + {0x90360000, 0x00000000}, {0x40000000, 0x00000000}, + {0x10030, 0x000201DF}, + {0x10030, 0x000205D9}, + {0x10030, 0x000209D3}, + {0x10030, 0x00020D99}, + {0x10030, 0x00021193}, + {0x10030, 0x0002155F}, + {0x10030, 0x00021959}, + {0x10030, 0x00021D21}, + {0x10030, 0x00022119}, + {0x10030, 0x000224DF}, + {0x10030, 0x000228D9}, + {0x10030, 0x00022C9F}, + {0x10030, 0x00023099}, + {0x10030, 0x0002345F}, + {0x10030, 0x00023859}, + {0x10030, 0x00023C1F}, + {0x10030, 0x00024019}, + {0x10030, 0x00024413}, + {0x10030, 0x000281CD}, + {0x10030, 0x000285DB}, + {0x10030, 0x000289D5}, + {0x10030, 0x00028D9B}, + {0x10030, 0x0002918D}, + {0x10030, 0x00029555}, + {0x10030, 0x00029957}, + {0x10030, 0x00029D1F}, + {0x10030, 0x0002A119}, + {0x10030, 0x0002A4DF}, + {0x10030, 0x0002A8D9}, + {0x10030, 0x0002AC9F}, + {0x10030, 0x0002B099}, + {0x10030, 0x0002B45F}, + {0x10030, 0x0002B859}, + {0x10030, 0x0002BC1F}, + {0x10030, 0x0002C019}, + {0x10030, 0x0002C413}, + {0x10030, 0x000301D9}, + {0x10030, 0x000305DB}, + {0x10030, 0x000309D5}, + {0x10030, 0x00030D9B}, + {0x10030, 0x00031195}, + {0x10030, 0x0003155D}, + {0x10030, 0x00031955}, + {0x10030, 0x00031D1D}, + {0x10030, 0x00032119}, + {0x10030, 0x000324DF}, + {0x10030, 0x000328D9}, + {0x10030, 0x00032C9F}, + {0x10030, 0x00033099}, + {0x10030, 0x0003345F}, + {0x10030, 0x00033859}, + {0x10030, 0x00033C1F}, + {0x10030, 0x00034019}, + {0x10030, 0x00034413}, + {0x10030, 0x000601E1}, + {0x10030, 0x000605DB}, + {0x10030, 0x000609D5}, + {0x10030, 0x00060D9B}, + {0x10030, 0x00061195}, + {0x10030, 0x0006155B}, + {0x10030, 0x00061957}, + {0x10030, 0x00061D1F}, + {0x10030, 0x00062119}, + {0x10030, 0x000624DF}, + {0x10030, 0x000628D9}, + {0x10030, 0x00062C9F}, + {0x10030, 0x00063099}, + {0x10030, 0x0006345F}, + {0x10030, 0x00063859}, + {0x10030, 0x00063C1F}, + {0x10030, 0x00064019}, + {0x10030, 0x00064413}, + {0x10030, 0x000681E1}, + {0x10030, 0x000685DB}, + {0x10030, 0x000689D5}, + {0x10030, 0x00068D9B}, + {0x10030, 0x00069195}, + {0x10030, 0x0006955B}, + {0x10030, 0x00069957}, + {0x10030, 0x00069D1F}, + {0x10030, 0x0006A119}, + {0x10030, 0x0006A4DF}, + {0x10030, 0x0006A8D9}, + {0x10030, 0x0006AC9F}, + {0x10030, 0x0006B099}, + {0x10030, 0x0006B45F}, + {0x10030, 0x0006B859}, + {0x10030, 0x0006BC1F}, + {0x10030, 0x0006C019}, + {0x10030, 0x0006C413}, + {0x10030, 0x000701E1}, + {0x10030, 0x000705DB}, + {0x10030, 0x000709D5}, + {0x10030, 0x00070D9B}, + {0x10030, 0x00071195}, + {0x10030, 0x0007155B}, + {0x10030, 0x00071957}, + {0x10030, 0x00071D1F}, + {0x10030, 0x00072119}, + {0x10030, 0x000724DF}, + {0x10030, 0x000728D9}, + {0x10030, 0x00072C9F}, + {0x10030, 0x00073099}, + {0x10030, 0x0007345F}, + {0x10030, 0x00073859}, + {0x10030, 0x00073C1F}, + {0x10030, 0x00074019}, + {0x10030, 0x00074413}, + {0x10030, 0x000781DF}, + {0x10030, 0x000785D9}, + {0x10030, 0x000789D3}, + {0x10030, 0x00078D99}, + {0x10030, 0x00079193}, + {0x10030, 0x0007955F}, + {0x10030, 0x00079959}, + {0x10030, 0x00079D21}, + {0x10030, 0x0007A115}, + {0x10030, 0x0007A4DF}, + {0x10030, 0x0007A8D9}, + {0x10030, 0x0007AC9F}, + {0x10030, 0x0007B099}, + {0x10030, 0x0007B45F}, + {0x10030, 0x0007B859}, + {0x10030, 0x0007BC1F}, + {0x10030, 0x0007C019}, + {0x10030, 0x0007C413}, + {0x10030, 0x00000000}, + {0x10030, 0x000785A9}, + {0x10030, 0x000789A3}, + {0x10030, 0x00078D9D}, + {0x10030, 0x00079197}, + {0x10030, 0x00079591}, + {0x10030, 0x00079957}, + {0x10030, 0x00079D51}, + {0x10030, 0x0007A119}, + {0x10030, 0x0007A513}, + {0x10030, 0x0007A8D9}, + {0x10030, 0x0007ACD3}, + {0x10030, 0x0007B099}, + {0x10030, 0x0007B493}, + {0x10030, 0x0007B859}, + {0x10030, 0x0007BC53}, + {0x10030, 0x0007C019}, + {0x10030, 0x0007C413}, + {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, + {0x10030, 0x000001EF}, + {0x10030, 0x000005E9}, + {0x10030, 0x000009E3}, + {0x10030, 0x00000DDD}, + {0x10030, 0x000011D7}, + {0x10030, 0x0000159F}, + {0x10030, 0x00001999}, + {0x10030, 0x00001D5F}, + {0x10030, 0x00002159}, + {0x10030, 0x0000251F}, + {0x10030, 0x00002919}, + {0x10030, 0x00002CDF}, + {0x10030, 0x000030D9}, + {0x10030, 0x0000349F}, + {0x10030, 0x00003899}, + {0x10030, 0x00003C5F}, + {0x10030, 0x00004059}, + {0x10030, 0x00004453}, + {0x10030, 0x000201ED}, + {0x10030, 0x000205AD}, + {0x10030, 0x000209A7}, + {0x10030, 0x00020DA1}, + {0x10030, 0x0002119B}, + {0x10030, 0x00021561}, + {0x10030, 0x0002195B}, + {0x10030, 0x00021D27}, + {0x10030, 0x00022121}, + {0x10030, 0x000224E9}, + {0x10030, 0x000228E3}, + {0x10030, 0x00022CA9}, + {0x10030, 0x000230A3}, + {0x10030, 0x00023469}, + {0x10030, 0x00023863}, + {0x10030, 0x00023C29}, + {0x10030, 0x00024023}, + {0x10030, 0x0002441D}, + {0x10030, 0x000281EF}, + {0x10030, 0x000285AF}, + {0x10030, 0x000289A9}, + {0x10030, 0x00028DA3}, + {0x10030, 0x0002919D}, + {0x10030, 0x00029563}, + {0x10030, 0x0002995D}, + {0x10030, 0x00029D25}, + {0x10030, 0x0002A11F}, + {0x10030, 0x0002A4E7}, + {0x10030, 0x0002A8E1}, + {0x10030, 0x0002ACA7}, + {0x10030, 0x0002B0A1}, + {0x10030, 0x0002B467}, + {0x10030, 0x0002B861}, + {0x10030, 0x0002BC27}, + {0x10030, 0x0002C021}, + {0x10030, 0x0002C41B}, + {0x10030, 0x000301EF}, + {0x10030, 0x000305AF}, + {0x10030, 0x000309A9}, + {0x10030, 0x00030DA3}, + {0x10030, 0x0003119D}, + {0x10030, 0x00031563}, + {0x10030, 0x0003195D}, + {0x10030, 0x00031D25}, + {0x10030, 0x0003211F}, + {0x10030, 0x000324E7}, + {0x10030, 0x000328E1}, + {0x10030, 0x00032CA7}, + {0x10030, 0x000330A1}, + {0x10030, 0x00033467}, + {0x10030, 0x00033861}, + {0x10030, 0x00033C27}, + {0x10030, 0x00034021}, + {0x10030, 0x0003441B}, + {0x10030, 0x000601EB}, + {0x10030, 0x000605AB}, + {0x10030, 0x000609A5}, + {0x10030, 0x00060D9F}, + {0x10030, 0x00061199}, + {0x10030, 0x00061593}, + {0x10030, 0x00061959}, + {0x10030, 0x00061D53}, + {0x10030, 0x0006211B}, + {0x10030, 0x00062515}, + {0x10030, 0x000628DD}, + {0x10030, 0x00062CD7}, + {0x10030, 0x0006309D}, + {0x10030, 0x00063497}, + {0x10030, 0x0006385D}, + {0x10030, 0x00063C57}, + {0x10030, 0x0006401D}, + {0x10030, 0x00064417}, + {0x10030, 0x000681E7}, + {0x10030, 0x000685A7}, + {0x10030, 0x000689A1}, + {0x10030, 0x00068D9B}, + {0x10030, 0x00069195}, + {0x10030, 0x0006955F}, + {0x10030, 0x00069959}, + {0x10030, 0x00069D21}, + {0x10030, 0x0006A11B}, + {0x10030, 0x0006A4E3}, + {0x10030, 0x0006A8DD}, + {0x10030, 0x0006ACA5}, + {0x10030, 0x0006B09F}, + {0x10030, 0x0006B465}, + {0x10030, 0x0006B85F}, + {0x10030, 0x0006BC25}, + {0x10030, 0x0006C01F}, + {0x10030, 0x0006C419}, + {0x10030, 0x000701E7}, + {0x10030, 0x000705A7}, + {0x10030, 0x000709A1}, + {0x10030, 0x00070D9B}, + {0x10030, 0x00071195}, + {0x10030, 0x0007155B}, + {0x10030, 0x00071955}, + {0x10030, 0x00071D1D}, + {0x10030, 0x00072117}, + {0x10030, 0x000724DF}, + {0x10030, 0x000728D9}, + {0x10030, 0x00072CA1}, + {0x10030, 0x0007309B}, + {0x10030, 0x00073461}, + {0x10030, 0x0007385B}, + {0x10030, 0x00073C21}, + {0x10030, 0x0007401B}, + {0x10030, 0x0007441B}, + {0x10030, 0x000781EF}, + {0x10030, 0x000785E9}, + {0x10030, 0x000789E3}, + {0x10030, 0x00078DA3}, + {0x10030, 0x00079161}, + {0x10030, 0x0007955B}, + {0x10030, 0x00079921}, + {0x10030, 0x00079D1B}, + {0x10030, 0x0007A0E1}, + {0x10030, 0x0007A4DB}, + {0x10030, 0x0007A8A1}, + {0x10030, 0x0007AC9B}, + {0x10030, 0x0007B061}, + {0x10030, 0x0007B45B}, + {0x10030, 0x0007B821}, + {0x10030, 0x0007BC1B}, + {0x10030, 0x0007C015}, + {0x10030, 0x0007C40F}, + {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, + {0x10030, 0x000001EF}, + {0x10030, 0x000005E9}, + {0x10030, 0x000009E3}, + {0x10030, 0x00000DDD}, + {0x10030, 0x000011D7}, + {0x10030, 0x0000159F}, + {0x10030, 0x00001999}, + {0x10030, 0x00001D5F}, + {0x10030, 0x00002159}, + {0x10030, 0x0000251F}, + {0x10030, 0x00002919}, + {0x10030, 0x00002CDF}, + {0x10030, 0x000030D9}, + {0x10030, 0x0000349F}, + {0x10030, 0x00003899}, + {0x10030, 0x00003C5F}, + {0x10030, 0x00004059}, + {0x10030, 0x00004453}, + {0x10030, 0x000201ED}, + {0x10030, 0x000205AD}, + {0x10030, 0x000209A7}, + {0x10030, 0x00020DA1}, + {0x10030, 0x0002119B}, + {0x10030, 0x00021561}, + {0x10030, 0x0002195B}, + {0x10030, 0x00021D27}, + {0x10030, 0x00022121}, + {0x10030, 0x000224E9}, + {0x10030, 0x000228E3}, + {0x10030, 0x00022CA9}, + {0x10030, 0x000230A3}, + {0x10030, 0x00023469}, + {0x10030, 0x00023863}, + {0x10030, 0x00023C29}, + {0x10030, 0x00024023}, + {0x10030, 0x0002441D}, + {0x10030, 0x000281EF}, + {0x10030, 0x000285AF}, + {0x10030, 0x000289A9}, + {0x10030, 0x00028DA3}, + {0x10030, 0x0002919D}, + {0x10030, 0x00029563}, + {0x10030, 0x0002995D}, + {0x10030, 0x00029D25}, + {0x10030, 0x0002A11F}, + {0x10030, 0x0002A4E7}, + {0x10030, 0x0002A8E1}, + {0x10030, 0x0002ACA7}, + {0x10030, 0x0002B0A1}, + {0x10030, 0x0002B467}, + {0x10030, 0x0002B861}, + {0x10030, 0x0002BC27}, + {0x10030, 0x0002C021}, + {0x10030, 0x0002C41B}, + {0x10030, 0x000301EF}, + {0x10030, 0x000305AF}, + {0x10030, 0x000309A9}, + {0x10030, 0x00030DA3}, + {0x10030, 0x0003119D}, + {0x10030, 0x00031563}, + {0x10030, 0x0003195D}, + {0x10030, 0x00031D25}, + {0x10030, 0x0003211F}, + {0x10030, 0x000324E7}, + {0x10030, 0x000328E1}, + {0x10030, 0x00032CA7}, + {0x10030, 0x000330A1}, + {0x10030, 0x00033467}, + {0x10030, 0x00033861}, + {0x10030, 0x00033C27}, + {0x10030, 0x00034021}, + {0x10030, 0x0003441B}, + {0x10030, 0x000601EB}, + {0x10030, 0x000605AB}, + {0x10030, 0x000609A5}, + {0x10030, 0x00060D9F}, + {0x10030, 0x00061199}, + {0x10030, 0x00061593}, + {0x10030, 0x00061959}, + {0x10030, 0x00061D53}, + {0x10030, 0x0006211B}, + {0x10030, 0x00062515}, + {0x10030, 0x000628DD}, + {0x10030, 0x00062CD7}, + {0x10030, 0x0006309D}, + {0x10030, 0x00063497}, + {0x10030, 0x0006385D}, + {0x10030, 0x00063C57}, + {0x10030, 0x0006401D}, + {0x10030, 0x00064417}, + {0x10030, 0x000681E7}, + {0x10030, 0x000685A7}, + {0x10030, 0x000689A1}, + {0x10030, 0x00068D9B}, + {0x10030, 0x00069195}, + {0x10030, 0x0006955F}, + {0x10030, 0x00069959}, + {0x10030, 0x00069D21}, + {0x10030, 0x0006A11B}, + {0x10030, 0x0006A4E3}, + {0x10030, 0x0006A8DD}, + {0x10030, 0x0006ACA5}, + {0x10030, 0x0006B09F}, + {0x10030, 0x0006B465}, + {0x10030, 0x0006B85F}, + {0x10030, 0x0006BC25}, + {0x10030, 0x0006C01F}, + {0x10030, 0x0006C419}, + {0x10030, 0x000701E7}, + {0x10030, 0x000705A7}, + {0x10030, 0x000709A1}, + {0x10030, 0x00070D9B}, + {0x10030, 0x00071195}, + {0x10030, 0x0007155B}, + {0x10030, 0x00071955}, + {0x10030, 0x00071D1D}, + {0x10030, 0x00072117}, + {0x10030, 0x000724DF}, + {0x10030, 0x000728D9}, + {0x10030, 0x00072CA1}, + {0x10030, 0x0007309B}, + {0x10030, 0x00073461}, + {0x10030, 0x0007385B}, + {0x10030, 0x00073C21}, + {0x10030, 0x0007401B}, + {0x10030, 0x0007441B}, + {0x10030, 0x000781EF}, + {0x10030, 0x000785E9}, + {0x10030, 0x000789E3}, + {0x10030, 0x00078DA3}, + {0x10030, 0x00079161}, + {0x10030, 0x0007955B}, + {0x10030, 0x00079921}, + {0x10030, 0x00079D1B}, + {0x10030, 0x0007A0E1}, + {0x10030, 0x0007A4DB}, + {0x10030, 0x0007A8A1}, + {0x10030, 0x0007AC9B}, + {0x10030, 0x0007B061}, + {0x10030, 0x0007B45B}, + {0x10030, 0x0007B821}, + {0x10030, 0x0007BC1B}, + {0x10030, 0x0007C015}, + {0x10030, 0x0007C40F}, + {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, + {0x10030, 0x000001EF}, + {0x10030, 0x000005E9}, + {0x10030, 0x000009E3}, + {0x10030, 0x00000DDD}, + {0x10030, 0x000011D7}, + {0x10030, 0x0000159F}, + {0x10030, 0x00001999}, + {0x10030, 0x00001D5F}, + {0x10030, 0x00002159}, + {0x10030, 0x0000251F}, + {0x10030, 0x00002919}, + {0x10030, 0x00002CDF}, + {0x10030, 0x000030D9}, + {0x10030, 0x0000349F}, + {0x10030, 0x00003899}, + {0x10030, 0x00003C5F}, + {0x10030, 0x00004059}, + {0x10030, 0x00004453}, + {0x10030, 0x000201ED}, + {0x10030, 0x000205AD}, + {0x10030, 0x000209A7}, + {0x10030, 0x00020DA1}, + {0x10030, 0x0002119B}, + {0x10030, 0x00021561}, + {0x10030, 0x0002195B}, + {0x10030, 0x00021D27}, + {0x10030, 0x00022121}, + {0x10030, 0x000224E9}, + {0x10030, 0x000228E3}, + {0x10030, 0x00022CA9}, + {0x10030, 0x000230A3}, + {0x10030, 0x00023469}, + {0x10030, 0x00023863}, + {0x10030, 0x00023C29}, + {0x10030, 0x00024023}, + {0x10030, 0x0002441D}, + {0x10030, 0x000281EF}, + {0x10030, 0x000285AF}, + {0x10030, 0x000289A9}, + {0x10030, 0x00028DA3}, + {0x10030, 0x0002919D}, + {0x10030, 0x00029563}, + {0x10030, 0x0002995D}, + {0x10030, 0x00029D25}, + {0x10030, 0x0002A11F}, + {0x10030, 0x0002A4E7}, + {0x10030, 0x0002A8E1}, + {0x10030, 0x0002ACA7}, + {0x10030, 0x0002B0A1}, + {0x10030, 0x0002B467}, + {0x10030, 0x0002B861}, + {0x10030, 0x0002BC27}, + {0x10030, 0x0002C021}, + {0x10030, 0x0002C41B}, + {0x10030, 0x000301EF}, + {0x10030, 0x000305AF}, + {0x10030, 0x000309A9}, + {0x10030, 0x00030DA3}, + {0x10030, 0x0003119D}, + {0x10030, 0x00031563}, + {0x10030, 0x0003195D}, + {0x10030, 0x00031D25}, + {0x10030, 0x0003211F}, + {0x10030, 0x000324E7}, + {0x10030, 0x000328E1}, + {0x10030, 0x00032CA7}, + {0x10030, 0x000330A1}, + {0x10030, 0x00033467}, + {0x10030, 0x00033861}, + {0x10030, 0x00033C27}, + {0x10030, 0x00034021}, + {0x10030, 0x0003441B}, + {0x10030, 0x000601EB}, + {0x10030, 0x000605AB}, + {0x10030, 0x000609A5}, + {0x10030, 0x00060D9F}, + {0x10030, 0x00061199}, + {0x10030, 0x00061593}, + {0x10030, 0x00061959}, + {0x10030, 0x00061D53}, + {0x10030, 0x0006211B}, + {0x10030, 0x00062515}, + {0x10030, 0x000628DD}, + {0x10030, 0x00062CD7}, + {0x10030, 0x0006309D}, + {0x10030, 0x00063497}, + {0x10030, 0x0006385D}, + {0x10030, 0x00063C57}, + {0x10030, 0x0006401D}, + {0x10030, 0x00064417}, + {0x10030, 0x000681E7}, + {0x10030, 0x000685A7}, + {0x10030, 0x000689A1}, + {0x10030, 0x00068D9B}, + {0x10030, 0x00069195}, + {0x10030, 0x0006955F}, + {0x10030, 0x00069959}, + {0x10030, 0x00069D21}, + {0x10030, 0x0006A11B}, + {0x10030, 0x0006A4E3}, + {0x10030, 0x0006A8DD}, + {0x10030, 0x0006ACA5}, + {0x10030, 0x0006B09F}, + {0x10030, 0x0006B465}, + {0x10030, 0x0006B85F}, + {0x10030, 0x0006BC25}, + {0x10030, 0x0006C01F}, + {0x10030, 0x0006C419}, + {0x10030, 0x000701E7}, + {0x10030, 0x000705A7}, + {0x10030, 0x000709A1}, + {0x10030, 0x00070D9B}, + {0x10030, 0x00071195}, + {0x10030, 0x0007155B}, + {0x10030, 0x00071955}, + {0x10030, 0x00071D1D}, + {0x10030, 0x00072117}, + {0x10030, 0x000724DF}, + {0x10030, 0x000728D9}, + {0x10030, 0x00072CA1}, + {0x10030, 0x0007309B}, + {0x10030, 0x00073461}, + {0x10030, 0x0007385B}, + {0x10030, 0x00073C21}, + {0x10030, 0x0007401B}, + {0x10030, 0x0007441B}, + {0x10030, 0x000781EF}, + {0x10030, 0x000785E9}, + {0x10030, 0x000789E3}, + {0x10030, 0x00078DA3}, + {0x10030, 0x00079161}, + {0x10030, 0x0007955B}, + {0x10030, 0x00079921}, + {0x10030, 0x00079D1B}, + {0x10030, 0x0007A0E1}, + {0x10030, 0x0007A4DB}, + {0x10030, 0x0007A8A1}, + {0x10030, 0x0007AC9B}, + {0x10030, 0x0007B061}, + {0x10030, 0x0007B45B}, + {0x10030, 0x0007B821}, + {0x10030, 0x0007BC1B}, + {0x10030, 0x0007C015}, + {0x10030, 0x0007C40F}, + {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, + {0x10030, 0x000201DF}, + {0x10030, 0x000205D9}, + {0x10030, 0x000209D3}, + {0x10030, 0x00020D99}, + {0x10030, 0x00021193}, + {0x10030, 0x0002155F}, + {0x10030, 0x00021959}, + {0x10030, 0x00021D21}, + {0x10030, 0x00022119}, + {0x10030, 0x000224DF}, + {0x10030, 0x000228D9}, + {0x10030, 0x00022C9F}, + {0x10030, 0x00023099}, + {0x10030, 0x0002345F}, + {0x10030, 0x00023859}, + {0x10030, 0x00023C1F}, + {0x10030, 0x00024019}, + {0x10030, 0x00024413}, + {0x10030, 0x000281CD}, + {0x10030, 0x000285DB}, + {0x10030, 0x000289D5}, + {0x10030, 0x00028D9B}, + {0x10030, 0x0002918D}, + {0x10030, 0x00029555}, + {0x10030, 0x00029957}, + {0x10030, 0x00029D1F}, + {0x10030, 0x0002A119}, + {0x10030, 0x0002A4DF}, + {0x10030, 0x0002A8D9}, + {0x10030, 0x0002AC9F}, + {0x10030, 0x0002B099}, + {0x10030, 0x0002B45F}, + {0x10030, 0x0002B859}, + {0x10030, 0x0002BC1F}, + {0x10030, 0x0002C019}, + {0x10030, 0x0002C413}, + {0x10030, 0x000301D9}, + {0x10030, 0x000305DB}, + {0x10030, 0x000309D5}, + {0x10030, 0x00030D9B}, + {0x10030, 0x00031195}, + {0x10030, 0x0003155D}, + {0x10030, 0x00031955}, + {0x10030, 0x00031D1D}, + {0x10030, 0x00032119}, + {0x10030, 0x000324DF}, + {0x10030, 0x000328D9}, + {0x10030, 0x00032C9F}, + {0x10030, 0x00033099}, + {0x10030, 0x0003345F}, + {0x10030, 0x00033859}, + {0x10030, 0x00033C1F}, + {0x10030, 0x00034019}, + {0x10030, 0x00034413}, + {0x10030, 0x000601E1}, + {0x10030, 0x000605DB}, + {0x10030, 0x000609D5}, + {0x10030, 0x00060D9B}, + {0x10030, 0x00061195}, + {0x10030, 0x0006155B}, + {0x10030, 0x00061957}, + {0x10030, 0x00061D1F}, + {0x10030, 0x00062119}, + {0x10030, 0x000624DF}, + {0x10030, 0x000628D9}, + {0x10030, 0x00062C9F}, + {0x10030, 0x00063099}, + {0x10030, 0x0006345F}, + {0x10030, 0x00063859}, + {0x10030, 0x00063C1F}, + {0x10030, 0x00064019}, + {0x10030, 0x00064413}, + {0x10030, 0x000681E1}, + {0x10030, 0x000685DB}, + {0x10030, 0x000689D5}, + {0x10030, 0x00068D9B}, + {0x10030, 0x00069195}, + {0x10030, 0x0006955B}, + {0x10030, 0x00069957}, + {0x10030, 0x00069D1F}, + {0x10030, 0x0006A119}, + {0x10030, 0x0006A4DF}, + {0x10030, 0x0006A8D9}, + {0x10030, 0x0006AC9F}, + {0x10030, 0x0006B099}, + {0x10030, 0x0006B45F}, + {0x10030, 0x0006B859}, + {0x10030, 0x0006BC1F}, + {0x10030, 0x0006C019}, + {0x10030, 0x0006C413}, + {0x10030, 0x000701E1}, + {0x10030, 0x000705DB}, + {0x10030, 0x000709D5}, + {0x10030, 0x00070D9B}, + {0x10030, 0x00071195}, + {0x10030, 0x0007155B}, + {0x10030, 0x00071957}, + {0x10030, 0x00071D1F}, + {0x10030, 0x00072119}, + {0x10030, 0x000724DF}, + {0x10030, 0x000728D9}, + {0x10030, 0x00072C9F}, + {0x10030, 0x00073099}, + {0x10030, 0x0007345F}, + {0x10030, 0x00073859}, + {0x10030, 0x00073C1F}, + {0x10030, 0x00074019}, + {0x10030, 0x00074413}, + {0x10030, 0x000781DF}, + {0x10030, 0x000785D9}, + {0x10030, 0x000789D3}, + {0x10030, 0x00078D99}, + {0x10030, 0x00079193}, + {0x10030, 0x0007955F}, + {0x10030, 0x00079959}, + {0x10030, 0x00079D21}, + {0x10030, 0x0007A115}, + {0x10030, 0x0007A4DF}, + {0x10030, 0x0007A8D9}, + {0x10030, 0x0007AC9F}, + {0x10030, 0x0007B099}, + {0x10030, 0x0007B45F}, + {0x10030, 0x0007B859}, + {0x10030, 0x0007BC1F}, + {0x10030, 0x0007C019}, + {0x10030, 0x0007C413}, + {0x10030, 0x00000000}, + {0x10030, 0x000785A9}, + {0x10030, 0x000789A3}, + {0x10030, 0x00078D9D}, + {0x10030, 0x00079197}, + {0x10030, 0x00079591}, + {0x10030, 0x00079957}, + {0x10030, 0x00079D51}, + {0x10030, 0x0007A119}, + {0x10030, 0x0007A513}, + {0x10030, 0x0007A8D9}, + {0x10030, 0x0007ACD3}, + {0x10030, 0x0007B099}, + {0x10030, 0x0007B493}, + {0x10030, 0x0007B859}, + {0x10030, 0x0007BC53}, + {0x10030, 0x0007C019}, + {0x10030, 0x0007C413}, + {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, + {0x10030, 0x000201DF}, + {0x10030, 0x000205D9}, + {0x10030, 0x000209D3}, + {0x10030, 0x00020D99}, + {0x10030, 0x00021193}, + {0x10030, 0x0002155F}, + {0x10030, 0x00021959}, + {0x10030, 0x00021D21}, + {0x10030, 0x00022119}, + {0x10030, 0x000224DF}, + {0x10030, 0x000228D9}, + {0x10030, 0x00022C9F}, + {0x10030, 0x00023099}, + {0x10030, 0x0002345F}, + {0x10030, 0x00023859}, + {0x10030, 0x00023C1F}, + {0x10030, 0x00024019}, + {0x10030, 0x00024413}, + {0x10030, 0x000281CD}, + {0x10030, 0x000285DB}, + {0x10030, 0x000289D5}, + {0x10030, 0x00028D9B}, + {0x10030, 0x0002918D}, + {0x10030, 0x00029555}, + {0x10030, 0x00029957}, + {0x10030, 0x00029D1F}, + {0x10030, 0x0002A119}, + {0x10030, 0x0002A4DF}, + {0x10030, 0x0002A8D9}, + {0x10030, 0x0002AC9F}, + {0x10030, 0x0002B099}, + {0x10030, 0x0002B45F}, + {0x10030, 0x0002B859}, + {0x10030, 0x0002BC1F}, + {0x10030, 0x0002C019}, + {0x10030, 0x0002C413}, + {0x10030, 0x000301D9}, + {0x10030, 0x000305DB}, + {0x10030, 0x000309D5}, + {0x10030, 0x00030D9B}, + {0x10030, 0x00031195}, + {0x10030, 0x0003155D}, + {0x10030, 0x00031955}, + {0x10030, 0x00031D1D}, + {0x10030, 0x00032119}, + {0x10030, 0x000324DF}, + {0x10030, 0x000328D9}, + {0x10030, 0x00032C9F}, + {0x10030, 0x00033099}, + {0x10030, 0x0003345F}, + {0x10030, 0x00033859}, + {0x10030, 0x00033C1F}, + {0x10030, 0x00034019}, + {0x10030, 0x00034413}, + {0x10030, 0x000601E1}, + {0x10030, 0x000605DB}, + {0x10030, 0x000609D5}, + {0x10030, 0x00060D9B}, + {0x10030, 0x00061195}, + {0x10030, 0x0006155B}, + {0x10030, 0x00061957}, + {0x10030, 0x00061D1F}, + {0x10030, 0x00062119}, + {0x10030, 0x000624DF}, + {0x10030, 0x000628D9}, + {0x10030, 0x00062C9F}, + {0x10030, 0x00063099}, + {0x10030, 0x0006345F}, + {0x10030, 0x00063859}, + {0x10030, 0x00063C1F}, + {0x10030, 0x00064019}, + {0x10030, 0x00064413}, + {0x10030, 0x000681E1}, + {0x10030, 0x000685DB}, + {0x10030, 0x000689D5}, + {0x10030, 0x00068D9B}, + {0x10030, 0x00069195}, + {0x10030, 0x0006955B}, + {0x10030, 0x00069957}, + {0x10030, 0x00069D1F}, + {0x10030, 0x0006A119}, + {0x10030, 0x0006A4DF}, + {0x10030, 0x0006A8D9}, + {0x10030, 0x0006AC9F}, + {0x10030, 0x0006B099}, + {0x10030, 0x0006B45F}, + {0x10030, 0x0006B859}, + {0x10030, 0x0006BC1F}, + {0x10030, 0x0006C019}, + {0x10030, 0x0006C413}, + {0x10030, 0x000701E1}, + {0x10030, 0x000705DB}, + {0x10030, 0x000709D5}, + {0x10030, 0x00070D9B}, + {0x10030, 0x00071195}, + {0x10030, 0x0007155B}, + {0x10030, 0x00071957}, + {0x10030, 0x00071D1F}, + {0x10030, 0x00072119}, + {0x10030, 0x000724DF}, + {0x10030, 0x000728D9}, + {0x10030, 0x00072C9F}, + {0x10030, 0x00073099}, + {0x10030, 0x0007345F}, + {0x10030, 0x00073859}, + {0x10030, 0x00073C1F}, + {0x10030, 0x00074019}, + {0x10030, 0x00074413}, + {0x10030, 0x000781DF}, + {0x10030, 0x000785D9}, + {0x10030, 0x000789D3}, + {0x10030, 0x00078D99}, + {0x10030, 0x00079193}, + {0x10030, 0x0007955F}, + {0x10030, 0x00079959}, + {0x10030, 0x00079D21}, + {0x10030, 0x0007A115}, + {0x10030, 0x0007A4DF}, + {0x10030, 0x0007A8D9}, + {0x10030, 0x0007AC9F}, + {0x10030, 0x0007B099}, + {0x10030, 0x0007B45F}, + {0x10030, 0x0007B859}, + {0x10030, 0x0007BC1F}, + {0x10030, 0x0007C019}, + {0x10030, 0x0007C413}, + {0x10030, 0x00000000}, + {0x10030, 0x000785A9}, + {0x10030, 0x000789A3}, + {0x10030, 0x00078D9D}, + {0x10030, 0x00079197}, + {0x10030, 0x00079591}, + {0x10030, 0x00079957}, + {0x10030, 0x00079D51}, + {0x10030, 0x0007A119}, + {0x10030, 0x0007A513}, + {0x10030, 0x0007A8D9}, + {0x10030, 0x0007ACD3}, + {0x10030, 0x0007B099}, + {0x10030, 0x0007B493}, + {0x10030, 0x0007B859}, + {0x10030, 0x0007BC53}, + {0x10030, 0x0007C019}, + {0x10030, 0x0007C413}, + {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, + {0x10030, 0x000201DF}, + {0x10030, 0x000205D9}, + {0x10030, 0x000209D3}, + {0x10030, 0x00020D99}, + {0x10030, 0x00021193}, + {0x10030, 0x0002155F}, + {0x10030, 0x00021959}, + {0x10030, 0x00021D21}, + {0x10030, 0x00022119}, + {0x10030, 0x000224DF}, + {0x10030, 0x000228D9}, + {0x10030, 0x00022C9F}, + {0x10030, 0x00023099}, + {0x10030, 0x0002345F}, + {0x10030, 0x00023859}, + {0x10030, 0x00023C1F}, + {0x10030, 0x00024019}, + {0x10030, 0x00024413}, + {0x10030, 0x000281CD}, + {0x10030, 0x000285DB}, + {0x10030, 0x000289D5}, + {0x10030, 0x00028D9B}, + {0x10030, 0x0002918D}, + {0x10030, 0x00029555}, + {0x10030, 0x00029957}, + {0x10030, 0x00029D1F}, + {0x10030, 0x0002A119}, + {0x10030, 0x0002A4DF}, + {0x10030, 0x0002A8D9}, + {0x10030, 0x0002AC9F}, + {0x10030, 0x0002B099}, + {0x10030, 0x0002B45F}, + {0x10030, 0x0002B859}, + {0x10030, 0x0002BC1F}, + {0x10030, 0x0002C019}, + {0x10030, 0x0002C413}, + {0x10030, 0x000301D9}, + {0x10030, 0x000305DB}, + {0x10030, 0x000309D5}, + {0x10030, 0x00030D9B}, + {0x10030, 0x00031195}, + {0x10030, 0x0003155D}, + {0x10030, 0x00031955}, + {0x10030, 0x00031D1D}, + {0x10030, 0x00032119}, + {0x10030, 0x000324DF}, + {0x10030, 0x000328D9}, + {0x10030, 0x00032C9F}, + {0x10030, 0x00033099}, + {0x10030, 0x0003345F}, + {0x10030, 0x00033859}, + {0x10030, 0x00033C1F}, + {0x10030, 0x00034019}, + {0x10030, 0x00034413}, + {0x10030, 0x000601E1}, + {0x10030, 0x000605DB}, + {0x10030, 0x000609D5}, + {0x10030, 0x00060D9B}, + {0x10030, 0x00061195}, + {0x10030, 0x0006155B}, + {0x10030, 0x00061957}, + {0x10030, 0x00061D1F}, + {0x10030, 0x00062119}, + {0x10030, 0x000624DF}, + {0x10030, 0x000628D9}, + {0x10030, 0x00062C9F}, + {0x10030, 0x00063099}, + {0x10030, 0x0006345F}, + {0x10030, 0x00063859}, + {0x10030, 0x00063C1F}, + {0x10030, 0x00064019}, + {0x10030, 0x00064413}, + {0x10030, 0x000681E1}, + {0x10030, 0x000685DB}, + {0x10030, 0x000689D5}, + {0x10030, 0x00068D9B}, + {0x10030, 0x00069195}, + {0x10030, 0x0006955B}, + {0x10030, 0x00069957}, + {0x10030, 0x00069D1F}, + {0x10030, 0x0006A119}, + {0x10030, 0x0006A4DF}, + {0x10030, 0x0006A8D9}, + {0x10030, 0x0006AC9F}, + {0x10030, 0x0006B099}, + {0x10030, 0x0006B45F}, + {0x10030, 0x0006B859}, + {0x10030, 0x0006BC1F}, + {0x10030, 0x0006C019}, + {0x10030, 0x0006C413}, + {0x10030, 0x000701E1}, + {0x10030, 0x000705DB}, + {0x10030, 0x000709D5}, + {0x10030, 0x00070D9B}, + {0x10030, 0x00071195}, + {0x10030, 0x0007155B}, + {0x10030, 0x00071957}, + {0x10030, 0x00071D1F}, + {0x10030, 0x00072119}, + {0x10030, 0x000724DF}, + {0x10030, 0x000728D9}, + {0x10030, 0x00072C9F}, + {0x10030, 0x00073099}, + {0x10030, 0x0007345F}, + {0x10030, 0x00073859}, + {0x10030, 0x00073C1F}, + {0x10030, 0x00074019}, + {0x10030, 0x00074413}, + {0x10030, 0x000781DF}, + {0x10030, 0x000785D9}, + {0x10030, 0x000789D3}, + {0x10030, 0x00078D99}, + {0x10030, 0x00079193}, + {0x10030, 0x0007955F}, + {0x10030, 0x00079959}, + {0x10030, 0x00079D21}, + {0x10030, 0x0007A115}, + {0x10030, 0x0007A4DF}, + {0x10030, 0x0007A8D9}, + {0x10030, 0x0007AC9F}, + {0x10030, 0x0007B099}, + {0x10030, 0x0007B45F}, + {0x10030, 0x0007B859}, + {0x10030, 0x0007BC1F}, + {0x10030, 0x0007C019}, + {0x10030, 0x0007C413}, + {0x10030, 0x00000000}, + {0x10030, 0x000785A9}, + {0x10030, 0x000789A3}, + {0x10030, 0x00078D9D}, + {0x10030, 0x00079197}, + {0x10030, 0x00079591}, + {0x10030, 0x00079957}, + {0x10030, 0x00079D51}, + {0x10030, 0x0007A119}, + {0x10030, 0x0007A513}, + {0x10030, 0x0007A8D9}, + {0x10030, 0x0007ACD3}, + {0x10030, 0x0007B099}, + {0x10030, 0x0007B493}, + {0x10030, 0x0007B859}, + {0x10030, 0x0007BC53}, + {0x10030, 0x0007C019}, + {0x10030, 0x0007C413}, + {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, + {0x10030, 0x000201DF}, + {0x10030, 0x000205D9}, + {0x10030, 0x000209D3}, + {0x10030, 0x00020D99}, + {0x10030, 0x00021193}, + {0x10030, 0x0002155F}, + {0x10030, 0x00021959}, + {0x10030, 0x00021D21}, + {0x10030, 0x00022119}, + {0x10030, 0x000224DF}, + {0x10030, 0x000228D9}, + {0x10030, 0x00022C9F}, + {0x10030, 0x00023099}, + {0x10030, 0x0002345F}, + {0x10030, 0x00023859}, + {0x10030, 0x00023C1F}, + {0x10030, 0x00024019}, + {0x10030, 0x00024413}, + {0x10030, 0x000281CD}, + {0x10030, 0x000285DB}, + {0x10030, 0x000289D5}, + {0x10030, 0x00028D9B}, + {0x10030, 0x0002918D}, + {0x10030, 0x00029555}, + {0x10030, 0x00029957}, + {0x10030, 0x00029D1F}, + {0x10030, 0x0002A119}, + {0x10030, 0x0002A4DF}, + {0x10030, 0x0002A8D9}, + {0x10030, 0x0002AC9F}, + {0x10030, 0x0002B099}, + {0x10030, 0x0002B45F}, + {0x10030, 0x0002B859}, + {0x10030, 0x0002BC1F}, + {0x10030, 0x0002C019}, + {0x10030, 0x0002C413}, + {0x10030, 0x000301D9}, + {0x10030, 0x000305DB}, + {0x10030, 0x000309D5}, + {0x10030, 0x00030D9B}, + {0x10030, 0x00031195}, + {0x10030, 0x0003155D}, + {0x10030, 0x00031955}, + {0x10030, 0x00031D1D}, + {0x10030, 0x00032119}, + {0x10030, 0x000324DF}, + {0x10030, 0x000328D9}, + {0x10030, 0x00032C9F}, + {0x10030, 0x00033099}, + {0x10030, 0x0003345F}, + {0x10030, 0x00033859}, + {0x10030, 0x00033C1F}, + {0x10030, 0x00034019}, + {0x10030, 0x00034413}, + {0x10030, 0x000601E1}, + {0x10030, 0x000605DB}, + {0x10030, 0x000609D5}, + {0x10030, 0x00060D9B}, + {0x10030, 0x00061195}, + {0x10030, 0x0006155B}, + {0x10030, 0x00061957}, + {0x10030, 0x00061D1F}, + {0x10030, 0x00062119}, + {0x10030, 0x000624DF}, + {0x10030, 0x000628D9}, + {0x10030, 0x00062C9F}, + {0x10030, 0x00063099}, + {0x10030, 0x0006345F}, + {0x10030, 0x00063859}, + {0x10030, 0x00063C1F}, + {0x10030, 0x00064019}, + {0x10030, 0x00064413}, + {0x10030, 0x000681E1}, + {0x10030, 0x000685DB}, + {0x10030, 0x000689D5}, + {0x10030, 0x00068D9B}, + {0x10030, 0x00069195}, + {0x10030, 0x0006955B}, + {0x10030, 0x00069957}, + {0x10030, 0x00069D1F}, + {0x10030, 0x0006A119}, + {0x10030, 0x0006A4DF}, + {0x10030, 0x0006A8D9}, + {0x10030, 0x0006AC9F}, + {0x10030, 0x0006B099}, + {0x10030, 0x0006B45F}, + {0x10030, 0x0006B859}, + {0x10030, 0x0006BC1F}, + {0x10030, 0x0006C019}, + {0x10030, 0x0006C413}, + {0x10030, 0x000701E1}, + {0x10030, 0x000705DB}, + {0x10030, 0x000709D5}, + {0x10030, 0x00070D9B}, + {0x10030, 0x00071195}, + {0x10030, 0x0007155B}, + {0x10030, 0x00071957}, + {0x10030, 0x00071D1F}, + {0x10030, 0x00072119}, + {0x10030, 0x000724DF}, + {0x10030, 0x000728D9}, + {0x10030, 0x00072C9F}, + {0x10030, 0x00073099}, + {0x10030, 0x0007345F}, + {0x10030, 0x00073859}, + {0x10030, 0x00073C1F}, + {0x10030, 0x00074019}, + {0x10030, 0x00074413}, + {0x10030, 0x000781DF}, + {0x10030, 0x000785D9}, + {0x10030, 0x000789D3}, + {0x10030, 0x00078D99}, + {0x10030, 0x00079193}, + {0x10030, 0x0007955F}, + {0x10030, 0x00079959}, + {0x10030, 0x00079D21}, + {0x10030, 0x0007A115}, + {0x10030, 0x0007A4DF}, + {0x10030, 0x0007A8D9}, + {0x10030, 0x0007AC9F}, + {0x10030, 0x0007B099}, + {0x10030, 0x0007B45F}, + {0x10030, 0x0007B859}, + {0x10030, 0x0007BC1F}, + {0x10030, 0x0007C019}, + {0x10030, 0x0007C413}, + {0x10030, 0x00000000}, + {0x10030, 0x000785A9}, + {0x10030, 0x000789A3}, + {0x10030, 0x00078D9D}, + {0x10030, 0x00079197}, + {0x10030, 0x00079591}, + {0x10030, 0x00079957}, + {0x10030, 0x00079D51}, + {0x10030, 0x0007A119}, + {0x10030, 0x0007A513}, + {0x10030, 0x0007A8D9}, + {0x10030, 0x0007ACD3}, + {0x10030, 0x0007B099}, + {0x10030, 0x0007B493}, + {0x10030, 0x0007B859}, + {0x10030, 0x0007BC53}, + {0x10030, 0x0007C019}, + {0x10030, 0x0007C413}, + {0x903f0001, 0x00000000}, {0x40000000, 0x00000000}, + {0x10030, 0x000201DF}, + {0x10030, 0x000205D9}, + {0x10030, 0x000209D3}, + {0x10030, 0x00020D99}, + {0x10030, 0x00021193}, + {0x10030, 0x0002155F}, + {0x10030, 0x00021959}, + {0x10030, 0x00021D21}, + {0x10030, 0x00022119}, + {0x10030, 0x000224DF}, + {0x10030, 0x000228D9}, + {0x10030, 0x00022C9F}, + {0x10030, 0x00023099}, + {0x10030, 0x0002345F}, + {0x10030, 0x00023859}, + {0x10030, 0x00023C1F}, + {0x10030, 0x00024019}, + {0x10030, 0x00024413}, + {0x10030, 0x000281CD}, + {0x10030, 0x000285DB}, + {0x10030, 0x000289D5}, + {0x10030, 0x00028D9B}, + {0x10030, 0x0002918D}, + {0x10030, 0x00029555}, + {0x10030, 0x00029957}, + {0x10030, 0x00029D1F}, + {0x10030, 0x0002A119}, + {0x10030, 0x0002A4DF}, + {0x10030, 0x0002A8D9}, + {0x10030, 0x0002AC9F}, + {0x10030, 0x0002B099}, + {0x10030, 0x0002B45F}, + {0x10030, 0x0002B859}, + {0x10030, 0x0002BC1F}, + {0x10030, 0x0002C019}, + {0x10030, 0x0002C413}, + {0x10030, 0x000301D9}, + {0x10030, 0x000305DB}, + {0x10030, 0x000309D5}, + {0x10030, 0x00030D9B}, + {0x10030, 0x00031195}, + {0x10030, 0x0003155D}, + {0x10030, 0x00031955}, + {0x10030, 0x00031D1D}, + {0x10030, 0x00032119}, + {0x10030, 0x000324DF}, + {0x10030, 0x000328D9}, + {0x10030, 0x00032C9F}, + {0x10030, 0x00033099}, + {0x10030, 0x0003345F}, + {0x10030, 0x00033859}, + {0x10030, 0x00033C1F}, + {0x10030, 0x00034019}, + {0x10030, 0x00034413}, + {0x10030, 0x000601E1}, + {0x10030, 0x000605DB}, + {0x10030, 0x000609D5}, + {0x10030, 0x00060D9B}, + {0x10030, 0x00061195}, + {0x10030, 0x0006155B}, + {0x10030, 0x00061957}, + {0x10030, 0x00061D1F}, + {0x10030, 0x00062119}, + {0x10030, 0x000624DF}, + {0x10030, 0x000628D9}, + {0x10030, 0x00062C9F}, + {0x10030, 0x00063099}, + {0x10030, 0x0006345F}, + {0x10030, 0x00063859}, + {0x10030, 0x00063C1F}, + {0x10030, 0x00064019}, + {0x10030, 0x00064413}, + {0x10030, 0x000681E1}, + {0x10030, 0x000685DB}, + {0x10030, 0x000689D5}, + {0x10030, 0x00068D9B}, + {0x10030, 0x00069195}, + {0x10030, 0x0006955B}, + {0x10030, 0x00069957}, + {0x10030, 0x00069D1F}, + {0x10030, 0x0006A119}, + {0x10030, 0x0006A4DF}, + {0x10030, 0x0006A8D9}, + {0x10030, 0x0006AC9F}, + {0x10030, 0x0006B099}, + {0x10030, 0x0006B45F}, + {0x10030, 0x0006B859}, + {0x10030, 0x0006BC1F}, + {0x10030, 0x0006C019}, + {0x10030, 0x0006C413}, + {0x10030, 0x000701E1}, + {0x10030, 0x000705DB}, + {0x10030, 0x000709D5}, + {0x10030, 0x00070D9B}, + {0x10030, 0x00071195}, + {0x10030, 0x0007155B}, + {0x10030, 0x00071957}, + {0x10030, 0x00071D1F}, + {0x10030, 0x00072119}, + {0x10030, 0x000724DF}, + {0x10030, 0x000728D9}, + {0x10030, 0x00072C9F}, + {0x10030, 0x00073099}, + {0x10030, 0x0007345F}, + {0x10030, 0x00073859}, + {0x10030, 0x00073C1F}, + {0x10030, 0x00074019}, + {0x10030, 0x00074413}, + {0x10030, 0x000781DF}, + {0x10030, 0x000785D9}, + {0x10030, 0x000789D3}, + {0x10030, 0x00078D99}, + {0x10030, 0x00079193}, + {0x10030, 0x0007955F}, + {0x10030, 0x00079959}, + {0x10030, 0x00079D21}, + {0x10030, 0x0007A115}, + {0x10030, 0x0007A4DF}, + {0x10030, 0x0007A8D9}, + {0x10030, 0x0007AC9F}, + {0x10030, 0x0007B099}, + {0x10030, 0x0007B45F}, + {0x10030, 0x0007B859}, + {0x10030, 0x0007BC1F}, + {0x10030, 0x0007C019}, + {0x10030, 0x0007C413}, + {0x10030, 0x00000000}, + {0x10030, 0x000785A9}, + {0x10030, 0x000789A3}, + {0x10030, 0x00078D9D}, + {0x10030, 0x00079197}, + {0x10030, 0x00079591}, + {0x10030, 0x00079957}, + {0x10030, 0x00079D51}, + {0x10030, 0x0007A119}, + {0x10030, 0x0007A513}, + {0x10030, 0x0007A8D9}, + {0x10030, 0x0007ACD3}, + {0x10030, 0x0007B099}, + {0x10030, 0x0007B493}, + {0x10030, 0x0007B859}, + {0x10030, 0x0007BC53}, + {0x10030, 0x0007C019}, + {0x10030, 0x0007C413}, + {0x90400001, 0x00000000}, {0x40000000, 0x00000000}, + {0x10030, 0x000201DF}, + {0x10030, 0x000205D9}, + {0x10030, 0x000209D3}, + {0x10030, 0x00020D99}, + {0x10030, 0x00021193}, + {0x10030, 0x0002155F}, + {0x10030, 0x00021959}, + {0x10030, 0x00021D21}, + {0x10030, 0x00022119}, + {0x10030, 0x000224DF}, + {0x10030, 0x000228D9}, + {0x10030, 0x00022C9F}, + {0x10030, 0x00023099}, + {0x10030, 0x0002345F}, + {0x10030, 0x00023859}, + {0x10030, 0x00023C1F}, + {0x10030, 0x00024019}, + {0x10030, 0x00024413}, + {0x10030, 0x000281CD}, + {0x10030, 0x000285DB}, + {0x10030, 0x000289D5}, + {0x10030, 0x00028D9B}, + {0x10030, 0x0002918D}, + {0x10030, 0x00029555}, + {0x10030, 0x00029957}, + {0x10030, 0x00029D1F}, + {0x10030, 0x0002A119}, + {0x10030, 0x0002A4DF}, + {0x10030, 0x0002A8D9}, + {0x10030, 0x0002AC9F}, + {0x10030, 0x0002B099}, + {0x10030, 0x0002B45F}, + {0x10030, 0x0002B859}, + {0x10030, 0x0002BC1F}, + {0x10030, 0x0002C019}, + {0x10030, 0x0002C413}, + {0x10030, 0x000301D9}, + {0x10030, 0x000305DB}, + {0x10030, 0x000309D5}, + {0x10030, 0x00030D9B}, + {0x10030, 0x00031195}, + {0x10030, 0x0003155D}, + {0x10030, 0x00031955}, + {0x10030, 0x00031D1D}, + {0x10030, 0x00032119}, + {0x10030, 0x000324DF}, + {0x10030, 0x000328D9}, + {0x10030, 0x00032C9F}, + {0x10030, 0x00033099}, + {0x10030, 0x0003345F}, + {0x10030, 0x00033859}, + {0x10030, 0x00033C1F}, + {0x10030, 0x00034019}, + {0x10030, 0x00034413}, + {0x10030, 0x000601E1}, + {0x10030, 0x000605DB}, + {0x10030, 0x000609D5}, + {0x10030, 0x00060D9B}, + {0x10030, 0x00061195}, + {0x10030, 0x0006155B}, + {0x10030, 0x00061957}, + {0x10030, 0x00061D1F}, + {0x10030, 0x00062119}, + {0x10030, 0x000624DF}, + {0x10030, 0x000628D9}, + {0x10030, 0x00062C9F}, + {0x10030, 0x00063099}, + {0x10030, 0x0006345F}, + {0x10030, 0x00063859}, + {0x10030, 0x00063C1F}, + {0x10030, 0x00064019}, + {0x10030, 0x00064413}, + {0x10030, 0x000681E1}, + {0x10030, 0x000685DB}, + {0x10030, 0x000689D5}, + {0x10030, 0x00068D9B}, + {0x10030, 0x00069195}, + {0x10030, 0x0006955B}, + {0x10030, 0x00069957}, + {0x10030, 0x00069D1F}, + {0x10030, 0x0006A119}, + {0x10030, 0x0006A4DF}, + {0x10030, 0x0006A8D9}, + {0x10030, 0x0006AC9F}, + {0x10030, 0x0006B099}, + {0x10030, 0x0006B45F}, + {0x10030, 0x0006B859}, + {0x10030, 0x0006BC1F}, + {0x10030, 0x0006C019}, + {0x10030, 0x0006C413}, + {0x10030, 0x000701E1}, + {0x10030, 0x000705DB}, + {0x10030, 0x000709D5}, + {0x10030, 0x00070D9B}, + {0x10030, 0x00071195}, + {0x10030, 0x0007155B}, + {0x10030, 0x00071957}, + {0x10030, 0x00071D1F}, + {0x10030, 0x00072119}, + {0x10030, 0x000724DF}, + {0x10030, 0x000728D9}, + {0x10030, 0x00072C9F}, + {0x10030, 0x00073099}, + {0x10030, 0x0007345F}, + {0x10030, 0x00073859}, + {0x10030, 0x00073C1F}, + {0x10030, 0x00074019}, + {0x10030, 0x00074413}, + {0x10030, 0x000781DF}, + {0x10030, 0x000785D9}, + {0x10030, 0x000789D3}, + {0x10030, 0x00078D99}, + {0x10030, 0x00079193}, + {0x10030, 0x0007955F}, + {0x10030, 0x00079959}, + {0x10030, 0x00079D21}, + {0x10030, 0x0007A115}, + {0x10030, 0x0007A4DF}, + {0x10030, 0x0007A8D9}, + {0x10030, 0x0007AC9F}, + {0x10030, 0x0007B099}, + {0x10030, 0x0007B45F}, + {0x10030, 0x0007B859}, + {0x10030, 0x0007BC1F}, + {0x10030, 0x0007C019}, + {0x10030, 0x0007C413}, + {0x10030, 0x00000000}, + {0x10030, 0x000785A9}, + {0x10030, 0x000789A3}, + {0x10030, 0x00078D9D}, + {0x10030, 0x00079197}, + {0x10030, 0x00079591}, + {0x10030, 0x00079957}, + {0x10030, 0x00079D51}, + {0x10030, 0x0007A119}, + {0x10030, 0x0007A513}, + {0x10030, 0x0007A8D9}, + {0x10030, 0x0007ACD3}, + {0x10030, 0x0007B099}, + {0x10030, 0x0007B493}, + {0x10030, 0x0007B859}, + {0x10030, 0x0007BC53}, + {0x10030, 0x0007C019}, + {0x10030, 0x0007C413}, + {0xA0000000, 0x00000000}, + {0x10030, 0x000001EF}, + {0x10030, 0x000005E9}, + {0x10030, 0x000009E3}, + {0x10030, 0x00000DDD}, + {0x10030, 0x000011D7}, + {0x10030, 0x0000159F}, + {0x10030, 0x00001999}, + {0x10030, 0x00001D5F}, + {0x10030, 0x00002159}, + {0x10030, 0x0000251F}, + {0x10030, 0x00002919}, + {0x10030, 0x00002CDF}, + {0x10030, 0x000030D9}, + {0x10030, 0x0000349F}, + {0x10030, 0x00003899}, + {0x10030, 0x00003C5F}, + {0x10030, 0x00004059}, + {0x10030, 0x00004453}, + {0x10030, 0x000201ED}, + {0x10030, 0x000205AD}, + {0x10030, 0x000209A7}, + {0x10030, 0x00020DA1}, + {0x10030, 0x0002119B}, + {0x10030, 0x00021561}, + {0x10030, 0x0002195B}, + {0x10030, 0x00021D27}, + {0x10030, 0x00022121}, + {0x10030, 0x000224E9}, + {0x10030, 0x000228E3}, + {0x10030, 0x00022CA9}, + {0x10030, 0x000230A3}, + {0x10030, 0x00023469}, + {0x10030, 0x00023863}, + {0x10030, 0x00023C29}, + {0x10030, 0x00024023}, + {0x10030, 0x0002441D}, + {0x10030, 0x000281EF}, + {0x10030, 0x000285AF}, + {0x10030, 0x000289A9}, + {0x10030, 0x00028DA3}, + {0x10030, 0x0002919D}, + {0x10030, 0x00029563}, + {0x10030, 0x0002995D}, + {0x10030, 0x00029D25}, + {0x10030, 0x0002A11F}, + {0x10030, 0x0002A4E7}, + {0x10030, 0x0002A8E1}, + {0x10030, 0x0002ACA7}, + {0x10030, 0x0002B0A1}, + {0x10030, 0x0002B467}, + {0x10030, 0x0002B861}, + {0x10030, 0x0002BC27}, + {0x10030, 0x0002C021}, + {0x10030, 0x0002C41B}, + {0x10030, 0x000301EF}, + {0x10030, 0x000305AF}, + {0x10030, 0x000309A9}, + {0x10030, 0x00030DA3}, + {0x10030, 0x0003119D}, + {0x10030, 0x00031563}, + {0x10030, 0x0003195D}, + {0x10030, 0x00031D25}, + {0x10030, 0x0003211F}, + {0x10030, 0x000324E7}, + {0x10030, 0x000328E1}, + {0x10030, 0x00032CA7}, + {0x10030, 0x000330A1}, + {0x10030, 0x00033467}, + {0x10030, 0x00033861}, + {0x10030, 0x00033C27}, + {0x10030, 0x00034021}, + {0x10030, 0x0003441B}, + {0x10030, 0x000601EB}, + {0x10030, 0x000605AB}, + {0x10030, 0x000609A5}, + {0x10030, 0x00060D9F}, + {0x10030, 0x00061199}, + {0x10030, 0x00061593}, + {0x10030, 0x00061959}, + {0x10030, 0x00061D53}, + {0x10030, 0x0006211B}, + {0x10030, 0x00062515}, + {0x10030, 0x000628DD}, + {0x10030, 0x00062CD7}, + {0x10030, 0x0006309D}, + {0x10030, 0x00063497}, + {0x10030, 0x0006385D}, + {0x10030, 0x00063C57}, + {0x10030, 0x0006401D}, + {0x10030, 0x00064417}, + {0x10030, 0x000681E7}, + {0x10030, 0x000685A7}, + {0x10030, 0x000689A1}, + {0x10030, 0x00068D9B}, + {0x10030, 0x00069195}, + {0x10030, 0x0006955F}, + {0x10030, 0x00069959}, + {0x10030, 0x00069D21}, + {0x10030, 0x0006A11B}, + {0x10030, 0x0006A4E3}, + {0x10030, 0x0006A8DD}, + {0x10030, 0x0006ACA5}, + {0x10030, 0x0006B09F}, + {0x10030, 0x0006B465}, + {0x10030, 0x0006B85F}, + {0x10030, 0x0006BC25}, + {0x10030, 0x0006C01F}, + {0x10030, 0x0006C419}, + {0x10030, 0x000701E7}, + {0x10030, 0x000705A7}, + {0x10030, 0x000709A1}, + {0x10030, 0x00070D9B}, + {0x10030, 0x00071195}, + {0x10030, 0x0007155B}, + {0x10030, 0x00071955}, + {0x10030, 0x00071D1D}, + {0x10030, 0x00072117}, + {0x10030, 0x000724DF}, + {0x10030, 0x000728D9}, + {0x10030, 0x00072CA1}, + {0x10030, 0x0007309B}, + {0x10030, 0x00073461}, + {0x10030, 0x0007385B}, + {0x10030, 0x00073C21}, + {0x10030, 0x0007401B}, + {0x10030, 0x0007441B}, + {0x10030, 0x000781E9}, + {0x10030, 0x000785A9}, + {0x10030, 0x000789A3}, + {0x10030, 0x00078D9D}, + {0x10030, 0x00079197}, + {0x10030, 0x00079591}, + {0x10030, 0x00079957}, + {0x10030, 0x00079D51}, + {0x10030, 0x0007A119}, + {0x10030, 0x0007A513}, + {0x10030, 0x0007A8D9}, + {0x10030, 0x0007ACD3}, + {0x10030, 0x0007B099}, + {0x10030, 0x0007B493}, + {0x10030, 0x0007B859}, + {0x10030, 0x0007BC53}, + {0x10030, 0x0007C019}, + {0x10030, 0x0007C413}, + {0xB0000000, 0x00000000}, + {0x100EE, 0x00000000}, + {0x100EE, 0x00002000}, + {0x10030, 0x000000FC}, + {0x10030, 0x000004F9}, + {0x10030, 0x000008F6}, + {0x10030, 0x00000CF3}, + {0x10030, 0x000010F0}, + {0x10030, 0x000014ED}, + {0x10030, 0x000018AC}, + {0x10030, 0x00001CA9}, + {0x10030, 0x00002069}, + {0x10030, 0x00002466}, + {0x10030, 0x00002829}, + {0x10030, 0x00002C26}, + {0x10030, 0x00003023}, + {0x10030, 0x00003420}, + {0x10030, 0x0000381D}, + {0x10030, 0x00003C1A}, + {0x10030, 0x00004017}, + {0x100EE, 0x00000000}, + {0x100EE, 0x00002000}, + {0x10030, 0x000780F4}, + {0x10030, 0x000784F1}, + {0x10030, 0x000788EE}, + {0x10030, 0x00078CEB}, + {0x10030, 0x000790E8}, + {0x10030, 0x000794E5}, + {0x10030, 0x000798E2}, + {0x10030, 0x00079CDF}, + {0x10030, 0x0007A0DC}, + {0x10030, 0x0007A4D9}, + {0x10030, 0x0007A8D6}, + {0x10030, 0x0007ACD3}, + {0x10030, 0x0007B0D0}, + {0x10030, 0x0007B4CD}, + {0x10030, 0x0007B8CA}, + {0x10030, 0x0007BC07}, + {0x10030, 0x0007C004}, + {0x100EE, 0x00000000}, + {0x0EF, 0x00002000}, + {0x033, 0x00000008}, + {0x03F, 0x00000004}, + {0x033, 0x00000009}, + {0x03F, 0x00000003}, + {0x033, 0x0000000A}, + {0x03F, 0x00000003}, + {0x033, 0x0000000B}, + {0x03F, 0x00000002}, + {0x033, 0x0000000C}, + {0x03F, 0x00000002}, + {0x033, 0x0000000D}, + {0x03F, 0x00000002}, + {0x033, 0x0000000E}, + {0x03F, 0x00000002}, + {0x033, 0x0000000F}, + {0x03F, 0x00000002}, + {0x0EF, 0x00000000}, + {0x0EB, 0x00040000}, + {0x030, 0x000109B7}, + {0x0EB, 0x00000000}, + {0x0EF, 0x00008000}, + {0x033, 0x00000020}, + {0x03F, 0x00050002}, + {0x033, 0x00000021}, + {0x03F, 0x00060032}, + {0x033, 0x00000022}, + {0x03F, 0x00050042}, + {0x033, 0x00000023}, + {0x03F, 0x00040042}, + {0x033, 0x00000024}, + {0x03F, 0x00008001}, + {0x033, 0x00000025}, + {0x03F, 0x00008002}, + {0x033, 0x00000026}, + {0x03F, 0x00000003}, + {0x033, 0x00000027}, + {0x03F, 0x00000003}, + {0x033, 0x00000028}, + {0x03F, 0x00050002}, + {0x033, 0x00000029}, + {0x03F, 0x00060032}, + {0x033, 0x0000002A}, + {0x03F, 0x00050042}, + {0x033, 0x0000002B}, + {0x03F, 0x00040042}, + {0x033, 0x0000002C}, + {0x03F, 0x00008001}, + {0x033, 0x0000002D}, + {0x03F, 0x00008002}, + {0x033, 0x0000002E}, + {0x03F, 0x00000003}, + {0x033, 0x0000002F}, + {0x03F, 0x00000003}, + {0x033, 0x00000030}, + {0x03F, 0x00050002}, + {0x033, 0x00000031}, + {0x03F, 0x00060032}, + {0x033, 0x00000032}, + {0x03F, 0x00050042}, + {0x033, 0x00000033}, + {0x03F, 0x00040042}, + {0x033, 0x00000034}, + {0x03F, 0x00008001}, + {0x033, 0x00000035}, + {0x03F, 0x00008002}, + {0x033, 0x00000036}, + {0x03F, 0x00000003}, + {0x033, 0x00000037}, + {0x03F, 0x00000003}, + {0x033, 0x00000060}, + {0x03F, 0x00050002}, + {0x033, 0x00000061}, + {0x03F, 0x00060032}, + {0x033, 0x00000062}, + {0x03F, 0x00050042}, + {0x033, 0x00000063}, + {0x03F, 0x00040042}, + {0x033, 0x00000064}, + {0x03F, 0x00008001}, + {0x033, 0x00000065}, + {0x03F, 0x00008002}, + {0x033, 0x00000066}, + {0x03F, 0x00000003}, + {0x033, 0x00000067}, + {0x03F, 0x00000003}, + {0x033, 0x00000068}, + {0x03F, 0x00050002}, + {0x033, 0x00000069}, + {0x03F, 0x00060032}, + {0x033, 0x0000006A}, + {0x03F, 0x00050042}, + {0x033, 0x0000006B}, + {0x03F, 0x00040042}, + {0x033, 0x0000006C}, + {0x03F, 0x00008001}, + {0x033, 0x0000006D}, + {0x03F, 0x00008002}, + {0x033, 0x0000006E}, + {0x03F, 0x00000003}, + {0x033, 0x0000006F}, + {0x03F, 0x00000003}, + {0x033, 0x00000070}, + {0x03F, 0x00050002}, + {0x033, 0x00000071}, + {0x03F, 0x00060032}, + {0x033, 0x00000072}, + {0x03F, 0x00050042}, + {0x033, 0x00000073}, + {0x03F, 0x00040042}, + {0x033, 0x00000074}, + {0x03F, 0x00008001}, + {0x033, 0x00000075}, + {0x03F, 0x00008002}, + {0x033, 0x00000076}, + {0x03F, 0x00000003}, + {0x033, 0x00000077}, + {0x03F, 0x00000003}, + {0x033, 0x00000078}, + {0x03F, 0x00050002}, + {0x033, 0x00000079}, + {0x03F, 0x00060032}, + {0x033, 0x0000007A}, + {0x03F, 0x00050042}, + {0x033, 0x0000007B}, + {0x03F, 0x00040042}, + {0x033, 0x0000007C}, + {0x03F, 0x00008001}, + {0x033, 0x0000007D}, + {0x03F, 0x00008002}, + {0x033, 0x0000007E}, + {0x03F, 0x00000003}, + {0x033, 0x0000007F}, + {0x03F, 0x00000003}, + {0x033, 0x000000A0}, + {0x03F, 0x00050002}, + {0x033, 0x000000A1}, + {0x03F, 0x00060032}, + {0x033, 0x000000A2}, + {0x03F, 0x00050042}, + {0x033, 0x000000A3}, + {0x03F, 0x00040042}, + {0x033, 0x000000A4}, + {0x03F, 0x00008001}, + {0x033, 0x000000A5}, + {0x03F, 0x00008002}, + {0x033, 0x000000A6}, + {0x03F, 0x00000003}, + {0x033, 0x000000A7}, + {0x03F, 0x00000003}, + {0x033, 0x000000A8}, + {0x03F, 0x00050002}, + {0x033, 0x000000A9}, + {0x03F, 0x00060032}, + {0x033, 0x000000AA}, + {0x03F, 0x00050042}, + {0x033, 0x000000AB}, + {0x03F, 0x00040042}, + {0x033, 0x000000AC}, + {0x03F, 0x00008001}, + {0x033, 0x000000AD}, + {0x03F, 0x00008002}, + {0x033, 0x000000AE}, + {0x03F, 0x00000003}, + {0x033, 0x000000AF}, + {0x03F, 0x00000003}, + {0x033, 0x000000B0}, + {0x03F, 0x00050002}, + {0x033, 0x000000B1}, + {0x03F, 0x00060032}, + {0x033, 0x000000B2}, + {0x03F, 0x00050042}, + {0x033, 0x000000B3}, + {0x03F, 0x00040042}, + {0x033, 0x000000B4}, + {0x03F, 0x00008001}, + {0x033, 0x000000B5}, + {0x03F, 0x00008002}, + {0x033, 0x000000B6}, + {0x03F, 0x00000003}, + {0x033, 0x000000B7}, + {0x03F, 0x00000003}, + {0x033, 0x000000E0}, + {0x03F, 0x00050002}, + {0x033, 0x000000E1}, + {0x03F, 0x00060032}, + {0x033, 0x000000E2}, + {0x03F, 0x00050042}, + {0x033, 0x000000E3}, + {0x03F, 0x00040042}, + {0x033, 0x000000E4}, + {0x03F, 0x00008001}, + {0x033, 0x000000E5}, + {0x03F, 0x00008002}, + {0x033, 0x000000E6}, + {0x03F, 0x00000003}, + {0x033, 0x000000E7}, + {0x03F, 0x00000003}, + {0x033, 0x000000E8}, + {0x03F, 0x00050002}, + {0x033, 0x000000E9}, + {0x03F, 0x00060032}, + {0x033, 0x000000EA}, + {0x03F, 0x00050042}, + {0x033, 0x000000EB}, + {0x03F, 0x00040042}, + {0x033, 0x000000EC}, + {0x03F, 0x00008001}, + {0x033, 0x000000ED}, + {0x03F, 0x00008002}, + {0x033, 0x000000EE}, + {0x03F, 0x00000003}, + {0x033, 0x000000EF}, + {0x03F, 0x00000003}, + {0x033, 0x000000F0}, + {0x03F, 0x00050002}, + {0x033, 0x000000F1}, + {0x03F, 0x00060032}, + {0x033, 0x000000F2}, + {0x03F, 0x00050042}, + {0x033, 0x000000F3}, + {0x03F, 0x00040042}, + {0x033, 0x000000F4}, + {0x03F, 0x00008001}, + {0x033, 0x000000F5}, + {0x03F, 0x00008002}, + {0x033, 0x000000F6}, + {0x03F, 0x00000003}, + {0x033, 0x000000F7}, + {0x03F, 0x00000003}, + {0x033, 0x000000F8}, + {0x03F, 0x00050002}, + {0x033, 0x000000F9}, + {0x03F, 0x00060032}, + {0x033, 0x000000FA}, + {0x03F, 0x00050042}, + {0x033, 0x000000FB}, + {0x03F, 0x00040042}, + {0x033, 0x000000FC}, + {0x03F, 0x00008001}, + {0x033, 0x000000FD}, + {0x03F, 0x00008002}, + {0x033, 0x000000FE}, + {0x03F, 0x00000003}, + {0x033, 0x000000FF}, + {0x03F, 0x00000003}, + {0x033, 0x00000120}, + {0x03F, 0x00050002}, + {0x033, 0x00000121}, + {0x03F, 0x00060032}, + {0x033, 0x00000122}, + {0x03F, 0x00050042}, + {0x033, 0x00000123}, + {0x03F, 0x00040042}, + {0x033, 0x00000124}, + {0x03F, 0x00008001}, + {0x033, 0x00000125}, + {0x03F, 0x00008002}, + {0x033, 0x00000126}, + {0x03F, 0x00000003}, + {0x033, 0x00000127}, + {0x03F, 0x00000003}, + {0x033, 0x00000128}, + {0x03F, 0x00050002}, + {0x033, 0x00000129}, + {0x03F, 0x00060032}, + {0x033, 0x0000012A}, + {0x03F, 0x00050042}, + {0x033, 0x0000012B}, + {0x03F, 0x00040042}, + {0x033, 0x0000012C}, + {0x03F, 0x00008001}, + {0x033, 0x0000012D}, + {0x03F, 0x00008002}, + {0x033, 0x0000012E}, + {0x03F, 0x00000003}, + {0x033, 0x0000012F}, + {0x03F, 0x00000003}, + {0x033, 0x00000130}, + {0x03F, 0x00050002}, + {0x033, 0x00000131}, + {0x03F, 0x00060032}, + {0x033, 0x00000132}, + {0x03F, 0x00050042}, + {0x033, 0x00000133}, + {0x03F, 0x00040042}, + {0x033, 0x00000134}, + {0x03F, 0x00008001}, + {0x033, 0x00000135}, + {0x03F, 0x00008002}, + {0x033, 0x00000136}, + {0x03F, 0x00000003}, + {0x033, 0x00000137}, + {0x03F, 0x00000003}, + {0x033, 0x00000160}, + {0x03F, 0x00050002}, + {0x033, 0x00000161}, + {0x03F, 0x00060032}, + {0x033, 0x00000162}, + {0x03F, 0x00050042}, + {0x033, 0x00000163}, + {0x03F, 0x00040042}, + {0x033, 0x00000164}, + {0x03F, 0x00008001}, + {0x033, 0x00000165}, + {0x03F, 0x00008002}, + {0x033, 0x00000166}, + {0x03F, 0x00000003}, + {0x033, 0x00000167}, + {0x03F, 0x00000003}, + {0x033, 0x00000168}, + {0x03F, 0x00050002}, + {0x033, 0x00000169}, + {0x03F, 0x00060032}, + {0x033, 0x0000016A}, + {0x03F, 0x00050042}, + {0x033, 0x0000016B}, + {0x03F, 0x00040042}, + {0x033, 0x0000016C}, + {0x03F, 0x00008001}, + {0x033, 0x0000016D}, + {0x03F, 0x00008002}, + {0x033, 0x0000016E}, + {0x03F, 0x00000003}, + {0x033, 0x0000016F}, + {0x03F, 0x00000003}, + {0x033, 0x00000170}, + {0x03F, 0x00050002}, + {0x033, 0x00000171}, + {0x03F, 0x00060032}, + {0x033, 0x00000172}, + {0x03F, 0x00050042}, + {0x033, 0x00000173}, + {0x03F, 0x00040042}, + {0x033, 0x00000174}, + {0x03F, 0x00008001}, + {0x033, 0x00000175}, + {0x03F, 0x00008002}, + {0x033, 0x00000176}, + {0x03F, 0x00000003}, + {0x033, 0x00000177}, + {0x03F, 0x00000003}, + {0x033, 0x00000178}, + {0x03F, 0x00050002}, + {0x033, 0x00000179}, + {0x03F, 0x00060032}, + {0x033, 0x0000017A}, + {0x03F, 0x00050042}, + {0x033, 0x0000017B}, + {0x03F, 0x00040042}, + {0x033, 0x0000017C}, + {0x03F, 0x00008001}, + {0x033, 0x0000017D}, + {0x03F, 0x00008002}, + {0x033, 0x0000017E}, + {0x03F, 0x00000003}, + {0x033, 0x0000017F}, + {0x03F, 0x00000003}, + {0x033, 0x000001A0}, + {0x03F, 0x00050002}, + {0x033, 0x000001A1}, + {0x03F, 0x00060032}, + {0x033, 0x000001A2}, + {0x03F, 0x00050042}, + {0x033, 0x000001A3}, + {0x03F, 0x00040042}, + {0x033, 0x000001A4}, + {0x03F, 0x00008001}, + {0x033, 0x000001A5}, + {0x03F, 0x00008002}, + {0x033, 0x000001A6}, + {0x03F, 0x00000003}, + {0x033, 0x000001A7}, + {0x03F, 0x00000003}, + {0x033, 0x000001A8}, + {0x03F, 0x00050002}, + {0x033, 0x000001A9}, + {0x03F, 0x00060032}, + {0x033, 0x000001AA}, + {0x03F, 0x00050042}, + {0x033, 0x000001AB}, + {0x03F, 0x00040042}, + {0x033, 0x000001AC}, + {0x03F, 0x00008001}, + {0x033, 0x000001AD}, + {0x03F, 0x00008002}, + {0x033, 0x000001AE}, + {0x03F, 0x00000003}, + {0x033, 0x000001AF}, + {0x03F, 0x00000003}, + {0x033, 0x000001B0}, + {0x03F, 0x00050002}, + {0x033, 0x000001B1}, + {0x03F, 0x00060032}, + {0x033, 0x000001B2}, + {0x03F, 0x00050042}, + {0x033, 0x000001B3}, + {0x03F, 0x00040042}, + {0x033, 0x000001B4}, + {0x03F, 0x00008001}, + {0x033, 0x000001B5}, + {0x03F, 0x00008002}, + {0x033, 0x000001B6}, + {0x03F, 0x00000003}, + {0x033, 0x000001B7}, + {0x03F, 0x00000003}, + {0x033, 0x000001E0}, + {0x03F, 0x00050002}, + {0x033, 0x000001E1}, + {0x03F, 0x00060032}, + {0x033, 0x000001E2}, + {0x03F, 0x00050042}, + {0x033, 0x000001E3}, + {0x03F, 0x00040042}, + {0x033, 0x000001E4}, + {0x03F, 0x00008001}, + {0x033, 0x000001E5}, + {0x03F, 0x00008002}, + {0x033, 0x000001E6}, + {0x03F, 0x00000003}, + {0x033, 0x000001E7}, + {0x03F, 0x00000003}, + {0x033, 0x000001E8}, + {0x03F, 0x00050002}, + {0x033, 0x000001E9}, + {0x03F, 0x00060032}, + {0x033, 0x000001EA}, + {0x03F, 0x00050042}, + {0x033, 0x000001EB}, + {0x03F, 0x00040042}, + {0x033, 0x000001EC}, + {0x03F, 0x00008001}, + {0x033, 0x000001ED}, + {0x03F, 0x00008002}, + {0x033, 0x000001EE}, + {0x03F, 0x00000003}, + {0x033, 0x000001EF}, + {0x03F, 0x00000003}, + {0x033, 0x000001F0}, + {0x03F, 0x00050002}, + {0x033, 0x000001F1}, + {0x03F, 0x00060032}, + {0x033, 0x000001F2}, + {0x03F, 0x00050042}, + {0x033, 0x000001F3}, + {0x03F, 0x00040042}, + {0x033, 0x000001F4}, + {0x03F, 0x00008001}, + {0x033, 0x000001F5}, + {0x03F, 0x00008002}, + {0x033, 0x000001F6}, + {0x03F, 0x00000003}, + {0x033, 0x000001F7}, + {0x03F, 0x00000003}, + {0x033, 0x000001F8}, + {0x03F, 0x00050002}, + {0x033, 0x000001F9}, + {0x03F, 0x00060032}, + {0x033, 0x000001FA}, + {0x03F, 0x00050042}, + {0x033, 0x000001FB}, + {0x03F, 0x00040042}, + {0x033, 0x000001FC}, + {0x03F, 0x00008001}, + {0x033, 0x000001FD}, + {0x03F, 0x00008002}, + {0x033, 0x000001FE}, + {0x03F, 0x00000003}, + {0x033, 0x000001FF}, + {0x03F, 0x00000003}, + {0x0EF, 0x00000000}, + {0x005, 0x00000001}, + {0x10005, 0x00000001}, + {0x100EE, 0x00000400}, + {0x10030, 0x00000000}, + {0x10030, 0x00001000}, + {0x10030, 0x00002000}, + {0x10030, 0x00003000}, + {0x10030, 0x00004000}, + {0x10030, 0x00005000}, + {0x10030, 0x00006003}, + {0x10030, 0x00007003}, + {0x10030, 0x00008000}, + {0x10030, 0x00009000}, + {0x10030, 0x0000A000}, + {0x10030, 0x0000B000}, + {0x10030, 0x0000C000}, + {0x10030, 0x0000D000}, + {0x10030, 0x0000E003}, + {0x10030, 0x0000F003}, + {0x10030, 0x00010000}, + {0x10030, 0x00011000}, + {0x10030, 0x00012000}, + {0x10030, 0x00013000}, + {0x10030, 0x00014000}, + {0x10030, 0x00015000}, + {0x10030, 0x00016003}, + {0x10030, 0x00017003}, + {0x10030, 0x00018000}, + {0x10030, 0x00019000}, + {0x10030, 0x0001A000}, + {0x10030, 0x0001B000}, + {0x10030, 0x0001C000}, + {0x10030, 0x0001D000}, + {0x10030, 0x0001E003}, + {0x10030, 0x0001F003}, + {0x10030, 0x00020000}, + {0x10030, 0x00021000}, + {0x10030, 0x00022000}, + {0x10030, 0x00023000}, + {0x10030, 0x00024000}, + {0x10030, 0x00025000}, + {0x10030, 0x00026003}, + {0x10030, 0x00027003}, + {0x10030, 0x00028000}, + {0x10030, 0x00029000}, + {0x10030, 0x0002A000}, + {0x10030, 0x0002B000}, + {0x10030, 0x0002C000}, + {0x10030, 0x0002D000}, + {0x10030, 0x0002E003}, + {0x10030, 0x0002F003}, + {0x10030, 0x00030000}, + {0x10030, 0x00031000}, + {0x10030, 0x00032000}, + {0x10030, 0x00033000}, + {0x10030, 0x00034000}, + {0x10030, 0x00035000}, + {0x10030, 0x00036003}, + {0x10030, 0x00037003}, + {0x10030, 0x00038000}, + {0x10030, 0x00039000}, + {0x10030, 0x0003A000}, + {0x10030, 0x0003B000}, + {0x10030, 0x0003C000}, + {0x10030, 0x0003D000}, + {0x10030, 0x0003E003}, + {0x10030, 0x0003F003}, + {0x10030, 0x00060000}, + {0x10030, 0x00061000}, + {0x10030, 0x00062000}, + {0x10030, 0x00063000}, + {0x10030, 0x00064000}, + {0x10030, 0x00065000}, + {0x10030, 0x00066000}, + {0x10030, 0x00067003}, + {0x10030, 0x00068000}, + {0x10030, 0x00069000}, + {0x10030, 0x0006A000}, + {0x10030, 0x0006B000}, + {0x10030, 0x0006C000}, + {0x10030, 0x0006D000}, + {0x10030, 0x0006E000}, + {0x10030, 0x0006F003}, + {0x10030, 0x00070000}, + {0x10030, 0x00071000}, + {0x10030, 0x00072000}, + {0x10030, 0x00073000}, + {0x10030, 0x00074000}, + {0x10030, 0x00075000}, + {0x10030, 0x00076000}, + {0x10030, 0x00077003}, + {0x10030, 0x00078000}, + {0x10030, 0x00079000}, + {0x10030, 0x0007A000}, + {0x10030, 0x0007B000}, + {0x10030, 0x0007C000}, + {0x10030, 0x0007D000}, + {0x10030, 0x0007E000}, + {0x10030, 0x0007F003}, + {0x0ED, 0x00000010}, + {0x033, 0x00000001}, + {0x03F, 0x0000000A}, + {0x033, 0x00000002}, + {0x03F, 0x0000000A}, + {0x033, 0x00000003}, + {0x03F, 0x0000000A}, + {0x033, 0x00000005}, + {0x03F, 0x0000000A}, + {0x033, 0x00000006}, + {0x03F, 0x0000000A}, + {0x033, 0x00000007}, + {0x03F, 0x0000000A}, + {0x0ED, 0x00000000}, + {0x100EE, 0x00000000}, + {0x0FE, 0x00000031}, +}; + +static const struct rtw89_reg2_def rtw89_8852c_phy_nctl_regs[] = { + {0x8008, 0x00000000}, + {0x8000, 0x00000008}, + {0x8004, 0xf0862966}, + {0x800c, 0x78000000}, + {0x8010, 0x88015000}, + {0x8014, 0x80010100}, + {0x8018, 0x10010100}, + {0x801c, 0xa210bc00}, + {0x8020, 0x000403e0}, + {0x8024, 0x00072160}, + {0x8028, 0x00180e00}, + {0x8030, 0x400000c0}, + {0x8034, 0x11000830}, + {0x8038, 0x00000009}, + {0x803c, 0x00000008}, + {0x8040, 0x00000046}, + {0x8044, 0x0010001f}, + {0x8048, 0xf0000003}, + {0x804c, 0x62ac6162}, + {0x8050, 0xf2acf162}, + {0x8054, 0x62ac6162}, + {0x8058, 0xf2acf162}, + {0x805c, 0x150c0b02}, + {0x8060, 0x150c0b02}, + {0x8064, 0x2aa00047}, + {0x8074, 0x80000000}, + {0x807c, 0x000000ee}, + {0x8088, 0x80000000}, + {0x808c, 0x00000000}, + {0x80b0, 0x00000000}, + {0x80d0, 0x00000000}, + {0x80ec, 0x00000002}, + {0x8098, 0x0000ff00}, + {0x8070, 0x00e80000}, + {0x80b0, 0xffe00fff}, + {0x809c, 0x0000001f}, + {0x80b8, 0x00001000}, + {0x80bc, 0x0005001d}, + {0x810c, 0x33112211}, + {0x8110, 0x33112211}, + {0x8114, 0x00000000}, + {0x8120, 0x10010000}, + {0x8124, 0x00000000}, + {0x8128, 0x00000200}, + {0x812c, 0x0000c000}, + {0x8138, 0x40000000}, + {0x813c, 0x40000000}, + {0x8140, 0x00000000}, + {0x8144, 0x0b040b03}, + {0x8148, 0x0a040b04}, + {0x814c, 0x0a040b04}, + {0x8150, 0xe4e40000}, + {0x8158, 0xffffffff}, + {0x815c, 0xffffffff}, + {0x8160, 0xffffffff}, + {0x8164, 0xffffffff}, + {0x8168, 0xffffffff}, + {0x816c, 0x1fffffff}, + {0x81cc, 0x00000000}, + {0x81dc, 0x00000002}, + {0x81e0, 0x00000000}, + {0x81e4, 0x00000001}, + {0x81a0, 0x00000000}, + {0x81ac, 0x3fc20400}, + {0x81b0, 0x3f914100}, + {0x81bc, 0x0000005b}, + {0x81c0, 0x0000005b}, + {0x81b4, 0x01e0f078}, + {0x81b8, 0x01e0f078}, + {0x81f0, 0x0000f078}, + {0x820c, 0x33112211}, + {0x8210, 0x33112211}, + {0x8214, 0x00000000}, + {0x8220, 0x10010000}, + {0x8224, 0x00000000}, + {0x8228, 0x00000200}, + {0x822c, 0x0000d000}, + {0x8238, 0x40000000}, + {0x823c, 0x40000000}, + {0x8240, 0x00000000}, + {0x8244, 0x0b040b03}, + {0x8248, 0x0a040b04}, + {0x824c, 0x0a040b04}, + {0x8250, 0xe4e40000}, + {0x8258, 0xffffffff}, + {0x825c, 0xffffffff}, + {0x8260, 0xffffffff}, + {0x8264, 0xffffffff}, + {0x8268, 0xffffffff}, + {0x826c, 0x1fffffff}, + {0x82cc, 0x00000000}, + {0x82dc, 0x00000002}, + {0x82e0, 0x00100000}, + {0x82e4, 0x00000001}, + {0x82a0, 0x00000000}, + {0x82ac, 0x3fc20400}, + {0x82b0, 0x3f914100}, + {0x82bc, 0x0000005b}, + {0x82c0, 0x0000005b}, + {0x82b4, 0x01e0f078}, + {0x82b8, 0x01e0f078}, + {0x82f0, 0x0000f078}, + {0x81d8, 0x00000001}, + {0x82d8, 0x00000001}, + {0x9500, 0x00000000}, + {0x9504, 0x00000000}, + {0x9508, 0x00000000}, + {0x950c, 0x00000000}, + {0x9510, 0x00000000}, + {0x9514, 0x00000000}, + {0x9518, 0x00000000}, + {0x951c, 0x00000000}, + {0x9520, 0x00000000}, + {0x9524, 0x00000000}, + {0x9528, 0x00000000}, + {0x952c, 0x00000000}, + {0x9530, 0x00000000}, + {0x9534, 0x00000000}, + {0x9538, 0x00000000}, + {0x953c, 0x00000000}, + {0x9540, 0x04000000}, + {0x9544, 0x00000000}, + {0x9548, 0x00000000}, + {0x954c, 0x00000000}, + {0x9550, 0x00000000}, + {0x9554, 0x00000000}, + {0x9558, 0x00000000}, + {0x955c, 0x00000000}, + {0x9560, 0x00000000}, + {0x9564, 0x00000000}, + {0x9568, 0x00000000}, + {0x956c, 0x00000000}, + {0x9570, 0x00000000}, + {0x9574, 0x00000000}, + {0x9578, 0x00000000}, + {0x957c, 0x00000000}, + {0x9580, 0x00000000}, + {0x9584, 0x04000000}, + {0x9588, 0x00000000}, + {0x958c, 0x00000000}, + {0x9590, 0x00000000}, + {0x9594, 0x00000000}, + {0x9598, 0x00000000}, + {0x959c, 0x00000000}, + {0x95a0, 0x00000000}, + {0x95a4, 0x00000000}, + {0x95a8, 0x00000000}, + {0x95ac, 0x00000000}, + {0x95b0, 0x00000000}, + {0x95b4, 0x00000000}, + {0x95b8, 0x00000000}, + {0x95bc, 0x00000000}, + {0x95c0, 0x00000000}, + {0x95c4, 0x00000000}, + {0x95c8, 0x04000000}, + {0x95cc, 0x00000000}, + {0x95d0, 0x00000000}, + {0x95d4, 0x00000000}, + {0x95d8, 0x00000000}, + {0x95dc, 0x00000000}, + {0x95e0, 0x00000000}, + {0x95e4, 0x00000000}, + {0x95e8, 0x00000000}, + {0x95ec, 0x00000000}, + {0x95f0, 0x00000000}, + {0x95f4, 0x00000000}, + {0x95f8, 0x00000000}, + {0x95fc, 0x00000000}, + {0x9600, 0x00000000}, + {0x9604, 0x00000000}, + {0x9608, 0x00000000}, + {0x960c, 0x04000000}, + {0x9610, 0x00000000}, + {0x9614, 0x00000000}, + {0x9618, 0x00000000}, + {0x961c, 0x00000000}, + {0x9620, 0x00000000}, + {0x9624, 0x00000000}, + {0x9628, 0x00000000}, + {0x962c, 0x00000000}, + {0x9630, 0x00000000}, + {0x9634, 0x00000000}, + {0x9638, 0x00000000}, + {0x963c, 0x00000000}, + {0x9640, 0x00000000}, + {0x9644, 0x00000000}, + {0x9648, 0x00000000}, + {0x964c, 0x00000000}, + {0x9650, 0x04000000}, + {0x9654, 0x00000000}, + {0x9658, 0x00000000}, + {0x965c, 0x00000000}, + {0x9660, 0x00000000}, + {0x9664, 0x00000000}, + {0x9668, 0x00000000}, + {0x966c, 0x00000000}, + {0x9670, 0x00000000}, + {0x9674, 0x00000000}, + {0x9678, 0x00000000}, + {0x967c, 0x00000000}, + {0x9680, 0x00000000}, + {0x9684, 0x00000000}, + {0x9688, 0x00000000}, + {0x968c, 0x00000000}, + {0x9690, 0x00000000}, + {0x9694, 0x04000000}, + {0x9698, 0x00000000}, + {0x969c, 0x00000000}, + {0x96a0, 0x00000000}, + {0x96a4, 0x00000000}, + {0x96a8, 0x00000000}, + {0x96ac, 0x00000000}, + {0x96b0, 0x00000000}, + {0x96b4, 0x00000000}, + {0x96b8, 0x00000000}, + {0x96bc, 0x00000000}, + {0x96c0, 0x00000000}, + {0x96c4, 0x00000000}, + {0x96c8, 0x00000000}, + {0x96cc, 0x00000000}, + {0x96d0, 0x00000000}, + {0x96d4, 0x00000000}, + {0x96d8, 0x04000000}, + {0x96dc, 0x00000000}, + {0x96e0, 0x00000000}, + {0x96e4, 0x00000000}, + {0x96e8, 0x00000000}, + {0x96ec, 0x00000000}, + {0x96f0, 0x00000000}, + {0x96f4, 0x00000000}, + {0x96f8, 0x00000000}, + {0x96fc, 0x00000000}, + {0x9700, 0x00000000}, + {0x9704, 0x00000000}, + {0x9708, 0x00000000}, + {0x970c, 0x00000000}, + {0x9710, 0x00000000}, + {0x9714, 0x00000000}, + {0x9718, 0x00000000}, + {0x971c, 0x04000000}, + {0x9720, 0x00000000}, + {0x9724, 0x00000000}, + {0x9728, 0x00000000}, + {0x972c, 0x00000000}, + {0x9730, 0x00000000}, + {0x9734, 0x00000000}, + {0x9738, 0x00000000}, + {0x973c, 0x00000000}, + {0x9740, 0x00000000}, + {0x9744, 0x00000000}, + {0x9748, 0x00000000}, + {0x974c, 0x00000000}, + {0x9750, 0x00000000}, + {0x9754, 0x00000000}, + {0x9758, 0x00000000}, + {0x975c, 0x00000000}, + {0x9760, 0x04000000}, + {0x9764, 0x00000000}, + {0x9768, 0x00000000}, + {0x976c, 0x00000000}, + {0x9770, 0x00000000}, + {0x9774, 0x00000000}, + {0x9778, 0x00000000}, + {0x977c, 0x00000000}, + {0x9780, 0x00000000}, + {0x9784, 0x00000000}, + {0x9788, 0x00000000}, + {0x978c, 0x00000000}, + {0x9790, 0x00000000}, + {0x9794, 0x00000000}, + {0x9798, 0x00000000}, + {0x979c, 0x00000000}, + {0x97a0, 0x00000000}, + {0x97a4, 0x04000000}, + {0x97a8, 0x00000000}, + {0x97ac, 0x00000000}, + {0x97b0, 0x00000000}, + {0x97b4, 0x00000000}, + {0x97b8, 0x00000000}, + {0x97bc, 0x00000000}, + {0x97c0, 0x00000000}, + {0x97c4, 0x00000000}, + {0x97c8, 0x00000000}, + {0x97cc, 0x00000000}, + {0x97d0, 0x00000000}, + {0x97d4, 0x00000000}, + {0x97d8, 0x00000000}, + {0x97dc, 0x00000000}, + {0x97e0, 0x00000000}, + {0x97e4, 0x00000000}, + {0x97e8, 0x04000000}, + {0x97ec, 0x00000000}, + {0x97f0, 0x00000000}, + {0x97f4, 0x00000000}, + {0x97f8, 0x00000000}, + {0x97fc, 0x00000000}, + {0x9800, 0x00000000}, + {0x9804, 0x00000000}, + {0x9808, 0x00000000}, + {0x980c, 0x00000000}, + {0x9810, 0x00000000}, + {0x9814, 0x00000000}, + {0x9818, 0x00000000}, + {0x981c, 0x00000000}, + {0x9820, 0x00000000}, + {0x9824, 0x00000000}, + {0x9828, 0x00000000}, + {0x982c, 0x04000000}, + {0x9830, 0x00000000}, + {0x9834, 0x00000000}, + {0x9838, 0x00000000}, + {0x983c, 0x00000000}, + {0x9840, 0x00000000}, + {0x9844, 0x00000000}, + {0x9848, 0x00000000}, + {0x984c, 0x00000000}, + {0x9850, 0x00000000}, + {0x9854, 0x00000000}, + {0x9858, 0x00000000}, + {0x985c, 0x00000000}, + {0x9860, 0x00000000}, + {0x9864, 0x00000000}, + {0x9868, 0x00000000}, + {0x986c, 0x00000000}, + {0x9870, 0x04000000}, + {0x9874, 0x00000000}, + {0x9878, 0x00000000}, + {0x987c, 0x00000000}, + {0x9880, 0x00000000}, + {0x9884, 0x00000000}, + {0x9888, 0x00000000}, + {0x988c, 0x00000000}, + {0x9890, 0x00000000}, + {0x9894, 0x00000000}, + {0x9898, 0x00000000}, + {0x989c, 0x00000000}, + {0x98a0, 0x00000000}, + {0x98a4, 0x00000000}, + {0x98a8, 0x00000000}, + {0x98ac, 0x00000000}, + {0x98b0, 0x00000000}, + {0x98b4, 0x04000000}, + {0x98b8, 0x00000000}, + {0x98bc, 0x00000000}, + {0x98c0, 0x00000000}, + {0x98c4, 0x00000000}, + {0x98c8, 0x00000000}, + {0x98cc, 0x00000000}, + {0x98d0, 0x00000000}, + {0x98d4, 0x00000000}, + {0x98d8, 0x00000000}, + {0x98dc, 0x00000000}, + {0x98e0, 0x00000000}, + {0x98e4, 0x00000000}, + {0x98e8, 0x00000000}, + {0x98ec, 0x00000000}, + {0x98f0, 0x00000000}, + {0x98f4, 0x00000000}, + {0x98f8, 0x04000000}, + {0x98fc, 0x00000000}, + {0x9900, 0x00000000}, + {0x9904, 0x00000000}, + {0x9908, 0x00000000}, + {0x990c, 0x00000000}, + {0x9910, 0x00000000}, + {0x9914, 0x00000000}, + {0x9918, 0x00000000}, + {0x991c, 0x00000000}, + {0x9920, 0x00000000}, + {0x9924, 0x00000000}, + {0x9928, 0x00000000}, + {0x992c, 0x00000000}, + {0x9930, 0x00000000}, + {0x9934, 0x00000000}, + {0x9938, 0x00000000}, + {0x993c, 0x04000000}, + {0x9940, 0x00000000}, + {0x9944, 0x00000000}, + {0x9948, 0x00000000}, + {0x994c, 0x00000000}, + {0x9950, 0x00000000}, + {0x9954, 0x00000000}, + {0x9958, 0x00000000}, + {0x995c, 0x00000000}, + {0x9960, 0x00000000}, + {0x9964, 0x00000000}, + {0x9968, 0x00000000}, + {0x996c, 0x00000000}, + {0x9970, 0x00000000}, + {0x9974, 0x00000000}, + {0x9978, 0x00000000}, + {0x997c, 0x00000000}, + {0x9980, 0x04000000}, + {0x9984, 0x00000000}, + {0x9988, 0x00000000}, + {0x998c, 0x00000000}, + {0x9990, 0x00000000}, + {0x9994, 0x00000000}, + {0x9998, 0x00000000}, + {0x999c, 0x00000000}, + {0x99a0, 0x00000000}, + {0x99a4, 0x00000000}, + {0x99a8, 0x00000000}, + {0x99ac, 0x00000000}, + {0x99b0, 0x00000000}, + {0x99b4, 0x00000000}, + {0x99b8, 0x00000000}, + {0x99bc, 0x00000000}, + {0x99c0, 0x00000000}, + {0x99c4, 0x04000000}, + {0x99c8, 0x00000000}, + {0x99cc, 0x00000000}, + {0x99d0, 0x00000000}, + {0x99d4, 0x00000000}, + {0x99d8, 0x00000000}, + {0x99dc, 0x00000000}, + {0x99e0, 0x00000000}, + {0x99e4, 0x00000000}, + {0x99e8, 0x00000000}, + {0x99ec, 0x00000000}, + {0x99f0, 0x00000000}, + {0x99f4, 0x00000000}, + {0x99f8, 0x00000000}, + {0x99fc, 0x00000000}, + {0x9a00, 0x00000000}, + {0x9a04, 0x00000000}, + {0x9a08, 0x04000000}, + {0x9a0c, 0x00000000}, + {0x9a10, 0x00000000}, + {0x9a14, 0x00000000}, + {0x9a18, 0x00000000}, + {0x9a1c, 0x00000000}, + {0x9a20, 0x00000000}, + {0x9a24, 0x00000000}, + {0x9a28, 0x00000000}, + {0x9a2c, 0x00000000}, + {0x9a30, 0x00000000}, + {0x9a34, 0x00000000}, + {0x9a38, 0x00000000}, + {0x9a3c, 0x00000000}, + {0x9a40, 0x00000000}, + {0x9a44, 0x00000000}, + {0x9a48, 0x00000000}, + {0x9a4c, 0x04000000}, + {0x9a50, 0x00000000}, + {0x9a54, 0x00000000}, + {0x9a58, 0x00000000}, + {0x9a5c, 0x00000000}, + {0x9a60, 0x00000000}, + {0x9a64, 0x00000000}, + {0x9a68, 0x00000000}, + {0x9a6c, 0x00000000}, + {0x9a70, 0x00000000}, + {0x9a74, 0x00000000}, + {0x9a78, 0x00000000}, + {0x9a7c, 0x00000000}, + {0x9a80, 0x00000000}, + {0x9a84, 0x00000000}, + {0x9a88, 0x00000000}, + {0x9a8c, 0x00000000}, + {0x9a90, 0x04000000}, + {0x9a94, 0x00000000}, + {0x9a98, 0x00000000}, + {0x9a9c, 0x00000000}, + {0x9aa0, 0x00000000}, + {0x9aa4, 0x00000000}, + {0x9aa8, 0x00000000}, + {0x9aac, 0x00000000}, + {0x9ab0, 0x00000000}, + {0x9ab4, 0x00000000}, + {0x9ab8, 0x00000000}, + {0x9abc, 0x00000000}, + {0x9ac0, 0x00000000}, + {0x9ac4, 0x00000000}, + {0x9ac8, 0x00000000}, + {0x9acc, 0x00000000}, + {0x9ad0, 0x00000000}, + {0x9ad4, 0x04000000}, + {0x9ad8, 0x00000000}, + {0x9adc, 0x00000000}, + {0x9ae0, 0x00000000}, + {0x9ae4, 0x00000000}, + {0x9ae8, 0x00000000}, + {0x9aec, 0x00000000}, + {0x9af0, 0x00000000}, + {0x9af4, 0x00000000}, + {0x9af8, 0x00000000}, + {0x9afc, 0x00000000}, + {0x9b00, 0x00000000}, + {0x9b04, 0x00000000}, + {0x9b08, 0x00000000}, + {0x9b0c, 0x00000000}, + {0x9b10, 0x00000000}, + {0x9b14, 0x00000000}, + {0x9b18, 0x04000000}, + {0x9b1c, 0x00000000}, + {0x9b20, 0x00000000}, + {0x9b24, 0x00000000}, + {0x9b28, 0x00000000}, + {0x9b2c, 0x00000000}, + {0x9b30, 0x00000000}, + {0x9b34, 0x00000000}, + {0x9b38, 0x00000000}, + {0x9b3c, 0x00000000}, + {0x9b40, 0x00000000}, + {0x9b44, 0x00000000}, + {0x9b48, 0x00000000}, + {0x9b4c, 0x00000000}, + {0x9b50, 0x00000000}, + {0x9b54, 0x00000000}, + {0x9b58, 0x00000000}, + {0x9b5c, 0x04000000}, + {0x9d00, 0x00000000}, + {0x9d04, 0x00000000}, + {0x9d08, 0x00000000}, + {0x9d0c, 0x00000000}, + {0x9d10, 0x00000000}, + {0x9d14, 0x00000000}, + {0x9d18, 0x00000000}, + {0x9d1c, 0x00000000}, + {0x9d20, 0x00000000}, + {0x9d24, 0x00000000}, + {0x9d28, 0x00000000}, + {0x9d2c, 0x00000000}, + {0x9d30, 0x00000000}, + {0x9d34, 0x00000000}, + {0x9d38, 0x00000000}, + {0x9d3c, 0x00000000}, + {0x9d40, 0x04000000}, + {0x9d44, 0x00000000}, + {0x9d48, 0x00000000}, + {0x9d4c, 0x00000000}, + {0x9d50, 0x00000000}, + {0x9d54, 0x00000000}, + {0x9d58, 0x00000000}, + {0x9d5c, 0x00000000}, + {0x9d60, 0x00000000}, + {0x9d64, 0x00000000}, + {0x9d68, 0x00000000}, + {0x9d6c, 0x00000000}, + {0x9d70, 0x00000000}, + {0x9d74, 0x00000000}, + {0x9d78, 0x00000000}, + {0x9d7c, 0x00000000}, + {0x9d80, 0x00000000}, + {0x9d84, 0x04000000}, + {0x9d88, 0x00000000}, + {0x9d8c, 0x00000000}, + {0x9d90, 0x00000000}, + {0x9d94, 0x00000000}, + {0x9d98, 0x00000000}, + {0x9d9c, 0x00000000}, + {0x9da0, 0x00000000}, + {0x9da4, 0x00000000}, + {0x9da8, 0x00000000}, + {0x9dac, 0x00000000}, + {0x9db0, 0x00000000}, + {0x9db4, 0x00000000}, + {0x9db8, 0x00000000}, + {0x9dbc, 0x00000000}, + {0x9dc0, 0x00000000}, + {0x9dc4, 0x00000000}, + {0x9dc8, 0x04000000}, + {0x9dcc, 0x00000000}, + {0x9dd0, 0x00000000}, + {0x9dd4, 0x00000000}, + {0x9dd8, 0x00000000}, + {0x9ddc, 0x00000000}, + {0x9de0, 0x00000000}, + {0x9de4, 0x00000000}, + {0x9de8, 0x00000000}, + {0x9dec, 0x00000000}, + {0x9df0, 0x00000000}, + {0x9df4, 0x00000000}, + {0x9df8, 0x00000000}, + {0x9dfc, 0x00000000}, + {0x9e00, 0x00000000}, + {0x9e04, 0x00000000}, + {0x9e08, 0x00000000}, + {0x9e0c, 0x04000000}, + {0x9e10, 0x00000000}, + {0x9e14, 0x00000000}, + {0x9e18, 0x00000000}, + {0x9e1c, 0x00000000}, + {0x9e20, 0x00000000}, + {0x9e24, 0x00000000}, + {0x9e28, 0x00000000}, + {0x9e2c, 0x00000000}, + {0x9e30, 0x00000000}, + {0x9e34, 0x00000000}, + {0x9e38, 0x00000000}, + {0x9e3c, 0x00000000}, + {0x9e40, 0x00000000}, + {0x9e44, 0x00000000}, + {0x9e48, 0x00000000}, + {0x9e4c, 0x00000000}, + {0x9e50, 0x04000000}, + {0x9e54, 0x00000000}, + {0x9e58, 0x00000000}, + {0x9e5c, 0x00000000}, + {0x9e60, 0x00000000}, + {0x9e64, 0x00000000}, + {0x9e68, 0x00000000}, + {0x9e6c, 0x00000000}, + {0x9e70, 0x00000000}, + {0x9e74, 0x00000000}, + {0x9e78, 0x00000000}, + {0x9e7c, 0x00000000}, + {0x9e80, 0x00000000}, + {0x9e84, 0x00000000}, + {0x9e88, 0x00000000}, + {0x9e8c, 0x00000000}, + {0x9e90, 0x00000000}, + {0x9e94, 0x04000000}, + {0x9e98, 0x00000000}, + {0x9e9c, 0x00000000}, + {0x9ea0, 0x00000000}, + {0x9ea4, 0x00000000}, + {0x9ea8, 0x00000000}, + {0x9eac, 0x00000000}, + {0x9eb0, 0x00000000}, + {0x9eb4, 0x00000000}, + {0x9eb8, 0x00000000}, + {0x9ebc, 0x00000000}, + {0x9ec0, 0x00000000}, + {0x9ec4, 0x00000000}, + {0x9ec8, 0x00000000}, + {0x9ecc, 0x00000000}, + {0x9ed0, 0x00000000}, + {0x9ed4, 0x00000000}, + {0x9ed8, 0x04000000}, + {0x9edc, 0x00000000}, + {0x9ee0, 0x00000000}, + {0x9ee4, 0x00000000}, + {0x9ee8, 0x00000000}, + {0x9eec, 0x00000000}, + {0x9ef0, 0x00000000}, + {0x9ef4, 0x00000000}, + {0x9ef8, 0x00000000}, + {0x9efc, 0x00000000}, + {0x9f00, 0x00000000}, + {0x9f04, 0x00000000}, + {0x9f08, 0x00000000}, + {0x9f0c, 0x00000000}, + {0x9f10, 0x00000000}, + {0x9f14, 0x00000000}, + {0x9f18, 0x00000000}, + {0x9f1c, 0x04000000}, + {0x9f20, 0x00000000}, + {0x9f24, 0x00000000}, + {0x9f28, 0x00000000}, + {0x9f2c, 0x00000000}, + {0x9f30, 0x00000000}, + {0x9f34, 0x00000000}, + {0x9f38, 0x00000000}, + {0x9f3c, 0x00000000}, + {0x9f40, 0x00000000}, + {0x9f44, 0x00000000}, + {0x9f48, 0x00000000}, + {0x9f4c, 0x00000000}, + {0x9f50, 0x00000000}, + {0x9f54, 0x00000000}, + {0x9f58, 0x00000000}, + {0x9f5c, 0x00000000}, + {0x9f60, 0x04000000}, + {0x9f64, 0x00000000}, + {0x9f68, 0x00000000}, + {0x9f6c, 0x00000000}, + {0x9f70, 0x00000000}, + {0x9f74, 0x00000000}, + {0x9f78, 0x00000000}, + {0x9f7c, 0x00000000}, + {0x9f80, 0x00000000}, + {0x9f84, 0x00000000}, + {0x9f88, 0x00000000}, + {0x9f8c, 0x00000000}, + {0x9f90, 0x00000000}, + {0x9f94, 0x00000000}, + {0x9f98, 0x00000000}, + {0x9f9c, 0x00000000}, + {0x9fa0, 0x00000000}, + {0x9fa4, 0x04000000}, + {0x9fa8, 0x00000000}, + {0x9fac, 0x00000000}, + {0x9fb0, 0x00000000}, + {0x9fb4, 0x00000000}, + {0x9fb8, 0x00000000}, + {0x9fbc, 0x00000000}, + {0x9fc0, 0x00000000}, + {0x9fc4, 0x00000000}, + {0x9fc8, 0x00000000}, + {0x9fcc, 0x00000000}, + {0x9fd0, 0x00000000}, + {0x9fd4, 0x00000000}, + {0x9fd8, 0x00000000}, + {0x9fdc, 0x00000000}, + {0x9fe0, 0x00000000}, + {0x9fe4, 0x00000000}, + {0x9fe8, 0x04000000}, + {0x9fec, 0x00000000}, + {0x9ff0, 0x00000000}, + {0x9ff4, 0x00000000}, + {0x9ff8, 0x00000000}, + {0x9ffc, 0x00000000}, + {0xa000, 0x00000000}, + {0xa004, 0x00000000}, + {0xa008, 0x00000000}, + {0xa00c, 0x00000000}, + {0xa010, 0x00000000}, + {0xa014, 0x00000000}, + {0xa018, 0x00000000}, + {0xa01c, 0x00000000}, + {0xa020, 0x00000000}, + {0xa024, 0x00000000}, + {0xa028, 0x00000000}, + {0xa02c, 0x04000000}, + {0xa030, 0x00000000}, + {0xa034, 0x00000000}, + {0xa038, 0x00000000}, + {0xa03c, 0x00000000}, + {0xa040, 0x00000000}, + {0xa044, 0x00000000}, + {0xa048, 0x00000000}, + {0xa04c, 0x00000000}, + {0xa050, 0x00000000}, + {0xa054, 0x00000000}, + {0xa058, 0x00000000}, + {0xa05c, 0x00000000}, + {0xa060, 0x00000000}, + {0xa064, 0x00000000}, + {0xa068, 0x00000000}, + {0xa06c, 0x00000000}, + {0xa070, 0x04000000}, + {0xa074, 0x00000000}, + {0xa078, 0x00000000}, + {0xa07c, 0x00000000}, + {0xa080, 0x00000000}, + {0xa084, 0x00000000}, + {0xa088, 0x00000000}, + {0xa08c, 0x00000000}, + {0xa090, 0x00000000}, + {0xa094, 0x00000000}, + {0xa098, 0x00000000}, + {0xa09c, 0x00000000}, + {0xa0a0, 0x00000000}, + {0xa0a4, 0x00000000}, + {0xa0a8, 0x00000000}, + {0xa0ac, 0x00000000}, + {0xa0b0, 0x00000000}, + {0xa0b4, 0x04000000}, + {0xa0b8, 0x00000000}, + {0xa0bc, 0x00000000}, + {0xa0c0, 0x00000000}, + {0xa0c4, 0x00000000}, + {0xa0c8, 0x00000000}, + {0xa0cc, 0x00000000}, + {0xa0d0, 0x00000000}, + {0xa0d4, 0x00000000}, + {0xa0d8, 0x00000000}, + {0xa0dc, 0x00000000}, + {0xa0e0, 0x00000000}, + {0xa0e4, 0x00000000}, + {0xa0e8, 0x00000000}, + {0xa0ec, 0x00000000}, + {0xa0f0, 0x00000000}, + {0xa0f4, 0x00000000}, + {0xa0f8, 0x04000000}, + {0xa0fc, 0x00000000}, + {0xa100, 0x00000000}, + {0xa104, 0x00000000}, + {0xa108, 0x00000000}, + {0xa10c, 0x00000000}, + {0xa110, 0x00000000}, + {0xa114, 0x00000000}, + {0xa118, 0x00000000}, + {0xa11c, 0x00000000}, + {0xa120, 0x00000000}, + {0xa124, 0x00000000}, + {0xa128, 0x00000000}, + {0xa12c, 0x00000000}, + {0xa130, 0x00000000}, + {0xa134, 0x00000000}, + {0xa138, 0x00000000}, + {0xa13c, 0x04000000}, + {0xa140, 0x00000000}, + {0xa144, 0x00000000}, + {0xa148, 0x00000000}, + {0xa14c, 0x00000000}, + {0xa150, 0x00000000}, + {0xa154, 0x00000000}, + {0xa158, 0x00000000}, + {0xa15c, 0x00000000}, + {0xa160, 0x00000000}, + {0xa164, 0x00000000}, + {0xa168, 0x00000000}, + {0xa16c, 0x00000000}, + {0xa170, 0x00000000}, + {0xa174, 0x00000000}, + {0xa178, 0x00000000}, + {0xa17c, 0x00000000}, + {0xa180, 0x04000000}, + {0xa184, 0x00000000}, + {0xa188, 0x00000000}, + {0xa18c, 0x00000000}, + {0xa190, 0x00000000}, + {0xa194, 0x00000000}, + {0xa198, 0x00000000}, + {0xa19c, 0x00000000}, + {0xa1a0, 0x00000000}, + {0xa1a4, 0x00000000}, + {0xa1a8, 0x00000000}, + {0xa1ac, 0x00000000}, + {0xa1b0, 0x00000000}, + {0xa1b4, 0x00000000}, + {0xa1b8, 0x00000000}, + {0xa1bc, 0x00000000}, + {0xa1c0, 0x00000000}, + {0xa1c4, 0x04000000}, + {0xa1c8, 0x00000000}, + {0xa1cc, 0x00000000}, + {0xa1d0, 0x00000000}, + {0xa1d4, 0x00000000}, + {0xa1d8, 0x00000000}, + {0xa1dc, 0x00000000}, + {0xa1e0, 0x00000000}, + {0xa1e4, 0x00000000}, + {0xa1e8, 0x00000000}, + {0xa1ec, 0x00000000}, + {0xa1f0, 0x00000000}, + {0xa1f4, 0x00000000}, + {0xa1f8, 0x00000000}, + {0xa1fc, 0x00000000}, + {0xa200, 0x00000000}, + {0xa204, 0x00000000}, + {0xa208, 0x04000000}, + {0xa20c, 0x00000000}, + {0xa210, 0x00000000}, + {0xa214, 0x00000000}, + {0xa218, 0x00000000}, + {0xa21c, 0x00000000}, + {0xa220, 0x00000000}, + {0xa224, 0x00000000}, + {0xa228, 0x00000000}, + {0xa22c, 0x00000000}, + {0xa230, 0x00000000}, + {0xa234, 0x00000000}, + {0xa238, 0x00000000}, + {0xa23c, 0x00000000}, + {0xa240, 0x00000000}, + {0xa244, 0x00000000}, + {0xa248, 0x00000000}, + {0xa24c, 0x04000000}, + {0xa250, 0x00000000}, + {0xa254, 0x00000000}, + {0xa258, 0x00000000}, + {0xa25c, 0x00000000}, + {0xa260, 0x00000000}, + {0xa264, 0x00000000}, + {0xa268, 0x00000000}, + {0xa26c, 0x00000000}, + {0xa270, 0x00000000}, + {0xa274, 0x00000000}, + {0xa278, 0x00000000}, + {0xa27c, 0x00000000}, + {0xa280, 0x00000000}, + {0xa284, 0x00000000}, + {0xa288, 0x00000000}, + {0xa28c, 0x00000000}, + {0xa290, 0x04000000}, + {0xa294, 0x00000000}, + {0xa298, 0x00000000}, + {0xa29c, 0x00000000}, + {0xa2a0, 0x00000000}, + {0xa2a4, 0x00000000}, + {0xa2a8, 0x00000000}, + {0xa2ac, 0x00000000}, + {0xa2b0, 0x00000000}, + {0xa2b4, 0x00000000}, + {0xa2b8, 0x00000000}, + {0xa2bc, 0x00000000}, + {0xa2c0, 0x00000000}, + {0xa2c4, 0x00000000}, + {0xa2c8, 0x00000000}, + {0xa2cc, 0x00000000}, + {0xa2d0, 0x00000000}, + {0xa2d4, 0x04000000}, + {0xa2d8, 0x00000000}, + {0xa2dc, 0x00000000}, + {0xa2e0, 0x00000000}, + {0xa2e4, 0x00000000}, + {0xa2e8, 0x00000000}, + {0xa2ec, 0x00000000}, + {0xa2f0, 0x00000000}, + {0xa2f4, 0x00000000}, + {0xa2f8, 0x00000000}, + {0xa2fc, 0x00000000}, + {0xa300, 0x00000000}, + {0xa304, 0x00000000}, + {0xa308, 0x00000000}, + {0xa30c, 0x00000000}, + {0xa310, 0x00000000}, + {0xa314, 0x00000000}, + {0xa318, 0x04000000}, + {0xa31c, 0x00000000}, + {0xa320, 0x00000000}, + {0xa324, 0x00000000}, + {0xa328, 0x00000000}, + {0xa32c, 0x00000000}, + {0xa330, 0x00000000}, + {0xa334, 0x00000000}, + {0xa338, 0x00000000}, + {0xa33c, 0x00000000}, + {0xa340, 0x00000000}, + {0xa344, 0x00000000}, + {0xa348, 0x00000000}, + {0xa34c, 0x00000000}, + {0xa350, 0x00000000}, + {0xa354, 0x00000000}, + {0xa358, 0x00000000}, + {0xa35c, 0x04000000}, + {0x81d8, 0x00000000}, + {0x82d8, 0x00000000}, + {0xb104, 0x2b251f19}, + {0xb108, 0x433d3731}, + {0xb10c, 0x5b554f49}, + {0xb110, 0x736d6761}, + {0xb114, 0x7f7f7f79}, + {0xb118, 0x120f7f7f}, + {0xb11c, 0x1e1b1815}, + {0xb120, 0x2a272421}, + {0xb124, 0x3633302d}, + {0xb128, 0x3f3f3c39}, + {0xb12c, 0x3f3f3f3f}, + {0x8088, 0x00000110}, + {0x8000, 0x00000008}, + {0x8080, 0x00000005}, + {0x8500, 0x80000008}, + {0x8504, 0x43000004}, + {0x8508, 0x4b044a00}, + {0x850c, 0x40098604}, + {0x8510, 0x0004e024}, + {0x8514, 0x87044b05}, + {0x8518, 0xe024400b}, + {0x851c, 0x4b000004}, + {0x8520, 0x21e07410}, + {0x8524, 0x16580000}, + {0x8528, 0x00047430}, + {0x852c, 0x00074380}, + {0x8530, 0x00044c00}, + {0x8534, 0x00074300}, + {0x8538, 0x00045603}, + {0x853c, 0x42fe5700}, + {0x8540, 0x42004000}, + {0x8544, 0x30005055}, + {0x8548, 0xa512b41c}, + {0x854c, 0xf02fe66f}, + {0x8550, 0xf22ff12f}, + {0x8554, 0xf42ff32f}, + {0x8558, 0xf62ff52f}, + {0x855c, 0xf82ff72f}, + {0x8560, 0xfa2ff92f}, + {0x8564, 0xfc2ffb2f}, + {0x8568, 0xfe2ffd2f}, + {0x856c, 0xe66fff2f}, + {0x8570, 0xf12ef02e}, + {0x8574, 0xf32ef22e}, + {0x8578, 0xf52ef42e}, + {0x857c, 0xff2ef62e}, + {0x8580, 0xa511000b}, + {0x8584, 0xf12cf02c}, + {0x8588, 0xf32cf22c}, + {0x858c, 0xf52cf42c}, + {0x8590, 0xf72cf62c}, + {0x8594, 0xf92cf82c}, + {0x8598, 0xfb2cfa2c}, + {0x859c, 0xfd2cfc2c}, + {0x85a0, 0xff2cfe2c}, + {0x85a4, 0xf12cf02c}, + {0x85a8, 0x0001f22c}, + {0x85ac, 0x30b330b3}, + {0x85b0, 0x310c3125}, + {0x85b4, 0x31253161}, + {0x85b8, 0x3081316f}, + {0x85bc, 0x317f3172}, + {0x85c0, 0x3192318c}, + {0x85c4, 0x32b832a6}, + {0x85c8, 0x31fd32c2}, + {0x85cc, 0x330732cc}, + {0x85d0, 0x33193343}, + {0x85d4, 0x331d3312}, + {0x85d8, 0x31663316}, + {0x85dc, 0x3365335b}, + {0x85e0, 0x3379336f}, + {0x85e4, 0x338d3383}, + {0x85e8, 0x33a13397}, + {0x85ec, 0x33b833ab}, + {0x85f0, 0x33d733c9}, + {0x85f4, 0x342333db}, + {0x85f8, 0x343c343b}, + {0x85fc, 0x3471346f}, + {0x8600, 0xe493347c}, + {0x8604, 0x20887410}, + {0x8608, 0x140f0200}, + {0x860c, 0x02002098}, + {0x8610, 0x20a8140f}, + {0x8614, 0x140f0200}, + {0x8618, 0xe4df7430}, + {0x861c, 0x74105b10}, + {0x8620, 0x000120a0}, + {0x8624, 0x140f140f}, + {0x8628, 0x56e15507}, + {0x862c, 0xe4c95c06}, + {0x8630, 0x20a87410}, + {0x8634, 0x140f0201}, + {0x8638, 0xe4c95517}, + {0x863c, 0x20a87410}, + {0x8640, 0x140f0200}, + {0x8644, 0x56c15517}, + {0x8648, 0xe4c95c02}, + {0x864c, 0x20a07410}, + {0x8650, 0x140f0000}, + {0x8654, 0x55071407}, + {0x8658, 0xe47ee4c9}, + {0x865c, 0x4686750a}, + {0x8660, 0xe159e4d3}, + {0x8664, 0xe4930001}, + {0x8668, 0x20a87410}, + {0x866c, 0x140f0200}, + {0x8670, 0x02002098}, + {0x8674, 0x2088140f}, + {0x8678, 0x140f0200}, + {0x867c, 0xe4df7430}, + {0x8680, 0x74105b10}, + {0x8684, 0x020120a8}, + {0x8688, 0x2080140f}, + {0x868c, 0x140f0000}, + {0x8690, 0x56615507}, + {0x8694, 0xe4c95c06}, + {0x8698, 0x20887410}, + {0x869c, 0x140f0200}, + {0x86a0, 0xe4c95517}, + {0x86a4, 0x20a87410}, + {0x86a8, 0x140f0200}, + {0x86ac, 0x56415517}, + {0x86b0, 0xe4c95c02}, + {0x86b4, 0x20807410}, + {0x86b8, 0x140f0000}, + {0x86bc, 0x55071407}, + {0x86c0, 0xe47ee4c9}, + {0x86c4, 0x468e7508}, + {0x86c8, 0xe159e4d3}, + {0x86cc, 0x5b10f025}, + {0x86d0, 0x20a87410}, + {0x86d4, 0x140f0201}, + {0x86d8, 0x00002090}, + {0x86dc, 0x5507140f}, + {0x86e0, 0x5c065661}, + {0x86e4, 0x7410e4c9}, + {0x86e8, 0x02002098}, + {0x86ec, 0x5517140f}, + {0x86f0, 0x7410e4c9}, + {0x86f4, 0x020020a8}, + {0x86f8, 0x5517140f}, + {0x86fc, 0x5c025641}, + {0x8700, 0x7410e4c9}, + {0x8704, 0x00002090}, + {0x8708, 0x5507140f}, + {0x870c, 0x7509e4c9}, + {0x8710, 0xe4d34696}, + {0x8714, 0x0001e159}, + {0x8718, 0x74105b10}, + {0x871c, 0x000020a0}, + {0x8720, 0x5507140f}, + {0x8724, 0xe4c95601}, + {0x8728, 0x20a87410}, + {0x872c, 0x140f0200}, + {0x8730, 0xe4c95517}, + {0x8734, 0x750ae47e}, + {0x8738, 0xe4d34686}, + {0x873c, 0x5500e159}, + {0x8740, 0x5501e4c5}, + {0x8744, 0xe4930001}, + {0x8748, 0x5b10e4df}, + {0x874c, 0x20807410}, + {0x8750, 0x140f0000}, + {0x8754, 0x02002098}, + {0x8758, 0xf205140f}, + {0x875c, 0x20a8f504}, + {0x8760, 0x140f0200}, + {0x8764, 0x56015507}, + {0x8768, 0x7410e4c9}, + {0x876c, 0x02002088}, + {0x8770, 0x5517140f}, + {0x8774, 0xe47ee4c9}, + {0x8778, 0x468e7508}, + {0x877c, 0xe159e4d3}, + {0x8780, 0x7410f512}, + {0x8784, 0x00002090}, + {0x8788, 0x5507140f}, + {0x878c, 0x7410e4c9}, + {0x8790, 0x02002098}, + {0x8794, 0x5517140f}, + {0x8798, 0x7509e4c9}, + {0x879c, 0xe4d34696}, + {0x87a0, 0x0001e159}, + {0x87a4, 0x46965b90}, + {0x87a8, 0xe4c55500}, + {0x87ac, 0x5b105501}, + {0x87b0, 0x79000001}, + {0x87b4, 0x57107420}, + {0x87b8, 0x140f5700}, + {0x87bc, 0x74309700}, + {0x87c0, 0xe4930001}, + {0x87c4, 0x0bbde4df}, + {0x87c8, 0x0001e662}, + {0x87cc, 0x5720e493}, + {0x87d0, 0x540054fd}, + {0x87d4, 0x70005700}, + {0x87d8, 0x70c0e4dd}, + {0x87dc, 0xe4a90001}, + {0x87e0, 0x0001e512}, + {0x87e4, 0x31abe493}, + {0x87e8, 0xe6620023}, + {0x87ec, 0x54ed0002}, + {0x87f0, 0x00230baa}, + {0x87f4, 0x0002e662}, + {0x87f8, 0xe486e52e}, + {0x87fc, 0xe4930001}, + {0x8800, 0x002231a1}, + {0x8804, 0x0002e662}, + {0x8808, 0x0baa54ec}, + {0x880c, 0xe6620022}, + {0x8810, 0xe52e0002}, + {0x8814, 0x0001e486}, + {0x8818, 0x0baae493}, + {0x881c, 0xe52e3194}, + {0x8820, 0x0001e486}, + {0x8824, 0x0babe493}, + {0x8828, 0x6d0f6c67}, + {0x882c, 0xe662e4df}, + {0x8830, 0x6c8bfb04}, + {0x8834, 0xe662e4df}, + {0x8838, 0x6c95fa04}, + {0x883c, 0xe662e4df}, + {0x8840, 0x0bacfb06}, + {0x8844, 0x6d0f6cb3}, + {0x8848, 0xe662e4df}, + {0x884c, 0xf904fa05}, + {0x8850, 0xe4df6ccb}, + {0x8854, 0xfb06e662}, + {0x8858, 0x6cdb0bad}, + {0x885c, 0xe4df6d0f}, + {0x8860, 0x6cf5e662}, + {0x8864, 0xe4df6d0f}, + {0x8868, 0x6c0be662}, + {0x886c, 0xe4df6d00}, + {0x8870, 0xfb04e662}, + {0x8874, 0xe4df6c25}, + {0x8878, 0xf8b7e662}, + {0x887c, 0xf904fa05}, + {0x8880, 0xe4df6c35}, + {0x8884, 0xfb04e662}, + {0x8888, 0xe4df6c4d}, + {0x888c, 0xf9bae662}, + {0x8890, 0x6c6bfa04}, + {0x8894, 0xe662e4df}, + {0x8898, 0x6c75fb04}, + {0x889c, 0xe662e4df}, + {0x88a0, 0xe4df6c99}, + {0x88a4, 0xfabce662}, + {0x88a8, 0x57200ba8}, + {0x88ac, 0x540054f0}, + {0x88b0, 0x7c355700}, + {0x88b4, 0x70007d00}, + {0x88b8, 0x6d0e6cc5}, + {0x88bc, 0xe662e4dd}, + {0x88c0, 0xe4dd6cf5}, + {0x88c4, 0x6c29e662}, + {0x88c8, 0xe4dd6d0f}, + {0x88cc, 0x0bb3e662}, + {0x88d0, 0x54ed5720}, + {0x88d4, 0x57005400}, + {0x88d8, 0x7d0f7ccb}, + {0x88dc, 0x6d006cd7}, + {0x88e0, 0xe662e4dd}, + {0x88e4, 0x6d016c0b}, + {0x88e8, 0xe662e4dd}, + {0x88ec, 0xe4dd6c3b}, + {0x88f0, 0x70c0e662}, + {0x88f4, 0xe486e52e}, + {0x88f8, 0xe4a90001}, + {0x88fc, 0x63424380}, + {0x8900, 0x43006887}, + {0x8904, 0x74100ba6}, + {0x8908, 0x000121e8}, + {0x890c, 0x6ec71658}, + {0x8910, 0xe5126f0e}, + {0x8914, 0x7410e667}, + {0x8918, 0x000321e8}, + {0x891c, 0x6eeb1658}, + {0x8920, 0xe667e512}, + {0x8924, 0x21e87410}, + {0x8928, 0x16580005}, + {0x892c, 0x6f0f6e13}, + {0x8930, 0xe667e512}, + {0x8934, 0x21e87410}, + {0x8938, 0x16580007}, + {0x893c, 0xe5126e3b}, + {0x8940, 0x7410e667}, + {0x8944, 0x000921e8}, + {0x8948, 0x6e671658}, + {0x894c, 0xe5126f0f}, + {0x8950, 0x7410e667}, + {0x8954, 0x000b21e8}, + {0x8958, 0x6e8b1658}, + {0x895c, 0xe667e512}, + {0x8960, 0x21e87410}, + {0x8964, 0x1658000d}, + {0x8968, 0x6f0f6eb3}, + {0x896c, 0xe667e512}, + {0x8970, 0xfe08ff09}, + {0x8974, 0x21e87410}, + {0x8978, 0x1658000e}, + {0x897c, 0xe5126ec7}, + {0x8980, 0x7410e667}, + {0x8984, 0x000f21e8}, + {0x8988, 0x6edb1658}, + {0x898c, 0xe5126f0f}, + {0x8990, 0x7410e667}, + {0x8994, 0x001021e8}, + {0x8998, 0x6eef1658}, + {0x899c, 0xe667e512}, + {0x89a0, 0xfe02ff03}, + {0x89a4, 0x7410e667}, + {0x89a8, 0x001321e8}, + {0x89ac, 0x6e111658}, + {0x89b0, 0xe5126f00}, + {0x89b4, 0xff03e667}, + {0x89b8, 0xe667fe02}, + {0x89bc, 0x21e87410}, + {0x89c0, 0x16580014}, + {0x89c4, 0xe5126e25}, + {0x89c8, 0xfc48e667}, + {0x89cc, 0xfe08ff09}, + {0x89d0, 0x21e87410}, + {0x89d4, 0x16580015}, + {0x89d8, 0xe5126e39}, + {0x89dc, 0x7410e667}, + {0x89e0, 0x001621e8}, + {0x89e4, 0x6e4d1658}, + {0x89e8, 0xe667e512}, + {0x89ec, 0x7410fd49}, + {0x89f0, 0x001821e8}, + {0x89f4, 0x6e751658}, + {0x89f8, 0xe667e512}, + {0x89fc, 0x21e87410}, + {0x8a00, 0x1658001a}, + {0x8a04, 0xe5126e99}, + {0x8a08, 0xfe44e667}, + {0x8a0c, 0x21e87410}, + {0x8a10, 0x1658001c}, + {0x8a14, 0xe5126ec5}, + {0x8a18, 0x7410e667}, + {0x8a1c, 0x001e21e8}, + {0x8a20, 0x6eed1658}, + {0x8a24, 0xe667e512}, + {0x8a28, 0x21e87410}, + {0x8a2c, 0x16580020}, + {0x8a30, 0x6f016e15}, + {0x8a34, 0xe667e512}, + {0x8a38, 0x21e87410}, + {0x8a3c, 0x16580022}, + {0x8a40, 0xe5126e39}, + {0x8a44, 0xe52ee667}, + {0x8a48, 0x0001e49c}, + {0x8a4c, 0x4380e4a9}, + {0x8a50, 0x68806340}, + {0x8a54, 0x0bac4300}, + {0x8a58, 0x00223241}, + {0x8a5c, 0x0002e667}, + {0x8a60, 0x0baa54ec}, + {0x8a64, 0xe6670022}, + {0x8a68, 0xe52e0002}, + {0x8a6c, 0x0001e49c}, + {0x8a70, 0x4380e4a9}, + {0x8a74, 0x68816340}, + {0x8a78, 0x0baa4300}, + {0x8a7c, 0xe52e3230}, + {0x8a80, 0x0001e49c}, + {0x8a84, 0x4380e4a9}, + {0x8a88, 0x68826341}, + {0x8a8c, 0x0baa4300}, + {0x8a90, 0xe52e3221}, + {0x8a94, 0x0001e49c}, + {0x8a98, 0x42fc0004}, + {0x8a9c, 0x60010007}, + {0x8aa0, 0x42000004}, + {0x8aa4, 0x62200007}, + {0x8aa8, 0x00046200}, + {0x8aac, 0x5b405501}, + {0x8ab0, 0x00076605}, + {0x8ab4, 0x63006200}, + {0x8ab8, 0x0004e54f}, + {0x8abc, 0x0a010900}, + {0x8ac0, 0x0d000b40}, + {0x8ac4, 0x00320e01}, + {0x8ac8, 0x95090004}, + {0x8acc, 0x790442fb}, + {0x8ad0, 0x43804200}, + {0x8ad4, 0x4d010007}, + {0x8ad8, 0x43000004}, + {0x8adc, 0x05620007}, + {0x8ae0, 0x961d05a3}, + {0x8ae4, 0x0004e54f}, + {0x8ae8, 0x0007e4c5}, + {0x8aec, 0x07a306a2}, + {0x8af0, 0x0004e54f}, + {0x8af4, 0xe53fe4c5}, + {0x8af8, 0xe5470002}, + {0x8afc, 0x00074380}, + {0x8b00, 0x00044d00}, + {0x8b04, 0x42fe4300}, + {0x8b08, 0x42007900}, + {0x8b0c, 0x00040001}, + {0x8b10, 0x000742fc}, + {0x8b14, 0x00046003}, + {0x8b18, 0x32d24200}, + {0x8b1c, 0x06a20007}, + {0x8b20, 0x32fc07a3}, + {0x8b24, 0xe32ee320}, + {0x8b28, 0x0001e333}, + {0x8b2c, 0xe333e320}, + {0x8b30, 0xe3270001}, + {0x8b34, 0xe333e32e}, + {0x8b38, 0xe3270001}, + {0x8b3c, 0x0001e333}, + {0x8b40, 0x42fc0004}, + {0x8b44, 0x60030007}, + {0x8b48, 0x42000004}, + {0x8b4c, 0x00040001}, + {0x8b50, 0x000742fc}, + {0x8b54, 0x00046001}, + {0x8b58, 0x00014200}, + {0x8b5c, 0x62200007}, + {0x8b60, 0xe5476200}, + {0x8b64, 0x00070001}, + {0x8b68, 0x00046300}, + {0x8b6c, 0x0a000900}, + {0x8b70, 0x00320e01}, + {0x8b74, 0x06a20007}, + {0x8b78, 0xe559e54f}, + {0x8b7c, 0x42fe0002}, + {0x8b80, 0x42007900}, + {0x8b84, 0x00050001}, + {0x8b88, 0x00077700}, + {0x8b8c, 0x00045200}, + {0x8b90, 0x000742fe}, + {0x8b94, 0x00046000}, + {0x8b98, 0x43804200}, + {0x8b9c, 0x61006000}, + {0x8ba0, 0x63106201}, + {0x8ba4, 0x00056804}, + {0x8ba8, 0x55004100}, + {0x8bac, 0x5c020007}, + {0x8bb0, 0x43000004}, + {0x8bb4, 0x00050001}, + {0x8bb8, 0xe3c96c06}, + {0x8bbc, 0xe3b8e3db}, + {0x8bc0, 0xe423e567}, + {0x8bc4, 0xe43ce56f}, + {0x8bc8, 0xe3b80001}, + {0x8bcc, 0x6c060005}, + {0x8bd0, 0xe5e6e3c9}, + {0x8bd4, 0xe423e567}, + {0x8bd8, 0xe43ce56f}, + {0x8bdc, 0x00050001}, + {0x8be0, 0xe3c96c00}, + {0x8be4, 0xe3b8e3db}, + {0x8be8, 0xe423e582}, + {0x8bec, 0xe43ce58a}, + {0x8bf0, 0xe3b80001}, + {0x8bf4, 0x6c000005}, + {0x8bf8, 0xe5e6e3c9}, + {0x8bfc, 0xe423e582}, + {0x8c00, 0xe43ce58a}, + {0x8c04, 0x00050001}, + {0x8c08, 0xe3c96c04}, + {0x8c0c, 0xe3b8e3db}, + {0x8c10, 0xe423e59d}, + {0x8c14, 0xe43ce5a5}, + {0x8c18, 0xe3b80001}, + {0x8c1c, 0x6c040005}, + {0x8c20, 0xe5e6e3c9}, + {0x8c24, 0xe423e59d}, + {0x8c28, 0xe43ce5a5}, + {0x8c2c, 0x00050001}, + {0x8c30, 0xe3c96c02}, + {0x8c34, 0xe3b8e3db}, + {0x8c38, 0xe423e5b8}, + {0x8c3c, 0xe43ce5c0}, + {0x8c40, 0xe3b80001}, + {0x8c44, 0x6c020005}, + {0x8c48, 0xe5e6e3c9}, + {0x8c4c, 0xe423e5b8}, + {0x8c50, 0xe43ce5c0}, + {0x8c54, 0x00040001}, + {0x8c58, 0x60084380}, + {0x8c5c, 0x6200610a}, + {0x8c60, 0x000663ce}, + {0x8c64, 0x7f006080}, + {0x8c68, 0x43000004}, + {0x8c6c, 0x0001e618}, + {0x8c70, 0x55000007}, + {0x8c74, 0x74200004}, + {0x8c78, 0x77117901}, + {0x8c7c, 0x57005710}, + {0x8c80, 0x7430140f}, + {0x8c84, 0x43800004}, + {0x8c88, 0x72000007}, + {0x8c8c, 0x43000004}, + {0x8c90, 0x00040001}, + {0x8c94, 0x00057420}, + {0x8c98, 0x7e067700}, + {0x8c9c, 0x73807388}, + {0x8ca0, 0x140f8f00}, + {0x8ca4, 0x74300004}, + {0x8ca8, 0x73000005}, + {0x8cac, 0xe5d30001}, + {0x8cb0, 0x73000005}, + {0x8cb4, 0x00040001}, + {0x8cb8, 0xb1034380}, + {0x8cbc, 0x7cdb0006}, + {0x8cc0, 0x00079103}, + {0x8cc4, 0x000440db}, + {0x8cc8, 0xe5d34300}, + {0x8ccc, 0x73800005}, + {0x8cd0, 0x5d010006}, + {0x8cd4, 0x62006002}, + {0x8cd8, 0x0005e5f7}, + {0x8cdc, 0x00077300}, + {0x8ce0, 0x75787608}, + {0x8ce4, 0x43800004}, + {0x8ce8, 0x5e010007}, + {0x8cec, 0x140a5e00}, + {0x8cf0, 0x63800006}, + {0x8cf4, 0x00077f00}, + {0x8cf8, 0x4e204c3f}, + {0x8cfc, 0x73047280}, + {0x8d00, 0x140a7300}, + {0x8d04, 0x00044d20}, + {0x8d08, 0x00064300}, + {0x8d0c, 0x00077402}, + {0x8d10, 0x40004001}, + {0x8d14, 0x0006ab00}, + {0x8d18, 0x00077404}, + {0x8d1c, 0x40004001}, + {0x8d20, 0x140aab00}, + {0x8d24, 0x43800004}, + {0x8d28, 0x52800007}, + {0x8d2c, 0x140a5200}, + {0x8d30, 0x4d004c00}, + {0x8d34, 0x00064e00}, + {0x8d38, 0x63006080}, + {0x8d3c, 0x43000004}, + {0x8d40, 0x76000007}, + {0x8d44, 0x00040001}, + {0x8d48, 0xb1034380}, + {0x8d4c, 0x7cdb0006}, + {0x8d50, 0x00079103}, + {0x8d54, 0x000440db}, + {0x8d58, 0xe5d34300}, + {0x8d5c, 0xe5f77e03}, + {0x8d60, 0x43800004}, + {0x8d64, 0x0006b103}, + {0x8d68, 0x91037c5b}, + {0x8d6c, 0x405b0007}, + {0x8d70, 0x43000004}, + {0x8d74, 0x00010001}, + {0x8d78, 0x43800004}, + {0x8d7c, 0x4e200007}, + {0x8d80, 0x63800006}, + {0x8d84, 0x5f807cdb}, + {0x8d88, 0x43000004}, + {0x8d8c, 0x76080007}, + {0x8d90, 0x00057560}, + {0x8d94, 0x00047380}, + {0x8d98, 0x0005420e}, + {0x8d9c, 0x92006c01}, + {0x8da0, 0x6c001432}, + {0x8da4, 0x42000004}, + {0x8da8, 0x43800004}, + {0x8dac, 0x5f000006}, + {0x8db0, 0x73010007}, + {0x8db4, 0x00047300}, + {0x8db8, 0x0007420f}, + {0x8dbc, 0x52005280}, + {0x8dc0, 0x0004140a}, + {0x8dc4, 0x00064200}, + {0x8dc8, 0x7c5b6300}, + {0x8dcc, 0x4e000007}, + {0x8dd0, 0x43000004}, + {0x8dd4, 0x73000005}, + {0x8dd8, 0x76000007}, + {0x8ddc, 0xe5fb0001}, + {0x8de0, 0x00040001}, + {0x8de4, 0x60004380}, + {0x8de8, 0x62016100}, + {0x8dec, 0x00066310}, + {0x8df0, 0x00046000}, + {0x8df4, 0x00014300}, + {0x8df8, 0x0001e618}, + {0x8dfc, 0x4e004f02}, + {0x8e00, 0x52015302}, + {0x8e04, 0x140f0001}, + {0x8e08, 0x00019700}, + {0x8e0c, 0x8a084380}, + {0x8e10, 0x7800aa09}, + {0x8e14, 0x7a007900}, + {0x8e18, 0x43007b40}, + {0x8e1c, 0x65010001}, + {0x8e20, 0x67013489}, + {0x8e24, 0x43803489}, + {0x8e28, 0xaa058a04}, + {0x8e2c, 0x00014300}, + {0x8e30, 0x34966500}, + {0x8e34, 0x34966700}, + {0x8e38, 0x8a084380}, + {0x8e3c, 0x7c00aa09}, + {0x8e40, 0x7e007d00}, + {0x8e44, 0x43007f40}, + {0x8e48, 0x64010001}, + {0x8e4c, 0x6601349f}, + {0x8e50, 0x4380349f}, + {0x8e54, 0xaa058a04}, + {0x8e58, 0x00014300}, + {0x8e5c, 0x34ac6400}, + {0x8e60, 0x34ac6600}, + {0x8e64, 0x7b484380}, + {0x8e68, 0x79007a90}, + {0x8e6c, 0x43007802}, + {0x8e70, 0x34c95503}, + {0x8e74, 0x7b384380}, + {0x8e78, 0x43007a80}, + {0x8e7c, 0x34c95513}, + {0x8e80, 0x7b404380}, + {0x8e84, 0x43007a00}, + {0x8e88, 0x74015523}, + {0x8e8c, 0x8e007400}, + {0x8e90, 0x00070001}, + {0x8e94, 0x00045230}, + {0x8e98, 0x74307431}, + {0x8e9c, 0x00078e00}, + {0x8ea0, 0x00045220}, + {0x8ea4, 0x57020001}, + {0x8ea8, 0x8e005700}, + {0x8eac, 0x42ef0001}, + {0x8eb0, 0x56005610}, + {0x8eb4, 0x8c004200}, + {0x8eb8, 0x5b500001}, + {0x8ebc, 0x5b2034e0}, + {0x8ec0, 0x4e004f78}, + {0x8ec4, 0x52015388}, + {0x8ec8, 0x4e004f78}, + {0x8ecc, 0x52015388}, + {0x8ed0, 0x5480e4f2}, + {0x8ed4, 0x54815400}, + {0x8ed8, 0x54825400}, + {0x8edc, 0xe4fd5400}, + {0x8ee0, 0x3010bf1d}, + {0x8ee4, 0xe4bae4b2}, + {0x8ee8, 0xe4d3e4c0}, + {0x8eec, 0x5523e65b}, + {0x8ef0, 0x5525e4c9}, + {0x8ef4, 0xe65be4d3}, + {0x8ef8, 0x54bf0001}, + {0x8efc, 0x54a354c0}, + {0x8f00, 0x54a454c1}, + {0x8f04, 0xbf074c18}, + {0x8f08, 0x54a454c2}, + {0x8f0c, 0x54c1bf04}, + {0x8f10, 0xbf0154a3}, + {0x8f14, 0x54dfe66c}, + {0x8f18, 0x54bf0001}, + {0x8f1c, 0x050a54e5}, + {0x8f20, 0x000154df}, + {0x8f24, 0x7b801657}, + {0x8f28, 0x43807430}, + {0x8f2c, 0x7e007f40}, + {0x8f30, 0x7c027d00}, + {0x8f34, 0x5b404300}, + {0x8f38, 0x5c015501}, + {0x8f3c, 0x5480e4d7}, + {0x8f40, 0x54815400}, + {0x8f44, 0x54825400}, + {0x8f48, 0x7b005400}, + {0x8f4c, 0xe4fd7410}, + {0x8f50, 0x3010bfe5}, + {0x8f54, 0x56005610}, + {0x8f58, 0x00018c00}, + {0x8f5c, 0x57005704}, + {0x8f60, 0x57088e00}, + {0x8f64, 0x8e005700}, + {0x8f68, 0x57805781}, + {0x8f6c, 0x43808e00}, + {0x8f70, 0x5c010007}, + {0x8f74, 0x14035c00}, + {0x8f78, 0x43000004}, + {0x8f7c, 0x427f0001}, + {0x8f80, 0x62800007}, + {0x8f84, 0x92006200}, + {0x8f88, 0x42000004}, + {0x8f8c, 0x427f0001}, + {0x8f90, 0x63940007}, + {0x8f94, 0x92006314}, + {0x8f98, 0x42000004}, + {0x8f9c, 0x00040001}, + {0x8fa0, 0x790142fe}, + {0x8fa4, 0x74204200}, + {0x8fa8, 0x5710140f}, + {0x8fac, 0x141f5700}, + {0x8fb0, 0x00040001}, + {0x8fb4, 0x790142fe}, + {0x8fb8, 0x74204200}, + {0x8fbc, 0x42bf140f}, + {0x8fc0, 0x62400007}, + {0x8fc4, 0x141f6200}, + {0x8fc8, 0x42000004}, + {0x8fcc, 0x00060001}, + {0x8fd0, 0x60035d06}, + {0x8fd4, 0x62016104}, + {0x8fd8, 0x73100005}, + {0x8fdc, 0x00040001}, + {0x8fe0, 0x00074380}, + {0x8fe4, 0x5e005e01}, + {0x8fe8, 0xb103140a}, + {0x8fec, 0x7f070006}, + {0x8ff0, 0x00079103}, + {0x8ff4, 0x00064307}, + {0x8ff8, 0x5d025c00}, + {0x8ffc, 0x00045e03}, + {0x9000, 0x00014300}, + {0x9004, 0x5d040006}, + {0x9008, 0x61046000}, + {0x900c, 0x00056201}, + {0x9010, 0x00017310}, + {0x9014, 0x43800004}, + {0x9018, 0x5e010007}, + {0x901c, 0x140a5e00}, + {0x9020, 0x0006b103}, + {0x9024, 0x91037fc6}, + {0x9028, 0x43c60007}, + {0x902c, 0x5c000006}, + {0x9030, 0x5e035d02}, + {0x9034, 0x43000004}, + {0x9038, 0x00060001}, + {0x903c, 0x60005d04}, + {0x9040, 0x62016104}, + {0x9044, 0x73100005}, + {0x9048, 0x00040001}, + {0x904c, 0x00074380}, + {0x9050, 0x5e005e01}, + {0x9054, 0xb103140a}, + {0x9058, 0x7fc60006}, + {0x905c, 0x00079103}, + {0x9060, 0x000643c6}, + {0x9064, 0x5d025c00}, + {0x9068, 0x00045e03}, + {0x906c, 0x00014300}, + {0x9070, 0x5d000006}, + {0x9074, 0x61006002}, + {0x9078, 0x00056201}, + {0x907c, 0x00017300}, + {0x9080, 0x43800004}, + {0x9084, 0x5e010007}, + {0x9088, 0x140a5e00}, + {0x908c, 0x0006b103}, + {0x9090, 0x91037fc0}, + {0x9094, 0x43c00007}, + {0x9098, 0x5c000006}, + {0x909c, 0x5e035d02}, + {0x90a0, 0x43000004}, + {0x90a4, 0x00050001}, + {0x90a8, 0x00047e02}, + {0x90ac, 0x000542f7}, + {0x90b0, 0x00046c08}, + {0x90b4, 0x00054270}, + {0x90b8, 0x73807381}, + {0x90bc, 0x00049300}, + {0x90c0, 0x000542f7}, + {0x90c4, 0x00046c00}, + {0x90c8, 0x00014200}, + {0x90cc, 0x43800004}, + {0x90d0, 0x73040007}, + {0x90d4, 0x14057300}, + {0x90d8, 0x00047240}, + {0x90dc, 0x00064300}, + {0x90e0, 0x00077404}, + {0x90e4, 0x40004001}, + {0x90e8, 0x140fab00}, + {0x90ec, 0xe64f0001}, + {0x90f0, 0xe656e5fb}, + {0x90f4, 0x00040001}, + {0x90f8, 0x00047410}, + {0x90fc, 0x42f04380}, + {0x9100, 0x62080007}, + {0x9104, 0x24206301}, + {0x9108, 0x14c80000}, + {0x910c, 0x00002428}, + {0x9110, 0x1a4215f4}, + {0x9114, 0x6300000b}, + {0x9118, 0x42000004}, + {0x911c, 0x74304300}, + {0x9120, 0x4380140f}, + {0x9124, 0x73080007}, + {0x9128, 0x00047300}, + {0x912c, 0x00014300}, + {0x9130, 0x4bf00007}, + {0x9134, 0x490b4a8f}, + {0x9138, 0x4a8e48f1}, + {0x913c, 0x48a5490a}, + {0x9140, 0x49094a8d}, + {0x9144, 0x4a8c487d}, + {0x9148, 0x48754908}, + {0x914c, 0x49074a8b}, + {0x9150, 0x4a8a4889}, + {0x9154, 0x48b74906}, + {0x9158, 0x49054a89}, + {0x915c, 0x4a8848fc}, + {0x9160, 0x48564905}, + {0x9164, 0x49044a87}, + {0x9168, 0x4a8648c1}, + {0x916c, 0x483d4904}, + {0x9170, 0x49034a85}, + {0x9174, 0x4a8448c7}, + {0x9178, 0x485e4903}, + {0x917c, 0x49024a83}, + {0x9180, 0x4a8248ac}, + {0x9184, 0x48624902}, + {0x9188, 0x49024a81}, + {0x918c, 0x4a804820}, + {0x9190, 0x48004900}, + {0x9194, 0x49014a90}, + {0x9198, 0x4a10481f}, + {0x919c, 0x00060001}, + {0x91a0, 0x5f005f80}, + {0x91a4, 0x00059900}, + {0x91a8, 0x00017300}, + {0x91ac, 0x63800006}, + {0x91b0, 0x98006300}, + {0x91b4, 0x549f0001}, + {0x91b8, 0x5c015400}, + {0x91bc, 0x540054df}, + {0x91c0, 0x00015c02}, + {0x91c4, 0x07145c01}, + {0x91c8, 0x5c025400}, + {0x91cc, 0x5c020001}, + {0x91d0, 0x54000714}, + {0x91d4, 0x00015c01}, + {0x91d8, 0x4c184c98}, + {0x91dc, 0x00080001}, + {0x91e0, 0x5c020004}, + {0x91e4, 0x09017430}, + {0x91e8, 0x0ba60c01}, + {0x91ec, 0x77800005}, + {0x91f0, 0x52200007}, + {0x91f4, 0x43800004}, + {0x91f8, 0x610a6008}, + {0x91fc, 0x63c26200}, + {0x9200, 0x5c000007}, + {0x9204, 0x43000004}, + {0x9208, 0x00000001}, + {0x8080, 0x00000004}, + {0x8080, 0x00000000}, + {0x8088, 0x00000000}, +}; + +const struct rtw89_phy_table rtw89_8852c_phy_bb_table = { + .regs = rtw89_8852c_phy_bb_regs, + .n_regs = ARRAY_SIZE(rtw89_8852c_phy_bb_regs), + .rf_path = 0, /* don't care */ +}; + +const struct rtw89_phy_table rtw89_8852c_phy_bb_gain_table = { + .regs = rtw89_8852c_phy_bb_reg_gain, + .n_regs = ARRAY_SIZE(rtw89_8852c_phy_bb_reg_gain), + .rf_path = 0, /* don't care */ +}; + +const struct rtw89_phy_table rtw89_8852c_phy_radioa_table = { + .regs = rtw89_8852c_phy_radioa_regs, + .n_regs = ARRAY_SIZE(rtw89_8852c_phy_radioa_regs), + .rf_path = RF_PATH_A, + .config = rtw89_phy_config_rf_reg_v1, +}; + +const struct rtw89_phy_table rtw89_8852c_phy_radiob_table = { + .regs = rtw89_8852c_phy_radiob_regs, + .n_regs = ARRAY_SIZE(rtw89_8852c_phy_radiob_regs), + .rf_path = RF_PATH_B, + .config = rtw89_phy_config_rf_reg_v1, +}; + +const struct rtw89_phy_table rtw89_8852c_phy_nctl_table = { + .regs = rtw89_8852c_phy_nctl_regs, + .n_regs = ARRAY_SIZE(rtw89_8852c_phy_nctl_regs), + .rf_path = 0, /* don't care */ +}; diff --git a/drivers/net/wireless/realtek/rtw89/rtw8852c_table.h b/drivers/net/wireless/realtek/rtw89/rtw8852c_table.h new file mode 100644 index 0000000000000..807021ab9f1da --- /dev/null +++ b/drivers/net/wireless/realtek/rtw89/rtw8852c_table.h @@ -0,0 +1,16 @@ +/* SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause */ +/* Copyright(c) 2019-2022 Realtek Corporation + */ + +#ifndef __RTW89_8852C_TABLE_H__ +#define __RTW89_8852C_TABLE_H__ + +#include "core.h" + +extern const struct rtw89_phy_table rtw89_8852c_phy_bb_table; +extern const struct rtw89_phy_table rtw89_8852c_phy_bb_gain_table; +extern const struct rtw89_phy_table rtw89_8852c_phy_radioa_table; +extern const struct rtw89_phy_table rtw89_8852c_phy_radiob_table; +extern const struct rtw89_phy_table rtw89_8852c_phy_nctl_table; + +#endif From 342475ac510ac0231fb38d00befdc86228453825 Mon Sep 17 00:00:00 2001 From: Ping-Ke Shih Date: Thu, 14 Apr 2022 14:20:16 +0800 Subject: [PATCH 154/228] rtw89: 8852c: add TX power by rate and limit tables TX power depends on rate, but must follow regulation for specific country. Once asked to set channel, we configure registers according to these TX power tables. Signed-off-by: Ping-Ke Shih Signed-off-by: Kalle Valo Link: https://lore.kernel.org/r/20220414062027.62638-3-pkshih@realtek.com --- drivers/net/wireless/realtek/rtw89/core.h | 1 + drivers/net/wireless/realtek/rtw89/rtw8852c.c | 9 + .../wireless/realtek/rtw89/rtw8852c_table.c | 5627 +++++++++++++++++ .../wireless/realtek/rtw89/rtw8852c_table.h | 18 + 4 files changed, 5655 insertions(+) diff --git a/drivers/net/wireless/realtek/rtw89/core.h b/drivers/net/wireless/realtek/rtw89/core.h index e8e31492b3639..1dd558d89567f 100644 --- a/drivers/net/wireless/realtek/rtw89/core.h +++ b/drivers/net/wireless/realtek/rtw89/core.h @@ -401,6 +401,7 @@ enum rtw89_rate_section { RTW89_RS_OFFSET, RTW89_RS_MAX, RTW89_RS_LMT_NUM = RTW89_RS_MCS + 1, + RTW89_RS_TX_SHAPE_NUM = RTW89_RS_OFDM + 1, }; enum rtw89_rate_max { diff --git a/drivers/net/wireless/realtek/rtw89/rtw8852c.c b/drivers/net/wireless/realtek/rtw89/rtw8852c.c index 0855c41e32afb..3f727dd420640 100644 --- a/drivers/net/wireless/realtek/rtw89/rtw8852c.c +++ b/drivers/net/wireless/realtek/rtw89/rtw8852c.c @@ -664,6 +664,15 @@ const struct rtw89_chip_info rtw8852c_chip_info = { .rf_table = {&rtw89_8852c_phy_radiob_table, &rtw89_8852c_phy_radioa_table,}, .nctl_table = &rtw89_8852c_phy_nctl_table, + .byr_table = &rtw89_8852c_byr_table, + .txpwr_lmt_2g = &rtw89_8852c_txpwr_lmt_2g, + .txpwr_lmt_5g = &rtw89_8852c_txpwr_lmt_5g, + .txpwr_lmt_6g = &rtw89_8852c_txpwr_lmt_6g, + .txpwr_lmt_ru_2g = &rtw89_8852c_txpwr_lmt_ru_2g, + .txpwr_lmt_ru_5g = &rtw89_8852c_txpwr_lmt_ru_5g, + .txpwr_lmt_ru_6g = &rtw89_8852c_txpwr_lmt_ru_6g, + .txpwr_factor_rf = 2, + .txpwr_factor_mac = 1, .dig_table = NULL, .hw_sec_hdr = true, .sec_ctrl_efuse_size = 4, diff --git a/drivers/net/wireless/realtek/rtw89/rtw8852c_table.c b/drivers/net/wireless/realtek/rtw89/rtw8852c_table.c index b0431874d7c4c..bd0c4ff5ca4dd 100644 --- a/drivers/net/wireless/realtek/rtw89/rtw8852c_table.c +++ b/drivers/net/wireless/realtek/rtw89/rtw8852c_table.c @@ -13664,6 +13664,5627 @@ static const struct rtw89_reg2_def rtw89_8852c_phy_nctl_regs[] = { {0x8088, 0x00000000}, }; +static const struct rtw89_txpwr_byrate_cfg rtw89_8852c_txpwr_byrate[] = { + { 0, 0, 0, 0, 4, 0x50505050, }, + { 0, 0, 1, 0, 4, 0x50505050, }, + { 0, 0, 1, 4, 4, 0x484c5050, }, + { 0, 0, 2, 0, 4, 0x50505050, }, + { 0, 0, 2, 4, 4, 0x44484c50, }, + { 0, 0, 2, 8, 4, 0x34383c40, }, + { 0, 0, 3, 0, 4, 0x50505050, }, + { 0, 1, 2, 0, 4, 0x50505050, }, + { 0, 1, 2, 4, 4, 0x44484c50, }, + { 0, 1, 2, 8, 4, 0x34383c40, }, + { 0, 1, 3, 0, 4, 0x50505050, }, + { 0, 0, 4, 1, 4, 0x00000000, }, + { 0, 0, 4, 0, 1, 0x00000000, }, + { 1, 0, 1, 0, 4, 0x5054585c, }, + { 1, 0, 1, 4, 4, 0x4044484c, }, + { 1, 0, 2, 0, 4, 0x4c505458, }, + { 1, 0, 2, 4, 4, 0x3c404448, }, + { 1, 0, 2, 8, 4, 0x2c303438, }, + { 1, 0, 3, 0, 4, 0x3c40484c, }, + { 1, 1, 2, 0, 4, 0x4c505458, }, + { 1, 1, 2, 4, 4, 0x3c404448, }, + { 1, 1, 2, 8, 4, 0x2c303438, }, + { 1, 1, 3, 0, 4, 0x3c40484c, }, + { 1, 0, 4, 0, 4, 0x00000000, }, + { 2, 0, 1, 0, 4, 0x5054585c, }, + { 2, 0, 1, 4, 4, 0x4044484c, }, + { 2, 0, 2, 0, 4, 0x4c505458, }, + { 2, 0, 2, 4, 4, 0x3c404448, }, + { 2, 0, 2, 8, 4, 0x2c303438, }, + { 2, 0, 3, 0, 4, 0x3c40484c, }, + { 2, 1, 2, 0, 4, 0x4c505458, }, + { 2, 1, 2, 4, 4, 0x3c404448, }, + { 2, 1, 2, 8, 4, 0x2c303438, }, + { 2, 1, 3, 0, 4, 0x3c40484c, }, + { 2, 0, 4, 0, 4, 0x00000000, }, +}; + +const u8 rtw89_8852c_tx_shape[RTW89_BAND_MAX][RTW89_RS_TX_SHAPE_NUM] + [RTW89_REGD_NUM] = { + [0][0][RTW89_ACMA] = 0, + [0][0][RTW89_ETSI] = 0, + [0][0][RTW89_FCC] = 1, + [0][0][RTW89_IC] = 1, + [0][0][RTW89_MKK] = 0, + [0][1][RTW89_ACMA] = 0, + [0][1][RTW89_ETSI] = 0, + [0][1][RTW89_FCC] = 3, + [0][1][RTW89_IC] = 3, + [0][1][RTW89_MKK] = 0, + [1][1][RTW89_ACMA] = 0, + [1][1][RTW89_ETSI] = 0, + [1][1][RTW89_FCC] = 3, + [1][1][RTW89_IC] = 3, + [1][1][RTW89_MKK] = 0, + [2][1][RTW89_FCC] = 1, +}; + +const s8 rtw89_8852c_txpwr_lmt_2g[RTW89_2G_BW_NUM][RTW89_NTX_NUM] + [RTW89_RS_LMT_NUM][RTW89_BF_NUM] + [RTW89_REGD_NUM][RTW89_2G_CH_NUM] = { + [0][0][0][0][RTW89_WW][0] = 60, + [0][0][0][0][RTW89_WW][1] = 60, + [0][0][0][0][RTW89_WW][2] = 60, + [0][0][0][0][RTW89_WW][3] = 60, + [0][0][0][0][RTW89_WW][4] = 60, + [0][0][0][0][RTW89_WW][5] = 60, + [0][0][0][0][RTW89_WW][6] = 60, + [0][0][0][0][RTW89_WW][7] = 60, + [0][0][0][0][RTW89_WW][8] = 60, + [0][0][0][0][RTW89_WW][9] = 60, + [0][0][0][0][RTW89_WW][10] = 60, + [0][0][0][0][RTW89_WW][11] = 60, + [0][0][0][0][RTW89_WW][12] = 58, + [0][0][0][0][RTW89_WW][13] = 74, + [0][1][0][0][RTW89_WW][0] = 48, + [0][1][0][0][RTW89_WW][1] = 48, + [0][1][0][0][RTW89_WW][2] = 48, + [0][1][0][0][RTW89_WW][3] = 48, + [0][1][0][0][RTW89_WW][4] = 48, + [0][1][0][0][RTW89_WW][5] = 48, + [0][1][0][0][RTW89_WW][6] = 48, + [0][1][0][0][RTW89_WW][7] = 48, + [0][1][0][0][RTW89_WW][8] = 48, + [0][1][0][0][RTW89_WW][9] = 48, + [0][1][0][0][RTW89_WW][10] = 48, + [0][1][0][0][RTW89_WW][11] = 48, + [0][1][0][0][RTW89_WW][12] = 44, + [0][1][0][0][RTW89_WW][13] = 62, + [1][0][0][0][RTW89_WW][0] = 0, + [1][0][0][0][RTW89_WW][1] = 0, + [1][0][0][0][RTW89_WW][2] = 52, + [1][0][0][0][RTW89_WW][3] = 52, + [1][0][0][0][RTW89_WW][4] = 52, + [1][0][0][0][RTW89_WW][5] = 60, + [1][0][0][0][RTW89_WW][6] = 52, + [1][0][0][0][RTW89_WW][7] = 52, + [1][0][0][0][RTW89_WW][8] = 52, + [1][0][0][0][RTW89_WW][9] = 44, + [1][0][0][0][RTW89_WW][10] = 32, + [1][0][0][0][RTW89_WW][11] = 0, + [1][0][0][0][RTW89_WW][12] = 0, + [1][0][0][0][RTW89_WW][13] = 0, + [1][1][0][0][RTW89_WW][0] = 0, + [1][1][0][0][RTW89_WW][1] = 0, + [1][1][0][0][RTW89_WW][2] = 48, + [1][1][0][0][RTW89_WW][3] = 48, + [1][1][0][0][RTW89_WW][4] = 48, + [1][1][0][0][RTW89_WW][5] = 48, + [1][1][0][0][RTW89_WW][6] = 36, + [1][1][0][0][RTW89_WW][7] = 36, + [1][1][0][0][RTW89_WW][8] = 36, + [1][1][0][0][RTW89_WW][9] = 32, + [1][1][0][0][RTW89_WW][10] = 32, + [1][1][0][0][RTW89_WW][11] = 0, + [1][1][0][0][RTW89_WW][12] = 0, + [1][1][0][0][RTW89_WW][13] = 0, + [0][0][1][0][RTW89_WW][0] = 60, + [0][0][1][0][RTW89_WW][1] = 60, + [0][0][1][0][RTW89_WW][2] = 60, + [0][0][1][0][RTW89_WW][3] = 60, + [0][0][1][0][RTW89_WW][4] = 60, + [0][0][1][0][RTW89_WW][5] = 60, + [0][0][1][0][RTW89_WW][6] = 60, + [0][0][1][0][RTW89_WW][7] = 60, + [0][0][1][0][RTW89_WW][8] = 60, + [0][0][1][0][RTW89_WW][9] = 60, + [0][0][1][0][RTW89_WW][10] = 60, + [0][0][1][0][RTW89_WW][11] = 56, + [0][0][1][0][RTW89_WW][12] = 52, + [0][0][1][0][RTW89_WW][13] = 0, + [0][1][1][0][RTW89_WW][0] = 48, + [0][1][1][0][RTW89_WW][1] = 48, + [0][1][1][0][RTW89_WW][2] = 48, + [0][1][1][0][RTW89_WW][3] = 48, + [0][1][1][0][RTW89_WW][4] = 48, + [0][1][1][0][RTW89_WW][5] = 48, + [0][1][1][0][RTW89_WW][6] = 48, + [0][1][1][0][RTW89_WW][7] = 48, + [0][1][1][0][RTW89_WW][8] = 48, + [0][1][1][0][RTW89_WW][9] = 48, + [0][1][1][0][RTW89_WW][10] = 48, + [0][1][1][0][RTW89_WW][11] = 48, + [0][1][1][0][RTW89_WW][12] = 44, + [0][1][1][0][RTW89_WW][13] = 0, + [0][0][2][0][RTW89_WW][0] = 60, + [0][0][2][0][RTW89_WW][1] = 60, + [0][0][2][0][RTW89_WW][2] = 60, + [0][0][2][0][RTW89_WW][3] = 60, + [0][0][2][0][RTW89_WW][4] = 60, + [0][0][2][0][RTW89_WW][5] = 60, + [0][0][2][0][RTW89_WW][6] = 60, + [0][0][2][0][RTW89_WW][7] = 60, + [0][0][2][0][RTW89_WW][8] = 60, + [0][0][2][0][RTW89_WW][9] = 60, + [0][0][2][0][RTW89_WW][10] = 60, + [0][0][2][0][RTW89_WW][11] = 56, + [0][0][2][0][RTW89_WW][12] = 52, + [0][0][2][0][RTW89_WW][13] = 0, + [0][1][2][0][RTW89_WW][0] = 48, + [0][1][2][0][RTW89_WW][1] = 48, + [0][1][2][0][RTW89_WW][2] = 48, + [0][1][2][0][RTW89_WW][3] = 48, + [0][1][2][0][RTW89_WW][4] = 48, + [0][1][2][0][RTW89_WW][5] = 48, + [0][1][2][0][RTW89_WW][6] = 48, + [0][1][2][0][RTW89_WW][7] = 48, + [0][1][2][0][RTW89_WW][8] = 48, + [0][1][2][0][RTW89_WW][9] = 48, + [0][1][2][0][RTW89_WW][10] = 48, + [0][1][2][0][RTW89_WW][11] = 48, + [0][1][2][0][RTW89_WW][12] = 44, + [0][1][2][0][RTW89_WW][13] = 0, + [0][1][2][1][RTW89_WW][0] = 36, + [0][1][2][1][RTW89_WW][1] = 36, + [0][1][2][1][RTW89_WW][2] = 36, + [0][1][2][1][RTW89_WW][3] = 36, + [0][1][2][1][RTW89_WW][4] = 36, + [0][1][2][1][RTW89_WW][5] = 36, + [0][1][2][1][RTW89_WW][6] = 36, + [0][1][2][1][RTW89_WW][7] = 36, + [0][1][2][1][RTW89_WW][8] = 36, + [0][1][2][1][RTW89_WW][9] = 36, + [0][1][2][1][RTW89_WW][10] = 36, + [0][1][2][1][RTW89_WW][11] = 36, + [0][1][2][1][RTW89_WW][12] = 36, + [0][1][2][1][RTW89_WW][13] = 0, + [1][0][2][0][RTW89_WW][0] = 0, + [1][0][2][0][RTW89_WW][1] = 0, + [1][0][2][0][RTW89_WW][2] = 60, + [1][0][2][0][RTW89_WW][3] = 60, + [1][0][2][0][RTW89_WW][4] = 60, + [1][0][2][0][RTW89_WW][5] = 60, + [1][0][2][0][RTW89_WW][6] = 60, + [1][0][2][0][RTW89_WW][7] = 60, + [1][0][2][0][RTW89_WW][8] = 60, + [1][0][2][0][RTW89_WW][9] = 60, + [1][0][2][0][RTW89_WW][10] = 60, + [1][0][2][0][RTW89_WW][11] = 0, + [1][0][2][0][RTW89_WW][12] = 0, + [1][0][2][0][RTW89_WW][13] = 0, + [1][1][2][0][RTW89_WW][0] = 0, + [1][1][2][0][RTW89_WW][1] = 0, + [1][1][2][0][RTW89_WW][2] = 48, + [1][1][2][0][RTW89_WW][3] = 48, + [1][1][2][0][RTW89_WW][4] = 48, + [1][1][2][0][RTW89_WW][5] = 48, + [1][1][2][0][RTW89_WW][6] = 48, + [1][1][2][0][RTW89_WW][7] = 48, + [1][1][2][0][RTW89_WW][8] = 48, + [1][1][2][0][RTW89_WW][9] = 44, + [1][1][2][0][RTW89_WW][10] = 40, + [1][1][2][0][RTW89_WW][11] = 0, + [1][1][2][0][RTW89_WW][12] = 0, + [1][1][2][0][RTW89_WW][13] = 0, + [1][1][2][1][RTW89_WW][0] = 0, + [1][1][2][1][RTW89_WW][1] = 0, + [1][1][2][1][RTW89_WW][2] = 36, + [1][1][2][1][RTW89_WW][3] = 36, + [1][1][2][1][RTW89_WW][4] = 36, + [1][1][2][1][RTW89_WW][5] = 36, + [1][1][2][1][RTW89_WW][6] = 36, + [1][1][2][1][RTW89_WW][7] = 36, + [1][1][2][1][RTW89_WW][8] = 36, + [1][1][2][1][RTW89_WW][9] = 36, + [1][1][2][1][RTW89_WW][10] = 36, + [1][1][2][1][RTW89_WW][11] = 0, + [1][1][2][1][RTW89_WW][12] = 0, + [1][1][2][1][RTW89_WW][13] = 0, + [0][0][0][0][RTW89_FCC][0] = 80, + [0][0][0][0][RTW89_ETSI][0] = 60, + [0][0][0][0][RTW89_MKK][0] = 72, + [0][0][0][0][RTW89_IC][0] = 80, + [0][0][0][0][RTW89_ACMA][0] = 60, + [0][0][0][0][RTW89_FCC][1] = 80, + [0][0][0][0][RTW89_ETSI][1] = 60, + [0][0][0][0][RTW89_MKK][1] = 72, + [0][0][0][0][RTW89_IC][1] = 80, + [0][0][0][0][RTW89_ACMA][1] = 60, + [0][0][0][0][RTW89_FCC][2] = 80, + [0][0][0][0][RTW89_ETSI][2] = 60, + [0][0][0][0][RTW89_MKK][2] = 72, + [0][0][0][0][RTW89_IC][2] = 80, + [0][0][0][0][RTW89_ACMA][2] = 60, + [0][0][0][0][RTW89_FCC][3] = 80, + [0][0][0][0][RTW89_ETSI][3] = 60, + [0][0][0][0][RTW89_MKK][3] = 72, + [0][0][0][0][RTW89_IC][3] = 80, + [0][0][0][0][RTW89_ACMA][3] = 60, + [0][0][0][0][RTW89_FCC][4] = 80, + [0][0][0][0][RTW89_ETSI][4] = 60, + [0][0][0][0][RTW89_MKK][4] = 72, + [0][0][0][0][RTW89_IC][4] = 80, + [0][0][0][0][RTW89_ACMA][4] = 60, + [0][0][0][0][RTW89_FCC][5] = 80, + [0][0][0][0][RTW89_ETSI][5] = 60, + [0][0][0][0][RTW89_MKK][5] = 72, + [0][0][0][0][RTW89_IC][5] = 80, + [0][0][0][0][RTW89_ACMA][5] = 60, + [0][0][0][0][RTW89_FCC][6] = 80, + [0][0][0][0][RTW89_ETSI][6] = 60, + [0][0][0][0][RTW89_MKK][6] = 72, + [0][0][0][0][RTW89_IC][6] = 80, + [0][0][0][0][RTW89_ACMA][6] = 60, + [0][0][0][0][RTW89_FCC][7] = 80, + [0][0][0][0][RTW89_ETSI][7] = 60, + [0][0][0][0][RTW89_MKK][7] = 72, + [0][0][0][0][RTW89_IC][7] = 80, + [0][0][0][0][RTW89_ACMA][7] = 60, + [0][0][0][0][RTW89_FCC][8] = 80, + [0][0][0][0][RTW89_ETSI][8] = 60, + [0][0][0][0][RTW89_MKK][8] = 72, + [0][0][0][0][RTW89_IC][8] = 80, + [0][0][0][0][RTW89_ACMA][8] = 60, + [0][0][0][0][RTW89_FCC][9] = 80, + [0][0][0][0][RTW89_ETSI][9] = 60, + [0][0][0][0][RTW89_MKK][9] = 72, + [0][0][0][0][RTW89_IC][9] = 80, + [0][0][0][0][RTW89_ACMA][9] = 60, + [0][0][0][0][RTW89_FCC][10] = 80, + [0][0][0][0][RTW89_ETSI][10] = 60, + [0][0][0][0][RTW89_MKK][10] = 72, + [0][0][0][0][RTW89_IC][10] = 80, + [0][0][0][0][RTW89_ACMA][10] = 60, + [0][0][0][0][RTW89_FCC][11] = 72, + [0][0][0][0][RTW89_ETSI][11] = 60, + [0][0][0][0][RTW89_MKK][11] = 72, + [0][0][0][0][RTW89_IC][11] = 72, + [0][0][0][0][RTW89_ACMA][11] = 60, + [0][0][0][0][RTW89_FCC][12] = 58, + [0][0][0][0][RTW89_ETSI][12] = 60, + [0][0][0][0][RTW89_MKK][12] = 72, + [0][0][0][0][RTW89_IC][12] = 58, + [0][0][0][0][RTW89_ACMA][12] = 60, + [0][0][0][0][RTW89_FCC][13] = 127, + [0][0][0][0][RTW89_ETSI][13] = 127, + [0][0][0][0][RTW89_MKK][13] = 74, + [0][0][0][0][RTW89_IC][13] = 127, + [0][0][0][0][RTW89_ACMA][13] = 127, + [0][1][0][0][RTW89_FCC][0] = 76, + [0][1][0][0][RTW89_ETSI][0] = 48, + [0][1][0][0][RTW89_MKK][0] = 60, + [0][1][0][0][RTW89_IC][0] = 76, + [0][1][0][0][RTW89_ACMA][0] = 48, + [0][1][0][0][RTW89_FCC][1] = 76, + [0][1][0][0][RTW89_ETSI][1] = 48, + [0][1][0][0][RTW89_MKK][1] = 60, + [0][1][0][0][RTW89_IC][1] = 76, + [0][1][0][0][RTW89_ACMA][1] = 48, + [0][1][0][0][RTW89_FCC][2] = 76, + [0][1][0][0][RTW89_ETSI][2] = 48, + [0][1][0][0][RTW89_MKK][2] = 60, + [0][1][0][0][RTW89_IC][2] = 76, + [0][1][0][0][RTW89_ACMA][2] = 48, + [0][1][0][0][RTW89_FCC][3] = 76, + [0][1][0][0][RTW89_ETSI][3] = 48, + [0][1][0][0][RTW89_MKK][3] = 60, + [0][1][0][0][RTW89_IC][3] = 76, + [0][1][0][0][RTW89_ACMA][3] = 48, + [0][1][0][0][RTW89_FCC][4] = 76, + [0][1][0][0][RTW89_ETSI][4] = 48, + [0][1][0][0][RTW89_MKK][4] = 60, + [0][1][0][0][RTW89_IC][4] = 76, + [0][1][0][0][RTW89_ACMA][4] = 48, + [0][1][0][0][RTW89_FCC][5] = 76, + [0][1][0][0][RTW89_ETSI][5] = 48, + [0][1][0][0][RTW89_MKK][5] = 60, + [0][1][0][0][RTW89_IC][5] = 76, + [0][1][0][0][RTW89_ACMA][5] = 48, + [0][1][0][0][RTW89_FCC][6] = 76, + [0][1][0][0][RTW89_ETSI][6] = 48, + [0][1][0][0][RTW89_MKK][6] = 60, + [0][1][0][0][RTW89_IC][6] = 76, + [0][1][0][0][RTW89_ACMA][6] = 48, + [0][1][0][0][RTW89_FCC][7] = 76, + [0][1][0][0][RTW89_ETSI][7] = 48, + [0][1][0][0][RTW89_MKK][7] = 60, + [0][1][0][0][RTW89_IC][7] = 76, + [0][1][0][0][RTW89_ACMA][7] = 48, + [0][1][0][0][RTW89_FCC][8] = 76, + [0][1][0][0][RTW89_ETSI][8] = 48, + [0][1][0][0][RTW89_MKK][8] = 60, + [0][1][0][0][RTW89_IC][8] = 76, + [0][1][0][0][RTW89_ACMA][8] = 48, + [0][1][0][0][RTW89_FCC][9] = 76, + [0][1][0][0][RTW89_ETSI][9] = 48, + [0][1][0][0][RTW89_MKK][9] = 60, + [0][1][0][0][RTW89_IC][9] = 76, + [0][1][0][0][RTW89_ACMA][9] = 48, + [0][1][0][0][RTW89_FCC][10] = 76, + [0][1][0][0][RTW89_ETSI][10] = 48, + [0][1][0][0][RTW89_MKK][10] = 60, + [0][1][0][0][RTW89_IC][10] = 76, + [0][1][0][0][RTW89_ACMA][10] = 48, + [0][1][0][0][RTW89_FCC][11] = 56, + [0][1][0][0][RTW89_ETSI][11] = 48, + [0][1][0][0][RTW89_MKK][11] = 60, + [0][1][0][0][RTW89_IC][11] = 56, + [0][1][0][0][RTW89_ACMA][11] = 48, + [0][1][0][0][RTW89_FCC][12] = 44, + [0][1][0][0][RTW89_ETSI][12] = 48, + [0][1][0][0][RTW89_MKK][12] = 60, + [0][1][0][0][RTW89_IC][12] = 44, + [0][1][0][0][RTW89_ACMA][12] = 48, + [0][1][0][0][RTW89_FCC][13] = 127, + [0][1][0][0][RTW89_ETSI][13] = 127, + [0][1][0][0][RTW89_MKK][13] = 62, + [0][1][0][0][RTW89_IC][13] = 127, + [0][1][0][0][RTW89_ACMA][13] = 127, + [1][0][0][0][RTW89_FCC][0] = 127, + [1][0][0][0][RTW89_ETSI][0] = 127, + [1][0][0][0][RTW89_MKK][0] = 127, + [1][0][0][0][RTW89_IC][0] = 127, + [1][0][0][0][RTW89_ACMA][0] = 127, + [1][0][0][0][RTW89_FCC][1] = 127, + [1][0][0][0][RTW89_ETSI][1] = 127, + [1][0][0][0][RTW89_MKK][1] = 127, + [1][0][0][0][RTW89_IC][1] = 127, + [1][0][0][0][RTW89_ACMA][1] = 127, + [1][0][0][0][RTW89_FCC][2] = 52, + [1][0][0][0][RTW89_ETSI][2] = 60, + [1][0][0][0][RTW89_MKK][2] = 72, + [1][0][0][0][RTW89_IC][2] = 52, + [1][0][0][0][RTW89_ACMA][2] = 60, + [1][0][0][0][RTW89_FCC][3] = 52, + [1][0][0][0][RTW89_ETSI][3] = 60, + [1][0][0][0][RTW89_MKK][3] = 72, + [1][0][0][0][RTW89_IC][3] = 52, + [1][0][0][0][RTW89_ACMA][3] = 60, + [1][0][0][0][RTW89_FCC][4] = 52, + [1][0][0][0][RTW89_ETSI][4] = 60, + [1][0][0][0][RTW89_MKK][4] = 72, + [1][0][0][0][RTW89_IC][4] = 52, + [1][0][0][0][RTW89_ACMA][4] = 60, + [1][0][0][0][RTW89_FCC][5] = 68, + [1][0][0][0][RTW89_ETSI][5] = 60, + [1][0][0][0][RTW89_MKK][5] = 72, + [1][0][0][0][RTW89_IC][5] = 68, + [1][0][0][0][RTW89_ACMA][5] = 60, + [1][0][0][0][RTW89_FCC][6] = 52, + [1][0][0][0][RTW89_ETSI][6] = 60, + [1][0][0][0][RTW89_MKK][6] = 72, + [1][0][0][0][RTW89_IC][6] = 52, + [1][0][0][0][RTW89_ACMA][6] = 60, + [1][0][0][0][RTW89_FCC][7] = 52, + [1][0][0][0][RTW89_ETSI][7] = 60, + [1][0][0][0][RTW89_MKK][7] = 72, + [1][0][0][0][RTW89_IC][7] = 52, + [1][0][0][0][RTW89_ACMA][7] = 60, + [1][0][0][0][RTW89_FCC][8] = 52, + [1][0][0][0][RTW89_ETSI][8] = 60, + [1][0][0][0][RTW89_MKK][8] = 72, + [1][0][0][0][RTW89_IC][8] = 52, + [1][0][0][0][RTW89_ACMA][8] = 60, + [1][0][0][0][RTW89_FCC][9] = 44, + [1][0][0][0][RTW89_ETSI][9] = 60, + [1][0][0][0][RTW89_MKK][9] = 72, + [1][0][0][0][RTW89_IC][9] = 44, + [1][0][0][0][RTW89_ACMA][9] = 60, + [1][0][0][0][RTW89_FCC][10] = 32, + [1][0][0][0][RTW89_ETSI][10] = 60, + [1][0][0][0][RTW89_MKK][10] = 70, + [1][0][0][0][RTW89_IC][10] = 32, + [1][0][0][0][RTW89_ACMA][10] = 60, + [1][0][0][0][RTW89_FCC][11] = 127, + [1][0][0][0][RTW89_ETSI][11] = 127, + [1][0][0][0][RTW89_MKK][11] = 127, + [1][0][0][0][RTW89_IC][11] = 127, + [1][0][0][0][RTW89_ACMA][11] = 127, + [1][0][0][0][RTW89_FCC][12] = 127, + [1][0][0][0][RTW89_ETSI][12] = 127, + [1][0][0][0][RTW89_MKK][12] = 127, + [1][0][0][0][RTW89_IC][12] = 127, + [1][0][0][0][RTW89_ACMA][12] = 127, + [1][0][0][0][RTW89_FCC][13] = 127, + [1][0][0][0][RTW89_ETSI][13] = 127, + [1][0][0][0][RTW89_MKK][13] = 127, + [1][0][0][0][RTW89_IC][13] = 127, + [1][0][0][0][RTW89_ACMA][13] = 127, + [1][1][0][0][RTW89_FCC][0] = 127, + [1][1][0][0][RTW89_ETSI][0] = 127, + [1][1][0][0][RTW89_MKK][0] = 127, + [1][1][0][0][RTW89_IC][0] = 127, + [1][1][0][0][RTW89_ACMA][0] = 127, + [1][1][0][0][RTW89_FCC][1] = 127, + [1][1][0][0][RTW89_ETSI][1] = 127, + [1][1][0][0][RTW89_MKK][1] = 127, + [1][1][0][0][RTW89_IC][1] = 127, + [1][1][0][0][RTW89_ACMA][1] = 127, + [1][1][0][0][RTW89_FCC][2] = 48, + [1][1][0][0][RTW89_ETSI][2] = 48, + [1][1][0][0][RTW89_MKK][2] = 60, + [1][1][0][0][RTW89_IC][2] = 48, + [1][1][0][0][RTW89_ACMA][2] = 48, + [1][1][0][0][RTW89_FCC][3] = 48, + [1][1][0][0][RTW89_ETSI][3] = 48, + [1][1][0][0][RTW89_MKK][3] = 60, + [1][1][0][0][RTW89_IC][3] = 48, + [1][1][0][0][RTW89_ACMA][3] = 48, + [1][1][0][0][RTW89_FCC][4] = 48, + [1][1][0][0][RTW89_ETSI][4] = 48, + [1][1][0][0][RTW89_MKK][4] = 60, + [1][1][0][0][RTW89_IC][4] = 48, + [1][1][0][0][RTW89_ACMA][4] = 48, + [1][1][0][0][RTW89_FCC][5] = 64, + [1][1][0][0][RTW89_ETSI][5] = 48, + [1][1][0][0][RTW89_MKK][5] = 60, + [1][1][0][0][RTW89_IC][5] = 64, + [1][1][0][0][RTW89_ACMA][5] = 48, + [1][1][0][0][RTW89_FCC][6] = 36, + [1][1][0][0][RTW89_ETSI][6] = 48, + [1][1][0][0][RTW89_MKK][6] = 60, + [1][1][0][0][RTW89_IC][6] = 36, + [1][1][0][0][RTW89_ACMA][6] = 48, + [1][1][0][0][RTW89_FCC][7] = 36, + [1][1][0][0][RTW89_ETSI][7] = 48, + [1][1][0][0][RTW89_MKK][7] = 60, + [1][1][0][0][RTW89_IC][7] = 36, + [1][1][0][0][RTW89_ACMA][7] = 48, + [1][1][0][0][RTW89_FCC][8] = 36, + [1][1][0][0][RTW89_ETSI][8] = 48, + [1][1][0][0][RTW89_MKK][8] = 60, + [1][1][0][0][RTW89_IC][8] = 36, + [1][1][0][0][RTW89_ACMA][8] = 48, + [1][1][0][0][RTW89_FCC][9] = 32, + [1][1][0][0][RTW89_ETSI][9] = 48, + [1][1][0][0][RTW89_MKK][9] = 60, + [1][1][0][0][RTW89_IC][9] = 32, + [1][1][0][0][RTW89_ACMA][9] = 48, + [1][1][0][0][RTW89_FCC][10] = 32, + [1][1][0][0][RTW89_ETSI][10] = 48, + [1][1][0][0][RTW89_MKK][10] = 58, + [1][1][0][0][RTW89_IC][10] = 32, + [1][1][0][0][RTW89_ACMA][10] = 48, + [1][1][0][0][RTW89_FCC][11] = 127, + [1][1][0][0][RTW89_ETSI][11] = 127, + [1][1][0][0][RTW89_MKK][11] = 127, + [1][1][0][0][RTW89_IC][11] = 127, + [1][1][0][0][RTW89_ACMA][11] = 127, + [1][1][0][0][RTW89_FCC][12] = 127, + [1][1][0][0][RTW89_ETSI][12] = 127, + [1][1][0][0][RTW89_MKK][12] = 127, + [1][1][0][0][RTW89_IC][12] = 127, + [1][1][0][0][RTW89_ACMA][12] = 127, + [1][1][0][0][RTW89_FCC][13] = 127, + [1][1][0][0][RTW89_ETSI][13] = 127, + [1][1][0][0][RTW89_MKK][13] = 127, + [1][1][0][0][RTW89_IC][13] = 127, + [1][1][0][0][RTW89_ACMA][13] = 127, + [0][0][1][0][RTW89_FCC][0] = 78, + [0][0][1][0][RTW89_ETSI][0] = 60, + [0][0][1][0][RTW89_MKK][0] = 76, + [0][0][1][0][RTW89_IC][0] = 78, + [0][0][1][0][RTW89_ACMA][0] = 60, + [0][0][1][0][RTW89_FCC][1] = 78, + [0][0][1][0][RTW89_ETSI][1] = 60, + [0][0][1][0][RTW89_MKK][1] = 76, + [0][0][1][0][RTW89_IC][1] = 78, + [0][0][1][0][RTW89_ACMA][1] = 60, + [0][0][1][0][RTW89_FCC][2] = 80, + [0][0][1][0][RTW89_ETSI][2] = 60, + [0][0][1][0][RTW89_MKK][2] = 76, + [0][0][1][0][RTW89_IC][2] = 80, + [0][0][1][0][RTW89_ACMA][2] = 60, + [0][0][1][0][RTW89_FCC][3] = 80, + [0][0][1][0][RTW89_ETSI][3] = 60, + [0][0][1][0][RTW89_MKK][3] = 76, + [0][0][1][0][RTW89_IC][3] = 80, + [0][0][1][0][RTW89_ACMA][3] = 60, + [0][0][1][0][RTW89_FCC][4] = 80, + [0][0][1][0][RTW89_ETSI][4] = 60, + [0][0][1][0][RTW89_MKK][4] = 76, + [0][0][1][0][RTW89_IC][4] = 80, + [0][0][1][0][RTW89_ACMA][4] = 60, + [0][0][1][0][RTW89_FCC][5] = 80, + [0][0][1][0][RTW89_ETSI][5] = 60, + [0][0][1][0][RTW89_MKK][5] = 76, + [0][0][1][0][RTW89_IC][5] = 80, + [0][0][1][0][RTW89_ACMA][5] = 60, + [0][0][1][0][RTW89_FCC][6] = 80, + [0][0][1][0][RTW89_ETSI][6] = 60, + [0][0][1][0][RTW89_MKK][6] = 76, + [0][0][1][0][RTW89_IC][6] = 80, + [0][0][1][0][RTW89_ACMA][6] = 60, + [0][0][1][0][RTW89_FCC][7] = 80, + [0][0][1][0][RTW89_ETSI][7] = 60, + [0][0][1][0][RTW89_MKK][7] = 76, + [0][0][1][0][RTW89_IC][7] = 80, + [0][0][1][0][RTW89_ACMA][7] = 60, + [0][0][1][0][RTW89_FCC][8] = 80, + [0][0][1][0][RTW89_ETSI][8] = 60, + [0][0][1][0][RTW89_MKK][8] = 76, + [0][0][1][0][RTW89_IC][8] = 80, + [0][0][1][0][RTW89_ACMA][8] = 60, + [0][0][1][0][RTW89_FCC][9] = 76, + [0][0][1][0][RTW89_ETSI][9] = 60, + [0][0][1][0][RTW89_MKK][9] = 76, + [0][0][1][0][RTW89_IC][9] = 76, + [0][0][1][0][RTW89_ACMA][9] = 60, + [0][0][1][0][RTW89_FCC][10] = 76, + [0][0][1][0][RTW89_ETSI][10] = 60, + [0][0][1][0][RTW89_MKK][10] = 76, + [0][0][1][0][RTW89_IC][10] = 76, + [0][0][1][0][RTW89_ACMA][10] = 60, + [0][0][1][0][RTW89_FCC][11] = 56, + [0][0][1][0][RTW89_ETSI][11] = 60, + [0][0][1][0][RTW89_MKK][11] = 76, + [0][0][1][0][RTW89_IC][11] = 56, + [0][0][1][0][RTW89_ACMA][11] = 60, + [0][0][1][0][RTW89_FCC][12] = 52, + [0][0][1][0][RTW89_ETSI][12] = 60, + [0][0][1][0][RTW89_MKK][12] = 76, + [0][0][1][0][RTW89_IC][12] = 52, + [0][0][1][0][RTW89_ACMA][12] = 60, + [0][0][1][0][RTW89_FCC][13] = 127, + [0][0][1][0][RTW89_ETSI][13] = 127, + [0][0][1][0][RTW89_MKK][13] = 127, + [0][0][1][0][RTW89_IC][13] = 127, + [0][0][1][0][RTW89_ACMA][13] = 127, + [0][1][1][0][RTW89_FCC][0] = 64, + [0][1][1][0][RTW89_ETSI][0] = 48, + [0][1][1][0][RTW89_MKK][0] = 68, + [0][1][1][0][RTW89_IC][0] = 64, + [0][1][1][0][RTW89_ACMA][0] = 48, + [0][1][1][0][RTW89_FCC][1] = 64, + [0][1][1][0][RTW89_ETSI][1] = 48, + [0][1][1][0][RTW89_MKK][1] = 68, + [0][1][1][0][RTW89_IC][1] = 64, + [0][1][1][0][RTW89_ACMA][1] = 48, + [0][1][1][0][RTW89_FCC][2] = 68, + [0][1][1][0][RTW89_ETSI][2] = 48, + [0][1][1][0][RTW89_MKK][2] = 68, + [0][1][1][0][RTW89_IC][2] = 68, + [0][1][1][0][RTW89_ACMA][2] = 48, + [0][1][1][0][RTW89_FCC][3] = 72, + [0][1][1][0][RTW89_ETSI][3] = 48, + [0][1][1][0][RTW89_MKK][3] = 68, + [0][1][1][0][RTW89_IC][3] = 72, + [0][1][1][0][RTW89_ACMA][3] = 48, + [0][1][1][0][RTW89_FCC][4] = 80, + [0][1][1][0][RTW89_ETSI][4] = 48, + [0][1][1][0][RTW89_MKK][4] = 68, + [0][1][1][0][RTW89_IC][4] = 80, + [0][1][1][0][RTW89_ACMA][4] = 48, + [0][1][1][0][RTW89_FCC][5] = 80, + [0][1][1][0][RTW89_ETSI][5] = 48, + [0][1][1][0][RTW89_MKK][5] = 68, + [0][1][1][0][RTW89_IC][5] = 80, + [0][1][1][0][RTW89_ACMA][5] = 48, + [0][1][1][0][RTW89_FCC][6] = 80, + [0][1][1][0][RTW89_ETSI][6] = 48, + [0][1][1][0][RTW89_MKK][6] = 68, + [0][1][1][0][RTW89_IC][6] = 80, + [0][1][1][0][RTW89_ACMA][6] = 48, + [0][1][1][0][RTW89_FCC][7] = 72, + [0][1][1][0][RTW89_ETSI][7] = 48, + [0][1][1][0][RTW89_MKK][7] = 68, + [0][1][1][0][RTW89_IC][7] = 72, + [0][1][1][0][RTW89_ACMA][7] = 48, + [0][1][1][0][RTW89_FCC][8] = 68, + [0][1][1][0][RTW89_ETSI][8] = 48, + [0][1][1][0][RTW89_MKK][8] = 68, + [0][1][1][0][RTW89_IC][8] = 68, + [0][1][1][0][RTW89_ACMA][8] = 48, + [0][1][1][0][RTW89_FCC][9] = 64, + [0][1][1][0][RTW89_ETSI][9] = 48, + [0][1][1][0][RTW89_MKK][9] = 68, + [0][1][1][0][RTW89_IC][9] = 64, + [0][1][1][0][RTW89_ACMA][9] = 48, + [0][1][1][0][RTW89_FCC][10] = 64, + [0][1][1][0][RTW89_ETSI][10] = 48, + [0][1][1][0][RTW89_MKK][10] = 68, + [0][1][1][0][RTW89_IC][10] = 64, + [0][1][1][0][RTW89_ACMA][10] = 48, + [0][1][1][0][RTW89_FCC][11] = 48, + [0][1][1][0][RTW89_ETSI][11] = 48, + [0][1][1][0][RTW89_MKK][11] = 68, + [0][1][1][0][RTW89_IC][11] = 48, + [0][1][1][0][RTW89_ACMA][11] = 48, + [0][1][1][0][RTW89_FCC][12] = 44, + [0][1][1][0][RTW89_ETSI][12] = 48, + [0][1][1][0][RTW89_MKK][12] = 68, + [0][1][1][0][RTW89_IC][12] = 44, + [0][1][1][0][RTW89_ACMA][12] = 48, + [0][1][1][0][RTW89_FCC][13] = 127, + [0][1][1][0][RTW89_ETSI][13] = 127, + [0][1][1][0][RTW89_MKK][13] = 127, + [0][1][1][0][RTW89_IC][13] = 127, + [0][1][1][0][RTW89_ACMA][13] = 127, + [0][0][2][0][RTW89_FCC][0] = 78, + [0][0][2][0][RTW89_ETSI][0] = 60, + [0][0][2][0][RTW89_MKK][0] = 76, + [0][0][2][0][RTW89_IC][0] = 78, + [0][0][2][0][RTW89_ACMA][0] = 60, + [0][0][2][0][RTW89_FCC][1] = 78, + [0][0][2][0][RTW89_ETSI][1] = 60, + [0][0][2][0][RTW89_MKK][1] = 76, + [0][0][2][0][RTW89_IC][1] = 78, + [0][0][2][0][RTW89_ACMA][1] = 60, + [0][0][2][0][RTW89_FCC][2] = 80, + [0][0][2][0][RTW89_ETSI][2] = 60, + [0][0][2][0][RTW89_MKK][2] = 76, + [0][0][2][0][RTW89_IC][2] = 80, + [0][0][2][0][RTW89_ACMA][2] = 60, + [0][0][2][0][RTW89_FCC][3] = 80, + [0][0][2][0][RTW89_ETSI][3] = 60, + [0][0][2][0][RTW89_MKK][3] = 76, + [0][0][2][0][RTW89_IC][3] = 80, + [0][0][2][0][RTW89_ACMA][3] = 60, + [0][0][2][0][RTW89_FCC][4] = 80, + [0][0][2][0][RTW89_ETSI][4] = 60, + [0][0][2][0][RTW89_MKK][4] = 76, + [0][0][2][0][RTW89_IC][4] = 80, + [0][0][2][0][RTW89_ACMA][4] = 60, + [0][0][2][0][RTW89_FCC][5] = 80, + [0][0][2][0][RTW89_ETSI][5] = 60, + [0][0][2][0][RTW89_MKK][5] = 76, + [0][0][2][0][RTW89_IC][5] = 80, + [0][0][2][0][RTW89_ACMA][5] = 60, + [0][0][2][0][RTW89_FCC][6] = 80, + [0][0][2][0][RTW89_ETSI][6] = 60, + [0][0][2][0][RTW89_MKK][6] = 76, + [0][0][2][0][RTW89_IC][6] = 80, + [0][0][2][0][RTW89_ACMA][6] = 60, + [0][0][2][0][RTW89_FCC][7] = 80, + [0][0][2][0][RTW89_ETSI][7] = 60, + [0][0][2][0][RTW89_MKK][7] = 76, + [0][0][2][0][RTW89_IC][7] = 80, + [0][0][2][0][RTW89_ACMA][7] = 60, + [0][0][2][0][RTW89_FCC][8] = 78, + [0][0][2][0][RTW89_ETSI][8] = 60, + [0][0][2][0][RTW89_MKK][8] = 76, + [0][0][2][0][RTW89_IC][8] = 78, + [0][0][2][0][RTW89_ACMA][8] = 60, + [0][0][2][0][RTW89_FCC][9] = 74, + [0][0][2][0][RTW89_ETSI][9] = 60, + [0][0][2][0][RTW89_MKK][9] = 76, + [0][0][2][0][RTW89_IC][9] = 74, + [0][0][2][0][RTW89_ACMA][9] = 60, + [0][0][2][0][RTW89_FCC][10] = 74, + [0][0][2][0][RTW89_ETSI][10] = 60, + [0][0][2][0][RTW89_MKK][10] = 76, + [0][0][2][0][RTW89_IC][10] = 74, + [0][0][2][0][RTW89_ACMA][10] = 60, + [0][0][2][0][RTW89_FCC][11] = 56, + [0][0][2][0][RTW89_ETSI][11] = 60, + [0][0][2][0][RTW89_MKK][11] = 76, + [0][0][2][0][RTW89_IC][11] = 56, + [0][0][2][0][RTW89_ACMA][11] = 60, + [0][0][2][0][RTW89_FCC][12] = 52, + [0][0][2][0][RTW89_ETSI][12] = 60, + [0][0][2][0][RTW89_MKK][12] = 76, + [0][0][2][0][RTW89_IC][12] = 52, + [0][0][2][0][RTW89_ACMA][12] = 60, + [0][0][2][0][RTW89_FCC][13] = 127, + [0][0][2][0][RTW89_ETSI][13] = 127, + [0][0][2][0][RTW89_MKK][13] = 127, + [0][0][2][0][RTW89_IC][13] = 127, + [0][0][2][0][RTW89_ACMA][13] = 127, + [0][1][2][0][RTW89_FCC][0] = 60, + [0][1][2][0][RTW89_ETSI][0] = 48, + [0][1][2][0][RTW89_MKK][0] = 70, + [0][1][2][0][RTW89_IC][0] = 60, + [0][1][2][0][RTW89_ACMA][0] = 48, + [0][1][2][0][RTW89_FCC][1] = 60, + [0][1][2][0][RTW89_ETSI][1] = 48, + [0][1][2][0][RTW89_MKK][1] = 70, + [0][1][2][0][RTW89_IC][1] = 60, + [0][1][2][0][RTW89_ACMA][1] = 48, + [0][1][2][0][RTW89_FCC][2] = 64, + [0][1][2][0][RTW89_ETSI][2] = 48, + [0][1][2][0][RTW89_MKK][2] = 70, + [0][1][2][0][RTW89_IC][2] = 64, + [0][1][2][0][RTW89_ACMA][2] = 48, + [0][1][2][0][RTW89_FCC][3] = 68, + [0][1][2][0][RTW89_ETSI][3] = 48, + [0][1][2][0][RTW89_MKK][3] = 70, + [0][1][2][0][RTW89_IC][3] = 68, + [0][1][2][0][RTW89_ACMA][3] = 48, + [0][1][2][0][RTW89_FCC][4] = 74, + [0][1][2][0][RTW89_ETSI][4] = 48, + [0][1][2][0][RTW89_MKK][4] = 70, + [0][1][2][0][RTW89_IC][4] = 74, + [0][1][2][0][RTW89_ACMA][4] = 48, + [0][1][2][0][RTW89_FCC][5] = 80, + [0][1][2][0][RTW89_ETSI][5] = 48, + [0][1][2][0][RTW89_MKK][5] = 70, + [0][1][2][0][RTW89_IC][5] = 80, + [0][1][2][0][RTW89_ACMA][5] = 48, + [0][1][2][0][RTW89_FCC][6] = 76, + [0][1][2][0][RTW89_ETSI][6] = 48, + [0][1][2][0][RTW89_MKK][6] = 70, + [0][1][2][0][RTW89_IC][6] = 76, + [0][1][2][0][RTW89_ACMA][6] = 48, + [0][1][2][0][RTW89_FCC][7] = 68, + [0][1][2][0][RTW89_ETSI][7] = 48, + [0][1][2][0][RTW89_MKK][7] = 70, + [0][1][2][0][RTW89_IC][7] = 68, + [0][1][2][0][RTW89_ACMA][7] = 48, + [0][1][2][0][RTW89_FCC][8] = 64, + [0][1][2][0][RTW89_ETSI][8] = 48, + [0][1][2][0][RTW89_MKK][8] = 70, + [0][1][2][0][RTW89_IC][8] = 64, + [0][1][2][0][RTW89_ACMA][8] = 48, + [0][1][2][0][RTW89_FCC][9] = 60, + [0][1][2][0][RTW89_ETSI][9] = 48, + [0][1][2][0][RTW89_MKK][9] = 70, + [0][1][2][0][RTW89_IC][9] = 60, + [0][1][2][0][RTW89_ACMA][9] = 48, + [0][1][2][0][RTW89_FCC][10] = 60, + [0][1][2][0][RTW89_ETSI][10] = 48, + [0][1][2][0][RTW89_MKK][10] = 70, + [0][1][2][0][RTW89_IC][10] = 60, + [0][1][2][0][RTW89_ACMA][10] = 48, + [0][1][2][0][RTW89_FCC][11] = 48, + [0][1][2][0][RTW89_ETSI][11] = 48, + [0][1][2][0][RTW89_MKK][11] = 70, + [0][1][2][0][RTW89_IC][11] = 48, + [0][1][2][0][RTW89_ACMA][11] = 48, + [0][1][2][0][RTW89_FCC][12] = 44, + [0][1][2][0][RTW89_ETSI][12] = 48, + [0][1][2][0][RTW89_MKK][12] = 70, + [0][1][2][0][RTW89_IC][12] = 44, + [0][1][2][0][RTW89_ACMA][12] = 48, + [0][1][2][0][RTW89_FCC][13] = 127, + [0][1][2][0][RTW89_ETSI][13] = 127, + [0][1][2][0][RTW89_MKK][13] = 127, + [0][1][2][0][RTW89_IC][13] = 127, + [0][1][2][0][RTW89_ACMA][13] = 127, + [0][1][2][1][RTW89_FCC][0] = 60, + [0][1][2][1][RTW89_ETSI][0] = 38, + [0][1][2][1][RTW89_MKK][0] = 58, + [0][1][2][1][RTW89_IC][0] = 60, + [0][1][2][1][RTW89_ACMA][0] = 36, + [0][1][2][1][RTW89_FCC][1] = 60, + [0][1][2][1][RTW89_ETSI][1] = 38, + [0][1][2][1][RTW89_MKK][1] = 58, + [0][1][2][1][RTW89_IC][1] = 60, + [0][1][2][1][RTW89_ACMA][1] = 36, + [0][1][2][1][RTW89_FCC][2] = 64, + [0][1][2][1][RTW89_ETSI][2] = 38, + [0][1][2][1][RTW89_MKK][2] = 58, + [0][1][2][1][RTW89_IC][2] = 64, + [0][1][2][1][RTW89_ACMA][2] = 36, + [0][1][2][1][RTW89_FCC][3] = 68, + [0][1][2][1][RTW89_ETSI][3] = 38, + [0][1][2][1][RTW89_MKK][3] = 58, + [0][1][2][1][RTW89_IC][3] = 68, + [0][1][2][1][RTW89_ACMA][3] = 36, + [0][1][2][1][RTW89_FCC][4] = 74, + [0][1][2][1][RTW89_ETSI][4] = 38, + [0][1][2][1][RTW89_MKK][4] = 58, + [0][1][2][1][RTW89_IC][4] = 74, + [0][1][2][1][RTW89_ACMA][4] = 36, + [0][1][2][1][RTW89_FCC][5] = 80, + [0][1][2][1][RTW89_ETSI][5] = 38, + [0][1][2][1][RTW89_MKK][5] = 58, + [0][1][2][1][RTW89_IC][5] = 80, + [0][1][2][1][RTW89_ACMA][5] = 36, + [0][1][2][1][RTW89_FCC][6] = 76, + [0][1][2][1][RTW89_ETSI][6] = 38, + [0][1][2][1][RTW89_MKK][6] = 58, + [0][1][2][1][RTW89_IC][6] = 76, + [0][1][2][1][RTW89_ACMA][6] = 36, + [0][1][2][1][RTW89_FCC][7] = 68, + [0][1][2][1][RTW89_ETSI][7] = 38, + [0][1][2][1][RTW89_MKK][7] = 58, + [0][1][2][1][RTW89_IC][7] = 68, + [0][1][2][1][RTW89_ACMA][7] = 36, + [0][1][2][1][RTW89_FCC][8] = 64, + [0][1][2][1][RTW89_ETSI][8] = 38, + [0][1][2][1][RTW89_MKK][8] = 58, + [0][1][2][1][RTW89_IC][8] = 64, + [0][1][2][1][RTW89_ACMA][8] = 36, + [0][1][2][1][RTW89_FCC][9] = 60, + [0][1][2][1][RTW89_ETSI][9] = 38, + [0][1][2][1][RTW89_MKK][9] = 58, + [0][1][2][1][RTW89_IC][9] = 60, + [0][1][2][1][RTW89_ACMA][9] = 36, + [0][1][2][1][RTW89_FCC][10] = 60, + [0][1][2][1][RTW89_ETSI][10] = 38, + [0][1][2][1][RTW89_MKK][10] = 58, + [0][1][2][1][RTW89_IC][10] = 60, + [0][1][2][1][RTW89_ACMA][10] = 36, + [0][1][2][1][RTW89_FCC][11] = 48, + [0][1][2][1][RTW89_ETSI][11] = 38, + [0][1][2][1][RTW89_MKK][11] = 58, + [0][1][2][1][RTW89_IC][11] = 48, + [0][1][2][1][RTW89_ACMA][11] = 36, + [0][1][2][1][RTW89_FCC][12] = 44, + [0][1][2][1][RTW89_ETSI][12] = 38, + [0][1][2][1][RTW89_MKK][12] = 58, + [0][1][2][1][RTW89_IC][12] = 44, + [0][1][2][1][RTW89_ACMA][12] = 36, + [0][1][2][1][RTW89_FCC][13] = 127, + [0][1][2][1][RTW89_ETSI][13] = 127, + [0][1][2][1][RTW89_MKK][13] = 127, + [0][1][2][1][RTW89_IC][13] = 127, + [0][1][2][1][RTW89_ACMA][13] = 127, + [1][0][2][0][RTW89_FCC][0] = 127, + [1][0][2][0][RTW89_ETSI][0] = 127, + [1][0][2][0][RTW89_MKK][0] = 127, + [1][0][2][0][RTW89_IC][0] = 127, + [1][0][2][0][RTW89_ACMA][0] = 127, + [1][0][2][0][RTW89_FCC][1] = 127, + [1][0][2][0][RTW89_ETSI][1] = 127, + [1][0][2][0][RTW89_MKK][1] = 127, + [1][0][2][0][RTW89_IC][1] = 127, + [1][0][2][0][RTW89_ACMA][1] = 127, + [1][0][2][0][RTW89_FCC][2] = 72, + [1][0][2][0][RTW89_ETSI][2] = 60, + [1][0][2][0][RTW89_MKK][2] = 72, + [1][0][2][0][RTW89_IC][2] = 72, + [1][0][2][0][RTW89_ACMA][2] = 60, + [1][0][2][0][RTW89_FCC][3] = 72, + [1][0][2][0][RTW89_ETSI][3] = 60, + [1][0][2][0][RTW89_MKK][3] = 72, + [1][0][2][0][RTW89_IC][3] = 72, + [1][0][2][0][RTW89_ACMA][3] = 60, + [1][0][2][0][RTW89_FCC][4] = 74, + [1][0][2][0][RTW89_ETSI][4] = 60, + [1][0][2][0][RTW89_MKK][4] = 72, + [1][0][2][0][RTW89_IC][4] = 74, + [1][0][2][0][RTW89_ACMA][4] = 60, + [1][0][2][0][RTW89_FCC][5] = 74, + [1][0][2][0][RTW89_ETSI][5] = 60, + [1][0][2][0][RTW89_MKK][5] = 72, + [1][0][2][0][RTW89_IC][5] = 74, + [1][0][2][0][RTW89_ACMA][5] = 60, + [1][0][2][0][RTW89_FCC][6] = 74, + [1][0][2][0][RTW89_ETSI][6] = 60, + [1][0][2][0][RTW89_MKK][6] = 72, + [1][0][2][0][RTW89_IC][6] = 74, + [1][0][2][0][RTW89_ACMA][6] = 60, + [1][0][2][0][RTW89_FCC][7] = 70, + [1][0][2][0][RTW89_ETSI][7] = 60, + [1][0][2][0][RTW89_MKK][7] = 72, + [1][0][2][0][RTW89_IC][7] = 70, + [1][0][2][0][RTW89_ACMA][7] = 60, + [1][0][2][0][RTW89_FCC][8] = 70, + [1][0][2][0][RTW89_ETSI][8] = 60, + [1][0][2][0][RTW89_MKK][8] = 72, + [1][0][2][0][RTW89_IC][8] = 70, + [1][0][2][0][RTW89_ACMA][8] = 60, + [1][0][2][0][RTW89_FCC][9] = 70, + [1][0][2][0][RTW89_ETSI][9] = 60, + [1][0][2][0][RTW89_MKK][9] = 72, + [1][0][2][0][RTW89_IC][9] = 70, + [1][0][2][0][RTW89_ACMA][9] = 60, + [1][0][2][0][RTW89_FCC][10] = 68, + [1][0][2][0][RTW89_ETSI][10] = 60, + [1][0][2][0][RTW89_MKK][10] = 72, + [1][0][2][0][RTW89_IC][10] = 68, + [1][0][2][0][RTW89_ACMA][10] = 60, + [1][0][2][0][RTW89_FCC][11] = 127, + [1][0][2][0][RTW89_ETSI][11] = 127, + [1][0][2][0][RTW89_MKK][11] = 127, + [1][0][2][0][RTW89_IC][11] = 127, + [1][0][2][0][RTW89_ACMA][11] = 127, + [1][0][2][0][RTW89_FCC][12] = 127, + [1][0][2][0][RTW89_ETSI][12] = 127, + [1][0][2][0][RTW89_MKK][12] = 127, + [1][0][2][0][RTW89_IC][12] = 127, + [1][0][2][0][RTW89_ACMA][12] = 127, + [1][0][2][0][RTW89_FCC][13] = 127, + [1][0][2][0][RTW89_ETSI][13] = 127, + [1][0][2][0][RTW89_MKK][13] = 127, + [1][0][2][0][RTW89_IC][13] = 127, + [1][0][2][0][RTW89_ACMA][13] = 127, + [1][1][2][0][RTW89_FCC][0] = 127, + [1][1][2][0][RTW89_ETSI][0] = 127, + [1][1][2][0][RTW89_MKK][0] = 127, + [1][1][2][0][RTW89_IC][0] = 127, + [1][1][2][0][RTW89_ACMA][0] = 127, + [1][1][2][0][RTW89_FCC][1] = 127, + [1][1][2][0][RTW89_ETSI][1] = 127, + [1][1][2][0][RTW89_MKK][1] = 127, + [1][1][2][0][RTW89_IC][1] = 127, + [1][1][2][0][RTW89_ACMA][1] = 127, + [1][1][2][0][RTW89_FCC][2] = 56, + [1][1][2][0][RTW89_ETSI][2] = 48, + [1][1][2][0][RTW89_MKK][2] = 70, + [1][1][2][0][RTW89_IC][2] = 56, + [1][1][2][0][RTW89_ACMA][2] = 48, + [1][1][2][0][RTW89_FCC][3] = 56, + [1][1][2][0][RTW89_ETSI][3] = 48, + [1][1][2][0][RTW89_MKK][3] = 70, + [1][1][2][0][RTW89_IC][3] = 56, + [1][1][2][0][RTW89_ACMA][3] = 48, + [1][1][2][0][RTW89_FCC][4] = 60, + [1][1][2][0][RTW89_ETSI][4] = 48, + [1][1][2][0][RTW89_MKK][4] = 70, + [1][1][2][0][RTW89_IC][4] = 60, + [1][1][2][0][RTW89_ACMA][4] = 48, + [1][1][2][0][RTW89_FCC][5] = 68, + [1][1][2][0][RTW89_ETSI][5] = 48, + [1][1][2][0][RTW89_MKK][5] = 70, + [1][1][2][0][RTW89_IC][5] = 68, + [1][1][2][0][RTW89_ACMA][5] = 48, + [1][1][2][0][RTW89_FCC][6] = 60, + [1][1][2][0][RTW89_ETSI][6] = 48, + [1][1][2][0][RTW89_MKK][6] = 70, + [1][1][2][0][RTW89_IC][6] = 60, + [1][1][2][0][RTW89_ACMA][6] = 48, + [1][1][2][0][RTW89_FCC][7] = 56, + [1][1][2][0][RTW89_ETSI][7] = 48, + [1][1][2][0][RTW89_MKK][7] = 70, + [1][1][2][0][RTW89_IC][7] = 56, + [1][1][2][0][RTW89_ACMA][7] = 48, + [1][1][2][0][RTW89_FCC][8] = 56, + [1][1][2][0][RTW89_ETSI][8] = 48, + [1][1][2][0][RTW89_MKK][8] = 70, + [1][1][2][0][RTW89_IC][8] = 56, + [1][1][2][0][RTW89_ACMA][8] = 48, + [1][1][2][0][RTW89_FCC][9] = 44, + [1][1][2][0][RTW89_ETSI][9] = 48, + [1][1][2][0][RTW89_MKK][9] = 70, + [1][1][2][0][RTW89_IC][9] = 44, + [1][1][2][0][RTW89_ACMA][9] = 48, + [1][1][2][0][RTW89_FCC][10] = 40, + [1][1][2][0][RTW89_ETSI][10] = 48, + [1][1][2][0][RTW89_MKK][10] = 70, + [1][1][2][0][RTW89_IC][10] = 40, + [1][1][2][0][RTW89_ACMA][10] = 48, + [1][1][2][0][RTW89_FCC][11] = 127, + [1][1][2][0][RTW89_ETSI][11] = 127, + [1][1][2][0][RTW89_MKK][11] = 127, + [1][1][2][0][RTW89_IC][11] = 127, + [1][1][2][0][RTW89_ACMA][11] = 127, + [1][1][2][0][RTW89_FCC][12] = 127, + [1][1][2][0][RTW89_ETSI][12] = 127, + [1][1][2][0][RTW89_MKK][12] = 127, + [1][1][2][0][RTW89_IC][12] = 127, + [1][1][2][0][RTW89_ACMA][12] = 127, + [1][1][2][0][RTW89_FCC][13] = 127, + [1][1][2][0][RTW89_ETSI][13] = 127, + [1][1][2][0][RTW89_MKK][13] = 127, + [1][1][2][0][RTW89_IC][13] = 127, + [1][1][2][0][RTW89_ACMA][13] = 127, + [1][1][2][1][RTW89_FCC][0] = 127, + [1][1][2][1][RTW89_ETSI][0] = 127, + [1][1][2][1][RTW89_MKK][0] = 127, + [1][1][2][1][RTW89_IC][0] = 127, + [1][1][2][1][RTW89_ACMA][0] = 127, + [1][1][2][1][RTW89_FCC][1] = 127, + [1][1][2][1][RTW89_ETSI][1] = 127, + [1][1][2][1][RTW89_MKK][1] = 127, + [1][1][2][1][RTW89_IC][1] = 127, + [1][1][2][1][RTW89_ACMA][1] = 127, + [1][1][2][1][RTW89_FCC][2] = 56, + [1][1][2][1][RTW89_ETSI][2] = 38, + [1][1][2][1][RTW89_MKK][2] = 58, + [1][1][2][1][RTW89_IC][2] = 56, + [1][1][2][1][RTW89_ACMA][2] = 36, + [1][1][2][1][RTW89_FCC][3] = 56, + [1][1][2][1][RTW89_ETSI][3] = 38, + [1][1][2][1][RTW89_MKK][3] = 58, + [1][1][2][1][RTW89_IC][3] = 56, + [1][1][2][1][RTW89_ACMA][3] = 36, + [1][1][2][1][RTW89_FCC][4] = 60, + [1][1][2][1][RTW89_ETSI][4] = 38, + [1][1][2][1][RTW89_MKK][4] = 58, + [1][1][2][1][RTW89_IC][4] = 60, + [1][1][2][1][RTW89_ACMA][4] = 36, + [1][1][2][1][RTW89_FCC][5] = 68, + [1][1][2][1][RTW89_ETSI][5] = 38, + [1][1][2][1][RTW89_MKK][5] = 58, + [1][1][2][1][RTW89_IC][5] = 68, + [1][1][2][1][RTW89_ACMA][5] = 36, + [1][1][2][1][RTW89_FCC][6] = 60, + [1][1][2][1][RTW89_ETSI][6] = 38, + [1][1][2][1][RTW89_MKK][6] = 58, + [1][1][2][1][RTW89_IC][6] = 60, + [1][1][2][1][RTW89_ACMA][6] = 36, + [1][1][2][1][RTW89_FCC][7] = 56, + [1][1][2][1][RTW89_ETSI][7] = 38, + [1][1][2][1][RTW89_MKK][7] = 58, + [1][1][2][1][RTW89_IC][7] = 56, + [1][1][2][1][RTW89_ACMA][7] = 36, + [1][1][2][1][RTW89_FCC][8] = 56, + [1][1][2][1][RTW89_ETSI][8] = 38, + [1][1][2][1][RTW89_MKK][8] = 58, + [1][1][2][1][RTW89_IC][8] = 56, + [1][1][2][1][RTW89_ACMA][8] = 36, + [1][1][2][1][RTW89_FCC][9] = 44, + [1][1][2][1][RTW89_ETSI][9] = 38, + [1][1][2][1][RTW89_MKK][9] = 58, + [1][1][2][1][RTW89_IC][9] = 44, + [1][1][2][1][RTW89_ACMA][9] = 36, + [1][1][2][1][RTW89_FCC][10] = 40, + [1][1][2][1][RTW89_ETSI][10] = 38, + [1][1][2][1][RTW89_MKK][10] = 58, + [1][1][2][1][RTW89_IC][10] = 40, + [1][1][2][1][RTW89_ACMA][10] = 36, + [1][1][2][1][RTW89_FCC][11] = 127, + [1][1][2][1][RTW89_ETSI][11] = 127, + [1][1][2][1][RTW89_MKK][11] = 127, + [1][1][2][1][RTW89_IC][11] = 127, + [1][1][2][1][RTW89_ACMA][11] = 127, + [1][1][2][1][RTW89_FCC][12] = 127, + [1][1][2][1][RTW89_ETSI][12] = 127, + [1][1][2][1][RTW89_MKK][12] = 127, + [1][1][2][1][RTW89_IC][12] = 127, + [1][1][2][1][RTW89_ACMA][12] = 127, + [1][1][2][1][RTW89_FCC][13] = 127, + [1][1][2][1][RTW89_ETSI][13] = 127, + [1][1][2][1][RTW89_MKK][13] = 127, + [1][1][2][1][RTW89_IC][13] = 127, + [1][1][2][1][RTW89_ACMA][13] = 127, +}; + +const s8 rtw89_8852c_txpwr_lmt_5g[RTW89_5G_BW_NUM][RTW89_NTX_NUM] + [RTW89_RS_LMT_NUM][RTW89_BF_NUM] + [RTW89_REGD_NUM][RTW89_5G_CH_NUM] = { + [0][0][1][0][RTW89_WW][0] = 60, + [0][0][1][0][RTW89_WW][2] = 60, + [0][0][1][0][RTW89_WW][4] = 60, + [0][0][1][0][RTW89_WW][6] = 60, + [0][0][1][0][RTW89_WW][8] = 60, + [0][0][1][0][RTW89_WW][10] = 60, + [0][0][1][0][RTW89_WW][12] = 60, + [0][0][1][0][RTW89_WW][14] = 60, + [0][0][1][0][RTW89_WW][15] = 60, + [0][0][1][0][RTW89_WW][17] = 60, + [0][0][1][0][RTW89_WW][19] = 60, + [0][0][1][0][RTW89_WW][21] = 60, + [0][0][1][0][RTW89_WW][23] = 60, + [0][0][1][0][RTW89_WW][25] = 60, + [0][0][1][0][RTW89_WW][27] = 60, + [0][0][1][0][RTW89_WW][29] = 60, + [0][0][1][0][RTW89_WW][31] = 60, + [0][0][1][0][RTW89_WW][33] = 60, + [0][0][1][0][RTW89_WW][35] = 60, + [0][0][1][0][RTW89_WW][37] = 78, + [0][0][1][0][RTW89_WW][38] = 30, + [0][0][1][0][RTW89_WW][40] = 30, + [0][0][1][0][RTW89_WW][42] = 30, + [0][0][1][0][RTW89_WW][44] = 30, + [0][0][1][0][RTW89_WW][46] = 30, + [0][0][1][0][RTW89_WW][48] = 80, + [0][0][1][0][RTW89_WW][50] = 80, + [0][0][1][0][RTW89_WW][52] = 80, + [0][1][1][0][RTW89_WW][0] = 42, + [0][1][1][0][RTW89_WW][2] = 42, + [0][1][1][0][RTW89_WW][4] = 42, + [0][1][1][0][RTW89_WW][6] = 42, + [0][1][1][0][RTW89_WW][8] = 48, + [0][1][1][0][RTW89_WW][10] = 48, + [0][1][1][0][RTW89_WW][12] = 48, + [0][1][1][0][RTW89_WW][14] = 48, + [0][1][1][0][RTW89_WW][15] = 48, + [0][1][1][0][RTW89_WW][17] = 48, + [0][1][1][0][RTW89_WW][19] = 48, + [0][1][1][0][RTW89_WW][21] = 48, + [0][1][1][0][RTW89_WW][23] = 48, + [0][1][1][0][RTW89_WW][25] = 48, + [0][1][1][0][RTW89_WW][27] = 48, + [0][1][1][0][RTW89_WW][29] = 48, + [0][1][1][0][RTW89_WW][31] = 48, + [0][1][1][0][RTW89_WW][33] = 48, + [0][1][1][0][RTW89_WW][35] = 48, + [0][1][1][0][RTW89_WW][37] = 70, + [0][1][1][0][RTW89_WW][38] = 18, + [0][1][1][0][RTW89_WW][40] = 16, + [0][1][1][0][RTW89_WW][42] = 18, + [0][1][1][0][RTW89_WW][44] = 16, + [0][1][1][0][RTW89_WW][46] = 18, + [0][1][1][0][RTW89_WW][48] = 58, + [0][1][1][0][RTW89_WW][50] = 58, + [0][1][1][0][RTW89_WW][52] = 58, + [0][0][2][0][RTW89_WW][0] = 62, + [0][0][2][0][RTW89_WW][2] = 62, + [0][0][2][0][RTW89_WW][4] = 62, + [0][0][2][0][RTW89_WW][6] = 62, + [0][0][2][0][RTW89_WW][8] = 62, + [0][0][2][0][RTW89_WW][10] = 62, + [0][0][2][0][RTW89_WW][12] = 62, + [0][0][2][0][RTW89_WW][14] = 62, + [0][0][2][0][RTW89_WW][15] = 62, + [0][0][2][0][RTW89_WW][17] = 62, + [0][0][2][0][RTW89_WW][19] = 62, + [0][0][2][0][RTW89_WW][21] = 62, + [0][0][2][0][RTW89_WW][23] = 62, + [0][0][2][0][RTW89_WW][25] = 62, + [0][0][2][0][RTW89_WW][27] = 62, + [0][0][2][0][RTW89_WW][29] = 62, + [0][0][2][0][RTW89_WW][31] = 62, + [0][0][2][0][RTW89_WW][33] = 62, + [0][0][2][0][RTW89_WW][35] = 62, + [0][0][2][0][RTW89_WW][37] = 78, + [0][0][2][0][RTW89_WW][38] = 30, + [0][0][2][0][RTW89_WW][40] = 30, + [0][0][2][0][RTW89_WW][42] = 30, + [0][0][2][0][RTW89_WW][44] = 30, + [0][0][2][0][RTW89_WW][46] = 30, + [0][0][2][0][RTW89_WW][48] = 80, + [0][0][2][0][RTW89_WW][50] = 80, + [0][0][2][0][RTW89_WW][52] = 80, + [0][1][2][0][RTW89_WW][0] = 44, + [0][1][2][0][RTW89_WW][2] = 44, + [0][1][2][0][RTW89_WW][4] = 44, + [0][1][2][0][RTW89_WW][6] = 44, + [0][1][2][0][RTW89_WW][8] = 50, + [0][1][2][0][RTW89_WW][10] = 50, + [0][1][2][0][RTW89_WW][12] = 50, + [0][1][2][0][RTW89_WW][14] = 50, + [0][1][2][0][RTW89_WW][15] = 50, + [0][1][2][0][RTW89_WW][17] = 50, + [0][1][2][0][RTW89_WW][19] = 50, + [0][1][2][0][RTW89_WW][21] = 50, + [0][1][2][0][RTW89_WW][23] = 50, + [0][1][2][0][RTW89_WW][25] = 50, + [0][1][2][0][RTW89_WW][27] = 50, + [0][1][2][0][RTW89_WW][29] = 50, + [0][1][2][0][RTW89_WW][31] = 50, + [0][1][2][0][RTW89_WW][33] = 50, + [0][1][2][0][RTW89_WW][35] = 50, + [0][1][2][0][RTW89_WW][37] = 72, + [0][1][2][0][RTW89_WW][38] = 18, + [0][1][2][0][RTW89_WW][40] = 18, + [0][1][2][0][RTW89_WW][42] = 18, + [0][1][2][0][RTW89_WW][44] = 18, + [0][1][2][0][RTW89_WW][46] = 18, + [0][1][2][0][RTW89_WW][48] = 60, + [0][1][2][0][RTW89_WW][50] = 60, + [0][1][2][0][RTW89_WW][52] = 60, + [0][1][2][1][RTW89_WW][0] = 38, + [0][1][2][1][RTW89_WW][2] = 38, + [0][1][2][1][RTW89_WW][4] = 38, + [0][1][2][1][RTW89_WW][6] = 38, + [0][1][2][1][RTW89_WW][8] = 38, + [0][1][2][1][RTW89_WW][10] = 38, + [0][1][2][1][RTW89_WW][12] = 38, + [0][1][2][1][RTW89_WW][14] = 38, + [0][1][2][1][RTW89_WW][15] = 38, + [0][1][2][1][RTW89_WW][17] = 38, + [0][1][2][1][RTW89_WW][19] = 38, + [0][1][2][1][RTW89_WW][21] = 38, + [0][1][2][1][RTW89_WW][23] = 38, + [0][1][2][1][RTW89_WW][25] = 42, + [0][1][2][1][RTW89_WW][27] = 42, + [0][1][2][1][RTW89_WW][29] = 42, + [0][1][2][1][RTW89_WW][31] = 38, + [0][1][2][1][RTW89_WW][33] = 38, + [0][1][2][1][RTW89_WW][35] = 38, + [0][1][2][1][RTW89_WW][37] = 70, + [0][1][2][1][RTW89_WW][38] = 8, + [0][1][2][1][RTW89_WW][40] = 8, + [0][1][2][1][RTW89_WW][42] = 8, + [0][1][2][1][RTW89_WW][44] = 8, + [0][1][2][1][RTW89_WW][46] = 8, + [0][1][2][1][RTW89_WW][48] = 60, + [0][1][2][1][RTW89_WW][50] = 60, + [0][1][2][1][RTW89_WW][52] = 60, + [1][0][2][0][RTW89_WW][1] = 66, + [1][0][2][0][RTW89_WW][5] = 66, + [1][0][2][0][RTW89_WW][9] = 66, + [1][0][2][0][RTW89_WW][13] = 66, + [1][0][2][0][RTW89_WW][16] = 66, + [1][0][2][0][RTW89_WW][20] = 66, + [1][0][2][0][RTW89_WW][24] = 66, + [1][0][2][0][RTW89_WW][28] = 66, + [1][0][2][0][RTW89_WW][32] = 66, + [1][0][2][0][RTW89_WW][36] = 76, + [1][0][2][0][RTW89_WW][39] = 30, + [1][0][2][0][RTW89_WW][43] = 30, + [1][0][2][0][RTW89_WW][47] = 80, + [1][0][2][0][RTW89_WW][51] = 72, + [1][1][2][0][RTW89_WW][1] = 54, + [1][1][2][0][RTW89_WW][5] = 54, + [1][1][2][0][RTW89_WW][9] = 54, + [1][1][2][0][RTW89_WW][13] = 54, + [1][1][2][0][RTW89_WW][16] = 54, + [1][1][2][0][RTW89_WW][20] = 54, + [1][1][2][0][RTW89_WW][24] = 54, + [1][1][2][0][RTW89_WW][28] = 54, + [1][1][2][0][RTW89_WW][32] = 54, + [1][1][2][0][RTW89_WW][36] = 72, + [1][1][2][0][RTW89_WW][39] = 18, + [1][1][2][0][RTW89_WW][43] = 18, + [1][1][2][0][RTW89_WW][47] = 70, + [1][1][2][0][RTW89_WW][51] = 68, + [1][1][2][1][RTW89_WW][1] = 42, + [1][1][2][1][RTW89_WW][5] = 42, + [1][1][2][1][RTW89_WW][9] = 42, + [1][1][2][1][RTW89_WW][13] = 42, + [1][1][2][1][RTW89_WW][16] = 42, + [1][1][2][1][RTW89_WW][20] = 42, + [1][1][2][1][RTW89_WW][24] = 42, + [1][1][2][1][RTW89_WW][28] = 42, + [1][1][2][1][RTW89_WW][32] = 42, + [1][1][2][1][RTW89_WW][36] = 70, + [1][1][2][1][RTW89_WW][39] = 8, + [1][1][2][1][RTW89_WW][43] = 8, + [1][1][2][1][RTW89_WW][47] = 70, + [1][1][2][1][RTW89_WW][51] = 68, + [2][0][2][0][RTW89_WW][3] = 64, + [2][0][2][0][RTW89_WW][11] = 66, + [2][0][2][0][RTW89_WW][18] = 64, + [2][0][2][0][RTW89_WW][26] = 66, + [2][0][2][0][RTW89_WW][34] = 72, + [2][0][2][0][RTW89_WW][41] = 30, + [2][0][2][0][RTW89_WW][49] = 66, + [2][1][2][0][RTW89_WW][3] = 54, + [2][1][2][0][RTW89_WW][11] = 54, + [2][1][2][0][RTW89_WW][18] = 54, + [2][1][2][0][RTW89_WW][26] = 54, + [2][1][2][0][RTW89_WW][34] = 72, + [2][1][2][0][RTW89_WW][41] = 18, + [2][1][2][0][RTW89_WW][49] = 60, + [2][1][2][1][RTW89_WW][3] = 42, + [2][1][2][1][RTW89_WW][11] = 42, + [2][1][2][1][RTW89_WW][18] = 42, + [2][1][2][1][RTW89_WW][26] = 44, + [2][1][2][1][RTW89_WW][34] = 70, + [2][1][2][1][RTW89_WW][41] = 8, + [2][1][2][1][RTW89_WW][49] = 60, + [3][0][2][0][RTW89_WW][7] = 56, + [3][0][2][0][RTW89_WW][22] = 56, + [3][0][2][0][RTW89_WW][45] = 56, + [3][1][2][0][RTW89_WW][7] = 44, + [3][1][2][0][RTW89_WW][22] = 44, + [3][1][2][0][RTW89_WW][45] = 44, + [3][1][2][1][RTW89_WW][7] = 32, + [3][1][2][1][RTW89_WW][22] = 32, + [3][1][2][1][RTW89_WW][45] = 32, + [0][0][1][0][RTW89_FCC][0] = 80, + [0][0][1][0][RTW89_ETSI][0] = 60, + [0][0][1][0][RTW89_MKK][0] = 62, + [0][0][1][0][RTW89_IC][0] = 62, + [0][0][1][0][RTW89_ACMA][0] = 60, + [0][0][1][0][RTW89_FCC][2] = 80, + [0][0][1][0][RTW89_ETSI][2] = 60, + [0][0][1][0][RTW89_MKK][2] = 62, + [0][0][1][0][RTW89_IC][2] = 62, + [0][0][1][0][RTW89_ACMA][2] = 60, + [0][0][1][0][RTW89_FCC][4] = 80, + [0][0][1][0][RTW89_ETSI][4] = 60, + [0][0][1][0][RTW89_MKK][4] = 62, + [0][0][1][0][RTW89_IC][4] = 62, + [0][0][1][0][RTW89_ACMA][4] = 60, + [0][0][1][0][RTW89_FCC][6] = 80, + [0][0][1][0][RTW89_ETSI][6] = 60, + [0][0][1][0][RTW89_MKK][6] = 62, + [0][0][1][0][RTW89_IC][6] = 62, + [0][0][1][0][RTW89_ACMA][6] = 60, + [0][0][1][0][RTW89_FCC][8] = 80, + [0][0][1][0][RTW89_ETSI][8] = 60, + [0][0][1][0][RTW89_MKK][8] = 64, + [0][0][1][0][RTW89_IC][8] = 66, + [0][0][1][0][RTW89_ACMA][8] = 60, + [0][0][1][0][RTW89_FCC][10] = 80, + [0][0][1][0][RTW89_ETSI][10] = 60, + [0][0][1][0][RTW89_MKK][10] = 64, + [0][0][1][0][RTW89_IC][10] = 66, + [0][0][1][0][RTW89_ACMA][10] = 60, + [0][0][1][0][RTW89_FCC][12] = 80, + [0][0][1][0][RTW89_ETSI][12] = 60, + [0][0][1][0][RTW89_MKK][12] = 64, + [0][0][1][0][RTW89_IC][12] = 66, + [0][0][1][0][RTW89_ACMA][12] = 60, + [0][0][1][0][RTW89_FCC][14] = 80, + [0][0][1][0][RTW89_ETSI][14] = 60, + [0][0][1][0][RTW89_MKK][14] = 62, + [0][0][1][0][RTW89_IC][14] = 66, + [0][0][1][0][RTW89_ACMA][14] = 60, + [0][0][1][0][RTW89_FCC][15] = 78, + [0][0][1][0][RTW89_ETSI][15] = 60, + [0][0][1][0][RTW89_MKK][15] = 78, + [0][0][1][0][RTW89_IC][15] = 78, + [0][0][1][0][RTW89_ACMA][15] = 60, + [0][0][1][0][RTW89_FCC][17] = 80, + [0][0][1][0][RTW89_ETSI][17] = 60, + [0][0][1][0][RTW89_MKK][17] = 78, + [0][0][1][0][RTW89_IC][17] = 80, + [0][0][1][0][RTW89_ACMA][17] = 60, + [0][0][1][0][RTW89_FCC][19] = 80, + [0][0][1][0][RTW89_ETSI][19] = 60, + [0][0][1][0][RTW89_MKK][19] = 78, + [0][0][1][0][RTW89_IC][19] = 80, + [0][0][1][0][RTW89_ACMA][19] = 60, + [0][0][1][0][RTW89_FCC][21] = 80, + [0][0][1][0][RTW89_ETSI][21] = 60, + [0][0][1][0][RTW89_MKK][21] = 78, + [0][0][1][0][RTW89_IC][21] = 80, + [0][0][1][0][RTW89_ACMA][21] = 60, + [0][0][1][0][RTW89_FCC][23] = 80, + [0][0][1][0][RTW89_ETSI][23] = 60, + [0][0][1][0][RTW89_MKK][23] = 78, + [0][0][1][0][RTW89_IC][23] = 80, + [0][0][1][0][RTW89_ACMA][23] = 60, + [0][0][1][0][RTW89_FCC][25] = 80, + [0][0][1][0][RTW89_ETSI][25] = 60, + [0][0][1][0][RTW89_MKK][25] = 78, + [0][0][1][0][RTW89_IC][25] = 127, + [0][0][1][0][RTW89_ACMA][25] = 127, + [0][0][1][0][RTW89_FCC][27] = 80, + [0][0][1][0][RTW89_ETSI][27] = 60, + [0][0][1][0][RTW89_MKK][27] = 78, + [0][0][1][0][RTW89_IC][27] = 127, + [0][0][1][0][RTW89_ACMA][27] = 127, + [0][0][1][0][RTW89_FCC][29] = 80, + [0][0][1][0][RTW89_ETSI][29] = 60, + [0][0][1][0][RTW89_MKK][29] = 78, + [0][0][1][0][RTW89_IC][29] = 127, + [0][0][1][0][RTW89_ACMA][29] = 127, + [0][0][1][0][RTW89_FCC][31] = 80, + [0][0][1][0][RTW89_ETSI][31] = 60, + [0][0][1][0][RTW89_MKK][31] = 78, + [0][0][1][0][RTW89_IC][31] = 80, + [0][0][1][0][RTW89_ACMA][31] = 60, + [0][0][1][0][RTW89_FCC][33] = 80, + [0][0][1][0][RTW89_ETSI][33] = 60, + [0][0][1][0][RTW89_MKK][33] = 78, + [0][0][1][0][RTW89_IC][33] = 80, + [0][0][1][0][RTW89_ACMA][33] = 60, + [0][0][1][0][RTW89_FCC][35] = 72, + [0][0][1][0][RTW89_ETSI][35] = 60, + [0][0][1][0][RTW89_MKK][35] = 78, + [0][0][1][0][RTW89_IC][35] = 72, + [0][0][1][0][RTW89_ACMA][35] = 60, + [0][0][1][0][RTW89_FCC][37] = 80, + [0][0][1][0][RTW89_ETSI][37] = 127, + [0][0][1][0][RTW89_MKK][37] = 78, + [0][0][1][0][RTW89_IC][37] = 80, + [0][0][1][0][RTW89_ACMA][37] = 78, + [0][0][1][0][RTW89_FCC][38] = 80, + [0][0][1][0][RTW89_ETSI][38] = 30, + [0][0][1][0][RTW89_MKK][38] = 127, + [0][0][1][0][RTW89_IC][38] = 80, + [0][0][1][0][RTW89_ACMA][38] = 78, + [0][0][1][0][RTW89_FCC][40] = 80, + [0][0][1][0][RTW89_ETSI][40] = 30, + [0][0][1][0][RTW89_MKK][40] = 127, + [0][0][1][0][RTW89_IC][40] = 80, + [0][0][1][0][RTW89_ACMA][40] = 78, + [0][0][1][0][RTW89_FCC][42] = 80, + [0][0][1][0][RTW89_ETSI][42] = 30, + [0][0][1][0][RTW89_MKK][42] = 127, + [0][0][1][0][RTW89_IC][42] = 80, + [0][0][1][0][RTW89_ACMA][42] = 78, + [0][0][1][0][RTW89_FCC][44] = 80, + [0][0][1][0][RTW89_ETSI][44] = 30, + [0][0][1][0][RTW89_MKK][44] = 127, + [0][0][1][0][RTW89_IC][44] = 80, + [0][0][1][0][RTW89_ACMA][44] = 78, + [0][0][1][0][RTW89_FCC][46] = 80, + [0][0][1][0][RTW89_ETSI][46] = 30, + [0][0][1][0][RTW89_MKK][46] = 127, + [0][0][1][0][RTW89_IC][46] = 80, + [0][0][1][0][RTW89_ACMA][46] = 78, + [0][0][1][0][RTW89_FCC][48] = 80, + [0][0][1][0][RTW89_ETSI][48] = 127, + [0][0][1][0][RTW89_MKK][48] = 127, + [0][0][1][0][RTW89_IC][48] = 127, + [0][0][1][0][RTW89_ACMA][48] = 127, + [0][0][1][0][RTW89_FCC][50] = 80, + [0][0][1][0][RTW89_ETSI][50] = 127, + [0][0][1][0][RTW89_MKK][50] = 127, + [0][0][1][0][RTW89_IC][50] = 127, + [0][0][1][0][RTW89_ACMA][50] = 127, + [0][0][1][0][RTW89_FCC][52] = 80, + [0][0][1][0][RTW89_ETSI][52] = 127, + [0][0][1][0][RTW89_MKK][52] = 127, + [0][0][1][0][RTW89_IC][52] = 127, + [0][0][1][0][RTW89_ACMA][52] = 127, + [0][1][1][0][RTW89_FCC][0] = 70, + [0][1][1][0][RTW89_ETSI][0] = 48, + [0][1][1][0][RTW89_MKK][0] = 50, + [0][1][1][0][RTW89_IC][0] = 42, + [0][1][1][0][RTW89_ACMA][0] = 48, + [0][1][1][0][RTW89_FCC][2] = 70, + [0][1][1][0][RTW89_ETSI][2] = 48, + [0][1][1][0][RTW89_MKK][2] = 50, + [0][1][1][0][RTW89_IC][2] = 42, + [0][1][1][0][RTW89_ACMA][2] = 48, + [0][1][1][0][RTW89_FCC][4] = 70, + [0][1][1][0][RTW89_ETSI][4] = 48, + [0][1][1][0][RTW89_MKK][4] = 50, + [0][1][1][0][RTW89_IC][4] = 42, + [0][1][1][0][RTW89_ACMA][4] = 48, + [0][1][1][0][RTW89_FCC][6] = 70, + [0][1][1][0][RTW89_ETSI][6] = 48, + [0][1][1][0][RTW89_MKK][6] = 50, + [0][1][1][0][RTW89_IC][6] = 42, + [0][1][1][0][RTW89_ACMA][6] = 48, + [0][1][1][0][RTW89_FCC][8] = 70, + [0][1][1][0][RTW89_ETSI][8] = 48, + [0][1][1][0][RTW89_MKK][8] = 50, + [0][1][1][0][RTW89_IC][8] = 54, + [0][1][1][0][RTW89_ACMA][8] = 48, + [0][1][1][0][RTW89_FCC][10] = 70, + [0][1][1][0][RTW89_ETSI][10] = 48, + [0][1][1][0][RTW89_MKK][10] = 50, + [0][1][1][0][RTW89_IC][10] = 54, + [0][1][1][0][RTW89_ACMA][10] = 48, + [0][1][1][0][RTW89_FCC][12] = 70, + [0][1][1][0][RTW89_ETSI][12] = 48, + [0][1][1][0][RTW89_MKK][12] = 50, + [0][1][1][0][RTW89_IC][12] = 54, + [0][1][1][0][RTW89_ACMA][12] = 48, + [0][1][1][0][RTW89_FCC][14] = 70, + [0][1][1][0][RTW89_ETSI][14] = 48, + [0][1][1][0][RTW89_MKK][14] = 50, + [0][1][1][0][RTW89_IC][14] = 54, + [0][1][1][0][RTW89_ACMA][14] = 48, + [0][1][1][0][RTW89_FCC][15] = 68, + [0][1][1][0][RTW89_ETSI][15] = 48, + [0][1][1][0][RTW89_MKK][15] = 70, + [0][1][1][0][RTW89_IC][15] = 68, + [0][1][1][0][RTW89_ACMA][15] = 48, + [0][1][1][0][RTW89_FCC][17] = 70, + [0][1][1][0][RTW89_ETSI][17] = 48, + [0][1][1][0][RTW89_MKK][17] = 72, + [0][1][1][0][RTW89_IC][17] = 70, + [0][1][1][0][RTW89_ACMA][17] = 48, + [0][1][1][0][RTW89_FCC][19] = 70, + [0][1][1][0][RTW89_ETSI][19] = 48, + [0][1][1][0][RTW89_MKK][19] = 72, + [0][1][1][0][RTW89_IC][19] = 70, + [0][1][1][0][RTW89_ACMA][19] = 48, + [0][1][1][0][RTW89_FCC][21] = 70, + [0][1][1][0][RTW89_ETSI][21] = 48, + [0][1][1][0][RTW89_MKK][21] = 72, + [0][1][1][0][RTW89_IC][21] = 70, + [0][1][1][0][RTW89_ACMA][21] = 48, + [0][1][1][0][RTW89_FCC][23] = 70, + [0][1][1][0][RTW89_ETSI][23] = 48, + [0][1][1][0][RTW89_MKK][23] = 72, + [0][1][1][0][RTW89_IC][23] = 70, + [0][1][1][0][RTW89_ACMA][23] = 48, + [0][1][1][0][RTW89_FCC][25] = 70, + [0][1][1][0][RTW89_ETSI][25] = 48, + [0][1][1][0][RTW89_MKK][25] = 70, + [0][1][1][0][RTW89_IC][25] = 127, + [0][1][1][0][RTW89_ACMA][25] = 127, + [0][1][1][0][RTW89_FCC][27] = 70, + [0][1][1][0][RTW89_ETSI][27] = 48, + [0][1][1][0][RTW89_MKK][27] = 72, + [0][1][1][0][RTW89_IC][27] = 127, + [0][1][1][0][RTW89_ACMA][27] = 127, + [0][1][1][0][RTW89_FCC][29] = 70, + [0][1][1][0][RTW89_ETSI][29] = 48, + [0][1][1][0][RTW89_MKK][29] = 72, + [0][1][1][0][RTW89_IC][29] = 127, + [0][1][1][0][RTW89_ACMA][29] = 127, + [0][1][1][0][RTW89_FCC][31] = 70, + [0][1][1][0][RTW89_ETSI][31] = 48, + [0][1][1][0][RTW89_MKK][31] = 72, + [0][1][1][0][RTW89_IC][31] = 70, + [0][1][1][0][RTW89_ACMA][31] = 48, + [0][1][1][0][RTW89_FCC][33] = 70, + [0][1][1][0][RTW89_ETSI][33] = 48, + [0][1][1][0][RTW89_MKK][33] = 72, + [0][1][1][0][RTW89_IC][33] = 70, + [0][1][1][0][RTW89_ACMA][33] = 48, + [0][1][1][0][RTW89_FCC][35] = 68, + [0][1][1][0][RTW89_ETSI][35] = 48, + [0][1][1][0][RTW89_MKK][35] = 72, + [0][1][1][0][RTW89_IC][35] = 68, + [0][1][1][0][RTW89_ACMA][35] = 48, + [0][1][1][0][RTW89_FCC][37] = 70, + [0][1][1][0][RTW89_ETSI][37] = 127, + [0][1][1][0][RTW89_MKK][37] = 72, + [0][1][1][0][RTW89_IC][37] = 70, + [0][1][1][0][RTW89_ACMA][37] = 72, + [0][1][1][0][RTW89_FCC][38] = 80, + [0][1][1][0][RTW89_ETSI][38] = 18, + [0][1][1][0][RTW89_MKK][38] = 127, + [0][1][1][0][RTW89_IC][38] = 80, + [0][1][1][0][RTW89_ACMA][38] = 74, + [0][1][1][0][RTW89_FCC][40] = 80, + [0][1][1][0][RTW89_ETSI][40] = 18, + [0][1][1][0][RTW89_MKK][40] = 127, + [0][1][1][0][RTW89_IC][40] = 80, + [0][1][1][0][RTW89_ACMA][40] = 16, + [0][1][1][0][RTW89_FCC][42] = 80, + [0][1][1][0][RTW89_ETSI][42] = 18, + [0][1][1][0][RTW89_MKK][42] = 127, + [0][1][1][0][RTW89_IC][42] = 80, + [0][1][1][0][RTW89_ACMA][42] = 78, + [0][1][1][0][RTW89_FCC][44] = 80, + [0][1][1][0][RTW89_ETSI][44] = 18, + [0][1][1][0][RTW89_MKK][44] = 127, + [0][1][1][0][RTW89_IC][44] = 80, + [0][1][1][0][RTW89_ACMA][44] = 16, + [0][1][1][0][RTW89_FCC][46] = 80, + [0][1][1][0][RTW89_ETSI][46] = 18, + [0][1][1][0][RTW89_MKK][46] = 127, + [0][1][1][0][RTW89_IC][46] = 80, + [0][1][1][0][RTW89_ACMA][46] = 78, + [0][1][1][0][RTW89_FCC][48] = 58, + [0][1][1][0][RTW89_ETSI][48] = 127, + [0][1][1][0][RTW89_MKK][48] = 127, + [0][1][1][0][RTW89_IC][48] = 127, + [0][1][1][0][RTW89_ACMA][48] = 127, + [0][1][1][0][RTW89_FCC][50] = 58, + [0][1][1][0][RTW89_ETSI][50] = 127, + [0][1][1][0][RTW89_MKK][50] = 127, + [0][1][1][0][RTW89_IC][50] = 127, + [0][1][1][0][RTW89_ACMA][50] = 127, + [0][1][1][0][RTW89_FCC][52] = 58, + [0][1][1][0][RTW89_ETSI][52] = 127, + [0][1][1][0][RTW89_MKK][52] = 127, + [0][1][1][0][RTW89_IC][52] = 127, + [0][1][1][0][RTW89_ACMA][52] = 127, + [0][0][2][0][RTW89_FCC][0] = 80, + [0][0][2][0][RTW89_ETSI][0] = 62, + [0][0][2][0][RTW89_MKK][0] = 64, + [0][0][2][0][RTW89_IC][0] = 66, + [0][0][2][0][RTW89_ACMA][0] = 62, + [0][0][2][0][RTW89_FCC][2] = 80, + [0][0][2][0][RTW89_ETSI][2] = 62, + [0][0][2][0][RTW89_MKK][2] = 64, + [0][0][2][0][RTW89_IC][2] = 66, + [0][0][2][0][RTW89_ACMA][2] = 62, + [0][0][2][0][RTW89_FCC][4] = 80, + [0][0][2][0][RTW89_ETSI][4] = 62, + [0][0][2][0][RTW89_MKK][4] = 64, + [0][0][2][0][RTW89_IC][4] = 66, + [0][0][2][0][RTW89_ACMA][4] = 62, + [0][0][2][0][RTW89_FCC][6] = 80, + [0][0][2][0][RTW89_ETSI][6] = 62, + [0][0][2][0][RTW89_MKK][6] = 64, + [0][0][2][0][RTW89_IC][6] = 66, + [0][0][2][0][RTW89_ACMA][6] = 62, + [0][0][2][0][RTW89_FCC][8] = 80, + [0][0][2][0][RTW89_ETSI][8] = 62, + [0][0][2][0][RTW89_MKK][8] = 64, + [0][0][2][0][RTW89_IC][8] = 66, + [0][0][2][0][RTW89_ACMA][8] = 62, + [0][0][2][0][RTW89_FCC][10] = 80, + [0][0][2][0][RTW89_ETSI][10] = 62, + [0][0][2][0][RTW89_MKK][10] = 64, + [0][0][2][0][RTW89_IC][10] = 66, + [0][0][2][0][RTW89_ACMA][10] = 62, + [0][0][2][0][RTW89_FCC][12] = 80, + [0][0][2][0][RTW89_ETSI][12] = 62, + [0][0][2][0][RTW89_MKK][12] = 64, + [0][0][2][0][RTW89_IC][12] = 66, + [0][0][2][0][RTW89_ACMA][12] = 62, + [0][0][2][0][RTW89_FCC][14] = 80, + [0][0][2][0][RTW89_ETSI][14] = 62, + [0][0][2][0][RTW89_MKK][14] = 64, + [0][0][2][0][RTW89_IC][14] = 66, + [0][0][2][0][RTW89_ACMA][14] = 62, + [0][0][2][0][RTW89_FCC][15] = 76, + [0][0][2][0][RTW89_ETSI][15] = 62, + [0][0][2][0][RTW89_MKK][15] = 78, + [0][0][2][0][RTW89_IC][15] = 76, + [0][0][2][0][RTW89_ACMA][15] = 62, + [0][0][2][0][RTW89_FCC][17] = 80, + [0][0][2][0][RTW89_ETSI][17] = 62, + [0][0][2][0][RTW89_MKK][17] = 78, + [0][0][2][0][RTW89_IC][17] = 80, + [0][0][2][0][RTW89_ACMA][17] = 62, + [0][0][2][0][RTW89_FCC][19] = 80, + [0][0][2][0][RTW89_ETSI][19] = 62, + [0][0][2][0][RTW89_MKK][19] = 78, + [0][0][2][0][RTW89_IC][19] = 80, + [0][0][2][0][RTW89_ACMA][19] = 62, + [0][0][2][0][RTW89_FCC][21] = 80, + [0][0][2][0][RTW89_ETSI][21] = 62, + [0][0][2][0][RTW89_MKK][21] = 78, + [0][0][2][0][RTW89_IC][21] = 80, + [0][0][2][0][RTW89_ACMA][21] = 62, + [0][0][2][0][RTW89_FCC][23] = 80, + [0][0][2][0][RTW89_ETSI][23] = 62, + [0][0][2][0][RTW89_MKK][23] = 78, + [0][0][2][0][RTW89_IC][23] = 80, + [0][0][2][0][RTW89_ACMA][23] = 62, + [0][0][2][0][RTW89_FCC][25] = 80, + [0][0][2][0][RTW89_ETSI][25] = 62, + [0][0][2][0][RTW89_MKK][25] = 78, + [0][0][2][0][RTW89_IC][25] = 127, + [0][0][2][0][RTW89_ACMA][25] = 127, + [0][0][2][0][RTW89_FCC][27] = 80, + [0][0][2][0][RTW89_ETSI][27] = 62, + [0][0][2][0][RTW89_MKK][27] = 78, + [0][0][2][0][RTW89_IC][27] = 127, + [0][0][2][0][RTW89_ACMA][27] = 127, + [0][0][2][0][RTW89_FCC][29] = 80, + [0][0][2][0][RTW89_ETSI][29] = 62, + [0][0][2][0][RTW89_MKK][29] = 78, + [0][0][2][0][RTW89_IC][29] = 127, + [0][0][2][0][RTW89_ACMA][29] = 127, + [0][0][2][0][RTW89_FCC][31] = 80, + [0][0][2][0][RTW89_ETSI][31] = 62, + [0][0][2][0][RTW89_MKK][31] = 78, + [0][0][2][0][RTW89_IC][31] = 80, + [0][0][2][0][RTW89_ACMA][31] = 62, + [0][0][2][0][RTW89_FCC][33] = 80, + [0][0][2][0][RTW89_ETSI][33] = 62, + [0][0][2][0][RTW89_MKK][33] = 78, + [0][0][2][0][RTW89_IC][33] = 80, + [0][0][2][0][RTW89_ACMA][33] = 62, + [0][0][2][0][RTW89_FCC][35] = 72, + [0][0][2][0][RTW89_ETSI][35] = 62, + [0][0][2][0][RTW89_MKK][35] = 78, + [0][0][2][0][RTW89_IC][35] = 72, + [0][0][2][0][RTW89_ACMA][35] = 62, + [0][0][2][0][RTW89_FCC][37] = 80, + [0][0][2][0][RTW89_ETSI][37] = 127, + [0][0][2][0][RTW89_MKK][37] = 78, + [0][0][2][0][RTW89_IC][37] = 80, + [0][0][2][0][RTW89_ACMA][37] = 78, + [0][0][2][0][RTW89_FCC][38] = 80, + [0][0][2][0][RTW89_ETSI][38] = 30, + [0][0][2][0][RTW89_MKK][38] = 127, + [0][0][2][0][RTW89_IC][38] = 80, + [0][0][2][0][RTW89_ACMA][38] = 78, + [0][0][2][0][RTW89_FCC][40] = 80, + [0][0][2][0][RTW89_ETSI][40] = 30, + [0][0][2][0][RTW89_MKK][40] = 127, + [0][0][2][0][RTW89_IC][40] = 80, + [0][0][2][0][RTW89_ACMA][40] = 78, + [0][0][2][0][RTW89_FCC][42] = 80, + [0][0][2][0][RTW89_ETSI][42] = 30, + [0][0][2][0][RTW89_MKK][42] = 127, + [0][0][2][0][RTW89_IC][42] = 80, + [0][0][2][0][RTW89_ACMA][42] = 78, + [0][0][2][0][RTW89_FCC][44] = 80, + [0][0][2][0][RTW89_ETSI][44] = 30, + [0][0][2][0][RTW89_MKK][44] = 127, + [0][0][2][0][RTW89_IC][44] = 80, + [0][0][2][0][RTW89_ACMA][44] = 78, + [0][0][2][0][RTW89_FCC][46] = 80, + [0][0][2][0][RTW89_ETSI][46] = 30, + [0][0][2][0][RTW89_MKK][46] = 127, + [0][0][2][0][RTW89_IC][46] = 80, + [0][0][2][0][RTW89_ACMA][46] = 78, + [0][0][2][0][RTW89_FCC][48] = 80, + [0][0][2][0][RTW89_ETSI][48] = 127, + [0][0][2][0][RTW89_MKK][48] = 127, + [0][0][2][0][RTW89_IC][48] = 127, + [0][0][2][0][RTW89_ACMA][48] = 127, + [0][0][2][0][RTW89_FCC][50] = 80, + [0][0][2][0][RTW89_ETSI][50] = 127, + [0][0][2][0][RTW89_MKK][50] = 127, + [0][0][2][0][RTW89_IC][50] = 127, + [0][0][2][0][RTW89_ACMA][50] = 127, + [0][0][2][0][RTW89_FCC][52] = 80, + [0][0][2][0][RTW89_ETSI][52] = 127, + [0][0][2][0][RTW89_MKK][52] = 127, + [0][0][2][0][RTW89_IC][52] = 127, + [0][0][2][0][RTW89_ACMA][52] = 127, + [0][1][2][0][RTW89_FCC][0] = 72, + [0][1][2][0][RTW89_ETSI][0] = 50, + [0][1][2][0][RTW89_MKK][0] = 52, + [0][1][2][0][RTW89_IC][0] = 44, + [0][1][2][0][RTW89_ACMA][0] = 50, + [0][1][2][0][RTW89_FCC][2] = 72, + [0][1][2][0][RTW89_ETSI][2] = 50, + [0][1][2][0][RTW89_MKK][2] = 52, + [0][1][2][0][RTW89_IC][2] = 44, + [0][1][2][0][RTW89_ACMA][2] = 50, + [0][1][2][0][RTW89_FCC][4] = 72, + [0][1][2][0][RTW89_ETSI][4] = 50, + [0][1][2][0][RTW89_MKK][4] = 52, + [0][1][2][0][RTW89_IC][4] = 44, + [0][1][2][0][RTW89_ACMA][4] = 50, + [0][1][2][0][RTW89_FCC][6] = 72, + [0][1][2][0][RTW89_ETSI][6] = 50, + [0][1][2][0][RTW89_MKK][6] = 52, + [0][1][2][0][RTW89_IC][6] = 44, + [0][1][2][0][RTW89_ACMA][6] = 50, + [0][1][2][0][RTW89_FCC][8] = 72, + [0][1][2][0][RTW89_ETSI][8] = 50, + [0][1][2][0][RTW89_MKK][8] = 52, + [0][1][2][0][RTW89_IC][8] = 54, + [0][1][2][0][RTW89_ACMA][8] = 50, + [0][1][2][0][RTW89_FCC][10] = 72, + [0][1][2][0][RTW89_ETSI][10] = 50, + [0][1][2][0][RTW89_MKK][10] = 52, + [0][1][2][0][RTW89_IC][10] = 54, + [0][1][2][0][RTW89_ACMA][10] = 50, + [0][1][2][0][RTW89_FCC][12] = 72, + [0][1][2][0][RTW89_ETSI][12] = 50, + [0][1][2][0][RTW89_MKK][12] = 52, + [0][1][2][0][RTW89_IC][12] = 54, + [0][1][2][0][RTW89_ACMA][12] = 50, + [0][1][2][0][RTW89_FCC][14] = 72, + [0][1][2][0][RTW89_ETSI][14] = 50, + [0][1][2][0][RTW89_MKK][14] = 52, + [0][1][2][0][RTW89_IC][14] = 54, + [0][1][2][0][RTW89_ACMA][14] = 50, + [0][1][2][0][RTW89_FCC][15] = 70, + [0][1][2][0][RTW89_ETSI][15] = 50, + [0][1][2][0][RTW89_MKK][15] = 72, + [0][1][2][0][RTW89_IC][15] = 70, + [0][1][2][0][RTW89_ACMA][15] = 50, + [0][1][2][0][RTW89_FCC][17] = 72, + [0][1][2][0][RTW89_ETSI][17] = 50, + [0][1][2][0][RTW89_MKK][17] = 72, + [0][1][2][0][RTW89_IC][17] = 72, + [0][1][2][0][RTW89_ACMA][17] = 50, + [0][1][2][0][RTW89_FCC][19] = 72, + [0][1][2][0][RTW89_ETSI][19] = 50, + [0][1][2][0][RTW89_MKK][19] = 72, + [0][1][2][0][RTW89_IC][19] = 72, + [0][1][2][0][RTW89_ACMA][19] = 50, + [0][1][2][0][RTW89_FCC][21] = 72, + [0][1][2][0][RTW89_ETSI][21] = 50, + [0][1][2][0][RTW89_MKK][21] = 72, + [0][1][2][0][RTW89_IC][21] = 72, + [0][1][2][0][RTW89_ACMA][21] = 50, + [0][1][2][0][RTW89_FCC][23] = 72, + [0][1][2][0][RTW89_ETSI][23] = 50, + [0][1][2][0][RTW89_MKK][23] = 72, + [0][1][2][0][RTW89_IC][23] = 72, + [0][1][2][0][RTW89_ACMA][23] = 50, + [0][1][2][0][RTW89_FCC][25] = 72, + [0][1][2][0][RTW89_ETSI][25] = 50, + [0][1][2][0][RTW89_MKK][25] = 72, + [0][1][2][0][RTW89_IC][25] = 127, + [0][1][2][0][RTW89_ACMA][25] = 127, + [0][1][2][0][RTW89_FCC][27] = 72, + [0][1][2][0][RTW89_ETSI][27] = 50, + [0][1][2][0][RTW89_MKK][27] = 72, + [0][1][2][0][RTW89_IC][27] = 127, + [0][1][2][0][RTW89_ACMA][27] = 127, + [0][1][2][0][RTW89_FCC][29] = 72, + [0][1][2][0][RTW89_ETSI][29] = 50, + [0][1][2][0][RTW89_MKK][29] = 72, + [0][1][2][0][RTW89_IC][29] = 127, + [0][1][2][0][RTW89_ACMA][29] = 127, + [0][1][2][0][RTW89_FCC][31] = 72, + [0][1][2][0][RTW89_ETSI][31] = 50, + [0][1][2][0][RTW89_MKK][31] = 72, + [0][1][2][0][RTW89_IC][31] = 72, + [0][1][2][0][RTW89_ACMA][31] = 50, + [0][1][2][0][RTW89_FCC][33] = 72, + [0][1][2][0][RTW89_ETSI][33] = 50, + [0][1][2][0][RTW89_MKK][33] = 72, + [0][1][2][0][RTW89_IC][33] = 72, + [0][1][2][0][RTW89_ACMA][33] = 50, + [0][1][2][0][RTW89_FCC][35] = 68, + [0][1][2][0][RTW89_ETSI][35] = 50, + [0][1][2][0][RTW89_MKK][35] = 72, + [0][1][2][0][RTW89_IC][35] = 68, + [0][1][2][0][RTW89_ACMA][35] = 50, + [0][1][2][0][RTW89_FCC][37] = 72, + [0][1][2][0][RTW89_ETSI][37] = 127, + [0][1][2][0][RTW89_MKK][37] = 72, + [0][1][2][0][RTW89_IC][37] = 72, + [0][1][2][0][RTW89_ACMA][37] = 72, + [0][1][2][0][RTW89_FCC][38] = 80, + [0][1][2][0][RTW89_ETSI][38] = 18, + [0][1][2][0][RTW89_MKK][38] = 127, + [0][1][2][0][RTW89_IC][38] = 80, + [0][1][2][0][RTW89_ACMA][38] = 76, + [0][1][2][0][RTW89_FCC][40] = 80, + [0][1][2][0][RTW89_ETSI][40] = 18, + [0][1][2][0][RTW89_MKK][40] = 127, + [0][1][2][0][RTW89_IC][40] = 80, + [0][1][2][0][RTW89_ACMA][40] = 76, + [0][1][2][0][RTW89_FCC][42] = 80, + [0][1][2][0][RTW89_ETSI][42] = 18, + [0][1][2][0][RTW89_MKK][42] = 127, + [0][1][2][0][RTW89_IC][42] = 80, + [0][1][2][0][RTW89_ACMA][42] = 78, + [0][1][2][0][RTW89_FCC][44] = 80, + [0][1][2][0][RTW89_ETSI][44] = 18, + [0][1][2][0][RTW89_MKK][44] = 127, + [0][1][2][0][RTW89_IC][44] = 80, + [0][1][2][0][RTW89_ACMA][44] = 78, + [0][1][2][0][RTW89_FCC][46] = 80, + [0][1][2][0][RTW89_ETSI][46] = 18, + [0][1][2][0][RTW89_MKK][46] = 127, + [0][1][2][0][RTW89_IC][46] = 80, + [0][1][2][0][RTW89_ACMA][46] = 78, + [0][1][2][0][RTW89_FCC][48] = 60, + [0][1][2][0][RTW89_ETSI][48] = 127, + [0][1][2][0][RTW89_MKK][48] = 127, + [0][1][2][0][RTW89_IC][48] = 127, + [0][1][2][0][RTW89_ACMA][48] = 127, + [0][1][2][0][RTW89_FCC][50] = 60, + [0][1][2][0][RTW89_ETSI][50] = 127, + [0][1][2][0][RTW89_MKK][50] = 127, + [0][1][2][0][RTW89_IC][50] = 127, + [0][1][2][0][RTW89_ACMA][50] = 127, + [0][1][2][0][RTW89_FCC][52] = 60, + [0][1][2][0][RTW89_ETSI][52] = 127, + [0][1][2][0][RTW89_MKK][52] = 127, + [0][1][2][0][RTW89_IC][52] = 127, + [0][1][2][0][RTW89_ACMA][52] = 127, + [0][1][2][1][RTW89_FCC][0] = 70, + [0][1][2][1][RTW89_ETSI][0] = 42, + [0][1][2][1][RTW89_MKK][0] = 52, + [0][1][2][1][RTW89_IC][0] = 42, + [0][1][2][1][RTW89_ACMA][0] = 38, + [0][1][2][1][RTW89_FCC][2] = 70, + [0][1][2][1][RTW89_ETSI][2] = 42, + [0][1][2][1][RTW89_MKK][2] = 52, + [0][1][2][1][RTW89_IC][2] = 42, + [0][1][2][1][RTW89_ACMA][2] = 38, + [0][1][2][1][RTW89_FCC][4] = 70, + [0][1][2][1][RTW89_ETSI][4] = 42, + [0][1][2][1][RTW89_MKK][4] = 52, + [0][1][2][1][RTW89_IC][4] = 42, + [0][1][2][1][RTW89_ACMA][4] = 38, + [0][1][2][1][RTW89_FCC][6] = 70, + [0][1][2][1][RTW89_ETSI][6] = 42, + [0][1][2][1][RTW89_MKK][6] = 52, + [0][1][2][1][RTW89_IC][6] = 42, + [0][1][2][1][RTW89_ACMA][6] = 38, + [0][1][2][1][RTW89_FCC][8] = 70, + [0][1][2][1][RTW89_ETSI][8] = 42, + [0][1][2][1][RTW89_MKK][8] = 52, + [0][1][2][1][RTW89_IC][8] = 42, + [0][1][2][1][RTW89_ACMA][8] = 38, + [0][1][2][1][RTW89_FCC][10] = 70, + [0][1][2][1][RTW89_ETSI][10] = 42, + [0][1][2][1][RTW89_MKK][10] = 52, + [0][1][2][1][RTW89_IC][10] = 42, + [0][1][2][1][RTW89_ACMA][10] = 38, + [0][1][2][1][RTW89_FCC][12] = 70, + [0][1][2][1][RTW89_ETSI][12] = 42, + [0][1][2][1][RTW89_MKK][12] = 52, + [0][1][2][1][RTW89_IC][12] = 42, + [0][1][2][1][RTW89_ACMA][12] = 38, + [0][1][2][1][RTW89_FCC][14] = 70, + [0][1][2][1][RTW89_ETSI][14] = 42, + [0][1][2][1][RTW89_MKK][14] = 52, + [0][1][2][1][RTW89_IC][14] = 42, + [0][1][2][1][RTW89_ACMA][14] = 38, + [0][1][2][1][RTW89_FCC][15] = 70, + [0][1][2][1][RTW89_ETSI][15] = 42, + [0][1][2][1][RTW89_MKK][15] = 72, + [0][1][2][1][RTW89_IC][15] = 70, + [0][1][2][1][RTW89_ACMA][15] = 38, + [0][1][2][1][RTW89_FCC][17] = 70, + [0][1][2][1][RTW89_ETSI][17] = 42, + [0][1][2][1][RTW89_MKK][17] = 72, + [0][1][2][1][RTW89_IC][17] = 70, + [0][1][2][1][RTW89_ACMA][17] = 38, + [0][1][2][1][RTW89_FCC][19] = 70, + [0][1][2][1][RTW89_ETSI][19] = 42, + [0][1][2][1][RTW89_MKK][19] = 72, + [0][1][2][1][RTW89_IC][19] = 70, + [0][1][2][1][RTW89_ACMA][19] = 38, + [0][1][2][1][RTW89_FCC][21] = 70, + [0][1][2][1][RTW89_ETSI][21] = 42, + [0][1][2][1][RTW89_MKK][21] = 72, + [0][1][2][1][RTW89_IC][21] = 70, + [0][1][2][1][RTW89_ACMA][21] = 38, + [0][1][2][1][RTW89_FCC][23] = 70, + [0][1][2][1][RTW89_ETSI][23] = 42, + [0][1][2][1][RTW89_MKK][23] = 72, + [0][1][2][1][RTW89_IC][23] = 70, + [0][1][2][1][RTW89_ACMA][23] = 38, + [0][1][2][1][RTW89_FCC][25] = 68, + [0][1][2][1][RTW89_ETSI][25] = 42, + [0][1][2][1][RTW89_MKK][25] = 72, + [0][1][2][1][RTW89_IC][25] = 127, + [0][1][2][1][RTW89_ACMA][25] = 127, + [0][1][2][1][RTW89_FCC][27] = 68, + [0][1][2][1][RTW89_ETSI][27] = 42, + [0][1][2][1][RTW89_MKK][27] = 72, + [0][1][2][1][RTW89_IC][27] = 127, + [0][1][2][1][RTW89_ACMA][27] = 127, + [0][1][2][1][RTW89_FCC][29] = 68, + [0][1][2][1][RTW89_ETSI][29] = 42, + [0][1][2][1][RTW89_MKK][29] = 72, + [0][1][2][1][RTW89_IC][29] = 127, + [0][1][2][1][RTW89_ACMA][29] = 127, + [0][1][2][1][RTW89_FCC][31] = 68, + [0][1][2][1][RTW89_ETSI][31] = 42, + [0][1][2][1][RTW89_MKK][31] = 72, + [0][1][2][1][RTW89_IC][31] = 68, + [0][1][2][1][RTW89_ACMA][31] = 38, + [0][1][2][1][RTW89_FCC][33] = 68, + [0][1][2][1][RTW89_ETSI][33] = 42, + [0][1][2][1][RTW89_MKK][33] = 72, + [0][1][2][1][RTW89_IC][33] = 68, + [0][1][2][1][RTW89_ACMA][33] = 38, + [0][1][2][1][RTW89_FCC][35] = 68, + [0][1][2][1][RTW89_ETSI][35] = 42, + [0][1][2][1][RTW89_MKK][35] = 72, + [0][1][2][1][RTW89_IC][35] = 68, + [0][1][2][1][RTW89_ACMA][35] = 38, + [0][1][2][1][RTW89_FCC][37] = 70, + [0][1][2][1][RTW89_ETSI][37] = 127, + [0][1][2][1][RTW89_MKK][37] = 72, + [0][1][2][1][RTW89_IC][37] = 70, + [0][1][2][1][RTW89_ACMA][37] = 72, + [0][1][2][1][RTW89_FCC][38] = 80, + [0][1][2][1][RTW89_ETSI][38] = 8, + [0][1][2][1][RTW89_MKK][38] = 127, + [0][1][2][1][RTW89_IC][38] = 80, + [0][1][2][1][RTW89_ACMA][38] = 76, + [0][1][2][1][RTW89_FCC][40] = 80, + [0][1][2][1][RTW89_ETSI][40] = 8, + [0][1][2][1][RTW89_MKK][40] = 127, + [0][1][2][1][RTW89_IC][40] = 80, + [0][1][2][1][RTW89_ACMA][40] = 76, + [0][1][2][1][RTW89_FCC][42] = 80, + [0][1][2][1][RTW89_ETSI][42] = 8, + [0][1][2][1][RTW89_MKK][42] = 127, + [0][1][2][1][RTW89_IC][42] = 80, + [0][1][2][1][RTW89_ACMA][42] = 78, + [0][1][2][1][RTW89_FCC][44] = 80, + [0][1][2][1][RTW89_ETSI][44] = 8, + [0][1][2][1][RTW89_MKK][44] = 127, + [0][1][2][1][RTW89_IC][44] = 80, + [0][1][2][1][RTW89_ACMA][44] = 78, + [0][1][2][1][RTW89_FCC][46] = 80, + [0][1][2][1][RTW89_ETSI][46] = 8, + [0][1][2][1][RTW89_MKK][46] = 127, + [0][1][2][1][RTW89_IC][46] = 80, + [0][1][2][1][RTW89_ACMA][46] = 78, + [0][1][2][1][RTW89_FCC][48] = 60, + [0][1][2][1][RTW89_ETSI][48] = 127, + [0][1][2][1][RTW89_MKK][48] = 127, + [0][1][2][1][RTW89_IC][48] = 127, + [0][1][2][1][RTW89_ACMA][48] = 127, + [0][1][2][1][RTW89_FCC][50] = 60, + [0][1][2][1][RTW89_ETSI][50] = 127, + [0][1][2][1][RTW89_MKK][50] = 127, + [0][1][2][1][RTW89_IC][50] = 127, + [0][1][2][1][RTW89_ACMA][50] = 127, + [0][1][2][1][RTW89_FCC][52] = 60, + [0][1][2][1][RTW89_ETSI][52] = 127, + [0][1][2][1][RTW89_MKK][52] = 127, + [0][1][2][1][RTW89_IC][52] = 127, + [0][1][2][1][RTW89_ACMA][52] = 127, + [1][0][2][0][RTW89_FCC][1] = 68, + [1][0][2][0][RTW89_ETSI][1] = 66, + [1][0][2][0][RTW89_MKK][1] = 72, + [1][0][2][0][RTW89_IC][1] = 72, + [1][0][2][0][RTW89_ACMA][1] = 72, + [1][0][2][0][RTW89_FCC][5] = 80, + [1][0][2][0][RTW89_ETSI][5] = 66, + [1][0][2][0][RTW89_MKK][5] = 72, + [1][0][2][0][RTW89_IC][5] = 72, + [1][0][2][0][RTW89_ACMA][5] = 72, + [1][0][2][0][RTW89_FCC][9] = 80, + [1][0][2][0][RTW89_ETSI][9] = 66, + [1][0][2][0][RTW89_MKK][9] = 72, + [1][0][2][0][RTW89_IC][9] = 72, + [1][0][2][0][RTW89_ACMA][9] = 72, + [1][0][2][0][RTW89_FCC][13] = 68, + [1][0][2][0][RTW89_ETSI][13] = 66, + [1][0][2][0][RTW89_MKK][13] = 72, + [1][0][2][0][RTW89_IC][13] = 72, + [1][0][2][0][RTW89_ACMA][13] = 72, + [1][0][2][0][RTW89_FCC][16] = 66, + [1][0][2][0][RTW89_ETSI][16] = 66, + [1][0][2][0][RTW89_MKK][16] = 76, + [1][0][2][0][RTW89_IC][16] = 72, + [1][0][2][0][RTW89_ACMA][16] = 72, + [1][0][2][0][RTW89_FCC][20] = 80, + [1][0][2][0][RTW89_ETSI][20] = 66, + [1][0][2][0][RTW89_MKK][20] = 76, + [1][0][2][0][RTW89_IC][20] = 80, + [1][0][2][0][RTW89_ACMA][20] = 72, + [1][0][2][0][RTW89_FCC][24] = 80, + [1][0][2][0][RTW89_ETSI][24] = 66, + [1][0][2][0][RTW89_MKK][24] = 76, + [1][0][2][0][RTW89_IC][24] = 127, + [1][0][2][0][RTW89_ACMA][24] = 127, + [1][0][2][0][RTW89_FCC][28] = 80, + [1][0][2][0][RTW89_ETSI][28] = 66, + [1][0][2][0][RTW89_MKK][28] = 76, + [1][0][2][0][RTW89_IC][28] = 127, + [1][0][2][0][RTW89_ACMA][28] = 127, + [1][0][2][0][RTW89_FCC][32] = 78, + [1][0][2][0][RTW89_ETSI][32] = 66, + [1][0][2][0][RTW89_MKK][32] = 76, + [1][0][2][0][RTW89_IC][32] = 78, + [1][0][2][0][RTW89_ACMA][32] = 66, + [1][0][2][0][RTW89_FCC][36] = 80, + [1][0][2][0][RTW89_ETSI][36] = 127, + [1][0][2][0][RTW89_MKK][36] = 76, + [1][0][2][0][RTW89_IC][36] = 80, + [1][0][2][0][RTW89_ACMA][36] = 76, + [1][0][2][0][RTW89_FCC][39] = 80, + [1][0][2][0][RTW89_ETSI][39] = 30, + [1][0][2][0][RTW89_MKK][39] = 127, + [1][0][2][0][RTW89_IC][39] = 80, + [1][0][2][0][RTW89_ACMA][39] = 76, + [1][0][2][0][RTW89_FCC][43] = 80, + [1][0][2][0][RTW89_ETSI][43] = 30, + [1][0][2][0][RTW89_MKK][43] = 127, + [1][0][2][0][RTW89_IC][43] = 80, + [1][0][2][0][RTW89_ACMA][43] = 76, + [1][0][2][0][RTW89_FCC][47] = 80, + [1][0][2][0][RTW89_ETSI][47] = 127, + [1][0][2][0][RTW89_MKK][47] = 127, + [1][0][2][0][RTW89_IC][47] = 127, + [1][0][2][0][RTW89_ACMA][47] = 127, + [1][0][2][0][RTW89_FCC][51] = 72, + [1][0][2][0][RTW89_ETSI][51] = 127, + [1][0][2][0][RTW89_MKK][51] = 127, + [1][0][2][0][RTW89_IC][51] = 127, + [1][0][2][0][RTW89_ACMA][51] = 127, + [1][1][2][0][RTW89_FCC][1] = 64, + [1][1][2][0][RTW89_ETSI][1] = 54, + [1][1][2][0][RTW89_MKK][1] = 60, + [1][1][2][0][RTW89_IC][1] = 60, + [1][1][2][0][RTW89_ACMA][1] = 60, + [1][1][2][0][RTW89_FCC][5] = 78, + [1][1][2][0][RTW89_ETSI][5] = 54, + [1][1][2][0][RTW89_MKK][5] = 60, + [1][1][2][0][RTW89_IC][5] = 60, + [1][1][2][0][RTW89_ACMA][5] = 60, + [1][1][2][0][RTW89_FCC][9] = 78, + [1][1][2][0][RTW89_ETSI][9] = 54, + [1][1][2][0][RTW89_MKK][9] = 60, + [1][1][2][0][RTW89_IC][9] = 60, + [1][1][2][0][RTW89_ACMA][9] = 60, + [1][1][2][0][RTW89_FCC][13] = 64, + [1][1][2][0][RTW89_ETSI][13] = 54, + [1][1][2][0][RTW89_MKK][13] = 60, + [1][1][2][0][RTW89_IC][13] = 60, + [1][1][2][0][RTW89_ACMA][13] = 60, + [1][1][2][0][RTW89_FCC][16] = 58, + [1][1][2][0][RTW89_ETSI][16] = 54, + [1][1][2][0][RTW89_MKK][16] = 72, + [1][1][2][0][RTW89_IC][16] = 58, + [1][1][2][0][RTW89_ACMA][16] = 60, + [1][1][2][0][RTW89_FCC][20] = 78, + [1][1][2][0][RTW89_ETSI][20] = 54, + [1][1][2][0][RTW89_MKK][20] = 72, + [1][1][2][0][RTW89_IC][20] = 78, + [1][1][2][0][RTW89_ACMA][20] = 60, + [1][1][2][0][RTW89_FCC][24] = 78, + [1][1][2][0][RTW89_ETSI][24] = 54, + [1][1][2][0][RTW89_MKK][24] = 72, + [1][1][2][0][RTW89_IC][24] = 127, + [1][1][2][0][RTW89_ACMA][24] = 127, + [1][1][2][0][RTW89_FCC][28] = 78, + [1][1][2][0][RTW89_ETSI][28] = 54, + [1][1][2][0][RTW89_MKK][28] = 72, + [1][1][2][0][RTW89_IC][28] = 127, + [1][1][2][0][RTW89_ACMA][28] = 127, + [1][1][2][0][RTW89_FCC][32] = 70, + [1][1][2][0][RTW89_ETSI][32] = 54, + [1][1][2][0][RTW89_MKK][32] = 72, + [1][1][2][0][RTW89_IC][32] = 70, + [1][1][2][0][RTW89_ACMA][32] = 54, + [1][1][2][0][RTW89_FCC][36] = 78, + [1][1][2][0][RTW89_ETSI][36] = 127, + [1][1][2][0][RTW89_MKK][36] = 72, + [1][1][2][0][RTW89_IC][36] = 78, + [1][1][2][0][RTW89_ACMA][36] = 76, + [1][1][2][0][RTW89_FCC][39] = 80, + [1][1][2][0][RTW89_ETSI][39] = 18, + [1][1][2][0][RTW89_MKK][39] = 127, + [1][1][2][0][RTW89_IC][39] = 80, + [1][1][2][0][RTW89_ACMA][39] = 74, + [1][1][2][0][RTW89_FCC][43] = 80, + [1][1][2][0][RTW89_ETSI][43] = 18, + [1][1][2][0][RTW89_MKK][43] = 127, + [1][1][2][0][RTW89_IC][43] = 80, + [1][1][2][0][RTW89_ACMA][43] = 76, + [1][1][2][0][RTW89_FCC][47] = 70, + [1][1][2][0][RTW89_ETSI][47] = 127, + [1][1][2][0][RTW89_MKK][47] = 127, + [1][1][2][0][RTW89_IC][47] = 127, + [1][1][2][0][RTW89_ACMA][47] = 127, + [1][1][2][0][RTW89_FCC][51] = 68, + [1][1][2][0][RTW89_ETSI][51] = 127, + [1][1][2][0][RTW89_MKK][51] = 127, + [1][1][2][0][RTW89_IC][51] = 127, + [1][1][2][0][RTW89_ACMA][51] = 127, + [1][1][2][1][RTW89_FCC][1] = 64, + [1][1][2][1][RTW89_ETSI][1] = 42, + [1][1][2][1][RTW89_MKK][1] = 60, + [1][1][2][1][RTW89_IC][1] = 48, + [1][1][2][1][RTW89_ACMA][1] = 48, + [1][1][2][1][RTW89_FCC][5] = 70, + [1][1][2][1][RTW89_ETSI][5] = 42, + [1][1][2][1][RTW89_MKK][5] = 60, + [1][1][2][1][RTW89_IC][5] = 48, + [1][1][2][1][RTW89_ACMA][5] = 48, + [1][1][2][1][RTW89_FCC][9] = 70, + [1][1][2][1][RTW89_ETSI][9] = 42, + [1][1][2][1][RTW89_MKK][9] = 60, + [1][1][2][1][RTW89_IC][9] = 48, + [1][1][2][1][RTW89_ACMA][9] = 48, + [1][1][2][1][RTW89_FCC][13] = 64, + [1][1][2][1][RTW89_ETSI][13] = 42, + [1][1][2][1][RTW89_MKK][13] = 60, + [1][1][2][1][RTW89_IC][13] = 48, + [1][1][2][1][RTW89_ACMA][13] = 48, + [1][1][2][1][RTW89_FCC][16] = 58, + [1][1][2][1][RTW89_ETSI][16] = 42, + [1][1][2][1][RTW89_MKK][16] = 72, + [1][1][2][1][RTW89_IC][16] = 58, + [1][1][2][1][RTW89_ACMA][16] = 48, + [1][1][2][1][RTW89_FCC][20] = 70, + [1][1][2][1][RTW89_ETSI][20] = 42, + [1][1][2][1][RTW89_MKK][20] = 72, + [1][1][2][1][RTW89_IC][20] = 70, + [1][1][2][1][RTW89_ACMA][20] = 48, + [1][1][2][1][RTW89_FCC][24] = 70, + [1][1][2][1][RTW89_ETSI][24] = 42, + [1][1][2][1][RTW89_MKK][24] = 72, + [1][1][2][1][RTW89_IC][24] = 127, + [1][1][2][1][RTW89_ACMA][24] = 127, + [1][1][2][1][RTW89_FCC][28] = 70, + [1][1][2][1][RTW89_ETSI][28] = 42, + [1][1][2][1][RTW89_MKK][28] = 72, + [1][1][2][1][RTW89_IC][28] = 127, + [1][1][2][1][RTW89_ACMA][28] = 127, + [1][1][2][1][RTW89_FCC][32] = 70, + [1][1][2][1][RTW89_ETSI][32] = 42, + [1][1][2][1][RTW89_MKK][32] = 72, + [1][1][2][1][RTW89_IC][32] = 70, + [1][1][2][1][RTW89_ACMA][32] = 42, + [1][1][2][1][RTW89_FCC][36] = 70, + [1][1][2][1][RTW89_ETSI][36] = 127, + [1][1][2][1][RTW89_MKK][36] = 72, + [1][1][2][1][RTW89_IC][36] = 70, + [1][1][2][1][RTW89_ACMA][36] = 72, + [1][1][2][1][RTW89_FCC][39] = 80, + [1][1][2][1][RTW89_ETSI][39] = 8, + [1][1][2][1][RTW89_MKK][39] = 127, + [1][1][2][1][RTW89_IC][39] = 80, + [1][1][2][1][RTW89_ACMA][39] = 74, + [1][1][2][1][RTW89_FCC][43] = 80, + [1][1][2][1][RTW89_ETSI][43] = 8, + [1][1][2][1][RTW89_MKK][43] = 127, + [1][1][2][1][RTW89_IC][43] = 80, + [1][1][2][1][RTW89_ACMA][43] = 76, + [1][1][2][1][RTW89_FCC][47] = 70, + [1][1][2][1][RTW89_ETSI][47] = 127, + [1][1][2][1][RTW89_MKK][47] = 127, + [1][1][2][1][RTW89_IC][47] = 127, + [1][1][2][1][RTW89_ACMA][47] = 127, + [1][1][2][1][RTW89_FCC][51] = 68, + [1][1][2][1][RTW89_ETSI][51] = 127, + [1][1][2][1][RTW89_MKK][51] = 127, + [1][1][2][1][RTW89_IC][51] = 127, + [1][1][2][1][RTW89_ACMA][51] = 127, + [2][0][2][0][RTW89_FCC][3] = 66, + [2][0][2][0][RTW89_ETSI][3] = 66, + [2][0][2][0][RTW89_MKK][3] = 66, + [2][0][2][0][RTW89_IC][3] = 64, + [2][0][2][0][RTW89_ACMA][3] = 66, + [2][0][2][0][RTW89_FCC][11] = 68, + [2][0][2][0][RTW89_ETSI][11] = 66, + [2][0][2][0][RTW89_MKK][11] = 66, + [2][0][2][0][RTW89_IC][11] = 66, + [2][0][2][0][RTW89_ACMA][11] = 66, + [2][0][2][0][RTW89_FCC][18] = 64, + [2][0][2][0][RTW89_ETSI][18] = 66, + [2][0][2][0][RTW89_MKK][18] = 72, + [2][0][2][0][RTW89_IC][18] = 64, + [2][0][2][0][RTW89_ACMA][18] = 66, + [2][0][2][0][RTW89_FCC][26] = 76, + [2][0][2][0][RTW89_ETSI][26] = 66, + [2][0][2][0][RTW89_MKK][26] = 72, + [2][0][2][0][RTW89_IC][26] = 127, + [2][0][2][0][RTW89_ACMA][26] = 127, + [2][0][2][0][RTW89_FCC][34] = 76, + [2][0][2][0][RTW89_ETSI][34] = 127, + [2][0][2][0][RTW89_MKK][34] = 72, + [2][0][2][0][RTW89_IC][34] = 76, + [2][0][2][0][RTW89_ACMA][34] = 72, + [2][0][2][0][RTW89_FCC][41] = 76, + [2][0][2][0][RTW89_ETSI][41] = 30, + [2][0][2][0][RTW89_MKK][41] = 127, + [2][0][2][0][RTW89_IC][41] = 76, + [2][0][2][0][RTW89_ACMA][41] = 72, + [2][0][2][0][RTW89_FCC][49] = 66, + [2][0][2][0][RTW89_ETSI][49] = 127, + [2][0][2][0][RTW89_MKK][49] = 127, + [2][0][2][0][RTW89_IC][49] = 127, + [2][0][2][0][RTW89_ACMA][49] = 127, + [2][1][2][0][RTW89_FCC][3] = 58, + [2][1][2][0][RTW89_ETSI][3] = 54, + [2][1][2][0][RTW89_MKK][3] = 54, + [2][1][2][0][RTW89_IC][3] = 54, + [2][1][2][0][RTW89_ACMA][3] = 54, + [2][1][2][0][RTW89_FCC][11] = 64, + [2][1][2][0][RTW89_ETSI][11] = 54, + [2][1][2][0][RTW89_MKK][11] = 54, + [2][1][2][0][RTW89_IC][11] = 54, + [2][1][2][0][RTW89_ACMA][11] = 54, + [2][1][2][0][RTW89_FCC][18] = 58, + [2][1][2][0][RTW89_ETSI][18] = 54, + [2][1][2][0][RTW89_MKK][18] = 72, + [2][1][2][0][RTW89_IC][18] = 58, + [2][1][2][0][RTW89_ACMA][18] = 54, + [2][1][2][0][RTW89_FCC][26] = 72, + [2][1][2][0][RTW89_ETSI][26] = 54, + [2][1][2][0][RTW89_MKK][26] = 72, + [2][1][2][0][RTW89_IC][26] = 127, + [2][1][2][0][RTW89_ACMA][26] = 127, + [2][1][2][0][RTW89_FCC][34] = 76, + [2][1][2][0][RTW89_ETSI][34] = 127, + [2][1][2][0][RTW89_MKK][34] = 72, + [2][1][2][0][RTW89_IC][34] = 76, + [2][1][2][0][RTW89_ACMA][34] = 72, + [2][1][2][0][RTW89_FCC][41] = 76, + [2][1][2][0][RTW89_ETSI][41] = 18, + [2][1][2][0][RTW89_MKK][41] = 127, + [2][1][2][0][RTW89_IC][41] = 76, + [2][1][2][0][RTW89_ACMA][41] = 72, + [2][1][2][0][RTW89_FCC][49] = 60, + [2][1][2][0][RTW89_ETSI][49] = 127, + [2][1][2][0][RTW89_MKK][49] = 127, + [2][1][2][0][RTW89_IC][49] = 127, + [2][1][2][0][RTW89_ACMA][49] = 127, + [2][1][2][1][RTW89_FCC][3] = 58, + [2][1][2][1][RTW89_ETSI][3] = 42, + [2][1][2][1][RTW89_MKK][3] = 54, + [2][1][2][1][RTW89_IC][3] = 42, + [2][1][2][1][RTW89_ACMA][3] = 42, + [2][1][2][1][RTW89_FCC][11] = 64, + [2][1][2][1][RTW89_ETSI][11] = 42, + [2][1][2][1][RTW89_MKK][11] = 54, + [2][1][2][1][RTW89_IC][11] = 42, + [2][1][2][1][RTW89_ACMA][11] = 42, + [2][1][2][1][RTW89_FCC][18] = 58, + [2][1][2][1][RTW89_ETSI][18] = 42, + [2][1][2][1][RTW89_MKK][18] = 72, + [2][1][2][1][RTW89_IC][18] = 58, + [2][1][2][1][RTW89_ACMA][18] = 42, + [2][1][2][1][RTW89_FCC][26] = 70, + [2][1][2][1][RTW89_ETSI][26] = 44, + [2][1][2][1][RTW89_MKK][26] = 72, + [2][1][2][1][RTW89_IC][26] = 127, + [2][1][2][1][RTW89_ACMA][26] = 127, + [2][1][2][1][RTW89_FCC][34] = 70, + [2][1][2][1][RTW89_ETSI][34] = 127, + [2][1][2][1][RTW89_MKK][34] = 72, + [2][1][2][1][RTW89_IC][34] = 70, + [2][1][2][1][RTW89_ACMA][34] = 72, + [2][1][2][1][RTW89_FCC][41] = 76, + [2][1][2][1][RTW89_ETSI][41] = 8, + [2][1][2][1][RTW89_MKK][41] = 127, + [2][1][2][1][RTW89_IC][41] = 76, + [2][1][2][1][RTW89_ACMA][41] = 72, + [2][1][2][1][RTW89_FCC][49] = 60, + [2][1][2][1][RTW89_ETSI][49] = 127, + [2][1][2][1][RTW89_MKK][49] = 127, + [2][1][2][1][RTW89_IC][49] = 127, + [2][1][2][1][RTW89_ACMA][49] = 127, + [3][0][2][0][RTW89_FCC][7] = 56, + [3][0][2][0][RTW89_ETSI][7] = 56, + [3][0][2][0][RTW89_MKK][7] = 56, + [3][0][2][0][RTW89_IC][7] = 56, + [3][0][2][0][RTW89_ACMA][7] = 56, + [3][0][2][0][RTW89_FCC][22] = 56, + [3][0][2][0][RTW89_ETSI][22] = 56, + [3][0][2][0][RTW89_MKK][22] = 56, + [3][0][2][0][RTW89_IC][22] = 56, + [3][0][2][0][RTW89_ACMA][22] = 56, + [3][0][2][0][RTW89_FCC][45] = 56, + [3][0][2][0][RTW89_ETSI][45] = 127, + [3][0][2][0][RTW89_MKK][45] = 127, + [3][0][2][0][RTW89_IC][45] = 127, + [3][0][2][0][RTW89_ACMA][45] = 127, + [3][1][2][0][RTW89_FCC][7] = 44, + [3][1][2][0][RTW89_ETSI][7] = 44, + [3][1][2][0][RTW89_MKK][7] = 44, + [3][1][2][0][RTW89_IC][7] = 44, + [3][1][2][0][RTW89_ACMA][7] = 44, + [3][1][2][0][RTW89_FCC][22] = 44, + [3][1][2][0][RTW89_ETSI][22] = 44, + [3][1][2][0][RTW89_MKK][22] = 44, + [3][1][2][0][RTW89_IC][22] = 44, + [3][1][2][0][RTW89_ACMA][22] = 44, + [3][1][2][0][RTW89_FCC][45] = 44, + [3][1][2][0][RTW89_ETSI][45] = 127, + [3][1][2][0][RTW89_MKK][45] = 127, + [3][1][2][0][RTW89_IC][45] = 127, + [3][1][2][0][RTW89_ACMA][45] = 127, + [3][1][2][1][RTW89_FCC][7] = 32, + [3][1][2][1][RTW89_ETSI][7] = 32, + [3][1][2][1][RTW89_MKK][7] = 32, + [3][1][2][1][RTW89_IC][7] = 32, + [3][1][2][1][RTW89_ACMA][7] = 32, + [3][1][2][1][RTW89_FCC][22] = 32, + [3][1][2][1][RTW89_ETSI][22] = 32, + [3][1][2][1][RTW89_MKK][22] = 32, + [3][1][2][1][RTW89_IC][22] = 32, + [3][1][2][1][RTW89_ACMA][22] = 32, + [3][1][2][1][RTW89_FCC][45] = 32, + [3][1][2][1][RTW89_ETSI][45] = 127, + [3][1][2][1][RTW89_MKK][45] = 127, + [3][1][2][1][RTW89_IC][45] = 127, + [3][1][2][1][RTW89_ACMA][45] = 127, +}; + +const s8 rtw89_8852c_txpwr_lmt_6g[RTW89_6G_BW_NUM][RTW89_NTX_NUM] + [RTW89_RS_LMT_NUM][RTW89_BF_NUM] + [RTW89_REGD_NUM][RTW89_6G_CH_NUM] = { + [0][0][1][0][RTW89_WW][0] = 72, + [0][0][1][0][RTW89_WW][2] = 72, + [0][0][1][0][RTW89_WW][4] = 72, + [0][0][1][0][RTW89_WW][6] = 72, + [0][0][1][0][RTW89_WW][8] = 72, + [0][0][1][0][RTW89_WW][10] = 72, + [0][0][1][0][RTW89_WW][12] = 72, + [0][0][1][0][RTW89_WW][14] = 72, + [0][0][1][0][RTW89_WW][15] = 72, + [0][0][1][0][RTW89_WW][17] = 72, + [0][0][1][0][RTW89_WW][19] = 72, + [0][0][1][0][RTW89_WW][21] = 72, + [0][0][1][0][RTW89_WW][23] = 72, + [0][0][1][0][RTW89_WW][25] = 72, + [0][0][1][0][RTW89_WW][27] = 72, + [0][0][1][0][RTW89_WW][29] = 72, + [0][0][1][0][RTW89_WW][30] = 72, + [0][0][1][0][RTW89_WW][32] = 72, + [0][0][1][0][RTW89_WW][34] = 72, + [0][0][1][0][RTW89_WW][36] = 72, + [0][0][1][0][RTW89_WW][38] = 72, + [0][0][1][0][RTW89_WW][40] = 72, + [0][0][1][0][RTW89_WW][42] = 72, + [0][0][1][0][RTW89_WW][44] = 72, + [0][0][1][0][RTW89_WW][45] = 72, + [0][0][1][0][RTW89_WW][47] = 72, + [0][0][1][0][RTW89_WW][49] = 72, + [0][0][1][0][RTW89_WW][51] = 72, + [0][0][1][0][RTW89_WW][53] = 72, + [0][0][1][0][RTW89_WW][55] = 72, + [0][0][1][0][RTW89_WW][57] = 72, + [0][0][1][0][RTW89_WW][59] = 72, + [0][0][1][0][RTW89_WW][60] = 72, + [0][0][1][0][RTW89_WW][62] = 72, + [0][0][1][0][RTW89_WW][64] = 72, + [0][0][1][0][RTW89_WW][66] = 72, + [0][0][1][0][RTW89_WW][68] = 72, + [0][0][1][0][RTW89_WW][70] = 72, + [0][0][1][0][RTW89_WW][72] = 72, + [0][0][1][0][RTW89_WW][74] = 72, + [0][0][1][0][RTW89_WW][75] = 72, + [0][0][1][0][RTW89_WW][77] = 72, + [0][0][1][0][RTW89_WW][79] = 72, + [0][0][1][0][RTW89_WW][81] = 72, + [0][0][1][0][RTW89_WW][83] = 72, + [0][0][1][0][RTW89_WW][85] = 72, + [0][0][1][0][RTW89_WW][87] = 72, + [0][0][1][0][RTW89_WW][89] = 72, + [0][0][1][0][RTW89_WW][90] = 72, + [0][0][1][0][RTW89_WW][92] = 72, + [0][0][1][0][RTW89_WW][94] = 72, + [0][0][1][0][RTW89_WW][96] = 72, + [0][0][1][0][RTW89_WW][98] = 72, + [0][0][1][0][RTW89_WW][100] = 72, + [0][0][1][0][RTW89_WW][102] = 72, + [0][0][1][0][RTW89_WW][104] = 72, + [0][0][1][0][RTW89_WW][105] = 72, + [0][0][1][0][RTW89_WW][107] = 72, + [0][0][1][0][RTW89_WW][109] = 72, + [0][0][1][0][RTW89_WW][111] = 0, + [0][0][1][0][RTW89_WW][113] = 0, + [0][0][1][0][RTW89_WW][115] = 0, + [0][0][1][0][RTW89_WW][117] = 0, + [0][0][1][0][RTW89_WW][119] = 0, + [0][1][1][0][RTW89_WW][0] = 60, + [0][1][1][0][RTW89_WW][2] = 60, + [0][1][1][0][RTW89_WW][4] = 60, + [0][1][1][0][RTW89_WW][6] = 60, + [0][1][1][0][RTW89_WW][8] = 60, + [0][1][1][0][RTW89_WW][10] = 60, + [0][1][1][0][RTW89_WW][12] = 60, + [0][1][1][0][RTW89_WW][14] = 60, + [0][1][1][0][RTW89_WW][15] = 60, + [0][1][1][0][RTW89_WW][17] = 60, + [0][1][1][0][RTW89_WW][19] = 60, + [0][1][1][0][RTW89_WW][21] = 60, + [0][1][1][0][RTW89_WW][23] = 60, + [0][1][1][0][RTW89_WW][25] = 60, + [0][1][1][0][RTW89_WW][27] = 60, + [0][1][1][0][RTW89_WW][29] = 60, + [0][1][1][0][RTW89_WW][30] = 60, + [0][1][1][0][RTW89_WW][32] = 60, + [0][1][1][0][RTW89_WW][34] = 60, + [0][1][1][0][RTW89_WW][36] = 60, + [0][1][1][0][RTW89_WW][38] = 60, + [0][1][1][0][RTW89_WW][40] = 60, + [0][1][1][0][RTW89_WW][42] = 60, + [0][1][1][0][RTW89_WW][44] = 60, + [0][1][1][0][RTW89_WW][45] = 60, + [0][1][1][0][RTW89_WW][47] = 60, + [0][1][1][0][RTW89_WW][49] = 60, + [0][1][1][0][RTW89_WW][51] = 60, + [0][1][1][0][RTW89_WW][53] = 60, + [0][1][1][0][RTW89_WW][55] = 60, + [0][1][1][0][RTW89_WW][57] = 60, + [0][1][1][0][RTW89_WW][59] = 60, + [0][1][1][0][RTW89_WW][60] = 60, + [0][1][1][0][RTW89_WW][62] = 60, + [0][1][1][0][RTW89_WW][64] = 60, + [0][1][1][0][RTW89_WW][66] = 60, + [0][1][1][0][RTW89_WW][68] = 60, + [0][1][1][0][RTW89_WW][70] = 60, + [0][1][1][0][RTW89_WW][72] = 60, + [0][1][1][0][RTW89_WW][74] = 60, + [0][1][1][0][RTW89_WW][75] = 60, + [0][1][1][0][RTW89_WW][77] = 60, + [0][1][1][0][RTW89_WW][79] = 60, + [0][1][1][0][RTW89_WW][81] = 60, + [0][1][1][0][RTW89_WW][83] = 60, + [0][1][1][0][RTW89_WW][85] = 60, + [0][1][1][0][RTW89_WW][87] = 60, + [0][1][1][0][RTW89_WW][89] = 60, + [0][1][1][0][RTW89_WW][90] = 60, + [0][1][1][0][RTW89_WW][92] = 60, + [0][1][1][0][RTW89_WW][94] = 60, + [0][1][1][0][RTW89_WW][96] = 60, + [0][1][1][0][RTW89_WW][98] = 60, + [0][1][1][0][RTW89_WW][100] = 60, + [0][1][1][0][RTW89_WW][102] = 60, + [0][1][1][0][RTW89_WW][104] = 60, + [0][1][1][0][RTW89_WW][105] = 60, + [0][1][1][0][RTW89_WW][107] = 60, + [0][1][1][0][RTW89_WW][109] = 60, + [0][1][1][0][RTW89_WW][111] = 0, + [0][1][1][0][RTW89_WW][113] = 0, + [0][1][1][0][RTW89_WW][115] = 0, + [0][1][1][0][RTW89_WW][117] = 0, + [0][1][1][0][RTW89_WW][119] = 0, + [0][0][2][0][RTW89_WW][0] = 72, + [0][0][2][0][RTW89_WW][2] = 72, + [0][0][2][0][RTW89_WW][4] = 72, + [0][0][2][0][RTW89_WW][6] = 72, + [0][0][2][0][RTW89_WW][8] = 72, + [0][0][2][0][RTW89_WW][10] = 72, + [0][0][2][0][RTW89_WW][12] = 72, + [0][0][2][0][RTW89_WW][14] = 72, + [0][0][2][0][RTW89_WW][15] = 72, + [0][0][2][0][RTW89_WW][17] = 72, + [0][0][2][0][RTW89_WW][19] = 72, + [0][0][2][0][RTW89_WW][21] = 72, + [0][0][2][0][RTW89_WW][23] = 72, + [0][0][2][0][RTW89_WW][25] = 72, + [0][0][2][0][RTW89_WW][27] = 72, + [0][0][2][0][RTW89_WW][29] = 72, + [0][0][2][0][RTW89_WW][30] = 72, + [0][0][2][0][RTW89_WW][32] = 72, + [0][0][2][0][RTW89_WW][34] = 72, + [0][0][2][0][RTW89_WW][36] = 72, + [0][0][2][0][RTW89_WW][38] = 72, + [0][0][2][0][RTW89_WW][40] = 72, + [0][0][2][0][RTW89_WW][42] = 72, + [0][0][2][0][RTW89_WW][44] = 72, + [0][0][2][0][RTW89_WW][45] = 72, + [0][0][2][0][RTW89_WW][47] = 72, + [0][0][2][0][RTW89_WW][49] = 72, + [0][0][2][0][RTW89_WW][51] = 72, + [0][0][2][0][RTW89_WW][53] = 72, + [0][0][2][0][RTW89_WW][55] = 72, + [0][0][2][0][RTW89_WW][57] = 72, + [0][0][2][0][RTW89_WW][59] = 72, + [0][0][2][0][RTW89_WW][60] = 72, + [0][0][2][0][RTW89_WW][62] = 72, + [0][0][2][0][RTW89_WW][64] = 72, + [0][0][2][0][RTW89_WW][66] = 72, + [0][0][2][0][RTW89_WW][68] = 72, + [0][0][2][0][RTW89_WW][70] = 72, + [0][0][2][0][RTW89_WW][72] = 72, + [0][0][2][0][RTW89_WW][74] = 72, + [0][0][2][0][RTW89_WW][75] = 72, + [0][0][2][0][RTW89_WW][77] = 72, + [0][0][2][0][RTW89_WW][79] = 72, + [0][0][2][0][RTW89_WW][81] = 72, + [0][0][2][0][RTW89_WW][83] = 72, + [0][0][2][0][RTW89_WW][85] = 72, + [0][0][2][0][RTW89_WW][87] = 72, + [0][0][2][0][RTW89_WW][89] = 72, + [0][0][2][0][RTW89_WW][90] = 72, + [0][0][2][0][RTW89_WW][92] = 72, + [0][0][2][0][RTW89_WW][94] = 72, + [0][0][2][0][RTW89_WW][96] = 72, + [0][0][2][0][RTW89_WW][98] = 72, + [0][0][2][0][RTW89_WW][100] = 72, + [0][0][2][0][RTW89_WW][102] = 72, + [0][0][2][0][RTW89_WW][104] = 72, + [0][0][2][0][RTW89_WW][105] = 72, + [0][0][2][0][RTW89_WW][107] = 72, + [0][0][2][0][RTW89_WW][109] = 72, + [0][0][2][0][RTW89_WW][111] = 0, + [0][0][2][0][RTW89_WW][113] = 0, + [0][0][2][0][RTW89_WW][115] = 0, + [0][0][2][0][RTW89_WW][117] = 0, + [0][0][2][0][RTW89_WW][119] = 0, + [0][1][2][0][RTW89_WW][0] = 60, + [0][1][2][0][RTW89_WW][2] = 60, + [0][1][2][0][RTW89_WW][4] = 60, + [0][1][2][0][RTW89_WW][6] = 60, + [0][1][2][0][RTW89_WW][8] = 60, + [0][1][2][0][RTW89_WW][10] = 60, + [0][1][2][0][RTW89_WW][12] = 60, + [0][1][2][0][RTW89_WW][14] = 60, + [0][1][2][0][RTW89_WW][15] = 60, + [0][1][2][0][RTW89_WW][17] = 60, + [0][1][2][0][RTW89_WW][19] = 60, + [0][1][2][0][RTW89_WW][21] = 60, + [0][1][2][0][RTW89_WW][23] = 60, + [0][1][2][0][RTW89_WW][25] = 60, + [0][1][2][0][RTW89_WW][27] = 60, + [0][1][2][0][RTW89_WW][29] = 60, + [0][1][2][0][RTW89_WW][30] = 60, + [0][1][2][0][RTW89_WW][32] = 60, + [0][1][2][0][RTW89_WW][34] = 60, + [0][1][2][0][RTW89_WW][36] = 60, + [0][1][2][0][RTW89_WW][38] = 60, + [0][1][2][0][RTW89_WW][40] = 60, + [0][1][2][0][RTW89_WW][42] = 60, + [0][1][2][0][RTW89_WW][44] = 60, + [0][1][2][0][RTW89_WW][45] = 60, + [0][1][2][0][RTW89_WW][47] = 60, + [0][1][2][0][RTW89_WW][49] = 60, + [0][1][2][0][RTW89_WW][51] = 60, + [0][1][2][0][RTW89_WW][53] = 60, + [0][1][2][0][RTW89_WW][55] = 60, + [0][1][2][0][RTW89_WW][57] = 60, + [0][1][2][0][RTW89_WW][59] = 60, + [0][1][2][0][RTW89_WW][60] = 60, + [0][1][2][0][RTW89_WW][62] = 60, + [0][1][2][0][RTW89_WW][64] = 60, + [0][1][2][0][RTW89_WW][66] = 60, + [0][1][2][0][RTW89_WW][68] = 60, + [0][1][2][0][RTW89_WW][70] = 60, + [0][1][2][0][RTW89_WW][72] = 60, + [0][1][2][0][RTW89_WW][74] = 60, + [0][1][2][0][RTW89_WW][75] = 60, + [0][1][2][0][RTW89_WW][77] = 60, + [0][1][2][0][RTW89_WW][79] = 60, + [0][1][2][0][RTW89_WW][81] = 60, + [0][1][2][0][RTW89_WW][83] = 60, + [0][1][2][0][RTW89_WW][85] = 60, + [0][1][2][0][RTW89_WW][87] = 60, + [0][1][2][0][RTW89_WW][89] = 60, + [0][1][2][0][RTW89_WW][90] = 60, + [0][1][2][0][RTW89_WW][92] = 60, + [0][1][2][0][RTW89_WW][94] = 60, + [0][1][2][0][RTW89_WW][96] = 60, + [0][1][2][0][RTW89_WW][98] = 60, + [0][1][2][0][RTW89_WW][100] = 60, + [0][1][2][0][RTW89_WW][102] = 60, + [0][1][2][0][RTW89_WW][104] = 60, + [0][1][2][0][RTW89_WW][105] = 60, + [0][1][2][0][RTW89_WW][107] = 60, + [0][1][2][0][RTW89_WW][109] = 60, + [0][1][2][0][RTW89_WW][111] = 0, + [0][1][2][0][RTW89_WW][113] = 0, + [0][1][2][0][RTW89_WW][115] = 0, + [0][1][2][0][RTW89_WW][117] = 0, + [0][1][2][0][RTW89_WW][119] = 0, + [0][1][2][1][RTW89_WW][0] = 48, + [0][1][2][1][RTW89_WW][2] = 48, + [0][1][2][1][RTW89_WW][4] = 48, + [0][1][2][1][RTW89_WW][6] = 48, + [0][1][2][1][RTW89_WW][8] = 48, + [0][1][2][1][RTW89_WW][10] = 48, + [0][1][2][1][RTW89_WW][12] = 48, + [0][1][2][1][RTW89_WW][14] = 48, + [0][1][2][1][RTW89_WW][15] = 48, + [0][1][2][1][RTW89_WW][17] = 48, + [0][1][2][1][RTW89_WW][19] = 48, + [0][1][2][1][RTW89_WW][21] = 48, + [0][1][2][1][RTW89_WW][23] = 48, + [0][1][2][1][RTW89_WW][25] = 48, + [0][1][2][1][RTW89_WW][27] = 48, + [0][1][2][1][RTW89_WW][29] = 48, + [0][1][2][1][RTW89_WW][30] = 48, + [0][1][2][1][RTW89_WW][32] = 48, + [0][1][2][1][RTW89_WW][34] = 48, + [0][1][2][1][RTW89_WW][36] = 48, + [0][1][2][1][RTW89_WW][38] = 48, + [0][1][2][1][RTW89_WW][40] = 48, + [0][1][2][1][RTW89_WW][42] = 48, + [0][1][2][1][RTW89_WW][44] = 48, + [0][1][2][1][RTW89_WW][45] = 48, + [0][1][2][1][RTW89_WW][47] = 48, + [0][1][2][1][RTW89_WW][49] = 48, + [0][1][2][1][RTW89_WW][51] = 48, + [0][1][2][1][RTW89_WW][53] = 48, + [0][1][2][1][RTW89_WW][55] = 48, + [0][1][2][1][RTW89_WW][57] = 48, + [0][1][2][1][RTW89_WW][59] = 48, + [0][1][2][1][RTW89_WW][60] = 48, + [0][1][2][1][RTW89_WW][62] = 48, + [0][1][2][1][RTW89_WW][64] = 48, + [0][1][2][1][RTW89_WW][66] = 48, + [0][1][2][1][RTW89_WW][68] = 48, + [0][1][2][1][RTW89_WW][70] = 48, + [0][1][2][1][RTW89_WW][72] = 48, + [0][1][2][1][RTW89_WW][74] = 48, + [0][1][2][1][RTW89_WW][75] = 48, + [0][1][2][1][RTW89_WW][77] = 48, + [0][1][2][1][RTW89_WW][79] = 48, + [0][1][2][1][RTW89_WW][81] = 48, + [0][1][2][1][RTW89_WW][83] = 48, + [0][1][2][1][RTW89_WW][85] = 48, + [0][1][2][1][RTW89_WW][87] = 48, + [0][1][2][1][RTW89_WW][89] = 48, + [0][1][2][1][RTW89_WW][90] = 48, + [0][1][2][1][RTW89_WW][92] = 48, + [0][1][2][1][RTW89_WW][94] = 48, + [0][1][2][1][RTW89_WW][96] = 48, + [0][1][2][1][RTW89_WW][98] = 48, + [0][1][2][1][RTW89_WW][100] = 48, + [0][1][2][1][RTW89_WW][102] = 48, + [0][1][2][1][RTW89_WW][104] = 48, + [0][1][2][1][RTW89_WW][105] = 48, + [0][1][2][1][RTW89_WW][107] = 48, + [0][1][2][1][RTW89_WW][109] = 48, + [0][1][2][1][RTW89_WW][111] = 0, + [0][1][2][1][RTW89_WW][113] = 0, + [0][1][2][1][RTW89_WW][115] = 0, + [0][1][2][1][RTW89_WW][117] = 0, + [0][1][2][1][RTW89_WW][119] = 0, + [1][0][2][0][RTW89_WW][1] = 72, + [1][0][2][0][RTW89_WW][5] = 72, + [1][0][2][0][RTW89_WW][9] = 72, + [1][0][2][0][RTW89_WW][13] = 72, + [1][0][2][0][RTW89_WW][16] = 72, + [1][0][2][0][RTW89_WW][20] = 72, + [1][0][2][0][RTW89_WW][24] = 72, + [1][0][2][0][RTW89_WW][28] = 72, + [1][0][2][0][RTW89_WW][31] = 72, + [1][0][2][0][RTW89_WW][35] = 72, + [1][0][2][0][RTW89_WW][39] = 72, + [1][0][2][0][RTW89_WW][43] = 72, + [1][0][2][0][RTW89_WW][46] = 72, + [1][0][2][0][RTW89_WW][50] = 72, + [1][0][2][0][RTW89_WW][54] = 72, + [1][0][2][0][RTW89_WW][58] = 72, + [1][0][2][0][RTW89_WW][61] = 72, + [1][0][2][0][RTW89_WW][65] = 72, + [1][0][2][0][RTW89_WW][69] = 72, + [1][0][2][0][RTW89_WW][73] = 72, + [1][0][2][0][RTW89_WW][76] = 72, + [1][0][2][0][RTW89_WW][80] = 72, + [1][0][2][0][RTW89_WW][84] = 72, + [1][0][2][0][RTW89_WW][88] = 72, + [1][0][2][0][RTW89_WW][91] = 72, + [1][0][2][0][RTW89_WW][95] = 72, + [1][0][2][0][RTW89_WW][99] = 72, + [1][0][2][0][RTW89_WW][103] = 72, + [1][0][2][0][RTW89_WW][106] = 72, + [1][0][2][0][RTW89_WW][110] = 0, + [1][0][2][0][RTW89_WW][114] = 0, + [1][0][2][0][RTW89_WW][118] = 0, + [1][1][2][0][RTW89_WW][1] = 60, + [1][1][2][0][RTW89_WW][5] = 60, + [1][1][2][0][RTW89_WW][9] = 60, + [1][1][2][0][RTW89_WW][13] = 60, + [1][1][2][0][RTW89_WW][16] = 60, + [1][1][2][0][RTW89_WW][20] = 60, + [1][1][2][0][RTW89_WW][24] = 60, + [1][1][2][0][RTW89_WW][28] = 60, + [1][1][2][0][RTW89_WW][31] = 60, + [1][1][2][0][RTW89_WW][35] = 60, + [1][1][2][0][RTW89_WW][39] = 60, + [1][1][2][0][RTW89_WW][43] = 60, + [1][1][2][0][RTW89_WW][46] = 60, + [1][1][2][0][RTW89_WW][50] = 60, + [1][1][2][0][RTW89_WW][54] = 60, + [1][1][2][0][RTW89_WW][58] = 60, + [1][1][2][0][RTW89_WW][61] = 60, + [1][1][2][0][RTW89_WW][65] = 60, + [1][1][2][0][RTW89_WW][69] = 60, + [1][1][2][0][RTW89_WW][73] = 60, + [1][1][2][0][RTW89_WW][76] = 60, + [1][1][2][0][RTW89_WW][80] = 60, + [1][1][2][0][RTW89_WW][84] = 60, + [1][1][2][0][RTW89_WW][88] = 60, + [1][1][2][0][RTW89_WW][91] = 60, + [1][1][2][0][RTW89_WW][95] = 60, + [1][1][2][0][RTW89_WW][99] = 60, + [1][1][2][0][RTW89_WW][103] = 60, + [1][1][2][0][RTW89_WW][106] = 60, + [1][1][2][0][RTW89_WW][110] = 0, + [1][1][2][0][RTW89_WW][114] = 0, + [1][1][2][0][RTW89_WW][118] = 0, + [1][1][2][1][RTW89_WW][1] = 48, + [1][1][2][1][RTW89_WW][5] = 48, + [1][1][2][1][RTW89_WW][9] = 48, + [1][1][2][1][RTW89_WW][13] = 48, + [1][1][2][1][RTW89_WW][16] = 48, + [1][1][2][1][RTW89_WW][20] = 48, + [1][1][2][1][RTW89_WW][24] = 48, + [1][1][2][1][RTW89_WW][28] = 48, + [1][1][2][1][RTW89_WW][31] = 48, + [1][1][2][1][RTW89_WW][35] = 48, + [1][1][2][1][RTW89_WW][39] = 48, + [1][1][2][1][RTW89_WW][43] = 48, + [1][1][2][1][RTW89_WW][46] = 48, + [1][1][2][1][RTW89_WW][50] = 48, + [1][1][2][1][RTW89_WW][54] = 48, + [1][1][2][1][RTW89_WW][58] = 48, + [1][1][2][1][RTW89_WW][61] = 48, + [1][1][2][1][RTW89_WW][65] = 48, + [1][1][2][1][RTW89_WW][69] = 48, + [1][1][2][1][RTW89_WW][73] = 48, + [1][1][2][1][RTW89_WW][76] = 48, + [1][1][2][1][RTW89_WW][80] = 48, + [1][1][2][1][RTW89_WW][84] = 48, + [1][1][2][1][RTW89_WW][88] = 48, + [1][1][2][1][RTW89_WW][91] = 48, + [1][1][2][1][RTW89_WW][95] = 48, + [1][1][2][1][RTW89_WW][99] = 48, + [1][1][2][1][RTW89_WW][103] = 48, + [1][1][2][1][RTW89_WW][106] = 48, + [1][1][2][1][RTW89_WW][110] = 0, + [1][1][2][1][RTW89_WW][114] = 0, + [1][1][2][1][RTW89_WW][118] = 0, + [2][0][2][0][RTW89_WW][3] = 64, + [2][0][2][0][RTW89_WW][11] = 64, + [2][0][2][0][RTW89_WW][18] = 64, + [2][0][2][0][RTW89_WW][26] = 64, + [2][0][2][0][RTW89_WW][33] = 64, + [2][0][2][0][RTW89_WW][41] = 64, + [2][0][2][0][RTW89_WW][48] = 64, + [2][0][2][0][RTW89_WW][56] = 64, + [2][0][2][0][RTW89_WW][63] = 64, + [2][0][2][0][RTW89_WW][71] = 64, + [2][0][2][0][RTW89_WW][78] = 64, + [2][0][2][0][RTW89_WW][86] = 64, + [2][0][2][0][RTW89_WW][93] = 64, + [2][0][2][0][RTW89_WW][101] = 64, + [2][0][2][0][RTW89_WW][108] = 0, + [2][0][2][0][RTW89_WW][116] = 0, + [2][1][2][0][RTW89_WW][3] = 52, + [2][1][2][0][RTW89_WW][11] = 52, + [2][1][2][0][RTW89_WW][18] = 52, + [2][1][2][0][RTW89_WW][26] = 52, + [2][1][2][0][RTW89_WW][33] = 52, + [2][1][2][0][RTW89_WW][41] = 52, + [2][1][2][0][RTW89_WW][48] = 52, + [2][1][2][0][RTW89_WW][56] = 52, + [2][1][2][0][RTW89_WW][63] = 52, + [2][1][2][0][RTW89_WW][71] = 52, + [2][1][2][0][RTW89_WW][78] = 52, + [2][1][2][0][RTW89_WW][86] = 52, + [2][1][2][0][RTW89_WW][93] = 52, + [2][1][2][0][RTW89_WW][101] = 52, + [2][1][2][0][RTW89_WW][108] = 0, + [2][1][2][0][RTW89_WW][116] = 0, + [2][1][2][1][RTW89_WW][3] = 40, + [2][1][2][1][RTW89_WW][11] = 40, + [2][1][2][1][RTW89_WW][18] = 40, + [2][1][2][1][RTW89_WW][26] = 40, + [2][1][2][1][RTW89_WW][33] = 40, + [2][1][2][1][RTW89_WW][41] = 40, + [2][1][2][1][RTW89_WW][48] = 40, + [2][1][2][1][RTW89_WW][56] = 40, + [2][1][2][1][RTW89_WW][63] = 40, + [2][1][2][1][RTW89_WW][71] = 40, + [2][1][2][1][RTW89_WW][78] = 40, + [2][1][2][1][RTW89_WW][86] = 40, + [2][1][2][1][RTW89_WW][93] = 40, + [2][1][2][1][RTW89_WW][101] = 40, + [2][1][2][1][RTW89_WW][108] = 0, + [2][1][2][1][RTW89_WW][116] = 0, + [3][0][2][0][RTW89_WW][7] = 56, + [3][0][2][0][RTW89_WW][22] = 56, + [3][0][2][0][RTW89_WW][37] = 56, + [3][0][2][0][RTW89_WW][52] = 56, + [3][0][2][0][RTW89_WW][67] = 56, + [3][0][2][0][RTW89_WW][82] = 56, + [3][0][2][0][RTW89_WW][97] = 56, + [3][0][2][0][RTW89_WW][112] = 0, + [3][1][2][0][RTW89_WW][7] = 44, + [3][1][2][0][RTW89_WW][22] = 44, + [3][1][2][0][RTW89_WW][37] = 44, + [3][1][2][0][RTW89_WW][52] = 44, + [3][1][2][0][RTW89_WW][67] = 44, + [3][1][2][0][RTW89_WW][82] = 44, + [3][1][2][0][RTW89_WW][97] = 44, + [3][1][2][0][RTW89_WW][112] = 0, + [3][1][2][1][RTW89_WW][7] = 32, + [3][1][2][1][RTW89_WW][22] = 32, + [3][1][2][1][RTW89_WW][37] = 32, + [3][1][2][1][RTW89_WW][52] = 32, + [3][1][2][1][RTW89_WW][67] = 32, + [3][1][2][1][RTW89_WW][82] = 32, + [3][1][2][1][RTW89_WW][97] = 32, + [3][1][2][1][RTW89_WW][112] = 0, + [0][0][1][0][RTW89_FCC][0] = 72, + [0][0][1][0][RTW89_FCC][2] = 72, + [0][0][1][0][RTW89_FCC][4] = 72, + [0][0][1][0][RTW89_FCC][6] = 72, + [0][0][1][0][RTW89_FCC][8] = 72, + [0][0][1][0][RTW89_FCC][10] = 72, + [0][0][1][0][RTW89_FCC][12] = 72, + [0][0][1][0][RTW89_FCC][14] = 72, + [0][0][1][0][RTW89_FCC][15] = 72, + [0][0][1][0][RTW89_FCC][17] = 72, + [0][0][1][0][RTW89_FCC][19] = 72, + [0][0][1][0][RTW89_FCC][21] = 72, + [0][0][1][0][RTW89_FCC][23] = 72, + [0][0][1][0][RTW89_FCC][25] = 72, + [0][0][1][0][RTW89_FCC][27] = 72, + [0][0][1][0][RTW89_FCC][29] = 72, + [0][0][1][0][RTW89_FCC][30] = 72, + [0][0][1][0][RTW89_FCC][32] = 72, + [0][0][1][0][RTW89_FCC][34] = 72, + [0][0][1][0][RTW89_FCC][36] = 72, + [0][0][1][0][RTW89_FCC][38] = 72, + [0][0][1][0][RTW89_FCC][40] = 72, + [0][0][1][0][RTW89_FCC][42] = 72, + [0][0][1][0][RTW89_FCC][44] = 72, + [0][0][1][0][RTW89_FCC][45] = 72, + [0][0][1][0][RTW89_FCC][47] = 72, + [0][0][1][0][RTW89_FCC][49] = 72, + [0][0][1][0][RTW89_FCC][51] = 72, + [0][0][1][0][RTW89_FCC][53] = 72, + [0][0][1][0][RTW89_FCC][55] = 72, + [0][0][1][0][RTW89_FCC][57] = 72, + [0][0][1][0][RTW89_FCC][59] = 72, + [0][0][1][0][RTW89_FCC][60] = 72, + [0][0][1][0][RTW89_FCC][62] = 72, + [0][0][1][0][RTW89_FCC][64] = 72, + [0][0][1][0][RTW89_FCC][66] = 72, + [0][0][1][0][RTW89_FCC][68] = 72, + [0][0][1][0][RTW89_FCC][70] = 72, + [0][0][1][0][RTW89_FCC][72] = 72, + [0][0][1][0][RTW89_FCC][74] = 72, + [0][0][1][0][RTW89_FCC][75] = 72, + [0][0][1][0][RTW89_FCC][77] = 72, + [0][0][1][0][RTW89_FCC][79] = 72, + [0][0][1][0][RTW89_FCC][81] = 72, + [0][0][1][0][RTW89_FCC][83] = 72, + [0][0][1][0][RTW89_FCC][85] = 72, + [0][0][1][0][RTW89_FCC][87] = 72, + [0][0][1][0][RTW89_FCC][89] = 72, + [0][0][1][0][RTW89_FCC][90] = 72, + [0][0][1][0][RTW89_FCC][92] = 72, + [0][0][1][0][RTW89_FCC][94] = 72, + [0][0][1][0][RTW89_FCC][96] = 72, + [0][0][1][0][RTW89_FCC][98] = 72, + [0][0][1][0][RTW89_FCC][100] = 72, + [0][0][1][0][RTW89_FCC][102] = 72, + [0][0][1][0][RTW89_FCC][104] = 72, + [0][0][1][0][RTW89_FCC][105] = 72, + [0][0][1][0][RTW89_FCC][107] = 72, + [0][0][1][0][RTW89_FCC][109] = 72, + [0][0][1][0][RTW89_FCC][111] = 127, + [0][0][1][0][RTW89_FCC][113] = 127, + [0][0][1][0][RTW89_FCC][115] = 127, + [0][0][1][0][RTW89_FCC][117] = 127, + [0][0][1][0][RTW89_FCC][119] = 127, + [0][1][1][0][RTW89_FCC][0] = 60, + [0][1][1][0][RTW89_FCC][2] = 60, + [0][1][1][0][RTW89_FCC][4] = 60, + [0][1][1][0][RTW89_FCC][6] = 60, + [0][1][1][0][RTW89_FCC][8] = 60, + [0][1][1][0][RTW89_FCC][10] = 60, + [0][1][1][0][RTW89_FCC][12] = 60, + [0][1][1][0][RTW89_FCC][14] = 60, + [0][1][1][0][RTW89_FCC][15] = 60, + [0][1][1][0][RTW89_FCC][17] = 60, + [0][1][1][0][RTW89_FCC][19] = 60, + [0][1][1][0][RTW89_FCC][21] = 60, + [0][1][1][0][RTW89_FCC][23] = 60, + [0][1][1][0][RTW89_FCC][25] = 60, + [0][1][1][0][RTW89_FCC][27] = 60, + [0][1][1][0][RTW89_FCC][29] = 60, + [0][1][1][0][RTW89_FCC][30] = 60, + [0][1][1][0][RTW89_FCC][32] = 60, + [0][1][1][0][RTW89_FCC][34] = 60, + [0][1][1][0][RTW89_FCC][36] = 60, + [0][1][1][0][RTW89_FCC][38] = 60, + [0][1][1][0][RTW89_FCC][40] = 60, + [0][1][1][0][RTW89_FCC][42] = 60, + [0][1][1][0][RTW89_FCC][44] = 60, + [0][1][1][0][RTW89_FCC][45] = 60, + [0][1][1][0][RTW89_FCC][47] = 60, + [0][1][1][0][RTW89_FCC][49] = 60, + [0][1][1][0][RTW89_FCC][51] = 60, + [0][1][1][0][RTW89_FCC][53] = 60, + [0][1][1][0][RTW89_FCC][55] = 60, + [0][1][1][0][RTW89_FCC][57] = 60, + [0][1][1][0][RTW89_FCC][59] = 60, + [0][1][1][0][RTW89_FCC][60] = 60, + [0][1][1][0][RTW89_FCC][62] = 60, + [0][1][1][0][RTW89_FCC][64] = 60, + [0][1][1][0][RTW89_FCC][66] = 60, + [0][1][1][0][RTW89_FCC][68] = 60, + [0][1][1][0][RTW89_FCC][70] = 60, + [0][1][1][0][RTW89_FCC][72] = 60, + [0][1][1][0][RTW89_FCC][74] = 60, + [0][1][1][0][RTW89_FCC][75] = 60, + [0][1][1][0][RTW89_FCC][77] = 60, + [0][1][1][0][RTW89_FCC][79] = 60, + [0][1][1][0][RTW89_FCC][81] = 60, + [0][1][1][0][RTW89_FCC][83] = 60, + [0][1][1][0][RTW89_FCC][85] = 60, + [0][1][1][0][RTW89_FCC][87] = 60, + [0][1][1][0][RTW89_FCC][89] = 60, + [0][1][1][0][RTW89_FCC][90] = 60, + [0][1][1][0][RTW89_FCC][92] = 60, + [0][1][1][0][RTW89_FCC][94] = 60, + [0][1][1][0][RTW89_FCC][96] = 60, + [0][1][1][0][RTW89_FCC][98] = 60, + [0][1][1][0][RTW89_FCC][100] = 60, + [0][1][1][0][RTW89_FCC][102] = 60, + [0][1][1][0][RTW89_FCC][104] = 60, + [0][1][1][0][RTW89_FCC][105] = 60, + [0][1][1][0][RTW89_FCC][107] = 60, + [0][1][1][0][RTW89_FCC][109] = 60, + [0][1][1][0][RTW89_FCC][111] = 127, + [0][1][1][0][RTW89_FCC][113] = 127, + [0][1][1][0][RTW89_FCC][115] = 127, + [0][1][1][0][RTW89_FCC][117] = 127, + [0][1][1][0][RTW89_FCC][119] = 127, + [0][0][2][0][RTW89_FCC][0] = 72, + [0][0][2][0][RTW89_FCC][2] = 72, + [0][0][2][0][RTW89_FCC][4] = 72, + [0][0][2][0][RTW89_FCC][6] = 72, + [0][0][2][0][RTW89_FCC][8] = 72, + [0][0][2][0][RTW89_FCC][10] = 72, + [0][0][2][0][RTW89_FCC][12] = 72, + [0][0][2][0][RTW89_FCC][14] = 72, + [0][0][2][0][RTW89_FCC][15] = 72, + [0][0][2][0][RTW89_FCC][17] = 72, + [0][0][2][0][RTW89_FCC][19] = 72, + [0][0][2][0][RTW89_FCC][21] = 72, + [0][0][2][0][RTW89_FCC][23] = 72, + [0][0][2][0][RTW89_FCC][25] = 72, + [0][0][2][0][RTW89_FCC][27] = 72, + [0][0][2][0][RTW89_FCC][29] = 72, + [0][0][2][0][RTW89_FCC][30] = 72, + [0][0][2][0][RTW89_FCC][32] = 72, + [0][0][2][0][RTW89_FCC][34] = 72, + [0][0][2][0][RTW89_FCC][36] = 72, + [0][0][2][0][RTW89_FCC][38] = 72, + [0][0][2][0][RTW89_FCC][40] = 72, + [0][0][2][0][RTW89_FCC][42] = 72, + [0][0][2][0][RTW89_FCC][44] = 72, + [0][0][2][0][RTW89_FCC][45] = 72, + [0][0][2][0][RTW89_FCC][47] = 72, + [0][0][2][0][RTW89_FCC][49] = 72, + [0][0][2][0][RTW89_FCC][51] = 72, + [0][0][2][0][RTW89_FCC][53] = 72, + [0][0][2][0][RTW89_FCC][55] = 72, + [0][0][2][0][RTW89_FCC][57] = 72, + [0][0][2][0][RTW89_FCC][59] = 72, + [0][0][2][0][RTW89_FCC][60] = 72, + [0][0][2][0][RTW89_FCC][62] = 72, + [0][0][2][0][RTW89_FCC][64] = 72, + [0][0][2][0][RTW89_FCC][66] = 72, + [0][0][2][0][RTW89_FCC][68] = 72, + [0][0][2][0][RTW89_FCC][70] = 72, + [0][0][2][0][RTW89_FCC][72] = 72, + [0][0][2][0][RTW89_FCC][74] = 72, + [0][0][2][0][RTW89_FCC][75] = 72, + [0][0][2][0][RTW89_FCC][77] = 72, + [0][0][2][0][RTW89_FCC][79] = 72, + [0][0][2][0][RTW89_FCC][81] = 72, + [0][0][2][0][RTW89_FCC][83] = 72, + [0][0][2][0][RTW89_FCC][85] = 72, + [0][0][2][0][RTW89_FCC][87] = 72, + [0][0][2][0][RTW89_FCC][89] = 72, + [0][0][2][0][RTW89_FCC][90] = 72, + [0][0][2][0][RTW89_FCC][92] = 72, + [0][0][2][0][RTW89_FCC][94] = 72, + [0][0][2][0][RTW89_FCC][96] = 72, + [0][0][2][0][RTW89_FCC][98] = 72, + [0][0][2][0][RTW89_FCC][100] = 72, + [0][0][2][0][RTW89_FCC][102] = 72, + [0][0][2][0][RTW89_FCC][104] = 72, + [0][0][2][0][RTW89_FCC][105] = 72, + [0][0][2][0][RTW89_FCC][107] = 72, + [0][0][2][0][RTW89_FCC][109] = 72, + [0][0][2][0][RTW89_FCC][111] = 127, + [0][0][2][0][RTW89_FCC][113] = 127, + [0][0][2][0][RTW89_FCC][115] = 127, + [0][0][2][0][RTW89_FCC][117] = 127, + [0][0][2][0][RTW89_FCC][119] = 127, + [0][1][2][0][RTW89_FCC][0] = 60, + [0][1][2][0][RTW89_FCC][2] = 60, + [0][1][2][0][RTW89_FCC][4] = 60, + [0][1][2][0][RTW89_FCC][6] = 60, + [0][1][2][0][RTW89_FCC][8] = 60, + [0][1][2][0][RTW89_FCC][10] = 60, + [0][1][2][0][RTW89_FCC][12] = 60, + [0][1][2][0][RTW89_FCC][14] = 60, + [0][1][2][0][RTW89_FCC][15] = 60, + [0][1][2][0][RTW89_FCC][17] = 60, + [0][1][2][0][RTW89_FCC][19] = 60, + [0][1][2][0][RTW89_FCC][21] = 60, + [0][1][2][0][RTW89_FCC][23] = 60, + [0][1][2][0][RTW89_FCC][25] = 60, + [0][1][2][0][RTW89_FCC][27] = 60, + [0][1][2][0][RTW89_FCC][29] = 60, + [0][1][2][0][RTW89_FCC][30] = 60, + [0][1][2][0][RTW89_FCC][32] = 60, + [0][1][2][0][RTW89_FCC][34] = 60, + [0][1][2][0][RTW89_FCC][36] = 60, + [0][1][2][0][RTW89_FCC][38] = 60, + [0][1][2][0][RTW89_FCC][40] = 60, + [0][1][2][0][RTW89_FCC][42] = 60, + [0][1][2][0][RTW89_FCC][44] = 60, + [0][1][2][0][RTW89_FCC][45] = 60, + [0][1][2][0][RTW89_FCC][47] = 60, + [0][1][2][0][RTW89_FCC][49] = 60, + [0][1][2][0][RTW89_FCC][51] = 60, + [0][1][2][0][RTW89_FCC][53] = 60, + [0][1][2][0][RTW89_FCC][55] = 60, + [0][1][2][0][RTW89_FCC][57] = 60, + [0][1][2][0][RTW89_FCC][59] = 60, + [0][1][2][0][RTW89_FCC][60] = 60, + [0][1][2][0][RTW89_FCC][62] = 60, + [0][1][2][0][RTW89_FCC][64] = 60, + [0][1][2][0][RTW89_FCC][66] = 60, + [0][1][2][0][RTW89_FCC][68] = 60, + [0][1][2][0][RTW89_FCC][70] = 60, + [0][1][2][0][RTW89_FCC][72] = 60, + [0][1][2][0][RTW89_FCC][74] = 60, + [0][1][2][0][RTW89_FCC][75] = 60, + [0][1][2][0][RTW89_FCC][77] = 60, + [0][1][2][0][RTW89_FCC][79] = 60, + [0][1][2][0][RTW89_FCC][81] = 60, + [0][1][2][0][RTW89_FCC][83] = 60, + [0][1][2][0][RTW89_FCC][85] = 60, + [0][1][2][0][RTW89_FCC][87] = 60, + [0][1][2][0][RTW89_FCC][89] = 60, + [0][1][2][0][RTW89_FCC][90] = 60, + [0][1][2][0][RTW89_FCC][92] = 60, + [0][1][2][0][RTW89_FCC][94] = 60, + [0][1][2][0][RTW89_FCC][96] = 60, + [0][1][2][0][RTW89_FCC][98] = 60, + [0][1][2][0][RTW89_FCC][100] = 60, + [0][1][2][0][RTW89_FCC][102] = 60, + [0][1][2][0][RTW89_FCC][104] = 60, + [0][1][2][0][RTW89_FCC][105] = 60, + [0][1][2][0][RTW89_FCC][107] = 60, + [0][1][2][0][RTW89_FCC][109] = 60, + [0][1][2][0][RTW89_FCC][111] = 127, + [0][1][2][0][RTW89_FCC][113] = 127, + [0][1][2][0][RTW89_FCC][115] = 127, + [0][1][2][0][RTW89_FCC][117] = 127, + [0][1][2][0][RTW89_FCC][119] = 127, + [0][1][2][1][RTW89_FCC][0] = 48, + [0][1][2][1][RTW89_FCC][2] = 48, + [0][1][2][1][RTW89_FCC][4] = 48, + [0][1][2][1][RTW89_FCC][6] = 48, + [0][1][2][1][RTW89_FCC][8] = 48, + [0][1][2][1][RTW89_FCC][10] = 48, + [0][1][2][1][RTW89_FCC][12] = 48, + [0][1][2][1][RTW89_FCC][14] = 48, + [0][1][2][1][RTW89_FCC][15] = 48, + [0][1][2][1][RTW89_FCC][17] = 48, + [0][1][2][1][RTW89_FCC][19] = 48, + [0][1][2][1][RTW89_FCC][21] = 48, + [0][1][2][1][RTW89_FCC][23] = 48, + [0][1][2][1][RTW89_FCC][25] = 48, + [0][1][2][1][RTW89_FCC][27] = 48, + [0][1][2][1][RTW89_FCC][29] = 48, + [0][1][2][1][RTW89_FCC][30] = 48, + [0][1][2][1][RTW89_FCC][32] = 48, + [0][1][2][1][RTW89_FCC][34] = 48, + [0][1][2][1][RTW89_FCC][36] = 48, + [0][1][2][1][RTW89_FCC][38] = 48, + [0][1][2][1][RTW89_FCC][40] = 48, + [0][1][2][1][RTW89_FCC][42] = 48, + [0][1][2][1][RTW89_FCC][44] = 48, + [0][1][2][1][RTW89_FCC][45] = 48, + [0][1][2][1][RTW89_FCC][47] = 48, + [0][1][2][1][RTW89_FCC][49] = 48, + [0][1][2][1][RTW89_FCC][51] = 48, + [0][1][2][1][RTW89_FCC][53] = 48, + [0][1][2][1][RTW89_FCC][55] = 48, + [0][1][2][1][RTW89_FCC][57] = 48, + [0][1][2][1][RTW89_FCC][59] = 48, + [0][1][2][1][RTW89_FCC][60] = 48, + [0][1][2][1][RTW89_FCC][62] = 48, + [0][1][2][1][RTW89_FCC][64] = 48, + [0][1][2][1][RTW89_FCC][66] = 48, + [0][1][2][1][RTW89_FCC][68] = 48, + [0][1][2][1][RTW89_FCC][70] = 48, + [0][1][2][1][RTW89_FCC][72] = 48, + [0][1][2][1][RTW89_FCC][74] = 48, + [0][1][2][1][RTW89_FCC][75] = 48, + [0][1][2][1][RTW89_FCC][77] = 48, + [0][1][2][1][RTW89_FCC][79] = 48, + [0][1][2][1][RTW89_FCC][81] = 48, + [0][1][2][1][RTW89_FCC][83] = 48, + [0][1][2][1][RTW89_FCC][85] = 48, + [0][1][2][1][RTW89_FCC][87] = 48, + [0][1][2][1][RTW89_FCC][89] = 48, + [0][1][2][1][RTW89_FCC][90] = 48, + [0][1][2][1][RTW89_FCC][92] = 48, + [0][1][2][1][RTW89_FCC][94] = 48, + [0][1][2][1][RTW89_FCC][96] = 48, + [0][1][2][1][RTW89_FCC][98] = 48, + [0][1][2][1][RTW89_FCC][100] = 48, + [0][1][2][1][RTW89_FCC][102] = 48, + [0][1][2][1][RTW89_FCC][104] = 48, + [0][1][2][1][RTW89_FCC][105] = 48, + [0][1][2][1][RTW89_FCC][107] = 48, + [0][1][2][1][RTW89_FCC][109] = 48, + [0][1][2][1][RTW89_FCC][111] = 127, + [0][1][2][1][RTW89_FCC][113] = 127, + [0][1][2][1][RTW89_FCC][115] = 127, + [0][1][2][1][RTW89_FCC][117] = 127, + [0][1][2][1][RTW89_FCC][119] = 127, + [1][0][2][0][RTW89_FCC][1] = 72, + [1][0][2][0][RTW89_FCC][5] = 72, + [1][0][2][0][RTW89_FCC][9] = 72, + [1][0][2][0][RTW89_FCC][13] = 72, + [1][0][2][0][RTW89_FCC][16] = 72, + [1][0][2][0][RTW89_FCC][20] = 72, + [1][0][2][0][RTW89_FCC][24] = 72, + [1][0][2][0][RTW89_FCC][28] = 72, + [1][0][2][0][RTW89_FCC][31] = 72, + [1][0][2][0][RTW89_FCC][35] = 72, + [1][0][2][0][RTW89_FCC][39] = 72, + [1][0][2][0][RTW89_FCC][43] = 72, + [1][0][2][0][RTW89_FCC][46] = 72, + [1][0][2][0][RTW89_FCC][50] = 72, + [1][0][2][0][RTW89_FCC][54] = 72, + [1][0][2][0][RTW89_FCC][58] = 72, + [1][0][2][0][RTW89_FCC][61] = 72, + [1][0][2][0][RTW89_FCC][65] = 72, + [1][0][2][0][RTW89_FCC][69] = 72, + [1][0][2][0][RTW89_FCC][73] = 72, + [1][0][2][0][RTW89_FCC][76] = 72, + [1][0][2][0][RTW89_FCC][80] = 72, + [1][0][2][0][RTW89_FCC][84] = 72, + [1][0][2][0][RTW89_FCC][88] = 72, + [1][0][2][0][RTW89_FCC][91] = 72, + [1][0][2][0][RTW89_FCC][95] = 72, + [1][0][2][0][RTW89_FCC][99] = 72, + [1][0][2][0][RTW89_FCC][103] = 72, + [1][0][2][0][RTW89_FCC][106] = 72, + [1][0][2][0][RTW89_FCC][110] = 127, + [1][0][2][0][RTW89_FCC][114] = 127, + [1][0][2][0][RTW89_FCC][118] = 127, + [1][1][2][0][RTW89_FCC][1] = 60, + [1][1][2][0][RTW89_FCC][5] = 60, + [1][1][2][0][RTW89_FCC][9] = 60, + [1][1][2][0][RTW89_FCC][13] = 60, + [1][1][2][0][RTW89_FCC][16] = 60, + [1][1][2][0][RTW89_FCC][20] = 60, + [1][1][2][0][RTW89_FCC][24] = 60, + [1][1][2][0][RTW89_FCC][28] = 60, + [1][1][2][0][RTW89_FCC][31] = 60, + [1][1][2][0][RTW89_FCC][35] = 60, + [1][1][2][0][RTW89_FCC][39] = 60, + [1][1][2][0][RTW89_FCC][43] = 60, + [1][1][2][0][RTW89_FCC][46] = 60, + [1][1][2][0][RTW89_FCC][50] = 60, + [1][1][2][0][RTW89_FCC][54] = 60, + [1][1][2][0][RTW89_FCC][58] = 60, + [1][1][2][0][RTW89_FCC][61] = 60, + [1][1][2][0][RTW89_FCC][65] = 60, + [1][1][2][0][RTW89_FCC][69] = 60, + [1][1][2][0][RTW89_FCC][73] = 60, + [1][1][2][0][RTW89_FCC][76] = 60, + [1][1][2][0][RTW89_FCC][80] = 60, + [1][1][2][0][RTW89_FCC][84] = 60, + [1][1][2][0][RTW89_FCC][88] = 60, + [1][1][2][0][RTW89_FCC][91] = 60, + [1][1][2][0][RTW89_FCC][95] = 60, + [1][1][2][0][RTW89_FCC][99] = 60, + [1][1][2][0][RTW89_FCC][103] = 60, + [1][1][2][0][RTW89_FCC][106] = 60, + [1][1][2][0][RTW89_FCC][110] = 127, + [1][1][2][0][RTW89_FCC][114] = 127, + [1][1][2][0][RTW89_FCC][118] = 127, + [1][1][2][1][RTW89_FCC][1] = 48, + [1][1][2][1][RTW89_FCC][5] = 48, + [1][1][2][1][RTW89_FCC][9] = 48, + [1][1][2][1][RTW89_FCC][13] = 48, + [1][1][2][1][RTW89_FCC][16] = 48, + [1][1][2][1][RTW89_FCC][20] = 48, + [1][1][2][1][RTW89_FCC][24] = 48, + [1][1][2][1][RTW89_FCC][28] = 48, + [1][1][2][1][RTW89_FCC][31] = 48, + [1][1][2][1][RTW89_FCC][35] = 48, + [1][1][2][1][RTW89_FCC][39] = 48, + [1][1][2][1][RTW89_FCC][43] = 48, + [1][1][2][1][RTW89_FCC][46] = 48, + [1][1][2][1][RTW89_FCC][50] = 48, + [1][1][2][1][RTW89_FCC][54] = 48, + [1][1][2][1][RTW89_FCC][58] = 48, + [1][1][2][1][RTW89_FCC][61] = 48, + [1][1][2][1][RTW89_FCC][65] = 48, + [1][1][2][1][RTW89_FCC][69] = 48, + [1][1][2][1][RTW89_FCC][73] = 48, + [1][1][2][1][RTW89_FCC][76] = 48, + [1][1][2][1][RTW89_FCC][80] = 48, + [1][1][2][1][RTW89_FCC][84] = 48, + [1][1][2][1][RTW89_FCC][88] = 48, + [1][1][2][1][RTW89_FCC][91] = 48, + [1][1][2][1][RTW89_FCC][95] = 48, + [1][1][2][1][RTW89_FCC][99] = 48, + [1][1][2][1][RTW89_FCC][103] = 48, + [1][1][2][1][RTW89_FCC][106] = 48, + [1][1][2][1][RTW89_FCC][110] = 127, + [1][1][2][1][RTW89_FCC][114] = 127, + [1][1][2][1][RTW89_FCC][118] = 127, + [2][0][2][0][RTW89_FCC][3] = 64, + [2][0][2][0][RTW89_FCC][11] = 64, + [2][0][2][0][RTW89_FCC][18] = 64, + [2][0][2][0][RTW89_FCC][26] = 64, + [2][0][2][0][RTW89_FCC][33] = 64, + [2][0][2][0][RTW89_FCC][41] = 64, + [2][0][2][0][RTW89_FCC][48] = 64, + [2][0][2][0][RTW89_FCC][56] = 64, + [2][0][2][0][RTW89_FCC][63] = 64, + [2][0][2][0][RTW89_FCC][71] = 64, + [2][0][2][0][RTW89_FCC][78] = 64, + [2][0][2][0][RTW89_FCC][86] = 64, + [2][0][2][0][RTW89_FCC][93] = 64, + [2][0][2][0][RTW89_FCC][101] = 64, + [2][0][2][0][RTW89_FCC][108] = 127, + [2][0][2][0][RTW89_FCC][116] = 127, + [2][1][2][0][RTW89_FCC][3] = 52, + [2][1][2][0][RTW89_FCC][11] = 52, + [2][1][2][0][RTW89_FCC][18] = 52, + [2][1][2][0][RTW89_FCC][26] = 52, + [2][1][2][0][RTW89_FCC][33] = 52, + [2][1][2][0][RTW89_FCC][41] = 52, + [2][1][2][0][RTW89_FCC][48] = 52, + [2][1][2][0][RTW89_FCC][56] = 52, + [2][1][2][0][RTW89_FCC][63] = 52, + [2][1][2][0][RTW89_FCC][71] = 52, + [2][1][2][0][RTW89_FCC][78] = 52, + [2][1][2][0][RTW89_FCC][86] = 52, + [2][1][2][0][RTW89_FCC][93] = 52, + [2][1][2][0][RTW89_FCC][101] = 52, + [2][1][2][0][RTW89_FCC][108] = 127, + [2][1][2][0][RTW89_FCC][116] = 127, + [2][1][2][1][RTW89_FCC][3] = 40, + [2][1][2][1][RTW89_FCC][11] = 40, + [2][1][2][1][RTW89_FCC][18] = 40, + [2][1][2][1][RTW89_FCC][26] = 40, + [2][1][2][1][RTW89_FCC][33] = 40, + [2][1][2][1][RTW89_FCC][41] = 40, + [2][1][2][1][RTW89_FCC][48] = 40, + [2][1][2][1][RTW89_FCC][56] = 40, + [2][1][2][1][RTW89_FCC][63] = 40, + [2][1][2][1][RTW89_FCC][71] = 40, + [2][1][2][1][RTW89_FCC][78] = 40, + [2][1][2][1][RTW89_FCC][86] = 40, + [2][1][2][1][RTW89_FCC][93] = 40, + [2][1][2][1][RTW89_FCC][101] = 40, + [2][1][2][1][RTW89_FCC][108] = 127, + [2][1][2][1][RTW89_FCC][116] = 127, + [3][0][2][0][RTW89_FCC][7] = 56, + [3][0][2][0][RTW89_FCC][22] = 56, + [3][0][2][0][RTW89_FCC][37] = 56, + [3][0][2][0][RTW89_FCC][52] = 56, + [3][0][2][0][RTW89_FCC][67] = 56, + [3][0][2][0][RTW89_FCC][82] = 56, + [3][0][2][0][RTW89_FCC][97] = 56, + [3][0][2][0][RTW89_FCC][112] = 127, + [3][1][2][0][RTW89_FCC][7] = 44, + [3][1][2][0][RTW89_FCC][22] = 44, + [3][1][2][0][RTW89_FCC][37] = 44, + [3][1][2][0][RTW89_FCC][52] = 44, + [3][1][2][0][RTW89_FCC][67] = 44, + [3][1][2][0][RTW89_FCC][82] = 44, + [3][1][2][0][RTW89_FCC][97] = 44, + [3][1][2][0][RTW89_FCC][112] = 127, + [3][1][2][1][RTW89_FCC][7] = 32, + [3][1][2][1][RTW89_FCC][22] = 32, + [3][1][2][1][RTW89_FCC][37] = 32, + [3][1][2][1][RTW89_FCC][52] = 32, + [3][1][2][1][RTW89_FCC][67] = 32, + [3][1][2][1][RTW89_FCC][82] = 32, + [3][1][2][1][RTW89_FCC][97] = 32, + [3][1][2][1][RTW89_FCC][112] = 127, +}; + +const s8 rtw89_8852c_txpwr_lmt_ru_2g[RTW89_RU_NUM][RTW89_NTX_NUM] + [RTW89_REGD_NUM][RTW89_2G_CH_NUM] = { + [0][0][RTW89_WW][0] = 32, + [0][0][RTW89_WW][1] = 32, + [0][0][RTW89_WW][2] = 32, + [0][0][RTW89_WW][3] = 32, + [0][0][RTW89_WW][4] = 32, + [0][0][RTW89_WW][5] = 32, + [0][0][RTW89_WW][6] = 32, + [0][0][RTW89_WW][7] = 32, + [0][0][RTW89_WW][8] = 32, + [0][0][RTW89_WW][9] = 32, + [0][0][RTW89_WW][10] = 32, + [0][0][RTW89_WW][11] = 32, + [0][0][RTW89_WW][12] = 32, + [0][0][RTW89_WW][13] = 0, + [0][1][RTW89_WW][0] = 20, + [0][1][RTW89_WW][1] = 22, + [0][1][RTW89_WW][2] = 22, + [0][1][RTW89_WW][3] = 22, + [0][1][RTW89_WW][4] = 22, + [0][1][RTW89_WW][5] = 22, + [0][1][RTW89_WW][6] = 22, + [0][1][RTW89_WW][7] = 22, + [0][1][RTW89_WW][8] = 22, + [0][1][RTW89_WW][9] = 22, + [0][1][RTW89_WW][10] = 22, + [0][1][RTW89_WW][11] = 22, + [0][1][RTW89_WW][12] = 20, + [0][1][RTW89_WW][13] = 0, + [1][0][RTW89_WW][0] = 42, + [1][0][RTW89_WW][1] = 44, + [1][0][RTW89_WW][2] = 44, + [1][0][RTW89_WW][3] = 44, + [1][0][RTW89_WW][4] = 44, + [1][0][RTW89_WW][5] = 44, + [1][0][RTW89_WW][6] = 44, + [1][0][RTW89_WW][7] = 44, + [1][0][RTW89_WW][8] = 44, + [1][0][RTW89_WW][9] = 44, + [1][0][RTW89_WW][10] = 44, + [1][0][RTW89_WW][11] = 44, + [1][0][RTW89_WW][12] = 38, + [1][0][RTW89_WW][13] = 0, + [1][1][RTW89_WW][0] = 32, + [1][1][RTW89_WW][1] = 32, + [1][1][RTW89_WW][2] = 32, + [1][1][RTW89_WW][3] = 32, + [1][1][RTW89_WW][4] = 32, + [1][1][RTW89_WW][5] = 32, + [1][1][RTW89_WW][6] = 32, + [1][1][RTW89_WW][7] = 32, + [1][1][RTW89_WW][8] = 32, + [1][1][RTW89_WW][9] = 32, + [1][1][RTW89_WW][10] = 32, + [1][1][RTW89_WW][11] = 32, + [1][1][RTW89_WW][12] = 32, + [1][1][RTW89_WW][13] = 0, + [2][0][RTW89_WW][0] = 56, + [2][0][RTW89_WW][1] = 56, + [2][0][RTW89_WW][2] = 56, + [2][0][RTW89_WW][3] = 56, + [2][0][RTW89_WW][4] = 56, + [2][0][RTW89_WW][5] = 56, + [2][0][RTW89_WW][6] = 56, + [2][0][RTW89_WW][7] = 56, + [2][0][RTW89_WW][8] = 56, + [2][0][RTW89_WW][9] = 56, + [2][0][RTW89_WW][10] = 56, + [2][0][RTW89_WW][11] = 56, + [2][0][RTW89_WW][12] = 56, + [2][0][RTW89_WW][13] = 0, + [2][1][RTW89_WW][0] = 44, + [2][1][RTW89_WW][1] = 44, + [2][1][RTW89_WW][2] = 44, + [2][1][RTW89_WW][3] = 44, + [2][1][RTW89_WW][4] = 44, + [2][1][RTW89_WW][5] = 44, + [2][1][RTW89_WW][6] = 44, + [2][1][RTW89_WW][7] = 44, + [2][1][RTW89_WW][8] = 44, + [2][1][RTW89_WW][9] = 44, + [2][1][RTW89_WW][10] = 44, + [2][1][RTW89_WW][11] = 44, + [2][1][RTW89_WW][12] = 42, + [2][1][RTW89_WW][13] = 0, + [0][0][RTW89_FCC][0] = 68, + [0][0][RTW89_ETSI][0] = 36, + [0][0][RTW89_MKK][0] = 38, + [0][0][RTW89_IC][0] = 68, + [0][0][RTW89_ACMA][0] = 32, + [0][0][RTW89_FCC][1] = 68, + [0][0][RTW89_ETSI][1] = 40, + [0][0][RTW89_MKK][1] = 44, + [0][0][RTW89_IC][1] = 68, + [0][0][RTW89_ACMA][1] = 32, + [0][0][RTW89_FCC][2] = 72, + [0][0][RTW89_ETSI][2] = 40, + [0][0][RTW89_MKK][2] = 44, + [0][0][RTW89_IC][2] = 72, + [0][0][RTW89_ACMA][2] = 32, + [0][0][RTW89_FCC][3] = 76, + [0][0][RTW89_ETSI][3] = 40, + [0][0][RTW89_MKK][3] = 44, + [0][0][RTW89_IC][3] = 76, + [0][0][RTW89_ACMA][3] = 32, + [0][0][RTW89_FCC][4] = 76, + [0][0][RTW89_ETSI][4] = 40, + [0][0][RTW89_MKK][4] = 44, + [0][0][RTW89_IC][4] = 76, + [0][0][RTW89_ACMA][4] = 32, + [0][0][RTW89_FCC][5] = 84, + [0][0][RTW89_ETSI][5] = 40, + [0][0][RTW89_MKK][5] = 44, + [0][0][RTW89_IC][5] = 84, + [0][0][RTW89_ACMA][5] = 32, + [0][0][RTW89_FCC][6] = 74, + [0][0][RTW89_ETSI][6] = 40, + [0][0][RTW89_MKK][6] = 44, + [0][0][RTW89_IC][6] = 74, + [0][0][RTW89_ACMA][6] = 32, + [0][0][RTW89_FCC][7] = 74, + [0][0][RTW89_ETSI][7] = 40, + [0][0][RTW89_MKK][7] = 44, + [0][0][RTW89_IC][7] = 74, + [0][0][RTW89_ACMA][7] = 32, + [0][0][RTW89_FCC][8] = 70, + [0][0][RTW89_ETSI][8] = 40, + [0][0][RTW89_MKK][8] = 44, + [0][0][RTW89_IC][8] = 70, + [0][0][RTW89_ACMA][8] = 32, + [0][0][RTW89_FCC][9] = 66, + [0][0][RTW89_ETSI][9] = 40, + [0][0][RTW89_MKK][9] = 44, + [0][0][RTW89_IC][9] = 66, + [0][0][RTW89_ACMA][9] = 32, + [0][0][RTW89_FCC][10] = 66, + [0][0][RTW89_ETSI][10] = 40, + [0][0][RTW89_MKK][10] = 44, + [0][0][RTW89_IC][10] = 66, + [0][0][RTW89_ACMA][10] = 32, + [0][0][RTW89_FCC][11] = 56, + [0][0][RTW89_ETSI][11] = 40, + [0][0][RTW89_MKK][11] = 44, + [0][0][RTW89_IC][11] = 56, + [0][0][RTW89_ACMA][11] = 32, + [0][0][RTW89_FCC][12] = 32, + [0][0][RTW89_ETSI][12] = 36, + [0][0][RTW89_MKK][12] = 38, + [0][0][RTW89_IC][12] = 32, + [0][0][RTW89_ACMA][12] = 32, + [0][0][RTW89_FCC][13] = 127, + [0][0][RTW89_ETSI][13] = 127, + [0][0][RTW89_MKK][13] = 127, + [0][0][RTW89_IC][13] = 127, + [0][0][RTW89_ACMA][13] = 127, + [0][1][RTW89_FCC][0] = 62, + [0][1][RTW89_ETSI][0] = 24, + [0][1][RTW89_MKK][0] = 26, + [0][1][RTW89_IC][0] = 62, + [0][1][RTW89_ACMA][0] = 20, + [0][1][RTW89_FCC][1] = 62, + [0][1][RTW89_ETSI][1] = 26, + [0][1][RTW89_MKK][1] = 32, + [0][1][RTW89_IC][1] = 62, + [0][1][RTW89_ACMA][1] = 22, + [0][1][RTW89_FCC][2] = 66, + [0][1][RTW89_ETSI][2] = 26, + [0][1][RTW89_MKK][2] = 32, + [0][1][RTW89_IC][2] = 66, + [0][1][RTW89_ACMA][2] = 22, + [0][1][RTW89_FCC][3] = 70, + [0][1][RTW89_ETSI][3] = 26, + [0][1][RTW89_MKK][3] = 32, + [0][1][RTW89_IC][3] = 70, + [0][1][RTW89_ACMA][3] = 22, + [0][1][RTW89_FCC][4] = 74, + [0][1][RTW89_ETSI][4] = 26, + [0][1][RTW89_MKK][4] = 32, + [0][1][RTW89_IC][4] = 74, + [0][1][RTW89_ACMA][4] = 22, + [0][1][RTW89_FCC][5] = 74, + [0][1][RTW89_ETSI][5] = 26, + [0][1][RTW89_MKK][5] = 32, + [0][1][RTW89_IC][5] = 74, + [0][1][RTW89_ACMA][5] = 22, + [0][1][RTW89_FCC][6] = 72, + [0][1][RTW89_ETSI][6] = 26, + [0][1][RTW89_MKK][6] = 32, + [0][1][RTW89_IC][6] = 72, + [0][1][RTW89_ACMA][6] = 22, + [0][1][RTW89_FCC][7] = 68, + [0][1][RTW89_ETSI][7] = 26, + [0][1][RTW89_MKK][7] = 32, + [0][1][RTW89_IC][7] = 68, + [0][1][RTW89_ACMA][7] = 22, + [0][1][RTW89_FCC][8] = 64, + [0][1][RTW89_ETSI][8] = 26, + [0][1][RTW89_MKK][8] = 32, + [0][1][RTW89_IC][8] = 64, + [0][1][RTW89_ACMA][8] = 22, + [0][1][RTW89_FCC][9] = 60, + [0][1][RTW89_ETSI][9] = 26, + [0][1][RTW89_MKK][9] = 32, + [0][1][RTW89_IC][9] = 60, + [0][1][RTW89_ACMA][9] = 22, + [0][1][RTW89_FCC][10] = 60, + [0][1][RTW89_ETSI][10] = 26, + [0][1][RTW89_MKK][10] = 32, + [0][1][RTW89_IC][10] = 60, + [0][1][RTW89_ACMA][10] = 22, + [0][1][RTW89_FCC][11] = 52, + [0][1][RTW89_ETSI][11] = 26, + [0][1][RTW89_MKK][11] = 32, + [0][1][RTW89_IC][11] = 52, + [0][1][RTW89_ACMA][11] = 22, + [0][1][RTW89_FCC][12] = 30, + [0][1][RTW89_ETSI][12] = 22, + [0][1][RTW89_MKK][12] = 26, + [0][1][RTW89_IC][12] = 30, + [0][1][RTW89_ACMA][12] = 20, + [0][1][RTW89_FCC][13] = 127, + [0][1][RTW89_ETSI][13] = 127, + [0][1][RTW89_MKK][13] = 127, + [0][1][RTW89_IC][13] = 127, + [0][1][RTW89_ACMA][13] = 127, + [1][0][RTW89_FCC][0] = 78, + [1][0][RTW89_ETSI][0] = 48, + [1][0][RTW89_MKK][0] = 48, + [1][0][RTW89_IC][0] = 78, + [1][0][RTW89_ACMA][0] = 42, + [1][0][RTW89_FCC][1] = 78, + [1][0][RTW89_ETSI][1] = 48, + [1][0][RTW89_MKK][1] = 48, + [1][0][RTW89_IC][1] = 78, + [1][0][RTW89_ACMA][1] = 44, + [1][0][RTW89_FCC][2] = 82, + [1][0][RTW89_ETSI][2] = 48, + [1][0][RTW89_MKK][2] = 48, + [1][0][RTW89_IC][2] = 82, + [1][0][RTW89_ACMA][2] = 44, + [1][0][RTW89_FCC][3] = 84, + [1][0][RTW89_ETSI][3] = 48, + [1][0][RTW89_MKK][3] = 48, + [1][0][RTW89_IC][3] = 84, + [1][0][RTW89_ACMA][3] = 44, + [1][0][RTW89_FCC][4] = 84, + [1][0][RTW89_ETSI][4] = 48, + [1][0][RTW89_MKK][4] = 48, + [1][0][RTW89_IC][4] = 84, + [1][0][RTW89_ACMA][4] = 44, + [1][0][RTW89_FCC][5] = 84, + [1][0][RTW89_ETSI][5] = 48, + [1][0][RTW89_MKK][5] = 48, + [1][0][RTW89_IC][5] = 84, + [1][0][RTW89_ACMA][5] = 44, + [1][0][RTW89_FCC][6] = 78, + [1][0][RTW89_ETSI][6] = 46, + [1][0][RTW89_MKK][6] = 48, + [1][0][RTW89_IC][6] = 78, + [1][0][RTW89_ACMA][6] = 44, + [1][0][RTW89_FCC][7] = 78, + [1][0][RTW89_ETSI][7] = 48, + [1][0][RTW89_MKK][7] = 48, + [1][0][RTW89_IC][7] = 78, + [1][0][RTW89_ACMA][7] = 44, + [1][0][RTW89_FCC][8] = 78, + [1][0][RTW89_ETSI][8] = 48, + [1][0][RTW89_MKK][8] = 48, + [1][0][RTW89_IC][8] = 78, + [1][0][RTW89_ACMA][8] = 44, + [1][0][RTW89_FCC][9] = 74, + [1][0][RTW89_ETSI][9] = 48, + [1][0][RTW89_MKK][9] = 48, + [1][0][RTW89_IC][9] = 74, + [1][0][RTW89_ACMA][9] = 44, + [1][0][RTW89_FCC][10] = 74, + [1][0][RTW89_ETSI][10] = 48, + [1][0][RTW89_MKK][10] = 48, + [1][0][RTW89_IC][10] = 74, + [1][0][RTW89_ACMA][10] = 44, + [1][0][RTW89_FCC][11] = 72, + [1][0][RTW89_ETSI][11] = 48, + [1][0][RTW89_MKK][11] = 48, + [1][0][RTW89_IC][11] = 72, + [1][0][RTW89_ACMA][11] = 44, + [1][0][RTW89_FCC][12] = 38, + [1][0][RTW89_ETSI][12] = 48, + [1][0][RTW89_MKK][12] = 48, + [1][0][RTW89_IC][12] = 38, + [1][0][RTW89_ACMA][12] = 42, + [1][0][RTW89_FCC][13] = 127, + [1][0][RTW89_ETSI][13] = 127, + [1][0][RTW89_MKK][13] = 127, + [1][0][RTW89_IC][13] = 127, + [1][0][RTW89_ACMA][13] = 127, + [1][1][RTW89_FCC][0] = 66, + [1][1][RTW89_ETSI][0] = 34, + [1][1][RTW89_MKK][0] = 36, + [1][1][RTW89_IC][0] = 66, + [1][1][RTW89_ACMA][0] = 32, + [1][1][RTW89_FCC][1] = 66, + [1][1][RTW89_ETSI][1] = 36, + [1][1][RTW89_MKK][1] = 36, + [1][1][RTW89_IC][1] = 66, + [1][1][RTW89_ACMA][1] = 32, + [1][1][RTW89_FCC][2] = 70, + [1][1][RTW89_ETSI][2] = 36, + [1][1][RTW89_MKK][2] = 36, + [1][1][RTW89_IC][2] = 70, + [1][1][RTW89_ACMA][2] = 32, + [1][1][RTW89_FCC][3] = 74, + [1][1][RTW89_ETSI][3] = 36, + [1][1][RTW89_MKK][3] = 36, + [1][1][RTW89_IC][3] = 74, + [1][1][RTW89_ACMA][3] = 32, + [1][1][RTW89_FCC][4] = 74, + [1][1][RTW89_ETSI][4] = 36, + [1][1][RTW89_MKK][4] = 36, + [1][1][RTW89_IC][4] = 74, + [1][1][RTW89_ACMA][4] = 32, + [1][1][RTW89_FCC][5] = 74, + [1][1][RTW89_ETSI][5] = 36, + [1][1][RTW89_MKK][5] = 36, + [1][1][RTW89_IC][5] = 74, + [1][1][RTW89_ACMA][5] = 32, + [1][1][RTW89_FCC][6] = 74, + [1][1][RTW89_ETSI][6] = 36, + [1][1][RTW89_MKK][6] = 36, + [1][1][RTW89_IC][6] = 74, + [1][1][RTW89_ACMA][6] = 32, + [1][1][RTW89_FCC][7] = 74, + [1][1][RTW89_ETSI][7] = 36, + [1][1][RTW89_MKK][7] = 36, + [1][1][RTW89_IC][7] = 74, + [1][1][RTW89_ACMA][7] = 32, + [1][1][RTW89_FCC][8] = 70, + [1][1][RTW89_ETSI][8] = 36, + [1][1][RTW89_MKK][8] = 36, + [1][1][RTW89_IC][8] = 70, + [1][1][RTW89_ACMA][8] = 32, + [1][1][RTW89_FCC][9] = 66, + [1][1][RTW89_ETSI][9] = 36, + [1][1][RTW89_MKK][9] = 36, + [1][1][RTW89_IC][9] = 66, + [1][1][RTW89_ACMA][9] = 32, + [1][1][RTW89_FCC][10] = 66, + [1][1][RTW89_ETSI][10] = 36, + [1][1][RTW89_MKK][10] = 36, + [1][1][RTW89_IC][10] = 66, + [1][1][RTW89_ACMA][10] = 32, + [1][1][RTW89_FCC][11] = 48, + [1][1][RTW89_ETSI][11] = 36, + [1][1][RTW89_MKK][11] = 36, + [1][1][RTW89_IC][11] = 48, + [1][1][RTW89_ACMA][11] = 32, + [1][1][RTW89_FCC][12] = 32, + [1][1][RTW89_ETSI][12] = 36, + [1][1][RTW89_MKK][12] = 36, + [1][1][RTW89_IC][12] = 32, + [1][1][RTW89_ACMA][12] = 32, + [1][1][RTW89_FCC][13] = 127, + [1][1][RTW89_ETSI][13] = 127, + [1][1][RTW89_MKK][13] = 127, + [1][1][RTW89_IC][13] = 127, + [1][1][RTW89_ACMA][13] = 127, + [2][0][RTW89_FCC][0] = 78, + [2][0][RTW89_ETSI][0] = 60, + [2][0][RTW89_MKK][0] = 60, + [2][0][RTW89_IC][0] = 78, + [2][0][RTW89_ACMA][0] = 56, + [2][0][RTW89_FCC][1] = 78, + [2][0][RTW89_ETSI][1] = 60, + [2][0][RTW89_MKK][1] = 60, + [2][0][RTW89_IC][1] = 78, + [2][0][RTW89_ACMA][1] = 56, + [2][0][RTW89_FCC][2] = 80, + [2][0][RTW89_ETSI][2] = 60, + [2][0][RTW89_MKK][2] = 60, + [2][0][RTW89_IC][2] = 80, + [2][0][RTW89_ACMA][2] = 56, + [2][0][RTW89_FCC][3] = 80, + [2][0][RTW89_ETSI][3] = 60, + [2][0][RTW89_MKK][3] = 60, + [2][0][RTW89_IC][3] = 80, + [2][0][RTW89_ACMA][3] = 56, + [2][0][RTW89_FCC][4] = 80, + [2][0][RTW89_ETSI][4] = 60, + [2][0][RTW89_MKK][4] = 60, + [2][0][RTW89_IC][4] = 80, + [2][0][RTW89_ACMA][4] = 56, + [2][0][RTW89_FCC][5] = 84, + [2][0][RTW89_ETSI][5] = 60, + [2][0][RTW89_MKK][5] = 60, + [2][0][RTW89_IC][5] = 84, + [2][0][RTW89_ACMA][5] = 56, + [2][0][RTW89_FCC][6] = 76, + [2][0][RTW89_ETSI][6] = 58, + [2][0][RTW89_MKK][6] = 60, + [2][0][RTW89_IC][6] = 76, + [2][0][RTW89_ACMA][6] = 56, + [2][0][RTW89_FCC][7] = 76, + [2][0][RTW89_ETSI][7] = 60, + [2][0][RTW89_MKK][7] = 60, + [2][0][RTW89_IC][7] = 76, + [2][0][RTW89_ACMA][7] = 56, + [2][0][RTW89_FCC][8] = 76, + [2][0][RTW89_ETSI][8] = 60, + [2][0][RTW89_MKK][8] = 60, + [2][0][RTW89_IC][8] = 76, + [2][0][RTW89_ACMA][8] = 56, + [2][0][RTW89_FCC][9] = 74, + [2][0][RTW89_ETSI][9] = 60, + [2][0][RTW89_MKK][9] = 60, + [2][0][RTW89_IC][9] = 74, + [2][0][RTW89_ACMA][9] = 56, + [2][0][RTW89_FCC][10] = 74, + [2][0][RTW89_ETSI][10] = 60, + [2][0][RTW89_MKK][10] = 60, + [2][0][RTW89_IC][10] = 74, + [2][0][RTW89_ACMA][10] = 56, + [2][0][RTW89_FCC][11] = 66, + [2][0][RTW89_ETSI][11] = 60, + [2][0][RTW89_MKK][11] = 60, + [2][0][RTW89_IC][11] = 66, + [2][0][RTW89_ACMA][11] = 56, + [2][0][RTW89_FCC][12] = 56, + [2][0][RTW89_ETSI][12] = 60, + [2][0][RTW89_MKK][12] = 60, + [2][0][RTW89_IC][12] = 56, + [2][0][RTW89_ACMA][12] = 56, + [2][0][RTW89_FCC][13] = 127, + [2][0][RTW89_ETSI][13] = 127, + [2][0][RTW89_MKK][13] = 127, + [2][0][RTW89_IC][13] = 127, + [2][0][RTW89_ACMA][13] = 127, + [2][1][RTW89_FCC][0] = 70, + [2][1][RTW89_ETSI][0] = 48, + [2][1][RTW89_MKK][0] = 48, + [2][1][RTW89_IC][0] = 70, + [2][1][RTW89_ACMA][0] = 44, + [2][1][RTW89_FCC][1] = 70, + [2][1][RTW89_ETSI][1] = 48, + [2][1][RTW89_MKK][1] = 48, + [2][1][RTW89_IC][1] = 70, + [2][1][RTW89_ACMA][1] = 44, + [2][1][RTW89_FCC][2] = 74, + [2][1][RTW89_ETSI][2] = 48, + [2][1][RTW89_MKK][2] = 48, + [2][1][RTW89_IC][2] = 74, + [2][1][RTW89_ACMA][2] = 44, + [2][1][RTW89_FCC][3] = 78, + [2][1][RTW89_ETSI][3] = 48, + [2][1][RTW89_MKK][3] = 48, + [2][1][RTW89_IC][3] = 78, + [2][1][RTW89_ACMA][3] = 44, + [2][1][RTW89_FCC][4] = 80, + [2][1][RTW89_ETSI][4] = 48, + [2][1][RTW89_MKK][4] = 48, + [2][1][RTW89_IC][4] = 80, + [2][1][RTW89_ACMA][4] = 44, + [2][1][RTW89_FCC][5] = 80, + [2][1][RTW89_ETSI][5] = 48, + [2][1][RTW89_MKK][5] = 48, + [2][1][RTW89_IC][5] = 80, + [2][1][RTW89_ACMA][5] = 44, + [2][1][RTW89_FCC][6] = 78, + [2][1][RTW89_ETSI][6] = 46, + [2][1][RTW89_MKK][6] = 48, + [2][1][RTW89_IC][6] = 78, + [2][1][RTW89_ACMA][6] = 44, + [2][1][RTW89_FCC][7] = 78, + [2][1][RTW89_ETSI][7] = 48, + [2][1][RTW89_MKK][7] = 48, + [2][1][RTW89_IC][7] = 78, + [2][1][RTW89_ACMA][7] = 44, + [2][1][RTW89_FCC][8] = 74, + [2][1][RTW89_ETSI][8] = 48, + [2][1][RTW89_MKK][8] = 48, + [2][1][RTW89_IC][8] = 74, + [2][1][RTW89_ACMA][8] = 44, + [2][1][RTW89_FCC][9] = 70, + [2][1][RTW89_ETSI][9] = 48, + [2][1][RTW89_MKK][9] = 48, + [2][1][RTW89_IC][9] = 70, + [2][1][RTW89_ACMA][9] = 44, + [2][1][RTW89_FCC][10] = 70, + [2][1][RTW89_ETSI][10] = 48, + [2][1][RTW89_MKK][10] = 48, + [2][1][RTW89_IC][10] = 70, + [2][1][RTW89_ACMA][10] = 44, + [2][1][RTW89_FCC][11] = 60, + [2][1][RTW89_ETSI][11] = 48, + [2][1][RTW89_MKK][11] = 48, + [2][1][RTW89_IC][11] = 60, + [2][1][RTW89_ACMA][11] = 44, + [2][1][RTW89_FCC][12] = 44, + [2][1][RTW89_ETSI][12] = 46, + [2][1][RTW89_MKK][12] = 48, + [2][1][RTW89_IC][12] = 44, + [2][1][RTW89_ACMA][12] = 42, + [2][1][RTW89_FCC][13] = 127, + [2][1][RTW89_ETSI][13] = 127, + [2][1][RTW89_MKK][13] = 127, + [2][1][RTW89_IC][13] = 127, + [2][1][RTW89_ACMA][13] = 127, +}; + +const s8 rtw89_8852c_txpwr_lmt_ru_5g[RTW89_RU_NUM][RTW89_NTX_NUM] + [RTW89_REGD_NUM][RTW89_5G_CH_NUM] = { + [0][0][RTW89_WW][0] = 24, + [0][0][RTW89_WW][2] = 24, + [0][0][RTW89_WW][4] = 24, + [0][0][RTW89_WW][6] = 24, + [0][0][RTW89_WW][8] = 24, + [0][0][RTW89_WW][10] = 24, + [0][0][RTW89_WW][12] = 24, + [0][0][RTW89_WW][14] = 24, + [0][0][RTW89_WW][15] = 24, + [0][0][RTW89_WW][17] = 24, + [0][0][RTW89_WW][19] = 24, + [0][0][RTW89_WW][21] = 24, + [0][0][RTW89_WW][23] = 24, + [0][0][RTW89_WW][25] = 32, + [0][0][RTW89_WW][27] = 32, + [0][0][RTW89_WW][29] = 32, + [0][0][RTW89_WW][31] = 24, + [0][0][RTW89_WW][33] = 24, + [0][0][RTW89_WW][35] = 24, + [0][0][RTW89_WW][37] = 44, + [0][0][RTW89_WW][38] = 30, + [0][0][RTW89_WW][40] = 30, + [0][0][RTW89_WW][42] = 30, + [0][0][RTW89_WW][44] = 30, + [0][0][RTW89_WW][46] = 30, + [0][0][RTW89_WW][48] = 32, + [0][0][RTW89_WW][50] = 32, + [0][0][RTW89_WW][52] = 32, + [0][1][RTW89_WW][0] = 0, + [0][1][RTW89_WW][2] = 4, + [0][1][RTW89_WW][4] = 0, + [0][1][RTW89_WW][6] = 0, + [0][1][RTW89_WW][8] = 12, + [0][1][RTW89_WW][10] = 12, + [0][1][RTW89_WW][12] = 12, + [0][1][RTW89_WW][14] = 12, + [0][1][RTW89_WW][15] = 12, + [0][1][RTW89_WW][17] = 12, + [0][1][RTW89_WW][19] = 12, + [0][1][RTW89_WW][21] = 12, + [0][1][RTW89_WW][23] = 12, + [0][1][RTW89_WW][25] = 20, + [0][1][RTW89_WW][27] = 18, + [0][1][RTW89_WW][29] = 18, + [0][1][RTW89_WW][31] = 12, + [0][1][RTW89_WW][33] = 12, + [0][1][RTW89_WW][35] = 12, + [0][1][RTW89_WW][37] = 34, + [0][1][RTW89_WW][38] = 18, + [0][1][RTW89_WW][40] = 18, + [0][1][RTW89_WW][42] = 18, + [0][1][RTW89_WW][44] = 18, + [0][1][RTW89_WW][46] = 18, + [0][1][RTW89_WW][48] = 20, + [0][1][RTW89_WW][50] = 20, + [0][1][RTW89_WW][52] = 20, + [1][0][RTW89_WW][0] = 34, + [1][0][RTW89_WW][2] = 34, + [1][0][RTW89_WW][4] = 34, + [1][0][RTW89_WW][6] = 34, + [1][0][RTW89_WW][8] = 34, + [1][0][RTW89_WW][10] = 34, + [1][0][RTW89_WW][12] = 34, + [1][0][RTW89_WW][14] = 34, + [1][0][RTW89_WW][15] = 34, + [1][0][RTW89_WW][17] = 34, + [1][0][RTW89_WW][19] = 34, + [1][0][RTW89_WW][21] = 34, + [1][0][RTW89_WW][23] = 34, + [1][0][RTW89_WW][25] = 42, + [1][0][RTW89_WW][27] = 44, + [1][0][RTW89_WW][29] = 44, + [1][0][RTW89_WW][31] = 34, + [1][0][RTW89_WW][33] = 34, + [1][0][RTW89_WW][35] = 34, + [1][0][RTW89_WW][37] = 52, + [1][0][RTW89_WW][38] = 30, + [1][0][RTW89_WW][40] = 30, + [1][0][RTW89_WW][42] = 30, + [1][0][RTW89_WW][44] = 30, + [1][0][RTW89_WW][46] = 30, + [1][0][RTW89_WW][48] = 44, + [1][0][RTW89_WW][50] = 44, + [1][0][RTW89_WW][52] = 44, + [1][1][RTW89_WW][0] = 10, + [1][1][RTW89_WW][2] = 14, + [1][1][RTW89_WW][4] = 10, + [1][1][RTW89_WW][6] = 10, + [1][1][RTW89_WW][8] = 20, + [1][1][RTW89_WW][10] = 20, + [1][1][RTW89_WW][12] = 22, + [1][1][RTW89_WW][14] = 22, + [1][1][RTW89_WW][15] = 22, + [1][1][RTW89_WW][17] = 22, + [1][1][RTW89_WW][19] = 22, + [1][1][RTW89_WW][21] = 22, + [1][1][RTW89_WW][23] = 22, + [1][1][RTW89_WW][25] = 30, + [1][1][RTW89_WW][27] = 32, + [1][1][RTW89_WW][29] = 32, + [1][1][RTW89_WW][31] = 22, + [1][1][RTW89_WW][33] = 22, + [1][1][RTW89_WW][35] = 22, + [1][1][RTW89_WW][37] = 42, + [1][1][RTW89_WW][38] = 18, + [1][1][RTW89_WW][40] = 18, + [1][1][RTW89_WW][42] = 18, + [1][1][RTW89_WW][44] = 18, + [1][1][RTW89_WW][46] = 18, + [1][1][RTW89_WW][48] = 32, + [1][1][RTW89_WW][50] = 32, + [1][1][RTW89_WW][52] = 32, + [2][0][RTW89_WW][0] = 46, + [2][0][RTW89_WW][2] = 46, + [2][0][RTW89_WW][4] = 46, + [2][0][RTW89_WW][6] = 46, + [2][0][RTW89_WW][8] = 48, + [2][0][RTW89_WW][10] = 48, + [2][0][RTW89_WW][12] = 46, + [2][0][RTW89_WW][14] = 46, + [2][0][RTW89_WW][15] = 48, + [2][0][RTW89_WW][17] = 48, + [2][0][RTW89_WW][19] = 48, + [2][0][RTW89_WW][21] = 48, + [2][0][RTW89_WW][23] = 48, + [2][0][RTW89_WW][25] = 54, + [2][0][RTW89_WW][27] = 54, + [2][0][RTW89_WW][29] = 54, + [2][0][RTW89_WW][31] = 48, + [2][0][RTW89_WW][33] = 48, + [2][0][RTW89_WW][35] = 48, + [2][0][RTW89_WW][37] = 66, + [2][0][RTW89_WW][38] = 30, + [2][0][RTW89_WW][40] = 30, + [2][0][RTW89_WW][42] = 30, + [2][0][RTW89_WW][44] = 30, + [2][0][RTW89_WW][46] = 30, + [2][0][RTW89_WW][48] = 56, + [2][0][RTW89_WW][50] = 56, + [2][0][RTW89_WW][52] = 56, + [2][1][RTW89_WW][0] = 20, + [2][1][RTW89_WW][2] = 18, + [2][1][RTW89_WW][4] = 22, + [2][1][RTW89_WW][6] = 22, + [2][1][RTW89_WW][8] = 34, + [2][1][RTW89_WW][10] = 34, + [2][1][RTW89_WW][12] = 36, + [2][1][RTW89_WW][14] = 36, + [2][1][RTW89_WW][15] = 36, + [2][1][RTW89_WW][17] = 36, + [2][1][RTW89_WW][19] = 36, + [2][1][RTW89_WW][21] = 36, + [2][1][RTW89_WW][23] = 36, + [2][1][RTW89_WW][25] = 42, + [2][1][RTW89_WW][27] = 42, + [2][1][RTW89_WW][29] = 42, + [2][1][RTW89_WW][31] = 36, + [2][1][RTW89_WW][33] = 36, + [2][1][RTW89_WW][35] = 36, + [2][1][RTW89_WW][37] = 50, + [2][1][RTW89_WW][38] = 18, + [2][1][RTW89_WW][40] = 18, + [2][1][RTW89_WW][42] = 18, + [2][1][RTW89_WW][44] = 18, + [2][1][RTW89_WW][46] = 18, + [2][1][RTW89_WW][48] = 44, + [2][1][RTW89_WW][50] = 44, + [2][1][RTW89_WW][52] = 44, + [0][0][RTW89_FCC][0] = 52, + [0][0][RTW89_ETSI][0] = 32, + [0][0][RTW89_MKK][0] = 26, + [0][0][RTW89_IC][0] = 24, + [0][0][RTW89_ACMA][0] = 24, + [0][0][RTW89_FCC][2] = 52, + [0][0][RTW89_ETSI][2] = 32, + [0][0][RTW89_MKK][2] = 26, + [0][0][RTW89_IC][2] = 24, + [0][0][RTW89_ACMA][2] = 24, + [0][0][RTW89_FCC][4] = 52, + [0][0][RTW89_ETSI][4] = 32, + [0][0][RTW89_MKK][4] = 26, + [0][0][RTW89_IC][4] = 24, + [0][0][RTW89_ACMA][4] = 24, + [0][0][RTW89_FCC][6] = 52, + [0][0][RTW89_ETSI][6] = 32, + [0][0][RTW89_MKK][6] = 26, + [0][0][RTW89_IC][6] = 24, + [0][0][RTW89_ACMA][6] = 24, + [0][0][RTW89_FCC][8] = 52, + [0][0][RTW89_ETSI][8] = 30, + [0][0][RTW89_MKK][8] = 26, + [0][0][RTW89_IC][8] = 52, + [0][0][RTW89_ACMA][8] = 24, + [0][0][RTW89_FCC][10] = 52, + [0][0][RTW89_ETSI][10] = 30, + [0][0][RTW89_MKK][10] = 26, + [0][0][RTW89_IC][10] = 52, + [0][0][RTW89_ACMA][10] = 24, + [0][0][RTW89_FCC][12] = 52, + [0][0][RTW89_ETSI][12] = 30, + [0][0][RTW89_MKK][12] = 24, + [0][0][RTW89_IC][12] = 52, + [0][0][RTW89_ACMA][12] = 24, + [0][0][RTW89_FCC][14] = 52, + [0][0][RTW89_ETSI][14] = 30, + [0][0][RTW89_MKK][14] = 24, + [0][0][RTW89_IC][14] = 52, + [0][0][RTW89_ACMA][14] = 24, + [0][0][RTW89_FCC][15] = 52, + [0][0][RTW89_ETSI][15] = 32, + [0][0][RTW89_MKK][15] = 46, + [0][0][RTW89_IC][15] = 52, + [0][0][RTW89_ACMA][15] = 24, + [0][0][RTW89_FCC][17] = 52, + [0][0][RTW89_ETSI][17] = 32, + [0][0][RTW89_MKK][17] = 48, + [0][0][RTW89_IC][17] = 52, + [0][0][RTW89_ACMA][17] = 24, + [0][0][RTW89_FCC][19] = 52, + [0][0][RTW89_ETSI][19] = 32, + [0][0][RTW89_MKK][19] = 48, + [0][0][RTW89_IC][19] = 52, + [0][0][RTW89_ACMA][19] = 24, + [0][0][RTW89_FCC][21] = 52, + [0][0][RTW89_ETSI][21] = 32, + [0][0][RTW89_MKK][21] = 48, + [0][0][RTW89_IC][21] = 52, + [0][0][RTW89_ACMA][21] = 24, + [0][0][RTW89_FCC][23] = 52, + [0][0][RTW89_ETSI][23] = 32, + [0][0][RTW89_MKK][23] = 48, + [0][0][RTW89_IC][23] = 52, + [0][0][RTW89_ACMA][23] = 24, + [0][0][RTW89_FCC][25] = 52, + [0][0][RTW89_ETSI][25] = 32, + [0][0][RTW89_MKK][25] = 48, + [0][0][RTW89_IC][25] = 127, + [0][0][RTW89_ACMA][25] = 127, + [0][0][RTW89_FCC][27] = 52, + [0][0][RTW89_ETSI][27] = 32, + [0][0][RTW89_MKK][27] = 48, + [0][0][RTW89_IC][27] = 127, + [0][0][RTW89_ACMA][27] = 127, + [0][0][RTW89_FCC][29] = 52, + [0][0][RTW89_ETSI][29] = 32, + [0][0][RTW89_MKK][29] = 48, + [0][0][RTW89_IC][29] = 127, + [0][0][RTW89_ACMA][29] = 127, + [0][0][RTW89_FCC][31] = 52, + [0][0][RTW89_ETSI][31] = 32, + [0][0][RTW89_MKK][31] = 48, + [0][0][RTW89_IC][31] = 52, + [0][0][RTW89_ACMA][31] = 24, + [0][0][RTW89_FCC][33] = 52, + [0][0][RTW89_ETSI][33] = 32, + [0][0][RTW89_MKK][33] = 48, + [0][0][RTW89_IC][33] = 52, + [0][0][RTW89_ACMA][33] = 24, + [0][0][RTW89_FCC][35] = 52, + [0][0][RTW89_ETSI][35] = 32, + [0][0][RTW89_MKK][35] = 48, + [0][0][RTW89_IC][35] = 52, + [0][0][RTW89_ACMA][35] = 24, + [0][0][RTW89_FCC][37] = 52, + [0][0][RTW89_ETSI][37] = 127, + [0][0][RTW89_MKK][37] = 44, + [0][0][RTW89_IC][37] = 52, + [0][0][RTW89_ACMA][37] = 52, + [0][0][RTW89_FCC][38] = 84, + [0][0][RTW89_ETSI][38] = 30, + [0][0][RTW89_MKK][38] = 127, + [0][0][RTW89_IC][38] = 84, + [0][0][RTW89_ACMA][38] = 84, + [0][0][RTW89_FCC][40] = 84, + [0][0][RTW89_ETSI][40] = 30, + [0][0][RTW89_MKK][40] = 127, + [0][0][RTW89_IC][40] = 84, + [0][0][RTW89_ACMA][40] = 84, + [0][0][RTW89_FCC][42] = 84, + [0][0][RTW89_ETSI][42] = 30, + [0][0][RTW89_MKK][42] = 127, + [0][0][RTW89_IC][42] = 84, + [0][0][RTW89_ACMA][42] = 84, + [0][0][RTW89_FCC][44] = 84, + [0][0][RTW89_ETSI][44] = 30, + [0][0][RTW89_MKK][44] = 127, + [0][0][RTW89_IC][44] = 84, + [0][0][RTW89_ACMA][44] = 84, + [0][0][RTW89_FCC][46] = 84, + [0][0][RTW89_ETSI][46] = 30, + [0][0][RTW89_MKK][46] = 127, + [0][0][RTW89_IC][46] = 84, + [0][0][RTW89_ACMA][46] = 84, + [0][0][RTW89_FCC][48] = 32, + [0][0][RTW89_ETSI][48] = 127, + [0][0][RTW89_MKK][48] = 127, + [0][0][RTW89_IC][48] = 127, + [0][0][RTW89_ACMA][48] = 127, + [0][0][RTW89_FCC][50] = 32, + [0][0][RTW89_ETSI][50] = 127, + [0][0][RTW89_MKK][50] = 127, + [0][0][RTW89_IC][50] = 127, + [0][0][RTW89_ACMA][50] = 127, + [0][0][RTW89_FCC][52] = 32, + [0][0][RTW89_ETSI][52] = 127, + [0][0][RTW89_MKK][52] = 127, + [0][0][RTW89_IC][52] = 127, + [0][0][RTW89_ACMA][52] = 127, + [0][1][RTW89_FCC][0] = 34, + [0][1][RTW89_ETSI][0] = 20, + [0][1][RTW89_MKK][0] = 12, + [0][1][RTW89_IC][0] = 0, + [0][1][RTW89_ACMA][0] = 12, + [0][1][RTW89_FCC][2] = 38, + [0][1][RTW89_ETSI][2] = 20, + [0][1][RTW89_MKK][2] = 12, + [0][1][RTW89_IC][2] = 4, + [0][1][RTW89_ACMA][2] = 12, + [0][1][RTW89_FCC][4] = 34, + [0][1][RTW89_ETSI][4] = 20, + [0][1][RTW89_MKK][4] = 14, + [0][1][RTW89_IC][4] = 0, + [0][1][RTW89_ACMA][4] = 12, + [0][1][RTW89_FCC][6] = 34, + [0][1][RTW89_ETSI][6] = 20, + [0][1][RTW89_MKK][6] = 14, + [0][1][RTW89_IC][6] = 0, + [0][1][RTW89_ACMA][6] = 12, + [0][1][RTW89_FCC][8] = 34, + [0][1][RTW89_ETSI][8] = 18, + [0][1][RTW89_MKK][8] = 14, + [0][1][RTW89_IC][8] = 34, + [0][1][RTW89_ACMA][8] = 12, + [0][1][RTW89_FCC][10] = 34, + [0][1][RTW89_ETSI][10] = 18, + [0][1][RTW89_MKK][10] = 14, + [0][1][RTW89_IC][10] = 34, + [0][1][RTW89_ACMA][10] = 12, + [0][1][RTW89_FCC][12] = 38, + [0][1][RTW89_ETSI][12] = 18, + [0][1][RTW89_MKK][12] = 12, + [0][1][RTW89_IC][12] = 38, + [0][1][RTW89_ACMA][12] = 12, + [0][1][RTW89_FCC][14] = 34, + [0][1][RTW89_ETSI][14] = 18, + [0][1][RTW89_MKK][14] = 12, + [0][1][RTW89_IC][14] = 34, + [0][1][RTW89_ACMA][14] = 12, + [0][1][RTW89_FCC][15] = 34, + [0][1][RTW89_ETSI][15] = 20, + [0][1][RTW89_MKK][15] = 32, + [0][1][RTW89_IC][15] = 34, + [0][1][RTW89_ACMA][15] = 12, + [0][1][RTW89_FCC][17] = 34, + [0][1][RTW89_ETSI][17] = 20, + [0][1][RTW89_MKK][17] = 34, + [0][1][RTW89_IC][17] = 34, + [0][1][RTW89_ACMA][17] = 12, + [0][1][RTW89_FCC][19] = 38, + [0][1][RTW89_ETSI][19] = 20, + [0][1][RTW89_MKK][19] = 34, + [0][1][RTW89_IC][19] = 38, + [0][1][RTW89_ACMA][19] = 12, + [0][1][RTW89_FCC][21] = 38, + [0][1][RTW89_ETSI][21] = 20, + [0][1][RTW89_MKK][21] = 34, + [0][1][RTW89_IC][21] = 38, + [0][1][RTW89_ACMA][21] = 12, + [0][1][RTW89_FCC][23] = 38, + [0][1][RTW89_ETSI][23] = 20, + [0][1][RTW89_MKK][23] = 34, + [0][1][RTW89_IC][23] = 38, + [0][1][RTW89_ACMA][23] = 12, + [0][1][RTW89_FCC][25] = 38, + [0][1][RTW89_ETSI][25] = 20, + [0][1][RTW89_MKK][25] = 34, + [0][1][RTW89_IC][25] = 127, + [0][1][RTW89_ACMA][25] = 127, + [0][1][RTW89_FCC][27] = 38, + [0][1][RTW89_ETSI][27] = 18, + [0][1][RTW89_MKK][27] = 34, + [0][1][RTW89_IC][27] = 127, + [0][1][RTW89_ACMA][27] = 127, + [0][1][RTW89_FCC][29] = 38, + [0][1][RTW89_ETSI][29] = 18, + [0][1][RTW89_MKK][29] = 34, + [0][1][RTW89_IC][29] = 127, + [0][1][RTW89_ACMA][29] = 127, + [0][1][RTW89_FCC][31] = 38, + [0][1][RTW89_ETSI][31] = 18, + [0][1][RTW89_MKK][31] = 34, + [0][1][RTW89_IC][31] = 34, + [0][1][RTW89_ACMA][31] = 12, + [0][1][RTW89_FCC][33] = 34, + [0][1][RTW89_ETSI][33] = 18, + [0][1][RTW89_MKK][33] = 34, + [0][1][RTW89_IC][33] = 34, + [0][1][RTW89_ACMA][33] = 12, + [0][1][RTW89_FCC][35] = 34, + [0][1][RTW89_ETSI][35] = 18, + [0][1][RTW89_MKK][35] = 34, + [0][1][RTW89_IC][35] = 34, + [0][1][RTW89_ACMA][35] = 12, + [0][1][RTW89_FCC][37] = 38, + [0][1][RTW89_ETSI][37] = 127, + [0][1][RTW89_MKK][37] = 34, + [0][1][RTW89_IC][37] = 38, + [0][1][RTW89_ACMA][37] = 38, + [0][1][RTW89_FCC][38] = 82, + [0][1][RTW89_ETSI][38] = 18, + [0][1][RTW89_MKK][38] = 127, + [0][1][RTW89_IC][38] = 82, + [0][1][RTW89_ACMA][38] = 84, + [0][1][RTW89_FCC][40] = 82, + [0][1][RTW89_ETSI][40] = 18, + [0][1][RTW89_MKK][40] = 127, + [0][1][RTW89_IC][40] = 82, + [0][1][RTW89_ACMA][40] = 84, + [0][1][RTW89_FCC][42] = 82, + [0][1][RTW89_ETSI][42] = 18, + [0][1][RTW89_MKK][42] = 127, + [0][1][RTW89_IC][42] = 82, + [0][1][RTW89_ACMA][42] = 84, + [0][1][RTW89_FCC][44] = 82, + [0][1][RTW89_ETSI][44] = 18, + [0][1][RTW89_MKK][44] = 127, + [0][1][RTW89_IC][44] = 82, + [0][1][RTW89_ACMA][44] = 84, + [0][1][RTW89_FCC][46] = 82, + [0][1][RTW89_ETSI][46] = 18, + [0][1][RTW89_MKK][46] = 127, + [0][1][RTW89_IC][46] = 82, + [0][1][RTW89_ACMA][46] = 84, + [0][1][RTW89_FCC][48] = 20, + [0][1][RTW89_ETSI][48] = 127, + [0][1][RTW89_MKK][48] = 127, + [0][1][RTW89_IC][48] = 127, + [0][1][RTW89_ACMA][48] = 127, + [0][1][RTW89_FCC][50] = 20, + [0][1][RTW89_ETSI][50] = 127, + [0][1][RTW89_MKK][50] = 127, + [0][1][RTW89_IC][50] = 127, + [0][1][RTW89_ACMA][50] = 127, + [0][1][RTW89_FCC][52] = 20, + [0][1][RTW89_ETSI][52] = 127, + [0][1][RTW89_MKK][52] = 127, + [0][1][RTW89_IC][52] = 127, + [0][1][RTW89_ACMA][52] = 127, + [1][0][RTW89_FCC][0] = 62, + [1][0][RTW89_ETSI][0] = 42, + [1][0][RTW89_MKK][0] = 36, + [1][0][RTW89_IC][0] = 36, + [1][0][RTW89_ACMA][0] = 34, + [1][0][RTW89_FCC][2] = 62, + [1][0][RTW89_ETSI][2] = 42, + [1][0][RTW89_MKK][2] = 36, + [1][0][RTW89_IC][2] = 36, + [1][0][RTW89_ACMA][2] = 34, + [1][0][RTW89_FCC][4] = 62, + [1][0][RTW89_ETSI][4] = 42, + [1][0][RTW89_MKK][4] = 34, + [1][0][RTW89_IC][4] = 36, + [1][0][RTW89_ACMA][4] = 34, + [1][0][RTW89_FCC][6] = 62, + [1][0][RTW89_ETSI][6] = 42, + [1][0][RTW89_MKK][6] = 34, + [1][0][RTW89_IC][6] = 36, + [1][0][RTW89_ACMA][6] = 34, + [1][0][RTW89_FCC][8] = 62, + [1][0][RTW89_ETSI][8] = 42, + [1][0][RTW89_MKK][8] = 36, + [1][0][RTW89_IC][8] = 62, + [1][0][RTW89_ACMA][8] = 34, + [1][0][RTW89_FCC][10] = 62, + [1][0][RTW89_ETSI][10] = 42, + [1][0][RTW89_MKK][10] = 36, + [1][0][RTW89_IC][10] = 62, + [1][0][RTW89_ACMA][10] = 34, + [1][0][RTW89_FCC][12] = 64, + [1][0][RTW89_ETSI][12] = 42, + [1][0][RTW89_MKK][12] = 36, + [1][0][RTW89_IC][12] = 64, + [1][0][RTW89_ACMA][12] = 34, + [1][0][RTW89_FCC][14] = 62, + [1][0][RTW89_ETSI][14] = 42, + [1][0][RTW89_MKK][14] = 36, + [1][0][RTW89_IC][14] = 62, + [1][0][RTW89_ACMA][14] = 34, + [1][0][RTW89_FCC][15] = 62, + [1][0][RTW89_ETSI][15] = 42, + [1][0][RTW89_MKK][15] = 54, + [1][0][RTW89_IC][15] = 62, + [1][0][RTW89_ACMA][15] = 34, + [1][0][RTW89_FCC][17] = 62, + [1][0][RTW89_ETSI][17] = 42, + [1][0][RTW89_MKK][17] = 58, + [1][0][RTW89_IC][17] = 62, + [1][0][RTW89_ACMA][17] = 34, + [1][0][RTW89_FCC][19] = 62, + [1][0][RTW89_ETSI][19] = 42, + [1][0][RTW89_MKK][19] = 58, + [1][0][RTW89_IC][19] = 62, + [1][0][RTW89_ACMA][19] = 34, + [1][0][RTW89_FCC][21] = 62, + [1][0][RTW89_ETSI][21] = 42, + [1][0][RTW89_MKK][21] = 58, + [1][0][RTW89_IC][21] = 62, + [1][0][RTW89_ACMA][21] = 34, + [1][0][RTW89_FCC][23] = 62, + [1][0][RTW89_ETSI][23] = 42, + [1][0][RTW89_MKK][23] = 58, + [1][0][RTW89_IC][23] = 62, + [1][0][RTW89_ACMA][23] = 34, + [1][0][RTW89_FCC][25] = 62, + [1][0][RTW89_ETSI][25] = 42, + [1][0][RTW89_MKK][25] = 58, + [1][0][RTW89_IC][25] = 127, + [1][0][RTW89_ACMA][25] = 127, + [1][0][RTW89_FCC][27] = 62, + [1][0][RTW89_ETSI][27] = 44, + [1][0][RTW89_MKK][27] = 58, + [1][0][RTW89_IC][27] = 127, + [1][0][RTW89_ACMA][27] = 127, + [1][0][RTW89_FCC][29] = 62, + [1][0][RTW89_ETSI][29] = 44, + [1][0][RTW89_MKK][29] = 58, + [1][0][RTW89_IC][29] = 127, + [1][0][RTW89_ACMA][29] = 127, + [1][0][RTW89_FCC][31] = 62, + [1][0][RTW89_ETSI][31] = 44, + [1][0][RTW89_MKK][31] = 58, + [1][0][RTW89_IC][31] = 62, + [1][0][RTW89_ACMA][31] = 34, + [1][0][RTW89_FCC][33] = 62, + [1][0][RTW89_ETSI][33] = 44, + [1][0][RTW89_MKK][33] = 58, + [1][0][RTW89_IC][33] = 62, + [1][0][RTW89_ACMA][33] = 34, + [1][0][RTW89_FCC][35] = 62, + [1][0][RTW89_ETSI][35] = 44, + [1][0][RTW89_MKK][35] = 58, + [1][0][RTW89_IC][35] = 62, + [1][0][RTW89_ACMA][35] = 34, + [1][0][RTW89_FCC][37] = 64, + [1][0][RTW89_ETSI][37] = 127, + [1][0][RTW89_MKK][37] = 52, + [1][0][RTW89_IC][37] = 64, + [1][0][RTW89_ACMA][37] = 64, + [1][0][RTW89_FCC][38] = 84, + [1][0][RTW89_ETSI][38] = 30, + [1][0][RTW89_MKK][38] = 127, + [1][0][RTW89_IC][38] = 84, + [1][0][RTW89_ACMA][38] = 84, + [1][0][RTW89_FCC][40] = 84, + [1][0][RTW89_ETSI][40] = 30, + [1][0][RTW89_MKK][40] = 127, + [1][0][RTW89_IC][40] = 84, + [1][0][RTW89_ACMA][40] = 84, + [1][0][RTW89_FCC][42] = 84, + [1][0][RTW89_ETSI][42] = 30, + [1][0][RTW89_MKK][42] = 127, + [1][0][RTW89_IC][42] = 84, + [1][0][RTW89_ACMA][42] = 84, + [1][0][RTW89_FCC][44] = 84, + [1][0][RTW89_ETSI][44] = 30, + [1][0][RTW89_MKK][44] = 127, + [1][0][RTW89_IC][44] = 84, + [1][0][RTW89_ACMA][44] = 84, + [1][0][RTW89_FCC][46] = 84, + [1][0][RTW89_ETSI][46] = 30, + [1][0][RTW89_MKK][46] = 127, + [1][0][RTW89_IC][46] = 84, + [1][0][RTW89_ACMA][46] = 84, + [1][0][RTW89_FCC][48] = 44, + [1][0][RTW89_ETSI][48] = 127, + [1][0][RTW89_MKK][48] = 127, + [1][0][RTW89_IC][48] = 127, + [1][0][RTW89_ACMA][48] = 127, + [1][0][RTW89_FCC][50] = 44, + [1][0][RTW89_ETSI][50] = 127, + [1][0][RTW89_MKK][50] = 127, + [1][0][RTW89_IC][50] = 127, + [1][0][RTW89_ACMA][50] = 127, + [1][0][RTW89_FCC][52] = 44, + [1][0][RTW89_ETSI][52] = 127, + [1][0][RTW89_MKK][52] = 127, + [1][0][RTW89_IC][52] = 127, + [1][0][RTW89_ACMA][52] = 127, + [1][1][RTW89_FCC][0] = 42, + [1][1][RTW89_ETSI][0] = 32, + [1][1][RTW89_MKK][0] = 22, + [1][1][RTW89_IC][0] = 10, + [1][1][RTW89_ACMA][0] = 22, + [1][1][RTW89_FCC][2] = 44, + [1][1][RTW89_ETSI][2] = 32, + [1][1][RTW89_MKK][2] = 22, + [1][1][RTW89_IC][2] = 14, + [1][1][RTW89_ACMA][2] = 22, + [1][1][RTW89_FCC][4] = 42, + [1][1][RTW89_ETSI][4] = 32, + [1][1][RTW89_MKK][4] = 20, + [1][1][RTW89_IC][4] = 10, + [1][1][RTW89_ACMA][4] = 22, + [1][1][RTW89_FCC][6] = 42, + [1][1][RTW89_ETSI][6] = 32, + [1][1][RTW89_MKK][6] = 20, + [1][1][RTW89_IC][6] = 10, + [1][1][RTW89_ACMA][6] = 22, + [1][1][RTW89_FCC][8] = 44, + [1][1][RTW89_ETSI][8] = 32, + [1][1][RTW89_MKK][8] = 20, + [1][1][RTW89_IC][8] = 44, + [1][1][RTW89_ACMA][8] = 22, + [1][1][RTW89_FCC][10] = 44, + [1][1][RTW89_ETSI][10] = 32, + [1][1][RTW89_MKK][10] = 20, + [1][1][RTW89_IC][10] = 44, + [1][1][RTW89_ACMA][10] = 22, + [1][1][RTW89_FCC][12] = 46, + [1][1][RTW89_ETSI][12] = 32, + [1][1][RTW89_MKK][12] = 22, + [1][1][RTW89_IC][12] = 46, + [1][1][RTW89_ACMA][12] = 22, + [1][1][RTW89_FCC][14] = 42, + [1][1][RTW89_ETSI][14] = 32, + [1][1][RTW89_MKK][14] = 22, + [1][1][RTW89_IC][14] = 40, + [1][1][RTW89_ACMA][14] = 22, + [1][1][RTW89_FCC][15] = 42, + [1][1][RTW89_ETSI][15] = 30, + [1][1][RTW89_MKK][15] = 42, + [1][1][RTW89_IC][15] = 42, + [1][1][RTW89_ACMA][15] = 22, + [1][1][RTW89_FCC][17] = 42, + [1][1][RTW89_ETSI][17] = 30, + [1][1][RTW89_MKK][17] = 44, + [1][1][RTW89_IC][17] = 42, + [1][1][RTW89_ACMA][17] = 22, + [1][1][RTW89_FCC][19] = 42, + [1][1][RTW89_ETSI][19] = 30, + [1][1][RTW89_MKK][19] = 44, + [1][1][RTW89_IC][19] = 42, + [1][1][RTW89_ACMA][19] = 22, + [1][1][RTW89_FCC][21] = 42, + [1][1][RTW89_ETSI][21] = 30, + [1][1][RTW89_MKK][21] = 44, + [1][1][RTW89_IC][21] = 42, + [1][1][RTW89_ACMA][21] = 22, + [1][1][RTW89_FCC][23] = 42, + [1][1][RTW89_ETSI][23] = 30, + [1][1][RTW89_MKK][23] = 44, + [1][1][RTW89_IC][23] = 42, + [1][1][RTW89_ACMA][23] = 22, + [1][1][RTW89_FCC][25] = 42, + [1][1][RTW89_ETSI][25] = 30, + [1][1][RTW89_MKK][25] = 44, + [1][1][RTW89_IC][25] = 127, + [1][1][RTW89_ACMA][25] = 127, + [1][1][RTW89_FCC][27] = 42, + [1][1][RTW89_ETSI][27] = 32, + [1][1][RTW89_MKK][27] = 44, + [1][1][RTW89_IC][27] = 127, + [1][1][RTW89_ACMA][27] = 127, + [1][1][RTW89_FCC][29] = 42, + [1][1][RTW89_ETSI][29] = 32, + [1][1][RTW89_MKK][29] = 44, + [1][1][RTW89_IC][29] = 127, + [1][1][RTW89_ACMA][29] = 127, + [1][1][RTW89_FCC][31] = 42, + [1][1][RTW89_ETSI][31] = 32, + [1][1][RTW89_MKK][31] = 44, + [1][1][RTW89_IC][31] = 38, + [1][1][RTW89_ACMA][31] = 22, + [1][1][RTW89_FCC][33] = 40, + [1][1][RTW89_ETSI][33] = 32, + [1][1][RTW89_MKK][33] = 44, + [1][1][RTW89_IC][33] = 38, + [1][1][RTW89_ACMA][33] = 22, + [1][1][RTW89_FCC][35] = 40, + [1][1][RTW89_ETSI][35] = 32, + [1][1][RTW89_MKK][35] = 44, + [1][1][RTW89_IC][35] = 38, + [1][1][RTW89_ACMA][35] = 22, + [1][1][RTW89_FCC][37] = 48, + [1][1][RTW89_ETSI][37] = 127, + [1][1][RTW89_MKK][37] = 42, + [1][1][RTW89_IC][37] = 48, + [1][1][RTW89_ACMA][37] = 48, + [1][1][RTW89_FCC][38] = 84, + [1][1][RTW89_ETSI][38] = 18, + [1][1][RTW89_MKK][38] = 127, + [1][1][RTW89_IC][38] = 84, + [1][1][RTW89_ACMA][38] = 82, + [1][1][RTW89_FCC][40] = 84, + [1][1][RTW89_ETSI][40] = 18, + [1][1][RTW89_MKK][40] = 127, + [1][1][RTW89_IC][40] = 84, + [1][1][RTW89_ACMA][40] = 82, + [1][1][RTW89_FCC][42] = 84, + [1][1][RTW89_ETSI][42] = 18, + [1][1][RTW89_MKK][42] = 127, + [1][1][RTW89_IC][42] = 84, + [1][1][RTW89_ACMA][42] = 84, + [1][1][RTW89_FCC][44] = 84, + [1][1][RTW89_ETSI][44] = 18, + [1][1][RTW89_MKK][44] = 127, + [1][1][RTW89_IC][44] = 84, + [1][1][RTW89_ACMA][44] = 84, + [1][1][RTW89_FCC][46] = 84, + [1][1][RTW89_ETSI][46] = 18, + [1][1][RTW89_MKK][46] = 127, + [1][1][RTW89_IC][46] = 84, + [1][1][RTW89_ACMA][46] = 84, + [1][1][RTW89_FCC][48] = 32, + [1][1][RTW89_ETSI][48] = 127, + [1][1][RTW89_MKK][48] = 127, + [1][1][RTW89_IC][48] = 127, + [1][1][RTW89_ACMA][48] = 127, + [1][1][RTW89_FCC][50] = 32, + [1][1][RTW89_ETSI][50] = 127, + [1][1][RTW89_MKK][50] = 127, + [1][1][RTW89_IC][50] = 127, + [1][1][RTW89_ACMA][50] = 127, + [1][1][RTW89_FCC][52] = 32, + [1][1][RTW89_ETSI][52] = 127, + [1][1][RTW89_MKK][52] = 127, + [1][1][RTW89_IC][52] = 127, + [1][1][RTW89_ACMA][52] = 127, + [2][0][RTW89_FCC][0] = 70, + [2][0][RTW89_ETSI][0] = 54, + [2][0][RTW89_MKK][0] = 48, + [2][0][RTW89_IC][0] = 46, + [2][0][RTW89_ACMA][0] = 48, + [2][0][RTW89_FCC][2] = 70, + [2][0][RTW89_ETSI][2] = 54, + [2][0][RTW89_MKK][2] = 48, + [2][0][RTW89_IC][2] = 46, + [2][0][RTW89_ACMA][2] = 48, + [2][0][RTW89_FCC][4] = 70, + [2][0][RTW89_ETSI][4] = 54, + [2][0][RTW89_MKK][4] = 48, + [2][0][RTW89_IC][4] = 46, + [2][0][RTW89_ACMA][4] = 48, + [2][0][RTW89_FCC][6] = 70, + [2][0][RTW89_ETSI][6] = 54, + [2][0][RTW89_MKK][6] = 48, + [2][0][RTW89_IC][6] = 46, + [2][0][RTW89_ACMA][6] = 48, + [2][0][RTW89_FCC][8] = 70, + [2][0][RTW89_ETSI][8] = 54, + [2][0][RTW89_MKK][8] = 48, + [2][0][RTW89_IC][8] = 66, + [2][0][RTW89_ACMA][8] = 48, + [2][0][RTW89_FCC][10] = 70, + [2][0][RTW89_ETSI][10] = 54, + [2][0][RTW89_MKK][10] = 48, + [2][0][RTW89_IC][10] = 66, + [2][0][RTW89_ACMA][10] = 48, + [2][0][RTW89_FCC][12] = 70, + [2][0][RTW89_ETSI][12] = 54, + [2][0][RTW89_MKK][12] = 46, + [2][0][RTW89_IC][12] = 66, + [2][0][RTW89_ACMA][12] = 48, + [2][0][RTW89_FCC][14] = 70, + [2][0][RTW89_ETSI][14] = 54, + [2][0][RTW89_MKK][14] = 46, + [2][0][RTW89_IC][14] = 66, + [2][0][RTW89_ACMA][14] = 48, + [2][0][RTW89_FCC][15] = 70, + [2][0][RTW89_ETSI][15] = 54, + [2][0][RTW89_MKK][15] = 68, + [2][0][RTW89_IC][15] = 70, + [2][0][RTW89_ACMA][15] = 48, + [2][0][RTW89_FCC][17] = 70, + [2][0][RTW89_ETSI][17] = 54, + [2][0][RTW89_MKK][17] = 70, + [2][0][RTW89_IC][17] = 70, + [2][0][RTW89_ACMA][17] = 48, + [2][0][RTW89_FCC][19] = 70, + [2][0][RTW89_ETSI][19] = 54, + [2][0][RTW89_MKK][19] = 70, + [2][0][RTW89_IC][19] = 70, + [2][0][RTW89_ACMA][19] = 48, + [2][0][RTW89_FCC][21] = 70, + [2][0][RTW89_ETSI][21] = 54, + [2][0][RTW89_MKK][21] = 70, + [2][0][RTW89_IC][21] = 70, + [2][0][RTW89_ACMA][21] = 48, + [2][0][RTW89_FCC][23] = 70, + [2][0][RTW89_ETSI][23] = 54, + [2][0][RTW89_MKK][23] = 70, + [2][0][RTW89_IC][23] = 70, + [2][0][RTW89_ACMA][23] = 48, + [2][0][RTW89_FCC][25] = 70, + [2][0][RTW89_ETSI][25] = 54, + [2][0][RTW89_MKK][25] = 70, + [2][0][RTW89_IC][25] = 127, + [2][0][RTW89_ACMA][25] = 127, + [2][0][RTW89_FCC][27] = 70, + [2][0][RTW89_ETSI][27] = 54, + [2][0][RTW89_MKK][27] = 70, + [2][0][RTW89_IC][27] = 127, + [2][0][RTW89_ACMA][27] = 127, + [2][0][RTW89_FCC][29] = 70, + [2][0][RTW89_ETSI][29] = 54, + [2][0][RTW89_MKK][29] = 70, + [2][0][RTW89_IC][29] = 127, + [2][0][RTW89_ACMA][29] = 127, + [2][0][RTW89_FCC][31] = 70, + [2][0][RTW89_ETSI][31] = 54, + [2][0][RTW89_MKK][31] = 70, + [2][0][RTW89_IC][31] = 72, + [2][0][RTW89_ACMA][31] = 48, + [2][0][RTW89_FCC][33] = 72, + [2][0][RTW89_ETSI][33] = 54, + [2][0][RTW89_MKK][33] = 70, + [2][0][RTW89_IC][33] = 72, + [2][0][RTW89_ACMA][33] = 48, + [2][0][RTW89_FCC][35] = 72, + [2][0][RTW89_ETSI][35] = 54, + [2][0][RTW89_MKK][35] = 70, + [2][0][RTW89_IC][35] = 72, + [2][0][RTW89_ACMA][35] = 48, + [2][0][RTW89_FCC][37] = 70, + [2][0][RTW89_ETSI][37] = 127, + [2][0][RTW89_MKK][37] = 66, + [2][0][RTW89_IC][37] = 70, + [2][0][RTW89_ACMA][37] = 76, + [2][0][RTW89_FCC][38] = 84, + [2][0][RTW89_ETSI][38] = 30, + [2][0][RTW89_MKK][38] = 127, + [2][0][RTW89_IC][38] = 84, + [2][0][RTW89_ACMA][38] = 84, + [2][0][RTW89_FCC][40] = 84, + [2][0][RTW89_ETSI][40] = 30, + [2][0][RTW89_MKK][40] = 127, + [2][0][RTW89_IC][40] = 84, + [2][0][RTW89_ACMA][40] = 84, + [2][0][RTW89_FCC][42] = 84, + [2][0][RTW89_ETSI][42] = 30, + [2][0][RTW89_MKK][42] = 127, + [2][0][RTW89_IC][42] = 84, + [2][0][RTW89_ACMA][42] = 84, + [2][0][RTW89_FCC][44] = 84, + [2][0][RTW89_ETSI][44] = 30, + [2][0][RTW89_MKK][44] = 127, + [2][0][RTW89_IC][44] = 84, + [2][0][RTW89_ACMA][44] = 84, + [2][0][RTW89_FCC][46] = 84, + [2][0][RTW89_ETSI][46] = 30, + [2][0][RTW89_MKK][46] = 127, + [2][0][RTW89_IC][46] = 84, + [2][0][RTW89_ACMA][46] = 84, + [2][0][RTW89_FCC][48] = 56, + [2][0][RTW89_ETSI][48] = 127, + [2][0][RTW89_MKK][48] = 127, + [2][0][RTW89_IC][48] = 127, + [2][0][RTW89_ACMA][48] = 127, + [2][0][RTW89_FCC][50] = 56, + [2][0][RTW89_ETSI][50] = 127, + [2][0][RTW89_MKK][50] = 127, + [2][0][RTW89_IC][50] = 127, + [2][0][RTW89_ACMA][50] = 127, + [2][0][RTW89_FCC][52] = 56, + [2][0][RTW89_ETSI][52] = 127, + [2][0][RTW89_MKK][52] = 127, + [2][0][RTW89_IC][52] = 127, + [2][0][RTW89_ACMA][52] = 127, + [2][1][RTW89_FCC][0] = 50, + [2][1][RTW89_ETSI][0] = 42, + [2][1][RTW89_MKK][0] = 36, + [2][1][RTW89_IC][0] = 20, + [2][1][RTW89_ACMA][0] = 36, + [2][1][RTW89_FCC][2] = 50, + [2][1][RTW89_ETSI][2] = 42, + [2][1][RTW89_MKK][2] = 36, + [2][1][RTW89_IC][2] = 18, + [2][1][RTW89_ACMA][2] = 36, + [2][1][RTW89_FCC][4] = 50, + [2][1][RTW89_ETSI][4] = 42, + [2][1][RTW89_MKK][4] = 36, + [2][1][RTW89_IC][4] = 22, + [2][1][RTW89_ACMA][4] = 36, + [2][1][RTW89_FCC][6] = 50, + [2][1][RTW89_ETSI][6] = 42, + [2][1][RTW89_MKK][6] = 36, + [2][1][RTW89_IC][6] = 22, + [2][1][RTW89_ACMA][6] = 36, + [2][1][RTW89_FCC][8] = 50, + [2][1][RTW89_ETSI][8] = 42, + [2][1][RTW89_MKK][8] = 34, + [2][1][RTW89_IC][8] = 50, + [2][1][RTW89_ACMA][8] = 36, + [2][1][RTW89_FCC][10] = 50, + [2][1][RTW89_ETSI][10] = 42, + [2][1][RTW89_MKK][10] = 34, + [2][1][RTW89_IC][10] = 50, + [2][1][RTW89_ACMA][10] = 36, + [2][1][RTW89_FCC][12] = 52, + [2][1][RTW89_ETSI][12] = 42, + [2][1][RTW89_MKK][12] = 36, + [2][1][RTW89_IC][12] = 52, + [2][1][RTW89_ACMA][12] = 36, + [2][1][RTW89_FCC][14] = 52, + [2][1][RTW89_ETSI][14] = 42, + [2][1][RTW89_MKK][14] = 36, + [2][1][RTW89_IC][14] = 52, + [2][1][RTW89_ACMA][14] = 36, + [2][1][RTW89_FCC][15] = 50, + [2][1][RTW89_ETSI][15] = 42, + [2][1][RTW89_MKK][15] = 54, + [2][1][RTW89_IC][15] = 50, + [2][1][RTW89_ACMA][15] = 36, + [2][1][RTW89_FCC][17] = 50, + [2][1][RTW89_ETSI][17] = 42, + [2][1][RTW89_MKK][17] = 56, + [2][1][RTW89_IC][17] = 50, + [2][1][RTW89_ACMA][17] = 36, + [2][1][RTW89_FCC][19] = 50, + [2][1][RTW89_ETSI][19] = 42, + [2][1][RTW89_MKK][19] = 56, + [2][1][RTW89_IC][19] = 50, + [2][1][RTW89_ACMA][19] = 36, + [2][1][RTW89_FCC][21] = 50, + [2][1][RTW89_ETSI][21] = 42, + [2][1][RTW89_MKK][21] = 56, + [2][1][RTW89_IC][21] = 50, + [2][1][RTW89_ACMA][21] = 36, + [2][1][RTW89_FCC][23] = 50, + [2][1][RTW89_ETSI][23] = 42, + [2][1][RTW89_MKK][23] = 56, + [2][1][RTW89_IC][23] = 50, + [2][1][RTW89_ACMA][23] = 36, + [2][1][RTW89_FCC][25] = 50, + [2][1][RTW89_ETSI][25] = 42, + [2][1][RTW89_MKK][25] = 56, + [2][1][RTW89_IC][25] = 127, + [2][1][RTW89_ACMA][25] = 127, + [2][1][RTW89_FCC][27] = 50, + [2][1][RTW89_ETSI][27] = 42, + [2][1][RTW89_MKK][27] = 56, + [2][1][RTW89_IC][27] = 127, + [2][1][RTW89_ACMA][27] = 127, + [2][1][RTW89_FCC][29] = 50, + [2][1][RTW89_ETSI][29] = 42, + [2][1][RTW89_MKK][29] = 56, + [2][1][RTW89_IC][29] = 127, + [2][1][RTW89_ACMA][29] = 127, + [2][1][RTW89_FCC][31] = 50, + [2][1][RTW89_ETSI][31] = 42, + [2][1][RTW89_MKK][31] = 56, + [2][1][RTW89_IC][31] = 50, + [2][1][RTW89_ACMA][31] = 36, + [2][1][RTW89_FCC][33] = 50, + [2][1][RTW89_ETSI][33] = 42, + [2][1][RTW89_MKK][33] = 56, + [2][1][RTW89_IC][33] = 50, + [2][1][RTW89_ACMA][33] = 36, + [2][1][RTW89_FCC][35] = 50, + [2][1][RTW89_ETSI][35] = 42, + [2][1][RTW89_MKK][35] = 56, + [2][1][RTW89_IC][35] = 50, + [2][1][RTW89_ACMA][35] = 36, + [2][1][RTW89_FCC][37] = 50, + [2][1][RTW89_ETSI][37] = 127, + [2][1][RTW89_MKK][37] = 54, + [2][1][RTW89_IC][37] = 50, + [2][1][RTW89_ACMA][37] = 60, + [2][1][RTW89_FCC][38] = 84, + [2][1][RTW89_ETSI][38] = 18, + [2][1][RTW89_MKK][38] = 127, + [2][1][RTW89_IC][38] = 84, + [2][1][RTW89_ACMA][38] = 84, + [2][1][RTW89_FCC][40] = 84, + [2][1][RTW89_ETSI][40] = 18, + [2][1][RTW89_MKK][40] = 127, + [2][1][RTW89_IC][40] = 84, + [2][1][RTW89_ACMA][40] = 84, + [2][1][RTW89_FCC][42] = 84, + [2][1][RTW89_ETSI][42] = 18, + [2][1][RTW89_MKK][42] = 127, + [2][1][RTW89_IC][42] = 84, + [2][1][RTW89_ACMA][42] = 84, + [2][1][RTW89_FCC][44] = 84, + [2][1][RTW89_ETSI][44] = 18, + [2][1][RTW89_MKK][44] = 127, + [2][1][RTW89_IC][44] = 84, + [2][1][RTW89_ACMA][44] = 84, + [2][1][RTW89_FCC][46] = 84, + [2][1][RTW89_ETSI][46] = 18, + [2][1][RTW89_MKK][46] = 127, + [2][1][RTW89_IC][46] = 84, + [2][1][RTW89_ACMA][46] = 84, + [2][1][RTW89_FCC][48] = 44, + [2][1][RTW89_ETSI][48] = 127, + [2][1][RTW89_MKK][48] = 127, + [2][1][RTW89_IC][48] = 127, + [2][1][RTW89_ACMA][48] = 127, + [2][1][RTW89_FCC][50] = 44, + [2][1][RTW89_ETSI][50] = 127, + [2][1][RTW89_MKK][50] = 127, + [2][1][RTW89_IC][50] = 127, + [2][1][RTW89_ACMA][50] = 127, + [2][1][RTW89_FCC][52] = 44, + [2][1][RTW89_ETSI][52] = 127, + [2][1][RTW89_MKK][52] = 127, + [2][1][RTW89_IC][52] = 127, + [2][1][RTW89_ACMA][52] = 127, +}; + +const s8 rtw89_8852c_txpwr_lmt_ru_6g[RTW89_RU_NUM][RTW89_NTX_NUM] + [RTW89_REGD_NUM][RTW89_6G_CH_NUM] = { + [0][0][RTW89_WW][0] = 76, + [0][0][RTW89_WW][2] = 76, + [0][0][RTW89_WW][4] = 76, + [0][0][RTW89_WW][6] = 76, + [0][0][RTW89_WW][8] = 76, + [0][0][RTW89_WW][10] = 76, + [0][0][RTW89_WW][12] = 76, + [0][0][RTW89_WW][14] = 76, + [0][0][RTW89_WW][15] = 76, + [0][0][RTW89_WW][17] = 76, + [0][0][RTW89_WW][19] = 76, + [0][0][RTW89_WW][21] = 76, + [0][0][RTW89_WW][23] = 76, + [0][0][RTW89_WW][25] = 76, + [0][0][RTW89_WW][27] = 76, + [0][0][RTW89_WW][29] = 76, + [0][0][RTW89_WW][30] = 76, + [0][0][RTW89_WW][32] = 76, + [0][0][RTW89_WW][34] = 76, + [0][0][RTW89_WW][36] = 76, + [0][0][RTW89_WW][38] = 76, + [0][0][RTW89_WW][40] = 76, + [0][0][RTW89_WW][42] = 76, + [0][0][RTW89_WW][44] = 76, + [0][0][RTW89_WW][45] = 76, + [0][0][RTW89_WW][47] = 76, + [0][0][RTW89_WW][49] = 76, + [0][0][RTW89_WW][51] = 76, + [0][0][RTW89_WW][53] = 76, + [0][0][RTW89_WW][55] = 76, + [0][0][RTW89_WW][57] = 76, + [0][0][RTW89_WW][59] = 76, + [0][0][RTW89_WW][60] = 76, + [0][0][RTW89_WW][62] = 76, + [0][0][RTW89_WW][64] = 76, + [0][0][RTW89_WW][66] = 76, + [0][0][RTW89_WW][68] = 76, + [0][0][RTW89_WW][70] = 76, + [0][0][RTW89_WW][72] = 76, + [0][0][RTW89_WW][74] = 76, + [0][0][RTW89_WW][75] = 76, + [0][0][RTW89_WW][77] = 76, + [0][0][RTW89_WW][79] = 76, + [0][0][RTW89_WW][81] = 76, + [0][0][RTW89_WW][83] = 76, + [0][0][RTW89_WW][85] = 76, + [0][0][RTW89_WW][87] = 76, + [0][0][RTW89_WW][89] = 76, + [0][0][RTW89_WW][90] = 76, + [0][0][RTW89_WW][92] = 76, + [0][0][RTW89_WW][94] = 76, + [0][0][RTW89_WW][96] = 76, + [0][0][RTW89_WW][98] = 76, + [0][0][RTW89_WW][100] = 76, + [0][0][RTW89_WW][102] = 76, + [0][0][RTW89_WW][104] = 76, + [0][0][RTW89_WW][105] = 76, + [0][0][RTW89_WW][107] = 76, + [0][0][RTW89_WW][109] = 76, + [0][0][RTW89_WW][111] = 0, + [0][0][RTW89_WW][113] = 0, + [0][0][RTW89_WW][115] = 0, + [0][0][RTW89_WW][117] = 0, + [0][0][RTW89_WW][119] = 0, + [0][1][RTW89_WW][0] = 76, + [0][1][RTW89_WW][2] = 76, + [0][1][RTW89_WW][4] = 76, + [0][1][RTW89_WW][6] = 76, + [0][1][RTW89_WW][8] = 76, + [0][1][RTW89_WW][10] = 76, + [0][1][RTW89_WW][12] = 76, + [0][1][RTW89_WW][14] = 76, + [0][1][RTW89_WW][15] = 76, + [0][1][RTW89_WW][17] = 76, + [0][1][RTW89_WW][19] = 76, + [0][1][RTW89_WW][21] = 76, + [0][1][RTW89_WW][23] = 76, + [0][1][RTW89_WW][25] = 76, + [0][1][RTW89_WW][27] = 76, + [0][1][RTW89_WW][29] = 76, + [0][1][RTW89_WW][30] = 76, + [0][1][RTW89_WW][32] = 76, + [0][1][RTW89_WW][34] = 76, + [0][1][RTW89_WW][36] = 76, + [0][1][RTW89_WW][38] = 76, + [0][1][RTW89_WW][40] = 76, + [0][1][RTW89_WW][42] = 76, + [0][1][RTW89_WW][44] = 76, + [0][1][RTW89_WW][45] = 76, + [0][1][RTW89_WW][47] = 76, + [0][1][RTW89_WW][49] = 76, + [0][1][RTW89_WW][51] = 76, + [0][1][RTW89_WW][53] = 76, + [0][1][RTW89_WW][55] = 76, + [0][1][RTW89_WW][57] = 76, + [0][1][RTW89_WW][59] = 76, + [0][1][RTW89_WW][60] = 76, + [0][1][RTW89_WW][62] = 76, + [0][1][RTW89_WW][64] = 76, + [0][1][RTW89_WW][66] = 76, + [0][1][RTW89_WW][68] = 76, + [0][1][RTW89_WW][70] = 76, + [0][1][RTW89_WW][72] = 76, + [0][1][RTW89_WW][74] = 76, + [0][1][RTW89_WW][75] = 76, + [0][1][RTW89_WW][77] = 76, + [0][1][RTW89_WW][79] = 76, + [0][1][RTW89_WW][81] = 76, + [0][1][RTW89_WW][83] = 76, + [0][1][RTW89_WW][85] = 76, + [0][1][RTW89_WW][87] = 76, + [0][1][RTW89_WW][89] = 76, + [0][1][RTW89_WW][90] = 76, + [0][1][RTW89_WW][92] = 76, + [0][1][RTW89_WW][94] = 76, + [0][1][RTW89_WW][96] = 76, + [0][1][RTW89_WW][98] = 76, + [0][1][RTW89_WW][100] = 76, + [0][1][RTW89_WW][102] = 76, + [0][1][RTW89_WW][104] = 76, + [0][1][RTW89_WW][105] = 76, + [0][1][RTW89_WW][107] = 76, + [0][1][RTW89_WW][109] = 76, + [0][1][RTW89_WW][111] = 0, + [0][1][RTW89_WW][113] = 0, + [0][1][RTW89_WW][115] = 0, + [0][1][RTW89_WW][117] = 0, + [0][1][RTW89_WW][119] = 0, + [1][0][RTW89_WW][0] = 76, + [1][0][RTW89_WW][2] = 76, + [1][0][RTW89_WW][4] = 76, + [1][0][RTW89_WW][6] = 76, + [1][0][RTW89_WW][8] = 76, + [1][0][RTW89_WW][10] = 76, + [1][0][RTW89_WW][12] = 76, + [1][0][RTW89_WW][14] = 76, + [1][0][RTW89_WW][15] = 76, + [1][0][RTW89_WW][17] = 76, + [1][0][RTW89_WW][19] = 76, + [1][0][RTW89_WW][21] = 76, + [1][0][RTW89_WW][23] = 76, + [1][0][RTW89_WW][25] = 76, + [1][0][RTW89_WW][27] = 76, + [1][0][RTW89_WW][29] = 76, + [1][0][RTW89_WW][30] = 76, + [1][0][RTW89_WW][32] = 76, + [1][0][RTW89_WW][34] = 76, + [1][0][RTW89_WW][36] = 76, + [1][0][RTW89_WW][38] = 76, + [1][0][RTW89_WW][40] = 76, + [1][0][RTW89_WW][42] = 76, + [1][0][RTW89_WW][44] = 76, + [1][0][RTW89_WW][45] = 76, + [1][0][RTW89_WW][47] = 76, + [1][0][RTW89_WW][49] = 76, + [1][0][RTW89_WW][51] = 76, + [1][0][RTW89_WW][53] = 76, + [1][0][RTW89_WW][55] = 76, + [1][0][RTW89_WW][57] = 76, + [1][0][RTW89_WW][59] = 76, + [1][0][RTW89_WW][60] = 76, + [1][0][RTW89_WW][62] = 76, + [1][0][RTW89_WW][64] = 76, + [1][0][RTW89_WW][66] = 76, + [1][0][RTW89_WW][68] = 76, + [1][0][RTW89_WW][70] = 76, + [1][0][RTW89_WW][72] = 76, + [1][0][RTW89_WW][74] = 76, + [1][0][RTW89_WW][75] = 76, + [1][0][RTW89_WW][77] = 76, + [1][0][RTW89_WW][79] = 76, + [1][0][RTW89_WW][81] = 76, + [1][0][RTW89_WW][83] = 76, + [1][0][RTW89_WW][85] = 76, + [1][0][RTW89_WW][87] = 76, + [1][0][RTW89_WW][89] = 76, + [1][0][RTW89_WW][90] = 76, + [1][0][RTW89_WW][92] = 76, + [1][0][RTW89_WW][94] = 76, + [1][0][RTW89_WW][96] = 76, + [1][0][RTW89_WW][98] = 76, + [1][0][RTW89_WW][100] = 76, + [1][0][RTW89_WW][102] = 76, + [1][0][RTW89_WW][104] = 76, + [1][0][RTW89_WW][105] = 76, + [1][0][RTW89_WW][107] = 76, + [1][0][RTW89_WW][109] = 76, + [1][0][RTW89_WW][111] = 0, + [1][0][RTW89_WW][113] = 0, + [1][0][RTW89_WW][115] = 0, + [1][0][RTW89_WW][117] = 0, + [1][0][RTW89_WW][119] = 0, + [1][1][RTW89_WW][0] = 76, + [1][1][RTW89_WW][2] = 76, + [1][1][RTW89_WW][4] = 76, + [1][1][RTW89_WW][6] = 76, + [1][1][RTW89_WW][8] = 76, + [1][1][RTW89_WW][10] = 76, + [1][1][RTW89_WW][12] = 76, + [1][1][RTW89_WW][14] = 76, + [1][1][RTW89_WW][15] = 76, + [1][1][RTW89_WW][17] = 76, + [1][1][RTW89_WW][19] = 76, + [1][1][RTW89_WW][21] = 76, + [1][1][RTW89_WW][23] = 76, + [1][1][RTW89_WW][25] = 76, + [1][1][RTW89_WW][27] = 76, + [1][1][RTW89_WW][29] = 76, + [1][1][RTW89_WW][30] = 76, + [1][1][RTW89_WW][32] = 76, + [1][1][RTW89_WW][34] = 76, + [1][1][RTW89_WW][36] = 76, + [1][1][RTW89_WW][38] = 76, + [1][1][RTW89_WW][40] = 76, + [1][1][RTW89_WW][42] = 76, + [1][1][RTW89_WW][44] = 76, + [1][1][RTW89_WW][45] = 76, + [1][1][RTW89_WW][47] = 76, + [1][1][RTW89_WW][49] = 76, + [1][1][RTW89_WW][51] = 76, + [1][1][RTW89_WW][53] = 76, + [1][1][RTW89_WW][55] = 76, + [1][1][RTW89_WW][57] = 76, + [1][1][RTW89_WW][59] = 76, + [1][1][RTW89_WW][60] = 76, + [1][1][RTW89_WW][62] = 76, + [1][1][RTW89_WW][64] = 76, + [1][1][RTW89_WW][66] = 76, + [1][1][RTW89_WW][68] = 76, + [1][1][RTW89_WW][70] = 76, + [1][1][RTW89_WW][72] = 76, + [1][1][RTW89_WW][74] = 76, + [1][1][RTW89_WW][75] = 76, + [1][1][RTW89_WW][77] = 76, + [1][1][RTW89_WW][79] = 76, + [1][1][RTW89_WW][81] = 76, + [1][1][RTW89_WW][83] = 76, + [1][1][RTW89_WW][85] = 76, + [1][1][RTW89_WW][87] = 76, + [1][1][RTW89_WW][89] = 76, + [1][1][RTW89_WW][90] = 76, + [1][1][RTW89_WW][92] = 76, + [1][1][RTW89_WW][94] = 76, + [1][1][RTW89_WW][96] = 76, + [1][1][RTW89_WW][98] = 76, + [1][1][RTW89_WW][100] = 76, + [1][1][RTW89_WW][102] = 76, + [1][1][RTW89_WW][104] = 76, + [1][1][RTW89_WW][105] = 76, + [1][1][RTW89_WW][107] = 76, + [1][1][RTW89_WW][109] = 76, + [1][1][RTW89_WW][111] = 0, + [1][1][RTW89_WW][113] = 0, + [1][1][RTW89_WW][115] = 0, + [1][1][RTW89_WW][117] = 0, + [1][1][RTW89_WW][119] = 0, + [2][0][RTW89_WW][0] = 76, + [2][0][RTW89_WW][2] = 76, + [2][0][RTW89_WW][4] = 76, + [2][0][RTW89_WW][6] = 76, + [2][0][RTW89_WW][8] = 76, + [2][0][RTW89_WW][10] = 76, + [2][0][RTW89_WW][12] = 76, + [2][0][RTW89_WW][14] = 76, + [2][0][RTW89_WW][15] = 76, + [2][0][RTW89_WW][17] = 76, + [2][0][RTW89_WW][19] = 76, + [2][0][RTW89_WW][21] = 76, + [2][0][RTW89_WW][23] = 76, + [2][0][RTW89_WW][25] = 76, + [2][0][RTW89_WW][27] = 76, + [2][0][RTW89_WW][29] = 76, + [2][0][RTW89_WW][30] = 76, + [2][0][RTW89_WW][32] = 76, + [2][0][RTW89_WW][34] = 76, + [2][0][RTW89_WW][36] = 76, + [2][0][RTW89_WW][38] = 76, + [2][0][RTW89_WW][40] = 76, + [2][0][RTW89_WW][42] = 76, + [2][0][RTW89_WW][44] = 76, + [2][0][RTW89_WW][45] = 76, + [2][0][RTW89_WW][47] = 76, + [2][0][RTW89_WW][49] = 76, + [2][0][RTW89_WW][51] = 76, + [2][0][RTW89_WW][53] = 76, + [2][0][RTW89_WW][55] = 76, + [2][0][RTW89_WW][57] = 76, + [2][0][RTW89_WW][59] = 76, + [2][0][RTW89_WW][60] = 76, + [2][0][RTW89_WW][62] = 76, + [2][0][RTW89_WW][64] = 76, + [2][0][RTW89_WW][66] = 76, + [2][0][RTW89_WW][68] = 76, + [2][0][RTW89_WW][70] = 76, + [2][0][RTW89_WW][72] = 76, + [2][0][RTW89_WW][74] = 76, + [2][0][RTW89_WW][75] = 76, + [2][0][RTW89_WW][77] = 76, + [2][0][RTW89_WW][79] = 76, + [2][0][RTW89_WW][81] = 76, + [2][0][RTW89_WW][83] = 76, + [2][0][RTW89_WW][85] = 76, + [2][0][RTW89_WW][87] = 76, + [2][0][RTW89_WW][89] = 76, + [2][0][RTW89_WW][90] = 76, + [2][0][RTW89_WW][92] = 76, + [2][0][RTW89_WW][94] = 76, + [2][0][RTW89_WW][96] = 76, + [2][0][RTW89_WW][98] = 76, + [2][0][RTW89_WW][100] = 76, + [2][0][RTW89_WW][102] = 76, + [2][0][RTW89_WW][104] = 76, + [2][0][RTW89_WW][105] = 76, + [2][0][RTW89_WW][107] = 76, + [2][0][RTW89_WW][109] = 76, + [2][0][RTW89_WW][111] = 0, + [2][0][RTW89_WW][113] = 0, + [2][0][RTW89_WW][115] = 0, + [2][0][RTW89_WW][117] = 0, + [2][0][RTW89_WW][119] = 0, + [2][1][RTW89_WW][0] = 76, + [2][1][RTW89_WW][2] = 76, + [2][1][RTW89_WW][4] = 76, + [2][1][RTW89_WW][6] = 76, + [2][1][RTW89_WW][8] = 76, + [2][1][RTW89_WW][10] = 76, + [2][1][RTW89_WW][12] = 76, + [2][1][RTW89_WW][14] = 76, + [2][1][RTW89_WW][15] = 76, + [2][1][RTW89_WW][17] = 76, + [2][1][RTW89_WW][19] = 76, + [2][1][RTW89_WW][21] = 76, + [2][1][RTW89_WW][23] = 76, + [2][1][RTW89_WW][25] = 76, + [2][1][RTW89_WW][27] = 76, + [2][1][RTW89_WW][29] = 76, + [2][1][RTW89_WW][30] = 76, + [2][1][RTW89_WW][32] = 76, + [2][1][RTW89_WW][34] = 76, + [2][1][RTW89_WW][36] = 76, + [2][1][RTW89_WW][38] = 76, + [2][1][RTW89_WW][40] = 76, + [2][1][RTW89_WW][42] = 76, + [2][1][RTW89_WW][44] = 76, + [2][1][RTW89_WW][45] = 76, + [2][1][RTW89_WW][47] = 76, + [2][1][RTW89_WW][49] = 76, + [2][1][RTW89_WW][51] = 76, + [2][1][RTW89_WW][53] = 76, + [2][1][RTW89_WW][55] = 76, + [2][1][RTW89_WW][57] = 76, + [2][1][RTW89_WW][59] = 76, + [2][1][RTW89_WW][60] = 76, + [2][1][RTW89_WW][62] = 76, + [2][1][RTW89_WW][64] = 76, + [2][1][RTW89_WW][66] = 76, + [2][1][RTW89_WW][68] = 76, + [2][1][RTW89_WW][70] = 76, + [2][1][RTW89_WW][72] = 76, + [2][1][RTW89_WW][74] = 76, + [2][1][RTW89_WW][75] = 76, + [2][1][RTW89_WW][77] = 76, + [2][1][RTW89_WW][79] = 76, + [2][1][RTW89_WW][81] = 76, + [2][1][RTW89_WW][83] = 76, + [2][1][RTW89_WW][85] = 76, + [2][1][RTW89_WW][87] = 76, + [2][1][RTW89_WW][89] = 76, + [2][1][RTW89_WW][90] = 76, + [2][1][RTW89_WW][92] = 76, + [2][1][RTW89_WW][94] = 76, + [2][1][RTW89_WW][96] = 76, + [2][1][RTW89_WW][98] = 76, + [2][1][RTW89_WW][100] = 76, + [2][1][RTW89_WW][102] = 76, + [2][1][RTW89_WW][104] = 76, + [2][1][RTW89_WW][105] = 76, + [2][1][RTW89_WW][107] = 76, + [2][1][RTW89_WW][109] = 76, + [2][1][RTW89_WW][111] = 0, + [2][1][RTW89_WW][113] = 0, + [2][1][RTW89_WW][115] = 0, + [2][1][RTW89_WW][117] = 0, + [2][1][RTW89_WW][119] = 0, + [0][0][RTW89_FCC][0] = 76, + [0][0][RTW89_FCC][2] = 76, + [0][0][RTW89_FCC][4] = 76, + [0][0][RTW89_FCC][6] = 76, + [0][0][RTW89_FCC][8] = 76, + [0][0][RTW89_FCC][10] = 76, + [0][0][RTW89_FCC][12] = 76, + [0][0][RTW89_FCC][14] = 76, + [0][0][RTW89_FCC][15] = 76, + [0][0][RTW89_FCC][17] = 76, + [0][0][RTW89_FCC][19] = 76, + [0][0][RTW89_FCC][21] = 76, + [0][0][RTW89_FCC][23] = 76, + [0][0][RTW89_FCC][25] = 76, + [0][0][RTW89_FCC][27] = 76, + [0][0][RTW89_FCC][29] = 76, + [0][0][RTW89_FCC][30] = 76, + [0][0][RTW89_FCC][32] = 76, + [0][0][RTW89_FCC][34] = 76, + [0][0][RTW89_FCC][36] = 76, + [0][0][RTW89_FCC][38] = 76, + [0][0][RTW89_FCC][40] = 76, + [0][0][RTW89_FCC][42] = 76, + [0][0][RTW89_FCC][44] = 76, + [0][0][RTW89_FCC][45] = 76, + [0][0][RTW89_FCC][47] = 76, + [0][0][RTW89_FCC][49] = 76, + [0][0][RTW89_FCC][51] = 76, + [0][0][RTW89_FCC][53] = 76, + [0][0][RTW89_FCC][55] = 76, + [0][0][RTW89_FCC][57] = 76, + [0][0][RTW89_FCC][59] = 76, + [0][0][RTW89_FCC][60] = 76, + [0][0][RTW89_FCC][62] = 76, + [0][0][RTW89_FCC][64] = 76, + [0][0][RTW89_FCC][66] = 76, + [0][0][RTW89_FCC][68] = 76, + [0][0][RTW89_FCC][70] = 76, + [0][0][RTW89_FCC][72] = 76, + [0][0][RTW89_FCC][74] = 76, + [0][0][RTW89_FCC][75] = 76, + [0][0][RTW89_FCC][77] = 76, + [0][0][RTW89_FCC][79] = 76, + [0][0][RTW89_FCC][81] = 76, + [0][0][RTW89_FCC][83] = 76, + [0][0][RTW89_FCC][85] = 76, + [0][0][RTW89_FCC][87] = 76, + [0][0][RTW89_FCC][89] = 76, + [0][0][RTW89_FCC][90] = 76, + [0][0][RTW89_FCC][92] = 76, + [0][0][RTW89_FCC][94] = 76, + [0][0][RTW89_FCC][96] = 76, + [0][0][RTW89_FCC][98] = 76, + [0][0][RTW89_FCC][100] = 76, + [0][0][RTW89_FCC][102] = 76, + [0][0][RTW89_FCC][104] = 76, + [0][0][RTW89_FCC][105] = 76, + [0][0][RTW89_FCC][107] = 76, + [0][0][RTW89_FCC][109] = 76, + [0][0][RTW89_FCC][111] = 127, + [0][0][RTW89_FCC][113] = 127, + [0][0][RTW89_FCC][115] = 127, + [0][0][RTW89_FCC][117] = 127, + [0][0][RTW89_FCC][119] = 127, + [0][1][RTW89_FCC][0] = 76, + [0][1][RTW89_FCC][2] = 76, + [0][1][RTW89_FCC][4] = 76, + [0][1][RTW89_FCC][6] = 76, + [0][1][RTW89_FCC][8] = 76, + [0][1][RTW89_FCC][10] = 76, + [0][1][RTW89_FCC][12] = 76, + [0][1][RTW89_FCC][14] = 76, + [0][1][RTW89_FCC][15] = 76, + [0][1][RTW89_FCC][17] = 76, + [0][1][RTW89_FCC][19] = 76, + [0][1][RTW89_FCC][21] = 76, + [0][1][RTW89_FCC][23] = 76, + [0][1][RTW89_FCC][25] = 76, + [0][1][RTW89_FCC][27] = 76, + [0][1][RTW89_FCC][29] = 76, + [0][1][RTW89_FCC][30] = 76, + [0][1][RTW89_FCC][32] = 76, + [0][1][RTW89_FCC][34] = 76, + [0][1][RTW89_FCC][36] = 76, + [0][1][RTW89_FCC][38] = 76, + [0][1][RTW89_FCC][40] = 76, + [0][1][RTW89_FCC][42] = 76, + [0][1][RTW89_FCC][44] = 76, + [0][1][RTW89_FCC][45] = 76, + [0][1][RTW89_FCC][47] = 76, + [0][1][RTW89_FCC][49] = 76, + [0][1][RTW89_FCC][51] = 76, + [0][1][RTW89_FCC][53] = 76, + [0][1][RTW89_FCC][55] = 76, + [0][1][RTW89_FCC][57] = 76, + [0][1][RTW89_FCC][59] = 76, + [0][1][RTW89_FCC][60] = 76, + [0][1][RTW89_FCC][62] = 76, + [0][1][RTW89_FCC][64] = 76, + [0][1][RTW89_FCC][66] = 76, + [0][1][RTW89_FCC][68] = 76, + [0][1][RTW89_FCC][70] = 76, + [0][1][RTW89_FCC][72] = 76, + [0][1][RTW89_FCC][74] = 76, + [0][1][RTW89_FCC][75] = 76, + [0][1][RTW89_FCC][77] = 76, + [0][1][RTW89_FCC][79] = 76, + [0][1][RTW89_FCC][81] = 76, + [0][1][RTW89_FCC][83] = 76, + [0][1][RTW89_FCC][85] = 76, + [0][1][RTW89_FCC][87] = 76, + [0][1][RTW89_FCC][89] = 76, + [0][1][RTW89_FCC][90] = 76, + [0][1][RTW89_FCC][92] = 76, + [0][1][RTW89_FCC][94] = 76, + [0][1][RTW89_FCC][96] = 76, + [0][1][RTW89_FCC][98] = 76, + [0][1][RTW89_FCC][100] = 76, + [0][1][RTW89_FCC][102] = 76, + [0][1][RTW89_FCC][104] = 76, + [0][1][RTW89_FCC][105] = 76, + [0][1][RTW89_FCC][107] = 76, + [0][1][RTW89_FCC][109] = 76, + [0][1][RTW89_FCC][111] = 127, + [0][1][RTW89_FCC][113] = 127, + [0][1][RTW89_FCC][115] = 127, + [0][1][RTW89_FCC][117] = 127, + [0][1][RTW89_FCC][119] = 127, + [1][0][RTW89_FCC][0] = 76, + [1][0][RTW89_FCC][2] = 76, + [1][0][RTW89_FCC][4] = 76, + [1][0][RTW89_FCC][6] = 76, + [1][0][RTW89_FCC][8] = 76, + [1][0][RTW89_FCC][10] = 76, + [1][0][RTW89_FCC][12] = 76, + [1][0][RTW89_FCC][14] = 76, + [1][0][RTW89_FCC][15] = 76, + [1][0][RTW89_FCC][17] = 76, + [1][0][RTW89_FCC][19] = 76, + [1][0][RTW89_FCC][21] = 76, + [1][0][RTW89_FCC][23] = 76, + [1][0][RTW89_FCC][25] = 76, + [1][0][RTW89_FCC][27] = 76, + [1][0][RTW89_FCC][29] = 76, + [1][0][RTW89_FCC][30] = 76, + [1][0][RTW89_FCC][32] = 76, + [1][0][RTW89_FCC][34] = 76, + [1][0][RTW89_FCC][36] = 76, + [1][0][RTW89_FCC][38] = 76, + [1][0][RTW89_FCC][40] = 76, + [1][0][RTW89_FCC][42] = 76, + [1][0][RTW89_FCC][44] = 76, + [1][0][RTW89_FCC][45] = 76, + [1][0][RTW89_FCC][47] = 76, + [1][0][RTW89_FCC][49] = 76, + [1][0][RTW89_FCC][51] = 76, + [1][0][RTW89_FCC][53] = 76, + [1][0][RTW89_FCC][55] = 76, + [1][0][RTW89_FCC][57] = 76, + [1][0][RTW89_FCC][59] = 76, + [1][0][RTW89_FCC][60] = 76, + [1][0][RTW89_FCC][62] = 76, + [1][0][RTW89_FCC][64] = 76, + [1][0][RTW89_FCC][66] = 76, + [1][0][RTW89_FCC][68] = 76, + [1][0][RTW89_FCC][70] = 76, + [1][0][RTW89_FCC][72] = 76, + [1][0][RTW89_FCC][74] = 76, + [1][0][RTW89_FCC][75] = 76, + [1][0][RTW89_FCC][77] = 76, + [1][0][RTW89_FCC][79] = 76, + [1][0][RTW89_FCC][81] = 76, + [1][0][RTW89_FCC][83] = 76, + [1][0][RTW89_FCC][85] = 76, + [1][0][RTW89_FCC][87] = 76, + [1][0][RTW89_FCC][89] = 76, + [1][0][RTW89_FCC][90] = 76, + [1][0][RTW89_FCC][92] = 76, + [1][0][RTW89_FCC][94] = 76, + [1][0][RTW89_FCC][96] = 76, + [1][0][RTW89_FCC][98] = 76, + [1][0][RTW89_FCC][100] = 76, + [1][0][RTW89_FCC][102] = 76, + [1][0][RTW89_FCC][104] = 76, + [1][0][RTW89_FCC][105] = 76, + [1][0][RTW89_FCC][107] = 76, + [1][0][RTW89_FCC][109] = 76, + [1][0][RTW89_FCC][111] = 127, + [1][0][RTW89_FCC][113] = 127, + [1][0][RTW89_FCC][115] = 127, + [1][0][RTW89_FCC][117] = 127, + [1][0][RTW89_FCC][119] = 127, + [1][1][RTW89_FCC][0] = 76, + [1][1][RTW89_FCC][2] = 76, + [1][1][RTW89_FCC][4] = 76, + [1][1][RTW89_FCC][6] = 76, + [1][1][RTW89_FCC][8] = 76, + [1][1][RTW89_FCC][10] = 76, + [1][1][RTW89_FCC][12] = 76, + [1][1][RTW89_FCC][14] = 76, + [1][1][RTW89_FCC][15] = 76, + [1][1][RTW89_FCC][17] = 76, + [1][1][RTW89_FCC][19] = 76, + [1][1][RTW89_FCC][21] = 76, + [1][1][RTW89_FCC][23] = 76, + [1][1][RTW89_FCC][25] = 76, + [1][1][RTW89_FCC][27] = 76, + [1][1][RTW89_FCC][29] = 76, + [1][1][RTW89_FCC][30] = 76, + [1][1][RTW89_FCC][32] = 76, + [1][1][RTW89_FCC][34] = 76, + [1][1][RTW89_FCC][36] = 76, + [1][1][RTW89_FCC][38] = 76, + [1][1][RTW89_FCC][40] = 76, + [1][1][RTW89_FCC][42] = 76, + [1][1][RTW89_FCC][44] = 76, + [1][1][RTW89_FCC][45] = 76, + [1][1][RTW89_FCC][47] = 76, + [1][1][RTW89_FCC][49] = 76, + [1][1][RTW89_FCC][51] = 76, + [1][1][RTW89_FCC][53] = 76, + [1][1][RTW89_FCC][55] = 76, + [1][1][RTW89_FCC][57] = 76, + [1][1][RTW89_FCC][59] = 76, + [1][1][RTW89_FCC][60] = 76, + [1][1][RTW89_FCC][62] = 76, + [1][1][RTW89_FCC][64] = 76, + [1][1][RTW89_FCC][66] = 76, + [1][1][RTW89_FCC][68] = 76, + [1][1][RTW89_FCC][70] = 76, + [1][1][RTW89_FCC][72] = 76, + [1][1][RTW89_FCC][74] = 76, + [1][1][RTW89_FCC][75] = 76, + [1][1][RTW89_FCC][77] = 76, + [1][1][RTW89_FCC][79] = 76, + [1][1][RTW89_FCC][81] = 76, + [1][1][RTW89_FCC][83] = 76, + [1][1][RTW89_FCC][85] = 76, + [1][1][RTW89_FCC][87] = 76, + [1][1][RTW89_FCC][89] = 76, + [1][1][RTW89_FCC][90] = 76, + [1][1][RTW89_FCC][92] = 76, + [1][1][RTW89_FCC][94] = 76, + [1][1][RTW89_FCC][96] = 76, + [1][1][RTW89_FCC][98] = 76, + [1][1][RTW89_FCC][100] = 76, + [1][1][RTW89_FCC][102] = 76, + [1][1][RTW89_FCC][104] = 76, + [1][1][RTW89_FCC][105] = 76, + [1][1][RTW89_FCC][107] = 76, + [1][1][RTW89_FCC][109] = 76, + [1][1][RTW89_FCC][111] = 127, + [1][1][RTW89_FCC][113] = 127, + [1][1][RTW89_FCC][115] = 127, + [1][1][RTW89_FCC][117] = 127, + [1][1][RTW89_FCC][119] = 127, + [2][0][RTW89_FCC][0] = 76, + [2][0][RTW89_FCC][2] = 76, + [2][0][RTW89_FCC][4] = 76, + [2][0][RTW89_FCC][6] = 76, + [2][0][RTW89_FCC][8] = 76, + [2][0][RTW89_FCC][10] = 76, + [2][0][RTW89_FCC][12] = 76, + [2][0][RTW89_FCC][14] = 76, + [2][0][RTW89_FCC][15] = 76, + [2][0][RTW89_FCC][17] = 76, + [2][0][RTW89_FCC][19] = 76, + [2][0][RTW89_FCC][21] = 76, + [2][0][RTW89_FCC][23] = 76, + [2][0][RTW89_FCC][25] = 76, + [2][0][RTW89_FCC][27] = 76, + [2][0][RTW89_FCC][29] = 76, + [2][0][RTW89_FCC][30] = 76, + [2][0][RTW89_FCC][32] = 76, + [2][0][RTW89_FCC][34] = 76, + [2][0][RTW89_FCC][36] = 76, + [2][0][RTW89_FCC][38] = 76, + [2][0][RTW89_FCC][40] = 76, + [2][0][RTW89_FCC][42] = 76, + [2][0][RTW89_FCC][44] = 76, + [2][0][RTW89_FCC][45] = 76, + [2][0][RTW89_FCC][47] = 76, + [2][0][RTW89_FCC][49] = 76, + [2][0][RTW89_FCC][51] = 76, + [2][0][RTW89_FCC][53] = 76, + [2][0][RTW89_FCC][55] = 76, + [2][0][RTW89_FCC][57] = 76, + [2][0][RTW89_FCC][59] = 76, + [2][0][RTW89_FCC][60] = 76, + [2][0][RTW89_FCC][62] = 76, + [2][0][RTW89_FCC][64] = 76, + [2][0][RTW89_FCC][66] = 76, + [2][0][RTW89_FCC][68] = 76, + [2][0][RTW89_FCC][70] = 76, + [2][0][RTW89_FCC][72] = 76, + [2][0][RTW89_FCC][74] = 76, + [2][0][RTW89_FCC][75] = 76, + [2][0][RTW89_FCC][77] = 76, + [2][0][RTW89_FCC][79] = 76, + [2][0][RTW89_FCC][81] = 76, + [2][0][RTW89_FCC][83] = 76, + [2][0][RTW89_FCC][85] = 76, + [2][0][RTW89_FCC][87] = 76, + [2][0][RTW89_FCC][89] = 76, + [2][0][RTW89_FCC][90] = 76, + [2][0][RTW89_FCC][92] = 76, + [2][0][RTW89_FCC][94] = 76, + [2][0][RTW89_FCC][96] = 76, + [2][0][RTW89_FCC][98] = 76, + [2][0][RTW89_FCC][100] = 76, + [2][0][RTW89_FCC][102] = 76, + [2][0][RTW89_FCC][104] = 76, + [2][0][RTW89_FCC][105] = 76, + [2][0][RTW89_FCC][107] = 76, + [2][0][RTW89_FCC][109] = 76, + [2][0][RTW89_FCC][111] = 127, + [2][0][RTW89_FCC][113] = 127, + [2][0][RTW89_FCC][115] = 127, + [2][0][RTW89_FCC][117] = 127, + [2][0][RTW89_FCC][119] = 127, + [2][1][RTW89_FCC][0] = 76, + [2][1][RTW89_FCC][2] = 76, + [2][1][RTW89_FCC][4] = 76, + [2][1][RTW89_FCC][6] = 76, + [2][1][RTW89_FCC][8] = 76, + [2][1][RTW89_FCC][10] = 76, + [2][1][RTW89_FCC][12] = 76, + [2][1][RTW89_FCC][14] = 76, + [2][1][RTW89_FCC][15] = 76, + [2][1][RTW89_FCC][17] = 76, + [2][1][RTW89_FCC][19] = 76, + [2][1][RTW89_FCC][21] = 76, + [2][1][RTW89_FCC][23] = 76, + [2][1][RTW89_FCC][25] = 76, + [2][1][RTW89_FCC][27] = 76, + [2][1][RTW89_FCC][29] = 76, + [2][1][RTW89_FCC][30] = 76, + [2][1][RTW89_FCC][32] = 76, + [2][1][RTW89_FCC][34] = 76, + [2][1][RTW89_FCC][36] = 76, + [2][1][RTW89_FCC][38] = 76, + [2][1][RTW89_FCC][40] = 76, + [2][1][RTW89_FCC][42] = 76, + [2][1][RTW89_FCC][44] = 76, + [2][1][RTW89_FCC][45] = 76, + [2][1][RTW89_FCC][47] = 76, + [2][1][RTW89_FCC][49] = 76, + [2][1][RTW89_FCC][51] = 76, + [2][1][RTW89_FCC][53] = 76, + [2][1][RTW89_FCC][55] = 76, + [2][1][RTW89_FCC][57] = 76, + [2][1][RTW89_FCC][59] = 76, + [2][1][RTW89_FCC][60] = 76, + [2][1][RTW89_FCC][62] = 76, + [2][1][RTW89_FCC][64] = 76, + [2][1][RTW89_FCC][66] = 76, + [2][1][RTW89_FCC][68] = 76, + [2][1][RTW89_FCC][70] = 76, + [2][1][RTW89_FCC][72] = 76, + [2][1][RTW89_FCC][74] = 76, + [2][1][RTW89_FCC][75] = 76, + [2][1][RTW89_FCC][77] = 76, + [2][1][RTW89_FCC][79] = 76, + [2][1][RTW89_FCC][81] = 76, + [2][1][RTW89_FCC][83] = 76, + [2][1][RTW89_FCC][85] = 76, + [2][1][RTW89_FCC][87] = 76, + [2][1][RTW89_FCC][89] = 76, + [2][1][RTW89_FCC][90] = 76, + [2][1][RTW89_FCC][92] = 76, + [2][1][RTW89_FCC][94] = 76, + [2][1][RTW89_FCC][96] = 76, + [2][1][RTW89_FCC][98] = 76, + [2][1][RTW89_FCC][100] = 76, + [2][1][RTW89_FCC][102] = 76, + [2][1][RTW89_FCC][104] = 76, + [2][1][RTW89_FCC][105] = 76, + [2][1][RTW89_FCC][107] = 76, + [2][1][RTW89_FCC][109] = 76, + [2][1][RTW89_FCC][111] = 127, + [2][1][RTW89_FCC][113] = 127, + [2][1][RTW89_FCC][115] = 127, + [2][1][RTW89_FCC][117] = 127, + [2][1][RTW89_FCC][119] = 127, +}; + const struct rtw89_phy_table rtw89_8852c_phy_bb_table = { .regs = rtw89_8852c_phy_bb_regs, .n_regs = ARRAY_SIZE(rtw89_8852c_phy_bb_regs), @@ -13695,3 +19316,9 @@ const struct rtw89_phy_table rtw89_8852c_phy_nctl_table = { .n_regs = ARRAY_SIZE(rtw89_8852c_phy_nctl_regs), .rf_path = 0, /* don't care */ }; + +const struct rtw89_txpwr_table rtw89_8852c_byr_table = { + .data = rtw89_8852c_txpwr_byrate, + .size = ARRAY_SIZE(rtw89_8852c_txpwr_byrate), + .load = rtw89_phy_load_txpwr_byrate, +}; diff --git a/drivers/net/wireless/realtek/rtw89/rtw8852c_table.h b/drivers/net/wireless/realtek/rtw89/rtw8852c_table.h index 807021ab9f1da..0c0df2ac8cff7 100644 --- a/drivers/net/wireless/realtek/rtw89/rtw8852c_table.h +++ b/drivers/net/wireless/realtek/rtw89/rtw8852c_table.h @@ -12,5 +12,23 @@ extern const struct rtw89_phy_table rtw89_8852c_phy_bb_gain_table; extern const struct rtw89_phy_table rtw89_8852c_phy_radioa_table; extern const struct rtw89_phy_table rtw89_8852c_phy_radiob_table; extern const struct rtw89_phy_table rtw89_8852c_phy_nctl_table; +extern const struct rtw89_txpwr_table rtw89_8852c_byr_table; +extern const u8 rtw89_8852c_tx_shape[RTW89_BAND_MAX][RTW89_RS_TX_SHAPE_NUM] + [RTW89_REGD_NUM]; +extern const s8 rtw89_8852c_txpwr_lmt_2g[RTW89_2G_BW_NUM][RTW89_NTX_NUM] + [RTW89_RS_LMT_NUM][RTW89_BF_NUM] + [RTW89_REGD_NUM][RTW89_2G_CH_NUM]; +extern const s8 rtw89_8852c_txpwr_lmt_5g[RTW89_5G_BW_NUM][RTW89_NTX_NUM] + [RTW89_RS_LMT_NUM][RTW89_BF_NUM] + [RTW89_REGD_NUM][RTW89_5G_CH_NUM]; +extern const s8 rtw89_8852c_txpwr_lmt_6g[RTW89_6G_BW_NUM][RTW89_NTX_NUM] + [RTW89_RS_LMT_NUM][RTW89_BF_NUM] + [RTW89_REGD_NUM][RTW89_6G_CH_NUM]; +extern const s8 rtw89_8852c_txpwr_lmt_ru_2g[RTW89_RU_NUM][RTW89_NTX_NUM] + [RTW89_REGD_NUM][RTW89_2G_CH_NUM]; +extern const s8 rtw89_8852c_txpwr_lmt_ru_5g[RTW89_RU_NUM][RTW89_NTX_NUM] + [RTW89_REGD_NUM][RTW89_5G_CH_NUM]; +extern const s8 rtw89_8852c_txpwr_lmt_ru_6g[RTW89_RU_NUM][RTW89_NTX_NUM] + [RTW89_REGD_NUM][RTW89_6G_CH_NUM]; #endif From c6badab206d5a2330c896ab1b77d79e80c6f16aa Mon Sep 17 00:00:00 2001 From: Zong-Zhe Yang Date: Thu, 14 Apr 2022 14:20:17 +0800 Subject: [PATCH 155/228] rtw89: 8852c: add TX power track tables TX power track tables are used to do TX power compensation according to thermal value. In order to work in existing and new chip, add new 6G entries, and change type from u8 to s8. Internal version table is HALRF_027_00_031. Signed-off-by: Zong-Zhe Yang Signed-off-by: Ping-Ke Shih Signed-off-by: Kalle Valo Link: https://lore.kernel.org/r/20220414062027.62638-4-pkshih@realtek.com --- drivers/net/wireless/realtek/rtw89/phy.h | 28 ++-- .../net/wireless/realtek/rtw89/rtw8852a_rfk.c | 8 +- .../wireless/realtek/rtw89/rtw8852a_table.c | 24 +-- .../wireless/realtek/rtw89/rtw8852c_table.c | 139 ++++++++++++++++++ .../wireless/realtek/rtw89/rtw8852c_table.h | 1 + 5 files changed, 172 insertions(+), 28 deletions(-) diff --git a/drivers/net/wireless/realtek/rtw89/phy.h b/drivers/net/wireless/realtek/rtw89/phy.h index adcfcb4c24296..9c97e77d97072 100644 --- a/drivers/net/wireless/realtek/rtw89/phy.h +++ b/drivers/net/wireless/realtek/rtw89/phy.h @@ -233,18 +233,22 @@ struct rtw89_txpwr_byrate_cfg { #define DELTA_SWINGIDX_SIZE 30 struct rtw89_txpwr_track_cfg { - const u8 (*delta_swingidx_5gb_n)[DELTA_SWINGIDX_SIZE]; - const u8 (*delta_swingidx_5gb_p)[DELTA_SWINGIDX_SIZE]; - const u8 (*delta_swingidx_5ga_n)[DELTA_SWINGIDX_SIZE]; - const u8 (*delta_swingidx_5ga_p)[DELTA_SWINGIDX_SIZE]; - const u8 *delta_swingidx_2gb_n; - const u8 *delta_swingidx_2gb_p; - const u8 *delta_swingidx_2ga_n; - const u8 *delta_swingidx_2ga_p; - const u8 *delta_swingidx_2g_cck_b_n; - const u8 *delta_swingidx_2g_cck_b_p; - const u8 *delta_swingidx_2g_cck_a_n; - const u8 *delta_swingidx_2g_cck_a_p; + const s8 (*delta_swingidx_6gb_n)[DELTA_SWINGIDX_SIZE]; + const s8 (*delta_swingidx_6gb_p)[DELTA_SWINGIDX_SIZE]; + const s8 (*delta_swingidx_6ga_n)[DELTA_SWINGIDX_SIZE]; + const s8 (*delta_swingidx_6ga_p)[DELTA_SWINGIDX_SIZE]; + const s8 (*delta_swingidx_5gb_n)[DELTA_SWINGIDX_SIZE]; + const s8 (*delta_swingidx_5gb_p)[DELTA_SWINGIDX_SIZE]; + const s8 (*delta_swingidx_5ga_n)[DELTA_SWINGIDX_SIZE]; + const s8 (*delta_swingidx_5ga_p)[DELTA_SWINGIDX_SIZE]; + const s8 *delta_swingidx_2gb_n; + const s8 *delta_swingidx_2gb_p; + const s8 *delta_swingidx_2ga_n; + const s8 *delta_swingidx_2ga_p; + const s8 *delta_swingidx_2g_cck_b_n; + const s8 *delta_swingidx_2g_cck_b_p; + const s8 *delta_swingidx_2g_cck_a_n; + const s8 *delta_swingidx_2g_cck_a_p; }; struct rtw89_phy_dig_gain_cfg { diff --git a/drivers/net/wireless/realtek/rtw89/rtw8852a_rfk.c b/drivers/net/wireless/realtek/rtw89/rtw8852a_rfk.c index ad272854c442f..aa782534e76be 100644 --- a/drivers/net/wireless/realtek/rtw89/rtw8852a_rfk.c +++ b/drivers/net/wireless/realtek/rtw89/rtw8852a_rfk.c @@ -2907,10 +2907,10 @@ static void _tssi_set_tmeter_tbl(struct rtw89_dev *rtwdev, enum rtw89_phy_idx ph struct rtw89_tssi_info *tssi_info = &rtwdev->tssi; u8 ch = rtwdev->hal.current_channel; u8 subband = rtwdev->hal.current_subband; - const u8 *thm_up_a = NULL; - const u8 *thm_down_a = NULL; - const u8 *thm_up_b = NULL; - const u8 *thm_down_b = NULL; + const s8 *thm_up_a = NULL; + const s8 *thm_down_a = NULL; + const s8 *thm_up_b = NULL; + const s8 *thm_down_b = NULL; u8 thermal = 0xff; s8 thm_ofst[64] = {0}; u32 tmp = 0; diff --git a/drivers/net/wireless/realtek/rtw89/rtw8852a_table.c b/drivers/net/wireless/realtek/rtw89/rtw8852a_table.c index 8c4749f106411..99479bbb09399 100644 --- a/drivers/net/wireless/realtek/rtw89/rtw8852a_table.c +++ b/drivers/net/wireless/realtek/rtw89/rtw8852a_table.c @@ -43313,7 +43313,7 @@ static const struct rtw89_txpwr_byrate_cfg rtw89_8852a_txpwr_byrate[] = { { 1, 0, 4, 0, 4, 0x00000000, }, }; -static const u8 _txpwr_track_delta_swingidx_5gb_n[][DELTA_SWINGIDX_SIZE] = { +static const s8 _txpwr_track_delta_swingidx_5gb_n[][DELTA_SWINGIDX_SIZE] = { {0, 1, 1, 2, 2, 2, 3, 3, 3, 4, 4, 5, 5, 5, 6, 6, 7, 7, 7, 8, 8, 9, 9, 9, 10, 10, 10, 11, 11, 11}, {0, 1, 1, 1, 1, 2, 2, 2, 2, 3, 3, 3, 4, 4, 4, 4, @@ -43322,7 +43322,7 @@ static const u8 _txpwr_track_delta_swingidx_5gb_n[][DELTA_SWINGIDX_SIZE] = { 5, 6, 6, 6, 6, 7, 7, 7, 8, 8, 8, 9, 9, 9}, }; -static const u8 _txpwr_track_delta_swingidx_5gb_p[][DELTA_SWINGIDX_SIZE] = { +static const s8 _txpwr_track_delta_swingidx_5gb_p[][DELTA_SWINGIDX_SIZE] = { {0, 1, 1, 1, 2, 2, 3, 3, 3, 4, 4, 4, 5, 5, 6, 6, 6, 7, 7, 7, 8, 8, 8, 9, 9, 10, 10, 10, 11, 11}, {0, 1, 1, 1, 1, 2, 2, 2, 2, 3, 3, 3, 4, 4, 4, 4, @@ -43331,7 +43331,7 @@ static const u8 _txpwr_track_delta_swingidx_5gb_p[][DELTA_SWINGIDX_SIZE] = { 5, 6, 6, 6, 6, 7, 7, 7, 8, 8, 8, 9, 9, 9}, }; -static const u8 _txpwr_track_delta_swingidx_5ga_n[][DELTA_SWINGIDX_SIZE] = { +static const s8 _txpwr_track_delta_swingidx_5ga_n[][DELTA_SWINGIDX_SIZE] = { {0, 1, 1, 2, 2, 2, 3, 3, 3, 4, 4, 5, 5, 5, 6, 6, 7, 7, 7, 8, 8, 9, 9, 9, 10, 10, 10, 11, 11, 11}, {0, 1, 1, 1, 1, 2, 2, 2, 2, 3, 3, 3, 4, 4, 4, 4, @@ -43340,7 +43340,7 @@ static const u8 _txpwr_track_delta_swingidx_5ga_n[][DELTA_SWINGIDX_SIZE] = { 5, 6, 6, 6, 6, 7, 7, 7, 8, 8, 8, 9, 9, 9}, }; -static const u8 _txpwr_track_delta_swingidx_5ga_p[][DELTA_SWINGIDX_SIZE] = { +static const s8 _txpwr_track_delta_swingidx_5ga_p[][DELTA_SWINGIDX_SIZE] = { {0, 1, 1, 1, 2, 2, 3, 3, 3, 4, 4, 4, 5, 5, 6, 6, 6, 7, 7, 7, 8, 8, 8, 9, 9, 10, 10, 10, 11, 11}, {0, 1, 1, 1, 1, 2, 2, 2, 2, 3, 3, 3, 4, 4, 4, 4, @@ -43349,35 +43349,35 @@ static const u8 _txpwr_track_delta_swingidx_5ga_p[][DELTA_SWINGIDX_SIZE] = { 5, 6, 6, 6, 6, 7, 7, 7, 8, 8, 8, 9, 9, 9}, }; -static const u8 _txpwr_track_delta_swingidx_2gb_n[] = { +static const s8 _txpwr_track_delta_swingidx_2gb_n[] = { 0, 1, 1, 1, 1, 1, 2, 2, 2, 2, 3, 3, 3, 3, 3, 4, 4, 4, 4, 5, 5, 5, 5, 5, 6, 6, 6, 6, 7, 7}; -static const u8 _txpwr_track_delta_swingidx_2gb_p[] = { +static const s8 _txpwr_track_delta_swingidx_2gb_p[] = { 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3, 3, 3, 3}; -static const u8 _txpwr_track_delta_swingidx_2ga_n[] = { +static const s8 _txpwr_track_delta_swingidx_2ga_n[] = { 0, 1, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3, 4, 4, 4, 4, 4, 4, 5, 5, 5, 5, 5}; -static const u8 _txpwr_track_delta_swingidx_2ga_p[] = { +static const s8 _txpwr_track_delta_swingidx_2ga_p[] = { 0, 1, 1, 1, 2, 2, 2, 3, 3, 3, 4, 4, 4, 5, 5, 5, 6, 6, 6, 7, 7, 7, 8, 8, 8, 9, 9, 9, 10, 10}; -static const u8 _txpwr_track_delta_swingidx_2g_cck_b_n[] = { +static const s8 _txpwr_track_delta_swingidx_2g_cck_b_n[] = { 0, 1, 1, 1, 1, 1, 2, 2, 2, 2, 3, 3, 3, 3, 3, 4, 4, 4, 4, 5, 5, 5, 5, 5, 6, 6, 6, 6, 7, 7}; -static const u8 _txpwr_track_delta_swingidx_2g_cck_b_p[] = { +static const s8 _txpwr_track_delta_swingidx_2g_cck_b_p[] = { 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3, 3, 3, 3}; -static const u8 _txpwr_track_delta_swingidx_2g_cck_a_n[] = { +static const s8 _txpwr_track_delta_swingidx_2g_cck_a_n[] = { 0, 1, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3, 4, 4, 4, 4, 4, 4, 5, 5, 5, 5, 5}; -static const u8 _txpwr_track_delta_swingidx_2g_cck_a_p[] = { +static const s8 _txpwr_track_delta_swingidx_2g_cck_a_p[] = { 0, 1, 1, 1, 2, 2, 2, 3, 3, 3, 4, 4, 4, 5, 5, 5, 6, 6, 6, 7, 7, 7, 8, 8, 8, 9, 9, 9, 10, 10}; diff --git a/drivers/net/wireless/realtek/rtw89/rtw8852c_table.c b/drivers/net/wireless/realtek/rtw89/rtw8852c_table.c index bd0c4ff5ca4dd..e7852d2861379 100644 --- a/drivers/net/wireless/realtek/rtw89/rtw8852c_table.c +++ b/drivers/net/wireless/realtek/rtw89/rtw8852c_table.c @@ -13702,6 +13702,126 @@ static const struct rtw89_txpwr_byrate_cfg rtw89_8852c_txpwr_byrate[] = { { 2, 0, 4, 0, 4, 0x00000000, }, }; +static const s8 _txpwr_track_delta_swingidx_6gb_n[][DELTA_SWINGIDX_SIZE] = { + {0, 1, 1, 1, 2, 2, 2, 3, 3, 3, 4, 4, 4, 5, 5, 5, + 6, 6, 6, 7, 7, 7, 8, 8, 8, 9, 9, 9, 10, 10}, + {0, 1, 1, 1, 2, 2, 2, 3, 3, 3, 4, 4, 4, 5, 5, 5, + 6, 6, 6, 7, 7, 7, 8, 8, 8, 9, 9, 9, 10, 10}, + {0, 1, 1, 1, 2, 2, 2, 3, 3, 3, 4, 4, 4, 5, 5, 5, + 6, 6, 6, 7, 7, 7, 8, 8, 8, 9, 9, 9, 10, 10}, + {0, 1, 1, 1, 2, 2, 2, 3, 3, 3, 4, 4, 4, 5, 5, 5, + 6, 6, 6, 7, 7, 7, 8, 8, 8, 9, 9, 9, 10, 10}, +}; + +static const s8 _txpwr_track_delta_swingidx_6gb_p[][DELTA_SWINGIDX_SIZE] = { + {0, 1, 2, 2, 3, 3, 4, 5, 5, 6, 6, 7, 8, 8, 9, 9, 10, 11, + 11, 12, 12, 13, 14, 14, 15, 15, 16, 17, 17, 18}, + {0, 1, 1, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7, 7, 8, 9, 9, 10, + 10, 11, 11, 12, 12, 13, 13, 14, 15, 15, 16, 16}, + {0, 1, 1, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7, 7, 8, 9, 9, 10, + 10, 11, 11, 12, 12, 13, 13, 14, 15, 15, 16, 16}, + {0, 1, 1, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7, 7, 8, 9, 9, 10, + 10, 11, 11, 12, 12, 13, 13, 14, 15, 15, 16, 16}, +}; + +static const s8 _txpwr_track_delta_swingidx_6ga_n[][DELTA_SWINGIDX_SIZE] = { + {0, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 3, 3, 3, 3, 3, + 4, 4, 4, 4, 5, 5, 5, 5, 5, 6, 6, 6, 6, 6}, + {0, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 3, 3, 3, 3, 3, + 4, 4, 4, 4, 5, 5, 5, 5, 5, 6, 6, 6, 6, 6}, + {0, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 3, 3, 3, 3, 3, + 4, 4, 4, 4, 5, 5, 5, 5, 5, 6, 6, 6, 6, 6}, + {0, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 3, 3, 3, 3, 3, + 4, 4, 4, 4, 5, 5, 5, 5, 5, 6, 6, 6, 6, 6}, +}; + +static const s8 _txpwr_track_delta_swingidx_6ga_p[][DELTA_SWINGIDX_SIZE] = { + {0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7, 7, 8, 8, + 9, 9, 10, 11, 11, 12, 12, 13, 13, 14, 14, 15, 15}, + {0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7, 7, 8, 8, + 9, 9, 10, 11, 11, 12, 12, 13, 13, 14, 14, 15, 15}, + {0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7, 7, 8, 8, + 9, 9, 10, 11, 11, 12, 12, 13, 13, 14, 14, 15, 15}, + {0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7, 7, 8, 8, + 9, 9, 10, 11, 11, 12, 12, 13, 13, 14, 14, 15, 15}, +}; + +static const s8 _txpwr_track_delta_swingidx_5gb_n[][DELTA_SWINGIDX_SIZE] = { + {0, 1, 1, 1, 2, 2, 2, 3, 3, 3, 4, 4, 4, 5, 5, 5, + 6, 6, 6, 7, 7, 7, 8, 8, 8, 9, 9, 9, 10, 10}, + {0, 1, 1, 1, 1, 2, 2, 2, 3, 3, 3, 3, 4, 4, 4, 4, + 5, 5, 5, 5, 6, 6, 6, 7, 7, 7, 7, 8, 8, 8}, + {0, 1, 1, 2, 2, 2, 3, 3, 4, 4, 4, 5, 5, 6, 6, 6, 7, + 7, 8, 8, 8, 9, 9, 10, 10, 10, 11, 11, 12, 12}, +}; + +static const s8 _txpwr_track_delta_swingidx_5gb_p[][DELTA_SWINGIDX_SIZE] = { + {0, 1, 1, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7, 8, 8, 9, 9, 10, + 10, 11, 11, 12, 13, 13, 14, 14, 15, 15, 16, 16}, + {0, 1, 1, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7, 8, 8, 9, 9, 10, + 10, 11, 11, 12, 13, 13, 14, 14, 15, 15, 16, 16}, + {0, 1, 1, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7, 8, 8, 9, 9, 10, + 10, 11, 11, 12, 13, 13, 14, 14, 15, 15, 16, 16}, +}; + +static const s8 _txpwr_track_delta_swingidx_5ga_n[][DELTA_SWINGIDX_SIZE] = { + {0, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 3, 3, 3, 3, 3, + 4, 4, 4, 4, 5, 5, 5, 5, 5, 6, 6, 6, 6, 6}, + {0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3}, + {0, 1, 1, 1, 1, 2, 2, 2, 3, 3, 3, 3, 4, 4, 4, 4, + 5, 5, 5, 5, 6, 6, 6, 7, 7, 7, 7, 8, 8, 8}, +}; + +static const s8 _txpwr_track_delta_swingidx_5ga_p[][DELTA_SWINGIDX_SIZE] = { + {0, 1, 1, 2, 2, 3, 3, 4, 4, 4, 5, 5, 6, 6, 7, 7, 8, + 8, 9, 9, 9, 10, 10, 11, 11, 12, 12, 13, 13, 14}, + {0, 1, 1, 2, 2, 3, 3, 4, 4, 4, 5, 5, 6, 6, 7, 7, 8, + 8, 9, 9, 9, 10, 10, 11, 11, 12, 12, 13, 13, 14}, + {0, 1, 1, 2, 2, 3, 3, 4, 4, 4, 5, 5, 6, 6, 7, 7, 8, + 8, 9, 9, 9, 10, 10, 11, 11, 12, 12, 13, 13, 14}, +}; + +static const s8 _txpwr_track_delta_swingidx_2gb_n[] = { + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 +}; + +static const s8 _txpwr_track_delta_swingidx_2gb_p[] = { + 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 2, 2, 2 +}; + +static const s8 _txpwr_track_delta_swingidx_2ga_n[] = { + 0, 0, 0, 0, 0, 0, 0, 0, -1, -1, -1, -1, -1, -1, -1, -2, -2, + -2, -2, -2, -2, -2, -2, -3, -3, -3, -3, -3, -3, -3 +}; + +static const s8 _txpwr_track_delta_swingidx_2ga_p[] = { + 0, 1, 1, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 2, 3, 3, + 3, 3, 3, 3, 3, 4, 4, 4, 4, 4, 4, 5, 5, 5 +}; + +static const s8 _txpwr_track_delta_swingidx_2g_cck_b_n[] = { + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 +}; + +static const s8 _txpwr_track_delta_swingidx_2g_cck_b_p[] = { + 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 2, 2, 2 +}; + +static const s8 _txpwr_track_delta_swingidx_2g_cck_a_n[] = { + 0, 0, 0, 0, 0, 0, 0, 0, -1, -1, -1, -1, -1, -1, -1, -2, -2, + -2, -2, -2, -2, -2, -2, -3, -3, -3, -3, -3, -3, -3 +}; + +static const s8 _txpwr_track_delta_swingidx_2g_cck_a_p[] = { + 0, 1, 1, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 2, 3, 3, + 3, 3, 3, 3, 3, 4, 4, 4, 4, 4, 4, 5, 5, 5 +}; + const u8 rtw89_8852c_tx_shape[RTW89_BAND_MAX][RTW89_RS_TX_SHAPE_NUM] [RTW89_REGD_NUM] = { [0][0][RTW89_ACMA] = 0, @@ -19322,3 +19442,22 @@ const struct rtw89_txpwr_table rtw89_8852c_byr_table = { .size = ARRAY_SIZE(rtw89_8852c_txpwr_byrate), .load = rtw89_phy_load_txpwr_byrate, }; + +const struct rtw89_txpwr_track_cfg rtw89_8852c_trk_cfg = { + .delta_swingidx_6gb_n = _txpwr_track_delta_swingidx_6gb_n, + .delta_swingidx_6gb_p = _txpwr_track_delta_swingidx_6gb_p, + .delta_swingidx_6ga_n = _txpwr_track_delta_swingidx_6ga_n, + .delta_swingidx_6ga_p = _txpwr_track_delta_swingidx_6ga_p, + .delta_swingidx_5gb_n = _txpwr_track_delta_swingidx_5gb_n, + .delta_swingidx_5gb_p = _txpwr_track_delta_swingidx_5gb_p, + .delta_swingidx_5ga_n = _txpwr_track_delta_swingidx_5ga_n, + .delta_swingidx_5ga_p = _txpwr_track_delta_swingidx_5ga_p, + .delta_swingidx_2gb_n = _txpwr_track_delta_swingidx_2gb_n, + .delta_swingidx_2gb_p = _txpwr_track_delta_swingidx_2gb_p, + .delta_swingidx_2ga_n = _txpwr_track_delta_swingidx_2ga_n, + .delta_swingidx_2ga_p = _txpwr_track_delta_swingidx_2ga_p, + .delta_swingidx_2g_cck_b_n = _txpwr_track_delta_swingidx_2g_cck_b_n, + .delta_swingidx_2g_cck_b_p = _txpwr_track_delta_swingidx_2g_cck_b_p, + .delta_swingidx_2g_cck_a_n = _txpwr_track_delta_swingidx_2g_cck_a_n, + .delta_swingidx_2g_cck_a_p = _txpwr_track_delta_swingidx_2g_cck_a_p, +}; diff --git a/drivers/net/wireless/realtek/rtw89/rtw8852c_table.h b/drivers/net/wireless/realtek/rtw89/rtw8852c_table.h index 0c0df2ac8cff7..616282c9bb986 100644 --- a/drivers/net/wireless/realtek/rtw89/rtw8852c_table.h +++ b/drivers/net/wireless/realtek/rtw89/rtw8852c_table.h @@ -13,6 +13,7 @@ extern const struct rtw89_phy_table rtw89_8852c_phy_radioa_table; extern const struct rtw89_phy_table rtw89_8852c_phy_radiob_table; extern const struct rtw89_phy_table rtw89_8852c_phy_nctl_table; extern const struct rtw89_txpwr_table rtw89_8852c_byr_table; +extern const struct rtw89_txpwr_track_cfg rtw89_8852c_trk_cfg; extern const u8 rtw89_8852c_tx_shape[RTW89_BAND_MAX][RTW89_RS_TX_SHAPE_NUM] [RTW89_REGD_NUM]; extern const s8 rtw89_8852c_txpwr_lmt_2g[RTW89_2G_BW_NUM][RTW89_NTX_NUM] From c7845551bf667894c5eb4320265d8717f056a8ac Mon Sep 17 00:00:00 2001 From: Ping-Ke Shih Date: Thu, 14 Apr 2022 14:20:18 +0800 Subject: [PATCH 156/228] rtw89: 8852c: phy: configure TSSI bandedge TSSI is used to manage TX power with thermal value as a factor. This patch is to configure bandedge to TX proper waveform. Signed-off-by: Ping-Ke Shih Signed-off-by: Kalle Valo Link: https://lore.kernel.org/r/20220414062027.62638-5-pkshih@realtek.com --- drivers/net/wireless/realtek/rtw89/core.h | 1 + drivers/net/wireless/realtek/rtw89/phy.c | 106 ++++++++++++++++++ drivers/net/wireless/realtek/rtw89/phy.h | 36 ++++++ drivers/net/wireless/realtek/rtw89/reg.h | 5 + drivers/net/wireless/realtek/rtw89/rtw8852a.c | 1 + drivers/net/wireless/realtek/rtw89/rtw8852c.c | 1 + .../wireless/realtek/rtw89/rtw8852c_table.c | 7 ++ .../wireless/realtek/rtw89/rtw8852c_table.h | 1 + 8 files changed, 158 insertions(+) diff --git a/drivers/net/wireless/realtek/rtw89/core.h b/drivers/net/wireless/realtek/rtw89/core.h index 1dd558d89567f..fd6b17b6498b9 100644 --- a/drivers/net/wireless/realtek/rtw89/core.h +++ b/drivers/net/wireless/realtek/rtw89/core.h @@ -2380,6 +2380,7 @@ struct rtw89_chip_info { const struct rtw89_phy_table *nctl_table; const struct rtw89_txpwr_table *byr_table; const struct rtw89_phy_dig_gain_table *dig_table; + const struct rtw89_phy_tssi_dbw_table *tssi_dbw_table; const s8 (*txpwr_lmt_2g)[RTW89_2G_BW_NUM][RTW89_NTX_NUM] [RTW89_RS_LMT_NUM][RTW89_BF_NUM] [RTW89_REGD_NUM][RTW89_2G_CH_NUM]; diff --git a/drivers/net/wireless/realtek/rtw89/phy.c b/drivers/net/wireless/realtek/rtw89/phy.c index eed6dbd0d5dbc..aff03261ab727 100644 --- a/drivers/net/wireless/realtek/rtw89/phy.c +++ b/drivers/net/wireless/realtek/rtw89/phy.c @@ -3420,3 +3420,109 @@ rtw89_rfk_parser(struct rtw89_dev *rtwdev, const struct rtw89_rfk_tbl *tbl) _rfk_handler[p->flag](rtwdev, p); } EXPORT_SYMBOL(rtw89_rfk_parser); + +#define RTW89_TSSI_FAST_MODE_NUM 4 + +static const struct rtw89_reg_def rtw89_tssi_fastmode_regs_flat[RTW89_TSSI_FAST_MODE_NUM] = { + {0xD934, 0xff0000}, + {0xD934, 0xff000000}, + {0xD938, 0xff}, + {0xD934, 0xff00}, +}; + +static const struct rtw89_reg_def rtw89_tssi_fastmode_regs_level[RTW89_TSSI_FAST_MODE_NUM] = { + {0xD930, 0xff0000}, + {0xD930, 0xff000000}, + {0xD934, 0xff}, + {0xD930, 0xff00}, +}; + +static +void rtw89_phy_tssi_ctrl_set_fast_mode_cfg(struct rtw89_dev *rtwdev, + enum rtw89_mac_idx mac_idx, + enum rtw89_tssi_bandedge_cfg bandedge_cfg, + u32 val) +{ + const struct rtw89_reg_def *regs; + u32 reg; + int i; + + if (bandedge_cfg == RTW89_TSSI_BANDEDGE_FLAT) + regs = rtw89_tssi_fastmode_regs_flat; + else + regs = rtw89_tssi_fastmode_regs_level; + + for (i = 0; i < RTW89_TSSI_FAST_MODE_NUM; i++) { + reg = rtw89_mac_reg_by_idx(regs[i].addr, mac_idx); + rtw89_write32_mask(rtwdev, reg, regs[i].mask, val); + } +} + +static const struct rtw89_reg_def rtw89_tssi_bandedge_regs_flat[RTW89_TSSI_SBW_NUM] = { + {0xD91C, 0xff000000}, + {0xD920, 0xff}, + {0xD920, 0xff00}, + {0xD920, 0xff0000}, + {0xD920, 0xff000000}, + {0xD924, 0xff}, + {0xD924, 0xff00}, + {0xD914, 0xff000000}, + {0xD918, 0xff}, + {0xD918, 0xff00}, + {0xD918, 0xff0000}, + {0xD918, 0xff000000}, + {0xD91C, 0xff}, + {0xD91C, 0xff00}, + {0xD91C, 0xff0000}, +}; + +static const struct rtw89_reg_def rtw89_tssi_bandedge_regs_level[RTW89_TSSI_SBW_NUM] = { + {0xD910, 0xff}, + {0xD910, 0xff00}, + {0xD910, 0xff0000}, + {0xD910, 0xff000000}, + {0xD914, 0xff}, + {0xD914, 0xff00}, + {0xD914, 0xff0000}, + {0xD908, 0xff}, + {0xD908, 0xff00}, + {0xD908, 0xff0000}, + {0xD908, 0xff000000}, + {0xD90C, 0xff}, + {0xD90C, 0xff00}, + {0xD90C, 0xff0000}, + {0xD90C, 0xff000000}, +}; + +void rtw89_phy_tssi_ctrl_set_bandedge_cfg(struct rtw89_dev *rtwdev, + enum rtw89_mac_idx mac_idx, + enum rtw89_tssi_bandedge_cfg bandedge_cfg) +{ + const struct rtw89_chip_info *chip = rtwdev->chip; + const struct rtw89_reg_def *regs; + const u32 *data; + u32 reg; + int i; + + if (bandedge_cfg >= RTW89_TSSI_CFG_NUM) + return; + + if (bandedge_cfg == RTW89_TSSI_BANDEDGE_FLAT) + regs = rtw89_tssi_bandedge_regs_flat; + else + regs = rtw89_tssi_bandedge_regs_level; + + data = chip->tssi_dbw_table->data[bandedge_cfg]; + + for (i = 0; i < RTW89_TSSI_SBW_NUM; i++) { + reg = rtw89_mac_reg_by_idx(regs[i].addr, mac_idx); + rtw89_write32_mask(rtwdev, reg, regs[i].mask, data[i]); + } + + reg = rtw89_mac_reg_by_idx(R_AX_BANDEDGE_CFG, mac_idx); + rtw89_write32_mask(rtwdev, reg, B_AX_BANDEDGE_CFG_IDX_MASK, bandedge_cfg); + + rtw89_phy_tssi_ctrl_set_fast_mode_cfg(rtwdev, mac_idx, bandedge_cfg, + data[RTW89_TSSI_SBW20]); +} +EXPORT_SYMBOL(rtw89_phy_tssi_ctrl_set_bandedge_cfg); diff --git a/drivers/net/wireless/realtek/rtw89/phy.h b/drivers/net/wireless/realtek/rtw89/phy.h index 9c97e77d97072..b8531bb7e606e 100644 --- a/drivers/net/wireless/realtek/rtw89/phy.h +++ b/drivers/net/wireless/realtek/rtw89/phy.h @@ -221,6 +221,35 @@ enum rtw89_dig_gain_tia_idx { RTW89_DIG_GAIN_TIA_IDX1 = 1 }; +enum rtw89_tssi_bandedge_cfg { + RTW89_TSSI_BANDEDGE_FLAT, + RTW89_TSSI_BANDEDGE_LOW, + RTW89_TSSI_BANDEDGE_MID, + RTW89_TSSI_BANDEDGE_HIGH, + + RTW89_TSSI_CFG_NUM, +}; + +enum rtw89_tssi_sbw_idx { + RTW89_TSSI_SBW20, + RTW89_TSSI_SBW40_0, + RTW89_TSSI_SBW40_1, + RTW89_TSSI_SBW80_0, + RTW89_TSSI_SBW80_1, + RTW89_TSSI_SBW80_2, + RTW89_TSSI_SBW80_3, + RTW89_TSSI_SBW160_0, + RTW89_TSSI_SBW160_1, + RTW89_TSSI_SBW160_2, + RTW89_TSSI_SBW160_3, + RTW89_TSSI_SBW160_4, + RTW89_TSSI_SBW160_5, + RTW89_TSSI_SBW160_6, + RTW89_TSSI_SBW160_7, + + RTW89_TSSI_SBW_NUM, +}; + struct rtw89_txpwr_byrate_cfg { enum rtw89_band band; enum rtw89_nss nss; @@ -263,6 +292,10 @@ struct rtw89_phy_dig_gain_table { const struct rtw89_phy_dig_gain_cfg *cfg_tia_a; }; +struct rtw89_phy_tssi_dbw_table { + u32 data[RTW89_TSSI_CFG_NUM][RTW89_TSSI_SBW_NUM]; +}; + struct rtw89_phy_reg3_tbl { const struct rtw89_reg3_def *reg3; int size; @@ -446,5 +479,8 @@ void rtw89_phy_set_phy_regs(struct rtw89_dev *rtwdev, u32 addr, u32 mask, void rtw89_phy_dig_reset(struct rtw89_dev *rtwdev); void rtw89_phy_dig(struct rtw89_dev *rtwdev); void rtw89_phy_set_bss_color(struct rtw89_dev *rtwdev, struct ieee80211_vif *vif); +void rtw89_phy_tssi_ctrl_set_bandedge_cfg(struct rtw89_dev *rtwdev, + enum rtw89_mac_idx mac_idx, + enum rtw89_tssi_bandedge_cfg bandedge_cfg); #endif diff --git a/drivers/net/wireless/realtek/rtw89/reg.h b/drivers/net/wireless/realtek/rtw89/reg.h index 98465d7469898..cd7916085e007 100644 --- a/drivers/net/wireless/realtek/rtw89/reg.h +++ b/drivers/net/wireless/realtek/rtw89/reg.h @@ -2958,6 +2958,11 @@ #define R_AX_PWR_MACID_LMT_TABLE0 0xD36C #define R_AX_PWR_MACID_LMT_TABLE127 0xD568 +#define R_AX_TSSI_CTRL_HEAD 0xD908 +#define R_AX_BANDEDGE_CFG 0xD94C +#define B_AX_BANDEDGE_CFG_IDX_MASK GENMASK(31, 30) +#define R_AX_TSSI_CTRL_TAIL 0xD95C + #define R_AX_TXPWR_IMR 0xD9E0 #define R_AX_TXPWR_IMR_C1 0xF9E0 #define R_AX_TXPWR_ISR 0xD9E4 diff --git a/drivers/net/wireless/realtek/rtw89/rtw8852a.c b/drivers/net/wireless/realtek/rtw89/rtw8852a.c index 2c5bd381ebf58..cb93287d47222 100644 --- a/drivers/net/wireless/realtek/rtw89/rtw8852a.c +++ b/drivers/net/wireless/realtek/rtw89/rtw8852a.c @@ -2113,6 +2113,7 @@ const struct rtw89_chip_info rtw8852a_chip_info = { .txpwr_factor_rf = 2, .txpwr_factor_mac = 1, .dig_table = &rtw89_8852a_phy_dig_table, + .tssi_dbw_table = NULL, .support_bands = BIT(NL80211_BAND_2GHZ) | BIT(NL80211_BAND_5GHZ), .support_bw160 = false, diff --git a/drivers/net/wireless/realtek/rtw89/rtw8852c.c b/drivers/net/wireless/realtek/rtw89/rtw8852c.c index 3f727dd420640..1b5f8da2e9e85 100644 --- a/drivers/net/wireless/realtek/rtw89/rtw8852c.c +++ b/drivers/net/wireless/realtek/rtw89/rtw8852c.c @@ -674,6 +674,7 @@ const struct rtw89_chip_info rtw8852c_chip_info = { .txpwr_factor_rf = 2, .txpwr_factor_mac = 1, .dig_table = NULL, + .tssi_dbw_table = &rtw89_8852c_tssi_dbw_table, .hw_sec_hdr = true, .sec_ctrl_efuse_size = 4, .physical_efuse_size = 1216, diff --git a/drivers/net/wireless/realtek/rtw89/rtw8852c_table.c b/drivers/net/wireless/realtek/rtw89/rtw8852c_table.c index e7852d2861379..477c46041c947 100644 --- a/drivers/net/wireless/realtek/rtw89/rtw8852c_table.c +++ b/drivers/net/wireless/realtek/rtw89/rtw8852c_table.c @@ -19461,3 +19461,10 @@ const struct rtw89_txpwr_track_cfg rtw89_8852c_trk_cfg = { .delta_swingidx_2g_cck_a_n = _txpwr_track_delta_swingidx_2g_cck_a_n, .delta_swingidx_2g_cck_a_p = _txpwr_track_delta_swingidx_2g_cck_a_p, }; + +const struct rtw89_phy_tssi_dbw_table rtw89_8852c_tssi_dbw_table = { + .data[RTW89_TSSI_BANDEDGE_FLAT] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, + .data[RTW89_TSSI_BANDEDGE_LOW] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, + .data[RTW89_TSSI_BANDEDGE_MID] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, + .data[RTW89_TSSI_BANDEDGE_HIGH] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, +}; diff --git a/drivers/net/wireless/realtek/rtw89/rtw8852c_table.h b/drivers/net/wireless/realtek/rtw89/rtw8852c_table.h index 616282c9bb986..7d71a92e2d27c 100644 --- a/drivers/net/wireless/realtek/rtw89/rtw8852c_table.h +++ b/drivers/net/wireless/realtek/rtw89/rtw8852c_table.h @@ -13,6 +13,7 @@ extern const struct rtw89_phy_table rtw89_8852c_phy_radioa_table; extern const struct rtw89_phy_table rtw89_8852c_phy_radiob_table; extern const struct rtw89_phy_table rtw89_8852c_phy_nctl_table; extern const struct rtw89_txpwr_table rtw89_8852c_byr_table; +extern const struct rtw89_phy_tssi_dbw_table rtw89_8852c_tssi_dbw_table; extern const struct rtw89_txpwr_track_cfg rtw89_8852c_trk_cfg; extern const u8 rtw89_8852c_tx_shape[RTW89_BAND_MAX][RTW89_RS_TX_SHAPE_NUM] [RTW89_REGD_NUM]; From cc99eefa61f08a655a6471ee31e3096ad2e329d2 Mon Sep 17 00:00:00 2001 From: Ping-Ke Shih Date: Thu, 14 Apr 2022 14:20:19 +0800 Subject: [PATCH 157/228] rtw89: 8852c: add BB initial and reset functions chip_ops::bb_sethw is to initialize BB settings out of BB parameters tables. Once switching channel or initialing, we do chip_ops::bb_reset to reset hardware counters and states to make things in expectation. Signed-off-by: Ping-Ke Shih Signed-off-by: Kalle Valo Link: https://lore.kernel.org/r/20220414062027.62638-6-pkshih@realtek.com --- drivers/net/wireless/realtek/rtw89/reg.h | 26 +++ drivers/net/wireless/realtek/rtw89/rtw8852c.c | 182 ++++++++++++++++++ 2 files changed, 208 insertions(+) diff --git a/drivers/net/wireless/realtek/rtw89/reg.h b/drivers/net/wireless/realtek/rtw89/reg.h index cd7916085e007..a7daca1d462c0 100644 --- a/drivers/net/wireless/realtek/rtw89/reg.h +++ b/drivers/net/wireless/realtek/rtw89/reg.h @@ -3280,6 +3280,10 @@ #define B_ANAPAR_FLTRST BIT(22) #define B_ANAPAR_CRXBB GENMASK(18, 16) #define B_ANAPAR_14 GENMASK(15, 0) +#define R_RFE_E_A2 0x0334 +#define R_RFE_O_SEL_A2 0x0338 +#define R_RFE_SEL0_A2 0x033C +#define R_RFE_SEL32_A2 0x0340 #define R_SWSI_DATA_V1 0x0370 #define B_SWSI_DATA_VAL_V1 GENMASK(19, 0) #define B_SWSI_DATA_ADDR_V1 GENMASK(27, 20) @@ -3340,6 +3344,8 @@ #define B_PMAC_PTX_EN BIT(4) #define R_PMAC_TX_CNT 0x09C8 #define B_PMAC_TX_CNT_MSK GENMASK(31, 0) +#define R_DBCC_80P80_SEL_EVM_RPT 0x0A10 +#define B_DBCC_80P80_SEL_EVM_RPT_EN BIT(0) #define R_CCX 0x0C00 #define B_CCX_EDCCA_OPT_MSK GENMASK(6, 4) #define B_MEASUREMENT_TRIG_MSK BIT(2) @@ -3380,6 +3386,8 @@ #define R_BRK_ASYNC_RST_EN_1 0x0DC0 #define R_BRK_ASYNC_RST_EN_2 0x0DC4 #define R_BRK_ASYNC_RST_EN_3 0x0DC8 +#define R_S0_HW_SI_DIS 0x1200 +#define B_S0_HW_SI_DIS_W_R_TRIG GENMASK(30, 28) #define R_P0_RXCK 0x12A0 #define B_P0_RXCK_VAL GENMASK(18, 16) #define B_P0_RXCK_ON BIT(19) @@ -3460,16 +3468,24 @@ #define B_TXFIR_CCD GENMASK(23, 0) #define R_TXFIRE 0x231c #define B_TXFIR_CEF GENMASK(23, 0) +#define R_11B_RX_V1 0x2320 +#define B_11B_RXCCA_DIS_V1 BIT(0) #define R_RXCCA 0x2344 #define B_RXCCA_DIS BIT(31) +#define R_RXCCA_V1 0x2320 +#define B_RXCCA_DIS_V1 BIT(0) #define R_RXSC 0x237C #define B_RXSC_EN BIT(0) #define R_RXSCOBC 0x23B0 #define B_RXSCOBC_TH GENMASK(18, 0) #define R_RXSCOCCK 0x23B4 #define B_RXSCOCCK_TH GENMASK(18, 0) +#define R_DBCC_80P80_SEL_EVM_RPT2 0x2A10 +#define B_DBCC_80P80_SEL_EVM_RPT2_EN BIT(0) #define R_P1_EN_SOUND_WO_NDP 0x2D7C #define B_P1_EN_SOUND_WO_NDP BIT(1) +#define R_S1_HW_SI_DIS 0x3200 +#define B_S1_HW_SI_DIS_W_R_TRIG GENMASK(30, 28) #define R_P1_DBGMOD 0x32B8 #define B_P1_DBGMOD_ON BIT(30) #define R_S1_RXDC 0x32D4 @@ -3614,6 +3630,16 @@ #define R_P0_RFCTM 0x5864 #define B_P0_RFCTM_VAL GENMASK(25, 20) #define R_P0_RFCTM_RDY BIT(26) +#define R_P0_TRSW 0x5868 +#define B_P0_TRSW_B BIT(0) +#define B_P0_TRSW_A BIT(1) +#define B_P0_TRSW_X BIT(2) +#define B_P0_TRSW_SO_A2 GENMASK(7, 5) +#define R_P0_RFM 0x5894 +#define B_P0_RFM_DIS_WL BIT(7) +#define B_P0_RFM_TX_OPT BIT(6) +#define B_P0_RFM_BT_EN BIT(5) +#define B_P0_RFM_OUT GENMASK(4, 0) #define R_P0_TXDPD 0x58D4 #define B_P0_TXDPD GENMASK(31, 28) #define R_P0_TXPW_RSTB 0x58DC diff --git a/drivers/net/wireless/realtek/rtw89/rtw8852c.c b/drivers/net/wireless/realtek/rtw89/rtw8852c.c index 1b5f8da2e9e85..9c6bef665c764 100644 --- a/drivers/net/wireless/realtek/rtw89/rtw8852c.c +++ b/drivers/net/wireless/realtek/rtw89/rtw8852c.c @@ -495,6 +495,186 @@ static void rtw8852c_power_trim(struct rtw89_dev *rtwdev) rtw8852c_pa_bias_trim(rtwdev); } +static void rtw8852c_bb_reset_all(struct rtw89_dev *rtwdev, + enum rtw89_phy_idx phy_idx) +{ + /*HW SI reset*/ + rtw89_phy_write32_mask(rtwdev, R_S0_HW_SI_DIS, B_S0_HW_SI_DIS_W_R_TRIG, + 0x7); + rtw89_phy_write32_mask(rtwdev, R_S1_HW_SI_DIS, B_S1_HW_SI_DIS_W_R_TRIG, + 0x7); + + udelay(1); + + rtw89_phy_write32_idx(rtwdev, R_RSTB_ASYNC, B_RSTB_ASYNC_ALL, 1, + phy_idx); + rtw89_phy_write32_idx(rtwdev, R_RSTB_ASYNC, B_RSTB_ASYNC_ALL, 0, + phy_idx); + /*HW SI reset*/ + rtw89_phy_write32_mask(rtwdev, R_S0_HW_SI_DIS, B_S0_HW_SI_DIS_W_R_TRIG, + 0x0); + rtw89_phy_write32_mask(rtwdev, R_S1_HW_SI_DIS, B_S1_HW_SI_DIS_W_R_TRIG, + 0x0); + + rtw89_phy_write32_idx(rtwdev, R_RSTB_ASYNC, B_RSTB_ASYNC_ALL, 1, + phy_idx); +} + +static void rtw8852c_bb_reset_en(struct rtw89_dev *rtwdev, + enum rtw89_phy_idx phy_idx, bool en) +{ + struct rtw89_hal *hal = &rtwdev->hal; + + if (en) { + rtw89_phy_write32_idx(rtwdev, R_S0_HW_SI_DIS, + B_S0_HW_SI_DIS_W_R_TRIG, 0x0, phy_idx); + rtw89_phy_write32_idx(rtwdev, R_S1_HW_SI_DIS, + B_S1_HW_SI_DIS_W_R_TRIG, 0x0, phy_idx); + rtw89_phy_write32_idx(rtwdev, R_RSTB_ASYNC, B_RSTB_ASYNC_ALL, 1, + phy_idx); + if (hal->current_band_type == RTW89_BAND_2G) + rtw89_phy_write32_mask(rtwdev, R_RXCCA_V1, B_RXCCA_DIS_V1, 0x0); + rtw89_phy_write32_mask(rtwdev, R_PD_CTRL, B_PD_HIT_DIS, 0x0); + } else { + rtw89_phy_write32_mask(rtwdev, R_RXCCA_V1, B_RXCCA_DIS_V1, 0x1); + rtw89_phy_write32_mask(rtwdev, R_PD_CTRL, B_PD_HIT_DIS, 0x1); + rtw89_phy_write32_idx(rtwdev, R_S0_HW_SI_DIS, + B_S0_HW_SI_DIS_W_R_TRIG, 0x7, phy_idx); + rtw89_phy_write32_idx(rtwdev, R_S1_HW_SI_DIS, + B_S1_HW_SI_DIS_W_R_TRIG, 0x7, phy_idx); + fsleep(1); + rtw89_phy_write32_idx(rtwdev, R_RSTB_ASYNC, B_RSTB_ASYNC_ALL, 0, + phy_idx); + } +} + +static void rtw8852c_bb_reset(struct rtw89_dev *rtwdev, + enum rtw89_phy_idx phy_idx) +{ + rtw8852c_bb_reset_all(rtwdev, phy_idx); +} + +static +void rtw8852c_bb_gpio_trsw(struct rtw89_dev *rtwdev, enum rtw89_rf_path path, + u8 tx_path_en, u8 trsw_tx, + u8 trsw_rx, u8 trsw, u8 trsw_b) +{ + static const u32 path_cr_bases[] = {0x5868, 0x7868}; + u32 mask_ofst = 16; + u32 cr; + u32 val; + + if (path >= ARRAY_SIZE(path_cr_bases)) + return; + + cr = path_cr_bases[path]; + + mask_ofst += (tx_path_en * 4 + trsw_tx * 2 + trsw_rx) * 2; + val = FIELD_PREP(B_P0_TRSW_A, trsw) | FIELD_PREP(B_P0_TRSW_B, trsw_b); + + rtw89_phy_write32_mask(rtwdev, cr, (B_P0_TRSW_A | B_P0_TRSW_B) << mask_ofst, val); +} + +enum rtw8852c_rfe_src { + PAPE_RFM, + TRSW_RFM, + LNAON_RFM, +}; + +static +void rtw8852c_bb_gpio_rfm(struct rtw89_dev *rtwdev, enum rtw89_rf_path path, + enum rtw8852c_rfe_src src, u8 dis_tx_gnt_wl, + u8 active_tx_opt, u8 act_bt_en, u8 rfm_output_val) +{ + static const u32 path_cr_bases[] = {0x5894, 0x7894}; + static const u32 masks[] = {0, 8, 16}; + u32 mask, mask_ofst; + u32 cr; + u32 val; + + if (src >= ARRAY_SIZE(masks) || path >= ARRAY_SIZE(path_cr_bases)) + return; + + mask_ofst = masks[src]; + cr = path_cr_bases[path]; + + val = FIELD_PREP(B_P0_RFM_DIS_WL, dis_tx_gnt_wl) | + FIELD_PREP(B_P0_RFM_TX_OPT, active_tx_opt) | + FIELD_PREP(B_P0_RFM_BT_EN, act_bt_en) | + FIELD_PREP(B_P0_RFM_OUT, rfm_output_val); + mask = 0xff << mask_ofst; + + rtw89_phy_write32_mask(rtwdev, cr, mask, val); +} + +static void rtw8852c_bb_gpio_init(struct rtw89_dev *rtwdev) +{ + static const u32 cr_bases[] = {0x5800, 0x7800}; + u32 addr; + u8 i; + + for (i = 0; i < ARRAY_SIZE(cr_bases); i++) { + addr = cr_bases[i]; + rtw89_phy_write32_set(rtwdev, (addr | 0x68), B_P0_TRSW_A); + rtw89_phy_write32_clr(rtwdev, (addr | 0x68), B_P0_TRSW_X); + rtw89_phy_write32_clr(rtwdev, (addr | 0x68), B_P0_TRSW_SO_A2); + rtw89_phy_write32(rtwdev, (addr | 0x80), 0x77777777); + rtw89_phy_write32(rtwdev, (addr | 0x84), 0x77777777); + } + + rtw89_phy_write32(rtwdev, R_RFE_E_A2, 0xffffffff); + rtw89_phy_write32(rtwdev, R_RFE_O_SEL_A2, 0); + rtw89_phy_write32(rtwdev, R_RFE_SEL0_A2, 0); + rtw89_phy_write32(rtwdev, R_RFE_SEL32_A2, 0); + + rtw8852c_bb_gpio_trsw(rtwdev, RF_PATH_A, 0, 0, 0, 0, 1); + rtw8852c_bb_gpio_trsw(rtwdev, RF_PATH_A, 0, 0, 1, 1, 0); + rtw8852c_bb_gpio_trsw(rtwdev, RF_PATH_A, 0, 1, 0, 1, 0); + rtw8852c_bb_gpio_trsw(rtwdev, RF_PATH_A, 0, 1, 1, 1, 0); + rtw8852c_bb_gpio_trsw(rtwdev, RF_PATH_A, 1, 0, 0, 0, 1); + rtw8852c_bb_gpio_trsw(rtwdev, RF_PATH_A, 1, 0, 1, 1, 0); + rtw8852c_bb_gpio_trsw(rtwdev, RF_PATH_A, 1, 1, 0, 1, 0); + rtw8852c_bb_gpio_trsw(rtwdev, RF_PATH_A, 1, 1, 1, 1, 0); + + rtw8852c_bb_gpio_trsw(rtwdev, RF_PATH_B, 0, 0, 0, 0, 1); + rtw8852c_bb_gpio_trsw(rtwdev, RF_PATH_B, 0, 0, 1, 1, 0); + rtw8852c_bb_gpio_trsw(rtwdev, RF_PATH_B, 0, 1, 0, 1, 0); + rtw8852c_bb_gpio_trsw(rtwdev, RF_PATH_B, 0, 1, 1, 1, 0); + rtw8852c_bb_gpio_trsw(rtwdev, RF_PATH_B, 1, 0, 0, 0, 1); + rtw8852c_bb_gpio_trsw(rtwdev, RF_PATH_B, 1, 0, 1, 1, 0); + rtw8852c_bb_gpio_trsw(rtwdev, RF_PATH_B, 1, 1, 0, 1, 0); + rtw8852c_bb_gpio_trsw(rtwdev, RF_PATH_B, 1, 1, 1, 1, 0); + + rtw8852c_bb_gpio_rfm(rtwdev, RF_PATH_A, PAPE_RFM, 0, 0, 0, 0x0); + rtw8852c_bb_gpio_rfm(rtwdev, RF_PATH_A, TRSW_RFM, 0, 0, 0, 0x4); + rtw8852c_bb_gpio_rfm(rtwdev, RF_PATH_A, LNAON_RFM, 0, 0, 0, 0x8); + + rtw8852c_bb_gpio_rfm(rtwdev, RF_PATH_B, PAPE_RFM, 0, 0, 0, 0x0); + rtw8852c_bb_gpio_rfm(rtwdev, RF_PATH_B, TRSW_RFM, 0, 0, 0, 0x4); + rtw8852c_bb_gpio_rfm(rtwdev, RF_PATH_B, LNAON_RFM, 0, 0, 0, 0x8); +} + +static void rtw8852c_bb_macid_ctrl_init(struct rtw89_dev *rtwdev, + enum rtw89_phy_idx phy_idx) +{ + u32 addr; + + for (addr = R_AX_PWR_MACID_LMT_TABLE0; + addr <= R_AX_PWR_MACID_LMT_TABLE127; addr += 4) + rtw89_mac_txpwr_write32(rtwdev, phy_idx, addr, 0); +} + +static void rtw8852c_bb_sethw(struct rtw89_dev *rtwdev) +{ + rtw89_phy_write32_set(rtwdev, R_DBCC_80P80_SEL_EVM_RPT, + B_DBCC_80P80_SEL_EVM_RPT_EN); + rtw89_phy_write32_set(rtwdev, R_DBCC_80P80_SEL_EVM_RPT2, + B_DBCC_80P80_SEL_EVM_RPT2_EN); + + rtw8852c_bb_macid_ctrl_init(rtwdev, RTW89_PHY_0); + rtw8852c_bb_gpio_init(rtwdev); +} + static void rtw8852c_set_txpwr_ul_tb_offset(struct rtw89_dev *rtwdev, s8 pw_ofst, enum rtw89_mac_idx mac_idx) @@ -632,6 +812,8 @@ static void rtw8852c_mac_disable_bb_rf(struct rtw89_dev *rtwdev) static const struct rtw89_chip_ops rtw8852c_chip_ops = { .enable_bb_rf = rtw8852c_mac_enable_bb_rf, .disable_bb_rf = rtw8852c_mac_disable_bb_rf, + .bb_reset = rtw8852c_bb_reset, + .bb_sethw = rtw8852c_bb_sethw, .read_efuse = rtw8852c_read_efuse, .read_phycap = rtw8852c_read_phycap, .power_trim = rtw8852c_power_trim, From e885871ee809aaadb06e8c63d5c3e90c8c07ccac Mon Sep 17 00:00:00 2001 From: Zong-Zhe Yang Date: Thu, 14 Apr 2022 14:20:20 +0800 Subject: [PATCH 158/228] rtw89: 8852c: support bb gain info Add parser for bb gain table and configure bb gain table for 8852c. While ctrl_ch, obtain bb gain error settings and write them to phy. Signed-off-by: Zong-Zhe Yang Signed-off-by: Ping-Ke Shih Signed-off-by: Kalle Valo Link: https://lore.kernel.org/r/20220414062027.62638-7-pkshih@realtek.com --- drivers/net/wireless/realtek/rtw89/core.h | 37 +++ drivers/net/wireless/realtek/rtw89/phy.c | 243 ++++++++++++++++++ drivers/net/wireless/realtek/rtw89/rtw8852c.c | 178 +++++++++++++ drivers/net/wireless/realtek/rtw89/rtw8852c.h | 1 + 4 files changed, 459 insertions(+) diff --git a/drivers/net/wireless/realtek/rtw89/core.h b/drivers/net/wireless/realtek/rtw89/core.h index fd6b17b6498b9..8ceee254d6274 100644 --- a/drivers/net/wireless/realtek/rtw89/core.h +++ b/drivers/net/wireless/realtek/rtw89/core.h @@ -3000,6 +3000,41 @@ struct rtw89_hw_scan_info { u8 op_band; }; +enum rtw89_phy_bb_gain_band { + RTW89_BB_GAIN_BAND_2G = 0, + RTW89_BB_GAIN_BAND_5G_L = 1, + RTW89_BB_GAIN_BAND_5G_M = 2, + RTW89_BB_GAIN_BAND_5G_H = 3, + RTW89_BB_GAIN_BAND_6G_L = 4, + RTW89_BB_GAIN_BAND_6G_M = 5, + RTW89_BB_GAIN_BAND_6G_H = 6, + RTW89_BB_GAIN_BAND_6G_UH = 7, + + RTW89_BB_GAIN_BAND_NR, +}; + +enum rtw89_phy_bb_rxsc_num { + RTW89_BB_RXSC_NUM_40 = 9, /* SC: 0, 1~8 */ + RTW89_BB_RXSC_NUM_80 = 13, /* SC: 0, 1~8, 9~12 */ + RTW89_BB_RXSC_NUM_160 = 15, /* SC: 0, 1~8, 9~12, 13~14 */ +}; + +struct rtw89_phy_bb_gain_info { + s8 lna_gain[RTW89_BB_GAIN_BAND_NR][RF_PATH_MAX][LNA_GAIN_NUM]; + s8 tia_gain[RTW89_BB_GAIN_BAND_NR][RF_PATH_MAX][TIA_GAIN_NUM]; + s8 lna_gain_bypass[RTW89_BB_GAIN_BAND_NR][RF_PATH_MAX][LNA_GAIN_NUM]; + s8 lna_op1db[RTW89_BB_GAIN_BAND_NR][RF_PATH_MAX][LNA_GAIN_NUM]; + s8 tia_lna_op1db[RTW89_BB_GAIN_BAND_NR][RF_PATH_MAX] + [LNA_GAIN_NUM + 1]; /* TIA0_LNA0~6 + TIA1_LNA6 */ + s8 rpl_ofst_20[RTW89_BB_GAIN_BAND_NR][RF_PATH_MAX]; + s8 rpl_ofst_40[RTW89_BB_GAIN_BAND_NR][RF_PATH_MAX] + [RTW89_BB_RXSC_NUM_40]; + s8 rpl_ofst_80[RTW89_BB_GAIN_BAND_NR][RF_PATH_MAX] + [RTW89_BB_RXSC_NUM_80]; + s8 rpl_ofst_160[RTW89_BB_GAIN_BAND_NR][RF_PATH_MAX] + [RTW89_BB_RXSC_NUM_160]; +}; + struct rtw89_dev { struct ieee80211_hw *hw; struct device *dev; @@ -3062,6 +3097,8 @@ struct rtw89_dev { struct rtw89_env_monitor_info env_monitor; struct rtw89_dig_info dig; struct rtw89_phy_ch_info ch_info; + struct rtw89_phy_bb_gain_info bb_gain; + struct delayed_work track_work; struct delayed_work coex_act1_work; struct delayed_work coex_bt_devinfo_work; diff --git a/drivers/net/wireless/realtek/rtw89/phy.c b/drivers/net/wireless/realtek/rtw89/phy.c index aff03261ab727..7d0593d8fafe9 100644 --- a/drivers/net/wireless/realtek/rtw89/phy.c +++ b/drivers/net/wireless/realtek/rtw89/phy.c @@ -790,6 +790,245 @@ static void rtw89_phy_config_bb_reg(struct rtw89_dev *rtwdev, rtw89_phy_write32(rtwdev, reg->addr, reg->data); } +union rtw89_phy_bb_gain_arg { + u32 addr; + struct { + union { + u8 type; + struct { + u8 rxsc_start:4; + u8 bw:4; + }; + }; + u8 path; + u8 gain_band; + u8 cfg_type; + }; +} __packed; + +static void +rtw89_phy_cfg_bb_gain_error(struct rtw89_dev *rtwdev, + union rtw89_phy_bb_gain_arg arg, u32 data) +{ + struct rtw89_phy_bb_gain_info *gain = &rtwdev->bb_gain; + u8 type = arg.type; + u8 path = arg.path; + u8 gband = arg.gain_band; + int i; + + switch (type) { + case 0: + for (i = 0; i < 4; i++, data >>= 8) + gain->lna_gain[gband][path][i] = data & 0xff; + break; + case 1: + for (i = 4; i < 7; i++, data >>= 8) + gain->lna_gain[gband][path][i] = data & 0xff; + break; + case 2: + for (i = 0; i < 2; i++, data >>= 8) + gain->tia_gain[gband][path][i] = data & 0xff; + break; + default: + rtw89_warn(rtwdev, + "bb gain error {0x%x:0x%x} with unknown type: %d\n", + arg.addr, data, type); + break; + } +} + +enum rtw89_phy_bb_rxsc_start_idx { + RTW89_BB_RXSC_START_IDX_FULL = 0, + RTW89_BB_RXSC_START_IDX_20 = 1, + RTW89_BB_RXSC_START_IDX_20_1 = 5, + RTW89_BB_RXSC_START_IDX_40 = 9, + RTW89_BB_RXSC_START_IDX_80 = 13, +}; + +static void +rtw89_phy_cfg_bb_rpl_ofst(struct rtw89_dev *rtwdev, + union rtw89_phy_bb_gain_arg arg, u32 data) +{ + struct rtw89_phy_bb_gain_info *gain = &rtwdev->bb_gain; + u8 rxsc_start = arg.rxsc_start; + u8 bw = arg.bw; + u8 path = arg.path; + u8 gband = arg.gain_band; + u8 rxsc; + s8 ofst; + int i; + + switch (bw) { + case RTW89_CHANNEL_WIDTH_20: + gain->rpl_ofst_20[gband][path] = (s8)data; + break; + case RTW89_CHANNEL_WIDTH_40: + if (rxsc_start == RTW89_BB_RXSC_START_IDX_FULL) { + gain->rpl_ofst_40[gband][path][0] = (s8)data; + } else if (rxsc_start == RTW89_BB_RXSC_START_IDX_20) { + for (i = 0; i < 2; i++, data >>= 8) { + rxsc = RTW89_BB_RXSC_START_IDX_20 + i; + ofst = (s8)(data & 0xff); + gain->rpl_ofst_40[gband][path][rxsc] = ofst; + } + } + break; + case RTW89_CHANNEL_WIDTH_80: + if (rxsc_start == RTW89_BB_RXSC_START_IDX_FULL) { + gain->rpl_ofst_80[gband][path][0] = (s8)data; + } else if (rxsc_start == RTW89_BB_RXSC_START_IDX_20) { + for (i = 0; i < 4; i++, data >>= 8) { + rxsc = RTW89_BB_RXSC_START_IDX_20 + i; + ofst = (s8)(data & 0xff); + gain->rpl_ofst_80[gband][path][rxsc] = ofst; + } + } else if (rxsc_start == RTW89_BB_RXSC_START_IDX_40) { + for (i = 0; i < 2; i++, data >>= 8) { + rxsc = RTW89_BB_RXSC_START_IDX_40 + i; + ofst = (s8)(data & 0xff); + gain->rpl_ofst_80[gband][path][rxsc] = ofst; + } + } + break; + case RTW89_CHANNEL_WIDTH_160: + if (rxsc_start == RTW89_BB_RXSC_START_IDX_FULL) { + gain->rpl_ofst_160[gband][path][0] = (s8)data; + } else if (rxsc_start == RTW89_BB_RXSC_START_IDX_20) { + for (i = 0; i < 4; i++, data >>= 8) { + rxsc = RTW89_BB_RXSC_START_IDX_20 + i; + ofst = (s8)(data & 0xff); + gain->rpl_ofst_160[gband][path][rxsc] = ofst; + } + } else if (rxsc_start == RTW89_BB_RXSC_START_IDX_20_1) { + for (i = 0; i < 4; i++, data >>= 8) { + rxsc = RTW89_BB_RXSC_START_IDX_20_1 + i; + ofst = (s8)(data & 0xff); + gain->rpl_ofst_160[gband][path][rxsc] = ofst; + } + } else if (rxsc_start == RTW89_BB_RXSC_START_IDX_40) { + for (i = 0; i < 4; i++, data >>= 8) { + rxsc = RTW89_BB_RXSC_START_IDX_40 + i; + ofst = (s8)(data & 0xff); + gain->rpl_ofst_160[gband][path][rxsc] = ofst; + } + } else if (rxsc_start == RTW89_BB_RXSC_START_IDX_80) { + for (i = 0; i < 2; i++, data >>= 8) { + rxsc = RTW89_BB_RXSC_START_IDX_80 + i; + ofst = (s8)(data & 0xff); + gain->rpl_ofst_160[gband][path][rxsc] = ofst; + } + } + break; + default: + rtw89_warn(rtwdev, + "bb rpl ofst {0x%x:0x%x} with unknown bw: %d\n", + arg.addr, data, bw); + break; + } +} + +static void +rtw89_phy_cfg_bb_gain_bypass(struct rtw89_dev *rtwdev, + union rtw89_phy_bb_gain_arg arg, u32 data) +{ + struct rtw89_phy_bb_gain_info *gain = &rtwdev->bb_gain; + u8 type = arg.type; + u8 path = arg.path; + u8 gband = arg.gain_band; + int i; + + switch (type) { + case 0: + for (i = 0; i < 4; i++, data >>= 8) + gain->lna_gain_bypass[gband][path][i] = data & 0xff; + break; + case 1: + for (i = 4; i < 7; i++, data >>= 8) + gain->lna_gain_bypass[gband][path][i] = data & 0xff; + break; + default: + rtw89_warn(rtwdev, + "bb gain bypass {0x%x:0x%x} with unknown type: %d\n", + arg.addr, data, type); + break; + } +} + +static void +rtw89_phy_cfg_bb_gain_op1db(struct rtw89_dev *rtwdev, + union rtw89_phy_bb_gain_arg arg, u32 data) +{ + struct rtw89_phy_bb_gain_info *gain = &rtwdev->bb_gain; + u8 type = arg.type; + u8 path = arg.path; + u8 gband = arg.gain_band; + int i; + + switch (type) { + case 0: + for (i = 0; i < 4; i++, data >>= 8) + gain->lna_op1db[gband][path][i] = data & 0xff; + break; + case 1: + for (i = 4; i < 7; i++, data >>= 8) + gain->lna_op1db[gband][path][i] = data & 0xff; + break; + case 2: + for (i = 0; i < 4; i++, data >>= 8) + gain->tia_lna_op1db[gband][path][i] = data & 0xff; + break; + case 3: + for (i = 4; i < 8; i++, data >>= 8) + gain->tia_lna_op1db[gband][path][i] = data & 0xff; + break; + default: + rtw89_warn(rtwdev, + "bb gain op1db {0x%x:0x%x} with unknown type: %d\n", + arg.addr, data, type); + break; + } +} + +static void rtw89_phy_config_bb_gain(struct rtw89_dev *rtwdev, + const struct rtw89_reg2_def *reg, + enum rtw89_rf_path rf_path, + void *extra_data) +{ + const struct rtw89_chip_info *chip = rtwdev->chip; + union rtw89_phy_bb_gain_arg arg = { .addr = reg->addr }; + + if (arg.gain_band >= RTW89_BB_GAIN_BAND_NR) + return; + + if (arg.path >= chip->rf_path_num) + return; + + if (arg.addr >= 0xf9 && arg.addr <= 0xfe) { + rtw89_warn(rtwdev, "bb gain table with flow ctrl\n"); + return; + } + + switch (arg.cfg_type) { + case 0: + rtw89_phy_cfg_bb_gain_error(rtwdev, arg, reg->data); + break; + case 1: + rtw89_phy_cfg_bb_rpl_ofst(rtwdev, arg, reg->data); + break; + case 2: + rtw89_phy_cfg_bb_gain_bypass(rtwdev, arg, reg->data); + break; + case 3: + rtw89_phy_cfg_bb_gain_op1db(rtwdev, arg, reg->data); + break; + default: + rtw89_warn(rtwdev, + "bb gain {0x%x:0x%x} with unknown cfg type: %d\n", + arg.addr, reg->data, arg.cfg_type); + break; + } +} + static void rtw89_phy_cofig_rf_reg_store(struct rtw89_dev *rtwdev, const struct rtw89_reg2_def *reg, @@ -1033,9 +1272,13 @@ void rtw89_phy_init_bb_reg(struct rtw89_dev *rtwdev) { const struct rtw89_chip_info *chip = rtwdev->chip; const struct rtw89_phy_table *bb_table = chip->bb_table; + const struct rtw89_phy_table *bb_gain_table = chip->bb_gain_table; rtw89_phy_init_reg(rtwdev, bb_table, rtw89_phy_config_bb_reg, NULL); rtw89_chip_init_txpwr_unit(rtwdev, RTW89_PHY_0); + if (bb_gain_table) + rtw89_phy_init_reg(rtwdev, bb_gain_table, + rtw89_phy_config_bb_gain, NULL); rtw89_phy_bb_reset(rtwdev, RTW89_PHY_0); } diff --git a/drivers/net/wireless/realtek/rtw89/rtw8852c.c b/drivers/net/wireless/realtek/rtw89/rtw8852c.c index 9c6bef665c764..dba2799383472 100644 --- a/drivers/net/wireless/realtek/rtw89/rtw8852c.c +++ b/drivers/net/wireless/realtek/rtw89/rtw8852c.c @@ -495,6 +495,184 @@ static void rtw8852c_power_trim(struct rtw89_dev *rtwdev) rtw8852c_pa_bias_trim(rtwdev); } +struct rtw8852c_bb_gain { + u32 gain_g[BB_PATH_NUM_8852C]; + u32 gain_a[BB_PATH_NUM_8852C]; + u32 gain_mask; +}; + +static const struct rtw8852c_bb_gain bb_gain_lna[LNA_GAIN_NUM] = { + { .gain_g = {0x4678, 0x475C}, .gain_a = {0x45DC, 0x4740}, + .gain_mask = 0x00ff0000 }, + { .gain_g = {0x4678, 0x475C}, .gain_a = {0x45DC, 0x4740}, + .gain_mask = 0xff000000 }, + { .gain_g = {0x467C, 0x4760}, .gain_a = {0x4660, 0x4744}, + .gain_mask = 0x000000ff }, + { .gain_g = {0x467C, 0x4760}, .gain_a = {0x4660, 0x4744}, + .gain_mask = 0x0000ff00 }, + { .gain_g = {0x467C, 0x4760}, .gain_a = {0x4660, 0x4744}, + .gain_mask = 0x00ff0000 }, + { .gain_g = {0x467C, 0x4760}, .gain_a = {0x4660, 0x4744}, + .gain_mask = 0xff000000 }, + { .gain_g = {0x4680, 0x4764}, .gain_a = {0x4664, 0x4748}, + .gain_mask = 0x000000ff }, +}; + +static const struct rtw8852c_bb_gain bb_gain_tia[TIA_GAIN_NUM] = { + { .gain_g = {0x4680, 0x4764}, .gain_a = {0x4664, 0x4748}, + .gain_mask = 0x00ff0000 }, + { .gain_g = {0x4680, 0x4764}, .gain_a = {0x4664, 0x4748}, + .gain_mask = 0xff000000 }, +}; + +struct rtw8852c_bb_gain_bypass { + u32 gain_g[BB_PATH_NUM_8852C]; + u32 gain_a[BB_PATH_NUM_8852C]; + u32 gain_mask_g; + u32 gain_mask_a; +}; + +static +const struct rtw8852c_bb_gain_bypass bb_gain_bypass_lna[LNA_GAIN_NUM] = { + { .gain_g = {0x4BB8, 0x4C7C}, .gain_a = {0x4BB4, 0x4C78}, + .gain_mask_g = 0xff000000, .gain_mask_a = 0xff}, + { .gain_g = {0x4BBC, 0x4C80}, .gain_a = {0x4BB4, 0x4C78}, + .gain_mask_g = 0xff, .gain_mask_a = 0xff00}, + { .gain_g = {0x4BBC, 0x4C80}, .gain_a = {0x4BB4, 0x4C78}, + .gain_mask_g = 0xff00, .gain_mask_a = 0xff0000}, + { .gain_g = {0x4BBC, 0x4C80}, .gain_a = {0x4BB4, 0x4C78}, + .gain_mask_g = 0xff0000, .gain_mask_a = 0xff000000}, + { .gain_g = {0x4BBC, 0x4C80}, .gain_a = {0x4BB8, 0x4C7C}, + .gain_mask_g = 0xff000000, .gain_mask_a = 0xff}, + { .gain_g = {0x4BC0, 0x4C84}, .gain_a = {0x4BB8, 0x4C7C}, + .gain_mask_g = 0xff, .gain_mask_a = 0xff00}, + { .gain_g = {0x4BC0, 0x4C84}, .gain_a = {0x4BB8, 0x4C7C}, + .gain_mask_g = 0xff00, .gain_mask_a = 0xff0000}, +}; + +struct rtw8852c_bb_gain_op1db { + struct { + u32 lna[BB_PATH_NUM_8852C]; + u32 tia_lna[BB_PATH_NUM_8852C]; + u32 mask; + } reg[LNA_GAIN_NUM]; + u32 reg_tia0_lna6[BB_PATH_NUM_8852C]; + u32 mask_tia0_lna6; +}; + +static const struct rtw8852c_bb_gain_op1db bb_gain_op1db_a = { + .reg = { + { .lna = {0x4668, 0x474c}, .tia_lna = {0x4670, 0x4754}, + .mask = 0xff}, + { .lna = {0x4668, 0x474c}, .tia_lna = {0x4670, 0x4754}, + .mask = 0xff00}, + { .lna = {0x4668, 0x474c}, .tia_lna = {0x4670, 0x4754}, + .mask = 0xff0000}, + { .lna = {0x4668, 0x474c}, .tia_lna = {0x4670, 0x4754}, + .mask = 0xff000000}, + { .lna = {0x466c, 0x4750}, .tia_lna = {0x4674, 0x4758}, + .mask = 0xff}, + { .lna = {0x466c, 0x4750}, .tia_lna = {0x4674, 0x4758}, + .mask = 0xff00}, + { .lna = {0x466c, 0x4750}, .tia_lna = {0x4674, 0x4758}, + .mask = 0xff0000}, + }, + .reg_tia0_lna6 = {0x4674, 0x4758}, + .mask_tia0_lna6 = 0xff000000, +}; + +static enum rtw89_phy_bb_gain_band +rtw8852c_mapping_gain_band(enum rtw89_subband subband) +{ + switch (subband) { + default: + case RTW89_CH_2G: + return RTW89_BB_GAIN_BAND_2G; + case RTW89_CH_5G_BAND_1: + return RTW89_BB_GAIN_BAND_5G_L; + case RTW89_CH_5G_BAND_3: + return RTW89_BB_GAIN_BAND_5G_M; + case RTW89_CH_5G_BAND_4: + return RTW89_BB_GAIN_BAND_5G_H; + case RTW89_CH_6G_BAND_IDX0: + case RTW89_CH_6G_BAND_IDX1: + return RTW89_BB_GAIN_BAND_6G_L; + case RTW89_CH_6G_BAND_IDX2: + case RTW89_CH_6G_BAND_IDX3: + return RTW89_BB_GAIN_BAND_6G_M; + case RTW89_CH_6G_BAND_IDX4: + case RTW89_CH_6G_BAND_IDX5: + return RTW89_BB_GAIN_BAND_6G_H; + case RTW89_CH_6G_BAND_IDX6: + case RTW89_CH_6G_BAND_IDX7: + return RTW89_BB_GAIN_BAND_6G_UH; + } +} + +static void rtw8852c_set_gain_error(struct rtw89_dev *rtwdev, + enum rtw89_subband subband, + enum rtw89_rf_path path) +{ + const struct rtw89_phy_bb_gain_info *gain = &rtwdev->bb_gain; + u8 gain_band = rtw8852c_mapping_gain_band(subband); + s32 val; + u32 reg; + u32 mask; + int i; + + for (i = 0; i < LNA_GAIN_NUM; i++) { + if (subband == RTW89_CH_2G) + reg = bb_gain_lna[i].gain_g[path]; + else + reg = bb_gain_lna[i].gain_a[path]; + + mask = bb_gain_lna[i].gain_mask; + val = gain->lna_gain[gain_band][path][i]; + rtw89_phy_write32_mask(rtwdev, reg, mask, val); + + if (subband == RTW89_CH_2G) { + reg = bb_gain_bypass_lna[i].gain_g[path]; + mask = bb_gain_bypass_lna[i].gain_mask_g; + } else { + reg = bb_gain_bypass_lna[i].gain_a[path]; + mask = bb_gain_bypass_lna[i].gain_mask_a; + } + + val = gain->lna_gain_bypass[gain_band][path][i]; + rtw89_phy_write32_mask(rtwdev, reg, mask, val); + + if (subband != RTW89_CH_2G) { + reg = bb_gain_op1db_a.reg[i].lna[path]; + mask = bb_gain_op1db_a.reg[i].mask; + val = gain->lna_op1db[gain_band][path][i]; + rtw89_phy_write32_mask(rtwdev, reg, mask, val); + + reg = bb_gain_op1db_a.reg[i].tia_lna[path]; + mask = bb_gain_op1db_a.reg[i].mask; + val = gain->tia_lna_op1db[gain_band][path][i]; + rtw89_phy_write32_mask(rtwdev, reg, mask, val); + } + } + + if (subband != RTW89_CH_2G) { + reg = bb_gain_op1db_a.reg_tia0_lna6[path]; + mask = bb_gain_op1db_a.mask_tia0_lna6; + val = gain->tia_lna_op1db[gain_band][path][7]; + rtw89_phy_write32_mask(rtwdev, reg, mask, val); + } + + for (i = 0; i < TIA_GAIN_NUM; i++) { + if (subband == RTW89_CH_2G) + reg = bb_gain_tia[i].gain_g[path]; + else + reg = bb_gain_tia[i].gain_a[path]; + + mask = bb_gain_tia[i].gain_mask; + val = gain->tia_gain[gain_band][path][i]; + rtw89_phy_write32_mask(rtwdev, reg, mask, val); + } +} + static void rtw8852c_bb_reset_all(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy_idx) { diff --git a/drivers/net/wireless/realtek/rtw89/rtw8852c.h b/drivers/net/wireless/realtek/rtw89/rtw8852c.h index d0594716040bc..d1c5b4367a9d2 100644 --- a/drivers/net/wireless/realtek/rtw89/rtw8852c.h +++ b/drivers/net/wireless/realtek/rtw89/rtw8852c.h @@ -8,6 +8,7 @@ #include "core.h" #define RF_PATH_NUM_8852C 2 +#define BB_PATH_NUM_8852C 2 struct rtw8852c_u_efuse { u8 rsvd[0x38]; From e6b17cbd34e3f7aa88169e21c814692c151c7418 Mon Sep 17 00:00:00 2001 From: Ping-Ke Shih Date: Thu, 14 Apr 2022 14:20:21 +0800 Subject: [PATCH 159/228] rtw89: 8852c: add efuse gain offset parser Define efuse struct to access gain offset, and store them for further use by setting channel. Signed-off-by: Ping-Ke Shih Signed-off-by: Kalle Valo Link: https://lore.kernel.org/r/20220414062027.62638-8-pkshih@realtek.com --- drivers/net/wireless/realtek/rtw89/core.h | 17 +++ drivers/net/wireless/realtek/rtw89/reg.h | 19 ++++ drivers/net/wireless/realtek/rtw89/rtw8852c.c | 101 ++++++++++++++++++ drivers/net/wireless/realtek/rtw89/rtw8852c.h | 18 +++- 4 files changed, 151 insertions(+), 4 deletions(-) diff --git a/drivers/net/wireless/realtek/rtw89/core.h b/drivers/net/wireless/realtek/rtw89/core.h index 8ceee254d6274..f34aca70908e0 100644 --- a/drivers/net/wireless/realtek/rtw89/core.h +++ b/drivers/net/wireless/realtek/rtw89/core.h @@ -74,6 +74,16 @@ enum rtw89_subband { RTW89_SUBBAND_NR, }; +enum rtw89_gain_offset { + RTW89_GAIN_OFFSET_2G_CCK, + RTW89_GAIN_OFFSET_2G_OFDM, + RTW89_GAIN_OFFSET_5G_LOW, + RTW89_GAIN_OFFSET_5G_MID, + RTW89_GAIN_OFFSET_5G_HIGH, + + RTW89_GAIN_OFFSET_NR, +}; + enum rtw89_hci_type { RTW89_HCI_TYPE_PCIE, RTW89_HCI_TYPE_USB, @@ -3035,6 +3045,12 @@ struct rtw89_phy_bb_gain_info { [RTW89_BB_RXSC_NUM_160]; }; +struct rtw89_phy_efuse_gain { + bool offset_valid; + s8 offset[RF_PATH_MAX][RTW89_GAIN_OFFSET_NR]; /* S(8, 0) */ + s8 offset_base[RTW89_PHY_MAX]; /* S(8, 4) */ +}; + struct rtw89_dev { struct ieee80211_hw *hw; struct device *dev; @@ -3098,6 +3114,7 @@ struct rtw89_dev { struct rtw89_dig_info dig; struct rtw89_phy_ch_info ch_info; struct rtw89_phy_bb_gain_info bb_gain; + struct rtw89_phy_efuse_gain efuse_gain; struct delayed_work track_work; struct delayed_work coex_act1_work; diff --git a/drivers/net/wireless/realtek/rtw89/reg.h b/drivers/net/wireless/realtek/rtw89/reg.h index a7daca1d462c0..bd5526ffb8dbd 100644 --- a/drivers/net/wireless/realtek/rtw89/reg.h +++ b/drivers/net/wireless/realtek/rtw89/reg.h @@ -3470,6 +3470,8 @@ #define B_TXFIR_CEF GENMASK(23, 0) #define R_11B_RX_V1 0x2320 #define B_11B_RXCCA_DIS_V1 BIT(0) +#define R_RPL_OFST 0x2340 +#define B_RPL_OFST_MASK GENMASK(14, 8) #define R_RXCCA 0x2344 #define B_RXCCA_DIS BIT(31) #define R_RXCCA_V1 0x2320 @@ -3570,6 +3572,11 @@ #define B_PATH0_P20_FOLLOW_BY_PAGCUGC_EN_MSK BIT(5) #define R_PATH0_S20_FOLLOW_BY_PAGCUGC 0x46A4 #define B_PATH0_S20_FOLLOW_BY_PAGCUGC_EN_MSK BIT(5) +#define R_PATH0_G_TIA0_LNA6_OP1DB_V1 0x4694 +#define B_PATH0_G_TIA0_LNA6_OP1DB_V1 GENMASK(7, 0) +#define R_PATH0_G_TIA1_LNA6_OP1DB_V1 0x4694 +#define B_PATH0_R_G_OFST_MASK GENMASK(23, 16) +#define B_PATH0_G_TIA1_LNA6_OP1DB_V1 GENMASK(15, 8) #define R_P0_NBIIDX 0x469C #define B_P0_NBIIDX_VAL GENMASK(11, 0) #define B_P0_NBIIDX_NOTCH_EN BIT(12) @@ -3587,6 +3594,8 @@ #define B_PATH1_P20_FOLLOW_BY_PAGCUGC_EN_MSK BIT(5) #define R_PATH1_S20_FOLLOW_BY_PAGCUGC 0x4778 #define B_PATH1_S20_FOLLOW_BY_PAGCUGC_EN_MSK BIT(5) +#define R_PATH1_G_TIA0_LNA6_OP1DB_V1 0x4778 +#define B_PATH1_G_TIA0_LNA6_OP1DB_V1 GENMASK(7, 0) #define R_P1_NBIIDX 0x4770 #define B_P1_NBIIDX_VAL GENMASK(11, 0) #define B_P1_NBIIDX_NOTCH_EN BIT(12) @@ -3601,6 +3610,14 @@ #define R_CHBW_MOD 0x4978 #define B_CHBW_MOD_PRICH GENMASK(11, 8) #define B_CHBW_MOD_SBW GENMASK(13, 12) +#define R_RPL_BIAS_COMP 0x4DF0 +#define B_RPL_BIAS_COMP_MASK GENMASK(7, 0) +#define R_RPL_PATHAB 0x4E0C +#define B_RPL_PATHB_MASK GENMASK(23, 16) +#define B_RPL_PATHA_MASK GENMASK(15, 8) +#define R_RSSI_M_PATHAB 0x4E2C +#define B_RSSI_M_PATHB_MASK GENMASK(15, 8) +#define B_RSSI_M_PATHA_MASK GENMASK(7, 0) #define R_DCFO_COMP_S0_V1 0x4A40 #define B_DCFO_COMP_S0_V1_MSK GENMASK(13, 0) #define R_BMODE_PDTH_V1 0x4B64 @@ -3669,6 +3686,8 @@ #define B_S0_DACKQ7_K GENMASK(15, 8) #define R_S0_DACKQ8 0x5E98 #define B_S0_DACKQ8_K GENMASK(15, 8) +#define R_RPL_BIAS_COMP1 0x6DF0 +#define B_RPL_BIAS_COMP1_MASK GENMASK(7, 0) #define R_P1_TMETER 0x7810 #define B_P1_TMETER GENMASK(15, 10) #define B_P1_TMETER_DIS BIT(16) diff --git a/drivers/net/wireless/realtek/rtw89/rtw8852c.c b/drivers/net/wireless/realtek/rtw89/rtw8852c.c index dba2799383472..bb935632ce40d 100644 --- a/drivers/net/wireless/realtek/rtw89/rtw8852c.c +++ b/drivers/net/wireless/realtek/rtw89/rtw8852c.c @@ -317,6 +317,41 @@ static void rtw8852c_efuse_parsing_tssi(struct rtw89_dev *rtwdev, } } +static bool _decode_efuse_gain(u8 data, s8 *high, s8 *low) +{ + if (high) + *high = sign_extend32(FIELD_GET(GENMASK(7, 4), data), 3); + if (low) + *low = sign_extend32(FIELD_GET(GENMASK(3, 0), data), 3); + + return data != 0xff; +} + +static void rtw8852c_efuse_parsing_gain_offset(struct rtw89_dev *rtwdev, + struct rtw8852c_efuse *map) +{ + struct rtw89_phy_efuse_gain *gain = &rtwdev->efuse_gain; + bool valid = false; + + valid |= _decode_efuse_gain(map->rx_gain_2g_cck, + &gain->offset[RF_PATH_A][RTW89_GAIN_OFFSET_2G_CCK], + &gain->offset[RF_PATH_B][RTW89_GAIN_OFFSET_2G_CCK]); + valid |= _decode_efuse_gain(map->rx_gain_2g_ofdm, + &gain->offset[RF_PATH_A][RTW89_GAIN_OFFSET_2G_OFDM], + &gain->offset[RF_PATH_B][RTW89_GAIN_OFFSET_2G_OFDM]); + valid |= _decode_efuse_gain(map->rx_gain_5g_low, + &gain->offset[RF_PATH_A][RTW89_GAIN_OFFSET_5G_LOW], + &gain->offset[RF_PATH_B][RTW89_GAIN_OFFSET_5G_LOW]); + valid |= _decode_efuse_gain(map->rx_gain_5g_mid, + &gain->offset[RF_PATH_A][RTW89_GAIN_OFFSET_5G_MID], + &gain->offset[RF_PATH_B][RTW89_GAIN_OFFSET_5G_MID]); + valid |= _decode_efuse_gain(map->rx_gain_5g_high, + &gain->offset[RF_PATH_A][RTW89_GAIN_OFFSET_5G_HIGH], + &gain->offset[RF_PATH_B][RTW89_GAIN_OFFSET_5G_HIGH]); + + gain->offset_valid = valid; +} + static int rtw8852c_read_efuse(struct rtw89_dev *rtwdev, u8 *log_map) { struct rtw89_efuse *efuse = &rtwdev->efuse; @@ -327,6 +362,7 @@ static int rtw8852c_read_efuse(struct rtw89_dev *rtwdev, u8 *log_map) efuse->country_code[0] = map->country_code[0]; efuse->country_code[1] = map->country_code[1]; rtw8852c_efuse_parsing_tssi(rtwdev, map); + rtw8852c_efuse_parsing_gain_offset(rtwdev, map); switch (rtwdev->hci.type) { case RTW89_HCI_TYPE_PCIE: @@ -673,6 +709,63 @@ static void rtw8852c_set_gain_error(struct rtw89_dev *rtwdev, } } +static void rtw8852c_set_gain_offset(struct rtw89_dev *rtwdev, + const struct rtw89_channel_params *param, + enum rtw89_phy_idx phy_idx, + enum rtw89_rf_path path) +{ + static const u32 rssi_ofst_addr[2] = {R_PATH0_G_TIA0_LNA6_OP1DB_V1, + R_PATH1_G_TIA0_LNA6_OP1DB_V1}; + static const u32 rpl_mask[2] = {B_RPL_PATHA_MASK, B_RPL_PATHB_MASK}; + static const u32 rpl_tb_mask[2] = {B_RSSI_M_PATHA_MASK, B_RSSI_M_PATHB_MASK}; + struct rtw89_phy_efuse_gain *efuse_gain = &rtwdev->efuse_gain; + enum rtw89_gain_offset gain_band; + s32 offset_q0, offset_base_q4; + s32 tmp = 0; + + if (!efuse_gain->offset_valid) + return; + + if (rtwdev->dbcc_en && path == RF_PATH_B) + phy_idx = RTW89_PHY_1; + + if (param->band_type == RTW89_BAND_2G) { + offset_q0 = efuse_gain->offset[path][RTW89_GAIN_OFFSET_2G_CCK]; + offset_base_q4 = efuse_gain->offset_base[phy_idx]; + + tmp = clamp_t(s32, (-offset_q0 << 3) + (offset_base_q4 >> 1), + S8_MIN >> 1, S8_MAX >> 1); + rtw89_phy_write32_mask(rtwdev, R_RPL_OFST, B_RPL_OFST_MASK, tmp & 0x7f); + } + + switch (param->subband_type) { + default: + case RTW89_CH_2G: + gain_band = RTW89_GAIN_OFFSET_2G_OFDM; + break; + case RTW89_CH_5G_BAND_1: + gain_band = RTW89_GAIN_OFFSET_5G_LOW; + break; + case RTW89_CH_5G_BAND_3: + gain_band = RTW89_GAIN_OFFSET_5G_MID; + break; + case RTW89_CH_5G_BAND_4: + gain_band = RTW89_GAIN_OFFSET_5G_HIGH; + break; + } + + offset_q0 = -efuse_gain->offset[path][gain_band]; + offset_base_q4 = efuse_gain->offset_base[phy_idx]; + + tmp = (offset_q0 << 2) + (offset_base_q4 >> 2); + tmp = clamp_t(s32, -tmp, S8_MIN, S8_MAX); + rtw89_phy_write32_mask(rtwdev, rssi_ofst_addr[path], B_PATH0_R_G_OFST_MASK, tmp & 0xff); + + tmp = clamp_t(s32, offset_q0 << 4, S8_MIN, S8_MAX); + rtw89_phy_write32_idx(rtwdev, R_RPL_PATHAB, rpl_mask[path], tmp & 0xff, phy_idx); + rtw89_phy_write32_idx(rtwdev, R_RSSI_M_PATHAB, rpl_tb_mask[path], tmp & 0xff, phy_idx); +} + static void rtw8852c_bb_reset_all(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy_idx) { @@ -844,6 +937,8 @@ static void rtw8852c_bb_macid_ctrl_init(struct rtw89_dev *rtwdev, static void rtw8852c_bb_sethw(struct rtw89_dev *rtwdev) { + struct rtw89_phy_efuse_gain *gain = &rtwdev->efuse_gain; + rtw89_phy_write32_set(rtwdev, R_DBCC_80P80_SEL_EVM_RPT, B_DBCC_80P80_SEL_EVM_RPT_EN); rtw89_phy_write32_set(rtwdev, R_DBCC_80P80_SEL_EVM_RPT2, @@ -851,6 +946,12 @@ static void rtw8852c_bb_sethw(struct rtw89_dev *rtwdev) rtw8852c_bb_macid_ctrl_init(rtwdev, RTW89_PHY_0); rtw8852c_bb_gpio_init(rtwdev); + + /* read these registers after loading BB parameters */ + gain->offset_base[RTW89_PHY_0] = + rtw89_phy_read32_mask(rtwdev, R_RPL_BIAS_COMP, B_RPL_BIAS_COMP_MASK); + gain->offset_base[RTW89_PHY_1] = + rtw89_phy_read32_mask(rtwdev, R_RPL_BIAS_COMP1, B_RPL_BIAS_COMP1_MASK); } static diff --git a/drivers/net/wireless/realtek/rtw89/rtw8852c.h b/drivers/net/wireless/realtek/rtw89/rtw8852c.h index d1c5b4367a9d2..ac642808a81ff 100644 --- a/drivers/net/wireless/realtek/rtw89/rtw8852c.h +++ b/drivers/net/wireless/realtek/rtw89/rtw8852c.h @@ -59,13 +59,23 @@ struct rtw8852c_efuse { u8 rsvd7[3]; u8 path_a_therm; u8 path_b_therm; - u8 rsvd8[46]; + u8 rsvd8[2]; + u8 rx_gain_2g_ofdm; + u8 rsvd9; + u8 rx_gain_2g_cck; + u8 rsvd10; + u8 rx_gain_5g_low; + u8 rsvd11; + u8 rx_gain_5g_mid; + u8 rsvd12; + u8 rx_gain_5g_high; + u8 rsvd13[35]; u8 bw40_1s_tssi_6g_a[TSSI_MCS_6G_CH_GROUP_NUM]; - u8 rsvd9[10]; + u8 rsvd14[10]; u8 bw40_1s_tssi_6g_b[TSSI_MCS_6G_CH_GROUP_NUM]; - u8 rsvd10[110]; + u8 rsvd15[110]; u8 channel_plan_6g; - u8 rsvd11[71]; + u8 rsvd16[71]; union { struct rtw8852c_u_efuse u; struct rtw8852c_e_efuse e; From 7b9c98c7a484f33c610d957f5fb9a281d1642828 Mon Sep 17 00:00:00 2001 From: Ping-Ke Shih Date: Thu, 14 Apr 2022 14:20:22 +0800 Subject: [PATCH 160/228] rtw89: 8852c: add HFC parameters HFC is short for HCI flow control, and these parameters is used to configure PCI quota for TX/RX. Signed-off-by: Ping-Ke Shih Signed-off-by: Kalle Valo Link: https://lore.kernel.org/r/20220414062027.62638-9-pkshih@realtek.com --- drivers/net/wireless/realtek/rtw89/rtw8852c.c | 32 +++++++++++++++++++ 1 file changed, 32 insertions(+) diff --git a/drivers/net/wireless/realtek/rtw89/rtw8852c.c b/drivers/net/wireless/realtek/rtw89/rtw8852c.c index bb935632ce40d..8be3cb22eb110 100644 --- a/drivers/net/wireless/realtek/rtw89/rtw8852c.c +++ b/drivers/net/wireless/realtek/rtw89/rtw8852c.c @@ -11,6 +11,37 @@ #include "rtw8852c.h" #include "rtw8852c_table.h" +static const struct rtw89_hfc_ch_cfg rtw8852c_hfc_chcfg_pcie[] = { + {13, 1614, grp_0}, /* ACH 0 */ + {13, 1614, grp_0}, /* ACH 1 */ + {13, 1614, grp_0}, /* ACH 2 */ + {13, 1614, grp_0}, /* ACH 3 */ + {13, 1614, grp_1}, /* ACH 4 */ + {13, 1614, grp_1}, /* ACH 5 */ + {13, 1614, grp_1}, /* ACH 6 */ + {13, 1614, grp_1}, /* ACH 7 */ + {13, 1614, grp_0}, /* B0MGQ */ + {13, 1614, grp_0}, /* B0HIQ */ + {13, 1614, grp_1}, /* B1MGQ */ + {13, 1614, grp_1}, /* B1HIQ */ + {40, 0, 0} /* FWCMDQ */ +}; + +static const struct rtw89_hfc_pub_cfg rtw8852c_hfc_pubcfg_pcie = { + 1614, /* Group 0 */ + 1614, /* Group 1 */ + 3228, /* Public Max */ + 0 /* WP threshold */ +}; + +static const struct rtw89_hfc_param_ini rtw8852c_hfc_param_ini_pcie[] = { + [RTW89_QTA_SCC] = {rtw8852c_hfc_chcfg_pcie, &rtw8852c_hfc_pubcfg_pcie, + &rtw89_mac_size.hfc_preccfg_pcie, RTW89_HCIFC_POH}, + [RTW89_QTA_DLFW] = {NULL, NULL, &rtw89_mac_size.hfc_preccfg_pcie, + RTW89_HCIFC_POH}, + [RTW89_QTA_INVALID] = {NULL}, +}; + static const struct rtw89_dle_mem rtw8852c_dle_mem_pcie[] = { [RTW89_QTA_SCC] = {RTW89_QTA_SCC, &rtw89_mac_size.wde_size19, &rtw89_mac_size.ple_size19, &rtw89_mac_size.wde_qt18, @@ -1116,6 +1147,7 @@ const struct rtw89_chip_info rtw8852c_chip_info = { .chip_id = RTL8852C, .ops = &rtw8852c_chip_ops, .fw_name = "rtw89/rtw8852c_fw.bin", + .hfc_param_ini = rtw8852c_hfc_param_ini_pcie, .dle_mem = rtw8852c_dle_mem_pcie, .rf_base_addr = {0xe000, 0xf000}, .pwr_on_seq = NULL, From bb865ba6ea83b561bfee2f74a3cb89ff5b983ecb Mon Sep 17 00:00:00 2001 From: Ping-Ke Shih Date: Thu, 14 Apr 2022 14:20:23 +0800 Subject: [PATCH 161/228] rtw89: 8852c: add set channel function of RF part Prepare functions to configure channel and bandwidth accordingly. Signed-off-by: Ping-Ke Shih Signed-off-by: Kalle Valo Link: https://lore.kernel.org/r/20220414062027.62638-10-pkshih@realtek.com --- drivers/net/wireless/realtek/rtw89/reg.h | 24 ++ .../net/wireless/realtek/rtw89/rtw8852c_rfk.c | 214 ++++++++++++++++++ .../net/wireless/realtek/rtw89/rtw8852c_rfk.h | 14 ++ 3 files changed, 252 insertions(+) create mode 100644 drivers/net/wireless/realtek/rtw89/rtw8852c_rfk.c create mode 100644 drivers/net/wireless/realtek/rtw89/rtw8852c_rfk.h diff --git a/drivers/net/wireless/realtek/rtw89/reg.h b/drivers/net/wireless/realtek/rtw89/reg.h index bd5526ffb8dbd..d666c6e2a9dec 100644 --- a/drivers/net/wireless/realtek/rtw89/reg.h +++ b/drivers/net/wireless/realtek/rtw89/reg.h @@ -3158,6 +3158,23 @@ #define RR_DTXLOK 0x08 #define RR_RSV2 0x09 #define RR_CFGCH 0x18 +#define RR_CFGCH_V1 0x10018 +#define RR_CFGCH_BAND1 GENMASK(17, 16) +#define CFGCH_BAND1_2G 0 +#define CFGCH_BAND1_5G 1 +#define CFGCH_BAND1_6G 3 +#define RR_CFGCH_BAND0 GENMASK(9, 8) +#define CFGCH_BAND0_2G 0 +#define CFGCH_BAND0_5G 1 +#define CFGCH_BAND0_6G 0 +#define RR_CFGCH_BW GENMASK(11, 10) +#define RR_CFGCH_CH GENMASK(7, 0) +#define CFGCH_BW_20M 3 +#define CFGCH_BW_40M 2 +#define CFGCH_BW_80M 1 +#define CFGCH_BW_160M 0 +#define RR_APK 0x19 +#define RR_APK_MOD GENMASK(5, 4) #define RR_BTC 0x1a #define RR_BTC_TXBB GENMASK(14, 12) #define RR_BTC_RXBB GENMASK(11, 10) @@ -3176,8 +3193,10 @@ #define RR_RXK_SEL2G BIT(8) #define RR_LUTWA 0x33 #define RR_LUTWA_MASK GENMASK(9, 0) +#define RR_LUTWA_M2 GENMASK(4, 0) #define RR_LUTWD1 0x3e #define RR_LUTWD0 0x3f +#define RR_LUTWD0_LB GENMASK(5, 0) #define RR_TM 0x42 #define RR_TM_TRI BIT(19) #define RR_TM_VAL GENMASK(6, 1) @@ -3260,6 +3279,7 @@ #define RR_LUTDBG 0xdf #define RR_LUTDBG_LOK BIT(2) #define RR_LUTWE2 0xee +#define RR_LUTWE2_RTXBW BIT(2) #define RR_LUTWE 0xef #define RR_LUTWE_LOK BIT(2) #define RR_RFC 0xf0 @@ -3856,6 +3876,10 @@ #define B_IQKINF2_FCNT GENMASK(23, 16) #define B_IQKINF2_KCNT GENMASK(15, 8) #define B_IQKINF2_NCTLV GENMAKS(7, 0) +#define R_P0_CFCH_BW0 0xC0D4 +#define B_P0_CFCH_BW0 GENMASK(27, 26) +#define R_P0_CFCH_BW1 0xC0D8 +#define B_P0_CFCH_BW1 GENMASK(8, 5) /* WiFi CPU local domain */ #define R_AX_WDT_CTRL 0x0040 diff --git a/drivers/net/wireless/realtek/rtw89/rtw8852c_rfk.c b/drivers/net/wireless/realtek/rtw89/rtw8852c_rfk.c new file mode 100644 index 0000000000000..56f0876c03fbd --- /dev/null +++ b/drivers/net/wireless/realtek/rtw89/rtw8852c_rfk.c @@ -0,0 +1,214 @@ +// SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause +/* Copyright(c) 2019-2022 Realtek Corporation + */ + +#include "debug.h" +#include "phy.h" +#include "reg.h" +#include "rtw8852c.h" +#include "rtw8852c_rfk.h" + +static u8 _kpath(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy_idx) +{ + rtw89_debug(rtwdev, RTW89_DBG_RFK, "[RFK]dbcc_en: %x, PHY%d\n", + rtwdev->dbcc_en, phy_idx); + + if (!rtwdev->dbcc_en) + return RF_AB; + + if (phy_idx == RTW89_PHY_0) + return RF_A; + else + return RF_B; +} + +static void _bw_setting(struct rtw89_dev *rtwdev, enum rtw89_rf_path path, + enum rtw89_bandwidth bw, bool is_dav) +{ + u32 rf_reg18; + u32 reg_reg18_addr; + + rtw89_debug(rtwdev, RTW89_DBG_RFK, "[RFK]===>%s\n", __func__); + if (is_dav) + reg_reg18_addr = RR_CFGCH; + else + reg_reg18_addr = RR_CFGCH_V1; + + rf_reg18 = rtw89_read_rf(rtwdev, path, reg_reg18_addr, RFREG_MASK); + rf_reg18 &= ~RR_CFGCH_BW; + + switch (bw) { + case RTW89_CHANNEL_WIDTH_5: + case RTW89_CHANNEL_WIDTH_10: + case RTW89_CHANNEL_WIDTH_20: + rf_reg18 |= FIELD_PREP(RR_CFGCH_BW, CFGCH_BW_20M); + rtw89_phy_write32_mask(rtwdev, R_P0_CFCH_BW0 | (path << 8), B_P0_CFCH_BW0, 0x3); + rtw89_phy_write32_mask(rtwdev, R_P0_CFCH_BW1 | (path << 8), B_P0_CFCH_BW1, 0xf); + break; + case RTW89_CHANNEL_WIDTH_40: + rf_reg18 |= FIELD_PREP(RR_CFGCH_BW, CFGCH_BW_40M); + rtw89_phy_write32_mask(rtwdev, R_P0_CFCH_BW0 | (path << 8), B_P0_CFCH_BW0, 0x3); + rtw89_phy_write32_mask(rtwdev, R_P0_CFCH_BW1 | (path << 8), B_P0_CFCH_BW1, 0xf); + break; + case RTW89_CHANNEL_WIDTH_80: + rf_reg18 |= FIELD_PREP(RR_CFGCH_BW, CFGCH_BW_80M); + rtw89_phy_write32_mask(rtwdev, R_P0_CFCH_BW0 | (path << 8), B_P0_CFCH_BW0, 0x2); + rtw89_phy_write32_mask(rtwdev, R_P0_CFCH_BW1 | (path << 8), B_P0_CFCH_BW1, 0xd); + break; + case RTW89_CHANNEL_WIDTH_160: + rf_reg18 |= FIELD_PREP(RR_CFGCH_BW, CFGCH_BW_160M); + rtw89_phy_write32_mask(rtwdev, R_P0_CFCH_BW0 | (path << 8), B_P0_CFCH_BW0, 0x1); + rtw89_phy_write32_mask(rtwdev, R_P0_CFCH_BW1 | (path << 8), B_P0_CFCH_BW1, 0xb); + break; + default: + break; + } + + rtw89_write_rf(rtwdev, path, reg_reg18_addr, RFREG_MASK, rf_reg18); +} + +static void _ctrl_bw(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy, + enum rtw89_bandwidth bw) +{ + bool is_dav; + u8 kpath, path; + u32 tmp = 0; + + rtw89_debug(rtwdev, RTW89_DBG_RFK, "[RFK]===>%s\n", __func__); + kpath = _kpath(rtwdev, phy); + + for (path = 0; path < 2; path++) { + if (!(kpath & BIT(path))) + continue; + + is_dav = true; + _bw_setting(rtwdev, path, bw, is_dav); + is_dav = false; + _bw_setting(rtwdev, path, bw, is_dav); + if (rtwdev->dbcc_en) + continue; + + if (path == RF_PATH_B && rtwdev->hal.cv == CHIP_CAV) { + rtw89_write_rf(rtwdev, RF_PATH_B, RR_RSV1, RR_RSV1_RST, 0x0); + tmp = rtw89_read_rf(rtwdev, RF_PATH_A, RR_CFGCH, RFREG_MASK); + rtw89_write_rf(rtwdev, RF_PATH_B, RR_APK, RR_APK_MOD, 0x3); + rtw89_write_rf(rtwdev, RF_PATH_B, RR_CFGCH, RFREG_MASK, tmp); + fsleep(100); + rtw89_write_rf(rtwdev, RF_PATH_B, RR_RSV1, RR_RSV1_RST, 0x1); + } + } +} + +static void _ch_setting(struct rtw89_dev *rtwdev, enum rtw89_rf_path path, + u8 central_ch, enum rtw89_band band, bool is_dav) +{ + u32 rf_reg18; + u32 reg_reg18_addr; + + rtw89_debug(rtwdev, RTW89_DBG_RFK, "[RFK]===>%s\n", __func__); + if (is_dav) + reg_reg18_addr = 0x18; + else + reg_reg18_addr = 0x10018; + + rf_reg18 = rtw89_read_rf(rtwdev, path, reg_reg18_addr, RFREG_MASK); + rf_reg18 &= ~(RR_CFGCH_BAND1 | RR_CFGCH_BAND0 | RR_CFGCH_CH); + rf_reg18 |= FIELD_PREP(RR_CFGCH_CH, central_ch); + + switch (band) { + case RTW89_BAND_2G: + rf_reg18 |= FIELD_PREP(RR_CFGCH_BAND1, CFGCH_BAND1_2G); + rf_reg18 |= FIELD_PREP(RR_CFGCH_BAND0, CFGCH_BAND0_2G); + break; + case RTW89_BAND_5G: + rf_reg18 |= FIELD_PREP(RR_CFGCH_BAND1, CFGCH_BAND1_5G); + rf_reg18 |= FIELD_PREP(RR_CFGCH_BAND0, CFGCH_BAND0_5G); + break; + case RTW89_BAND_6G: + rf_reg18 |= FIELD_PREP(RR_CFGCH_BAND1, CFGCH_BAND1_6G); + rf_reg18 |= FIELD_PREP(RR_CFGCH_BAND0, CFGCH_BAND0_6G); + break; + default: + break; + } + rtw89_write_rf(rtwdev, path, reg_reg18_addr, RFREG_MASK, rf_reg18); + fsleep(100); +} + +static void _ctrl_ch(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy, + u8 central_ch, enum rtw89_band band) +{ + u8 kpath, path; + + rtw89_debug(rtwdev, RTW89_DBG_RFK, "[RFK]===>%s\n", __func__); + if (band != RTW89_BAND_6G) { + if ((central_ch > 14 && central_ch < 36) || + (central_ch > 64 && central_ch < 100) || + (central_ch > 144 && central_ch < 149) || central_ch > 177) + return; + } else { + if (central_ch > 253 || central_ch == 2) + return; + } + + kpath = _kpath(rtwdev, phy); + + for (path = 0; path < 2; path++) { + if (kpath & BIT(path)) { + _ch_setting(rtwdev, path, central_ch, band, true); + _ch_setting(rtwdev, path, central_ch, band, false); + } + } +} + +static void _rxbb_bw(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy, + enum rtw89_bandwidth bw) +{ + u8 kpath; + u8 path; + u32 val; + + kpath = _kpath(rtwdev, phy); + for (path = 0; path < 2; path++) { + if (!(kpath & BIT(path))) + continue; + + rtw89_write_rf(rtwdev, path, RR_LUTWE2, RR_LUTWE2_RTXBW, 0x1); + rtw89_write_rf(rtwdev, path, RR_LUTWA, RR_LUTWA_M2, 0xa); + switch (bw) { + case RTW89_CHANNEL_WIDTH_20: + val = 0x1b; + break; + case RTW89_CHANNEL_WIDTH_40: + val = 0x13; + break; + case RTW89_CHANNEL_WIDTH_80: + val = 0xb; + break; + case RTW89_CHANNEL_WIDTH_160: + default: + val = 0x3; + break; + } + rtw89_write_rf(rtwdev, path, RR_LUTWD0, RR_LUTWD0_LB, val); + rtw89_write_rf(rtwdev, path, RR_LUTWE2, RR_LUTWE2_RTXBW, 0x0); + } +} + +static +void rtw8852c_ctrl_bw_ch(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy, + u8 central_ch, enum rtw89_band band, + enum rtw89_bandwidth bw) +{ + _ctrl_ch(rtwdev, phy, central_ch, band); + _ctrl_bw(rtwdev, phy, bw); + _rxbb_bw(rtwdev, phy, bw); +} + +void rtw8852c_set_channel_rf(struct rtw89_dev *rtwdev, + struct rtw89_channel_params *param, + enum rtw89_phy_idx phy_idx) +{ + rtw8852c_ctrl_bw_ch(rtwdev, phy_idx, param->center_chan, param->band_type, + param->bandwidth); +} diff --git a/drivers/net/wireless/realtek/rtw89/rtw8852c_rfk.h b/drivers/net/wireless/realtek/rtw89/rtw8852c_rfk.h new file mode 100644 index 0000000000000..0e75555c1612d --- /dev/null +++ b/drivers/net/wireless/realtek/rtw89/rtw8852c_rfk.h @@ -0,0 +1,14 @@ +/* SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause */ +/* Copyright(c) 2019-2022 Realtek Corporation + */ + +#ifndef __RTW89_8852C_RFK_H__ +#define __RTW89_8852C_RFK_H__ + +#include "core.h" + +void rtw8852c_set_channel_rf(struct rtw89_dev *rtwdev, + struct rtw89_channel_params *param, + enum rtw89_phy_idx phy_idx); + +#endif From 63fb5c981590f0bdf1708077b94563ee609efe8f Mon Sep 17 00:00:00 2001 From: Ping-Ke Shih Date: Thu, 14 Apr 2022 14:20:24 +0800 Subject: [PATCH 162/228] rtw89: 8852c: set channel of MAC part Configure channel and bandwidth of MAC registers to work properly. Signed-off-by: Ping-Ke Shih Signed-off-by: Kalle Valo Link: https://lore.kernel.org/r/20220414062027.62638-11-pkshih@realtek.com --- drivers/net/wireless/realtek/rtw89/reg.h | 4 ++ drivers/net/wireless/realtek/rtw89/rtw8852c.c | 71 +++++++++++++++++++ 2 files changed, 75 insertions(+) diff --git a/drivers/net/wireless/realtek/rtw89/reg.h b/drivers/net/wireless/realtek/rtw89/reg.h index d666c6e2a9dec..44a2d984ebe19 100644 --- a/drivers/net/wireless/realtek/rtw89/reg.h +++ b/drivers/net/wireless/realtek/rtw89/reg.h @@ -1802,6 +1802,10 @@ #define R_AX_WMAC_RFMOD 0xC010 #define R_AX_WMAC_RFMOD_C1 0xE010 #define B_AX_WMAC_RFMOD_MASK GENMASK(1, 0) +#define AX_WMAC_RFMOD_20M 0 +#define AX_WMAC_RFMOD_40M 1 +#define AX_WMAC_RFMOD_80M 2 +#define AX_WMAC_RFMOD_160M 3 #define R_AX_GID_POSITION0 0xC070 #define R_AX_GID_POSITION0_C1 0xE070 diff --git a/drivers/net/wireless/realtek/rtw89/rtw8852c.c b/drivers/net/wireless/realtek/rtw89/rtw8852c.c index 8be3cb22eb110..07ff3bd50f62b 100644 --- a/drivers/net/wireless/realtek/rtw89/rtw8852c.c +++ b/drivers/net/wireless/realtek/rtw89/rtw8852c.c @@ -562,6 +562,77 @@ static void rtw8852c_power_trim(struct rtw89_dev *rtwdev) rtw8852c_pa_bias_trim(rtwdev); } +static void rtw8852c_set_channel_mac(struct rtw89_dev *rtwdev, + struct rtw89_channel_params *param, + u8 mac_idx) +{ + u32 rf_mod = rtw89_mac_reg_by_idx(R_AX_WMAC_RFMOD, mac_idx); + u32 sub_carr = rtw89_mac_reg_by_idx(R_AX_TX_SUB_CARRIER_VALUE, + mac_idx); + u32 chk_rate = rtw89_mac_reg_by_idx(R_AX_TXRATE_CHK, mac_idx); + u8 txsc20 = 0, txsc40 = 0, txsc80 = 0; + u8 rf_mod_val = 0, chk_rate_mask = 0; + u32 txsc; + + switch (param->bandwidth) { + case RTW89_CHANNEL_WIDTH_160: + txsc80 = rtw89_phy_get_txsc(rtwdev, param, + RTW89_CHANNEL_WIDTH_80); + fallthrough; + case RTW89_CHANNEL_WIDTH_80: + txsc40 = rtw89_phy_get_txsc(rtwdev, param, + RTW89_CHANNEL_WIDTH_40); + fallthrough; + case RTW89_CHANNEL_WIDTH_40: + txsc20 = rtw89_phy_get_txsc(rtwdev, param, + RTW89_CHANNEL_WIDTH_20); + break; + default: + break; + } + + switch (param->bandwidth) { + case RTW89_CHANNEL_WIDTH_160: + rf_mod_val = AX_WMAC_RFMOD_160M; + txsc = FIELD_PREP(B_AX_TXSC_20M_MASK, txsc20) | + FIELD_PREP(B_AX_TXSC_40M_MASK, txsc40) | + FIELD_PREP(B_AX_TXSC_80M_MASK, txsc80); + break; + case RTW89_CHANNEL_WIDTH_80: + rf_mod_val = AX_WMAC_RFMOD_80M; + txsc = FIELD_PREP(B_AX_TXSC_20M_MASK, txsc20) | + FIELD_PREP(B_AX_TXSC_40M_MASK, txsc40); + break; + case RTW89_CHANNEL_WIDTH_40: + rf_mod_val = AX_WMAC_RFMOD_40M; + txsc = FIELD_PREP(B_AX_TXSC_20M_MASK, txsc20); + break; + case RTW89_CHANNEL_WIDTH_20: + default: + rf_mod_val = AX_WMAC_RFMOD_20M; + txsc = 0; + break; + } + rtw89_write8_mask(rtwdev, rf_mod, B_AX_WMAC_RFMOD_MASK, rf_mod_val); + rtw89_write32(rtwdev, sub_carr, txsc); + + switch (param->band_type) { + case RTW89_BAND_2G: + chk_rate_mask = B_AX_BAND_MODE; + break; + case RTW89_BAND_5G: + case RTW89_BAND_6G: + chk_rate_mask = B_AX_CHECK_CCK_EN | B_AX_RTS_LIMIT_IN_OFDM6; + break; + default: + rtw89_warn(rtwdev, "Invalid band_type:%d\n", param->band_type); + return; + } + rtw89_write8_clr(rtwdev, chk_rate, B_AX_BAND_MODE | B_AX_CHECK_CCK_EN | + B_AX_RTS_LIMIT_IN_OFDM6); + rtw89_write8_set(rtwdev, chk_rate, chk_rate_mask); +} + struct rtw8852c_bb_gain { u32 gain_g[BB_PATH_NUM_8852C]; u32 gain_a[BB_PATH_NUM_8852C]; From 1b00e9236a7131284609d10e6f63ff2864ebe650 Mon Sep 17 00:00:00 2001 From: Ping-Ke Shih Date: Thu, 14 Apr 2022 14:20:25 +0800 Subject: [PATCH 163/228] rtw89: 8852c: add set channel of BB part BB does many settings during setting channel. First is to configure CCK for 2G channels, and then basic channel and bandwidth settings with a encoded channel index that will report to driver when we receive packets. Configure spur elimination to avoid spur of CSI and NBI tones in certain frequencies. Also, it initializes BT grant to arrange path sharing with BT according to band. Finally, reset TSSI and BB hardware to ensure it stays in initial state. Signed-off-by: Ping-Ke Shih Signed-off-by: Kalle Valo Link: https://lore.kernel.org/r/20220414062027.62638-12-pkshih@realtek.com --- drivers/net/wireless/realtek/rtw89/phy.h | 9 + drivers/net/wireless/realtek/rtw89/reg.h | 93 ++- drivers/net/wireless/realtek/rtw89/rtw8852c.c | 718 ++++++++++++++++++ drivers/net/wireless/realtek/rtw89/util.h | 30 + 4 files changed, 846 insertions(+), 4 deletions(-) diff --git a/drivers/net/wireless/realtek/rtw89/phy.h b/drivers/net/wireless/realtek/rtw89/phy.h index b8531bb7e606e..3ca5efa4c097b 100644 --- a/drivers/net/wireless/realtek/rtw89/phy.h +++ b/drivers/net/wireless/realtek/rtw89/phy.h @@ -307,6 +307,15 @@ const struct rtw89_phy_reg3_tbl _name ## _tbl = { \ .size = ARRAY_SIZE(_name), \ } +struct rtw89_nbi_reg_def { + struct rtw89_reg_def notch1_idx; + struct rtw89_reg_def notch1_frac_idx; + struct rtw89_reg_def notch1_en; + struct rtw89_reg_def notch2_idx; + struct rtw89_reg_def notch2_frac_idx; + struct rtw89_reg_def notch2_en; +}; + extern const u8 rtw89_rs_idx_max[RTW89_RS_MAX]; extern const u8 rtw89_rs_nss_max[RTW89_RS_MAX]; diff --git a/drivers/net/wireless/realtek/rtw89/reg.h b/drivers/net/wireless/realtek/rtw89/reg.h index 44a2d984ebe19..0f08b25817976 100644 --- a/drivers/net/wireless/realtek/rtw89/reg.h +++ b/drivers/net/wireless/realtek/rtw89/reg.h @@ -2962,6 +2962,8 @@ #define R_AX_PWR_MACID_LMT_TABLE0 0xD36C #define R_AX_PWR_MACID_LMT_TABLE127 0xD568 +#define R_P80_AT_HIGH_FREQ_BB_WRP 0xD848 +#define B_P80_AT_HIGH_FREQ_BB_WRP BIT(28) #define R_AX_TSSI_CTRL_HEAD 0xD908 #define R_AX_BANDEDGE_CFG 0xD94C #define B_AX_BANDEDGE_CFG_IDX_MASK GENMASK(31, 30) @@ -3192,9 +3194,9 @@ #define RR_RXKPLL_POW BIT(19) #define RR_RSV4 0x1f #define RR_RXK 0x20 -#define RR_RXK_PLLEN BIT(5) -#define RR_RXK_SEL5G BIT(7) #define RR_RXK_SEL2G BIT(8) +#define RR_RXK_SEL5G BIT(7) +#define RR_RXK_PLLEN BIT(5) #define RR_LUTWA 0x33 #define RR_LUTWA_MASK GENMASK(9, 0) #define RR_LUTWA_M2 GENMASK(4, 0) @@ -3320,8 +3322,9 @@ #define B_SWSI_READ_ADDR_PATH_V1 GENMASK(10, 8) #define B_SWSI_READ_ADDR_V1 GENMASK(10, 0) #define R_UPD_CLK_ADC 0x0700 -#define B_UPD_CLK_ADC_ON BIT(24) #define B_UPD_CLK_ADC_VAL GENMASK(26, 25) +#define B_UPD_CLK_ADC_ON BIT(24) +#define B_ENABLE_CCK BIT(5) #define R_RSTB_ASYNC 0x0704 #define B_RSTB_ASYNC_ALL BIT(1) #define R_MAC_PIN_SEL 0x0734 @@ -3368,6 +3371,8 @@ #define B_PMAC_PTX_EN BIT(4) #define R_PMAC_TX_CNT 0x09C8 #define B_PMAC_TX_CNT_MSK GENMASK(31, 0) +#define R_P80_AT_HIGH_FREQ 0x09D8 +#define B_P80_AT_HIGH_FREQ BIT(26) #define R_DBCC_80P80_SEL_EVM_RPT 0x0A10 #define B_DBCC_80P80_SEL_EVM_RPT_EN BIT(0) #define R_CCX 0x0C00 @@ -3400,6 +3405,14 @@ #define B_PD_HIT_DIS BIT(9) #define R_IOQ_IQK_DPK 0x0C60 #define B_IOQ_IQK_DPK_EN BIT(1) +#define R_GNT_BT_WGT_EN 0x0C6C +#define B_GNT_BT_WGT_EN BIT(21) +#define R_PD_ARBITER_OFF 0x0C80 +#define B_PD_ARBITER_OFF BIT(31) +#define R_SNDCCA_A1 0x0C9C +#define B_SNDCCA_A1_EN GENMASK(19, 12) +#define R_SNDCCA_A2 0x0CA0 +#define B_SNDCCA_A2_VAL GENMASK(19, 12) #define R_P0_EN_SOUND_WO_NDP 0x0D7C #define B_P0_EN_SOUND_WO_NDP BIT(1) #define R_SPOOF_ASYNC_RST 0x0D84 @@ -3506,6 +3519,9 @@ #define B_RXSCOBC_TH GENMASK(18, 0) #define R_RXSCOCCK 0x23B4 #define B_RXSCOCCK_TH GENMASK(18, 0) +#define R_P80_AT_HIGH_FREQ_RU_ALLOC 0x2410 +#define B_P80_AT_HIGH_FREQ_RU_ALLOC_PHY1 BIT(14) +#define B_P80_AT_HIGH_FREQ_RU_ALLOC_PHY0 BIT(13) #define R_DBCC_80P80_SEL_EVM_RPT2 0x2A10 #define B_DBCC_80P80_SEL_EVM_RPT2_EN BIT(0) #define R_P1_EN_SOUND_WO_NDP 0x2D7C @@ -3540,6 +3556,12 @@ #define R_CFO_TRK0 0x4404 #define R_CFO_TRK1 0x440C #define B_CFO_TRK_MSK GENMASK(14, 10) +#define R_T2F_GI_COMB 0x4424 +#define B_T2F_GI_COMB_EN BIT(2) +#define R_BT_DYN_DC_EST_EN 0x441C +#define B_BT_DYN_DC_EST_EN_MSK BIT(31) +#define R_ASSIGN_SBD_OPT 0x4450 +#define B_ASSIGN_SBD_OPT_EN BIT(24) #define R_DCFO_COMP_S0 0x448C #define B_DCFO_COMP_S0_MSK GENMASK(11, 0) #define R_DCFO_WEIGHT 0x4490 @@ -3554,6 +3576,22 @@ #define B_TXPWR_MSK GENMASK(30, 22) #define R_TXNSS_MAP 0x45B4 #define B_TXNSS_MAP_MSK GENMASK(20, 17) +#define R_PCOEFF0_V1 0x45BC +#define B_PCOEFF01_MSK_V1 GENMASK(23, 0) +#define R_PCOEFF2_V1 0x45CC +#define B_PCOEFF23_MSK_V1 GENMASK(23, 0) +#define R_PCOEFF4_V1 0x45D0 +#define B_PCOEFF45_MSK_V1 GENMASK(23, 0) +#define R_PCOEFF6_V1 0x45D4 +#define B_PCOEFF67_MSK_V1 GENMASK(23, 0) +#define R_PCOEFF8_V1 0x45D8 +#define B_PCOEFF89_MSK_V1 GENMASK(23, 0) +#define R_PCOEFFA_V1 0x45C0 +#define B_PCOEFFAB_MSK_V1 GENMASK(23, 0) +#define R_PCOEFFC_V1 0x45C4 +#define B_PCOEFFCD_MSK_V1 GENMASK(23, 0) +#define R_PCOEFFE_V1 0x45C8 +#define B_PCOEFFEF_MSK_V1 GENMASK(23, 0) #define R_PATH0_IB_PKPW 0x4628 #define B_PATH0_IB_PKPW_MSK GENMASK(11, 6) #define R_PATH0_LNA_ERR1 0x462C @@ -3601,6 +3639,14 @@ #define R_PATH0_G_TIA1_LNA6_OP1DB_V1 0x4694 #define B_PATH0_R_G_OFST_MASK GENMASK(23, 16) #define B_PATH0_G_TIA1_LNA6_OP1DB_V1 GENMASK(15, 8) +#define R_CDD_EVM_CHK_EN 0x46C0 +#define B_CDD_EVM_CHK_EN BIT(0) +#define R_PATH0_BAND_SEL_V1 0x4738 +#define B_PATH0_BAND_SEL_MSK_V1 BIT(17) +#define R_PATH0_BT_SHARE_V1 0x4738 +#define B_PATH0_BT_SHARE_V1 BIT(19) +#define R_PATH0_BTG_PATH_V1 0x4738 +#define B_PATH0_BTG_PATH_V1 BIT(22) #define R_P0_NBIIDX 0x469C #define B_P0_NBIIDX_VAL GENMASK(11, 0) #define B_P0_NBIIDX_NOTCH_EN BIT(12) @@ -3614,12 +3660,20 @@ #define B_PATH1_BTG_SHEN GENMASK(18, 17) #define R_PATH1_RXB_INIT 0x472C #define B_PATH1_RXB_INIT_IDX_MSK GENMASK(9, 5) +#define R_PATH1_G_LNA6_OP1DB_V1 0x476C +#define B_PATH1_G_LNA6_OP1DB_V1 GENMASK(31, 24) #define R_PATH1_P20_FOLLOW_BY_PAGCUGC 0x4774 #define B_PATH1_P20_FOLLOW_BY_PAGCUGC_EN_MSK BIT(5) #define R_PATH1_S20_FOLLOW_BY_PAGCUGC 0x4778 #define B_PATH1_S20_FOLLOW_BY_PAGCUGC_EN_MSK BIT(5) #define R_PATH1_G_TIA0_LNA6_OP1DB_V1 0x4778 #define B_PATH1_G_TIA0_LNA6_OP1DB_V1 GENMASK(7, 0) +#define R_PATH1_BAND_SEL_V1 0x4AA4 +#define B_PATH1_BAND_SEL_MSK_V1 BIT(17) +#define R_PATH1_BT_SHARE_V1 0x4AA4 +#define B_PATH1_BT_SHARE_V1 BIT(19) +#define R_PATH1_BTG_PATH_V1 0x4AA4 +#define B_PATH1_BTG_PATH_V1 BIT(22) #define R_P1_NBIIDX 0x4770 #define B_P1_NBIIDX_VAL GENMASK(11, 0) #define B_P1_NBIIDX_NOTCH_EN BIT(12) @@ -3631,9 +3685,28 @@ #define R_FC0_BW 0x4974 #define B_FC0_BW_INV GENMASK(6, 0) #define B_FC0_BW_SET GENMASK(31, 30) +#define B_ANT_RX_BT_SEG0 GENMASK(25, 22) +#define B_ANT_RX_1RCCA_SEG1 GENMASK(21, 18) +#define B_ANT_RX_1RCCA_SEG0 GENMASK(17, 14) #define R_CHBW_MOD 0x4978 -#define B_CHBW_MOD_PRICH GENMASK(11, 8) +#define B_BT_SHARE BIT(14) #define B_CHBW_MOD_SBW GENMASK(13, 12) +#define B_CHBW_MOD_PRICH GENMASK(11, 8) +#define B_ANT_RX_SEG0 GENMASK(3, 0) +#define R_BK_FC0_INV_V1 0x4A1C +#define B_BK_FC0_INV_MSK_V1 GENMASK(18, 0) +#define R_CCK_FC0_INV_V1 0x4A20 +#define B_CCK_FC0_INV_MSK_V1 GENMASK(18, 0) +#define R_PATH0_5MDET 0x4C4C +#define B_PATH0_5MDET_EN BIT(12) +#define B_PATH0_5MDET_SB2 BIT(8) +#define B_PATH0_5MDET_SB0 BIT(6) +#define B_PATH0_5MDET_TH GENMASK(5, 0) +#define R_PATH1_5MDET 0x4D10 +#define B_PATH1_5MDET_EN BIT(12) +#define B_PATH1_5MDET_SB2 BIT(8) +#define B_PATH1_5MDET_SB0 BIT(6) +#define B_PATH1_5MDET_TH GENMASK(5, 0) #define R_RPL_BIAS_COMP 0x4DF0 #define B_RPL_BIAS_COMP_MASK GENMASK(7, 0) #define R_RPL_PATHAB 0x4E0C @@ -3642,6 +3715,10 @@ #define R_RSSI_M_PATHAB 0x4E2C #define B_RSSI_M_PATHB_MASK GENMASK(15, 8) #define B_RSSI_M_PATHA_MASK GENMASK(7, 0) +#define R_FC0_V1 0x4E30 +#define B_FC0_MSK_V1 GENMASK(12, 0) +#define R_RX_BW40_2XFFT_EN_V1 0x4E30 +#define B_RX_BW40_2XFFT_EN_MSK_V1 BIT(26) #define R_DCFO_COMP_S0_V1 0x4A40 #define B_DCFO_COMP_S0_V1_MSK GENMASK(13, 0) #define R_BMODE_PDTH_V1 0x4B64 @@ -3880,6 +3957,14 @@ #define B_IQKINF2_FCNT GENMASK(23, 16) #define B_IQKINF2_KCNT GENMASK(15, 8) #define B_IQKINF2_NCTLV GENMAKS(7, 0) +#define R_PATH0_SAMPL_DLY_T_V1 0xC0D4 +#define B_PATH0_SAMPL_DLY_T_MSK_V1 GENMASK(27, 26) +#define R_PATH1_SAMPL_DLY_T_V1 0xC1D4 +#define B_PATH1_SAMPL_DLY_T_MSK_V1 GENMASK(27, 26) +#define R_PATH0_BW_SEL_V1 0xC0D8 +#define B_PATH0_BW_SEL_MSK_V1 GENMASK(8, 5) +#define R_PATH1_BW_SEL_V1 0xC1D8 +#define B_PATH1_BW_SEL_MSK_V1 GENMASK(8, 5) #define R_P0_CFCH_BW0 0xC0D4 #define B_P0_CFCH_BW0 GENMASK(27, 26) #define R_P0_CFCH_BW1 0xC0D8 diff --git a/drivers/net/wireless/realtek/rtw89/rtw8852c.c b/drivers/net/wireless/realtek/rtw89/rtw8852c.c index 07ff3bd50f62b..c5377e8843dd2 100644 --- a/drivers/net/wireless/realtek/rtw89/rtw8852c.c +++ b/drivers/net/wireless/realtek/rtw89/rtw8852c.c @@ -9,7 +9,9 @@ #include "phy.h" #include "reg.h" #include "rtw8852c.h" +#include "rtw8852c_rfk.h" #include "rtw8852c_table.h" +#include "util.h" static const struct rtw89_hfc_ch_cfg rtw8852c_hfc_chcfg_pcie[] = { {13, 1614, grp_0}, /* ACH 0 */ @@ -129,6 +131,8 @@ static const struct rtw89_imr_info rtw8852c_imr_info = { .tmac_imr_set = B_AX_TMAC_IMR_SET_V1, }; +static void rtw8852c_ctrl_btg(struct rtw89_dev *rtwdev, bool btg); + static int rtw8852c_pwr_on_func(struct rtw89_dev *rtwdev) { u32 val32; @@ -633,6 +637,40 @@ static void rtw8852c_set_channel_mac(struct rtw89_dev *rtwdev, rtw89_write8_set(rtwdev, chk_rate, chk_rate_mask); } +static const u32 rtw8852c_sco_barker_threshold[14] = { + 0x1fe4f, 0x1ff5e, 0x2006c, 0x2017b, 0x2028a, 0x20399, 0x204a8, 0x205b6, + 0x206c5, 0x207d4, 0x208e3, 0x209f2, 0x20b00, 0x20d8a +}; + +static const u32 rtw8852c_sco_cck_threshold[14] = { + 0x2bdac, 0x2bf21, 0x2c095, 0x2c209, 0x2c37e, 0x2c4f2, 0x2c666, 0x2c7db, + 0x2c94f, 0x2cac3, 0x2cc38, 0x2cdac, 0x2cf21, 0x2d29e +}; + +static int rtw8852c_ctrl_sco_cck(struct rtw89_dev *rtwdev, u8 central_ch, + u8 primary_ch, enum rtw89_bandwidth bw) +{ + u8 ch_element; + + if (bw == RTW89_CHANNEL_WIDTH_20) { + ch_element = central_ch - 1; + } else if (bw == RTW89_CHANNEL_WIDTH_40) { + if (primary_ch == 1) + ch_element = central_ch - 1 + 2; + else + ch_element = central_ch - 1 - 2; + } else { + rtw89_warn(rtwdev, "Invalid BW:%d for CCK\n", bw); + return -EINVAL; + } + rtw89_phy_write32_mask(rtwdev, R_BK_FC0_INV_V1, B_BK_FC0_INV_MSK_V1, + rtw8852c_sco_barker_threshold[ch_element]); + rtw89_phy_write32_mask(rtwdev, R_CCK_FC0_INV_V1, B_CCK_FC0_INV_MSK_V1, + rtw8852c_sco_cck_threshold[ch_element]); + + return 0; +} + struct rtw8852c_bb_gain { u32 gain_g[BB_PATH_NUM_8852C]; u32 gain_a[BB_PATH_NUM_8852C]; @@ -811,6 +849,76 @@ static void rtw8852c_set_gain_error(struct rtw89_dev *rtwdev, } } +static +const u8 rtw8852c_ch_base_table[16] = {1, 0xff, + 36, 100, 132, 149, 0xff, + 1, 33, 65, 97, 129, 161, 193, 225, 0xff}; +#define RTW8852C_CH_BASE_IDX_2G 0 +#define RTW8852C_CH_BASE_IDX_5G_FIRST 2 +#define RTW8852C_CH_BASE_IDX_5G_LAST 5 +#define RTW8852C_CH_BASE_IDX_6G_FIRST 7 +#define RTW8852C_CH_BASE_IDX_6G_LAST 14 + +#define RTW8852C_CH_BASE_IDX_MASK GENMASK(7, 4) +#define RTW8852C_CH_OFFSET_MASK GENMASK(3, 0) + +static u8 rtw8852c_encode_chan_idx(struct rtw89_dev *rtwdev, u8 central_ch, u8 band) +{ + u8 chan_idx; + u8 last, first; + u8 idx; + + switch (band) { + case RTW89_BAND_2G: + chan_idx = FIELD_PREP(RTW8852C_CH_BASE_IDX_MASK, RTW8852C_CH_BASE_IDX_2G) | + FIELD_PREP(RTW8852C_CH_OFFSET_MASK, central_ch); + return chan_idx; + case RTW89_BAND_5G: + first = RTW8852C_CH_BASE_IDX_5G_FIRST; + last = RTW8852C_CH_BASE_IDX_5G_LAST; + break; + case RTW89_BAND_6G: + first = RTW8852C_CH_BASE_IDX_6G_FIRST; + last = RTW8852C_CH_BASE_IDX_6G_LAST; + break; + default: + rtw89_warn(rtwdev, "Unsupported band %d\n", band); + return 0; + } + + for (idx = last; idx >= first; idx--) + if (central_ch >= rtw8852c_ch_base_table[idx]) + break; + + if (idx < first) { + rtw89_warn(rtwdev, "Unknown band %d channel %d\n", band, central_ch); + return 0; + } + + chan_idx = FIELD_PREP(RTW8852C_CH_BASE_IDX_MASK, idx) | + FIELD_PREP(RTW8852C_CH_OFFSET_MASK, + (central_ch - rtw8852c_ch_base_table[idx]) >> 1); + return chan_idx; +} + +static void rtw8852c_decode_chan_idx(struct rtw89_dev *rtwdev, u8 chan_idx, + u8 *ch, enum nl80211_band *band) +{ + u8 idx, offset; + + idx = FIELD_GET(RTW8852C_CH_BASE_IDX_MASK, chan_idx); + offset = FIELD_GET(RTW8852C_CH_OFFSET_MASK, chan_idx); + + if (idx == RTW8852C_CH_BASE_IDX_2G) { + *band = NL80211_BAND_2GHZ; + *ch = offset; + return; + } + + *band = idx <= RTW8852C_CH_BASE_IDX_5G_LAST ? NL80211_BAND_5GHZ : NL80211_BAND_6GHZ; + *ch = rtw8852c_ch_base_table[idx] + (offset << 1); +} + static void rtw8852c_set_gain_offset(struct rtw89_dev *rtwdev, const struct rtw89_channel_params *param, enum rtw89_phy_idx phy_idx, @@ -868,6 +976,478 @@ static void rtw8852c_set_gain_offset(struct rtw89_dev *rtwdev, rtw89_phy_write32_idx(rtwdev, R_RSSI_M_PATHAB, rpl_tb_mask[path], tmp & 0xff, phy_idx); } +static void rtw8852c_ctrl_ch(struct rtw89_dev *rtwdev, + const struct rtw89_channel_params *param, + enum rtw89_phy_idx phy_idx) +{ + u8 sco; + u16 central_freq = param->center_freq; + u8 central_ch = param->center_chan; + u8 band = param->band_type; + u8 subband = param->subband_type; + bool is_2g = band == RTW89_BAND_2G; + u8 chan_idx; + + if (!central_freq) { + rtw89_warn(rtwdev, "Invalid central_freq\n"); + return; + } + + if (phy_idx == RTW89_PHY_0) { + /* Path A */ + rtw8852c_set_gain_error(rtwdev, subband, RF_PATH_A); + rtw8852c_set_gain_offset(rtwdev, param, phy_idx, RF_PATH_A); + + if (is_2g) + rtw89_phy_write32_idx(rtwdev, R_PATH0_BAND_SEL_V1, + B_PATH0_BAND_SEL_MSK_V1, 1, + phy_idx); + else + rtw89_phy_write32_idx(rtwdev, R_PATH0_BAND_SEL_V1, + B_PATH0_BAND_SEL_MSK_V1, 0, + phy_idx); + /* Path B */ + if (!rtwdev->dbcc_en) { + rtw8852c_set_gain_error(rtwdev, subband, RF_PATH_B); + rtw8852c_set_gain_offset(rtwdev, param, phy_idx, RF_PATH_B); + + if (is_2g) + rtw89_phy_write32_idx(rtwdev, + R_PATH1_BAND_SEL_V1, + B_PATH1_BAND_SEL_MSK_V1, + 1, phy_idx); + else + rtw89_phy_write32_idx(rtwdev, + R_PATH1_BAND_SEL_V1, + B_PATH1_BAND_SEL_MSK_V1, + 0, phy_idx); + rtw89_phy_write32_clr(rtwdev, R_2P4G_BAND, B_2P4G_BAND_SEL); + } else { + if (is_2g) + rtw89_phy_write32_clr(rtwdev, R_2P4G_BAND, B_2P4G_BAND_SEL); + else + rtw89_phy_write32_set(rtwdev, R_2P4G_BAND, B_2P4G_BAND_SEL); + } + /* SCO compensate FC setting */ + rtw89_phy_write32_idx(rtwdev, R_FC0_V1, B_FC0_MSK_V1, + central_freq, phy_idx); + /* round_up((1/fc0)*pow(2,18)) */ + sco = DIV_ROUND_CLOSEST(1 << 18, central_freq); + rtw89_phy_write32_idx(rtwdev, R_FC0_BW, B_FC0_BW_INV, sco, + phy_idx); + } else { + /* Path B */ + rtw8852c_set_gain_error(rtwdev, subband, RF_PATH_B); + rtw8852c_set_gain_offset(rtwdev, param, phy_idx, RF_PATH_B); + + if (is_2g) + rtw89_phy_write32_idx(rtwdev, R_PATH1_BAND_SEL_V1, + B_PATH1_BAND_SEL_MSK_V1, + 1, phy_idx); + else + rtw89_phy_write32_idx(rtwdev, R_PATH1_BAND_SEL_V1, + B_PATH1_BAND_SEL_MSK_V1, + 0, phy_idx); + /* SCO compensate FC setting */ + rtw89_phy_write32_idx(rtwdev, R_FC0_V1, B_FC0_MSK_V1, + central_freq, phy_idx); + /* round_up((1/fc0)*pow(2,18)) */ + sco = DIV_ROUND_CLOSEST(1 << 18, central_freq); + rtw89_phy_write32_idx(rtwdev, R_FC0_BW, B_FC0_BW_INV, sco, + phy_idx); + } + /* CCK parameters */ + if (band == RTW89_BAND_2G) { + if (central_ch == 14) { + rtw89_phy_write32_mask(rtwdev, R_PCOEFF0_V1, + B_PCOEFF01_MSK_V1, 0x3b13ff); + rtw89_phy_write32_mask(rtwdev, R_PCOEFF2_V1, + B_PCOEFF23_MSK_V1, 0x1c42de); + rtw89_phy_write32_mask(rtwdev, R_PCOEFF4_V1, + B_PCOEFF45_MSK_V1, 0xfdb0ad); + rtw89_phy_write32_mask(rtwdev, R_PCOEFF6_V1, + B_PCOEFF67_MSK_V1, 0xf60f6e); + rtw89_phy_write32_mask(rtwdev, R_PCOEFF8_V1, + B_PCOEFF89_MSK_V1, 0xfd8f92); + rtw89_phy_write32_mask(rtwdev, R_PCOEFFA_V1, + B_PCOEFFAB_MSK_V1, 0x2d011); + rtw89_phy_write32_mask(rtwdev, R_PCOEFFC_V1, + B_PCOEFFCD_MSK_V1, 0x1c02c); + rtw89_phy_write32_mask(rtwdev, R_PCOEFFE_V1, + B_PCOEFFEF_MSK_V1, 0xfff00a); + } else { + rtw89_phy_write32_mask(rtwdev, R_PCOEFF0_V1, + B_PCOEFF01_MSK_V1, 0x3d23ff); + rtw89_phy_write32_mask(rtwdev, R_PCOEFF2_V1, + B_PCOEFF23_MSK_V1, 0x29b354); + rtw89_phy_write32_mask(rtwdev, R_PCOEFF4_V1, + B_PCOEFF45_MSK_V1, 0xfc1c8); + rtw89_phy_write32_mask(rtwdev, R_PCOEFF6_V1, + B_PCOEFF67_MSK_V1, 0xfdb053); + rtw89_phy_write32_mask(rtwdev, R_PCOEFF8_V1, + B_PCOEFF89_MSK_V1, 0xf86f9a); + rtw89_phy_write32_mask(rtwdev, R_PCOEFFA_V1, + B_PCOEFFAB_MSK_V1, 0xfaef92); + rtw89_phy_write32_mask(rtwdev, R_PCOEFFC_V1, + B_PCOEFFCD_MSK_V1, 0xfe5fcc); + rtw89_phy_write32_mask(rtwdev, R_PCOEFFE_V1, + B_PCOEFFEF_MSK_V1, 0xffdff5); + } + } + + chan_idx = rtw8852c_encode_chan_idx(rtwdev, param->primary_chan, band); + rtw89_phy_write32_idx(rtwdev, R_MAC_PIN_SEL, B_CH_IDX_SEG0, chan_idx, phy_idx); +} + +static void rtw8852c_bw_setting(struct rtw89_dev *rtwdev, u8 bw, u8 path) +{ + static const u32 adc_sel[2] = {0xC0EC, 0xC1EC}; + static const u32 wbadc_sel[2] = {0xC0E4, 0xC1E4}; + + switch (bw) { + case RTW89_CHANNEL_WIDTH_5: + rtw89_phy_write32_mask(rtwdev, adc_sel[path], 0x6000, 0x1); + rtw89_phy_write32_mask(rtwdev, wbadc_sel[path], 0x30, 0x0); + break; + case RTW89_CHANNEL_WIDTH_10: + rtw89_phy_write32_mask(rtwdev, adc_sel[path], 0x6000, 0x2); + rtw89_phy_write32_mask(rtwdev, wbadc_sel[path], 0x30, 0x1); + break; + case RTW89_CHANNEL_WIDTH_20: + case RTW89_CHANNEL_WIDTH_40: + case RTW89_CHANNEL_WIDTH_80: + case RTW89_CHANNEL_WIDTH_160: + rtw89_phy_write32_mask(rtwdev, adc_sel[path], 0x6000, 0x0); + rtw89_phy_write32_mask(rtwdev, wbadc_sel[path], 0x30, 0x2); + break; + default: + rtw89_warn(rtwdev, "Fail to set ADC\n"); + } +} + +static void rtw8852c_edcca_per20_bitmap_sifs(struct rtw89_dev *rtwdev, u8 bw, + enum rtw89_phy_idx phy_idx) +{ + if (bw == RTW89_CHANNEL_WIDTH_20) { + rtw89_phy_write32_idx(rtwdev, R_SNDCCA_A1, B_SNDCCA_A1_EN, 0xff, phy_idx); + rtw89_phy_write32_idx(rtwdev, R_SNDCCA_A2, B_SNDCCA_A2_VAL, 0, phy_idx); + } else { + rtw89_phy_write32_idx(rtwdev, R_SNDCCA_A1, B_SNDCCA_A1_EN, 0, phy_idx); + rtw89_phy_write32_idx(rtwdev, R_SNDCCA_A2, B_SNDCCA_A2_VAL, 0, phy_idx); + } +} + +static void +rtw8852c_ctrl_bw(struct rtw89_dev *rtwdev, u8 pri_ch, u8 bw, + enum rtw89_phy_idx phy_idx) +{ + u8 mod_sbw = 0; + + switch (bw) { + case RTW89_CHANNEL_WIDTH_5: + case RTW89_CHANNEL_WIDTH_10: + case RTW89_CHANNEL_WIDTH_20: + if (bw == RTW89_CHANNEL_WIDTH_5) + mod_sbw = 0x1; + else if (bw == RTW89_CHANNEL_WIDTH_10) + mod_sbw = 0x2; + else if (bw == RTW89_CHANNEL_WIDTH_20) + mod_sbw = 0x0; + rtw89_phy_write32_idx(rtwdev, R_FC0_BW, B_FC0_BW_SET, 0x0, + phy_idx); + rtw89_phy_write32_idx(rtwdev, R_CHBW_MOD, B_CHBW_MOD_SBW, + mod_sbw, phy_idx); + rtw89_phy_write32_idx(rtwdev, R_CHBW_MOD, B_CHBW_MOD_PRICH, 0x0, + phy_idx); + rtw89_phy_write32_mask(rtwdev, R_PATH0_SAMPL_DLY_T_V1, + B_PATH0_SAMPL_DLY_T_MSK_V1, 0x3); + rtw89_phy_write32_mask(rtwdev, R_PATH1_SAMPL_DLY_T_V1, + B_PATH1_SAMPL_DLY_T_MSK_V1, 0x3); + rtw89_phy_write32_mask(rtwdev, R_PATH0_BW_SEL_V1, + B_PATH0_BW_SEL_MSK_V1, 0xf); + rtw89_phy_write32_mask(rtwdev, R_PATH1_BW_SEL_V1, + B_PATH1_BW_SEL_MSK_V1, 0xf); + break; + case RTW89_CHANNEL_WIDTH_40: + rtw89_phy_write32_idx(rtwdev, R_FC0_BW, B_FC0_BW_SET, 0x1, + phy_idx); + rtw89_phy_write32_idx(rtwdev, R_CHBW_MOD, B_CHBW_MOD_SBW, 0x0, + phy_idx); + rtw89_phy_write32_idx(rtwdev, R_CHBW_MOD, B_CHBW_MOD_PRICH, + pri_ch, + phy_idx); + rtw89_phy_write32_mask(rtwdev, R_PATH0_SAMPL_DLY_T_V1, + B_PATH0_SAMPL_DLY_T_MSK_V1, 0x3); + rtw89_phy_write32_mask(rtwdev, R_PATH1_SAMPL_DLY_T_V1, + B_PATH1_SAMPL_DLY_T_MSK_V1, 0x3); + rtw89_phy_write32_mask(rtwdev, R_PATH0_BW_SEL_V1, + B_PATH0_BW_SEL_MSK_V1, 0xf); + rtw89_phy_write32_mask(rtwdev, R_PATH1_BW_SEL_V1, + B_PATH1_BW_SEL_MSK_V1, 0xf); + break; + case RTW89_CHANNEL_WIDTH_80: + rtw89_phy_write32_idx(rtwdev, R_FC0_BW, B_FC0_BW_SET, 0x2, + phy_idx); + rtw89_phy_write32_idx(rtwdev, R_CHBW_MOD, B_CHBW_MOD_SBW, 0x0, + phy_idx); + rtw89_phy_write32_idx(rtwdev, R_CHBW_MOD, B_CHBW_MOD_PRICH, + pri_ch, + phy_idx); + rtw89_phy_write32_mask(rtwdev, R_PATH0_SAMPL_DLY_T_V1, + B_PATH0_SAMPL_DLY_T_MSK_V1, 0x2); + rtw89_phy_write32_mask(rtwdev, R_PATH1_SAMPL_DLY_T_V1, + B_PATH1_SAMPL_DLY_T_MSK_V1, 0x2); + rtw89_phy_write32_mask(rtwdev, R_PATH0_BW_SEL_V1, + B_PATH0_BW_SEL_MSK_V1, 0xd); + rtw89_phy_write32_mask(rtwdev, R_PATH1_BW_SEL_V1, + B_PATH1_BW_SEL_MSK_V1, 0xd); + break; + case RTW89_CHANNEL_WIDTH_160: + rtw89_phy_write32_idx(rtwdev, R_FC0_BW, B_FC0_BW_SET, 0x3, + phy_idx); + rtw89_phy_write32_idx(rtwdev, R_CHBW_MOD, B_CHBW_MOD_SBW, 0x0, + phy_idx); + rtw89_phy_write32_idx(rtwdev, R_CHBW_MOD, B_CHBW_MOD_PRICH, + pri_ch, + phy_idx); + rtw89_phy_write32_mask(rtwdev, R_PATH0_SAMPL_DLY_T_V1, + B_PATH0_SAMPL_DLY_T_MSK_V1, 0x1); + rtw89_phy_write32_mask(rtwdev, R_PATH1_SAMPL_DLY_T_V1, + B_PATH1_SAMPL_DLY_T_MSK_V1, 0x1); + rtw89_phy_write32_mask(rtwdev, R_PATH0_BW_SEL_V1, + B_PATH0_BW_SEL_MSK_V1, 0xb); + rtw89_phy_write32_mask(rtwdev, R_PATH1_BW_SEL_V1, + B_PATH1_BW_SEL_MSK_V1, 0xb); + break; + default: + rtw89_warn(rtwdev, "Fail to switch bw (bw:%d, pri ch:%d)\n", bw, + pri_ch); + } + + if (bw == RTW89_CHANNEL_WIDTH_40) { + rtw89_phy_write32_idx(rtwdev, R_RX_BW40_2XFFT_EN_V1, + B_RX_BW40_2XFFT_EN_MSK_V1, 0x1, phy_idx); + rtw89_phy_write32_idx(rtwdev, R_T2F_GI_COMB, B_T2F_GI_COMB_EN, 1, phy_idx); + } else { + rtw89_phy_write32_idx(rtwdev, R_RX_BW40_2XFFT_EN_V1, + B_RX_BW40_2XFFT_EN_MSK_V1, 0x0, phy_idx); + rtw89_phy_write32_idx(rtwdev, R_T2F_GI_COMB, B_T2F_GI_COMB_EN, 0, phy_idx); + } + + if (phy_idx == RTW89_PHY_0) { + rtw8852c_bw_setting(rtwdev, bw, RF_PATH_A); + if (!rtwdev->dbcc_en) + rtw8852c_bw_setting(rtwdev, bw, RF_PATH_B); + } else { + rtw8852c_bw_setting(rtwdev, bw, RF_PATH_B); + } + + rtw8852c_edcca_per20_bitmap_sifs(rtwdev, bw, phy_idx); +} + +static u32 rtw8852c_spur_freq(struct rtw89_dev *rtwdev, + struct rtw89_channel_params *param) +{ + u8 center_chan = param->center_chan; + u8 bw = param->bandwidth; + + switch (param->band_type) { + case RTW89_BAND_2G: + if (bw == RTW89_CHANNEL_WIDTH_20) { + if (center_chan >= 5 && center_chan <= 8) + return 2440; + if (center_chan == 13) + return 2480; + } else if (bw == RTW89_CHANNEL_WIDTH_40) { + if (center_chan >= 3 && center_chan <= 10) + return 2440; + } + break; + case RTW89_BAND_5G: + if (center_chan == 151 || center_chan == 153 || + center_chan == 155 || center_chan == 163) + return 5760; + break; + case RTW89_BAND_6G: + if (center_chan == 195 || center_chan == 197 || + center_chan == 199 || center_chan == 207) + return 6920; + break; + default: + break; + } + + return 0; +} + +#define CARRIER_SPACING_312_5 312500 /* 312.5 kHz */ +#define CARRIER_SPACING_78_125 78125 /* 78.125 kHz */ +#define MAX_TONE_NUM 2048 + +static void rtw8852c_set_csi_tone_idx(struct rtw89_dev *rtwdev, + struct rtw89_channel_params *param, + enum rtw89_phy_idx phy_idx) +{ + u32 spur_freq; + s32 freq_diff, csi_idx, csi_tone_idx; + + spur_freq = rtw8852c_spur_freq(rtwdev, param); + if (spur_freq == 0) { + rtw89_phy_write32_idx(rtwdev, R_SEG0CSI_EN, B_SEG0CSI_EN, 0, phy_idx); + return; + } + + freq_diff = (spur_freq - param->center_freq) * 1000000; + csi_idx = s32_div_u32_round_closest(freq_diff, CARRIER_SPACING_78_125); + s32_div_u32_round_down(csi_idx, MAX_TONE_NUM, &csi_tone_idx); + + rtw89_phy_write32_idx(rtwdev, R_SEG0CSI, B_SEG0CSI_IDX, csi_tone_idx, phy_idx); + rtw89_phy_write32_idx(rtwdev, R_SEG0CSI_EN, B_SEG0CSI_EN, 1, phy_idx); +} + +static const struct rtw89_nbi_reg_def rtw8852c_nbi_reg_def[] = { + [RF_PATH_A] = { + .notch1_idx = {0x4C14, 0xFF}, + .notch1_frac_idx = {0x4C14, 0xC00}, + .notch1_en = {0x4C14, 0x1000}, + .notch2_idx = {0x4C20, 0xFF}, + .notch2_frac_idx = {0x4C20, 0xC00}, + .notch2_en = {0x4C20, 0x1000}, + }, + [RF_PATH_B] = { + .notch1_idx = {0x4CD8, 0xFF}, + .notch1_frac_idx = {0x4CD8, 0xC00}, + .notch1_en = {0x4CD8, 0x1000}, + .notch2_idx = {0x4CE4, 0xFF}, + .notch2_frac_idx = {0x4CE4, 0xC00}, + .notch2_en = {0x4CE4, 0x1000}, + }, +}; + +static void rtw8852c_set_nbi_tone_idx(struct rtw89_dev *rtwdev, + struct rtw89_channel_params *param, + enum rtw89_rf_path path) +{ + const struct rtw89_nbi_reg_def *nbi = &rtw8852c_nbi_reg_def[path]; + u32 spur_freq, fc; + s32 freq_diff; + s32 nbi_idx, nbi_tone_idx; + s32 nbi_frac_idx, nbi_frac_tone_idx; + bool notch2_chk = false; + + spur_freq = rtw8852c_spur_freq(rtwdev, param); + if (spur_freq == 0) { + rtw89_phy_write32_mask(rtwdev, nbi->notch1_en.addr, nbi->notch1_en.mask, 0); + rtw89_phy_write32_mask(rtwdev, nbi->notch1_en.addr, nbi->notch1_en.mask, 0); + return; + } + + fc = param->center_freq; + if (param->bandwidth == RTW89_CHANNEL_WIDTH_160) { + fc = (spur_freq > fc) ? fc + 40 : fc - 40; + if ((fc > spur_freq && param->center_chan < param->primary_chan) || + (fc < spur_freq && param->center_chan > param->primary_chan)) + notch2_chk = true; + } + + freq_diff = (spur_freq - fc) * 1000000; + nbi_idx = s32_div_u32_round_down(freq_diff, CARRIER_SPACING_312_5, &nbi_frac_idx); + + if (param->bandwidth == RTW89_CHANNEL_WIDTH_20) { + s32_div_u32_round_down(nbi_idx + 32, 64, &nbi_tone_idx); + } else { + u16 tone_para = (param->bandwidth == RTW89_CHANNEL_WIDTH_40) ? 128 : 256; + + s32_div_u32_round_down(nbi_idx, tone_para, &nbi_tone_idx); + } + nbi_frac_tone_idx = s32_div_u32_round_closest(nbi_frac_idx, CARRIER_SPACING_78_125); + + if (param->bandwidth == RTW89_CHANNEL_WIDTH_160 && notch2_chk) { + rtw89_phy_write32_mask(rtwdev, nbi->notch2_idx.addr, + nbi->notch2_idx.mask, nbi_tone_idx); + rtw89_phy_write32_mask(rtwdev, nbi->notch2_frac_idx.addr, + nbi->notch2_frac_idx.mask, nbi_frac_tone_idx); + rtw89_phy_write32_mask(rtwdev, nbi->notch2_en.addr, nbi->notch2_en.mask, 0); + rtw89_phy_write32_mask(rtwdev, nbi->notch2_en.addr, nbi->notch2_en.mask, 1); + rtw89_phy_write32_mask(rtwdev, nbi->notch1_en.addr, nbi->notch1_en.mask, 0); + } else { + rtw89_phy_write32_mask(rtwdev, nbi->notch1_idx.addr, + nbi->notch1_idx.mask, nbi_tone_idx); + rtw89_phy_write32_mask(rtwdev, nbi->notch1_frac_idx.addr, + nbi->notch1_frac_idx.mask, nbi_frac_tone_idx); + rtw89_phy_write32_mask(rtwdev, nbi->notch1_en.addr, nbi->notch1_en.mask, 0); + rtw89_phy_write32_mask(rtwdev, nbi->notch1_en.addr, nbi->notch1_en.mask, 1); + rtw89_phy_write32_mask(rtwdev, nbi->notch2_en.addr, nbi->notch2_en.mask, 0); + } +} + +static void rtw8852c_spur_elimination(struct rtw89_dev *rtwdev, + struct rtw89_channel_params *param, + enum rtw89_phy_idx phy_idx) +{ + rtw8852c_set_csi_tone_idx(rtwdev, param, phy_idx); + + if (phy_idx == RTW89_PHY_0) { + rtw8852c_set_nbi_tone_idx(rtwdev, param, RF_PATH_A); + if (!rtwdev->dbcc_en) + rtw8852c_set_nbi_tone_idx(rtwdev, param, RF_PATH_B); + } else { + rtw8852c_set_nbi_tone_idx(rtwdev, param, RF_PATH_B); + } +} + +static void rtw8852c_5m_mask(struct rtw89_dev *rtwdev, + struct rtw89_channel_params *param, + enum rtw89_phy_idx phy_idx) +{ + u8 pri_ch = param->primary_chan; + bool mask_5m_low; + bool mask_5m_en; + + switch (param->bandwidth) { + case RTW89_CHANNEL_WIDTH_40: + mask_5m_en = true; + mask_5m_low = pri_ch == 2; + break; + case RTW89_CHANNEL_WIDTH_80: + mask_5m_en = ((pri_ch == 3) || (pri_ch == 4)); + mask_5m_low = pri_ch == 4; + break; + default: + mask_5m_en = false; + mask_5m_low = false; + break; + } + + if (!mask_5m_en) { + rtw89_phy_write32_mask(rtwdev, R_PATH0_5MDET, B_PATH0_5MDET_EN, 0x0); + rtw89_phy_write32_mask(rtwdev, R_PATH1_5MDET, B_PATH1_5MDET_EN, 0x0); + rtw89_phy_write32_idx(rtwdev, R_ASSIGN_SBD_OPT, + B_ASSIGN_SBD_OPT_EN, 0x0, phy_idx); + } else { + if (mask_5m_low) { + rtw89_phy_write32_mask(rtwdev, R_PATH0_5MDET, B_PATH0_5MDET_TH, 0x4); + rtw89_phy_write32_mask(rtwdev, R_PATH0_5MDET, B_PATH0_5MDET_EN, 0x1); + rtw89_phy_write32_mask(rtwdev, R_PATH0_5MDET, B_PATH0_5MDET_SB2, 0x0); + rtw89_phy_write32_mask(rtwdev, R_PATH0_5MDET, B_PATH0_5MDET_SB0, 0x1); + rtw89_phy_write32_mask(rtwdev, R_PATH1_5MDET, B_PATH1_5MDET_TH, 0x4); + rtw89_phy_write32_mask(rtwdev, R_PATH1_5MDET, B_PATH1_5MDET_EN, 0x1); + rtw89_phy_write32_mask(rtwdev, R_PATH1_5MDET, B_PATH1_5MDET_SB2, 0x0); + rtw89_phy_write32_mask(rtwdev, R_PATH1_5MDET, B_PATH1_5MDET_SB0, 0x1); + } else { + rtw89_phy_write32_mask(rtwdev, R_PATH0_5MDET, B_PATH0_5MDET_TH, 0x4); + rtw89_phy_write32_mask(rtwdev, R_PATH0_5MDET, B_PATH0_5MDET_EN, 0x1); + rtw89_phy_write32_mask(rtwdev, R_PATH0_5MDET, B_PATH0_5MDET_SB2, 0x1); + rtw89_phy_write32_mask(rtwdev, R_PATH0_5MDET, B_PATH0_5MDET_SB0, 0x0); + rtw89_phy_write32_mask(rtwdev, R_PATH1_5MDET, B_PATH1_5MDET_TH, 0x4); + rtw89_phy_write32_mask(rtwdev, R_PATH1_5MDET, B_PATH1_5MDET_EN, 0x1); + rtw89_phy_write32_mask(rtwdev, R_PATH1_5MDET, B_PATH1_5MDET_SB2, 0x1); + rtw89_phy_write32_mask(rtwdev, R_PATH1_5MDET, B_PATH1_5MDET_SB0, 0x0); + } + rtw89_phy_write32_idx(rtwdev, R_ASSIGN_SBD_OPT, B_ASSIGN_SBD_OPT_EN, 0x1, phy_idx); + } +} + static void rtw8852c_bb_reset_all(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy_idx) { @@ -1056,6 +1636,97 @@ static void rtw8852c_bb_sethw(struct rtw89_dev *rtwdev) rtw89_phy_read32_mask(rtwdev, R_RPL_BIAS_COMP1, B_RPL_BIAS_COMP1_MASK); } +static void rtw8852c_set_channel_bb(struct rtw89_dev *rtwdev, + struct rtw89_channel_params *param, + enum rtw89_phy_idx phy_idx) +{ + bool cck_en = param->band_type == RTW89_BAND_2G; + u8 pri_ch_idx = param->pri_ch_idx; + u32 mask, reg; + u32 ru_alloc_msk[2] = {B_P80_AT_HIGH_FREQ_RU_ALLOC_PHY0, + B_P80_AT_HIGH_FREQ_RU_ALLOC_PHY1}; + + if (param->band_type == RTW89_BAND_2G) + rtw8852c_ctrl_sco_cck(rtwdev, param->center_chan, + param->primary_chan, param->bandwidth); + + rtw8852c_ctrl_ch(rtwdev, param, phy_idx); + rtw8852c_ctrl_bw(rtwdev, pri_ch_idx, param->bandwidth, phy_idx); + if (cck_en) { + rtw89_phy_write32_mask(rtwdev, R_UPD_CLK_ADC, B_ENABLE_CCK, 1); + rtw89_phy_write32_mask(rtwdev, R_RXCCA_V1, B_RXCCA_DIS_V1, 0); + rtw89_phy_write32_idx(rtwdev, R_PD_ARBITER_OFF, + B_PD_ARBITER_OFF, 0x0, phy_idx); + } else { + rtw89_phy_write32_mask(rtwdev, R_UPD_CLK_ADC, B_ENABLE_CCK, 0); + rtw89_phy_write32_mask(rtwdev, R_RXCCA_V1, B_RXCCA_DIS_V1, 1); + rtw89_phy_write32_idx(rtwdev, R_PD_ARBITER_OFF, + B_PD_ARBITER_OFF, 0x1, phy_idx); + } + + rtw8852c_spur_elimination(rtwdev, param, phy_idx); + rtw8852c_ctrl_btg(rtwdev, param->band_type == RTW89_BAND_2G); + rtw8852c_5m_mask(rtwdev, param, phy_idx); + + if (param->bandwidth == RTW89_CHANNEL_WIDTH_160 && + rtwdev->hal.cv != CHIP_CAV) { + rtw89_phy_write32_idx(rtwdev, R_P80_AT_HIGH_FREQ, + B_P80_AT_HIGH_FREQ, 0x0, phy_idx); + reg = rtw89_mac_reg_by_idx(R_P80_AT_HIGH_FREQ_BB_WRP, + phy_idx); + if (param->primary_chan > param->center_chan) { + rtw89_phy_write32_mask(rtwdev, + R_P80_AT_HIGH_FREQ_RU_ALLOC, + ru_alloc_msk[phy_idx], 1); + rtw89_write32_mask(rtwdev, reg, + B_P80_AT_HIGH_FREQ_BB_WRP, 1); + } else { + rtw89_phy_write32_mask(rtwdev, + R_P80_AT_HIGH_FREQ_RU_ALLOC, + ru_alloc_msk[phy_idx], 0); + rtw89_write32_mask(rtwdev, reg, + B_P80_AT_HIGH_FREQ_BB_WRP, 0); + } + } + + if (param->band_type == RTW89_BAND_6G && + param->bandwidth == RTW89_CHANNEL_WIDTH_160) + rtw89_phy_write32_idx(rtwdev, R_CDD_EVM_CHK_EN, + B_CDD_EVM_CHK_EN, 0, phy_idx); + else + rtw89_phy_write32_idx(rtwdev, R_CDD_EVM_CHK_EN, + B_CDD_EVM_CHK_EN, 1, phy_idx); + + if (!rtwdev->dbcc_en) { + mask = B_P0_TXPW_RSTB_TSSI | B_P0_TXPW_RSTB_MANON; + rtw89_phy_write32_mask(rtwdev, R_P0_TXPW_RSTB, mask, 0x1); + rtw89_phy_write32_mask(rtwdev, R_P0_TXPW_RSTB, mask, 0x3); + mask = B_P1_TXPW_RSTB_TSSI | B_P1_TXPW_RSTB_MANON; + rtw89_phy_write32_mask(rtwdev, R_P1_TXPW_RSTB, mask, 0x1); + rtw89_phy_write32_mask(rtwdev, R_P1_TXPW_RSTB, mask, 0x3); + } else { + if (phy_idx == RTW89_PHY_0) { + mask = B_P0_TXPW_RSTB_TSSI | B_P0_TXPW_RSTB_MANON; + rtw89_phy_write32_mask(rtwdev, R_P0_TXPW_RSTB, mask, 0x1); + rtw89_phy_write32_mask(rtwdev, R_P0_TXPW_RSTB, mask, 0x3); + } else { + mask = B_P1_TXPW_RSTB_TSSI | B_P1_TXPW_RSTB_MANON; + rtw89_phy_write32_mask(rtwdev, R_P1_TXPW_RSTB, mask, 0x1); + rtw89_phy_write32_mask(rtwdev, R_P1_TXPW_RSTB, mask, 0x3); + } + } + + rtw8852c_bb_reset_all(rtwdev, phy_idx); +} + +static void rtw8852c_set_channel(struct rtw89_dev *rtwdev, + struct rtw89_channel_params *params) +{ + rtw8852c_set_channel_mac(rtwdev, params, RTW89_MAC_0); + rtw8852c_set_channel_bb(rtwdev, params, RTW89_PHY_0); + rtw8852c_set_channel_rf(rtwdev, params, RTW89_PHY_0); +} + static void rtw8852c_set_txpwr_ul_tb_offset(struct rtw89_dev *rtwdev, s8 pw_ofst, enum rtw89_mac_idx mac_idx) @@ -1091,6 +1762,52 @@ void rtw8852c_set_txpwr_ul_tb_offset(struct rtw89_dev *rtwdev, } } +static void rtw8852c_ctrl_btg(struct rtw89_dev *rtwdev, bool btg) +{ + if (btg) { + rtw89_phy_write32_mask(rtwdev, R_PATH0_BT_SHARE_V1, + B_PATH0_BT_SHARE_V1, 0x1); + rtw89_phy_write32_mask(rtwdev, R_PATH0_BTG_PATH_V1, + B_PATH0_BTG_PATH_V1, 0x0); + rtw89_phy_write32_mask(rtwdev, R_PATH1_G_LNA6_OP1DB_V1, + B_PATH1_G_LNA6_OP1DB_V1, 0x20); + rtw89_phy_write32_mask(rtwdev, R_PATH1_G_TIA0_LNA6_OP1DB_V1, + B_PATH1_G_TIA0_LNA6_OP1DB_V1, 0x30); + rtw89_phy_write32_mask(rtwdev, R_PATH1_BT_SHARE_V1, + B_PATH1_BT_SHARE_V1, 0x1); + rtw89_phy_write32_mask(rtwdev, R_PATH1_BTG_PATH_V1, + B_PATH1_BTG_PATH_V1, 0x1); + rtw89_phy_write32_mask(rtwdev, R_PMAC_GNT, B_PMAC_GNT_P1, 0x0); + rtw89_phy_write32_mask(rtwdev, R_CHBW_MOD, B_BT_SHARE, 0x1); + rtw89_phy_write32_mask(rtwdev, R_FC0_BW, B_ANT_RX_BT_SEG0, 0x2); + rtw89_phy_write32_mask(rtwdev, R_BT_DYN_DC_EST_EN, + B_BT_DYN_DC_EST_EN_MSK, 0x1); + rtw89_phy_write32_mask(rtwdev, R_GNT_BT_WGT_EN, B_GNT_BT_WGT_EN, + 0x1); + } else { + rtw89_phy_write32_mask(rtwdev, R_PATH0_BT_SHARE_V1, + B_PATH0_BT_SHARE_V1, 0x0); + rtw89_phy_write32_mask(rtwdev, R_PATH0_BTG_PATH_V1, + B_PATH0_BTG_PATH_V1, 0x0); + rtw89_phy_write32_mask(rtwdev, R_PATH1_G_LNA6_OP1DB_V1, + B_PATH1_G_LNA6_OP1DB_V1, 0x1a); + rtw89_phy_write32_mask(rtwdev, R_PATH1_G_TIA0_LNA6_OP1DB_V1, + B_PATH1_G_TIA0_LNA6_OP1DB_V1, 0x2a); + rtw89_phy_write32_mask(rtwdev, R_PATH1_BT_SHARE_V1, + B_PATH1_BT_SHARE_V1, 0x0); + rtw89_phy_write32_mask(rtwdev, R_PATH1_BTG_PATH_V1, + B_PATH1_BTG_PATH_V1, 0x0); + rtw89_phy_write32_mask(rtwdev, R_PMAC_GNT, B_PMAC_GNT_P1, 0xf); + rtw89_phy_write32_mask(rtwdev, R_PMAC_GNT, B_PMAC_GNT_P2, 0x4); + rtw89_phy_write32_mask(rtwdev, R_CHBW_MOD, B_BT_SHARE, 0x0); + rtw89_phy_write32_mask(rtwdev, R_FC0_BW, B_ANT_RX_BT_SEG0, 0x0); + rtw89_phy_write32_mask(rtwdev, R_BT_DYN_DC_EST_EN, + B_BT_DYN_DC_EST_EN_MSK, 0x0); + rtw89_phy_write32_mask(rtwdev, R_GNT_BT_WGT_EN, B_GNT_BT_WGT_EN, + 0x0); + } +} + static void rtw8852c_set_trx_mask(struct rtw89_dev *rtwdev, u8 path, u8 group, u32 val) { @@ -1195,6 +1912,7 @@ static const struct rtw89_chip_ops rtw8852c_chip_ops = { .disable_bb_rf = rtw8852c_mac_disable_bb_rf, .bb_reset = rtw8852c_bb_reset, .bb_sethw = rtw8852c_bb_sethw, + .set_channel = rtw8852c_set_channel, .read_efuse = rtw8852c_read_efuse, .read_phycap = rtw8852c_read_phycap, .power_trim = rtw8852c_power_trim, diff --git a/drivers/net/wireless/realtek/rtw89/util.h b/drivers/net/wireless/realtek/rtw89/util.h index 229e81009de63..1ae80b7561daa 100644 --- a/drivers/net/wireless/realtek/rtw89/util.h +++ b/drivers/net/wireless/realtek/rtw89/util.h @@ -14,4 +14,34 @@ #define rtw89_for_each_rtwvif(rtwdev, rtwvif) \ list_for_each_entry(rtwvif, &(rtwdev)->rtwvifs_list, list) +/* The result of negative dividend and positive divisor is undefined, but it + * should be one case of round-down or round-up. So, make it round-down if the + * result is round-up. + * Note: the maximum value of divisor is 0x7FFF_FFFF, because we cast it to + * signed value to make compiler to use signed divide instruction. + */ +static inline s32 s32_div_u32_round_down(s32 dividend, u32 divisor, s32 *remainder) +{ + s32 i_divisor = (s32)divisor; + s32 i_remainder; + s32 quotient; + + quotient = dividend / i_divisor; + i_remainder = dividend % i_divisor; + + if (i_remainder < 0) { + quotient--; + i_remainder += i_divisor; + } + + if (remainder) + *remainder = i_remainder; + return quotient; +} + +static inline s32 s32_div_u32_round_closest(s32 dividend, u32 divisor) +{ + return s32_div_u32_round_down(dividend + divisor / 2, divisor, NULL); +} + #endif From 79dafcd4ff6fc5edb86528345e91b417d0bd016e Mon Sep 17 00:00:00 2001 From: Ping-Ke Shih Date: Thu, 14 Apr 2022 14:20:26 +0800 Subject: [PATCH 164/228] rtw89: 8852c: add help function of set channel During setting channel, we need to backup/restore and disable/enable some settings. The settings include SCH (scheduler channel), PPDU status report, and RF components, DFS and ADC. Signed-off-by: Ping-Ke Shih Signed-off-by: Kalle Valo Link: https://lore.kernel.org/r/20220414062027.62638-13-pkshih@realtek.com --- drivers/net/wireless/realtek/rtw89/rtw8852c.c | 40 +++++++++++++++++++ 1 file changed, 40 insertions(+) diff --git a/drivers/net/wireless/realtek/rtw89/rtw8852c.c b/drivers/net/wireless/realtek/rtw89/rtw8852c.c index c5377e8843dd2..510614630bfbb 100644 --- a/drivers/net/wireless/realtek/rtw89/rtw8852c.c +++ b/drivers/net/wireless/realtek/rtw89/rtw8852c.c @@ -1727,6 +1727,45 @@ static void rtw8852c_set_channel(struct rtw89_dev *rtwdev, rtw8852c_set_channel_rf(rtwdev, params, RTW89_PHY_0); } +static void rtw8852c_dfs_en(struct rtw89_dev *rtwdev, bool en) +{ + if (en) + rtw89_phy_write32_mask(rtwdev, R_UPD_P0, B_UPD_P0_EN, 1); + else + rtw89_phy_write32_mask(rtwdev, R_UPD_P0, B_UPD_P0_EN, 0); +} + +static void rtw8852c_adc_en(struct rtw89_dev *rtwdev, bool en) +{ + if (en) + rtw89_phy_write32_mask(rtwdev, R_ADC_FIFO, B_ADC_FIFO_RST, + 0x0); + else + rtw89_phy_write32_mask(rtwdev, R_ADC_FIFO, B_ADC_FIFO_RST, + 0xf); +} + +static void rtw8852c_set_channel_help(struct rtw89_dev *rtwdev, bool enter, + struct rtw89_channel_help_params *p) +{ + u8 phy_idx = RTW89_PHY_0; + + if (enter) { + rtw89_chip_stop_sch_tx(rtwdev, RTW89_MAC_0, &p->tx_en, RTW89_SCH_TX_SEL_ALL); + rtw89_mac_cfg_ppdu_status(rtwdev, RTW89_MAC_0, false); + rtw8852c_dfs_en(rtwdev, false); + rtw8852c_adc_en(rtwdev, false); + fsleep(40); + rtw8852c_bb_reset_en(rtwdev, phy_idx, false); + } else { + rtw89_mac_cfg_ppdu_status(rtwdev, RTW89_MAC_0, true); + rtw8852c_adc_en(rtwdev, true); + rtw8852c_dfs_en(rtwdev, true); + rtw8852c_bb_reset_en(rtwdev, phy_idx, true); + rtw89_chip_resume_sch_tx(rtwdev, RTW89_MAC_0, p->tx_en); + } +} + static void rtw8852c_set_txpwr_ul_tb_offset(struct rtw89_dev *rtwdev, s8 pw_ofst, enum rtw89_mac_idx mac_idx) @@ -1913,6 +1952,7 @@ static const struct rtw89_chip_ops rtw8852c_chip_ops = { .bb_reset = rtw8852c_bb_reset, .bb_sethw = rtw8852c_bb_sethw, .set_channel = rtw8852c_set_channel, + .set_channel_help = rtw8852c_set_channel_help, .read_efuse = rtw8852c_read_efuse, .read_phycap = rtw8852c_read_phycap, .power_trim = rtw8852c_power_trim, From 54d5ecc1710e4b43a73305bce5d91dc954fbb872 Mon Sep 17 00:00:00 2001 From: Minghao Chi Date: Wed, 20 Apr 2022 09:02:14 +0000 Subject: [PATCH 165/228] wl12xx: use pm_runtime_resume_and_get() instead of pm_runtime_get_sync() Using pm_runtime_resume_and_get() to replace pm_runtime_get_sync and pm_runtime_put_noidle. This change is just to simplify the code, no actual functional changes. Reported-by: Zeal Robot Signed-off-by: Minghao Chi Signed-off-by: Kalle Valo Link: https://lore.kernel.org/r/20220420090214.2588618-1-chi.minghao@zte.com.cn --- drivers/net/wireless/ti/wlcore/tx.c | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/drivers/net/wireless/ti/wlcore/tx.c b/drivers/net/wireless/ti/wlcore/tx.c index e20e18cd04aed..7bd3ce2f08044 100644 --- a/drivers/net/wireless/ti/wlcore/tx.c +++ b/drivers/net/wireless/ti/wlcore/tx.c @@ -855,11 +855,9 @@ void wl1271_tx_work(struct work_struct *work) int ret; mutex_lock(&wl->mutex); - ret = pm_runtime_get_sync(wl->dev); - if (ret < 0) { - pm_runtime_put_noidle(wl->dev); + ret = pm_runtime_resume_and_get(wl->dev); + if (ret < 0) goto out; - } ret = wlcore_tx_work_locked(wl); if (ret < 0) { From c94e36908467011d6f793d7667cd0462a8c68710 Mon Sep 17 00:00:00 2001 From: Minghao Chi Date: Wed, 20 Apr 2022 09:02:47 +0000 Subject: [PATCH 166/228] wl12xx: scan: use pm_runtime_resume_and_get() instead of pm_runtime_get_sync() Using pm_runtime_resume_and_get() to replace pm_runtime_get_sync and pm_runtime_put_noidle. This change is just to simplify the code, no actual functional changes. Reported-by: Zeal Robot Signed-off-by: Minghao Chi Signed-off-by: Kalle Valo Link: https://lore.kernel.org/r/20220420090247.2588680-1-chi.minghao@zte.com.cn --- drivers/net/wireless/ti/wlcore/scan.c | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/drivers/net/wireless/ti/wlcore/scan.c b/drivers/net/wireless/ti/wlcore/scan.c index 29fa51c37e88f..b414305acc322 100644 --- a/drivers/net/wireless/ti/wlcore/scan.c +++ b/drivers/net/wireless/ti/wlcore/scan.c @@ -53,11 +53,9 @@ void wl1271_scan_complete_work(struct work_struct *work) wl->scan.req = NULL; wl->scan_wlvif = NULL; - ret = pm_runtime_get_sync(wl->dev); - if (ret < 0) { - pm_runtime_put_noidle(wl->dev); + ret = pm_runtime_resume_and_get(wl->dev); + if (ret < 0) goto out; - } if (test_bit(WLVIF_FLAG_STA_ASSOCIATED, &wlvif->flags)) { /* restore hardware connection monitoring template */ From 9cbdadf0097fc4a77071c61ed28a07eaac97f8f6 Mon Sep 17 00:00:00 2001 From: Po-Hao Huang Date: Wed, 20 Apr 2022 17:30:57 +0800 Subject: [PATCH 167/228] rtw88: fix uninitialized 'tim_offset' warning This avoids below warning and makes compiler happy. error: uninitialized symbol 'tim_offset' Signed-off-by: Po-Hao Huang Signed-off-by: Ping-Ke Shih Signed-off-by: Kalle Valo Link: https://lore.kernel.org/r/20220420093058.31646-1-pkshih@realtek.com --- drivers/net/wireless/realtek/rtw88/fw.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/net/wireless/realtek/rtw88/fw.c b/drivers/net/wireless/realtek/rtw88/fw.c index c1af2704bb866..3545d51c6951a 100644 --- a/drivers/net/wireless/realtek/rtw88/fw.c +++ b/drivers/net/wireless/realtek/rtw88/fw.c @@ -1047,7 +1047,7 @@ static struct sk_buff *rtw_get_rsvd_page_skb(struct ieee80211_hw *hw, struct rtw_vif *rtwvif; struct sk_buff *skb_new; struct cfg80211_ssid *ssid; - u16 tim_offset; + u16 tim_offset = 0; if (rsvd_pkt->type == RSVD_DUMMY) { skb_new = alloc_skb(1, GFP_KERNEL); From 9ebacb1e7e75f2a7a9745d42da7031d3a1741029 Mon Sep 17 00:00:00 2001 From: Po-Hao Huang Date: Wed, 20 Apr 2022 17:30:58 +0800 Subject: [PATCH 168/228] rtw88: pci: 8821c: Disable 21ce completion timeout Disable this capability to avoid timeout errors on certain platforms. Without it, pci bus might stuck and leads to disconnection. Signed-off-by: Po-Hao Huang Signed-off-by: Ping-Ke Shih Tested-by: Chris Chiu Signed-off-by: Kalle Valo Link: https://lore.kernel.org/r/20220420093058.31646-2-pkshih@realtek.com --- drivers/net/wireless/realtek/rtw88/pci.c | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/drivers/net/wireless/realtek/rtw88/pci.c b/drivers/net/wireless/realtek/rtw88/pci.c index 33042b63a151e..3ef0de70af328 100644 --- a/drivers/net/wireless/realtek/rtw88/pci.c +++ b/drivers/net/wireless/realtek/rtw88/pci.c @@ -1482,12 +1482,15 @@ static void rtw_pci_interface_cfg(struct rtw_dev *rtwdev) static void rtw_pci_phy_cfg(struct rtw_dev *rtwdev) { + struct rtw_pci *rtwpci = (struct rtw_pci *)rtwdev->priv; struct rtw_chip_info *chip = rtwdev->chip; + struct pci_dev *pdev = rtwpci->pdev; const struct rtw_intf_phy_para *para; u16 cut; u16 value; u16 offset; int i; + int ret; cut = BIT(0) << rtwdev->hal.cut_version; @@ -1520,6 +1523,15 @@ static void rtw_pci_phy_cfg(struct rtw_dev *rtwdev) } rtw_pci_link_cfg(rtwdev); + + /* Disable 8821ce completion timeout by default */ + if (chip->id == RTW_CHIP_TYPE_8821C) { + ret = pcie_capability_set_word(pdev, PCI_EXP_DEVCTL2, + PCI_EXP_DEVCTL2_COMP_TMOUT_DIS); + if (ret) + rtw_err(rtwdev, "failed to set PCI cap, ret = %d\n", + ret); + } } static int __maybe_unused rtw_pci_suspend(struct device *dev) From 948e521c728536db40dc7fba5a641f2115161802 Mon Sep 17 00:00:00 2001 From: Ping-Ke Shih Date: Thu, 21 Apr 2022 20:08:50 +0800 Subject: [PATCH 169/228] rtw89: pci: add variant IMR/ISR and configure functions 8852CE uses different but similar IMR/ISR registers, and its masks are also different in various states, so add config_intr_mask ops to configure masks according to under_recovery or low_power states. Signed-off-by: Ping-Ke Shih Signed-off-by: Kalle Valo Link: https://lore.kernel.org/r/20220421120903.73715-2-pkshih@realtek.com --- drivers/net/wireless/realtek/rtw89/pci.c | 168 +++++++++++++++--- drivers/net/wireless/realtek/rtw89/pci.h | 123 +++++++++++++ .../net/wireless/realtek/rtw89/rtw8852ae.c | 4 + .../net/wireless/realtek/rtw89/rtw8852ce.c | 4 + 4 files changed, 270 insertions(+), 29 deletions(-) diff --git a/drivers/net/wireless/realtek/rtw89/pci.c b/drivers/net/wireless/realtek/rtw89/pci.c index ecb419010f0c2..0d9cd8033c778 100644 --- a/drivers/net/wireless/realtek/rtw89/pci.c +++ b/drivers/net/wireless/realtek/rtw89/pci.c @@ -612,9 +612,9 @@ static void rtw89_pci_isr_rxd_unavail(struct rtw89_dev *rtwdev, } } -static void rtw89_pci_recognize_intrs(struct rtw89_dev *rtwdev, - struct rtw89_pci *rtwpci, - struct rtw89_pci_isrs *isrs) +void rtw89_pci_recognize_intrs(struct rtw89_dev *rtwdev, + struct rtw89_pci *rtwpci, + struct rtw89_pci_isrs *isrs) { isrs->halt_c2h_isrs = rtw89_read32(rtwdev, R_AX_HISR0) & rtwpci->halt_c2h_intrs; isrs->isrs[0] = rtw89_read32(rtwdev, R_AX_PCIE_HISR00) & rtwpci->intrs[0]; @@ -624,6 +624,28 @@ static void rtw89_pci_recognize_intrs(struct rtw89_dev *rtwdev, rtw89_write32(rtwdev, R_AX_PCIE_HISR00, isrs->isrs[0]); rtw89_write32(rtwdev, R_AX_PCIE_HISR10, isrs->isrs[1]); } +EXPORT_SYMBOL(rtw89_pci_recognize_intrs); + +void rtw89_pci_recognize_intrs_v1(struct rtw89_dev *rtwdev, + struct rtw89_pci *rtwpci, + struct rtw89_pci_isrs *isrs) +{ + isrs->ind_isrs = rtw89_read32(rtwdev, R_AX_PCIE_HISR00_V1) & rtwpci->ind_intrs; + isrs->halt_c2h_isrs = isrs->ind_isrs & B_AX_HS0ISR_IND_INT_EN ? + rtw89_read32(rtwdev, R_AX_HISR0) & rtwpci->halt_c2h_intrs : 0; + isrs->isrs[0] = isrs->ind_isrs & B_AX_HCI_AXIDMA_INT_EN ? + rtw89_read32(rtwdev, R_AX_HAXI_HISR00) & rtwpci->intrs[0] : 0; + isrs->isrs[1] = isrs->ind_isrs & B_AX_HS1ISR_IND_INT_EN ? + rtw89_read32(rtwdev, R_AX_HISR1) & rtwpci->intrs[1] : 0; + + if (isrs->halt_c2h_isrs) + rtw89_write32(rtwdev, R_AX_HISR0, isrs->halt_c2h_isrs); + if (isrs->isrs[0]) + rtw89_write32(rtwdev, R_AX_HAXI_HISR00, isrs->isrs[0]); + if (isrs->isrs[1]) + rtw89_write32(rtwdev, R_AX_HISR1, isrs->isrs[1]); +} +EXPORT_SYMBOL(rtw89_pci_recognize_intrs_v1); static void rtw89_pci_clear_isr0(struct rtw89_dev *rtwdev, u32 isr00) { @@ -631,21 +653,39 @@ static void rtw89_pci_clear_isr0(struct rtw89_dev *rtwdev, u32 isr00) rtw89_write32(rtwdev, R_AX_PCIE_HISR00, isr00); } -static void rtw89_pci_enable_intr(struct rtw89_dev *rtwdev, - struct rtw89_pci *rtwpci) +void rtw89_pci_enable_intr(struct rtw89_dev *rtwdev, struct rtw89_pci *rtwpci) { rtw89_write32(rtwdev, R_AX_HIMR0, rtwpci->halt_c2h_intrs); rtw89_write32(rtwdev, R_AX_PCIE_HIMR00, rtwpci->intrs[0]); rtw89_write32(rtwdev, R_AX_PCIE_HIMR10, rtwpci->intrs[1]); } +EXPORT_SYMBOL(rtw89_pci_enable_intr); -static void rtw89_pci_disable_intr(struct rtw89_dev *rtwdev, - struct rtw89_pci *rtwpci) +void rtw89_pci_disable_intr(struct rtw89_dev *rtwdev, struct rtw89_pci *rtwpci) { rtw89_write32(rtwdev, R_AX_HIMR0, 0); rtw89_write32(rtwdev, R_AX_PCIE_HIMR00, 0); rtw89_write32(rtwdev, R_AX_PCIE_HIMR10, 0); } +EXPORT_SYMBOL(rtw89_pci_disable_intr); + +void rtw89_pci_enable_intr_v1(struct rtw89_dev *rtwdev, struct rtw89_pci *rtwpci) +{ + rtw89_write32(rtwdev, R_AX_PCIE_HIMR00_V1, rtwpci->ind_intrs); + rtw89_write32(rtwdev, R_AX_HIMR0, rtwpci->halt_c2h_intrs); + rtw89_write32(rtwdev, R_AX_HAXI_HIMR00, rtwpci->intrs[0]); + rtw89_write32(rtwdev, R_AX_HIMR1, rtwpci->intrs[1]); +} +EXPORT_SYMBOL(rtw89_pci_enable_intr_v1); + +void rtw89_pci_disable_intr_v1(struct rtw89_dev *rtwdev, struct rtw89_pci *rtwpci) +{ + rtw89_write32(rtwdev, R_AX_PCIE_HIMR00_V1, 0); + rtw89_write32(rtwdev, R_AX_HIMR0, 0); + rtw89_write32(rtwdev, R_AX_HAXI_HIMR00, 0); + rtw89_write32(rtwdev, R_AX_HIMR1, 0); +} +EXPORT_SYMBOL(rtw89_pci_disable_intr_v1); static void rtw89_pci_ops_recovery_start(struct rtw89_dev *rtwdev) { @@ -653,9 +693,9 @@ static void rtw89_pci_ops_recovery_start(struct rtw89_dev *rtwdev) unsigned long flags; spin_lock_irqsave(&rtwpci->irq_lock, flags); - rtwpci->under_recovery = true; - rtw89_write32(rtwdev, R_AX_PCIE_HIMR00, 0); - rtw89_write32(rtwdev, R_AX_PCIE_HIMR10, 0); + rtw89_chip_disable_intr(rtwdev, rtwpci); + rtw89_chip_config_intr_mask(rtwdev, RTW89_PCI_INTR_MASK_RECOVERY_START); + rtw89_chip_enable_intr(rtwdev, rtwpci); spin_unlock_irqrestore(&rtwpci->irq_lock, flags); } @@ -665,8 +705,9 @@ static void rtw89_pci_ops_recovery_complete(struct rtw89_dev *rtwdev) unsigned long flags; spin_lock_irqsave(&rtwpci->irq_lock, flags); - rtwpci->under_recovery = false; - rtw89_pci_enable_intr(rtwdev, rtwpci); + rtw89_chip_disable_intr(rtwdev, rtwpci); + rtw89_chip_config_intr_mask(rtwdev, RTW89_PCI_INTR_MASK_RECOVERY_COMPLETE); + rtw89_chip_enable_intr(rtwdev, rtwpci); spin_unlock_irqrestore(&rtwpci->irq_lock, flags); } @@ -678,7 +719,7 @@ static irqreturn_t rtw89_pci_interrupt_threadfn(int irq, void *dev) unsigned long flags; spin_lock_irqsave(&rtwpci->irq_lock, flags); - rtw89_pci_recognize_intrs(rtwdev, rtwpci, &isrs); + rtw89_chip_recognize_intrs(rtwdev, rtwpci, &isrs); spin_unlock_irqrestore(&rtwpci->irq_lock, flags); if (unlikely(isrs.isrs[0] & B_AX_RDU_INT)) @@ -716,7 +757,7 @@ static irqreturn_t rtw89_pci_interrupt_handler(int irq, void *dev) goto exit; } - rtw89_pci_disable_intr(rtwdev, rtwpci); + rtw89_chip_disable_intr(rtwdev, rtwpci); exit: spin_unlock_irqrestore(&rtwpci->irq_lock, flags); @@ -1313,32 +1354,42 @@ static void rtw89_pci_ops_reset(struct rtw89_dev *rtwdev) spin_unlock_bh(&rtwpci->trx_lock); } -static int rtw89_pci_ops_start(struct rtw89_dev *rtwdev) +static void rtw89_pci_enable_intr_lock(struct rtw89_dev *rtwdev) { struct rtw89_pci *rtwpci = (struct rtw89_pci *)rtwdev->priv; unsigned long flags; - rtw89_core_napi_start(rtwdev); - spin_lock_irqsave(&rtwpci->irq_lock, flags); rtwpci->running = true; - rtw89_pci_enable_intr(rtwdev, rtwpci); + rtw89_chip_enable_intr(rtwdev, rtwpci); spin_unlock_irqrestore(&rtwpci->irq_lock, flags); - - return 0; } -static void rtw89_pci_ops_stop(struct rtw89_dev *rtwdev) +static void rtw89_pci_disable_intr_lock(struct rtw89_dev *rtwdev) { struct rtw89_pci *rtwpci = (struct rtw89_pci *)rtwdev->priv; - struct pci_dev *pdev = rtwpci->pdev; unsigned long flags; spin_lock_irqsave(&rtwpci->irq_lock, flags); rtwpci->running = false; - rtw89_pci_disable_intr(rtwdev, rtwpci); + rtw89_chip_disable_intr(rtwdev, rtwpci); spin_unlock_irqrestore(&rtwpci->irq_lock, flags); +} + +static int rtw89_pci_ops_start(struct rtw89_dev *rtwdev) +{ + rtw89_core_napi_start(rtwdev); + rtw89_pci_enable_intr_lock(rtwdev); + + return 0; +} +static void rtw89_pci_ops_stop(struct rtw89_dev *rtwdev) +{ + struct rtw89_pci *rtwpci = (struct rtw89_pci *)rtwdev->priv; + struct pci_dev *pdev = rtwpci->pdev; + + rtw89_pci_disable_intr_lock(rtwdev); synchronize_irq(pdev->irq); rtw89_core_napi_stop(rtwdev); } @@ -2924,22 +2975,81 @@ static void rtw89_pci_clear_resource(struct rtw89_dev *rtwdev, skb_queue_len(&rtwpci->h2c_queue), true); } -static void rtw89_pci_default_intr_mask(struct rtw89_dev *rtwdev) +void rtw89_pci_config_intr_mask(struct rtw89_dev *rtwdev) { struct rtw89_pci *rtwpci = (struct rtw89_pci *)rtwdev->priv; rtwpci->halt_c2h_intrs = B_AX_HALT_C2H_INT_EN | 0; + + if (rtwpci->under_recovery) { + rtwpci->intrs[0] = 0; + rtwpci->intrs[1] = 0; + } else { + rtwpci->intrs[0] = B_AX_TXDMA_STUCK_INT_EN | + B_AX_RXDMA_INT_EN | + B_AX_RXP1DMA_INT_EN | + B_AX_RPQDMA_INT_EN | + B_AX_RXDMA_STUCK_INT_EN | + B_AX_RDU_INT_EN | + B_AX_RPQBD_FULL_INT_EN | + B_AX_HS0ISR_IND_INT_EN; + + rtwpci->intrs[1] = B_AX_HC10ISR_IND_INT_EN; + } +} +EXPORT_SYMBOL(rtw89_pci_config_intr_mask); + +static void rtw89_pci_recovery_intr_mask_v1(struct rtw89_dev *rtwdev) +{ + struct rtw89_pci *rtwpci = (struct rtw89_pci *)rtwdev->priv; + + rtwpci->ind_intrs = B_AX_HS0ISR_IND_INT_EN; + rtwpci->halt_c2h_intrs = B_AX_HALT_C2H_INT_EN; + rtwpci->intrs[0] = 0; + rtwpci->intrs[1] = 0; +} + +static void rtw89_pci_default_intr_mask_v1(struct rtw89_dev *rtwdev) +{ + struct rtw89_pci *rtwpci = (struct rtw89_pci *)rtwdev->priv; + + rtwpci->ind_intrs = B_AX_HCI_AXIDMA_INT_EN | + B_AX_HS1ISR_IND_INT_EN | + B_AX_HS0ISR_IND_INT_EN; + rtwpci->halt_c2h_intrs = B_AX_HALT_C2H_INT_EN; rtwpci->intrs[0] = B_AX_TXDMA_STUCK_INT_EN | B_AX_RXDMA_INT_EN | B_AX_RXP1DMA_INT_EN | B_AX_RPQDMA_INT_EN | B_AX_RXDMA_STUCK_INT_EN | B_AX_RDU_INT_EN | - B_AX_RPQBD_FULL_INT_EN | - B_AX_HS0ISR_IND_INT_EN; + B_AX_RPQBD_FULL_INT_EN; + rtwpci->intrs[1] = B_AX_GPIO18_INT_EN; +} + +static void rtw89_pci_low_power_intr_mask_v1(struct rtw89_dev *rtwdev) +{ + struct rtw89_pci *rtwpci = (struct rtw89_pci *)rtwdev->priv; + + rtwpci->ind_intrs = B_AX_HS1ISR_IND_INT_EN | + B_AX_HS0ISR_IND_INT_EN; + rtwpci->halt_c2h_intrs = B_AX_HALT_C2H_INT_EN; + rtwpci->intrs[0] = 0; + rtwpci->intrs[1] = B_AX_GPIO18_INT_EN; +} - rtwpci->intrs[1] = B_AX_HC10ISR_IND_INT_EN; +void rtw89_pci_config_intr_mask_v1(struct rtw89_dev *rtwdev) +{ + struct rtw89_pci *rtwpci = (struct rtw89_pci *)rtwdev->priv; + + if (rtwpci->under_recovery) + rtw89_pci_recovery_intr_mask_v1(rtwdev); + else if (rtwpci->low_power) + rtw89_pci_low_power_intr_mask_v1(rtwdev); + else + rtw89_pci_default_intr_mask_v1(rtwdev); } +EXPORT_SYMBOL(rtw89_pci_config_intr_mask_v1); static int rtw89_pci_request_irq(struct rtw89_dev *rtwdev, struct pci_dev *pdev) @@ -2963,7 +3073,7 @@ static int rtw89_pci_request_irq(struct rtw89_dev *rtwdev, goto err_free_vector; } - rtw89_pci_default_intr_mask(rtwdev); + rtw89_chip_config_intr_mask(rtwdev, RTW89_PCI_INTR_MASK_RESET); return 0; @@ -3285,7 +3395,7 @@ static int rtw89_pci_napi_poll(struct napi_struct *napi, int budget) if (work_done < budget && napi_complete_done(napi, work_done)) { spin_lock_irqsave(&rtwpci->irq_lock, flags); if (likely(rtwpci->running)) - rtw89_pci_enable_intr(rtwdev, rtwpci); + rtw89_chip_enable_intr(rtwdev, rtwpci); spin_unlock_irqrestore(&rtwpci->irq_lock, flags); } diff --git a/drivers/net/wireless/realtek/rtw89/pci.h b/drivers/net/wireless/realtek/rtw89/pci.h index a085d1f27a120..aa804b577df27 100644 --- a/drivers/net/wireless/realtek/rtw89/pci.h +++ b/drivers/net/wireless/realtek/rtw89/pci.h @@ -97,6 +97,16 @@ #define B_AX_HALT_C2H_INT_EN BIT(21) #define R_AX_HISR0 0x01A4 +#define R_AX_HIMR1 0x01A8 +#define B_AX_GPIO18_INT_EN BIT(2) +#define B_AX_GPIO17_INT_EN BIT(1) +#define B_AX_GPIO16_INT_EN BIT(0) + +#define R_AX_HISR1 0x01AC +#define B_AX_GPIO18_INT BIT(2) +#define B_AX_GPIO17_INT BIT(1) +#define B_AX_GPIO16_INT BIT(0) + #define R_AX_MDIO_CFG 0x10A0 #define B_AX_MDIO_PHY_ADDR_MASK GENMASK(13, 12) #define B_AX_MDIO_RFLAG BIT(9) @@ -104,6 +114,7 @@ #define B_AX_MDIO_ADDR_MASK GENMASK(4, 0) #define R_AX_PCIE_HIMR00 0x10B0 +#define R_AX_HAXI_HIMR00 0x10B0 #define B_AX_HC00ISR_IND_INT_EN BIT(27) #define B_AX_HD1ISR_IND_INT_EN BIT(26) #define B_AX_HD0ISR_IND_INT_EN BIT(25) @@ -132,6 +143,7 @@ #define B_AX_RXDMA_INT_EN BIT(0) #define R_AX_PCIE_HISR00 0x10B4 +#define R_AX_HAXI_HISR00 0x10B4 #define B_AX_HC00ISR_IND_INT BIT(27) #define B_AX_HD1ISR_IND_INT BIT(26) #define B_AX_HD0ISR_IND_INT BIT(25) @@ -159,6 +171,10 @@ #define B_AX_RXP1DMA_INT BIT(1) #define B_AX_RXDMA_INT BIT(0) +#define R_AX_HAXI_HIMR10 0x11E0 +#define B_AX_TXDMA_CH11_INT_EN_V1 BIT(1) +#define B_AX_TXDMA_CH10_INT_EN_V1 BIT(0) + #define R_AX_PCIE_HIMR10 0x13B0 #define B_AX_HC10ISR_IND_INT_EN BIT(28) #define B_AX_TXDMA_CH11_INT_EN BIT(12) @@ -169,6 +185,22 @@ #define B_AX_TXDMA_CH11_INT BIT(12) #define B_AX_TXDMA_CH10_INT BIT(11) +#define R_AX_PCIE_HIMR00_V1 0x30B0 +#define B_AX_HCI_AXIDMA_INT_EN BIT(29) +#define B_AX_HC00ISR_IND_INT_EN_V1 BIT(28) +#define B_AX_HD1ISR_IND_INT_EN_V1 BIT(27) +#define B_AX_HD0ISR_IND_INT_EN_V1 BIT(26) +#define B_AX_HS1ISR_IND_INT_EN BIT(25) +#define B_AX_PCIE_DBG_STE_INT_EN BIT(13) + +#define R_AX_PCIE_HISR00_V1 0x30B4 +#define B_AX_HCI_AXIDMA_INT BIT(29) +#define B_AX_HC00ISR_IND_INT_V1 BIT(28) +#define B_AX_HD1ISR_IND_INT_V1 BIT(27) +#define B_AX_HD0ISR_IND_INT_V1 BIT(26) +#define B_AX_HS1ISR_IND_INT BIT(25) +#define B_AX_PCIE_DBG_STE_INT BIT(13) + /* TX/RX */ #define R_AX_RXQ_RXBD_IDX 0x1050 #define R_AX_RPQ_RXBD_IDX 0x1054 @@ -612,6 +644,17 @@ enum mac_ax_io_rcy_tmr { MAC_AX_IO_RCY_ANA_TMR_DEF = 0xFE }; +enum rtw89_pci_intr_mask_cfg { + RTW89_PCI_INTR_MASK_RESET, + RTW89_PCI_INTR_MASK_NORMAL, + RTW89_PCI_INTR_MASK_LOW_POWER, + RTW89_PCI_INTR_MASK_RECOVERY_START, + RTW89_PCI_INTR_MASK_RECOVERY_COMPLETE, +}; + +struct rtw89_pci_isrs; +struct rtw89_pci; + struct rtw89_pci_ch_dma_addr { u32 num; u32 idx; @@ -661,6 +704,12 @@ struct rtw89_pci_info { u32 (*fill_txaddr_info)(struct rtw89_dev *rtwdev, void *txaddr_info_addr, u32 total_len, dma_addr_t dma, u8 *add_info_nr); + void (*config_intr_mask)(struct rtw89_dev *rtwdev); + void (*enable_intr)(struct rtw89_dev *rtwdev, struct rtw89_pci *rtwpci); + void (*disable_intr)(struct rtw89_dev *rtwdev, struct rtw89_pci *rtwpci); + void (*recognize_intrs)(struct rtw89_dev *rtwdev, + struct rtw89_pci *rtwpci, + struct rtw89_pci_isrs *isrs); }; struct rtw89_pci_bd_ram { @@ -807,6 +856,7 @@ struct rtw89_pci_rx_ring { }; struct rtw89_pci_isrs { + u32 ind_isrs; u32 halt_c2h_isrs; u32 isrs[2]; }; @@ -819,12 +869,14 @@ struct rtw89_pci { /* protect TRX resources (exclude RXQ) */ spinlock_t trx_lock; bool running; + bool low_power; bool under_recovery; struct rtw89_pci_tx_ring tx_rings[RTW89_TXCH_NUM]; struct rtw89_pci_rx_ring rx_rings[RTW89_RXCH_NUM]; struct sk_buff_head h2c_queue; struct sk_buff_head h2c_release_queue; + u32 ind_intrs; u32 halt_c2h_intrs; u32 intrs[2]; void __iomem *mmap; @@ -931,6 +983,18 @@ u32 rtw89_pci_fill_txaddr_info(struct rtw89_dev *rtwdev, u32 rtw89_pci_fill_txaddr_info_v1(struct rtw89_dev *rtwdev, void *txaddr_info_addr, u32 total_len, dma_addr_t dma, u8 *add_info_nr); +void rtw89_pci_config_intr_mask(struct rtw89_dev *rtwdev); +void rtw89_pci_config_intr_mask_v1(struct rtw89_dev *rtwdev); +void rtw89_pci_enable_intr(struct rtw89_dev *rtwdev, struct rtw89_pci *rtwpci); +void rtw89_pci_disable_intr(struct rtw89_dev *rtwdev, struct rtw89_pci *rtwpci); +void rtw89_pci_enable_intr_v1(struct rtw89_dev *rtwdev, struct rtw89_pci *rtwpci); +void rtw89_pci_disable_intr_v1(struct rtw89_dev *rtwdev, struct rtw89_pci *rtwpci); +void rtw89_pci_recognize_intrs(struct rtw89_dev *rtwdev, + struct rtw89_pci *rtwpci, + struct rtw89_pci_isrs *isrs); +void rtw89_pci_recognize_intrs_v1(struct rtw89_dev *rtwdev, + struct rtw89_pci *rtwpci, + struct rtw89_pci_isrs *isrs); static inline u32 rtw89_chip_fill_txaddr_info(struct rtw89_dev *rtwdev, @@ -943,4 +1007,63 @@ u32 rtw89_chip_fill_txaddr_info(struct rtw89_dev *rtwdev, dma, add_info_nr); } +static inline void rtw89_chip_config_intr_mask(struct rtw89_dev *rtwdev, + enum rtw89_pci_intr_mask_cfg cfg) +{ + struct rtw89_pci *rtwpci = (struct rtw89_pci *)rtwdev->priv; + const struct rtw89_pci_info *info = rtwdev->pci_info; + + switch (cfg) { + default: + case RTW89_PCI_INTR_MASK_RESET: + rtwpci->low_power = false; + rtwpci->under_recovery = false; + break; + case RTW89_PCI_INTR_MASK_NORMAL: + rtwpci->low_power = false; + break; + case RTW89_PCI_INTR_MASK_LOW_POWER: + rtwpci->low_power = true; + break; + case RTW89_PCI_INTR_MASK_RECOVERY_START: + rtwpci->under_recovery = true; + break; + case RTW89_PCI_INTR_MASK_RECOVERY_COMPLETE: + rtwpci->under_recovery = false; + break; + } + + rtw89_debug(rtwdev, RTW89_DBG_HCI, + "Configure PCI interrupt mask mode low_power=%d under_recovery=%d\n", + rtwpci->low_power, rtwpci->under_recovery); + + info->config_intr_mask(rtwdev); +} + +static inline +void rtw89_chip_enable_intr(struct rtw89_dev *rtwdev, struct rtw89_pci *rtwpci) +{ + const struct rtw89_pci_info *info = rtwdev->pci_info; + + info->enable_intr(rtwdev, rtwpci); +} + +static inline +void rtw89_chip_disable_intr(struct rtw89_dev *rtwdev, struct rtw89_pci *rtwpci) +{ + const struct rtw89_pci_info *info = rtwdev->pci_info; + + info->disable_intr(rtwdev, rtwpci); +} + +static inline +void rtw89_chip_recognize_intrs(struct rtw89_dev *rtwdev, + struct rtw89_pci *rtwpci, + struct rtw89_pci_isrs *isrs) +{ + const struct rtw89_pci_info *info = rtwdev->pci_info; + + info->recognize_intrs(rtwdev, rtwpci, isrs); +} + #endif diff --git a/drivers/net/wireless/realtek/rtw89/rtw8852ae.c b/drivers/net/wireless/realtek/rtw89/rtw8852ae.c index 61a1693535d8a..73b5dd05235aa 100644 --- a/drivers/net/wireless/realtek/rtw89/rtw8852ae.c +++ b/drivers/net/wireless/realtek/rtw89/rtw8852ae.c @@ -42,6 +42,10 @@ static const struct rtw89_pci_info rtw8852a_pci_info = { .ltr_set = rtw89_pci_ltr_set, .fill_txaddr_info = rtw89_pci_fill_txaddr_info, + .config_intr_mask = rtw89_pci_config_intr_mask, + .enable_intr = rtw89_pci_enable_intr, + .disable_intr = rtw89_pci_disable_intr, + .recognize_intrs = rtw89_pci_recognize_intrs, }; static const struct rtw89_driver_info rtw89_8852ae_info = { diff --git a/drivers/net/wireless/realtek/rtw89/rtw8852ce.c b/drivers/net/wireless/realtek/rtw89/rtw8852ce.c index aeafac553f404..4021a56a82bc5 100644 --- a/drivers/net/wireless/realtek/rtw89/rtw8852ce.c +++ b/drivers/net/wireless/realtek/rtw89/rtw8852ce.c @@ -43,6 +43,10 @@ static const struct rtw89_pci_info rtw8852c_pci_info = { .ltr_set = rtw89_pci_ltr_set_v1, .fill_txaddr_info = rtw89_pci_fill_txaddr_info_v1, + .config_intr_mask = rtw89_pci_config_intr_mask_v1, + .enable_intr = rtw89_pci_enable_intr_v1, + .disable_intr = rtw89_pci_disable_intr_v1, + .recognize_intrs = rtw89_pci_recognize_intrs_v1, }; static const struct rtw89_driver_info rtw89_8852ce_info = { From e1757e80450164ede118993a889979e65ead591b Mon Sep 17 00:00:00 2001 From: Ping-Ke Shih Date: Thu, 21 Apr 2022 20:08:51 +0800 Subject: [PATCH 170/228] rtw89: pci: add variant RPWM/CPWM to enter low power mode RPWM/CPWM are registers that can set and check low power mode. Since chips use different address, add a field to access them in common flow. Signed-off-by: Ping-Ke Shih Signed-off-by: Kalle Valo Link: https://lore.kernel.org/r/20220421120903.73715-3-pkshih@realtek.com --- drivers/net/wireless/realtek/rtw89/mac.c | 6 +++--- drivers/net/wireless/realtek/rtw89/pci.c | 14 ++++++++------ drivers/net/wireless/realtek/rtw89/pci.h | 5 +++++ drivers/net/wireless/realtek/rtw89/rtw8852ae.c | 3 +++ drivers/net/wireless/realtek/rtw89/rtw8852ce.c | 2 ++ 5 files changed, 21 insertions(+), 9 deletions(-) diff --git a/drivers/net/wireless/realtek/rtw89/mac.c b/drivers/net/wireless/realtek/rtw89/mac.c index 127d5d74c426b..05b94842fe662 100644 --- a/drivers/net/wireless/realtek/rtw89/mac.c +++ b/drivers/net/wireless/realtek/rtw89/mac.c @@ -1027,7 +1027,7 @@ static int rtw89_mac_check_cpwm_state(struct rtw89_dev *rtwdev, return 0; rpwm_req_num = rtwdev->mac.rpwm_seq_num; - cpwm_rsp_seq = rtw89_read16_mask(rtwdev, R_AX_CPWM, + cpwm_rsp_seq = rtw89_read16_mask(rtwdev, rtwdev->hci.cpwm_addr, PS_CPWM_RSP_SEQ_NUM); if (rpwm_req_num != cpwm_rsp_seq) @@ -1036,11 +1036,11 @@ static int rtw89_mac_check_cpwm_state(struct rtw89_dev *rtwdev, rtwdev->mac.cpwm_seq_num = (rtwdev->mac.cpwm_seq_num + 1) & CPWM_SEQ_NUM_MAX; - cpwm_seq = rtw89_read16_mask(rtwdev, R_AX_CPWM, PS_CPWM_SEQ_NUM); + cpwm_seq = rtw89_read16_mask(rtwdev, rtwdev->hci.cpwm_addr, PS_CPWM_SEQ_NUM); if (cpwm_seq != rtwdev->mac.cpwm_seq_num) return -EPERM; - cpwm_status = rtw89_read16_mask(rtwdev, R_AX_CPWM, PS_CPWM_STATE); + cpwm_status = rtw89_read16_mask(rtwdev, rtwdev->hci.cpwm_addr, PS_CPWM_STATE); if (cpwm_status != req_pwr_state) return -EPERM; diff --git a/drivers/net/wireless/realtek/rtw89/pci.c b/drivers/net/wireless/realtek/rtw89/pci.c index 0d9cd8033c778..338a032490e16 100644 --- a/drivers/net/wireless/realtek/rtw89/pci.c +++ b/drivers/net/wireless/realtek/rtw89/pci.c @@ -3486,6 +3486,7 @@ int rtw89_pci_probe(struct pci_dev *pdev, const struct pci_device_id *id) struct ieee80211_hw *hw; struct rtw89_dev *rtwdev; const struct rtw89_driver_info *info; + const struct rtw89_pci_info *pci_info; int driver_data_size; int ret; @@ -3496,20 +3497,21 @@ int rtw89_pci_probe(struct pci_dev *pdev, const struct pci_device_id *id) return -ENOMEM; } + info = (const struct rtw89_driver_info *)id->driver_data; + pci_info = info->bus.pci; + rtwdev = hw->priv; rtwdev->hw = hw; rtwdev->dev = &pdev->dev; + rtwdev->chip = info->chip; + rtwdev->pci_info = info->bus.pci; rtwdev->hci.ops = &rtw89_pci_ops; rtwdev->hci.type = RTW89_HCI_TYPE_PCIE; - rtwdev->hci.rpwm_addr = R_AX_PCIE_HRPWM; - rtwdev->hci.cpwm_addr = R_AX_CPWM; + rtwdev->hci.rpwm_addr = pci_info->rpwm_addr; + rtwdev->hci.cpwm_addr = pci_info->cpwm_addr; SET_IEEE80211_DEV(rtwdev->hw, &pdev->dev); - info = (const struct rtw89_driver_info *)id->driver_data; - rtwdev->chip = info->chip; - rtwdev->pci_info = info->bus.pci; - ret = rtw89_core_init(rtwdev); if (ret) { rtw89_err(rtwdev, "failed to initialise core\n"); diff --git a/drivers/net/wireless/realtek/rtw89/pci.h b/drivers/net/wireless/realtek/rtw89/pci.h index aa804b577df27..c203c8cbf1632 100644 --- a/drivers/net/wireless/realtek/rtw89/pci.h +++ b/drivers/net/wireless/realtek/rtw89/pci.h @@ -481,6 +481,9 @@ #define R_AX_PCIE_RX_PREF_ADV 0x13F4 #define B_AX_RXDMA_PREF_ADV_EN BIT(0) +#define R_AX_PCIE_HRPWM_V1 0x30C0 +#define R_AX_PCIE_CRPWM 0x30C4 + #define RTW89_PCI_TXBD_NUM_MAX 256 #define RTW89_PCI_RXBD_NUM_MAX 256 #define RTW89_PCI_TXWD_NUM_MAX 512 @@ -698,6 +701,8 @@ struct rtw89_pci_info { u32 dma_busy2_reg; u32 dma_busy3_reg; + u32 rpwm_addr; + u32 cpwm_addr; const struct rtw89_pci_ch_dma_addr_set *dma_addr_set; int (*ltr_set)(struct rtw89_dev *rtwdev, bool en); diff --git a/drivers/net/wireless/realtek/rtw89/rtw8852ae.c b/drivers/net/wireless/realtek/rtw89/rtw8852ae.c index 73b5dd05235aa..c6937e5943ea7 100644 --- a/drivers/net/wireless/realtek/rtw89/rtw8852ae.c +++ b/drivers/net/wireless/realtek/rtw89/rtw8852ae.c @@ -6,6 +6,7 @@ #include #include "pci.h" +#include "reg.h" #include "rtw8852a.h" static const struct rtw89_pci_info rtw8852a_pci_info = { @@ -38,6 +39,8 @@ static const struct rtw89_pci_info rtw8852a_pci_info = { .dma_busy2_reg = R_AX_PCIE_DMA_BUSY2, .dma_busy3_reg = R_AX_PCIE_DMA_BUSY1, + .rpwm_addr = R_AX_PCIE_HRPWM, + .cpwm_addr = R_AX_CPWM, .dma_addr_set = &rtw89_pci_ch_dma_addr_set, .ltr_set = rtw89_pci_ltr_set, diff --git a/drivers/net/wireless/realtek/rtw89/rtw8852ce.c b/drivers/net/wireless/realtek/rtw89/rtw8852ce.c index 4021a56a82bc5..4d71cc87f7ba8 100644 --- a/drivers/net/wireless/realtek/rtw89/rtw8852ce.c +++ b/drivers/net/wireless/realtek/rtw89/rtw8852ce.c @@ -39,6 +39,8 @@ static const struct rtw89_pci_info rtw8852c_pci_info = { .dma_busy2_reg = R_AX_HAXI_DMA_BUSY2, .dma_busy3_reg = R_AX_HAXI_DMA_BUSY3, + .rpwm_addr = R_AX_PCIE_HRPWM_V1, + .cpwm_addr = R_AX_PCIE_CRPWM, .dma_addr_set = &rtw89_pci_ch_dma_addr_set_v1, .ltr_set = rtw89_pci_ltr_set_v1, From 837202684657c2829bcdc057c1d25db751a6587b Mon Sep 17 00:00:00 2001 From: Ping-Ke Shih Date: Thu, 21 Apr 2022 20:08:52 +0800 Subject: [PATCH 171/228] rtw89: pci: reclaim TX BD only if it really need To reclaim TX BD, we need to read hardware reading index to determine if any DMA is complete. Since this IO spends time, do this thing only if we really need it when TX BD has no free buffer corresponding to target skb. The experimental result shows that reading counter decreases from 26,000 to 130 per second. Signed-off-by: Ping-Ke Shih Signed-off-by: Kalle Valo Link: https://lore.kernel.org/r/20220421120903.73715-4-pkshih@realtek.com --- drivers/net/wireless/realtek/rtw89/pci.c | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) diff --git a/drivers/net/wireless/realtek/rtw89/pci.c b/drivers/net/wireless/realtek/rtw89/pci.c index 338a032490e16..c1bb44bcd48e1 100644 --- a/drivers/net/wireless/realtek/rtw89/pci.c +++ b/drivers/net/wireless/realtek/rtw89/pci.c @@ -412,9 +412,12 @@ static void rtw89_pci_release_txwd_skb(struct rtw89_dev *rtwdev, u8 txch = tx_ring->txch; if (!list_empty(&txwd->list)) { - rtw89_warn(rtwdev, "queue %d txwd %d is not idle\n", - txch, seq); - return; + rtw89_pci_reclaim_txbd(rtwdev, tx_ring); + if (!list_empty(&txwd->list)) { + rtw89_warn(rtwdev, "queue %d txwd %d is not idle\n", + txch, seq); + return; + } } /* currently, support for only one frame */ @@ -458,7 +461,6 @@ static void rtw89_pci_release_rpp(struct rtw89_dev *rtwdev, } tx_ring = &rtwpci->tx_rings[txch]; - rtw89_pci_reclaim_txbd(rtwdev, tx_ring); wd_ring = &tx_ring->wd_ring; txwd = &wd_ring->pages[seq]; @@ -915,6 +917,10 @@ static u32 __rtw89_pci_check_and_reclaim_tx_resource(struct rtw89_dev *rtwdev, if (!cnt) goto out_unlock; rtw89_pci_release_tx(rtwdev, rx_ring, cnt); + + bd_cnt = rtw89_pci_get_avail_txbd_num(tx_ring); + if (bd_cnt == 0) + rtw89_pci_reclaim_txbd(rtwdev, tx_ring); } bd_cnt = rtw89_pci_get_avail_txbd_num(tx_ring); From c83dcd0508e231f909be3f52fee5ccf4844896c8 Mon Sep 17 00:00:00 2001 From: Ping-Ke Shih Date: Thu, 21 Apr 2022 20:08:53 +0800 Subject: [PATCH 172/228] rtw89: pci: add a separate interrupt handler for low power mode In lower power mode, there are very low amount of RX, and it must process in a separated function instead of schedule_napi(), because the existing napi_poll does many things to optimize performance, but not all registers can access in low power mode. The simple way is to use threadfn to process the simple thing. Signed-off-by: Ping-Ke Shih Signed-off-by: Kalle Valo Link: https://lore.kernel.org/r/20220421120903.73715-5-pkshih@realtek.com --- drivers/net/wireless/realtek/rtw89/core.c | 3 +++ drivers/net/wireless/realtek/rtw89/pci.c | 23 +++++++++++++++++++++++ 2 files changed, 26 insertions(+) diff --git a/drivers/net/wireless/realtek/rtw89/core.c b/drivers/net/wireless/realtek/rtw89/core.c index 6e8a65b021ce4..796b205854ac6 100644 --- a/drivers/net/wireless/realtek/rtw89/core.c +++ b/drivers/net/wireless/realtek/rtw89/core.c @@ -1420,7 +1420,10 @@ static void rtw89_core_rx_to_mac80211(struct rtw89_dev *rtwdev, { rtw89_core_hw_to_sband_rate(rx_status); rtw89_core_rx_stats(rtwdev, phy_ppdu, desc_info, skb_ppdu); + /* In low power mode, it does RX in thread context. */ + local_bh_disable(); ieee80211_rx_napi(rtwdev->hw, NULL, skb_ppdu, &rtwdev->napi); + local_bh_enable(); rtwdev->napi_budget_countdown--; } diff --git a/drivers/net/wireless/realtek/rtw89/pci.c b/drivers/net/wireless/realtek/rtw89/pci.c index c1bb44bcd48e1..e8bcecbe77e14 100644 --- a/drivers/net/wireless/realtek/rtw89/pci.c +++ b/drivers/net/wireless/realtek/rtw89/pci.c @@ -713,6 +713,18 @@ static void rtw89_pci_ops_recovery_complete(struct rtw89_dev *rtwdev) spin_unlock_irqrestore(&rtwpci->irq_lock, flags); } +static void rtw89_pci_low_power_interrupt_handler(struct rtw89_dev *rtwdev) +{ + struct rtw89_pci *rtwpci = (struct rtw89_pci *)rtwdev->priv; + int budget = NAPI_POLL_WEIGHT; + + /* To prevent RXQ get stuck due to run out of budget. */ + rtwdev->napi_budget_countdown = budget; + + rtw89_pci_poll_rpq_dma(rtwdev, rtwpci, budget); + rtw89_pci_poll_rxq_dma(rtwdev, rtwpci, budget); +} + static irqreturn_t rtw89_pci_interrupt_threadfn(int irq, void *dev) { struct rtw89_dev *rtwdev = dev; @@ -733,6 +745,11 @@ static irqreturn_t rtw89_pci_interrupt_threadfn(int irq, void *dev) if (unlikely(rtwpci->under_recovery)) return IRQ_HANDLED; + if (unlikely(rtwpci->low_power)) { + rtw89_pci_low_power_interrupt_handler(rtwdev); + goto enable_intr; + } + if (likely(rtwpci->running)) { local_bh_disable(); napi_schedule(&rtwdev->napi); @@ -740,6 +757,12 @@ static irqreturn_t rtw89_pci_interrupt_threadfn(int irq, void *dev) } return IRQ_HANDLED; + +enable_intr: + spin_lock_irqsave(&rtwpci->irq_lock, flags); + rtw89_chip_enable_intr(rtwdev, rtwpci); + spin_unlock_irqrestore(&rtwpci->irq_lock, flags); + return IRQ_HANDLED; } static irqreturn_t rtw89_pci_interrupt_handler(int irq, void *dev) From 98816def1973dfb493143de93446a273b9f83327 Mon Sep 17 00:00:00 2001 From: Ping-Ke Shih Date: Thu, 21 Apr 2022 20:08:54 +0800 Subject: [PATCH 173/228] rtw89: ser: re-enable interrupt in threadfn if under_recovery Normally, we re-enable interrupt by napi_poll, but for this special situation, we must turn it on immediately because napi_poll isn't scheduled. Signed-off-by: Ping-Ke Shih Signed-off-by: Kalle Valo Link: https://lore.kernel.org/r/20220421120903.73715-6-pkshih@realtek.com --- drivers/net/wireless/realtek/rtw89/pci.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/net/wireless/realtek/rtw89/pci.c b/drivers/net/wireless/realtek/rtw89/pci.c index e8bcecbe77e14..ad3db5aa890c6 100644 --- a/drivers/net/wireless/realtek/rtw89/pci.c +++ b/drivers/net/wireless/realtek/rtw89/pci.c @@ -743,7 +743,7 @@ static irqreturn_t rtw89_pci_interrupt_threadfn(int irq, void *dev) rtw89_ser_notify(rtwdev, rtw89_mac_get_err_status(rtwdev)); if (unlikely(rtwpci->under_recovery)) - return IRQ_HANDLED; + goto enable_intr; if (unlikely(rtwpci->low_power)) { rtw89_pci_low_power_interrupt_handler(rtwdev); From 52edbb9fb78a24f355830da2e668db13689e3da6 Mon Sep 17 00:00:00 2001 From: Ping-Ke Shih Date: Thu, 21 Apr 2022 20:08:55 +0800 Subject: [PATCH 174/228] rtw89: ps: access TX/RX rings via another registers in low power mode In low power mode, we need to pause PCI to configure IMR and PCI ring index registers accordingly, because the regular registers are power-off in this mode. In the transition moment named paused in code, we can't touch ring index, so don't kick off DMA immediately. Instead, queue them into pending queue, and kick off after the moment. There are three low power modes, which are RF off/clock gate/power gate, but PCI enter low power mode in later two modes only. So, add a mask to achieve this. Signed-off-by: Ping-Ke Shih Signed-off-by: Kalle Valo Link: https://lore.kernel.org/r/20220421120903.73715-7-pkshih@realtek.com --- drivers/net/wireless/realtek/rtw89/core.h | 14 +++ drivers/net/wireless/realtek/rtw89/pci.c | 103 +++++++++++++++++- drivers/net/wireless/realtek/rtw89/pci.h | 16 +++ drivers/net/wireless/realtek/rtw89/ps.c | 34 +++++- drivers/net/wireless/realtek/rtw89/rtw8852a.c | 1 + .../net/wireless/realtek/rtw89/rtw8852ae.c | 1 + drivers/net/wireless/realtek/rtw89/rtw8852c.c | 2 + .../net/wireless/realtek/rtw89/rtw8852ce.c | 10 ++ 8 files changed, 177 insertions(+), 4 deletions(-) diff --git a/drivers/net/wireless/realtek/rtw89/core.h b/drivers/net/wireless/realtek/rtw89/core.h index f34aca70908e0..27a3ceda90b90 100644 --- a/drivers/net/wireless/realtek/rtw89/core.h +++ b/drivers/net/wireless/realtek/rtw89/core.h @@ -2036,6 +2036,8 @@ struct rtw89_hci_ops { void (*reset)(struct rtw89_dev *rtwdev); int (*start)(struct rtw89_dev *rtwdev); void (*stop)(struct rtw89_dev *rtwdev); + void (*pause)(struct rtw89_dev *rtwdev, bool pause); + void (*switch_mode)(struct rtw89_dev *rtwdev, bool low_power); void (*recalc_int_mit)(struct rtw89_dev *rtwdev); u8 (*read8)(struct rtw89_dev *rtwdev, u32 addr); @@ -2067,6 +2069,7 @@ struct rtw89_hci_info { enum rtw89_hci_type type; u32 rpwm_addr; u32 cpwm_addr; + bool paused; }; struct rtw89_chip_ops { @@ -2428,6 +2431,7 @@ struct rtw89_chip_info { u8 rf_para_dlink_num; const struct rtw89_btc_rf_trx_para *rf_para_dlink; u8 ps_mode_supported; + u8 low_power_hci_modes; u32 h2c_cctl_func_id; u32 hci_func_en_addr; @@ -3167,6 +3171,16 @@ static inline int rtw89_hci_deinit(struct rtw89_dev *rtwdev) return rtwdev->hci.ops->deinit(rtwdev); } +static inline void rtw89_hci_pause(struct rtw89_dev *rtwdev, bool pause) +{ + rtwdev->hci.ops->pause(rtwdev, pause); +} + +static inline void rtw89_hci_switch_mode(struct rtw89_dev *rtwdev, bool low_power) +{ + rtwdev->hci.ops->switch_mode(rtwdev, low_power); +} + static inline void rtw89_hci_recalc_int_mit(struct rtw89_dev *rtwdev) { rtwdev->hci.ops->recalc_int_mit(rtwdev); diff --git a/drivers/net/wireless/realtek/rtw89/pci.c b/drivers/net/wireless/realtek/rtw89/pci.c index ad3db5aa890c6..31c62d116f44f 100644 --- a/drivers/net/wireless/realtek/rtw89/pci.c +++ b/drivers/net/wireless/realtek/rtw89/pci.c @@ -919,6 +919,21 @@ u32 __rtw89_pci_check_and_reclaim_tx_fwcmd_resource(struct rtw89_dev *rtwdev) return cnt; } +static +u32 __rtw89_pci_check_and_reclaim_tx_resource_noio(struct rtw89_dev *rtwdev, + u8 txch) +{ + struct rtw89_pci *rtwpci = (struct rtw89_pci *)rtwdev->priv; + struct rtw89_pci_tx_ring *tx_ring = &rtwpci->tx_rings[txch]; + u32 cnt; + + spin_lock_bh(&rtwpci->trx_lock); + cnt = rtw89_pci_get_avail_txbd_num(tx_ring); + spin_unlock_bh(&rtwpci->trx_lock); + + return cnt; +} + static u32 __rtw89_pci_check_and_reclaim_tx_resource(struct rtw89_dev *rtwdev, u8 txch) { @@ -961,6 +976,9 @@ static u32 __rtw89_pci_check_and_reclaim_tx_resource(struct rtw89_dev *rtwdev, static u32 rtw89_pci_check_and_reclaim_tx_resource(struct rtw89_dev *rtwdev, u8 txch) { + if (rtwdev->hci.paused) + return __rtw89_pci_check_and_reclaim_tx_resource_noio(rtwdev, txch); + if (txch == RTW89_TXCH_CH12) return __rtw89_pci_check_and_reclaim_tx_fwcmd_resource(rtwdev); @@ -969,12 +987,17 @@ static u32 rtw89_pci_check_and_reclaim_tx_resource(struct rtw89_dev *rtwdev, static void __rtw89_pci_tx_kick_off(struct rtw89_dev *rtwdev, struct rtw89_pci_tx_ring *tx_ring) { + struct rtw89_pci *rtwpci = (struct rtw89_pci *)rtwdev->priv; struct rtw89_pci_dma_ring *bd_ring = &tx_ring->bd_ring; u32 host_idx, addr; + spin_lock_bh(&rtwpci->trx_lock); + addr = bd_ring->addr.idx; host_idx = bd_ring->wp; rtw89_write16(rtwdev, addr, host_idx); + + spin_unlock_bh(&rtwpci->trx_lock); } static void rtw89_pci_tx_bd_ring_update(struct rtw89_dev *rtwdev, struct rtw89_pci_tx_ring *tx_ring, @@ -995,9 +1018,27 @@ static void rtw89_pci_ops_tx_kick_off(struct rtw89_dev *rtwdev, u8 txch) struct rtw89_pci *rtwpci = (struct rtw89_pci *)rtwdev->priv; struct rtw89_pci_tx_ring *tx_ring = &rtwpci->tx_rings[txch]; - spin_lock_bh(&rtwpci->trx_lock); + if (rtwdev->hci.paused) { + set_bit(txch, rtwpci->kick_map); + return; + } + __rtw89_pci_tx_kick_off(rtwdev, tx_ring); - spin_unlock_bh(&rtwpci->trx_lock); +} + +static void rtw89_pci_tx_kick_off_pending(struct rtw89_dev *rtwdev) +{ + struct rtw89_pci *rtwpci = (struct rtw89_pci *)rtwdev->priv; + struct rtw89_pci_tx_ring *tx_ring; + int txch; + + for (txch = 0; txch < RTW89_TXCH_NUM; txch++) { + if (!test_and_clear_bit(txch, rtwpci->kick_map)) + continue; + + tx_ring = &rtwpci->tx_rings[txch]; + __rtw89_pci_tx_kick_off(rtwdev, tx_ring); + } } static void __pci_flush_txch(struct rtw89_dev *rtwdev, u8 txch, bool drop) @@ -1423,6 +1464,62 @@ static void rtw89_pci_ops_stop(struct rtw89_dev *rtwdev) rtw89_core_napi_stop(rtwdev); } +static void rtw89_pci_ops_pause(struct rtw89_dev *rtwdev, bool pause) +{ + struct rtw89_pci *rtwpci = (struct rtw89_pci *)rtwdev->priv; + struct pci_dev *pdev = rtwpci->pdev; + + if (pause) { + rtw89_pci_disable_intr_lock(rtwdev); + synchronize_irq(pdev->irq); + if (test_bit(RTW89_FLAG_NAPI_RUNNING, rtwdev->flags)) + napi_synchronize(&rtwdev->napi); + } else { + rtw89_pci_enable_intr_lock(rtwdev); + rtw89_pci_tx_kick_off_pending(rtwdev); + } +} + +static +void rtw89_pci_switch_bd_idx_addr(struct rtw89_dev *rtwdev, bool low_power) +{ + struct rtw89_pci *rtwpci = (struct rtw89_pci *)rtwdev->priv; + const struct rtw89_pci_info *info = rtwdev->pci_info; + const struct rtw89_pci_bd_idx_addr *bd_idx_addr = info->bd_idx_addr_low_power; + const struct rtw89_pci_ch_dma_addr_set *dma_addr_set = info->dma_addr_set; + struct rtw89_pci_tx_ring *tx_ring; + struct rtw89_pci_rx_ring *rx_ring; + int i; + + if (WARN(!bd_idx_addr, "only HCI with low power mode needs this\n")) + return; + + for (i = 0; i < RTW89_TXCH_NUM; i++) { + tx_ring = &rtwpci->tx_rings[i]; + tx_ring->bd_ring.addr.idx = low_power ? + bd_idx_addr->tx_bd_addrs[i] : + dma_addr_set->tx[i].idx; + } + + for (i = 0; i < RTW89_RXCH_NUM; i++) { + rx_ring = &rtwpci->rx_rings[i]; + rx_ring->bd_ring.addr.idx = low_power ? + bd_idx_addr->rx_bd_addrs[i] : + dma_addr_set->rx[i].idx; + } +} + +static void rtw89_pci_ops_switch_mode(struct rtw89_dev *rtwdev, bool low_power) +{ + enum rtw89_pci_intr_mask_cfg cfg; + + WARN(!rtwdev->hci.paused, "HCI isn't paused\n"); + + cfg = low_power ? RTW89_PCI_INTR_MASK_LOW_POWER : RTW89_PCI_INTR_MASK_NORMAL; + rtw89_chip_config_intr_mask(rtwdev, cfg); + rtw89_pci_switch_bd_idx_addr(rtwdev, low_power); +} + static void rtw89_pci_ops_write32(struct rtw89_dev *rtwdev, u32 addr, u32 data); static u32 rtw89_pci_ops_read32_cmac(struct rtw89_dev *rtwdev, u32 addr) @@ -3488,6 +3585,8 @@ static const struct rtw89_hci_ops rtw89_pci_ops = { .reset = rtw89_pci_ops_reset, .start = rtw89_pci_ops_start, .stop = rtw89_pci_ops_stop, + .pause = rtw89_pci_ops_pause, + .switch_mode = rtw89_pci_ops_switch_mode, .recalc_int_mit = rtw89_pci_recalc_int_mit, .read8 = rtw89_pci_ops_read8, diff --git a/drivers/net/wireless/realtek/rtw89/pci.h b/drivers/net/wireless/realtek/rtw89/pci.h index c203c8cbf1632..bb585ed191908 100644 --- a/drivers/net/wireless/realtek/rtw89/pci.h +++ b/drivers/net/wireless/realtek/rtw89/pci.h @@ -202,6 +202,15 @@ #define B_AX_PCIE_DBG_STE_INT BIT(13) /* TX/RX */ +#define R_AX_DRV_FW_HSK_0 0x01B0 +#define R_AX_DRV_FW_HSK_1 0x01B4 +#define R_AX_DRV_FW_HSK_2 0x01B8 +#define R_AX_DRV_FW_HSK_3 0x01BC +#define R_AX_DRV_FW_HSK_4 0x01C0 +#define R_AX_DRV_FW_HSK_5 0x01C4 +#define R_AX_DRV_FW_HSK_6 0x01C8 +#define R_AX_DRV_FW_HSK_7 0x01CC + #define R_AX_RXQ_RXBD_IDX 0x1050 #define R_AX_RPQ_RXBD_IDX 0x1054 #define R_AX_ACH0_TXBD_IDX 0x1058 @@ -658,6 +667,11 @@ enum rtw89_pci_intr_mask_cfg { struct rtw89_pci_isrs; struct rtw89_pci; +struct rtw89_pci_bd_idx_addr { + u32 tx_bd_addrs[RTW89_TXCH_NUM]; + u32 rx_bd_addrs[RTW89_RXCH_NUM]; +}; + struct rtw89_pci_ch_dma_addr { u32 num; u32 idx; @@ -703,6 +717,7 @@ struct rtw89_pci_info { u32 rpwm_addr; u32 cpwm_addr; + const struct rtw89_pci_bd_idx_addr *bd_idx_addr_low_power; const struct rtw89_pci_ch_dma_addr_set *dma_addr_set; int (*ltr_set)(struct rtw89_dev *rtwdev, bool en); @@ -880,6 +895,7 @@ struct rtw89_pci { struct rtw89_pci_rx_ring rx_rings[RTW89_RXCH_NUM]; struct sk_buff_head h2c_queue; struct sk_buff_head h2c_release_queue; + DECLARE_BITMAP(kick_map, RTW89_TXCH_NUM); u32 ind_intrs; u32 halt_c2h_intrs; diff --git a/drivers/net/wireless/realtek/rtw89/ps.c b/drivers/net/wireless/realtek/rtw89/ps.c index 7eaa01e41ef24..a90b337205885 100644 --- a/drivers/net/wireless/realtek/rtw89/ps.c +++ b/drivers/net/wireless/realtek/rtw89/ps.c @@ -29,6 +29,36 @@ static int rtw89_fw_leave_lps_check(struct rtw89_dev *rtwdev, u8 macid) return 0; } +static void rtw89_ps_power_mode_change_with_hci(struct rtw89_dev *rtwdev, + bool enter) +{ + ieee80211_stop_queues(rtwdev->hw); + rtwdev->hci.paused = true; + flush_work(&rtwdev->txq_work); + ieee80211_wake_queues(rtwdev->hw); + + rtw89_hci_pause(rtwdev, true); + rtw89_mac_power_mode_change(rtwdev, enter); + rtw89_hci_switch_mode(rtwdev, enter); + rtw89_hci_pause(rtwdev, false); + + rtwdev->hci.paused = false; + + if (!enter) { + local_bh_disable(); + napi_schedule(&rtwdev->napi); + local_bh_enable(); + } +} + +static void rtw89_ps_power_mode_change(struct rtw89_dev *rtwdev, bool enter) +{ + if (rtwdev->chip->low_power_hci_modes & BIT(rtwdev->ps_mode)) + rtw89_ps_power_mode_change_with_hci(rtwdev, enter); + else + rtw89_mac_power_mode_change(rtwdev, enter); +} + static void __rtw89_enter_ps_mode(struct rtw89_dev *rtwdev) { if (!rtwdev->ps_mode) @@ -37,7 +67,7 @@ static void __rtw89_enter_ps_mode(struct rtw89_dev *rtwdev) if (test_and_set_bit(RTW89_FLAG_LOW_POWER_MODE, rtwdev->flags)) return; - rtw89_mac_power_mode_change(rtwdev, true); + rtw89_ps_power_mode_change(rtwdev, true); } void __rtw89_leave_ps_mode(struct rtw89_dev *rtwdev) @@ -46,7 +76,7 @@ void __rtw89_leave_ps_mode(struct rtw89_dev *rtwdev) return; if (test_and_clear_bit(RTW89_FLAG_LOW_POWER_MODE, rtwdev->flags)) - rtw89_mac_power_mode_change(rtwdev, false); + rtw89_ps_power_mode_change(rtwdev, false); } static void __rtw89_enter_lps(struct rtw89_dev *rtwdev, u8 mac_id) diff --git a/drivers/net/wireless/realtek/rtw89/rtw8852a.c b/drivers/net/wireless/realtek/rtw89/rtw8852a.c index cb93287d47222..5af618709dedd 100644 --- a/drivers/net/wireless/realtek/rtw89/rtw8852a.c +++ b/drivers/net/wireless/realtek/rtw89/rtw8852a.c @@ -2150,6 +2150,7 @@ const struct rtw89_chip_info rtw8852a_chip_info = { .ps_mode_supported = BIT(RTW89_PS_MODE_RFOFF) | BIT(RTW89_PS_MODE_CLK_GATED) | BIT(RTW89_PS_MODE_PWR_GATED), + .low_power_hci_modes = 0, .h2c_cctl_func_id = H2C_FUNC_MAC_CCTLINFO_UD, .hci_func_en_addr = R_AX_HCI_FUNC_EN, .h2c_desc_size = sizeof(struct rtw89_txwd_body), diff --git a/drivers/net/wireless/realtek/rtw89/rtw8852ae.c b/drivers/net/wireless/realtek/rtw89/rtw8852ae.c index c6937e5943ea7..190c4aefb02e3 100644 --- a/drivers/net/wireless/realtek/rtw89/rtw8852ae.c +++ b/drivers/net/wireless/realtek/rtw89/rtw8852ae.c @@ -41,6 +41,7 @@ static const struct rtw89_pci_info rtw8852a_pci_info = { .rpwm_addr = R_AX_PCIE_HRPWM, .cpwm_addr = R_AX_CPWM, + .bd_idx_addr_low_power = NULL, .dma_addr_set = &rtw89_pci_ch_dma_addr_set, .ltr_set = rtw89_pci_ltr_set, diff --git a/drivers/net/wireless/realtek/rtw89/rtw8852c.c b/drivers/net/wireless/realtek/rtw89/rtw8852c.c index 510614630bfbb..1302d4324473e 100644 --- a/drivers/net/wireless/realtek/rtw89/rtw8852c.c +++ b/drivers/net/wireless/realtek/rtw89/rtw8852c.c @@ -2006,6 +2006,8 @@ const struct rtw89_chip_info rtw8852c_chip_info = { .dav_log_efuse_size = 16, .phycap_addr = 0x590, .phycap_size = 0x60, + .low_power_hci_modes = BIT(RTW89_PS_MODE_CLK_GATED) | + BIT(RTW89_PS_MODE_PWR_GATED), .h2c_cctl_func_id = H2C_FUNC_MAC_CCTLINFO_UD_V1, .hci_func_en_addr = R_AX_HCI_FUNC_EN_V1, .h2c_desc_size = sizeof(struct rtw89_rxdesc_short), diff --git a/drivers/net/wireless/realtek/rtw89/rtw8852ce.c b/drivers/net/wireless/realtek/rtw89/rtw8852ce.c index 4d71cc87f7ba8..fc03944940130 100644 --- a/drivers/net/wireless/realtek/rtw89/rtw8852ce.c +++ b/drivers/net/wireless/realtek/rtw89/rtw8852ce.c @@ -9,6 +9,15 @@ #include "reg.h" #include "rtw8852c.h" +static const struct rtw89_pci_bd_idx_addr rtw8852c_bd_idx_addr_low_power = { + .tx_bd_addrs = {R_AX_DRV_FW_HSK_0, R_AX_DRV_FW_HSK_1, R_AX_DRV_FW_HSK_2, + R_AX_DRV_FW_HSK_3, 0, 0, + 0, 0, R_AX_DRV_FW_HSK_4, + 0, 0, 0, + R_AX_DRV_FW_HSK_5}, + .rx_bd_addrs = {R_AX_DRV_FW_HSK_6, R_AX_DRV_FW_HSK_7}, +}; + static const struct rtw89_pci_info rtw8852c_pci_info = { .txbd_trunc_mode = MAC_AX_BD_TRUNC, .rxbd_trunc_mode = MAC_AX_BD_TRUNC, @@ -41,6 +50,7 @@ static const struct rtw89_pci_info rtw8852c_pci_info = { .rpwm_addr = R_AX_PCIE_HRPWM_V1, .cpwm_addr = R_AX_PCIE_CRPWM, + .bd_idx_addr_low_power = &rtw8852c_bd_idx_addr_low_power, .dma_addr_set = &rtw89_pci_ch_dma_addr_set_v1, .ltr_set = rtw89_pci_ltr_set_v1, From d7259cdbd05598ec7e1e5a14f4c3644d80331758 Mon Sep 17 00:00:00 2001 From: Ping-Ke Shih Date: Thu, 21 Apr 2022 20:08:56 +0800 Subject: [PATCH 175/228] rtw89: pci: allow to process RPP prior to TX BD RPP is to report certain skb(s) can be freed, and TX BD indicates which TX descriptors can be freed. Normally, TX BD is happened before RPP. In low power mode, RPP can happen ahead, so change flow to handle this case. Signed-off-by: Ping-Ke Shih Signed-off-by: Kalle Valo Link: https://lore.kernel.org/r/20220421120903.73715-8-pkshih@realtek.com --- drivers/net/wireless/realtek/rtw89/pci.c | 21 ++++++++++----------- 1 file changed, 10 insertions(+), 11 deletions(-) diff --git a/drivers/net/wireless/realtek/rtw89/pci.c b/drivers/net/wireless/realtek/rtw89/pci.c index 31c62d116f44f..2bdce7024f25b 100644 --- a/drivers/net/wireless/realtek/rtw89/pci.c +++ b/drivers/net/wireless/realtek/rtw89/pci.c @@ -382,6 +382,10 @@ static void rtw89_pci_reclaim_txbd(struct rtw89_dev *rtwdev, struct rtw89_pci_tx } list_del_init(&txwd->list); + + /* this skb has been freed by RPP */ + if (skb_queue_len(&txwd->queue) == 0) + rtw89_pci_enqueue_txwd(tx_ring, txwd); } } @@ -413,18 +417,12 @@ static void rtw89_pci_release_txwd_skb(struct rtw89_dev *rtwdev, if (!list_empty(&txwd->list)) { rtw89_pci_reclaim_txbd(rtwdev, tx_ring); - if (!list_empty(&txwd->list)) { + /* In low power mode, RPP can receive before updating of TX BD. + * In normal mode, it should not happen so give it a warning. + */ + if (!rtwpci->low_power && !list_empty(&txwd->list)) rtw89_warn(rtwdev, "queue %d txwd %d is not idle\n", txch, seq); - return; - } - } - - /* currently, support for only one frame */ - if (skb_queue_len(&txwd->queue) != 1) { - rtw89_warn(rtwdev, "empty pending queue %d page %d\n", - txch, seq); - return; } skb_queue_walk_safe(&txwd->queue, skb, tmp) { @@ -437,7 +435,8 @@ static void rtw89_pci_release_txwd_skb(struct rtw89_dev *rtwdev, rtw89_pci_tx_status(rtwdev, tx_ring, skb, tx_status); } - rtw89_pci_enqueue_txwd(tx_ring, txwd); + if (list_empty(&txwd->list)) + rtw89_pci_enqueue_txwd(tx_ring, txwd); } static void rtw89_pci_release_rpp(struct rtw89_dev *rtwdev, From fc5f311fce742d906294360e378c1df631d2d692 Mon Sep 17 00:00:00 2001 From: Ping-Ke Shih Date: Thu, 21 Apr 2022 20:08:57 +0800 Subject: [PATCH 176/228] rtw89: don't flush hci queues and send h2c if power is off When disconnecting, it warns somethings after power is off, and we can't do HCI IO. So, add this patch to avoid below messages: rtw89_8852ce 0000:03:00.0: timed out to flush pci txch: 11 rtw89_8852ce 0000:03:00.0: failed to pre-release fwcmd Signed-off-by: Ping-Ke Shih Signed-off-by: Kalle Valo Link: https://lore.kernel.org/r/20220421120903.73715-9-pkshih@realtek.com --- drivers/net/wireless/realtek/rtw89/core.c | 7 +++++++ drivers/net/wireless/realtek/rtw89/core.h | 3 +++ 2 files changed, 10 insertions(+) diff --git a/drivers/net/wireless/realtek/rtw89/core.c b/drivers/net/wireless/realtek/rtw89/core.c index 796b205854ac6..e3317deafa1d0 100644 --- a/drivers/net/wireless/realtek/rtw89/core.c +++ b/drivers/net/wireless/realtek/rtw89/core.c @@ -856,6 +856,13 @@ int rtw89_h2c_tx(struct rtw89_dev *rtwdev, u32 cnt; int ret; + if (!test_bit(RTW89_FLAG_POWERON, rtwdev->flags)) { + rtw89_debug(rtwdev, RTW89_DBG_FW, + "ignore h2c due to power is off with firmware state=%d\n", + test_bit(RTW89_FLAG_FW_RDY, rtwdev->flags)); + return 0; + } + tx_req.skb = skb; tx_req.tx_type = RTW89_CORE_TX_TYPE_FWCMD; if (fwdl) diff --git a/drivers/net/wireless/realtek/rtw89/core.h b/drivers/net/wireless/realtek/rtw89/core.h index 27a3ceda90b90..6ca915cb7a29f 100644 --- a/drivers/net/wireless/realtek/rtw89/core.h +++ b/drivers/net/wireless/realtek/rtw89/core.h @@ -3199,6 +3199,9 @@ static inline void rtw89_hci_tx_kick_off(struct rtw89_dev *rtwdev, u8 txch) static inline void rtw89_hci_flush_queues(struct rtw89_dev *rtwdev, u32 queues, bool drop) { + if (!test_bit(RTW89_FLAG_POWERON, rtwdev->flags)) + return; + if (rtwdev->hci.ops->flush_queues) return rtwdev->hci.ops->flush_queues(rtwdev, queues, drop); } From 16b44ed0ffd3ccb4bfe741a6ed88c08faf84efa4 Mon Sep 17 00:00:00 2001 From: Ping-Ke Shih Date: Thu, 21 Apr 2022 20:08:58 +0800 Subject: [PATCH 177/228] rtw89: add RF H2C to notify firmware IQK results in hardware has two copies that are used by firmware to switch these two to support MCC. This H2C tell firmware the corresponding channel and band of each IQK results, and currrent one. Signed-off-by: Ping-Ke Shih Signed-off-by: Kalle Valo Link: https://lore.kernel.org/r/20220421120903.73715-10-pkshih@realtek.com --- drivers/net/wireless/realtek/rtw89/core.h | 8 ++++ drivers/net/wireless/realtek/rtw89/fw.c | 39 +++++++++++++++++++ drivers/net/wireless/realtek/rtw89/fw.h | 12 ++++++ drivers/net/wireless/realtek/rtw89/rtw8852c.c | 14 +++++++ 4 files changed, 73 insertions(+) diff --git a/drivers/net/wireless/realtek/rtw89/core.h b/drivers/net/wireless/realtek/rtw89/core.h index 6ca915cb7a29f..9be74d8673cfd 100644 --- a/drivers/net/wireless/realtek/rtw89/core.h +++ b/drivers/net/wireless/realtek/rtw89/core.h @@ -2634,6 +2634,13 @@ struct rtw89_dack_info { #define RTW89_IQK_CHS_NR 2 #define RTW89_IQK_PATH_NR 4 + +struct rtw89_mcc_info { + u8 ch[RTW89_IQK_CHS_NR]; + u8 band[RTW89_IQK_CHS_NR]; + u8 table_idx; +}; + struct rtw89_iqk_info { bool lok_cor_fail[RTW89_IQK_CHS_NR][RTW89_IQK_PATH_NR]; bool lok_fin_fail[RTW89_IQK_CHS_NR][RTW89_IQK_PATH_NR]; @@ -3105,6 +3112,7 @@ struct rtw89_dev { struct rtw89_dack_info dack; struct rtw89_iqk_info iqk; struct rtw89_dpk_info dpk; + struct rtw89_mcc_info mcc; bool is_tssi_mode[RF_PATH_MAX]; bool is_bt_iqk_timeout; diff --git a/drivers/net/wireless/realtek/rtw89/fw.c b/drivers/net/wireless/realtek/rtw89/fw.c index 7bef8b4288f0c..e4be785709d10 100644 --- a/drivers/net/wireless/realtek/rtw89/fw.c +++ b/drivers/net/wireless/realtek/rtw89/fw.c @@ -1785,6 +1785,45 @@ int rtw89_fw_h2c_rf_reg(struct rtw89_dev *rtwdev, return -EBUSY; } +int rtw89_fw_h2c_rf_ntfy_mcc(struct rtw89_dev *rtwdev) +{ + struct rtw89_mcc_info *mcc_info = &rtwdev->mcc; + struct rtw89_fw_h2c_rf_get_mccch *mccch; + struct sk_buff *skb; + + skb = rtw89_fw_h2c_alloc_skb_with_hdr(rtwdev, sizeof(*mccch)); + if (!skb) { + rtw89_err(rtwdev, "failed to alloc skb for h2c cxdrv_ctrl\n"); + return -ENOMEM; + } + skb_put(skb, sizeof(*mccch)); + mccch = (struct rtw89_fw_h2c_rf_get_mccch *)skb->data; + + mccch->ch_0 = cpu_to_le32(mcc_info->ch[0]); + mccch->ch_1 = cpu_to_le32(mcc_info->ch[1]); + mccch->band_0 = cpu_to_le32(mcc_info->band[0]); + mccch->band_1 = cpu_to_le32(mcc_info->band[1]); + mccch->current_channel = cpu_to_le32(rtwdev->hal.current_channel); + mccch->current_band_type = cpu_to_le32(rtwdev->hal.current_band_type); + + rtw89_h2c_pkt_set_hdr(rtwdev, skb, FWCMD_TYPE_H2C, + H2C_CAT_OUTSRC, H2C_CL_OUTSRC_RF_FW_NOTIFY, + H2C_FUNC_OUTSRC_RF_GET_MCCCH, 0, 0, + sizeof(*mccch)); + + if (rtw89_h2c_tx(rtwdev, skb, false)) { + rtw89_err(rtwdev, "failed to send h2c\n"); + goto fail; + } + + return 0; +fail: + dev_kfree_skb_any(skb); + + return -EBUSY; +} +EXPORT_SYMBOL(rtw89_fw_h2c_rf_ntfy_mcc); + int rtw89_fw_h2c_raw_with_hdr(struct rtw89_dev *rtwdev, u8 h2c_class, u8 h2c_func, u8 *buf, u16 len, bool rack, bool dack) diff --git a/drivers/net/wireless/realtek/rtw89/fw.h b/drivers/net/wireless/realtek/rtw89/fw.h index aaabfc0dfd713..95a55c4213db3 100644 --- a/drivers/net/wireless/realtek/rtw89/fw.h +++ b/drivers/net/wireless/realtek/rtw89/fw.h @@ -2538,6 +2538,17 @@ struct rtw89_fw_h2c_rf_reg_info { #define H2C_CL_OUTSRC_RF_REG_A 0x8 #define H2C_CL_OUTSRC_RF_REG_B 0x9 +#define H2C_CL_OUTSRC_RF_FW_NOTIFY 0xa +#define H2C_FUNC_OUTSRC_RF_GET_MCCCH 0x2 + +struct rtw89_fw_h2c_rf_get_mccch { + __le32 ch_0; + __le32 ch_1; + __le32 band_0; + __le32 band_1; + __le32 current_channel; + __le32 current_band_type; +} __packed; #define RTW89_FW_RSVD_PLE_SIZE 0x800 @@ -2602,6 +2613,7 @@ int rtw89_fw_h2c_scan_offload(struct rtw89_dev *rtwdev, int rtw89_fw_h2c_rf_reg(struct rtw89_dev *rtwdev, struct rtw89_fw_h2c_rf_reg_info *info, u16 len, u8 page); +int rtw89_fw_h2c_rf_ntfy_mcc(struct rtw89_dev *rtwdev); int rtw89_fw_h2c_raw_with_hdr(struct rtw89_dev *rtwdev, u8 h2c_class, u8 h2c_func, u8 *buf, u16 len, bool rack, bool dack); diff --git a/drivers/net/wireless/realtek/rtw89/rtw8852c.c b/drivers/net/wireless/realtek/rtw89/rtw8852c.c index 1302d4324473e..3ee57df0a6396 100644 --- a/drivers/net/wireless/realtek/rtw89/rtw8852c.c +++ b/drivers/net/wireless/realtek/rtw89/rtw8852c.c @@ -1766,6 +1766,18 @@ static void rtw8852c_set_channel_help(struct rtw89_dev *rtwdev, bool enter, } } +static void rtw8852c_rfk_init(struct rtw89_dev *rtwdev) +{ + struct rtw89_mcc_info *mcc_info = &rtwdev->mcc; + + memset(mcc_info, 0, sizeof(*mcc_info)); +} + +static void rtw8852c_rfk_channel(struct rtw89_dev *rtwdev) +{ + rtw89_fw_h2c_rf_ntfy_mcc(rtwdev); +} + static void rtw8852c_set_txpwr_ul_tb_offset(struct rtw89_dev *rtwdev, s8 pw_ofst, enum rtw89_mac_idx mac_idx) @@ -1955,6 +1967,8 @@ static const struct rtw89_chip_ops rtw8852c_chip_ops = { .set_channel_help = rtw8852c_set_channel_help, .read_efuse = rtw8852c_read_efuse, .read_phycap = rtw8852c_read_phycap, + .rfk_init = rtw8852c_rfk_init, + .rfk_channel = rtw8852c_rfk_channel, .power_trim = rtw8852c_power_trim, .read_rf = rtw89_phy_read_rf_v1, .write_rf = rtw89_phy_write_rf_v1, From cd89a47105dc697ee8a1e36f09147c2f0a03c830 Mon Sep 17 00:00:00 2001 From: Ping-Ke Shih Date: Thu, 21 Apr 2022 20:08:59 +0800 Subject: [PATCH 178/228] rtw89: 8852c: configure default BB TX/RX path 8852c propose new API to configure BB TX/RX path. Without fix patch, it can't transmit any packet. Signed-off-by: Ping-Ke Shih Signed-off-by: Kalle Valo Link: https://lore.kernel.org/r/20220421120903.73715-11-pkshih@realtek.com --- drivers/net/wireless/realtek/rtw89/core.h | 9 + drivers/net/wireless/realtek/rtw89/phy.c | 1 + drivers/net/wireless/realtek/rtw89/reg.h | 76 ++++++- drivers/net/wireless/realtek/rtw89/rtw8852a.c | 1 + drivers/net/wireless/realtek/rtw89/rtw8852c.c | 194 ++++++++++++++++++ 5 files changed, 279 insertions(+), 2 deletions(-) diff --git a/drivers/net/wireless/realtek/rtw89/core.h b/drivers/net/wireless/realtek/rtw89/core.h index 9be74d8673cfd..d544cf29e588a 100644 --- a/drivers/net/wireless/realtek/rtw89/core.h +++ b/drivers/net/wireless/realtek/rtw89/core.h @@ -2104,6 +2104,7 @@ struct rtw89_chip_ops { struct rtw89_rx_phy_ppdu *phy_ppdu, struct ieee80211_rx_status *status); void (*bb_ctrl_btc_preagc)(struct rtw89_dev *rtwdev, bool bt_en); + void (*cfg_txrx_path)(struct rtw89_dev *rtwdev); void (*set_txpwr_ul_tb_offset)(struct rtw89_dev *rtwdev, s8 pw_ofst, enum rtw89_mac_idx mac_idx); int (*pwr_on_func)(struct rtw89_dev *rtwdev); @@ -3633,6 +3634,14 @@ static inline void rtw89_chip_bb_ctrl_btc_preagc(struct rtw89_dev *rtwdev, chip->ops->bb_ctrl_btc_preagc(rtwdev, bt_en); } +static inline void rtw89_chip_cfg_txrx_path(struct rtw89_dev *rtwdev) +{ + const struct rtw89_chip_info *chip = rtwdev->chip; + + if (chip->ops->cfg_txrx_path) + chip->ops->cfg_txrx_path(rtwdev); +} + static inline void rtw89_chip_cfg_txpwr_ul_tb_offset(struct rtw89_dev *rtwdev, struct ieee80211_vif *vif) diff --git a/drivers/net/wireless/realtek/rtw89/phy.c b/drivers/net/wireless/realtek/rtw89/phy.c index 7d0593d8fafe9..33494e8451cf3 100644 --- a/drivers/net/wireless/realtek/rtw89/phy.c +++ b/drivers/net/wireless/realtek/rtw89/phy.c @@ -3592,6 +3592,7 @@ void rtw89_phy_dm_init(struct rtw89_dev *rtwdev) rtw89_load_txpwr_table(rtwdev, chip->byr_table); rtw89_chip_set_txpwr_ctrl(rtwdev); rtw89_chip_power_trim(rtwdev); + rtw89_chip_cfg_txrx_path(rtwdev); } void rtw89_phy_set_bss_color(struct rtw89_dev *rtwdev, struct ieee80211_vif *vif) diff --git a/drivers/net/wireless/realtek/rtw89/reg.h b/drivers/net/wireless/realtek/rtw89/reg.h index 0f08b25817976..6dc11e8e2a839 100644 --- a/drivers/net/wireless/realtek/rtw89/reg.h +++ b/drivers/net/wireless/realtek/rtw89/reg.h @@ -2962,6 +2962,45 @@ #define R_AX_PWR_MACID_LMT_TABLE0 0xD36C #define R_AX_PWR_MACID_LMT_TABLE127 0xD568 +#define R_AX_PATH_COM0 0xD800 +#define AX_PATH_COM0_DFVAL 0x00000000 +#define AX_PATH_COM0_PATHA 0x08888880 +#define AX_PATH_COM0_PATHB 0x11111100 +#define AX_PATH_COM0_PATHAB 0x19999980 +#define R_AX_PATH_COM1 0xD804 +#define AX_PATH_COM1_DFVAL 0x00000000 +#define AX_PATH_COM1_PATHA 0x11111111 +#define AX_PATH_COM1_PATHB 0x22222222 +#define AX_PATH_COM1_PATHAB 0x33333333 +#define R_AX_PATH_COM2 0xD808 +#define AX_PATH_COM2_DFVAL 0x00000000 +#define AX_PATH_COM2_PATHA 0x01209111 +#define AX_PATH_COM2_PATHB 0x01209222 +#define AX_PATH_COM2_PATHAB 0x01209333 +#define R_AX_PATH_COM3 0xD80C +#define AX_PATH_COM3_DFVAL 0x49249249 +#define R_AX_PATH_COM4 0xD810 +#define AX_PATH_COM4_DFVAL 0x1C9C9C49 +#define R_AX_PATH_COM5 0xD814 +#define AX_PATH_COM5_DFVAL 0x39393939 +#define R_AX_PATH_COM6 0xD818 +#define AX_PATH_COM6_DFVAL 0x39393939 +#define R_AX_PATH_COM7 0xD81C +#define AX_PATH_COM7_DFVAL 0x39393939 +#define AX_PATH_COM7_PATHA 0x39393939 +#define AX_PATH_COM7_PATHB 0x39383939 +#define AX_PATH_COM7_PATHAB 0x39393939 +#define R_AX_PATH_COM8 0xD820 +#define AX_PATH_COM8_DFVAL 0x00000000 +#define AX_PATH_COM8_PATHA 0x00003939 +#define AX_PATH_COM8_PATHB 0x00003938 +#define AX_PATH_COM8_PATHAB 0x00003939 +#define R_AX_PATH_COM9 0xD824 +#define AX_PATH_COM9_DFVAL 0x000007C0 +#define R_AX_PATH_COM10 0xD828 +#define AX_PATH_COM10_DFVAL 0xE0000000 +#define R_AX_PATH_COM11 0xD82C +#define AX_PATH_COM11_DFVAL 0x00000000 #define R_P80_AT_HIGH_FREQ_BB_WRP 0xD848 #define B_P80_AT_HIGH_FREQ_BB_WRP BIT(28) #define R_AX_TSSI_CTRL_HEAD 0xD908 @@ -3097,6 +3136,9 @@ #define R_AX_LTE_WDATA 0xDAF4 #define R_AX_LTE_RDATA 0xDAF8 +#define R_AX_MACID_ANT_TABLE 0xDC00 +#define R_AX_MACID_ANT_TABLE_LAST 0xDDFC + #define CMAC1_START_ADDR 0xE000 #define CMAC1_END_ADDR 0xFFFF #define R_AX_CMAC_REG_END 0xFFFF @@ -3360,9 +3402,10 @@ #define R_PMAC_RXMOD 0x0994 #define B_PMAC_RXMOD_MSK GENMASK(7, 4) #define R_MAC_SEL 0x09A4 -#define B_MAC_SEL_MOD GENMASK(4, 2) -#define B_MAC_SEL_DPD_EN BIT(10) +#define B_MAC_SEL_OFDM_TRI_FILTER BIT(31) #define B_MAC_SEL_PWR_EN BIT(16) +#define B_MAC_SEL_DPD_EN BIT(10) +#define B_MAC_SEL_MOD GENMASK(4, 2) #define R_PMAC_TX_CTRL 0x09C0 #define B_PMAC_TXEN_DIS BIT(0) #define R_PMAC_TX_PRD 0x09C4 @@ -3413,8 +3456,16 @@ #define B_SNDCCA_A1_EN GENMASK(19, 12) #define R_SNDCCA_A2 0x0CA0 #define B_SNDCCA_A2_VAL GENMASK(19, 12) +#define R_RXHT_MCS_LIMIT 0x0D18 +#define B_RXHT_MCS_LIMIT GENMASK(9, 8) +#define R_RXVHT_MCS_LIMIT 0x0D18 +#define B_RXVHT_MCS_LIMIT GENMASK(22, 21) #define R_P0_EN_SOUND_WO_NDP 0x0D7C #define B_P0_EN_SOUND_WO_NDP BIT(1) +#define R_RXHE 0x0D80 +#define B_RXHETB_MAX_NSS GENMASK(25, 23) +#define B_RXHE_MAX_NSS GENMASK(16, 14) +#define B_RXHE_USER_MAX GENMASK(13, 6) #define R_SPOOF_ASYNC_RST 0x0D84 #define B_SPOOF_ASYNC_RST BIT(15) #define R_NDP_BRK0 0xDA0 @@ -3634,6 +3685,8 @@ #define B_PATH0_P20_FOLLOW_BY_PAGCUGC_EN_MSK BIT(5) #define R_PATH0_S20_FOLLOW_BY_PAGCUGC 0x46A4 #define B_PATH0_S20_FOLLOW_BY_PAGCUGC_EN_MSK BIT(5) +#define R_PATH0_G_LNA6_OP1DB_V1 0x4688 +#define B_PATH0_G_LNA6_OP1DB_V1 GENMASK(31, 24) #define R_PATH0_G_TIA0_LNA6_OP1DB_V1 0x4694 #define B_PATH0_G_TIA0_LNA6_OP1DB_V1 GENMASK(7, 0) #define R_PATH0_G_TIA1_LNA6_OP1DB_V1 0x4694 @@ -3650,6 +3703,9 @@ #define R_P0_NBIIDX 0x469C #define B_P0_NBIIDX_VAL GENMASK(11, 0) #define B_P0_NBIIDX_NOTCH_EN BIT(12) +#define R_P0_BACKOFF_IBADC_V1 0x469C +#define B_P0_BACKOFF_IBADC_V1 GENMASK(31, 26) +#define B_P0_NBIIDX_NOTCH_EN_V1 BIT(12) #define R_P1_MODE 0x4718 #define B_P1_MODE_SEL GENMASK(31, 30) #define R_PATH1_LNA_INIT 0x473C @@ -3668,6 +3724,8 @@ #define B_PATH1_S20_FOLLOW_BY_PAGCUGC_EN_MSK BIT(5) #define R_PATH1_G_TIA0_LNA6_OP1DB_V1 0x4778 #define B_PATH1_G_TIA0_LNA6_OP1DB_V1 GENMASK(7, 0) +#define R_PATH1_G_TIA1_LNA6_OP1DB_V1 0x4778 +#define B_PATH1_G_TIA1_LNA6_OP1DB_V1 GENMASK(15, 8) #define R_PATH1_BAND_SEL_V1 0x4AA4 #define B_PATH1_BAND_SEL_MSK_V1 BIT(17) #define R_PATH1_BT_SHARE_V1 0x4AA4 @@ -3693,15 +3751,29 @@ #define B_CHBW_MOD_SBW GENMASK(13, 12) #define B_CHBW_MOD_PRICH GENMASK(11, 8) #define B_ANT_RX_SEG0 GENMASK(3, 0) +#define R_P1_BACKOFF_IBADC_V1 0x49F0 +#define B_P1_BACKOFF_IBADC_V1 GENMASK(31, 26) #define R_BK_FC0_INV_V1 0x4A1C #define B_BK_FC0_INV_MSK_V1 GENMASK(18, 0) #define R_CCK_FC0_INV_V1 0x4A20 #define B_CCK_FC0_INV_MSK_V1 GENMASK(18, 0) +#define R_PATH0_RXBB_V1 0x4AD4 +#define B_PATH0_RXBB_MSK_V1 GENMASK(31, 0) +#define R_PATH1_RXBB_V1 0x4AE0 +#define B_PATH1_RXBB_MSK_V1 GENMASK(31, 0) +#define R_PATH0_BT_BACKOFF_V1 0x4AE4 +#define B_PATH0_BT_BACKOFF_V1 GENMASK(23, 0) +#define R_PATH1_BT_BACKOFF_V1 0x4AEC +#define B_PATH1_BT_BACKOFF_V1 GENMASK(23, 0) +#define R_PATH0_FRC_FIR_TYPE_V1 0x4C00 +#define B_PATH0_FRC_FIR_TYPE_MSK_V1 GENMASK(1, 0) #define R_PATH0_5MDET 0x4C4C #define B_PATH0_5MDET_EN BIT(12) #define B_PATH0_5MDET_SB2 BIT(8) #define B_PATH0_5MDET_SB0 BIT(6) #define B_PATH0_5MDET_TH GENMASK(5, 0) +#define R_PATH1_FRC_FIR_TYPE_V1 0x4CC4 +#define B_PATH1_FRC_FIR_TYPE_MSK_V1 GENMASK(1, 0) #define R_PATH1_5MDET 0x4D10 #define B_PATH1_5MDET_EN BIT(12) #define B_PATH1_5MDET_SB2 BIT(8) diff --git a/drivers/net/wireless/realtek/rtw89/rtw8852a.c b/drivers/net/wireless/realtek/rtw89/rtw8852a.c index 5af618709dedd..81bd0c4fe21bc 100644 --- a/drivers/net/wireless/realtek/rtw89/rtw8852a.c +++ b/drivers/net/wireless/realtek/rtw89/rtw8852a.c @@ -2066,6 +2066,7 @@ static const struct rtw89_chip_ops rtw8852a_chip_ops = { .ctrl_btg = rtw8852a_ctrl_btg, .query_ppdu = rtw8852a_query_ppdu, .bb_ctrl_btc_preagc = rtw8852a_bb_ctrl_btc_preagc, + .cfg_txrx_path = NULL, .set_txpwr_ul_tb_offset = rtw8852a_set_txpwr_ul_tb_offset, .pwr_on_func = NULL, .pwr_off_func = NULL, diff --git a/drivers/net/wireless/realtek/rtw89/rtw8852c.c b/drivers/net/wireless/realtek/rtw89/rtw8852c.c index 3ee57df0a6396..290c453d8c23a 100644 --- a/drivers/net/wireless/realtek/rtw89/rtw8852c.c +++ b/drivers/net/wireless/realtek/rtw89/rtw8852c.c @@ -1813,6 +1813,199 @@ void rtw8852c_set_txpwr_ul_tb_offset(struct rtw89_dev *rtwdev, } } +static void rtw8852c_bb_cfg_rx_path(struct rtw89_dev *rtwdev, u8 rx_path) +{ + struct rtw89_hal *hal = &rtwdev->hal; + u32 rst_mask0 = B_P0_TXPW_RSTB_MANON | B_P0_TXPW_RSTB_TSSI; + u32 rst_mask1 = B_P1_TXPW_RSTB_MANON | B_P1_TXPW_RSTB_TSSI; + + if (rtwdev->dbcc_en) { + rtw89_phy_write32_mask(rtwdev, R_CHBW_MOD, B_ANT_RX_SEG0, 1); + rtw89_phy_write32_idx(rtwdev, R_CHBW_MOD, B_ANT_RX_SEG0, 2, + RTW89_PHY_1); + + rtw89_phy_write32_mask(rtwdev, R_FC0_BW, B_ANT_RX_1RCCA_SEG0, + 1); + rtw89_phy_write32_mask(rtwdev, R_FC0_BW, B_ANT_RX_1RCCA_SEG1, + 1); + rtw89_phy_write32_idx(rtwdev, R_FC0_BW, B_ANT_RX_1RCCA_SEG0, 2, + RTW89_PHY_1); + rtw89_phy_write32_idx(rtwdev, R_FC0_BW, B_ANT_RX_1RCCA_SEG1, 2, + RTW89_PHY_1); + + rtw89_phy_write32_mask(rtwdev, R_RXHT_MCS_LIMIT, + B_RXHT_MCS_LIMIT, 0); + rtw89_phy_write32_mask(rtwdev, R_RXVHT_MCS_LIMIT, + B_RXVHT_MCS_LIMIT, 0); + rtw89_phy_write32_mask(rtwdev, R_RXHE, B_RXHE_USER_MAX, 8); + rtw89_phy_write32_mask(rtwdev, R_RXHE, B_RXHE_MAX_NSS, 0); + rtw89_phy_write32_mask(rtwdev, R_RXHE, B_RXHETB_MAX_NSS, 0); + + rtw89_phy_write32_idx(rtwdev, R_RXHT_MCS_LIMIT, + B_RXHT_MCS_LIMIT, 0, RTW89_PHY_1); + rtw89_phy_write32_idx(rtwdev, R_RXVHT_MCS_LIMIT, + B_RXVHT_MCS_LIMIT, 0, RTW89_PHY_1); + rtw89_phy_write32_idx(rtwdev, R_RXHE, B_RXHE_USER_MAX, 1, + RTW89_PHY_1); + rtw89_phy_write32_idx(rtwdev, R_RXHE, B_RXHE_MAX_NSS, 0, + RTW89_PHY_1); + rtw89_phy_write32_idx(rtwdev, R_RXHE, B_RXHETB_MAX_NSS, 0, + RTW89_PHY_1); + rtw89_phy_write32_mask(rtwdev, R_P0_TXPW_RSTB, rst_mask0, 1); + rtw89_phy_write32_mask(rtwdev, R_P0_TXPW_RSTB, rst_mask0, 3); + rtw89_phy_write32_mask(rtwdev, R_P1_TXPW_RSTB, rst_mask1, 1); + rtw89_phy_write32_mask(rtwdev, R_P1_TXPW_RSTB, rst_mask1, 3); + } else { + if (rx_path == RF_PATH_A) { + rtw89_phy_write32_mask(rtwdev, R_CHBW_MOD, + B_ANT_RX_SEG0, 1); + rtw89_phy_write32_mask(rtwdev, R_FC0_BW, + B_ANT_RX_1RCCA_SEG0, 1); + rtw89_phy_write32_mask(rtwdev, R_FC0_BW, + B_ANT_RX_1RCCA_SEG1, 1); + rtw89_phy_write32_mask(rtwdev, R_RXHT_MCS_LIMIT, + B_RXHT_MCS_LIMIT, 0); + rtw89_phy_write32_mask(rtwdev, R_RXVHT_MCS_LIMIT, + B_RXVHT_MCS_LIMIT, 0); + rtw89_phy_write32_mask(rtwdev, R_RXHE, B_RXHE_MAX_NSS, + 0); + rtw89_phy_write32_mask(rtwdev, R_RXHE, B_RXHETB_MAX_NSS, + 0); + rtw89_phy_write32_mask(rtwdev, R_P0_TXPW_RSTB, + rst_mask0, 1); + rtw89_phy_write32_mask(rtwdev, R_P0_TXPW_RSTB, + rst_mask0, 3); + } else if (rx_path == RF_PATH_B) { + rtw89_phy_write32_mask(rtwdev, R_CHBW_MOD, + B_ANT_RX_SEG0, 2); + rtw89_phy_write32_mask(rtwdev, R_FC0_BW, + B_ANT_RX_1RCCA_SEG0, 2); + rtw89_phy_write32_mask(rtwdev, R_FC0_BW, + B_ANT_RX_1RCCA_SEG1, 2); + rtw89_phy_write32_mask(rtwdev, R_RXHT_MCS_LIMIT, + B_RXHT_MCS_LIMIT, 0); + rtw89_phy_write32_mask(rtwdev, R_RXVHT_MCS_LIMIT, + B_RXVHT_MCS_LIMIT, 0); + rtw89_phy_write32_mask(rtwdev, R_RXHE, B_RXHE_MAX_NSS, + 0); + rtw89_phy_write32_mask(rtwdev, R_RXHE, B_RXHETB_MAX_NSS, + 0); + rtw89_phy_write32_mask(rtwdev, R_P1_TXPW_RSTB, + rst_mask1, 1); + rtw89_phy_write32_mask(rtwdev, R_P1_TXPW_RSTB, + rst_mask1, 3); + } else { + rtw89_phy_write32_mask(rtwdev, R_CHBW_MOD, + B_ANT_RX_SEG0, 3); + rtw89_phy_write32_mask(rtwdev, R_FC0_BW, + B_ANT_RX_1RCCA_SEG0, 3); + rtw89_phy_write32_mask(rtwdev, R_FC0_BW, + B_ANT_RX_1RCCA_SEG1, 3); + rtw89_phy_write32_mask(rtwdev, R_RXHT_MCS_LIMIT, + B_RXHT_MCS_LIMIT, 1); + rtw89_phy_write32_mask(rtwdev, R_RXVHT_MCS_LIMIT, + B_RXVHT_MCS_LIMIT, 1); + rtw89_phy_write32_mask(rtwdev, R_RXHE, B_RXHE_MAX_NSS, + 1); + rtw89_phy_write32_mask(rtwdev, R_RXHE, B_RXHETB_MAX_NSS, + 1); + rtw8852c_ctrl_btg(rtwdev, hal->current_band_type == RTW89_BAND_2G); + rtw89_phy_write32_mask(rtwdev, R_P0_TXPW_RSTB, + rst_mask0, 1); + rtw89_phy_write32_mask(rtwdev, R_P0_TXPW_RSTB, + rst_mask0, 3); + rtw89_phy_write32_mask(rtwdev, R_P1_TXPW_RSTB, + rst_mask1, 1); + rtw89_phy_write32_mask(rtwdev, R_P1_TXPW_RSTB, + rst_mask1, 3); + } + rtw89_phy_write32_mask(rtwdev, R_RXHE, B_RXHE_USER_MAX, 8); + } +} + +static void rtw8852c_ctrl_tx_path_tmac(struct rtw89_dev *rtwdev, u8 tx_path, + enum rtw89_mac_idx mac_idx) +{ + struct rtw89_reg2_def path_com[] = { + {R_AX_PATH_COM0, AX_PATH_COM0_DFVAL}, + {R_AX_PATH_COM1, AX_PATH_COM1_DFVAL}, + {R_AX_PATH_COM2, AX_PATH_COM2_DFVAL}, + {R_AX_PATH_COM3, AX_PATH_COM3_DFVAL}, + {R_AX_PATH_COM4, AX_PATH_COM4_DFVAL}, + {R_AX_PATH_COM5, AX_PATH_COM5_DFVAL}, + {R_AX_PATH_COM6, AX_PATH_COM6_DFVAL}, + {R_AX_PATH_COM7, AX_PATH_COM7_DFVAL}, + {R_AX_PATH_COM8, AX_PATH_COM8_DFVAL}, + {R_AX_PATH_COM9, AX_PATH_COM9_DFVAL}, + {R_AX_PATH_COM10, AX_PATH_COM10_DFVAL}, + {R_AX_PATH_COM11, AX_PATH_COM11_DFVAL}, + }; + u32 addr; + u32 reg; + u8 cr_size = ARRAY_SIZE(path_com); + u8 i = 0; + + rtw89_phy_write32_idx(rtwdev, R_MAC_SEL, B_MAC_SEL_MOD, 0, RTW89_PHY_0); + rtw89_phy_write32_idx(rtwdev, R_MAC_SEL, B_MAC_SEL_MOD, 0, RTW89_PHY_1); + + for (addr = R_AX_MACID_ANT_TABLE; + addr <= R_AX_MACID_ANT_TABLE_LAST; addr += 4) { + reg = rtw89_mac_reg_by_idx(addr, mac_idx); + rtw89_write32(rtwdev, reg, 0); + } + + if (tx_path == RF_PATH_A) { + path_com[0].data = AX_PATH_COM0_PATHA; + path_com[1].data = AX_PATH_COM1_PATHA; + path_com[2].data = AX_PATH_COM2_PATHA; + path_com[7].data = AX_PATH_COM7_PATHA; + path_com[8].data = AX_PATH_COM8_PATHA; + } else if (tx_path == RF_PATH_B) { + path_com[0].data = AX_PATH_COM0_PATHB; + path_com[1].data = AX_PATH_COM1_PATHB; + path_com[2].data = AX_PATH_COM2_PATHB; + path_com[7].data = AX_PATH_COM7_PATHB; + path_com[8].data = AX_PATH_COM8_PATHB; + } else if (tx_path == RF_PATH_AB) { + path_com[0].data = AX_PATH_COM0_PATHAB; + path_com[1].data = AX_PATH_COM1_PATHAB; + path_com[2].data = AX_PATH_COM2_PATHAB; + path_com[7].data = AX_PATH_COM7_PATHAB; + path_com[8].data = AX_PATH_COM8_PATHAB; + } else { + rtw89_warn(rtwdev, "[Invalid Tx Path]Tx Path: %d\n", tx_path); + return; + } + + for (i = 0; i < cr_size; i++) { + rtw89_debug(rtwdev, RTW89_DBG_TSSI, "0x%x = 0x%x\n", + path_com[i].addr, path_com[i].data); + reg = rtw89_mac_reg_by_idx(path_com[i].addr, mac_idx); + rtw89_write32(rtwdev, reg, path_com[i].data); + } +} + +static void rtw8852c_bb_cfg_txrx_path(struct rtw89_dev *rtwdev) +{ + struct rtw89_hal *hal = &rtwdev->hal; + + rtw8852c_bb_cfg_rx_path(rtwdev, RF_PATH_AB); + + if (hal->rx_nss == 1) { + rtw89_phy_write32_mask(rtwdev, R_RXHT_MCS_LIMIT, B_RXHT_MCS_LIMIT, 0); + rtw89_phy_write32_mask(rtwdev, R_RXVHT_MCS_LIMIT, B_RXVHT_MCS_LIMIT, 0); + rtw89_phy_write32_mask(rtwdev, R_RXHE, B_RXHE_MAX_NSS, 0); + rtw89_phy_write32_mask(rtwdev, R_RXHE, B_RXHETB_MAX_NSS, 0); + } else { + rtw89_phy_write32_mask(rtwdev, R_RXHT_MCS_LIMIT, B_RXHT_MCS_LIMIT, 1); + rtw89_phy_write32_mask(rtwdev, R_RXVHT_MCS_LIMIT, B_RXVHT_MCS_LIMIT, 1); + rtw89_phy_write32_mask(rtwdev, R_RXHE, B_RXHE_MAX_NSS, 1); + rtw89_phy_write32_mask(rtwdev, R_RXHE, B_RXHETB_MAX_NSS, 1); + } + + rtw8852c_ctrl_tx_path_tmac(rtwdev, RF_PATH_AB, RTW89_MAC_0); +} + static void rtw8852c_ctrl_btg(struct rtw89_dev *rtwdev, bool btg) { if (btg) { @@ -1973,6 +2166,7 @@ static const struct rtw89_chip_ops rtw8852c_chip_ops = { .read_rf = rtw89_phy_read_rf_v1, .write_rf = rtw89_phy_write_rf_v1, .set_txpwr_ul_tb_offset = rtw8852c_set_txpwr_ul_tb_offset, + .cfg_txrx_path = rtw8852c_bb_cfg_txrx_path, .pwr_on_func = rtw8852c_pwr_on_func, .pwr_off_func = rtw8852c_pwr_off_func, .fill_txdesc = rtw89_core_fill_txdesc_v1, From af0cac159b1c96633436b71a4a790d77a1d75858 Mon Sep 17 00:00:00 2001 From: Ping-Ke Shih Date: Thu, 21 Apr 2022 20:09:00 +0800 Subject: [PATCH 179/228] rtw89: 8852c: implement chip_ops related to TX power Three chip_ops are implemented in this patch. The ::set_txpwr_ctrl and ::init_txpwr_unit are called when we up interface and then configure TX power registers to initial values. The ::set_txpwr_ctrl is to configure 'txpwr_ref' to make basic output TX power of OFDM and CCK rate to be the same. The ::init_txpwr_unit is to initialize TSSI (a method to do TX power compensation depends on thermal value) control and bandedge. The ::set_txpwr is called once switching channel. First, it sets TX power for each rate section (e.g. CCK, OFDM), and then sets TX power offset between 1SS and 2SS rate. Finally, it sets TX power limit to prevent power over regulation. Signed-off-by: Ping-Ke Shih Signed-off-by: Kalle Valo Link: https://lore.kernel.org/r/20220421120903.73715-12-pkshih@realtek.com --- drivers/net/wireless/realtek/rtw89/rtw8852c.c | 324 ++++++++++++++++++ drivers/net/wireless/realtek/rtw89/rtw8852c.h | 1 + 2 files changed, 325 insertions(+) diff --git a/drivers/net/wireless/realtek/rtw89/rtw8852c.c b/drivers/net/wireless/realtek/rtw89/rtw8852c.c index 290c453d8c23a..adcc2b597419d 100644 --- a/drivers/net/wireless/realtek/rtw89/rtw8852c.c +++ b/drivers/net/wireless/realtek/rtw89/rtw8852c.c @@ -1778,6 +1778,32 @@ static void rtw8852c_rfk_channel(struct rtw89_dev *rtwdev) rtw89_fw_h2c_rf_ntfy_mcc(rtwdev); } +static u32 rtw8852c_bb_cal_txpwr_ref(struct rtw89_dev *rtwdev, + enum rtw89_phy_idx phy_idx, s16 ref) +{ + s8 ofst_int = 0; + u8 base_cw_0db = 0x27; + u16 tssi_16dbm_cw = 0x12c; + s16 pwr_s10_3 = 0; + s16 rf_pwr_cw = 0; + u16 bb_pwr_cw = 0; + u32 pwr_cw = 0; + u32 tssi_ofst_cw = 0; + + pwr_s10_3 = (ref << 1) + (s16)(ofst_int) + (s16)(base_cw_0db << 3); + bb_pwr_cw = FIELD_GET(GENMASK(2, 0), pwr_s10_3); + rf_pwr_cw = FIELD_GET(GENMASK(8, 3), pwr_s10_3); + rf_pwr_cw = clamp_t(s16, rf_pwr_cw, 15, 63); + pwr_cw = (rf_pwr_cw << 3) | bb_pwr_cw; + + tssi_ofst_cw = (u32)((s16)tssi_16dbm_cw + (ref << 1) - (16 << 3)); + rtw89_debug(rtwdev, RTW89_DBG_TXPWR, + "[TXPWR] tssi_ofst_cw=%d rf_cw=0x%x bb_cw=0x%x\n", + tssi_ofst_cw, rf_pwr_cw, bb_pwr_cw); + + return (tssi_ofst_cw << 18) | (pwr_cw << 9) | (ref & GENMASK(8, 0)); +} + static void rtw8852c_set_txpwr_ul_tb_offset(struct rtw89_dev *rtwdev, s8 pw_ofst, enum rtw89_mac_idx mac_idx) @@ -1813,6 +1839,301 @@ void rtw8852c_set_txpwr_ul_tb_offset(struct rtw89_dev *rtwdev, } } +static void rtw8852c_set_txpwr_ref(struct rtw89_dev *rtwdev, + enum rtw89_phy_idx phy_idx) +{ + static const u32 addr[RF_PATH_NUM_8852C] = {0x5800, 0x7800}; + const u32 mask = 0x7FFFFFF; + const u8 ofst_ofdm = 0x4; + const u8 ofst_cck = 0x8; + s16 ref_ofdm = 0; + s16 ref_cck = 0; + u32 val; + u8 i; + + rtw89_debug(rtwdev, RTW89_DBG_TXPWR, "[TXPWR] set txpwr reference\n"); + + rtw89_mac_txpwr_write32_mask(rtwdev, phy_idx, R_AX_PWR_RATE_CTRL, + GENMASK(27, 10), 0x0); + + rtw89_debug(rtwdev, RTW89_DBG_TXPWR, "[TXPWR] set bb ofdm txpwr ref\n"); + val = rtw8852c_bb_cal_txpwr_ref(rtwdev, phy_idx, ref_ofdm); + + for (i = 0; i < RF_PATH_NUM_8852C; i++) + rtw89_phy_write32_idx(rtwdev, addr[i] + ofst_ofdm, mask, val, + phy_idx); + + rtw89_debug(rtwdev, RTW89_DBG_TXPWR, "[TXPWR] set bb cck txpwr ref\n"); + val = rtw8852c_bb_cal_txpwr_ref(rtwdev, phy_idx, ref_cck); + + for (i = 0; i < RF_PATH_NUM_8852C; i++) + rtw89_phy_write32_idx(rtwdev, addr[i] + ofst_cck, mask, val, + phy_idx); +} + +static void rtw8852c_set_txpwr_byrate(struct rtw89_dev *rtwdev, + enum rtw89_phy_idx phy_idx) +{ + u8 ch = rtwdev->hal.current_channel; + static const u8 rs[] = { + RTW89_RS_CCK, + RTW89_RS_OFDM, + RTW89_RS_MCS, + RTW89_RS_HEDCM, + }; + s8 tmp; + u8 i, j; + u32 val, shf, addr = R_AX_PWR_BY_RATE; + struct rtw89_rate_desc cur; + + rtw89_debug(rtwdev, RTW89_DBG_TXPWR, + "[TXPWR] set txpwr byrate with ch=%d\n", ch); + + for (cur.nss = 0; cur.nss <= RTW89_NSS_2; cur.nss++) { + for (i = 0; i < ARRAY_SIZE(rs); i++) { + if (cur.nss >= rtw89_rs_nss_max[rs[i]]) + continue; + + val = 0; + cur.rs = rs[i]; + + for (j = 0; j < rtw89_rs_idx_max[rs[i]]; j++) { + cur.idx = j; + shf = (j % 4) * 8; + tmp = rtw89_phy_read_txpwr_byrate(rtwdev, &cur); + val |= (tmp << shf); + + if ((j + 1) % 4) + continue; + + rtw89_mac_txpwr_write32(rtwdev, phy_idx, addr, val); + val = 0; + addr += 4; + } + } + } +} + +static void rtw8852c_set_txpwr_offset(struct rtw89_dev *rtwdev, + enum rtw89_phy_idx phy_idx) +{ + struct rtw89_rate_desc desc = { + .nss = RTW89_NSS_1, + .rs = RTW89_RS_OFFSET, + }; + u32 val = 0; + s8 v; + + rtw89_debug(rtwdev, RTW89_DBG_TXPWR, "[TXPWR] set txpwr offset\n"); + + for (desc.idx = 0; desc.idx < RTW89_RATE_OFFSET_MAX; desc.idx++) { + v = rtw89_phy_read_txpwr_byrate(rtwdev, &desc); + val |= ((v & 0xf) << (4 * desc.idx)); + } + + rtw89_mac_txpwr_write32_mask(rtwdev, phy_idx, R_AX_PWR_RATE_OFST_CTRL, + GENMASK(19, 0), val); +} + +static void rtw8852c_bb_set_tx_shape_dfir(struct rtw89_dev *rtwdev, + u8 tx_shape_idx, + enum rtw89_phy_idx phy_idx) +{ +#define __DFIR_CFG_MASK 0xffffff +#define __DFIR_CFG_NR 8 +#define __DECL_DFIR_VAR(_prefix, _name, _val...) \ + static const u32 _prefix ## _ ## _name[] = {_val}; \ + static_assert(ARRAY_SIZE(_prefix ## _ ## _name) == __DFIR_CFG_NR) +#define __DECL_DFIR_PARAM(_name, _val...) __DECL_DFIR_VAR(param, _name, _val) +#define __DECL_DFIR_ADDR(_name, _val...) __DECL_DFIR_VAR(addr, _name, _val) + + __DECL_DFIR_PARAM(flat, + 0x003D23FF, 0x0029B354, 0x000FC1C8, 0x00FDB053, + 0x00F86F9A, 0x00FAEF92, 0x00FE5FCC, 0x00FFDFF5); + __DECL_DFIR_PARAM(sharp, + 0x003D83FF, 0x002C636A, 0x0013F204, 0x00008090, + 0x00F87FB0, 0x00F99F83, 0x00FDBFBA, 0x00003FF5); + __DECL_DFIR_PARAM(sharp_14, + 0x003B13FF, 0x001C42DE, 0x00FDB0AD, 0x00F60F6E, + 0x00FD8F92, 0x0002D011, 0x0001C02C, 0x00FFF00A); + __DECL_DFIR_ADDR(filter, + 0x45BC, 0x45CC, 0x45D0, 0x45D4, 0x45D8, 0x45C0, + 0x45C4, 0x45C8); + u8 ch = rtwdev->hal.current_channel; + const u32 *param; + int i; + + if (ch > 14) { + rtw89_warn(rtwdev, + "set tx shape dfir by unknown ch: %d on 2G\n", ch); + return; + } + + if (ch == 14) + param = param_sharp_14; + else + param = tx_shape_idx == 0 ? param_flat : param_sharp; + + for (i = 0; i < __DFIR_CFG_NR; i++) { + rtw89_debug(rtwdev, RTW89_DBG_TXPWR, + "set tx shape dfir: 0x%x: 0x%x\n", addr_filter[i], + param[i]); + rtw89_phy_write32_idx(rtwdev, addr_filter[i], __DFIR_CFG_MASK, + param[i], phy_idx); + } + +#undef __DECL_DFIR_ADDR +#undef __DECL_DFIR_PARAM +#undef __DECL_DFIR_VAR +#undef __DFIR_CFG_NR +#undef __DFIR_CFG_MASK +} + +static void rtw8852c_set_tx_shape(struct rtw89_dev *rtwdev, + enum rtw89_phy_idx phy_idx) +{ + u8 band = rtwdev->hal.current_band_type; + u8 regd = rtw89_regd_get(rtwdev, band); + u8 tx_shape_cck = rtw89_8852c_tx_shape[band][RTW89_RS_CCK][regd]; + u8 tx_shape_ofdm = rtw89_8852c_tx_shape[band][RTW89_RS_OFDM][regd]; + + if (band == RTW89_BAND_2G) + rtw8852c_bb_set_tx_shape_dfir(rtwdev, tx_shape_cck, phy_idx); + + rtw89_phy_tssi_ctrl_set_bandedge_cfg(rtwdev, + (enum rtw89_mac_idx)phy_idx, + tx_shape_ofdm); +} + +static void rtw8852c_set_txpwr_limit(struct rtw89_dev *rtwdev, + enum rtw89_phy_idx phy_idx) +{ +#define __MAC_TXPWR_LMT_PAGE_SIZE 40 + u8 ch = rtwdev->hal.current_channel; + u8 bw = rtwdev->hal.current_band_width; + struct rtw89_txpwr_limit lmt[NTX_NUM_8852C]; + u32 addr, val; + const s8 *ptr; + u8 i, j, k; + + rtw89_debug(rtwdev, RTW89_DBG_TXPWR, + "[TXPWR] set txpwr limit with ch=%d bw=%d\n", ch, bw); + + for (i = 0; i < NTX_NUM_8852C; i++) { + rtw89_phy_fill_txpwr_limit(rtwdev, &lmt[i], i); + + for (j = 0; j < __MAC_TXPWR_LMT_PAGE_SIZE; j += 4) { + addr = R_AX_PWR_LMT + j + __MAC_TXPWR_LMT_PAGE_SIZE * i; + ptr = (s8 *)&lmt[i] + j; + val = 0; + + for (k = 0; k < 4; k++) + val |= (ptr[k] << (8 * k)); + + rtw89_mac_txpwr_write32(rtwdev, phy_idx, addr, val); + } + } +#undef __MAC_TXPWR_LMT_PAGE_SIZE +} + +static void rtw8852c_set_txpwr_limit_ru(struct rtw89_dev *rtwdev, + enum rtw89_phy_idx phy_idx) +{ +#define __MAC_TXPWR_LMT_RU_PAGE_SIZE 24 + u8 ch = rtwdev->hal.current_channel; + u8 bw = rtwdev->hal.current_band_width; + struct rtw89_txpwr_limit_ru lmt_ru[NTX_NUM_8852C]; + u32 addr, val; + const s8 *ptr; + u8 i, j, k; + + rtw89_debug(rtwdev, RTW89_DBG_TXPWR, + "[TXPWR] set txpwr limit ru with ch=%d bw=%d\n", ch, bw); + + for (i = 0; i < NTX_NUM_8852C; i++) { + rtw89_phy_fill_txpwr_limit_ru(rtwdev, &lmt_ru[i], i); + + for (j = 0; j < __MAC_TXPWR_LMT_RU_PAGE_SIZE; j += 4) { + addr = R_AX_PWR_RU_LMT + j + + __MAC_TXPWR_LMT_RU_PAGE_SIZE * i; + ptr = (s8 *)&lmt_ru[i] + j; + val = 0; + + for (k = 0; k < 4; k++) + val |= (ptr[k] << (8 * k)); + + rtw89_mac_txpwr_write32(rtwdev, phy_idx, addr, val); + } + } + +#undef __MAC_TXPWR_LMT_RU_PAGE_SIZE +} + +static void rtw8852c_set_txpwr(struct rtw89_dev *rtwdev) +{ + rtw8852c_set_txpwr_byrate(rtwdev, RTW89_PHY_0); + rtw8852c_set_txpwr_offset(rtwdev, RTW89_PHY_0); + rtw8852c_set_tx_shape(rtwdev, RTW89_PHY_0); + rtw8852c_set_txpwr_limit(rtwdev, RTW89_PHY_0); + rtw8852c_set_txpwr_limit_ru(rtwdev, RTW89_PHY_0); +} + +static void rtw8852c_set_txpwr_ctrl(struct rtw89_dev *rtwdev) +{ + rtw8852c_set_txpwr_ref(rtwdev, RTW89_PHY_0); +} + +static void +rtw8852c_init_tssi_ctrl(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy_idx) +{ + static const struct rtw89_reg2_def ctrl_ini[] = { + {0xD938, 0x00010100}, + {0xD93C, 0x0500D500}, + {0xD940, 0x00000500}, + {0xD944, 0x00000005}, + {0xD94C, 0x00220000}, + {0xD950, 0x00030000}, + }; + u32 addr; + int i; + + for (addr = R_AX_TSSI_CTRL_HEAD; addr <= R_AX_TSSI_CTRL_TAIL; addr += 4) + rtw89_mac_txpwr_write32(rtwdev, phy_idx, addr, 0); + + for (i = 0; i < ARRAY_SIZE(ctrl_ini); i++) + rtw89_mac_txpwr_write32(rtwdev, phy_idx, ctrl_ini[i].addr, + ctrl_ini[i].data); + + rtw89_phy_tssi_ctrl_set_bandedge_cfg(rtwdev, + (enum rtw89_mac_idx)phy_idx, + RTW89_TSSI_BANDEDGE_FLAT); +} + +static int +rtw8852c_init_txpwr_unit(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy_idx) +{ + int ret; + + ret = rtw89_mac_txpwr_write32(rtwdev, phy_idx, R_AX_PWR_UL_CTRL2, 0x07763333); + if (ret) + return ret; + + ret = rtw89_mac_txpwr_write32(rtwdev, phy_idx, R_AX_PWR_COEXT_CTRL, 0x01ebf000); + if (ret) + return ret; + + ret = rtw89_mac_txpwr_write32(rtwdev, phy_idx, R_AX_PWR_UL_CTRL0, 0x0002f8ff); + if (ret) + return ret; + + rtw8852c_set_txpwr_ul_tb_offset(rtwdev, 0, phy_idx == RTW89_PHY_1 ? + RTW89_MAC_1 : + RTW89_MAC_0); + rtw8852c_init_tssi_ctrl(rtwdev, phy_idx); + + return 0; +} + static void rtw8852c_bb_cfg_rx_path(struct rtw89_dev *rtwdev, u8 rx_path) { struct rtw89_hal *hal = &rtwdev->hal; @@ -2163,6 +2484,9 @@ static const struct rtw89_chip_ops rtw8852c_chip_ops = { .rfk_init = rtw8852c_rfk_init, .rfk_channel = rtw8852c_rfk_channel, .power_trim = rtw8852c_power_trim, + .set_txpwr = rtw8852c_set_txpwr, + .set_txpwr_ctrl = rtw8852c_set_txpwr_ctrl, + .init_txpwr_unit = rtw8852c_init_txpwr_unit, .read_rf = rtw89_phy_read_rf_v1, .write_rf = rtw89_phy_write_rf_v1, .set_txpwr_ul_tb_offset = rtw8852c_set_txpwr_ul_tb_offset, diff --git a/drivers/net/wireless/realtek/rtw89/rtw8852c.h b/drivers/net/wireless/realtek/rtw89/rtw8852c.h index ac642808a81ff..558dd0f048f2b 100644 --- a/drivers/net/wireless/realtek/rtw89/rtw8852c.h +++ b/drivers/net/wireless/realtek/rtw89/rtw8852c.h @@ -9,6 +9,7 @@ #define RF_PATH_NUM_8852C 2 #define BB_PATH_NUM_8852C 2 +#define NTX_NUM_8852C 2 struct rtw8852c_u_efuse { u8 rsvd[0x38]; From 3ecca403d9bf714be570ca2a31569485618c9da0 Mon Sep 17 00:00:00 2001 From: Ping-Ke Shih Date: Thu, 21 Apr 2022 20:09:01 +0800 Subject: [PATCH 180/228] rtw89: 8852c: implement chip_ops::get_thermal Read thermal value, and then we can use EWMA thermal value to do RF calibrations if the value is changed over a threshold. Signed-off-by: Ping-Ke Shih Signed-off-by: Kalle Valo Link: https://lore.kernel.org/r/20220421120903.73715-13-pkshih@realtek.com --- drivers/net/wireless/realtek/rtw89/rtw8852c.c | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/drivers/net/wireless/realtek/rtw89/rtw8852c.c b/drivers/net/wireless/realtek/rtw89/rtw8852c.c index adcc2b597419d..daf467eaef665 100644 --- a/drivers/net/wireless/realtek/rtw89/rtw8852c.c +++ b/drivers/net/wireless/realtek/rtw89/rtw8852c.c @@ -2327,6 +2327,17 @@ static void rtw8852c_bb_cfg_txrx_path(struct rtw89_dev *rtwdev) rtw8852c_ctrl_tx_path_tmac(rtwdev, RF_PATH_AB, RTW89_MAC_0); } +static u8 rtw8852c_get_thermal(struct rtw89_dev *rtwdev, enum rtw89_rf_path rf_path) +{ + rtw89_write_rf(rtwdev, rf_path, RR_TM, RR_TM_TRI, 0x1); + rtw89_write_rf(rtwdev, rf_path, RR_TM, RR_TM_TRI, 0x0); + rtw89_write_rf(rtwdev, rf_path, RR_TM, RR_TM_TRI, 0x1); + + fsleep(200); + + return rtw89_read_rf(rtwdev, rf_path, RR_TM, RR_TM_VAL); +} + static void rtw8852c_ctrl_btg(struct rtw89_dev *rtwdev, bool btg) { if (btg) { @@ -2487,6 +2498,7 @@ static const struct rtw89_chip_ops rtw8852c_chip_ops = { .set_txpwr = rtw8852c_set_txpwr, .set_txpwr_ctrl = rtw8852c_set_txpwr_ctrl, .init_txpwr_unit = rtw8852c_init_txpwr_unit, + .get_thermal = rtw8852c_get_thermal, .read_rf = rtw89_phy_read_rf_v1, .write_rf = rtw89_phy_write_rf_v1, .set_txpwr_ul_tb_offset = rtw8852c_set_txpwr_ul_tb_offset, From f4ae7ccc2bbfa597db09ed5000a1efa4feb0d962 Mon Sep 17 00:00:00 2001 From: Ping-Ke Shih Date: Thu, 21 Apr 2022 20:09:02 +0800 Subject: [PATCH 181/228] rtw89: 8852c: fill freq and band of RX status by PPDU report Hardware reports PPDU status containing encoded channel index to driver, so we decode it and then fill freq and band. Signed-off-by: Ping-Ke Shih Signed-off-by: Kalle Valo Link: https://lore.kernel.org/r/20220421120903.73715-14-pkshih@realtek.com --- drivers/net/wireless/realtek/rtw89/rtw8852c.c | 33 +++++++++++++++++++ 1 file changed, 33 insertions(+) diff --git a/drivers/net/wireless/realtek/rtw89/rtw8852c.c b/drivers/net/wireless/realtek/rtw89/rtw8852c.c index daf467eaef665..f66e4e091e439 100644 --- a/drivers/net/wireless/realtek/rtw89/rtw8852c.c +++ b/drivers/net/wireless/realtek/rtw89/rtw8852c.c @@ -2440,6 +2440,38 @@ static void rtw8852c_btc_init_cfg(struct rtw89_dev *rtwdev) btc->cx.wl.status.map.init_ok = true; } +static void rtw8852c_fill_freq_with_ppdu(struct rtw89_dev *rtwdev, + struct rtw89_rx_phy_ppdu *phy_ppdu, + struct ieee80211_rx_status *status) +{ + u8 chan_idx = phy_ppdu->chan_idx; + enum nl80211_band band; + u8 ch; + + if (chan_idx == 0) + return; + + rtw8852c_decode_chan_idx(rtwdev, chan_idx, &ch, &band); + status->freq = ieee80211_channel_to_frequency(ch, band); + status->band = band; +} + +static void rtw8852c_query_ppdu(struct rtw89_dev *rtwdev, + struct rtw89_rx_phy_ppdu *phy_ppdu, + struct ieee80211_rx_status *status) +{ + u8 path; + s8 *rx_power = phy_ppdu->rssi; + + status->signal = max_t(s8, rx_power[RF_PATH_A], rx_power[RF_PATH_B]); + for (path = 0; path < rtwdev->chip->rf_path_num; path++) { + status->chains |= BIT(path); + status->chain_signal[path] = rx_power[path]; + } + if (phy_ppdu->valid) + rtw8852c_fill_freq_with_ppdu(rtwdev, phy_ppdu, status); +} + static int rtw8852c_mac_enable_bb_rf(struct rtw89_dev *rtwdev) { int ret; @@ -2499,6 +2531,7 @@ static const struct rtw89_chip_ops rtw8852c_chip_ops = { .set_txpwr_ctrl = rtw8852c_set_txpwr_ctrl, .init_txpwr_unit = rtw8852c_init_txpwr_unit, .get_thermal = rtw8852c_get_thermal, + .query_ppdu = rtw8852c_query_ppdu, .read_rf = rtw89_phy_read_rf_v1, .write_rf = rtw89_phy_write_rf_v1, .set_txpwr_ul_tb_offset = rtw8852c_set_txpwr_ul_tb_offset, From 2fb822f82a59db899ba7b3a615cb0ddbc8c04f0f Mon Sep 17 00:00:00 2001 From: Ping-Ke Shih Date: Thu, 21 Apr 2022 20:09:03 +0800 Subject: [PATCH 182/228] rtw89: 8852c: add chip_ops related to BTC Add some chip_ops to support BT coexistence to work properly. Signed-off-by: Ping-Ke Shih Signed-off-by: Kalle Valo Link: https://lore.kernel.org/r/20220421120903.73715-15-pkshih@realtek.com --- drivers/net/wireless/realtek/rtw89/reg.h | 7 + drivers/net/wireless/realtek/rtw89/rtw8852c.c | 187 ++++++++++++++++++ 2 files changed, 194 insertions(+) diff --git a/drivers/net/wireless/realtek/rtw89/reg.h b/drivers/net/wireless/realtek/rtw89/reg.h index 6dc11e8e2a839..83cb509d2fbe9 100644 --- a/drivers/net/wireless/realtek/rtw89/reg.h +++ b/drivers/net/wireless/realtek/rtw89/reg.h @@ -3048,11 +3048,18 @@ #define B_AX_BT_CNT_RST_V1 BIT(1) #define B_AX_BT_CNT_EN BIT(0) +#define R_BTC_BT_CNT_HIGH 0xDA14 +#define R_BTC_BT_CNT_LOW 0xDA18 + #define R_AX_BTC_FUNC_EN 0xDA20 #define R_AX_BTC_FUNC_EN_C1 0xFA20 #define B_AX_PTA_WL_TX_EN BIT(1) #define B_AX_PTA_EDCCA_EN BIT(0) +#define R_BTC_COEX_WL_REQ 0xDA24 +#define B_BTC_TX_BCN_HI BIT(22) +#define B_BTC_RSP_ACK_HI BIT(10) + #define R_BTC_BREAK_TABLE 0xDA2C #define BTC_BREAK_PARAM 0xf0ffffff diff --git a/drivers/net/wireless/realtek/rtw89/rtw8852c.c b/drivers/net/wireless/realtek/rtw89/rtw8852c.c index f66e4e091e439..858611c64e6bf 100644 --- a/drivers/net/wireless/realtek/rtw89/rtw8852c.c +++ b/drivers/net/wireless/realtek/rtw89/rtw8852c.c @@ -2338,6 +2338,33 @@ static u8 rtw8852c_get_thermal(struct rtw89_dev *rtwdev, enum rtw89_rf_path rf_p return rtw89_read_rf(rtwdev, rf_path, RR_TM, RR_TM_VAL); } +static void rtw8852c_btc_set_rfe(struct rtw89_dev *rtwdev) +{ + struct rtw89_btc *btc = &rtwdev->btc; + struct rtw89_btc_module *module = &btc->mdinfo; + + module->rfe_type = rtwdev->efuse.rfe_type; + module->cv = rtwdev->hal.cv; + module->bt_solo = 0; + module->switch_type = BTC_SWITCH_INTERNAL; + + if (module->rfe_type > 0) + module->ant.num = (module->rfe_type % 2 ? 2 : 3); + else + module->ant.num = 2; + + module->ant.diversity = 0; + module->ant.isolation = 10; + + if (module->ant.num == 3) { + module->ant.type = BTC_ANT_DEDICATED; + module->bt_pos = BTC_BT_ALONE; + } else { + module->ant.type = BTC_ANT_SHARED; + module->bt_pos = BTC_BT_BTG; + } +} + static void rtw8852c_ctrl_btg(struct rtw89_dev *rtwdev, bool btg) { if (btg) { @@ -2440,6 +2467,159 @@ static void rtw8852c_btc_init_cfg(struct rtw89_dev *rtwdev) btc->cx.wl.status.map.init_ok = true; } +static +void rtw8852c_btc_set_wl_pri(struct rtw89_dev *rtwdev, u8 map, bool state) +{ + u32 bitmap = 0; + u32 reg = 0; + + switch (map) { + case BTC_PRI_MASK_TX_RESP: + reg = R_BTC_COEX_WL_REQ; + bitmap = B_BTC_RSP_ACK_HI; + break; + case BTC_PRI_MASK_BEACON: + reg = R_BTC_COEX_WL_REQ; + bitmap = B_BTC_TX_BCN_HI; + break; + default: + return; + } + + if (state) + rtw89_write32_set(rtwdev, reg, bitmap); + else + rtw89_write32_clr(rtwdev, reg, bitmap); +} + +union rtw8852c_btc_wl_txpwr_ctrl { + u32 txpwr_val; + struct { + union { + u16 ctrl_all_time; + struct { + s16 data:9; + u16 rsvd:6; + u16 flag:1; + } all_time; + }; + union { + u16 ctrl_gnt_bt; + struct { + s16 data:9; + u16 rsvd:7; + } gnt_bt; + }; + }; +} __packed; + +static void +rtw8852c_btc_set_wl_txpwr_ctrl(struct rtw89_dev *rtwdev, u32 txpwr_val) +{ + union rtw8852c_btc_wl_txpwr_ctrl arg = { .txpwr_val = txpwr_val }; + s32 val; + +#define __write_ctrl(_reg, _msk, _val, _en, _cond) \ +do { \ + const typeof(_msk) __msk = _msk; \ + const typeof(_en) __en = _en; \ + u32 _wrt = FIELD_PREP(__msk, _val); \ + BUILD_BUG_ON((__msk & __en) != 0); \ + if (_cond) \ + _wrt |= __en; \ + else \ + _wrt &= ~__en; \ + rtw89_mac_txpwr_write32_mask(rtwdev, RTW89_PHY_0, _reg, \ + __msk | __en, _wrt); \ +} while (0) + + switch (arg.ctrl_all_time) { + case 0xffff: + val = 0; + break; + default: + val = arg.all_time.data; + break; + } + + __write_ctrl(R_AX_PWR_RATE_CTRL, B_AX_FORCE_PWR_BY_RATE_VALUE_MASK, + val, B_AX_FORCE_PWR_BY_RATE_EN, + arg.ctrl_all_time != 0xffff); + + switch (arg.ctrl_gnt_bt) { + case 0xffff: + val = 0; + break; + default: + val = arg.gnt_bt.data; + break; + }; + + __write_ctrl(R_AX_PWR_COEXT_CTRL, B_AX_TXAGC_BT_MASK, val, + B_AX_TXAGC_BT_EN, arg.ctrl_gnt_bt != 0xffff); + +#undef __write_ctrl +} + +static +s8 rtw8852c_btc_get_bt_rssi(struct rtw89_dev *rtwdev, s8 val) +{ + return clamp_t(s8, val, -100, 0) + 100; +} + +static +void rtw8852c_btc_bt_aci_imp(struct rtw89_dev *rtwdev) +{ + struct rtw89_btc *btc = &rtwdev->btc; + struct rtw89_btc_dm *dm = &btc->dm; + struct rtw89_btc_bt_info *bt = &btc->cx.bt; + struct rtw89_btc_bt_link_info *b = &bt->link_info; + + /* fix LNA2 = level-5 for BT ACI issue at BTG */ + if (btc->dm.wl_btg_rx && b->profile_cnt.now != 0) + dm->trx_para_level = 1; +} + +static +void rtw8852c_btc_update_bt_cnt(struct rtw89_dev *rtwdev) +{ + struct rtw89_btc *btc = &rtwdev->btc; + struct rtw89_btc_cx *cx = &btc->cx; + u32 val; + + val = rtw89_read32(rtwdev, R_BTC_BT_CNT_HIGH); + cx->cnt_bt[BTC_BCNT_HIPRI_TX] = FIELD_GET(B_AX_STATIS_BT_HI_TX_MASK, val); + cx->cnt_bt[BTC_BCNT_HIPRI_RX] = FIELD_GET(B_AX_STATIS_BT_HI_RX_MASK, val); + + val = rtw89_read32(rtwdev, R_BTC_BT_CNT_LOW); + cx->cnt_bt[BTC_BCNT_LOPRI_TX] = FIELD_GET(B_AX_STATIS_BT_LO_TX_1_MASK, val); + cx->cnt_bt[BTC_BCNT_LOPRI_RX] = FIELD_GET(B_AX_STATIS_BT_LO_RX_1_MASK, val); + + /* clock-gate off before reset counter*/ + rtw89_write32_set(rtwdev, R_AX_BTC_CFG, B_AX_DIS_BTC_CLK_G); + rtw89_write32_clr(rtwdev, R_AX_BT_CNT_CFG, B_AX_BT_CNT_RST); + rtw89_write32_set(rtwdev, R_AX_BT_CNT_CFG, B_AX_BT_CNT_RST); + rtw89_write32_clr(rtwdev, R_AX_BTC_CFG, B_AX_DIS_BTC_CLK_G); +} + +static +void rtw8852c_btc_wl_s1_standby(struct rtw89_dev *rtwdev, bool state) +{ + rtw89_write_rf(rtwdev, RF_PATH_B, RR_LUTWE, RFREG_MASK, 0x80000); + rtw89_write_rf(rtwdev, RF_PATH_B, RR_LUTWA, RFREG_MASK, 0x1); + rtw89_write_rf(rtwdev, RF_PATH_B, RR_LUTWD1, RFREG_MASK, 0x620); + + /* set WL standby = Rx for GNT_BT_Tx = 1->0 settle issue */ + if (state) + rtw89_write_rf(rtwdev, RF_PATH_B, RR_LUTWD0, + RFREG_MASK, 0x179c); + else + rtw89_write_rf(rtwdev, RF_PATH_B, RR_LUTWD0, + RFREG_MASK, 0x208); + + rtw89_write_rf(rtwdev, RF_PATH_B, RR_LUTWE, RFREG_MASK, 0x0); +} + static void rtw8852c_fill_freq_with_ppdu(struct rtw89_dev *rtwdev, struct rtw89_rx_phy_ppdu *phy_ppdu, struct ieee80211_rx_status *status) @@ -2546,7 +2726,14 @@ static const struct rtw89_chip_ops rtw8852c_chip_ops = { .resume_sch_tx = rtw89_mac_resume_sch_tx_v1, .h2c_dctl_sec_cam = rtw89_fw_h2c_dctl_sec_cam_v1, + .btc_set_rfe = rtw8852c_btc_set_rfe, .btc_init_cfg = rtw8852c_btc_init_cfg, + .btc_set_wl_pri = rtw8852c_btc_set_wl_pri, + .btc_set_wl_txpwr_ctrl = rtw8852c_btc_set_wl_txpwr_ctrl, + .btc_get_bt_rssi = rtw8852c_btc_get_bt_rssi, + .btc_bt_aci_imp = rtw8852c_btc_bt_aci_imp, + .btc_update_bt_cnt = rtw8852c_btc_update_bt_cnt, + .btc_wl_s1_standby = rtw8852c_btc_wl_s1_standby, }; const struct rtw89_chip_info rtw8852c_chip_info = { From 68d57a07bfe5bb29b80cd8b8fa24c9d1ea104124 Mon Sep 17 00:00:00 2001 From: Srinivasan Raju Date: Thu, 24 Feb 2022 18:20:07 +0000 Subject: [PATCH 183/228] wireless: add plfxlc driver for pureLiFi X, XL, XC devices This is a driver for pureLiFi X, XL, XC devices which use light to transmit data, so they are not compatible with normal Wi-Fi devices. The driver uses separate NL80211_BAND_LC band to distinguish from Wi-Fi. The driver is based on 802.11 softMAC Architecture and uses native 802.11 for configuration and management. Station and Ad-Hoc modes are supported. The driver is compiled and tested in ARM, x86 architectures and compiled in powerpc architecture. This driver implementation has been based on the zd1211rw driver. Signed-off-by: Srinivasan Raju Signed-off-by: Kalle Valo Link: https://lore.kernel.org/r/20220224182042.132466-3-srini.raju@purelifi.com --- MAINTAINERS | 6 + drivers/net/wireless/Kconfig | 1 + drivers/net/wireless/Makefile | 1 + drivers/net/wireless/purelifi/Kconfig | 17 + drivers/net/wireless/purelifi/Makefile | 2 + drivers/net/wireless/purelifi/plfxlc/Kconfig | 14 + drivers/net/wireless/purelifi/plfxlc/Makefile | 3 + drivers/net/wireless/purelifi/plfxlc/chip.c | 99 ++ drivers/net/wireless/purelifi/plfxlc/chip.h | 70 ++ .../net/wireless/purelifi/plfxlc/firmware.c | 276 ++++++ drivers/net/wireless/purelifi/plfxlc/intf.h | 52 + drivers/net/wireless/purelifi/plfxlc/mac.c | 754 +++++++++++++++ drivers/net/wireless/purelifi/plfxlc/mac.h | 184 ++++ drivers/net/wireless/purelifi/plfxlc/usb.c | 892 ++++++++++++++++++ drivers/net/wireless/purelifi/plfxlc/usb.h | 198 ++++ 15 files changed, 2569 insertions(+) create mode 100644 drivers/net/wireless/purelifi/Kconfig create mode 100644 drivers/net/wireless/purelifi/Makefile create mode 100644 drivers/net/wireless/purelifi/plfxlc/Kconfig create mode 100644 drivers/net/wireless/purelifi/plfxlc/Makefile create mode 100644 drivers/net/wireless/purelifi/plfxlc/chip.c create mode 100644 drivers/net/wireless/purelifi/plfxlc/chip.h create mode 100644 drivers/net/wireless/purelifi/plfxlc/firmware.c create mode 100644 drivers/net/wireless/purelifi/plfxlc/intf.h create mode 100644 drivers/net/wireless/purelifi/plfxlc/mac.c create mode 100644 drivers/net/wireless/purelifi/plfxlc/mac.h create mode 100644 drivers/net/wireless/purelifi/plfxlc/usb.c create mode 100644 drivers/net/wireless/purelifi/plfxlc/usb.h diff --git a/MAINTAINERS b/MAINTAINERS index ba405f6ec31a9..f9a37b926aeea 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -15970,6 +15970,12 @@ T: git git://linuxtv.org/media_tree.git F: Documentation/admin-guide/media/pulse8-cec.rst F: drivers/media/cec/usb/pulse8/ +PURELIFI PLFXLC DRIVER +M: Srinivasan Raju +L: linux-wireless@vger.kernel.org +S: Supported +F: drivers/net/wireless/purelifi/plfxlc/ + PVRUSB2 VIDEO4LINUX DRIVER M: Mike Isely L: pvrusb2@isely.net (subscribers-only) diff --git a/drivers/net/wireless/Kconfig b/drivers/net/wireless/Kconfig index e78ff7af6517a..cb1c15012dd02 100644 --- a/drivers/net/wireless/Kconfig +++ b/drivers/net/wireless/Kconfig @@ -28,6 +28,7 @@ source "drivers/net/wireless/intersil/Kconfig" source "drivers/net/wireless/marvell/Kconfig" source "drivers/net/wireless/mediatek/Kconfig" source "drivers/net/wireless/microchip/Kconfig" +source "drivers/net/wireless/purelifi/Kconfig" source "drivers/net/wireless/ralink/Kconfig" source "drivers/net/wireless/realtek/Kconfig" source "drivers/net/wireless/rsi/Kconfig" diff --git a/drivers/net/wireless/Makefile b/drivers/net/wireless/Makefile index 76885e5f0ea7a..abf3e5c87ca7f 100644 --- a/drivers/net/wireless/Makefile +++ b/drivers/net/wireless/Makefile @@ -13,6 +13,7 @@ obj-$(CONFIG_WLAN_VENDOR_INTERSIL) += intersil/ obj-$(CONFIG_WLAN_VENDOR_MARVELL) += marvell/ obj-$(CONFIG_WLAN_VENDOR_MEDIATEK) += mediatek/ obj-$(CONFIG_WLAN_VENDOR_MICROCHIP) += microchip/ +obj-$(CONFIG_WLAN_VENDOR_PURELIFI) += purelifi/ obj-$(CONFIG_WLAN_VENDOR_RALINK) += ralink/ obj-$(CONFIG_WLAN_VENDOR_REALTEK) += realtek/ obj-$(CONFIG_WLAN_VENDOR_RSI) += rsi/ diff --git a/drivers/net/wireless/purelifi/Kconfig b/drivers/net/wireless/purelifi/Kconfig new file mode 100644 index 0000000000000..e39afec3dcae5 --- /dev/null +++ b/drivers/net/wireless/purelifi/Kconfig @@ -0,0 +1,17 @@ +# SPDX-License-Identifier: GPL-2.0-only +config WLAN_VENDOR_PURELIFI + bool "pureLiFi devices" + default y + help + If you have a pureLiFi device, say Y. + + Note that the answer to this question doesn't directly affect the + kernel: saying N will just cause the configurator to skip all the + questions about these cards. If you say Y, you will be asked for + your specific card in the following questions. + +if WLAN_VENDOR_PURELIFI + +source "drivers/net/wireless/purelifi/plfxlc/Kconfig" + +endif # WLAN_VENDOR_PURELIFI diff --git a/drivers/net/wireless/purelifi/Makefile b/drivers/net/wireless/purelifi/Makefile new file mode 100644 index 0000000000000..0bd6880b022ca --- /dev/null +++ b/drivers/net/wireless/purelifi/Makefile @@ -0,0 +1,2 @@ +# SPDX-License-Identifier: GPL-2.0-only +obj-$(CONFIG_PLFXLC) := plfxlc/ diff --git a/drivers/net/wireless/purelifi/plfxlc/Kconfig b/drivers/net/wireless/purelifi/plfxlc/Kconfig new file mode 100644 index 0000000000000..4e0be27a5e0eb --- /dev/null +++ b/drivers/net/wireless/purelifi/plfxlc/Kconfig @@ -0,0 +1,14 @@ +# SPDX-License-Identifier: GPL-2.0-only +config PLFXLC + tristate "pureLiFi X, XL, XC device support" + depends on CFG80211 && MAC80211 && USB + help + This option adds support for pureLiFi LiFi wireless USB + adapters. The pureLiFi X, XL, XC USB devices are based on + 802.11 OFDM PHY but uses light as the transmission medium. + The driver supports common 802.11 encryption/authentication + methods including Open, WPA, WPA2-Personal and + WPA2-Enterprise (802.1X). + + To compile this driver as a module, choose m here. The module will + be called plfxlc. diff --git a/drivers/net/wireless/purelifi/plfxlc/Makefile b/drivers/net/wireless/purelifi/plfxlc/Makefile new file mode 100644 index 0000000000000..7ed954e871d6e --- /dev/null +++ b/drivers/net/wireless/purelifi/plfxlc/Makefile @@ -0,0 +1,3 @@ +# SPDX-License-Identifier: GPL-2.0-only +obj-$(CONFIG_PLFXLC) := plfxlc.o +plfxlc-objs += chip.o firmware.o usb.o mac.o diff --git a/drivers/net/wireless/purelifi/plfxlc/chip.c b/drivers/net/wireless/purelifi/plfxlc/chip.c new file mode 100644 index 0000000000000..a5ec10b66ed53 --- /dev/null +++ b/drivers/net/wireless/purelifi/plfxlc/chip.c @@ -0,0 +1,99 @@ +// SPDX-License-Identifier: GPL-2.0-only +/* + * Copyright (c) 2021 pureLiFi + */ + +#include +#include + +#include "chip.h" +#include "mac.h" +#include "usb.h" + +void plfxlc_chip_init(struct plfxlc_chip *chip, + struct ieee80211_hw *hw, + struct usb_interface *intf) +{ + memset(chip, 0, sizeof(*chip)); + mutex_init(&chip->mutex); + plfxlc_usb_init(&chip->usb, hw, intf); +} + +void plfxlc_chip_release(struct plfxlc_chip *chip) +{ + plfxlc_usb_release(&chip->usb); + mutex_destroy(&chip->mutex); +} + +int plfxlc_set_beacon_interval(struct plfxlc_chip *chip, u16 interval, + u8 dtim_period, int type) +{ + if (!interval || + (chip->beacon_set && + le16_to_cpu(chip->beacon_interval) == interval)) + return 0; + + chip->beacon_interval = cpu_to_le16(interval); + chip->beacon_set = true; + return plfxlc_usb_wreq(chip->usb.ez_usb, + &chip->beacon_interval, + sizeof(chip->beacon_interval), + USB_REQ_BEACON_INTERVAL_WR); +} + +int plfxlc_chip_init_hw(struct plfxlc_chip *chip) +{ + unsigned char *addr = plfxlc_mac_get_perm_addr(plfxlc_chip_to_mac(chip)); + struct usb_device *udev = interface_to_usbdev(chip->usb.intf); + + pr_info("plfxlc chip %04x:%04x v%02x %pM %s\n", + le16_to_cpu(udev->descriptor.idVendor), + le16_to_cpu(udev->descriptor.idProduct), + le16_to_cpu(udev->descriptor.bcdDevice), + addr, + plfxlc_speed(udev->speed)); + + return plfxlc_set_beacon_interval(chip, 100, 0, 0); +} + +int plfxlc_chip_switch_radio(struct plfxlc_chip *chip, u16 value) +{ + int r; + __le16 radio_on = cpu_to_le16(value); + + r = plfxlc_usb_wreq(chip->usb.ez_usb, &radio_on, + sizeof(value), USB_REQ_POWER_WR); + if (r) + dev_err(plfxlc_chip_dev(chip), "POWER_WR failed (%d)\n", r); + return r; +} + +int plfxlc_chip_enable_rxtx(struct plfxlc_chip *chip) +{ + plfxlc_usb_enable_tx(&chip->usb); + return plfxlc_usb_enable_rx(&chip->usb); +} + +void plfxlc_chip_disable_rxtx(struct plfxlc_chip *chip) +{ + u8 value = 0; + + plfxlc_usb_wreq(chip->usb.ez_usb, + &value, sizeof(value), USB_REQ_RXTX_WR); + plfxlc_usb_disable_rx(&chip->usb); + plfxlc_usb_disable_tx(&chip->usb); +} + +int plfxlc_chip_set_rate(struct plfxlc_chip *chip, u8 rate) +{ + int r; + + if (!chip) + return -EINVAL; + + r = plfxlc_usb_wreq(chip->usb.ez_usb, + &rate, sizeof(rate), USB_REQ_RATE_WR); + if (r) + dev_err(plfxlc_chip_dev(chip), "RATE_WR failed (%d)\n", r); + return r; +} diff --git a/drivers/net/wireless/purelifi/plfxlc/chip.h b/drivers/net/wireless/purelifi/plfxlc/chip.h new file mode 100644 index 0000000000000..dc04bbed07ac1 --- /dev/null +++ b/drivers/net/wireless/purelifi/plfxlc/chip.h @@ -0,0 +1,70 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ +/* + * Copyright (c) 2021 pureLiFi + */ + +#ifndef PLFXLC_CHIP_H +#define PLFXLC_CHIP_H + +#include + +#include "usb.h" + +enum unit_type { + STA = 0, + AP = 1, +}; + +enum { + PLFXLC_RADIO_OFF = 0, + PLFXLC_RADIO_ON = 1, +}; + +struct plfxlc_chip { + struct plfxlc_usb usb; + struct mutex mutex; /* lock to protect chip data */ + enum unit_type unit_type; + u16 link_led; + u8 beacon_set; + u16 beacon_interval; +}; + +struct plfxlc_mc_hash { + u32 low; + u32 high; +}; + +#define plfxlc_chip_dev(chip) (&(chip)->usb.intf->dev) + +void plfxlc_chip_init(struct plfxlc_chip *chip, + struct ieee80211_hw *hw, + struct usb_interface *intf); + +void plfxlc_chip_release(struct plfxlc_chip *chip); + +void plfxlc_chip_disable_rxtx(struct plfxlc_chip *chip); + +int plfxlc_chip_init_hw(struct plfxlc_chip *chip); + +int plfxlc_chip_enable_rxtx(struct plfxlc_chip *chip); + +int plfxlc_chip_set_rate(struct plfxlc_chip *chip, u8 rate); + +int plfxlc_set_beacon_interval(struct plfxlc_chip *chip, u16 interval, + u8 dtim_period, int type); + +int plfxlc_chip_switch_radio(struct plfxlc_chip *chip, u16 value); + +static inline struct plfxlc_chip *plfxlc_usb_to_chip(struct plfxlc_usb + *usb) +{ + return container_of(usb, struct plfxlc_chip, usb); +} + +static inline void plfxlc_mc_add_all(struct plfxlc_mc_hash *hash) +{ + hash->low = 0xffffffff; + hash->high = 0xffffffff; +} + +#endif /* PLFXLC_CHIP_H */ diff --git a/drivers/net/wireless/purelifi/plfxlc/firmware.c b/drivers/net/wireless/purelifi/plfxlc/firmware.c new file mode 100644 index 0000000000000..8a3529d07927d --- /dev/null +++ b/drivers/net/wireless/purelifi/plfxlc/firmware.c @@ -0,0 +1,276 @@ +// SPDX-License-Identifier: GPL-2.0-only +/* + * Copyright (c) 2021 pureLiFi + */ + +#include +#include + +#include "mac.h" +#include "usb.h" + +static int send_vendor_request(struct usb_device *udev, int request, + unsigned char *buffer, int buffer_size) +{ + return usb_control_msg(udev, + usb_rcvctrlpipe(udev, 0), + request, 0xC0, 0, 0, + buffer, buffer_size, PLF_USB_TIMEOUT); +} + +static int send_vendor_command(struct usb_device *udev, int request, + unsigned char *buffer, int buffer_size) +{ + return usb_control_msg(udev, + usb_sndctrlpipe(udev, 0), + request, USB_TYPE_VENDOR /*0x40*/, 0, 0, + buffer, buffer_size, PLF_USB_TIMEOUT); +} + +int plfxlc_download_fpga(struct usb_interface *intf) +{ + struct usb_device *udev = interface_to_usbdev(intf); + unsigned char *fpga_dmabuff = NULL; + const struct firmware *fw = NULL; + int blk_tran_len = PLF_BULK_TLEN; + unsigned char *fw_data; + const char *fw_name; + int r, actual_length; + int fw_data_i = 0; + + if ((le16_to_cpu(udev->descriptor.idVendor) == + PURELIFI_X_VENDOR_ID_0) && + (le16_to_cpu(udev->descriptor.idProduct) == + PURELIFI_X_PRODUCT_ID_0)) { + fw_name = "plfxlc/lifi-x.bin"; + dev_dbg(&intf->dev, "bin file for X selected\n"); + + } else if ((le16_to_cpu(udev->descriptor.idVendor)) == + PURELIFI_XC_VENDOR_ID_0 && + (le16_to_cpu(udev->descriptor.idProduct) == + PURELIFI_XC_PRODUCT_ID_0)) { + fw_name = "plfxlc/lifi-xc.bin"; + dev_dbg(&intf->dev, "bin file for XC selected\n"); + + } else { + r = -EINVAL; + goto error; + } + + r = request_firmware(&fw, fw_name, &intf->dev); + if (r) { + dev_err(&intf->dev, "request_firmware failed (%d)\n", r); + goto error; + } + fpga_dmabuff = kmalloc(PLF_FPGA_STATUS_LEN, GFP_KERNEL); + + if (!fpga_dmabuff) { + r = -ENOMEM; + goto error_free_fw; + } + send_vendor_request(udev, PLF_VNDR_FPGA_SET_REQ, + fpga_dmabuff, PLF_FPGA_STATUS_LEN); + + send_vendor_command(udev, PLF_VNDR_FPGA_SET_CMD, NULL, 0); + + if (fpga_dmabuff[0] != PLF_FPGA_MG) { + dev_err(&intf->dev, "fpga_dmabuff[0] is wrong\n"); + r = -EINVAL; + goto error_free_fw; + } + + for (fw_data_i = 0; fw_data_i < fw->size;) { + int tbuf_idx; + + if ((fw->size - fw_data_i) < blk_tran_len) + blk_tran_len = fw->size - fw_data_i; + + fw_data = kmemdup(&fw->data[fw_data_i], blk_tran_len, + GFP_KERNEL); + if (!fw_data) { + r = -ENOMEM; + goto error_free_fw; + } + + for (tbuf_idx = 0; tbuf_idx < blk_tran_len; tbuf_idx++) { + /* u8 bit reverse */ + fw_data[tbuf_idx] = bitrev8(fw_data[tbuf_idx]); + } + r = usb_bulk_msg(udev, + usb_sndbulkpipe(interface_to_usbdev(intf), + fpga_dmabuff[0] & 0xff), + fw_data, + blk_tran_len, + &actual_length, + 2 * PLF_USB_TIMEOUT); + + if (r) + dev_err(&intf->dev, "Bulk msg failed (%d)\n", r); + + kfree(fw_data); + fw_data_i += blk_tran_len; + } + + kfree(fpga_dmabuff); + fpga_dmabuff = kmalloc(PLF_FPGA_STATE_LEN, GFP_KERNEL); + if (!fpga_dmabuff) { + r = -ENOMEM; + goto error_free_fw; + } + memset(fpga_dmabuff, 0xff, PLF_FPGA_STATE_LEN); + + send_vendor_request(udev, PLF_VNDR_FPGA_STATE_REQ, fpga_dmabuff, + PLF_FPGA_STATE_LEN); + + dev_dbg(&intf->dev, "%*ph\n", 8, fpga_dmabuff); + + if (fpga_dmabuff[0] != 0) { + r = -EINVAL; + goto error_free_fw; + } + + send_vendor_command(udev, PLF_VNDR_FPGA_STATE_CMD, NULL, 0); + + msleep(PLF_MSLEEP_TIME); + +error_free_fw: + kfree(fpga_dmabuff); + release_firmware(fw); +error: + return r; +} + +int plfxlc_download_xl_firmware(struct usb_interface *intf) +{ + struct usb_device *udev = interface_to_usbdev(intf); + const struct firmware *fwp = NULL; + struct plfxlc_firmware_file file = {0}; + const char *fw_pack; + int s, r; + u8 *buf; + u32 i; + + r = send_vendor_command(udev, PLF_VNDR_XL_FW_CMD, NULL, 0); + msleep(PLF_MSLEEP_TIME); + + if (r) { + dev_err(&intf->dev, "vendor command failed (%d)\n", r); + return -EINVAL; + } + /* Code for single pack file download */ + + fw_pack = "plfxlc/lifi-xl.bin"; + + r = request_firmware(&fwp, fw_pack, &intf->dev); + if (r) { + dev_err(&intf->dev, "Request_firmware failed (%d)\n", r); + return -EINVAL; + } + file.total_files = get_unaligned_le32(&fwp->data[0]); + file.total_size = get_unaligned_le32(&fwp->size); + + dev_dbg(&intf->dev, "XL Firmware (%d, %d)\n", + file.total_files, file.total_size); + + buf = kzalloc(PLF_XL_BUF_LEN, GFP_KERNEL); + if (!buf) { + release_firmware(fwp); + return -ENOMEM; + } + + if (file.total_files > 10) { + dev_err(&intf->dev, "Too many files (%d)\n", file.total_files); + release_firmware(fwp); + kfree(buf); + return -EINVAL; + } + + /* Download firmware files in multiple steps */ + for (s = 0; s < file.total_files; s++) { + buf[0] = s; + r = send_vendor_command(udev, PLF_VNDR_XL_FILE_CMD, buf, + PLF_XL_BUF_LEN); + + if (s < file.total_files - 1) + file.size = get_unaligned_le32(&fwp->data[4 + ((s + 1) * 4)]) + - get_unaligned_le32(&fwp->data[4 + (s) * 4]); + else + file.size = file.total_size - + get_unaligned_le32(&fwp->data[4 + (s) * 4]); + + if (file.size > file.total_size || file.size > 60000) { + dev_err(&intf->dev, "File size is too large (%d)\n", file.size); + break; + } + + file.start_addr = get_unaligned_le32(&fwp->data[4 + (s * 4)]); + + if (file.size % PLF_XL_BUF_LEN && s < 2) + file.size += PLF_XL_BUF_LEN - file.size % PLF_XL_BUF_LEN; + + file.control_packets = file.size / PLF_XL_BUF_LEN; + + for (i = 0; i < file.control_packets; i++) { + memcpy(buf, + &fwp->data[file.start_addr + (i * PLF_XL_BUF_LEN)], + PLF_XL_BUF_LEN); + r = send_vendor_command(udev, PLF_VNDR_XL_DATA_CMD, buf, + PLF_XL_BUF_LEN); + } + dev_dbg(&intf->dev, "fw-dw step=%d,r=%d size=%d\n", s, r, + file.size); + } + release_firmware(fwp); + kfree(buf); + + /* Code for single pack file download ends fw download finish */ + + r = send_vendor_command(udev, PLF_VNDR_XL_EX_CMD, NULL, 0); + dev_dbg(&intf->dev, "Download fpga (4) (%d)\n", r); + + return 0; +} + +int plfxlc_upload_mac_and_serial(struct usb_interface *intf, + unsigned char *hw_address, + unsigned char *serial_number) +{ + struct usb_device *udev = interface_to_usbdev(intf); + unsigned long long firmware_version; + unsigned char *dma_buffer = NULL; + + dma_buffer = kmalloc(PLF_SERIAL_LEN, GFP_KERNEL); + if (!dma_buffer) + return -ENOMEM; + + BUILD_BUG_ON(ETH_ALEN > PLF_SERIAL_LEN); + BUILD_BUG_ON(PLF_FW_VER_LEN > PLF_SERIAL_LEN); + + send_vendor_request(udev, PLF_MAC_VENDOR_REQUEST, dma_buffer, + ETH_ALEN); + + memcpy(hw_address, dma_buffer, ETH_ALEN); + + send_vendor_request(udev, PLF_SERIAL_NUMBER_VENDOR_REQUEST, + dma_buffer, PLF_SERIAL_LEN); + + send_vendor_request(udev, PLF_SERIAL_NUMBER_VENDOR_REQUEST, + dma_buffer, PLF_SERIAL_LEN); + + memcpy(serial_number, dma_buffer, PLF_SERIAL_LEN); + + memset(dma_buffer, 0x00, PLF_SERIAL_LEN); + + send_vendor_request(udev, PLF_FIRMWARE_VERSION_VENDOR_REQUEST, + (unsigned char *)dma_buffer, PLF_FW_VER_LEN); + + memcpy(&firmware_version, dma_buffer, PLF_FW_VER_LEN); + + dev_info(&intf->dev, "Firmware Version: %llu\n", firmware_version); + kfree(dma_buffer); + + dev_dbg(&intf->dev, "Mac: %pM\n", hw_address); + + return 0; +} + diff --git a/drivers/net/wireless/purelifi/plfxlc/intf.h b/drivers/net/wireless/purelifi/plfxlc/intf.h new file mode 100644 index 0000000000000..5ae89343b5794 --- /dev/null +++ b/drivers/net/wireless/purelifi/plfxlc/intf.h @@ -0,0 +1,52 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ +/* + * Copyright (c) 2021 pureLiFi + */ + +#define PURELIFI_BYTE_NUM_ALIGNMENT 4 +#define ETH_ALEN 6 +#define AP_USER_LIMIT 8 + +#define PLF_VNDR_FPGA_STATE_REQ 0x30 +#define PLF_VNDR_FPGA_SET_REQ 0x33 +#define PLF_VNDR_FPGA_SET_CMD 0x34 +#define PLF_VNDR_FPGA_STATE_CMD 0x35 + +#define PLF_VNDR_XL_FW_CMD 0x80 +#define PLF_VNDR_XL_DATA_CMD 0x81 +#define PLF_VNDR_XL_FILE_CMD 0x82 +#define PLF_VNDR_XL_EX_CMD 0x83 + +#define PLF_MAC_VENDOR_REQUEST 0x36 +#define PLF_SERIAL_NUMBER_VENDOR_REQUEST 0x37 +#define PLF_FIRMWARE_VERSION_VENDOR_REQUEST 0x39 +#define PLF_SERIAL_LEN 14 +#define PLF_FW_VER_LEN 8 + +struct rx_status { + __be16 rssi; + u8 rate_idx; + u8 pad; + __be64 crc_error_count; +} __packed; + +enum plf_usb_req_enum { + USB_REQ_TEST_WR = 0, + USB_REQ_MAC_WR = 1, + USB_REQ_POWER_WR = 2, + USB_REQ_RXTX_WR = 3, + USB_REQ_BEACON_WR = 4, + USB_REQ_BEACON_INTERVAL_WR = 5, + USB_REQ_RTS_CTS_RATE_WR = 6, + USB_REQ_HASH_WR = 7, + USB_REQ_DATA_TX = 8, + USB_REQ_RATE_WR = 9, + USB_REQ_SET_FREQ = 15 +}; + +struct plf_usb_req { + __be32 id; /* should be plf_usb_req_enum */ + __be32 len; + u8 buf[512]; +}; + diff --git a/drivers/net/wireless/purelifi/plfxlc/mac.c b/drivers/net/wireless/purelifi/plfxlc/mac.c new file mode 100644 index 0000000000000..90e552532701a --- /dev/null +++ b/drivers/net/wireless/purelifi/plfxlc/mac.c @@ -0,0 +1,754 @@ +// SPDX-License-Identifier: GPL-2.0-only +/* + * Copyright (c) 2021 pureLiFi + */ + +#include +#include +#include +#include +#include +#include +#include + +#include "chip.h" +#include "mac.h" +#include "usb.h" + +static const struct ieee80211_rate plfxlc_rates[] = { + { .bitrate = 10, + .hw_value = PURELIFI_CCK_RATE_1M, + .flags = 0 }, + { .bitrate = 20, + .hw_value = PURELIFI_CCK_RATE_2M, + .hw_value_short = PURELIFI_CCK_RATE_2M + | PURELIFI_CCK_PREA_SHORT, + .flags = IEEE80211_RATE_SHORT_PREAMBLE }, + { .bitrate = 55, + .hw_value = PURELIFI_CCK_RATE_5_5M, + .hw_value_short = PURELIFI_CCK_RATE_5_5M + | PURELIFI_CCK_PREA_SHORT, + .flags = IEEE80211_RATE_SHORT_PREAMBLE }, + { .bitrate = 110, + .hw_value = PURELIFI_CCK_RATE_11M, + .hw_value_short = PURELIFI_CCK_RATE_11M + | PURELIFI_CCK_PREA_SHORT, + .flags = IEEE80211_RATE_SHORT_PREAMBLE }, + { .bitrate = 60, + .hw_value = PURELIFI_OFDM_RATE_6M, + .flags = 0 }, + { .bitrate = 90, + .hw_value = PURELIFI_OFDM_RATE_9M, + .flags = 0 }, + { .bitrate = 120, + .hw_value = PURELIFI_OFDM_RATE_12M, + .flags = 0 }, + { .bitrate = 180, + .hw_value = PURELIFI_OFDM_RATE_18M, + .flags = 0 }, + { .bitrate = 240, + .hw_value = PURELIFI_OFDM_RATE_24M, + .flags = 0 }, + { .bitrate = 360, + .hw_value = PURELIFI_OFDM_RATE_36M, + .flags = 0 }, + { .bitrate = 480, + .hw_value = PURELIFI_OFDM_RATE_48M, + .flags = 0 }, + { .bitrate = 540, + .hw_value = PURELIFI_OFDM_RATE_54M, + .flags = 0 } +}; + +static const struct ieee80211_channel plfxlc_channels[] = { + { .center_freq = 2412, .hw_value = 1 }, + { .center_freq = 2417, .hw_value = 2 }, + { .center_freq = 2422, .hw_value = 3 }, + { .center_freq = 2427, .hw_value = 4 }, + { .center_freq = 2432, .hw_value = 5 }, + { .center_freq = 2437, .hw_value = 6 }, + { .center_freq = 2442, .hw_value = 7 }, + { .center_freq = 2447, .hw_value = 8 }, + { .center_freq = 2452, .hw_value = 9 }, + { .center_freq = 2457, .hw_value = 10 }, + { .center_freq = 2462, .hw_value = 11 }, + { .center_freq = 2467, .hw_value = 12 }, + { .center_freq = 2472, .hw_value = 13 }, + { .center_freq = 2484, .hw_value = 14 }, +}; + +int plfxlc_mac_preinit_hw(struct ieee80211_hw *hw, const u8 *hw_address) +{ + SET_IEEE80211_PERM_ADDR(hw, hw_address); + return 0; +} + +int plfxlc_mac_init_hw(struct ieee80211_hw *hw) +{ + struct plfxlc_mac *mac = plfxlc_hw_mac(hw); + struct plfxlc_chip *chip = &mac->chip; + int r; + + r = plfxlc_chip_init_hw(chip); + if (r) { + dev_warn(plfxlc_mac_dev(mac), "init hw failed (%d)\n", r); + return r; + } + + dev_dbg(plfxlc_mac_dev(mac), "irq_disabled (%d)\n", irqs_disabled()); + regulatory_hint(hw->wiphy, "00"); + return r; +} + +void plfxlc_mac_release(struct plfxlc_mac *mac) +{ + plfxlc_chip_release(&mac->chip); + lockdep_assert_held(&mac->lock); +} + +int plfxlc_op_start(struct ieee80211_hw *hw) +{ + plfxlc_hw_mac(hw)->chip.usb.initialized = 1; + return 0; +} + +void plfxlc_op_stop(struct ieee80211_hw *hw) +{ + struct plfxlc_mac *mac = plfxlc_hw_mac(hw); + + clear_bit(PURELIFI_DEVICE_RUNNING, &mac->flags); +} + +int plfxlc_restore_settings(struct plfxlc_mac *mac) +{ + int beacon_interval, beacon_period; + struct sk_buff *beacon; + + spin_lock_irq(&mac->lock); + beacon_interval = mac->beacon.interval; + beacon_period = mac->beacon.period; + spin_unlock_irq(&mac->lock); + + if (mac->type != NL80211_IFTYPE_ADHOC) + return 0; + + if (mac->vif) { + beacon = ieee80211_beacon_get(mac->hw, mac->vif); + if (beacon) { + /*beacon is hardcoded in firmware */ + kfree_skb(beacon); + /* Returned skb is used only once and lowlevel + * driver is responsible for freeing it. + */ + } + } + + plfxlc_set_beacon_interval(&mac->chip, beacon_interval, + beacon_period, mac->type); + + spin_lock_irq(&mac->lock); + mac->beacon.last_update = jiffies; + spin_unlock_irq(&mac->lock); + + return 0; +} + +static void plfxlc_mac_tx_status(struct ieee80211_hw *hw, + struct sk_buff *skb, + int ackssi, + struct tx_status *tx_status) +{ + struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb); + int success = 1; + + ieee80211_tx_info_clear_status(info); + if (tx_status) + success = !tx_status->failure; + + if (success) + info->flags |= IEEE80211_TX_STAT_ACK; + else + info->flags &= ~IEEE80211_TX_STAT_ACK; + + info->status.ack_signal = 50; + ieee80211_tx_status_irqsafe(hw, skb); +} + +void plfxlc_mac_tx_to_dev(struct sk_buff *skb, int error) +{ + struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb); + struct ieee80211_hw *hw = info->rate_driver_data[0]; + struct plfxlc_mac *mac = plfxlc_hw_mac(hw); + struct sk_buff_head *q = NULL; + + ieee80211_tx_info_clear_status(info); + skb_pull(skb, sizeof(struct plfxlc_ctrlset)); + + if (unlikely(error || + (info->flags & IEEE80211_TX_CTL_NO_ACK))) { + ieee80211_tx_status_irqsafe(hw, skb); + return; + } + + q = &mac->ack_wait_queue; + + skb_queue_tail(q, skb); + while (skb_queue_len(q)/* > PURELIFI_MAC_MAX_ACK_WAITERS*/) { + plfxlc_mac_tx_status(hw, skb_dequeue(q), + mac->ack_pending ? + mac->ack_signal : 0, + NULL); + mac->ack_pending = 0; + } +} + +static int plfxlc_fill_ctrlset(struct plfxlc_mac *mac, struct sk_buff *skb) +{ + unsigned int frag_len = skb->len; + struct plfxlc_ctrlset *cs; + u32 temp_payload_len = 0; + unsigned int tmp; + u32 temp_len = 0; + + if (skb_headroom(skb) < sizeof(struct plfxlc_ctrlset)) { + dev_dbg(plfxlc_mac_dev(mac), "Not enough hroom(1)\n"); + return 1; + } + + cs = (void *)skb_push(skb, sizeof(struct plfxlc_ctrlset)); + temp_payload_len = frag_len; + temp_len = temp_payload_len + + sizeof(struct plfxlc_ctrlset) - + sizeof(cs->id) - sizeof(cs->len); + + /* Data packet lengths must be multiple of four bytes and must + * not be a multiple of 512 bytes. First, it is attempted to + * append the data packet in the tailroom of the skb. In rare + * occasions, the tailroom is too small. In this case, the + * content of the packet is shifted into the headroom of the skb + * by memcpy. Headroom is allocated at startup (below in this + * file). Therefore, there will be always enough headroom. The + * call skb_headroom is an additional safety which might be + * dropped. + */ + /* check if 32 bit aligned and align data */ + tmp = skb->len & 3; + if (tmp) { + if (skb_tailroom(skb) < (3 - tmp)) { + if (skb_headroom(skb) >= 4 - tmp) { + u8 len; + u8 *src_pt; + u8 *dest_pt; + + len = skb->len; + src_pt = skb->data; + dest_pt = skb_push(skb, 4 - tmp); + memmove(dest_pt, src_pt, len); + } else { + return -ENOBUFS; + } + } else { + skb_put(skb, 4 - tmp); + } + temp_len += 4 - tmp; + } + + /* check if not multiple of 512 and align data */ + tmp = skb->len & 0x1ff; + if (!tmp) { + if (skb_tailroom(skb) < 4) { + if (skb_headroom(skb) >= 4) { + u8 len = skb->len; + u8 *src_pt = skb->data; + u8 *dest_pt = skb_push(skb, 4); + + memmove(dest_pt, src_pt, len); + } else { + /* should never happen because + * sufficient headroom was reserved + */ + return -ENOBUFS; + } + } else { + skb_put(skb, 4); + } + temp_len += 4; + } + + cs->id = cpu_to_be32(USB_REQ_DATA_TX); + cs->len = cpu_to_be32(temp_len); + cs->payload_len_nw = cpu_to_be32(temp_payload_len); + + return 0; +} + +static void plfxlc_op_tx(struct ieee80211_hw *hw, + struct ieee80211_tx_control *control, + struct sk_buff *skb) +{ + struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb); + struct plfxlc_header *plhdr = (void *)skb->data; + struct plfxlc_mac *mac = plfxlc_hw_mac(hw); + struct plfxlc_usb *usb = &mac->chip.usb; + unsigned long flags; + int r; + + r = plfxlc_fill_ctrlset(mac, skb); + if (r) + goto fail; + + info->rate_driver_data[0] = hw; + + if (plhdr->frametype == IEEE80211_FTYPE_DATA) { + u8 *dst_mac = plhdr->dmac; + u8 sidx; + bool found = false; + struct plfxlc_usb_tx *tx = &usb->tx; + + for (sidx = 0; sidx < MAX_STA_NUM; sidx++) { + if (!(tx->station[sidx].flag & STATION_CONNECTED_FLAG)) + continue; + if (memcmp(tx->station[sidx].mac, dst_mac, ETH_ALEN)) + continue; + found = true; + break; + } + + /* Default to broadcast address for unknown MACs */ + if (!found) + sidx = STA_BROADCAST_INDEX; + + /* Stop OS from sending packets, if the queue is half full */ + if (skb_queue_len(&tx->station[sidx].data_list) > 60) + ieee80211_stop_queues(plfxlc_usb_to_hw(usb)); + + /* Schedule packet for transmission if queue is not full */ + if (skb_queue_len(&tx->station[sidx].data_list) > 256) + goto fail; + skb_queue_tail(&tx->station[sidx].data_list, skb); + plfxlc_send_packet_from_data_queue(usb); + + } else { + spin_lock_irqsave(&usb->tx.lock, flags); + r = plfxlc_usb_wreq_async(&mac->chip.usb, skb->data, skb->len, + USB_REQ_DATA_TX, plfxlc_tx_urb_complete, skb); + spin_unlock_irqrestore(&usb->tx.lock, flags); + if (r) + goto fail; + } + return; + +fail: + dev_kfree_skb(skb); +} + +static int plfxlc_filter_ack(struct ieee80211_hw *hw, struct ieee80211_hdr *rx_hdr, + struct ieee80211_rx_status *stats) +{ + struct plfxlc_mac *mac = plfxlc_hw_mac(hw); + struct sk_buff_head *q; + int i, position = 0; + unsigned long flags; + struct sk_buff *skb; + bool found = false; + + if (!ieee80211_is_ack(rx_hdr->frame_control)) + return 0; + + dev_dbg(plfxlc_mac_dev(mac), "ACK Received\n"); + + /* code based on zy driver, this logic may need fix */ + q = &mac->ack_wait_queue; + spin_lock_irqsave(&q->lock, flags); + + skb_queue_walk(q, skb) { + struct ieee80211_hdr *tx_hdr; + + position++; + + if (mac->ack_pending && skb_queue_is_first(q, skb)) + continue; + if (mac->ack_pending == 0) + break; + + tx_hdr = (struct ieee80211_hdr *)skb->data; + if (likely(ether_addr_equal(tx_hdr->addr2, rx_hdr->addr1))) { + found = 1; + break; + } + } + + if (found) { + for (i = 1; i < position; i++) + skb = __skb_dequeue(q); + if (i == position) { + plfxlc_mac_tx_status(hw, skb, + mac->ack_pending ? + mac->ack_signal : 0, + NULL); + mac->ack_pending = 0; + } + + mac->ack_pending = skb_queue_len(q) ? 1 : 0; + mac->ack_signal = stats->signal; + } + + spin_unlock_irqrestore(&q->lock, flags); + return 1; +} + +int plfxlc_mac_rx(struct ieee80211_hw *hw, const u8 *buffer, + unsigned int length) +{ + struct plfxlc_mac *mac = plfxlc_hw_mac(hw); + struct ieee80211_rx_status stats; + const struct rx_status *status; + unsigned int payload_length; + struct plfxlc_usb_tx *tx; + struct sk_buff *skb; + int need_padding; + __le16 fc; + int sidx; + + /* Packet blockade during disabled interface. */ + if (!mac->vif) + return 0; + + status = (struct rx_status *)buffer; + + memset(&stats, 0, sizeof(stats)); + + stats.flag = 0; + stats.freq = 2412; + stats.band = NL80211_BAND_LC; + mac->rssi = -15 * be16_to_cpu(status->rssi) / 10; + + stats.signal = mac->rssi; + + if (status->rate_idx > 7) + stats.rate_idx = 0; + else + stats.rate_idx = status->rate_idx; + + mac->crc_errors = be64_to_cpu(status->crc_error_count); + + /* TODO bad frame check for CRC error*/ + if (plfxlc_filter_ack(hw, (struct ieee80211_hdr *)buffer, &stats) && + !mac->pass_ctrl) + return 0; + + buffer += sizeof(struct rx_status); + payload_length = get_unaligned_be32(buffer); + + if (payload_length > 1560) { + dev_err(plfxlc_mac_dev(mac), " > MTU %u\n", payload_length); + return 0; + } + buffer += sizeof(u32); + + fc = get_unaligned((__le16 *)buffer); + need_padding = ieee80211_is_data_qos(fc) ^ ieee80211_has_a4(fc); + + tx = &mac->chip.usb.tx; + + for (sidx = 0; sidx < MAX_STA_NUM - 1; sidx++) { + if (memcmp(&buffer[10], tx->station[sidx].mac, ETH_ALEN)) + continue; + if (tx->station[sidx].flag & STATION_CONNECTED_FLAG) { + tx->station[sidx].flag |= STATION_HEARTBEAT_FLAG; + break; + } + } + + if (sidx == MAX_STA_NUM - 1) { + for (sidx = 0; sidx < MAX_STA_NUM - 1; sidx++) { + if (tx->station[sidx].flag & STATION_CONNECTED_FLAG) + continue; + memcpy(tx->station[sidx].mac, &buffer[10], ETH_ALEN); + tx->station[sidx].flag |= STATION_CONNECTED_FLAG; + tx->station[sidx].flag |= STATION_HEARTBEAT_FLAG; + break; + } + } + + switch (buffer[0]) { + case IEEE80211_STYPE_PROBE_REQ: + dev_dbg(plfxlc_mac_dev(mac), "Probe request\n"); + break; + case IEEE80211_STYPE_ASSOC_REQ: + dev_dbg(plfxlc_mac_dev(mac), "Association request\n"); + break; + case IEEE80211_STYPE_AUTH: + dev_dbg(plfxlc_mac_dev(mac), "Authentication req\n"); + break; + case IEEE80211_FTYPE_DATA: + dev_dbg(plfxlc_mac_dev(mac), "802.11 data frame\n"); + break; + } + + skb = dev_alloc_skb(payload_length + (need_padding ? 2 : 0)); + if (!skb) + return -ENOMEM; + + if (need_padding) + /* Make sure that the payload data is 4 byte aligned. */ + skb_reserve(skb, 2); + + skb_put_data(skb, buffer, payload_length); + memcpy(IEEE80211_SKB_RXCB(skb), &stats, sizeof(stats)); + ieee80211_rx_irqsafe(hw, skb); + return 0; +} + +static int plfxlc_op_add_interface(struct ieee80211_hw *hw, + struct ieee80211_vif *vif) +{ + struct plfxlc_mac *mac = plfxlc_hw_mac(hw); + static const char * const iftype80211[] = { + [NL80211_IFTYPE_STATION] = "Station", + [NL80211_IFTYPE_ADHOC] = "Adhoc" + }; + + if (mac->type != NL80211_IFTYPE_UNSPECIFIED) + return -EOPNOTSUPP; + + if (vif->type == NL80211_IFTYPE_ADHOC || + vif->type == NL80211_IFTYPE_STATION) { + dev_dbg(plfxlc_mac_dev(mac), "%s %s\n", __func__, + iftype80211[vif->type]); + mac->type = vif->type; + mac->vif = vif; + return 0; + } + dev_dbg(plfxlc_mac_dev(mac), "unsupported iftype\n"); + return -EOPNOTSUPP; +} + +static void plfxlc_op_remove_interface(struct ieee80211_hw *hw, + struct ieee80211_vif *vif) +{ + struct plfxlc_mac *mac = plfxlc_hw_mac(hw); + + mac->type = NL80211_IFTYPE_UNSPECIFIED; + mac->vif = NULL; +} + +static int plfxlc_op_config(struct ieee80211_hw *hw, u32 changed) +{ + return 0; +} + +#define SUPPORTED_FIF_FLAGS \ + (FIF_ALLMULTI | FIF_FCSFAIL | FIF_CONTROL | \ + FIF_OTHER_BSS | FIF_BCN_PRBRESP_PROMISC) +static void plfxlc_op_configure_filter(struct ieee80211_hw *hw, + unsigned int changed_flags, + unsigned int *new_flags, + u64 multicast) +{ + struct plfxlc_mc_hash hash = { + .low = multicast, + .high = multicast >> 32, + }; + struct plfxlc_mac *mac = plfxlc_hw_mac(hw); + unsigned long flags; + + /* Only deal with supported flags */ + *new_flags &= SUPPORTED_FIF_FLAGS; + + /* If multicast parameter + * (as returned by plfxlc_op_prepare_multicast) + * has changed, no bit in changed_flags is set. To handle this + * situation, we do not return if changed_flags is 0. If we do so, + * we will have some issue with IPv6 which uses multicast for link + * layer address resolution. + */ + if (*new_flags & (FIF_ALLMULTI)) + plfxlc_mc_add_all(&hash); + + spin_lock_irqsave(&mac->lock, flags); + mac->pass_failed_fcs = !!(*new_flags & FIF_FCSFAIL); + mac->pass_ctrl = !!(*new_flags & FIF_CONTROL); + mac->multicast_hash = hash; + spin_unlock_irqrestore(&mac->lock, flags); + + /* no handling required for FIF_OTHER_BSS as we don't currently + * do BSSID filtering + */ + /* FIXME: in future it would be nice to enable the probe response + * filter (so that the driver doesn't see them) until + * FIF_BCN_PRBRESP_PROMISC is set. however due to atomicity here, we'd + * have to schedule work to enable prbresp reception, which might + * happen too late. For now we'll just listen and forward them all the + * time. + */ +} + +static void plfxlc_op_bss_info_changed(struct ieee80211_hw *hw, + struct ieee80211_vif *vif, + struct ieee80211_bss_conf *bss_conf, + u32 changes) +{ + struct plfxlc_mac *mac = plfxlc_hw_mac(hw); + int associated; + + dev_dbg(plfxlc_mac_dev(mac), "changes: %x\n", changes); + + if (mac->type != NL80211_IFTYPE_ADHOC) { /* for STATION */ + associated = is_valid_ether_addr(bss_conf->bssid); + goto exit_all; + } + /* for ADHOC */ + associated = true; + if (changes & BSS_CHANGED_BEACON) { + struct sk_buff *beacon = ieee80211_beacon_get(hw, vif); + + if (beacon) { + /*beacon is hardcoded in firmware */ + kfree_skb(beacon); + /*Returned skb is used only once and + * low-level driver is + * responsible for freeing it. + */ + } + } + + if (changes & BSS_CHANGED_BEACON_ENABLED) { + u16 interval = 0; + u8 period = 0; + + if (bss_conf->enable_beacon) { + period = bss_conf->dtim_period; + interval = bss_conf->beacon_int; + } + + spin_lock_irq(&mac->lock); + mac->beacon.period = period; + mac->beacon.interval = interval; + mac->beacon.last_update = jiffies; + spin_unlock_irq(&mac->lock); + + plfxlc_set_beacon_interval(&mac->chip, interval, + period, mac->type); + } +exit_all: + spin_lock_irq(&mac->lock); + mac->associated = associated; + spin_unlock_irq(&mac->lock); +} + +static int plfxlc_get_stats(struct ieee80211_hw *hw, + struct ieee80211_low_level_stats *stats) +{ + stats->dot11ACKFailureCount = 0; + stats->dot11RTSFailureCount = 0; + stats->dot11FCSErrorCount = 0; + stats->dot11RTSSuccessCount = 0; + return 0; +} + +static const char et_strings[][ETH_GSTRING_LEN] = { + "phy_rssi", + "phy_rx_crc_err" +}; + +static int plfxlc_get_et_sset_count(struct ieee80211_hw *hw, + struct ieee80211_vif *vif, int sset) +{ + if (sset == ETH_SS_STATS) + return ARRAY_SIZE(et_strings); + + return 0; +} + +static void plfxlc_get_et_strings(struct ieee80211_hw *hw, + struct ieee80211_vif *vif, + u32 sset, u8 *data) +{ + if (sset == ETH_SS_STATS) + memcpy(data, *et_strings, sizeof(et_strings)); +} + +static void plfxlc_get_et_stats(struct ieee80211_hw *hw, + struct ieee80211_vif *vif, + struct ethtool_stats *stats, u64 *data) +{ + struct plfxlc_mac *mac = plfxlc_hw_mac(hw); + + data[0] = mac->rssi; + data[1] = mac->crc_errors; +} + +static int plfxlc_set_rts_threshold(struct ieee80211_hw *hw, u32 value) +{ + return 0; +} + +static const struct ieee80211_ops plfxlc_ops = { + .tx = plfxlc_op_tx, + .start = plfxlc_op_start, + .stop = plfxlc_op_stop, + .add_interface = plfxlc_op_add_interface, + .remove_interface = plfxlc_op_remove_interface, + .set_rts_threshold = plfxlc_set_rts_threshold, + .config = plfxlc_op_config, + .configure_filter = plfxlc_op_configure_filter, + .bss_info_changed = plfxlc_op_bss_info_changed, + .get_stats = plfxlc_get_stats, + .get_et_sset_count = plfxlc_get_et_sset_count, + .get_et_stats = plfxlc_get_et_stats, + .get_et_strings = plfxlc_get_et_strings, +}; + +struct ieee80211_hw *plfxlc_mac_alloc_hw(struct usb_interface *intf) +{ + struct ieee80211_hw *hw; + struct plfxlc_mac *mac; + + hw = ieee80211_alloc_hw(sizeof(struct plfxlc_mac), &plfxlc_ops); + if (!hw) { + dev_dbg(&intf->dev, "out of memory\n"); + return NULL; + } + set_wiphy_dev(hw->wiphy, &intf->dev); + + mac = plfxlc_hw_mac(hw); + memset(mac, 0, sizeof(*mac)); + spin_lock_init(&mac->lock); + mac->hw = hw; + + mac->type = NL80211_IFTYPE_UNSPECIFIED; + + memcpy(mac->channels, plfxlc_channels, sizeof(plfxlc_channels)); + memcpy(mac->rates, plfxlc_rates, sizeof(plfxlc_rates)); + mac->band.n_bitrates = ARRAY_SIZE(plfxlc_rates); + mac->band.bitrates = mac->rates; + mac->band.n_channels = ARRAY_SIZE(plfxlc_channels); + mac->band.channels = mac->channels; + hw->wiphy->bands[NL80211_BAND_LC] = &mac->band; + hw->conf.chandef.width = NL80211_CHAN_WIDTH_20; + + ieee80211_hw_set(hw, RX_INCLUDES_FCS); + ieee80211_hw_set(hw, SIGNAL_DBM); + ieee80211_hw_set(hw, HOST_BROADCAST_PS_BUFFERING); + ieee80211_hw_set(hw, MFP_CAPABLE); + + hw->wiphy->interface_modes = + BIT(NL80211_IFTYPE_STATION) | + BIT(NL80211_IFTYPE_ADHOC); + hw->max_signal = 100; + hw->queues = 1; + /* 4 for 32 bit alignment if no tailroom */ + hw->extra_tx_headroom = sizeof(struct plfxlc_ctrlset) + 4; + /* Tell mac80211 that we support multi rate retries */ + hw->max_rates = IEEE80211_TX_MAX_RATES; + hw->max_rate_tries = 18; /* 9 rates * 2 retries/rate */ + + skb_queue_head_init(&mac->ack_wait_queue); + mac->ack_pending = 0; + + plfxlc_chip_init(&mac->chip, hw, intf); + + SET_IEEE80211_DEV(hw, &intf->dev); + return hw; +} diff --git a/drivers/net/wireless/purelifi/plfxlc/mac.h b/drivers/net/wireless/purelifi/plfxlc/mac.h new file mode 100644 index 0000000000000..49b92413729bf --- /dev/null +++ b/drivers/net/wireless/purelifi/plfxlc/mac.h @@ -0,0 +1,184 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ +/* + * Copyright (c) 2021 pureLiFi + */ + +#ifndef PLFXLC_MAC_H +#define PLFXLC_MAC_H + +#include +#include + +#include "chip.h" + +#define PURELIFI_CCK 0x00 +#define PURELIFI_OFDM 0x10 +#define PURELIFI_CCK_PREA_SHORT 0x20 + +#define PURELIFI_OFDM_PLCP_RATE_6M 0xb +#define PURELIFI_OFDM_PLCP_RATE_9M 0xf +#define PURELIFI_OFDM_PLCP_RATE_12M 0xa +#define PURELIFI_OFDM_PLCP_RATE_18M 0xe +#define PURELIFI_OFDM_PLCP_RATE_24M 0x9 +#define PURELIFI_OFDM_PLCP_RATE_36M 0xd +#define PURELIFI_OFDM_PLCP_RATE_48M 0x8 +#define PURELIFI_OFDM_PLCP_RATE_54M 0xc + +#define PURELIFI_CCK_RATE_1M (PURELIFI_CCK | 0x00) +#define PURELIFI_CCK_RATE_2M (PURELIFI_CCK | 0x01) +#define PURELIFI_CCK_RATE_5_5M (PURELIFI_CCK | 0x02) +#define PURELIFI_CCK_RATE_11M (PURELIFI_CCK | 0x03) +#define PURELIFI_OFDM_RATE_6M (PURELIFI_OFDM | PURELIFI_OFDM_PLCP_RATE_6M) +#define PURELIFI_OFDM_RATE_9M (PURELIFI_OFDM | PURELIFI_OFDM_PLCP_RATE_9M) +#define PURELIFI_OFDM_RATE_12M (PURELIFI_OFDM | PURELIFI_OFDM_PLCP_RATE_12M) +#define PURELIFI_OFDM_RATE_18M (PURELIFI_OFDM | PURELIFI_OFDM_PLCP_RATE_18M) +#define PURELIFI_OFDM_RATE_24M (PURELIFI_OFDM | PURELIFI_OFDM_PLCP_RATE_24M) +#define PURELIFI_OFDM_RATE_36M (PURELIFI_OFDM | PURELIFI_OFDM_PLCP_RATE_36M) +#define PURELIFI_OFDM_RATE_48M (PURELIFI_OFDM | PURELIFI_OFDM_PLCP_RATE_48M) +#define PURELIFI_OFDM_RATE_54M (PURELIFI_OFDM | PURELIFI_OFDM_PLCP_RATE_54M) + +#define PURELIFI_RX_ERROR 0x80 +#define PURELIFI_RX_CRC32_ERROR 0x10 + +#define PLF_REGDOMAIN_FCC 0x10 +#define PLF_REGDOMAIN_IC 0x20 +#define PLF_REGDOMAIN_ETSI 0x30 +#define PLF_REGDOMAIN_SPAIN 0x31 +#define PLF_REGDOMAIN_FRANCE 0x32 +#define PLF_REGDOMAIN_JAPAN_2 0x40 +#define PLF_REGDOMAIN_JAPAN 0x41 +#define PLF_REGDOMAIN_JAPAN_3 0x49 + +#define PLF_RX_ERROR 0x80 +#define PLF_RX_CRC32_ERROR 0x10 + +enum { + MODULATION_RATE_BPSK_1_2 = 0, + MODULATION_RATE_BPSK_3_4, + MODULATION_RATE_QPSK_1_2, + MODULATION_RATE_QPSK_3_4, + MODULATION_RATE_QAM16_1_2, + MODULATION_RATE_QAM16_3_4, + MODULATION_RATE_QAM64_1_2, + MODULATION_RATE_QAM64_3_4, + MODULATION_RATE_AUTO, + MODULATION_RATE_NUM +}; + +#define plfxlc_mac_dev(mac) plfxlc_chip_dev(&(mac)->chip) + +#define PURELIFI_MAC_STATS_BUFFER_SIZE 16 +#define PURELIFI_MAC_MAX_ACK_WAITERS 50 + +struct plfxlc_ctrlset { + /* id should be plf_usb_req_enum */ + __be32 id; + __be32 len; + u8 modulation; + u8 control; + u8 service; + u8 pad; + __le16 packet_length; + __le16 current_length; + __le16 next_frame_length; + __le16 tx_length; + __be32 payload_len_nw; +} __packed; + +/* overlay */ +struct plfxlc_header { + struct plfxlc_ctrlset plf_ctrl; + u32 frametype; + u8 *dmac; +} __packed; + +struct tx_status { + u8 type; + u8 id; + u8 rate; + u8 pad; + u8 mac[ETH_ALEN]; + u8 retry; + u8 failure; +} __packed; + +struct beacon { + struct delayed_work watchdog_work; + struct sk_buff *cur_beacon; + unsigned long last_update; + u16 interval; + u8 period; +}; + +enum plfxlc_device_flags { + PURELIFI_DEVICE_RUNNING, +}; + +struct plfxlc_mac { + struct ieee80211_hw *hw; + struct ieee80211_vif *vif; + struct beacon beacon; + struct work_struct set_rts_cts_work; + struct work_struct process_intr; + struct plfxlc_mc_hash multicast_hash; + struct sk_buff_head ack_wait_queue; + struct ieee80211_channel channels[14]; + struct ieee80211_rate rates[12]; + struct ieee80211_supported_band band; + struct plfxlc_chip chip; + spinlock_t lock; /* lock for mac data */ + u8 intr_buffer[USB_MAX_EP_INT_BUFFER]; + char serial_number[PURELIFI_SERIAL_LEN]; + unsigned char hw_address[ETH_ALEN]; + u8 default_regdomain; + unsigned long flags; + bool pass_failed_fcs; + bool pass_ctrl; + bool ack_pending; + int ack_signal; + int associated; + u8 regdomain; + u8 channel; + int type; + u64 crc_errors; + u64 rssi; +}; + +static inline struct plfxlc_mac * +plfxlc_hw_mac(struct ieee80211_hw *hw) +{ + return hw->priv; +} + +static inline struct plfxlc_mac * +plfxlc_chip_to_mac(struct plfxlc_chip *chip) +{ + return container_of(chip, struct plfxlc_mac, chip); +} + +static inline struct plfxlc_mac * +plfxlc_usb_to_mac(struct plfxlc_usb *usb) +{ + return plfxlc_chip_to_mac(plfxlc_usb_to_chip(usb)); +} + +static inline u8 *plfxlc_mac_get_perm_addr(struct plfxlc_mac *mac) +{ + return mac->hw->wiphy->perm_addr; +} + +struct ieee80211_hw *plfxlc_mac_alloc_hw(struct usb_interface *intf); +void plfxlc_mac_release(struct plfxlc_mac *mac); + +int plfxlc_mac_preinit_hw(struct ieee80211_hw *hw, const u8 *hw_address); +int plfxlc_mac_init_hw(struct ieee80211_hw *hw); + +int plfxlc_mac_rx(struct ieee80211_hw *hw, const u8 *buffer, + unsigned int length); +void plfxlc_mac_tx_failed(struct urb *urb); +void plfxlc_mac_tx_to_dev(struct sk_buff *skb, int error); +int plfxlc_op_start(struct ieee80211_hw *hw); +void plfxlc_op_stop(struct ieee80211_hw *hw); +int plfxlc_restore_settings(struct plfxlc_mac *mac); + +#endif /* PLFXLC_MAC_H */ diff --git a/drivers/net/wireless/purelifi/plfxlc/usb.c b/drivers/net/wireless/purelifi/plfxlc/usb.c new file mode 100644 index 0000000000000..6f338b1572a1c --- /dev/null +++ b/drivers/net/wireless/purelifi/plfxlc/usb.c @@ -0,0 +1,892 @@ +// SPDX-License-Identifier: GPL-2.0-only +/* + * Copyright (c) 2021 pureLiFi + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "mac.h" +#include "usb.h" +#include "chip.h" + +static const struct usb_device_id usb_ids[] = { + { USB_DEVICE(PURELIFI_X_VENDOR_ID_0, PURELIFI_X_PRODUCT_ID_0), + .driver_info = DEVICE_LIFI_X }, + { USB_DEVICE(PURELIFI_XC_VENDOR_ID_0, PURELIFI_XC_PRODUCT_ID_0), + .driver_info = DEVICE_LIFI_XC }, + { USB_DEVICE(PURELIFI_XL_VENDOR_ID_0, PURELIFI_XL_PRODUCT_ID_0), + .driver_info = DEVICE_LIFI_XL }, + {} +}; + +void plfxlc_send_packet_from_data_queue(struct plfxlc_usb *usb) +{ + struct plfxlc_usb_tx *tx = &usb->tx; + struct sk_buff *skb = NULL; + unsigned long flags; + u8 last_served_sidx; + + spin_lock_irqsave(&tx->lock, flags); + last_served_sidx = usb->sidx; + do { + usb->sidx = (usb->sidx + 1) % MAX_STA_NUM; + if (!(tx->station[usb->sidx].flag & STATION_CONNECTED_FLAG)) + continue; + if (!(tx->station[usb->sidx].flag & STATION_FIFO_FULL_FLAG)) + skb = skb_peek(&tx->station[usb->sidx].data_list); + } while ((usb->sidx != last_served_sidx) && (!skb)); + + if (skb) { + skb = skb_dequeue(&tx->station[usb->sidx].data_list); + plfxlc_usb_wreq_async(usb, skb->data, skb->len, USB_REQ_DATA_TX, + plfxlc_tx_urb_complete, skb); + if (skb_queue_len(&tx->station[usb->sidx].data_list) <= 60) + ieee80211_wake_queues(plfxlc_usb_to_hw(usb)); + } + spin_unlock_irqrestore(&tx->lock, flags); +} + +static void handle_rx_packet(struct plfxlc_usb *usb, const u8 *buffer, + unsigned int length) +{ + plfxlc_mac_rx(plfxlc_usb_to_hw(usb), buffer, length); +} + +static void rx_urb_complete(struct urb *urb) +{ + struct plfxlc_usb_tx *tx; + struct plfxlc_usb *usb; + unsigned int length; + const u8 *buffer; + u16 status; + u8 sidx; + int r; + + if (!urb) { + pr_err("urb is NULL\n"); + return; + } + if (!urb->context) { + pr_err("urb ctx is NULL\n"); + return; + } + usb = urb->context; + + if (usb->initialized != 1) { + pr_err("usb is not initialized\n"); + return; + } + + tx = &usb->tx; + switch (urb->status) { + case 0: + break; + case -ESHUTDOWN: + case -EINVAL: + case -ENODEV: + case -ENOENT: + case -ECONNRESET: + case -EPIPE: + dev_dbg(plfxlc_urb_dev(urb), "urb %p error %d\n", urb, urb->status); + return; + default: + dev_dbg(plfxlc_urb_dev(urb), "urb %p error %d\n", urb, urb->status); + if (tx->submitted_urbs++ < PURELIFI_URB_RETRY_MAX) { + dev_dbg(plfxlc_urb_dev(urb), "urb %p resubmit %d", urb, + tx->submitted_urbs++); + goto resubmit; + } else { + dev_dbg(plfxlc_urb_dev(urb), "urb %p max resubmits reached", urb); + tx->submitted_urbs = 0; + return; + } + } + + buffer = urb->transfer_buffer; + length = le32_to_cpu(*(__le32 *)(buffer + sizeof(struct rx_status))) + + sizeof(u32); + + if (urb->actual_length != (PLF_MSG_STATUS_OFFSET + 1)) { + if (usb->initialized && usb->link_up) + handle_rx_packet(usb, buffer, length); + goto resubmit; + } + + status = buffer[PLF_MSG_STATUS_OFFSET]; + + switch (status) { + case STATION_FIFO_ALMOST_FULL_NOT_MESSAGE: + dev_dbg(&usb->intf->dev, + "FIFO full not packet receipt\n"); + tx->mac_fifo_full = 1; + for (sidx = 0; sidx < MAX_STA_NUM; sidx++) + tx->station[sidx].flag |= STATION_FIFO_FULL_FLAG; + break; + case STATION_FIFO_ALMOST_FULL_MESSAGE: + dev_dbg(&usb->intf->dev, "FIFO full packet receipt\n"); + + for (sidx = 0; sidx < MAX_STA_NUM; sidx++) + tx->station[sidx].flag &= STATION_ACTIVE_FLAG; + + plfxlc_send_packet_from_data_queue(usb); + break; + case STATION_CONNECT_MESSAGE: + usb->link_up = 1; + dev_dbg(&usb->intf->dev, "ST_CONNECT_MSG packet receipt\n"); + break; + case STATION_DISCONNECT_MESSAGE: + usb->link_up = 0; + dev_dbg(&usb->intf->dev, "ST_DISCONN_MSG packet receipt\n"); + break; + default: + dev_dbg(&usb->intf->dev, "Unknown packet receipt\n"); + break; + } + +resubmit: + r = usb_submit_urb(urb, GFP_ATOMIC); + if (r) + dev_dbg(plfxlc_urb_dev(urb), "urb %p resubmit fail (%d)\n", urb, r); +} + +static struct urb *alloc_rx_urb(struct plfxlc_usb *usb) +{ + struct usb_device *udev = plfxlc_usb_to_usbdev(usb); + struct urb *urb; + void *buffer; + + urb = usb_alloc_urb(0, GFP_KERNEL); + if (!urb) + return NULL; + + buffer = usb_alloc_coherent(udev, USB_MAX_RX_SIZE, GFP_KERNEL, + &urb->transfer_dma); + if (!buffer) { + usb_free_urb(urb); + return NULL; + } + + usb_fill_bulk_urb(urb, udev, usb_rcvbulkpipe(udev, EP_DATA_IN), + buffer, USB_MAX_RX_SIZE, + rx_urb_complete, usb); + urb->transfer_flags |= URB_NO_TRANSFER_DMA_MAP; + + return urb; +} + +static void free_rx_urb(struct urb *urb) +{ + if (!urb) + return; + usb_free_coherent(urb->dev, urb->transfer_buffer_length, + urb->transfer_buffer, urb->transfer_dma); + usb_free_urb(urb); +} + +static int __lf_x_usb_enable_rx(struct plfxlc_usb *usb) +{ + struct plfxlc_usb_rx *rx = &usb->rx; + struct urb **urbs; + int i, r; + + r = -ENOMEM; + urbs = kcalloc(RX_URBS_COUNT, sizeof(struct urb *), GFP_KERNEL); + if (!urbs) + goto error; + + for (i = 0; i < RX_URBS_COUNT; i++) { + urbs[i] = alloc_rx_urb(usb); + if (!urbs[i]) + goto error; + } + + spin_lock_irq(&rx->lock); + + dev_dbg(plfxlc_usb_dev(usb), "irq_disabled %d\n", irqs_disabled()); + + if (rx->urbs) { + spin_unlock_irq(&rx->lock); + r = 0; + goto error; + } + rx->urbs = urbs; + rx->urbs_count = RX_URBS_COUNT; + spin_unlock_irq(&rx->lock); + + for (i = 0; i < RX_URBS_COUNT; i++) { + r = usb_submit_urb(urbs[i], GFP_KERNEL); + if (r) + goto error_submit; + } + + return 0; + +error_submit: + for (i = 0; i < RX_URBS_COUNT; i++) + usb_kill_urb(urbs[i]); + spin_lock_irq(&rx->lock); + rx->urbs = NULL; + rx->urbs_count = 0; + spin_unlock_irq(&rx->lock); +error: + if (urbs) { + for (i = 0; i < RX_URBS_COUNT; i++) + free_rx_urb(urbs[i]); + } + return r; +} + +int plfxlc_usb_enable_rx(struct plfxlc_usb *usb) +{ + struct plfxlc_usb_rx *rx = &usb->rx; + int r; + + mutex_lock(&rx->setup_mutex); + r = __lf_x_usb_enable_rx(usb); + if (!r) + usb->rx_usb_enabled = 1; + + mutex_unlock(&rx->setup_mutex); + + return r; +} + +static void __lf_x_usb_disable_rx(struct plfxlc_usb *usb) +{ + struct plfxlc_usb_rx *rx = &usb->rx; + unsigned long flags; + unsigned int count; + struct urb **urbs; + int i; + + spin_lock_irqsave(&rx->lock, flags); + urbs = rx->urbs; + count = rx->urbs_count; + spin_unlock_irqrestore(&rx->lock, flags); + + if (!urbs) + return; + + for (i = 0; i < count; i++) { + usb_kill_urb(urbs[i]); + free_rx_urb(urbs[i]); + } + kfree(urbs); + rx->urbs = NULL; + rx->urbs_count = 0; +} + +void plfxlc_usb_disable_rx(struct plfxlc_usb *usb) +{ + struct plfxlc_usb_rx *rx = &usb->rx; + + mutex_lock(&rx->setup_mutex); + __lf_x_usb_disable_rx(usb); + usb->rx_usb_enabled = 0; + mutex_unlock(&rx->setup_mutex); +} + +void plfxlc_usb_disable_tx(struct plfxlc_usb *usb) +{ + struct plfxlc_usb_tx *tx = &usb->tx; + unsigned long flags; + + clear_bit(PLF_BIT_ENABLED, &tx->enabled); + + /* kill all submitted tx-urbs */ + usb_kill_anchored_urbs(&tx->submitted); + + spin_lock_irqsave(&tx->lock, flags); + WARN_ON(!skb_queue_empty(&tx->submitted_skbs)); + WARN_ON(tx->submitted_urbs != 0); + tx->submitted_urbs = 0; + spin_unlock_irqrestore(&tx->lock, flags); + + /* The stopped state is ignored, relying on ieee80211_wake_queues() + * in a potentionally following plfxlc_usb_enable_tx(). + */ +} + +void plfxlc_usb_enable_tx(struct plfxlc_usb *usb) +{ + struct plfxlc_usb_tx *tx = &usb->tx; + unsigned long flags; + + spin_lock_irqsave(&tx->lock, flags); + set_bit(PLF_BIT_ENABLED, &tx->enabled); + tx->submitted_urbs = 0; + ieee80211_wake_queues(plfxlc_usb_to_hw(usb)); + tx->stopped = 0; + spin_unlock_irqrestore(&tx->lock, flags); +} + +void plfxlc_tx_urb_complete(struct urb *urb) +{ + struct ieee80211_tx_info *info; + struct plfxlc_usb *usb; + struct sk_buff *skb; + + skb = urb->context; + info = IEEE80211_SKB_CB(skb); + /* grab 'usb' pointer before handing off the skb (since + * it might be freed by plfxlc_mac_tx_to_dev or mac80211) + */ + usb = &plfxlc_hw_mac(info->rate_driver_data[0])->chip.usb; + + switch (urb->status) { + case 0: + break; + case -ESHUTDOWN: + case -EINVAL: + case -ENODEV: + case -ENOENT: + case -ECONNRESET: + case -EPIPE: + dev_dbg(plfxlc_urb_dev(urb), "urb %p error %d\n", urb, urb->status); + break; + default: + dev_dbg(plfxlc_urb_dev(urb), "urb %p error %d\n", urb, urb->status); + return; + } + + plfxlc_mac_tx_to_dev(skb, urb->status); + plfxlc_send_packet_from_data_queue(usb); + usb_free_urb(urb); +} + +static inline void init_usb_rx(struct plfxlc_usb *usb) +{ + struct plfxlc_usb_rx *rx = &usb->rx; + + spin_lock_init(&rx->lock); + mutex_init(&rx->setup_mutex); + + if (interface_to_usbdev(usb->intf)->speed == USB_SPEED_HIGH) + rx->usb_packet_size = 512; + else + rx->usb_packet_size = 64; + + if (rx->fragment_length != 0) + dev_dbg(plfxlc_usb_dev(usb), "fragment_length error\n"); +} + +static inline void init_usb_tx(struct plfxlc_usb *usb) +{ + struct plfxlc_usb_tx *tx = &usb->tx; + + spin_lock_init(&tx->lock); + clear_bit(PLF_BIT_ENABLED, &tx->enabled); + tx->stopped = 0; + skb_queue_head_init(&tx->submitted_skbs); + init_usb_anchor(&tx->submitted); +} + +void plfxlc_usb_init(struct plfxlc_usb *usb, struct ieee80211_hw *hw, + struct usb_interface *intf) +{ + memset(usb, 0, sizeof(*usb)); + usb->intf = usb_get_intf(intf); + usb_set_intfdata(usb->intf, hw); + init_usb_tx(usb); + init_usb_rx(usb); +} + +void plfxlc_usb_release(struct plfxlc_usb *usb) +{ + plfxlc_op_stop(plfxlc_usb_to_hw(usb)); + plfxlc_usb_disable_tx(usb); + plfxlc_usb_disable_rx(usb); + usb_set_intfdata(usb->intf, NULL); + usb_put_intf(usb->intf); +} + +const char *plfxlc_speed(enum usb_device_speed speed) +{ + switch (speed) { + case USB_SPEED_LOW: + return "low"; + case USB_SPEED_FULL: + return "full"; + case USB_SPEED_HIGH: + return "high"; + default: + return "unknown"; + } +} + +int plfxlc_usb_init_hw(struct plfxlc_usb *usb) +{ + int r; + + r = usb_reset_configuration(plfxlc_usb_to_usbdev(usb)); + if (r) { + dev_err(plfxlc_usb_dev(usb), "cfg reset failed (%d)\n", r); + return r; + } + return 0; +} + +static void get_usb_req(struct usb_device *udev, void *buffer, + u32 buffer_len, enum plf_usb_req_enum usb_req_id, + struct plf_usb_req *usb_req) +{ + __be32 payload_len_nw = cpu_to_be32(buffer_len + FCS_LEN); + const u8 *buffer_src_p = buffer; + u8 *buffer_dst = usb_req->buf; + u32 temp_usb_len = 0; + + usb_req->id = cpu_to_be32(usb_req_id); + usb_req->len = cpu_to_be32(0); + + /* Copy buffer length into the transmitted buffer, as it is important + * for the Rx MAC to know its exact length. + */ + if (usb_req->id == cpu_to_be32(USB_REQ_BEACON_WR)) { + memcpy(buffer_dst, &payload_len_nw, sizeof(payload_len_nw)); + buffer_dst += sizeof(payload_len_nw); + temp_usb_len += sizeof(payload_len_nw); + } + + memcpy(buffer_dst, buffer_src_p, buffer_len); + buffer_dst += buffer_len; + buffer_src_p += buffer_len; + temp_usb_len += buffer_len; + + /* Set the FCS_LEN (4) bytes as 0 for CRC checking. */ + memset(buffer_dst, 0, FCS_LEN); + buffer_dst += FCS_LEN; + temp_usb_len += FCS_LEN; + + /* Round the packet to be transmitted to 4 bytes. */ + if (temp_usb_len % PURELIFI_BYTE_NUM_ALIGNMENT) { + memset(buffer_dst, 0, PURELIFI_BYTE_NUM_ALIGNMENT - + (temp_usb_len % + PURELIFI_BYTE_NUM_ALIGNMENT)); + buffer_dst += PURELIFI_BYTE_NUM_ALIGNMENT - + (temp_usb_len % + PURELIFI_BYTE_NUM_ALIGNMENT); + temp_usb_len += PURELIFI_BYTE_NUM_ALIGNMENT - + (temp_usb_len % PURELIFI_BYTE_NUM_ALIGNMENT); + } + + usb_req->len = cpu_to_be32(temp_usb_len); +} + +int plfxlc_usb_wreq_async(struct plfxlc_usb *usb, const u8 *buffer, + int buffer_len, enum plf_usb_req_enum usb_req_id, + usb_complete_t complete_fn, + void *context) +{ + struct usb_device *udev = interface_to_usbdev(usb->ez_usb); + struct urb *urb = usb_alloc_urb(0, GFP_ATOMIC); + int r; + + usb_fill_bulk_urb(urb, udev, usb_sndbulkpipe(udev, EP_DATA_OUT), + (void *)buffer, buffer_len, complete_fn, context); + + r = usb_submit_urb(urb, GFP_ATOMIC); + if (r) + dev_err(&udev->dev, "Async write submit failed (%d)\n", r); + + return r; +} + +int plfxlc_usb_wreq(struct usb_interface *ez_usb, void *buffer, int buffer_len, + enum plf_usb_req_enum usb_req_id) +{ + struct usb_device *udev = interface_to_usbdev(ez_usb); + unsigned char *dma_buffer = NULL; + struct plf_usb_req usb_req; + int usb_bulk_msg_len; + int actual_length; + int r; + + get_usb_req(udev, buffer, buffer_len, usb_req_id, &usb_req); + usb_bulk_msg_len = sizeof(__le32) + sizeof(__le32) + + be32_to_cpu(usb_req.len); + + dma_buffer = kmemdup(&usb_req, usb_bulk_msg_len, GFP_KERNEL); + + if (!dma_buffer) { + r = -ENOMEM; + goto error; + } + + r = usb_bulk_msg(udev, + usb_sndbulkpipe(udev, EP_DATA_OUT), + dma_buffer, usb_bulk_msg_len, + &actual_length, USB_BULK_MSG_TIMEOUT_MS); + kfree(dma_buffer); +error: + if (r) { + r = -ENOMEM; + dev_err(&udev->dev, "usb_bulk_msg failed (%d)\n", r); + } + + return r; +} + +static void slif_data_plane_sap_timer_callb(struct timer_list *t) +{ + struct plfxlc_usb *usb = from_timer(usb, t, tx.tx_retry_timer); + + plfxlc_send_packet_from_data_queue(usb); + timer_setup(&usb->tx.tx_retry_timer, + slif_data_plane_sap_timer_callb, 0); + mod_timer(&usb->tx.tx_retry_timer, jiffies + TX_RETRY_BACKOFF_JIFF); +} + +static void sta_queue_cleanup_timer_callb(struct timer_list *t) +{ + struct plfxlc_usb *usb = from_timer(usb, t, sta_queue_cleanup); + struct plfxlc_usb_tx *tx = &usb->tx; + int sidx; + + for (sidx = 0; sidx < MAX_STA_NUM - 1; sidx++) { + if (!(tx->station[sidx].flag & STATION_CONNECTED_FLAG)) + continue; + if (tx->station[sidx].flag & STATION_HEARTBEAT_FLAG) { + tx->station[sidx].flag ^= STATION_HEARTBEAT_FLAG; + } else { + memset(tx->station[sidx].mac, 0, ETH_ALEN); + tx->station[sidx].flag = 0; + } + } + timer_setup(&usb->sta_queue_cleanup, + sta_queue_cleanup_timer_callb, 0); + mod_timer(&usb->sta_queue_cleanup, jiffies + STA_QUEUE_CLEANUP_JIFF); +} + +static int probe(struct usb_interface *intf, + const struct usb_device_id *id) +{ + u8 serial_number[PURELIFI_SERIAL_LEN]; + struct ieee80211_hw *hw = NULL; + struct plfxlc_usb_tx *tx; + struct plfxlc_chip *chip; + struct plfxlc_usb *usb; + u8 hw_address[ETH_ALEN]; + unsigned int i; + int r = 0; + + hw = plfxlc_mac_alloc_hw(intf); + + if (!hw) { + r = -ENOMEM; + goto error; + } + + chip = &plfxlc_hw_mac(hw)->chip; + usb = &chip->usb; + usb->ez_usb = intf; + tx = &usb->tx; + + r = plfxlc_upload_mac_and_serial(intf, hw_address, serial_number); + if (r) { + dev_err(&intf->dev, "MAC and Serial upload failed (%d)\n", r); + goto error; + } + + chip->unit_type = STA; + dev_err(&intf->dev, "Unit type is station"); + + r = plfxlc_mac_preinit_hw(hw, hw_address); + if (r) { + dev_err(&intf->dev, "Init mac failed (%d)\n", r); + goto error; + } + + r = ieee80211_register_hw(hw); + if (r) { + dev_err(&intf->dev, "Register device failed (%d)\n", r); + goto error; + } + + if ((le16_to_cpu(interface_to_usbdev(intf)->descriptor.idVendor) == + PURELIFI_XL_VENDOR_ID_0) && + (le16_to_cpu(interface_to_usbdev(intf)->descriptor.idProduct) == + PURELIFI_XL_PRODUCT_ID_0)) { + r = plfxlc_download_xl_firmware(intf); + } else { + r = plfxlc_download_fpga(intf); + } + if (r != 0) { + dev_err(&intf->dev, "FPGA download failed (%d)\n", r); + goto error; + } + + tx->mac_fifo_full = 0; + spin_lock_init(&tx->lock); + + msleep(PLF_MSLEEP_TIME); + r = plfxlc_usb_init_hw(usb); + if (r < 0) { + dev_err(&intf->dev, "usb_init_hw failed (%d)\n", r); + goto error; + } + + msleep(PLF_MSLEEP_TIME); + r = plfxlc_chip_switch_radio(chip, PLFXLC_RADIO_ON); + if (r < 0) { + dev_dbg(&intf->dev, "chip_switch_radio_on failed (%d)\n", r); + goto error; + } + + msleep(PLF_MSLEEP_TIME); + r = plfxlc_chip_set_rate(chip, 8); + if (r < 0) { + dev_dbg(&intf->dev, "chip_set_rate failed (%d)\n", r); + goto error; + } + + msleep(PLF_MSLEEP_TIME); + r = plfxlc_usb_wreq(usb->ez_usb, + hw_address, ETH_ALEN, USB_REQ_MAC_WR); + if (r < 0) { + dev_dbg(&intf->dev, "MAC_WR failure (%d)\n", r); + goto error; + } + + plfxlc_chip_enable_rxtx(chip); + + /* Initialise the data plane Tx queue */ + for (i = 0; i < MAX_STA_NUM; i++) { + skb_queue_head_init(&tx->station[i].data_list); + tx->station[i].flag = 0; + } + + tx->station[STA_BROADCAST_INDEX].flag |= STATION_CONNECTED_FLAG; + for (i = 0; i < ETH_ALEN; i++) + tx->station[STA_BROADCAST_INDEX].mac[i] = 0xFF; + + timer_setup(&tx->tx_retry_timer, slif_data_plane_sap_timer_callb, 0); + tx->tx_retry_timer.expires = jiffies + TX_RETRY_BACKOFF_JIFF; + add_timer(&tx->tx_retry_timer); + + timer_setup(&usb->sta_queue_cleanup, + sta_queue_cleanup_timer_callb, 0); + usb->sta_queue_cleanup.expires = jiffies + STA_QUEUE_CLEANUP_JIFF; + add_timer(&usb->sta_queue_cleanup); + + plfxlc_mac_init_hw(hw); + usb->initialized = true; + return 0; +error: + if (hw) { + plfxlc_mac_release(plfxlc_hw_mac(hw)); + ieee80211_unregister_hw(hw); + ieee80211_free_hw(hw); + } + dev_err(&intf->dev, "pureLifi:Device error"); + return r; +} + +static void disconnect(struct usb_interface *intf) +{ + struct ieee80211_hw *hw = plfxlc_intf_to_hw(intf); + struct plfxlc_mac *mac; + struct plfxlc_usb *usb; + + /* Either something really bad happened, or + * we're just dealing with a DEVICE_INSTALLER. + */ + if (!hw) + return; + + mac = plfxlc_hw_mac(hw); + usb = &mac->chip.usb; + + del_timer_sync(&usb->tx.tx_retry_timer); + del_timer_sync(&usb->sta_queue_cleanup); + + ieee80211_unregister_hw(hw); + + plfxlc_chip_disable_rxtx(&mac->chip); + + /* If the disconnect has been caused by a removal of the + * driver module, the reset allows reloading of the driver. If the + * reset will not be executed here, the upload of the firmware in the + * probe function caused by the reloading of the driver will fail. + */ + usb_reset_device(interface_to_usbdev(intf)); + + plfxlc_mac_release(mac); + ieee80211_free_hw(hw); +} + +static void plfxlc_usb_resume(struct plfxlc_usb *usb) +{ + struct plfxlc_mac *mac = plfxlc_usb_to_mac(usb); + int r; + + r = plfxlc_op_start(plfxlc_usb_to_hw(usb)); + if (r < 0) { + dev_warn(plfxlc_usb_dev(usb), + "Device resume failed (%d)\n", r); + + if (usb->was_running) + set_bit(PURELIFI_DEVICE_RUNNING, &mac->flags); + + usb_queue_reset_device(usb->intf); + return; + } + + if (mac->type != NL80211_IFTYPE_UNSPECIFIED) { + r = plfxlc_restore_settings(mac); + if (r < 0) { + dev_dbg(plfxlc_usb_dev(usb), + "Restore failed (%d)\n", r); + return; + } + } +} + +static void plfxlc_usb_stop(struct plfxlc_usb *usb) +{ + plfxlc_op_stop(plfxlc_usb_to_hw(usb)); + plfxlc_usb_disable_tx(usb); + plfxlc_usb_disable_rx(usb); + + usb->initialized = false; +} + +static int pre_reset(struct usb_interface *intf) +{ + struct ieee80211_hw *hw = usb_get_intfdata(intf); + struct plfxlc_mac *mac; + struct plfxlc_usb *usb; + + if (!hw || intf->condition != USB_INTERFACE_BOUND) + return 0; + + mac = plfxlc_hw_mac(hw); + usb = &mac->chip.usb; + + usb->was_running = test_bit(PURELIFI_DEVICE_RUNNING, &mac->flags); + + plfxlc_usb_stop(usb); + + return 0; +} + +static int post_reset(struct usb_interface *intf) +{ + struct ieee80211_hw *hw = usb_get_intfdata(intf); + struct plfxlc_mac *mac; + struct plfxlc_usb *usb; + + if (!hw || intf->condition != USB_INTERFACE_BOUND) + return 0; + + mac = plfxlc_hw_mac(hw); + usb = &mac->chip.usb; + + if (usb->was_running) + plfxlc_usb_resume(usb); + + return 0; +} + +#ifdef CONFIG_PM + +static struct plfxlc_usb *get_plfxlc_usb(struct usb_interface *intf) +{ + struct ieee80211_hw *hw = plfxlc_intf_to_hw(intf); + struct plfxlc_mac *mac; + + /* Either something really bad happened, or + * we're just dealing with a DEVICE_INSTALLER. + */ + if (!hw) + return NULL; + + mac = plfxlc_hw_mac(hw); + return &mac->chip.usb; +} + +static int suspend(struct usb_interface *interface, + pm_message_t message) +{ + struct plfxlc_usb *pl = get_plfxlc_usb(interface); + struct plfxlc_mac *mac = plfxlc_usb_to_mac(pl); + + if (!pl || !plfxlc_usb_dev(pl)) + return -ENODEV; + if (pl->initialized == 0) + return 0; + pl->was_running = test_bit(PURELIFI_DEVICE_RUNNING, &mac->flags); + plfxlc_usb_stop(pl); + return 0; +} + +static int resume(struct usb_interface *interface) +{ + struct plfxlc_usb *pl = get_plfxlc_usb(interface); + + if (!pl || !plfxlc_usb_dev(pl)) + return -ENODEV; + if (pl->was_running) + plfxlc_usb_resume(pl); + return 0; +} + +#endif + +static struct usb_driver driver = { + .name = KBUILD_MODNAME, + .id_table = usb_ids, + .probe = probe, + .disconnect = disconnect, + .pre_reset = pre_reset, + .post_reset = post_reset, +#ifdef CONFIG_PM + .suspend = suspend, + .resume = resume, +#endif + .disable_hub_initiated_lpm = 1, +}; + +static int __init usb_init(void) +{ + int r; + + r = usb_register(&driver); + if (r) { + pr_err("%s usb_register() failed %d\n", driver.name, r); + return r; + } + + pr_debug("Driver initialized :%s\n", driver.name); + return 0; +} + +static void __exit usb_exit(void) +{ + usb_deregister(&driver); + pr_debug("%s %s\n", driver.name, __func__); +} + +MODULE_LICENSE("GPL"); +MODULE_DESCRIPTION("USB driver for pureLiFi devices"); +MODULE_AUTHOR("pureLiFi"); +MODULE_VERSION("1.0"); +MODULE_FIRMWARE("plfxlc/lifi-x.bin"); +MODULE_DEVICE_TABLE(usb, usb_ids); + +module_init(usb_init); +module_exit(usb_exit); diff --git a/drivers/net/wireless/purelifi/plfxlc/usb.h b/drivers/net/wireless/purelifi/plfxlc/usb.h new file mode 100644 index 0000000000000..ba2defd593bdb --- /dev/null +++ b/drivers/net/wireless/purelifi/plfxlc/usb.h @@ -0,0 +1,198 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ +/* + * Copyright (c) 2021 pureLiFi + */ + +#ifndef PLFXLC_USB_H +#define PLFXLC_USB_H + +#include +#include +#include +#include +#include + +#include "intf.h" + +#define USB_BULK_MSG_TIMEOUT_MS 2000 + +#define PURELIFI_X_VENDOR_ID_0 0x16C1 +#define PURELIFI_X_PRODUCT_ID_0 0x1CDE +#define PURELIFI_XC_VENDOR_ID_0 0x2EF5 +#define PURELIFI_XC_PRODUCT_ID_0 0x0008 +#define PURELIFI_XL_VENDOR_ID_0 0x2EF5 +#define PURELIFI_XL_PRODUCT_ID_0 0x000A /* Station */ + +#define PLF_FPGA_STATUS_LEN 2 +#define PLF_FPGA_STATE_LEN 9 +#define PLF_BULK_TLEN 16384 +#define PLF_FPGA_MG 6 /* Magic check */ +#define PLF_XL_BUF_LEN 64 +#define PLF_MSG_STATUS_OFFSET 7 + +#define PLF_USB_TIMEOUT 1000 +#define PLF_MSLEEP_TIME 200 + +#define PURELIFI_URB_RETRY_MAX 5 + +#define plfxlc_usb_dev(usb) (&(usb)->intf->dev) + +/* Tx retry backoff timer (in milliseconds) */ +#define TX_RETRY_BACKOFF_MS 10 +#define STA_QUEUE_CLEANUP_MS 5000 + +/* Tx retry backoff timer (in jiffies) */ +#define TX_RETRY_BACKOFF_JIFF ((TX_RETRY_BACKOFF_MS * HZ) / 1000) +#define STA_QUEUE_CLEANUP_JIFF ((STA_QUEUE_CLEANUP_MS * HZ) / 1000) + +/* Ensures that MAX_TRANSFER_SIZE is even. */ +#define MAX_TRANSFER_SIZE (USB_MAX_TRANSFER_SIZE & ~1) +#define plfxlc_urb_dev(urb) (&(urb)->dev->dev) + +#define STATION_FIFO_ALMOST_FULL_MESSAGE 0 +#define STATION_FIFO_ALMOST_FULL_NOT_MESSAGE 1 +#define STATION_CONNECT_MESSAGE 2 +#define STATION_DISCONNECT_MESSAGE 3 + +int plfxlc_usb_wreq(struct usb_interface *ez_usb, void *buffer, int buffer_len, + enum plf_usb_req_enum usb_req_id); +void plfxlc_tx_urb_complete(struct urb *urb); + +enum { + USB_MAX_RX_SIZE = 4800, + USB_MAX_EP_INT_BUFFER = 64, +}; + +struct plfxlc_usb_interrupt { + spinlock_t lock; /* spin lock for usb interrupt buffer */ + struct urb *urb; + void *buffer; + int interval; +}; + +#define RX_URBS_COUNT 5 + +struct plfxlc_usb_rx { + spinlock_t lock; /* spin lock for rx urb */ + struct mutex setup_mutex; /* mutex lockt for rx urb */ + u8 fragment[2 * USB_MAX_RX_SIZE]; + unsigned int fragment_length; + unsigned int usb_packet_size; + struct urb **urbs; + int urbs_count; +}; + +struct plf_station { + /* 7...3 | 2 | 1 | 0 | + * Reserved | Heartbeat | FIFO full | Connected | + */ + unsigned char flag; + unsigned char mac[ETH_ALEN]; + struct sk_buff_head data_list; +}; + +struct plfxlc_firmware_file { + u32 total_files; + u32 total_size; + u32 size; + u32 start_addr; + u32 control_packets; +} __packed; + +#define STATION_CONNECTED_FLAG 0x1 +#define STATION_FIFO_FULL_FLAG 0x2 +#define STATION_HEARTBEAT_FLAG 0x4 +#define STATION_ACTIVE_FLAG 0xFD + +#define PURELIFI_SERIAL_LEN 256 +#define STA_BROADCAST_INDEX (AP_USER_LIMIT) +#define MAX_STA_NUM (AP_USER_LIMIT + 1) + +struct plfxlc_usb_tx { + unsigned long enabled; + spinlock_t lock; /* spinlock for USB tx */ + u8 mac_fifo_full; + struct sk_buff_head submitted_skbs; + struct usb_anchor submitted; + int submitted_urbs; + bool stopped; + struct timer_list tx_retry_timer; + struct plf_station station[MAX_STA_NUM]; +}; + +/* Contains the usb parts. The structure doesn't require a lock because intf + * will not be changed after initialization. + */ +struct plfxlc_usb { + struct timer_list sta_queue_cleanup; + struct plfxlc_usb_rx rx; + struct plfxlc_usb_tx tx; + struct usb_interface *intf; + struct usb_interface *ez_usb; + u8 req_buf[64]; /* plfxlc_usb_iowrite16v needs 62 bytes */ + u8 sidx; /* store last served */ + bool rx_usb_enabled; + bool initialized; + bool was_running; + bool link_up; +}; + +enum endpoints { + EP_DATA_IN = 2, + EP_DATA_OUT = 8, +}; + +enum devicetype { + DEVICE_LIFI_X = 0, + DEVICE_LIFI_XC = 1, + DEVICE_LIFI_XL = 1, +}; + +enum { + PLF_BIT_ENABLED = 1, + PLF_BIT_MAX = 2, +}; + +int plfxlc_usb_wreq_async(struct plfxlc_usb *usb, const u8 *buffer, + int buffer_len, enum plf_usb_req_enum usb_req_id, + usb_complete_t complete_fn, void *context); + +static inline struct usb_device * +plfxlc_usb_to_usbdev(struct plfxlc_usb *usb) +{ + return interface_to_usbdev(usb->intf); +} + +static inline struct ieee80211_hw * +plfxlc_intf_to_hw(struct usb_interface *intf) +{ + return usb_get_intfdata(intf); +} + +static inline struct ieee80211_hw * +plfxlc_usb_to_hw(struct plfxlc_usb *usb) +{ + return plfxlc_intf_to_hw(usb->intf); +} + +void plfxlc_usb_init(struct plfxlc_usb *usb, struct ieee80211_hw *hw, + struct usb_interface *intf); +void plfxlc_send_packet_from_data_queue(struct plfxlc_usb *usb); +void plfxlc_usb_release(struct plfxlc_usb *usb); +void plfxlc_usb_disable_rx(struct plfxlc_usb *usb); +void plfxlc_usb_enable_tx(struct plfxlc_usb *usb); +void plfxlc_usb_disable_tx(struct plfxlc_usb *usb); +int plfxlc_usb_tx(struct plfxlc_usb *usb, struct sk_buff *skb); +int plfxlc_usb_enable_rx(struct plfxlc_usb *usb); +int plfxlc_usb_init_hw(struct plfxlc_usb *usb); +const char *plfxlc_speed(enum usb_device_speed speed); + +/* Firmware declarations */ +int plfxlc_download_xl_firmware(struct usb_interface *intf); +int plfxlc_download_fpga(struct usb_interface *intf); + +int plfxlc_upload_mac_and_serial(struct usb_interface *intf, + unsigned char *hw_address, + unsigned char *serial_number); + +#endif /* PLFXLC_USB_H */ From 255ca28a659d3cfb069f73c7644853ed93aecdb0 Mon Sep 17 00:00:00 2001 From: Andrejs Cainikovs Date: Fri, 22 Apr 2022 11:03:12 +0200 Subject: [PATCH 184/228] mwifiex: Select firmware based on strapping MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Some WiFi/Bluetooth modules might have different host connection options, allowing to either use SDIO for both WiFi and Bluetooth, or SDIO for WiFi and UART for Bluetooth. It is possible to detect whether a module has SDIO-SDIO or SDIO-UART connection by reading its host strap register. This change introduces a way to automatically select appropriate firmware depending of the connection method, and removes a need of symlinking or overwriting the original firmware file with a required one. Host strap register used in this commit comes from the NXP driver [1] hosted at Code Aurora. [1] https://source.codeaurora.org/external/imx/linux-imx/tree/drivers/net/wireless/nxp/mxm_wifiex/wlan_src/mlinux/moal_sdio_mmc.c?h=rel_imx_5.4.70_2.3.2&id=688b67b2c7220b01521ffe560da7eee33042c7bd#n1274 Signed-off-by: Andrejs Cainikovs Reviewed-by: Alvin Šipraga Signed-off-by: Kalle Valo Link: https://lore.kernel.org/r/20220422090313.125857-2-andrejs.cainikovs@toradex.com --- drivers/net/wireless/marvell/mwifiex/sdio.c | 21 ++++++++++++++++++++- drivers/net/wireless/marvell/mwifiex/sdio.h | 5 +++++ 2 files changed, 25 insertions(+), 1 deletion(-) diff --git a/drivers/net/wireless/marvell/mwifiex/sdio.c b/drivers/net/wireless/marvell/mwifiex/sdio.c index bde9e4bbfffe7..ae85118481eee 100644 --- a/drivers/net/wireless/marvell/mwifiex/sdio.c +++ b/drivers/net/wireless/marvell/mwifiex/sdio.c @@ -182,6 +182,9 @@ static const struct mwifiex_sdio_card_reg mwifiex_reg_sd8997 = { .host_int_rsr_reg = 0x4, .host_int_status_reg = 0x0C, .host_int_mask_reg = 0x08, + .host_strap_reg = 0xF4, + .host_strap_mask = 0x01, + .host_strap_value = 0x00, .status_reg_0 = 0xE8, .status_reg_1 = 0xE9, .sdio_int_mask = 0xff, @@ -283,6 +286,9 @@ static const struct mwifiex_sdio_card_reg mwifiex_reg_sd8987 = { .host_int_rsr_reg = 0x4, .host_int_status_reg = 0x0C, .host_int_mask_reg = 0x08, + .host_strap_reg = 0xF4, + .host_strap_mask = 0x01, + .host_strap_value = 0x00, .status_reg_0 = 0xE8, .status_reg_1 = 0xE9, .sdio_int_mask = 0xff, @@ -536,6 +542,7 @@ mwifiex_sdio_probe(struct sdio_func *func, const struct sdio_device_id *id) struct mwifiex_sdio_device *data = (void *)id->driver_data; card->firmware = data->firmware; + card->firmware_sdiouart = data->firmware_sdiouart; card->reg = data->reg; card->max_ports = data->max_ports; card->mp_agg_pkt_limit = data->mp_agg_pkt_limit; @@ -2439,6 +2446,7 @@ static int mwifiex_register_dev(struct mwifiex_adapter *adapter) int ret; struct sdio_mmc_card *card = adapter->card; struct sdio_func *func = card->func; + const char *firmware = card->firmware; /* save adapter pointer in card */ card->adapter = adapter; @@ -2455,7 +2463,18 @@ static int mwifiex_register_dev(struct mwifiex_adapter *adapter) return ret; } - strcpy(adapter->fw_name, card->firmware); + /* Select correct firmware (sdsd or sdiouart) firmware based on the strapping + * option + */ + if (card->firmware_sdiouart) { + u8 val; + + mwifiex_read_reg(adapter, card->reg->host_strap_reg, &val); + if ((val & card->reg->host_strap_mask) == card->reg->host_strap_value) + firmware = card->firmware_sdiouart; + } + strcpy(adapter->fw_name, firmware); + if (card->fw_dump_enh) { adapter->mem_type_mapping_tbl = generic_mem_type_map; adapter->num_mem_types = 1; diff --git a/drivers/net/wireless/marvell/mwifiex/sdio.h b/drivers/net/wireless/marvell/mwifiex/sdio.h index 5648512c9300a..ad2c28cbb6305 100644 --- a/drivers/net/wireless/marvell/mwifiex/sdio.h +++ b/drivers/net/wireless/marvell/mwifiex/sdio.h @@ -196,6 +196,9 @@ struct mwifiex_sdio_card_reg { u8 host_int_rsr_reg; u8 host_int_status_reg; u8 host_int_mask_reg; + u8 host_strap_reg; + u8 host_strap_mask; + u8 host_strap_value; u8 status_reg_0; u8 status_reg_1; u8 sdio_int_mask; @@ -241,6 +244,7 @@ struct sdio_mmc_card { struct completion fw_done; const char *firmware; + const char *firmware_sdiouart; const struct mwifiex_sdio_card_reg *reg; u8 max_ports; u8 mp_agg_pkt_limit; @@ -274,6 +278,7 @@ struct sdio_mmc_card { struct mwifiex_sdio_device { const char *firmware; + const char *firmware_sdiouart; const struct mwifiex_sdio_card_reg *reg; u8 max_ports; u8 mp_agg_pkt_limit; From 562354ab9f0aa4fcd8f2184506dcb9c18a792182 Mon Sep 17 00:00:00 2001 From: Andrejs Cainikovs Date: Fri, 22 Apr 2022 11:03:13 +0200 Subject: [PATCH 185/228] mwifiex: Add SD8997 SDIO-UART firmware With a recent change now it is possible to detect the strapping option on SD8997, which allows to pick up a correct firmware for either SDIO-SDIO or SDIO-UART. This commit enables SDIO-UART firmware on SD8997. Signed-off-by: Andrejs Cainikovs Signed-off-by: Kalle Valo Link: https://lore.kernel.org/r/20220422090313.125857-3-andrejs.cainikovs@toradex.com --- drivers/net/wireless/marvell/mwifiex/sdio.c | 2 ++ drivers/net/wireless/marvell/mwifiex/sdio.h | 1 + 2 files changed, 3 insertions(+) diff --git a/drivers/net/wireless/marvell/mwifiex/sdio.c b/drivers/net/wireless/marvell/mwifiex/sdio.c index ae85118481eee..e931672bb836f 100644 --- a/drivers/net/wireless/marvell/mwifiex/sdio.c +++ b/drivers/net/wireless/marvell/mwifiex/sdio.c @@ -408,6 +408,7 @@ static const struct mwifiex_sdio_device mwifiex_sdio_sd8977 = { static const struct mwifiex_sdio_device mwifiex_sdio_sd8997 = { .firmware = SD8997_DEFAULT_FW_NAME, + .firmware_sdiouart = SD8997_SDIOUART_FW_NAME, .reg = &mwifiex_reg_sd8997, .max_ports = 32, .mp_agg_pkt_limit = 16, @@ -3176,3 +3177,4 @@ MODULE_FIRMWARE(SD8887_DEFAULT_FW_NAME); MODULE_FIRMWARE(SD8977_DEFAULT_FW_NAME); MODULE_FIRMWARE(SD8987_DEFAULT_FW_NAME); MODULE_FIRMWARE(SD8997_DEFAULT_FW_NAME); +MODULE_FIRMWARE(SD8997_SDIOUART_FW_NAME); diff --git a/drivers/net/wireless/marvell/mwifiex/sdio.h b/drivers/net/wireless/marvell/mwifiex/sdio.h index ad2c28cbb6305..28e8f76bdd589 100644 --- a/drivers/net/wireless/marvell/mwifiex/sdio.h +++ b/drivers/net/wireless/marvell/mwifiex/sdio.h @@ -39,6 +39,7 @@ #define SD8977_DEFAULT_FW_NAME "mrvl/sdsd8977_combo_v2.bin" #define SD8987_DEFAULT_FW_NAME "mrvl/sd8987_uapsta.bin" #define SD8997_DEFAULT_FW_NAME "mrvl/sdsd8997_combo_v4.bin" +#define SD8997_SDIOUART_FW_NAME "mrvl/sdiouart8997_combo_v4.bin" #define BLOCK_MODE 1 #define BYTE_MODE 0 From fc6234d7e2e322e84ed3c5c6c05a54f611faa9ab Mon Sep 17 00:00:00 2001 From: Kevin Lo Date: Fri, 22 Apr 2022 22:50:54 +0800 Subject: [PATCH 186/228] rtw88: use the correct bit in the REG_HCI_OPT_CTRL register Write the BIT_USB_SUS_DIS bit rather than BIT_BT_DIG_CLK_EN to the REG_HCI_OPT_CTRL register for fixing failure to PCIe power on. Signed-off-by: Kevin Lo Acked-by: Ping-Ke Shih Signed-off-by: Kalle Valo Link: https://lore.kernel.org/r/YmLAzuyPr0P4Y6BP@ns.kevlo.org --- drivers/net/wireless/realtek/rtw88/mac.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/net/wireless/realtek/rtw88/mac.c b/drivers/net/wireless/realtek/rtw88/mac.c index d1678aed9d9cb..caf2603da2d65 100644 --- a/drivers/net/wireless/realtek/rtw88/mac.c +++ b/drivers/net/wireless/realtek/rtw88/mac.c @@ -75,7 +75,7 @@ static int rtw_mac_pre_system_cfg(struct rtw_dev *rtwdev) switch (rtw_hci_type(rtwdev)) { case RTW_HCI_TYPE_PCIE: - rtw_write32_set(rtwdev, REG_HCI_OPT_CTRL, BIT_BT_DIG_CLK_EN); + rtw_write32_set(rtwdev, REG_HCI_OPT_CTRL, BIT_USB_SUS_DIS); break; case RTW_HCI_TYPE_USB: break; From 746285cf81dc19502ab238249d75f5990bd2d231 Mon Sep 17 00:00:00 2001 From: Alexander Wetzel Date: Fri, 22 Apr 2022 16:52:28 +0200 Subject: [PATCH 187/228] rtl818x: Prevent using not initialized queues Using not existing queues can panic the kernel with rtl8180/rtl8185 cards. Ignore the skb priority for those cards, they only have one tx queue. Pierre Asselin (pa@panix.com) reported the kernel crash in the Gentoo forum: https://forums.gentoo.org/viewtopic-t-1147832-postdays-0-postorder-asc-start-25.html He also confirmed that this patch fixes the issue. In summary this happened: After updating wpa_supplicant from 2.9 to 2.10 the kernel crashed with a "divide error: 0000" when connecting to an AP. Control port tx now tries to use IEEE80211_AC_VO for the priority, which wpa_supplicants starts to use in 2.10. Since only the rtl8187se part of the driver supports QoS, the priority of the skb is set to IEEE80211_AC_BE (2) by mac80211 for rtl8180/rtl8185 cards. rtl8180 is then unconditionally reading out the priority and finally crashes on drivers/net/wireless/realtek/rtl818x/rtl8180/dev.c line 544 without this patch: idx = (ring->idx + skb_queue_len(&ring->queue)) % ring->entries "ring->entries" is zero for rtl8180/rtl8185 cards, tx_ring[2] never got initialized. Cc: stable@vger.kernel.org Reported-by: pa@panix.com Tested-by: pa@panix.com Signed-off-by: Alexander Wetzel Signed-off-by: Kalle Valo Link: https://lore.kernel.org/r/20220422145228.7567-1-alexander@wetzel-home.de --- drivers/net/wireless/realtek/rtl818x/rtl8180/dev.c | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/drivers/net/wireless/realtek/rtl818x/rtl8180/dev.c b/drivers/net/wireless/realtek/rtl818x/rtl8180/dev.c index 2477e18c7caec..025619cd14e82 100644 --- a/drivers/net/wireless/realtek/rtl818x/rtl8180/dev.c +++ b/drivers/net/wireless/realtek/rtl818x/rtl8180/dev.c @@ -460,8 +460,10 @@ static void rtl8180_tx(struct ieee80211_hw *dev, struct rtl8180_priv *priv = dev->priv; struct rtl8180_tx_ring *ring; struct rtl8180_tx_desc *entry; + unsigned int prio = 0; unsigned long flags; - unsigned int idx, prio, hw_prio; + unsigned int idx, hw_prio; + dma_addr_t mapping; u32 tx_flags; u8 rc_flags; @@ -470,7 +472,9 @@ static void rtl8180_tx(struct ieee80211_hw *dev, /* do arithmetic and then convert to le16 */ u16 frame_duration = 0; - prio = skb_get_queue_mapping(skb); + /* rtl8180/rtl8185 only has one useable tx queue */ + if (dev->queues > IEEE80211_AC_BK) + prio = skb_get_queue_mapping(skb); ring = &priv->tx_ring[prio]; mapping = dma_map_single(&priv->pdev->dev, skb->data, skb->len, From 21947f3a74d6c90508e1065d649791c9a38d515b Mon Sep 17 00:00:00 2001 From: Hamid Zamani Date: Sat, 23 Apr 2022 15:42:37 +0430 Subject: [PATCH 188/228] brcmfmac: use ISO3166 country code and 0 rev as fallback on brcmfmac43602 chips This uses ISO3166 country code and 0 rev on brcmfmac43602 chips. Without this patch 80 MHz width is not selected on 5 GHz channels. Commit a21bf90e927f ("brcmfmac: use ISO3166 country code and 0 rev as fallback on some devices") provides a way to specify chips for using the fallback case. Before commit 151a7c12c4fc ("Revert "brcmfmac: use ISO3166 country code and 0 rev as fallback"") brcmfmac43602 devices works correctly and for this specific case 80 MHz width is selected. Signed-off-by: Hamid Zamani Signed-off-by: Kalle Valo Link: https://lore.kernel.org/r/20220423111237.60892-1-hzamani.cs91@gmail.com --- drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c index f0ad1e23f3c80..360b103fe8980 100644 --- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c +++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c @@ -7481,6 +7481,7 @@ static bool brmcf_use_iso3166_ccode_fallback(struct brcmf_pub *drvr) { switch (drvr->bus_if->chip) { case BRCM_CC_4345_CHIP_ID: + case BRCM_CC_43602_CHIP_ID: return true; default: return false; From 8c783024d6acbd7a18b94ae7ed0e0ed4f163d0ba Mon Sep 17 00:00:00 2001 From: Guo Zhengkui Date: Mon, 25 Apr 2022 11:17:23 +0800 Subject: [PATCH 189/228] rtlwifi: btcoex: fix if == else warning Fix the following coccicheck warning: drivers/net/wireless/realtek/rtlwifi/btcoexist/halbtc8821a1ant.c:1604:2-4: WARNING: possible condition with no effect (if == else). Signed-off-by: Guo Zhengkui Acked-by: Ping-Ke Shih Signed-off-by: Kalle Valo Link: https://lore.kernel.org/r/20220425031725.5808-1-guozhengkui@vivo.com --- .../realtek/rtlwifi/btcoexist/halbtc8821a1ant.c | 16 ++++------------ 1 file changed, 4 insertions(+), 12 deletions(-) diff --git a/drivers/net/wireless/realtek/rtlwifi/btcoexist/halbtc8821a1ant.c b/drivers/net/wireless/realtek/rtlwifi/btcoexist/halbtc8821a1ant.c index a18dffc8753a9..67d0b9aee0648 100644 --- a/drivers/net/wireless/realtek/rtlwifi/btcoexist/halbtc8821a1ant.c +++ b/drivers/net/wireless/realtek/rtlwifi/btcoexist/halbtc8821a1ant.c @@ -1600,18 +1600,10 @@ static void btc8821a1ant_act_wifi_con_bt_acl_busy(struct btc_coexist *btcoexist, coex_dm->auto_tdma_adjust = false; } } else if (bt_link_info->hid_exist && bt_link_info->a2dp_exist) { - /* HID+A2DP */ - if ((bt_rssi_state == BTC_RSSI_STATE_HIGH) || - (bt_rssi_state == BTC_RSSI_STATE_STAY_HIGH)) { - btc8821a1ant_ps_tdma(btcoexist, NORMAL_EXEC, - true, 14); - coex_dm->auto_tdma_adjust = false; - } else { - /*for low BT RSSI*/ - btc8821a1ant_ps_tdma(btcoexist, NORMAL_EXEC, - true, 14); - coex_dm->auto_tdma_adjust = false; - } + /* HID+A2DP (no need to consider BT RSSI) */ + btc8821a1ant_ps_tdma(btcoexist, NORMAL_EXEC, + true, 14); + coex_dm->auto_tdma_adjust = false; btc8821a1ant_coex_table_with_type(btcoexist, NORMAL_EXEC, 1); } else if ((bt_link_info->pan_only) || From b6f6301041a3f27cb3085abb395c2607ac71671c Mon Sep 17 00:00:00 2001 From: Manikanta Pubbisetty Date: Wed, 6 Apr 2022 15:11:03 +0530 Subject: [PATCH 190/228] ath11k: Do not put HW in DBS mode for WCN6750 Though WCN6750 is a single PDEV device, it is not a DBS solution. So, do not put HW in DBS mode for WCN6750. Tested-on: WCN6750 hw1.0 AHB WLAN.MSL.1.0.1-00573-QCAMSLSWPLZ-1 Tested-on: WCN6855 hw2.0 PCI WLAN.HSP.1.1-01720.1-QCAHSPSWPL_V1_V2_SILICONZ_LITE-1 Tested-on: QCN9074 hw1.0 PCI WLAN.HK.2.5.0.1-01100-QCAHKSWPL_SILICONZ-1 Tested-on: IPQ8074 hw2.0 AHB WLAN.HK.2.4.0.1-00192-QCAHKSWPL_SILICONZ-1 Signed-off-by: Manikanta Pubbisetty Signed-off-by: Kalle Valo Link: https://lore.kernel.org/r/20220406094107.17878-10-quic_mpubbise@quicinc.com --- drivers/net/wireless/ath/ath11k/core.c | 2 +- drivers/net/wireless/ath/ath11k/wmi.c | 3 ++- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/drivers/net/wireless/ath/ath11k/core.c b/drivers/net/wireless/ath/ath11k/core.c index f011db4bcd2b2..06958f358307c 100644 --- a/drivers/net/wireless/ath/ath11k/core.c +++ b/drivers/net/wireless/ath/ath11k/core.c @@ -1213,7 +1213,7 @@ static int ath11k_core_start(struct ath11k_base *ab, } /* put hardware to DBS mode */ - if (ab->hw_params.single_pdev_only) { + if (ab->hw_params.single_pdev_only && ab->hw_params.num_rxmda_per_pdev > 1) { ret = ath11k_wmi_set_hw_mode(ab, WMI_HOST_HW_MODE_DBS); if (ret) { ath11k_err(ab, "failed to send dbs mode: %d\n", ret); diff --git a/drivers/net/wireless/ath/ath11k/wmi.c b/drivers/net/wireless/ath/ath11k/wmi.c index dcf31bdad47ef..d7243819d9bd4 100644 --- a/drivers/net/wireless/ath/ath11k/wmi.c +++ b/drivers/net/wireless/ath/ath11k/wmi.c @@ -1,6 +1,7 @@ // SPDX-License-Identifier: BSD-3-Clause-Clear /* * Copyright (c) 2018-2019 The Linux Foundation. All rights reserved. + * Copyright (c) 2021, Qualcomm Innovation Center, Inc. All rights reserved. */ #include #include @@ -8225,7 +8226,7 @@ int ath11k_wmi_attach(struct ath11k_base *ab) ab->wmi_ab.preferred_hw_mode = WMI_HOST_HW_MODE_MAX; /* It's overwritten when service_ext_ready is handled */ - if (ab->hw_params.single_pdev_only) + if (ab->hw_params.single_pdev_only && ab->hw_params.num_rxmda_per_pdev > 1) ab->wmi_ab.preferred_hw_mode = WMI_HOST_HW_MODE_SINGLE; /* TODO: Init remaining wmi soc resources required */ From 95959d702ede5fffd1abfcfa739b5179828cfe24 Mon Sep 17 00:00:00 2001 From: Manikanta Pubbisetty Date: Wed, 6 Apr 2022 15:11:04 +0530 Subject: [PATCH 191/228] ath11k: WMI changes to support WCN6750 WCN6750 is a single PDEV non-DBS chip which supports 2G, 5G and 6G bands. It is a single LMAC device which can be either hooked to 2G/5G/6G bands. Add WMI changes to support WCN6750. Tested-on: WCN6750 hw1.0 AHB WLAN.MSL.1.0.1-00573-QCAMSLSWPLZ-1 Tested-on: WCN6855 hw2.0 PCI WLAN.HSP.1.1-01720.1-QCAHSPSWPL_V1_V2_SILICONZ_LITE-1 Tested-on: QCN9074 hw1.0 PCI WLAN.HK.2.5.0.1-01100-QCAHKSWPL_SILICONZ-1 Tested-on: IPQ8074 hw2.0 AHB WLAN.HK.2.4.0.1-00192-QCAHKSWPL_SILICONZ-1 Signed-off-by: Manikanta Pubbisetty Signed-off-by: Kalle Valo Link: https://lore.kernel.org/r/20220406094107.17878-11-quic_mpubbise@quicinc.com --- drivers/net/wireless/ath/ath11k/wmi.c | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/drivers/net/wireless/ath/ath11k/wmi.c b/drivers/net/wireless/ath/ath11k/wmi.c index d7243819d9bd4..3c0ac1e29479e 100644 --- a/drivers/net/wireless/ath/ath11k/wmi.c +++ b/drivers/net/wireless/ath/ath11k/wmi.c @@ -391,6 +391,10 @@ ath11k_pull_mac_phy_cap_svc_ready_ext(struct ath11k_pdev_wmi *wmi_handle, ab->target_pdev_ids[ab->target_pdev_count].pdev_id = mac_phy_caps->pdev_id; ab->target_pdev_count++; + if (!(mac_phy_caps->supported_bands & WMI_HOST_WLAN_2G_CAP) && + !(mac_phy_caps->supported_bands & WMI_HOST_WLAN_5G_CAP)) + return -EINVAL; + /* Take non-zero tx/rx chainmask. If tx/rx chainmask differs from * band to band for a single radio, need to see how this should be * handled. @@ -398,7 +402,9 @@ ath11k_pull_mac_phy_cap_svc_ready_ext(struct ath11k_pdev_wmi *wmi_handle, if (mac_phy_caps->supported_bands & WMI_HOST_WLAN_2G_CAP) { pdev_cap->tx_chain_mask = mac_phy_caps->tx_chain_mask_2g; pdev_cap->rx_chain_mask = mac_phy_caps->rx_chain_mask_2g; - } else if (mac_phy_caps->supported_bands & WMI_HOST_WLAN_5G_CAP) { + } + + if (mac_phy_caps->supported_bands & WMI_HOST_WLAN_5G_CAP) { pdev_cap->vht_cap = mac_phy_caps->vht_cap_info_5g; pdev_cap->vht_mcs = mac_phy_caps->vht_supp_mcs_5g; pdev_cap->he_mcs = mac_phy_caps->he_supp_mcs_5g; @@ -408,8 +414,6 @@ ath11k_pull_mac_phy_cap_svc_ready_ext(struct ath11k_pdev_wmi *wmi_handle, WMI_NSS_RATIO_ENABLE_DISABLE_GET(mac_phy_caps->nss_ratio); pdev_cap->nss_ratio_info = WMI_NSS_RATIO_INFO_GET(mac_phy_caps->nss_ratio); - } else { - return -EINVAL; } /* tx/rx chainmask reported from fw depends on the actual hw chains used, From 33b67a4b4e64275b6f2cbc4318f1596c70659111 Mon Sep 17 00:00:00 2001 From: Manikanta Pubbisetty Date: Wed, 6 Apr 2022 15:11:05 +0530 Subject: [PATCH 192/228] ath11k: Update WBM idle ring HP after FW mode on Currently, WBM idle ring HP is updated much before the shadow configuration is sent to the FW. Any update to the shadow registers before FW mode on request would not be reflected on to the actual HW registers failing to bring up the device. Send FW mode ON QMI request before WBM idle ring HP update to fix this problem. Tested-on: WCN6750 hw1.0 AHB WLAN.MSL.1.0.1-00573-QCAMSLSWPLZ-1 Tested-on: WCN6855 hw2.0 PCI WLAN.HSP.1.1-01720.1-QCAHSPSWPL_V1_V2_SILICONZ_LITE-1 Tested-on: QCN9074 hw1.0 PCI WLAN.HK.2.5.0.1-01100-QCAHKSWPL_SILICONZ-1 Tested-on: IPQ8074 hw2.0 AHB WLAN.HK.2.4.0.1-00192-QCAHKSWPL_SILICONZ-1 Signed-off-by: Manikanta Pubbisetty Signed-off-by: Kalle Valo Link: https://lore.kernel.org/r/20220406094107.17878-12-quic_mpubbise@quicinc.com --- drivers/net/wireless/ath/ath11k/ce.c | 4 +-- drivers/net/wireless/ath/ath11k/core.c | 45 ++++++++++++++++++-------- 2 files changed, 32 insertions(+), 17 deletions(-) diff --git a/drivers/net/wireless/ath/ath11k/ce.c b/drivers/net/wireless/ath/ath11k/ce.c index aaa7b05ff49d3..c14c51f387094 100644 --- a/drivers/net/wireless/ath/ath11k/ce.c +++ b/drivers/net/wireless/ath/ath11k/ce.c @@ -1,6 +1,7 @@ // SPDX-License-Identifier: BSD-3-Clause-Clear /* * Copyright (c) 2018-2019 The Linux Foundation. All rights reserved. + * Copyright (c) 2021, Qualcomm Innovation Center, Inc. All rights reserved. */ #include "dp_rx.h" @@ -918,9 +919,6 @@ int ath11k_ce_init_pipes(struct ath11k_base *ab) int i; int ret; - ath11k_ce_get_shadow_config(ab, &ab->qmi.ce_cfg.shadow_reg_v2, - &ab->qmi.ce_cfg.shadow_reg_v2_len); - for (i = 0; i < ab->hw_params.ce_count; i++) { pipe = &ab->ce.ce_pipe[i]; diff --git a/drivers/net/wireless/ath/ath11k/core.c b/drivers/net/wireless/ath/ath11k/core.c index 06958f358307c..36d265454e26d 100644 --- a/drivers/net/wireless/ath/ath11k/core.c +++ b/drivers/net/wireless/ath/ath11k/core.c @@ -1124,21 +1124,14 @@ static void ath11k_core_pdev_destroy(struct ath11k_base *ab) ath11k_debugfs_pdev_destroy(ab); } -static int ath11k_core_start(struct ath11k_base *ab, - enum ath11k_firmware_mode mode) +static int ath11k_core_start(struct ath11k_base *ab) { int ret; - ret = ath11k_qmi_firmware_start(ab, mode); - if (ret) { - ath11k_err(ab, "failed to attach wmi: %d\n", ret); - return ret; - } - ret = ath11k_wmi_attach(ab); if (ret) { ath11k_err(ab, "failed to attach wmi: %d\n", ret); - goto err_firmware_stop; + return ret; } ret = ath11k_htc_init(ab); @@ -1238,8 +1231,23 @@ static int ath11k_core_start(struct ath11k_base *ab, ath11k_hif_stop(ab); err_wmi_detach: ath11k_wmi_detach(ab); -err_firmware_stop: - ath11k_qmi_firmware_stop(ab); + + return ret; +} + +static int ath11k_core_start_firmware(struct ath11k_base *ab, + enum ath11k_firmware_mode mode) +{ + int ret; + + ath11k_ce_get_shadow_config(ab, &ab->qmi.ce_cfg.shadow_reg_v2, + &ab->qmi.ce_cfg.shadow_reg_v2_len); + + ret = ath11k_qmi_firmware_start(ab, mode); + if (ret) { + ath11k_err(ab, "failed to send firmware start: %d\n", ret); + return ret; + } return ret; } @@ -1269,16 +1277,22 @@ int ath11k_core_qmi_firmware_ready(struct ath11k_base *ab) { int ret; + ret = ath11k_core_start_firmware(ab, ATH11K_FIRMWARE_MODE_NORMAL); + if (ret) { + ath11k_err(ab, "failed to start firmware: %d\n", ret); + return ret; + } + ret = ath11k_ce_init_pipes(ab); if (ret) { ath11k_err(ab, "failed to initialize CE: %d\n", ret); - return ret; + goto err_firmware_stop; } ret = ath11k_dp_alloc(ab); if (ret) { ath11k_err(ab, "failed to init DP: %d\n", ret); - return ret; + goto err_firmware_stop; } switch (ath11k_crypto_mode) { @@ -1299,7 +1313,7 @@ int ath11k_core_qmi_firmware_ready(struct ath11k_base *ab) set_bit(ATH11K_FLAG_RAW_MODE, &ab->dev_flags); mutex_lock(&ab->core_lock); - ret = ath11k_core_start(ab, ATH11K_FIRMWARE_MODE_NORMAL); + ret = ath11k_core_start(ab); if (ret) { ath11k_err(ab, "failed to start core: %d\n", ret); goto err_dp_free; @@ -1328,6 +1342,9 @@ int ath11k_core_qmi_firmware_ready(struct ath11k_base *ab) err_dp_free: ath11k_dp_free(ab); mutex_unlock(&ab->core_lock); +err_firmware_stop: + ath11k_qmi_firmware_stop(ab); + return ret; } From 161c64de239c7018e0295e7e0520a19f00aa32dc Mon Sep 17 00:00:00 2001 From: Hari Chandrakanthan Date: Sat, 23 Apr 2022 12:36:47 +0300 Subject: [PATCH 193/228] ath11k: disable spectral scan during spectral deinit When ath11k modules are removed using rmmod with spectral scan enabled, crash is observed. Different crash trace is observed for each crash. Send spectral scan disable WMI command to firmware before cleaning the spectral dbring in the spectral_deinit API to avoid this crash. call trace from one of the crash observed: [ 1252.880802] Unable to handle kernel NULL pointer dereference at virtual address 00000008 [ 1252.882722] pgd = 0f42e886 [ 1252.890955] [00000008] *pgd=00000000 [ 1252.893478] Internal error: Oops: 5 [#1] PREEMPT SMP ARM [ 1253.093035] CPU: 0 PID: 0 Comm: swapper/0 Not tainted 5.4.89 #0 [ 1253.115261] Hardware name: Generic DT based system [ 1253.121149] PC is at ath11k_spectral_process_data+0x434/0x574 [ath11k] [ 1253.125940] LR is at 0x88e31017 [ 1253.132448] pc : [<7f9387b8>] lr : [<88e31017>] psr: a0000193 [ 1253.135488] sp : 80d01bc8 ip : 00000001 fp : 970e0000 [ 1253.141737] r10: 88e31000 r9 : 970ec000 r8 : 00000080 [ 1253.146946] r7 : 94734040 r6 : a0000113 r5 : 00000057 r4 : 00000000 [ 1253.152159] r3 : e18cb694 r2 : 00000217 r1 : 1df1f000 r0 : 00000001 [ 1253.158755] Flags: NzCv IRQs off FIQs on Mode SVC_32 ISA ARM Segment user [ 1253.165266] Control: 10c0383d Table: 5e71006a DAC: 00000055 [ 1253.172472] Process swapper/0 (pid: 0, stack limit = 0x60870141) [ 1253.458055] [<7f9387b8>] (ath11k_spectral_process_data [ath11k]) from [<7f917fdc>] (ath11k_dbring_buffer_release_event+0x214/0x2e4 [ath11k]) [ 1253.466139] [<7f917fdc>] (ath11k_dbring_buffer_release_event [ath11k]) from [<7f8ea3c4>] (ath11k_wmi_tlv_op_rx+0x1840/0x29cc [ath11k]) [ 1253.478807] [<7f8ea3c4>] (ath11k_wmi_tlv_op_rx [ath11k]) from [<7f8fe868>] (ath11k_htc_rx_completion_handler+0x180/0x4e0 [ath11k]) [ 1253.490699] [<7f8fe868>] (ath11k_htc_rx_completion_handler [ath11k]) from [<7f91308c>] (ath11k_ce_per_engine_service+0x2c4/0x3b4 [ath11k]) [ 1253.502386] [<7f91308c>] (ath11k_ce_per_engine_service [ath11k]) from [<7f9a4198>] (ath11k_pci_ce_tasklet+0x28/0x80 [ath11k_pci]) [ 1253.514811] [<7f9a4198>] (ath11k_pci_ce_tasklet [ath11k_pci]) from [<8032227c>] (tasklet_action_common.constprop.2+0x64/0xe8) [ 1253.526476] [<8032227c>] (tasklet_action_common.constprop.2) from [<803021e8>] (__do_softirq+0x130/0x2d0) [ 1253.537756] [<803021e8>] (__do_softirq) from [<80322610>] (irq_exit+0xcc/0xe8) [ 1253.547304] [<80322610>] (irq_exit) from [<8036a4a4>] (__handle_domain_irq+0x60/0xb4) [ 1253.554428] [<8036a4a4>] (__handle_domain_irq) from [<805eb348>] (gic_handle_irq+0x4c/0x90) [ 1253.562321] [<805eb348>] (gic_handle_irq) from [<80301a78>] (__irq_svc+0x58/0x8c) Tested-on: QCN6122 hw1.0 AHB WLAN.HK.2.6.0.1-00851-QCAHKSWPL_SILICONZ-1 Signed-off-by: Hari Chandrakanthan Signed-off-by: Kalle Valo Link: https://lore.kernel.org/r/1649396345-349-1-git-send-email-quic_haric@quicinc.com --- drivers/net/wireless/ath/ath11k/spectral.c | 17 +++++++++-------- 1 file changed, 9 insertions(+), 8 deletions(-) diff --git a/drivers/net/wireless/ath/ath11k/spectral.c b/drivers/net/wireless/ath/ath11k/spectral.c index 2b18871d5f7cb..516a7b4cd1805 100644 --- a/drivers/net/wireless/ath/ath11k/spectral.c +++ b/drivers/net/wireless/ath/ath11k/spectral.c @@ -212,7 +212,10 @@ static int ath11k_spectral_scan_config(struct ath11k *ar, return -ENODEV; arvif->spectral_enabled = (mode != ATH11K_SPECTRAL_DISABLED); + + spin_lock_bh(&ar->spectral.lock); ar->spectral.mode = mode; + spin_unlock_bh(&ar->spectral.lock); ret = ath11k_wmi_vdev_spectral_enable(ar, arvif->vdev_id, ATH11K_WMI_SPECTRAL_TRIGGER_CMD_CLEAR, @@ -843,9 +846,6 @@ static inline void ath11k_spectral_ring_free(struct ath11k *ar) { struct ath11k_spectral *sp = &ar->spectral; - if (!sp->enabled) - return; - ath11k_dbring_srng_cleanup(ar, &sp->rx_ring); ath11k_dbring_buf_cleanup(ar, &sp->rx_ring); } @@ -897,15 +897,16 @@ void ath11k_spectral_deinit(struct ath11k_base *ab) if (!sp->enabled) continue; - ath11k_spectral_debug_unregister(ar); - ath11k_spectral_ring_free(ar); + mutex_lock(&ar->conf_mutex); + ath11k_spectral_scan_config(ar, ATH11K_SPECTRAL_DISABLED); + mutex_unlock(&ar->conf_mutex); spin_lock_bh(&sp->lock); - - sp->mode = ATH11K_SPECTRAL_DISABLED; sp->enabled = false; - spin_unlock_bh(&sp->lock); + + ath11k_spectral_debug_unregister(ar); + ath11k_spectral_ring_free(ar); } } From 66721bb4bbf25e990e003a2303ef86ce34556bac Mon Sep 17 00:00:00 2001 From: Wen Gong Date: Wed, 20 Apr 2022 22:35:01 -0400 Subject: [PATCH 194/228] ath11k: read country code from SMBIOS for WCN6855/QCA6390 This read the country code from SMBIOS and send the country code to firmware, firmware will indicate the regulatory domain info of the country code and then ath11k will use the info. dmesg: [ 1242.637173] ath11k_pci 0000:02:00.0: chip_id 0x2 chip_family 0xb board_id 0xff soc_id 0x400c0200 [ 1242.637176] ath11k_pci 0000:02:00.0: fw_version 0x110b09e5 fw_build_timestamp 2021-06-22 09:32 fw_build_id QC_IMAGE_VERSION_STRING=WLAN.HSP.1.1-02533-QCAHSPSWPL_V1_V2_SILICONZ_LITE-1 [ 1242.637253] ath11k_pci 0000:02:00.0: worldwide regdomain setting from SMBIOS [ 1242.637259] ath11k_pci 0000:02:00.0: bdf variant name not found. [ 1242.637261] ath11k_pci 0000:02:00.0: SMBIOS bdf variant name not set. [ 1242.637263] ath11k_pci 0000:02:00.0: DT bdf variant name not set. [ 1242.927543] ath11k_pci 0000:02:00.0: set current country pdev id 0 alpha2 00 Tested-on: WCN6855 hw2.0 PCI WLAN.HSP.1.1-03125-QCAHSPSWPL_V1_V2_SILICONZ_LITE-3 Signed-off-by: Wen Gong Signed-off-by: Kalle Valo Link: https://lore.kernel.org/r/20220421023501.32167-1-quic_wgong@quicinc.com --- drivers/net/wireless/ath/ath11k/core.c | 26 ++++++++++++++++++++-- drivers/net/wireless/ath/ath11k/core.h | 30 ++++++++++++++++++++++++-- drivers/net/wireless/ath/ath11k/mac.c | 11 ++++++++++ 3 files changed, 63 insertions(+), 4 deletions(-) diff --git a/drivers/net/wireless/ath/ath11k/core.c b/drivers/net/wireless/ath/ath11k/core.c index 36d265454e26d..7e074b7716e75 100644 --- a/drivers/net/wireless/ath/ath11k/core.c +++ b/drivers/net/wireless/ath/ath11k/core.c @@ -544,7 +544,7 @@ int ath11k_core_resume(struct ath11k_base *ab) } EXPORT_SYMBOL(ath11k_core_resume); -static void ath11k_core_check_bdfext(const struct dmi_header *hdr, void *data) +static void ath11k_core_check_cc_code_bdfext(const struct dmi_header *hdr, void *data) { struct ath11k_base *ab = data; const char *magic = ATH11K_SMBIOS_BDF_EXT_MAGIC; @@ -566,6 +566,28 @@ static void ath11k_core_check_bdfext(const struct dmi_header *hdr, void *data) return; } + spin_lock_bh(&ab->base_lock); + + switch (smbios->country_code_flag) { + case ATH11K_SMBIOS_CC_ISO: + ab->new_alpha2[0] = (smbios->cc_code >> 8) & 0xff; + ab->new_alpha2[1] = smbios->cc_code & 0xff; + ath11k_dbg(ab, ATH11K_DBG_BOOT, "boot smbios cc_code %c%c\n", + ab->new_alpha2[0], ab->new_alpha2[1]); + break; + case ATH11K_SMBIOS_CC_WW: + ab->new_alpha2[0] = '0'; + ab->new_alpha2[1] = '0'; + ath11k_dbg(ab, ATH11K_DBG_BOOT, "boot smbios worldwide regdomain\n"); + break; + default: + ath11k_dbg(ab, ATH11K_DBG_BOOT, "boot ignore smbios country code setting %d\n", + smbios->country_code_flag); + break; + } + + spin_unlock_bh(&ab->base_lock); + if (!smbios->bdf_enabled) { ath11k_dbg(ab, ATH11K_DBG_BOOT, "bdf variant name not found.\n"); return; @@ -605,7 +627,7 @@ static void ath11k_core_check_bdfext(const struct dmi_header *hdr, void *data) int ath11k_core_check_smbios(struct ath11k_base *ab) { ab->qmi.target.bdf_ext[0] = '\0'; - dmi_walk(ath11k_core_check_bdfext, ab); + dmi_walk(ath11k_core_check_cc_code_bdfext, ab); if (ab->qmi.target.bdf_ext[0] == '\0') return -ENODATA; diff --git a/drivers/net/wireless/ath/ath11k/core.h b/drivers/net/wireless/ath/ath11k/core.h index fa299bfb4efcd..7a505531acf92 100644 --- a/drivers/net/wireless/ath/ath11k/core.h +++ b/drivers/net/wireless/ath/ath11k/core.h @@ -169,12 +169,38 @@ struct ath11k_ext_irq_grp { struct net_device napi_ndev; }; +enum ath11k_smbios_cc_type { + /* disable country code setting from SMBIOS */ + ATH11K_SMBIOS_CC_DISABLE = 0, + + /* set country code by ANSI country name, based on ISO3166-1 alpha2 */ + ATH11K_SMBIOS_CC_ISO = 1, + + /* worldwide regdomain */ + ATH11K_SMBIOS_CC_WW = 2, +}; + struct ath11k_smbios_bdf { struct dmi_header hdr; - u32 padding; + + u8 features_disabled; + + /* enum ath11k_smbios_cc_type */ + u8 country_code_flag; + + /* To set specific country, you need to set country code + * flag=ATH11K_SMBIOS_CC_ISO first, then if country is United + * States, then country code value = 0x5553 ("US",'U' = 0x55, 'S'= + * 0x53). To set country to INDONESIA, then country code value = + * 0x4944 ("IN", 'I'=0x49, 'D'=0x44). If country code flag = + * ATH11K_SMBIOS_CC_WW, then you can use worldwide regulatory + * setting. + */ + u16 cc_code; + u8 bdf_enabled; u8 bdf_ext[]; -}; +} __packed; #define HEHANDLE_CAP_PHYINFO_SIZE 3 #define HECAP_PHYINFO_SIZE 9 diff --git a/drivers/net/wireless/ath/ath11k/mac.c b/drivers/net/wireless/ath/ath11k/mac.c index c987f365c63a1..c025bcb25c007 100644 --- a/drivers/net/wireless/ath/ath11k/mac.c +++ b/drivers/net/wireless/ath/ath11k/mac.c @@ -8836,6 +8836,17 @@ static int __ath11k_mac_register(struct ath11k *ar) goto err_unregister_hw; } + if (ab->hw_params.current_cc_support && ab->new_alpha2[0]) { + struct wmi_set_current_country_params set_current_param = {}; + + memcpy(&set_current_param.alpha2, ab->new_alpha2, 2); + memcpy(&ar->alpha2, ab->new_alpha2, 2); + ret = ath11k_wmi_send_set_current_country_cmd(ar, &set_current_param); + if (ret) + ath11k_warn(ar->ab, + "failed set cc code for mac register: %d\n", ret); + } + ret = ath11k_debugfs_register(ar); if (ret) { ath11k_err(ar->ab, "debugfs registration failed: %d\n", ret); From 7471f7d273ac51f044dad3d78af6afb87a14bb67 Mon Sep 17 00:00:00 2001 From: Wan Jiabing Date: Sun, 24 Apr 2022 17:45:22 +0800 Subject: [PATCH 195/228] ath10k: simplify if-if to if-else Use if and else instead of if(A) and if (!A). Signed-off-by: Wan Jiabing Signed-off-by: Kalle Valo Link: https://lore.kernel.org/r/20220424094522.105262-1-wanjiabing@vivo.com --- drivers/net/wireless/ath/ath10k/mac.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/drivers/net/wireless/ath/ath10k/mac.c b/drivers/net/wireless/ath/ath10k/mac.c index b11aaee8b8c03..a46f56a1efca6 100644 --- a/drivers/net/wireless/ath/ath10k/mac.c +++ b/drivers/net/wireless/ath/ath10k/mac.c @@ -4118,11 +4118,10 @@ void ath10k_offchan_tx_work(struct work_struct *work) peer = ath10k_peer_find(ar, vdev_id, peer_addr); spin_unlock_bh(&ar->data_lock); - if (peer) + if (peer) { ath10k_warn(ar, "peer %pM on vdev %d already present\n", peer_addr, vdev_id); - - if (!peer) { + } else { ret = ath10k_peer_create(ar, NULL, NULL, vdev_id, peer_addr, WMI_PEER_TYPE_DEFAULT); From a5f3aed5889eac9ed72f071dd439b9c671d1092f Mon Sep 17 00:00:00 2001 From: Wan Jiabing Date: Sun, 24 Apr 2022 17:45:50 +0800 Subject: [PATCH 196/228] wil6210: simplify if-if to if-else Use if and else instead of if(A) and if (!A). Signed-off-by: Wan Jiabing Signed-off-by: Kalle Valo Link: https://lore.kernel.org/r/20220424094552.105466-1-wanjiabing@vivo.com --- drivers/net/wireless/ath/wil6210/cfg80211.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/drivers/net/wireless/ath/wil6210/cfg80211.c b/drivers/net/wireless/ath/wil6210/cfg80211.c index 764d1d14132b0..8f2638f5b87bb 100644 --- a/drivers/net/wireless/ath/wil6210/cfg80211.c +++ b/drivers/net/wireless/ath/wil6210/cfg80211.c @@ -1653,10 +1653,9 @@ static int wil_cfg80211_add_key(struct wiphy *wiphy, params->seq_len, params->seq); return -EINVAL; } - } - - if (!IS_ERR(cs)) + } else { wil_del_rx_key(key_index, key_usage, cs); + } if (params->seq && params->seq_len != IEEE80211_GCMP_PN_LEN) { wil_err(wil, From 11dc130b4ee010396b5374300e03f0b6c729ce8c Mon Sep 17 00:00:00 2001 From: Yang Li Date: Wed, 27 Apr 2022 08:31:42 +0800 Subject: [PATCH 197/228] rtw89: remove unneeded semicolon Eliminate the following coccicheck warning: ./drivers/net/wireless/realtek/rtw89/rtw8852c.c:2556:2-3: Unneeded semicolon Reported-by: Abaci Robot Signed-off-by: Yang Li Acked-by: Ping-Ke Shih Signed-off-by: Kalle Valo Link: https://lore.kernel.org/r/20220427003142.107916-1-yang.lee@linux.alibaba.com --- drivers/net/wireless/realtek/rtw89/rtw8852c.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/net/wireless/realtek/rtw89/rtw8852c.c b/drivers/net/wireless/realtek/rtw89/rtw8852c.c index 858611c64e6bf..2755684682126 100644 --- a/drivers/net/wireless/realtek/rtw89/rtw8852c.c +++ b/drivers/net/wireless/realtek/rtw89/rtw8852c.c @@ -2553,7 +2553,7 @@ do { \ default: val = arg.gnt_bt.data; break; - }; + } __write_ctrl(R_AX_PWR_COEXT_CTRL, B_AX_TXAGC_BT_MASK, val, B_AX_TXAGC_BT_EN, arg.ctrl_gnt_bt != 0xffff); From 2950833f10cfa601813262e1d9c8473f9415681b Mon Sep 17 00:00:00 2001 From: Wan Jiabing Date: Wed, 27 Apr 2022 10:37:32 +0300 Subject: [PATCH 198/228] ath9k: hif_usb: simplify if-if to if-else MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Use if and else instead of if(A) and if (!A). Signed-off-by: Wan Jiabing Acked-by: Toke Høiland-Jørgensen Signed-off-by: Kalle Valo Link: https://lore.kernel.org/r/20220424094441.104937-1-wanjiabing@vivo.com --- drivers/net/wireless/ath/ath9k/hif_usb.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/drivers/net/wireless/ath/ath9k/hif_usb.c b/drivers/net/wireless/ath/ath9k/hif_usb.c index f06eec99de688..518deb5098a2f 100644 --- a/drivers/net/wireless/ath/ath9k/hif_usb.c +++ b/drivers/net/wireless/ath/ath9k/hif_usb.c @@ -368,10 +368,9 @@ static int __hif_usb_tx(struct hif_device_usb *hif_dev) __skb_queue_head_init(&tx_buf->skb_queue); list_move_tail(&tx_buf->list, &hif_dev->tx.tx_buf); hif_dev->tx.tx_buf_cnt++; - } - - if (!ret) + } else { TX_STAT_INC(buf_queued); + } return ret; } From b72a4aff947ba807177bdabb43debaf2c66bee05 Mon Sep 17 00:00:00 2001 From: Abhishek Kumar Date: Wed, 27 Apr 2022 10:37:33 +0300 Subject: [PATCH 199/228] ath10k: skip ath10k_halt during suspend for driver state RESTARTING Double free crash is observed when FW recovery(caused by wmi timeout/crash) is followed by immediate suspend event. The FW recovery is triggered by ath10k_core_restart() which calls driver clean up via ath10k_halt(). When the suspend event occurs between the FW recovery, the restart worker thread is put into frozen state until suspend completes. The suspend event triggers ath10k_stop() which again triggers ath10k_halt() The double invocation of ath10k_halt() causes ath10k_htt_rx_free() to be called twice(Note: ath10k_htt_rx_alloc was not called by restart worker thread because of its frozen state), causing the crash. To fix this, during the suspend flow, skip call to ath10k_halt() in ath10k_stop() when the current driver state is ATH10K_STATE_RESTARTING. Also, for driver state ATH10K_STATE_RESTARTING, call ath10k_wait_for_suspend() in ath10k_stop(). This is because call to ath10k_wait_for_suspend() is skipped later in [ath10k_halt() > ath10k_core_stop()] for the driver state ATH10K_STATE_RESTARTING. The frozen restart worker thread will be cancelled during resume when the device comes out of suspend. Below is the crash stack for reference: [ 428.469167] ------------[ cut here ]------------ [ 428.469180] kernel BUG at mm/slub.c:4150! [ 428.469193] invalid opcode: 0000 [#1] PREEMPT SMP NOPTI [ 428.469219] Workqueue: events_unbound async_run_entry_fn [ 428.469230] RIP: 0010:kfree+0x319/0x31b [ 428.469241] RSP: 0018:ffffa1fac015fc30 EFLAGS: 00010246 [ 428.469247] RAX: ffffedb10419d108 RBX: ffff8c05262b0000 [ 428.469252] RDX: ffff8c04a8c07000 RSI: 0000000000000000 [ 428.469256] RBP: ffffa1fac015fc78 R08: 0000000000000000 [ 428.469276] CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033 [ 428.469285] Call Trace: [ 428.469295] ? dma_free_attrs+0x5f/0x7d [ 428.469320] ath10k_core_stop+0x5b/0x6f [ 428.469336] ath10k_halt+0x126/0x177 [ 428.469352] ath10k_stop+0x41/0x7e [ 428.469387] drv_stop+0x88/0x10e [ 428.469410] __ieee80211_suspend+0x297/0x411 [ 428.469441] rdev_suspend+0x6e/0xd0 [ 428.469462] wiphy_suspend+0xb1/0x105 [ 428.469483] ? name_show+0x2d/0x2d [ 428.469490] dpm_run_callback+0x8c/0x126 [ 428.469511] ? name_show+0x2d/0x2d [ 428.469517] __device_suspend+0x2e7/0x41b [ 428.469523] async_suspend+0x1f/0x93 [ 428.469529] async_run_entry_fn+0x3d/0xd1 [ 428.469535] process_one_work+0x1b1/0x329 [ 428.469541] worker_thread+0x213/0x372 [ 428.469547] kthread+0x150/0x15f [ 428.469552] ? pr_cont_work+0x58/0x58 [ 428.469558] ? kthread_blkcg+0x31/0x31 Tested-on: QCA6174 hw3.2 PCI WLAN.RM.4.4.1-00288-QCARMSWPZ-1 Co-developed-by: Wen Gong Signed-off-by: Wen Gong Signed-off-by: Abhishek Kumar Reviewed-by: Brian Norris Signed-off-by: Kalle Valo Link: https://lore.kernel.org/r/20220426221859.v2.1.I650b809482e1af8d0156ed88b5dc2677a0711d46@changeid --- drivers/net/wireless/ath/ath10k/mac.c | 20 ++++++++++++++++++-- 1 file changed, 18 insertions(+), 2 deletions(-) diff --git a/drivers/net/wireless/ath/ath10k/mac.c b/drivers/net/wireless/ath/ath10k/mac.c index a46f56a1efca6..75d7a004a1158 100644 --- a/drivers/net/wireless/ath/ath10k/mac.c +++ b/drivers/net/wireless/ath/ath10k/mac.c @@ -5338,13 +5338,29 @@ static int ath10k_start(struct ieee80211_hw *hw) static void ath10k_stop(struct ieee80211_hw *hw) { struct ath10k *ar = hw->priv; + u32 opt; ath10k_drain_tx(ar); mutex_lock(&ar->conf_mutex); if (ar->state != ATH10K_STATE_OFF) { - if (!ar->hw_rfkill_on) - ath10k_halt(ar); + if (!ar->hw_rfkill_on) { + /* If the current driver state is RESTARTING but not yet + * fully RESTARTED because of incoming suspend event, + * then ath10k_halt() is already called via + * ath10k_core_restart() and should not be called here. + */ + if (ar->state != ATH10K_STATE_RESTARTING) { + ath10k_halt(ar); + } else { + /* Suspending here, because when in RESTARTING + * state, ath10k_core_stop() skips + * ath10k_wait_for_suspend(). + */ + opt = WMI_PDEV_SUSPEND_AND_DISABLE_INTR; + ath10k_wait_for_suspend(ar, opt); + } + } ar->state = ATH10K_STATE_OFF; } mutex_unlock(&ar->conf_mutex); From eee645eccfc4edc9fb7dcef1b381e406c5dd4d14 Mon Sep 17 00:00:00 2001 From: Baochen Qiang Date: Fri, 29 Apr 2022 09:09:25 +0300 Subject: [PATCH 200/228] ath11k: Don't use GFP_KERNEL in atomic context We are seeing below warning: ... kernel: [ 5720.362941] BUG: sleeping function called from invalid context at include/linux/sched/mm.h:197 kernel: [ 5720.362943] in_atomic(): 1, irqs_disabled(): 0, non_block: 0, pid: 0, name: swapper/4 kernel: [ 5720.362947] CPU: 4 PID: 0 Comm: swapper/4 Tainted: G W 5.10.90 #18 4fa489e3e5c16043994f416310c2f60eff666320 kernel: [ 5720.362949] Hardware name: Google Nipperkin/Nipperkin, BIOS Google_Nipperkin.14316.0.0 10/30/2021 kernel: [ 5720.362950] Call Trace: kernel: [ 5720.362953] kernel: [ 5720.362959] dump_stack+0x9c/0xe7 kernel: [ 5720.362964] ___might_sleep+0x14a/0x160 kernel: [ 5720.362967] kmem_cache_alloc+0x46/0x226 kernel: [ 5720.362970] ? __alloc_skb+0x6c/0x19e kernel: [ 5720.362972] __alloc_skb+0x6c/0x19e kernel: [ 5720.362985] cfg80211_gtk_rekey_notify+0xa2/0x21d [cfg80211 2c8b5aee0416e7d010d70c332a47990fc843c1c5] kernel: [ 5720.362995] ath11k_wmi_gtk_offload_status_event+0x102/0x155 [ath11k 4c6bb5f7331c81199d56a7e37bdc10030f167838] kernel: [ 5720.363002] ath11k_wmi_tlv_op_rx+0x301/0x51b [ath11k 4c6bb5f7331c81199d56a7e37bdc10030f167838] kernel: [ 5720.363009] ath11k_htc_rx_completion_handler+0xee/0x3f5 [ath11k 4c6bb5f7331c81199d56a7e37bdc10030f167838] kernel: [ 5720.363017] ath11k_ce_per_engine_service+0x2aa/0x32c [ath11k 4c6bb5f7331c81199d56a7e37bdc10030f167838] kernel: [ 5720.363024] ath11k_pci_ce_tasklet+0x1a/0x30 [ath11k_pci 9acc399855ea172aa14a892c0bfdba0ce22d6f07] kernel: [ 5720.363028] tasklet_action_common+0x8d/0x9f kernel: [ 5720.363032] __do_softirq+0x163/0x29a kernel: [ 5720.363035] asm_call_irq_on_stack+0x12/0x20 kernel: [ 5720.363037] kernel: [ 5720.363041] do_softirq_own_stack+0x3c/0x48 kernel: [ 5720.363043] __irq_exit_rcu+0x9b/0x9d kernel: [ 5720.363046] common_interrupt+0xc9/0x14d kernel: [ 5720.363049] asm_common_interrupt+0x1e/0x40 kernel: [ 5720.363054] RIP: 0010:cpuidle_enter_state+0x1c5/0x2ac kernel: [ 5720.363056] Code: 84 f6 4c 8b 75 c0 74 1e 48 c7 45 c8 00 00 00 00 9c 8f 45 c8 0f ba 65 c8 09 0f 82 d1 00 00 00 31 ff e8 4a bb 6c ff fb 45 85 e4 <78> 47 44 89 e0 48 6b d0 68 49 8b 4c 16 48 48 2b 5d b8 49 89 5d 18 kernel: [ 5720.363058] RSP: 0018:ffffa7e640157e78 EFLAGS: 00000206 kernel: [ 5720.363060] RAX: ffff9807ddf29b40 RBX: 00000533e033584c RCX: 00000533e033584c kernel: [ 5720.363062] RDX: 0000000000000004 RSI: 0000000000000000 RDI: 0000000000000000 kernel: [ 5720.363063] RBP: ffffa7e640157ec0 R08: 0000000000000002 R09: 00000533e171bb7a kernel: [ 5720.363064] R10: 0000000000000900 R11: fffffffffffffffe R12: 0000000000000003 kernel: [ 5720.363065] R13: ffff9804c2ef6000 R14: ffffffffbe9a7bd0 R15: 0000000000000003 kernel: [ 5720.363069] ? cpuidle_enter_state+0x19a/0x2ac kernel: [ 5720.363072] cpuidle_enter+0x2e/0x3d kernel: [ 5720.363074] do_idle+0x163/0x1ee kernel: [ 5720.363076] cpu_startup_entry+0x1d/0x1f kernel: [ 5720.363078] secondary_startup_64_no_verify+0xb1/0xbb ... This is because GFP_KERNEL is used by ath11k_wmi_gtk_offload_status_event while in atomic context. Fix it by using GFP_ATOMIC instead. Tested-on: WCN6855 hw2.0 PCI WLAN.HSP.1.1-03125-QCAHSPSWPL_V1_V2_SILICONZ_LITE-3 Fixes: a16d9b50cfba ("ath11k: support GTK rekey offload") Signed-off-by: Baochen Qiang Signed-off-by: Kalle Valo Link: https://lore.kernel.org/r/20220427120033.1046759-1-quic_bqiang@quicinc.com --- drivers/net/wireless/ath/ath11k/wmi.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/net/wireless/ath/ath11k/wmi.c b/drivers/net/wireless/ath/ath11k/wmi.c index 3c0ac1e29479e..598ec061694f7 100644 --- a/drivers/net/wireless/ath/ath11k/wmi.c +++ b/drivers/net/wireless/ath/ath11k/wmi.c @@ -7844,7 +7844,7 @@ static void ath11k_wmi_gtk_offload_status_event(struct ath11k_base *ab, replay_ctr_be = cpu_to_be64(replay_ctr); ieee80211_gtk_rekey_notify(arvif->vif, arvif->bssid, - (void *)&replay_ctr_be, GFP_KERNEL); + (void *)&replay_ctr_be, GFP_ATOMIC); kfree(tb); } From 72a1a2edeb1cfb9d4400e19ff80ba5b0f93e9bd6 Mon Sep 17 00:00:00 2001 From: Jiapeng Chong Date: Fri, 29 Apr 2022 15:54:59 +0800 Subject: [PATCH 201/228] plfxlc: Remove unused include Eliminate the follow versioncheck warning: ./drivers/net/wireless/purelifi/plfxlc/usb.c: 20 linux/version.h not needed. Reported-by: Abaci Robot Signed-off-by: Jiapeng Chong Signed-off-by: Kalle Valo Link: https://lore.kernel.org/r/20220429075459.72029-1-jiapeng.chong@linux.alibaba.com --- drivers/net/wireless/purelifi/plfxlc/usb.c | 1 - 1 file changed, 1 deletion(-) diff --git a/drivers/net/wireless/purelifi/plfxlc/usb.c b/drivers/net/wireless/purelifi/plfxlc/usb.c index 6f338b1572a1c..d0e98b2f13652 100644 --- a/drivers/net/wireless/purelifi/plfxlc/usb.c +++ b/drivers/net/wireless/purelifi/plfxlc/usb.c @@ -17,7 +17,6 @@ #include #include #include -#include #include #include "mac.h" From 1d6d131d504922327dbef7aded01430a251d765c Mon Sep 17 00:00:00 2001 From: Chih-Kang Chang Date: Thu, 28 Apr 2022 10:05:19 +0800 Subject: [PATCH 202/228] rtw88: add HT MPDU density value for each chip Each chip have best ampdu density value, the correct setting can improve throughput performance. Signed-off-by: Chih-Kang Chang Signed-off-by: Ping-Ke Shih Signed-off-by: Kalle Valo Link: https://lore.kernel.org/r/20220428020521.8015-1-pkshih@realtek.com --- drivers/net/wireless/realtek/rtw88/main.c | 3 ++- drivers/net/wireless/realtek/rtw88/main.h | 1 + drivers/net/wireless/realtek/rtw88/rtw8723d.c | 1 + drivers/net/wireless/realtek/rtw88/rtw8821c.c | 1 + drivers/net/wireless/realtek/rtw88/rtw8822b.c | 1 + drivers/net/wireless/realtek/rtw88/rtw8822c.c | 1 + 6 files changed, 7 insertions(+), 1 deletion(-) diff --git a/drivers/net/wireless/realtek/rtw88/main.c b/drivers/net/wireless/realtek/rtw88/main.c index 7431988b59859..14289f83feb54 100644 --- a/drivers/net/wireless/realtek/rtw88/main.c +++ b/drivers/net/wireless/realtek/rtw88/main.c @@ -1461,6 +1461,7 @@ static void rtw_init_ht_cap(struct rtw_dev *rtwdev, struct ieee80211_sta_ht_cap *ht_cap) { struct rtw_efuse *efuse = &rtwdev->efuse; + struct rtw_chip_info *chip = rtwdev->chip; ht_cap->ht_supported = true; ht_cap->cap = 0; @@ -1478,7 +1479,7 @@ static void rtw_init_ht_cap(struct rtw_dev *rtwdev, IEEE80211_HT_CAP_DSSSCCK40 | IEEE80211_HT_CAP_SGI_40; ht_cap->ampdu_factor = IEEE80211_HT_MAX_AMPDU_64K; - ht_cap->ampdu_density = IEEE80211_HT_MPDU_DENSITY_16; + ht_cap->ampdu_density = chip->ampdu_density; ht_cap->mcs.tx_params = IEEE80211_HT_MCS_TX_DEFINED; if (efuse->hw_cap.nss > 1) { ht_cap->mcs.rx_mask[0] = 0xFF; diff --git a/drivers/net/wireless/realtek/rtw88/main.h b/drivers/net/wireless/realtek/rtw88/main.h index 2743074a42560..de149a3b3ba1b 100644 --- a/drivers/net/wireless/realtek/rtw88/main.h +++ b/drivers/net/wireless/realtek/rtw88/main.h @@ -1179,6 +1179,7 @@ struct rtw_chip_info { bool rx_ldpc; bool tx_stbc; u8 max_power_index; + u8 ampdu_density; u16 fw_fifo_addr[RTW_FW_FIFO_MAX]; const struct rtw_fwcd_segs *fwcd_segs; diff --git a/drivers/net/wireless/realtek/rtw88/rtw8723d.c b/drivers/net/wireless/realtek/rtw88/rtw8723d.c index ad2b323a0423c..93cce44df5318 100644 --- a/drivers/net/wireless/realtek/rtw88/rtw8723d.c +++ b/drivers/net/wireless/realtek/rtw88/rtw8723d.c @@ -2747,6 +2747,7 @@ struct rtw_chip_info rtw8723d_hw_spec = { .rx_ldpc = false, .pwr_track_tbl = &rtw8723d_rtw_pwr_track_tbl, .iqk_threshold = 8, + .ampdu_density = IEEE80211_HT_MPDU_DENSITY_16, .coex_para_ver = 0x2007022f, .bt_desired_ver = 0x2f, diff --git a/drivers/net/wireless/realtek/rtw88/rtw8821c.c b/drivers/net/wireless/realtek/rtw88/rtw8821c.c index ec38a7c849517..ffee39ea5df69 100644 --- a/drivers/net/wireless/realtek/rtw88/rtw8821c.c +++ b/drivers/net/wireless/realtek/rtw88/rtw8821c.c @@ -1923,6 +1923,7 @@ struct rtw_chip_info rtw8821c_hw_spec = { .iqk_threshold = 8, .bfer_su_max_num = 2, .bfer_mu_max_num = 1, + .ampdu_density = IEEE80211_HT_MPDU_DENSITY_2, .coex_para_ver = 0x19092746, .bt_desired_ver = 0x46, diff --git a/drivers/net/wireless/realtek/rtw88/rtw8822b.c b/drivers/net/wireless/realtek/rtw88/rtw8822b.c index eee7bf0354030..dccd722b8e624 100644 --- a/drivers/net/wireless/realtek/rtw88/rtw8822b.c +++ b/drivers/net/wireless/realtek/rtw88/rtw8822b.c @@ -2548,6 +2548,7 @@ struct rtw_chip_info rtw8822b_hw_spec = { .edcca_th = rtw8822b_edcca_th, .l2h_th_ini_cs = 10 + EDCCA_IGI_BASE, .l2h_th_ini_ad = -14 + EDCCA_IGI_BASE, + .ampdu_density = IEEE80211_HT_MPDU_DENSITY_2, .coex_para_ver = 0x20070206, .bt_desired_ver = 0x6, diff --git a/drivers/net/wireless/realtek/rtw88/rtw8822c.c b/drivers/net/wireless/realtek/rtw88/rtw8822c.c index cd74607a61a28..c043b5c520b9a 100644 --- a/drivers/net/wireless/realtek/rtw88/rtw8822c.c +++ b/drivers/net/wireless/realtek/rtw88/rtw8822c.c @@ -5368,6 +5368,7 @@ struct rtw_chip_info rtw8822c_hw_spec = { .edcca_th = rtw8822c_edcca_th, .l2h_th_ini_cs = 60, .l2h_th_ini_ad = 45, + .ampdu_density = IEEE80211_HT_MPDU_DENSITY_2, #ifdef CONFIG_PM .wow_fw_name = "rtw88/rtw8822c_wow_fw.bin", From 02ee806843bd8ee868a0a2ff4364188807ce321d Mon Sep 17 00:00:00 2001 From: Chih-Kang Chang Date: Thu, 28 Apr 2022 10:05:20 +0800 Subject: [PATCH 203/228] rtw88: fix not disabling beacon filter after disconnection Correct the judgment to let beacon filter disable after disconnection. Signed-off-by: Chih-Kang Chang Signed-off-by: Ping-Ke Shih Signed-off-by: Kalle Valo Link: https://lore.kernel.org/r/20220428020521.8015-2-pkshih@realtek.com --- drivers/net/wireless/realtek/rtw88/fw.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/drivers/net/wireless/realtek/rtw88/fw.c b/drivers/net/wireless/realtek/rtw88/fw.c index 3545d51c6951a..28cc8d680be31 100644 --- a/drivers/net/wireless/realtek/rtw88/fw.c +++ b/drivers/net/wireless/realtek/rtw88/fw.c @@ -649,7 +649,7 @@ void rtw_fw_beacon_filter_config(struct rtw_dev *rtwdev, bool connect, s32 threshold = bss_conf->cqm_rssi_thold + rssi_offset; u8 h2c_pkt[H2C_PKT_SIZE] = {0}; - if (!rtw_fw_feature_check(&rtwdev->fw, FW_FEATURE_BCN_FILTER) || !si) + if (!rtw_fw_feature_check(&rtwdev->fw, FW_FEATURE_BCN_FILTER)) return; if (!connect) { @@ -659,6 +659,10 @@ void rtw_fw_beacon_filter_config(struct rtw_dev *rtwdev, bool connect, return; } + + if (!si) + return; + SET_H2C_CMD_ID_CLASS(h2c_pkt, H2C_CMD_BCN_FILTER_OFFLOAD_P0); ether_addr_copy(&h2c_pkt[1], bss_conf->bssid); rtw_fw_send_h2c_command(rtwdev, h2c_pkt); From 5b3fd8fd7ceb135d08edf52adf6e833ee92a351e Mon Sep 17 00:00:00 2001 From: Chih-Kang Chang Date: Thu, 28 Apr 2022 10:05:21 +0800 Subject: [PATCH 204/228] rtw88: fix hw scan may cause disconnect issue After scan aborts we still receive some hw scan c2h packets, and processing these c2h commands will change current channel. If device already connect to other AP, driver will set wrong op channel due to current channel changed. The disconnection happens when hw scan back to wrong op channel that device can't receive beacon from AP. To fix this issue, we ignore the late c2h if we are not scanning, and set current channel back to op channel after scan to align the FW behavior. Signed-off-by: Chih-Kang Chang Signed-off-by: Ping-Ke Shih Signed-off-by: Kalle Valo Link: https://lore.kernel.org/r/20220428020521.8015-3-pkshih@realtek.com --- drivers/net/wireless/realtek/rtw88/fw.c | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/drivers/net/wireless/realtek/rtw88/fw.c b/drivers/net/wireless/realtek/rtw88/fw.c index 28cc8d680be31..e344e058f9432 100644 --- a/drivers/net/wireless/realtek/rtw88/fw.c +++ b/drivers/net/wireless/realtek/rtw88/fw.c @@ -2056,7 +2056,10 @@ void rtw_hw_scan_complete(struct rtw_dev *rtwdev, struct ieee80211_vif *vif, struct cfg80211_scan_info info = { .aborted = aborted, }; + struct rtw_hw_scan_info *scan_info = &rtwdev->scan_info; + struct rtw_hal *hal = &rtwdev->hal; struct rtw_vif *rtwvif; + u8 chan = scan_info->op_chan; if (!vif) return; @@ -2066,10 +2069,14 @@ void rtw_hw_scan_complete(struct rtw_dev *rtwdev, struct ieee80211_vif *vif, rtw_core_scan_complete(rtwdev, vif, true); + rtwvif = (struct rtw_vif *)vif->drv_priv; + if (rtwvif->net_type == RTW_NET_MGD_LINKED) { + hal->current_channel = chan; + hal->current_band_type = chan > 14 ? RTW_BAND_5G : RTW_BAND_2G; + } ieee80211_wake_queues(rtwdev->hw); ieee80211_scan_completed(rtwdev->hw, &info); - rtwvif = (struct rtw_vif *)vif->drv_priv; rtwvif->scan_req = NULL; rtwvif->scan_ies = NULL; rtwdev->scan_info.scanning_vif = NULL; @@ -2178,6 +2185,9 @@ void rtw_hw_scan_chan_switch(struct rtw_dev *rtwdev, struct sk_buff *skb) enum rtw_scan_notify_id id; u8 chan, status; + if (!test_bit(RTW_FLAG_SCANNING, rtwdev->flags)) + return; + c2h = get_c2h_from_skb(skb); chan = GET_CHAN_SWITCH_CENTRAL_CH(c2h->payload); id = GET_CHAN_SWITCH_ID(c2h->payload); From 7330e1ec9748948177830c6e1a13379835d577f9 Mon Sep 17 00:00:00 2001 From: Wen Gong Date: Fri, 29 Apr 2022 16:15:02 +0300 Subject: [PATCH 205/228] ath11k: fix warning of not found station for bssid in message When test connect/disconnect to an AP frequently with WCN6855, sometimes it show below log. [ 277.040121] wls1: deauthenticating from 8c:21:0a:b3:5a:64 by local choice (Reason: 3=DEAUTH_LEAVING) [ 277.050906] ath11k_pci 0000:05:00.0: wmi stats vdev id 0 mac 00:03:7f:29:61:11 [ 277.050944] ath11k_pci 0000:05:00.0: wmi stats bssid 8c:21:0a:b3:5a:64 vif pK-error [ 277.050954] ath11k_pci 0000:05:00.0: not found station for bssid 8c:21:0a:b3:5a:64 [ 277.050961] ath11k_pci 0000:05:00.0: failed to parse rssi chain -71 [ 277.050967] ath11k_pci 0000:05:00.0: failed to pull fw stats: -71 [ 277.050976] ath11k_pci 0000:05:00.0: wmi stats vdev id 0 mac 00:03:7f:29:61:11 [ 277.050983] ath11k_pci 0000:05:00.0: wmi stats bssid 8c:21:0a:b3:5a:64 vif pK-error [ 277.050989] ath11k_pci 0000:05:00.0: not found station for bssid 8c:21:0a:b3:5a:64 [ 277.050995] ath11k_pci 0000:05:00.0: failed to parse rssi chain -71 [ 277.051000] ath11k_pci 0000:05:00.0: failed to pull fw stats: -71 [ 278.064050] ath11k_pci 0000:05:00.0: failed to request fw stats: -110 Reason is: When running disconnect operation, sta_info removed from local->sta_hash by __sta_info_destroy_part1() from __sta_info_flush(), after this, ieee80211_find_sta_by_ifaddr() which called by ath11k_wmi_tlv_fw_stats_data_parse() and ath11k_wmi_tlv_rssi_chain_parse() cannot find this station, then failed log printed. steps are like this: 1. when disconnect from AP, __sta_info_destroy() called __sta_info_destroy_part1() and __sta_info_destroy_part2(). 2. in __sta_info_destroy_part1(), it has "sta_info_hash_del(local, sta)" and "list_del_rcu(&sta->list)", it will remove the ieee80211_sta from the list of ieee80211_hw. 3. in __sta_info_destroy_part2(), it called drv_sta_state()->ath11k_mac_op_sta_state(), then peer->sta is clear at this moment. 4. in __sta_info_destroy_part2(), it then called sta_set_sinfo()->drv_sta_statistics() ->ath11k_mac_op_sta_statistics(), then WMI_REQUEST_STATS_CMDID sent to firmware. 5. WMI_UPDATE_STATS_EVENTID reported from firmware, at this moment, the ieee80211_sta can not be found again because it has remove from list in step2 and also peer->sta is clear in step3. 6. in __sta_info_destroy_part2(), it then called cleanup_single_sta()-> sta_info_free()->kfree(sta), at this moment, the ieee80211_sta is freed in memory, then the failed log will not happen because function ath11k_mac_op_sta_state() will not be called. Actually this print log is not a real error, it is only to skip parse the info, so change to skip print by default debug setting. Tested-on: WCN6855 hw2.0 PCI WLAN.HSP.1.1-03125-QCAHSPSWPL_V1_V2_SILICONZ_LITE-3 Signed-off-by: Wen Gong Signed-off-by: Kalle Valo Link: https://lore.kernel.org/r/20220428022426.2927-1-quic_wgong@quicinc.com --- drivers/net/wireless/ath/ath11k/wmi.c | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/drivers/net/wireless/ath/ath11k/wmi.c b/drivers/net/wireless/ath/ath11k/wmi.c index 598ec061694f7..1410114d1d5cb 100644 --- a/drivers/net/wireless/ath/ath11k/wmi.c +++ b/drivers/net/wireless/ath/ath11k/wmi.c @@ -5794,9 +5794,9 @@ static int ath11k_wmi_tlv_rssi_chain_parse(struct ath11k_base *ab, arvif->bssid, NULL); if (!sta) { - ath11k_warn(ab, "not found station for bssid %pM\n", - arvif->bssid); - ret = -EPROTO; + ath11k_dbg(ab, ATH11K_DBG_WMI, + "not found station of bssid %pM for rssi chain\n", + arvif->bssid); goto exit; } @@ -5894,8 +5894,9 @@ static int ath11k_wmi_tlv_fw_stats_data_parse(struct ath11k_base *ab, "wmi stats vdev id %d snr %d\n", src->vdev_id, src->beacon_snr); } else { - ath11k_warn(ab, "not found station for bssid %pM\n", - arvif->bssid); + ath11k_dbg(ab, ATH11K_DBG_WMI, + "not found station of bssid %pM for vdev stat\n", + arvif->bssid); } } From 3a597f0d425b2160ce4278c3e1c8384bec8ccfb4 Mon Sep 17 00:00:00 2001 From: Wen Gong Date: Fri, 29 Apr 2022 16:15:02 +0300 Subject: [PATCH 206/228] ath11k: change management tx queue to avoid connection timed out In the phase of wlan load, it has hw scan and 11d scan which sent to firmware by ath11k, then hw scan and 11d scan will use about 14 seconds, and meanwhile ath11k_reg_update_chan_list() is running in workqueue of ath11k_base, and wait for 11d scan/hw scan finished. When the hw scan finished, mac80211 will start to connect and send management packet, at this moment, ath11k_reg_update_chan_list() is still waiting for 11d scan finished, so wmi_mgmt_tx_work of ath11k will not run and thus the tx management packet also not send out and lead authentication timed out. log: INFO kernel: [ 187.885322] wlan0: authenticate with 72:6c:57:43:9f:90 INFO kernel: [ 187.937266] wlan0: send auth to 72:6c:57:43:9f:90 (try 1/3) INFO kernel: [ 188.626944] wlan0: send auth to 72:6c:57:43:9f:90 (try 2/3) INFO kernel: [ 189.650999] wlan0: send auth to 72:6c:57:43:9f:90 (try 3/3) INFO kernel: [ 190.651917] wlan0: authentication with 72:6c:57:43:9f:90 timed out Change wmi_mgmt_tx_work to another queue workqueue_aux of ath11k_base, then connection success. Tested-on: WCN6855 hw2.0 PCI WLAN.HSP.1.1-03125-QCAHSPSWPL_V1_V2_SILICONZ_LITE-3 Signed-off-by: Wen Gong Signed-off-by: Kalle Valo Link: https://lore.kernel.org/r/20220428023320.4007-1-quic_wgong@quicinc.com --- drivers/net/wireless/ath/ath11k/mac.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/net/wireless/ath/ath11k/mac.c b/drivers/net/wireless/ath/ath11k/mac.c index c025bcb25c007..769319604340b 100644 --- a/drivers/net/wireless/ath/ath11k/mac.c +++ b/drivers/net/wireless/ath/ath11k/mac.c @@ -5592,7 +5592,7 @@ static int ath11k_mac_mgmt_tx(struct ath11k *ar, struct sk_buff *skb, skb_queue_tail(q, skb); atomic_inc(&ar->num_pending_mgmt_tx); - queue_work(ar->ab->workqueue, &ar->wmi_mgmt_tx_work); + queue_work(ar->ab->workqueue_aux, &ar->wmi_mgmt_tx_work); return 0; } From 00fd24089b8154ddf5b3e724e2c4c9974b9ba91e Mon Sep 17 00:00:00 2001 From: Manikanta Pubbisetty Date: Fri, 29 Apr 2022 22:34:54 +0530 Subject: [PATCH 207/228] dt: bindings: net: add bindings of WCN6750 for ath11k WCN6750 is the WLAN chip on Qualcomm Snapdragon SoC SC7280; Though being a PCIe based solution, it is not attached to the APSS processor (Application Processor SubSystem), it is instead attached to another tiny processor called WPSS Q6 processor (Wireless Processor SubSystem) on the SC7280 MSM, where the WLAN firmware runs, and it is the WLAN firmware running on the Q6 processor which enumerates WCN6750, as a result APPS processor would never know such a device being present in the system and would not detect the WCN6750 hardware unless and otherwise WCN6750 is registered as a platform device. This is the reason behind adding WCN6750 WLAN node in the device tree. Add WCN6750 wireless driver support, its based on ath11k driver. Reviewed-by: Rob Herring Signed-off-by: Manikanta Pubbisetty Signed-off-by: Kalle Valo Link: https://lore.kernel.org/r/20220429170502.20080-2-quic_mpubbise@quicinc.com --- .../bindings/net/wireless/qcom,ath11k.yaml | 361 ++++++++++++------ 1 file changed, 252 insertions(+), 109 deletions(-) diff --git a/Documentation/devicetree/bindings/net/wireless/qcom,ath11k.yaml b/Documentation/devicetree/bindings/net/wireless/qcom,ath11k.yaml index cdf7b873b419a..6b32caa8311c3 100644 --- a/Documentation/devicetree/bindings/net/wireless/qcom,ath11k.yaml +++ b/Documentation/devicetree/bindings/net/wireless/qcom,ath11k.yaml @@ -20,120 +20,17 @@ properties: enum: - qcom,ipq8074-wifi - qcom,ipq6018-wifi + - qcom,wcn6750-wifi reg: maxItems: 1 interrupts: - items: - - description: misc-pulse1 interrupt events - - description: misc-latch interrupt events - - description: sw exception interrupt events - - description: watchdog interrupt events - - description: interrupt event for ring CE0 - - description: interrupt event for ring CE1 - - description: interrupt event for ring CE2 - - description: interrupt event for ring CE3 - - description: interrupt event for ring CE4 - - description: interrupt event for ring CE5 - - description: interrupt event for ring CE6 - - description: interrupt event for ring CE7 - - description: interrupt event for ring CE8 - - description: interrupt event for ring CE9 - - description: interrupt event for ring CE10 - - description: interrupt event for ring CE11 - - description: interrupt event for ring host2wbm-desc-feed - - description: interrupt event for ring host2reo-re-injection - - description: interrupt event for ring host2reo-command - - description: interrupt event for ring host2rxdma-monitor-ring3 - - description: interrupt event for ring host2rxdma-monitor-ring2 - - description: interrupt event for ring host2rxdma-monitor-ring1 - - description: interrupt event for ring reo2ost-exception - - description: interrupt event for ring wbm2host-rx-release - - description: interrupt event for ring reo2host-status - - description: interrupt event for ring reo2host-destination-ring4 - - description: interrupt event for ring reo2host-destination-ring3 - - description: interrupt event for ring reo2host-destination-ring2 - - description: interrupt event for ring reo2host-destination-ring1 - - description: interrupt event for ring rxdma2host-monitor-destination-mac3 - - description: interrupt event for ring rxdma2host-monitor-destination-mac2 - - description: interrupt event for ring rxdma2host-monitor-destination-mac1 - - description: interrupt event for ring ppdu-end-interrupts-mac3 - - description: interrupt event for ring ppdu-end-interrupts-mac2 - - description: interrupt event for ring ppdu-end-interrupts-mac1 - - description: interrupt event for ring rxdma2host-monitor-status-ring-mac3 - - description: interrupt event for ring rxdma2host-monitor-status-ring-mac2 - - description: interrupt event for ring rxdma2host-monitor-status-ring-mac1 - - description: interrupt event for ring host2rxdma-host-buf-ring-mac3 - - description: interrupt event for ring host2rxdma-host-buf-ring-mac2 - - description: interrupt event for ring host2rxdma-host-buf-ring-mac1 - - description: interrupt event for ring rxdma2host-destination-ring-mac3 - - description: interrupt event for ring rxdma2host-destination-ring-mac2 - - description: interrupt event for ring rxdma2host-destination-ring-mac1 - - description: interrupt event for ring host2tcl-input-ring4 - - description: interrupt event for ring host2tcl-input-ring3 - - description: interrupt event for ring host2tcl-input-ring2 - - description: interrupt event for ring host2tcl-input-ring1 - - description: interrupt event for ring wbm2host-tx-completions-ring3 - - description: interrupt event for ring wbm2host-tx-completions-ring2 - - description: interrupt event for ring wbm2host-tx-completions-ring1 - - description: interrupt event for ring tcl2host-status-ring - + minItems: 32 + maxItems: 52 interrupt-names: - items: - - const: misc-pulse1 - - const: misc-latch - - const: sw-exception - - const: watchdog - - const: ce0 - - const: ce1 - - const: ce2 - - const: ce3 - - const: ce4 - - const: ce5 - - const: ce6 - - const: ce7 - - const: ce8 - - const: ce9 - - const: ce10 - - const: ce11 - - const: host2wbm-desc-feed - - const: host2reo-re-injection - - const: host2reo-command - - const: host2rxdma-monitor-ring3 - - const: host2rxdma-monitor-ring2 - - const: host2rxdma-monitor-ring1 - - const: reo2ost-exception - - const: wbm2host-rx-release - - const: reo2host-status - - const: reo2host-destination-ring4 - - const: reo2host-destination-ring3 - - const: reo2host-destination-ring2 - - const: reo2host-destination-ring1 - - const: rxdma2host-monitor-destination-mac3 - - const: rxdma2host-monitor-destination-mac2 - - const: rxdma2host-monitor-destination-mac1 - - const: ppdu-end-interrupts-mac3 - - const: ppdu-end-interrupts-mac2 - - const: ppdu-end-interrupts-mac1 - - const: rxdma2host-monitor-status-ring-mac3 - - const: rxdma2host-monitor-status-ring-mac2 - - const: rxdma2host-monitor-status-ring-mac1 - - const: host2rxdma-host-buf-ring-mac3 - - const: host2rxdma-host-buf-ring-mac2 - - const: host2rxdma-host-buf-ring-mac1 - - const: rxdma2host-destination-ring-mac3 - - const: rxdma2host-destination-ring-mac2 - - const: rxdma2host-destination-ring-mac1 - - const: host2tcl-input-ring4 - - const: host2tcl-input-ring3 - - const: host2tcl-input-ring2 - - const: host2tcl-input-ring1 - - const: wbm2host-tx-completions-ring3 - - const: wbm2host-tx-completions-ring2 - - const: wbm2host-tx-completions-ring1 - - const: tcl2host-status-ring + maxItems: 52 qcom,rproc: $ref: /schemas/types.yaml#/definitions/phandle @@ -151,20 +48,205 @@ properties: board-2.bin for designs with colliding bus and device specific ids memory-region: - maxItems: 1 + minItems: 1 + maxItems: 2 description: phandle to a node describing reserved memory (System RAM memory) used by ath11k firmware (see bindings/reserved-memory/reserved-memory.txt) + iommus: + minItems: 1 + maxItems: 2 + + wifi-firmware: + type: object + description: | + WCN6750 wifi node can contain one optional firmware subnode. + Firmware subnode is needed when the platform does not have Trustzone. + required: + - iommus + required: - compatible - reg - interrupts - - interrupt-names - qcom,rproc additionalProperties: false +allOf: + - if: + properties: + compatible: + contains: + enum: + - qcom,ipq8074-wifi + - qcom,ipq6018-wifi + then: + properties: + interrupts: + items: + - description: misc-pulse1 interrupt events + - description: misc-latch interrupt events + - description: sw exception interrupt events + - description: watchdog interrupt events + - description: interrupt event for ring CE0 + - description: interrupt event for ring CE1 + - description: interrupt event for ring CE2 + - description: interrupt event for ring CE3 + - description: interrupt event for ring CE4 + - description: interrupt event for ring CE5 + - description: interrupt event for ring CE6 + - description: interrupt event for ring CE7 + - description: interrupt event for ring CE8 + - description: interrupt event for ring CE9 + - description: interrupt event for ring CE10 + - description: interrupt event for ring CE11 + - description: interrupt event for ring host2wbm-desc-feed + - description: interrupt event for ring host2reo-re-injection + - description: interrupt event for ring host2reo-command + - description: interrupt event for ring host2rxdma-monitor-ring3 + - description: interrupt event for ring host2rxdma-monitor-ring2 + - description: interrupt event for ring host2rxdma-monitor-ring1 + - description: interrupt event for ring reo2ost-exception + - description: interrupt event for ring wbm2host-rx-release + - description: interrupt event for ring reo2host-status + - description: interrupt event for ring reo2host-destination-ring4 + - description: interrupt event for ring reo2host-destination-ring3 + - description: interrupt event for ring reo2host-destination-ring2 + - description: interrupt event for ring reo2host-destination-ring1 + - description: interrupt event for ring rxdma2host-monitor-destination-mac3 + - description: interrupt event for ring rxdma2host-monitor-destination-mac2 + - description: interrupt event for ring rxdma2host-monitor-destination-mac1 + - description: interrupt event for ring ppdu-end-interrupts-mac3 + - description: interrupt event for ring ppdu-end-interrupts-mac2 + - description: interrupt event for ring ppdu-end-interrupts-mac1 + - description: interrupt event for ring rxdma2host-monitor-status-ring-mac3 + - description: interrupt event for ring rxdma2host-monitor-status-ring-mac2 + - description: interrupt event for ring rxdma2host-monitor-status-ring-mac1 + - description: interrupt event for ring host2rxdma-host-buf-ring-mac3 + - description: interrupt event for ring host2rxdma-host-buf-ring-mac2 + - description: interrupt event for ring host2rxdma-host-buf-ring-mac1 + - description: interrupt event for ring rxdma2host-destination-ring-mac3 + - description: interrupt event for ring rxdma2host-destination-ring-mac2 + - description: interrupt event for ring rxdma2host-destination-ring-mac1 + - description: interrupt event for ring host2tcl-input-ring4 + - description: interrupt event for ring host2tcl-input-ring3 + - description: interrupt event for ring host2tcl-input-ring2 + - description: interrupt event for ring host2tcl-input-ring1 + - description: interrupt event for ring wbm2host-tx-completions-ring3 + - description: interrupt event for ring wbm2host-tx-completions-ring2 + - description: interrupt event for ring wbm2host-tx-completions-ring1 + - description: interrupt event for ring tcl2host-status-ring + interrupt-names: + items: + - const: misc-pulse1 + - const: misc-latch + - const: sw-exception + - const: watchdog + - const: ce0 + - const: ce1 + - const: ce2 + - const: ce3 + - const: ce4 + - const: ce5 + - const: ce6 + - const: ce7 + - const: ce8 + - const: ce9 + - const: ce10 + - const: ce11 + - const: host2wbm-desc-feed + - const: host2reo-re-injection + - const: host2reo-command + - const: host2rxdma-monitor-ring3 + - const: host2rxdma-monitor-ring2 + - const: host2rxdma-monitor-ring1 + - const: reo2ost-exception + - const: wbm2host-rx-release + - const: reo2host-status + - const: reo2host-destination-ring4 + - const: reo2host-destination-ring3 + - const: reo2host-destination-ring2 + - const: reo2host-destination-ring1 + - const: rxdma2host-monitor-destination-mac3 + - const: rxdma2host-monitor-destination-mac2 + - const: rxdma2host-monitor-destination-mac1 + - const: ppdu-end-interrupts-mac3 + - const: ppdu-end-interrupts-mac2 + - const: ppdu-end-interrupts-mac1 + - const: rxdma2host-monitor-status-ring-mac3 + - const: rxdma2host-monitor-status-ring-mac2 + - const: rxdma2host-monitor-status-ring-mac1 + - const: host2rxdma-host-buf-ring-mac3 + - const: host2rxdma-host-buf-ring-mac2 + - const: host2rxdma-host-buf-ring-mac1 + - const: rxdma2host-destination-ring-mac3 + - const: rxdma2host-destination-ring-mac2 + - const: rxdma2host-destination-ring-mac1 + - const: host2tcl-input-ring4 + - const: host2tcl-input-ring3 + - const: host2tcl-input-ring2 + - const: host2tcl-input-ring1 + - const: wbm2host-tx-completions-ring3 + - const: wbm2host-tx-completions-ring2 + - const: wbm2host-tx-completions-ring1 + - const: tcl2host-status-ring + + - if: + properties: + compatible: + contains: + enum: + - qcom,ipq8074-wifi + - qcom,ipq6018-wifi + then: + required: + - interrupt-names + + - if: + properties: + compatible: + contains: + enum: + - qcom,wcn6750-wifi + then: + properties: + interrupts: + items: + - description: interrupt event for ring CE1 + - description: interrupt event for ring CE2 + - description: interrupt event for ring CE3 + - description: interrupt event for ring CE4 + - description: interrupt event for ring CE5 + - description: interrupt event for ring CE6 + - description: interrupt event for ring CE7 + - description: interrupt event for ring CE8 + - description: interrupt event for ring CE9 + - description: interrupt event for ring CE10 + - description: interrupt event for ring DP1 + - description: interrupt event for ring DP2 + - description: interrupt event for ring DP3 + - description: interrupt event for ring DP4 + - description: interrupt event for ring DP5 + - description: interrupt event for ring DP6 + - description: interrupt event for ring DP7 + - description: interrupt event for ring DP8 + - description: interrupt event for ring DP9 + - description: interrupt event for ring DP10 + - description: interrupt event for ring DP11 + - description: interrupt event for ring DP12 + - description: interrupt event for ring DP13 + - description: interrupt event for ring DP14 + - description: interrupt event for ring DP15 + - description: interrupt event for ring DP16 + - description: interrupt event for ring DP17 + - description: interrupt event for ring DP18 + - description: interrupt event for ring DP19 + - description: interrupt event for ring DP20 + - description: interrupt event for ring DP21 + - description: interrupt event for ring DP22 + examples: - | @@ -309,3 +391,64 @@ examples: }; }; }; + + - | + #include + + reserved-memory { + #address-cells = <2>; + #size-cells = <2>; + + wlan_ce_mem: memory@4cd000 { + no-map; + reg = <0x0 0x004cd000 0x0 0x1000>; + }; + + wlan_fw_mem: memory@80c00000 { + no-map; + reg = <0x0 0x80c00000 0x0 0xc00000>; + }; + }; + + wifi: wifi@17a10040 { + compatible = "qcom,wcn6750-wifi"; + reg = <0x17a10040 0x0>; + iommus = <&apps_smmu 0x1c00 0x1>; + interrupts = , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + ; + qcom,rproc = <&remoteproc_wpss>; + memory-region = <&wlan_fw_mem>, <&wlan_ce_mem>; + wifi-firmware { + iommus = <&apps_smmu 0x1c02 0x1>; + }; + }; From 92c1858e4399edc093a41cbf8f74874bdab59da7 Mon Sep 17 00:00:00 2001 From: Manikanta Pubbisetty Date: Fri, 29 Apr 2022 22:34:55 +0530 Subject: [PATCH 208/228] ath11k: Move parameters in bus_params to hw_params In ath11k, bus_params were added with an intention to hold parameters related to bus (AHB/PCI), but this is not true as some bus parameters being different between chipsets of the same bus. With the addition of WCN6750 to ath11k, bus parameters are going to be entirely different among AHB devices. Therefore, it is wise to move bus_params to hw_params and get rid of bus_params entirely. Also, mhi_support parameter is not used anywhere in the driver, remove it from bus_params. Tested-on: WCN6750 hw1.0 AHB WLAN.MSL.1.0.1-00887-QCAMSLSWPLZ-1 Signed-off-by: Manikanta Pubbisetty Signed-off-by: Kalle Valo Link: https://lore.kernel.org/r/20220429170502.20080-3-quic_mpubbise@quicinc.com --- drivers/net/wireless/ath/ath11k/ahb.c | 11 ++-------- drivers/net/wireless/ath/ath11k/core.c | 28 +++++++++++++++++++++++--- drivers/net/wireless/ath/ath11k/core.h | 12 +---------- drivers/net/wireless/ath/ath11k/hw.h | 4 ++++ drivers/net/wireless/ath/ath11k/pci.c | 14 +++---------- drivers/net/wireless/ath/ath11k/pcic.c | 4 ++-- drivers/net/wireless/ath/ath11k/qmi.c | 23 +++++++++++---------- 7 files changed, 49 insertions(+), 47 deletions(-) diff --git a/drivers/net/wireless/ath/ath11k/ahb.c b/drivers/net/wireless/ath/ath11k/ahb.c index f407d4af2074b..49d79cfbf21c7 100644 --- a/drivers/net/wireless/ath/ath11k/ahb.c +++ b/drivers/net/wireless/ath/ath11k/ahb.c @@ -1,6 +1,7 @@ // SPDX-License-Identifier: BSD-3-Clause-Clear /* * Copyright (c) 2018-2019 The Linux Foundation. All rights reserved. + * Copyright (c) 2022 Qualcomm Innovation Center, Inc. All rights reserved. */ #include @@ -28,13 +29,6 @@ static const struct of_device_id ath11k_ahb_of_match[] = { MODULE_DEVICE_TABLE(of, ath11k_ahb_of_match); -static const struct ath11k_bus_params ath11k_ahb_bus_params = { - .mhi_support = false, - .m3_fw_support = false, - .fixed_bdf_addr = true, - .fixed_mem_region = true, -}; - #define ATH11K_IRQ_CE0_OFFSET 4 static const char *irq_name[ATH11K_IRQ_NUM_MAX] = { @@ -685,8 +679,7 @@ static int ath11k_ahb_probe(struct platform_device *pdev) } ab = ath11k_core_alloc(&pdev->dev, sizeof(struct ath11k_ahb), - ATH11K_BUS_AHB, - &ath11k_ahb_bus_params); + ATH11K_BUS_AHB); if (!ab) { dev_err(&pdev->dev, "failed to allocate ath11k base\n"); return -ENOMEM; diff --git a/drivers/net/wireless/ath/ath11k/core.c b/drivers/net/wireless/ath/ath11k/core.c index 7e074b7716e75..19b5bb06c7e8a 100644 --- a/drivers/net/wireless/ath/ath11k/core.c +++ b/drivers/net/wireless/ath/ath11k/core.c @@ -102,6 +102,10 @@ static const struct ath11k_hw_params ath11k_hw_params[] = { .dbr_debug_support = true, .global_reset = false, .bios_sar_capa = NULL, + .m3_fw_support = false, + .fixed_bdf_addr = true, + .fixed_mem_region = true, + .static_window_map = false, }, { .hw_rev = ATH11K_HW_IPQ6018_HW10, @@ -169,6 +173,10 @@ static const struct ath11k_hw_params ath11k_hw_params[] = { .dbr_debug_support = true, .global_reset = false, .bios_sar_capa = NULL, + .m3_fw_support = false, + .fixed_bdf_addr = true, + .fixed_mem_region = true, + .static_window_map = false, }, { .name = "qca6390 hw2.0", @@ -235,6 +243,10 @@ static const struct ath11k_hw_params ath11k_hw_params[] = { .dbr_debug_support = false, .global_reset = true, .bios_sar_capa = NULL, + .m3_fw_support = true, + .fixed_bdf_addr = false, + .fixed_mem_region = false, + .static_window_map = false, }, { .name = "qcn9074 hw1.0", @@ -301,6 +313,10 @@ static const struct ath11k_hw_params ath11k_hw_params[] = { .dbr_debug_support = true, .global_reset = false, .bios_sar_capa = NULL, + .m3_fw_support = true, + .fixed_bdf_addr = false, + .fixed_mem_region = false, + .static_window_map = true, }, { .name = "wcn6855 hw2.0", @@ -367,6 +383,10 @@ static const struct ath11k_hw_params ath11k_hw_params[] = { .dbr_debug_support = false, .global_reset = true, .bios_sar_capa = &ath11k_hw_sar_capa_wcn6855, + .m3_fw_support = true, + .fixed_bdf_addr = false, + .fixed_mem_region = false, + .static_window_map = false, }, { .name = "wcn6855 hw2.1", @@ -432,6 +452,10 @@ static const struct ath11k_hw_params ath11k_hw_params[] = { .dbr_debug_support = false, .global_reset = true, .bios_sar_capa = &ath11k_hw_sar_capa_wcn6855, + .m3_fw_support = true, + .fixed_bdf_addr = false, + .fixed_mem_region = false, + .static_window_map = false, }, }; @@ -1730,8 +1754,7 @@ void ath11k_core_free(struct ath11k_base *ab) EXPORT_SYMBOL(ath11k_core_free); struct ath11k_base *ath11k_core_alloc(struct device *dev, size_t priv_size, - enum ath11k_bus bus, - const struct ath11k_bus_params *bus_params) + enum ath11k_bus bus) { struct ath11k_base *ab; @@ -1770,7 +1793,6 @@ struct ath11k_base *ath11k_core_alloc(struct device *dev, size_t priv_size, init_completion(&ab->wow.wakeup_completed); ab->dev = dev; - ab->bus_params = *bus_params; ab->hif.bus = bus; return ab; diff --git a/drivers/net/wireless/ath/ath11k/core.h b/drivers/net/wireless/ath/ath11k/core.h index 7a505531acf92..d8ab28413d95a 100644 --- a/drivers/net/wireless/ath/ath11k/core.h +++ b/drivers/net/wireless/ath/ath11k/core.h @@ -748,14 +748,6 @@ struct ath11k_board_data { size_t len; }; -struct ath11k_bus_params { - bool mhi_support; - bool m3_fw_support; - bool fixed_bdf_addr; - bool fixed_mem_region; - bool static_window_map; -}; - struct ath11k_pci_ops { int (*wakeup)(struct ath11k_base *ab); void (*release)(struct ath11k_base *ab); @@ -887,7 +879,6 @@ struct ath11k_base { int bd_api; struct ath11k_hw_params hw_params; - struct ath11k_bus_params bus_params; const struct firmware *cal_file; @@ -1135,8 +1126,7 @@ int ath11k_core_pre_init(struct ath11k_base *ab); int ath11k_core_init(struct ath11k_base *ath11k); void ath11k_core_deinit(struct ath11k_base *ath11k); struct ath11k_base *ath11k_core_alloc(struct device *dev, size_t priv_size, - enum ath11k_bus bus, - const struct ath11k_bus_params *bus_params); + enum ath11k_bus bus); void ath11k_core_free(struct ath11k_base *ath11k); int ath11k_core_fetch_bdf(struct ath11k_base *ath11k, struct ath11k_board_data *bd); diff --git a/drivers/net/wireless/ath/ath11k/hw.h b/drivers/net/wireless/ath/ath11k/hw.h index b7ece3d5678c3..09fa020bfee45 100644 --- a/drivers/net/wireless/ath/ath11k/hw.h +++ b/drivers/net/wireless/ath/ath11k/hw.h @@ -196,6 +196,10 @@ struct ath11k_hw_params { bool dbr_debug_support; bool global_reset; const struct cfg80211_sar_capa *bios_sar_capa; + bool m3_fw_support; + bool fixed_bdf_addr; + bool fixed_mem_region; + bool static_window_map; }; struct ath11k_hw_ops { diff --git a/drivers/net/wireless/ath/ath11k/pci.c b/drivers/net/wireless/ath/ath11k/pci.c index 024661a170085..dedf1b88ddf6b 100644 --- a/drivers/net/wireless/ath/ath11k/pci.c +++ b/drivers/net/wireless/ath/ath11k/pci.c @@ -115,13 +115,6 @@ static const struct ath11k_pci_ops ath11k_pci_ops_qcn9074 = { .window_read32 = ath11k_pci_window_read32, }; -static const struct ath11k_bus_params ath11k_pci_bus_params = { - .mhi_support = true, - .m3_fw_support = true, - .fixed_bdf_addr = false, - .fixed_mem_region = false, -}; - static const struct ath11k_msi_config msi_config_one_msi = { .total_vectors = 1, .total_users = 4, @@ -593,7 +586,7 @@ static int ath11k_pci_power_up(struct ath11k_base *ab) return ret; } - if (ab->bus_params.static_window_map) + if (ab->hw_params.static_window_map) ath11k_pci_select_static_window(ab_pci); return 0; @@ -706,8 +699,8 @@ static int ath11k_pci_probe(struct pci_dev *pdev, u32 soc_hw_version_major, soc_hw_version_minor, addr; int ret; - ab = ath11k_core_alloc(&pdev->dev, sizeof(*ab_pci), ATH11K_BUS_PCI, - &ath11k_pci_bus_params); + ab = ath11k_core_alloc(&pdev->dev, sizeof(*ab_pci), ATH11K_BUS_PCI); + if (!ab) { dev_err(&pdev->dev, "failed to allocate ath11k base\n"); return -ENOMEM; @@ -764,7 +757,6 @@ static int ath11k_pci_probe(struct pci_dev *pdev, ab->pci.ops = &ath11k_pci_ops_qca6390; break; case QCN9074_DEVICE_ID: - ab->bus_params.static_window_map = true; ab->pci.ops = &ath11k_pci_ops_qcn9074; ab->hw_rev = ATH11K_HW_QCN9074_HW10; break; diff --git a/drivers/net/wireless/ath/ath11k/pcic.c b/drivers/net/wireless/ath/ath11k/pcic.c index 63c678aea29e0..7a920d65023f6 100644 --- a/drivers/net/wireless/ath/ath11k/pcic.c +++ b/drivers/net/wireless/ath/ath11k/pcic.c @@ -163,7 +163,7 @@ void ath11k_pcic_write32(struct ath11k_base *ab, u32 offset, u32 value) if (offset < ATH11K_PCI_WINDOW_START) { iowrite32(value, ab->mem + offset); } else { - if (ab->bus_params.static_window_map) + if (ab->hw_params.static_window_map) window_start = ath11k_pcic_get_window_start(ab, offset); else window_start = ATH11K_PCI_WINDOW_START; @@ -198,7 +198,7 @@ u32 ath11k_pcic_read32(struct ath11k_base *ab, u32 offset) if (offset < ATH11K_PCI_WINDOW_START) { val = ioread32(ab->mem + offset); } else { - if (ab->bus_params.static_window_map) + if (ab->hw_params.static_window_map) window_start = ath11k_pcic_get_window_start(ab, offset); else window_start = ATH11K_PCI_WINDOW_START; diff --git a/drivers/net/wireless/ath/ath11k/qmi.c b/drivers/net/wireless/ath/ath11k/qmi.c index 0442faa3b7afb..c89e761082371 100644 --- a/drivers/net/wireless/ath/ath11k/qmi.c +++ b/drivers/net/wireless/ath/ath11k/qmi.c @@ -1,6 +1,7 @@ // SPDX-License-Identifier: BSD-3-Clause-Clear /* * Copyright (c) 2018-2019 The Linux Foundation. All rights reserved. + * Copyright (c) 2022 Qualcomm Innovation Center, Inc. All rights reserved. */ #include @@ -1648,7 +1649,7 @@ static int ath11k_qmi_host_cap_send(struct ath11k_base *ab) req.bdf_support_valid = 1; req.bdf_support = 1; - if (ab->bus_params.m3_fw_support) { + if (ab->hw_params.m3_fw_support) { req.m3_support_valid = 1; req.m3_support = 1; req.m3_cache_support_valid = 1; @@ -1803,7 +1804,7 @@ static int ath11k_qmi_respond_fw_mem_request(struct ath11k_base *ab) * failure to FW and FW will then request mulitple blocks of small * chunk size memory. */ - if (!(ab->bus_params.fixed_mem_region || + if (!(ab->hw_params.fixed_mem_region || test_bit(ATH11K_FLAG_FIXED_MEM_RGN, &ab->dev_flags)) && ab->qmi.target_mem_delayed) { delayed = true; @@ -1873,7 +1874,7 @@ static void ath11k_qmi_free_target_mem_chunk(struct ath11k_base *ab) int i; for (i = 0; i < ab->qmi.mem_seg_count; i++) { - if ((ab->bus_params.fixed_mem_region || + if ((ab->hw_params.fixed_mem_region || test_bit(ATH11K_FLAG_FIXED_MEM_RGN, &ab->dev_flags)) && ab->qmi.target_mem[i].iaddr) iounmap(ab->qmi.target_mem[i].iaddr); @@ -2124,7 +2125,7 @@ static int ath11k_qmi_load_file_target_mem(struct ath11k_base *ab, memset(&resp, 0, sizeof(resp)); - if (ab->bus_params.fixed_bdf_addr) { + if (ab->hw_params.fixed_bdf_addr) { bdf_addr = ioremap(ab->hw_params.bdf_addr, ab->hw_params.fw.board_size); if (!bdf_addr) { ath11k_warn(ab, "qmi ioremap error for bdf_addr\n"); @@ -2153,7 +2154,7 @@ static int ath11k_qmi_load_file_target_mem(struct ath11k_base *ab, req->end = 1; } - if (ab->bus_params.fixed_bdf_addr || + if (ab->hw_params.fixed_bdf_addr || type == ATH11K_QMI_FILE_TYPE_EEPROM) { req->data_valid = 0; req->end = 1; @@ -2162,7 +2163,7 @@ static int ath11k_qmi_load_file_target_mem(struct ath11k_base *ab, memcpy(req->data, temp, req->data_len); } - if (ab->bus_params.fixed_bdf_addr) { + if (ab->hw_params.fixed_bdf_addr) { if (type == ATH11K_QMI_FILE_TYPE_CALDATA) bdf_addr += ab->hw_params.fw.cal_offset; @@ -2201,7 +2202,7 @@ static int ath11k_qmi_load_file_target_mem(struct ath11k_base *ab, goto err_iounmap; } - if (ab->bus_params.fixed_bdf_addr || + if (ab->hw_params.fixed_bdf_addr || type == ATH11K_QMI_FILE_TYPE_EEPROM) { remaining = 0; } else { @@ -2214,7 +2215,7 @@ static int ath11k_qmi_load_file_target_mem(struct ath11k_base *ab, } err_iounmap: - if (ab->bus_params.fixed_bdf_addr) + if (ab->hw_params.fixed_bdf_addr) iounmap(bdf_addr); err_free_req: @@ -2353,7 +2354,7 @@ static void ath11k_qmi_m3_free(struct ath11k_base *ab) { struct m3_mem_region *m3_mem = &ab->qmi.m3_mem; - if (!ab->bus_params.m3_fw_support || !m3_mem->vaddr) + if (!ab->hw_params.m3_fw_support || !m3_mem->vaddr) return; dma_free_coherent(ab->dev, m3_mem->size, @@ -2373,7 +2374,7 @@ static int ath11k_qmi_wlanfw_m3_info_send(struct ath11k_base *ab) memset(&req, 0, sizeof(req)); memset(&resp, 0, sizeof(resp)); - if (ab->bus_params.m3_fw_support) { + if (ab->hw_params.m3_fw_support) { ret = ath11k_qmi_m3_load(ab); if (ret) { ath11k_err(ab, "failed to load m3 firmware: %d", ret); @@ -2792,7 +2793,7 @@ static void ath11k_qmi_msg_mem_request_cb(struct qmi_handle *qmi_hdl, msg->mem_seg[i].type, msg->mem_seg[i].size); } - if (ab->bus_params.fixed_mem_region || + if (ab->hw_params.fixed_mem_region || test_bit(ATH11K_FLAG_FIXED_MEM_RGN, &ab->dev_flags)) { ret = ath11k_qmi_assign_target_mem_chunk(ab); if (ret) { From d1e1edfde0352321af52599ad447b71c91bc6e76 Mon Sep 17 00:00:00 2001 From: Manikanta Pubbisetty Date: Fri, 29 Apr 2022 22:34:56 +0530 Subject: [PATCH 209/228] ath11k: Add HW params for WCN6750 WCN6750 is a PCIe based solution that is attached to and enumerated by the WPSS (Wireless Processor SubSystem) Q6 processor. Though it is a PCIe device, since it is not attached to APSS processor (Application Processor SubSystem), APSS will be unaware of such a decice and hence it is registered to the APSS processor as a platform device(AHB). Because of this hybrid nature, it is called as a hybrid bus device. A new variable hybrid_bus_type is defined in hw_params to indicate the hybrid nature of the device. Add HW params for WCN6750. Tested-on: WCN6750 hw1.0 AHB WLAN.MSL.1.0.1-00887-QCAMSLSWPLZ-1 Tested-on: WCN6855 hw2.0 PCI WLAN.HSP.1.1-01720.1-QCAHSPSWPL_V1_V2_SILICONZ_LITE-1 Tested-on: QCN9074 hw1.0 PCI WLAN.HK.2.5.0.1-01100-QCAHKSWPL_SILICONZ-1 Tested-on: IPQ8074 hw2.0 AHB WLAN.HK.2.4.0.1-00192-QCAHKSWPL_SILICONZ-1 Signed-off-by: Manikanta Pubbisetty Signed-off-by: Kalle Valo Link: https://lore.kernel.org/r/20220429170502.20080-4-quic_mpubbise@quicinc.com --- drivers/net/wireless/ath/ath11k/core.c | 73 ++++++++++++++++++++++++++ drivers/net/wireless/ath/ath11k/core.h | 1 + drivers/net/wireless/ath/ath11k/hw.h | 1 + drivers/net/wireless/ath/ath11k/qmi.h | 2 + 4 files changed, 77 insertions(+) diff --git a/drivers/net/wireless/ath/ath11k/core.c b/drivers/net/wireless/ath/ath11k/core.c index 19b5bb06c7e8a..1220514e19bf9 100644 --- a/drivers/net/wireless/ath/ath11k/core.c +++ b/drivers/net/wireless/ath/ath11k/core.c @@ -106,6 +106,7 @@ static const struct ath11k_hw_params ath11k_hw_params[] = { .fixed_bdf_addr = true, .fixed_mem_region = true, .static_window_map = false, + .hybrid_bus_type = false, }, { .hw_rev = ATH11K_HW_IPQ6018_HW10, @@ -177,6 +178,7 @@ static const struct ath11k_hw_params ath11k_hw_params[] = { .fixed_bdf_addr = true, .fixed_mem_region = true, .static_window_map = false, + .hybrid_bus_type = false, }, { .name = "qca6390 hw2.0", @@ -247,6 +249,7 @@ static const struct ath11k_hw_params ath11k_hw_params[] = { .fixed_bdf_addr = false, .fixed_mem_region = false, .static_window_map = false, + .hybrid_bus_type = false, }, { .name = "qcn9074 hw1.0", @@ -317,6 +320,7 @@ static const struct ath11k_hw_params ath11k_hw_params[] = { .fixed_bdf_addr = false, .fixed_mem_region = false, .static_window_map = true, + .hybrid_bus_type = false, }, { .name = "wcn6855 hw2.0", @@ -387,6 +391,7 @@ static const struct ath11k_hw_params ath11k_hw_params[] = { .fixed_bdf_addr = false, .fixed_mem_region = false, .static_window_map = false, + .hybrid_bus_type = false, }, { .name = "wcn6855 hw2.1", @@ -456,6 +461,74 @@ static const struct ath11k_hw_params ath11k_hw_params[] = { .fixed_bdf_addr = false, .fixed_mem_region = false, .static_window_map = false, + .hybrid_bus_type = false, + }, + { + .name = "wcn6750 hw1.0", + .hw_rev = ATH11K_HW_WCN6750_HW10, + .fw = { + .dir = "WCN6750/hw1.0", + .board_size = 256 * 1024, + .cal_offset = 128 * 1024, + }, + .max_radios = 1, + .bdf_addr = 0x4B0C0000, + .ring_mask = &ath11k_hw_ring_mask_qca6390, + .internal_sleep_clock = false, + .qmi_service_ins_id = ATH11K_QMI_WLFW_SERVICE_INS_ID_V01_WCN6750, + .host_ce_config = ath11k_host_ce_config_qca6390, + .ce_count = 9, + .target_ce_config = ath11k_target_ce_config_wlan_qca6390, + .target_ce_count = 9, + .svc_to_ce_map = ath11k_target_service_to_ce_map_wlan_qca6390, + .svc_to_ce_map_len = 14, + .rfkill_pin = 0, + .rfkill_cfg = 0, + .rfkill_on_level = 0, + .single_pdev_only = true, + .rxdma1_enable = false, + .num_rxmda_per_pdev = 1, + .rx_mac_buf_ring = true, + .vdev_start_delay = true, + .htt_peer_map_v2 = false, + + .spectral = { + .fft_sz = 0, + .fft_pad_sz = 0, + .summary_pad_sz = 0, + .fft_hdr_len = 0, + .max_fft_bins = 0, + }, + + .interface_modes = BIT(NL80211_IFTYPE_STATION) | + BIT(NL80211_IFTYPE_AP), + .supports_monitor = false, + .supports_shadow_regs = true, + .idle_ps = true, + .supports_sta_ps = true, + .cold_boot_calib = false, + .fw_mem_mode = 0, + .num_vdevs = 16 + 1, + .num_peers = 512, + .supports_suspend = false, + .supports_regdb = true, + .fix_l1ss = false, + .credit_flow = true, + .max_tx_ring = DP_TCL_NUM_RING_MAX_QCA6390, + .hal_params = &ath11k_hw_hal_params_qca6390, + .supports_dynamic_smps_6ghz = false, + .alloc_cacheable_memory = false, + .supports_rssi_stats = true, + .fw_wmi_diag_event = false, + .current_cc_support = true, + .dbr_debug_support = false, + .global_reset = false, + .bios_sar_capa = NULL, + .m3_fw_support = false, + .fixed_bdf_addr = false, + .fixed_mem_region = false, + .static_window_map = true, + .hybrid_bus_type = true, }, }; diff --git a/drivers/net/wireless/ath/ath11k/core.h b/drivers/net/wireless/ath/ath11k/core.h index d8ab28413d95a..fdea446271255 100644 --- a/drivers/net/wireless/ath/ath11k/core.h +++ b/drivers/net/wireless/ath/ath11k/core.h @@ -140,6 +140,7 @@ enum ath11k_hw_rev { ATH11K_HW_QCN9074_HW10, ATH11K_HW_WCN6855_HW20, ATH11K_HW_WCN6855_HW21, + ATH11K_HW_WCN6750_HW10, }; enum ath11k_firmware_mode { diff --git a/drivers/net/wireless/ath/ath11k/hw.h b/drivers/net/wireless/ath/ath11k/hw.h index 09fa020bfee45..03eb5dfd4a5ea 100644 --- a/drivers/net/wireless/ath/ath11k/hw.h +++ b/drivers/net/wireless/ath/ath11k/hw.h @@ -200,6 +200,7 @@ struct ath11k_hw_params { bool fixed_bdf_addr; bool fixed_mem_region; bool static_window_map; + bool hybrid_bus_type; }; struct ath11k_hw_ops { diff --git a/drivers/net/wireless/ath/ath11k/qmi.h b/drivers/net/wireless/ath/ath11k/qmi.h index 61678de56ac7e..e0201e1847337 100644 --- a/drivers/net/wireless/ath/ath11k/qmi.h +++ b/drivers/net/wireless/ath/ath11k/qmi.h @@ -1,6 +1,7 @@ /* SPDX-License-Identifier: BSD-3-Clause-Clear */ /* * Copyright (c) 2018-2019 The Linux Foundation. All rights reserved. + * Copyright (c) 2022, Qualcomm Innovation Center, Inc. All rights reserved. */ #ifndef ATH11K_QMI_H @@ -20,6 +21,7 @@ #define ATH11K_QMI_WLFW_SERVICE_INS_ID_V01_QCA6390 0x01 #define ATH11K_QMI_WLFW_SERVICE_INS_ID_V01_IPQ8074 0x02 #define ATH11K_QMI_WLFW_SERVICE_INS_ID_V01_QCN9074 0x07 +#define ATH11K_QMI_WLFW_SERVICE_INS_ID_V01_WCN6750 0x03 #define ATH11K_QMI_WLANFW_MAX_TIMESTAMP_LEN_V01 32 #define ATH11K_QMI_RESP_LEN_MAX 8192 #define ATH11K_QMI_WLANFW_MAX_NUM_MEM_SEG_V01 52 From 56c8ccf331bd2ebf8b85f70efb4844803ef3f768 Mon Sep 17 00:00:00 2001 From: Manikanta Pubbisetty Date: Fri, 29 Apr 2022 22:34:57 +0530 Subject: [PATCH 210/228] ath11k: Add register access logic for WCN6750 WCN6750 uses static window mapping to access the HW registers. Unlike QCN9074 which uses 3rd window for UMAC and 2nd window for CE register access, WCN6750 uses 1st window for UMAC and 2nd window for CE registers. Also, refactor the code so that WCN6750 can use the existing ath11k_pci_read32/write32() APIs for accessing the registers. Tested-on: WCN6750 hw1.0 AHB WLAN.MSL.1.0.1-00887-QCAMSLSWPLZ-1 Tested-on: WCN6855 hw2.0 PCI WLAN.HSP.1.1-01720.1-QCAHSPSWPL_V1_V2_SILICONZ_LITE-1 Tested-on: QCN9074 hw1.0 PCI WLAN.HK.2.5.0.1-01100-QCAHKSWPL_SILICONZ-1 Tested-on: IPQ8074 hw2.0 AHB WLAN.HK.2.4.0.1-00192-QCAHKSWPL_SILICONZ-1 Signed-off-by: Manikanta Pubbisetty Signed-off-by: Kalle Valo Link: https://lore.kernel.org/r/20220429170502.20080-5-quic_mpubbise@quicinc.com --- drivers/net/wireless/ath/ath11k/core.c | 14 +++++++ drivers/net/wireless/ath/ath11k/hw.h | 2 + drivers/net/wireless/ath/ath11k/pcic.c | 54 +++++++++----------------- 3 files changed, 35 insertions(+), 35 deletions(-) diff --git a/drivers/net/wireless/ath/ath11k/core.c b/drivers/net/wireless/ath/ath11k/core.c index 1220514e19bf9..3be4327b4d9c4 100644 --- a/drivers/net/wireless/ath/ath11k/core.c +++ b/drivers/net/wireless/ath/ath11k/core.c @@ -107,6 +107,8 @@ static const struct ath11k_hw_params ath11k_hw_params[] = { .fixed_mem_region = true, .static_window_map = false, .hybrid_bus_type = false, + .dp_window_idx = 0, + .ce_window_idx = 0, }, { .hw_rev = ATH11K_HW_IPQ6018_HW10, @@ -179,6 +181,8 @@ static const struct ath11k_hw_params ath11k_hw_params[] = { .fixed_mem_region = true, .static_window_map = false, .hybrid_bus_type = false, + .dp_window_idx = 0, + .ce_window_idx = 0, }, { .name = "qca6390 hw2.0", @@ -250,6 +254,8 @@ static const struct ath11k_hw_params ath11k_hw_params[] = { .fixed_mem_region = false, .static_window_map = false, .hybrid_bus_type = false, + .dp_window_idx = 0, + .ce_window_idx = 0, }, { .name = "qcn9074 hw1.0", @@ -321,6 +327,8 @@ static const struct ath11k_hw_params ath11k_hw_params[] = { .fixed_mem_region = false, .static_window_map = true, .hybrid_bus_type = false, + .dp_window_idx = 3, + .ce_window_idx = 2, }, { .name = "wcn6855 hw2.0", @@ -392,6 +400,8 @@ static const struct ath11k_hw_params ath11k_hw_params[] = { .fixed_mem_region = false, .static_window_map = false, .hybrid_bus_type = false, + .dp_window_idx = 0, + .ce_window_idx = 0, }, { .name = "wcn6855 hw2.1", @@ -462,6 +472,8 @@ static const struct ath11k_hw_params ath11k_hw_params[] = { .fixed_mem_region = false, .static_window_map = false, .hybrid_bus_type = false, + .dp_window_idx = 0, + .ce_window_idx = 0, }, { .name = "wcn6750 hw1.0", @@ -529,6 +541,8 @@ static const struct ath11k_hw_params ath11k_hw_params[] = { .fixed_mem_region = false, .static_window_map = true, .hybrid_bus_type = true, + .dp_window_idx = 1, + .ce_window_idx = 2, }, }; diff --git a/drivers/net/wireless/ath/ath11k/hw.h b/drivers/net/wireless/ath/ath11k/hw.h index 03eb5dfd4a5ea..b63538084215e 100644 --- a/drivers/net/wireless/ath/ath11k/hw.h +++ b/drivers/net/wireless/ath/ath11k/hw.h @@ -201,6 +201,8 @@ struct ath11k_hw_params { bool fixed_mem_region; bool static_window_map; bool hybrid_bus_type; + u8 dp_window_idx; + u8 ce_window_idx; }; struct ath11k_hw_ops { diff --git a/drivers/net/wireless/ath/ath11k/pcic.c b/drivers/net/wireless/ath/ath11k/pcic.c index 7a920d65023f6..46cf96d3e1d2d 100644 --- a/drivers/net/wireless/ath/ath11k/pcic.c +++ b/drivers/net/wireless/ath/ath11k/pcic.c @@ -134,16 +134,13 @@ EXPORT_SYMBOL(ath11k_pcic_init_msi_config); static inline u32 ath11k_pcic_get_window_start(struct ath11k_base *ab, u32 offset) { - u32 window_start; + u32 window_start = 0; - /* If offset lies within DP register range, use 3rd window */ if ((offset ^ HAL_SEQ_WCSS_UMAC_OFFSET) < ATH11K_PCI_WINDOW_RANGE_MASK) - window_start = 3 * ATH11K_PCI_WINDOW_START; - /* If offset lies within CE register range, use 2nd window */ - else if ((offset ^ HAL_CE_WFSS_CE_REG_BASE) < ATH11K_PCI_WINDOW_RANGE_MASK) - window_start = 2 * ATH11K_PCI_WINDOW_START; - else - window_start = ATH11K_PCI_WINDOW_START; + window_start = ab->hw_params.dp_window_idx * ATH11K_PCI_WINDOW_START; + else if ((offset ^ HAL_SEQ_WCSS_UMAC_CE0_SRC_REG(ab)) < + ATH11K_PCI_WINDOW_RANGE_MASK) + window_start = ab->hw_params.ce_window_idx * ATH11K_PCI_WINDOW_START; return window_start; } @@ -162,19 +159,12 @@ void ath11k_pcic_write32(struct ath11k_base *ab, u32 offset, u32 value) if (offset < ATH11K_PCI_WINDOW_START) { iowrite32(value, ab->mem + offset); - } else { - if (ab->hw_params.static_window_map) - window_start = ath11k_pcic_get_window_start(ab, offset); - else - window_start = ATH11K_PCI_WINDOW_START; - - if (window_start == ATH11K_PCI_WINDOW_START && - ab->pci.ops->window_write32) { - ab->pci.ops->window_write32(ab, offset, value); - } else { - iowrite32(value, ab->mem + window_start + - (offset & ATH11K_PCI_WINDOW_RANGE_MASK)); - } + } else if (ab->hw_params.static_window_map) { + window_start = ath11k_pcic_get_window_start(ab, offset); + iowrite32(value, ab->mem + window_start + + (offset & ATH11K_PCI_WINDOW_RANGE_MASK)); + } else if (ab->pci.ops->window_write32) { + ab->pci.ops->window_write32(ab, offset, value); } if (test_bit(ATH11K_FLAG_DEVICE_INIT_DONE, &ab->dev_flags) && @@ -185,7 +175,8 @@ void ath11k_pcic_write32(struct ath11k_base *ab, u32 offset, u32 value) u32 ath11k_pcic_read32(struct ath11k_base *ab, u32 offset) { - u32 val, window_start; + u32 val = 0; + u32 window_start; int ret = 0; /* for offset beyond BAR + 4K - 32, may @@ -197,19 +188,12 @@ u32 ath11k_pcic_read32(struct ath11k_base *ab, u32 offset) if (offset < ATH11K_PCI_WINDOW_START) { val = ioread32(ab->mem + offset); - } else { - if (ab->hw_params.static_window_map) - window_start = ath11k_pcic_get_window_start(ab, offset); - else - window_start = ATH11K_PCI_WINDOW_START; - - if (window_start == ATH11K_PCI_WINDOW_START && - ab->pci.ops->window_read32) { - val = ab->pci.ops->window_read32(ab, offset); - } else { - val = ioread32(ab->mem + window_start + - (offset & ATH11K_PCI_WINDOW_RANGE_MASK)); - } + } else if (ab->hw_params.static_window_map) { + window_start = ath11k_pcic_get_window_start(ab, offset); + val = ioread32(ab->mem + window_start + + (offset & ATH11K_PCI_WINDOW_RANGE_MASK)); + } else if (ab->pci.ops->window_read32) { + val = ab->pci.ops->window_read32(ab, offset); } if (test_bit(ATH11K_FLAG_DEVICE_INIT_DONE, &ab->dev_flags) && From 676f8905fff904ea3e4ee52086a18ab54912b410 Mon Sep 17 00:00:00 2001 From: Manikanta Pubbisetty Date: Fri, 29 Apr 2022 22:34:58 +0530 Subject: [PATCH 211/228] ath11k: Fetch device information via QMI for WCN6750 Since WPPS Q6 does the PCIe enumeration of WCN6750, device information like BAR and BAR size is not known to the APPS processor (Application Processor SubSystem). In order to fetch these details, a QMI message called device info request will be sent to the target. Therefore, add logic to fetch BAR details from the target. Tested-on: WCN6750 hw1.0 AHB WLAN.MSL.1.0.1-00887-QCAMSLSWPLZ-1 Tested-on: WCN6855 hw2.0 PCI WLAN.HSP.1.1-01720.1-QCAHSPSWPL_V1_V2_SILICONZ_LITE-1 Tested-on: QCN9074 hw1.0 PCI WLAN.HK.2.5.0.1-01100-QCAHKSWPL_SILICONZ-1 Tested-on: IPQ8074 hw2.0 AHB WLAN.HK.2.4.0.1-00192-QCAHKSWPL_SILICONZ-1 Signed-off-by: Manikanta Pubbisetty Signed-off-by: Kalle Valo Link: https://lore.kernel.org/r/20220429170502.20080-6-quic_mpubbise@quicinc.com --- drivers/net/wireless/ath/ath11k/qmi.c | 144 ++++++++++++++++++++++++++ drivers/net/wireless/ath/ath11k/qmi.h | 24 ++++- 2 files changed, 164 insertions(+), 4 deletions(-) diff --git a/drivers/net/wireless/ath/ath11k/qmi.c b/drivers/net/wireless/ath/ath11k/qmi.c index c89e761082371..ad422256f1c60 100644 --- a/drivers/net/wireless/ath/ath11k/qmi.c +++ b/drivers/net/wireless/ath/ath11k/qmi.c @@ -13,6 +13,8 @@ #include #include #include +#include +#include #define SLEEP_CLOCK_SELECT_INTERNAL_BIT 0x02 #define HOST_CSTATE_BIT 0x04 @@ -749,6 +751,68 @@ static struct qmi_elem_info qmi_wlanfw_cap_req_msg_v01_ei[] = { }, }; +static struct qmi_elem_info qmi_wlanfw_device_info_req_msg_v01_ei[] = { + { + .data_type = QMI_EOTI, + .array_type = NO_ARRAY, + .tlv_type = QMI_COMMON_TLV_TYPE, + }, +}; + +static struct qmi_elem_info qmi_wlfw_device_info_resp_msg_v01_ei[] = { + { + .data_type = QMI_STRUCT, + .elem_len = 1, + .elem_size = sizeof(struct qmi_response_type_v01), + .array_type = NO_ARRAY, + .tlv_type = 0x02, + .offset = offsetof(struct qmi_wlanfw_device_info_resp_msg_v01, + resp), + .ei_array = qmi_response_type_v01_ei, + }, + { + .data_type = QMI_OPT_FLAG, + .elem_len = 1, + .elem_size = sizeof(u8), + .array_type = NO_ARRAY, + .tlv_type = 0x10, + .offset = offsetof(struct qmi_wlanfw_device_info_resp_msg_v01, + bar_addr_valid), + }, + { + .data_type = QMI_UNSIGNED_8_BYTE, + .elem_len = 1, + .elem_size = sizeof(u64), + .array_type = NO_ARRAY, + .tlv_type = 0x10, + .offset = offsetof(struct qmi_wlanfw_device_info_resp_msg_v01, + bar_addr), + }, + { + .data_type = QMI_OPT_FLAG, + .elem_len = 1, + .elem_size = sizeof(u8), + .array_type = NO_ARRAY, + .tlv_type = 0x11, + .offset = offsetof(struct qmi_wlanfw_device_info_resp_msg_v01, + bar_size_valid), + }, + { + .data_type = QMI_UNSIGNED_4_BYTE, + .elem_len = 1, + .elem_size = sizeof(u32), + .array_type = NO_ARRAY, + .tlv_type = 0x11, + .offset = offsetof(struct qmi_wlanfw_device_info_resp_msg_v01, + bar_size), + }, + { + .data_type = QMI_EOTI, + .array_type = NO_ARRAY, + .tlv_type = QMI_COMMON_TLV_TYPE, + }, +}; + static struct qmi_elem_info qmi_wlanfw_rf_chip_info_s_v01_ei[] = { { .data_type = QMI_UNSIGNED_4_BYTE, @@ -2008,6 +2072,80 @@ static int ath11k_qmi_assign_target_mem_chunk(struct ath11k_base *ab) return 0; } +static int ath11k_qmi_request_device_info(struct ath11k_base *ab) +{ + struct qmi_wlanfw_device_info_req_msg_v01 req = {}; + struct qmi_wlanfw_device_info_resp_msg_v01 resp = {}; + struct qmi_txn txn; + void __iomem *bar_addr_va; + int ret; + + /* device info message req is only sent for hybrid bus devices */ + if (!ab->hw_params.hybrid_bus_type) + return 0; + + ret = qmi_txn_init(&ab->qmi.handle, &txn, + qmi_wlfw_device_info_resp_msg_v01_ei, &resp); + if (ret < 0) + goto out; + + ret = qmi_send_request(&ab->qmi.handle, NULL, &txn, + QMI_WLANFW_DEVICE_INFO_REQ_V01, + QMI_WLANFW_DEVICE_INFO_REQ_MSG_V01_MAX_LEN, + qmi_wlanfw_device_info_req_msg_v01_ei, &req); + if (ret < 0) { + qmi_txn_cancel(&txn); + ath11k_warn(ab, "failed to send qmi target device info request: %d\n", + ret); + goto out; + } + + ret = qmi_txn_wait(&txn, msecs_to_jiffies(ATH11K_QMI_WLANFW_TIMEOUT_MS)); + if (ret < 0) { + ath11k_warn(ab, "failed to wait qmi target device info request: %d\n", + ret); + goto out; + } + + if (resp.resp.result != QMI_RESULT_SUCCESS_V01) { + ath11k_warn(ab, "qmi device info request failed: %d %d\n", + resp.resp.result, resp.resp.error); + ret = -EINVAL; + goto out; + } + + if (!resp.bar_addr_valid || !resp.bar_size_valid) { + ath11k_warn(ab, "qmi device info response invalid: %d %d\n", + resp.resp.result, resp.resp.error); + ret = -EINVAL; + goto out; + } + + if (!resp.bar_addr || + resp.bar_size != ATH11K_QMI_DEVICE_BAR_SIZE) { + ath11k_warn(ab, "qmi device info invalid address and size: %llu %u\n", + resp.bar_addr, resp.bar_size); + ret = -EINVAL; + goto out; + } + + bar_addr_va = devm_ioremap(ab->dev, resp.bar_addr, resp.bar_size); + + if (!bar_addr_va) { + ath11k_warn(ab, "qmi device info ioremap failed\n"); + ab->mem_len = 0; + ret = -EIO; + goto out; + } + + ab->mem = bar_addr_va; + ab->mem_len = resp.bar_size; + + return 0; +out: + return ret; +} + static int ath11k_qmi_request_target_cap(struct ath11k_base *ab) { struct qmi_wlanfw_cap_req_msg_v01 req; @@ -2749,6 +2887,12 @@ static int ath11k_qmi_event_load_bdf(struct ath11k_qmi *qmi) return ret; } + ret = ath11k_qmi_request_device_info(ab); + if (ret < 0) { + ath11k_warn(ab, "failed to request qmi device info: %d\n", ret); + return ret; + } + if (ab->hw_params.supports_regdb) ath11k_qmi_load_bdf_qmi(ab, true); diff --git a/drivers/net/wireless/ath/ath11k/qmi.h b/drivers/net/wireless/ath/ath11k/qmi.h index e0201e1847337..c24e6995cca35 100644 --- a/drivers/net/wireless/ath/ath11k/qmi.h +++ b/drivers/net/wireless/ath/ath11k/qmi.h @@ -38,6 +38,8 @@ #define ATH11K_FIRMWARE_MODE_OFF 4 #define ATH11K_COLD_BOOT_FW_RESET_DELAY (40 * HZ) +#define ATH11K_QMI_DEVICE_BAR_SIZE 0x200000 + struct ath11k_base; enum ath11k_qmi_file_type { @@ -287,10 +289,12 @@ struct qmi_wlanfw_fw_cold_cal_done_ind_msg_v01 { char placeholder; }; -#define QMI_WLANFW_CAP_REQ_MSG_V01_MAX_LEN 0 -#define QMI_WLANFW_CAP_RESP_MSG_V01_MAX_LEN 235 -#define QMI_WLANFW_CAP_REQ_V01 0x0024 -#define QMI_WLANFW_CAP_RESP_V01 0x0024 +#define QMI_WLANFW_CAP_REQ_MSG_V01_MAX_LEN 0 +#define QMI_WLANFW_CAP_RESP_MSG_V01_MAX_LEN 235 +#define QMI_WLANFW_CAP_REQ_V01 0x0024 +#define QMI_WLANFW_CAP_RESP_V01 0x0024 +#define QMI_WLANFW_DEVICE_INFO_REQ_V01 0x004C +#define QMI_WLANFW_DEVICE_INFO_REQ_MSG_V01_MAX_LEN 0 enum qmi_wlanfw_pipedir_enum_v01 { QMI_WLFW_PIPEDIR_NONE_V01 = 0, @@ -383,6 +387,18 @@ struct qmi_wlanfw_cap_req_msg_v01 { char placeholder; }; +struct qmi_wlanfw_device_info_req_msg_v01 { + char placeholder; +}; + +struct qmi_wlanfw_device_info_resp_msg_v01 { + struct qmi_response_type_v01 resp; + u64 bar_addr; + u32 bar_size; + u8 bar_addr_valid; + u8 bar_size_valid; +}; + #define QMI_WLANFW_BDF_DOWNLOAD_REQ_MSG_V01_MAX_LEN 6182 #define QMI_WLANFW_BDF_DOWNLOAD_RESP_MSG_V01_MAX_LEN 7 #define QMI_WLANFW_BDF_DOWNLOAD_RESP_V01 0x0025 From 73d3e71306fe864d9667e8d37f731e93a91e2040 Mon Sep 17 00:00:00 2001 From: Manikanta Pubbisetty Date: Fri, 29 Apr 2022 22:34:59 +0530 Subject: [PATCH 212/228] ath11k: Add QMI changes for WCN6750 In the case of WCN6750, FW doesn't request for DDR memory via QMI, instead it uses a fixed 12MB reserved Memory region in the DDR which is called as MSA region. As a result, QMI message sequence is not same as other ath11k supported devices. Also, M3 firmware will be bundled into the FW and will be downloaded to the target as part of Q6 boot. This is the QMI flow in the case of WCN6750, 1) QMI firmware indication REQ/RESP 2) QMI host capability REQ/RESP 3) QMI target capability REQ/RESP 4) QMI device info REQ/RESP 5) QMI BDF download 6) QMI FW ready Tested-on: WCN6750 hw1.0 AHB WLAN.MSL.1.0.1-00887-QCAMSLSWPLZ-1 Tested-on: WCN6855 hw2.0 PCI WLAN.HSP.1.1-01720.1-QCAHSPSWPL_V1_V2_SILICONZ_LITE-1 Tested-on: QCN9074 hw1.0 PCI WLAN.HK.2.5.0.1-01100-QCAHKSWPL_SILICONZ-1 Tested-on: IPQ8074 hw2.0 AHB WLAN.HK.2.4.0.1-00192-QCAHKSWPL_SILICONZ-1 Signed-off-by: Manikanta Pubbisetty Signed-off-by: Kalle Valo Link: https://lore.kernel.org/r/20220429170502.20080-7-quic_mpubbise@quicinc.com --- drivers/net/wireless/ath/ath11k/core.c | 7 +++ drivers/net/wireless/ath/ath11k/hw.h | 1 + drivers/net/wireless/ath/ath11k/qmi.c | 76 ++++++++++++++++---------- 3 files changed, 56 insertions(+), 28 deletions(-) diff --git a/drivers/net/wireless/ath/ath11k/core.c b/drivers/net/wireless/ath/ath11k/core.c index 3be4327b4d9c4..64cf87fd6a7fc 100644 --- a/drivers/net/wireless/ath/ath11k/core.c +++ b/drivers/net/wireless/ath/ath11k/core.c @@ -109,6 +109,7 @@ static const struct ath11k_hw_params ath11k_hw_params[] = { .hybrid_bus_type = false, .dp_window_idx = 0, .ce_window_idx = 0, + .fixed_fw_mem = false, }, { .hw_rev = ATH11K_HW_IPQ6018_HW10, @@ -183,6 +184,7 @@ static const struct ath11k_hw_params ath11k_hw_params[] = { .hybrid_bus_type = false, .dp_window_idx = 0, .ce_window_idx = 0, + .fixed_fw_mem = false, }, { .name = "qca6390 hw2.0", @@ -256,6 +258,7 @@ static const struct ath11k_hw_params ath11k_hw_params[] = { .hybrid_bus_type = false, .dp_window_idx = 0, .ce_window_idx = 0, + .fixed_fw_mem = false, }, { .name = "qcn9074 hw1.0", @@ -329,6 +332,7 @@ static const struct ath11k_hw_params ath11k_hw_params[] = { .hybrid_bus_type = false, .dp_window_idx = 3, .ce_window_idx = 2, + .fixed_fw_mem = false, }, { .name = "wcn6855 hw2.0", @@ -402,6 +406,7 @@ static const struct ath11k_hw_params ath11k_hw_params[] = { .hybrid_bus_type = false, .dp_window_idx = 0, .ce_window_idx = 0, + .fixed_fw_mem = false, }, { .name = "wcn6855 hw2.1", @@ -474,6 +479,7 @@ static const struct ath11k_hw_params ath11k_hw_params[] = { .hybrid_bus_type = false, .dp_window_idx = 0, .ce_window_idx = 0, + .fixed_fw_mem = false, }, { .name = "wcn6750 hw1.0", @@ -543,6 +549,7 @@ static const struct ath11k_hw_params ath11k_hw_params[] = { .hybrid_bus_type = true, .dp_window_idx = 1, .ce_window_idx = 2, + .fixed_fw_mem = true, }, }; diff --git a/drivers/net/wireless/ath/ath11k/hw.h b/drivers/net/wireless/ath/ath11k/hw.h index b63538084215e..b5a4758a6bc50 100644 --- a/drivers/net/wireless/ath/ath11k/hw.h +++ b/drivers/net/wireless/ath/ath11k/hw.h @@ -203,6 +203,7 @@ struct ath11k_hw_params { bool hybrid_bus_type; u8 dp_window_idx; u8 ce_window_idx; + bool fixed_fw_mem; }; struct ath11k_hw_ops { diff --git a/drivers/net/wireless/ath/ath11k/qmi.c b/drivers/net/wireless/ath/ath11k/qmi.c index ad422256f1c60..d1e945074bc11 100644 --- a/drivers/net/wireless/ath/ath11k/qmi.c +++ b/drivers/net/wireless/ath/ath11k/qmi.c @@ -1799,10 +1799,6 @@ static int ath11k_qmi_fw_ind_register_send(struct ath11k_base *ab) req->client_id = QMI_WLANFW_CLIENT_ID; req->fw_ready_enable_valid = 1; req->fw_ready_enable = 1; - req->request_mem_enable_valid = 1; - req->request_mem_enable = 1; - req->fw_mem_ready_enable_valid = 1; - req->fw_mem_ready_enable = 1; req->cal_done_enable_valid = 1; req->cal_done_enable = 1; req->fw_init_done_enable_valid = 1; @@ -1811,6 +1807,17 @@ static int ath11k_qmi_fw_ind_register_send(struct ath11k_base *ab) req->pin_connect_result_enable_valid = 0; req->pin_connect_result_enable = 0; + /* WCN6750 doesn't request for DDR memory via QMI, + * instead it uses a fixed 12MB reserved memory + * region in DDR. + */ + if (!ab->hw_params.fixed_fw_mem) { + req->request_mem_enable_valid = 1; + req->request_mem_enable = 1; + req->fw_mem_ready_enable_valid = 1; + req->fw_mem_ready_enable = 1; + } + ret = qmi_txn_init(handle, &txn, qmi_wlanfw_ind_register_resp_msg_v01_ei, resp); if (ret < 0) @@ -2840,27 +2847,6 @@ ath11k_qmi_driver_event_post(struct ath11k_qmi *qmi, return 0; } -static int ath11k_qmi_event_server_arrive(struct ath11k_qmi *qmi) -{ - struct ath11k_base *ab = qmi->ab; - int ret; - - ret = ath11k_qmi_fw_ind_register_send(ab); - if (ret < 0) { - ath11k_warn(ab, "failed to send qmi firmware indication: %d\n", - ret); - return ret; - } - - ret = ath11k_qmi_host_cap_send(ab); - if (ret < 0) { - ath11k_warn(ab, "failed to send qmi host cap: %d\n", ret); - return ret; - } - - return ret; -} - static int ath11k_qmi_event_mem_request(struct ath11k_qmi *qmi) { struct ath11k_base *ab = qmi->ab; @@ -2902,9 +2888,33 @@ static int ath11k_qmi_event_load_bdf(struct ath11k_qmi *qmi) return ret; } - ret = ath11k_qmi_wlanfw_m3_info_send(ab); + return 0; +} + +static int ath11k_qmi_event_server_arrive(struct ath11k_qmi *qmi) +{ + struct ath11k_base *ab = qmi->ab; + int ret; + + ret = ath11k_qmi_fw_ind_register_send(ab); + if (ret < 0) { + ath11k_warn(ab, "failed to send qmi firmware indication: %d\n", + ret); + return ret; + } + + ret = ath11k_qmi_host_cap_send(ab); if (ret < 0) { - ath11k_warn(ab, "failed to send qmi m3 info req: %d\n", ret); + ath11k_warn(ab, "failed to send qmi host cap: %d\n", ret); + return ret; + } + + if (!ab->hw_params.fixed_fw_mem) + return ret; + + ret = ath11k_qmi_event_load_bdf(qmi); + if (ret < 0) { + ath11k_warn(ab, "qmi failed to download BDF:%d\n", ret); return ret; } @@ -3104,8 +3114,18 @@ static void ath11k_qmi_driver_event_work(struct work_struct *work) break; case ATH11K_QMI_EVENT_FW_MEM_READY: ret = ath11k_qmi_event_load_bdf(qmi); - if (ret < 0) + if (ret < 0) { set_bit(ATH11K_FLAG_QMI_FAIL, &ab->dev_flags); + break; + } + + ret = ath11k_qmi_wlanfw_m3_info_send(ab); + if (ret < 0) { + ath11k_warn(ab, + "failed to send qmi m3 info req: %d\n", ret); + set_bit(ATH11K_FLAG_QMI_FAIL, &ab->dev_flags); + } + break; case ATH11K_QMI_EVENT_FW_READY: clear_bit(ATH11K_FLAG_QMI_FAIL, &ab->dev_flags); From 49890d9c93d5abf21babda2b495c7d3014fb9c98 Mon Sep 17 00:00:00 2001 From: Manikanta Pubbisetty Date: Fri, 29 Apr 2022 22:35:00 +0530 Subject: [PATCH 213/228] ath11k: HAL changes to support WCN6750 Add HAL changes required to support WCN6750. Offsets of some registers for WCN6750 are different from other supported devices; move such register offsets to platform specific ath11k_hw_regs. Tested-on: WCN6750 hw1.0 AHB WLAN.MSL.1.0.1-00887-QCAMSLSWPLZ-1 Tested-on: WCN6855 hw2.0 PCI WLAN.HSP.1.1-01720.1-QCAHSPSWPL_V1_V2_SILICONZ_LITE-1 Tested-on: QCN9074 hw1.0 PCI WLAN.HK.2.5.0.1-01100-QCAHKSWPL_SILICONZ-1 Tested-on: IPQ8074 hw2.0 AHB WLAN.HK.2.4.0.1-00192-QCAHKSWPL_SILICONZ-1 Signed-off-by: Manikanta Pubbisetty Signed-off-by: Kalle Valo Link: https://lore.kernel.org/r/20220429170502.20080-8-quic_mpubbise@quicinc.com --- drivers/net/wireless/ath/ath11k/core.c | 2 + drivers/net/wireless/ath/ath11k/hal.c | 15 +-- drivers/net/wireless/ath/ath11k/hal.h | 15 +-- drivers/net/wireless/ath/ath11k/hw.c | 134 +++++++++++++++++++++++++ drivers/net/wireless/ath/ath11k/hw.h | 10 ++ 5 files changed, 163 insertions(+), 13 deletions(-) diff --git a/drivers/net/wireless/ath/ath11k/core.c b/drivers/net/wireless/ath/ath11k/core.c index 64cf87fd6a7fc..7385e1c60ca1f 100644 --- a/drivers/net/wireless/ath/ath11k/core.c +++ b/drivers/net/wireless/ath/ath11k/core.c @@ -491,8 +491,10 @@ static const struct ath11k_hw_params ath11k_hw_params[] = { }, .max_radios = 1, .bdf_addr = 0x4B0C0000, + .hw_ops = &wcn6750_ops, .ring_mask = &ath11k_hw_ring_mask_qca6390, .internal_sleep_clock = false, + .regs = &wcn6750_regs, .qmi_service_ins_id = ATH11K_QMI_WLFW_SERVICE_INS_ID_V01_WCN6750, .host_ce_config = ath11k_host_ce_config_qca6390, .ce_count = 9, diff --git a/drivers/net/wireless/ath/ath11k/hal.c b/drivers/net/wireless/ath/ath11k/hal.c index 2ec09ae900802..1dba7b9e0bdaa 100644 --- a/drivers/net/wireless/ath/ath11k/hal.c +++ b/drivers/net/wireless/ath/ath11k/hal.c @@ -1,6 +1,7 @@ // SPDX-License-Identifier: BSD-3-Clause-Clear /* * Copyright (c) 2018-2019 The Linux Foundation. All rights reserved. + * Copyright (c) 2022, Qualcomm Innovation Center, Inc. All rights reserved. */ #include #include "hal_tx.h" @@ -1082,10 +1083,10 @@ static void ath11k_hal_srng_update_hp_tp_addr(struct ath11k_base *ab, srng = &hal->srng_list[ring_id]; if (srng_config->ring_dir == HAL_SRNG_DIR_DST) - srng->u.dst_ring.tp_addr = (u32 *)(HAL_SHADOW_REG(shadow_cfg_idx) + + srng->u.dst_ring.tp_addr = (u32 *)(HAL_SHADOW_REG(ab, shadow_cfg_idx) + (unsigned long)ab->mem); else - srng->u.src_ring.hp_addr = (u32 *)(HAL_SHADOW_REG(shadow_cfg_idx) + + srng->u.src_ring.hp_addr = (u32 *)(HAL_SHADOW_REG(ab, shadow_cfg_idx) + (unsigned long)ab->mem); } @@ -1120,7 +1121,7 @@ int ath11k_hal_srng_update_shadow_config(struct ath11k_base *ab, ath11k_dbg(ab, ATH11k_DBG_HAL, "target_reg %x, shadow reg 0x%x shadow_idx 0x%x, ring_type %d, ring num %d", target_reg, - HAL_SHADOW_REG(shadow_cfg_idx), + HAL_SHADOW_REG(ab, shadow_cfg_idx), shadow_cfg_idx, ring_type, ring_num); @@ -1193,12 +1194,12 @@ static int ath11k_hal_srng_create_config(struct ath11k_base *ab) s->reg_start[1] = HAL_SEQ_WCSS_UMAC_REO_REG + HAL_REO_TCL_RING_HP(ab); s = &hal->srng_config[HAL_REO_REINJECT]; - s->reg_start[0] = HAL_SEQ_WCSS_UMAC_REO_REG + HAL_SW2REO_RING_BASE_LSB; - s->reg_start[1] = HAL_SEQ_WCSS_UMAC_REO_REG + HAL_SW2REO_RING_HP; + s->reg_start[0] = HAL_SEQ_WCSS_UMAC_REO_REG + HAL_SW2REO_RING_BASE_LSB(ab); + s->reg_start[1] = HAL_SEQ_WCSS_UMAC_REO_REG + HAL_SW2REO_RING_HP(ab); s = &hal->srng_config[HAL_REO_CMD]; - s->reg_start[0] = HAL_SEQ_WCSS_UMAC_REO_REG + HAL_REO_CMD_RING_BASE_LSB; - s->reg_start[1] = HAL_SEQ_WCSS_UMAC_REO_REG + HAL_REO_CMD_HP; + s->reg_start[0] = HAL_SEQ_WCSS_UMAC_REO_REG + HAL_REO_CMD_RING_BASE_LSB(ab); + s->reg_start[1] = HAL_SEQ_WCSS_UMAC_REO_REG + HAL_REO_CMD_HP(ab); s = &hal->srng_config[HAL_REO_STATUS]; s->reg_start[0] = HAL_SEQ_WCSS_UMAC_REO_REG + HAL_REO_STATUS_RING_BASE_LSB(ab); diff --git a/drivers/net/wireless/ath/ath11k/hal.h b/drivers/net/wireless/ath/ath11k/hal.h index a7d9b4c551ada..1aadb1566df87 100644 --- a/drivers/net/wireless/ath/ath11k/hal.h +++ b/drivers/net/wireless/ath/ath11k/hal.h @@ -1,6 +1,7 @@ /* SPDX-License-Identifier: BSD-3-Clause-Clear */ /* * Copyright (c) 2018-2019 The Linux Foundation. All rights reserved. + * Copyright (c) 2022, Qualcomm Innovation Center, Inc. All rights reserved. */ #ifndef ATH11K_HAL_H @@ -31,12 +32,12 @@ struct ath11k_base; #define HAL_DSCP_TID_TBL_SIZE 24 /* calculate the register address from bar0 of shadow register x */ -#define HAL_SHADOW_BASE_ADDR 0x000008fc +#define HAL_SHADOW_BASE_ADDR(ab) ab->hw_params.regs->hal_shadow_base_addr #define HAL_SHADOW_NUM_REGS 36 #define HAL_HP_OFFSET_IN_REG_START 1 #define HAL_OFFSET_FROM_HP_TO_TP 4 -#define HAL_SHADOW_REG(x) (HAL_SHADOW_BASE_ADDR + (4 * (x))) +#define HAL_SHADOW_REG(ab, x) (HAL_SHADOW_BASE_ADDR(ab) + (4 * (x))) /* WCSS Relative address */ #define HAL_SEQ_WCSS_UMAC_OFFSET 0x00a00000 @@ -180,16 +181,18 @@ struct ath11k_base; #define HAL_REO_TCL_RING_HP(ab) ab->hw_params.regs->hal_reo_tcl_ring_hp /* REO CMD R0 address */ -#define HAL_REO_CMD_RING_BASE_LSB 0x00000194 +#define HAL_REO_CMD_RING_BASE_LSB(ab) \ + ab->hw_params.regs->hal_reo_cmd_ring_base_lsb /* REO CMD R2 address */ -#define HAL_REO_CMD_HP 0x00003020 +#define HAL_REO_CMD_HP(ab) ab->hw_params.regs->hal_reo_cmd_ring_hp /* SW2REO R0 address */ -#define HAL_SW2REO_RING_BASE_LSB 0x000001ec +#define HAL_SW2REO_RING_BASE_LSB(ab) \ + ab->hw_params.regs->hal_sw2reo_ring_base_lsb /* SW2REO R2 address */ -#define HAL_SW2REO_RING_HP 0x00003028 +#define HAL_SW2REO_RING_HP(ab) ab->hw_params.regs->hal_sw2reo_ring_hp /* CE ring R0 address */ #define HAL_CE_DST_RING_BASE_LSB 0x00000000 diff --git a/drivers/net/wireless/ath/ath11k/hw.c b/drivers/net/wireless/ath/ath11k/hw.c index 46449a18b5cb9..a9f5c4e63d62a 100644 --- a/drivers/net/wireless/ath/ath11k/hw.c +++ b/drivers/net/wireless/ath/ath11k/hw.c @@ -1,6 +1,7 @@ // SPDX-License-Identifier: BSD-3-Clause-Clear /* * Copyright (c) 2018-2020 The Linux Foundation. All rights reserved. + * Copyright (c) 2022, Qualcomm Innovation Center, Inc. All rights reserved. */ #include @@ -1014,6 +1015,13 @@ const struct ath11k_hw_ops wcn6855_ops = { .rx_desc_mpdu_start_addr2 = ath11k_hw_wcn6855_rx_desc_mpdu_start_addr2, }; +const struct ath11k_hw_ops wcn6750_ops = { + .get_hw_mac_from_pdev_id = ath11k_hw_ipq8074_mac_from_pdev_id, + .wmi_init_config = ath11k_init_wmi_config_qca6390, + .mac_id_to_pdev_id = ath11k_hw_mac_id_to_pdev_id_qca6390, + .mac_id_to_srng_id = ath11k_hw_mac_id_to_srng_id_qca6390, +}; + #define ATH11K_TX_RING_MASK_0 0x1 #define ATH11K_TX_RING_MASK_1 0x2 #define ATH11K_TX_RING_MASK_2 0x4 @@ -1908,10 +1916,18 @@ const struct ath11k_hw_regs ipq8074_regs = { .hal_reo_tcl_ring_base_lsb = 0x000003fc, .hal_reo_tcl_ring_hp = 0x00003058, + /* REO CMD ring address */ + .hal_reo_cmd_ring_base_lsb = 0x00000194, + .hal_reo_cmd_ring_hp = 0x00003020, + /* REO status address */ .hal_reo_status_ring_base_lsb = 0x00000504, .hal_reo_status_hp = 0x00003070, + /* SW2REO ring address */ + .hal_sw2reo_ring_base_lsb = 0x000001ec, + .hal_sw2reo_ring_hp = 0x00003028, + /* WCSS relative address */ .hal_seq_wcss_umac_ce0_src_reg = 0x00a00000, .hal_seq_wcss_umac_ce0_dst_reg = 0x00a01000, @@ -1932,6 +1948,9 @@ const struct ath11k_hw_regs ipq8074_regs = { /* PCIe base address */ .pcie_qserdes_sysclk_en_sel = 0x0, .pcie_pcs_osc_dtct_config_base = 0x0, + + /* Shadow register area */ + .hal_shadow_base_addr = 0x0, }; const struct ath11k_hw_regs qca6390_regs = { @@ -1979,10 +1998,18 @@ const struct ath11k_hw_regs qca6390_regs = { .hal_reo_tcl_ring_base_lsb = 0x000003a4, .hal_reo_tcl_ring_hp = 0x00003050, + /* REO CMD ring address */ + .hal_reo_cmd_ring_base_lsb = 0x00000194, + .hal_reo_cmd_ring_hp = 0x00003020, + /* REO status address */ .hal_reo_status_ring_base_lsb = 0x000004ac, .hal_reo_status_hp = 0x00003068, + /* SW2REO ring address */ + .hal_sw2reo_ring_base_lsb = 0x000001ec, + .hal_sw2reo_ring_hp = 0x00003028, + /* WCSS relative address */ .hal_seq_wcss_umac_ce0_src_reg = 0x00a00000, .hal_seq_wcss_umac_ce0_dst_reg = 0x00a01000, @@ -2003,6 +2030,9 @@ const struct ath11k_hw_regs qca6390_regs = { /* PCIe base address */ .pcie_qserdes_sysclk_en_sel = 0x01e0c0ac, .pcie_pcs_osc_dtct_config_base = 0x01e0c628, + + /* Shadow register area */ + .hal_shadow_base_addr = 0x000008fc, }; const struct ath11k_hw_regs qcn9074_regs = { @@ -2050,10 +2080,18 @@ const struct ath11k_hw_regs qcn9074_regs = { .hal_reo_tcl_ring_base_lsb = 0x000003fc, .hal_reo_tcl_ring_hp = 0x00003058, + /* REO CMD ring address */ + .hal_reo_cmd_ring_base_lsb = 0x00000194, + .hal_reo_cmd_ring_hp = 0x00003020, + /* REO status address */ .hal_reo_status_ring_base_lsb = 0x00000504, .hal_reo_status_hp = 0x00003070, + /* SW2REO ring address */ + .hal_sw2reo_ring_base_lsb = 0x000001ec, + .hal_sw2reo_ring_hp = 0x00003028, + /* WCSS relative address */ .hal_seq_wcss_umac_ce0_src_reg = 0x01b80000, .hal_seq_wcss_umac_ce0_dst_reg = 0x01b81000, @@ -2074,6 +2112,9 @@ const struct ath11k_hw_regs qcn9074_regs = { /* PCIe base address */ .pcie_qserdes_sysclk_en_sel = 0x01e0e0a8, .pcie_pcs_osc_dtct_config_base = 0x01e0f45c, + + /* Shadow register area */ + .hal_shadow_base_addr = 0x0, }; const struct ath11k_hw_regs wcn6855_regs = { @@ -2121,10 +2162,18 @@ const struct ath11k_hw_regs wcn6855_regs = { .hal_reo_tcl_ring_base_lsb = 0x00000454, .hal_reo_tcl_ring_hp = 0x00003060, + /* REO CMD ring address */ + .hal_reo_cmd_ring_base_lsb = 0x00000194, + .hal_reo_cmd_ring_hp = 0x00003020, + /* REO status address */ .hal_reo_status_ring_base_lsb = 0x0000055c, .hal_reo_status_hp = 0x00003078, + /* SW2REO ring address */ + .hal_sw2reo_ring_base_lsb = 0x000001ec, + .hal_sw2reo_ring_hp = 0x00003028, + /* WCSS relative address */ .hal_seq_wcss_umac_ce0_src_reg = 0x1b80000, .hal_seq_wcss_umac_ce0_dst_reg = 0x1b81000, @@ -2145,6 +2194,91 @@ const struct ath11k_hw_regs wcn6855_regs = { /* PCIe base address */ .pcie_qserdes_sysclk_en_sel = 0x01e0c0ac, .pcie_pcs_osc_dtct_config_base = 0x01e0c628, + + /* Shadow register area */ + .hal_shadow_base_addr = 0x000008fc, +}; + +const struct ath11k_hw_regs wcn6750_regs = { + /* SW2TCL(x) R0 ring configuration address */ + .hal_tcl1_ring_base_lsb = 0x00000694, + .hal_tcl1_ring_base_msb = 0x00000698, + .hal_tcl1_ring_id = 0x0000069c, + .hal_tcl1_ring_misc = 0x000006a4, + .hal_tcl1_ring_tp_addr_lsb = 0x000006b0, + .hal_tcl1_ring_tp_addr_msb = 0x000006b4, + .hal_tcl1_ring_consumer_int_setup_ix0 = 0x000006c4, + .hal_tcl1_ring_consumer_int_setup_ix1 = 0x000006c8, + .hal_tcl1_ring_msi1_base_lsb = 0x000006dc, + .hal_tcl1_ring_msi1_base_msb = 0x000006e0, + .hal_tcl1_ring_msi1_data = 0x000006e4, + .hal_tcl2_ring_base_lsb = 0x000006ec, + .hal_tcl_ring_base_lsb = 0x0000079c, + + /* TCL STATUS ring address */ + .hal_tcl_status_ring_base_lsb = 0x000008a4, + + /* REO2SW(x) R0 ring configuration address */ + .hal_reo1_ring_base_lsb = 0x000001ec, + .hal_reo1_ring_base_msb = 0x000001f0, + .hal_reo1_ring_id = 0x000001f4, + .hal_reo1_ring_misc = 0x000001fc, + .hal_reo1_ring_hp_addr_lsb = 0x00000200, + .hal_reo1_ring_hp_addr_msb = 0x00000204, + .hal_reo1_ring_producer_int_setup = 0x00000210, + .hal_reo1_ring_msi1_base_lsb = 0x00000234, + .hal_reo1_ring_msi1_base_msb = 0x00000238, + .hal_reo1_ring_msi1_data = 0x0000023c, + .hal_reo2_ring_base_lsb = 0x00000244, + .hal_reo1_aging_thresh_ix_0 = 0x00000564, + .hal_reo1_aging_thresh_ix_1 = 0x00000568, + .hal_reo1_aging_thresh_ix_2 = 0x0000056c, + .hal_reo1_aging_thresh_ix_3 = 0x00000570, + + /* REO2SW(x) R2 ring pointers (head/tail) address */ + .hal_reo1_ring_hp = 0x00003028, + .hal_reo1_ring_tp = 0x0000302c, + .hal_reo2_ring_hp = 0x00003030, + + /* REO2TCL R0 ring configuration address */ + .hal_reo_tcl_ring_base_lsb = 0x000003fc, + .hal_reo_tcl_ring_hp = 0x00003058, + + /* REO CMD ring address */ + .hal_reo_cmd_ring_base_lsb = 0x000000e4, + .hal_reo_cmd_ring_hp = 0x00003010, + + /* REO status address */ + .hal_reo_status_ring_base_lsb = 0x00000504, + .hal_reo_status_hp = 0x00003070, + + /* SW2REO ring address */ + .hal_sw2reo_ring_base_lsb = 0x0000013c, + .hal_sw2reo_ring_hp = 0x00003018, + + /* WCSS relative address */ + .hal_seq_wcss_umac_ce0_src_reg = 0x01b80000, + .hal_seq_wcss_umac_ce0_dst_reg = 0x01b81000, + .hal_seq_wcss_umac_ce1_src_reg = 0x01b82000, + .hal_seq_wcss_umac_ce1_dst_reg = 0x01b83000, + + /* WBM Idle address */ + .hal_wbm_idle_link_ring_base_lsb = 0x00000874, + .hal_wbm_idle_link_ring_misc = 0x00000884, + + /* SW2WBM release address */ + .hal_wbm_release_ring_base_lsb = 0x000001ec, + + /* WBM2SW release address */ + .hal_wbm0_release_ring_base_lsb = 0x00000924, + .hal_wbm1_release_ring_base_lsb = 0x0000097c, + + /* PCIe base address */ + .pcie_qserdes_sysclk_en_sel = 0x0, + .pcie_pcs_osc_dtct_config_base = 0x0, + + /* Shadow register area */ + .hal_shadow_base_addr = 0x00000504, }; const struct ath11k_hw_hal_params ath11k_hw_hal_params_ipq8074 = { diff --git a/drivers/net/wireless/ath/ath11k/hw.h b/drivers/net/wireless/ath/ath11k/hw.h index b5a4758a6bc50..6d588cd80093a 100644 --- a/drivers/net/wireless/ath/ath11k/hw.h +++ b/drivers/net/wireless/ath/ath11k/hw.h @@ -253,6 +253,7 @@ extern const struct ath11k_hw_ops ipq6018_ops; extern const struct ath11k_hw_ops qca6390_ops; extern const struct ath11k_hw_ops qcn9074_ops; extern const struct ath11k_hw_ops wcn6855_ops; +extern const struct ath11k_hw_ops wcn6750_ops; extern const struct ath11k_hw_ring_mask ath11k_hw_ring_mask_ipq8074; extern const struct ath11k_hw_ring_mask ath11k_hw_ring_mask_qca6390; @@ -355,6 +356,12 @@ struct ath11k_hw_regs { u32 hal_reo_status_ring_base_lsb; u32 hal_reo_status_hp; + u32 hal_reo_cmd_ring_base_lsb; + u32 hal_reo_cmd_ring_hp; + + u32 hal_sw2reo_ring_base_lsb; + u32 hal_sw2reo_ring_hp; + u32 hal_seq_wcss_umac_ce0_src_reg; u32 hal_seq_wcss_umac_ce0_dst_reg; u32 hal_seq_wcss_umac_ce1_src_reg; @@ -370,12 +377,15 @@ struct ath11k_hw_regs { u32 pcie_qserdes_sysclk_en_sel; u32 pcie_pcs_osc_dtct_config_base; + + u32 hal_shadow_base_addr; }; extern const struct ath11k_hw_regs ipq8074_regs; extern const struct ath11k_hw_regs qca6390_regs; extern const struct ath11k_hw_regs qcn9074_regs; extern const struct ath11k_hw_regs wcn6855_regs; +extern const struct ath11k_hw_regs wcn6750_regs; static inline const char *ath11k_bd_ie_type_str(enum ath11k_bd_ie_type type) { From e67ba19739177f95706c1d4a53c884c89973b843 Mon Sep 17 00:00:00 2001 From: Manikanta Pubbisetty Date: Fri, 29 Apr 2022 22:35:01 +0530 Subject: [PATCH 214/228] ath11k: Datapath changes to support WCN6750 HAL RX descriptor for WCN6750 is same as QCN9074, this means that the size of the HAL RX decriptor and the DP APIs that WCN6750 requires to enable datapath should be initialized with that of QCN9074's RX descriptor size and the DP APIs respectively. There is one change wrt to REO configuration though, REO configuration for WCN6750 follows WCN6855, therefore use reo_setup() of WCN6855 for WCN6750. Tested-on: WCN6750 hw1.0 AHB WLAN.MSL.1.0.1-00887-QCAMSLSWPLZ-1 Tested-on: WCN6855 hw2.0 PCI WLAN.HSP.1.1-01720.1-QCAHSPSWPL_V1_V2_SILICONZ_LITE-1 Tested-on: QCN9074 hw1.0 PCI WLAN.HK.2.5.0.1-01100-QCAHKSWPL_SILICONZ-1 Tested-on: IPQ8074 hw2.0 AHB WLAN.HK.2.4.0.1-00192-QCAHKSWPL_SILICONZ-1 Signed-off-by: Manikanta Pubbisetty Signed-off-by: Kalle Valo Link: https://lore.kernel.org/r/20220429170502.20080-9-quic_mpubbise@quicinc.com --- drivers/net/wireless/ath/ath11k/core.c | 1 + drivers/net/wireless/ath/ath11k/hw.c | 32 ++++++++++++++++++++++++++ 2 files changed, 33 insertions(+) diff --git a/drivers/net/wireless/ath/ath11k/core.c b/drivers/net/wireless/ath/ath11k/core.c index 7385e1c60ca1f..01e1d494b527e 100644 --- a/drivers/net/wireless/ath/ath11k/core.c +++ b/drivers/net/wireless/ath/ath11k/core.c @@ -531,6 +531,7 @@ static const struct ath11k_hw_params ath11k_hw_params[] = { .num_vdevs = 16 + 1, .num_peers = 512, .supports_suspend = false, + .hal_desc_sz = sizeof(struct hal_rx_desc_qcn9074), .supports_regdb = true, .fix_l1ss = false, .credit_flow = true, diff --git a/drivers/net/wireless/ath/ath11k/hw.c b/drivers/net/wireless/ath/ath11k/hw.c index a9f5c4e63d62a..09ce357f0f0d0 100644 --- a/drivers/net/wireless/ath/ath11k/hw.c +++ b/drivers/net/wireless/ath/ath11k/hw.c @@ -1020,6 +1020,38 @@ const struct ath11k_hw_ops wcn6750_ops = { .wmi_init_config = ath11k_init_wmi_config_qca6390, .mac_id_to_pdev_id = ath11k_hw_mac_id_to_pdev_id_qca6390, .mac_id_to_srng_id = ath11k_hw_mac_id_to_srng_id_qca6390, + .tx_mesh_enable = ath11k_hw_qcn9074_tx_mesh_enable, + .rx_desc_get_first_msdu = ath11k_hw_qcn9074_rx_desc_get_first_msdu, + .rx_desc_get_last_msdu = ath11k_hw_qcn9074_rx_desc_get_last_msdu, + .rx_desc_get_l3_pad_bytes = ath11k_hw_qcn9074_rx_desc_get_l3_pad_bytes, + .rx_desc_get_hdr_status = ath11k_hw_qcn9074_rx_desc_get_hdr_status, + .rx_desc_encrypt_valid = ath11k_hw_qcn9074_rx_desc_encrypt_valid, + .rx_desc_get_encrypt_type = ath11k_hw_qcn9074_rx_desc_get_encrypt_type, + .rx_desc_get_decap_type = ath11k_hw_qcn9074_rx_desc_get_decap_type, + .rx_desc_get_mesh_ctl = ath11k_hw_qcn9074_rx_desc_get_mesh_ctl, + .rx_desc_get_ldpc_support = ath11k_hw_qcn9074_rx_desc_get_ldpc_support, + .rx_desc_get_mpdu_seq_ctl_vld = ath11k_hw_qcn9074_rx_desc_get_mpdu_seq_ctl_vld, + .rx_desc_get_mpdu_fc_valid = ath11k_hw_qcn9074_rx_desc_get_mpdu_fc_valid, + .rx_desc_get_mpdu_start_seq_no = ath11k_hw_qcn9074_rx_desc_get_mpdu_start_seq_no, + .rx_desc_get_msdu_len = ath11k_hw_qcn9074_rx_desc_get_msdu_len, + .rx_desc_get_msdu_sgi = ath11k_hw_qcn9074_rx_desc_get_msdu_sgi, + .rx_desc_get_msdu_rate_mcs = ath11k_hw_qcn9074_rx_desc_get_msdu_rate_mcs, + .rx_desc_get_msdu_rx_bw = ath11k_hw_qcn9074_rx_desc_get_msdu_rx_bw, + .rx_desc_get_msdu_freq = ath11k_hw_qcn9074_rx_desc_get_msdu_freq, + .rx_desc_get_msdu_pkt_type = ath11k_hw_qcn9074_rx_desc_get_msdu_pkt_type, + .rx_desc_get_msdu_nss = ath11k_hw_qcn9074_rx_desc_get_msdu_nss, + .rx_desc_get_mpdu_tid = ath11k_hw_qcn9074_rx_desc_get_mpdu_tid, + .rx_desc_get_mpdu_peer_id = ath11k_hw_qcn9074_rx_desc_get_mpdu_peer_id, + .rx_desc_copy_attn_end_tlv = ath11k_hw_qcn9074_rx_desc_copy_attn_end, + .rx_desc_get_mpdu_start_tag = ath11k_hw_qcn9074_rx_desc_get_mpdu_start_tag, + .rx_desc_get_mpdu_ppdu_id = ath11k_hw_qcn9074_rx_desc_get_mpdu_ppdu_id, + .rx_desc_set_msdu_len = ath11k_hw_qcn9074_rx_desc_set_msdu_len, + .rx_desc_get_attention = ath11k_hw_qcn9074_rx_desc_get_attention, + .rx_desc_get_msdu_payload = ath11k_hw_qcn9074_rx_desc_get_msdu_payload, + .reo_setup = ath11k_hw_wcn6855_reo_setup, + .mpdu_info_get_peerid = ath11k_hw_ipq8074_mpdu_info_get_peerid, + .rx_desc_mac_addr2_valid = ath11k_hw_ipq9074_rx_desc_mac_addr2_valid, + .rx_desc_mpdu_start_addr2 = ath11k_hw_ipq9074_rx_desc_mpdu_start_addr2, }; #define ATH11K_TX_RING_MASK_0 0x1 From 00402f49d26ffe991892bba76ccbdfed26538824 Mon Sep 17 00:00:00 2001 From: Manikanta Pubbisetty Date: Fri, 29 Apr 2022 22:35:02 +0530 Subject: [PATCH 215/228] ath11k: Add support for WCN6750 device WCN6750 is non-DBS 2x2 11AX chipset. Unlike QCA6390 which is a DBS (dual band simultaneous) solution (2 LMACs), WCN6750 has a single LMAC supporting 2G, 5G and 6G bands but will operate only on one band at any given point. WCN6750 is a PCIe based solution, but it is attached to the WPSS (Wireless Processor SubSystem) Q6 processor, hence it is enumerated by the Q6 processor. It is registered to the APSS processor (Application Processor SubSystem) as a platform device(AHB) and remoteproc APIs are used to boot up or shutdown the device like other AHB devices. Also, Device information like BAR and it's size is not known to the APSS processor as the chip is enumerated by WPSS Q6. These details are fetched over QMI. STA and AP modes are supported. Verified basic connectivity and ping in both the modes. An important point to note is that though WCN6750 is a PCIe device, it cannot be attached to any other platform except on Qualcomm Snapdragon SoCs due to the aforementioned reasons. Tested-on: WCN6750 hw1.0 AHB WLAN.MSL.1.0.1-00887-QCAMSLSWPLZ-1 Tested-on: WCN6855 hw2.0 PCI WLAN.HSP.1.1-01720.1-QCAHSPSWPL_V1_V2_SILICONZ_LITE-1 Tested-on: QCN9074 hw1.0 PCI WLAN.HK.2.5.0.1-01100-QCAHKSWPL_SILICONZ-1 Tested-on: IPQ8074 hw2.0 AHB WLAN.HK.2.4.0.1-00192-QCAHKSWPL_SILICONZ-1 Signed-off-by: Manikanta Pubbisetty Signed-off-by: Kalle Valo Link: https://lore.kernel.org/r/20220429170502.20080-10-quic_mpubbise@quicinc.com --- drivers/net/wireless/ath/ath11k/Makefile | 5 +- drivers/net/wireless/ath/ath11k/ahb.c | 142 +++++++++++++++++++++-- drivers/net/wireless/ath/ath11k/core.h | 1 + drivers/net/wireless/ath/ath11k/pcic.c | 23 ++++ 4 files changed, 158 insertions(+), 13 deletions(-) diff --git a/drivers/net/wireless/ath/ath11k/Makefile b/drivers/net/wireless/ath/ath11k/Makefile index 0ebfe41d61436..cc47e0114595f 100644 --- a/drivers/net/wireless/ath/ath11k/Makefile +++ b/drivers/net/wireless/ath/ath11k/Makefile @@ -16,7 +16,8 @@ ath11k-y += core.o \ ce.o \ peer.o \ dbring.o \ - hw.o + hw.o \ + pcic.o ath11k-$(CONFIG_ATH11K_DEBUGFS) += debugfs.o debugfs_htt_stats.o debugfs_sta.o ath11k-$(CONFIG_NL80211_TESTMODE) += testmode.o @@ -29,7 +30,7 @@ obj-$(CONFIG_ATH11K_AHB) += ath11k_ahb.o ath11k_ahb-y += ahb.o obj-$(CONFIG_ATH11K_PCI) += ath11k_pci.o -ath11k_pci-y += mhi.o pci.o pcic.o +ath11k_pci-y += mhi.o pci.o # for tracing framework to find trace.h CFLAGS_trace.o := -I$(src) diff --git a/drivers/net/wireless/ath/ath11k/ahb.c b/drivers/net/wireless/ath/ath11k/ahb.c index 49d79cfbf21c7..050bda828966e 100644 --- a/drivers/net/wireless/ath/ath11k/ahb.c +++ b/drivers/net/wireless/ath/ath11k/ahb.c @@ -13,6 +13,7 @@ #include "debug.h" #include "hif.h" #include +#include "pcic.h" static const struct of_device_id ath11k_ahb_of_match[] = { /* TODO: Should we change the compatible string to something similar @@ -24,6 +25,9 @@ static const struct of_device_id ath11k_ahb_of_match[] = { { .compatible = "qcom,ipq6018-wifi", .data = (void *)ATH11K_HW_IPQ6018_HW10, }, + { .compatible = "qcom,wcn6750-wifi", + .data = (void *)ATH11K_HW_WCN6750_HW10, + }, { } }; @@ -128,6 +132,16 @@ enum ext_irq_num { tcl2host_status_ring, }; +static int +ath11k_ahb_get_msi_irq_wcn6750(struct ath11k_base *ab, unsigned int vector) +{ + return ab->pci.msi.irqs[vector]; +} + +static const struct ath11k_pci_ops ath11k_ahb_pci_ops_wcn6750 = { + .get_msi_irq = ath11k_ahb_get_msi_irq_wcn6750, +}; + static inline u32 ath11k_ahb_read32(struct ath11k_base *ab, u32 offset) { return ioread32(ab->mem + offset); @@ -395,6 +409,9 @@ static void ath11k_ahb_free_irq(struct ath11k_base *ab) int irq_idx; int i; + if (ab->hw_params.hybrid_bus_type) + return ath11k_pcic_free_irq(ab); + for (i = 0; i < ab->hw_params.ce_count; i++) { if (ath11k_ce_get_attr_flags(ab, i) & CE_ATTR_DIS_INTR) continue; @@ -549,6 +566,9 @@ static int ath11k_ahb_config_irq(struct ath11k_base *ab) int irq, irq_idx, i; int ret; + if (ab->hw_params.hybrid_bus_type) + return ath11k_pcic_config_irq(ab); + /* Configure CE irqs */ for (i = 0; i < ab->hw_params.ce_count; i++) { struct ath11k_ce_pipe *ce_pipe = &ab->ce.ce_pipe[i]; @@ -618,7 +638,7 @@ static int ath11k_ahb_map_service_to_pipe(struct ath11k_base *ab, u16 service_id return 0; } -static const struct ath11k_hif_ops ath11k_ahb_hif_ops = { +static const struct ath11k_hif_ops ath11k_ahb_hif_ops_ipq8074 = { .start = ath11k_ahb_start, .stop = ath11k_ahb_stop, .read32 = ath11k_ahb_read32, @@ -630,6 +650,20 @@ static const struct ath11k_hif_ops ath11k_ahb_hif_ops = { .power_up = ath11k_ahb_power_up, }; +static const struct ath11k_hif_ops ath11k_ahb_hif_ops_wcn6750 = { + .start = ath11k_pcic_start, + .stop = ath11k_pcic_stop, + .read32 = ath11k_pcic_read32, + .write32 = ath11k_pcic_write32, + .irq_enable = ath11k_pcic_ext_irq_enable, + .irq_disable = ath11k_pcic_ext_irq_disable, + .get_msi_address = ath11k_pcic_get_msi_address, + .get_user_msi_vector = ath11k_pcic_get_user_msi_assignment, + .map_service_to_pipe = ath11k_pcic_map_service_to_pipe, + .power_down = ath11k_ahb_power_down, + .power_up = ath11k_ahb_power_up, +}; + static int ath11k_core_get_rproc(struct ath11k_base *ab) { struct ath11k_ahb *ab_ahb = ath11k_ahb_priv(ab); @@ -652,12 +686,84 @@ static int ath11k_core_get_rproc(struct ath11k_base *ab) return 0; } +static int ath11k_ahb_setup_msi_resources(struct ath11k_base *ab) +{ + struct platform_device *pdev = ab->pdev; + phys_addr_t msi_addr_pa; + dma_addr_t msi_addr_iova; + struct resource *res; + int int_prop; + int ret; + int i; + + ret = ath11k_pcic_init_msi_config(ab); + if (ret) { + ath11k_err(ab, "failed to init msi config: %d\n", ret); + return ret; + } + + res = platform_get_resource(pdev, IORESOURCE_MEM, 0); + if (!res) { + ath11k_err(ab, "failed to fetch msi_addr\n"); + return -ENOENT; + } + + msi_addr_pa = res->start; + msi_addr_iova = dma_map_resource(ab->dev, msi_addr_pa, PAGE_SIZE, + DMA_FROM_DEVICE, 0); + if (dma_mapping_error(ab->dev, msi_addr_iova)) + return -ENOMEM; + + ab->pci.msi.addr_lo = lower_32_bits(msi_addr_iova); + ab->pci.msi.addr_hi = upper_32_bits(msi_addr_iova); + + ret = of_property_read_u32_index(ab->dev->of_node, "interrupts", 1, &int_prop); + if (ret) + return ret; + + ab->pci.msi.ep_base_data = int_prop + 32; + + for (i = 0; i < ab->pci.msi.config->total_vectors; i++) { + res = platform_get_resource(pdev, IORESOURCE_IRQ, i); + if (!res) + return -ENODEV; + + ab->pci.msi.irqs[i] = res->start; + } + + set_bit(ATH11K_FLAG_MULTI_MSI_VECTORS, &ab->dev_flags); + + return 0; +} + +static int ath11k_ahb_setup_resources(struct ath11k_base *ab) +{ + struct platform_device *pdev = ab->pdev; + struct resource *mem_res; + void __iomem *mem; + + if (ab->hw_params.hybrid_bus_type) + return ath11k_ahb_setup_msi_resources(ab); + + mem = devm_platform_get_and_ioremap_resource(pdev, 0, &mem_res); + if (IS_ERR(mem)) { + dev_err(&pdev->dev, "ioremap error\n"); + return PTR_ERR(mem); + } + + ab->mem = mem; + ab->mem_len = resource_size(mem_res); + + return 0; +} + static int ath11k_ahb_probe(struct platform_device *pdev) { struct ath11k_base *ab; const struct of_device_id *of_id; - struct resource *mem_res; - void __iomem *mem; + const struct ath11k_hif_ops *hif_ops; + const struct ath11k_pci_ops *pci_ops; + enum ath11k_hw_rev hw_rev; int ret; of_id = of_match_device(ath11k_ahb_of_match, &pdev->dev); @@ -666,10 +772,21 @@ static int ath11k_ahb_probe(struct platform_device *pdev) return -EINVAL; } - mem = devm_platform_get_and_ioremap_resource(pdev, 0, &mem_res); - if (IS_ERR(mem)) { - dev_err(&pdev->dev, "ioremap error\n"); - return PTR_ERR(mem); + hw_rev = (enum ath11k_hw_rev)of_id->data; + + switch (hw_rev) { + case ATH11K_HW_IPQ8074: + case ATH11K_HW_IPQ6018_HW10: + hif_ops = &ath11k_ahb_hif_ops_ipq8074; + pci_ops = NULL; + break; + case ATH11K_HW_WCN6750_HW10: + hif_ops = &ath11k_ahb_hif_ops_wcn6750; + pci_ops = &ath11k_ahb_pci_ops_wcn6750; + break; + default: + dev_err(&pdev->dev, "unsupported device type %d\n", hw_rev); + return -EOPNOTSUPP; } ret = dma_set_mask_and_coherent(&pdev->dev, DMA_BIT_MASK(32)); @@ -685,13 +802,16 @@ static int ath11k_ahb_probe(struct platform_device *pdev) return -ENOMEM; } - ab->hif.ops = &ath11k_ahb_hif_ops; + ab->hif.ops = hif_ops; + ab->pci.ops = pci_ops; ab->pdev = pdev; - ab->hw_rev = (enum ath11k_hw_rev)of_id->data; - ab->mem = mem; - ab->mem_len = resource_size(mem_res); + ab->hw_rev = hw_rev; platform_set_drvdata(pdev, ab); + ret = ath11k_ahb_setup_resources(ab); + if (ret) + goto err_core_free; + ret = ath11k_core_pre_init(ab); if (ret) goto err_core_free; diff --git a/drivers/net/wireless/ath/ath11k/core.h b/drivers/net/wireless/ath/ath11k/core.h index fdea446271255..95bca0b078b16 100644 --- a/drivers/net/wireless/ath/ath11k/core.h +++ b/drivers/net/wireless/ath/ath11k/core.h @@ -950,6 +950,7 @@ struct ath11k_base { struct { const struct ath11k_msi_config *config; u32 ep_base_data; + u32 irqs[32]; u32 addr_lo; u32 addr_hi; } msi; diff --git a/drivers/net/wireless/ath/ath11k/pcic.c b/drivers/net/wireless/ath/ath11k/pcic.c index 46cf96d3e1d2d..cf12b98c480d6 100644 --- a/drivers/net/wireless/ath/ath11k/pcic.c +++ b/drivers/net/wireless/ath/ath11k/pcic.c @@ -106,6 +106,15 @@ static const struct ath11k_msi_config ath11k_msi_config[] = { }, .hw_rev = ATH11K_HW_WCN6855_HW21, }, + { + .total_vectors = 28, + .total_users = 2, + .users = (struct ath11k_msi_user[]) { + { .name = "CE", .num_vectors = 10, .base_vector = 0 }, + { .name = "DP", .num_vectors = 18, .base_vector = 10 }, + }, + .hw_rev = ATH11K_HW_WCN6750_HW10, + }, }; int ath11k_pcic_init_msi_config(struct ath11k_base *ab) @@ -172,6 +181,7 @@ void ath11k_pcic_write32(struct ath11k_base *ab, u32 offset, u32 value) !ret) ab->pci.ops->release(ab); } +EXPORT_SYMBOL(ath11k_pcic_write32); u32 ath11k_pcic_read32(struct ath11k_base *ab, u32 offset) { @@ -203,6 +213,7 @@ u32 ath11k_pcic_read32(struct ath11k_base *ab, u32 offset) return val; } +EXPORT_SYMBOL(ath11k_pcic_read32); void ath11k_pcic_get_msi_address(struct ath11k_base *ab, u32 *msi_addr_lo, u32 *msi_addr_hi) @@ -210,6 +221,7 @@ void ath11k_pcic_get_msi_address(struct ath11k_base *ab, u32 *msi_addr_lo, *msi_addr_lo = ab->pci.msi.addr_lo; *msi_addr_hi = ab->pci.msi.addr_hi; } +EXPORT_SYMBOL(ath11k_pcic_get_msi_address); int ath11k_pcic_get_user_msi_assignment(struct ath11k_base *ab, char *user_name, int *num_vectors, u32 *user_base_data, @@ -237,6 +249,7 @@ int ath11k_pcic_get_user_msi_assignment(struct ath11k_base *ab, char *user_name, return -EINVAL; } +EXPORT_SYMBOL(ath11k_pcic_get_user_msi_assignment); void ath11k_pcic_get_ce_msi_idx(struct ath11k_base *ab, u32 ce_id, u32 *msi_idx) { @@ -253,6 +266,7 @@ void ath11k_pcic_get_ce_msi_idx(struct ath11k_base *ab, u32 ce_id, u32 *msi_idx) } *msi_idx = msi_data_idx; } +EXPORT_SYMBOL(ath11k_pcic_get_ce_msi_idx); static void ath11k_pcic_free_ext_irq(struct ath11k_base *ab) { @@ -281,6 +295,7 @@ void ath11k_pcic_free_irq(struct ath11k_base *ab) ath11k_pcic_free_ext_irq(ab); } +EXPORT_SYMBOL(ath11k_pcic_free_irq); static void ath11k_pcic_ce_irq_enable(struct ath11k_base *ab, u16 ce_id) { @@ -431,6 +446,7 @@ void ath11k_pcic_ext_irq_enable(struct ath11k_base *ab) ath11k_pcic_ext_grp_enable(irq_grp); } } +EXPORT_SYMBOL(ath11k_pcic_ext_irq_enable); static void ath11k_pcic_sync_ext_irqs(struct ath11k_base *ab) { @@ -451,6 +467,7 @@ void ath11k_pcic_ext_irq_disable(struct ath11k_base *ab) __ath11k_pcic_ext_irq_disable(ab); ath11k_pcic_sync_ext_irqs(ab); } +EXPORT_SYMBOL(ath11k_pcic_ext_irq_disable); static int ath11k_pcic_ext_grp_napi_poll(struct napi_struct *napi, int budget) { @@ -630,6 +647,7 @@ int ath11k_pcic_config_irq(struct ath11k_base *ab) return 0; } +EXPORT_SYMBOL(ath11k_pcic_config_irq); void ath11k_pcic_ce_irqs_enable(struct ath11k_base *ab) { @@ -643,6 +661,7 @@ void ath11k_pcic_ce_irqs_enable(struct ath11k_base *ab) ath11k_pcic_ce_irq_enable(ab, i); } } +EXPORT_SYMBOL(ath11k_pcic_ce_irqs_enable); static void ath11k_pcic_kill_tasklets(struct ath11k_base *ab) { @@ -664,12 +683,14 @@ void ath11k_pcic_ce_irq_disable_sync(struct ath11k_base *ab) ath11k_pcic_sync_ce_irqs(ab); ath11k_pcic_kill_tasklets(ab); } +EXPORT_SYMBOL(ath11k_pcic_ce_irq_disable_sync); void ath11k_pcic_stop(struct ath11k_base *ab) { ath11k_pcic_ce_irq_disable_sync(ab); ath11k_ce_cleanup_pipes(ab); } +EXPORT_SYMBOL(ath11k_pcic_stop); int ath11k_pcic_start(struct ath11k_base *ab) { @@ -680,6 +701,7 @@ int ath11k_pcic_start(struct ath11k_base *ab) return 0; } +EXPORT_SYMBOL(ath11k_pcic_start); int ath11k_pcic_map_service_to_pipe(struct ath11k_base *ab, u16 service_id, u8 *ul_pipe, u8 *dl_pipe) @@ -723,3 +745,4 @@ int ath11k_pcic_map_service_to_pipe(struct ath11k_base *ab, u16 service_id, return 0; } +EXPORT_SYMBOL(ath11k_pcic_map_service_to_pipe); From 52bcfd1b239b0a62d863b92abcc1a04528a41946 Mon Sep 17 00:00:00 2001 From: Jakub Kicinski Date: Fri, 29 Apr 2022 10:46:42 -0700 Subject: [PATCH 216/228] ath10k: remove a copy of the NAPI_POLL_WEIGHT define Defining local versions of NAPI_POLL_WEIGHT with the same values in the drivers just makes refactoring harder. Signed-off-by: Jakub Kicinski Signed-off-by: Kalle Valo Link: https://lore.kernel.org/r/20220429174643.196994-3-kuba@kernel.org --- drivers/net/wireless/ath/ath10k/core.h | 3 --- drivers/net/wireless/ath/ath10k/pci.c | 2 +- drivers/net/wireless/ath/ath10k/sdio.c | 2 +- drivers/net/wireless/ath/ath10k/snoc.c | 2 +- drivers/net/wireless/ath/ath10k/usb.c | 2 +- 5 files changed, 4 insertions(+), 7 deletions(-) diff --git a/drivers/net/wireless/ath/ath10k/core.h b/drivers/net/wireless/ath/ath10k/core.h index 9f6680b3be0a7..8bfabbcfdb143 100644 --- a/drivers/net/wireless/ath/ath10k/core.h +++ b/drivers/net/wireless/ath/ath10k/core.h @@ -59,9 +59,6 @@ #define ATH10K_KEEPALIVE_MAX_IDLE 3895 #define ATH10K_KEEPALIVE_MAX_UNRESPONSIVE 3900 -/* NAPI poll budget */ -#define ATH10K_NAPI_BUDGET 64 - /* SMBIOS type containing Board Data File Name Extension */ #define ATH10K_SMBIOS_BDF_EXT_TYPE 0xF8 diff --git a/drivers/net/wireless/ath/ath10k/pci.c b/drivers/net/wireless/ath/ath10k/pci.c index 4d4e2f91e15cf..bf1c938be7d0a 100644 --- a/drivers/net/wireless/ath/ath10k/pci.c +++ b/drivers/net/wireless/ath/ath10k/pci.c @@ -3216,7 +3216,7 @@ static void ath10k_pci_free_irq(struct ath10k *ar) void ath10k_pci_init_napi(struct ath10k *ar) { netif_napi_add(&ar->napi_dev, &ar->napi, ath10k_pci_napi_poll, - ATH10K_NAPI_BUDGET); + NAPI_POLL_WEIGHT); } static int ath10k_pci_init_irq(struct ath10k *ar) diff --git a/drivers/net/wireless/ath/ath10k/sdio.c b/drivers/net/wireless/ath/ath10k/sdio.c index 63e1c2d783c5f..9162b02b72113 100644 --- a/drivers/net/wireless/ath/ath10k/sdio.c +++ b/drivers/net/wireless/ath/ath10k/sdio.c @@ -2532,7 +2532,7 @@ static int ath10k_sdio_probe(struct sdio_func *func, } netif_napi_add(&ar->napi_dev, &ar->napi, ath10k_sdio_napi_poll, - ATH10K_NAPI_BUDGET); + NAPI_POLL_WEIGHT); ath10k_dbg(ar, ATH10K_DBG_BOOT, "sdio new func %d vendor 0x%x device 0x%x block 0x%x/0x%x\n", diff --git a/drivers/net/wireless/ath/ath10k/snoc.c b/drivers/net/wireless/ath/ath10k/snoc.c index 8328966a0471c..607e8164bf984 100644 --- a/drivers/net/wireless/ath/ath10k/snoc.c +++ b/drivers/net/wireless/ath/ath10k/snoc.c @@ -1243,7 +1243,7 @@ static int ath10k_snoc_napi_poll(struct napi_struct *ctx, int budget) static void ath10k_snoc_init_napi(struct ath10k *ar) { netif_napi_add(&ar->napi_dev, &ar->napi, ath10k_snoc_napi_poll, - ATH10K_NAPI_BUDGET); + NAPI_POLL_WEIGHT); } static int ath10k_snoc_request_irq(struct ath10k *ar) diff --git a/drivers/net/wireless/ath/ath10k/usb.c b/drivers/net/wireless/ath/ath10k/usb.c index 10df6ca303a1c..ad6471b217964 100644 --- a/drivers/net/wireless/ath/ath10k/usb.c +++ b/drivers/net/wireless/ath/ath10k/usb.c @@ -1015,7 +1015,7 @@ static int ath10k_usb_probe(struct usb_interface *interface, } netif_napi_add(&ar->napi_dev, &ar->napi, ath10k_usb_napi_poll, - ATH10K_NAPI_BUDGET); + NAPI_POLL_WEIGHT); usb_get_dev(dev); vendor_id = le16_to_cpu(dev->descriptor.idVendor); From 3b3299a1080e357c540e968b704f2eeb46a697f7 Mon Sep 17 00:00:00 2001 From: Jakub Kicinski Date: Fri, 29 Apr 2022 10:46:43 -0700 Subject: [PATCH 217/228] wil6210: use NAPI_POLL_WEIGHT for napi budget The comment next to WIL6210_NAPI_BUDGET says "arbitrary". If we're picking arbitrary values let's pick the recommended default which is NAPI_POLL_WEIGHT. Signed-off-by: Jakub Kicinski Signed-off-by: Kalle Valo Link: https://lore.kernel.org/r/20220429174643.196994-4-kuba@kernel.org --- drivers/net/wireless/ath/wil6210/netdev.c | 8 ++++---- drivers/net/wireless/ath/wil6210/wil6210.h | 1 - 2 files changed, 4 insertions(+), 5 deletions(-) diff --git a/drivers/net/wireless/ath/wil6210/netdev.c b/drivers/net/wireless/ath/wil6210/netdev.c index 0913f0bf60e79..3906480663823 100644 --- a/drivers/net/wireless/ath/wil6210/netdev.c +++ b/drivers/net/wireless/ath/wil6210/netdev.c @@ -457,17 +457,17 @@ int wil_if_add(struct wil6210_priv *wil) if (wil->use_enhanced_dma_hw) { netif_napi_add(&wil->napi_ndev, &wil->napi_rx, wil6210_netdev_poll_rx_edma, - WIL6210_NAPI_BUDGET); + NAPI_POLL_WEIGHT); netif_tx_napi_add(&wil->napi_ndev, &wil->napi_tx, wil6210_netdev_poll_tx_edma, - WIL6210_NAPI_BUDGET); + NAPI_POLL_WEIGHT); } else { netif_napi_add(&wil->napi_ndev, &wil->napi_rx, wil6210_netdev_poll_rx, - WIL6210_NAPI_BUDGET); + NAPI_POLL_WEIGHT); netif_tx_napi_add(&wil->napi_ndev, &wil->napi_tx, wil6210_netdev_poll_tx, - WIL6210_NAPI_BUDGET); + NAPI_POLL_WEIGHT); } wil_update_net_queues_bh(wil, vif, NULL, true); diff --git a/drivers/net/wireless/ath/wil6210/wil6210.h b/drivers/net/wireless/ath/wil6210/wil6210.h index 11946ecd0b999..22a6eb3e12b7e 100644 --- a/drivers/net/wireless/ath/wil6210/wil6210.h +++ b/drivers/net/wireless/ath/wil6210/wil6210.h @@ -82,7 +82,6 @@ static inline u32 WIL_GET_BITS(u32 x, int b0, int b1) #define WIL6210_MAX_TX_RINGS (24) /* HW limit */ #define WIL6210_MAX_CID (20) /* max number of stations */ #define WIL6210_RX_DESC_MAX_CID (8) /* HW limit */ -#define WIL6210_NAPI_BUDGET (16) /* arbitrary */ #define WIL_MAX_AMPDU_SIZE (64 * 1024) /* FW/HW limit */ #define WIL_MAX_AGG_WSIZE (32) /* FW/HW limit */ #define WIL_MAX_AMPDU_SIZE_128 (128 * 1024) /* FW/HW limit */ From 54a6f29522da3c914da30e50721dedf51046449a Mon Sep 17 00:00:00 2001 From: Xiaomeng Tong Date: Mon, 28 Mar 2022 20:28:20 +0800 Subject: [PATCH 218/228] carl9170: tx: fix an incorrect use of list iterator If the previous list_for_each_entry_continue_rcu() don't exit early (no goto hit inside the loop), the iterator 'cvif' after the loop will be a bogus pointer to an invalid structure object containing the HEAD (&ar->vif_list). As a result, the use of 'cvif' after that will lead to a invalid memory access (i.e., 'cvif->id': the invalid pointer dereference when return back to/after the callsite in the carl9170_update_beacon()). The original intention should have been to return the valid 'cvif' when found in list, NULL otherwise. So just return NULL when no entry found, to fix this bug. Cc: stable@vger.kernel.org Fixes: 1f1d9654e183c ("carl9170: refactor carl9170_update_beacon") Signed-off-by: Xiaomeng Tong Acked-by: Christian Lamparter Signed-off-by: Kalle Valo Link: https://lore.kernel.org/r/20220328122820.1004-1-xiam0nd.tong@gmail.com --- drivers/net/wireless/ath/carl9170/tx.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/drivers/net/wireless/ath/carl9170/tx.c b/drivers/net/wireless/ath/carl9170/tx.c index 1b76f4434c069..791f9f120af3a 100644 --- a/drivers/net/wireless/ath/carl9170/tx.c +++ b/drivers/net/wireless/ath/carl9170/tx.c @@ -1558,6 +1558,9 @@ static struct carl9170_vif_info *carl9170_pick_beaconing_vif(struct ar9170 *ar) goto out; } } while (ar->beacon_enabled && i--); + + /* no entry found in list */ + return NULL; } out: From 0d3b26c4b97ae1a561070a973f0b2086e3644d1a Mon Sep 17 00:00:00 2001 From: Jakub Kicinski Date: Fri, 29 Apr 2022 10:46:41 -0700 Subject: [PATCH 219/228] rtw88: remove a copy of the NAPI_POLL_WEIGHT define Defining local versions of NAPI_POLL_WEIGHT with the same values in the drivers just makes refactoring harder. Signed-off-by: Jakub Kicinski Signed-off-by: Kalle Valo Link: https://lore.kernel.org/r/20220429174643.196994-2-kuba@kernel.org --- drivers/net/wireless/realtek/rtw88/main.h | 1 - drivers/net/wireless/realtek/rtw88/pci.c | 2 +- 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/drivers/net/wireless/realtek/rtw88/main.h b/drivers/net/wireless/realtek/rtw88/main.h index de149a3b3ba1b..0baaf5a32e82d 100644 --- a/drivers/net/wireless/realtek/rtw88/main.h +++ b/drivers/net/wireless/realtek/rtw88/main.h @@ -17,7 +17,6 @@ #include "util.h" -#define RTW_NAPI_WEIGHT_NUM 64 #define RTW_MAX_MAC_ID_NUM 32 #define RTW_MAX_SEC_CAM_NUM 32 #define MAX_PG_CAM_BACKUP_NUM 8 diff --git a/drivers/net/wireless/realtek/rtw88/pci.c b/drivers/net/wireless/realtek/rtw88/pci.c index 3ef0de70af328..24d5695363d3f 100644 --- a/drivers/net/wireless/realtek/rtw88/pci.c +++ b/drivers/net/wireless/realtek/rtw88/pci.c @@ -1718,7 +1718,7 @@ static void rtw_pci_napi_init(struct rtw_dev *rtwdev) init_dummy_netdev(&rtwpci->netdev); netif_napi_add(&rtwpci->netdev, &rtwpci->napi, rtw_pci_napi_poll, - RTW_NAPI_WEIGHT_NUM); + NAPI_POLL_WEIGHT); } static void rtw_pci_napi_deinit(struct rtw_dev *rtwdev) From ccc915e7dd7e79d2d810a62a73c57e25a120795d Mon Sep 17 00:00:00 2001 From: Srinivasan Raju Date: Mon, 2 May 2022 16:01:32 +0100 Subject: [PATCH 220/228] plfxlc: fix le16_to_cpu warning for beacon_interval Fix the following sparse warnings: drivers/net/wireless/purelifi/plfxlc/chip.c:36:31: sparse: expected unsigned short [usertype] beacon_interval drivers/net/wireless/purelifi/plfxlc/chip.c:36:31: sparse: got restricted __le16 [usertype] Reported-by: kernel test robot Signed-off-by: Srinivasan Raju Signed-off-by: Kalle Valo Link: https://lore.kernel.org/r/20220502150133.6052-1-srini.raju@purelifi.com --- drivers/net/wireless/purelifi/plfxlc/chip.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/drivers/net/wireless/purelifi/plfxlc/chip.c b/drivers/net/wireless/purelifi/plfxlc/chip.c index a5ec10b66ed53..f4ef9ff971469 100644 --- a/drivers/net/wireless/purelifi/plfxlc/chip.c +++ b/drivers/net/wireless/purelifi/plfxlc/chip.c @@ -29,11 +29,10 @@ int plfxlc_set_beacon_interval(struct plfxlc_chip *chip, u16 interval, u8 dtim_period, int type) { if (!interval || - (chip->beacon_set && - le16_to_cpu(chip->beacon_interval) == interval)) + (chip->beacon_set && chip->beacon_interval == interval)) return 0; - chip->beacon_interval = cpu_to_le16(interval); + chip->beacon_interval = interval; chip->beacon_set = true; return plfxlc_usb_wreq(chip->usb.ez_usb, &chip->beacon_interval, From ec424639d41b82aee16282b47091f95ee42e1767 Mon Sep 17 00:00:00 2001 From: Ping-Ke Shih Date: Tue, 3 May 2022 07:54:01 +0800 Subject: [PATCH 221/228] rtw89: 8852c: rfk: add RFK tables These tables are used by RFK (RF calibration) to set parameters. These parameters can trigger certain calibration, or configure/reset settings before and after RF calibrations. Signed-off-by: Ping-Ke Shih Signed-off-by: Kalle Valo Link: https://lore.kernel.org/r/20220502235408.15052-2-pkshih@realtek.com --- .../realtek/rtw89/rtw8852c_rfk_table.c | 781 ++++++++++++++++++ .../realtek/rtw89/rtw8852c_rfk_table.h | 67 ++ 2 files changed, 848 insertions(+) create mode 100644 drivers/net/wireless/realtek/rtw89/rtw8852c_rfk_table.c create mode 100644 drivers/net/wireless/realtek/rtw89/rtw8852c_rfk_table.h diff --git a/drivers/net/wireless/realtek/rtw89/rtw8852c_rfk_table.c b/drivers/net/wireless/realtek/rtw89/rtw8852c_rfk_table.c new file mode 100644 index 0000000000000..d727d528b3651 --- /dev/null +++ b/drivers/net/wireless/realtek/rtw89/rtw8852c_rfk_table.c @@ -0,0 +1,781 @@ +// SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause +/* Copyright(c) 2019-2022 Realtek Corporation + */ + +#include "rtw8852c_rfk_table.h" + +static const struct rtw89_reg5_def rtw8852c_dack_reload_defs[] = { + RTW89_DECL_RFK_WM(0xc004, BIT(17), 0x1), + RTW89_DECL_RFK_WM(0xc024, BIT(17), 0x1), + RTW89_DECL_RFK_WM(0xc104, BIT(17), 0x1), + RTW89_DECL_RFK_WM(0xc124, BIT(17), 0x1), +}; + +RTW89_DECLARE_RFK_TBL(rtw8852c_dack_reload_defs); + +static const struct rtw89_reg5_def rtw8852c_dack_reset_defs_a[] = { + RTW89_DECL_RFK_WM(0xc000, BIT(17), 0x0), + RTW89_DECL_RFK_WM(0xc000, BIT(17), 0x1), +}; + +RTW89_DECLARE_RFK_TBL(rtw8852c_dack_reset_defs_a); + +static const struct rtw89_reg5_def rtw8852c_dack_reset_defs_b[] = { + RTW89_DECL_RFK_WM(0xc100, BIT(17), 0x0), + RTW89_DECL_RFK_WM(0xc100, BIT(17), 0x1), +}; + +RTW89_DECLARE_RFK_TBL(rtw8852c_dack_reset_defs_b); + +static const struct rtw89_reg5_def rtw8852c_dack_defs_s0[] = { + RTW89_DECL_RFK_WM(0x12b8, BIT(30), 0x1), + RTW89_DECL_RFK_WM(0x030c, BIT(28), 0x1), + RTW89_DECL_RFK_WM(0x032c, 0x80000000, 0x0), + RTW89_DECL_RFK_WM(0xc004, 0xfff00000, 0x30), + RTW89_DECL_RFK_WM(0xc024, 0xfff00000, 0x30), +}; + +RTW89_DECLARE_RFK_TBL(rtw8852c_dack_defs_s0); + +static const struct rtw89_reg5_def rtw8852c_dack_defs_s1[] = { + RTW89_DECL_RFK_WM(0x32b8, BIT(30), 0x1), + RTW89_DECL_RFK_WM(0x030c, BIT(28), 0x1), + RTW89_DECL_RFK_WM(0x032c, 0x80000000, 0x0), + RTW89_DECL_RFK_WM(0xc104, 0xfff00000, 0x30), + RTW89_DECL_RFK_WM(0xc124, 0xfff00000, 0x30), +}; + +RTW89_DECLARE_RFK_TBL(rtw8852c_dack_defs_s1); + +static const struct rtw89_reg5_def rtw8852c_drck_defs[] = { + RTW89_DECL_RFK_WM(0xc0c4, BIT(6), 0x0), + RTW89_DECL_RFK_WM(0xc094, BIT(9), 0x1), + RTW89_DECL_RFK_DELAY(1), + RTW89_DECL_RFK_WM(0xc094, BIT(9), 0x0), +}; + +RTW89_DECLARE_RFK_TBL(rtw8852c_drck_defs); + +static const struct rtw89_reg5_def rtw8852c_iqk_rxk_cfg_defs[] = { + RTW89_DECL_RFK_WM(0x030c, 0xff000000, 0x0f), + RTW89_DECL_RFK_WM(0x030c, 0xff000000, 0x03), + RTW89_DECL_RFK_WM(0x032c, 0xffff0000, 0x0001), + RTW89_DECL_RFK_WM(0x032c, 0xffff0000, 0x0041), +}; + +RTW89_DECLARE_RFK_TBL(rtw8852c_iqk_rxk_cfg_defs); + +static const struct rtw89_reg5_def rtw8852c_iqk_afebb_restore_defs_a[] = { + RTW89_DECL_RFK_WM(0x12b8, 0x40000000, 0x0), + RTW89_DECL_RFK_WM(0x20fc, 0x00010000, 0x1), + RTW89_DECL_RFK_WM(0x20fc, 0x00100000, 0x0), + RTW89_DECL_RFK_WM(0x20fc, 0x01000000, 0x1), + RTW89_DECL_RFK_WM(0x20fc, 0x10000000, 0x0), + RTW89_DECL_RFK_WM(0x5670, MASKDWORD, 0x00000000), + RTW89_DECL_RFK_WM(0x12a0, 0x000ff000, 0x00), + RTW89_DECL_RFK_WM(0x20fc, 0x00010000, 0x0), + RTW89_DECL_RFK_WM(0x20fc, 0x01000000, 0x0), + RTW89_DECL_RFK_WRF(RF_PATH_A, 0x10005, 0x00001, 0x1), +}; + +RTW89_DECLARE_RFK_TBL(rtw8852c_iqk_afebb_restore_defs_a); + +static const struct rtw89_reg5_def rtw8852c_iqk_afebb_restore_defs_b[] = { + RTW89_DECL_RFK_WM(0x32b8, 0x40000000, 0x0), + RTW89_DECL_RFK_WM(0x20fc, 0x00020000, 0x1), + RTW89_DECL_RFK_WM(0x20fc, 0x00200000, 0x0), + RTW89_DECL_RFK_WM(0x20fc, 0x02000000, 0x1), + RTW89_DECL_RFK_WM(0x20fc, 0x20000000, 0x0), + RTW89_DECL_RFK_WM(0x7670, MASKDWORD, 0x00000000), + RTW89_DECL_RFK_WM(0x32a0, 0x000ff000, 0x00), + RTW89_DECL_RFK_WM(0x20fc, 0x00020000, 0x0), + RTW89_DECL_RFK_WM(0x20fc, 0x02000000, 0x0), + RTW89_DECL_RFK_WRF(RF_PATH_B, 0x10005, 0x00001, 0x1), +}; + +RTW89_DECLARE_RFK_TBL(rtw8852c_iqk_afebb_restore_defs_b); + +static const struct rtw89_reg5_def rtw8852c_read_rxsram_pre_defs[] = { + RTW89_DECL_RFK_WM(0x80e8, BIT(7), 0x1), + RTW89_DECL_RFK_WM(0x8074, BIT(31), 0x1), + RTW89_DECL_RFK_WM(0x80d4, MASKDWORD, 0x00020000), +}; + +RTW89_DECLARE_RFK_TBL(rtw8852c_read_rxsram_pre_defs); + +static const struct rtw89_reg5_def rtw8852c_read_rxsram_post_defs[] = { + RTW89_DECL_RFK_WM(0x80e8, BIT(7), 0x0), + RTW89_DECL_RFK_WM(0x8074, BIT(31), 0x0), +}; + +RTW89_DECLARE_RFK_TBL(rtw8852c_read_rxsram_post_defs); + +static const struct rtw89_reg5_def rtw8852c_dpk_mdpd_order0_defs[] = { + RTW89_DECL_RFK_WM(0x80a0, BIT(1) | BIT(0), 0x0), + RTW89_DECL_RFK_WM(0x809c, BIT(10) | BIT(9), 0x2), + RTW89_DECL_RFK_WM(0x80a0, 0x00001F00, 0x4), + RTW89_DECL_RFK_WM(0x8070, 0x70000000, 0x1), +}; + +RTW89_DECLARE_RFK_TBL(rtw8852c_dpk_mdpd_order0_defs); + +static const struct rtw89_reg5_def rtw8852c_dpk_mdpd_order1_defs[] = { + RTW89_DECL_RFK_WM(0x80a0, BIT(1) | BIT(0), 0x1), + RTW89_DECL_RFK_WM(0x809c, BIT(10) | BIT(9), 0x1), + RTW89_DECL_RFK_WM(0x80a0, 0x00001F00, 0x0), + RTW89_DECL_RFK_WM(0x8070, 0x70000000, 0x0), +}; + +RTW89_DECLARE_RFK_TBL(rtw8852c_dpk_mdpd_order1_defs); + +static const struct rtw89_reg5_def rtw8852c_dpk_mdpd_order2_defs[] = { + RTW89_DECL_RFK_WM(0x80a0, BIT(1) | BIT(0), 0x2), + RTW89_DECL_RFK_WM(0x809c, BIT(10) | BIT(9), 0x0), + RTW89_DECL_RFK_WM(0x80a0, 0x00001F00, 0x0), + RTW89_DECL_RFK_WM(0x8070, 0x70000000, 0x0), +}; + +RTW89_DECLARE_RFK_TBL(rtw8852c_dpk_mdpd_order2_defs); + +static const struct rtw89_reg5_def rtw8852c_dpk_mdpd_order3_defs[] = { + RTW89_DECL_RFK_WM(0x80a0, BIT(1) | BIT(0), 0x3), + RTW89_DECL_RFK_WM(0x809c, BIT(10) | BIT(9), 0x3), + RTW89_DECL_RFK_WM(0x80a0, 0x00001F00, 0x4), + RTW89_DECL_RFK_WM(0x8070, 0x70000000, 0x1), +}; + +RTW89_DECLARE_RFK_TBL(rtw8852c_dpk_mdpd_order3_defs); + +static const struct rtw89_reg5_def rtw8852c_dpk_kip_pwr_clk_on_defs[] = { + RTW89_DECL_RFK_WM(0x8008, MASKDWORD, 0x00000080), + RTW89_DECL_RFK_WM(0x8088, MASKDWORD, 0x807f030a), +}; + +RTW89_DECLARE_RFK_TBL(rtw8852c_dpk_kip_pwr_clk_on_defs); + +static const struct rtw89_reg5_def rtw8852c_dpk_kip_pwr_clk_off_defs[] = { + RTW89_DECL_RFK_WM(0x8008, MASKDWORD, 0x00000000), + RTW89_DECL_RFK_WM(0x8088, MASKDWORD, 0x80000000), + RTW89_DECL_RFK_WM(0x80f4, BIT(18), 0x1), +}; + +RTW89_DECLARE_RFK_TBL(rtw8852c_dpk_kip_pwr_clk_off_defs); + +static const struct rtw89_reg5_def rtw8852c_tssi_sys_defs[] = { + RTW89_DECL_RFK_WM(0x12bc, 0x000ffff0, 0xb5b5), + RTW89_DECL_RFK_WM(0x32bc, 0x000ffff0, 0xb5b5), + RTW89_DECL_RFK_WM(0x0300, 0xff000000, 0x16), + RTW89_DECL_RFK_WM(0x0304, 0x0000ffff, 0x1f19), + RTW89_DECL_RFK_WM(0x0308, 0xff000000, 0x1c), + RTW89_DECL_RFK_WM(0x0314, 0xffff0000, 0x2041), + RTW89_DECL_RFK_WM(0x0318, 0xffffffff, 0x20012041), + RTW89_DECL_RFK_WM(0x0324, 0xffff0000, 0x2001), + RTW89_DECL_RFK_WM(0x0020, 0x00006000, 0x3), + RTW89_DECL_RFK_WM(0x0024, 0x00006000, 0x3), + RTW89_DECL_RFK_WM(0x0704, 0xffff0000, 0x601e), + RTW89_DECL_RFK_WM(0x2704, 0xffff0000, 0x601e), + RTW89_DECL_RFK_WM(0x0700, 0xf0000000, 0x4), + RTW89_DECL_RFK_WM(0x2700, 0xf0000000, 0x4), + RTW89_DECL_RFK_WM(0x0650, 0x3c000000, 0x0), + RTW89_DECL_RFK_WM(0x2650, 0x3c000000, 0x0), +}; + +RTW89_DECLARE_RFK_TBL(rtw8852c_tssi_sys_defs); + +static const struct rtw89_reg5_def rtw8852c_tssi_sys_defs_2g_a[] = { + RTW89_DECL_RFK_WM(0x120c, 0x000000ff, 0x33), + RTW89_DECL_RFK_WM(0x12c0, 0x0ff00000, 0x33), + RTW89_DECL_RFK_WM(0x58f8, 0x40000000, 0x1), +}; + +RTW89_DECLARE_RFK_TBL(rtw8852c_tssi_sys_defs_2g_a); + +static const struct rtw89_reg5_def rtw8852c_tssi_sys_defs_2g_b[] = { + RTW89_DECL_RFK_WM(0x320c, 0x000000ff, 0x33), + RTW89_DECL_RFK_WM(0x32c0, 0x0ff00000, 0x33), + RTW89_DECL_RFK_WM(0x78f8, 0x40000000, 0x1), +}; + +RTW89_DECLARE_RFK_TBL(rtw8852c_tssi_sys_defs_2g_b); + +static const struct rtw89_reg5_def rtw8852c_tssi_sys_defs_5g_a[] = { + RTW89_DECL_RFK_WM(0x120c, 0x000000ff, 0x44), + RTW89_DECL_RFK_WM(0x12c0, 0x0ff00000, 0x44), + RTW89_DECL_RFK_WM(0x58f8, 0x40000000, 0x0), +}; + +RTW89_DECLARE_RFK_TBL(rtw8852c_tssi_sys_defs_5g_a); + +static const struct rtw89_reg5_def rtw8852c_tssi_sys_defs_5g_b[] = { + RTW89_DECL_RFK_WM(0x320c, 0x000000ff, 0x44), + RTW89_DECL_RFK_WM(0x32c0, 0x0ff00000, 0x44), + RTW89_DECL_RFK_WM(0x78f8, 0x40000000, 0x0), +}; + +RTW89_DECLARE_RFK_TBL(rtw8852c_tssi_sys_defs_5g_b); + +static const struct rtw89_reg5_def rtw8852c_tssi_txpwr_ctrl_bb_defs_a[] = { + RTW89_DECL_RFK_WM(0x566c, 0x00001000, 0x0), + RTW89_DECL_RFK_WM(0x5800, 0xffffffff, 0x003f807f), + RTW89_DECL_RFK_WM(0x580c, 0x0000007f, 0x40), + RTW89_DECL_RFK_WM(0x580c, 0x0fffff00, 0x00040), + RTW89_DECL_RFK_WM(0x5810, 0xffffffff, 0x59010000), + RTW89_DECL_RFK_WM(0x5814, 0x01ffffff, 0x026d000), + RTW89_DECL_RFK_WM(0x5814, 0xf8000000, 0x00), + RTW89_DECL_RFK_WM(0x5818, 0xffffffff, 0x002c1800), + RTW89_DECL_RFK_WM(0x581c, 0x3fffffff, 0x3dc80280), + RTW89_DECL_RFK_WM(0x5820, 0xffffffff, 0x00000080), + RTW89_DECL_RFK_WM(0x58e8, 0x0000003f, 0x03), + RTW89_DECL_RFK_WM(0x580c, 0x10000000, 0x1), + RTW89_DECL_RFK_WM(0x580c, 0x40000000, 0x1), + RTW89_DECL_RFK_WM(0x5834, 0x3fffffff, 0x000115f2), + RTW89_DECL_RFK_WM(0x5838, 0x7fffffff, 0x0000121), + RTW89_DECL_RFK_WM(0x5854, 0x3fffffff, 0x000115f2), + RTW89_DECL_RFK_WM(0x5858, 0x7fffffff, 0x0000121), + RTW89_DECL_RFK_WM(0x5860, 0x80000000, 0x0), + RTW89_DECL_RFK_WM(0x5864, 0x07ffffff, 0x00801ff), + RTW89_DECL_RFK_WM(0x5898, 0xffffffff, 0x00000000), + RTW89_DECL_RFK_WM(0x589c, 0xffffffff, 0x00000000), + RTW89_DECL_RFK_WM(0x58a4, 0x000000ff, 0x16), + RTW89_DECL_RFK_WM(0x58b4, 0x7fffffff, 0x0a002000), + RTW89_DECL_RFK_WM(0x58b8, 0x7fffffff, 0x00007628), + RTW89_DECL_RFK_WM(0x58bc, 0x07ffffff, 0x7a7807f), + RTW89_DECL_RFK_WM(0x58c0, 0xfffe0000, 0x003f), + RTW89_DECL_RFK_WM(0x58c4, 0xffffffff, 0x0003ffff), + RTW89_DECL_RFK_WM(0x58c8, 0x00ffffff, 0x000000), + RTW89_DECL_RFK_WM(0x58c8, 0xf0000000, 0x0), + RTW89_DECL_RFK_WM(0x58cc, 0xffffffff, 0x00000000), + RTW89_DECL_RFK_WM(0x58d0, 0x07ffffff, 0x2008101), + RTW89_DECL_RFK_WM(0x58d4, 0x000000ff, 0x00), + RTW89_DECL_RFK_WM(0x58d4, 0x0003fe00, 0x0ff), + RTW89_DECL_RFK_WM(0x58d4, 0x07fc0000, 0x100), + RTW89_DECL_RFK_WM(0x58d8, 0xffffffff, 0x8008016c), + RTW89_DECL_RFK_WM(0x58dc, 0x0001ffff, 0x0807f), + RTW89_DECL_RFK_WM(0x58dc, 0xfff00000, 0x800), + RTW89_DECL_RFK_WM(0x58f0, 0x0003ffff, 0x001ff), + RTW89_DECL_RFK_WM(0x58f4, 0x000fffff, 0x000), + RTW89_DECL_RFK_WM(0x58f8, 0x000fffff, 0x000), +}; + +RTW89_DECLARE_RFK_TBL(rtw8852c_tssi_txpwr_ctrl_bb_defs_a); + +static const struct rtw89_reg5_def rtw8852c_tssi_txpwr_ctrl_bb_defs_b[] = { + RTW89_DECL_RFK_WM(0x566c, 0x00001000, 0x0), + RTW89_DECL_RFK_WM(0x7800, 0xffffffff, 0x003f807f), + RTW89_DECL_RFK_WM(0x780c, 0x0000007f, 0x40), + RTW89_DECL_RFK_WM(0x780c, 0x0fffff00, 0x00040), + RTW89_DECL_RFK_WM(0x7810, 0xffffffff, 0x59010000), + RTW89_DECL_RFK_WM(0x7814, 0x01ffffff, 0x026d000), + RTW89_DECL_RFK_WM(0x7814, 0xf8000000, 0x00), + RTW89_DECL_RFK_WM(0x7818, 0xffffffff, 0x002c1800), + RTW89_DECL_RFK_WM(0x781c, 0x3fffffff, 0x3dc80280), + RTW89_DECL_RFK_WM(0x7820, 0xffffffff, 0x00000080), + RTW89_DECL_RFK_WM(0x78e8, 0x0000003f, 0x03), + RTW89_DECL_RFK_WM(0x780c, 0x10000000, 0x1), + RTW89_DECL_RFK_WM(0x780c, 0x40000000, 0x1), + RTW89_DECL_RFK_WM(0x7834, 0x3fffffff, 0x000115f2), + RTW89_DECL_RFK_WM(0x7838, 0x7fffffff, 0x0000121), + RTW89_DECL_RFK_WM(0x7854, 0x3fffffff, 0x000115f2), + RTW89_DECL_RFK_WM(0x7858, 0x7fffffff, 0x0000121), + RTW89_DECL_RFK_WM(0x7860, 0x80000000, 0x0), + RTW89_DECL_RFK_WM(0x7864, 0x07ffffff, 0x00801ff), + RTW89_DECL_RFK_WM(0x7898, 0xffffffff, 0x00000000), + RTW89_DECL_RFK_WM(0x789c, 0xffffffff, 0x00000000), + RTW89_DECL_RFK_WM(0x78a4, 0x000000ff, 0x16), + RTW89_DECL_RFK_WM(0x78b4, 0x7fffffff, 0x0a002000), + RTW89_DECL_RFK_WM(0x78b8, 0x7fffffff, 0x00007628), + RTW89_DECL_RFK_WM(0x78bc, 0x07ffffff, 0x7a7807f), + RTW89_DECL_RFK_WM(0x78c0, 0xfffe0000, 0x003f), + RTW89_DECL_RFK_WM(0x78c4, 0xffffffff, 0x0003ffff), + RTW89_DECL_RFK_WM(0x78c8, 0x00ffffff, 0x000000), + RTW89_DECL_RFK_WM(0x78c8, 0xf0000000, 0x0), + RTW89_DECL_RFK_WM(0x78cc, 0xffffffff, 0x00000000), + RTW89_DECL_RFK_WM(0x78d0, 0x07ffffff, 0x2008101), + RTW89_DECL_RFK_WM(0x78d4, 0x000000ff, 0x00), + RTW89_DECL_RFK_WM(0x78d4, 0x0003fe00, 0x0ff), + RTW89_DECL_RFK_WM(0x78d4, 0x07fc0000, 0x100), + RTW89_DECL_RFK_WM(0x78d8, 0xffffffff, 0x8008016c), + RTW89_DECL_RFK_WM(0x78dc, 0x0001ffff, 0x0807f), + RTW89_DECL_RFK_WM(0x78dc, 0xfff00000, 0x800), + RTW89_DECL_RFK_WM(0x78f0, 0x0003ffff, 0x001ff), + RTW89_DECL_RFK_WM(0x78f4, 0x000fffff, 0x000), + RTW89_DECL_RFK_WM(0x78f8, 0x000fffff, 0x000), +}; + +RTW89_DECLARE_RFK_TBL(rtw8852c_tssi_txpwr_ctrl_bb_defs_b); + +static const struct rtw89_reg5_def rtw8852c_tssi_txpwr_ctrl_bb_he_tb_defs_a[] = { + RTW89_DECL_RFK_WM(0x58a0, 0xffffffff, 0x000000fe), + RTW89_DECL_RFK_WM(0x58e4, 0x0000007f, 0x1f), +}; + +RTW89_DECLARE_RFK_TBL(rtw8852c_tssi_txpwr_ctrl_bb_he_tb_defs_a); + +static const struct rtw89_reg5_def rtw8852c_tssi_txpwr_ctrl_bb_he_tb_defs_b[] = { + RTW89_DECL_RFK_WM(0x78a0, 0xffffffff, 0x000000fe), + RTW89_DECL_RFK_WM(0x78e4, 0x0000007f, 0x1f), +}; + +RTW89_DECLARE_RFK_TBL(rtw8852c_tssi_txpwr_ctrl_bb_he_tb_defs_b); + +static const struct rtw89_reg5_def rtw8852c_tssi_dck_defs_a[] = { + RTW89_DECL_RFK_WM(0x58c4, 0x3ffc0000, 0x0), + RTW89_DECL_RFK_WM(0x58c8, 0x00000fff, 0x0), + RTW89_DECL_RFK_WM(0x58c8, 0x00fff000, 0x0), +}; + +RTW89_DECLARE_RFK_TBL(rtw8852c_tssi_dck_defs_a); + +static const struct rtw89_reg5_def rtw8852c_tssi_dck_defs_b[] = { + RTW89_DECL_RFK_WM(0x78c4, 0x3ffc0000, 0x0), + RTW89_DECL_RFK_WM(0x78c8, 0x00000fff, 0x0), + RTW89_DECL_RFK_WM(0x78c8, 0x00fff000, 0x0), +}; + +RTW89_DECLARE_RFK_TBL(rtw8852c_tssi_dck_defs_b); + +static const struct rtw89_reg5_def rtw8852c_tssi_dck_defs_2g_a[] = { + RTW89_DECL_RFK_WM(0x580c, 0x0fff0000, 0x000), + RTW89_DECL_RFK_WM(0x5814, 0x003ff000, 0x1af), + RTW89_DECL_RFK_WM(0x5814, 0x18000000, 0x0), +}; + +RTW89_DECLARE_RFK_TBL(rtw8852c_tssi_dck_defs_2g_a); + +static const struct rtw89_reg5_def rtw8852c_tssi_dck_defs_2g_b[] = { + RTW89_DECL_RFK_WM(0x780c, 0x0fff0000, 0x000), + RTW89_DECL_RFK_WM(0x7814, 0x003ff000, 0x1af), + RTW89_DECL_RFK_WM(0x7814, 0x18000000, 0x0), +}; + +RTW89_DECLARE_RFK_TBL(rtw8852c_tssi_dck_defs_2g_b); + +static const struct rtw89_reg5_def rtw8852c_tssi_dck_defs_5g_a[] = { + RTW89_DECL_RFK_WM(0x580c, 0x0fff0000, 0x000), + RTW89_DECL_RFK_WM(0x5814, 0x00001000, 0x1), + RTW89_DECL_RFK_WM(0x5814, 0x0003c000, 0xb), + RTW89_DECL_RFK_WM(0x5814, 0x00002000, 0x1), + RTW89_DECL_RFK_WM(0x5814, 0x003c0000, 0x6), + RTW89_DECL_RFK_WM(0x5814, 0x18000000, 0x0), +}; + +RTW89_DECLARE_RFK_TBL(rtw8852c_tssi_dck_defs_5g_a); + +static const struct rtw89_reg5_def rtw8852c_tssi_dck_defs_5g_b[] = { + RTW89_DECL_RFK_WM(0x780c, 0x0fff0000, 0x000), + RTW89_DECL_RFK_WM(0x7814, 0x00001000, 0x1), + RTW89_DECL_RFK_WM(0x7814, 0x0003c000, 0xb), + RTW89_DECL_RFK_WM(0x7814, 0x00002000, 0x1), + RTW89_DECL_RFK_WM(0x7814, 0x003c0000, 0x6), + RTW89_DECL_RFK_WM(0x7814, 0x18000000, 0x0), +}; + +RTW89_DECLARE_RFK_TBL(rtw8852c_tssi_dck_defs_5g_b); + +static const struct rtw89_reg5_def rtw8852c_tssi_set_bbgain_split_a[] = { + RTW89_DECL_RFK_WM(0x5818, 0x08000000, 0x1), + RTW89_DECL_RFK_WM(0x58d4, 0xf0000000, 0x7), + RTW89_DECL_RFK_WM(0x58f0, 0x000c0000, 0x1), + RTW89_DECL_RFK_WM(0x58f0, 0xfff00000, 0x400), +}; + +RTW89_DECLARE_RFK_TBL(rtw8852c_tssi_set_bbgain_split_a); + +static const struct rtw89_reg5_def rtw8852c_tssi_set_bbgain_split_b[] = { + RTW89_DECL_RFK_WM(0x7818, 0x08000000, 0x1), + RTW89_DECL_RFK_WM(0x78d4, 0xf0000000, 0x7), + RTW89_DECL_RFK_WM(0x78f0, 0x000c0000, 0x1), + RTW89_DECL_RFK_WM(0x78f0, 0xfff00000, 0x400), +}; + +RTW89_DECLARE_RFK_TBL(rtw8852c_tssi_set_bbgain_split_b); + +static const struct rtw89_reg5_def rtw8852c_tssi_slope_cal_org_defs_2g_a[] = { + RTW89_DECL_RFK_WM(0x5608, 0x07ffffff, 0x0201008), + RTW89_DECL_RFK_WM(0x560c, 0x07ffffff, 0x0201008), + RTW89_DECL_RFK_WM(0x5610, 0x07ffffff, 0x0201020), + RTW89_DECL_RFK_WM(0x5614, 0x07ffffff, 0x0201008), + RTW89_DECL_RFK_WM(0x5618, 0x07ffffff, 0x0801008), + RTW89_DECL_RFK_WM(0x561c, 0x000001ff, 0x008), + RTW89_DECL_RFK_WM(0x561c, 0xffff0000, 0x0808), + RTW89_DECL_RFK_WM(0x5620, 0xffffffff, 0x08080808), + RTW89_DECL_RFK_WM(0x5624, 0xffffffff, 0x0808081e), + RTW89_DECL_RFK_WM(0x5628, 0xffffffff, 0x08080808), + RTW89_DECL_RFK_WM(0x562c, 0x0000ffff, 0x081d), + RTW89_DECL_RFK_WM(0x581c, 0x00100000, 0x1), +}; + +RTW89_DECLARE_RFK_TBL(rtw8852c_tssi_slope_cal_org_defs_2g_a); + +static const struct rtw89_reg5_def rtw8852c_tssi_slope_cal_org_defs_2g_b[] = { + RTW89_DECL_RFK_WM(0x7608, 0x07ffffff, 0x0201008), + RTW89_DECL_RFK_WM(0x760c, 0x07ffffff, 0x0201008), + RTW89_DECL_RFK_WM(0x7610, 0x07ffffff, 0x0204020), + RTW89_DECL_RFK_WM(0x7614, 0x07ffffff, 0x0201008), + RTW89_DECL_RFK_WM(0x7618, 0x07ffffff, 0x0801008), + RTW89_DECL_RFK_WM(0x761c, 0x000001ff, 0x020), + RTW89_DECL_RFK_WM(0x761c, 0xffff0000, 0x0808), + RTW89_DECL_RFK_WM(0x7620, 0xffffffff, 0x08080808), + RTW89_DECL_RFK_WM(0x7624, 0xffffffff, 0x08081e21), + RTW89_DECL_RFK_WM(0x7628, 0xffffffff, 0x08080808), + RTW89_DECL_RFK_WM(0x762c, 0x0000ffff, 0x1d23), + RTW89_DECL_RFK_WM(0x781c, 0x00100000, 0x1), +}; + +RTW89_DECLARE_RFK_TBL(rtw8852c_tssi_slope_cal_org_defs_2g_b); + +static const struct rtw89_reg5_def rtw8852c_tssi_slope_cal_org_defs_5g_a[] = { + RTW89_DECL_RFK_WM(0x5608, 0x07ffffff, 0x0201008), + RTW89_DECL_RFK_WM(0x560c, 0x07ffffff, 0x0201008), + RTW89_DECL_RFK_WM(0x5610, 0x07ffffff, 0x0201008), + RTW89_DECL_RFK_WM(0x5614, 0x07ffffff, 0x0201008), + RTW89_DECL_RFK_WM(0x5618, 0x07ffffff, 0x0201008), + RTW89_DECL_RFK_WM(0x561c, 0x000001ff, 0x008), + RTW89_DECL_RFK_WM(0x561c, 0xffff0000, 0x0808), + RTW89_DECL_RFK_WM(0x5620, 0xffffffff, 0x08080808), + RTW89_DECL_RFK_WM(0x5624, 0xffffffff, 0x08080808), + RTW89_DECL_RFK_WM(0x5628, 0xffffffff, 0x08080808), + RTW89_DECL_RFK_WM(0x562c, 0x0000ffff, 0x0808), + RTW89_DECL_RFK_WM(0x581c, 0x00100000, 0x0), +}; + +RTW89_DECLARE_RFK_TBL(rtw8852c_tssi_slope_cal_org_defs_5g_a); + +static const struct rtw89_reg5_def rtw8852c_tssi_slope_cal_org_defs_5g_b[] = { + RTW89_DECL_RFK_WM(0x7608, 0x07ffffff, 0x0201008), + RTW89_DECL_RFK_WM(0x760c, 0x07ffffff, 0x0201008), + RTW89_DECL_RFK_WM(0x7610, 0x07ffffff, 0x0201008), + RTW89_DECL_RFK_WM(0x7614, 0x07ffffff, 0x0201008), + RTW89_DECL_RFK_WM(0x7618, 0x07ffffff, 0x0201008), + RTW89_DECL_RFK_WM(0x761c, 0x000001ff, 0x008), + RTW89_DECL_RFK_WM(0x761c, 0xffff0000, 0x0808), + RTW89_DECL_RFK_WM(0x7620, 0xffffffff, 0x08080808), + RTW89_DECL_RFK_WM(0x7624, 0xffffffff, 0x08080808), + RTW89_DECL_RFK_WM(0x7628, 0xffffffff, 0x08080808), + RTW89_DECL_RFK_WM(0x762c, 0x0000ffff, 0x0808), + RTW89_DECL_RFK_WM(0x781c, 0x00100000, 0x0), +}; + +RTW89_DECLARE_RFK_TBL(rtw8852c_tssi_slope_cal_org_defs_5g_b); + +static const struct rtw89_reg5_def rtw8852c_tssi_set_aligk_default_defs_2g_a[] = { + RTW89_DECL_RFK_WM(0x5604, 0x80000000, 0x1), + RTW89_DECL_RFK_WM(0x5600, 0x3fffffff, 0x000000), + RTW89_DECL_RFK_WM(0x5604, 0x003fffff, 0x2d2721), + RTW89_DECL_RFK_WM(0x5630, 0x3fffffff, 0x00000000), + RTW89_DECL_RFK_WM(0x5634, 0x000003ff, 0x000), + RTW89_DECL_RFK_WM(0x5634, 0x000ffc00, 0x3b8), + RTW89_DECL_RFK_WM(0x5634, 0x3ff00000, 0x3d2), + RTW89_DECL_RFK_WM(0x5638, 0x000003ff, 0x042), + RTW89_DECL_RFK_WM(0x5638, 0x000ffc00, 0x06b), + RTW89_DECL_RFK_WM(0x563c, 0x3fffffff, 0x00000000), + RTW89_DECL_RFK_WM(0x5640, 0x000003ff, 0x000), + RTW89_DECL_RFK_WM(0x5640, 0x000ffc00, 0x3bc), + RTW89_DECL_RFK_WM(0x5640, 0x3ff00000, 0x3d6), + RTW89_DECL_RFK_WM(0x5644, 0x000003ff, 0x03e), + RTW89_DECL_RFK_WM(0x5644, 0x000ffc00, 0x06b), +}; + +RTW89_DECLARE_RFK_TBL(rtw8852c_tssi_set_aligk_default_defs_2g_a); + +static const struct rtw89_reg5_def rtw8852c_tssi_set_aligk_default_defs_2g_b[] = { + RTW89_DECL_RFK_WM(0x7604, 0x80000000, 0x1), + RTW89_DECL_RFK_WM(0x7600, 0x3fffffff, 0x000000), + RTW89_DECL_RFK_WM(0x7604, 0x003fffff, 0x2d2721), + RTW89_DECL_RFK_WM(0x7630, 0x3fffffff, 0x00000000), + RTW89_DECL_RFK_WM(0x7634, 0x000003ff, 0x000), + RTW89_DECL_RFK_WM(0x7634, 0x000ffc00, 0x3c0), + RTW89_DECL_RFK_WM(0x7634, 0x3ff00000, 0x3da), + RTW89_DECL_RFK_WM(0x7638, 0x000003ff, 0x002), + RTW89_DECL_RFK_WM(0x7638, 0x000ffc00, 0x071), + RTW89_DECL_RFK_WM(0x763c, 0x3fffffff, 0x00000000), + RTW89_DECL_RFK_WM(0x7640, 0x000003ff, 0x000), + RTW89_DECL_RFK_WM(0x7640, 0x000ffc00, 0x3c8), + RTW89_DECL_RFK_WM(0x7640, 0x3ff00000, 0x3e2), + RTW89_DECL_RFK_WM(0x7644, 0x000003ff, 0x00c), + RTW89_DECL_RFK_WM(0x7644, 0x000ffc00, 0x071), +}; + +RTW89_DECLARE_RFK_TBL(rtw8852c_tssi_set_aligk_default_defs_2g_b); + +static const struct rtw89_reg5_def rtw8852c_tssi_set_aligk_default_defs_5g_a[] = { + RTW89_DECL_RFK_WM(0x5604, 0x80000000, 0x1), + RTW89_DECL_RFK_WM(0x5600, 0x3fffffff, 0x000000), + RTW89_DECL_RFK_WM(0x5604, 0x003fffff, 0x312600), + RTW89_DECL_RFK_WM(0x5630, 0x3fffffff, 0x00000000), + RTW89_DECL_RFK_WM(0x5634, 0x000003ff, 0x000), + RTW89_DECL_RFK_WM(0x5634, 0x000ffc00, 0x000), + RTW89_DECL_RFK_WM(0x5634, 0x3ff00000, 0x3e9), + RTW89_DECL_RFK_WM(0x5638, 0x000003ff, 0x039), + RTW89_DECL_RFK_WM(0x5638, 0x000ffc00, 0x07d), + RTW89_DECL_RFK_WM(0x563c, 0x3fffffff, 0x00000000), + RTW89_DECL_RFK_WM(0x5640, 0x000003ff, 0x000), + RTW89_DECL_RFK_WM(0x5640, 0x000ffc00, 0x000), + RTW89_DECL_RFK_WM(0x5640, 0x3ff00000, 0x000), + RTW89_DECL_RFK_WM(0x5644, 0x000003ff, 0x000), + RTW89_DECL_RFK_WM(0x5644, 0x000ffc00, 0x000), +}; + +RTW89_DECLARE_RFK_TBL(rtw8852c_tssi_set_aligk_default_defs_5g_a); + +static const struct rtw89_reg5_def rtw8852c_tssi_set_aligk_default_defs_5g_b[] = { + RTW89_DECL_RFK_WM(0x7604, 0x80000000, 0x1), + RTW89_DECL_RFK_WM(0x7600, 0x3fffffff, 0x000000), + RTW89_DECL_RFK_WM(0x7604, 0x003fffff, 0x312600), + RTW89_DECL_RFK_WM(0x7630, 0x3fffffff, 0x00000000), + RTW89_DECL_RFK_WM(0x7634, 0x000003ff, 0x000), + RTW89_DECL_RFK_WM(0x7634, 0x000ffc00, 0x000), + RTW89_DECL_RFK_WM(0x7634, 0x3ff00000, 0x3e9), + RTW89_DECL_RFK_WM(0x7638, 0x000003ff, 0x039), + RTW89_DECL_RFK_WM(0x7638, 0x000ffc00, 0x07d), + RTW89_DECL_RFK_WM(0x763c, 0x3fffffff, 0x00000000), + RTW89_DECL_RFK_WM(0x7640, 0x000003ff, 0x000), + RTW89_DECL_RFK_WM(0x7640, 0x000ffc00, 0x000), + RTW89_DECL_RFK_WM(0x7640, 0x3ff00000, 0x000), + RTW89_DECL_RFK_WM(0x7644, 0x000003ff, 0x000), + RTW89_DECL_RFK_WM(0x7644, 0x000ffc00, 0x000), +}; + +RTW89_DECLARE_RFK_TBL(rtw8852c_tssi_set_aligk_default_defs_5g_b); + +static const struct rtw89_reg5_def rtw8852c_tssi_set_aligk_default_defs_6g_a[] = { + RTW89_DECL_RFK_WM(0x5604, 0x80000000, 0x1), + RTW89_DECL_RFK_WM(0x5600, 0x3fffffff, 0x000000), + RTW89_DECL_RFK_WM(0x5604, 0x003fffff, 0x312600), + RTW89_DECL_RFK_WM(0x5630, 0x3fffffff, 0x00000000), + RTW89_DECL_RFK_WM(0x5634, 0x000003ff, 0x000), + RTW89_DECL_RFK_WM(0x5634, 0x000ffc00, 0x000), + RTW89_DECL_RFK_WM(0x5634, 0x3ff00000, 0x3e9), + RTW89_DECL_RFK_WM(0x5638, 0x000003ff, 0x039), + RTW89_DECL_RFK_WM(0x5638, 0x000ffc00, 0x080), + RTW89_DECL_RFK_WM(0x563c, 0x3fffffff, 0x00000000), + RTW89_DECL_RFK_WM(0x5640, 0x000003ff, 0x000), + RTW89_DECL_RFK_WM(0x5640, 0x000ffc00, 0x000), + RTW89_DECL_RFK_WM(0x5640, 0x3ff00000, 0x000), + RTW89_DECL_RFK_WM(0x5644, 0x000003ff, 0x000), + RTW89_DECL_RFK_WM(0x5644, 0x000ffc00, 0x000), +}; + +RTW89_DECLARE_RFK_TBL(rtw8852c_tssi_set_aligk_default_defs_6g_a); + +static const struct rtw89_reg5_def rtw8852c_tssi_set_aligk_default_defs_6g_b[] = { + RTW89_DECL_RFK_WM(0x7604, 0x80000000, 0x1), + RTW89_DECL_RFK_WM(0x7600, 0x3fffffff, 0x000000), + RTW89_DECL_RFK_WM(0x7604, 0x003fffff, 0x312600), + RTW89_DECL_RFK_WM(0x7630, 0x3fffffff, 0x00000000), + RTW89_DECL_RFK_WM(0x7634, 0x000003ff, 0x000), + RTW89_DECL_RFK_WM(0x7634, 0x000ffc00, 0x000), + RTW89_DECL_RFK_WM(0x7634, 0x3ff00000, 0x3e9), + RTW89_DECL_RFK_WM(0x7638, 0x000003ff, 0x039), + RTW89_DECL_RFK_WM(0x7638, 0x000ffc00, 0x080), + RTW89_DECL_RFK_WM(0x763c, 0x3fffffff, 0x00000000), + RTW89_DECL_RFK_WM(0x7640, 0x000003ff, 0x000), + RTW89_DECL_RFK_WM(0x7640, 0x000ffc00, 0x000), + RTW89_DECL_RFK_WM(0x7640, 0x3ff00000, 0x000), + RTW89_DECL_RFK_WM(0x7644, 0x000003ff, 0x000), + RTW89_DECL_RFK_WM(0x7644, 0x000ffc00, 0x000), +}; + +RTW89_DECLARE_RFK_TBL(rtw8852c_tssi_set_aligk_default_defs_6g_b); + +static const struct rtw89_reg5_def rtw8852c_tssi_slope_defs_a[] = { + RTW89_DECL_RFK_WM(0x5820, 0x80000000, 0x0), + RTW89_DECL_RFK_WM(0x5818, 0x10000000, 0x0), + RTW89_DECL_RFK_WM(0x5814, 0x00000800, 0x1), + RTW89_DECL_RFK_WM(0x581c, 0x20000000, 0x1), + RTW89_DECL_RFK_WM(0x58e8, 0x0000003f, 0x0f), + RTW89_DECL_RFK_WM(0x581c, 0x000003ff, 0x280), + RTW89_DECL_RFK_WM(0x581c, 0x000ffc00, 0x200), + RTW89_DECL_RFK_WM(0x58b8, 0x007f0000, 0x00), + RTW89_DECL_RFK_WM(0x58b8, 0x7f000000, 0x00), + RTW89_DECL_RFK_WM(0x58b4, 0x7f000000, 0x0a), + RTW89_DECL_RFK_WM(0x58b8, 0x0000007f, 0x28), + RTW89_DECL_RFK_WM(0x58b8, 0x00007f00, 0x76), + RTW89_DECL_RFK_WM(0x5810, 0x20000000, 0x0), + RTW89_DECL_RFK_WM(0x5814, 0x20000000, 0x1), + RTW89_DECL_RFK_WM(0x580c, 0x10000000, 0x1), + RTW89_DECL_RFK_WM(0x580c, 0x40000000, 0x1), + RTW89_DECL_RFK_WM(0x5834, 0x0003ffff, 0x115f2), + RTW89_DECL_RFK_WM(0x5834, 0x3ffc0000, 0x000), + RTW89_DECL_RFK_WM(0x5838, 0x00000fff, 0x121), + RTW89_DECL_RFK_WM(0x5838, 0x003ff000, 0x000), + RTW89_DECL_RFK_WM(0x5854, 0x0003ffff, 0x115f2), + RTW89_DECL_RFK_WM(0x5854, 0x3ffc0000, 0x000), + RTW89_DECL_RFK_WM(0x5858, 0x00000fff, 0x121), + RTW89_DECL_RFK_WM(0x5858, 0x003ff000, 0x000), + RTW89_DECL_RFK_WM(0x5824, 0x0003ffff, 0x115f2), + RTW89_DECL_RFK_WM(0x5824, 0x3ffc0000, 0x000), + RTW89_DECL_RFK_WM(0x5828, 0x00000fff, 0x121), + RTW89_DECL_RFK_WM(0x5828, 0x003ff000, 0x000), + RTW89_DECL_RFK_WM(0x582c, 0x0003ffff, 0x115f2), + RTW89_DECL_RFK_WM(0x582c, 0x3ffc0000, 0x000), + RTW89_DECL_RFK_WM(0x5830, 0x00000fff, 0x121), + RTW89_DECL_RFK_WM(0x5830, 0x003ff000, 0x000), + RTW89_DECL_RFK_WM(0x583c, 0x0003ffff, 0x115f2), + RTW89_DECL_RFK_WM(0x583c, 0x3ffc0000, 0x000), + RTW89_DECL_RFK_WM(0x5840, 0x00000fff, 0x121), + RTW89_DECL_RFK_WM(0x5840, 0x003ff000, 0x000), + RTW89_DECL_RFK_WM(0x5844, 0x0003ffff, 0x115f2), + RTW89_DECL_RFK_WM(0x5844, 0x3ffc0000, 0x000), + RTW89_DECL_RFK_WM(0x5848, 0x00000fff, 0x121), + RTW89_DECL_RFK_WM(0x5848, 0x003ff000, 0x000), + RTW89_DECL_RFK_WM(0x584c, 0x0003ffff, 0x115f2), + RTW89_DECL_RFK_WM(0x584c, 0x3ffc0000, 0x000), + RTW89_DECL_RFK_WM(0x5850, 0x00000fff, 0x121), + RTW89_DECL_RFK_WM(0x5850, 0x003ff000, 0x000), + RTW89_DECL_RFK_WM(0x585c, 0x0003ffff, 0x115f2), + RTW89_DECL_RFK_WM(0x585c, 0x3ffc0000, 0x000), + RTW89_DECL_RFK_WM(0x5860, 0x00000fff, 0x121), + RTW89_DECL_RFK_WM(0x5860, 0x003ff000, 0x000), +}; + +RTW89_DECLARE_RFK_TBL(rtw8852c_tssi_slope_defs_a); + +static const struct rtw89_reg5_def rtw8852c_tssi_slope_defs_b[] = { + RTW89_DECL_RFK_WM(0x7820, 0x80000000, 0x0), + RTW89_DECL_RFK_WM(0x7818, 0x10000000, 0x0), + RTW89_DECL_RFK_WM(0x7814, 0x00000800, 0x1), + RTW89_DECL_RFK_WM(0x781c, 0x20000000, 0x1), + RTW89_DECL_RFK_WM(0x78e8, 0x0000003f, 0x0f), + RTW89_DECL_RFK_WM(0x781c, 0x000003ff, 0x280), + RTW89_DECL_RFK_WM(0x781c, 0x000ffc00, 0x200), + RTW89_DECL_RFK_WM(0x78b8, 0x007f0000, 0x00), + RTW89_DECL_RFK_WM(0x78b8, 0x7f000000, 0x00), + RTW89_DECL_RFK_WM(0x78b4, 0x7f000000, 0x0a), + RTW89_DECL_RFK_WM(0x78b8, 0x0000007f, 0x28), + RTW89_DECL_RFK_WM(0x78b8, 0x00007f00, 0x76), + RTW89_DECL_RFK_WM(0x7810, 0x20000000, 0x0), + RTW89_DECL_RFK_WM(0x7814, 0x20000000, 0x1), + RTW89_DECL_RFK_WM(0x780c, 0x10000000, 0x1), + RTW89_DECL_RFK_WM(0x780c, 0x40000000, 0x1), + RTW89_DECL_RFK_WM(0x7834, 0x0003ffff, 0x115f2), + RTW89_DECL_RFK_WM(0x7834, 0x3ffc0000, 0x000), + RTW89_DECL_RFK_WM(0x7838, 0x00000fff, 0x121), + RTW89_DECL_RFK_WM(0x7838, 0x003ff000, 0x000), + RTW89_DECL_RFK_WM(0x7854, 0x0003ffff, 0x115f2), + RTW89_DECL_RFK_WM(0x7854, 0x3ffc0000, 0x000), + RTW89_DECL_RFK_WM(0x7858, 0x00000fff, 0x121), + RTW89_DECL_RFK_WM(0x7858, 0x003ff000, 0x000), + RTW89_DECL_RFK_WM(0x7824, 0x0003ffff, 0x115f2), + RTW89_DECL_RFK_WM(0x7824, 0x3ffc0000, 0x000), + RTW89_DECL_RFK_WM(0x7828, 0x00000fff, 0x121), + RTW89_DECL_RFK_WM(0x7828, 0x003ff000, 0x000), + RTW89_DECL_RFK_WM(0x782c, 0x0003ffff, 0x115f2), + RTW89_DECL_RFK_WM(0x782c, 0x3ffc0000, 0x000), + RTW89_DECL_RFK_WM(0x7830, 0x00000fff, 0x121), + RTW89_DECL_RFK_WM(0x7830, 0x003ff000, 0x000), + RTW89_DECL_RFK_WM(0x783c, 0x0003ffff, 0x115f2), + RTW89_DECL_RFK_WM(0x783c, 0x3ffc0000, 0x000), + RTW89_DECL_RFK_WM(0x7840, 0x00000fff, 0x121), + RTW89_DECL_RFK_WM(0x7840, 0x003ff000, 0x000), + RTW89_DECL_RFK_WM(0x7844, 0x0003ffff, 0x115f2), + RTW89_DECL_RFK_WM(0x7844, 0x3ffc0000, 0x000), + RTW89_DECL_RFK_WM(0x7848, 0x00000fff, 0x121), + RTW89_DECL_RFK_WM(0x7848, 0x003ff000, 0x000), + RTW89_DECL_RFK_WM(0x784c, 0x0003ffff, 0x115f2), + RTW89_DECL_RFK_WM(0x784c, 0x3ffc0000, 0x000), + RTW89_DECL_RFK_WM(0x7850, 0x00000fff, 0x121), + RTW89_DECL_RFK_WM(0x7850, 0x003ff000, 0x000), + RTW89_DECL_RFK_WM(0x785c, 0x0003ffff, 0x115f2), + RTW89_DECL_RFK_WM(0x785c, 0x3ffc0000, 0x000), + RTW89_DECL_RFK_WM(0x7860, 0x00000fff, 0x121), + RTW89_DECL_RFK_WM(0x7860, 0x003ff000, 0x000), +}; + +RTW89_DECLARE_RFK_TBL(rtw8852c_tssi_slope_defs_b); + +static const struct rtw89_reg5_def rtw8852c_tssi_run_slope_defs_a[] = { + RTW89_DECL_RFK_WM(0x5820, 0x80000000, 0x0), + RTW89_DECL_RFK_WM(0x5820, 0x80000000, 0x1), +}; + +RTW89_DECLARE_RFK_TBL(rtw8852c_tssi_run_slope_defs_a); + +static const struct rtw89_reg5_def rtw8852c_tssi_run_slope_defs_b[] = { + RTW89_DECL_RFK_WM(0x7820, 0x80000000, 0x0), + RTW89_DECL_RFK_WM(0x7820, 0x80000000, 0x1), +}; + +RTW89_DECLARE_RFK_TBL(rtw8852c_tssi_run_slope_defs_b); + +static const struct rtw89_reg5_def rtw8852c_tssi_track_defs_a[] = { + RTW89_DECL_RFK_WM(0x5820, 0x80000000, 0x0), + RTW89_DECL_RFK_WM(0x5818, 0x10000000, 0x0), + RTW89_DECL_RFK_WM(0x5814, 0x00000800, 0x0), + RTW89_DECL_RFK_WM(0x581c, 0x20000000, 0x1), + RTW89_DECL_RFK_WM(0x5864, 0x000003ff, 0x1ff), + RTW89_DECL_RFK_WM(0x5864, 0x000ffc00, 0x200), + RTW89_DECL_RFK_WM(0x5820, 0x00000fff, 0x080), + RTW89_DECL_RFK_WM(0x5814, 0x01000000, 0x0), +}; + +RTW89_DECLARE_RFK_TBL(rtw8852c_tssi_track_defs_a); + +static const struct rtw89_reg5_def rtw8852c_tssi_track_defs_b[] = { + RTW89_DECL_RFK_WM(0x7820, 0x80000000, 0x0), + RTW89_DECL_RFK_WM(0x7818, 0x10000000, 0x0), + RTW89_DECL_RFK_WM(0x7814, 0x00000800, 0x0), + RTW89_DECL_RFK_WM(0x781c, 0x20000000, 0x1), + RTW89_DECL_RFK_WM(0x7864, 0x000003ff, 0x1ff), + RTW89_DECL_RFK_WM(0x7864, 0x000ffc00, 0x200), + RTW89_DECL_RFK_WM(0x7820, 0x00000fff, 0x080), + RTW89_DECL_RFK_WM(0x7814, 0x01000000, 0x0), +}; + +RTW89_DECLARE_RFK_TBL(rtw8852c_tssi_track_defs_b); + +static const struct rtw89_reg5_def rtw8852c_tssi_txagc_ofst_mv_avg_defs_a[] = { + RTW89_DECL_RFK_WM(0x58e4, 0x00003800, 0x1), + RTW89_DECL_RFK_WM(0x58e4, 0x00004000, 0x0), + RTW89_DECL_RFK_WM(0x58e4, 0x00008000, 0x1), + RTW89_DECL_RFK_WM(0x58e4, 0x000f0000, 0x0), + RTW89_DECL_RFK_WM(0x58e8, 0x0000003f, 0x03), +}; + +RTW89_DECLARE_RFK_TBL(rtw8852c_tssi_txagc_ofst_mv_avg_defs_a); + +static const struct rtw89_reg5_def rtw8852c_tssi_txagc_ofst_mv_avg_defs_b[] = { + RTW89_DECL_RFK_WM(0x78e4, 0x00003800, 0x1), + RTW89_DECL_RFK_WM(0x78e4, 0x00004000, 0x0), + RTW89_DECL_RFK_WM(0x78e4, 0x00008000, 0x1), + RTW89_DECL_RFK_WM(0x78e4, 0x000f0000, 0x0), + RTW89_DECL_RFK_WM(0x78e8, 0x0000003f, 0x03), +}; + +RTW89_DECLARE_RFK_TBL(rtw8852c_tssi_txagc_ofst_mv_avg_defs_b); + +static const struct rtw89_reg5_def rtw8852c_tssi_enable_defs_a[] = { + RTW89_DECL_RFK_WM(0x58e4, 0x00004000, 0x0), + RTW89_DECL_RFK_WM(0x5820, 0x80000000, 0x0), + RTW89_DECL_RFK_WM(0x5820, 0x80000000, 0x1), + RTW89_DECL_RFK_WRF(0x0, 0x10055, 0x00080, 0x1), + RTW89_DECL_RFK_WM(0x5818, 0x10000000, 0x1), +}; + +RTW89_DECLARE_RFK_TBL(rtw8852c_tssi_enable_defs_a); + +static const struct rtw89_reg5_def rtw8852c_tssi_enable_defs_b[] = { + RTW89_DECL_RFK_WM(0x78e4, 0x00004000, 0x0), + RTW89_DECL_RFK_WM(0x7820, 0x80000000, 0x0), + RTW89_DECL_RFK_WM(0x7820, 0x80000000, 0x1), + RTW89_DECL_RFK_WRF(0x1, 0x10055, 0x00080, 0x1), + RTW89_DECL_RFK_WM(0x7818, 0x10000000, 0x1), +}; + +RTW89_DECLARE_RFK_TBL(rtw8852c_tssi_enable_defs_b); + +static const struct rtw89_reg5_def rtw8852c_tssi_disable_defs_a[] = { + RTW89_DECL_RFK_WM(0x5820, 0x80000000, 0x00000000), + RTW89_DECL_RFK_WM(0x5818, 0x10000000, 0x00000000), + RTW89_DECL_RFK_WM(0x58e4, 0x00004000, 0x00000001), +}; + +RTW89_DECLARE_RFK_TBL(rtw8852c_tssi_disable_defs_a); + +static const struct rtw89_reg5_def rtw8852c_tssi_disable_defs_b[] = { + RTW89_DECL_RFK_WM(0x7820, 0x80000000, 0x00000000), + RTW89_DECL_RFK_WM(0x7818, 0x10000000, 0x00000000), + RTW89_DECL_RFK_WM(0x78e4, 0x00004000, 0x00000001), +}; + +RTW89_DECLARE_RFK_TBL(rtw8852c_tssi_disable_defs_b); diff --git a/drivers/net/wireless/realtek/rtw89/rtw8852c_rfk_table.h b/drivers/net/wireless/realtek/rtw89/rtw8852c_rfk_table.h new file mode 100644 index 0000000000000..953a960ef1e85 --- /dev/null +++ b/drivers/net/wireless/realtek/rtw89/rtw8852c_rfk_table.h @@ -0,0 +1,67 @@ +/* SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause */ +/* Copyright(c) 2019-2022 Realtek Corporation + */ + +#ifndef __RTW89_8852C_RFK_TABLE_H__ +#define __RTW89_8852C_RFK_TABLE_H__ + +#include "phy.h" + +extern const struct rtw89_rfk_tbl rtw8852c_dack_reload_defs_tbl; +extern const struct rtw89_rfk_tbl rtw8852c_dack_reset_defs_a_tbl; +extern const struct rtw89_rfk_tbl rtw8852c_dack_reset_defs_b_tbl; +extern const struct rtw89_rfk_tbl rtw8852c_dack_defs_s0_tbl; +extern const struct rtw89_rfk_tbl rtw8852c_dack_defs_s1_tbl; +extern const struct rtw89_rfk_tbl rtw8852c_drck_defs_tbl; +extern const struct rtw89_rfk_tbl rtw8852c_iqk_rxk_cfg_defs_tbl; +extern const struct rtw89_rfk_tbl rtw8852c_iqk_afebb_restore_defs_a_tbl; +extern const struct rtw89_rfk_tbl rtw8852c_iqk_afebb_restore_defs_b_tbl; +extern const struct rtw89_rfk_tbl rtw8852c_read_rxsram_pre_defs_tbl; +extern const struct rtw89_rfk_tbl rtw8852c_read_rxsram_post_defs_tbl; +extern const struct rtw89_rfk_tbl rtw8852c_dpk_mdpd_order0_defs_tbl; +extern const struct rtw89_rfk_tbl rtw8852c_dpk_mdpd_order1_defs_tbl; +extern const struct rtw89_rfk_tbl rtw8852c_dpk_mdpd_order2_defs_tbl; +extern const struct rtw89_rfk_tbl rtw8852c_dpk_mdpd_order3_defs_tbl; +extern const struct rtw89_rfk_tbl rtw8852c_dpk_kip_pwr_clk_on_defs_tbl; +extern const struct rtw89_rfk_tbl rtw8852c_dpk_kip_pwr_clk_off_defs_tbl; +extern const struct rtw89_rfk_tbl rtw8852c_tssi_sys_defs_tbl; +extern const struct rtw89_rfk_tbl rtw8852c_tssi_sys_defs_2g_a_tbl; +extern const struct rtw89_rfk_tbl rtw8852c_tssi_sys_defs_2g_b_tbl; +extern const struct rtw89_rfk_tbl rtw8852c_tssi_sys_defs_5g_a_tbl; +extern const struct rtw89_rfk_tbl rtw8852c_tssi_sys_defs_5g_b_tbl; +extern const struct rtw89_rfk_tbl rtw8852c_tssi_txpwr_ctrl_bb_defs_a_tbl; +extern const struct rtw89_rfk_tbl rtw8852c_tssi_txpwr_ctrl_bb_defs_b_tbl; +extern const struct rtw89_rfk_tbl rtw8852c_tssi_txpwr_ctrl_bb_he_tb_defs_a_tbl; +extern const struct rtw89_rfk_tbl rtw8852c_tssi_txpwr_ctrl_bb_he_tb_defs_b_tbl; +extern const struct rtw89_rfk_tbl rtw8852c_tssi_dck_defs_a_tbl; +extern const struct rtw89_rfk_tbl rtw8852c_tssi_dck_defs_b_tbl; +extern const struct rtw89_rfk_tbl rtw8852c_tssi_dck_defs_2g_a_tbl; +extern const struct rtw89_rfk_tbl rtw8852c_tssi_dck_defs_2g_b_tbl; +extern const struct rtw89_rfk_tbl rtw8852c_tssi_dck_defs_5g_a_tbl; +extern const struct rtw89_rfk_tbl rtw8852c_tssi_dck_defs_5g_b_tbl; +extern const struct rtw89_rfk_tbl rtw8852c_tssi_set_bbgain_split_a_tbl; +extern const struct rtw89_rfk_tbl rtw8852c_tssi_set_bbgain_split_b_tbl; +extern const struct rtw89_rfk_tbl rtw8852c_tssi_slope_cal_org_defs_2g_a_tbl; +extern const struct rtw89_rfk_tbl rtw8852c_tssi_slope_cal_org_defs_2g_b_tbl; +extern const struct rtw89_rfk_tbl rtw8852c_tssi_slope_cal_org_defs_5g_a_tbl; +extern const struct rtw89_rfk_tbl rtw8852c_tssi_slope_cal_org_defs_5g_b_tbl; +extern const struct rtw89_rfk_tbl rtw8852c_tssi_set_aligk_default_defs_2g_a_tbl; +extern const struct rtw89_rfk_tbl rtw8852c_tssi_set_aligk_default_defs_2g_b_tbl; +extern const struct rtw89_rfk_tbl rtw8852c_tssi_set_aligk_default_defs_5g_a_tbl; +extern const struct rtw89_rfk_tbl rtw8852c_tssi_set_aligk_default_defs_5g_b_tbl; +extern const struct rtw89_rfk_tbl rtw8852c_tssi_set_aligk_default_defs_6g_a_tbl; +extern const struct rtw89_rfk_tbl rtw8852c_tssi_set_aligk_default_defs_6g_b_tbl; +extern const struct rtw89_rfk_tbl rtw8852c_tssi_slope_defs_a_tbl; +extern const struct rtw89_rfk_tbl rtw8852c_tssi_slope_defs_b_tbl; +extern const struct rtw89_rfk_tbl rtw8852c_tssi_run_slope_defs_a_tbl; +extern const struct rtw89_rfk_tbl rtw8852c_tssi_run_slope_defs_b_tbl; +extern const struct rtw89_rfk_tbl rtw8852c_tssi_track_defs_a_tbl; +extern const struct rtw89_rfk_tbl rtw8852c_tssi_track_defs_b_tbl; +extern const struct rtw89_rfk_tbl rtw8852c_tssi_txagc_ofst_mv_avg_defs_a_tbl; +extern const struct rtw89_rfk_tbl rtw8852c_tssi_txagc_ofst_mv_avg_defs_b_tbl; +extern const struct rtw89_rfk_tbl rtw8852c_tssi_enable_defs_a_tbl; +extern const struct rtw89_rfk_tbl rtw8852c_tssi_enable_defs_b_tbl; +extern const struct rtw89_rfk_tbl rtw8852c_tssi_disable_defs_a_tbl; +extern const struct rtw89_rfk_tbl rtw8852c_tssi_disable_defs_b_tbl; + +#endif From 76599a8d0b7d23b990d03dc5a0ceb450afd18391 Mon Sep 17 00:00:00 2001 From: Ping-Ke Shih Date: Tue, 3 May 2022 07:54:02 +0800 Subject: [PATCH 222/228] rtw89: 8852c: rfk: add DACK DACK (digital-to-analog converters calibration) is used to calibrate DAC to output analog signals as expected. Signed-off-by: Ping-Ke Shih Signed-off-by: Kalle Valo Link: https://lore.kernel.org/r/20220502235408.15052-3-pkshih@realtek.com --- drivers/net/wireless/realtek/rtw89/reg.h | 96 +++- drivers/net/wireless/realtek/rtw89/rtw8852c.c | 2 + .../net/wireless/realtek/rtw89/rtw8852c_rfk.c | 446 ++++++++++++++++++ .../net/wireless/realtek/rtw89/rtw8852c_rfk.h | 1 + 4 files changed, 538 insertions(+), 7 deletions(-) diff --git a/drivers/net/wireless/realtek/rtw89/reg.h b/drivers/net/wireless/realtek/rtw89/reg.h index 83cb509d2fbe9..ce472d3b1a665 100644 --- a/drivers/net/wireless/realtek/rtw89/reg.h +++ b/drivers/net/wireless/realtek/rtw89/reg.h @@ -3484,9 +3484,12 @@ #define R_S0_HW_SI_DIS 0x1200 #define B_S0_HW_SI_DIS_W_R_TRIG GENMASK(30, 28) #define R_P0_RXCK 0x12A0 -#define B_P0_RXCK_VAL GENMASK(18, 16) -#define B_P0_RXCK_ON BIT(19) #define B_P0_RXCK_BW3 BIT(30) +#define B_P0_TXCK_ALL GENMASK(19, 12) +#define B_P0_RXCK_ON BIT(19) +#define B_P0_RXCK_VAL GENMASK(18, 16) +#define B_P0_TXCK_ON BIT(15) +#define B_P0_TXCK_VAL GENMASK(14, 12) #define R_P0_NRBW 0x12B8 #define B_P0_NRBW_DBG BIT(30) #define R_S0_RXDC 0x12D4 @@ -4035,19 +4038,98 @@ #define R_IQKINF2 0x9FE8 #define B_IQKINF2_FCNT GENMASK(23, 16) #define B_IQKINF2_KCNT GENMASK(15, 8) -#define B_IQKINF2_NCTLV GENMAKS(7, 0) +#define B_IQKINF2_NCTLV GENMASK(7, 0) +#define R_DCOF0 0xC000 +#define B_DCOF0_V GENMASK(4, 1) +#define R_DCOF1 0xC004 +#define B_DCOF1_S BIT(0) +#define R_DCOF8 0xC020 +#define B_DCOF8_V GENMASK(4, 1) +#define R_DACK_S0P0 0xC040 +#define B_DACK_S0P0_OK BIT(31) +#define R_DACK_BIAS00 0xc048 +#define B_DACK_BIAS00 GENMASK(11, 2) +#define R_DACK_S0P2 0xC05C +#define B_DACK_S0M0 GENMASK(31, 24) +#define B_DACK_S0P2_OK BIT(2) +#define R_DACK_DADCK00 0xC060 +#define B_DACK_DADCK00 GENMASK(31, 24) +#define R_DACK_S0P1 0xC064 +#define B_DACK_S0P1_OK BIT(31) +#define R_DACK_BIAS01 0xC06C +#define B_DACK_BIAS01 GENMASK(11, 2) +#define R_DACK_S0P3 0xC080 +#define B_DACK_S0M1 GENMASK(31, 24) +#define B_DACK_S0P3_OK BIT(2) +#define R_DACK_DADCK01 0xC084 +#define B_DACK_DADCK01 GENMASK(31, 24) +#define R_DRCK 0xC0C4 +#define B_DRCK_IDLE BIT(9) +#define B_DRCK_EN BIT(6) +#define B_DRCK_VAL GENMASK(4, 0) +#define R_DRCK_RES 0xC0C8 +#define B_DRCK_RES GENMASK(19, 15) +#define B_DRCK_POL BIT(3) #define R_PATH0_SAMPL_DLY_T_V1 0xC0D4 #define B_PATH0_SAMPL_DLY_T_MSK_V1 GENMASK(27, 26) +#define R_P0_CFCH_BW0 0xC0D4 +#define B_P0_CFCH_BW0 GENMASK(27, 26) +#define R_P0_CFCH_BW1 0xC0D8 +#define B_P0_CFCH_BW1 GENMASK(8, 5) +#define R_ADDCK0 0xC0F4 +#define B_ADDCK0 GENMASK(9, 8) +#define B_ADDCK0_EN BIT(4) +#define B_ADDCK0_RST BIT(2) +#define R_ADDCK0_RL 0xC0F8 +#define B_ADDCK0_RLS GENMASK(29, 28) +#define B_ADDCK0_RL1 GENMASK(27, 18) +#define B_ADDCK0_RL0 GENMASK(17, 8) +#define R_ADDCKR0 0xC0FC +#define B_ADDCKR0_A0 GENMASK(19, 10) +#define B_ADDCKR0_A1 GENMASK(9, 0) +#define R_DACK10 0xC100 +#define B_DACK10 GENMASK(4, 1) +#define R_DACK1_K 0xc104 +#define B_DACK1_EN BIT(0) +#define R_DACK11 0xC120 +#define B_DACK11 GENMASK(4, 1) +#define R_DACK_S1P0 0xC140 +#define B_DACK_S1P0_OK BIT(31) +#define R_DACK_BIAS10 0xC148 +#define B_DACK_BIAS10 GENMASK(11, 2) +#define R_DACK10S 0xC15C +#define B_DACK10S GENMASK(31, 24) +#define R_DACK_S1P2 0xC15C +#define B_DACK_S1P2_OK BIT(2) +#define R_DACK_DADCK10 0xC160 +#define B_DACK_DADCK10 GENMASK(31, 24) +#define R_DACK_S1P1 0xC164 +#define B_DACK_S1P1_OK BIT(31) +#define R_DACK_BIAS11 0xC16C +#define B_DACK_BIAS11 GENMASK(11, 2) +#define R_DACK11S 0xC180 +#define B_DACK11S GENMASK(31, 24) +#define R_DACK_S1P3 0xC180 +#define B_DACK_S1P3_OK BIT(2) +#define R_DACK_DADCK11 0xC184 +#define B_DACK_DADCK11 GENMASK(31, 24) #define R_PATH1_SAMPL_DLY_T_V1 0xC1D4 #define B_PATH1_SAMPL_DLY_T_MSK_V1 GENMASK(27, 26) #define R_PATH0_BW_SEL_V1 0xC0D8 #define B_PATH0_BW_SEL_MSK_V1 GENMASK(8, 5) #define R_PATH1_BW_SEL_V1 0xC1D8 #define B_PATH1_BW_SEL_MSK_V1 GENMASK(8, 5) -#define R_P0_CFCH_BW0 0xC0D4 -#define B_P0_CFCH_BW0 GENMASK(27, 26) -#define R_P0_CFCH_BW1 0xC0D8 -#define B_P0_CFCH_BW1 GENMASK(8, 5) +#define R_ADDCK1 0xC1F4 +#define B_ADDCK1 GENMASK(9, 8) +#define B_ADDCK1_EN BIT(4) +#define B_ADDCK1_RST BIT(2) +#define R_ADDCK1_RL 0xC1F8 +#define B_ADDCK1_RLS GENMASK(29, 28) +#define B_ADDCK1_RL1 GENMASK(27, 18) +#define B_ADDCK1_RL0 GENMASK(17, 8) +#define R_ADDCKR1 0xC1fC +#define B_ADDCKR1_A0 GENMASK(19, 10) +#define B_ADDCKR1_A1 GENMASK(9, 0) /* WiFi CPU local domain */ #define R_AX_WDT_CTRL 0x0040 diff --git a/drivers/net/wireless/realtek/rtw89/rtw8852c.c b/drivers/net/wireless/realtek/rtw89/rtw8852c.c index 2755684682126..502627d8141d4 100644 --- a/drivers/net/wireless/realtek/rtw89/rtw8852c.c +++ b/drivers/net/wireless/realtek/rtw89/rtw8852c.c @@ -1771,6 +1771,8 @@ static void rtw8852c_rfk_init(struct rtw89_dev *rtwdev) struct rtw89_mcc_info *mcc_info = &rtwdev->mcc; memset(mcc_info, 0, sizeof(*mcc_info)); + + rtw8852c_dack(rtwdev); } static void rtw8852c_rfk_channel(struct rtw89_dev *rtwdev) diff --git a/drivers/net/wireless/realtek/rtw89/rtw8852c_rfk.c b/drivers/net/wireless/realtek/rtw89/rtw8852c_rfk.c index 56f0876c03fbd..4245a2c5f9d67 100644 --- a/drivers/net/wireless/realtek/rtw89/rtw8852c_rfk.c +++ b/drivers/net/wireless/realtek/rtw89/rtw8852c_rfk.c @@ -2,11 +2,13 @@ /* Copyright(c) 2019-2022 Realtek Corporation */ +#include "coex.h" #include "debug.h" #include "phy.h" #include "reg.h" #include "rtw8852c.h" #include "rtw8852c_rfk.h" +#include "rtw8852c_rfk_table.h" static u8 _kpath(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy_idx) { @@ -22,6 +24,441 @@ static u8 _kpath(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy_idx) return RF_B; } +static void _dack_dump(struct rtw89_dev *rtwdev) +{ + struct rtw89_dack_info *dack = &rtwdev->dack; + u8 i; + u8 t; + + rtw89_debug(rtwdev, RTW89_DBG_RFK, + "[DACK]S0 ADC_DCK ic = 0x%x, qc = 0x%x\n", + dack->addck_d[0][0], dack->addck_d[0][1]); + rtw89_debug(rtwdev, RTW89_DBG_RFK, + "[DACK]S1 ADC_DCK ic = 0x%x, qc = 0x%x\n", + dack->addck_d[1][0], dack->addck_d[1][1]); + rtw89_debug(rtwdev, RTW89_DBG_RFK, + "[DACK]S0 DAC_DCK ic = 0x%x, qc = 0x%x\n", + dack->dadck_d[0][0], dack->dadck_d[0][1]); + rtw89_debug(rtwdev, RTW89_DBG_RFK, + "[DACK]S1 DAC_DCK ic = 0x%x, qc = 0x%x\n", + dack->dadck_d[1][0], dack->dadck_d[1][1]); + + rtw89_debug(rtwdev, RTW89_DBG_RFK, + "[DACK]S0 biask ic = 0x%x, qc = 0x%x\n", + dack->biask_d[0][0], dack->biask_d[0][1]); + rtw89_debug(rtwdev, RTW89_DBG_RFK, + "[DACK]S1 biask ic = 0x%x, qc = 0x%x\n", + dack->biask_d[1][0], dack->biask_d[1][1]); + + rtw89_debug(rtwdev, RTW89_DBG_RFK, "[DACK]S0 MSBK ic:\n"); + for (i = 0; i < RTW89_DACK_MSBK_NR; i++) { + t = dack->msbk_d[0][0][i]; + rtw89_debug(rtwdev, RTW89_DBG_RFK, "[DACK]0x%x\n", t); + } + rtw89_debug(rtwdev, RTW89_DBG_RFK, "[DACK]S0 MSBK qc:\n"); + for (i = 0; i < RTW89_DACK_MSBK_NR; i++) { + t = dack->msbk_d[0][1][i]; + rtw89_debug(rtwdev, RTW89_DBG_RFK, "[DACK]0x%x\n", t); + } + rtw89_debug(rtwdev, RTW89_DBG_RFK, "[DACK]S1 MSBK ic:\n"); + for (i = 0; i < RTW89_DACK_MSBK_NR; i++) { + t = dack->msbk_d[1][0][i]; + rtw89_debug(rtwdev, RTW89_DBG_RFK, "[DACK]0x%x\n", t); + } + rtw89_debug(rtwdev, RTW89_DBG_RFK, "[DACK]S1 MSBK qc:\n"); + for (i = 0; i < RTW89_DACK_MSBK_NR; i++) { + t = dack->msbk_d[1][1][i]; + rtw89_debug(rtwdev, RTW89_DBG_RFK, "[DACK]0x%x\n", t); + } +} + +static void _addck_backup(struct rtw89_dev *rtwdev) +{ + struct rtw89_dack_info *dack = &rtwdev->dack; + + rtw89_phy_write32_mask(rtwdev, R_ADDCK0, B_ADDCK0, 0x0); + dack->addck_d[0][0] = rtw89_phy_read32_mask(rtwdev, R_ADDCKR0, + B_ADDCKR0_A0); + dack->addck_d[0][1] = rtw89_phy_read32_mask(rtwdev, R_ADDCKR0, + B_ADDCKR0_A1); + + rtw89_phy_write32_mask(rtwdev, R_ADDCK1, B_ADDCK1, 0x0); + dack->addck_d[1][0] = rtw89_phy_read32_mask(rtwdev, R_ADDCKR1, + B_ADDCKR1_A0); + dack->addck_d[1][1] = rtw89_phy_read32_mask(rtwdev, R_ADDCKR1, + B_ADDCKR1_A1); +} + +static void _addck_reload(struct rtw89_dev *rtwdev) +{ + struct rtw89_dack_info *dack = &rtwdev->dack; + + rtw89_phy_write32_mask(rtwdev, R_ADDCK0_RL, B_ADDCK0_RL1, + dack->addck_d[0][0]); + rtw89_phy_write32_mask(rtwdev, R_ADDCK0_RL, B_ADDCK0_RL0, + dack->addck_d[0][1]); + rtw89_phy_write32_mask(rtwdev, R_ADDCK0_RL, B_ADDCK0_RLS, 0x3); + rtw89_phy_write32_mask(rtwdev, R_ADDCK1_RL, B_ADDCK1_RL1, + dack->addck_d[1][0]); + rtw89_phy_write32_mask(rtwdev, R_ADDCK1_RL, B_ADDCK1_RL0, + dack->addck_d[1][1]); + rtw89_phy_write32_mask(rtwdev, R_ADDCK1_RL, B_ADDCK1_RLS, 0x3); +} + +static void _dack_backup_s0(struct rtw89_dev *rtwdev) +{ + struct rtw89_dack_info *dack = &rtwdev->dack; + u8 i; + + rtw89_phy_write32_mask(rtwdev, R_P0_NRBW, B_P0_NRBW_DBG, 0x1); + for (i = 0; i < RTW89_DACK_MSBK_NR; i++) { + rtw89_phy_write32_mask(rtwdev, R_DCOF0, B_DCOF0_V, i); + dack->msbk_d[0][0][i] = rtw89_phy_read32_mask(rtwdev, + R_DACK_S0P2, + B_DACK_S0M0); + rtw89_phy_write32_mask(rtwdev, R_DCOF8, B_DCOF8_V, i); + dack->msbk_d[0][1][i] = rtw89_phy_read32_mask(rtwdev, + R_DACK_S0P3, + B_DACK_S0M1); + } + dack->biask_d[0][0] = rtw89_phy_read32_mask(rtwdev, R_DACK_BIAS00, + B_DACK_BIAS00); + dack->biask_d[0][1] = rtw89_phy_read32_mask(rtwdev, R_DACK_BIAS01, + B_DACK_BIAS01); + dack->dadck_d[0][0] = rtw89_phy_read32_mask(rtwdev, R_DACK_DADCK00, + B_DACK_DADCK00); + dack->dadck_d[0][1] = rtw89_phy_read32_mask(rtwdev, R_DACK_DADCK01, + B_DACK_DADCK01); +} + +static void _dack_backup_s1(struct rtw89_dev *rtwdev) +{ + struct rtw89_dack_info *dack = &rtwdev->dack; + u8 i; + + rtw89_phy_write32_mask(rtwdev, R_P1_DBGMOD, B_P1_DBGMOD_ON, 0x1); + for (i = 0; i < RTW89_DACK_MSBK_NR; i++) { + rtw89_phy_write32_mask(rtwdev, R_DACK10, B_DACK10, i); + dack->msbk_d[1][0][i] = rtw89_phy_read32_mask(rtwdev, + R_DACK10S, + B_DACK10S); + rtw89_phy_write32_mask(rtwdev, R_DACK11, B_DACK11, i); + dack->msbk_d[1][1][i] = rtw89_phy_read32_mask(rtwdev, + R_DACK11S, + B_DACK11S); + } + dack->biask_d[1][0] = rtw89_phy_read32_mask(rtwdev, R_DACK_BIAS10, + B_DACK_BIAS10); + dack->biask_d[1][1] = rtw89_phy_read32_mask(rtwdev, R_DACK_BIAS11, + B_DACK_BIAS11); + dack->dadck_d[1][0] = rtw89_phy_read32_mask(rtwdev, R_DACK_DADCK10, + B_DACK_DADCK10); + dack->dadck_d[1][1] = rtw89_phy_read32_mask(rtwdev, R_DACK_DADCK11, + B_DACK_DADCK11); +} + +static void _dack_reload_by_path(struct rtw89_dev *rtwdev, + enum rtw89_rf_path path, u8 index) +{ + struct rtw89_dack_info *dack = &rtwdev->dack; + u32 idx_offset, path_offset; + u32 val32, offset, addr; + u8 i; + + idx_offset = (index == 0 ? 0 : 0x14); + path_offset = (path == RF_PATH_A ? 0 : 0x28); + offset = idx_offset + path_offset; + + rtw89_rfk_parser(rtwdev, &rtw8852c_dack_reload_defs_tbl); + + /* msbk_d: 15/14/13/12 */ + val32 = 0x0; + for (i = 0; i < RTW89_DACK_MSBK_NR / 4; i++) + val32 |= dack->msbk_d[path][index][i + 12] << (i * 8); + addr = 0xc200 + offset; + rtw89_phy_write32(rtwdev, addr, val32); + rtw89_debug(rtwdev, RTW89_DBG_RFK, "[DACK]0x%x=0x%x\n", addr, + rtw89_phy_read32_mask(rtwdev, addr, MASKDWORD)); + + /* msbk_d: 11/10/9/8 */ + val32 = 0x0; + for (i = 0; i < RTW89_DACK_MSBK_NR / 4; i++) + val32 |= dack->msbk_d[path][index][i + 8] << (i * 8); + addr = 0xc204 + offset; + rtw89_phy_write32(rtwdev, addr, val32); + rtw89_debug(rtwdev, RTW89_DBG_RFK, "[DACK]0x%x=0x%x\n", addr, + rtw89_phy_read32_mask(rtwdev, addr, MASKDWORD)); + + /* msbk_d: 7/6/5/4 */ + val32 = 0x0; + for (i = 0; i < RTW89_DACK_MSBK_NR / 4; i++) + val32 |= dack->msbk_d[path][index][i + 4] << (i * 8); + addr = 0xc208 + offset; + rtw89_phy_write32(rtwdev, addr, val32); + rtw89_debug(rtwdev, RTW89_DBG_RFK, "[DACK]0x%x=0x%x\n", addr, + rtw89_phy_read32_mask(rtwdev, addr, MASKDWORD)); + + /* msbk_d: 3/2/1/0 */ + val32 = 0x0; + for (i = 0; i < RTW89_DACK_MSBK_NR / 4; i++) + val32 |= dack->msbk_d[path][index][i] << (i * 8); + addr = 0xc20c + offset; + rtw89_phy_write32(rtwdev, addr, val32); + rtw89_debug(rtwdev, RTW89_DBG_RFK, "[DACK]0x%x=0x%x\n", addr, + rtw89_phy_read32_mask(rtwdev, addr, MASKDWORD)); + + /* dadak_d/biask_d */ + val32 = (dack->biask_d[path][index] << 22) | + (dack->dadck_d[path][index] << 14); + addr = 0xc210 + offset; + rtw89_phy_write32(rtwdev, addr, val32); + rtw89_phy_write32_set(rtwdev, addr, BIT(1)); +} + +static void _dack_reload(struct rtw89_dev *rtwdev, enum rtw89_rf_path path) +{ + u8 i; + + for (i = 0; i < 2; i++) + _dack_reload_by_path(rtwdev, path, i); +} + +static void _addck(struct rtw89_dev *rtwdev) +{ + struct rtw89_dack_info *dack = &rtwdev->dack; + u32 val; + int ret; + + /* S0 */ + rtw89_phy_write32_mask(rtwdev, R_ADDCK0, B_ADDCK0_RST, 0x1); + rtw89_phy_write32_mask(rtwdev, R_ADDCK0, B_ADDCK0_EN, 0x1); + rtw89_phy_write32_mask(rtwdev, R_ADDCK0, B_ADDCK0_EN, 0x0); + fsleep(1); + rtw89_phy_write32_mask(rtwdev, R_ADDCK0, B_ADDCK0, 0x1); + + ret = read_poll_timeout_atomic(rtw89_phy_read32_mask, val, val, + 1, 10000, false, rtwdev, 0xc0fc, BIT(0)); + if (ret) { + rtw89_debug(rtwdev, RTW89_DBG_RFK, "[DACK]S0 ADDCK timeout\n"); + dack->addck_timeout[0] = true; + } + + rtw89_phy_write32_mask(rtwdev, R_ADDCK0, B_ADDCK0_RST, 0x0); + + /* S1 */ + rtw89_phy_write32_mask(rtwdev, R_ADDCK1, B_ADDCK1_RST, 0x1); + rtw89_phy_write32_mask(rtwdev, R_ADDCK1, B_ADDCK1_EN, 0x1); + rtw89_phy_write32_mask(rtwdev, R_ADDCK1, B_ADDCK1_EN, 0x0); + udelay(1); + rtw89_phy_write32_mask(rtwdev, R_ADDCK1, B_ADDCK1, 0x1); + + ret = read_poll_timeout_atomic(rtw89_phy_read32_mask, val, val, + 1, 10000, false, rtwdev, 0xc1fc, BIT(0)); + if (ret) { + rtw89_debug(rtwdev, RTW89_DBG_RFK, "[DACK]S1 ADDCK timeout\n"); + dack->addck_timeout[0] = true; + } + rtw89_phy_write32_mask(rtwdev, R_ADDCK1, B_ADDCK1_RST, 0x0); +} + +static void _dack_reset(struct rtw89_dev *rtwdev, u8 path) +{ + rtw89_rfk_parser_by_cond(rtwdev, path == RF_PATH_A, + &rtw8852c_dack_reset_defs_a_tbl, + &rtw8852c_dack_reset_defs_b_tbl); +} + +enum adc_ck { + ADC_NA = 0, + ADC_480M = 1, + ADC_960M = 2, + ADC_1920M = 3, +}; + +enum dac_ck { + DAC_40M = 0, + DAC_80M = 1, + DAC_120M = 2, + DAC_160M = 3, + DAC_240M = 4, + DAC_320M = 5, + DAC_480M = 6, + DAC_960M = 7, +}; + +enum rf_mode { + RF_SHUT_DOWN = 0x0, + RF_STANDBY = 0x1, + RF_TX = 0x2, + RF_RX = 0x3, + RF_TXIQK = 0x4, + RF_DPK = 0x5, + RF_RXK1 = 0x6, + RF_RXK2 = 0x7, +}; + +static void rtw8852c_txck_force(struct rtw89_dev *rtwdev, u8 path, bool force, + enum dac_ck ck) +{ + rtw89_phy_write32_mask(rtwdev, R_P0_RXCK | (path << 13), B_P0_TXCK_ON, 0x0); + + if (!force) + return; + + rtw89_phy_write32_mask(rtwdev, R_P0_RXCK | (path << 13), B_P0_TXCK_VAL, ck); + rtw89_phy_write32_mask(rtwdev, R_P0_RXCK | (path << 13), B_P0_TXCK_ON, 0x1); +} + +static void rtw8852c_rxck_force(struct rtw89_dev *rtwdev, u8 path, bool force, + enum adc_ck ck) +{ + rtw89_phy_write32_mask(rtwdev, R_P0_RXCK | (path << 13), B_P0_RXCK_ON, 0x0); + + if (!force) + return; + + rtw89_phy_write32_mask(rtwdev, R_P0_RXCK | (path << 13), B_P0_RXCK_VAL, ck); + rtw89_phy_write32_mask(rtwdev, R_P0_RXCK | (path << 13), B_P0_RXCK_ON, 0x1); +} + +static bool _check_dack_done(struct rtw89_dev *rtwdev, bool s0) +{ + if (s0) { + if (rtw89_phy_read32_mask(rtwdev, R_DACK_S0P0, B_DACK_S0P0_OK) == 0 || + rtw89_phy_read32_mask(rtwdev, R_DACK_S0P1, B_DACK_S0P1_OK) == 0 || + rtw89_phy_read32_mask(rtwdev, R_DACK_S0P2, B_DACK_S0P2_OK) == 0 || + rtw89_phy_read32_mask(rtwdev, R_DACK_S0P3, B_DACK_S0P3_OK) == 0) + return false; + } else { + if (rtw89_phy_read32_mask(rtwdev, R_DACK_S1P0, B_DACK_S1P0_OK) == 0 || + rtw89_phy_read32_mask(rtwdev, R_DACK_S1P1, B_DACK_S1P1_OK) == 0 || + rtw89_phy_read32_mask(rtwdev, R_DACK_S1P2, B_DACK_S1P2_OK) == 0 || + rtw89_phy_read32_mask(rtwdev, R_DACK_S1P3, B_DACK_S1P3_OK) == 0) + return false; + } + + return true; +} + +static void _dack_s0(struct rtw89_dev *rtwdev) +{ + struct rtw89_dack_info *dack = &rtwdev->dack; + bool done; + int ret; + + rtw8852c_txck_force(rtwdev, RF_PATH_A, true, DAC_160M); + rtw89_rfk_parser(rtwdev, &rtw8852c_dack_defs_s0_tbl); + + _dack_reset(rtwdev, RF_PATH_A); + + rtw89_phy_write32_mask(rtwdev, R_DCOF1, B_DCOF1_S, 0x1); + ret = read_poll_timeout_atomic(_check_dack_done, done, done, + 1, 10000, false, rtwdev, true); + if (ret) { + rtw89_debug(rtwdev, RTW89_DBG_RFK, "[DACK]S0 DACK timeout\n"); + dack->msbk_timeout[0] = true; + } + rtw89_phy_write32_mask(rtwdev, R_DCOF1, B_DCOF1_S, 0x0); + rtw8852c_txck_force(rtwdev, RF_PATH_A, false, DAC_960M); + rtw89_debug(rtwdev, RTW89_DBG_RFK, "[DACK]after S0 DADCK\n"); + + _dack_backup_s0(rtwdev); + _dack_reload(rtwdev, RF_PATH_A); + rtw89_phy_write32_mask(rtwdev, R_P0_NRBW, B_P0_NRBW_DBG, 0x0); +} + +static void _dack_s1(struct rtw89_dev *rtwdev) +{ + struct rtw89_dack_info *dack = &rtwdev->dack; + bool done; + int ret; + + rtw8852c_txck_force(rtwdev, RF_PATH_B, true, DAC_160M); + rtw89_rfk_parser(rtwdev, &rtw8852c_dack_defs_s1_tbl); + + _dack_reset(rtwdev, RF_PATH_B); + + rtw89_phy_write32_mask(rtwdev, R_DACK1_K, B_DACK1_EN, 0x1); + ret = read_poll_timeout_atomic(_check_dack_done, done, done, + 1, 10000, false, rtwdev, false); + if (ret) { + rtw89_debug(rtwdev, RTW89_DBG_RFK, "[DACK]S1 DACK timeout\n"); + dack->msbk_timeout[0] = true; + } + rtw89_phy_write32_mask(rtwdev, R_DACK1_K, B_DACK1_EN, 0x0); + rtw8852c_txck_force(rtwdev, RF_PATH_B, false, DAC_960M); + rtw89_debug(rtwdev, RTW89_DBG_RFK, "[DACK]after S1 DADCK\n"); + + _dack_backup_s1(rtwdev); + _dack_reload(rtwdev, RF_PATH_B); + rtw89_phy_write32_mask(rtwdev, R_P1_DBGMOD, B_P1_DBGMOD_ON, 0x0); +} + +static void _dack(struct rtw89_dev *rtwdev) +{ + _dack_s0(rtwdev); + _dack_s1(rtwdev); +} + +static void _drck(struct rtw89_dev *rtwdev) +{ + u32 val; + int ret; + + rtw89_phy_write32_mask(rtwdev, R_DRCK, B_DRCK_EN, 0x1); + ret = read_poll_timeout_atomic(rtw89_phy_read32_mask, val, val, + 1, 10000, false, rtwdev, 0xc0c8, BIT(3)); + if (ret) + rtw89_debug(rtwdev, RTW89_DBG_RFK, "[DACK]DRCK timeout\n"); + + rtw89_rfk_parser(rtwdev, &rtw8852c_drck_defs_tbl); + + val = rtw89_phy_read32_mask(rtwdev, R_DRCK_RES, B_DRCK_RES); + rtw89_phy_write32_mask(rtwdev, R_DRCK, B_DRCK_IDLE, 0x0); + rtw89_phy_write32_mask(rtwdev, R_DRCK, B_DRCK_VAL, val); + rtw89_debug(rtwdev, RTW89_DBG_RFK, "[DACK]0xc0c4 = 0x%x\n", + rtw89_phy_read32_mask(rtwdev, R_DRCK, MASKDWORD)); +} + +static void _dac_cal(struct rtw89_dev *rtwdev, bool force) +{ + struct rtw89_dack_info *dack = &rtwdev->dack; + u32 rf0_0, rf1_0; + u8 phy_map = rtw89_btc_phymap(rtwdev, RTW89_PHY_0, RF_AB); + + dack->dack_done = false; + rtw89_debug(rtwdev, RTW89_DBG_RFK, "[DACK]DACK b\n"); + rtw89_debug(rtwdev, RTW89_DBG_RFK, "[DACK]DACK start!!!\n"); + rf0_0 = rtw89_read_rf(rtwdev, RF_PATH_A, RR_MOD, RFREG_MASK); + rf1_0 = rtw89_read_rf(rtwdev, RF_PATH_B, RR_MOD, RFREG_MASK); + _drck(rtwdev); + + rtw89_write_rf(rtwdev, RF_PATH_A, RR_RSV1, RR_RSV1_RST, 0x0); + rtw89_write_rf(rtwdev, RF_PATH_B, RR_RSV1, RR_RSV1_RST, 0x0); + rtw89_write_rf(rtwdev, RF_PATH_A, RR_MOD, RFREG_MASK, 0x337e1); + rtw89_write_rf(rtwdev, RF_PATH_B, RR_MOD, RFREG_MASK, 0x337e1); + rtw89_btc_ntfy_wl_rfk(rtwdev, phy_map, BTC_WRFKT_DACK, BTC_WRFK_ONESHOT_START); + _addck(rtwdev); + rtw89_btc_ntfy_wl_rfk(rtwdev, phy_map, BTC_WRFKT_DACK, BTC_WRFK_ONESHOT_STOP); + + _addck_backup(rtwdev); + _addck_reload(rtwdev); + rtw89_write_rf(rtwdev, RF_PATH_A, RR_MODOPT, RFREG_MASK, 0x0); + rtw89_write_rf(rtwdev, RF_PATH_B, RR_MODOPT, RFREG_MASK, 0x0); + rtw89_btc_ntfy_wl_rfk(rtwdev, phy_map, BTC_WRFKT_DACK, BTC_WRFK_ONESHOT_START); + _dack(rtwdev); + rtw89_btc_ntfy_wl_rfk(rtwdev, phy_map, BTC_WRFKT_DACK, BTC_WRFK_ONESHOT_STOP); + + _dack_dump(rtwdev); + dack->dack_done = true; + rtw89_write_rf(rtwdev, RF_PATH_A, RR_MOD, RFREG_MASK, rf0_0); + rtw89_write_rf(rtwdev, RF_PATH_B, RR_MOD, RFREG_MASK, rf1_0); + rtw89_write_rf(rtwdev, RF_PATH_A, RR_RSV1, RR_RSV1_RST, 0x1); + rtw89_write_rf(rtwdev, RF_PATH_B, RR_RSV1, RR_RSV1_RST, 0x1); + dack->dack_cnt++; + rtw89_debug(rtwdev, RTW89_DBG_RFK, "[DACK]DACK finish!!!\n"); +} + static void _bw_setting(struct rtw89_dev *rtwdev, enum rtw89_rf_path path, enum rtw89_bandwidth bw, bool is_dav) { @@ -212,3 +649,12 @@ void rtw8852c_set_channel_rf(struct rtw89_dev *rtwdev, rtw8852c_ctrl_bw_ch(rtwdev, phy_idx, param->center_chan, param->band_type, param->bandwidth); } + +void rtw8852c_dack(struct rtw89_dev *rtwdev) +{ + u8 phy_map = rtw89_btc_phymap(rtwdev, RTW89_PHY_0, 0); + + rtw89_btc_ntfy_wl_rfk(rtwdev, phy_map, BTC_WRFKT_DACK, BTC_WRFK_START); + _dac_cal(rtwdev, false); + rtw89_btc_ntfy_wl_rfk(rtwdev, phy_map, BTC_WRFKT_DACK, BTC_WRFK_STOP); +} diff --git a/drivers/net/wireless/realtek/rtw89/rtw8852c_rfk.h b/drivers/net/wireless/realtek/rtw89/rtw8852c_rfk.h index 0e75555c1612d..7323183e74d41 100644 --- a/drivers/net/wireless/realtek/rtw89/rtw8852c_rfk.h +++ b/drivers/net/wireless/realtek/rtw89/rtw8852c_rfk.h @@ -7,6 +7,7 @@ #include "core.h" +void rtw8852c_dack(struct rtw89_dev *rtwdev); void rtw8852c_set_channel_rf(struct rtw89_dev *rtwdev, struct rtw89_channel_params *param, enum rtw89_phy_idx phy_idx); From fb8177d729f2c1f772128441adc80962d7e6ee85 Mon Sep 17 00:00:00 2001 From: Ping-Ke Shih Date: Tue, 3 May 2022 07:54:03 +0800 Subject: [PATCH 223/228] rtw89: 8852c: rfk: add LCK LCK is short fro LC Tank calibration. Do this calibration once driver loads RF parameters table. Since the characteristic can be changed by temperature, we do this calibration again if difference of thermal value is over a threshold. Signed-off-by: Ping-Ke Shih Signed-off-by: Kalle Valo Link: https://lore.kernel.org/r/20220502235408.15052-4-pkshih@realtek.com --- drivers/net/wireless/realtek/rtw89/core.h | 5 ++ drivers/net/wireless/realtek/rtw89/reg.h | 2 + drivers/net/wireless/realtek/rtw89/rtw8852c.c | 7 +++ .../net/wireless/realtek/rtw89/rtw8852c_rfk.c | 63 +++++++++++++++++++ .../net/wireless/realtek/rtw89/rtw8852c_rfk.h | 2 + 5 files changed, 79 insertions(+) diff --git a/drivers/net/wireless/realtek/rtw89/core.h b/drivers/net/wireless/realtek/rtw89/core.h index d544cf29e588a..41d23711dc354 100644 --- a/drivers/net/wireless/realtek/rtw89/core.h +++ b/drivers/net/wireless/realtek/rtw89/core.h @@ -2642,6 +2642,10 @@ struct rtw89_mcc_info { u8 table_idx; }; +struct rtw89_lck_info { + u8 thermal[RF_PATH_MAX]; +}; + struct rtw89_iqk_info { bool lok_cor_fail[RTW89_IQK_CHS_NR][RTW89_IQK_PATH_NR]; bool lok_fin_fail[RTW89_IQK_CHS_NR][RTW89_IQK_PATH_NR]; @@ -3114,6 +3118,7 @@ struct rtw89_dev { struct rtw89_iqk_info iqk; struct rtw89_dpk_info dpk; struct rtw89_mcc_info mcc; + struct rtw89_lck_info lck; bool is_tssi_mode[RF_PATH_MAX]; bool is_bt_iqk_timeout; diff --git a/drivers/net/wireless/realtek/rtw89/reg.h b/drivers/net/wireless/realtek/rtw89/reg.h index ce472d3b1a665..028c881308237 100644 --- a/drivers/net/wireless/realtek/rtw89/reg.h +++ b/drivers/net/wireless/realtek/rtw89/reg.h @@ -3327,6 +3327,8 @@ #define RR_MIXER_GN GENMASK(4, 3) #define RR_XTALX2 0xb8 #define RR_MALSEL 0xbe +#define RR_LCK_TRG 0xd3 +#define RR_LCK_TRGSEL BIT(8) #define RR_RCKD 0xde #define RR_RCKD_POW GENMASK(19, 13) #define RR_RCKD_BW BIT(2) diff --git a/drivers/net/wireless/realtek/rtw89/rtw8852c.c b/drivers/net/wireless/realtek/rtw89/rtw8852c.c index 502627d8141d4..14302ebed3d5e 100644 --- a/drivers/net/wireless/realtek/rtw89/rtw8852c.c +++ b/drivers/net/wireless/realtek/rtw89/rtw8852c.c @@ -1771,6 +1771,7 @@ static void rtw8852c_rfk_init(struct rtw89_dev *rtwdev) struct rtw89_mcc_info *mcc_info = &rtwdev->mcc; memset(mcc_info, 0, sizeof(*mcc_info)); + rtw8852c_lck_init(rtwdev); rtw8852c_dack(rtwdev); } @@ -1780,6 +1781,11 @@ static void rtw8852c_rfk_channel(struct rtw89_dev *rtwdev) rtw89_fw_h2c_rf_ntfy_mcc(rtwdev); } +static void rtw8852c_rfk_track(struct rtw89_dev *rtwdev) +{ + rtw8852c_lck_track(rtwdev); +} + static u32 rtw8852c_bb_cal_txpwr_ref(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy_idx, s16 ref) { @@ -2708,6 +2714,7 @@ static const struct rtw89_chip_ops rtw8852c_chip_ops = { .read_phycap = rtw8852c_read_phycap, .rfk_init = rtw8852c_rfk_init, .rfk_channel = rtw8852c_rfk_channel, + .rfk_track = rtw8852c_rfk_track, .power_trim = rtw8852c_power_trim, .set_txpwr = rtw8852c_set_txpwr, .set_txpwr_ctrl = rtw8852c_set_txpwr_ctrl, diff --git a/drivers/net/wireless/realtek/rtw89/rtw8852c_rfk.c b/drivers/net/wireless/realtek/rtw89/rtw8852c_rfk.c index 4245a2c5f9d67..ce08b2dcf5459 100644 --- a/drivers/net/wireless/realtek/rtw89/rtw8852c_rfk.c +++ b/drivers/net/wireless/realtek/rtw89/rtw8852c_rfk.c @@ -632,6 +632,69 @@ static void _rxbb_bw(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy, } } +static void _lck_keep_thermal(struct rtw89_dev *rtwdev) +{ + struct rtw89_lck_info *lck = &rtwdev->lck; + int path; + + for (path = 0; path < rtwdev->chip->rf_path_num; path++) { + lck->thermal[path] = + ewma_thermal_read(&rtwdev->phystat.avg_thermal[path]); + rtw89_debug(rtwdev, RTW89_DBG_RFK_TRACK, + "[LCK] path=%d thermal=0x%x", path, lck->thermal[path]); + } +} + +static void _lck(struct rtw89_dev *rtwdev) +{ + u32 tmp18[2]; + int path = rtwdev->dbcc_en ? 2 : 1; + int i; + + rtw89_debug(rtwdev, RTW89_DBG_RFK_TRACK, "[LCK] DO LCK\n"); + + tmp18[0] = rtw89_read_rf(rtwdev, RF_PATH_A, RR_CFGCH, RFREG_MASK); + tmp18[1] = rtw89_read_rf(rtwdev, RF_PATH_B, RR_CFGCH, RFREG_MASK); + + for (i = 0; i < path; i++) { + rtw89_write_rf(rtwdev, i, RR_LCK_TRG, RR_LCK_TRGSEL, 0x1); + rtw89_write_rf(rtwdev, i, RR_CFGCH, RFREG_MASK, tmp18[i]); + rtw89_write_rf(rtwdev, i, RR_LCK_TRG, RR_LCK_TRGSEL, 0x0); + } + + _lck_keep_thermal(rtwdev); +} + +#define RTW8852C_LCK_TH 8 + +void rtw8852c_lck_track(struct rtw89_dev *rtwdev) +{ + struct rtw89_lck_info *lck = &rtwdev->lck; + u8 cur_thermal; + int delta; + int path; + + for (path = 0; path < rtwdev->chip->rf_path_num; path++) { + cur_thermal = + ewma_thermal_read(&rtwdev->phystat.avg_thermal[path]); + delta = abs((int)cur_thermal - lck->thermal[path]); + + rtw89_debug(rtwdev, RTW89_DBG_RFK_TRACK, + "[LCK] path=%d current thermal=0x%x delta=0x%x\n", + path, cur_thermal, delta); + + if (delta >= RTW8852C_LCK_TH) { + _lck(rtwdev); + return; + } + } +} + +void rtw8852c_lck_init(struct rtw89_dev *rtwdev) +{ + _lck_keep_thermal(rtwdev); +} + static void rtw8852c_ctrl_bw_ch(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy, u8 central_ch, enum rtw89_band band, diff --git a/drivers/net/wireless/realtek/rtw89/rtw8852c_rfk.h b/drivers/net/wireless/realtek/rtw89/rtw8852c_rfk.h index 7323183e74d41..4ce76ef4c5e60 100644 --- a/drivers/net/wireless/realtek/rtw89/rtw8852c_rfk.h +++ b/drivers/net/wireless/realtek/rtw89/rtw8852c_rfk.h @@ -11,5 +11,7 @@ void rtw8852c_dack(struct rtw89_dev *rtwdev); void rtw8852c_set_channel_rf(struct rtw89_dev *rtwdev, struct rtw89_channel_params *param, enum rtw89_phy_idx phy_idx); +void rtw8852c_lck_init(struct rtw89_dev *rtwdev); +void rtw8852c_lck_track(struct rtw89_dev *rtwdev); #endif From e5efc4d55c20beea57683b3c94f0e1c4e254c9c9 Mon Sep 17 00:00:00 2001 From: Ping-Ke Shih Date: Tue, 3 May 2022 07:54:04 +0800 Subject: [PATCH 224/228] rtw89: 8852c: rfk: add TSSI TSSI is transmitter signal strength indication, which is a close-loop hardware circuit to feedback actual transmitting power as a reference for next transmission. When we setup channel to connect an AP, it does full calibration. When switching bands or channels, it needs to reset hardware status to prevent use wrong feedback of previous transmission. To do TX power compensation reflecting current temperature, it loads tables of compensation values into registers according to channel and band group. Signed-off-by: Ping-Ke Shih Signed-off-by: Kalle Valo Link: https://lore.kernel.org/r/20220502235408.15052-5-pkshih@realtek.com --- drivers/net/wireless/realtek/rtw89/rtw8852c.c | 19 + .../net/wireless/realtek/rtw89/rtw8852c_rfk.c | 1033 +++++++++++++++++ .../net/wireless/realtek/rtw89/rtw8852c_rfk.h | 5 + 3 files changed, 1057 insertions(+) diff --git a/drivers/net/wireless/realtek/rtw89/rtw8852c.c b/drivers/net/wireless/realtek/rtw89/rtw8852c.c index 14302ebed3d5e..36406488e60e4 100644 --- a/drivers/net/wireless/realtek/rtw89/rtw8852c.c +++ b/drivers/net/wireless/realtek/rtw89/rtw8852c.c @@ -1754,6 +1754,7 @@ static void rtw8852c_set_channel_help(struct rtw89_dev *rtwdev, bool enter, rtw89_chip_stop_sch_tx(rtwdev, RTW89_MAC_0, &p->tx_en, RTW89_SCH_TX_SEL_ALL); rtw89_mac_cfg_ppdu_status(rtwdev, RTW89_MAC_0, false); rtw8852c_dfs_en(rtwdev, false); + rtw8852c_tssi_cont_en_phyidx(rtwdev, false, RTW89_PHY_0); rtw8852c_adc_en(rtwdev, false); fsleep(40); rtw8852c_bb_reset_en(rtwdev, phy_idx, false); @@ -1761,6 +1762,7 @@ static void rtw8852c_set_channel_help(struct rtw89_dev *rtwdev, bool enter, rtw89_mac_cfg_ppdu_status(rtwdev, RTW89_MAC_0, true); rtw8852c_adc_en(rtwdev, true); rtw8852c_dfs_en(rtwdev, true); + rtw8852c_tssi_cont_en_phyidx(rtwdev, true, RTW89_PHY_0); rtw8852c_bb_reset_en(rtwdev, phy_idx, true); rtw89_chip_resume_sch_tx(rtwdev, RTW89_MAC_0, p->tx_en); } @@ -1770,6 +1772,8 @@ static void rtw8852c_rfk_init(struct rtw89_dev *rtwdev) { struct rtw89_mcc_info *mcc_info = &rtwdev->mcc; + rtwdev->is_tssi_mode[RF_PATH_A] = false; + rtwdev->is_tssi_mode[RF_PATH_B] = false; memset(mcc_info, 0, sizeof(*mcc_info)); rtw8852c_lck_init(rtwdev); @@ -1778,9 +1782,22 @@ static void rtw8852c_rfk_init(struct rtw89_dev *rtwdev) static void rtw8852c_rfk_channel(struct rtw89_dev *rtwdev) { + enum rtw89_phy_idx phy_idx = RTW89_PHY_0; + + rtw8852c_tssi(rtwdev, phy_idx); rtw89_fw_h2c_rf_ntfy_mcc(rtwdev); } +static void rtw8852c_rfk_band_changed(struct rtw89_dev *rtwdev) +{ + rtw8852c_tssi_scan(rtwdev, RTW89_PHY_0); +} + +static void rtw8852c_rfk_scan(struct rtw89_dev *rtwdev, bool start) +{ + rtw8852c_wifi_scan_notify(rtwdev, start, RTW89_PHY_0); +} + static void rtw8852c_rfk_track(struct rtw89_dev *rtwdev) { rtw8852c_lck_track(rtwdev); @@ -2714,6 +2731,8 @@ static const struct rtw89_chip_ops rtw8852c_chip_ops = { .read_phycap = rtw8852c_read_phycap, .rfk_init = rtw8852c_rfk_init, .rfk_channel = rtw8852c_rfk_channel, + .rfk_band_changed = rtw8852c_rfk_band_changed, + .rfk_scan = rtw8852c_rfk_scan, .rfk_track = rtw8852c_rfk_track, .power_trim = rtw8852c_power_trim, .set_txpwr = rtw8852c_set_txpwr, diff --git a/drivers/net/wireless/realtek/rtw89/rtw8852c_rfk.c b/drivers/net/wireless/realtek/rtw89/rtw8852c_rfk.c index ce08b2dcf5459..974bb5794ad9f 100644 --- a/drivers/net/wireless/realtek/rtw89/rtw8852c_rfk.c +++ b/drivers/net/wireless/realtek/rtw89/rtw8852c_rfk.c @@ -9,6 +9,17 @@ #include "rtw8852c.h" #include "rtw8852c_rfk.h" #include "rtw8852c_rfk_table.h" +#include "rtw8852c_table.h" + +#define _TSSI_DE_MASK GENMASK(21, 12) +static const u32 _tssi_de_cck_long[RF_PATH_NUM_8852C] = {0x5858, 0x7858}; +static const u32 _tssi_de_cck_short[RF_PATH_NUM_8852C] = {0x5860, 0x7860}; +static const u32 _tssi_de_mcs_20m[RF_PATH_NUM_8852C] = {0x5838, 0x7838}; +static const u32 _tssi_de_mcs_40m[RF_PATH_NUM_8852C] = {0x5840, 0x7840}; +static const u32 _tssi_de_mcs_80m[RF_PATH_NUM_8852C] = {0x5848, 0x7848}; +static const u32 _tssi_de_mcs_80m_80m[RF_PATH_NUM_8852C] = {0x5850, 0x7850}; +static const u32 _tssi_de_mcs_5m[RF_PATH_NUM_8852C] = {0x5828, 0x7828}; +static const u32 _tssi_de_mcs_10m[RF_PATH_NUM_8852C] = {0x5830, 0x7830}; static u8 _kpath(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy_idx) { @@ -459,6 +470,901 @@ static void _dac_cal(struct rtw89_dev *rtwdev, bool force) rtw89_debug(rtwdev, RTW89_DBG_RFK, "[DACK]DACK finish!!!\n"); } +static void _tssi_set_sys(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy, + enum rtw89_rf_path path) +{ + enum rtw89_band band = rtwdev->hal.current_band_type; + + rtw89_rfk_parser(rtwdev, &rtw8852c_tssi_sys_defs_tbl); + + if (path == RF_PATH_A) + rtw89_rfk_parser_by_cond(rtwdev, band == RTW89_BAND_2G, + &rtw8852c_tssi_sys_defs_2g_a_tbl, + &rtw8852c_tssi_sys_defs_5g_a_tbl); + else + rtw89_rfk_parser_by_cond(rtwdev, band == RTW89_BAND_2G, + &rtw8852c_tssi_sys_defs_2g_b_tbl, + &rtw8852c_tssi_sys_defs_5g_b_tbl); +} + +static void _tssi_ini_txpwr_ctrl_bb(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy, + enum rtw89_rf_path path) +{ + rtw89_rfk_parser_by_cond(rtwdev, path == RF_PATH_A, + &rtw8852c_tssi_txpwr_ctrl_bb_defs_a_tbl, + &rtw8852c_tssi_txpwr_ctrl_bb_defs_b_tbl); +} + +static void _tssi_ini_txpwr_ctrl_bb_he_tb(struct rtw89_dev *rtwdev, + enum rtw89_phy_idx phy, + enum rtw89_rf_path path) +{ + rtw89_rfk_parser_by_cond(rtwdev, path == RF_PATH_A, + &rtw8852c_tssi_txpwr_ctrl_bb_he_tb_defs_a_tbl, + &rtw8852c_tssi_txpwr_ctrl_bb_he_tb_defs_b_tbl); +} + +static void _tssi_set_dck(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy, + enum rtw89_rf_path path) +{ + enum rtw89_band band = rtwdev->hal.current_band_type; + + if (path == RF_PATH_A) { + rtw89_rfk_parser(rtwdev, &rtw8852c_tssi_dck_defs_a_tbl); + rtw89_rfk_parser_by_cond(rtwdev, band == RTW89_BAND_2G, + &rtw8852c_tssi_dck_defs_2g_a_tbl, + &rtw8852c_tssi_dck_defs_5g_a_tbl); + } else { + rtw89_rfk_parser(rtwdev, &rtw8852c_tssi_dck_defs_b_tbl); + rtw89_rfk_parser_by_cond(rtwdev, band == RTW89_BAND_2G, + &rtw8852c_tssi_dck_defs_2g_b_tbl, + &rtw8852c_tssi_dck_defs_5g_b_tbl); + } +} + +static void _tssi_set_bbgain_split(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy, + enum rtw89_rf_path path) +{ + rtw89_rfk_parser_by_cond(rtwdev, path == RF_PATH_A, + &rtw8852c_tssi_set_bbgain_split_a_tbl, + &rtw8852c_tssi_set_bbgain_split_b_tbl); +} + +static void _tssi_set_tmeter_tbl(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy, + enum rtw89_rf_path path) +{ +#define RTW8852C_TSSI_GET_VAL(ptr, idx) \ +({ \ + s8 *__ptr = (ptr); \ + u8 __idx = (idx), __i, __v; \ + u32 __val = 0; \ + for (__i = 0; __i < 4; __i++) { \ + __v = (__ptr[__idx + __i]); \ + __val |= (__v << (8 * __i)); \ + } \ + __val; \ +}) + struct rtw89_tssi_info *tssi_info = &rtwdev->tssi; + u8 ch = rtwdev->hal.current_channel; + u8 subband = rtwdev->hal.current_subband; + const s8 *thm_up_a = NULL; + const s8 *thm_down_a = NULL; + const s8 *thm_up_b = NULL; + const s8 *thm_down_b = NULL; + u8 thermal = 0xff; + s8 thm_ofst[64] = {0}; + u32 tmp = 0; + u8 i, j; + + switch (subband) { + default: + case RTW89_CH_2G: + thm_up_a = rtw89_8852c_trk_cfg.delta_swingidx_2ga_p; + thm_down_a = rtw89_8852c_trk_cfg.delta_swingidx_2ga_n; + thm_up_b = rtw89_8852c_trk_cfg.delta_swingidx_2gb_p; + thm_down_b = rtw89_8852c_trk_cfg.delta_swingidx_2gb_n; + break; + case RTW89_CH_5G_BAND_1: + thm_up_a = rtw89_8852c_trk_cfg.delta_swingidx_5ga_p[0]; + thm_down_a = rtw89_8852c_trk_cfg.delta_swingidx_5ga_n[0]; + thm_up_b = rtw89_8852c_trk_cfg.delta_swingidx_5gb_p[0]; + thm_down_b = rtw89_8852c_trk_cfg.delta_swingidx_5gb_n[0]; + break; + case RTW89_CH_5G_BAND_3: + thm_up_a = rtw89_8852c_trk_cfg.delta_swingidx_5ga_p[1]; + thm_down_a = rtw89_8852c_trk_cfg.delta_swingidx_5ga_n[1]; + thm_up_b = rtw89_8852c_trk_cfg.delta_swingidx_5gb_p[1]; + thm_down_b = rtw89_8852c_trk_cfg.delta_swingidx_5gb_n[1]; + break; + case RTW89_CH_5G_BAND_4: + thm_up_a = rtw89_8852c_trk_cfg.delta_swingidx_5ga_p[2]; + thm_down_a = rtw89_8852c_trk_cfg.delta_swingidx_5ga_n[2]; + thm_up_b = rtw89_8852c_trk_cfg.delta_swingidx_5gb_p[2]; + thm_down_b = rtw89_8852c_trk_cfg.delta_swingidx_5gb_n[2]; + break; + case RTW89_CH_6G_BAND_IDX0: + case RTW89_CH_6G_BAND_IDX1: + thm_up_a = rtw89_8852c_trk_cfg.delta_swingidx_6ga_p[0]; + thm_down_a = rtw89_8852c_trk_cfg.delta_swingidx_6ga_n[0]; + thm_up_b = rtw89_8852c_trk_cfg.delta_swingidx_6gb_p[0]; + thm_down_b = rtw89_8852c_trk_cfg.delta_swingidx_6gb_n[0]; + break; + case RTW89_CH_6G_BAND_IDX2: + case RTW89_CH_6G_BAND_IDX3: + thm_up_a = rtw89_8852c_trk_cfg.delta_swingidx_6ga_p[1]; + thm_down_a = rtw89_8852c_trk_cfg.delta_swingidx_6ga_n[1]; + thm_up_b = rtw89_8852c_trk_cfg.delta_swingidx_6gb_p[1]; + thm_down_b = rtw89_8852c_trk_cfg.delta_swingidx_6gb_n[1]; + break; + case RTW89_CH_6G_BAND_IDX4: + case RTW89_CH_6G_BAND_IDX5: + thm_up_a = rtw89_8852c_trk_cfg.delta_swingidx_6ga_p[2]; + thm_down_a = rtw89_8852c_trk_cfg.delta_swingidx_6ga_n[2]; + thm_up_b = rtw89_8852c_trk_cfg.delta_swingidx_6gb_p[2]; + thm_down_b = rtw89_8852c_trk_cfg.delta_swingidx_6gb_n[2]; + break; + case RTW89_CH_6G_BAND_IDX6: + case RTW89_CH_6G_BAND_IDX7: + thm_up_a = rtw89_8852c_trk_cfg.delta_swingidx_6ga_p[3]; + thm_down_a = rtw89_8852c_trk_cfg.delta_swingidx_6ga_n[3]; + thm_up_b = rtw89_8852c_trk_cfg.delta_swingidx_6gb_p[3]; + thm_down_b = rtw89_8852c_trk_cfg.delta_swingidx_6gb_n[3]; + break; + } + + if (path == RF_PATH_A) { + thermal = tssi_info->thermal[RF_PATH_A]; + + rtw89_debug(rtwdev, RTW89_DBG_TSSI, + "[TSSI] ch=%d thermal_pathA=0x%x\n", ch, thermal); + + rtw89_phy_write32_mask(rtwdev, R_P0_TMETER, B_P0_TMETER_DIS, 0x0); + rtw89_phy_write32_mask(rtwdev, R_P0_TMETER, B_P0_TMETER_TRK, 0x1); + + if (thermal == 0xff) { + rtw89_phy_write32_mask(rtwdev, R_P0_TMETER, B_P0_TMETER, 32); + rtw89_phy_write32_mask(rtwdev, R_P0_RFCTM, B_P0_RFCTM_VAL, 32); + + for (i = 0; i < 64; i += 4) { + rtw89_phy_write32(rtwdev, R_P0_TSSI_BASE + i, 0x0); + + rtw89_debug(rtwdev, RTW89_DBG_TSSI, + "[TSSI] write 0x%x val=0x%08x\n", + 0x5c00 + i, 0x0); + } + + } else { + rtw89_phy_write32_mask(rtwdev, R_P0_TMETER, B_P0_TMETER, thermal); + rtw89_phy_write32_mask(rtwdev, R_P0_RFCTM, B_P0_RFCTM_VAL, + thermal); + + i = 0; + for (j = 0; j < 32; j++) + thm_ofst[j] = i < DELTA_SWINGIDX_SIZE ? + -thm_down_a[i++] : + -thm_down_a[DELTA_SWINGIDX_SIZE - 1]; + + i = 1; + for (j = 63; j >= 32; j--) + thm_ofst[j] = i < DELTA_SWINGIDX_SIZE ? + thm_up_a[i++] : + thm_up_a[DELTA_SWINGIDX_SIZE - 1]; + + for (i = 0; i < 64; i += 4) { + tmp = RTW8852C_TSSI_GET_VAL(thm_ofst, i); + rtw89_phy_write32(rtwdev, R_P0_TSSI_BASE + i, tmp); + + rtw89_debug(rtwdev, RTW89_DBG_TSSI, + "[TSSI] write 0x%x val=0x%08x\n", + 0x5c00 + i, tmp); + } + } + rtw89_phy_write32_mask(rtwdev, R_P0_RFCTM, R_P0_RFCTM_RDY, 0x1); + rtw89_phy_write32_mask(rtwdev, R_P0_RFCTM, R_P0_RFCTM_RDY, 0x0); + + } else { + thermal = tssi_info->thermal[RF_PATH_B]; + + rtw89_debug(rtwdev, RTW89_DBG_TSSI, + "[TSSI] ch=%d thermal_pathB=0x%x\n", ch, thermal); + + rtw89_phy_write32_mask(rtwdev, R_P1_TMETER, B_P1_TMETER_DIS, 0x0); + rtw89_phy_write32_mask(rtwdev, R_P1_TMETER, B_P1_TMETER_TRK, 0x1); + + if (thermal == 0xff) { + rtw89_phy_write32_mask(rtwdev, R_P1_TMETER, B_P1_TMETER, 32); + rtw89_phy_write32_mask(rtwdev, R_P1_RFCTM, B_P1_RFCTM_VAL, 32); + + for (i = 0; i < 64; i += 4) { + rtw89_phy_write32(rtwdev, R_TSSI_THOF + i, 0x0); + + rtw89_debug(rtwdev, RTW89_DBG_TSSI, + "[TSSI] write 0x%x val=0x%08x\n", + 0x7c00 + i, 0x0); + } + + } else { + rtw89_phy_write32_mask(rtwdev, R_P1_TMETER, B_P1_TMETER, thermal); + rtw89_phy_write32_mask(rtwdev, R_P1_RFCTM, B_P1_RFCTM_VAL, + thermal); + + i = 0; + for (j = 0; j < 32; j++) + thm_ofst[j] = i < DELTA_SWINGIDX_SIZE ? + -thm_down_b[i++] : + -thm_down_b[DELTA_SWINGIDX_SIZE - 1]; + + i = 1; + for (j = 63; j >= 32; j--) + thm_ofst[j] = i < DELTA_SWINGIDX_SIZE ? + thm_up_b[i++] : + thm_up_b[DELTA_SWINGIDX_SIZE - 1]; + + for (i = 0; i < 64; i += 4) { + tmp = RTW8852C_TSSI_GET_VAL(thm_ofst, i); + rtw89_phy_write32(rtwdev, R_TSSI_THOF + i, tmp); + + rtw89_debug(rtwdev, RTW89_DBG_TSSI, + "[TSSI] write 0x%x val=0x%08x\n", + 0x7c00 + i, tmp); + } + } + rtw89_phy_write32_mask(rtwdev, R_P1_RFCTM, R_P1_RFCTM_RDY, 0x1); + rtw89_phy_write32_mask(rtwdev, R_P1_RFCTM, R_P1_RFCTM_RDY, 0x0); + } +#undef RTW8852C_TSSI_GET_VAL +} + +static void _tssi_slope_cal_org(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy, + enum rtw89_rf_path path) +{ + enum rtw89_band band = rtwdev->hal.current_band_type; + + if (path == RF_PATH_A) { + rtw89_rfk_parser_by_cond(rtwdev, band == RTW89_BAND_2G, + &rtw8852c_tssi_slope_cal_org_defs_2g_a_tbl, + &rtw8852c_tssi_slope_cal_org_defs_5g_a_tbl); + } else { + rtw89_rfk_parser_by_cond(rtwdev, band == RTW89_BAND_2G, + &rtw8852c_tssi_slope_cal_org_defs_2g_b_tbl, + &rtw8852c_tssi_slope_cal_org_defs_5g_b_tbl); + } +} + +static void _tssi_set_aligk_default(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy, + enum rtw89_rf_path path) +{ + enum rtw89_band band = rtwdev->hal.current_band_type; + const struct rtw89_rfk_tbl *tbl; + + if (path == RF_PATH_A) { + if (band == RTW89_BAND_2G) + tbl = &rtw8852c_tssi_set_aligk_default_defs_2g_a_tbl; + else if (band == RTW89_BAND_6G) + tbl = &rtw8852c_tssi_set_aligk_default_defs_6g_a_tbl; + else + tbl = &rtw8852c_tssi_set_aligk_default_defs_5g_a_tbl; + } else { + if (band == RTW89_BAND_2G) + tbl = &rtw8852c_tssi_set_aligk_default_defs_2g_b_tbl; + else if (band == RTW89_BAND_6G) + tbl = &rtw8852c_tssi_set_aligk_default_defs_6g_b_tbl; + else + tbl = &rtw8852c_tssi_set_aligk_default_defs_5g_b_tbl; + } + + rtw89_rfk_parser(rtwdev, tbl); +} + +static void _tssi_set_slope(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy, + enum rtw89_rf_path path) +{ + rtw89_rfk_parser_by_cond(rtwdev, path == RF_PATH_A, + &rtw8852c_tssi_slope_defs_a_tbl, + &rtw8852c_tssi_slope_defs_b_tbl); +} + +static void _tssi_run_slope(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy, + enum rtw89_rf_path path) +{ + rtw89_rfk_parser_by_cond(rtwdev, path == RF_PATH_A, + &rtw8852c_tssi_run_slope_defs_a_tbl, + &rtw8852c_tssi_run_slope_defs_b_tbl); +} + +static void _tssi_set_track(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy, + enum rtw89_rf_path path) +{ + rtw89_rfk_parser_by_cond(rtwdev, path == RF_PATH_A, + &rtw8852c_tssi_track_defs_a_tbl, + &rtw8852c_tssi_track_defs_b_tbl); +} + +static void _tssi_set_txagc_offset_mv_avg(struct rtw89_dev *rtwdev, + enum rtw89_phy_idx phy, + enum rtw89_rf_path path) +{ + rtw89_rfk_parser_by_cond(rtwdev, path == RF_PATH_A, + &rtw8852c_tssi_txagc_ofst_mv_avg_defs_a_tbl, + &rtw8852c_tssi_txagc_ofst_mv_avg_defs_b_tbl); +} + +static void _tssi_enable(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy) +{ + struct rtw89_tssi_info *tssi_info = &rtwdev->tssi; + u32 i, path = RF_PATH_A, path_max = RF_PATH_NUM_8852C; + + if (rtwdev->dbcc_en) { + if (phy == RTW89_PHY_0) { + path = RF_PATH_A; + path_max = RF_PATH_B; + } else if (phy == RTW89_PHY_1) { + path = RF_PATH_B; + path_max = RF_PATH_NUM_8852C; + } + } + + for (i = path; i < path_max; i++) { + _tssi_set_track(rtwdev, phy, i); + _tssi_set_txagc_offset_mv_avg(rtwdev, phy, i); + + rtw89_rfk_parser_by_cond(rtwdev, i == RF_PATH_A, + &rtw8852c_tssi_enable_defs_a_tbl, + &rtw8852c_tssi_enable_defs_b_tbl); + + tssi_info->base_thermal[i] = + ewma_thermal_read(&rtwdev->phystat.avg_thermal[i]); + rtwdev->is_tssi_mode[i] = true; + } +} + +static void _tssi_disable(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy) +{ + u32 i, path = RF_PATH_A, path_max = RF_PATH_NUM_8852C; + + if (rtwdev->dbcc_en) { + if (phy == RTW89_PHY_0) { + path = RF_PATH_A; + path_max = RF_PATH_B; + } else if (phy == RTW89_PHY_1) { + path = RF_PATH_B; + path_max = RF_PATH_NUM_8852C; + } + } + + for (i = path; i < path_max; i++) { + if (i == RF_PATH_A) { + rtw89_rfk_parser(rtwdev, &rtw8852c_tssi_disable_defs_a_tbl); + rtwdev->is_tssi_mode[RF_PATH_A] = false; + } else if (i == RF_PATH_B) { + rtw89_rfk_parser(rtwdev, &rtw8852c_tssi_disable_defs_b_tbl); + rtwdev->is_tssi_mode[RF_PATH_B] = false; + } + } +} + +static u32 _tssi_get_cck_group(struct rtw89_dev *rtwdev, u8 ch) +{ + switch (ch) { + case 1 ... 2: + return 0; + case 3 ... 5: + return 1; + case 6 ... 8: + return 2; + case 9 ... 11: + return 3; + case 12 ... 13: + return 4; + case 14: + return 5; + } + + return 0; +} + +#define TSSI_EXTRA_GROUP_BIT (BIT(31)) +#define TSSI_EXTRA_GROUP(idx) (TSSI_EXTRA_GROUP_BIT | (idx)) +#define IS_TSSI_EXTRA_GROUP(group) ((group) & TSSI_EXTRA_GROUP_BIT) +#define TSSI_EXTRA_GET_GROUP_IDX1(group) ((group) & ~TSSI_EXTRA_GROUP_BIT) +#define TSSI_EXTRA_GET_GROUP_IDX2(group) (TSSI_EXTRA_GET_GROUP_IDX1(group) + 1) + +static u32 _tssi_get_ofdm_group(struct rtw89_dev *rtwdev, u8 ch) +{ + switch (ch) { + case 1 ... 2: + return 0; + case 3 ... 5: + return 1; + case 6 ... 8: + return 2; + case 9 ... 11: + return 3; + case 12 ... 14: + return 4; + case 36 ... 40: + return 5; + case 41 ... 43: + return TSSI_EXTRA_GROUP(5); + case 44 ... 48: + return 6; + case 49 ... 51: + return TSSI_EXTRA_GROUP(6); + case 52 ... 56: + return 7; + case 57 ... 59: + return TSSI_EXTRA_GROUP(7); + case 60 ... 64: + return 8; + case 100 ... 104: + return 9; + case 105 ... 107: + return TSSI_EXTRA_GROUP(9); + case 108 ... 112: + return 10; + case 113 ... 115: + return TSSI_EXTRA_GROUP(10); + case 116 ... 120: + return 11; + case 121 ... 123: + return TSSI_EXTRA_GROUP(11); + case 124 ... 128: + return 12; + case 129 ... 131: + return TSSI_EXTRA_GROUP(12); + case 132 ... 136: + return 13; + case 137 ... 139: + return TSSI_EXTRA_GROUP(13); + case 140 ... 144: + return 14; + case 149 ... 153: + return 15; + case 154 ... 156: + return TSSI_EXTRA_GROUP(15); + case 157 ... 161: + return 16; + case 162 ... 164: + return TSSI_EXTRA_GROUP(16); + case 165 ... 169: + return 17; + case 170 ... 172: + return TSSI_EXTRA_GROUP(17); + case 173 ... 177: + return 18; + } + + return 0; +} + +static u32 _tssi_get_6g_ofdm_group(struct rtw89_dev *rtwdev, u8 ch) +{ + switch (ch) { + case 1 ... 5: + return 0; + case 6 ... 8: + return TSSI_EXTRA_GROUP(0); + case 9 ... 13: + return 1; + case 14 ... 16: + return TSSI_EXTRA_GROUP(1); + case 17 ... 21: + return 2; + case 22 ... 24: + return TSSI_EXTRA_GROUP(2); + case 25 ... 29: + return 3; + case 33 ... 37: + return 4; + case 38 ... 40: + return TSSI_EXTRA_GROUP(4); + case 41 ... 45: + return 5; + case 46 ... 48: + return TSSI_EXTRA_GROUP(5); + case 49 ... 53: + return 6; + case 54 ... 56: + return TSSI_EXTRA_GROUP(6); + case 57 ... 61: + return 7; + case 65 ... 69: + return 8; + case 70 ... 72: + return TSSI_EXTRA_GROUP(8); + case 73 ... 77: + return 9; + case 78 ... 80: + return TSSI_EXTRA_GROUP(9); + case 81 ... 85: + return 10; + case 86 ... 88: + return TSSI_EXTRA_GROUP(10); + case 89 ... 93: + return 11; + case 97 ... 101: + return 12; + case 102 ... 104: + return TSSI_EXTRA_GROUP(12); + case 105 ... 109: + return 13; + case 110 ... 112: + return TSSI_EXTRA_GROUP(13); + case 113 ... 117: + return 14; + case 118 ... 120: + return TSSI_EXTRA_GROUP(14); + case 121 ... 125: + return 15; + case 129 ... 133: + return 16; + case 134 ... 136: + return TSSI_EXTRA_GROUP(16); + case 137 ... 141: + return 17; + case 142 ... 144: + return TSSI_EXTRA_GROUP(17); + case 145 ... 149: + return 18; + case 150 ... 152: + return TSSI_EXTRA_GROUP(18); + case 153 ... 157: + return 19; + case 161 ... 165: + return 20; + case 166 ... 168: + return TSSI_EXTRA_GROUP(20); + case 169 ... 173: + return 21; + case 174 ... 176: + return TSSI_EXTRA_GROUP(21); + case 177 ... 181: + return 22; + case 182 ... 184: + return TSSI_EXTRA_GROUP(22); + case 185 ... 189: + return 23; + case 193 ... 197: + return 24; + case 198 ... 200: + return TSSI_EXTRA_GROUP(24); + case 201 ... 205: + return 25; + case 206 ... 208: + return TSSI_EXTRA_GROUP(25); + case 209 ... 213: + return 26; + case 214 ... 216: + return TSSI_EXTRA_GROUP(26); + case 217 ... 221: + return 27; + case 225 ... 229: + return 28; + case 230 ... 232: + return TSSI_EXTRA_GROUP(28); + case 233 ... 237: + return 29; + case 238 ... 240: + return TSSI_EXTRA_GROUP(29); + case 241 ... 245: + return 30; + case 246 ... 248: + return TSSI_EXTRA_GROUP(30); + case 249 ... 253: + return 31; + } + + return 0; +} + +static u32 _tssi_get_trim_group(struct rtw89_dev *rtwdev, u8 ch) +{ + switch (ch) { + case 1 ... 8: + return 0; + case 9 ... 14: + return 1; + case 36 ... 48: + return 2; + case 49 ... 51: + return TSSI_EXTRA_GROUP(2); + case 52 ... 64: + return 3; + case 100 ... 112: + return 4; + case 113 ... 115: + return TSSI_EXTRA_GROUP(4); + case 116 ... 128: + return 5; + case 132 ... 144: + return 6; + case 149 ... 177: + return 7; + } + + return 0; +} + +static u32 _tssi_get_6g_trim_group(struct rtw89_dev *rtwdev, u8 ch) +{ + switch (ch) { + case 1 ... 13: + return 0; + case 14 ... 16: + return TSSI_EXTRA_GROUP(0); + case 17 ... 29: + return 1; + case 33 ... 45: + return 2; + case 46 ... 48: + return TSSI_EXTRA_GROUP(2); + case 49 ... 61: + return 3; + case 65 ... 77: + return 4; + case 78 ... 80: + return TSSI_EXTRA_GROUP(4); + case 81 ... 93: + return 5; + case 97 ... 109: + return 6; + case 110 ... 112: + return TSSI_EXTRA_GROUP(6); + case 113 ... 125: + return 7; + case 129 ... 141: + return 8; + case 142 ... 144: + return TSSI_EXTRA_GROUP(8); + case 145 ... 157: + return 9; + case 161 ... 173: + return 10; + case 174 ... 176: + return TSSI_EXTRA_GROUP(10); + case 177 ... 189: + return 11; + case 193 ... 205: + return 12; + case 206 ... 208: + return TSSI_EXTRA_GROUP(12); + case 209 ... 221: + return 13; + case 225 ... 237: + return 14; + case 238 ... 240: + return TSSI_EXTRA_GROUP(14); + case 241 ... 253: + return 15; + } + + return 0; +} + +static s8 _tssi_get_ofdm_de(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy, + enum rtw89_rf_path path) +{ + struct rtw89_tssi_info *tssi_info = &rtwdev->tssi; + enum rtw89_band band = rtwdev->hal.current_band_type; + u8 ch = rtwdev->hal.current_channel; + u32 gidx, gidx_1st, gidx_2nd; + s8 de_1st; + s8 de_2nd; + s8 val; + + if (band == RTW89_BAND_2G || band == RTW89_BAND_5G) { + gidx = _tssi_get_ofdm_group(rtwdev, ch); + + rtw89_debug(rtwdev, RTW89_DBG_TSSI, + "[TSSI][TRIM]: path=%d mcs group_idx=0x%x\n", + path, gidx); + + if (IS_TSSI_EXTRA_GROUP(gidx)) { + gidx_1st = TSSI_EXTRA_GET_GROUP_IDX1(gidx); + gidx_2nd = TSSI_EXTRA_GET_GROUP_IDX2(gidx); + de_1st = tssi_info->tssi_mcs[path][gidx_1st]; + de_2nd = tssi_info->tssi_mcs[path][gidx_2nd]; + val = (de_1st + de_2nd) / 2; + + rtw89_debug(rtwdev, RTW89_DBG_TSSI, + "[TSSI][TRIM]: path=%d mcs de=%d 1st=%d 2nd=%d\n", + path, val, de_1st, de_2nd); + } else { + val = tssi_info->tssi_mcs[path][gidx]; + + rtw89_debug(rtwdev, RTW89_DBG_TSSI, + "[TSSI][TRIM]: path=%d mcs de=%d\n", path, val); + } + } else { + gidx = _tssi_get_6g_ofdm_group(rtwdev, ch); + + rtw89_debug(rtwdev, RTW89_DBG_TSSI, + "[TSSI][TRIM]: path=%d mcs group_idx=0x%x\n", + path, gidx); + + if (IS_TSSI_EXTRA_GROUP(gidx)) { + gidx_1st = TSSI_EXTRA_GET_GROUP_IDX1(gidx); + gidx_2nd = TSSI_EXTRA_GET_GROUP_IDX2(gidx); + de_1st = tssi_info->tssi_6g_mcs[path][gidx_1st]; + de_2nd = tssi_info->tssi_6g_mcs[path][gidx_2nd]; + val = (de_1st + de_2nd) / 2; + + rtw89_debug(rtwdev, RTW89_DBG_TSSI, + "[TSSI][TRIM]: path=%d mcs de=%d 1st=%d 2nd=%d\n", + path, val, de_1st, de_2nd); + } else { + val = tssi_info->tssi_6g_mcs[path][gidx]; + + rtw89_debug(rtwdev, RTW89_DBG_TSSI, + "[TSSI][TRIM]: path=%d mcs de=%d\n", path, val); + } + } + + return val; +} + +static s8 _tssi_get_ofdm_trim_de(struct rtw89_dev *rtwdev, + enum rtw89_phy_idx phy, + enum rtw89_rf_path path) +{ + struct rtw89_tssi_info *tssi_info = &rtwdev->tssi; + enum rtw89_band band = rtwdev->hal.current_band_type; + u8 ch = rtwdev->hal.current_channel; + u32 tgidx, tgidx_1st, tgidx_2nd; + s8 tde_1st = 0; + s8 tde_2nd = 0; + s8 val; + + if (band == RTW89_BAND_2G || band == RTW89_BAND_5G) { + tgidx = _tssi_get_trim_group(rtwdev, ch); + + rtw89_debug(rtwdev, RTW89_DBG_TSSI, + "[TSSI][TRIM]: path=%d mcs trim_group_idx=0x%x\n", + path, tgidx); + + if (IS_TSSI_EXTRA_GROUP(tgidx)) { + tgidx_1st = TSSI_EXTRA_GET_GROUP_IDX1(tgidx); + tgidx_2nd = TSSI_EXTRA_GET_GROUP_IDX2(tgidx); + tde_1st = tssi_info->tssi_trim[path][tgidx_1st]; + tde_2nd = tssi_info->tssi_trim[path][tgidx_2nd]; + val = (tde_1st + tde_2nd) / 2; + + rtw89_debug(rtwdev, RTW89_DBG_TSSI, + "[TSSI][TRIM]: path=%d mcs trim_de=%d 1st=%d 2nd=%d\n", + path, val, tde_1st, tde_2nd); + } else { + val = tssi_info->tssi_trim[path][tgidx]; + + rtw89_debug(rtwdev, RTW89_DBG_TSSI, + "[TSSI][TRIM]: path=%d mcs trim_de=%d\n", + path, val); + } + } else { + tgidx = _tssi_get_6g_trim_group(rtwdev, ch); + + rtw89_debug(rtwdev, RTW89_DBG_TSSI, + "[TSSI][TRIM]: path=%d mcs trim_group_idx=0x%x\n", + path, tgidx); + + if (IS_TSSI_EXTRA_GROUP(tgidx)) { + tgidx_1st = TSSI_EXTRA_GET_GROUP_IDX1(tgidx); + tgidx_2nd = TSSI_EXTRA_GET_GROUP_IDX2(tgidx); + tde_1st = tssi_info->tssi_trim_6g[path][tgidx_1st]; + tde_2nd = tssi_info->tssi_trim_6g[path][tgidx_2nd]; + val = (tde_1st + tde_2nd) / 2; + + rtw89_debug(rtwdev, RTW89_DBG_TSSI, + "[TSSI][TRIM]: path=%d mcs trim_de=%d 1st=%d 2nd=%d\n", + path, val, tde_1st, tde_2nd); + } else { + val = tssi_info->tssi_trim_6g[path][tgidx]; + + rtw89_debug(rtwdev, RTW89_DBG_TSSI, + "[TSSI][TRIM]: path=%d mcs trim_de=%d\n", + path, val); + } + } + + return val; +} + +static void _tssi_set_efuse_to_de(struct rtw89_dev *rtwdev, + enum rtw89_phy_idx phy) +{ + struct rtw89_tssi_info *tssi_info = &rtwdev->tssi; + u8 ch = rtwdev->hal.current_channel; + u8 gidx; + s8 ofdm_de; + s8 trim_de; + s32 val; + u32 i, path = RF_PATH_A, path_max = RF_PATH_NUM_8852C; + + rtw89_debug(rtwdev, RTW89_DBG_TSSI, "[TSSI][TRIM]: phy=%d ch=%d\n", + phy, ch); + + if (rtwdev->dbcc_en) { + if (phy == RTW89_PHY_0) { + path = RF_PATH_A; + path_max = RF_PATH_B; + } else if (phy == RTW89_PHY_1) { + path = RF_PATH_B; + path_max = RF_PATH_NUM_8852C; + } + } + + for (i = path; i < path_max; i++) { + gidx = _tssi_get_cck_group(rtwdev, ch); + trim_de = _tssi_get_ofdm_trim_de(rtwdev, phy, i); + val = tssi_info->tssi_cck[i][gidx] + trim_de; + + rtw89_debug(rtwdev, RTW89_DBG_TSSI, + "[TSSI][TRIM]: path=%d cck[%d]=0x%x trim=0x%x\n", + i, gidx, tssi_info->tssi_cck[i][gidx], trim_de); + + rtw89_phy_write32_mask(rtwdev, _tssi_de_cck_long[i], _TSSI_DE_MASK, val); + rtw89_phy_write32_mask(rtwdev, _tssi_de_cck_short[i], _TSSI_DE_MASK, val); + + rtw89_debug(rtwdev, RTW89_DBG_TSSI, + "[TSSI] Set TSSI CCK DE 0x%x[21:12]=0x%x\n", + _tssi_de_cck_long[i], + rtw89_phy_read32_mask(rtwdev, _tssi_de_cck_long[i], + _TSSI_DE_MASK)); + + ofdm_de = _tssi_get_ofdm_de(rtwdev, phy, i); + trim_de = _tssi_get_ofdm_trim_de(rtwdev, phy, i); + val = ofdm_de + trim_de; + + rtw89_debug(rtwdev, RTW89_DBG_TSSI, + "[TSSI][TRIM]: path=%d mcs=0x%x trim=0x%x\n", + i, ofdm_de, trim_de); + + rtw89_phy_write32_mask(rtwdev, _tssi_de_mcs_20m[i], _TSSI_DE_MASK, val); + rtw89_phy_write32_mask(rtwdev, _tssi_de_mcs_40m[i], _TSSI_DE_MASK, val); + rtw89_phy_write32_mask(rtwdev, _tssi_de_mcs_80m[i], _TSSI_DE_MASK, val); + rtw89_phy_write32_mask(rtwdev, _tssi_de_mcs_80m_80m[i], _TSSI_DE_MASK, val); + rtw89_phy_write32_mask(rtwdev, _tssi_de_mcs_5m[i], _TSSI_DE_MASK, val); + rtw89_phy_write32_mask(rtwdev, _tssi_de_mcs_10m[i], _TSSI_DE_MASK, val); + + rtw89_debug(rtwdev, RTW89_DBG_TSSI, + "[TSSI] Set TSSI MCS DE 0x%x[21:12]=0x%x\n", + _tssi_de_mcs_20m[i], + rtw89_phy_read32_mask(rtwdev, _tssi_de_mcs_20m[i], + _TSSI_DE_MASK)); + } +} + +static void rtw8852c_tssi_cont_en(struct rtw89_dev *rtwdev, bool en, + enum rtw89_rf_path path) +{ + static const u32 tssi_trk[2] = {0x5818, 0x7818}; + static const u32 tssi_en[2] = {0x5820, 0x7820}; + + if (en) { + rtw89_phy_write32_mask(rtwdev, tssi_trk[path], BIT(30), 0x0); + rtw89_phy_write32_mask(rtwdev, tssi_en[path], BIT(31), 0x0); + if (rtwdev->dbcc_en && path == RF_PATH_B) + _tssi_set_efuse_to_de(rtwdev, RTW89_PHY_1); + else + _tssi_set_efuse_to_de(rtwdev, RTW89_PHY_0); + } else { + rtw89_phy_write32_mask(rtwdev, tssi_trk[path], BIT(30), 0x1); + rtw89_phy_write32_mask(rtwdev, tssi_en[path], BIT(31), 0x1); + } +} + +void rtw8852c_tssi_cont_en_phyidx(struct rtw89_dev *rtwdev, bool en, u8 phy_idx) +{ + if (!rtwdev->dbcc_en) { + rtw8852c_tssi_cont_en(rtwdev, en, RF_PATH_A); + rtw8852c_tssi_cont_en(rtwdev, en, RF_PATH_B); + } else { + if (phy_idx == RTW89_PHY_0) + rtw8852c_tssi_cont_en(rtwdev, en, RF_PATH_A); + else + rtw8852c_tssi_cont_en(rtwdev, en, RF_PATH_B); + } +} + static void _bw_setting(struct rtw89_dev *rtwdev, enum rtw89_rf_path path, enum rtw89_bandwidth bw, bool is_dav) { @@ -721,3 +1627,130 @@ void rtw8852c_dack(struct rtw89_dev *rtwdev) _dac_cal(rtwdev, false); rtw89_btc_ntfy_wl_rfk(rtwdev, phy_map, BTC_WRFKT_DACK, BTC_WRFK_STOP); } + +void rtw8852c_tssi(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy) +{ + u32 i, path = RF_PATH_A, path_max = RF_PATH_NUM_8852C; + + rtw89_debug(rtwdev, RTW89_DBG_TSSI, "[TSSI] %s: phy=%d\n", __func__, phy); + + if (rtwdev->dbcc_en) { + if (phy == RTW89_PHY_0) { + path = RF_PATH_A; + path_max = RF_PATH_B; + } else if (phy == RTW89_PHY_1) { + path = RF_PATH_B; + path_max = RF_PATH_NUM_8852C; + } + } + + _tssi_disable(rtwdev, phy); + + for (i = path; i < path_max; i++) { + _tssi_set_sys(rtwdev, phy, i); + _tssi_ini_txpwr_ctrl_bb(rtwdev, phy, i); + _tssi_ini_txpwr_ctrl_bb_he_tb(rtwdev, phy, i); + _tssi_set_dck(rtwdev, phy, i); + _tssi_set_bbgain_split(rtwdev, phy, i); + _tssi_set_tmeter_tbl(rtwdev, phy, i); + _tssi_slope_cal_org(rtwdev, phy, i); + _tssi_set_aligk_default(rtwdev, phy, i); + _tssi_set_slope(rtwdev, phy, i); + _tssi_run_slope(rtwdev, phy, i); + } + + _tssi_enable(rtwdev, phy); + _tssi_set_efuse_to_de(rtwdev, phy); +} + +void rtw8852c_tssi_scan(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy) +{ + u32 i, path = RF_PATH_A, path_max = RF_PATH_NUM_8852C; + + rtw89_debug(rtwdev, RTW89_DBG_TSSI, "[TSSI] %s: phy=%d\n", + __func__, phy); + + if (!rtwdev->is_tssi_mode[RF_PATH_A]) + return; + if (!rtwdev->is_tssi_mode[RF_PATH_B]) + return; + + if (rtwdev->dbcc_en) { + if (phy == RTW89_PHY_0) { + path = RF_PATH_A; + path_max = RF_PATH_B; + } else if (phy == RTW89_PHY_1) { + path = RF_PATH_B; + path_max = RF_PATH_NUM_8852C; + } + } + + _tssi_disable(rtwdev, phy); + + for (i = path; i < path_max; i++) { + _tssi_set_sys(rtwdev, phy, i); + _tssi_set_dck(rtwdev, phy, i); + _tssi_set_tmeter_tbl(rtwdev, phy, i); + _tssi_slope_cal_org(rtwdev, phy, i); + _tssi_set_aligk_default(rtwdev, phy, i); + } + + _tssi_enable(rtwdev, phy); + _tssi_set_efuse_to_de(rtwdev, phy); +} + +static void rtw8852c_tssi_default_txagc(struct rtw89_dev *rtwdev, + enum rtw89_phy_idx phy, bool enable) +{ + struct rtw89_tssi_info *tssi_info = &rtwdev->tssi; + u8 i; + + if (!rtwdev->is_tssi_mode[RF_PATH_A] && !rtwdev->is_tssi_mode[RF_PATH_B]) + return; + + if (enable) { + /* SCAN_START */ + if (rtw89_phy_read32_mask(rtwdev, R_TXAGC_BB, B_TXAGC_BB_OFT) != 0xc000 && + rtw89_phy_read32_mask(rtwdev, R_TXAGC_BB, B_TXAGC_BB_OFT) != 0x0) { + for (i = 0; i < 6; i++) { + tssi_info->default_txagc_offset[RF_PATH_A] = + rtw89_phy_read32_mask(rtwdev, R_TXAGC_BB, + B_TXAGC_BB); + if (tssi_info->default_txagc_offset[RF_PATH_A]) + break; + } + } + + if (rtw89_phy_read32_mask(rtwdev, R_TXAGC_BB_S1, B_TXAGC_BB_S1_OFT) != 0xc000 && + rtw89_phy_read32_mask(rtwdev, R_TXAGC_BB_S1, B_TXAGC_BB_S1_OFT) != 0x0) { + for (i = 0; i < 6; i++) { + tssi_info->default_txagc_offset[RF_PATH_B] = + rtw89_phy_read32_mask(rtwdev, R_TXAGC_BB_S1, + B_TXAGC_BB_S1); + if (tssi_info->default_txagc_offset[RF_PATH_B]) + break; + } + } + } else { + /* SCAN_END */ + rtw89_phy_write32_mask(rtwdev, R_P0_TSSI_TRK, B_P0_TSSI_OFT, + tssi_info->default_txagc_offset[RF_PATH_A]); + rtw89_phy_write32_mask(rtwdev, R_P1_TSSI_TRK, B_P1_TSSI_OFT, + tssi_info->default_txagc_offset[RF_PATH_B]); + + rtw89_phy_write32_mask(rtwdev, R_P0_TSSI_TRK, B_P0_TSSI_OFT_EN, 0x0); + rtw89_phy_write32_mask(rtwdev, R_P0_TSSI_TRK, B_P0_TSSI_OFT_EN, 0x1); + + rtw89_phy_write32_mask(rtwdev, R_P1_TSSI_TRK, B_P1_TSSI_OFT_EN, 0x0); + rtw89_phy_write32_mask(rtwdev, R_P1_TSSI_TRK, B_P1_TSSI_OFT_EN, 0x1); + } +} + +void rtw8852c_wifi_scan_notify(struct rtw89_dev *rtwdev, + bool scan_start, enum rtw89_phy_idx phy_idx) +{ + if (scan_start) + rtw8852c_tssi_default_txagc(rtwdev, phy_idx, true); + else + rtw8852c_tssi_default_txagc(rtwdev, phy_idx, false); +} diff --git a/drivers/net/wireless/realtek/rtw89/rtw8852c_rfk.h b/drivers/net/wireless/realtek/rtw89/rtw8852c_rfk.h index 4ce76ef4c5e60..a16ad9305ba42 100644 --- a/drivers/net/wireless/realtek/rtw89/rtw8852c_rfk.h +++ b/drivers/net/wireless/realtek/rtw89/rtw8852c_rfk.h @@ -8,6 +8,11 @@ #include "core.h" void rtw8852c_dack(struct rtw89_dev *rtwdev); +void rtw8852c_tssi(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy); +void rtw8852c_tssi_scan(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy); +void rtw8852c_tssi_cont_en_phyidx(struct rtw89_dev *rtwdev, bool en, u8 phy_idx); +void rtw8852c_wifi_scan_notify(struct rtw89_dev *rtwdev, bool scan_start, + enum rtw89_phy_idx phy_idx); void rtw8852c_set_channel_rf(struct rtw89_dev *rtwdev, struct rtw89_channel_params *param, enum rtw89_phy_idx phy_idx); From 30052c5a1c997da1c2523336b59d9a5eeb1905c9 Mon Sep 17 00:00:00 2001 From: Ping-Ke Shih Date: Tue, 3 May 2022 07:54:05 +0800 Subject: [PATCH 225/228] rtw89: 8852c: rfk: add RCK RCK is synchronize RC calibration. It needs to be triggered only once when interface is going to up. Signed-off-by: Ping-Ke Shih Signed-off-by: Kalle Valo Link: https://lore.kernel.org/r/20220502235408.15052-6-pkshih@realtek.com --- drivers/net/wireless/realtek/rtw89/rtw8852c.c | 1 + .../net/wireless/realtek/rtw89/rtw8852c_rfk.c | 43 +++++++++++++++++++ .../net/wireless/realtek/rtw89/rtw8852c_rfk.h | 1 + 3 files changed, 45 insertions(+) diff --git a/drivers/net/wireless/realtek/rtw89/rtw8852c.c b/drivers/net/wireless/realtek/rtw89/rtw8852c.c index 36406488e60e4..6db61e6df1ff0 100644 --- a/drivers/net/wireless/realtek/rtw89/rtw8852c.c +++ b/drivers/net/wireless/realtek/rtw89/rtw8852c.c @@ -1777,6 +1777,7 @@ static void rtw8852c_rfk_init(struct rtw89_dev *rtwdev) memset(mcc_info, 0, sizeof(*mcc_info)); rtw8852c_lck_init(rtwdev); + rtw8852c_rck(rtwdev); rtw8852c_dack(rtwdev); } diff --git a/drivers/net/wireless/realtek/rtw89/rtw8852c_rfk.c b/drivers/net/wireless/realtek/rtw89/rtw8852c_rfk.c index 974bb5794ad9f..4025245cd7e6b 100644 --- a/drivers/net/wireless/realtek/rtw89/rtw8852c_rfk.c +++ b/drivers/net/wireless/realtek/rtw89/rtw8852c_rfk.c @@ -470,6 +470,41 @@ static void _dac_cal(struct rtw89_dev *rtwdev, bool force) rtw89_debug(rtwdev, RTW89_DBG_RFK, "[DACK]DACK finish!!!\n"); } +static void _rck(struct rtw89_dev *rtwdev, enum rtw89_rf_path path) +{ + u32 rf_reg5, rck_val = 0; + u32 val; + int ret; + + rtw89_debug(rtwdev, RTW89_DBG_RFK, "[RCK] ====== S%d RCK ======\n", path); + + rf_reg5 = rtw89_read_rf(rtwdev, path, RR_RSV1, RFREG_MASK); + + rtw89_write_rf(rtwdev, path, RR_RSV1, RR_RSV1_RST, 0x0); + rtw89_write_rf(rtwdev, path, RR_MOD, RR_MOD_MASK, RR_MOD_V_RX); + + rtw89_debug(rtwdev, RTW89_DBG_RFK, "[RCK] RF0x00 = 0x%x\n", + rtw89_read_rf(rtwdev, path, RR_MOD, RFREG_MASK)); + + /* RCK trigger */ + rtw89_write_rf(rtwdev, path, RR_RCKC, RFREG_MASK, 0x00240); + + ret = read_poll_timeout_atomic(rtw89_read_rf, val, val, 2, 20, + false, rtwdev, path, 0x1c, BIT(3)); + if (ret) + rtw89_debug(rtwdev, RTW89_DBG_RFK, "[RCK] RCK timeout\n"); + + rck_val = rtw89_read_rf(rtwdev, path, RR_RCKC, RR_RCKC_CA); + rtw89_write_rf(rtwdev, path, RR_RCKC, RFREG_MASK, rck_val); + + rtw89_write_rf(rtwdev, path, RR_RSV1, RFREG_MASK, rf_reg5); + + rtw89_debug(rtwdev, RTW89_DBG_RFK, + "[RCK] RF 0x1b / 0x1c = 0x%x / 0x%x\n", + rtw89_read_rf(rtwdev, path, RR_RCKC, RFREG_MASK), + rtw89_read_rf(rtwdev, path, RR_RCKS, RFREG_MASK)); +} + static void _tssi_set_sys(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy, enum rtw89_rf_path path) { @@ -1619,6 +1654,14 @@ void rtw8852c_set_channel_rf(struct rtw89_dev *rtwdev, param->bandwidth); } +void rtw8852c_rck(struct rtw89_dev *rtwdev) +{ + u8 path; + + for (path = 0; path < 2; path++) + _rck(rtwdev, path); +} + void rtw8852c_dack(struct rtw89_dev *rtwdev) { u8 phy_map = rtw89_btc_phymap(rtwdev, RTW89_PHY_0, 0); diff --git a/drivers/net/wireless/realtek/rtw89/rtw8852c_rfk.h b/drivers/net/wireless/realtek/rtw89/rtw8852c_rfk.h index a16ad9305ba42..faacdf17a9286 100644 --- a/drivers/net/wireless/realtek/rtw89/rtw8852c_rfk.h +++ b/drivers/net/wireless/realtek/rtw89/rtw8852c_rfk.h @@ -7,6 +7,7 @@ #include "core.h" +void rtw8852c_rck(struct rtw89_dev *rtwdev); void rtw8852c_dack(struct rtw89_dev *rtwdev); void rtw8852c_tssi(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy); void rtw8852c_tssi_scan(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy); From ac91be9756168c7834ffb2ab5692c1dfbf2e957a Mon Sep 17 00:00:00 2001 From: Ping-Ke Shih Date: Tue, 3 May 2022 07:54:06 +0800 Subject: [PATCH 226/228] rtw89: 8852c: rfk: add RX DCK RX DCK is receiver DC calibration. Do this calibration when bringing up interface and going to run on AP channel. Signed-off-by: Ping-Ke Shih Signed-off-by: Kalle Valo Link: https://lore.kernel.org/r/20220502235408.15052-7-pkshih@realtek.com --- drivers/net/wireless/realtek/rtw89/reg.h | 9 ++- drivers/net/wireless/realtek/rtw89/rtw8852c.c | 2 + .../net/wireless/realtek/rtw89/rtw8852c_rfk.c | 67 +++++++++++++++++++ .../net/wireless/realtek/rtw89/rtw8852c_rfk.h | 1 + 4 files changed, 78 insertions(+), 1 deletion(-) diff --git a/drivers/net/wireless/realtek/rtw89/reg.h b/drivers/net/wireless/realtek/rtw89/reg.h index 028c881308237..c65598a7af268 100644 --- a/drivers/net/wireless/realtek/rtw89/reg.h +++ b/drivers/net/wireless/realtek/rtw89/reg.h @@ -3312,17 +3312,24 @@ #define RR_RXIQGEN_ATTL GENMASK(12, 8) #define RR_RXIQGEN_ATTH GENMASK(14, 13) #define RR_RXBB2 0x8f -#define RR_EN_TIA_IDA GENMASK(11, 10) #define RR_RXBB2_DAC_EN BIT(13) +#define RR_RXBB2_CKT BIT(12) +#define RR_EN_TIA_IDA GENMASK(11, 10) +#define RR_RXBB2_IDAC GENMASK(11, 9) +#define RR_RXBB2_EBW GENMASK(6, 5) #define RR_XALNA2 0x90 #define RR_XALNA2_SW GENMASK(1, 0) #define RR_DCK 0x92 +#define RR_DCK_DONE GENMASK(7, 5) #define RR_DCK_FINE BIT(1) #define RR_DCK_LV BIT(0) #define RR_DCK1 0x93 +#define RR_DCK1_CLR GENMASK(3, 0) #define RR_DCK1_SEL BIT(3) #define RR_DCK2 0x94 #define RR_DCK2_CYCLE GENMASK(7, 2) +#define RR_DCKC 0x95 +#define RR_DCKC_CHK BIT(3) #define RR_MIXER 0x9f #define RR_MIXER_GN GENMASK(4, 3) #define RR_XTALX2 0xb8 diff --git a/drivers/net/wireless/realtek/rtw89/rtw8852c.c b/drivers/net/wireless/realtek/rtw89/rtw8852c.c index 6db61e6df1ff0..cbf69670eafe0 100644 --- a/drivers/net/wireless/realtek/rtw89/rtw8852c.c +++ b/drivers/net/wireless/realtek/rtw89/rtw8852c.c @@ -1779,12 +1779,14 @@ static void rtw8852c_rfk_init(struct rtw89_dev *rtwdev) rtw8852c_rck(rtwdev); rtw8852c_dack(rtwdev); + rtw8852c_rx_dck(rtwdev, RTW89_PHY_0, false); } static void rtw8852c_rfk_channel(struct rtw89_dev *rtwdev) { enum rtw89_phy_idx phy_idx = RTW89_PHY_0; + rtw8852c_rx_dck(rtwdev, phy_idx, false); rtw8852c_tssi(rtwdev, phy_idx); rtw89_fw_h2c_rf_ntfy_mcc(rtwdev); } diff --git a/drivers/net/wireless/realtek/rtw89/rtw8852c_rfk.c b/drivers/net/wireless/realtek/rtw89/rtw8852c_rfk.c index 4025245cd7e6b..197d177494dab 100644 --- a/drivers/net/wireless/realtek/rtw89/rtw8852c_rfk.c +++ b/drivers/net/wireless/realtek/rtw89/rtw8852c_rfk.c @@ -505,6 +505,42 @@ static void _rck(struct rtw89_dev *rtwdev, enum rtw89_rf_path path) rtw89_read_rf(rtwdev, path, RR_RCKS, RFREG_MASK)); } +static void _rx_dck_toggle(struct rtw89_dev *rtwdev, u8 path) +{ + int ret; + u32 val; + + rtw89_write_rf(rtwdev, path, RR_DCK, RR_DCK_LV, 0x0); + rtw89_write_rf(rtwdev, path, RR_DCK, RR_DCK_LV, 0x1); + + ret = read_poll_timeout_atomic(rtw89_read_rf, val, val, + 2, 1000, false, rtwdev, path, 0x93, BIT(5)); + if (ret) + rtw89_warn(rtwdev, "[RX_DCK] S%d RXDCK timeout\n", path); + else + rtw89_debug(rtwdev, RTW89_DBG_RFK, "[RX_DCK] S%d RXDCK finish\n", path); + + rtw89_write_rf(rtwdev, path, RR_DCK, RR_DCK_LV, 0x0); +} + +static void _set_rx_dck(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy, u8 path, + bool is_afe) +{ + u8 res; + + rtw89_write_rf(rtwdev, path, RR_DCK1, RR_DCK1_CLR, 0x0); + + _rx_dck_toggle(rtwdev, path); + if (rtw89_read_rf(rtwdev, path, RR_DCKC, RR_DCKC_CHK) == 0) + return; + res = rtw89_read_rf(rtwdev, path, RR_DCK, RR_DCK_DONE); + if (res > 1) { + rtw89_write_rf(rtwdev, path, RR_RXBB2, RR_RXBB2_IDAC, res); + _rx_dck_toggle(rtwdev, path); + rtw89_write_rf(rtwdev, path, RR_RXBB2, RR_RXBB2_IDAC, 0x1); + } +} + static void _tssi_set_sys(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy, enum rtw89_rf_path path) { @@ -1671,6 +1707,37 @@ void rtw8852c_dack(struct rtw89_dev *rtwdev) rtw89_btc_ntfy_wl_rfk(rtwdev, phy_map, BTC_WRFKT_DACK, BTC_WRFK_STOP); } +#define RXDCK_VER_8852C 0xe + +void rtw8852c_rx_dck(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy, bool is_afe) +{ + u8 path, kpath; + u32 rf_reg5; + + kpath = _kpath(rtwdev, phy); + rtw89_debug(rtwdev, RTW89_DBG_RFK, + "[RX_DCK] ****** RXDCK Start (Ver: 0x%x, Cv: %d) ******\n", + RXDCK_VER_8852C, rtwdev->hal.cv); + + for (path = 0; path < 2; path++) { + rf_reg5 = rtw89_read_rf(rtwdev, path, RR_RSV1, RFREG_MASK); + if (!(kpath & BIT(path))) + continue; + + if (rtwdev->is_tssi_mode[path]) + rtw89_phy_write32_mask(rtwdev, R_P0_TSSI_TRK + (path << 13), + B_P0_TSSI_TRK_EN, 0x1); + rtw89_write_rf(rtwdev, path, RR_RSV1, RR_RSV1_RST, 0x0); + rtw89_write_rf(rtwdev, path, RR_MOD, RR_MOD_MASK, RR_MOD_V_RX); + _set_rx_dck(rtwdev, phy, path, is_afe); + rtw89_write_rf(rtwdev, path, RR_RSV1, RFREG_MASK, rf_reg5); + + if (rtwdev->is_tssi_mode[path]) + rtw89_phy_write32_mask(rtwdev, R_P0_TSSI_TRK + (path << 13), + B_P0_TSSI_TRK_EN, 0x0); + } +} + void rtw8852c_tssi(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy) { u32 i, path = RF_PATH_A, path_max = RF_PATH_NUM_8852C; diff --git a/drivers/net/wireless/realtek/rtw89/rtw8852c_rfk.h b/drivers/net/wireless/realtek/rtw89/rtw8852c_rfk.h index faacdf17a9286..fd07028a49640 100644 --- a/drivers/net/wireless/realtek/rtw89/rtw8852c_rfk.h +++ b/drivers/net/wireless/realtek/rtw89/rtw8852c_rfk.h @@ -9,6 +9,7 @@ void rtw8852c_rck(struct rtw89_dev *rtwdev); void rtw8852c_dack(struct rtw89_dev *rtwdev); +void rtw8852c_rx_dck(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy_idx, bool is_afe); void rtw8852c_tssi(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy); void rtw8852c_tssi_scan(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy); void rtw8852c_tssi_cont_en_phyidx(struct rtw89_dev *rtwdev, bool en, u8 phy_idx); From 2da8109d9885395b2439d8460cc7f616a9ccb3a8 Mon Sep 17 00:00:00 2001 From: Ping-Ke Shih Date: Tue, 3 May 2022 07:54:07 +0800 Subject: [PATCH 227/228] rtw89: 8852c: rfk: add IQK IQ signal calibration is a very important calibration to yield good RF performance. We do this calibration only if we are going to run on AP channel. During scanning phase, without this calibration RF performance is still acceptable because it transmits with low data rate at this phase. Signed-off-by: Ping-Ke Shih Signed-off-by: Kalle Valo Link: https://lore.kernel.org/r/20220502235408.15052-8-pkshih@realtek.com --- drivers/net/wireless/realtek/rtw89/core.h | 3 + drivers/net/wireless/realtek/rtw89/reg.h | 55 +- drivers/net/wireless/realtek/rtw89/rtw8852c.c | 1 + .../net/wireless/realtek/rtw89/rtw8852c_rfk.c | 1043 +++++++++++++++++ .../net/wireless/realtek/rtw89/rtw8852c_rfk.h | 1 + 5 files changed, 1099 insertions(+), 4 deletions(-) diff --git a/drivers/net/wireless/realtek/rtw89/core.h b/drivers/net/wireless/realtek/rtw89/core.h index 41d23711dc354..8fd719f93d6c7 100644 --- a/drivers/net/wireless/realtek/rtw89/core.h +++ b/drivers/net/wireless/realtek/rtw89/core.h @@ -2649,6 +2649,7 @@ struct rtw89_lck_info { struct rtw89_iqk_info { bool lok_cor_fail[RTW89_IQK_CHS_NR][RTW89_IQK_PATH_NR]; bool lok_fin_fail[RTW89_IQK_CHS_NR][RTW89_IQK_PATH_NR]; + bool lok_fail[RTW89_IQK_PATH_NR]; bool iqk_tx_fail[RTW89_IQK_CHS_NR][RTW89_IQK_PATH_NR]; bool iqk_rx_fail[RTW89_IQK_CHS_NR][RTW89_IQK_PATH_NR]; u32 iqk_fail_cnt; @@ -2677,6 +2678,8 @@ struct rtw89_iqk_info { u32 syn1to2; u8 iqk_mcc_ch[RTW89_IQK_CHS_NR][RTW89_IQK_PATH_NR]; u8 iqk_table_idx[RTW89_IQK_PATH_NR]; + u32 lok_idac[RTW89_IQK_CHS_NR][RTW89_IQK_PATH_NR]; + u32 lok_vbuf[RTW89_IQK_CHS_NR][RTW89_IQK_PATH_NR]; }; #define RTW89_DPK_RF_PATH 2 diff --git a/drivers/net/wireless/realtek/rtw89/reg.h b/drivers/net/wireless/realtek/rtw89/reg.h index c65598a7af268..120fc13520fcc 100644 --- a/drivers/net/wireless/realtek/rtw89/reg.h +++ b/drivers/net/wireless/realtek/rtw89/reg.h @@ -3202,6 +3202,7 @@ #define RR_MOD_V_DPK 0x5 #define RR_MOD_V_RXK1 0x6 #define RR_MOD_V_RXK2 0x7 +#define RR_MOD_NBW GENMASK(15, 14) #define RR_MOD_M_RXG GENMASK(13, 4) #define RR_MOD_M_RXBB GENMASK(9, 5) #define RR_MODOPT 0x01 @@ -3210,8 +3211,20 @@ #define RR_WLSEL_AG GENMASK(18, 16) #define RR_RSV1 0x05 #define RR_RSV1_RST BIT(0) +#define RR_BBDC 0x10005 +#define RR_BBDC_SEL BIT(0) #define RR_DTXLOK 0x08 #define RR_RSV2 0x09 +#define RR_LOKVB 0x0a +#define RR_LOKVB_COI GENMASK(19, 14) +#define RR_LOKVB_COQ GENMASK(9, 4) +#define RR_TXIG 0x11 +#define RR_TXIG_TG GENMASK(16, 12) +#define RR_TXIG_GR1 GENMASK(6, 4) +#define RR_TXIG_GR0 GENMASK(1, 0) +#define RR_CHTR 0x17 +#define RR_CHTR_MOD GENMASK(11, 10) +#define RR_CHTR_TXRX GENMASK(9, 0) #define RR_CFGCH 0x18 #define RR_CFGCH_V1 0x10018 #define RR_CFGCH_BAND1 GENMASK(17, 16) @@ -3242,6 +3255,8 @@ #define RR_RXKPLL_OFF GENMASK(5, 0) #define RR_RXKPLL_POW BIT(19) #define RR_RSV4 0x1f +#define RR_RSV4_AGH GENMASK(17, 16) +#define RR_RSV4_PLLCH GENMASK(9, 0) #define RR_RXK 0x20 #define RR_RXK_SEL2G BIT(8) #define RR_RXK_SEL5G BIT(7) @@ -3264,8 +3279,9 @@ #define RR_TXG2_ATT0 BIT(11) #define RR_BSPAD 0x54 #define RR_TXGA 0x55 -#define RR_TXGA_LOK_EN BIT(0) #define RR_TXGA_TRK_EN BIT(7) +#define RR_TXGA_LOK_EXT GENMASK(4, 0) +#define RR_TXGA_LOK_EN BIT(0) #define RR_GAINTX 0x56 #define RR_GAINTX_ALL GENMASK(15, 0) #define RR_GAINTX_PAD GENMASK(9, 5) @@ -3288,26 +3304,37 @@ #define RR_BIASA2 0x63 #define RR_BIASA2_LB GENMASK(4, 2) #define RR_TXATANK 0x64 +#define RR_TXATANK_LBSW2 GENMASK(17, 15) #define RR_TXATANK_LBSW GENMASK(16, 15) +#define RR_TXA2 0x65 +#define RR_TXA2_LDO GENMASK(19, 16) #define RR_TRXIQ 0x66 #define RR_RSV6 0x6d #define RR_TXPOW 0x7f -#define RR_TXPOW_TXG BIT(1) #define RR_TXPOW_TXA BIT(8) +#define RR_TXPOW_TXAS BIT(7) +#define RR_TXPOW_TXG BIT(1) #define RR_RXPOW 0x80 #define RR_RXPOW_IQK GENMASK(17, 16) #define RR_RXBB 0x83 +#define RR_RXBB_VOBUF GENMASK(15, 12) #define RR_RXBB_C2G GENMASK(16, 10) #define RR_RXBB_C1G GENMASK(9, 8) #define RR_RXBB_ATTR GENMASK(7, 4) #define RR_RXBB_ATTC GENMASK(2, 0) +#define RR_RXG 0x84 +#define RR_RXG_IQKMOD GENMASK(19, 16) #define RR_XGLNA2 0x85 #define RR_XGLNA2_SW GENMASK(1, 0) +#define RR_RXAE 0x89 +#define RR_RXAE_IQKMOD GENMASK(3, 0) #define RR_RXA 0x8a #define RR_RXA_DPK GENMASK(9, 8) #define RR_RXA2 0x8c -#define RR_RXA2_C2 GENMASK(9, 3) #define RR_RXA2_C1 GENMASK(12, 10) +#define RR_RXA2_C2 GENMASK(9, 3) +#define RR_RXA2_IATT GENMASK(7, 4) +#define RR_RXA2_ATT GENMASK(3, 0) #define RR_RXIQGEN 0x8d #define RR_RXIQGEN_ATTL GENMASK(12, 8) #define RR_RXIQGEN_ATTH GENMASK(14, 13) @@ -3336,6 +3363,8 @@ #define RR_MALSEL 0xbe #define RR_LCK_TRG 0xd3 #define RR_LCK_TRGSEL BIT(8) +#define RR_IQKPLL 0xdc +#define RR_IQKPLL_MOD GENMASK(9, 8) #define RR_RCKD 0xde #define RR_RCKD_POW GENMASK(19, 13) #define RR_RCKD_BW BIT(2) @@ -3559,6 +3588,11 @@ #define B_S0_ADDCK_Q GENMASK(19, 10) #define R_ADC_FIFO 0x20fc #define B_ADC_FIFO_RST GENMASK(31, 24) +#define B_ADC_FIFO_RXK GENMASK(31, 16) +#define B_ADC_FIFO_A3 BIT(28) +#define B_ADC_FIFO_A2 BIT(24) +#define B_ADC_FIFO_A1 BIT(20) +#define B_ADC_FIFO_A0 BIT(16) #define R_TXFIR0 0x2300 #define B_TXFIR_C01 GENMASK(23, 0) #define R_TXFIR2 0x2304 @@ -3727,6 +3761,8 @@ #define B_P0_NBIIDX_NOTCH_EN_V1 BIT(12) #define R_P1_MODE 0x4718 #define B_P1_MODE_SEL GENMASK(31, 30) +#define R_P0_AGC_CTL 0x4730 +#define B_P0_AGC_EN BIT(31) #define R_PATH1_LNA_INIT 0x473C #define B_PATH1_LNA_INIT_IDX_MSK GENMASK(26, 24) #define R_PATH1_TIA_INIT 0x4748 @@ -3776,6 +3812,8 @@ #define B_BK_FC0_INV_MSK_V1 GENMASK(18, 0) #define R_CCK_FC0_INV_V1 0x4A20 #define B_CCK_FC0_INV_MSK_V1 GENMASK(18, 0) +#define R_P1_AGC_CTL 0x4A9C +#define B_P1_AGC_EN BIT(31) #define R_PATH0_RXBB_V1 0x4AD4 #define B_PATH0_RXBB_MSK_V1 GENMASK(31, 0) #define R_PATH1_RXBB_V1 0x4AE0 @@ -3822,6 +3860,12 @@ #define B_CFO_COMP_VALID_BIT BIT(29) #define B_CFO_COMP_WEIGHT_MSK GENMASK(27, 24) #define B_CFO_COMP_VAL_MSK GENMASK(11, 0) +#define R_UPD_CLK 0x5670 +#define B_DAC_VAL BIT(31) +#define B_ACK_VAL GENMASK(30, 29) +#define B_DPD_DIS BIT(14) +#define B_DPD_GDIS BIT(13) +#define B_IQK_RFC_ON BIT(1) #define R_DPD_OFT_EN 0x5800 #define B_DPD_OFT_EN BIT(28) #define R_DPD_OFT_ADDR 0x5804 @@ -3932,8 +3976,9 @@ #define R_IQK_DIF2 0x8024 #define B_IQK_DIF2_RXPI GENMASK(19, 0) #define R_IQK_DIF4 0x802C -#define B_IQK_DIF4_TXT GENMASK(11, 0) #define B_IQK_DIF4_RXT GENMASK(27, 16) +#define B_IQK_DIF4_TXT GENMASK(11, 0) +#define IQK_DF4_TXT_8_25MHZ 0x021 #define R_IQK_CFG 0x8034 #define B_IQK_CFG_SET GENMASK(5, 4) #define R_TPG_MOD 0x806C @@ -3995,8 +4040,10 @@ #define R_CFIR_MAP 0x8150 #define R_CFIR_LUT 0x8154 #define B_CFIR_LUT_SEL BIT(8) +#define B_CFIR_LUT_SET BIT(4) #define B_CFIR_LUT_G3 BIT(3) #define B_CFIR_LUT_G2 BIT(2) +#define B_CFIR_LUT_GP_V1 GENMASK(2, 0) #define B_CFIR_LUT_GP GENMASK(1, 0) #define R_DPD_V1 0x81a0 #define R_DPD_CH0 0x81AC diff --git a/drivers/net/wireless/realtek/rtw89/rtw8852c.c b/drivers/net/wireless/realtek/rtw89/rtw8852c.c index cbf69670eafe0..0b722675aad42 100644 --- a/drivers/net/wireless/realtek/rtw89/rtw8852c.c +++ b/drivers/net/wireless/realtek/rtw89/rtw8852c.c @@ -1787,6 +1787,7 @@ static void rtw8852c_rfk_channel(struct rtw89_dev *rtwdev) enum rtw89_phy_idx phy_idx = RTW89_PHY_0; rtw8852c_rx_dck(rtwdev, phy_idx, false); + rtw8852c_iqk(rtwdev, phy_idx); rtw8852c_tssi(rtwdev, phy_idx); rtw89_fw_h2c_rf_ntfy_mcc(rtwdev); } diff --git a/drivers/net/wireless/realtek/rtw89/rtw8852c_rfk.c b/drivers/net/wireless/realtek/rtw89/rtw8852c_rfk.c index 197d177494dab..3108fa9cd5b20 100644 --- a/drivers/net/wireless/realtek/rtw89/rtw8852c_rfk.c +++ b/drivers/net/wireless/realtek/rtw89/rtw8852c_rfk.c @@ -21,6 +21,40 @@ static const u32 _tssi_de_mcs_80m_80m[RF_PATH_NUM_8852C] = {0x5850, 0x7850}; static const u32 _tssi_de_mcs_5m[RF_PATH_NUM_8852C] = {0x5828, 0x7828}; static const u32 _tssi_de_mcs_10m[RF_PATH_NUM_8852C] = {0x5830, 0x7830}; +static const u32 rtw8852c_backup_bb_regs[] = { + 0x813c, 0x8124, 0x8120, 0xc0d4, 0xc0d8, 0xc0e8, 0x823c, 0x8224, 0x8220, + 0xc1d4, 0xc1d8, 0xc1e8 +}; + +static const u32 rtw8852c_backup_rf_regs[] = { + 0xdf, 0x8f, 0x97, 0xa3, 0x5, 0x10005 +}; + +#define BACKUP_BB_REGS_NR ARRAY_SIZE(rtw8852c_backup_bb_regs) +#define BACKUP_RF_REGS_NR ARRAY_SIZE(rtw8852c_backup_rf_regs) + +#define RXK_GROUP_NR 4 +static const u32 _rxk_a6_idxrxgain[RXK_GROUP_NR] = {0x190, 0x196, 0x290, 0x316}; +static const u32 _rxk_a6_idxattc2[RXK_GROUP_NR] = {0x00, 0x0, 0x00, 0x00}; +static const u32 _rxk_a_idxrxgain[RXK_GROUP_NR] = {0x190, 0x198, 0x310, 0x318}; +static const u32 _rxk_a_idxattc2[RXK_GROUP_NR] = {0x00, 0x00, 0x00, 0x00}; +static const u32 _rxk_g_idxrxgain[RXK_GROUP_NR] = {0x252, 0x26c, 0x350, 0x360}; +static const u32 _rxk_g_idxattc2[RXK_GROUP_NR] = {0x00, 0x07, 0x00, 0x3}; + +#define TXK_GROUP_NR 3 +static const u32 _txk_a6_power_range[TXK_GROUP_NR] = {0x0, 0x0, 0x0}; +static const u32 _txk_a6_track_range[TXK_GROUP_NR] = {0x6, 0x7, 0x7}; +static const u32 _txk_a6_gain_bb[TXK_GROUP_NR] = {0x12, 0x09, 0x0e}; +static const u32 _txk_a6_itqt[TXK_GROUP_NR] = {0x12, 0x12, 0x12}; +static const u32 _txk_a_power_range[TXK_GROUP_NR] = {0x0, 0x0, 0x0}; +static const u32 _txk_a_track_range[TXK_GROUP_NR] = {0x5, 0x6, 0x7}; +static const u32 _txk_a_gain_bb[TXK_GROUP_NR] = {0x12, 0x09, 0x0e}; +static const u32 _txk_a_itqt[TXK_GROUP_NR] = {0x12, 0x12, 0x12}; +static const u32 _txk_g_power_range[TXK_GROUP_NR] = {0x0, 0x0, 0x0}; +static const u32 _txk_g_track_range[TXK_GROUP_NR] = {0x5, 0x6, 0x6}; +static const u32 _txk_g_gain_bb[TXK_GROUP_NR] = {0x0e, 0x0a, 0x0e}; +static const u32 _txk_g_itqt[TXK_GROUP_NR] = { 0x12, 0x12, 0x12}; + static u8 _kpath(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy_idx) { rtw89_debug(rtwdev, RTW89_DBG_RFK, "[RFK]dbcc_en: %x, PHY%d\n", @@ -35,6 +69,82 @@ static u8 _kpath(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy_idx) return RF_B; } +static void _rfk_backup_bb_reg(struct rtw89_dev *rtwdev, u32 backup_bb_reg_val[]) +{ + u32 i; + + for (i = 0; i < BACKUP_BB_REGS_NR; i++) { + backup_bb_reg_val[i] = + rtw89_phy_read32_mask(rtwdev, rtw8852c_backup_bb_regs[i], + MASKDWORD); + rtw89_debug(rtwdev, RTW89_DBG_RFK, + "[IQK]backup bb reg : %x, value =%x\n", + rtw8852c_backup_bb_regs[i], backup_bb_reg_val[i]); + } +} + +static void _rfk_backup_rf_reg(struct rtw89_dev *rtwdev, u32 backup_rf_reg_val[], + u8 rf_path) +{ + u32 i; + + for (i = 0; i < BACKUP_RF_REGS_NR; i++) { + backup_rf_reg_val[i] = + rtw89_read_rf(rtwdev, rf_path, + rtw8852c_backup_rf_regs[i], RFREG_MASK); + rtw89_debug(rtwdev, RTW89_DBG_RFK, + "[IQK]backup rf S%d reg : %x, value =%x\n", rf_path, + rtw8852c_backup_rf_regs[i], backup_rf_reg_val[i]); + } +} + +static void _rfk_restore_bb_reg(struct rtw89_dev *rtwdev, u32 backup_bb_reg_val[]) +{ + u32 i; + + for (i = 0; i < BACKUP_BB_REGS_NR; i++) { + rtw89_phy_write32_mask(rtwdev, rtw8852c_backup_bb_regs[i], + MASKDWORD, backup_bb_reg_val[i]); + rtw89_debug(rtwdev, RTW89_DBG_RFK, + "[IQK]restore bb reg : %x, value =%x\n", + rtw8852c_backup_bb_regs[i], backup_bb_reg_val[i]); + } +} + +static void _rfk_restore_rf_reg(struct rtw89_dev *rtwdev, u32 backup_rf_reg_val[], + u8 rf_path) +{ + u32 i; + + for (i = 0; i < BACKUP_RF_REGS_NR; i++) { + rtw89_write_rf(rtwdev, rf_path, rtw8852c_backup_rf_regs[i], + RFREG_MASK, backup_rf_reg_val[i]); + + rtw89_debug(rtwdev, RTW89_DBG_RFK, + "[IQK]restore rf S%d reg: %x, value =%x\n", rf_path, + rtw8852c_backup_rf_regs[i], backup_rf_reg_val[i]); + } +} + +static void _wait_rx_mode(struct rtw89_dev *rtwdev, u8 kpath) +{ + u8 path; + u32 rf_mode; + int ret; + + for (path = 0; path < RF_PATH_MAX; path++) { + if (!(kpath & BIT(path))) + continue; + + ret = read_poll_timeout_atomic(rtw89_read_rf, rf_mode, rf_mode != 2, + 2, 5000, false, rtwdev, path, 0x00, + RR_MOD_MASK); + rtw89_debug(rtwdev, RTW89_DBG_RFK, + "[RFK] Wait S%d to Rx mode!! (ret = %d)\n", + path, ret); + } +} + static void _dack_dump(struct rtw89_dev *rtwdev) { struct rtw89_dack_info *dack = &rtwdev->dack; @@ -470,6 +580,843 @@ static void _dac_cal(struct rtw89_dev *rtwdev, bool force) rtw89_debug(rtwdev, RTW89_DBG_RFK, "[DACK]DACK finish!!!\n"); } +#define RTW8852C_NCTL_VER 0xd +#define RTW8852C_IQK_VER 0x2a +#define RTW8852C_IQK_SS 2 +#define RTW8852C_IQK_THR_REK 8 +#define RTW8852C_IQK_CFIR_GROUP_NR 4 + +enum rtw8852c_iqk_type { + ID_TXAGC, + ID_G_FLOK_COARSE, + ID_A_FLOK_COARSE, + ID_G_FLOK_FINE, + ID_A_FLOK_FINE, + ID_FLOK_VBUFFER, + ID_TXK, + ID_RXAGC, + ID_RXK, + ID_NBTXK, + ID_NBRXK, +}; + +static void rtw8852c_disable_rxagc(struct rtw89_dev *rtwdev, u8 path, u8 en_rxgac) +{ + if (path == RF_PATH_A) + rtw89_phy_write32_mask(rtwdev, R_P0_AGC_CTL, B_P0_AGC_EN, en_rxgac); + else + rtw89_phy_write32_mask(rtwdev, R_P1_AGC_CTL, B_P1_AGC_EN, en_rxgac); +} + +static void _iqk_rxk_setting(struct rtw89_dev *rtwdev, u8 path) +{ + struct rtw89_iqk_info *iqk_info = &rtwdev->iqk; + + if (path == RF_PATH_A) + rtw89_phy_write32_mask(rtwdev, R_ADC_FIFO, B_ADC_FIFO_RXK, 0x0101); + else + rtw89_phy_write32_mask(rtwdev, R_ADC_FIFO, B_ADC_FIFO_RXK, 0x0202); + + switch (iqk_info->iqk_bw[path]) { + case RTW89_CHANNEL_WIDTH_20: + case RTW89_CHANNEL_WIDTH_40: + rtw89_phy_write32_mask(rtwdev, R_UPD_CLK + (path << 13), B_DPD_GDIS, 0x1); + rtw8852c_rxck_force(rtwdev, path, true, ADC_480M); + rtw89_phy_write32_mask(rtwdev, R_UPD_CLK + (path << 13), B_ACK_VAL, 0x0); + rtw89_phy_write32_mask(rtwdev, R_P0_CFCH_BW0 + (path << 8), B_P0_CFCH_BW0, 0x3); + rtw89_phy_write32_mask(rtwdev, R_P0_CFCH_BW1 + (path << 8), B_P0_CFCH_BW1, 0xf); + rtw89_write_rf(rtwdev, path, RR_RXBB2, RR_RXBB2_CKT, 0x1); + rtw89_phy_write32_mask(rtwdev, R_P0_NRBW + (path << 13), B_P0_NRBW_DBG, 0x1); + break; + case RTW89_CHANNEL_WIDTH_80: + rtw89_phy_write32_mask(rtwdev, R_UPD_CLK + (path << 13), B_DPD_GDIS, 0x1); + rtw8852c_rxck_force(rtwdev, path, true, ADC_960M); + rtw89_phy_write32_mask(rtwdev, R_UPD_CLK + (path << 13), B_ACK_VAL, 0x1); + rtw89_phy_write32_mask(rtwdev, R_P0_CFCH_BW0 + (path << 8), B_P0_CFCH_BW0, 0x2); + rtw89_phy_write32_mask(rtwdev, R_P0_CFCH_BW1 + (path << 8), B_P0_CFCH_BW1, 0xd); + rtw89_write_rf(rtwdev, path, RR_RXBB2, RR_RXBB2_CKT, 0x1); + rtw89_phy_write32_mask(rtwdev, R_P0_NRBW + (path << 13), B_P0_NRBW_DBG, 0x1); + break; + case RTW89_CHANNEL_WIDTH_160: + rtw89_phy_write32_mask(rtwdev, R_UPD_CLK + (path << 13), B_DPD_GDIS, 0x1); + rtw8852c_rxck_force(rtwdev, path, true, ADC_1920M); + rtw89_phy_write32_mask(rtwdev, R_UPD_CLK + (path << 13), B_ACK_VAL, 0x2); + rtw89_phy_write32_mask(rtwdev, R_P0_CFCH_BW0 + (path << 8), B_P0_CFCH_BW0, 0x1); + rtw89_phy_write32_mask(rtwdev, R_P0_CFCH_BW1 + (path << 8), B_P0_CFCH_BW1, 0xb); + rtw89_write_rf(rtwdev, path, RR_RXBB2, RR_RXBB2_CKT, 0x1); + rtw89_phy_write32_mask(rtwdev, R_P0_NRBW + (path << 13), B_P0_NRBW_DBG, 0x1); + break; + default: + break; + } + + rtw89_rfk_parser(rtwdev, &rtw8852c_iqk_rxk_cfg_defs_tbl); + + if (path == RF_PATH_A) + rtw89_phy_write32_mask(rtwdev, R_ADC_FIFO, B_ADC_FIFO_RXK, 0x1101); + else + rtw89_phy_write32_mask(rtwdev, R_ADC_FIFO, B_ADC_FIFO_RXK, 0x2202); +} + +static bool _iqk_check_cal(struct rtw89_dev *rtwdev, u8 path, u8 ktype) +{ + u32 tmp; + u32 val; + int ret; + + ret = read_poll_timeout_atomic(rtw89_phy_read32_mask, val, val == 0x55, + 1, 8200, false, rtwdev, 0xbff8, MASKBYTE0); + if (ret) + rtw89_debug(rtwdev, RTW89_DBG_RFK, "[IQK]IQK timeout!!!\n"); + + rtw89_phy_write32_clr(rtwdev, R_NCTL_N1, MASKBYTE0); + rtw89_debug(rtwdev, RTW89_DBG_RFK, "[IQK]S%x, ret=%d\n", path, ret); + tmp = rtw89_phy_read32_mask(rtwdev, R_NCTL_RPT, MASKDWORD); + rtw89_debug(rtwdev, RTW89_DBG_RFK, + "[IQK]S%x, type= %x, 0x8008 = 0x%x\n", path, ktype, tmp); + + return false; +} + +static bool _iqk_one_shot(struct rtw89_dev *rtwdev, + enum rtw89_phy_idx phy_idx, u8 path, u8 ktype) +{ + struct rtw89_iqk_info *iqk_info = &rtwdev->iqk; + u32 addr_rfc_ctl = R_UPD_CLK + (path << 13); + u32 iqk_cmd; + bool fail; + + switch (ktype) { + case ID_TXAGC: + iqk_cmd = 0x008 | (1 << (4 + path)) | (path << 1); + break; + case ID_A_FLOK_COARSE: + rtw89_phy_write32_mask(rtwdev, addr_rfc_ctl, 0x00000002, 0x1); + iqk_cmd = 0x008 | (1 << (4 + path)); + break; + case ID_G_FLOK_COARSE: + rtw89_phy_write32_mask(rtwdev, addr_rfc_ctl, 0x00000002, 0x1); + iqk_cmd = 0x108 | (1 << (4 + path)); + break; + case ID_A_FLOK_FINE: + rtw89_phy_write32_mask(rtwdev, addr_rfc_ctl, 0x00000002, 0x1); + iqk_cmd = 0x508 | (1 << (4 + path)); + break; + case ID_G_FLOK_FINE: + rtw89_phy_write32_mask(rtwdev, addr_rfc_ctl, 0x00000002, 0x1); + iqk_cmd = 0x208 | (1 << (4 + path)); + break; + case ID_FLOK_VBUFFER: + rtw89_phy_write32_mask(rtwdev, addr_rfc_ctl, 0x00000002, 0x1); + iqk_cmd = 0x308 | (1 << (4 + path)); + break; + case ID_TXK: + rtw89_phy_write32_mask(rtwdev, addr_rfc_ctl, 0x00000002, 0x0); + iqk_cmd = 0x008 | (1 << (4 + path)) | ((0x8 + iqk_info->iqk_bw[path]) << 8); + break; + case ID_RXAGC: + iqk_cmd = 0x508 | (1 << (4 + path)) | (path << 1); + break; + case ID_RXK: + rtw89_phy_write32_mask(rtwdev, addr_rfc_ctl, 0x00000002, 0x1); + iqk_cmd = 0x008 | (1 << (4 + path)) | ((0xc + iqk_info->iqk_bw[path]) << 8); + break; + case ID_NBTXK: + rtw89_phy_write32_mask(rtwdev, addr_rfc_ctl, 0x00000002, 0x0); + iqk_cmd = 0x408 | (1 << (4 + path)); + break; + case ID_NBRXK: + rtw89_phy_write32_mask(rtwdev, addr_rfc_ctl, 0x00000002, 0x1); + iqk_cmd = 0x608 | (1 << (4 + path)); + break; + default: + return false; + } + + rtw89_phy_write32_mask(rtwdev, R_NCTL_CFG, MASKDWORD, iqk_cmd + 1); + fsleep(15); + fail = _iqk_check_cal(rtwdev, path, ktype); + rtw89_phy_write32_mask(rtwdev, addr_rfc_ctl, 0x00000002, 0x0); + + return fail; +} + +static bool _rxk_group_sel(struct rtw89_dev *rtwdev, + enum rtw89_phy_idx phy_idx, u8 path) +{ + struct rtw89_iqk_info *iqk_info = &rtwdev->iqk; + bool fail; + u32 tmp; + u32 bkrf0; + u8 gp; + + bkrf0 = rtw89_read_rf(rtwdev, path, RR_MOD, RR_MOD_NBW); + if (path == RF_PATH_B) { + rtw89_write_rf(rtwdev, RF_PATH_B, RR_IQKPLL, RR_IQKPLL_MOD, 0x3); + tmp = rtw89_read_rf(rtwdev, RF_PATH_B, RR_CHTR, RR_CHTR_MOD); + rtw89_write_rf(rtwdev, RF_PATH_B, RR_RSV4, RR_RSV4_AGH, tmp); + tmp = rtw89_read_rf(rtwdev, RF_PATH_B, RR_CHTR, RR_CHTR_TXRX); + rtw89_write_rf(rtwdev, RF_PATH_B, RR_RSV4, RR_RSV4_PLLCH, tmp); + } + + switch (iqk_info->iqk_band[path]) { + case RTW89_BAND_2G: + default: + rtw89_write_rf(rtwdev, path, RR_MOD, RR_MOD_MASK, 0xc); + rtw89_write_rf(rtwdev, path, RR_MOD, RR_MOD_NBW, 0x0); + rtw89_write_rf(rtwdev, path, RR_RXG, RR_RXG_IQKMOD, 0x9); + break; + case RTW89_BAND_5G: + rtw89_write_rf(rtwdev, path, RR_MOD, RR_MOD_MASK, 0xc); + rtw89_write_rf(rtwdev, path, RR_MOD, RR_MOD_NBW, 0x0); + rtw89_write_rf(rtwdev, path, RR_RXAE, RR_RXAE_IQKMOD, 0x8); + break; + case RTW89_BAND_6G: + rtw89_write_rf(rtwdev, path, RR_MOD, RR_MOD_MASK, 0xc); + rtw89_write_rf(rtwdev, path, RR_MOD, RR_MOD_NBW, 0x0); + rtw89_write_rf(rtwdev, path, RR_RXAE, RR_RXAE_IQKMOD, 0x9); + break; + } + + fsleep(10); + + for (gp = 0; gp < RXK_GROUP_NR; gp++) { + switch (iqk_info->iqk_band[path]) { + case RTW89_BAND_2G: + default: + rtw89_write_rf(rtwdev, path, RR_MOD, RR_MOD_M_RXG, + _rxk_g_idxrxgain[gp]); + rtw89_write_rf(rtwdev, path, RR_RXBB, RR_RXBB_VOBUF, + _rxk_g_idxattc2[gp]); + break; + case RTW89_BAND_5G: + rtw89_write_rf(rtwdev, path, RR_MOD, RR_MOD_M_RXG, + _rxk_a_idxrxgain[gp]); + rtw89_write_rf(rtwdev, path, RR_RXA2, RR_RXA2_IATT, + _rxk_a_idxattc2[gp]); + break; + case RTW89_BAND_6G: + rtw89_write_rf(rtwdev, path, RR_MOD, RR_MOD_M_RXG, + _rxk_a6_idxrxgain[gp]); + rtw89_write_rf(rtwdev, path, RR_RXA2, RR_RXA2_IATT, + _rxk_a6_idxattc2[gp]); + break; + } + rtw89_phy_write32_mask(rtwdev, R_CFIR_LUT + (path << 8), + B_CFIR_LUT_SEL, 0x1); + rtw89_phy_write32_mask(rtwdev, R_CFIR_LUT + (path << 8), + B_CFIR_LUT_SET, 0x0); + rtw89_phy_write32_mask(rtwdev, R_CFIR_LUT + (path << 8), + B_CFIR_LUT_GP_V1, gp); + fail = _iqk_one_shot(rtwdev, phy_idx, path, ID_RXK); + } + + if (path == RF_PATH_B) + rtw89_write_rf(rtwdev, path, RR_IQKPLL, RR_IQKPLL_MOD, 0x0); + rtw89_write_rf(rtwdev, path, RR_MOD, RR_MOD_NBW, bkrf0); + + if (fail) { + iqk_info->nb_rxcfir[path] = 0x40000002; + iqk_info->is_wb_rxiqk[path] = false; + } else { + iqk_info->nb_rxcfir[path] = 0x40000000; + iqk_info->is_wb_rxiqk[path] = true; + } + + return false; +} + +static bool _iqk_nbrxk(struct rtw89_dev *rtwdev, + enum rtw89_phy_idx phy_idx, u8 path) +{ + struct rtw89_iqk_info *iqk_info = &rtwdev->iqk; + bool fail; + u32 tmp; + u32 bkrf0; + u8 gp = 0x2; + + bkrf0 = rtw89_read_rf(rtwdev, path, RR_MOD, RR_MOD_NBW); + if (path == RF_PATH_B) { + rtw89_write_rf(rtwdev, RF_PATH_B, RR_IQKPLL, RR_IQKPLL_MOD, 0x3); + tmp = rtw89_read_rf(rtwdev, RF_PATH_B, RR_CHTR, RR_CHTR_MOD); + rtw89_write_rf(rtwdev, RF_PATH_B, RR_RSV4, RR_RSV4_AGH, tmp); + tmp = rtw89_read_rf(rtwdev, RF_PATH_B, RR_CHTR, RR_CHTR_TXRX); + rtw89_write_rf(rtwdev, RF_PATH_B, RR_RSV4, RR_RSV4_PLLCH, tmp); + } + + switch (iqk_info->iqk_band[path]) { + case RTW89_BAND_2G: + default: + rtw89_write_rf(rtwdev, path, RR_MOD, RR_MOD_MASK, 0xc); + rtw89_write_rf(rtwdev, path, RR_MOD, RR_MOD_NBW, 0x0); + rtw89_write_rf(rtwdev, path, RR_RXG, RR_RXG_IQKMOD, 0x9); + break; + case RTW89_BAND_5G: + rtw89_write_rf(rtwdev, path, RR_MOD, RR_MOD_MASK, 0xc); + rtw89_write_rf(rtwdev, path, RR_MOD, RR_MOD_NBW, 0x0); + rtw89_write_rf(rtwdev, path, RR_RXAE, RR_RXAE_IQKMOD, 0x8); + break; + case RTW89_BAND_6G: + rtw89_write_rf(rtwdev, path, RR_MOD, RR_MOD_MASK, 0xc); + rtw89_write_rf(rtwdev, path, RR_MOD, RR_MOD_NBW, 0x0); + rtw89_write_rf(rtwdev, path, RR_RXAE, RR_RXAE_IQKMOD, 0x9); + break; + } + + fsleep(10); + + switch (iqk_info->iqk_band[path]) { + case RTW89_BAND_2G: + default: + rtw89_write_rf(rtwdev, path, RR_MOD, RR_MOD_M_RXG, _rxk_g_idxrxgain[gp]); + rtw89_write_rf(rtwdev, path, RR_RXBB, RR_RXBB_VOBUF, _rxk_g_idxattc2[gp]); + break; + case RTW89_BAND_5G: + rtw89_write_rf(rtwdev, path, RR_MOD, RR_MOD_M_RXG, _rxk_a_idxrxgain[gp]); + rtw89_write_rf(rtwdev, path, RR_RXA2, RR_RXA2_IATT, _rxk_a_idxattc2[gp]); + break; + case RTW89_BAND_6G: + rtw89_write_rf(rtwdev, path, RR_MOD, RR_MOD_M_RXG, _rxk_a6_idxrxgain[gp]); + rtw89_write_rf(rtwdev, path, RR_RXA2, RR_RXA2_IATT, _rxk_a6_idxattc2[gp]); + break; + } + + rtw89_phy_write32_mask(rtwdev, R_CFIR_LUT + (path << 8), B_CFIR_LUT_SEL, 0x1); + rtw89_phy_write32_mask(rtwdev, R_CFIR_LUT + (path << 8), B_CFIR_LUT_SET, 0x0); + rtw89_phy_write32_mask(rtwdev, R_CFIR_LUT + (path << 8), B_CFIR_LUT_GP_V1, gp); + fail = _iqk_one_shot(rtwdev, phy_idx, path, ID_RXK); + + if (path == RF_PATH_B) + rtw89_write_rf(rtwdev, path, RR_IQKPLL, RR_IQKPLL_MOD, 0x0); + + rtw89_write_rf(rtwdev, path, RR_MOD, RR_MOD_NBW, bkrf0); + + if (fail) + iqk_info->nb_rxcfir[path] = + rtw89_phy_read32_mask(rtwdev, R_RXIQC + (path << 8), + MASKDWORD) | 0x2; + else + iqk_info->nb_rxcfir[path] = 0x40000002; + + iqk_info->is_wb_rxiqk[path] = false; + return fail; +} + +static bool _txk_group_sel(struct rtw89_dev *rtwdev, + enum rtw89_phy_idx phy_idx, u8 path) +{ + struct rtw89_iqk_info *iqk_info = &rtwdev->iqk; + bool fail; + u8 gp; + + for (gp = 0; gp < TXK_GROUP_NR; gp++) { + switch (iqk_info->iqk_band[path]) { + case RTW89_BAND_2G: + rtw89_write_rf(rtwdev, path, RR_TXIG, RR_TXIG_GR0, + _txk_g_power_range[gp]); + rtw89_write_rf(rtwdev, path, RR_TXIG, RR_TXIG_GR1, + _txk_g_track_range[gp]); + rtw89_write_rf(rtwdev, path, RR_TXIG, RR_TXIG_TG, + _txk_g_gain_bb[gp]); + rtw89_phy_write32_mask(rtwdev, + R_KIP_IQP + (path << 8), + MASKDWORD, _txk_g_itqt[gp]); + break; + case RTW89_BAND_5G: + rtw89_write_rf(rtwdev, path, RR_TXIG, RR_TXIG_GR0, + _txk_a_power_range[gp]); + rtw89_write_rf(rtwdev, path, RR_TXIG, RR_TXIG_GR1, + _txk_a_track_range[gp]); + rtw89_write_rf(rtwdev, path, RR_TXIG, RR_TXIG_TG, + _txk_a_gain_bb[gp]); + rtw89_phy_write32_mask(rtwdev, + R_KIP_IQP + (path << 8), + MASKDWORD, _txk_a_itqt[gp]); + break; + case RTW89_BAND_6G: + rtw89_write_rf(rtwdev, path, RR_TXIG, RR_TXIG_GR0, + _txk_a6_power_range[gp]); + rtw89_write_rf(rtwdev, path, RR_TXIG, RR_TXIG_GR1, + _txk_a6_track_range[gp]); + rtw89_write_rf(rtwdev, path, RR_TXIG, RR_TXIG_TG, + _txk_a6_gain_bb[gp]); + rtw89_phy_write32_mask(rtwdev, + R_KIP_IQP + (path << 8), + MASKDWORD, _txk_a6_itqt[gp]); + break; + default: + break; + } + rtw89_phy_write32_mask(rtwdev, R_CFIR_LUT + (path << 8), + B_CFIR_LUT_SEL, 0x1); + rtw89_phy_write32_mask(rtwdev, R_CFIR_LUT + (path << 8), + B_CFIR_LUT_SET, 0x1); + rtw89_phy_write32_mask(rtwdev, R_CFIR_LUT + (path << 8), + B_CFIR_LUT_G2, 0x0); + rtw89_phy_write32_mask(rtwdev, R_CFIR_LUT + (path << 8), + B_CFIR_LUT_GP, gp + 1); + rtw89_phy_write32_mask(rtwdev, R_IQK_DIF4, B_IQK_DIF4_TXT, 0x00b); + rtw89_phy_write32_mask(rtwdev, R_NCTL_N1, B_NCTL_N1_CIP, 0x00); + fail = _iqk_one_shot(rtwdev, phy_idx, path, ID_TXK); + } + + if (fail) { + iqk_info->nb_txcfir[path] = 0x40000002; + iqk_info->is_wb_txiqk[path] = false; + } else { + iqk_info->nb_txcfir[path] = 0x40000000; + iqk_info->is_wb_txiqk[path] = true; + } + + return fail; +} + +static bool _iqk_nbtxk(struct rtw89_dev *rtwdev, + enum rtw89_phy_idx phy_idx, u8 path) +{ + struct rtw89_iqk_info *iqk_info = &rtwdev->iqk; + bool fail; + u8 gp = 0x2; + + switch (iqk_info->iqk_band[path]) { + case RTW89_BAND_2G: + rtw89_write_rf(rtwdev, path, RR_TXIG, RR_TXIG_GR0, _txk_g_power_range[gp]); + rtw89_write_rf(rtwdev, path, RR_TXIG, RR_TXIG_GR1, _txk_g_track_range[gp]); + rtw89_write_rf(rtwdev, path, RR_TXIG, RR_TXIG_TG, _txk_g_gain_bb[gp]); + rtw89_phy_write32_mask(rtwdev, R_KIP_IQP + (path << 8), + MASKDWORD, _txk_g_itqt[gp]); + break; + case RTW89_BAND_5G: + rtw89_write_rf(rtwdev, path, RR_TXIG, RR_TXIG_GR0, _txk_a_power_range[gp]); + rtw89_write_rf(rtwdev, path, RR_TXIG, RR_TXIG_GR1, _txk_a_track_range[gp]); + rtw89_write_rf(rtwdev, path, RR_TXIG, RR_TXIG_TG, _txk_a_gain_bb[gp]); + rtw89_phy_write32_mask(rtwdev, R_KIP_IQP + (path << 8), + MASKDWORD, _txk_a_itqt[gp]); + break; + case RTW89_BAND_6G: + rtw89_write_rf(rtwdev, path, RR_TXIG, RR_TXIG_GR0, _txk_a6_power_range[gp]); + rtw89_write_rf(rtwdev, path, RR_TXIG, RR_TXIG_GR1, _txk_a6_track_range[gp]); + rtw89_write_rf(rtwdev, path, RR_TXIG, RR_TXIG_TG, _txk_a6_gain_bb[gp]); + rtw89_phy_write32_mask(rtwdev, R_KIP_IQP + (path << 8), + MASKDWORD, _txk_a6_itqt[gp]); + break; + default: + break; + } + + rtw89_phy_write32_mask(rtwdev, R_CFIR_LUT + (path << 8), B_CFIR_LUT_SEL, 0x1); + rtw89_phy_write32_mask(rtwdev, R_CFIR_LUT + (path << 8), B_CFIR_LUT_SET, 0x1); + rtw89_phy_write32_mask(rtwdev, R_CFIR_LUT + (path << 8), B_CFIR_LUT_G2, 0x0); + rtw89_phy_write32_mask(rtwdev, R_CFIR_LUT + (path << 8), B_CFIR_LUT_GP, gp + 1); + rtw89_phy_write32_mask(rtwdev, R_IQK_DIF4, B_IQK_DIF4_TXT, 0x00b); + rtw89_phy_write32_mask(rtwdev, R_NCTL_N1, B_NCTL_N1_CIP, 0x00); + fail = _iqk_one_shot(rtwdev, phy_idx, path, ID_NBTXK); + + if (!fail) + iqk_info->nb_txcfir[path] = + rtw89_phy_read32_mask(rtwdev, R_TXIQC + (path << 8), + MASKDWORD) | 0x2; + else + iqk_info->nb_txcfir[path] = 0x40000002; + + iqk_info->is_wb_txiqk[path] = false; + + return fail; +} + +static bool _lok_finetune_check(struct rtw89_dev *rtwdev, u8 path) +{ + struct rtw89_mcc_info *mcc_info = &rtwdev->mcc; + struct rtw89_iqk_info *iqk_info = &rtwdev->iqk; + u8 idx = mcc_info->table_idx; + bool is_fail1, is_fail2; + u32 val; + u32 core_i; + u32 core_q; + u32 vbuff_i; + u32 vbuff_q; + + rtw89_debug(rtwdev, RTW89_DBG_RFK, "[IQK]===>%s\n", __func__); + val = rtw89_read_rf(rtwdev, path, RR_TXMO, RFREG_MASK); + core_i = FIELD_GET(RR_TXMO_COI, val); + core_q = FIELD_GET(RR_TXMO_COQ, val); + + if (core_i < 0x2 || core_i > 0x1d || core_q < 0x2 || core_q > 0x1d) + is_fail1 = true; + else + is_fail1 = false; + + iqk_info->lok_idac[idx][path] = val; + + val = rtw89_read_rf(rtwdev, path, RR_LOKVB, RFREG_MASK); + vbuff_i = FIELD_GET(RR_LOKVB_COI, val); + vbuff_q = FIELD_GET(RR_LOKVB_COQ, val); + + if (vbuff_i < 0x2 || vbuff_i > 0x3d || vbuff_q < 0x2 || vbuff_q > 0x3d) + is_fail2 = true; + else + is_fail2 = false; + + iqk_info->lok_vbuf[idx][path] = val; + + return is_fail1 || is_fail2; +} + +static bool _iqk_lok(struct rtw89_dev *rtwdev, + enum rtw89_phy_idx phy_idx, u8 path) +{ + struct rtw89_iqk_info *iqk_info = &rtwdev->iqk; + u8 tmp_id = 0x0; + bool fail = false; + bool tmp = false; + + /* Step 0: Init RF gain & tone idx= 8.25Mhz */ + rtw89_phy_write32_mask(rtwdev, R_IQK_DIF4, B_IQK_DIF4_TXT, IQK_DF4_TXT_8_25MHZ); + + /* Step 1 START: _lok_coarse_fine_wi_swap */ + switch (iqk_info->iqk_band[path]) { + case RTW89_BAND_2G: + rtw89_write_rf(rtwdev, path, RR_TXIG, RR_TXIG_TG, 0x6); + rtw89_phy_write32_mask(rtwdev, R_KIP_IQP + (path << 8), + B_KIP_IQP_IQSW, 0x9); + tmp_id = ID_G_FLOK_COARSE; + break; + case RTW89_BAND_5G: + rtw89_write_rf(rtwdev, path, RR_TXIG, RR_TXIG_TG, 0x6); + rtw89_phy_write32_mask(rtwdev, R_KIP_IQP + (path << 8), + B_KIP_IQP_IQSW, 0x9); + tmp_id = ID_A_FLOK_COARSE; + break; + case RTW89_BAND_6G: + rtw89_write_rf(rtwdev, path, RR_TXIG, RR_TXIG_TG, 0x6); + rtw89_phy_write32_mask(rtwdev, R_KIP_IQP + (path << 8), + B_KIP_IQP_IQSW, 0x9); + tmp_id = ID_A_FLOK_COARSE; + break; + default: + break; + } + tmp = _iqk_one_shot(rtwdev, phy_idx, path, tmp_id); + iqk_info->lok_cor_fail[0][path] = tmp; + + /* Step 2 */ + switch (iqk_info->iqk_band[path]) { + case RTW89_BAND_2G: + rtw89_write_rf(rtwdev, path, RR_TXIG, RR_TXIG_TG, 0x12); + rtw89_phy_write32_mask(rtwdev, R_KIP_IQP + (path << 8), + B_KIP_IQP_IQSW, 0x1b); + break; + case RTW89_BAND_5G: + rtw89_write_rf(rtwdev, path, RR_TXIG, RR_TXIG_TG, 0x12); + rtw89_phy_write32_mask(rtwdev, R_KIP_IQP + (path << 8), + B_KIP_IQP_IQSW, 0x1b); + break; + case RTW89_BAND_6G: + rtw89_write_rf(rtwdev, path, RR_TXIG, RR_TXIG_TG, 0x12); + rtw89_phy_write32_mask(rtwdev, R_KIP_IQP + (path << 8), + B_KIP_IQP_IQSW, 0x1b); + break; + default: + break; + } + tmp = _iqk_one_shot(rtwdev, phy_idx, path, ID_FLOK_VBUFFER); + + /* Step 3 */ + switch (iqk_info->iqk_band[path]) { + case RTW89_BAND_2G: + rtw89_write_rf(rtwdev, path, RR_TXIG, RR_TXIG_TG, 0x6); + rtw89_phy_write32_mask(rtwdev, R_KIP_IQP + (path << 8), + B_KIP_IQP_IQSW, 0x9); + tmp_id = ID_G_FLOK_FINE; + break; + case RTW89_BAND_5G: + rtw89_write_rf(rtwdev, path, RR_TXIG, RR_TXIG_TG, 0x6); + rtw89_phy_write32_mask(rtwdev, R_KIP_IQP + (path << 8), + B_KIP_IQP_IQSW, 0x9); + tmp_id = ID_A_FLOK_FINE; + break; + case RTW89_BAND_6G: + rtw89_write_rf(rtwdev, path, RR_TXIG, RR_TXIG_TG, 0x6); + rtw89_phy_write32_mask(rtwdev, R_KIP_IQP + (path << 8), + B_KIP_IQP_IQSW, 0x9); + tmp_id = ID_A_FLOK_FINE; + break; + default: + break; + } + tmp = _iqk_one_shot(rtwdev, phy_idx, path, tmp_id); + iqk_info->lok_fin_fail[0][path] = tmp; + + /* Step 4 large rf gain */ + switch (iqk_info->iqk_band[path]) { + case RTW89_BAND_2G: + default: + rtw89_write_rf(rtwdev, path, RR_TXIG, RR_TXIG_TG, 0x12); + rtw89_phy_write32_mask(rtwdev, R_KIP_IQP + (path << 8), + B_KIP_IQP_IQSW, 0x1b); + break; + case RTW89_BAND_5G: + rtw89_write_rf(rtwdev, path, RR_TXIG, RR_TXIG_TG, 0x12); + rtw89_phy_write32_mask(rtwdev, R_KIP_IQP + (path << 8), + B_KIP_IQP_IQSW, 0x1b); + break; + case RTW89_BAND_6G: + rtw89_write_rf(rtwdev, path, RR_TXIG, RR_TXIG_TG, 0x12); + rtw89_phy_write32_mask(rtwdev, R_KIP_IQP + (path << 8), + B_KIP_IQP_IQSW, 0x1b); + break; + } + tmp = _iqk_one_shot(rtwdev, phy_idx, path, ID_FLOK_VBUFFER); + fail = _lok_finetune_check(rtwdev, path); + + return fail; +} + +static void _iqk_txk_setting(struct rtw89_dev *rtwdev, u8 path) +{ + struct rtw89_iqk_info *iqk_info = &rtwdev->iqk; + + switch (iqk_info->iqk_band[path]) { + case RTW89_BAND_2G: + default: + rtw89_write_rf(rtwdev, path, RR_TXG1, RR_TXG1_ATT2, 0x0); + rtw89_write_rf(rtwdev, path, RR_TXG1, RR_TXG1_ATT1, 0x0); + rtw89_write_rf(rtwdev, path, RR_TXG2, RR_TXG2_ATT0, 0x1); + rtw89_write_rf(rtwdev, path, RR_TXA2, RR_TXA2_LDO, 0xf); + rtw89_write_rf(rtwdev, path, RR_TXGA, RR_TXGA_LOK_EXT, 0x0); + rtw89_write_rf(rtwdev, path, RR_LUTWE, RR_LUTWE_LOK, 0x1); + rtw89_write_rf(rtwdev, path, RR_MOD, RFREG_MASK, + 0x403e0 | iqk_info->syn1to2); + fsleep(10); + rtw89_write_rf(rtwdev, path, RR_TXIG, RR_TXIG_GR0, 0x0); + rtw89_write_rf(rtwdev, path, RR_TXIG, RR_TXIG_GR1, 0x6); + break; + case RTW89_BAND_5G: + rtw89_write_rf(rtwdev, path, RR_TXATANK, RR_TXATANK_LBSW2, 0x0); + rtw89_write_rf(rtwdev, path, RR_TXPOW, RR_TXPOW_TXAS, 0x1); + rtw89_write_rf(rtwdev, path, RR_TXA2, RR_TXA2_LDO, 0xf); + rtw89_write_rf(rtwdev, path, RR_TXGA, RR_TXGA_LOK_EXT, 0x0); + rtw89_write_rf(rtwdev, path, RR_LUTWE, RR_LUTWE_LOK, 0x1); + rtw89_write_rf(rtwdev, path, RR_MOD, RFREG_MASK, + 0x403e0 | iqk_info->syn1to2); + fsleep(10); + rtw89_write_rf(rtwdev, path, RR_TXIG, RR_TXIG_GR0, 0x0); + rtw89_write_rf(rtwdev, path, RR_TXIG, RR_TXIG_GR1, 0x6); + break; + case RTW89_BAND_6G: + rtw89_write_rf(rtwdev, path, RR_TXATANK, RR_TXATANK_LBSW2, 0x0); + rtw89_write_rf(rtwdev, path, RR_TXPOW, RR_TXPOW_TXAS, 0x1); + rtw89_write_rf(rtwdev, path, RR_TXA2, RR_TXA2_LDO, 0xf); + rtw89_write_rf(rtwdev, path, RR_TXGA, RR_TXGA_LOK_EXT, 0x0); + rtw89_write_rf(rtwdev, path, RR_LUTWE, RR_LUTWE_LOK, 0x1); + rtw89_write_rf(rtwdev, path, RR_MOD, RFREG_MASK, + 0x403e0 | iqk_info->syn1to2); + fsleep(10); + rtw89_write_rf(rtwdev, path, RR_TXIG, RR_TXIG_GR0, 0x0); + rtw89_write_rf(rtwdev, path, RR_TXIG, RR_TXIG_GR1, 0x6); + break; + } +} + +static void _iqk_info_iqk(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy_idx, + u8 path) +{ + struct rtw89_iqk_info *iqk_info = &rtwdev->iqk; + u32 tmp; + bool flag; + + iqk_info->thermal[path] = + ewma_thermal_read(&rtwdev->phystat.avg_thermal[path]); + iqk_info->thermal_rek_en = false; + rtw89_debug(rtwdev, RTW89_DBG_RFK, "[IQK]S%d_thermal = %d\n", path, + iqk_info->thermal[path]); + rtw89_debug(rtwdev, RTW89_DBG_RFK, "[IQK]S%d_LOK_COR_fail= %d\n", path, + iqk_info->lok_cor_fail[0][path]); + rtw89_debug(rtwdev, RTW89_DBG_RFK, "[IQK]S%d_LOK_FIN_fail= %d\n", path, + iqk_info->lok_fin_fail[0][path]); + rtw89_debug(rtwdev, RTW89_DBG_RFK, "[IQK]S%d_TXIQK_fail = %d\n", path, + iqk_info->iqk_tx_fail[0][path]); + rtw89_debug(rtwdev, RTW89_DBG_RFK, "[IQK]S%d_RXIQK_fail= %d,\n", path, + iqk_info->iqk_rx_fail[0][path]); + + flag = iqk_info->lok_cor_fail[0][path]; + rtw89_phy_write32_mask(rtwdev, R_IQKINF, B_IQKINF_FCOR << (path * 4), flag); + flag = iqk_info->lok_fin_fail[0][path]; + rtw89_phy_write32_mask(rtwdev, R_IQKINF, B_IQKINF_FFIN << (path * 4), flag); + flag = iqk_info->iqk_tx_fail[0][path]; + rtw89_phy_write32_mask(rtwdev, R_IQKINF, B_IQKINF_FTX << (path * 4), flag); + flag = iqk_info->iqk_rx_fail[0][path]; + rtw89_phy_write32_mask(rtwdev, R_IQKINF, B_IQKINF_F_RX << (path * 4), flag); + + tmp = rtw89_phy_read32_mask(rtwdev, R_IQK_RES + (path << 8), MASKDWORD); + iqk_info->bp_iqkenable[path] = tmp; + tmp = rtw89_phy_read32_mask(rtwdev, R_TXIQC + (path << 8), MASKDWORD); + iqk_info->bp_txkresult[path] = tmp; + tmp = rtw89_phy_read32_mask(rtwdev, R_RXIQC + (path << 8), MASKDWORD); + iqk_info->bp_rxkresult[path] = tmp; + + rtw89_phy_write32_mask(rtwdev, R_IQKINF2, B_IQKINF2_KCNT, + iqk_info->iqk_times); + + tmp = rtw89_phy_read32_mask(rtwdev, R_IQKINF, B_IQKINF_FAIL << (path * 4)); + if (tmp != 0x0) + iqk_info->iqk_fail_cnt++; + rtw89_phy_write32_mask(rtwdev, R_IQKINF2, B_IQKINF2_FCNT << (path * 4), + iqk_info->iqk_fail_cnt); +} + +static void _iqk_by_path(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy_idx, u8 path) +{ + struct rtw89_iqk_info *iqk_info = &rtwdev->iqk; + + _iqk_txk_setting(rtwdev, path); + iqk_info->lok_fail[path] = _iqk_lok(rtwdev, phy_idx, path); + + if (iqk_info->is_nbiqk) + iqk_info->iqk_tx_fail[0][path] = _iqk_nbtxk(rtwdev, phy_idx, path); + else + iqk_info->iqk_tx_fail[0][path] = _txk_group_sel(rtwdev, phy_idx, path); + + _iqk_rxk_setting(rtwdev, path); + if (iqk_info->is_nbiqk) + iqk_info->iqk_rx_fail[0][path] = _iqk_nbrxk(rtwdev, phy_idx, path); + else + iqk_info->iqk_rx_fail[0][path] = _rxk_group_sel(rtwdev, phy_idx, path); + + _iqk_info_iqk(rtwdev, phy_idx, path); +} + +static void _iqk_get_ch_info(struct rtw89_dev *rtwdev, + enum rtw89_phy_idx phy, u8 path) +{ + struct rtw89_iqk_info *iqk_info = &rtwdev->iqk; + struct rtw89_hal *hal = &rtwdev->hal; + + rtw89_debug(rtwdev, RTW89_DBG_RFK, "[IQK]===>%s\n", __func__); + + iqk_info->iqk_band[path] = hal->current_band_type; + iqk_info->iqk_bw[path] = hal->current_band_width; + iqk_info->iqk_ch[path] = hal->current_channel; + + rtw89_debug(rtwdev, RTW89_DBG_RFK, + "[IQK]iqk_info->iqk_band[%x] = 0x%x\n", path, + iqk_info->iqk_band[path]); + rtw89_debug(rtwdev, RTW89_DBG_RFK, "[IQK]iqk_info->iqk_bw[%x] = 0x%x\n", + path, iqk_info->iqk_bw[path]); + rtw89_debug(rtwdev, RTW89_DBG_RFK, "[IQK]iqk_info->iqk_ch[%x] = 0x%x\n", + path, iqk_info->iqk_ch[path]); + rtw89_debug(rtwdev, RTW89_DBG_RFK, + "[IQK]S%d (PHY%d): / DBCC %s/ %s/ CH%d/ %s\n", path, phy, + rtwdev->dbcc_en ? "on" : "off", + iqk_info->iqk_band[path] == 0 ? "2G" : + iqk_info->iqk_band[path] == 1 ? "5G" : "6G", + iqk_info->iqk_ch[path], + iqk_info->iqk_bw[path] == 0 ? "20M" : + iqk_info->iqk_bw[path] == 1 ? "40M" : "80M"); + if (!rtwdev->dbcc_en) + iqk_info->syn1to2 = 0x1; + else + iqk_info->syn1to2 = 0x3; + + rtw89_phy_write32_mask(rtwdev, R_IQKINF, B_IQKINF_VER, RTW8852C_IQK_VER); + rtw89_phy_write32_mask(rtwdev, R_IQKCH, B_IQKCH_BAND << (path * 16), + iqk_info->iqk_band[path]); + rtw89_phy_write32_mask(rtwdev, R_IQKCH, B_IQKCH_BW << (path * 16), + iqk_info->iqk_bw[path]); + rtw89_phy_write32_mask(rtwdev, R_IQKCH, B_IQKCH_CH << (path * 16), + iqk_info->iqk_ch[path]); + + rtw89_phy_write32_mask(rtwdev, R_IQKINF2, B_IQKINF2_NCTLV, RTW8852C_NCTL_VER); +} + +static void _iqk_start_iqk(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy_idx, + u8 path) +{ + _iqk_by_path(rtwdev, phy_idx, path); +} + +static void _iqk_restore(struct rtw89_dev *rtwdev, u8 path) +{ + struct rtw89_iqk_info *iqk_info = &rtwdev->iqk; + bool fail; + + rtw89_phy_write32_mask(rtwdev, R_TXIQC + (path << 8), MASKDWORD, + iqk_info->nb_txcfir[path]); + rtw89_phy_write32_mask(rtwdev, R_RXIQC + (path << 8), MASKDWORD, + iqk_info->nb_rxcfir[path]); + rtw89_phy_write32_mask(rtwdev, R_NCTL_CFG, MASKDWORD, + 0x00001219 + (path << 4)); + fsleep(200); + fail = _iqk_check_cal(rtwdev, path, 0x12); + rtw89_debug(rtwdev, RTW89_DBG_RFK, "[IQK] restore fail = %x\n", fail); + + rtw89_phy_write32_mask(rtwdev, R_NCTL_N1, B_NCTL_N1_CIP, 0x00); + rtw89_phy_write32_mask(rtwdev, R_NCTL_RPT, MASKDWORD, 0x00000000); + rtw89_phy_write32_mask(rtwdev, R_KIP_SYSCFG, MASKDWORD, 0x80000000); + + rtw89_write_rf(rtwdev, path, RR_LUTWE, RR_LUTWE_LOK, 0x0); + rtw89_write_rf(rtwdev, path, RR_MOD, RR_MOD_MASK, RR_MOD_V_RX); + rtw89_write_rf(rtwdev, path, RR_RSV1, RR_RSV1_RST, 0x1); +} + +static void _iqk_afebb_restore(struct rtw89_dev *rtwdev, + enum rtw89_phy_idx phy_idx, u8 path) +{ + rtw89_rfk_parser_by_cond(rtwdev, path == RF_PATH_A, + &rtw8852c_iqk_afebb_restore_defs_a_tbl, + &rtw8852c_iqk_afebb_restore_defs_b_tbl); + + rtw8852c_disable_rxagc(rtwdev, path, 0x1); +} + +static void _iqk_preset(struct rtw89_dev *rtwdev, u8 path) +{ + struct rtw89_mcc_info *mcc_info = &rtwdev->mcc; + u8 idx = 0; + + idx = mcc_info->table_idx; + rtw89_phy_write32_mask(rtwdev, R_COEF_SEL + (path << 8), B_COEF_SEL_IQC, idx); + rtw89_phy_write32_mask(rtwdev, R_CFIR_LUT + (path << 8), B_CFIR_LUT_G3, idx); + rtw89_write_rf(rtwdev, path, RR_RSV1, RR_RSV1_RST, 0x0); + rtw89_phy_write32_mask(rtwdev, R_NCTL_RPT, MASKDWORD, 0x00000080); + rtw89_phy_write32_mask(rtwdev, R_KIP_SYSCFG, MASKDWORD, 0x81ff010a); +} + +static void _iqk_macbb_setting(struct rtw89_dev *rtwdev, + enum rtw89_phy_idx phy_idx, u8 path) +{ + rtw89_debug(rtwdev, RTW89_DBG_RFK, "[IQK]===> %s\n", __func__); + + /* 01_BB_AFE_for DPK_S0_20210820 */ + rtw89_write_rf(rtwdev, path, RR_BBDC, RR_BBDC_SEL, 0x0); + rtw89_phy_write32_mask(rtwdev, R_ADC_FIFO, B_ADC_FIFO_A0 << path, 0x1); + rtw89_phy_write32_mask(rtwdev, R_ADC_FIFO, B_ADC_FIFO_A1 << path, 0x0); + rtw89_phy_write32_mask(rtwdev, R_ADC_FIFO, B_ADC_FIFO_A2 << path, 0x1); + rtw89_phy_write32_mask(rtwdev, R_ADC_FIFO, B_ADC_FIFO_A3 << path, 0x0); + + /* disable rxgac */ + rtw8852c_disable_rxagc(rtwdev, path, 0x0); + rtw89_phy_write32_mask(rtwdev, R_UPD_CLK | (path << 13), MASKDWORD, 0xf801fffd); + rtw89_phy_write32_mask(rtwdev, R_UPD_CLK | (path << 13), B_DPD_DIS, 0x1); + rtw89_phy_write32_mask(rtwdev, R_UPD_CLK | (path << 13), B_DAC_VAL, 0x1); + + rtw8852c_txck_force(rtwdev, path, true, DAC_960M); + rtw89_phy_write32_mask(rtwdev, R_UPD_CLK | (path << 13), B_DPD_GDIS, 0x1); + + rtw8852c_rxck_force(rtwdev, path, true, ADC_1920M); + rtw89_phy_write32_mask(rtwdev, R_UPD_CLK | (path << 13), B_ACK_VAL, 0x2); + + rtw89_phy_write32_mask(rtwdev, R_P0_CFCH_BW0 | (path << 8), B_P0_CFCH_BW0, 0x1); + rtw89_phy_write32_mask(rtwdev, R_P0_CFCH_BW1 | (path << 8), B_P0_CFCH_BW1, 0xb); + rtw89_phy_write32_mask(rtwdev, R_P0_NRBW | (path << 13), B_P0_NRBW_DBG, 0x1); + rtw89_phy_write32_mask(rtwdev, R_ANAPAR_PW15, B_ANAPAR_PW15, 0x1f); + rtw89_phy_write32_mask(rtwdev, R_ANAPAR_PW15, B_ANAPAR_PW15, 0x13); + rtw89_phy_write32_mask(rtwdev, R_ANAPAR, B_ANAPAR_15, 0x0001); + rtw89_phy_write32_mask(rtwdev, R_ANAPAR, B_ANAPAR_15, 0x0041); + rtw89_phy_write32_mask(rtwdev, R_ADC_FIFO, B_ADC_FIFO_A1 << path, 0x1); + rtw89_phy_write32_mask(rtwdev, R_ADC_FIFO, B_ADC_FIFO_A3 << path, 0x1); +} + static void _rck(struct rtw89_dev *rtwdev, enum rtw89_rf_path path) { u32 rf_reg5, rck_val = 0; @@ -505,6 +1452,86 @@ static void _rck(struct rtw89_dev *rtwdev, enum rtw89_rf_path path) rtw89_read_rf(rtwdev, path, RR_RCKS, RFREG_MASK)); } +static void _iqk_init(struct rtw89_dev *rtwdev) +{ + struct rtw89_iqk_info *iqk_info = &rtwdev->iqk; + u8 ch, path; + + rtw89_phy_write32_clr(rtwdev, R_IQKINF, MASKDWORD); + if (iqk_info->is_iqk_init) + return; + + rtw89_debug(rtwdev, RTW89_DBG_RFK, "[IQK]===>%s\n", __func__); + iqk_info->is_iqk_init = true; + iqk_info->is_nbiqk = false; + iqk_info->iqk_fft_en = false; + iqk_info->iqk_sram_en = false; + iqk_info->iqk_cfir_en = false; + iqk_info->iqk_xym_en = false; + iqk_info->thermal_rek_en = false; + iqk_info->iqk_times = 0x0; + + for (ch = 0; ch < RTW89_IQK_CHS_NR; ch++) { + iqk_info->iqk_channel[ch] = 0x0; + for (path = 0; path < RTW8852C_IQK_SS; path++) { + iqk_info->lok_cor_fail[ch][path] = false; + iqk_info->lok_fin_fail[ch][path] = false; + iqk_info->iqk_tx_fail[ch][path] = false; + iqk_info->iqk_rx_fail[ch][path] = false; + iqk_info->iqk_mcc_ch[ch][path] = 0x0; + iqk_info->iqk_table_idx[path] = 0x0; + } + } +} + +static void _doiqk(struct rtw89_dev *rtwdev, bool force, + enum rtw89_phy_idx phy_idx, u8 path) +{ + struct rtw89_iqk_info *iqk_info = &rtwdev->iqk; + u32 backup_bb_val[BACKUP_BB_REGS_NR]; + u32 backup_rf_val[RTW8852C_IQK_SS][BACKUP_RF_REGS_NR]; + u8 phy_map = rtw89_btc_phymap(rtwdev, phy_idx, RF_AB); + + rtw89_btc_ntfy_wl_rfk(rtwdev, phy_map, BTC_WRFKT_IQK, BTC_WRFK_ONESHOT_START); + + rtw89_debug(rtwdev, RTW89_DBG_RFK, + "[IQK]==========IQK strat!!!!!==========\n"); + iqk_info->iqk_times++; + iqk_info->kcount = 0; + iqk_info->version = RTW8852C_IQK_VER; + + rtw89_debug(rtwdev, RTW89_DBG_RFK, "[IQK]Test Ver 0x%x\n", iqk_info->version); + _iqk_get_ch_info(rtwdev, phy_idx, path); + _rfk_backup_bb_reg(rtwdev, backup_bb_val); + _rfk_backup_rf_reg(rtwdev, backup_rf_val[path], path); + _iqk_macbb_setting(rtwdev, phy_idx, path); + _iqk_preset(rtwdev, path); + _iqk_start_iqk(rtwdev, phy_idx, path); + _iqk_restore(rtwdev, path); + _iqk_afebb_restore(rtwdev, phy_idx, path); + _rfk_restore_bb_reg(rtwdev, backup_bb_val); + _rfk_restore_rf_reg(rtwdev, backup_rf_val[path], path); + rtw89_btc_ntfy_wl_rfk(rtwdev, phy_map, BTC_WRFKT_IQK, BTC_WRFK_ONESHOT_STOP); +} + +static void _iqk(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy_idx, bool force) +{ + switch (_kpath(rtwdev, phy_idx)) { + case RF_A: + _doiqk(rtwdev, force, phy_idx, RF_PATH_A); + break; + case RF_B: + _doiqk(rtwdev, force, phy_idx, RF_PATH_B); + break; + case RF_AB: + _doiqk(rtwdev, force, phy_idx, RF_PATH_A); + _doiqk(rtwdev, force, phy_idx, RF_PATH_B); + break; + default: + break; + } +} + static void _rx_dck_toggle(struct rtw89_dev *rtwdev, u8 path) { int ret; @@ -1707,6 +2734,22 @@ void rtw8852c_dack(struct rtw89_dev *rtwdev) rtw89_btc_ntfy_wl_rfk(rtwdev, phy_map, BTC_WRFKT_DACK, BTC_WRFK_STOP); } +void rtw8852c_iqk(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy_idx) +{ + u32 tx_en; + u8 phy_map = rtw89_btc_phymap(rtwdev, phy_idx, 0); + + rtw89_btc_ntfy_wl_rfk(rtwdev, phy_map, BTC_WRFKT_IQK, BTC_WRFK_START); + rtw89_chip_stop_sch_tx(rtwdev, phy_idx, &tx_en, RTW89_SCH_TX_SEL_ALL); + _wait_rx_mode(rtwdev, _kpath(rtwdev, phy_idx)); + + _iqk_init(rtwdev); + _iqk(rtwdev, phy_idx, false); + + rtw89_chip_resume_sch_tx(rtwdev, phy_idx, tx_en); + rtw89_btc_ntfy_wl_rfk(rtwdev, phy_map, BTC_WRFKT_IQK, BTC_WRFK_STOP); +} + #define RXDCK_VER_8852C 0xe void rtw8852c_rx_dck(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy, bool is_afe) diff --git a/drivers/net/wireless/realtek/rtw89/rtw8852c_rfk.h b/drivers/net/wireless/realtek/rtw89/rtw8852c_rfk.h index fd07028a49640..5c0623f6af208 100644 --- a/drivers/net/wireless/realtek/rtw89/rtw8852c_rfk.h +++ b/drivers/net/wireless/realtek/rtw89/rtw8852c_rfk.h @@ -9,6 +9,7 @@ void rtw8852c_rck(struct rtw89_dev *rtwdev); void rtw8852c_dack(struct rtw89_dev *rtwdev); +void rtw8852c_iqk(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy_idx); void rtw8852c_rx_dck(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy_idx, bool is_afe); void rtw8852c_tssi(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy); void rtw8852c_tssi_scan(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy); From da4cea16cb1340576459e1a703cae4084f9e6514 Mon Sep 17 00:00:00 2001 From: Ping-Ke Shih Date: Tue, 3 May 2022 07:54:08 +0800 Subject: [PATCH 228/228] rtw89: 8852c: rfk: add DPK DPK is short for digital pre-distortion calibration. It can adjusts digital waveform according to PA linear characteristics dynamically to enhance TX EVM. Do this calibration when we are going to run on AP channel. To prevent power offset out of boundary, it monitors thermal and set proper boundary to register. 8852c needs two backup buffers, so we enlarge the array. But, 8852a still needs only one, so it only uses first element (index zero). Signed-off-by: Ping-Ke Shih Signed-off-by: Kalle Valo Link: https://lore.kernel.org/r/20220502235408.15052-9-pkshih@realtek.com --- drivers/net/wireless/realtek/rtw89/core.h | 11 +- drivers/net/wireless/realtek/rtw89/reg.h | 49 + .../net/wireless/realtek/rtw89/rtw8852a_rfk.c | 8 +- drivers/net/wireless/realtek/rtw89/rtw8852c.c | 2 + .../net/wireless/realtek/rtw89/rtw8852c_rfk.c | 1114 +++++++++++++++++ .../net/wireless/realtek/rtw89/rtw8852c_rfk.h | 2 + 6 files changed, 1178 insertions(+), 8 deletions(-) diff --git a/drivers/net/wireless/realtek/rtw89/core.h b/drivers/net/wireless/realtek/rtw89/core.h index 8fd719f93d6c7..2921814842ffa 100644 --- a/drivers/net/wireless/realtek/rtw89/core.h +++ b/drivers/net/wireless/realtek/rtw89/core.h @@ -2690,6 +2690,7 @@ struct rtw89_dpk_bkup_para { enum rtw89_bandwidth bw; u8 ch; bool path_ok; + u8 mdpd_en; u8 txagc_dpk; u8 ther_dpk; u8 gs; @@ -2699,11 +2700,12 @@ struct rtw89_dpk_bkup_para { struct rtw89_dpk_info { bool is_dpk_enable; bool is_dpk_reload_en; - u16 dc_i[RTW89_DPK_RF_PATH]; - u16 dc_q[RTW89_DPK_RF_PATH]; - u8 corr_val[RTW89_DPK_RF_PATH]; - u8 corr_idx[RTW89_DPK_RF_PATH]; + 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]; + u8 corr_idx[RTW89_DPK_RF_PATH][RTW89_DPK_BKUP_NUM]; u8 cur_idx[RTW89_DPK_RF_PATH]; + u8 cur_k_set; struct rtw89_dpk_bkup_para bp[RTW89_DPK_RF_PATH][RTW89_DPK_BKUP_NUM]; }; @@ -2712,6 +2714,7 @@ struct rtw89_fem_info { bool elna_5g; bool epa_2g; bool epa_5g; + bool epa_6g; }; struct rtw89_phy_ch_info { diff --git a/drivers/net/wireless/realtek/rtw89/reg.h b/drivers/net/wireless/realtek/rtw89/reg.h index 120fc13520fcc..6f5d1012c90c6 100644 --- a/drivers/net/wireless/realtek/rtw89/reg.h +++ b/drivers/net/wireless/realtek/rtw89/reg.h @@ -3191,6 +3191,7 @@ #define B_AX_GNT_BT_TX_SW_CTRL BIT(0) #define RR_MOD 0x00 +#define RR_MOD_V1 0x10000 #define RR_MOD_IQK GENMASK(19, 4) #define RR_MOD_DPK GENMASK(19, 5) #define RR_MOD_MASK GENMASK(19, 16) @@ -3357,8 +3358,16 @@ #define RR_DCK2_CYCLE GENMASK(7, 2) #define RR_DCKC 0x95 #define RR_DCKC_CHK BIT(3) +#define RR_IQGEN 0x97 +#define RR_IQGEN_BIAS GENMASK(11, 8) +#define RR_TXIQK 0x98 +#define RR_TXIQK_ATT2 GENMASK(15, 12) +#define RR_TIA 0x9e +#define RR_TIA_N6 BIT(8) #define RR_MIXER 0x9f #define RR_MIXER_GN GENMASK(4, 3) +#define RR_LOGEN 0xa3 +#define RR_LOGEN_RPT GENMASK(19, 16) #define RR_XTALX2 0xb8 #define RR_MALSEL 0xbe #define RR_LCK_TRG 0xd3 @@ -3370,6 +3379,7 @@ #define RR_RCKD_BW BIT(2) #define RR_TXADBG 0xde #define RR_LUTDBG 0xdf +#define RR_LUTDBG_TIA BIT(12) #define RR_LUTDBG_LOK BIT(2) #define RR_LUTWE2 0xee #define RR_LUTWE2_RTXBW BIT(2) @@ -3580,6 +3590,8 @@ #define B_TXAGC_TP GENMASK(2, 0) #define R_TSSI_THER 0x1C10 #define B_TSSI_THER GENMASK(29, 24) +#define R_TXAGC_BTP 0x1CA0 +#define B_TXAGC_BTP GENMASK(31, 24) #define R_TXAGC_BB 0x1C60 #define B_TXAGC_BB_OFT GENMASK(31, 16) #define B_TXAGC_BB GENMASK(31, 24) @@ -3866,10 +3878,15 @@ #define B_DPD_DIS BIT(14) #define B_DPD_GDIS BIT(13) #define B_IQK_RFC_ON BIT(1) +#define R_TXPWRB 0x56CC +#define B_TXPWRB_ON BIT(28) +#define B_TXPWRB_VAL GENMASK(27, 19) #define R_DPD_OFT_EN 0x5800 #define B_DPD_OFT_EN BIT(28) #define R_DPD_OFT_ADDR 0x5804 #define B_DPD_OFT_ADDR GENMASK(31, 27) +#define R_TXPWRB_H 0x580c +#define B_TXPWRB_RDY BIT(15) #define R_P0_TMETER 0x5810 #define B_P0_TMETER GENMASK(15, 10) #define B_P0_TMETER_DIS BIT(16) @@ -3981,16 +3998,23 @@ #define IQK_DF4_TXT_8_25MHZ 0x021 #define R_IQK_CFG 0x8034 #define B_IQK_CFG_SET GENMASK(5, 4) +#define R_TPG_SEL 0x8068 #define R_TPG_MOD 0x806C #define B_TPG_MOD_F GENMASK(2, 1) #define R_MDPK_SYNC 0x8070 #define B_MDPK_SYNC_SEL BIT(31) #define B_MDPK_SYNC_MAN GENMASK(31, 28) #define R_MDPK_RX_DCK 0x8074 +#define B_MDPK_RX_DCK_EN BIT(31) +#define R_KIP_MOD 0x8078 +#define B_KIP_MOD GENMASK(19, 0) #define R_NCTL_RW 0x8080 #define R_KIP_SYSCFG 0x8088 #define R_KIP_CLK 0x808C +#define R_DPK_IDL 0x809C +#define B_DPK_IDL BIT(8) #define R_LDL_NORM 0x80A0 +#define B_LDL_NORM_MA BIT(16) #define B_LDL_NORM_PN GENMASK(12, 8) #define B_LDL_NORM_OP GENMASK(1, 0) #define R_DPK_CTL 0x80B0 @@ -4001,12 +4025,19 @@ #define B_DPK_CFG2_ST BIT(14) #define R_DPK_CFG3 0x80C0 #define R_KPATH_CFG 0x80D0 +#define B_KPATH_CFG_ED GENMASK(21, 20) #define R_KIP_RPT1 0x80D4 #define B_KIP_RPT1_SEL GENMASK(21, 16) #define R_SRAM_IQRX 0x80D8 #define R_GAPK 0x80E0 #define B_GAPK_ADR BIT(0) #define R_SRAM_IQRX2 0x80E8 +#define R_DPK_MPA 0x80EC +#define B_DPK_MPA_T0 BIT(10) +#define B_DPK_MPA_T1 BIT(9) +#define B_DPK_MPA_T2 BIT(8) +#define R_DPK_WR 0x80F4 +#define B_DPK_WR_ST BIT(29) #define R_DPK_TRK 0x80f0 #define B_DPK_TRK_DIS BIT(31) #define R_RPT_COM 0x80FC @@ -4014,8 +4045,11 @@ #define B_PRT_COM_DCI GENMASK(27, 16) #define B_PRT_COM_CORV GENMASK(15, 8) #define B_PRT_COM_DCQ GENMASK(11, 0) +#define B_PRT_COM_RXOV BIT(8) #define B_PRT_COM_GL GENMASK(7, 4) #define B_PRT_COM_CORI GENMASK(7, 0) +#define B_PRT_COM_RXBB GENMASK(5, 0) +#define B_PRT_COM_DONE BIT(0) #define R_COEF_SEL 0x8104 #define B_COEF_SEL_IQC BIT(0) #define B_COEF_SEL_MDPD BIT(8) @@ -4045,14 +4079,22 @@ #define B_CFIR_LUT_G2 BIT(2) #define B_CFIR_LUT_GP_V1 GENMASK(2, 0) #define B_CFIR_LUT_GP GENMASK(1, 0) +#define R_DPK_GN 0x819C +#define B_DPK_GN_EN GENMASK(17, 16) +#define B_DPK_GN_AG GENMASK(9, 0) #define R_DPD_V1 0x81a0 +#define B_DPD_LBK BIT(7) #define R_DPD_CH0 0x81AC #define R_DPD_BND 0x81B4 #define R_DPD_CH0A 0x81BC +#define B_DPD_MEN GENMASK(31, 28) +#define B_DPD_ORDER GENMASK(26, 24) +#define B_DPD_SEL GENMASK(13, 8) #define R_TXAGC_RFK 0x81C4 #define B_TXAGC_RFK_CH0 GENMASK(5, 0) #define R_DPD_COM 0x81C8 #define R_KIP_IQP 0x81CC +#define B_KIP_IQP_SW GENMASK(13, 12) #define B_KIP_IQP_IQSW GENMASK(5, 0) #define R_KIP_RPT 0x81D4 #define B_KIP_RPT_SEL GENMASK(21, 16) @@ -4060,8 +4102,15 @@ #define R_LOAD_COEF 0x81DC #define B_LOAD_COEF_MDPD BIT(16) #define B_LOAD_COEF_CFIR GENMASK(1, 0) +#define B_LOAD_COEF_DI BIT(1) #define B_LOAD_COEF_AUTO BIT(0) +#define R_DPK_GL 0x81F0 +#define B_DPK_GL_A0 GENMASK(31, 28) +#define B_DPK_GL_A1 GENMASK(17, 0) #define R_RPT_PER 0x81FC +#define B_RPT_PER_TSSI GENMASK(28, 16) +#define B_RPT_PER_OF GENMASK(15, 8) +#define B_RPT_PER_TH GENMASK(5, 0) #define R_RXCFIR_P0C0 0x8D40 #define R_RXCFIR_P0C1 0x8D84 #define R_RXCFIR_P0C2 0x8DC8 diff --git a/drivers/net/wireless/realtek/rtw89/rtw8852a_rfk.c b/drivers/net/wireless/realtek/rtw89/rtw8852a_rfk.c index aa782534e76be..e3c2fce326516 100644 --- a/drivers/net/wireless/realtek/rtw89/rtw8852a_rfk.c +++ b/drivers/net/wireless/realtek/rtw89/rtw8852a_rfk.c @@ -2189,8 +2189,8 @@ static bool _dpk_sync_check(struct rtw89_dev *rtwdev, "[DPK] S%d Corr_idx / Corr_val = %d / %d\n", path, corr_idx, corr_val); - dpk->corr_idx[path] = corr_idx; - dpk->corr_val[path] = corr_val; + dpk->corr_idx[path][0] = corr_idx; + dpk->corr_val[path][0] = corr_val; rtw89_phy_write32_mask(rtwdev, R_KIP_RPT1, B_KIP_RPT1_SEL, 0x9); @@ -2203,8 +2203,8 @@ static bool _dpk_sync_check(struct rtw89_dev *rtwdev, rtw89_debug(rtwdev, RTW89_DBG_RFK, "[DPK] S%d DC I/Q, = %d / %d\n", path, dc_i, dc_q); - dpk->dc_i[path] = dc_i; - dpk->dc_q[path] = dc_q; + dpk->dc_i[path][0] = dc_i; + dpk->dc_q[path][0] = dc_q; if (dc_i > DPK_SYNC_TH_DC_I || dc_q > DPK_SYNC_TH_DC_Q || corr_val < DPK_SYNC_TH_CORR) diff --git a/drivers/net/wireless/realtek/rtw89/rtw8852c.c b/drivers/net/wireless/realtek/rtw89/rtw8852c.c index 0b722675aad42..4fb3de71d032f 100644 --- a/drivers/net/wireless/realtek/rtw89/rtw8852c.c +++ b/drivers/net/wireless/realtek/rtw89/rtw8852c.c @@ -1789,6 +1789,7 @@ static void rtw8852c_rfk_channel(struct rtw89_dev *rtwdev) rtw8852c_rx_dck(rtwdev, phy_idx, false); rtw8852c_iqk(rtwdev, phy_idx); rtw8852c_tssi(rtwdev, phy_idx); + rtw8852c_dpk(rtwdev, phy_idx); rtw89_fw_h2c_rf_ntfy_mcc(rtwdev); } @@ -1804,6 +1805,7 @@ static void rtw8852c_rfk_scan(struct rtw89_dev *rtwdev, bool start) static void rtw8852c_rfk_track(struct rtw89_dev *rtwdev) { + rtw8852c_dpk_track(rtwdev); rtw8852c_lck_track(rtwdev); } diff --git a/drivers/net/wireless/realtek/rtw89/rtw8852c_rfk.c b/drivers/net/wireless/realtek/rtw89/rtw8852c_rfk.c index 3108fa9cd5b20..ffc71ad249270 100644 --- a/drivers/net/wireless/realtek/rtw89/rtw8852c_rfk.c +++ b/drivers/net/wireless/realtek/rtw89/rtw8852c_rfk.c @@ -55,6 +55,11 @@ static const u32 _txk_g_track_range[TXK_GROUP_NR] = {0x5, 0x6, 0x6}; static const u32 _txk_g_gain_bb[TXK_GROUP_NR] = {0x0e, 0x0a, 0x0e}; static const u32 _txk_g_itqt[TXK_GROUP_NR] = { 0x12, 0x12, 0x12}; +static const u32 dpk_par_regs[RTW89_DPK_RF_PATH][4] = { + {0x8190, 0x8194, 0x8198, 0x81a4}, + {0x81a8, 0x81c4, 0x81c8, 0x81e8}, +}; + static u8 _kpath(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy_idx) { rtw89_debug(rtwdev, RTW89_DBG_RFK, "[RFK]dbcc_en: %x, PHY%d\n", @@ -1568,6 +1573,1093 @@ static void _set_rx_dck(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy, u8 pat } } +#define RTW8852C_RF_REL_VERSION 34 +#define RTW8852C_DPK_VER 0x10 +#define RTW8852C_DPK_TH_AVG_NUM 4 +#define RTW8852C_DPK_RF_PATH 2 +#define RTW8852C_DPK_KIP_REG_NUM 5 +#define RTW8852C_DPK_RXSRAM_DBG 0 + +enum rtw8852c_dpk_id { + LBK_RXIQK = 0x06, + SYNC = 0x10, + MDPK_IDL = 0x11, + MDPK_MPA = 0x12, + GAIN_LOSS = 0x13, + GAIN_CAL = 0x14, + DPK_RXAGC = 0x15, + KIP_PRESET = 0x16, + KIP_RESTORE = 0x17, + DPK_TXAGC = 0x19, + D_KIP_PRESET = 0x28, + D_TXAGC = 0x29, + D_RXAGC = 0x2a, + D_SYNC = 0x2b, + D_GAIN_LOSS = 0x2c, + D_MDPK_IDL = 0x2d, + D_GAIN_NORM = 0x2f, + D_KIP_THERMAL = 0x30, + D_KIP_RESTORE = 0x31 +}; + +#define DPK_TXAGC_LOWER 0x2e +#define DPK_TXAGC_UPPER 0x3f +#define DPK_TXAGC_INVAL 0xff + +enum dpk_agc_step { + DPK_AGC_STEP_SYNC_DGAIN, + DPK_AGC_STEP_GAIN_LOSS_IDX, + DPK_AGC_STEP_GL_GT_CRITERION, + DPK_AGC_STEP_GL_LT_CRITERION, + DPK_AGC_STEP_SET_TX_GAIN, +}; + +static void _rf_direct_cntrl(struct rtw89_dev *rtwdev, + enum rtw89_rf_path path, bool is_bybb) +{ + if (is_bybb) + rtw89_write_rf(rtwdev, path, RR_RSV1, RR_RSV1_RST, 0x1); + else + rtw89_write_rf(rtwdev, path, RR_RSV1, RR_RSV1_RST, 0x0); +} + +static void _dpk_onoff(struct rtw89_dev *rtwdev, + enum rtw89_rf_path path, bool off); + +static void _dpk_bkup_kip(struct rtw89_dev *rtwdev, const u32 reg[], + u32 reg_bkup[][RTW8852C_DPK_KIP_REG_NUM], u8 path) +{ + u8 i; + + for (i = 0; i < RTW8852C_DPK_KIP_REG_NUM; i++) { + reg_bkup[path][i] = + rtw89_phy_read32_mask(rtwdev, reg[i] + (path << 8), MASKDWORD); + + rtw89_debug(rtwdev, RTW89_DBG_RFK, "[DPK] Backup 0x%x = %x\n", + reg[i] + (path << 8), reg_bkup[path][i]); + } +} + +static void _dpk_reload_kip(struct rtw89_dev *rtwdev, const u32 reg[], + u32 reg_bkup[][RTW8852C_DPK_KIP_REG_NUM], u8 path) +{ + u8 i; + + for (i = 0; i < RTW8852C_DPK_KIP_REG_NUM; i++) { + rtw89_phy_write32_mask(rtwdev, reg[i] + (path << 8), + MASKDWORD, reg_bkup[path][i]); + rtw89_debug(rtwdev, RTW89_DBG_RFK, "[DPK] Reload 0x%x = %x\n", + reg[i] + (path << 8), reg_bkup[path][i]); + } +} + +static u8 _dpk_one_shot(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy, + enum rtw89_rf_path path, enum rtw8852c_dpk_id id) +{ + u16 dpk_cmd; + u32 val; + int ret; + + dpk_cmd = (u16)((id << 8) | (0x19 + path * 0x12)); + + rtw89_phy_write32_mask(rtwdev, R_NCTL_CFG, MASKDWORD, dpk_cmd); + + ret = read_poll_timeout_atomic(rtw89_phy_read32_mask, val, val == 0x55, + 10, 20000, false, rtwdev, 0xbff8, MASKBYTE0); + mdelay(10); + rtw89_phy_write32_clr(rtwdev, R_NCTL_N1, MASKBYTE0); + + rtw89_debug(rtwdev, RTW89_DBG_RFK, + "[DPK] one-shot for %s = 0x%x (ret=%d)\n", + id == 0x06 ? "LBK_RXIQK" : + id == 0x10 ? "SYNC" : + id == 0x11 ? "MDPK_IDL" : + id == 0x12 ? "MDPK_MPA" : + id == 0x13 ? "GAIN_LOSS" : "PWR_CAL", + dpk_cmd, ret); + + if (ret) { + rtw89_debug(rtwdev, RTW89_DBG_RFK, + "[DPK] one-shot over 20ms!!!!\n"); + return 1; + } + + return 0; +} + +static void _dpk_information(struct rtw89_dev *rtwdev, + enum rtw89_phy_idx phy, + enum rtw89_rf_path path) +{ + struct rtw89_dpk_info *dpk = &rtwdev->dpk; + struct rtw89_hal *hal = &rtwdev->hal; + + u8 kidx = dpk->cur_idx[path]; + + dpk->bp[path][kidx].band = hal->current_band_type; + dpk->bp[path][kidx].ch = hal->current_channel; + dpk->bp[path][kidx].bw = hal->current_band_width; + + rtw89_debug(rtwdev, RTW89_DBG_RFK, + "[DPK] S%d[%d] (PHY%d): TSSI %s/ DBCC %s/ %s/ CH%d/ %s\n", + path, dpk->cur_idx[path], phy, + rtwdev->is_tssi_mode[path] ? "on" : "off", + rtwdev->dbcc_en ? "on" : "off", + dpk->bp[path][kidx].band == 0 ? "2G" : + dpk->bp[path][kidx].band == 1 ? "5G" : "6G", + dpk->bp[path][kidx].ch, + dpk->bp[path][kidx].bw == 0 ? "20M" : + dpk->bp[path][kidx].bw == 1 ? "40M" : "80M"); +} + +static void _dpk_bb_afe_setting(struct rtw89_dev *rtwdev, + enum rtw89_phy_idx phy, + enum rtw89_rf_path path, u8 kpath) +{ + /*1. Keep ADC_fifo reset*/ + rtw89_phy_write32_mask(rtwdev, R_ADC_FIFO, B_ADC_FIFO_A0 << path, 0x1); + rtw89_phy_write32_mask(rtwdev, R_ADC_FIFO, B_ADC_FIFO_A1 << path, 0x0); + rtw89_phy_write32_mask(rtwdev, R_ADC_FIFO, B_ADC_FIFO_A2 << path, 0x1); + rtw89_phy_write32_mask(rtwdev, R_ADC_FIFO, B_ADC_FIFO_A3 << path, 0x0); + + /*2. BB for IQK DBG mode*/ + rtw89_phy_write32_mask(rtwdev, R_UPD_CLK + (path << 13), MASKDWORD, 0xd801dffd); + + /*3.Set DAC clk*/ + rtw8852c_txck_force(rtwdev, path, true, DAC_960M); + + /*4. Set ADC clk*/ + rtw8852c_rxck_force(rtwdev, path, true, ADC_1920M); + rtw89_phy_write32_mask(rtwdev, R_P0_CFCH_BW0 + (path << 8), B_P0_CFCH_BW0, 0x1); + rtw89_phy_write32_mask(rtwdev, R_P0_CFCH_BW1 + (path << 8), B_P0_CFCH_BW1, 0xb); + rtw89_phy_write32_mask(rtwdev, R_P0_NRBW + (path << 13), + B_P0_NRBW_DBG, 0x1); + rtw89_phy_write32_mask(rtwdev, R_ANAPAR_PW15, MASKBYTE3, 0x1f); + rtw89_phy_write32_mask(rtwdev, R_ANAPAR_PW15, MASKBYTE3, 0x13); + rtw89_phy_write32_mask(rtwdev, R_ANAPAR, MASKHWORD, 0x0001); + rtw89_phy_write32_mask(rtwdev, R_ANAPAR, MASKHWORD, 0x0041); + + /*5. ADDA fifo rst*/ + rtw89_phy_write32_mask(rtwdev, R_ADC_FIFO, B_ADC_FIFO_A1 << path, 0x1); + rtw89_phy_write32_mask(rtwdev, R_ADC_FIFO, B_ADC_FIFO_A3 << path, 0x1); + + rtw89_debug(rtwdev, RTW89_DBG_RFK, "[DPK] S%d BB/AFE setting\n", path); +} + +static void _dpk_bb_afe_restore(struct rtw89_dev *rtwdev, u8 path) +{ + rtw89_phy_write32_mask(rtwdev, R_P0_NRBW + (path << 13), + B_P0_NRBW_DBG, 0x0); + rtw89_phy_write32_mask(rtwdev, R_ADC_FIFO, B_ADC_FIFO_A0 << path, 0x1); + rtw89_phy_write32_mask(rtwdev, R_ADC_FIFO, B_ADC_FIFO_A1 << path, 0x0); + rtw89_phy_write32_mask(rtwdev, R_ADC_FIFO, B_ADC_FIFO_A2 << path, 0x1); + rtw89_phy_write32_mask(rtwdev, R_ADC_FIFO, B_ADC_FIFO_A3 << path, 0x0); + rtw89_phy_write32_mask(rtwdev, R_UPD_CLK + (path << 13), MASKDWORD, 0x00000000); + rtw89_phy_write32_mask(rtwdev, R_P0_RXCK + (path << 13), B_P0_TXCK_ALL, 0x00); + rtw89_phy_write32_mask(rtwdev, R_ADC_FIFO, B_ADC_FIFO_A0 << path, 0x0); + rtw89_phy_write32_mask(rtwdev, R_ADC_FIFO, B_ADC_FIFO_A2 << path, 0x0); + + rtw89_debug(rtwdev, RTW89_DBG_RFK, "[DPK] S%d BB/AFE restore\n", path); +} + +static void _dpk_tssi_pause(struct rtw89_dev *rtwdev, + enum rtw89_rf_path path, bool is_pause) +{ + rtw89_phy_write32_mask(rtwdev, R_P0_TSSI_TRK + (path << 13), + B_P0_TSSI_TRK_EN, is_pause); + + rtw89_debug(rtwdev, RTW89_DBG_RFK, "[DPK] S%d TSSI %s\n", path, + is_pause ? "pause" : "resume"); +} + +static void _dpk_kip_control_rfc(struct rtw89_dev *rtwdev, u8 path, bool ctrl_by_kip) +{ + rtw89_phy_write32_mask(rtwdev, R_UPD_CLK + (path << 13), B_IQK_RFC_ON, ctrl_by_kip); + rtw89_debug(rtwdev, RTW89_DBG_RFK, "[DPK] RFC is controlled by %s\n", + ctrl_by_kip ? "KIP" : "BB"); +} + +static void _dpk_txpwr_bb_force(struct rtw89_dev *rtwdev, u8 path, bool force) +{ + rtw89_phy_write32_mask(rtwdev, R_TXPWRB + (path << 13), B_TXPWRB_ON, force); + rtw89_phy_write32_mask(rtwdev, R_TXPWRB_H + (path << 13), B_TXPWRB_RDY, force); + + rtw89_debug(rtwdev, RTW89_DBG_RFK, "[DPK] S%d txpwr_bb_force %s\n", + path, force ? "on" : "off"); +} + +static void _dpk_kip_restore(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy, + enum rtw89_rf_path path) +{ + _dpk_one_shot(rtwdev, phy, path, D_KIP_RESTORE); + _dpk_kip_control_rfc(rtwdev, path, false); + _dpk_txpwr_bb_force(rtwdev, path, false); + rtw89_debug(rtwdev, RTW89_DBG_RFK, "[DPK] S%d restore KIP\n", path); +} + +static void _dpk_lbk_rxiqk(struct rtw89_dev *rtwdev, + enum rtw89_phy_idx phy, + enum rtw89_rf_path path) +{ +#define RX_TONE_IDX 0x00250025 /* Q.2 9.25MHz */ + u8 cur_rxbb; + u32 rf_11, reg_81cc; + + rtw89_phy_write32_mask(rtwdev, R_DPD_V1 + (path << 8), B_DPD_LBK, 0x1); + rtw89_phy_write32_mask(rtwdev, R_MDPK_RX_DCK, B_MDPK_RX_DCK_EN, 0x1); + + _dpk_kip_control_rfc(rtwdev, path, false); + + cur_rxbb = rtw89_read_rf(rtwdev, path, RR_MOD, RR_MOD_M_RXBB); + rf_11 = rtw89_read_rf(rtwdev, path, RR_TXIG, RFREG_MASK); + reg_81cc = rtw89_phy_read32_mask(rtwdev, R_KIP_IQP + (path << 8), + B_KIP_IQP_SW); + + rtw89_write_rf(rtwdev, path, RR_TXIG, RR_TXIG_GR0, 0x0); + rtw89_write_rf(rtwdev, path, RR_TXIG, RR_TXIG_GR1, 0x3); + rtw89_write_rf(rtwdev, path, RR_TXIG, RR_TXIG_TG, 0xd); + rtw89_write_rf(rtwdev, path, RR_MOD, RR_MOD_M_RXBB, 0x1f); + + rtw89_phy_write32_mask(rtwdev, R_KIP_IQP + (path << 8), B_KIP_IQP_IQSW, 0x12); + rtw89_phy_write32_mask(rtwdev, R_KIP_IQP + (path << 8), B_KIP_IQP_SW, 0x3); + + _dpk_kip_control_rfc(rtwdev, path, true); + + rtw89_phy_write32_mask(rtwdev, R_IQK_DIF4, MASKDWORD, RX_TONE_IDX); + + _dpk_one_shot(rtwdev, phy, path, LBK_RXIQK); + + rtw89_debug(rtwdev, RTW89_DBG_RFK, "[DPK] S%d LBK RXIQC = 0x%x\n", path, + rtw89_phy_read32_mask(rtwdev, R_RXIQC + (path << 8), MASKDWORD)); + + _dpk_kip_control_rfc(rtwdev, path, false); + + rtw89_write_rf(rtwdev, path, RR_TXIG, RFREG_MASK, rf_11); + rtw89_write_rf(rtwdev, path, RR_MOD, RR_MOD_M_RXBB, cur_rxbb); + rtw89_phy_write32_mask(rtwdev, R_KIP_IQP + (path << 8), B_KIP_IQP_SW, reg_81cc); + + rtw89_phy_write32_mask(rtwdev, R_MDPK_RX_DCK, B_MDPK_RX_DCK_EN, 0x0); + rtw89_phy_write32_mask(rtwdev, R_KPATH_CFG, B_KPATH_CFG_ED, 0x0); + rtw89_phy_write32_mask(rtwdev, R_LOAD_COEF + (path << 8), B_LOAD_COEF_DI, 0x1); + + _dpk_kip_control_rfc(rtwdev, path, true); +} + +static void _dpk_rf_setting(struct rtw89_dev *rtwdev, u8 gain, + enum rtw89_rf_path path, u8 kidx) +{ + struct rtw89_dpk_info *dpk = &rtwdev->dpk; + + if (dpk->bp[path][kidx].band == RTW89_BAND_2G) { + rtw89_write_rf(rtwdev, path, RR_MOD, RFREG_MASK, + 0x50121 | BIT(rtwdev->dbcc_en)); + rtw89_write_rf(rtwdev, path, RR_MOD_V1, RR_MOD_MASK, RF_DPK); + rtw89_write_rf(rtwdev, path, RR_RXBB, RR_RXBB_ATTC, 0x2); + rtw89_write_rf(rtwdev, path, RR_RXBB, RR_RXBB_ATTR, 0x4); + rtw89_write_rf(rtwdev, path, RR_LUTDBG, RR_LUTDBG_TIA, 0x1); + rtw89_write_rf(rtwdev, path, RR_TIA, RR_TIA_N6, 0x1); + + rtw89_debug(rtwdev, RTW89_DBG_RFK, + "[DPK] RF 0x0/0x83/0x9e/0x1a/0xdf/0x1001a = 0x%x/ 0x%x/ 0x%x/ 0x%x/ 0x%x/ 0x%x\n", + rtw89_read_rf(rtwdev, path, RR_MOD, RFREG_MASK), + rtw89_read_rf(rtwdev, path, RR_RXBB, RFREG_MASK), + rtw89_read_rf(rtwdev, path, RR_TIA, RFREG_MASK), + rtw89_read_rf(rtwdev, path, RR_BTC, RFREG_MASK), + rtw89_read_rf(rtwdev, path, RR_LUTDBG, RFREG_MASK), + rtw89_read_rf(rtwdev, path, 0x1001a, RFREG_MASK)); + } else { + rtw89_write_rf(rtwdev, path, RR_MOD, RFREG_MASK, + 0x50101 | BIT(rtwdev->dbcc_en)); + rtw89_write_rf(rtwdev, path, RR_MOD_V1, RR_MOD_MASK, RF_DPK); + + if (dpk->bp[path][kidx].band == RTW89_BAND_6G && dpk->bp[path][kidx].ch >= 161) { + rtw89_write_rf(rtwdev, path, RR_IQGEN, RR_IQGEN_BIAS, 0x8); + rtw89_write_rf(rtwdev, path, RR_LOGEN, RR_LOGEN_RPT, 0xd); + } else { + rtw89_write_rf(rtwdev, path, RR_LOGEN, RR_LOGEN_RPT, 0xd); + } + + rtw89_write_rf(rtwdev, path, RR_RXA2, RR_RXA2_ATT, 0x0); + rtw89_write_rf(rtwdev, path, RR_TXIQK, RR_TXIQK_ATT2, 0x3); + rtw89_write_rf(rtwdev, path, RR_LUTDBG, RR_LUTDBG_TIA, 0x1); + rtw89_write_rf(rtwdev, path, RR_TIA, RR_TIA_N6, 0x1); + + if (dpk->bp[path][kidx].bw == RTW89_CHANNEL_WIDTH_160) + rtw89_write_rf(rtwdev, path, RR_RXBB2, RR_RXBB2_EBW, 0x0); + } +} + +static void _dpk_tpg_sel(struct rtw89_dev *rtwdev, enum rtw89_rf_path path, u8 kidx) +{ + struct rtw89_dpk_info *dpk = &rtwdev->dpk; + + if (dpk->bp[path][kidx].bw == RTW89_CHANNEL_WIDTH_160) { + rtw89_phy_write32_mask(rtwdev, R_TPG_MOD, B_TPG_MOD_F, 0x3); + rtw89_phy_write32_mask(rtwdev, R_TPG_SEL, MASKDWORD, 0x0180ff30); + } else if (dpk->bp[path][kidx].bw == RTW89_CHANNEL_WIDTH_80) { + rtw89_phy_write32_mask(rtwdev, R_TPG_MOD, B_TPG_MOD_F, 0x0); + rtw89_phy_write32_mask(rtwdev, R_TPG_SEL, MASKDWORD, 0xffe0fa00); + } else if (dpk->bp[path][kidx].bw == RTW89_CHANNEL_WIDTH_40) { + rtw89_phy_write32_mask(rtwdev, R_TPG_MOD, B_TPG_MOD_F, 0x2); + rtw89_phy_write32_mask(rtwdev, R_TPG_SEL, MASKDWORD, 0xff4009e0); + } else { + rtw89_phy_write32_mask(rtwdev, R_TPG_MOD, B_TPG_MOD_F, 0x1); + rtw89_phy_write32_mask(rtwdev, R_TPG_SEL, MASKDWORD, 0xf9f007d0); + } + rtw89_debug(rtwdev, RTW89_DBG_RFK, "[DPK] TPG_Select for %s\n", + dpk->bp[path][kidx].bw == RTW89_CHANNEL_WIDTH_160 ? "160M" : + dpk->bp[path][kidx].bw == RTW89_CHANNEL_WIDTH_80 ? "80M" : + dpk->bp[path][kidx].bw == RTW89_CHANNEL_WIDTH_40 ? "40M" : "20M"); +} + +static bool _dpk_sync_check(struct rtw89_dev *rtwdev, enum rtw89_rf_path path, u8 kidx) +{ +#define DPK_SYNC_TH_DC_I 200 +#define DPK_SYNC_TH_DC_Q 200 +#define DPK_SYNC_TH_CORR 170 + struct rtw89_dpk_info *dpk = &rtwdev->dpk; + u16 dc_i, dc_q; + u8 corr_val, corr_idx, rxbb; + u8 rxbb_ov; + + rtw89_phy_write32_mask(rtwdev, R_KIP_RPT1, B_KIP_RPT1_SEL, 0x0); + + corr_idx = rtw89_phy_read32_mask(rtwdev, R_RPT_COM, B_PRT_COM_CORI); + corr_val = rtw89_phy_read32_mask(rtwdev, R_RPT_COM, B_PRT_COM_CORV); + + dpk->corr_idx[path][kidx] = corr_idx; + dpk->corr_val[path][kidx] = corr_val; + + rtw89_phy_write32_mask(rtwdev, R_KIP_RPT1, B_KIP_RPT1_SEL, 0x9); + + dc_i = rtw89_phy_read32_mask(rtwdev, R_RPT_COM, B_PRT_COM_DCI); + dc_q = rtw89_phy_read32_mask(rtwdev, R_RPT_COM, B_PRT_COM_DCQ); + + dc_i = abs(sign_extend32(dc_i, 11)); + dc_q = abs(sign_extend32(dc_q, 11)); + + rtw89_debug(rtwdev, RTW89_DBG_RFK, + "[DPK] S%d Corr_idx/ Corr_val /DC I/Q, = %d / %d / %d / %d\n", + path, corr_idx, corr_val, dc_i, dc_q); + + dpk->dc_i[path][kidx] = dc_i; + dpk->dc_q[path][kidx] = dc_q; + + rtw89_phy_write32_mask(rtwdev, R_KIP_RPT1, B_KIP_RPT1_SEL, 0x8); + rxbb = rtw89_phy_read32_mask(rtwdev, R_RPT_COM, B_PRT_COM_RXBB); + + rtw89_phy_write32_mask(rtwdev, R_KIP_RPT1, B_KIP_RPT1_SEL, 0x31); + rxbb_ov = rtw89_phy_read32_mask(rtwdev, R_RPT_COM, B_PRT_COM_RXOV); + + rtw89_debug(rtwdev, RTW89_DBG_RFK, + "[DPK] S%d RXBB/ RXAGC_done /RXBB_ovlmt = %d / %d / %d\n", + path, rxbb, + rtw89_phy_read32_mask(rtwdev, R_RPT_COM, B_PRT_COM_DONE), + rxbb_ov); + + if (dc_i > DPK_SYNC_TH_DC_I || dc_q > DPK_SYNC_TH_DC_Q || + corr_val < DPK_SYNC_TH_CORR) + return true; + else + return false; +} + +static u16 _dpk_dgain_read(struct rtw89_dev *rtwdev) +{ + u16 dgain = 0x0; + + rtw89_phy_write32_clr(rtwdev, R_KIP_RPT1, B_KIP_RPT1_SEL); + + dgain = rtw89_phy_read32_mask(rtwdev, R_RPT_COM, B_PRT_COM_DCI); + + rtw89_debug(rtwdev, RTW89_DBG_RFK, "[DPK] DGain = 0x%x (%d)\n", dgain, dgain); + + return dgain; +} + +static u8 _dpk_gainloss_read(struct rtw89_dev *rtwdev) +{ + u8 result; + + rtw89_phy_write32_mask(rtwdev, R_KIP_RPT1, B_KIP_RPT1_SEL, 0x6); + rtw89_phy_write32_mask(rtwdev, R_DPK_CFG2, B_DPK_CFG2_ST, 0x1); + + result = rtw89_phy_read32_mask(rtwdev, R_RPT_COM, B_PRT_COM_GL); + + rtw89_debug(rtwdev, RTW89_DBG_RFK, "[DPK] tmp GL = %d\n", result); + + return result; +} + +static void _dpk_kset_query(struct rtw89_dev *rtwdev, enum rtw89_rf_path path) +{ + struct rtw89_dpk_info *dpk = &rtwdev->dpk; + + rtw89_phy_write32_mask(rtwdev, R_KIP_RPT + (path << 8), B_KIP_RPT_SEL, 0x10); + dpk->cur_k_set = + rtw89_phy_read32_mask(rtwdev, R_RPT_PER + (path << 8), 0xE0000000) - 1; +} + +static void _dpk_kip_set_txagc(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy, + enum rtw89_rf_path path, u8 dbm, bool set_from_bb) +{ + if (set_from_bb) { + dbm = clamp_t(u8, dbm, 7, 24); + rtw89_debug(rtwdev, RTW89_DBG_RFK, "[DPK] set S%d txagc to %ddBm\n", path, dbm); + rtw89_phy_write32_mask(rtwdev, R_TXPWRB + (path << 13), B_TXPWRB_VAL, dbm << 2); + } + _dpk_one_shot(rtwdev, phy, path, D_TXAGC); + _dpk_kset_query(rtwdev, path); +} + +static u8 _dpk_gainloss(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy, + enum rtw89_rf_path path, u8 kidx) +{ + _dpk_one_shot(rtwdev, phy, path, D_GAIN_LOSS); + _dpk_kip_set_txagc(rtwdev, phy, path, 0xff, false); + + rtw89_phy_write32_mask(rtwdev, R_DPK_GL + (path << 8), B_DPK_GL_A1, 0x0); + rtw89_phy_write32_mask(rtwdev, R_DPK_GL + (path << 8), B_DPK_GL_A0, 0x0); + + return _dpk_gainloss_read(rtwdev); +} + +static bool _dpk_pas_read(struct rtw89_dev *rtwdev, bool is_check) +{ + u32 val1_i = 0, val1_q = 0, val2_i = 0, val2_q = 0; + u8 i; + + rtw89_phy_write32_mask(rtwdev, R_KIP_RPT1, MASKBYTE2, 0x06); + rtw89_phy_write32_mask(rtwdev, R_DPK_CFG2, B_DPK_CFG2_ST, 0x0); + rtw89_phy_write32_mask(rtwdev, R_DPK_CFG3, MASKBYTE2, 0x08); + + if (is_check) { + rtw89_phy_write32_mask(rtwdev, R_DPK_CFG3, MASKBYTE3, 0x00); + val1_i = rtw89_phy_read32_mask(rtwdev, R_RPT_COM, MASKHWORD); + val1_i = abs(sign_extend32(val1_i, 11)); + val1_q = rtw89_phy_read32_mask(rtwdev, R_RPT_COM, MASKLWORD); + val1_q = abs(sign_extend32(val1_q, 11)); + + rtw89_phy_write32_mask(rtwdev, R_DPK_CFG3, MASKBYTE3, 0x1f); + val2_i = rtw89_phy_read32_mask(rtwdev, R_RPT_COM, MASKHWORD); + val2_i = abs(sign_extend32(val2_i, 11)); + val2_q = rtw89_phy_read32_mask(rtwdev, R_RPT_COM, MASKLWORD); + val2_q = abs(sign_extend32(val2_q, 11)); + + rtw89_debug(rtwdev, RTW89_DBG_RFK, "[DPK] PAS_delta = 0x%x\n", + phy_div(val1_i * val1_i + val1_q * val1_q, + val2_i * val2_i + val2_q * val2_q)); + } else { + for (i = 0; i < 32; i++) { + rtw89_phy_write32_mask(rtwdev, R_DPK_CFG3, MASKBYTE3, i); + rtw89_debug(rtwdev, RTW89_DBG_RFK, "[DPK] PAS_Read[%02d]= 0x%08x\n", i, + rtw89_phy_read32_mask(rtwdev, R_RPT_COM, MASKDWORD)); + } + } + + if (val1_i * val1_i + val1_q * val1_q >= (val2_i * val2_i + val2_q * val2_q) * 8 / 5) + return true; + else + return false; +} + +static bool _dpk_kip_set_rxagc(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy, + enum rtw89_rf_path path, u8 kidx) +{ + _dpk_one_shot(rtwdev, phy, path, D_RXAGC); + + return _dpk_sync_check(rtwdev, path, kidx); +} + +static void _dpk_read_rxsram(struct rtw89_dev *rtwdev) +{ + u32 addr; + + rtw89_rfk_parser(rtwdev, &rtw8852c_read_rxsram_pre_defs_tbl); + + for (addr = 0; addr < 0x200; addr++) { + rtw89_phy_write32_mask(rtwdev, R_SRAM_IQRX, MASKDWORD, 0x00010000 | addr); + + rtw89_debug(rtwdev, RTW89_DBG_RFK, "[DPK] RXSRAM[%03d] = 0x%07x\n", addr, + rtw89_phy_read32_mask(rtwdev, R_RPT_COM, MASKDWORD)); + } + + rtw89_rfk_parser(rtwdev, &rtw8852c_read_rxsram_post_defs_tbl); +} + +static void _dpk_bypass_rxiqc(struct rtw89_dev *rtwdev, enum rtw89_rf_path path) +{ + rtw89_phy_write32_mask(rtwdev, R_DPD_V1 + (path << 8), B_DPD_LBK, 0x1); + rtw89_phy_write32_mask(rtwdev, R_RXIQC + (path << 8), MASKDWORD, 0x40000002); + + rtw89_debug(rtwdev, RTW89_DBG_RFK, "[DPK] Bypass RXIQC\n"); +} + +static u8 _dpk_agc(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy, + enum rtw89_rf_path path, u8 kidx, u8 init_xdbm, u8 loss_only) +{ + struct rtw89_dpk_info *dpk = &rtwdev->dpk; + u8 step = DPK_AGC_STEP_SYNC_DGAIN; + u8 tmp_dbm = init_xdbm, tmp_gl_idx = 0; + u8 tmp_rxbb; + u8 goout = 0, agc_cnt = 0; + u16 dgain = 0; + bool is_fail = false; + int limit = 200; + + do { + switch (step) { + case DPK_AGC_STEP_SYNC_DGAIN: + is_fail = _dpk_kip_set_rxagc(rtwdev, phy, path, kidx); + + if (RTW8852C_DPK_RXSRAM_DBG) + _dpk_read_rxsram(rtwdev); + + if (is_fail) { + goout = 1; + break; + } + + dgain = _dpk_dgain_read(rtwdev); + + if (dgain > 0x5fc || dgain < 0x556) { + _dpk_one_shot(rtwdev, phy, path, D_SYNC); + dgain = _dpk_dgain_read(rtwdev); + } + + if (agc_cnt == 0) { + if (dpk->bp[path][kidx].band == RTW89_BAND_2G) + _dpk_bypass_rxiqc(rtwdev, path); + else + _dpk_lbk_rxiqk(rtwdev, phy, path); + } + step = DPK_AGC_STEP_GAIN_LOSS_IDX; + break; + + case DPK_AGC_STEP_GAIN_LOSS_IDX: + tmp_gl_idx = _dpk_gainloss(rtwdev, phy, path, kidx); + + if ((tmp_gl_idx == 0 && _dpk_pas_read(rtwdev, true)) || + tmp_gl_idx >= 7) + step = DPK_AGC_STEP_GL_GT_CRITERION; + else if (tmp_gl_idx == 0) + step = DPK_AGC_STEP_GL_LT_CRITERION; + else + step = DPK_AGC_STEP_SET_TX_GAIN; + break; + + case DPK_AGC_STEP_GL_GT_CRITERION: + if (tmp_dbm <= 7) { + goout = 1; + rtw89_debug(rtwdev, RTW89_DBG_RFK, "[DPK] Txagc@lower bound!!\n"); + } else { + tmp_dbm = max_t(u8, tmp_dbm - 3, 7); + _dpk_kip_set_txagc(rtwdev, phy, path, tmp_dbm, true); + } + step = DPK_AGC_STEP_SYNC_DGAIN; + agc_cnt++; + break; + + case DPK_AGC_STEP_GL_LT_CRITERION: + if (tmp_dbm >= 24) { + goout = 1; + rtw89_debug(rtwdev, RTW89_DBG_RFK, "[DPK] Txagc@upper bound!!\n"); + } else { + tmp_dbm = min_t(u8, tmp_dbm + 2, 24); + _dpk_kip_set_txagc(rtwdev, phy, path, tmp_dbm, true); + } + step = DPK_AGC_STEP_SYNC_DGAIN; + agc_cnt++; + break; + + case DPK_AGC_STEP_SET_TX_GAIN: + _dpk_kip_control_rfc(rtwdev, path, false); + tmp_rxbb = rtw89_read_rf(rtwdev, path, RR_MOD, RR_MOD_M_RXBB); + if (tmp_rxbb + tmp_gl_idx > 0x1f) + tmp_rxbb = 0x1f; + else + tmp_rxbb = tmp_rxbb + tmp_gl_idx; + + rtw89_write_rf(rtwdev, path, RR_MOD, RR_MOD_M_RXBB, tmp_rxbb); + rtw89_debug(rtwdev, RTW89_DBG_RFK, "[DPK] Adjust RXBB (%+d) = 0x%x\n", + tmp_gl_idx, tmp_rxbb); + _dpk_kip_control_rfc(rtwdev, path, true); + goout = 1; + break; + default: + goout = 1; + break; + } + } while (!goout && agc_cnt < 6 && --limit > 0); + + if (limit <= 0) + rtw89_warn(rtwdev, "[DPK] exceed loop limit\n"); + + return is_fail; +} + +static void _dpk_set_mdpd_para(struct rtw89_dev *rtwdev, u8 order) +{ + static const struct rtw89_rfk_tbl *order_tbls[] = { + &rtw8852c_dpk_mdpd_order0_defs_tbl, + &rtw8852c_dpk_mdpd_order1_defs_tbl, + &rtw8852c_dpk_mdpd_order2_defs_tbl, + &rtw8852c_dpk_mdpd_order3_defs_tbl, + }; + + if (order >= ARRAY_SIZE(order_tbls)) { + rtw89_debug(rtwdev, RTW89_DBG_RFK, "[DPK] Wrong MDPD order!!(0x%x)\n", order); + return; + } + + rtw89_rfk_parser(rtwdev, order_tbls[order]); + + rtw89_debug(rtwdev, RTW89_DBG_RFK, "[DPK] Set %s for IDL\n", + order == 0x0 ? "(5,3,1)" : + order == 0x1 ? "(5,3,0)" : + order == 0x2 ? "(5,0,0)" : "(7,3,1)"); +} + +static void _dpk_idl_mpa(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy, + enum rtw89_rf_path path, u8 kidx) +{ + struct rtw89_dpk_info *dpk = &rtwdev->dpk; + u8 cnt; + u8 ov_flag; + u32 dpk_sync; + + rtw89_phy_write32_mask(rtwdev, R_LDL_NORM, B_LDL_NORM_MA, 0x1); + + if (rtw89_phy_read32_mask(rtwdev, R_DPK_MPA, B_DPK_MPA_T2) == 0x1) + _dpk_set_mdpd_para(rtwdev, 0x2); + else if (rtw89_phy_read32_mask(rtwdev, R_DPK_MPA, B_DPK_MPA_T1) == 0x1) + _dpk_set_mdpd_para(rtwdev, 0x1); + else if (rtw89_phy_read32_mask(rtwdev, R_DPK_MPA, B_DPK_MPA_T0) == 0x1) + _dpk_set_mdpd_para(rtwdev, 0x0); + else if (dpk->bp[path][kidx].bw == RTW89_CHANNEL_WIDTH_5 || + dpk->bp[path][kidx].bw == RTW89_CHANNEL_WIDTH_10 || + dpk->bp[path][kidx].bw == RTW89_CHANNEL_WIDTH_20) + _dpk_set_mdpd_para(rtwdev, 0x2); + else if (dpk->bp[path][kidx].bw == RTW89_CHANNEL_WIDTH_40 || + dpk->bp[path][kidx].bw == RTW89_CHANNEL_WIDTH_80) + _dpk_set_mdpd_para(rtwdev, 0x1); + else + _dpk_set_mdpd_para(rtwdev, 0x0); + + rtw89_phy_write32_mask(rtwdev, R_DPK_IDL, B_DPK_IDL, 0x0); + fsleep(1000); + + _dpk_one_shot(rtwdev, phy, path, D_MDPK_IDL); + rtw89_phy_write32_mask(rtwdev, R_KIP_RPT1, B_KIP_RPT1_SEL, 0x0); + dpk_sync = rtw89_phy_read32_mask(rtwdev, R_RPT_COM, MASKDWORD); + rtw89_debug(rtwdev, RTW89_DBG_RFK, "[DPK] dpk_sync = 0x%x\n", dpk_sync); + + rtw89_phy_write32_mask(rtwdev, R_KIP_RPT1, B_KIP_RPT1_SEL, 0xf); + ov_flag = rtw89_phy_read32_mask(rtwdev, R_RPT_COM, B_PRT_COM_SYNERR); + for (cnt = 0; cnt < 5 && ov_flag == 0x1; cnt++) { + rtw89_debug(rtwdev, RTW89_DBG_RFK, "[DPK] ReK due to MDPK ov!!!\n"); + _dpk_one_shot(rtwdev, phy, path, D_MDPK_IDL); + rtw89_phy_write32_mask(rtwdev, R_KIP_RPT1, B_KIP_RPT1_SEL, 0xf); + ov_flag = rtw89_phy_read32_mask(rtwdev, R_RPT_COM, B_PRT_COM_SYNERR); + } + + if (ov_flag) { + _dpk_set_mdpd_para(rtwdev, 0x2); + _dpk_one_shot(rtwdev, phy, path, D_MDPK_IDL); + } +} + +static bool _dpk_reload_check(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy, + enum rtw89_rf_path path) +{ + struct rtw89_dpk_info *dpk = &rtwdev->dpk; + bool is_reload = false; + u8 idx, cur_band, cur_ch; + + cur_band = rtwdev->hal.current_band_type; + cur_ch = rtwdev->hal.current_channel; + + for (idx = 0; idx < RTW89_DPK_BKUP_NUM; idx++) { + if (cur_band != dpk->bp[path][idx].band || + cur_ch != dpk->bp[path][idx].ch) + continue; + + rtw89_phy_write32_mask(rtwdev, R_COEF_SEL + (path << 8), + B_COEF_SEL_MDPD, idx); + dpk->cur_idx[path] = idx; + is_reload = true; + rtw89_debug(rtwdev, RTW89_DBG_RFK, + "[DPK] reload S%d[%d] success\n", path, idx); + } + + return is_reload; +} + +static void _dpk_kip_pwr_clk_onoff(struct rtw89_dev *rtwdev, bool turn_on) +{ + rtw89_rfk_parser(rtwdev, turn_on ? &rtw8852c_dpk_kip_pwr_clk_on_defs_tbl : + &rtw8852c_dpk_kip_pwr_clk_off_defs_tbl); +} + +static void _dpk_kip_preset_8852c(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy, + enum rtw89_rf_path path, u8 kidx) +{ + rtw89_phy_write32_mask(rtwdev, R_KIP_MOD, B_KIP_MOD, + rtw89_read_rf(rtwdev, path, RR_MOD, RFREG_MASK)); + + if (rtwdev->hal.cv == CHIP_CAV) + rtw89_phy_write32_mask(rtwdev, + R_DPD_CH0A + (path << 8) + (kidx << 2), + B_DPD_SEL, 0x01); + else + rtw89_phy_write32_mask(rtwdev, + R_DPD_CH0A + (path << 8) + (kidx << 2), + B_DPD_SEL, 0x0c); + + _dpk_kip_control_rfc(rtwdev, path, true); + rtw89_phy_write32_mask(rtwdev, R_COEF_SEL + (path << 8), B_COEF_SEL_MDPD, kidx); + + _dpk_one_shot(rtwdev, phy, path, D_KIP_PRESET); +} + +static void _dpk_para_query(struct rtw89_dev *rtwdev, enum rtw89_rf_path path, u8 kidx) +{ +#define _DPK_PARA_TXAGC GENMASK(15, 10) +#define _DPK_PARA_THER GENMASK(31, 26) + struct rtw89_dpk_info *dpk = &rtwdev->dpk; + u32 para; + + para = rtw89_phy_read32_mask(rtwdev, dpk_par_regs[kidx][dpk->cur_k_set] + (path << 8), + MASKDWORD); + + dpk->bp[path][kidx].txagc_dpk = FIELD_GET(_DPK_PARA_TXAGC, para); + dpk->bp[path][kidx].ther_dpk = FIELD_GET(_DPK_PARA_THER, para); + + rtw89_debug(rtwdev, RTW89_DBG_RFK, "[DPK] thermal/ txagc_RF (K%d) = 0x%x/ 0x%x\n", + dpk->cur_k_set, dpk->bp[path][kidx].ther_dpk, dpk->bp[path][kidx].txagc_dpk); +} + +static void _dpk_gain_normalize_8852c(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy, + enum rtw89_rf_path path, u8 kidx, bool is_execute) +{ + struct rtw89_dpk_info *dpk = &rtwdev->dpk; + + if (is_execute) { + rtw89_phy_write32_mask(rtwdev, R_DPK_GN + (path << 8), B_DPK_GN_AG, 0x200); + rtw89_phy_write32_mask(rtwdev, R_DPK_GN + (path << 8), B_DPK_GN_EN, 0x3); + + _dpk_one_shot(rtwdev, phy, path, D_GAIN_NORM); + } else { + rtw89_phy_write32_mask(rtwdev, dpk_par_regs[kidx][dpk->cur_k_set] + (path << 8), + 0x0000007F, 0x5b); + } + dpk->bp[path][kidx].gs = + rtw89_phy_read32_mask(rtwdev, dpk_par_regs[kidx][dpk->cur_k_set] + (path << 8), + 0x0000007F); +} + +static u8 _dpk_order_convert(struct rtw89_dev *rtwdev) +{ + u32 val32 = rtw89_phy_read32_mask(rtwdev, R_LDL_NORM, B_LDL_NORM_OP); + u8 val; + + switch (val32) { + case 0: + val = 0x6; + break; + case 1: + val = 0x2; + break; + case 2: + val = 0x0; + break; + case 3: + val = 0x7; + break; + default: + val = 0xff; + break; + } + + rtw89_debug(rtwdev, RTW89_DBG_RFK, "[DPK] convert MDPD order to 0x%x\n", val); + + return val; +} + +static void _dpk_on(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy, + enum rtw89_rf_path path, u8 kidx) +{ + struct rtw89_dpk_info *dpk = &rtwdev->dpk; + + rtw89_phy_write32_mask(rtwdev, R_LOAD_COEF + (path << 8), B_LOAD_COEF_MDPD, 0x1); + rtw89_phy_write32_mask(rtwdev, R_LOAD_COEF + (path << 8), B_LOAD_COEF_MDPD, 0x0); + rtw89_phy_write32_mask(rtwdev, R_DPD_CH0A + (path << 8) + (kidx << 2), + B_DPD_ORDER, _dpk_order_convert(rtwdev)); + + dpk->bp[path][kidx].mdpd_en = BIT(dpk->cur_k_set); + dpk->bp[path][kidx].path_ok = true; + + rtw89_debug(rtwdev, RTW89_DBG_RFK, "[DPK] S%d[%d] path_ok = 0x%x\n", + path, kidx, dpk->bp[path][kidx].mdpd_en); + + rtw89_phy_write32_mask(rtwdev, R_DPD_CH0A + (path << 8) + (kidx << 2), + B_DPD_MEN, dpk->bp[path][kidx].mdpd_en); + + _dpk_gain_normalize_8852c(rtwdev, phy, path, kidx, false); +} + +static bool _dpk_main(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy, + enum rtw89_rf_path path, u8 gain) +{ + struct rtw89_dpk_info *dpk = &rtwdev->dpk; + u8 kidx = dpk->cur_idx[path]; + u8 init_xdbm = 15; + bool is_fail; + + rtw89_debug(rtwdev, RTW89_DBG_RFK, + "[DPK] ========= S%d[%d] DPK Start =========\n", path, kidx); + _dpk_kip_control_rfc(rtwdev, path, false); + _rf_direct_cntrl(rtwdev, path, false); + rtw89_write_rf(rtwdev, path, RR_BBDC, RFREG_MASK, 0x03ffd); + _dpk_rf_setting(rtwdev, gain, path, kidx); + _set_rx_dck(rtwdev, phy, path, false); + _dpk_kip_pwr_clk_onoff(rtwdev, true); + _dpk_kip_preset_8852c(rtwdev, phy, path, kidx); + _dpk_txpwr_bb_force(rtwdev, path, true); + _dpk_kip_set_txagc(rtwdev, phy, path, init_xdbm, true); + _dpk_tpg_sel(rtwdev, path, kidx); + + is_fail = _dpk_agc(rtwdev, phy, path, kidx, init_xdbm, false); + if (is_fail) + goto _error; + + _dpk_idl_mpa(rtwdev, phy, path, kidx); + _dpk_para_query(rtwdev, path, kidx); + _dpk_on(rtwdev, phy, path, kidx); + +_error: + _dpk_kip_control_rfc(rtwdev, path, false); + rtw89_write_rf(rtwdev, path, RR_MOD, RR_MOD_MASK, RF_RX); + rtw89_debug(rtwdev, RTW89_DBG_RFK, "[DPK] S%d[%d]_K%d %s\n", path, kidx, + dpk->cur_k_set, is_fail ? "need Check" : "is Success"); + + return is_fail; +} + +static void _dpk_init(struct rtw89_dev *rtwdev, u8 path) +{ + struct rtw89_dpk_info *dpk = &rtwdev->dpk; + u8 kidx = dpk->cur_idx[path]; + + dpk->bp[path][kidx].path_ok = false; +} + +static void _dpk_drf_direct_cntrl(struct rtw89_dev *rtwdev, u8 path, bool is_bybb) +{ + if (is_bybb) + rtw89_write_rf(rtwdev, path, RR_BBDC, RR_BBDC_SEL, 0x1); + else + rtw89_write_rf(rtwdev, path, RR_BBDC, RR_BBDC_SEL, 0x0); +} + +static void _dpk_cal_select(struct rtw89_dev *rtwdev, bool force, + enum rtw89_phy_idx phy, u8 kpath) +{ + struct rtw89_dpk_info *dpk = &rtwdev->dpk; + static const u32 kip_reg[] = {0x813c, 0x8124, 0x8120, 0xc0d4, 0xc0d8}; + u32 backup_rf_val[RTW8852C_DPK_RF_PATH][BACKUP_RF_REGS_NR]; + u32 kip_bkup[RTW8852C_DPK_RF_PATH][RTW8852C_DPK_KIP_REG_NUM] = {}; + u8 path; + bool is_fail = true, reloaded[RTW8852C_DPK_RF_PATH] = {false}; + + if (dpk->is_dpk_reload_en) { + for (path = 0; path < RTW8852C_DPK_RF_PATH; path++) { + if (!(kpath & BIT(path))) + continue; + + reloaded[path] = _dpk_reload_check(rtwdev, phy, path); + if (!reloaded[path] && dpk->bp[path][0].ch != 0) + dpk->cur_idx[path] = !dpk->cur_idx[path]; + else + _dpk_onoff(rtwdev, path, false); + } + } else { + for (path = 0; path < RTW8852C_DPK_RF_PATH; path++) + dpk->cur_idx[path] = 0; + } + + for (path = 0; path < RTW8852C_DPK_RF_PATH; path++) { + rtw89_debug(rtwdev, RTW89_DBG_RFK, + "[DPK] ========= S%d[%d] DPK Init =========\n", + path, dpk->cur_idx[path]); + _dpk_bkup_kip(rtwdev, kip_reg, kip_bkup, path); + _rfk_backup_rf_reg(rtwdev, backup_rf_val[path], path); + _dpk_information(rtwdev, phy, path); + _dpk_init(rtwdev, path); + if (rtwdev->is_tssi_mode[path]) + _dpk_tssi_pause(rtwdev, path, true); + } + + for (path = 0; path < RTW8852C_DPK_RF_PATH; path++) { + rtw89_debug(rtwdev, RTW89_DBG_RFK, + "[DPK] ========= S%d[%d] DPK Start =========\n", + path, dpk->cur_idx[path]); + rtw8852c_disable_rxagc(rtwdev, path, 0x0); + _dpk_drf_direct_cntrl(rtwdev, path, false); + _dpk_bb_afe_setting(rtwdev, phy, path, kpath); + is_fail = _dpk_main(rtwdev, phy, path, 1); + _dpk_onoff(rtwdev, path, is_fail); + } + + for (path = 0; path < RTW8852C_DPK_RF_PATH; path++) { + rtw89_debug(rtwdev, RTW89_DBG_RFK, + "[DPK] ========= S%d[%d] DPK Restore =========\n", + path, dpk->cur_idx[path]); + _dpk_kip_restore(rtwdev, phy, path); + _dpk_reload_kip(rtwdev, kip_reg, kip_bkup, path); + _rfk_restore_rf_reg(rtwdev, backup_rf_val[path], path); + _dpk_bb_afe_restore(rtwdev, path); + rtw8852c_disable_rxagc(rtwdev, path, 0x1); + if (rtwdev->is_tssi_mode[path]) + _dpk_tssi_pause(rtwdev, path, false); + } + + _dpk_kip_pwr_clk_onoff(rtwdev, false); +} + +static bool _dpk_bypass_check(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy) +{ + struct rtw89_fem_info *fem = &rtwdev->fem; + + if (rtwdev->hal.cv == CHIP_CAV && rtwdev->hal.current_band_type != RTW89_BAND_2G) { + rtw89_debug(rtwdev, RTW89_DBG_RFK, "[DPK] Skip DPK due to CAV & not 2G!!\n"); + return true; + } else if (fem->epa_2g && rtwdev->hal.current_band_type == RTW89_BAND_2G) { + rtw89_debug(rtwdev, RTW89_DBG_RFK, "[DPK] Skip DPK due to 2G_ext_PA exist!!\n"); + return true; + } else if (fem->epa_5g && rtwdev->hal.current_band_type == RTW89_BAND_5G) { + rtw89_debug(rtwdev, RTW89_DBG_RFK, "[DPK] Skip DPK due to 5G_ext_PA exist!!\n"); + return true; + } else if (fem->epa_6g && rtwdev->hal.current_band_type == RTW89_BAND_6G) { + rtw89_debug(rtwdev, RTW89_DBG_RFK, "[DPK] Skip DPK due to 6G_ext_PA exist!!\n"); + return true; + } + + return false; +} + +static void _dpk_force_bypass(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy) +{ + u8 path, kpath; + + kpath = _kpath(rtwdev, phy); + + for (path = 0; path < RTW8852C_DPK_RF_PATH; path++) { + if (kpath & BIT(path)) + _dpk_onoff(rtwdev, path, true); + } +} + +static void _dpk(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy, bool force) +{ + rtw89_debug(rtwdev, RTW89_DBG_RFK, + "[DPK] ****** DPK Start (Ver: 0x%x, Cv: %d, RF_para: %d) ******\n", + RTW8852C_DPK_VER, rtwdev->hal.cv, + RTW8852C_RF_REL_VERSION); + + if (_dpk_bypass_check(rtwdev, phy)) + _dpk_force_bypass(rtwdev, phy); + else + _dpk_cal_select(rtwdev, force, phy, _kpath(rtwdev, phy)); + + if (rtw89_read_rf(rtwdev, RF_PATH_A, RR_DCKC, RR_DCKC_CHK) == 0x1) + rtw8852c_rx_dck(rtwdev, phy, false); +} + +static void _dpk_onoff(struct rtw89_dev *rtwdev, + enum rtw89_rf_path path, bool off) +{ + struct rtw89_dpk_info *dpk = &rtwdev->dpk; + u8 val, kidx = dpk->cur_idx[path]; + + val = dpk->is_dpk_enable && !off && dpk->bp[path][kidx].path_ok ? + dpk->bp[path][kidx].mdpd_en : 0; + + rtw89_phy_write32_mask(rtwdev, R_DPD_CH0A + (path << 8) + (kidx << 2), + B_DPD_MEN, val); + + rtw89_debug(rtwdev, RTW89_DBG_RFK, "[DPK] S%d[%d] DPK %s !!!\n", path, + kidx, dpk->is_dpk_enable && !off ? "enable" : "disable"); +} + +static void _dpk_track(struct rtw89_dev *rtwdev) +{ + struct rtw89_dpk_info *dpk = &rtwdev->dpk; + u8 path, kidx; + u8 txagc_rf = 0; + s8 txagc_bb = 0, txagc_bb_tp = 0, txagc_ofst = 0; + u8 cur_ther; + s8 delta_ther = 0; + s16 pwsf_tssi_ofst; + + for (path = 0; path < RTW8852C_DPK_RF_PATH; path++) { + kidx = dpk->cur_idx[path]; + rtw89_debug(rtwdev, RTW89_DBG_RFK_TRACK, + "[DPK_TRK] ================[S%d[%d] (CH %d)]================\n", + path, kidx, dpk->bp[path][kidx].ch); + + txagc_rf = + rtw89_phy_read32_mask(rtwdev, R_TXAGC_BB + (path << 13), 0x0000003f); + txagc_bb = + rtw89_phy_read32_mask(rtwdev, R_TXAGC_BB + (path << 13), MASKBYTE2); + txagc_bb_tp = + rtw89_phy_read32_mask(rtwdev, R_TXAGC_BTP + (path << 13), B_TXAGC_BTP); + + /* report from KIP */ + rtw89_phy_write32_mask(rtwdev, R_KIP_RPT + (path << 8), B_KIP_RPT_SEL, 0xf); + cur_ther = + rtw89_phy_read32_mask(rtwdev, R_RPT_PER + (path << 8), B_RPT_PER_TH); + txagc_ofst = + rtw89_phy_read32_mask(rtwdev, R_RPT_PER + (path << 8), B_RPT_PER_OF); + pwsf_tssi_ofst = + rtw89_phy_read32_mask(rtwdev, R_RPT_PER + (path << 8), B_RPT_PER_TSSI); + pwsf_tssi_ofst = sign_extend32(pwsf_tssi_ofst, 12); + + cur_ther = ewma_thermal_read(&rtwdev->phystat.avg_thermal[path]); + + rtw89_debug(rtwdev, RTW89_DBG_RFK_TRACK, + "[DPK_TRK] thermal now = %d\n", cur_ther); + + if (dpk->bp[path][kidx].ch != 0 && cur_ther != 0) + delta_ther = dpk->bp[path][kidx].ther_dpk - cur_ther; + + delta_ther = delta_ther * 1 / 2; + + rtw89_debug(rtwdev, RTW89_DBG_RFK_TRACK, + "[DPK_TRK] extra delta_ther = %d (0x%x / 0x%x@k)\n", + delta_ther, cur_ther, dpk->bp[path][kidx].ther_dpk); + rtw89_debug(rtwdev, RTW89_DBG_RFK_TRACK, + "[DPK_TRK] delta_txagc = %d (0x%x / 0x%x@k)\n", + txagc_rf - dpk->bp[path][kidx].txagc_dpk, txagc_rf, + dpk->bp[path][kidx].txagc_dpk); + rtw89_debug(rtwdev, RTW89_DBG_RFK_TRACK, + "[DPK_TRK] txagc_offset / pwsf_tssi_ofst = 0x%x / %+d\n", + txagc_ofst, pwsf_tssi_ofst); + rtw89_debug(rtwdev, RTW89_DBG_RFK_TRACK, + "[DPK_TRK] txagc_bb_tp / txagc_bb = 0x%x / 0x%x\n", + txagc_bb_tp, txagc_bb); + + if (rtw89_phy_read32_mask(rtwdev, R_DPK_WR, B_DPK_WR_ST) == 0x0 && + txagc_rf != 0 && rtwdev->hal.cv == CHIP_CAV) { + rtw89_debug(rtwdev, RTW89_DBG_RFK_TRACK, + "[DPK_TRK] New pwsf = 0x%x\n", 0x78 - delta_ther); + + rtw89_phy_write32_mask(rtwdev, R_DPD_BND + (path << 8) + (kidx << 2), + 0x07FC0000, 0x78 - delta_ther); + } + } +} + static void _tssi_set_sys(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy, enum rtw89_rf_path path) { @@ -2781,6 +3873,28 @@ void rtw8852c_rx_dck(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy, bool is_a } } +void rtw8852c_dpk(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy_idx) +{ + u32 tx_en; + u8 phy_map = rtw89_btc_phymap(rtwdev, phy_idx, 0); + + rtw89_btc_ntfy_wl_rfk(rtwdev, phy_map, BTC_WRFKT_DPK, BTC_WRFK_START); + rtw89_chip_stop_sch_tx(rtwdev, phy_idx, &tx_en, RTW89_SCH_TX_SEL_ALL); + _wait_rx_mode(rtwdev, _kpath(rtwdev, phy_idx)); + + rtwdev->dpk.is_dpk_enable = true; + rtwdev->dpk.is_dpk_reload_en = false; + _dpk(rtwdev, phy_idx, false); + + rtw89_chip_resume_sch_tx(rtwdev, phy_idx, tx_en); + rtw89_btc_ntfy_wl_rfk(rtwdev, phy_map, BTC_WRFKT_DPK, BTC_WRFK_STOP); +} + +void rtw8852c_dpk_track(struct rtw89_dev *rtwdev) +{ + _dpk_track(rtwdev); +} + void rtw8852c_tssi(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy) { u32 i, path = RF_PATH_A, path_max = RF_PATH_NUM_8852C; diff --git a/drivers/net/wireless/realtek/rtw89/rtw8852c_rfk.h b/drivers/net/wireless/realtek/rtw89/rtw8852c_rfk.h index 5c0623f6af208..e42fb1a4965ef 100644 --- a/drivers/net/wireless/realtek/rtw89/rtw8852c_rfk.h +++ b/drivers/net/wireless/realtek/rtw89/rtw8852c_rfk.h @@ -11,6 +11,8 @@ void rtw8852c_rck(struct rtw89_dev *rtwdev); void rtw8852c_dack(struct rtw89_dev *rtwdev); void rtw8852c_iqk(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy_idx); void rtw8852c_rx_dck(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy_idx, bool is_afe); +void rtw8852c_dpk(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy); +void rtw8852c_dpk_track(struct rtw89_dev *rtwdev); void rtw8852c_tssi(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy); void rtw8852c_tssi_scan(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy); void rtw8852c_tssi_cont_en_phyidx(struct rtw89_dev *rtwdev, bool en, u8 phy_idx);