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