diff options
author | David S. Miller <davem@davemloft.net> | 2020-07-20 17:52:50 -0700 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2020-07-20 17:52:50 -0700 |
commit | cfd6920175ac848e057ed258e87c427792f371d0 (patch) | |
tree | cb5d78abeb9eb98235ab8b47c8ae0ab865a1a307 | |
parent | 256ca7449fbcc0351c349abf83d1869e31504725 (diff) | |
parent | 0e20c3e10333326fc63646fa40b159eb88b7e8c8 (diff) | |
download | linux-cfd6920175ac848e057ed258e87c427792f371d0.tar.gz linux-cfd6920175ac848e057ed258e87c427792f371d0.tar.bz2 linux-cfd6920175ac848e057ed258e87c427792f371d0.zip |
Merge tag 'wireless-drivers-next-2020-07-20' of git://git.kernel.org/pub/scm/linux/kernel/git/kvalo/wireless-drivers-next
Kalle Valo says:
====================
wireless-drivers-next patches for v5.9
First set of patches for v5.9. This comes later than usual as I was
offline for two weeks. The biggest change here is moving Microchip
wilc1000 driver from staging. There was an immutable topic branch with
one commit moving the whole driver and the topic branch was pulled
both to staging-next and wireless-drivers-next. At the moment the only
reported conflict is in MAINTAINERS file, so I'm hoping the move
should go smoothly.
Other notable changes are ath11k getting 6 GHz band support and rtw88
supporting RTL8821CE. And there's also the usual fixes, API changes
and cleanups all over.
Major changes:
wilc1000
* move from drivers/staging to drivers/net/wireless/microchip
ath11k
* add 6G band support
* add spectral scan support
iwlwifi
* make FW reconfiguration quieter by not using warn level
rtw88
* add support for RTL8821CE
====================
Signed-off-by: David S. Miller <davem@davemloft.net>
131 files changed, 11831 insertions, 626 deletions
diff --git a/drivers/staging/wilc1000/microchip,wilc1000.yaml b/Documentation/devicetree/bindings/net/wireless/microchip,wilc1000.yaml index 2c320eb2a8c4..2c320eb2a8c4 100644 --- a/drivers/staging/wilc1000/microchip,wilc1000.yaml +++ b/Documentation/devicetree/bindings/net/wireless/microchip,wilc1000.yaml diff --git a/MAINTAINERS b/MAINTAINERS index b325ed166228..6200eb14757c 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -11352,6 +11352,13 @@ L: linux-arm-kernel@lists.infradead.org (moderated for non-subscribers) S: Supported F: drivers/usb/gadget/udc/atmel_usba_udc.* +MICROCHIP WILC1000 WIFI DRIVER +M: Ajay Singh <ajay.kathat@microchip.com> +M: Claudiu Beznea <claudiu.beznea@microchip.com> +L: linux-wireless@vger.kernel.org +S: Supported +F: drivers/net/wireless/microchip/wilc1000/ + MICROCHIP XDMA DRIVER M: Ludovic Desroches <ludovic.desroches@microchip.com> L: linux-arm-kernel@lists.infradead.org @@ -16256,13 +16263,6 @@ M: Forest Bond <forest@alittletooquiet.net> S: Odd Fixes F: drivers/staging/vt665?/ -STAGING - WILC1000 WIFI DRIVER -M: Adham Abozaeid <adham.abozaeid@microchip.com> -M: Ajay Singh <ajay.kathat@microchip.com> -L: linux-wireless@vger.kernel.org -S: Supported -F: drivers/staging/wilc1000/ - STAGING SUBSYSTEM M: Greg Kroah-Hartman <gregkh@linuxfoundation.org> L: devel@driverdev.osuosl.org diff --git a/drivers/net/wireless/Kconfig b/drivers/net/wireless/Kconfig index 2c6dd50b6935..170a64e67709 100644 --- a/drivers/net/wireless/Kconfig +++ b/drivers/net/wireless/Kconfig @@ -14,7 +14,7 @@ menuconfig WLAN device drivers. For a complete list of drivers and documentation on them refer to the wireless wiki: - http://wireless.kernel.org/en/users/Drivers + https://wireless.wiki.kernel.org/en/users/Drivers if WLAN @@ -40,6 +40,7 @@ source "drivers/net/wireless/intel/Kconfig" 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/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 6cfe74515c95..80b324499786 100644 --- a/drivers/net/wireless/Makefile +++ b/drivers/net/wireless/Makefile @@ -12,6 +12,7 @@ obj-$(CONFIG_WLAN_VENDOR_INTEL) += intel/ 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_RALINK) += ralink/ obj-$(CONFIG_WLAN_VENDOR_REALTEK) += realtek/ obj-$(CONFIG_WLAN_VENDOR_RSI) += rsi/ diff --git a/drivers/net/wireless/admtek/adm8211.c b/drivers/net/wireless/admtek/adm8211.c index ba326f6c1214..22f9f2f8af10 100644 --- a/drivers/net/wireless/admtek/adm8211.c +++ b/drivers/net/wireless/admtek/adm8211.c @@ -1976,35 +1976,20 @@ static void adm8211_remove(struct pci_dev *pdev) } -#ifdef CONFIG_PM -static int adm8211_suspend(struct pci_dev *pdev, pm_message_t state) -{ - pci_save_state(pdev); - pci_set_power_state(pdev, pci_choose_state(pdev, state)); - return 0; -} - -static int adm8211_resume(struct pci_dev *pdev) -{ - pci_set_power_state(pdev, PCI_D0); - pci_restore_state(pdev); - return 0; -} -#endif /* CONFIG_PM */ - +#define adm8211_suspend NULL +#define adm8211_resume NULL MODULE_DEVICE_TABLE(pci, adm8211_pci_id_table); +static SIMPLE_DEV_PM_OPS(adm8211_pm_ops, adm8211_suspend, adm8211_resume); + /* TODO: implement enable_wake */ static struct pci_driver adm8211_driver = { .name = "adm8211", .id_table = adm8211_pci_id_table, .probe = adm8211_probe, .remove = adm8211_remove, -#ifdef CONFIG_PM - .suspend = adm8211_suspend, - .resume = adm8211_resume, -#endif /* CONFIG_PM */ + .driver.pm = &adm8211_pm_ops, }; module_pci_driver(adm8211_driver); diff --git a/drivers/net/wireless/ath/Kconfig b/drivers/net/wireless/ath/Kconfig index 6e9d46b96555..d88edbf1bea3 100644 --- a/drivers/net/wireless/ath/Kconfig +++ b/drivers/net/wireless/ath/Kconfig @@ -15,11 +15,11 @@ config WLAN_VENDOR_ATH For more information and documentation on this module you can visit: - http://wireless.kernel.org/en/users/Drivers/ath + https://wireless.wiki.kernel.org/en/users/Drivers/ath For information on all Atheros wireless drivers visit: - http://wireless.kernel.org/en/users/Drivers/Atheros + https://wireless.wiki.kernel.org/en/users/Drivers/Atheros if WLAN_VENDOR_ATH diff --git a/drivers/net/wireless/ath/ath10k/htt_tx.c b/drivers/net/wireless/ath/ath10k/htt_tx.c index 4fd10ac3a941..bbe869575855 100644 --- a/drivers/net/wireless/ath/ath10k/htt_tx.c +++ b/drivers/net/wireless/ath/ath10k/htt_tx.c @@ -1591,7 +1591,9 @@ static int ath10k_htt_tx_32(struct ath10k_htt *htt, err_unmap_msdu: dma_unmap_single(dev, skb_cb->paddr, msdu->len, DMA_TO_DEVICE); err_free_msdu_id: + spin_lock_bh(&htt->tx_lock); ath10k_htt_tx_free_msdu_id(htt, msdu_id); + spin_unlock_bh(&htt->tx_lock); err: return res; } @@ -1798,7 +1800,9 @@ static int ath10k_htt_tx_64(struct ath10k_htt *htt, err_unmap_msdu: dma_unmap_single(dev, skb_cb->paddr, msdu->len, DMA_TO_DEVICE); err_free_msdu_id: + spin_lock_bh(&htt->tx_lock); ath10k_htt_tx_free_msdu_id(htt, msdu_id); + spin_unlock_bh(&htt->tx_lock); err: return res; } diff --git a/drivers/net/wireless/ath/ath10k/usb.c b/drivers/net/wireless/ath/ath10k/usb.c index b7daf344d012..05a620ff6fe2 100644 --- a/drivers/net/wireless/ath/ath10k/usb.c +++ b/drivers/net/wireless/ath/ath10k/usb.c @@ -824,7 +824,7 @@ static int ath10k_usb_setup_pipe_resources(struct ath10k *ar, ath10k_dbg(ar, ATH10K_DBG_USB, "usb setting up pipes using interface\n"); - /* walk decriptors and setup pipes */ + /* walk descriptors and setup pipes */ for (i = 0; i < iface_desc->desc.bNumEndpoints; ++i) { endpoint = &iface_desc->endpoint[i].desc; diff --git a/drivers/net/wireless/ath/ath11k/Kconfig b/drivers/net/wireless/ath/ath11k/Kconfig index 7acb42e2e6e2..88a97356f0a1 100644 --- a/drivers/net/wireless/ath/ath11k/Kconfig +++ b/drivers/net/wireless/ath/ath11k/Kconfig @@ -34,3 +34,12 @@ config ATH11K_TRACING depends on ATH11K && EVENT_TRACING help Select this to use ath11k tracing infrastructure. + +config ATH11K_SPECTRAL + bool "QCA ath11k spectral scan support" + depends on ATH11K_DEBUGFS + depends on RELAY + help + Enable ath11k spectral scan support + + Say Y to enable access to the FFT/spectral data via debugfs. diff --git a/drivers/net/wireless/ath/ath11k/Makefile b/drivers/net/wireless/ath/ath11k/Makefile index fe7736e53583..104186373c9e 100644 --- a/drivers/net/wireless/ath/ath11k/Makefile +++ b/drivers/net/wireless/ath/ath11k/Makefile @@ -15,12 +15,14 @@ ath11k-y += core.o \ dp_rx.o \ debug.o \ ce.o \ - peer.o + peer.o \ + dbring.o ath11k-$(CONFIG_ATH11K_DEBUGFS) += debug_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 # for tracing framework to find trace.h CFLAGS_trace.o := -I$(src) diff --git a/drivers/net/wireless/ath/ath11k/core.c b/drivers/net/wireless/ath/ath11k/core.c index 02501cc154fe..905cd8beaf28 100644 --- a/drivers/net/wireless/ath/ath11k/core.c +++ b/drivers/net/wireless/ath/ath11k/core.c @@ -400,8 +400,16 @@ static int ath11k_core_pdev_create(struct ath11k_base *ab) goto err_dp_pdev_free; } + ret = ath11k_spectral_init(ab); + if (ret) { + ath11k_err(ab, "failed to init spectral %d\n", ret); + goto err_thermal_unregister; + } + return 0; +err_thermal_unregister: + ath11k_thermal_unregister(ab); err_dp_pdev_free: ath11k_dp_pdev_free(ab); err_mac_unregister: @@ -414,6 +422,7 @@ err_pdev_debug: static void ath11k_core_pdev_destroy(struct ath11k_base *ab) { + ath11k_spectral_deinit(ab); ath11k_thermal_unregister(ab); ath11k_mac_unregister(ab); ath11k_hif_irq_disable(ab); @@ -582,6 +591,7 @@ static int ath11k_core_reconfigure_on_crash(struct ath11k_base *ab) ath11k_thermal_unregister(ab); ath11k_hif_irq_disable(ab); ath11k_dp_pdev_free(ab); + ath11k_spectral_deinit(ab); ath11k_hif_stop(ab); ath11k_wmi_detach(ab); ath11k_dp_pdev_reo_cleanup(ab); diff --git a/drivers/net/wireless/ath/ath11k/core.h b/drivers/net/wireless/ath/ath11k/core.h index e04f0e711779..e5c4e19020ee 100644 --- a/drivers/net/wireless/ath/ath11k/core.h +++ b/drivers/net/wireless/ath/ath11k/core.h @@ -21,6 +21,8 @@ #include "hal_rx.h" #include "reg.h" #include "thermal.h" +#include "dbring.h" +#include "spectral.h" #define SM(_v, _f) (((_v) << _f##_LSB) & _f##_MASK) @@ -215,12 +217,15 @@ struct ath11k_vif { bool is_started; bool is_up; + bool spectral_enabled; u32 aid; u8 bssid[ETH_ALEN]; struct cfg80211_bitrate_mask bitrate_mask; int num_legacy_stations; int rtscts_prot_mode; int txpower; + bool rsnie_present; + bool wpaie_present; }; struct ath11k_vif_iter { @@ -353,7 +358,10 @@ struct ath11k_sta { #endif }; -#define ATH11K_NUM_CHANS 41 +#define ATH11K_MIN_5G_FREQ 4150 +#define ATH11K_MIN_6G_FREQ 5945 +#define ATH11K_MAX_6G_FREQ 7115 +#define ATH11K_NUM_CHANS 100 #define ATH11K_MAX_5G_CHAN 173 enum ath11k_state { @@ -431,6 +439,7 @@ struct ath11k { u32 vht_cap_info; struct ath11k_he ar_he; enum ath11k_state state; + bool supports_6ghz; struct { struct completion started; struct completion completed; @@ -537,6 +546,9 @@ struct ath11k { #ifdef CONFIG_ATH11K_DEBUGFS struct ath11k_debug debug; #endif +#ifdef CONFIG_ATH11K_SPECTRAL + struct ath11k_spectral spectral; +#endif bool dfs_block_radar_events; struct ath11k_thermal thermal; }; @@ -548,6 +560,7 @@ struct ath11k_band_cap { u32 he_mcs; u32 he_cap_phy_info[PSOC_HOST_MAX_PHY_SIZE]; struct ath11k_ppe_threshold he_ppet; + u16 he_6ghz_capa; }; struct ath11k_pdev_cap { @@ -579,12 +592,42 @@ struct ath11k_board_data { /* IPQ8074 HW channel counters frequency value in hertz */ #define IPQ8074_CC_FREQ_HERTZ 320000 -struct ath11k_soc_dp_rx_stats { +struct ath11k_bp_stats { + /* Head Pointer reported by the last HTT Backpressure event for the ring */ + u16 hp; + + /* Tail Pointer reported by the last HTT Backpressure event for the ring */ + u16 tp; + + /* Number of Backpressure events received for the ring */ + u32 count; + + /* Last recorded event timestamp */ + unsigned long jiffies; +}; + +struct ath11k_dp_ring_bp_stats { + struct ath11k_bp_stats umac_ring_bp_stats[HTT_SW_UMAC_RING_IDX_MAX]; + struct ath11k_bp_stats lmac_ring_bp_stats[HTT_SW_LMAC_RING_IDX_MAX][MAX_RADIOS]; +}; + +struct ath11k_soc_dp_tx_err_stats { + /* TCL Ring Descriptor unavailable */ + u32 desc_na[DP_TCL_NUM_RING_MAX]; + /* Other failures during dp_tx due to mem allocation failure + * idr unavailable etc. + */ + atomic_t misc_fail; +}; + +struct ath11k_soc_dp_stats { u32 err_ring_pkts; u32 invalid_rbm; u32 rxdma_error[HAL_REO_ENTR_RING_RXDMA_ECODE_MAX]; u32 reo_error[HAL_REO_DEST_RING_ERROR_CODE_MAX]; u32 hal_reo_error[DP_REO_DST_RING_MAX]; + struct ath11k_soc_dp_tx_err_stats tx_err; + struct ath11k_dp_ring_bp_stats bp_stats; }; /* Master structure to hold the hw data which may be used in core module */ @@ -653,7 +696,7 @@ struct ath11k_base { struct dentry *debugfs_soc; struct dentry *debugfs_ath11k; #endif - struct ath11k_soc_dp_rx_stats soc_stats; + struct ath11k_soc_dp_stats soc_stats; unsigned long dev_flags; struct completion driver_recovery; @@ -668,6 +711,9 @@ struct ath11k_base { /* Round robbin based TCL ring selector */ atomic_t tcl_ring_selector; + struct ath11k_dbring_cap *db_caps; + u32 num_db_cap; + /* must be last */ u8 drv_priv[0] __aligned(sizeof(void *)); }; diff --git a/drivers/net/wireless/ath/ath11k/dbring.c b/drivers/net/wireless/ath/ath11k/dbring.c new file mode 100644 index 000000000000..cf20db370123 --- /dev/null +++ b/drivers/net/wireless/ath/ath11k/dbring.c @@ -0,0 +1,356 @@ +// SPDX-License-Identifier: BSD-3-Clause-Clear +/* + * Copyright (c) 2019-2020 The Linux Foundation. All rights reserved. + */ + +#include "core.h" +#include "debug.h" + +static int ath11k_dbring_bufs_replenish(struct ath11k *ar, + struct ath11k_dbring *ring, + struct ath11k_dbring_element *buff, + gfp_t gfp) +{ + struct ath11k_base *ab = ar->ab; + struct hal_srng *srng; + dma_addr_t paddr; + void *ptr_aligned, *ptr_unaligned, *desc; + int ret; + int buf_id; + u32 cookie; + + srng = &ab->hal.srng_list[ring->refill_srng.ring_id]; + + lockdep_assert_held(&srng->lock); + + ath11k_hal_srng_access_begin(ab, srng); + + ptr_unaligned = buff->payload; + ptr_aligned = PTR_ALIGN(ptr_unaligned, ring->buf_align); + paddr = dma_map_single(ab->dev, ptr_aligned, ring->buf_sz, + DMA_FROM_DEVICE); + + ret = dma_mapping_error(ab->dev, paddr); + if (ret) + goto err; + + spin_lock_bh(&ring->idr_lock); + buf_id = idr_alloc(&ring->bufs_idr, buff, 0, ring->bufs_max, gfp); + spin_unlock_bh(&ring->idr_lock); + if (buf_id < 0) { + ret = -ENOBUFS; + goto err_dma_unmap; + } + + desc = ath11k_hal_srng_src_get_next_entry(ab, srng); + if (!desc) { + ret = -ENOENT; + goto err_idr_remove; + } + + buff->paddr = paddr; + + cookie = FIELD_PREP(DP_RXDMA_BUF_COOKIE_PDEV_ID, ar->pdev_idx) | + FIELD_PREP(DP_RXDMA_BUF_COOKIE_BUF_ID, buf_id); + + ath11k_hal_rx_buf_addr_info_set(desc, paddr, cookie, 0); + + ath11k_hal_srng_access_end(ab, srng); + + return 0; + +err_idr_remove: + spin_lock_bh(&ring->idr_lock); + idr_remove(&ring->bufs_idr, buf_id); + spin_unlock_bh(&ring->idr_lock); +err_dma_unmap: + dma_unmap_single(ab->dev, paddr, ring->buf_sz, + DMA_FROM_DEVICE); +err: + ath11k_hal_srng_access_end(ab, srng); + return ret; +} + +static int ath11k_dbring_fill_bufs(struct ath11k *ar, + struct ath11k_dbring *ring, + gfp_t gfp) +{ + struct ath11k_dbring_element *buff; + struct hal_srng *srng; + int num_remain, req_entries, num_free; + u32 align; + int size, ret; + + srng = &ar->ab->hal.srng_list[ring->refill_srng.ring_id]; + + spin_lock_bh(&srng->lock); + + num_free = ath11k_hal_srng_src_num_free(ar->ab, srng, true); + req_entries = min(num_free, ring->bufs_max); + num_remain = req_entries; + align = ring->buf_align; + size = sizeof(*buff) + ring->buf_sz + align - 1; + + while (num_remain > 0) { + buff = kzalloc(size, gfp); + if (!buff) + break; + + ret = ath11k_dbring_bufs_replenish(ar, ring, buff, gfp); + if (ret) { + ath11k_warn(ar->ab, "failed to replenish db ring num_remain %d req_ent %d\n", + num_remain, req_entries); + kfree(buff); + break; + } + num_remain--; + } + + spin_unlock_bh(&srng->lock); + + return num_remain; +} + +int ath11k_dbring_wmi_cfg_setup(struct ath11k *ar, + struct ath11k_dbring *ring, + enum wmi_direct_buffer_module id) +{ + struct ath11k_wmi_pdev_dma_ring_cfg_req_cmd param = {0}; + int ret; + + if (id >= WMI_DIRECT_BUF_MAX) + return -EINVAL; + + param.pdev_id = DP_SW2HW_MACID(ring->pdev_id); + param.module_id = id; + param.base_paddr_lo = lower_32_bits(ring->refill_srng.paddr); + param.base_paddr_hi = upper_32_bits(ring->refill_srng.paddr); + param.head_idx_paddr_lo = lower_32_bits(ring->hp_addr); + param.head_idx_paddr_hi = upper_32_bits(ring->hp_addr); + param.tail_idx_paddr_lo = lower_32_bits(ring->tp_addr); + param.tail_idx_paddr_hi = upper_32_bits(ring->tp_addr); + param.num_elems = ring->bufs_max; + param.buf_size = ring->buf_sz; + param.num_resp_per_event = ring->num_resp_per_event; + param.event_timeout_ms = ring->event_timeout_ms; + + ret = ath11k_wmi_pdev_dma_ring_cfg(ar, ¶m); + if (ret) { + ath11k_warn(ar->ab, "failed to setup db ring cfg\n"); + return ret; + } + + return 0; +} + +int ath11k_dbring_set_cfg(struct ath11k *ar, struct ath11k_dbring *ring, + u32 num_resp_per_event, u32 event_timeout_ms, + int (*handler)(struct ath11k *, + struct ath11k_dbring_data *)) +{ + if (WARN_ON(!ring)) + return -EINVAL; + + ring->num_resp_per_event = num_resp_per_event; + ring->event_timeout_ms = event_timeout_ms; + ring->handler = handler; + + return 0; +} + +int ath11k_dbring_buf_setup(struct ath11k *ar, + struct ath11k_dbring *ring, + struct ath11k_dbring_cap *db_cap) +{ + struct ath11k_base *ab = ar->ab; + struct hal_srng *srng; + int ret; + + srng = &ab->hal.srng_list[ring->refill_srng.ring_id]; + ring->bufs_max = ring->refill_srng.size / + ath11k_hal_srng_get_entrysize(HAL_RXDMA_DIR_BUF); + + ring->buf_sz = db_cap->min_buf_sz; + ring->buf_align = db_cap->min_buf_align; + ring->pdev_id = db_cap->pdev_id; + ring->hp_addr = ath11k_hal_srng_get_hp_addr(ar->ab, srng); + ring->tp_addr = ath11k_hal_srng_get_tp_addr(ar->ab, srng); + + ret = ath11k_dbring_fill_bufs(ar, ring, GFP_KERNEL); + + return ret; +} + +int ath11k_dbring_srng_setup(struct ath11k *ar, struct ath11k_dbring *ring, + int ring_num, int num_entries) +{ + int ret; + + ret = ath11k_dp_srng_setup(ar->ab, &ring->refill_srng, HAL_RXDMA_DIR_BUF, + ring_num, ar->pdev_idx, num_entries); + if (ret < 0) { + ath11k_warn(ar->ab, "failed to setup srng: %d ring_id %d\n", + ret, ring_num); + goto err; + } + + return 0; +err: + ath11k_dp_srng_cleanup(ar->ab, &ring->refill_srng); + return ret; +} + +int ath11k_dbring_get_cap(struct ath11k_base *ab, + u8 pdev_idx, + enum wmi_direct_buffer_module id, + struct ath11k_dbring_cap *db_cap) +{ + int i; + + if (!ab->num_db_cap || !ab->db_caps) + return -ENOENT; + + if (id >= WMI_DIRECT_BUF_MAX) + return -EINVAL; + + for (i = 0; i < ab->num_db_cap; i++) { + if (pdev_idx == ab->db_caps[i].pdev_id && + id == ab->db_caps[i].id) { + *db_cap = ab->db_caps[i]; + + return 0; + } + } + + return -ENOENT; +} + +int ath11k_dbring_buffer_release_event(struct ath11k_base *ab, + struct ath11k_dbring_buf_release_event *ev) +{ + struct ath11k_dbring *ring; + struct hal_srng *srng; + struct ath11k *ar; + struct ath11k_dbring_element *buff; + struct ath11k_dbring_data handler_data; + struct ath11k_buffer_addr desc; + u8 *vaddr_unalign; + u32 num_entry, num_buff_reaped; + u8 pdev_idx, rbm; + u32 cookie; + int buf_id; + int size; + dma_addr_t paddr; + int ret = 0; + + pdev_idx = ev->fixed.pdev_id; + + if (pdev_idx >= ab->num_radios) { + ath11k_warn(ab, "Invalid pdev id %d\n", pdev_idx); + return -EINVAL; + } + + if (ev->fixed.num_buf_release_entry != + ev->fixed.num_meta_data_entry) { + ath11k_warn(ab, "Buffer entry %d mismatch meta entry %d\n", + ev->fixed.num_buf_release_entry, + ev->fixed.num_meta_data_entry); + return -EINVAL; + } + + ar = ab->pdevs[pdev_idx].ar; + + rcu_read_lock(); + if (!rcu_dereference(ab->pdevs_active[pdev_idx])) { + ret = -EINVAL; + goto rcu_unlock; + } + + switch (ev->fixed.module_id) { + case WMI_DIRECT_BUF_SPECTRAL: + ring = ath11k_spectral_get_dbring(ar); + break; + default: + ring = NULL; + ath11k_warn(ab, "Recv dma buffer release ev on unsupp module %d\n", + ev->fixed.module_id); + break; + } + + if (!ring) { + ret = -EINVAL; + goto rcu_unlock; + } + + srng = &ab->hal.srng_list[ring->refill_srng.ring_id]; + num_entry = ev->fixed.num_buf_release_entry; + size = sizeof(*buff) + ring->buf_sz + ring->buf_align - 1; + num_buff_reaped = 0; + + spin_lock_bh(&srng->lock); + + while (num_buff_reaped < num_entry) { + desc.info0 = ev->buf_entry[num_buff_reaped].paddr_lo; + desc.info1 = ev->buf_entry[num_buff_reaped].paddr_hi; + handler_data.meta = ev->meta_data[num_buff_reaped]; + + num_buff_reaped++; + + ath11k_hal_rx_buf_addr_info_get(&desc, &paddr, &cookie, &rbm); + + buf_id = FIELD_GET(DP_RXDMA_BUF_COOKIE_BUF_ID, cookie); + + spin_lock_bh(&ring->idr_lock); + buff = idr_find(&ring->bufs_idr, buf_id); + if (!buff) { + spin_unlock_bh(&ring->idr_lock); + continue; + } + idr_remove(&ring->bufs_idr, buf_id); + spin_unlock_bh(&ring->idr_lock); + + dma_unmap_single(ab->dev, buff->paddr, ring->buf_sz, + DMA_FROM_DEVICE); + + if (ring->handler) { + vaddr_unalign = buff->payload; + handler_data.data = PTR_ALIGN(vaddr_unalign, + ring->buf_align); + handler_data.data_sz = ring->buf_sz; + + ring->handler(ar, &handler_data); + } + + memset(buff, 0, size); + ath11k_dbring_bufs_replenish(ar, ring, buff, GFP_ATOMIC); + } + + spin_unlock_bh(&srng->lock); + +rcu_unlock: + rcu_read_unlock(); + + return ret; +} + +void ath11k_dbring_srng_cleanup(struct ath11k *ar, struct ath11k_dbring *ring) +{ + ath11k_dp_srng_cleanup(ar->ab, &ring->refill_srng); +} + +void ath11k_dbring_buf_cleanup(struct ath11k *ar, struct ath11k_dbring *ring) +{ + struct ath11k_dbring_element *buff; + int buf_id; + + spin_lock_bh(&ring->idr_lock); + idr_for_each_entry(&ring->bufs_idr, buff, buf_id) { + idr_remove(&ring->bufs_idr, buf_id); + dma_unmap_single(ar->ab->dev, buff->paddr, + ring->buf_sz, DMA_FROM_DEVICE); + kfree(buff); + } + + idr_destroy(&ring->bufs_idr); + spin_unlock_bh(&ring->idr_lock); +} diff --git a/drivers/net/wireless/ath/ath11k/dbring.h b/drivers/net/wireless/ath/ath11k/dbring.h new file mode 100644 index 000000000000..f7fce9ef9c36 --- /dev/null +++ b/drivers/net/wireless/ath/ath11k/dbring.h @@ -0,0 +1,79 @@ +/* SPDX-License-Identifier: BSD-3-Clause-Clear */ +/* + * Copyright (c) 2019-2020 The Linux Foundation. All rights reserved. + */ + +#ifndef ATH11K_DBRING_H +#define ATH11K_DBRING_H + +#include <linux/types.h> +#include <linux/idr.h> +#include <linux/spinlock.h> +#include "dp.h" + +struct ath11k_dbring_element { + dma_addr_t paddr; + u8 payload[0]; +}; + +struct ath11k_dbring_data { + void *data; + u32 data_sz; + struct wmi_dma_buf_release_meta_data meta; +}; + +struct ath11k_dbring_buf_release_event { + struct ath11k_wmi_dma_buf_release_fixed_param fixed; + struct wmi_dma_buf_release_entry *buf_entry; + struct wmi_dma_buf_release_meta_data *meta_data; + u32 num_buf_entry; + u32 num_meta; +}; + +struct ath11k_dbring_cap { + u32 pdev_id; + enum wmi_direct_buffer_module id; + u32 min_elem; + u32 min_buf_sz; + u32 min_buf_align; +}; + +struct ath11k_dbring { + struct dp_srng refill_srng; + struct idr bufs_idr; + /* Protects bufs_idr */ + spinlock_t idr_lock; + dma_addr_t tp_addr; + dma_addr_t hp_addr; + int bufs_max; + u32 pdev_id; + u32 buf_sz; + u32 buf_align; + u32 num_resp_per_event; + u32 event_timeout_ms; + int (*handler)(struct ath11k *, struct ath11k_dbring_data *); +}; + +int ath11k_dbring_set_cfg(struct ath11k *ar, + struct ath11k_dbring *ring, + u32 num_resp_per_event, + u32 event_timeout_ms, + int (*handler)(struct ath11k *, + struct ath11k_dbring_data *)); +int ath11k_dbring_wmi_cfg_setup(struct ath11k *ar, + struct ath11k_dbring *ring, + enum wmi_direct_buffer_module id); +int ath11k_dbring_buf_setup(struct ath11k *ar, + struct ath11k_dbring *ring, + struct ath11k_dbring_cap *db_cap); +int ath11k_dbring_srng_setup(struct ath11k *ar, struct ath11k_dbring *ring, + int ring_num, int num_entries); +int ath11k_dbring_buffer_release_event(struct ath11k_base *ab, + struct ath11k_dbring_buf_release_event *ev); +int ath11k_dbring_get_cap(struct ath11k_base *ab, + u8 pdev_idx, + enum wmi_direct_buffer_module id, + struct ath11k_dbring_cap *db_cap); +void ath11k_dbring_srng_cleanup(struct ath11k *ar, struct ath11k_dbring *ring); +void ath11k_dbring_buf_cleanup(struct ath11k *ar, struct ath11k_dbring *ring); +#endif /* ATH11K_DBRING_H */ diff --git a/drivers/net/wireless/ath/ath11k/debug.c b/drivers/net/wireless/ath/ath11k/debug.c index 3fd6b5af073b..62a1aa0565a9 100644 --- a/drivers/net/wireless/ath/ath11k/debug.c +++ b/drivers/net/wireless/ath/ath11k/debug.c @@ -12,6 +12,43 @@ #include "debug_htt_stats.h" #include "peer.h" +static const char *htt_bp_umac_ring[HTT_SW_UMAC_RING_IDX_MAX] = { + "REO2SW1_RING", + "REO2SW2_RING", + "REO2SW3_RING", + "REO2SW4_RING", + "WBM2REO_LINK_RING", + "REO2TCL_RING", + "REO2FW_RING", + "RELEASE_RING", + "PPE_RELEASE_RING", + "TCL2TQM_RING", + "TQM_RELEASE_RING", + "REO_RELEASE_RING", + "WBM2SW0_RELEASE_RING", + "WBM2SW1_RELEASE_RING", + "WBM2SW2_RELEASE_RING", + "WBM2SW3_RELEASE_RING", + "REO_CMD_RING", + "REO_STATUS_RING", +}; + +static const char *htt_bp_lmac_ring[HTT_SW_LMAC_RING_IDX_MAX] = { + "FW2RXDMA_BUF_RING", + "FW2RXDMA_STATUS_RING", + "FW2RXDMA_LINK_RING", + "SW2RXDMA_BUF_RING", + "WBM2RXDMA_LINK_RING", + "RXDMA2FW_RING", + "RXDMA2SW_RING", + "RXDMA2RELEASE_RING", + "RXDMA2REO_RING", + "MONITOR_STATUS_RING", + "MONITOR_BUF_RING", + "MONITOR_DESC_RING", + "MONITOR_DEST_RING", +}; + void ath11k_info(struct ath11k_base *ab, const char *fmt, ...) { struct va_format vaf = { @@ -739,12 +776,78 @@ static const struct file_operations fops_extd_rx_stats = { .open = simple_open, }; -static ssize_t ath11k_debug_dump_soc_rx_stats(struct file *file, +static int ath11k_fill_bp_stats(struct ath11k_base *ab, + struct ath11k_bp_stats *bp_stats, + char *buf, int len, int size) +{ + lockdep_assert_held(&ab->base_lock); + + len += scnprintf(buf + len, size - len, "count: %u\n", + bp_stats->count); + len += scnprintf(buf + len, size - len, "hp: %u\n", + bp_stats->hp); + len += scnprintf(buf + len, size - len, "tp: %u\n", + bp_stats->tp); + len += scnprintf(buf + len, size - len, "seen before: %ums\n\n", + jiffies_to_msecs(jiffies - bp_stats->jiffies)); + return len; +} + +static ssize_t ath11k_debug_dump_soc_ring_bp_stats(struct ath11k_base *ab, + char *buf, int size) +{ + struct ath11k_bp_stats *bp_stats; + bool stats_rxd = false; + u8 i, pdev_idx; + int len = 0; + + len += scnprintf(buf + len, size - len, "\nBackpressure Stats\n"); + len += scnprintf(buf + len, size - len, "==================\n"); + + spin_lock_bh(&ab->base_lock); + for (i = 0; i < HTT_SW_UMAC_RING_IDX_MAX; i++) { + bp_stats = &ab->soc_stats.bp_stats.umac_ring_bp_stats[i]; + + if (!bp_stats->count) + continue; + + len += scnprintf(buf + len, size - len, "Ring: %s\n", + htt_bp_umac_ring[i]); + len = ath11k_fill_bp_stats(ab, bp_stats, buf, len, size); + stats_rxd = true; + } + + for (i = 0; i < HTT_SW_LMAC_RING_IDX_MAX; i++) { + for (pdev_idx = 0; pdev_idx < MAX_RADIOS; pdev_idx++) { + bp_stats = + &ab->soc_stats.bp_stats.lmac_ring_bp_stats[i][pdev_idx]; + + if (!bp_stats->count) + continue; + + len += scnprintf(buf + len, size - len, "Ring: %s\n", + htt_bp_lmac_ring[i]); + len += scnprintf(buf + len, size - len, "pdev: %d\n", + pdev_idx); + len = ath11k_fill_bp_stats(ab, bp_stats, buf, len, size); + stats_rxd = true; + } + } + spin_unlock_bh(&ab->base_lock); + + if (!stats_rxd) + len += scnprintf(buf + len, size - len, + "No Ring Backpressure stats received\n\n"); + + return len; +} + +static ssize_t ath11k_debug_dump_soc_dp_stats(struct file *file, char __user *user_buf, size_t count, loff_t *ppos) { struct ath11k_base *ab = file->private_data; - struct ath11k_soc_dp_rx_stats *soc_stats = &ab->soc_stats; + struct ath11k_soc_dp_stats *soc_stats = &ab->soc_stats; int len = 0, i, retval; const int size = 4096; static const char *rxdma_err[HAL_REO_ENTR_RING_RXDMA_ECODE_MAX] = { @@ -788,6 +891,19 @@ static ssize_t ath11k_debug_dump_soc_rx_stats(struct file *file, soc_stats->hal_reo_error[2], soc_stats->hal_reo_error[3]); + len += scnprintf(buf + len, size - len, "\nSOC TX STATS:\n"); + len += scnprintf(buf + len, size - len, "\nTCL Ring Full Failures:\n"); + + for (i = 0; i < DP_TCL_NUM_RING_MAX; i++) + len += scnprintf(buf + len, size - len, "ring%d: %u\n", + i, soc_stats->tx_err.desc_na[i]); + + len += scnprintf(buf + len, size - len, + "\nMisc Transmit Failures: %d\n", + atomic_read(&soc_stats->tx_err.misc_fail)); + + len += ath11k_debug_dump_soc_ring_bp_stats(ab, buf + len, size - len); + if (len > size) len = size; retval = simple_read_from_buffer(user_buf, count, ppos, buf, len); @@ -796,8 +912,8 @@ static ssize_t ath11k_debug_dump_soc_rx_stats(struct file *file, return retval; } -static const struct file_operations fops_soc_rx_stats = { - .read = ath11k_debug_dump_soc_rx_stats, +static const struct file_operations fops_soc_dp_stats = { + .read = ath11k_debug_dump_soc_dp_stats, .open = simple_open, .owner = THIS_MODULE, .llseek = default_llseek, @@ -819,8 +935,8 @@ int ath11k_debug_pdev_create(struct ath11k_base *ab) debugfs_create_file("simulate_fw_crash", 0600, ab->debugfs_soc, ab, &fops_simulate_fw_crash); - debugfs_create_file("soc_rx_stats", 0600, ab->debugfs_soc, ab, - &fops_soc_rx_stats); + debugfs_create_file("soc_dp_stats", 0600, ab->debugfs_soc, ab, + &fops_soc_dp_stats); return 0; } diff --git a/drivers/net/wireless/ath/ath11k/dp.c b/drivers/net/wireless/ath/ath11k/dp.c index 9ae743e528af..1d64c3c51ac9 100644 --- a/drivers/net/wireless/ath/ath11k/dp.c +++ b/drivers/net/wireless/ath/ath11k/dp.c @@ -172,11 +172,12 @@ int ath11k_dp_srng_setup(struct ath11k_base *ab, struct dp_srng *ring, case HAL_RXDMA_DST: case HAL_RXDMA_MONITOR_DST: case HAL_RXDMA_MONITOR_DESC: - case HAL_RXDMA_DIR_BUF: params.intr_batch_cntr_thres_entries = HAL_SRNG_INT_BATCH_THRESHOLD_OTHER; params.intr_timer_thres_us = HAL_SRNG_INT_TIMER_THRESHOLD_OTHER; break; + case HAL_RXDMA_DIR_BUF: + break; default: ath11k_warn(ab, "Not a valid ring type in dp :%d\n", type); return -EINVAL; diff --git a/drivers/net/wireless/ath/ath11k/dp.h b/drivers/net/wireless/ath/ath11k/dp.h index 058a5c1d86ff..7587862d2e32 100644 --- a/drivers/net/wireless/ath/ath11k/dp.h +++ b/drivers/net/wireless/ath/ath11k/dp.h @@ -999,6 +999,48 @@ struct htt_resp_msg { #define HTT_BACKPRESSURE_EVENT_HP_M GENMASK(15, 0) #define HTT_BACKPRESSURE_EVENT_TP_M GENMASK(31, 16) +#define HTT_BACKPRESSURE_UMAC_RING_TYPE 0 +#define HTT_BACKPRESSURE_LMAC_RING_TYPE 1 + +enum htt_backpressure_umac_ringid { + HTT_SW_RING_IDX_REO_REO2SW1_RING, + HTT_SW_RING_IDX_REO_REO2SW2_RING, + HTT_SW_RING_IDX_REO_REO2SW3_RING, + HTT_SW_RING_IDX_REO_REO2SW4_RING, + HTT_SW_RING_IDX_REO_WBM2REO_LINK_RING, + HTT_SW_RING_IDX_REO_REO2TCL_RING, + HTT_SW_RING_IDX_REO_REO2FW_RING, + HTT_SW_RING_IDX_REO_REO_RELEASE_RING, + HTT_SW_RING_IDX_WBM_PPE_RELEASE_RING, + HTT_SW_RING_IDX_TCL_TCL2TQM_RING, + HTT_SW_RING_IDX_WBM_TQM_RELEASE_RING, + HTT_SW_RING_IDX_WBM_REO_RELEASE_RING, + HTT_SW_RING_IDX_WBM_WBM2SW0_RELEASE_RING, + HTT_SW_RING_IDX_WBM_WBM2SW1_RELEASE_RING, + HTT_SW_RING_IDX_WBM_WBM2SW2_RELEASE_RING, + HTT_SW_RING_IDX_WBM_WBM2SW3_RELEASE_RING, + HTT_SW_RING_IDX_REO_REO_CMD_RING, + HTT_SW_RING_IDX_REO_REO_STATUS_RING, + HTT_SW_UMAC_RING_IDX_MAX, +}; + +enum htt_backpressure_lmac_ringid { + HTT_SW_RING_IDX_FW2RXDMA_BUF_RING, + HTT_SW_RING_IDX_FW2RXDMA_STATUS_RING, + HTT_SW_RING_IDX_FW2RXDMA_LINK_RING, + HTT_SW_RING_IDX_SW2RXDMA_BUF_RING, + HTT_SW_RING_IDX_WBM2RXDMA_LINK_RING, + HTT_SW_RING_IDX_RXDMA2FW_RING, + HTT_SW_RING_IDX_RXDMA2SW_RING, + HTT_SW_RING_IDX_RXDMA2RELEASE_RING, + HTT_SW_RING_IDX_RXDMA2REO_RING, + HTT_SW_RING_IDX_MONITOR_STATUS_RING, + HTT_SW_RING_IDX_MONITOR_BUF_RING, + HTT_SW_RING_IDX_MONITOR_DESC_RING, + HTT_SW_RING_IDX_MONITOR_DEST_RING, + HTT_SW_LMAC_RING_IDX_MAX, +}; + /* ppdu stats * * @details diff --git a/drivers/net/wireless/ath/ath11k/dp_rx.c b/drivers/net/wireless/ath/ath11k/dp_rx.c index a54610d75c40..791d971784ce 100644 --- a/drivers/net/wireless/ath/ath11k/dp_rx.c +++ b/drivers/net/wireless/ath/ath11k/dp_rx.c @@ -653,10 +653,8 @@ static void ath11k_dp_rx_tid_del_func(struct ath11k_dp *dp, void *ctx, spin_lock_bh(&dp->reo_cmd_lock); list_add_tail(&elem->list, &dp->reo_cmd_cache_flush_list); dp->reo_cmd_cache_flush_count++; - spin_unlock_bh(&dp->reo_cmd_lock); /* Flush and invalidate aged REO desc from HW cache */ - spin_lock_bh(&dp->reo_cmd_lock); list_for_each_entry_safe(elem, tmp, &dp->reo_cmd_cache_flush_list, list) { if (dp->reo_cmd_cache_flush_count > DP_REO_DESC_FREE_THRESHOLD || @@ -1503,9 +1501,10 @@ static void ath11k_htt_backpressure_event_handler(struct ath11k_base *ab, struct sk_buff *skb) { u32 *data = (u32 *)skb->data; - u8 pdev_id, ring_type, ring_id; + u8 pdev_id, ring_type, ring_id, pdev_idx; u16 hp, tp; u32 backpressure_time; + struct ath11k_bp_stats *bp_stats; pdev_id = FIELD_GET(HTT_BACKPRESSURE_EVENT_PDEV_ID_M, *data); ring_type = FIELD_GET(HTT_BACKPRESSURE_EVENT_RING_TYPE_M, *data); @@ -1520,6 +1519,31 @@ static void ath11k_htt_backpressure_event_handler(struct ath11k_base *ab, ath11k_dbg(ab, ATH11K_DBG_DP_HTT, "htt backpressure event, pdev %d, ring type %d,ring id %d, hp %d tp %d, backpressure time %d\n", pdev_id, ring_type, ring_id, hp, tp, backpressure_time); + + if (ring_type == HTT_BACKPRESSURE_UMAC_RING_TYPE) { + if (ring_id >= HTT_SW_UMAC_RING_IDX_MAX) + return; + + bp_stats = &ab->soc_stats.bp_stats.umac_ring_bp_stats[ring_id]; + } else if (ring_type == HTT_BACKPRESSURE_LMAC_RING_TYPE) { + pdev_idx = DP_HW2SW_MACID(pdev_id); + + if (ring_id >= HTT_SW_LMAC_RING_IDX_MAX || pdev_idx >= MAX_RADIOS) + return; + + bp_stats = &ab->soc_stats.bp_stats.lmac_ring_bp_stats[ring_id][pdev_idx]; + } else { + ath11k_warn(ab, "unknown ring type received in htt bp event %d\n", + ring_type); + return; + } + + spin_lock_bh(&ab->base_lock); + bp_stats->hp = hp; + bp_stats->tp = tp; + bp_stats->count++; + bp_stats->jiffies = jiffies; + spin_unlock_bh(&ab->base_lock); } void ath11k_dp_htt_htc_t2h_msg_handler(struct ath11k_base *ab, @@ -2162,6 +2186,7 @@ static void ath11k_dp_rx_h_ppdu(struct ath11k *ar, struct hal_rx_desc *rx_desc, struct ieee80211_rx_status *rx_status) { u8 channel_num; + u32 center_freq; rx_status->freq = 0; rx_status->rate_idx = 0; @@ -2172,8 +2197,11 @@ static void ath11k_dp_rx_h_ppdu(struct ath11k *ar, struct hal_rx_desc *rx_desc, rx_status->flag |= RX_FLAG_NO_SIGNAL_VAL; channel_num = ath11k_dp_rx_h_msdu_start_freq(rx_desc); + center_freq = ath11k_dp_rx_h_msdu_start_freq(rx_desc) >> 16; - if (channel_num >= 1 && channel_num <= 14) { + if (center_freq >= 5935 && center_freq <= 7105) { + rx_status->band = NL80211_BAND_6GHZ; + } else if (channel_num >= 1 && channel_num <= 14) { rx_status->band = NL80211_BAND_2GHZ; } else if (channel_num >= 36 && channel_num <= 173) { rx_status->band = NL80211_BAND_5GHZ; diff --git a/drivers/net/wireless/ath/ath11k/dp_tx.c b/drivers/net/wireless/ath/ath11k/dp_tx.c index 41c990aec6b7..1af76775b1a8 100644 --- a/drivers/net/wireless/ath/ath11k/dp_tx.c +++ b/drivers/net/wireless/ath/ath11k/dp_tx.c @@ -121,8 +121,10 @@ tcl_ring_sel: spin_unlock_bh(&tx_ring->tx_idr_lock); if (ret < 0) { - if (ring_map == (BIT(DP_TCL_NUM_RING_MAX) - 1)) + if (ring_map == (BIT(DP_TCL_NUM_RING_MAX) - 1)) { + atomic_inc(&ab->soc_stats.tx_err.misc_fail); return -ENOSPC; + } /* Check if the next ring is available */ ring_selector++; @@ -180,11 +182,13 @@ tcl_ring_sel: default: /* TODO: Take care of other encap modes as well */ ret = -EINVAL; + atomic_inc(&ab->soc_stats.tx_err.misc_fail); goto fail_remove_idr; } ti.paddr = dma_map_single(ab->dev, skb->data, skb->len, DMA_TO_DEVICE); if (dma_mapping_error(ab->dev, ti.paddr)) { + atomic_inc(&ab->soc_stats.tx_err.misc_fail); ath11k_warn(ab, "failed to DMA map data Tx buffer\n"); ret = -ENOMEM; goto fail_remove_idr; @@ -208,6 +212,7 @@ tcl_ring_sel: * desc because the desc is directly enqueued onto hw queue. */ ath11k_hal_srng_access_end(ab, tcl_ring); + ab->soc_stats.tx_err.desc_na[ti.ring_id]++; spin_unlock_bh(&tcl_ring->lock); ret = -ENOMEM; diff --git a/drivers/net/wireless/ath/ath11k/mac.c b/drivers/net/wireless/ath/ath11k/mac.c index 2836a0f197ab..07d3e031c75a 100644 --- a/drivers/net/wireless/ath/ath11k/mac.c +++ b/drivers/net/wireless/ath/ath11k/mac.c @@ -33,6 +33,15 @@ .max_power = 30, \ } +#define CHAN6G(_channel, _freq, _flags) { \ + .band = NL80211_BAND_6GHZ, \ + .hw_value = (_channel), \ + .center_freq = (_freq), \ + .flags = (_flags), \ + .max_antenna_gain = 0, \ + .max_power = 30, \ +} + /* frame mode values are mapped as per enum ath11k_hw_txrx_mode */ static unsigned int ath11k_frame_mode = ATH11K_HW_TXRX_NATIVE_WIFI; module_param_named(frame_mode, ath11k_frame_mode, uint, 0644); @@ -86,6 +95,68 @@ static const struct ieee80211_channel ath11k_5ghz_channels[] = { CHAN5G(173, 5865, 0), }; +static const struct ieee80211_channel ath11k_6ghz_channels[] = { + CHAN6G(1, 5955, 0), + CHAN6G(5, 5975, 0), + CHAN6G(9, 5995, 0), + CHAN6G(13, 6015, 0), + CHAN6G(17, 6035, 0), + CHAN6G(21, 6055, 0), + CHAN6G(25, 6075, 0), + CHAN6G(29, 6095, 0), + CHAN6G(33, 6115, 0), + CHAN6G(37, 6135, 0), + CHAN6G(41, 6155, 0), + CHAN6G(45, 6175, 0), + CHAN6G(49, 6195, 0), + CHAN6G(53, 6215, 0), + CHAN6G(57, 6235, 0), + CHAN6G(61, 6255, 0), + CHAN6G(65, 6275, 0), + CHAN6G(69, 6295, 0), + CHAN6G(73, 6315, 0), + CHAN6G(77, 6335, 0), + CHAN6G(81, 6355, 0), + CHAN6G(85, 6375, 0), + CHAN6G(89, 6395, 0), + CHAN6G(93, 6415, 0), + CHAN6G(97, 6435, 0), + CHAN6G(101, 6455, 0), + CHAN6G(105, 6475, 0), + CHAN6G(109, 6495, 0), + CHAN6G(113, 6515, 0), + CHAN6G(117, 6535, 0), + CHAN6G(121, 6555, 0), + CHAN6G(125, 6575, 0), + CHAN6G(129, 6595, 0), + CHAN6G(133, 6615, 0), + CHAN6G(137, 6635, 0), + CHAN6G(141, 6655, 0), + CHAN6G(145, 6675, 0), + CHAN6G(149, 6695, 0), + CHAN6G(153, 6715, 0), + CHAN6G(157, 6735, 0), + CHAN6G(161, 6755, 0), + CHAN6G(165, 6775, 0), + CHAN6G(169, 6795, 0), + CHAN6G(173, 6815, 0), + CHAN6G(177, 6835, 0), + CHAN6G(181, 6855, 0), + CHAN6G(185, 6875, 0), + CHAN6G(189, 6895, 0), + CHAN6G(193, 6915, 0), + CHAN6G(197, 6935, 0), + CHAN6G(201, 6955, 0), + CHAN6G(205, 6975, 0), + CHAN6G(209, 6995, 0), + CHAN6G(213, 7015, 0), + CHAN6G(217, 7035, 0), + CHAN6G(221, 7055, 0), + CHAN6G(225, 7075, 0), + CHAN6G(229, 7095, 0), + CHAN6G(233, 7115, 0), +}; + static struct ieee80211_rate ath11k_legacy_rates[] = { { .bitrate = 10, .hw_value = ATH11K_HW_RATE_CCK_LP_1M }, @@ -134,6 +205,17 @@ ath11k_phymodes[NUM_NL80211_BANDS][ATH11K_CHAN_WIDTH_NUM] = { [NL80211_CHAN_WIDTH_160] = MODE_11AX_HE160, [NL80211_CHAN_WIDTH_80P80] = MODE_11AX_HE80_80, }, + [NL80211_BAND_6GHZ] = { + [NL80211_CHAN_WIDTH_5] = MODE_UNKNOWN, + [NL80211_CHAN_WIDTH_10] = MODE_UNKNOWN, + [NL80211_CHAN_WIDTH_20_NOHT] = MODE_11AX_HE20, + [NL80211_CHAN_WIDTH_20] = MODE_11AX_HE20, + [NL80211_CHAN_WIDTH_40] = MODE_11AX_HE40, + [NL80211_CHAN_WIDTH_80] = MODE_11AX_HE80, + [NL80211_CHAN_WIDTH_160] = MODE_11AX_HE160, + [NL80211_CHAN_WIDTH_80P80] = MODE_11AX_HE80_80, + }, + }; const struct htt_rx_ring_tlv_filter ath11k_mac_mon_status_filter_default = { @@ -698,6 +780,8 @@ static int ath11k_mac_setup_bcn_tmpl(struct ath11k_vif *arvif) struct ieee80211_vif *vif = arvif->vif; struct ieee80211_mutable_offsets offs = {}; struct sk_buff *bcn; + struct ieee80211_mgmt *mgmt; + u8 *ies; int ret; if (arvif->vdev_type != WMI_VDEV_TYPE_AP) @@ -709,6 +793,17 @@ static int ath11k_mac_setup_bcn_tmpl(struct ath11k_vif *arvif) return -EPERM; } + ies = bcn->data + ieee80211_get_hdrlen_from_skb(bcn); + ies += sizeof(mgmt->u.beacon); + + if (cfg80211_find_ie(WLAN_EID_RSN, ies, (skb_tail_pointer(bcn) - ies))) + arvif->rsnie_present = true; + + if (cfg80211_find_vendor_ie(WLAN_OUI_MICROSOFT, + WLAN_OUI_TYPE_MICROSOFT_WPA, + ies, (skb_tail_pointer(bcn) - ies))) + arvif->wpaie_present = true; + ret = ath11k_wmi_bcn_tmpl(ar, arvif->vdev_id, &offs, bcn); kfree_skb(bcn); @@ -798,6 +893,7 @@ static void ath11k_peer_assoc_h_crypto(struct ath11k *ar, struct ieee80211_bss_conf *info = &vif->bss_conf; struct cfg80211_chan_def def; struct cfg80211_bss *bss; + struct ath11k_vif *arvif = (struct ath11k_vif *)vif->drv_priv; const u8 *rsnie = NULL; const u8 *wpaie = NULL; @@ -808,7 +904,12 @@ static void ath11k_peer_assoc_h_crypto(struct ath11k *ar, bss = cfg80211_get_bss(ar->hw->wiphy, def.chan, info->bssid, NULL, 0, IEEE80211_BSS_TYPE_ANY, IEEE80211_PRIVACY_ANY); - if (bss) { + + if (arvif->rsnie_present || arvif->wpaie_present) { + arg->need_ptk_4_way = true; + if (arvif->wpaie_present) + arg->need_gtk_2_way = true; + } else if (bss) { const struct cfg80211_bss_ies *ies; rcu_read_lock(); @@ -1489,6 +1590,7 @@ static void ath11k_peer_assoc_h_phymode(struct ath11k *ar, } break; case NL80211_BAND_5GHZ: + case NL80211_BAND_6GHZ: /* Check HE first */ if (sta->he_cap.has_he) { phymode = ath11k_mac_get_phymode_he(ar, sta); @@ -2125,6 +2227,9 @@ static int ath11k_start_scan(struct ath11k *ar, lockdep_assert_held(&ar->conf_mutex); + if (ath11k_spectral_get_mode(ar) == ATH11K_SPECTRAL_BACKGROUND) + ath11k_spectral_reset_buffer(ar); + ret = ath11k_wmi_send_scan_start_cmd(ar, arg); if (ret) return ret; @@ -3411,7 +3516,7 @@ static void ath11k_mac_setup_ht_vht_cap(struct ath11k *ar, rate_cap_rx_chainmask); } - if (cap->supported_bands & WMI_HOST_WLAN_5G_CAP) { + if (cap->supported_bands & WMI_HOST_WLAN_5G_CAP && !ar->supports_6ghz) { band = &ar->mac.sbands[NL80211_BAND_5GHZ]; ht_cap = cap->band[NL80211_BAND_5GHZ].ht_cap_info; if (ht_cap_info) @@ -3532,6 +3637,35 @@ ath11k_mac_filter_he_cap_mesh(struct ieee80211_he_cap_elem *he_cap_elem) he_cap_elem->phy_cap_info[9] &= ~m; } +static __le16 ath11k_mac_setup_he_6ghz_cap(struct ath11k_pdev_cap *pcap, + struct ath11k_band_cap *bcap) +{ + u8 val; + + bcap->he_6ghz_capa = IEEE80211_HT_MPDU_DENSITY_NONE; + if (bcap->ht_cap_info & WMI_HT_CAP_DYNAMIC_SMPS) + bcap->he_6ghz_capa |= + FIELD_PREP(IEEE80211_HE_6GHZ_CAP_SM_PS, + WLAN_HT_CAP_SM_PS_DYNAMIC); + else + bcap->he_6ghz_capa |= + FIELD_PREP(IEEE80211_HE_6GHZ_CAP_SM_PS, + WLAN_HT_CAP_SM_PS_DISABLED); + val = FIELD_GET(IEEE80211_VHT_CAP_MAX_A_MPDU_LENGTH_EXPONENT_MASK, + pcap->vht_cap); + bcap->he_6ghz_capa |= + FIELD_PREP(IEEE80211_HE_6GHZ_CAP_MAX_AMPDU_LEN_EXP, val); + val = FIELD_GET(IEEE80211_VHT_CAP_MAX_MPDU_MASK, pcap->vht_cap); + bcap->he_6ghz_capa |= + FIELD_PREP(IEEE80211_HE_6GHZ_CAP_MAX_MPDU_LEN, val); + if (pcap->vht_cap & IEEE80211_VHT_CAP_RX_ANTENNA_PATTERN) + bcap->he_6ghz_capa |= IEEE80211_HE_6GHZ_CAP_RX_ANTPAT_CONS; + if (pcap->vht_cap & IEEE80211_VHT_CAP_TX_ANTENNA_PATTERN) + bcap->he_6ghz_capa |= IEEE80211_HE_6GHZ_CAP_TX_ANTPAT_CONS; + + return cpu_to_le16(bcap->he_6ghz_capa); +} + static int ath11k_mac_copy_he_cap(struct ath11k *ar, struct ath11k_pdev_cap *cap, struct ieee80211_sband_iftype_data *data, @@ -3614,6 +3748,11 @@ static int ath11k_mac_copy_he_cap(struct ath11k *ar, IEEE80211_HE_PHY_CAP6_PPE_THRESHOLD_PRESENT) ath11k_gen_ppe_thresh(&band_cap->he_ppet, he_cap->ppe_thres); + + if (band == NL80211_BAND_6GHZ) { + data[idx].he_6ghz_capa.capa = + ath11k_mac_setup_he_6ghz_cap(cap, band_cap); + } idx++; } @@ -3643,6 +3782,16 @@ static void ath11k_mac_setup_he_cap(struct ath11k *ar, band->iftype_data = ar->mac.iftype[NL80211_BAND_5GHZ]; band->n_iftype_data = count; } + + if (cap->supported_bands & WMI_HOST_WLAN_5G_CAP && + ar->supports_6ghz) { + count = ath11k_mac_copy_he_cap(ar, cap, + ar->mac.iftype[NL80211_BAND_6GHZ], + NL80211_BAND_6GHZ); + band = &ar->mac.sbands[NL80211_BAND_6GHZ]; + band->iftype_data = ar->mac.iftype[NL80211_BAND_6GHZ]; + band->n_iftype_data = count; + } } static int __ath11k_set_antenna(struct ath11k *ar, u32 tx_ant, u32 rx_ant) @@ -4085,6 +4234,11 @@ ath11k_mac_setup_vdev_create_params(struct ath11k_vif *arvif, params->chains[NL80211_BAND_5GHZ].tx = ar->num_tx_chains; params->chains[NL80211_BAND_5GHZ].rx = ar->num_rx_chains; } + if (pdev->cap.supported_bands & WMI_HOST_WLAN_5G_CAP && + ar->supports_6ghz) { + params->chains[NL80211_BAND_6GHZ].tx = ar->num_tx_chains; + params->chains[NL80211_BAND_6GHZ].rx = ar->num_rx_chains; + } } static u32 @@ -5217,7 +5371,7 @@ ath11k_mac_get_single_legacy_rate(struct ath11k *ar, rate_idx = ffs(mask->control[band].legacy) - 1; - if (band == NL80211_BAND_5GHZ) + if (band == NL80211_BAND_5GHZ || band == NL80211_BAND_6GHZ) rate_idx += ATH11K_MAC_FIRST_OFDM_RATE_IDX; hw_rate = ath11k_legacy_rates[rate_idx].hw_value; @@ -5683,7 +5837,8 @@ static int ath11k_mac_setup_channels_rates(struct ath11k *ar, void *channels; BUILD_BUG_ON((ARRAY_SIZE(ath11k_2ghz_channels) + - ARRAY_SIZE(ath11k_5ghz_channels)) != + ARRAY_SIZE(ath11k_5ghz_channels) + + ARRAY_SIZE(ath11k_6ghz_channels)) != ATH11K_NUM_CHANS); reg_cap = &ar->ab->hal_reg_cap[ar->pdev_idx]; @@ -5696,6 +5851,7 @@ static int ath11k_mac_setup_channels_rates(struct ath11k *ar, return -ENOMEM; band = &ar->mac.sbands[NL80211_BAND_2GHZ]; + band->band = NL80211_BAND_2GHZ; band->n_channels = ARRAY_SIZE(ath11k_2ghz_channels); band->channels = channels; band->n_bitrates = ath11k_g_rates_size; @@ -5707,23 +5863,48 @@ static int ath11k_mac_setup_channels_rates(struct ath11k *ar, } if (supported_bands & WMI_HOST_WLAN_5G_CAP) { - channels = kmemdup(ath11k_5ghz_channels, - sizeof(ath11k_5ghz_channels), - GFP_KERNEL); - if (!channels) { - kfree(ar->mac.sbands[NL80211_BAND_2GHZ].channels); - return -ENOMEM; + if (reg_cap->high_5ghz_chan >= ATH11K_MAX_6G_FREQ) { + channels = kmemdup(ath11k_6ghz_channels, + sizeof(ath11k_6ghz_channels), GFP_KERNEL); + if (!channels) { + kfree(ar->mac.sbands[NL80211_BAND_2GHZ].channels); + return -ENOMEM; + } + + ar->supports_6ghz = true; + band = &ar->mac.sbands[NL80211_BAND_6GHZ]; + band->band = NL80211_BAND_6GHZ; + band->n_channels = ARRAY_SIZE(ath11k_6ghz_channels); + band->channels = channels; + band->n_bitrates = ath11k_a_rates_size; + band->bitrates = ath11k_a_rates; + ar->hw->wiphy->bands[NL80211_BAND_6GHZ] = band; + ath11k_mac_update_ch_list(ar, band, + reg_cap->low_5ghz_chan, + reg_cap->high_5ghz_chan); } - band = &ar->mac.sbands[NL80211_BAND_5GHZ]; - band->n_channels = ARRAY_SIZE(ath11k_5ghz_channels); - band->channels = channels; - band->n_bitrates = ath11k_a_rates_size; - band->bitrates = ath11k_a_rates; - ar->hw->wiphy->bands[NL80211_BAND_5GHZ] = band; - ath11k_mac_update_ch_list(ar, band, - reg_cap->low_5ghz_chan, - reg_cap->high_5ghz_chan); + if (reg_cap->low_5ghz_chan < ATH11K_MIN_6G_FREQ) { + channels = kmemdup(ath11k_5ghz_channels, + sizeof(ath11k_5ghz_channels), + GFP_KERNEL); + if (!channels) { + kfree(ar->mac.sbands[NL80211_BAND_2GHZ].channels); + kfree(ar->mac.sbands[NL80211_BAND_6GHZ].channels); + return -ENOMEM; + } + + band = &ar->mac.sbands[NL80211_BAND_5GHZ]; + band->band = NL80211_BAND_5GHZ; + band->n_channels = ARRAY_SIZE(ath11k_5ghz_channels); + band->channels = channels; + band->n_bitrates = ath11k_a_rates_size; + band->bitrates = ath11k_a_rates; + ar->hw->wiphy->bands[NL80211_BAND_5GHZ] = band; + ath11k_mac_update_ch_list(ar, band, + reg_cap->low_5ghz_chan, + reg_cap->high_5ghz_chan); + } } return 0; @@ -5777,6 +5958,7 @@ static void __ath11k_mac_unregister(struct ath11k *ar) kfree(ar->mac.sbands[NL80211_BAND_2GHZ].channels); kfree(ar->mac.sbands[NL80211_BAND_5GHZ].channels); + kfree(ar->mac.sbands[NL80211_BAND_6GHZ].channels); SET_IEEE80211_DEV(ar->hw, NULL); } diff --git a/drivers/net/wireless/ath/ath11k/reg.c b/drivers/net/wireless/ath/ath11k/reg.c index 453aa9c06969..7c9dc91cc48a 100644 --- a/drivers/net/wireless/ath/ath11k/reg.c +++ b/drivers/net/wireless/ath/ath11k/reg.c @@ -161,6 +161,10 @@ int ath11k_reg_update_chan_list(struct ath11k *ar) else ch->phy_mode = MODE_11A; + if (channel->band == NL80211_BAND_6GHZ && + cfg80211_channel_is_psc(channel)) + ch->psc_channel = true; + ath11k_dbg(ar->ab, ATH11K_DBG_WMI, "mac channel [%d/%d] freq %d maxpower %d regpower %d antenna %d mode %d\n", i, params->nallchans, diff --git a/drivers/net/wireless/ath/ath11k/spectral.c b/drivers/net/wireless/ath/ath11k/spectral.c new file mode 100644 index 000000000000..1c5d65bb411f --- /dev/null +++ b/drivers/net/wireless/ath/ath11k/spectral.c @@ -0,0 +1,1023 @@ +// SPDX-License-Identifier: BSD-3-Clause-Clear +/* + * Copyright (c) 2019-2020 The Linux Foundation. All rights reserved. + */ + +#include <linux/relay.h> +#include "core.h" +#include "debug.h" + +#define ATH11K_SPECTRAL_NUM_RESP_PER_EVENT 2 +#define ATH11K_SPECTRAL_EVENT_TIMEOUT_MS 1 + +#define ATH11K_SPECTRAL_DWORD_SIZE 4 +/* HW bug, expected BIN size is 2 bytes but HW report as 4 bytes */ +#define ATH11K_SPECTRAL_BIN_SIZE 4 +#define ATH11K_SPECTRAL_ATH11K_MIN_BINS 64 +#define ATH11K_SPECTRAL_ATH11K_MIN_IB_BINS 32 +#define ATH11K_SPECTRAL_ATH11K_MAX_IB_BINS 256 + +#define ATH11K_SPECTRAL_SAMPLE_FFT_BIN_MASK 0xFF + +#define ATH11K_SPECTRAL_SCAN_COUNT_MAX 4095 + +/* Max channel computed by sum of 2g and 5g band channels */ +#define ATH11K_SPECTRAL_TOTAL_CHANNEL 41 +#define ATH11K_SPECTRAL_SAMPLES_PER_CHANNEL 70 +#define ATH11K_SPECTRAL_PER_SAMPLE_SIZE (sizeof(struct fft_sample_ath11k) + \ + ATH11K_SPECTRAL_ATH11K_MAX_IB_BINS) +#define ATH11K_SPECTRAL_TOTAL_SAMPLE (ATH11K_SPECTRAL_TOTAL_CHANNEL * \ + ATH11K_SPECTRAL_SAMPLES_PER_CHANNEL) +#define ATH11K_SPECTRAL_SUB_BUFF_SIZE ATH11K_SPECTRAL_PER_SAMPLE_SIZE +#define ATH11K_SPECTRAL_NUM_SUB_BUF ATH11K_SPECTRAL_TOTAL_SAMPLE + +#define ATH11K_SPECTRAL_20MHZ 20 +#define ATH11K_SPECTRAL_40MHZ 40 +#define ATH11K_SPECTRAL_80MHZ 80 + +#define ATH11K_SPECTRAL_SIGNATURE 0xFA + +#define ATH11K_SPECTRAL_TAG_RADAR_SUMMARY 0x0 +#define ATH11K_SPECTRAL_TAG_RADAR_FFT 0x1 +#define ATH11K_SPECTRAL_TAG_SCAN_SUMMARY 0x2 +#define ATH11K_SPECTRAL_TAG_SCAN_SEARCH 0x3 + +#define SPECTRAL_TLV_HDR_LEN GENMASK(15, 0) +#define SPECTRAL_TLV_HDR_TAG GENMASK(23, 16) +#define SPECTRAL_TLV_HDR_SIGN GENMASK(31, 24) + +#define SPECTRAL_SUMMARY_INFO0_AGC_TOTAL_GAIN GENMASK(7, 0) +#define SPECTRAL_SUMMARY_INFO0_OB_FLAG BIT(8) +#define SPECTRAL_SUMMARY_INFO0_GRP_IDX GENMASK(16, 9) +#define SPECTRAL_SUMMARY_INFO0_RECENT_RFSAT BIT(17) +#define SPECTRAL_SUMMARY_INFO0_INBAND_PWR_DB GENMASK(27, 18) +#define SPECTRAL_SUMMARY_INFO0_FALSE_SCAN BIT(28) +#define SPECTRAL_SUMMARY_INFO0_DETECTOR_ID GENMASK(30, 29) +#define SPECTRAL_SUMMARY_INFO0_PRI80 BIT(31) + +#define SPECTRAL_SUMMARY_INFO2_PEAK_SIGNED_IDX GENMASK(11, 0) +#define SPECTRAL_SUMMARY_INFO2_PEAK_MAGNITUDE GENMASK(21, 12) +#define SPECTRAL_SUMMARY_INFO2_NARROWBAND_MASK GENMASK(29, 22) +#define SPECTRAL_SUMMARY_INFO2_GAIN_CHANGE BIT(30) + +struct spectral_tlv { + __le32 timestamp; + __le32 header; +} __packed; + +struct spectral_summary_fft_report { + __le32 timestamp; + __le32 tlv_header; + __le32 info0; + __le32 reserve0; + __le32 info2; + __le32 reserve1; +} __packed; + +struct ath11k_spectral_summary_report { + struct wmi_dma_buf_release_meta_data meta; + u32 timestamp; + u8 agc_total_gain; + u8 grp_idx; + u16 inb_pwr_db; + s16 peak_idx; + u16 peak_mag; + u8 detector_id; + bool out_of_band_flag; + bool rf_saturation; + bool primary80; + bool gain_change; + bool false_scan; +}; + +#define SPECTRAL_FFT_REPORT_INFO0_DETECTOR_ID GENMASK(1, 0) +#define SPECTRAL_FFT_REPORT_INFO0_FFT_NUM GENMASK(4, 2) +#define SPECTRAL_FFT_REPORT_INFO0_RADAR_CHECK GENMASK(16, 5) +#define SPECTRAL_FFT_REPORT_INFO0_PEAK_SIGNED_IDX GENMASK(27, 17) +#define SPECTRAL_FFT_REPORT_INFO0_CHAIN_IDX GENMASK(30, 28) + +#define SPECTRAL_FFT_REPORT_INFO1_BASE_PWR_DB GENMASK(8, 0) +#define SPECTRAL_FFT_REPORT_INFO1_TOTAL_GAIN_DB GENMASK(16, 9) + +#define SPECTRAL_FFT_REPORT_INFO2_NUM_STRONG_BINS GENMASK(7, 0) +#define SPECTRAL_FFT_REPORT_INFO2_PEAK_MAGNITUDE GENMASK(17, 8) +#define SPECTRAL_FFT_REPORT_INFO2_AVG_PWR_DB GENMASK(24, 18) +#define SPECTRAL_FFT_REPORT_INFO2_REL_PWR_DB GENMASK(31, 25) + +struct spectral_search_fft_report { + __le32 timestamp; + __le32 tlv_header; + __le32 info0; + __le32 info1; + __le32 info2; + __le32 reserve0; + u8 bins[0]; +} __packed; + +struct ath11k_spectral_search_report { + u32 timestamp; + u8 detector_id; + u8 fft_count; + u16 radar_check; + s16 peak_idx; + u8 chain_idx; + u16 base_pwr_db; + u8 total_gain_db; + u8 strong_bin_count; + u16 peak_mag; + u8 avg_pwr_db; + u8 rel_pwr_db; +}; + +static struct dentry *create_buf_file_handler(const char *filename, + struct dentry *parent, + umode_t mode, + struct rchan_buf *buf, + int *is_global) +{ + struct dentry *buf_file; + + buf_file = debugfs_create_file(filename, mode, parent, buf, + &relay_file_operations); + *is_global = 1; + return buf_file; +} + +static int remove_buf_file_handler(struct dentry *dentry) +{ + debugfs_remove(dentry); + + return 0; +} + +static struct rchan_callbacks rfs_scan_cb = { + .create_buf_file = create_buf_file_handler, + .remove_buf_file = remove_buf_file_handler, +}; + +static struct ath11k_vif *ath11k_spectral_get_vdev(struct ath11k *ar) +{ + struct ath11k_vif *arvif; + + lockdep_assert_held(&ar->conf_mutex); + + if (list_empty(&ar->arvifs)) + return NULL; + + /* if there already is a vif doing spectral, return that. */ + list_for_each_entry(arvif, &ar->arvifs, list) + if (arvif->spectral_enabled) + return arvif; + + /* otherwise, return the first vif. */ + return list_first_entry(&ar->arvifs, typeof(*arvif), list); +} + +static int ath11k_spectral_scan_trigger(struct ath11k *ar) +{ + struct ath11k_vif *arvif; + int ret; + + lockdep_assert_held(&ar->conf_mutex); + + arvif = ath11k_spectral_get_vdev(ar); + if (!arvif) + return -ENODEV; + + if (ar->spectral.mode == ATH11K_SPECTRAL_DISABLED) + return 0; + + ret = ath11k_wmi_vdev_spectral_enable(ar, arvif->vdev_id, + ATH11K_WMI_SPECTRAL_TRIGGER_CMD_CLEAR, + ATH11K_WMI_SPECTRAL_ENABLE_CMD_ENABLE); + if (ret) + return ret; + + ret = ath11k_wmi_vdev_spectral_enable(ar, arvif->vdev_id, + ATH11K_WMI_SPECTRAL_TRIGGER_CMD_TRIGGER, + ATH11K_WMI_SPECTRAL_ENABLE_CMD_ENABLE); + if (ret) + return ret; + + return 0; +} + +static int ath11k_spectral_scan_config(struct ath11k *ar, + enum ath11k_spectral_mode mode) +{ + struct ath11k_wmi_vdev_spectral_conf_param param = { 0 }; + struct ath11k_vif *arvif; + int ret, count; + + lockdep_assert_held(&ar->conf_mutex); + + arvif = ath11k_spectral_get_vdev(ar); + if (!arvif) + return -ENODEV; + + arvif->spectral_enabled = (mode != ATH11K_SPECTRAL_DISABLED); + ar->spectral.mode = mode; + + ret = ath11k_wmi_vdev_spectral_enable(ar, arvif->vdev_id, + ATH11K_WMI_SPECTRAL_TRIGGER_CMD_CLEAR, + ATH11K_WMI_SPECTRAL_ENABLE_CMD_DISABLE); + if (ret) { + ath11k_warn(ar->ab, "failed to enable spectral scan: %d\n", ret); + return ret; + } + + if (mode == ATH11K_SPECTRAL_DISABLED) + return 0; + + if (mode == ATH11K_SPECTRAL_BACKGROUND) + count = ATH11K_WMI_SPECTRAL_COUNT_DEFAULT; + else + count = max_t(u16, 1, ar->spectral.count); + + param.vdev_id = arvif->vdev_id; + param.scan_count = count; + param.scan_fft_size = ar->spectral.fft_size; + param.scan_period = ATH11K_WMI_SPECTRAL_PERIOD_DEFAULT; + param.scan_priority = ATH11K_WMI_SPECTRAL_PRIORITY_DEFAULT; + param.scan_gc_ena = ATH11K_WMI_SPECTRAL_GC_ENA_DEFAULT; + param.scan_restart_ena = ATH11K_WMI_SPECTRAL_RESTART_ENA_DEFAULT; + param.scan_noise_floor_ref = ATH11K_WMI_SPECTRAL_NOISE_FLOOR_REF_DEFAULT; + param.scan_init_delay = ATH11K_WMI_SPECTRAL_INIT_DELAY_DEFAULT; + param.scan_nb_tone_thr = ATH11K_WMI_SPECTRAL_NB_TONE_THR_DEFAULT; + param.scan_str_bin_thr = ATH11K_WMI_SPECTRAL_STR_BIN_THR_DEFAULT; + param.scan_wb_rpt_mode = ATH11K_WMI_SPECTRAL_WB_RPT_MODE_DEFAULT; + param.scan_rssi_rpt_mode = ATH11K_WMI_SPECTRAL_RSSI_RPT_MODE_DEFAULT; + param.scan_rssi_thr = ATH11K_WMI_SPECTRAL_RSSI_THR_DEFAULT; + param.scan_pwr_format = ATH11K_WMI_SPECTRAL_PWR_FORMAT_DEFAULT; + param.scan_rpt_mode = ATH11K_WMI_SPECTRAL_RPT_MODE_DEFAULT; + param.scan_bin_scale = ATH11K_WMI_SPECTRAL_BIN_SCALE_DEFAULT; + param.scan_dbm_adj = ATH11K_WMI_SPECTRAL_DBM_ADJ_DEFAULT; + param.scan_chn_mask = ATH11K_WMI_SPECTRAL_CHN_MASK_DEFAULT; + + ret = ath11k_wmi_vdev_spectral_conf(ar, ¶m); + if (ret) { + ath11k_warn(ar->ab, "failed to configure spectral scan: %d\n", ret); + return ret; + } + + return 0; +} + +static ssize_t ath11k_read_file_spec_scan_ctl(struct file *file, + char __user *user_buf, + size_t count, loff_t *ppos) +{ + struct ath11k *ar = file->private_data; + char *mode = ""; + size_t len; + enum ath11k_spectral_mode spectral_mode; + + mutex_lock(&ar->conf_mutex); + spectral_mode = ar->spectral.mode; + mutex_unlock(&ar->conf_mutex); + + switch (spectral_mode) { + case ATH11K_SPECTRAL_DISABLED: + mode = "disable"; + break; + case ATH11K_SPECTRAL_BACKGROUND: + mode = "background"; + break; + case ATH11K_SPECTRAL_MANUAL: + mode = "manual"; + break; + } + + len = strlen(mode); + return simple_read_from_buffer(user_buf, count, ppos, mode, len); +} + +static ssize_t ath11k_write_file_spec_scan_ctl(struct file *file, + const char __user *user_buf, + size_t count, loff_t *ppos) +{ + struct ath11k *ar = file->private_data; + char buf[32]; + ssize_t len; + int ret; + + len = min(count, sizeof(buf) - 1); + if (copy_from_user(buf, user_buf, len)) + return -EFAULT; + + buf[len] = '\0'; + + mutex_lock(&ar->conf_mutex); + + if (strncmp("trigger", buf, 7) == 0) { + if (ar->spectral.mode == ATH11K_SPECTRAL_MANUAL || + ar->spectral.mode == ATH11K_SPECTRAL_BACKGROUND) { + /* reset the configuration to adopt possibly changed + * debugfs parameters + */ + ret = ath11k_spectral_scan_config(ar, ar->spectral.mode); + if (ret) { + ath11k_warn(ar->ab, "failed to reconfigure spectral scan: %d\n", + ret); + goto unlock; + } + + ret = ath11k_spectral_scan_trigger(ar); + if (ret) { + ath11k_warn(ar->ab, "failed to trigger spectral scan: %d\n", + ret); + } + } else { + ret = -EINVAL; + } + } else if (strncmp("background", buf, 10) == 0) { + ret = ath11k_spectral_scan_config(ar, ATH11K_SPECTRAL_BACKGROUND); + } else if (strncmp("manual", buf, 6) == 0) { + ret = ath11k_spectral_scan_config(ar, ATH11K_SPECTRAL_MANUAL); + } else if (strncmp("disable", buf, 7) == 0) { + ret = ath11k_spectral_scan_config(ar, ATH11K_SPECTRAL_DISABLED); + } else { + ret = -EINVAL; + } + +unlock: + mutex_unlock(&ar->conf_mutex); + + if (ret) + return ret; + + return count; +} + +static const struct file_operations fops_scan_ctl = { + .read = ath11k_read_file_spec_scan_ctl, + .write = ath11k_write_file_spec_scan_ctl, + .open = simple_open, + .owner = THIS_MODULE, + .llseek = default_llseek, +}; + +static ssize_t ath11k_read_file_spectral_count(struct file *file, + char __user *user_buf, + size_t count, loff_t *ppos) +{ + struct ath11k *ar = file->private_data; + char buf[32]; + size_t len; + u16 spectral_count; + + mutex_lock(&ar->conf_mutex); + spectral_count = ar->spectral.count; + mutex_unlock(&ar->conf_mutex); + + len = sprintf(buf, "%d\n", spectral_count); + return simple_read_from_buffer(user_buf, count, ppos, buf, len); +} + +static ssize_t ath11k_write_file_spectral_count(struct file *file, + const char __user *user_buf, + size_t count, loff_t *ppos) +{ + struct ath11k *ar = file->private_data; + unsigned long val; + char buf[32]; + ssize_t len; + + len = min(count, sizeof(buf) - 1); + if (copy_from_user(buf, user_buf, len)) + return -EFAULT; + + buf[len] = '\0'; + if (kstrtoul(buf, 0, &val)) + return -EINVAL; + + if (val > ATH11K_SPECTRAL_SCAN_COUNT_MAX) + return -EINVAL; + + mutex_lock(&ar->conf_mutex); + ar->spectral.count = val; + mutex_unlock(&ar->conf_mutex); + + return count; +} + +static const struct file_operations fops_scan_count = { + .read = ath11k_read_file_spectral_count, + .write = ath11k_write_file_spectral_count, + .open = simple_open, + .owner = THIS_MODULE, + .llseek = default_llseek, +}; + +static ssize_t ath11k_read_file_spectral_bins(struct file *file, + char __user *user_buf, + size_t count, loff_t *ppos) +{ + struct ath11k *ar = file->private_data; + char buf[32]; + unsigned int bins, fft_size; + size_t len; + + mutex_lock(&ar->conf_mutex); + + fft_size = ar->spectral.fft_size; + bins = 1 << fft_size; + + mutex_unlock(&ar->conf_mutex); + + len = sprintf(buf, "%d\n", bins); + return simple_read_from_buffer(user_buf, count, ppos, buf, len); +} + +static ssize_t ath11k_write_file_spectral_bins(struct file *file, + const char __user *user_buf, + size_t count, loff_t *ppos) +{ + struct ath11k *ar = file->private_data; + unsigned long val; + char buf[32]; + ssize_t len; + + len = min(count, sizeof(buf) - 1); + if (copy_from_user(buf, user_buf, len)) + return -EFAULT; + + buf[len] = '\0'; + if (kstrtoul(buf, 0, &val)) + return -EINVAL; + + if (val < ATH11K_SPECTRAL_ATH11K_MIN_BINS || + val > SPECTRAL_ATH11K_MAX_NUM_BINS) + return -EINVAL; + + if (!is_power_of_2(val)) + return -EINVAL; + + mutex_lock(&ar->conf_mutex); + ar->spectral.fft_size = ilog2(val); + mutex_unlock(&ar->conf_mutex); + + return count; +} + +static const struct file_operations fops_scan_bins = { + .read = ath11k_read_file_spectral_bins, + .write = ath11k_write_file_spectral_bins, + .open = simple_open, + .owner = THIS_MODULE, + .llseek = default_llseek, +}; + +static int ath11k_spectral_pull_summary(struct ath11k *ar, + struct wmi_dma_buf_release_meta_data *meta, + struct spectral_summary_fft_report *summary, + struct ath11k_spectral_summary_report *report) +{ + report->timestamp = __le32_to_cpu(summary->timestamp); + report->agc_total_gain = FIELD_GET(SPECTRAL_SUMMARY_INFO0_AGC_TOTAL_GAIN, + __le32_to_cpu(summary->info0)); + report->out_of_band_flag = FIELD_GET(SPECTRAL_SUMMARY_INFO0_OB_FLAG, + __le32_to_cpu(summary->info0)); + report->grp_idx = FIELD_GET(SPECTRAL_SUMMARY_INFO0_GRP_IDX, + __le32_to_cpu(summary->info0)); + report->rf_saturation = FIELD_GET(SPECTRAL_SUMMARY_INFO0_RECENT_RFSAT, + __le32_to_cpu(summary->info0)); + report->inb_pwr_db = FIELD_GET(SPECTRAL_SUMMARY_INFO0_INBAND_PWR_DB, + __le32_to_cpu(summary->info0)); + report->false_scan = FIELD_GET(SPECTRAL_SUMMARY_INFO0_FALSE_SCAN, + __le32_to_cpu(summary->info0)); + report->detector_id = FIELD_GET(SPECTRAL_SUMMARY_INFO0_DETECTOR_ID, + __le32_to_cpu(summary->info0)); + report->primary80 = FIELD_GET(SPECTRAL_SUMMARY_INFO0_PRI80, + __le32_to_cpu(summary->info0)); + report->peak_idx = FIELD_GET(SPECTRAL_SUMMARY_INFO2_PEAK_SIGNED_IDX, + __le32_to_cpu(summary->info2)); + report->peak_mag = FIELD_GET(SPECTRAL_SUMMARY_INFO2_PEAK_MAGNITUDE, + __le32_to_cpu(summary->info2)); + report->gain_change = FIELD_GET(SPECTRAL_SUMMARY_INFO2_GAIN_CHANGE, + __le32_to_cpu(summary->info2)); + + memcpy(&report->meta, meta, sizeof(*meta)); + + return 0; +} + +static int ath11k_spectral_pull_search(struct ath11k *ar, + struct spectral_search_fft_report *search, + struct ath11k_spectral_search_report *report) +{ + report->timestamp = __le32_to_cpu(search->timestamp); + report->detector_id = FIELD_GET(SPECTRAL_FFT_REPORT_INFO0_DETECTOR_ID, + __le32_to_cpu(search->info0)); + report->fft_count = FIELD_GET(SPECTRAL_FFT_REPORT_INFO0_FFT_NUM, + __le32_to_cpu(search->info0)); + report->radar_check = FIELD_GET(SPECTRAL_FFT_REPORT_INFO0_RADAR_CHECK, + __le32_to_cpu(search->info0)); + report->peak_idx = FIELD_GET(SPECTRAL_FFT_REPORT_INFO0_PEAK_SIGNED_IDX, + __le32_to_cpu(search->info0)); + report->chain_idx = FIELD_GET(SPECTRAL_FFT_REPORT_INFO0_CHAIN_IDX, + __le32_to_cpu(search->info0)); + report->base_pwr_db = FIELD_GET(SPECTRAL_FFT_REPORT_INFO1_BASE_PWR_DB, + __le32_to_cpu(search->info1)); + report->total_gain_db = FIELD_GET(SPECTRAL_FFT_REPORT_INFO1_TOTAL_GAIN_DB, + __le32_to_cpu(search->info1)); + report->strong_bin_count = FIELD_GET(SPECTRAL_FFT_REPORT_INFO2_NUM_STRONG_BINS, + __le32_to_cpu(search->info2)); + report->peak_mag = FIELD_GET(SPECTRAL_FFT_REPORT_INFO2_PEAK_MAGNITUDE, + __le32_to_cpu(search->info2)); + report->avg_pwr_db = FIELD_GET(SPECTRAL_FFT_REPORT_INFO2_AVG_PWR_DB, + __le32_to_cpu(search->info2)); + report->rel_pwr_db = FIELD_GET(SPECTRAL_FFT_REPORT_INFO2_REL_PWR_DB, + __le32_to_cpu(search->info2)); + + return 0; +} + +static u8 ath11k_spectral_get_max_exp(s8 max_index, u8 max_magnitude, + int bin_len, u8 *bins) +{ + int dc_pos; + u8 max_exp; + + dc_pos = bin_len / 2; + + /* peak index outside of bins */ + if (dc_pos <= max_index || -dc_pos >= max_index) + return 0; + + for (max_exp = 0; max_exp < 8; max_exp++) { + if (bins[dc_pos + max_index] == (max_magnitude >> max_exp)) + break; + } + + /* max_exp not found */ + if (bins[dc_pos + max_index] != (max_magnitude >> max_exp)) + return 0; + + return max_exp; +} + +static void ath11k_spectral_parse_16bit_fft(u8 *outbins, u8 *inbins, int num_bins) +{ + int i; + __le16 *data = (__le16 *)inbins; + + i = 0; + while (i < num_bins) { + outbins[i] = (__le16_to_cpu(data[i])) & + ATH11K_SPECTRAL_SAMPLE_FFT_BIN_MASK; + i++; + } +} + +static +int ath11k_spectral_process_fft(struct ath11k *ar, + struct ath11k_spectral_summary_report *summary, + void *data, + struct fft_sample_ath11k *fft_sample, + u32 data_len) +{ + struct ath11k_base *ab = ar->ab; + struct spectral_search_fft_report *fft_report = data; + struct ath11k_spectral_search_report search; + struct spectral_tlv *tlv; + int tlv_len, bin_len, num_bins; + u16 length, freq; + u8 chan_width_mhz; + int ret; + + lockdep_assert_held(&ar->spectral.lock); + + tlv = (struct spectral_tlv *)data; + tlv_len = FIELD_GET(SPECTRAL_TLV_HDR_LEN, __le32_to_cpu(tlv->header)); + /* convert Dword into bytes */ + tlv_len *= ATH11K_SPECTRAL_DWORD_SIZE; + bin_len = tlv_len - (sizeof(*fft_report) - sizeof(*tlv)); + + if (data_len < (bin_len + sizeof(*fft_report))) { + ath11k_warn(ab, "mismatch in expected bin len %d and data len %d\n", + bin_len, data_len); + return -EINVAL; + } + + num_bins = bin_len / ATH11K_SPECTRAL_BIN_SIZE; + /* Only In-band bins are useful to user for visualize */ + num_bins >>= 1; + + if (num_bins < ATH11K_SPECTRAL_ATH11K_MIN_IB_BINS || + num_bins > ATH11K_SPECTRAL_ATH11K_MAX_IB_BINS || + !is_power_of_2(num_bins)) { + ath11k_warn(ab, "Invalid num of bins %d\n", num_bins); + return -EINVAL; + } + + ret = ath11k_spectral_pull_search(ar, data, &search); + if (ret) { + ath11k_warn(ab, "failed to pull search report %d\n", ret); + return ret; + } + + chan_width_mhz = summary->meta.ch_width; + + switch (chan_width_mhz) { + case ATH11K_SPECTRAL_20MHZ: + case ATH11K_SPECTRAL_40MHZ: + case ATH11K_SPECTRAL_80MHZ: + fft_sample->chan_width_mhz = chan_width_mhz; + break; + default: + ath11k_warn(ab, "invalid channel width %d\n", chan_width_mhz); + return -EINVAL; + } + + length = sizeof(*fft_sample) - sizeof(struct fft_sample_tlv) + num_bins; + fft_sample->tlv.type = ATH_FFT_SAMPLE_ATH11K; + fft_sample->tlv.length = __cpu_to_be16(length); + + fft_sample->tsf = __cpu_to_be32(search.timestamp); + fft_sample->max_magnitude = __cpu_to_be16(search.peak_mag); + fft_sample->max_index = FIELD_GET(SPECTRAL_FFT_REPORT_INFO0_PEAK_SIGNED_IDX, + __le32_to_cpu(fft_report->info0)); + + summary->inb_pwr_db >>= 1; + fft_sample->rssi = __cpu_to_be16(summary->inb_pwr_db); + fft_sample->noise = __cpu_to_be32(summary->meta.noise_floor[search.chain_idx]); + + freq = summary->meta.freq1; + fft_sample->freq1 = __cpu_to_be16(freq); + + freq = summary->meta.freq2; + fft_sample->freq2 = __cpu_to_be16(freq); + + ath11k_spectral_parse_16bit_fft(fft_sample->data, + fft_report->bins, + num_bins); + + fft_sample->max_exp = ath11k_spectral_get_max_exp(fft_sample->max_index, + search.peak_mag, + num_bins, + fft_sample->data); + + if (ar->spectral.rfs_scan) + relay_write(ar->spectral.rfs_scan, fft_sample, + length + sizeof(struct fft_sample_tlv)); + + return 0; +} + +static int ath11k_spectral_process_data(struct ath11k *ar, + struct ath11k_dbring_data *param) +{ + struct ath11k_base *ab = ar->ab; + struct spectral_tlv *tlv; + struct spectral_summary_fft_report *summary = NULL; + struct ath11k_spectral_summary_report summ_rpt; + struct fft_sample_ath11k *fft_sample = NULL; + u8 *data; + u32 data_len, i; + u8 sign, tag; + int tlv_len, sample_sz; + int ret; + bool quit = false; + + spin_lock_bh(&ar->spectral.lock); + + if (!ar->spectral.enabled) { + ret = -EINVAL; + goto unlock; + } + + sample_sz = sizeof(*fft_sample) + ATH11K_SPECTRAL_ATH11K_MAX_IB_BINS; + fft_sample = kmalloc(sample_sz, GFP_ATOMIC); + if (!fft_sample) { + ret = -ENOBUFS; + goto unlock; + } + + data = param->data; + data_len = param->data_sz; + i = 0; + while (!quit && (i < data_len)) { + if ((i + sizeof(*tlv)) > data_len) { + ath11k_warn(ab, "failed to parse spectral tlv hdr at bytes %d\n", + i); + ret = -EINVAL; + goto err; + } + + tlv = (struct spectral_tlv *)&data[i]; + sign = FIELD_GET(SPECTRAL_TLV_HDR_SIGN, + __le32_to_cpu(tlv->header)); + if (sign != ATH11K_SPECTRAL_SIGNATURE) { + ath11k_warn(ab, "Invalid sign 0x%x at bytes %d\n", + sign, i); + ret = -EINVAL; + goto err; + } + + tlv_len = FIELD_GET(SPECTRAL_TLV_HDR_LEN, + __le32_to_cpu(tlv->header)); + /* convert Dword into bytes */ + tlv_len *= ATH11K_SPECTRAL_DWORD_SIZE; + if ((i + sizeof(*tlv) + tlv_len) > data_len) { + ath11k_warn(ab, "failed to parse spectral tlv payload at bytes %d tlv_len:%d data_len:%d\n", + i, tlv_len, data_len); + ret = -EINVAL; + goto err; + } + + tag = FIELD_GET(SPECTRAL_TLV_HDR_TAG, + __le32_to_cpu(tlv->header)); + switch (tag) { + case ATH11K_SPECTRAL_TAG_SCAN_SUMMARY: + /* HW bug in tlv length of summary report, + * HW report 3 DWORD size but the data payload + * is 4 DWORD size (16 bytes). + * Need to remove this workaround once HW bug fixed + */ + tlv_len = sizeof(*summary) - sizeof(*tlv); + + if (tlv_len < (sizeof(*summary) - sizeof(*tlv))) { + ath11k_warn(ab, "failed to parse spectral summary at bytes %d tlv_len:%d\n", + i, tlv_len); + ret = -EINVAL; + goto err; + } + + summary = (struct spectral_summary_fft_report *)tlv; + ath11k_spectral_pull_summary(ar, ¶m->meta, + summary, &summ_rpt); + break; + case ATH11K_SPECTRAL_TAG_SCAN_SEARCH: + if (tlv_len < (sizeof(struct spectral_search_fft_report) - + sizeof(*tlv))) { + ath11k_warn(ab, "failed to parse spectral search fft at bytes %d\n", + i); + ret = -EINVAL; + goto err; + } + + memset(fft_sample, 0, sample_sz); + ret = ath11k_spectral_process_fft(ar, &summ_rpt, tlv, + fft_sample, + data_len - i); + if (ret) { + ath11k_warn(ab, "failed to process spectral fft at bytes %d\n", + i); + goto err; + } + quit = true; + break; + } + + i += sizeof(*tlv) + tlv_len; + } + +err: + kfree(fft_sample); +unlock: + spin_unlock_bh(&ar->spectral.lock); + return ret; +} + +static int ath11k_spectral_ring_alloc(struct ath11k *ar, + struct ath11k_dbring_cap *db_cap) +{ + struct ath11k_spectral *sp = &ar->spectral; + int ret; + + ret = ath11k_dbring_srng_setup(ar, &sp->rx_ring, + 0, db_cap->min_elem); + if (ret) { + ath11k_warn(ar->ab, "failed to setup db ring\n"); + return ret; + } + + ath11k_dbring_set_cfg(ar, &sp->rx_ring, + ATH11K_SPECTRAL_NUM_RESP_PER_EVENT, + ATH11K_SPECTRAL_EVENT_TIMEOUT_MS, + ath11k_spectral_process_data); + + ret = ath11k_dbring_buf_setup(ar, &sp->rx_ring, db_cap); + if (ret) { + ath11k_warn(ar->ab, "failed to setup db ring buffer\n"); + goto srng_cleanup; + } + + ret = ath11k_dbring_wmi_cfg_setup(ar, &sp->rx_ring, + WMI_DIRECT_BUF_SPECTRAL); + if (ret) { + ath11k_warn(ar->ab, "failed to setup db ring cfg\n"); + goto buffer_cleanup; + } + + return 0; + +buffer_cleanup: + ath11k_dbring_buf_cleanup(ar, &sp->rx_ring); +srng_cleanup: + ath11k_dbring_srng_cleanup(ar, &sp->rx_ring); + return ret; +} + +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); +} + +static inline void ath11k_spectral_debug_unregister(struct ath11k *ar) +{ + debugfs_remove(ar->spectral.scan_bins); + ar->spectral.scan_bins = NULL; + + debugfs_remove(ar->spectral.scan_count); + ar->spectral.scan_count = NULL; + + debugfs_remove(ar->spectral.scan_ctl); + ar->spectral.scan_ctl = NULL; + + if (ar->spectral.rfs_scan) { + relay_close(ar->spectral.rfs_scan); + ar->spectral.rfs_scan = NULL; + } +} + +int ath11k_spectral_vif_stop(struct ath11k_vif *arvif) +{ + if (!arvif->spectral_enabled) + return 0; + + return ath11k_spectral_scan_config(arvif->ar, ATH11K_SPECTRAL_DISABLED); +} + +void ath11k_spectral_reset_buffer(struct ath11k *ar) +{ + if (!ar->spectral.enabled) + return; + + if (ar->spectral.rfs_scan) + relay_reset(ar->spectral.rfs_scan); +} + +void ath11k_spectral_deinit(struct ath11k_base *ab) +{ + struct ath11k *ar; + struct ath11k_spectral *sp; + int i; + + for (i = 0; i < ab->num_radios; i++) { + ar = ab->pdevs[i].ar; + sp = &ar->spectral; + + if (!sp->enabled) + continue; + + ath11k_spectral_debug_unregister(ar); + ath11k_spectral_ring_free(ar); + + spin_lock_bh(&sp->lock); + + sp->mode = ATH11K_SPECTRAL_DISABLED; + sp->enabled = false; + + spin_unlock_bh(&sp->lock); + } +} + +static inline int ath11k_spectral_debug_register(struct ath11k *ar) +{ + int ret; + + ar->spectral.rfs_scan = relay_open("spectral_scan", + ar->debug.debugfs_pdev, + ATH11K_SPECTRAL_SUB_BUFF_SIZE, + ATH11K_SPECTRAL_NUM_SUB_BUF, + &rfs_scan_cb, NULL); + if (!ar->spectral.rfs_scan) { + ath11k_warn(ar->ab, "failed to open relay in pdev %d\n", + ar->pdev_idx); + return -EINVAL; + } + + ar->spectral.scan_ctl = debugfs_create_file("spectral_scan_ctl", + 0600, + ar->debug.debugfs_pdev, ar, + &fops_scan_ctl); + if (!ar->spectral.scan_ctl) { + ath11k_warn(ar->ab, "failed to open debugfs in pdev %d\n", + ar->pdev_idx); + ret = -EINVAL; + goto debug_unregister; + } + + ar->spectral.scan_count = debugfs_create_file("spectral_count", + 0600, + ar->debug.debugfs_pdev, ar, + &fops_scan_count); + if (!ar->spectral.scan_count) { + ath11k_warn(ar->ab, "failed to open debugfs in pdev %d\n", + ar->pdev_idx); + ret = -EINVAL; + goto debug_unregister; + } + + ar->spectral.scan_bins = debugfs_create_file("spectral_bins", + 0600, + ar->debug.debugfs_pdev, ar, + &fops_scan_bins); + if (!ar->spectral.scan_bins) { + ath11k_warn(ar->ab, "failed to open debugfs in pdev %d\n", + ar->pdev_idx); + ret = -EINVAL; + goto debug_unregister; + } + + return 0; + +debug_unregister: + ath11k_spectral_debug_unregister(ar); + return ret; +} + +int ath11k_spectral_init(struct ath11k_base *ab) +{ + struct ath11k *ar; + struct ath11k_spectral *sp; + struct ath11k_dbring_cap db_cap; + int ret; + int i; + + if (!test_bit(WMI_TLV_SERVICE_FREQINFO_IN_METADATA, + ab->wmi_ab.svc_map)) { + ath11k_info(ab, "spectral not supported\n"); + return 0; + } + + for (i = 0; i < ab->num_radios; i++) { + ar = ab->pdevs[i].ar; + sp = &ar->spectral; + + ret = ath11k_dbring_get_cap(ar->ab, ar->pdev_idx, + WMI_DIRECT_BUF_SPECTRAL, + &db_cap); + if (ret) { + ath11k_info(ab, "spectral not enabled for pdev %d\n", i); + continue; + } + + idr_init(&sp->rx_ring.bufs_idr); + spin_lock_init(&sp->rx_ring.idr_lock); + spin_lock_init(&sp->lock); + + ret = ath11k_spectral_ring_alloc(ar, &db_cap); + if (ret) { + ath11k_warn(ab, "failed to init spectral ring for pdev %d\n", + i); + goto deinit; + } + + spin_lock_bh(&sp->lock); + + sp->mode = ATH11K_SPECTRAL_DISABLED; + sp->count = ATH11K_WMI_SPECTRAL_COUNT_DEFAULT; + sp->fft_size = ATH11K_WMI_SPECTRAL_FFT_SIZE_DEFAULT; + sp->enabled = true; + + spin_unlock_bh(&sp->lock); + + ret = ath11k_spectral_debug_register(ar); + if (ret) { + ath11k_warn(ab, "failed to register spectral for pdev %d\n", + i); + goto deinit; + } + } + + return 0; + +deinit: + ath11k_spectral_deinit(ab); + return ret; +} + +enum ath11k_spectral_mode ath11k_spectral_get_mode(struct ath11k *ar) +{ + if (ar->spectral.enabled) + return ar->spectral.mode; + else + return ATH11K_SPECTRAL_DISABLED; +} + +struct ath11k_dbring *ath11k_spectral_get_dbring(struct ath11k *ar) +{ + if (ar->spectral.enabled) + return &ar->spectral.rx_ring; + else + return NULL; +} diff --git a/drivers/net/wireless/ath/ath11k/spectral.h b/drivers/net/wireless/ath/ath11k/spectral.h new file mode 100644 index 000000000000..081744265f2a --- /dev/null +++ b/drivers/net/wireless/ath/ath11k/spectral.h @@ -0,0 +1,82 @@ +/* SPDX-License-Identifier: BSD-3-Clause-Clear */ +/* + * Copyright (c) 2019-2020 The Linux Foundation. All rights reserved. + */ + +#ifndef ATH11K_SPECTRAL_H +#define ATH11K_SPECTRAL_H + +#include "../spectral_common.h" +#include "dbring.h" + +/* enum ath11k_spectral_mode: + * + * @SPECTRAL_DISABLED: spectral mode is disabled + * @SPECTRAL_BACKGROUND: hardware sends samples when it is not busy with + * something else. + * @SPECTRAL_MANUAL: spectral scan is enabled, triggering for samples + * is performed manually. + */ +enum ath11k_spectral_mode { + ATH11K_SPECTRAL_DISABLED = 0, + ATH11K_SPECTRAL_BACKGROUND, + ATH11K_SPECTRAL_MANUAL, +}; + +struct ath11k_spectral { + struct ath11k_dbring rx_ring; + /* Protects enabled */ + spinlock_t lock; + struct rchan *rfs_scan; /* relay(fs) channel for spectral scan */ + struct dentry *scan_ctl; + struct dentry *scan_count; + struct dentry *scan_bins; + enum ath11k_spectral_mode mode; + u16 count; + u8 fft_size; + bool enabled; +}; + +#ifdef CONFIG_ATH11K_SPECTRAL + +int ath11k_spectral_init(struct ath11k_base *ab); +void ath11k_spectral_deinit(struct ath11k_base *ab); +int ath11k_spectral_vif_stop(struct ath11k_vif *arvif); +void ath11k_spectral_reset_buffer(struct ath11k *ar); +enum ath11k_spectral_mode ath11k_spectral_get_mode(struct ath11k *ar); +struct ath11k_dbring *ath11k_spectral_get_dbring(struct ath11k *ar); + +#else + +static inline int ath11k_spectral_init(struct ath11k_base *ab) +{ + return 0; +} + +static inline void ath11k_spectral_deinit(struct ath11k_base *ab) +{ +} + +static inline int ath11k_spectral_vif_stop(struct ath11k_vif *arvif) +{ + return 0; +} + +static inline void ath11k_spectral_reset_buffer(struct ath11k *ar) +{ +} + +static inline +enum ath11k_spectral_mode ath11k_spectral_get_mode(struct ath11k *ar) +{ + return ATH11K_SPECTRAL_DISABLED; +} + +static inline +struct ath11k_dbring *ath11k_spectral_get_dbring(struct ath11k *ar) +{ + return NULL; +} + +#endif /* CONFIG_ATH11K_SPECTRAL */ +#endif /* ATH11K_SPECTRAL_H */ diff --git a/drivers/net/wireless/ath/ath11k/wmi.c b/drivers/net/wireless/ath/ath11k/wmi.c index c2a972377687..8e3437a65673 100644 --- a/drivers/net/wireless/ath/ath11k/wmi.c +++ b/drivers/net/wireless/ath/ath11k/wmi.c @@ -27,6 +27,11 @@ struct wmi_tlv_svc_ready_parse { bool wmi_svc_bitmap_done; }; +struct wmi_tlv_dma_ring_caps_parse { + struct wmi_dma_ring_capabilities *dma_ring_caps; + u32 n_dma_ring_caps; +}; + struct wmi_tlv_svc_rdy_ext_parse { struct ath11k_service_ext_param param; struct wmi_soc_mac_phy_hw_mode_caps *hw_caps; @@ -39,15 +44,35 @@ struct wmi_tlv_svc_rdy_ext_parse { struct wmi_soc_hal_reg_capabilities *soc_hal_reg_caps; struct wmi_hal_reg_capabilities_ext *ext_hal_reg_caps; u32 n_ext_hal_reg_caps; + struct wmi_tlv_dma_ring_caps_parse dma_caps_parse; bool hw_mode_done; bool mac_phy_done; bool ext_hal_reg_done; + bool mac_phy_chainmask_combo_done; + bool mac_phy_chainmask_cap_done; + bool oem_dma_ring_cap_done; + bool dma_ring_cap_done; +}; + +struct wmi_tlv_svc_rdy_ext2_parse { + struct wmi_tlv_dma_ring_caps_parse dma_caps_parse; + bool dma_ring_cap_done; }; struct wmi_tlv_rdy_parse { u32 num_extra_mac_addr; }; +struct wmi_tlv_dma_buf_release_parse { + struct ath11k_wmi_dma_buf_release_fixed_param fixed; + struct wmi_dma_buf_release_entry *buf_entry; + struct wmi_dma_buf_release_meta_data *meta_data; + u32 num_buf_entry; + u32 num_meta; + bool buf_entry_done; + bool meta_data_done; +}; + static const struct wmi_tlv_policy wmi_tlv_policies[] = { [WMI_TAG_ARRAY_BYTE] = { .min_len = 0 }, @@ -368,6 +393,17 @@ ath11k_pull_mac_phy_cap_svc_ready_ext(struct ath11k_pdev_wmi *wmi_handle, memcpy(&cap_band->he_ppet, &mac_phy_caps->he_ppet5g, sizeof(struct ath11k_ppe_threshold)); + cap_band = &pdev_cap->band[NL80211_BAND_6GHZ]; + cap_band->max_bw_supported = mac_phy_caps->max_bw_supported_5g; + cap_band->ht_cap_info = mac_phy_caps->ht_cap_info_5g; + cap_band->he_cap_info[0] = mac_phy_caps->he_cap_info_5g; + cap_band->he_cap_info[1] = mac_phy_caps->he_cap_info_5g_ext; + cap_band->he_mcs = mac_phy_caps->he_supp_mcs_5g; + memcpy(cap_band->he_cap_phy_info, &mac_phy_caps->he_cap_phy_info_5g, + sizeof(u32) * PSOC_HOST_MAX_PHY_SIZE); + memcpy(&cap_band->he_ppet, &mac_phy_caps->he_ppet5g, + sizeof(struct ath11k_ppe_threshold)); + return 0; } @@ -1692,10 +1728,10 @@ ath11k_wmi_copy_peer_flags(struct wmi_peer_assoc_complete_cmd *cmd, */ if (param->auth_flag) cmd->peer_flags |= WMI_PEER_AUTH; - if (param->need_ptk_4_way) + if (param->need_ptk_4_way) { cmd->peer_flags |= WMI_PEER_NEED_PTK_4_WAY; - else - cmd->peer_flags &= ~WMI_PEER_NEED_PTK_4_WAY; + cmd->peer_flags &= ~WMI_PEER_AUTH; + } if (param->need_gtk_2_way) cmd->peer_flags |= WMI_PEER_NEED_GTK_2_WAY; /* safe mode bypass the 4-way handshake */ @@ -1778,6 +1814,7 @@ int ath11k_wmi_send_peer_assoc_cmd(struct ath11k *ar, cmd->peer_he_cap_info = param->peer_he_cap_macinfo[0]; cmd->peer_he_cap_info_ext = param->peer_he_cap_macinfo[1]; cmd->peer_he_cap_info_internal = param->peer_he_cap_macinfo_internal; + cmd->peer_he_caps_6ghz = param->peer_he_caps_6ghz; cmd->peer_he_ops = param->peer_he_ops; memcpy(&cmd->peer_he_cap_phy, ¶m->peer_he_cap_phyinfo, sizeof(param->peer_he_cap_phyinfo)); @@ -1831,6 +1868,7 @@ int ath11k_wmi_send_peer_assoc_cmd(struct ath11k *ar, /* HE Rates */ cmd->peer_he_mcs = param->peer_he_mcs_count; + cmd->min_data_rate = param->min_data_rate; ptr += sizeof(*mcs); @@ -1886,6 +1924,8 @@ void ath11k_wmi_start_scan_init(struct ath11k *ar, arg->dwell_time_active = 50; arg->dwell_time_active_2g = 0; arg->dwell_time_passive = 150; + arg->dwell_time_active_6g = 40; + arg->dwell_time_passive_6g = 30; arg->min_rest_time = 50; arg->max_rest_time = 500; arg->repeat_probe_time = 0; @@ -1990,6 +2030,8 @@ int ath11k_wmi_send_scan_start_cmd(struct ath11k *ar, int i, ret, len; u32 *tmp_ptr; u8 extraie_len_with_pad = 0; + struct hint_short_ssid *s_ssid = NULL; + struct hint_bssid *hint_bssid = NULL; len = sizeof(*cmd); @@ -2011,6 +2053,14 @@ int ath11k_wmi_send_scan_start_cmd(struct ath11k *ar, roundup(params->extraie.len, sizeof(u32)); len += extraie_len_with_pad; + if (params->num_hint_bssid) + len += TLV_HDR_SIZE + + params->num_hint_bssid * sizeof(struct hint_bssid); + + if (params->num_hint_s_ssid) + len += TLV_HDR_SIZE + + params->num_hint_s_ssid * sizeof(struct hint_short_ssid); + skb = ath11k_wmi_alloc_skb(wmi->wmi_ab, len); if (!skb) return -ENOMEM; @@ -2032,6 +2082,8 @@ int ath11k_wmi_send_scan_start_cmd(struct ath11k *ar, cmd->dwell_time_active = params->dwell_time_active; cmd->dwell_time_active_2g = params->dwell_time_active_2g; cmd->dwell_time_passive = params->dwell_time_passive; + cmd->dwell_time_active_6g = params->dwell_time_active_6g; + cmd->dwell_time_passive_6g = params->dwell_time_passive_6g; cmd->min_rest_time = params->min_rest_time; cmd->max_rest_time = params->max_rest_time; cmd->repeat_probe_time = params->repeat_probe_time; @@ -2109,6 +2161,68 @@ int ath11k_wmi_send_scan_start_cmd(struct ath11k *ar, ptr += extraie_len_with_pad; + if (params->num_hint_s_ssid) { + len = params->num_hint_s_ssid * sizeof(struct hint_short_ssid); + tlv = ptr; + tlv->header = FIELD_PREP(WMI_TLV_TAG, WMI_TAG_ARRAY_FIXED_STRUCT) | + FIELD_PREP(WMI_TLV_LEN, len); + ptr += TLV_HDR_SIZE; + s_ssid = ptr; + for (i = 0; i < params->num_hint_s_ssid; ++i) { + s_ssid->freq_flags = params->hint_s_ssid[i].freq_flags; + s_ssid->short_ssid = params->hint_s_ssid[i].short_ssid; + s_ssid++; + } + ptr += len; + } + + if (params->num_hint_bssid) { + len = params->num_hint_bssid * sizeof(struct hint_bssid); + tlv = ptr; + tlv->header = FIELD_PREP(WMI_TLV_TAG, WMI_TAG_ARRAY_FIXED_STRUCT) | + FIELD_PREP(WMI_TLV_LEN, len); + ptr += TLV_HDR_SIZE; + hint_bssid = ptr; + for (i = 0; i < params->num_hint_bssid; ++i) { + hint_bssid->freq_flags = + params->hint_bssid[i].freq_flags; + ether_addr_copy(¶ms->hint_bssid[i].bssid.addr[0], + &hint_bssid->bssid.addr[0]); + hint_bssid++; + } + } + + len = params->num_hint_s_ssid * sizeof(struct hint_short_ssid); + tlv = ptr; + tlv->header = FIELD_PREP(WMI_TLV_TAG, WMI_TAG_ARRAY_FIXED_STRUCT) | + FIELD_PREP(WMI_TLV_LEN, len); + ptr += TLV_HDR_SIZE; + if (params->num_hint_s_ssid) { + s_ssid = ptr; + for (i = 0; i < params->num_hint_s_ssid; ++i) { + s_ssid->freq_flags = params->hint_s_ssid[i].freq_flags; + s_ssid->short_ssid = params->hint_s_ssid[i].short_ssid; + s_ssid++; + } + } + ptr += len; + + len = params->num_hint_bssid * sizeof(struct hint_bssid); + tlv = ptr; + tlv->header = FIELD_PREP(WMI_TLV_TAG, WMI_TAG_ARRAY_FIXED_STRUCT) | + FIELD_PREP(WMI_TLV_LEN, len); + ptr += TLV_HDR_SIZE; + if (params->num_hint_bssid) { + hint_bssid = ptr; + for (i = 0; i < params->num_hint_bssid; ++i) { + hint_bssid->freq_flags = + params->hint_bssid[i].freq_flags; + ether_addr_copy(¶ms->hint_bssid[i].bssid.addr[0], + &hint_bssid->bssid.addr[0]); + hint_bssid++; + } + } + ret = ath11k_wmi_cmd_send(wmi, skb, WMI_START_SCAN_CMDID); if (ret) { @@ -2178,91 +2292,110 @@ int ath11k_wmi_send_scan_chan_list_cmd(struct ath11k *ar, struct wmi_tlv *tlv; void *ptr; int i, ret, len; + u16 num_send_chans, num_sends = 0, max_chan_limit = 0; u32 *reg1, *reg2; - len = sizeof(*cmd) + TLV_HDR_SIZE + - sizeof(*chan_info) * chan_list->nallchans; + tchan_info = &chan_list->ch_param[0]; + while (chan_list->nallchans) { + len = sizeof(*cmd) + TLV_HDR_SIZE; + max_chan_limit = (wmi->wmi_ab->max_msg_len[ar->pdev_idx] - len) / + sizeof(*chan_info); - skb = ath11k_wmi_alloc_skb(wmi->wmi_ab, len); - if (!skb) - return -ENOMEM; + if (chan_list->nallchans > max_chan_limit) + num_send_chans = max_chan_limit; + else + num_send_chans = chan_list->nallchans; - cmd = (struct wmi_scan_chan_list_cmd *)skb->data; - cmd->tlv_header = FIELD_PREP(WMI_TLV_TAG, WMI_TAG_SCAN_CHAN_LIST_CMD) | - FIELD_PREP(WMI_TLV_LEN, sizeof(*cmd) - TLV_HDR_SIZE); + chan_list->nallchans -= num_send_chans; + len += sizeof(*chan_info) * num_send_chans; - ath11k_dbg(ar->ab, ATH11K_DBG_WMI, - "WMI no.of chan = %d len = %d\n", chan_list->nallchans, len); - cmd->pdev_id = chan_list->pdev_id; - cmd->num_scan_chans = chan_list->nallchans; - - ptr = skb->data + sizeof(*cmd); + skb = ath11k_wmi_alloc_skb(wmi->wmi_ab, len); + if (!skb) + return -ENOMEM; - len = sizeof(*chan_info) * chan_list->nallchans; - tlv = ptr; - tlv->header = FIELD_PREP(WMI_TLV_TAG, WMI_TAG_ARRAY_STRUCT) | - FIELD_PREP(WMI_TLV_LEN, len - TLV_HDR_SIZE); - ptr += TLV_HDR_SIZE; + cmd = (struct wmi_scan_chan_list_cmd *)skb->data; + cmd->tlv_header = FIELD_PREP(WMI_TLV_TAG, WMI_TAG_SCAN_CHAN_LIST_CMD) | + FIELD_PREP(WMI_TLV_LEN, sizeof(*cmd) - TLV_HDR_SIZE); + cmd->pdev_id = chan_list->pdev_id; + cmd->num_scan_chans = num_send_chans; + if (num_sends) + cmd->flags |= WMI_APPEND_TO_EXISTING_CHAN_LIST_FLAG; - tchan_info = &chan_list->ch_param[0]; + ath11k_dbg(ar->ab, ATH11K_DBG_WMI, + "WMI no.of chan = %d len = %d pdev_id = %d num_sends = %d\n", + num_send_chans, len, cmd->pdev_id, num_sends); - for (i = 0; i < chan_list->nallchans; ++i) { - chan_info = ptr; - memset(chan_info, 0, sizeof(*chan_info)); - len = sizeof(*chan_info); - chan_info->tlv_header = FIELD_PREP(WMI_TLV_TAG, - WMI_TAG_CHANNEL) | - FIELD_PREP(WMI_TLV_LEN, - len - TLV_HDR_SIZE); - - reg1 = &chan_info->reg_info_1; - reg2 = &chan_info->reg_info_2; - chan_info->mhz = tchan_info->mhz; - chan_info->band_center_freq1 = tchan_info->cfreq1; - chan_info->band_center_freq2 = tchan_info->cfreq2; - - if (tchan_info->is_chan_passive) - chan_info->info |= WMI_CHAN_INFO_PASSIVE; - if (tchan_info->allow_he) - chan_info->info |= WMI_CHAN_INFO_ALLOW_HE; - else if (tchan_info->allow_vht) - chan_info->info |= WMI_CHAN_INFO_ALLOW_VHT; - else if (tchan_info->allow_ht) - chan_info->info |= WMI_CHAN_INFO_ALLOW_HT; - if (tchan_info->half_rate) - chan_info->info |= WMI_CHAN_INFO_HALF_RATE; - if (tchan_info->quarter_rate) - chan_info->info |= WMI_CHAN_INFO_QUARTER_RATE; - - chan_info->info |= FIELD_PREP(WMI_CHAN_INFO_MODE, - tchan_info->phy_mode); - *reg1 |= FIELD_PREP(WMI_CHAN_REG_INFO1_MIN_PWR, - tchan_info->minpower); - *reg1 |= FIELD_PREP(WMI_CHAN_REG_INFO1_MAX_PWR, - tchan_info->maxpower); - *reg1 |= FIELD_PREP(WMI_CHAN_REG_INFO1_MAX_REG_PWR, - tchan_info->maxregpower); - *reg1 |= FIELD_PREP(WMI_CHAN_REG_INFO1_REG_CLS, - tchan_info->reg_class_id); - *reg2 |= FIELD_PREP(WMI_CHAN_REG_INFO2_ANT_MAX, - tchan_info->antennamax); + ptr = skb->data + sizeof(*cmd); - ath11k_dbg(ar->ab, ATH11K_DBG_WMI, - "WMI chan scan list chan[%d] = %u\n", - i, chan_info->mhz); + len = sizeof(*chan_info) * num_send_chans; + tlv = ptr; + tlv->header = FIELD_PREP(WMI_TLV_TAG, WMI_TAG_ARRAY_STRUCT) | + FIELD_PREP(WMI_TLV_LEN, len - TLV_HDR_SIZE); + ptr += TLV_HDR_SIZE; - ptr += sizeof(*chan_info); + for (i = 0; i < num_send_chans; ++i) { + chan_info = ptr; + memset(chan_info, 0, sizeof(*chan_info)); + len = sizeof(*chan_info); + chan_info->tlv_header = FIELD_PREP(WMI_TLV_TAG, + WMI_TAG_CHANNEL) | + FIELD_PREP(WMI_TLV_LEN, + len - TLV_HDR_SIZE); + + reg1 = &chan_info->reg_info_1; + reg2 = &chan_info->reg_info_2; + chan_info->mhz = tchan_info->mhz; + chan_info->band_center_freq1 = tchan_info->cfreq1; + chan_info->band_center_freq2 = tchan_info->cfreq2; + + if (tchan_info->is_chan_passive) + chan_info->info |= WMI_CHAN_INFO_PASSIVE; + if (tchan_info->allow_he) + chan_info->info |= WMI_CHAN_INFO_ALLOW_HE; + else if (tchan_info->allow_vht) + chan_info->info |= WMI_CHAN_INFO_ALLOW_VHT; + else if (tchan_info->allow_ht) + chan_info->info |= WMI_CHAN_INFO_ALLOW_HT; + if (tchan_info->half_rate) + chan_info->info |= WMI_CHAN_INFO_HALF_RATE; + if (tchan_info->quarter_rate) + chan_info->info |= WMI_CHAN_INFO_QUARTER_RATE; + if (tchan_info->psc_channel) + chan_info->info |= WMI_CHAN_INFO_PSC; + + chan_info->info |= FIELD_PREP(WMI_CHAN_INFO_MODE, + tchan_info->phy_mode); + *reg1 |= FIELD_PREP(WMI_CHAN_REG_INFO1_MIN_PWR, + tchan_info->minpower); + *reg1 |= FIELD_PREP(WMI_CHAN_REG_INFO1_MAX_PWR, + tchan_info->maxpower); + *reg1 |= FIELD_PREP(WMI_CHAN_REG_INFO1_MAX_REG_PWR, + tchan_info->maxregpower); + *reg1 |= FIELD_PREP(WMI_CHAN_REG_INFO1_REG_CLS, + tchan_info->reg_class_id); + *reg2 |= FIELD_PREP(WMI_CHAN_REG_INFO2_ANT_MAX, + tchan_info->antennamax); + + ath11k_dbg(ar->ab, ATH11K_DBG_WMI, + "WMI chan scan list chan[%d] = %u, chan_info->info %8x\n", + i, chan_info->mhz, chan_info->info); + + ptr += sizeof(*chan_info); + + tchan_info++; + } - tchan_info++; - } + ret = ath11k_wmi_cmd_send(wmi, skb, WMI_SCAN_CHAN_LIST_CMDID); + if (ret) { + ath11k_warn(ar->ab, "failed to send WMI_SCAN_CHAN_LIST cmd\n"); + dev_kfree_skb(skb); + return ret; + } - ret = ath11k_wmi_cmd_send(wmi, skb, WMI_SCAN_CHAN_LIST_CMDID); - if (ret) { - ath11k_warn(ar->ab, "failed to send WMI_SCAN_CHAN_LIST cmd\n"); - dev_kfree_skb(skb); + num_sends++; } - return ret; + return 0; } int ath11k_wmi_send_wmm_update_cmd_tlv(struct ath11k *ar, u32 vdev_id, @@ -3265,6 +3398,236 @@ int ath11k_wmi_cmd_init(struct ath11k_base *ab) return ath11k_init_cmd_send(&wmi_sc->wmi[0], &init_param); } +int ath11k_wmi_vdev_spectral_conf(struct ath11k *ar, + struct ath11k_wmi_vdev_spectral_conf_param *param) +{ + struct ath11k_wmi_vdev_spectral_conf_cmd *cmd; + struct sk_buff *skb; + int ret; + + skb = ath11k_wmi_alloc_skb(ar->wmi->wmi_ab, sizeof(*cmd)); + if (!skb) + return -ENOMEM; + + cmd = (struct ath11k_wmi_vdev_spectral_conf_cmd *)skb->data; + cmd->tlv_header = FIELD_PREP(WMI_TLV_TAG, + WMI_TAG_VDEV_SPECTRAL_CONFIGURE_CMD) | + FIELD_PREP(WMI_TLV_LEN, sizeof(*cmd) - TLV_HDR_SIZE); + + memcpy(&cmd->param, param, sizeof(*param)); + + ret = ath11k_wmi_cmd_send(ar->wmi, skb, + WMI_VDEV_SPECTRAL_SCAN_CONFIGURE_CMDID); + if (ret) { + ath11k_warn(ar->ab, + "failed to send spectral scan config wmi cmd\n"); + goto err; + } + + ath11k_dbg(ar->ab, ATH11K_DBG_WMI, + "WMI spectral scan config cmd vdev_id 0x%x\n", + param->vdev_id); + + return 0; +err: + dev_kfree_skb(skb); + return ret; +} + +int ath11k_wmi_vdev_spectral_enable(struct ath11k *ar, u32 vdev_id, + u32 trigger, u32 enable) +{ + struct ath11k_wmi_vdev_spectral_enable_cmd *cmd; + struct sk_buff *skb; + int ret; + + skb = ath11k_wmi_alloc_skb(ar->wmi->wmi_ab, sizeof(*cmd)); + if (!skb) + return -ENOMEM; + + cmd = (struct ath11k_wmi_vdev_spectral_enable_cmd *)skb->data; + cmd->tlv_header = FIELD_PREP(WMI_TLV_TAG, + WMI_TAG_VDEV_SPECTRAL_ENABLE_CMD) | + FIELD_PREP(WMI_TLV_LEN, sizeof(*cmd) - TLV_HDR_SIZE); + + cmd->vdev_id = vdev_id; + cmd->trigger_cmd = trigger; + cmd->enable_cmd = enable; + + ret = ath11k_wmi_cmd_send(ar->wmi, skb, + WMI_VDEV_SPECTRAL_SCAN_ENABLE_CMDID); + if (ret) { + ath11k_warn(ar->ab, + "failed to send spectral enable wmi cmd\n"); + goto err; + } + + ath11k_dbg(ar->ab, ATH11K_DBG_WMI, + "WMI spectral enable cmd vdev id 0x%x\n", + vdev_id); + + return 0; +err: + dev_kfree_skb(skb); + return ret; +} + +int ath11k_wmi_pdev_dma_ring_cfg(struct ath11k *ar, + struct ath11k_wmi_pdev_dma_ring_cfg_req_cmd *param) +{ + struct ath11k_wmi_pdev_dma_ring_cfg_req_cmd *cmd; + struct sk_buff *skb; + int ret; + + skb = ath11k_wmi_alloc_skb(ar->wmi->wmi_ab, sizeof(*cmd)); + if (!skb) + return -ENOMEM; + + cmd = (struct ath11k_wmi_pdev_dma_ring_cfg_req_cmd *)skb->data; + cmd->tlv_header = FIELD_PREP(WMI_TLV_TAG, WMI_TAG_DMA_RING_CFG_REQ) | + FIELD_PREP(WMI_TLV_LEN, sizeof(*cmd) - TLV_HDR_SIZE); + + cmd->pdev_id = param->pdev_id; + cmd->module_id = param->module_id; + cmd->base_paddr_lo = param->base_paddr_lo; + cmd->base_paddr_hi = param->base_paddr_hi; + cmd->head_idx_paddr_lo = param->head_idx_paddr_lo; + cmd->head_idx_paddr_hi = param->head_idx_paddr_hi; + cmd->tail_idx_paddr_lo = param->tail_idx_paddr_lo; + cmd->tail_idx_paddr_hi = param->tail_idx_paddr_hi; + cmd->num_elems = param->num_elems; + cmd->buf_size = param->buf_size; + cmd->num_resp_per_event = param->num_resp_per_event; + cmd->event_timeout_ms = param->event_timeout_ms; + + ret = ath11k_wmi_cmd_send(ar->wmi, skb, + WMI_PDEV_DMA_RING_CFG_REQ_CMDID); + if (ret) { + ath11k_warn(ar->ab, + "failed to send dma ring cfg req wmi cmd\n"); + goto err; + } + + ath11k_dbg(ar->ab, ATH11K_DBG_WMI, + "WMI DMA ring cfg req cmd pdev_id 0x%x\n", + param->pdev_id); + + return 0; +err: + dev_kfree_skb(skb); + return ret; +} + +static int ath11k_wmi_tlv_dma_buf_entry_parse(struct ath11k_base *soc, + u16 tag, u16 len, + const void *ptr, void *data) +{ + struct wmi_tlv_dma_buf_release_parse *parse = data; + + if (tag != WMI_TAG_DMA_BUF_RELEASE_ENTRY) + return -EPROTO; + + if (parse->num_buf_entry >= parse->fixed.num_buf_release_entry) + return -ENOBUFS; + + parse->num_buf_entry++; + return 0; +} + +static int ath11k_wmi_tlv_dma_buf_meta_parse(struct ath11k_base *soc, + u16 tag, u16 len, + const void *ptr, void *data) +{ + struct wmi_tlv_dma_buf_release_parse *parse = data; + + if (tag != WMI_TAG_DMA_BUF_RELEASE_SPECTRAL_META_DATA) + return -EPROTO; + + if (parse->num_meta >= parse->fixed.num_meta_data_entry) + return -ENOBUFS; + + parse->num_meta++; + return 0; +} + +static int ath11k_wmi_tlv_dma_buf_parse(struct ath11k_base *ab, + u16 tag, u16 len, + const void *ptr, void *data) +{ + struct wmi_tlv_dma_buf_release_parse *parse = data; + int ret; + + switch (tag) { + case WMI_TAG_DMA_BUF_RELEASE: + memcpy(&parse->fixed, ptr, + sizeof(struct ath11k_wmi_dma_buf_release_fixed_param)); + parse->fixed.pdev_id = DP_HW2SW_MACID(parse->fixed.pdev_id); + break; + case WMI_TAG_ARRAY_STRUCT: + if (!parse->buf_entry_done) { + parse->num_buf_entry = 0; + parse->buf_entry = (struct wmi_dma_buf_release_entry *)ptr; + + ret = ath11k_wmi_tlv_iter(ab, ptr, len, + ath11k_wmi_tlv_dma_buf_entry_parse, + parse); + if (ret) { + ath11k_warn(ab, "failed to parse dma buf entry tlv %d\n", + ret); + return ret; + } + + parse->buf_entry_done = true; + } else if (!parse->meta_data_done) { + parse->num_meta = 0; + parse->meta_data = (struct wmi_dma_buf_release_meta_data *)ptr; + + ret = ath11k_wmi_tlv_iter(ab, ptr, len, + ath11k_wmi_tlv_dma_buf_meta_parse, + parse); + if (ret) { + ath11k_warn(ab, "failed to parse dma buf meta tlv %d\n", + ret); + return ret; + } + + parse->meta_data_done = true; + } + break; + default: + break; + } + return 0; +} + +static void ath11k_wmi_pdev_dma_ring_buf_release_event(struct ath11k_base *ab, + struct sk_buff *skb) +{ + struct wmi_tlv_dma_buf_release_parse parse = { }; + struct ath11k_dbring_buf_release_event param; + int ret; + + ret = ath11k_wmi_tlv_iter(ab, skb->data, skb->len, + ath11k_wmi_tlv_dma_buf_parse, + &parse); + if (ret) { + ath11k_warn(ab, "failed to parse dma buf release tlv %d\n", ret); + return; + } + + param.fixed = parse.fixed; + param.buf_entry = parse.buf_entry; + param.num_buf_entry = parse.num_buf_entry; + param.meta_data = parse.meta_data; + param.num_meta = parse.num_meta; + + ret = ath11k_dbring_buffer_release_event(ab, ¶m); + if (ret) { + ath11k_warn(ab, "failed to handle dma buf release event %d\n", ret); + return; + } +} + static int ath11k_wmi_tlv_hw_mode_caps_parse(struct ath11k_base *soc, u16 tag, u16 len, const void *ptr, void *data) @@ -3445,6 +3808,95 @@ static int ath11k_wmi_tlv_ext_soc_hal_reg_caps_parse(struct ath11k_base *soc, return 0; } +static int ath11k_wmi_tlv_dma_ring_caps_parse(struct ath11k_base *soc, + u16 tag, u16 len, + const void *ptr, void *data) +{ + struct wmi_tlv_dma_ring_caps_parse *parse = data; + + if (tag != WMI_TAG_DMA_RING_CAPABILITIES) + return -EPROTO; + + parse->n_dma_ring_caps++; + return 0; +} + +static int ath11k_wmi_alloc_dbring_caps(struct ath11k_base *ab, + u32 num_cap) +{ + size_t sz; + void *ptr; + + sz = num_cap * sizeof(struct ath11k_dbring_cap); + ptr = kzalloc(sz, GFP_ATOMIC); + if (!ptr) + return -ENOMEM; + + ab->db_caps = ptr; + ab->num_db_cap = num_cap; + + return 0; +} + +static void ath11k_wmi_free_dbring_caps(struct ath11k_base *ab) +{ + kfree(ab->db_caps); + ab->db_caps = NULL; +} + +static int ath11k_wmi_tlv_dma_ring_caps(struct ath11k_base *ab, + u16 len, const void *ptr, void *data) +{ + struct wmi_tlv_dma_ring_caps_parse *dma_caps_parse = data; + struct wmi_dma_ring_capabilities *dma_caps; + struct ath11k_dbring_cap *dir_buff_caps; + int ret; + u32 i; + + dma_caps_parse->n_dma_ring_caps = 0; + dma_caps = (struct wmi_dma_ring_capabilities *)ptr; + ret = ath11k_wmi_tlv_iter(ab, ptr, len, + ath11k_wmi_tlv_dma_ring_caps_parse, + dma_caps_parse); + if (ret) { + ath11k_warn(ab, "failed to parse dma ring caps tlv %d\n", ret); + return ret; + } + + if (!dma_caps_parse->n_dma_ring_caps) + return 0; + + if (ab->num_db_cap) { + ath11k_warn(ab, "Already processed, so ignoring dma ring caps\n"); + return 0; + } + + ret = ath11k_wmi_alloc_dbring_caps(ab, dma_caps_parse->n_dma_ring_caps); + if (ret) + return ret; + + dir_buff_caps = ab->db_caps; + for (i = 0; i < dma_caps_parse->n_dma_ring_caps; i++) { + if (dma_caps[i].module_id >= WMI_DIRECT_BUF_MAX) { + ath11k_warn(ab, "Invalid module id %d\n", dma_caps[i].module_id); + ret = -EINVAL; + goto free_dir_buff; + } + + dir_buff_caps[i].id = dma_caps[i].module_id; + dir_buff_caps[i].pdev_id = DP_HW2SW_MACID(dma_caps[i].pdev_id); + dir_buff_caps[i].min_elem = dma_caps[i].min_elem; + dir_buff_caps[i].min_buf_sz = dma_caps[i].min_buf_sz; + dir_buff_caps[i].min_buf_align = dma_caps[i].min_buf_align; + } + + return 0; + +free_dir_buff: + ath11k_wmi_free_dbring_caps(ab); + return ret; +} + static int ath11k_wmi_tlv_svc_rdy_ext_parse(struct ath11k_base *ab, u16 tag, u16 len, const void *ptr, void *data) @@ -3501,7 +3953,19 @@ static int ath11k_wmi_tlv_svc_rdy_ext_parse(struct ath11k_base *ab, return ret; svc_rdy_ext->ext_hal_reg_done = true; - complete(&ab->wmi_ab.service_ready); + } else if (!svc_rdy_ext->mac_phy_chainmask_combo_done) { + svc_rdy_ext->mac_phy_chainmask_combo_done = true; + } else if (!svc_rdy_ext->mac_phy_chainmask_cap_done) { + svc_rdy_ext->mac_phy_chainmask_cap_done = true; + } else if (!svc_rdy_ext->oem_dma_ring_cap_done) { + svc_rdy_ext->oem_dma_ring_cap_done = true; + } else if (!svc_rdy_ext->dma_ring_cap_done) { + ret = ath11k_wmi_tlv_dma_ring_caps(ab, len, ptr, + &svc_rdy_ext->dma_caps_parse); + if (ret) + return ret; + + svc_rdy_ext->dma_ring_cap_done = true; } break; @@ -3522,11 +3986,66 @@ static int ath11k_service_ready_ext_event(struct ath11k_base *ab, &svc_rdy_ext); if (ret) { ath11k_warn(ab, "failed to parse tlv %d\n", ret); - return ret; + goto err; } + if (!test_bit(WMI_TLV_SERVICE_EXT2_MSG, ab->wmi_ab.svc_map)) + complete(&ab->wmi_ab.service_ready); + kfree(svc_rdy_ext.mac_phy_caps); return 0; + +err: + ath11k_wmi_free_dbring_caps(ab); + return ret; +} + +static int ath11k_wmi_tlv_svc_rdy_ext2_parse(struct ath11k_base *ab, + u16 tag, u16 len, + const void *ptr, void *data) +{ + struct wmi_tlv_svc_rdy_ext2_parse *parse = data; + int ret; + + switch (tag) { + case WMI_TAG_ARRAY_STRUCT: + if (!parse->dma_ring_cap_done) { + ret = ath11k_wmi_tlv_dma_ring_caps(ab, len, ptr, + &parse->dma_caps_parse); + if (ret) + return ret; + + parse->dma_ring_cap_done = true; + } + break; + default: + break; + } + + return 0; +} + +static int ath11k_service_ready_ext2_event(struct ath11k_base *ab, + struct sk_buff *skb) +{ + struct wmi_tlv_svc_rdy_ext2_parse svc_rdy_ext2 = { }; + int ret; + + ret = ath11k_wmi_tlv_iter(ab, skb->data, skb->len, + ath11k_wmi_tlv_svc_rdy_ext2_parse, + &svc_rdy_ext2); + if (ret) { + ath11k_warn(ab, "failed to parse ext2 event tlv %d\n", ret); + goto err; + } + + complete(&ab->wmi_ab.service_ready); + + return 0; + +err: + ath11k_wmi_free_dbring_caps(ab); + return ret; } static int ath11k_pull_vdev_start_resp_tlv(struct ath11k_base *ab, struct sk_buff *skb, @@ -3822,6 +4341,7 @@ static int ath11k_pull_mgmt_rx_params_tlv(struct ath11k_base *ab, } hdr->pdev_id = ev->pdev_id; + hdr->chan_freq = ev->chan_freq; hdr->channel = ev->channel; hdr->snr = ev->snr; hdr->rate = ev->rate; @@ -5193,7 +5713,9 @@ static void ath11k_mgmt_rx_event(struct ath11k_base *ab, struct sk_buff *skb) if (rx_ev.status & WMI_RX_STATUS_ERR_MIC) status->flag |= RX_FLAG_MMIC_ERROR; - if (rx_ev.channel >= 1 && rx_ev.channel <= 14) { + if (rx_ev.chan_freq >= ATH11K_MIN_6G_FREQ) { + status->band = NL80211_BAND_6GHZ; + } else if (rx_ev.channel >= 1 && rx_ev.channel <= 14) { status->band = NL80211_BAND_2GHZ; } else if (rx_ev.channel >= 36 && rx_ev.channel <= ATH11K_MAX_5G_CHAN) { status->band = NL80211_BAND_5GHZ; @@ -5206,9 +5728,10 @@ static void ath11k_mgmt_rx_event(struct ath11k_base *ab, struct sk_buff *skb) goto exit; } - if (rx_ev.phy_mode == MODE_11B && status->band == NL80211_BAND_5GHZ) + if (rx_ev.phy_mode == MODE_11B && + (status->band == NL80211_BAND_5GHZ || status->band == NL80211_BAND_6GHZ)) ath11k_dbg(ab, ATH11K_DBG_WMI, - "wmi mgmt rx 11b (CCK) on 5GHz\n"); + "wmi mgmt rx 11b (CCK) on 5/6GHz, band = %d\n", status->band); sband = &ar->mac.sbands[status->band]; @@ -5933,6 +6456,9 @@ static void ath11k_wmi_tlv_op_rx(struct ath11k_base *ab, struct sk_buff *skb) case WMI_SERVICE_READY_EXT_EVENTID: ath11k_service_ready_ext_event(ab, skb); break; + case WMI_SERVICE_READY_EXT2_EVENTID: + ath11k_service_ready_ext2_event(ab, skb); + break; case WMI_REG_CHAN_LIST_CC_EVENTID: ath11k_reg_chan_list_event(ab, skb); break; @@ -5994,12 +6520,16 @@ static void ath11k_wmi_tlv_op_rx(struct ath11k_base *ab, struct sk_buff *skb) case WMI_PDEV_TEMPERATURE_EVENTID: ath11k_wmi_pdev_temperature_event(ab, skb); break; + case WMI_PDEV_DMA_RING_BUF_RELEASE_EVENTID: + ath11k_wmi_pdev_dma_ring_buf_release_event(ab, skb); + break; /* add Unsupported events here */ case WMI_TBTTOFFSET_EXT_UPDATE_EVENTID: case WMI_VDEV_DELETE_RESP_EVENTID: case WMI_PEER_OPER_MODE_CHANGE_EVENTID: case WMI_TWT_ENABLE_EVENTID: case WMI_TWT_DISABLE_EVENTID: + case WMI_PDEV_DMA_RING_CFG_RSP_EVENTID: ath11k_dbg(ab, ATH11K_DBG_WMI, "ignoring unsupported event 0x%x\n", id); break; @@ -6213,4 +6743,6 @@ void ath11k_wmi_detach(struct ath11k_base *ab) for (i = 0; i < ab->htc.wmi_ep_count; i++) ath11k_wmi_pdev_detach(ab, i); + + ath11k_wmi_free_dbring_caps(ab); } diff --git a/drivers/net/wireless/ath/ath11k/wmi.h b/drivers/net/wireless/ath/ath11k/wmi.h index b9f3e559ced7..5a32ba0eb4f5 100644 --- a/drivers/net/wireless/ath/ath11k/wmi.h +++ b/drivers/net/wireless/ath/ath11k/wmi.h @@ -24,6 +24,8 @@ struct ath11k_fw_stats; #define HE_PET_8_USEC 1 #define HE_PET_16_USEC 2 +#define WMI_MAX_CHAINS 8 + #define WMI_MAX_NUM_SS MAX_HE_NSS #define WMI_MAX_NUM_RU MAX_HE_RU @@ -50,10 +52,20 @@ struct wmi_tlv { #define WMI_MAX_MEM_REQS 32 #define ATH11K_MAX_HW_LISTEN_INTERVAL 5 +#define WLAN_SCAN_MAX_HINT_S_SSID 10 +#define WLAN_SCAN_MAX_HINT_BSSID 10 +#define MAX_RNR_BSS 5 + +#define WLAN_SCAN_MAX_HINT_S_SSID 10 +#define WLAN_SCAN_MAX_HINT_BSSID 10 +#define MAX_RNR_BSS 5 + #define WLAN_SCAN_PARAMS_MAX_SSID 16 #define WLAN_SCAN_PARAMS_MAX_BSSID 4 #define WLAN_SCAN_PARAMS_MAX_IE_LEN 256 +#define WMI_APPEND_TO_EXISTING_CHAN_LIST_FLAG 1 + #define WMI_BA_MODE_BUFFER_SIZE_256 3 /* * HW mode config type replicated from FW header @@ -586,6 +598,11 @@ enum wmi_tlv_event_id { WMI_PDEV_DMA_RING_CFG_RSP_EVENTID, WMI_PDEV_DMA_RING_BUF_RELEASE_EVENTID, WMI_PDEV_CTL_FAILSAFE_CHECK_EVENTID, + WMI_PDEV_CSC_SWITCH_COUNT_STATUS_EVENTID, + WMI_PDEV_COLD_BOOT_CAL_DATA_EVENTID, + WMI_PDEV_RAP_INFO_EVENTID, + WMI_CHAN_RF_CHARACTERIZATION_INFO_EVENTID, + WMI_SERVICE_READY_EXT2_EVENTID, WMI_VDEV_START_RESP_EVENTID = WMI_TLV_CMD(WMI_GRP_VDEV), WMI_VDEV_STOPPED_EVENTID, WMI_VDEV_INSTALL_KEY_COMPLETE_EVENTID, @@ -1011,6 +1028,7 @@ enum wmi_tlv_vdev_param { WMI_VDEV_PARAM_FILS_MAX_CHANNEL_GUARD_TIME, WMI_VDEV_PARAM_BA_MODE = 0x7e, WMI_VDEV_PARAM_SET_HE_SOUNDING_MODE = 0x87, + WMI_VDEV_PARAM_6GHZ_PARAMS = 0x99, WMI_VDEV_PARAM_PROTOTYPE = 0x8000, WMI_VDEV_PARAM_BSS_COLOR, WMI_VDEV_PARAM_SET_HEMU_MODE, @@ -2013,9 +2031,10 @@ enum wmi_tlv_service { WMI_TLV_SERVICE_DSM_ROAM_FILTER = 211, WMI_TLV_SERVICE_PACKET_CAPTURE_SUPPORT = 212, WMI_TLV_SERVICE_PER_PEER_HTT_STATS_RESET = 213, + WMI_TLV_SERVICE_FREQINFO_IN_METADATA = 219, + WMI_TLV_SERVICE_EXT2_MSG = 220, WMI_MAX_EXT_SERVICE - }; enum { @@ -2076,6 +2095,14 @@ enum wmi_beacon_gen_mode { WMI_BEACON_BURST_MODE = 1 }; +enum wmi_direct_buffer_module { + WMI_DIRECT_BUF_SPECTRAL = 0, + WMI_DIRECT_BUF_CFR = 1, + + /* keep it last */ + WMI_DIRECT_BUF_MAX +}; + struct wmi_host_pdev_band_to_mac { u32 pdev_id; u32 start_freq; @@ -2382,6 +2409,15 @@ struct wmi_mac_addr { } __packed; } __packed; +struct wmi_dma_ring_capabilities { + u32 tlv_header; + u32 pdev_id; + u32 module_id; + u32 min_elem; + u32 min_buf_sz; + u32 min_buf_align; +} __packed; + struct wmi_ready_event_min { struct wmi_abi_version fw_abi_vers; struct wmi_mac_addr mac_addr; @@ -2519,7 +2555,8 @@ struct channel_param { allow_ht:1, allow_vht:1, allow_he:1, - set_agile:1; + set_agile:1, + psc_channel:1; u32 phy_mode; u32 cfreq1; u32 cfreq2; @@ -3059,6 +3096,9 @@ struct wmi_start_scan_cmd { u32 num_vendor_oui; u32 scan_ctrl_flags_ext; u32 dwell_time_active_2g; + u32 dwell_time_active_6g; + u32 dwell_time_passive_6g; + u32 scan_start_offset; } __packed; #define WMI_SCAN_FLAG_PASSIVE 0x1 @@ -3098,6 +3138,16 @@ enum { ((flag) |= (((mode) << WMI_SCAN_DWELL_MODE_SHIFT) & \ WMI_SCAN_DWELL_MODE_MASK)) +struct hint_short_ssid { + u32 freq_flags; + u32 short_ssid; +}; + +struct hint_bssid { + u32 freq_flags; + struct wmi_mac_addr bssid; +}; + struct scan_req_params { u32 scan_id; u32 scan_req_id; @@ -3125,6 +3175,8 @@ struct scan_req_params { u32 dwell_time_active; u32 dwell_time_active_2g; u32 dwell_time_passive; + u32 dwell_time_active_6g; + u32 dwell_time_passive_6g; u32 min_rest_time; u32 max_rest_time; u32 repeat_probe_time; @@ -3175,6 +3227,10 @@ struct scan_req_params { struct element_info extraie; struct element_info htcap; struct element_info vhtcap; + u32 num_hint_s_ssid; + u32 num_hint_bssid; + struct hint_short_ssid hint_s_ssid[WLAN_SCAN_MAX_HINT_S_SSID]; + struct hint_bssid hint_bssid[WLAN_SCAN_MAX_HINT_BSSID]; }; struct wmi_ssid_arg { @@ -3264,6 +3320,7 @@ struct wmi_bcn_send_from_host_cmd { #define WMI_CHAN_INFO_QUARTER_RATE BIT(15) #define WMI_CHAN_INFO_DFS_FREQ2 BIT(16) #define WMI_CHAN_INFO_ALLOW_HE BIT(17) +#define WMI_CHAN_INFO_PSC BIT(18) #define WMI_CHAN_REG_INFO1_MIN_PWR GENMASK(7, 0) #define WMI_CHAN_REG_INFO1_MAX_PWR GENMASK(15, 8) @@ -3444,6 +3501,7 @@ struct peer_assoc_params { u32 tx_max_rate; u32 tx_mcs_set; u8 vht_capable; + u8 min_data_rate; u32 tx_max_mcs_nss; u32 peer_bw_rxnss_override; bool is_pmf_enabled; @@ -3472,6 +3530,7 @@ struct peer_assoc_params { bool he_flag; u32 peer_he_cap_macinfo[2]; u32 peer_he_cap_macinfo_internal; + u32 peer_he_caps_6ghz; u32 peer_he_ops; u32 peer_he_cap_phyinfo[WMI_HOST_MAX_HECAP_PHY_SIZE]; u32 peer_he_mcs_count; @@ -3509,6 +3568,8 @@ struct wmi_peer_assoc_complete_cmd { u32 peer_he_mcs; u32 peer_he_cap_info_ext; u32 peer_he_cap_info_internal; + u32 min_data_rate; + u32 peer_he_caps_6ghz; } __packed; struct wmi_stop_scan_cmd { @@ -4228,6 +4289,7 @@ struct wmi_pdev_temperature_event { #define WLAN_MGMT_TXRX_HOST_MAX_ANTENNA 4 struct mgmt_rx_event_params { + u32 chan_freq; u32 channel; u32 snr; u8 rssi_ctl[WLAN_MGMT_TXRX_HOST_MAX_ANTENNA]; @@ -4257,6 +4319,7 @@ struct wmi_mgmt_rx_hdr { u32 rx_tsf_l32; u32 rx_tsf_u32; u32 pdev_id; + u32 chan_freq; } __packed; #define MAX_ANTENNA_EIGHT 8 @@ -4734,6 +4797,117 @@ struct ath11k_wmi_pdev_lro_config_cmd { u32 pdev_id; } __packed; +#define ATH11K_WMI_SPECTRAL_COUNT_DEFAULT 0 +#define ATH11K_WMI_SPECTRAL_PERIOD_DEFAULT 224 +#define ATH11K_WMI_SPECTRAL_PRIORITY_DEFAULT 1 +#define ATH11K_WMI_SPECTRAL_FFT_SIZE_DEFAULT 7 +#define ATH11K_WMI_SPECTRAL_GC_ENA_DEFAULT 1 +#define ATH11K_WMI_SPECTRAL_RESTART_ENA_DEFAULT 0 +#define ATH11K_WMI_SPECTRAL_NOISE_FLOOR_REF_DEFAULT -96 +#define ATH11K_WMI_SPECTRAL_INIT_DELAY_DEFAULT 80 +#define ATH11K_WMI_SPECTRAL_NB_TONE_THR_DEFAULT 12 +#define ATH11K_WMI_SPECTRAL_STR_BIN_THR_DEFAULT 8 +#define ATH11K_WMI_SPECTRAL_WB_RPT_MODE_DEFAULT 0 +#define ATH11K_WMI_SPECTRAL_RSSI_RPT_MODE_DEFAULT 0 +#define ATH11K_WMI_SPECTRAL_RSSI_THR_DEFAULT 0xf0 +#define ATH11K_WMI_SPECTRAL_PWR_FORMAT_DEFAULT 0 +#define ATH11K_WMI_SPECTRAL_RPT_MODE_DEFAULT 2 +#define ATH11K_WMI_SPECTRAL_BIN_SCALE_DEFAULT 1 +#define ATH11K_WMI_SPECTRAL_DBM_ADJ_DEFAULT 1 +#define ATH11K_WMI_SPECTRAL_CHN_MASK_DEFAULT 1 + +struct ath11k_wmi_vdev_spectral_conf_param { + u32 vdev_id; + u32 scan_count; + u32 scan_period; + u32 scan_priority; + u32 scan_fft_size; + u32 scan_gc_ena; + u32 scan_restart_ena; + u32 scan_noise_floor_ref; + u32 scan_init_delay; + u32 scan_nb_tone_thr; + u32 scan_str_bin_thr; + u32 scan_wb_rpt_mode; + u32 scan_rssi_rpt_mode; + u32 scan_rssi_thr; + u32 scan_pwr_format; + u32 scan_rpt_mode; + u32 scan_bin_scale; + u32 scan_dbm_adj; + u32 scan_chn_mask; +} __packed; + +struct ath11k_wmi_vdev_spectral_conf_cmd { + u32 tlv_header; + struct ath11k_wmi_vdev_spectral_conf_param param; +} __packed; + +#define ATH11K_WMI_SPECTRAL_TRIGGER_CMD_TRIGGER 1 +#define ATH11K_WMI_SPECTRAL_TRIGGER_CMD_CLEAR 2 +#define ATH11K_WMI_SPECTRAL_ENABLE_CMD_ENABLE 1 +#define ATH11K_WMI_SPECTRAL_ENABLE_CMD_DISABLE 2 + +struct ath11k_wmi_vdev_spectral_enable_cmd { + u32 tlv_header; + u32 vdev_id; + u32 trigger_cmd; + u32 enable_cmd; +} __packed; + +struct ath11k_wmi_pdev_dma_ring_cfg_req_cmd { + u32 tlv_header; + u32 pdev_id; + u32 module_id; /* see enum wmi_direct_buffer_module */ + u32 base_paddr_lo; + u32 base_paddr_hi; + u32 head_idx_paddr_lo; + u32 head_idx_paddr_hi; + u32 tail_idx_paddr_lo; + u32 tail_idx_paddr_hi; + u32 num_elems; /* Number of elems in the ring */ + u32 buf_size; /* size of allocated buffer in bytes */ + + /* Number of wmi_dma_buf_release_entry packed together */ + u32 num_resp_per_event; + + /* Target should timeout and send whatever resp + * it has if this time expires, units in milliseconds + */ + u32 event_timeout_ms; +} __packed; + +struct ath11k_wmi_dma_buf_release_fixed_param { + u32 pdev_id; + u32 module_id; + u32 num_buf_release_entry; + u32 num_meta_data_entry; +} __packed; + +struct wmi_dma_buf_release_entry { + u32 tlv_header; + u32 paddr_lo; + + /* Bits 11:0: address of data + * Bits 31:12: host context data + */ + u32 paddr_hi; +} __packed; + +#define WMI_SPECTRAL_META_INFO1_FREQ1 GENMASK(15, 0) +#define WMI_SPECTRAL_META_INFO1_FREQ2 GENMASK(31, 16) + +#define WMI_SPECTRAL_META_INFO2_CHN_WIDTH GENMASK(7, 0) + +struct wmi_dma_buf_release_meta_data { + u32 tlv_header; + s32 noise_floor[WMI_MAX_CHAINS]; + u32 reset_delay; + u32 freq1; + u32 freq2; + u32 ch_width; +} __packed; + struct target_resource_config { u32 num_vdevs; u32 num_peers; @@ -4941,4 +5115,10 @@ int ath11k_wmi_send_obss_color_collision_cfg_cmd(struct ath11k *ar, u32 vdev_id, int ath11k_wmi_send_bss_color_change_enable_cmd(struct ath11k *ar, u32 vdev_id, bool enable); int ath11k_wmi_pdev_lro_cfg(struct ath11k *ar, int pdev_id); +int ath11k_wmi_pdev_dma_ring_cfg(struct ath11k *ar, + struct ath11k_wmi_pdev_dma_ring_cfg_req_cmd *param); +int ath11k_wmi_vdev_spectral_enable(struct ath11k *ar, u32 vdev_id, + u32 trigger, u32 enable); +int ath11k_wmi_vdev_spectral_conf(struct ath11k *ar, + struct ath11k_wmi_vdev_spectral_conf_param *param); #endif diff --git a/drivers/net/wireless/ath/ath6kl/usb.c b/drivers/net/wireless/ath/ath6kl/usb.c index 53b66e9434c9..5372e948e761 100644 --- a/drivers/net/wireless/ath/ath6kl/usb.c +++ b/drivers/net/wireless/ath/ath6kl/usb.c @@ -311,7 +311,7 @@ static int ath6kl_usb_setup_pipe_resources(struct ath6kl_usb *ar_usb) ath6kl_dbg(ATH6KL_DBG_USB, "setting up USB Pipes using interface\n"); - /* walk decriptors and setup pipes */ + /* walk descriptors and setup pipes */ for (i = 0; i < iface_desc->desc.bNumEndpoints; ++i) { endpoint = &iface_desc->endpoint[i].desc; diff --git a/drivers/net/wireless/ath/ath9k/Kconfig b/drivers/net/wireless/ath/ath9k/Kconfig index 42bfdb4a6214..d5e9af2dddd8 100644 --- a/drivers/net/wireless/ath/ath9k/Kconfig +++ b/drivers/net/wireless/ath/ath9k/Kconfig @@ -34,7 +34,7 @@ config ATH9K APs that come with these cards refer to ath9k wiki products page: - http://wireless.kernel.org/en/users/Drivers/ath9k/products + https://wireless.wiki.kernel.org/en/users/Drivers/ath9k/products If you choose to build a module, it'll be called ath9k. @@ -185,7 +185,8 @@ config ATH9K_HTC Support for Atheros HTC based cards. Chipsets supported: AR9271 - For more information: http://wireless.kernel.org/en/users/Drivers/ath9k_htc + For more information: + https://wireless.wiki.kernel.org/en/users/Drivers/ath9k_htc The built module will be ath9k_htc. diff --git a/drivers/net/wireless/ath/ath9k/hw.c b/drivers/net/wireless/ath/ath9k/hw.c index 052deffb4c9d..8c97db73e34c 100644 --- a/drivers/net/wireless/ath/ath9k/hw.c +++ b/drivers/net/wireless/ath/ath9k/hw.c @@ -2410,7 +2410,7 @@ static u8 fixup_chainmask(u8 chip_chainmask, u8 eeprom_chainmask) * of tests. The testing requirements are going to be documented. Desired * test requirements are documented at: * - * http://wireless.kernel.org/en/users/Drivers/ath9k/dfs + * https://wireless.wiki.kernel.org/en/users/Drivers/ath9k/dfs * * Once a new chipset gets properly tested an individual commit can be used * to document the testing for DFS for that chipset. diff --git a/drivers/net/wireless/ath/carl9170/Kconfig b/drivers/net/wireless/ath/carl9170/Kconfig index b1bce7aad399..b2d760873992 100644 --- a/drivers/net/wireless/ath/carl9170/Kconfig +++ b/drivers/net/wireless/ath/carl9170/Kconfig @@ -10,7 +10,7 @@ config CARL9170 It needs a special firmware (carl9170-1.fw), which can be downloaded from our wiki here: - <http://wireless.kernel.org/en/users/Drivers/carl9170> + <https://wireless.wiki.kernel.org/en/users/Drivers/carl9170> If you choose to build a module, it'll be called carl9170. diff --git a/drivers/net/wireless/ath/carl9170/usb.c b/drivers/net/wireless/ath/carl9170/usb.c index 486957a04bd1..ead79335823a 100644 --- a/drivers/net/wireless/ath/carl9170/usb.c +++ b/drivers/net/wireless/ath/carl9170/usb.c @@ -61,7 +61,7 @@ MODULE_ALIAS("arusb_lnx"); * Note: * * Always update our wiki's device list (located at: - * http://wireless.kernel.org/en/users/Drivers/ar9170/devices ), + * https://wireless.wiki.kernel.org/en/users/Drivers/ar9170/devices ), * whenever you add a new device. */ static const struct usb_device_id carl9170_usb_ids[] = { diff --git a/drivers/net/wireless/ath/spectral_common.h b/drivers/net/wireless/ath/spectral_common.h index 0d742acb1599..9c2e5458e425 100644 --- a/drivers/net/wireless/ath/spectral_common.h +++ b/drivers/net/wireless/ath/spectral_common.h @@ -24,6 +24,7 @@ * could be acquired so far. */ #define SPECTRAL_ATH10K_MAX_NUM_BINS 256 +#define SPECTRAL_ATH11K_MAX_NUM_BINS 512 /* FFT sample format given to userspace via debugfs. * @@ -37,6 +38,7 @@ enum ath_fft_sample_type { ATH_FFT_SAMPLE_HT20 = 1, ATH_FFT_SAMPLE_HT20_40, ATH_FFT_SAMPLE_ATH10K, + ATH_FFT_SAMPLE_ATH11K }; struct fft_sample_tlv { @@ -110,4 +112,19 @@ struct fft_sample_ath10k { u8 data[0]; } __packed; +struct fft_sample_ath11k { + struct fft_sample_tlv tlv; + u8 chan_width_mhz; + s8 max_index; + u8 max_exp; + __be16 freq1; + __be16 freq2; + __be16 max_magnitude; + __be16 rssi; + __be32 tsf; + __be32 noise; + + u8 data[0]; +} __packed; + #endif /* SPECTRAL_COMMON_H */ diff --git a/drivers/net/wireless/ath/wil6210/Kconfig b/drivers/net/wireless/ath/wil6210/Kconfig index dadba2d41bbb..6a95b199bf62 100644 --- a/drivers/net/wireless/ath/wil6210/Kconfig +++ b/drivers/net/wireless/ath/wil6210/Kconfig @@ -10,7 +10,7 @@ config WIL6210 wil6210 chip by Wilocity. It supports operation on the 60 GHz band, covered by the IEEE802.11ad standard. - http://wireless.kernel.org/en/users/Drivers/wil6210 + https://wireless.wiki.kernel.org/en/users/Drivers/wil6210 If you choose to build it as a module, it will be called wil6210 diff --git a/drivers/net/wireless/atmel/at76c50x-usb.c b/drivers/net/wireless/atmel/at76c50x-usb.c index 3b2680772f03..a63b5c2f1e17 100644 --- a/drivers/net/wireless/atmel/at76c50x-usb.c +++ b/drivers/net/wireless/atmel/at76c50x-usb.c @@ -17,7 +17,7 @@ * * TODO list is at the wiki: * - * http://wireless.kernel.org/en/users/Drivers/at76c50x-usb#TODO + * https://wireless.wiki.kernel.org/en/users/Drivers/at76c50x-usb#TODO */ #include <linux/init.h> diff --git a/drivers/net/wireless/broadcom/b43/main.c b/drivers/net/wireless/broadcom/b43/main.c index 3ad94dad2d89..0c2ea12fca19 100644 --- a/drivers/net/wireless/broadcom/b43/main.c +++ b/drivers/net/wireless/broadcom/b43/main.c @@ -2164,7 +2164,7 @@ static void b43_print_fw_helptext(struct b43_wl *wl, bool error) { const char text[] = "You must go to " \ - "http://wireless.kernel.org/en/users/Drivers/b43#devicefirmware " \ + "https://wireless.wiki.kernel.org/en/users/Drivers/b43#devicefirmware " \ "and download the correct firmware for this driver version. " \ "Please carefully read all instructions on this website.\n"; diff --git a/drivers/net/wireless/broadcom/b43/phy_n.c b/drivers/net/wireless/broadcom/b43/phy_n.c index c33b4235839d..46db91846007 100644 --- a/drivers/net/wireless/broadcom/b43/phy_n.c +++ b/drivers/net/wireless/broadcom/b43/phy_n.c @@ -4222,7 +4222,7 @@ static void b43_nphy_tx_gain_table_upload(struct b43_wldev *dev) u32 rfpwr_offset; u8 pga_gain, pad_gain; int i; - const s16 *uninitialized_var(rf_pwr_offset_table); + const s16 *rf_pwr_offset_table = NULL; table = b43_nphy_get_tx_gain_table(dev); if (!table) diff --git a/drivers/net/wireless/broadcom/b43legacy/main.c b/drivers/net/wireless/broadcom/b43legacy/main.c index 5208a39fd6f7..7bb6681fa882 100644 --- a/drivers/net/wireless/broadcom/b43legacy/main.c +++ b/drivers/net/wireless/broadcom/b43legacy/main.c @@ -1477,8 +1477,8 @@ static void b43legacy_release_firmware(struct b43legacy_wldev *dev) static void b43legacy_print_fw_helptext(struct b43legacy_wl *wl) { - b43legacyerr(wl, "You must go to http://wireless.kernel.org/en/users/" - "Drivers/b43#devicefirmware " + b43legacyerr(wl, "You must go to https://wireless.wiki.kernel.org/en/" + "users/Drivers/b43#devicefirmware " "and download the correct firmware (version 3).\n"); } diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/bcmsdh.c b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/bcmsdh.c index 46346cb3bc84..1a7ab49295aa 100644 --- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/bcmsdh.c +++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/bcmsdh.c @@ -863,7 +863,7 @@ static void brcmf_sdiod_freezer_detach(struct brcmf_sdio_dev *sdiodev) } #endif /* CONFIG_PM_SLEEP */ -static int brcmf_sdiod_remove(struct brcmf_sdio_dev *sdiodev) +int brcmf_sdiod_remove(struct brcmf_sdio_dev *sdiodev) { sdiodev->state = BRCMF_SDIOD_DOWN; if (sdiodev->bus) { @@ -898,7 +898,7 @@ static void brcmf_sdiod_host_fixup(struct mmc_host *host) host->caps |= MMC_CAP_NONREMOVABLE; } -static int brcmf_sdiod_probe(struct brcmf_sdio_dev *sdiodev) +int brcmf_sdiod_probe(struct brcmf_sdio_dev *sdiodev) { int ret = 0; unsigned int f2_blksz = SDIO_FUNC2_BLOCKSIZE; diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c index a757abd7a599..5d99771c3f64 100644 --- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c +++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c @@ -1387,7 +1387,8 @@ static int brcmf_set_sae_password(struct brcmf_if *ifp, const u8 *pwd_data, return err; } -static void brcmf_link_down(struct brcmf_cfg80211_vif *vif, u16 reason) +static void brcmf_link_down(struct brcmf_cfg80211_vif *vif, u16 reason, + bool locally_generated) { struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(vif->wdev.wiphy); struct brcmf_pub *drvr = cfg->pub; @@ -1409,7 +1410,7 @@ static void brcmf_link_down(struct brcmf_cfg80211_vif *vif, u16 reason) if ((vif->wdev.iftype == NL80211_IFTYPE_STATION) || (vif->wdev.iftype == NL80211_IFTYPE_P2P_CLIENT)) cfg80211_disconnected(vif->wdev.netdev, reason, NULL, 0, - true, GFP_KERNEL); + locally_generated, GFP_KERNEL); } clear_bit(BRCMF_VIF_STATUS_CONNECTING, &vif->sme_state); clear_bit(BRCMF_SCAN_STATUS_SUPPRESS, &cfg->scan_status); @@ -1588,7 +1589,7 @@ brcmf_cfg80211_leave_ibss(struct wiphy *wiphy, struct net_device *ndev) return 0; } - brcmf_link_down(ifp->vif, WLAN_REASON_DEAUTH_LEAVING); + brcmf_link_down(ifp->vif, WLAN_REASON_DEAUTH_LEAVING, true); brcmf_net_setcarrier(ifp, false); brcmf_dbg(TRACE, "Exit\n"); @@ -3907,7 +3908,7 @@ static s32 brcmf_cfg80211_suspend(struct wiphy *wiphy, * disassociate from AP to save power while system is * in suspended state */ - brcmf_link_down(vif, WLAN_REASON_UNSPECIFIED); + brcmf_link_down(vif, WLAN_REASON_UNSPECIFIED, true); /* Make sure WPA_Supplicant receives all the event * generated due to DISASSOC call to the fw to keep * the state fw and WPA_Supplicant state consistent @@ -4835,12 +4836,14 @@ brcmf_cfg80211_start_ap(struct wiphy *wiphy, struct net_device *ndev, goto exit; } - if (settings->hidden_ssid) { - err = brcmf_fil_iovar_int_set(ifp, "closednet", 1); - if (err) { - bphy_err(drvr, "closednet error (%d)\n", err); - goto exit; - } + err = brcmf_fil_iovar_int_set(ifp, "closednet", + settings->hidden_ssid); + if (err) { + bphy_err(drvr, "%s closednet error (%d)\n", + settings->hidden_ssid ? + "enabled" : "disabled", + err); + goto exit; } brcmf_dbg(TRACE, "AP mode configuration complete\n"); @@ -5129,7 +5132,7 @@ brcmf_cfg80211_mgmt_tx(struct wiphy *wiphy, struct wireless_dev *wdev, &freq); chan_nr = ieee80211_frequency_to_channel(freq); af_params->channel = cpu_to_le32(chan_nr); - + af_params->dwell_time = cpu_to_le32(params->wait); memcpy(action_frame->data, &buf[DOT11_MGMT_HDR_LEN], le16_to_cpu(action_frame->len)); @@ -6024,10 +6027,19 @@ brcmf_notify_connect_status(struct brcmf_if *ifp, brcmf_net_setcarrier(ifp, true); } else if (brcmf_is_linkdown(e)) { brcmf_dbg(CONN, "Linkdown\n"); - if (!brcmf_is_ibssmode(ifp->vif)) { + if (!brcmf_is_ibssmode(ifp->vif) && + test_bit(BRCMF_VIF_STATUS_CONNECTED, + &ifp->vif->sme_state)) { + if (memcmp(profile->bssid, e->addr, ETH_ALEN)) + return err; + brcmf_bss_connect_done(cfg, ndev, e, false); brcmf_link_down(ifp->vif, - brcmf_map_fw_linkdown_reason(e)); + brcmf_map_fw_linkdown_reason(e), + e->event_code & + (BRCMF_E_DEAUTH_IND | + BRCMF_E_DISASSOC_IND) + ? false : true); brcmf_init_prof(ndev_to_prof(ndev)); if (ndev != cfg_to_ndev(cfg)) complete(&cfg->vif_disabled); @@ -6801,7 +6813,7 @@ brcmf_txrx_stypes[NUM_NL80211_IFTYPES] = { * #AP <= 4, matching BI, channels = 1, 4 total * * no p2p and rsdb: - * #STA <= 2, #AP <= 2, channels = 2, 4 total + * #STA <= 1, #AP <= 2, channels = 2, 4 total * * p2p, no mchan, and mbss: * @@ -6816,7 +6828,7 @@ brcmf_txrx_stypes[NUM_NL80211_IFTYPES] = { * #AP <= 4, matching BI, channels = 1, 4 total * * p2p, rsdb, and no mbss: - * #STA <= 2, #P2P-DEV <= 1, #{P2P-CL, P2P-GO} <= 2, AP <= 2, + * #STA <= 1, #P2P-DEV <= 1, #{P2P-CL, P2P-GO} <= 2, AP <= 2, * channels = 2, 4 total */ static int brcmf_setup_ifmodes(struct wiphy *wiphy, struct brcmf_if *ifp) @@ -6857,7 +6869,7 @@ static int brcmf_setup_ifmodes(struct wiphy *wiphy, struct brcmf_if *ifp) goto err; combo[c].num_different_channels = 1 + (rsdb || (p2p && mchan)); - c0_limits[i].max = 1 + rsdb; + c0_limits[i].max = 1; c0_limits[i++].types = BIT(NL80211_IFTYPE_STATION); if (mon_flag) { c0_limits[i].max = 1; @@ -6873,7 +6885,7 @@ static int brcmf_setup_ifmodes(struct wiphy *wiphy, struct brcmf_if *ifp) if (p2p && rsdb) { c0_limits[i].max = 2; c0_limits[i++].types = BIT(NL80211_IFTYPE_AP); - combo[c].max_interfaces = 5; + combo[c].max_interfaces = 4; } else if (p2p) { combo[c].max_interfaces = i; } else if (rsdb) { @@ -7180,7 +7192,7 @@ static s32 __brcmf_cfg80211_down(struct brcmf_if *ifp) * from AP to save power */ if (check_vif_up(ifp->vif)) { - brcmf_link_down(ifp->vif, WLAN_REASON_UNSPECIFIED); + brcmf_link_down(ifp->vif, WLAN_REASON_UNSPECIFIED, true); /* Make sure WPA_Supplicant receives all the event generated due to DISASSOC call to the fw to keep diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/common.c b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/common.c index dec25e415619..e3758bd86acf 100644 --- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/common.c +++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/common.c @@ -209,8 +209,8 @@ int brcmf_c_preinit_dcmds(struct brcmf_if *ifp) bphy_err(drvr, "Retrieving cur_etheraddr failed, %d\n", err); goto done; } - memcpy(ifp->drvr->wiphy->perm_addr, ifp->drvr->mac, ETH_ALEN); memcpy(ifp->drvr->mac, ifp->mac_addr, sizeof(ifp->drvr->mac)); + memcpy(ifp->drvr->wiphy->perm_addr, ifp->drvr->mac, ETH_ALEN); bus = ifp->drvr->bus_if; ri = &ifp->drvr->revinfo; diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/core.c b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/core.c index c88655acc78c..f89010a81ffb 100644 --- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/core.c +++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/core.c @@ -352,6 +352,9 @@ static netdev_tx_t brcmf_netdev_start_xmit(struct sk_buff *skb, if ((skb->priority == 0) || (skb->priority > 7)) skb->priority = cfg80211_classify8021d(skb, NULL); + /* set pacing shift for packet aggregation */ + sk_pacing_shift_update(skb->sk, 8); + ret = brcmf_proto_tx_queue_data(drvr, ifp->ifidx, skb); if (ret < 0) brcmf_txfinalize(ifp, skb, false); diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/fwil_types.h b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/fwil_types.h index de0ef1b545c4..2e31cc10c195 100644 --- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/fwil_types.h +++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/fwil_types.h @@ -19,7 +19,7 @@ #define BRCMF_ARP_OL_PEER_AUTO_REPLY 0x00000008 #define BRCMF_BSS_INFO_VERSION 109 /* curr ver of brcmf_bss_info_le struct */ -#define BRCMF_BSS_RSSI_ON_CHANNEL 0x0002 +#define BRCMF_BSS_RSSI_ON_CHANNEL 0x0004 #define BRCMF_STA_BRCM 0x00000001 /* Running a Broadcom driver */ #define BRCMF_STA_WME 0x00000002 /* WMM association */ diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/fwsignal.c b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/fwsignal.c index 09701262330d..2df6811c066e 100644 --- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/fwsignal.c +++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/fwsignal.c @@ -323,6 +323,10 @@ struct brcmf_skbuff_cb { * firmware suppress the packet as device is already in PS mode. * @BRCMF_FWS_TXSTATUS_FW_TOSSED: * firmware tossed the packet. + * @BRCMF_FWS_TXSTATUS_FW_DISCARD_NOACK: + * firmware tossed the packet after retries. + * @BRCMF_FWS_TXSTATUS_FW_SUPPRESS_ACKED: + * firmware wrongly reported suppressed previously, now fixing to acked. * @BRCMF_FWS_TXSTATUS_HOST_TOSSED: * host tossed the packet. */ @@ -331,6 +335,8 @@ enum brcmf_fws_txstatus { BRCMF_FWS_TXSTATUS_CORE_SUPPRESS, BRCMF_FWS_TXSTATUS_FW_PS_SUPPRESS, BRCMF_FWS_TXSTATUS_FW_TOSSED, + BRCMF_FWS_TXSTATUS_FW_DISCARD_NOACK, + BRCMF_FWS_TXSTATUS_FW_SUPPRESS_ACKED, BRCMF_FWS_TXSTATUS_HOST_TOSSED }; @@ -383,6 +389,7 @@ struct brcmf_fws_mac_descriptor { }; #define BRCMF_FWS_HANGER_MAXITEMS 3072 +#define BRCMF_BORROW_RATIO 3 /** * enum brcmf_fws_hanger_item_state - state of hanger item. @@ -479,7 +486,8 @@ struct brcmf_fws_info { u32 fifo_enqpkt[BRCMF_FWS_FIFO_COUNT]; int fifo_credit[BRCMF_FWS_FIFO_COUNT]; int init_fifo_credit[BRCMF_FWS_FIFO_COUNT]; - int credits_borrowed[BRCMF_FWS_FIFO_AC_VO + 1]; + int credits_borrowed[BRCMF_FWS_FIFO_AC_VO + 1] + [BRCMF_FWS_FIFO_AC_VO + 1]; int deq_node_pos[BRCMF_FWS_FIFO_COUNT]; u32 fifo_credit_map; u32 fifo_delay_map; @@ -621,6 +629,7 @@ static inline int brcmf_fws_hanger_poppkt(struct brcmf_fws_hanger *h, static void brcmf_fws_psq_flush(struct brcmf_fws_info *fws, struct pktq *q, int ifidx) { + struct brcmf_fws_hanger_item *hi; bool (*matchfn)(struct sk_buff *, void *) = NULL; struct sk_buff *skb; int prec; @@ -632,6 +641,9 @@ static void brcmf_fws_psq_flush(struct brcmf_fws_info *fws, struct pktq *q, skb = brcmu_pktq_pdeq_match(q, prec, matchfn, &ifidx); while (skb) { hslot = brcmf_skb_htod_tag_get_field(skb, HSLOT); + hi = &fws->hanger.items[hslot]; + WARN_ON(skb != hi->pkt); + hi->state = BRCMF_FWS_HANGER_ITEM_STATE_FREE; brcmf_fws_hanger_poppkt(&fws->hanger, hslot, &skb, true); brcmu_pkt_buf_free_skb(skb); @@ -1187,11 +1199,11 @@ static void brcmf_fws_return_credits(struct brcmf_fws_info *fws, fws->fifo_credit_map |= 1 << fifo; - if ((fifo == BRCMF_FWS_FIFO_AC_BE) && - (fws->credits_borrowed[0])) { + if (fifo > BRCMF_FWS_FIFO_AC_BK && + fifo <= BRCMF_FWS_FIFO_AC_VO) { for (lender_ac = BRCMF_FWS_FIFO_AC_VO; lender_ac >= 0; lender_ac--) { - borrowed = &fws->credits_borrowed[lender_ac]; + borrowed = &fws->credits_borrowed[fifo][lender_ac]; if (*borrowed) { fws->fifo_credit_map |= (1 << lender_ac); fifo_credit = &fws->fifo_credit[lender_ac]; @@ -1208,7 +1220,10 @@ static void brcmf_fws_return_credits(struct brcmf_fws_info *fws, } } - fws->fifo_credit[fifo] += credits; + if (credits) { + fws->fifo_credit[fifo] += credits; + } + if (fws->fifo_credit[fifo] > fws->init_fifo_credit[fifo]) fws->fifo_credit[fifo] = fws->init_fifo_credit[fifo]; @@ -1451,6 +1466,10 @@ brcmf_fws_txs_process(struct brcmf_fws_info *fws, u8 flags, u32 hslot, remove_from_hanger = false; } else if (flags == BRCMF_FWS_TXSTATUS_FW_TOSSED) fws->stats.txs_tossed += compcnt; + else if (flags == BRCMF_FWS_TXSTATUS_FW_DISCARD_NOACK) + fws->stats.txs_discard += compcnt; + else if (flags == BRCMF_FWS_TXSTATUS_FW_SUPPRESS_ACKED) + fws->stats.txs_discard += compcnt; else if (flags == BRCMF_FWS_TXSTATUS_HOST_TOSSED) fws->stats.txs_host_tossed += compcnt; else @@ -1843,6 +1862,9 @@ void brcmf_fws_hdrpull(struct brcmf_if *ifp, s16 siglen, struct sk_buff *skb) WARN_ON(siglen > skb->len); + if (siglen > skb->len) + siglen = skb->len; + if (!siglen) return; /* if flow control disabled, skip to packet data and leave */ @@ -2005,27 +2027,31 @@ static void brcmf_fws_rollback_toq(struct brcmf_fws_info *fws, } } -static int brcmf_fws_borrow_credit(struct brcmf_fws_info *fws) +static int brcmf_fws_borrow_credit(struct brcmf_fws_info *fws, + int highest_lender_ac, int borrower_ac, + bool borrow_all) { - int lender_ac; + int lender_ac, borrow_limit = 0; - if (time_after(fws->borrow_defer_timestamp, jiffies)) { - fws->fifo_credit_map &= ~(1 << BRCMF_FWS_FIFO_AC_BE); - return -ENAVAIL; - } + for (lender_ac = 0; lender_ac <= highest_lender_ac; lender_ac++) { - for (lender_ac = 0; lender_ac <= BRCMF_FWS_FIFO_AC_VO; lender_ac++) { - if (fws->fifo_credit[lender_ac] > 0) { - fws->credits_borrowed[lender_ac]++; + if (!borrow_all) + borrow_limit = + fws->init_fifo_credit[lender_ac] / BRCMF_BORROW_RATIO; + else + borrow_limit = 0; + + if (fws->fifo_credit[lender_ac] > borrow_limit) { + fws->credits_borrowed[borrower_ac][lender_ac]++; fws->fifo_credit[lender_ac]--; if (fws->fifo_credit[lender_ac] == 0) fws->fifo_credit_map &= ~(1 << lender_ac); - fws->fifo_credit_map |= (1 << BRCMF_FWS_FIFO_AC_BE); + fws->fifo_credit_map |= (1 << borrower_ac); brcmf_dbg(DATA, "borrow credit from: %d\n", lender_ac); return 0; } } - fws->fifo_credit_map &= ~(1 << BRCMF_FWS_FIFO_AC_BE); + fws->fifo_credit_map &= ~(1 << borrower_ac); return -ENAVAIL; } @@ -2216,9 +2242,10 @@ static void brcmf_fws_dequeue_worker(struct work_struct *worker) } continue; } - while ((fws->fifo_credit[fifo] > 0) || + + while ((fws->fifo_credit[fifo]) || ((!fws->bcmc_credit_check) && - (fifo == BRCMF_FWS_FIFO_BCMC))) { + (fifo == BRCMF_FWS_FIFO_BCMC))) { skb = brcmf_fws_deq(fws, fifo); if (!skb) break; @@ -2228,10 +2255,14 @@ static void brcmf_fws_dequeue_worker(struct work_struct *worker) if (fws->bus_flow_blocked) break; } - if ((fifo == BRCMF_FWS_FIFO_AC_BE) && - (fws->fifo_credit[fifo] <= 0) && - (!fws->bus_flow_blocked)) { - while (brcmf_fws_borrow_credit(fws) == 0) { + + if (fifo >= BRCMF_FWS_FIFO_AC_BE && + fifo <= BRCMF_FWS_FIFO_AC_VO && + fws->fifo_credit[fifo] == 0 && + !fws->bus_flow_blocked) { + while (brcmf_fws_borrow_credit(fws, + fifo - 1, fifo, + true) == 0) { skb = brcmf_fws_deq(fws, fifo); if (!skb) { brcmf_fws_return_credits(fws, fifo, 1); diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/msgbuf.c b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/msgbuf.c index 8bb4f1fa790e..f1a20db8daab 100644 --- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/msgbuf.c +++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/msgbuf.c @@ -54,6 +54,7 @@ #define BRCMF_IOCTL_REQ_PKTID 0xFFFE #define BRCMF_MSGBUF_MAX_PKT_SIZE 2048 +#define BRCMF_MSGBUF_MAX_CTL_PKT_SIZE 8192 #define BRCMF_MSGBUF_RXBUFPOST_THRESHOLD 32 #define BRCMF_MSGBUF_MAX_IOCTLRESPBUF_POST 8 #define BRCMF_MSGBUF_MAX_EVENTBUF_POST 8 @@ -1028,7 +1029,7 @@ brcmf_msgbuf_rxbuf_ctrl_post(struct brcmf_msgbuf *msgbuf, bool event_buf, rx_bufpost = (struct msgbuf_rx_ioctl_resp_or_event *)ret_ptr; memset(rx_bufpost, 0, sizeof(*rx_bufpost)); - skb = brcmu_pkt_buf_get_skb(BRCMF_MSGBUF_MAX_PKT_SIZE); + skb = brcmu_pkt_buf_get_skb(BRCMF_MSGBUF_MAX_CTL_PKT_SIZE); if (skb == NULL) { bphy_err(drvr, "Failed to alloc SKB\n"); diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/of.c b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/of.c index b886b56a5e5a..a7554265f95f 100644 --- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/of.c +++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/of.c @@ -17,7 +17,6 @@ void brcmf_of_probe(struct device *dev, enum brcmf_bus_type bus_type, { struct brcmfmac_sdio_pd *sdio = &settings->bus.sdio; struct device_node *root, *np = dev->of_node; - struct property *prop; int irq; u32 irqf; u32 val; @@ -25,8 +24,22 @@ void brcmf_of_probe(struct device *dev, enum brcmf_bus_type bus_type, /* Set board-type to the first string of the machine compatible prop */ root = of_find_node_by_path("/"); if (root) { - prop = of_find_property(root, "compatible", NULL); - settings->board_type = of_prop_next_string(prop, NULL); + int i, len; + char *board_type; + const char *tmp; + + of_property_read_string_index(root, "compatible", 0, &tmp); + + /* get rid of '/' in the compatible string to be able to find the FW */ + len = strlen(tmp) + 1; + board_type = devm_kzalloc(dev, len, GFP_KERNEL); + strscpy(board_type, tmp, len); + for (i = 0; i < board_type[i]; i++) { + if (board_type[i] == '/') + board_type[i] = '-'; + } + settings->board_type = board_type; + of_node_put(root); } diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/p2p.c b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/p2p.c index d2795dc17c46..debd887e159e 100644 --- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/p2p.c +++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/p2p.c @@ -1700,7 +1700,7 @@ static s32 brcmf_p2p_pub_af_tx(struct brcmf_cfg80211_info *cfg, return err; } -static bool brcmf_p2p_check_dwell_overflow(s32 requested_dwell, +static bool brcmf_p2p_check_dwell_overflow(u32 requested_dwell, unsigned long dwell_jiffies) { if ((requested_dwell & CUSTOM_RETRY_MASK) && @@ -1738,8 +1738,7 @@ bool brcmf_p2p_send_action_frame(struct brcmf_cfg80211_info *cfg, unsigned long dwell_jiffies = 0; bool dwell_overflow = false; - s32 requested_dwell = af_params->dwell_time; - + u32 requested_dwell = le32_to_cpu(af_params->dwell_time); action_frame = &af_params->action_frame; action_frame_len = le16_to_cpu(action_frame->len); diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.c b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.c index 310d8075f5d7..e8712ad3ac45 100644 --- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.c +++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.c @@ -16,6 +16,7 @@ #include <linux/mmc/sdio_ids.h> #include <linux/mmc/sdio_func.h> #include <linux/mmc/card.h> +#include <linux/mmc/core.h> #include <linux/semaphore.h> #include <linux/firmware.h> #include <linux/module.h> @@ -648,6 +649,8 @@ static const struct brcmf_firmware_mapping brcmf_sdio_fwnames[] = { BRCMF_FW_ENTRY(CY_CC_43012_CHIP_ID, 0xFFFFFFFF, 43012) }; +#define TXCTL_CREDITS 2 + static void pkt_align(struct sk_buff *p, int len, int align) { uint datalign; @@ -661,8 +664,16 @@ static void pkt_align(struct sk_buff *p, int len, int align) /* To check if there's window offered */ static bool data_ok(struct brcmf_sdio *bus) { - return (u8)(bus->tx_max - bus->tx_seq) != 0 && - ((u8)(bus->tx_max - bus->tx_seq) & 0x80) == 0; + /* Reserve TXCTL_CREDITS credits for txctl */ + return (bus->tx_max - bus->tx_seq) > TXCTL_CREDITS && + ((bus->tx_max - bus->tx_seq) & 0x80) == 0; +} + +/* To check if there's window offered */ +static bool txctl_ok(struct brcmf_sdio *bus) +{ + return (bus->tx_max - bus->tx_seq) != 0 && + ((bus->tx_max - bus->tx_seq) & 0x80) == 0; } static int @@ -2668,7 +2679,7 @@ static void brcmf_sdio_dpc(struct brcmf_sdio *bus) brcmf_sdio_clrintr(bus); if (bus->ctrl_frame_stat && (bus->clkstate == CLK_AVAIL) && - data_ok(bus)) { + txctl_ok(bus)) { sdio_claim_host(bus->sdiodev->func1); if (bus->ctrl_frame_stat) { err = brcmf_sdio_tx_ctrlframe(bus, bus->ctrl_frame_buf, @@ -2676,6 +2687,9 @@ static void brcmf_sdio_dpc(struct brcmf_sdio *bus) bus->ctrl_frame_err = err; wmb(); bus->ctrl_frame_stat = false; + if (err) + brcmf_err("sdio ctrlframe tx failed err=%d\n", + err); } sdio_release_host(bus->sdiodev->func1); brcmf_sdio_wait_event_wakeup(bus); @@ -3699,7 +3713,11 @@ static void brcmf_sdio_bus_watchdog(struct brcmf_sdio *bus) if (bus->idlecount > bus->idletime) { brcmf_dbg(SDIO, "idle\n"); sdio_claim_host(bus->sdiodev->func1); - brcmf_sdio_wd_timer(bus, false); +#ifdef DEBUG + if (!BRCMF_FWCON_ON() || + bus->console_interval == 0) +#endif + brcmf_sdio_wd_timer(bus, false); bus->idlecount = 0; brcmf_sdio_bus_sleep(bus, true, false); sdio_release_host(bus->sdiodev->func1); @@ -4109,6 +4127,36 @@ int brcmf_sdio_get_fwname(struct device *dev, const char *ext, u8 *fw_name) return 0; } +static int brcmf_sdio_bus_reset(struct device *dev) +{ + int ret = 0; + struct brcmf_bus *bus_if = dev_get_drvdata(dev); + struct brcmf_sdio_dev *sdiodev = bus_if->bus_priv.sdio; + + brcmf_dbg(SDIO, "Enter\n"); + + /* start by unregistering irqs */ + brcmf_sdiod_intr_unregister(sdiodev); + + brcmf_sdiod_remove(sdiodev); + + /* reset the adapter */ + sdio_claim_host(sdiodev->func1); + mmc_hw_reset(sdiodev->func1->card->host); + sdio_release_host(sdiodev->func1); + + brcmf_bus_change_state(sdiodev->bus_if, BRCMF_BUS_DOWN); + + ret = brcmf_sdiod_probe(sdiodev); + if (ret) { + brcmf_err("Failed to probe after sdio device reset: ret %d\n", + ret); + brcmf_sdiod_remove(sdiodev); + } + + return ret; +} + static const struct brcmf_bus_ops brcmf_sdio_bus_ops = { .stop = brcmf_sdio_bus_stop, .preinit = brcmf_sdio_bus_preinit, @@ -4120,7 +4168,8 @@ static const struct brcmf_bus_ops brcmf_sdio_bus_ops = { .get_ramsize = brcmf_sdio_bus_get_ramsize, .get_memdump = brcmf_sdio_bus_get_memdump, .get_fwname = brcmf_sdio_get_fwname, - .debugfs_create = brcmf_sdio_debugfs_create + .debugfs_create = brcmf_sdio_debugfs_create, + .reset = brcmf_sdio_bus_reset }; #define BRCMF_SDIO_FW_CODE 0 diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.h b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.h index 163fd664780a..12108927fb50 100644 --- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.h +++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.h @@ -367,6 +367,9 @@ static inline void brcmf_sdiod_freezer_uncount(struct brcmf_sdio_dev *sdiodev) } #endif /* CONFIG_PM_SLEEP */ +int brcmf_sdiod_probe(struct brcmf_sdio_dev *sdiodev); +int brcmf_sdiod_remove(struct brcmf_sdio_dev *sdiodev); + struct brcmf_sdio *brcmf_sdio_probe(struct brcmf_sdio_dev *sdiodev); void brcmf_sdio_remove(struct brcmf_sdio *bus); void brcmf_sdio_isr(struct brcmf_sdio *bus); diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmsmac/led.c b/drivers/net/wireless/broadcom/brcm80211/brcmsmac/led.c index c0a5449ed72c..c1b9ac692d26 100644 --- a/drivers/net/wireless/broadcom/brcm80211/brcmsmac/led.c +++ b/drivers/net/wireless/broadcom/brcm80211/brcmsmac/led.c @@ -1,7 +1,9 @@ // SPDX-License-Identifier: GPL-2.0 #include <net/mac80211.h> #include <linux/bcma/bcma_driver_chipcommon.h> -#include <linux/gpio.h> +#include <linux/gpio/driver.h> +#include <linux/gpio/machine.h> +#include <linux/gpio/consumer.h> #include "mac80211_if.h" #include "pub.h" @@ -19,16 +21,13 @@ static void brcms_radio_led_ctrl(struct brcms_info *wl, bool state) { - if (wl->radio_led.gpio == -1) + if (!wl->radio_led.gpiod) return; - if (wl->radio_led.active_low) - state = !state; - if (state) - gpio_set_value(wl->radio_led.gpio, 1); + gpiod_set_value(wl->radio_led.gpiod, 1); else - gpio_set_value(wl->radio_led.gpio, 0); + gpiod_set_value(wl->radio_led.gpiod, 0); } @@ -45,8 +44,8 @@ void brcms_led_unregister(struct brcms_info *wl) { if (wl->led_dev.dev) led_classdev_unregister(&wl->led_dev); - if (wl->radio_led.gpio != -1) - gpio_free(wl->radio_led.gpio); + if (wl->radio_led.gpiod) + gpiochip_free_own_desc(wl->radio_led.gpiod); } int brcms_led_register(struct brcms_info *wl) @@ -61,12 +60,8 @@ int brcms_led_register(struct brcms_info *wl) &sprom->gpio1, &sprom->gpio2, &sprom->gpio3 }; - unsigned gpio = -1; - bool active_low = false; - - /* none by default */ - radio_led->gpio = -1; - radio_led->active_low = false; + int hwnum = -1; + enum gpio_lookup_flags lflags = GPIO_ACTIVE_HIGH; if (!bcma_gpio || !gpio_is_valid(bcma_gpio->base)) return -ENODEV; @@ -75,30 +70,26 @@ int brcms_led_register(struct brcms_info *wl) for (i = 0; i < BRCMS_LED_NO; i++) { u8 led = *leds[i]; if ((led & BRCMS_LED_BEH_MASK) == BRCMS_LED_RADIO) { - gpio = bcma_gpio->base + i; + hwnum = i; if (led & BRCMS_LED_AL_MASK) - active_low = true; + lflags = GPIO_ACTIVE_LOW; break; } } - if (gpio == -1 || !gpio_is_valid(gpio)) + /* No LED, bail out */ + if (hwnum == -1) return -ENODEV; - /* request and configure LED gpio */ - err = gpio_request_one(gpio, - active_low ? GPIOF_OUT_INIT_HIGH - : GPIOF_OUT_INIT_LOW, - "radio on"); - if (err) { - wiphy_err(wl->wiphy, "requesting led gpio %d failed (err: %d)\n", - gpio, err); - return err; - } - err = gpio_direction_output(gpio, 1); - if (err) { - wiphy_err(wl->wiphy, "cannot set led gpio %d to output (err: %d)\n", - gpio, err); + /* Try to obtain this LED GPIO line */ + radio_led->gpiod = gpiochip_request_own_desc(bcma_gpio, hwnum, + "radio on", lflags, + GPIOD_OUT_LOW); + + if (IS_ERR(radio_led->gpiod)) { + err = PTR_ERR(radio_led->gpiod); + wiphy_err(wl->wiphy, "requesting led GPIO failed (err: %d)\n", + err); return err; } @@ -117,11 +108,8 @@ int brcms_led_register(struct brcms_info *wl) return err; } - wiphy_info(wl->wiphy, "registered radio enabled led device: %s gpio: %d\n", - wl->radio_led.name, - gpio); - radio_led->gpio = gpio; - radio_led->active_low = active_low; + wiphy_info(wl->wiphy, "registered radio enabled led device: %s\n", + wl->radio_led.name); return 0; } diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmsmac/led.h b/drivers/net/wireless/broadcom/brcm80211/brcmsmac/led.h index 17a0b1f5dbcf..d65f5c268fd7 100644 --- a/drivers/net/wireless/broadcom/brcm80211/brcmsmac/led.h +++ b/drivers/net/wireless/broadcom/brcm80211/brcmsmac/led.h @@ -16,10 +16,12 @@ #ifndef _BRCM_LED_H_ #define _BRCM_LED_H_ + +struct gpio_desc; + struct brcms_led { char name[32]; - unsigned gpio; - bool active_low; + struct gpio_desc *gpiod; }; #ifdef CONFIG_BCMA_DRIVER_GPIO diff --git a/drivers/net/wireless/cisco/airo.c b/drivers/net/wireless/cisco/airo.c index 827bb6d74815..726cb1bc86cd 100644 --- a/drivers/net/wireless/cisco/airo.c +++ b/drivers/net/wireless/cisco/airo.c @@ -2450,7 +2450,7 @@ static void mpi_unmap_card(struct pci_dev *pci) /************************************************************* * This routine assumes that descriptors have been setup . - * Run at insmod time or after reset when the decriptors + * Run at insmod time or after reset when the descriptors * have been initialized . Returns 0 if all is well nz * otherwise . Does not allocate memory but sets up card * using previously allocated descriptors. @@ -3113,7 +3113,7 @@ static int airo_thread(void *data) { } break; } - current->state = TASK_RUNNING; + __set_current_state(TASK_RUNNING); remove_wait_queue(&ai->thr_wait, &wait); locked = 1; } diff --git a/drivers/net/wireless/intel/ipw2x00/ipw2100.c b/drivers/net/wireless/intel/ipw2x00/ipw2100.c index 753dada5a243..83d2f2acc0de 100644 --- a/drivers/net/wireless/intel/ipw2x00/ipw2100.c +++ b/drivers/net/wireless/intel/ipw2x00/ipw2100.c @@ -6397,10 +6397,9 @@ static void ipw2100_pci_remove_one(struct pci_dev *pci_dev) IPW_DEBUG_INFO("exit\n"); } -#ifdef CONFIG_PM -static int ipw2100_suspend(struct pci_dev *pci_dev, pm_message_t state) +static int __maybe_unused ipw2100_suspend(struct device *dev_d) { - struct ipw2100_priv *priv = pci_get_drvdata(pci_dev); + struct ipw2100_priv *priv = dev_get_drvdata(dev_d); struct net_device *dev = priv->net_dev; IPW_DEBUG_INFO("%s: Going into suspend...\n", dev->name); @@ -6414,10 +6413,6 @@ static int ipw2100_suspend(struct pci_dev *pci_dev, pm_message_t state) /* Remove the PRESENT state of the device */ netif_device_detach(dev); - pci_save_state(pci_dev); - pci_disable_device(pci_dev); - pci_set_power_state(pci_dev, PCI_D3hot); - priv->suspend_at = ktime_get_boottime_seconds(); mutex_unlock(&priv->action_mutex); @@ -6425,11 +6420,11 @@ static int ipw2100_suspend(struct pci_dev *pci_dev, pm_message_t state) return 0; } -static int ipw2100_resume(struct pci_dev *pci_dev) +static int __maybe_unused ipw2100_resume(struct device *dev_d) { + struct pci_dev *pci_dev = to_pci_dev(dev_d); struct ipw2100_priv *priv = pci_get_drvdata(pci_dev); struct net_device *dev = priv->net_dev; - int err; u32 val; if (IPW2100_PM_DISABLED) @@ -6439,16 +6434,6 @@ static int ipw2100_resume(struct pci_dev *pci_dev) IPW_DEBUG_INFO("%s: Coming out of suspend...\n", dev->name); - pci_set_power_state(pci_dev, PCI_D0); - err = pci_enable_device(pci_dev); - if (err) { - printk(KERN_ERR "%s: pci_enable_device failed on resume\n", - dev->name); - mutex_unlock(&priv->action_mutex); - return err; - } - pci_restore_state(pci_dev); - /* * Suspend/Resume resets the PCI configuration space, so we have to * re-disable the RETRY_TIMEOUT register (0x41) to keep PCI Tx retries @@ -6473,7 +6458,6 @@ static int ipw2100_resume(struct pci_dev *pci_dev) return 0; } -#endif static void ipw2100_shutdown(struct pci_dev *pci_dev) { @@ -6539,15 +6523,14 @@ static const struct pci_device_id ipw2100_pci_id_table[] = { MODULE_DEVICE_TABLE(pci, ipw2100_pci_id_table); +static SIMPLE_DEV_PM_OPS(ipw2100_pm_ops, ipw2100_suspend, ipw2100_resume); + static struct pci_driver ipw2100_pci_driver = { .name = DRV_NAME, .id_table = ipw2100_pci_id_table, .probe = ipw2100_pci_init_one, .remove = ipw2100_pci_remove_one, -#ifdef CONFIG_PM - .suspend = ipw2100_suspend, - .resume = ipw2100_resume, -#endif + .driver.pm = &ipw2100_pm_ops, .shutdown = ipw2100_shutdown, }; diff --git a/drivers/net/wireless/intel/ipw2x00/ipw2200.c b/drivers/net/wireless/intel/ipw2x00/ipw2200.c index 661e63bfc892..39ff3a426092 100644 --- a/drivers/net/wireless/intel/ipw2x00/ipw2200.c +++ b/drivers/net/wireless/intel/ipw2x00/ipw2200.c @@ -11838,10 +11838,9 @@ static void ipw_pci_remove(struct pci_dev *pdev) free_firmware(); } -#ifdef CONFIG_PM -static int ipw_pci_suspend(struct pci_dev *pdev, pm_message_t state) +static int __maybe_unused ipw_pci_suspend(struct device *dev_d) { - struct ipw_priv *priv = pci_get_drvdata(pdev); + struct ipw_priv *priv = dev_get_drvdata(dev_d); struct net_device *dev = priv->net_dev; printk(KERN_INFO "%s: Going into suspend...\n", dev->name); @@ -11852,33 +11851,20 @@ static int ipw_pci_suspend(struct pci_dev *pdev, pm_message_t state) /* Remove the PRESENT state of the device */ netif_device_detach(dev); - pci_save_state(pdev); - pci_disable_device(pdev); - pci_set_power_state(pdev, pci_choose_state(pdev, state)); - priv->suspend_at = ktime_get_boottime_seconds(); return 0; } -static int ipw_pci_resume(struct pci_dev *pdev) +static int __maybe_unused ipw_pci_resume(struct device *dev_d) { + struct pci_dev *pdev = to_pci_dev(dev_d); struct ipw_priv *priv = pci_get_drvdata(pdev); struct net_device *dev = priv->net_dev; - int err; u32 val; printk(KERN_INFO "%s: Coming out of suspend...\n", dev->name); - pci_set_power_state(pdev, PCI_D0); - err = pci_enable_device(pdev); - if (err) { - printk(KERN_ERR "%s: pci_enable_device failed on resume\n", - dev->name); - return err; - } - pci_restore_state(pdev); - /* * Suspend/Resume resets the PCI configuration space, so we have to * re-disable the RETRY_TIMEOUT register (0x41) to keep PCI Tx retries @@ -11900,7 +11886,6 @@ static int ipw_pci_resume(struct pci_dev *pdev) return 0; } -#endif static void ipw_pci_shutdown(struct pci_dev *pdev) { @@ -11912,16 +11897,15 @@ static void ipw_pci_shutdown(struct pci_dev *pdev) pci_disable_device(pdev); } +static SIMPLE_DEV_PM_OPS(ipw_pci_pm_ops, ipw_pci_suspend, ipw_pci_resume); + /* driver initialization stuff */ static struct pci_driver ipw_driver = { .name = DRV_NAME, .id_table = card_ids, .probe = ipw_pci_probe, .remove = ipw_pci_remove, -#ifdef CONFIG_PM - .suspend = ipw_pci_suspend, - .resume = ipw_pci_resume, -#endif + .driver.pm = &ipw_pci_pm_ops, .shutdown = ipw_pci_shutdown, }; diff --git a/drivers/net/wireless/intel/iwlegacy/4965-mac.c b/drivers/net/wireless/intel/iwlegacy/4965-mac.c index da6d4202611c..ad9d7e702a29 100644 --- a/drivers/net/wireless/intel/iwlegacy/4965-mac.c +++ b/drivers/net/wireless/intel/iwlegacy/4965-mac.c @@ -1415,7 +1415,7 @@ il4965_hdl_c_stats(struct il_priv *il, struct il_rx_buf *rxb) /* * mac80211 queues, ACs, hardware queues, FIFOs. * - * Cf. http://wireless.kernel.org/en/developers/Documentation/mac80211/queues + * Cf. https://wireless.wiki.kernel.org/en/developers/Documentation/mac80211/queues * * Mac80211 uses the following numbers, which we get as from it * by way of skb_get_queue_mapping(skb): diff --git a/drivers/net/wireless/intel/iwlegacy/4965-rs.c b/drivers/net/wireless/intel/iwlegacy/4965-rs.c index 0a02d8aca320..1f196665d21f 100644 --- a/drivers/net/wireless/intel/iwlegacy/4965-rs.c +++ b/drivers/net/wireless/intel/iwlegacy/4965-rs.c @@ -1749,7 +1749,7 @@ il4965_rs_rate_scale_perform(struct il_priv *il, struct sk_buff *skb, u8 done_search = 0; u16 high_low; s32 sr; - u8 tid = MAX_TID_COUNT; + u8 tid; struct il_tid_data *tid_data; D_RATE("rate scale calculate new rate for skb\n"); diff --git a/drivers/net/wireless/intel/iwlegacy/common.c b/drivers/net/wireless/intel/iwlegacy/common.c index 348c17ce72f5..f78e062df572 100644 --- a/drivers/net/wireless/intel/iwlegacy/common.c +++ b/drivers/net/wireless/intel/iwlegacy/common.c @@ -4286,8 +4286,8 @@ il_apm_init(struct il_priv *il) * power savings, even without L1. */ if (il->cfg->set_l0s) { - pcie_capability_read_word(il->pci_dev, PCI_EXP_LNKCTL, &lctl); - if (lctl & PCI_EXP_LNKCTL_ASPM_L1) { + ret = pcie_capability_read_word(il->pci_dev, PCI_EXP_LNKCTL, &lctl); + if (!ret && (lctl & PCI_EXP_LNKCTL_ASPM_L1)) { /* L1-ASPM enabled; disable(!) L0S */ il_set_bit(il, CSR_GIO_REG, CSR_GIO_REG_VAL_L0S_ENABLED); diff --git a/drivers/net/wireless/intel/iwlwifi/Kconfig b/drivers/net/wireless/intel/iwlwifi/Kconfig index 36153fa5f96a..1085afbefba8 100644 --- a/drivers/net/wireless/intel/iwlwifi/Kconfig +++ b/drivers/net/wireless/intel/iwlwifi/Kconfig @@ -31,7 +31,7 @@ config IWLWIFI In order to use this driver, you will need a firmware image for it. You can obtain the microcode from: - <http://wireless.kernel.org/en/users/Drivers/iwlwifi>. + <https://wireless.wiki.kernel.org/en/users/Drivers/iwlwifi>. The firmware is typically installed in /lib/firmware. You can look in the hotplug script /etc/hotplug/firmware.agent to diff --git a/drivers/net/wireless/intel/iwlwifi/dvm/commands.h b/drivers/net/wireless/intel/iwlwifi/dvm/commands.h index 0f4be4be181c..fdcc1292a92b 100644 --- a/drivers/net/wireless/intel/iwlwifi/dvm/commands.h +++ b/drivers/net/wireless/intel/iwlwifi/dvm/commands.h @@ -1023,7 +1023,7 @@ struct iwl_wep_cmd { u8 global_key_type; u8 flags; u8 reserved; - struct iwl_wep_key key[0]; + struct iwl_wep_key key[]; } __packed; #define WEP_KEY_WEP_TYPE 1 @@ -1305,7 +1305,7 @@ struct iwl_tx_cmd { * length is 26 or 30 bytes, followed by payload data */ u8 payload[0]; - struct ieee80211_hdr hdr[0]; + struct ieee80211_hdr hdr[]; } __packed; /* @@ -2380,7 +2380,7 @@ struct iwl_scan_cmd { * for one scan to complete (i.e. receive SCAN_COMPLETE_NOTIFICATION) * before requesting another scan. */ - u8 data[0]; + u8 data[]; } __packed; /* Can abort will notify by complete notification with abort status. */ @@ -2475,7 +2475,7 @@ struct iwl_tx_beacon_cmd { __le16 tim_idx; u8 tim_size; u8 reserved1; - struct ieee80211_hdr frame[0]; /* beacon frame */ + struct ieee80211_hdr frame[]; /* beacon frame */ } __packed; /****************************************************************************** @@ -3188,7 +3188,7 @@ struct iwl_calib_hdr { struct iwl_calib_cmd { struct iwl_calib_hdr hdr; - u8 data[0]; + u8 data[]; } __packed; struct iwl_calib_xtal_freq_cmd { @@ -3216,7 +3216,7 @@ struct iwl_calib_temperature_offset_v2_cmd { /* IWL_PHY_CALIBRATE_CHAIN_NOISE_RESET_CMD */ struct iwl_calib_chain_noise_reset_cmd { struct iwl_calib_hdr hdr; - u8 data[0]; + u8 data[]; }; /* IWL_PHY_CALIBRATE_CHAIN_NOISE_GAIN_CMD */ diff --git a/drivers/net/wireless/intel/iwlwifi/dvm/mac80211.c b/drivers/net/wireless/intel/iwlwifi/dvm/mac80211.c index 6512d25e3563..423d3c396b2d 100644 --- a/drivers/net/wireless/intel/iwlwifi/dvm/mac80211.c +++ b/drivers/net/wireless/intel/iwlwifi/dvm/mac80211.c @@ -200,6 +200,7 @@ int iwlagn_mac_setup_register(struct iwl_priv *priv, iwl_leds_init(priv); wiphy_ext_feature_set(hw->wiphy, NL80211_EXT_FEATURE_CQM_RSSI_LIST); + wiphy_ext_feature_set(hw->wiphy, NL80211_EXT_FEATURE_EXT_KEY_ID); ret = ieee80211_register_hw(priv->hw); if (ret) { diff --git a/drivers/net/wireless/intel/iwlwifi/fw/api/nvm-reg.h b/drivers/net/wireless/intel/iwlwifi/fw/api/nvm-reg.h index fd719c37428c..b6c31f01ea9e 100644 --- a/drivers/net/wireless/intel/iwlwifi/fw/api/nvm-reg.h +++ b/drivers/net/wireless/intel/iwlwifi/fw/api/nvm-reg.h @@ -361,7 +361,7 @@ struct iwl_mcc_update_resp_v3 { __le16 time; __le16 geo_info; __le32 n_channels; - __le32 channels[0]; + __le32 channels[]; } __packed; /* LAR_UPDATE_MCC_CMD_RESP_S_VER_3 */ /** @@ -390,7 +390,7 @@ struct iwl_mcc_update_resp { u8 source_id; u8 reserved[3]; __le32 n_channels; - __le32 channels[0]; + __le32 channels[]; } __packed; /* LAR_UPDATE_MCC_CMD_RESP_S_VER_4 */ /** diff --git a/drivers/net/wireless/intel/iwlwifi/fw/api/tx.h b/drivers/net/wireless/intel/iwlwifi/fw/api/tx.h index f1d1fe96fecc..82d59b5a5f8c 100644 --- a/drivers/net/wireless/intel/iwlwifi/fw/api/tx.h +++ b/drivers/net/wireless/intel/iwlwifi/fw/api/tx.h @@ -293,7 +293,7 @@ struct iwl_tx_cmd { __le16 pm_frame_timeout; __le16 reserved4; u8 payload[0]; - struct ieee80211_hdr hdr[0]; + struct ieee80211_hdr hdr[]; } __packed; /* TX_CMD_API_S_VER_6 */ struct iwl_dram_sec_info { @@ -319,7 +319,7 @@ struct iwl_tx_cmd_gen2 { __le32 flags; struct iwl_dram_sec_info dram_info; __le32 rate_n_flags; - struct ieee80211_hdr hdr[0]; + struct ieee80211_hdr hdr[]; } __packed; /* TX_CMD_API_S_VER_7 */ /** @@ -342,7 +342,7 @@ struct iwl_tx_cmd_gen3 { struct iwl_dram_sec_info dram_info; __le32 rate_n_flags; __le64 ttl; - struct ieee80211_hdr hdr[0]; + struct ieee80211_hdr hdr[]; } __packed; /* TX_CMD_API_S_VER_8 */ /* @@ -766,8 +766,8 @@ struct iwl_mvm_compressed_ba_notif { __le32 tx_rate; __le16 tfd_cnt; __le16 ra_tid_cnt; - struct iwl_mvm_compressed_ba_tfd tfd[0]; struct iwl_mvm_compressed_ba_ratid ra_tid[0]; + struct iwl_mvm_compressed_ba_tfd tfd[]; } __packed; /* COMPRESSED_BA_RES_API_S_VER_4 */ /** @@ -784,7 +784,7 @@ struct iwl_mac_beacon_cmd_v6 { __le32 template_id; __le32 tim_idx; __le32 tim_size; - struct ieee80211_hdr frame[0]; + struct ieee80211_hdr frame[]; } __packed; /* BEACON_TEMPLATE_CMD_API_S_VER_6 */ /** @@ -805,7 +805,7 @@ struct iwl_mac_beacon_cmd_v7 { __le32 tim_size; __le32 ecsa_offset; __le32 csa_offset; - struct ieee80211_hdr frame[0]; + struct ieee80211_hdr frame[]; } __packed; /* BEACON_TEMPLATE_CMD_API_S_VER_7 */ enum iwl_mac_beacon_flags { @@ -840,7 +840,7 @@ struct iwl_mac_beacon_cmd { __le32 tim_size; __le32 ecsa_offset; __le32 csa_offset; - struct ieee80211_hdr frame[0]; + struct ieee80211_hdr frame[]; } __packed; /* BEACON_TEMPLATE_CMD_API_S_VER_10 */ struct iwl_beacon_notif { diff --git a/drivers/net/wireless/intel/iwlwifi/fw/dbg.c b/drivers/net/wireless/intel/iwlwifi/fw/dbg.c index 4d3687cc83a4..7ea55cfdd8a8 100644 --- a/drivers/net/wireless/intel/iwlwifi/fw/dbg.c +++ b/drivers/net/wireless/intel/iwlwifi/fw/dbg.c @@ -2554,7 +2554,7 @@ int iwl_fw_start_dbg_conf(struct iwl_fw_runtime *fwrt, u8 conf_id) return -EINVAL; if (fwrt->dump.conf != FW_DBG_INVALID) - IWL_WARN(fwrt, "FW already configured (%d) - re-configuring\n", + IWL_INFO(fwrt, "FW already configured (%d) - re-configuring\n", fwrt->dump.conf); /* Send all HCMDs for configuring the FW debug */ diff --git a/drivers/net/wireless/intel/iwlwifi/fw/debugfs.c b/drivers/net/wireless/intel/iwlwifi/fw/debugfs.c index 6e72c27f527b..267ad4eddb5c 100644 --- a/drivers/net/wireless/intel/iwlwifi/fw/debugfs.c +++ b/drivers/net/wireless/intel/iwlwifi/fw/debugfs.c @@ -260,7 +260,7 @@ struct hcmd_write_data { __be32 cmd_id; __be32 flags; __be16 length; - u8 data[0]; + u8 data[]; } __packed; static ssize_t iwl_dbgfs_send_hcmd_write(struct iwl_fw_runtime *fwrt, char *buf, diff --git a/drivers/net/wireless/intel/iwlwifi/iwl-config.h b/drivers/net/wireless/intel/iwlwifi/iwl-config.h index 244899f3f3bf..e27c13263a23 100644 --- a/drivers/net/wireless/intel/iwlwifi/iwl-config.h +++ b/drivers/net/wireless/intel/iwlwifi/iwl-config.h @@ -641,6 +641,6 @@ extern const struct iwl_cfg iwlax411_2ax_cfg_so_gf4_a0; extern const struct iwl_cfg iwlax411_2ax_cfg_so_gf4_a0_long; extern const struct iwl_cfg iwlax411_2ax_cfg_sosnj_gf4_a0; extern const struct iwl_cfg iwlax211_cfg_snj_gf_a0; -#endif /* CPTCFG_IWLMVM || CPTCFG_IWLFMAC */ +#endif /* CONFIG_IWLMVM */ #endif /* __IWL_CONFIG_H__ */ diff --git a/drivers/net/wireless/intel/iwlwifi/iwl-op-mode.h b/drivers/net/wireless/intel/iwlwifi/iwl-op-mode.h index 3008a5246be8..b35b8920941b 100644 --- a/drivers/net/wireless/intel/iwlwifi/iwl-op-mode.h +++ b/drivers/net/wireless/intel/iwlwifi/iwl-op-mode.h @@ -175,7 +175,7 @@ void iwl_opmode_deregister(const char *name); struct iwl_op_mode { const struct iwl_op_mode_ops *ops; - char op_mode_specific[0] __aligned(sizeof(void *)); + char op_mode_specific[] __aligned(sizeof(void *)); }; static inline void iwl_op_mode_stop(struct iwl_op_mode *op_mode) diff --git a/drivers/net/wireless/intel/iwlwifi/iwl-trans.h b/drivers/net/wireless/intel/iwlwifi/iwl-trans.h index a301e2484cdb..34788e7afc7b 100644 --- a/drivers/net/wireless/intel/iwlwifi/iwl-trans.h +++ b/drivers/net/wireless/intel/iwlwifi/iwl-trans.h @@ -1006,7 +1006,7 @@ struct iwl_trans { /* pointer to trans specific struct */ /*Ensure that this pointer will always be aligned to sizeof pointer */ - char trans_specific[0] __aligned(sizeof(void *)); + char trans_specific[] __aligned(sizeof(void *)); }; const char *iwl_get_cmd_string(struct iwl_trans *trans, u32 id); diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/mac80211.c b/drivers/net/wireless/intel/iwlwifi/mvm/mac80211.c index 77916231ff7d..9374c85c5caf 100644 --- a/drivers/net/wireless/intel/iwlwifi/mvm/mac80211.c +++ b/drivers/net/wireless/intel/iwlwifi/mvm/mac80211.c @@ -543,6 +543,14 @@ int iwl_mvm_mac_setup_register(struct iwl_mvm *mvm) hw->wiphy->flags |= WIPHY_FLAG_IBSS_RSN; wiphy_ext_feature_set(hw->wiphy, NL80211_EXT_FEATURE_VHT_IBSS); + + /* The new Tx API does not allow to pass the key or keyid of a MPDU to + * the hw, preventing us to control which key(id) to use per MPDU. + * Till that's fixed we can't use Extended Key ID for the newer cards. + */ + if (!iwl_mvm_has_new_tx_api(mvm)) + wiphy_ext_feature_set(hw->wiphy, + NL80211_EXT_FEATURE_EXT_KEY_ID); hw->wiphy->features |= NL80211_FEATURE_HT_IBSS; hw->wiphy->regulatory_flags |= REGULATORY_ENABLE_RELAX_NO_IR; @@ -4903,7 +4911,7 @@ static void iwl_mvm_mac_sta_statistics(struct ieee80211_hw *hw, struct iwl_mvm_sta *mvmsta = iwl_mvm_sta_from_mac80211(sta); if (mvmsta->avg_energy) { - sinfo->signal_avg = mvmsta->avg_energy; + sinfo->signal_avg = -(s8)mvmsta->avg_energy; sinfo->filled |= BIT_ULL(NL80211_STA_INFO_SIGNAL_AVG); } diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/rs.c b/drivers/net/wireless/intel/iwlwifi/mvm/rs.c index a7264b282d79..86b2ebb5d5fb 100644 --- a/drivers/net/wireless/intel/iwlwifi/mvm/rs.c +++ b/drivers/net/wireless/intel/iwlwifi/mvm/rs.c @@ -603,7 +603,7 @@ static int rs_tl_turn_on_agg_for_tid(struct iwl_mvm *mvm, struct iwl_lq_sta *lq_data, u8 tid, struct ieee80211_sta *sta) { - int ret = -EAGAIN; + int ret; IWL_DEBUG_HT(mvm, "Starting Tx agg: STA: %pM tid: %d\n", sta->addr, tid); diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/sta.c b/drivers/net/wireless/intel/iwlwifi/mvm/sta.c index fee01cbbd3ac..53af3c910eae 100644 --- a/drivers/net/wireless/intel/iwlwifi/mvm/sta.c +++ b/drivers/net/wireless/intel/iwlwifi/mvm/sta.c @@ -1369,14 +1369,6 @@ out_err: return ret; } -static inline u8 iwl_mvm_tid_to_ac_queue(int tid) -{ - if (tid == IWL_MAX_TID_COUNT) - return IEEE80211_AC_VO; /* MGMT */ - - return tid_to_mac80211_ac[tid]; -} - void iwl_mvm_add_new_dqa_stream_wk(struct work_struct *wk) { struct iwl_mvm *mvm = container_of(wk, struct iwl_mvm, diff --git a/drivers/net/wireless/intersil/orinoco/orinoco_nortel.c b/drivers/net/wireless/intersil/orinoco/orinoco_nortel.c index 048693b6c6c2..96a03d10a080 100644 --- a/drivers/net/wireless/intersil/orinoco/orinoco_nortel.c +++ b/drivers/net/wireless/intersil/orinoco/orinoco_nortel.c @@ -290,8 +290,7 @@ static struct pci_driver orinoco_nortel_driver = { .id_table = orinoco_nortel_id_table, .probe = orinoco_nortel_init_one, .remove = orinoco_nortel_remove_one, - .suspend = orinoco_pci_suspend, - .resume = orinoco_pci_resume, + .driver.pm = &orinoco_pci_pm_ops, }; static char version[] __initdata = DRIVER_NAME " " DRIVER_VERSION diff --git a/drivers/net/wireless/intersil/orinoco/orinoco_pci.c b/drivers/net/wireless/intersil/orinoco/orinoco_pci.c index 4938a2208a37..f3c86b07b1b9 100644 --- a/drivers/net/wireless/intersil/orinoco/orinoco_pci.c +++ b/drivers/net/wireless/intersil/orinoco/orinoco_pci.c @@ -230,8 +230,7 @@ static struct pci_driver orinoco_pci_driver = { .id_table = orinoco_pci_id_table, .probe = orinoco_pci_init_one, .remove = orinoco_pci_remove_one, - .suspend = orinoco_pci_suspend, - .resume = orinoco_pci_resume, + .driver.pm = &orinoco_pci_pm_ops, }; static char version[] __initdata = DRIVER_NAME " " DRIVER_VERSION diff --git a/drivers/net/wireless/intersil/orinoco/orinoco_pci.h b/drivers/net/wireless/intersil/orinoco/orinoco_pci.h index 43f5b9f5a0b0..d49d940864b4 100644 --- a/drivers/net/wireless/intersil/orinoco/orinoco_pci.h +++ b/drivers/net/wireless/intersil/orinoco/orinoco_pci.h @@ -18,51 +18,37 @@ struct orinoco_pci_card { void __iomem *attr_io; }; -#ifdef CONFIG_PM -static int orinoco_pci_suspend(struct pci_dev *pdev, pm_message_t state) +static int __maybe_unused orinoco_pci_suspend(struct device *dev_d) { + struct pci_dev *pdev = to_pci_dev(dev_d); struct orinoco_private *priv = pci_get_drvdata(pdev); orinoco_down(priv); free_irq(pdev->irq, priv); - pci_save_state(pdev); - pci_disable_device(pdev); - pci_set_power_state(pdev, PCI_D3hot); return 0; } -static int orinoco_pci_resume(struct pci_dev *pdev) +static int __maybe_unused orinoco_pci_resume(struct device *dev_d) { + struct pci_dev *pdev = to_pci_dev(dev_d); struct orinoco_private *priv = pci_get_drvdata(pdev); struct net_device *dev = priv->ndev; int err; - pci_set_power_state(pdev, PCI_D0); - err = pci_enable_device(pdev); - if (err) { - printk(KERN_ERR "%s: pci_enable_device failed on resume\n", - dev->name); - return err; - } - pci_restore_state(pdev); - err = request_irq(pdev->irq, orinoco_interrupt, IRQF_SHARED, dev->name, priv); if (err) { printk(KERN_ERR "%s: cannot re-allocate IRQ on resume\n", dev->name); - pci_disable_device(pdev); return -EBUSY; } - err = orinoco_up(priv); - - return err; + return orinoco_up(priv); } -#else -#define orinoco_pci_suspend NULL -#define orinoco_pci_resume NULL -#endif + +static SIMPLE_DEV_PM_OPS(orinoco_pci_pm_ops, + orinoco_pci_suspend, + orinoco_pci_resume); #endif /* _ORINOCO_PCI_H */ diff --git a/drivers/net/wireless/intersil/orinoco/orinoco_plx.c b/drivers/net/wireless/intersil/orinoco/orinoco_plx.c index 221352027779..16dada94c774 100644 --- a/drivers/net/wireless/intersil/orinoco/orinoco_plx.c +++ b/drivers/net/wireless/intersil/orinoco/orinoco_plx.c @@ -336,8 +336,7 @@ static struct pci_driver orinoco_plx_driver = { .id_table = orinoco_plx_id_table, .probe = orinoco_plx_init_one, .remove = orinoco_plx_remove_one, - .suspend = orinoco_pci_suspend, - .resume = orinoco_pci_resume, + .driver.pm = &orinoco_pci_pm_ops, }; static char version[] __initdata = DRIVER_NAME " " DRIVER_VERSION diff --git a/drivers/net/wireless/intersil/orinoco/orinoco_tmd.c b/drivers/net/wireless/intersil/orinoco/orinoco_tmd.c index 20ce569b8a43..9a9d335611ac 100644 --- a/drivers/net/wireless/intersil/orinoco/orinoco_tmd.c +++ b/drivers/net/wireless/intersil/orinoco/orinoco_tmd.c @@ -213,8 +213,7 @@ static struct pci_driver orinoco_tmd_driver = { .id_table = orinoco_tmd_id_table, .probe = orinoco_tmd_init_one, .remove = orinoco_tmd_remove_one, - .suspend = orinoco_pci_suspend, - .resume = orinoco_pci_resume, + .driver.pm = &orinoco_pci_pm_ops, }; static char version[] __initdata = DRIVER_NAME " " DRIVER_VERSION diff --git a/drivers/net/wireless/intersil/orinoco/orinoco_usb.c b/drivers/net/wireless/intersil/orinoco/orinoco_usb.c index 651c676b5506..11fa38fedd87 100644 --- a/drivers/net/wireless/intersil/orinoco/orinoco_usb.c +++ b/drivers/net/wireless/intersil/orinoco/orinoco_usb.c @@ -158,7 +158,7 @@ MODULE_FIRMWARE("orinoco_ezusb_fw"); #define EZUSB_REQUEST_FW_TRANS 0xA0 -#define EZUSB_REQUEST_TRIGER 0xAA +#define EZUSB_REQUEST_TRIGGER 0xAA #define EZUSB_REQUEST_TRIG_AC 0xAC #define EZUSB_CPUCS_REG 0x7F92 @@ -1318,12 +1318,12 @@ static int ezusb_hard_reset(struct orinoco_private *priv) netdev_dbg(upriv->dev, "sending control message\n"); retval = usb_control_msg(upriv->udev, usb_sndctrlpipe(upriv->udev, 0), - EZUSB_REQUEST_TRIGER, + EZUSB_REQUEST_TRIGGER, USB_TYPE_VENDOR | USB_RECIP_DEVICE | USB_DIR_OUT, 0x0, 0x0, NULL, 0, DEF_TIMEOUT); if (retval < 0) { - err("EZUSB_REQUEST_TRIGER failed retval %d", retval); + err("EZUSB_REQUEST_TRIGGER failed retval %d", retval); return retval; } #if 0 diff --git a/drivers/net/wireless/marvell/mwifiex/cfg80211.c b/drivers/net/wireless/marvell/mwifiex/cfg80211.c index 4e4f59c17ded..96848fa0e417 100644 --- a/drivers/net/wireless/marvell/mwifiex/cfg80211.c +++ b/drivers/net/wireless/marvell/mwifiex/cfg80211.c @@ -27,7 +27,8 @@ module_param(reg_alpha2, charp, 0); static const struct ieee80211_iface_limit mwifiex_ap_sta_limits[] = { { - .max = 3, .types = BIT(NL80211_IFTYPE_STATION) | + .max = MWIFIEX_MAX_BSS_NUM, + .types = BIT(NL80211_IFTYPE_STATION) | BIT(NL80211_IFTYPE_P2P_GO) | BIT(NL80211_IFTYPE_P2P_CLIENT) | BIT(NL80211_IFTYPE_AP), @@ -3726,11 +3727,11 @@ mwifiex_cfg80211_tdls_mgmt(struct wiphy *wiphy, struct net_device *dev, int ret; if (!(wiphy->flags & WIPHY_FLAG_SUPPORTS_TDLS)) - return -ENOTSUPP; + return -EOPNOTSUPP; /* make sure we are in station mode and connected */ if (!(priv->bss_type == MWIFIEX_BSS_TYPE_STA && priv->media_connected)) - return -ENOTSUPP; + return -EOPNOTSUPP; switch (action_code) { case WLAN_TDLS_SETUP_REQUEST: @@ -3798,11 +3799,11 @@ mwifiex_cfg80211_tdls_oper(struct wiphy *wiphy, struct net_device *dev, if (!(wiphy->flags & WIPHY_FLAG_SUPPORTS_TDLS) || !(wiphy->flags & WIPHY_FLAG_TDLS_EXTERNAL_SETUP)) - return -ENOTSUPP; + return -EOPNOTSUPP; /* make sure we are in station mode and connected */ if (!(priv->bss_type == MWIFIEX_BSS_TYPE_STA && priv->media_connected)) - return -ENOTSUPP; + return -EOPNOTSUPP; mwifiex_dbg(priv->adapter, MSG, "TDLS peer=%pM, oper=%d\n", peer, action); @@ -3832,7 +3833,7 @@ mwifiex_cfg80211_tdls_oper(struct wiphy *wiphy, struct net_device *dev, default: mwifiex_dbg(priv->adapter, ERROR, "tdls_oper: operation not supported\n"); - return -ENOTSUPP; + return -EOPNOTSUPP; } return mwifiex_tdls_oper(priv, peer, action); @@ -3913,11 +3914,11 @@ mwifiex_cfg80211_add_station(struct wiphy *wiphy, struct net_device *dev, struct mwifiex_private *priv = mwifiex_netdev_get_priv(dev); if (!(params->sta_flags_set & BIT(NL80211_STA_FLAG_TDLS_PEER))) - return -ENOTSUPP; + return -EOPNOTSUPP; /* make sure we are in station mode and connected */ if ((priv->bss_type != MWIFIEX_BSS_TYPE_STA) || !priv->media_connected) - return -ENOTSUPP; + return -EOPNOTSUPP; return mwifiex_tdls_oper(priv, mac, MWIFIEX_TDLS_CREATE_LINK); } @@ -4150,11 +4151,11 @@ mwifiex_cfg80211_change_station(struct wiphy *wiphy, struct net_device *dev, /* we support change_station handler only for TDLS peers*/ if (!(params->sta_flags_set & BIT(NL80211_STA_FLAG_TDLS_PEER))) - return -ENOTSUPP; + return -EOPNOTSUPP; /* make sure we are in station mode and connected */ if ((priv->bss_type != MWIFIEX_BSS_TYPE_STA) || !priv->media_connected) - return -ENOTSUPP; + return -EOPNOTSUPP; priv->sta_params = params; diff --git a/drivers/net/wireless/marvell/mwifiex/main.c b/drivers/net/wireless/marvell/mwifiex/main.c index 529099137644..9ee5600351a7 100644 --- a/drivers/net/wireless/marvell/mwifiex/main.c +++ b/drivers/net/wireless/marvell/mwifiex/main.c @@ -953,7 +953,7 @@ int mwifiex_set_mac_address(struct mwifiex_private *priv, } else { /* Internal mac address change */ if (priv->bss_type == MWIFIEX_BSS_TYPE_ANY) - return -ENOTSUPP; + return -EOPNOTSUPP; mac_addr = old_mac_addr; diff --git a/drivers/net/wireless/marvell/mwifiex/sta_cmd.c b/drivers/net/wireless/marvell/mwifiex/sta_cmd.c index 8bd355d7974e..d3a968ef21ef 100644 --- a/drivers/net/wireless/marvell/mwifiex/sta_cmd.c +++ b/drivers/net/wireless/marvell/mwifiex/sta_cmd.c @@ -1723,7 +1723,7 @@ mwifiex_cmd_tdls_config(struct mwifiex_private *priv, default: mwifiex_dbg(priv->adapter, ERROR, "Unknown TDLS configuration\n"); - return -ENOTSUPP; + return -EOPNOTSUPP; } le16_unaligned_add_cpu(&cmd->size, len); @@ -1849,7 +1849,7 @@ mwifiex_cmd_tdls_oper(struct mwifiex_private *priv, break; default: mwifiex_dbg(priv->adapter, ERROR, "Unknown TDLS operation\n"); - return -ENOTSUPP; + return -EOPNOTSUPP; } le16_unaligned_add_cpu(&cmd->size, config_len); diff --git a/drivers/net/wireless/marvell/mwifiex/sta_cmdresp.c b/drivers/net/wireless/marvell/mwifiex/sta_cmdresp.c index f21660149f58..962d8bfe6f10 100644 --- a/drivers/net/wireless/marvell/mwifiex/sta_cmdresp.c +++ b/drivers/net/wireless/marvell/mwifiex/sta_cmdresp.c @@ -580,6 +580,11 @@ static int mwifiex_ret_802_11_key_material_v1(struct mwifiex_private *priv, { struct host_cmd_ds_802_11_key_material *key = &resp->params.key_material; + int len; + + len = le16_to_cpu(key->key_param_set.key_len); + if (len > sizeof(key->key_param_set.key)) + return -EINVAL; if (le16_to_cpu(key->action) == HostCmd_ACT_GEN_SET) { if ((le16_to_cpu(key->key_param_set.key_info) & KEY_MCAST)) { @@ -593,9 +598,8 @@ static int mwifiex_ret_802_11_key_material_v1(struct mwifiex_private *priv, memset(priv->aes_key.key_param_set.key, 0, sizeof(key->key_param_set.key)); - priv->aes_key.key_param_set.key_len = key->key_param_set.key_len; - memcpy(priv->aes_key.key_param_set.key, key->key_param_set.key, - le16_to_cpu(priv->aes_key.key_param_set.key_len)); + priv->aes_key.key_param_set.key_len = cpu_to_le16(len); + memcpy(priv->aes_key.key_param_set.key, key->key_param_set.key, len); return 0; } @@ -610,9 +614,14 @@ static int mwifiex_ret_802_11_key_material_v2(struct mwifiex_private *priv, struct host_cmd_ds_command *resp) { struct host_cmd_ds_802_11_key_material_v2 *key_v2; - __le16 len; + int len; key_v2 = &resp->params.key_material_v2; + + len = le16_to_cpu(key_v2->key_param_set.key_params.aes.key_len); + if (len > WLAN_KEY_LEN_CCMP) + return -EINVAL; + if (le16_to_cpu(key_v2->action) == HostCmd_ACT_GEN_SET) { if ((le16_to_cpu(key_v2->key_param_set.key_info) & KEY_MCAST)) { mwifiex_dbg(priv->adapter, INFO, "info: key: GTK is set\n"); @@ -628,10 +637,9 @@ static int mwifiex_ret_802_11_key_material_v2(struct mwifiex_private *priv, memset(priv->aes_key_v2.key_param_set.key_params.aes.key, 0, WLAN_KEY_LEN_CCMP); priv->aes_key_v2.key_param_set.key_params.aes.key_len = - key_v2->key_param_set.key_params.aes.key_len; - len = priv->aes_key_v2.key_param_set.key_params.aes.key_len; + cpu_to_le16(len); memcpy(priv->aes_key_v2.key_param_set.key_params.aes.key, - key_v2->key_param_set.key_params.aes.key, le16_to_cpu(len)); + key_v2->key_param_set.key_params.aes.key, len); return 0; } diff --git a/drivers/net/wireless/microchip/Kconfig b/drivers/net/wireless/microchip/Kconfig new file mode 100644 index 000000000000..a6b46fb6b1ec --- /dev/null +++ b/drivers/net/wireless/microchip/Kconfig @@ -0,0 +1,15 @@ +# SPDX-License-Identifier: GPL-2.0 +config WLAN_VENDOR_MICROCHIP + bool "Microchip 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_MICROCHIP +source "drivers/net/wireless/microchip/wilc1000/Kconfig" +endif # WLAN_VENDOR_MICROCHIP diff --git a/drivers/net/wireless/microchip/Makefile b/drivers/net/wireless/microchip/Makefile new file mode 100644 index 000000000000..73b763c7393e --- /dev/null +++ b/drivers/net/wireless/microchip/Makefile @@ -0,0 +1,2 @@ +# SPDX-License-Identifier: GPL-2.0 +obj-$(CONFIG_WILC1000) += wilc1000/ diff --git a/drivers/staging/wilc1000/Kconfig b/drivers/net/wireless/microchip/wilc1000/Kconfig index 80c92e8bf8a5..80c92e8bf8a5 100644 --- a/drivers/staging/wilc1000/Kconfig +++ b/drivers/net/wireless/microchip/wilc1000/Kconfig diff --git a/drivers/staging/wilc1000/Makefile b/drivers/net/wireless/microchip/wilc1000/Makefile index a3305a0a888a..c3c9e34c1eaa 100644 --- a/drivers/staging/wilc1000/Makefile +++ b/drivers/net/wireless/microchip/wilc1000/Makefile @@ -1,9 +1,6 @@ # SPDX-License-Identifier: GPL-2.0 obj-$(CONFIG_WILC1000) += wilc1000.o -ccflags-y += -DFIRMWARE_1002=\"atmel/wilc1002_firmware.bin\" \ - -DFIRMWARE_1003=\"atmel/wilc1003_firmware.bin\" - wilc1000-objs := cfg80211.o netdev.o mon.o \ hif.o wlan_cfg.o wlan.o diff --git a/drivers/staging/wilc1000/cfg80211.c b/drivers/net/wireless/microchip/wilc1000/cfg80211.c index b6065a0d660f..c1ac1d84790f 100644 --- a/drivers/staging/wilc1000/cfg80211.c +++ b/drivers/net/wireless/microchip/wilc1000/cfg80211.c @@ -46,9 +46,11 @@ static const struct ieee80211_txrx_stypes } }; +#ifdef CONFIG_PM static const struct wiphy_wowlan_support wowlan_support = { .flags = WIPHY_WOWLAN_ANY }; +#endif struct wilc_p2p_mgmt_data { int size; diff --git a/drivers/staging/wilc1000/cfg80211.h b/drivers/net/wireless/microchip/wilc1000/cfg80211.h index 37b294cb3b37..37b294cb3b37 100644 --- a/drivers/staging/wilc1000/cfg80211.h +++ b/drivers/net/wireless/microchip/wilc1000/cfg80211.h diff --git a/drivers/staging/wilc1000/fw.h b/drivers/net/wireless/microchip/wilc1000/fw.h index a76e1dea4345..a76e1dea4345 100644 --- a/drivers/staging/wilc1000/fw.h +++ b/drivers/net/wireless/microchip/wilc1000/fw.h diff --git a/drivers/staging/wilc1000/hif.c b/drivers/net/wireless/microchip/wilc1000/hif.c index d025a3093015..d025a3093015 100644 --- a/drivers/staging/wilc1000/hif.c +++ b/drivers/net/wireless/microchip/wilc1000/hif.c diff --git a/drivers/staging/wilc1000/hif.h b/drivers/net/wireless/microchip/wilc1000/hif.h index db9179171f05..db9179171f05 100644 --- a/drivers/staging/wilc1000/hif.h +++ b/drivers/net/wireless/microchip/wilc1000/hif.h diff --git a/drivers/staging/wilc1000/mon.c b/drivers/net/wireless/microchip/wilc1000/mon.c index 60331417bd98..358ac8601333 100644 --- a/drivers/staging/wilc1000/mon.c +++ b/drivers/net/wireless/microchip/wilc1000/mon.c @@ -229,8 +229,7 @@ struct net_device *wilc_wfi_init_mon_interface(struct wilc *wl, return NULL; wl->monitor_dev->type = ARPHRD_IEEE80211_RADIOTAP; - strncpy(wl->monitor_dev->name, name, IFNAMSIZ); - wl->monitor_dev->name[IFNAMSIZ - 1] = 0; + strlcpy(wl->monitor_dev->name, name, IFNAMSIZ); wl->monitor_dev->netdev_ops = &wilc_wfi_netdev_ops; wl->monitor_dev->needs_free_netdev = true; diff --git a/drivers/staging/wilc1000/netdev.c b/drivers/net/wireless/microchip/wilc1000/netdev.c index fda0ab97b02c..20615c7ec168 100644 --- a/drivers/staging/wilc1000/netdev.c +++ b/drivers/net/wireless/microchip/wilc1000/netdev.c @@ -15,6 +15,13 @@ #define WILC_MULTICAST_TABLE_SIZE 8 +/* latest API version supported */ +#define WILC1000_API_VER 1 + +#define WILC1000_FW_PREFIX "atmel/wilc1000_wifi_firmware-" +#define __WILC1000_FW(api) WILC1000_FW_PREFIX #api ".bin" +#define WILC1000_FW(api) __WILC1000_FW(api) + static irqreturn_t isr_uh_routine(int irq, void *user_data) { struct net_device *dev = user_data; @@ -176,23 +183,22 @@ static int wilc_wlan_get_firmware(struct net_device *dev) struct wilc_vif *vif = netdev_priv(dev); struct wilc *wilc = vif->wilc; int chip_id; - const struct firmware *wilc_firmware; - char *firmware; + const struct firmware *wilc_fw; + int ret; chip_id = wilc_get_chipid(wilc, false); - if (chip_id < 0x1003a0) - firmware = FIRMWARE_1002; - else - firmware = FIRMWARE_1003; - - netdev_info(dev, "loading firmware %s\n", firmware); + netdev_info(dev, "ChipID [%x] loading firmware [%s]\n", chip_id, + WILC1000_FW(WILC1000_API_VER)); - if (request_firmware(&wilc_firmware, firmware, wilc->dev) != 0) { - netdev_err(dev, "%s - firmware not available\n", firmware); + ret = request_firmware(&wilc_fw, WILC1000_FW(WILC1000_API_VER), + wilc->dev); + if (ret != 0) { + netdev_err(dev, "%s - firmware not available\n", + WILC1000_FW(WILC1000_API_VER)); return -EINVAL; } - wilc->firmware = wilc_firmware; + wilc->firmware = wilc_fw; return 0; } @@ -678,14 +684,14 @@ netdev_tx_t wilc_mac_xmit(struct sk_buff *skb, struct net_device *ndev) if (skb->dev != ndev) { netdev_err(ndev, "Packet not destined to this device\n"); - return 0; + return NETDEV_TX_OK; } tx_data = kmalloc(sizeof(*tx_data), GFP_ATOMIC); if (!tx_data) { dev_kfree_skb(skb); netif_wake_queue(ndev); - return 0; + return NETDEV_TX_OK; } tx_data->buff = skb->data; @@ -710,7 +716,7 @@ netdev_tx_t wilc_mac_xmit(struct sk_buff *skb, struct net_device *ndev) srcu_read_unlock(&wilc->srcu, srcu_idx); } - return 0; + return NETDEV_TX_OK; } static int wilc_mac_close(struct net_device *ndev) @@ -929,3 +935,4 @@ struct wilc_vif *wilc_netdev_ifc_init(struct wilc *wl, const char *name, } MODULE_LICENSE("GPL"); +MODULE_FIRMWARE(WILC1000_FW(WILC1000_API_VER)); diff --git a/drivers/staging/wilc1000/netdev.h b/drivers/net/wireless/microchip/wilc1000/netdev.h index d0a006b68d08..d0a006b68d08 100644 --- a/drivers/staging/wilc1000/netdev.h +++ b/drivers/net/wireless/microchip/wilc1000/netdev.h diff --git a/drivers/staging/wilc1000/sdio.c b/drivers/net/wireless/microchip/wilc1000/sdio.c index 36eb589263bf..36eb589263bf 100644 --- a/drivers/staging/wilc1000/sdio.c +++ b/drivers/net/wireless/microchip/wilc1000/sdio.c diff --git a/drivers/staging/wilc1000/spi.c b/drivers/net/wireless/microchip/wilc1000/spi.c index 3f19e3f38a39..3f19e3f38a39 100644 --- a/drivers/staging/wilc1000/spi.c +++ b/drivers/net/wireless/microchip/wilc1000/spi.c diff --git a/drivers/staging/wilc1000/wlan.c b/drivers/net/wireless/microchip/wilc1000/wlan.c index 6a82fb2f283e..6a82fb2f283e 100644 --- a/drivers/staging/wilc1000/wlan.c +++ b/drivers/net/wireless/microchip/wilc1000/wlan.c diff --git a/drivers/staging/wilc1000/wlan.h b/drivers/net/wireless/microchip/wilc1000/wlan.h index 7689569cd82f..7689569cd82f 100644 --- a/drivers/staging/wilc1000/wlan.h +++ b/drivers/net/wireless/microchip/wilc1000/wlan.h diff --git a/drivers/staging/wilc1000/wlan_cfg.c b/drivers/net/wireless/microchip/wilc1000/wlan_cfg.c index fe2a7ed8e5cd..fe2a7ed8e5cd 100644 --- a/drivers/staging/wilc1000/wlan_cfg.c +++ b/drivers/net/wireless/microchip/wilc1000/wlan_cfg.c diff --git a/drivers/staging/wilc1000/wlan_cfg.h b/drivers/net/wireless/microchip/wilc1000/wlan_cfg.h index 614c5673f232..614c5673f232 100644 --- a/drivers/staging/wilc1000/wlan_cfg.h +++ b/drivers/net/wireless/microchip/wilc1000/wlan_cfg.h diff --git a/drivers/staging/wilc1000/wlan_if.h b/drivers/net/wireless/microchip/wilc1000/wlan_if.h index f85fd575136d..f85fd575136d 100644 --- a/drivers/staging/wilc1000/wlan_if.h +++ b/drivers/net/wireless/microchip/wilc1000/wlan_if.h diff --git a/drivers/net/wireless/realtek/rtl818x/rtl8180/dev.c b/drivers/net/wireless/realtek/rtl818x/rtl8180/dev.c index d5f65372356b..ba3286f732cc 100644 --- a/drivers/net/wireless/realtek/rtl818x/rtl8180/dev.c +++ b/drivers/net/wireless/realtek/rtl818x/rtl8180/dev.c @@ -1966,32 +1966,17 @@ static void rtl8180_remove(struct pci_dev *pdev) ieee80211_free_hw(dev); } -#ifdef CONFIG_PM -static int rtl8180_suspend(struct pci_dev *pdev, pm_message_t state) -{ - pci_save_state(pdev); - pci_set_power_state(pdev, pci_choose_state(pdev, state)); - return 0; -} - -static int rtl8180_resume(struct pci_dev *pdev) -{ - pci_set_power_state(pdev, PCI_D0); - pci_restore_state(pdev); - return 0; -} +#define rtl8180_suspend NULL +#define rtl8180_resume NULL -#endif /* CONFIG_PM */ +static SIMPLE_DEV_PM_OPS(rtl8180_pm_ops, rtl8180_suspend, rtl8180_resume); static struct pci_driver rtl8180_driver = { .name = KBUILD_MODNAME, .id_table = rtl8180_table, .probe = rtl8180_probe, .remove = rtl8180_remove, -#ifdef CONFIG_PM - .suspend = rtl8180_suspend, - .resume = rtl8180_resume, -#endif /* CONFIG_PM */ + .driver.pm = &rtl8180_pm_ops, }; module_pci_driver(rtl8180_driver); diff --git a/drivers/net/wireless/realtek/rtlwifi/ps.c b/drivers/net/wireless/realtek/rtlwifi/ps.c index bc0ac96ee615..90f92728e16a 100644 --- a/drivers/net/wireless/realtek/rtlwifi/ps.c +++ b/drivers/net/wireless/realtek/rtlwifi/ps.c @@ -769,13 +769,13 @@ static void rtl_p2p_noa_ie(struct ieee80211_hw *hw, void *data, *(u8 *)(ie + index); index += 1; p2pinfo->noa_duration[i] = - le32_to_cpu(*(__le32 *)ie + index); + le32_to_cpu(*(__le32 *)(ie + index)); index += 4; p2pinfo->noa_interval[i] = - le32_to_cpu(*(__le32 *)ie + index); + le32_to_cpu(*(__le32 *)(ie + index)); index += 4; p2pinfo->noa_start_time[i] = - le32_to_cpu(*(__le32 *)ie + index); + le32_to_cpu(*(__le32 *)(ie + index)); index += 4; } @@ -864,13 +864,13 @@ static void rtl_p2p_action_ie(struct ieee80211_hw *hw, void *data, *(u8 *)(ie + index); index += 1; p2pinfo->noa_duration[i] = - le32_to_cpu(*(__le32 *)ie + index); + le32_to_cpu(*(__le32 *)(ie + index)); index += 4; p2pinfo->noa_interval[i] = - le32_to_cpu(*(__le32 *)ie + index); + le32_to_cpu(*(__le32 *)(ie + index)); index += 4; p2pinfo->noa_start_time[i] = - le32_to_cpu(*(__le32 *)ie + index); + le32_to_cpu(*(__le32 *)(ie + index)); index += 4; } diff --git a/drivers/net/wireless/realtek/rtlwifi/rtl8188ee/dm.c b/drivers/net/wireless/realtek/rtlwifi/rtl8188ee/dm.c index dceb04a9b3f5..1ffa188a65c9 100644 --- a/drivers/net/wireless/realtek/rtlwifi/rtl8188ee/dm.c +++ b/drivers/net/wireless/realtek/rtlwifi/rtl8188ee/dm.c @@ -870,11 +870,11 @@ static void dm_txpower_track_cb_therm(struct ieee80211_hw *hw) /*0.1 the following TWO tables decide the *final index of OFDM/CCK swing table */ - s8 delta_swing_table_idx[2][15] = { + static const s8 delta_swing_table_idx[2][15] = { {0, 0, 2, 3, 4, 4, 5, 6, 7, 7, 8, 9, 10, 10, 11}, {0, 0, -1, -2, -3, -4, -4, -4, -4, -5, -7, -8, -9, -9, -10} }; - u8 thermal_threshold[2][15] = { + static const u8 thermal_threshold[2][15] = { {0, 2, 4, 6, 8, 10, 12, 14, 16, 18, 20, 22, 24, 26, 27}, {0, 2, 4, 6, 8, 10, 12, 14, 16, 18, 20, 22, 25, 25, 25} }; diff --git a/drivers/net/wireless/realtek/rtlwifi/rtl8188ee/trx.c b/drivers/net/wireless/realtek/rtlwifi/rtl8188ee/trx.c index aa2e9e88be53..a5d2d6ece8db 100644 --- a/drivers/net/wireless/realtek/rtlwifi/rtl8188ee/trx.c +++ b/drivers/net/wireless/realtek/rtlwifi/rtl8188ee/trx.c @@ -497,7 +497,7 @@ void rtl88ee_tx_fill_desc(struct ieee80211_hw *hw, dma_addr_t mapping; u8 bw_40 = 0; u8 short_gi = 0; - __le32 *pdesc = (u32 *)pdesc8; + __le32 *pdesc = (__le32 *)pdesc8; if (mac->opmode == NL80211_IFTYPE_STATION) { bw_40 = mac->bw_40; diff --git a/drivers/net/wireless/realtek/rtlwifi/rtl8192cu/hw.c b/drivers/net/wireless/realtek/rtlwifi/rtl8192cu/hw.c index f070f25bb735..5b071b70bc08 100644 --- a/drivers/net/wireless/realtek/rtlwifi/rtl8192cu/hw.c +++ b/drivers/net/wireless/realtek/rtlwifi/rtl8192cu/hw.c @@ -592,7 +592,7 @@ static void _rtl92cu_init_chipn_one_out_ep_priority(struct ieee80211_hw *hw, bool wmm_enable, u8 queue_sel) { - u16 uninitialized_var(value); + u16 value; switch (queue_sel) { case TX_SELE_HQ: @@ -606,7 +606,7 @@ static void _rtl92cu_init_chipn_one_out_ep_priority(struct ieee80211_hw *hw, break; default: WARN_ON(1); /* Shall not reach here! */ - break; + return; } _rtl92c_init_chipn_reg_priority(hw, value, value, value, value, value, value); diff --git a/drivers/net/wireless/realtek/rtlwifi/rtl8723be/dm.c b/drivers/net/wireless/realtek/rtlwifi/rtl8723be/dm.c index b13fd3c0c832..c9b3d9d09c48 100644 --- a/drivers/net/wireless/realtek/rtlwifi/rtl8723be/dm.c +++ b/drivers/net/wireless/realtek/rtlwifi/rtl8723be/dm.c @@ -736,11 +736,11 @@ static void rtl8723be_dm_txpower_tracking_callback_thermalmeter( u8 ofdm_min_index = 6; u8 index_for_channel = 0; - s8 delta_swing_table_idx_tup_a[TXSCALE_TABLE_SIZE] = { + static const s8 delta_swing_table_idx_tup_a[TXSCALE_TABLE_SIZE] = { 0, 0, 1, 2, 2, 2, 3, 3, 3, 4, 5, 5, 6, 6, 7, 7, 8, 8, 9, 9, 9, 10, 10, 11, 11, 12, 12, 13, 14, 15}; - s8 delta_swing_table_idx_tdown_a[TXSCALE_TABLE_SIZE] = { + static const s8 delta_swing_table_idx_tdown_a[TXSCALE_TABLE_SIZE] = { 0, 0, 1, 2, 2, 2, 3, 3, 3, 4, 5, 5, 6, 6, 6, 6, 7, 7, 7, 8, 8, 9, 9, 10, 10, 11, 12, 13, 14, 15}; diff --git a/drivers/net/wireless/realtek/rtlwifi/rtl8821ae/dm.c b/drivers/net/wireless/realtek/rtlwifi/rtl8821ae/dm.c index f57e8794f0ec..97a30ccf0b27 100644 --- a/drivers/net/wireless/realtek/rtlwifi/rtl8821ae/dm.c +++ b/drivers/net/wireless/realtek/rtlwifi/rtl8821ae/dm.c @@ -115,47 +115,47 @@ static const u32 edca_setting_ul[PEER_MAX] = { 0x5ea44f, /* 7 MARV */ }; -static u8 rtl8818e_delta_swing_table_idx_24gb_p[] = { +static const u8 rtl8818e_delta_swing_table_idx_24gb_p[] = { 0, 0, 0, 0, 1, 1, 2, 2, 3, 3, 4, 4, 4, 4, 4, 4, 4, 4, 5, 5, 7, 7, 8, 8, 8, 9, 9, 9, 9, 9}; -static u8 rtl8818e_delta_swing_table_idx_24gb_n[] = { +static const u8 rtl8818e_delta_swing_table_idx_24gb_n[] = { 0, 0, 0, 2, 2, 3, 3, 4, 4, 4, 4, 5, 5, 6, 6, 7, 7, 7, 7, 8, 8, 9, 9, 10, 10, 10, 11, 11, 11, 11}; -static u8 rtl8812ae_delta_swing_table_idx_24gb_n[] = { +static const u8 rtl8812ae_delta_swing_table_idx_24gb_n[] = { 0, 1, 1, 1, 2, 2, 2, 3, 3, 3, 4, 4, 5, 5, 5, 6, 6, 6, 7, 8, 9, 9, 9, 9, 10, 10, 10, 10, 11, 11}; -static u8 rtl8812ae_delta_swing_table_idx_24gb_p[] = { +static const u8 rtl8812ae_delta_swing_table_idx_24gb_p[] = { 0, 0, 1, 1, 2, 2, 2, 2, 3, 3, 3, 4, 4, 5, 5, 6, 6, 6, 7, 7, 7, 8, 8, 8, 9, 9, 9, 9, 9, 9}; -static u8 rtl8812ae_delta_swing_table_idx_24ga_n[] = { +static const u8 rtl8812ae_delta_swing_table_idx_24ga_n[] = { 0, 1, 1, 1, 2, 2, 2, 3, 3, 3, 4, 4, 5, 5, 5, 6, 6, 6, 7, 8, 8, 9, 9, 9, 10, 10, 10, 10, 11, 11}; -static u8 rtl8812ae_delta_swing_table_idx_24ga_p[] = { +static const u8 rtl8812ae_delta_swing_table_idx_24ga_p[] = { 0, 0, 1, 1, 2, 2, 2, 2, 3, 3, 3, 4, 4, 5, 5, 6, 6, 6, 7, 7, 7, 8, 8, 8, 9, 9, 9, 9, 9, 9}; -static u8 rtl8812ae_delta_swing_table_idx_24gcckb_n[] = { +static const u8 rtl8812ae_delta_swing_table_idx_24gcckb_n[] = { 0, 1, 1, 1, 2, 2, 2, 3, 3, 3, 4, 4, 5, 5, 5, 6, 6, 6, 7, 8, 9, 9, 9, 9, 10, 10, 10, 10, 11, 11}; -static u8 rtl8812ae_delta_swing_table_idx_24gcckb_p[] = { +static const u8 rtl8812ae_delta_swing_table_idx_24gcckb_p[] = { 0, 0, 1, 1, 2, 2, 2, 2, 3, 3, 3, 4, 4, 5, 5, 6, 6, 6, 7, 7, 7, 8, 8, 8, 9, 9, 9, 9, 9, 9}; -static u8 rtl8812ae_delta_swing_table_idx_24gccka_n[] = { +static const u8 rtl8812ae_delta_swing_table_idx_24gccka_n[] = { 0, 1, 1, 1, 2, 2, 2, 3, 3, 3, 4, 4, 5, 5, 5, 6, 6, 6, 7, 8, 8, 9, 9, 9, 10, 10, 10, 10, 11, 11}; -static u8 rtl8812ae_delta_swing_table_idx_24gccka_p[] = { +static const u8 rtl8812ae_delta_swing_table_idx_24gccka_p[] = { 0, 0, 1, 1, 2, 2, 2, 2, 3, 3, 3, 4, 4, 5, 5, 6, 6, 6, 7, 7, 7, 8, 8, 8, 9, 9, 9, 9, 9, 9}; -static u8 rtl8812ae_delta_swing_table_idx_5gb_n[][DEL_SW_IDX_SZ] = { +static const u8 rtl8812ae_delta_swing_table_idx_5gb_n[][DEL_SW_IDX_SZ] = { {0, 1, 1, 2, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 6, 7, 7, 7, 8, 8, 9, 9, 9, 10, 10, 11, 11, 12, 12, 13}, {0, 1, 1, 2, 2, 2, 3, 3, 4, 4, 4, 5, 5, 6, 6, 7, @@ -164,7 +164,7 @@ static u8 rtl8812ae_delta_swing_table_idx_5gb_n[][DEL_SW_IDX_SZ] = { 12, 12, 13, 14, 14, 14, 15, 16, 17, 17, 17, 18, 18, 18}, }; -static u8 rtl8812ae_delta_swing_table_idx_5gb_p[][DEL_SW_IDX_SZ] = { +static const u8 rtl8812ae_delta_swing_table_idx_5gb_p[][DEL_SW_IDX_SZ] = { {0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 6, 7, 7, 8, 8, 9, 9, 10, 10, 11, 11, 11, 11, 11, 11, 11, 11}, {0, 1, 1, 2, 2, 3, 3, 4, 4, 4, 5, 5, 6, 6, 7, 7, 8, @@ -173,7 +173,7 @@ static u8 rtl8812ae_delta_swing_table_idx_5gb_p[][DEL_SW_IDX_SZ] = { 9, 10, 10, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11}, }; -static u8 rtl8812ae_delta_swing_table_idx_5ga_n[][DEL_SW_IDX_SZ] = { +static const u8 rtl8812ae_delta_swing_table_idx_5ga_n[][DEL_SW_IDX_SZ] = { {0, 1, 1, 2, 2, 3, 3, 4, 4, 4, 5, 5, 6, 6, 7, 7, 8, 8, 9, 9, 10, 10, 11, 11, 12, 12, 12, 13, 13, 13}, {0, 1, 1, 2, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7, 8, 9, @@ -182,7 +182,7 @@ static u8 rtl8812ae_delta_swing_table_idx_5ga_n[][DEL_SW_IDX_SZ] = { 12, 13, 14, 14, 15, 15, 15, 16, 16, 16, 17, 17, 18, 18}, }; -static u8 rtl8812ae_delta_swing_table_idx_5ga_p[][DEL_SW_IDX_SZ] = { +static const u8 rtl8812ae_delta_swing_table_idx_5ga_p[][DEL_SW_IDX_SZ] = { {0, 1, 1, 2, 2, 3, 3, 4, 4, 4, 4, 5, 5, 6, 7, 7, 8, 8, 9, 9, 10, 10, 11, 11, 11, 11, 11, 11, 11, 11}, {0, 1, 1, 2, 2, 3, 3, 4, 4, 4, 5, 5, 6, 6, 7, 7, 8, @@ -191,57 +191,23 @@ static u8 rtl8812ae_delta_swing_table_idx_5ga_p[][DEL_SW_IDX_SZ] = { 10, 10, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11}, }; -static u8 rtl8821ae_delta_swing_table_idx_24gb_n[] = { +static const u8 rtl8821ae_delta_swing_table_idx_24ga_n[] = { 0, 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, 10}; -static u8 rtl8821ae_delta_swing_table_idx_24gb_p[] = { +static const u8 rtl8821ae_delta_swing_table_idx_24ga_p[] = { 0, 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7, 7, 8, 8, 9, 9, 10, 10, 11, 11, 12, 12, 12, 12, 12, 12}; -static u8 rtl8821ae_delta_swing_table_idx_24ga_n[] = { +static const u8 rtl8821ae_delta_swing_table_idx_24gccka_n[] = { 0, 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, 10}; -static u8 rtl8821ae_delta_swing_table_idx_24ga_p[] = { +static const u8 rtl8821ae_delta_swing_table_idx_24gccka_p[] = { 0, 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7, 7, 8, 8, 9, 9, 10, 10, 11, 11, 12, 12, 12, 12, 12, 12}; -static u8 rtl8821ae_delta_swing_table_idx_24gcckb_n[] = { - 0, 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, 10}; - -static u8 rtl8821ae_delta_swing_table_idx_24gcckb_p[] = { - 0, 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7, 7, 8, - 8, 9, 9, 10, 10, 11, 11, 12, 12, 12, 12, 12, 12}; - -static u8 rtl8821ae_delta_swing_table_idx_24gccka_n[] = { - 0, 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, 10}; - -static u8 rtl8821ae_delta_swing_table_idx_24gccka_p[] = { - 0, 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7, 7, 8, - 8, 9, 9, 10, 10, 11, 11, 12, 12, 12, 12, 12, 12}; - -static u8 rtl8821ae_delta_swing_table_idx_5gb_n[][DEL_SW_IDX_SZ] = { - {0, 0, 1, 2, 3, 3, 4, 5, 6, 6, 7, 8, 9, 9, 10, 11, - 12, 12, 13, 14, 15, 15, 16, 16, 16, 16, 16, 16, 16, 16}, - {0, 0, 1, 2, 3, 3, 4, 5, 6, 6, 7, 8, 9, 9, 10, 11, - 12, 12, 13, 14, 15, 15, 16, 16, 16, 16, 16, 16, 16, 16}, - {0, 0, 1, 2, 3, 3, 4, 5, 6, 6, 7, 8, 9, 9, 10, 11, - 12, 12, 13, 14, 15, 15, 16, 16, 16, 16, 16, 16, 16, 16}, -}; - -static u8 rtl8821ae_delta_swing_table_idx_5gb_p[][DEL_SW_IDX_SZ] = { - {0, 0, 1, 2, 3, 3, 4, 5, 6, 6, 7, 8, 9, 9, 10, 11, - 12, 12, 13, 14, 15, 15, 16, 16, 16, 16, 16, 16, 16, 16}, - {0, 0, 1, 2, 3, 3, 4, 5, 6, 6, 7, 8, 9, 9, 10, 11, - 12, 12, 13, 14, 15, 15, 16, 16, 16, 16, 16, 16, 16, 16}, - {0, 0, 1, 2, 3, 3, 4, 5, 6, 6, 7, 8, 9, 9, 10, 11, - 12, 12, 13, 14, 15, 15, 16, 16, 16, 16, 16, 16, 16, 16}, -}; - -static u8 rtl8821ae_delta_swing_table_idx_5ga_n[][DEL_SW_IDX_SZ] = { +static const u8 rtl8821ae_delta_swing_table_idx_5ga_n[][DEL_SW_IDX_SZ] = { {0, 0, 1, 2, 3, 3, 4, 5, 6, 6, 7, 8, 9, 9, 10, 11, 12, 12, 13, 14, 15, 15, 16, 16, 16, 16, 16, 16, 16, 16}, {0, 0, 1, 2, 3, 3, 4, 5, 6, 6, 7, 8, 9, 9, 10, 11, @@ -250,7 +216,7 @@ static u8 rtl8821ae_delta_swing_table_idx_5ga_n[][DEL_SW_IDX_SZ] = { 12, 12, 13, 14, 15, 15, 16, 16, 16, 16, 16, 16, 16, 16}, }; -static u8 rtl8821ae_delta_swing_table_idx_5ga_p[][DEL_SW_IDX_SZ] = { +static const u8 rtl8821ae_delta_swing_table_idx_5ga_p[][DEL_SW_IDX_SZ] = { {0, 0, 1, 2, 3, 3, 4, 5, 6, 6, 7, 8, 9, 9, 10, 11, 12, 12, 13, 14, 15, 15, 16, 16, 16, 16, 16, 16, 16, 16}, {0, 0, 1, 2, 3, 3, 4, 5, 6, 6, 7, 8, 9, 9, 10, 11, @@ -962,8 +928,10 @@ static void rtl8821ae_dm_iq_calibrate(struct ieee80211_hw *hw) } static void rtl8812ae_get_delta_swing_table(struct ieee80211_hw *hw, - u8 **up_a, u8 **down_a, - u8 **up_b, u8 **down_b) + const u8 **up_a, + const u8 **down_a, + const u8 **up_b, + const u8 **down_b) { struct rtl_priv *rtlpriv = rtl_priv(hw); struct rtl_phy *rtlphy = &rtlpriv->phy; @@ -999,10 +967,10 @@ static void rtl8812ae_get_delta_swing_table(struct ieee80211_hw *hw, *up_b = rtl8812ae_delta_swing_table_idx_5gb_p[2]; *down_b = rtl8812ae_delta_swing_table_idx_5gb_n[2]; } else { - *up_a = (u8 *)rtl8818e_delta_swing_table_idx_24gb_p; - *down_a = (u8 *)rtl8818e_delta_swing_table_idx_24gb_n; - *up_b = (u8 *)rtl8818e_delta_swing_table_idx_24gb_p; - *down_b = (u8 *)rtl8818e_delta_swing_table_idx_24gb_n; + *up_a = rtl8818e_delta_swing_table_idx_24gb_p; + *down_a = rtl8818e_delta_swing_table_idx_24gb_n; + *up_b = rtl8818e_delta_swing_table_idx_24gb_p; + *down_b = rtl8818e_delta_swing_table_idx_24gb_n; } } @@ -1492,17 +1460,17 @@ void rtl8812ae_dm_txpower_tracking_callback_thermalmeter( /* 1. The following TWO tables decide * the final index of OFDM/CCK swing table. */ - u8 *delta_swing_table_idx_tup_a; - u8 *delta_swing_table_idx_tdown_a; - u8 *delta_swing_table_idx_tup_b; - u8 *delta_swing_table_idx_tdown_b; + const u8 *delta_swing_table_idx_tup_a; + const u8 *delta_swing_table_idx_tdown_a; + const u8 *delta_swing_table_idx_tup_b; + const u8 *delta_swing_table_idx_tdown_b; /*2. Initilization ( 7 steps in total )*/ rtl8812ae_get_delta_swing_table(hw, - (u8 **)&delta_swing_table_idx_tup_a, - (u8 **)&delta_swing_table_idx_tdown_a, - (u8 **)&delta_swing_table_idx_tup_b, - (u8 **)&delta_swing_table_idx_tdown_b); + &delta_swing_table_idx_tup_a, + &delta_swing_table_idx_tdown_a, + &delta_swing_table_idx_tup_b, + &delta_swing_table_idx_tdown_b); rtldm->txpower_trackinginit = true; @@ -1830,8 +1798,9 @@ void rtl8812ae_dm_txpower_tracking_callback_thermalmeter( "<===rtl8812ae_dm_txpower_tracking_callback_thermalmeter\n"); } -static void rtl8821ae_get_delta_swing_table(struct ieee80211_hw *hw, u8 **up_a, - u8 **down_a, u8 **up_b, u8 **down_b) +static void rtl8821ae_get_delta_swing_table(struct ieee80211_hw *hw, + const u8 **up_a, + const u8 **down_a) { struct rtl_priv *rtlpriv = rtl_priv(hw); struct rtl_phy *rtlphy = &rtlpriv->phy; @@ -1843,34 +1812,22 @@ static void rtl8821ae_get_delta_swing_table(struct ieee80211_hw *hw, u8 **up_a, if (RTL8821AE_RX_HAL_IS_CCK_RATE(rate)) { *up_a = rtl8821ae_delta_swing_table_idx_24gccka_p; *down_a = rtl8821ae_delta_swing_table_idx_24gccka_n; - *up_b = rtl8821ae_delta_swing_table_idx_24gcckb_p; - *down_b = rtl8821ae_delta_swing_table_idx_24gcckb_n; } else { *up_a = rtl8821ae_delta_swing_table_idx_24ga_p; *down_a = rtl8821ae_delta_swing_table_idx_24ga_n; - *up_b = rtl8821ae_delta_swing_table_idx_24gb_p; - *down_b = rtl8821ae_delta_swing_table_idx_24gb_n; } } else if (36 <= channel && channel <= 64) { *up_a = rtl8821ae_delta_swing_table_idx_5ga_p[0]; *down_a = rtl8821ae_delta_swing_table_idx_5ga_n[0]; - *up_b = rtl8821ae_delta_swing_table_idx_5gb_p[0]; - *down_b = rtl8821ae_delta_swing_table_idx_5gb_n[0]; } else if (100 <= channel && channel <= 140) { *up_a = rtl8821ae_delta_swing_table_idx_5ga_p[1]; *down_a = rtl8821ae_delta_swing_table_idx_5ga_n[1]; - *up_b = rtl8821ae_delta_swing_table_idx_5gb_p[1]; - *down_b = rtl8821ae_delta_swing_table_idx_5gb_n[1]; } else if (149 <= channel && channel <= 173) { *up_a = rtl8821ae_delta_swing_table_idx_5ga_p[2]; *down_a = rtl8821ae_delta_swing_table_idx_5ga_n[2]; - *up_b = rtl8821ae_delta_swing_table_idx_5gb_p[2]; - *down_b = rtl8821ae_delta_swing_table_idx_5gb_n[2]; } else { - *up_a = (u8 *)rtl8818e_delta_swing_table_idx_24gb_p; - *down_a = (u8 *)rtl8818e_delta_swing_table_idx_24gb_n; - *up_b = (u8 *)rtl8818e_delta_swing_table_idx_24gb_p; - *down_b = (u8 *)rtl8818e_delta_swing_table_idx_24gb_n; + *up_a = rtl8818e_delta_swing_table_idx_24gb_p; + *down_a = rtl8818e_delta_swing_table_idx_24gb_n; } return; } @@ -2075,16 +2032,13 @@ void rtl8821ae_dm_txpower_tracking_callback_thermalmeter( /* 1. The following TWO tables decide the final * index of OFDM/CCK swing table. */ - u8 *delta_swing_table_idx_tup_a; - u8 *delta_swing_table_idx_tdown_a; - u8 *delta_swing_table_idx_tup_b; - u8 *delta_swing_table_idx_tdown_b; + const u8 *delta_swing_table_idx_tup_a; + const u8 *delta_swing_table_idx_tdown_a; /*2. Initilization ( 7 steps in total )*/ - rtl8821ae_get_delta_swing_table(hw, (u8 **)&delta_swing_table_idx_tup_a, - (u8 **)&delta_swing_table_idx_tdown_a, - (u8 **)&delta_swing_table_idx_tup_b, - (u8 **)&delta_swing_table_idx_tdown_b); + rtl8821ae_get_delta_swing_table(hw, + &delta_swing_table_idx_tup_a, + &delta_swing_table_idx_tdown_a); rtldm->txpower_trackinginit = true; diff --git a/drivers/net/wireless/realtek/rtlwifi/usb.c b/drivers/net/wireless/realtek/rtlwifi/usb.c index c66c6dc00378..d05e709536ea 100644 --- a/drivers/net/wireless/realtek/rtlwifi/usb.c +++ b/drivers/net/wireless/realtek/rtlwifi/usb.c @@ -680,8 +680,10 @@ static void _rtl_usb_cleanup_rx(struct ieee80211_hw *hw) tasklet_kill(&rtlusb->rx_work_tasklet); cancel_work_sync(&rtlpriv->works.lps_change_work); - flush_workqueue(rtlpriv->works.rtl_wq); - destroy_workqueue(rtlpriv->works.rtl_wq); + if (rtlpriv->works.rtl_wq) { + destroy_workqueue(rtlpriv->works.rtl_wq); + rtlpriv->works.rtl_wq = NULL; + } skb_queue_purge(&rtlusb->rx_queue); @@ -718,8 +720,11 @@ static int _rtl_usb_receive(struct ieee80211_hw *hw) usb_anchor_urb(urb, &rtlusb->rx_submitted); err = usb_submit_urb(urb, GFP_KERNEL); - if (err) + if (err) { + usb_unanchor_urb(urb); + usb_free_urb(urb); goto err_out; + } usb_free_urb(urb); } return 0; @@ -1082,6 +1087,7 @@ error_out2: usb_put_dev(udev); complete(&rtlpriv->firmware_loading_complete); kfree(rtlpriv->usb_data); + ieee80211_free_hw(hw); return -ENODEV; } EXPORT_SYMBOL(rtl_usb_probe); diff --git a/drivers/net/wireless/realtek/rtw88/Kconfig b/drivers/net/wireless/realtek/rtw88/Kconfig index ca894c4f96ac..e3d7cb6c1290 100644 --- a/drivers/net/wireless/realtek/rtw88/Kconfig +++ b/drivers/net/wireless/realtek/rtw88/Kconfig @@ -25,6 +25,9 @@ config RTW88_8822C config RTW88_8723D tristate +config RTW88_8821C + tristate + config RTW88_8822BE tristate "Realtek 8822BE PCI wireless network adapter" depends on PCI @@ -58,6 +61,17 @@ config RTW88_8723DE 802.11n PCIe wireless network adapter +config RTW88_8821CE + tristate "Realtek 8821CE PCI wireless network adapter" + depends on PCI + select RTW88_CORE + select RTW88_PCI + select RTW88_8821C + help + Select this option will enable support for 8821CE chipset + + 802.11ac PCIe wireless network adapter + config RTW88_DEBUG bool "Realtek rtw88 debug support" depends on RTW88_CORE diff --git a/drivers/net/wireless/realtek/rtw88/Makefile b/drivers/net/wireless/realtek/rtw88/Makefile index f31e78a6f146..c0e4b111c8b4 100644 --- a/drivers/net/wireless/realtek/rtw88/Makefile +++ b/drivers/net/wireless/realtek/rtw88/Makefile @@ -37,5 +37,11 @@ rtw88_8723d-objs := rtw8723d.o rtw8723d_table.o obj-$(CONFIG_RTW88_8723DE) += rtw88_8723de.o rtw88_8723de-objs := rtw8723de.o +obj-$(CONFIG_RTW88_8821C) += rtw88_8821c.o +rtw88_8821c-objs := rtw8821c.o rtw8821c_table.o + +obj-$(CONFIG_RTW88_8821CE) += rtw88_8821ce.o +rtw88_8821ce-objs := rtw8821ce.o + obj-$(CONFIG_RTW88_PCI) += rtw88_pci.o rtw88_pci-objs := pci.o diff --git a/drivers/net/wireless/realtek/rtw88/bf.c b/drivers/net/wireless/realtek/rtw88/bf.c index 8a070d5d9174..aff70e4ae028 100644 --- a/drivers/net/wireless/realtek/rtw88/bf.c +++ b/drivers/net/wireless/realtek/rtw88/bf.c @@ -183,7 +183,7 @@ void rtw_bf_del_sounding(struct rtw_dev *rtwdev) void rtw_bf_enable_bfee_su(struct rtw_dev *rtwdev, struct rtw_vif *vif, struct rtw_bfee *bfee) { - u8 nc_index = 1; + u8 nc_index = hweight8(rtwdev->hal.antenna_rx) - 1; u8 nr_index = bfee->sound_dim; u8 grouping = 0, codebookinfo = 1, coefficientsize = 3; u32 addr_bfer_info, addr_csi_rpt, csi_param; @@ -231,7 +231,8 @@ void rtw_bf_enable_bfee_mu(struct rtw_dev *rtwdev, struct rtw_vif *vif, { struct rtw_bf_info *bf_info = &rtwdev->bf_info; struct mu_bfer_init_para param; - u8 nc_index = 1, nr_index = 1; + u8 nc_index = hweight8(rtwdev->hal.antenna_rx) - 1; + u8 nr_index = 1; u8 grouping = 0, codebookinfo = 1, coefficientsize = 0; u32 csi_param; diff --git a/drivers/net/wireless/realtek/rtw88/coex.c b/drivers/net/wireless/realtek/rtw88/coex.c index cbf3d503df1c..3abae32341c4 100644 --- a/drivers/net/wireless/realtek/rtw88/coex.c +++ b/drivers/net/wireless/realtek/rtw88/coex.c @@ -378,6 +378,7 @@ static void rtw_coex_update_wl_link_info(struct rtw_dev *rtwdev, u8 reason) struct rtw_chip_info *chip = rtwdev->chip; struct rtw_traffic_stats *stats = &rtwdev->stats; bool is_5G = false; + bool wl_busy = false; bool scan = false, link = false; int i; u8 rssi_state; @@ -386,7 +387,16 @@ static void rtw_coex_update_wl_link_info(struct rtw_dev *rtwdev, u8 reason) scan = test_bit(RTW_FLAG_SCANNING, rtwdev->flags); coex_stat->wl_connected = !!rtwdev->sta_cnt; - coex_stat->wl_gl_busy = test_bit(RTW_FLAG_BUSY_TRAFFIC, rtwdev->flags); + + wl_busy = test_bit(RTW_FLAG_BUSY_TRAFFIC, rtwdev->flags); + if (wl_busy != coex_stat->wl_gl_busy) { + if (wl_busy) + coex_stat->wl_gl_busy = true; + else + ieee80211_queue_delayed_work(rtwdev->hw, + &coex->wl_remain_work, + 12 * HZ); + } if (stats->tx_throughput > stats->rx_throughput) coex_stat->wl_tput_dir = COEX_WL_TPUT_TX; @@ -888,10 +898,12 @@ static void rtw_coex_tdma(struct rtw_dev *rtwdev, bool force, u32 tcase) { struct rtw_coex *coex = &rtwdev->coex; struct rtw_coex_dm *coex_dm = &coex->dm; + struct rtw_coex_stat *coex_stat = &coex->stat; struct rtw_chip_info *chip = rtwdev->chip; struct rtw_efuse *efuse = &rtwdev->efuse; u8 n, type; bool turn_on; + bool wl_busy = false; if (tcase & TDMA_4SLOT)/* 4-slot (50ms) mode */ rtw_coex_tdma_timer_base(rtwdev, 3); @@ -909,13 +921,18 @@ static void rtw_coex_tdma(struct rtw_dev *rtwdev, bool force, u32 tcase) } } - if (turn_on) { - /* enable TBTT interrupt */ + /* enable TBTT interrupt */ + if (turn_on) rtw_write8_set(rtwdev, REG_BCN_CTRL, BIT_EN_BCN_FUNCTION); - rtw_coex_write_scbd(rtwdev, COEX_SCBD_TDMA, true); - } else { + + wl_busy = test_bit(RTW_FLAG_BUSY_TRAFFIC, rtwdev->flags); + + if ((coex_stat->bt_a2dp_exist && + (coex_stat->bt_inq_remain || coex_stat->bt_multi_link)) || + !wl_busy) rtw_coex_write_scbd(rtwdev, COEX_SCBD_TDMA, false); - } + else + rtw_coex_write_scbd(rtwdev, COEX_SCBD_TDMA, true); if (efuse->share_ant) { if (type < chip->tdma_sant_num) @@ -1323,20 +1340,31 @@ static void rtw_coex_action_bt_inquiry(struct rtw_dev *rtwdev) /* Shared-Ant */ if (wl_hi_pri) { table_case = 15; - if (coex_stat->bt_a2dp_exist && - !coex_stat->bt_pan_exist) { - slot_type = TDMA_4SLOT; - tdma_case = 11; - } else if (coex_stat->wl_hi_pri_task1) { + if (coex_stat->bt_profile_num > 0) + tdma_case = 10; + else if (coex_stat->wl_hi_pri_task1) tdma_case = 6; - } else if (!coex_stat->bt_page) { + else if (!coex_stat->bt_page) tdma_case = 8; - } else { + else tdma_case = 9; + } else if (coex_stat->wl_gl_busy) { + if (coex_stat->bt_profile_num == 0) { + table_case = 12; + tdma_case = 18; + } else if (coex_stat->bt_profile_num == 1 && + !coex_stat->bt_a2dp_exist) { + slot_type = TDMA_4SLOT; + table_case = 12; + tdma_case = 20; + } else { + slot_type = TDMA_4SLOT; + table_case = 12; + tdma_case = 26; } } else if (coex_stat->wl_connected) { - table_case = 10; - tdma_case = 10; + table_case = 9; + tdma_case = 27; } else { table_case = 1; tdma_case = 0; @@ -2277,6 +2305,7 @@ void rtw_coex_bt_info_notify(struct rtw_dev *rtwdev, u8 *buf, u8 length) struct rtw_chip_info *chip = rtwdev->chip; unsigned long bt_relink_time; u8 i, rsp_source = 0, type; + bool inq_page = false; rsp_source = buf[0] & 0xf; if (rsp_source >= COEX_BTINFO_SRC_MAX) @@ -2343,7 +2372,20 @@ void rtw_coex_bt_info_notify(struct rtw_dev *rtwdev, u8 *buf, u8 length) /* 0xff means BT is under WHCK test */ coex_stat->bt_whck_test = (coex_stat->bt_info_lb2 == 0xff); - coex_stat->bt_inq_page = ((coex_stat->bt_info_lb2 & BIT(2)) == BIT(2)); + + inq_page = ((coex_stat->bt_info_lb2 & BIT(2)) == BIT(2)); + + if (inq_page != coex_stat->bt_inq_page) { + cancel_delayed_work_sync(&coex->bt_remain_work); + coex_stat->bt_inq_page = inq_page; + + if (inq_page) + coex_stat->bt_inq_remain = true; + else + ieee80211_queue_delayed_work(rtwdev->hw, + &coex->bt_remain_work, + 4 * HZ); + } coex_stat->bt_acl_busy = ((coex_stat->bt_info_lb2 & BIT(3)) == BIT(3)); coex_stat->cnt_bt[COEX_CNT_BT_RETRY] = coex_stat->bt_info_lb3 & 0xf; if (coex_stat->cnt_bt[COEX_CNT_BT_RETRY] >= 1) @@ -2518,6 +2560,30 @@ void rtw_coex_defreeze_work(struct work_struct *work) mutex_unlock(&rtwdev->mutex); } +void rtw_coex_wl_remain_work(struct work_struct *work) +{ + struct rtw_dev *rtwdev = container_of(work, struct rtw_dev, + coex.wl_remain_work.work); + struct rtw_coex_stat *coex_stat = &rtwdev->coex.stat; + + mutex_lock(&rtwdev->mutex); + coex_stat->wl_gl_busy = test_bit(RTW_FLAG_BUSY_TRAFFIC, rtwdev->flags); + rtw_coex_run_coex(rtwdev, COEX_RSN_WLSTATUS); + mutex_unlock(&rtwdev->mutex); +} + +void rtw_coex_bt_remain_work(struct work_struct *work) +{ + struct rtw_dev *rtwdev = container_of(work, struct rtw_dev, + coex.bt_remain_work.work); + struct rtw_coex_stat *coex_stat = &rtwdev->coex.stat; + + mutex_lock(&rtwdev->mutex); + coex_stat->bt_inq_remain = coex_stat->bt_inq_page; + rtw_coex_run_coex(rtwdev, COEX_RSN_BTSTATUS); + mutex_unlock(&rtwdev->mutex); +} + #ifdef CONFIG_RTW88_DEBUGFS #define INFO_SIZE 80 diff --git a/drivers/net/wireless/realtek/rtw88/coex.h b/drivers/net/wireless/realtek/rtw88/coex.h index 4c3a01968f5e..44720fdfc053 100644 --- a/drivers/net/wireless/realtek/rtw88/coex.h +++ b/drivers/net/wireless/realtek/rtw88/coex.h @@ -95,6 +95,7 @@ enum coex_runreason { COEX_RSN_BTINFO = 12, COEX_RSN_LPS = 13, COEX_RSN_WLSTATUS = 14, + COEX_RSN_BTSTATUS = 15, COEX_RSN_MAX }; @@ -362,6 +363,8 @@ void rtw_coex_write_scbd(struct rtw_dev *rtwdev, u16 bitpos, bool set); void rtw_coex_bt_relink_work(struct work_struct *work); void rtw_coex_bt_reenable_work(struct work_struct *work); void rtw_coex_defreeze_work(struct work_struct *work); +void rtw_coex_wl_remain_work(struct work_struct *work); +void rtw_coex_bt_remain_work(struct work_struct *work); void rtw_coex_power_on_setting(struct rtw_dev *rtwdev); void rtw_coex_init_hw_config(struct rtw_dev *rtwdev, bool wifi_only); diff --git a/drivers/net/wireless/realtek/rtw88/main.c b/drivers/net/wireless/realtek/rtw88/main.c index 0eefafc51c62..7304e8bc5e31 100644 --- a/drivers/net/wireless/realtek/rtw88/main.c +++ b/drivers/net/wireless/realtek/rtw88/main.c @@ -935,6 +935,8 @@ void rtw_core_stop(struct rtw_dev *rtwdev) cancel_delayed_work_sync(&coex->bt_relink_work); cancel_delayed_work_sync(&coex->bt_reenable_work); cancel_delayed_work_sync(&coex->defreeze_work); + cancel_delayed_work_sync(&coex->wl_remain_work); + cancel_delayed_work_sync(&coex->bt_remain_work); mutex_lock(&rtwdev->mutex); @@ -989,12 +991,12 @@ static void rtw_init_vht_cap(struct rtw_dev *rtwdev, vht_cap->vht_supported = true; vht_cap->cap = IEEE80211_VHT_CAP_MAX_MPDU_LENGTH_11454 | IEEE80211_VHT_CAP_SHORT_GI_80 | - IEEE80211_VHT_CAP_TXSTBC | IEEE80211_VHT_CAP_RXSTBC_1 | IEEE80211_VHT_CAP_HTC_VHT | IEEE80211_VHT_CAP_MAX_A_MPDU_LENGTH_EXPONENT_MASK | 0; - + if (rtwdev->hal.rf_path_num > 1) + vht_cap->cap |= IEEE80211_VHT_CAP_TXSTBC; vht_cap->cap |= IEEE80211_VHT_CAP_MU_BEAMFORMEE_CAPABLE | IEEE80211_VHT_CAP_SU_BEAMFORMEE_CAPABLE; vht_cap->cap |= (rtwdev->hal.bfee_sts_cap << @@ -1326,6 +1328,10 @@ static int rtw_chip_efuse_info_setup(struct rtw_dev *rtwdev) efuse->share_ant = true; if (efuse->regd == 0xff) efuse->regd = 0; + if (efuse->tx_bb_swing_setting_2g == 0xff) + efuse->tx_bb_swing_setting_2g = 0; + if (efuse->tx_bb_swing_setting_5g == 0xff) + efuse->tx_bb_swing_setting_5g = 0; efuse->btcoex = (efuse->rf_board_option & 0xe0) == 0x20; efuse->ext_pa_2g = efuse->pa_type_2g & BIT(4) ? 1 : 0; @@ -1422,6 +1428,8 @@ int rtw_core_init(struct rtw_dev *rtwdev) INIT_DELAYED_WORK(&coex->bt_relink_work, rtw_coex_bt_relink_work); INIT_DELAYED_WORK(&coex->bt_reenable_work, rtw_coex_bt_reenable_work); INIT_DELAYED_WORK(&coex->defreeze_work, rtw_coex_defreeze_work); + INIT_DELAYED_WORK(&coex->wl_remain_work, rtw_coex_wl_remain_work); + INIT_DELAYED_WORK(&coex->bt_remain_work, rtw_coex_bt_remain_work); INIT_WORK(&rtwdev->c2h_work, rtw_c2h_work); INIT_WORK(&rtwdev->ba_work, rtw_txq_ba_work); skb_queue_head_init(&rtwdev->c2h_queue); diff --git a/drivers/net/wireless/realtek/rtw88/main.h b/drivers/net/wireless/realtek/rtw88/main.h index 0841f5fa4bf2..45ebc5a70b1e 100644 --- a/drivers/net/wireless/realtek/rtw88/main.h +++ b/drivers/net/wireless/realtek/rtw88/main.h @@ -183,6 +183,7 @@ enum rtw_chip_type { RTW_CHIP_TYPE_8822B, RTW_CHIP_TYPE_8822C, RTW_CHIP_TYPE_8723D, + RTW_CHIP_TYPE_8821C, }; enum rtw_tx_queue_type { @@ -1147,6 +1148,9 @@ struct rtw_chip_info { const struct wiphy_wowlan_support *wowlan_stub; const u8 max_sched_scan_ssids; + /* for 8821c set channel */ + u32 ch_param[3]; + /* coex paras */ u32 coex_para_ver; u8 bt_desired_ver; @@ -1263,6 +1267,7 @@ struct rtw_coex_stat { bool bt_link_exist; bool bt_whck_test; bool bt_inq_page; + bool bt_inq_remain; bool bt_inq; bool bt_page; bool bt_ble_voice; @@ -1363,6 +1368,8 @@ struct rtw_coex { struct delayed_work bt_relink_work; struct delayed_work bt_reenable_work; struct delayed_work defreeze_work; + struct delayed_work wl_remain_work; + struct delayed_work bt_remain_work; }; #define DPK_RF_REG_NUM 7 @@ -1462,6 +1469,7 @@ struct rtw_dm_info { u8 thermal_avg[RTW_RF_PATH_MAX]; u8 thermal_meter_k; s8 delta_power_index[RTW_RF_PATH_MAX]; + s8 delta_power_index_last[RTW_RF_PATH_MAX]; u8 default_ofdm_index; bool pwr_trk_triggered; bool pwr_trk_init_trigger; @@ -1479,6 +1487,7 @@ struct rtw_dm_info { /* [bandwidth 0:20M/1:40M][number of path] */ u8 cck_pd_lv[2][RTW_RF_PATH_MAX]; u32 cck_fa_avg; + u8 cck_pd_default; /* save the last rx phy status for debug */ s8 rx_snr[RTW_RF_PATH_MAX]; @@ -1526,6 +1535,8 @@ struct rtw_efuse { u8 apa_type; bool ext_pa_2g; bool ext_pa_5g; + u8 tx_bb_swing_setting_2g; + u8 tx_bb_swing_setting_5g; bool btcoex; /* bt share antenna with wifi */ diff --git a/drivers/net/wireless/realtek/rtw88/pci.c b/drivers/net/wireless/realtek/rtw88/pci.c index 8228db9a5fc8..3413973bc475 100644 --- a/drivers/net/wireless/realtek/rtw88/pci.c +++ b/drivers/net/wireless/realtek/rtw88/pci.c @@ -14,8 +14,11 @@ #include "debug.h" static bool rtw_disable_msi; +static bool rtw_pci_disable_aspm; module_param_named(disable_msi, rtw_disable_msi, bool, 0644); +module_param_named(disable_aspm, rtw_pci_disable_aspm, bool, 0644); MODULE_PARM_DESC(disable_msi, "Set Y to disable MSI interrupt support"); +MODULE_PARM_DESC(disable_aspm, "Set Y to disable PCI ASPM support"); static u32 rtw_pci_tx_queue_idx_addr[] = { [RTW_TX_QUEUE_BK] = RTK_PCI_TXBD_IDX_BKQ, @@ -1200,6 +1203,9 @@ static void rtw_pci_clkreq_set(struct rtw_dev *rtwdev, bool enable) u8 value; int ret; + if (rtw_pci_disable_aspm) + return; + ret = rtw_dbi_read8(rtwdev, RTK_PCIE_LINK_CFG, &value); if (ret) { rtw_err(rtwdev, "failed to read CLKREQ_L1, ret=%d", ret); @@ -1219,6 +1225,9 @@ static void rtw_pci_aspm_set(struct rtw_dev *rtwdev, bool enable) u8 value; int ret; + if (rtw_pci_disable_aspm) + return; + ret = rtw_dbi_read8(rtwdev, RTK_PCIE_LINK_CFG, &value); if (ret) { rtw_err(rtwdev, "failed to read ASPM, ret=%d", ret); diff --git a/drivers/net/wireless/realtek/rtw88/reg.h b/drivers/net/wireless/realtek/rtw88/reg.h index 5a3e9cc7c400..f1275757f6b4 100644 --- a/drivers/net/wireless/realtek/rtw88/reg.h +++ b/drivers/net/wireless/realtek/rtw88/reg.h @@ -43,6 +43,8 @@ #define BITS_EF_ADDR (BIT_MASK_EF_ADDR << BIT_SHIFT_EF_ADDR) #define BITS_PLL 0xf0 +#define REG_AFE_XTAL_CTRL 0x24 +#define REG_AFE_PLL_CTRL 0x28 #define REG_AFE_CTRL3 0x2c #define BIT_MASK_XTAL 0x00FFF000 #define BIT_XTAL_GMP_BIT4 BIT(28) @@ -476,6 +478,8 @@ #define REG_RFE_CTRL_E 0x0974 #define REG_2ND_CCA_CTRL 0x0976 +#define REG_CCK0_FAREPORT 0xa2c + #define REG_DIS_DPD 0x0a70 #define DIS_DPD_MASK GENMASK(9, 0) #define DIS_DPD_RATE6M BIT(0) diff --git a/drivers/net/wireless/realtek/rtw88/rtw8723d.c b/drivers/net/wireless/realtek/rtw88/rtw8723d.c index 4700195c8eef..3ddd170f1651 100644 --- a/drivers/net/wireless/realtek/rtw88/rtw8723d.c +++ b/drivers/net/wireless/realtek/rtw88/rtw8723d.c @@ -1956,13 +1956,13 @@ static const struct coex_table_para table_sant_8723d[] = { {0xa5555555, 0xaaaa5aaa}, {0x6a5a5a5a, 0x5a5a5a5a}, {0x6a5a5a5a, 0x6a5a5a5a}, - {0x65555555, 0x5a5a5a5a}, + {0x66555555, 0x5a5a5a5a}, {0x65555555, 0x6a5a5a5a}, /* case-10 */ {0x65555555, 0xfafafafa}, - {0x65555555, 0x6a5a5aaa}, + {0x66555555, 0x5a5a5aaa}, {0x65555555, 0x5aaa5aaa}, {0x65555555, 0xaaaa5aaa}, - {0x65555555, 0xaaaaaaaa}, /* case-15 */ + {0x66555555, 0xaaaaaaaa}, /* case-15 */ {0xffff55ff, 0xfafafafa}, {0xffff55ff, 0x6afa5afa}, {0xaaffffaa, 0xfafafafa}, @@ -2034,8 +2034,9 @@ static const struct coex_tdma_para tdma_sant_8723d[] = { { {0x51, 0x0c, 0x03, 0x10, 0x54} }, { {0x55, 0x08, 0x03, 0x10, 0x54} }, { {0x65, 0x10, 0x03, 0x11, 0x11} }, - { {0x51, 0x10, 0x03, 0x10, 0x51} }, - { {0x61, 0x15, 0x03, 0x11, 0x10} } + { {0x51, 0x10, 0x03, 0x10, 0x51} }, /* case-25 */ + { {0x51, 0x08, 0x03, 0x10, 0x50} }, + { {0x61, 0x08, 0x03, 0x11, 0x11} } }; /* Non-Shared-Antenna TDMA */ @@ -2714,7 +2715,7 @@ struct rtw_chip_info rtw8723d_hw_spec = { .pwr_track_tbl = &rtw8723d_rtw_pwr_track_tbl, .iqk_threshold = 8, - .coex_para_ver = 0x1905302f, + .coex_para_ver = 0x2007022f, .bt_desired_ver = 0x2f, .scbd_support = true, .new_scbd10_def = true, diff --git a/drivers/net/wireless/realtek/rtw88/rtw8821c.c b/drivers/net/wireless/realtek/rtw88/rtw8821c.c new file mode 100644 index 000000000000..c41c61ee2fb6 --- /dev/null +++ b/drivers/net/wireless/realtek/rtw88/rtw8821c.c @@ -0,0 +1,1450 @@ +// SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause +/* Copyright(c) 2018-2019 Realtek Corporation + */ + +#include "main.h" +#include "coex.h" +#include "fw.h" +#include "tx.h" +#include "rx.h" +#include "phy.h" +#include "rtw8821c.h" +#include "rtw8821c_table.h" +#include "mac.h" +#include "reg.h" +#include "debug.h" +#include "bf.h" + +static void rtw8821ce_efuse_parsing(struct rtw_efuse *efuse, + struct rtw8821c_efuse *map) +{ + ether_addr_copy(efuse->addr, map->e.mac_addr); +} + +static int rtw8821c_read_efuse(struct rtw_dev *rtwdev, u8 *log_map) +{ + struct rtw_efuse *efuse = &rtwdev->efuse; + struct rtw8821c_efuse *map; + int i; + + map = (struct rtw8821c_efuse *)log_map; + + efuse->rfe_option = map->rfe_option; + efuse->rf_board_option = map->rf_board_option; + efuse->crystal_cap = map->xtal_k; + efuse->pa_type_2g = map->pa_type; + efuse->pa_type_5g = map->pa_type; + efuse->lna_type_2g = map->lna_type_2g[0]; + efuse->lna_type_5g = map->lna_type_5g[0]; + efuse->channel_plan = map->channel_plan; + efuse->country_code[0] = map->country_code[0]; + efuse->country_code[1] = map->country_code[1]; + efuse->bt_setting = map->rf_bt_setting; + efuse->regd = map->rf_board_option & 0x7; + efuse->thermal_meter[0] = map->thermal_meter; + efuse->thermal_meter_k = map->thermal_meter; + efuse->tx_bb_swing_setting_2g = map->tx_bb_swing_setting_2g; + efuse->tx_bb_swing_setting_5g = map->tx_bb_swing_setting_5g; + + for (i = 0; i < 4; i++) + efuse->txpwr_idx_table[i] = map->txpwr_idx_table[i]; + + switch (rtw_hci_type(rtwdev)) { + case RTW_HCI_TYPE_PCIE: + rtw8821ce_efuse_parsing(efuse, map); + break; + default: + /* unsupported now */ + return -ENOTSUPP; + } + + return 0; +} + +static const u32 rtw8821c_txscale_tbl[] = { + 0x081, 0x088, 0x090, 0x099, 0x0a2, 0x0ac, 0x0b6, 0x0c0, 0x0cc, 0x0d8, + 0x0e5, 0x0f2, 0x101, 0x110, 0x120, 0x131, 0x143, 0x156, 0x16a, 0x180, + 0x197, 0x1af, 0x1c8, 0x1e3, 0x200, 0x21e, 0x23e, 0x261, 0x285, 0x2ab, + 0x2d3, 0x2fe, 0x32b, 0x35c, 0x38e, 0x3c4, 0x3fe +}; + +static const u8 rtw8821c_get_swing_index(struct rtw_dev *rtwdev) +{ + u8 i = 0; + u32 swing, table_value; + + swing = rtw_read32_mask(rtwdev, REG_TXSCALE_A, 0xffe00000); + for (i = 0; i < ARRAY_SIZE(rtw8821c_txscale_tbl); i++) { + table_value = rtw8821c_txscale_tbl[i]; + if (swing == table_value) + break; + } + + return i; +} + +static void rtw8821c_pwrtrack_init(struct rtw_dev *rtwdev) +{ + struct rtw_dm_info *dm_info = &rtwdev->dm_info; + u8 swing_idx = rtw8821c_get_swing_index(rtwdev); + + if (swing_idx >= ARRAY_SIZE(rtw8821c_txscale_tbl)) + dm_info->default_ofdm_index = 24; + else + dm_info->default_ofdm_index = swing_idx; + + ewma_thermal_init(&dm_info->avg_thermal[RF_PATH_A]); + dm_info->delta_power_index[RF_PATH_A] = 0; + dm_info->delta_power_index_last[RF_PATH_A] = 0; + dm_info->pwr_trk_triggered = false; + dm_info->pwr_trk_init_trigger = true; + dm_info->thermal_meter_k = rtwdev->efuse.thermal_meter_k; +} + +static void rtw8821c_phy_bf_init(struct rtw_dev *rtwdev) +{ + rtw_bf_phy_init(rtwdev); + /* Grouping bitmap parameters */ + rtw_write32(rtwdev, 0x1C94, 0xAFFFAFFF); +} + +static void rtw8821c_phy_set_param(struct rtw_dev *rtwdev) +{ + u8 crystal_cap, val; + + /* power on BB/RF domain */ + val = rtw_read8(rtwdev, REG_SYS_FUNC_EN); + val |= BIT_FEN_PCIEA; + rtw_write8(rtwdev, REG_SYS_FUNC_EN, val); + + /* toggle BB reset */ + val |= BIT_FEN_BB_RSTB | BIT_FEN_BB_GLB_RST; + rtw_write8(rtwdev, REG_SYS_FUNC_EN, val); + val &= ~(BIT_FEN_BB_RSTB | BIT_FEN_BB_GLB_RST); + rtw_write8(rtwdev, REG_SYS_FUNC_EN, val); + val |= BIT_FEN_BB_RSTB | BIT_FEN_BB_GLB_RST; + rtw_write8(rtwdev, REG_SYS_FUNC_EN, val); + + rtw_write8(rtwdev, REG_RF_CTRL, + BIT_RF_EN | BIT_RF_RSTB | BIT_RF_SDM_RSTB); + usleep_range(10, 11); + rtw_write8(rtwdev, REG_WLRF1 + 3, + BIT_RF_EN | BIT_RF_RSTB | BIT_RF_SDM_RSTB); + usleep_range(10, 11); + + /* pre init before header files config */ + rtw_write32_clr(rtwdev, REG_RXPSEL, BIT_RX_PSEL_RST); + + rtw_phy_load_tables(rtwdev); + + crystal_cap = rtwdev->efuse.crystal_cap & 0x3F; + rtw_write32_mask(rtwdev, REG_AFE_XTAL_CTRL, 0x7e000000, crystal_cap); + rtw_write32_mask(rtwdev, REG_AFE_PLL_CTRL, 0x7e, crystal_cap); + rtw_write32_mask(rtwdev, REG_CCK0_FAREPORT, BIT(18) | BIT(22), 0); + + /* post init after header files config */ + rtw_write32_set(rtwdev, REG_RXPSEL, BIT_RX_PSEL_RST); + rtwdev->chip->ch_param[0] = rtw_read32_mask(rtwdev, REG_TXSF2, MASKDWORD); + rtwdev->chip->ch_param[1] = rtw_read32_mask(rtwdev, REG_TXSF6, MASKDWORD); + rtwdev->chip->ch_param[2] = rtw_read32_mask(rtwdev, REG_TXFILTER, MASKDWORD); + + rtw_phy_init(rtwdev); + rtwdev->dm_info.cck_pd_default = rtw_read8(rtwdev, REG_CSRATIO) & 0x1f; + + rtw8821c_pwrtrack_init(rtwdev); + + rtw8821c_phy_bf_init(rtwdev); +} + +static int rtw8821c_mac_init(struct rtw_dev *rtwdev) +{ + u32 value32; + u16 pre_txcnt; + + /* protocol configuration */ + rtw_write8(rtwdev, REG_AMPDU_MAX_TIME_V1, WLAN_AMPDU_MAX_TIME); + rtw_write8_set(rtwdev, REG_TX_HANG_CTRL, BIT_EN_EOF_V1); + pre_txcnt = WLAN_PRE_TXCNT_TIME_TH | BIT_EN_PRECNT; + rtw_write8(rtwdev, REG_PRECNT_CTRL, (u8)(pre_txcnt & 0xFF)); + rtw_write8(rtwdev, REG_PRECNT_CTRL + 1, (u8)(pre_txcnt >> 8)); + value32 = WLAN_RTS_LEN_TH | (WLAN_RTS_TX_TIME_TH << 8) | + (WLAN_MAX_AGG_PKT_LIMIT << 16) | + (WLAN_RTS_MAX_AGG_PKT_LIMIT << 24); + rtw_write32(rtwdev, REG_PROT_MODE_CTRL, value32); + rtw_write16(rtwdev, REG_BAR_MODE_CTRL + 2, + WLAN_BAR_RETRY_LIMIT | WLAN_RA_TRY_RATE_AGG_LIMIT << 8); + rtw_write8(rtwdev, REG_FAST_EDCA_VOVI_SETTING, FAST_EDCA_VO_TH); + rtw_write8(rtwdev, REG_FAST_EDCA_VOVI_SETTING + 2, FAST_EDCA_VI_TH); + rtw_write8(rtwdev, REG_FAST_EDCA_BEBK_SETTING, FAST_EDCA_BE_TH); + rtw_write8(rtwdev, REG_FAST_EDCA_BEBK_SETTING + 2, FAST_EDCA_BK_TH); + rtw_write8_set(rtwdev, REG_INIRTS_RATE_SEL, BIT(5)); + + /* EDCA configuration */ + rtw_write8_clr(rtwdev, REG_TIMER0_SRC_SEL, BIT_TSFT_SEL_TIMER0); + rtw_write16(rtwdev, REG_TXPAUSE, 0); + rtw_write8(rtwdev, REG_SLOT, WLAN_SLOT_TIME); + rtw_write8(rtwdev, REG_PIFS, WLAN_PIFS_TIME); + rtw_write32(rtwdev, REG_SIFS, WLAN_SIFS_CFG); + rtw_write16(rtwdev, REG_EDCA_VO_PARAM + 2, WLAN_VO_TXOP_LIMIT); + rtw_write16(rtwdev, REG_EDCA_VI_PARAM + 2, WLAN_VI_TXOP_LIMIT); + rtw_write32(rtwdev, REG_RD_NAV_NXT, WLAN_NAV_CFG); + rtw_write16(rtwdev, REG_RXTSF_OFFSET_CCK, WLAN_RX_TSF_CFG); + + /* Set beacon cotnrol - enable TSF and other related functions */ + rtw_write8_set(rtwdev, REG_BCN_CTRL, BIT_EN_BCN_FUNCTION); + + /* Set send beacon related registers */ + rtw_write32(rtwdev, REG_TBTT_PROHIBIT, WLAN_TBTT_TIME); + rtw_write8(rtwdev, REG_DRVERLYINT, WLAN_DRV_EARLY_INT); + rtw_write8(rtwdev, REG_BCNDMATIM, WLAN_BCN_DMA_TIME); + rtw_write8_clr(rtwdev, REG_TX_PTCL_CTRL + 1, BIT_SIFS_BK_EN >> 8); + + /* WMAC configuration */ + rtw_write32(rtwdev, REG_RXFLTMAP0, WLAN_RX_FILTER0); + rtw_write16(rtwdev, REG_RXFLTMAP2, WLAN_RX_FILTER2); + rtw_write32(rtwdev, REG_RCR, WLAN_RCR_CFG); + rtw_write8(rtwdev, REG_RX_PKT_LIMIT, WLAN_RXPKT_MAX_SZ_512); + rtw_write8(rtwdev, REG_TCR + 2, WLAN_TX_FUNC_CFG2); + rtw_write8(rtwdev, REG_TCR + 1, WLAN_TX_FUNC_CFG1); + rtw_write8(rtwdev, REG_ACKTO_CCK, 0x40); + rtw_write8_set(rtwdev, REG_WMAC_TRXPTCL_CTL_H, BIT(1)); + rtw_write8_set(rtwdev, REG_SND_PTCL_CTRL, BIT(6)); + rtw_write32(rtwdev, REG_WMAC_OPTION_FUNCTION + 8, WLAN_MAC_OPT_FUNC2); + rtw_write8(rtwdev, REG_WMAC_OPTION_FUNCTION + 4, WLAN_MAC_OPT_NORM_FUNC1); + + return 0; +} + +static void rtw8821c_cfg_ldo25(struct rtw_dev *rtwdev, bool enable) +{ + u8 ldo_pwr; + + ldo_pwr = rtw_read8(rtwdev, REG_LDO_EFUSE_CTRL + 3); + ldo_pwr = enable ? ldo_pwr | BIT(7) : ldo_pwr & ~BIT(7); + rtw_write8(rtwdev, REG_LDO_EFUSE_CTRL + 3, ldo_pwr); +} + +static void rtw8821c_set_channel_rf(struct rtw_dev *rtwdev, u8 channel, u8 bw) +{ + u32 rf_reg18; + + rf_reg18 = rtw_read_rf(rtwdev, RF_PATH_A, 0x18, RFREG_MASK); + + rf_reg18 &= ~(RF18_BAND_MASK | RF18_CHANNEL_MASK | RF18_RFSI_MASK | + RF18_BW_MASK); + + rf_reg18 |= (channel <= 14 ? RF18_BAND_2G : RF18_BAND_5G); + rf_reg18 |= (channel & RF18_CHANNEL_MASK); + + if (channel >= 100 && channel <= 140) + rf_reg18 |= RF18_RFSI_GE; + else if (channel > 140) + rf_reg18 |= RF18_RFSI_GT; + + switch (bw) { + case RTW_CHANNEL_WIDTH_5: + case RTW_CHANNEL_WIDTH_10: + case RTW_CHANNEL_WIDTH_20: + default: + rf_reg18 |= RF18_BW_20M; + break; + case RTW_CHANNEL_WIDTH_40: + rf_reg18 |= RF18_BW_40M; + break; + case RTW_CHANNEL_WIDTH_80: + rf_reg18 |= RF18_BW_80M; + break; + } + + if (channel <= 14) { + rtw_write_rf(rtwdev, RF_PATH_A, RF_LUTDBG, BIT(6), 0x1); + rtw_write_rf(rtwdev, RF_PATH_A, 0x64, 0xf, 0xf); + } else { + rtw_write_rf(rtwdev, RF_PATH_A, RF_LUTDBG, BIT(6), 0x0); + } + + rtw_write_rf(rtwdev, RF_PATH_A, 0x18, RFREG_MASK, rf_reg18); + + rtw_write_rf(rtwdev, RF_PATH_A, RF_XTALX2, BIT(19), 0); + rtw_write_rf(rtwdev, RF_PATH_A, RF_XTALX2, BIT(19), 1); +} + +static void rtw8821c_set_channel_rxdfir(struct rtw_dev *rtwdev, u8 bw) +{ + if (bw == RTW_CHANNEL_WIDTH_40) { + /* RX DFIR for BW40 */ + rtw_write32_mask(rtwdev, REG_ACBB0, BIT(29) | BIT(28), 0x2); + rtw_write32_mask(rtwdev, REG_ACBBRXFIR, BIT(29) | BIT(28), 0x2); + rtw_write32_mask(rtwdev, REG_TXDFIR, BIT(31), 0x0); + rtw_write32_mask(rtwdev, REG_CHFIR, BIT(31), 0x0); + } else if (bw == RTW_CHANNEL_WIDTH_80) { + /* RX DFIR for BW80 */ + rtw_write32_mask(rtwdev, REG_ACBB0, BIT(29) | BIT(28), 0x2); + rtw_write32_mask(rtwdev, REG_ACBBRXFIR, BIT(29) | BIT(28), 0x1); + rtw_write32_mask(rtwdev, REG_TXDFIR, BIT(31), 0x0); + rtw_write32_mask(rtwdev, REG_CHFIR, BIT(31), 0x1); + } else { + /* RX DFIR for BW20, BW10 and BW5 */ + rtw_write32_mask(rtwdev, REG_ACBB0, BIT(29) | BIT(28), 0x2); + rtw_write32_mask(rtwdev, REG_ACBBRXFIR, BIT(29) | BIT(28), 0x2); + rtw_write32_mask(rtwdev, REG_TXDFIR, BIT(31), 0x1); + rtw_write32_mask(rtwdev, REG_CHFIR, BIT(31), 0x0); + } +} + +static void rtw8821c_set_channel_bb(struct rtw_dev *rtwdev, u8 channel, u8 bw, + u8 primary_ch_idx) +{ + u32 val32; + + if (channel <= 14) { + rtw_write32_mask(rtwdev, REG_RXPSEL, BIT(28), 0x1); + rtw_write32_mask(rtwdev, REG_CCK_CHECK, BIT(7), 0x0); + rtw_write32_mask(rtwdev, REG_ENTXCCK, BIT(18), 0x0); + rtw_write32_mask(rtwdev, REG_RXCCAMSK, 0x0000FC00, 15); + + rtw_write32_mask(rtwdev, REG_TXSCALE_A, 0xf00, 0x0); + rtw_write32_mask(rtwdev, REG_CLKTRK, 0x1ffe0000, 0x96a); + if (channel == 14) { + rtw_write32_mask(rtwdev, REG_TXSF2, MASKDWORD, 0x0000b81c); + rtw_write32_mask(rtwdev, REG_TXSF6, MASKLWORD, 0x0000); + rtw_write32_mask(rtwdev, REG_TXFILTER, MASKDWORD, 0x00003667); + } else { + rtw_write32_mask(rtwdev, REG_TXSF2, MASKDWORD, + rtwdev->chip->ch_param[0]); + rtw_write32_mask(rtwdev, REG_TXSF6, MASKLWORD, + rtwdev->chip->ch_param[1] & MASKLWORD); + rtw_write32_mask(rtwdev, REG_TXFILTER, MASKDWORD, + rtwdev->chip->ch_param[2]); + } + } else if (channel > 35) { + rtw_write32_mask(rtwdev, REG_ENTXCCK, BIT(18), 0x1); + rtw_write32_mask(rtwdev, REG_CCK_CHECK, BIT(7), 0x1); + rtw_write32_mask(rtwdev, REG_RXPSEL, BIT(28), 0x0); + rtw_write32_mask(rtwdev, REG_RXCCAMSK, 0x0000FC00, 15); + + if (channel >= 36 && channel <= 64) + rtw_write32_mask(rtwdev, REG_TXSCALE_A, 0xf00, 0x1); + else if (channel >= 100 && channel <= 144) + rtw_write32_mask(rtwdev, REG_TXSCALE_A, 0xf00, 0x2); + else if (channel >= 149) + rtw_write32_mask(rtwdev, REG_TXSCALE_A, 0xf00, 0x3); + + if (channel >= 36 && channel <= 48) + rtw_write32_mask(rtwdev, REG_CLKTRK, 0x1ffe0000, 0x494); + else if (channel >= 52 && channel <= 64) + rtw_write32_mask(rtwdev, REG_CLKTRK, 0x1ffe0000, 0x453); + else if (channel >= 100 && channel <= 116) + rtw_write32_mask(rtwdev, REG_CLKTRK, 0x1ffe0000, 0x452); + else if (channel >= 118 && channel <= 177) + rtw_write32_mask(rtwdev, REG_CLKTRK, 0x1ffe0000, 0x412); + } + + switch (bw) { + case RTW_CHANNEL_WIDTH_20: + default: + val32 = rtw_read32_mask(rtwdev, REG_ADCCLK, MASKDWORD); + val32 &= 0xffcffc00; + val32 |= 0x10010000; + rtw_write32_mask(rtwdev, REG_ADCCLK, MASKDWORD, val32); + + rtw_write32_mask(rtwdev, REG_ADC160, BIT(30), 0x1); + break; + case RTW_CHANNEL_WIDTH_40: + if (primary_ch_idx == 1) + rtw_write32_set(rtwdev, REG_RXSB, BIT(4)); + else + rtw_write32_clr(rtwdev, REG_RXSB, BIT(4)); + + val32 = rtw_read32_mask(rtwdev, REG_ADCCLK, MASKDWORD); + val32 &= 0xff3ff300; + val32 |= 0x20020000 | ((primary_ch_idx & 0xf) << 2) | + RTW_CHANNEL_WIDTH_40; + rtw_write32_mask(rtwdev, REG_ADCCLK, MASKDWORD, val32); + + rtw_write32_mask(rtwdev, REG_ADC160, BIT(30), 0x1); + break; + case RTW_CHANNEL_WIDTH_80: + val32 = rtw_read32_mask(rtwdev, REG_ADCCLK, MASKDWORD); + val32 &= 0xfcffcf00; + val32 |= 0x40040000 | ((primary_ch_idx & 0xf) << 2) | + RTW_CHANNEL_WIDTH_80; + rtw_write32_mask(rtwdev, REG_ADCCLK, MASKDWORD, val32); + + rtw_write32_mask(rtwdev, REG_ADC160, BIT(30), 0x1); + break; + case RTW_CHANNEL_WIDTH_5: + val32 = rtw_read32_mask(rtwdev, REG_ADCCLK, MASKDWORD); + val32 &= 0xefcefc00; + val32 |= 0x200240; + rtw_write32_mask(rtwdev, REG_ADCCLK, MASKDWORD, val32); + + rtw_write32_mask(rtwdev, REG_ADC160, BIT(30), 0x0); + rtw_write32_mask(rtwdev, REG_ADC40, BIT(31), 0x1); + break; + case RTW_CHANNEL_WIDTH_10: + val32 = rtw_read32_mask(rtwdev, REG_ADCCLK, MASKDWORD); + val32 &= 0xefcefc00; + val32 |= 0x300380; + rtw_write32_mask(rtwdev, REG_ADCCLK, MASKDWORD, val32); + + rtw_write32_mask(rtwdev, REG_ADC160, BIT(30), 0x0); + rtw_write32_mask(rtwdev, REG_ADC40, BIT(31), 0x1); + break; + } +} + +static u32 rtw8821c_get_bb_swing(struct rtw_dev *rtwdev, u8 channel) +{ + struct rtw_efuse efuse = rtwdev->efuse; + u8 tx_bb_swing; + u32 swing2setting[4] = {0x200, 0x16a, 0x101, 0x0b6}; + + tx_bb_swing = channel <= 14 ? efuse.tx_bb_swing_setting_2g : + efuse.tx_bb_swing_setting_5g; + if (tx_bb_swing > 9) + tx_bb_swing = 0; + + return swing2setting[(tx_bb_swing / 3)]; +} + +static void rtw8821c_set_channel_bb_swing(struct rtw_dev *rtwdev, u8 channel, + u8 bw, u8 primary_ch_idx) +{ + rtw_write32_mask(rtwdev, REG_TXSCALE_A, GENMASK(31, 21), + rtw8821c_get_bb_swing(rtwdev, channel)); + rtw8821c_pwrtrack_init(rtwdev); +} + +static void rtw8821c_set_channel(struct rtw_dev *rtwdev, u8 channel, u8 bw, + u8 primary_chan_idx) +{ + rtw8821c_set_channel_bb(rtwdev, channel, bw, primary_chan_idx); + rtw8821c_set_channel_bb_swing(rtwdev, channel, bw, primary_chan_idx); + rtw_set_channel_mac(rtwdev, channel, bw, primary_chan_idx); + rtw8821c_set_channel_rf(rtwdev, channel, bw); + rtw8821c_set_channel_rxdfir(rtwdev, bw); +} + +static void query_phy_status_page0(struct rtw_dev *rtwdev, u8 *phy_status, + struct rtw_rx_pkt_stat *pkt_stat) +{ + s8 min_rx_power = -120; + u8 pwdb = GET_PHY_STAT_P0_PWDB(phy_status); + + pkt_stat->rx_power[RF_PATH_A] = pwdb - 100; + pkt_stat->rssi = rtw_phy_rf_power_2_rssi(pkt_stat->rx_power, 1); + pkt_stat->bw = RTW_CHANNEL_WIDTH_20; + pkt_stat->signal_power = max(pkt_stat->rx_power[RF_PATH_A], + min_rx_power); +} + +static void query_phy_status_page1(struct rtw_dev *rtwdev, u8 *phy_status, + struct rtw_rx_pkt_stat *pkt_stat) +{ + u8 rxsc, bw; + s8 min_rx_power = -120; + + if (pkt_stat->rate > DESC_RATE11M && pkt_stat->rate < DESC_RATEMCS0) + rxsc = GET_PHY_STAT_P1_L_RXSC(phy_status); + else + rxsc = GET_PHY_STAT_P1_HT_RXSC(phy_status); + + if (rxsc >= 1 && rxsc <= 8) + bw = RTW_CHANNEL_WIDTH_20; + else if (rxsc >= 9 && rxsc <= 12) + bw = RTW_CHANNEL_WIDTH_40; + else if (rxsc >= 13) + bw = RTW_CHANNEL_WIDTH_80; + else + bw = GET_PHY_STAT_P1_RF_MODE(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); + pkt_stat->bw = bw; + pkt_stat->signal_power = max(pkt_stat->rx_power[RF_PATH_A], + min_rx_power); +} + +static void query_phy_status(struct rtw_dev *rtwdev, u8 *phy_status, + struct rtw_rx_pkt_stat *pkt_stat) +{ + u8 page; + + page = *phy_status & 0xf; + + switch (page) { + case 0: + query_phy_status_page0(rtwdev, phy_status, pkt_stat); + break; + case 1: + query_phy_status_page1(rtwdev, phy_status, pkt_stat); + break; + default: + rtw_warn(rtwdev, "unused phy status page (%d)\n", page); + return; + } +} + +static void rtw8821c_query_rx_desc(struct rtw_dev *rtwdev, u8 *rx_desc, + struct rtw_rx_pkt_stat *pkt_stat, + struct ieee80211_rx_status *rx_status) +{ + struct ieee80211_hdr *hdr; + u32 desc_sz = rtwdev->chip->rx_pkt_desc_sz; + u8 *phy_status = NULL; + + memset(pkt_stat, 0, sizeof(*pkt_stat)); + + pkt_stat->phy_status = GET_RX_DESC_PHYST(rx_desc); + pkt_stat->icv_err = GET_RX_DESC_ICV_ERR(rx_desc); + pkt_stat->crc_err = GET_RX_DESC_CRC32(rx_desc); + pkt_stat->decrypted = !GET_RX_DESC_SWDEC(rx_desc); + pkt_stat->is_c2h = GET_RX_DESC_C2H(rx_desc); + pkt_stat->pkt_len = GET_RX_DESC_PKT_LEN(rx_desc); + pkt_stat->drv_info_sz = GET_RX_DESC_DRV_INFO_SIZE(rx_desc); + pkt_stat->shift = GET_RX_DESC_SHIFT(rx_desc); + pkt_stat->rate = GET_RX_DESC_RX_RATE(rx_desc); + pkt_stat->cam_id = GET_RX_DESC_MACID(rx_desc); + pkt_stat->ppdu_cnt = GET_RX_DESC_PPDU_CNT(rx_desc); + pkt_stat->tsf_low = GET_RX_DESC_TSFL(rx_desc); + + /* drv_info_sz is in unit of 8-bytes */ + pkt_stat->drv_info_sz *= 8; + + /* c2h cmd pkt's rx/phy status is not interested */ + if (pkt_stat->is_c2h) + return; + + hdr = (struct ieee80211_hdr *)(rx_desc + desc_sz + pkt_stat->shift + + pkt_stat->drv_info_sz); + if (pkt_stat->phy_status) { + phy_status = rx_desc + desc_sz + pkt_stat->shift; + query_phy_status(rtwdev, phy_status, pkt_stat); + } + + rtw_rx_fill_rx_status(rtwdev, pkt_stat, hdr, rx_status, phy_status); +} + +static void +rtw8821c_set_tx_power_index_by_rate(struct rtw_dev *rtwdev, u8 path, u8 rs) +{ + struct rtw_hal *hal = &rtwdev->hal; + static const u32 offset_txagc[2] = {0x1d00, 0x1d80}; + static u32 phy_pwr_idx; + u8 rate, rate_idx, pwr_index, shift; + int j; + + for (j = 0; j < rtw_rate_size[rs]; j++) { + rate = rtw_rate_section[rs][j]; + pwr_index = hal->tx_pwr_tbl[path][rate]; + shift = rate & 0x3; + phy_pwr_idx |= ((u32)pwr_index << (shift * 8)); + if (shift == 0x3 || rate == DESC_RATEVHT1SS_MCS9) { + rate_idx = rate & 0xfc; + rtw_write32(rtwdev, offset_txagc[path] + rate_idx, + phy_pwr_idx); + phy_pwr_idx = 0; + } + } +} + +static void rtw8821c_set_tx_power_index(struct rtw_dev *rtwdev) +{ + struct rtw_hal *hal = &rtwdev->hal; + int rs, path; + + for (path = 0; path < hal->rf_path_num; path++) { + for (rs = 0; rs < RTW_RATE_SECTION_MAX; rs++) { + if (rs == RTW_RATE_SECTION_HT_2S || + rs == RTW_RATE_SECTION_VHT_2S) + continue; + rtw8821c_set_tx_power_index_by_rate(rtwdev, path, rs); + } + } +} + +static void rtw8821c_false_alarm_statistics(struct rtw_dev *rtwdev) +{ + struct rtw_dm_info *dm_info = &rtwdev->dm_info; + u32 cck_enable; + u32 cck_fa_cnt; + u32 ofdm_fa_cnt; + u32 crc32_cnt; + u32 cca32_cnt; + + cck_enable = rtw_read32(rtwdev, REG_RXPSEL) & BIT(28); + cck_fa_cnt = rtw_read16(rtwdev, REG_FA_CCK); + ofdm_fa_cnt = rtw_read16(rtwdev, REG_FA_OFDM); + + dm_info->cck_fa_cnt = cck_fa_cnt; + dm_info->ofdm_fa_cnt = ofdm_fa_cnt; + if (cck_enable) + dm_info->total_fa_cnt += cck_fa_cnt; + dm_info->total_fa_cnt = ofdm_fa_cnt; + + crc32_cnt = rtw_read32(rtwdev, REG_CRC_CCK); + dm_info->cck_ok_cnt = FIELD_GET(GENMASK(15, 0), crc32_cnt); + dm_info->cck_err_cnt = FIELD_GET(GENMASK(31, 16), crc32_cnt); + + crc32_cnt = rtw_read32(rtwdev, REG_CRC_OFDM); + dm_info->ofdm_ok_cnt = FIELD_GET(GENMASK(15, 0), crc32_cnt); + dm_info->ofdm_err_cnt = FIELD_GET(GENMASK(31, 16), crc32_cnt); + + crc32_cnt = rtw_read32(rtwdev, REG_CRC_HT); + dm_info->ht_ok_cnt = FIELD_GET(GENMASK(15, 0), crc32_cnt); + dm_info->ht_err_cnt = FIELD_GET(GENMASK(31, 16), crc32_cnt); + + crc32_cnt = rtw_read32(rtwdev, REG_CRC_VHT); + dm_info->vht_ok_cnt = FIELD_GET(GENMASK(15, 0), crc32_cnt); + dm_info->vht_err_cnt = FIELD_GET(GENMASK(31, 16), crc32_cnt); + + cca32_cnt = rtw_read32(rtwdev, REG_CCA_OFDM); + dm_info->ofdm_cca_cnt = FIELD_GET(GENMASK(31, 16), cca32_cnt); + dm_info->total_cca_cnt = dm_info->ofdm_cca_cnt; + if (cck_enable) { + cca32_cnt = rtw_read32(rtwdev, REG_CCA_CCK); + dm_info->cck_cca_cnt = FIELD_GET(GENMASK(15, 0), cca32_cnt); + dm_info->total_cca_cnt += dm_info->cck_cca_cnt; + } + + rtw_write32_set(rtwdev, REG_FAS, BIT(17)); + rtw_write32_clr(rtwdev, REG_FAS, BIT(17)); + rtw_write32_clr(rtwdev, REG_RXDESC, BIT(15)); + rtw_write32_set(rtwdev, REG_RXDESC, BIT(15)); + rtw_write32_set(rtwdev, REG_CNTRST, BIT(0)); + rtw_write32_clr(rtwdev, REG_CNTRST, BIT(0)); +} + +static void rtw8821c_do_iqk(struct rtw_dev *rtwdev) +{ + static int do_iqk_cnt; + struct rtw_iqk_para para = {.clear = 0, .segment_iqk = 0}; + u32 rf_reg, iqk_fail_mask; + int counter; + bool reload; + + if (rtw_is_assoc(rtwdev)) + para.segment_iqk = 1; + + rtw_fw_do_iqk(rtwdev, ¶); + + for (counter = 0; counter < 300; counter++) { + rf_reg = rtw_read_rf(rtwdev, RF_PATH_A, RF_DTXLOK, RFREG_MASK); + if (rf_reg == 0xabcde) + break; + msleep(20); + } + rtw_write_rf(rtwdev, RF_PATH_A, RF_DTXLOK, RFREG_MASK, 0x0); + + reload = !!rtw_read32_mask(rtwdev, REG_IQKFAILMSK, BIT(16)); + iqk_fail_mask = rtw_read32_mask(rtwdev, REG_IQKFAILMSK, GENMASK(7, 0)); + rtw_dbg(rtwdev, RTW_DBG_PHY, + "iqk counter=%d reload=%d do_iqk_cnt=%d n_iqk_fail(mask)=0x%02x\n", + counter, reload, ++do_iqk_cnt, iqk_fail_mask); +} + +static void rtw8821c_phy_calibration(struct rtw_dev *rtwdev) +{ + rtw8821c_do_iqk(rtwdev); +} + +static void +rtw8821c_txagc_swing_offset(struct rtw_dev *rtwdev, u8 pwr_idx_offset, + s8 pwr_idx_offset_lower, + s8 *txagc_idx, u8 *swing_idx) +{ + struct rtw_dm_info *dm_info = &rtwdev->dm_info; + s8 delta_pwr_idx = dm_info->delta_power_index[RF_PATH_A]; + u8 swing_upper_bound = dm_info->default_ofdm_index + 10; + u8 swing_lower_bound = 0; + u8 max_pwr_idx_offset = 0xf; + s8 agc_index = 0; + u8 swing_index = dm_info->default_ofdm_index; + + pwr_idx_offset = min_t(u8, pwr_idx_offset, max_pwr_idx_offset); + pwr_idx_offset_lower = max_t(s8, pwr_idx_offset_lower, -15); + + if (delta_pwr_idx >= 0) { + if (delta_pwr_idx <= pwr_idx_offset) { + agc_index = delta_pwr_idx; + swing_index = dm_info->default_ofdm_index; + } else if (delta_pwr_idx > pwr_idx_offset) { + agc_index = pwr_idx_offset; + swing_index = dm_info->default_ofdm_index + + delta_pwr_idx - pwr_idx_offset; + swing_index = min_t(u8, swing_index, swing_upper_bound); + } + } else if (delta_pwr_idx < 0) { + if (delta_pwr_idx >= pwr_idx_offset_lower) { + agc_index = delta_pwr_idx; + swing_index = dm_info->default_ofdm_index; + } else if (delta_pwr_idx < pwr_idx_offset_lower) { + if (dm_info->default_ofdm_index > + (pwr_idx_offset_lower - delta_pwr_idx)) + swing_index = dm_info->default_ofdm_index + + delta_pwr_idx - pwr_idx_offset_lower; + else + swing_index = swing_lower_bound; + + agc_index = pwr_idx_offset_lower; + } + } + + if (swing_index >= ARRAY_SIZE(rtw8821c_txscale_tbl)) { + rtw_warn(rtwdev, "swing index overflow\n"); + swing_index = ARRAY_SIZE(rtw8821c_txscale_tbl) - 1; + } + + *txagc_idx = agc_index; + *swing_idx = swing_index; +} + +static void rtw8821c_pwrtrack_set_pwr(struct rtw_dev *rtwdev, u8 pwr_idx_offset, + s8 pwr_idx_offset_lower) +{ + s8 txagc_idx; + u8 swing_idx; + + rtw8821c_txagc_swing_offset(rtwdev, pwr_idx_offset, pwr_idx_offset_lower, + &txagc_idx, &swing_idx); + rtw_write32_mask(rtwdev, REG_TXAGCIDX, GENMASK(6, 1), txagc_idx); + rtw_write32_mask(rtwdev, REG_TXSCALE_A, GENMASK(31, 21), + rtw8821c_txscale_tbl[swing_idx]); +} + +static void rtw8821c_pwrtrack_set(struct rtw_dev *rtwdev) +{ + struct rtw_dm_info *dm_info = &rtwdev->dm_info; + u8 pwr_idx_offset, tx_pwr_idx; + s8 pwr_idx_offset_lower; + u8 channel = rtwdev->hal.current_channel; + u8 band_width = rtwdev->hal.current_band_width; + u8 regd = rtwdev->regd.txpwr_regd; + u8 tx_rate = dm_info->tx_rate; + u8 max_pwr_idx = rtwdev->chip->max_power_index; + + tx_pwr_idx = rtw_phy_get_tx_power_index(rtwdev, RF_PATH_A, tx_rate, + band_width, channel, regd); + + tx_pwr_idx = min_t(u8, tx_pwr_idx, max_pwr_idx); + + pwr_idx_offset = max_pwr_idx - tx_pwr_idx; + pwr_idx_offset_lower = 0 - tx_pwr_idx; + + rtw8821c_pwrtrack_set_pwr(rtwdev, pwr_idx_offset, pwr_idx_offset_lower); +} + +static void rtw8821c_phy_pwrtrack(struct rtw_dev *rtwdev) +{ + struct rtw_dm_info *dm_info = &rtwdev->dm_info; + struct rtw_swing_table swing_table; + u8 thermal_value, delta; + + rtw_phy_config_swing_table(rtwdev, &swing_table); + + if (rtwdev->efuse.thermal_meter[0] == 0xff) + return; + + thermal_value = rtw_read_rf(rtwdev, RF_PATH_A, RF_T_METER, 0xfc00); + + rtw_phy_pwrtrack_avg(rtwdev, thermal_value, RF_PATH_A); + + if (dm_info->pwr_trk_init_trigger) + dm_info->pwr_trk_init_trigger = false; + else if (!rtw_phy_pwrtrack_thermal_changed(rtwdev, thermal_value, + RF_PATH_A)) + goto iqk; + + delta = rtw_phy_pwrtrack_get_delta(rtwdev, RF_PATH_A); + + delta = min_t(u8, delta, RTW_PWR_TRK_TBL_SZ - 1); + + dm_info->delta_power_index[RF_PATH_A] = + rtw_phy_pwrtrack_get_pwridx(rtwdev, &swing_table, RF_PATH_A, + RF_PATH_A, delta); + if (dm_info->delta_power_index[RF_PATH_A] == + dm_info->delta_power_index_last[RF_PATH_A]) + goto iqk; + else + dm_info->delta_power_index_last[RF_PATH_A] = + dm_info->delta_power_index[RF_PATH_A]; + rtw8821c_pwrtrack_set(rtwdev); + +iqk: + if (rtw_phy_pwrtrack_need_iqk(rtwdev)) + rtw8821c_do_iqk(rtwdev); +} + +static void rtw8821c_pwr_track(struct rtw_dev *rtwdev) +{ + struct rtw_efuse *efuse = &rtwdev->efuse; + struct rtw_dm_info *dm_info = &rtwdev->dm_info; + + if (efuse->power_track_type != 0) + return; + + if (!dm_info->pwr_trk_triggered) { + rtw_write_rf(rtwdev, RF_PATH_A, RF_T_METER, + GENMASK(17, 16), 0x03); + dm_info->pwr_trk_triggered = true; + return; + } + + rtw8821c_phy_pwrtrack(rtwdev); + dm_info->pwr_trk_triggered = false; +} + +static void rtw8821c_bf_config_bfee_su(struct rtw_dev *rtwdev, + struct rtw_vif *vif, + struct rtw_bfee *bfee, bool enable) +{ + if (enable) + rtw_bf_enable_bfee_su(rtwdev, vif, bfee); + else + rtw_bf_remove_bfee_su(rtwdev, bfee); +} + +static void rtw8821c_bf_config_bfee_mu(struct rtw_dev *rtwdev, + struct rtw_vif *vif, + struct rtw_bfee *bfee, bool enable) +{ + if (enable) + rtw_bf_enable_bfee_mu(rtwdev, vif, bfee); + else + rtw_bf_remove_bfee_mu(rtwdev, bfee); +} + +static void rtw8821c_bf_config_bfee(struct rtw_dev *rtwdev, struct rtw_vif *vif, + struct rtw_bfee *bfee, bool enable) +{ + if (bfee->role == RTW_BFEE_SU) + rtw8821c_bf_config_bfee_su(rtwdev, vif, bfee, enable); + else if (bfee->role == RTW_BFEE_MU) + rtw8821c_bf_config_bfee_mu(rtwdev, vif, bfee, enable); + else + rtw_warn(rtwdev, "wrong bfee role\n"); +} + +static void rtw8821c_phy_cck_pd_set(struct rtw_dev *rtwdev, u8 new_lvl) +{ + struct rtw_dm_info *dm_info = &rtwdev->dm_info; + u8 pd[CCK_PD_LV_MAX] = {3, 7, 13, 13, 13}; + + if (dm_info->min_rssi > 60) { + new_lvl = 4; + pd[4] = 0x1d; + goto set_cck_pd; + } + + if (dm_info->cck_pd_lv[RTW_CHANNEL_WIDTH_20][RF_PATH_A] == new_lvl) + return; + + dm_info->cck_fa_avg = CCK_FA_AVG_RESET; + +set_cck_pd: + dm_info->cck_pd_lv[RTW_CHANNEL_WIDTH_20][RF_PATH_A] = new_lvl; + rtw_write32_mask(rtwdev, REG_PWRTH, 0x3f0000, pd[new_lvl]); + rtw_write32_mask(rtwdev, REG_PWRTH2, 0x1f0000, + dm_info->cck_pd_default + new_lvl * 2); +} + +static struct rtw_pwr_seq_cmd trans_carddis_to_cardemu_8821c[] = { + {0x0086, + RTW_PWR_CUT_ALL_MSK, + RTW_PWR_INTF_SDIO_MSK, + RTW_PWR_ADDR_SDIO, + RTW_PWR_CMD_WRITE, BIT(0), 0}, + {0x0086, + RTW_PWR_CUT_ALL_MSK, + RTW_PWR_INTF_SDIO_MSK, + RTW_PWR_ADDR_SDIO, + RTW_PWR_CMD_POLLING, BIT(1), BIT(1)}, + {0x004A, + RTW_PWR_CUT_ALL_MSK, + RTW_PWR_INTF_USB_MSK, + RTW_PWR_ADDR_MAC, + RTW_PWR_CMD_WRITE, BIT(0), 0}, + {0x0005, + RTW_PWR_CUT_ALL_MSK, + RTW_PWR_INTF_ALL_MSK, + RTW_PWR_ADDR_MAC, + RTW_PWR_CMD_WRITE, BIT(3) | BIT(4) | BIT(7), 0}, + {0x0300, + RTW_PWR_CUT_ALL_MSK, + RTW_PWR_INTF_PCI_MSK, + RTW_PWR_ADDR_MAC, + RTW_PWR_CMD_WRITE, 0xFF, 0}, + {0x0301, + RTW_PWR_CUT_ALL_MSK, + RTW_PWR_INTF_PCI_MSK, + RTW_PWR_ADDR_MAC, + RTW_PWR_CMD_WRITE, 0xFF, 0}, + {0xFFFF, + RTW_PWR_CUT_ALL_MSK, + RTW_PWR_INTF_ALL_MSK, + 0, + RTW_PWR_CMD_END, 0, 0}, +}; + +static struct rtw_pwr_seq_cmd trans_cardemu_to_act_8821c[] = { + {0x0020, + RTW_PWR_CUT_ALL_MSK, + RTW_PWR_INTF_USB_MSK | RTW_PWR_INTF_SDIO_MSK, + RTW_PWR_ADDR_MAC, + RTW_PWR_CMD_WRITE, BIT(0), BIT(0)}, + {0x0001, + RTW_PWR_CUT_ALL_MSK, + RTW_PWR_INTF_USB_MSK | RTW_PWR_INTF_SDIO_MSK, + RTW_PWR_ADDR_MAC, + RTW_PWR_CMD_DELAY, 1, RTW_PWR_DELAY_MS}, + {0x0000, + RTW_PWR_CUT_ALL_MSK, + RTW_PWR_INTF_USB_MSK | RTW_PWR_INTF_SDIO_MSK, + RTW_PWR_ADDR_MAC, + RTW_PWR_CMD_WRITE, BIT(5), 0}, + {0x0005, + RTW_PWR_CUT_ALL_MSK, + RTW_PWR_INTF_ALL_MSK, + RTW_PWR_ADDR_MAC, + RTW_PWR_CMD_WRITE, (BIT(4) | BIT(3) | BIT(2)), 0}, + {0x0075, + RTW_PWR_CUT_ALL_MSK, + RTW_PWR_INTF_PCI_MSK, + RTW_PWR_ADDR_MAC, + RTW_PWR_CMD_WRITE, BIT(0), BIT(0)}, + {0x0006, + RTW_PWR_CUT_ALL_MSK, + RTW_PWR_INTF_ALL_MSK, + RTW_PWR_ADDR_MAC, + RTW_PWR_CMD_POLLING, BIT(1), BIT(1)}, + {0x0075, + RTW_PWR_CUT_ALL_MSK, + RTW_PWR_INTF_PCI_MSK, + RTW_PWR_ADDR_MAC, + RTW_PWR_CMD_WRITE, BIT(0), 0}, + {0x0006, + RTW_PWR_CUT_ALL_MSK, + RTW_PWR_INTF_ALL_MSK, + RTW_PWR_ADDR_MAC, + RTW_PWR_CMD_WRITE, BIT(0), BIT(0)}, + {0x0005, + RTW_PWR_CUT_ALL_MSK, + RTW_PWR_INTF_ALL_MSK, + RTW_PWR_ADDR_MAC, + RTW_PWR_CMD_WRITE, BIT(7), 0}, + {0x0005, + RTW_PWR_CUT_ALL_MSK, + RTW_PWR_INTF_ALL_MSK, + RTW_PWR_ADDR_MAC, + RTW_PWR_CMD_WRITE, (BIT(4) | BIT(3)), 0}, + {0x10C3, + RTW_PWR_CUT_ALL_MSK, + RTW_PWR_INTF_USB_MSK, + RTW_PWR_ADDR_MAC, + RTW_PWR_CMD_WRITE, BIT(0), BIT(0)}, + {0x0005, + RTW_PWR_CUT_ALL_MSK, + RTW_PWR_INTF_ALL_MSK, + RTW_PWR_ADDR_MAC, + RTW_PWR_CMD_WRITE, BIT(0), BIT(0)}, + {0x0005, + RTW_PWR_CUT_ALL_MSK, + RTW_PWR_INTF_ALL_MSK, + RTW_PWR_ADDR_MAC, + RTW_PWR_CMD_POLLING, BIT(0), 0}, + {0x0020, + RTW_PWR_CUT_ALL_MSK, + RTW_PWR_INTF_ALL_MSK, + RTW_PWR_ADDR_MAC, + RTW_PWR_CMD_WRITE, BIT(3), BIT(3)}, + {0x0074, + RTW_PWR_CUT_ALL_MSK, + RTW_PWR_INTF_PCI_MSK, + RTW_PWR_ADDR_MAC, + RTW_PWR_CMD_WRITE, BIT(5), BIT(5)}, + {0x0022, + RTW_PWR_CUT_ALL_MSK, + RTW_PWR_INTF_PCI_MSK, + RTW_PWR_ADDR_MAC, + RTW_PWR_CMD_WRITE, BIT(1), 0}, + {0x0062, + RTW_PWR_CUT_ALL_MSK, + RTW_PWR_INTF_PCI_MSK, + RTW_PWR_ADDR_MAC, + RTW_PWR_CMD_WRITE, (BIT(7) | BIT(6) | BIT(5)), + (BIT(7) | BIT(6) | BIT(5))}, + {0x0061, + RTW_PWR_CUT_ALL_MSK, + RTW_PWR_INTF_PCI_MSK, + RTW_PWR_ADDR_MAC, + RTW_PWR_CMD_WRITE, (BIT(7) | BIT(6) | BIT(5)), 0}, + {0x007C, + RTW_PWR_CUT_ALL_MSK, + RTW_PWR_INTF_ALL_MSK, + RTW_PWR_ADDR_MAC, + RTW_PWR_CMD_WRITE, BIT(1), 0}, + {0xFFFF, + RTW_PWR_CUT_ALL_MSK, + RTW_PWR_INTF_ALL_MSK, + 0, + RTW_PWR_CMD_END, 0, 0}, +}; + +static struct rtw_pwr_seq_cmd trans_act_to_cardemu_8821c[] = { + {0x0093, + RTW_PWR_CUT_ALL_MSK, + RTW_PWR_INTF_ALL_MSK, + RTW_PWR_ADDR_MAC, + RTW_PWR_CMD_WRITE, BIT(3), 0}, + {0x001F, + RTW_PWR_CUT_ALL_MSK, + RTW_PWR_INTF_ALL_MSK, + RTW_PWR_ADDR_MAC, + RTW_PWR_CMD_WRITE, 0xFF, 0}, + {0x0049, + RTW_PWR_CUT_ALL_MSK, + RTW_PWR_INTF_ALL_MSK, + RTW_PWR_ADDR_MAC, + RTW_PWR_CMD_WRITE, BIT(1), 0}, + {0x0006, + RTW_PWR_CUT_ALL_MSK, + RTW_PWR_INTF_ALL_MSK, + RTW_PWR_ADDR_MAC, + RTW_PWR_CMD_WRITE, BIT(0), BIT(0)}, + {0x0002, + RTW_PWR_CUT_ALL_MSK, + RTW_PWR_INTF_ALL_MSK, + RTW_PWR_ADDR_MAC, + RTW_PWR_CMD_WRITE, BIT(1), 0}, + {0x10C3, + RTW_PWR_CUT_ALL_MSK, + RTW_PWR_INTF_USB_MSK, + RTW_PWR_ADDR_MAC, + RTW_PWR_CMD_WRITE, BIT(0), 0}, + {0x0005, + RTW_PWR_CUT_ALL_MSK, + RTW_PWR_INTF_ALL_MSK, + RTW_PWR_ADDR_MAC, + RTW_PWR_CMD_WRITE, BIT(1), BIT(1)}, + {0x0005, + RTW_PWR_CUT_ALL_MSK, + RTW_PWR_INTF_ALL_MSK, + RTW_PWR_ADDR_MAC, + RTW_PWR_CMD_POLLING, BIT(1), 0}, + {0x0020, + RTW_PWR_CUT_ALL_MSK, + RTW_PWR_INTF_ALL_MSK, + RTW_PWR_ADDR_MAC, + RTW_PWR_CMD_WRITE, BIT(3), 0}, + {0x0000, + RTW_PWR_CUT_ALL_MSK, + RTW_PWR_INTF_USB_MSK | RTW_PWR_INTF_SDIO_MSK, + RTW_PWR_ADDR_MAC, + RTW_PWR_CMD_WRITE, BIT(5), BIT(5)}, + {0xFFFF, + RTW_PWR_CUT_ALL_MSK, + RTW_PWR_INTF_ALL_MSK, + 0, + RTW_PWR_CMD_END, 0, 0}, +}; + +static struct rtw_pwr_seq_cmd trans_cardemu_to_carddis_8821c[] = { + {0x0007, + RTW_PWR_CUT_ALL_MSK, + RTW_PWR_INTF_USB_MSK | RTW_PWR_INTF_SDIO_MSK, + RTW_PWR_ADDR_MAC, + RTW_PWR_CMD_WRITE, 0xFF, 0x20}, + {0x0067, + RTW_PWR_CUT_ALL_MSK, + RTW_PWR_INTF_ALL_MSK, + RTW_PWR_ADDR_MAC, + RTW_PWR_CMD_WRITE, BIT(5), 0}, + {0x0005, + RTW_PWR_CUT_ALL_MSK, + RTW_PWR_INTF_PCI_MSK, + RTW_PWR_ADDR_MAC, + RTW_PWR_CMD_WRITE, BIT(2), BIT(2)}, + {0x004A, + RTW_PWR_CUT_ALL_MSK, + RTW_PWR_INTF_USB_MSK, + RTW_PWR_ADDR_MAC, + RTW_PWR_CMD_WRITE, BIT(0), 0}, + {0x0067, + RTW_PWR_CUT_ALL_MSK, + RTW_PWR_INTF_SDIO_MSK, + RTW_PWR_ADDR_MAC, + RTW_PWR_CMD_WRITE, BIT(5), 0}, + {0x0067, + RTW_PWR_CUT_ALL_MSK, + RTW_PWR_INTF_SDIO_MSK, + RTW_PWR_ADDR_MAC, + RTW_PWR_CMD_WRITE, BIT(4), 0}, + {0x004F, + RTW_PWR_CUT_ALL_MSK, + RTW_PWR_INTF_SDIO_MSK, + RTW_PWR_ADDR_MAC, + RTW_PWR_CMD_WRITE, BIT(0), 0}, + {0x0067, + RTW_PWR_CUT_ALL_MSK, + RTW_PWR_INTF_SDIO_MSK, + RTW_PWR_ADDR_MAC, + RTW_PWR_CMD_WRITE, BIT(1), 0}, + {0x0046, + RTW_PWR_CUT_ALL_MSK, + RTW_PWR_INTF_SDIO_MSK, + RTW_PWR_ADDR_MAC, + RTW_PWR_CMD_WRITE, BIT(6), BIT(6)}, + {0x0067, + RTW_PWR_CUT_ALL_MSK, + RTW_PWR_INTF_SDIO_MSK, + RTW_PWR_ADDR_MAC, + RTW_PWR_CMD_WRITE, BIT(2), 0}, + {0x0046, + RTW_PWR_CUT_ALL_MSK, + RTW_PWR_INTF_SDIO_MSK, + RTW_PWR_ADDR_MAC, + RTW_PWR_CMD_WRITE, BIT(7), BIT(7)}, + {0x0062, + RTW_PWR_CUT_ALL_MSK, + RTW_PWR_INTF_SDIO_MSK, + RTW_PWR_ADDR_MAC, + RTW_PWR_CMD_WRITE, BIT(4), BIT(4)}, + {0x0081, + RTW_PWR_CUT_ALL_MSK, + RTW_PWR_INTF_ALL_MSK, + RTW_PWR_ADDR_MAC, + RTW_PWR_CMD_WRITE, BIT(7) | BIT(6), 0}, + {0x0005, + RTW_PWR_CUT_ALL_MSK, + RTW_PWR_INTF_USB_MSK | RTW_PWR_INTF_SDIO_MSK, + RTW_PWR_ADDR_MAC, + RTW_PWR_CMD_WRITE, BIT(3) | BIT(4), BIT(3)}, + {0x0086, + RTW_PWR_CUT_ALL_MSK, + RTW_PWR_INTF_SDIO_MSK, + RTW_PWR_ADDR_SDIO, + RTW_PWR_CMD_WRITE, BIT(0), BIT(0)}, + {0x0086, + RTW_PWR_CUT_ALL_MSK, + RTW_PWR_INTF_SDIO_MSK, + RTW_PWR_ADDR_SDIO, + RTW_PWR_CMD_POLLING, BIT(1), 0}, + {0x0090, + RTW_PWR_CUT_ALL_MSK, + RTW_PWR_INTF_USB_MSK | RTW_PWR_INTF_PCI_MSK, + RTW_PWR_ADDR_MAC, + RTW_PWR_CMD_WRITE, BIT(1), 0}, + {0x0044, + RTW_PWR_CUT_ALL_MSK, + RTW_PWR_INTF_SDIO_MSK, + RTW_PWR_ADDR_SDIO, + RTW_PWR_CMD_WRITE, 0xFF, 0}, + {0x0040, + RTW_PWR_CUT_ALL_MSK, + RTW_PWR_INTF_SDIO_MSK, + RTW_PWR_ADDR_SDIO, + RTW_PWR_CMD_WRITE, 0xFF, 0x90}, + {0x0041, + RTW_PWR_CUT_ALL_MSK, + RTW_PWR_INTF_SDIO_MSK, + RTW_PWR_ADDR_SDIO, + RTW_PWR_CMD_WRITE, 0xFF, 0x00}, + {0x0042, + RTW_PWR_CUT_ALL_MSK, + RTW_PWR_INTF_SDIO_MSK, + RTW_PWR_ADDR_SDIO, + RTW_PWR_CMD_WRITE, 0xFF, 0x04}, + {0xFFFF, + RTW_PWR_CUT_ALL_MSK, + RTW_PWR_INTF_ALL_MSK, + 0, + RTW_PWR_CMD_END, 0, 0}, +}; + +static const struct rtw_pwr_seq_cmd *card_enable_flow_8821c[] = { + trans_carddis_to_cardemu_8821c, + trans_cardemu_to_act_8821c, + NULL +}; + +static const struct rtw_pwr_seq_cmd *card_disable_flow_8821c[] = { + trans_act_to_cardemu_8821c, + trans_cardemu_to_carddis_8821c, + NULL +}; + +static const struct rtw_intf_phy_para usb2_param_8821c[] = { + {0xFFFF, 0x00, + RTW_IP_SEL_PHY, + RTW_INTF_PHY_CUT_ALL, + RTW_INTF_PHY_PLATFORM_ALL}, +}; + +static const struct rtw_intf_phy_para usb3_param_8821c[] = { + {0xFFFF, 0x0000, + RTW_IP_SEL_PHY, + RTW_INTF_PHY_CUT_ALL, + RTW_INTF_PHY_PLATFORM_ALL}, +}; + +static const struct rtw_intf_phy_para pcie_gen1_param_8821c[] = { + {0x0009, 0x6380, + RTW_IP_SEL_PHY, + RTW_INTF_PHY_CUT_ALL, + RTW_INTF_PHY_PLATFORM_ALL}, + {0xFFFF, 0x0000, + RTW_IP_SEL_PHY, + RTW_INTF_PHY_CUT_ALL, + RTW_INTF_PHY_PLATFORM_ALL}, +}; + +static const struct rtw_intf_phy_para pcie_gen2_param_8821c[] = { + {0xFFFF, 0x0000, + RTW_IP_SEL_PHY, + RTW_INTF_PHY_CUT_ALL, + RTW_INTF_PHY_PLATFORM_ALL}, +}; + +static const struct rtw_intf_phy_para_table phy_para_table_8821c = { + .usb2_para = usb2_param_8821c, + .usb3_para = usb3_param_8821c, + .gen1_para = pcie_gen1_param_8821c, + .gen2_para = pcie_gen2_param_8821c, + .n_usb2_para = ARRAY_SIZE(usb2_param_8821c), + .n_usb3_para = ARRAY_SIZE(usb2_param_8821c), + .n_gen1_para = ARRAY_SIZE(pcie_gen1_param_8821c), + .n_gen2_para = ARRAY_SIZE(pcie_gen2_param_8821c), +}; + +static const struct rtw_rfe_def rtw8821c_rfe_defs[] = { + [0] = RTW_DEF_RFE(8821c, 0, 0), +}; + +static struct rtw_hw_reg rtw8821c_dig[] = { + [0] = { .addr = 0xc50, .mask = 0x7f }, +}; + +static const struct rtw_ltecoex_addr rtw8821c_ltecoex_addr = { + .ctrl = LTECOEX_ACCESS_CTRL, + .wdata = LTECOEX_WRITE_DATA, + .rdata = LTECOEX_READ_DATA, +}; + +static struct rtw_page_table page_table_8821c[] = { + /* not sure what [0] stands for */ + {16, 16, 16, 14, 1}, + {16, 16, 16, 14, 1}, + {16, 16, 0, 0, 1}, + {16, 16, 16, 0, 1}, + {16, 16, 16, 14, 1}, +}; + +static struct rtw_rqpn rqpn_table_8821c[] = { + /* not sure what [0] stands for */ + {RTW_DMA_MAPPING_NORMAL, RTW_DMA_MAPPING_NORMAL, + RTW_DMA_MAPPING_LOW, RTW_DMA_MAPPING_LOW, + RTW_DMA_MAPPING_EXTRA, RTW_DMA_MAPPING_HIGH}, + {RTW_DMA_MAPPING_NORMAL, RTW_DMA_MAPPING_NORMAL, + RTW_DMA_MAPPING_LOW, RTW_DMA_MAPPING_LOW, + RTW_DMA_MAPPING_EXTRA, RTW_DMA_MAPPING_HIGH}, + {RTW_DMA_MAPPING_NORMAL, RTW_DMA_MAPPING_NORMAL, + RTW_DMA_MAPPING_NORMAL, RTW_DMA_MAPPING_HIGH, + RTW_DMA_MAPPING_HIGH, RTW_DMA_MAPPING_HIGH}, + {RTW_DMA_MAPPING_NORMAL, RTW_DMA_MAPPING_NORMAL, + RTW_DMA_MAPPING_LOW, RTW_DMA_MAPPING_LOW, + RTW_DMA_MAPPING_HIGH, RTW_DMA_MAPPING_HIGH}, + {RTW_DMA_MAPPING_NORMAL, RTW_DMA_MAPPING_NORMAL, + RTW_DMA_MAPPING_LOW, RTW_DMA_MAPPING_LOW, + RTW_DMA_MAPPING_EXTRA, RTW_DMA_MAPPING_HIGH}, +}; + +static struct rtw_prioq_addrs prioq_addrs_8821c = { + .prio[RTW_DMA_MAPPING_EXTRA] = { + .rsvd = REG_FIFOPAGE_INFO_4, .avail = REG_FIFOPAGE_INFO_4 + 2, + }, + .prio[RTW_DMA_MAPPING_LOW] = { + .rsvd = REG_FIFOPAGE_INFO_2, .avail = REG_FIFOPAGE_INFO_2 + 2, + }, + .prio[RTW_DMA_MAPPING_NORMAL] = { + .rsvd = REG_FIFOPAGE_INFO_3, .avail = REG_FIFOPAGE_INFO_3 + 2, + }, + .prio[RTW_DMA_MAPPING_HIGH] = { + .rsvd = REG_FIFOPAGE_INFO_1, .avail = REG_FIFOPAGE_INFO_1 + 2, + }, + .wsize = true, +}; + +static struct rtw_chip_ops rtw8821c_ops = { + .phy_set_param = rtw8821c_phy_set_param, + .read_efuse = rtw8821c_read_efuse, + .query_rx_desc = rtw8821c_query_rx_desc, + .set_channel = rtw8821c_set_channel, + .mac_init = rtw8821c_mac_init, + .read_rf = rtw_phy_read_rf, + .write_rf = rtw_phy_write_rf_reg_sipi, + .set_antenna = NULL, + .set_tx_power_index = rtw8821c_set_tx_power_index, + .cfg_ldo25 = rtw8821c_cfg_ldo25, + .false_alarm_statistics = rtw8821c_false_alarm_statistics, + .phy_calibration = rtw8821c_phy_calibration, + .cck_pd_set = rtw8821c_phy_cck_pd_set, + .pwr_track = rtw8821c_pwr_track, + .config_bfee = rtw8821c_bf_config_bfee, + .set_gid_table = rtw_bf_set_gid_table, + .cfg_csi_rate = rtw_bf_cfg_csi_rate, +}; + +static const u8 rtw8821c_pwrtrk_5gb_n[][RTW_PWR_TRK_TBL_SZ] = { + {0, 1, 1, 2, 3, 3, 3, 4, 4, 5, 5, 6, 6, 6, 7, 8, 8, 8, 9, 9, 9, 10, 10, + 11, 11, 12, 12, 12, 12, 12}, + {0, 1, 1, 1, 2, 3, 3, 4, 4, 5, 5, 5, 6, 6, 7, 8, 8, 9, 9, 10, 10, 11, + 11, 12, 12, 12, 12, 12, 12, 12}, + {0, 1, 2, 2, 3, 4, 4, 4, 4, 5, 5, 6, 6, 7, 7, 8, 8, 9, 9, 9, 10, 10, 11, + 11, 12, 12, 12, 12, 12, 12}, +}; + +static const u8 rtw8821c_pwrtrk_5gb_p[][RTW_PWR_TRK_TBL_SZ] = { + {0, 1, 1, 2, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7, 7, 8, 8, 9, 9, 10, 11, 11, + 12, 12, 12, 12, 12, 12, 12}, + {0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 5, 6, 7, 7, 8, 8, 9, 10, 10, 11, 11, + 12, 12, 12, 12, 12, 12, 12, 12}, + {0, 1, 1, 1, 2, 3, 3, 3, 4, 4, 4, 5, 6, 6, 7, 7, 8, 8, 9, 10, 10, 11, + 11, 12, 12, 12, 12, 12, 12, 12}, +}; + +static const u8 rtw8821c_pwrtrk_5ga_n[][RTW_PWR_TRK_TBL_SZ] = { + {0, 1, 1, 2, 3, 3, 3, 4, 4, 5, 5, 6, 6, 6, 7, 8, 8, 8, 9, 9, 9, 10, 10, + 11, 11, 12, 12, 12, 12, 12}, + {0, 1, 1, 1, 2, 3, 3, 4, 4, 5, 5, 5, 6, 6, 7, 8, 8, 9, 9, 10, 10, 11, + 11, 12, 12, 12, 12, 12, 12, 12}, + {0, 1, 2, 2, 3, 4, 4, 4, 4, 5, 5, 6, 6, 7, 7, 8, 8, 9, 9, 9, 10, 10, 11, + 11, 12, 12, 12, 12, 12, 12}, +}; + +static const u8 rtw8821c_pwrtrk_5ga_p[][RTW_PWR_TRK_TBL_SZ] = { + {0, 1, 1, 2, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7, 7, 8, 8, 9, 9, 10, 11, 11, + 12, 12, 12, 12, 12, 12, 12}, + {0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 5, 6, 7, 7, 8, 8, 9, 10, 10, 11, 11, + 12, 12, 12, 12, 12, 12, 12, 12}, + {0, 1, 1, 1, 2, 3, 3, 3, 4, 4, 4, 5, 6, 6, 7, 7, 8, 8, 9, 10, 10, 11, + 11, 12, 12, 12, 12, 12, 12, 12}, +}; + +static const u8 rtw8821c_pwrtrk_2gb_n[] = { + 0, 0, 0, 1, 1, 1, 2, 2, 2, 3, 3, 3, 3, 3, 4, 4, + 4, 4, 5, 5, 5, 5, 6, 6, 6, 7, 7, 8, 8, 9 +}; + +static const u8 rtw8821c_pwrtrk_2gb_p[] = { + 0, 1, 1, 1, 1, 2, 2, 2, 3, 3, 3, 3, 4, 4, 5, 5, + 5, 5, 6, 6, 6, 7, 7, 7, 8, 8, 9, 9, 9, 9 +}; + +static const u8 rtw8821c_pwrtrk_2ga_n[] = { + 0, 0, 0, 1, 1, 1, 2, 2, 2, 3, 3, 3, 3, 3, 4, 4, + 4, 4, 5, 5, 5, 5, 6, 6, 6, 7, 7, 8, 8, 9 +}; + +static const u8 rtw8821c_pwrtrk_2ga_p[] = { + 0, 1, 1, 1, 1, 2, 2, 2, 3, 3, 3, 3, 4, 4, 5, 5, + 5, 5, 6, 6, 6, 7, 7, 7, 8, 8, 9, 9, 9, 9 +}; + +static const u8 rtw8821c_pwrtrk_2g_cck_b_n[] = { + 0, 0, 1, 1, 1, 1, 2, 2, 2, 2, 3, 3, 3, 3, 4, 4, + 4, 5, 5, 5, 5, 6, 6, 7, 7, 8, 8, 9, 9, 9 +}; + +static const u8 rtw8821c_pwrtrk_2g_cck_b_p[] = { + 0, 1, 1, 1, 1, 2, 2, 2, 3, 3, 3, 4, 4, 4, 5, 5, + 5, 6, 6, 7, 7, 7, 8, 8, 9, 9, 9, 9, 9, 9 +}; + +static const u8 rtw8821c_pwrtrk_2g_cck_a_n[] = { + 0, 0, 1, 1, 1, 1, 2, 2, 2, 2, 3, 3, 3, 3, 4, 4, + 4, 5, 5, 5, 5, 6, 6, 7, 7, 8, 8, 9, 9, 9 +}; + +static const u8 rtw8821c_pwrtrk_2g_cck_a_p[] = { + 0, 1, 1, 1, 1, 2, 2, 2, 3, 3, 3, 4, 4, 4, 5, 5, + 5, 6, 6, 7, 7, 7, 8, 8, 9, 9, 9, 9, 9, 9 +}; + +const struct rtw_pwr_track_tbl rtw8821c_rtw_pwr_track_tbl = { + .pwrtrk_5gb_n[0] = rtw8821c_pwrtrk_5gb_n[0], + .pwrtrk_5gb_n[1] = rtw8821c_pwrtrk_5gb_n[1], + .pwrtrk_5gb_n[2] = rtw8821c_pwrtrk_5gb_n[2], + .pwrtrk_5gb_p[0] = rtw8821c_pwrtrk_5gb_p[0], + .pwrtrk_5gb_p[1] = rtw8821c_pwrtrk_5gb_p[1], + .pwrtrk_5gb_p[2] = rtw8821c_pwrtrk_5gb_p[2], + .pwrtrk_5ga_n[0] = rtw8821c_pwrtrk_5ga_n[0], + .pwrtrk_5ga_n[1] = rtw8821c_pwrtrk_5ga_n[1], + .pwrtrk_5ga_n[2] = rtw8821c_pwrtrk_5ga_n[2], + .pwrtrk_5ga_p[0] = rtw8821c_pwrtrk_5ga_p[0], + .pwrtrk_5ga_p[1] = rtw8821c_pwrtrk_5ga_p[1], + .pwrtrk_5ga_p[2] = rtw8821c_pwrtrk_5ga_p[2], + .pwrtrk_2gb_n = rtw8821c_pwrtrk_2gb_n, + .pwrtrk_2gb_p = rtw8821c_pwrtrk_2gb_p, + .pwrtrk_2ga_n = rtw8821c_pwrtrk_2ga_n, + .pwrtrk_2ga_p = rtw8821c_pwrtrk_2ga_p, + .pwrtrk_2g_cckb_n = rtw8821c_pwrtrk_2g_cck_b_n, + .pwrtrk_2g_cckb_p = rtw8821c_pwrtrk_2g_cck_b_p, + .pwrtrk_2g_ccka_n = rtw8821c_pwrtrk_2g_cck_a_n, + .pwrtrk_2g_ccka_p = rtw8821c_pwrtrk_2g_cck_a_p, +}; + +struct rtw_chip_info rtw8821c_hw_spec = { + .ops = &rtw8821c_ops, + .id = RTW_CHIP_TYPE_8821C, + .fw_name = "rtw88/rtw8821c_fw.bin", + .wlan_cpu = RTW_WCPU_11AC, + .tx_pkt_desc_sz = 48, + .tx_buf_desc_sz = 16, + .rx_pkt_desc_sz = 24, + .rx_buf_desc_sz = 8, + .phy_efuse_size = 512, + .log_efuse_size = 512, + .ptct_efuse_size = 96, + .txff_size = 65536, + .rxff_size = 16384, + .txgi_factor = 1, + .is_pwr_by_rate_dec = true, + .max_power_index = 0x3f, + .csi_buf_pg_num = 0, + .band = RTW_BAND_2G | RTW_BAND_5G, + .page_size = 128, + .dig_min = 0x1c, + .ht_supported = true, + .vht_supported = true, + .lps_deep_mode_supported = BIT(LPS_DEEP_MODE_LCLK), + .sys_func_en = 0xD8, + .pwr_on_seq = card_enable_flow_8821c, + .pwr_off_seq = card_disable_flow_8821c, + .page_table = page_table_8821c, + .rqpn_table = rqpn_table_8821c, + .prioq_addrs = &prioq_addrs_8821c, + .intf_table = &phy_para_table_8821c, + .dig = rtw8821c_dig, + .rf_base_addr = {0x2800, 0x2c00}, + .rf_sipi_addr = {0xc90, 0xe90}, + .ltecoex_addr = &rtw8821c_ltecoex_addr, + .mac_tbl = &rtw8821c_mac_tbl, + .agc_tbl = &rtw8821c_agc_tbl, + .bb_tbl = &rtw8821c_bb_tbl, + .rf_tbl = {&rtw8821c_rf_a_tbl}, + .rfe_defs = rtw8821c_rfe_defs, + .rfe_defs_size = ARRAY_SIZE(rtw8821c_rfe_defs), + .rx_ldpc = false, + .pwr_track_tbl = &rtw8821c_rtw_pwr_track_tbl, + .iqk_threshold = 8, + .bfer_su_max_num = 2, + .bfer_mu_max_num = 1, +}; +EXPORT_SYMBOL(rtw8821c_hw_spec); + +MODULE_FIRMWARE("rtw88/rtw8821c_fw.bin"); + +MODULE_AUTHOR("Realtek Corporation"); +MODULE_DESCRIPTION("Realtek 802.11ac wireless 8821c driver"); +MODULE_LICENSE("Dual BSD/GPL"); diff --git a/drivers/net/wireless/realtek/rtw88/rtw8821c.h b/drivers/net/wireless/realtek/rtw88/rtw8821c.h new file mode 100644 index 000000000000..166bd0e9294e --- /dev/null +++ b/drivers/net/wireless/realtek/rtw88/rtw8821c.h @@ -0,0 +1,233 @@ +/* SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause */ +/* Copyright(c) 2018-2019 Realtek Corporation + */ + +#ifndef __RTW8821C_H__ +#define __RTW8821C_H__ + +#include <asm/byteorder.h> + +#define RCR_VHT_ACK BIT(26) + +struct rtw8821ce_efuse { + u8 mac_addr[ETH_ALEN]; /* 0xd0 */ + u8 vender_id[2]; + u8 device_id[2]; + u8 sub_vender_id[2]; + u8 sub_device_id[2]; + u8 pmc[2]; + u8 exp_device_cap[2]; + u8 msi_cap; + u8 ltr_cap; /* 0xe3 */ + u8 exp_link_control[2]; + u8 link_cap[4]; + u8 link_control[2]; + u8 serial_number[8]; + u8 res0:2; /* 0xf4 */ + u8 ltr_en:1; + u8 res1:2; + u8 obff:2; + u8 res2:3; + u8 obff_cap:2; + u8 res3:4; + u8 res4[3]; + u8 class_code[3]; + u8 pci_pm_L1_2_supp:1; + u8 pci_pm_L1_1_supp:1; + u8 aspm_pm_L1_2_supp:1; + u8 aspm_pm_L1_1_supp:1; + u8 L1_pm_substates_supp:1; + u8 res5:3; + u8 port_common_mode_restore_time; + u8 port_t_power_on_scale:2; + u8 res6:1; + u8 port_t_power_on_value:5; + u8 res7; +}; + +struct rtw8821c_efuse { + __le16 rtl_id; + u8 res0[0x0e]; + + /* power index for four RF paths */ + struct rtw_txpwr_idx txpwr_idx_table[4]; + + u8 channel_plan; /* 0xb8 */ + u8 xtal_k; + u8 thermal_meter; + u8 iqk_lck; + u8 pa_type; /* 0xbc */ + u8 lna_type_2g[2]; /* 0xbd */ + u8 lna_type_5g[2]; + u8 rf_board_option; + u8 rf_feature_option; + u8 rf_bt_setting; + u8 eeprom_version; + u8 eeprom_customer_id; + u8 tx_bb_swing_setting_2g; + u8 tx_bb_swing_setting_5g; + u8 tx_pwr_calibrate_rate; + u8 rf_antenna_option; /* 0xc9 */ + u8 rfe_option; + u8 country_code[2]; + u8 res[3]; + union { + struct rtw8821ce_efuse e; + }; +}; + +static inline void +_rtw_write32s_mask(struct rtw_dev *rtwdev, u32 addr, u32 mask, u32 data) +{ + /* 0xC00-0xCFF and 0xE00-0xEFF have the same layout */ + rtw_write32_mask(rtwdev, addr, mask, data); + rtw_write32_mask(rtwdev, addr + 0x200, mask, data); +} + +#define rtw_write32s_mask(rtwdev, addr, mask, data) \ + do { \ + BUILD_BUG_ON((addr) < 0xC00 || (addr) >= 0xD00); \ + \ + _rtw_write32s_mask(rtwdev, addr, mask, data); \ + } while (0) + +#define BIT_FEN_PCIEA BIT(6) +#define WLAN_SLOT_TIME 0x09 +#define WLAN_PIFS_TIME 0x19 +#define WLAN_SIFS_CCK_CONT_TX 0xA +#define WLAN_SIFS_OFDM_CONT_TX 0xE +#define WLAN_SIFS_CCK_TRX 0x10 +#define WLAN_SIFS_OFDM_TRX 0x10 +#define WLAN_VO_TXOP_LIMIT 0x186 +#define WLAN_VI_TXOP_LIMIT 0x3BC +#define WLAN_RDG_NAV 0x05 +#define WLAN_TXOP_NAV 0x1B +#define WLAN_CCK_RX_TSF 0x30 +#define WLAN_OFDM_RX_TSF 0x30 +#define WLAN_TBTT_PROHIBIT 0x04 +#define WLAN_TBTT_HOLD_TIME 0x064 +#define WLAN_DRV_EARLY_INT 0x04 +#define WLAN_BCN_DMA_TIME 0x02 + +#define WLAN_RX_FILTER0 0x0FFFFFFF +#define WLAN_RX_FILTER2 0xFFFF +#define WLAN_RCR_CFG 0xE400220E +#define WLAN_RXPKT_MAX_SZ 12288 +#define WLAN_RXPKT_MAX_SZ_512 (WLAN_RXPKT_MAX_SZ >> 9) + +#define WLAN_AMPDU_MAX_TIME 0x70 +#define WLAN_RTS_LEN_TH 0xFF +#define WLAN_RTS_TX_TIME_TH 0x08 +#define WLAN_MAX_AGG_PKT_LIMIT 0x20 +#define WLAN_RTS_MAX_AGG_PKT_LIMIT 0x20 +#define FAST_EDCA_VO_TH 0x06 +#define FAST_EDCA_VI_TH 0x06 +#define FAST_EDCA_BE_TH 0x06 +#define FAST_EDCA_BK_TH 0x06 +#define WLAN_BAR_RETRY_LIMIT 0x01 +#define WLAN_RA_TRY_RATE_AGG_LIMIT 0x08 + +#define WLAN_TX_FUNC_CFG1 0x30 +#define WLAN_TX_FUNC_CFG2 0x30 +#define WLAN_MAC_OPT_NORM_FUNC1 0x98 +#define WLAN_MAC_OPT_LB_FUNC1 0x80 +#define WLAN_MAC_OPT_FUNC2 0x30810041 + +#define WLAN_SIFS_CFG (WLAN_SIFS_CCK_CONT_TX | \ + (WLAN_SIFS_OFDM_CONT_TX << BIT_SHIFT_SIFS_OFDM_CTX) | \ + (WLAN_SIFS_CCK_TRX << BIT_SHIFT_SIFS_CCK_TRX) | \ + (WLAN_SIFS_OFDM_TRX << BIT_SHIFT_SIFS_OFDM_TRX)) + +#define WLAN_TBTT_TIME (WLAN_TBTT_PROHIBIT |\ + (WLAN_TBTT_HOLD_TIME << BIT_SHIFT_TBTT_HOLD_TIME_AP)) + +#define WLAN_NAV_CFG (WLAN_RDG_NAV | (WLAN_TXOP_NAV << 16)) +#define WLAN_RX_TSF_CFG (WLAN_CCK_RX_TSF | (WLAN_OFDM_RX_TSF) << 8) +#define WLAN_PRE_TXCNT_TIME_TH 0x1E4 + +/* phy status page0 */ +#define GET_PHY_STAT_P0_PWDB(phy_stat) \ + le32_get_bits(*((__le32 *)(phy_stat) + 0x00), GENMASK(15, 8)) + +/* phy status page1 */ +#define GET_PHY_STAT_P1_PWDB_A(phy_stat) \ + le32_get_bits(*((__le32 *)(phy_stat) + 0x00), GENMASK(15, 8)) +#define GET_PHY_STAT_P1_PWDB_B(phy_stat) \ + le32_get_bits(*((__le32 *)(phy_stat) + 0x00), GENMASK(23, 16)) +#define GET_PHY_STAT_P1_RF_MODE(phy_stat) \ + le32_get_bits(*((__le32 *)(phy_stat) + 0x03), GENMASK(29, 28)) +#define GET_PHY_STAT_P1_L_RXSC(phy_stat) \ + le32_get_bits(*((__le32 *)(phy_stat) + 0x01), GENMASK(11, 8)) +#define GET_PHY_STAT_P1_HT_RXSC(phy_stat) \ + le32_get_bits(*((__le32 *)(phy_stat) + 0x01), GENMASK(15, 12)) + +#define REG_INIRTS_RATE_SEL 0x0480 +#define REG_HTSTFWT 0x800 +#define REG_RXPSEL 0x808 +#define BIT_RX_PSEL_RST (BIT(28) | BIT(29)) +#define REG_TXPSEL 0x80c +#define REG_RXCCAMSK 0x814 +#define REG_CCASEL 0x82c +#define REG_PDMFTH 0x830 +#define REG_CCA2ND 0x838 +#define REG_L1WT 0x83c +#define REG_L1PKWT 0x840 +#define REG_MRC 0x850 +#define REG_CLKTRK 0x860 +#define REG_ADCCLK 0x8ac +#define REG_ADC160 0x8c4 +#define REG_ADC40 0x8c8 +#define REG_CHFIR 0x8f0 +#define REG_CDDTXP 0x93c +#define REG_TXPSEL1 0x940 +#define REG_ACBB0 0x948 +#define REG_ACBBRXFIR 0x94c +#define REG_ACGG2TBL 0x958 +#define REG_FAS 0x9a4 +#define REG_RXSB 0xa00 +#define REG_ADCINI 0xa04 +#define REG_PWRTH 0xa08 +#define REG_TXSF2 0xa24 +#define REG_TXSF6 0xa28 +#define REG_FA_CCK 0xa5c +#define REG_RXDESC 0xa2c +#define REG_ENTXCCK 0xa80 +#define REG_PWRTH2 0xaa8 +#define REG_CSRATIO 0xaaa +#define REG_TXFILTER 0xaac +#define REG_CNTRST 0xb58 +#define REG_AGCTR_A 0xc08 +#define REG_TXSCALE_A 0xc1c +#define REG_TXDFIR 0xc20 +#define REG_RXIGI_A 0xc50 +#define REG_TXAGCIDX 0xc94 +#define REG_TRSW 0xca0 +#define REG_RFESEL0 0xcb0 +#define REG_RFESEL8 0xcb4 +#define REG_RFECTL 0xcb8 +#define REG_RFEINV 0xcbc +#define REG_AGCTR_B 0xe08 +#define REG_RXIGI_B 0xe50 +#define REG_CRC_CCK 0xf04 +#define REG_CRC_OFDM 0xf14 +#define REG_CRC_HT 0xf10 +#define REG_CRC_VHT 0xf0c +#define REG_CCA_OFDM 0xf08 +#define REG_FA_OFDM 0xf48 +#define REG_CCA_CCK 0xfcc +#define REG_ANTWT 0x1904 +#define REG_IQKFAILMSK 0x1bf0 + +#define RF18_BAND_MASK (BIT(16) | BIT(9) | BIT(8)) +#define RF18_BAND_2G (0) +#define RF18_BAND_5G (BIT(16) | BIT(8)) +#define RF18_CHANNEL_MASK (MASKBYTE0) +#define RF18_RFSI_MASK (BIT(18) | BIT(17)) +#define RF18_RFSI_GE (BIT(17)) +#define RF18_RFSI_GT (BIT(18)) +#define RF18_BW_MASK (BIT(11) | BIT(10)) +#define RF18_BW_20M (BIT(11) | BIT(10)) +#define RF18_BW_40M (BIT(11)) +#define RF18_BW_80M (BIT(10)) + +#endif diff --git a/drivers/net/wireless/realtek/rtw88/rtw8821c_table.c b/drivers/net/wireless/realtek/rtw88/rtw8821c_table.c new file mode 100644 index 000000000000..970f903f7dc7 --- /dev/null +++ b/drivers/net/wireless/realtek/rtw88/rtw8821c_table.c @@ -0,0 +1,6611 @@ +// SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause +/* Copyright(c) 2018-2019 Realtek Corporation + */ + +#include "main.h" +#include "phy.h" +#include "rtw8821c_table.h" + +static const u32 rtw8821c_mac[] = { + 0x010, 0x00000043, + 0x025, 0x0000001D, + 0x026, 0x000000CE, + 0x04F, 0x00000001, + 0x029, 0x000000F9, + 0x420, 0x00000080, + 0x421, 0x0000000F, + 0x428, 0x0000000A, + 0x429, 0x00000010, + 0x430, 0x00000000, + 0x431, 0x00000000, + 0x432, 0x00000000, + 0x433, 0x00000001, + 0x434, 0x00000004, + 0x435, 0x00000005, + 0x436, 0x00000007, + 0x437, 0x00000008, + 0x43C, 0x00000004, + 0x43D, 0x00000005, + 0x43E, 0x00000007, + 0x43F, 0x00000008, + 0x440, 0x0000005D, + 0x441, 0x00000001, + 0x442, 0x00000000, + 0x444, 0x00000010, + 0x445, 0x000000F0, + 0x446, 0x00000001, + 0x447, 0x000000FE, + 0x448, 0x00000000, + 0x449, 0x00000000, + 0x44A, 0x00000000, + 0x44B, 0x00000040, + 0x44C, 0x00000010, + 0x44D, 0x000000F0, + 0x44E, 0x0000003F, + 0x44F, 0x00000000, + 0x450, 0x00000000, + 0x451, 0x00000000, + 0x452, 0x00000000, + 0x453, 0x00000040, + 0x455, 0x00000070, + 0x45E, 0x00000004, + 0x49C, 0x00000010, + 0x49D, 0x000000F0, + 0x49E, 0x00000000, + 0x49F, 0x00000006, + 0x4A0, 0x000000E0, + 0x4A1, 0x00000003, + 0x4A2, 0x00000000, + 0x4A3, 0x00000040, + 0x4A4, 0x00000015, + 0x4A5, 0x000000F0, + 0x4A6, 0x00000000, + 0x4A7, 0x00000006, + 0x4A8, 0x000000E0, + 0x4A9, 0x00000000, + 0x4AA, 0x00000000, + 0x4AB, 0x00000000, + 0x7DA, 0x00000008, + 0x1448, 0x00000006, + 0x144A, 0x00000006, + 0x144C, 0x00000006, + 0x144E, 0x00000006, + 0x4C8, 0x000000FF, + 0x4C9, 0x00000008, + 0x4CC, 0x000000FF, + 0x4CD, 0x000000FF, + 0x4CE, 0x00000001, + 0x4CF, 0x00000008, + 0x500, 0x00000026, + 0x501, 0x000000A2, + 0x502, 0x0000002F, + 0x503, 0x00000000, + 0x504, 0x00000028, + 0x505, 0x000000A3, + 0x506, 0x0000005E, + 0x507, 0x00000000, + 0x508, 0x0000002B, + 0x509, 0x000000A4, + 0x50A, 0x0000005E, + 0x50B, 0x00000000, + 0x50C, 0x0000004F, + 0x50D, 0x000000A4, + 0x50E, 0x00000000, + 0x50F, 0x00000000, + 0x512, 0x0000001C, + 0x514, 0x0000000A, + 0x516, 0x0000000A, + 0x521, 0x0000002F, + 0x525, 0x0000004F, + 0x551, 0x00000010, + 0x559, 0x00000002, + 0x55C, 0x00000050, + 0x55D, 0x000000FF, + 0x577, 0x0000000B, + 0x578, 0x00000014, + 0x579, 0x00000014, + 0x57A, 0x00000014, + 0x5BE, 0x00000064, + 0x605, 0x00000030, + 0x608, 0x0000000E, + 0x609, 0x00000022, + 0x60C, 0x00000018, + 0x6A0, 0x000000FF, + 0x6A1, 0x000000FF, + 0x6A2, 0x000000FF, + 0x6A3, 0x000000FF, + 0x6A4, 0x000000FF, + 0x6A5, 0x000000FF, + 0x6DE, 0x00000084, + 0x620, 0x000000FF, + 0x621, 0x000000FF, + 0x622, 0x000000FF, + 0x623, 0x000000FF, + 0x624, 0x000000FF, + 0x625, 0x000000FF, + 0x626, 0x000000FF, + 0x627, 0x000000FF, + 0x638, 0x00000050, + 0x63C, 0x0000000A, + 0x63D, 0x0000000A, + 0x63E, 0x0000000E, + 0x63F, 0x0000000E, + 0x640, 0x00000040, + 0x642, 0x00000040, + 0x643, 0x00000000, + 0x652, 0x000000C8, + 0x66E, 0x00000005, + 0x700, 0x00000021, + 0x701, 0x00000043, + 0x702, 0x00000065, + 0x703, 0x00000087, + 0x708, 0x00000021, + 0x709, 0x00000043, + 0x70A, 0x00000065, + 0x70B, 0x00000087, + 0x718, 0x00000040, + 0x7D4, 0x00000098, + +}; + +RTW_DECL_TABLE_PHY_COND(rtw8821c_mac, rtw_phy_cfg_mac); + +static const u32 rtw8821c_agc[] = { + 0x80001004, 0x00000000, 0x40000000, 0x00000000, + 0x81C, 0xFB000003, + 0x81C, 0xFA020003, + 0x81C, 0xF9040003, + 0x81C, 0xF8060003, + 0x81C, 0xF7080003, + 0x81C, 0xF60A0003, + 0x81C, 0xF50C0003, + 0x81C, 0xF40E0003, + 0x81C, 0xF3100003, + 0x81C, 0xF2120003, + 0x81C, 0xF1140003, + 0x81C, 0xF0160003, + 0x81C, 0xEF180003, + 0x81C, 0xEE1A0003, + 0x81C, 0xED1C0003, + 0x81C, 0xEC1E0003, + 0x81C, 0xEB200003, + 0x81C, 0xEA220003, + 0x81C, 0xE9240003, + 0x81C, 0xE8260003, + 0x81C, 0xE7280003, + 0x81C, 0xE62A0003, + 0x81C, 0xE52C0003, + 0x81C, 0xE42E0003, + 0x81C, 0xE3300003, + 0x81C, 0xE2320003, + 0x81C, 0xE1340003, + 0x81C, 0xC4360003, + 0x81C, 0xC3380003, + 0x81C, 0xC23A0003, + 0x81C, 0xC13C0003, + 0x81C, 0x883E0003, + 0x81C, 0x87400003, + 0x81C, 0x86420003, + 0x81C, 0x85440003, + 0x81C, 0x84460003, + 0x81C, 0x83480003, + 0x81C, 0x824A0003, + 0x81C, 0x814C0003, + 0x81C, 0x804E0003, + 0x81C, 0x64500003, + 0x81C, 0x63520003, + 0x81C, 0x62540003, + 0x81C, 0x61560003, + 0x81C, 0x60580003, + 0x81C, 0x475A0003, + 0x81C, 0x465C0003, + 0x81C, 0x455E0003, + 0x81C, 0x44600003, + 0x81C, 0x43620003, + 0x81C, 0x42640003, + 0x81C, 0x41660003, + 0x81C, 0x40680003, + 0x81C, 0x236A0003, + 0x81C, 0x226C0003, + 0x81C, 0x056E0003, + 0x81C, 0x04700003, + 0x81C, 0x03720003, + 0x81C, 0x02740003, + 0x81C, 0x01760003, + 0x81C, 0x01780003, + 0x81C, 0x017A0003, + 0x81C, 0x017C0003, + 0x81C, 0x017E0003, + 0x90001005, 0x00000000, 0x40000000, 0x00000000, + 0x81C, 0xFB000003, + 0x81C, 0xFA020003, + 0x81C, 0xF9040003, + 0x81C, 0xF8060003, + 0x81C, 0xF7080003, + 0x81C, 0xF60A0003, + 0x81C, 0xF50C0003, + 0x81C, 0xF40E0003, + 0x81C, 0xF3100003, + 0x81C, 0xF2120003, + 0x81C, 0xF1140003, + 0x81C, 0xF0160003, + 0x81C, 0xEF180003, + 0x81C, 0xEE1A0003, + 0x81C, 0xED1C0003, + 0x81C, 0xEC1E0003, + 0x81C, 0xEB200003, + 0x81C, 0xEA220003, + 0x81C, 0xE9240003, + 0x81C, 0xE8260003, + 0x81C, 0xE7280003, + 0x81C, 0xE62A0003, + 0x81C, 0xE52C0003, + 0x81C, 0xE42E0003, + 0x81C, 0xE3300003, + 0x81C, 0xE2320003, + 0x81C, 0xE1340003, + 0x81C, 0xC4360003, + 0x81C, 0xC3380003, + 0x81C, 0xC23A0003, + 0x81C, 0xC13C0003, + 0x81C, 0x883E0003, + 0x81C, 0x87400003, + 0x81C, 0x86420003, + 0x81C, 0x85440003, + 0x81C, 0x84460003, + 0x81C, 0x83480003, + 0x81C, 0x824A0003, + 0x81C, 0x814C0003, + 0x81C, 0x804E0003, + 0x81C, 0x64500003, + 0x81C, 0x63520003, + 0x81C, 0x62540003, + 0x81C, 0x61560003, + 0x81C, 0x60580003, + 0x81C, 0x475A0003, + 0x81C, 0x465C0003, + 0x81C, 0x455E0003, + 0x81C, 0x44600003, + 0x81C, 0x43620003, + 0x81C, 0x42640003, + 0x81C, 0x41660003, + 0x81C, 0x40680003, + 0x81C, 0x236A0003, + 0x81C, 0x226C0003, + 0x81C, 0x056E0003, + 0x81C, 0x04700003, + 0x81C, 0x03720003, + 0x81C, 0x02740003, + 0x81C, 0x01760003, + 0x81C, 0x01780003, + 0x81C, 0x017A0003, + 0x81C, 0x017C0003, + 0x81C, 0x017E0003, + 0xA0000000, 0x00000000, + 0x81C, 0xFB000003, + 0x81C, 0xFA020003, + 0x81C, 0xF9040003, + 0x81C, 0xF8060003, + 0x81C, 0xF7080003, + 0x81C, 0xF60A0003, + 0x81C, 0xF50C0003, + 0x81C, 0xF40E0003, + 0x81C, 0xF3100003, + 0x81C, 0xF2120003, + 0x81C, 0xF1140003, + 0x81C, 0xF0160003, + 0x81C, 0xEF180003, + 0x81C, 0xEE1A0003, + 0x81C, 0xED1C0003, + 0x81C, 0xEC1E0003, + 0x81C, 0xEB200003, + 0x81C, 0xEA220003, + 0x81C, 0xE9240003, + 0x81C, 0xE8260003, + 0x81C, 0xE7280003, + 0x81C, 0xE62A0003, + 0x81C, 0xCA2C0003, + 0x81C, 0xC92E0003, + 0x81C, 0xC8300003, + 0x81C, 0xC7320003, + 0x81C, 0xC6340003, + 0x81C, 0xC5360003, + 0x81C, 0xC4380003, + 0x81C, 0xC33A0003, + 0x81C, 0xC23C0003, + 0x81C, 0xC13E0003, + 0x81C, 0x88400003, + 0x81C, 0x87420003, + 0x81C, 0x86440003, + 0x81C, 0x85460003, + 0x81C, 0x84480003, + 0x81C, 0x834A0003, + 0x81C, 0x674C0003, + 0x81C, 0x664E0003, + 0x81C, 0x65500003, + 0x81C, 0x64520003, + 0x81C, 0x63540003, + 0x81C, 0x62560003, + 0x81C, 0x61580003, + 0x81C, 0x455A0003, + 0x81C, 0x445C0003, + 0x81C, 0x435E0003, + 0x81C, 0x42600003, + 0x81C, 0x41620003, + 0x81C, 0x25640003, + 0x81C, 0x24660003, + 0x81C, 0x23680003, + 0x81C, 0x226A0003, + 0x81C, 0x216C0003, + 0x81C, 0x016E0003, + 0x81C, 0x01700003, + 0x81C, 0x01720003, + 0x81C, 0x01740003, + 0x81C, 0x01760003, + 0x81C, 0x01780003, + 0x81C, 0x017A0003, + 0x81C, 0x017C0003, + 0x81C, 0x017E0003, + 0xB0000000, 0x00000000, + 0x80001004, 0x00000000, 0x40000000, 0x00000000, + 0x81C, 0xFD000103, + 0x81C, 0xFC020103, + 0x81C, 0xFB040103, + 0x81C, 0xFA060103, + 0x81C, 0xF9080103, + 0x81C, 0xF80A0103, + 0x81C, 0xF70C0103, + 0x81C, 0xF60E0103, + 0x81C, 0xF5100103, + 0x81C, 0xF4120103, + 0x81C, 0xF3140103, + 0x81C, 0xF2160103, + 0x81C, 0xF1180103, + 0x81C, 0xF01A0103, + 0x81C, 0xEF1C0103, + 0x81C, 0xEE1E0103, + 0x81C, 0xED200103, + 0x81C, 0xEC220103, + 0x81C, 0xEB240103, + 0x81C, 0xEA260103, + 0x81C, 0xE9280103, + 0x81C, 0xE82A0103, + 0x81C, 0xE72C0103, + 0x81C, 0xE62E0103, + 0x81C, 0xE5300103, + 0x81C, 0xE4320103, + 0x81C, 0xE3340103, + 0x81C, 0xE2360103, + 0x81C, 0xE1380103, + 0x81C, 0xE03A0103, + 0x81C, 0xC33C0103, + 0x81C, 0xC23E0103, + 0x81C, 0xC1400103, + 0x81C, 0xC0420103, + 0x81C, 0xA3440103, + 0x81C, 0xA2460103, + 0x81C, 0xA1480103, + 0x81C, 0xA04A0103, + 0x81C, 0x824C0103, + 0x81C, 0x814E0103, + 0x81C, 0x80500103, + 0x81C, 0x62520103, + 0x81C, 0x61540103, + 0x81C, 0x60560103, + 0x81C, 0x24580103, + 0x81C, 0x235A0103, + 0x81C, 0x225C0103, + 0x81C, 0x215E0103, + 0x81C, 0x20600103, + 0x81C, 0x03620103, + 0x81C, 0x02640103, + 0x81C, 0x01660103, + 0x81C, 0x01680103, + 0x81C, 0x016A0103, + 0x81C, 0x016C0103, + 0x81C, 0x016E0103, + 0x81C, 0x01700103, + 0x81C, 0x01720103, + 0x81C, 0x01740103, + 0x81C, 0x01760103, + 0x81C, 0x01780103, + 0x81C, 0x017A0103, + 0x81C, 0x017C0103, + 0x81C, 0x017E0103, + 0x90001005, 0x00000000, 0x40000000, 0x00000000, + 0x81C, 0xF6000103, + 0x81C, 0xF5020103, + 0x81C, 0xF4040103, + 0x81C, 0xF3060103, + 0x81C, 0xF2080103, + 0x81C, 0xF10A0103, + 0x81C, 0xF00C0103, + 0x81C, 0xEF0E0103, + 0x81C, 0xEE100103, + 0x81C, 0xED120103, + 0x81C, 0xEC140103, + 0x81C, 0xCE160103, + 0x81C, 0xEA180103, + 0x81C, 0xE91A0103, + 0x81C, 0xE81C0103, + 0x81C, 0xE71E0103, + 0x81C, 0xE6200103, + 0x81C, 0xE5220103, + 0x81C, 0xE4240103, + 0x81C, 0xE3260103, + 0x81C, 0xE2280103, + 0x81C, 0xE12A0103, + 0x81C, 0xC32C0103, + 0x81C, 0xA62E0103, + 0x81C, 0xC1300103, + 0x81C, 0xA4320103, + 0x81C, 0xA3340103, + 0x81C, 0xA2360103, + 0x81C, 0xA1380103, + 0x81C, 0x833A0103, + 0x81C, 0x823C0103, + 0x81C, 0x813E0103, + 0x81C, 0x63400103, + 0x81C, 0x62420103, + 0x81C, 0x61440103, + 0x81C, 0x60460103, + 0x81C, 0x25480103, + 0x81C, 0x244A0103, + 0x81C, 0x234C0103, + 0x81C, 0x064E0103, + 0x81C, 0x21500103, + 0x81C, 0x04520103, + 0x81C, 0x03540103, + 0x81C, 0x02560103, + 0x81C, 0x01580103, + 0x81C, 0x005A0103, + 0x81C, 0x005C0103, + 0x81C, 0x005E0103, + 0x81C, 0x00600103, + 0x81C, 0x00620103, + 0x81C, 0x00640103, + 0x81C, 0x00660103, + 0x81C, 0x00680103, + 0x81C, 0x006A0103, + 0x81C, 0x006C0103, + 0x81C, 0x006E0103, + 0x81C, 0x00700103, + 0x81C, 0x00720103, + 0x81C, 0x00740103, + 0x81C, 0x00760103, + 0x81C, 0x00780103, + 0x81C, 0x007A0103, + 0x81C, 0x007C0103, + 0x81C, 0x007E0103, + 0xA0000000, 0x00000000, + 0x81C, 0xFD000103, + 0x81C, 0xFC020103, + 0x81C, 0xFB040103, + 0x81C, 0xFA060103, + 0x81C, 0xF9080103, + 0x81C, 0xF80A0103, + 0x81C, 0xF70C0103, + 0x81C, 0xF60E0103, + 0x81C, 0xF5100103, + 0x81C, 0xF4120103, + 0x81C, 0xF3140103, + 0x81C, 0xF2160103, + 0x81C, 0xF1180103, + 0x81C, 0xF01A0103, + 0x81C, 0xEF1C0103, + 0x81C, 0xEE1E0103, + 0x81C, 0xED200103, + 0x81C, 0xEC220103, + 0x81C, 0xEB240103, + 0x81C, 0xEA260103, + 0x81C, 0xE9280103, + 0x81C, 0xE82A0103, + 0x81C, 0xE72C0103, + 0x81C, 0xE62E0103, + 0x81C, 0xE5300103, + 0x81C, 0xE4320103, + 0x81C, 0xE3340103, + 0x81C, 0xE2360103, + 0x81C, 0xE1380103, + 0x81C, 0xE03A0103, + 0x81C, 0xA83C0103, + 0x81C, 0xA73E0103, + 0x81C, 0xA6400103, + 0x81C, 0xA5420103, + 0x81C, 0xA4440103, + 0x81C, 0xA3460103, + 0x81C, 0xA2480103, + 0x81C, 0xA14A0103, + 0x81C, 0x834C0103, + 0x81C, 0x824E0103, + 0x81C, 0x81500103, + 0x81C, 0x63520103, + 0x81C, 0x62540103, + 0x81C, 0x61560103, + 0x81C, 0x25580103, + 0x81C, 0x245A0103, + 0x81C, 0x235C0103, + 0x81C, 0x225E0103, + 0x81C, 0x04600103, + 0x81C, 0x03620103, + 0x81C, 0x02640103, + 0x81C, 0x01660103, + 0x81C, 0x01680103, + 0x81C, 0x016A0103, + 0x81C, 0x016C0103, + 0x81C, 0x016E0103, + 0x81C, 0x01700103, + 0x81C, 0x01720103, + 0x81C, 0x01740103, + 0x81C, 0x01760103, + 0x81C, 0x01780103, + 0x81C, 0x017A0103, + 0x81C, 0x017C0103, + 0x81C, 0x017E0103, + 0xB0000000, 0x00000000, + 0x80001004, 0x00000000, 0x40000000, 0x00000000, + 0x81C, 0xFB000203, + 0x81C, 0xFA020203, + 0x81C, 0xF9040203, + 0x81C, 0xF8060203, + 0x81C, 0xF7080203, + 0x81C, 0xF60A0203, + 0x81C, 0xF50C0203, + 0x81C, 0xF40E0203, + 0x81C, 0xF3100203, + 0x81C, 0xF2120203, + 0x81C, 0xF1140203, + 0x81C, 0xF0160203, + 0x81C, 0xEF180203, + 0x81C, 0xEE1A0203, + 0x81C, 0xED1C0203, + 0x81C, 0xEC1E0203, + 0x81C, 0xEB200203, + 0x81C, 0xEA220203, + 0x81C, 0xE9240203, + 0x81C, 0xE8260203, + 0x81C, 0xE7280203, + 0x81C, 0xE62A0203, + 0x81C, 0xE52C0203, + 0x81C, 0xE42E0203, + 0x81C, 0xE3300203, + 0x81C, 0xE2320203, + 0x81C, 0xE1340203, + 0x81C, 0xC5360203, + 0x81C, 0xC4380203, + 0x81C, 0xC33A0203, + 0x81C, 0xC23C0203, + 0x81C, 0xC13E0203, + 0x81C, 0xA4400203, + 0x81C, 0xA3420203, + 0x81C, 0xA2440203, + 0x81C, 0xA1460203, + 0x81C, 0xA0480203, + 0x81C, 0x834A0203, + 0x81C, 0x824C0203, + 0x81C, 0x814E0203, + 0x81C, 0x63500203, + 0x81C, 0x62520203, + 0x81C, 0x61540203, + 0x81C, 0x60560203, + 0x81C, 0x23580203, + 0x81C, 0x225A0203, + 0x81C, 0x215C0203, + 0x81C, 0x205E0203, + 0x81C, 0x04600203, + 0x81C, 0x03620203, + 0x81C, 0x02640203, + 0x81C, 0x01660203, + 0x81C, 0x01680203, + 0x81C, 0x016A0203, + 0x81C, 0x016C0203, + 0x81C, 0x016E0203, + 0x81C, 0x01700203, + 0x81C, 0x01720203, + 0x81C, 0x01740203, + 0x81C, 0x01760203, + 0x81C, 0x01780203, + 0x81C, 0x017A0203, + 0x81C, 0x017C0203, + 0x81C, 0x017E0203, + 0x90001005, 0x00000000, 0x40000000, 0x00000000, + 0x81C, 0xF6000203, + 0x81C, 0xF5020203, + 0x81C, 0xF4040203, + 0x81C, 0xF3060203, + 0x81C, 0xF2080203, + 0x81C, 0xF10A0203, + 0x81C, 0xF00C0203, + 0x81C, 0xEF0E0203, + 0x81C, 0xEE100203, + 0x81C, 0xED120203, + 0x81C, 0xEC140203, + 0x81C, 0xEB160203, + 0x81C, 0xEA180203, + 0x81C, 0xE91A0203, + 0x81C, 0xE81C0203, + 0x81C, 0xE71E0203, + 0x81C, 0xE6200203, + 0x81C, 0xE5220203, + 0x81C, 0xE4240203, + 0x81C, 0xE3260203, + 0x81C, 0xE2280203, + 0x81C, 0xE12A0203, + 0x81C, 0xE02C0203, + 0x81C, 0xC22E0203, + 0x81C, 0xC1300203, + 0x81C, 0xC0320203, + 0x81C, 0xA3340203, + 0x81C, 0xA2360203, + 0x81C, 0xA1380203, + 0x81C, 0xA03A0203, + 0x81C, 0x833C0203, + 0x81C, 0x823E0203, + 0x81C, 0x81400203, + 0x81C, 0x80420203, + 0x81C, 0x62440203, + 0x81C, 0x61460203, + 0x81C, 0x42480203, + 0x81C, 0x414A0203, + 0x81C, 0x234C0203, + 0x81C, 0x224E0203, + 0x81C, 0x21500203, + 0x81C, 0x20520203, + 0x81C, 0x03540203, + 0x81C, 0x02560203, + 0x81C, 0x01580203, + 0x81C, 0x005A0203, + 0x81C, 0x005C0203, + 0x81C, 0x005E0203, + 0x81C, 0x00600203, + 0x81C, 0x00620203, + 0x81C, 0x00640203, + 0x81C, 0x00660203, + 0x81C, 0x00680203, + 0x81C, 0x006A0203, + 0x81C, 0x006C0203, + 0x81C, 0x006E0203, + 0x81C, 0x00700203, + 0x81C, 0x00720203, + 0x81C, 0x00740203, + 0x81C, 0x00760203, + 0x81C, 0x00780203, + 0x81C, 0x007A0203, + 0x81C, 0x007C0203, + 0x81C, 0x007E0203, + 0xA0000000, 0x00000000, + 0x81C, 0xFC000203, + 0x81C, 0xFB020203, + 0x81C, 0xFA040203, + 0x81C, 0xF9060203, + 0x81C, 0xF8080203, + 0x81C, 0xF70A0203, + 0x81C, 0xF60C0203, + 0x81C, 0xF50E0203, + 0x81C, 0xF4100203, + 0x81C, 0xF3120203, + 0x81C, 0xF2140203, + 0x81C, 0xF1160203, + 0x81C, 0xF0180203, + 0x81C, 0xEF1A0203, + 0x81C, 0xEE1C0203, + 0x81C, 0xED1E0203, + 0x81C, 0xEC200203, + 0x81C, 0xEB220203, + 0x81C, 0xEA240203, + 0x81C, 0xE9260203, + 0x81C, 0xE8280203, + 0x81C, 0xE72A0203, + 0x81C, 0xE62C0203, + 0x81C, 0xE52E0203, + 0x81C, 0xE4300203, + 0x81C, 0xE3320203, + 0x81C, 0xE2340203, + 0x81C, 0xE1360203, + 0x81C, 0xC5380203, + 0x81C, 0xC43A0203, + 0x81C, 0xC33C0203, + 0x81C, 0xC23E0203, + 0x81C, 0xA6400203, + 0x81C, 0xA5420203, + 0x81C, 0xA4440203, + 0x81C, 0xA3460203, + 0x81C, 0xA2480203, + 0x81C, 0x844A0203, + 0x81C, 0x834C0203, + 0x81C, 0x824E0203, + 0x81C, 0x64500203, + 0x81C, 0x63520203, + 0x81C, 0x62540203, + 0x81C, 0x61560203, + 0x81C, 0x60580203, + 0x81C, 0x235A0203, + 0x81C, 0x225C0203, + 0x81C, 0x215E0203, + 0x81C, 0x04600203, + 0x81C, 0x03620203, + 0x81C, 0x02640203, + 0x81C, 0x01660203, + 0x81C, 0x01680203, + 0x81C, 0x016A0203, + 0x81C, 0x016C0203, + 0x81C, 0x016E0203, + 0x81C, 0x01700203, + 0x81C, 0x01720203, + 0x81C, 0x01740203, + 0x81C, 0x01760203, + 0x81C, 0x01780203, + 0x81C, 0x017A0203, + 0x81C, 0x017C0203, + 0x81C, 0x017E0203, + 0xB0000000, 0x00000000, + 0x80001004, 0x00000000, 0x40000000, 0x00000000, + 0x81C, 0xFB000303, + 0x81C, 0xFA020303, + 0x81C, 0xF9040303, + 0x81C, 0xF8060303, + 0x81C, 0xF7080303, + 0x81C, 0xF60A0303, + 0x81C, 0xF50C0303, + 0x81C, 0xF40E0303, + 0x81C, 0xF3100303, + 0x81C, 0xF2120303, + 0x81C, 0xF1140303, + 0x81C, 0xF0160303, + 0x81C, 0xEF180303, + 0x81C, 0xEE1A0303, + 0x81C, 0xED1C0303, + 0x81C, 0xEC1E0303, + 0x81C, 0xEB200303, + 0x81C, 0xEA220303, + 0x81C, 0xE9240303, + 0x81C, 0xE8260303, + 0x81C, 0xE7280303, + 0x81C, 0xE62A0303, + 0x81C, 0xE52C0303, + 0x81C, 0xE42E0303, + 0x81C, 0xE3300303, + 0x81C, 0xE2320303, + 0x81C, 0xE1340303, + 0x81C, 0xC4360303, + 0x81C, 0xC3380303, + 0x81C, 0xC23A0303, + 0x81C, 0xC13C0303, + 0x81C, 0xA53E0303, + 0x81C, 0xA4400303, + 0x81C, 0xA3420303, + 0x81C, 0xA2440303, + 0x81C, 0xA1460303, + 0x81C, 0x83480303, + 0x81C, 0x824A0303, + 0x81C, 0x814C0303, + 0x81C, 0x644E0303, + 0x81C, 0x63500303, + 0x81C, 0x62520303, + 0x81C, 0x61540303, + 0x81C, 0x60560303, + 0x81C, 0x23580303, + 0x81C, 0x225A0303, + 0x81C, 0x215C0303, + 0x81C, 0x045E0303, + 0x81C, 0x03600303, + 0x81C, 0x02620303, + 0x81C, 0x01640303, + 0x81C, 0x01660303, + 0x81C, 0x01680303, + 0x81C, 0x016A0303, + 0x81C, 0x016C0303, + 0x81C, 0x016E0303, + 0x81C, 0x01700303, + 0x81C, 0x01720303, + 0x81C, 0x01740303, + 0x81C, 0x01760303, + 0x81C, 0x01780303, + 0x81C, 0x017A0303, + 0x81C, 0x017C0303, + 0x81C, 0x017E0303, + 0x90001005, 0x00000000, 0x40000000, 0x00000000, + 0x81C, 0xF5000303, + 0x81C, 0xF4020303, + 0x81C, 0xF3040303, + 0x81C, 0xF2060303, + 0x81C, 0xF1080303, + 0x81C, 0xF00A0303, + 0x81C, 0xEF0C0303, + 0x81C, 0xEE0E0303, + 0x81C, 0xED100303, + 0x81C, 0xEC120303, + 0x81C, 0xEB140303, + 0x81C, 0xEA160303, + 0x81C, 0xE9180303, + 0x81C, 0xE81A0303, + 0x81C, 0xE71C0303, + 0x81C, 0xE61E0303, + 0x81C, 0xE5200303, + 0x81C, 0xE4220303, + 0x81C, 0xE3240303, + 0x81C, 0xE2260303, + 0x81C, 0xE1280303, + 0x81C, 0xE02A0303, + 0x81C, 0xA72C0303, + 0x81C, 0xA62E0303, + 0x81C, 0xA5300303, + 0x81C, 0xA4320303, + 0x81C, 0xA3340303, + 0x81C, 0xA2360303, + 0x81C, 0xA1380303, + 0x81C, 0xA03A0303, + 0x81C, 0x823C0303, + 0x81C, 0x643E0303, + 0x81C, 0x63400303, + 0x81C, 0x62420303, + 0x81C, 0x61440303, + 0x81C, 0x60460303, + 0x81C, 0x24480303, + 0x81C, 0x234A0303, + 0x81C, 0x224C0303, + 0x81C, 0x054E0303, + 0x81C, 0x04500303, + 0x81C, 0x03520303, + 0x81C, 0x02540303, + 0x81C, 0x01560303, + 0x81C, 0x00580303, + 0x81C, 0x005A0303, + 0x81C, 0x005C0303, + 0x81C, 0x005E0303, + 0x81C, 0x00600303, + 0x81C, 0x00620303, + 0x81C, 0x00640303, + 0x81C, 0x00660303, + 0x81C, 0x00680303, + 0x81C, 0x006A0303, + 0x81C, 0x006C0303, + 0x81C, 0x006E0303, + 0x81C, 0x00700303, + 0x81C, 0x00720303, + 0x81C, 0x00740303, + 0x81C, 0x00760303, + 0x81C, 0x00780303, + 0x81C, 0x007A0303, + 0x81C, 0x007C0303, + 0x81C, 0x007E0303, + 0xA0000000, 0x00000000, + 0x81C, 0xFC000303, + 0x81C, 0xFB020303, + 0x81C, 0xFA040303, + 0x81C, 0xF9060303, + 0x81C, 0xF8080303, + 0x81C, 0xF70A0303, + 0x81C, 0xF60C0303, + 0x81C, 0xF50E0303, + 0x81C, 0xF4100303, + 0x81C, 0xF3120303, + 0x81C, 0xF2140303, + 0x81C, 0xF1160303, + 0x81C, 0xF0180303, + 0x81C, 0xEF1A0303, + 0x81C, 0xEE1C0303, + 0x81C, 0xED1E0303, + 0x81C, 0xEC200303, + 0x81C, 0xEB220303, + 0x81C, 0xEA240303, + 0x81C, 0xE9260303, + 0x81C, 0xE8280303, + 0x81C, 0xE72A0303, + 0x81C, 0xE62C0303, + 0x81C, 0xE52E0303, + 0x81C, 0xE4300303, + 0x81C, 0xE3320303, + 0x81C, 0xE2340303, + 0x81C, 0xE1360303, + 0x81C, 0xC4380303, + 0x81C, 0xC33A0303, + 0x81C, 0xC23C0303, + 0x81C, 0xC13E0303, + 0x81C, 0xA5400303, + 0x81C, 0xA4420303, + 0x81C, 0xA3440303, + 0x81C, 0xA2460303, + 0x81C, 0xA1480303, + 0x81C, 0x834A0303, + 0x81C, 0x824C0303, + 0x81C, 0x814E0303, + 0x81C, 0x64500303, + 0x81C, 0x63520303, + 0x81C, 0x62540303, + 0x81C, 0x61560303, + 0x81C, 0x24580303, + 0x81C, 0x235A0303, + 0x81C, 0x225C0303, + 0x81C, 0x215E0303, + 0x81C, 0x04600303, + 0x81C, 0x03620303, + 0x81C, 0x02640303, + 0x81C, 0x01660303, + 0x81C, 0x01680303, + 0x81C, 0x016A0303, + 0x81C, 0x016C0303, + 0x81C, 0x016E0303, + 0x81C, 0x01700303, + 0x81C, 0x01720303, + 0x81C, 0x01740303, + 0x81C, 0x01760303, + 0x81C, 0x01780303, + 0x81C, 0x017A0303, + 0x81C, 0x017C0303, + 0x81C, 0x017E0303, + 0xB0000000, 0x00000000, + 0x80001004, 0x00000000, 0x40000000, 0x00000000, + 0x81C, 0xFC000803, + 0x81C, 0xFB020803, + 0x81C, 0xFA040803, + 0x81C, 0xF9060803, + 0x81C, 0xF8080803, + 0x81C, 0xF70A0803, + 0x81C, 0xF60C0803, + 0x81C, 0xF50E0803, + 0x81C, 0xF4100803, + 0x81C, 0xF3120803, + 0x81C, 0xF2140803, + 0x81C, 0xF1160803, + 0x81C, 0xF0180803, + 0x81C, 0xEF1A0803, + 0x81C, 0xEE1C0803, + 0x81C, 0xED1E0803, + 0x81C, 0xB5200803, + 0x81C, 0xB4220803, + 0x81C, 0xB3240803, + 0x81C, 0xB2260803, + 0x81C, 0xB1280803, + 0x81C, 0xB02A0803, + 0x81C, 0xAF2C0803, + 0x81C, 0xAE2E0803, + 0x81C, 0xAD300803, + 0x81C, 0xAC320803, + 0x81C, 0xAB340803, + 0x81C, 0xAA360803, + 0x81C, 0xA9380803, + 0x81C, 0xA83A0803, + 0x81C, 0xA73C0803, + 0x81C, 0xA63E0803, + 0x81C, 0x88400803, + 0x81C, 0x87420803, + 0x81C, 0x86440803, + 0x81C, 0x85460803, + 0x81C, 0x84480803, + 0x81C, 0x834A0803, + 0x81C, 0x674C0803, + 0x81C, 0x664E0803, + 0x81C, 0x65500803, + 0x81C, 0x64520803, + 0x81C, 0x63540803, + 0x81C, 0x62560803, + 0x81C, 0x61580803, + 0x81C, 0x455A0803, + 0x81C, 0x445C0803, + 0x81C, 0x435E0803, + 0x81C, 0x42600803, + 0x81C, 0x41620803, + 0x81C, 0x25640803, + 0x81C, 0x24660803, + 0x81C, 0x23680803, + 0x81C, 0x226A0803, + 0x81C, 0x216C0803, + 0x81C, 0x016E0803, + 0x81C, 0x01700803, + 0x81C, 0x01720803, + 0x81C, 0x01740803, + 0x81C, 0x01760803, + 0x81C, 0x01780803, + 0x81C, 0x017A0803, + 0x81C, 0x017C0803, + 0x81C, 0x017E0803, + 0x90001005, 0x00000000, 0x40000000, 0x00000000, + 0x81C, 0xFC000803, + 0x81C, 0xFB020803, + 0x81C, 0xFA040803, + 0x81C, 0xF9060803, + 0x81C, 0xF8080803, + 0x81C, 0xF70A0803, + 0x81C, 0xF60C0803, + 0x81C, 0xF50E0803, + 0x81C, 0xF4100803, + 0x81C, 0xF3120803, + 0x81C, 0xF2140803, + 0x81C, 0xF1160803, + 0x81C, 0xF0180803, + 0x81C, 0xEF1A0803, + 0x81C, 0xEE1C0803, + 0x81C, 0xED1E0803, + 0x81C, 0xB5200803, + 0x81C, 0xB4220803, + 0x81C, 0xB3240803, + 0x81C, 0xB2260803, + 0x81C, 0xB1280803, + 0x81C, 0xB02A0803, + 0x81C, 0xAF2C0803, + 0x81C, 0xAE2E0803, + 0x81C, 0xAD300803, + 0x81C, 0xAC320803, + 0x81C, 0xAB340803, + 0x81C, 0xAA360803, + 0x81C, 0xA9380803, + 0x81C, 0xA83A0803, + 0x81C, 0xA73C0803, + 0x81C, 0xA63E0803, + 0x81C, 0x88400803, + 0x81C, 0x87420803, + 0x81C, 0x86440803, + 0x81C, 0x85460803, + 0x81C, 0x84480803, + 0x81C, 0x834A0803, + 0x81C, 0x674C0803, + 0x81C, 0x664E0803, + 0x81C, 0x65500803, + 0x81C, 0x64520803, + 0x81C, 0x63540803, + 0x81C, 0x62560803, + 0x81C, 0x61580803, + 0x81C, 0x455A0803, + 0x81C, 0x445C0803, + 0x81C, 0x435E0803, + 0x81C, 0x42600803, + 0x81C, 0x41620803, + 0x81C, 0x25640803, + 0x81C, 0x24660803, + 0x81C, 0x23680803, + 0x81C, 0x226A0803, + 0x81C, 0x216C0803, + 0x81C, 0x016E0803, + 0x81C, 0x01700803, + 0x81C, 0x01720803, + 0x81C, 0x01740803, + 0x81C, 0x01760803, + 0x81C, 0x01780803, + 0x81C, 0x017A0803, + 0x81C, 0x017C0803, + 0x81C, 0x017E0803, + 0xA0000000, 0x00000000, + 0x81C, 0xFC000803, + 0x81C, 0xFB020803, + 0x81C, 0xFA040803, + 0x81C, 0xF9060803, + 0x81C, 0xF8080803, + 0x81C, 0xF70A0803, + 0x81C, 0xF60C0803, + 0x81C, 0xF50E0803, + 0x81C, 0xF4100803, + 0x81C, 0xF3120803, + 0x81C, 0xF2140803, + 0x81C, 0xF1160803, + 0x81C, 0xF0180803, + 0x81C, 0xEF1A0803, + 0x81C, 0xEE1C0803, + 0x81C, 0xED1E0803, + 0x81C, 0xB5200803, + 0x81C, 0xB4220803, + 0x81C, 0xB3240803, + 0x81C, 0xB2260803, + 0x81C, 0xB1280803, + 0x81C, 0xB02A0803, + 0x81C, 0xAF2C0803, + 0x81C, 0xAE2E0803, + 0x81C, 0xAD300803, + 0x81C, 0xAC320803, + 0x81C, 0xAB340803, + 0x81C, 0xAA360803, + 0x81C, 0xA9380803, + 0x81C, 0xA83A0803, + 0x81C, 0xA73C0803, + 0x81C, 0xA63E0803, + 0x81C, 0x88400803, + 0x81C, 0x87420803, + 0x81C, 0x86440803, + 0x81C, 0x85460803, + 0x81C, 0x84480803, + 0x81C, 0x834A0803, + 0x81C, 0x674C0803, + 0x81C, 0x664E0803, + 0x81C, 0x65500803, + 0x81C, 0x64520803, + 0x81C, 0x63540803, + 0x81C, 0x62560803, + 0x81C, 0x61580803, + 0x81C, 0x455A0803, + 0x81C, 0x445C0803, + 0x81C, 0x435E0803, + 0x81C, 0x42600803, + 0x81C, 0x41620803, + 0x81C, 0x25640803, + 0x81C, 0x24660803, + 0x81C, 0x23680803, + 0x81C, 0x226A0803, + 0x81C, 0x216C0803, + 0x81C, 0x016E0803, + 0x81C, 0x01700803, + 0x81C, 0x01720803, + 0x81C, 0x01740803, + 0x81C, 0x01760803, + 0x81C, 0x01780803, + 0x81C, 0x017A0803, + 0x81C, 0x017C0803, + 0x81C, 0x017E0803, + 0xB0000000, 0x00000000, + 0x80001004, 0x00000000, 0x40000000, 0x00000000, + 0x81C, 0xFF000913, + 0x81C, 0xFE020913, + 0x81C, 0xFD040913, + 0x81C, 0xFC060913, + 0x81C, 0xFB080913, + 0x81C, 0xFA0A0913, + 0x81C, 0xF90C0913, + 0x81C, 0xF80E0913, + 0x81C, 0xF7100913, + 0x81C, 0xF6120913, + 0x81C, 0xF5140913, + 0x81C, 0xF4160913, + 0x81C, 0xF3180913, + 0x81C, 0xF21A0913, + 0x81C, 0xF11C0913, + 0x81C, 0x941E0913, + 0x81C, 0x93200913, + 0x81C, 0x92220913, + 0x81C, 0x91240913, + 0x81C, 0x90260913, + 0x81C, 0x8F280913, + 0x81C, 0x8E2A0913, + 0x81C, 0x8D2C0913, + 0x81C, 0x8C2E0913, + 0x81C, 0x8B300913, + 0x81C, 0x8A320913, + 0x81C, 0x89340913, + 0x81C, 0x88360913, + 0x81C, 0x87380913, + 0x81C, 0x863A0913, + 0x81C, 0x853C0913, + 0x81C, 0x843E0913, + 0x81C, 0x83400913, + 0x81C, 0x82420913, + 0x81C, 0x81440913, + 0x81C, 0x07460913, + 0x81C, 0x06480913, + 0x81C, 0x054A0913, + 0x81C, 0x044C0913, + 0x81C, 0x034E0913, + 0x81C, 0x02500913, + 0x81C, 0x01520913, + 0x81C, 0x88540903, + 0x81C, 0x87560903, + 0x81C, 0x86580903, + 0x81C, 0x855A0903, + 0x81C, 0x845C0903, + 0x81C, 0x835E0903, + 0x81C, 0x82600903, + 0x81C, 0x81620903, + 0x81C, 0x07640903, + 0x81C, 0x06660903, + 0x81C, 0x05680903, + 0x81C, 0x046A0903, + 0x81C, 0x036C0903, + 0x81C, 0x026E0903, + 0x81C, 0x01700903, + 0x81C, 0x01720903, + 0x81C, 0x01740903, + 0x81C, 0x01760903, + 0x81C, 0x01780903, + 0x81C, 0x017A0903, + 0x81C, 0x017C0903, + 0x81C, 0x017E0903, + 0x90001005, 0x00000000, 0x40000000, 0x00000000, + 0x81C, 0xFF000913, + 0x81C, 0xFE020913, + 0x81C, 0xFD040913, + 0x81C, 0xFC060913, + 0x81C, 0xFB080913, + 0x81C, 0xFA0A0913, + 0x81C, 0xF90C0913, + 0x81C, 0xF80E0913, + 0x81C, 0xF7100913, + 0x81C, 0xF6120913, + 0x81C, 0xF5140913, + 0x81C, 0xF4160913, + 0x81C, 0xF3180913, + 0x81C, 0xF21A0913, + 0x81C, 0xF11C0913, + 0x81C, 0x941E0913, + 0x81C, 0x93200913, + 0x81C, 0x92220913, + 0x81C, 0x91240913, + 0x81C, 0x90260913, + 0x81C, 0x8F280913, + 0x81C, 0x8E2A0913, + 0x81C, 0x8D2C0913, + 0x81C, 0x8C2E0913, + 0x81C, 0x8B300913, + 0x81C, 0x8A320913, + 0x81C, 0x89340913, + 0x81C, 0x88360913, + 0x81C, 0x87380913, + 0x81C, 0x863A0913, + 0x81C, 0x853C0913, + 0x81C, 0x843E0913, + 0x81C, 0x83400913, + 0x81C, 0x82420913, + 0x81C, 0x81440913, + 0x81C, 0x07460913, + 0x81C, 0x06480913, + 0x81C, 0x054A0913, + 0x81C, 0x044C0913, + 0x81C, 0x034E0913, + 0x81C, 0x02500913, + 0x81C, 0x01520913, + 0x81C, 0x88540903, + 0x81C, 0x87560903, + 0x81C, 0x86580903, + 0x81C, 0x855A0903, + 0x81C, 0x845C0903, + 0x81C, 0x835E0903, + 0x81C, 0x82600903, + 0x81C, 0x81620903, + 0x81C, 0x07640903, + 0x81C, 0x06660903, + 0x81C, 0x05680903, + 0x81C, 0x046A0903, + 0x81C, 0x036C0903, + 0x81C, 0x026E0903, + 0x81C, 0x01700903, + 0x81C, 0x01720903, + 0x81C, 0x01740903, + 0x81C, 0x01760903, + 0x81C, 0x01780903, + 0x81C, 0x017A0903, + 0x81C, 0x017C0903, + 0x81C, 0x017E0903, + 0xA0000000, 0x00000000, + 0x81C, 0xFF000913, + 0x81C, 0xFE020913, + 0x81C, 0xFD040913, + 0x81C, 0xFC060913, + 0x81C, 0xFB080913, + 0x81C, 0xFA0A0913, + 0x81C, 0xF90C0913, + 0x81C, 0xF80E0913, + 0x81C, 0xF7100913, + 0x81C, 0xF6120913, + 0x81C, 0xF5140913, + 0x81C, 0xF4160913, + 0x81C, 0xF3180913, + 0x81C, 0xF21A0913, + 0x81C, 0xF11C0913, + 0x81C, 0x941E0913, + 0x81C, 0x93200913, + 0x81C, 0x92220913, + 0x81C, 0x91240913, + 0x81C, 0x90260913, + 0x81C, 0x8F280913, + 0x81C, 0x8E2A0913, + 0x81C, 0x8D2C0913, + 0x81C, 0x8C2E0913, + 0x81C, 0x8B300913, + 0x81C, 0x8A320913, + 0x81C, 0x89340913, + 0x81C, 0x88360913, + 0x81C, 0x87380913, + 0x81C, 0x863A0913, + 0x81C, 0x853C0913, + 0x81C, 0x843E0913, + 0x81C, 0x83400913, + 0x81C, 0x82420913, + 0x81C, 0x81440913, + 0x81C, 0x07460913, + 0x81C, 0x06480913, + 0x81C, 0x054A0913, + 0x81C, 0x044C0913, + 0x81C, 0x034E0913, + 0x81C, 0x02500913, + 0x81C, 0x01520913, + 0x81C, 0x88540903, + 0x81C, 0x87560903, + 0x81C, 0x86580903, + 0x81C, 0x855A0903, + 0x81C, 0x845C0903, + 0x81C, 0x835E0903, + 0x81C, 0x82600903, + 0x81C, 0x81620903, + 0x81C, 0x07640903, + 0x81C, 0x06660903, + 0x81C, 0x05680903, + 0x81C, 0x046A0903, + 0x81C, 0x036C0903, + 0x81C, 0x026E0903, + 0x81C, 0x01700903, + 0x81C, 0x01720903, + 0x81C, 0x01740903, + 0x81C, 0x01760903, + 0x81C, 0x01780903, + 0x81C, 0x017A0903, + 0x81C, 0x017C0903, + 0x81C, 0x017E0903, + 0xB0000000, 0x00000000, + 0x80001004, 0x00000000, 0x40000000, 0x00000000, + 0xC50, 0x00000022, + 0xC50, 0x00000020, + 0x90001005, 0x00000000, 0x40000000, 0x00000000, + 0xC50, 0x00000022, + 0xC50, 0x00000022, + 0xA0000000, 0x00000000, + 0xC50, 0x00000022, + 0xC50, 0x00000020, + 0xB0000000, 0x00000000, + +}; + +RTW_DECL_TABLE_PHY_COND(rtw8821c_agc, rtw_phy_cfg_agc); + +static const u32 rtw8821c_bb[] = { + 0x800, 0x9020D010, + 0x804, 0x80018180, + 0x808, 0x04028211, + 0x80C, 0x13D10011, + 0x810, 0x21104255, + 0x814, 0x020C3D10, + 0x818, 0x84A10385, + 0x81C, 0x1E1E081F, + 0x820, 0x0001AAAA, + 0x824, 0x00030FE0, + 0x828, 0x0000CCCC, + 0x82C, 0x75CB7010, + 0x830, 0x79A0EAAA, + 0x834, 0x072E698A, + 0x838, 0x87766461, + 0x83C, 0x9194B2B6, + 0x840, 0x171740E0, + 0x844, 0x4D3D7CDB, + 0x848, 0x4AD0408B, + 0x84C, 0x6AFBF7A5, + 0x850, 0x28A74706, + 0x854, 0x0001520C, + 0x858, 0x4060C000, + 0x85C, 0x74010160, + 0x860, 0x68A7C321, + 0x864, 0x79F27432, + 0x868, 0x8CA7A314, + 0x86C, 0x558C2878, + 0x870, 0x55555555, + 0x874, 0x27612C2E, + 0x878, 0xC0003152, + 0x87C, 0x5C8FC000, + 0x880, 0x00000000, + 0x884, 0x00000000, + 0x888, 0x00000000, + 0x88C, 0x00000000, + 0x890, 0x00000000, + 0x894, 0x00000000, + 0x898, 0x00000000, + 0x89C, 0x00000000, + 0x8A0, 0x00000013, + 0x8A4, 0x7F7F7F7F, + 0x8A8, 0x2202033E, + 0x8AC, 0xF00F000A, + 0x8B0, 0x00000600, + 0x8B4, 0x000FC080, + 0x8B8, 0xEC0057FF, + 0x8BC, 0x2CB520A3, + 0x8C0, 0xFFE04020, + 0x8C4, 0x47C00000, + 0x8C8, 0x00025165, + 0x8CC, 0x08188492, + 0x8D0, 0x0000B800, + 0x8D4, 0x860308A0, + 0x8D8, 0x290B5612, + 0x8DC, 0x00000000, + 0x8E0, 0x32D16777, + 0x8E4, 0x49092925, + 0x8E8, 0xFFFFC42C, + 0x8EC, 0x99999999, + 0x8F0, 0x00009999, + 0x8F4, 0x00D80FA1, + 0x8F8, 0x400000C0, + 0x8FC, 0x00000130, + 0x900, 0x00C00000, + 0x904, 0x0FFF0FFF, + 0x908, 0x00000000, + 0x90C, 0x13000000, + 0x910, 0x0000FC00, + 0x914, 0xC6380000, + 0x918, 0x1C1028C0, + 0x91C, 0x64B11A1C, + 0x920, 0xE0767233, + 0x924, 0x855A2500, + 0x928, 0x4AB0E4E4, + 0x92C, 0xFFFEB200, + 0x930, 0xFFFFFFFE, + 0x934, 0x001FFFFF, + 0x938, 0x00008480, + 0x93C, 0xE41C0642, + 0x940, 0x0E470430, + 0x944, 0x00000000, + 0x948, 0xAC000000, + 0x94C, 0x10000083, + 0x950, 0xB2010080, + 0x954, 0x86510080, + 0x958, 0x00000181, + 0x95C, 0x04248000, + 0x960, 0x00000000, + 0x964, 0x00000000, + 0x968, 0x00000000, + 0x96C, 0x00000000, + 0x970, 0x00001FFF, + 0x974, 0x04000FFF, + 0x978, 0x00000000, + 0x97C, 0x00000000, + 0x980, 0x00000000, + 0x984, 0x00000000, + 0x988, 0x00000000, + 0x98C, 0x23440000, + 0x990, 0x27100000, + 0x994, 0xFFFF0100, + 0x998, 0xFFFFFF5C, + 0x99C, 0xFFFFFFFF, + 0x9A0, 0x000000FF, + 0x9A4, 0x80000088, + 0x9A8, 0x0C2F0000, + 0x9AC, 0x01560000, + 0x9B0, 0x70000000, + 0x9B4, 0x00000000, + 0x9B8, 0x00000000, + 0x9BC, 0x00000000, + 0x9C0, 0x00000000, + 0x9C4, 0x00000000, + 0x9C8, 0x00000000, + 0x9CC, 0x00000000, + 0x9D0, 0x00000000, + 0x9D4, 0x00000000, + 0x9D8, 0x00000000, + 0x9DC, 0x00000000, + 0x9E0, 0x00000000, + 0x9E4, 0x02000402, + 0x9E8, 0x000022D4, + 0x9EC, 0x00000000, + 0x9F0, 0x00000000, + 0x9F4, 0x00000000, + 0x9F8, 0x00000000, + 0x9FC, 0xEFFFF7FF, + 0xA00, 0x00D040C8, + 0xA04, 0x80FF800C, + 0xA08, 0x9C838300, + 0xA0C, 0x297E000F, + 0xA10, 0x9500BB78, + 0xA14, 0x1114D028, + 0xA18, 0x00881117, + 0xA1C, 0x89140F00, + 0xA20, 0xE82C0000, + 0xA24, 0x64B80C1C, + 0xA28, 0x00008810, + 0xA2C, 0x00D20000, + 0xA70, 0x101FBF00, + 0xA74, 0x00000107, + 0xA78, 0x00008900, + 0xA7C, 0x225B0606, + 0xA80, 0x21807532, + 0xA84, 0x80120000, + 0xA88, 0x048C0000, + 0xA8C, 0x12345678, + 0xA90, 0xABCDEF00, + 0xA94, 0x001B1B89, + 0xA98, 0x00000000, + 0xA9C, 0x3F000000, + 0xAA0, 0x00000000, + 0xAA4, 0x00080000, + 0xAA8, 0xEACF0004, + 0xAAC, 0x01235667, + 0xAB0, 0x00000000, + 0xB00, 0xE1000440, + 0xB04, 0x00800000, + 0xB08, 0xFF02030B, + 0xB0C, 0x01EAA406, + 0xB10, 0x00030690, + 0xB14, 0x006000FA, + 0xB18, 0x00000002, + 0xB1C, 0x00000002, + 0xB20, 0x4B00001F, + 0xB24, 0x4E8E3E40, + 0xB28, 0x03020100, + 0xB2C, 0x07060504, + 0xB30, 0x0B0A0908, + 0xB34, 0x0F0E0D0C, + 0xB38, 0x13121110, + 0xB3C, 0x0000003A, + 0xB40, 0x00000000, + 0xB44, 0x80000000, + 0xB48, 0x3F0000FA, + 0xB4C, 0x88C80020, + 0xB50, 0x00000000, + 0xB54, 0x00004241, + 0xB58, 0xE0008208, + 0xB5C, 0x41EFFFF9, + 0xB60, 0x00000000, + 0xB64, 0x00200063, + 0xB68, 0x0000003A, + 0xB6C, 0x00000102, + 0xB70, 0x4E6D1870, + 0xB74, 0x03020100, + 0xB78, 0x07060504, + 0xB7C, 0x0B0A0908, + 0xB80, 0x0F0E0D0C, + 0xB84, 0x13121110, + 0xB88, 0x00000000, + 0xB8C, 0x00000000, + 0xC00, 0x00000007, + 0xC04, 0x03050020, + 0xC08, 0x60403231, + 0xC0C, 0x00012345, + 0xC10, 0x00000100, + 0xC14, 0x01000000, + 0xC18, 0x00000000, + 0xC1C, 0x40040053, + 0xC20, 0x400503A3, + 0xC24, 0x00000000, + 0xC28, 0x00000000, + 0xC2C, 0x00000000, + 0xC30, 0x00000000, + 0xC34, 0x00000000, + 0xC38, 0x00000000, + 0xC3C, 0x00000000, + 0xC40, 0x00000000, + 0xC44, 0x00000000, + 0xC48, 0x00000000, + 0xC4C, 0x00000000, + 0xC50, 0x00000020, + 0xC54, 0x00000000, + 0xC58, 0xD8020402, + 0xC5C, 0xDE000120, + 0xC68, 0x0000003F, + 0xC6C, 0x0000122A, + 0xC70, 0x00000000, + 0xC74, 0x00000000, + 0xC78, 0x00000000, + 0xC7C, 0x00000000, + 0xC80, 0x00000000, + 0xC84, 0x00000000, + 0xC88, 0x00000000, + 0xC8C, 0x07000000, + 0xC94, 0x01000100, + 0xC98, 0x201C8000, + 0xC9C, 0x00000000, + 0xCA0, 0x0000A555, + 0xCA4, 0x08040201, + 0xCA8, 0x80402010, + 0xCAC, 0x00000000, + 0x80001005, 0x00000000, 0x40000000, 0x00000000, + 0xCB0, 0x77777717, + 0xCB4, 0x00000073, + 0xA0000000, 0x00000000, + 0xCB0, 0x77775747, + 0xCB4, 0x10000077, + 0xB0000000, 0x00000000, + 0xCB8, 0x00000000, + 0xCBC, 0x00000000, + 0xCC0, 0x00000000, + 0xCC4, 0x00000000, + 0xCC8, 0x00000000, + 0xCCC, 0x00000000, + 0xCD0, 0x00000000, + 0xCD4, 0x00000000, + 0xCD8, 0x00000000, + 0xCDC, 0x00000000, + 0xCE0, 0x00000000, + 0xCE4, 0x00000000, + 0xCE8, 0x00000000, + 0xCEC, 0x00000000, + 0xE00, 0x00000007, + 0xE04, 0x00000020, + 0xE08, 0x60403231, + 0xE0C, 0x00012345, + 0xE10, 0x00000100, + 0xE14, 0x01000000, + 0xE18, 0x00000000, + 0xE1C, 0x40040053, + 0xE20, 0x00020103, + 0xE24, 0x00000000, + 0xE28, 0x00000000, + 0xE2C, 0x00000000, + 0xE30, 0x00000000, + 0xE34, 0x00000000, + 0xE38, 0x00000000, + 0xE3C, 0x00000000, + 0xE40, 0x00000000, + 0xE44, 0x00000000, + 0xE48, 0x00000000, + 0xE4C, 0x00000000, + 0xE50, 0x00000020, + 0xE54, 0x00000000, + 0xE58, 0xD8020402, + 0xE5C, 0xDE000120, + 0xE68, 0x59799979, + 0xE6C, 0x0000122A, + 0xE70, 0x99795979, + 0xE74, 0x99795979, + 0xE78, 0x99799979, + 0xE7C, 0x99791979, + 0xE80, 0x19791979, + 0xE84, 0x19791979, + 0xE88, 0x00000000, + 0xE8C, 0x07000000, + 0xE94, 0x01000100, + 0xE98, 0x201C8000, + 0xE9C, 0x00000000, + 0xEA0, 0x0000A555, + 0xEA4, 0x08040201, + 0xEA8, 0x80402010, + 0xEAC, 0x00000000, + 0xEB0, 0x98543210, + 0xEB4, 0x000000BA, + 0xEB8, 0x00000000, + 0xEBC, 0x00000000, + 0xEC0, 0x00000000, + 0xEC4, 0x00000000, + 0xEC8, 0x00000000, + 0xECC, 0x00000000, + 0xED0, 0x00000000, + 0xED4, 0x00000000, + 0xED8, 0x00000000, + 0xEDC, 0x00000000, + 0xEE0, 0x00000000, + 0xEE4, 0x00000000, + 0xEE8, 0x00000000, + 0xEEC, 0x00000000, + 0x1900, 0x00000000, + 0x1904, 0x00238000, + 0x1908, 0x00000000, + 0x190C, 0x00000000, + 0x1910, 0x00001800, + 0x1914, 0x00000000, + 0x1918, 0x00000000, + 0x191C, 0x00000000, + 0x1920, 0x00000000, + 0x1924, 0x00000000, + 0x1928, 0x00000000, + 0x192C, 0x00000000, + 0x1930, 0x00000000, + 0x1934, 0x00000000, + 0x1938, 0x00000000, + 0x193C, 0x00000000, + 0x1940, 0x00000000, + 0x1944, 0x00000000, + 0x1948, 0x00000000, + 0x194C, 0x00000000, + 0x1950, 0x00000000, + 0x1954, 0x00000000, + 0x1958, 0x00000000, + 0x195C, 0x00000000, + 0x1960, 0x00000000, + 0x1964, 0x00000000, + 0x1968, 0x00000000, + 0x196C, 0x00000000, + 0x1970, 0x00000000, + 0x1974, 0x00000000, + 0x1978, 0x00000000, + 0x197C, 0x00000000, + 0x1980, 0x00000000, + 0x1984, 0x03000000, + 0x1988, 0x21401E88, + 0x198C, 0x00004000, + 0x1990, 0x00000000, + 0x1994, 0x00000000, + 0x1998, 0x00000053, + 0x199C, 0x00000000, + 0x19A0, 0x00000000, + 0x19A4, 0x00000000, + 0x19A8, 0x010A0000, + 0x19AC, 0x0E47E47F, + 0x19B0, 0x00008000, + 0x19B4, 0x0E47E47F, + 0x19B8, 0x00000000, + 0x19BC, 0x00000000, + 0x19C0, 0x00000000, + 0x19C4, 0x00000000, + 0x19C8, 0x00000000, + 0x19CC, 0x00000000, + 0x19D0, 0x00000000, + 0x19D4, 0x77777777, + 0x19D8, 0x00000777, + 0x19DC, 0x133E0F37, + 0x19E0, 0x00000000, + 0x19E4, 0x00000000, + 0x19E8, 0x00000000, + 0x19EC, 0x00000000, + 0x19F0, 0x00000000, + 0x19F4, 0x00000000, + 0x19F8, 0x01A00000, + 0x19FC, 0x00000000, + 0x1C00, 0x00000100, + 0x1C04, 0x01000000, + 0x1C08, 0x00000100, + 0x1C0C, 0x01000000, + 0x1C10, 0x00000100, + 0x1C14, 0x01000000, + 0x1C18, 0x00000100, + 0x1C1C, 0x01000000, + 0x1C20, 0x00000100, + 0x1C24, 0x01000000, + 0x1C28, 0x00000100, + 0x1C2C, 0x01000000, + 0x1C30, 0x00000100, + 0x1C34, 0x01000000, + 0x1C38, 0x00000000, + 0x1C3C, 0x00008000, + 0x1C40, 0x000C0100, + 0x1C44, 0x000000F3, + 0x1C48, 0x1A8249A8, + 0x1C4C, 0x1461C826, + 0x1C50, 0x0001469E, + 0x1C54, 0x58D158D1, + 0x1C58, 0x04490088, + 0x1C5C, 0x04004400, + 0x1C60, 0x00000000, + 0x1C64, 0x04004400, + 0x1C68, 0x0B7B7B75, + 0x1C6C, 0x01000000, + 0x1C70, 0x00A08145, + 0x1C74, 0x2080E0E0, + 0x1C78, 0x00000000, + 0x1C7C, 0x00000010, + 0x1C80, 0x00000100, + 0x1C84, 0x01000000, + 0x1C88, 0x00000100, + 0x1C8C, 0x01000000, + 0x1C90, 0x00000100, + 0x1C94, 0x01000000, + 0x1C98, 0x00000100, + 0x1C9C, 0x01000000, + 0x1CA0, 0x00000100, + 0x1CA4, 0x01000000, + 0x1CA8, 0x00000100, + 0x1CAC, 0x01000000, + 0x1CB0, 0x00000100, + 0x1CB4, 0x01000000, + 0x1CB8, 0x00000000, + 0x1CBC, 0x00000000, + 0x1CC0, 0x201B0100, + 0x1CC4, 0x00308000, + 0x1CC8, 0x5B74B6E9, + 0x1CCC, 0x01000000, + 0x1CD0, 0x00000400, + 0x1CD4, 0x01000000, + 0x1CD8, 0x01B8ADEB, + 0x1CDC, 0x01000000, + 0x1CE0, 0x00030003, + 0x1CE4, 0x4E4A0306, + 0x1CE8, 0x00000100, + 0x1CEC, 0x01000000, + 0x1CF0, 0x00000100, + 0x1CF4, 0x01000000, + 0x1CF8, 0x01B8ADEB, + 0x1CFC, 0x00000000, + 0xC60, 0x700B8040, + 0xC60, 0x700B8040, + 0xC60, 0x70146040, + 0xC60, 0x70246040, + 0xC60, 0x70346040, + 0xC60, 0x70446040, + 0xC60, 0x705B2040, + 0xC60, 0x70646040, + 0xC60, 0x707B8040, + 0xC60, 0x708B8040, + 0xC60, 0x709B8040, + 0xC60, 0x70AB8040, + 0xC60, 0x70BB6040, + 0xC60, 0x70C06040, + 0xC60, 0x70D06040, + 0xC60, 0x70EF6040, + 0xC60, 0x70F06040, + 0xE60, 0x700B8040, + 0xE60, 0x700B8040, + 0xE60, 0x70146040, + 0xE60, 0x70246040, + 0xE60, 0x70346040, + 0xE60, 0x70446040, + 0xE60, 0x705B2040, + 0xE60, 0x70646040, + 0xE60, 0x707B8040, + 0xE60, 0x708B8040, + 0xE60, 0x709B8040, + 0xE60, 0x70AB8040, + 0xE60, 0x70BB6040, + 0xE60, 0x70C06040, + 0xE60, 0x70D06040, + 0xE60, 0x70EF6040, + 0xE60, 0x70F06040, + 0xC64, 0x00800000, + 0xC64, 0x08800001, + 0xC64, 0x00800002, + 0xC64, 0x00800003, + 0xC64, 0x00800004, + 0xC64, 0x00800005, + 0xC64, 0x00800006, + 0xC64, 0x08800007, + 0xC64, 0x00004000, + 0xE64, 0x00800000, + 0xE64, 0x08800001, + 0xE64, 0x00800002, + 0xE64, 0x00800003, + 0xE64, 0x00800004, + 0xE64, 0x00800005, + 0xE64, 0x00800006, + 0xE64, 0x08800007, + 0xE64, 0x00004000, + 0x1B00, 0xF8000008, + 0x1B00, 0xF80A7008, + 0x1B00, 0xF8015008, + 0x1B00, 0xF8000008, + 0x1B04, 0xE24629D2, + 0x1B08, 0x00000080, + 0x1B0C, 0x00000000, + 0x1B10, 0x00011C00, + 0x1B14, 0x00000000, + 0x1B18, 0x00292903, + 0x1B1C, 0xA2193C32, + 0x1B20, 0x01840008, + 0x1B24, 0x01860008, + 0x1B28, 0x80060300, + 0x1B2C, 0x00000003, + 0x1B30, 0x20000000, + 0x1B34, 0x00000800, + 0x1B3C, 0x20000000, + 0x1BC0, 0x01000000, + 0x1BCC, 0x00000000, + 0x1B90, 0x0001E018, + 0x1B94, 0xF76D9F84, + 0x1BC8, 0x000C44AA, + 0x1BCC, 0x11978200, + 0x1B8C, 0x00002000, + 0x1B9C, 0x5B554F48, + 0x1BA0, 0x6F6B6661, + 0x1BA4, 0x817D7874, + 0x1BA8, 0x908C8884, + 0x1BAC, 0x9D9A9793, + 0x1BB0, 0xAAA7A4A1, + 0x1BB4, 0xB6B3B0AD, + 0x1B40, 0x02CE03E8, + 0x1B44, 0x01FD024C, + 0x1B48, 0x01A101C9, + 0x1B4C, 0x016A0183, + 0x1B50, 0x01430153, + 0x1B54, 0x01280134, + 0x1B58, 0x0112011C, + 0x1B5C, 0x01000107, + 0x1B60, 0x00F200F9, + 0x1B64, 0x00E500EB, + 0x1B68, 0x00DA00E0, + 0x1B6C, 0x00D200D6, + 0x1B70, 0x00C900CD, + 0x1B74, 0x00C200C5, + 0x1B78, 0x00BB00BE, + 0x1B7C, 0x00B500B8, + 0x1BDC, 0x40CAFFE1, + 0x1BDC, 0x4080A1E3, + 0x1BDC, 0x405165E5, + 0x1BDC, 0x403340E7, + 0x1BDC, 0x402028E9, + 0x1BDC, 0x401419EB, + 0x1BDC, 0x400D10ED, + 0x1BDC, 0x40080AEF, + 0x1BDC, 0x400506F1, + 0x1BDC, 0x400304F3, + 0x1BDC, 0x400203F5, + 0x1BDC, 0x400102F7, + 0x1BDC, 0x400101F9, + 0x1BDC, 0x400101FB, + 0x1BDC, 0x400101FD, + 0x1BDC, 0x400101FF, + 0x1BDC, 0x40CAFF81, + 0x1BDC, 0x4080A183, + 0x1BDC, 0x40516585, + 0x1BDC, 0x40334087, + 0x1BDC, 0x40202889, + 0x1BDC, 0x4014198B, + 0x1BDC, 0x400D108D, + 0x1BDC, 0x40080A8F, + 0x1BDC, 0x40050691, + 0x1BDC, 0x40030493, + 0x1BDC, 0x40020395, + 0x1BDC, 0x40010297, + 0x1BDC, 0x40010199, + 0x1BDC, 0x4001019B, + 0x1BDC, 0x4001019D, + 0x1BDC, 0x4001019F, + 0x1BDC, 0x00000000, + 0x1BDC, 0xD0000001, + 0x1BDC, 0xD0000003, + 0x1BDC, 0xD0000005, + 0x1BDC, 0xD0000007, + 0x1BDC, 0xD0000009, + 0x1BDC, 0xD000000B, + 0x1BDC, 0xD000000D, + 0x1BDC, 0xD000000F, + 0x1BDC, 0xD0000011, + 0x1BDC, 0xD0000013, + 0x1BDC, 0xD0000015, + 0x1BDC, 0xD0000017, + 0x1BDC, 0xD0000019, + 0x1BDC, 0xD000001B, + 0x1BDC, 0xD000001D, + 0x1BDC, 0xD000001F, + 0x1BDC, 0xD0000021, + 0x1BDC, 0xD0000023, + 0x1BDC, 0xD0000025, + 0x1BDC, 0xD0000027, + 0x1BDC, 0xD0000029, + 0x1BDC, 0xD000002B, + 0x1BDC, 0xD000002D, + 0x1BDC, 0xD000002F, + 0x1BDC, 0xD0000031, + 0x1BDC, 0xD0000033, + 0x1BDC, 0xD0000035, + 0x1BDC, 0xD0000037, + 0x1BDC, 0xD0000039, + 0x1BDC, 0xD000003B, + 0x1BDC, 0xD000003D, + 0x1BDC, 0xD000003F, + 0x1BDC, 0xD0000041, + 0x1BDC, 0xD0000043, + 0x1BDC, 0xD0000045, + 0x1BDC, 0xD0000047, + 0x1BDC, 0xD0000049, + 0x1BDC, 0xD000004B, + 0x1BDC, 0xD000004D, + 0x1BDC, 0xD000004F, + 0x1BDC, 0xD0000051, + 0x1BDC, 0xD0000053, + 0x1BDC, 0xD0000055, + 0x1BDC, 0xD0000057, + 0x1BDC, 0xD0000059, + 0x1BDC, 0xD000005B, + 0x1BDC, 0xD000005D, + 0x1BDC, 0xD000005F, + 0x1BDC, 0xD0000061, + 0x1BDC, 0xD0000063, + 0x1BDC, 0xD0000065, + 0x1BDC, 0xD0000067, + 0x1BDC, 0xD0000069, + 0x1BDC, 0xD000006B, + 0x1BDC, 0xD000006D, + 0x1BDC, 0xD000006F, + 0x1BDC, 0xD0000071, + 0x1BDC, 0xD0000073, + 0x1BDC, 0xD0000075, + 0x1BDC, 0xD0000077, + 0x1BDC, 0xD0000079, + 0x1BDC, 0xD000007B, + 0x1BDC, 0xD000007D, + 0x1BDC, 0xD000007F, + 0x1BDC, 0x90000081, + 0x1BDC, 0x90000083, + 0x1BDC, 0x90000085, + 0x1BDC, 0x90000087, + 0x1BDC, 0x90000089, + 0x1BDC, 0x9000008B, + 0x1BDC, 0x9000008D, + 0x1BDC, 0x9000008F, + 0x1BDC, 0x90000091, + 0x1BDC, 0x90000093, + 0x1BDC, 0x90000095, + 0x1BDC, 0x90000097, + 0x1BDC, 0x90000099, + 0x1BDC, 0x9000009B, + 0x1BDC, 0x9000009D, + 0x1BDC, 0x9000009F, + 0x1BDC, 0x900000A1, + 0x1BDC, 0x900000A3, + 0x1BDC, 0x900000A5, + 0x1BDC, 0x900000A7, + 0x1BDC, 0x900000A9, + 0x1BDC, 0x900000AB, + 0x1BDC, 0x900000AD, + 0x1BDC, 0x900000AF, + 0x1BDC, 0x900000B1, + 0x1BDC, 0x900000B3, + 0x1BDC, 0x900000B5, + 0x1BDC, 0x900000B7, + 0x1BDC, 0x900000B9, + 0x1BDC, 0x900000BB, + 0x1BDC, 0x900000BD, + 0x1BDC, 0x900000BF, + 0x1BDC, 0x900000C1, + 0x1BDC, 0x900000C3, + 0x1BDC, 0x900000C5, + 0x1BDC, 0x900000C7, + 0x1BDC, 0x900000C9, + 0x1BDC, 0x900000CB, + 0x1BDC, 0x900000CD, + 0x1BDC, 0x900000CF, + 0x1BDC, 0x900000D1, + 0x1BDC, 0x900000D3, + 0x1BDC, 0x900000D5, + 0x1BDC, 0x900000D7, + 0x1BDC, 0x900000D9, + 0x1BDC, 0x900000DB, + 0x1BDC, 0x900000DD, + 0x1BDC, 0x900000DF, + 0x1BDC, 0x900000E1, + 0x1BDC, 0x900000E3, + 0x1BDC, 0x900000E5, + 0x1BDC, 0x900000E7, + 0x1BDC, 0x900000E9, + 0x1BDC, 0x900000EB, + 0x1BDC, 0x900000ED, + 0x1BDC, 0x900000EF, + 0x1BDC, 0x900000F1, + 0x1BDC, 0x900000F3, + 0x1BDC, 0x900000F5, + 0x1BDC, 0x900000F7, + 0x1BDC, 0x900000F9, + 0x1BDC, 0x900000FB, + 0x1BDC, 0x900000FD, + 0x1BDC, 0x900000FF, + 0x1BDC, 0x00000000, + 0x1B00, 0xF8000000, + 0x1B80, 0x00000007, + 0x1B80, 0x090A0005, + 0x1B80, 0x090A0007, + 0x1B80, 0x0FFE0015, + 0x1B80, 0x0FFE0017, + 0x1B80, 0x00220025, + 0x1B80, 0x00220027, + 0x1B80, 0x00040035, + 0x1B80, 0x00040037, + 0x1B80, 0x05C00045, + 0x1B80, 0x05C00047, + 0x1B80, 0x00070055, + 0x1B80, 0x00070057, + 0x1B80, 0x64000065, + 0x1B80, 0x64000067, + 0x1B80, 0x00020075, + 0x1B80, 0x00020077, + 0x1B80, 0x00080085, + 0x1B80, 0x00080087, + 0x1B80, 0x80000095, + 0x1B80, 0x80000097, + 0x1B80, 0x090800A5, + 0x1B80, 0x090800A7, + 0x1B80, 0x0F0200B5, + 0x1B80, 0x0F0200B7, + 0x1B80, 0x002200C5, + 0x1B80, 0x002200C7, + 0x1B80, 0x000400D5, + 0x1B80, 0x000400D7, + 0x1B80, 0x05C000E5, + 0x1B80, 0x05C000E7, + 0x1B80, 0x000700F5, + 0x1B80, 0x000700F7, + 0x1B80, 0x64020105, + 0x1B80, 0x64020107, + 0x1B80, 0x00020115, + 0x1B80, 0x00020117, + 0x1B80, 0x00040125, + 0x1B80, 0x00040127, + 0x1B80, 0x4A000135, + 0x1B80, 0x4A000137, + 0x1B80, 0x4B040145, + 0x1B80, 0x4B040147, + 0x1B80, 0x85030155, + 0x1B80, 0x85030157, + 0x1B80, 0x40090165, + 0x1B80, 0x40090167, + 0x1B80, 0xE02A0175, + 0x1B80, 0xE02A0177, + 0x1B80, 0x4B050185, + 0x1B80, 0x4B050187, + 0x1B80, 0x86030195, + 0x1B80, 0x86030197, + 0x1B80, 0x400B01A5, + 0x1B80, 0x400B01A7, + 0x1B80, 0xE02A01B5, + 0x1B80, 0xE02A01B7, + 0x1B80, 0x4B0001C5, + 0x1B80, 0x4B0001C7, + 0x1B80, 0x000701D5, + 0x1B80, 0x000701D7, + 0x1B80, 0x4C0001E5, + 0x1B80, 0x4C0001E7, + 0x1B80, 0x000401F5, + 0x1B80, 0x000401F7, + 0x1B80, 0x4D040205, + 0x1B80, 0x4D040207, + 0x1B80, 0x2EE00215, + 0x1B80, 0x2EE00217, + 0x1B80, 0x00000225, + 0x1B80, 0x00000227, + 0x1B80, 0x2EF00235, + 0x1B80, 0x2EF00237, + 0x1B80, 0x00000245, + 0x1B80, 0x00000247, + 0x1B80, 0x20810255, + 0x1B80, 0x20810257, + 0x1B80, 0x23450265, + 0x1B80, 0x23450267, + 0x1B80, 0x4D000275, + 0x1B80, 0x4D000277, + 0x1B80, 0x00040285, + 0x1B80, 0x00040287, + 0x1B80, 0x30000295, + 0x1B80, 0x30000297, + 0x1B80, 0xE1D602A5, + 0x1B80, 0xE1D602A7, + 0x1B80, 0xF01102B5, + 0x1B80, 0xF01102B7, + 0x1B80, 0xF11102C5, + 0x1B80, 0xF11102C7, + 0x1B80, 0xF21102D5, + 0x1B80, 0xF21102D7, + 0x1B80, 0xF31102E5, + 0x1B80, 0xF31102E7, + 0x1B80, 0xF41102F5, + 0x1B80, 0xF41102F7, + 0x1B80, 0xF5110305, + 0x1B80, 0xF5110307, + 0x1B80, 0xF6110315, + 0x1B80, 0xF6110317, + 0x1B80, 0xF7110325, + 0x1B80, 0xF7110327, + 0x1B80, 0xF8110335, + 0x1B80, 0xF8110337, + 0x1B80, 0xF9110345, + 0x1B80, 0xF9110347, + 0x1B80, 0xFA110355, + 0x1B80, 0xFA110357, + 0x1B80, 0xFB110365, + 0x1B80, 0xFB110367, + 0x1B80, 0xFC110375, + 0x1B80, 0xFC110377, + 0x1B80, 0xFD110385, + 0x1B80, 0xFD110387, + 0x1B80, 0xFE110395, + 0x1B80, 0xFE110397, + 0x1B80, 0xFF1103A5, + 0x1B80, 0xFF1103A7, + 0x1B80, 0x000103B5, + 0x1B80, 0x000103B7, + 0x1B80, 0x305503C5, + 0x1B80, 0x305503C7, + 0x1B80, 0x306D03D5, + 0x1B80, 0x306D03D7, + 0x1B80, 0x30B803E5, + 0x1B80, 0x30B803E7, + 0x1B80, 0x30BB03F5, + 0x1B80, 0x30BB03F7, + 0x1B80, 0x306F0405, + 0x1B80, 0x306F0407, + 0x1B80, 0x307A0415, + 0x1B80, 0x307A0417, + 0x1B80, 0x30850425, + 0x1B80, 0x30850427, + 0x1B80, 0x30C50435, + 0x1B80, 0x30C50437, + 0x1B80, 0x30BF0445, + 0x1B80, 0x30BF0447, + 0x1B80, 0x30D30455, + 0x1B80, 0x30D30457, + 0x1B80, 0x30DE0465, + 0x1B80, 0x30DE0467, + 0x1B80, 0x30E90475, + 0x1B80, 0x30E90477, + 0x1B80, 0x304C0485, + 0x1B80, 0x304C0487, + 0x1B80, 0x31180495, + 0x1B80, 0x31180497, + 0x1B80, 0x312904A5, + 0x1B80, 0x312904A7, + 0x1B80, 0x313E04B5, + 0x1B80, 0x313E04B7, + 0x1B80, 0x4D0404C5, + 0x1B80, 0x4D0404C7, + 0x1B80, 0x2EE004D5, + 0x1B80, 0x2EE004D7, + 0x1B80, 0x000004E5, + 0x1B80, 0x000004E7, + 0x1B80, 0x2EF004F5, + 0x1B80, 0x2EF004F7, + 0x1B80, 0x00000505, + 0x1B80, 0x00000507, + 0x1B80, 0x20810515, + 0x1B80, 0x20810517, + 0x1B80, 0xA3B50525, + 0x1B80, 0xA3B50527, + 0x1B80, 0x4D000535, + 0x1B80, 0x4D000537, + 0x1B80, 0x30000545, + 0x1B80, 0x30000547, + 0x1B80, 0xE1690555, + 0x1B80, 0xE1690557, + 0x1B80, 0x4D040565, + 0x1B80, 0x4D040567, + 0x1B80, 0x20800575, + 0x1B80, 0x20800577, + 0x1B80, 0x00000585, + 0x1B80, 0x00000587, + 0x1B80, 0x4D000595, + 0x1B80, 0x4D000597, + 0x1B80, 0x550705A5, + 0x1B80, 0x550705A7, + 0x1B80, 0xE16105B5, + 0x1B80, 0xE16105B7, + 0x1B80, 0xE16105C5, + 0x1B80, 0xE16105C7, + 0x1B80, 0x4D0405D5, + 0x1B80, 0x4D0405D7, + 0x1B80, 0x208805E5, + 0x1B80, 0x208805E7, + 0x1B80, 0x020005F5, + 0x1B80, 0x020005F7, + 0x1B80, 0x4D000605, + 0x1B80, 0x4D000607, + 0x1B80, 0x550F0615, + 0x1B80, 0x550F0617, + 0x1B80, 0xE1610625, + 0x1B80, 0xE1610627, + 0x1B80, 0x4F020635, + 0x1B80, 0x4F020637, + 0x1B80, 0x4E000645, + 0x1B80, 0x4E000647, + 0x1B80, 0x53020655, + 0x1B80, 0x53020657, + 0x1B80, 0x52010665, + 0x1B80, 0x52010667, + 0x1B80, 0xE1650675, + 0x1B80, 0xE1650677, + 0x1B80, 0x4D080685, + 0x1B80, 0x4D080687, + 0x1B80, 0x57100695, + 0x1B80, 0x57100697, + 0x1B80, 0x570006A5, + 0x1B80, 0x570006A7, + 0x1B80, 0x4D0006B5, + 0x1B80, 0x4D0006B7, + 0x1B80, 0x000106C5, + 0x1B80, 0x000106C7, + 0x1B80, 0xE16906D5, + 0x1B80, 0xE16906D7, + 0x1B80, 0x000106E5, + 0x1B80, 0x000106E7, + 0x1B80, 0x308F06F5, + 0x1B80, 0x308F06F7, + 0x1B80, 0x00230705, + 0x1B80, 0x00230707, + 0x1B80, 0xE1C90715, + 0x1B80, 0xE1C90717, + 0x1B80, 0x00020725, + 0x1B80, 0x00020727, + 0x1B80, 0x54E90735, + 0x1B80, 0x54E90737, + 0x1B80, 0x0BA60745, + 0x1B80, 0x0BA60747, + 0x1B80, 0x00230755, + 0x1B80, 0x00230757, + 0x1B80, 0xE1C90765, + 0x1B80, 0xE1C90767, + 0x1B80, 0x00020775, + 0x1B80, 0x00020777, + 0x1B80, 0x4D300785, + 0x1B80, 0x4D300787, + 0x1B80, 0x30A80795, + 0x1B80, 0x30A80797, + 0x1B80, 0x308B07A5, + 0x1B80, 0x308B07A7, + 0x1B80, 0x002207B5, + 0x1B80, 0x002207B7, + 0x1B80, 0xE1C907C5, + 0x1B80, 0xE1C907C7, + 0x1B80, 0x000207D5, + 0x1B80, 0x000207D7, + 0x1B80, 0x54E807E5, + 0x1B80, 0x54E807E7, + 0x1B80, 0x0BA607F5, + 0x1B80, 0x0BA607F7, + 0x1B80, 0x00220805, + 0x1B80, 0x00220807, + 0x1B80, 0xE1C90815, + 0x1B80, 0xE1C90817, + 0x1B80, 0x00020825, + 0x1B80, 0x00020827, + 0x1B80, 0x4D300835, + 0x1B80, 0x4D300837, + 0x1B80, 0x30A80845, + 0x1B80, 0x30A80847, + 0x1B80, 0x63F10855, + 0x1B80, 0x63F10857, + 0x1B80, 0xE1690865, + 0x1B80, 0xE1690867, + 0x1B80, 0xE1C90875, + 0x1B80, 0xE1C90877, + 0x1B80, 0x63F40885, + 0x1B80, 0x63F40887, + 0x1B80, 0xE1690895, + 0x1B80, 0xE1690897, + 0x1B80, 0xE1C908A5, + 0x1B80, 0xE1C908A7, + 0x1B80, 0x0BA808B5, + 0x1B80, 0x0BA808B7, + 0x1B80, 0x63F808C5, + 0x1B80, 0x63F808C7, + 0x1B80, 0xE16908D5, + 0x1B80, 0xE16908D7, + 0x1B80, 0xE1C908E5, + 0x1B80, 0xE1C908E7, + 0x1B80, 0x0BA908F5, + 0x1B80, 0x0BA908F7, + 0x1B80, 0x63FC0905, + 0x1B80, 0x63FC0907, + 0x1B80, 0xE1690915, + 0x1B80, 0xE1690917, + 0x1B80, 0xE1C90925, + 0x1B80, 0xE1C90927, + 0x1B80, 0x63FF0935, + 0x1B80, 0x63FF0937, + 0x1B80, 0xE1690945, + 0x1B80, 0xE1690947, + 0x1B80, 0xE1C90955, + 0x1B80, 0xE1C90957, + 0x1B80, 0x63000965, + 0x1B80, 0x63000967, + 0x1B80, 0xE1690975, + 0x1B80, 0xE1690977, + 0x1B80, 0xE1C90985, + 0x1B80, 0xE1C90987, + 0x1B80, 0x63030995, + 0x1B80, 0x63030997, + 0x1B80, 0xE16909A5, + 0x1B80, 0xE16909A7, + 0x1B80, 0xE1C909B5, + 0x1B80, 0xE1C909B7, + 0x1B80, 0xF4D409C5, + 0x1B80, 0xF4D409C7, + 0x1B80, 0x630709D5, + 0x1B80, 0x630709D7, + 0x1B80, 0xE16909E5, + 0x1B80, 0xE16909E7, + 0x1B80, 0xE1C909F5, + 0x1B80, 0xE1C909F7, + 0x1B80, 0xF5DB0A05, + 0x1B80, 0xF5DB0A07, + 0x1B80, 0x630B0A15, + 0x1B80, 0x630B0A17, + 0x1B80, 0xE1690A25, + 0x1B80, 0xE1690A27, + 0x1B80, 0xE1C90A35, + 0x1B80, 0xE1C90A37, + 0x1B80, 0x630E0A45, + 0x1B80, 0x630E0A47, + 0x1B80, 0xE1690A55, + 0x1B80, 0xE1690A57, + 0x1B80, 0xE1C90A65, + 0x1B80, 0xE1C90A67, + 0x1B80, 0x4D300A75, + 0x1B80, 0x4D300A77, + 0x1B80, 0x55010A85, + 0x1B80, 0x55010A87, + 0x1B80, 0x57040A95, + 0x1B80, 0x57040A97, + 0x1B80, 0x57000AA5, + 0x1B80, 0x57000AA7, + 0x1B80, 0x96000AB5, + 0x1B80, 0x96000AB7, + 0x1B80, 0x57080AC5, + 0x1B80, 0x57080AC7, + 0x1B80, 0x57000AD5, + 0x1B80, 0x57000AD7, + 0x1B80, 0x95000AE5, + 0x1B80, 0x95000AE7, + 0x1B80, 0x4D000AF5, + 0x1B80, 0x4D000AF7, + 0x1B80, 0x6C070B05, + 0x1B80, 0x6C070B07, + 0x1B80, 0x7B200B15, + 0x1B80, 0x7B200B17, + 0x1B80, 0x7A000B25, + 0x1B80, 0x7A000B27, + 0x1B80, 0x79000B35, + 0x1B80, 0x79000B37, + 0x1B80, 0x7F200B45, + 0x1B80, 0x7F200B47, + 0x1B80, 0x7E000B55, + 0x1B80, 0x7E000B57, + 0x1B80, 0x7D000B65, + 0x1B80, 0x7D000B67, + 0x1B80, 0x00010B75, + 0x1B80, 0x00010B77, + 0x1B80, 0x62850B85, + 0x1B80, 0x62850B87, + 0x1B80, 0xE1690B95, + 0x1B80, 0xE1690B97, + 0x1B80, 0x00010BA5, + 0x1B80, 0x00010BA7, + 0x1B80, 0x5C320BB5, + 0x1B80, 0x5C320BB7, + 0x1B80, 0xE1C50BC5, + 0x1B80, 0xE1C50BC7, + 0x1B80, 0xE1950BD5, + 0x1B80, 0xE1950BD7, + 0x1B80, 0x00010BE5, + 0x1B80, 0x00010BE7, + 0x1B80, 0x5C320BF5, + 0x1B80, 0x5C320BF7, + 0x1B80, 0x63F40C05, + 0x1B80, 0x63F40C07, + 0x1B80, 0x62850C15, + 0x1B80, 0x62850C17, + 0x1B80, 0x0BB00C25, + 0x1B80, 0x0BB00C27, + 0x1B80, 0xE1690C35, + 0x1B80, 0xE1690C37, + 0x1B80, 0xE1C90C45, + 0x1B80, 0xE1C90C47, + 0x1B80, 0x5C320C55, + 0x1B80, 0x5C320C57, + 0x1B80, 0x63FC0C65, + 0x1B80, 0x63FC0C67, + 0x1B80, 0x62850C75, + 0x1B80, 0x62850C77, + 0x1B80, 0x0BB10C85, + 0x1B80, 0x0BB10C87, + 0x1B80, 0xE1690C95, + 0x1B80, 0xE1690C97, + 0x1B80, 0xE1C90CA5, + 0x1B80, 0xE1C90CA7, + 0x1B80, 0x63030CB5, + 0x1B80, 0x63030CB7, + 0x1B80, 0xE1690CC5, + 0x1B80, 0xE1690CC7, + 0x1B80, 0xE1C90CD5, + 0x1B80, 0xE1C90CD7, + 0x1B80, 0xF7040CE5, + 0x1B80, 0xF7040CE7, + 0x1B80, 0x630B0CF5, + 0x1B80, 0x630B0CF7, + 0x1B80, 0xE1690D05, + 0x1B80, 0xE1690D07, + 0x1B80, 0xE1C90D15, + 0x1B80, 0xE1C90D17, + 0x1B80, 0x00010D25, + 0x1B80, 0x00010D27, + 0x1B80, 0x30F70D35, + 0x1B80, 0x30F70D37, + 0x1B80, 0x00230D45, + 0x1B80, 0x00230D47, + 0x1B80, 0xE1CE0D55, + 0x1B80, 0xE1CE0D57, + 0x1B80, 0x00020D65, + 0x1B80, 0x00020D67, + 0x1B80, 0x54E90D75, + 0x1B80, 0x54E90D77, + 0x1B80, 0x0BA60D85, + 0x1B80, 0x0BA60D87, + 0x1B80, 0x00230D95, + 0x1B80, 0x00230D97, + 0x1B80, 0xE1CE0DA5, + 0x1B80, 0xE1CE0DA7, + 0x1B80, 0x00020DB5, + 0x1B80, 0x00020DB7, + 0x1B80, 0x4D100DC5, + 0x1B80, 0x4D100DC7, + 0x1B80, 0x30A80DD5, + 0x1B80, 0x30A80DD7, + 0x1B80, 0x30F10DE5, + 0x1B80, 0x30F10DE7, + 0x1B80, 0x00220DF5, + 0x1B80, 0x00220DF7, + 0x1B80, 0xE1CE0E05, + 0x1B80, 0xE1CE0E07, + 0x1B80, 0x00020E15, + 0x1B80, 0x00020E17, + 0x1B80, 0x54E80E25, + 0x1B80, 0x54E80E27, + 0x1B80, 0x0BA60E35, + 0x1B80, 0x0BA60E37, + 0x1B80, 0x00220E45, + 0x1B80, 0x00220E47, + 0x1B80, 0xE1CE0E55, + 0x1B80, 0xE1CE0E57, + 0x1B80, 0x00020E65, + 0x1B80, 0x00020E67, + 0x1B80, 0x4D100E75, + 0x1B80, 0x4D100E77, + 0x1B80, 0x30A80E85, + 0x1B80, 0x30A80E87, + 0x1B80, 0x5C320E95, + 0x1B80, 0x5C320E97, + 0x1B80, 0x54F00EA5, + 0x1B80, 0x54F00EA7, + 0x1B80, 0x67F10EB5, + 0x1B80, 0x67F10EB7, + 0x1B80, 0xE1950EC5, + 0x1B80, 0xE1950EC7, + 0x1B80, 0xE1CE0ED5, + 0x1B80, 0xE1CE0ED7, + 0x1B80, 0x67F40EE5, + 0x1B80, 0x67F40EE7, + 0x1B80, 0xE1950EF5, + 0x1B80, 0xE1950EF7, + 0x1B80, 0xE1CE0F05, + 0x1B80, 0xE1CE0F07, + 0x1B80, 0x5C320F15, + 0x1B80, 0x5C320F17, + 0x1B80, 0x54F10F25, + 0x1B80, 0x54F10F27, + 0x1B80, 0x0BA80F35, + 0x1B80, 0x0BA80F37, + 0x1B80, 0x67F80F45, + 0x1B80, 0x67F80F47, + 0x1B80, 0xE1950F55, + 0x1B80, 0xE1950F57, + 0x1B80, 0xE1CE0F65, + 0x1B80, 0xE1CE0F67, + 0x1B80, 0x5C320F75, + 0x1B80, 0x5C320F77, + 0x1B80, 0x54F10F85, + 0x1B80, 0x54F10F87, + 0x1B80, 0x0BA90F95, + 0x1B80, 0x0BA90F97, + 0x1B80, 0x67FC0FA5, + 0x1B80, 0x67FC0FA7, + 0x1B80, 0xE1950FB5, + 0x1B80, 0xE1950FB7, + 0x1B80, 0xE1CE0FC5, + 0x1B80, 0xE1CE0FC7, + 0x1B80, 0x67FF0FD5, + 0x1B80, 0x67FF0FD7, + 0x1B80, 0xE1950FE5, + 0x1B80, 0xE1950FE7, + 0x1B80, 0xE1CE0FF5, + 0x1B80, 0xE1CE0FF7, + 0x1B80, 0x5C321005, + 0x1B80, 0x5C321007, + 0x1B80, 0x54F21015, + 0x1B80, 0x54F21017, + 0x1B80, 0x67001025, + 0x1B80, 0x67001027, + 0x1B80, 0xE1951035, + 0x1B80, 0xE1951037, + 0x1B80, 0xE1CE1045, + 0x1B80, 0xE1CE1047, + 0x1B80, 0x67031055, + 0x1B80, 0x67031057, + 0x1B80, 0xE1951065, + 0x1B80, 0xE1951067, + 0x1B80, 0xE1CE1075, + 0x1B80, 0xE1CE1077, + 0x1B80, 0xF9CC1085, + 0x1B80, 0xF9CC1087, + 0x1B80, 0x67071095, + 0x1B80, 0x67071097, + 0x1B80, 0xE19510A5, + 0x1B80, 0xE19510A7, + 0x1B80, 0xE1CE10B5, + 0x1B80, 0xE1CE10B7, + 0x1B80, 0xFAD310C5, + 0x1B80, 0xFAD310C7, + 0x1B80, 0x5C3210D5, + 0x1B80, 0x5C3210D7, + 0x1B80, 0x54F310E5, + 0x1B80, 0x54F310E7, + 0x1B80, 0x670B10F5, + 0x1B80, 0x670B10F7, + 0x1B80, 0xE1951105, + 0x1B80, 0xE1951107, + 0x1B80, 0xE1CE1115, + 0x1B80, 0xE1CE1117, + 0x1B80, 0x670E1125, + 0x1B80, 0x670E1127, + 0x1B80, 0xE1951135, + 0x1B80, 0xE1951137, + 0x1B80, 0xE1CE1145, + 0x1B80, 0xE1CE1147, + 0x1B80, 0x4D101155, + 0x1B80, 0x4D101157, + 0x1B80, 0x30A81165, + 0x1B80, 0x30A81167, + 0x1B80, 0x00011175, + 0x1B80, 0x00011177, + 0x1B80, 0x6C001185, + 0x1B80, 0x6C001187, + 0x1B80, 0x00061195, + 0x1B80, 0x00061197, + 0x1B80, 0x530011A5, + 0x1B80, 0x530011A7, + 0x1B80, 0x57F711B5, + 0x1B80, 0x57F711B7, + 0x1B80, 0x582111C5, + 0x1B80, 0x582111C7, + 0x1B80, 0x592E11D5, + 0x1B80, 0x592E11D7, + 0x1B80, 0x5A3811E5, + 0x1B80, 0x5A3811E7, + 0x1B80, 0x5B4111F5, + 0x1B80, 0x5B4111F7, + 0x1B80, 0x00071205, + 0x1B80, 0x00071207, + 0x1B80, 0x5C001215, + 0x1B80, 0x5C001217, + 0x1B80, 0x4B001225, + 0x1B80, 0x4B001227, + 0x1B80, 0x4E8F1235, + 0x1B80, 0x4E8F1237, + 0x1B80, 0x4F151245, + 0x1B80, 0x4F151247, + 0x1B80, 0x00041255, + 0x1B80, 0x00041257, + 0x1B80, 0xE1B31265, + 0x1B80, 0xE1B31267, + 0x1B80, 0xAB001275, + 0x1B80, 0xAB001277, + 0x1B80, 0x00011285, + 0x1B80, 0x00011287, + 0x1B80, 0x6C001295, + 0x1B80, 0x6C001297, + 0x1B80, 0x000612A5, + 0x1B80, 0x000612A7, + 0x1B80, 0x530012B5, + 0x1B80, 0x530012B7, + 0x1B80, 0x57F712C5, + 0x1B80, 0x57F712C7, + 0x1B80, 0x582112D5, + 0x1B80, 0x582112D7, + 0x1B80, 0x592E12E5, + 0x1B80, 0x592E12E7, + 0x1B80, 0x5A3812F5, + 0x1B80, 0x5A3812F7, + 0x1B80, 0x5B411305, + 0x1B80, 0x5B411307, + 0x1B80, 0x00071315, + 0x1B80, 0x00071317, + 0x1B80, 0x5C001325, + 0x1B80, 0x5C001327, + 0x1B80, 0x4B401335, + 0x1B80, 0x4B401337, + 0x1B80, 0x4E971345, + 0x1B80, 0x4E971347, + 0x1B80, 0x4F111355, + 0x1B80, 0x4F111357, + 0x1B80, 0x00041365, + 0x1B80, 0x00041367, + 0x1B80, 0xE1B31375, + 0x1B80, 0xE1B31377, + 0x1B80, 0xAB001385, + 0x1B80, 0xAB001387, + 0x1B80, 0x8B001395, + 0x1B80, 0x8B001397, + 0x1B80, 0xAB0013A5, + 0x1B80, 0xAB0013A7, + 0x1B80, 0x8A1913B5, + 0x1B80, 0x8A1913B7, + 0x1B80, 0x301D13C5, + 0x1B80, 0x301D13C7, + 0x1B80, 0x000113D5, + 0x1B80, 0x000113D7, + 0x1B80, 0x6C0113E5, + 0x1B80, 0x6C0113E7, + 0x1B80, 0x000613F5, + 0x1B80, 0x000613F7, + 0x1B80, 0x53011405, + 0x1B80, 0x53011407, + 0x1B80, 0x57F71415, + 0x1B80, 0x57F71417, + 0x1B80, 0x58211425, + 0x1B80, 0x58211427, + 0x1B80, 0x592E1435, + 0x1B80, 0x592E1437, + 0x1B80, 0x5A381445, + 0x1B80, 0x5A381447, + 0x1B80, 0x5B411455, + 0x1B80, 0x5B411457, + 0x1B80, 0x00071465, + 0x1B80, 0x00071467, + 0x1B80, 0x5C001475, + 0x1B80, 0x5C001477, + 0x1B80, 0x4B001485, + 0x1B80, 0x4B001487, + 0x1B80, 0x4E871495, + 0x1B80, 0x4E871497, + 0x1B80, 0x4F1114A5, + 0x1B80, 0x4F1114A7, + 0x1B80, 0x000414B5, + 0x1B80, 0x000414B7, + 0x1B80, 0xE1B314C5, + 0x1B80, 0xE1B314C7, + 0x1B80, 0xAB0014D5, + 0x1B80, 0xAB0014D7, + 0x1B80, 0x000614E5, + 0x1B80, 0x000614E7, + 0x1B80, 0x577714F5, + 0x1B80, 0x577714F7, + 0x1B80, 0x00071505, + 0x1B80, 0x00071507, + 0x1B80, 0x4E861515, + 0x1B80, 0x4E861517, + 0x1B80, 0x00041525, + 0x1B80, 0x00041527, + 0x1B80, 0x00011535, + 0x1B80, 0x00011537, + 0x1B80, 0x00011545, + 0x1B80, 0x00011547, + 0x1B80, 0x7B241555, + 0x1B80, 0x7B241557, + 0x1B80, 0x7A401565, + 0x1B80, 0x7A401567, + 0x1B80, 0x79001575, + 0x1B80, 0x79001577, + 0x1B80, 0x55031585, + 0x1B80, 0x55031587, + 0x1B80, 0x31611595, + 0x1B80, 0x31611597, + 0x1B80, 0x7B1C15A5, + 0x1B80, 0x7B1C15A7, + 0x1B80, 0x7A4015B5, + 0x1B80, 0x7A4015B7, + 0x1B80, 0x550B15C5, + 0x1B80, 0x550B15C7, + 0x1B80, 0x316115D5, + 0x1B80, 0x316115D7, + 0x1B80, 0x7B2015E5, + 0x1B80, 0x7B2015E7, + 0x1B80, 0x7A0015F5, + 0x1B80, 0x7A0015F7, + 0x1B80, 0x55131605, + 0x1B80, 0x55131607, + 0x1B80, 0x74011615, + 0x1B80, 0x74011617, + 0x1B80, 0x74001625, + 0x1B80, 0x74001627, + 0x1B80, 0x8E001635, + 0x1B80, 0x8E001637, + 0x1B80, 0x00011645, + 0x1B80, 0x00011647, + 0x1B80, 0x57021655, + 0x1B80, 0x57021657, + 0x1B80, 0x57001665, + 0x1B80, 0x57001667, + 0x1B80, 0x97001675, + 0x1B80, 0x97001677, + 0x1B80, 0x00011685, + 0x1B80, 0x00011687, + 0x1B80, 0x4F781695, + 0x1B80, 0x4F781697, + 0x1B80, 0x538816A5, + 0x1B80, 0x538816A7, + 0x1B80, 0xE17516B5, + 0x1B80, 0xE17516B7, + 0x1B80, 0x548016C5, + 0x1B80, 0x548016C7, + 0x1B80, 0x540016D5, + 0x1B80, 0x540016D7, + 0x1B80, 0x548116E5, + 0x1B80, 0x548116E7, + 0x1B80, 0x540016F5, + 0x1B80, 0x540016F7, + 0x1B80, 0x54821705, + 0x1B80, 0x54821707, + 0x1B80, 0x54001715, + 0x1B80, 0x54001717, + 0x1B80, 0xE1801725, + 0x1B80, 0xE1801727, + 0x1B80, 0xBF1D1735, + 0x1B80, 0xBF1D1737, + 0x1B80, 0x301D1745, + 0x1B80, 0x301D1747, + 0x1B80, 0xE1551755, + 0x1B80, 0xE1551757, + 0x1B80, 0xE15A1765, + 0x1B80, 0xE15A1767, + 0x1B80, 0xE15E1775, + 0x1B80, 0xE15E1777, + 0x1B80, 0xE1651785, + 0x1B80, 0xE1651787, + 0x1B80, 0xE1C51795, + 0x1B80, 0xE1C51797, + 0x1B80, 0x551317A5, + 0x1B80, 0x551317A7, + 0x1B80, 0xE16117B5, + 0x1B80, 0xE16117B7, + 0x1B80, 0x551517C5, + 0x1B80, 0x551517C7, + 0x1B80, 0xE16517D5, + 0x1B80, 0xE16517D7, + 0x1B80, 0xE1C517E5, + 0x1B80, 0xE1C517E7, + 0x1B80, 0x000117F5, + 0x1B80, 0x000117F7, + 0x1B80, 0x54BF1805, + 0x1B80, 0x54BF1807, + 0x1B80, 0x54C01815, + 0x1B80, 0x54C01817, + 0x1B80, 0x54A31825, + 0x1B80, 0x54A31827, + 0x1B80, 0x54C11835, + 0x1B80, 0x54C11837, + 0x1B80, 0x54A41845, + 0x1B80, 0x54A41847, + 0x1B80, 0x4C181855, + 0x1B80, 0x4C181857, + 0x1B80, 0xBF071865, + 0x1B80, 0xBF071867, + 0x1B80, 0x54C21875, + 0x1B80, 0x54C21877, + 0x1B80, 0x54A41885, + 0x1B80, 0x54A41887, + 0x1B80, 0xBF041895, + 0x1B80, 0xBF041897, + 0x1B80, 0x54C118A5, + 0x1B80, 0x54C118A7, + 0x1B80, 0x54A318B5, + 0x1B80, 0x54A318B7, + 0x1B80, 0xBF0118C5, + 0x1B80, 0xBF0118C7, + 0x1B80, 0xE1D318D5, + 0x1B80, 0xE1D318D7, + 0x1B80, 0x54DF18E5, + 0x1B80, 0x54DF18E7, + 0x1B80, 0x000118F5, + 0x1B80, 0x000118F7, + 0x1B80, 0x54BF1905, + 0x1B80, 0x54BF1907, + 0x1B80, 0x54E51915, + 0x1B80, 0x54E51917, + 0x1B80, 0x050A1925, + 0x1B80, 0x050A1927, + 0x1B80, 0x54DF1935, + 0x1B80, 0x54DF1937, + 0x1B80, 0x00011945, + 0x1B80, 0x00011947, + 0x1B80, 0x7F201955, + 0x1B80, 0x7F201957, + 0x1B80, 0x7E001965, + 0x1B80, 0x7E001967, + 0x1B80, 0x7D001975, + 0x1B80, 0x7D001977, + 0x1B80, 0x55011985, + 0x1B80, 0x55011987, + 0x1B80, 0x5C311995, + 0x1B80, 0x5C311997, + 0x1B80, 0xE16119A5, + 0x1B80, 0xE16119A7, + 0x1B80, 0xE16519B5, + 0x1B80, 0xE16519B7, + 0x1B80, 0x548019C5, + 0x1B80, 0x548019C7, + 0x1B80, 0x540019D5, + 0x1B80, 0x540019D7, + 0x1B80, 0x548119E5, + 0x1B80, 0x548119E7, + 0x1B80, 0x540019F5, + 0x1B80, 0x540019F7, + 0x1B80, 0x54821A05, + 0x1B80, 0x54821A07, + 0x1B80, 0x54001A15, + 0x1B80, 0x54001A17, + 0x1B80, 0xE1801A25, + 0x1B80, 0xE1801A27, + 0x1B80, 0xBFED1A35, + 0x1B80, 0xBFED1A37, + 0x1B80, 0x301D1A45, + 0x1B80, 0x301D1A47, + 0x1B80, 0x00231A55, + 0x1B80, 0x00231A57, + 0x1B80, 0x7B201A65, + 0x1B80, 0x7B201A67, + 0x1B80, 0x7A001A75, + 0x1B80, 0x7A001A77, + 0x1B80, 0x79001A85, + 0x1B80, 0x79001A87, + 0x1B80, 0xE1C91A95, + 0x1B80, 0xE1C91A97, + 0x1B80, 0x00021AA5, + 0x1B80, 0x00021AA7, + 0x1B80, 0x00011AB5, + 0x1B80, 0x00011AB7, + 0x1B80, 0x00221AC5, + 0x1B80, 0x00221AC7, + 0x1B80, 0x7B201AD5, + 0x1B80, 0x7B201AD7, + 0x1B80, 0x7A001AE5, + 0x1B80, 0x7A001AE7, + 0x1B80, 0x79001AF5, + 0x1B80, 0x79001AF7, + 0x1B80, 0xE1C91B05, + 0x1B80, 0xE1C91B07, + 0x1B80, 0x00021B15, + 0x1B80, 0x00021B17, + 0x1B80, 0x00011B25, + 0x1B80, 0x00011B27, + 0x1B80, 0x74021B35, + 0x1B80, 0x74021B37, + 0x1B80, 0x003F1B45, + 0x1B80, 0x003F1B47, + 0x1B80, 0x74001B55, + 0x1B80, 0x74001B57, + 0x1B80, 0x00021B65, + 0x1B80, 0x00021B67, + 0x1B80, 0x00011B75, + 0x1B80, 0x00011B77, + 0x1B80, 0x4D041B85, + 0x1B80, 0x4D041B87, + 0x1B80, 0x2EF81B95, + 0x1B80, 0x2EF81B97, + 0x1B80, 0x00001BA5, + 0x1B80, 0x00001BA7, + 0x1B80, 0x23301BB5, + 0x1B80, 0x23301BB7, + 0x1B80, 0x00241BC5, + 0x1B80, 0x00241BC7, + 0x1B80, 0x23E01BD5, + 0x1B80, 0x23E01BD7, + 0x1B80, 0x003F1BE5, + 0x1B80, 0x003F1BE7, + 0x1B80, 0x23FC1BF5, + 0x1B80, 0x23FC1BF7, + 0x1B80, 0xBFCE1C05, + 0x1B80, 0xBFCE1C07, + 0x1B80, 0x2EF01C15, + 0x1B80, 0x2EF01C17, + 0x1B80, 0x00001C25, + 0x1B80, 0x00001C27, + 0x1B80, 0x4D001C35, + 0x1B80, 0x4D001C37, + 0x1B80, 0x00011C45, + 0x1B80, 0x00011C47, + 0x1B80, 0x549F1C55, + 0x1B80, 0x549F1C57, + 0x1B80, 0x54FF1C65, + 0x1B80, 0x54FF1C67, + 0x1B80, 0x54001C75, + 0x1B80, 0x54001C77, + 0x1B80, 0x00011C85, + 0x1B80, 0x00011C87, + 0x1B80, 0x5C311C95, + 0x1B80, 0x5C311C97, + 0x1B80, 0x07141CA5, + 0x1B80, 0x07141CA7, + 0x1B80, 0x54001CB5, + 0x1B80, 0x54001CB7, + 0x1B80, 0x5C321CC5, + 0x1B80, 0x5C321CC7, + 0x1B80, 0x00011CD5, + 0x1B80, 0x00011CD7, + 0x1B80, 0x5C321CE5, + 0x1B80, 0x5C321CE7, + 0x1B80, 0x07141CF5, + 0x1B80, 0x07141CF7, + 0x1B80, 0x54001D05, + 0x1B80, 0x54001D07, + 0x1B80, 0x5C311D15, + 0x1B80, 0x5C311D17, + 0x1B80, 0x00011D25, + 0x1B80, 0x00011D27, + 0x1B80, 0x4C981D35, + 0x1B80, 0x4C981D37, + 0x1B80, 0x4C181D45, + 0x1B80, 0x4C181D47, + 0x1B80, 0x00011D55, + 0x1B80, 0x00011D57, + 0x1B80, 0x5C321D65, + 0x1B80, 0x5C321D67, + 0x1B80, 0x62841D75, + 0x1B80, 0x62841D77, + 0x1B80, 0x66861D85, + 0x1B80, 0x66861D87, + 0x1B80, 0x6C031D95, + 0x1B80, 0x6C031D97, + 0x1B80, 0x7B201DA5, + 0x1B80, 0x7B201DA7, + 0x1B80, 0x7A001DB5, + 0x1B80, 0x7A001DB7, + 0x1B80, 0x79001DC5, + 0x1B80, 0x79001DC7, + 0x1B80, 0x7F201DD5, + 0x1B80, 0x7F201DD7, + 0x1B80, 0x7E001DE5, + 0x1B80, 0x7E001DE7, + 0x1B80, 0x7D001DF5, + 0x1B80, 0x7D001DF7, + 0x1B80, 0x09011E05, + 0x1B80, 0x09011E07, + 0x1B80, 0x0C011E15, + 0x1B80, 0x0C011E17, + 0x1B80, 0x0BA61E25, + 0x1B80, 0x0BA61E27, + 0x1B80, 0x00011E35, + 0x1B80, 0x00011E37, + 0x1B80, 0x00000006, + 0x1B80, 0x00000002, + +}; + +RTW_DECL_TABLE_PHY_COND(rtw8821c_bb, rtw_phy_cfg_bb); + +static const struct rtw_phy_pg_cfg_pair rtw8821c_bb_pg_type0[] = { + { 0, 0, 0, 0x00000c20, 0xffffffff, 0x32343638, }, + { 0, 0, 0, 0x00000c24, 0xffffffff, 0x36363636, }, + { 0, 0, 0, 0x00000c28, 0xffffffff, 0x28303234, }, + { 0, 0, 0, 0x00000c2c, 0xffffffff, 0x34363636, }, + { 0, 0, 0, 0x00000c30, 0xffffffff, 0x26283032, }, + { 0, 0, 0, 0x00000c3c, 0xffffffff, 0x34363636, }, + { 0, 0, 0, 0x00000c40, 0xffffffff, 0x26283032, }, + { 0, 0, 0, 0x00000c44, 0xffffffff, 0x22222224, }, + { 1, 0, 0, 0x00000c24, 0xffffffff, 0x34343434, }, + { 1, 0, 0, 0x00000c28, 0xffffffff, 0x26283032, }, + { 1, 0, 0, 0x00000c2c, 0xffffffff, 0x32343434, }, + { 1, 0, 0, 0x00000c30, 0xffffffff, 0x24262830, }, + { 1, 0, 0, 0x00000c3c, 0xffffffff, 0x32343434, }, + { 1, 0, 0, 0x00000c40, 0xffffffff, 0x24262830, }, + { 1, 0, 0, 0x00000c44, 0xffffffff, 0x20202022, }, +}; + +RTW_DECL_TABLE_BB_PG(rtw8821c_bb_pg_type0); + +static const u32 rtw8821c_rf_a[] = { + 0x80001005, 0x00000000, 0x40000000, 0x00000000, + 0x000, 0x00010000, + 0x018, 0x00010D24, + 0x90001004, 0x00000000, 0x40000000, 0x00000000, + 0x000, 0x00010000, + 0x018, 0x00010D24, + 0x90000400, 0x00000000, 0x40000000, 0x00000000, + 0x000, 0x00010000, + 0x018, 0x00010D24, + 0xA0000000, 0x00000000, + 0x000, 0x00010000, + 0x018, 0x00010D24, + 0xB0000000, 0x00000000, + 0x80001005, 0x00000000, 0x40000000, 0x00000000, + 0x0EF, 0x00080000, + 0x033, 0x00000002, + 0x03E, 0x0000003F, + 0x03F, 0x000C0F4E, + 0x033, 0x00000001, + 0x03E, 0x00000034, + 0x03F, 0x0004080E, + 0x90001004, 0x00000000, 0x40000000, 0x00000000, + 0x0EF, 0x00080000, + 0x033, 0x00000002, + 0x03E, 0x0000003F, + 0x03F, 0x000C0F4E, + 0x033, 0x00000001, + 0x03E, 0x00000034, + 0x03F, 0x0004080E, + 0x90000400, 0x00000000, 0x40000000, 0x00000000, + 0x0EF, 0x00080000, + 0x033, 0x00000002, + 0x03E, 0x0000003F, + 0x03F, 0x000C0F4E, + 0x033, 0x00000001, + 0x03E, 0x00000034, + 0x03F, 0x0004080E, + 0xA0000000, 0x00000000, + 0x0EF, 0x00080000, + 0x033, 0x00000002, + 0x03E, 0x0000003F, + 0x03F, 0x000C0F4E, + 0x033, 0x00000001, + 0x03E, 0x00000034, + 0x03F, 0x0004080E, + 0xB0000000, 0x00000000, + 0x80001005, 0x00000000, 0x40000000, 0x00000000, + 0x0EF, 0x00002000, + 0x033, 0x00000000, + 0x03F, 0x000005DF, + 0x0EF, 0x00000000, + 0x90001004, 0x00000000, 0x40000000, 0x00000000, + 0x0EF, 0x00002000, + 0x033, 0x00000000, + 0x03F, 0x000005DF, + 0x0EF, 0x00000000, + 0x90000400, 0x00000000, 0x40000000, 0x00000000, + 0x0EF, 0x00002000, + 0x033, 0x00000000, + 0x03F, 0x000005DF, + 0x0EF, 0x00000000, + 0xA0000000, 0x00000000, + 0x0EF, 0x00002000, + 0x033, 0x00000000, + 0x03F, 0x000005DF, + 0x0EF, 0x00000000, + 0xB0000000, 0x00000000, + 0x80001005, 0x00000000, 0x40000000, 0x00000000, + 0x0EE, 0x00000400, + 0x033, 0x00000000, + 0x03F, 0x000005DF, + 0x0EE, 0x00000000, + 0x90001004, 0x00000000, 0x40000000, 0x00000000, + 0x0EE, 0x00000400, + 0x033, 0x00000000, + 0x03F, 0x000005DF, + 0x0EE, 0x00000000, + 0x90000400, 0x00000000, 0x40000000, 0x00000000, + 0x0EE, 0x00000400, + 0x033, 0x00000000, + 0x03F, 0x000005DF, + 0x0EE, 0x00000000, + 0xA0000000, 0x00000000, + 0x0EE, 0x00000400, + 0x033, 0x00000000, + 0x03F, 0x000005DF, + 0x0EE, 0x00000000, + 0xB0000000, 0x00000000, + 0x80001005, 0x00000000, 0x40000000, 0x00000000, + 0x0B0, 0x000FF0F8, + 0x0B1, 0x0007DBE4, + 0x0B2, 0x000225D1, + 0x0B3, 0x000FC760, + 0x0B4, 0x00099DD0, + 0x0B5, 0x000400FC, + 0x0B6, 0x000187F0, + 0x0B7, 0x00030018, + 0x0B8, 0x00080800, + 0x0B9, 0x00000000, + 0x0BA, 0x00008000, + 0x0BB, 0x00000004, + 0x0BC, 0x00040000, + 0x0BD, 0x00000000, + 0x0BE, 0x00000000, + 0x0BF, 0x00000000, + 0x0C0, 0x00000000, + 0x0C1, 0x00000000, + 0x0C2, 0x00000000, + 0x0C3, 0x00000000, + 0x0C4, 0x00002402, + 0x0C5, 0x00000009, + 0x0C6, 0x00040299, + 0x0C7, 0x00055555, + 0x0C8, 0x0000C16C, + 0x0C9, 0x0001C140, + 0x0CA, 0x00000000, + 0x0CB, 0x00000000, + 0x0CC, 0x00000000, + 0x0CD, 0x00000000, + 0x0CE, 0x00090C00, + 0x0CF, 0x0006D200, + 0x0DF, 0x00000009, + 0x90001004, 0x00000000, 0x40000000, 0x00000000, + 0x0B0, 0x000FF0F8, + 0x0B1, 0x0007DBE4, + 0x0B2, 0x000225D1, + 0x0B3, 0x000FC760, + 0x0B4, 0x00099DD0, + 0x0B5, 0x000400FC, + 0x0B6, 0x000187F0, + 0x0B7, 0x00030018, + 0x0B8, 0x00080800, + 0x0B9, 0x00000000, + 0x0BA, 0x00008000, + 0x0BB, 0x00000004, + 0x0BC, 0x00040000, + 0x0BD, 0x00000000, + 0x0BE, 0x00000000, + 0x0BF, 0x00000000, + 0x0C0, 0x00000000, + 0x0C1, 0x00000000, + 0x0C2, 0x00000000, + 0x0C3, 0x00000000, + 0x0C4, 0x00002402, + 0x0C5, 0x00000009, + 0x0C6, 0x00040299, + 0x0C7, 0x00055555, + 0x0C8, 0x0000C16C, + 0x0C9, 0x0001C140, + 0x0CA, 0x00000000, + 0x0CB, 0x00000000, + 0x0CC, 0x00000000, + 0x0CD, 0x00000000, + 0x0CE, 0x00090C00, + 0x0CF, 0x0006D200, + 0x0DF, 0x00000009, + 0x90000400, 0x00000000, 0x40000000, 0x00000000, + 0x0B0, 0x000FF0F8, + 0x0B1, 0x0007DBE4, + 0x0B2, 0x000225D1, + 0x0B3, 0x000FC760, + 0x0B4, 0x00099DD0, + 0x0B5, 0x000400FC, + 0x0B6, 0x000187F0, + 0x0B7, 0x00030018, + 0x0B8, 0x00080800, + 0x0B9, 0x00000000, + 0x0BA, 0x00008000, + 0x0BB, 0x00000004, + 0x0BC, 0x00040000, + 0x0BD, 0x00000000, + 0x0BE, 0x00000000, + 0x0BF, 0x00000000, + 0x0C0, 0x00000000, + 0x0C1, 0x00000000, + 0x0C2, 0x00000000, + 0x0C3, 0x00000000, + 0x0C4, 0x00002402, + 0x0C5, 0x00000009, + 0x0C6, 0x00040299, + 0x0C7, 0x00055555, + 0x0C8, 0x0000C16C, + 0x0C9, 0x0001C140, + 0x0CA, 0x00000000, + 0x0CB, 0x00000000, + 0x0CC, 0x00000000, + 0x0CD, 0x00000000, + 0x0CE, 0x00090C00, + 0x0CF, 0x0006D200, + 0x0DF, 0x00000009, + 0xA0000000, 0x00000000, + 0x0B0, 0x000FF0F8, + 0x0B1, 0x0007DBE4, + 0x0B2, 0x000225D1, + 0x0B3, 0x000FC760, + 0x0B4, 0x00099DD0, + 0x0B5, 0x000400FC, + 0x0B6, 0x000187F0, + 0x0B7, 0x00030018, + 0x0B8, 0x00080800, + 0x0B9, 0x00000000, + 0x0BA, 0x00008000, + 0x0BB, 0x00000004, + 0x0BC, 0x00040000, + 0x0BD, 0x00000000, + 0x0BE, 0x00000000, + 0x0BF, 0x00000000, + 0x0C0, 0x00000000, + 0x0C1, 0x00000000, + 0x0C2, 0x00000000, + 0x0C3, 0x00000000, + 0x0C4, 0x00002402, + 0x0C5, 0x00000009, + 0x0C6, 0x00040299, + 0x0C7, 0x00055555, + 0x0C8, 0x0000C16C, + 0x0C9, 0x0001C140, + 0x0CA, 0x00000000, + 0x0CB, 0x00000000, + 0x0CC, 0x00000000, + 0x0CD, 0x00000000, + 0x0CE, 0x00090C00, + 0x0CF, 0x0006D200, + 0x0DF, 0x00000009, + 0xB0000000, 0x00000000, + 0x80001005, 0x00000000, 0x40000000, 0x00000000, + 0x0EE, 0x00010000, + 0x033, 0x00000058, + 0x03F, 0x0000001C, + 0x0EE, 0x00000000, + 0x90001004, 0x00000000, 0x40000000, 0x00000000, + 0x0EE, 0x00010000, + 0x033, 0x00000058, + 0x03F, 0x0000001C, + 0x0EE, 0x00000000, + 0x90000400, 0x00000000, 0x40000000, 0x00000000, + 0x0EE, 0x00010000, + 0x033, 0x00000058, + 0x03F, 0x0000001C, + 0x0EE, 0x00000000, + 0xA0000000, 0x00000000, + 0x0EE, 0x00010000, + 0x033, 0x00000058, + 0x03F, 0x0000001C, + 0x0EE, 0x00000000, + 0xB0000000, 0x00000000, + 0x80001005, 0x00000000, 0x40000000, 0x00000000, + 0x018, 0x00010524, + 0x081, 0x0000FCC1, + 0x089, 0x00000004, + 0x08A, 0x0008A186, + 0x08B, 0x0006FFFC, + 0x08C, 0x000312C7, + 0x08D, 0x00020888, + 0x08E, 0x00064140, + 0x08F, 0x000A8010, + 0x90001004, 0x00000000, 0x40000000, 0x00000000, + 0x018, 0x00010524, + 0x081, 0x0000FCC1, + 0x089, 0x00000004, + 0x08A, 0x0008A186, + 0x08B, 0x0006FFFC, + 0x08C, 0x000312C7, + 0x08D, 0x00020888, + 0x08E, 0x00064140, + 0x08F, 0x000A8010, + 0x90000400, 0x00000000, 0x40000000, 0x00000000, + 0x018, 0x00010524, + 0x081, 0x0000FCC1, + 0x089, 0x00000004, + 0x08A, 0x0008A186, + 0x08B, 0x0007060C, + 0x08C, 0x000312C7, + 0x08D, 0x00020888, + 0x08E, 0x00064140, + 0x08F, 0x000A8010, + 0xA0000000, 0x00000000, + 0x018, 0x00010524, + 0x081, 0x0000FCC1, + 0x089, 0x00000004, + 0x08A, 0x0008A186, + 0x08B, 0x0007060C, + 0x08C, 0x000312C7, + 0x08D, 0x00020888, + 0x08E, 0x00064140, + 0x08F, 0x000A8010, + 0xB0000000, 0x00000000, + 0x80001005, 0x00000000, 0x40000000, 0x00000000, + 0x0DD, 0x00000020, + 0x90001004, 0x00000000, 0x40000000, 0x00000000, + 0x0DD, 0x00000020, + 0x90000400, 0x00000000, 0x40000000, 0x00000000, + 0x0DD, 0x00000020, + 0xA0000000, 0x00000000, + 0x0DD, 0x00000020, + 0xB0000000, 0x00000000, + 0x80001005, 0x00000000, 0x40000000, 0x00000000, + 0x0EF, 0x00020000, + 0x90001004, 0x00000000, 0x40000000, 0x00000000, + 0x0EF, 0x00020000, + 0x90000400, 0x00000000, 0x40000000, 0x00000000, + 0x0EF, 0x00020000, + 0xA0000000, 0x00000000, + 0x0EF, 0x00020000, + 0xB0000000, 0x00000000, + 0x80001005, 0x00000000, 0x40000000, 0x00000000, + 0x033, 0x00000007, + 0x03E, 0x00038000, + 0x03F, 0x000C3186, + 0x033, 0x00000006, + 0x03E, 0x00038080, + 0x03F, 0x000C3186, + 0x033, 0x00000005, + 0x03E, 0x000380C8, + 0x03F, 0x000C3186, + 0x033, 0x00000004, + 0x03E, 0x00038190, + 0x03F, 0x000C3186, + 0x033, 0x00000003, + 0x03E, 0x00038998, + 0x03F, 0x000C3186, + 0x033, 0x00000002, + 0x03E, 0x00039840, + 0x03F, 0x000C3186, + 0x033, 0x00000001, + 0x03E, 0x000398C4, + 0x03F, 0x000C3186, + 0x033, 0x00000000, + 0x03E, 0x00039930, + 0x03F, 0x000C3186, + 0x90001004, 0x00000000, 0x40000000, 0x00000000, + 0x033, 0x00000007, + 0x03E, 0x00038000, + 0x03F, 0x000C3186, + 0x033, 0x00000006, + 0x03E, 0x00038080, + 0x03F, 0x000C3186, + 0x033, 0x00000005, + 0x03E, 0x000380C8, + 0x03F, 0x000C3186, + 0x033, 0x00000004, + 0x03E, 0x00038190, + 0x03F, 0x000C3186, + 0x033, 0x00000003, + 0x03E, 0x00038998, + 0x03F, 0x000C3186, + 0x033, 0x00000002, + 0x03E, 0x00039840, + 0x03F, 0x000C3186, + 0x033, 0x00000001, + 0x03E, 0x000398C4, + 0x03F, 0x000C3186, + 0x033, 0x00000000, + 0x03E, 0x00039930, + 0x03F, 0x000C3186, + 0x90000400, 0x00000000, 0x40000000, 0x00000000, + 0x033, 0x00000007, + 0x03E, 0x00038000, + 0x03F, 0x000C3186, + 0x033, 0x00000006, + 0x03E, 0x00038080, + 0x03F, 0x000C3186, + 0x033, 0x00000005, + 0x03E, 0x000380C8, + 0x03F, 0x000C3186, + 0x033, 0x00000004, + 0x03E, 0x00038190, + 0x03F, 0x000C3186, + 0x033, 0x00000003, + 0x03E, 0x00038998, + 0x03F, 0x000C3186, + 0x033, 0x00000002, + 0x03E, 0x00039840, + 0x03F, 0x000C3186, + 0x033, 0x00000001, + 0x03E, 0x000398C4, + 0x03F, 0x000C3186, + 0x033, 0x00000000, + 0x03E, 0x00039930, + 0x03F, 0x000C3186, + 0xA0000000, 0x00000000, + 0x033, 0x00000007, + 0x03E, 0x00038000, + 0x03F, 0x000C3186, + 0x033, 0x00000006, + 0x03E, 0x00038080, + 0x03F, 0x000C3186, + 0x033, 0x00000005, + 0x03E, 0x000380C8, + 0x03F, 0x000C3186, + 0x033, 0x00000004, + 0x03E, 0x00038190, + 0x03F, 0x000C3186, + 0x033, 0x00000003, + 0x03E, 0x00038998, + 0x03F, 0x000C3186, + 0x033, 0x00000002, + 0x03E, 0x00039840, + 0x03F, 0x000C3186, + 0x033, 0x00000001, + 0x03E, 0x000398C4, + 0x03F, 0x000C3186, + 0x033, 0x00000000, + 0x03E, 0x00039930, + 0x03F, 0x000C3186, + 0xB0000000, 0x00000000, + 0x80001005, 0x00000000, 0x40000000, 0x00000000, + 0x033, 0x0000000F, + 0x03E, 0x00038000, + 0x03F, 0x000C3186, + 0x033, 0x0000000E, + 0x03E, 0x00038080, + 0x03F, 0x000C3186, + 0x033, 0x0000000D, + 0x03E, 0x000380C8, + 0x03F, 0x000C3186, + 0x033, 0x0000000C, + 0x03E, 0x00038190, + 0x03F, 0x000C3186, + 0x033, 0x0000000B, + 0x03E, 0x00038998, + 0x03F, 0x000C3186, + 0x033, 0x0000000A, + 0x03E, 0x00039840, + 0x03F, 0x000C3186, + 0x033, 0x00000009, + 0x03E, 0x000398C4, + 0x03F, 0x000C3186, + 0x033, 0x00000008, + 0x03E, 0x00039930, + 0x03F, 0x000C3186, + 0x90001004, 0x00000000, 0x40000000, 0x00000000, + 0x033, 0x0000000F, + 0x03E, 0x00038000, + 0x03F, 0x000C3186, + 0x033, 0x0000000E, + 0x03E, 0x00038080, + 0x03F, 0x000C3186, + 0x033, 0x0000000D, + 0x03E, 0x000380C8, + 0x03F, 0x000C3186, + 0x033, 0x0000000C, + 0x03E, 0x00038190, + 0x03F, 0x000C3186, + 0x033, 0x0000000B, + 0x03E, 0x00038998, + 0x03F, 0x000C3186, + 0x033, 0x0000000A, + 0x03E, 0x00039840, + 0x03F, 0x000C3186, + 0x033, 0x00000009, + 0x03E, 0x000398C4, + 0x03F, 0x000C3186, + 0x033, 0x00000008, + 0x03E, 0x00039930, + 0x03F, 0x000C3186, + 0x90000400, 0x00000000, 0x40000000, 0x00000000, + 0x033, 0x0000000F, + 0x03E, 0x00038000, + 0x03F, 0x000C3186, + 0x033, 0x0000000E, + 0x03E, 0x00038080, + 0x03F, 0x000C3186, + 0x033, 0x0000000D, + 0x03E, 0x000380C8, + 0x03F, 0x000C3186, + 0x033, 0x0000000C, + 0x03E, 0x00038190, + 0x03F, 0x000C3186, + 0x033, 0x0000000B, + 0x03E, 0x00038998, + 0x03F, 0x000C3186, + 0x033, 0x0000000A, + 0x03E, 0x00039840, + 0x03F, 0x000C3186, + 0x033, 0x00000009, + 0x03E, 0x000398C4, + 0x03F, 0x000C3186, + 0x033, 0x00000008, + 0x03E, 0x00039930, + 0x03F, 0x000C3186, + 0xA0000000, 0x00000000, + 0x033, 0x0000000F, + 0x03E, 0x00038000, + 0x03F, 0x000C3186, + 0x033, 0x0000000E, + 0x03E, 0x00038080, + 0x03F, 0x000C3186, + 0x033, 0x0000000D, + 0x03E, 0x000380C8, + 0x03F, 0x000C3186, + 0x033, 0x0000000C, + 0x03E, 0x00038190, + 0x03F, 0x000C3186, + 0x033, 0x0000000B, + 0x03E, 0x00038998, + 0x03F, 0x000C3186, + 0x033, 0x0000000A, + 0x03E, 0x00039840, + 0x03F, 0x000C3186, + 0x033, 0x00000009, + 0x03E, 0x000398C4, + 0x03F, 0x000C3186, + 0x033, 0x00000008, + 0x03E, 0x00039930, + 0x03F, 0x000C3186, + 0xB0000000, 0x00000000, + 0x80001005, 0x00000000, 0x40000000, 0x00000000, + 0x033, 0x00000017, + 0x03E, 0x00038000, + 0x03F, 0x000C3186, + 0x033, 0x00000016, + 0x03E, 0x00038080, + 0x03F, 0x000C3186, + 0x033, 0x00000015, + 0x03E, 0x000380C8, + 0x03F, 0x000C3186, + 0x033, 0x00000014, + 0x03E, 0x00038190, + 0x03F, 0x000C3186, + 0x033, 0x00000013, + 0x03E, 0x00038998, + 0x03F, 0x000C3186, + 0x033, 0x00000012, + 0x03E, 0x00039840, + 0x03F, 0x000C3186, + 0x033, 0x00000011, + 0x03E, 0x000398C4, + 0x03F, 0x000C3186, + 0x033, 0x00000010, + 0x03E, 0x00039930, + 0x03F, 0x000C3186, + 0x0EF, 0x00000000, + 0x90001004, 0x00000000, 0x40000000, 0x00000000, + 0x033, 0x00000017, + 0x03E, 0x00038000, + 0x03F, 0x000C3186, + 0x033, 0x00000016, + 0x03E, 0x00038080, + 0x03F, 0x000C3186, + 0x033, 0x00000015, + 0x03E, 0x000380C8, + 0x03F, 0x000C3186, + 0x033, 0x00000014, + 0x03E, 0x00038190, + 0x03F, 0x000C3186, + 0x033, 0x00000013, + 0x03E, 0x00038998, + 0x03F, 0x000C3186, + 0x033, 0x00000012, + 0x03E, 0x00039840, + 0x03F, 0x000C3186, + 0x033, 0x00000011, + 0x03E, 0x000398C4, + 0x03F, 0x000C3186, + 0x033, 0x00000010, + 0x03E, 0x00039930, + 0x03F, 0x000C3186, + 0x0EF, 0x00000000, + 0x90000400, 0x00000000, 0x40000000, 0x00000000, + 0x033, 0x00000017, + 0x03E, 0x00038000, + 0x03F, 0x000C3186, + 0x033, 0x00000016, + 0x03E, 0x00038080, + 0x03F, 0x000C3186, + 0x033, 0x00000015, + 0x03E, 0x000380C8, + 0x03F, 0x000C3186, + 0x033, 0x00000014, + 0x03E, 0x00038190, + 0x03F, 0x000C3186, + 0x033, 0x00000013, + 0x03E, 0x00038998, + 0x03F, 0x000C3186, + 0x033, 0x00000012, + 0x03E, 0x00039840, + 0x03F, 0x000C3186, + 0x033, 0x00000011, + 0x03E, 0x000398C4, + 0x03F, 0x000C3186, + 0x033, 0x00000010, + 0x03E, 0x00039930, + 0x03F, 0x000C3186, + 0x0EF, 0x00000000, + 0xA0000000, 0x00000000, + 0x033, 0x00000017, + 0x03E, 0x00038000, + 0x03F, 0x000C3186, + 0x033, 0x00000016, + 0x03E, 0x00038080, + 0x03F, 0x000C3186, + 0x033, 0x00000015, + 0x03E, 0x000380C8, + 0x03F, 0x000C3186, + 0x033, 0x00000014, + 0x03E, 0x00038190, + 0x03F, 0x000C3186, + 0x033, 0x00000013, + 0x03E, 0x00038998, + 0x03F, 0x000C3186, + 0x033, 0x00000012, + 0x03E, 0x00039840, + 0x03F, 0x000C3186, + 0x033, 0x00000011, + 0x03E, 0x000398C4, + 0x03F, 0x000C3186, + 0x033, 0x00000010, + 0x03E, 0x00039930, + 0x03F, 0x000C3186, + 0x0EF, 0x00000000, + 0xB0000000, 0x00000000, + 0x80001005, 0x00000000, 0x40000000, 0x00000000, + 0x0EF, 0x00004000, + 0x033, 0x00000000, + 0x03F, 0x0000000F, + 0x033, 0x00000001, + 0x03F, 0x0000000A, + 0x033, 0x00000002, + 0x03F, 0x00000005, + 0x0EF, 0x00000000, + 0x90001004, 0x00000000, 0x40000000, 0x00000000, + 0x0EF, 0x00004000, + 0x033, 0x00000000, + 0x03F, 0x0000000F, + 0x033, 0x00000001, + 0x03F, 0x0000000A, + 0x033, 0x00000002, + 0x03F, 0x00000005, + 0x0EF, 0x00000000, + 0x90000400, 0x00000000, 0x40000000, 0x00000000, + 0x0EF, 0x00004000, + 0x033, 0x00000000, + 0x03F, 0x0000000F, + 0x033, 0x00000001, + 0x03F, 0x0000000A, + 0x033, 0x00000002, + 0x03F, 0x00000005, + 0x0EF, 0x00000000, + 0xA0000000, 0x00000000, + 0x0EF, 0x00004000, + 0x033, 0x00000000, + 0x03F, 0x0000000F, + 0x033, 0x00000001, + 0x03F, 0x0000000A, + 0x033, 0x00000002, + 0x03F, 0x00000005, + 0x0EF, 0x00000000, + 0xB0000000, 0x00000000, + 0x80001005, 0x00000000, 0x40000000, 0x00000000, + 0x018, 0x00000401, + 0x084, 0x00001209, + 0x086, 0x000001A0, + 0x087, 0x000E8180, + 0x088, 0x00006020, + 0x0DF, 0x00008009, + 0x90001004, 0x00000000, 0x40000000, 0x00000000, + 0x018, 0x00000401, + 0x084, 0x00001209, + 0x086, 0x000001A0, + 0x087, 0x000E8180, + 0x088, 0x00006020, + 0x0DF, 0x00008009, + 0x90000400, 0x00000000, 0x40000000, 0x00000000, + 0x018, 0x00000401, + 0x084, 0x00001209, + 0x086, 0x000001A0, + 0x087, 0x000E8180, + 0x088, 0x00006020, + 0x0DF, 0x00008009, + 0xA0000000, 0x00000000, + 0x018, 0x00000401, + 0x084, 0x00001209, + 0x086, 0x000001A0, + 0x087, 0x000E8180, + 0x088, 0x00006020, + 0x0DF, 0x00008009, + 0xB0000000, 0x00000000, + 0x80001005, 0x00000000, 0x40000000, 0x00000000, + 0x0EF, 0x00008000, + 0x033, 0x0000000F, + 0x03F, 0x0000003C, + 0x033, 0x0000000E, + 0x03F, 0x00000038, + 0x033, 0x0000000D, + 0x03F, 0x00000030, + 0x033, 0x0000000C, + 0x03F, 0x00000028, + 0x033, 0x0000000B, + 0x03F, 0x00000020, + 0x033, 0x0000000A, + 0x03F, 0x00000018, + 0x033, 0x00000009, + 0x03F, 0x00000010, + 0x033, 0x00000008, + 0x03F, 0x00000008, + 0x033, 0x00000007, + 0x03F, 0x0000003C, + 0x033, 0x00000006, + 0x03F, 0x00000038, + 0x033, 0x00000005, + 0x03F, 0x00000030, + 0x033, 0x00000004, + 0x03F, 0x00000028, + 0x033, 0x00000003, + 0x03F, 0x00000020, + 0x033, 0x00000002, + 0x03F, 0x00000018, + 0x033, 0x00000001, + 0x03F, 0x00000010, + 0x033, 0x00000000, + 0x03F, 0x00000008, + 0x0EF, 0x00000000, + 0x90001004, 0x00000000, 0x40000000, 0x00000000, + 0x0EF, 0x00008000, + 0x033, 0x0000000F, + 0x03F, 0x0000003C, + 0x033, 0x0000000E, + 0x03F, 0x00000038, + 0x033, 0x0000000D, + 0x03F, 0x00000030, + 0x033, 0x0000000C, + 0x03F, 0x00000028, + 0x033, 0x0000000B, + 0x03F, 0x00000020, + 0x033, 0x0000000A, + 0x03F, 0x00000018, + 0x033, 0x00000009, + 0x03F, 0x00000010, + 0x033, 0x00000008, + 0x03F, 0x00000008, + 0x033, 0x00000007, + 0x03F, 0x0000003C, + 0x033, 0x00000006, + 0x03F, 0x00000038, + 0x033, 0x00000005, + 0x03F, 0x00000030, + 0x033, 0x00000004, + 0x03F, 0x00000028, + 0x033, 0x00000003, + 0x03F, 0x00000020, + 0x033, 0x00000002, + 0x03F, 0x00000018, + 0x033, 0x00000001, + 0x03F, 0x00000010, + 0x033, 0x00000000, + 0x03F, 0x00000008, + 0x0EF, 0x00000000, + 0x90000400, 0x00000000, 0x40000000, 0x00000000, + 0x0EF, 0x00008000, + 0x033, 0x0000000F, + 0x03F, 0x0000003C, + 0x033, 0x0000000E, + 0x03F, 0x00000038, + 0x033, 0x0000000D, + 0x03F, 0x00000030, + 0x033, 0x0000000C, + 0x03F, 0x00000028, + 0x033, 0x0000000B, + 0x03F, 0x00000020, + 0x033, 0x0000000A, + 0x03F, 0x00000018, + 0x033, 0x00000009, + 0x03F, 0x00000010, + 0x033, 0x00000008, + 0x03F, 0x00000008, + 0x033, 0x00000007, + 0x03F, 0x0000003C, + 0x033, 0x00000006, + 0x03F, 0x00000038, + 0x033, 0x00000005, + 0x03F, 0x00000030, + 0x033, 0x00000004, + 0x03F, 0x00000028, + 0x033, 0x00000003, + 0x03F, 0x00000020, + 0x033, 0x00000002, + 0x03F, 0x00000018, + 0x033, 0x00000001, + 0x03F, 0x00000010, + 0x033, 0x00000000, + 0x03F, 0x00000008, + 0x0EF, 0x00000000, + 0xA0000000, 0x00000000, + 0x0EF, 0x00008000, + 0x033, 0x0000000F, + 0x03F, 0x0000003C, + 0x033, 0x0000000E, + 0x03F, 0x00000038, + 0x033, 0x0000000D, + 0x03F, 0x00000030, + 0x033, 0x0000000C, + 0x03F, 0x00000028, + 0x033, 0x0000000B, + 0x03F, 0x00000020, + 0x033, 0x0000000A, + 0x03F, 0x00000018, + 0x033, 0x00000009, + 0x03F, 0x00000010, + 0x033, 0x00000008, + 0x03F, 0x00000008, + 0x033, 0x00000007, + 0x03F, 0x0000003C, + 0x033, 0x00000006, + 0x03F, 0x00000038, + 0x033, 0x00000005, + 0x03F, 0x00000030, + 0x033, 0x00000004, + 0x03F, 0x00000028, + 0x033, 0x00000003, + 0x03F, 0x00000020, + 0x033, 0x00000002, + 0x03F, 0x00000018, + 0x033, 0x00000001, + 0x03F, 0x00000010, + 0x033, 0x00000000, + 0x03F, 0x00000008, + 0x0EF, 0x00000000, + 0xB0000000, 0x00000000, + 0x80001005, 0x00000000, 0x40000000, 0x00000000, + 0x0EE, 0x00000002, + 0x033, 0x0000001E, + 0x03F, 0x00000000, + 0x033, 0x0000001C, + 0x03F, 0x00000000, + 0x033, 0x0000000E, + 0x03F, 0x00000000, + 0x033, 0x0000000C, + 0x03F, 0x00000000, + 0x033, 0x0000000A, + 0x03F, 0x00000002, + 0x033, 0x00000008, + 0x03F, 0x00000000, + 0x033, 0x00000036, + 0x03F, 0x00000000, + 0x033, 0x00000037, + 0x03F, 0x00000000, + 0x033, 0x00000034, + 0x03F, 0x00000000, + 0x033, 0x00000026, + 0x03F, 0x00000006, + 0x033, 0x00000027, + 0x03F, 0x00000006, + 0x033, 0x00000024, + 0x03F, 0x00000006, + 0x033, 0x00000022, + 0x03F, 0x00000006, + 0x033, 0x00000020, + 0x03F, 0x00000006, + 0x033, 0x00000006, + 0x03F, 0x00000000, + 0x033, 0x00000007, + 0x03F, 0x00000006, + 0x033, 0x00000004, + 0x03F, 0x00000006, + 0x033, 0x00000002, + 0x03F, 0x00000006, + 0x033, 0x00000000, + 0x03F, 0x00000006, + 0x0EE, 0x00000000, + 0x90001004, 0x00000000, 0x40000000, 0x00000000, + 0x0EE, 0x00000002, + 0x033, 0x0000001E, + 0x03F, 0x00000000, + 0x033, 0x0000001C, + 0x03F, 0x00000000, + 0x033, 0x0000000E, + 0x03F, 0x00000000, + 0x033, 0x0000000C, + 0x03F, 0x00000000, + 0x033, 0x0000000A, + 0x03F, 0x00000002, + 0x033, 0x00000008, + 0x03F, 0x00000000, + 0x033, 0x00000036, + 0x03F, 0x00000000, + 0x033, 0x00000037, + 0x03F, 0x00000000, + 0x033, 0x00000034, + 0x03F, 0x00000000, + 0x033, 0x00000026, + 0x03F, 0x00000006, + 0x033, 0x00000027, + 0x03F, 0x00000006, + 0x033, 0x00000024, + 0x03F, 0x00000006, + 0x033, 0x00000022, + 0x03F, 0x00000006, + 0x033, 0x00000020, + 0x03F, 0x00000006, + 0x033, 0x00000006, + 0x03F, 0x00000000, + 0x033, 0x00000007, + 0x03F, 0x00000006, + 0x033, 0x00000004, + 0x03F, 0x00000006, + 0x033, 0x00000002, + 0x03F, 0x00000006, + 0x033, 0x00000000, + 0x03F, 0x00000006, + 0x0EE, 0x00000000, + 0x90000400, 0x00000000, 0x40000000, 0x00000000, + 0x0EE, 0x00000002, + 0x033, 0x0000001E, + 0x03F, 0x00000000, + 0x033, 0x0000001C, + 0x03F, 0x00000000, + 0x033, 0x0000000E, + 0x03F, 0x00000000, + 0x033, 0x0000000C, + 0x03F, 0x00000000, + 0x033, 0x0000000A, + 0x03F, 0x00000002, + 0x033, 0x00000008, + 0x03F, 0x00000000, + 0x033, 0x00000036, + 0x03F, 0x00000000, + 0x033, 0x00000037, + 0x03F, 0x00000000, + 0x033, 0x00000034, + 0x03F, 0x00000000, + 0x033, 0x00000026, + 0x03F, 0x00000006, + 0x033, 0x00000027, + 0x03F, 0x00000006, + 0x033, 0x00000024, + 0x03F, 0x00000006, + 0x033, 0x00000022, + 0x03F, 0x00000006, + 0x033, 0x00000020, + 0x03F, 0x00000006, + 0x033, 0x00000006, + 0x03F, 0x00000000, + 0x033, 0x00000007, + 0x03F, 0x00000006, + 0x033, 0x00000004, + 0x03F, 0x00000006, + 0x033, 0x00000002, + 0x03F, 0x00000006, + 0x033, 0x00000000, + 0x03F, 0x00000006, + 0x0EE, 0x00000000, + 0xA0000000, 0x00000000, + 0x0EE, 0x00000002, + 0x033, 0x0000001E, + 0x03F, 0x00000000, + 0x033, 0x0000001C, + 0x03F, 0x00000000, + 0x033, 0x0000000E, + 0x03F, 0x00000000, + 0x033, 0x0000000C, + 0x03F, 0x00000000, + 0x033, 0x0000000A, + 0x03F, 0x00000002, + 0x033, 0x00000008, + 0x03F, 0x00000000, + 0x033, 0x00000036, + 0x03F, 0x00000000, + 0x033, 0x00000037, + 0x03F, 0x00000000, + 0x033, 0x00000034, + 0x03F, 0x00000000, + 0x033, 0x00000026, + 0x03F, 0x00000006, + 0x033, 0x00000027, + 0x03F, 0x00000006, + 0x033, 0x00000024, + 0x03F, 0x00000006, + 0x033, 0x00000022, + 0x03F, 0x00000006, + 0x033, 0x00000020, + 0x03F, 0x00000006, + 0x033, 0x00000006, + 0x03F, 0x00000000, + 0x033, 0x00000007, + 0x03F, 0x00000006, + 0x033, 0x00000004, + 0x03F, 0x00000006, + 0x033, 0x00000002, + 0x03F, 0x00000006, + 0x033, 0x00000000, + 0x03F, 0x00000006, + 0x0EE, 0x00000000, + 0xB0000000, 0x00000000, + 0x80001005, 0x00000000, 0x40000000, 0x00000000, + 0x0A0, 0x000F0005, + 0x0A1, 0x0006C000, + 0x0A2, 0x0000161B, + 0x0A3, 0x000B9CBD, + 0x0AF, 0x00070000, + 0x90001004, 0x00000000, 0x40000000, 0x00000000, + 0x0A0, 0x000F0005, + 0x0A1, 0x0006C000, + 0x0A2, 0x0000161B, + 0x0A3, 0x000B9CBD, + 0x0AF, 0x00070000, + 0x90000400, 0x00000000, 0x40000000, 0x00000000, + 0x0A0, 0x000F0005, + 0x0A1, 0x0006C000, + 0x0A2, 0x0000161B, + 0x0A3, 0x000B9CBD, + 0x0AF, 0x00070000, + 0xA0000000, 0x00000000, + 0x0A0, 0x000F0005, + 0x0A1, 0x0006C000, + 0x0A2, 0x0000161B, + 0x0A3, 0x000B9CBD, + 0x0AF, 0x00070000, + 0xB0000000, 0x00000000, + 0x80001005, 0x00000000, 0x40000000, 0x00000000, + 0x0DE, 0x00000200, + 0x0EE, 0x00000100, + 0x033, 0x00000007, + 0x03F, 0x00000043, + 0x033, 0x00000006, + 0x03F, 0x0000007A, + 0x033, 0x00000005, + 0x03F, 0x00000041, + 0x033, 0x00000004, + 0x03F, 0x00000079, + 0x033, 0x00000003, + 0x03F, 0x00000043, + 0x033, 0x00000002, + 0x03F, 0x0000007A, + 0x033, 0x00000001, + 0x03F, 0x00000041, + 0x033, 0x00000000, + 0x03F, 0x00000079, + 0x0EE, 0x00000000, + 0x90001004, 0x00000000, 0x40000000, 0x00000000, + 0x0DE, 0x00000200, + 0x0EE, 0x00000100, + 0x033, 0x00000007, + 0x03F, 0x00000043, + 0x033, 0x00000006, + 0x03F, 0x0000007A, + 0x033, 0x00000005, + 0x03F, 0x00000041, + 0x033, 0x00000004, + 0x03F, 0x00000079, + 0x033, 0x00000003, + 0x03F, 0x00000043, + 0x033, 0x00000002, + 0x03F, 0x0000007A, + 0x033, 0x00000001, + 0x03F, 0x00000041, + 0x033, 0x00000000, + 0x03F, 0x00000079, + 0x0EE, 0x00000000, + 0x90000400, 0x00000000, 0x40000000, 0x00000000, + 0x0DE, 0x00000200, + 0x0EE, 0x00000100, + 0x033, 0x00000007, + 0x03F, 0x00000043, + 0x033, 0x00000006, + 0x03F, 0x0000007A, + 0x033, 0x00000005, + 0x03F, 0x00000041, + 0x033, 0x00000004, + 0x03F, 0x00000079, + 0x033, 0x00000003, + 0x03F, 0x00000043, + 0x033, 0x00000002, + 0x03F, 0x0000007A, + 0x033, 0x00000001, + 0x03F, 0x00000041, + 0x033, 0x00000000, + 0x03F, 0x00000079, + 0x0EE, 0x00000000, + 0xA0000000, 0x00000000, + 0x0DE, 0x00000200, + 0x0EE, 0x00000100, + 0x033, 0x00000007, + 0x03F, 0x00000043, + 0x033, 0x00000006, + 0x03F, 0x0000007A, + 0x033, 0x00000005, + 0x03F, 0x00000041, + 0x033, 0x00000004, + 0x03F, 0x00000079, + 0x033, 0x00000003, + 0x03F, 0x00000043, + 0x033, 0x00000002, + 0x03F, 0x0000007A, + 0x033, 0x00000001, + 0x03F, 0x00000041, + 0x033, 0x00000000, + 0x03F, 0x00000079, + 0x0EE, 0x00000000, + 0xB0000000, 0x00000000, + 0x80001005, 0x00000000, 0x40000000, 0x00000000, + 0x0B8, 0x00080A00, + 0x0B0, 0x000FF0FA, + 0x90001004, 0x00000000, 0x40000000, 0x00000000, + 0x0B8, 0x00080A00, + 0x0B0, 0x000FF0FA, + 0x90000400, 0x00000000, 0x40000000, 0x00000000, + 0x0B8, 0x00080A00, + 0x0B0, 0x000FF0FA, + 0xA0000000, 0x00000000, + 0x0B8, 0x00080A00, + 0x0B0, 0x000FF0FA, + 0xB0000000, 0x00000000, + 0xFFE, 0x00000000, + 0x80001005, 0x00000000, 0x40000000, 0x00000000, + 0x0CA, 0x00080000, + 0x0C9, 0x0001C141, + 0x90001004, 0x00000000, 0x40000000, 0x00000000, + 0x0CA, 0x00080000, + 0x0C9, 0x0001C141, + 0x90000400, 0x00000000, 0x40000000, 0x00000000, + 0x0CA, 0x00080000, + 0x0C9, 0x0001C141, + 0xA0000000, 0x00000000, + 0x0CA, 0x00080000, + 0x0C9, 0x0001C141, + 0xB0000000, 0x00000000, + 0xFFE, 0x00000000, + 0x80001005, 0x00000000, 0x40000000, 0x00000000, + 0x0B0, 0x000FF0F8, + 0x90001004, 0x00000000, 0x40000000, 0x00000000, + 0x0B0, 0x000FF0F8, + 0x90000400, 0x00000000, 0x40000000, 0x00000000, + 0x0B0, 0x000FF0F8, + 0xA0000000, 0x00000000, + 0x0B0, 0x000FF0F8, + 0xB0000000, 0x00000000, + 0x80001005, 0x00000000, 0x40000000, 0x00000000, + 0x018, 0x00018D24, + 0x90001004, 0x00000000, 0x40000000, 0x00000000, + 0x018, 0x00018D24, + 0x90000400, 0x00000000, 0x40000000, 0x00000000, + 0x018, 0x00018D24, + 0xA0000000, 0x00000000, + 0x018, 0x00018D24, + 0xB0000000, 0x00000000, + 0xFFE, 0x00000000, + 0xFFE, 0x00000000, + 0xFFE, 0x00000000, + 0xFFE, 0x00000000, + 0xFFE, 0x00000000, + 0xFFE, 0x00000000, + 0x80001005, 0x00000000, 0x40000000, 0x00000000, + 0x018, 0x00010D24, + 0x90001004, 0x00000000, 0x40000000, 0x00000000, + 0x018, 0x00010D24, + 0x90000400, 0x00000000, 0x40000000, 0x00000000, + 0x018, 0x00010D24, + 0xA0000000, 0x00000000, + 0x018, 0x00010D24, + 0xB0000000, 0x00000000, + 0x80001005, 0x00000000, 0x40000000, 0x00000000, + 0x01B, 0x00003A40, + 0x90001004, 0x00000000, 0x40000000, 0x00000000, + 0x01B, 0x00003A40, + 0x90000400, 0x00000000, 0x40000000, 0x00000000, + 0x01B, 0x00003A40, + 0xA0000000, 0x00000000, + 0x01B, 0x00003A40, + 0xB0000000, 0x00000000, + 0x80001005, 0x00000000, 0x40000000, 0x00000000, + 0x061, 0x0004D3A3, + 0x062, 0x0000D303, + 0x063, 0x00000002, + 0x90001004, 0x00000000, 0x40000000, 0x00000000, + 0x061, 0x0004D3A3, + 0x062, 0x0000D303, + 0x063, 0x00000002, + 0x90000400, 0x00000000, 0x40000000, 0x00000000, + 0x061, 0x0004D3A1, + 0x062, 0x0000D3A3, + 0x063, 0x00000002, + 0xA0000000, 0x00000000, + 0x061, 0x0004D3A1, + 0x062, 0x0000D3A3, + 0x063, 0x00000002, + 0xB0000000, 0x00000000, + 0x80001005, 0x00000000, 0x40000000, 0x00000000, + 0x0EF, 0x00000200, + 0x030, 0x00000000, + 0x03F, 0x00033303, + 0x030, 0x00001000, + 0x03F, 0x00033303, + 0x030, 0x00002000, + 0x03F, 0x00033303, + 0x030, 0x00003000, + 0x03F, 0x00033303, + 0x030, 0x00004000, + 0x03F, 0x00033303, + 0x030, 0x00005000, + 0x03F, 0x00033303, + 0x030, 0x00006000, + 0x03F, 0x00033303, + 0x030, 0x00007000, + 0x03F, 0x00033303, + 0x030, 0x00008000, + 0x03F, 0x00033303, + 0x030, 0x00009000, + 0x03F, 0x00033303, + 0x030, 0x0000A000, + 0x03F, 0x00033303, + 0x030, 0x0000B000, + 0x03F, 0x00033303, + 0x0EF, 0x00000000, + 0x90001004, 0x00000000, 0x40000000, 0x00000000, + 0x0EF, 0x00000200, + 0x030, 0x00000000, + 0x03F, 0x000333A3, + 0x030, 0x00001000, + 0x03F, 0x000333A3, + 0x030, 0x00002000, + 0x03F, 0x000333A3, + 0x030, 0x00003000, + 0x03F, 0x000333A3, + 0x030, 0x00004000, + 0x03F, 0x000313A3, + 0x030, 0x00005000, + 0x03F, 0x000313A3, + 0x030, 0x00006000, + 0x03F, 0x000313A3, + 0x030, 0x00007000, + 0x03F, 0x000313A3, + 0x030, 0x00008000, + 0x03F, 0x000333A3, + 0x030, 0x00009000, + 0x03F, 0x000333A3, + 0x030, 0x0000A000, + 0x03F, 0x000333A3, + 0x030, 0x0000B000, + 0x03F, 0x000333A3, + 0x0EF, 0x00000000, + 0x90000400, 0x00000000, 0x40000000, 0x00000000, + 0x0EF, 0x00000200, + 0x030, 0x00000000, + 0x03F, 0x000335A3, + 0x030, 0x00001000, + 0x03F, 0x000335A3, + 0x030, 0x00002000, + 0x03F, 0x000335A3, + 0x030, 0x00003000, + 0x03F, 0x000335A3, + 0x030, 0x00004000, + 0x03F, 0x000335A3, + 0x030, 0x00005000, + 0x03F, 0x000335A3, + 0x030, 0x00006000, + 0x03F, 0x000335A3, + 0x030, 0x00007000, + 0x03F, 0x000335A3, + 0x030, 0x00008000, + 0x03F, 0x000335A3, + 0x030, 0x00009000, + 0x03F, 0x000335A3, + 0x030, 0x0000A000, + 0x03F, 0x000335A3, + 0x030, 0x0000B000, + 0x03F, 0x000335A3, + 0x0EF, 0x00000000, + 0xA0000000, 0x00000000, + 0x0EF, 0x00000200, + 0x030, 0x00000000, + 0x03F, 0x000335A3, + 0x030, 0x00001000, + 0x03F, 0x000335A3, + 0x030, 0x00002000, + 0x03F, 0x000335A3, + 0x030, 0x00003000, + 0x03F, 0x000335A3, + 0x030, 0x00004000, + 0x03F, 0x000335A3, + 0x030, 0x00005000, + 0x03F, 0x000335A3, + 0x030, 0x00006000, + 0x03F, 0x000335A3, + 0x030, 0x00007000, + 0x03F, 0x000335A3, + 0x030, 0x00008000, + 0x03F, 0x000335A3, + 0x030, 0x00009000, + 0x03F, 0x000335A3, + 0x030, 0x0000A000, + 0x03F, 0x000335A3, + 0x030, 0x0000B000, + 0x03F, 0x000335A3, + 0x0EF, 0x00000000, + 0xB0000000, 0x00000000, + 0x80001005, 0x00000000, 0x40000000, 0x00000000, + 0x0EF, 0x00000080, + 0x033, 0x00000000, + 0x03F, 0x00033303, + 0x033, 0x00000001, + 0x03F, 0x00033303, + 0x033, 0x00000002, + 0x03F, 0x00033303, + 0x033, 0x00000003, + 0x03F, 0x00033303, + 0x033, 0x00000004, + 0x03F, 0x00033303, + 0x033, 0x00000005, + 0x03F, 0x00033303, + 0x033, 0x00000006, + 0x03F, 0x00033303, + 0x033, 0x00000007, + 0x03F, 0x00033303, + 0x033, 0x00000008, + 0x03F, 0x00033303, + 0x033, 0x00000009, + 0x03F, 0x00033303, + 0x033, 0x0000000A, + 0x03F, 0x00033303, + 0x033, 0x0000000B, + 0x03F, 0x00033303, + 0x033, 0x0000000C, + 0x03F, 0x00033303, + 0x033, 0x0000000D, + 0x03F, 0x00033303, + 0x033, 0x0000000E, + 0x03F, 0x00033303, + 0x033, 0x0000000F, + 0x03F, 0x00033303, + 0x033, 0x00000010, + 0x03F, 0x00033303, + 0x033, 0x00000011, + 0x03F, 0x00033303, + 0x033, 0x00000012, + 0x03F, 0x00033303, + 0x0EF, 0x00000000, + 0x90001004, 0x00000000, 0x40000000, 0x00000000, + 0x0EF, 0x00000080, + 0x033, 0x00000000, + 0x03F, 0x000333A3, + 0x033, 0x00000001, + 0x03F, 0x000333A3, + 0x033, 0x00000002, + 0x03F, 0x000333A3, + 0x033, 0x00000003, + 0x03F, 0x000333A3, + 0x033, 0x00000004, + 0x03F, 0x000333A3, + 0x033, 0x00000005, + 0x03F, 0x000333A3, + 0x033, 0x00000006, + 0x03F, 0x000333A3, + 0x033, 0x00000007, + 0x03F, 0x000333A3, + 0x033, 0x00000008, + 0x03F, 0x000313A3, + 0x033, 0x00000009, + 0x03F, 0x000313A3, + 0x033, 0x0000000A, + 0x03F, 0x000313A3, + 0x033, 0x0000000B, + 0x03F, 0x000313A3, + 0x033, 0x0000000C, + 0x03F, 0x000313A3, + 0x033, 0x0000000D, + 0x03F, 0x000333A3, + 0x033, 0x0000000E, + 0x03F, 0x000333A3, + 0x033, 0x0000000F, + 0x03F, 0x000333A3, + 0x033, 0x00000010, + 0x03F, 0x000333A3, + 0x033, 0x00000011, + 0x03F, 0x000333A3, + 0x033, 0x00000012, + 0x03F, 0x000333A3, + 0x0EF, 0x00000000, + 0x90000400, 0x00000000, 0x40000000, 0x00000000, + 0x0EF, 0x00000080, + 0x033, 0x00000000, + 0x03F, 0x000335A3, + 0x033, 0x00000001, + 0x03F, 0x000335A3, + 0x033, 0x00000002, + 0x03F, 0x000335A3, + 0x033, 0x00000003, + 0x03F, 0x000335A3, + 0x033, 0x00000004, + 0x03F, 0x000335A3, + 0x033, 0x00000005, + 0x03F, 0x000335A3, + 0x033, 0x00000006, + 0x03F, 0x000335A3, + 0x033, 0x00000007, + 0x03F, 0x000335A3, + 0x033, 0x00000008, + 0x03F, 0x000335A3, + 0x033, 0x00000009, + 0x03F, 0x000335A3, + 0x033, 0x0000000A, + 0x03F, 0x000335A3, + 0x033, 0x0000000B, + 0x03F, 0x000335A3, + 0x033, 0x0000000C, + 0x03F, 0x000335A3, + 0x033, 0x0000000D, + 0x03F, 0x000335A3, + 0x033, 0x0000000E, + 0x03F, 0x000335A3, + 0x033, 0x0000000F, + 0x03F, 0x000335A3, + 0x033, 0x00000010, + 0x03F, 0x000335A3, + 0x033, 0x00000011, + 0x03F, 0x000335A3, + 0x033, 0x00000012, + 0x03F, 0x000335A3, + 0x0EF, 0x00000000, + 0xA0000000, 0x00000000, + 0x0EF, 0x00000080, + 0x033, 0x00000000, + 0x03F, 0x000335A3, + 0x033, 0x00000001, + 0x03F, 0x000335A3, + 0x033, 0x00000002, + 0x03F, 0x000335A3, + 0x033, 0x00000003, + 0x03F, 0x000335A3, + 0x033, 0x00000004, + 0x03F, 0x000335A3, + 0x033, 0x00000005, + 0x03F, 0x000335A3, + 0x033, 0x00000006, + 0x03F, 0x000335A3, + 0x033, 0x00000007, + 0x03F, 0x000335A3, + 0x033, 0x00000008, + 0x03F, 0x000335A3, + 0x033, 0x00000009, + 0x03F, 0x000335A3, + 0x033, 0x0000000A, + 0x03F, 0x000335A3, + 0x033, 0x0000000B, + 0x03F, 0x000335A3, + 0x033, 0x0000000C, + 0x03F, 0x000335A3, + 0x033, 0x0000000D, + 0x03F, 0x000335A3, + 0x033, 0x0000000E, + 0x03F, 0x000335A3, + 0x033, 0x0000000F, + 0x03F, 0x000335A3, + 0x033, 0x00000010, + 0x03F, 0x000335A3, + 0x033, 0x00000011, + 0x03F, 0x000335A3, + 0x033, 0x00000012, + 0x03F, 0x000335A3, + 0x0EF, 0x00000000, + 0xB0000000, 0x00000000, + 0x80001005, 0x00000000, 0x40000000, 0x00000000, + 0x0EF, 0x00000040, + 0x030, 0x00000644, + 0x030, 0x00001135, + 0x030, 0x00002133, + 0x030, 0x00004000, + 0x030, 0x00005000, + 0x030, 0x00006000, + 0x0EF, 0x00000000, + 0x90001004, 0x00000000, 0x40000000, 0x00000000, + 0x0EF, 0x00000040, + 0x030, 0x00000644, + 0x030, 0x00001412, + 0x030, 0x00002202, + 0x030, 0x00004000, + 0x030, 0x00005000, + 0x030, 0x00006000, + 0x0EF, 0x00000000, + 0x90000400, 0x00000000, 0x40000000, 0x00000000, + 0x0EF, 0x00000040, + 0x030, 0x00000640, + 0x030, 0x00001512, + 0x030, 0x00002202, + 0x030, 0x00004000, + 0x030, 0x00005000, + 0x030, 0x00006000, + 0x0EF, 0x00000000, + 0xA0000000, 0x00000000, + 0x0EF, 0x00000040, + 0x030, 0x00000640, + 0x030, 0x00001512, + 0x030, 0x00002202, + 0x030, 0x00004000, + 0x030, 0x00005000, + 0x030, 0x00006000, + 0x0EF, 0x00000000, + 0xB0000000, 0x00000000, + 0x80001005, 0x00000000, 0x40000000, 0x00000000, + 0x0EF, 0x00000800, + 0x90001004, 0x00000000, 0x40000000, 0x00000000, + 0x0EF, 0x00000800, + 0x90000400, 0x00000000, 0x40000000, 0x00000000, + 0x0EF, 0x00000800, + 0xA0000000, 0x00000000, + 0x0EF, 0x00000800, + 0xB0000000, 0x00000000, + 0x80001005, 0x00000000, 0x40000000, 0x00000000, + 0x033, 0x00000020, + 0x03F, 0x00000001, + 0x033, 0x00000021, + 0x03F, 0x00000004, + 0x033, 0x00000022, + 0x03F, 0x00000007, + 0x033, 0x00000023, + 0x03F, 0x00000024, + 0x033, 0x00000024, + 0x03F, 0x00000027, + 0x033, 0x00000025, + 0x03F, 0x0000002A, + 0x033, 0x00000026, + 0x03F, 0x0000002D, + 0x033, 0x00000027, + 0x03F, 0x00000030, + 0x033, 0x00000028, + 0x03F, 0x00000033, + 0x033, 0x00000029, + 0x03F, 0x00000036, + 0x033, 0x0000002A, + 0x03F, 0x00000039, + 0x90001004, 0x00000000, 0x40000000, 0x00000000, + 0x033, 0x00000020, + 0x03F, 0x00000E42, + 0x033, 0x00000021, + 0x03F, 0x00000E45, + 0x033, 0x00000022, + 0x03F, 0x00000E65, + 0x033, 0x00000023, + 0x03F, 0x00000E68, + 0x033, 0x00000024, + 0x03F, 0x00000EE4, + 0x033, 0x00000025, + 0x03F, 0x00000EE7, + 0x033, 0x00000026, + 0x03F, 0x00000EEA, + 0x033, 0x00000027, + 0x03F, 0x00000EED, + 0x033, 0x00000028, + 0x03F, 0x00000EF0, + 0x033, 0x00000029, + 0x03F, 0x00000EF3, + 0x033, 0x0000002A, + 0x03F, 0x00000EF6, + 0x90000400, 0x00000000, 0x40000000, 0x00000000, + 0x033, 0x00000020, + 0x03F, 0x00000E42, + 0x033, 0x00000021, + 0x03F, 0x00000E45, + 0x033, 0x00000022, + 0x03F, 0x00000E48, + 0x033, 0x00000023, + 0x03F, 0x00000E68, + 0x033, 0x00000024, + 0x03F, 0x00000E6B, + 0x033, 0x00000025, + 0x03F, 0x00000EAA, + 0x033, 0x00000026, + 0x03F, 0x00000EEA, + 0x033, 0x00000027, + 0x03F, 0x00000EED, + 0x033, 0x00000028, + 0x03F, 0x00000EF0, + 0x033, 0x00000029, + 0x03F, 0x00000EF3, + 0x033, 0x0000002A, + 0x03F, 0x00000EF6, + 0xA0000000, 0x00000000, + 0x033, 0x00000020, + 0x03F, 0x00000E42, + 0x033, 0x00000021, + 0x03F, 0x00000E45, + 0x033, 0x00000022, + 0x03F, 0x00000E65, + 0x033, 0x00000023, + 0x03F, 0x00000E68, + 0x033, 0x00000024, + 0x03F, 0x00000EE4, + 0x033, 0x00000025, + 0x03F, 0x00000EE7, + 0x033, 0x00000026, + 0x03F, 0x00000EEA, + 0x033, 0x00000027, + 0x03F, 0x00000EED, + 0x033, 0x00000028, + 0x03F, 0x00000EF0, + 0x033, 0x00000029, + 0x03F, 0x00000EF3, + 0x033, 0x0000002A, + 0x03F, 0x00000EF6, + 0xB0000000, 0x00000000, + 0x80001005, 0x00000000, 0x40000000, 0x00000000, + 0x033, 0x00000060, + 0x03F, 0x00000001, + 0x033, 0x00000061, + 0x03F, 0x00000004, + 0x033, 0x00000062, + 0x03F, 0x00000007, + 0x033, 0x00000063, + 0x03F, 0x00000024, + 0x033, 0x00000064, + 0x03F, 0x00000027, + 0x033, 0x00000065, + 0x03F, 0x0000002A, + 0x033, 0x00000066, + 0x03F, 0x0000002D, + 0x033, 0x00000067, + 0x03F, 0x00000030, + 0x033, 0x00000068, + 0x03F, 0x00000033, + 0x033, 0x00000069, + 0x03F, 0x00000036, + 0x033, 0x0000006A, + 0x03F, 0x00000039, + 0x90001004, 0x00000000, 0x40000000, 0x00000000, + 0x033, 0x00000060, + 0x03F, 0x00000E42, + 0x033, 0x00000061, + 0x03F, 0x00000E45, + 0x033, 0x00000062, + 0x03F, 0x00000E65, + 0x033, 0x00000063, + 0x03F, 0x00000E68, + 0x033, 0x00000064, + 0x03F, 0x00000EE5, + 0x033, 0x00000065, + 0x03F, 0x00000EE8, + 0x033, 0x00000066, + 0x03F, 0x00000EEB, + 0x033, 0x00000067, + 0x03F, 0x00000EEE, + 0x033, 0x00000068, + 0x03F, 0x00000EF1, + 0x033, 0x00000069, + 0x03F, 0x00000EF4, + 0x033, 0x0000006A, + 0x03F, 0x00000EF7, + 0x90000400, 0x00000000, 0x40000000, 0x00000000, + 0x033, 0x00000060, + 0x03F, 0x00000E09, + 0x033, 0x00000061, + 0x03F, 0x00000E43, + 0x033, 0x00000062, + 0x03F, 0x00000E46, + 0x033, 0x00000063, + 0x03F, 0x00000E49, + 0x033, 0x00000064, + 0x03F, 0x00000E88, + 0x033, 0x00000065, + 0x03F, 0x00000E8B, + 0x033, 0x00000066, + 0x03F, 0x00000ECB, + 0x033, 0x00000067, + 0x03F, 0x00000ECE, + 0x033, 0x00000068, + 0x03F, 0x00000EF0, + 0x033, 0x00000069, + 0x03F, 0x00000EF3, + 0x033, 0x0000006A, + 0x03F, 0x00000EF6, + 0xA0000000, 0x00000000, + 0x033, 0x00000060, + 0x03F, 0x00000E42, + 0x033, 0x00000061, + 0x03F, 0x00000E45, + 0x033, 0x00000062, + 0x03F, 0x00000E65, + 0x033, 0x00000063, + 0x03F, 0x00000E68, + 0x033, 0x00000064, + 0x03F, 0x00000EE5, + 0x033, 0x00000065, + 0x03F, 0x00000EE8, + 0x033, 0x00000066, + 0x03F, 0x00000EEB, + 0x033, 0x00000067, + 0x03F, 0x00000EEE, + 0x033, 0x00000068, + 0x03F, 0x00000EF1, + 0x033, 0x00000069, + 0x03F, 0x00000EF4, + 0x033, 0x0000006A, + 0x03F, 0x00000EF7, + 0xB0000000, 0x00000000, + 0x80001005, 0x00000000, 0x40000000, 0x00000000, + 0x033, 0x000000A0, + 0x03F, 0x00000001, + 0x033, 0x000000A1, + 0x03F, 0x00000004, + 0x033, 0x000000A2, + 0x03F, 0x00000007, + 0x033, 0x000000A3, + 0x03F, 0x00000025, + 0x033, 0x000000A4, + 0x03F, 0x00000028, + 0x033, 0x000000A5, + 0x03F, 0x0000002B, + 0x033, 0x000000A6, + 0x03F, 0x0000002E, + 0x033, 0x000000A7, + 0x03F, 0x00000031, + 0x033, 0x000000A8, + 0x03F, 0x00000034, + 0x033, 0x000000A9, + 0x03F, 0x00000037, + 0x033, 0x000000AA, + 0x03F, 0x0000003A, + 0x0EF, 0x00000000, + 0x90001004, 0x00000000, 0x40000000, 0x00000000, + 0x033, 0x000000A0, + 0x03F, 0x00000E09, + 0x033, 0x000000A1, + 0x03F, 0x00000E43, + 0x033, 0x000000A2, + 0x03F, 0x00000E64, + 0x033, 0x000000A3, + 0x03F, 0x00000E67, + 0x033, 0x000000A4, + 0x03F, 0x00000EE4, + 0x033, 0x000000A5, + 0x03F, 0x00000EE7, + 0x033, 0x000000A6, + 0x03F, 0x00000EEA, + 0x033, 0x000000A7, + 0x03F, 0x00000EED, + 0x033, 0x000000A8, + 0x03F, 0x00000EF0, + 0x033, 0x000000A9, + 0x03F, 0x00000EF3, + 0x033, 0x000000AA, + 0x03F, 0x00000EF6, + 0x0EF, 0x00000000, + 0x90000400, 0x00000000, 0x40000000, 0x00000000, + 0x033, 0x000000A0, + 0x03F, 0x00000E08, + 0x033, 0x000000A1, + 0x03F, 0x00000E42, + 0x033, 0x000000A2, + 0x03F, 0x00000E45, + 0x033, 0x000000A3, + 0x03F, 0x00000E48, + 0x033, 0x000000A4, + 0x03F, 0x00000EA5, + 0x033, 0x000000A5, + 0x03F, 0x00000EA8, + 0x033, 0x000000A6, + 0x03F, 0x00000ECA, + 0x033, 0x000000A7, + 0x03F, 0x00000ECD, + 0x033, 0x000000A8, + 0x03F, 0x00000EEF, + 0x033, 0x000000A9, + 0x03F, 0x00000EF2, + 0x033, 0x000000AA, + 0x03F, 0x00000EF5, + 0x0EF, 0x00000000, + 0xA0000000, 0x00000000, + 0x033, 0x000000A0, + 0x03F, 0x00000E09, + 0x033, 0x000000A1, + 0x03F, 0x00000E43, + 0x033, 0x000000A2, + 0x03F, 0x00000E64, + 0x033, 0x000000A3, + 0x03F, 0x00000E67, + 0x033, 0x000000A4, + 0x03F, 0x00000EE4, + 0x033, 0x000000A5, + 0x03F, 0x00000EE7, + 0x033, 0x000000A6, + 0x03F, 0x00000EEA, + 0x033, 0x000000A7, + 0x03F, 0x00000EED, + 0x033, 0x000000A8, + 0x03F, 0x00000EF0, + 0x033, 0x000000A9, + 0x03F, 0x00000EF3, + 0x033, 0x000000AA, + 0x03F, 0x00000EF6, + 0x0EF, 0x00000000, + 0xB0000000, 0x00000000, + 0x80001005, 0x00000000, 0x40000000, 0x00000000, + 0x0EF, 0x00000400, + 0x033, 0x00000000, + 0x03F, 0x0006AC00, + 0x033, 0x00000001, + 0x03F, 0x00060C00, + 0x033, 0x00000002, + 0x03F, 0x0006AC00, + 0x033, 0x00000003, + 0x03F, 0x00086A00, + 0x0EF, 0x00000000, + 0x90001004, 0x00000000, 0x40000000, 0x00000000, + 0x0EF, 0x00000400, + 0x033, 0x00000000, + 0x03F, 0x0006AC00, + 0x033, 0x00000001, + 0x03F, 0x00060C00, + 0x033, 0x00000002, + 0x03F, 0x0006AC00, + 0x033, 0x00000003, + 0x03F, 0x00086A00, + 0x0EF, 0x00000000, + 0x90000400, 0x00000000, 0x40000000, 0x00000000, + 0x0EF, 0x00000400, + 0x033, 0x00000000, + 0x03F, 0x0006AC00, + 0x033, 0x00000001, + 0x03F, 0x00060C00, + 0x033, 0x00000002, + 0x03F, 0x0006AC00, + 0x033, 0x00000003, + 0x03F, 0x00086A00, + 0x0EF, 0x00000000, + 0xA0000000, 0x00000000, + 0x0EF, 0x00000400, + 0x033, 0x00000000, + 0x03F, 0x0006AC00, + 0x033, 0x00000001, + 0x03F, 0x00060C00, + 0x033, 0x00000002, + 0x03F, 0x0006AC00, + 0x033, 0x00000003, + 0x03F, 0x00086A00, + 0x0EF, 0x00000000, + 0xB0000000, 0x00000000, + 0x80001005, 0x00000000, 0x40000000, 0x00000000, + 0x0EF, 0x00000100, + 0x033, 0x00000000, + 0x03F, 0x00000040, + 0x033, 0x00000001, + 0x03F, 0x00000040, + 0x033, 0x00000002, + 0x03F, 0x00000040, + 0x033, 0x00000003, + 0x03F, 0x00000040, + 0x0EF, 0x00000000, + 0x90001004, 0x00000000, 0x40000000, 0x00000000, + 0x0EF, 0x00000100, + 0x033, 0x00000000, + 0x03F, 0x00000040, + 0x033, 0x00000001, + 0x03F, 0x00000040, + 0x033, 0x00000002, + 0x03F, 0x00000040, + 0x033, 0x00000003, + 0x03F, 0x00000040, + 0x0EF, 0x00000000, + 0x90000400, 0x00000000, 0x40000000, 0x00000000, + 0x0EF, 0x00000100, + 0x033, 0x00000000, + 0x03F, 0x00000040, + 0x033, 0x00000001, + 0x03F, 0x00000040, + 0x033, 0x00000002, + 0x03F, 0x00000040, + 0x033, 0x00000003, + 0x03F, 0x00000040, + 0x0EF, 0x00000000, + 0xA0000000, 0x00000000, + 0x0EF, 0x00000100, + 0x033, 0x00000000, + 0x03F, 0x00000040, + 0x033, 0x00000001, + 0x03F, 0x00000040, + 0x033, 0x00000002, + 0x03F, 0x00000040, + 0x033, 0x00000003, + 0x03F, 0x00000040, + 0x0EF, 0x00000000, + 0xB0000000, 0x00000000, + 0x80001005, 0x00000000, 0x40000000, 0x00000000, + 0x0EF, 0x00040000, + 0x033, 0x00000000, + 0x03F, 0x00086A40, + 0x033, 0x00000001, + 0x03F, 0x00086A40, + 0x033, 0x00000002, + 0x03F, 0x00086A40, + 0x033, 0x00000003, + 0x03F, 0x00086A40, + 0x033, 0x00000004, + 0x03F, 0x00086A40, + 0x033, 0x00000005, + 0x03F, 0x00086A40, + 0x033, 0x00000006, + 0x03F, 0x00084A40, + 0x033, 0x00000007, + 0x03F, 0x00084A40, + 0x0EF, 0x00000000, + 0x90001004, 0x00000000, 0x40000000, 0x00000000, + 0x0EF, 0x00040000, + 0x033, 0x00000000, + 0x03F, 0x00086A40, + 0x033, 0x00000001, + 0x03F, 0x00086A40, + 0x033, 0x00000002, + 0x03F, 0x00086A40, + 0x033, 0x00000003, + 0x03F, 0x00086A40, + 0x033, 0x00000004, + 0x03F, 0x00086A40, + 0x033, 0x00000005, + 0x03F, 0x00086A40, + 0x033, 0x00000006, + 0x03F, 0x00084A40, + 0x033, 0x00000007, + 0x03F, 0x00084A40, + 0x0EF, 0x00000000, + 0x90000400, 0x00000000, 0x40000000, 0x00000000, + 0x0EF, 0x00040000, + 0x033, 0x00000000, + 0x03F, 0x00086A40, + 0x033, 0x00000001, + 0x03F, 0x00086A40, + 0x033, 0x00000002, + 0x03F, 0x00086A40, + 0x033, 0x00000003, + 0x03F, 0x00086A40, + 0x033, 0x00000004, + 0x03F, 0x00086A40, + 0x033, 0x00000005, + 0x03F, 0x00086A40, + 0x033, 0x00000006, + 0x03F, 0x00084A40, + 0x033, 0x00000007, + 0x03F, 0x00084A40, + 0x0EF, 0x00000000, + 0xA0000000, 0x00000000, + 0x0EF, 0x00040000, + 0x033, 0x00000000, + 0x03F, 0x00086A40, + 0x033, 0x00000001, + 0x03F, 0x00086A40, + 0x033, 0x00000002, + 0x03F, 0x00086A40, + 0x033, 0x00000003, + 0x03F, 0x00086A40, + 0x033, 0x00000004, + 0x03F, 0x00086A40, + 0x033, 0x00000005, + 0x03F, 0x00086A40, + 0x033, 0x00000006, + 0x03F, 0x00084A40, + 0x033, 0x00000007, + 0x03F, 0x00084A40, + 0x0EF, 0x00000000, + 0xB0000000, 0x00000000, + 0x80001005, 0x00000000, 0x40000000, 0x00000000, + 0x051, 0x000801A8, + 0x052, 0x000972E3, + 0x053, 0x00008069, + 0x054, 0x00030032, + 0x055, 0x00082003, + 0x056, 0x00051CCB, + 0x057, 0x0000CFC2, + 0x058, 0x00000010, + 0x059, 0x00030000, + 0x90001004, 0x00000000, 0x40000000, 0x00000000, + 0x051, 0x000801A8, + 0x052, 0x000972E3, + 0x053, 0x00008069, + 0x054, 0x00030032, + 0x055, 0x00082003, + 0x056, 0x00051CCB, + 0x057, 0x0000CFC2, + 0x058, 0x00000010, + 0x059, 0x00030000, + 0x90000400, 0x00000000, 0x40000000, 0x00000000, + 0x051, 0x000801A8, + 0x052, 0x000972E3, + 0x053, 0x00008069, + 0x054, 0x00030032, + 0x055, 0x00082003, + 0x056, 0x00051CCB, + 0x057, 0x0000CFC2, + 0x058, 0x00000010, + 0x059, 0x00030000, + 0xA0000000, 0x00000000, + 0x051, 0x000801A8, + 0x052, 0x000972E3, + 0x053, 0x00008069, + 0x054, 0x00030032, + 0x055, 0x00082003, + 0x056, 0x00051CCB, + 0x057, 0x0000CFC2, + 0x058, 0x00000010, + 0x059, 0x00030000, + 0xB0000000, 0x00000000, + 0x80001005, 0x00000000, 0x40000000, 0x00000000, + 0x0EF, 0x00000800, + 0x033, 0x00000000, + 0x03F, 0x00051429, + 0x033, 0x00000001, + 0x03F, 0x00051449, + 0x033, 0x00000002, + 0x03F, 0x0005144C, + 0x033, 0x00000003, + 0x03F, 0x00051C66, + 0x033, 0x00000004, + 0x03F, 0x00051C69, + 0x033, 0x00000005, + 0x03F, 0x00051C6C, + 0x033, 0x00000006, + 0x03F, 0x00051CE8, + 0x033, 0x00000007, + 0x03F, 0x00051CEB, + 0x033, 0x00000008, + 0x03F, 0x00051CEE, + 0x033, 0x00000009, + 0x03F, 0x00051CF1, + 0x033, 0x0000000A, + 0x03F, 0x00051CF4, + 0x0EF, 0x00000000, + 0x90001004, 0x00000000, 0x40000000, 0x00000000, + 0x0EF, 0x00000800, + 0x033, 0x00000000, + 0x03F, 0x00051429, + 0x033, 0x00000001, + 0x03F, 0x00051449, + 0x033, 0x00000002, + 0x03F, 0x0005144C, + 0x033, 0x00000003, + 0x03F, 0x00051C66, + 0x033, 0x00000004, + 0x03F, 0x00051C69, + 0x033, 0x00000005, + 0x03F, 0x00051C6C, + 0x033, 0x00000006, + 0x03F, 0x00051CE8, + 0x033, 0x00000007, + 0x03F, 0x00051CEB, + 0x033, 0x00000008, + 0x03F, 0x00051CEE, + 0x033, 0x00000009, + 0x03F, 0x00051CF1, + 0x033, 0x0000000A, + 0x03F, 0x00051CF4, + 0x0EF, 0x00000000, + 0x90000400, 0x00000000, 0x40000000, 0x00000000, + 0x0EF, 0x00000800, + 0x033, 0x00000000, + 0x03F, 0x00051427, + 0x033, 0x00000001, + 0x03F, 0x00051446, + 0x033, 0x00000002, + 0x03F, 0x00051449, + 0x033, 0x00000003, + 0x03F, 0x0005144C, + 0x033, 0x00000004, + 0x03F, 0x00051C67, + 0x033, 0x00000005, + 0x03F, 0x00051C6A, + 0x033, 0x00000006, + 0x03F, 0x00051C8B, + 0x033, 0x00000007, + 0x03F, 0x00051CE9, + 0x033, 0x00000008, + 0x03F, 0x00051CEC, + 0x033, 0x00000009, + 0x03F, 0x00051CEF, + 0x033, 0x0000000A, + 0x03F, 0x00051CF2, + 0x0EF, 0x00000000, + 0xA0000000, 0x00000000, + 0x0EF, 0x00000800, + 0x033, 0x00000000, + 0x03F, 0x00051427, + 0x033, 0x00000001, + 0x03F, 0x00051446, + 0x033, 0x00000002, + 0x03F, 0x00051449, + 0x033, 0x00000003, + 0x03F, 0x0005144C, + 0x033, 0x00000004, + 0x03F, 0x00051C67, + 0x033, 0x00000005, + 0x03F, 0x00051C6A, + 0x033, 0x00000006, + 0x03F, 0x00051C8B, + 0x033, 0x00000007, + 0x03F, 0x00051CE9, + 0x033, 0x00000008, + 0x03F, 0x00051CEC, + 0x033, 0x00000009, + 0x03F, 0x00051CEF, + 0x033, 0x0000000A, + 0x03F, 0x00051CF2, + 0x0EF, 0x00000000, + 0xB0000000, 0x00000000, + 0x80001005, 0x00000000, 0x40000000, 0x00000000, + 0x0EE, 0x00004000, + 0x033, 0x00000000, + 0x03F, 0x00048400, + 0x033, 0x00000001, + 0x03F, 0x00086E00, + 0x033, 0x00000002, + 0x03F, 0x00048400, + 0x033, 0x00000003, + 0x03F, 0x00048400, + 0x0EE, 0x00000000, + 0x90001004, 0x00000000, 0x40000000, 0x00000000, + 0x0EE, 0x00004000, + 0x033, 0x00000000, + 0x03F, 0x00048400, + 0x033, 0x00000001, + 0x03F, 0x00086E00, + 0x033, 0x00000002, + 0x03F, 0x00048400, + 0x033, 0x00000003, + 0x03F, 0x00048400, + 0x0EE, 0x00000000, + 0x90000400, 0x00000000, 0x40000000, 0x00000000, + 0x0EE, 0x00004000, + 0x033, 0x00000000, + 0x03F, 0x00048400, + 0x033, 0x00000001, + 0x03F, 0x00086E00, + 0x033, 0x00000002, + 0x03F, 0x00048400, + 0x033, 0x00000003, + 0x03F, 0x00048400, + 0x0EE, 0x00000000, + 0xA0000000, 0x00000000, + 0x0EE, 0x00004000, + 0x033, 0x00000000, + 0x03F, 0x00048400, + 0x033, 0x00000001, + 0x03F, 0x00086E00, + 0x033, 0x00000002, + 0x03F, 0x00048400, + 0x033, 0x00000003, + 0x03F, 0x00048400, + 0x0EE, 0x00000000, + 0xB0000000, 0x00000000, + 0x80001005, 0x00000000, 0x40000000, 0x00000000, + 0x0EE, 0x00002000, + 0x033, 0x00000000, + 0x03F, 0x00000000, + 0x033, 0x00000001, + 0x03F, 0x00000000, + 0x033, 0x00000002, + 0x03F, 0x00000000, + 0x033, 0x00000003, + 0x03F, 0x00000000, + 0x0EE, 0x00000000, + 0x90001004, 0x00000000, 0x40000000, 0x00000000, + 0x0EE, 0x00002000, + 0x033, 0x00000000, + 0x03F, 0x00000000, + 0x033, 0x00000001, + 0x03F, 0x00000000, + 0x033, 0x00000002, + 0x03F, 0x00000000, + 0x033, 0x00000003, + 0x03F, 0x00000000, + 0x0EE, 0x00000000, + 0x90000400, 0x00000000, 0x40000000, 0x00000000, + 0x0EE, 0x00002000, + 0x033, 0x00000000, + 0x03F, 0x00000000, + 0x033, 0x00000001, + 0x03F, 0x00000000, + 0x033, 0x00000002, + 0x03F, 0x00000000, + 0x033, 0x00000003, + 0x03F, 0x00000000, + 0x0EE, 0x00000000, + 0xA0000000, 0x00000000, + 0x0EE, 0x00002000, + 0x033, 0x00000000, + 0x03F, 0x00000000, + 0x033, 0x00000001, + 0x03F, 0x00000000, + 0x033, 0x00000002, + 0x03F, 0x00000000, + 0x033, 0x00000003, + 0x03F, 0x00000000, + 0x0EE, 0x00000000, + 0xB0000000, 0x00000000, + 0x80001005, 0x00000000, 0x40000000, 0x00000000, + 0x0EE, 0x00080000, + 0x033, 0x00000000, + 0x03F, 0x00048400, + 0x033, 0x00000001, + 0x03F, 0x00048400, + 0x033, 0x00000002, + 0x03F, 0x00048400, + 0x033, 0x00000003, + 0x03F, 0x00048400, + 0x033, 0x00000004, + 0x03F, 0x00048400, + 0x033, 0x00000005, + 0x03F, 0x00048400, + 0x033, 0x00000006, + 0x03F, 0x00048400, + 0x033, 0x00000007, + 0x03F, 0x00048400, + 0x0EE, 0x00000000, + 0x90001004, 0x00000000, 0x40000000, 0x00000000, + 0x0EE, 0x00080000, + 0x033, 0x00000000, + 0x03F, 0x00048400, + 0x033, 0x00000001, + 0x03F, 0x00048400, + 0x033, 0x00000002, + 0x03F, 0x00048400, + 0x033, 0x00000003, + 0x03F, 0x00048400, + 0x033, 0x00000004, + 0x03F, 0x00048400, + 0x033, 0x00000005, + 0x03F, 0x00048400, + 0x033, 0x00000006, + 0x03F, 0x00048400, + 0x033, 0x00000007, + 0x03F, 0x00048400, + 0x0EE, 0x00000000, + 0x90000400, 0x00000000, 0x40000000, 0x00000000, + 0x0EE, 0x00080000, + 0x033, 0x00000000, + 0x03F, 0x00048400, + 0x033, 0x00000001, + 0x03F, 0x00048400, + 0x033, 0x00000002, + 0x03F, 0x00048400, + 0x033, 0x00000003, + 0x03F, 0x00048400, + 0x033, 0x00000004, + 0x03F, 0x00048400, + 0x033, 0x00000005, + 0x03F, 0x00048400, + 0x033, 0x00000006, + 0x03F, 0x00048400, + 0x033, 0x00000007, + 0x03F, 0x00048400, + 0x0EE, 0x00000000, + 0xA0000000, 0x00000000, + 0x0EE, 0x00080000, + 0x033, 0x00000000, + 0x03F, 0x00048400, + 0x033, 0x00000001, + 0x03F, 0x00048400, + 0x033, 0x00000002, + 0x03F, 0x00048400, + 0x033, 0x00000003, + 0x03F, 0x00048400, + 0x033, 0x00000004, + 0x03F, 0x00048400, + 0x033, 0x00000005, + 0x03F, 0x00048400, + 0x033, 0x00000006, + 0x03F, 0x00048400, + 0x033, 0x00000007, + 0x03F, 0x00048400, + 0x0EE, 0x00000000, + 0xB0000000, 0x00000000, + 0x80001005, 0x00000000, 0x40000000, 0x00000000, + 0x070, 0x00008000, + 0x075, 0x000027DA, + 0x076, 0x00006997, + 0x077, 0x00070418, + 0x078, 0x000BB000, + 0x07D, 0x00007600, + 0x07F, 0x00000000, + 0x06A, 0x000F4C00, + 0x065, 0x00082030, + 0x90001004, 0x00000000, 0x40000000, 0x00000000, + 0x070, 0x00008000, + 0x075, 0x000027DA, + 0x076, 0x00006997, + 0x077, 0x00070418, + 0x078, 0x000BB000, + 0x07D, 0x00007600, + 0x07F, 0x00000000, + 0x06A, 0x000F4C00, + 0x065, 0x00082030, + 0x90000400, 0x00000000, 0x40000000, 0x00000000, + 0x070, 0x00008000, + 0x075, 0x000027DA, + 0x076, 0x00006997, + 0x077, 0x00070418, + 0x078, 0x000BB000, + 0x07D, 0x00007600, + 0x07F, 0x00000000, + 0x06A, 0x000F4C00, + 0x065, 0x00082030, + 0xA0000000, 0x00000000, + 0x070, 0x00008000, + 0x075, 0x000027DA, + 0x076, 0x00006997, + 0x077, 0x00070418, + 0x078, 0x000BB000, + 0x07D, 0x00007600, + 0x07F, 0x00000000, + 0x06A, 0x000F4C00, + 0x065, 0x00082030, + 0xB0000000, 0x00000000, + 0x80001005, 0x00000000, 0x40000000, 0x00000000, + 0x0EE, 0x00008000, + 0x033, 0x00000000, + 0x03F, 0x00051427, + 0x033, 0x00000001, + 0x03F, 0x00051446, + 0x033, 0x00000002, + 0x03F, 0x00051449, + 0x033, 0x00000003, + 0x03F, 0x0005144C, + 0x033, 0x00000004, + 0x03F, 0x00051C69, + 0x033, 0x00000005, + 0x03F, 0x00051C6C, + 0x033, 0x00000006, + 0x03F, 0x00051C8D, + 0x033, 0x00000007, + 0x03F, 0x00051CEB, + 0x033, 0x00000008, + 0x03F, 0x00051CEE, + 0x033, 0x00000009, + 0x03F, 0x00051CF1, + 0x033, 0x0000000A, + 0x03F, 0x00051CF4, + 0x0EE, 0x00000000, + 0x90001004, 0x00000000, 0x40000000, 0x00000000, + 0x0EE, 0x00008000, + 0x033, 0x00000000, + 0x03F, 0x00051427, + 0x033, 0x00000001, + 0x03F, 0x00051446, + 0x033, 0x00000002, + 0x03F, 0x00051449, + 0x033, 0x00000003, + 0x03F, 0x0005144C, + 0x033, 0x00000004, + 0x03F, 0x00051C69, + 0x033, 0x00000005, + 0x03F, 0x00051C6C, + 0x033, 0x00000006, + 0x03F, 0x00051C8D, + 0x033, 0x00000007, + 0x03F, 0x00051CEB, + 0x033, 0x00000008, + 0x03F, 0x00051CEE, + 0x033, 0x00000009, + 0x03F, 0x00051CF1, + 0x033, 0x0000000A, + 0x03F, 0x00051CF4, + 0x0EE, 0x00000000, + 0x90000400, 0x00000000, 0x40000000, 0x00000000, + 0x0EE, 0x00008000, + 0x033, 0x00000000, + 0x03F, 0x00051427, + 0x033, 0x00000001, + 0x03F, 0x00051446, + 0x033, 0x00000002, + 0x03F, 0x00051449, + 0x033, 0x00000003, + 0x03F, 0x0005144C, + 0x033, 0x00000004, + 0x03F, 0x00051C69, + 0x033, 0x00000005, + 0x03F, 0x00051C6C, + 0x033, 0x00000006, + 0x03F, 0x00051C8D, + 0x033, 0x00000007, + 0x03F, 0x00051CEB, + 0x033, 0x00000008, + 0x03F, 0x00051CEE, + 0x033, 0x00000009, + 0x03F, 0x00051CF1, + 0x033, 0x0000000A, + 0x03F, 0x00051CF4, + 0x0EE, 0x00000000, + 0xA0000000, 0x00000000, + 0x0EE, 0x00008000, + 0x033, 0x00000000, + 0x03F, 0x00051427, + 0x033, 0x00000001, + 0x03F, 0x00051446, + 0x033, 0x00000002, + 0x03F, 0x00051449, + 0x033, 0x00000003, + 0x03F, 0x0005144C, + 0x033, 0x00000004, + 0x03F, 0x00051C69, + 0x033, 0x00000005, + 0x03F, 0x00051C6C, + 0x033, 0x00000006, + 0x03F, 0x00051C8D, + 0x033, 0x00000007, + 0x03F, 0x00051CEB, + 0x033, 0x00000008, + 0x03F, 0x00051CEE, + 0x033, 0x00000009, + 0x03F, 0x00051CF1, + 0x033, 0x0000000A, + 0x03F, 0x00051CF4, + 0x0EE, 0x00000000, + 0xB0000000, 0x00000000, + 0x80001005, 0x00000000, 0x40000000, 0x00000000, + 0x0EF, 0x00000010, + 0x033, 0x00000000, + 0x008, 0x0009C060, + 0x033, 0x00000001, + 0x008, 0x0009C060, + 0x0EF, 0x00000000, + 0x90001004, 0x00000000, 0x40000000, 0x00000000, + 0x0EF, 0x00000010, + 0x033, 0x00000000, + 0x008, 0x0009C060, + 0x033, 0x00000001, + 0x008, 0x0009C060, + 0x0EF, 0x00000000, + 0x90000400, 0x00000000, 0x40000000, 0x00000000, + 0x0EF, 0x00000010, + 0x033, 0x00000000, + 0x008, 0x0009C060, + 0x033, 0x00000001, + 0x008, 0x0009C060, + 0x0EF, 0x00000000, + 0xA0000000, 0x00000000, + 0x0EF, 0x00000010, + 0x033, 0x00000000, + 0x008, 0x0009C060, + 0x033, 0x00000001, + 0x008, 0x0009C060, + 0x0EF, 0x00000000, + 0xB0000000, 0x00000000, + 0x80001005, 0x00000000, 0x40000000, 0x00000000, + 0x0EF, 0x00080000, + 0x033, 0x00000024, + 0x03E, 0x0000003F, + 0x03F, 0x00060FDE, + 0x0EF, 0x00000000, + 0x90001004, 0x00000000, 0x40000000, 0x00000000, + 0x0EF, 0x00080000, + 0x033, 0x00000024, + 0x03E, 0x0000003F, + 0x03F, 0x00060FDE, + 0x0EF, 0x00000000, + 0x90000400, 0x00000000, 0x40000000, 0x00000000, + 0x0EF, 0x00080000, + 0x033, 0x00000024, + 0x03E, 0x0000003F, + 0x03F, 0x00060FDE, + 0x0EF, 0x00000000, + 0xA0000000, 0x00000000, + 0x0EF, 0x00080000, + 0x033, 0x00000024, + 0x03E, 0x0000003F, + 0x03F, 0x00060FDE, + 0x0EF, 0x00000000, + 0xB0000000, 0x00000000, + 0x80001005, 0x00000000, 0x40000000, 0x00000000, + 0x0EF, 0x00080000, + 0x033, 0x00000025, + 0x03E, 0x00000037, + 0x03F, 0x0007EFCE, + 0x0EF, 0x00000000, + 0x90001004, 0x00000000, 0x40000000, 0x00000000, + 0x0EF, 0x00080000, + 0x033, 0x00000025, + 0x03E, 0x00000037, + 0x03F, 0x0007EFCE, + 0x0EF, 0x00000000, + 0x90000400, 0x00000000, 0x40000000, 0x00000000, + 0x0EF, 0x00080000, + 0x033, 0x00000025, + 0x03E, 0x00000037, + 0x03F, 0x0007EFCE, + 0x0EF, 0x00000000, + 0xA0000000, 0x00000000, + 0x0EF, 0x00080000, + 0x033, 0x00000025, + 0x03E, 0x00000037, + 0x03F, 0x0007EFCE, + 0x0EF, 0x00000000, + 0xB0000000, 0x00000000, + 0x80001005, 0x00000000, 0x40000000, 0x00000000, + 0x0EF, 0x00080000, + 0x033, 0x00000026, + 0x03E, 0x00000037, + 0x03F, 0x0005EFCE, + 0x0EF, 0x00000000, + 0x90001004, 0x00000000, 0x40000000, 0x00000000, + 0x0EF, 0x00080000, + 0x033, 0x00000026, + 0x03E, 0x00000037, + 0x03F, 0x0005EFCE, + 0x0EF, 0x00000000, + 0x90000400, 0x00000000, 0x40000000, 0x00000000, + 0x0EF, 0x00080000, + 0x033, 0x00000026, + 0x03E, 0x00000037, + 0x03F, 0x0005EFCE, + 0x0EF, 0x00000000, + 0xA0000000, 0x00000000, + 0x0EF, 0x00080000, + 0x033, 0x00000026, + 0x03E, 0x00000037, + 0x03F, 0x0005EFCE, + 0x0EF, 0x00000000, + 0xB0000000, 0x00000000, + 0x80001005, 0x00000000, 0x40000000, 0x00000000, + 0x0EE, 0x00001000, + 0x033, 0x00000004, + 0x03F, 0x00001EC1, + 0x0EE, 0x00000000, + 0x90001004, 0x00000000, 0x40000000, 0x00000000, + 0x0EE, 0x00001000, + 0x033, 0x00000004, + 0x03F, 0x00001EC1, + 0x0EE, 0x00000000, + 0x90000400, 0x00000000, 0x40000000, 0x00000000, + 0x0EE, 0x00001000, + 0x033, 0x00000004, + 0x03F, 0x00001EC1, + 0x0EE, 0x00000000, + 0xA0000000, 0x00000000, + 0x0EE, 0x00001000, + 0x033, 0x00000004, + 0x03F, 0x00001EC1, + 0x0EE, 0x00000000, + 0xB0000000, 0x00000000, + 0x80001005, 0x00000000, 0x40000000, 0x00000000, + 0x0EE, 0x00001000, + 0x033, 0x00000005, + 0x03F, 0x00001ECF, + 0x0EE, 0x00000000, + 0x90001004, 0x00000000, 0x40000000, 0x00000000, + 0x0EE, 0x00001000, + 0x033, 0x00000005, + 0x03F, 0x00001ECF, + 0x0EE, 0x00000000, + 0x90000400, 0x00000000, 0x40000000, 0x00000000, + 0x0EE, 0x00001000, + 0x033, 0x00000005, + 0x03F, 0x00001ECF, + 0x0EE, 0x00000000, + 0xA0000000, 0x00000000, + 0x0EE, 0x00001000, + 0x033, 0x00000005, + 0x03F, 0x00001ECF, + 0x0EE, 0x00000000, + 0xB0000000, 0x00000000, + 0x80001005, 0x00000000, 0x40000000, 0x00000000, + 0x0EE, 0x00001000, + 0x033, 0x00000006, + 0x03F, 0x00001F9D, + 0x0EE, 0x00000000, + 0x90001004, 0x00000000, 0x40000000, 0x00000000, + 0x0EE, 0x00001000, + 0x033, 0x00000006, + 0x03F, 0x00001F9D, + 0x0EE, 0x00000000, + 0x90000400, 0x00000000, 0x40000000, 0x00000000, + 0x0EE, 0x00001000, + 0x033, 0x00000006, + 0x03F, 0x00001F9D, + 0x0EE, 0x00000000, + 0xA0000000, 0x00000000, + 0x0EE, 0x00001000, + 0x033, 0x00000006, + 0x03F, 0x00001F9D, + 0x0EE, 0x00000000, + 0xB0000000, 0x00000000, + +}; + +RTW_DECL_TABLE_RF_RADIO(rtw8821c_rf_a, A); + +static const struct rtw_txpwr_lmt_cfg_pair rtw8821c_txpwr_lmt_type0[] = { + { 0, 0, 0, 0, 1, 30, }, + { 2, 0, 0, 0, 1, 30, }, + { 0, 0, 0, 0, 2, 32, }, + { 2, 0, 0, 0, 2, 30, }, + { 0, 0, 0, 0, 3, 32, }, + { 2, 0, 0, 0, 3, 30, }, + { 0, 0, 0, 0, 4, 32, }, + { 2, 0, 0, 0, 4, 30, }, + { 0, 0, 0, 0, 5, 32, }, + { 2, 0, 0, 0, 5, 30, }, + { 0, 0, 0, 0, 6, 32, }, + { 2, 0, 0, 0, 6, 30, }, + { 0, 0, 0, 0, 7, 32, }, + { 2, 0, 0, 0, 7, 30, }, + { 0, 0, 0, 0, 8, 32, }, + { 2, 0, 0, 0, 8, 30, }, + { 0, 0, 0, 0, 9, 32, }, + { 2, 0, 0, 0, 9, 30, }, + { 0, 0, 0, 0, 10, 32, }, + { 2, 0, 0, 0, 10, 30, }, + { 0, 0, 0, 0, 11, 32, }, + { 2, 0, 0, 0, 11, 30, }, + { 0, 0, 0, 0, 12, 24, }, + { 2, 0, 0, 0, 12, 30, }, + { 0, 0, 0, 0, 13, 16, }, + { 2, 0, 0, 0, 13, 30, }, + { 0, 0, 0, 0, 14, 63, }, + { 2, 0, 0, 0, 14, 63, }, + { 0, 0, 0, 1, 1, 30, }, + { 2, 0, 0, 1, 1, 30, }, + { 0, 0, 0, 1, 2, 32, }, + { 2, 0, 0, 1, 2, 30, }, + { 0, 0, 0, 1, 3, 34, }, + { 2, 0, 0, 1, 3, 30, }, + { 0, 0, 0, 1, 4, 34, }, + { 2, 0, 0, 1, 4, 30, }, + { 0, 0, 0, 1, 5, 34, }, + { 2, 0, 0, 1, 5, 30, }, + { 0, 0, 0, 1, 6, 34, }, + { 2, 0, 0, 1, 6, 30, }, + { 0, 0, 0, 1, 7, 34, }, + { 2, 0, 0, 1, 7, 30, }, + { 0, 0, 0, 1, 8, 34, }, + { 2, 0, 0, 1, 8, 30, }, + { 0, 0, 0, 1, 9, 34, }, + { 2, 0, 0, 1, 9, 30, }, + { 0, 0, 0, 1, 10, 32, }, + { 2, 0, 0, 1, 10, 30, }, + { 0, 0, 0, 1, 11, 30, }, + { 2, 0, 0, 1, 11, 30, }, + { 0, 0, 0, 1, 12, 28, }, + { 2, 0, 0, 1, 12, 30, }, + { 0, 0, 0, 1, 13, 16, }, + { 2, 0, 0, 1, 13, 30, }, + { 0, 0, 0, 1, 14, 63, }, + { 2, 0, 0, 1, 14, 63, }, + { 0, 0, 0, 2, 1, 26, }, + { 2, 0, 0, 2, 1, 30, }, + { 0, 0, 0, 2, 2, 30, }, + { 2, 0, 0, 2, 2, 30, }, + { 0, 0, 0, 2, 3, 32, }, + { 2, 0, 0, 2, 3, 30, }, + { 0, 0, 0, 2, 4, 34, }, + { 2, 0, 0, 2, 4, 30, }, + { 0, 0, 0, 2, 5, 34, }, + { 2, 0, 0, 2, 5, 30, }, + { 0, 0, 0, 2, 6, 34, }, + { 2, 0, 0, 2, 6, 30, }, + { 0, 0, 0, 2, 7, 34, }, + { 2, 0, 0, 2, 7, 30, }, + { 0, 0, 0, 2, 8, 34, }, + { 2, 0, 0, 2, 8, 30, }, + { 0, 0, 0, 2, 9, 32, }, + { 2, 0, 0, 2, 9, 30, }, + { 0, 0, 0, 2, 10, 30, }, + { 2, 0, 0, 2, 10, 30, }, + { 0, 0, 0, 2, 11, 28, }, + { 2, 0, 0, 2, 11, 30, }, + { 0, 0, 0, 2, 12, 26, }, + { 2, 0, 0, 2, 12, 30, }, + { 0, 0, 0, 2, 13, 12, }, + { 2, 0, 0, 2, 13, 30, }, + { 0, 0, 0, 2, 14, 63, }, + { 2, 0, 0, 2, 14, 63, }, + { 0, 0, 1, 2, 1, 63, }, + { 2, 0, 1, 2, 1, 63, }, + { 0, 0, 1, 2, 2, 63, }, + { 2, 0, 1, 2, 2, 63, }, + { 0, 0, 1, 2, 3, 26, }, + { 2, 0, 1, 2, 3, 30, }, + { 0, 0, 1, 2, 4, 26, }, + { 2, 0, 1, 2, 4, 30, }, + { 0, 0, 1, 2, 5, 30, }, + { 2, 0, 1, 2, 5, 30, }, + { 0, 0, 1, 2, 6, 30, }, + { 2, 0, 1, 2, 6, 30, }, + { 0, 0, 1, 2, 7, 30, }, + { 2, 0, 1, 2, 7, 30, }, + { 0, 0, 1, 2, 8, 26, }, + { 2, 0, 1, 2, 8, 30, }, + { 0, 0, 1, 2, 9, 26, }, + { 2, 0, 1, 2, 9, 30, }, + { 0, 0, 1, 2, 10, 28, }, + { 2, 0, 1, 2, 10, 30, }, + { 0, 0, 1, 2, 11, 20, }, + { 2, 0, 1, 2, 11, 30, }, + { 0, 0, 1, 2, 12, 63, }, + { 2, 0, 1, 2, 12, 63, }, + { 0, 0, 1, 2, 13, 63, }, + { 2, 0, 1, 2, 13, 63, }, + { 0, 0, 1, 2, 14, 63, }, + { 2, 0, 1, 2, 14, 63, }, + { 0, 1, 0, 1, 36, 31, }, + { 2, 1, 0, 1, 36, 32, }, + { 0, 1, 0, 1, 40, 33, }, + { 2, 1, 0, 1, 40, 32, }, + { 0, 1, 0, 1, 44, 33, }, + { 2, 1, 0, 1, 44, 32, }, + { 0, 1, 0, 1, 48, 31, }, + { 2, 1, 0, 1, 48, 32, }, + { 0, 1, 0, 1, 52, 33, }, + { 2, 1, 0, 1, 52, 32, }, + { 0, 1, 0, 1, 56, 33, }, + { 2, 1, 0, 1, 56, 32, }, + { 0, 1, 0, 1, 60, 33, }, + { 2, 1, 0, 1, 60, 32, }, + { 0, 1, 0, 1, 64, 30, }, + { 2, 1, 0, 1, 64, 32, }, + { 0, 1, 0, 1, 100, 30, }, + { 2, 1, 0, 1, 100, 32, }, + { 0, 1, 0, 1, 104, 33, }, + { 2, 1, 0, 1, 104, 32, }, + { 0, 1, 0, 1, 108, 33, }, + { 2, 1, 0, 1, 108, 32, }, + { 0, 1, 0, 1, 112, 33, }, + { 2, 1, 0, 1, 112, 32, }, + { 0, 1, 0, 1, 116, 33, }, + { 2, 1, 0, 1, 116, 32, }, + { 0, 1, 0, 1, 120, 33, }, + { 2, 1, 0, 1, 120, 32, }, + { 0, 1, 0, 1, 124, 33, }, + { 2, 1, 0, 1, 124, 32, }, + { 0, 1, 0, 1, 128, 33, }, + { 2, 1, 0, 1, 128, 32, }, + { 0, 1, 0, 1, 132, 33, }, + { 2, 1, 0, 1, 132, 32, }, + { 0, 1, 0, 1, 136, 33, }, + { 2, 1, 0, 1, 136, 32, }, + { 0, 1, 0, 1, 140, 31, }, + { 2, 1, 0, 1, 140, 32, }, + { 0, 1, 0, 1, 144, 30, }, + { 2, 1, 0, 1, 144, 63, }, + { 0, 1, 0, 1, 149, 33, }, + { 2, 1, 0, 1, 149, 63, }, + { 0, 1, 0, 1, 153, 33, }, + { 2, 1, 0, 1, 153, 63, }, + { 0, 1, 0, 1, 157, 33, }, + { 2, 1, 0, 1, 157, 63, }, + { 0, 1, 0, 1, 161, 33, }, + { 2, 1, 0, 1, 161, 63, }, + { 0, 1, 0, 1, 165, 33, }, + { 2, 1, 0, 1, 165, 63, }, + { 0, 1, 0, 2, 36, 30, }, + { 2, 1, 0, 2, 36, 32, }, + { 0, 1, 0, 2, 40, 33, }, + { 2, 1, 0, 2, 40, 32, }, + { 0, 1, 0, 2, 44, 33, }, + { 2, 1, 0, 2, 44, 32, }, + { 0, 1, 0, 2, 48, 33, }, + { 2, 1, 0, 2, 48, 32, }, + { 0, 1, 0, 2, 52, 33, }, + { 2, 1, 0, 2, 52, 32, }, + { 0, 1, 0, 2, 56, 33, }, + { 2, 1, 0, 2, 56, 32, }, + { 0, 1, 0, 2, 60, 33, }, + { 2, 1, 0, 2, 60, 32, }, + { 0, 1, 0, 2, 64, 30, }, + { 2, 1, 0, 2, 64, 32, }, + { 0, 1, 0, 2, 100, 30, }, + { 2, 1, 0, 2, 100, 32, }, + { 0, 1, 0, 2, 104, 33, }, + { 2, 1, 0, 2, 104, 32, }, + { 0, 1, 0, 2, 108, 33, }, + { 2, 1, 0, 2, 108, 32, }, + { 0, 1, 0, 2, 112, 33, }, + { 2, 1, 0, 2, 112, 32, }, + { 0, 1, 0, 2, 116, 33, }, + { 2, 1, 0, 2, 116, 32, }, + { 0, 1, 0, 2, 120, 33, }, + { 2, 1, 0, 2, 120, 32, }, + { 0, 1, 0, 2, 124, 33, }, + { 2, 1, 0, 2, 124, 32, }, + { 0, 1, 0, 2, 128, 33, }, + { 2, 1, 0, 2, 128, 32, }, + { 0, 1, 0, 2, 132, 33, }, + { 2, 1, 0, 2, 132, 32, }, + { 0, 1, 0, 2, 136, 33, }, + { 2, 1, 0, 2, 136, 32, }, + { 0, 1, 0, 2, 140, 29, }, + { 2, 1, 0, 2, 140, 32, }, + { 0, 1, 0, 2, 144, 27, }, + { 2, 1, 0, 2, 144, 63, }, + { 0, 1, 0, 2, 149, 33, }, + { 2, 1, 0, 2, 149, 63, }, + { 0, 1, 0, 2, 153, 33, }, + { 2, 1, 0, 2, 153, 63, }, + { 0, 1, 0, 2, 157, 33, }, + { 2, 1, 0, 2, 157, 63, }, + { 0, 1, 0, 2, 161, 33, }, + { 2, 1, 0, 2, 161, 63, }, + { 0, 1, 0, 2, 165, 33, }, + { 2, 1, 0, 2, 165, 63, }, + { 0, 1, 1, 2, 38, 22, }, + { 2, 1, 1, 2, 38, 32, }, + { 0, 1, 1, 2, 46, 32, }, + { 2, 1, 1, 2, 46, 32, }, + { 0, 1, 1, 2, 54, 32, }, + { 2, 1, 1, 2, 54, 32, }, + { 0, 1, 1, 2, 62, 23, }, + { 2, 1, 1, 2, 62, 32, }, + { 0, 1, 1, 2, 102, 21, }, + { 2, 1, 1, 2, 102, 32, }, + { 0, 1, 1, 2, 110, 32, }, + { 2, 1, 1, 2, 110, 32, }, + { 0, 1, 1, 2, 118, 32, }, + { 2, 1, 1, 2, 118, 32, }, + { 0, 1, 1, 2, 126, 32, }, + { 2, 1, 1, 2, 126, 32, }, + { 0, 1, 1, 2, 134, 32, }, + { 2, 1, 1, 2, 134, 32, }, + { 0, 1, 1, 2, 142, 29, }, + { 2, 1, 1, 2, 142, 63, }, + { 0, 1, 1, 2, 151, 32, }, + { 2, 1, 1, 2, 151, 63, }, + { 0, 1, 1, 2, 159, 32, }, + { 2, 1, 1, 2, 159, 63, }, + { 0, 1, 2, 4, 42, 19, }, + { 2, 1, 2, 4, 42, 32, }, + { 0, 1, 2, 4, 58, 22, }, + { 2, 1, 2, 4, 58, 32, }, + { 0, 1, 2, 4, 106, 18, }, + { 2, 1, 2, 4, 106, 32, }, + { 0, 1, 2, 4, 122, 32, }, + { 2, 1, 2, 4, 122, 32, }, + { 0, 1, 2, 4, 138, 28, }, + { 2, 1, 2, 4, 138, 63, }, + { 0, 1, 2, 4, 155, 32, }, + { 2, 1, 2, 4, 155, 63, }, + { 1, 0, 0, 0, 1, 34, }, + { 3, 0, 0, 0, 1, 30, }, + { 4, 0, 0, 0, 1, 34, }, + { 5, 0, 0, 0, 1, 30, }, + { 6, 0, 0, 0, 1, 30, }, + { 7, 0, 0, 0, 1, 30, }, + { 1, 0, 0, 0, 2, 34, }, + { 3, 0, 0, 0, 2, 32, }, + { 4, 0, 0, 0, 2, 34, }, + { 5, 0, 0, 0, 2, 30, }, + { 6, 0, 0, 0, 2, 32, }, + { 7, 0, 0, 0, 2, 30, }, + { 1, 0, 0, 0, 3, 34, }, + { 3, 0, 0, 0, 3, 32, }, + { 4, 0, 0, 0, 3, 34, }, + { 5, 0, 0, 0, 3, 30, }, + { 6, 0, 0, 0, 3, 32, }, + { 7, 0, 0, 0, 3, 30, }, + { 1, 0, 0, 0, 4, 34, }, + { 3, 0, 0, 0, 4, 32, }, + { 4, 0, 0, 0, 4, 34, }, + { 5, 0, 0, 0, 4, 30, }, + { 6, 0, 0, 0, 4, 32, }, + { 7, 0, 0, 0, 4, 30, }, + { 1, 0, 0, 0, 5, 34, }, + { 3, 0, 0, 0, 5, 32, }, + { 4, 0, 0, 0, 5, 34, }, + { 5, 0, 0, 0, 5, 30, }, + { 6, 0, 0, 0, 5, 32, }, + { 7, 0, 0, 0, 5, 30, }, + { 1, 0, 0, 0, 6, 34, }, + { 3, 0, 0, 0, 6, 32, }, + { 4, 0, 0, 0, 6, 34, }, + { 5, 0, 0, 0, 6, 30, }, + { 6, 0, 0, 0, 6, 32, }, + { 7, 0, 0, 0, 6, 30, }, + { 1, 0, 0, 0, 7, 34, }, + { 3, 0, 0, 0, 7, 32, }, + { 4, 0, 0, 0, 7, 34, }, + { 5, 0, 0, 0, 7, 30, }, + { 6, 0, 0, 0, 7, 32, }, + { 7, 0, 0, 0, 7, 30, }, + { 1, 0, 0, 0, 8, 34, }, + { 3, 0, 0, 0, 8, 32, }, + { 4, 0, 0, 0, 8, 34, }, + { 5, 0, 0, 0, 8, 30, }, + { 6, 0, 0, 0, 8, 32, }, + { 7, 0, 0, 0, 8, 30, }, + { 1, 0, 0, 0, 9, 34, }, + { 3, 0, 0, 0, 9, 32, }, + { 4, 0, 0, 0, 9, 34, }, + { 5, 0, 0, 0, 9, 30, }, + { 6, 0, 0, 0, 9, 32, }, + { 7, 0, 0, 0, 9, 30, }, + { 1, 0, 0, 0, 10, 34, }, + { 3, 0, 0, 0, 10, 32, }, + { 4, 0, 0, 0, 10, 34, }, + { 5, 0, 0, 0, 10, 30, }, + { 6, 0, 0, 0, 10, 32, }, + { 7, 0, 0, 0, 10, 30, }, + { 1, 0, 0, 0, 11, 34, }, + { 3, 0, 0, 0, 11, 32, }, + { 4, 0, 0, 0, 11, 34, }, + { 5, 0, 0, 0, 11, 30, }, + { 6, 0, 0, 0, 11, 32, }, + { 7, 0, 0, 0, 11, 30, }, + { 1, 0, 0, 0, 12, 34, }, + { 3, 0, 0, 0, 12, 24, }, + { 4, 0, 0, 0, 12, 34, }, + { 5, 0, 0, 0, 12, 30, }, + { 6, 0, 0, 0, 12, 24, }, + { 7, 0, 0, 0, 12, 30, }, + { 1, 0, 0, 0, 13, 34, }, + { 3, 0, 0, 0, 13, 16, }, + { 4, 0, 0, 0, 13, 34, }, + { 5, 0, 0, 0, 13, 30, }, + { 6, 0, 0, 0, 13, 16, }, + { 7, 0, 0, 0, 13, 30, }, + { 1, 0, 0, 0, 14, 34, }, + { 3, 0, 0, 0, 14, 63, }, + { 4, 0, 0, 0, 14, 63, }, + { 5, 0, 0, 0, 14, 63, }, + { 6, 0, 0, 0, 14, 63, }, + { 7, 0, 0, 0, 14, 63, }, + { 1, 0, 0, 1, 1, 34, }, + { 3, 0, 0, 1, 1, 30, }, + { 4, 0, 0, 1, 1, 32, }, + { 5, 0, 0, 1, 1, 30, }, + { 6, 0, 0, 1, 1, 30, }, + { 7, 0, 0, 1, 1, 30, }, + { 1, 0, 0, 1, 2, 34, }, + { 3, 0, 0, 1, 2, 32, }, + { 4, 0, 0, 1, 2, 34, }, + { 5, 0, 0, 1, 2, 30, }, + { 6, 0, 0, 1, 2, 32, }, + { 7, 0, 0, 1, 2, 30, }, + { 1, 0, 0, 1, 3, 34, }, + { 3, 0, 0, 1, 3, 34, }, + { 4, 0, 0, 1, 3, 34, }, + { 5, 0, 0, 1, 3, 30, }, + { 6, 0, 0, 1, 3, 34, }, + { 7, 0, 0, 1, 3, 30, }, + { 1, 0, 0, 1, 4, 34, }, + { 3, 0, 0, 1, 4, 34, }, + { 4, 0, 0, 1, 4, 34, }, + { 5, 0, 0, 1, 4, 30, }, + { 6, 0, 0, 1, 4, 34, }, + { 7, 0, 0, 1, 4, 30, }, + { 1, 0, 0, 1, 5, 34, }, + { 3, 0, 0, 1, 5, 34, }, + { 4, 0, 0, 1, 5, 34, }, + { 5, 0, 0, 1, 5, 30, }, + { 6, 0, 0, 1, 5, 34, }, + { 7, 0, 0, 1, 5, 30, }, + { 1, 0, 0, 1, 6, 34, }, + { 3, 0, 0, 1, 6, 34, }, + { 4, 0, 0, 1, 6, 34, }, + { 5, 0, 0, 1, 6, 30, }, + { 6, 0, 0, 1, 6, 34, }, + { 7, 0, 0, 1, 6, 30, }, + { 1, 0, 0, 1, 7, 34, }, + { 3, 0, 0, 1, 7, 34, }, + { 4, 0, 0, 1, 7, 34, }, + { 5, 0, 0, 1, 7, 30, }, + { 6, 0, 0, 1, 7, 34, }, + { 7, 0, 0, 1, 7, 30, }, + { 1, 0, 0, 1, 8, 34, }, + { 3, 0, 0, 1, 8, 34, }, + { 4, 0, 0, 1, 8, 34, }, + { 5, 0, 0, 1, 8, 30, }, + { 6, 0, 0, 1, 8, 34, }, + { 7, 0, 0, 1, 8, 30, }, + { 1, 0, 0, 1, 9, 34, }, + { 3, 0, 0, 1, 9, 34, }, + { 4, 0, 0, 1, 9, 34, }, + { 5, 0, 0, 1, 9, 30, }, + { 6, 0, 0, 1, 9, 34, }, + { 7, 0, 0, 1, 9, 30, }, + { 1, 0, 0, 1, 10, 34, }, + { 3, 0, 0, 1, 10, 32, }, + { 4, 0, 0, 1, 10, 34, }, + { 5, 0, 0, 1, 10, 30, }, + { 6, 0, 0, 1, 10, 32, }, + { 7, 0, 0, 1, 10, 30, }, + { 1, 0, 0, 1, 11, 34, }, + { 3, 0, 0, 1, 11, 30, }, + { 4, 0, 0, 1, 11, 34, }, + { 5, 0, 0, 1, 11, 30, }, + { 6, 0, 0, 1, 11, 30, }, + { 7, 0, 0, 1, 11, 30, }, + { 1, 0, 0, 1, 12, 34, }, + { 3, 0, 0, 1, 12, 28, }, + { 4, 0, 0, 1, 12, 34, }, + { 5, 0, 0, 1, 12, 30, }, + { 6, 0, 0, 1, 12, 28, }, + { 7, 0, 0, 1, 12, 30, }, + { 1, 0, 0, 1, 13, 34, }, + { 3, 0, 0, 1, 13, 16, }, + { 4, 0, 0, 1, 13, 32, }, + { 5, 0, 0, 1, 13, 30, }, + { 6, 0, 0, 1, 13, 16, }, + { 7, 0, 0, 1, 13, 30, }, + { 1, 0, 0, 1, 14, 63, }, + { 3, 0, 0, 1, 14, 63, }, + { 4, 0, 0, 1, 14, 63, }, + { 5, 0, 0, 1, 14, 63, }, + { 6, 0, 0, 1, 14, 63, }, + { 7, 0, 0, 1, 14, 63, }, + { 1, 0, 0, 2, 1, 34, }, + { 3, 0, 0, 2, 1, 26, }, + { 4, 0, 0, 2, 1, 32, }, + { 5, 0, 0, 2, 1, 30, }, + { 6, 0, 0, 2, 1, 26, }, + { 7, 0, 0, 2, 1, 30, }, + { 1, 0, 0, 2, 2, 34, }, + { 3, 0, 0, 2, 2, 30, }, + { 4, 0, 0, 2, 2, 34, }, + { 5, 0, 0, 2, 2, 30, }, + { 6, 0, 0, 2, 2, 30, }, + { 7, 0, 0, 2, 2, 30, }, + { 1, 0, 0, 2, 3, 34, }, + { 3, 0, 0, 2, 3, 32, }, + { 4, 0, 0, 2, 3, 34, }, + { 5, 0, 0, 2, 3, 30, }, + { 6, 0, 0, 2, 3, 32, }, + { 7, 0, 0, 2, 3, 30, }, + { 1, 0, 0, 2, 4, 34, }, + { 3, 0, 0, 2, 4, 34, }, + { 4, 0, 0, 2, 4, 34, }, + { 5, 0, 0, 2, 4, 30, }, + { 6, 0, 0, 2, 4, 34, }, + { 7, 0, 0, 2, 4, 30, }, + { 1, 0, 0, 2, 5, 34, }, + { 3, 0, 0, 2, 5, 34, }, + { 4, 0, 0, 2, 5, 34, }, + { 5, 0, 0, 2, 5, 30, }, + { 6, 0, 0, 2, 5, 34, }, + { 7, 0, 0, 2, 5, 30, }, + { 1, 0, 0, 2, 6, 34, }, + { 3, 0, 0, 2, 6, 34, }, + { 4, 0, 0, 2, 6, 34, }, + { 5, 0, 0, 2, 6, 30, }, + { 6, 0, 0, 2, 6, 34, }, + { 7, 0, 0, 2, 6, 30, }, + { 1, 0, 0, 2, 7, 34, }, + { 3, 0, 0, 2, 7, 34, }, + { 4, 0, 0, 2, 7, 34, }, + { 5, 0, 0, 2, 7, 30, }, + { 6, 0, 0, 2, 7, 34, }, + { 7, 0, 0, 2, 7, 30, }, + { 1, 0, 0, 2, 8, 34, }, + { 3, 0, 0, 2, 8, 34, }, + { 4, 0, 0, 2, 8, 34, }, + { 5, 0, 0, 2, 8, 30, }, + { 6, 0, 0, 2, 8, 34, }, + { 7, 0, 0, 2, 8, 30, }, + { 1, 0, 0, 2, 9, 34, }, + { 3, 0, 0, 2, 9, 32, }, + { 4, 0, 0, 2, 9, 34, }, + { 5, 0, 0, 2, 9, 30, }, + { 6, 0, 0, 2, 9, 32, }, + { 7, 0, 0, 2, 9, 30, }, + { 1, 0, 0, 2, 10, 34, }, + { 3, 0, 0, 2, 10, 30, }, + { 4, 0, 0, 2, 10, 34, }, + { 5, 0, 0, 2, 10, 30, }, + { 6, 0, 0, 2, 10, 30, }, + { 7, 0, 0, 2, 10, 30, }, + { 1, 0, 0, 2, 11, 34, }, + { 3, 0, 0, 2, 11, 28, }, + { 4, 0, 0, 2, 11, 34, }, + { 5, 0, 0, 2, 11, 30, }, + { 6, 0, 0, 2, 11, 28, }, + { 7, 0, 0, 2, 11, 30, }, + { 1, 0, 0, 2, 12, 34, }, + { 3, 0, 0, 2, 12, 26, }, + { 4, 0, 0, 2, 12, 34, }, + { 5, 0, 0, 2, 12, 30, }, + { 6, 0, 0, 2, 12, 26, }, + { 7, 0, 0, 2, 12, 30, }, + { 1, 0, 0, 2, 13, 34, }, + { 3, 0, 0, 2, 13, 12, }, + { 4, 0, 0, 2, 13, 32, }, + { 5, 0, 0, 2, 13, 30, }, + { 6, 0, 0, 2, 13, 12, }, + { 7, 0, 0, 2, 13, 30, }, + { 1, 0, 0, 2, 14, 63, }, + { 3, 0, 0, 2, 14, 63, }, + { 4, 0, 0, 2, 14, 63, }, + { 5, 0, 0, 2, 14, 63, }, + { 6, 0, 0, 2, 14, 63, }, + { 7, 0, 0, 2, 14, 63, }, + { 1, 0, 1, 2, 1, 63, }, + { 3, 0, 1, 2, 1, 63, }, + { 4, 0, 1, 2, 1, 63, }, + { 5, 0, 1, 2, 1, 63, }, + { 6, 0, 1, 2, 1, 63, }, + { 7, 0, 1, 2, 1, 63, }, + { 1, 0, 1, 2, 2, 63, }, + { 3, 0, 1, 2, 2, 63, }, + { 4, 0, 1, 2, 2, 63, }, + { 5, 0, 1, 2, 2, 63, }, + { 6, 0, 1, 2, 2, 63, }, + { 7, 0, 1, 2, 2, 63, }, + { 1, 0, 1, 2, 3, 30, }, + { 3, 0, 1, 2, 3, 26, }, + { 4, 0, 1, 2, 3, 30, }, + { 5, 0, 1, 2, 3, 30, }, + { 6, 0, 1, 2, 3, 26, }, + { 7, 0, 1, 2, 3, 30, }, + { 1, 0, 1, 2, 4, 30, }, + { 3, 0, 1, 2, 4, 26, }, + { 4, 0, 1, 2, 4, 30, }, + { 5, 0, 1, 2, 4, 30, }, + { 6, 0, 1, 2, 4, 26, }, + { 7, 0, 1, 2, 4, 30, }, + { 1, 0, 1, 2, 5, 30, }, + { 3, 0, 1, 2, 5, 30, }, + { 4, 0, 1, 2, 5, 30, }, + { 5, 0, 1, 2, 5, 30, }, + { 6, 0, 1, 2, 5, 30, }, + { 7, 0, 1, 2, 5, 30, }, + { 1, 0, 1, 2, 6, 30, }, + { 3, 0, 1, 2, 6, 30, }, + { 4, 0, 1, 2, 6, 30, }, + { 5, 0, 1, 2, 6, 30, }, + { 6, 0, 1, 2, 6, 30, }, + { 7, 0, 1, 2, 6, 30, }, + { 1, 0, 1, 2, 7, 30, }, + { 3, 0, 1, 2, 7, 30, }, + { 4, 0, 1, 2, 7, 30, }, + { 5, 0, 1, 2, 7, 30, }, + { 6, 0, 1, 2, 7, 30, }, + { 7, 0, 1, 2, 7, 30, }, + { 1, 0, 1, 2, 8, 30, }, + { 3, 0, 1, 2, 8, 26, }, + { 4, 0, 1, 2, 8, 30, }, + { 5, 0, 1, 2, 8, 30, }, + { 6, 0, 1, 2, 8, 26, }, + { 7, 0, 1, 2, 8, 30, }, + { 1, 0, 1, 2, 9, 30, }, + { 3, 0, 1, 2, 9, 26, }, + { 4, 0, 1, 2, 9, 30, }, + { 5, 0, 1, 2, 9, 30, }, + { 6, 0, 1, 2, 9, 26, }, + { 7, 0, 1, 2, 9, 30, }, + { 1, 0, 1, 2, 10, 30, }, + { 3, 0, 1, 2, 10, 28, }, + { 4, 0, 1, 2, 10, 30, }, + { 5, 0, 1, 2, 10, 30, }, + { 6, 0, 1, 2, 10, 28, }, + { 7, 0, 1, 2, 10, 30, }, + { 1, 0, 1, 2, 11, 30, }, + { 3, 0, 1, 2, 11, 20, }, + { 4, 0, 1, 2, 11, 30, }, + { 5, 0, 1, 2, 11, 30, }, + { 6, 0, 1, 2, 11, 20, }, + { 7, 0, 1, 2, 11, 30, }, + { 1, 0, 1, 2, 12, 63, }, + { 3, 0, 1, 2, 12, 63, }, + { 4, 0, 1, 2, 12, 63, }, + { 5, 0, 1, 2, 12, 63, }, + { 6, 0, 1, 2, 12, 63, }, + { 7, 0, 1, 2, 12, 63, }, + { 1, 0, 1, 2, 13, 63, }, + { 3, 0, 1, 2, 13, 63, }, + { 4, 0, 1, 2, 13, 63, }, + { 5, 0, 1, 2, 13, 63, }, + { 6, 0, 1, 2, 13, 63, }, + { 7, 0, 1, 2, 13, 63, }, + { 1, 0, 1, 2, 14, 63, }, + { 3, 0, 1, 2, 14, 63, }, + { 4, 0, 1, 2, 14, 63, }, + { 5, 0, 1, 2, 14, 63, }, + { 6, 0, 1, 2, 14, 63, }, + { 7, 0, 1, 2, 14, 63, }, + { 1, 1, 0, 1, 36, 33, }, + { 3, 1, 0, 1, 36, 31, }, + { 4, 1, 0, 1, 36, 29, }, + { 5, 1, 0, 1, 36, 32, }, + { 6, 1, 0, 1, 36, 29, }, + { 7, 1, 0, 1, 36, 27, }, + { 1, 1, 0, 1, 40, 33, }, + { 3, 1, 0, 1, 40, 31, }, + { 4, 1, 0, 1, 40, 28, }, + { 5, 1, 0, 1, 40, 32, }, + { 6, 1, 0, 1, 40, 29, }, + { 7, 1, 0, 1, 40, 27, }, + { 1, 1, 0, 1, 44, 33, }, + { 3, 1, 0, 1, 44, 31, }, + { 4, 1, 0, 1, 44, 28, }, + { 5, 1, 0, 1, 44, 32, }, + { 6, 1, 0, 1, 44, 30, }, + { 7, 1, 0, 1, 44, 27, }, + { 1, 1, 0, 1, 48, 33, }, + { 3, 1, 0, 1, 48, 31, }, + { 4, 1, 0, 1, 48, 27, }, + { 5, 1, 0, 1, 48, 32, }, + { 6, 1, 0, 1, 48, 30, }, + { 7, 1, 0, 1, 48, 27, }, + { 1, 1, 0, 1, 52, 33, }, + { 3, 1, 0, 1, 52, 32, }, + { 4, 1, 0, 1, 52, 16, }, + { 5, 1, 0, 1, 52, 32, }, + { 6, 1, 0, 1, 52, 30, }, + { 7, 1, 0, 1, 52, 27, }, + { 1, 1, 0, 1, 56, 33, }, + { 3, 1, 0, 1, 56, 32, }, + { 4, 1, 0, 1, 56, 33, }, + { 5, 1, 0, 1, 56, 32, }, + { 6, 1, 0, 1, 56, 30, }, + { 7, 1, 0, 1, 56, 27, }, + { 1, 1, 0, 1, 60, 33, }, + { 3, 1, 0, 1, 60, 32, }, + { 4, 1, 0, 1, 60, 33, }, + { 5, 1, 0, 1, 60, 32, }, + { 6, 1, 0, 1, 60, 30, }, + { 7, 1, 0, 1, 60, 27, }, + { 1, 1, 0, 1, 64, 33, }, + { 3, 1, 0, 1, 64, 30, }, + { 4, 1, 0, 1, 64, 33, }, + { 5, 1, 0, 1, 64, 32, }, + { 6, 1, 0, 1, 64, 29, }, + { 7, 1, 0, 1, 64, 27, }, + { 1, 1, 0, 1, 100, 33, }, + { 3, 1, 0, 1, 100, 30, }, + { 4, 1, 0, 1, 100, 33, }, + { 5, 1, 0, 1, 100, 32, }, + { 6, 1, 0, 1, 100, 30, }, + { 7, 1, 0, 1, 100, 27, }, + { 1, 1, 0, 1, 104, 33, }, + { 3, 1, 0, 1, 104, 33, }, + { 4, 1, 0, 1, 104, 33, }, + { 5, 1, 0, 1, 104, 32, }, + { 6, 1, 0, 1, 104, 30, }, + { 7, 1, 0, 1, 104, 27, }, + { 1, 1, 0, 1, 108, 33, }, + { 3, 1, 0, 1, 108, 33, }, + { 4, 1, 0, 1, 108, 33, }, + { 5, 1, 0, 1, 108, 32, }, + { 6, 1, 0, 1, 108, 30, }, + { 7, 1, 0, 1, 108, 27, }, + { 1, 1, 0, 1, 112, 33, }, + { 3, 1, 0, 1, 112, 33, }, + { 4, 1, 0, 1, 112, 33, }, + { 5, 1, 0, 1, 112, 32, }, + { 6, 1, 0, 1, 112, 30, }, + { 7, 1, 0, 1, 112, 27, }, + { 1, 1, 0, 1, 116, 33, }, + { 3, 1, 0, 1, 116, 33, }, + { 4, 1, 0, 1, 116, 33, }, + { 5, 1, 0, 1, 116, 32, }, + { 6, 1, 0, 1, 116, 30, }, + { 7, 1, 0, 1, 116, 27, }, + { 1, 1, 0, 1, 120, 33, }, + { 3, 1, 0, 1, 120, 63, }, + { 4, 1, 0, 1, 120, 33, }, + { 5, 1, 0, 1, 120, 63, }, + { 6, 1, 0, 1, 120, 30, }, + { 7, 1, 0, 1, 120, 27, }, + { 1, 1, 0, 1, 124, 33, }, + { 3, 1, 0, 1, 124, 63, }, + { 4, 1, 0, 1, 124, 33, }, + { 5, 1, 0, 1, 124, 63, }, + { 6, 1, 0, 1, 124, 30, }, + { 7, 1, 0, 1, 124, 27, }, + { 1, 1, 0, 1, 128, 33, }, + { 3, 1, 0, 1, 128, 63, }, + { 4, 1, 0, 1, 128, 63, }, + { 5, 1, 0, 1, 128, 63, }, + { 6, 1, 0, 1, 128, 30, }, + { 7, 1, 0, 1, 128, 27, }, + { 1, 1, 0, 1, 132, 33, }, + { 3, 1, 0, 1, 132, 33, }, + { 4, 1, 0, 1, 132, 63, }, + { 5, 1, 0, 1, 132, 32, }, + { 6, 1, 0, 1, 132, 30, }, + { 7, 1, 0, 1, 132, 27, }, + { 1, 1, 0, 1, 136, 33, }, + { 3, 1, 0, 1, 136, 33, }, + { 4, 1, 0, 1, 136, 63, }, + { 5, 1, 0, 1, 136, 32, }, + { 6, 1, 0, 1, 136, 30, }, + { 7, 1, 0, 1, 136, 63, }, + { 1, 1, 0, 1, 140, 33, }, + { 3, 1, 0, 1, 140, 31, }, + { 4, 1, 0, 1, 140, 63, }, + { 5, 1, 0, 1, 140, 32, }, + { 6, 1, 0, 1, 140, 30, }, + { 7, 1, 0, 1, 140, 63, }, + { 1, 1, 0, 1, 144, 63, }, + { 3, 1, 0, 1, 144, 30, }, + { 4, 1, 0, 1, 144, 63, }, + { 5, 1, 0, 1, 144, 63, }, + { 6, 1, 0, 1, 144, 30, }, + { 7, 1, 0, 1, 144, 63, }, + { 1, 1, 0, 1, 149, 63, }, + { 3, 1, 0, 1, 149, 30, }, + { 4, 1, 0, 1, 149, 33, }, + { 5, 1, 0, 1, 149, 33, }, + { 6, 1, 0, 1, 149, 30, }, + { 7, 1, 0, 1, 149, 27, }, + { 1, 1, 0, 1, 153, 63, }, + { 3, 1, 0, 1, 153, 33, }, + { 4, 1, 0, 1, 153, 33, }, + { 5, 1, 0, 1, 153, 33, }, + { 6, 1, 0, 1, 153, 30, }, + { 7, 1, 0, 1, 153, 27, }, + { 1, 1, 0, 1, 157, 63, }, + { 3, 1, 0, 1, 157, 33, }, + { 4, 1, 0, 1, 157, 33, }, + { 5, 1, 0, 1, 157, 33, }, + { 6, 1, 0, 1, 157, 30, }, + { 7, 1, 0, 1, 157, 27, }, + { 1, 1, 0, 1, 161, 63, }, + { 3, 1, 0, 1, 161, 33, }, + { 4, 1, 0, 1, 161, 31, }, + { 5, 1, 0, 1, 161, 33, }, + { 6, 1, 0, 1, 161, 30, }, + { 7, 1, 0, 1, 161, 27, }, + { 1, 1, 0, 1, 165, 63, }, + { 3, 1, 0, 1, 165, 33, }, + { 4, 1, 0, 1, 165, 63, }, + { 5, 1, 0, 1, 165, 33, }, + { 6, 1, 0, 1, 165, 30, }, + { 7, 1, 0, 1, 165, 27, }, + { 1, 1, 0, 2, 36, 33, }, + { 3, 1, 0, 2, 36, 30, }, + { 4, 1, 0, 2, 36, 27, }, + { 5, 1, 0, 2, 36, 32, }, + { 6, 1, 0, 2, 36, 30, }, + { 7, 1, 0, 2, 36, 27, }, + { 1, 1, 0, 2, 40, 33, }, + { 3, 1, 0, 2, 40, 31, }, + { 4, 1, 0, 2, 40, 29, }, + { 5, 1, 0, 2, 40, 32, }, + { 6, 1, 0, 2, 40, 30, }, + { 7, 1, 0, 2, 40, 27, }, + { 1, 1, 0, 2, 44, 33, }, + { 3, 1, 0, 2, 44, 31, }, + { 4, 1, 0, 2, 44, 29, }, + { 5, 1, 0, 2, 44, 32, }, + { 6, 1, 0, 2, 44, 30, }, + { 7, 1, 0, 2, 44, 27, }, + { 1, 1, 0, 2, 48, 33, }, + { 3, 1, 0, 2, 48, 31, }, + { 4, 1, 0, 2, 48, 26, }, + { 5, 1, 0, 2, 48, 32, }, + { 6, 1, 0, 2, 48, 30, }, + { 7, 1, 0, 2, 48, 27, }, + { 1, 1, 0, 2, 52, 33, }, + { 3, 1, 0, 2, 52, 32, }, + { 4, 1, 0, 2, 52, 7, }, + { 5, 1, 0, 2, 52, 32, }, + { 6, 1, 0, 2, 52, 30, }, + { 7, 1, 0, 2, 52, 27, }, + { 1, 1, 0, 2, 56, 33, }, + { 3, 1, 0, 2, 56, 32, }, + { 4, 1, 0, 2, 56, 33, }, + { 5, 1, 0, 2, 56, 32, }, + { 6, 1, 0, 2, 56, 30, }, + { 7, 1, 0, 2, 56, 27, }, + { 1, 1, 0, 2, 60, 33, }, + { 3, 1, 0, 2, 60, 32, }, + { 4, 1, 0, 2, 60, 33, }, + { 5, 1, 0, 2, 60, 32, }, + { 6, 1, 0, 2, 60, 30, }, + { 7, 1, 0, 2, 60, 27, }, + { 1, 1, 0, 2, 64, 33, }, + { 3, 1, 0, 2, 64, 30, }, + { 4, 1, 0, 2, 64, 33, }, + { 5, 1, 0, 2, 64, 32, }, + { 6, 1, 0, 2, 64, 30, }, + { 7, 1, 0, 2, 64, 27, }, + { 1, 1, 0, 2, 100, 33, }, + { 3, 1, 0, 2, 100, 30, }, + { 4, 1, 0, 2, 100, 33, }, + { 5, 1, 0, 2, 100, 32, }, + { 6, 1, 0, 2, 100, 30, }, + { 7, 1, 0, 2, 100, 27, }, + { 1, 1, 0, 2, 104, 33, }, + { 3, 1, 0, 2, 104, 33, }, + { 4, 1, 0, 2, 104, 33, }, + { 5, 1, 0, 2, 104, 32, }, + { 6, 1, 0, 2, 104, 30, }, + { 7, 1, 0, 2, 104, 27, }, + { 1, 1, 0, 2, 108, 33, }, + { 3, 1, 0, 2, 108, 33, }, + { 4, 1, 0, 2, 108, 33, }, + { 5, 1, 0, 2, 108, 32, }, + { 6, 1, 0, 2, 108, 30, }, + { 7, 1, 0, 2, 108, 27, }, + { 1, 1, 0, 2, 112, 33, }, + { 3, 1, 0, 2, 112, 33, }, + { 4, 1, 0, 2, 112, 33, }, + { 5, 1, 0, 2, 112, 32, }, + { 6, 1, 0, 2, 112, 30, }, + { 7, 1, 0, 2, 112, 27, }, + { 1, 1, 0, 2, 116, 33, }, + { 3, 1, 0, 2, 116, 33, }, + { 4, 1, 0, 2, 116, 33, }, + { 5, 1, 0, 2, 116, 32, }, + { 6, 1, 0, 2, 116, 30, }, + { 7, 1, 0, 2, 116, 27, }, + { 1, 1, 0, 2, 120, 33, }, + { 3, 1, 0, 2, 120, 63, }, + { 4, 1, 0, 2, 120, 33, }, + { 5, 1, 0, 2, 120, 63, }, + { 6, 1, 0, 2, 120, 30, }, + { 7, 1, 0, 2, 120, 27, }, + { 1, 1, 0, 2, 124, 33, }, + { 3, 1, 0, 2, 124, 63, }, + { 4, 1, 0, 2, 124, 33, }, + { 5, 1, 0, 2, 124, 63, }, + { 6, 1, 0, 2, 124, 30, }, + { 7, 1, 0, 2, 124, 27, }, + { 1, 1, 0, 2, 128, 33, }, + { 3, 1, 0, 2, 128, 63, }, + { 4, 1, 0, 2, 128, 63, }, + { 5, 1, 0, 2, 128, 63, }, + { 6, 1, 0, 2, 128, 30, }, + { 7, 1, 0, 2, 128, 27, }, + { 1, 1, 0, 2, 132, 33, }, + { 3, 1, 0, 2, 132, 33, }, + { 4, 1, 0, 2, 132, 63, }, + { 5, 1, 0, 2, 132, 32, }, + { 6, 1, 0, 2, 132, 30, }, + { 7, 1, 0, 2, 132, 27, }, + { 1, 1, 0, 2, 136, 33, }, + { 3, 1, 0, 2, 136, 33, }, + { 4, 1, 0, 2, 136, 63, }, + { 5, 1, 0, 2, 136, 32, }, + { 6, 1, 0, 2, 136, 30, }, + { 7, 1, 0, 2, 136, 63, }, + { 1, 1, 0, 2, 140, 33, }, + { 3, 1, 0, 2, 140, 29, }, + { 4, 1, 0, 2, 140, 63, }, + { 5, 1, 0, 2, 140, 32, }, + { 6, 1, 0, 2, 140, 30, }, + { 7, 1, 0, 2, 140, 63, }, + { 1, 1, 0, 2, 144, 63, }, + { 3, 1, 0, 2, 144, 27, }, + { 4, 1, 0, 2, 144, 63, }, + { 5, 1, 0, 2, 144, 63, }, + { 6, 1, 0, 2, 144, 30, }, + { 7, 1, 0, 2, 144, 63, }, + { 1, 1, 0, 2, 149, 63, }, + { 3, 1, 0, 2, 149, 33, }, + { 4, 1, 0, 2, 149, 33, }, + { 5, 1, 0, 2, 149, 33, }, + { 6, 1, 0, 2, 149, 30, }, + { 7, 1, 0, 2, 149, 27, }, + { 1, 1, 0, 2, 153, 63, }, + { 3, 1, 0, 2, 153, 33, }, + { 4, 1, 0, 2, 153, 33, }, + { 5, 1, 0, 2, 153, 33, }, + { 6, 1, 0, 2, 153, 30, }, + { 7, 1, 0, 2, 153, 27, }, + { 1, 1, 0, 2, 157, 63, }, + { 3, 1, 0, 2, 157, 33, }, + { 4, 1, 0, 2, 157, 33, }, + { 5, 1, 0, 2, 157, 33, }, + { 6, 1, 0, 2, 157, 30, }, + { 7, 1, 0, 2, 157, 27, }, + { 1, 1, 0, 2, 161, 63, }, + { 3, 1, 0, 2, 161, 33, }, + { 4, 1, 0, 2, 161, 31, }, + { 5, 1, 0, 2, 161, 33, }, + { 6, 1, 0, 2, 161, 30, }, + { 7, 1, 0, 2, 161, 27, }, + { 1, 1, 0, 2, 165, 63, }, + { 3, 1, 0, 2, 165, 33, }, + { 4, 1, 0, 2, 165, 63, }, + { 5, 1, 0, 2, 165, 33, }, + { 6, 1, 0, 2, 165, 30, }, + { 7, 1, 0, 2, 165, 27, }, + { 1, 1, 1, 2, 38, 32, }, + { 3, 1, 1, 2, 38, 22, }, + { 4, 1, 1, 2, 38, 26, }, + { 5, 1, 1, 2, 38, 32, }, + { 6, 1, 1, 2, 38, 22, }, + { 7, 1, 1, 2, 38, 27, }, + { 1, 1, 1, 2, 46, 32, }, + { 3, 1, 1, 2, 46, 32, }, + { 4, 1, 1, 2, 46, 28, }, + { 5, 1, 1, 2, 46, 32, }, + { 6, 1, 1, 2, 46, 30, }, + { 7, 1, 1, 2, 46, 27, }, + { 1, 1, 1, 2, 54, 32, }, + { 3, 1, 1, 2, 54, 32, }, + { 4, 1, 1, 2, 54, 22, }, + { 5, 1, 1, 2, 54, 32, }, + { 6, 1, 1, 2, 54, 30, }, + { 7, 1, 1, 2, 54, 27, }, + { 1, 1, 1, 2, 62, 32, }, + { 3, 1, 1, 2, 62, 23, }, + { 4, 1, 1, 2, 62, 31, }, + { 5, 1, 1, 2, 62, 32, }, + { 6, 1, 1, 2, 62, 23, }, + { 7, 1, 1, 2, 62, 27, }, + { 1, 1, 1, 2, 102, 32, }, + { 3, 1, 1, 2, 102, 21, }, + { 4, 1, 1, 2, 102, 31, }, + { 5, 1, 1, 2, 102, 32, }, + { 6, 1, 1, 2, 102, 30, }, + { 7, 1, 1, 2, 102, 27, }, + { 1, 1, 1, 2, 110, 32, }, + { 3, 1, 1, 2, 110, 32, }, + { 4, 1, 1, 2, 110, 32, }, + { 5, 1, 1, 2, 110, 32, }, + { 6, 1, 1, 2, 110, 30, }, + { 7, 1, 1, 2, 110, 27, }, + { 1, 1, 1, 2, 118, 32, }, + { 3, 1, 1, 2, 118, 63, }, + { 4, 1, 1, 2, 118, 32, }, + { 5, 1, 1, 2, 118, 63, }, + { 6, 1, 1, 2, 118, 30, }, + { 7, 1, 1, 2, 118, 27, }, + { 1, 1, 1, 2, 126, 32, }, + { 3, 1, 1, 2, 126, 63, }, + { 4, 1, 1, 2, 126, 63, }, + { 5, 1, 1, 2, 126, 63, }, + { 6, 1, 1, 2, 126, 30, }, + { 7, 1, 1, 2, 126, 27, }, + { 1, 1, 1, 2, 134, 32, }, + { 3, 1, 1, 2, 134, 32, }, + { 4, 1, 1, 2, 134, 63, }, + { 5, 1, 1, 2, 134, 32, }, + { 6, 1, 1, 2, 134, 30, }, + { 7, 1, 1, 2, 134, 63, }, + { 1, 1, 1, 2, 142, 63, }, + { 3, 1, 1, 2, 142, 29, }, + { 4, 1, 1, 2, 142, 63, }, + { 5, 1, 1, 2, 142, 63, }, + { 6, 1, 1, 2, 142, 30, }, + { 7, 1, 1, 2, 142, 63, }, + { 1, 1, 1, 2, 151, 63, }, + { 3, 1, 1, 2, 151, 32, }, + { 4, 1, 1, 2, 151, 27, }, + { 5, 1, 1, 2, 151, 32, }, + { 6, 1, 1, 2, 151, 30, }, + { 7, 1, 1, 2, 151, 27, }, + { 1, 1, 1, 2, 159, 63, }, + { 3, 1, 1, 2, 159, 32, }, + { 4, 1, 1, 2, 159, 26, }, + { 5, 1, 1, 2, 159, 32, }, + { 6, 1, 1, 2, 159, 30, }, + { 7, 1, 1, 2, 159, 27, }, + { 1, 1, 2, 4, 42, 28, }, + { 3, 1, 2, 4, 42, 19, }, + { 4, 1, 2, 4, 42, 25, }, + { 5, 1, 2, 4, 42, 32, }, + { 6, 1, 2, 4, 42, 19, }, + { 7, 1, 2, 4, 42, 27, }, + { 1, 1, 2, 4, 58, 28, }, + { 3, 1, 2, 4, 58, 22, }, + { 4, 1, 2, 4, 58, 28, }, + { 5, 1, 2, 4, 58, 32, }, + { 6, 1, 2, 4, 58, 22, }, + { 7, 1, 2, 4, 58, 27, }, + { 1, 1, 2, 4, 106, 32, }, + { 3, 1, 2, 4, 106, 18, }, + { 4, 1, 2, 4, 106, 30, }, + { 5, 1, 2, 4, 106, 32, }, + { 6, 1, 2, 4, 106, 30, }, + { 7, 1, 2, 4, 106, 27, }, + { 1, 1, 2, 4, 122, 32, }, + { 3, 1, 2, 4, 122, 63, }, + { 4, 1, 2, 4, 122, 26, }, + { 5, 1, 2, 4, 122, 63, }, + { 6, 1, 2, 4, 122, 30, }, + { 7, 1, 2, 4, 122, 27, }, + { 1, 1, 2, 4, 138, 63, }, + { 3, 1, 2, 4, 138, 28, }, + { 4, 1, 2, 4, 138, 63, }, + { 5, 1, 2, 4, 138, 63, }, + { 6, 1, 2, 4, 138, 30, }, + { 7, 1, 2, 4, 138, 63, }, + { 1, 1, 2, 4, 155, 63, }, + { 3, 1, 2, 4, 155, 32, }, + { 4, 1, 2, 4, 155, 27, }, + { 5, 1, 2, 4, 155, 32, }, + { 6, 1, 2, 4, 155, 30, }, + { 7, 1, 2, 4, 155, 27, }, +}; + +RTW_DECL_TABLE_TXPWR_LMT(rtw8821c_txpwr_lmt_type0); diff --git a/drivers/net/wireless/realtek/rtw88/rtw8821c_table.h b/drivers/net/wireless/realtek/rtw88/rtw8821c_table.h new file mode 100644 index 000000000000..5ea8b4fc7fba --- /dev/null +++ b/drivers/net/wireless/realtek/rtw88/rtw8821c_table.h @@ -0,0 +1,15 @@ +/* SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause */ +/* Copyright(c) 2018-2019 Realtek Corporation + */ + +#ifndef __RTW8821C_TABLE_H__ +#define __RTW8821C_TABLE_H__ + +extern const struct rtw_table rtw8821c_mac_tbl; +extern const struct rtw_table rtw8821c_agc_tbl; +extern const struct rtw_table rtw8821c_bb_tbl; +extern const struct rtw_table rtw8821c_bb_pg_type0_tbl; +extern const struct rtw_table rtw8821c_rf_a_tbl; +extern const struct rtw_table rtw8821c_txpwr_lmt_type0_tbl; + +#endif diff --git a/drivers/net/wireless/realtek/rtw88/rtw8821ce.c b/drivers/net/wireless/realtek/rtw88/rtw8821ce.c new file mode 100644 index 000000000000..616fdcfd62c9 --- /dev/null +++ b/drivers/net/wireless/realtek/rtw88/rtw8821ce.c @@ -0,0 +1,30 @@ +// SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause +/* Copyright(c) 2018-2019 Realtek Corporation + */ + +#include <linux/module.h> +#include <linux/pci.h> +#include "rtw8821ce.h" + +static const struct pci_device_id rtw_8821ce_id_table[] = { + { + PCI_DEVICE(PCI_VENDOR_ID_REALTEK, 0xC821), + .driver_data = (kernel_ulong_t)&rtw8821c_hw_spec + }, + {} +}; +MODULE_DEVICE_TABLE(pci, rtw_8821ce_id_table); + +static struct pci_driver rtw_8821ce_driver = { + .name = "rtw_8821ce", + .id_table = rtw_8821ce_id_table, + .probe = rtw_pci_probe, + .remove = rtw_pci_remove, + .driver.pm = &rtw_pm_ops, + .shutdown = rtw_pci_shutdown, +}; +module_pci_driver(rtw_8821ce_driver); + +MODULE_AUTHOR("Realtek Corporation"); +MODULE_DESCRIPTION("Realtek 802.11ac wireless 8821ce driver"); +MODULE_LICENSE("Dual BSD/GPL"); diff --git a/drivers/net/wireless/realtek/rtw88/rtw8821ce.h b/drivers/net/wireless/realtek/rtw88/rtw8821ce.h new file mode 100644 index 000000000000..8d3eb77a876b --- /dev/null +++ b/drivers/net/wireless/realtek/rtw88/rtw8821ce.h @@ -0,0 +1,14 @@ +/* SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause */ +/* Copyright(c) 2018-2019 Realtek Corporation + */ + +#ifndef __RTW_8821CE_H_ +#define __RTW_8821CE_H_ + +extern const struct dev_pm_ops rtw_pm_ops; +extern struct rtw_chip_info rtw8821c_hw_spec; +int rtw_pci_probe(struct pci_dev *pdev, const struct pci_device_id *id); +void rtw_pci_remove(struct pci_dev *pdev); +void rtw_pci_shutdown(struct pci_dev *pdev); + +#endif diff --git a/drivers/net/wireless/realtek/rtw88/rtw8822b.c b/drivers/net/wireless/realtek/rtw88/rtw8822b.c index e49bdd76ab9a..351cd055a295 100644 --- a/drivers/net/wireless/realtek/rtw88/rtw8822b.c +++ b/drivers/net/wireless/realtek/rtw88/rtw8822b.c @@ -2147,7 +2147,7 @@ static const struct coex_table_para table_sant_8822b[] = { {0x66555555, 0x5a5a5a5a}, {0x66555555, 0x6a5a5a5a}, /* case-10 */ {0x66555555, 0xfafafafa}, - {0x66555555, 0x6a5a5aaa}, + {0x66555555, 0x5a5a5aaa}, {0x66555555, 0x5aaa5aaa}, {0x66555555, 0xaaaa5aaa}, {0x66555555, 0xaaaaaaaa}, /* case-15 */ @@ -2223,7 +2223,8 @@ static const struct coex_tdma_para tdma_sant_8822b[] = { { {0x55, 0x08, 0x03, 0x10, 0x54} }, { {0x65, 0x10, 0x03, 0x11, 0x11} }, { {0x51, 0x10, 0x03, 0x10, 0x51} }, /* case-25 */ - { {0x51, 0x08, 0x03, 0x10, 0x50} } + { {0x51, 0x08, 0x03, 0x10, 0x50} }, + { {0x61, 0x08, 0x03, 0x11, 0x11} } }; /* Non-Shared-Antenna TDMA */ @@ -2475,7 +2476,7 @@ struct rtw_chip_info rtw8822b_hw_spec = { .bfer_mu_max_num = 1, .rx_ldpc = true, - .coex_para_ver = 0x19062706, + .coex_para_ver = 0x20070206, .bt_desired_ver = 0x6, .scbd_support = true, .new_scbd10_def = false, diff --git a/drivers/net/wireless/realtek/rtw88/rtw8822c.c b/drivers/net/wireless/realtek/rtw88/rtw8822c.c index c3d72ef611c6..426808413baa 100644 --- a/drivers/net/wireless/realtek/rtw88/rtw8822c.c +++ b/drivers/net/wireless/realtek/rtw88/rtw8822c.c @@ -3899,6 +3899,7 @@ static const struct rtw_rfe_def rtw8822c_rfe_defs[] = { [1] = RTW_DEF_RFE(8822c, 0, 0), [2] = RTW_DEF_RFE(8822c, 0, 0), [5] = RTW_DEF_RFE(8822c, 0, 5), + [6] = RTW_DEF_RFE(8822c, 0, 0), }; static const struct rtw_hw_reg rtw8822c_dig[] = { @@ -3997,7 +3998,7 @@ static const struct coex_table_para table_sant_8822c[] = { {0x66555555, 0x5a5a5a5a}, {0x66555555, 0x6a5a5a5a}, /* case-10 */ {0x66555555, 0xfafafafa}, - {0x66555555, 0x6a5a5aaa}, + {0x66555555, 0x5a5a5aaa}, {0x66555555, 0x5aaa5aaa}, {0x66555555, 0xaaaa5aaa}, {0x66555555, 0xaaaaaaaa}, /* case-15 */ @@ -4073,7 +4074,8 @@ static const struct coex_tdma_para tdma_sant_8822c[] = { { {0x55, 0x08, 0x03, 0x10, 0x54} }, { {0x65, 0x10, 0x03, 0x11, 0x11} }, { {0x51, 0x10, 0x03, 0x10, 0x51} }, /* case-25 */ - { {0x51, 0x08, 0x03, 0x10, 0x50} } + { {0x51, 0x08, 0x03, 0x10, 0x50} }, + { {0x61, 0x08, 0x03, 0x11, 0x11} } }; /* Non-Shared-Antenna TDMA */ @@ -4343,8 +4345,8 @@ struct rtw_chip_info rtw8822c_hw_spec = { .wowlan_stub = &rtw_wowlan_stub_8822c, .max_sched_scan_ssids = 4, #endif - .coex_para_ver = 0x19062706, - .bt_desired_ver = 0x6, + .coex_para_ver = 0x20070217, + .bt_desired_ver = 0x17, .scbd_support = true, .new_scbd10_def = true, .pstdma_type = COEX_PSTDMA_FORCE_LPSOFF, diff --git a/drivers/net/wireless/realtek/rtw88/rtw8822ce.c b/drivers/net/wireless/realtek/rtw88/rtw8822ce.c index 7b6bd990651e..026ac49ce6e3 100644 --- a/drivers/net/wireless/realtek/rtw88/rtw8822ce.c +++ b/drivers/net/wireless/realtek/rtw88/rtw8822ce.c @@ -11,6 +11,10 @@ static const struct pci_device_id rtw_8822ce_id_table[] = { PCI_DEVICE(PCI_VENDOR_ID_REALTEK, 0xC822), .driver_data = (kernel_ulong_t)&rtw8822c_hw_spec }, + { + PCI_DEVICE(PCI_VENDOR_ID_REALTEK, 0xC82F), + .driver_data = (kernel_ulong_t)&rtw8822c_hw_spec + }, {} }; MODULE_DEVICE_TABLE(pci, rtw_8822ce_id_table); diff --git a/drivers/net/wireless/ti/wlcore/main.c b/drivers/net/wireless/ti/wlcore/main.c index de6c8a7589ca..821ad1acd505 100644 --- a/drivers/net/wireless/ti/wlcore/main.c +++ b/drivers/net/wireless/ti/wlcore/main.c @@ -521,6 +521,7 @@ static int wlcore_irq_locked(struct wl1271 *wl) int ret = 0; u32 intr; int loopcount = WL1271_IRQ_MAX_LOOPS; + bool run_tx_queue = true; bool done = false; unsigned int defer_count; unsigned long flags; @@ -586,19 +587,22 @@ static int wlcore_irq_locked(struct wl1271 *wl) goto err_ret; /* Check if any tx blocks were freed */ - spin_lock_irqsave(&wl->wl_lock, flags); - if (!test_bit(WL1271_FLAG_FW_TX_BUSY, &wl->flags) && - wl1271_tx_total_queue_count(wl) > 0) { - spin_unlock_irqrestore(&wl->wl_lock, flags); + if (!test_bit(WL1271_FLAG_FW_TX_BUSY, &wl->flags)) { + if (spin_trylock_irqsave(&wl->wl_lock, flags)) { + if (!wl1271_tx_total_queue_count(wl)) + run_tx_queue = false; + spin_unlock_irqrestore(&wl->wl_lock, flags); + } + /* * In order to avoid starvation of the TX path, * call the work function directly. */ - ret = wlcore_tx_work_locked(wl); - if (ret < 0) - goto err_ret; - } else { - spin_unlock_irqrestore(&wl->wl_lock, flags); + if (run_tx_queue) { + ret = wlcore_tx_work_locked(wl); + if (ret < 0) + goto err_ret; + } } /* check for tx results */ @@ -648,25 +652,28 @@ static irqreturn_t wlcore_irq(int irq, void *cookie) int ret; unsigned long flags; struct wl1271 *wl = cookie; + bool queue_tx_work = true; - /* complete the ELP completion */ - spin_lock_irqsave(&wl->wl_lock, flags); set_bit(WL1271_FLAG_IRQ_RUNNING, &wl->flags); - if (wl->elp_compl) { - complete(wl->elp_compl); - wl->elp_compl = NULL; + + /* complete the ELP completion */ + if (test_bit(WL1271_FLAG_IN_ELP, &wl->flags)) { + spin_lock_irqsave(&wl->wl_lock, flags); + if (wl->elp_compl) + complete(wl->elp_compl); + spin_unlock_irqrestore(&wl->wl_lock, flags); } if (test_bit(WL1271_FLAG_SUSPENDED, &wl->flags)) { /* don't enqueue a work right now. mark it as pending */ set_bit(WL1271_FLAG_PENDING_WORK, &wl->flags); wl1271_debug(DEBUG_IRQ, "should not enqueue work"); + spin_lock_irqsave(&wl->wl_lock, flags); disable_irq_nosync(wl->irq); pm_wakeup_event(wl->dev, 0); spin_unlock_irqrestore(&wl->wl_lock, flags); goto out_handled; } - spin_unlock_irqrestore(&wl->wl_lock, flags); /* TX might be handled here, avoid redundant work */ set_bit(WL1271_FLAG_TX_PENDING, &wl->flags); @@ -678,20 +685,22 @@ static irqreturn_t wlcore_irq(int irq, void *cookie) if (ret) wl12xx_queue_recovery_work(wl); - spin_lock_irqsave(&wl->wl_lock, flags); - /* In case TX was not handled here, queue TX work */ + /* In case TX was not handled in wlcore_irq_locked(), queue TX work */ clear_bit(WL1271_FLAG_TX_PENDING, &wl->flags); - if (!test_bit(WL1271_FLAG_FW_TX_BUSY, &wl->flags) && - wl1271_tx_total_queue_count(wl) > 0) - ieee80211_queue_work(wl->hw, &wl->tx_work); - spin_unlock_irqrestore(&wl->wl_lock, flags); + if (!test_bit(WL1271_FLAG_FW_TX_BUSY, &wl->flags)) { + if (spin_trylock_irqsave(&wl->wl_lock, flags)) { + if (!wl1271_tx_total_queue_count(wl)) + queue_tx_work = false; + spin_unlock_irqrestore(&wl->wl_lock, flags); + } + if (queue_tx_work) + ieee80211_queue_work(wl->hw, &wl->tx_work); + } mutex_unlock(&wl->mutex); out_handled: - spin_lock_irqsave(&wl->wl_lock, flags); clear_bit(WL1271_FLAG_IRQ_RUNNING, &wl->flags); - spin_unlock_irqrestore(&wl->wl_lock, flags); return IRQ_HANDLED; } @@ -6732,7 +6741,6 @@ static int __maybe_unused wlcore_runtime_resume(struct device *dev) unsigned long flags; int ret; unsigned long start_time = jiffies; - bool pending = false; bool recovery = false; /* Nothing to do if no ELP mode requested */ @@ -6742,49 +6750,35 @@ static int __maybe_unused wlcore_runtime_resume(struct device *dev) wl1271_debug(DEBUG_PSM, "waking up chip from elp"); spin_lock_irqsave(&wl->wl_lock, flags); - if (test_bit(WL1271_FLAG_IRQ_RUNNING, &wl->flags)) - pending = true; - else - wl->elp_compl = &compl; + wl->elp_compl = &compl; spin_unlock_irqrestore(&wl->wl_lock, flags); ret = wlcore_raw_write32(wl, HW_ACCESS_ELP_CTRL_REG, ELPCTRL_WAKE_UP); if (ret < 0) { recovery = true; - goto err; - } - - if (!pending) { + } else if (!test_bit(WL1271_FLAG_IRQ_RUNNING, &wl->flags)) { ret = wait_for_completion_timeout(&compl, msecs_to_jiffies(WL1271_WAKEUP_TIMEOUT)); if (ret == 0) { wl1271_warning("ELP wakeup timeout!"); - - /* Return no error for runtime PM for recovery */ - ret = 0; recovery = true; - goto err; } } - clear_bit(WL1271_FLAG_IN_ELP, &wl->flags); - - wl1271_debug(DEBUG_PSM, "wakeup time: %u ms", - jiffies_to_msecs(jiffies - start_time)); - - return 0; - -err: spin_lock_irqsave(&wl->wl_lock, flags); wl->elp_compl = NULL; spin_unlock_irqrestore(&wl->wl_lock, flags); + clear_bit(WL1271_FLAG_IN_ELP, &wl->flags); if (recovery) { set_bit(WL1271_FLAG_INTENDED_FW_RECOVERY, &wl->flags); wl12xx_queue_recovery_work(wl); + } else { + wl1271_debug(DEBUG_PSM, "wakeup time: %u ms", + jiffies_to_msecs(jiffies - start_time)); } - return ret; + return 0; } static const struct dev_pm_ops wlcore_pm_ops = { diff --git a/drivers/net/wireless/zydas/zd1211rw/zd_usb.c b/drivers/net/wireless/zydas/zd1211rw/zd_usb.c index 8ff0374126e4..65b5985ad402 100644 --- a/drivers/net/wireless/zydas/zd1211rw/zd_usb.c +++ b/drivers/net/wireless/zydas/zd1211rw/zd_usb.c @@ -600,9 +600,7 @@ void zd_usb_disable_int(struct zd_usb *usb) dev_dbg_f(zd_usb_dev(usb), "urb %p killed\n", urb); usb_free_urb(urb); - if (buffer) - usb_free_coherent(udev, USB_MAX_EP_INT_BUFFER, - buffer, buffer_dma); + usb_free_coherent(udev, USB_MAX_EP_INT_BUFFER, buffer, buffer_dma); } static void handle_rx_packet(struct zd_usb *usb, const u8 *buffer, diff --git a/drivers/ssb/driver_chipcommon.c b/drivers/ssb/driver_chipcommon.c index 3861cb659cb9..85542bfd7715 100644 --- a/drivers/ssb/driver_chipcommon.c +++ b/drivers/ssb/driver_chipcommon.c @@ -238,7 +238,7 @@ static void chipco_powercontrol_init(struct ssb_chipcommon *cc) } } -/* http://bcm-v4.sipsolutions.net/802.11/PmuFastPwrupDelay */ +/* https://bcm-v4.sipsolutions.net/802.11/PmuFastPwrupDelay */ static u16 pmu_fast_powerup_delay(struct ssb_chipcommon *cc) { struct ssb_bus *bus = cc->dev->bus; @@ -255,7 +255,7 @@ static u16 pmu_fast_powerup_delay(struct ssb_chipcommon *cc) } } -/* http://bcm-v4.sipsolutions.net/802.11/ClkctlFastPwrupDelay */ +/* https://bcm-v4.sipsolutions.net/802.11/ClkctlFastPwrupDelay */ static void calc_fast_powerup_delay(struct ssb_chipcommon *cc) { struct ssb_bus *bus = cc->dev->bus; diff --git a/drivers/ssb/driver_chipcommon_pmu.c b/drivers/ssb/driver_chipcommon_pmu.c index 0f60e90ded26..888069e10659 100644 --- a/drivers/ssb/driver_chipcommon_pmu.c +++ b/drivers/ssb/driver_chipcommon_pmu.c @@ -513,7 +513,7 @@ static void ssb_pmu_resources_init(struct ssb_chipcommon *cc) chipco_write32(cc, SSB_CHIPCO_PMU_MAXRES_MSK, max_msk); } -/* http://bcm-v4.sipsolutions.net/802.11/SSB/PmuInit */ +/* https://bcm-v4.sipsolutions.net/802.11/SSB/PmuInit */ void ssb_pmu_init(struct ssb_chipcommon *cc) { u32 pmucap; diff --git a/drivers/ssb/sprom.c b/drivers/ssb/sprom.c index 42d620cee8a9..7cd553127861 100644 --- a/drivers/ssb/sprom.c +++ b/drivers/ssb/sprom.c @@ -186,7 +186,7 @@ int ssb_fill_sprom_with_fallback(struct ssb_bus *bus, struct ssb_sprom *out) return get_fallback_sprom(bus, out); } -/* http://bcm-v4.sipsolutions.net/802.11/IsSpromAvailable */ +/* https://bcm-v4.sipsolutions.net/802.11/IsSpromAvailable */ bool ssb_is_sprom_available(struct ssb_bus *bus) { /* status register only exists on chipcomon rev >= 11 and we need check diff --git a/drivers/staging/Kconfig b/drivers/staging/Kconfig index 4ec5528f89fa..b3fb4d41e231 100644 --- a/drivers/staging/Kconfig +++ b/drivers/staging/Kconfig @@ -84,8 +84,6 @@ source "drivers/staging/fbtft/Kconfig" source "drivers/staging/fsl-dpaa2/Kconfig" -source "drivers/staging/wilc1000/Kconfig" - source "drivers/staging/most/Kconfig" source "drivers/staging/ks7010/Kconfig" diff --git a/drivers/staging/Makefile b/drivers/staging/Makefile index 4d34198151b3..3d8c7ea21a10 100644 --- a/drivers/staging/Makefile +++ b/drivers/staging/Makefile @@ -32,7 +32,6 @@ obj-$(CONFIG_UNISYSSPAR) += unisys/ obj-$(CONFIG_COMMON_CLK_XLNX_CLKWZRD) += clocking-wizard/ obj-$(CONFIG_FB_TFT) += fbtft/ obj-$(CONFIG_FSL_DPAA2) += fsl-dpaa2/ -obj-$(CONFIG_WILC1000) += wilc1000/ obj-$(CONFIG_MOST) += most/ obj-$(CONFIG_KS7010) += ks7010/ obj-$(CONFIG_GREYBUS) += greybus/ |