mirror of
https://github.com/Telecominfraproject/wlan-ap.git
synced 2025-12-18 01:41:24 +00:00
This series is based on * 2020-07-10 ipq6018-ilq-11-0_qca_oem-034672b0676c37b1f4519e5720e18e95fe6236ef Add support for * qsdk kernel/v4.4 * qsdk ethernet subsystem * v5.7 ath11k backport + QualComm staging patches (wlan_ap_1.0) * ath11k-firmware * hostapd/iw/... Feature support * full boot, system detection * sysupgrade to nand * HE support via latest hostapd * driver support for usb, crypto, hwmon, cpufreq, ... Missing * NSS/HW flow offloading - FW blob is not redistributable Using the qsdk v4.4 is an intermediate solution while the vanilla is being tested. Vanilla kernel is almost on feature par. Work has already started to upstream the ethernet and switch drivers. Once complete the target will be fully upstream. Signed-off-by: John Crispin <john@phrozen.org>
340 lines
9.1 KiB
Diff
340 lines
9.1 KiB
Diff
From 4cbfe92c1d89900c83bfb623b021871ee805b93f Mon Sep 17 00:00:00 2001
|
|
From: Anilkumar Kolli <akolli@codeaurora.org>
|
|
Date: Fri, 15 May 2020 14:44:16 +0530
|
|
Subject: [PATCH 180/187] ath11k: add support poll based dp service
|
|
|
|
Add code to process lmac rings in polling.
|
|
|
|
Signed-off-by: Karthikeyan Periyasamy <periyasa@codeaurora.org>
|
|
Signed-off-by: Anilkumar Kolli <akolli@codeaurora.org>
|
|
---
|
|
drivers/net/wireless/ath/ath11k/core.c | 154 +++++++++++++++++++++++++++++++++
|
|
drivers/net/wireless/ath/ath11k/core.h | 19 ++++
|
|
drivers/net/wireless/ath/ath11k/dp.c | 39 +++++++++
|
|
drivers/net/wireless/ath/ath11k/dp.h | 3 +
|
|
drivers/net/wireless/ath/ath11k/pci.c | 19 ++++
|
|
5 files changed, 234 insertions(+)
|
|
|
|
Index: backports-20200415-4.4.60-9de9a9b19d3f/drivers/net/wireless/ath/ath11k/core.c
|
|
===================================================================
|
|
--- backports-20200415-4.4.60-9de9a9b19d3f.orig/drivers/net/wireless/ath/ath11k/core.c
|
|
+++ backports-20200415-4.4.60-9de9a9b19d3f/drivers/net/wireless/ath/ath11k/core.c
|
|
@@ -13,6 +13,8 @@
|
|
#include "debug.h"
|
|
#include "hif.h"
|
|
|
|
+#define ATH11K_POLL_TIMEOUT_MS (10)
|
|
+
|
|
unsigned int ath11k_debug_mask;
|
|
EXPORT_SYMBOL(ath11k_debug_mask);
|
|
unsigned int rawmode;
|
|
@@ -901,6 +903,142 @@ static int ath11k_init_hw_params(struct
|
|
return 0;
|
|
}
|
|
|
|
+static int ath11k_core_poll_timer_enable(struct ath11k_poll *poll)
|
|
+{
|
|
+ if (!poll->is_init)
|
|
+ return -EINVAL;
|
|
+
|
|
+ spin_lock_bh(&poll->lock);
|
|
+
|
|
+ mod_timer(&poll->timer,
|
|
+ jiffies + msecs_to_jiffies(ATH11K_POLL_TIMEOUT_MS));
|
|
+ poll->is_enable = true;
|
|
+
|
|
+ spin_unlock_bh(&poll->lock);
|
|
+
|
|
+ return 0;
|
|
+}
|
|
+
|
|
+static int ath11k_core_napi_poll(struct napi_struct *napi, int budget)
|
|
+{
|
|
+ struct ath11k_poll *poll = container_of(napi, struct ath11k_poll, napi);
|
|
+ struct ath11k_base *ab = poll->ab;
|
|
+ int work_done = 0;
|
|
+
|
|
+ if (poll->lmac_poll)
|
|
+ work_done = ath11k_dp_service_lmac_srng(ab, napi, budget);
|
|
+
|
|
+ if (work_done < budget) {
|
|
+ napi_complete_done(napi, work_done);
|
|
+ ath11k_core_poll_timer_enable(poll);
|
|
+ }
|
|
+
|
|
+ if (work_done > budget)
|
|
+ work_done = budget;
|
|
+
|
|
+ return work_done;
|
|
+}
|
|
+
|
|
+static void ath11k_core_poll_handler(struct timer_list *timer)
|
|
+{
|
|
+ struct ath11k_poll *poll = from_timer(poll, timer, timer);
|
|
+ struct ath11k_base *ab;
|
|
+
|
|
+ if (!poll)
|
|
+ return;
|
|
+
|
|
+ ab = poll->ab;
|
|
+ poll->timestamp = jiffies;
|
|
+
|
|
+ napi_schedule(&poll->napi);
|
|
+}
|
|
+
|
|
+int ath11k_core_poll_enable(struct ath11k_poll *poll)
|
|
+{
|
|
+ if (!poll->is_init)
|
|
+ return -EINVAL;
|
|
+
|
|
+ napi_enable(&poll->napi);
|
|
+ ath11k_core_poll_timer_enable(poll);
|
|
+
|
|
+ return 0;
|
|
+}
|
|
+EXPORT_SYMBOL(ath11k_core_poll_enable);
|
|
+
|
|
+static void __ath11k_core_poll_timer_disable(struct ath11k_poll *poll)
|
|
+{
|
|
+ del_timer_sync(&poll->timer);
|
|
+}
|
|
+
|
|
+static void ath11k_core_poll_timer_disable(struct ath11k_poll *poll)
|
|
+{
|
|
+ if (!poll->is_init)
|
|
+ return;
|
|
+
|
|
+ spin_lock_bh(&poll->lock);
|
|
+
|
|
+ if (poll->is_enable) {
|
|
+ __ath11k_core_poll_timer_disable(poll);
|
|
+
|
|
+ poll->is_enable = false;
|
|
+ }
|
|
+
|
|
+ spin_unlock_bh(&poll->lock);
|
|
+}
|
|
+
|
|
+void ath11k_core_poll_disable(struct ath11k_poll *poll)
|
|
+{
|
|
+ if (!poll->is_init)
|
|
+ return;
|
|
+
|
|
+ ath11k_core_poll_timer_disable(poll);
|
|
+
|
|
+ napi_synchronize(&poll->napi);
|
|
+ napi_disable(&poll->napi);
|
|
+}
|
|
+EXPORT_SYMBOL(ath11k_core_poll_disable);
|
|
+
|
|
+int ath11k_core_poll_config(struct ath11k_base *ab)
|
|
+{
|
|
+ if (ab->poll.is_init)
|
|
+ return 0;
|
|
+
|
|
+ spin_lock_init(&ab->poll.lock);
|
|
+
|
|
+ ab->poll.ab = ab;
|
|
+ ab->poll.is_enable = false;
|
|
+
|
|
+ timer_setup(&ab->poll.timer, ath11k_core_poll_handler, 0);
|
|
+ init_dummy_netdev(&ab->poll.napi_ndev);
|
|
+ netif_napi_add(&ab->poll.napi_ndev, &ab->poll.napi,
|
|
+ ath11k_core_napi_poll, NAPI_POLL_WEIGHT);
|
|
+
|
|
+ ab->poll.is_init = true;
|
|
+
|
|
+ return 0;
|
|
+}
|
|
+EXPORT_SYMBOL(ath11k_core_poll_config);
|
|
+
|
|
+void ath11k_core_poll_free(struct ath11k_base *ab)
|
|
+{
|
|
+ if (!ab->poll.is_init)
|
|
+ return;
|
|
+
|
|
+ spin_lock_bh(&ab->poll.lock);
|
|
+
|
|
+ if (ab->poll.is_enable) {
|
|
+ __ath11k_core_poll_timer_disable(&ab->poll);
|
|
+
|
|
+ ab->poll.is_enable = false;
|
|
+ }
|
|
+
|
|
+ ab->poll.ab = NULL;
|
|
+ ab->poll.is_init = false;
|
|
+
|
|
+ spin_unlock_bh(&ab->poll.lock);
|
|
+}
|
|
+EXPORT_SYMBOL(ath11k_core_poll_free);
|
|
+
|
|
int ath11k_core_pre_init(struct ath11k_base *ab)
|
|
{
|
|
int ret;
|
|
Index: backports-20200415-4.4.60-9de9a9b19d3f/drivers/net/wireless/ath/ath11k/core.h
|
|
===================================================================
|
|
--- backports-20200415-4.4.60-9de9a9b19d3f.orig/drivers/net/wireless/ath/ath11k/core.h
|
|
+++ backports-20200415-4.4.60-9de9a9b19d3f/drivers/net/wireless/ath/ath11k/core.h
|
|
@@ -710,6 +710,18 @@ struct ath11k_soc_dp_stats {
|
|
struct ath11k_soc_dp_tx_err_stats tx_err;
|
|
};
|
|
|
|
+struct ath11k_poll {
|
|
+ spinlock_t lock;
|
|
+ struct timer_list timer;
|
|
+ struct ath11k_base *ab;
|
|
+ struct napi_struct napi;
|
|
+ struct net_device napi_ndev;
|
|
+ u64 timestamp;
|
|
+ bool is_enable;
|
|
+ bool is_init;
|
|
+ bool lmac_poll;
|
|
+};
|
|
+
|
|
/* Master structure to hold the hw data which may be used in core module */
|
|
struct ath11k_base {
|
|
enum ath11k_hw_rev hw_rev;
|
|
@@ -811,6 +823,8 @@ struct ath11k_base {
|
|
bool use_register_windowing;
|
|
bool static_window_map;
|
|
const struct ath11k_hw_regs *regs;
|
|
+ bool is_poll;
|
|
+ struct ath11k_poll poll;
|
|
|
|
/* must be last */
|
|
u8 drv_priv[0] __aligned(sizeof(void *));
|
|
@@ -961,6 +975,11 @@ void ath11k_core_free_bdf(struct ath11k_
|
|
void ath11k_core_halt(struct ath11k *ar);
|
|
int ath11k_core_pre_init(struct ath11k_base *ab);
|
|
|
|
+int ath11k_core_poll_config(struct ath11k_base *ab);
|
|
+int ath11k_core_poll_enable(struct ath11k_poll *poll);
|
|
+void ath11k_core_poll_disable(struct ath11k_poll *poll);
|
|
+void ath11k_core_poll_free(struct ath11k_base *ab);
|
|
+
|
|
static inline const char *ath11k_scan_state_str(enum ath11k_scan_state state)
|
|
{
|
|
switch (state) {
|
|
Index: backports-20200415-4.4.60-9de9a9b19d3f/drivers/net/wireless/ath/ath11k/dp.c
|
|
===================================================================
|
|
--- backports-20200415-4.4.60-9de9a9b19d3f.orig/drivers/net/wireless/ath/ath11k/dp.c
|
|
+++ backports-20200415-4.4.60-9de9a9b19d3f/drivers/net/wireless/ath/ath11k/dp.c
|
|
@@ -736,6 +736,45 @@ fail_desc_bank_free:
|
|
return ret;
|
|
}
|
|
|
|
+int ath11k_dp_service_lmac_srng(struct ath11k_base *ab,
|
|
+ struct napi_struct *napi,
|
|
+ int budget)
|
|
+{
|
|
+ struct ath11k_pdev_dp *dp;
|
|
+ struct dp_rxdma_ring *rx_ring;
|
|
+ int i, tot_work_done = 0, work_done = 0;
|
|
+
|
|
+ for (i = 0; i < ab->num_radios; i++) {
|
|
+ work_done = ath11k_dp_rx_process_mon_rings(ab, i, napi, budget);
|
|
+
|
|
+ budget -= work_done;
|
|
+ tot_work_done += work_done;
|
|
+
|
|
+ if (budget <= 0)
|
|
+ goto done;
|
|
+ }
|
|
+
|
|
+ for (i = 0; i < ab->num_radios; i++) {
|
|
+ dp = &ab->pdevs[i].ar->dp;
|
|
+ rx_ring = &dp->rx_refill_buf_ring;
|
|
+
|
|
+ work_done = ath11k_dp_process_rxdma_err(ab, i, budget);
|
|
+
|
|
+ budget -= work_done;
|
|
+ tot_work_done += work_done;
|
|
+
|
|
+ if (budget <= 0)
|
|
+ goto done;
|
|
+
|
|
+ ath11k_dp_rxbufs_replenish(ab, i, rx_ring, 0,
|
|
+ HAL_RX_BUF_RBM_SW3_BM,
|
|
+ GFP_ATOMIC);
|
|
+ }
|
|
+
|
|
+done:
|
|
+ return tot_work_done;
|
|
+}
|
|
+
|
|
int ath11k_dp_service_srng(struct ath11k_base *ab,
|
|
struct ath11k_ext_irq_grp *irq_grp,
|
|
int budget)
|
|
Index: backports-20200415-4.4.60-9de9a9b19d3f/drivers/net/wireless/ath/ath11k/dp.h
|
|
===================================================================
|
|
--- backports-20200415-4.4.60-9de9a9b19d3f.orig/drivers/net/wireless/ath/ath11k/dp.h
|
|
+++ backports-20200415-4.4.60-9de9a9b19d3f/drivers/net/wireless/ath/ath11k/dp.h
|
|
@@ -1664,6 +1664,9 @@ static inline void ath11k_dp_get_mac_add
|
|
memcpy(addr + 4, &addr_h16, ETH_ALEN - 4);
|
|
}
|
|
|
|
+int ath11k_dp_service_lmac_srng(struct ath11k_base *ab,
|
|
+ struct napi_struct *napi,
|
|
+ int budget);
|
|
int ath11k_dp_service_srng(struct ath11k_base *ab,
|
|
struct ath11k_ext_irq_grp *irq_grp,
|
|
int budget);
|
|
Index: backports-20200415-4.4.60-9de9a9b19d3f/drivers/net/wireless/ath/ath11k/pci.c
|
|
===================================================================
|
|
--- backports-20200415-4.4.60-9de9a9b19d3f.orig/drivers/net/wireless/ath/ath11k/pci.c
|
|
+++ backports-20200415-4.4.60-9de9a9b19d3f/drivers/net/wireless/ath/ath11k/pci.c
|
|
@@ -535,6 +535,9 @@ static void ath11k_pci_free_ext_irq(stru
|
|
for (j = 0; j < irq_grp->num_irq; j++)
|
|
free_irq(ab->irq_num[irq_grp->irqs[j]], irq_grp);
|
|
}
|
|
+
|
|
+ if (ab->is_poll)
|
|
+ ath11k_core_poll_free(ab);
|
|
}
|
|
|
|
static void ath11k_pci_free_irq(struct ath11k_base *ab)
|
|
@@ -656,6 +659,9 @@ static void ath11k_pci_ext_irq_enable(st
|
|
napi_enable(&irq_grp->napi);
|
|
ath11k_pci_ext_grp_enable(irq_grp);
|
|
}
|
|
+
|
|
+ if (ab->is_poll)
|
|
+ ath11k_core_poll_enable(&ab->poll);
|
|
}
|
|
|
|
static void ath11k_pci_sync_ext_irqs(struct ath11k_base *ab)
|
|
@@ -677,6 +683,9 @@ static void ath11k_pci_ext_irq_disable(s
|
|
{
|
|
__ath11k_pci_ext_irq_disable(ab);
|
|
ath11k_pci_sync_ext_irqs(ab);
|
|
+
|
|
+ if (ab->is_poll)
|
|
+ ath11k_core_poll_disable(&ab->poll);
|
|
}
|
|
|
|
static int ath11k_pci_ext_grp_napi_poll(struct napi_struct *napi, int budget)
|
|
@@ -773,6 +782,14 @@ static int ath11k_pci_ext_irq_config(str
|
|
}
|
|
}
|
|
|
|
+ if (ab->is_poll) {
|
|
+ ret = ath11k_core_poll_config(ab);
|
|
+ if (ret) {
|
|
+ ath11k_err(ab, "failed to config poll %d\n", ret);
|
|
+ return ret;
|
|
+ }
|
|
+ }
|
|
+
|
|
return 0;
|
|
}
|
|
|
|
@@ -1175,6 +1192,8 @@ static int ath11k_pci_probe(struct pci_d
|
|
if (ab->hw_rev == ATH11K_HW_QCN90XX) {
|
|
ab->fixed_mem_region = true;
|
|
ab->static_window_map = true;
|
|
+ ab->is_poll = true;
|
|
+ ab->poll.lmac_poll = true;
|
|
} else {
|
|
ab->use_register_windowing = true;
|
|
ab->fixed_mem_region = false;
|