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/rwnx_msg_rx.c |  171 +++++++++++++++++++++++++++++++++++++++++---------------
 1 files changed, 124 insertions(+), 47 deletions(-)

diff --git a/longan/kernel/linux-4.9/drivers/net/wireless/aic8800/aic8800_fdrv/rwnx_msg_rx.c b/longan/kernel/linux-4.9/drivers/net/wireless/aic8800/aic8800_fdrv/rwnx_msg_rx.c
old mode 100644
new mode 100755
index f1a6ae8..58857db
--- a/longan/kernel/linux-4.9/drivers/net/wireless/aic8800/aic8800_fdrv/rwnx_msg_rx.c
+++ b/longan/kernel/linux-4.9/drivers/net/wireless/aic8800/aic8800_fdrv/rwnx_msg_rx.c
@@ -23,6 +23,7 @@
 #include "rwnx_events.h"
 #include "rwnx_compat.h"
 #include "aicwf_txrxif.h"
+#include "rwnx_msg_rx.h"
 
 static int rwnx_freq_to_idx(struct rwnx_hw *rwnx_hw, int freq)
 {
@@ -61,16 +62,13 @@
 	struct rwnx_vif *rwnx_vif;
 	int chan_idx = ((struct mm_channel_pre_switch_ind *)msg->param)->chan_index;
 
-	RWNX_DBG(RWNX_FN_ENTRY_STR);
-
 	REG_SW_SET_PROFILING_CHAN(rwnx_hw, SW_PROF_CHAN_CTXT_PSWTCH_BIT);
 
 #ifdef CONFIG_RWNX_FULLMAC
 	list_for_each_entry(rwnx_vif, &rwnx_hw->vifs, list) {
-	if (rwnx_vif->up && rwnx_vif->ch_index == chan_idx) {
-		printk("rwnx_txq_vif_stop\r\n");
-		rwnx_txq_vif_stop(rwnx_vif, RWNX_TXQ_STOP_CHAN, rwnx_hw);
-	}
+		if (rwnx_vif->up && rwnx_vif->ch_index == chan_idx) {
+			rwnx_txq_vif_stop(rwnx_vif, RWNX_TXQ_STOP_CHAN, rwnx_hw);
+		}
 	}
 #endif /* CONFIG_RWNX_FULLMAC */
 
@@ -88,8 +86,6 @@
 	bool roc     = ((struct mm_channel_switch_ind *)msg->param)->roc;
 	bool roc_tdls = ((struct mm_channel_switch_ind *)msg->param)->roc_tdls;
 
-	RWNX_DBG(RWNX_FN_ENTRY_STR);
-
 	REG_SW_SET_PROFILING_CHAN(rwnx_hw, SW_PROF_CHAN_CTXT_SWTCH_BIT);
 
 #ifdef CONFIG_RWNX_FULLMAC
@@ -97,16 +93,16 @@
 		u8 vif_index = ((struct mm_channel_switch_ind *)msg->param)->vif_index;
 		list_for_each_entry(rwnx_vif, &rwnx_hw->vifs, list) {
 			if (rwnx_vif->vif_index == vif_index) {
-			rwnx_vif->roc_tdls = true;
-			rwnx_txq_tdls_sta_start(rwnx_vif, RWNX_TXQ_STOP_CHAN, rwnx_hw);
+				rwnx_vif->roc_tdls = true;
+				rwnx_txq_tdls_sta_start(rwnx_vif, RWNX_TXQ_STOP_CHAN, rwnx_hw);
 			}
-	}
-	} else if (!roc) {
-	list_for_each_entry(rwnx_vif, &rwnx_hw->vifs, list) {
-		if (rwnx_vif->up && rwnx_vif->ch_index == chan_idx) {
-		rwnx_txq_vif_start(rwnx_vif, RWNX_TXQ_STOP_CHAN, rwnx_hw);
 		}
-	}
+	} else if (!roc) {
+		list_for_each_entry(rwnx_vif, &rwnx_hw->vifs, list) {
+			if (rwnx_vif->up && rwnx_vif->ch_index == chan_idx) {
+				rwnx_txq_vif_start(rwnx_vif, RWNX_TXQ_STOP_CHAN, rwnx_hw);
+			}
+		}
 	} else {
 		/* Retrieve the allocated RoC element */
 		struct rwnx_roc_elem *roc_elem = rwnx_hw->roc_elem;
@@ -116,16 +112,19 @@
 		/* For debug purpose (use ftrace kernel option) */
 		//trace_switch_roc(rwnx_vif->vif_index);
 
-		/* If mgmt_roc is true, remain on channel has been started by ourself */
-		if (!roc_elem->mgmt_roc) {
-			/* Inform the host that we have switch on the indicated off-channel */
-			cfg80211_ready_on_channel(roc_elem->wdev, (u64)(rwnx_hw->roc_cookie_cnt),
+		if (roc_elem) {
+			/* If mgmt_roc is true, remain on channel has been started by ourself */
+			if (!roc_elem->mgmt_roc) {
+				/* Inform the host that we have switch on the indicated off-channel */
+				cfg80211_ready_on_channel(roc_elem->wdev, (u64)(rwnx_hw->roc_cookie_cnt),
 									  roc_elem->chan, roc_elem->duration, GFP_ATOMIC);
+			}
+
+			/* Keep in mind that we have switched on the channel */
+			roc_elem->on_chan = true;
+		} else {
+			printk("roc_elem == null\n");
 		}
-
-		/* Keep in mind that we have switched on the channel */
-		roc_elem->on_chan = true;
-
 		// Enable traffic on OFF channel queue
 		rwnx_txq_offchan_start(rwnx_hw);
 	}
@@ -210,13 +209,18 @@
 	/* Retrieve the allocated RoC element */
 	struct rwnx_roc_elem *roc_elem = rwnx_hw->roc_elem;
 	/* Get VIF on which RoC has been started */
-	struct rwnx_vif *rwnx_vif = container_of(roc_elem->wdev, struct rwnx_vif, wdev);
+	struct rwnx_vif *rwnx_vif;
 
 	RWNX_DBG(RWNX_FN_ENTRY_STR);
 
-	/* For debug purpose (use ftrace kernel option) */
-	trace_roc_exp(rwnx_vif->vif_index);
+	if (!roc_elem)
+		return 0;
 
+	rwnx_vif = container_of(roc_elem->wdev, struct rwnx_vif, wdev);
+	/* For debug purpose (use ftrace kernel option) */
+#ifdef CREATE_TRACE_POINTS
+	trace_roc_exp(rwnx_vif->vif_index);
+#endif
 	/* If mgmt_roc is true, remain on channel has been started by ourself */
 	/* If RoC has been cancelled before we switched on channel, do not call cfg80211 */
 	if (!roc_elem->mgmt_roc && roc_elem->on_chan) {
@@ -251,7 +255,7 @@
 	int ps_state = ((struct mm_p2p_vif_ps_change_ind *)msg->param)->ps_state;
 	struct rwnx_vif *vif_entry;
 
-	RWNX_DBG(RWNX_FN_ENTRY_STR);
+	//RWNX_DBG(RWNX_FN_ENTRY_STR);
 
 #ifdef CONFIG_RWNX_FULLMAC
 	vif_entry = rwnx_hw->vif_table[vif_idx];
@@ -269,6 +273,7 @@
 	if (ps_state == MM_PS_MODE_OFF) {
 		// Start TX queues for provided VIF
 		rwnx_txq_vif_start(vif_entry, RWNX_TXQ_STOP_VIF_PS, rwnx_hw);
+		tasklet_schedule(&rwnx_hw->task);
 	} else {
 		// Stop TX queues for provided VIF
 		rwnx_txq_vif_stop(vif_entry, RWNX_TXQ_STOP_VIF_PS, rwnx_hw);
@@ -288,8 +293,6 @@
 	int idx = rwnx_freq_to_idx(rwnx_hw, ind->freq);
 	// Get the survey
 	struct rwnx_survey_info *rwnx_survey;
-
-	RWNX_DBG(RWNX_FN_ENTRY_STR);
 
 	if (idx >  ARRAY_SIZE(rwnx_hw->survey))
 		return 0;
@@ -359,6 +362,22 @@
 									ind->num_packets, GFP_ATOMIC);
 	}
 #endif /* CONFIG_RWNX_FULLMAC */
+
+	return 0;
+}
+
+static inline int rwnx_apm_staloss_ind(struct rwnx_hw *rwnx_hw,
+										struct rwnx_cmd *cmd,
+										struct ipc_e2a_msg *msg)
+{
+	struct mm_apm_staloss_ind *ind = (struct mm_apm_staloss_ind *)msg->param;
+
+	RWNX_DBG(RWNX_FN_ENTRY_STR);
+
+	memcpy(rwnx_hw->sta_mac_addr, ind->mac_addr, 6);
+	rwnx_hw->apm_vif_idx = ind->vif_idx;
+
+	queue_work(rwnx_hw->apmStaloss_wq, &rwnx_hw->apmStalossWork);
 
 	return 0;
 }
@@ -473,8 +492,6 @@
 	struct mm_ps_change_ind *ind = (struct mm_ps_change_ind *)msg->param;
 	struct rwnx_sta *sta = &rwnx_hw->sta_table[ind->sta_idx];
 
-	RWNX_DBG(RWNX_FN_ENTRY_STR);
-
 	if (ind->sta_idx >= (NX_REMOTE_STA_MAX + NX_VIRT_DEV_MAX)) {
 		wiphy_err(rwnx_hw->wiphy, "Invalid sta index reported by fw %d\n",
 				  ind->sta_idx);
@@ -490,7 +507,8 @@
 	} else if (rwnx_hw->adding_sta) {
 		sta->ps.active = ind->ps_state ? true : false;
 	} else {
-		netdev_err(rwnx_hw->vif_table[sta->vif_idx]->ndev,
+		if (rwnx_hw->vif_table[sta->vif_idx]->ndev)
+			netdev_err(rwnx_hw->vif_table[sta->vif_idx]->ndev,
 				   "Ignore PS mode change on invalid sta\n");
 	}
 
@@ -555,8 +573,6 @@
 {
 	RWNX_DBG(RWNX_FN_ENTRY_STR);
 
-	scanning = 0;
-	//rwnx_ipc_elem_var_deallocs(rwnx_hw, &rwnx_hw->scan_ie);
 	if (rwnx_hw->scan_request) {
 #if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 8, 0)
 		struct cfg80211_scan_info info = {
@@ -570,6 +586,7 @@
 	}
 
 	rwnx_hw->scan_request = NULL;
+	scanning = 0;
 
 	return 0;
 }
@@ -587,7 +604,6 @@
 	size_t ielen;
 	u16 capability, beacon_interval;
 	u16 len = ind->length;
-	RWNX_DBG(RWNX_FN_ENTRY_STR);
 
 	chan = ieee80211_get_channel(rwnx_hw->wiphy, ind->center_freq);
 
@@ -597,9 +613,14 @@
 		ts = ktime_to_timespec(ktime_get_boottime());
 		tsf = (u64)ts.tv_sec * 1000000 + div_u64(ts.tv_nsec, 1000);
 		mgmt->u.probe_resp.timestamp = ((u64)ts.tv.sec*1000000) + ts.tv.nsec/1000;
-#else
+#elif LINUX_VERSION_CODE < KERNEL_VERSION(5, 6, 0)
 		struct timespec ts;
 		ts = ktime_to_timespec(ktime_get_boottime());
+		tsf = (u64)ts.tv_sec * 1000000 + div_u64(ts.tv_nsec, 1000);
+		mgmt->u.probe_resp.timestamp = tsf;
+#else
+		struct timespec64 ts;
+		ts = ktime_to_timespec64(ktime_get_boottime());
 		tsf = (u64)ts.tv_sec * 1000000 + div_u64(ts.tv_nsec, 1000);
 		mgmt->u.probe_resp.timestamp = tsf;
 #endif
@@ -613,7 +634,7 @@
 				CFG80211_BSS_FTYPE_UNKNOWN,
 #endif
 				mgmt->bssid, tsf, capability, beacon_interval,
-				ie, ielen, ind->rssi * 100, GFP_KERNEL);
+				ie, ielen, ind->rssi * 100, GFP_ATOMIC);
 	}
 
 	if (bss != NULL)
@@ -719,9 +740,9 @@
 		memcpy(sta->ac_param, ind->ac_param, sizeof(sta->ac_param));
 		rwnx_txq_sta_init(rwnx_hw, sta, txq_status);
 		rwnx_txq_tdls_vif_init(rwnx_vif);
-		#if 0
+#ifdef CONFIG_DEBUG_FS
 		rwnx_dbgfs_register_rc_stat(rwnx_hw, sta);
-		#endif
+#endif
 		rwnx_mu_group_sta_init(sta, NULL);
 		/* Look for TDLS Channel Switch Prohibited flag in the Extended Capability
 		 * Information Element*/
@@ -730,6 +751,9 @@
 			extcap = (void *)(extcap_ie);
 			rwnx_vif->tdls_chsw_prohibited = extcap->ext_capab[4] & WLAN_EXT_CAPA5_TDLS_CH_SW_PROHIBITED;
 		}
+
+		if (rwnx_vif->wep_enabled)
+			rwnx_vif->wep_auth_err = false;
 
 #ifdef CONFIG_RWNX_BFMER
 		/* If Beamformer feature is activated, check if features can be used
@@ -819,7 +843,7 @@
 {
 	struct sm_disconnect_ind *ind = (struct sm_disconnect_ind *)msg->param;
 	struct rwnx_vif *rwnx_vif = rwnx_hw->vif_table[ind->vif_idx];
-	struct net_device *dev = rwnx_vif->ndev;
+	struct net_device *dev;
 #ifdef AICWF_RX_REORDER
 	struct reord_ctrl_info *reord_info, *tmp;
 	u8 *macaddr;
@@ -828,6 +852,10 @@
 
 	RWNX_DBG(RWNX_FN_ENTRY_STR);
 	dhcped = 0;
+
+	if (!rwnx_vif)
+		return 0;
+	dev = rwnx_vif->ndev;
 
 	if (rwnx_vif->wdev.iftype == NL80211_IFTYPE_P2P_CLIENT)
 		rwnx_hw->is_p2p_connected = 0;
@@ -856,7 +884,6 @@
 		macaddr = rwnx_vif->ndev->dev_addr;
 		printk("deinit:macaddr:%x,%x,%x,%x,%x,%x\r\n", macaddr[0], macaddr[1], macaddr[2], \
 							   macaddr[3], macaddr[4], macaddr[5]);
-
 		spin_lock_bh(&rx_priv->stas_reord_lock);
 		list_for_each_entry_safe(reord_info, tmp, &rx_priv->stas_reord_list, list) {
 			macaddr = rwnx_vif->ndev->dev_addr;
@@ -893,7 +920,7 @@
 	struct sm_external_auth_required_ind *ind =
 		(struct sm_external_auth_required_ind *)msg->param;
 	struct rwnx_vif *rwnx_vif = rwnx_hw->vif_table[ind->vif_idx];
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 17, 0)
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 17, 0) || defined(CONFIG_WPA3_FOR_OLD_KERNEL)
 	struct net_device *dev = rwnx_vif->ndev;
 	struct cfg80211_external_auth_params params;
 
@@ -989,8 +1016,9 @@
 				}
 
 				rwnx_txq_sta_init(rwnx_hw, rwnx_sta, txq_status);
+#ifdef CONFIG_DEBUG_FS
 				rwnx_dbgfs_register_rc_stat(rwnx_hw, rwnx_sta);
-
+#endif
 #ifdef CONFIG_RWNX_BFMER
 				// TODO: update indication to contains vht capabilties
 				if (rwnx_hw->mod_params->bfmer)
@@ -1011,7 +1039,9 @@
 				list_del_init(&rwnx_sta->list);
 
 				rwnx_txq_sta_deinit(rwnx_hw, rwnx_sta);
+#ifdef CONFIG_DEBUG_FS
 				rwnx_dbgfs_unregister_rc_stat(rwnx_hw, rwnx_sta);
+#endif
 			} else {
 				WARN_ON(0);
 			}
@@ -1027,7 +1057,9 @@
 			list_del_init(&rwnx_sta->list);
 
 			rwnx_txq_sta_deinit(rwnx_hw, rwnx_sta);
+#ifdef CONFIG_DEBUG_FS
 			rwnx_dbgfs_unregister_rc_stat(rwnx_hw, rwnx_sta);
+#endif
 		} else {
 			WARN_ON(0);
 		}
@@ -1064,7 +1096,9 @@
 	/* Check if element has been deleted */
 	if (ind->delete) {
 		if (found) {
+#ifdef CREATE_TRACE_POINTS
 			trace_mesh_delete_path(mesh_path);
+#endif
 			/* Remove element from list */
 			list_del_init(&mesh_path->list);
 			/* Free the element */
@@ -1074,7 +1108,9 @@
 		if (found) {
 			// Update the Next Hop STA
 			mesh_path->p_nhop_sta = &rwnx_hw->sta_table[ind->nhop_sta_idx];
+#ifdef CREATE_TRACE_POINTS
 			trace_mesh_update_path(mesh_path);
+#endif
 		} else {
 			// Allocate a Mesh Path structure
 			mesh_path = (struct rwnx_mesh_path *)kmalloc(sizeof(struct rwnx_mesh_path), GFP_ATOMIC);
@@ -1088,8 +1124,9 @@
 
 				// Insert the path in the list of path
 				list_add_tail(&mesh_path->list, &rwnx_vif->ap.mpath_list);
-
+#ifdef CREATE_TRACE_POINTS
 				trace_mesh_create_path(mesh_path);
+#endif
 			}
 		}
 	}
@@ -1164,8 +1201,6 @@
 {
 	RWNX_DBG(RWNX_FN_ENTRY_STR);
 
-	rwnx_error_ind(rwnx_hw);
-
 	return 0;
 }
 
@@ -1185,6 +1220,7 @@
 	[MSG_I(MM_P2P_NOA_UPD_IND)]        = rwnx_rx_p2p_noa_upd_ind,
 	[MSG_I(MM_RSSI_STATUS_IND)]        = rwnx_rx_rssi_status_ind,
 	[MSG_I(MM_PKTLOSS_IND)]            = rwnx_rx_pktloss_notify_ind,
+	[MSG_I(MM_APM_STALOSS_IND)]        = rwnx_apm_staloss_ind,
 };
 
 static msg_cb_fct scan_hdlrs[MSG_I(SCANU_MAX)] = {
@@ -1247,3 +1283,44 @@
 	rwnx_hw->cmd_mgr->msgind(rwnx_hw->cmd_mgr, msg,
 							msg_hdlrs[MSG_T(msg->id)][MSG_I(msg->id)]);
 }
+
+void rwnx_rx_handle_print(struct rwnx_hw *rwnx_hw, u8 *msg, u32 len)
+{
+	u8 *data_end = NULL;
+	(void)data_end;
+
+	if (!rwnx_hw || !rwnx_hw->fwlog_en) {
+		pr_err("FWLOG-OVFL: %s", msg);
+		return;
+	}
+
+	printk("FWLOG: %s", msg);
+
+#ifdef CONFIG_RWNX_DEBUGFS
+	data_end = rwnx_hw->debugfs.fw_log.buf.dataend;
+
+	if (!rwnx_hw->debugfs.fw_log.buf.data)
+		return ;
+
+	//printk("end=%lx, len=%d\n", (unsigned long)rwnx_hw->debugfs.fw_log.buf.end, len);
+
+	spin_lock_bh(&rwnx_hw->debugfs.fw_log.lock);
+
+	if (rwnx_hw->debugfs.fw_log.buf.end + len > data_end) {
+		int rem = data_end - rwnx_hw->debugfs.fw_log.buf.end;
+		memcpy(rwnx_hw->debugfs.fw_log.buf.end, msg, rem);
+		memcpy(rwnx_hw->debugfs.fw_log.buf.data, &msg[rem], len - rem);
+		rwnx_hw->debugfs.fw_log.buf.end = rwnx_hw->debugfs.fw_log.buf.data + (len - rem);
+	} else {
+		memcpy(rwnx_hw->debugfs.fw_log.buf.end, msg, len);
+		rwnx_hw->debugfs.fw_log.buf.end += len;
+	}
+
+	rwnx_hw->debugfs.fw_log.buf.size += len;
+	if (rwnx_hw->debugfs.fw_log.buf.size > FW_LOG_SIZE)
+		rwnx_hw->debugfs.fw_log.buf.size = FW_LOG_SIZE;
+
+	spin_unlock_bh(&rwnx_hw->debugfs.fw_log.lock);
+#endif
+}
+

--
Gitblit v1.6.2