Commit 70442ee6 authored by Kalle Valo's avatar Kalle Valo
Browse files
ath.git patches for v5.10. Major changes:

ath11k

* improvements to QCA6390 PCI support, adding essential missing
  features: ELF board files, packet log handling to avoid data stalls
  and crash fixes
parents 855f69fc fd5ad4d1
Loading
Loading
Loading
Loading
+80 −0
Original line number Diff line number Diff line
@@ -187,6 +187,26 @@ const struct ce_attr ath11k_host_ce_config_qca6390[] = {

};

static bool ath11k_ce_need_shadow_fix(int ce_id)
{
	/* only ce4 needs shadow workaroud*/
	if (ce_id == 4)
		return true;
	return false;
}

static void ath11k_ce_stop_shadow_timers(struct ath11k_base *ab)
{
	int i;

	if (!ab->hw_params.supports_shadow_regs)
		return;

	for (i = 0; i < ab->hw_params.ce_count; i++)
		if (ath11k_ce_need_shadow_fix(i))
			ath11k_dp_shadow_stop_timer(ab, &ab->ce.hp_timer[i]);
}

static int ath11k_ce_rx_buf_enqueue_pipe(struct ath11k_ce_pipe *pipe,
					 struct sk_buff *skb, dma_addr_t paddr)
{
@@ -505,6 +525,12 @@ static int ath11k_ce_init_ring(struct ath11k_base *ab,

	ce_ring->hal_ring_id = ret;

	if (ab->hw_params.supports_shadow_regs &&
	    ath11k_ce_need_shadow_fix(ce_id))
		ath11k_dp_shadow_init_timer(ab, &ab->ce.hp_timer[ce_id],
					    ATH11K_SHADOW_CTRL_TIMER_INTERVAL,
					    ce_ring->hal_ring_id);

	return 0;
}

@@ -677,6 +703,9 @@ int ath11k_ce_send(struct ath11k_base *ab, struct sk_buff *skb, u8 pipe_id,

	ath11k_hal_srng_access_end(ab, srng);

	if (ath11k_ce_need_shadow_fix(pipe_id))
		ath11k_dp_shadow_start_timer(ab, srng, &ab->ce.hp_timer[pipe_id]);

	spin_unlock_bh(&srng->lock);

	spin_unlock_bh(&ab->ce.ce_lock);
@@ -713,11 +742,56 @@ static void ath11k_ce_rx_pipe_cleanup(struct ath11k_ce_pipe *pipe)
	}
}

static void ath11k_ce_shadow_config(struct ath11k_base *ab)
{
	int i;

	for (i = 0; i < ab->hw_params.ce_count; i++) {
		if (ab->hw_params.host_ce_config[i].src_nentries)
			ath11k_hal_srng_update_shadow_config(ab,
							     HAL_CE_SRC, i);

		if (ab->hw_params.host_ce_config[i].dest_nentries) {
			ath11k_hal_srng_update_shadow_config(ab,
							     HAL_CE_DST, i);

			ath11k_hal_srng_update_shadow_config(ab,
							     HAL_CE_DST_STATUS, i);
		}
	}
}

void ath11k_ce_get_shadow_config(struct ath11k_base *ab,
				 u32 **shadow_cfg, u32 *shadow_cfg_len)
{
	if (!ab->hw_params.supports_shadow_regs)
		return;

	ath11k_hal_srng_get_shadow_config(ab, shadow_cfg, shadow_cfg_len);

	/* shadow is already configured */
	if (*shadow_cfg_len)
		return;

	/* shadow isn't configured yet, configure now.
	 * non-CE srngs are configured firstly, then
	 * all CE srngs.
	 */
	ath11k_hal_srng_shadow_config(ab);
	ath11k_ce_shadow_config(ab);

	/* get the shadow configuration */
	ath11k_hal_srng_get_shadow_config(ab, shadow_cfg, shadow_cfg_len);
}
EXPORT_SYMBOL(ath11k_ce_get_shadow_config);

void ath11k_ce_cleanup_pipes(struct ath11k_base *ab)
{
	struct ath11k_ce_pipe *pipe;
	int pipe_num;

	ath11k_ce_stop_shadow_timers(ab);

	for (pipe_num = 0; pipe_num < ab->hw_params.ce_count; pipe_num++) {
		pipe = &ab->ce.ce_pipe[pipe_num];
		ath11k_ce_rx_pipe_cleanup(pipe);
@@ -767,6 +841,9 @@ int ath11k_ce_init_pipes(struct ath11k_base *ab)
	int i;
	int ret;

	ath11k_ce_get_shadow_config(ab, &ab->qmi.ce_cfg.shadow_reg_v2,
				    &ab->qmi.ce_cfg.shadow_reg_v2_len);

	for (i = 0; i < ab->hw_params.ce_count; i++) {
		pipe = &ab->ce.ce_pipe[i];

@@ -828,6 +905,9 @@ void ath11k_ce_free_pipes(struct ath11k_base *ab)
	for (i = 0; i < ab->hw_params.ce_count; i++) {
		pipe = &ab->ce.ce_pipe[i];

		if (ath11k_ce_need_shadow_fix(i))
			ath11k_dp_shadow_stop_timer(ab, &ab->ce.hp_timer[i]);

		if (pipe->src_ring) {
			desc_sz = ath11k_hal_ce_get_desc_size(HAL_CE_DESC_SRC);
			dma_free_coherent(ab->dev,
+3 −0
Original line number Diff line number Diff line
@@ -168,6 +168,7 @@ struct ath11k_ce {
	struct ath11k_ce_pipe ce_pipe[CE_COUNT_MAX];
	/* Protects rings of all ce pipes */
	spinlock_t ce_lock;
	struct ath11k_hp_update_timer hp_timer[CE_COUNT_MAX];
};

extern const struct ce_attr ath11k_host_ce_config_ipq8074[];
@@ -187,4 +188,6 @@ void ath11k_ce_poll_send_completed(struct ath11k_base *ab, u8 pipe_id);
int ath11k_ce_map_service_to_pipe(struct ath11k_base *ab, u16 service_id,
				  u8 *ul_pipe, u8 *dl_pipe);
int ath11k_ce_attr_attach(struct ath11k_base *ab);
void ath11k_ce_get_shadow_config(struct ath11k_base *ab,
				 u32 **shadow_cfg, u32 *shadow_cfg_len);
#endif
+21 −0
Original line number Diff line number Diff line
@@ -58,6 +58,13 @@ static const struct ath11k_hw_params ath11k_hw_params[] = {
		.htt_peer_map_v2 = true,
		.tcl_0_only = false,
		.spectral_fft_sz = 2,

		.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,
	},
	{
		.hw_rev = ATH11K_HW_IPQ6018_HW10,
@@ -88,6 +95,13 @@ static const struct ath11k_hw_params ath11k_hw_params[] = {
		.htt_peer_map_v2 = true,
		.tcl_0_only = false,
		.spectral_fft_sz = 4,

		.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,
	},
	{
		.name = "qca6390 hw2.0",
@@ -118,6 +132,12 @@ static const struct ath11k_hw_params ath11k_hw_params[] = {
		.htt_peer_map_v2 = false,
		.tcl_0_only = true,
		.spectral_fft_sz = 0,

		.interface_modes = BIT(NL80211_IFTYPE_STATION) |
					BIT(NL80211_IFTYPE_AP),
		.supports_monitor = false,
		.supports_shadow_regs = true,
		.idle_ps = true,
	},
};

@@ -398,6 +418,7 @@ static void ath11k_core_stop(struct ath11k_base *ab)
{
	if (!test_bit(ATH11K_FLAG_CRASH_FLUSH, &ab->dev_flags))
		ath11k_qmi_firmware_stop(ab);

	ath11k_hif_stop(ab);
	ath11k_wmi_detach(ab);
	ath11k_dp_pdev_reo_cleanup(ab);
+3 −0
Original line number Diff line number Diff line
@@ -37,6 +37,8 @@

extern unsigned int ath11k_frame_mode;

#define ATH11K_MON_TIMER_INTERVAL  10

enum ath11k_supported_bw {
	ATH11K_BW_20	= 0,
	ATH11K_BW_40	= 1,
@@ -727,6 +729,7 @@ struct ath11k_base {
	struct ath11k_dbring_cap *db_caps;
	u32 num_db_cap;

	struct timer_list mon_reap_timer;
	/* must be last */
	u8 drv_priv[0] __aligned(sizeof(void *));
};
+9 −24
Original line number Diff line number Diff line
@@ -837,12 +837,8 @@ int ath11k_debugfs_pdev_create(struct ath11k_base *ab)
		return 0;

	ab->debugfs_soc = debugfs_create_dir(ab->hw_params.name, ab->debugfs_ath11k);

	if (IS_ERR_OR_NULL(ab->debugfs_soc)) {
	if (IS_ERR(ab->debugfs_soc))
		return PTR_ERR(ab->debugfs_soc);
		return -ENOMEM;
	}

	debugfs_create_file("simulate_fw_crash", 0600, ab->debugfs_soc, ab,
			    &fops_simulate_fw_crash);
@@ -855,27 +851,21 @@ int ath11k_debugfs_pdev_create(struct ath11k_base *ab)

void ath11k_debugfs_pdev_destroy(struct ath11k_base *ab)
{
	debugfs_remove_recursive(ab->debugfs_ath11k);
	ab->debugfs_ath11k = NULL;
	debugfs_remove_recursive(ab->debugfs_soc);
	ab->debugfs_soc = NULL;
}

int ath11k_debugfs_soc_create(struct ath11k_base *ab)
{
	ab->debugfs_ath11k = debugfs_create_dir("ath11k", NULL);

	if (IS_ERR_OR_NULL(ab->debugfs_ath11k)) {
		if (IS_ERR(ab->debugfs_ath11k))
			return PTR_ERR(ab->debugfs_ath11k);
		return -ENOMEM;
	}

	return 0;
	return PTR_ERR_OR_ZERO(ab->debugfs_ath11k);
}

void ath11k_debugfs_soc_destroy(struct ath11k_base *ab)
{
	debugfs_remove_recursive(ab->debugfs_soc);
	ab->debugfs_soc = NULL;
	debugfs_remove_recursive(ab->debugfs_ath11k);
	ab->debugfs_ath11k = NULL;
}

void ath11k_debugfs_fw_stats_init(struct ath11k *ar)
@@ -1069,14 +1059,9 @@ int ath11k_debugfs_register(struct ath11k *ar)
	snprintf(pdev_name, sizeof(pdev_name), "%s%d", "mac", ar->pdev_idx);

	ar->debug.debugfs_pdev = debugfs_create_dir(pdev_name, ab->debugfs_soc);

	if (IS_ERR_OR_NULL(ar->debug.debugfs_pdev)) {
	if (IS_ERR(ar->debug.debugfs_pdev))
		return PTR_ERR(ar->debug.debugfs_pdev);

		return -ENOMEM;
	}

	/* Create a symlink under ieee80211/phy* */
	snprintf(buf, 100, "../../ath11k/%pd2", ar->debug.debugfs_pdev);
	debugfs_create_symlink("ath11k", ar->hw->wiphy->debugfsdir, buf);
Loading