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