mirror of
https://github.com/torvalds/linux.git
synced 2026-06-07 14:04:54 +02:00
wireless-drivers-next patches for v5.16
First set of patches for v5.16. ath11k getting most of new features this time. Other drivers also have few new features, and of course the usual set of fixes and cleanups all over. Major changes: rtw88 * support adaptivity for ETSI/JP DFS region * 8821c: support RFE type4 wifi NIC brcmfmac * DMI nvram filename quirk for Cyberbook T116 tablet ath9k * load calibration data and pci init values via nvmem subsystem ath11k * include channel rx and tx time in survey dump statistics * support for setting fixed Wi-Fi 6 rates from user space * support for 80P80 and 160 MHz bandwidths * spectral scan support for QCN9074 * support for calibration data files per radio * support for calibration data via eeprom * support for rx decapsulation offload (data frames in 802.3 format) * support channel 2 in 6 GHz band ath10k * include frame time stamp in beacon and probe response frames wcn36xx * enable Idle Mode Power Save (IMPS) to reduce power consumption during idle -----BEGIN PGP SIGNATURE----- iQFJBAABCgAzFiEEiBjanGPFTz4PRfLobhckVSbrbZsFAmFeqCYVHGt2YWxvQGNv ZGVhdXJvcmEub3JnAAoJEG4XJFUm622b1+QIAKeCfq25i6ObhdgKP7etAHyaOupP 0wKxXwuOMLllwUSDp/1vyONqMgNbpurXlGzqcwG2fRyljZouuuzAM/WUxtSETVEC TaXYhoX7+u0DuVZ+QvREL0fK+jBB2qbpRpAneNPQ+nvjND5dVm233NwZ4oG65Z4f qQC21WeP6rfi870Bj5ycmGIWbb+OVT0B7FHfNzy5tSkcCFmlKZBfP7p6raUyy6/Z 0EBosxEd5FWjAHbWHXLGtXb+k/48ntcFyCswa9qMBjVawahgNfXGG1JwceHFMRvE fwNMweWj4M5QVs7jBZoQaxijBXUPjJdp/2adybgIpgQp50FmlC8uyRSe9YQ= =yAni -----END PGP SIGNATURE----- Merge tag 'wireless-drivers-next-2021-10-07' of git://git.kernel.org/pub/scm/linux/kernel/git/kvalo/wireless-drivers-next Kalle Valo says: ==================== wireless-drivers-next patches for v5.16 First set of patches for v5.16. ath11k getting most of new features this time. Other drivers also have few new features, and of course the usual set of fixes and cleanups all over. Major changes: rtw88 * support adaptivity for ETSI/JP DFS region * 8821c: support RFE type4 wifi NIC brcmfmac * DMI nvram filename quirk for Cyberbook T116 tablet ath9k * load calibration data and pci init values via nvmem subsystem ath11k * include channel rx and tx time in survey dump statistics * support for setting fixed Wi-Fi 6 rates from user space * support for 80P80 and 160 MHz bandwidths * spectral scan support for QCN9074 * support for calibration data files per radio * support for calibration data via eeprom * support for rx decapsulation offload (data frames in 802.3 format) * support channel 2 in 6 GHz band ath10k * include frame time stamp in beacon and probe response frames wcn36xx * enable Idle Mode Power Save (IMPS) to reduce power consumption during idle ==================== Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:
commit
44cc24b04b
|
|
@ -20,7 +20,7 @@ MODULE_DESCRIPTION("Broadcom's specific AMBA driver");
|
|||
MODULE_LICENSE("GPL");
|
||||
|
||||
/* contains the number the next bus should get. */
|
||||
static unsigned int bcma_bus_next_num = 0;
|
||||
static unsigned int bcma_bus_next_num;
|
||||
|
||||
/* bcma_buses_mutex locks the bcma_bus_next_num */
|
||||
static DEFINE_MUTEX(bcma_buses_mutex);
|
||||
|
|
|
|||
|
|
@ -1772,9 +1772,8 @@ static const struct usb_device_id ar5523_id_table[] = {
|
|||
AR5523_DEVICE_UG(0x0846, 0x5f00), /* Netgear / WPN111 */
|
||||
AR5523_DEVICE_UG(0x083a, 0x4506), /* SMC / EZ Connect
|
||||
SMCWUSBT-G2 */
|
||||
AR5523_DEVICE_UG(0x157e, 0x3006), /* Umedia / AR5523_1 */
|
||||
AR5523_DEVICE_UG(0x157e, 0x3006), /* Umedia / AR5523_1, TEW444UBEU*/
|
||||
AR5523_DEVICE_UX(0x157e, 0x3205), /* Umedia / AR5523_2 */
|
||||
AR5523_DEVICE_UG(0x157e, 0x3006), /* Umedia / TEW444UBEU */
|
||||
AR5523_DEVICE_UG(0x1435, 0x0826), /* Wistronneweb / AR5523_1 */
|
||||
AR5523_DEVICE_UX(0x1435, 0x0828), /* Wistronneweb / AR5523_2 */
|
||||
AR5523_DEVICE_UG(0x0cde, 0x0012), /* Zcom / AR5523 */
|
||||
|
|
|
|||
|
|
@ -993,8 +993,12 @@ static void ath10k_mac_vif_beacon_cleanup(struct ath10k_vif *arvif)
|
|||
ath10k_mac_vif_beacon_free(arvif);
|
||||
|
||||
if (arvif->beacon_buf) {
|
||||
dma_free_coherent(ar->dev, IEEE80211_MAX_FRAME_LEN,
|
||||
arvif->beacon_buf, arvif->beacon_paddr);
|
||||
if (ar->bus_param.dev_type == ATH10K_DEV_TYPE_HL)
|
||||
kfree(arvif->beacon_buf);
|
||||
else
|
||||
dma_free_coherent(ar->dev, IEEE80211_MAX_FRAME_LEN,
|
||||
arvif->beacon_buf,
|
||||
arvif->beacon_paddr);
|
||||
arvif->beacon_buf = NULL;
|
||||
}
|
||||
}
|
||||
|
|
@ -5576,10 +5580,17 @@ static int ath10k_add_interface(struct ieee80211_hw *hw,
|
|||
if (vif->type == NL80211_IFTYPE_ADHOC ||
|
||||
vif->type == NL80211_IFTYPE_MESH_POINT ||
|
||||
vif->type == NL80211_IFTYPE_AP) {
|
||||
arvif->beacon_buf = dma_alloc_coherent(ar->dev,
|
||||
IEEE80211_MAX_FRAME_LEN,
|
||||
&arvif->beacon_paddr,
|
||||
GFP_ATOMIC);
|
||||
if (ar->bus_param.dev_type == ATH10K_DEV_TYPE_HL) {
|
||||
arvif->beacon_buf = kmalloc(IEEE80211_MAX_FRAME_LEN,
|
||||
GFP_KERNEL);
|
||||
arvif->beacon_paddr = (dma_addr_t)arvif->beacon_buf;
|
||||
} else {
|
||||
arvif->beacon_buf =
|
||||
dma_alloc_coherent(ar->dev,
|
||||
IEEE80211_MAX_FRAME_LEN,
|
||||
&arvif->beacon_paddr,
|
||||
GFP_ATOMIC);
|
||||
}
|
||||
if (!arvif->beacon_buf) {
|
||||
ret = -ENOMEM;
|
||||
ath10k_warn(ar, "failed to allocate beacon buffer: %d\n",
|
||||
|
|
@ -5794,8 +5805,12 @@ static int ath10k_add_interface(struct ieee80211_hw *hw,
|
|||
|
||||
err:
|
||||
if (arvif->beacon_buf) {
|
||||
dma_free_coherent(ar->dev, IEEE80211_MAX_FRAME_LEN,
|
||||
arvif->beacon_buf, arvif->beacon_paddr);
|
||||
if (ar->bus_param.dev_type == ATH10K_DEV_TYPE_HL)
|
||||
kfree(arvif->beacon_buf);
|
||||
else
|
||||
dma_free_coherent(ar->dev, IEEE80211_MAX_FRAME_LEN,
|
||||
arvif->beacon_buf,
|
||||
arvif->beacon_paddr);
|
||||
arvif->beacon_buf = NULL;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -1363,8 +1363,11 @@ static void ath10k_rx_indication_async_work(struct work_struct *work)
|
|||
ep->ep_ops.ep_rx_complete(ar, skb);
|
||||
}
|
||||
|
||||
if (test_bit(ATH10K_FLAG_CORE_REGISTERED, &ar->dev_flags))
|
||||
if (test_bit(ATH10K_FLAG_CORE_REGISTERED, &ar->dev_flags)) {
|
||||
local_bh_disable();
|
||||
napi_schedule(&ar->napi);
|
||||
local_bh_enable();
|
||||
}
|
||||
}
|
||||
|
||||
static int ath10k_sdio_read_rtc_state(struct ath10k_sdio *ar_sdio, unsigned char *state)
|
||||
|
|
|
|||
|
|
@ -2610,6 +2610,10 @@ int ath10k_wmi_event_mgmt_rx(struct ath10k *ar, struct sk_buff *skb)
|
|||
if (ieee80211_is_beacon(hdr->frame_control))
|
||||
ath10k_mac_handle_beacon(ar, skb);
|
||||
|
||||
if (ieee80211_is_beacon(hdr->frame_control) ||
|
||||
ieee80211_is_probe_resp(hdr->frame_control))
|
||||
status->boottime_ns = ktime_get_boottime_ns();
|
||||
|
||||
ath10k_dbg(ar, ATH10K_DBG_MGMT,
|
||||
"event mgmt rx skb %pK len %d ftype %02x stype %02x\n",
|
||||
skb, skb->len,
|
||||
|
|
|
|||
|
|
@ -37,7 +37,7 @@ static const struct ath11k_hw_params ath11k_hw_params[] = {
|
|||
.fw = {
|
||||
.dir = "IPQ8074/hw2.0",
|
||||
.board_size = 256 * 1024,
|
||||
.cal_size = 256 * 1024,
|
||||
.cal_offset = 128 * 1024,
|
||||
},
|
||||
.max_radios = 3,
|
||||
.bdf_addr = 0x4B0C0000,
|
||||
|
|
@ -59,7 +59,17 @@ static const struct ath11k_hw_params ath11k_hw_params[] = {
|
|||
.vdev_start_delay = false,
|
||||
.htt_peer_map_v2 = true,
|
||||
.tcl_0_only = false,
|
||||
.spectral_fft_sz = 2,
|
||||
|
||||
.spectral = {
|
||||
.fft_sz = 2,
|
||||
/* HW bug, expected BIN size is 2 bytes but HW report as 4 bytes.
|
||||
* so added pad size as 2 bytes to compensate the BIN size
|
||||
*/
|
||||
.fft_pad_sz = 2,
|
||||
.summary_pad_sz = 0,
|
||||
.fft_hdr_len = 16,
|
||||
.max_fft_bins = 512,
|
||||
},
|
||||
|
||||
.interface_modes = BIT(NL80211_IFTYPE_STATION) |
|
||||
BIT(NL80211_IFTYPE_AP) |
|
||||
|
|
@ -78,7 +88,7 @@ static const struct ath11k_hw_params ath11k_hw_params[] = {
|
|||
.fw = {
|
||||
.dir = "IPQ6018/hw1.0",
|
||||
.board_size = 256 * 1024,
|
||||
.cal_size = 256 * 1024,
|
||||
.cal_offset = 128 * 1024,
|
||||
},
|
||||
.max_radios = 2,
|
||||
.bdf_addr = 0x4ABC0000,
|
||||
|
|
@ -100,7 +110,14 @@ static const struct ath11k_hw_params ath11k_hw_params[] = {
|
|||
.vdev_start_delay = false,
|
||||
.htt_peer_map_v2 = true,
|
||||
.tcl_0_only = false,
|
||||
.spectral_fft_sz = 4,
|
||||
|
||||
.spectral = {
|
||||
.fft_sz = 4,
|
||||
.fft_pad_sz = 0,
|
||||
.summary_pad_sz = 0,
|
||||
.fft_hdr_len = 16,
|
||||
.max_fft_bins = 512,
|
||||
},
|
||||
|
||||
.interface_modes = BIT(NL80211_IFTYPE_STATION) |
|
||||
BIT(NL80211_IFTYPE_AP) |
|
||||
|
|
@ -119,7 +136,7 @@ static const struct ath11k_hw_params ath11k_hw_params[] = {
|
|||
.fw = {
|
||||
.dir = "QCA6390/hw2.0",
|
||||
.board_size = 256 * 1024,
|
||||
.cal_size = 256 * 1024,
|
||||
.cal_offset = 128 * 1024,
|
||||
},
|
||||
.max_radios = 3,
|
||||
.bdf_addr = 0x4B0C0000,
|
||||
|
|
@ -141,7 +158,14 @@ static const struct ath11k_hw_params ath11k_hw_params[] = {
|
|||
.vdev_start_delay = true,
|
||||
.htt_peer_map_v2 = false,
|
||||
.tcl_0_only = true,
|
||||
.spectral_fft_sz = 0,
|
||||
|
||||
.spectral = {
|
||||
.fft_sz = 0,
|
||||
.fft_pad_sz = 0,
|
||||
.summary_pad_sz = 0,
|
||||
.fft_hdr_len = 0,
|
||||
.max_fft_bins = 0,
|
||||
},
|
||||
|
||||
.interface_modes = BIT(NL80211_IFTYPE_STATION) |
|
||||
BIT(NL80211_IFTYPE_AP),
|
||||
|
|
@ -159,7 +183,7 @@ static const struct ath11k_hw_params ath11k_hw_params[] = {
|
|||
.fw = {
|
||||
.dir = "QCN9074/hw1.0",
|
||||
.board_size = 256 * 1024,
|
||||
.cal_size = 256 * 1024,
|
||||
.cal_offset = 128 * 1024,
|
||||
},
|
||||
.max_radios = 1,
|
||||
.single_pdev_only = false,
|
||||
|
|
@ -180,6 +204,15 @@ static const struct ath11k_hw_params ath11k_hw_params[] = {
|
|||
.vdev_start_delay = false,
|
||||
.htt_peer_map_v2 = true,
|
||||
.tcl_0_only = false,
|
||||
|
||||
.spectral = {
|
||||
.fft_sz = 2,
|
||||
.fft_pad_sz = 0,
|
||||
.summary_pad_sz = 16,
|
||||
.fft_hdr_len = 24,
|
||||
.max_fft_bins = 1024,
|
||||
},
|
||||
|
||||
.interface_modes = BIT(NL80211_IFTYPE_STATION) |
|
||||
BIT(NL80211_IFTYPE_AP) |
|
||||
BIT(NL80211_IFTYPE_MESH_POINT),
|
||||
|
|
@ -197,7 +230,7 @@ static const struct ath11k_hw_params ath11k_hw_params[] = {
|
|||
.fw = {
|
||||
.dir = "WCN6855/hw2.0",
|
||||
.board_size = 256 * 1024,
|
||||
.cal_size = 256 * 1024,
|
||||
.cal_offset = 128 * 1024,
|
||||
},
|
||||
.max_radios = 3,
|
||||
.bdf_addr = 0x4B0C0000,
|
||||
|
|
@ -219,7 +252,14 @@ static const struct ath11k_hw_params ath11k_hw_params[] = {
|
|||
.vdev_start_delay = true,
|
||||
.htt_peer_map_v2 = false,
|
||||
.tcl_0_only = true,
|
||||
.spectral_fft_sz = 0,
|
||||
|
||||
.spectral = {
|
||||
.fft_sz = 0,
|
||||
.fft_pad_sz = 0,
|
||||
.summary_pad_sz = 0,
|
||||
.fft_hdr_len = 0,
|
||||
.max_fft_bins = 0,
|
||||
},
|
||||
|
||||
.interface_modes = BIT(NL80211_IFTYPE_STATION) |
|
||||
BIT(NL80211_IFTYPE_AP),
|
||||
|
|
|
|||
|
|
@ -93,6 +93,8 @@ struct ath11k_skb_rxcb {
|
|||
bool is_first_msdu;
|
||||
bool is_last_msdu;
|
||||
bool is_continuation;
|
||||
bool is_mcbc;
|
||||
bool is_eapol;
|
||||
struct hal_rx_desc *rx_desc;
|
||||
u8 err_rel_src;
|
||||
u8 err_code;
|
||||
|
|
@ -100,6 +102,8 @@ struct ath11k_skb_rxcb {
|
|||
u8 unmapped;
|
||||
u8 is_frag;
|
||||
u8 tid;
|
||||
u16 peer_id;
|
||||
u16 seq_no;
|
||||
};
|
||||
|
||||
enum ath11k_hw_rev {
|
||||
|
|
@ -193,7 +197,9 @@ enum ath11k_dev_flags {
|
|||
};
|
||||
|
||||
enum ath11k_monitor_flags {
|
||||
ATH11K_FLAG_MONITOR_ENABLED,
|
||||
ATH11K_FLAG_MONITOR_CONF_ENABLED,
|
||||
ATH11K_FLAG_MONITOR_STARTED,
|
||||
ATH11K_FLAG_MONITOR_VDEV_CREATED,
|
||||
};
|
||||
|
||||
struct ath11k_vif {
|
||||
|
|
@ -362,6 +368,7 @@ struct ath11k_sta {
|
|||
enum hal_pn_type pn_type;
|
||||
|
||||
struct work_struct update_wk;
|
||||
struct work_struct set_4addr_wk;
|
||||
struct rate_info txrate;
|
||||
struct rate_info last_txrate;
|
||||
u64 rx_duration;
|
||||
|
|
@ -374,12 +381,15 @@ struct ath11k_sta {
|
|||
/* protected by conf_mutex */
|
||||
bool aggr_mode;
|
||||
#endif
|
||||
|
||||
bool use_4addr_set;
|
||||
u16 tcl_metadata;
|
||||
};
|
||||
|
||||
#define ATH11K_MIN_5G_FREQ 4150
|
||||
#define ATH11K_MIN_6G_FREQ 5945
|
||||
#define ATH11K_MIN_6G_FREQ 5925
|
||||
#define ATH11K_MAX_6G_FREQ 7115
|
||||
#define ATH11K_NUM_CHANS 100
|
||||
#define ATH11K_NUM_CHANS 101
|
||||
#define ATH11K_MAX_5G_CHAN 173
|
||||
|
||||
enum ath11k_state {
|
||||
|
|
@ -484,7 +494,6 @@ struct ath11k {
|
|||
u32 chan_tx_pwr;
|
||||
u32 num_stations;
|
||||
u32 max_num_stations;
|
||||
bool monitor_present;
|
||||
/* To synchronize concurrent synchronous mac80211 callback operations,
|
||||
* concurrent debugfs configuration and concurrent FW statistics events.
|
||||
*/
|
||||
|
|
@ -559,6 +568,7 @@ struct ath11k {
|
|||
struct ath11k_per_peer_tx_stats cached_stats;
|
||||
u32 last_ppdu_id;
|
||||
u32 cached_ppdu_id;
|
||||
int monitor_vdev_id;
|
||||
#ifdef CONFIG_ATH11K_DEBUGFS
|
||||
struct ath11k_debug debug;
|
||||
#endif
|
||||
|
|
@ -591,6 +601,8 @@ struct ath11k_pdev_cap {
|
|||
u32 tx_chain_mask_shift;
|
||||
u32 rx_chain_mask_shift;
|
||||
struct ath11k_band_cap band[NUM_NL80211_BANDS];
|
||||
bool nss_ratio_enabled;
|
||||
u8 nss_ratio_info;
|
||||
};
|
||||
|
||||
struct ath11k_pdev {
|
||||
|
|
@ -794,12 +806,15 @@ struct ath11k_fw_stats_pdev {
|
|||
s32 hw_reaped;
|
||||
/* Num underruns */
|
||||
s32 underrun;
|
||||
/* Num hw paused */
|
||||
u32 hw_paused;
|
||||
/* Num PPDUs cleaned up in TX abort */
|
||||
s32 tx_abort;
|
||||
/* Num MPDUs requeued by SW */
|
||||
s32 mpdus_requeued;
|
||||
/* excessive retries */
|
||||
u32 tx_ko;
|
||||
u32 tx_xretry;
|
||||
/* data hw rate code */
|
||||
u32 data_rc;
|
||||
/* Scheduler self triggers */
|
||||
|
|
@ -820,6 +835,30 @@ struct ath11k_fw_stats_pdev {
|
|||
u32 phy_underrun;
|
||||
/* MPDU is more than txop limit */
|
||||
u32 txop_ovf;
|
||||
/* Num sequences posted */
|
||||
u32 seq_posted;
|
||||
/* Num sequences failed in queueing */
|
||||
u32 seq_failed_queueing;
|
||||
/* Num sequences completed */
|
||||
u32 seq_completed;
|
||||
/* Num sequences restarted */
|
||||
u32 seq_restarted;
|
||||
/* Num of MU sequences posted */
|
||||
u32 mu_seq_posted;
|
||||
/* Num MPDUs flushed by SW, HWPAUSED, SW TXABORT
|
||||
* (Reset,channel change)
|
||||
*/
|
||||
s32 mpdus_sw_flush;
|
||||
/* Num MPDUs filtered by HW, all filter condition (TTL expired) */
|
||||
s32 mpdus_hw_filter;
|
||||
/* Num MPDUs truncated by PDG (TXOP, TBTT,
|
||||
* PPDU_duration based on rate, dyn_bw)
|
||||
*/
|
||||
s32 mpdus_truncated;
|
||||
/* Num MPDUs that was tried but didn't receive ACK or BA */
|
||||
s32 mpdus_ack_failed;
|
||||
/* Num MPDUs that was dropped du to expiry. */
|
||||
s32 mpdus_expired;
|
||||
|
||||
/* PDEV RX stats */
|
||||
/* Cnts any change in ring routing mid-ppdu */
|
||||
|
|
@ -845,6 +884,8 @@ struct ath11k_fw_stats_pdev {
|
|||
s32 phy_err_drop;
|
||||
/* Number of mpdu errors - FCS, MIC, ENC etc. */
|
||||
s32 mpdu_errs;
|
||||
/* Num overflow errors */
|
||||
s32 rx_ovfl_errs;
|
||||
};
|
||||
|
||||
struct ath11k_fw_stats_vdev {
|
||||
|
|
|
|||
|
|
@ -8,8 +8,7 @@
|
|||
|
||||
static int ath11k_dbring_bufs_replenish(struct ath11k *ar,
|
||||
struct ath11k_dbring *ring,
|
||||
struct ath11k_dbring_element *buff,
|
||||
gfp_t gfp)
|
||||
struct ath11k_dbring_element *buff)
|
||||
{
|
||||
struct ath11k_base *ab = ar->ab;
|
||||
struct hal_srng *srng;
|
||||
|
|
@ -35,7 +34,7 @@ static int ath11k_dbring_bufs_replenish(struct ath11k *ar,
|
|||
goto err;
|
||||
|
||||
spin_lock_bh(&ring->idr_lock);
|
||||
buf_id = idr_alloc(&ring->bufs_idr, buff, 0, ring->bufs_max, gfp);
|
||||
buf_id = idr_alloc(&ring->bufs_idr, buff, 0, ring->bufs_max, GFP_ATOMIC);
|
||||
spin_unlock_bh(&ring->idr_lock);
|
||||
if (buf_id < 0) {
|
||||
ret = -ENOBUFS;
|
||||
|
|
@ -72,8 +71,7 @@ static int ath11k_dbring_bufs_replenish(struct ath11k *ar,
|
|||
}
|
||||
|
||||
static int ath11k_dbring_fill_bufs(struct ath11k *ar,
|
||||
struct ath11k_dbring *ring,
|
||||
gfp_t gfp)
|
||||
struct ath11k_dbring *ring)
|
||||
{
|
||||
struct ath11k_dbring_element *buff;
|
||||
struct hal_srng *srng;
|
||||
|
|
@ -92,11 +90,11 @@ static int ath11k_dbring_fill_bufs(struct ath11k *ar,
|
|||
size = sizeof(*buff) + ring->buf_sz + align - 1;
|
||||
|
||||
while (num_remain > 0) {
|
||||
buff = kzalloc(size, gfp);
|
||||
buff = kzalloc(size, GFP_ATOMIC);
|
||||
if (!buff)
|
||||
break;
|
||||
|
||||
ret = ath11k_dbring_bufs_replenish(ar, ring, buff, gfp);
|
||||
ret = ath11k_dbring_bufs_replenish(ar, ring, buff);
|
||||
if (ret) {
|
||||
ath11k_warn(ar->ab, "failed to replenish db ring num_remain %d req_ent %d\n",
|
||||
num_remain, req_entries);
|
||||
|
|
@ -176,7 +174,7 @@ int ath11k_dbring_buf_setup(struct ath11k *ar,
|
|||
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);
|
||||
ret = ath11k_dbring_fill_bufs(ar, ring);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
|
@ -322,7 +320,7 @@ int ath11k_dbring_buffer_release_event(struct ath11k_base *ab,
|
|||
}
|
||||
|
||||
memset(buff, 0, size);
|
||||
ath11k_dbring_bufs_replenish(ar, ring, buff, GFP_ATOMIC);
|
||||
ath11k_dbring_bufs_replenish(ar, ring, buff);
|
||||
}
|
||||
|
||||
spin_unlock_bh(&srng->lock);
|
||||
|
|
|
|||
|
|
@ -902,7 +902,7 @@ static ssize_t ath11k_write_pktlog_filter(struct file *file,
|
|||
struct htt_rx_ring_tlv_filter tlv_filter = {0};
|
||||
u32 rx_filter = 0, ring_id, filter, mode;
|
||||
u8 buf[128] = {0};
|
||||
int i, ret;
|
||||
int i, ret, rx_buf_sz = 0;
|
||||
ssize_t rc;
|
||||
|
||||
mutex_lock(&ar->conf_mutex);
|
||||
|
|
@ -940,6 +940,17 @@ static ssize_t ath11k_write_pktlog_filter(struct file *file,
|
|||
}
|
||||
}
|
||||
|
||||
/* Clear rx filter set for monitor mode and rx status */
|
||||
for (i = 0; i < ab->hw_params.num_rxmda_per_pdev; i++) {
|
||||
ring_id = ar->dp.rx_mon_status_refill_ring[i].refill_buf_ring.ring_id;
|
||||
ret = ath11k_dp_tx_htt_rx_filter_setup(ar->ab, ring_id, ar->dp.mac_id,
|
||||
HAL_RXDMA_MONITOR_STATUS,
|
||||
rx_buf_sz, &tlv_filter);
|
||||
if (ret) {
|
||||
ath11k_warn(ar->ab, "failed to set rx filter for monitor status ring\n");
|
||||
goto out;
|
||||
}
|
||||
}
|
||||
#define HTT_RX_FILTER_TLV_LITE_MODE \
|
||||
(HTT_RX_FILTER_TLV_FLAGS_PPDU_START | \
|
||||
HTT_RX_FILTER_TLV_FLAGS_PPDU_END | \
|
||||
|
|
@ -955,6 +966,7 @@ static ssize_t ath11k_write_pktlog_filter(struct file *file,
|
|||
HTT_RX_FILTER_TLV_FLAGS_MPDU_END |
|
||||
HTT_RX_FILTER_TLV_FLAGS_PACKET_HEADER |
|
||||
HTT_RX_FILTER_TLV_FLAGS_ATTENTION;
|
||||
rx_buf_sz = DP_RX_BUFFER_SIZE;
|
||||
} else if (mode == ATH11K_PKTLOG_MODE_LITE) {
|
||||
ret = ath11k_dp_tx_htt_h2t_ppdu_stats_req(ar,
|
||||
HTT_PPDU_STATS_TAG_PKTLOG);
|
||||
|
|
@ -964,7 +976,12 @@ static ssize_t ath11k_write_pktlog_filter(struct file *file,
|
|||
}
|
||||
|
||||
rx_filter = HTT_RX_FILTER_TLV_LITE_MODE;
|
||||
rx_buf_sz = DP_RX_BUFFER_SIZE_LITE;
|
||||
} else {
|
||||
rx_buf_sz = DP_RX_BUFFER_SIZE;
|
||||
tlv_filter = ath11k_mac_mon_status_filter_default;
|
||||
rx_filter = tlv_filter.rx_filter;
|
||||
|
||||
ret = ath11k_dp_tx_htt_h2t_ppdu_stats_req(ar,
|
||||
HTT_PPDU_STATS_TAG_DEFAULT);
|
||||
if (ret) {
|
||||
|
|
@ -988,7 +1005,7 @@ static ssize_t ath11k_write_pktlog_filter(struct file *file,
|
|||
ret = ath11k_dp_tx_htt_rx_filter_setup(ab, ring_id,
|
||||
ar->dp.mac_id + i,
|
||||
HAL_RXDMA_MONITOR_STATUS,
|
||||
DP_RX_BUFFER_SIZE, &tlv_filter);
|
||||
rx_buf_sz, &tlv_filter);
|
||||
|
||||
if (ret) {
|
||||
ath11k_warn(ab, "failed to set rx filter for monitor status ring\n");
|
||||
|
|
@ -996,8 +1013,8 @@ static ssize_t ath11k_write_pktlog_filter(struct file *file,
|
|||
}
|
||||
}
|
||||
|
||||
ath11k_dbg(ab, ATH11K_DBG_WMI, "pktlog filter %d mode %s\n",
|
||||
filter, ((mode == ATH11K_PKTLOG_MODE_FULL) ? "full" : "lite"));
|
||||
ath11k_info(ab, "pktlog mode %s\n",
|
||||
((mode == ATH11K_PKTLOG_MODE_FULL) ? "full" : "lite"));
|
||||
|
||||
ar->debug.pktlog_filter = filter;
|
||||
ar->debug.pktlog_mode = mode;
|
||||
|
|
|
|||
|
|
@ -38,6 +38,10 @@ enum ath11k_dbg_htt_ext_stats_type {
|
|||
ATH11K_DBG_HTT_EXT_STATS_TX_SOUNDING_INFO = 22,
|
||||
ATH11K_DBG_HTT_EXT_STATS_PDEV_OBSS_PD_STATS = 23,
|
||||
ATH11K_DBG_HTT_EXT_STATS_RING_BACKPRESSURE_STATS = 24,
|
||||
ATH11K_DBG_HTT_EXT_STATS_PEER_CTRL_PATH_TXRX_STATS = 29,
|
||||
ATH11K_DBG_HTT_EXT_STATS_PDEV_TX_RATE_TXBF_STATS = 31,
|
||||
ATH11K_DBG_HTT_EXT_STATS_TXBF_OFDMA = 32,
|
||||
ATH11K_DBG_HTT_EXT_PHY_COUNTERS_AND_PHY_STATS = 37,
|
||||
|
||||
/* keep this last */
|
||||
ATH11K_DBG_HTT_NUM_EXT_STATS,
|
||||
|
|
|
|||
File diff suppressed because it is too large
Load Diff
|
|
@ -102,6 +102,14 @@ enum htt_tlv_tag_t {
|
|||
HTT_STATS_PDEV_OBSS_PD_TAG = 88,
|
||||
HTT_STATS_HW_WAR_TAG = 89,
|
||||
HTT_STATS_RING_BACKPRESSURE_STATS_TAG = 90,
|
||||
HTT_STATS_PEER_CTRL_PATH_TXRX_STATS_TAG = 101,
|
||||
HTT_STATS_PDEV_TX_RATE_TXBF_STATS_TAG = 108,
|
||||
HTT_STATS_TXBF_OFDMA_NDPA_STATS_TAG = 113,
|
||||
HTT_STATS_TXBF_OFDMA_NDP_STATS_TAG = 114,
|
||||
HTT_STATS_TXBF_OFDMA_BRP_STATS_TAG = 115,
|
||||
HTT_STATS_TXBF_OFDMA_STEER_STATS_TAG = 116,
|
||||
HTT_STATS_PHY_COUNTERS_TAG = 121,
|
||||
HTT_STATS_PHY_STATS_TAG = 122,
|
||||
|
||||
HTT_STATS_MAX_TAG,
|
||||
};
|
||||
|
|
@ -137,6 +145,8 @@ struct htt_stats_string_tlv {
|
|||
u32 data[0]; /* Can be variable length */
|
||||
} __packed;
|
||||
|
||||
#define HTT_STATS_MAC_ID GENMASK(7, 0)
|
||||
|
||||
/* == TX PDEV STATS == */
|
||||
struct htt_tx_pdev_stats_cmn_tlv {
|
||||
u32 mac_id__word;
|
||||
|
|
@ -290,6 +300,10 @@ struct htt_hw_stats_whal_tx_tlv {
|
|||
};
|
||||
|
||||
/* ============ PEER STATS ============ */
|
||||
#define HTT_MSDU_FLOW_STATS_TX_FLOW_NO GENMASK(15, 0)
|
||||
#define HTT_MSDU_FLOW_STATS_TID_NUM GENMASK(19, 16)
|
||||
#define HTT_MSDU_FLOW_STATS_DROP_RULE BIT(20)
|
||||
|
||||
struct htt_msdu_flow_stats_tlv {
|
||||
u32 last_update_timestamp;
|
||||
u32 last_add_timestamp;
|
||||
|
|
@ -306,6 +320,11 @@ struct htt_msdu_flow_stats_tlv {
|
|||
|
||||
#define MAX_HTT_TID_NAME 8
|
||||
|
||||
#define HTT_TX_TID_STATS_SW_PEER_ID GENMASK(15, 0)
|
||||
#define HTT_TX_TID_STATS_TID_NUM GENMASK(31, 16)
|
||||
#define HTT_TX_TID_STATS_NUM_SCHED_PENDING GENMASK(7, 0)
|
||||
#define HTT_TX_TID_STATS_NUM_PPDU_IN_HWQ GENMASK(15, 8)
|
||||
|
||||
/* Tidq stats */
|
||||
struct htt_tx_tid_stats_tlv {
|
||||
/* Stored as little endian */
|
||||
|
|
@ -326,6 +345,11 @@ struct htt_tx_tid_stats_tlv {
|
|||
u32 tid_tx_airtime;
|
||||
};
|
||||
|
||||
#define HTT_TX_TID_STATS_V1_SW_PEER_ID GENMASK(15, 0)
|
||||
#define HTT_TX_TID_STATS_V1_TID_NUM GENMASK(31, 16)
|
||||
#define HTT_TX_TID_STATS_V1_NUM_SCHED_PENDING GENMASK(7, 0)
|
||||
#define HTT_TX_TID_STATS_V1_NUM_PPDU_IN_HWQ GENMASK(15, 8)
|
||||
|
||||
/* Tidq stats */
|
||||
struct htt_tx_tid_stats_v1_tlv {
|
||||
/* Stored as little endian */
|
||||
|
|
@ -348,6 +372,9 @@ struct htt_tx_tid_stats_v1_tlv {
|
|||
u32 sendn_frms_allowed;
|
||||
};
|
||||
|
||||
#define HTT_RX_TID_STATS_SW_PEER_ID GENMASK(15, 0)
|
||||
#define HTT_RX_TID_STATS_TID_NUM GENMASK(31, 16)
|
||||
|
||||
struct htt_rx_tid_stats_tlv {
|
||||
u32 sw_peer_id__tid_num;
|
||||
u8 tid_name[MAX_HTT_TID_NAME];
|
||||
|
|
@ -386,6 +413,10 @@ struct htt_peer_stats_cmn_tlv {
|
|||
u32 inactive_time;
|
||||
};
|
||||
|
||||
#define HTT_PEER_DETAILS_VDEV_ID GENMASK(7, 0)
|
||||
#define HTT_PEER_DETAILS_PDEV_ID GENMASK(15, 8)
|
||||
#define HTT_PEER_DETAILS_AST_IDX GENMASK(31, 16)
|
||||
|
||||
struct htt_peer_details_tlv {
|
||||
u32 peer_type;
|
||||
u32 sw_peer_id;
|
||||
|
|
@ -510,6 +541,9 @@ struct htt_tx_hwq_mu_mimo_mpdu_stats_tlv {
|
|||
u32 mu_mimo_ampdu_underrun_usr;
|
||||
};
|
||||
|
||||
#define HTT_TX_HWQ_STATS_MAC_ID GENMASK(7, 0)
|
||||
#define HTT_TX_HWQ_STATS_HWQ_ID GENMASK(15, 8)
|
||||
|
||||
struct htt_tx_hwq_mu_mimo_cmn_stats_tlv {
|
||||
u32 mac_id__hwq_id__word;
|
||||
};
|
||||
|
|
@ -789,6 +823,9 @@ struct htt_sched_txq_sched_ineligibility_tlv_v {
|
|||
u32 sched_ineligibility[0];
|
||||
};
|
||||
|
||||
#define HTT_TX_PDEV_STATS_SCHED_PER_TXQ_MAC_ID GENMASK(7, 0)
|
||||
#define HTT_TX_PDEV_STATS_SCHED_PER_TXQ_ID GENMASK(15, 8)
|
||||
|
||||
struct htt_tx_pdev_stats_sched_per_txq_tlv {
|
||||
u32 mac_id__txq_id__word;
|
||||
u32 sched_policy;
|
||||
|
|
@ -910,6 +947,9 @@ struct htt_tx_tqm_error_stats_tlv {
|
|||
};
|
||||
|
||||
/* == TQM CMDQ stats == */
|
||||
#define HTT_TX_TQM_CMDQ_STATUS_MAC_ID GENMASK(7, 0)
|
||||
#define HTT_TX_TQM_CMDQ_STATUS_CMDQ_ID GENMASK(15, 8)
|
||||
|
||||
struct htt_tx_tqm_cmdq_status_tlv {
|
||||
u32 mac_id__cmdq_id__word;
|
||||
u32 sync_cmd;
|
||||
|
|
@ -1055,6 +1095,15 @@ struct htt_tx_de_cmn_stats_tlv {
|
|||
#define HTT_STATS_LOW_WM_BINS 5
|
||||
#define HTT_STATS_HIGH_WM_BINS 5
|
||||
|
||||
#define HTT_RING_IF_STATS_NUM_ELEMS GENMASK(15, 0)
|
||||
#define HTT_RING_IF_STATS_PREFETCH_TAIL_INDEX GENMASK(31, 16)
|
||||
#define HTT_RING_IF_STATS_HEAD_IDX GENMASK(15, 0)
|
||||
#define HTT_RING_IF_STATS_TAIL_IDX GENMASK(31, 16)
|
||||
#define HTT_RING_IF_STATS_SHADOW_HEAD_IDX GENMASK(15, 0)
|
||||
#define HTT_RING_IF_STATS_SHADOW_TAIL_IDX GENMASK(31, 16)
|
||||
#define HTT_RING_IF_STATS_LWM_THRESH GENMASK(15, 0)
|
||||
#define HTT_RING_IF_STATS_HWM_THRESH GENMASK(31, 16)
|
||||
|
||||
struct htt_ring_if_stats_tlv {
|
||||
u32 base_addr; /* DWORD aligned base memory address of the ring */
|
||||
u32 elem_size;
|
||||
|
|
@ -1117,6 +1166,19 @@ struct htt_sfm_cmn_tlv {
|
|||
};
|
||||
|
||||
/* == SRNG STATS == */
|
||||
#define HTT_SRING_STATS_MAC_ID GENMASK(7, 0)
|
||||
#define HTT_SRING_STATS_RING_ID GENMASK(15, 8)
|
||||
#define HTT_SRING_STATS_ARENA GENMASK(23, 16)
|
||||
#define HTT_SRING_STATS_EP BIT(24)
|
||||
#define HTT_SRING_STATS_NUM_AVAIL_WORDS GENMASK(15, 0)
|
||||
#define HTT_SRING_STATS_NUM_VALID_WORDS GENMASK(31, 16)
|
||||
#define HTT_SRING_STATS_HEAD_PTR GENMASK(15, 0)
|
||||
#define HTT_SRING_STATS_TAIL_PTR GENMASK(31, 16)
|
||||
#define HTT_SRING_STATS_CONSUMER_EMPTY GENMASK(15, 0)
|
||||
#define HTT_SRING_STATS_PRODUCER_FULL GENMASK(31, 16)
|
||||
#define HTT_SRING_STATS_PREFETCH_COUNT GENMASK(15, 0)
|
||||
#define HTT_SRING_STATS_INTERNAL_TAIL_PTR GENMASK(31, 16)
|
||||
|
||||
struct htt_sring_stats_tlv {
|
||||
u32 mac_id__ring_id__arena__ep;
|
||||
u32 base_addr_lsb; /* DWORD aligned base memory address of the ring */
|
||||
|
|
@ -1696,6 +1758,170 @@ struct htt_ring_backpressure_stats_tlv {
|
|||
u32 backpressure_hist[5];
|
||||
};
|
||||
|
||||
#define HTT_TX_TXBF_RATE_STATS_NUM_MCS_COUNTERS 14
|
||||
#define HTT_TX_TXBF_RATE_STATS_NUM_BW_COUNTERS 5
|
||||
#define HTT_TX_PDEV_STATS_NUM_SPATIAL_STREAMS 8
|
||||
|
||||
struct htt_pdev_txrate_txbf_stats_tlv {
|
||||
/* SU TxBF TX MCS stats */
|
||||
u32 tx_su_txbf_mcs[HTT_TX_TXBF_RATE_STATS_NUM_MCS_COUNTERS];
|
||||
/* Implicit BF TX MCS stats */
|
||||
u32 tx_su_ibf_mcs[HTT_TX_TXBF_RATE_STATS_NUM_MCS_COUNTERS];
|
||||
/* Open loop TX MCS stats */
|
||||
u32 tx_su_ol_mcs[HTT_TX_TXBF_RATE_STATS_NUM_MCS_COUNTERS];
|
||||
/* SU TxBF TX NSS stats */
|
||||
u32 tx_su_txbf_nss[HTT_TX_PDEV_STATS_NUM_SPATIAL_STREAMS];
|
||||
/* Implicit BF TX NSS stats */
|
||||
u32 tx_su_ibf_nss[HTT_TX_PDEV_STATS_NUM_SPATIAL_STREAMS];
|
||||
/* Open loop TX NSS stats */
|
||||
u32 tx_su_ol_nss[HTT_TX_PDEV_STATS_NUM_SPATIAL_STREAMS];
|
||||
/* SU TxBF TX BW stats */
|
||||
u32 tx_su_txbf_bw[HTT_TX_TXBF_RATE_STATS_NUM_BW_COUNTERS];
|
||||
/* Implicit BF TX BW stats */
|
||||
u32 tx_su_ibf_bw[HTT_TX_TXBF_RATE_STATS_NUM_BW_COUNTERS];
|
||||
/* Open loop TX BW stats */
|
||||
u32 tx_su_ol_bw[HTT_TX_TXBF_RATE_STATS_NUM_BW_COUNTERS];
|
||||
};
|
||||
|
||||
struct htt_txbf_ofdma_ndpa_stats_tlv {
|
||||
/* 11AX HE OFDMA NDPA frame queued to the HW */
|
||||
u32 ax_ofdma_ndpa_queued[HTT_TX_PDEV_STATS_NUM_OFDMA_USER_STATS];
|
||||
/* 11AX HE OFDMA NDPA frame sent over the air */
|
||||
u32 ax_ofdma_ndpa_tried[HTT_TX_PDEV_STATS_NUM_OFDMA_USER_STATS];
|
||||
/* 11AX HE OFDMA NDPA frame flushed by HW */
|
||||
u32 ax_ofdma_ndpa_flushed[HTT_TX_PDEV_STATS_NUM_OFDMA_USER_STATS];
|
||||
/* 11AX HE OFDMA NDPA frame completed with error(s) */
|
||||
u32 ax_ofdma_ndpa_err[HTT_TX_PDEV_STATS_NUM_OFDMA_USER_STATS];
|
||||
};
|
||||
|
||||
struct htt_txbf_ofdma_ndp_stats_tlv {
|
||||
/* 11AX HE OFDMA NDP frame queued to the HW */
|
||||
u32 ax_ofdma_ndp_queued[HTT_TX_PDEV_STATS_NUM_OFDMA_USER_STATS];
|
||||
/* 11AX HE OFDMA NDPA frame sent over the air */
|
||||
u32 ax_ofdma_ndp_tried[HTT_TX_PDEV_STATS_NUM_OFDMA_USER_STATS];
|
||||
/* 11AX HE OFDMA NDPA frame flushed by HW */
|
||||
u32 ax_ofdma_ndp_flushed[HTT_TX_PDEV_STATS_NUM_OFDMA_USER_STATS];
|
||||
/* 11AX HE OFDMA NDPA frame completed with error(s) */
|
||||
u32 ax_ofdma_ndp_err[HTT_TX_PDEV_STATS_NUM_OFDMA_USER_STATS];
|
||||
};
|
||||
|
||||
struct htt_txbf_ofdma_brp_stats_tlv {
|
||||
/* 11AX HE OFDMA MU BRPOLL frame queued to the HW */
|
||||
u32 ax_ofdma_brpoll_queued[HTT_TX_PDEV_STATS_NUM_OFDMA_USER_STATS];
|
||||
/* 11AX HE OFDMA MU BRPOLL frame sent over the air */
|
||||
u32 ax_ofdma_brpoll_tried[HTT_TX_PDEV_STATS_NUM_OFDMA_USER_STATS];
|
||||
/* 11AX HE OFDMA MU BRPOLL frame flushed by HW */
|
||||
u32 ax_ofdma_brpoll_flushed[HTT_TX_PDEV_STATS_NUM_OFDMA_USER_STATS];
|
||||
/* 11AX HE OFDMA MU BRPOLL frame completed with error(s) */
|
||||
u32 ax_ofdma_brp_err[HTT_TX_PDEV_STATS_NUM_OFDMA_USER_STATS];
|
||||
/* Number of CBF(s) received when 11AX HE OFDMA MU BRPOLL frame
|
||||
* completed with error(s).
|
||||
*/
|
||||
u32 ax_ofdma_brp_err_num_cbf_rcvd[HTT_TX_PDEV_STATS_NUM_OFDMA_USER_STATS + 1];
|
||||
};
|
||||
|
||||
struct htt_txbf_ofdma_steer_stats_tlv {
|
||||
/* 11AX HE OFDMA PPDUs that were sent over the air with steering (TXBF + OFDMA) */
|
||||
u32 ax_ofdma_num_ppdu_steer[HTT_TX_PDEV_STATS_NUM_OFDMA_USER_STATS];
|
||||
/* 11AX HE OFDMA PPDUs that were sent over the air in open loop */
|
||||
u32 ax_ofdma_num_ppdu_ol[HTT_TX_PDEV_STATS_NUM_OFDMA_USER_STATS];
|
||||
/* 11AX HE OFDMA number of users for which CBF prefetch was
|
||||
* initiated to PHY HW during TX.
|
||||
*/
|
||||
u32 ax_ofdma_num_usrs_prefetch[HTT_TX_PDEV_STATS_NUM_OFDMA_USER_STATS];
|
||||
/* 11AX HE OFDMA number of users for which sounding was initiated during TX */
|
||||
u32 ax_ofdma_num_usrs_sound[HTT_TX_PDEV_STATS_NUM_OFDMA_USER_STATS];
|
||||
/* 11AX HE OFDMA number of users for which sounding was forced during TX */
|
||||
u32 ax_ofdma_num_usrs_force_sound[HTT_TX_PDEV_STATS_NUM_OFDMA_USER_STATS];
|
||||
};
|
||||
|
||||
#define HTT_MAX_RX_PKT_CNT 8
|
||||
#define HTT_MAX_RX_PKT_CRC_PASS_CNT 8
|
||||
#define HTT_MAX_PER_BLK_ERR_CNT 20
|
||||
#define HTT_MAX_RX_OTA_ERR_CNT 14
|
||||
#define HTT_STATS_MAX_CHAINS 8
|
||||
#define ATH11K_STATS_MGMT_FRM_TYPE_MAX 16
|
||||
|
||||
struct htt_phy_counters_tlv {
|
||||
/* number of RXTD OFDMA OTA error counts except power surge and drop */
|
||||
u32 rx_ofdma_timing_err_cnt;
|
||||
/* rx_cck_fail_cnt:
|
||||
* number of cck error counts due to rx reception failure because of
|
||||
* timing error in cck
|
||||
*/
|
||||
u32 rx_cck_fail_cnt;
|
||||
/* number of times tx abort initiated by mac */
|
||||
u32 mactx_abort_cnt;
|
||||
/* number of times rx abort initiated by mac */
|
||||
u32 macrx_abort_cnt;
|
||||
/* number of times tx abort initiated by phy */
|
||||
u32 phytx_abort_cnt;
|
||||
/* number of times rx abort initiated by phy */
|
||||
u32 phyrx_abort_cnt;
|
||||
/* number of rx defered count initiated by phy */
|
||||
u32 phyrx_defer_abort_cnt;
|
||||
/* number of sizing events generated at LSTF */
|
||||
u32 rx_gain_adj_lstf_event_cnt;
|
||||
/* number of sizing events generated at non-legacy LTF */
|
||||
u32 rx_gain_adj_non_legacy_cnt;
|
||||
/* rx_pkt_cnt -
|
||||
* Received EOP (end-of-packet) count per packet type;
|
||||
* [0] = 11a; [1] = 11b; [2] = 11n; [3] = 11ac; [4] = 11ax; [5] = GF
|
||||
* [6-7]=RSVD
|
||||
*/
|
||||
u32 rx_pkt_cnt[HTT_MAX_RX_PKT_CNT];
|
||||
/* rx_pkt_crc_pass_cnt -
|
||||
* Received EOP (end-of-packet) count per packet type;
|
||||
* [0] = 11a; [1] = 11b; [2] = 11n; [3] = 11ac; [4] = 11ax; [5] = GF
|
||||
* [6-7]=RSVD
|
||||
*/
|
||||
u32 rx_pkt_crc_pass_cnt[HTT_MAX_RX_PKT_CRC_PASS_CNT];
|
||||
/* per_blk_err_cnt -
|
||||
* Error count per error source;
|
||||
* [0] = unknown; [1] = LSIG; [2] = HTSIG; [3] = VHTSIG; [4] = HESIG;
|
||||
* [5] = RXTD_OTA; [6] = RXTD_FATAL; [7] = DEMF; [8] = ROBE;
|
||||
* [9] = PMI; [10] = TXFD; [11] = TXTD; [12] = PHYRF
|
||||
* [13-19]=RSVD
|
||||
*/
|
||||
u32 per_blk_err_cnt[HTT_MAX_PER_BLK_ERR_CNT];
|
||||
/* rx_ota_err_cnt -
|
||||
* RXTD OTA (over-the-air) error count per error reason;
|
||||
* [0] = voting fail; [1] = weak det fail; [2] = strong sig fail;
|
||||
* [3] = cck fail; [4] = power surge; [5] = power drop;
|
||||
* [6] = btcf timing timeout error; [7] = btcf packet detect error;
|
||||
* [8] = coarse timing timeout error
|
||||
* [9-13]=RSVD
|
||||
*/
|
||||
u32 rx_ota_err_cnt[HTT_MAX_RX_OTA_ERR_CNT];
|
||||
};
|
||||
|
||||
struct htt_phy_stats_tlv {
|
||||
/* per chain hw noise floor values in dBm */
|
||||
s32 nf_chain[HTT_STATS_MAX_CHAINS];
|
||||
/* number of false radars detected */
|
||||
u32 false_radar_cnt;
|
||||
/* number of channel switches happened due to radar detection */
|
||||
u32 radar_cs_cnt;
|
||||
/* ani_level -
|
||||
* ANI level (noise interference) corresponds to the channel
|
||||
* the desense levels range from -5 to 15 in dB units,
|
||||
* higher values indicating more noise interference.
|
||||
*/
|
||||
s32 ani_level;
|
||||
/* running time in minutes since FW boot */
|
||||
u32 fw_run_time;
|
||||
};
|
||||
|
||||
struct htt_peer_ctrl_path_txrx_stats_tlv {
|
||||
/* peer mac address */
|
||||
u8 peer_mac_addr[ETH_ALEN];
|
||||
u8 rsvd[2];
|
||||
/* Num of tx mgmt frames with subtype on peer level */
|
||||
u32 peer_tx_mgmt_subtype[ATH11K_STATS_MGMT_FRM_TYPE_MAX];
|
||||
/* Num of rx mgmt frames with subtype on peer level */
|
||||
u32 peer_rx_mgmt_subtype[ATH11K_STATS_MGMT_FRM_TYPE_MAX];
|
||||
};
|
||||
|
||||
#ifdef CONFIG_ATH11K_DEBUGFS
|
||||
|
||||
void ath11k_debugfs_htt_stats_init(struct ath11k *ar);
|
||||
|
|
|
|||
|
|
@ -419,15 +419,21 @@ ath11k_dbg_sta_open_htt_peer_stats(struct inode *inode, struct file *file)
|
|||
struct ath11k_sta *arsta = (struct ath11k_sta *)sta->drv_priv;
|
||||
struct ath11k *ar = arsta->arvif->ar;
|
||||
struct debug_htt_stats_req *stats_req;
|
||||
int type = ar->debug.htt_stats.type;
|
||||
int ret;
|
||||
|
||||
if ((type != ATH11K_DBG_HTT_EXT_STATS_PEER_INFO &&
|
||||
type != ATH11K_DBG_HTT_EXT_STATS_PEER_CTRL_PATH_TXRX_STATS) ||
|
||||
type == ATH11K_DBG_HTT_EXT_STATS_RESET)
|
||||
return -EPERM;
|
||||
|
||||
stats_req = vzalloc(sizeof(*stats_req) + ATH11K_HTT_STATS_BUF_SIZE);
|
||||
if (!stats_req)
|
||||
return -ENOMEM;
|
||||
|
||||
mutex_lock(&ar->conf_mutex);
|
||||
ar->debug.htt_stats.stats_req = stats_req;
|
||||
stats_req->type = ATH11K_DBG_HTT_EXT_STATS_PEER_INFO;
|
||||
stats_req->type = type;
|
||||
memcpy(stats_req->peer_addr, sta->addr, ETH_ALEN);
|
||||
ret = ath11k_debugfs_htt_stats_req(ar);
|
||||
mutex_unlock(&ar->conf_mutex);
|
||||
|
|
|
|||
|
|
@ -195,6 +195,7 @@ struct ath11k_pdev_dp {
|
|||
#define DP_RXDMA_MONITOR_DESC_RING_SIZE 4096
|
||||
|
||||
#define DP_RX_BUFFER_SIZE 2048
|
||||
#define DP_RX_BUFFER_SIZE_LITE 1024
|
||||
#define DP_RX_BUFFER_ALIGN_SIZE 128
|
||||
|
||||
#define DP_RXDMA_BUF_COOKIE_BUF_ID GENMASK(17, 0)
|
||||
|
|
@ -1592,6 +1593,13 @@ struct ath11k_htt_extd_stats_msg {
|
|||
u8 data[0];
|
||||
} __packed;
|
||||
|
||||
#define HTT_MAC_ADDR_L32_0 GENMASK(7, 0)
|
||||
#define HTT_MAC_ADDR_L32_1 GENMASK(15, 8)
|
||||
#define HTT_MAC_ADDR_L32_2 GENMASK(23, 16)
|
||||
#define HTT_MAC_ADDR_L32_3 GENMASK(31, 24)
|
||||
#define HTT_MAC_ADDR_H16_0 GENMASK(7, 0)
|
||||
#define HTT_MAC_ADDR_H16_1 GENMASK(15, 8)
|
||||
|
||||
struct htt_mac_addr {
|
||||
u32 mac_addr_l32;
|
||||
u32 mac_addr_h16;
|
||||
|
|
|
|||
|
|
@ -142,6 +142,18 @@ static u32 ath11k_dp_rx_h_attn_mpdu_err(struct rx_attention *attn)
|
|||
return errmap;
|
||||
}
|
||||
|
||||
static bool ath11k_dp_rx_h_attn_msdu_len_err(struct ath11k_base *ab,
|
||||
struct hal_rx_desc *desc)
|
||||
{
|
||||
struct rx_attention *rx_attention;
|
||||
u32 errmap;
|
||||
|
||||
rx_attention = ath11k_dp_rx_get_attention(ab, desc);
|
||||
errmap = ath11k_dp_rx_h_attn_mpdu_err(rx_attention);
|
||||
|
||||
return errmap & DP_RX_MPDU_ERR_MSDU_LEN;
|
||||
}
|
||||
|
||||
static u16 ath11k_dp_rx_h_msdu_start_msdu_len(struct ath11k_base *ab,
|
||||
struct hal_rx_desc *desc)
|
||||
{
|
||||
|
|
@ -270,6 +282,18 @@ static bool ath11k_dp_rx_h_attn_is_mcbc(struct ath11k_base *ab,
|
|||
__le32_to_cpu(attn->info1)));
|
||||
}
|
||||
|
||||
static bool ath11k_dp_rxdesc_mac_addr2_valid(struct ath11k_base *ab,
|
||||
struct hal_rx_desc *desc)
|
||||
{
|
||||
return ab->hw_params.hw_ops->rx_desc_mac_addr2_valid(desc);
|
||||
}
|
||||
|
||||
static u8 *ath11k_dp_rxdesc_mpdu_start_addr2(struct ath11k_base *ab,
|
||||
struct hal_rx_desc *desc)
|
||||
{
|
||||
return ab->hw_params.hw_ops->rx_desc_mpdu_start_addr2(desc);
|
||||
}
|
||||
|
||||
static void ath11k_dp_service_mon_ring(struct timer_list *t)
|
||||
{
|
||||
struct ath11k_base *ab = from_timer(ab, t, mon_reap_timer);
|
||||
|
|
@ -2156,6 +2180,7 @@ static void ath11k_dp_rx_h_undecap(struct ath11k *ar, struct sk_buff *msdu,
|
|||
{
|
||||
u8 *first_hdr;
|
||||
u8 decap;
|
||||
struct ethhdr *ehdr;
|
||||
|
||||
first_hdr = ath11k_dp_rx_h_80211_hdr(ar->ab, rx_desc);
|
||||
decap = ath11k_dp_rx_h_msdu_start_decap_type(ar->ab, rx_desc);
|
||||
|
|
@ -2170,9 +2195,22 @@ static void ath11k_dp_rx_h_undecap(struct ath11k *ar, struct sk_buff *msdu,
|
|||
decrypted);
|
||||
break;
|
||||
case DP_RX_DECAP_TYPE_ETHERNET2_DIX:
|
||||
/* TODO undecap support for middle/last msdu's of amsdu */
|
||||
ath11k_dp_rx_h_undecap_eth(ar, msdu, first_hdr,
|
||||
enctype, status);
|
||||
ehdr = (struct ethhdr *)msdu->data;
|
||||
|
||||
/* mac80211 allows fast path only for authorized STA */
|
||||
if (ehdr->h_proto == cpu_to_be16(ETH_P_PAE)) {
|
||||
ATH11K_SKB_RXCB(msdu)->is_eapol = true;
|
||||
ath11k_dp_rx_h_undecap_eth(ar, msdu, first_hdr,
|
||||
enctype, status);
|
||||
break;
|
||||
}
|
||||
|
||||
/* PN for mcast packets will be validated in mac80211;
|
||||
* remove eth header and add 802.11 header.
|
||||
*/
|
||||
if (ATH11K_SKB_RXCB(msdu)->is_mcbc && decrypted)
|
||||
ath11k_dp_rx_h_undecap_eth(ar, msdu, first_hdr,
|
||||
enctype, status);
|
||||
break;
|
||||
case DP_RX_DECAP_TYPE_8023:
|
||||
/* TODO: Handle undecap for these formats */
|
||||
|
|
@ -2180,35 +2218,62 @@ static void ath11k_dp_rx_h_undecap(struct ath11k *ar, struct sk_buff *msdu,
|
|||
}
|
||||
}
|
||||
|
||||
static struct ath11k_peer *
|
||||
ath11k_dp_rx_h_find_peer(struct ath11k_base *ab, struct sk_buff *msdu)
|
||||
{
|
||||
struct ath11k_skb_rxcb *rxcb = ATH11K_SKB_RXCB(msdu);
|
||||
struct hal_rx_desc *rx_desc = rxcb->rx_desc;
|
||||
struct ath11k_peer *peer = NULL;
|
||||
|
||||
lockdep_assert_held(&ab->base_lock);
|
||||
|
||||
if (rxcb->peer_id)
|
||||
peer = ath11k_peer_find_by_id(ab, rxcb->peer_id);
|
||||
|
||||
if (peer)
|
||||
return peer;
|
||||
|
||||
if (!rx_desc || !(ath11k_dp_rxdesc_mac_addr2_valid(ab, rx_desc)))
|
||||
return NULL;
|
||||
|
||||
peer = ath11k_peer_find_by_addr(ab,
|
||||
ath11k_dp_rxdesc_mpdu_start_addr2(ab, rx_desc));
|
||||
return peer;
|
||||
}
|
||||
|
||||
static void ath11k_dp_rx_h_mpdu(struct ath11k *ar,
|
||||
struct sk_buff *msdu,
|
||||
struct hal_rx_desc *rx_desc,
|
||||
struct ieee80211_rx_status *rx_status)
|
||||
{
|
||||
bool fill_crypto_hdr, mcast;
|
||||
bool fill_crypto_hdr;
|
||||
enum hal_encrypt_type enctype;
|
||||
bool is_decrypted = false;
|
||||
struct ath11k_skb_rxcb *rxcb;
|
||||
struct ieee80211_hdr *hdr;
|
||||
struct ath11k_peer *peer;
|
||||
struct rx_attention *rx_attention;
|
||||
u32 err_bitmap;
|
||||
|
||||
hdr = (struct ieee80211_hdr *)msdu->data;
|
||||
|
||||
/* PN for multicast packets will be checked in mac80211 */
|
||||
rxcb = ATH11K_SKB_RXCB(msdu);
|
||||
fill_crypto_hdr = ath11k_dp_rx_h_attn_is_mcbc(ar->ab, rx_desc);
|
||||
rxcb->is_mcbc = fill_crypto_hdr;
|
||||
|
||||
mcast = is_multicast_ether_addr(hdr->addr1);
|
||||
fill_crypto_hdr = mcast;
|
||||
if (rxcb->is_mcbc) {
|
||||
rxcb->peer_id = ath11k_dp_rx_h_mpdu_start_peer_id(ar->ab, rx_desc);
|
||||
rxcb->seq_no = ath11k_dp_rx_h_mpdu_start_seq_no(ar->ab, rx_desc);
|
||||
}
|
||||
|
||||
spin_lock_bh(&ar->ab->base_lock);
|
||||
peer = ath11k_peer_find_by_addr(ar->ab, hdr->addr2);
|
||||
peer = ath11k_dp_rx_h_find_peer(ar->ab, msdu);
|
||||
if (peer) {
|
||||
if (mcast)
|
||||
if (rxcb->is_mcbc)
|
||||
enctype = peer->sec_type_grp;
|
||||
else
|
||||
enctype = peer->sec_type;
|
||||
} else {
|
||||
enctype = HAL_ENCRYPT_TYPE_OPEN;
|
||||
enctype = ath11k_dp_rx_h_mpdu_start_enctype(ar->ab, rx_desc);
|
||||
}
|
||||
spin_unlock_bh(&ar->ab->base_lock);
|
||||
|
||||
|
|
@ -2247,8 +2312,11 @@ static void ath11k_dp_rx_h_mpdu(struct ath11k *ar,
|
|||
if (!is_decrypted || fill_crypto_hdr)
|
||||
return;
|
||||
|
||||
hdr = (void *)msdu->data;
|
||||
hdr->frame_control &= ~__cpu_to_le16(IEEE80211_FCTL_PROTECTED);
|
||||
if (ath11k_dp_rx_h_msdu_start_decap_type(ar->ab, rx_desc) !=
|
||||
DP_RX_DECAP_TYPE_ETHERNET2_DIX) {
|
||||
hdr = (void *)msdu->data;
|
||||
hdr->frame_control &= ~__cpu_to_le16(IEEE80211_FCTL_PROTECTED);
|
||||
}
|
||||
}
|
||||
|
||||
static void ath11k_dp_rx_h_rate(struct ath11k *ar, struct hal_rx_desc *rx_desc,
|
||||
|
|
@ -2337,8 +2405,10 @@ static void ath11k_dp_rx_h_ppdu(struct ath11k *ar, struct hal_rx_desc *rx_desc,
|
|||
channel_num = meta_data;
|
||||
center_freq = meta_data >> 16;
|
||||
|
||||
if (center_freq >= 5935 && center_freq <= 7105) {
|
||||
if (center_freq >= ATH11K_MIN_6G_FREQ &&
|
||||
center_freq <= ATH11K_MAX_6G_FREQ) {
|
||||
rx_status->band = NL80211_BAND_6GHZ;
|
||||
rx_status->freq = center_freq;
|
||||
} else if (channel_num >= 1 && channel_num <= 14) {
|
||||
rx_status->band = NL80211_BAND_2GHZ;
|
||||
} else if (channel_num >= 36 && channel_num <= 173) {
|
||||
|
|
@ -2356,57 +2426,56 @@ static void ath11k_dp_rx_h_ppdu(struct ath11k *ar, struct hal_rx_desc *rx_desc,
|
|||
rx_desc, sizeof(struct hal_rx_desc));
|
||||
}
|
||||
|
||||
rx_status->freq = ieee80211_channel_to_frequency(channel_num,
|
||||
rx_status->band);
|
||||
if (rx_status->band != NL80211_BAND_6GHZ)
|
||||
rx_status->freq = ieee80211_channel_to_frequency(channel_num,
|
||||
rx_status->band);
|
||||
|
||||
ath11k_dp_rx_h_rate(ar, rx_desc, rx_status);
|
||||
}
|
||||
|
||||
static char *ath11k_print_get_tid(struct ieee80211_hdr *hdr, char *out,
|
||||
size_t size)
|
||||
{
|
||||
u8 *qc;
|
||||
int tid;
|
||||
|
||||
if (!ieee80211_is_data_qos(hdr->frame_control))
|
||||
return "";
|
||||
|
||||
qc = ieee80211_get_qos_ctl(hdr);
|
||||
tid = *qc & IEEE80211_QOS_CTL_TID_MASK;
|
||||
snprintf(out, size, "tid %d", tid);
|
||||
|
||||
return out;
|
||||
}
|
||||
|
||||
static void ath11k_dp_rx_deliver_msdu(struct ath11k *ar, struct napi_struct *napi,
|
||||
struct sk_buff *msdu)
|
||||
struct sk_buff *msdu,
|
||||
struct ieee80211_rx_status *status)
|
||||
{
|
||||
static const struct ieee80211_radiotap_he known = {
|
||||
.data1 = cpu_to_le16(IEEE80211_RADIOTAP_HE_DATA1_DATA_MCS_KNOWN |
|
||||
IEEE80211_RADIOTAP_HE_DATA1_BW_RU_ALLOC_KNOWN),
|
||||
.data2 = cpu_to_le16(IEEE80211_RADIOTAP_HE_DATA2_GI_KNOWN),
|
||||
};
|
||||
struct ieee80211_rx_status *status;
|
||||
struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)msdu->data;
|
||||
struct ieee80211_rx_status *rx_status;
|
||||
struct ieee80211_radiotap_he *he = NULL;
|
||||
char tid[32];
|
||||
struct ieee80211_sta *pubsta = NULL;
|
||||
struct ath11k_peer *peer;
|
||||
struct ath11k_skb_rxcb *rxcb = ATH11K_SKB_RXCB(msdu);
|
||||
u8 decap = DP_RX_DECAP_TYPE_RAW;
|
||||
bool is_mcbc = rxcb->is_mcbc;
|
||||
bool is_eapol = rxcb->is_eapol;
|
||||
|
||||
status = IEEE80211_SKB_RXCB(msdu);
|
||||
if (status->encoding == RX_ENC_HE) {
|
||||
if (status->encoding == RX_ENC_HE &&
|
||||
!(status->flag & RX_FLAG_RADIOTAP_HE) &&
|
||||
!(status->flag & RX_FLAG_SKIP_MONITOR)) {
|
||||
he = skb_push(msdu, sizeof(known));
|
||||
memcpy(he, &known, sizeof(known));
|
||||
status->flag |= RX_FLAG_RADIOTAP_HE;
|
||||
}
|
||||
|
||||
if (!(status->flag & RX_FLAG_ONLY_MONITOR))
|
||||
decap = ath11k_dp_rx_h_msdu_start_decap_type(ar->ab, rxcb->rx_desc);
|
||||
|
||||
spin_lock_bh(&ar->ab->base_lock);
|
||||
peer = ath11k_dp_rx_h_find_peer(ar->ab, msdu);
|
||||
if (peer && peer->sta)
|
||||
pubsta = peer->sta;
|
||||
spin_unlock_bh(&ar->ab->base_lock);
|
||||
|
||||
ath11k_dbg(ar->ab, ATH11K_DBG_DATA,
|
||||
"rx skb %pK len %u peer %pM %s %s sn %u %s%s%s%s%s%s%s %srate_idx %u vht_nss %u freq %u band %u flag 0x%x fcs-err %i mic-err %i amsdu-more %i\n",
|
||||
"rx skb %pK len %u peer %pM %d %s sn %u %s%s%s%s%s%s%s %srate_idx %u vht_nss %u freq %u band %u flag 0x%x fcs-err %i mic-err %i amsdu-more %i\n",
|
||||
msdu,
|
||||
msdu->len,
|
||||
ieee80211_get_SA(hdr),
|
||||
ath11k_print_get_tid(hdr, tid, sizeof(tid)),
|
||||
is_multicast_ether_addr(ieee80211_get_DA(hdr)) ?
|
||||
"mcast" : "ucast",
|
||||
(__le16_to_cpu(hdr->seq_ctrl) & IEEE80211_SCTL_SEQ) >> 4,
|
||||
peer ? peer->addr : NULL,
|
||||
rxcb->tid,
|
||||
is_mcbc ? "mcast" : "ucast",
|
||||
rxcb->seq_no,
|
||||
(status->encoding == RX_ENC_LEGACY) ? "legacy" : "",
|
||||
(status->encoding == RX_ENC_HT) ? "ht" : "",
|
||||
(status->encoding == RX_ENC_VHT) ? "vht" : "",
|
||||
|
|
@ -2426,22 +2495,32 @@ static void ath11k_dp_rx_deliver_msdu(struct ath11k *ar, struct napi_struct *nap
|
|||
ath11k_dbg_dump(ar->ab, ATH11K_DBG_DP_RX, NULL, "dp rx msdu: ",
|
||||
msdu->data, msdu->len);
|
||||
|
||||
rx_status = IEEE80211_SKB_RXCB(msdu);
|
||||
*rx_status = *status;
|
||||
|
||||
/* TODO: trace rx packet */
|
||||
|
||||
ieee80211_rx_napi(ar->hw, NULL, msdu, napi);
|
||||
/* PN for multicast packets are not validate in HW,
|
||||
* so skip 802.3 rx path
|
||||
* Also, fast_rx expectes the STA to be authorized, hence
|
||||
* eapol packets are sent in slow path.
|
||||
*/
|
||||
if (decap == DP_RX_DECAP_TYPE_ETHERNET2_DIX && !is_eapol &&
|
||||
!(is_mcbc && rx_status->flag & RX_FLAG_DECRYPTED))
|
||||
rx_status->flag |= RX_FLAG_8023;
|
||||
|
||||
ieee80211_rx_napi(ar->hw, pubsta, msdu, napi);
|
||||
}
|
||||
|
||||
static int ath11k_dp_rx_process_msdu(struct ath11k *ar,
|
||||
struct sk_buff *msdu,
|
||||
struct sk_buff_head *msdu_list)
|
||||
struct sk_buff_head *msdu_list,
|
||||
struct ieee80211_rx_status *rx_status)
|
||||
{
|
||||
struct ath11k_base *ab = ar->ab;
|
||||
struct hal_rx_desc *rx_desc, *lrx_desc;
|
||||
struct rx_attention *rx_attention;
|
||||
struct ieee80211_rx_status rx_status = {0};
|
||||
struct ieee80211_rx_status *status;
|
||||
struct ath11k_skb_rxcb *rxcb;
|
||||
struct ieee80211_hdr *hdr;
|
||||
struct sk_buff *last_buf;
|
||||
u8 l3_pad_bytes;
|
||||
u8 *hdr_status;
|
||||
|
|
@ -2458,6 +2537,12 @@ static int ath11k_dp_rx_process_msdu(struct ath11k *ar,
|
|||
}
|
||||
|
||||
rx_desc = (struct hal_rx_desc *)msdu->data;
|
||||
if (ath11k_dp_rx_h_attn_msdu_len_err(ab, rx_desc)) {
|
||||
ath11k_warn(ar->ab, "msdu len not valid\n");
|
||||
ret = -EIO;
|
||||
goto free_out;
|
||||
}
|
||||
|
||||
lrx_desc = (struct hal_rx_desc *)last_buf->data;
|
||||
rx_attention = ath11k_dp_rx_get_attention(ab, lrx_desc);
|
||||
if (!ath11k_dp_rx_h_attn_msdu_done(rx_attention)) {
|
||||
|
|
@ -2497,19 +2582,11 @@ static int ath11k_dp_rx_process_msdu(struct ath11k *ar,
|
|||
}
|
||||
}
|
||||
|
||||
hdr = (struct ieee80211_hdr *)msdu->data;
|
||||
ath11k_dp_rx_h_ppdu(ar, rx_desc, rx_status);
|
||||
ath11k_dp_rx_h_mpdu(ar, msdu, rx_desc, rx_status);
|
||||
|
||||
/* Process only data frames */
|
||||
if (!ieee80211_is_data(hdr->frame_control))
|
||||
return -EINVAL;
|
||||
rx_status->flag |= RX_FLAG_SKIP_MONITOR | RX_FLAG_DUP_VALIDATED;
|
||||
|
||||
ath11k_dp_rx_h_ppdu(ar, rx_desc, &rx_status);
|
||||
ath11k_dp_rx_h_mpdu(ar, msdu, rx_desc, &rx_status);
|
||||
|
||||
rx_status.flag |= RX_FLAG_SKIP_MONITOR | RX_FLAG_DUP_VALIDATED;
|
||||
|
||||
status = IEEE80211_SKB_RXCB(msdu);
|
||||
*status = rx_status;
|
||||
return 0;
|
||||
|
||||
free_out:
|
||||
|
|
@ -2524,6 +2601,7 @@ static void ath11k_dp_rx_process_received_packets(struct ath11k_base *ab,
|
|||
struct ath11k_skb_rxcb *rxcb;
|
||||
struct sk_buff *msdu;
|
||||
struct ath11k *ar;
|
||||
struct ieee80211_rx_status rx_status = {0};
|
||||
u8 mac_id;
|
||||
int ret;
|
||||
|
||||
|
|
@ -2546,7 +2624,7 @@ static void ath11k_dp_rx_process_received_packets(struct ath11k_base *ab,
|
|||
continue;
|
||||
}
|
||||
|
||||
ret = ath11k_dp_rx_process_msdu(ar, msdu, msdu_list);
|
||||
ret = ath11k_dp_rx_process_msdu(ar, msdu, msdu_list, &rx_status);
|
||||
if (ret) {
|
||||
ath11k_dbg(ab, ATH11K_DBG_DATA,
|
||||
"Unable to process msdu %d", ret);
|
||||
|
|
@ -2554,7 +2632,7 @@ static void ath11k_dp_rx_process_received_packets(struct ath11k_base *ab,
|
|||
continue;
|
||||
}
|
||||
|
||||
ath11k_dp_rx_deliver_msdu(ar, napi, msdu);
|
||||
ath11k_dp_rx_deliver_msdu(ar, napi, msdu, &rx_status);
|
||||
(*quota)--;
|
||||
}
|
||||
|
||||
|
|
@ -2636,10 +2714,14 @@ int ath11k_dp_process_rx(struct ath11k_base *ab, int ring_id,
|
|||
RX_MSDU_DESC_INFO0_LAST_MSDU_IN_MPDU);
|
||||
rxcb->is_continuation = !!(desc.rx_msdu_info.info0 &
|
||||
RX_MSDU_DESC_INFO0_MSDU_CONTINUATION);
|
||||
rxcb->mac_id = mac_id;
|
||||
rxcb->peer_id = FIELD_GET(RX_MPDU_DESC_META_DATA_PEER_ID,
|
||||
desc.rx_mpdu_info.meta_data);
|
||||
rxcb->seq_no = FIELD_GET(RX_MPDU_DESC_INFO0_SEQ_NUM,
|
||||
desc.rx_mpdu_info.info0);
|
||||
rxcb->tid = FIELD_GET(HAL_REO_DEST_RING_INFO0_RX_QUEUE_NUM,
|
||||
desc.info0);
|
||||
|
||||
rxcb->mac_id = mac_id;
|
||||
__skb_queue_tail(&msdu_list, msdu);
|
||||
|
||||
if (total_msdu_reaped >= quota && !rxcb->is_continuation) {
|
||||
|
|
@ -2969,6 +3051,8 @@ int ath11k_dp_rx_process_mon_status(struct ath11k_base *ab, int mac_id,
|
|||
struct ath11k_peer *peer;
|
||||
struct ath11k_sta *arsta;
|
||||
int num_buffs_reaped = 0;
|
||||
u32 rx_buf_sz;
|
||||
u16 log_type = 0;
|
||||
|
||||
__skb_queue_head_init(&skb_list);
|
||||
|
||||
|
|
@ -2981,8 +3065,16 @@ int ath11k_dp_rx_process_mon_status(struct ath11k_base *ab, int mac_id,
|
|||
memset(&ppdu_info, 0, sizeof(ppdu_info));
|
||||
ppdu_info.peer_id = HAL_INVALID_PEERID;
|
||||
|
||||
if (ath11k_debugfs_is_pktlog_rx_stats_enabled(ar))
|
||||
trace_ath11k_htt_rxdesc(ar, skb->data, DP_RX_BUFFER_SIZE);
|
||||
if (ath11k_debugfs_is_pktlog_lite_mode_enabled(ar)) {
|
||||
log_type = ATH11K_PKTLOG_TYPE_LITE_RX;
|
||||
rx_buf_sz = DP_RX_BUFFER_SIZE_LITE;
|
||||
} else if (ath11k_debugfs_is_pktlog_rx_stats_enabled(ar)) {
|
||||
log_type = ATH11K_PKTLOG_TYPE_RX_STATBUF;
|
||||
rx_buf_sz = DP_RX_BUFFER_SIZE;
|
||||
}
|
||||
|
||||
if (log_type)
|
||||
trace_ath11k_htt_rxdesc(ar, skb->data, log_type, rx_buf_sz);
|
||||
|
||||
hal_status = ath11k_hal_rx_parse_mon_status(ab, &ppdu_info, skb);
|
||||
|
||||
|
|
@ -3010,7 +3102,7 @@ int ath11k_dp_rx_process_mon_status(struct ath11k_base *ab, int mac_id,
|
|||
ath11k_dp_rx_update_peer_stats(arsta, &ppdu_info);
|
||||
|
||||
if (ath11k_debugfs_is_pktlog_peer_valid(ar, peer->addr))
|
||||
trace_ath11k_htt_rxdesc(ar, skb->data, DP_RX_BUFFER_SIZE);
|
||||
trace_ath11k_htt_rxdesc(ar, skb->data, log_type, rx_buf_sz);
|
||||
|
||||
spin_unlock_bh(&ab->base_lock);
|
||||
rcu_read_unlock();
|
||||
|
|
@ -3310,7 +3402,7 @@ static int ath11k_dp_rx_h_defrag_reo_reinject(struct ath11k *ar, struct dp_rx_ti
|
|||
|
||||
paddr = dma_map_single(ab->dev, defrag_skb->data,
|
||||
defrag_skb->len + skb_tailroom(defrag_skb),
|
||||
DMA_FROM_DEVICE);
|
||||
DMA_TO_DEVICE);
|
||||
if (dma_mapping_error(ab->dev, paddr))
|
||||
return -ENOMEM;
|
||||
|
||||
|
|
@ -3375,7 +3467,7 @@ static int ath11k_dp_rx_h_defrag_reo_reinject(struct ath11k *ar, struct dp_rx_ti
|
|||
spin_unlock_bh(&rx_refill_ring->idr_lock);
|
||||
err_unmap_dma:
|
||||
dma_unmap_single(ab->dev, paddr, defrag_skb->len + skb_tailroom(defrag_skb),
|
||||
DMA_FROM_DEVICE);
|
||||
DMA_TO_DEVICE);
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
|
@ -3941,7 +4033,6 @@ static void ath11k_dp_rx_wbm_err(struct ath11k *ar,
|
|||
{
|
||||
struct ath11k_skb_rxcb *rxcb = ATH11K_SKB_RXCB(msdu);
|
||||
struct ieee80211_rx_status rxs = {0};
|
||||
struct ieee80211_rx_status *status;
|
||||
bool drop = true;
|
||||
|
||||
switch (rxcb->err_rel_src) {
|
||||
|
|
@ -3961,10 +4052,7 @@ static void ath11k_dp_rx_wbm_err(struct ath11k *ar,
|
|||
return;
|
||||
}
|
||||
|
||||
status = IEEE80211_SKB_RXCB(msdu);
|
||||
*status = rxs;
|
||||
|
||||
ath11k_dp_rx_deliver_msdu(ar, napi, msdu);
|
||||
ath11k_dp_rx_deliver_msdu(ar, napi, msdu, &rxs);
|
||||
}
|
||||
|
||||
int ath11k_dp_rx_process_wbm_err(struct ath11k_base *ab,
|
||||
|
|
@ -4848,7 +4936,7 @@ static int ath11k_dp_rx_mon_deliver(struct ath11k *ar, u32 mac_id,
|
|||
{
|
||||
struct ath11k_pdev_dp *dp = &ar->dp;
|
||||
struct sk_buff *mon_skb, *skb_next, *header;
|
||||
struct ieee80211_rx_status *rxs = &dp->rx_status, *status;
|
||||
struct ieee80211_rx_status *rxs = &dp->rx_status;
|
||||
|
||||
mon_skb = ath11k_dp_rx_mon_merg_msdus(ar, mac_id, head_msdu,
|
||||
tail_msdu, rxs);
|
||||
|
|
@ -4874,10 +4962,7 @@ static int ath11k_dp_rx_mon_deliver(struct ath11k *ar, u32 mac_id,
|
|||
}
|
||||
rxs->flag |= RX_FLAG_ONLY_MONITOR;
|
||||
|
||||
status = IEEE80211_SKB_RXCB(mon_skb);
|
||||
*status = *rxs;
|
||||
|
||||
ath11k_dp_rx_deliver_msdu(ar, napi, mon_skb);
|
||||
ath11k_dp_rx_deliver_msdu(ar, napi, mon_skb, rxs);
|
||||
mon_skb = skb_next;
|
||||
} while (mon_skb);
|
||||
rxs->flag = 0;
|
||||
|
|
@ -5029,7 +5114,7 @@ int ath11k_dp_rx_process_mon_rings(struct ath11k_base *ab, int mac_id,
|
|||
struct ath11k *ar = ath11k_ab_to_ar(ab, mac_id);
|
||||
int ret = 0;
|
||||
|
||||
if (test_bit(ATH11K_FLAG_MONITOR_ENABLED, &ar->monitor_flags))
|
||||
if (test_bit(ATH11K_FLAG_MONITOR_STARTED, &ar->monitor_flags))
|
||||
ret = ath11k_dp_mon_process_rx(ab, mac_id, napi, budget);
|
||||
else
|
||||
ret = ath11k_dp_rx_process_mon_status(ab, mac_id, napi, budget);
|
||||
|
|
|
|||
|
|
@ -78,7 +78,7 @@ enum hal_encrypt_type ath11k_dp_tx_get_encrypt_type(u32 cipher)
|
|||
}
|
||||
|
||||
int ath11k_dp_tx(struct ath11k *ar, struct ath11k_vif *arvif,
|
||||
struct sk_buff *skb)
|
||||
struct ath11k_sta *arsta, struct sk_buff *skb)
|
||||
{
|
||||
struct ath11k_base *ab = ar->ab;
|
||||
struct ath11k_dp *dp = &ab->dp;
|
||||
|
|
@ -145,7 +145,15 @@ int ath11k_dp_tx(struct ath11k *ar, struct ath11k_vif *arvif,
|
|||
FIELD_PREP(DP_TX_DESC_ID_MSDU_ID, ret) |
|
||||
FIELD_PREP(DP_TX_DESC_ID_POOL_ID, pool_id);
|
||||
ti.encap_type = ath11k_dp_tx_get_encap_type(arvif, skb);
|
||||
ti.meta_data_flags = arvif->tcl_metadata;
|
||||
|
||||
if (ieee80211_has_a4(hdr->frame_control) &&
|
||||
is_multicast_ether_addr(hdr->addr3) && arsta &&
|
||||
arsta->use_4addr_set) {
|
||||
ti.meta_data_flags = arsta->tcl_metadata;
|
||||
ti.flags0 |= FIELD_PREP(HAL_TCL_DATA_CMD_INFO1_TO_FW, 1);
|
||||
} else {
|
||||
ti.meta_data_flags = arvif->tcl_metadata;
|
||||
}
|
||||
|
||||
if (ti.encap_type == HAL_TCL_ENCAP_TYPE_RAW) {
|
||||
if (skb_cb->flags & ATH11K_SKB_CIPHER_SET) {
|
||||
|
|
@ -614,6 +622,9 @@ int ath11k_dp_tx_send_reo_cmd(struct ath11k_base *ab, struct dp_rx_tid *rx_tid,
|
|||
struct hal_srng *cmd_ring;
|
||||
int cmd_num;
|
||||
|
||||
if (test_bit(ATH11K_FLAG_CRASH_FLUSH, &ab->dev_flags))
|
||||
return -ESHUTDOWN;
|
||||
|
||||
cmd_ring = &ab->hal.srng_list[dp->reo_cmd_ring.ring_id];
|
||||
cmd_num = ath11k_hal_reo_cmd_send(ab, cmd_ring, type, cmd);
|
||||
|
||||
|
|
@ -1068,12 +1079,16 @@ int ath11k_dp_tx_htt_monitor_mode_ring_config(struct ath11k *ar, bool reset)
|
|||
|
||||
for (i = 0; i < ab->hw_params.num_rxmda_per_pdev; i++) {
|
||||
ring_id = dp->rx_mon_status_refill_ring[i].refill_buf_ring.ring_id;
|
||||
if (!reset)
|
||||
if (!reset) {
|
||||
tlv_filter.rx_filter =
|
||||
HTT_RX_MON_FILTER_TLV_FLAGS_MON_STATUS_RING;
|
||||
else
|
||||
} else {
|
||||
tlv_filter = ath11k_mac_mon_status_filter_default;
|
||||
|
||||
if (ath11k_debugfs_is_extd_rx_stats_enabled(ar))
|
||||
tlv_filter.rx_filter = ath11k_debugfs_rx_filter(ar);
|
||||
}
|
||||
|
||||
ret = ath11k_dp_tx_htt_rx_filter_setup(ab, ring_id,
|
||||
dp->mac_id + i,
|
||||
HAL_RXDMA_MONITOR_STATUS,
|
||||
|
|
|
|||
|
|
@ -17,7 +17,7 @@ struct ath11k_dp_htt_wbm_tx_status {
|
|||
|
||||
int ath11k_dp_tx_htt_h2t_ver_req_msg(struct ath11k_base *ab);
|
||||
int ath11k_dp_tx(struct ath11k *ar, struct ath11k_vif *arvif,
|
||||
struct sk_buff *skb);
|
||||
struct ath11k_sta *arsta, struct sk_buff *skb);
|
||||
void ath11k_dp_tx_completion_handler(struct ath11k_base *ab, int ring_id);
|
||||
int ath11k_dp_tx_send_reo_cmd(struct ath11k_base *ab, struct dp_rx_tid *rx_tid,
|
||||
enum hal_reo_cmd_type type,
|
||||
|
|
|
|||
|
|
@ -496,6 +496,8 @@ struct hal_tlv_hdr {
|
|||
#define RX_MPDU_DESC_INFO0_DA_IDX_TIMEOUT BIT(29)
|
||||
#define RX_MPDU_DESC_INFO0_RAW_MPDU BIT(30)
|
||||
|
||||
#define RX_MPDU_DESC_META_DATA_PEER_ID GENMASK(15, 0)
|
||||
|
||||
struct rx_mpdu_desc {
|
||||
u32 info0; /* %RX_MPDU_DESC_INFO */
|
||||
u32 meta_data;
|
||||
|
|
|
|||
|
|
@ -97,6 +97,7 @@ static void ath11k_init_wmi_config_qca6390(struct ath11k_base *ab,
|
|||
config->num_multicast_filter_entries = 0x20;
|
||||
config->num_wow_filters = 0x16;
|
||||
config->num_keep_alive_pattern = 0;
|
||||
config->flag1 |= WMI_RSRC_CFG_FLAG1_BSS_CHANNEL_INFO_64;
|
||||
}
|
||||
|
||||
static void ath11k_hw_ipq8074_reo_setup(struct ath11k_base *ab)
|
||||
|
|
@ -197,6 +198,7 @@ static void ath11k_init_wmi_config_ipq8074(struct ath11k_base *ab,
|
|||
config->peer_map_unmap_v2_support = 1;
|
||||
config->twt_ap_pdev_count = ab->num_radios;
|
||||
config->twt_ap_sta_count = 1000;
|
||||
config->flag1 |= WMI_RSRC_CFG_FLAG1_BSS_CHANNEL_INFO_64;
|
||||
}
|
||||
|
||||
static int ath11k_hw_mac_id_to_pdev_id_ipq8074(struct ath11k_hw_params *hw,
|
||||
|
|
@ -372,6 +374,17 @@ static void ath11k_hw_ipq8074_rx_desc_set_msdu_len(struct hal_rx_desc *desc, u16
|
|||
desc->u.ipq8074.msdu_start.info1 = __cpu_to_le32(info);
|
||||
}
|
||||
|
||||
static bool ath11k_hw_ipq8074_rx_desc_mac_addr2_valid(struct hal_rx_desc *desc)
|
||||
{
|
||||
return __le32_to_cpu(desc->u.ipq8074.mpdu_start.info1) &
|
||||
RX_MPDU_START_INFO1_MAC_ADDR2_VALID;
|
||||
}
|
||||
|
||||
static u8 *ath11k_hw_ipq8074_rx_desc_mpdu_start_addr2(struct hal_rx_desc *desc)
|
||||
{
|
||||
return desc->u.ipq8074.mpdu_start.addr2;
|
||||
}
|
||||
|
||||
static
|
||||
struct rx_attention *ath11k_hw_ipq8074_rx_desc_get_attention(struct hal_rx_desc *desc)
|
||||
{
|
||||
|
|
@ -543,6 +556,17 @@ static u8 *ath11k_hw_qcn9074_rx_desc_get_msdu_payload(struct hal_rx_desc *desc)
|
|||
return &desc->u.qcn9074.msdu_payload[0];
|
||||
}
|
||||
|
||||
static bool ath11k_hw_ipq9074_rx_desc_mac_addr2_valid(struct hal_rx_desc *desc)
|
||||
{
|
||||
return __le32_to_cpu(desc->u.qcn9074.mpdu_start.info11) &
|
||||
RX_MPDU_START_INFO11_MAC_ADDR2_VALID;
|
||||
}
|
||||
|
||||
static u8 *ath11k_hw_ipq9074_rx_desc_mpdu_start_addr2(struct hal_rx_desc *desc)
|
||||
{
|
||||
return desc->u.qcn9074.mpdu_start.addr2;
|
||||
}
|
||||
|
||||
static bool ath11k_hw_wcn6855_rx_desc_get_first_msdu(struct hal_rx_desc *desc)
|
||||
{
|
||||
return !!FIELD_GET(RX_MSDU_END_INFO2_FIRST_MSDU_WCN6855,
|
||||
|
|
@ -703,6 +727,17 @@ static u8 *ath11k_hw_wcn6855_rx_desc_get_msdu_payload(struct hal_rx_desc *desc)
|
|||
return &desc->u.wcn6855.msdu_payload[0];
|
||||
}
|
||||
|
||||
static bool ath11k_hw_wcn6855_rx_desc_mac_addr2_valid(struct hal_rx_desc *desc)
|
||||
{
|
||||
return __le32_to_cpu(desc->u.wcn6855.mpdu_start.info1) &
|
||||
RX_MPDU_START_INFO1_MAC_ADDR2_VALID;
|
||||
}
|
||||
|
||||
static u8 *ath11k_hw_wcn6855_rx_desc_mpdu_start_addr2(struct hal_rx_desc *desc)
|
||||
{
|
||||
return desc->u.wcn6855.mpdu_start.addr2;
|
||||
}
|
||||
|
||||
static void ath11k_hw_wcn6855_reo_setup(struct ath11k_base *ab)
|
||||
{
|
||||
u32 reo_base = HAL_SEQ_WCSS_UMAC_REO_REG;
|
||||
|
|
@ -799,6 +834,8 @@ const struct ath11k_hw_ops ipq8074_ops = {
|
|||
.rx_desc_get_msdu_payload = ath11k_hw_ipq8074_rx_desc_get_msdu_payload,
|
||||
.reo_setup = ath11k_hw_ipq8074_reo_setup,
|
||||
.mpdu_info_get_peerid = ath11k_hw_ipq8074_mpdu_info_get_peerid,
|
||||
.rx_desc_mac_addr2_valid = ath11k_hw_ipq8074_rx_desc_mac_addr2_valid,
|
||||
.rx_desc_mpdu_start_addr2 = ath11k_hw_ipq8074_rx_desc_mpdu_start_addr2,
|
||||
};
|
||||
|
||||
const struct ath11k_hw_ops ipq6018_ops = {
|
||||
|
|
@ -835,6 +872,8 @@ const struct ath11k_hw_ops ipq6018_ops = {
|
|||
.rx_desc_get_msdu_payload = ath11k_hw_ipq8074_rx_desc_get_msdu_payload,
|
||||
.reo_setup = ath11k_hw_ipq8074_reo_setup,
|
||||
.mpdu_info_get_peerid = ath11k_hw_ipq8074_mpdu_info_get_peerid,
|
||||
.rx_desc_mac_addr2_valid = ath11k_hw_ipq8074_rx_desc_mac_addr2_valid,
|
||||
.rx_desc_mpdu_start_addr2 = ath11k_hw_ipq8074_rx_desc_mpdu_start_addr2,
|
||||
};
|
||||
|
||||
const struct ath11k_hw_ops qca6390_ops = {
|
||||
|
|
@ -871,6 +910,8 @@ const struct ath11k_hw_ops qca6390_ops = {
|
|||
.rx_desc_get_msdu_payload = ath11k_hw_ipq8074_rx_desc_get_msdu_payload,
|
||||
.reo_setup = ath11k_hw_ipq8074_reo_setup,
|
||||
.mpdu_info_get_peerid = ath11k_hw_ipq8074_mpdu_info_get_peerid,
|
||||
.rx_desc_mac_addr2_valid = ath11k_hw_ipq8074_rx_desc_mac_addr2_valid,
|
||||
.rx_desc_mpdu_start_addr2 = ath11k_hw_ipq8074_rx_desc_mpdu_start_addr2,
|
||||
};
|
||||
|
||||
const struct ath11k_hw_ops qcn9074_ops = {
|
||||
|
|
@ -907,6 +948,8 @@ const struct ath11k_hw_ops qcn9074_ops = {
|
|||
.rx_desc_get_msdu_payload = ath11k_hw_qcn9074_rx_desc_get_msdu_payload,
|
||||
.reo_setup = ath11k_hw_ipq8074_reo_setup,
|
||||
.mpdu_info_get_peerid = ath11k_hw_ipq8074_mpdu_info_get_peerid,
|
||||
.rx_desc_mac_addr2_valid = ath11k_hw_ipq9074_rx_desc_mac_addr2_valid,
|
||||
.rx_desc_mpdu_start_addr2 = ath11k_hw_ipq9074_rx_desc_mpdu_start_addr2,
|
||||
};
|
||||
|
||||
const struct ath11k_hw_ops wcn6855_ops = {
|
||||
|
|
@ -943,6 +986,8 @@ const struct ath11k_hw_ops wcn6855_ops = {
|
|||
.rx_desc_get_msdu_payload = ath11k_hw_wcn6855_rx_desc_get_msdu_payload,
|
||||
.reo_setup = ath11k_hw_wcn6855_reo_setup,
|
||||
.mpdu_info_get_peerid = ath11k_hw_wcn6855_mpdu_info_get_peerid,
|
||||
.rx_desc_mac_addr2_valid = ath11k_hw_wcn6855_rx_desc_mac_addr2_valid,
|
||||
.rx_desc_mpdu_start_addr2 = ath11k_hw_wcn6855_rx_desc_mpdu_start_addr2,
|
||||
};
|
||||
|
||||
#define ATH11K_TX_RING_MASK_0 0x1
|
||||
|
|
|
|||
|
|
@ -128,7 +128,7 @@ struct ath11k_hw_params {
|
|||
struct {
|
||||
const char *dir;
|
||||
size_t board_size;
|
||||
size_t cal_size;
|
||||
size_t cal_offset;
|
||||
} fw;
|
||||
|
||||
const struct ath11k_hw_ops *hw_ops;
|
||||
|
|
@ -153,7 +153,14 @@ struct ath11k_hw_params {
|
|||
bool vdev_start_delay;
|
||||
bool htt_peer_map_v2;
|
||||
bool tcl_0_only;
|
||||
u8 spectral_fft_sz;
|
||||
|
||||
struct {
|
||||
u8 fft_sz;
|
||||
u8 fft_pad_sz;
|
||||
u8 summary_pad_sz;
|
||||
u8 fft_hdr_len;
|
||||
u16 max_fft_bins;
|
||||
} spectral;
|
||||
|
||||
u16 interface_modes;
|
||||
bool supports_monitor;
|
||||
|
|
@ -202,6 +209,8 @@ struct ath11k_hw_ops {
|
|||
u8 *(*rx_desc_get_msdu_payload)(struct hal_rx_desc *desc);
|
||||
void (*reo_setup)(struct ath11k_base *ab);
|
||||
u16 (*mpdu_info_get_peerid)(u8 *tlv_data);
|
||||
bool (*rx_desc_mac_addr2_valid)(struct hal_rx_desc *desc);
|
||||
u8* (*rx_desc_mpdu_start_addr2)(struct hal_rx_desc *desc);
|
||||
};
|
||||
|
||||
extern const struct ath11k_hw_ops ipq8074_ops;
|
||||
|
|
|
|||
File diff suppressed because it is too large
Load Diff
|
|
@ -115,6 +115,9 @@ struct ath11k_generic_iter {
|
|||
#define WMI_MAX_SPATIAL_STREAM 3
|
||||
|
||||
#define ATH11K_CHAN_WIDTH_NUM 8
|
||||
#define ATH11K_BW_NSS_MAP_ENABLE BIT(31)
|
||||
#define ATH11K_PEER_RX_NSS_160MHZ GENMASK(2, 0)
|
||||
#define ATH11K_PEER_RX_NSS_80_80MHZ GENMASK(5, 3)
|
||||
|
||||
#define ATH11K_OBSS_PD_MAX_THRESHOLD -82
|
||||
#define ATH11K_OBSS_PD_NON_SRG_MAX_THRESHOLD -62
|
||||
|
|
|
|||
|
|
@ -430,6 +430,8 @@ static void ath11k_pci_force_wake(struct ath11k_base *ab)
|
|||
|
||||
static void ath11k_pci_sw_reset(struct ath11k_base *ab, bool power_on)
|
||||
{
|
||||
mdelay(100);
|
||||
|
||||
if (power_on) {
|
||||
ath11k_pci_enable_ltssm(ab);
|
||||
ath11k_pci_clear_all_intrs(ab);
|
||||
|
|
@ -439,9 +441,9 @@ static void ath11k_pci_sw_reset(struct ath11k_base *ab, bool power_on)
|
|||
}
|
||||
|
||||
ath11k_mhi_clear_vector(ab);
|
||||
ath11k_pci_clear_dbg_registers(ab);
|
||||
ath11k_pci_soc_global_reset(ab);
|
||||
ath11k_mhi_set_mhictrl_reset(ab);
|
||||
ath11k_pci_clear_dbg_registers(ab);
|
||||
}
|
||||
|
||||
int ath11k_pci_get_msi_irq(struct device *dev, unsigned int vector)
|
||||
|
|
|
|||
|
|
@ -251,6 +251,7 @@ int ath11k_peer_create(struct ath11k *ar, struct ath11k_vif *arvif,
|
|||
struct ieee80211_sta *sta, struct peer_create_params *param)
|
||||
{
|
||||
struct ath11k_peer *peer;
|
||||
struct ath11k_sta *arsta;
|
||||
int ret;
|
||||
|
||||
lockdep_assert_held(&ar->conf_mutex);
|
||||
|
|
@ -319,6 +320,16 @@ int ath11k_peer_create(struct ath11k *ar, struct ath11k_vif *arvif,
|
|||
peer->sec_type = HAL_ENCRYPT_TYPE_OPEN;
|
||||
peer->sec_type_grp = HAL_ENCRYPT_TYPE_OPEN;
|
||||
|
||||
if (sta) {
|
||||
arsta = (struct ath11k_sta *)sta->drv_priv;
|
||||
arsta->tcl_metadata |= FIELD_PREP(HTT_TCL_META_DATA_TYPE, 0) |
|
||||
FIELD_PREP(HTT_TCL_META_DATA_PEER_ID,
|
||||
peer->peer_id);
|
||||
|
||||
/* set HTT extension valid bit to 0 by default */
|
||||
arsta->tcl_metadata &= ~HTT_TCL_META_DATA_VALID_HTT;
|
||||
}
|
||||
|
||||
ar->num_peers++;
|
||||
|
||||
spin_unlock_bh(&ar->ab->base_lock);
|
||||
|
|
|
|||
|
|
@ -950,6 +950,78 @@ static struct qmi_elem_info qmi_wlanfw_cap_resp_msg_v01_ei[] = {
|
|||
.offset = offsetof(struct qmi_wlanfw_cap_resp_msg_v01,
|
||||
num_macs),
|
||||
},
|
||||
{
|
||||
.data_type = QMI_OPT_FLAG,
|
||||
.elem_len = 1,
|
||||
.elem_size = sizeof(u8),
|
||||
.array_type = NO_ARRAY,
|
||||
.tlv_type = 0x16,
|
||||
.offset = offsetof(struct qmi_wlanfw_cap_resp_msg_v01,
|
||||
voltage_mv_valid),
|
||||
},
|
||||
{
|
||||
.data_type = QMI_UNSIGNED_4_BYTE,
|
||||
.elem_len = 1,
|
||||
.elem_size = sizeof(u32),
|
||||
.array_type = NO_ARRAY,
|
||||
.tlv_type = 0x16,
|
||||
.offset = offsetof(struct qmi_wlanfw_cap_resp_msg_v01,
|
||||
voltage_mv),
|
||||
},
|
||||
{
|
||||
.data_type = QMI_OPT_FLAG,
|
||||
.elem_len = 1,
|
||||
.elem_size = sizeof(u8),
|
||||
.array_type = NO_ARRAY,
|
||||
.tlv_type = 0x17,
|
||||
.offset = offsetof(struct qmi_wlanfw_cap_resp_msg_v01,
|
||||
time_freq_hz_valid),
|
||||
},
|
||||
{
|
||||
.data_type = QMI_UNSIGNED_4_BYTE,
|
||||
.elem_len = 1,
|
||||
.elem_size = sizeof(u32),
|
||||
.array_type = NO_ARRAY,
|
||||
.tlv_type = 0x17,
|
||||
.offset = offsetof(struct qmi_wlanfw_cap_resp_msg_v01,
|
||||
time_freq_hz),
|
||||
},
|
||||
{
|
||||
.data_type = QMI_OPT_FLAG,
|
||||
.elem_len = 1,
|
||||
.elem_size = sizeof(u8),
|
||||
.array_type = NO_ARRAY,
|
||||
.tlv_type = 0x18,
|
||||
.offset = offsetof(struct qmi_wlanfw_cap_resp_msg_v01,
|
||||
otp_version_valid),
|
||||
},
|
||||
{
|
||||
.data_type = QMI_UNSIGNED_4_BYTE,
|
||||
.elem_len = 1,
|
||||
.elem_size = sizeof(u32),
|
||||
.array_type = NO_ARRAY,
|
||||
.tlv_type = 0x18,
|
||||
.offset = offsetof(struct qmi_wlanfw_cap_resp_msg_v01,
|
||||
otp_version),
|
||||
},
|
||||
{
|
||||
.data_type = QMI_OPT_FLAG,
|
||||
.elem_len = 1,
|
||||
.elem_size = sizeof(u8),
|
||||
.array_type = NO_ARRAY,
|
||||
.tlv_type = 0x19,
|
||||
.offset = offsetof(struct qmi_wlanfw_cap_resp_msg_v01,
|
||||
eeprom_read_timeout_valid),
|
||||
},
|
||||
{
|
||||
.data_type = QMI_UNSIGNED_4_BYTE,
|
||||
.elem_len = 1,
|
||||
.elem_size = sizeof(u32),
|
||||
.array_type = NO_ARRAY,
|
||||
.tlv_type = 0x19,
|
||||
.offset = offsetof(struct qmi_wlanfw_cap_resp_msg_v01,
|
||||
eeprom_read_timeout),
|
||||
},
|
||||
{
|
||||
.data_type = QMI_EOTI,
|
||||
.array_type = NO_ARRAY,
|
||||
|
|
@ -1770,7 +1842,7 @@ static int ath11k_qmi_alloc_target_mem_chunk(struct ath11k_base *ab)
|
|||
chunk->vaddr = dma_alloc_coherent(ab->dev,
|
||||
chunk->size,
|
||||
&chunk->paddr,
|
||||
GFP_KERNEL);
|
||||
GFP_KERNEL | __GFP_NOWARN);
|
||||
if (!chunk->vaddr) {
|
||||
if (ab->qmi.mem_seg_count <= ATH11K_QMI_FW_MEM_REQ_SEGMENT_CNT) {
|
||||
ath11k_dbg(ab, ATH11K_DBG_QMI,
|
||||
|
|
@ -1846,8 +1918,8 @@ static int ath11k_qmi_request_target_cap(struct ath11k_base *ab)
|
|||
memset(&req, 0, sizeof(req));
|
||||
memset(&resp, 0, sizeof(resp));
|
||||
|
||||
ret = qmi_txn_init(&ab->qmi.handle, &txn,
|
||||
qmi_wlanfw_cap_resp_msg_v01_ei, &resp);
|
||||
ret = qmi_txn_init(&ab->qmi.handle, &txn, qmi_wlanfw_cap_resp_msg_v01_ei,
|
||||
&resp);
|
||||
if (ret < 0)
|
||||
goto out;
|
||||
|
||||
|
|
@ -1900,6 +1972,12 @@ static int ath11k_qmi_request_target_cap(struct ath11k_base *ab)
|
|||
strlcpy(ab->qmi.target.fw_build_id, resp.fw_build_id,
|
||||
sizeof(ab->qmi.target.fw_build_id));
|
||||
|
||||
if (resp.eeprom_read_timeout_valid) {
|
||||
ab->qmi.target.eeprom_caldata =
|
||||
resp.eeprom_read_timeout;
|
||||
ath11k_dbg(ab, ATH11K_DBG_QMI, "qmi cal data supported from eeprom\n");
|
||||
}
|
||||
|
||||
ath11k_info(ab, "chip_id 0x%x chip_family 0x%x board_id 0x%x soc_id 0x%x\n",
|
||||
ab->qmi.target.chip_id, ab->qmi.target.chip_family,
|
||||
ab->qmi.target.board_id, ab->qmi.target.soc_id);
|
||||
|
|
@ -1917,173 +1995,41 @@ static int ath11k_qmi_request_target_cap(struct ath11k_base *ab)
|
|||
return ret;
|
||||
}
|
||||
|
||||
static int
|
||||
ath11k_qmi_prepare_bdf_download(struct ath11k_base *ab, int type,
|
||||
struct qmi_wlanfw_bdf_download_req_msg_v01 *req,
|
||||
void __iomem *bdf_addr)
|
||||
{
|
||||
const struct firmware *fw_entry;
|
||||
struct ath11k_board_data bd;
|
||||
u32 fw_size;
|
||||
int ret;
|
||||
|
||||
switch (type) {
|
||||
case ATH11K_QMI_FILE_TYPE_BDF_GOLDEN:
|
||||
memset(&bd, 0, sizeof(bd));
|
||||
|
||||
ret = ath11k_core_fetch_bdf(ab, &bd);
|
||||
if (ret) {
|
||||
ath11k_warn(ab, "failed to load board file: %d\n", ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
fw_size = min_t(u32, ab->hw_params.fw.board_size, bd.len);
|
||||
memcpy_toio(bdf_addr, bd.data, fw_size);
|
||||
ath11k_core_free_bdf(ab, &bd);
|
||||
break;
|
||||
case ATH11K_QMI_FILE_TYPE_CALDATA:
|
||||
fw_entry = ath11k_core_firmware_request(ab, ATH11K_DEFAULT_CAL_FILE);
|
||||
if (IS_ERR(fw_entry)) {
|
||||
ret = PTR_ERR(fw_entry);
|
||||
ath11k_warn(ab, "failed to load %s: %d\n",
|
||||
ATH11K_DEFAULT_CAL_FILE, ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
fw_size = min_t(u32, ab->hw_params.fw.board_size,
|
||||
fw_entry->size);
|
||||
|
||||
memcpy_toio(bdf_addr + ATH11K_QMI_CALDATA_OFFSET,
|
||||
fw_entry->data, fw_size);
|
||||
|
||||
release_firmware(fw_entry);
|
||||
break;
|
||||
default:
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
req->total_size = fw_size;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int ath11k_qmi_load_bdf_fixed_addr(struct ath11k_base *ab)
|
||||
static int ath11k_qmi_load_file_target_mem(struct ath11k_base *ab,
|
||||
const u8 *data, u32 len, u8 type)
|
||||
{
|
||||
struct qmi_wlanfw_bdf_download_req_msg_v01 *req;
|
||||
struct qmi_wlanfw_bdf_download_resp_msg_v01 resp;
|
||||
struct qmi_txn txn = {};
|
||||
const u8 *temp = data;
|
||||
void __iomem *bdf_addr = NULL;
|
||||
int type, ret;
|
||||
|
||||
req = kzalloc(sizeof(*req), GFP_KERNEL);
|
||||
if (!req)
|
||||
return -ENOMEM;
|
||||
memset(&resp, 0, sizeof(resp));
|
||||
|
||||
bdf_addr = ioremap(ab->hw_params.bdf_addr, ATH11K_QMI_BDF_MAX_SIZE);
|
||||
if (!bdf_addr) {
|
||||
ath11k_warn(ab, "failed ioremap for board file\n");
|
||||
ret = -EIO;
|
||||
goto out;
|
||||
}
|
||||
|
||||
for (type = 0; type < ATH11K_QMI_MAX_FILE_TYPE; type++) {
|
||||
req->valid = 1;
|
||||
req->file_id_valid = 1;
|
||||
req->file_id = ab->qmi.target.board_id;
|
||||
req->total_size_valid = 1;
|
||||
req->seg_id_valid = 1;
|
||||
req->seg_id = type;
|
||||
req->data_valid = 0;
|
||||
req->data_len = ATH11K_QMI_MAX_BDF_FILE_NAME_SIZE;
|
||||
req->bdf_type = 0;
|
||||
req->bdf_type_valid = 0;
|
||||
req->end_valid = 1;
|
||||
req->end = 1;
|
||||
|
||||
ret = ath11k_qmi_prepare_bdf_download(ab, type, req, bdf_addr);
|
||||
if (ret < 0)
|
||||
goto out_qmi_bdf;
|
||||
|
||||
ret = qmi_txn_init(&ab->qmi.handle, &txn,
|
||||
qmi_wlanfw_bdf_download_resp_msg_v01_ei,
|
||||
&resp);
|
||||
if (ret < 0)
|
||||
goto out_qmi_bdf;
|
||||
|
||||
ath11k_dbg(ab, ATH11K_DBG_QMI, "qmi bdf download req fixed addr type %d\n",
|
||||
type);
|
||||
|
||||
ret = qmi_send_request(&ab->qmi.handle, NULL, &txn,
|
||||
QMI_WLANFW_BDF_DOWNLOAD_REQ_V01,
|
||||
QMI_WLANFW_BDF_DOWNLOAD_REQ_MSG_V01_MAX_LEN,
|
||||
qmi_wlanfw_bdf_download_req_msg_v01_ei, req);
|
||||
if (ret < 0) {
|
||||
qmi_txn_cancel(&txn);
|
||||
goto out_qmi_bdf;
|
||||
}
|
||||
|
||||
ret = qmi_txn_wait(&txn, msecs_to_jiffies(ATH11K_QMI_WLANFW_TIMEOUT_MS));
|
||||
if (ret < 0)
|
||||
goto out_qmi_bdf;
|
||||
|
||||
if (resp.resp.result != QMI_RESULT_SUCCESS_V01) {
|
||||
ath11k_warn(ab, "board file download request failed: %d %d\n",
|
||||
resp.resp.result, resp.resp.error);
|
||||
ret = -EINVAL;
|
||||
goto out_qmi_bdf;
|
||||
}
|
||||
}
|
||||
|
||||
out_qmi_bdf:
|
||||
iounmap(bdf_addr);
|
||||
out:
|
||||
kfree(req);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int ath11k_qmi_load_bdf_qmi(struct ath11k_base *ab)
|
||||
{
|
||||
struct qmi_wlanfw_bdf_download_req_msg_v01 *req;
|
||||
struct qmi_wlanfw_bdf_download_resp_msg_v01 resp;
|
||||
struct ath11k_board_data bd;
|
||||
unsigned int remaining;
|
||||
struct qmi_txn txn = {};
|
||||
int ret;
|
||||
const u8 *temp;
|
||||
int bdf_type;
|
||||
u32 remaining = len;
|
||||
|
||||
req = kzalloc(sizeof(*req), GFP_KERNEL);
|
||||
if (!req)
|
||||
return -ENOMEM;
|
||||
|
||||
memset(&resp, 0, sizeof(resp));
|
||||
|
||||
memset(&bd, 0, sizeof(bd));
|
||||
ret = ath11k_core_fetch_bdf(ab, &bd);
|
||||
if (ret) {
|
||||
ath11k_warn(ab, "failed to fetch board file: %d\n", ret);
|
||||
goto out;
|
||||
if (ab->bus_params.fixed_bdf_addr) {
|
||||
bdf_addr = ioremap(ab->hw_params.bdf_addr, ab->hw_params.fw.board_size);
|
||||
if (!bdf_addr) {
|
||||
ath11k_warn(ab, "qmi ioremap error for bdf_addr\n");
|
||||
ret = -EIO;
|
||||
goto err_free_req;
|
||||
}
|
||||
}
|
||||
|
||||
temp = bd.data;
|
||||
remaining = bd.len;
|
||||
|
||||
if (bd.len >= SELFMAG && memcmp(bd.data, ELFMAG, SELFMAG) == 0)
|
||||
bdf_type = ATH11K_QMI_BDF_TYPE_ELF;
|
||||
else
|
||||
bdf_type = ATH11K_QMI_BDF_TYPE_BIN;
|
||||
|
||||
ath11k_dbg(ab, ATH11K_DBG_QMI, "qmi bdf_type %d\n", bdf_type);
|
||||
|
||||
while (remaining) {
|
||||
req->valid = 1;
|
||||
req->file_id_valid = 1;
|
||||
req->file_id = ab->qmi.target.board_id;
|
||||
req->total_size_valid = 1;
|
||||
req->total_size = bd.len;
|
||||
req->total_size = remaining;
|
||||
req->seg_id_valid = 1;
|
||||
req->data_valid = 1;
|
||||
req->data_len = ATH11K_QMI_MAX_BDF_FILE_NAME_SIZE;
|
||||
req->bdf_type = bdf_type;
|
||||
req->bdf_type = type;
|
||||
req->bdf_type_valid = 1;
|
||||
req->end_valid = 1;
|
||||
req->end = 0;
|
||||
|
|
@ -2095,16 +2041,30 @@ static int ath11k_qmi_load_bdf_qmi(struct ath11k_base *ab)
|
|||
req->end = 1;
|
||||
}
|
||||
|
||||
memcpy(req->data, temp, req->data_len);
|
||||
if (ab->bus_params.fixed_bdf_addr ||
|
||||
type == ATH11K_QMI_FILE_TYPE_EEPROM) {
|
||||
req->data_valid = 0;
|
||||
req->end = 1;
|
||||
req->data_len = ATH11K_QMI_MAX_BDF_FILE_NAME_SIZE;
|
||||
} else {
|
||||
memcpy(req->data, temp, req->data_len);
|
||||
}
|
||||
|
||||
if (ab->bus_params.fixed_bdf_addr) {
|
||||
if (type == ATH11K_QMI_FILE_TYPE_CALDATA)
|
||||
bdf_addr += ab->hw_params.fw.cal_offset;
|
||||
|
||||
memcpy_toio(bdf_addr, temp, len);
|
||||
}
|
||||
|
||||
ret = qmi_txn_init(&ab->qmi.handle, &txn,
|
||||
qmi_wlanfw_bdf_download_resp_msg_v01_ei,
|
||||
&resp);
|
||||
if (ret < 0)
|
||||
goto out_qmi_bdf;
|
||||
goto err_iounmap;
|
||||
|
||||
ath11k_dbg(ab, ATH11K_DBG_QMI, "qmi bdf download request remaining %i\n",
|
||||
remaining);
|
||||
ath11k_dbg(ab, ATH11K_DBG_QMI, "qmi bdf download req fixed addr type %d\n",
|
||||
type);
|
||||
|
||||
ret = qmi_send_request(&ab->qmi.handle, NULL, &txn,
|
||||
QMI_WLANFW_BDF_DOWNLOAD_REQ_V01,
|
||||
|
|
@ -2112,29 +2072,124 @@ static int ath11k_qmi_load_bdf_qmi(struct ath11k_base *ab)
|
|||
qmi_wlanfw_bdf_download_req_msg_v01_ei, req);
|
||||
if (ret < 0) {
|
||||
qmi_txn_cancel(&txn);
|
||||
goto out_qmi_bdf;
|
||||
goto err_iounmap;
|
||||
}
|
||||
|
||||
ret = qmi_txn_wait(&txn, msecs_to_jiffies(ATH11K_QMI_WLANFW_TIMEOUT_MS));
|
||||
if (ret < 0)
|
||||
goto out_qmi_bdf;
|
||||
if (ret < 0) {
|
||||
ath11k_warn(ab, "failed to wait board file download request: %d\n",
|
||||
ret);
|
||||
goto err_iounmap;
|
||||
}
|
||||
|
||||
if (resp.resp.result != QMI_RESULT_SUCCESS_V01) {
|
||||
ath11k_warn(ab, "bdf download request failed: %d %d\n",
|
||||
ath11k_warn(ab, "board file download request failed: %d %d\n",
|
||||
resp.resp.result, resp.resp.error);
|
||||
ret = resp.resp.result;
|
||||
goto out_qmi_bdf;
|
||||
ret = -EINVAL;
|
||||
goto err_iounmap;
|
||||
}
|
||||
|
||||
if (ab->bus_params.fixed_bdf_addr ||
|
||||
type == ATH11K_QMI_FILE_TYPE_EEPROM) {
|
||||
remaining = 0;
|
||||
} else {
|
||||
remaining -= req->data_len;
|
||||
temp += req->data_len;
|
||||
req->seg_id++;
|
||||
ath11k_dbg(ab, ATH11K_DBG_QMI, "qmi bdf download request remaining %i\n",
|
||||
remaining);
|
||||
}
|
||||
remaining -= req->data_len;
|
||||
temp += req->data_len;
|
||||
req->seg_id++;
|
||||
}
|
||||
|
||||
out_qmi_bdf:
|
||||
ath11k_core_free_bdf(ab, &bd);
|
||||
err_iounmap:
|
||||
if (ab->bus_params.fixed_bdf_addr)
|
||||
iounmap(bdf_addr);
|
||||
|
||||
out:
|
||||
err_free_req:
|
||||
kfree(req);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int ath11k_qmi_load_bdf_qmi(struct ath11k_base *ab)
|
||||
{
|
||||
struct device *dev = ab->dev;
|
||||
char filename[ATH11K_QMI_MAX_BDF_FILE_NAME_SIZE];
|
||||
const struct firmware *fw_entry;
|
||||
struct ath11k_board_data bd;
|
||||
u32 fw_size, file_type;
|
||||
int ret = 0, bdf_type;
|
||||
const u8 *tmp;
|
||||
|
||||
memset(&bd, 0, sizeof(bd));
|
||||
ret = ath11k_core_fetch_bdf(ab, &bd);
|
||||
if (ret) {
|
||||
ath11k_warn(ab, "qmi failed to fetch board file: %d\n", ret);
|
||||
goto out;
|
||||
}
|
||||
|
||||
if (bd.len >= SELFMAG && memcmp(bd.data, ELFMAG, SELFMAG) == 0)
|
||||
bdf_type = ATH11K_QMI_BDF_TYPE_ELF;
|
||||
else
|
||||
bdf_type = ATH11K_QMI_BDF_TYPE_BIN;
|
||||
|
||||
ath11k_dbg(ab, ATH11K_DBG_QMI, "qmi bdf_type %d\n", bdf_type);
|
||||
|
||||
fw_size = bd.len;
|
||||
fw_size = min_t(u32, ab->hw_params.fw.board_size, bd.len);
|
||||
|
||||
ret = ath11k_qmi_load_file_target_mem(ab, bd.data, fw_size, bdf_type);
|
||||
if (ret < 0) {
|
||||
ath11k_warn(ab, "qmi failed to load bdf file\n");
|
||||
goto out;
|
||||
}
|
||||
|
||||
/* QCA6390 does not support cal data, skip it */
|
||||
if (bdf_type == ATH11K_QMI_BDF_TYPE_ELF)
|
||||
goto out;
|
||||
|
||||
if (ab->qmi.target.eeprom_caldata) {
|
||||
file_type = ATH11K_QMI_FILE_TYPE_EEPROM;
|
||||
tmp = filename;
|
||||
fw_size = ATH11K_QMI_MAX_BDF_FILE_NAME_SIZE;
|
||||
} else {
|
||||
file_type = ATH11K_QMI_FILE_TYPE_CALDATA;
|
||||
|
||||
/* cal-<bus>-<id>.bin */
|
||||
snprintf(filename, sizeof(filename), "cal-%s-%s.bin",
|
||||
ath11k_bus_str(ab->hif.bus), dev_name(dev));
|
||||
fw_entry = ath11k_core_firmware_request(ab, filename);
|
||||
if (!IS_ERR(fw_entry))
|
||||
goto success;
|
||||
|
||||
fw_entry = ath11k_core_firmware_request(ab, ATH11K_DEFAULT_CAL_FILE);
|
||||
if (IS_ERR(fw_entry)) {
|
||||
ret = PTR_ERR(fw_entry);
|
||||
ath11k_warn(ab,
|
||||
"qmi failed to load CAL data file:%s\n",
|
||||
filename);
|
||||
goto out;
|
||||
}
|
||||
success:
|
||||
fw_size = min_t(u32, ab->hw_params.fw.board_size, fw_entry->size);
|
||||
tmp = fw_entry->data;
|
||||
}
|
||||
|
||||
ret = ath11k_qmi_load_file_target_mem(ab, tmp, fw_size, file_type);
|
||||
if (ret < 0) {
|
||||
ath11k_warn(ab, "qmi failed to load caldata\n");
|
||||
goto out_qmi_cal;
|
||||
}
|
||||
|
||||
ath11k_dbg(ab, ATH11K_DBG_QMI, "qmi caldata type: %u\n", file_type);
|
||||
|
||||
out_qmi_cal:
|
||||
if (!ab->qmi.target.eeprom_caldata)
|
||||
release_firmware(fw_entry);
|
||||
out:
|
||||
ath11k_core_free_bdf(ab, &bd);
|
||||
ath11k_dbg(ab, ATH11K_DBG_QMI, "qmi BDF download sequence completed\n");
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
|
@ -2519,10 +2574,7 @@ static int ath11k_qmi_event_load_bdf(struct ath11k_qmi *qmi)
|
|||
return ret;
|
||||
}
|
||||
|
||||
if (ab->bus_params.fixed_bdf_addr)
|
||||
ret = ath11k_qmi_load_bdf_fixed_addr(ab);
|
||||
else
|
||||
ret = ath11k_qmi_load_bdf_qmi(ab);
|
||||
ret = ath11k_qmi_load_bdf_qmi(ab);
|
||||
if (ret < 0) {
|
||||
ath11k_warn(ab, "failed to load board data file: %d\n", ret);
|
||||
return ret;
|
||||
|
|
@ -2707,8 +2759,10 @@ static void ath11k_qmi_driver_event_work(struct work_struct *work)
|
|||
list_del(&event->list);
|
||||
spin_unlock(&qmi->event_lock);
|
||||
|
||||
if (test_bit(ATH11K_FLAG_UNREGISTERING, &ab->dev_flags))
|
||||
if (test_bit(ATH11K_FLAG_UNREGISTERING, &ab->dev_flags)) {
|
||||
kfree(event);
|
||||
return;
|
||||
}
|
||||
|
||||
switch (event->type) {
|
||||
case ATH11K_QMI_EVENT_SERVER_ARRIVE:
|
||||
|
|
|
|||
|
|
@ -10,11 +10,9 @@
|
|||
#include <linux/soc/qcom/qmi.h>
|
||||
|
||||
#define ATH11K_HOST_VERSION_STRING "WIN"
|
||||
#define ATH11K_QMI_WLANFW_TIMEOUT_MS 5000
|
||||
#define ATH11K_QMI_WLANFW_TIMEOUT_MS 10000
|
||||
#define ATH11K_QMI_MAX_BDF_FILE_NAME_SIZE 64
|
||||
#define ATH11K_QMI_CALDB_ADDRESS 0x4BA00000
|
||||
#define ATH11K_QMI_BDF_MAX_SIZE (256 * 1024)
|
||||
#define ATH11K_QMI_CALDATA_OFFSET (128 * 1024)
|
||||
#define ATH11K_QMI_WLANFW_MAX_BUILD_ID_LEN_V01 128
|
||||
#define ATH11K_QMI_WLFW_SERVICE_ID_V01 0x45
|
||||
#define ATH11K_QMI_WLFW_SERVICE_VERS_V01 0x01
|
||||
|
|
@ -44,6 +42,7 @@ struct ath11k_base;
|
|||
enum ath11k_qmi_file_type {
|
||||
ATH11K_QMI_FILE_TYPE_BDF_GOLDEN,
|
||||
ATH11K_QMI_FILE_TYPE_CALDATA,
|
||||
ATH11K_QMI_FILE_TYPE_EEPROM,
|
||||
ATH11K_QMI_MAX_FILE_TYPE,
|
||||
};
|
||||
|
||||
|
|
@ -104,6 +103,7 @@ struct target_info {
|
|||
u32 board_id;
|
||||
u32 soc_id;
|
||||
u32 fw_version;
|
||||
u32 eeprom_caldata;
|
||||
char fw_build_timestamp[ATH11K_QMI_WLANFW_MAX_TIMESTAMP_LEN_V01 + 1];
|
||||
char fw_build_id[ATH11K_QMI_WLANFW_MAX_BUILD_ID_LEN_V01 + 1];
|
||||
char bdf_ext[ATH11K_QMI_BDF_EXT_STR_LENGTH];
|
||||
|
|
@ -135,7 +135,7 @@ struct ath11k_qmi {
|
|||
wait_queue_head_t cold_boot_waitq;
|
||||
};
|
||||
|
||||
#define QMI_WLANFW_HOST_CAP_REQ_MSG_V01_MAX_LEN 189
|
||||
#define QMI_WLANFW_HOST_CAP_REQ_MSG_V01_MAX_LEN 261
|
||||
#define QMI_WLANFW_HOST_CAP_REQ_V01 0x0034
|
||||
#define QMI_WLANFW_HOST_CAP_RESP_MSG_V01_MAX_LEN 7
|
||||
#define QMI_WLFW_HOST_CAP_RESP_V01 0x0034
|
||||
|
|
@ -285,7 +285,7 @@ struct qmi_wlanfw_fw_cold_cal_done_ind_msg_v01 {
|
|||
};
|
||||
|
||||
#define QMI_WLANFW_CAP_REQ_MSG_V01_MAX_LEN 0
|
||||
#define QMI_WLANFW_CAP_RESP_MSG_V01_MAX_LEN 207
|
||||
#define QMI_WLANFW_CAP_RESP_MSG_V01_MAX_LEN 235
|
||||
#define QMI_WLANFW_CAP_REQ_V01 0x0024
|
||||
#define QMI_WLANFW_CAP_RESP_V01 0x0024
|
||||
|
||||
|
|
@ -366,6 +366,14 @@ struct qmi_wlanfw_cap_resp_msg_v01 {
|
|||
char fw_build_id[ATH11K_QMI_WLANFW_MAX_BUILD_ID_LEN_V01 + 1];
|
||||
u8 num_macs_valid;
|
||||
u8 num_macs;
|
||||
u8 voltage_mv_valid;
|
||||
u32 voltage_mv;
|
||||
u8 time_freq_hz_valid;
|
||||
u32 time_freq_hz;
|
||||
u8 otp_version_valid;
|
||||
u32 otp_version;
|
||||
u8 eeprom_read_timeout_valid;
|
||||
u32 eeprom_read_timeout;
|
||||
};
|
||||
|
||||
struct qmi_wlanfw_cap_req_msg_v01 {
|
||||
|
|
|
|||
|
|
@ -97,7 +97,6 @@ int ath11k_reg_update_chan_list(struct ath11k *ar)
|
|||
struct channel_param *ch;
|
||||
enum nl80211_band band;
|
||||
int num_channels = 0;
|
||||
int params_len;
|
||||
int i, ret;
|
||||
|
||||
bands = hw->wiphy->bands;
|
||||
|
|
@ -117,10 +116,8 @@ int ath11k_reg_update_chan_list(struct ath11k *ar)
|
|||
if (WARN_ON(!num_channels))
|
||||
return -EINVAL;
|
||||
|
||||
params_len = sizeof(struct scan_chan_list_params) +
|
||||
num_channels * sizeof(struct channel_param);
|
||||
params = kzalloc(params_len, GFP_KERNEL);
|
||||
|
||||
params = kzalloc(struct_size(params, ch_param, num_channels),
|
||||
GFP_KERNEL);
|
||||
if (!params)
|
||||
return -ENOMEM;
|
||||
|
||||
|
|
@ -198,7 +195,7 @@ static void ath11k_copy_regd(struct ieee80211_regdomain *regd_orig,
|
|||
sizeof(struct ieee80211_reg_rule));
|
||||
}
|
||||
|
||||
int ath11k_regd_update(struct ath11k *ar, bool init)
|
||||
int ath11k_regd_update(struct ath11k *ar)
|
||||
{
|
||||
struct ieee80211_regdomain *regd, *regd_copy = NULL;
|
||||
int ret, regd_len, pdev_id;
|
||||
|
|
@ -209,7 +206,10 @@ int ath11k_regd_update(struct ath11k *ar, bool init)
|
|||
|
||||
spin_lock_bh(&ab->base_lock);
|
||||
|
||||
if (init) {
|
||||
/* Prefer the latest regd update over default if it's available */
|
||||
if (ab->new_regd[pdev_id]) {
|
||||
regd = ab->new_regd[pdev_id];
|
||||
} else {
|
||||
/* Apply the regd received during init through
|
||||
* WMI_REG_CHAN_LIST_CC event. In case of failure to
|
||||
* receive the regd, initialize with a default world
|
||||
|
|
@ -222,8 +222,6 @@ int ath11k_regd_update(struct ath11k *ar, bool init)
|
|||
"failed to receive default regd during init\n");
|
||||
regd = (struct ieee80211_regdomain *)&ath11k_world_regd;
|
||||
}
|
||||
} else {
|
||||
regd = ab->new_regd[pdev_id];
|
||||
}
|
||||
|
||||
if (!regd) {
|
||||
|
|
@ -683,7 +681,7 @@ void ath11k_regd_update_work(struct work_struct *work)
|
|||
regd_update_work);
|
||||
int ret;
|
||||
|
||||
ret = ath11k_regd_update(ar, false);
|
||||
ret = ath11k_regd_update(ar);
|
||||
if (ret) {
|
||||
/* Firmware has already moved to the new regd. We need
|
||||
* to maintain channel consistency across FW, Host driver
|
||||
|
|
|
|||
|
|
@ -31,6 +31,6 @@ void ath11k_regd_update_work(struct work_struct *work);
|
|||
struct ieee80211_regdomain *
|
||||
ath11k_reg_build_regd(struct ath11k_base *ab,
|
||||
struct cur_regulatory_info *reg_info, bool intersect);
|
||||
int ath11k_regd_update(struct ath11k *ar, bool init);
|
||||
int ath11k_regd_update(struct ath11k *ar);
|
||||
int ath11k_reg_update_chan_list(struct ath11k *ar);
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -11,22 +11,20 @@
|
|||
#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_MIN_BINS 32
|
||||
#define ATH11K_SPECTRAL_MIN_IB_BINS (ATH11K_SPECTRAL_MIN_BINS >> 1)
|
||||
#define ATH11K_SPECTRAL_MAX_IB_BINS(x) ((x)->hw_params.spectral.max_fft_bins >> 1)
|
||||
|
||||
#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_PER_SAMPLE_SIZE(x) (sizeof(struct fft_sample_ath11k) + \
|
||||
ATH11K_SPECTRAL_MAX_IB_BINS(x))
|
||||
#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_SUB_BUFF_SIZE(x) ATH11K_SPECTRAL_PER_SAMPLE_SIZE(x)
|
||||
#define ATH11K_SPECTRAL_NUM_SUB_BUF ATH11K_SPECTRAL_TOTAL_SAMPLE
|
||||
|
||||
#define ATH11K_SPECTRAL_20MHZ 20
|
||||
|
|
@ -444,8 +442,8 @@ static ssize_t ath11k_write_file_spectral_bins(struct file *file,
|
|||
if (kstrtoul(buf, 0, &val))
|
||||
return -EINVAL;
|
||||
|
||||
if (val < ATH11K_SPECTRAL_ATH11K_MIN_BINS ||
|
||||
val > SPECTRAL_ATH11K_MAX_NUM_BINS)
|
||||
if (val < ATH11K_SPECTRAL_MIN_BINS ||
|
||||
val > ar->ab->hw_params.spectral.max_fft_bins)
|
||||
return -EINVAL;
|
||||
|
||||
if (!is_power_of_2(val))
|
||||
|
|
@ -581,12 +579,12 @@ int ath11k_spectral_process_fft(struct ath11k *ar,
|
|||
struct spectral_tlv *tlv;
|
||||
int tlv_len, bin_len, num_bins;
|
||||
u16 length, freq;
|
||||
u8 chan_width_mhz;
|
||||
u8 chan_width_mhz, bin_sz;
|
||||
int ret;
|
||||
|
||||
lockdep_assert_held(&ar->spectral.lock);
|
||||
|
||||
if (!ab->hw_params.spectral_fft_sz) {
|
||||
if (!ab->hw_params.spectral.fft_sz) {
|
||||
ath11k_warn(ab, "invalid bin size type for hw rev %d\n",
|
||||
ab->hw_rev);
|
||||
return -EINVAL;
|
||||
|
|
@ -596,7 +594,7 @@ int ath11k_spectral_process_fft(struct ath11k *ar,
|
|||
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));
|
||||
bin_len = tlv_len - ab->hw_params.spectral.fft_hdr_len;
|
||||
|
||||
if (data_len < (bin_len + sizeof(*fft_report))) {
|
||||
ath11k_warn(ab, "mismatch in expected bin len %d and data len %d\n",
|
||||
|
|
@ -604,12 +602,13 @@ int ath11k_spectral_process_fft(struct ath11k *ar,
|
|||
return -EINVAL;
|
||||
}
|
||||
|
||||
num_bins = bin_len / ATH11K_SPECTRAL_BIN_SIZE;
|
||||
bin_sz = ab->hw_params.spectral.fft_sz + ab->hw_params.spectral.fft_pad_sz;
|
||||
num_bins = bin_len / bin_sz;
|
||||
/* 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 ||
|
||||
if (num_bins < ATH11K_SPECTRAL_MIN_IB_BINS ||
|
||||
num_bins > ATH11K_SPECTRAL_MAX_IB_BINS(ab) ||
|
||||
!is_power_of_2(num_bins)) {
|
||||
ath11k_warn(ab, "Invalid num of bins %d\n", num_bins);
|
||||
return -EINVAL;
|
||||
|
|
@ -654,7 +653,7 @@ int ath11k_spectral_process_fft(struct ath11k *ar,
|
|||
fft_sample->freq2 = __cpu_to_be16(freq);
|
||||
|
||||
ath11k_spectral_parse_fft(fft_sample->data, fft_report->bins, num_bins,
|
||||
ab->hw_params.spectral_fft_sz);
|
||||
ab->hw_params.spectral.fft_sz);
|
||||
|
||||
fft_sample->max_exp = ath11k_spectral_get_max_exp(fft_sample->max_index,
|
||||
search.peak_mag,
|
||||
|
|
@ -690,7 +689,7 @@ static int ath11k_spectral_process_data(struct ath11k *ar,
|
|||
goto unlock;
|
||||
}
|
||||
|
||||
sample_sz = sizeof(*fft_sample) + ATH11K_SPECTRAL_ATH11K_MAX_IB_BINS;
|
||||
sample_sz = sizeof(*fft_sample) + ATH11K_SPECTRAL_MAX_IB_BINS(ab);
|
||||
fft_sample = kmalloc(sample_sz, GFP_ATOMIC);
|
||||
if (!fft_sample) {
|
||||
ret = -ENOBUFS;
|
||||
|
|
@ -738,7 +737,8 @@ static int ath11k_spectral_process_data(struct ath11k *ar,
|
|||
* is 4 DWORD size (16 bytes).
|
||||
* Need to remove this workaround once HW bug fixed
|
||||
*/
|
||||
tlv_len = sizeof(*summary) - sizeof(*tlv);
|
||||
tlv_len = sizeof(*summary) - sizeof(*tlv) +
|
||||
ab->hw_params.spectral.summary_pad_sz;
|
||||
|
||||
if (tlv_len < (sizeof(*summary) - sizeof(*tlv))) {
|
||||
ath11k_warn(ab, "failed to parse spectral summary at bytes %d tlv_len:%d\n",
|
||||
|
|
@ -901,7 +901,7 @@ static inline int ath11k_spectral_debug_register(struct ath11k *ar)
|
|||
|
||||
ar->spectral.rfs_scan = relay_open("spectral_scan",
|
||||
ar->debug.debugfs_pdev,
|
||||
ATH11K_SPECTRAL_SUB_BUFF_SIZE,
|
||||
ATH11K_SPECTRAL_SUB_BUFF_SIZE(ar->ab),
|
||||
ATH11K_SPECTRAL_NUM_SUB_BUF,
|
||||
&rfs_scan_cb, NULL);
|
||||
if (!ar->spectral.rfs_scan) {
|
||||
|
|
@ -962,7 +962,7 @@ int ath11k_spectral_init(struct ath11k_base *ab)
|
|||
ab->wmi_ab.svc_map))
|
||||
return 0;
|
||||
|
||||
if (!ab->hw_params.spectral_fft_sz)
|
||||
if (!ab->hw_params.spectral.fft_sz)
|
||||
return 0;
|
||||
|
||||
for (i = 0; i < ab->num_radios; i++) {
|
||||
|
|
|
|||
|
|
@ -79,14 +79,15 @@ TRACE_EVENT(ath11k_htt_ppdu_stats,
|
|||
);
|
||||
|
||||
TRACE_EVENT(ath11k_htt_rxdesc,
|
||||
TP_PROTO(struct ath11k *ar, const void *data, size_t len),
|
||||
TP_PROTO(struct ath11k *ar, const void *data, size_t log_type, size_t len),
|
||||
|
||||
TP_ARGS(ar, data, len),
|
||||
TP_ARGS(ar, data, log_type, len),
|
||||
|
||||
TP_STRUCT__entry(
|
||||
__string(device, dev_name(ar->ab->dev))
|
||||
__string(driver, dev_driver_string(ar->ab->dev))
|
||||
__field(u16, len)
|
||||
__field(u16, log_type)
|
||||
__dynamic_array(u8, rxdesc, len)
|
||||
),
|
||||
|
||||
|
|
@ -94,14 +95,16 @@ TRACE_EVENT(ath11k_htt_rxdesc,
|
|||
__assign_str(device, dev_name(ar->ab->dev));
|
||||
__assign_str(driver, dev_driver_string(ar->ab->dev));
|
||||
__entry->len = len;
|
||||
__entry->log_type = log_type;
|
||||
memcpy(__get_dynamic_array(rxdesc), data, len);
|
||||
),
|
||||
|
||||
TP_printk(
|
||||
"%s %s rxdesc len %d",
|
||||
"%s %s rxdesc len %d type %d",
|
||||
__get_str(driver),
|
||||
__get_str(device),
|
||||
__entry->len
|
||||
__entry->len,
|
||||
__entry->log_type
|
||||
)
|
||||
);
|
||||
|
||||
|
|
|
|||
|
|
@ -360,6 +360,10 @@ ath11k_pull_mac_phy_cap_svc_ready_ext(struct ath11k_pdev_wmi *wmi_handle,
|
|||
pdev_cap->he_mcs = mac_phy_caps->he_supp_mcs_5g;
|
||||
pdev_cap->tx_chain_mask = mac_phy_caps->tx_chain_mask_5g;
|
||||
pdev_cap->rx_chain_mask = mac_phy_caps->rx_chain_mask_5g;
|
||||
pdev_cap->nss_ratio_enabled =
|
||||
WMI_NSS_RATIO_ENABLE_DISABLE_GET(mac_phy_caps->nss_ratio);
|
||||
pdev_cap->nss_ratio_info =
|
||||
WMI_NSS_RATIO_INFO_GET(mac_phy_caps->nss_ratio);
|
||||
} else {
|
||||
return -EINVAL;
|
||||
}
|
||||
|
|
@ -403,18 +407,18 @@ ath11k_pull_mac_phy_cap_svc_ready_ext(struct ath11k_pdev_wmi *wmi_handle,
|
|||
sizeof(u32) * PSOC_HOST_MAX_PHY_SIZE);
|
||||
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));
|
||||
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;
|
||||
}
|
||||
|
|
@ -783,14 +787,26 @@ int ath11k_wmi_vdev_down(struct ath11k *ar, u8 vdev_id)
|
|||
static void ath11k_wmi_put_wmi_channel(struct wmi_channel *chan,
|
||||
struct wmi_vdev_start_req_arg *arg)
|
||||
{
|
||||
u32 center_freq1 = arg->channel.band_center_freq1;
|
||||
|
||||
memset(chan, 0, sizeof(*chan));
|
||||
|
||||
chan->mhz = arg->channel.freq;
|
||||
chan->band_center_freq1 = arg->channel.band_center_freq1;
|
||||
if (arg->channel.mode == MODE_11AC_VHT80_80)
|
||||
|
||||
if (arg->channel.mode == MODE_11AX_HE160) {
|
||||
if (arg->channel.freq > arg->channel.band_center_freq1)
|
||||
chan->band_center_freq1 = center_freq1 + 40;
|
||||
else
|
||||
chan->band_center_freq1 = center_freq1 - 40;
|
||||
|
||||
chan->band_center_freq2 = arg->channel.band_center_freq1;
|
||||
|
||||
} else if (arg->channel.mode == MODE_11AC_VHT80_80) {
|
||||
chan->band_center_freq2 = arg->channel.band_center_freq2;
|
||||
else
|
||||
} else {
|
||||
chan->band_center_freq2 = 0;
|
||||
}
|
||||
|
||||
chan->info |= FIELD_PREP(WMI_CHAN_INFO_MODE, arg->channel.mode);
|
||||
if (arg->channel.passive)
|
||||
|
|
@ -868,6 +884,8 @@ int ath11k_wmi_vdev_start(struct ath11k *ar, struct wmi_vdev_start_req_arg *arg,
|
|||
}
|
||||
|
||||
cmd->flags |= WMI_VDEV_START_LDPC_RX_ENABLED;
|
||||
if (test_bit(ATH11K_FLAG_HW_CRYPTO_DISABLED, &ar->ab->dev_flags))
|
||||
cmd->flags |= WMI_VDEV_START_HW_ENCRYPTION_DISABLED;
|
||||
|
||||
ptr = skb->data + sizeof(*cmd);
|
||||
chan = ptr;
|
||||
|
|
@ -1339,6 +1357,7 @@ int ath11k_wmi_pdev_bss_chan_info_request(struct ath11k *ar,
|
|||
WMI_TAG_PDEV_BSS_CHAN_INFO_REQUEST) |
|
||||
FIELD_PREP(WMI_TLV_LEN, sizeof(*cmd) - TLV_HDR_SIZE);
|
||||
cmd->req_type = type;
|
||||
cmd->pdev_id = ar->pdev->pdev_id;
|
||||
|
||||
ath11k_dbg(ar->ab, ATH11K_DBG_WMI,
|
||||
"WMI bss chan info req type %d\n", type);
|
||||
|
|
@ -1903,8 +1922,8 @@ int ath11k_wmi_send_peer_assoc_cmd(struct ath11k *ar,
|
|||
FIELD_PREP(WMI_TLV_LEN,
|
||||
sizeof(*he_mcs) - TLV_HDR_SIZE);
|
||||
|
||||
he_mcs->rx_mcs_set = param->peer_he_rx_mcs_set[i];
|
||||
he_mcs->tx_mcs_set = param->peer_he_tx_mcs_set[i];
|
||||
he_mcs->rx_mcs_set = param->peer_he_tx_mcs_set[i];
|
||||
he_mcs->tx_mcs_set = param->peer_he_rx_mcs_set[i];
|
||||
ptr += sizeof(*he_mcs);
|
||||
}
|
||||
|
||||
|
|
@ -2285,7 +2304,7 @@ int ath11k_wmi_send_scan_chan_list_cmd(struct ath11k *ar,
|
|||
u16 num_send_chans, num_sends = 0, max_chan_limit = 0;
|
||||
u32 *reg1, *reg2;
|
||||
|
||||
tchan_info = &chan_list->ch_param[0];
|
||||
tchan_info = chan_list->ch_param;
|
||||
while (chan_list->nallchans) {
|
||||
len = sizeof(*cmd) + TLV_HDR_SIZE;
|
||||
max_chan_limit = (wmi->wmi_ab->max_msg_len[ar->pdev_idx] - len) /
|
||||
|
|
@ -3495,7 +3514,7 @@ ath11k_wmi_copy_resource_config(struct wmi_resource_config *wmi_cfg,
|
|||
wmi_cfg->bpf_instruction_size = tg_cfg->bpf_instruction_size;
|
||||
wmi_cfg->max_bssid_rx_filters = tg_cfg->max_bssid_rx_filters;
|
||||
wmi_cfg->use_pdev_id = tg_cfg->use_pdev_id;
|
||||
wmi_cfg->flag1 = tg_cfg->atf_config;
|
||||
wmi_cfg->flag1 = tg_cfg->flag1;
|
||||
wmi_cfg->peer_map_unmap_v2_support = tg_cfg->peer_map_unmap_v2_support;
|
||||
wmi_cfg->sched_params = tg_cfg->sched_params;
|
||||
wmi_cfg->twt_ap_pdev_count = tg_cfg->twt_ap_pdev_count;
|
||||
|
|
@ -5234,9 +5253,11 @@ ath11k_wmi_pull_pdev_stats_tx(const struct wmi_pdev_stats_tx *src,
|
|||
dst->hw_queued = src->hw_queued;
|
||||
dst->hw_reaped = src->hw_reaped;
|
||||
dst->underrun = src->underrun;
|
||||
dst->hw_paused = src->hw_paused;
|
||||
dst->tx_abort = src->tx_abort;
|
||||
dst->mpdus_requeued = src->mpdus_requeued;
|
||||
dst->tx_ko = src->tx_ko;
|
||||
dst->tx_xretry = src->tx_xretry;
|
||||
dst->data_rc = src->data_rc;
|
||||
dst->self_triggers = src->self_triggers;
|
||||
dst->sw_retry_failure = src->sw_retry_failure;
|
||||
|
|
@ -5247,6 +5268,16 @@ ath11k_wmi_pull_pdev_stats_tx(const struct wmi_pdev_stats_tx *src,
|
|||
dst->stateless_tid_alloc_failure = src->stateless_tid_alloc_failure;
|
||||
dst->phy_underrun = src->phy_underrun;
|
||||
dst->txop_ovf = src->txop_ovf;
|
||||
dst->seq_posted = src->seq_posted;
|
||||
dst->seq_failed_queueing = src->seq_failed_queueing;
|
||||
dst->seq_completed = src->seq_completed;
|
||||
dst->seq_restarted = src->seq_restarted;
|
||||
dst->mu_seq_posted = src->mu_seq_posted;
|
||||
dst->mpdus_sw_flush = src->mpdus_sw_flush;
|
||||
dst->mpdus_hw_filter = src->mpdus_hw_filter;
|
||||
dst->mpdus_truncated = src->mpdus_truncated;
|
||||
dst->mpdus_ack_failed = src->mpdus_ack_failed;
|
||||
dst->mpdus_expired = src->mpdus_expired;
|
||||
}
|
||||
|
||||
static void ath11k_wmi_pull_pdev_stats_rx(const struct wmi_pdev_stats_rx *src,
|
||||
|
|
@ -5266,6 +5297,7 @@ static void ath11k_wmi_pull_pdev_stats_rx(const struct wmi_pdev_stats_rx *src,
|
|||
dst->phy_errs = src->phy_errs;
|
||||
dst->phy_err_drop = src->phy_err_drop;
|
||||
dst->mpdu_errs = src->mpdu_errs;
|
||||
dst->rx_ovfl_errs = src->rx_ovfl_errs;
|
||||
}
|
||||
|
||||
static void
|
||||
|
|
@ -5502,12 +5534,16 @@ ath11k_wmi_fw_pdev_tx_stats_fill(const struct ath11k_fw_stats_pdev *pdev,
|
|||
"PPDUs reaped", pdev->hw_reaped);
|
||||
len += scnprintf(buf + len, buf_len - len, "%30s %10d\n",
|
||||
"Num underruns", pdev->underrun);
|
||||
len += scnprintf(buf + len, buf_len - len, "%30s %10d\n",
|
||||
"Num HW Paused", pdev->hw_paused);
|
||||
len += scnprintf(buf + len, buf_len - len, "%30s %10d\n",
|
||||
"PPDUs cleaned", pdev->tx_abort);
|
||||
len += scnprintf(buf + len, buf_len - len, "%30s %10d\n",
|
||||
"MPDUs requeued", pdev->mpdus_requeued);
|
||||
len += scnprintf(buf + len, buf_len - len, "%30s %10u\n",
|
||||
"Excessive retries", pdev->tx_ko);
|
||||
"PPDU OK", pdev->tx_ko);
|
||||
len += scnprintf(buf + len, buf_len - len, "%30s %10u\n",
|
||||
"Excessive retries", pdev->tx_xretry);
|
||||
len += scnprintf(buf + len, buf_len - len, "%30s %10u\n",
|
||||
"HW rate", pdev->data_rc);
|
||||
len += scnprintf(buf + len, buf_len - len, "%30s %10u\n",
|
||||
|
|
@ -5531,6 +5567,26 @@ ath11k_wmi_fw_pdev_tx_stats_fill(const struct ath11k_fw_stats_pdev *pdev,
|
|||
"PHY underrun", pdev->phy_underrun);
|
||||
len += scnprintf(buf + len, buf_len - len, "%30s %10u\n",
|
||||
"MPDU is more than txop limit", pdev->txop_ovf);
|
||||
len += scnprintf(buf + len, buf_len - len, "%30s %10u\n",
|
||||
"Num sequences posted", pdev->seq_posted);
|
||||
len += scnprintf(buf + len, buf_len - len, "%30s %10u\n",
|
||||
"Num seq failed queueing ", pdev->seq_failed_queueing);
|
||||
len += scnprintf(buf + len, buf_len - len, "%30s %10u\n",
|
||||
"Num sequences completed ", pdev->seq_completed);
|
||||
len += scnprintf(buf + len, buf_len - len, "%30s %10u\n",
|
||||
"Num sequences restarted ", pdev->seq_restarted);
|
||||
len += scnprintf(buf + len, buf_len - len, "%30s %10u\n",
|
||||
"Num of MU sequences posted ", pdev->mu_seq_posted);
|
||||
len += scnprintf(buf + len, buf_len - len, "%30s %10u\n",
|
||||
"Num of MPDUS SW flushed ", pdev->mpdus_sw_flush);
|
||||
len += scnprintf(buf + len, buf_len - len, "%30s %10u\n",
|
||||
"Num of MPDUS HW filtered ", pdev->mpdus_hw_filter);
|
||||
len += scnprintf(buf + len, buf_len - len, "%30s %10u\n",
|
||||
"Num of MPDUS truncated ", pdev->mpdus_truncated);
|
||||
len += scnprintf(buf + len, buf_len - len, "%30s %10u\n",
|
||||
"Num of MPDUS ACK failed ", pdev->mpdus_ack_failed);
|
||||
len += scnprintf(buf + len, buf_len - len, "%30s %10u\n",
|
||||
"Num of MPDUS expired ", pdev->mpdus_expired);
|
||||
*length = len;
|
||||
}
|
||||
|
||||
|
|
@ -5575,6 +5631,8 @@ ath11k_wmi_fw_pdev_rx_stats_fill(const struct ath11k_fw_stats_pdev *pdev,
|
|||
"PHY errors drops", pdev->phy_err_drop);
|
||||
len += scnprintf(buf + len, buf_len - len, "%30s %10d\n",
|
||||
"MPDU errors (FCS, MIC, ENC)", pdev->mpdu_errs);
|
||||
len += scnprintf(buf + len, buf_len - len, "%30s %10d\n",
|
||||
"Overflow errors", pdev->rx_ovfl_errs);
|
||||
*length = len;
|
||||
}
|
||||
|
||||
|
|
@ -5792,6 +5850,17 @@ static int ath11k_reg_chan_list_event(struct ath11k_base *ab, struct sk_buff *sk
|
|||
|
||||
pdev_idx = reg_info->phy_id;
|
||||
|
||||
/* Avoid default reg rule updates sent during FW recovery if
|
||||
* it is already available
|
||||
*/
|
||||
spin_lock(&ab->base_lock);
|
||||
if (test_bit(ATH11K_FLAG_RECOVERY, &ab->dev_flags) &&
|
||||
ab->default_regd[pdev_idx]) {
|
||||
spin_unlock(&ab->base_lock);
|
||||
goto mem_free;
|
||||
}
|
||||
spin_unlock(&ab->base_lock);
|
||||
|
||||
if (pdev_idx >= ab->num_radios) {
|
||||
/* Process the event for phy0 only if single_pdev_only
|
||||
* is true. If pdev_idx is valid but not 0, discard the
|
||||
|
|
@ -5829,10 +5898,10 @@ static int ath11k_reg_chan_list_event(struct ath11k_base *ab, struct sk_buff *sk
|
|||
}
|
||||
|
||||
spin_lock(&ab->base_lock);
|
||||
if (test_bit(ATH11K_FLAG_REGISTERED, &ab->dev_flags)) {
|
||||
/* Once mac is registered, ar is valid and all CC events from
|
||||
* fw is considered to be received due to user requests
|
||||
* currently.
|
||||
if (ab->default_regd[pdev_idx]) {
|
||||
/* The initial rules from FW after WMI Init is to build
|
||||
* the default regd. From then on, any rules updated for
|
||||
* the pdev could be due to user reg changes.
|
||||
* Free previously built regd before assigning the newly
|
||||
* generated regd to ar. NULL pointer handling will be
|
||||
* taken care by kfree itself.
|
||||
|
|
@ -5842,13 +5911,9 @@ static int ath11k_reg_chan_list_event(struct ath11k_base *ab, struct sk_buff *sk
|
|||
ab->new_regd[pdev_idx] = regd;
|
||||
ieee80211_queue_work(ar->hw, &ar->regd_update_work);
|
||||
} else {
|
||||
/* Multiple events for the same *ar is not expected. But we
|
||||
* can still clear any previously stored default_regd if we
|
||||
* are receiving this event for the same radio by mistake.
|
||||
* NULL pointer handling will be taken care by kfree itself.
|
||||
/* This regd would be applied during mac registration and is
|
||||
* held constant throughout for regd intersection purpose
|
||||
*/
|
||||
kfree(ab->default_regd[pdev_idx]);
|
||||
/* This regd would be applied during mac registration */
|
||||
ab->default_regd[pdev_idx] = regd;
|
||||
}
|
||||
ab->dfs_region = reg_info->dfs_region;
|
||||
|
|
@ -6119,8 +6184,10 @@ 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.chan_freq >= ATH11K_MIN_6G_FREQ) {
|
||||
if (rx_ev.chan_freq >= ATH11K_MIN_6G_FREQ &&
|
||||
rx_ev.chan_freq <= ATH11K_MAX_6G_FREQ) {
|
||||
status->band = NL80211_BAND_6GHZ;
|
||||
status->freq = rx_ev.chan_freq;
|
||||
} 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) {
|
||||
|
|
@ -6141,8 +6208,10 @@ static void ath11k_mgmt_rx_event(struct ath11k_base *ab, struct sk_buff *skb)
|
|||
|
||||
sband = &ar->mac.sbands[status->band];
|
||||
|
||||
status->freq = ieee80211_channel_to_frequency(rx_ev.channel,
|
||||
status->band);
|
||||
if (status->band != NL80211_BAND_6GHZ)
|
||||
status->freq = ieee80211_channel_to_frequency(rx_ev.channel,
|
||||
status->band);
|
||||
|
||||
status->signal = rx_ev.snr + ATH11K_DEFAULT_NOISE_FLOOR;
|
||||
status->rate_idx = ath11k_mac_bitrate_to_idx(sband, rx_ev.rate / 100);
|
||||
|
||||
|
|
@ -6220,8 +6289,9 @@ static void ath11k_mgmt_tx_compl_event(struct ath11k_base *ab, struct sk_buff *s
|
|||
rcu_read_unlock();
|
||||
}
|
||||
|
||||
static struct ath11k *ath11k_get_ar_on_scan_abort(struct ath11k_base *ab,
|
||||
u32 vdev_id)
|
||||
static struct ath11k *ath11k_get_ar_on_scan_state(struct ath11k_base *ab,
|
||||
u32 vdev_id,
|
||||
enum ath11k_scan_state state)
|
||||
{
|
||||
int i;
|
||||
struct ath11k_pdev *pdev;
|
||||
|
|
@ -6233,7 +6303,7 @@ static struct ath11k *ath11k_get_ar_on_scan_abort(struct ath11k_base *ab,
|
|||
ar = pdev->ar;
|
||||
|
||||
spin_lock_bh(&ar->data_lock);
|
||||
if (ar->scan.state == ATH11K_SCAN_ABORTING &&
|
||||
if (ar->scan.state == state &&
|
||||
ar->scan.vdev_id == vdev_id) {
|
||||
spin_unlock_bh(&ar->data_lock);
|
||||
return ar;
|
||||
|
|
@ -6263,10 +6333,15 @@ static void ath11k_scan_event(struct ath11k_base *ab, struct sk_buff *skb)
|
|||
* aborting scan's vdev id matches this event info.
|
||||
*/
|
||||
if (scan_ev.event_type == WMI_SCAN_EVENT_COMPLETED &&
|
||||
scan_ev.reason == WMI_SCAN_REASON_CANCELLED)
|
||||
ar = ath11k_get_ar_on_scan_abort(ab, scan_ev.vdev_id);
|
||||
else
|
||||
scan_ev.reason == WMI_SCAN_REASON_CANCELLED) {
|
||||
ar = ath11k_get_ar_on_scan_state(ab, scan_ev.vdev_id,
|
||||
ATH11K_SCAN_ABORTING);
|
||||
if (!ar)
|
||||
ar = ath11k_get_ar_on_scan_state(ab, scan_ev.vdev_id,
|
||||
ATH11K_SCAN_RUNNING);
|
||||
} else {
|
||||
ar = ath11k_mac_get_ar_by_vdev_id(ab, scan_ev.vdev_id);
|
||||
}
|
||||
|
||||
if (!ar) {
|
||||
ath11k_warn(ab, "Received scan event for unknown vdev");
|
||||
|
|
@ -6301,6 +6376,8 @@ static void ath11k_scan_event(struct ath11k_base *ab, struct sk_buff *skb)
|
|||
ath11k_wmi_event_scan_start_failed(ar);
|
||||
break;
|
||||
case WMI_SCAN_EVENT_DEQUEUED:
|
||||
__ath11k_mac_scan_finish(ar);
|
||||
break;
|
||||
case WMI_SCAN_EVENT_PREEMPTED:
|
||||
case WMI_SCAN_EVENT_RESTARTED:
|
||||
case WMI_SCAN_EVENT_FOREIGN_CHAN_EXIT:
|
||||
|
|
@ -7065,6 +7142,7 @@ static void ath11k_wmi_tlv_op_rx(struct ath11k_base *ab, struct sk_buff *skb)
|
|||
case WMI_TWT_ENABLE_EVENTID:
|
||||
case WMI_TWT_DISABLE_EVENTID:
|
||||
case WMI_PDEV_DMA_RING_CFG_RSP_EVENTID:
|
||||
case WMI_PEER_CREATE_CONF_EVENTID:
|
||||
ath11k_dbg(ab, ATH11K_DBG_WMI,
|
||||
"ignoring unsupported event 0x%x\n", id);
|
||||
break;
|
||||
|
|
|
|||
|
|
@ -119,6 +119,22 @@ enum {
|
|||
WMI_HOST_WLAN_2G_5G_CAP = 0x3,
|
||||
};
|
||||
|
||||
/* Parameters used for WMI_VDEV_PARAM_AUTORATE_MISC_CFG command.
|
||||
* Used only for HE auto rate mode.
|
||||
*/
|
||||
enum {
|
||||
/* HE LTF related configuration */
|
||||
WMI_HE_AUTORATE_LTF_1X = BIT(0),
|
||||
WMI_HE_AUTORATE_LTF_2X = BIT(1),
|
||||
WMI_HE_AUTORATE_LTF_4X = BIT(2),
|
||||
|
||||
/* HE GI related configuration */
|
||||
WMI_AUTORATE_400NS_GI = BIT(8),
|
||||
WMI_AUTORATE_800NS_GI = BIT(9),
|
||||
WMI_AUTORATE_1600NS_GI = BIT(10),
|
||||
WMI_AUTORATE_3200NS_GI = BIT(11),
|
||||
};
|
||||
|
||||
/*
|
||||
* wmi command groups.
|
||||
*/
|
||||
|
|
@ -647,6 +663,9 @@ enum wmi_tlv_event_id {
|
|||
WMI_PEER_RESERVED9_EVENTID,
|
||||
WMI_PEER_RESERVED10_EVENTID,
|
||||
WMI_PEER_OPER_MODE_CHANGE_EVENTID,
|
||||
WMI_PEER_TX_PN_RESPONSE_EVENTID,
|
||||
WMI_PEER_CFR_CAPTURE_EVENTID,
|
||||
WMI_PEER_CREATE_CONF_EVENTID,
|
||||
WMI_MGMT_RX_EVENTID = WMI_TLV_CMD(WMI_GRP_MGMT),
|
||||
WMI_HOST_SWBA_EVENTID,
|
||||
WMI_TBTTOFFSET_UPDATE_EVENTID,
|
||||
|
|
@ -1044,7 +1063,9 @@ enum wmi_tlv_vdev_param {
|
|||
WMI_VDEV_PARAM_HE_RANGE_EXT,
|
||||
WMI_VDEV_PARAM_ENABLE_BCAST_PROBE_RESPONSE,
|
||||
WMI_VDEV_PARAM_FILS_MAX_CHANNEL_GUARD_TIME,
|
||||
WMI_VDEV_PARAM_HE_LTF = 0x74,
|
||||
WMI_VDEV_PARAM_BA_MODE = 0x7e,
|
||||
WMI_VDEV_PARAM_AUTORATE_MISC_CFG = 0x80,
|
||||
WMI_VDEV_PARAM_SET_HE_SOUNDING_MODE = 0x87,
|
||||
WMI_VDEV_PARAM_6GHZ_PARAMS = 0x99,
|
||||
WMI_VDEV_PARAM_PROTOTYPE = 0x8000,
|
||||
|
|
@ -2128,6 +2149,24 @@ enum wmi_direct_buffer_module {
|
|||
WMI_DIRECT_BUF_MAX
|
||||
};
|
||||
|
||||
/* enum wmi_nss_ratio - NSS ratio received from FW during service ready ext
|
||||
* event
|
||||
* WMI_NSS_RATIO_1BY2_NSS -Max nss of 160MHz is equals to half of the max nss
|
||||
* of 80MHz
|
||||
* WMI_NSS_RATIO_3BY4_NSS - Max nss of 160MHz is equals to 3/4 of the max nss
|
||||
* of 80MHz
|
||||
* WMI_NSS_RATIO_1_NSS - Max nss of 160MHz is equals to the max nss of 80MHz
|
||||
* WMI_NSS_RATIO_2_NSS - Max nss of 160MHz is equals to two times the max
|
||||
* nss of 80MHz
|
||||
*/
|
||||
|
||||
enum wmi_nss_ratio {
|
||||
WMI_NSS_RATIO_1BY2_NSS = 0x0,
|
||||
WMI_NSS_RATIO_3BY4_NSS = 0x1,
|
||||
WMI_NSS_RATIO_1_NSS = 0x2,
|
||||
WMI_NSS_RATIO_2_NSS = 0x3,
|
||||
};
|
||||
|
||||
struct wmi_host_pdev_band_to_mac {
|
||||
u32 pdev_id;
|
||||
u32 start_freq;
|
||||
|
|
@ -2244,6 +2283,8 @@ struct wmi_init_cmd {
|
|||
u32 num_host_mem_chunks;
|
||||
} __packed;
|
||||
|
||||
#define WMI_RSRC_CFG_FLAG1_BSS_CHANNEL_INFO_64 BIT(5)
|
||||
|
||||
struct wmi_resource_config {
|
||||
u32 tlv_header;
|
||||
u32 num_vdevs;
|
||||
|
|
@ -2370,6 +2411,12 @@ struct wmi_hw_mode_capabilities {
|
|||
} __packed;
|
||||
|
||||
#define WMI_MAX_HECAP_PHY_SIZE (3)
|
||||
#define WMI_NSS_RATIO_ENABLE_DISABLE_BITPOS BIT(0)
|
||||
#define WMI_NSS_RATIO_ENABLE_DISABLE_GET(_val) \
|
||||
FIELD_GET(WMI_NSS_RATIO_ENABLE_DISABLE_BITPOS, _val)
|
||||
#define WMI_NSS_RATIO_INFO_BITPOS GENMASK(4, 1)
|
||||
#define WMI_NSS_RATIO_INFO_GET(_val) \
|
||||
FIELD_GET(WMI_NSS_RATIO_INFO_BITPOS, _val)
|
||||
|
||||
struct wmi_mac_phy_capabilities {
|
||||
u32 hw_mode_id;
|
||||
|
|
@ -2403,6 +2450,12 @@ struct wmi_mac_phy_capabilities {
|
|||
u32 he_cap_info_2g_ext;
|
||||
u32 he_cap_info_5g_ext;
|
||||
u32 he_cap_info_internal;
|
||||
u32 wireless_modes;
|
||||
u32 low_2ghz_chan_freq;
|
||||
u32 high_2ghz_chan_freq;
|
||||
u32 low_5ghz_chan_freq;
|
||||
u32 high_5ghz_chan_freq;
|
||||
u32 nss_ratio;
|
||||
} __packed;
|
||||
|
||||
struct wmi_hal_reg_capabilities_ext {
|
||||
|
|
@ -2527,6 +2580,7 @@ struct wmi_vdev_down_cmd {
|
|||
#define WMI_VDEV_START_HIDDEN_SSID BIT(0)
|
||||
#define WMI_VDEV_START_PMF_ENABLED BIT(1)
|
||||
#define WMI_VDEV_START_LDPC_RX_ENABLED BIT(3)
|
||||
#define WMI_VDEV_START_HW_ENCRYPTION_DISABLED BIT(4)
|
||||
|
||||
struct wmi_ssid {
|
||||
u32 ssid_len;
|
||||
|
|
@ -2960,6 +3014,7 @@ struct wmi_pdev_bss_chan_info_req_cmd {
|
|||
u32 tlv_header;
|
||||
/* ref wmi_bss_chan_info_req_type */
|
||||
u32 req_type;
|
||||
u32 pdev_id;
|
||||
} __packed;
|
||||
|
||||
struct wmi_ap_ps_peer_cmd {
|
||||
|
|
@ -3608,7 +3663,7 @@ struct wmi_stop_scan_cmd {
|
|||
struct scan_chan_list_params {
|
||||
u32 pdev_id;
|
||||
u16 nallchans;
|
||||
struct channel_param ch_param[1];
|
||||
struct channel_param ch_param[];
|
||||
};
|
||||
|
||||
struct wmi_scan_chan_list_cmd {
|
||||
|
|
@ -3917,7 +3972,11 @@ struct wmi_vht_rate_set {
|
|||
|
||||
struct wmi_he_rate_set {
|
||||
u32 tlv_header;
|
||||
|
||||
/* MCS at which the peer can receive */
|
||||
u32 rx_mcs_set;
|
||||
|
||||
/* MCS at which the peer can transmit */
|
||||
u32 tx_mcs_set;
|
||||
} __packed;
|
||||
|
||||
|
|
@ -4056,7 +4115,6 @@ struct wmi_vdev_stopped_event {
|
|||
} __packed;
|
||||
|
||||
struct wmi_pdev_bss_chan_info_event {
|
||||
u32 pdev_id;
|
||||
u32 freq; /* Units in MHz */
|
||||
u32 noise_floor; /* units are dBm */
|
||||
/* rx clear - how often the channel was unused */
|
||||
|
|
@ -4074,6 +4132,7 @@ struct wmi_pdev_bss_chan_info_event {
|
|||
/*rx_cycle cnt for my bss in 64bits format */
|
||||
u32 rx_bss_cycle_count_low;
|
||||
u32 rx_bss_cycle_count_high;
|
||||
u32 pdev_id;
|
||||
} __packed;
|
||||
|
||||
#define WMI_VDEV_INSTALL_KEY_COMPL_STATUS_SUCCESS 0
|
||||
|
|
@ -4168,6 +4227,9 @@ struct wmi_pdev_stats_tx {
|
|||
/* Num underruns */
|
||||
s32 underrun;
|
||||
|
||||
/* Num hw paused */
|
||||
u32 hw_paused;
|
||||
|
||||
/* Num PPDUs cleaned up in TX abort */
|
||||
s32 tx_abort;
|
||||
|
||||
|
|
@ -4177,6 +4239,8 @@ struct wmi_pdev_stats_tx {
|
|||
/* excessive retries */
|
||||
u32 tx_ko;
|
||||
|
||||
u32 tx_xretry;
|
||||
|
||||
/* data hw rate code */
|
||||
u32 data_rc;
|
||||
|
||||
|
|
@ -4206,6 +4270,40 @@ struct wmi_pdev_stats_tx {
|
|||
|
||||
/* MPDU is more than txop limit */
|
||||
u32 txop_ovf;
|
||||
|
||||
/* Num sequences posted */
|
||||
u32 seq_posted;
|
||||
|
||||
/* Num sequences failed in queueing */
|
||||
u32 seq_failed_queueing;
|
||||
|
||||
/* Num sequences completed */
|
||||
u32 seq_completed;
|
||||
|
||||
/* Num sequences restarted */
|
||||
u32 seq_restarted;
|
||||
|
||||
/* Num of MU sequences posted */
|
||||
u32 mu_seq_posted;
|
||||
|
||||
/* Num MPDUs flushed by SW, HWPAUSED, SW TXABORT
|
||||
* (Reset,channel change)
|
||||
*/
|
||||
s32 mpdus_sw_flush;
|
||||
|
||||
/* Num MPDUs filtered by HW, all filter condition (TTL expired) */
|
||||
s32 mpdus_hw_filter;
|
||||
|
||||
/* Num MPDUs truncated by PDG (TXOP, TBTT,
|
||||
* PPDU_duration based on rate, dyn_bw)
|
||||
*/
|
||||
s32 mpdus_truncated;
|
||||
|
||||
/* Num MPDUs that was tried but didn't receive ACK or BA */
|
||||
s32 mpdus_ack_failed;
|
||||
|
||||
/* Num MPDUs that was dropped du to expiry. */
|
||||
s32 mpdus_expired;
|
||||
} __packed;
|
||||
|
||||
struct wmi_pdev_stats_rx {
|
||||
|
|
@ -4240,6 +4338,9 @@ struct wmi_pdev_stats_rx {
|
|||
|
||||
/* Number of mpdu errors - FCS, MIC, ENC etc. */
|
||||
s32 mpdu_errs;
|
||||
|
||||
/* Num overflow errors */
|
||||
s32 rx_ovfl_errs;
|
||||
} __packed;
|
||||
|
||||
struct wmi_pdev_stats {
|
||||
|
|
@ -5014,7 +5115,7 @@ struct target_resource_config {
|
|||
u32 vo_minfree;
|
||||
u32 rx_batchmode;
|
||||
u32 tt_support;
|
||||
u32 atf_config;
|
||||
u32 flag1;
|
||||
u32 iphdr_pad_config;
|
||||
u32 qwrap_config:16,
|
||||
alloc_frag_desc_for_data_pkt:16;
|
||||
|
|
|
|||
|
|
@ -19,9 +19,14 @@
|
|||
#include <linux/delay.h>
|
||||
#include <linux/platform_device.h>
|
||||
#include <linux/ath9k_platform.h>
|
||||
#include <linux/nvmem-consumer.h>
|
||||
#include <linux/workqueue.h>
|
||||
|
||||
struct owl_ctx {
|
||||
struct pci_dev *pdev;
|
||||
struct completion eeprom_load;
|
||||
struct work_struct work;
|
||||
struct nvmem_cell *cell;
|
||||
};
|
||||
|
||||
#define EEPROM_FILENAME_LEN 100
|
||||
|
|
@ -42,6 +47,12 @@ static int ath9k_pci_fixup(struct pci_dev *pdev, const u16 *cal_data,
|
|||
u32 bar0;
|
||||
bool swap_needed = false;
|
||||
|
||||
/* also note that we are doing *u16 operations on the file */
|
||||
if (cal_len > 4096 || cal_len < 0x200 || (cal_len & 1) == 1) {
|
||||
dev_err(&pdev->dev, "eeprom has an invalid size.\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
if (*cal_data != AR5416_EEPROM_MAGIC) {
|
||||
if (*cal_data != swab16(AR5416_EEPROM_MAGIC)) {
|
||||
dev_err(&pdev->dev, "invalid calibration data\n");
|
||||
|
|
@ -99,38 +110,31 @@ static int ath9k_pci_fixup(struct pci_dev *pdev, const u16 *cal_data,
|
|||
return 0;
|
||||
}
|
||||
|
||||
static void owl_fw_cb(const struct firmware *fw, void *context)
|
||||
static void owl_rescan(struct pci_dev *pdev)
|
||||
{
|
||||
struct pci_dev *pdev = (struct pci_dev *)context;
|
||||
struct owl_ctx *ctx = (struct owl_ctx *)pci_get_drvdata(pdev);
|
||||
struct pci_bus *bus;
|
||||
|
||||
complete(&ctx->eeprom_load);
|
||||
|
||||
if (!fw) {
|
||||
dev_err(&pdev->dev, "no eeprom data received.\n");
|
||||
goto release;
|
||||
}
|
||||
|
||||
/* also note that we are doing *u16 operations on the file */
|
||||
if (fw->size > 4096 || fw->size < 0x200 || (fw->size & 1) == 1) {
|
||||
dev_err(&pdev->dev, "eeprom file has an invalid size.\n");
|
||||
goto release;
|
||||
}
|
||||
|
||||
if (ath9k_pci_fixup(pdev, (const u16 *)fw->data, fw->size))
|
||||
goto release;
|
||||
struct pci_bus *bus = pdev->bus;
|
||||
|
||||
pci_lock_rescan_remove();
|
||||
bus = pdev->bus;
|
||||
pci_stop_and_remove_bus_device(pdev);
|
||||
/* the device should come back with the proper
|
||||
* ProductId. But we have to initiate a rescan.
|
||||
*/
|
||||
pci_rescan_bus(bus);
|
||||
pci_unlock_rescan_remove();
|
||||
}
|
||||
|
||||
release:
|
||||
static void owl_fw_cb(const struct firmware *fw, void *context)
|
||||
{
|
||||
struct owl_ctx *ctx = (struct owl_ctx *)context;
|
||||
|
||||
complete(&ctx->eeprom_load);
|
||||
|
||||
if (fw) {
|
||||
ath9k_pci_fixup(ctx->pdev, (const u16 *)fw->data, fw->size);
|
||||
owl_rescan(ctx->pdev);
|
||||
} else {
|
||||
dev_err(&ctx->pdev->dev, "no eeprom data received.\n");
|
||||
}
|
||||
release_firmware(fw);
|
||||
}
|
||||
|
||||
|
|
@ -152,6 +156,43 @@ static const char *owl_get_eeprom_name(struct pci_dev *pdev)
|
|||
return eeprom_name;
|
||||
}
|
||||
|
||||
static void owl_nvmem_work(struct work_struct *work)
|
||||
{
|
||||
struct owl_ctx *ctx = container_of(work, struct owl_ctx, work);
|
||||
void *buf;
|
||||
size_t len;
|
||||
|
||||
complete(&ctx->eeprom_load);
|
||||
|
||||
buf = nvmem_cell_read(ctx->cell, &len);
|
||||
if (!IS_ERR(buf)) {
|
||||
ath9k_pci_fixup(ctx->pdev, buf, len);
|
||||
kfree(buf);
|
||||
owl_rescan(ctx->pdev);
|
||||
} else {
|
||||
dev_err(&ctx->pdev->dev, "no nvmem data received.\n");
|
||||
}
|
||||
}
|
||||
|
||||
static int owl_nvmem_probe(struct owl_ctx *ctx)
|
||||
{
|
||||
int err;
|
||||
|
||||
ctx->cell = devm_nvmem_cell_get(&ctx->pdev->dev, "calibration");
|
||||
if (IS_ERR(ctx->cell)) {
|
||||
err = PTR_ERR(ctx->cell);
|
||||
if (err == -ENOENT || err == -EOPNOTSUPP)
|
||||
return 1; /* not present, try firmware_request */
|
||||
|
||||
return err;
|
||||
}
|
||||
|
||||
INIT_WORK(&ctx->work, owl_nvmem_work);
|
||||
schedule_work(&ctx->work);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int owl_probe(struct pci_dev *pdev,
|
||||
const struct pci_device_id *id)
|
||||
{
|
||||
|
|
@ -164,21 +205,27 @@ static int owl_probe(struct pci_dev *pdev,
|
|||
|
||||
pcim_pin_device(pdev);
|
||||
|
||||
ctx = devm_kzalloc(&pdev->dev, sizeof(*ctx), GFP_KERNEL);
|
||||
if (!ctx)
|
||||
return -ENOMEM;
|
||||
|
||||
init_completion(&ctx->eeprom_load);
|
||||
ctx->pdev = pdev;
|
||||
|
||||
pci_set_drvdata(pdev, ctx);
|
||||
|
||||
err = owl_nvmem_probe(ctx);
|
||||
if (err <= 0)
|
||||
return err;
|
||||
|
||||
eeprom_name = owl_get_eeprom_name(pdev);
|
||||
if (!eeprom_name) {
|
||||
dev_err(&pdev->dev, "no eeprom filename found.\n");
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
ctx = devm_kzalloc(&pdev->dev, sizeof(*ctx), GFP_KERNEL);
|
||||
if (!ctx)
|
||||
return -ENOMEM;
|
||||
|
||||
init_completion(&ctx->eeprom_load);
|
||||
|
||||
pci_set_drvdata(pdev, ctx);
|
||||
err = request_firmware_nowait(THIS_MODULE, true, eeprom_name,
|
||||
&pdev->dev, GFP_KERNEL, pdev, owl_fw_cb);
|
||||
&pdev->dev, GFP_KERNEL, ctx, owl_fw_cb);
|
||||
if (err)
|
||||
dev_err(&pdev->dev, "failed to request caldata (%d).\n", err);
|
||||
|
||||
|
|
|
|||
|
|
@ -135,13 +135,23 @@ static bool ath9k_hw_nvram_read_firmware(const struct firmware *eeprom_blob,
|
|||
offset, data);
|
||||
}
|
||||
|
||||
static bool ath9k_hw_nvram_read_nvmem(struct ath_hw *ah, off_t offset,
|
||||
u16 *data)
|
||||
{
|
||||
return ath9k_hw_nvram_read_array(ah->nvmem_blob,
|
||||
ah->nvmem_blob_len / sizeof(u16),
|
||||
offset, data);
|
||||
}
|
||||
|
||||
bool ath9k_hw_nvram_read(struct ath_hw *ah, u32 off, u16 *data)
|
||||
{
|
||||
struct ath_common *common = ath9k_hw_common(ah);
|
||||
struct ath9k_platform_data *pdata = ah->dev->platform_data;
|
||||
bool ret;
|
||||
|
||||
if (ah->eeprom_blob)
|
||||
if (ah->nvmem_blob)
|
||||
ret = ath9k_hw_nvram_read_nvmem(ah, off, data);
|
||||
else if (ah->eeprom_blob)
|
||||
ret = ath9k_hw_nvram_read_firmware(ah->eeprom_blob, off, data);
|
||||
else if (pdata && !pdata->use_eeprom)
|
||||
ret = ath9k_hw_nvram_read_pdata(pdata, off, data);
|
||||
|
|
|
|||
|
|
@ -977,6 +977,8 @@ struct ath_hw {
|
|||
bool disable_5ghz;
|
||||
|
||||
const struct firmware *eeprom_blob;
|
||||
u16 *nvmem_blob; /* devres managed */
|
||||
size_t nvmem_blob_len;
|
||||
|
||||
struct ath_dynack dynack;
|
||||
|
||||
|
|
|
|||
|
|
@ -22,6 +22,7 @@
|
|||
#include <linux/module.h>
|
||||
#include <linux/of.h>
|
||||
#include <linux/of_net.h>
|
||||
#include <linux/nvmem-consumer.h>
|
||||
#include <linux/relay.h>
|
||||
#include <linux/dmi.h>
|
||||
#include <net/ieee80211_radiotap.h>
|
||||
|
|
@ -568,6 +569,57 @@ static void ath9k_eeprom_release(struct ath_softc *sc)
|
|||
release_firmware(sc->sc_ah->eeprom_blob);
|
||||
}
|
||||
|
||||
static int ath9k_nvmem_request_eeprom(struct ath_softc *sc)
|
||||
{
|
||||
struct ath_hw *ah = sc->sc_ah;
|
||||
struct nvmem_cell *cell;
|
||||
void *buf;
|
||||
size_t len;
|
||||
int err;
|
||||
|
||||
cell = devm_nvmem_cell_get(sc->dev, "calibration");
|
||||
if (IS_ERR(cell)) {
|
||||
err = PTR_ERR(cell);
|
||||
|
||||
/* nvmem cell might not be defined, or the nvmem
|
||||
* subsystem isn't included. In this case, follow
|
||||
* the established "just return 0;" convention of
|
||||
* ath9k_init_platform to say:
|
||||
* "All good. Nothing to see here. Please go on."
|
||||
*/
|
||||
if (err == -ENOENT || err == -EOPNOTSUPP)
|
||||
return 0;
|
||||
|
||||
return err;
|
||||
}
|
||||
|
||||
buf = nvmem_cell_read(cell, &len);
|
||||
if (IS_ERR(buf))
|
||||
return PTR_ERR(buf);
|
||||
|
||||
/* run basic sanity checks on the returned nvram cell length.
|
||||
* That length has to be a multiple of a "u16" (i.e.: & 1).
|
||||
* Furthermore, it has to be more than "let's say" 512 bytes
|
||||
* but less than the maximum of AR9300_EEPROM_SIZE (16kb).
|
||||
*/
|
||||
if ((len & 1) == 1 || len < 512 || len >= AR9300_EEPROM_SIZE) {
|
||||
kfree(buf);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
/* devres manages the calibration values release on shutdown */
|
||||
ah->nvmem_blob = (u16 *)devm_kmemdup(sc->dev, buf, len, GFP_KERNEL);
|
||||
kfree(buf);
|
||||
if (IS_ERR(ah->nvmem_blob))
|
||||
return PTR_ERR(ah->nvmem_blob);
|
||||
|
||||
ah->nvmem_blob_len = len;
|
||||
ah->ah_flags &= ~AH_USE_EEPROM;
|
||||
ah->ah_flags |= AH_NO_EEP_SWAP;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int ath9k_init_platform(struct ath_softc *sc)
|
||||
{
|
||||
struct ath9k_platform_data *pdata = sc->dev->platform_data;
|
||||
|
|
@ -704,6 +756,10 @@ static int ath9k_init_softc(u16 devid, struct ath_softc *sc,
|
|||
if (ret)
|
||||
return ret;
|
||||
|
||||
ret = ath9k_nvmem_request_eeprom(sc);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
if (ath9k_led_active_high != -1)
|
||||
ah->config.led_active_high = ath9k_led_active_high == 1;
|
||||
|
||||
|
|
|
|||
|
|
@ -24,7 +24,6 @@
|
|||
* 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.
|
||||
*
|
||||
|
|
|
|||
|
|
@ -120,7 +120,7 @@ static ssize_t write_file_dump(struct file *file,
|
|||
if (begin == NULL)
|
||||
break;
|
||||
|
||||
if (kstrtou32(begin, 0, &arg[i]) != 0)
|
||||
if (kstrtos32(begin, 0, &arg[i]) != 0)
|
||||
break;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -3384,11 +3384,11 @@ struct tl_hal_flush_ac_rsp_msg {
|
|||
|
||||
struct wcn36xx_hal_enter_imps_req_msg {
|
||||
struct wcn36xx_hal_msg_header header;
|
||||
};
|
||||
} __packed;
|
||||
|
||||
struct wcn36xx_hal_exit_imps_req {
|
||||
struct wcn36xx_hal_exit_imps_req_msg {
|
||||
struct wcn36xx_hal_msg_header header;
|
||||
};
|
||||
} __packed;
|
||||
|
||||
struct wcn36xx_hal_enter_bmps_req_msg {
|
||||
struct wcn36xx_hal_msg_header header;
|
||||
|
|
|
|||
|
|
@ -432,6 +432,13 @@ static int wcn36xx_config(struct ieee80211_hw *hw, u32 changed)
|
|||
if (changed & IEEE80211_CONF_CHANGE_PS)
|
||||
wcn36xx_change_ps(wcn, hw->conf.flags & IEEE80211_CONF_PS);
|
||||
|
||||
if (changed & IEEE80211_CONF_CHANGE_IDLE) {
|
||||
if (hw->conf.flags & IEEE80211_CONF_IDLE)
|
||||
wcn36xx_smd_enter_imps(wcn);
|
||||
else
|
||||
wcn36xx_smd_exit_imps(wcn);
|
||||
}
|
||||
|
||||
mutex_unlock(&wcn->conf_mutex);
|
||||
|
||||
return 0;
|
||||
|
|
@ -569,12 +576,14 @@ static int wcn36xx_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd,
|
|||
if (IEEE80211_KEY_FLAG_PAIRWISE & key_conf->flags) {
|
||||
sta_priv->is_data_encrypted = true;
|
||||
/* Reconfigure bss with encrypt_type */
|
||||
if (NL80211_IFTYPE_STATION == vif->type)
|
||||
if (NL80211_IFTYPE_STATION == vif->type) {
|
||||
wcn36xx_smd_config_bss(wcn,
|
||||
vif,
|
||||
sta,
|
||||
sta->addr,
|
||||
true);
|
||||
wcn36xx_smd_config_sta(wcn, vif, sta);
|
||||
}
|
||||
|
||||
wcn36xx_smd_set_stakey(wcn,
|
||||
vif_priv->encrypt_type,
|
||||
|
|
|
|||
|
|
@ -2184,6 +2184,59 @@ int wcn36xx_smd_exit_bmps(struct wcn36xx *wcn, struct ieee80211_vif *vif)
|
|||
return ret;
|
||||
}
|
||||
|
||||
int wcn36xx_smd_enter_imps(struct wcn36xx *wcn)
|
||||
{
|
||||
struct wcn36xx_hal_enter_imps_req_msg msg_body;
|
||||
int ret;
|
||||
|
||||
mutex_lock(&wcn->hal_mutex);
|
||||
INIT_HAL_MSG(msg_body, WCN36XX_HAL_ENTER_IMPS_REQ);
|
||||
|
||||
PREPARE_HAL_BUF(wcn->hal_buf, msg_body);
|
||||
|
||||
ret = wcn36xx_smd_send_and_wait(wcn, msg_body.header.len);
|
||||
if (ret) {
|
||||
wcn36xx_err("Sending hal_enter_imps failed\n");
|
||||
goto out;
|
||||
}
|
||||
ret = wcn36xx_smd_rsp_status_check(wcn->hal_buf, wcn->hal_rsp_len);
|
||||
if (ret) {
|
||||
wcn36xx_err("hal_enter_imps response failed err=%d\n", ret);
|
||||
goto out;
|
||||
}
|
||||
|
||||
wcn36xx_dbg(WCN36XX_DBG_HAL, "Entered idle mode\n");
|
||||
out:
|
||||
mutex_unlock(&wcn->hal_mutex);
|
||||
return ret;
|
||||
}
|
||||
|
||||
int wcn36xx_smd_exit_imps(struct wcn36xx *wcn)
|
||||
{
|
||||
struct wcn36xx_hal_exit_imps_req_msg msg_body;
|
||||
int ret;
|
||||
|
||||
mutex_lock(&wcn->hal_mutex);
|
||||
INIT_HAL_MSG(msg_body, WCN36XX_HAL_EXIT_IMPS_REQ);
|
||||
|
||||
PREPARE_HAL_BUF(wcn->hal_buf, msg_body);
|
||||
|
||||
ret = wcn36xx_smd_send_and_wait(wcn, msg_body.header.len);
|
||||
if (ret) {
|
||||
wcn36xx_err("Sending hal_exit_imps failed\n");
|
||||
goto out;
|
||||
}
|
||||
ret = wcn36xx_smd_rsp_status_check(wcn->hal_buf, wcn->hal_rsp_len);
|
||||
if (ret) {
|
||||
wcn36xx_err("hal_exit_imps response failed err=%d\n", ret);
|
||||
goto out;
|
||||
}
|
||||
wcn36xx_dbg(WCN36XX_DBG_HAL, "Exited idle mode\n");
|
||||
out:
|
||||
mutex_unlock(&wcn->hal_mutex);
|
||||
return ret;
|
||||
}
|
||||
|
||||
int wcn36xx_smd_set_power_params(struct wcn36xx *wcn, bool ignore_dtim)
|
||||
{
|
||||
struct wcn36xx_hal_set_power_params_req_msg msg_body;
|
||||
|
|
@ -2623,30 +2676,52 @@ static int wcn36xx_smd_delete_sta_context_ind(struct wcn36xx *wcn,
|
|||
size_t len)
|
||||
{
|
||||
struct wcn36xx_hal_delete_sta_context_ind_msg *rsp = buf;
|
||||
struct wcn36xx_vif *tmp;
|
||||
struct wcn36xx_vif *vif_priv;
|
||||
struct ieee80211_vif *vif;
|
||||
struct ieee80211_bss_conf *bss_conf;
|
||||
struct ieee80211_sta *sta;
|
||||
bool found = false;
|
||||
|
||||
if (len != sizeof(*rsp)) {
|
||||
wcn36xx_warn("Corrupted delete sta indication\n");
|
||||
return -EIO;
|
||||
}
|
||||
|
||||
wcn36xx_dbg(WCN36XX_DBG_HAL, "delete station indication %pM index %d\n",
|
||||
rsp->addr2, rsp->sta_id);
|
||||
wcn36xx_dbg(WCN36XX_DBG_HAL,
|
||||
"delete station indication %pM index %d reason %d\n",
|
||||
rsp->addr2, rsp->sta_id, rsp->reason_code);
|
||||
|
||||
list_for_each_entry(tmp, &wcn->vif_list, list) {
|
||||
list_for_each_entry(vif_priv, &wcn->vif_list, list) {
|
||||
rcu_read_lock();
|
||||
sta = ieee80211_find_sta(wcn36xx_priv_to_vif(tmp), rsp->addr2);
|
||||
if (sta)
|
||||
ieee80211_report_low_ack(sta, 0);
|
||||
vif = wcn36xx_priv_to_vif(vif_priv);
|
||||
|
||||
if (vif->type == NL80211_IFTYPE_STATION) {
|
||||
/* We could call ieee80211_find_sta too, but checking
|
||||
* bss_conf is clearer.
|
||||
*/
|
||||
bss_conf = &vif->bss_conf;
|
||||
if (vif_priv->sta_assoc &&
|
||||
!memcmp(bss_conf->bssid, rsp->addr2, ETH_ALEN)) {
|
||||
found = true;
|
||||
wcn36xx_dbg(WCN36XX_DBG_HAL,
|
||||
"connection loss bss_index %d\n",
|
||||
vif_priv->bss_index);
|
||||
ieee80211_connection_loss(vif);
|
||||
}
|
||||
} else {
|
||||
sta = ieee80211_find_sta(vif, rsp->addr2);
|
||||
if (sta) {
|
||||
found = true;
|
||||
ieee80211_report_low_ack(sta, 0);
|
||||
}
|
||||
}
|
||||
|
||||
rcu_read_unlock();
|
||||
if (sta)
|
||||
if (found)
|
||||
return 0;
|
||||
}
|
||||
|
||||
wcn36xx_warn("STA with addr %pM and index %d not found\n",
|
||||
rsp->addr2,
|
||||
rsp->sta_id);
|
||||
wcn36xx_warn("BSS or STA with addr %pM not found\n", rsp->addr2);
|
||||
return -ENOENT;
|
||||
}
|
||||
|
||||
|
|
@ -3060,6 +3135,8 @@ int wcn36xx_smd_rsp_process(struct rpmsg_device *rpdev,
|
|||
case WCN36XX_HAL_GTK_OFFLOAD_RSP:
|
||||
case WCN36XX_HAL_GTK_OFFLOAD_GETINFO_RSP:
|
||||
case WCN36XX_HAL_HOST_RESUME_RSP:
|
||||
case WCN36XX_HAL_ENTER_IMPS_RSP:
|
||||
case WCN36XX_HAL_EXIT_IMPS_RSP:
|
||||
memcpy(wcn->hal_buf, buf, len);
|
||||
wcn->hal_rsp_len = len;
|
||||
complete(&wcn->hal_rsp_compl);
|
||||
|
|
|
|||
|
|
@ -163,4 +163,7 @@ int wcn36xx_smd_wlan_host_suspend_ind(struct wcn36xx *wcn);
|
|||
|
||||
int wcn36xx_smd_host_resume(struct wcn36xx *wcn);
|
||||
|
||||
int wcn36xx_smd_enter_imps(struct wcn36xx *wcn);
|
||||
int wcn36xx_smd_exit_imps(struct wcn36xx *wcn);
|
||||
|
||||
#endif /* _SMD_H_ */
|
||||
|
|
|
|||
|
|
@ -1783,8 +1783,8 @@ brcmf_set_key_mgmt(struct net_device *ndev, struct cfg80211_connect_params *sme)
|
|||
val = WPA_AUTH_PSK;
|
||||
break;
|
||||
default:
|
||||
bphy_err(drvr, "invalid cipher group (%d)\n",
|
||||
sme->crypto.cipher_group);
|
||||
bphy_err(drvr, "invalid akm suite (%d)\n",
|
||||
sme->crypto.akm_suites[0]);
|
||||
return -EINVAL;
|
||||
}
|
||||
} else if (val & (WPA2_AUTH_PSK | WPA2_AUTH_UNSPECIFIED)) {
|
||||
|
|
@ -1816,8 +1816,8 @@ brcmf_set_key_mgmt(struct net_device *ndev, struct cfg80211_connect_params *sme)
|
|||
profile->is_ft = true;
|
||||
break;
|
||||
default:
|
||||
bphy_err(drvr, "invalid cipher group (%d)\n",
|
||||
sme->crypto.cipher_group);
|
||||
bphy_err(drvr, "invalid akm suite (%d)\n",
|
||||
sme->crypto.akm_suites[0]);
|
||||
return -EINVAL;
|
||||
}
|
||||
} else if (val & WPA3_AUTH_SAE_PSK) {
|
||||
|
|
@ -1838,8 +1838,8 @@ brcmf_set_key_mgmt(struct net_device *ndev, struct cfg80211_connect_params *sme)
|
|||
}
|
||||
break;
|
||||
default:
|
||||
bphy_err(drvr, "invalid cipher group (%d)\n",
|
||||
sme->crypto.cipher_group);
|
||||
bphy_err(drvr, "invalid akm suite (%d)\n",
|
||||
sme->crypto.akm_suites[0]);
|
||||
return -EINVAL;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -75,6 +75,16 @@ static const struct dmi_system_id dmi_platform_data[] = {
|
|||
},
|
||||
.driver_data = (void *)&acepc_t8_data,
|
||||
},
|
||||
{
|
||||
/* Cyberbook T116 rugged tablet */
|
||||
.matches = {
|
||||
DMI_EXACT_MATCH(DMI_BOARD_VENDOR, "Default string"),
|
||||
DMI_EXACT_MATCH(DMI_BOARD_NAME, "Cherry Trail CR"),
|
||||
DMI_EXACT_MATCH(DMI_PRODUCT_SKU, "20170531"),
|
||||
},
|
||||
/* The factory image nvram file is identical to the ACEPC T8 one */
|
||||
.driver_data = (void *)&acepc_t8_data,
|
||||
},
|
||||
{
|
||||
/* Match for the GPDwin which unfortunately uses somewhat
|
||||
* generic dmi strings, which is why we test for 4 strings.
|
||||
|
|
|
|||
|
|
@ -29,7 +29,7 @@ static int brcmf_of_get_country_codes(struct device *dev,
|
|||
return (count == -EINVAL) ? 0 : count;
|
||||
}
|
||||
|
||||
cc = devm_kzalloc(dev, sizeof(*cc) + count * sizeof(*cce), GFP_KERNEL);
|
||||
cc = devm_kzalloc(dev, struct_size(cc, table, count), GFP_KERNEL);
|
||||
if (!cc)
|
||||
return -ENOMEM;
|
||||
|
||||
|
|
|
|||
|
|
@ -3777,7 +3777,7 @@ static int ipw_queue_tx_init(struct ipw_priv *priv,
|
|||
dma_alloc_coherent(&dev->dev, sizeof(q->bd[0]) * count,
|
||||
&q->q.dma_addr, GFP_KERNEL);
|
||||
if (!q->bd) {
|
||||
IPW_ERROR("pci_alloc_consistent(%zd) failed\n",
|
||||
IPW_ERROR("dma_alloc_coherent(%zd) failed\n",
|
||||
sizeof(q->bd[0]) * count);
|
||||
kfree(q->txb);
|
||||
q->txb = NULL;
|
||||
|
|
|
|||
|
|
@ -908,16 +908,20 @@ mwifiex_init_new_priv_params(struct mwifiex_private *priv,
|
|||
switch (type) {
|
||||
case NL80211_IFTYPE_STATION:
|
||||
case NL80211_IFTYPE_ADHOC:
|
||||
priv->bss_role = MWIFIEX_BSS_ROLE_STA;
|
||||
priv->bss_role = MWIFIEX_BSS_ROLE_STA;
|
||||
priv->bss_type = MWIFIEX_BSS_TYPE_STA;
|
||||
break;
|
||||
case NL80211_IFTYPE_P2P_CLIENT:
|
||||
priv->bss_role = MWIFIEX_BSS_ROLE_STA;
|
||||
priv->bss_role = MWIFIEX_BSS_ROLE_STA;
|
||||
priv->bss_type = MWIFIEX_BSS_TYPE_P2P;
|
||||
break;
|
||||
case NL80211_IFTYPE_P2P_GO:
|
||||
priv->bss_role = MWIFIEX_BSS_ROLE_UAP;
|
||||
priv->bss_role = MWIFIEX_BSS_ROLE_UAP;
|
||||
priv->bss_type = MWIFIEX_BSS_TYPE_P2P;
|
||||
break;
|
||||
case NL80211_IFTYPE_AP:
|
||||
priv->bss_role = MWIFIEX_BSS_ROLE_UAP;
|
||||
priv->bss_type = MWIFIEX_BSS_TYPE_UAP;
|
||||
break;
|
||||
default:
|
||||
mwifiex_dbg(adapter, ERROR,
|
||||
|
|
@ -939,6 +943,117 @@ mwifiex_init_new_priv_params(struct mwifiex_private *priv,
|
|||
return 0;
|
||||
}
|
||||
|
||||
static bool
|
||||
is_vif_type_change_allowed(struct mwifiex_adapter *adapter,
|
||||
enum nl80211_iftype old_iftype,
|
||||
enum nl80211_iftype new_iftype)
|
||||
{
|
||||
switch (old_iftype) {
|
||||
case NL80211_IFTYPE_ADHOC:
|
||||
switch (new_iftype) {
|
||||
case NL80211_IFTYPE_STATION:
|
||||
return true;
|
||||
case NL80211_IFTYPE_P2P_CLIENT:
|
||||
case NL80211_IFTYPE_P2P_GO:
|
||||
return adapter->curr_iface_comb.p2p_intf !=
|
||||
adapter->iface_limit.p2p_intf;
|
||||
case NL80211_IFTYPE_AP:
|
||||
return adapter->curr_iface_comb.uap_intf !=
|
||||
adapter->iface_limit.uap_intf;
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
|
||||
case NL80211_IFTYPE_STATION:
|
||||
switch (new_iftype) {
|
||||
case NL80211_IFTYPE_ADHOC:
|
||||
return true;
|
||||
case NL80211_IFTYPE_P2P_CLIENT:
|
||||
case NL80211_IFTYPE_P2P_GO:
|
||||
return adapter->curr_iface_comb.p2p_intf !=
|
||||
adapter->iface_limit.p2p_intf;
|
||||
case NL80211_IFTYPE_AP:
|
||||
return adapter->curr_iface_comb.uap_intf !=
|
||||
adapter->iface_limit.uap_intf;
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
|
||||
case NL80211_IFTYPE_AP:
|
||||
switch (new_iftype) {
|
||||
case NL80211_IFTYPE_ADHOC:
|
||||
case NL80211_IFTYPE_STATION:
|
||||
return adapter->curr_iface_comb.sta_intf !=
|
||||
adapter->iface_limit.sta_intf;
|
||||
case NL80211_IFTYPE_P2P_CLIENT:
|
||||
case NL80211_IFTYPE_P2P_GO:
|
||||
return adapter->curr_iface_comb.p2p_intf !=
|
||||
adapter->iface_limit.p2p_intf;
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
|
||||
case NL80211_IFTYPE_P2P_CLIENT:
|
||||
switch (new_iftype) {
|
||||
case NL80211_IFTYPE_ADHOC:
|
||||
case NL80211_IFTYPE_STATION:
|
||||
return true;
|
||||
case NL80211_IFTYPE_P2P_GO:
|
||||
return true;
|
||||
case NL80211_IFTYPE_AP:
|
||||
return adapter->curr_iface_comb.uap_intf !=
|
||||
adapter->iface_limit.uap_intf;
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
|
||||
case NL80211_IFTYPE_P2P_GO:
|
||||
switch (new_iftype) {
|
||||
case NL80211_IFTYPE_ADHOC:
|
||||
case NL80211_IFTYPE_STATION:
|
||||
return true;
|
||||
case NL80211_IFTYPE_P2P_CLIENT:
|
||||
return true;
|
||||
case NL80211_IFTYPE_AP:
|
||||
return adapter->curr_iface_comb.uap_intf !=
|
||||
adapter->iface_limit.uap_intf;
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
static void
|
||||
update_vif_type_counter(struct mwifiex_adapter *adapter,
|
||||
enum nl80211_iftype iftype,
|
||||
int change)
|
||||
{
|
||||
switch (iftype) {
|
||||
case NL80211_IFTYPE_UNSPECIFIED:
|
||||
case NL80211_IFTYPE_ADHOC:
|
||||
case NL80211_IFTYPE_STATION:
|
||||
adapter->curr_iface_comb.sta_intf += change;
|
||||
break;
|
||||
case NL80211_IFTYPE_AP:
|
||||
adapter->curr_iface_comb.uap_intf += change;
|
||||
break;
|
||||
case NL80211_IFTYPE_P2P_CLIENT:
|
||||
case NL80211_IFTYPE_P2P_GO:
|
||||
adapter->curr_iface_comb.p2p_intf += change;
|
||||
break;
|
||||
default:
|
||||
mwifiex_dbg(adapter, ERROR,
|
||||
"%s: Unsupported iftype passed: %d\n",
|
||||
__func__, iftype);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static int
|
||||
mwifiex_change_vif_to_p2p(struct net_device *dev,
|
||||
enum nl80211_iftype curr_iftype,
|
||||
|
|
@ -955,13 +1070,6 @@ mwifiex_change_vif_to_p2p(struct net_device *dev,
|
|||
|
||||
adapter = priv->adapter;
|
||||
|
||||
if (adapter->curr_iface_comb.p2p_intf ==
|
||||
adapter->iface_limit.p2p_intf) {
|
||||
mwifiex_dbg(adapter, ERROR,
|
||||
"cannot create multiple P2P ifaces\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
mwifiex_dbg(adapter, INFO,
|
||||
"%s: changing role to p2p\n", dev->name);
|
||||
|
||||
|
|
@ -970,6 +1078,10 @@ mwifiex_change_vif_to_p2p(struct net_device *dev,
|
|||
if (mwifiex_init_new_priv_params(priv, dev, type))
|
||||
return -1;
|
||||
|
||||
update_vif_type_counter(adapter, curr_iftype, -1);
|
||||
update_vif_type_counter(adapter, type, +1);
|
||||
dev->ieee80211_ptr->iftype = type;
|
||||
|
||||
switch (type) {
|
||||
case NL80211_IFTYPE_P2P_CLIENT:
|
||||
if (mwifiex_cfg80211_init_p2p_client(priv))
|
||||
|
|
@ -993,21 +1105,6 @@ mwifiex_change_vif_to_p2p(struct net_device *dev,
|
|||
if (mwifiex_sta_init_cmd(priv, false, false))
|
||||
return -1;
|
||||
|
||||
switch (curr_iftype) {
|
||||
case NL80211_IFTYPE_STATION:
|
||||
case NL80211_IFTYPE_ADHOC:
|
||||
adapter->curr_iface_comb.sta_intf--;
|
||||
break;
|
||||
case NL80211_IFTYPE_AP:
|
||||
adapter->curr_iface_comb.uap_intf--;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
adapter->curr_iface_comb.p2p_intf++;
|
||||
dev->ieee80211_ptr->iftype = type;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
@ -1027,15 +1124,6 @@ mwifiex_change_vif_to_sta_adhoc(struct net_device *dev,
|
|||
|
||||
adapter = priv->adapter;
|
||||
|
||||
if ((curr_iftype != NL80211_IFTYPE_P2P_CLIENT &&
|
||||
curr_iftype != NL80211_IFTYPE_P2P_GO) &&
|
||||
(adapter->curr_iface_comb.sta_intf ==
|
||||
adapter->iface_limit.sta_intf)) {
|
||||
mwifiex_dbg(adapter, ERROR,
|
||||
"cannot create multiple station/adhoc ifaces\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (type == NL80211_IFTYPE_STATION)
|
||||
mwifiex_dbg(adapter, INFO,
|
||||
"%s: changing role to station\n", dev->name);
|
||||
|
|
@ -1047,26 +1135,17 @@ mwifiex_change_vif_to_sta_adhoc(struct net_device *dev,
|
|||
return -1;
|
||||
if (mwifiex_init_new_priv_params(priv, dev, type))
|
||||
return -1;
|
||||
|
||||
update_vif_type_counter(adapter, curr_iftype, -1);
|
||||
update_vif_type_counter(adapter, type, +1);
|
||||
dev->ieee80211_ptr->iftype = type;
|
||||
|
||||
if (mwifiex_send_cmd(priv, HostCmd_CMD_SET_BSS_MODE,
|
||||
HostCmd_ACT_GEN_SET, 0, NULL, true))
|
||||
return -1;
|
||||
if (mwifiex_sta_init_cmd(priv, false, false))
|
||||
return -1;
|
||||
|
||||
switch (curr_iftype) {
|
||||
case NL80211_IFTYPE_P2P_CLIENT:
|
||||
case NL80211_IFTYPE_P2P_GO:
|
||||
adapter->curr_iface_comb.p2p_intf--;
|
||||
break;
|
||||
case NL80211_IFTYPE_AP:
|
||||
adapter->curr_iface_comb.uap_intf--;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
adapter->curr_iface_comb.sta_intf++;
|
||||
dev->ieee80211_ptr->iftype = type;
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
@ -1086,13 +1165,6 @@ mwifiex_change_vif_to_ap(struct net_device *dev,
|
|||
|
||||
adapter = priv->adapter;
|
||||
|
||||
if (adapter->curr_iface_comb.uap_intf ==
|
||||
adapter->iface_limit.uap_intf) {
|
||||
mwifiex_dbg(adapter, ERROR,
|
||||
"cannot create multiple AP ifaces\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
mwifiex_dbg(adapter, INFO,
|
||||
"%s: changing role to AP\n", dev->name);
|
||||
|
||||
|
|
@ -1100,27 +1172,17 @@ mwifiex_change_vif_to_ap(struct net_device *dev,
|
|||
return -1;
|
||||
if (mwifiex_init_new_priv_params(priv, dev, type))
|
||||
return -1;
|
||||
|
||||
update_vif_type_counter(adapter, curr_iftype, -1);
|
||||
update_vif_type_counter(adapter, type, +1);
|
||||
dev->ieee80211_ptr->iftype = type;
|
||||
|
||||
if (mwifiex_send_cmd(priv, HostCmd_CMD_SET_BSS_MODE,
|
||||
HostCmd_ACT_GEN_SET, 0, NULL, true))
|
||||
return -1;
|
||||
if (mwifiex_sta_init_cmd(priv, false, false))
|
||||
return -1;
|
||||
|
||||
switch (curr_iftype) {
|
||||
case NL80211_IFTYPE_P2P_CLIENT:
|
||||
case NL80211_IFTYPE_P2P_GO:
|
||||
adapter->curr_iface_comb.p2p_intf--;
|
||||
break;
|
||||
case NL80211_IFTYPE_STATION:
|
||||
case NL80211_IFTYPE_ADHOC:
|
||||
adapter->curr_iface_comb.sta_intf--;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
adapter->curr_iface_comb.uap_intf++;
|
||||
dev->ieee80211_ptr->iftype = type;
|
||||
return 0;
|
||||
}
|
||||
/*
|
||||
|
|
@ -1141,6 +1203,27 @@ mwifiex_cfg80211_change_virtual_intf(struct wiphy *wiphy,
|
|||
return -EBUSY;
|
||||
}
|
||||
|
||||
if (type == NL80211_IFTYPE_UNSPECIFIED) {
|
||||
mwifiex_dbg(priv->adapter, INFO,
|
||||
"%s: no new type specified, keeping old type %d\n",
|
||||
dev->name, curr_iftype);
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (curr_iftype == type) {
|
||||
mwifiex_dbg(priv->adapter, INFO,
|
||||
"%s: interface already is of type %d\n",
|
||||
dev->name, curr_iftype);
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (!is_vif_type_change_allowed(priv->adapter, curr_iftype, type)) {
|
||||
mwifiex_dbg(priv->adapter, ERROR,
|
||||
"%s: change from type %d to %d is not allowed\n",
|
||||
dev->name, curr_iftype, type);
|
||||
return -EOPNOTSUPP;
|
||||
}
|
||||
|
||||
switch (curr_iftype) {
|
||||
case NL80211_IFTYPE_ADHOC:
|
||||
switch (type) {
|
||||
|
|
@ -1160,19 +1243,10 @@ mwifiex_cfg80211_change_virtual_intf(struct wiphy *wiphy,
|
|||
case NL80211_IFTYPE_AP:
|
||||
return mwifiex_change_vif_to_ap(dev, curr_iftype, type,
|
||||
params);
|
||||
case NL80211_IFTYPE_UNSPECIFIED:
|
||||
mwifiex_dbg(priv->adapter, INFO,
|
||||
"%s: kept type as IBSS\n", dev->name);
|
||||
fallthrough;
|
||||
case NL80211_IFTYPE_ADHOC: /* This shouldn't happen */
|
||||
return 0;
|
||||
default:
|
||||
mwifiex_dbg(priv->adapter, ERROR,
|
||||
"%s: changing to %d not supported\n",
|
||||
dev->name, type);
|
||||
return -EOPNOTSUPP;
|
||||
goto errnotsupp;
|
||||
}
|
||||
break;
|
||||
|
||||
case NL80211_IFTYPE_STATION:
|
||||
switch (type) {
|
||||
case NL80211_IFTYPE_ADHOC:
|
||||
|
|
@ -1191,22 +1265,14 @@ mwifiex_cfg80211_change_virtual_intf(struct wiphy *wiphy,
|
|||
case NL80211_IFTYPE_AP:
|
||||
return mwifiex_change_vif_to_ap(dev, curr_iftype, type,
|
||||
params);
|
||||
case NL80211_IFTYPE_UNSPECIFIED:
|
||||
mwifiex_dbg(priv->adapter, INFO,
|
||||
"%s: kept type as STA\n", dev->name);
|
||||
fallthrough;
|
||||
case NL80211_IFTYPE_STATION: /* This shouldn't happen */
|
||||
return 0;
|
||||
default:
|
||||
mwifiex_dbg(priv->adapter, ERROR,
|
||||
"%s: changing to %d not supported\n",
|
||||
dev->name, type);
|
||||
return -EOPNOTSUPP;
|
||||
goto errnotsupp;
|
||||
}
|
||||
break;
|
||||
|
||||
case NL80211_IFTYPE_AP:
|
||||
switch (type) {
|
||||
case NL80211_IFTYPE_ADHOC:
|
||||
case NL80211_IFTYPE_STATION:
|
||||
return mwifiex_change_vif_to_sta_adhoc(dev, curr_iftype,
|
||||
type, params);
|
||||
break;
|
||||
|
|
@ -1214,69 +1280,60 @@ mwifiex_cfg80211_change_virtual_intf(struct wiphy *wiphy,
|
|||
case NL80211_IFTYPE_P2P_GO:
|
||||
return mwifiex_change_vif_to_p2p(dev, curr_iftype,
|
||||
type, params);
|
||||
case NL80211_IFTYPE_UNSPECIFIED:
|
||||
mwifiex_dbg(priv->adapter, INFO,
|
||||
"%s: kept type as AP\n", dev->name);
|
||||
fallthrough;
|
||||
case NL80211_IFTYPE_AP: /* This shouldn't happen */
|
||||
return 0;
|
||||
default:
|
||||
mwifiex_dbg(priv->adapter, ERROR,
|
||||
"%s: changing to %d not supported\n",
|
||||
dev->name, type);
|
||||
return -EOPNOTSUPP;
|
||||
goto errnotsupp;
|
||||
}
|
||||
break;
|
||||
|
||||
case NL80211_IFTYPE_P2P_CLIENT:
|
||||
case NL80211_IFTYPE_P2P_GO:
|
||||
if (mwifiex_cfg80211_deinit_p2p(priv))
|
||||
return -EFAULT;
|
||||
|
||||
switch (type) {
|
||||
case NL80211_IFTYPE_STATION:
|
||||
if (mwifiex_cfg80211_deinit_p2p(priv))
|
||||
return -EFAULT;
|
||||
priv->adapter->curr_iface_comb.p2p_intf--;
|
||||
priv->adapter->curr_iface_comb.sta_intf++;
|
||||
dev->ieee80211_ptr->iftype = type;
|
||||
if (mwifiex_deinit_priv_params(priv))
|
||||
return -1;
|
||||
if (mwifiex_init_new_priv_params(priv, dev, type))
|
||||
return -1;
|
||||
if (mwifiex_sta_init_cmd(priv, false, false))
|
||||
return -1;
|
||||
break;
|
||||
case NL80211_IFTYPE_ADHOC:
|
||||
if (mwifiex_cfg80211_deinit_p2p(priv))
|
||||
return -EFAULT;
|
||||
case NL80211_IFTYPE_STATION:
|
||||
return mwifiex_change_vif_to_sta_adhoc(dev, curr_iftype,
|
||||
type, params);
|
||||
break;
|
||||
case NL80211_IFTYPE_P2P_GO:
|
||||
return mwifiex_change_vif_to_p2p(dev, curr_iftype,
|
||||
type, params);
|
||||
case NL80211_IFTYPE_AP:
|
||||
if (mwifiex_cfg80211_deinit_p2p(priv))
|
||||
return -EFAULT;
|
||||
return mwifiex_change_vif_to_ap(dev, curr_iftype, type,
|
||||
params);
|
||||
case NL80211_IFTYPE_UNSPECIFIED:
|
||||
mwifiex_dbg(priv->adapter, INFO,
|
||||
"%s: kept type as P2P\n", dev->name);
|
||||
fallthrough;
|
||||
case NL80211_IFTYPE_P2P_CLIENT:
|
||||
case NL80211_IFTYPE_P2P_GO:
|
||||
return 0;
|
||||
default:
|
||||
mwifiex_dbg(priv->adapter, ERROR,
|
||||
"%s: changing to %d not supported\n",
|
||||
dev->name, type);
|
||||
return -EOPNOTSUPP;
|
||||
goto errnotsupp;
|
||||
}
|
||||
break;
|
||||
|
||||
case NL80211_IFTYPE_P2P_GO:
|
||||
if (mwifiex_cfg80211_deinit_p2p(priv))
|
||||
return -EFAULT;
|
||||
|
||||
switch (type) {
|
||||
case NL80211_IFTYPE_ADHOC:
|
||||
case NL80211_IFTYPE_STATION:
|
||||
return mwifiex_change_vif_to_sta_adhoc(dev, curr_iftype,
|
||||
type, params);
|
||||
case NL80211_IFTYPE_P2P_CLIENT:
|
||||
return mwifiex_change_vif_to_p2p(dev, curr_iftype,
|
||||
type, params);
|
||||
case NL80211_IFTYPE_AP:
|
||||
return mwifiex_change_vif_to_ap(dev, curr_iftype, type,
|
||||
params);
|
||||
default:
|
||||
goto errnotsupp;
|
||||
}
|
||||
|
||||
default:
|
||||
mwifiex_dbg(priv->adapter, ERROR,
|
||||
"%s: unknown iftype: %d\n",
|
||||
dev->name, dev->ieee80211_ptr->iftype);
|
||||
return -EOPNOTSUPP;
|
||||
goto errnotsupp;
|
||||
}
|
||||
|
||||
|
||||
return 0;
|
||||
|
||||
errnotsupp:
|
||||
mwifiex_dbg(priv->adapter, ERROR,
|
||||
"unsupported interface type transition: %d to %d\n",
|
||||
curr_iftype, type);
|
||||
return -EOPNOTSUPP;
|
||||
}
|
||||
|
||||
static void
|
||||
|
|
@ -2997,7 +3054,7 @@ struct wireless_dev *mwifiex_add_virtual_intf(struct wiphy *wiphy,
|
|||
priv->bss_type = MWIFIEX_BSS_TYPE_P2P;
|
||||
|
||||
priv->frame_type = MWIFIEX_DATA_FRAME_TYPE_ETH_II;
|
||||
priv->bss_priority = MWIFIEX_BSS_ROLE_STA;
|
||||
priv->bss_priority = 0;
|
||||
priv->bss_role = MWIFIEX_BSS_ROLE_STA;
|
||||
priv->bss_started = 0;
|
||||
|
||||
|
|
@ -3108,23 +3165,7 @@ struct wireless_dev *mwifiex_add_virtual_intf(struct wiphy *wiphy,
|
|||
mwifiex_dev_debugfs_init(priv);
|
||||
#endif
|
||||
|
||||
switch (type) {
|
||||
case NL80211_IFTYPE_UNSPECIFIED:
|
||||
case NL80211_IFTYPE_STATION:
|
||||
case NL80211_IFTYPE_ADHOC:
|
||||
adapter->curr_iface_comb.sta_intf++;
|
||||
break;
|
||||
case NL80211_IFTYPE_AP:
|
||||
adapter->curr_iface_comb.uap_intf++;
|
||||
break;
|
||||
case NL80211_IFTYPE_P2P_CLIENT:
|
||||
adapter->curr_iface_comb.p2p_intf++;
|
||||
break;
|
||||
default:
|
||||
/* This should be dead code; checked above */
|
||||
mwifiex_dbg(adapter, ERROR, "type not supported\n");
|
||||
return ERR_PTR(-EINVAL);
|
||||
}
|
||||
update_vif_type_counter(adapter, type, +1);
|
||||
|
||||
return &priv->wdev;
|
||||
|
||||
|
|
@ -3190,24 +3231,7 @@ int mwifiex_del_virtual_intf(struct wiphy *wiphy, struct wireless_dev *wdev)
|
|||
/* Clear the priv in adapter */
|
||||
priv->netdev = NULL;
|
||||
|
||||
switch (priv->bss_mode) {
|
||||
case NL80211_IFTYPE_UNSPECIFIED:
|
||||
case NL80211_IFTYPE_STATION:
|
||||
case NL80211_IFTYPE_ADHOC:
|
||||
adapter->curr_iface_comb.sta_intf--;
|
||||
break;
|
||||
case NL80211_IFTYPE_AP:
|
||||
adapter->curr_iface_comb.uap_intf--;
|
||||
break;
|
||||
case NL80211_IFTYPE_P2P_CLIENT:
|
||||
case NL80211_IFTYPE_P2P_GO:
|
||||
adapter->curr_iface_comb.p2p_intf--;
|
||||
break;
|
||||
default:
|
||||
mwifiex_dbg(adapter, ERROR,
|
||||
"del_virtual_intf: type not supported\n");
|
||||
break;
|
||||
}
|
||||
update_vif_type_counter(adapter, priv->bss_mode, -1);
|
||||
|
||||
priv->bss_mode = NL80211_IFTYPE_UNSPECIFIED;
|
||||
|
||||
|
|
|
|||
|
|
@ -129,8 +129,7 @@ static void cfg_scan_result(enum scan_event scan_event,
|
|||
info->frame_len,
|
||||
(s32)info->rssi * 100,
|
||||
GFP_KERNEL);
|
||||
if (!bss)
|
||||
cfg80211_put_bss(wiphy, bss);
|
||||
cfg80211_put_bss(wiphy, bss);
|
||||
} else if (scan_event == SCAN_EVENT_DONE) {
|
||||
mutex_lock(&priv->scan_req_lock);
|
||||
|
||||
|
|
@ -729,6 +728,7 @@ static int get_station(struct wiphy *wiphy, struct net_device *dev,
|
|||
{
|
||||
struct wilc_vif *vif = netdev_priv(dev);
|
||||
struct wilc_priv *priv = &vif->priv;
|
||||
struct wilc *wilc = vif->wilc;
|
||||
u32 i = 0;
|
||||
u32 associatedsta = ~0;
|
||||
u32 inactive_time = 0;
|
||||
|
|
@ -755,6 +755,9 @@ static int get_station(struct wiphy *wiphy, struct net_device *dev,
|
|||
} else if (vif->iftype == WILC_STATION_MODE) {
|
||||
struct rf_info stats;
|
||||
|
||||
if (!wilc->initialized)
|
||||
return -EBUSY;
|
||||
|
||||
wilc_get_statistics(vif, &stats);
|
||||
|
||||
sinfo->filled |= BIT_ULL(NL80211_STA_INFO_SIGNAL) |
|
||||
|
|
@ -1581,6 +1584,7 @@ static void wilc_set_wakeup(struct wiphy *wiphy, bool enabled)
|
|||
}
|
||||
|
||||
netdev_info(vif->ndev, "cfg set wake up = %d\n", enabled);
|
||||
wilc_set_wowlan_trigger(vif, enabled);
|
||||
srcu_read_unlock(&wl->srcu, srcu_idx);
|
||||
}
|
||||
|
||||
|
|
@ -1683,6 +1687,7 @@ static void wlan_init_locks(struct wilc *wl)
|
|||
mutex_init(&wl->rxq_cs);
|
||||
mutex_init(&wl->cfg_cmd_lock);
|
||||
mutex_init(&wl->vif_mutex);
|
||||
mutex_init(&wl->deinit_lock);
|
||||
|
||||
spin_lock_init(&wl->txq_spinlock);
|
||||
mutex_init(&wl->txq_add_to_head_cs);
|
||||
|
|
@ -1701,6 +1706,7 @@ void wlan_deinit_locks(struct wilc *wilc)
|
|||
mutex_destroy(&wilc->cfg_cmd_lock);
|
||||
mutex_destroy(&wilc->txq_add_to_head_cs);
|
||||
mutex_destroy(&wilc->vif_mutex);
|
||||
mutex_destroy(&wilc->deinit_lock);
|
||||
cleanup_srcu_struct(&wilc->srcu);
|
||||
}
|
||||
|
||||
|
|
@ -1724,7 +1730,6 @@ int wilc_cfg80211_init(struct wilc **wilc, struct device *dev, int io_type,
|
|||
*wilc = wl;
|
||||
wl->io_type = io_type;
|
||||
wl->hif_func = ops;
|
||||
wl->chip_ps_state = WILC_CHIP_WAKEDUP;
|
||||
|
||||
for (i = 0; i < NQUEUES; i++)
|
||||
INIT_LIST_HEAD(&wl->txq[i].txq_head.list);
|
||||
|
|
|
|||
|
|
@ -23,6 +23,10 @@ struct wilc_set_multicast {
|
|||
u8 *mc_list;
|
||||
};
|
||||
|
||||
struct host_if_wowlan_trigger {
|
||||
u8 wowlan_trigger;
|
||||
};
|
||||
|
||||
struct wilc_del_all_sta {
|
||||
u8 assoc_sta;
|
||||
u8 mac[WILC_MAX_NUM_STA][ETH_ALEN];
|
||||
|
|
@ -34,6 +38,7 @@ union wilc_message_body {
|
|||
struct wilc_set_multicast mc_info;
|
||||
struct wilc_remain_ch remain_on_ch;
|
||||
char *data;
|
||||
struct host_if_wowlan_trigger wow_trigger;
|
||||
};
|
||||
|
||||
struct host_if_msg {
|
||||
|
|
@ -962,6 +967,25 @@ static void handle_set_mcast_filter(struct work_struct *work)
|
|||
kfree(msg);
|
||||
}
|
||||
|
||||
void wilc_set_wowlan_trigger(struct wilc_vif *vif, bool enabled)
|
||||
{
|
||||
int ret;
|
||||
struct wid wid;
|
||||
u8 wowlan_trigger = 0;
|
||||
|
||||
if (enabled)
|
||||
wowlan_trigger = 1;
|
||||
|
||||
wid.id = WID_WOWLAN_TRIGGER;
|
||||
wid.type = WID_CHAR;
|
||||
wid.val = &wowlan_trigger;
|
||||
wid.size = sizeof(char);
|
||||
|
||||
ret = wilc_send_config_pkt(vif, WILC_SET_CFG, &wid, 1);
|
||||
if (ret)
|
||||
pr_err("Failed to send wowlan trigger config packet\n");
|
||||
}
|
||||
|
||||
static void handle_scan_timer(struct work_struct *work)
|
||||
{
|
||||
struct host_if_msg *msg = container_of(work, struct host_if_msg, work);
|
||||
|
|
@ -1494,7 +1518,6 @@ int wilc_init(struct net_device *dev, struct host_if_drv **hif_drv_handler)
|
|||
{
|
||||
struct host_if_drv *hif_drv;
|
||||
struct wilc_vif *vif = netdev_priv(dev);
|
||||
struct wilc *wilc = vif->wilc;
|
||||
|
||||
hif_drv = kzalloc(sizeof(*hif_drv), GFP_KERNEL);
|
||||
if (!hif_drv)
|
||||
|
|
@ -1504,9 +1527,6 @@ int wilc_init(struct net_device *dev, struct host_if_drv **hif_drv_handler)
|
|||
|
||||
vif->hif_drv = hif_drv;
|
||||
|
||||
if (wilc->clients_count == 0)
|
||||
mutex_init(&wilc->deinit_lock);
|
||||
|
||||
timer_setup(&vif->periodic_rssi, get_periodic_rssi, 0);
|
||||
mod_timer(&vif->periodic_rssi, jiffies + msecs_to_jiffies(5000));
|
||||
|
||||
|
|
@ -1518,8 +1538,6 @@ int wilc_init(struct net_device *dev, struct host_if_drv **hif_drv_handler)
|
|||
|
||||
hif_drv->p2p_timeout = 0;
|
||||
|
||||
wilc->clients_count++;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
@ -1550,7 +1568,6 @@ int wilc_deinit(struct wilc_vif *vif)
|
|||
|
||||
kfree(hif_drv);
|
||||
vif->hif_drv = NULL;
|
||||
vif->wilc->clients_count--;
|
||||
mutex_unlock(&vif->wilc->deinit_lock);
|
||||
return result;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -207,6 +207,7 @@ int wilc_get_statistics(struct wilc_vif *vif, struct rf_info *stats);
|
|||
int wilc_get_vif_idx(struct wilc_vif *vif);
|
||||
int wilc_set_tx_power(struct wilc_vif *vif, u8 tx_power);
|
||||
int wilc_get_tx_power(struct wilc_vif *vif, u8 *tx_power);
|
||||
void wilc_set_wowlan_trigger(struct wilc_vif *vif, bool enabled);
|
||||
void wilc_scan_complete_received(struct wilc *wilc, u8 *buffer, u32 length);
|
||||
void wilc_network_info_received(struct wilc *wilc, u8 *buffer, u32 length);
|
||||
void wilc_gnrl_async_info_received(struct wilc *wilc, u8 *buffer, u32 length);
|
||||
|
|
|
|||
|
|
@ -264,9 +264,7 @@ struct wilc {
|
|||
struct device *dev;
|
||||
bool suspend_event;
|
||||
|
||||
int clients_count;
|
||||
struct workqueue_struct *hif_workqueue;
|
||||
enum chip_ps_states chip_ps_state;
|
||||
struct wilc_cfg cfg;
|
||||
void *bus_data;
|
||||
struct net_device *monitor_dev;
|
||||
|
|
|
|||
|
|
@ -978,6 +978,7 @@ static const struct wilc_hif_func wilc_hif_sdio = {
|
|||
.hif_sync_ext = wilc_sdio_sync_ext,
|
||||
.enable_interrupt = wilc_sdio_enable_interrupt,
|
||||
.disable_interrupt = wilc_sdio_disable_interrupt,
|
||||
.hif_reset = wilc_sdio_reset,
|
||||
};
|
||||
|
||||
static int wilc_sdio_resume(struct device *dev)
|
||||
|
|
|
|||
|
|
@ -47,6 +47,8 @@ struct wilc_spi {
|
|||
|
||||
static const struct wilc_hif_func wilc_hif_spi;
|
||||
|
||||
static int wilc_spi_reset(struct wilc *wilc);
|
||||
|
||||
/********************************************
|
||||
*
|
||||
* Spi protocol Function
|
||||
|
|
@ -144,6 +146,12 @@ struct wilc_spi_rsp_data {
|
|||
u8 data[];
|
||||
} __packed;
|
||||
|
||||
struct wilc_spi_special_cmd_rsp {
|
||||
u8 skip_byte;
|
||||
u8 rsp_cmd_type;
|
||||
u8 status;
|
||||
} __packed;
|
||||
|
||||
static int wilc_bus_probe(struct spi_device *spi)
|
||||
{
|
||||
int ret;
|
||||
|
|
@ -466,7 +474,7 @@ static int wilc_spi_single_read(struct wilc *wilc, u8 cmd, u32 adr, void *b,
|
|||
}
|
||||
|
||||
r = (struct wilc_spi_rsp_data *)&rb[cmd_len];
|
||||
if (r->rsp_cmd_type != cmd) {
|
||||
if (r->rsp_cmd_type != cmd && !clockless) {
|
||||
if (!spi_priv->probing_crc)
|
||||
dev_err(&spi->dev,
|
||||
"Failed cmd, cmd (%02x), resp (%02x)\n",
|
||||
|
|
@ -474,7 +482,7 @@ static int wilc_spi_single_read(struct wilc *wilc, u8 cmd, u32 adr, void *b,
|
|||
return -EINVAL;
|
||||
}
|
||||
|
||||
if (r->status != WILC_SPI_COMMAND_STAT_SUCCESS) {
|
||||
if (r->status != WILC_SPI_COMMAND_STAT_SUCCESS && !clockless) {
|
||||
dev_err(&spi->dev, "Failed cmd state response state (%02x)\n",
|
||||
r->status);
|
||||
return -EINVAL;
|
||||
|
|
@ -563,14 +571,18 @@ static int wilc_spi_write_cmd(struct wilc *wilc, u8 cmd, u32 adr, u32 data,
|
|||
}
|
||||
|
||||
r = (struct wilc_spi_rsp_data *)&rb[cmd_len];
|
||||
if (r->rsp_cmd_type != cmd) {
|
||||
/*
|
||||
* Clockless registers operations might return unexptected responses,
|
||||
* even if successful.
|
||||
*/
|
||||
if (r->rsp_cmd_type != cmd && !clockless) {
|
||||
dev_err(&spi->dev,
|
||||
"Failed cmd response, cmd (%02x), resp (%02x)\n",
|
||||
cmd, r->rsp_cmd_type);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
if (r->status != WILC_SPI_COMMAND_STAT_SUCCESS) {
|
||||
if (r->status != WILC_SPI_COMMAND_STAT_SUCCESS && !clockless) {
|
||||
dev_err(&spi->dev, "Failed cmd state response state (%02x)\n",
|
||||
r->status);
|
||||
return -EINVAL;
|
||||
|
|
@ -709,6 +721,61 @@ static int wilc_spi_dma_rw(struct wilc *wilc, u8 cmd, u32 adr, u8 *b, u32 sz)
|
|||
return 0;
|
||||
}
|
||||
|
||||
static int wilc_spi_special_cmd(struct wilc *wilc, u8 cmd)
|
||||
{
|
||||
struct spi_device *spi = to_spi_device(wilc->dev);
|
||||
struct wilc_spi *spi_priv = wilc->bus_data;
|
||||
u8 wb[32], rb[32];
|
||||
int cmd_len, resp_len = 0;
|
||||
struct wilc_spi_cmd *c;
|
||||
struct wilc_spi_special_cmd_rsp *r;
|
||||
|
||||
if (cmd != CMD_TERMINATE && cmd != CMD_REPEAT && cmd != CMD_RESET)
|
||||
return -EINVAL;
|
||||
|
||||
memset(wb, 0x0, sizeof(wb));
|
||||
memset(rb, 0x0, sizeof(rb));
|
||||
c = (struct wilc_spi_cmd *)wb;
|
||||
c->cmd_type = cmd;
|
||||
|
||||
if (cmd == CMD_RESET)
|
||||
memset(c->u.simple_cmd.addr, 0xFF, 3);
|
||||
|
||||
cmd_len = offsetof(struct wilc_spi_cmd, u.simple_cmd.crc);
|
||||
resp_len = sizeof(*r);
|
||||
|
||||
if (spi_priv->crc7_enabled) {
|
||||
c->u.simple_cmd.crc[0] = wilc_get_crc7(wb, cmd_len);
|
||||
cmd_len += 1;
|
||||
}
|
||||
if (cmd_len + resp_len > ARRAY_SIZE(wb)) {
|
||||
dev_err(&spi->dev, "spi buffer size too small (%d) (%d) (%zu)\n",
|
||||
cmd_len, resp_len, ARRAY_SIZE(wb));
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
if (wilc_spi_tx_rx(wilc, wb, rb, cmd_len + resp_len)) {
|
||||
dev_err(&spi->dev, "Failed cmd write, bus error...\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
r = (struct wilc_spi_special_cmd_rsp *)&rb[cmd_len];
|
||||
if (r->rsp_cmd_type != cmd) {
|
||||
if (!spi_priv->probing_crc)
|
||||
dev_err(&spi->dev,
|
||||
"Failed cmd response, cmd (%02x), resp (%02x)\n",
|
||||
cmd, r->rsp_cmd_type);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
if (r->status != WILC_SPI_COMMAND_STAT_SUCCESS) {
|
||||
dev_err(&spi->dev, "Failed cmd state response state (%02x)\n",
|
||||
r->status);
|
||||
return -EINVAL;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int wilc_spi_read_reg(struct wilc *wilc, u32 addr, u32 *data)
|
||||
{
|
||||
struct spi_device *spi = to_spi_device(wilc->dev);
|
||||
|
|
@ -895,6 +962,19 @@ static int wilc_spi_write(struct wilc *wilc, u32 addr, u8 *buf, u32 size)
|
|||
*
|
||||
********************************************/
|
||||
|
||||
static int wilc_spi_reset(struct wilc *wilc)
|
||||
{
|
||||
struct spi_device *spi = to_spi_device(wilc->dev);
|
||||
struct wilc_spi *spi_priv = wilc->bus_data;
|
||||
int result;
|
||||
|
||||
result = wilc_spi_special_cmd(wilc, CMD_RESET);
|
||||
if (result && !spi_priv->probing_crc)
|
||||
dev_err(&spi->dev, "Failed cmd reset\n");
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
static int wilc_spi_deinit(struct wilc *wilc)
|
||||
{
|
||||
/*
|
||||
|
|
@ -1087,7 +1167,7 @@ static int wilc_spi_sync_ext(struct wilc *wilc, int nint)
|
|||
for (i = 0; (i < 3) && (nint > 0); i++, nint--)
|
||||
reg |= BIT(i);
|
||||
|
||||
ret = wilc_spi_read_reg(wilc, WILC_INTR2_ENABLE, ®);
|
||||
ret = wilc_spi_write_reg(wilc, WILC_INTR2_ENABLE, reg);
|
||||
if (ret) {
|
||||
dev_err(&spi->dev, "Failed write reg (%08x)...\n",
|
||||
WILC_INTR2_ENABLE);
|
||||
|
|
@ -1112,4 +1192,5 @@ static const struct wilc_hif_func wilc_hif_spi = {
|
|||
.hif_block_tx_ext = wilc_spi_write,
|
||||
.hif_block_rx_ext = wilc_spi_read,
|
||||
.hif_sync_ext = wilc_spi_sync_ext,
|
||||
.hif_reset = wilc_spi_reset,
|
||||
};
|
||||
|
|
|
|||
|
|
@ -10,6 +10,8 @@
|
|||
#include "cfg80211.h"
|
||||
#include "wlan_cfg.h"
|
||||
|
||||
#define WAKE_UP_TRIAL_RETRY 10000
|
||||
|
||||
static inline bool is_wilc1000(u32 id)
|
||||
{
|
||||
return (id & (~WILC_CHIP_REV_FIELD)) == WILC_1000_BASE_ID;
|
||||
|
|
@ -425,6 +427,11 @@ int wilc_wlan_txq_add_net_pkt(struct net_device *dev,
|
|||
return 0;
|
||||
}
|
||||
|
||||
if (!wilc->initialized) {
|
||||
tx_complete_fn(tx_data, 0);
|
||||
return 0;
|
||||
}
|
||||
|
||||
tqe = kmalloc(sizeof(*tqe), GFP_ATOMIC);
|
||||
|
||||
if (!tqe) {
|
||||
|
|
@ -474,6 +481,10 @@ int wilc_wlan_txq_add_mgmt_pkt(struct net_device *dev, void *priv, u8 *buffer,
|
|||
return 0;
|
||||
}
|
||||
|
||||
if (!wilc->initialized) {
|
||||
tx_complete_fn(priv, 0);
|
||||
return 0;
|
||||
}
|
||||
tqe = kmalloc(sizeof(*tqe), GFP_ATOMIC);
|
||||
|
||||
if (!tqe) {
|
||||
|
|
@ -611,60 +622,67 @@ EXPORT_SYMBOL_GPL(chip_allow_sleep);
|
|||
|
||||
void chip_wakeup(struct wilc *wilc)
|
||||
{
|
||||
u32 reg, clk_status_reg;
|
||||
const struct wilc_hif_func *h = wilc->hif_func;
|
||||
u32 ret = 0;
|
||||
u32 clk_status_val = 0, trials = 0;
|
||||
u32 wakeup_reg, wakeup_bit;
|
||||
u32 clk_status_reg, clk_status_bit;
|
||||
u32 to_host_from_fw_reg, to_host_from_fw_bit;
|
||||
u32 from_host_to_fw_reg, from_host_to_fw_bit;
|
||||
const struct wilc_hif_func *hif_func = wilc->hif_func;
|
||||
|
||||
if (wilc->io_type == WILC_HIF_SPI) {
|
||||
do {
|
||||
h->hif_read_reg(wilc, WILC_SPI_WAKEUP_REG, ®);
|
||||
h->hif_write_reg(wilc, WILC_SPI_WAKEUP_REG,
|
||||
reg | WILC_SPI_WAKEUP_BIT);
|
||||
h->hif_write_reg(wilc, WILC_SPI_WAKEUP_REG,
|
||||
reg & ~WILC_SPI_WAKEUP_BIT);
|
||||
|
||||
do {
|
||||
usleep_range(2000, 2500);
|
||||
wilc_get_chipid(wilc, true);
|
||||
} while (wilc_get_chipid(wilc, true) == 0);
|
||||
} while (wilc_get_chipid(wilc, true) == 0);
|
||||
} else if (wilc->io_type == WILC_HIF_SDIO) {
|
||||
h->hif_write_reg(wilc, WILC_SDIO_HOST_TO_FW_REG,
|
||||
WILC_SDIO_HOST_TO_FW_BIT);
|
||||
usleep_range(200, 400);
|
||||
h->hif_read_reg(wilc, WILC_SDIO_WAKEUP_REG, ®);
|
||||
do {
|
||||
h->hif_write_reg(wilc, WILC_SDIO_WAKEUP_REG,
|
||||
reg | WILC_SDIO_WAKEUP_BIT);
|
||||
h->hif_read_reg(wilc, WILC_SDIO_CLK_STATUS_REG,
|
||||
&clk_status_reg);
|
||||
|
||||
while (!(clk_status_reg & WILC_SDIO_CLK_STATUS_BIT)) {
|
||||
usleep_range(2000, 2500);
|
||||
|
||||
h->hif_read_reg(wilc, WILC_SDIO_CLK_STATUS_REG,
|
||||
&clk_status_reg);
|
||||
}
|
||||
if (!(clk_status_reg & WILC_SDIO_CLK_STATUS_BIT)) {
|
||||
h->hif_write_reg(wilc, WILC_SDIO_WAKEUP_REG,
|
||||
reg & ~WILC_SDIO_WAKEUP_BIT);
|
||||
}
|
||||
} while (!(clk_status_reg & WILC_SDIO_CLK_STATUS_BIT));
|
||||
if (wilc->io_type == WILC_HIF_SDIO) {
|
||||
wakeup_reg = WILC_SDIO_WAKEUP_REG;
|
||||
wakeup_bit = WILC_SDIO_WAKEUP_BIT;
|
||||
clk_status_reg = WILC_SDIO_CLK_STATUS_REG;
|
||||
clk_status_bit = WILC_SDIO_CLK_STATUS_BIT;
|
||||
from_host_to_fw_reg = WILC_SDIO_HOST_TO_FW_REG;
|
||||
from_host_to_fw_bit = WILC_SDIO_HOST_TO_FW_BIT;
|
||||
to_host_from_fw_reg = WILC_SDIO_FW_TO_HOST_REG;
|
||||
to_host_from_fw_bit = WILC_SDIO_FW_TO_HOST_BIT;
|
||||
} else {
|
||||
wakeup_reg = WILC_SPI_WAKEUP_REG;
|
||||
wakeup_bit = WILC_SPI_WAKEUP_BIT;
|
||||
clk_status_reg = WILC_SPI_CLK_STATUS_REG;
|
||||
clk_status_bit = WILC_SPI_CLK_STATUS_BIT;
|
||||
from_host_to_fw_reg = WILC_SPI_HOST_TO_FW_REG;
|
||||
from_host_to_fw_bit = WILC_SPI_HOST_TO_FW_BIT;
|
||||
to_host_from_fw_reg = WILC_SPI_FW_TO_HOST_REG;
|
||||
to_host_from_fw_bit = WILC_SPI_FW_TO_HOST_BIT;
|
||||
}
|
||||
|
||||
if (wilc->chip_ps_state == WILC_CHIP_SLEEPING_MANUAL) {
|
||||
if (wilc_get_chipid(wilc, false) < WILC_1000_BASE_ID_2B) {
|
||||
u32 val32;
|
||||
/* indicate host wakeup */
|
||||
ret = hif_func->hif_write_reg(wilc, from_host_to_fw_reg,
|
||||
from_host_to_fw_bit);
|
||||
if (ret)
|
||||
return;
|
||||
|
||||
h->hif_read_reg(wilc, WILC_REG_4_TO_1_RX, &val32);
|
||||
val32 |= BIT(6);
|
||||
h->hif_write_reg(wilc, WILC_REG_4_TO_1_RX, val32);
|
||||
/* Set wake-up bit */
|
||||
ret = hif_func->hif_write_reg(wilc, wakeup_reg,
|
||||
wakeup_bit);
|
||||
if (ret)
|
||||
return;
|
||||
|
||||
h->hif_read_reg(wilc, WILC_REG_4_TO_1_TX_BANK0, &val32);
|
||||
val32 |= BIT(6);
|
||||
h->hif_write_reg(wilc, WILC_REG_4_TO_1_TX_BANK0, val32);
|
||||
while (trials < WAKE_UP_TRIAL_RETRY) {
|
||||
ret = hif_func->hif_read_reg(wilc, clk_status_reg,
|
||||
&clk_status_val);
|
||||
if (ret) {
|
||||
pr_err("Bus error %d %x\n", ret, clk_status_val);
|
||||
return;
|
||||
}
|
||||
if (clk_status_val & clk_status_bit)
|
||||
break;
|
||||
|
||||
trials++;
|
||||
}
|
||||
wilc->chip_ps_state = WILC_CHIP_WAKEDUP;
|
||||
if (trials >= WAKE_UP_TRIAL_RETRY) {
|
||||
pr_err("Failed to wake-up the chip\n");
|
||||
return;
|
||||
}
|
||||
/* Sometimes spi fail to read clock regs after reading
|
||||
* writing clockless registers
|
||||
*/
|
||||
if (wilc->io_type == WILC_HIF_SPI)
|
||||
wilc->hif_func->hif_reset(wilc);
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(chip_wakeup);
|
||||
|
||||
|
|
@ -1071,6 +1089,7 @@ int wilc_wlan_firmware_download(struct wilc *wilc, const u8 *buffer,
|
|||
u32 addr, size, size2, blksz;
|
||||
u8 *dma_buffer;
|
||||
int ret = 0;
|
||||
u32 reg = 0;
|
||||
|
||||
blksz = BIT(12);
|
||||
|
||||
|
|
@ -1079,10 +1098,22 @@ int wilc_wlan_firmware_download(struct wilc *wilc, const u8 *buffer,
|
|||
return -EIO;
|
||||
|
||||
offset = 0;
|
||||
pr_debug("%s: Downloading firmware size = %d\n", __func__, buffer_size);
|
||||
|
||||
acquire_bus(wilc, WILC_BUS_ACQUIRE_AND_WAKEUP);
|
||||
|
||||
wilc->hif_func->hif_read_reg(wilc, WILC_GLB_RESET_0, ®);
|
||||
reg &= ~BIT(10);
|
||||
ret = wilc->hif_func->hif_write_reg(wilc, WILC_GLB_RESET_0, reg);
|
||||
wilc->hif_func->hif_read_reg(wilc, WILC_GLB_RESET_0, ®);
|
||||
if (reg & BIT(10))
|
||||
pr_err("%s: Failed to reset\n", __func__);
|
||||
|
||||
release_bus(wilc, WILC_BUS_RELEASE_ONLY);
|
||||
do {
|
||||
addr = get_unaligned_le32(&buffer[offset]);
|
||||
size = get_unaligned_le32(&buffer[offset + 4]);
|
||||
acquire_bus(wilc, WILC_BUS_ACQUIRE_ONLY);
|
||||
acquire_bus(wilc, WILC_BUS_ACQUIRE_AND_WAKEUP);
|
||||
offset += 8;
|
||||
while (((int)size) && (offset < buffer_size)) {
|
||||
if (size <= blksz)
|
||||
|
|
@ -1100,10 +1131,13 @@ int wilc_wlan_firmware_download(struct wilc *wilc, const u8 *buffer,
|
|||
offset += size2;
|
||||
size -= size2;
|
||||
}
|
||||
release_bus(wilc, WILC_BUS_RELEASE_ONLY);
|
||||
release_bus(wilc, WILC_BUS_RELEASE_ALLOW_SLEEP);
|
||||
|
||||
if (ret)
|
||||
if (ret) {
|
||||
pr_err("%s Bus error\n", __func__);
|
||||
goto fail;
|
||||
}
|
||||
pr_debug("%s Offset = %d\n", __func__, offset);
|
||||
} while (offset < buffer_size);
|
||||
|
||||
fail:
|
||||
|
|
|
|||
|
|
@ -97,6 +97,8 @@
|
|||
#define WILC_SPI_WAKEUP_REG 0x1
|
||||
#define WILC_SPI_WAKEUP_BIT BIT(1)
|
||||
|
||||
#define WILC_SPI_CLK_STATUS_REG 0x0f
|
||||
#define WILC_SPI_CLK_STATUS_BIT BIT(2)
|
||||
#define WILC_SPI_HOST_TO_FW_REG 0x0b
|
||||
#define WILC_SPI_HOST_TO_FW_BIT BIT(0)
|
||||
|
||||
|
|
@ -300,7 +302,7 @@
|
|||
#define ENABLE_RX_VMM (SEL_VMM_TBL1 | EN_VMM)
|
||||
#define ENABLE_TX_VMM (SEL_VMM_TBL0 | EN_VMM)
|
||||
/* time for expiring the completion of cfg packets */
|
||||
#define WILC_CFG_PKTS_TIMEOUT msecs_to_jiffies(2000)
|
||||
#define WILC_CFG_PKTS_TIMEOUT msecs_to_jiffies(3000)
|
||||
|
||||
#define IS_MANAGMEMENT 0x100
|
||||
#define IS_MANAGMEMENT_CALLBACK 0x080
|
||||
|
|
@ -371,6 +373,7 @@ struct wilc_hif_func {
|
|||
int (*hif_sync_ext)(struct wilc *wilc, int nint);
|
||||
int (*enable_interrupt)(struct wilc *nic);
|
||||
void (*disable_interrupt)(struct wilc *nic);
|
||||
int (*hif_reset)(struct wilc *wilc);
|
||||
};
|
||||
|
||||
#define WILC_MAX_CFG_FRAME_SIZE 1468
|
||||
|
|
|
|||
|
|
@ -22,6 +22,7 @@ static const struct wilc_cfg_byte g_cfg_byte[] = {
|
|||
{WID_STATUS, 0},
|
||||
{WID_RSSI, 0},
|
||||
{WID_LINKSPEED, 0},
|
||||
{WID_WOWLAN_TRIGGER, 0},
|
||||
{WID_NIL, 0}
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -48,12 +48,6 @@ enum {
|
|||
WILC_FW_MAX_PSPOLL_PS = 4
|
||||
};
|
||||
|
||||
enum chip_ps_states {
|
||||
WILC_CHIP_WAKEDUP = 0,
|
||||
WILC_CHIP_SLEEPING_AUTO = 1,
|
||||
WILC_CHIP_SLEEPING_MANUAL = 2
|
||||
};
|
||||
|
||||
enum bus_acquire {
|
||||
WILC_BUS_ACQUIRE_ONLY = 0,
|
||||
WILC_BUS_ACQUIRE_AND_WAKEUP = 1,
|
||||
|
|
@ -662,6 +656,7 @@ enum {
|
|||
|
||||
WID_LOG_TERMINAL_SWITCH = 0x00CD,
|
||||
WID_TX_POWER = 0x00CE,
|
||||
WID_WOWLAN_TRIGGER = 0X00CF,
|
||||
/* EMAC Short WID list */
|
||||
/* RTS Threshold */
|
||||
/*
|
||||
|
|
|
|||
|
|
@ -1101,7 +1101,6 @@ static const struct usb_device_id rt2800usb_device_table[] = {
|
|||
#ifdef CONFIG_RT2800USB_RT53XX
|
||||
/* Arcadyan */
|
||||
{ USB_DEVICE(0x043e, 0x7a12) },
|
||||
{ USB_DEVICE(0x043e, 0x7a32) },
|
||||
/* ASUS */
|
||||
{ USB_DEVICE(0x0b05, 0x17e8) },
|
||||
/* Azurewave */
|
||||
|
|
|
|||
|
|
@ -4460,13 +4460,17 @@ void rtl8xxxu_gen1_init_aggregation(struct rtl8xxxu_priv *priv)
|
|||
|
||||
static void rtl8xxxu_set_basic_rates(struct rtl8xxxu_priv *priv, u32 rate_cfg)
|
||||
{
|
||||
struct ieee80211_hw *hw = priv->hw;
|
||||
u32 val32;
|
||||
u8 rate_idx = 0;
|
||||
|
||||
rate_cfg &= RESPONSE_RATE_BITMAP_ALL;
|
||||
|
||||
val32 = rtl8xxxu_read32(priv, REG_RESPONSE_RATE_SET);
|
||||
val32 &= ~RESPONSE_RATE_BITMAP_ALL;
|
||||
if (hw->conf.chandef.chan->band == NL80211_BAND_5GHZ)
|
||||
val32 &= RESPONSE_RATE_RRSR_INIT_5G;
|
||||
else
|
||||
val32 &= RESPONSE_RATE_RRSR_INIT_2G;
|
||||
val32 |= rate_cfg;
|
||||
rtl8xxxu_write32(priv, REG_RESPONSE_RATE_SET, val32);
|
||||
|
||||
|
|
|
|||
|
|
@ -516,6 +516,8 @@
|
|||
#define REG_RESPONSE_RATE_SET 0x0440
|
||||
#define RESPONSE_RATE_BITMAP_ALL 0xfffff
|
||||
#define RESPONSE_RATE_RRSR_CCK_ONLY_1M 0xffff1
|
||||
#define RESPONSE_RATE_RRSR_INIT_2G 0x15f
|
||||
#define RESPONSE_RATE_RRSR_INIT_5G 0x150
|
||||
#define RSR_1M BIT(0)
|
||||
#define RSR_2M BIT(1)
|
||||
#define RSR_5_5M BIT(2)
|
||||
|
|
|
|||
|
|
@ -12,6 +12,7 @@
|
|||
#include "phy.h"
|
||||
#include "reg.h"
|
||||
#include "ps.h"
|
||||
#include "regd.h"
|
||||
|
||||
#ifdef CONFIG_RTW88_DEBUGFS
|
||||
|
||||
|
|
@ -587,7 +588,7 @@ static int rtw_debugfs_get_tx_pwr_tbl(struct seq_file *m, void *v)
|
|||
struct rtw_power_params pwr_param = {0};
|
||||
u8 bw = hal->current_band_width;
|
||||
u8 ch = hal->current_channel;
|
||||
u8 regd = rtwdev->regd.txpwr_regd;
|
||||
u8 regd = rtw_regd_get(rtwdev);
|
||||
|
||||
seq_printf(m, "regulatory: %s\n", rtw_get_regd_string(regd));
|
||||
seq_printf(m, "%-4s %-10s %-3s%6s %-4s %4s (%-4s %-4s) %-4s\n",
|
||||
|
|
@ -828,6 +829,38 @@ static int rtw_debugfs_get_coex_enable(struct seq_file *m, void *v)
|
|||
return 0;
|
||||
}
|
||||
|
||||
static ssize_t rtw_debugfs_set_edcca_enable(struct file *filp,
|
||||
const char __user *buffer,
|
||||
size_t count, loff_t *loff)
|
||||
{
|
||||
struct seq_file *seqpriv = (struct seq_file *)filp->private_data;
|
||||
struct rtw_debugfs_priv *debugfs_priv = seqpriv->private;
|
||||
struct rtw_dev *rtwdev = debugfs_priv->rtwdev;
|
||||
bool input;
|
||||
int err;
|
||||
|
||||
err = kstrtobool_from_user(buffer, count, &input);
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
rtw_edcca_enabled = input;
|
||||
rtw_phy_adaptivity_set_mode(rtwdev);
|
||||
|
||||
return count;
|
||||
}
|
||||
|
||||
static int rtw_debugfs_get_edcca_enable(struct seq_file *m, void *v)
|
||||
{
|
||||
struct rtw_debugfs_priv *debugfs_priv = m->private;
|
||||
struct rtw_dev *rtwdev = debugfs_priv->rtwdev;
|
||||
struct rtw_dm_info *dm_info = &rtwdev->dm_info;
|
||||
|
||||
seq_printf(m, "EDCCA %s: EDCCA mode %d\n",
|
||||
rtw_edcca_enabled ? "enabled" : "disabled",
|
||||
dm_info->edcca_mode);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static ssize_t rtw_debugfs_set_fw_crash(struct file *filp,
|
||||
const char __user *buffer,
|
||||
size_t count, loff_t *loff)
|
||||
|
|
@ -853,6 +886,7 @@ static ssize_t rtw_debugfs_set_fw_crash(struct file *filp,
|
|||
|
||||
mutex_lock(&rtwdev->mutex);
|
||||
rtw_leave_lps_deep(rtwdev);
|
||||
set_bit(RTW_FLAG_RESTART_TRIGGERING, rtwdev->flags);
|
||||
rtw_write8(rtwdev, REG_HRCV_MSG, 1);
|
||||
mutex_unlock(&rtwdev->mutex);
|
||||
|
||||
|
|
@ -864,7 +898,9 @@ static int rtw_debugfs_get_fw_crash(struct seq_file *m, void *v)
|
|||
struct rtw_debugfs_priv *debugfs_priv = m->private;
|
||||
struct rtw_dev *rtwdev = debugfs_priv->rtwdev;
|
||||
|
||||
seq_printf(m, "%d\n", test_bit(RTW_FLAG_RESTARTING, rtwdev->flags));
|
||||
seq_printf(m, "%d\n",
|
||||
test_bit(RTW_FLAG_RESTART_TRIGGERING, rtwdev->flags) ||
|
||||
test_bit(RTW_FLAG_RESTARTING, rtwdev->flags));
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
@ -1048,6 +1084,11 @@ static struct rtw_debugfs_priv rtw_debug_priv_coex_info = {
|
|||
.cb_read = rtw_debugfs_get_coex_info,
|
||||
};
|
||||
|
||||
static struct rtw_debugfs_priv rtw_debug_priv_edcca_enable = {
|
||||
.cb_write = rtw_debugfs_set_edcca_enable,
|
||||
.cb_read = rtw_debugfs_get_edcca_enable,
|
||||
};
|
||||
|
||||
static struct rtw_debugfs_priv rtw_debug_priv_fw_crash = {
|
||||
.cb_write = rtw_debugfs_set_fw_crash,
|
||||
.cb_read = rtw_debugfs_get_fw_crash,
|
||||
|
|
@ -1131,6 +1172,7 @@ void rtw_debugfs_init(struct rtw_dev *rtwdev)
|
|||
}
|
||||
rtw_debugfs_add_r(rf_dump);
|
||||
rtw_debugfs_add_r(tx_pwr_tbl);
|
||||
rtw_debugfs_add_rw(edcca_enable);
|
||||
rtw_debugfs_add_rw(fw_crash);
|
||||
rtw_debugfs_add_rw(dm_cap);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -21,6 +21,7 @@ enum rtw_debug_mask {
|
|||
RTW_DBG_WOW = 0x00001000,
|
||||
RTW_DBG_CFO = 0x00002000,
|
||||
RTW_DBG_PATH_DIV = 0x00004000,
|
||||
RTW_DBG_ADAPTIVITY = 0x00008000,
|
||||
|
||||
RTW_DBG_ALL = 0xffffffff
|
||||
};
|
||||
|
|
|
|||
|
|
@ -183,6 +183,28 @@ static void rtw_fw_scan_result(struct rtw_dev *rtwdev, u8 *payload,
|
|||
dm_info->scan_density);
|
||||
}
|
||||
|
||||
static void rtw_fw_adaptivity_result(struct rtw_dev *rtwdev, u8 *payload,
|
||||
u8 length)
|
||||
{
|
||||
struct rtw_hw_reg_offset *edcca_th = rtwdev->chip->edcca_th;
|
||||
struct rtw_c2h_adaptivity *result = (struct rtw_c2h_adaptivity *)payload;
|
||||
|
||||
rtw_dbg(rtwdev, RTW_DBG_ADAPTIVITY,
|
||||
"Adaptivity: density %x igi %x l2h_th_init %x l2h %x h2l %x option %x\n",
|
||||
result->density, result->igi, result->l2h_th_init, result->l2h,
|
||||
result->h2l, result->option);
|
||||
|
||||
rtw_dbg(rtwdev, RTW_DBG_ADAPTIVITY, "Reg Setting: L2H %x H2L %x\n",
|
||||
rtw_read32_mask(rtwdev, edcca_th[EDCCA_TH_L2H_IDX].hw_reg.addr,
|
||||
edcca_th[EDCCA_TH_L2H_IDX].hw_reg.mask),
|
||||
rtw_read32_mask(rtwdev, edcca_th[EDCCA_TH_H2L_IDX].hw_reg.addr,
|
||||
edcca_th[EDCCA_TH_H2L_IDX].hw_reg.mask));
|
||||
|
||||
rtw_dbg(rtwdev, RTW_DBG_ADAPTIVITY, "EDCCA Flag %s\n",
|
||||
rtw_read32_mask(rtwdev, REG_EDCCA_REPORT, BIT_EDCCA_FLAG) ?
|
||||
"Set" : "Unset");
|
||||
}
|
||||
|
||||
void rtw_fw_c2h_cmd_handle(struct rtw_dev *rtwdev, struct sk_buff *skb)
|
||||
{
|
||||
struct rtw_c2h_cmd *c2h;
|
||||
|
|
@ -252,6 +274,10 @@ void rtw_fw_c2h_cmd_rx_irqsafe(struct rtw_dev *rtwdev, u32 pkt_offset,
|
|||
rtw_fw_scan_result(rtwdev, c2h->payload, len);
|
||||
dev_kfree_skb_any(skb);
|
||||
break;
|
||||
case C2H_ADAPTIVITY:
|
||||
rtw_fw_adaptivity_result(rtwdev, c2h->payload, len);
|
||||
dev_kfree_skb_any(skb);
|
||||
break;
|
||||
default:
|
||||
/* pass offset for further operation */
|
||||
*((u32 *)skb->cb) = pkt_offset;
|
||||
|
|
@ -1556,12 +1582,10 @@ static void rtw_fw_read_fifo_page(struct rtw_dev *rtwdev, u32 offset, u32 size,
|
|||
u32 i;
|
||||
u16 idx = 0;
|
||||
u16 ctl;
|
||||
u8 rcr;
|
||||
|
||||
rcr = rtw_read8(rtwdev, REG_RCR + 2);
|
||||
ctl = rtw_read16(rtwdev, REG_PKTBUF_DBG_CTRL) & 0xf000;
|
||||
/* disable rx clock gate */
|
||||
rtw_write8(rtwdev, REG_RCR, rcr | BIT(3));
|
||||
rtw_write32_set(rtwdev, REG_RCR, BIT_DISGCLK);
|
||||
|
||||
do {
|
||||
rtw_write16(rtwdev, REG_PKTBUF_DBG_CTRL, start_pg | ctl);
|
||||
|
|
@ -1580,7 +1604,8 @@ static void rtw_fw_read_fifo_page(struct rtw_dev *rtwdev, u32 offset, u32 size,
|
|||
|
||||
out:
|
||||
rtw_write16(rtwdev, REG_PKTBUF_DBG_CTRL, ctl);
|
||||
rtw_write8(rtwdev, REG_RCR + 2, rcr);
|
||||
/* restore rx clock gate */
|
||||
rtw_write32_clr(rtwdev, REG_RCR, BIT_DISGCLK);
|
||||
}
|
||||
|
||||
static void rtw_fw_read_fifo(struct rtw_dev *rtwdev, enum rtw_fw_fifo_sel sel,
|
||||
|
|
@ -1722,6 +1747,27 @@ void rtw_fw_channel_switch(struct rtw_dev *rtwdev, bool enable)
|
|||
rtw_fw_send_h2c_packet(rtwdev, h2c_pkt);
|
||||
}
|
||||
|
||||
void rtw_fw_adaptivity(struct rtw_dev *rtwdev)
|
||||
{
|
||||
struct rtw_dm_info *dm_info = &rtwdev->dm_info;
|
||||
u8 h2c_pkt[H2C_PKT_SIZE] = {0};
|
||||
|
||||
if (!rtw_edcca_enabled) {
|
||||
dm_info->edcca_mode = RTW_EDCCA_NORMAL;
|
||||
rtw_dbg(rtwdev, RTW_DBG_ADAPTIVITY,
|
||||
"EDCCA disabled by debugfs\n");
|
||||
}
|
||||
|
||||
SET_H2C_CMD_ID_CLASS(h2c_pkt, H2C_CMD_ADAPTIVITY);
|
||||
SET_ADAPTIVITY_MODE(h2c_pkt, dm_info->edcca_mode);
|
||||
SET_ADAPTIVITY_OPTION(h2c_pkt, 2);
|
||||
SET_ADAPTIVITY_IGI(h2c_pkt, dm_info->igi_history[0]);
|
||||
SET_ADAPTIVITY_L2H(h2c_pkt, dm_info->l2h_th_ini);
|
||||
SET_ADAPTIVITY_DENSITY(h2c_pkt, dm_info->scan_density);
|
||||
|
||||
rtw_fw_send_h2c_command(rtwdev, h2c_pkt);
|
||||
}
|
||||
|
||||
void rtw_fw_scan_notify(struct rtw_dev *rtwdev, bool start)
|
||||
{
|
||||
u8 h2c_pkt[H2C_PKT_SIZE] = {0};
|
||||
|
|
|
|||
|
|
@ -41,6 +41,7 @@ enum rtw_c2h_cmd_id {
|
|||
C2H_WLAN_INFO = 0x27,
|
||||
C2H_WLAN_RFON = 0x32,
|
||||
C2H_BCN_FILTER_NOTIFY = 0x36,
|
||||
C2H_ADAPTIVITY = 0x37,
|
||||
C2H_SCAN_RESULT = 0x38,
|
||||
C2H_HW_FEATURE_DUMP = 0xfd,
|
||||
C2H_HALMAC = 0xff,
|
||||
|
|
@ -56,6 +57,15 @@ struct rtw_c2h_cmd {
|
|||
u8 payload[];
|
||||
} __packed;
|
||||
|
||||
struct rtw_c2h_adaptivity {
|
||||
u8 density;
|
||||
u8 igi;
|
||||
u8 l2h_th_init;
|
||||
u8 l2h;
|
||||
u8 h2l;
|
||||
u8 option;
|
||||
} __packed;
|
||||
|
||||
enum rtw_rsvd_packet_type {
|
||||
RSVD_BEACON,
|
||||
RSVD_DUMMY,
|
||||
|
|
@ -90,6 +100,7 @@ enum rtw_fw_feature {
|
|||
FW_FEATURE_PG = BIT(3),
|
||||
FW_FEATURE_BCN_FILTER = BIT(5),
|
||||
FW_FEATURE_NOTIFY_SCAN = BIT(6),
|
||||
FW_FEATURE_ADAPTIVITY = BIT(7),
|
||||
FW_FEATURE_MAX = BIT(31),
|
||||
};
|
||||
|
||||
|
|
@ -375,6 +386,7 @@ static inline void rtw_h2c_pkt_set_header(u8 *h2c_pkt, u8 sub_id)
|
|||
#define H2C_CMD_BCN_FILTER_OFFLOAD_P1 0x57
|
||||
#define H2C_CMD_WL_PHY_INFO 0x58
|
||||
#define H2C_CMD_SCAN 0x59
|
||||
#define H2C_CMD_ADAPTIVITY 0x5A
|
||||
|
||||
#define H2C_CMD_COEX_TDMA_TYPE 0x60
|
||||
#define H2C_CMD_QUERY_BT_INFO 0x61
|
||||
|
|
@ -428,6 +440,17 @@ static inline void rtw_h2c_pkt_set_header(u8 *h2c_pkt, u8 sub_id)
|
|||
#define SET_SCAN_START(h2c_pkt, value) \
|
||||
le32p_replace_bits((__le32 *)(h2c_pkt) + 0x00, value, BIT(8))
|
||||
|
||||
#define SET_ADAPTIVITY_MODE(h2c_pkt, value) \
|
||||
le32p_replace_bits((__le32 *)(h2c_pkt) + 0x00, value, GENMASK(11, 8))
|
||||
#define SET_ADAPTIVITY_OPTION(h2c_pkt, value) \
|
||||
le32p_replace_bits((__le32 *)(h2c_pkt) + 0x00, value, GENMASK(15, 12))
|
||||
#define SET_ADAPTIVITY_IGI(h2c_pkt, value) \
|
||||
le32p_replace_bits((__le32 *)(h2c_pkt) + 0x00, value, GENMASK(23, 16))
|
||||
#define SET_ADAPTIVITY_L2H(h2c_pkt, value) \
|
||||
le32p_replace_bits((__le32 *)(h2c_pkt) + 0x00, value, GENMASK(31, 24))
|
||||
#define SET_ADAPTIVITY_DENSITY(h2c_pkt, value) \
|
||||
le32p_replace_bits((__le32 *)(h2c_pkt) + 0x01, value, GENMASK(7, 0))
|
||||
|
||||
#define SET_PWR_MODE_SET_MODE(h2c_pkt, value) \
|
||||
le32p_replace_bits((__le32 *)(h2c_pkt) + 0x00, value, GENMASK(14, 8))
|
||||
#define SET_PWR_MODE_SET_RLBM(h2c_pkt, value) \
|
||||
|
|
@ -662,4 +685,5 @@ void rtw_fw_c2h_cmd_isr(struct rtw_dev *rtwdev);
|
|||
int rtw_fw_dump_fifo(struct rtw_dev *rtwdev, u8 fifo_sel, u32 addr, u32 size,
|
||||
u32 *buffer);
|
||||
void rtw_fw_scan_notify(struct rtw_dev *rtwdev, bool start);
|
||||
void rtw_fw_adaptivity(struct rtw_dev *rtwdev);
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -23,6 +23,14 @@ EXPORT_SYMBOL(rtw_disable_lps_deep_mode);
|
|||
bool rtw_bf_support = true;
|
||||
unsigned int rtw_debug_mask;
|
||||
EXPORT_SYMBOL(rtw_debug_mask);
|
||||
/* EDCCA is enabled during normal behavior. For debugging purpose in
|
||||
* a noisy environment, it can be disabled via edcca debugfs. Because
|
||||
* all rtw88 devices will probably be affected if environment is noisy,
|
||||
* rtw_edcca_enabled is just declared by driver instead of by device.
|
||||
* So, turning it off will take effect for all rtw88 devices before
|
||||
* there is a tough reason to maintain rtw_edcca_enabled by device.
|
||||
*/
|
||||
bool rtw_edcca_enabled = true;
|
||||
|
||||
module_param_named(disable_lps_deep, rtw_disable_lps_deep_mode, bool, 0644);
|
||||
module_param_named(support_bf, rtw_bf_support, bool, 0644);
|
||||
|
|
@ -556,6 +564,7 @@ static void __fw_recovery_work(struct rtw_dev *rtwdev)
|
|||
int ret = 0;
|
||||
|
||||
set_bit(RTW_FLAG_RESTARTING, rtwdev->flags);
|
||||
clear_bit(RTW_FLAG_RESTART_TRIGGERING, rtwdev->flags);
|
||||
|
||||
ret = rtw_fwcd_prep(rtwdev);
|
||||
if (ret)
|
||||
|
|
@ -1964,7 +1973,11 @@ int rtw_register_hw(struct rtw_dev *rtwdev, struct ieee80211_hw *hw)
|
|||
rtw_set_supported_band(hw, rtwdev->chip);
|
||||
SET_IEEE80211_PERM_ADDR(hw, rtwdev->efuse.addr);
|
||||
|
||||
rtw_regd_init(rtwdev, rtw_regd_notifier);
|
||||
ret = rtw_regd_init(rtwdev);
|
||||
if (ret) {
|
||||
rtw_err(rtwdev, "failed to init regd\n");
|
||||
return ret;
|
||||
}
|
||||
|
||||
ret = ieee80211_register_hw(hw);
|
||||
if (ret) {
|
||||
|
|
@ -1972,8 +1985,11 @@ int rtw_register_hw(struct rtw_dev *rtwdev, struct ieee80211_hw *hw)
|
|||
return ret;
|
||||
}
|
||||
|
||||
if (regulatory_hint(hw->wiphy, rtwdev->regd.alpha2))
|
||||
rtw_err(rtwdev, "regulatory_hint fail\n");
|
||||
ret = rtw_regd_hint(rtwdev);
|
||||
if (ret) {
|
||||
rtw_err(rtwdev, "failed to hint regd\n");
|
||||
return ret;
|
||||
}
|
||||
|
||||
rtw_debugfs_init(rtwdev);
|
||||
|
||||
|
|
|
|||
|
|
@ -41,6 +41,7 @@
|
|||
extern bool rtw_bf_support;
|
||||
extern bool rtw_disable_lps_deep_mode;
|
||||
extern unsigned int rtw_debug_mask;
|
||||
extern bool rtw_edcca_enabled;
|
||||
extern const struct ieee80211_ops rtw_ops;
|
||||
|
||||
#define RTW_MAX_CHANNEL_NUM_2G 14
|
||||
|
|
@ -362,6 +363,7 @@ enum rtw_flags {
|
|||
RTW_FLAG_BUSY_TRAFFIC,
|
||||
RTW_FLAG_WOWLAN,
|
||||
RTW_FLAG_RESTARTING,
|
||||
RTW_FLAG_RESTART_TRIGGERING,
|
||||
|
||||
NUM_OF_RTW_FLAGS,
|
||||
};
|
||||
|
|
@ -545,6 +547,11 @@ struct rtw_rf_sipi_addr {
|
|||
u32 lssi_read_pi;
|
||||
};
|
||||
|
||||
struct rtw_hw_reg_offset {
|
||||
struct rtw_hw_reg hw_reg;
|
||||
u8 offset;
|
||||
};
|
||||
|
||||
struct rtw_backup_info {
|
||||
u8 len;
|
||||
u32 reg;
|
||||
|
|
@ -800,8 +807,22 @@ struct rtw_vif {
|
|||
|
||||
struct rtw_regulatory {
|
||||
char alpha2[2];
|
||||
u8 chplan;
|
||||
u8 txpwr_regd;
|
||||
u8 txpwr_regd_2g;
|
||||
u8 txpwr_regd_5g;
|
||||
};
|
||||
|
||||
enum rtw_regd_state {
|
||||
RTW_REGD_STATE_WORLDWIDE,
|
||||
RTW_REGD_STATE_PROGRAMMED,
|
||||
RTW_REGD_STATE_SETTING,
|
||||
|
||||
RTW_REGD_STATE_NR,
|
||||
};
|
||||
|
||||
struct rtw_regd {
|
||||
enum rtw_regd_state state;
|
||||
const struct rtw_regulatory *regulatory;
|
||||
enum nl80211_dfs_regions dfs_region;
|
||||
};
|
||||
|
||||
struct rtw_chip_ops {
|
||||
|
|
@ -839,6 +860,8 @@ struct rtw_chip_ops {
|
|||
struct ieee80211_bss_conf *conf);
|
||||
void (*cfg_csi_rate)(struct rtw_dev *rtwdev, u8 rssi, u8 cur_rate,
|
||||
u8 fixrate_en, u8 *new_rate);
|
||||
void (*adaptivity_init)(struct rtw_dev *rtwdev);
|
||||
void (*adaptivity)(struct rtw_dev *rtwdev);
|
||||
void (*cfo_init)(struct rtw_dev *rtwdev);
|
||||
void (*cfo_track)(struct rtw_dev *rtwdev);
|
||||
void (*config_tx_path)(struct rtw_dev *rtwdev, u8 tx_path,
|
||||
|
|
@ -1194,6 +1217,10 @@ struct rtw_chip_info {
|
|||
u8 bfer_su_max_num;
|
||||
u8 bfer_mu_max_num;
|
||||
|
||||
struct rtw_hw_reg_offset *edcca_th;
|
||||
s8 l2h_th_ini_cs;
|
||||
s8 l2h_th_ini_ad;
|
||||
|
||||
const char *wow_fw_name;
|
||||
const struct wiphy_wowlan_support *wowlan_stub;
|
||||
const u8 max_sched_scan_ssids;
|
||||
|
|
@ -1542,6 +1569,20 @@ struct rtw_gapk_info {
|
|||
u8 channel;
|
||||
};
|
||||
|
||||
#define EDCCA_TH_L2H_IDX 0
|
||||
#define EDCCA_TH_H2L_IDX 1
|
||||
#define EDCCA_TH_L2H_LB 48
|
||||
#define EDCCA_ADC_BACKOFF 12
|
||||
#define EDCCA_IGI_BASE 50
|
||||
#define EDCCA_IGI_L2H_DIFF 8
|
||||
#define EDCCA_L2H_H2L_DIFF 7
|
||||
#define EDCCA_L2H_H2L_DIFF_NORMAL 8
|
||||
|
||||
enum rtw_edcca_mode {
|
||||
RTW_EDCCA_NORMAL = 0,
|
||||
RTW_EDCCA_ADAPTIVITY = 1,
|
||||
};
|
||||
|
||||
struct rtw_cfo_track {
|
||||
bool is_adjust;
|
||||
u8 crystal_cap;
|
||||
|
|
@ -1633,6 +1674,8 @@ struct rtw_dm_info {
|
|||
struct rtw_gapk_info gapk;
|
||||
bool is_bt_iqk_timeout;
|
||||
|
||||
s8 l2h_th_ini;
|
||||
enum rtw_edcca_mode edcca_mode;
|
||||
u8 scan_density;
|
||||
};
|
||||
|
||||
|
|
@ -1833,7 +1876,7 @@ struct rtw_dev {
|
|||
struct rtw_efuse efuse;
|
||||
struct rtw_sec_desc sec;
|
||||
struct rtw_traffic_stats stats;
|
||||
struct rtw_regulatory regd;
|
||||
struct rtw_regd regd;
|
||||
struct rtw_bf_info bf_info;
|
||||
|
||||
struct rtw_dm_info dm_info;
|
||||
|
|
|
|||
|
|
@ -9,6 +9,7 @@
|
|||
#include "fw.h"
|
||||
#include "phy.h"
|
||||
#include "debug.h"
|
||||
#include "regd.h"
|
||||
|
||||
struct phy_cfg_pair {
|
||||
u32 addr;
|
||||
|
|
@ -119,6 +120,63 @@ static void rtw_phy_cck_pd_init(struct rtw_dev *rtwdev)
|
|||
dm_info->cck_fa_avg = CCK_FA_AVG_RESET;
|
||||
}
|
||||
|
||||
void rtw_phy_set_edcca_th(struct rtw_dev *rtwdev, u8 l2h, u8 h2l)
|
||||
{
|
||||
struct rtw_hw_reg_offset *edcca_th = rtwdev->chip->edcca_th;
|
||||
|
||||
rtw_write32_mask(rtwdev,
|
||||
edcca_th[EDCCA_TH_L2H_IDX].hw_reg.addr,
|
||||
edcca_th[EDCCA_TH_L2H_IDX].hw_reg.mask,
|
||||
l2h + edcca_th[EDCCA_TH_L2H_IDX].offset);
|
||||
rtw_write32_mask(rtwdev,
|
||||
edcca_th[EDCCA_TH_H2L_IDX].hw_reg.addr,
|
||||
edcca_th[EDCCA_TH_H2L_IDX].hw_reg.mask,
|
||||
h2l + edcca_th[EDCCA_TH_H2L_IDX].offset);
|
||||
}
|
||||
EXPORT_SYMBOL(rtw_phy_set_edcca_th);
|
||||
|
||||
void rtw_phy_adaptivity_set_mode(struct rtw_dev *rtwdev)
|
||||
{
|
||||
struct rtw_chip_info *chip = rtwdev->chip;
|
||||
struct rtw_dm_info *dm_info = &rtwdev->dm_info;
|
||||
|
||||
/* turn off in debugfs for debug usage */
|
||||
if (!rtw_edcca_enabled) {
|
||||
dm_info->edcca_mode = RTW_EDCCA_NORMAL;
|
||||
rtw_dbg(rtwdev, RTW_DBG_PHY, "EDCCA disabled, cannot be set\n");
|
||||
return;
|
||||
}
|
||||
|
||||
switch (rtwdev->regd.dfs_region) {
|
||||
case NL80211_DFS_ETSI:
|
||||
dm_info->edcca_mode = RTW_EDCCA_ADAPTIVITY;
|
||||
dm_info->l2h_th_ini = chip->l2h_th_ini_ad;
|
||||
break;
|
||||
case NL80211_DFS_JP:
|
||||
dm_info->edcca_mode = RTW_EDCCA_ADAPTIVITY;
|
||||
dm_info->l2h_th_ini = chip->l2h_th_ini_cs;
|
||||
break;
|
||||
default:
|
||||
dm_info->edcca_mode = RTW_EDCCA_NORMAL;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static void rtw_phy_adaptivity_init(struct rtw_dev *rtwdev)
|
||||
{
|
||||
struct rtw_chip_info *chip = rtwdev->chip;
|
||||
|
||||
rtw_phy_adaptivity_set_mode(rtwdev);
|
||||
if (chip->ops->adaptivity_init)
|
||||
chip->ops->adaptivity_init(rtwdev);
|
||||
}
|
||||
|
||||
static void rtw_phy_adaptivity(struct rtw_dev *rtwdev)
|
||||
{
|
||||
if (rtwdev->chip->ops->adaptivity)
|
||||
rtwdev->chip->ops->adaptivity(rtwdev);
|
||||
}
|
||||
|
||||
static void rtw_phy_cfo_init(struct rtw_dev *rtwdev)
|
||||
{
|
||||
struct rtw_chip_info *chip = rtwdev->chip;
|
||||
|
|
@ -159,6 +217,7 @@ void rtw_phy_init(struct rtw_dev *rtwdev)
|
|||
rtw_phy_cck_pd_init(rtwdev);
|
||||
|
||||
dm_info->iqk.done = false;
|
||||
rtw_phy_adaptivity_init(rtwdev);
|
||||
rtw_phy_cfo_init(rtwdev);
|
||||
rtw_phy_tx_path_div_init(rtwdev);
|
||||
}
|
||||
|
|
@ -711,6 +770,11 @@ void rtw_phy_dynamic_mechanism(struct rtw_dev *rtwdev)
|
|||
rtw_phy_cfo_track(rtwdev);
|
||||
rtw_phy_dpk_track(rtwdev);
|
||||
rtw_phy_pwr_track(rtwdev);
|
||||
|
||||
if (rtw_fw_feature_check(&rtwdev->fw, FW_FEATURE_ADAPTIVITY))
|
||||
rtw_fw_adaptivity(rtwdev);
|
||||
else
|
||||
rtw_phy_adaptivity(rtwdev);
|
||||
}
|
||||
|
||||
#define FRAC_BITS 3
|
||||
|
|
@ -1564,17 +1628,70 @@ static void rtw_xref_txpwr_lmt(struct rtw_dev *rtwdev)
|
|||
rtw_xref_txpwr_lmt_by_bw(rtwdev, regd);
|
||||
}
|
||||
|
||||
static void
|
||||
__cfg_txpwr_lmt_by_alt(struct rtw_hal *hal, u8 regd, u8 regd_alt, u8 bw, u8 rs)
|
||||
{
|
||||
u8 ch;
|
||||
|
||||
for (ch = 0; ch < RTW_MAX_CHANNEL_NUM_2G; ch++)
|
||||
hal->tx_pwr_limit_2g[regd][bw][rs][ch] =
|
||||
hal->tx_pwr_limit_2g[regd_alt][bw][rs][ch];
|
||||
|
||||
for (ch = 0; ch < RTW_MAX_CHANNEL_NUM_5G; ch++)
|
||||
hal->tx_pwr_limit_5g[regd][bw][rs][ch] =
|
||||
hal->tx_pwr_limit_5g[regd_alt][bw][rs][ch];
|
||||
}
|
||||
|
||||
static void
|
||||
rtw_cfg_txpwr_lmt_by_alt(struct rtw_dev *rtwdev, u8 regd, u8 regd_alt)
|
||||
{
|
||||
u8 bw, rs;
|
||||
|
||||
for (bw = 0; bw < RTW_CHANNEL_WIDTH_MAX; bw++)
|
||||
for (rs = 0; rs < RTW_RATE_SECTION_MAX; rs++)
|
||||
__cfg_txpwr_lmt_by_alt(&rtwdev->hal, regd, regd_alt,
|
||||
bw, rs);
|
||||
}
|
||||
|
||||
void rtw_parse_tbl_txpwr_lmt(struct rtw_dev *rtwdev,
|
||||
const struct rtw_table *tbl)
|
||||
{
|
||||
const struct rtw_txpwr_lmt_cfg_pair *p = tbl->data;
|
||||
const struct rtw_txpwr_lmt_cfg_pair *end = p + tbl->size;
|
||||
u32 regd_cfg_flag = 0;
|
||||
u8 regd_alt;
|
||||
u8 i;
|
||||
|
||||
for (; p < end; p++) {
|
||||
regd_cfg_flag |= BIT(p->regd);
|
||||
rtw_phy_set_tx_power_limit(rtwdev, p->regd, p->band,
|
||||
p->bw, p->rs, p->ch, p->txpwr_lmt);
|
||||
}
|
||||
|
||||
for (i = 0; i < RTW_REGD_MAX; i++) {
|
||||
if (i == RTW_REGD_WW)
|
||||
continue;
|
||||
|
||||
if (regd_cfg_flag & BIT(i))
|
||||
continue;
|
||||
|
||||
rtw_dbg(rtwdev, RTW_DBG_REGD,
|
||||
"txpwr regd %d does not be configured\n", i);
|
||||
|
||||
if (rtw_regd_has_alt(i, ®d_alt) &&
|
||||
regd_cfg_flag & BIT(regd_alt)) {
|
||||
rtw_dbg(rtwdev, RTW_DBG_REGD,
|
||||
"cfg txpwr regd %d by regd %d as alternative\n",
|
||||
i, regd_alt);
|
||||
|
||||
rtw_cfg_txpwr_lmt_by_alt(rtwdev, i, regd_alt);
|
||||
continue;
|
||||
}
|
||||
|
||||
rtw_dbg(rtwdev, RTW_DBG_REGD, "cfg txpwr regd %d by WW\n", i);
|
||||
rtw_cfg_txpwr_lmt_by_alt(rtwdev, i, RTW_REGD_WW);
|
||||
}
|
||||
|
||||
rtw_xref_txpwr_lmt(rtwdev);
|
||||
}
|
||||
EXPORT_SYMBOL(rtw_parse_tbl_txpwr_lmt);
|
||||
|
|
@ -2014,7 +2131,7 @@ static void rtw_phy_set_tx_power_index_by_rs(struct rtw_dev *rtwdev,
|
|||
u8 ch, u8 path, u8 rs)
|
||||
{
|
||||
struct rtw_hal *hal = &rtwdev->hal;
|
||||
u8 regd = rtwdev->regd.txpwr_regd;
|
||||
u8 regd = rtw_regd_get(rtwdev);
|
||||
u8 *rates;
|
||||
u8 size;
|
||||
u8 rate;
|
||||
|
|
|
|||
|
|
@ -59,6 +59,8 @@ bool rtw_phy_pwrtrack_need_lck(struct rtw_dev *rtwdev);
|
|||
bool rtw_phy_pwrtrack_need_iqk(struct rtw_dev *rtwdev);
|
||||
void rtw_phy_config_swing_table(struct rtw_dev *rtwdev,
|
||||
struct rtw_swing_table *swing_table);
|
||||
void rtw_phy_set_edcca_th(struct rtw_dev *rtwdev, u8 l2h, u8 h2l);
|
||||
void rtw_phy_adaptivity_set_mode(struct rtw_dev *rtwdev);
|
||||
void rtw_phy_parsing_cfo(struct rtw_dev *rtwdev,
|
||||
struct rtw_rx_pkt_stat *pkt_stat);
|
||||
void rtw_phy_tx_path_diversity(struct rtw_dev *rtwdev);
|
||||
|
|
|
|||
|
|
@ -361,10 +361,12 @@
|
|||
#define REG_AGGR_BREAK_TIME 0x051A
|
||||
#define REG_SLOT 0x051B
|
||||
#define REG_TX_PTCL_CTRL 0x0520
|
||||
#define BIT_DIS_EDCCA BIT(15)
|
||||
#define BIT_SIFS_BK_EN BIT(12)
|
||||
#define REG_TXPAUSE 0x0522
|
||||
#define BIT_AC_QUEUE GENMASK(7, 0)
|
||||
#define REG_RD_CTRL 0x0524
|
||||
#define BIT_EDCCA_MSK_CNTDOWN_EN BIT(11)
|
||||
#define BIT_DIS_TXOP_CFE BIT(10)
|
||||
#define BIT_DIS_LSIG_CFE BIT(9)
|
||||
#define BIT_DIS_STBC_CFE BIT(8)
|
||||
|
|
@ -406,6 +408,7 @@
|
|||
#define BIT_MFBEN BIT(22)
|
||||
#define BIT_DISCHKPPDLLEN BIT(21)
|
||||
#define BIT_PKTCTL_DLEN BIT(20)
|
||||
#define BIT_DISGCLK BIT(19)
|
||||
#define BIT_TIM_PARSER_EN BIT(18)
|
||||
#define BIT_BC_MD_EN BIT(17)
|
||||
#define BIT_UC_MD_EN BIT(16)
|
||||
|
|
@ -640,6 +643,9 @@
|
|||
|
||||
#define REG_HRCV_MSG 0x1cf
|
||||
|
||||
#define REG_EDCCA_REPORT 0x2d38
|
||||
#define BIT_EDCCA_FLAG BIT(24)
|
||||
|
||||
#define REG_IGN_GNTBT4 0x4160
|
||||
|
||||
#define RF_MODE 0x00
|
||||
|
|
|
|||
|
|
@ -7,288 +7,274 @@
|
|||
#include "debug.h"
|
||||
#include "phy.h"
|
||||
|
||||
#define COUNTRY_CHPLAN_ENT(_alpha2, _chplan, _txpwr_regd) \
|
||||
#define COUNTRY_REGD_ENT(_alpha2, _regd_2g, _regd_5g) \
|
||||
{.alpha2 = (_alpha2), \
|
||||
.chplan = (_chplan), \
|
||||
.txpwr_regd = (_txpwr_regd) \
|
||||
.txpwr_regd_2g = (_regd_2g), \
|
||||
.txpwr_regd_5g = (_regd_5g), \
|
||||
}
|
||||
|
||||
#define rtw_dbg_regd_dump(_dev, _msg, _args...) \
|
||||
do { \
|
||||
struct rtw_dev *__d = (_dev); \
|
||||
const struct rtw_regd *__r = &__d->regd; \
|
||||
rtw_dbg(__d, RTW_DBG_REGD, _msg \
|
||||
"apply alpha2 %c%c, regd {%d, %d}, dfs_region %d\n",\
|
||||
##_args, \
|
||||
__r->regulatory->alpha2[0], \
|
||||
__r->regulatory->alpha2[1], \
|
||||
__r->regulatory->txpwr_regd_2g, \
|
||||
__r->regulatory->txpwr_regd_5g, \
|
||||
__r->dfs_region); \
|
||||
} while (0)
|
||||
|
||||
/* If country code is not correctly defined in efuse,
|
||||
* use worldwide country code and txpwr regd.
|
||||
*/
|
||||
static const struct rtw_regulatory rtw_defined_chplan =
|
||||
COUNTRY_CHPLAN_ENT("00", RTW_CHPLAN_REALTEK_DEFINE, RTW_REGD_WW);
|
||||
static const struct rtw_regulatory rtw_reg_ww =
|
||||
COUNTRY_REGD_ENT("00", RTW_REGD_WW, RTW_REGD_WW);
|
||||
|
||||
static const struct rtw_regulatory all_chplan_map[] = {
|
||||
COUNTRY_CHPLAN_ENT("AD", RTW_CHPLAN_WORLD_ETSI1, RTW_REGD_ETSI),
|
||||
COUNTRY_CHPLAN_ENT("AE", RTW_CHPLAN_WORLD_ETSI2, RTW_REGD_ETSI),
|
||||
COUNTRY_CHPLAN_ENT("AF", RTW_CHPLAN_ETSI1_ETSI4, RTW_REGD_ETSI),
|
||||
COUNTRY_CHPLAN_ENT("AG", RTW_CHPLAN_FCC2_FCC11, RTW_REGD_FCC),
|
||||
COUNTRY_CHPLAN_ENT("AI", RTW_CHPLAN_WORLD_ETSI1, RTW_REGD_ETSI),
|
||||
COUNTRY_CHPLAN_ENT("AL", RTW_CHPLAN_WORLD_ETSI1, RTW_REGD_ETSI),
|
||||
COUNTRY_CHPLAN_ENT("AM", RTW_CHPLAN_WORLD_ETSI1, RTW_REGD_ETSI),
|
||||
COUNTRY_CHPLAN_ENT("AN", RTW_CHPLAN_FCC2_FCC11, RTW_REGD_FCC),
|
||||
COUNTRY_CHPLAN_ENT("AO", RTW_CHPLAN_WORLD_ETSI6, RTW_REGD_ETSI),
|
||||
COUNTRY_CHPLAN_ENT("AQ", RTW_CHPLAN_WORLD_ETSI1, RTW_REGD_ETSI),
|
||||
COUNTRY_CHPLAN_ENT("AR", RTW_CHPLAN_FCC2_FCC7, RTW_REGD_FCC),
|
||||
COUNTRY_CHPLAN_ENT("AS", RTW_CHPLAN_FCC2_FCC11, RTW_REGD_FCC),
|
||||
COUNTRY_CHPLAN_ENT("AT", RTW_CHPLAN_WORLD_ETSI1, RTW_REGD_ETSI),
|
||||
COUNTRY_CHPLAN_ENT("AU", RTW_CHPLAN_WORLD_ACMA1, RTW_REGD_ACMA),
|
||||
COUNTRY_CHPLAN_ENT("AW", RTW_CHPLAN_FCC2_FCC11, RTW_REGD_FCC),
|
||||
COUNTRY_CHPLAN_ENT("AZ", RTW_CHPLAN_WORLD_ETSI1, RTW_REGD_ETSI),
|
||||
COUNTRY_CHPLAN_ENT("BA", RTW_CHPLAN_WORLD_ETSI1, RTW_REGD_ETSI),
|
||||
COUNTRY_CHPLAN_ENT("BB", RTW_CHPLAN_FCC2_FCC11, RTW_REGD_FCC),
|
||||
COUNTRY_CHPLAN_ENT("BD", RTW_CHPLAN_WORLD_ETSI1, RTW_REGD_ETSI),
|
||||
COUNTRY_CHPLAN_ENT("BE", RTW_CHPLAN_WORLD_ETSI1, RTW_REGD_ETSI),
|
||||
COUNTRY_CHPLAN_ENT("BF", RTW_CHPLAN_WORLD_ETSI1, RTW_REGD_ETSI),
|
||||
COUNTRY_CHPLAN_ENT("BG", RTW_CHPLAN_WORLD_ETSI1, RTW_REGD_ETSI),
|
||||
COUNTRY_CHPLAN_ENT("BH", RTW_CHPLAN_WORLD_ETSI7, RTW_REGD_ETSI),
|
||||
COUNTRY_CHPLAN_ENT("BI", RTW_CHPLAN_WORLD_ETSI1, RTW_REGD_ETSI),
|
||||
COUNTRY_CHPLAN_ENT("BJ", RTW_CHPLAN_WORLD_ETSI1, RTW_REGD_ETSI),
|
||||
COUNTRY_CHPLAN_ENT("BM", RTW_CHPLAN_FCC2_FCC11, RTW_REGD_FCC),
|
||||
COUNTRY_CHPLAN_ENT("BN", RTW_CHPLAN_WORLD_ETSI6, RTW_REGD_ETSI),
|
||||
COUNTRY_CHPLAN_ENT("BO", RTW_CHPLAN_WORLD_FCC7, RTW_REGD_FCC),
|
||||
COUNTRY_CHPLAN_ENT("BR", RTW_CHPLAN_FCC2_FCC1, RTW_REGD_FCC),
|
||||
COUNTRY_CHPLAN_ENT("BS", RTW_CHPLAN_FCC2_FCC11, RTW_REGD_FCC),
|
||||
COUNTRY_CHPLAN_ENT("BT", RTW_CHPLAN_WORLD_ETSI1, RTW_REGD_ETSI),
|
||||
COUNTRY_CHPLAN_ENT("BV", RTW_CHPLAN_WORLD_ETSI1, RTW_REGD_ETSI),
|
||||
COUNTRY_CHPLAN_ENT("BW", RTW_CHPLAN_WORLD_ETSI2, RTW_REGD_ETSI),
|
||||
COUNTRY_CHPLAN_ENT("BY", RTW_CHPLAN_WORLD_ETSI1, RTW_REGD_ETSI),
|
||||
COUNTRY_CHPLAN_ENT("BZ", RTW_CHPLAN_FCC2_FCC11, RTW_REGD_FCC),
|
||||
COUNTRY_CHPLAN_ENT("CA", RTW_CHPLAN_IC1_IC2, RTW_REGD_IC),
|
||||
COUNTRY_CHPLAN_ENT("CC", RTW_CHPLAN_WORLD_ETSI1, RTW_REGD_ETSI),
|
||||
COUNTRY_CHPLAN_ENT("CD", RTW_CHPLAN_WORLD_ETSI1, RTW_REGD_ETSI),
|
||||
COUNTRY_CHPLAN_ENT("CF", RTW_CHPLAN_WORLD_ETSI1, RTW_REGD_ETSI),
|
||||
COUNTRY_CHPLAN_ENT("CG", RTW_CHPLAN_WORLD_ETSI1, RTW_REGD_ETSI),
|
||||
COUNTRY_CHPLAN_ENT("CH", RTW_CHPLAN_WORLD_ETSI1, RTW_REGD_ETSI),
|
||||
COUNTRY_CHPLAN_ENT("CI", RTW_CHPLAN_ETSI1_ETSI4, RTW_REGD_ETSI),
|
||||
COUNTRY_CHPLAN_ENT("CK", RTW_CHPLAN_WORLD_ETSI1, RTW_REGD_ETSI),
|
||||
COUNTRY_CHPLAN_ENT("CL", RTW_CHPLAN_WORLD_CHILE1, RTW_REGD_CHILE),
|
||||
COUNTRY_CHPLAN_ENT("CM", RTW_CHPLAN_WORLD_ETSI1, RTW_REGD_ETSI),
|
||||
COUNTRY_CHPLAN_ENT("CN", RTW_CHPLAN_WORLD_ETSI7, RTW_REGD_ETSI),
|
||||
COUNTRY_CHPLAN_ENT("CO", RTW_CHPLAN_FCC2_FCC11, RTW_REGD_FCC),
|
||||
COUNTRY_CHPLAN_ENT("CR", RTW_CHPLAN_FCC2_FCC11, RTW_REGD_FCC),
|
||||
COUNTRY_CHPLAN_ENT("CV", RTW_CHPLAN_WORLD_ETSI1, RTW_REGD_ETSI),
|
||||
COUNTRY_CHPLAN_ENT("CX", RTW_CHPLAN_WORLD_ACMA1, RTW_REGD_ACMA),
|
||||
COUNTRY_CHPLAN_ENT("CY", RTW_CHPLAN_WORLD_ETSI1, RTW_REGD_ETSI),
|
||||
COUNTRY_CHPLAN_ENT("CZ", RTW_CHPLAN_WORLD_ETSI1, RTW_REGD_ETSI),
|
||||
COUNTRY_CHPLAN_ENT("DE", RTW_CHPLAN_WORLD_ETSI1, RTW_REGD_ETSI),
|
||||
COUNTRY_CHPLAN_ENT("DJ", RTW_CHPLAN_WORLD_ETSI1, RTW_REGD_ETSI),
|
||||
COUNTRY_CHPLAN_ENT("DK", RTW_CHPLAN_WORLD_ETSI1, RTW_REGD_ETSI),
|
||||
COUNTRY_CHPLAN_ENT("DM", RTW_CHPLAN_FCC2_FCC11, RTW_REGD_FCC),
|
||||
COUNTRY_CHPLAN_ENT("DO", RTW_CHPLAN_FCC2_FCC11, RTW_REGD_FCC),
|
||||
COUNTRY_CHPLAN_ENT("DZ", RTW_CHPLAN_WORLD_ETSI1, RTW_REGD_ETSI),
|
||||
COUNTRY_CHPLAN_ENT("EC", RTW_CHPLAN_FCC2_FCC11, RTW_REGD_FCC),
|
||||
COUNTRY_CHPLAN_ENT("EE", RTW_CHPLAN_WORLD_ETSI1, RTW_REGD_ETSI),
|
||||
COUNTRY_CHPLAN_ENT("EG", RTW_CHPLAN_WORLD_ETSI6, RTW_REGD_ETSI),
|
||||
COUNTRY_CHPLAN_ENT("EH", RTW_CHPLAN_WORLD_ETSI6, RTW_REGD_ETSI),
|
||||
COUNTRY_CHPLAN_ENT("ER", RTW_CHPLAN_WORLD_ETSI1, RTW_REGD_ETSI),
|
||||
COUNTRY_CHPLAN_ENT("ES", RTW_CHPLAN_WORLD_ETSI1, RTW_REGD_ETSI),
|
||||
COUNTRY_CHPLAN_ENT("ET", RTW_CHPLAN_WORLD_ETSI1, RTW_REGD_ETSI),
|
||||
COUNTRY_CHPLAN_ENT("FI", RTW_CHPLAN_WORLD_ETSI1, RTW_REGD_ETSI),
|
||||
COUNTRY_CHPLAN_ENT("FJ", RTW_CHPLAN_FCC2_FCC11, RTW_REGD_FCC),
|
||||
COUNTRY_CHPLAN_ENT("FK", RTW_CHPLAN_WORLD_ETSI1, RTW_REGD_ETSI),
|
||||
COUNTRY_CHPLAN_ENT("FM", RTW_CHPLAN_FCC2_FCC11, RTW_REGD_FCC),
|
||||
COUNTRY_CHPLAN_ENT("FO", RTW_CHPLAN_WORLD_ETSI1, RTW_REGD_ETSI),
|
||||
COUNTRY_CHPLAN_ENT("FR", RTW_CHPLAN_WORLD_ETSI1, RTW_REGD_ETSI),
|
||||
COUNTRY_CHPLAN_ENT("GA", RTW_CHPLAN_WORLD_ETSI1, RTW_REGD_ETSI),
|
||||
COUNTRY_CHPLAN_ENT("GB", RTW_CHPLAN_WORLD_ETSI1, RTW_REGD_ETSI),
|
||||
COUNTRY_CHPLAN_ENT("GD", RTW_CHPLAN_FCC2_FCC11, RTW_REGD_FCC),
|
||||
COUNTRY_CHPLAN_ENT("GE", RTW_CHPLAN_WORLD_ETSI1, RTW_REGD_ETSI),
|
||||
COUNTRY_CHPLAN_ENT("GF", RTW_CHPLAN_WORLD_ETSI1, RTW_REGD_ETSI),
|
||||
COUNTRY_CHPLAN_ENT("GG", RTW_CHPLAN_WORLD_ETSI1, RTW_REGD_ETSI),
|
||||
COUNTRY_CHPLAN_ENT("GH", RTW_CHPLAN_WORLD_ETSI1, RTW_REGD_ETSI),
|
||||
COUNTRY_CHPLAN_ENT("GI", RTW_CHPLAN_WORLD_ETSI1, RTW_REGD_ETSI),
|
||||
COUNTRY_CHPLAN_ENT("GL", RTW_CHPLAN_WORLD_ETSI1, RTW_REGD_ETSI),
|
||||
COUNTRY_CHPLAN_ENT("GM", RTW_CHPLAN_WORLD_ETSI1, RTW_REGD_ETSI),
|
||||
COUNTRY_CHPLAN_ENT("GN", RTW_CHPLAN_WORLD_ETSI1, RTW_REGD_ETSI),
|
||||
COUNTRY_CHPLAN_ENT("GP", RTW_CHPLAN_WORLD_ETSI1, RTW_REGD_ETSI),
|
||||
COUNTRY_CHPLAN_ENT("GQ", RTW_CHPLAN_WORLD_ETSI1, RTW_REGD_ETSI),
|
||||
COUNTRY_CHPLAN_ENT("GR", RTW_CHPLAN_WORLD_ETSI1, RTW_REGD_ETSI),
|
||||
COUNTRY_CHPLAN_ENT("GS", RTW_CHPLAN_WORLD_ETSI1, RTW_REGD_ETSI),
|
||||
COUNTRY_CHPLAN_ENT("GT", RTW_CHPLAN_FCC2_FCC7, RTW_REGD_FCC),
|
||||
COUNTRY_CHPLAN_ENT("GU", RTW_CHPLAN_FCC2_FCC11, RTW_REGD_FCC),
|
||||
COUNTRY_CHPLAN_ENT("GW", RTW_CHPLAN_WORLD_ETSI1, RTW_REGD_ETSI),
|
||||
COUNTRY_CHPLAN_ENT("GY", RTW_CHPLAN_FCC1_NCC3, RTW_REGD_FCC),
|
||||
COUNTRY_CHPLAN_ENT("HK", RTW_CHPLAN_WORLD_ETSI2, RTW_REGD_ETSI),
|
||||
COUNTRY_CHPLAN_ENT("HM", RTW_CHPLAN_WORLD_ACMA1, RTW_REGD_ACMA),
|
||||
COUNTRY_CHPLAN_ENT("HN", RTW_CHPLAN_WORLD_FCC5, RTW_REGD_FCC),
|
||||
COUNTRY_CHPLAN_ENT("HR", RTW_CHPLAN_WORLD_ETSI1, RTW_REGD_ETSI),
|
||||
COUNTRY_CHPLAN_ENT("HT", RTW_CHPLAN_FCC2_FCC11, RTW_REGD_FCC),
|
||||
COUNTRY_CHPLAN_ENT("HU", RTW_CHPLAN_WORLD_ETSI1, RTW_REGD_ETSI),
|
||||
COUNTRY_CHPLAN_ENT("ID", RTW_CHPLAN_ETSI1_ETSI12, RTW_REGD_ETSI),
|
||||
COUNTRY_CHPLAN_ENT("IE", RTW_CHPLAN_WORLD_ETSI1, RTW_REGD_ETSI),
|
||||
COUNTRY_CHPLAN_ENT("IL", RTW_CHPLAN_WORLD_ETSI6, RTW_REGD_ETSI),
|
||||
COUNTRY_CHPLAN_ENT("IM", RTW_CHPLAN_WORLD_ETSI1, RTW_REGD_ETSI),
|
||||
COUNTRY_CHPLAN_ENT("IN", RTW_CHPLAN_WORLD_ETSI7, RTW_REGD_ETSI),
|
||||
COUNTRY_CHPLAN_ENT("IO", RTW_CHPLAN_WORLD_ETSI1, RTW_REGD_ETSI),
|
||||
COUNTRY_CHPLAN_ENT("IQ", RTW_CHPLAN_WORLD_ETSI1, RTW_REGD_ETSI),
|
||||
COUNTRY_CHPLAN_ENT("IR", RTW_CHPLAN_WORLD_ETSI1, RTW_REGD_ETSI),
|
||||
COUNTRY_CHPLAN_ENT("IS", RTW_CHPLAN_WORLD_ETSI1, RTW_REGD_ETSI),
|
||||
COUNTRY_CHPLAN_ENT("IT", RTW_CHPLAN_WORLD_ETSI1, RTW_REGD_ETSI),
|
||||
COUNTRY_CHPLAN_ENT("JE", RTW_CHPLAN_WORLD_ETSI1, RTW_REGD_ETSI),
|
||||
COUNTRY_CHPLAN_ENT("JM", RTW_CHPLAN_WORLD_FCC5, RTW_REGD_FCC),
|
||||
COUNTRY_CHPLAN_ENT("JO", RTW_CHPLAN_WORLD_ETSI8, RTW_REGD_ETSI),
|
||||
COUNTRY_CHPLAN_ENT("JP", RTW_CHPLAN_MKK1_MKK1, RTW_REGD_MKK),
|
||||
COUNTRY_CHPLAN_ENT("KE", RTW_CHPLAN_WORLD_ETSI6, RTW_REGD_ETSI),
|
||||
COUNTRY_CHPLAN_ENT("KG", RTW_CHPLAN_WORLD_ETSI1, RTW_REGD_ETSI),
|
||||
COUNTRY_CHPLAN_ENT("KH", RTW_CHPLAN_WORLD_ETSI1, RTW_REGD_ETSI),
|
||||
COUNTRY_CHPLAN_ENT("KI", RTW_CHPLAN_WORLD_ETSI1, RTW_REGD_ETSI),
|
||||
COUNTRY_CHPLAN_ENT("KM", RTW_CHPLAN_WORLD_ETSI1, RTW_REGD_ETSI),
|
||||
COUNTRY_CHPLAN_ENT("KN", RTW_CHPLAN_FCC2_FCC11, RTW_REGD_FCC),
|
||||
COUNTRY_CHPLAN_ENT("KR", RTW_CHPLAN_KCC1_KCC3, RTW_REGD_KCC),
|
||||
COUNTRY_CHPLAN_ENT("KW", RTW_CHPLAN_WORLD_ETSI6, RTW_REGD_ETSI),
|
||||
COUNTRY_CHPLAN_ENT("KY", RTW_CHPLAN_FCC2_FCC11, RTW_REGD_FCC),
|
||||
COUNTRY_CHPLAN_ENT("KZ", RTW_CHPLAN_WORLD_ETSI1, RTW_REGD_ETSI),
|
||||
COUNTRY_CHPLAN_ENT("LA", RTW_CHPLAN_WORLD_ETSI1, RTW_REGD_ETSI),
|
||||
COUNTRY_CHPLAN_ENT("LB", RTW_CHPLAN_WORLD_ETSI1, RTW_REGD_ETSI),
|
||||
COUNTRY_CHPLAN_ENT("LC", RTW_CHPLAN_FCC2_FCC11, RTW_REGD_FCC),
|
||||
COUNTRY_CHPLAN_ENT("LI", RTW_CHPLAN_WORLD_ETSI1, RTW_REGD_ETSI),
|
||||
COUNTRY_CHPLAN_ENT("LK", RTW_CHPLAN_WORLD_ETSI1, RTW_REGD_ETSI),
|
||||
COUNTRY_CHPLAN_ENT("LR", RTW_CHPLAN_WORLD_ETSI1, RTW_REGD_ETSI),
|
||||
COUNTRY_CHPLAN_ENT("LS", RTW_CHPLAN_WORLD_ETSI1, RTW_REGD_ETSI),
|
||||
COUNTRY_CHPLAN_ENT("LT", RTW_CHPLAN_WORLD_ETSI1, RTW_REGD_ETSI),
|
||||
COUNTRY_CHPLAN_ENT("LU", RTW_CHPLAN_WORLD_ETSI1, RTW_REGD_ETSI),
|
||||
COUNTRY_CHPLAN_ENT("LV", RTW_CHPLAN_WORLD_ETSI1, RTW_REGD_ETSI),
|
||||
COUNTRY_CHPLAN_ENT("LY", RTW_CHPLAN_WORLD_ETSI1, RTW_REGD_ETSI),
|
||||
COUNTRY_CHPLAN_ENT("MA", RTW_CHPLAN_WORLD_ETSI6, RTW_REGD_ETSI),
|
||||
COUNTRY_CHPLAN_ENT("MC", RTW_CHPLAN_WORLD_ETSI1, RTW_REGD_ETSI),
|
||||
COUNTRY_CHPLAN_ENT("MD", RTW_CHPLAN_WORLD_ETSI1, RTW_REGD_ETSI),
|
||||
COUNTRY_CHPLAN_ENT("ME", RTW_CHPLAN_WORLD_ETSI1, RTW_REGD_ETSI),
|
||||
COUNTRY_CHPLAN_ENT("MF", RTW_CHPLAN_FCC2_FCC11, RTW_REGD_FCC),
|
||||
COUNTRY_CHPLAN_ENT("MG", RTW_CHPLAN_WORLD_ETSI1, RTW_REGD_ETSI),
|
||||
COUNTRY_CHPLAN_ENT("MH", RTW_CHPLAN_FCC2_FCC11, RTW_REGD_FCC),
|
||||
COUNTRY_CHPLAN_ENT("MK", RTW_CHPLAN_WORLD_ETSI1, RTW_REGD_ETSI),
|
||||
COUNTRY_CHPLAN_ENT("ML", RTW_CHPLAN_WORLD_ETSI1, RTW_REGD_ETSI),
|
||||
COUNTRY_CHPLAN_ENT("MM", RTW_CHPLAN_WORLD_ETSI1, RTW_REGD_ETSI),
|
||||
COUNTRY_CHPLAN_ENT("MN", RTW_CHPLAN_WORLD_ETSI1, RTW_REGD_ETSI),
|
||||
COUNTRY_CHPLAN_ENT("MO", RTW_CHPLAN_WORLD_ETSI2, RTW_REGD_ETSI),
|
||||
COUNTRY_CHPLAN_ENT("MP", RTW_CHPLAN_FCC2_FCC11, RTW_REGD_FCC),
|
||||
COUNTRY_CHPLAN_ENT("MQ", RTW_CHPLAN_WORLD_ETSI1, RTW_REGD_ETSI),
|
||||
COUNTRY_CHPLAN_ENT("MR", RTW_CHPLAN_WORLD_ETSI1, RTW_REGD_ETSI),
|
||||
COUNTRY_CHPLAN_ENT("MS", RTW_CHPLAN_WORLD_ETSI1, RTW_REGD_ETSI),
|
||||
COUNTRY_CHPLAN_ENT("MT", RTW_CHPLAN_WORLD_ETSI1, RTW_REGD_ETSI),
|
||||
COUNTRY_CHPLAN_ENT("MU", RTW_CHPLAN_WORLD_ETSI1, RTW_REGD_ETSI),
|
||||
COUNTRY_CHPLAN_ENT("MV", RTW_CHPLAN_WORLD_ETSI6, RTW_REGD_ETSI),
|
||||
COUNTRY_CHPLAN_ENT("MW", RTW_CHPLAN_WORLD_ETSI1, RTW_REGD_ETSI),
|
||||
COUNTRY_CHPLAN_ENT("MX", RTW_CHPLAN_FCC2_FCC7, RTW_REGD_FCC),
|
||||
COUNTRY_CHPLAN_ENT("MY", RTW_CHPLAN_WORLD_ETSI15, RTW_REGD_ETSI),
|
||||
COUNTRY_CHPLAN_ENT("MZ", RTW_CHPLAN_WORLD_ETSI1, RTW_REGD_ETSI),
|
||||
COUNTRY_CHPLAN_ENT("NA", RTW_CHPLAN_WORLD_ETSI1, RTW_REGD_ETSI),
|
||||
COUNTRY_CHPLAN_ENT("NC", RTW_CHPLAN_WORLD_ETSI1, RTW_REGD_ETSI),
|
||||
COUNTRY_CHPLAN_ENT("NE", RTW_CHPLAN_WORLD_ETSI1, RTW_REGD_ETSI),
|
||||
COUNTRY_CHPLAN_ENT("NF", RTW_CHPLAN_WORLD_ACMA1, RTW_REGD_ACMA),
|
||||
COUNTRY_CHPLAN_ENT("NG", RTW_CHPLAN_WORLD_ETSI20, RTW_REGD_ETSI),
|
||||
COUNTRY_CHPLAN_ENT("NI", RTW_CHPLAN_FCC2_FCC11, RTW_REGD_FCC),
|
||||
COUNTRY_CHPLAN_ENT("NL", RTW_CHPLAN_WORLD_ETSI1, RTW_REGD_ETSI),
|
||||
COUNTRY_CHPLAN_ENT("NO", RTW_CHPLAN_WORLD_ETSI1, RTW_REGD_ETSI),
|
||||
COUNTRY_CHPLAN_ENT("NP", RTW_CHPLAN_WORLD_ETSI7, RTW_REGD_ETSI),
|
||||
COUNTRY_CHPLAN_ENT("NR", RTW_CHPLAN_WORLD_ETSI1, RTW_REGD_ETSI),
|
||||
COUNTRY_CHPLAN_ENT("NU", RTW_CHPLAN_WORLD_ACMA1, RTW_REGD_ACMA),
|
||||
COUNTRY_CHPLAN_ENT("NZ", RTW_CHPLAN_WORLD_ACMA1, RTW_REGD_ACMA),
|
||||
COUNTRY_CHPLAN_ENT("OM", RTW_CHPLAN_WORLD_ETSI1, RTW_REGD_ETSI),
|
||||
COUNTRY_CHPLAN_ENT("PA", RTW_CHPLAN_FCC2_FCC11, RTW_REGD_FCC),
|
||||
COUNTRY_CHPLAN_ENT("PE", RTW_CHPLAN_FCC2_FCC11, RTW_REGD_FCC),
|
||||
COUNTRY_CHPLAN_ENT("PF", RTW_CHPLAN_WORLD_ETSI1, RTW_REGD_ETSI),
|
||||
COUNTRY_CHPLAN_ENT("PG", RTW_CHPLAN_WORLD_ETSI2, RTW_REGD_ETSI),
|
||||
COUNTRY_CHPLAN_ENT("PH", RTW_CHPLAN_WORLD_ETSI2, RTW_REGD_ETSI),
|
||||
COUNTRY_CHPLAN_ENT("PK", RTW_CHPLAN_WORLD_ETSI10, RTW_REGD_ETSI),
|
||||
COUNTRY_CHPLAN_ENT("PL", RTW_CHPLAN_WORLD_ETSI1, RTW_REGD_ETSI),
|
||||
COUNTRY_CHPLAN_ENT("PM", RTW_CHPLAN_WORLD_ETSI1, RTW_REGD_ETSI),
|
||||
COUNTRY_CHPLAN_ENT("PR", RTW_CHPLAN_FCC2_FCC11, RTW_REGD_FCC),
|
||||
COUNTRY_CHPLAN_ENT("PT", RTW_CHPLAN_WORLD_ETSI1, RTW_REGD_ETSI),
|
||||
COUNTRY_CHPLAN_ENT("PW", RTW_CHPLAN_FCC2_FCC11, RTW_REGD_FCC),
|
||||
COUNTRY_CHPLAN_ENT("PY", RTW_CHPLAN_FCC2_FCC11, RTW_REGD_FCC),
|
||||
COUNTRY_CHPLAN_ENT("QA", RTW_CHPLAN_WORLD_ETSI2, RTW_REGD_ETSI),
|
||||
COUNTRY_CHPLAN_ENT("RE", RTW_CHPLAN_WORLD_ETSI1, RTW_REGD_ETSI),
|
||||
COUNTRY_CHPLAN_ENT("RO", RTW_CHPLAN_WORLD_ETSI1, RTW_REGD_ETSI),
|
||||
COUNTRY_CHPLAN_ENT("RS", RTW_CHPLAN_WORLD_ETSI1, RTW_REGD_ETSI),
|
||||
COUNTRY_CHPLAN_ENT("RU", RTW_CHPLAN_WORLD_ETSI14, RTW_REGD_ETSI),
|
||||
COUNTRY_CHPLAN_ENT("RW", RTW_CHPLAN_WORLD_ETSI1, RTW_REGD_ETSI),
|
||||
COUNTRY_CHPLAN_ENT("SA", RTW_CHPLAN_WORLD_ETSI2, RTW_REGD_ETSI),
|
||||
COUNTRY_CHPLAN_ENT("SB", RTW_CHPLAN_WORLD_ETSI1, RTW_REGD_ETSI),
|
||||
COUNTRY_CHPLAN_ENT("SC", RTW_CHPLAN_FCC2_FCC11, RTW_REGD_FCC),
|
||||
COUNTRY_CHPLAN_ENT("SE", RTW_CHPLAN_WORLD_ETSI1, RTW_REGD_ETSI),
|
||||
COUNTRY_CHPLAN_ENT("SG", RTW_CHPLAN_WORLD_ETSI2, RTW_REGD_ETSI),
|
||||
COUNTRY_CHPLAN_ENT("SH", RTW_CHPLAN_WORLD_ETSI1, RTW_REGD_ETSI),
|
||||
COUNTRY_CHPLAN_ENT("SI", RTW_CHPLAN_WORLD_ETSI1, RTW_REGD_ETSI),
|
||||
COUNTRY_CHPLAN_ENT("SJ", RTW_CHPLAN_WORLD_ETSI1, RTW_REGD_ETSI),
|
||||
COUNTRY_CHPLAN_ENT("SK", RTW_CHPLAN_WORLD_ETSI1, RTW_REGD_ETSI),
|
||||
COUNTRY_CHPLAN_ENT("SL", RTW_CHPLAN_WORLD_ETSI1, RTW_REGD_ETSI),
|
||||
COUNTRY_CHPLAN_ENT("SM", RTW_CHPLAN_WORLD_ETSI1, RTW_REGD_ETSI),
|
||||
COUNTRY_CHPLAN_ENT("SN", RTW_CHPLAN_WORLD_ETSI1, RTW_REGD_ETSI),
|
||||
COUNTRY_CHPLAN_ENT("SO", RTW_CHPLAN_WORLD_ETSI1, RTW_REGD_ETSI),
|
||||
COUNTRY_CHPLAN_ENT("SR", RTW_CHPLAN_FCC2_FCC17, RTW_REGD_FCC),
|
||||
COUNTRY_CHPLAN_ENT("ST", RTW_CHPLAN_FCC2_FCC11, RTW_REGD_FCC),
|
||||
COUNTRY_CHPLAN_ENT("SV", RTW_CHPLAN_WORLD_FCC3, RTW_REGD_FCC),
|
||||
COUNTRY_CHPLAN_ENT("SX", RTW_CHPLAN_FCC2_FCC11, RTW_REGD_FCC),
|
||||
COUNTRY_CHPLAN_ENT("SZ", RTW_CHPLAN_WORLD_ETSI1, RTW_REGD_ETSI),
|
||||
COUNTRY_CHPLAN_ENT("TC", RTW_CHPLAN_WORLD_ETSI1, RTW_REGD_ETSI),
|
||||
COUNTRY_CHPLAN_ENT("TD", RTW_CHPLAN_WORLD_ETSI1, RTW_REGD_ETSI),
|
||||
COUNTRY_CHPLAN_ENT("TF", RTW_CHPLAN_WORLD_ETSI1, RTW_REGD_ETSI),
|
||||
COUNTRY_CHPLAN_ENT("TG", RTW_CHPLAN_WORLD_ETSI1, RTW_REGD_ETSI),
|
||||
COUNTRY_CHPLAN_ENT("TH", RTW_CHPLAN_WORLD_ETSI2, RTW_REGD_ETSI),
|
||||
COUNTRY_CHPLAN_ENT("TJ", RTW_CHPLAN_WORLD_ETSI1, RTW_REGD_ETSI),
|
||||
COUNTRY_CHPLAN_ENT("TK", RTW_CHPLAN_WORLD_ACMA1, RTW_REGD_ACMA),
|
||||
COUNTRY_CHPLAN_ENT("TM", RTW_CHPLAN_WORLD_ETSI1, RTW_REGD_ETSI),
|
||||
COUNTRY_CHPLAN_ENT("TN", RTW_CHPLAN_WORLD_ETSI6, RTW_REGD_ETSI),
|
||||
COUNTRY_CHPLAN_ENT("TO", RTW_CHPLAN_WORLD_ETSI1, RTW_REGD_ETSI),
|
||||
COUNTRY_CHPLAN_ENT("TR", RTW_CHPLAN_WORLD_ETSI1, RTW_REGD_ETSI),
|
||||
COUNTRY_CHPLAN_ENT("TT", RTW_CHPLAN_FCC2_FCC11, RTW_REGD_FCC),
|
||||
COUNTRY_CHPLAN_ENT("TV", RTW_CHPLAN_ETSI1_NULL, RTW_REGD_ETSI),
|
||||
COUNTRY_CHPLAN_ENT("TW", RTW_CHPLAN_FCC2_FCC11, RTW_REGD_FCC),
|
||||
COUNTRY_CHPLAN_ENT("TZ", RTW_CHPLAN_WORLD_ETSI1, RTW_REGD_ETSI),
|
||||
COUNTRY_CHPLAN_ENT("UA", RTW_CHPLAN_WORLD_ETSI3, RTW_REGD_ETSI),
|
||||
COUNTRY_CHPLAN_ENT("UG", RTW_CHPLAN_WORLD_ETSI1, RTW_REGD_ETSI),
|
||||
COUNTRY_CHPLAN_ENT("US", RTW_CHPLAN_FCC2_FCC11, RTW_REGD_FCC),
|
||||
COUNTRY_CHPLAN_ENT("UY", RTW_CHPLAN_WORLD_FCC3, RTW_REGD_FCC),
|
||||
COUNTRY_CHPLAN_ENT("UZ", RTW_CHPLAN_WORLD_ETSI6, RTW_REGD_ETSI),
|
||||
COUNTRY_CHPLAN_ENT("VA", RTW_CHPLAN_WORLD_ETSI1, RTW_REGD_ETSI),
|
||||
COUNTRY_CHPLAN_ENT("VC", RTW_CHPLAN_FCC2_FCC11, RTW_REGD_FCC),
|
||||
COUNTRY_CHPLAN_ENT("VE", RTW_CHPLAN_WORLD_FCC3, RTW_REGD_FCC),
|
||||
COUNTRY_CHPLAN_ENT("VG", RTW_CHPLAN_FCC2_FCC11, RTW_REGD_FCC),
|
||||
COUNTRY_CHPLAN_ENT("VI", RTW_CHPLAN_FCC2_FCC11, RTW_REGD_FCC),
|
||||
COUNTRY_CHPLAN_ENT("VN", RTW_CHPLAN_WORLD_ETSI2, RTW_REGD_ETSI),
|
||||
COUNTRY_CHPLAN_ENT("VU", RTW_CHPLAN_WORLD_ETSI1, RTW_REGD_ETSI),
|
||||
COUNTRY_CHPLAN_ENT("WF", RTW_CHPLAN_WORLD_ETSI1, RTW_REGD_ETSI),
|
||||
COUNTRY_CHPLAN_ENT("WS", RTW_CHPLAN_FCC2_FCC11, RTW_REGD_FCC),
|
||||
COUNTRY_CHPLAN_ENT("YE", RTW_CHPLAN_WORLD_ETSI1, RTW_REGD_ETSI),
|
||||
COUNTRY_CHPLAN_ENT("YT", RTW_CHPLAN_WORLD_ETSI1, RTW_REGD_ETSI),
|
||||
COUNTRY_CHPLAN_ENT("ZA", RTW_CHPLAN_WORLD_ETSI2, RTW_REGD_ETSI),
|
||||
COUNTRY_CHPLAN_ENT("ZM", RTW_CHPLAN_WORLD_ETSI1, RTW_REGD_ETSI),
|
||||
COUNTRY_CHPLAN_ENT("ZW", RTW_CHPLAN_WORLD_ETSI1, RTW_REGD_ETSI),
|
||||
static const struct rtw_regulatory rtw_reg_map[] = {
|
||||
COUNTRY_REGD_ENT("AD", RTW_REGD_ETSI, RTW_REGD_ETSI),
|
||||
COUNTRY_REGD_ENT("AE", RTW_REGD_ETSI, RTW_REGD_ETSI),
|
||||
COUNTRY_REGD_ENT("AF", RTW_REGD_ETSI, RTW_REGD_ETSI),
|
||||
COUNTRY_REGD_ENT("AG", RTW_REGD_FCC, RTW_REGD_FCC),
|
||||
COUNTRY_REGD_ENT("AI", RTW_REGD_ETSI, RTW_REGD_ETSI),
|
||||
COUNTRY_REGD_ENT("AL", RTW_REGD_ETSI, RTW_REGD_ETSI),
|
||||
COUNTRY_REGD_ENT("AM", RTW_REGD_ETSI, RTW_REGD_ETSI),
|
||||
COUNTRY_REGD_ENT("AN", RTW_REGD_FCC, RTW_REGD_FCC),
|
||||
COUNTRY_REGD_ENT("AO", RTW_REGD_ETSI, RTW_REGD_ETSI),
|
||||
COUNTRY_REGD_ENT("AQ", RTW_REGD_ETSI, RTW_REGD_ETSI),
|
||||
COUNTRY_REGD_ENT("AR", RTW_REGD_MEXICO, RTW_REGD_MEXICO),
|
||||
COUNTRY_REGD_ENT("AS", RTW_REGD_FCC, RTW_REGD_FCC),
|
||||
COUNTRY_REGD_ENT("AT", RTW_REGD_ETSI, RTW_REGD_ETSI),
|
||||
COUNTRY_REGD_ENT("AU", RTW_REGD_ACMA, RTW_REGD_ACMA),
|
||||
COUNTRY_REGD_ENT("AW", RTW_REGD_FCC, RTW_REGD_FCC),
|
||||
COUNTRY_REGD_ENT("AZ", RTW_REGD_ETSI, RTW_REGD_ETSI),
|
||||
COUNTRY_REGD_ENT("BA", RTW_REGD_ETSI, RTW_REGD_ETSI),
|
||||
COUNTRY_REGD_ENT("BB", RTW_REGD_FCC, RTW_REGD_FCC),
|
||||
COUNTRY_REGD_ENT("BD", RTW_REGD_ETSI, RTW_REGD_ETSI),
|
||||
COUNTRY_REGD_ENT("BE", RTW_REGD_ETSI, RTW_REGD_ETSI),
|
||||
COUNTRY_REGD_ENT("BF", RTW_REGD_ETSI, RTW_REGD_ETSI),
|
||||
COUNTRY_REGD_ENT("BG", RTW_REGD_ETSI, RTW_REGD_ETSI),
|
||||
COUNTRY_REGD_ENT("BH", RTW_REGD_ETSI, RTW_REGD_ETSI),
|
||||
COUNTRY_REGD_ENT("BI", RTW_REGD_ETSI, RTW_REGD_ETSI),
|
||||
COUNTRY_REGD_ENT("BJ", RTW_REGD_ETSI, RTW_REGD_ETSI),
|
||||
COUNTRY_REGD_ENT("BM", RTW_REGD_FCC, RTW_REGD_FCC),
|
||||
COUNTRY_REGD_ENT("BN", RTW_REGD_ETSI, RTW_REGD_ETSI),
|
||||
COUNTRY_REGD_ENT("BO", RTW_REGD_FCC, RTW_REGD_FCC),
|
||||
COUNTRY_REGD_ENT("BR", RTW_REGD_FCC, RTW_REGD_FCC),
|
||||
COUNTRY_REGD_ENT("BS", RTW_REGD_FCC, RTW_REGD_FCC),
|
||||
COUNTRY_REGD_ENT("BT", RTW_REGD_ETSI, RTW_REGD_ETSI),
|
||||
COUNTRY_REGD_ENT("BV", RTW_REGD_ETSI, RTW_REGD_ETSI),
|
||||
COUNTRY_REGD_ENT("BW", RTW_REGD_ETSI, RTW_REGD_ETSI),
|
||||
COUNTRY_REGD_ENT("BY", RTW_REGD_ETSI, RTW_REGD_ETSI),
|
||||
COUNTRY_REGD_ENT("BZ", RTW_REGD_FCC, RTW_REGD_FCC),
|
||||
COUNTRY_REGD_ENT("CA", RTW_REGD_IC, RTW_REGD_IC),
|
||||
COUNTRY_REGD_ENT("CC", RTW_REGD_ETSI, RTW_REGD_ETSI),
|
||||
COUNTRY_REGD_ENT("CD", RTW_REGD_ETSI, RTW_REGD_ETSI),
|
||||
COUNTRY_REGD_ENT("CF", RTW_REGD_ETSI, RTW_REGD_ETSI),
|
||||
COUNTRY_REGD_ENT("CG", RTW_REGD_ETSI, RTW_REGD_ETSI),
|
||||
COUNTRY_REGD_ENT("CH", RTW_REGD_ETSI, RTW_REGD_ETSI),
|
||||
COUNTRY_REGD_ENT("CI", RTW_REGD_ETSI, RTW_REGD_ETSI),
|
||||
COUNTRY_REGD_ENT("CK", RTW_REGD_ETSI, RTW_REGD_ETSI),
|
||||
COUNTRY_REGD_ENT("CL", RTW_REGD_FCC, RTW_REGD_FCC),
|
||||
COUNTRY_REGD_ENT("CM", RTW_REGD_ETSI, RTW_REGD_ETSI),
|
||||
COUNTRY_REGD_ENT("CN", RTW_REGD_ETSI, RTW_REGD_ETSI),
|
||||
COUNTRY_REGD_ENT("CO", RTW_REGD_FCC, RTW_REGD_FCC),
|
||||
COUNTRY_REGD_ENT("CR", RTW_REGD_FCC, RTW_REGD_FCC),
|
||||
COUNTRY_REGD_ENT("CV", RTW_REGD_ETSI, RTW_REGD_ETSI),
|
||||
COUNTRY_REGD_ENT("CX", RTW_REGD_ACMA, RTW_REGD_ACMA),
|
||||
COUNTRY_REGD_ENT("CY", RTW_REGD_ETSI, RTW_REGD_ETSI),
|
||||
COUNTRY_REGD_ENT("CZ", RTW_REGD_ETSI, RTW_REGD_ETSI),
|
||||
COUNTRY_REGD_ENT("DE", RTW_REGD_ETSI, RTW_REGD_ETSI),
|
||||
COUNTRY_REGD_ENT("DJ", RTW_REGD_ETSI, RTW_REGD_ETSI),
|
||||
COUNTRY_REGD_ENT("DK", RTW_REGD_ETSI, RTW_REGD_ETSI),
|
||||
COUNTRY_REGD_ENT("DM", RTW_REGD_FCC, RTW_REGD_FCC),
|
||||
COUNTRY_REGD_ENT("DO", RTW_REGD_FCC, RTW_REGD_FCC),
|
||||
COUNTRY_REGD_ENT("DZ", RTW_REGD_ETSI, RTW_REGD_ETSI),
|
||||
COUNTRY_REGD_ENT("EC", RTW_REGD_FCC, RTW_REGD_FCC),
|
||||
COUNTRY_REGD_ENT("EE", RTW_REGD_ETSI, RTW_REGD_ETSI),
|
||||
COUNTRY_REGD_ENT("EG", RTW_REGD_ETSI, RTW_REGD_ETSI),
|
||||
COUNTRY_REGD_ENT("EH", RTW_REGD_ETSI, RTW_REGD_ETSI),
|
||||
COUNTRY_REGD_ENT("ER", RTW_REGD_ETSI, RTW_REGD_ETSI),
|
||||
COUNTRY_REGD_ENT("ES", RTW_REGD_ETSI, RTW_REGD_ETSI),
|
||||
COUNTRY_REGD_ENT("ET", RTW_REGD_ETSI, RTW_REGD_ETSI),
|
||||
COUNTRY_REGD_ENT("FI", RTW_REGD_ETSI, RTW_REGD_ETSI),
|
||||
COUNTRY_REGD_ENT("FJ", RTW_REGD_FCC, RTW_REGD_FCC),
|
||||
COUNTRY_REGD_ENT("FK", RTW_REGD_ETSI, RTW_REGD_ETSI),
|
||||
COUNTRY_REGD_ENT("FM", RTW_REGD_FCC, RTW_REGD_FCC),
|
||||
COUNTRY_REGD_ENT("FO", RTW_REGD_ETSI, RTW_REGD_ETSI),
|
||||
COUNTRY_REGD_ENT("FR", RTW_REGD_ETSI, RTW_REGD_ETSI),
|
||||
COUNTRY_REGD_ENT("GA", RTW_REGD_ETSI, RTW_REGD_ETSI),
|
||||
COUNTRY_REGD_ENT("GB", RTW_REGD_ETSI, RTW_REGD_ETSI),
|
||||
COUNTRY_REGD_ENT("GD", RTW_REGD_FCC, RTW_REGD_FCC),
|
||||
COUNTRY_REGD_ENT("GE", RTW_REGD_ETSI, RTW_REGD_ETSI),
|
||||
COUNTRY_REGD_ENT("GF", RTW_REGD_ETSI, RTW_REGD_ETSI),
|
||||
COUNTRY_REGD_ENT("GG", RTW_REGD_ETSI, RTW_REGD_ETSI),
|
||||
COUNTRY_REGD_ENT("GH", RTW_REGD_ETSI, RTW_REGD_ETSI),
|
||||
COUNTRY_REGD_ENT("GI", RTW_REGD_ETSI, RTW_REGD_ETSI),
|
||||
COUNTRY_REGD_ENT("GL", RTW_REGD_ETSI, RTW_REGD_ETSI),
|
||||
COUNTRY_REGD_ENT("GM", RTW_REGD_ETSI, RTW_REGD_ETSI),
|
||||
COUNTRY_REGD_ENT("GN", RTW_REGD_ETSI, RTW_REGD_ETSI),
|
||||
COUNTRY_REGD_ENT("GP", RTW_REGD_ETSI, RTW_REGD_ETSI),
|
||||
COUNTRY_REGD_ENT("GQ", RTW_REGD_ETSI, RTW_REGD_ETSI),
|
||||
COUNTRY_REGD_ENT("GR", RTW_REGD_ETSI, RTW_REGD_ETSI),
|
||||
COUNTRY_REGD_ENT("GS", RTW_REGD_ETSI, RTW_REGD_ETSI),
|
||||
COUNTRY_REGD_ENT("GT", RTW_REGD_FCC, RTW_REGD_FCC),
|
||||
COUNTRY_REGD_ENT("GU", RTW_REGD_FCC, RTW_REGD_FCC),
|
||||
COUNTRY_REGD_ENT("GW", RTW_REGD_ETSI, RTW_REGD_ETSI),
|
||||
COUNTRY_REGD_ENT("GY", RTW_REGD_FCC, RTW_REGD_FCC),
|
||||
COUNTRY_REGD_ENT("HK", RTW_REGD_ETSI, RTW_REGD_ETSI),
|
||||
COUNTRY_REGD_ENT("HM", RTW_REGD_ACMA, RTW_REGD_ACMA),
|
||||
COUNTRY_REGD_ENT("HN", RTW_REGD_FCC, RTW_REGD_FCC),
|
||||
COUNTRY_REGD_ENT("HR", RTW_REGD_ETSI, RTW_REGD_ETSI),
|
||||
COUNTRY_REGD_ENT("HT", RTW_REGD_FCC, RTW_REGD_FCC),
|
||||
COUNTRY_REGD_ENT("HU", RTW_REGD_ETSI, RTW_REGD_ETSI),
|
||||
COUNTRY_REGD_ENT("ID", RTW_REGD_ETSI, RTW_REGD_ETSI),
|
||||
COUNTRY_REGD_ENT("IE", RTW_REGD_ETSI, RTW_REGD_ETSI),
|
||||
COUNTRY_REGD_ENT("IL", RTW_REGD_ETSI, RTW_REGD_ETSI),
|
||||
COUNTRY_REGD_ENT("IM", RTW_REGD_ETSI, RTW_REGD_ETSI),
|
||||
COUNTRY_REGD_ENT("IN", RTW_REGD_ETSI, RTW_REGD_ETSI),
|
||||
COUNTRY_REGD_ENT("IO", RTW_REGD_ETSI, RTW_REGD_ETSI),
|
||||
COUNTRY_REGD_ENT("IQ", RTW_REGD_ETSI, RTW_REGD_ETSI),
|
||||
COUNTRY_REGD_ENT("IR", RTW_REGD_ETSI, RTW_REGD_ETSI),
|
||||
COUNTRY_REGD_ENT("IS", RTW_REGD_ETSI, RTW_REGD_ETSI),
|
||||
COUNTRY_REGD_ENT("IT", RTW_REGD_ETSI, RTW_REGD_ETSI),
|
||||
COUNTRY_REGD_ENT("JE", RTW_REGD_ETSI, RTW_REGD_ETSI),
|
||||
COUNTRY_REGD_ENT("JM", RTW_REGD_FCC, RTW_REGD_FCC),
|
||||
COUNTRY_REGD_ENT("JO", RTW_REGD_ETSI, RTW_REGD_ETSI),
|
||||
COUNTRY_REGD_ENT("JP", RTW_REGD_MKK, RTW_REGD_MKK),
|
||||
COUNTRY_REGD_ENT("KE", RTW_REGD_ETSI, RTW_REGD_ETSI),
|
||||
COUNTRY_REGD_ENT("KG", RTW_REGD_ETSI, RTW_REGD_ETSI),
|
||||
COUNTRY_REGD_ENT("KH", RTW_REGD_ETSI, RTW_REGD_ETSI),
|
||||
COUNTRY_REGD_ENT("KI", RTW_REGD_ETSI, RTW_REGD_ETSI),
|
||||
COUNTRY_REGD_ENT("KM", RTW_REGD_ETSI, RTW_REGD_ETSI),
|
||||
COUNTRY_REGD_ENT("KN", RTW_REGD_FCC, RTW_REGD_FCC),
|
||||
COUNTRY_REGD_ENT("KR", RTW_REGD_KCC, RTW_REGD_KCC),
|
||||
COUNTRY_REGD_ENT("KW", RTW_REGD_ETSI, RTW_REGD_ETSI),
|
||||
COUNTRY_REGD_ENT("KY", RTW_REGD_FCC, RTW_REGD_FCC),
|
||||
COUNTRY_REGD_ENT("KZ", RTW_REGD_ETSI, RTW_REGD_ETSI),
|
||||
COUNTRY_REGD_ENT("LA", RTW_REGD_ETSI, RTW_REGD_ETSI),
|
||||
COUNTRY_REGD_ENT("LB", RTW_REGD_ETSI, RTW_REGD_ETSI),
|
||||
COUNTRY_REGD_ENT("LC", RTW_REGD_FCC, RTW_REGD_FCC),
|
||||
COUNTRY_REGD_ENT("LI", RTW_REGD_ETSI, RTW_REGD_ETSI),
|
||||
COUNTRY_REGD_ENT("LK", RTW_REGD_ETSI, RTW_REGD_ETSI),
|
||||
COUNTRY_REGD_ENT("LR", RTW_REGD_ETSI, RTW_REGD_ETSI),
|
||||
COUNTRY_REGD_ENT("LS", RTW_REGD_ETSI, RTW_REGD_ETSI),
|
||||
COUNTRY_REGD_ENT("LT", RTW_REGD_ETSI, RTW_REGD_ETSI),
|
||||
COUNTRY_REGD_ENT("LU", RTW_REGD_ETSI, RTW_REGD_ETSI),
|
||||
COUNTRY_REGD_ENT("LV", RTW_REGD_ETSI, RTW_REGD_ETSI),
|
||||
COUNTRY_REGD_ENT("LY", RTW_REGD_ETSI, RTW_REGD_ETSI),
|
||||
COUNTRY_REGD_ENT("MA", RTW_REGD_ETSI, RTW_REGD_ETSI),
|
||||
COUNTRY_REGD_ENT("MC", RTW_REGD_ETSI, RTW_REGD_ETSI),
|
||||
COUNTRY_REGD_ENT("MD", RTW_REGD_ETSI, RTW_REGD_ETSI),
|
||||
COUNTRY_REGD_ENT("ME", RTW_REGD_ETSI, RTW_REGD_ETSI),
|
||||
COUNTRY_REGD_ENT("MF", RTW_REGD_FCC, RTW_REGD_FCC),
|
||||
COUNTRY_REGD_ENT("MG", RTW_REGD_ETSI, RTW_REGD_ETSI),
|
||||
COUNTRY_REGD_ENT("MH", RTW_REGD_FCC, RTW_REGD_FCC),
|
||||
COUNTRY_REGD_ENT("MK", RTW_REGD_ETSI, RTW_REGD_ETSI),
|
||||
COUNTRY_REGD_ENT("ML", RTW_REGD_ETSI, RTW_REGD_ETSI),
|
||||
COUNTRY_REGD_ENT("MM", RTW_REGD_ETSI, RTW_REGD_ETSI),
|
||||
COUNTRY_REGD_ENT("MN", RTW_REGD_ETSI, RTW_REGD_ETSI),
|
||||
COUNTRY_REGD_ENT("MO", RTW_REGD_ETSI, RTW_REGD_ETSI),
|
||||
COUNTRY_REGD_ENT("MP", RTW_REGD_FCC, RTW_REGD_FCC),
|
||||
COUNTRY_REGD_ENT("MQ", RTW_REGD_ETSI, RTW_REGD_ETSI),
|
||||
COUNTRY_REGD_ENT("MR", RTW_REGD_ETSI, RTW_REGD_ETSI),
|
||||
COUNTRY_REGD_ENT("MS", RTW_REGD_ETSI, RTW_REGD_ETSI),
|
||||
COUNTRY_REGD_ENT("MT", RTW_REGD_ETSI, RTW_REGD_ETSI),
|
||||
COUNTRY_REGD_ENT("MU", RTW_REGD_ETSI, RTW_REGD_ETSI),
|
||||
COUNTRY_REGD_ENT("MV", RTW_REGD_ETSI, RTW_REGD_ETSI),
|
||||
COUNTRY_REGD_ENT("MW", RTW_REGD_ETSI, RTW_REGD_ETSI),
|
||||
COUNTRY_REGD_ENT("MX", RTW_REGD_MEXICO, RTW_REGD_MEXICO),
|
||||
COUNTRY_REGD_ENT("MY", RTW_REGD_ETSI, RTW_REGD_ETSI),
|
||||
COUNTRY_REGD_ENT("MZ", RTW_REGD_ETSI, RTW_REGD_ETSI),
|
||||
COUNTRY_REGD_ENT("NA", RTW_REGD_ETSI, RTW_REGD_ETSI),
|
||||
COUNTRY_REGD_ENT("NC", RTW_REGD_ETSI, RTW_REGD_ETSI),
|
||||
COUNTRY_REGD_ENT("NE", RTW_REGD_ETSI, RTW_REGD_ETSI),
|
||||
COUNTRY_REGD_ENT("NF", RTW_REGD_ACMA, RTW_REGD_ACMA),
|
||||
COUNTRY_REGD_ENT("NG", RTW_REGD_ETSI, RTW_REGD_ETSI),
|
||||
COUNTRY_REGD_ENT("NI", RTW_REGD_FCC, RTW_REGD_FCC),
|
||||
COUNTRY_REGD_ENT("NL", RTW_REGD_ETSI, RTW_REGD_ETSI),
|
||||
COUNTRY_REGD_ENT("NO", RTW_REGD_ETSI, RTW_REGD_ETSI),
|
||||
COUNTRY_REGD_ENT("NP", RTW_REGD_ETSI, RTW_REGD_ETSI),
|
||||
COUNTRY_REGD_ENT("NR", RTW_REGD_ETSI, RTW_REGD_ETSI),
|
||||
COUNTRY_REGD_ENT("NU", RTW_REGD_ACMA, RTW_REGD_ACMA),
|
||||
COUNTRY_REGD_ENT("NZ", RTW_REGD_ACMA, RTW_REGD_ACMA),
|
||||
COUNTRY_REGD_ENT("OM", RTW_REGD_ETSI, RTW_REGD_ETSI),
|
||||
COUNTRY_REGD_ENT("PA", RTW_REGD_FCC, RTW_REGD_FCC),
|
||||
COUNTRY_REGD_ENT("PE", RTW_REGD_FCC, RTW_REGD_FCC),
|
||||
COUNTRY_REGD_ENT("PF", RTW_REGD_ETSI, RTW_REGD_ETSI),
|
||||
COUNTRY_REGD_ENT("PG", RTW_REGD_ETSI, RTW_REGD_ETSI),
|
||||
COUNTRY_REGD_ENT("PH", RTW_REGD_ETSI, RTW_REGD_ETSI),
|
||||
COUNTRY_REGD_ENT("PK", RTW_REGD_ETSI, RTW_REGD_ETSI),
|
||||
COUNTRY_REGD_ENT("PL", RTW_REGD_ETSI, RTW_REGD_ETSI),
|
||||
COUNTRY_REGD_ENT("PM", RTW_REGD_ETSI, RTW_REGD_ETSI),
|
||||
COUNTRY_REGD_ENT("PR", RTW_REGD_FCC, RTW_REGD_FCC),
|
||||
COUNTRY_REGD_ENT("PS", RTW_REGD_ETSI, RTW_REGD_ETSI),
|
||||
COUNTRY_REGD_ENT("PT", RTW_REGD_ETSI, RTW_REGD_ETSI),
|
||||
COUNTRY_REGD_ENT("PW", RTW_REGD_FCC, RTW_REGD_FCC),
|
||||
COUNTRY_REGD_ENT("PY", RTW_REGD_FCC, RTW_REGD_FCC),
|
||||
COUNTRY_REGD_ENT("QA", RTW_REGD_ETSI, RTW_REGD_ETSI),
|
||||
COUNTRY_REGD_ENT("RE", RTW_REGD_ETSI, RTW_REGD_ETSI),
|
||||
COUNTRY_REGD_ENT("RO", RTW_REGD_ETSI, RTW_REGD_ETSI),
|
||||
COUNTRY_REGD_ENT("RS", RTW_REGD_ETSI, RTW_REGD_ETSI),
|
||||
COUNTRY_REGD_ENT("RU", RTW_REGD_ETSI, RTW_REGD_ETSI),
|
||||
COUNTRY_REGD_ENT("RW", RTW_REGD_ETSI, RTW_REGD_ETSI),
|
||||
COUNTRY_REGD_ENT("SA", RTW_REGD_ETSI, RTW_REGD_ETSI),
|
||||
COUNTRY_REGD_ENT("SB", RTW_REGD_ETSI, RTW_REGD_ETSI),
|
||||
COUNTRY_REGD_ENT("SC", RTW_REGD_FCC, RTW_REGD_FCC),
|
||||
COUNTRY_REGD_ENT("SE", RTW_REGD_ETSI, RTW_REGD_ETSI),
|
||||
COUNTRY_REGD_ENT("SG", RTW_REGD_ETSI, RTW_REGD_ETSI),
|
||||
COUNTRY_REGD_ENT("SH", RTW_REGD_ETSI, RTW_REGD_ETSI),
|
||||
COUNTRY_REGD_ENT("SI", RTW_REGD_ETSI, RTW_REGD_ETSI),
|
||||
COUNTRY_REGD_ENT("SJ", RTW_REGD_ETSI, RTW_REGD_ETSI),
|
||||
COUNTRY_REGD_ENT("SK", RTW_REGD_ETSI, RTW_REGD_ETSI),
|
||||
COUNTRY_REGD_ENT("SL", RTW_REGD_ETSI, RTW_REGD_ETSI),
|
||||
COUNTRY_REGD_ENT("SM", RTW_REGD_ETSI, RTW_REGD_ETSI),
|
||||
COUNTRY_REGD_ENT("SN", RTW_REGD_ETSI, RTW_REGD_ETSI),
|
||||
COUNTRY_REGD_ENT("SO", RTW_REGD_ETSI, RTW_REGD_ETSI),
|
||||
COUNTRY_REGD_ENT("SR", RTW_REGD_FCC, RTW_REGD_FCC),
|
||||
COUNTRY_REGD_ENT("ST", RTW_REGD_FCC, RTW_REGD_FCC),
|
||||
COUNTRY_REGD_ENT("SV", RTW_REGD_FCC, RTW_REGD_FCC),
|
||||
COUNTRY_REGD_ENT("SX", RTW_REGD_FCC, RTW_REGD_FCC),
|
||||
COUNTRY_REGD_ENT("SZ", RTW_REGD_ETSI, RTW_REGD_ETSI),
|
||||
COUNTRY_REGD_ENT("TC", RTW_REGD_ETSI, RTW_REGD_ETSI),
|
||||
COUNTRY_REGD_ENT("TD", RTW_REGD_ETSI, RTW_REGD_ETSI),
|
||||
COUNTRY_REGD_ENT("TF", RTW_REGD_ETSI, RTW_REGD_ETSI),
|
||||
COUNTRY_REGD_ENT("TG", RTW_REGD_ETSI, RTW_REGD_ETSI),
|
||||
COUNTRY_REGD_ENT("TH", RTW_REGD_ETSI, RTW_REGD_ETSI),
|
||||
COUNTRY_REGD_ENT("TJ", RTW_REGD_ETSI, RTW_REGD_ETSI),
|
||||
COUNTRY_REGD_ENT("TK", RTW_REGD_ACMA, RTW_REGD_ACMA),
|
||||
COUNTRY_REGD_ENT("TM", RTW_REGD_ETSI, RTW_REGD_ETSI),
|
||||
COUNTRY_REGD_ENT("TN", RTW_REGD_ETSI, RTW_REGD_ETSI),
|
||||
COUNTRY_REGD_ENT("TO", RTW_REGD_ETSI, RTW_REGD_ETSI),
|
||||
COUNTRY_REGD_ENT("TR", RTW_REGD_ETSI, RTW_REGD_ETSI),
|
||||
COUNTRY_REGD_ENT("TT", RTW_REGD_FCC, RTW_REGD_FCC),
|
||||
COUNTRY_REGD_ENT("TV", RTW_REGD_ETSI, RTW_REGD_WW),
|
||||
COUNTRY_REGD_ENT("TW", RTW_REGD_FCC, RTW_REGD_FCC),
|
||||
COUNTRY_REGD_ENT("TZ", RTW_REGD_ETSI, RTW_REGD_ETSI),
|
||||
COUNTRY_REGD_ENT("UA", RTW_REGD_ETSI, RTW_REGD_ETSI),
|
||||
COUNTRY_REGD_ENT("UG", RTW_REGD_ETSI, RTW_REGD_ETSI),
|
||||
COUNTRY_REGD_ENT("US", RTW_REGD_FCC, RTW_REGD_FCC),
|
||||
COUNTRY_REGD_ENT("UY", RTW_REGD_FCC, RTW_REGD_FCC),
|
||||
COUNTRY_REGD_ENT("UZ", RTW_REGD_ETSI, RTW_REGD_ETSI),
|
||||
COUNTRY_REGD_ENT("VA", RTW_REGD_ETSI, RTW_REGD_ETSI),
|
||||
COUNTRY_REGD_ENT("VC", RTW_REGD_FCC, RTW_REGD_FCC),
|
||||
COUNTRY_REGD_ENT("VE", RTW_REGD_FCC, RTW_REGD_FCC),
|
||||
COUNTRY_REGD_ENT("VG", RTW_REGD_FCC, RTW_REGD_FCC),
|
||||
COUNTRY_REGD_ENT("VI", RTW_REGD_FCC, RTW_REGD_FCC),
|
||||
COUNTRY_REGD_ENT("VN", RTW_REGD_ETSI, RTW_REGD_ETSI),
|
||||
COUNTRY_REGD_ENT("VU", RTW_REGD_ETSI, RTW_REGD_ETSI),
|
||||
COUNTRY_REGD_ENT("WF", RTW_REGD_ETSI, RTW_REGD_ETSI),
|
||||
COUNTRY_REGD_ENT("WS", RTW_REGD_FCC, RTW_REGD_FCC),
|
||||
COUNTRY_REGD_ENT("XK", RTW_REGD_ETSI, RTW_REGD_ETSI),
|
||||
COUNTRY_REGD_ENT("YE", RTW_REGD_ETSI, RTW_REGD_ETSI),
|
||||
COUNTRY_REGD_ENT("YT", RTW_REGD_ETSI, RTW_REGD_ETSI),
|
||||
COUNTRY_REGD_ENT("ZA", RTW_REGD_ETSI, RTW_REGD_ETSI),
|
||||
COUNTRY_REGD_ENT("ZM", RTW_REGD_ETSI, RTW_REGD_ETSI),
|
||||
COUNTRY_REGD_ENT("ZW", RTW_REGD_ETSI, RTW_REGD_ETSI),
|
||||
};
|
||||
|
||||
static void rtw_regd_apply_beaconing_flags(struct wiphy *wiphy,
|
||||
enum nl80211_reg_initiator initiator)
|
||||
{
|
||||
enum nl80211_band band;
|
||||
struct ieee80211_supported_band *sband;
|
||||
const struct ieee80211_reg_rule *reg_rule;
|
||||
struct ieee80211_channel *ch;
|
||||
unsigned int i;
|
||||
|
||||
for (band = 0; band < NUM_NL80211_BANDS; band++) {
|
||||
if (!wiphy->bands[band])
|
||||
continue;
|
||||
|
||||
sband = wiphy->bands[band];
|
||||
for (i = 0; i < sband->n_channels; i++) {
|
||||
ch = &sband->channels[i];
|
||||
|
||||
reg_rule = freq_reg_info(wiphy,
|
||||
MHZ_TO_KHZ(ch->center_freq));
|
||||
if (IS_ERR(reg_rule))
|
||||
continue;
|
||||
|
||||
ch->flags &= ~IEEE80211_CHAN_DISABLED;
|
||||
|
||||
if (!(reg_rule->flags & NL80211_RRF_NO_IR))
|
||||
ch->flags &= ~IEEE80211_CHAN_NO_IR;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void rtw_regd_apply_hw_cap_flags(struct wiphy *wiphy)
|
||||
{
|
||||
struct ieee80211_hw *hw = wiphy_to_ieee80211_hw(wiphy);
|
||||
|
|
@ -321,78 +307,223 @@ static void rtw_regd_apply_hw_cap_flags(struct wiphy *wiphy)
|
|||
}
|
||||
}
|
||||
|
||||
static void rtw_regd_apply_world_flags(struct wiphy *wiphy,
|
||||
enum nl80211_reg_initiator initiator)
|
||||
static bool rtw_reg_is_ww(const struct rtw_regulatory *reg)
|
||||
{
|
||||
rtw_regd_apply_beaconing_flags(wiphy, initiator);
|
||||
return reg == &rtw_reg_ww;
|
||||
}
|
||||
|
||||
static struct rtw_regulatory rtw_regd_find_reg_by_name(char *alpha2)
|
||||
static bool rtw_reg_match(const struct rtw_regulatory *reg, const char *alpha2)
|
||||
{
|
||||
return memcmp(reg->alpha2, alpha2, 2) == 0;
|
||||
}
|
||||
|
||||
static const struct rtw_regulatory *rtw_reg_find_by_name(const char *alpha2)
|
||||
{
|
||||
unsigned int i;
|
||||
|
||||
for (i = 0; i < ARRAY_SIZE(all_chplan_map); i++) {
|
||||
if (!memcmp(all_chplan_map[i].alpha2, alpha2, 2))
|
||||
return all_chplan_map[i];
|
||||
for (i = 0; i < ARRAY_SIZE(rtw_reg_map); i++) {
|
||||
if (rtw_reg_match(&rtw_reg_map[i], alpha2))
|
||||
return &rtw_reg_map[i];
|
||||
}
|
||||
|
||||
return rtw_defined_chplan;
|
||||
return &rtw_reg_ww;
|
||||
}
|
||||
|
||||
static int rtw_regd_notifier_apply(struct rtw_dev *rtwdev,
|
||||
struct wiphy *wiphy,
|
||||
struct regulatory_request *request)
|
||||
{
|
||||
if (request->initiator == NL80211_REGDOM_SET_BY_USER)
|
||||
return 0;
|
||||
rtwdev->regd = rtw_regd_find_reg_by_name(request->alpha2);
|
||||
rtw_regd_apply_world_flags(wiphy, request->initiator);
|
||||
static
|
||||
void rtw_regd_notifier(struct wiphy *wiphy, struct regulatory_request *request);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
rtw_regd_init_wiphy(struct rtw_regulatory *reg, struct wiphy *wiphy,
|
||||
void (*reg_notifier)(struct wiphy *wiphy,
|
||||
struct regulatory_request *request))
|
||||
{
|
||||
wiphy->reg_notifier = reg_notifier;
|
||||
|
||||
wiphy->regulatory_flags &= ~REGULATORY_CUSTOM_REG;
|
||||
wiphy->regulatory_flags &= ~REGULATORY_STRICT_REG;
|
||||
wiphy->regulatory_flags &= ~REGULATORY_DISABLE_BEACON_HINTS;
|
||||
|
||||
rtw_regd_apply_hw_cap_flags(wiphy);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int rtw_regd_init(struct rtw_dev *rtwdev,
|
||||
void (*reg_notifier)(struct wiphy *wiphy,
|
||||
struct regulatory_request *request))
|
||||
/* call this before ieee80211_register_hw() */
|
||||
int rtw_regd_init(struct rtw_dev *rtwdev)
|
||||
{
|
||||
struct wiphy *wiphy = rtwdev->hw->wiphy;
|
||||
const struct rtw_regulatory *chip_reg;
|
||||
|
||||
if (!wiphy)
|
||||
return -EINVAL;
|
||||
|
||||
rtwdev->regd = rtw_regd_find_reg_by_name(rtwdev->efuse.country_code);
|
||||
rtw_regd_init_wiphy(&rtwdev->regd, wiphy, reg_notifier);
|
||||
wiphy->reg_notifier = rtw_regd_notifier;
|
||||
|
||||
chip_reg = rtw_reg_find_by_name(rtwdev->efuse.country_code);
|
||||
if (!rtw_reg_is_ww(chip_reg)) {
|
||||
rtwdev->regd.state = RTW_REGD_STATE_PROGRAMMED;
|
||||
|
||||
/* Set REGULATORY_STRICT_REG before ieee80211_register_hw(),
|
||||
* stack will wait for regulatory_hint() and consider it
|
||||
* as the superset for our regulatory rule.
|
||||
*/
|
||||
wiphy->regulatory_flags |= REGULATORY_STRICT_REG;
|
||||
wiphy->regulatory_flags |= REGULATORY_COUNTRY_IE_IGNORE;
|
||||
} else {
|
||||
rtwdev->regd.state = RTW_REGD_STATE_WORLDWIDE;
|
||||
}
|
||||
|
||||
rtwdev->regd.regulatory = &rtw_reg_ww;
|
||||
rtwdev->regd.dfs_region = NL80211_DFS_UNSET;
|
||||
rtw_dbg_regd_dump(rtwdev, "regd init state %d: ", rtwdev->regd.state);
|
||||
|
||||
rtw_regd_apply_hw_cap_flags(wiphy);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* call this after ieee80211_register_hw() */
|
||||
int rtw_regd_hint(struct rtw_dev *rtwdev)
|
||||
{
|
||||
struct wiphy *wiphy = rtwdev->hw->wiphy;
|
||||
int ret;
|
||||
|
||||
if (!wiphy)
|
||||
return -EINVAL;
|
||||
|
||||
if (rtwdev->regd.state == RTW_REGD_STATE_PROGRAMMED) {
|
||||
rtw_dbg(rtwdev, RTW_DBG_REGD,
|
||||
"country domain %c%c is PGed on efuse",
|
||||
rtwdev->efuse.country_code[0],
|
||||
rtwdev->efuse.country_code[1]);
|
||||
|
||||
ret = regulatory_hint(wiphy, rtwdev->efuse.country_code);
|
||||
if (ret) {
|
||||
rtw_warn(rtwdev,
|
||||
"failed to hint regulatory: %d\n", ret);
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static bool rtw_regd_mgmt_worldwide(struct rtw_dev *rtwdev,
|
||||
struct rtw_regd *next_regd,
|
||||
struct regulatory_request *request)
|
||||
{
|
||||
struct wiphy *wiphy = rtwdev->hw->wiphy;
|
||||
|
||||
next_regd->state = RTW_REGD_STATE_WORLDWIDE;
|
||||
|
||||
if (request->initiator == NL80211_REGDOM_SET_BY_USER &&
|
||||
!rtw_reg_is_ww(next_regd->regulatory)) {
|
||||
next_regd->state = RTW_REGD_STATE_SETTING;
|
||||
wiphy->regulatory_flags |= REGULATORY_COUNTRY_IE_IGNORE;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool rtw_regd_mgmt_programmed(struct rtw_dev *rtwdev,
|
||||
struct rtw_regd *next_regd,
|
||||
struct regulatory_request *request)
|
||||
{
|
||||
if (request->initiator == NL80211_REGDOM_SET_BY_DRIVER &&
|
||||
rtw_reg_match(next_regd->regulatory, rtwdev->efuse.country_code)) {
|
||||
next_regd->state = RTW_REGD_STATE_PROGRAMMED;
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
static bool rtw_regd_mgmt_setting(struct rtw_dev *rtwdev,
|
||||
struct rtw_regd *next_regd,
|
||||
struct regulatory_request *request)
|
||||
{
|
||||
struct wiphy *wiphy = rtwdev->hw->wiphy;
|
||||
|
||||
if (request->initiator != NL80211_REGDOM_SET_BY_USER)
|
||||
return false;
|
||||
|
||||
next_regd->state = RTW_REGD_STATE_SETTING;
|
||||
|
||||
if (rtw_reg_is_ww(next_regd->regulatory)) {
|
||||
next_regd->state = RTW_REGD_STATE_WORLDWIDE;
|
||||
wiphy->regulatory_flags &= ~REGULATORY_COUNTRY_IE_IGNORE;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool (*const rtw_regd_handler[RTW_REGD_STATE_NR])
|
||||
(struct rtw_dev *, struct rtw_regd *, struct regulatory_request *) = {
|
||||
[RTW_REGD_STATE_WORLDWIDE] = rtw_regd_mgmt_worldwide,
|
||||
[RTW_REGD_STATE_PROGRAMMED] = rtw_regd_mgmt_programmed,
|
||||
[RTW_REGD_STATE_SETTING] = rtw_regd_mgmt_setting,
|
||||
};
|
||||
|
||||
static bool rtw_regd_state_hdl(struct rtw_dev *rtwdev,
|
||||
struct rtw_regd *next_regd,
|
||||
struct regulatory_request *request)
|
||||
{
|
||||
next_regd->regulatory = rtw_reg_find_by_name(request->alpha2);
|
||||
next_regd->dfs_region = request->dfs_region;
|
||||
return rtw_regd_handler[rtwdev->regd.state](rtwdev, next_regd, request);
|
||||
}
|
||||
|
||||
static
|
||||
void rtw_regd_notifier(struct wiphy *wiphy, struct regulatory_request *request)
|
||||
{
|
||||
struct ieee80211_hw *hw = wiphy_to_ieee80211_hw(wiphy);
|
||||
struct rtw_dev *rtwdev = hw->priv;
|
||||
struct rtw_hal *hal = &rtwdev->hal;
|
||||
struct rtw_regd next_regd = {0};
|
||||
bool hdl;
|
||||
|
||||
rtw_regd_notifier_apply(rtwdev, wiphy, request);
|
||||
rtw_dbg(rtwdev, RTW_DBG_REGD,
|
||||
"get alpha2 %c%c from initiator %d, mapping to chplan 0x%x, txregd %d\n",
|
||||
request->alpha2[0], request->alpha2[1], request->initiator,
|
||||
rtwdev->regd.chplan, rtwdev->regd.txpwr_regd);
|
||||
hdl = rtw_regd_state_hdl(rtwdev, &next_regd, request);
|
||||
if (!hdl) {
|
||||
rtw_dbg(rtwdev, RTW_DBG_REGD,
|
||||
"regd state %d: ignore request %c%c of initiator %d\n",
|
||||
rtwdev->regd.state,
|
||||
request->alpha2[0],
|
||||
request->alpha2[1],
|
||||
request->initiator);
|
||||
return;
|
||||
}
|
||||
|
||||
rtw_dbg(rtwdev, RTW_DBG_REGD, "regd state: %d -> %d\n",
|
||||
rtwdev->regd.state, next_regd.state);
|
||||
|
||||
rtwdev->regd = next_regd;
|
||||
rtw_dbg_regd_dump(rtwdev, "get alpha2 %c%c from initiator %d: ",
|
||||
request->alpha2[0],
|
||||
request->alpha2[1],
|
||||
request->initiator);
|
||||
|
||||
rtw_phy_adaptivity_set_mode(rtwdev);
|
||||
rtw_phy_set_tx_power_level(rtwdev, hal->current_channel);
|
||||
}
|
||||
|
||||
u8 rtw_regd_get(struct rtw_dev *rtwdev)
|
||||
{
|
||||
struct rtw_hal *hal = &rtwdev->hal;
|
||||
u8 band = hal->current_band_type;
|
||||
|
||||
return band == RTW_BAND_2G ?
|
||||
rtwdev->regd.regulatory->txpwr_regd_2g :
|
||||
rtwdev->regd.regulatory->txpwr_regd_5g;
|
||||
}
|
||||
EXPORT_SYMBOL(rtw_regd_get);
|
||||
|
||||
struct rtw_regd_alternative_t {
|
||||
bool set;
|
||||
u8 alt;
|
||||
};
|
||||
|
||||
#define DECL_REGD_ALT(_regd, _regd_alt) \
|
||||
[(_regd)] = {.set = true, .alt = (_regd_alt)}
|
||||
|
||||
static const struct rtw_regd_alternative_t
|
||||
rtw_regd_alt[RTW_REGD_MAX] = {
|
||||
DECL_REGD_ALT(RTW_REGD_IC, RTW_REGD_FCC),
|
||||
DECL_REGD_ALT(RTW_REGD_KCC, RTW_REGD_ETSI),
|
||||
DECL_REGD_ALT(RTW_REGD_ACMA, RTW_REGD_ETSI),
|
||||
DECL_REGD_ALT(RTW_REGD_CHILE, RTW_REGD_FCC),
|
||||
DECL_REGD_ALT(RTW_REGD_UKRAINE, RTW_REGD_ETSI),
|
||||
DECL_REGD_ALT(RTW_REGD_MEXICO, RTW_REGD_FCC),
|
||||
DECL_REGD_ALT(RTW_REGD_CN, RTW_REGD_ETSI),
|
||||
};
|
||||
|
||||
bool rtw_regd_has_alt(u8 regd, u8 *regd_alt)
|
||||
{
|
||||
if (!rtw_regd_alt[regd].set)
|
||||
return false;
|
||||
|
||||
*regd_alt = rtw_regd_alt[regd].alt;
|
||||
return true;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -64,8 +64,8 @@ enum country_code_type {
|
|||
COUNTRY_CODE_MAX
|
||||
};
|
||||
|
||||
int rtw_regd_init(struct rtw_dev *rtwdev,
|
||||
void (*reg_notifier)(struct wiphy *wiphy,
|
||||
struct regulatory_request *request));
|
||||
void rtw_regd_notifier(struct wiphy *wiphy, struct regulatory_request *request);
|
||||
int rtw_regd_init(struct rtw_dev *rtwdev);
|
||||
int rtw_regd_hint(struct rtw_dev *rtwdev);
|
||||
u8 rtw_regd_get(struct rtw_dev *rtwdev);
|
||||
bool rtw_regd_has_alt(u8 regd, u8 *regd_alt);
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -14,6 +14,7 @@
|
|||
#include "reg.h"
|
||||
#include "debug.h"
|
||||
#include "bf.h"
|
||||
#include "regd.h"
|
||||
|
||||
static const s8 lna_gain_table_0[8] = {22, 8, -6, -22, -31, -40, -46, -52};
|
||||
static const s8 lna_gain_table_1[16] = {10, 6, 2, -2, -6, -10, -14, -17,
|
||||
|
|
@ -60,6 +61,9 @@ static int rtw8821c_read_efuse(struct rtw_dev *rtwdev, u8 *log_map)
|
|||
for (i = 0; i < 4; i++)
|
||||
efuse->txpwr_idx_table[i] = map->txpwr_idx_table[i];
|
||||
|
||||
if (rtwdev->efuse.rfe_option == 2 || rtwdev->efuse.rfe_option == 4)
|
||||
efuse->txpwr_idx_table[0].pwr_idx_2g = map->txpwr_idx_table[1].pwr_idx_2g;
|
||||
|
||||
switch (rtw_hci_type(rtwdev)) {
|
||||
case RTW_HCI_TYPE_PCIE:
|
||||
rtw8821ce_efuse_parsing(efuse, map);
|
||||
|
|
@ -304,7 +308,8 @@ static void rtw8821c_set_channel_rf(struct rtw_dev *rtwdev, u8 channel, u8 bw)
|
|||
if (channel <= 14) {
|
||||
if (rtwdev->efuse.rfe_option == 0)
|
||||
rtw8821c_switch_rf_set(rtwdev, SWITCH_TO_WLG);
|
||||
else if (rtwdev->efuse.rfe_option == 2)
|
||||
else if (rtwdev->efuse.rfe_option == 2 ||
|
||||
rtwdev->efuse.rfe_option == 4)
|
||||
rtw8821c_switch_rf_set(rtwdev, SWITCH_TO_BTG);
|
||||
rtw_write_rf(rtwdev, RF_PATH_A, RF_LUTDBG, BIT(6), 0x1);
|
||||
rtw_write_rf(rtwdev, RF_PATH_A, 0x64, 0xf, 0xf);
|
||||
|
|
@ -773,6 +778,15 @@ static void rtw8821c_coex_cfg_ant_switch(struct rtw_dev *rtwdev, u8 ctrl_type,
|
|||
if (switch_status == coex_dm->cur_switch_status)
|
||||
return;
|
||||
|
||||
if (coex_rfe->wlg_at_btg) {
|
||||
ctrl_type = COEX_SWITCH_CTRL_BY_BBSW;
|
||||
|
||||
if (coex_rfe->ant_switch_polarity)
|
||||
pos_type = COEX_SWITCH_TO_WLA;
|
||||
else
|
||||
pos_type = COEX_SWITCH_TO_WLG_BT;
|
||||
}
|
||||
|
||||
coex_dm->cur_switch_status = switch_status;
|
||||
|
||||
if (coex_rfe->ant_switch_diversity &&
|
||||
|
|
@ -993,7 +1007,7 @@ static void rtw8821c_pwrtrack_set(struct rtw_dev *rtwdev)
|
|||
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 regd = rtw_regd_get(rtwdev);
|
||||
u8 tx_rate = dm_info->tx_rate;
|
||||
u8 max_pwr_idx = rtwdev->chip->max_power_index;
|
||||
|
||||
|
|
@ -1498,6 +1512,7 @@ static const struct rtw_intf_phy_para_table phy_para_table_8821c = {
|
|||
static const struct rtw_rfe_def rtw8821c_rfe_defs[] = {
|
||||
[0] = RTW_DEF_RFE(8821c, 0, 0),
|
||||
[2] = RTW_DEF_RFE_EXT(8821c, 0, 0, 2),
|
||||
[4] = RTW_DEF_RFE_EXT(8821c, 0, 0, 2),
|
||||
};
|
||||
|
||||
static struct rtw_hw_reg rtw8821c_dig[] = {
|
||||
|
|
|
|||
|
|
@ -15,6 +15,7 @@
|
|||
#include "reg.h"
|
||||
#include "debug.h"
|
||||
#include "bf.h"
|
||||
#include "regd.h"
|
||||
|
||||
static void rtw8822b_config_trx_mode(struct rtw_dev *rtwdev, u8 tx_path,
|
||||
u8 rx_path, bool is_tx2_path);
|
||||
|
|
@ -1436,7 +1437,7 @@ static void rtw8822b_pwrtrack_set(struct rtw_dev *rtwdev, u8 path)
|
|||
u8 pwr_idx_offset, tx_pwr_idx;
|
||||
u8 channel = rtwdev->hal.current_channel;
|
||||
u8 band_width = rtwdev->hal.current_band_width;
|
||||
u8 regd = rtwdev->regd.txpwr_regd;
|
||||
u8 regd = rtw_regd_get(rtwdev);
|
||||
u8 tx_rate = dm_info->tx_rate;
|
||||
u8 max_pwr_idx = rtwdev->chip->max_power_index;
|
||||
|
||||
|
|
@ -1552,6 +1553,39 @@ static void rtw8822b_bf_config_bfee(struct rtw_dev *rtwdev, struct rtw_vif *vif,
|
|||
rtw_warn(rtwdev, "wrong bfee role\n");
|
||||
}
|
||||
|
||||
static void rtw8822b_adaptivity_init(struct rtw_dev *rtwdev)
|
||||
{
|
||||
rtw_phy_set_edcca_th(rtwdev, RTW8822B_EDCCA_MAX, RTW8822B_EDCCA_MAX);
|
||||
|
||||
/* mac edcca state setting */
|
||||
rtw_write32_clr(rtwdev, REG_TX_PTCL_CTRL, BIT_DIS_EDCCA);
|
||||
rtw_write32_set(rtwdev, REG_RD_CTRL, BIT_EDCCA_MSK_CNTDOWN_EN);
|
||||
rtw_write32_mask(rtwdev, REG_EDCCA_SOURCE, BIT_SOURCE_OPTION,
|
||||
RTW8822B_EDCCA_SRC_DEF);
|
||||
rtw_write32_mask(rtwdev, REG_EDCCA_POW_MA, BIT_MA_LEVEL, 0);
|
||||
|
||||
/* edcca decision opt */
|
||||
rtw_write32_set(rtwdev, REG_EDCCA_DECISION, BIT_EDCCA_OPTION);
|
||||
}
|
||||
|
||||
static void rtw8822b_adaptivity(struct rtw_dev *rtwdev)
|
||||
{
|
||||
struct rtw_dm_info *dm_info = &rtwdev->dm_info;
|
||||
s8 l2h, h2l;
|
||||
u8 igi;
|
||||
|
||||
igi = dm_info->igi_history[0];
|
||||
if (dm_info->edcca_mode == RTW_EDCCA_NORMAL) {
|
||||
l2h = max_t(s8, igi + EDCCA_IGI_L2H_DIFF, EDCCA_TH_L2H_LB);
|
||||
h2l = l2h - EDCCA_L2H_H2L_DIFF_NORMAL;
|
||||
} else {
|
||||
l2h = min_t(s8, igi, dm_info->l2h_th_ini);
|
||||
h2l = l2h - EDCCA_L2H_H2L_DIFF;
|
||||
}
|
||||
|
||||
rtw_phy_set_edcca_th(rtwdev, l2h, h2l);
|
||||
}
|
||||
|
||||
static const struct rtw_pwr_seq_cmd trans_carddis_to_cardemu_8822b[] = {
|
||||
{0x0086,
|
||||
RTW_PWR_CUT_ALL_MSK,
|
||||
|
|
@ -2125,6 +2159,8 @@ static struct rtw_chip_ops rtw8822b_ops = {
|
|||
.config_bfee = rtw8822b_bf_config_bfee,
|
||||
.set_gid_table = rtw_bf_set_gid_table,
|
||||
.cfg_csi_rate = rtw_bf_cfg_csi_rate,
|
||||
.adaptivity_init = rtw8822b_adaptivity_init,
|
||||
.adaptivity = rtw8822b_adaptivity,
|
||||
|
||||
.coex_set_init = rtw8822b_coex_cfg_init,
|
||||
.coex_set_ant_switch = rtw8822b_coex_cfg_ant_switch,
|
||||
|
|
@ -2454,6 +2490,11 @@ static const struct rtw_reg_domain coex_info_hw_regs_8822b[] = {
|
|||
{0xc50, MASKBYTE0, RTW_REG_DOMAIN_MAC8},
|
||||
};
|
||||
|
||||
static struct rtw_hw_reg_offset rtw8822b_edcca_th[] = {
|
||||
[EDCCA_TH_L2H_IDX] = {{.addr = 0x8a4, .mask = MASKBYTE0}, .offset = 0},
|
||||
[EDCCA_TH_H2L_IDX] = {{.addr = 0x8a4, .mask = MASKBYTE1}, .offset = 0},
|
||||
};
|
||||
|
||||
struct rtw_chip_info rtw8822b_hw_spec = {
|
||||
.ops = &rtw8822b_ops,
|
||||
.id = RTW_CHIP_TYPE_8822B,
|
||||
|
|
@ -2502,6 +2543,9 @@ struct rtw_chip_info rtw8822b_hw_spec = {
|
|||
.bfer_su_max_num = 2,
|
||||
.bfer_mu_max_num = 1,
|
||||
.rx_ldpc = true,
|
||||
.edcca_th = rtw8822b_edcca_th,
|
||||
.l2h_th_ini_cs = 10 + EDCCA_IGI_BASE,
|
||||
.l2h_th_ini_ad = -14 + EDCCA_IGI_BASE,
|
||||
|
||||
.coex_para_ver = 0x20070206,
|
||||
.bt_desired_ver = 0x6,
|
||||
|
|
|
|||
|
|
@ -140,6 +140,8 @@ _rtw_write32s_mask(struct rtw_dev *rtwdev, u32 addr, u32 mask, u32 data)
|
|||
#define GET_PHY_STAT_P1_RXSNR_B(phy_stat) \
|
||||
le32_get_bits(*((__le32 *)(phy_stat) + 0x06), GENMASK(15, 8))
|
||||
|
||||
#define RTW8822B_EDCCA_MAX 0x7f
|
||||
#define RTW8822B_EDCCA_SRC_DEF 1
|
||||
#define REG_HTSTFWT 0x800
|
||||
#define REG_RXPSEL 0x808
|
||||
#define BIT_RX_PSEL_RST (BIT(28) | BIT(29))
|
||||
|
|
@ -152,11 +154,17 @@ _rtw_write32s_mask(struct rtw_dev *rtwdev, u32 addr, u32 mask, u32 data)
|
|||
#define REG_L1PKWT 0x840
|
||||
#define REG_MRC 0x850
|
||||
#define REG_CLKTRK 0x860
|
||||
#define REG_EDCCA_POW_MA 0x8a0
|
||||
#define BIT_MA_LEVEL GENMASK(1, 0)
|
||||
#define REG_ADCCLK 0x8ac
|
||||
#define REG_ADC160 0x8c4
|
||||
#define REG_ADC40 0x8c8
|
||||
#define REG_EDCCA_DECISION 0x8dc
|
||||
#define BIT_EDCCA_OPTION BIT(5)
|
||||
#define REG_CDDTXP 0x93c
|
||||
#define REG_TXPSEL1 0x940
|
||||
#define REG_EDCCA_SOURCE 0x944
|
||||
#define BIT_SOURCE_OPTION GENMASK(29, 28)
|
||||
#define REG_ACBB0 0x948
|
||||
#define REG_ACBBRXFIR 0x94c
|
||||
#define REG_ACGG2TBL 0x958
|
||||
|
|
|
|||
|
|
@ -4497,6 +4497,39 @@ static void rtw8822c_pwr_track(struct rtw_dev *rtwdev)
|
|||
dm_info->pwr_trk_triggered = false;
|
||||
}
|
||||
|
||||
static void rtw8822c_adaptivity_init(struct rtw_dev *rtwdev)
|
||||
{
|
||||
rtw_phy_set_edcca_th(rtwdev, RTW8822C_EDCCA_MAX, RTW8822C_EDCCA_MAX);
|
||||
|
||||
/* mac edcca state setting */
|
||||
rtw_write32_clr(rtwdev, REG_TX_PTCL_CTRL, BIT_DIS_EDCCA);
|
||||
rtw_write32_set(rtwdev, REG_RD_CTRL, BIT_EDCCA_MSK_CNTDOWN_EN);
|
||||
|
||||
/* edcca decistion opt */
|
||||
rtw_write32_clr(rtwdev, REG_EDCCA_DECISION, BIT_EDCCA_OPTION);
|
||||
}
|
||||
|
||||
static void rtw8822c_adaptivity(struct rtw_dev *rtwdev)
|
||||
{
|
||||
struct rtw_dm_info *dm_info = &rtwdev->dm_info;
|
||||
s8 l2h, h2l;
|
||||
u8 igi;
|
||||
|
||||
igi = dm_info->igi_history[0];
|
||||
if (dm_info->edcca_mode == RTW_EDCCA_NORMAL) {
|
||||
l2h = max_t(s8, igi + EDCCA_IGI_L2H_DIFF, EDCCA_TH_L2H_LB);
|
||||
h2l = l2h - EDCCA_L2H_H2L_DIFF_NORMAL;
|
||||
} else {
|
||||
if (igi < dm_info->l2h_th_ini - EDCCA_ADC_BACKOFF)
|
||||
l2h = igi + EDCCA_ADC_BACKOFF;
|
||||
else
|
||||
l2h = dm_info->l2h_th_ini;
|
||||
h2l = l2h - EDCCA_L2H_H2L_DIFF;
|
||||
}
|
||||
|
||||
rtw_phy_set_edcca_th(rtwdev, l2h, h2l);
|
||||
}
|
||||
|
||||
static const struct rtw_pwr_seq_cmd trans_carddis_to_cardemu_8822c[] = {
|
||||
{0x0086,
|
||||
RTW_PWR_CUT_ALL_MSK,
|
||||
|
|
@ -4912,6 +4945,8 @@ static struct rtw_chip_ops rtw8822c_ops = {
|
|||
.config_bfee = rtw8822c_bf_config_bfee,
|
||||
.set_gid_table = rtw_bf_set_gid_table,
|
||||
.cfg_csi_rate = rtw_bf_cfg_csi_rate,
|
||||
.adaptivity_init = rtw8822c_adaptivity_init,
|
||||
.adaptivity = rtw8822c_adaptivity,
|
||||
.cfo_init = rtw8822c_cfo_init,
|
||||
.cfo_track = rtw8822c_cfo_track,
|
||||
.config_tx_path = rtw8822c_config_tx_path,
|
||||
|
|
@ -5197,6 +5232,15 @@ static const struct rtw_pwr_track_tbl rtw8822c_rtw_pwr_track_tbl = {
|
|||
.pwrtrk_2g_ccka_p = rtw8822c_pwrtrk_2g_cck_a_p,
|
||||
};
|
||||
|
||||
static struct rtw_hw_reg_offset rtw8822c_edcca_th[] = {
|
||||
[EDCCA_TH_L2H_IDX] = {
|
||||
{.addr = 0x84c, .mask = MASKBYTE2}, .offset = 0x80
|
||||
},
|
||||
[EDCCA_TH_H2L_IDX] = {
|
||||
{.addr = 0x84c, .mask = MASKBYTE3}, .offset = 0x80
|
||||
},
|
||||
};
|
||||
|
||||
#ifdef CONFIG_PM
|
||||
static const struct wiphy_wowlan_support rtw_wowlan_stub_8822c = {
|
||||
.flags = WIPHY_WOWLAN_MAGIC_PKT | WIPHY_WOWLAN_GTK_REKEY_FAILURE |
|
||||
|
|
@ -5289,6 +5333,9 @@ struct rtw_chip_info rtw8822c_hw_spec = {
|
|||
.bfer_mu_max_num = 1,
|
||||
.rx_ldpc = true,
|
||||
.tx_stbc = true,
|
||||
.edcca_th = rtw8822c_edcca_th,
|
||||
.l2h_th_ini_cs = 60,
|
||||
.l2h_th_ini_ad = 45,
|
||||
|
||||
#ifdef CONFIG_PM
|
||||
.wow_fw_name = "rtw88/rtw8822c_wow_fw.bin",
|
||||
|
|
|
|||
|
|
@ -162,6 +162,7 @@ const struct rtw_table name ## _tbl = { \
|
|||
#define GET_PHY_STAT_P1_RXSNR_B(phy_stat) \
|
||||
le32_get_bits(*((__le32 *)(phy_stat) + 0x06), GENMASK(15, 8))
|
||||
|
||||
#define RTW8822C_EDCCA_MAX 0x7f
|
||||
#define REG_ANAPARLDO_POW_MAC 0x0029
|
||||
#define BIT_LDOE25_PON BIT(0)
|
||||
#define XCAP_MASK GENMASK(6, 0)
|
||||
|
|
@ -174,6 +175,8 @@ const struct rtw_table name ## _tbl = { \
|
|||
#define REG_ANTMAP0 0x820
|
||||
#define BIT_ANT_PATH GENMASK(1, 0)
|
||||
#define REG_ANTMAP 0x824
|
||||
#define REG_EDCCA_DECISION 0x844
|
||||
#define BIT_EDCCA_OPTION GENMASK(30, 29)
|
||||
#define REG_DYMPRITH 0x86c
|
||||
#define REG_DYMENTH0 0x870
|
||||
#define REG_DYMENTH 0x874
|
||||
|
|
|
|||
|
|
@ -399,6 +399,8 @@ void rsi_core_xmit(struct rsi_common *common, struct sk_buff *skb)
|
|||
|
||||
info = IEEE80211_SKB_CB(skb);
|
||||
tx_params = (struct skb_info *)info->driver_data;
|
||||
/* info->driver_data and info->control part of union so make copy */
|
||||
tx_params->have_key = !!info->control.hw_key;
|
||||
wh = (struct ieee80211_hdr *)&skb->data[0];
|
||||
tx_params->sta_id = 0;
|
||||
|
||||
|
|
|
|||
|
|
@ -203,7 +203,7 @@ int rsi_prepare_data_desc(struct rsi_common *common, struct sk_buff *skb)
|
|||
wh->frame_control |= cpu_to_le16(RSI_SET_PS_ENABLE);
|
||||
|
||||
if ((!(info->flags & IEEE80211_TX_INTFL_DONT_ENCRYPT)) &&
|
||||
info->control.hw_key) {
|
||||
tx_params->have_key) {
|
||||
if (rsi_is_cipher_wep(common))
|
||||
ieee80211_size += 4;
|
||||
else
|
||||
|
|
@ -214,15 +214,17 @@ int rsi_prepare_data_desc(struct rsi_common *common, struct sk_buff *skb)
|
|||
RSI_WIFI_DATA_Q);
|
||||
data_desc->header_len = ieee80211_size;
|
||||
|
||||
if (common->min_rate != RSI_RATE_AUTO) {
|
||||
if (common->rate_config[common->band].fixed_enabled) {
|
||||
/* Send fixed rate */
|
||||
u16 fixed_rate = common->rate_config[common->band].fixed_hw_rate;
|
||||
|
||||
data_desc->frame_info = cpu_to_le16(RATE_INFO_ENABLE);
|
||||
data_desc->rate_info = cpu_to_le16(common->min_rate);
|
||||
data_desc->rate_info = cpu_to_le16(fixed_rate);
|
||||
|
||||
if (conf_is_ht40(&common->priv->hw->conf))
|
||||
data_desc->bbp_info = cpu_to_le16(FULL40M_ENABLE);
|
||||
|
||||
if ((common->vif_info[0].sgi) && (common->min_rate & 0x100)) {
|
||||
if (common->vif_info[0].sgi && (fixed_rate & 0x100)) {
|
||||
/* Only MCS rates */
|
||||
data_desc->rate_info |=
|
||||
cpu_to_le16(ENABLE_SHORTGI_RATE);
|
||||
|
|
|
|||
|
|
@ -510,7 +510,6 @@ static int rsi_mac80211_add_interface(struct ieee80211_hw *hw,
|
|||
if ((vif->type == NL80211_IFTYPE_AP) ||
|
||||
(vif->type == NL80211_IFTYPE_P2P_GO)) {
|
||||
rsi_send_rx_filter_frame(common, DISALLOW_BEACONS);
|
||||
common->min_rate = RSI_RATE_AUTO;
|
||||
for (i = 0; i < common->max_stations; i++)
|
||||
common->stations[i].sta = NULL;
|
||||
}
|
||||
|
|
@ -1228,20 +1227,32 @@ static int rsi_mac80211_set_rate_mask(struct ieee80211_hw *hw,
|
|||
struct ieee80211_vif *vif,
|
||||
const struct cfg80211_bitrate_mask *mask)
|
||||
{
|
||||
const unsigned int mcs_offset = ARRAY_SIZE(rsi_rates);
|
||||
struct rsi_hw *adapter = hw->priv;
|
||||
struct rsi_common *common = adapter->priv;
|
||||
enum nl80211_band band = hw->conf.chandef.chan->band;
|
||||
int i;
|
||||
|
||||
mutex_lock(&common->mutex);
|
||||
common->fixedrate_mask[band] = 0;
|
||||
|
||||
if (mask->control[band].legacy == 0xfff) {
|
||||
common->fixedrate_mask[band] =
|
||||
(mask->control[band].ht_mcs[0] << 12);
|
||||
} else {
|
||||
common->fixedrate_mask[band] =
|
||||
mask->control[band].legacy;
|
||||
for (i = 0; i < ARRAY_SIZE(common->rate_config); i++) {
|
||||
struct rsi_rate_config *cfg = &common->rate_config[i];
|
||||
u32 bm;
|
||||
|
||||
bm = mask->control[i].legacy | (mask->control[i].ht_mcs[0] << mcs_offset);
|
||||
if (hweight32(bm) == 1) { /* single rate */
|
||||
int rate_index = ffs(bm) - 1;
|
||||
|
||||
if (rate_index < mcs_offset)
|
||||
cfg->fixed_hw_rate = rsi_rates[rate_index].hw_value;
|
||||
else
|
||||
cfg->fixed_hw_rate = rsi_mcsrates[rate_index - mcs_offset];
|
||||
cfg->fixed_enabled = true;
|
||||
} else {
|
||||
cfg->configured_mask = bm;
|
||||
cfg->fixed_enabled = false;
|
||||
}
|
||||
}
|
||||
|
||||
mutex_unlock(&common->mutex);
|
||||
|
||||
return 0;
|
||||
|
|
@ -1378,46 +1389,6 @@ void rsi_indicate_pkt_to_os(struct rsi_common *common,
|
|||
ieee80211_rx_irqsafe(hw, skb);
|
||||
}
|
||||
|
||||
static void rsi_set_min_rate(struct ieee80211_hw *hw,
|
||||
struct ieee80211_sta *sta,
|
||||
struct rsi_common *common)
|
||||
{
|
||||
u8 band = hw->conf.chandef.chan->band;
|
||||
u8 ii;
|
||||
u32 rate_bitmap;
|
||||
bool matched = false;
|
||||
|
||||
common->bitrate_mask[band] = sta->supp_rates[band];
|
||||
|
||||
rate_bitmap = (common->fixedrate_mask[band] & sta->supp_rates[band]);
|
||||
|
||||
if (rate_bitmap & 0xfff) {
|
||||
/* Find out the min rate */
|
||||
for (ii = 0; ii < ARRAY_SIZE(rsi_rates); ii++) {
|
||||
if (rate_bitmap & BIT(ii)) {
|
||||
common->min_rate = rsi_rates[ii].hw_value;
|
||||
matched = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
common->vif_info[0].is_ht = sta->ht_cap.ht_supported;
|
||||
|
||||
if ((common->vif_info[0].is_ht) && (rate_bitmap >> 12)) {
|
||||
for (ii = 0; ii < ARRAY_SIZE(rsi_mcsrates); ii++) {
|
||||
if ((rate_bitmap >> 12) & BIT(ii)) {
|
||||
common->min_rate = rsi_mcsrates[ii];
|
||||
matched = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!matched)
|
||||
common->min_rate = 0xffff;
|
||||
}
|
||||
|
||||
/**
|
||||
* rsi_mac80211_sta_add() - This function notifies driver about a peer getting
|
||||
* connected.
|
||||
|
|
@ -1516,9 +1487,9 @@ static int rsi_mac80211_sta_add(struct ieee80211_hw *hw,
|
|||
|
||||
if ((vif->type == NL80211_IFTYPE_STATION) ||
|
||||
(vif->type == NL80211_IFTYPE_P2P_CLIENT)) {
|
||||
rsi_set_min_rate(hw, sta, common);
|
||||
common->bitrate_mask[common->band] = sta->supp_rates[common->band];
|
||||
common->vif_info[0].is_ht = sta->ht_cap.ht_supported;
|
||||
if (sta->ht_cap.ht_supported) {
|
||||
common->vif_info[0].is_ht = true;
|
||||
common->bitrate_mask[NL80211_BAND_2GHZ] =
|
||||
sta->supp_rates[NL80211_BAND_2GHZ];
|
||||
if ((sta->ht_cap.cap & IEEE80211_HT_CAP_SGI_20) ||
|
||||
|
|
@ -1592,7 +1563,6 @@ static int rsi_mac80211_sta_remove(struct ieee80211_hw *hw,
|
|||
bss->qos = sta->wme;
|
||||
common->bitrate_mask[NL80211_BAND_2GHZ] = 0;
|
||||
common->bitrate_mask[NL80211_BAND_5GHZ] = 0;
|
||||
common->min_rate = 0xffff;
|
||||
common->vif_info[0].is_ht = false;
|
||||
common->vif_info[0].sgi = false;
|
||||
common->vif_info[0].seq_start = 0;
|
||||
|
|
|
|||
|
|
@ -211,9 +211,10 @@ int rsi_read_pkt(struct rsi_common *common, u8 *rx_pkt, s32 rcv_pkt_len)
|
|||
bt_pkt_type = frame_desc[offset + BT_RX_PKT_TYPE_OFST];
|
||||
if (bt_pkt_type == BT_CARD_READY_IND) {
|
||||
rsi_dbg(INFO_ZONE, "BT Card ready recvd\n");
|
||||
if (rsi_bt_ops.attach(common, &g_proto_ops))
|
||||
rsi_dbg(ERR_ZONE,
|
||||
"Failed to attach BT module\n");
|
||||
if (common->fsm_state == FSM_MAC_INIT_DONE)
|
||||
rsi_attach_bt(common);
|
||||
else
|
||||
common->bt_defer_attach = true;
|
||||
} else {
|
||||
if (common->bt_adapter)
|
||||
rsi_bt_ops.recv_pkt(common->bt_adapter,
|
||||
|
|
@ -278,6 +279,15 @@ void rsi_set_bt_context(void *priv, void *bt_context)
|
|||
}
|
||||
#endif
|
||||
|
||||
void rsi_attach_bt(struct rsi_common *common)
|
||||
{
|
||||
#ifdef CONFIG_RSI_COEX
|
||||
if (rsi_bt_ops.attach(common, &g_proto_ops))
|
||||
rsi_dbg(ERR_ZONE,
|
||||
"Failed to attach BT module\n");
|
||||
#endif
|
||||
}
|
||||
|
||||
/**
|
||||
* rsi_91x_init() - This function initializes os interface operations.
|
||||
* @oper_mode: One of DEV_OPMODE_*.
|
||||
|
|
|
|||
|
|
@ -276,7 +276,7 @@ static void rsi_set_default_parameters(struct rsi_common *common)
|
|||
common->channel_width = BW_20MHZ;
|
||||
common->rts_threshold = IEEE80211_MAX_RTS_THRESHOLD;
|
||||
common->channel = 1;
|
||||
common->min_rate = 0xffff;
|
||||
memset(&common->rate_config, 0, sizeof(common->rate_config));
|
||||
common->fsm_state = FSM_CARD_NOT_READY;
|
||||
common->iface_down = true;
|
||||
common->endpoint = EP_2GHZ_20MHZ;
|
||||
|
|
@ -1314,7 +1314,7 @@ static int rsi_send_auto_rate_request(struct rsi_common *common,
|
|||
u8 band = hw->conf.chandef.chan->band;
|
||||
u8 num_supported_rates = 0;
|
||||
u8 rate_table_offset, rate_offset = 0;
|
||||
u32 rate_bitmap;
|
||||
u32 rate_bitmap, configured_rates;
|
||||
u16 *selected_rates, min_rate;
|
||||
bool is_ht = false, is_sgi = false;
|
||||
u16 frame_len = sizeof(struct rsi_auto_rate);
|
||||
|
|
@ -1364,6 +1364,10 @@ static int rsi_send_auto_rate_request(struct rsi_common *common,
|
|||
is_sgi = true;
|
||||
}
|
||||
|
||||
/* Limit to any rates administratively configured by cfg80211 */
|
||||
configured_rates = common->rate_config[band].configured_mask ?: 0xffffffff;
|
||||
rate_bitmap &= configured_rates;
|
||||
|
||||
if (band == NL80211_BAND_2GHZ) {
|
||||
if ((rate_bitmap == 0) && (is_ht))
|
||||
min_rate = RSI_RATE_MCS0;
|
||||
|
|
@ -1389,10 +1393,13 @@ static int rsi_send_auto_rate_request(struct rsi_common *common,
|
|||
num_supported_rates = jj;
|
||||
|
||||
if (is_ht) {
|
||||
for (ii = 0; ii < ARRAY_SIZE(mcs); ii++)
|
||||
selected_rates[jj++] = mcs[ii];
|
||||
num_supported_rates += ARRAY_SIZE(mcs);
|
||||
rate_offset += ARRAY_SIZE(mcs);
|
||||
for (ii = 0; ii < ARRAY_SIZE(mcs); ii++) {
|
||||
if (configured_rates & BIT(ii + ARRAY_SIZE(rsi_rates))) {
|
||||
selected_rates[jj++] = mcs[ii];
|
||||
num_supported_rates++;
|
||||
rate_offset++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
sort(selected_rates, jj, sizeof(u16), &rsi_compare, NULL);
|
||||
|
|
@ -1482,7 +1489,7 @@ void rsi_inform_bss_status(struct rsi_common *common,
|
|||
qos_enable,
|
||||
aid, sta_id,
|
||||
vif);
|
||||
if (common->min_rate == 0xffff)
|
||||
if (!common->rate_config[common->band].fixed_enabled)
|
||||
rsi_send_auto_rate_request(common, sta, sta_id, vif);
|
||||
if (opmode == RSI_OPMODE_STA &&
|
||||
!(assoc_cap & WLAN_CAPABILITY_PRIVACY) &&
|
||||
|
|
@ -2071,6 +2078,9 @@ static int rsi_handle_ta_confirm_type(struct rsi_common *common,
|
|||
if (common->reinit_hw) {
|
||||
complete(&common->wlan_init_completion);
|
||||
} else {
|
||||
if (common->bt_defer_attach)
|
||||
rsi_attach_bt(common);
|
||||
|
||||
return rsi_mac80211_attach(common);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -24,10 +24,7 @@
|
|||
/* Default operating mode is wlan STA + BT */
|
||||
static u16 dev_oper_mode = DEV_OPMODE_STA_BT_DUAL;
|
||||
module_param(dev_oper_mode, ushort, 0444);
|
||||
MODULE_PARM_DESC(dev_oper_mode,
|
||||
"1[Wi-Fi], 4[BT], 8[BT LE], 5[Wi-Fi STA + BT classic]\n"
|
||||
"9[Wi-Fi STA + BT LE], 13[Wi-Fi STA + BT classic + BT LE]\n"
|
||||
"6[AP + BT classic], 14[AP + BT classic + BT LE]");
|
||||
MODULE_PARM_DESC(dev_oper_mode, DEV_OPMODE_PARAM_DESC);
|
||||
|
||||
/**
|
||||
* rsi_sdio_set_cmd52_arg() - This function prepares cmd 52 read/write arg.
|
||||
|
|
|
|||
|
|
@ -25,10 +25,7 @@
|
|||
/* Default operating mode is wlan STA + BT */
|
||||
static u16 dev_oper_mode = DEV_OPMODE_STA_BT_DUAL;
|
||||
module_param(dev_oper_mode, ushort, 0444);
|
||||
MODULE_PARM_DESC(dev_oper_mode,
|
||||
"1[Wi-Fi], 4[BT], 8[BT LE], 5[Wi-Fi STA + BT classic]\n"
|
||||
"9[Wi-Fi STA + BT LE], 13[Wi-Fi STA + BT classic + BT LE]\n"
|
||||
"6[AP + BT classic], 14[AP + BT classic + BT LE]");
|
||||
MODULE_PARM_DESC(dev_oper_mode, DEV_OPMODE_PARAM_DESC);
|
||||
|
||||
static int rsi_rx_urb_submit(struct rsi_hw *adapter, u8 ep_num, gfp_t flags);
|
||||
|
||||
|
|
|
|||
|
|
@ -28,6 +28,17 @@
|
|||
#define DEV_OPMODE_AP_BT 6
|
||||
#define DEV_OPMODE_AP_BT_DUAL 14
|
||||
|
||||
#define DEV_OPMODE_PARAM_DESC \
|
||||
__stringify(DEV_OPMODE_WIFI_ALONE) "[Wi-Fi alone], " \
|
||||
__stringify(DEV_OPMODE_BT_ALONE) "[BT classic alone], " \
|
||||
__stringify(DEV_OPMODE_BT_LE_ALONE) "[BT LE alone], " \
|
||||
__stringify(DEV_OPMODE_BT_DUAL) "[BT classic + BT LE alone], " \
|
||||
__stringify(DEV_OPMODE_STA_BT) "[Wi-Fi STA + BT classic], " \
|
||||
__stringify(DEV_OPMODE_STA_BT_LE) "[Wi-Fi STA + BT LE], " \
|
||||
__stringify(DEV_OPMODE_STA_BT_DUAL) "[Wi-Fi STA + BT classic + BT LE], " \
|
||||
__stringify(DEV_OPMODE_AP_BT) "[Wi-Fi AP + BT classic], " \
|
||||
__stringify(DEV_OPMODE_AP_BT_DUAL) "[Wi-Fi AP + BT classic + BT LE]"
|
||||
|
||||
#define FLASH_WRITE_CHUNK_SIZE (4 * 1024)
|
||||
#define FLASH_SECTOR_SIZE (4 * 1024)
|
||||
|
||||
|
|
|
|||
|
|
@ -61,6 +61,7 @@ enum RSI_FSM_STATES {
|
|||
extern u32 rsi_zone_enabled;
|
||||
extern __printf(2, 3) void rsi_dbg(u32 zone, const char *fmt, ...);
|
||||
|
||||
#define RSI_MAX_BANDS 2
|
||||
#define RSI_MAX_VIFS 3
|
||||
#define NUM_EDCA_QUEUES 4
|
||||
#define IEEE80211_ADDR_LEN 6
|
||||
|
|
@ -139,6 +140,7 @@ struct skb_info {
|
|||
u8 internal_hdr_size;
|
||||
struct ieee80211_vif *vif;
|
||||
u8 vap_id;
|
||||
bool have_key;
|
||||
};
|
||||
|
||||
enum edca_queue {
|
||||
|
|
@ -229,6 +231,12 @@ struct rsi_9116_features {
|
|||
u32 ps_options;
|
||||
};
|
||||
|
||||
struct rsi_rate_config {
|
||||
u32 configured_mask; /* configured by mac80211 bits 0-11=legacy 12+ mcs */
|
||||
u16 fixed_hw_rate;
|
||||
bool fixed_enabled;
|
||||
};
|
||||
|
||||
struct rsi_common {
|
||||
struct rsi_hw *priv;
|
||||
struct vif_priv vif_info[RSI_MAX_VIFS];
|
||||
|
|
@ -254,8 +262,8 @@ struct rsi_common {
|
|||
u8 channel_width;
|
||||
|
||||
u16 rts_threshold;
|
||||
u16 bitrate_mask[2];
|
||||
u32 fixedrate_mask[2];
|
||||
u32 bitrate_mask[RSI_MAX_BANDS];
|
||||
struct rsi_rate_config rate_config[RSI_MAX_BANDS];
|
||||
|
||||
u8 rf_reset;
|
||||
struct transmit_q_stats tx_stats;
|
||||
|
|
@ -276,7 +284,6 @@ struct rsi_common {
|
|||
u8 mac_id;
|
||||
u8 radio_id;
|
||||
u16 rate_pwr[20];
|
||||
u16 min_rate;
|
||||
|
||||
/* WMM algo related */
|
||||
u8 selected_qnum;
|
||||
|
|
@ -320,6 +327,7 @@ struct rsi_common {
|
|||
struct ieee80211_vif *roc_vif;
|
||||
|
||||
bool eapol4_confirm;
|
||||
bool bt_defer_attach;
|
||||
void *bt_adapter;
|
||||
|
||||
struct cfg80211_scan_request *hwscan;
|
||||
|
|
@ -401,5 +409,6 @@ struct rsi_host_intf_ops {
|
|||
|
||||
enum rsi_host_intf rsi_get_host_intf(void *priv);
|
||||
void rsi_set_bt_context(void *priv, void *bt_context);
|
||||
void rsi_attach_bt(struct rsi_common *common);
|
||||
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -65,7 +65,6 @@ static const struct usb_device_id usb_ids[] = {
|
|||
{ USB_DEVICE(0x0586, 0x3412), .driver_info = DEVICE_ZD1211B },
|
||||
{ USB_DEVICE(0x0586, 0x3413), .driver_info = DEVICE_ZD1211B },
|
||||
{ USB_DEVICE(0x079b, 0x0062), .driver_info = DEVICE_ZD1211B },
|
||||
{ USB_DEVICE(0x07b8, 0x6001), .driver_info = DEVICE_ZD1211B },
|
||||
{ USB_DEVICE(0x07fa, 0x1196), .driver_info = DEVICE_ZD1211B },
|
||||
{ USB_DEVICE(0x083a, 0x4505), .driver_info = DEVICE_ZD1211B },
|
||||
{ USB_DEVICE(0x083a, 0xe501), .driver_info = DEVICE_ZD1211B },
|
||||
|
|
|
|||
|
|
@ -2084,6 +2084,7 @@ int ieee80211_get_vht_max_nss(struct ieee80211_vht_cap *cap,
|
|||
|
||||
#define IEEE80211_HE_VHT_MAX_AMPDU_FACTOR 20
|
||||
#define IEEE80211_HE_HT_MAX_AMPDU_FACTOR 16
|
||||
#define IEEE80211_HE_6GHZ_MAX_AMPDU_FACTOR 13
|
||||
|
||||
/* 802.11ax HE PHY capabilities */
|
||||
#define IEEE80211_HE_PHY_CAP0_CHANNEL_WIDTH_SET_40MHZ_IN_2G 0x02
|
||||
|
|
|
|||
|
|
@ -125,7 +125,7 @@ struct brcmfmac_pd_cc_entry {
|
|||
*/
|
||||
struct brcmfmac_pd_cc {
|
||||
int table_size;
|
||||
struct brcmfmac_pd_cc_entry table[0];
|
||||
struct brcmfmac_pd_cc_entry table[];
|
||||
};
|
||||
|
||||
/**
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user