diff mbox series

[RFC,v1,062/256] cl8k: add dfs/radar.c

Message ID 20210617160223.160998-63-viktor.barna@celeno.com (mailing list archive)
State RFC
Delegated to: Kalle Valo
Headers show
Series wireless: cl8k driver for Celeno IEEE 802.11ax devices | expand

Commit Message

Viktor Barna June 17, 2021, 3:59 p.m. UTC
From: Viktor Barna <viktor.barna@celeno.com>

(Part of the split. Please, take a look at the cover letter for more
details).

Signed-off-by: Viktor Barna <viktor.barna@celeno.com>
---
 drivers/net/wireless/celeno/cl8k/dfs/radar.c | 116 +++++++++++++++++++
 1 file changed, 116 insertions(+)
 create mode 100644 drivers/net/wireless/celeno/cl8k/dfs/radar.c

--
2.30.0
diff mbox series

Patch

diff --git a/drivers/net/wireless/celeno/cl8k/dfs/radar.c b/drivers/net/wireless/celeno/cl8k/dfs/radar.c
new file mode 100644
index 000000000000..3f763e274102
--- /dev/null
+++ b/drivers/net/wireless/celeno/cl8k/dfs/radar.c
@@ -0,0 +1,116 @@ 
+// SPDX-License-Identifier: MIT
+/* Copyright(c) 2019-2021, Celeno Communications Ltd. */
+
+#include "dfs/radar.h"
+#include "dfs/dfs.h"
+#ifdef CONFIG_CL_PCIE
+#include "bus/pci/irq.h"
+#include "ipc_shared.h"
+#endif
+
+static void cl_radar_handler(struct cl_hw *cl_hw, struct cl_radar_elem *radar_elem,
+                            unsigned long time)
+{
+       /* Retrieve the radar pulses structure */
+       struct cl_radar_pulse_array *pulses = radar_elem->radarbuf_ptr;
+
+       cl_dfs_pulse_process(cl_hw, (struct cl_radar_pulse *)pulses->pulse,
+                            pulses->cnt, time);
+}
+
+static void cl_radar_tasklet(unsigned long data)
+{
+       struct cl_hw *cl_hw = (struct cl_hw *)data;
+       struct cl_radar_queue_elem *radar_elem = NULL;
+       unsigned long flags = 0;
+
+       while (!list_empty(&cl_hw->radar_queue.head)) {
+               spin_lock_irqsave(&cl_hw->radar_queue.lock, flags);
+               radar_elem = list_first_entry(&cl_hw->radar_queue.head,
+                                             struct cl_radar_queue_elem, list);
+               list_del(&radar_elem->list);
+               spin_unlock_irqrestore(&cl_hw->radar_queue.lock, flags);
+
+               cl_radar_handler(radar_elem->cl_hw, &radar_elem->radar_elem,
+                                radar_elem->time);
+
+               kfree(radar_elem->radar_elem.radarbuf_ptr);
+               kfree(radar_elem);
+       }
+
+#ifdef CONFIG_CL_PCIE
+       if (!test_bit(CL_DEV_STOP_HW, &cl_hw->drv_flags))
+               cl_irq_enable(cl_hw, cl_hw->ipc_e2a_irq.radar);
+#endif
+}
+
+void cl_radar_init(struct cl_hw *cl_hw)
+{
+       INIT_LIST_HEAD(&cl_hw->radar_queue.head);
+
+       tasklet_init(&cl_hw->radar_tasklet, cl_radar_tasklet, (unsigned long)cl_hw);
+
+       spin_lock_init(&cl_hw->radar_queue.lock);
+}
+
+void cl_radar_push(struct cl_hw *cl_hw, struct cl_radar_elem *radar_elem)
+{
+       struct cl_radar_queue_elem *new_queue_elem = NULL;
+       u32 i;
+
+       new_queue_elem = kzalloc(sizeof(*new_queue_elem), GFP_ATOMIC);
+
+       if (new_queue_elem) {
+               new_queue_elem->radar_elem.radarbuf_ptr =
+                       kzalloc(sizeof(*new_queue_elem->radar_elem.radarbuf_ptr), GFP_ATOMIC);
+
+               if (new_queue_elem->radar_elem.radarbuf_ptr) {
+                       new_queue_elem->radar_elem.dma_addr = radar_elem->dma_addr;
+                       new_queue_elem->radar_elem.radarbuf_ptr->cnt =
+                               le32_to_cpu(radar_elem->radarbuf_ptr->cnt);
+
+                       /* Copy into local list */
+                       for (i = 0; i < ARRAY_SIZE(radar_elem->radarbuf_ptr->pulse); i++)
+                               new_queue_elem->radar_elem.radarbuf_ptr->pulse[i] =
+                                       le64_to_cpu(radar_elem->radarbuf_ptr->pulse[i]);
+
+                       new_queue_elem->time = jiffies_to_msecs(jiffies);
+                       new_queue_elem->cl_hw = cl_hw;
+
+                       spin_lock(&cl_hw->radar_queue.lock);
+                       list_add_tail(&new_queue_elem->list, &cl_hw->radar_queue.head);
+                       spin_unlock(&cl_hw->radar_queue.lock);
+               } else {
+                       kfree(new_queue_elem);
+               }
+       }
+}
+
+void cl_radar_tasklet_schedule(struct cl_hw *cl_hw)
+{
+       tasklet_schedule(&cl_hw->radar_tasklet);
+}
+
+void cl_radar_flush(struct cl_hw *cl_hw)
+{
+       struct cl_radar_queue_elem *radar_elem = NULL;
+       unsigned long flags = 0;
+
+       spin_lock_irqsave(&cl_hw->radar_queue.lock, flags);
+
+       while (!list_empty(&cl_hw->radar_queue.head)) {
+               radar_elem = list_first_entry(&cl_hw->radar_queue.head,
+                                             struct cl_radar_queue_elem, list);
+               list_del(&radar_elem->list);
+               kfree(radar_elem->radar_elem.radarbuf_ptr);
+               kfree(radar_elem);
+       }
+
+       spin_unlock_irqrestore(&cl_hw->radar_queue.lock, flags);
+}
+
+void cl_radar_close(struct cl_hw *cl_hw)
+{
+       cl_radar_flush(cl_hw);
+       tasklet_kill(&cl_hw->radar_tasklet);
+}