wireless-drivers-next patches for v5.13

First set of patches for v5.13. I have been offline for a couple of
 and I have a smaller pull request this time. The next one will be
 bigger. Nothing really special standing out.
 
 ath11k
 
 * add initial support for QCN9074, but not enabled yet due to firmware problems
 
 * enable radar detection for 160MHz secondary segment
 
 * handle beacon misses in station mode
 
 rtw88
 
 * 8822c: support firmware crash dump
 
 mt7601u
 
 * enable TDLS support
 -----BEGIN PGP SIGNATURE-----
 Version: GnuPG v1
 
 iQEcBAABAgAGBQJgdSxyAAoJEG4XJFUm622bSIcH/1YFegVfAXx8YJmNUFaPbtka
 EZtG7t+5Dqv+hfO3fLvd0fq7Qbdcc0lodoCEBjyu6U0ylDydN+jtmwnwUexkfHQa
 Q1nl5Mc5JOpmQdiWG20VsQAKAedxYKck3LIESz9S3TmlGYn+V/nzse3WLpOWSvSR
 GVb2KZyd7s1h112Kh6zwEHfMw5h9yMq6+mR/lUU81inpCeMZQDZjXOvZ+ullyL/H
 avKftAwcmCmPVoz8n7H0xJgwDCf81nuriSUeu0H5xqTHL/tbGjHUCOS9N7xv0J6a
 9DiepfSOEXXUMpO8n4NQ1tVULDxut+fo8EZ6ocGAY2JT5F+6YUOcv3ouVc/26Yg=
 =6jDY
 -----END PGP SIGNATURE-----

Merge tag 'wireless-drivers-next-2021-04-13' of git://git.kernel.org/pub/scm/linux/kernel/git/kvalo/wireless-drivers-next

Kalle Valo says:

====================
wireless-drivers-next patches for v5.13

First set of patches for v5.13. I have been offline for a couple of
and I have a smaller pull request this time. The next one will be
bigger. Nothing really special standing out.

ath11k

* add initial support for QCN9074, but not enabled yet due to firmware problems

* enable radar detection for 160MHz secondary segment

* handle beacon misses in station mode

rtw88

* 8822c: support firmware crash dump

mt7601u

* enable TDLS support
====================

Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:
David S. Miller 2021-04-13 14:12:34 -07:00
commit 5fff4c14ae
50 changed files with 2708 additions and 870 deletions

View File

@ -1759,17 +1759,11 @@ err_core_destroy:
return ret;
}
static int ath10k_snoc_remove(struct platform_device *pdev)
static int ath10k_snoc_free_resources(struct ath10k *ar)
{
struct ath10k *ar = platform_get_drvdata(pdev);
struct ath10k_snoc *ar_snoc = ath10k_snoc_priv(ar);
ath10k_dbg(ar, ATH10K_DBG_SNOC, "snoc remove\n");
reinit_completion(&ar->driver_recovery);
if (test_bit(ATH10K_SNOC_FLAG_RECOVERY, &ar_snoc->flags))
wait_for_completion_timeout(&ar->driver_recovery, 3 * HZ);
ath10k_dbg(ar, ATH10K_DBG_SNOC, "snoc free resources\n");
set_bit(ATH10K_SNOC_FLAG_UNREGISTERING, &ar_snoc->flags);
@ -1783,12 +1777,29 @@ static int ath10k_snoc_remove(struct platform_device *pdev)
return 0;
}
static int ath10k_snoc_remove(struct platform_device *pdev)
{
struct ath10k *ar = platform_get_drvdata(pdev);
struct ath10k_snoc *ar_snoc = ath10k_snoc_priv(ar);
ath10k_dbg(ar, ATH10K_DBG_SNOC, "snoc remove\n");
reinit_completion(&ar->driver_recovery);
if (test_bit(ATH10K_SNOC_FLAG_RECOVERY, &ar_snoc->flags))
wait_for_completion_timeout(&ar->driver_recovery, 3 * HZ);
ath10k_snoc_free_resources(ar);
return 0;
}
static void ath10k_snoc_shutdown(struct platform_device *pdev)
{
struct ath10k *ar = platform_get_drvdata(pdev);
ath10k_dbg(ar, ATH10K_DBG_SNOC, "snoc shutdown\n");
ath10k_snoc_remove(pdev);
ath10k_snoc_free_resources(ar);
}
static struct platform_driver ath10k_snoc_driver = {

View File

@ -373,7 +373,7 @@ static void ath11k_ahb_init_qmi_ce_config(struct ath11k_base *ab)
cfg->tgt_ce = ab->hw_params.target_ce_config;
cfg->svc_to_ce_map_len = ab->hw_params.svc_to_ce_map_len;
cfg->svc_to_ce_map = ab->hw_params.svc_to_ce_map;
ab->qmi.service_ins_id = ATH11K_QMI_WLFW_SERVICE_INS_ID_V01_IPQ8074;
ab->qmi.service_ins_id = ab->hw_params.qmi_service_ins_id;
}
static void ath11k_ahb_free_ext_irq(struct ath11k_base *ab)

View File

@ -187,6 +187,59 @@ const struct ce_attr ath11k_host_ce_config_qca6390[] = {
};
const struct ce_attr ath11k_host_ce_config_qcn9074[] = {
/* CE0: host->target HTC control and raw streams */
{
.flags = CE_ATTR_FLAGS,
.src_nentries = 16,
.src_sz_max = 2048,
.dest_nentries = 0,
},
/* CE1: target->host HTT + HTC control */
{
.flags = CE_ATTR_FLAGS,
.src_nentries = 0,
.src_sz_max = 2048,
.dest_nentries = 512,
.recv_cb = ath11k_htc_rx_completion_handler,
},
/* CE2: target->host WMI */
{
.flags = CE_ATTR_FLAGS,
.src_nentries = 0,
.src_sz_max = 2048,
.dest_nentries = 32,
.recv_cb = ath11k_htc_rx_completion_handler,
},
/* CE3: host->target WMI (mac0) */
{
.flags = CE_ATTR_FLAGS,
.src_nentries = 32,
.src_sz_max = 2048,
.dest_nentries = 0,
},
/* CE4: host->target HTT */
{
.flags = CE_ATTR_FLAGS | CE_ATTR_DIS_INTR,
.src_nentries = 2048,
.src_sz_max = 256,
.dest_nentries = 0,
},
/* CE5: target->host pktlog */
{
.flags = CE_ATTR_FLAGS,
.src_nentries = 0,
.src_sz_max = 2048,
.dest_nentries = 512,
.recv_cb = ath11k_dp_htt_htc_t2h_msg_handler,
},
};
static bool ath11k_ce_need_shadow_fix(int ce_id)
{
/* only ce4 needs shadow workaroud*/
@ -455,7 +508,7 @@ static void ath11k_ce_srng_msi_ring_params_setup(struct ath11k_base *ab, u32 ce_
struct hal_srng_params *ring_params)
{
u32 msi_data_start;
u32 msi_data_count;
u32 msi_data_count, msi_data_idx;
u32 msi_irq_start;
u32 addr_lo;
u32 addr_hi;
@ -469,10 +522,11 @@ static void ath11k_ce_srng_msi_ring_params_setup(struct ath11k_base *ab, u32 ce_
return;
ath11k_get_msi_address(ab, &addr_lo, &addr_hi);
ath11k_get_ce_msi_idx(ab, ce_id, &msi_data_idx);
ring_params->msi_addr = addr_lo;
ring_params->msi_addr |= (dma_addr_t)(((uint64_t)addr_hi) << 32);
ring_params->msi_data = (ce_id % msi_data_count) + msi_data_start;
ring_params->msi_data = (msi_data_idx % msi_data_count) + msi_data_start;
ring_params->flags |= HAL_SRNG_FLAGS_MSI_INTR;
}

View File

@ -173,6 +173,7 @@ struct ath11k_ce {
extern const struct ce_attr ath11k_host_ce_config_ipq8074[];
extern const struct ce_attr ath11k_host_ce_config_qca6390[];
extern const struct ce_attr ath11k_host_ce_config_qcn9074[];
void ath11k_ce_cleanup_pipes(struct ath11k_base *ab);
void ath11k_ce_rx_replenish_retry(struct timer_list *t);

View File

@ -45,6 +45,7 @@ static const struct ath11k_hw_params ath11k_hw_params[] = {
.ring_mask = &ath11k_hw_ring_mask_ipq8074,
.internal_sleep_clock = false,
.regs = &ipq8074_regs,
.qmi_service_ins_id = ATH11K_QMI_WLFW_SERVICE_INS_ID_V01_IPQ8074,
.host_ce_config = ath11k_host_ce_config_ipq8074,
.ce_count = 12,
.target_ce_config = ath11k_target_ce_config_wlan_ipq8074,
@ -68,6 +69,7 @@ static const struct ath11k_hw_params ath11k_hw_params[] = {
.idle_ps = false,
.cold_boot_calib = true,
.supports_suspend = false,
.hal_desc_sz = sizeof(struct hal_rx_desc_ipq8074),
},
{
.hw_rev = ATH11K_HW_IPQ6018_HW10,
@ -83,6 +85,7 @@ static const struct ath11k_hw_params ath11k_hw_params[] = {
.ring_mask = &ath11k_hw_ring_mask_ipq8074,
.internal_sleep_clock = false,
.regs = &ipq8074_regs,
.qmi_service_ins_id = ATH11K_QMI_WLFW_SERVICE_INS_ID_V01_IPQ8074,
.host_ce_config = ath11k_host_ce_config_ipq8074,
.ce_count = 12,
.target_ce_config = ath11k_target_ce_config_wlan_ipq8074,
@ -106,6 +109,7 @@ static const struct ath11k_hw_params ath11k_hw_params[] = {
.idle_ps = false,
.cold_boot_calib = true,
.supports_suspend = false,
.hal_desc_sz = sizeof(struct hal_rx_desc_ipq8074),
},
{
.name = "qca6390 hw2.0",
@ -121,6 +125,7 @@ static const struct ath11k_hw_params ath11k_hw_params[] = {
.ring_mask = &ath11k_hw_ring_mask_qca6390,
.internal_sleep_clock = true,
.regs = &qca6390_regs,
.qmi_service_ins_id = ATH11K_QMI_WLFW_SERVICE_INS_ID_V01_QCA6390,
.host_ce_config = ath11k_host_ce_config_qca6390,
.ce_count = 9,
.target_ce_config = ath11k_target_ce_config_wlan_qca6390,
@ -143,6 +148,44 @@ static const struct ath11k_hw_params ath11k_hw_params[] = {
.idle_ps = true,
.cold_boot_calib = false,
.supports_suspend = true,
.hal_desc_sz = sizeof(struct hal_rx_desc_ipq8074),
},
{
.name = "qcn9074 hw1.0",
.hw_rev = ATH11K_HW_QCN9074_HW10,
.fw = {
.dir = "QCN9074/hw1.0",
.board_size = 256 * 1024,
.cal_size = 256 * 1024,
},
.max_radios = 1,
.single_pdev_only = false,
.qmi_service_ins_id = ATH11K_QMI_WLFW_SERVICE_INS_ID_V01_QCN9074,
.hw_ops = &qcn9074_ops,
.ring_mask = &ath11k_hw_ring_mask_qcn9074,
.internal_sleep_clock = false,
.regs = &qcn9074_regs,
.host_ce_config = ath11k_host_ce_config_qcn9074,
.ce_count = 6,
.target_ce_config = ath11k_target_ce_config_wlan_qcn9074,
.target_ce_count = 9,
.svc_to_ce_map = ath11k_target_service_to_ce_map_wlan_qcn9074,
.svc_to_ce_map_len = 18,
.rxdma1_enable = true,
.num_rxmda_per_pdev = 1,
.rx_mac_buf_ring = false,
.vdev_start_delay = false,
.htt_peer_map_v2 = true,
.tcl_0_only = false,
.interface_modes = BIT(NL80211_IFTYPE_STATION) |
BIT(NL80211_IFTYPE_AP) |
BIT(NL80211_IFTYPE_MESH_POINT),
.supports_monitor = true,
.supports_shadow_regs = false,
.idle_ps = false,
.cold_boot_calib = false,
.supports_suspend = false,
.hal_desc_sz = sizeof(struct hal_rx_desc_qcn9074),
},
};
@ -974,7 +1017,7 @@ static int ath11k_init_hw_params(struct ath11k_base *ab)
ab->hw_params = *hw_params;
ath11k_dbg(ab, ATH11K_DBG_BOOT, "Hardware name %s\n", ab->hw_params.name);
ath11k_info(ab, "%s\n", ab->hw_params.name);
return 0;
}

View File

@ -34,6 +34,7 @@
#define ATH11K_PRB_RSP_DROP_THRESHOLD ((ATH11K_TX_MGMT_TARGET_MAX_SUPPORT_WMI * 3) / 4)
#define ATH11K_INVALID_HW_MAC_ID 0xFF
#define ATH11K_CONNECTION_LOSS_HZ (3 * HZ)
extern unsigned int ath11k_frame_mode;
@ -105,6 +106,7 @@ enum ath11k_hw_rev {
ATH11K_HW_IPQ8074,
ATH11K_HW_QCA6390_HW20,
ATH11K_HW_IPQ6018_HW10,
ATH11K_HW_QCN9074_HW10,
};
enum ath11k_firmware_mode {
@ -234,6 +236,7 @@ struct ath11k_vif {
u32 aid;
u8 bssid[ETH_ALEN];
struct cfg80211_bitrate_mask bitrate_mask;
struct delayed_work connection_loss_work;
int num_legacy_stations;
int rtscts_prot_mode;
int txpower;
@ -607,6 +610,7 @@ struct ath11k_bus_params {
bool m3_fw_support;
bool fixed_bdf_addr;
bool fixed_mem_region;
bool static_window_map;
};
/* IPQ8074 HW channel counters frequency value in hertz */
@ -876,6 +880,8 @@ extern const struct service_to_pipe ath11k_target_service_to_ce_map_wlan_ipq6018
extern const struct ce_pipe_config ath11k_target_ce_config_wlan_qca6390[];
extern const struct service_to_pipe ath11k_target_service_to_ce_map_wlan_qca6390[];
extern const struct ce_pipe_config ath11k_target_ce_config_wlan_qcn9074[];
extern const struct service_to_pipe ath11k_target_service_to_ce_map_wlan_qcn9074[];
int ath11k_core_qmi_firmware_ready(struct ath11k_base *ab);
int ath11k_core_pre_init(struct ath11k_base *ab);
int ath11k_core_init(struct ath11k_base *ath11k);

View File

@ -3851,7 +3851,7 @@ htt_print_pdev_obss_pd_stats_tlv_v(const void *tag_buf,
htt_stats_buf->num_non_srg_ppdu_tried);
len += HTT_DBG_OUT(buf + len, buf_len - len, "Non-SRG success PPDU = %u\n",
htt_stats_buf->num_non_srg_ppdu_success);
len += HTT_DBG_OUT(buf + len, buf_len - len, "SRG Opportunies = %u\n",
len += HTT_DBG_OUT(buf + len, buf_len - len, "SRG Opportunities = %u\n",
htt_stats_buf->num_srg_opportunities);
len += HTT_DBG_OUT(buf + len, buf_len - len, "SRG tried PPDU = %u\n",
htt_stats_buf->num_srg_ppdu_tried);

File diff suppressed because it is too large Load Diff

View File

@ -178,7 +178,7 @@ tcl_ring_sel:
}
if (ieee80211_vif_is_mesh(arvif->vif))
ti.flags1 |= FIELD_PREP(HAL_TCL_DATA_CMD_INFO2_MESH_ENABLE, 1);
ti.enable_mesh = true;
ti.flags1 |= FIELD_PREP(HAL_TCL_DATA_CMD_INFO2_TID_OVERWRITE, 1);
@ -792,8 +792,8 @@ int ath11k_dp_tx_htt_srng_setup(struct ath11k_base *ab, u32 ring_id,
cmd->ring_tail_off32_remote_addr_hi = (u64)tp_addr >>
HAL_ADDR_MSB_REG_SHIFT;
cmd->ring_msi_addr_lo = params.msi_addr & 0xffffffff;
cmd->ring_msi_addr_hi = ((uint64_t)(params.msi_addr) >> 32) & 0xffffffff;
cmd->ring_msi_addr_lo = lower_32_bits(params.msi_addr);
cmd->ring_msi_addr_hi = upper_32_bits(params.msi_addr);
cmd->msi_data = params.msi_data;
cmd->intr_info = FIELD_PREP(

View File

@ -89,17 +89,6 @@ static const struct hal_srng_config hw_srng_config_template[] = {
.entry_size = sizeof(struct hal_ce_srng_src_desc) >> 2,
.lmac_ring = false,
.ring_dir = HAL_SRNG_DIR_SRC,
.reg_start = {
(HAL_SEQ_WCSS_UMAC_CE0_SRC_REG +
HAL_CE_DST_RING_BASE_LSB),
HAL_SEQ_WCSS_UMAC_CE0_SRC_REG + HAL_CE_DST_RING_HP,
},
.reg_size = {
(HAL_SEQ_WCSS_UMAC_CE1_SRC_REG -
HAL_SEQ_WCSS_UMAC_CE0_SRC_REG),
(HAL_SEQ_WCSS_UMAC_CE1_SRC_REG -
HAL_SEQ_WCSS_UMAC_CE0_SRC_REG),
},
.max_size = HAL_CE_SRC_RING_BASE_MSB_RING_SIZE,
},
{ /* CE_DST */
@ -108,17 +97,6 @@ static const struct hal_srng_config hw_srng_config_template[] = {
.entry_size = sizeof(struct hal_ce_srng_dest_desc) >> 2,
.lmac_ring = false,
.ring_dir = HAL_SRNG_DIR_SRC,
.reg_start = {
(HAL_SEQ_WCSS_UMAC_CE0_DST_REG +
HAL_CE_DST_RING_BASE_LSB),
HAL_SEQ_WCSS_UMAC_CE0_DST_REG + HAL_CE_DST_RING_HP,
},
.reg_size = {
(HAL_SEQ_WCSS_UMAC_CE1_DST_REG -
HAL_SEQ_WCSS_UMAC_CE0_DST_REG),
(HAL_SEQ_WCSS_UMAC_CE1_DST_REG -
HAL_SEQ_WCSS_UMAC_CE0_DST_REG),
},
.max_size = HAL_CE_DST_RING_BASE_MSB_RING_SIZE,
},
{ /* CE_DST_STATUS */
@ -127,18 +105,6 @@ static const struct hal_srng_config hw_srng_config_template[] = {
.entry_size = sizeof(struct hal_ce_srng_dst_status_desc) >> 2,
.lmac_ring = false,
.ring_dir = HAL_SRNG_DIR_DST,
.reg_start = {
(HAL_SEQ_WCSS_UMAC_CE0_DST_REG +
HAL_CE_DST_STATUS_RING_BASE_LSB),
(HAL_SEQ_WCSS_UMAC_CE0_DST_REG +
HAL_CE_DST_STATUS_RING_HP),
},
.reg_size = {
(HAL_SEQ_WCSS_UMAC_CE1_DST_REG -
HAL_SEQ_WCSS_UMAC_CE0_DST_REG),
(HAL_SEQ_WCSS_UMAC_CE1_DST_REG -
HAL_SEQ_WCSS_UMAC_CE0_DST_REG),
},
.max_size = HAL_CE_DST_STATUS_RING_BASE_MSB_RING_SIZE,
},
{ /* WBM_IDLE_LINK */
@ -147,11 +113,6 @@ static const struct hal_srng_config hw_srng_config_template[] = {
.entry_size = sizeof(struct hal_wbm_link_desc) >> 2,
.lmac_ring = false,
.ring_dir = HAL_SRNG_DIR_SRC,
.reg_start = {
(HAL_SEQ_WCSS_UMAC_WBM_REG +
HAL_WBM_IDLE_LINK_RING_BASE_LSB),
(HAL_SEQ_WCSS_UMAC_WBM_REG + HAL_WBM_IDLE_LINK_RING_HP),
},
.max_size = HAL_WBM_IDLE_LINK_RING_BASE_MSB_RING_SIZE,
},
{ /* SW2WBM_RELEASE */
@ -160,11 +121,6 @@ static const struct hal_srng_config hw_srng_config_template[] = {
.entry_size = sizeof(struct hal_wbm_release_ring) >> 2,
.lmac_ring = false,
.ring_dir = HAL_SRNG_DIR_SRC,
.reg_start = {
(HAL_SEQ_WCSS_UMAC_WBM_REG +
HAL_WBM_RELEASE_RING_BASE_LSB),
(HAL_SEQ_WCSS_UMAC_WBM_REG + HAL_WBM_RELEASE_RING_HP),
},
.max_size = HAL_SW2WBM_RELEASE_RING_BASE_MSB_RING_SIZE,
},
{ /* WBM2SW_RELEASE */
@ -173,16 +129,6 @@ static const struct hal_srng_config hw_srng_config_template[] = {
.entry_size = sizeof(struct hal_wbm_release_ring) >> 2,
.lmac_ring = false,
.ring_dir = HAL_SRNG_DIR_DST,
.reg_start = {
(HAL_SEQ_WCSS_UMAC_WBM_REG +
HAL_WBM0_RELEASE_RING_BASE_LSB),
(HAL_SEQ_WCSS_UMAC_WBM_REG + HAL_WBM0_RELEASE_RING_HP),
},
.reg_size = {
(HAL_WBM1_RELEASE_RING_BASE_LSB -
HAL_WBM0_RELEASE_RING_BASE_LSB),
(HAL_WBM1_RELEASE_RING_HP - HAL_WBM0_RELEASE_RING_HP),
},
.max_size = HAL_WBM2SW_RELEASE_RING_BASE_MSB_RING_SIZE,
},
{ /* RXDMA_BUF */
@ -955,7 +901,7 @@ void ath11k_hal_setup_link_idle_list(struct ath11k_base *ab,
/* Enable the SRNG */
ath11k_hif_write32(ab,
HAL_SEQ_WCSS_UMAC_WBM_REG +
HAL_WBM_IDLE_LINK_RING_MISC_ADDR, 0x40);
HAL_WBM_IDLE_LINK_RING_MISC_ADDR(ab), 0x40);
}
int ath11k_hal_srng_setup(struct ath11k_base *ab, enum hal_ring_type type,
@ -1234,6 +1180,46 @@ static int ath11k_hal_srng_create_config(struct ath11k_base *ab)
s->reg_start[0] = HAL_SEQ_WCSS_UMAC_TCL_REG + HAL_TCL_STATUS_RING_BASE_LSB(ab);
s->reg_start[1] = HAL_SEQ_WCSS_UMAC_TCL_REG + HAL_TCL_STATUS_RING_HP;
s = &hal->srng_config[HAL_CE_SRC];
s->reg_start[0] = HAL_SEQ_WCSS_UMAC_CE0_SRC_REG(ab) + HAL_CE_DST_RING_BASE_LSB;
s->reg_start[1] = HAL_SEQ_WCSS_UMAC_CE0_SRC_REG(ab) + HAL_CE_DST_RING_HP;
s->reg_size[0] = HAL_SEQ_WCSS_UMAC_CE1_SRC_REG(ab) -
HAL_SEQ_WCSS_UMAC_CE0_SRC_REG(ab);
s->reg_size[1] = HAL_SEQ_WCSS_UMAC_CE1_SRC_REG(ab) -
HAL_SEQ_WCSS_UMAC_CE0_SRC_REG(ab);
s = &hal->srng_config[HAL_CE_DST];
s->reg_start[0] = HAL_SEQ_WCSS_UMAC_CE0_DST_REG(ab) + HAL_CE_DST_RING_BASE_LSB;
s->reg_start[1] = HAL_SEQ_WCSS_UMAC_CE0_DST_REG(ab) + HAL_CE_DST_RING_HP;
s->reg_size[0] = HAL_SEQ_WCSS_UMAC_CE1_DST_REG(ab) -
HAL_SEQ_WCSS_UMAC_CE0_DST_REG(ab);
s->reg_size[1] = HAL_SEQ_WCSS_UMAC_CE1_DST_REG(ab) -
HAL_SEQ_WCSS_UMAC_CE0_DST_REG(ab);
s = &hal->srng_config[HAL_CE_DST_STATUS];
s->reg_start[0] = HAL_SEQ_WCSS_UMAC_CE0_DST_REG(ab) +
HAL_CE_DST_STATUS_RING_BASE_LSB;
s->reg_start[1] = HAL_SEQ_WCSS_UMAC_CE0_DST_REG(ab) + HAL_CE_DST_STATUS_RING_HP;
s->reg_size[0] = HAL_SEQ_WCSS_UMAC_CE1_DST_REG(ab) -
HAL_SEQ_WCSS_UMAC_CE0_DST_REG(ab);
s->reg_size[1] = HAL_SEQ_WCSS_UMAC_CE1_DST_REG(ab) -
HAL_SEQ_WCSS_UMAC_CE0_DST_REG(ab);
s = &hal->srng_config[HAL_WBM_IDLE_LINK];
s->reg_start[0] = HAL_SEQ_WCSS_UMAC_WBM_REG + HAL_WBM_IDLE_LINK_RING_BASE_LSB(ab);
s->reg_start[1] = HAL_SEQ_WCSS_UMAC_WBM_REG + HAL_WBM_IDLE_LINK_RING_HP;
s = &hal->srng_config[HAL_SW2WBM_RELEASE];
s->reg_start[0] = HAL_SEQ_WCSS_UMAC_WBM_REG + HAL_WBM_RELEASE_RING_BASE_LSB(ab);
s->reg_start[1] = HAL_SEQ_WCSS_UMAC_WBM_REG + HAL_WBM_RELEASE_RING_HP;
s = &hal->srng_config[HAL_WBM2SW_RELEASE];
s->reg_start[0] = HAL_SEQ_WCSS_UMAC_WBM_REG + HAL_WBM0_RELEASE_RING_BASE_LSB(ab);
s->reg_start[1] = HAL_SEQ_WCSS_UMAC_WBM_REG + HAL_WBM0_RELEASE_RING_HP;
s->reg_size[0] = HAL_WBM1_RELEASE_RING_BASE_LSB(ab) -
HAL_WBM0_RELEASE_RING_BASE_LSB(ab);
s->reg_size[1] = HAL_WBM1_RELEASE_RING_HP - HAL_WBM0_RELEASE_RING_HP;
return 0;
}

View File

@ -39,14 +39,22 @@ struct ath11k_base;
#define HAL_SHADOW_REG(x) (HAL_SHADOW_BASE_ADDR + (4 * (x)))
/* WCSS Relative address */
#define HAL_SEQ_WCSS_UMAC_OFFSET 0x00a00000
#define HAL_SEQ_WCSS_UMAC_REO_REG 0x00a38000
#define HAL_SEQ_WCSS_UMAC_TCL_REG 0x00a44000
#define HAL_SEQ_WCSS_UMAC_CE0_SRC_REG 0x00a00000
#define HAL_SEQ_WCSS_UMAC_CE0_DST_REG 0x00a01000
#define HAL_SEQ_WCSS_UMAC_CE1_SRC_REG 0x00a02000
#define HAL_SEQ_WCSS_UMAC_CE1_DST_REG 0x00a03000
#define HAL_SEQ_WCSS_UMAC_CE0_SRC_REG(x) \
(ab->hw_params.regs->hal_seq_wcss_umac_ce0_src_reg)
#define HAL_SEQ_WCSS_UMAC_CE0_DST_REG(x) \
(ab->hw_params.regs->hal_seq_wcss_umac_ce0_dst_reg)
#define HAL_SEQ_WCSS_UMAC_CE1_SRC_REG(x) \
(ab->hw_params.regs->hal_seq_wcss_umac_ce1_src_reg)
#define HAL_SEQ_WCSS_UMAC_CE1_DST_REG(x) \
(ab->hw_params.regs->hal_seq_wcss_umac_ce1_dst_reg)
#define HAL_SEQ_WCSS_UMAC_WBM_REG 0x00a34000
#define HAL_CE_WFSS_CE_REG_BASE 0x01b80000
#define HAL_WLAON_REG_BASE 0x01f80000
/* SW2TCL(x) R0 ring configuration address */
#define HAL_TCL1_RING_CMN_CTRL_REG 0x00000014
#define HAL_TCL1_RING_DSCP_TID_MAP 0x0000002c
@ -197,8 +205,10 @@ struct ath11k_base;
#define HAL_REO_STATUS_HP(ab) ab->hw_params.regs->hal_reo_status_hp
/* WBM Idle R0 address */
#define HAL_WBM_IDLE_LINK_RING_BASE_LSB 0x00000860
#define HAL_WBM_IDLE_LINK_RING_MISC_ADDR 0x00000870
#define HAL_WBM_IDLE_LINK_RING_BASE_LSB(x) \
(ab->hw_params.regs->hal_wbm_idle_link_ring_base_lsb)
#define HAL_WBM_IDLE_LINK_RING_MISC_ADDR(x) \
(ab->hw_params.regs->hal_wbm_idle_link_ring_misc)
#define HAL_WBM_R0_IDLE_LIST_CONTROL_ADDR 0x00000048
#define HAL_WBM_R0_IDLE_LIST_SIZE_ADDR 0x0000004c
#define HAL_WBM_SCATTERED_RING_BASE_LSB 0x00000058
@ -213,14 +223,17 @@ struct ath11k_base;
#define HAL_WBM_IDLE_LINK_RING_HP 0x000030b0
/* SW2WBM R0 release address */
#define HAL_WBM_RELEASE_RING_BASE_LSB 0x000001d8
#define HAL_WBM_RELEASE_RING_BASE_LSB(x) \
(ab->hw_params.regs->hal_wbm_release_ring_base_lsb)
/* SW2WBM R2 release address */
#define HAL_WBM_RELEASE_RING_HP 0x00003018
/* WBM2SW R0 release address */
#define HAL_WBM0_RELEASE_RING_BASE_LSB 0x00000910
#define HAL_WBM1_RELEASE_RING_BASE_LSB 0x00000968
#define HAL_WBM0_RELEASE_RING_BASE_LSB(x) \
(ab->hw_params.regs->hal_wbm0_release_ring_base_lsb)
#define HAL_WBM1_RELEASE_RING_BASE_LSB(x) \
(ab->hw_params.regs->hal_wbm1_release_ring_base_lsb)
/* WBM2SW R2 release address */
#define HAL_WBM0_RELEASE_RING_HP 0x000030c0
@ -303,8 +316,6 @@ struct ath11k_base;
#define HAL_WBM2SW_RELEASE_RING_BASE_MSB_RING_SIZE 0x000fffff
#define HAL_RXDMA_RING_MAX_SIZE 0x0000ffff
#define HAL_RX_DESC_SIZE (sizeof(struct hal_rx_desc))
/* Add any other errors here and return them in
* ath11k_hal_rx_desc_get_err().
*/

View File

@ -949,16 +949,17 @@ struct hal_reo_flush_cache {
#define HAL_TCL_DATA_CMD_INFO1_TO_FW BIT(21)
#define HAL_TCL_DATA_CMD_INFO1_PKT_OFFSET GENMASK(31, 23)
#define HAL_TCL_DATA_CMD_INFO2_BUF_TIMESTAMP GENMASK(18, 0)
#define HAL_TCL_DATA_CMD_INFO2_BUF_T_VALID BIT(19)
#define HAL_TCL_DATA_CMD_INFO2_MESH_ENABLE BIT(20)
#define HAL_TCL_DATA_CMD_INFO2_TID_OVERWRITE BIT(21)
#define HAL_TCL_DATA_CMD_INFO2_TID GENMASK(25, 22)
#define HAL_TCL_DATA_CMD_INFO2_LMAC_ID GENMASK(27, 26)
#define HAL_TCL_DATA_CMD_INFO2_BUF_TIMESTAMP GENMASK(18, 0)
#define HAL_TCL_DATA_CMD_INFO2_BUF_T_VALID BIT(19)
#define HAL_IPQ8074_TCL_DATA_CMD_INFO2_MESH_ENABLE BIT(20)
#define HAL_TCL_DATA_CMD_INFO2_TID_OVERWRITE BIT(21)
#define HAL_TCL_DATA_CMD_INFO2_TID GENMASK(25, 22)
#define HAL_TCL_DATA_CMD_INFO2_LMAC_ID GENMASK(27, 26)
#define HAL_TCL_DATA_CMD_INFO3_DSCP_TID_TABLE_IDX GENMASK(5, 0)
#define HAL_TCL_DATA_CMD_INFO3_SEARCH_INDEX GENMASK(25, 6)
#define HAL_TCL_DATA_CMD_INFO3_CACHE_SET_NUM GENMASK(29, 26)
#define HAL_QCN9074_TCL_DATA_CMD_INFO3_MESH_ENABLE GENMASK(31, 30)
#define HAL_TCL_DATA_CMD_INFO4_RING_ID GENMASK(27, 20)
#define HAL_TCL_DATA_CMD_INFO4_LOOPING_COUNT GENMASK(31, 28)

View File

@ -75,6 +75,9 @@ void ath11k_hal_tx_cmd_desc_setup(struct ath11k_base *ab, void *cmd,
FIELD_PREP(HAL_TCL_DATA_CMD_INFO3_CACHE_SET_NUM,
ti->bss_ast_hash);
tcl_cmd->info4 = 0;
if (ti->enable_mesh)
ab->hw_params.hw_ops->tx_mesh_enable(ab, tcl_cmd);
}
void ath11k_hal_tx_set_dscp_tid_map(struct ath11k_base *ab, int id)

View File

@ -34,6 +34,7 @@ struct hal_tx_info {
u8 search_type; /* %HAL_TX_ADDR_SEARCH_ */
u8 lmac_id;
u8 dscp_tid_tbl_idx;
bool enable_mesh;
};
/* TODO: Check if the actual desc macros can be used instead */

View File

@ -28,6 +28,7 @@ struct ath11k_hif_ops {
u32 *msi_addr_hi);
void (*ce_irq_enable)(struct ath11k_base *ab);
void (*ce_irq_disable)(struct ath11k_base *ab);
void (*get_ce_msi_idx)(struct ath11k_base *ab, u32 ce_id, u32 *msi_idx);
};
static inline void ath11k_hif_ce_irq_enable(struct ath11k_base *ab)
@ -124,4 +125,13 @@ static inline void ath11k_get_msi_address(struct ath11k_base *ab, u32 *msi_addr_
ab->hif.ops->get_msi_address(ab, msi_addr_lo, msi_addr_hi);
}
static inline void ath11k_get_ce_msi_idx(struct ath11k_base *ab, u32 ce_id,
u32 *msi_data_idx)
{
if (ab->hif.ops->get_ce_msi_idx)
ab->hif.ops->get_ce_msi_idx(ab, ce_id, msi_data_idx);
else
*msi_data_idx = ce_id;
}
#endif /* _HIF_H_ */

View File

@ -31,6 +31,20 @@ static u8 ath11k_hw_ipq6018_mac_from_pdev_id(int pdev_idx)
return pdev_idx;
}
static void ath11k_hw_ipq8074_tx_mesh_enable(struct ath11k_base *ab,
struct hal_tcl_data_cmd *tcl_cmd)
{
tcl_cmd->info2 |= FIELD_PREP(HAL_IPQ8074_TCL_DATA_CMD_INFO2_MESH_ENABLE,
true);
}
static void ath11k_hw_qcn9074_tx_mesh_enable(struct ath11k_base *ab,
struct hal_tcl_data_cmd *tcl_cmd)
{
tcl_cmd->info3 |= FIELD_PREP(HAL_QCN9074_TCL_DATA_CMD_INFO3_MESH_ENABLE,
true);
}
static void ath11k_init_wmi_config_qca6390(struct ath11k_base *ab,
struct target_resource_config *config)
{
@ -155,11 +169,358 @@ static int ath11k_hw_mac_id_to_srng_id_qca6390(struct ath11k_hw_params *hw,
return mac_id;
}
static bool ath11k_hw_ipq8074_rx_desc_get_first_msdu(struct hal_rx_desc *desc)
{
return !!FIELD_GET(RX_MSDU_END_INFO2_FIRST_MSDU,
__le32_to_cpu(desc->u.ipq8074.msdu_end.info2));
}
static bool ath11k_hw_ipq8074_rx_desc_get_last_msdu(struct hal_rx_desc *desc)
{
return !!FIELD_GET(RX_MSDU_END_INFO2_LAST_MSDU,
__le32_to_cpu(desc->u.ipq8074.msdu_end.info2));
}
static u8 ath11k_hw_ipq8074_rx_desc_get_l3_pad_bytes(struct hal_rx_desc *desc)
{
return FIELD_GET(RX_MSDU_END_INFO2_L3_HDR_PADDING,
__le32_to_cpu(desc->u.ipq8074.msdu_end.info2));
}
static u8 *ath11k_hw_ipq8074_rx_desc_get_hdr_status(struct hal_rx_desc *desc)
{
return desc->u.ipq8074.hdr_status;
}
static bool ath11k_hw_ipq8074_rx_desc_encrypt_valid(struct hal_rx_desc *desc)
{
return __le32_to_cpu(desc->u.ipq8074.mpdu_start.info1) &
RX_MPDU_START_INFO1_ENCRYPT_INFO_VALID;
}
static u32 ath11k_hw_ipq8074_rx_desc_get_encrypt_type(struct hal_rx_desc *desc)
{
return FIELD_GET(RX_MPDU_START_INFO2_ENC_TYPE,
__le32_to_cpu(desc->u.ipq8074.mpdu_start.info2));
}
static u8 ath11k_hw_ipq8074_rx_desc_get_decap_type(struct hal_rx_desc *desc)
{
return FIELD_GET(RX_MSDU_START_INFO2_DECAP_FORMAT,
__le32_to_cpu(desc->u.ipq8074.msdu_start.info2));
}
static u8 ath11k_hw_ipq8074_rx_desc_get_mesh_ctl(struct hal_rx_desc *desc)
{
return FIELD_GET(RX_MSDU_START_INFO2_MESH_CTRL_PRESENT,
__le32_to_cpu(desc->u.ipq8074.msdu_start.info2));
}
static bool ath11k_hw_ipq8074_rx_desc_get_mpdu_seq_ctl_vld(struct hal_rx_desc *desc)
{
return !!FIELD_GET(RX_MPDU_START_INFO1_MPDU_SEQ_CTRL_VALID,
__le32_to_cpu(desc->u.ipq8074.mpdu_start.info1));
}
static bool ath11k_hw_ipq8074_rx_desc_get_mpdu_fc_valid(struct hal_rx_desc *desc)
{
return !!FIELD_GET(RX_MPDU_START_INFO1_MPDU_FCTRL_VALID,
__le32_to_cpu(desc->u.ipq8074.mpdu_start.info1));
}
static u16 ath11k_hw_ipq8074_rx_desc_get_mpdu_start_seq_no(struct hal_rx_desc *desc)
{
return FIELD_GET(RX_MPDU_START_INFO1_MPDU_SEQ_NUM,
__le32_to_cpu(desc->u.ipq8074.mpdu_start.info1));
}
static u16 ath11k_hw_ipq8074_rx_desc_get_msdu_len(struct hal_rx_desc *desc)
{
return FIELD_GET(RX_MSDU_START_INFO1_MSDU_LENGTH,
__le32_to_cpu(desc->u.ipq8074.msdu_start.info1));
}
static u8 ath11k_hw_ipq8074_rx_desc_get_msdu_sgi(struct hal_rx_desc *desc)
{
return FIELD_GET(RX_MSDU_START_INFO3_SGI,
__le32_to_cpu(desc->u.ipq8074.msdu_start.info3));
}
static u8 ath11k_hw_ipq8074_rx_desc_get_msdu_rate_mcs(struct hal_rx_desc *desc)
{
return FIELD_GET(RX_MSDU_START_INFO3_RATE_MCS,
__le32_to_cpu(desc->u.ipq8074.msdu_start.info3));
}
static u8 ath11k_hw_ipq8074_rx_desc_get_msdu_rx_bw(struct hal_rx_desc *desc)
{
return FIELD_GET(RX_MSDU_START_INFO3_RECV_BW,
__le32_to_cpu(desc->u.ipq8074.msdu_start.info3));
}
static u32 ath11k_hw_ipq8074_rx_desc_get_msdu_freq(struct hal_rx_desc *desc)
{
return __le32_to_cpu(desc->u.ipq8074.msdu_start.phy_meta_data);
}
static u8 ath11k_hw_ipq8074_rx_desc_get_msdu_pkt_type(struct hal_rx_desc *desc)
{
return FIELD_GET(RX_MSDU_START_INFO3_PKT_TYPE,
__le32_to_cpu(desc->u.ipq8074.msdu_start.info3));
}
static u8 ath11k_hw_ipq8074_rx_desc_get_msdu_nss(struct hal_rx_desc *desc)
{
return FIELD_GET(RX_MSDU_START_INFO3_MIMO_SS_BITMAP,
__le32_to_cpu(desc->u.ipq8074.msdu_start.info3));
}
static u8 ath11k_hw_ipq8074_rx_desc_get_mpdu_tid(struct hal_rx_desc *desc)
{
return FIELD_GET(RX_MPDU_START_INFO2_TID,
__le32_to_cpu(desc->u.ipq8074.mpdu_start.info2));
}
static u16 ath11k_hw_ipq8074_rx_desc_get_mpdu_peer_id(struct hal_rx_desc *desc)
{
return __le16_to_cpu(desc->u.ipq8074.mpdu_start.sw_peer_id);
}
static void ath11k_hw_ipq8074_rx_desc_copy_attn_end(struct hal_rx_desc *fdesc,
struct hal_rx_desc *ldesc)
{
memcpy((u8 *)&fdesc->u.ipq8074.msdu_end, (u8 *)&ldesc->u.ipq8074.msdu_end,
sizeof(struct rx_msdu_end_ipq8074));
memcpy((u8 *)&fdesc->u.ipq8074.attention, (u8 *)&ldesc->u.ipq8074.attention,
sizeof(struct rx_attention));
memcpy((u8 *)&fdesc->u.ipq8074.mpdu_end, (u8 *)&ldesc->u.ipq8074.mpdu_end,
sizeof(struct rx_mpdu_end));
}
static u32 ath11k_hw_ipq8074_rx_desc_get_mpdu_start_tag(struct hal_rx_desc *desc)
{
return FIELD_GET(HAL_TLV_HDR_TAG,
__le32_to_cpu(desc->u.ipq8074.mpdu_start_tag));
}
static u32 ath11k_hw_ipq8074_rx_desc_get_mpdu_ppdu_id(struct hal_rx_desc *desc)
{
return __le16_to_cpu(desc->u.ipq8074.mpdu_start.phy_ppdu_id);
}
static void ath11k_hw_ipq8074_rx_desc_set_msdu_len(struct hal_rx_desc *desc, u16 len)
{
u32 info = __le32_to_cpu(desc->u.ipq8074.msdu_start.info1);
info &= ~RX_MSDU_START_INFO1_MSDU_LENGTH;
info |= FIELD_PREP(RX_MSDU_START_INFO1_MSDU_LENGTH, len);
desc->u.ipq8074.msdu_start.info1 = __cpu_to_le32(info);
}
static
struct rx_attention *ath11k_hw_ipq8074_rx_desc_get_attention(struct hal_rx_desc *desc)
{
return &desc->u.ipq8074.attention;
}
static u8 *ath11k_hw_ipq8074_rx_desc_get_msdu_payload(struct hal_rx_desc *desc)
{
return &desc->u.ipq8074.msdu_payload[0];
}
static bool ath11k_hw_qcn9074_rx_desc_get_first_msdu(struct hal_rx_desc *desc)
{
return !!FIELD_GET(RX_MSDU_END_INFO4_FIRST_MSDU,
__le16_to_cpu(desc->u.qcn9074.msdu_end.info4));
}
static bool ath11k_hw_qcn9074_rx_desc_get_last_msdu(struct hal_rx_desc *desc)
{
return !!FIELD_GET(RX_MSDU_END_INFO4_LAST_MSDU,
__le16_to_cpu(desc->u.qcn9074.msdu_end.info4));
}
static u8 ath11k_hw_qcn9074_rx_desc_get_l3_pad_bytes(struct hal_rx_desc *desc)
{
return FIELD_GET(RX_MSDU_END_INFO4_L3_HDR_PADDING,
__le16_to_cpu(desc->u.qcn9074.msdu_end.info4));
}
static u8 *ath11k_hw_qcn9074_rx_desc_get_hdr_status(struct hal_rx_desc *desc)
{
return desc->u.qcn9074.hdr_status;
}
static bool ath11k_hw_qcn9074_rx_desc_encrypt_valid(struct hal_rx_desc *desc)
{
return __le32_to_cpu(desc->u.qcn9074.mpdu_start.info11) &
RX_MPDU_START_INFO11_ENCRYPT_INFO_VALID;
}
static u32 ath11k_hw_qcn9074_rx_desc_get_encrypt_type(struct hal_rx_desc *desc)
{
return FIELD_GET(RX_MPDU_START_INFO9_ENC_TYPE,
__le32_to_cpu(desc->u.qcn9074.mpdu_start.info9));
}
static u8 ath11k_hw_qcn9074_rx_desc_get_decap_type(struct hal_rx_desc *desc)
{
return FIELD_GET(RX_MSDU_START_INFO2_DECAP_FORMAT,
__le32_to_cpu(desc->u.qcn9074.msdu_start.info2));
}
static u8 ath11k_hw_qcn9074_rx_desc_get_mesh_ctl(struct hal_rx_desc *desc)
{
return FIELD_GET(RX_MSDU_START_INFO2_MESH_CTRL_PRESENT,
__le32_to_cpu(desc->u.qcn9074.msdu_start.info2));
}
static bool ath11k_hw_qcn9074_rx_desc_get_mpdu_seq_ctl_vld(struct hal_rx_desc *desc)
{
return !!FIELD_GET(RX_MPDU_START_INFO11_MPDU_SEQ_CTRL_VALID,
__le32_to_cpu(desc->u.qcn9074.mpdu_start.info11));
}
static bool ath11k_hw_qcn9074_rx_desc_get_mpdu_fc_valid(struct hal_rx_desc *desc)
{
return !!FIELD_GET(RX_MPDU_START_INFO11_MPDU_FCTRL_VALID,
__le32_to_cpu(desc->u.qcn9074.mpdu_start.info11));
}
static u16 ath11k_hw_qcn9074_rx_desc_get_mpdu_start_seq_no(struct hal_rx_desc *desc)
{
return FIELD_GET(RX_MPDU_START_INFO11_MPDU_SEQ_NUM,
__le32_to_cpu(desc->u.qcn9074.mpdu_start.info11));
}
static u16 ath11k_hw_qcn9074_rx_desc_get_msdu_len(struct hal_rx_desc *desc)
{
return FIELD_GET(RX_MSDU_START_INFO1_MSDU_LENGTH,
__le32_to_cpu(desc->u.qcn9074.msdu_start.info1));
}
static u8 ath11k_hw_qcn9074_rx_desc_get_msdu_sgi(struct hal_rx_desc *desc)
{
return FIELD_GET(RX_MSDU_START_INFO3_SGI,
__le32_to_cpu(desc->u.qcn9074.msdu_start.info3));
}
static u8 ath11k_hw_qcn9074_rx_desc_get_msdu_rate_mcs(struct hal_rx_desc *desc)
{
return FIELD_GET(RX_MSDU_START_INFO3_RATE_MCS,
__le32_to_cpu(desc->u.qcn9074.msdu_start.info3));
}
static u8 ath11k_hw_qcn9074_rx_desc_get_msdu_rx_bw(struct hal_rx_desc *desc)
{
return FIELD_GET(RX_MSDU_START_INFO3_RECV_BW,
__le32_to_cpu(desc->u.qcn9074.msdu_start.info3));
}
static u32 ath11k_hw_qcn9074_rx_desc_get_msdu_freq(struct hal_rx_desc *desc)
{
return __le32_to_cpu(desc->u.qcn9074.msdu_start.phy_meta_data);
}
static u8 ath11k_hw_qcn9074_rx_desc_get_msdu_pkt_type(struct hal_rx_desc *desc)
{
return FIELD_GET(RX_MSDU_START_INFO3_PKT_TYPE,
__le32_to_cpu(desc->u.qcn9074.msdu_start.info3));
}
static u8 ath11k_hw_qcn9074_rx_desc_get_msdu_nss(struct hal_rx_desc *desc)
{
return FIELD_GET(RX_MSDU_START_INFO3_MIMO_SS_BITMAP,
__le32_to_cpu(desc->u.qcn9074.msdu_start.info3));
}
static u8 ath11k_hw_qcn9074_rx_desc_get_mpdu_tid(struct hal_rx_desc *desc)
{
return FIELD_GET(RX_MPDU_START_INFO9_TID,
__le32_to_cpu(desc->u.qcn9074.mpdu_start.info9));
}
static u16 ath11k_hw_qcn9074_rx_desc_get_mpdu_peer_id(struct hal_rx_desc *desc)
{
return __le16_to_cpu(desc->u.qcn9074.mpdu_start.sw_peer_id);
}
static void ath11k_hw_qcn9074_rx_desc_copy_attn_end(struct hal_rx_desc *fdesc,
struct hal_rx_desc *ldesc)
{
memcpy((u8 *)&fdesc->u.qcn9074.msdu_end, (u8 *)&ldesc->u.qcn9074.msdu_end,
sizeof(struct rx_msdu_end_qcn9074));
memcpy((u8 *)&fdesc->u.qcn9074.attention, (u8 *)&ldesc->u.qcn9074.attention,
sizeof(struct rx_attention));
memcpy((u8 *)&fdesc->u.qcn9074.mpdu_end, (u8 *)&ldesc->u.qcn9074.mpdu_end,
sizeof(struct rx_mpdu_end));
}
static u32 ath11k_hw_qcn9074_rx_desc_get_mpdu_start_tag(struct hal_rx_desc *desc)
{
return FIELD_GET(HAL_TLV_HDR_TAG,
__le32_to_cpu(desc->u.qcn9074.mpdu_start_tag));
}
static u32 ath11k_hw_qcn9074_rx_desc_get_mpdu_ppdu_id(struct hal_rx_desc *desc)
{
return __le16_to_cpu(desc->u.qcn9074.mpdu_start.phy_ppdu_id);
}
static void ath11k_hw_qcn9074_rx_desc_set_msdu_len(struct hal_rx_desc *desc, u16 len)
{
u32 info = __le32_to_cpu(desc->u.qcn9074.msdu_start.info1);
info &= ~RX_MSDU_START_INFO1_MSDU_LENGTH;
info |= FIELD_PREP(RX_MSDU_START_INFO1_MSDU_LENGTH, len);
desc->u.qcn9074.msdu_start.info1 = __cpu_to_le32(info);
}
static
struct rx_attention *ath11k_hw_qcn9074_rx_desc_get_attention(struct hal_rx_desc *desc)
{
return &desc->u.qcn9074.attention;
}
static u8 *ath11k_hw_qcn9074_rx_desc_get_msdu_payload(struct hal_rx_desc *desc)
{
return &desc->u.qcn9074.msdu_payload[0];
}
const struct ath11k_hw_ops ipq8074_ops = {
.get_hw_mac_from_pdev_id = ath11k_hw_ipq8074_mac_from_pdev_id,
.wmi_init_config = ath11k_init_wmi_config_ipq8074,
.mac_id_to_pdev_id = ath11k_hw_mac_id_to_pdev_id_ipq8074,
.mac_id_to_srng_id = ath11k_hw_mac_id_to_srng_id_ipq8074,
.tx_mesh_enable = ath11k_hw_ipq8074_tx_mesh_enable,
.rx_desc_get_first_msdu = ath11k_hw_ipq8074_rx_desc_get_first_msdu,
.rx_desc_get_last_msdu = ath11k_hw_ipq8074_rx_desc_get_last_msdu,
.rx_desc_get_l3_pad_bytes = ath11k_hw_ipq8074_rx_desc_get_l3_pad_bytes,
.rx_desc_get_hdr_status = ath11k_hw_ipq8074_rx_desc_get_hdr_status,
.rx_desc_encrypt_valid = ath11k_hw_ipq8074_rx_desc_encrypt_valid,
.rx_desc_get_encrypt_type = ath11k_hw_ipq8074_rx_desc_get_encrypt_type,
.rx_desc_get_decap_type = ath11k_hw_ipq8074_rx_desc_get_decap_type,
.rx_desc_get_mesh_ctl = ath11k_hw_ipq8074_rx_desc_get_mesh_ctl,
.rx_desc_get_mpdu_seq_ctl_vld = ath11k_hw_ipq8074_rx_desc_get_mpdu_seq_ctl_vld,
.rx_desc_get_mpdu_fc_valid = ath11k_hw_ipq8074_rx_desc_get_mpdu_fc_valid,
.rx_desc_get_mpdu_start_seq_no = ath11k_hw_ipq8074_rx_desc_get_mpdu_start_seq_no,
.rx_desc_get_msdu_len = ath11k_hw_ipq8074_rx_desc_get_msdu_len,
.rx_desc_get_msdu_sgi = ath11k_hw_ipq8074_rx_desc_get_msdu_sgi,
.rx_desc_get_msdu_rate_mcs = ath11k_hw_ipq8074_rx_desc_get_msdu_rate_mcs,
.rx_desc_get_msdu_rx_bw = ath11k_hw_ipq8074_rx_desc_get_msdu_rx_bw,
.rx_desc_get_msdu_freq = ath11k_hw_ipq8074_rx_desc_get_msdu_freq,
.rx_desc_get_msdu_pkt_type = ath11k_hw_ipq8074_rx_desc_get_msdu_pkt_type,
.rx_desc_get_msdu_nss = ath11k_hw_ipq8074_rx_desc_get_msdu_nss,
.rx_desc_get_mpdu_tid = ath11k_hw_ipq8074_rx_desc_get_mpdu_tid,
.rx_desc_get_mpdu_peer_id = ath11k_hw_ipq8074_rx_desc_get_mpdu_peer_id,
.rx_desc_copy_attn_end_tlv = ath11k_hw_ipq8074_rx_desc_copy_attn_end,
.rx_desc_get_mpdu_start_tag = ath11k_hw_ipq8074_rx_desc_get_mpdu_start_tag,
.rx_desc_get_mpdu_ppdu_id = ath11k_hw_ipq8074_rx_desc_get_mpdu_ppdu_id,
.rx_desc_set_msdu_len = ath11k_hw_ipq8074_rx_desc_set_msdu_len,
.rx_desc_get_attention = ath11k_hw_ipq8074_rx_desc_get_attention,
.rx_desc_get_msdu_payload = ath11k_hw_ipq8074_rx_desc_get_msdu_payload,
};
const struct ath11k_hw_ops ipq6018_ops = {
@ -167,6 +528,33 @@ const struct ath11k_hw_ops ipq6018_ops = {
.wmi_init_config = ath11k_init_wmi_config_ipq8074,
.mac_id_to_pdev_id = ath11k_hw_mac_id_to_pdev_id_ipq8074,
.mac_id_to_srng_id = ath11k_hw_mac_id_to_srng_id_ipq8074,
.tx_mesh_enable = ath11k_hw_ipq8074_tx_mesh_enable,
.rx_desc_get_first_msdu = ath11k_hw_ipq8074_rx_desc_get_first_msdu,
.rx_desc_get_last_msdu = ath11k_hw_ipq8074_rx_desc_get_last_msdu,
.rx_desc_get_l3_pad_bytes = ath11k_hw_ipq8074_rx_desc_get_l3_pad_bytes,
.rx_desc_get_hdr_status = ath11k_hw_ipq8074_rx_desc_get_hdr_status,
.rx_desc_encrypt_valid = ath11k_hw_ipq8074_rx_desc_encrypt_valid,
.rx_desc_get_encrypt_type = ath11k_hw_ipq8074_rx_desc_get_encrypt_type,
.rx_desc_get_decap_type = ath11k_hw_ipq8074_rx_desc_get_decap_type,
.rx_desc_get_mesh_ctl = ath11k_hw_ipq8074_rx_desc_get_mesh_ctl,
.rx_desc_get_mpdu_seq_ctl_vld = ath11k_hw_ipq8074_rx_desc_get_mpdu_seq_ctl_vld,
.rx_desc_get_mpdu_fc_valid = ath11k_hw_ipq8074_rx_desc_get_mpdu_fc_valid,
.rx_desc_get_mpdu_start_seq_no = ath11k_hw_ipq8074_rx_desc_get_mpdu_start_seq_no,
.rx_desc_get_msdu_len = ath11k_hw_ipq8074_rx_desc_get_msdu_len,
.rx_desc_get_msdu_sgi = ath11k_hw_ipq8074_rx_desc_get_msdu_sgi,
.rx_desc_get_msdu_rate_mcs = ath11k_hw_ipq8074_rx_desc_get_msdu_rate_mcs,
.rx_desc_get_msdu_rx_bw = ath11k_hw_ipq8074_rx_desc_get_msdu_rx_bw,
.rx_desc_get_msdu_freq = ath11k_hw_ipq8074_rx_desc_get_msdu_freq,
.rx_desc_get_msdu_pkt_type = ath11k_hw_ipq8074_rx_desc_get_msdu_pkt_type,
.rx_desc_get_msdu_nss = ath11k_hw_ipq8074_rx_desc_get_msdu_nss,
.rx_desc_get_mpdu_tid = ath11k_hw_ipq8074_rx_desc_get_mpdu_tid,
.rx_desc_get_mpdu_peer_id = ath11k_hw_ipq8074_rx_desc_get_mpdu_peer_id,
.rx_desc_copy_attn_end_tlv = ath11k_hw_ipq8074_rx_desc_copy_attn_end,
.rx_desc_get_mpdu_start_tag = ath11k_hw_ipq8074_rx_desc_get_mpdu_start_tag,
.rx_desc_get_mpdu_ppdu_id = ath11k_hw_ipq8074_rx_desc_get_mpdu_ppdu_id,
.rx_desc_set_msdu_len = ath11k_hw_ipq8074_rx_desc_set_msdu_len,
.rx_desc_get_attention = ath11k_hw_ipq8074_rx_desc_get_attention,
.rx_desc_get_msdu_payload = ath11k_hw_ipq8074_rx_desc_get_msdu_payload,
};
const struct ath11k_hw_ops qca6390_ops = {
@ -174,6 +562,67 @@ const struct ath11k_hw_ops qca6390_ops = {
.wmi_init_config = ath11k_init_wmi_config_qca6390,
.mac_id_to_pdev_id = ath11k_hw_mac_id_to_pdev_id_qca6390,
.mac_id_to_srng_id = ath11k_hw_mac_id_to_srng_id_qca6390,
.tx_mesh_enable = ath11k_hw_ipq8074_tx_mesh_enable,
.rx_desc_get_first_msdu = ath11k_hw_ipq8074_rx_desc_get_first_msdu,
.rx_desc_get_last_msdu = ath11k_hw_ipq8074_rx_desc_get_last_msdu,
.rx_desc_get_l3_pad_bytes = ath11k_hw_ipq8074_rx_desc_get_l3_pad_bytes,
.rx_desc_get_hdr_status = ath11k_hw_ipq8074_rx_desc_get_hdr_status,
.rx_desc_encrypt_valid = ath11k_hw_ipq8074_rx_desc_encrypt_valid,
.rx_desc_get_encrypt_type = ath11k_hw_ipq8074_rx_desc_get_encrypt_type,
.rx_desc_get_decap_type = ath11k_hw_ipq8074_rx_desc_get_decap_type,
.rx_desc_get_mesh_ctl = ath11k_hw_ipq8074_rx_desc_get_mesh_ctl,
.rx_desc_get_mpdu_seq_ctl_vld = ath11k_hw_ipq8074_rx_desc_get_mpdu_seq_ctl_vld,
.rx_desc_get_mpdu_fc_valid = ath11k_hw_ipq8074_rx_desc_get_mpdu_fc_valid,
.rx_desc_get_mpdu_start_seq_no = ath11k_hw_ipq8074_rx_desc_get_mpdu_start_seq_no,
.rx_desc_get_msdu_len = ath11k_hw_ipq8074_rx_desc_get_msdu_len,
.rx_desc_get_msdu_sgi = ath11k_hw_ipq8074_rx_desc_get_msdu_sgi,
.rx_desc_get_msdu_rate_mcs = ath11k_hw_ipq8074_rx_desc_get_msdu_rate_mcs,
.rx_desc_get_msdu_rx_bw = ath11k_hw_ipq8074_rx_desc_get_msdu_rx_bw,
.rx_desc_get_msdu_freq = ath11k_hw_ipq8074_rx_desc_get_msdu_freq,
.rx_desc_get_msdu_pkt_type = ath11k_hw_ipq8074_rx_desc_get_msdu_pkt_type,
.rx_desc_get_msdu_nss = ath11k_hw_ipq8074_rx_desc_get_msdu_nss,
.rx_desc_get_mpdu_tid = ath11k_hw_ipq8074_rx_desc_get_mpdu_tid,
.rx_desc_get_mpdu_peer_id = ath11k_hw_ipq8074_rx_desc_get_mpdu_peer_id,
.rx_desc_copy_attn_end_tlv = ath11k_hw_ipq8074_rx_desc_copy_attn_end,
.rx_desc_get_mpdu_start_tag = ath11k_hw_ipq8074_rx_desc_get_mpdu_start_tag,
.rx_desc_get_mpdu_ppdu_id = ath11k_hw_ipq8074_rx_desc_get_mpdu_ppdu_id,
.rx_desc_set_msdu_len = ath11k_hw_ipq8074_rx_desc_set_msdu_len,
.rx_desc_get_attention = ath11k_hw_ipq8074_rx_desc_get_attention,
.rx_desc_get_msdu_payload = ath11k_hw_ipq8074_rx_desc_get_msdu_payload,
};
const struct ath11k_hw_ops qcn9074_ops = {
.get_hw_mac_from_pdev_id = ath11k_hw_ipq6018_mac_from_pdev_id,
.wmi_init_config = ath11k_init_wmi_config_ipq8074,
.mac_id_to_pdev_id = ath11k_hw_mac_id_to_pdev_id_ipq8074,
.mac_id_to_srng_id = ath11k_hw_mac_id_to_srng_id_ipq8074,
.tx_mesh_enable = ath11k_hw_qcn9074_tx_mesh_enable,
.rx_desc_get_first_msdu = ath11k_hw_qcn9074_rx_desc_get_first_msdu,
.rx_desc_get_last_msdu = ath11k_hw_qcn9074_rx_desc_get_last_msdu,
.rx_desc_get_l3_pad_bytes = ath11k_hw_qcn9074_rx_desc_get_l3_pad_bytes,
.rx_desc_get_hdr_status = ath11k_hw_qcn9074_rx_desc_get_hdr_status,
.rx_desc_encrypt_valid = ath11k_hw_qcn9074_rx_desc_encrypt_valid,
.rx_desc_get_encrypt_type = ath11k_hw_qcn9074_rx_desc_get_encrypt_type,
.rx_desc_get_decap_type = ath11k_hw_qcn9074_rx_desc_get_decap_type,
.rx_desc_get_mesh_ctl = ath11k_hw_qcn9074_rx_desc_get_mesh_ctl,
.rx_desc_get_mpdu_seq_ctl_vld = ath11k_hw_qcn9074_rx_desc_get_mpdu_seq_ctl_vld,
.rx_desc_get_mpdu_fc_valid = ath11k_hw_qcn9074_rx_desc_get_mpdu_fc_valid,
.rx_desc_get_mpdu_start_seq_no = ath11k_hw_qcn9074_rx_desc_get_mpdu_start_seq_no,
.rx_desc_get_msdu_len = ath11k_hw_qcn9074_rx_desc_get_msdu_len,
.rx_desc_get_msdu_sgi = ath11k_hw_qcn9074_rx_desc_get_msdu_sgi,
.rx_desc_get_msdu_rate_mcs = ath11k_hw_qcn9074_rx_desc_get_msdu_rate_mcs,
.rx_desc_get_msdu_rx_bw = ath11k_hw_qcn9074_rx_desc_get_msdu_rx_bw,
.rx_desc_get_msdu_freq = ath11k_hw_qcn9074_rx_desc_get_msdu_freq,
.rx_desc_get_msdu_pkt_type = ath11k_hw_qcn9074_rx_desc_get_msdu_pkt_type,
.rx_desc_get_msdu_nss = ath11k_hw_qcn9074_rx_desc_get_msdu_nss,
.rx_desc_get_mpdu_tid = ath11k_hw_qcn9074_rx_desc_get_mpdu_tid,
.rx_desc_get_mpdu_peer_id = ath11k_hw_qcn9074_rx_desc_get_mpdu_peer_id,
.rx_desc_copy_attn_end_tlv = ath11k_hw_qcn9074_rx_desc_copy_attn_end,
.rx_desc_get_mpdu_start_tag = ath11k_hw_qcn9074_rx_desc_get_mpdu_start_tag,
.rx_desc_get_mpdu_ppdu_id = ath11k_hw_qcn9074_rx_desc_get_mpdu_ppdu_id,
.rx_desc_set_msdu_len = ath11k_hw_qcn9074_rx_desc_set_msdu_len,
.rx_desc_get_attention = ath11k_hw_qcn9074_rx_desc_get_attention,
.rx_desc_get_msdu_payload = ath11k_hw_qcn9074_rx_desc_get_msdu_payload,
};
#define ATH11K_TX_RING_MASK_0 0x1
@ -792,6 +1241,241 @@ const struct service_to_pipe ath11k_target_service_to_ce_map_wlan_qca6390[] = {
},
};
/* Target firmware's Copy Engine configuration. */
const struct ce_pipe_config ath11k_target_ce_config_wlan_qcn9074[] = {
/* CE0: host->target HTC control and raw streams */
{
.pipenum = __cpu_to_le32(0),
.pipedir = __cpu_to_le32(PIPEDIR_OUT),
.nentries = __cpu_to_le32(32),
.nbytes_max = __cpu_to_le32(2048),
.flags = __cpu_to_le32(CE_ATTR_FLAGS),
.reserved = __cpu_to_le32(0),
},
/* CE1: target->host HTT + HTC control */
{
.pipenum = __cpu_to_le32(1),
.pipedir = __cpu_to_le32(PIPEDIR_IN),
.nentries = __cpu_to_le32(32),
.nbytes_max = __cpu_to_le32(2048),
.flags = __cpu_to_le32(CE_ATTR_FLAGS),
.reserved = __cpu_to_le32(0),
},
/* CE2: target->host WMI */
{
.pipenum = __cpu_to_le32(2),
.pipedir = __cpu_to_le32(PIPEDIR_IN),
.nentries = __cpu_to_le32(32),
.nbytes_max = __cpu_to_le32(2048),
.flags = __cpu_to_le32(CE_ATTR_FLAGS),
.reserved = __cpu_to_le32(0),
},
/* CE3: host->target WMI */
{
.pipenum = __cpu_to_le32(3),
.pipedir = __cpu_to_le32(PIPEDIR_OUT),
.nentries = __cpu_to_le32(32),
.nbytes_max = __cpu_to_le32(2048),
.flags = __cpu_to_le32(CE_ATTR_FLAGS),
.reserved = __cpu_to_le32(0),
},
/* CE4: host->target HTT */
{
.pipenum = __cpu_to_le32(4),
.pipedir = __cpu_to_le32(PIPEDIR_OUT),
.nentries = __cpu_to_le32(256),
.nbytes_max = __cpu_to_le32(256),
.flags = __cpu_to_le32(CE_ATTR_FLAGS | CE_ATTR_DIS_INTR),
.reserved = __cpu_to_le32(0),
},
/* CE5: target->host Pktlog */
{
.pipenum = __cpu_to_le32(5),
.pipedir = __cpu_to_le32(PIPEDIR_IN),
.nentries = __cpu_to_le32(32),
.nbytes_max = __cpu_to_le32(2048),
.flags = __cpu_to_le32(CE_ATTR_FLAGS),
.reserved = __cpu_to_le32(0),
},
/* CE6: Reserved for target autonomous hif_memcpy */
{
.pipenum = __cpu_to_le32(6),
.pipedir = __cpu_to_le32(PIPEDIR_INOUT),
.nentries = __cpu_to_le32(32),
.nbytes_max = __cpu_to_le32(16384),
.flags = __cpu_to_le32(CE_ATTR_FLAGS),
.reserved = __cpu_to_le32(0),
},
/* CE7 used only by Host */
{
.pipenum = __cpu_to_le32(7),
.pipedir = __cpu_to_le32(PIPEDIR_INOUT_H2H),
.nentries = __cpu_to_le32(0),
.nbytes_max = __cpu_to_le32(0),
.flags = __cpu_to_le32(CE_ATTR_FLAGS | CE_ATTR_DIS_INTR),
.reserved = __cpu_to_le32(0),
},
/* CE8 target->host used only by IPA */
{
.pipenum = __cpu_to_le32(8),
.pipedir = __cpu_to_le32(PIPEDIR_INOUT),
.nentries = __cpu_to_le32(32),
.nbytes_max = __cpu_to_le32(16384),
.flags = __cpu_to_le32(CE_ATTR_FLAGS),
.reserved = __cpu_to_le32(0),
},
/* CE 9, 10, 11 are used by MHI driver */
};
/* Map from service/endpoint to Copy Engine.
* This table is derived from the CE_PCI TABLE, above.
* It is passed to the Target at startup for use by firmware.
*/
const struct service_to_pipe ath11k_target_service_to_ce_map_wlan_qcn9074[] = {
{
__cpu_to_le32(ATH11K_HTC_SVC_ID_WMI_DATA_VO),
__cpu_to_le32(PIPEDIR_OUT), /* out = UL = host -> target */
__cpu_to_le32(3),
},
{
__cpu_to_le32(ATH11K_HTC_SVC_ID_WMI_DATA_VO),
__cpu_to_le32(PIPEDIR_IN), /* in = DL = target -> host */
__cpu_to_le32(2),
},
{
__cpu_to_le32(ATH11K_HTC_SVC_ID_WMI_DATA_BK),
__cpu_to_le32(PIPEDIR_OUT), /* out = UL = host -> target */
__cpu_to_le32(3),
},
{
__cpu_to_le32(ATH11K_HTC_SVC_ID_WMI_DATA_BK),
__cpu_to_le32(PIPEDIR_IN), /* in = DL = target -> host */
__cpu_to_le32(2),
},
{
__cpu_to_le32(ATH11K_HTC_SVC_ID_WMI_DATA_BE),
__cpu_to_le32(PIPEDIR_OUT), /* out = UL = host -> target */
__cpu_to_le32(3),
},
{
__cpu_to_le32(ATH11K_HTC_SVC_ID_WMI_DATA_BE),
__cpu_to_le32(PIPEDIR_IN), /* in = DL = target -> host */
__cpu_to_le32(2),
},
{
__cpu_to_le32(ATH11K_HTC_SVC_ID_WMI_DATA_VI),
__cpu_to_le32(PIPEDIR_OUT), /* out = UL = host -> target */
__cpu_to_le32(3),
},
{
__cpu_to_le32(ATH11K_HTC_SVC_ID_WMI_DATA_VI),
__cpu_to_le32(PIPEDIR_IN), /* in = DL = target -> host */
__cpu_to_le32(2),
},
{
__cpu_to_le32(ATH11K_HTC_SVC_ID_WMI_CONTROL),
__cpu_to_le32(PIPEDIR_OUT), /* out = UL = host -> target */
__cpu_to_le32(3),
},
{
__cpu_to_le32(ATH11K_HTC_SVC_ID_WMI_CONTROL),
__cpu_to_le32(PIPEDIR_IN), /* in = DL = target -> host */
__cpu_to_le32(2),
},
{
__cpu_to_le32(ATH11K_HTC_SVC_ID_RSVD_CTRL),
__cpu_to_le32(PIPEDIR_OUT), /* out = UL = host -> target */
__cpu_to_le32(0),
},
{
__cpu_to_le32(ATH11K_HTC_SVC_ID_RSVD_CTRL),
__cpu_to_le32(PIPEDIR_IN), /* in = DL = target -> host */
__cpu_to_le32(1),
},
{
__cpu_to_le32(ATH11K_HTC_SVC_ID_TEST_RAW_STREAMS),
__cpu_to_le32(PIPEDIR_OUT), /* out = UL = host -> target */
__cpu_to_le32(0),
},
{
__cpu_to_le32(ATH11K_HTC_SVC_ID_TEST_RAW_STREAMS),
__cpu_to_le32(PIPEDIR_IN), /* in = DL = target -> host */
__cpu_to_le32(1),
},
{
__cpu_to_le32(ATH11K_HTC_SVC_ID_HTT_DATA_MSG),
__cpu_to_le32(PIPEDIR_OUT), /* out = UL = host -> target */
__cpu_to_le32(4),
},
{
__cpu_to_le32(ATH11K_HTC_SVC_ID_HTT_DATA_MSG),
__cpu_to_le32(PIPEDIR_IN), /* in = DL = target -> host */
__cpu_to_le32(1),
},
{
__cpu_to_le32(ATH11K_HTC_SVC_ID_PKT_LOG),
__cpu_to_le32(PIPEDIR_IN), /* in = DL = target -> host */
__cpu_to_le32(5),
},
/* (Additions here) */
{ /* must be last */
__cpu_to_le32(0),
__cpu_to_le32(0),
__cpu_to_le32(0),
},
};
const struct ath11k_hw_ring_mask ath11k_hw_ring_mask_qcn9074 = {
.tx = {
ATH11K_TX_RING_MASK_0,
ATH11K_TX_RING_MASK_1,
ATH11K_TX_RING_MASK_2,
},
.rx_mon_status = {
0, 0, 0,
ATH11K_RX_MON_STATUS_RING_MASK_0,
ATH11K_RX_MON_STATUS_RING_MASK_1,
ATH11K_RX_MON_STATUS_RING_MASK_2,
},
.rx = {
0, 0, 0, 0,
ATH11K_RX_RING_MASK_0,
ATH11K_RX_RING_MASK_1,
ATH11K_RX_RING_MASK_2,
ATH11K_RX_RING_MASK_3,
},
.rx_err = {
0, 0, 0,
ATH11K_RX_ERR_RING_MASK_0,
},
.rx_wbm_rel = {
0, 0, 0,
ATH11K_RX_WBM_REL_RING_MASK_0,
},
.reo_status = {
0, 0, 0,
ATH11K_REO_STATUS_RING_MASK_0,
},
.rxdma2host = {
0, 0, 0,
ATH11K_RXDMA2HOST_RING_MASK_0,
},
.host2rxdma = {
0, 0, 0,
ATH11K_HOST2RXDMA_RING_MASK_0,
},
};
const struct ath11k_hw_regs ipq8074_regs = {
/* SW2TCL(x) R0 ring configuration address */
.hal_tcl1_ring_base_lsb = 0x00000510,
@ -841,6 +1525,26 @@ const struct ath11k_hw_regs ipq8074_regs = {
.hal_reo_status_ring_base_lsb = 0x00000504,
.hal_reo_status_hp = 0x00003070,
/* WCSS relative address */
.hal_seq_wcss_umac_ce0_src_reg = 0x00a00000,
.hal_seq_wcss_umac_ce0_dst_reg = 0x00a01000,
.hal_seq_wcss_umac_ce1_src_reg = 0x00a02000,
.hal_seq_wcss_umac_ce1_dst_reg = 0x00a03000,
/* WBM Idle address */
.hal_wbm_idle_link_ring_base_lsb = 0x00000860,
.hal_wbm_idle_link_ring_misc = 0x00000870,
/* SW2WBM release address */
.hal_wbm_release_ring_base_lsb = 0x000001d8,
/* WBM2SW release address */
.hal_wbm0_release_ring_base_lsb = 0x00000910,
.hal_wbm1_release_ring_base_lsb = 0x00000968,
/* PCIe base address */
.pcie_qserdes_sysclk_en_sel = 0x0,
.pcie_pcs_osc_dtct_config_base = 0x0,
};
const struct ath11k_hw_regs qca6390_regs = {
@ -891,4 +1595,96 @@ const struct ath11k_hw_regs qca6390_regs = {
/* REO status address */
.hal_reo_status_ring_base_lsb = 0x000004ac,
.hal_reo_status_hp = 0x00003068,
/* WCSS relative address */
.hal_seq_wcss_umac_ce0_src_reg = 0x00a00000,
.hal_seq_wcss_umac_ce0_dst_reg = 0x00a01000,
.hal_seq_wcss_umac_ce1_src_reg = 0x00a02000,
.hal_seq_wcss_umac_ce1_dst_reg = 0x00a03000,
/* WBM Idle address */
.hal_wbm_idle_link_ring_base_lsb = 0x00000860,
.hal_wbm_idle_link_ring_misc = 0x00000870,
/* SW2WBM release address */
.hal_wbm_release_ring_base_lsb = 0x000001d8,
/* WBM2SW release address */
.hal_wbm0_release_ring_base_lsb = 0x00000910,
.hal_wbm1_release_ring_base_lsb = 0x00000968,
/* PCIe base address */
.pcie_qserdes_sysclk_en_sel = 0x01e0c0ac,
.pcie_pcs_osc_dtct_config_base = 0x01e0c628,
};
const struct ath11k_hw_regs qcn9074_regs = {
/* SW2TCL(x) R0 ring configuration address */
.hal_tcl1_ring_base_lsb = 0x000004f0,
.hal_tcl1_ring_base_msb = 0x000004f4,
.hal_tcl1_ring_id = 0x000004f8,
.hal_tcl1_ring_misc = 0x00000500,
.hal_tcl1_ring_tp_addr_lsb = 0x0000050c,
.hal_tcl1_ring_tp_addr_msb = 0x00000510,
.hal_tcl1_ring_consumer_int_setup_ix0 = 0x00000520,
.hal_tcl1_ring_consumer_int_setup_ix1 = 0x00000524,
.hal_tcl1_ring_msi1_base_lsb = 0x00000538,
.hal_tcl1_ring_msi1_base_msb = 0x0000053c,
.hal_tcl1_ring_msi1_data = 0x00000540,
.hal_tcl2_ring_base_lsb = 0x00000548,
.hal_tcl_ring_base_lsb = 0x000005f8,
/* TCL STATUS ring address */
.hal_tcl_status_ring_base_lsb = 0x00000700,
/* REO2SW(x) R0 ring configuration address */
.hal_reo1_ring_base_lsb = 0x0000029c,
.hal_reo1_ring_base_msb = 0x000002a0,
.hal_reo1_ring_id = 0x000002a4,
.hal_reo1_ring_misc = 0x000002ac,
.hal_reo1_ring_hp_addr_lsb = 0x000002b0,
.hal_reo1_ring_hp_addr_msb = 0x000002b4,
.hal_reo1_ring_producer_int_setup = 0x000002c0,
.hal_reo1_ring_msi1_base_lsb = 0x000002e4,
.hal_reo1_ring_msi1_base_msb = 0x000002e8,
.hal_reo1_ring_msi1_data = 0x000002ec,
.hal_reo2_ring_base_lsb = 0x000002f4,
.hal_reo1_aging_thresh_ix_0 = 0x00000564,
.hal_reo1_aging_thresh_ix_1 = 0x00000568,
.hal_reo1_aging_thresh_ix_2 = 0x0000056c,
.hal_reo1_aging_thresh_ix_3 = 0x00000570,
/* REO2SW(x) R2 ring pointers (head/tail) address */
.hal_reo1_ring_hp = 0x00003038,
.hal_reo1_ring_tp = 0x0000303c,
.hal_reo2_ring_hp = 0x00003040,
/* REO2TCL R0 ring configuration address */
.hal_reo_tcl_ring_base_lsb = 0x000003fc,
.hal_reo_tcl_ring_hp = 0x00003058,
/* REO status address */
.hal_reo_status_ring_base_lsb = 0x00000504,
.hal_reo_status_hp = 0x00003070,
/* WCSS relative address */
.hal_seq_wcss_umac_ce0_src_reg = 0x01b80000,
.hal_seq_wcss_umac_ce0_dst_reg = 0x01b81000,
.hal_seq_wcss_umac_ce1_src_reg = 0x01b82000,
.hal_seq_wcss_umac_ce1_dst_reg = 0x01b83000,
/* WBM Idle address */
.hal_wbm_idle_link_ring_base_lsb = 0x00000874,
.hal_wbm_idle_link_ring_misc = 0x00000884,
/* SW2WBM release address */
.hal_wbm_release_ring_base_lsb = 0x000001ec,
/* WBM2SW release address */
.hal_wbm0_release_ring_base_lsb = 0x00000924,
.hal_wbm1_release_ring_base_lsb = 0x0000097c,
/* PCIe base address */
.pcie_qserdes_sysclk_en_sel = 0x01e0e0a8,
.pcie_pcs_osc_dtct_config_base = 0x01e0f45c,
};

View File

@ -105,6 +105,9 @@ enum ath11k_bus {
#define ATH11K_EXT_IRQ_GRP_NUM_MAX 11
struct hal_rx_desc;
struct hal_tcl_data_cmd;
struct ath11k_hw_ring_mask {
u8 tx[ATH11K_EXT_IRQ_GRP_NUM_MAX];
u8 rx_mon_status[ATH11K_EXT_IRQ_GRP_NUM_MAX];
@ -134,6 +137,7 @@ struct ath11k_hw_params {
bool internal_sleep_clock;
const struct ath11k_hw_regs *regs;
u32 qmi_service_ins_id;
const struct ce_attr *host_ce_config;
u32 ce_count;
const struct ce_pipe_config *target_ce_config;
@ -157,6 +161,7 @@ struct ath11k_hw_params {
bool idle_ps;
bool cold_boot_calib;
bool supports_suspend;
u32 hal_desc_sz;
};
struct ath11k_hw_ops {
@ -165,14 +170,45 @@ struct ath11k_hw_ops {
struct target_resource_config *config);
int (*mac_id_to_pdev_id)(struct ath11k_hw_params *hw, int mac_id);
int (*mac_id_to_srng_id)(struct ath11k_hw_params *hw, int mac_id);
void (*tx_mesh_enable)(struct ath11k_base *ab,
struct hal_tcl_data_cmd *tcl_cmd);
bool (*rx_desc_get_first_msdu)(struct hal_rx_desc *desc);
bool (*rx_desc_get_last_msdu)(struct hal_rx_desc *desc);
u8 (*rx_desc_get_l3_pad_bytes)(struct hal_rx_desc *desc);
u8 *(*rx_desc_get_hdr_status)(struct hal_rx_desc *desc);
bool (*rx_desc_encrypt_valid)(struct hal_rx_desc *desc);
u32 (*rx_desc_get_encrypt_type)(struct hal_rx_desc *desc);
u8 (*rx_desc_get_decap_type)(struct hal_rx_desc *desc);
u8 (*rx_desc_get_mesh_ctl)(struct hal_rx_desc *desc);
bool (*rx_desc_get_mpdu_seq_ctl_vld)(struct hal_rx_desc *desc);
bool (*rx_desc_get_mpdu_fc_valid)(struct hal_rx_desc *desc);
u16 (*rx_desc_get_mpdu_start_seq_no)(struct hal_rx_desc *desc);
u16 (*rx_desc_get_msdu_len)(struct hal_rx_desc *desc);
u8 (*rx_desc_get_msdu_sgi)(struct hal_rx_desc *desc);
u8 (*rx_desc_get_msdu_rate_mcs)(struct hal_rx_desc *desc);
u8 (*rx_desc_get_msdu_rx_bw)(struct hal_rx_desc *desc);
u32 (*rx_desc_get_msdu_freq)(struct hal_rx_desc *desc);
u8 (*rx_desc_get_msdu_pkt_type)(struct hal_rx_desc *desc);
u8 (*rx_desc_get_msdu_nss)(struct hal_rx_desc *desc);
u8 (*rx_desc_get_mpdu_tid)(struct hal_rx_desc *desc);
u16 (*rx_desc_get_mpdu_peer_id)(struct hal_rx_desc *desc);
void (*rx_desc_copy_attn_end_tlv)(struct hal_rx_desc *fdesc,
struct hal_rx_desc *ldesc);
u32 (*rx_desc_get_mpdu_start_tag)(struct hal_rx_desc *desc);
u32 (*rx_desc_get_mpdu_ppdu_id)(struct hal_rx_desc *desc);
void (*rx_desc_set_msdu_len)(struct hal_rx_desc *desc, u16 len);
struct rx_attention *(*rx_desc_get_attention)(struct hal_rx_desc *desc);
u8 *(*rx_desc_get_msdu_payload)(struct hal_rx_desc *desc);
};
extern const struct ath11k_hw_ops ipq8074_ops;
extern const struct ath11k_hw_ops ipq6018_ops;
extern const struct ath11k_hw_ops qca6390_ops;
extern const struct ath11k_hw_ops qcn9074_ops;
extern const struct ath11k_hw_ring_mask ath11k_hw_ring_mask_ipq8074;
extern const struct ath11k_hw_ring_mask ath11k_hw_ring_mask_qca6390;
extern const struct ath11k_hw_ring_mask ath11k_hw_ring_mask_qcn9074;
static inline
int ath11k_hw_get_mac_from_pdev_id(struct ath11k_hw_params *hw,
@ -261,9 +297,26 @@ struct ath11k_hw_regs {
u32 hal_reo_status_ring_base_lsb;
u32 hal_reo_status_hp;
u32 hal_seq_wcss_umac_ce0_src_reg;
u32 hal_seq_wcss_umac_ce0_dst_reg;
u32 hal_seq_wcss_umac_ce1_src_reg;
u32 hal_seq_wcss_umac_ce1_dst_reg;
u32 hal_wbm_idle_link_ring_base_lsb;
u32 hal_wbm_idle_link_ring_misc;
u32 hal_wbm_release_ring_base_lsb;
u32 hal_wbm0_release_ring_base_lsb;
u32 hal_wbm1_release_ring_base_lsb;
u32 pcie_qserdes_sysclk_en_sel;
u32 pcie_pcs_osc_dtct_config_base;
};
extern const struct ath11k_hw_regs ipq8074_regs;
extern const struct ath11k_hw_regs qca6390_regs;
extern const struct ath11k_hw_regs qcn9074_regs;
#endif

View File

@ -829,6 +829,75 @@ static void ath11k_control_beaconing(struct ath11k_vif *arvif,
ath11k_dbg(ar->ab, ATH11K_DBG_MAC, "mac vdev %d up\n", arvif->vdev_id);
}
static void ath11k_mac_handle_beacon_iter(void *data, u8 *mac,
struct ieee80211_vif *vif)
{
struct sk_buff *skb = data;
struct ieee80211_mgmt *mgmt = (void *)skb->data;
struct ath11k_vif *arvif = (void *)vif->drv_priv;
if (vif->type != NL80211_IFTYPE_STATION)
return;
if (!ether_addr_equal(mgmt->bssid, vif->bss_conf.bssid))
return;
cancel_delayed_work(&arvif->connection_loss_work);
}
void ath11k_mac_handle_beacon(struct ath11k *ar, struct sk_buff *skb)
{
ieee80211_iterate_active_interfaces_atomic(ar->hw,
IEEE80211_IFACE_ITER_NORMAL,
ath11k_mac_handle_beacon_iter,
skb);
}
static void ath11k_mac_handle_beacon_miss_iter(void *data, u8 *mac,
struct ieee80211_vif *vif)
{
u32 *vdev_id = data;
struct ath11k_vif *arvif = (void *)vif->drv_priv;
struct ath11k *ar = arvif->ar;
struct ieee80211_hw *hw = ar->hw;
if (arvif->vdev_id != *vdev_id)
return;
if (!arvif->is_up)
return;
ieee80211_beacon_loss(vif);
/* Firmware doesn't report beacon loss events repeatedly. If AP probe
* (done by mac80211) succeeds but beacons do not resume then it
* doesn't make sense to continue operation. Queue connection loss work
* which can be cancelled when beacon is received.
*/
ieee80211_queue_delayed_work(hw, &arvif->connection_loss_work,
ATH11K_CONNECTION_LOSS_HZ);
}
void ath11k_mac_handle_beacon_miss(struct ath11k *ar, u32 vdev_id)
{
ieee80211_iterate_active_interfaces_atomic(ar->hw,
IEEE80211_IFACE_ITER_NORMAL,
ath11k_mac_handle_beacon_miss_iter,
&vdev_id);
}
static void ath11k_mac_vif_sta_connection_loss_work(struct work_struct *work)
{
struct ath11k_vif *arvif = container_of(work, struct ath11k_vif,
connection_loss_work.work);
struct ieee80211_vif *vif = arvif->vif;
if (!arvif->is_up)
return;
ieee80211_connection_loss(vif);
}
static void ath11k_peer_assoc_h_basic(struct ath11k *ar,
struct ieee80211_vif *vif,
struct ieee80211_sta *sta,
@ -1760,7 +1829,7 @@ static void ath11k_bss_disassoc(struct ieee80211_hw *hw,
arvif->is_up = false;
/* TODO: cancel connection_loss_work */
cancel_delayed_work_sync(&arvif->connection_loss_work);
}
static u32 ath11k_mac_get_rate_hw_value(int bitrate)
@ -3919,8 +3988,6 @@ static int ath11k_mac_copy_he_cap(struct ath11k *ar,
he_cap_elem->phy_cap_info[5] &=
~IEEE80211_HE_PHY_CAP5_BEAMFORMEE_NUM_SND_DIM_UNDER_80MHZ_MASK;
he_cap_elem->phy_cap_info[5] &=
~IEEE80211_HE_PHY_CAP5_BEAMFORMEE_NUM_SND_DIM_ABOVE_80MHZ_MASK;
he_cap_elem->phy_cap_info[5] |= ar->num_tx_chains - 1;
switch (i) {
@ -4213,7 +4280,7 @@ static int ath11k_mac_mgmt_tx(struct ath11k *ar, struct sk_buff *skb,
return -ENOSPC;
}
if (skb_queue_len(q) == ATH11K_TX_MGMT_NUM_PENDING_MAX) {
if (skb_queue_len_lockless(q) >= ATH11K_TX_MGMT_NUM_PENDING_MAX) {
ath11k_warn(ar->ab, "mgmt tx queue is full\n");
return -ENOSPC;
}
@ -4617,10 +4684,8 @@ static int ath11k_mac_op_add_interface(struct ieee80211_hw *hw,
arvif->vif = vif;
INIT_LIST_HEAD(&arvif->list);
/* Should we initialize any worker to handle connection loss indication
* from firmware in sta mode?
*/
INIT_DELAYED_WORK(&arvif->connection_loss_work,
ath11k_mac_vif_sta_connection_loss_work);
for (i = 0; i < ARRAY_SIZE(arvif->bitrate_mask.control); i++) {
arvif->bitrate_mask.control[i].legacy = 0xffffffff;
@ -4829,6 +4894,8 @@ static void ath11k_mac_op_remove_interface(struct ieee80211_hw *hw,
int ret;
int i;
cancel_delayed_work_sync(&arvif->connection_loss_work);
mutex_lock(&ar->conf_mutex);
ath11k_dbg(ab, ATH11K_DBG_MAC, "mac remove interface (vdev %d)\n",
@ -5096,13 +5163,15 @@ ath11k_mac_vdev_start_restart(struct ath11k_vif *arvif,
arg.channel.chan_radar =
!!(chandef->chan->flags & IEEE80211_CHAN_RADAR);
arg.channel.freq2_radar =
!!(chandef->chan->flags & IEEE80211_CHAN_RADAR);
arg.channel.passive = arg.channel.chan_radar;
spin_lock_bh(&ab->base_lock);
arg.regdomain = ar->ab->dfs_region;
spin_unlock_bh(&ab->base_lock);
/* TODO: Notify if secondary 80Mhz also needs radar detection */
if (he_support) {
ret = ath11k_set_he_mu_sounding_mode(ar, arvif);
if (ret) {
@ -6082,6 +6151,7 @@ static void ath11k_mac_op_sta_statistics(struct ieee80211_hw *hw,
/* TODO: Use real NF instead of default one. */
sinfo->signal = arsta->rssi_comb + ATH11K_DEFAULT_NOISE_FLOOR;
sinfo->filled |= BIT_ULL(NL80211_STA_INFO_SIGNAL);
}
static const struct ieee80211_ops ath11k_ops = {

View File

@ -150,4 +150,6 @@ int ath11k_mac_tx_mgmt_pending_free(int buf_id, void *skb, void *ctx);
u8 ath11k_mac_bw_to_mac80211_bw(u8 bw);
enum ath11k_supported_bw ath11k_mac_mac80211_bw_to_ath11k_bw(enum rate_info_bw bw);
enum hal_encrypt_type ath11k_dp_tx_get_encrypt_type(u32 cipher);
void ath11k_mac_handle_beacon(struct ath11k *ar, struct sk_buff *skb);
void ath11k_mac_handle_beacon_miss(struct ath11k *ar, u32 vdev_id);
#endif

View File

@ -7,10 +7,11 @@
#include "core.h"
#include "debug.h"
#include "mhi.h"
#include "pci.h"
#define MHI_TIMEOUT_DEFAULT_MS 90000
static struct mhi_channel_config ath11k_mhi_channels[] = {
static struct mhi_channel_config ath11k_mhi_channels_qca6390[] = {
{
.num = 0,
.name = "LOOPBACK",
@ -69,7 +70,7 @@ static struct mhi_channel_config ath11k_mhi_channels[] = {
},
};
static struct mhi_event_config ath11k_mhi_events[] = {
static struct mhi_event_config ath11k_mhi_events_qca6390[] = {
{
.num_elements = 32,
.irq_moderation_ms = 0,
@ -92,15 +93,108 @@ static struct mhi_event_config ath11k_mhi_events[] = {
},
};
static struct mhi_controller_config ath11k_mhi_config = {
static struct mhi_controller_config ath11k_mhi_config_qca6390 = {
.max_channels = 128,
.timeout_ms = 2000,
.use_bounce_buf = false,
.buf_len = 0,
.num_channels = ARRAY_SIZE(ath11k_mhi_channels),
.ch_cfg = ath11k_mhi_channels,
.num_events = ARRAY_SIZE(ath11k_mhi_events),
.event_cfg = ath11k_mhi_events,
.num_channels = ARRAY_SIZE(ath11k_mhi_channels_qca6390),
.ch_cfg = ath11k_mhi_channels_qca6390,
.num_events = ARRAY_SIZE(ath11k_mhi_events_qca6390),
.event_cfg = ath11k_mhi_events_qca6390,
};
static struct mhi_channel_config ath11k_mhi_channels_qcn9074[] = {
{
.num = 0,
.name = "LOOPBACK",
.num_elements = 32,
.event_ring = 1,
.dir = DMA_TO_DEVICE,
.ee_mask = 0x14,
.pollcfg = 0,
.doorbell = MHI_DB_BRST_DISABLE,
.lpm_notify = false,
.offload_channel = false,
.doorbell_mode_switch = false,
.auto_queue = false,
},
{
.num = 1,
.name = "LOOPBACK",
.num_elements = 32,
.event_ring = 1,
.dir = DMA_FROM_DEVICE,
.ee_mask = 0x14,
.pollcfg = 0,
.doorbell = MHI_DB_BRST_DISABLE,
.lpm_notify = false,
.offload_channel = false,
.doorbell_mode_switch = false,
.auto_queue = false,
},
{
.num = 20,
.name = "IPCR",
.num_elements = 32,
.event_ring = 1,
.dir = DMA_TO_DEVICE,
.ee_mask = 0x14,
.pollcfg = 0,
.doorbell = MHI_DB_BRST_DISABLE,
.lpm_notify = false,
.offload_channel = false,
.doorbell_mode_switch = false,
.auto_queue = false,
},
{
.num = 21,
.name = "IPCR",
.num_elements = 32,
.event_ring = 1,
.dir = DMA_FROM_DEVICE,
.ee_mask = 0x14,
.pollcfg = 0,
.doorbell = MHI_DB_BRST_DISABLE,
.lpm_notify = false,
.offload_channel = false,
.doorbell_mode_switch = false,
.auto_queue = true,
},
};
static struct mhi_event_config ath11k_mhi_events_qcn9074[] = {
{
.num_elements = 32,
.irq_moderation_ms = 0,
.irq = 1,
.data_type = MHI_ER_CTRL,
.mode = MHI_DB_BRST_DISABLE,
.hardware_event = false,
.client_managed = false,
.offload_channel = false,
},
{
.num_elements = 256,
.irq_moderation_ms = 1,
.irq = 2,
.mode = MHI_DB_BRST_DISABLE,
.priority = 1,
.hardware_event = false,
.client_managed = false,
.offload_channel = false,
},
};
static struct mhi_controller_config ath11k_mhi_config_qcn9074 = {
.max_channels = 30,
.timeout_ms = 10000,
.use_bounce_buf = false,
.buf_len = 0,
.num_channels = ARRAY_SIZE(ath11k_mhi_channels_qcn9074),
.ch_cfg = ath11k_mhi_channels_qcn9074,
.num_events = ARRAY_SIZE(ath11k_mhi_events_qcn9074),
.event_cfg = ath11k_mhi_events_qcn9074,
};
void ath11k_mhi_set_mhictrl_reset(struct ath11k_base *ab)
@ -221,6 +315,7 @@ int ath11k_mhi_register(struct ath11k_pci *ab_pci)
{
struct ath11k_base *ab = ab_pci->ab;
struct mhi_controller *mhi_ctrl;
struct mhi_controller_config *ath11k_mhi_config;
int ret;
mhi_ctrl = mhi_alloc_controller();
@ -254,7 +349,12 @@ int ath11k_mhi_register(struct ath11k_pci *ab_pci)
mhi_ctrl->read_reg = ath11k_mhi_op_read_reg;
mhi_ctrl->write_reg = ath11k_mhi_op_write_reg;
ret = mhi_register_controller(mhi_ctrl, &ath11k_mhi_config);
if (ab->hw_rev == ATH11K_HW_QCA6390_HW20)
ath11k_mhi_config = &ath11k_mhi_config_qca6390;
else if (ab->hw_rev == ATH11K_HW_QCN9074_HW10)
ath11k_mhi_config = &ath11k_mhi_config_qcn9074;
ret = mhi_register_controller(mhi_ctrl, ath11k_mhi_config);
if (ret) {
ath11k_err(ab, "failed to register to mhi bus, err = %d\n", ret);
mhi_free_controller(mhi_ctrl);

View File

@ -35,9 +35,11 @@
#define ACCESS_ALWAYS_OFF 0xFE0
#define QCA6390_DEVICE_ID 0x1101
#define QCN9074_DEVICE_ID 0x1104
static const struct pci_device_id ath11k_pci_id_table[] = {
{ PCI_VDEVICE(QCOM, QCA6390_DEVICE_ID) },
/* TODO: add QCN9074_DEVICE_ID) once firmware issues are resolved */
{0}
};
@ -50,14 +52,25 @@ static const struct ath11k_bus_params ath11k_pci_bus_params = {
.fixed_mem_region = false,
};
static const struct ath11k_msi_config msi_config = {
.total_vectors = 32,
.total_users = 4,
.users = (struct ath11k_msi_user[]) {
{ .name = "MHI", .num_vectors = 3, .base_vector = 0 },
{ .name = "CE", .num_vectors = 10, .base_vector = 3 },
{ .name = "WAKE", .num_vectors = 1, .base_vector = 13 },
{ .name = "DP", .num_vectors = 18, .base_vector = 14 },
static const struct ath11k_msi_config ath11k_msi_config[] = {
{
.total_vectors = 32,
.total_users = 4,
.users = (struct ath11k_msi_user[]) {
{ .name = "MHI", .num_vectors = 3, .base_vector = 0 },
{ .name = "CE", .num_vectors = 10, .base_vector = 3 },
{ .name = "WAKE", .num_vectors = 1, .base_vector = 13 },
{ .name = "DP", .num_vectors = 18, .base_vector = 14 },
},
},
{
.total_vectors = 16,
.total_users = 3,
.users = (struct ath11k_msi_user[]) {
{ .name = "MHI", .num_vectors = 3, .base_vector = 0 },
{ .name = "CE", .num_vectors = 5, .base_vector = 3 },
{ .name = "DP", .num_vectors = 8, .base_vector = 8 },
},
},
};
@ -131,9 +144,38 @@ static inline void ath11k_pci_select_window(struct ath11k_pci *ab_pci, u32 offse
}
}
static inline void ath11k_pci_select_static_window(struct ath11k_pci *ab_pci)
{
u32 umac_window = FIELD_GET(WINDOW_VALUE_MASK, HAL_SEQ_WCSS_UMAC_OFFSET);
u32 ce_window = FIELD_GET(WINDOW_VALUE_MASK, HAL_CE_WFSS_CE_REG_BASE);
u32 window;
window = (umac_window << 12) | (ce_window << 6);
iowrite32(WINDOW_ENABLE_BIT | window, ab_pci->ab->mem + WINDOW_REG_ADDRESS);
}
static inline u32 ath11k_pci_get_window_start(struct ath11k_base *ab,
u32 offset)
{
u32 window_start;
/* If offset lies within DP register range, use 3rd window */
if ((offset ^ HAL_SEQ_WCSS_UMAC_OFFSET) < WINDOW_RANGE_MASK)
window_start = 3 * WINDOW_START;
/* If offset lies within CE register range, use 2nd window */
else if ((offset ^ HAL_CE_WFSS_CE_REG_BASE) < WINDOW_RANGE_MASK)
window_start = 2 * WINDOW_START;
else
window_start = WINDOW_START;
return window_start;
}
void ath11k_pci_write32(struct ath11k_base *ab, u32 offset, u32 value)
{
struct ath11k_pci *ab_pci = ath11k_pci_priv(ab);
u32 window_start;
/* for offset beyond BAR + 4K - 32, may
* need to wakeup MHI to access.
@ -145,10 +187,21 @@ void ath11k_pci_write32(struct ath11k_base *ab, u32 offset, u32 value)
if (offset < WINDOW_START) {
iowrite32(value, ab->mem + offset);
} else {
spin_lock_bh(&ab_pci->window_lock);
ath11k_pci_select_window(ab_pci, offset);
iowrite32(value, ab->mem + WINDOW_START + (offset & WINDOW_RANGE_MASK));
spin_unlock_bh(&ab_pci->window_lock);
if (ab->bus_params.static_window_map)
window_start = ath11k_pci_get_window_start(ab, offset);
else
window_start = WINDOW_START;
if (window_start == WINDOW_START) {
spin_lock_bh(&ab_pci->window_lock);
ath11k_pci_select_window(ab_pci, offset);
iowrite32(value, ab->mem + window_start +
(offset & WINDOW_RANGE_MASK));
spin_unlock_bh(&ab_pci->window_lock);
} else {
iowrite32(value, ab->mem + window_start +
(offset & WINDOW_RANGE_MASK));
}
}
if (test_bit(ATH11K_PCI_FLAG_INIT_DONE, &ab_pci->flags) &&
@ -159,7 +212,7 @@ void ath11k_pci_write32(struct ath11k_base *ab, u32 offset, u32 value)
u32 ath11k_pci_read32(struct ath11k_base *ab, u32 offset)
{
struct ath11k_pci *ab_pci = ath11k_pci_priv(ab);
u32 val;
u32 val, window_start;
/* for offset beyond BAR + 4K - 32, may
* need to wakeup MHI to access.
@ -171,10 +224,21 @@ u32 ath11k_pci_read32(struct ath11k_base *ab, u32 offset)
if (offset < WINDOW_START) {
val = ioread32(ab->mem + offset);
} else {
spin_lock_bh(&ab_pci->window_lock);
ath11k_pci_select_window(ab_pci, offset);
val = ioread32(ab->mem + WINDOW_START + (offset & WINDOW_RANGE_MASK));
spin_unlock_bh(&ab_pci->window_lock);
if (ab->bus_params.static_window_map)
window_start = ath11k_pci_get_window_start(ab, offset);
else
window_start = WINDOW_START;
if (window_start == WINDOW_START) {
spin_lock_bh(&ab_pci->window_lock);
ath11k_pci_select_window(ab_pci, offset);
val = ioread32(ab->mem + window_start +
(offset & WINDOW_RANGE_MASK));
spin_unlock_bh(&ab_pci->window_lock);
} else {
val = ioread32(ab->mem + window_start +
(offset & WINDOW_RANGE_MASK));
}
}
if (test_bit(ATH11K_PCI_FLAG_INIT_DONE, &ab_pci->flags) &&
@ -271,7 +335,7 @@ static int ath11k_pci_fix_l1ss(struct ath11k_base *ab)
int ret;
ret = ath11k_pci_set_link_reg(ab,
PCIE_QSERDES_COM_SYSCLK_EN_SEL_REG,
PCIE_QSERDES_COM_SYSCLK_EN_SEL_REG(ab),
PCIE_QSERDES_COM_SYSCLK_EN_SEL_VAL,
PCIE_QSERDES_COM_SYSCLK_EN_SEL_MSK);
if (ret) {
@ -280,27 +344,27 @@ static int ath11k_pci_fix_l1ss(struct ath11k_base *ab)
}
ret = ath11k_pci_set_link_reg(ab,
PCIE_USB3_PCS_MISC_OSC_DTCT_CONFIG1_REG,
PCIE_USB3_PCS_MISC_OSC_DTCT_CONFIG1_VAL,
PCIE_USB3_PCS_MISC_OSC_DTCT_CONFIG_MSK);
PCIE_PCS_OSC_DTCT_CONFIG1_REG(ab),
PCIE_PCS_OSC_DTCT_CONFIG1_VAL,
PCIE_PCS_OSC_DTCT_CONFIG_MSK);
if (ret) {
ath11k_warn(ab, "failed to set dtct config1 error: %d\n", ret);
return ret;
}
ret = ath11k_pci_set_link_reg(ab,
PCIE_USB3_PCS_MISC_OSC_DTCT_CONFIG2_REG,
PCIE_USB3_PCS_MISC_OSC_DTCT_CONFIG2_VAL,
PCIE_USB3_PCS_MISC_OSC_DTCT_CONFIG_MSK);
PCIE_PCS_OSC_DTCT_CONFIG2_REG(ab),
PCIE_PCS_OSC_DTCT_CONFIG2_VAL,
PCIE_PCS_OSC_DTCT_CONFIG_MSK);
if (ret) {
ath11k_warn(ab, "failed to set dtct config2: %d\n", ret);
return ret;
}
ret = ath11k_pci_set_link_reg(ab,
PCIE_USB3_PCS_MISC_OSC_DTCT_CONFIG4_REG,
PCIE_USB3_PCS_MISC_OSC_DTCT_CONFIG4_VAL,
PCIE_USB3_PCS_MISC_OSC_DTCT_CONFIG_MSK);
PCIE_PCS_OSC_DTCT_CONFIG4_REG(ab),
PCIE_PCS_OSC_DTCT_CONFIG4_VAL,
PCIE_PCS_OSC_DTCT_CONFIG_MSK);
if (ret) {
ath11k_warn(ab, "failed to set dtct config4: %d\n", ret);
return ret;
@ -406,14 +470,15 @@ int ath11k_pci_get_user_msi_assignment(struct ath11k_pci *ab_pci, char *user_nam
u32 *base_vector)
{
struct ath11k_base *ab = ab_pci->ab;
const struct ath11k_msi_config *msi_config = ab_pci->msi_config;
int idx;
for (idx = 0; idx < msi_config.total_users; idx++) {
if (strcmp(user_name, msi_config.users[idx].name) == 0) {
*num_vectors = msi_config.users[idx].num_vectors;
*user_base_data = msi_config.users[idx].base_vector
for (idx = 0; idx < msi_config->total_users; idx++) {
if (strcmp(user_name, msi_config->users[idx].name) == 0) {
*num_vectors = msi_config->users[idx].num_vectors;
*user_base_data = msi_config->users[idx].base_vector
+ ab_pci->msi_ep_base_data;
*base_vector = msi_config.users[idx].base_vector;
*base_vector = msi_config->users[idx].base_vector;
ath11k_dbg(ab, ATH11K_DBG_PCI, "Assign MSI to user: %s, num_vectors: %d, user_base_data: %u, base_vector: %u\n",
user_name, *num_vectors, *user_base_data,
@ -428,6 +493,23 @@ int ath11k_pci_get_user_msi_assignment(struct ath11k_pci *ab_pci, char *user_nam
return -EINVAL;
}
static void ath11k_pci_get_ce_msi_idx(struct ath11k_base *ab, u32 ce_id,
u32 *msi_idx)
{
u32 i, msi_data_idx;
for (i = 0, msi_data_idx = 0; i < ab->hw_params.ce_count; i++) {
if (ath11k_ce_get_attr_flags(ab, i) & CE_ATTR_DIS_INTR)
continue;
if (ce_id == i)
break;
msi_data_idx++;
}
*msi_idx = msi_data_idx;
}
static int ath11k_get_user_msi_assignment(struct ath11k_base *ab, char *user_name,
int *num_vectors, u32 *user_base_data,
u32 *base_vector)
@ -521,6 +603,9 @@ static irqreturn_t ath11k_pci_ce_interrupt_handler(int irq, void *arg)
{
struct ath11k_ce_pipe *ce_pipe = arg;
/* last interrupt received for this CE */
ce_pipe->timestamp = jiffies;
ath11k_pci_ce_irq_disable(ce_pipe->ab, ce_pipe->pipe_num);
tasklet_schedule(&ce_pipe->intr_tq);
@ -615,6 +700,9 @@ static irqreturn_t ath11k_pci_ext_interrupt_handler(int irq, void *arg)
ath11k_dbg(irq_grp->ab, ATH11K_DBG_PCI, "ext irq:%d\n", irq);
/* last interrupt received for this group */
irq_grp->timestamp = jiffies;
ath11k_pci_ext_grp_disable(irq_grp);
napi_schedule(&irq_grp->napi);
@ -625,8 +713,9 @@ static irqreturn_t ath11k_pci_ext_interrupt_handler(int irq, void *arg)
static int ath11k_pci_ext_irq_config(struct ath11k_base *ab)
{
int i, j, ret, num_vectors = 0;
u32 user_base_data = 0, base_vector = 0;
u32 user_base_data = 0, base_vector = 0, base_idx;
base_idx = ATH11K_PCI_IRQ_CE0_OFFSET + CE_COUNT_MAX;
ret = ath11k_pci_get_user_msi_assignment(ath11k_pci_priv(ab), "DP",
&num_vectors,
&user_base_data,
@ -656,7 +745,7 @@ static int ath11k_pci_ext_irq_config(struct ath11k_base *ab)
}
irq_grp->num_irq = num_irq;
irq_grp->irqs[0] = base_vector + i;
irq_grp->irqs[0] = base_idx + i;
for (j = 0; j < irq_grp->num_irq; j++) {
int irq_idx = irq_grp->irqs[j];
@ -667,6 +756,8 @@ static int ath11k_pci_ext_irq_config(struct ath11k_base *ab)
ath11k_dbg(ab, ATH11K_DBG_PCI,
"irq:%d group:%d\n", irq, i);
irq_set_status_flags(irq, IRQ_DISABLE_UNLAZY);
ret = request_irq(irq, ath11k_pci_ext_interrupt_handler,
IRQF_SHARED,
"DP_EXT_IRQ", irq_grp);
@ -687,7 +778,7 @@ static int ath11k_pci_config_irq(struct ath11k_base *ab)
{
struct ath11k_ce_pipe *ce_pipe;
u32 msi_data_start;
u32 msi_data_count;
u32 msi_data_count, msi_data_idx;
u32 msi_irq_start;
unsigned int msi_data;
int irq, i, ret, irq_idx;
@ -699,14 +790,14 @@ static int ath11k_pci_config_irq(struct ath11k_base *ab)
return ret;
/* Configure CE irqs */
for (i = 0; i < ab->hw_params.ce_count; i++) {
msi_data = (i % msi_data_count) + msi_irq_start;
irq = ath11k_pci_get_msi_irq(ab->dev, msi_data);
ce_pipe = &ab->ce.ce_pipe[i];
for (i = 0, msi_data_idx = 0; i < ab->hw_params.ce_count; i++) {
if (ath11k_ce_get_attr_flags(ab, i) & CE_ATTR_DIS_INTR)
continue;
msi_data = (msi_data_idx % msi_data_count) + msi_irq_start;
irq = ath11k_pci_get_msi_irq(ab->dev, msi_data);
ce_pipe = &ab->ce.ce_pipe[i];
irq_idx = ATH11K_PCI_IRQ_CE0_OFFSET + i;
tasklet_setup(&ce_pipe->intr_tq, ath11k_pci_ce_tasklet);
@ -721,6 +812,8 @@ static int ath11k_pci_config_irq(struct ath11k_base *ab)
}
ab->irq_num[irq_idx] = irq;
msi_data_idx++;
ath11k_pci_ce_irq_disable(ab, i);
}
@ -740,7 +833,7 @@ static void ath11k_pci_init_qmi_ce_config(struct ath11k_base *ab)
cfg->svc_to_ce_map = ab->hw_params.svc_to_ce_map;
cfg->svc_to_ce_map_len = ab->hw_params.svc_to_ce_map_len;
ab->qmi.service_ins_id = ATH11K_QMI_WLFW_SERVICE_INS_ID_V01_QCA6390;
ab->qmi.service_ins_id = ab->hw_params.qmi_service_ins_id;
ath11k_ce_get_shadow_config(ab, &cfg->shadow_reg_v2,
&cfg->shadow_reg_v2_len);
@ -760,17 +853,18 @@ static void ath11k_pci_ce_irqs_enable(struct ath11k_base *ab)
static int ath11k_pci_enable_msi(struct ath11k_pci *ab_pci)
{
struct ath11k_base *ab = ab_pci->ab;
const struct ath11k_msi_config *msi_config = ab_pci->msi_config;
struct msi_desc *msi_desc;
int num_vectors;
int ret;
num_vectors = pci_alloc_irq_vectors(ab_pci->pdev,
msi_config.total_vectors,
msi_config.total_vectors,
msi_config->total_vectors,
msi_config->total_vectors,
PCI_IRQ_MSI);
if (num_vectors != msi_config.total_vectors) {
if (num_vectors != msi_config->total_vectors) {
ath11k_err(ab, "failed to get %d MSI vectors, only %d available",
msi_config.total_vectors, num_vectors);
msi_config->total_vectors, num_vectors);
if (num_vectors >= 0)
return -EINVAL;
@ -932,6 +1026,9 @@ static int ath11k_pci_power_up(struct ath11k_base *ab)
return ret;
}
if (ab->bus_params.static_window_map)
ath11k_pci_select_static_window(ab_pci);
return 0;
}
@ -1076,6 +1173,7 @@ static const struct ath11k_hif_ops ath11k_pci_hif_ops = {
.map_service_to_pipe = ath11k_pci_map_service_to_pipe,
.ce_irq_enable = ath11k_pci_hif_ce_irq_enable,
.ce_irq_disable = ath11k_pci_hif_ce_irq_disable,
.get_ce_msi_idx = ath11k_pci_get_ce_msi_idx,
};
static int ath11k_pci_probe(struct pci_dev *pdev,
@ -1130,6 +1228,12 @@ static int ath11k_pci_probe(struct pci_dev *pdev,
ret = -EOPNOTSUPP;
goto err_pci_free_region;
}
ab_pci->msi_config = &ath11k_msi_config[0];
break;
case QCN9074_DEVICE_ID:
ab_pci->msi_config = &ath11k_msi_config[1];
ab->bus_params.static_window_map = true;
ab->hw_rev = ATH11K_HW_QCN9074_HW10;
break;
default:
dev_err(&pdev->dev, "Unknown PCI device found: 0x%x\n",

View File

@ -34,16 +34,20 @@
#define PCIE_SMLH_REQ_RST_LINK_DOWN 0x2
#define PCIE_INT_CLEAR_ALL 0xffffffff
#define PCIE_QSERDES_COM_SYSCLK_EN_SEL_REG 0x01e0c0ac
#define PCIE_QSERDES_COM_SYSCLK_EN_SEL_REG(x) \
(ab->hw_params.regs->pcie_qserdes_sysclk_en_sel)
#define PCIE_QSERDES_COM_SYSCLK_EN_SEL_VAL 0x10
#define PCIE_QSERDES_COM_SYSCLK_EN_SEL_MSK 0xffffffff
#define PCIE_USB3_PCS_MISC_OSC_DTCT_CONFIG1_REG 0x01e0c628
#define PCIE_USB3_PCS_MISC_OSC_DTCT_CONFIG1_VAL 0x02
#define PCIE_USB3_PCS_MISC_OSC_DTCT_CONFIG2_REG 0x01e0c62c
#define PCIE_USB3_PCS_MISC_OSC_DTCT_CONFIG2_VAL 0x52
#define PCIE_USB3_PCS_MISC_OSC_DTCT_CONFIG4_REG 0x01e0c634
#define PCIE_USB3_PCS_MISC_OSC_DTCT_CONFIG4_VAL 0xff
#define PCIE_USB3_PCS_MISC_OSC_DTCT_CONFIG_MSK 0x000000ff
#define PCIE_PCS_OSC_DTCT_CONFIG1_REG(x) \
(ab->hw_params.regs->pcie_pcs_osc_dtct_config_base)
#define PCIE_PCS_OSC_DTCT_CONFIG1_VAL 0x02
#define PCIE_PCS_OSC_DTCT_CONFIG2_REG(x) \
(ab->hw_params.regs->pcie_pcs_osc_dtct_config_base + 0x4)
#define PCIE_PCS_OSC_DTCT_CONFIG2_VAL 0x52
#define PCIE_PCS_OSC_DTCT_CONFIG4_REG(x) \
(ab->hw_params.regs->pcie_pcs_osc_dtct_config_base + 0xc)
#define PCIE_PCS_OSC_DTCT_CONFIG4_VAL 0xff
#define PCIE_PCS_OSC_DTCT_CONFIG_MSK 0x000000ff
#define WLAON_QFPROM_PWR_CTRL_REG 0x01f8031c
#define QFPROM_PWR_CTRL_VDD4BLOW_MASK 0x4
@ -73,6 +77,7 @@ struct ath11k_pci {
char amss_path[100];
u32 msi_ep_base_data;
struct mhi_controller *mhi_ctrl;
const struct ath11k_msi_config *msi_config;
unsigned long mhi_state;
u32 register_window;

View File

@ -1556,6 +1556,8 @@ static int ath11k_qmi_host_cap_send(struct ath11k_base *ab)
req.nm_modem |= SLEEP_CLOCK_SELECT_INTERNAL_BIT;
}
ath11k_dbg(ab, ATH11K_DBG_QMI, "qmi host cap request\n");
ret = qmi_txn_init(&ab->qmi.handle, &txn,
qmi_wlanfw_host_cap_resp_msg_v01_ei, &resp);
if (ret < 0)
@ -1566,7 +1568,7 @@ static int ath11k_qmi_host_cap_send(struct ath11k_base *ab)
QMI_WLANFW_HOST_CAP_REQ_MSG_V01_MAX_LEN,
qmi_wlanfw_host_cap_req_msg_v01_ei, &req);
if (ret < 0) {
ath11k_warn(ab, "Failed to send host capability request,err = %d\n", ret);
ath11k_warn(ab, "failed to send host capability request: %d\n", ret);
goto out;
}
@ -1575,7 +1577,7 @@ static int ath11k_qmi_host_cap_send(struct ath11k_base *ab)
goto out;
if (resp.resp.result != QMI_RESULT_SUCCESS_V01) {
ath11k_warn(ab, "Host capability request failed, result: %d, err: %d\n",
ath11k_warn(ab, "host capability request failed: %d %d\n",
resp.resp.result, resp.resp.error);
ret = -EINVAL;
goto out;
@ -1624,24 +1626,26 @@ static int ath11k_qmi_fw_ind_register_send(struct ath11k_base *ab)
if (ret < 0)
goto out;
ath11k_dbg(ab, ATH11K_DBG_QMI, "qmi indication register request\n");
ret = qmi_send_request(&ab->qmi.handle, NULL, &txn,
QMI_WLANFW_IND_REGISTER_REQ_V01,
QMI_WLANFW_IND_REGISTER_REQ_MSG_V01_MAX_LEN,
qmi_wlanfw_ind_register_req_msg_v01_ei, req);
if (ret < 0) {
ath11k_warn(ab, "Failed to send indication register request, err = %d\n",
ath11k_warn(ab, "failed to send indication register request: %d\n",
ret);
goto out;
}
ret = qmi_txn_wait(&txn, msecs_to_jiffies(ATH11K_QMI_WLANFW_TIMEOUT_MS));
if (ret < 0) {
ath11k_warn(ab, "failed to register fw indication %d\n", ret);
ath11k_warn(ab, "failed to register fw indication: %d\n", ret);
goto out;
}
if (resp->resp.result != QMI_RESULT_SUCCESS_V01) {
ath11k_warn(ab, "FW Ind register request failed, result: %d, err: %d\n",
ath11k_warn(ab, "firmware indication register request failed: %d %d\n",
resp->resp.result, resp->resp.error);
ret = -EINVAL;
goto out;
@ -1699,19 +1703,22 @@ static int ath11k_qmi_respond_fw_mem_request(struct ath11k_base *ab)
if (ret < 0)
goto out;
ath11k_dbg(ab, ATH11K_DBG_QMI, "qmi respond memory request delayed %i\n",
delayed);
ret = qmi_send_request(&ab->qmi.handle, NULL, &txn,
QMI_WLANFW_RESPOND_MEM_REQ_V01,
QMI_WLANFW_RESPOND_MEM_REQ_MSG_V01_MAX_LEN,
qmi_wlanfw_respond_mem_req_msg_v01_ei, req);
if (ret < 0) {
ath11k_warn(ab, "qmi failed to respond memory request, err = %d\n",
ath11k_warn(ab, "failed to respond qmi memory request: %d\n",
ret);
goto out;
}
ret = qmi_txn_wait(&txn, msecs_to_jiffies(ATH11K_QMI_WLANFW_TIMEOUT_MS));
if (ret < 0) {
ath11k_warn(ab, "qmi failed memory request, err = %d\n", ret);
ath11k_warn(ab, "failed to wait qmi memory request: %d\n", ret);
goto out;
}
@ -1722,7 +1729,7 @@ static int ath11k_qmi_respond_fw_mem_request(struct ath11k_base *ab)
if (delayed && resp.resp.error == 0)
goto out;
ath11k_warn(ab, "Respond mem req failed, result: %d, err: %d\n",
ath11k_warn(ab, "qmi respond memory request failed: %d %d\n",
resp.resp.result, resp.resp.error);
ret = -EINVAL;
goto out;
@ -1765,7 +1772,7 @@ static int ath11k_qmi_alloc_target_mem_chunk(struct ath11k_base *ab)
&chunk->paddr,
GFP_KERNEL);
if (!chunk->vaddr) {
if (ab->qmi.mem_seg_count <= 2) {
if (ab->qmi.mem_seg_count <= ATH11K_QMI_FW_MEM_REQ_SEGMENT_CNT) {
ath11k_dbg(ab, ATH11K_DBG_QMI,
"qmi dma allocation failed (%d B type %u), will try later with small size\n",
chunk->size,
@ -1774,7 +1781,8 @@ static int ath11k_qmi_alloc_target_mem_chunk(struct ath11k_base *ab)
ab->qmi.target_mem_delayed = true;
return 0;
}
ath11k_err(ab, "failed to alloc memory, size: 0x%x, type: %u\n",
ath11k_err(ab, "failed to allocate dma memory for qmi (%d B type %u)\n",
chunk->size,
chunk->type);
return -EINVAL;
@ -1843,24 +1851,26 @@ static int ath11k_qmi_request_target_cap(struct ath11k_base *ab)
if (ret < 0)
goto out;
ath11k_dbg(ab, ATH11K_DBG_QMI, "qmi target cap request\n");
ret = qmi_send_request(&ab->qmi.handle, NULL, &txn,
QMI_WLANFW_CAP_REQ_V01,
QMI_WLANFW_CAP_REQ_MSG_V01_MAX_LEN,
qmi_wlanfw_cap_req_msg_v01_ei, &req);
if (ret < 0) {
ath11k_warn(ab, "qmi failed to send target cap request, err = %d\n",
ath11k_warn(ab, "failed to send qmi cap request: %d\n",
ret);
goto out;
}
ret = qmi_txn_wait(&txn, msecs_to_jiffies(ATH11K_QMI_WLANFW_TIMEOUT_MS));
if (ret < 0) {
ath11k_warn(ab, "qmi failed target cap request %d\n", ret);
ath11k_warn(ab, "failed to wait qmi cap request: %d\n", ret);
goto out;
}
if (resp.resp.result != QMI_RESULT_SUCCESS_V01) {
ath11k_warn(ab, "qmi targetcap req failed, result: %d, err: %d\n",
ath11k_warn(ab, "qmi cap request failed: %d %d\n",
resp.resp.result, resp.resp.error);
ret = -EINVAL;
goto out;
@ -1923,7 +1933,7 @@ ath11k_qmi_prepare_bdf_download(struct ath11k_base *ab, int type,
ret = ath11k_core_fetch_bdf(ab, &bd);
if (ret) {
ath11k_warn(ab, "qmi failed to load BDF\n");
ath11k_warn(ab, "failed to load board file: %d\n", ret);
return ret;
}
@ -1971,7 +1981,7 @@ static int ath11k_qmi_load_bdf_fixed_addr(struct ath11k_base *ab)
bdf_addr = ioremap(ab->hw_params.bdf_addr, ATH11K_QMI_BDF_MAX_SIZE);
if (!bdf_addr) {
ath11k_warn(ab, "qmi ioremap error for BDF\n");
ath11k_warn(ab, "failed ioremap for board file\n");
ret = -EIO;
goto out;
}
@ -2000,6 +2010,9 @@ static int ath11k_qmi_load_bdf_fixed_addr(struct ath11k_base *ab)
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,
@ -2014,7 +2027,7 @@ static int ath11k_qmi_load_bdf_fixed_addr(struct ath11k_base *ab)
goto out_qmi_bdf;
if (resp.resp.result != QMI_RESULT_SUCCESS_V01) {
ath11k_warn(ab, "qmi BDF download failed, result: %d, err: %d\n",
ath11k_warn(ab, "board file download request failed: %d %d\n",
resp.resp.result, resp.resp.error);
ret = -EINVAL;
goto out_qmi_bdf;
@ -2047,7 +2060,7 @@ static int ath11k_qmi_load_bdf_qmi(struct ath11k_base *ab)
memset(&bd, 0, sizeof(bd));
ret = ath11k_core_fetch_bdf(ab, &bd);
if (ret) {
ath11k_warn(ab, "qmi failed to load bdf:\n");
ath11k_warn(ab, "failed to fetch board file: %d\n", ret);
goto out;
}
@ -2090,6 +2103,9 @@ static int ath11k_qmi_load_bdf_qmi(struct ath11k_base *ab)
if (ret < 0)
goto out_qmi_bdf;
ath11k_dbg(ab, ATH11K_DBG_QMI, "qmi bdf download request remaining %i\n",
remaining);
ret = qmi_send_request(&ab->qmi.handle, NULL, &txn,
QMI_WLANFW_BDF_DOWNLOAD_REQ_V01,
QMI_WLANFW_BDF_DOWNLOAD_REQ_MSG_V01_MAX_LEN,
@ -2104,7 +2120,7 @@ static int ath11k_qmi_load_bdf_qmi(struct ath11k_base *ab)
goto out_qmi_bdf;
if (resp.resp.result != QMI_RESULT_SUCCESS_V01) {
ath11k_warn(ab, "qmi BDF download failed, result: %d, err: %d\n",
ath11k_warn(ab, "bdf download request failed: %d %d\n",
resp.resp.result, resp.resp.error);
ret = resp.resp.result;
goto out_qmi_bdf;
@ -2200,24 +2216,26 @@ static int ath11k_qmi_wlanfw_m3_info_send(struct ath11k_base *ab)
if (ret < 0)
goto out;
ath11k_dbg(ab, ATH11K_DBG_QMI, "qmi m3 info req\n");
ret = qmi_send_request(&ab->qmi.handle, NULL, &txn,
QMI_WLANFW_M3_INFO_REQ_V01,
QMI_WLANFW_M3_INFO_REQ_MSG_V01_MAX_MSG_LEN,
qmi_wlanfw_m3_info_req_msg_v01_ei, &req);
if (ret < 0) {
ath11k_warn(ab, "qmi failed to send M3 information request, err = %d\n",
ath11k_warn(ab, "failed to send m3 information request: %d\n",
ret);
goto out;
}
ret = qmi_txn_wait(&txn, msecs_to_jiffies(ATH11K_QMI_WLANFW_TIMEOUT_MS));
if (ret < 0) {
ath11k_warn(ab, "qmi failed M3 information request %d\n", ret);
ath11k_warn(ab, "failed to wait m3 information request: %d\n", ret);
goto out;
}
if (resp.resp.result != QMI_RESULT_SUCCESS_V01) {
ath11k_warn(ab, "qmi M3 info request failed, result: %d, err: %d\n",
ath11k_warn(ab, "m3 info request failed: %d %d\n",
resp.resp.result, resp.resp.error);
ret = -EINVAL;
goto out;
@ -2246,12 +2264,14 @@ static int ath11k_qmi_wlanfw_mode_send(struct ath11k_base *ab,
if (ret < 0)
goto out;
ath11k_dbg(ab, ATH11K_DBG_QMI, "qmi wlan mode req mode %d\n", mode);
ret = qmi_send_request(&ab->qmi.handle, NULL, &txn,
QMI_WLANFW_WLAN_MODE_REQ_V01,
QMI_WLANFW_WLAN_MODE_REQ_MSG_V01_MAX_LEN,
qmi_wlanfw_wlan_mode_req_msg_v01_ei, &req);
if (ret < 0) {
ath11k_warn(ab, "qmi failed to send mode request, mode: %d, err = %d\n",
ath11k_warn(ab, "failed to send wlan mode request (mode %d): %d\n",
mode, ret);
goto out;
}
@ -2262,13 +2282,13 @@ static int ath11k_qmi_wlanfw_mode_send(struct ath11k_base *ab,
ath11k_warn(ab, "WLFW service is dis-connected\n");
return 0;
}
ath11k_warn(ab, "qmi failed set mode request, mode: %d, err = %d\n",
ath11k_warn(ab, "failed to wait wlan mode request (mode %d): %d\n",
mode, ret);
goto out;
}
if (resp.resp.result != QMI_RESULT_SUCCESS_V01) {
ath11k_warn(ab, "Mode request failed, mode: %d, result: %d err: %d\n",
ath11k_warn(ab, "wlan mode request failed (mode: %d): %d %d\n",
mode, resp.resp.result, resp.resp.error);
ret = -EINVAL;
goto out;
@ -2338,24 +2358,26 @@ static int ath11k_qmi_wlanfw_wlan_cfg_send(struct ath11k_base *ab)
if (ret < 0)
goto out;
ath11k_dbg(ab, ATH11K_DBG_QMI, "qmi wlan cfg req\n");
ret = qmi_send_request(&ab->qmi.handle, NULL, &txn,
QMI_WLANFW_WLAN_CFG_REQ_V01,
QMI_WLANFW_WLAN_CFG_REQ_MSG_V01_MAX_LEN,
qmi_wlanfw_wlan_cfg_req_msg_v01_ei, req);
if (ret < 0) {
ath11k_warn(ab, "qmi failed to send wlan config request, err = %d\n",
ath11k_warn(ab, "failed to send wlan config request: %d\n",
ret);
goto out;
}
ret = qmi_txn_wait(&txn, msecs_to_jiffies(ATH11K_QMI_WLANFW_TIMEOUT_MS));
if (ret < 0) {
ath11k_warn(ab, "qmi failed wlan config request, err = %d\n", ret);
ath11k_warn(ab, "failed to wait wlan config request: %d\n", ret);
goto out;
}
if (resp.resp.result != QMI_RESULT_SUCCESS_V01) {
ath11k_warn(ab, "qmi wlan config request failed, result: %d, err: %d\n",
ath11k_warn(ab, "wlan config request failed: %d %d\n",
resp.resp.result, resp.resp.error);
ret = -EINVAL;
goto out;
@ -2370,9 +2392,11 @@ void ath11k_qmi_firmware_stop(struct ath11k_base *ab)
{
int ret;
ath11k_dbg(ab, ATH11K_DBG_QMI, "qmi firmware stop\n");
ret = ath11k_qmi_wlanfw_mode_send(ab, ATH11K_FIRMWARE_MODE_OFF);
if (ret < 0) {
ath11k_warn(ab, "qmi failed to send wlan mode off\n");
ath11k_warn(ab, "qmi failed to send wlan mode off: %d\n", ret);
return;
}
}
@ -2382,15 +2406,17 @@ int ath11k_qmi_firmware_start(struct ath11k_base *ab,
{
int ret;
ath11k_dbg(ab, ATH11K_DBG_QMI, "qmi firmware start\n");
ret = ath11k_qmi_wlanfw_wlan_cfg_send(ab);
if (ret < 0) {
ath11k_warn(ab, "qmi failed to send wlan cfg:%d\n", ret);
ath11k_warn(ab, "qmi failed to send wlan cfg: %d\n", ret);
return ret;
}
ret = ath11k_qmi_wlanfw_mode_send(ab, mode);
if (ret < 0) {
ath11k_warn(ab, "qmi failed to send wlan fw mode:%d\n", ret);
ath11k_warn(ab, "qmi failed to send wlan fw mode: %d\n", ret);
return ret;
}
@ -2404,7 +2430,7 @@ static int ath11k_qmi_process_coldboot_calibration(struct ath11k_base *ab)
ret = ath11k_qmi_wlanfw_mode_send(ab, ATH11K_FIRMWARE_MODE_COLD_BOOT);
if (ret < 0) {
ath11k_warn(ab, "qmi failed to send wlan fw mode:%d\n", ret);
ath11k_warn(ab, "qmi failed to send wlan fw mode: %d\n", ret);
return ret;
}
@ -2414,7 +2440,7 @@ static int ath11k_qmi_process_coldboot_calibration(struct ath11k_base *ab)
(ab->qmi.cal_done == 1),
ATH11K_COLD_BOOT_FW_RESET_DELAY);
if (timeout <= 0) {
ath11k_warn(ab, "Coldboot Calibration failed - wait ended\n");
ath11k_warn(ab, "coldboot calibration timed out\n");
return 0;
}
@ -2453,13 +2479,14 @@ static int ath11k_qmi_event_server_arrive(struct ath11k_qmi *qmi)
ret = ath11k_qmi_fw_ind_register_send(ab);
if (ret < 0) {
ath11k_warn(ab, "qmi failed to send FW indication QMI:%d\n", ret);
ath11k_warn(ab, "failed to send qmi firmware indication: %d\n",
ret);
return ret;
}
ret = ath11k_qmi_host_cap_send(ab);
if (ret < 0) {
ath11k_warn(ab, "qmi failed to send host cap QMI:%d\n", ret);
ath11k_warn(ab, "failed to send qmi host cap: %d\n", ret);
return ret;
}
@ -2473,7 +2500,7 @@ static int ath11k_qmi_event_mem_request(struct ath11k_qmi *qmi)
ret = ath11k_qmi_respond_fw_mem_request(ab);
if (ret < 0) {
ath11k_warn(ab, "qmi failed to respond fw mem req:%d\n", ret);
ath11k_warn(ab, "qmi failed to respond fw mem req: %d\n", ret);
return ret;
}
@ -2487,7 +2514,8 @@ static int ath11k_qmi_event_load_bdf(struct ath11k_qmi *qmi)
ret = ath11k_qmi_request_target_cap(ab);
if (ret < 0) {
ath11k_warn(ab, "qmi failed to req target capabilities:%d\n", ret);
ath11k_warn(ab, "failed to requeqst qmi target capabilities: %d\n",
ret);
return ret;
}
@ -2496,13 +2524,13 @@ static int ath11k_qmi_event_load_bdf(struct ath11k_qmi *qmi)
else
ret = ath11k_qmi_load_bdf_qmi(ab);
if (ret < 0) {
ath11k_warn(ab, "qmi failed to load board data file:%d\n", ret);
ath11k_warn(ab, "failed to load board data file: %d\n", ret);
return ret;
}
ret = ath11k_qmi_wlanfw_m3_info_send(ab);
if (ret < 0) {
ath11k_warn(ab, "qmi failed to send m3 info req:%d\n", ret);
ath11k_warn(ab, "failed to send qmi m3 info req: %d\n", ret);
return ret;
}
@ -2523,7 +2551,7 @@ static void ath11k_qmi_msg_mem_request_cb(struct qmi_handle *qmi_hdl,
if (msg->mem_seg_len == 0 ||
msg->mem_seg_len > ATH11K_QMI_WLANFW_MAX_NUM_MEM_SEG_V01)
ath11k_warn(ab, "Invalid memory segment length: %u\n",
ath11k_warn(ab, "invalid memory segment length: %u\n",
msg->mem_seg_len);
ab->qmi.mem_seg_count = msg->mem_seg_len;
@ -2538,14 +2566,14 @@ static void ath11k_qmi_msg_mem_request_cb(struct qmi_handle *qmi_hdl,
if (ab->bus_params.fixed_mem_region) {
ret = ath11k_qmi_assign_target_mem_chunk(ab);
if (ret) {
ath11k_warn(ab, "qmi failed to assign target memory: %d\n",
ath11k_warn(ab, "failed to assign qmi target memory: %d\n",
ret);
return;
}
} else {
ret = ath11k_qmi_alloc_target_mem_chunk(ab);
if (ret) {
ath11k_warn(ab, "qmi failed to alloc target memory: %d\n",
ath11k_warn(ab, "failed to allocate qmi target memory: %d\n",
ret);
return;
}
@ -2639,7 +2667,7 @@ static int ath11k_qmi_ops_new_server(struct qmi_handle *qmi_hdl,
ret = kernel_connect(qmi_hdl->sock, (struct sockaddr *)sq,
sizeof(*sq), 0);
if (ret) {
ath11k_warn(ab, "qmi failed to connect to remote service %d\n", ret);
ath11k_warn(ab, "failed to connect to qmi remote service: %d\n", ret);
return ret;
}
@ -2725,7 +2753,7 @@ static void ath11k_qmi_driver_event_work(struct work_struct *work)
case ATH11K_QMI_EVENT_COLD_BOOT_CAL_DONE:
break;
default:
ath11k_warn(ab, "invalid event type: %d", event->type);
ath11k_warn(ab, "invalid qmi event type: %d", event->type);
break;
}
kfree(event);
@ -2746,7 +2774,7 @@ int ath11k_qmi_init_service(struct ath11k_base *ab)
ret = qmi_handle_init(&ab->qmi.handle, ATH11K_QMI_RESP_LEN_MAX,
&ath11k_qmi_ops, ath11k_qmi_msg_handlers);
if (ret < 0) {
ath11k_warn(ab, "failed to initialize qmi handle\n");
ath11k_warn(ab, "failed to initialize qmi handle: %d\n", ret);
return ret;
}
@ -2765,7 +2793,7 @@ int ath11k_qmi_init_service(struct ath11k_base *ab)
ATH11K_QMI_WLFW_SERVICE_VERS_V01,
ab->qmi.service_ins_id);
if (ret < 0) {
ath11k_warn(ab, "failed to add qmi lookup\n");
ath11k_warn(ab, "failed to add qmi lookup: %d\n", ret);
destroy_workqueue(ab->qmi.event_wq);
return ret;
}

View File

@ -21,11 +21,13 @@
#define ATH11K_QMI_WLFW_SERVICE_INS_ID_V01 0x02
#define ATH11K_QMI_WLFW_SERVICE_INS_ID_V01_QCA6390 0x01
#define ATH11K_QMI_WLFW_SERVICE_INS_ID_V01_IPQ8074 0x02
#define ATH11K_QMI_WLFW_SERVICE_INS_ID_V01_QCN9074 0x07
#define ATH11K_QMI_WLANFW_MAX_TIMESTAMP_LEN_V01 32
#define ATH11K_QMI_RESP_LEN_MAX 8192
#define ATH11K_QMI_WLANFW_MAX_NUM_MEM_SEG_V01 32
#define ATH11K_QMI_WLANFW_MAX_NUM_MEM_SEG_V01 52
#define ATH11K_QMI_CALDB_SIZE 0x480000
#define ATH11K_QMI_BDF_EXT_STR_LENGTH 0x20
#define ATH11K_QMI_FW_MEM_REQ_SEGMENT_CNT 3
#define QMI_WLFW_REQUEST_MEM_IND_V01 0x0035
#define QMI_WLFW_FW_MEM_READY_IND_V01 0x0037
@ -141,6 +143,7 @@ struct ath11k_qmi {
#define QMI_IPQ8074_FW_MEM_MODE 0xFF
#define HOST_DDR_REGION_TYPE 0x1
#define BDF_MEM_REGION_TYPE 0x2
#define M3_DUMP_REGION_TYPE 0x3
#define CALDB_MEM_REGION_TYPE 0x4
struct qmi_wlanfw_host_cap_req_msg_v01 {
@ -216,8 +219,8 @@ struct qmi_wlanfw_ind_register_resp_msg_v01 {
u64 fw_status;
};
#define QMI_WLANFW_REQUEST_MEM_IND_MSG_V01_MAX_LEN 1124
#define QMI_WLANFW_RESPOND_MEM_REQ_MSG_V01_MAX_LEN 548
#define QMI_WLANFW_REQUEST_MEM_IND_MSG_V01_MAX_LEN 1824
#define QMI_WLANFW_RESPOND_MEM_REQ_MSG_V01_MAX_LEN 888
#define QMI_WLANFW_RESPOND_MEM_RESP_MSG_V01_MAX_LEN 7
#define QMI_WLANFW_REQUEST_MEM_IND_V01 0x0035
#define QMI_WLANFW_RESPOND_MEM_REQ_V01 0x0036

View File

@ -414,7 +414,7 @@ struct rx_attention {
#define RX_MPDU_START_RAW_MPDU BIT(0)
struct rx_mpdu_start {
struct rx_mpdu_start_ipq8074 {
__le16 info0;
__le16 phy_ppdu_id;
__le16 ast_index;
@ -440,6 +440,112 @@ struct rx_mpdu_start {
__le32 raw;
} __packed;
#define RX_MPDU_START_INFO7_REO_DEST_IND GENMASK(4, 0)
#define RX_MPDU_START_INFO7_LMAC_PEER_ID_MSB GENMASK(6, 5)
#define RX_MPDU_START_INFO7_FLOW_ID_TOEPLITZ BIT(7)
#define RX_MPDU_START_INFO7_PKT_SEL_FP_UCAST_DATA BIT(8)
#define RX_MPDU_START_INFO7_PKT_SEL_FP_MCAST_DATA BIT(9)
#define RX_MPDU_START_INFO7_PKT_SEL_FP_CTRL_BAR BIT(10)
#define RX_MPDU_START_INFO7_RXDMA0_SRC_RING_SEL GENMASK(12, 11)
#define RX_MPDU_START_INFO7_RXDMA0_DST_RING_SEL GENMASK(14, 13)
#define RX_MPDU_START_INFO8_REO_QUEUE_DESC_HI GENMASK(7, 0)
#define RX_MPDU_START_INFO8_RECV_QUEUE_NUM GENMASK(23, 8)
#define RX_MPDU_START_INFO8_PRE_DELIM_ERR_WARN BIT(24)
#define RX_MPDU_START_INFO8_FIRST_DELIM_ERR BIT(25)
#define RX_MPDU_START_INFO9_EPD_EN BIT(0)
#define RX_MPDU_START_INFO9_ALL_FRAME_ENCPD BIT(1)
#define RX_MPDU_START_INFO9_ENC_TYPE GENMASK(5, 2)
#define RX_MPDU_START_INFO9_VAR_WEP_KEY_WIDTH GENMASK(7, 6)
#define RX_MPDU_START_INFO9_MESH_STA GENMASK(9, 8)
#define RX_MPDU_START_INFO9_BSSID_HIT BIT(10)
#define RX_MPDU_START_INFO9_BSSID_NUM GENMASK(14, 11)
#define RX_MPDU_START_INFO9_TID GENMASK(18, 15)
#define RX_MPDU_START_INFO10_RXPCU_MPDU_FLTR GENMASK(1, 0)
#define RX_MPDU_START_INFO10_SW_FRAME_GRP_ID GENMASK(8, 2)
#define RX_MPDU_START_INFO10_NDP_FRAME BIT(9)
#define RX_MPDU_START_INFO10_PHY_ERR BIT(10)
#define RX_MPDU_START_INFO10_PHY_ERR_MPDU_HDR BIT(11)
#define RX_MPDU_START_INFO10_PROTO_VER_ERR BIT(12)
#define RX_MPDU_START_INFO10_AST_LOOKUP_VALID BIT(13)
#define RX_MPDU_START_INFO11_MPDU_FCTRL_VALID BIT(0)
#define RX_MPDU_START_INFO11_MPDU_DUR_VALID BIT(1)
#define RX_MPDU_START_INFO11_MAC_ADDR1_VALID BIT(2)
#define RX_MPDU_START_INFO11_MAC_ADDR2_VALID BIT(3)
#define RX_MPDU_START_INFO11_MAC_ADDR3_VALID BIT(4)
#define RX_MPDU_START_INFO11_MAC_ADDR4_VALID BIT(5)
#define RX_MPDU_START_INFO11_MPDU_SEQ_CTRL_VALID BIT(6)
#define RX_MPDU_START_INFO11_MPDU_QOS_CTRL_VALID BIT(7)
#define RX_MPDU_START_INFO11_MPDU_HT_CTRL_VALID BIT(8)
#define RX_MPDU_START_INFO11_ENCRYPT_INFO_VALID BIT(9)
#define RX_MPDU_START_INFO11_MPDU_FRAG_NUMBER GENMASK(13, 10)
#define RX_MPDU_START_INFO11_MORE_FRAG_FLAG BIT(14)
#define RX_MPDU_START_INFO11_FROM_DS BIT(16)
#define RX_MPDU_START_INFO11_TO_DS BIT(17)
#define RX_MPDU_START_INFO11_ENCRYPTED BIT(18)
#define RX_MPDU_START_INFO11_MPDU_RETRY BIT(19)
#define RX_MPDU_START_INFO11_MPDU_SEQ_NUM GENMASK(31, 20)
#define RX_MPDU_START_INFO12_KEY_ID GENMASK(7, 0)
#define RX_MPDU_START_INFO12_NEW_PEER_ENTRY BIT(8)
#define RX_MPDU_START_INFO12_DECRYPT_NEEDED BIT(9)
#define RX_MPDU_START_INFO12_DECAP_TYPE GENMASK(11, 10)
#define RX_MPDU_START_INFO12_VLAN_TAG_C_PADDING BIT(12)
#define RX_MPDU_START_INFO12_VLAN_TAG_S_PADDING BIT(13)
#define RX_MPDU_START_INFO12_STRIP_VLAN_TAG_C BIT(14)
#define RX_MPDU_START_INFO12_STRIP_VLAN_TAG_S BIT(15)
#define RX_MPDU_START_INFO12_PRE_DELIM_COUNT GENMASK(27, 16)
#define RX_MPDU_START_INFO12_AMPDU_FLAG BIT(28)
#define RX_MPDU_START_INFO12_BAR_FRAME BIT(29)
#define RX_MPDU_START_INFO12_RAW_MPDU BIT(30)
#define RX_MPDU_START_INFO13_MPDU_LEN GENMASK(13, 0)
#define RX_MPDU_START_INFO13_FIRST_MPDU BIT(14)
#define RX_MPDU_START_INFO13_MCAST_BCAST BIT(15)
#define RX_MPDU_START_INFO13_AST_IDX_NOT_FOUND BIT(16)
#define RX_MPDU_START_INFO13_AST_IDX_TIMEOUT BIT(17)
#define RX_MPDU_START_INFO13_POWER_MGMT BIT(18)
#define RX_MPDU_START_INFO13_NON_QOS BIT(19)
#define RX_MPDU_START_INFO13_NULL_DATA BIT(20)
#define RX_MPDU_START_INFO13_MGMT_TYPE BIT(21)
#define RX_MPDU_START_INFO13_CTRL_TYPE BIT(22)
#define RX_MPDU_START_INFO13_MORE_DATA BIT(23)
#define RX_MPDU_START_INFO13_EOSP BIT(24)
#define RX_MPDU_START_INFO13_FRAGMENT BIT(25)
#define RX_MPDU_START_INFO13_ORDER BIT(26)
#define RX_MPDU_START_INFO13_UAPSD_TRIGGER BIT(27)
#define RX_MPDU_START_INFO13_ENCRYPT_REQUIRED BIT(28)
#define RX_MPDU_START_INFO13_DIRECTED BIT(29)
#define RX_MPDU_START_INFO13_AMSDU_PRESENT BIT(30)
struct rx_mpdu_start_qcn9074 {
__le32 info7;
__le32 reo_queue_desc_lo;
__le32 info8;
__le32 pn[4];
__le32 info9;
__le32 peer_meta_data;
__le16 info10;
__le16 phy_ppdu_id;
__le16 ast_index;
__le16 sw_peer_id;
__le32 info11;
__le32 info12;
__le32 info13;
__le16 frame_ctrl;
__le16 duration;
u8 addr1[ETH_ALEN];
u8 addr2[ETH_ALEN];
u8 addr3[ETH_ALEN];
__le16 seq_ctrl;
u8 addr4[ETH_ALEN];
__le16 qos_ctrl;
__le32 ht_ctrl;
} __packed;
/* rx_mpdu_start
*
* rxpcu_mpdu_filter_in_category
@ -672,7 +778,7 @@ enum rx_msdu_start_reception_type {
#define RX_MSDU_START_INFO3_RECEPTION_TYPE GENMASK(23, 21)
#define RX_MSDU_START_INFO3_MIMO_SS_BITMAP GENMASK(31, 24)
struct rx_msdu_start {
struct rx_msdu_start_ipq8074 {
__le16 info0;
__le16 phy_ppdu_id;
__le32 info1;
@ -684,6 +790,20 @@ struct rx_msdu_start {
__le32 phy_meta_data;
} __packed;
struct rx_msdu_start_qcn9074 {
__le16 info0;
__le16 phy_ppdu_id;
__le32 info1;
__le32 info2;
__le32 toeplitz_hash;
__le32 flow_id_toeplitz;
__le32 info3;
__le32 ppdu_start_timestamp;
__le32 phy_meta_data;
__le16 vlan_ctag_c1;
__le16 vlan_stag_c1;
} __packed;
/* rx_msdu_start
*
* rxpcu_mpdu_filter_in_category
@ -894,7 +1014,7 @@ struct rx_msdu_start {
#define RX_MSDU_END_INFO5_REO_DEST_IND GENMASK(5, 1)
#define RX_MSDU_END_INFO5_FLOW_IDX GENMASK(25, 6)
struct rx_msdu_end {
struct rx_msdu_end_ipq8074 {
__le16 info0;
__le16 phy_ppdu_id;
__le16 ip_hdr_cksum;
@ -917,6 +1037,58 @@ struct rx_msdu_end {
__le16 sa_sw_peer_id;
} __packed;
#define RX_MSDU_END_MPDU_LENGTH_INFO GENMASK(13, 0)
#define RX_MSDU_END_INFO2_DA_OFFSET GENMASK(5, 0)
#define RX_MSDU_END_INFO2_SA_OFFSET GENMASK(11, 6)
#define RX_MSDU_END_INFO2_DA_OFFSET_VALID BIT(12)
#define RX_MSDU_END_INFO2_SA_OFFSET_VALID BIT(13)
#define RX_MSDU_END_INFO2_L3_TYPE GENMASK(31, 16)
#define RX_MSDU_END_INFO4_SA_IDX_TIMEOUT BIT(0)
#define RX_MSDU_END_INFO4_DA_IDX_TIMEOUT BIT(1)
#define RX_MSDU_END_INFO4_MSDU_LIMIT_ERR BIT(2)
#define RX_MSDU_END_INFO4_FLOW_IDX_TIMEOUT BIT(3)
#define RX_MSDU_END_INFO4_FLOW_IDX_INVALID BIT(4)
#define RX_MSDU_END_INFO4_WIFI_PARSER_ERR BIT(5)
#define RX_MSDU_END_INFO4_AMSDU_PARSER_ERR BIT(6)
#define RX_MSDU_END_INFO4_SA_IS_VALID BIT(7)
#define RX_MSDU_END_INFO4_DA_IS_VALID BIT(8)
#define RX_MSDU_END_INFO4_DA_IS_MCBC BIT(9)
#define RX_MSDU_END_INFO4_L3_HDR_PADDING GENMASK(11, 10)
#define RX_MSDU_END_INFO4_FIRST_MSDU BIT(12)
#define RX_MSDU_END_INFO4_LAST_MSDU BIT(13)
#define RX_MSDU_END_INFO6_AGGR_COUNT GENMASK(7, 0)
#define RX_MSDU_END_INFO6_FLOW_AGGR_CONTN BIT(8)
#define RX_MSDU_END_INFO6_FISA_TIMEOUT BIT(9)
struct rx_msdu_end_qcn9074 {
__le16 info0;
__le16 phy_ppdu_id;
__le16 ip_hdr_cksum;
__le16 mpdu_length_info;
__le32 info1;
__le32 rule_indication[2];
__le32 info2;
__le32 ipv6_options_crc;
__le32 tcp_seq_num;
__le32 tcp_ack_num;
__le16 info3;
__le16 window_size;
__le16 tcp_udp_cksum;
__le16 info4;
__le16 sa_idx;
__le16 da_idx;
__le32 info5;
__le32 fse_metadata;
__le16 cce_metadata;
__le16 sa_sw_peer_id;
__le32 info6;
__le16 cum_l4_cksum;
__le16 cum_ip_length;
} __packed;
/* rx_msdu_end
*
* rxpcu_mpdu_filter_in_category
@ -1190,16 +1362,16 @@ struct rx_mpdu_end {
#define HAL_RX_DESC_HDR_STATUS_LEN 120
struct hal_rx_desc {
struct hal_rx_desc_ipq8074 {
__le32 msdu_end_tag;
struct rx_msdu_end msdu_end;
struct rx_msdu_end_ipq8074 msdu_end;
__le32 rx_attn_tag;
struct rx_attention attention;
__le32 msdu_start_tag;
struct rx_msdu_start msdu_start;
struct rx_msdu_start_ipq8074 msdu_start;
u8 rx_padding0[HAL_RX_DESC_PADDING0_BYTES];
__le32 mpdu_start_tag;
struct rx_mpdu_start mpdu_start;
struct rx_mpdu_start_ipq8074 mpdu_start;
__le32 mpdu_end_tag;
struct rx_mpdu_end mpdu_end;
u8 rx_padding1[HAL_RX_DESC_PADDING1_BYTES];
@ -1209,6 +1381,32 @@ struct hal_rx_desc {
u8 msdu_payload[0];
} __packed;
struct hal_rx_desc_qcn9074 {
__le32 msdu_end_tag;
struct rx_msdu_end_qcn9074 msdu_end;
__le32 rx_attn_tag;
struct rx_attention attention;
__le32 msdu_start_tag;
struct rx_msdu_start_qcn9074 msdu_start;
u8 rx_padding0[HAL_RX_DESC_PADDING0_BYTES];
__le32 mpdu_start_tag;
struct rx_mpdu_start_qcn9074 mpdu_start;
__le32 mpdu_end_tag;
struct rx_mpdu_end mpdu_end;
u8 rx_padding1[HAL_RX_DESC_PADDING1_BYTES];
__le32 hdr_status_tag;
__le32 phy_ppdu_id;
u8 hdr_status[HAL_RX_DESC_HDR_STATUS_LEN];
u8 msdu_payload[0];
} __packed;
struct hal_rx_desc {
union {
struct hal_rx_desc_ipq8074 ipq8074;
struct hal_rx_desc_qcn9074 qcn9074;
} u;
} __packed;
#define HAL_RX_RU_ALLOC_TYPE_MAX 6
#define RU_26 1
#define RU_52 2

View File

@ -5417,31 +5417,6 @@ int ath11k_wmi_pull_fw_stats(struct ath11k_base *ab, struct sk_buff *skb,
return 0;
}
static int
ath11k_pull_pdev_temp_ev(struct ath11k_base *ab, u8 *evt_buf,
u32 len, const struct wmi_pdev_temperature_event *ev)
{
const void **tb;
int ret;
tb = ath11k_wmi_tlv_parse_alloc(ab, evt_buf, len, GFP_ATOMIC);
if (IS_ERR(tb)) {
ret = PTR_ERR(tb);
ath11k_warn(ab, "failed to parse tlv: %d\n", ret);
return ret;
}
ev = tb[WMI_TAG_PDEV_TEMPERATURE_EVENT];
if (!ev) {
ath11k_warn(ab, "failed to fetch pdev temp ev");
kfree(tb);
return -EPROTO;
}
kfree(tb);
return 0;
}
size_t ath11k_wmi_fw_stats_num_vdevs(struct list_head *head)
{
struct ath11k_fw_stats_vdev *i;
@ -6196,10 +6171,8 @@ static void ath11k_mgmt_rx_event(struct ath11k_base *ab, struct sk_buff *skb)
}
}
/* TODO: Pending handle beacon implementation
*if (ieee80211_is_beacon(hdr->frame_control))
* ath11k_mac_handle_beacon(ar, skb);
*/
if (ieee80211_is_beacon(hdr->frame_control))
ath11k_mac_handle_beacon(ar, skb);
ath11k_dbg(ab, ATH11K_DBG_MGMT,
"event mgmt rx skb %pK len %d ftype %02x stype %02x\n",
@ -6418,10 +6391,7 @@ static void ath11k_roam_event(struct ath11k_base *ab, struct sk_buff *skb)
switch (roam_ev.reason) {
case WMI_ROAM_REASON_BEACON_MISS:
/* TODO: Pending beacon miss and connection_loss_work
* implementation
* ath11k_mac_handle_beacon_miss(ar, vdev_id);
*/
ath11k_mac_handle_beacon_miss(ar, roam_ev.vdev_id);
break;
case WMI_ROAM_REASON_BETTER_AP:
case WMI_ROAM_REASON_LOW_RSSI:
@ -6849,23 +6819,37 @@ ath11k_wmi_pdev_temperature_event(struct ath11k_base *ab,
struct sk_buff *skb)
{
struct ath11k *ar;
struct wmi_pdev_temperature_event ev = {0};
const void **tb;
const struct wmi_pdev_temperature_event *ev;
int ret;
if (ath11k_pull_pdev_temp_ev(ab, skb->data, skb->len, &ev) != 0) {
ath11k_warn(ab, "failed to extract pdev temperature event");
tb = ath11k_wmi_tlv_parse_alloc(ab, skb->data, skb->len, GFP_ATOMIC);
if (IS_ERR(tb)) {
ret = PTR_ERR(tb);
ath11k_warn(ab, "failed to parse tlv: %d\n", ret);
return;
}
ev = tb[WMI_TAG_PDEV_TEMPERATURE_EVENT];
if (!ev) {
ath11k_warn(ab, "failed to fetch pdev temp ev");
kfree(tb);
return;
}
ath11k_dbg(ab, ATH11K_DBG_WMI,
"pdev temperature ev temp %d pdev_id %d\n", ev.temp, ev.pdev_id);
"pdev temperature ev temp %d pdev_id %d\n", ev->temp, ev->pdev_id);
ar = ath11k_mac_get_ar_by_pdev_id(ab, ev.pdev_id);
ar = ath11k_mac_get_ar_by_pdev_id(ab, ev->pdev_id);
if (!ar) {
ath11k_warn(ab, "invalid pdev id in pdev temperature ev %d", ev.pdev_id);
ath11k_warn(ab, "invalid pdev id in pdev temperature ev %d", ev->pdev_id);
kfree(tb);
return;
}
ath11k_thermal_event_temperature(ar, ev.temp);
ath11k_thermal_event_temperature(ar, ev->temp);
kfree(tb);
}
static void ath11k_fils_discovery_event(struct ath11k_base *ab,

View File

@ -751,9 +751,7 @@ il3945_hdl_alive(struct il_priv *il, struct il_rx_buf *rxb)
static void
il3945_hdl_add_sta(struct il_priv *il, struct il_rx_buf *rxb)
{
#ifdef CONFIG_IWLEGACY_DEBUG
struct il_rx_pkt *pkt = rxb_addr(rxb);
#endif
D_RX("Received C_ADD_STA: 0x%02X\n", pkt->u.status);
}

View File

@ -1430,10 +1430,8 @@ static void
il_hdl_scan_complete(struct il_priv *il, struct il_rx_buf *rxb)
{
#ifdef CONFIG_IWLEGACY_DEBUG
struct il_rx_pkt *pkt = rxb_addr(rxb);
struct il_scancomplete_notification *scan_notif = (void *)pkt->u.raw;
#endif
D_SCAN("Scan complete: %d channels (TSF 0x%08X:%08X) - %d\n",
scan_notif->scanned_channels, scan_notif->tsf_low,

View File

@ -2937,7 +2937,7 @@ do { \
} while (0)
#else
#define IL_DBG(level, fmt, args...)
#define IL_DBG(level, fmt, args...) no_printk(fmt, ##args)
static inline void
il_print_hex_dump(struct il_priv *il, int level, const void *p, u32 len)
{

View File

@ -99,7 +99,7 @@ mt7601u_has_tssi(struct mt7601u_dev *dev, u8 *eeprom)
{
u16 nic_conf1 = get_unaligned_le16(eeprom + MT_EE_NIC_CONF_1);
return ~nic_conf1 && (nic_conf1 & MT_EE_NIC_CONF_1_TX_ALC_EN);
return (u16)~nic_conf1 && (nic_conf1 & MT_EE_NIC_CONF_1_TX_ALC_EN);
}
static void

View File

@ -610,6 +610,7 @@ int mt7601u_register_device(struct mt7601u_dev *dev)
wiphy->features |= NL80211_FEATURE_ACTIVE_MONITOR;
wiphy->interface_modes = BIT(NL80211_IFTYPE_STATION);
wiphy->flags |= WIPHY_FLAG_SUPPORTS_TDLS;
wiphy_ext_feature_set(wiphy, NL80211_EXT_FEATURE_CQM_RSSI_LIST);

View File

@ -24,12 +24,10 @@
static irqreturn_t isr_uh_routine(int irq, void *user_data)
{
struct net_device *dev = user_data;
struct wilc_vif *vif = netdev_priv(dev);
struct wilc *wilc = vif->wilc;
struct wilc *wilc = user_data;
if (wilc->close) {
netdev_err(dev, "Can't handle UH interrupt\n");
pr_err("Can't handle UH interrupt");
return IRQ_HANDLED;
}
return IRQ_WAKE_THREAD;
@ -37,12 +35,10 @@ static irqreturn_t isr_uh_routine(int irq, void *user_data)
static irqreturn_t isr_bh_routine(int irq, void *userdata)
{
struct net_device *dev = userdata;
struct wilc_vif *vif = netdev_priv(userdata);
struct wilc *wilc = vif->wilc;
struct wilc *wilc = userdata;
if (wilc->close) {
netdev_err(dev, "Can't handle BH interrupt\n");
pr_err("Can't handle BH interrupt\n");
return IRQ_HANDLED;
}
@ -60,7 +56,7 @@ static int init_irq(struct net_device *dev)
ret = request_threaded_irq(wl->dev_irq_num, isr_uh_routine,
isr_bh_routine,
IRQF_TRIGGER_FALLING | IRQF_ONESHOT,
"WILC_IRQ", dev);
"WILC_IRQ", wl);
if (ret) {
netdev_err(dev, "Failed to request IRQ [%d]\n", ret);
return ret;

View File

@ -947,7 +947,7 @@ static int wilc_sdio_sync_ext(struct wilc *wilc, int nint)
for (i = 0; (i < 3) && (nint > 0); i++, nint--)
reg |= BIT(i);
ret = wilc_sdio_read_reg(wilc, WILC_INTR2_ENABLE, &reg);
ret = wilc_sdio_write_reg(wilc, WILC_INTR2_ENABLE, reg);
if (ret) {
dev_err(&func->dev,
"Failed write reg (%08x)...\n",

View File

@ -552,12 +552,60 @@ static struct rxq_entry_t *wilc_wlan_rxq_remove(struct wilc *wilc)
void chip_allow_sleep(struct wilc *wilc)
{
u32 reg = 0;
const struct wilc_hif_func *hif_func = wilc->hif_func;
u32 wakeup_reg, wakeup_bit;
u32 to_host_from_fw_reg, to_host_from_fw_bit;
u32 from_host_to_fw_reg, from_host_to_fw_bit;
u32 trials = 100;
int ret;
wilc->hif_func->hif_read_reg(wilc, WILC_SDIO_WAKEUP_REG, &reg);
if (wilc->io_type == WILC_HIF_SDIO) {
wakeup_reg = WILC_SDIO_WAKEUP_REG;
wakeup_bit = WILC_SDIO_WAKEUP_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;
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;
}
wilc->hif_func->hif_write_reg(wilc, WILC_SDIO_WAKEUP_REG,
reg & ~WILC_SDIO_WAKEUP_BIT);
wilc->hif_func->hif_write_reg(wilc, WILC_SDIO_HOST_TO_FW_REG, 0);
while (trials--) {
ret = hif_func->hif_read_reg(wilc, to_host_from_fw_reg, &reg);
if (ret)
return;
if ((reg & to_host_from_fw_bit) == 0)
break;
}
if (!trials)
pr_warn("FW not responding\n");
/* Clear bit 1 */
ret = hif_func->hif_read_reg(wilc, wakeup_reg, &reg);
if (ret)
return;
if (reg & wakeup_bit) {
reg &= ~wakeup_bit;
ret = hif_func->hif_write_reg(wilc, wakeup_reg, reg);
if (ret)
return;
}
ret = hif_func->hif_read_reg(wilc, from_host_to_fw_reg, &reg);
if (ret)
return;
if (reg & from_host_to_fw_bit) {
reg &= ~from_host_to_fw_bit;
ret = hif_func->hif_write_reg(wilc, from_host_to_fw_reg, reg);
if (ret)
return;
}
}
EXPORT_SYMBOL_GPL(chip_allow_sleep);

View File

@ -97,6 +97,12 @@
#define WILC_SPI_WAKEUP_REG 0x1
#define WILC_SPI_WAKEUP_BIT BIT(1)
#define WILC_SPI_HOST_TO_FW_REG 0x0b
#define WILC_SPI_HOST_TO_FW_BIT BIT(0)
#define WILC_SPI_FW_TO_HOST_REG 0x10
#define WILC_SPI_FW_TO_HOST_BIT BIT(0)
#define WILC_SPI_PROTOCOL_OFFSET (WILC_SPI_PROTOCOL_CONFIG - \
WILC_SPI_REG_BASE)

View File

@ -787,7 +787,6 @@ static void rtw_coex_update_wl_ch_info(struct rtw_dev *rtwdev, u8 type)
{
struct rtw_chip_info *chip = rtwdev->chip;
struct rtw_coex_dm *coex_dm = &rtwdev->coex.dm;
struct rtw_efuse *efuse = &rtwdev->efuse;
u8 link = 0;
u8 center_chan = 0;
u8 bw;
@ -798,7 +797,7 @@ static void rtw_coex_update_wl_ch_info(struct rtw_dev *rtwdev, u8 type)
if (type != COEX_MEDIA_DISCONNECT)
center_chan = rtwdev->hal.current_channel;
if (center_chan == 0 || (efuse->share_ant && center_chan <= 14)) {
if (center_chan == 0) {
link = 0;
center_chan = 0;
bw = 0;
@ -2325,8 +2324,11 @@ static void rtw_coex_action_wl_linkscan(struct rtw_dev *rtwdev)
if (efuse->share_ant) { /* Shared-Ant */
if (coex_stat->bt_a2dp_exist) {
slot_type = TDMA_4SLOT;
table_case = 9;
tdma_case = 11;
if (coex_stat->wl_gl_busy)
table_case = 26;
else
table_case = 9;
} else {
table_case = 9;
tdma_case = 7;
@ -2646,6 +2648,11 @@ void rtw_coex_power_on_setting(struct rtw_dev *rtwdev)
rtw_coex_set_gnt_debug(rtwdev);
}
void rtw_coex_power_off_setting(struct rtw_dev *rtwdev)
{
rtw_write16(rtwdev, REG_WIFI_BT_INFO, BIT_BT_INT_EN);
}
void rtw_coex_init_hw_config(struct rtw_dev *rtwdev, bool wifi_only)
{
__rtw_coex_init_hw_config(rtwdev, wifi_only);

View File

@ -393,6 +393,7 @@ void rtw_coex_bt_multi_link_remain_work(struct work_struct *work);
void rtw_coex_wl_ccklock_work(struct work_struct *work);
void rtw_coex_power_on_setting(struct rtw_dev *rtwdev);
void rtw_coex_power_off_setting(struct rtw_dev *rtwdev);
void rtw_coex_init_hw_config(struct rtw_dev *rtwdev, bool wifi_only);
void rtw_coex_ips_notify(struct rtw_dev *rtwdev, u8 type);
void rtw_coex_lps_notify(struct rtw_dev *rtwdev, u8 type);

View File

@ -10,6 +10,7 @@
#include "fw.h"
#include "debug.h"
#include "phy.h"
#include "reg.h"
#ifdef CONFIG_RTW88_DEBUGFS
@ -270,7 +271,7 @@ static ssize_t rtw_debugfs_set_rsvd_page(struct file *filp,
if (num != 2) {
rtw_warn(rtwdev, "invalid arguments\n");
return num;
return -EINVAL;
}
debugfs_priv->rsvd_page.page_offset = offset;
@ -818,6 +819,40 @@ static int rtw_debugfs_get_coex_enable(struct seq_file *m, void *v)
return 0;
}
static ssize_t rtw_debugfs_set_fw_crash(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;
char tmp[32 + 1];
bool input;
int ret;
rtw_debugfs_copy_from_user(tmp, sizeof(tmp), buffer, count, 1);
ret = kstrtobool(tmp, &input);
if (ret)
return -EINVAL;
if (!input)
return -EINVAL;
rtw_write8(rtwdev, REG_HRCV_MSG, 1);
return count;
}
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));
return 0;
}
#define rtw_debug_impl_mac(page, addr) \
static struct rtw_debugfs_priv rtw_debug_priv_mac_ ##page = { \
.cb_read = rtw_debug_get_mac_page, \
@ -921,6 +956,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_fw_crash = {
.cb_write = rtw_debugfs_set_fw_crash,
.cb_read = rtw_debugfs_get_fw_crash,
};
#define rtw_debugfs_add_core(name, mode, fopname, parent) \
do { \
rtw_debug_priv_ ##name.rtwdev = rtwdev; \
@ -994,6 +1034,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(fw_crash);
}
#endif /* CONFIG_RTW88_DEBUGFS */

View File

@ -11,6 +11,7 @@ struct rtw_hci_ops {
struct rtw_tx_pkt_info *pkt_info,
struct sk_buff *skb);
void (*tx_kick_off)(struct rtw_dev *rtwdev);
void (*flush_queues)(struct rtw_dev *rtwdev, u32 queues, bool drop);
int (*setup)(struct rtw_dev *rtwdev);
int (*start)(struct rtw_dev *rtwdev);
void (*stop)(struct rtw_dev *rtwdev);
@ -258,4 +259,19 @@ static inline enum rtw_hci_type rtw_hci_type(struct rtw_dev *rtwdev)
return rtwdev->hci.type;
}
static inline void rtw_hci_flush_queues(struct rtw_dev *rtwdev, u32 queues,
bool drop)
{
if (rtwdev->hci.ops->flush_queues)
rtwdev->hci.ops->flush_queues(rtwdev, queues, drop);
}
static inline void rtw_hci_flush_all_queues(struct rtw_dev *rtwdev, bool drop)
{
if (rtwdev->hci.ops->flush_queues)
rtwdev->hci.ops->flush_queues(rtwdev,
BIT(rtwdev->hw->queues) - 1,
drop);
}
#endif

View File

@ -530,6 +530,25 @@ static int iddma_download_firmware(struct rtw_dev *rtwdev, u32 src, u32 dst,
return 0;
}
int rtw_ddma_to_fw_fifo(struct rtw_dev *rtwdev, u32 ocp_src, u32 size)
{
u32 ch0_ctrl = BIT_DDMACH0_OWN | BIT_DDMACH0_DDMA_MODE;
if (!check_hw_ready(rtwdev, REG_DDMA_CH0CTRL, BIT_DDMACH0_OWN, 0)) {
rtw_dbg(rtwdev, RTW_DBG_FW, "busy to start ddma\n");
return -EBUSY;
}
ch0_ctrl |= size & BIT_MASK_DDMACH0_DLEN;
if (iddma_enable(rtwdev, ocp_src, OCPBASE_RXBUF_FW_88XX, ch0_ctrl)) {
rtw_dbg(rtwdev, RTW_DBG_FW, "busy to complete ddma\n");
return -EBUSY;
}
return 0;
}
static bool
check_fw_checksum(struct rtw_dev *rtwdev, u32 addr)
{

View File

@ -15,7 +15,10 @@
#define ILLEGAL_KEY_GROUP 0xFAAAAA00
/* HW memory address */
#define OCPBASE_RXBUF_FW_88XX 0x18680000
#define OCPBASE_TXBUF_88XX 0x18780000
#define OCPBASE_ROM_88XX 0x00000000
#define OCPBASE_IMEM_88XX 0x00030000
#define OCPBASE_DMEM_88XX 0x00200000
#define OCPBASE_EMEM_88XX 0x00100000
@ -33,6 +36,7 @@ void rtw_mac_power_off(struct rtw_dev *rtwdev);
int rtw_download_firmware(struct rtw_dev *rtwdev, struct rtw_fw_state *fw);
int rtw_mac_init(struct rtw_dev *rtwdev);
void rtw_mac_flush_queues(struct rtw_dev *rtwdev, u32 queues, bool drop);
int rtw_ddma_to_fw_fifo(struct rtw_dev *rtwdev, u32 ocp_src, u32 size);
static inline void rtw_mac_flush_all_queues(struct rtw_dev *rtwdev, bool drop)
{

View File

@ -520,6 +520,7 @@ static int rtw_ops_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd,
hw_key_type, hw_key_idx);
break;
case DISABLE_KEY:
rtw_hci_flush_all_queues(rtwdev, false);
rtw_mac_flush_all_queues(rtwdev, false);
rtw_sec_clear_cam(rtwdev, sec, key->hw_key_idx);
break;
@ -670,6 +671,7 @@ static void rtw_ops_flush(struct ieee80211_hw *hw,
mutex_lock(&rtwdev->mutex);
rtw_leave_lps_deep(rtwdev);
rtw_hci_flush_queues(rtwdev, queues, drop);
rtw_mac_flush_queues(rtwdev, queues, drop);
mutex_unlock(&rtwdev->mutex);
}

View File

@ -345,15 +345,9 @@ static bool rtw_fw_dump_crash_log(struct rtw_dev *rtwdev)
"fw crash dump's seq is wrong: %d\n", seq);
goto free_buf;
}
if (seq == 0 &&
(GET_FW_DUMP_TLV_TYPE(buf) != FW_CD_TYPE ||
GET_FW_DUMP_TLV_LEN(buf) != FW_CD_LEN ||
GET_FW_DUMP_TLV_VAL(buf) != FW_CD_VAL)) {
rtw_dbg(rtwdev, RTW_DBG_FW, "fw crash dump's tlv is wrong\n");
goto free_buf;
}
print_hex_dump_bytes("rtw88 fw dump: ", DUMP_PREFIX_OFFSET, buf, size);
print_hex_dump(KERN_ERR, "rtw88 fw dump: ", DUMP_PREFIX_OFFSET, 16, 1,
buf, size, true);
if (GET_FW_DUMP_MORE(buf) == 1) {
rtwdev->fw.prev_dump_seq = seq;
@ -368,6 +362,78 @@ exit:
return ret;
}
int rtw_dump_fw(struct rtw_dev *rtwdev, const u32 ocp_src, u32 size,
const char *prefix_str)
{
u32 rxff = rtwdev->chip->fw_rxff_size;
u32 dump_size, done_size = 0;
u8 *buf;
int ret;
buf = vzalloc(size);
if (!buf)
return -ENOMEM;
while (size) {
dump_size = size > rxff ? rxff : size;
ret = rtw_ddma_to_fw_fifo(rtwdev, ocp_src + done_size,
dump_size);
if (ret) {
rtw_err(rtwdev,
"ddma fw 0x%x [+0x%x] to fw fifo fail\n",
ocp_src, done_size);
goto exit;
}
ret = rtw_fw_dump_fifo(rtwdev, RTW_FW_FIFO_SEL_RXBUF_FW, 0,
dump_size, (u32 *)(buf + done_size));
if (ret) {
rtw_err(rtwdev,
"dump fw 0x%x [+0x%x] from fw fifo fail\n",
ocp_src, done_size);
goto exit;
}
size -= dump_size;
done_size += dump_size;
}
print_hex_dump(KERN_ERR, prefix_str, DUMP_PREFIX_OFFSET, 16, 1,
buf, done_size, true);
exit:
vfree(buf);
return ret;
}
EXPORT_SYMBOL(rtw_dump_fw);
int rtw_dump_reg(struct rtw_dev *rtwdev, const u32 addr, const u32 size,
const char *prefix_str)
{
u8 *buf;
u32 i;
if (addr & 0x3) {
WARN(1, "should be 4-byte aligned, addr = 0x%08x\n", addr);
return -EINVAL;
}
buf = vzalloc(size);
if (!buf)
return -ENOMEM;
for (i = 0; i < size; i += 4)
*(u32 *)(buf + i) = rtw_read32(rtwdev, addr + i);
print_hex_dump(KERN_ERR, prefix_str, DUMP_PREFIX_OFFSET, 16, 4, buf,
size, true);
vfree(buf);
return 0;
}
EXPORT_SYMBOL(rtw_dump_reg);
void rtw_vif_assoc_changed(struct rtw_vif *rtwvif,
struct ieee80211_bss_conf *conf)
{
@ -419,10 +485,8 @@ void rtw_fw_recovery(struct rtw_dev *rtwdev)
ieee80211_queue_work(rtwdev->hw, &rtwdev->fw_recovery_work);
}
static void rtw_fw_recovery_work(struct work_struct *work)
static void __fw_recovery_work(struct rtw_dev *rtwdev)
{
struct rtw_dev *rtwdev = container_of(work, struct rtw_dev,
fw_recovery_work);
/* rtw_fw_dump_crash_log() returns false indicates that there are
* still more log to dump. Driver set 0x1cf[7:0] = 0x1 to tell firmware
@ -435,18 +499,26 @@ static void rtw_fw_recovery_work(struct work_struct *work)
}
rtwdev->fw.prev_dump_seq = 0;
set_bit(RTW_FLAG_RESTARTING, rtwdev->flags);
rtw_chip_dump_fw_crash(rtwdev);
WARN(1, "firmware crash, start reset and recover\n");
mutex_lock(&rtwdev->mutex);
set_bit(RTW_FLAG_RESTARTING, rtwdev->flags);
rcu_read_lock();
rtw_iterate_keys_rcu(rtwdev, NULL, rtw_reset_key_iter, rtwdev);
rcu_read_unlock();
rtw_iterate_stas_atomic(rtwdev, rtw_reset_sta_iter, rtwdev);
rtw_iterate_vifs_atomic(rtwdev, rtw_reset_vif_iter, rtwdev);
rtw_enter_ips(rtwdev);
}
static void rtw_fw_recovery_work(struct work_struct *work)
{
struct rtw_dev *rtwdev = container_of(work, struct rtw_dev,
fw_recovery_work);
mutex_lock(&rtwdev->mutex);
__fw_recovery_work(rtwdev);
mutex_unlock(&rtwdev->mutex);
ieee80211_restart_hw(rtwdev->hw);
@ -1138,6 +1210,7 @@ int rtw_core_start(struct rtw_dev *rtwdev)
static void rtw_power_off(struct rtw_dev *rtwdev)
{
rtw_hci_stop(rtwdev);
rtw_coex_power_off_setting(rtwdev);
rtw_mac_power_off(rtwdev);
}
@ -1393,7 +1466,6 @@ static int rtw_chip_parameter_setup(struct rtw_dev *rtwdev)
struct rtw_chip_info *chip = rtwdev->chip;
struct rtw_hal *hal = &rtwdev->hal;
struct rtw_efuse *efuse = &rtwdev->efuse;
int ret = 0;
switch (rtw_hci_type(rtwdev)) {
case RTW_HCI_TYPE_PCIE:
@ -1431,7 +1503,7 @@ static int rtw_chip_parameter_setup(struct rtw_dev *rtwdev)
hal->bfee_sts_cap = 3;
return ret;
return 0;
}
static int rtw_chip_efuse_enable(struct rtw_dev *rtwdev)

View File

@ -805,6 +805,7 @@ struct rtw_regulatory {
struct rtw_chip_ops {
int (*mac_init)(struct rtw_dev *rtwdev);
void (*dump_fw_crash)(struct rtw_dev *rtwdev);
void (*shutdown)(struct rtw_dev *rtwdev);
int (*read_efuse)(struct rtw_dev *rtwdev, u8 *map);
void (*phy_set_param)(struct rtw_dev *rtwdev);
@ -1166,6 +1167,7 @@ struct rtw_chip_info {
bool en_dis_dpd;
u16 dpd_ratemask;
u8 iqk_threshold;
u8 lck_threshold;
const struct rtw_pwr_track_tbl *pwr_track_tbl;
u8 bfer_su_max_num;
@ -1534,6 +1536,7 @@ struct rtw_dm_info {
u32 rrsr_mask_min;
u8 thermal_avg[RTW_RF_PATH_MAX];
u8 thermal_meter_k;
u8 thermal_meter_lck;
s8 delta_power_index[RTW_RF_PATH_MAX];
s8 delta_power_index_last[RTW_RF_PATH_MAX];
u8 default_ofdm_index;
@ -1876,6 +1879,12 @@ static inline void rtw_release_macid(struct rtw_dev *rtwdev, u8 mac_id)
clear_bit(mac_id, rtwdev->mac_id_map);
}
static inline void rtw_chip_dump_fw_crash(struct rtw_dev *rtwdev)
{
if (rtwdev->chip->ops->dump_fw_crash)
rtwdev->chip->ops->dump_fw_crash(rtwdev);
}
void rtw_get_channel_params(struct cfg80211_chan_def *chandef,
struct rtw_channel_params *ch_param);
bool check_hw_ready(struct rtw_dev *rtwdev, u32 addr, u32 mask, u32 target);
@ -1905,5 +1914,9 @@ int rtw_sta_add(struct rtw_dev *rtwdev, struct ieee80211_sta *sta,
void rtw_sta_remove(struct rtw_dev *rtwdev, struct ieee80211_sta *sta,
bool fw_exist);
void rtw_fw_recovery(struct rtw_dev *rtwdev);
int rtw_dump_fw(struct rtw_dev *rtwdev, const u32 ocp_src, u32 size,
const char *prefix_str);
int rtw_dump_reg(struct rtw_dev *rtwdev, const u32 addr, const u32 size,
const char *prefix_str);
#endif

View File

@ -671,6 +671,8 @@ static u8 ac_to_hwq[] = {
[IEEE80211_AC_BK] = RTW_TX_QUEUE_BK,
};
static_assert(ARRAY_SIZE(ac_to_hwq) == IEEE80211_NUM_ACS);
static u8 rtw_hw_queue_mapping(struct sk_buff *skb)
{
struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data;
@ -727,6 +729,72 @@ static void rtw_pci_dma_check(struct rtw_dev *rtwdev,
rtwpci->rx_tag = (rtwpci->rx_tag + 1) % RX_TAG_MAX;
}
static u32 __pci_get_hw_tx_ring_rp(struct rtw_dev *rtwdev, u8 pci_q)
{
u32 bd_idx_addr = rtw_pci_tx_queue_idx_addr[pci_q];
u32 bd_idx = rtw_read16(rtwdev, bd_idx_addr + 2);
return FIELD_GET(TRX_BD_IDX_MASK, bd_idx);
}
static void __pci_flush_queue(struct rtw_dev *rtwdev, u8 pci_q, bool drop)
{
struct rtw_pci *rtwpci = (struct rtw_pci *)rtwdev->priv;
struct rtw_pci_tx_ring *ring = &rtwpci->tx_rings[pci_q];
u32 cur_rp;
u8 i;
/* Because the time taked by the I/O in __pci_get_hw_tx_ring_rp is a
* bit dynamic, it's hard to define a reasonable fixed total timeout to
* use read_poll_timeout* helper. Instead, we can ensure a reasonable
* polling times, so we just use for loop with udelay here.
*/
for (i = 0; i < 30; i++) {
cur_rp = __pci_get_hw_tx_ring_rp(rtwdev, pci_q);
if (cur_rp == ring->r.wp)
return;
udelay(1);
}
if (!drop)
rtw_warn(rtwdev, "timed out to flush pci tx ring[%d]\n", pci_q);
}
static void __rtw_pci_flush_queues(struct rtw_dev *rtwdev, u32 pci_queues,
bool drop)
{
u8 q;
for (q = 0; q < RTK_MAX_TX_QUEUE_NUM; q++) {
/* It may be not necessary to flush BCN and H2C tx queues. */
if (q == RTW_TX_QUEUE_BCN || q == RTW_TX_QUEUE_H2C)
continue;
if (pci_queues & BIT(q))
__pci_flush_queue(rtwdev, q, drop);
}
}
static void rtw_pci_flush_queues(struct rtw_dev *rtwdev, u32 queues, bool drop)
{
u32 pci_queues = 0;
u8 i;
/* If all of the hardware queues are requested to flush,
* flush all of the pci queues.
*/
if (queues == BIT(rtwdev->hw->queues) - 1) {
pci_queues = BIT(RTK_MAX_TX_QUEUE_NUM) - 1;
} else {
for (i = 0; i < rtwdev->hw->queues; i++)
if (queues & BIT(i))
pci_queues |= BIT(ac_to_hwq[i]);
}
__rtw_pci_flush_queues(rtwdev, pci_queues, drop);
}
static void rtw_pci_tx_kick_off_queue(struct rtw_dev *rtwdev, u8 queue)
{
struct rtw_pci *rtwpci = (struct rtw_pci *)rtwdev->priv;
@ -1490,6 +1558,7 @@ static void rtw_pci_destroy(struct rtw_dev *rtwdev, struct pci_dev *pdev)
static struct rtw_hci_ops rtw_pci_ops = {
.tx_write = rtw_pci_tx_write,
.tx_kick_off = rtw_pci_tx_kick_off,
.flush_queues = rtw_pci_flush_queues,
.setup = rtw_pci_setup,
.start = rtw_pci_start,
.stop = rtw_pci_stop,

View File

@ -316,7 +316,8 @@ rtw_phy_dig_check_damping(struct rtw_dm_info *dm_info)
return damping;
}
static void rtw_phy_dig_get_boundary(struct rtw_dm_info *dm_info,
static void rtw_phy_dig_get_boundary(struct rtw_dev *rtwdev,
struct rtw_dm_info *dm_info,
u8 *upper, u8 *lower, bool linked)
{
u8 dig_max, dig_min, dig_mid;
@ -325,8 +326,7 @@ static void rtw_phy_dig_get_boundary(struct rtw_dm_info *dm_info,
if (linked) {
dig_max = DIG_PERF_MAX;
dig_mid = DIG_PERF_MID;
/* 22B=0x1c, 22C=0x20 */
dig_min = 0x1c;
dig_min = rtwdev->chip->dig_min;
min_rssi = max_t(u8, dm_info->min_rssi, dig_min);
} else {
dig_max = DIG_CVRG_MAX;
@ -437,7 +437,8 @@ static void rtw_phy_dig(struct rtw_dev *rtwdev)
* the peers connected with us, meanwhile make sure the igi value does
* not beyond the hardware limitation
*/
rtw_phy_dig_get_boundary(dm_info, &upper_bound, &lower_bound, linked);
rtw_phy_dig_get_boundary(rtwdev, dm_info, &upper_bound, &lower_bound,
linked);
cur_igi = clamp_t(u8, cur_igi, lower_bound, upper_bound);
/* record current igi value and false alarm statistics for further
@ -2219,6 +2220,20 @@ s8 rtw_phy_pwrtrack_get_pwridx(struct rtw_dev *rtwdev,
}
EXPORT_SYMBOL(rtw_phy_pwrtrack_get_pwridx);
bool rtw_phy_pwrtrack_need_lck(struct rtw_dev *rtwdev)
{
struct rtw_dm_info *dm_info = &rtwdev->dm_info;
u8 delta_lck;
delta_lck = abs(dm_info->thermal_avg[0] - dm_info->thermal_meter_lck);
if (delta_lck >= rtwdev->chip->lck_threshold) {
dm_info->thermal_meter_lck = dm_info->thermal_avg[0];
return true;
}
return false;
}
EXPORT_SYMBOL(rtw_phy_pwrtrack_need_lck);
bool rtw_phy_pwrtrack_need_iqk(struct rtw_dev *rtwdev)
{
struct rtw_dm_info *dm_info = &rtwdev->dm_info;

View File

@ -55,6 +55,7 @@ u8 rtw_phy_pwrtrack_get_delta(struct rtw_dev *rtwdev, u8 path);
s8 rtw_phy_pwrtrack_get_pwridx(struct rtw_dev *rtwdev,
struct rtw_swing_table *swing_table,
u8 tbl_path, u8 therm_path, u8 delta);
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);

View File

@ -534,6 +534,7 @@
#define BIT_DDMACH0_OWN BIT(31)
#define BIT_DDMACH0_CHKSUM_EN BIT(29)
#define BIT_DDMACH0_CHKSUM_STS BIT(27)
#define BIT_DDMACH0_DDMA_MODE BIT(26)
#define BIT_DDMACH0_RESET_CHKSUM_STS BIT(25)
#define BIT_DDMACH0_CHKSUM_CONT BIT(24)
#define BIT_MASK_DDMACH0_DLEN 0x3ffff
@ -652,8 +653,13 @@
#define RF_TXATANK 0x64
#define RF_TRXIQ 0x66
#define RF_RXIQGEN 0x8d
#define RF_SYN_PFD 0xb0
#define RF_XTALX2 0xb8
#define RF_SYN_CTRL 0xbb
#define RF_MALSEL 0xbe
#define RF_SYN_AAC 0xc9
#define RF_AAC_CTRL 0xca
#define RF_FAST_LCK 0xcc
#define RF_RCKD 0xde
#define RF_TXADBG 0xde
#define RF_LUTDBG 0xdf

View File

@ -1126,6 +1126,7 @@ static void rtw8822c_pwrtrack_init(struct rtw_dev *rtwdev)
dm_info->pwr_trk_triggered = false;
dm_info->thermal_meter_k = rtwdev->efuse.thermal_meter_k;
dm_info->thermal_meter_lck = rtwdev->efuse.thermal_meter_k;
}
static void rtw8822c_phy_set_param(struct rtw_dev *rtwdev)
@ -1396,6 +1397,15 @@ static int rtw8822c_mac_init(struct rtw_dev *rtwdev)
return 0;
}
static void rtw8822c_dump_fw_crash(struct rtw_dev *rtwdev)
{
rtw_dump_reg(rtwdev, 0x0, 0x2000, "rtw8822c reg_");
rtw_dump_fw(rtwdev, OCPBASE_DMEM_88XX, 0x10000, "rtw8822c DMEM_");
rtw_dump_fw(rtwdev, OCPBASE_IMEM_88XX, 0x10000, "rtw8822c IMEM_");
rtw_dump_fw(rtwdev, OCPBASE_EMEM_88XX, 0x20000, "rtw8822c EMEM_");
rtw_dump_fw(rtwdev, OCPBASE_ROM_88XX, 0x10000, "rtw8822c ROM_");
}
static void rtw8822c_rstb_3wire(struct rtw_dev *rtwdev, bool enable)
{
if (enable) {
@ -2108,6 +2118,26 @@ static void rtw8822c_false_alarm_statistics(struct rtw_dev *rtwdev)
rtw_write32_set(rtwdev, REG_RX_BREAK, BIT_COM_RX_GCK_EN);
}
static void rtw8822c_do_lck(struct rtw_dev *rtwdev)
{
u32 val;
rtw_write_rf(rtwdev, RF_PATH_A, RF_SYN_CTRL, RFREG_MASK, 0x80010);
rtw_write_rf(rtwdev, RF_PATH_A, RF_SYN_PFD, RFREG_MASK, 0x1F0FA);
fsleep(1);
rtw_write_rf(rtwdev, RF_PATH_A, RF_AAC_CTRL, RFREG_MASK, 0x80000);
rtw_write_rf(rtwdev, RF_PATH_A, RF_SYN_AAC, RFREG_MASK, 0x80001);
read_poll_timeout(rtw_read_rf, val, val != 0x1, 1000, 100000,
true, rtwdev, RF_PATH_A, RF_AAC_CTRL, 0x1000);
rtw_write_rf(rtwdev, RF_PATH_A, RF_SYN_PFD, RFREG_MASK, 0x1F0F8);
rtw_write_rf(rtwdev, RF_PATH_B, RF_SYN_CTRL, RFREG_MASK, 0x80010);
rtw_write_rf(rtwdev, RF_PATH_A, RF_FAST_LCK, RFREG_MASK, 0x0f000);
rtw_write_rf(rtwdev, RF_PATH_A, RF_FAST_LCK, RFREG_MASK, 0x4f000);
fsleep(1);
rtw_write_rf(rtwdev, RF_PATH_A, RF_FAST_LCK, RFREG_MASK, 0x0f000);
}
static void rtw8822c_do_iqk(struct rtw_dev *rtwdev)
{
struct rtw_iqk_para para = {0};
@ -3538,11 +3568,12 @@ static void __rtw8822c_pwr_track(struct rtw_dev *rtwdev)
rtw_phy_config_swing_table(rtwdev, &swing_table);
if (rtw_phy_pwrtrack_need_lck(rtwdev))
rtw8822c_do_lck(rtwdev);
for (i = 0; i < rtwdev->hal.rf_path_num; i++)
rtw8822c_pwr_track_path(rtwdev, &swing_table, i);
if (rtw_phy_pwrtrack_need_iqk(rtwdev))
rtw8822c_do_iqk(rtwdev);
}
static void rtw8822c_pwr_track(struct rtw_dev *rtwdev)
@ -3971,6 +4002,7 @@ static struct rtw_chip_ops rtw8822c_ops = {
.query_rx_desc = rtw8822c_query_rx_desc,
.set_channel = rtw8822c_set_channel,
.mac_init = rtw8822c_mac_init,
.dump_fw_crash = rtw8822c_dump_fw_crash,
.read_rf = rtw_phy_read_rf,
.write_rf = rtw_phy_write_rf_reg_mix,
.set_tx_power_index = rtw8822c_set_tx_power_index,
@ -4351,6 +4383,7 @@ struct rtw_chip_info rtw8822c_hw_spec = {
.dpd_ratemask = DIS_DPD_RATEALL,
.pwr_track_tbl = &rtw8822c_rtw_pwr_track_tbl,
.iqk_threshold = 8,
.lck_threshold = 8,
.bfer_su_max_num = 2,
.bfer_mu_max_num = 1,
.rx_ldpc = true,
@ -4360,7 +4393,7 @@ struct rtw_chip_info rtw8822c_hw_spec = {
.wowlan_stub = &rtw_wowlan_stub_8822c,
.max_sched_scan_ssids = 4,
#endif
.coex_para_ver = 0x201029,
.coex_para_ver = 0x2103181c,
.bt_desired_ver = 0x1c,
.scbd_support = true,
.new_scbd10_def = true,

File diff suppressed because it is too large Load Diff