diff --git a/hif/src/ce/ce_api.h b/hif/src/ce/ce_api.h index d2b0f31530..7ba2b344a2 100644 --- a/hif/src/ce/ce_api.h +++ b/hif/src/ce/ce_api.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2013-2020 The Linux Foundation. All rights reserved. + * Copyright (c) 2013-2021 The Linux Foundation. All rights reserved. * * Permission to use, copy, modify, and/or distribute this software for * any purpose with or without fee is hereby granted, provided that the @@ -438,6 +438,7 @@ void war_ce_src_ring_write_idx_set(struct hif_softc *scn, #define CE_ATTR_ENABLE_POLL 0x10 /* poll for residue descriptors */ #define CE_ATTR_DIAG 0x20 /* Diag CE */ #define CE_ATTR_INIT_ON_DEMAND 0x40 /* Initialized on demand */ +#define CE_ATTR_HI_TASKLET 0x80 /* HI_TASKLET CE */ /** * struct CE_attr - Attributes of an instance of a Copy Engine diff --git a/hif/src/ce/ce_assignment.h b/hif/src/ce/ce_assignment.h index 3756a099f1..a9e873ade6 100644 --- a/hif/src/ce/ce_assignment.h +++ b/hif/src/ce/ce_assignment.h @@ -1325,7 +1325,7 @@ static struct CE_attr host_ce_config_wlan_qca6750[] = { /* target->host HTT + HTC control */ { /* CE1 */ CE_ATTR_FLAGS, 0, 0, 2048, 512, NULL,}, /* target->host WMI */ - { /* CE2 */ CE_ATTR_FLAGS, 0, 0, 2048, 32, NULL,}, + { /* CE2 */ CE_ATTR_FLAGS | CE_ATTR_HI_TASKLET, 0, 0, 2048, 32, NULL,}, /* host->target WMI */ { /* CE3 */ CE_ATTR_FLAGS, 0, 32, 2048, 0, NULL,}, /* host->target HTT */ diff --git a/hif/src/ce/ce_main.h b/hif/src/ce/ce_main.h index c5070549b5..7ccbed28b7 100644 --- a/hif/src/ce/ce_main.h +++ b/hif/src/ce/ce_main.h @@ -147,6 +147,7 @@ struct ce_tasklet_entry { struct tasklet_struct intr_tq; enum ce_id_type ce_id; bool inited; + bool hi_tasklet_ce; void *hif_ce_state; }; diff --git a/hif/src/ce/ce_tasklet.c b/hif/src/ce/ce_tasklet.c index df60c54e70..0e8f897010 100644 --- a/hif/src/ce/ce_tasklet.c +++ b/hif/src/ce/ce_tasklet.c @@ -48,6 +48,20 @@ struct tasklet_work { }; +/** + * ce_tasklet_schedule() - schedule CE tasklet + * @tasklet_entry: ce tasklet entry + * + * Return: None + */ +static inline void ce_tasklet_schedule(struct ce_tasklet_entry *tasklet_entry) +{ + if (tasklet_entry->hi_tasklet_ce) + tasklet_hi_schedule(&tasklet_entry->intr_tq); + else + tasklet_schedule(&tasklet_entry->intr_tq); +} + /** * reschedule_ce_tasklet_work_handler() - reschedule work * @work: struct work_struct @@ -75,7 +89,7 @@ static void reschedule_ce_tasklet_work_handler(struct work_struct *work) return; } if (hif_ce_state->tasklets[ce_work->id].inited) - tasklet_schedule(&hif_ce_state->tasklets[ce_work->id].intr_tq); + ce_tasklet_schedule(&hif_ce_state->tasklets[ce_work->id]); } static struct tasklet_work tasklet_workers[CE_ID_MAX]; @@ -122,17 +136,6 @@ void deinit_tasklet_workers(struct hif_opaque_softc *scn) qdf_cancel_work(&tasklet_workers[id].reg_work); } -/** - * ce_schedule_tasklet() - schedule ce tasklet - * @tasklet_entry: struct ce_tasklet_entry - * - * Return: N/A - */ -static inline void ce_schedule_tasklet(struct ce_tasklet_entry *tasklet_entry) -{ - tasklet_schedule(&tasklet_entry->intr_tq); -} - #ifdef CE_TASKLET_DEBUG_ENABLE /** * hif_record_tasklet_exec_entry_ts() - Record ce tasklet execution @@ -421,7 +424,7 @@ static void ce_tasklet(unsigned long data) return; } - ce_schedule_tasklet(tasklet_entry); + ce_tasklet_schedule(tasklet_entry); hif_latency_detect_tasklet_sched(scn, tasklet_entry); return; } @@ -448,12 +451,20 @@ static void ce_tasklet(unsigned long data) void ce_tasklet_init(struct HIF_CE_state *hif_ce_state, uint32_t mask) { int i; + struct CE_attr *attr; for (i = 0; i < CE_COUNT_MAX; i++) { if (mask & (1 << i)) { hif_ce_state->tasklets[i].ce_id = i; hif_ce_state->tasklets[i].inited = true; hif_ce_state->tasklets[i].hif_ce_state = hif_ce_state; + + attr = &hif_ce_state->host_ce_config[i]; + if (attr->flags & CE_ATTR_HI_TASKLET) + hif_ce_state->tasklets[i].hi_tasklet_ce = true; + else + hif_ce_state->tasklets[i].hi_tasklet_ce = false; + tasklet_init(&hif_ce_state->tasklets[i].intr_tq, ce_tasklet, (unsigned long)&hif_ce_state->tasklets[i]); @@ -649,7 +660,7 @@ static inline bool hif_tasklet_schedule(struct hif_opaque_softc *hif_ctx, * in whunt, tasklet may run before finished hif_tasklet_schedule. */ hif_latency_detect_tasklet_sched(scn, tasklet_entry); - tasklet_schedule(&tasklet_entry->intr_tq); + ce_tasklet_schedule(tasklet_entry); if (scn->ce_latency_stats) hif_record_tasklet_sched_entry_ts(scn, tasklet_entry->ce_id);