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