Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit db56287b authored by Govind Singh's avatar Govind Singh
Browse files

ath10k: Enable single queue NAPI for WCN3990 target



Up-streamed driver uses NAPI in rx data path. Add napi
implementation in snoc layer.

CRs-Fixed: 1112504
Change-Id: I33d3405ee99233af474f8bc236c43898086f044c
Signed-off-by: default avatarGovind Singh <govinds@codeaurora.org>
parent f16ca2c0
Loading
Loading
Loading
Loading
+29 −2
Original line number Diff line number Diff line
@@ -735,7 +735,11 @@ void ath10k_ce_per_engine_service_any(struct ath10k *ar)
{
	int ce_id;
	u32 intr_summary;
	struct ath10k_ce_pipe *ce_state;

	if (ar->target_version == ATH10K_HW_WCN3990)
		intr_summary = 0xFFF;
	else
		intr_summary = CE_INTERRUPT_SUMMARY(ar);

	for (ce_id = 0; intr_summary && (ce_id < CE_COUNT); ce_id++) {
@@ -745,8 +749,11 @@ void ath10k_ce_per_engine_service_any(struct ath10k *ar)
			/* no intr pending on this CE */
			continue;

		ce_state = ((struct ath10k_ce_pipe *)ar->ce_states + ce_id);
		if (ce_state->send_cb || ce_state->recv_cb)
			ath10k_ce_per_engine_service(ar, ce_id);
	}

}

/*
@@ -798,6 +805,26 @@ void ath10k_ce_enable_interrupts(struct ath10k *ar)
			((struct ath10k_ce_pipe *)ar->ce_states + ce_id));
}

void ath10k_ce_enable_per_ce_interrupts(struct ath10k *ar, unsigned int ce_id)
{
	u32 offset;
	u32 ctrl_addr = ath10k_ce_base_address(ar, ce_id);

	offset = HOST_IE_ADDRESS + ctrl_addr;
	ar->bus_write32(ar, offset, 1);
	ar->bus_read32(ar, offset);
}

void ath10k_ce_disable_per_ce_interrupts(struct ath10k *ar, unsigned int ce_id)
{
	u32 offset;
	u32 ctrl_addr = ath10k_ce_base_address(ar, ce_id);

	offset = HOST_IE_ADDRESS + ctrl_addr;
	ar->bus_write32(ar, offset, 0);
	ar->bus_read32(ar, offset);
}

static int ath10k_ce_init_src_ring(struct ath10k *ar,
				   unsigned int ce_id,
				   const struct ce_attr *attr)
+2 −0
Original line number Diff line number Diff line
@@ -239,6 +239,8 @@ void ath10k_ce_per_engine_service_any(struct ath10k *ar);
void ath10k_ce_per_engine_service(struct ath10k *ar, unsigned int ce_id);
int ath10k_ce_disable_interrupts(struct ath10k *ar);
void ath10k_ce_enable_interrupts(struct ath10k *ar);
void ath10k_ce_disable_per_ce_interrupts(struct ath10k *ar, unsigned int ce_id);
void ath10k_ce_enable_per_ce_interrupts(struct ath10k *ar, unsigned int ce_id);

/* ce_attr.flags values */
/* Use NonSnooping PCIe accesses? */
+46 −29
Original line number Diff line number Diff line
@@ -27,9 +27,8 @@
#include <soc/qcom/icnss.h>
#include <linux/of.h>
#include <linux/platform_device.h>

#define ICNSS_MAX_IRQ_REGISTRATIONS 12
const char *ce_name[ICNSS_MAX_IRQ_REGISTRATIONS] = {
#define WCN3990_MAX_IRQ 12
const char *ce_name[WCN3990_MAX_IRQ] = {
	"WLAN_CE_0",
	"WLAN_CE_1",
	"WLAN_CE_2",
@@ -46,6 +45,7 @@ const char *ce_name[ICNSS_MAX_IRQ_REGISTRATIONS] = {

#define ATH10K_SNOC_TARGET_WAIT 3000
#define ATH10K_SNOC_NUM_WARM_RESET_ATTEMPTS 3
#define SNOC_HIF_POWER_DOWN_DELAY 30

static void ath10k_snoc_buffer_cleanup(struct ath10k *ar);
static int ath10k_snoc_init_irq(struct ath10k *ar);
@@ -714,6 +714,20 @@ static void ath10k_snoc_kill_tasklet(struct ath10k *ar)
	del_timer_sync(&ar_snoc->rx_post_retry);
}

static void ath10k_snoc_ce_deinit(struct ath10k *ar)
{
	int i;

	for (i = 0; i < CE_COUNT; i++)
		ath10k_ce_deinit_pipe(ar, i);
}

static void ath10k_snoc_release_resource(struct ath10k *ar)
{
	netif_napi_del(&ar->napi);
	ath10k_snoc_ce_deinit(ar);
}

static int ath10k_snoc_hif_map_service_to_pipe(struct ath10k *ar,
					       u16 service_id,
					       u8 *ul_pipe, u8 *dl_pipe)
@@ -857,14 +871,6 @@ static void ath10k_snoc_buffer_cleanup(struct ath10k *ar)
	}
}

static void ath10k_snoc_ce_deinit(struct ath10k *ar)
{
	int i;

	for (i = 0; i < CE_COUNT; i++)
		ath10k_ce_deinit_pipe(ar, i);
}

static void ath10k_snoc_flush(struct ath10k *ar)
{
	ath10k_snoc_kill_tasklet(ar);
@@ -873,14 +879,13 @@ static void ath10k_snoc_flush(struct ath10k *ar)

static void ath10k_snoc_hif_stop(struct ath10k *ar)
{
	if (!ar)
		return;
	ath10k_dbg(ar, ATH10K_DBG_BOOT, "boot hif stop\n");
	ath10k_snoc_irq_disable(ar);
	ath10k_snoc_flush(ar);
}

static int ath10k_snoc_init_config(struct ath10k *ar)
{
	return 0;
	napi_synchronize(&ar->napi);
	napi_disable(&ar->napi);
}

static int ath10k_snoc_alloc_pipes(struct ath10k *ar)
@@ -935,9 +940,8 @@ static int ath10k_snoc_init_pipes(struct ath10k *ar)
static void ath10k_snoc_hif_power_down(struct ath10k *ar)
{
	ath10k_dbg(ar, ATH10K_DBG_BOOT, "boot hif power down\n");
	msleep(1000);
	msleep(SNOC_HIF_POWER_DOWN_DELAY);
	icnss_wlan_disable(ICNSS_OFF);
	icnss_power_off(ar->dev);
}

static void ath10k_snoc_ce_tasklet(unsigned long ptr)
@@ -974,7 +978,8 @@ static irqreturn_t ath10k_snoc_per_engine_handler(int irq, void *arg)
		return IRQ_HANDLED;
	}

	tasklet_schedule(&ar_snoc->pipe_info[ce_id].intr);
	ath10k_snoc_irq_disable(ar);
	napi_schedule(&ar->napi);

	return IRQ_HANDLED;
}
@@ -1149,7 +1154,6 @@ static int ath10k_snoc_hif_power_up(struct ath10k *ar)
		   __func__, ar->state);

	if (ar->state == ATH10K_STATE_ON) {
		icnss_power_on(ar->dev);
		ret = ath10k_snoc_bus_configure(ar);
		if (ret)
			ath10k_err(ar, "failed to configure bus: %d\n", ret);
@@ -1160,21 +1164,30 @@ static int ath10k_snoc_hif_power_up(struct ath10k *ar)
		goto err_sleep;
	}

	ret = ath10k_snoc_init_config(ar);
	if (ret) {
		ath10k_err(ar, "failed to setup init config: %d\n", ret);
		goto err_ce;
	}

	napi_enable(&ar->napi);
	return 0;

err_ce:
	ath10k_snoc_ce_deinit(ar);

err_sleep:
	return ret;
}

static int ath10k_snoc_napi_poll(struct napi_struct *ctx, int budget)
{
	struct ath10k *ar = container_of(ctx, struct ath10k, napi);
	int done = 0;

	ath10k_ce_per_engine_service_any(ar);

	done = ath10k_htt_txrx_compl_task(ar, budget);

	if (done < budget) {
		napi_complete(ctx);
		ath10k_snoc_irq_enable(ar);
	}

	return done;
}

static int ath10k_snoc_resource_init(struct ath10k *ar)
{
	int i, ret = 0;
@@ -1266,6 +1279,9 @@ static int ath10k_snoc_probe(struct platform_device *pdev)
		goto err_core_destroy;
	}

	netif_napi_add(&ar->napi_dev, &ar->napi, ath10k_snoc_napi_poll,
		       ATH10K_NAPI_BUDGET);

	ret = ath10k_snoc_init_irq(ar);
	if (ret) {
		ath10k_err(ar, "failed to init irqs: %d\n", ret);
@@ -1320,6 +1336,7 @@ static int ath10k_snoc_remove(struct platform_device *pdev)
	ath10k_snoc_free_irq(ar);
	ath10k_snoc_kill_tasklet(ar);
	ath10k_snoc_deinit_irq(ar);
	ath10k_snoc_release_resource(ar);
	ath10k_snoc_free_pipes(ar);
	ath10k_core_destroy(ar);