diff --git a/hif/src/ce/ce_api.h b/hif/src/ce/ce_api.h index 828a8e8682f8..946b4b4943ef 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 @@ -437,6 +437,7 @@ void war_ce_src_ring_write_idx_set(struct hif_softc *scn, #define CE_ATTR_DISABLE_INTR 0x08 /* no interrupt on copy completion */ #define CE_ATTR_ENABLE_POLL 0x10 /* poll for residue descriptors */ #define CE_ATTR_DIAG 0x20 /* Diag CE */ +#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 e749ef2dae07..b37e69bb8fb8 100644 --- a/hif/src/ce/ce_assignment.h +++ b/hif/src/ce/ce_assignment.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014-2020 The Linux Foundation. All rights reserved. + * Copyright (c) 2014-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 @@ -1311,7 +1311,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 d28753436442..9912b8dbf47a 100644 --- a/hif/src/ce/ce_main.h +++ b/hif/src/ce/ce_main.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015-2020 The Linux Foundation. All rights reserved. + * Copyright (c) 2015-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 @@ -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 a1381c380e50..b766932f60a3 100644 --- a/hif/src/ce/ce_tasklet.c +++ b/hif/src/ce/ce_tasklet.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015-2020 The Linux Foundation. All rights reserved. + * Copyright (c) 2015-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 @@ -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 @@ -73,7 +87,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]; @@ -127,17 +141,6 @@ void deinit_tasklet_workers(struct hif_opaque_softc *scn) work_initialized = false; } -/** - * 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 @@ -418,7 +421,7 @@ static void ce_tasklet(unsigned long data) hif_record_ce_desc_event(scn, tasklet_entry->ce_id, HIF_CE_TASKLET_RESCHEDULE, NULL, NULL, -1, 0); - ce_schedule_tasklet(tasklet_entry); + ce_tasklet_schedule(tasklet_entry); hif_latency_detect_tasklet_sched(scn, tasklet_entry); return; } @@ -445,12 +448,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]); @@ -648,7 +659,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);