From d4a1bd480003f3e1a0590bc46fbcb24f05652ca7 Mon Sep 17 00:00:00 2001
From: tzh <tanzhtanzh@gmail.com>
Date: Thu, 15 Aug 2024 06:56:47 +0000
Subject: [PATCH] feat(wfit/bt): update aic8800 wifi/bt drive and hal

---
 longan/kernel/linux-4.9/drivers/net/wireless/aic8800/aic8800_fdrv/aicwf_txrxif.c |  191 +++++++++++++++++++++++++----------------------
 1 files changed, 103 insertions(+), 88 deletions(-)

diff --git a/longan/kernel/linux-4.9/drivers/net/wireless/aic8800/aic8800_fdrv/aicwf_txrxif.c b/longan/kernel/linux-4.9/drivers/net/wireless/aic8800/aic8800_fdrv/aicwf_txrxif.c
old mode 100644
new mode 100755
index 340fcad..5b21dc6
--- a/longan/kernel/linux-4.9/drivers/net/wireless/aic8800/aic8800_fdrv/aicwf_txrxif.c
+++ b/longan/kernel/linux-4.9/drivers/net/wireless/aic8800/aic8800_fdrv/aicwf_txrxif.c
@@ -25,6 +25,7 @@
 #ifdef AICWF_SDIO_SUPPORT
 #include "sdio_host.h"
 #endif
+#include "aic_bsp_export.h"
 
 int aicwf_bus_init(uint bus_hdrlen, struct device *dev)
 {
@@ -99,8 +100,9 @@
 #endif
 #ifdef AICWF_SDIO_SUPPORT
 	sdiodev = bus_if->bus_priv.sdio;
-	if (g_rwnx_plat->enabled)
+	if (g_rwnx_plat && g_rwnx_plat->enabled) {
 		rwnx_platform_deinit(sdiodev->rwnx_hw);
+	}
 #endif
 
 	if (bus_if->cmd_buf) {
@@ -109,7 +111,7 @@
 	}
 
 	if (bus_if->bustx_thread) {
-		complete(&bus_if->bustx_trgg);
+		complete_all(&bus_if->bustx_trgg);
 		kthread_stop(bus_if->bustx_thread);
 		bus_if->bustx_thread = NULL;
 	}
@@ -149,7 +151,11 @@
 #endif
 
 	atomic_set(&tx_priv->aggr_count, 0);
+#ifdef AICBSP_RESV_MEM_SUPPORT
+	tx_priv->aggr_buf = aicbsp_resv_mem_alloc_skb(MAX_AGGR_TXPKT_LEN, AIC_RESV_MEM_TXDATA);
+#else
 	tx_priv->aggr_buf = dev_alloc_skb(MAX_AGGR_TXPKT_LEN);
+#endif
 	if (!tx_priv->aggr_buf) {
 		txrx_err("Alloc bus->txdata_buf failed!\n");
 		kfree(tx_priv);
@@ -163,10 +169,14 @@
 
 void aicwf_tx_deinit(struct aicwf_tx_priv *tx_priv)
 {
-	if (tx_priv && tx_priv->aggr_buf)
+	if (tx_priv && tx_priv->aggr_buf) {
+#ifdef AICBSP_RESV_MEM_SUPPORT
+		aicbsp_resv_mem_kfree_skb(tx_priv->aggr_buf, AIC_RESV_MEM_TXDATA);
+#else
 		dev_kfree_skb(tx_priv->aggr_buf);
-
-	kfree(tx_priv);
+#endif
+		kfree(tx_priv);
+	}
 }
 
 #ifdef AICWF_SDIO_SUPPORT
@@ -187,6 +197,41 @@
 	return true;
 }
 #endif
+
+static void aicwf_count_rx_tp(struct aicwf_rx_priv *rx_priv, int len)
+{
+#ifdef AICWF_SDIO_SUPPORT
+	struct device *rwnx_dev = rx_priv->sdiodev->dev;
+#endif
+#ifdef AICWF_USB_SUPPORT
+	struct device *rwnx_dev = rx_priv->usbdev->dev;
+#endif
+	long long timeus = 0;
+	char *envp[] = {
+		"SYSTEM=WIFI",
+		"EVENT=BOOSTREQ",
+		"SUBEVENT=RX",
+		"TIMEOUT_SEC=5",
+		NULL};
+
+	rx_priv->rx_data_len += len;
+
+	rx_priv->rxtimeend = ktime_get();
+#if LINUX_VERSION_CODE < KERNEL_VERSION(4, 10, 0)
+	timeus = div_u64(rx_priv->rxtimeend.tv64 - rx_priv->rxtimebegin.tv64, NSEC_PER_USEC);
+#else
+	timeus = ktime_to_us(rx_priv->rxtimeend - rx_priv->rxtimebegin);
+#endif
+
+	if (timeus >= USEC_PER_SEC) {
+		// calc & send uevent
+		if (div_u64(rx_priv->rx_data_len, timeus) >= 6)
+			kobject_uevent_env(&rwnx_dev->kobj, KOBJ_CHANGE, envp);
+
+		rx_priv->rx_data_len = 0;
+		rx_priv->rxtimebegin = rx_priv->rxtimeend;
+	}
+}
 
 int aicwf_process_rxframes(struct aicwf_rx_priv *rx_priv)
 {
@@ -224,43 +269,48 @@
 				else
 					adjust_len = aggr_len;
 
-		skb_inblock = __dev_alloc_skb(aggr_len + CCMP_OR_WEP_INFO, GFP_KERNEL);
-		if (skb_inblock == NULL) {
-			txrx_err("no more space! skip\n");
-			skb_pull(skb, adjust_len);
-			continue;
+				skb_inblock = __dev_alloc_skb(aggr_len + CCMP_OR_WEP_INFO, GFP_KERNEL);
+				if (skb_inblock == NULL) {
+					txrx_err("no more space! skip\n");
+					skb_pull(skb, adjust_len);
+					continue;
+				}
+
+				skb_put(skb_inblock, aggr_len);
+				memcpy(skb_inblock->data, data, aggr_len);
+				aicwf_count_rx_tp(rx_priv, aggr_len);
+				rwnx_rxdataind_aicwf(rx_priv->sdiodev->rwnx_hw, skb_inblock, (void *)rx_priv);
+				skb_pull(skb, adjust_len);
+			} else {
+				//  type : config
+				aggr_len = pkt_len;
+
+				if (aggr_len & (RX_ALIGNMENT - 1))
+					adjust_len = roundup(aggr_len, RX_ALIGNMENT);
+				else
+					adjust_len = aggr_len;
+
+				msg = kmalloc(aggr_len+4, GFP_KERNEL);
+				if (msg == NULL) {
+					txrx_err("no more space for msg!\n");
+					aicwf_dev_skb_free(skb);
+					return -EBADE;
+				}
+
+				memcpy(msg, data, aggr_len + 4);
+				if ((*(msg + 2) & 0x7f) == SDIO_TYPE_CFG_CMD_RSP)
+					rwnx_rx_handle_msg(rx_priv->sdiodev->rwnx_hw, (struct ipc_e2a_msg *)(msg + 4));
+
+				if ((*(msg + 2) & 0x7f) == SDIO_TYPE_CFG_DATA_CFM)
+					aicwf_sdio_host_tx_cfm_handler(&(rx_priv->sdiodev->rwnx_hw->sdio_env), (u32 *)(msg + 4));
+
+				if ((*(msg + 2) & 0x7f) == SDIO_TYPE_CFG_PRINT)
+					rwnx_rx_handle_print(rx_priv->sdiodev->rwnx_hw, msg + 4, aggr_len);
+
+				skb_pull(skb, adjust_len+4);
+				kfree(msg);
+			}
 		}
-
-		skb_put(skb_inblock, aggr_len);
-		memcpy(skb_inblock->data, data, aggr_len);
-		rwnx_rxdataind_aicwf(rx_priv->sdiodev->rwnx_hw, skb_inblock, (void *)rx_priv);
-		skb_pull(skb, adjust_len);
-		} else {
-		//  type : config
-		aggr_len = pkt_len;
-
-		if (aggr_len & (RX_ALIGNMENT - 1))
-			adjust_len = roundup(aggr_len, RX_ALIGNMENT);
-		else
-			adjust_len = aggr_len;
-
-		msg = kmalloc(aggr_len+4, GFP_KERNEL);
-		if (msg == NULL) {
-			txrx_err("no more space for msg!\n");
-			aicwf_dev_skb_free(skb);
-			return -EBADE;
-		}
-
-		memcpy(msg, data, aggr_len + 4);
-		if ((*(msg + 2) & 0x7f) == SDIO_TYPE_CFG_CMD_RSP)
-			rwnx_rx_handle_msg(rx_priv->sdiodev->rwnx_hw, (struct ipc_e2a_msg *)(msg + 4));
-
-		if ((*(msg + 2) & 0x7f) == SDIO_TYPE_CFG_DATA_CFM)
-			aicwf_sdio_host_tx_cfm_handler(&(rx_priv->sdiodev->rwnx_hw->sdio_env), (u32 *)(msg + 4));
-		skb_pull(skb, adjust_len+4);
-		kfree(msg);
-		}
-	}
 
 		dev_kfree_skb(skb);
 		atomic_dec(&rx_priv->rx_cnt);
@@ -308,15 +358,16 @@
 			else
 				adjust_len = aggr_len;
 
-		skb_inblock = __dev_alloc_skb(aggr_len + CCMP_OR_WEP_INFO, GFP_KERNEL);//8 is for ccmp mic or wep icv
-		if (skb_inblock == NULL) {
-			txrx_err("no more space! skip!\n");
-			skb_pull(skb, adjust_len);
-			continue;
-		}
+			skb_inblock = __dev_alloc_skb(aggr_len + CCMP_OR_WEP_INFO, GFP_KERNEL);//8 is for ccmp mic or wep icv
+			if (skb_inblock == NULL) {
+				txrx_err("no more space! skip!\n");
+				skb_pull(skb, adjust_len);
+				continue;
+			}
 
 			skb_put(skb_inblock, aggr_len);
 			memcpy(skb_inblock->data, data, aggr_len);
+			aicwf_count_rx_tp(rx_priv, aggr_len);
 			rwnx_rxdataind_aicwf(rx_priv->usbdev->rwnx_hw, skb_inblock, (void *)rx_priv);
 			///TODO: here need to add rx data process
 
@@ -421,7 +472,6 @@
 	struct reord_ctrl_info *reord_info, *tmp;
 
 	txrx_dbg("%s\n", __func__);
-
 	spin_lock_bh(&rx_priv->stas_reord_lock);
 	list_for_each_entry_safe(reord_info, tmp,
 		&rx_priv->stas_reord_list, list) {
@@ -430,17 +480,17 @@
 	spin_unlock_bh(&rx_priv->stas_reord_lock);
 #endif
 
-	txrx_dbg("stio rx thread\n");
 #ifdef AICWF_SDIO_SUPPORT
+	txrx_dbg("sdio rx thread\n");
 	if (rx_priv->sdiodev->bus_if->busrx_thread) {
-		complete(&rx_priv->sdiodev->bus_if->busrx_trgg);
+		complete_all(&rx_priv->sdiodev->bus_if->busrx_trgg);
 		kthread_stop(rx_priv->sdiodev->bus_if->busrx_thread);
 		rx_priv->sdiodev->bus_if->busrx_thread = NULL;
 	}
 #endif
 #ifdef AICWF_USB_SUPPORT
 	if (rx_priv->usbdev->bus_if->busrx_thread) {
-		complete(&rx_priv->usbdev->bus_if->busrx_trgg);
+		complete_all(&rx_priv->usbdev->bus_if->busrx_trgg);
 		kthread_stop(rx_priv->usbdev->bus_if->busrx_thread);
 		rx_priv->usbdev->bus_if->busrx_thread = NULL;
 	}
@@ -569,48 +619,13 @@
 	return p;
 }
 
-static struct sk_buff *aicwf_skb_dequeue_tail(struct frame_queue *pq, int prio)
-{
-	struct sk_buff_head *q = &pq->queuelist[prio];
-	struct sk_buff *p = skb_dequeue_tail(q);
-
-	if (!p)
-		return NULL;
-
-	pq->qcnt--;
-	return p;
-}
-
 bool aicwf_frame_enq(struct device *dev, struct frame_queue *q, struct sk_buff *pkt, int prio)
 {
-	struct sk_buff *p = NULL;
-	int prio_modified = -1;
-
 	if (q->queuelist[prio].qlen < q->qmax && q->qcnt < q->qmax) {
 		aicwf_frame_queue_penq(q, prio, pkt);
 		return true;
-	}
-	if (q->queuelist[prio].qlen >= q->qmax) {
-		prio_modified = prio;
-	} else if (q->qcnt >= q->qmax) {
-		p = aicwf_frame_queue_peek_tail(q, &prio_modified);
-		if (prio_modified > prio)
-			return false;
-	}
-
-	if (prio_modified >= 0) {
-		if (prio_modified == prio)
-			return false;
-
-		p = aicwf_skb_dequeue_tail(q, prio_modified);
-		aicwf_dev_skb_free(p);
-
-		p = aicwf_frame_queue_penq(q, prio_modified, pkt);
-		if (p == NULL)
-			txrx_err("failed\n");
-	}
-
-	return p != NULL;
+	} else
+		return false;
 }
 
 

--
Gitblit v1.6.2