• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright: Copyright (c) 2020 HiSilicon (Shanghai) Technologies CO., LIMITED.
3  * Licensed under the Apache License, Version 2.0 (the "License");
4  * you may not use this file except in compliance with the License.
5  * You may obtain a copy of the License at
6  *
7  *     http://www.apache.org/licenses/LICENSE-2.0
8  *
9  * Unless required by applicable law or agreed to in writing, software
10  * distributed under the License is distributed on an "AS IS" BASIS,
11  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12  * See the License for the specific language governing permissions and
13  * limitations under the License.
14  * Description: bt业务场景变化处理
15  * Date: 2023-01-16 15:01
16  */
17 
18 #ifndef __HMAC_BTCOEX_BTSTA_C__
19 #define __HMAC_BTCOEX_BTSTA_C__
20 
21 #include "frw_ext_if.h"
22 #include "oam_ext_if.h"
23 #include "hmac_btcoex.h"
24 #include "hmac_btcoex_ba.h"
25 #include "hmac_btcoex_m2s.h"
26 #include "hmac_btcoex_ps.h"
27 #include "hmac_alg_notify.h"
28 #include "hmac_feature_interface.h"
29 #include "hmac_btcoex_btsta.h"
30 
31 #ifdef __cplusplus
32 #if __cplusplus
33     extern "C" {
34 #endif
35 #endif
36 #undef THIS_FILE_ID
37 #define THIS_FILE_ID DIAG_FILE_ID_WIFI_HOST_HMAC_BTCOEX_BTSTA_C
38 
39 #undef THIS_MOD_ID
40 #define THIS_MOD_ID DIAG_MOD_ID_WIFI_HOST
41 
42 #ifdef _PRE_WLAN_FEATURE_BT_SUPPORT
43 #ifdef _PRE_WLAN_FEATURE_M2S
44 /*****************************************************************************
45  函 数 名  : hmac_btcoex_double_chain_timeout_callback()
46  功能描述  : 电话双链路下业务结束延迟处理定时器超时处理函数
47 *****************************************************************************/
hmac_btcoex_double_chain_timeout_callback(osal_void * arg)48 OSAL_STATIC osal_u32 hmac_btcoex_double_chain_timeout_callback(osal_void *arg)
49 {
50     hal_btcoex_btble_status_stru *btcoex_btble_status = OSAL_NULL;
51     hal_to_dmac_chip_stru *hal_chip = OSAL_NULL;
52     hmac_vap_stru *hmac_vap = OSAL_NULL;
53     hmac_user_stru *hmac_user = OSAL_NULL;
54     hmac_user_btcoex_delba_stru *btcoex_delba = OSAL_NULL;
55 
56     if (arg == OSAL_NULL) {
57         oam_warning_log0(0, 0, "{hmac_btcoex_double_chain_timeout_callback:: arg null}");
58         return OAL_ERR_CODE_PTR_NULL;
59     }
60 
61     hmac_vap = (hmac_vap_stru *)arg;
62     hal_chip = hmac_vap->hal_chip;
63     if (hal_chip == OSAL_NULL) {
64         oam_warning_log1(0, OAM_SF_COEX,
65             "vap_id[%d] {hmac_btcoex_double_chain_timeout_callback:: hal_chip null}", hmac_vap->vap_id);
66         return OAL_ERR_CODE_PTR_NULL;
67     }
68 
69     hmac_user = (hmac_user_stru *)mac_res_get_hmac_user_etc(hmac_vap->assoc_vap_id);
70     if (osal_unlikely(hmac_user == OSAL_NULL)) {
71         oam_warning_log2(0, 0, "vap_id[%d] {hmac_btcoex_double_chain_timeout_callback::hmac_user[%d] null.}",
72             hmac_vap->vap_id, hmac_vap->assoc_vap_id);
73         return OAL_ERR_CODE_PTR_NULL;
74     }
75 
76     btcoex_btble_status = hal_btcoex_btble_status();
77     btcoex_delba = &(hmac_btcoex_get_user_info(hmac_user)->hmac_user_btcoex_delba);
78 
79     /* 更新标记刷新 */
80     hmac_btcoex_get_vap_info(hmac_vap)->bitmap_update_flag = OSAL_FALSE;
81 
82     /* 3s之后蓝牙电话结束 */
83     if (btcoex_btble_status->bt_status.bt_status.bt_6slot == OSAL_FALSE) {
84         /* 双链路电话结束,恢复聚合64 */
85         btcoex_delba->ba_size_real_index = BTCOEX_RX_WINDOW_SIZE_INDEX_3;
86         btcoex_delba->ba_size_expect_index = BTCOEX_RX_WINDOW_SIZE_INDEX_3;
87         hmac_btcoex_update_ba_size(hmac_vap, btcoex_delba, btcoex_btble_status);
88         hmac_btcoex_delba_trigger(hmac_vap, OSAL_TRUE, btcoex_delba);
89     } else {
90         oam_warning_log3(0, OAM_SF_COEX,
91             "vap_id[%d] {hmac_btcoex_sco_rx_rate_statistics_flag_callback:: 6s change[%d] to [%d].}", hmac_vap->vap_id,
92             hmac_vap_get_vap_btcoex_mgr_6slot(hmac_vap), btcoex_btble_status->bt_status.bt_status.bt_6slot);
93 
94         /* 要判断是否出现了双链接切换,从6slot切换到12slot的话,不删聚合,12slot切到6slot需要删聚合到1 */
95         if (hmac_vap_get_vap_btcoex_mgr_6slot(hmac_vap) != btcoex_btble_status->bt_status.bt_status.bt_6slot) {
96             /* 1.如果出现12slot切换到6slot,需要继续删聚合到1(这里记录第一次的电话状态) */
97             if ((hmac_vap_get_vap_btcoex_mgr_6slot(hmac_vap) == 1) &&
98                 (hmac_btcoex_get_vap_info(hmac_vap)->delba_on_6slot == OSAL_FALSE)) {
99                 /* 如果没有切换过6slot,才删聚合到1,已经聚合到了1,就一直保持1,直到删64恢复 */
100                     btcoex_delba->ba_size = 1;
101                     hmac_btcoex_delba_trigger(hmac_vap, OSAL_TRUE, btcoex_delba);
102             }
103         }
104 
105         /* 完成之后,需要做一次赋值更新 */
106         hmac_btcoex_get_vap_info(hmac_vap)->bitmap_6slot = btcoex_btble_status->bt_status.bt_status.bt_6slot;
107     }
108     return OAL_SUCC;
109 }
110 
hmac_btcoex_sco_status_delba_prepare(hal_to_dmac_device_stru * hal_device,const bt_status_stru * bt_status)111 OSAL_STATIC osal_u32 hmac_btcoex_sco_status_delba_prepare(hal_to_dmac_device_stru *hal_device,
112     const bt_status_stru *bt_status)
113 {
114     /* c1 siso不需要执行 */
115     if (hal_device->hal_m2s_fsm.oal_fsm.cur_state == HAL_M2S_STATE_SISO &&
116         hal_device->cfg_cap_info->phy_chain == WLAN_PHY_CHAIN_ONE) {
117         return OAL_SUCC;
118     }
119 
120     /* ac86u上行电话位置敏感概率掉坑,需要调整聚合时间 */
121     if (bt_status->bt_6slot == 1) {
122         /* mimo和siso场景有区分 */
123         if (hal_device->hal_m2s_fsm.oal_fsm.cur_state == HAL_M2S_STATE_MIMO ||
124             hal_device->hal_m2s_fsm.oal_fsm.cur_state == HAL_M2S_STATE_SIMO) {
125             hmac_alg_cfg_btcoex_state_notify(hal_device, HMAC_ALG_BT_AGGR_TIME_4MS);
126         } else {
127             hmac_alg_cfg_btcoex_state_notify(hal_device, HMAC_ALG_BT_AGGR_TIME_2MS);
128         }
129     } else if (bt_status->bt_6slot == 2) { /* 六时隙时是否为2 */
130         /* 6slot场景下,mimo和siso都需要此档位 */
131         hmac_alg_cfg_btcoex_state_notify(hal_device, HMAC_ALG_BT_AGGR_TIME_1MS);
132     } else {
133         hmac_alg_cfg_btcoex_state_notify(hal_device, HMAC_ALG_BT_AGGR_TIME_OFF);
134     }
135 
136     return OAL_CONTINUE;
137 }
138 #endif
139 
140 /*****************************************************************************
141  函 数 名  : hmac_btcoex_ldac_status_ps_process
142  功能描述  : ldac场景处理方式(1)m2s切换 (2)ps+关闭动态调频
143 *****************************************************************************/
hmac_btcoex_ldac_status_ps_process(hal_to_dmac_device_stru * hal_device,const bt_status_stru * bt_status)144 OSAL_STATIC osal_void hmac_btcoex_ldac_status_ps_process(hal_to_dmac_device_stru *hal_device,
145     const bt_status_stru *bt_status)
146 {
147     osal_void *fhook = hmac_get_feature_fhook(HMAC_FHOOK_AUTO_FREQ_BTCOEX);
148 
149     /* c1 siso不需要执行 */
150     if ((hal_device->hal_m2s_fsm.oal_fsm.cur_state == HAL_M2S_STATE_SISO &&
151         hal_device->cfg_cap_info->phy_chain == WLAN_PHY_CHAIN_ONE) ||
152         (bt_status == OSAL_NULL)) {
153         return;
154     }
155 
156     if (fhook != OSAL_NULL) {
157         ((hmac_auto_freq_btcoex_handle_cb)fhook)((osal_u8)bt_status->bt_ldac);
158     }
159 
160     hmac_btcoex_restart_ps_timer(hal_device);
161     // ldac状态变化后,更新ps param
162     hmac_btcoex_set_dev_ps_frame(hal_device);
163 
164     return;
165 }
166 
167 /*****************************************************************************
168  函 数 名  : hmac_btcoex_update_coex_pri
169  功能描述  : 根据ldac更新onepkt优先级
170 *****************************************************************************/
hmac_btcoex_update_coex_pri(hal_to_dmac_device_stru * hal_device)171 OSAL_STATIC osal_void hmac_btcoex_update_coex_pri(hal_to_dmac_device_stru *hal_device)
172 {
173     hal_btcoex_btble_status_stru *btble_status = hal_btcoex_btble_status();
174     /* ldac业务期间,禁止onepkt优先级配置 */
175     if (btble_status->bt_status.bt_status.bt_ldac == OSAL_FALSE) {
176         hal_device->btcoex_sw_preempt.coex_pri_forbit = OSAL_FALSE;
177     } else {
178         if ((btble_status->bt_status.bt_status.bt_a2dp != 0) ||
179             (btble_status->bt_status.bt_status.bt_transfer != 0)) {
180             hal_device->btcoex_sw_preempt.coex_pri_forbit = OSAL_TRUE;
181         }
182     }
183 }
184 
185 /*****************************************************************************
186  函 数 名  : hmac_btcoex_wifi_and_bt_insulate_check
187  功能描述  : 查询bt和wifi是否可以隔离开,并判断是否需要刷新聚合大小,对应btcoex下业务不需要考虑处理
188              (1)dbdc (2)主路dbac  (3)主路单vap  (4)主路多vap同信道  无单独辅路工作
189              (5)当前c0 c1 siso/mimo都需要刷新发送聚合大小,因为放置在这里统一保证有效执行
190              (6)业务assoc也要处理
191 *****************************************************************************/
hmac_btcoex_wifi_and_bt_insulate_check(hal_to_dmac_device_stru * hal_device,const bt_status_stru * bt_status,oal_bool_enum_uint8 aggr_num_check)192 OSAL_STATIC oal_bool_enum_uint8 hmac_btcoex_wifi_and_bt_insulate_check(hal_to_dmac_device_stru *hal_device,
193     const bt_status_stru *bt_status, oal_bool_enum_uint8 aggr_num_check)
194 {
195     hmac_vap_stru *hmac_vap = OSAL_NULL;
196     osal_u8 vap_index;
197     osal_u8 up_vap_num;
198     osal_u8 mac_vap_id[WLAN_SERVICE_VAP_MAX_NUM_PER_DEVICE] = {0};
199     oal_bool_enum_uint8 insulate = OSAL_TRUE;
200 
201     /* 2.主路device上存在一个5g,就等同于多vap同信道或者单vap工作在5g  不需要执行 */
202     /* 找到所有up的vap设备 */
203     up_vap_num = hal_device_find_all_up_vap(hal_device, mac_vap_id, WLAN_SERVICE_VAP_MAX_NUM_PER_DEVICE);
204     for (vap_index = 0; vap_index < up_vap_num; vap_index++) {
205         hmac_vap = (hmac_vap_stru *)mac_res_get_hmac_vap(mac_vap_id[vap_index]);
206         if (hmac_vap == OSAL_NULL) {
207             oam_error_log1(0, OAM_SF_COEX,
208                 "vap_id[%d] hmac_btcoex_wifi_and_bt_insulate_check::hmac_vap IS NULL.", mac_vap_id[vap_index]);
209             continue;
210         }
211 
212         /* 存在2G的设备,单2G  2G dbac或者同信道多vap 2G */
213         if (mac_btcoex_check_valid_vap(hmac_vap) == OSAL_TRUE) {
214             insulate = OSAL_FALSE;
215         }
216     }
217 
218     if (aggr_num_check == OSAL_TRUE) {
219         /* 1.存在2g vap,dbac也算,2.主路只有单5g下,但是dbdc的话也需要处理(辅路默认不单独工作) */
220         if (insulate == OSAL_FALSE) {
221             /* 1.当前6slot/ldac下即使c1
222               siso下也不是空分,降低聚合时间保证上行性能稳定; 2.需要提前配置,dbdc/c1
223               siso也需要处理,因此放置在这里; 3.纯5g场景不需要处理,反而影响性能
224               4. 中断标志过来,本身和6slot是互斥的,不冲突 */
225             if (bt_status->bt_ldac == 1 || bt_status->bt_6slot == 2) { /* WiFi蓝牙共存需要设ldac为1,6slot为2 */
226                 /* ldac场景下,mimo和siso都需要此档位 */
227                 hmac_alg_cfg_btcoex_state_notify(hal_device, HMAC_ALG_BT_AGGR_TIME_1MS);
228             } else {
229                 hmac_alg_cfg_btcoex_state_notify(hal_device, HMAC_ALG_BT_AGGR_TIME_OFF);
230             }
231         }
232     }
233 
234     return insulate;
235 }
236 
237 #ifdef _PRE_WLAN_FEATURE_M2S
238 /*****************************************************************************
239  函 数 名  : hmac_btcoex_sco_status_delba_process
240  功能描述  : BT电话场景处理方式(1)m2s切换 (2)删聚合
241 *****************************************************************************/
hmac_btcoex_sco_status_delba_process(hal_to_dmac_device_stru * hal_device,const hal_btcoex_btble_status_stru * btble_status)242 OSAL_STATIC osal_u32 hmac_btcoex_sco_status_delba_process(hal_to_dmac_device_stru *hal_device,
243     const hal_btcoex_btble_status_stru *btble_status)
244 {
245     const bt_status_stru *bt_status = &(btble_status->bt_status.bt_status);
246     hmac_user_btcoex_delba_stru *btcoex_delba = OSAL_NULL;
247     hmac_user_stru *hmac_user = OSAL_NULL;
248     oal_bool_enum_uint8 need_delba = OSAL_TRUE;
249     osal_u8 vap_idx;
250     osal_u8 valid_vap_num;
251     osal_u8                           mac_vap_id[WLAN_SERVICE_VAP_MAX_NUM_PER_DEVICE] = {0};
252     hmac_vap_stru                       *hmac_vap[WLAN_SERVICE_VAP_MAX_NUM_PER_DEVICE] = {OSAL_NULL};
253 
254     if (hmac_btcoex_sco_status_delba_prepare(hal_device, bt_status) != OAL_CONTINUE) {
255         return OAL_SUCC;
256     }
257 
258     /* 找到满足要求的vap个数 */
259     valid_vap_num = hmac_btcoex_find_all_valid_sta_per_device(hal_device, mac_vap_id,
260         WLAN_SERVICE_VAP_MAX_NUM_PER_DEVICE);
261 
262     /* valid的vap设备都做对应处理, 02只处理legacy sta   03要处理gc sta */
263     for (vap_idx = 0; vap_idx < valid_vap_num; vap_idx++) {
264         hmac_vap[vap_idx] = (hmac_vap_stru *)mac_res_get_hmac_vap(mac_vap_id[vap_idx]);
265         if (hmac_vap[vap_idx] == OSAL_NULL) {
266             oam_error_log1(0, OAM_SF_COEX, "hmac_btcoex_sco_status_handler::hmac_vap[%d] NULL !", mac_vap_id[vap_idx]);
267             return OAL_ERR_CODE_PTR_NULL;
268         }
269 
270         hmac_user = (hmac_user_stru *)mac_res_get_hmac_user_etc((hmac_vap[vap_idx])->assoc_vap_id);
271         if (osal_unlikely(hmac_user == OSAL_NULL)) {
272             return OAL_ERR_CODE_PTR_NULL;
273         }
274 
275         btcoex_delba = &(hmac_btcoex_get_user_info(hmac_user)->hmac_user_btcoex_delba);
276 
277         /* 正常bt打开和关闭场景下,对聚合进行处理,中断上半部能保证不会连续来6slot标志相同的下半部,
278            双链接来了,这里也需要切换聚合个数,下面聚合档位一致,能保证不再删聚合
279            但是12slot切到6slot,需要继续删聚合才能保证基本吞吐
280            电话来时候,就不做速率统计了,立即删聚合,定时器单独用于sco结束做3s的状态保持,不立即恢复聚合,用于双链接 */
281         if (bt_status->bt_6slot != 0) {
282             /* 电话模式需要固定到BTCOEX_RX_WINDOW_SIZE_INDEX_1聚合方式,和当前聚合个数一致不需要删除BA,否则删除BA */
283             /* Tplink5630不识别聚合2个,还是高聚合发送造成电话下容易掉底断流 */
284             btcoex_delba->ba_size_expect_index = BTCOEX_RX_WINDOW_SIZE_INDEX_1;
285 
286             if (btcoex_delba->ba_size_expect_index == btcoex_delba->ba_size_real_index) {
287                 need_delba = OSAL_FALSE;
288             }
289 
290             /* 6slot=0开启统计时,不能更新bitmap */
291             if (hmac_btcoex_get_vap_info(hmac_vap[vap_idx])->bitmap_update_flag == OSAL_FALSE) {
292                 /* 支持双链接,每次电话业务触发时记录前一次,也即是当前6slot电话场景,便于后续出现切换时做删聚合操作 */
293                 hmac_btcoex_get_vap_info(hmac_vap[vap_idx])->bitmap_6slot = bt_status->bt_6slot;
294             }
295 
296             hmac_btcoex_update_ba_size(hmac_vap[vap_idx], btcoex_delba, btble_status);
297 
298             hmac_btcoex_delba_trigger(hmac_vap[vap_idx], need_delba, btcoex_delba);
299         } else {
300             hmac_btcoex_get_vap_info(hmac_vap[vap_idx])->bitmap_update_flag = OSAL_TRUE;
301 
302             /* 电话业务结束,需要使能双链路统计定制器 */
303             if (hmac_btcoex_get_vap_info(hmac_vap[vap_idx])->bt_coex_double_chain_timer.is_registerd == OSAL_TRUE) {
304                 frw_destroy_timer_entry(&(hmac_btcoex_get_vap_info(hmac_vap[vap_idx])->bt_coex_double_chain_timer));
305             }
306             frw_create_timer_entry(&(hmac_btcoex_get_vap_info(hmac_vap[vap_idx])->bt_coex_double_chain_timer),
307                 hmac_btcoex_double_chain_timeout_callback, BTCOEX_RX_STATISTICS_TIME,
308                 (osal_void *)(hmac_vap[vap_idx]), OSAL_FALSE);
309         }
310     }
311 
312     return OAL_SUCC;
313 }
314 #endif
315 
316 /*****************************************************************************
317  函 数 名  : hmac_btcoex_sco_status_handler
318  功能描述  : BT电话场景处理入口: 处理聚合个数调整
319 *****************************************************************************/
hmac_btcoex_sco_status_handler(hmac_vap_stru * hmac_vap)320 OSAL_STATIC osal_s32 hmac_btcoex_sco_status_handler(hmac_vap_stru *hmac_vap)
321 {
322     hal_chip_stru *hal_chip = OSAL_NULL;
323     hal_to_dmac_device_stru *hal_device = OSAL_NULL;
324     hal_btcoex_btble_status_stru *btble_status = OSAL_NULL;
325 
326     unref_param(hmac_vap);
327 
328     /* 获取chip指针 */
329     hal_chip = hal_get_chip_stru();
330 
331     /* 暂时只是处理主路的STA */
332     hal_device = &hal_chip->device.hal_device_base;
333 
334     btble_status = hal_btcoex_btble_status();
335 
336     /* 刷新ps stop标记 */
337     hmac_btcoex_ps_stop_check_and_notify(hal_device);
338 
339     /* 1.如果是不需要执行,只有5g,或者无设备关联状态,dbdc包含在此范畴,直接返回 */
340     /* 2.已经是c1 siso的话,这个需要在删聚合,以及m2s接口两套处理接口里面单独判断,不然m2s会被误返回 */
341     /* siso ap已经切换到了siso,不处理即可,一定要保证siso ap切换在之前完成 */
342     if ((hmac_btcoex_wifi_and_bt_insulate_check(hal_device, &(btble_status->bt_status.bt_status), OSAL_TRUE) ==
343         OSAL_TRUE) || (hal_device->device_btcoex_mgr.siso_ap_excute_on == OSAL_TRUE)) {
344         return OAL_SUCC;
345     }
346 #ifdef _PRE_WLAN_FEATURE_M2S
347     if (hal_device->device_btcoex_mgr.m2s_6slot == OSAL_TRUE) {
348         /* 如果是0,并且已经触发了切siso, 不能用m2s_mode做判断,没有正式切mimo,但是标记已经清掉,此时需要申请回mimo */
349         if (btble_status->bt_status.bt_status.bt_6slot == 0) {
350             /* 电话业务结束 */
351             get_hal_device_btcoex_s2m_mode_bitmap(hal_device) &= (~BT_M2S_6SLOT_MASK);
352 
353             if (hal_m2s_check_btcoex_on(hal_device) == OSAL_TRUE) {
354                 /* 申请切换回mimo */
355                 hmac_btcoex_s2m_switch_apply(hal_device, BT_M2S_6SLOT_MASK);
356             } else {
357                 hmac_btcoex_sco_status_delba_process(hal_device, btble_status);
358             }
359         } else if (btble_status->bt_status.bt_status.bt_6slot == 2) { /* 判断六时隙时是否为2 */
360             get_hal_device_btcoex_s2m_mode_bitmap(hal_device) |= BT_M2S_6SLOT_MASK;
361 
362             /* 双链接下,从2 0 1 0 2时,因为不会有a2dp标记存在,此时6slot 1又没有了,m2s_mode是等于0 就触发siso下切siso了
363              */
364             if (hal_m2s_check_btcoex_on(hal_device) == OSAL_TRUE) {
365                 /* 置m2s bitmap标记 */
366                 get_hal_device_btcoex_m2s_mode_bitmap(hal_device) |= BT_M2S_6SLOT_MASK;
367 
368                 oam_warning_log1(0, OAM_SF_COEX,
369                     "{hmac_btcoex_sco_status_handler::already siso m2s_mode[%d]!}",
370                     get_hal_device_btcoex_m2s_mode_bitmap(hal_device));
371             } else if (hmac_btcoex_m2s_switch_apply(hal_device, BT_M2S_6SLOT_MASK) != OAL_SUCC) {
372                 /* 申请切换siso */
373                 hmac_btcoex_sco_status_delba_process(hal_device, btble_status);
374             }
375         } else {
376             get_hal_device_btcoex_s2m_mode_bitmap(hal_device) |= BT_M2S_6SLOT_MASK;
377 
378             /* 双链接时,从2 0 1,或者ldac切换到电话,此时判断已经处于siso切换状态下,就保持不处理即可 */
379             if (hal_m2s_check_btcoex_on(hal_device) == OSAL_TRUE) {
380                 oam_warning_log1(0, OAM_SF_COEX,
381                     "{hmac_btcoex_sco_status_handler::already siso m2s_mode[%d]!}",
382                     get_hal_device_btcoex_m2s_mode_bitmap(hal_device));
383             } else {
384                 /* 需要先判断是不是已经是SISO 那就也不需要删聚合了 */
385                 hmac_btcoex_sco_status_delba_process(hal_device, btble_status);
386             }
387         }
388     } else {
389         hmac_btcoex_sco_status_delba_process(hal_device, btble_status);
390     }
391 #endif
392     return OAL_SUCC;
393 }
394 
395 /*****************************************************************************
396  函 数 名  : hmac_btcoex_ldac_status_handler
397  功能描述  : BT音乐场景针对ldac,识别处理
398              音乐先来,bt侧做速率识别之后,再产生ldac中断,因此ldac使能时需要判断音乐状态
399              音乐结束之后,会立即来ldac中断, 因此ldac禁能时不需要判断音乐状态
400 *****************************************************************************/
hmac_btcoex_ldac_status_handler(hmac_vap_stru * hmac_vap)401 OSAL_STATIC osal_s32 hmac_btcoex_ldac_status_handler(hmac_vap_stru *hmac_vap)
402 {
403     hal_chip_stru *hal_chip = OSAL_NULL;
404     hal_to_dmac_device_stru *hal_device = OSAL_NULL;
405     bt_status_stru *bt_status = OSAL_NULL;
406 
407     unref_param(hmac_vap);
408 
409     /* 获取chip指针 */
410     hal_chip = hal_get_chip_stru();
411 
412     /* 暂时只是处理主路的STA */
413     hal_device = &hal_chip->device.hal_device_base;
414     hmac_btcoex_update_coex_pri(hal_device);
415 
416     bt_status = &(hal_btcoex_btble_status()->bt_status.bt_status);
417     /* 1.如果是不需要执行,只有5g,或者无设备关联状态,dbdc包含在此范畴,直接返回 */
418     if (hmac_btcoex_wifi_and_bt_insulate_check(hal_device, bt_status, OSAL_TRUE) == OSAL_TRUE) {
419         return OAL_SUCC;
420     }
421 
422     /* 2.已经是c1 siso的话,这个需要在删聚合,以及m2s接口两套处理接口里面单独判断,不然m2s会被误返回 */
423     /* siso ap已经切换到了siso,不处理即可,一定要保证siso ap切换在之前完成 */
424     if (hal_device->device_btcoex_mgr.siso_ap_excute_on == OSAL_TRUE) {
425         return OAL_SUCC;
426     }
427 
428     /* LDAC先执行方案1,并申请方案2,方案2切换siso成功的话,再关闭方案1 */
429     hmac_btcoex_ldac_status_ps_process(hal_device, bt_status);
430 #ifdef _PRE_WLAN_FEATURE_M2S
431     /* LDAC打开m2s方案, 如果切换失败,需要保持在miso时,等中断0来切回mimo,m2s本身逻辑不打断 */
432     if (hal_device->device_btcoex_mgr.m2s_ldac == OSAL_TRUE) {
433         /* ldac使能时 1.触发切换m2s 2.切换成功,暂停ps,业务置位 3.m2s切换失败,不处理即可 */
434         if (bt_status->bt_ldac == OSAL_TRUE) {
435             /* 双链接下,从ldac 1 0 到a2dp 1 保持siso时,此时来了a2dp = 0 ldac = 1 会出现siso下切siso */
436             if (hal_m2s_check_btcoex_on(hal_device) == OSAL_TRUE) {
437                 /* 置m2s bitmap标记 */
438                 get_hal_device_btcoex_m2s_mode_bitmap(hal_device) |= BT_M2S_LDAC_MASK;
439 
440                 oam_warning_log1(0, OAM_SF_COEX,
441                     "{hmac_btcoex_ldac_status_handler::already siso m2s_mode[%d]!}",
442                     get_hal_device_btcoex_m2s_mode_bitmap(hal_device));
443             } else {
444                 hmac_btcoex_m2s_switch_apply(hal_device, BT_M2S_LDAC_MASK);
445             }
446 
447             get_hal_device_btcoex_s2m_mode_bitmap(hal_device) |= BT_M2S_LDAC_MASK;
448         } else {
449             get_hal_device_btcoex_s2m_mode_bitmap(hal_device) &= (~BT_M2S_LDAC_MASK);
450 
451             if (hal_m2s_check_btcoex_on(hal_device) == OSAL_TRUE) {
452                 /* ldac禁用时  1.如果初始切换到siso,触发切换m2s 回mimo模块综合之后,看是否回mimo 2.恢复ps */
453                 hmac_btcoex_s2m_switch_apply(hal_device, BT_M2S_LDAC_MASK);
454             }
455         }
456     }
457 #endif
458     oam_warning_log3(0, OAM_SF_COEX,
459         "{hmac_btcoex_ldac_status_handler::ldac state[%d],m2s_bitmap[%d],s2m_bitmap[%d].}", bt_status->bt_ldac,
460         get_hal_device_btcoex_m2s_mode_bitmap(hal_device), get_hal_device_btcoex_s2m_mode_bitmap(hal_device));
461 
462     return OAL_SUCC;
463 }
464 
465 /*****************************************************************************
466  函 数 名  : hmac_btcoex_status_event_handler
467  功能描述  : BT音乐场景处理入口: 处理聚合个数调整, 配置聚合个数,在接收速率逻辑进行删除BA操作
468 *****************************************************************************/
hmac_btcoex_a2dp_status_handler(hmac_vap_stru * hmac_vap)469 OSAL_STATIC osal_s32 hmac_btcoex_a2dp_status_handler(hmac_vap_stru *hmac_vap)
470 {
471     osal_u8 vap_idx, valid_vap_num;
472     osal_u8 mac_vap_id[WLAN_SERVICE_VAP_MAX_NUM_PER_DEVICE] = {0};
473     hmac_vap_stru *hmac_valid_vap = OSAL_NULL;
474     osal_u32 ret;
475     hal_to_dmac_device_stru *hal_device = &hal_get_chip_stru()->device.hal_device_base;
476     hal_btcoex_btble_status_stru *btble_status = hal_btcoex_btble_status();
477 
478     unref_param(hmac_vap);
479     /* 1.如果是不需要执行,只有5g,或者无设备关联状态,dbdc包含在此范畴,直接返回 */
480     if (hmac_btcoex_wifi_and_bt_insulate_check(hal_device, &(btble_status->bt_status.bt_status), OSAL_FALSE) ==
481         OSAL_TRUE) {
482         return OAL_SUCC;
483     }
484     /* 2.已经是c1 siso的话,这个需要在删聚合,以及m2s接口两套处理接口里面单独判断,不然m2s会被误返回 */
485     /* 找到满足要求的vap个数 */
486     valid_vap_num = hmac_btcoex_find_all_valid_sta_per_device(hal_device, mac_vap_id,
487         WLAN_SERVICE_VAP_MAX_NUM_PER_DEVICE);
488 #ifdef _PRE_WLAN_FEATURE_M2S
489     /* 如果是支持m2s切换,在音乐结束,并且bt业务已经在siso状态时做申请切回mimo */
490     if (hal_device->device_btcoex_mgr.m2s_ldac == OSAL_TRUE) {
491         if (btble_status->bt_status.bt_status.bt_a2dp == 0) {
492             get_hal_device_btcoex_s2m_mode_bitmap(hal_device) &= (~BT_M2S_A2DP_MASK);
493 
494             if (hal_m2s_check_btcoex_on(hal_device) == OSAL_TRUE &&
495                 hal_device->device_btcoex_mgr.siso_ap_excute_on == OSAL_FALSE) {
496                 hmac_btcoex_s2m_switch_apply(hal_device, BT_M2S_A2DP_MASK);
497             }
498         } else {
499             get_hal_device_btcoex_s2m_mode_bitmap(hal_device) |= BT_M2S_A2DP_MASK;
500         }
501     }
502 #endif
503     /* 如果定时器创建了,需要按照新的时间来刷新 */
504     hmac_btcoex_restart_ps_timer(hal_device);
505 
506     /* valid的vap设备都做对应处理 */
507     for (vap_idx = 0; vap_idx < valid_vap_num; vap_idx++) {
508         hmac_valid_vap = (hmac_vap_stru *)mac_res_get_hmac_vap(mac_vap_id[vap_idx]);
509         if (hmac_valid_vap == OSAL_NULL) {
510             oam_error_log1(0, OAM_SF_COEX, "{hmac_btcoex_a2dp_status_handler::vap[%d] IS NULL.}", mac_vap_id[vap_idx]);
511             return OAL_ERR_CODE_PTR_NULL;
512         }
513 
514         /* 找到valid sta,进行删减BA逻辑处理 */
515         ret = hmac_btcoex_delba_event_process(btble_status, hmac_valid_vap);
516         if (ret != OAL_SUCC) {
517             oam_warning_log1(0, OAM_SF_COEX,
518                 "{hmac_btcoex_a2dp_status_handler::hmac_btcoex_delba_event_process() fail!, ret=[%d]}", ret);
519         }
520     }
521 
522     return OAL_SUCC;
523 }
524 
525 /*****************************************************************************
526  函 数 名  : hmac_btcoex_assoc_ap_check_status_handler
527  功能描述  : BT ba业务状态下场景处理入口: 如果存在siso legacy ap,就切siso,bt最高优先级切siso业务
528              主要是解决行车记录仪  运动dv场景共存下wifi性能差
529 *****************************************************************************/
hmac_btcoex_assoc_ap_check_status_handler(hmac_vap_stru * hmac_vap)530 OSAL_STATIC osal_s32 hmac_btcoex_assoc_ap_check_status_handler(hmac_vap_stru *hmac_vap)
531 {
532     hal_chip_stru *hal_chip = OSAL_NULL;
533     hal_to_dmac_device_stru *hal_device = OSAL_NULL;
534     hal_btcoex_btble_status_stru *btble_status = OSAL_NULL;
535 
536     unref_param(hmac_vap);
537     /* 获取chip指针 */
538     hal_chip = hal_get_chip_stru();
539     /* 暂时只是处理主路的STA */
540     hal_device = &hal_chip->device.hal_device_base;
541     btble_status = hal_btcoex_btble_status();
542     /* 1.如果是不需要执行,只有5g,或者无设备关联状态,dbdc包含在此范畴,直接返回 */
543     if (hmac_btcoex_wifi_and_bt_insulate_check(hal_device, &(btble_status->bt_status.bt_status), OSAL_FALSE) ==
544         OSAL_TRUE) {
545         return OAL_SUCC;
546     }
547 
548     /* 2.已经是c1 siso的话,这个需要在删聚合,以及m2s接口两套处理接口里面单独判断,不然m2s会被误返回 */
549     /* 清除定时器,连续来了0 1 时也需要清定时器 */
550     if (hal_device->device_btcoex_mgr.bt_coex_s2m_siso_ap_timer.is_registerd == OSAL_TRUE) {
551         frw_destroy_timer_entry(&(hal_device->device_btcoex_mgr.bt_coex_s2m_siso_ap_timer));
552     }
553 
554     /* 查找当前device是否存在legacy ap是siso的,看是否需要申请切到c1 siso */
555     if (btble_status->bt_status.bt_status.bt_ba != 0) {
556         hmac_btcoex_assoc_ap_check_process(hal_device);
557     } else { /* 对应业务结束,查看是否已经置位c1 siso,启动定时器回mimo,防止音乐和电话切换太频繁 */
558         /* 在该模式执行siso阶段,此时要保证能力和m2s状态一致 */
559         if (hal_device->device_btcoex_mgr.siso_ap_excute_on == OSAL_TRUE) {
560             frw_create_timer_entry(&(hal_device->device_btcoex_mgr.bt_coex_s2m_siso_ap_timer),
561                 hmac_btcoex_s2m_siso_ap_resume_callback, BTCOEX_S2M_RESUME_TIMEOUT,
562                 (osal_void *)hal_device, OSAL_FALSE);
563         }
564     }
565 
566     return OAL_SUCC;
567 }
568 
569 /*****************************************************************************
570  函 数 名  : hmac_btcoex_page_scan_handler
571  功能描述  : BT PAGE场景处理入口: beacon count刷新
572 *****************************************************************************/
hmac_btcoex_page_scan_handler(hmac_vap_stru * hmac_vap)573 OSAL_STATIC osal_s32 hmac_btcoex_page_scan_handler(hmac_vap_stru *hmac_vap)
574 {
575     hmac_vap_btcoex_occupied_stru *btcoex_occupied = OSAL_NULL;
576     hal_chip_stru *hal_chip = OSAL_NULL;
577     hal_to_dmac_device_stru *hal_device = OSAL_NULL;
578     hmac_vap_stru *hmac_valid_vap = OSAL_NULL;
579     osal_u8 vap_idx;
580     osal_u8 valid_vap_num;
581     osal_u8                      mac_vap_id[WLAN_SERVICE_VAP_MAX_NUM_PER_DEVICE] = {0};
582 
583     unref_param(hmac_vap);
584 
585     /* 获取chip指针 */
586     hal_chip = hal_get_chip_stru();
587 
588     /* 暂时只是处理主路的STA */
589     hal_device = &hal_chip->device.hal_device_base;
590     /* 1.如果是不需要执行,只有5g,或者无设备关联状态,dbdc包含在此范畴,直接返回 */
591     if (hmac_btcoex_wifi_and_bt_insulate_check(hal_device,
592         &(hal_btcoex_btble_status()->bt_status.bt_status), OSAL_FALSE) == OSAL_TRUE) {
593         return OAL_SUCC;
594     }
595 
596     /* 2.已经是c1 siso的话,这个需要在删聚合,以及m2s接口两套处理接口里面单独判断,不然m2s会被误返回 */
597     /* 找到满足要求的vap个数 */
598     valid_vap_num = hmac_btcoex_find_all_valid_ap_per_device(hal_device, mac_vap_id,
599         WLAN_SERVICE_VAP_MAX_NUM_PER_DEVICE);
600 
601     /* valid的vap设备都做对应处理, 02只处理legacy sta   03要处理gc sta */
602     for (vap_idx = 0; vap_idx < valid_vap_num; vap_idx++) {
603         hmac_valid_vap = (hmac_vap_stru *)mac_res_get_hmac_vap(mac_vap_id[vap_idx]);
604         if (hmac_valid_vap == OSAL_NULL) {
605             oam_error_log1(0, OAM_SF_COEX, "{hmac_btcoex_page_scan_handler::hmac_vap[%d] IS NULL.}",
606                 mac_vap_id[vap_idx]);
607             return OAL_ERR_CODE_PTR_NULL;
608         }
609 
610         /* 找到valid sta,进行beacon miss逻辑处理 */
611         btcoex_occupied = &(hmac_btcoex_get_vap_info(hmac_vap)->hmac_vap_btcoex_occupied);
612 
613         btcoex_occupied->ap_beacon_count = hal_btcoex_update_ap_beacon_count();
614         btcoex_occupied->beacon_miss_cnt = 0;
615     }
616 
617     /* 如果定时器创建了,需要按照新的时间来刷新 */
618     hmac_btcoex_restart_ps_timer(hal_device);
619     return OAL_SUCC;
620 }
621 
622 /*****************************************************************************
623  函 数 名  : hmac_btcoex_inquiry_status_handler
624  功能描述  : BT inquiry场景处理入口: 如果ps定时器在启动,需要刷新寄存器时间
625 *****************************************************************************/
hmac_btcoex_inquiry_status_handler(hmac_vap_stru * hmac_vap)626 OSAL_STATIC osal_s32 hmac_btcoex_inquiry_status_handler(hmac_vap_stru *hmac_vap)
627 {
628     hal_chip_stru *hal_chip = OSAL_NULL;
629     hal_to_dmac_device_stru *hal_device = OSAL_NULL;
630 
631     unref_param(hmac_vap);
632 
633     /* 获取chip指针 */
634     hal_chip = hal_get_chip_stru();
635 
636     /* 暂时只是处理主路的STA */
637     hal_device = &hal_chip->device.hal_device_base;
638     /* 1.如果是不需要执行,只有5g,或者无设备关联状态,dbdc包含在此范畴,直接返回 */
639     if (hmac_btcoex_wifi_and_bt_insulate_check(hal_device,
640         &(hal_btcoex_btble_status()->bt_status.bt_status), OSAL_FALSE) == OSAL_TRUE) {
641         return OAL_SUCC;
642     }
643 
644     /* 2.已经是c1 siso的话,这个需要在删聚合,以及m2s接口两套处理接口里面单独判断,不然m2s会被误返回 */
645     /* 如果定时器创建了,需要按照新的时间来刷新 */
646     hmac_btcoex_restart_ps_timer(hal_device);
647     return OAL_SUCC;
648 }
649 
650 /*****************************************************************************
651  函 数 名  : hmac_btcoex_transfer_status_handler
652  功能描述  : BT文件传输场景处理入口: 处理聚合个数调整
653 *****************************************************************************/
hmac_btcoex_transfer_status_handler(hmac_vap_stru * hmac_vap)654 OSAL_STATIC osal_s32 hmac_btcoex_transfer_status_handler(hmac_vap_stru *hmac_vap)
655 {
656     hal_btcoex_btble_status_stru *btble_status = hal_btcoex_btble_status();
657     hal_to_dmac_device_stru *hal_device = &hal_get_chip_stru()->device.hal_device_base;
658     osal_u8 vap_idx;
659     osal_u8 valid_vap_num;
660     osal_u8 mac_vap_id[WLAN_SERVICE_VAP_MAX_NUM_PER_DEVICE] = {0};
661     hmac_vap_stru *hmac_valid_vap = OSAL_NULL;
662     osal_u32 ret;
663 
664     unref_param(hmac_vap);
665 
666     /* 1.如果是不需要执行,只有5g,或者无设备关联状态,dbdc包含在此范畴,直接返回 */
667     if (hmac_btcoex_wifi_and_bt_insulate_check(hal_device, &(btble_status->bt_status.bt_status), OSAL_FALSE) ==
668         OSAL_TRUE) {
669         return OAL_SUCC;
670     }
671 
672     /* 2.已经是c1 siso的话,这个需要在删聚合,以及m2s接口两套处理接口里面单独判断,不然m2s会被误返回 */
673     /* 找到满足要求的vap个数 */
674     valid_vap_num = hmac_btcoex_find_all_valid_sta_per_device(hal_device, mac_vap_id,
675         WLAN_SERVICE_VAP_MAX_NUM_PER_DEVICE);
676 
677     /* 如果定时器创建了,需要按照新的时间来刷新 */
678     hmac_btcoex_restart_ps_timer(hal_device);
679 
680     /* valid的vap设备都做对应处理 */
681     for (vap_idx = 0; vap_idx < valid_vap_num; vap_idx++) {
682         hmac_valid_vap = (hmac_vap_stru *)mac_res_get_hmac_vap(mac_vap_id[vap_idx]);
683         if (hmac_valid_vap == OSAL_NULL) {
684             oam_error_log1(0, OAM_SF_COEX, "{hmac_btcoex_transfer_status_handler::hmac_vap[%d] IS NULL.}",
685                 mac_vap_id[vap_idx]);
686             return OAL_ERR_CODE_PTR_NULL;
687         }
688 
689         /* 找到valid sta,进行删减BA逻辑处理 */
690         ret = hmac_btcoex_delba_event_process(btble_status, hmac_valid_vap);
691         if (ret != OAL_SUCC) {
692             oam_warning_log1(0, OAM_SF_COEX,
693                 "{hmac_btcoex_transfer_status_handler::hmac_btcoex_delba_event_process() fail!, ret=[%d]}", ret);
694         }
695     }
696 
697     return OAL_SUCC;
698 }
699 
700 /*****************************************************************************
701  函 数 名  : hmac_btcoex_status_dispatch
702  功能描述  : 状态寄存器处理分发
703 *****************************************************************************/
hmac_btcoex_status_dispatch(hmac_vap_stru * hmac_vap,const hal_btcoex_btble_status_stru * status_old,hal_btcoex_btble_status_stru * status_new)704 osal_void hmac_btcoex_status_dispatch(hmac_vap_stru *hmac_vap,
705     const hal_btcoex_btble_status_stru *status_old, hal_btcoex_btble_status_stru *status_new)
706 {
707     /* 数据传输 */
708     if (status_old->bt_status.bt_status.bt_ba != status_new->bt_status.bt_status.bt_ba) {
709         oam_warning_log1(0, OAM_SF_COEX, "{hmac_btcoex_status_dispatch::bt_ba change to %u}",
710             status_new->bt_status.bt_status.bt_ba);
711         hmac_btcoex_assoc_ap_check_status_handler(hmac_vap);
712     }
713 
714     /* LDAC音乐 */
715     if (status_old->bt_status.bt_status.bt_ldac != status_new->bt_status.bt_status.bt_ldac) {
716         oam_warning_log1(0, OAM_SF_COEX, "{hmac_btcoex_status_dispatch::bt_ldac change to %u}",
717             status_new->bt_status.bt_status.bt_ldac);
718         hmac_btcoex_ldac_status_handler(hmac_vap);
719     }
720 
721     /* SCO */
722     if (status_old->bt_status.bt_status.bt_6slot != status_new->bt_status.bt_status.bt_6slot) {
723         oam_warning_log1(0, OAM_SF_COEX, "{hmac_btcoex_status_dispatch::bt_6slot change to %u}",
724             status_new->bt_status.bt_status.bt_6slot);
725         hmac_btcoex_sco_status_handler(hmac_vap);
726     }
727 
728     /* A2DP音乐 */
729     if (status_old->bt_status.bt_status.bt_a2dp != status_new->bt_status.bt_status.bt_a2dp) {
730         oam_warning_log1(0, OAM_SF_COEX, "{hmac_btcoex_status_dispatch::bt_a2dp change to %u}",
731             status_new->bt_status.bt_status.bt_a2dp);
732         hmac_btcoex_a2dp_status_handler(hmac_vap);
733     }
734 
735     /* Page scan */
736     if (status_old->bt_status.bt_status.bt_page != status_new->bt_status.bt_status.bt_page) {
737         oam_warning_log1(0, OAM_SF_COEX, "{hmac_btcoex_status_dispatch::bt_page change to %u}",
738             status_new->bt_status.bt_status.bt_page);
739         hmac_btcoex_page_scan_handler(hmac_vap);
740     }
741 
742     /* Inquiry */
743     if (status_old->bt_status.bt_status.bt_inquiry != status_new->bt_status.bt_status.bt_inquiry) {
744         oam_warning_log1(0, OAM_SF_COEX, "{hmac_btcoex_status_dispatch::bt_inquiry change to %u}",
745             status_new->bt_status.bt_status.bt_inquiry);
746         hmac_btcoex_inquiry_status_handler(hmac_vap);
747     }
748 
749     /* Transfer */
750     if (status_old->bt_status.bt_status.bt_transfer != status_new->bt_status.bt_status.bt_transfer) {
751         oam_warning_log1(0, OAM_SF_COEX, "{hmac_btcoex_status_dispatch::bt_transfer change to %u}",
752             status_new->bt_status.bt_status.bt_transfer);
753         hmac_btcoex_transfer_status_handler(hmac_vap);
754     }
755 }
756 #endif
757 
758 #ifdef __cplusplus
759 #if __cplusplus
760 }
761 #endif
762 #endif
763 
764 #endif
765