1 /*
2 * 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: M2S处理
15 * Date: 2023-01-31 10:14
16 */
17 #ifndef __HMAC_BTCOEX_M2S_C__
18 #define __HMAC_BTCOEX_M2S_C__
19
20 #include "hmac_mgmt_sta.h"
21 #include "hmac_feature_interface.h"
22 #include "hmac_scan.h"
23 #include "hmac_btcoex.h"
24 #include "hmac_btcoex_ps.h"
25 #include "hmac_btcoex_m2s.h"
26
27 #ifdef __cplusplus
28 #if __cplusplus
29 extern "C" {
30 #endif
31 #endif
32 #undef THIS_FILE_ID
33 #define THIS_FILE_ID DIAG_FILE_ID_WIFI_HOST_HMAC_BTCOEX_M2S_C
34
35 #undef THIS_MOD_ID
36 #define THIS_MOD_ID DIAG_MOD_ID_WIFI_HOST
37
38 #ifdef _PRE_WLAN_FEATURE_M2S
39 /*****************************************************************************
40 函 数 名 : hmac_m2s_btcoex_need_switch_check
41 功能描述 : 其他业务结束之后,在回到mimo时,是否需要继续切到siso,保证btcoex业务性能
42 *****************************************************************************/
hmac_m2s_btcoex_need_switch_check(const hal_to_dmac_device_stru * hal_device,osal_u8 * m2s_mode_mask)43 oal_bool_enum_uint8 hmac_m2s_btcoex_need_switch_check(const hal_to_dmac_device_stru *hal_device, osal_u8 *m2s_mode_mask)
44 {
45 hal_chip_stru *hal_chip = OSAL_NULL;
46 hal_btcoex_btble_status_stru *btble_status = OSAL_NULL;
47 hmac_vap_stru *mac_vap_temp = OSAL_NULL;
48 osal_u8 vap_index;
49 osal_u8 up_vap_num;
50 osal_u8 mac_vap_id[WLAN_SERVICE_VAP_MAX_NUM_PER_DEVICE] = {0};
51 oal_bool_enum_uint8 m2s_wifi_need = OSAL_FALSE; /* btcoex业务满足切换需求 */
52 oal_bool_enum_uint8 m2s_bt_need = OSAL_FALSE; /* wifi业务满足切换需求 */
53
54 hal_chip = hal_get_chip_stru();
55 btble_status = hal_btcoex_btble_status();
56
57 /* 1.需要考虑此时是不是只有5g,是的话,不需要切 */
58 up_vap_num = hal_device_find_all_up_vap(hal_device, mac_vap_id, WLAN_SERVICE_VAP_MAX_NUM_PER_DEVICE);
59 for (vap_index = 0; vap_index < up_vap_num; vap_index++) {
60 mac_vap_temp = (hmac_vap_stru *)mac_res_get_hmac_vap(mac_vap_id[vap_index]);
61 if (mac_vap_temp == OSAL_NULL) {
62 oam_error_log1(0, OAM_SF_COEX,
63 "vap_id[%d] hmac_m2s_btcoex_need_switch_check::hmac_vap IS NULL.", mac_vap_id[vap_index]);
64 continue;
65 }
66
67 /* 存在2G的vap设备,dbac也需要考虑 */
68 if (mac_btcoex_check_valid_vap(mac_vap_temp) == OSAL_TRUE) {
69 m2s_wifi_need = OSAL_TRUE;
70 }
71 }
72
73 /* 2.6slot,注意业务不存在时清一下业务标记,很可能是dbdc期间m2s业务置位了,但是中途业务结束,dbdc结束也要同步清bt业务标记
74 */
75 if (hal_device->device_btcoex_mgr.m2s_6slot == OSAL_TRUE) {
76 if (btble_status->bt_status.bt_status.bt_6slot == 2) { /* 6slot为2时,m2s_bt_need才为true */
77 *m2s_mode_mask = BT_M2S_6SLOT_MASK;
78 m2s_bt_need = OSAL_TRUE;
79 }
80 }
81
82 /* 3.ldac, 两个标志不会同时存在 */
83 if (hal_device->device_btcoex_mgr.m2s_ldac == OSAL_TRUE) {
84 if (btble_status->bt_status.bt_status.bt_ldac == 1) {
85 *m2s_mode_mask = BT_M2S_LDAC_MASK;
86 m2s_bt_need = OSAL_TRUE;
87 }
88 }
89
90 /* 4.wifi存在2g,并且bt存在切换业务,才允许做切换 */
91 if (m2s_wifi_need == OSAL_TRUE && m2s_bt_need == OSAL_TRUE) {
92 return OSAL_TRUE;
93 }
94
95 return OSAL_FALSE;
96 }
97
98 /*****************************************************************************
99 函 数 名 : hmac_btcoex_s2m_allow_check
100 功能描述 : (1)当前处于bt切siso状态
101 (2)当前hal device上是否还有2g up vap,没有的话,需要回到mimo
102 (3)如果关联失败去关联,需要在去关联接口重新判断当前bt业务状态是否再切siso
103 *****************************************************************************/
hmac_btcoex_s2m_allow_check(hal_to_dmac_device_stru * hal_device)104 osal_void hmac_btcoex_s2m_allow_check(hal_to_dmac_device_stru *hal_device)
105 {
106 osal_u8 vap_idx;
107 osal_u8 up_vap_num;
108 oal_bool_enum_uint8 s2m_need = OSAL_TRUE;
109 osal_u8 mac_vap_id[WLAN_SERVICE_VAP_MAX_NUM_PER_DEVICE] = {0};
110 hmac_vap_stru *hmac_vap = OSAL_NULL;
111
112 /* 整个逻辑在dbdc和btcoex切siso on判断之后,此时肯定不是dbdc场景;没有切换到c1 siso,也不存在回mimo */
113 /* 1.如果不支持切换直接返回; 注意GET_HAL_DEVICE_BTCOEX_SISO_AP_EXCUTE_ON(hal_device)默认这两个要打开 */
114 if (hal_device->device_btcoex_mgr.m2s_6slot == OSAL_FALSE &&
115 hal_device->device_btcoex_mgr.m2s_ldac == OSAL_FALSE) {
116 return;
117 }
118
119 /* 找到所有up的vap设备 */
120 up_vap_num = hal_device_find_all_up_vap(hal_device, mac_vap_id, WLAN_SERVICE_VAP_MAX_NUM_PER_DEVICE);
121 for (vap_idx = 0; vap_idx < up_vap_num; vap_idx++) {
122 hmac_vap = (hmac_vap_stru *)mac_res_get_hmac_vap(mac_vap_id[vap_idx]);
123 if (hmac_vap == OSAL_NULL) {
124 oam_error_log1(0, OAM_SF_COEX,
125 "vap_id[%d] {hmac_btcoex_s2m_allow_check::mac_temp_vap IS NULL.}", mac_vap_id[vap_idx]);
126 return;
127 }
128
129 /* 存在2G的vap设备,dbac也需要考虑,此时需要保持在c1 siso */
130 if (mac_btcoex_check_valid_vap(hmac_vap) == OSAL_TRUE) {
131 s2m_need = OSAL_FALSE;
132 }
133 }
134
135 /* 2.判断是否需要回mimo,需要的话从siso执行 */
136 if (s2m_need == OSAL_TRUE) {
137 oam_warning_log1(0, OAM_SF_COEX,
138 "{hmac_btcoex_s2m_allow_check::up_vap_num[%d]resume to mimo!}", up_vap_num);
139
140 hmac_m2s_handle_event(hal_device, HAL_M2S_EVENT_BT_SISO_TO_MIMO, 0, OSAL_NULL);
141
142 /* 回到mimo的话,需要恢复ps机制 */
143 hmac_btcoex_ps_stop_check_and_notify(hal_device);
144
145 /* 此时可能电话 ldac业务已经结束,3s定时器已经创建,需要清定时器 */
146 if (hal_device->device_btcoex_mgr.s2m_resume_timer.is_registerd == OSAL_TRUE) {
147 frw_destroy_timer_entry(&(hal_device->device_btcoex_mgr.s2m_resume_timer));
148 }
149
150 /* 如果是ap siso模式切换,此时需要清标志,重关联时候再切换 */
151 hal_device->device_btcoex_mgr.siso_ap_excute_on = OSAL_FALSE;
152 frw_destroy_timer_entry(&(hal_device->device_btcoex_mgr.bt_coex_s2m_siso_ap_timer));
153
154 /* 此时可能多个业务同时结束,定时器清除,造成可能某个业务m2s标记一直在,切回mimo,需要清所有业务标记 */
155 get_hal_device_btcoex_m2s_mode_bitmap(hal_device) = 0;
156
157 get_hal_device_btcoex_s2m_wait_bitmap(hal_device) = 0;
158 }
159 }
160
161 /*****************************************************************************
162 函 数 名 : hmac_btcoex_s2m_resume_callback
163 功能描述 : 申请回mimo定时器超时处理函数,判断是否当前业务都结束才申请回mimo,否则继续保持siso不处理
164 *****************************************************************************/
hmac_btcoex_s2m_resume_callback(osal_void * arg)165 osal_u32 hmac_btcoex_s2m_resume_callback(osal_void *arg)
166 {
167 hal_to_dmac_device_stru *hal_device = (hal_to_dmac_device_stru *)arg;
168
169 /* 1.统计当前m2s业务状态,各业务下半部根据业务=0/1 完成m2s mode的刷新,此处直接用 */
170 get_hal_device_btcoex_m2s_mode_bitmap(hal_device) &= (~(get_hal_device_btcoex_s2m_wait_bitmap(hal_device)));
171
172 /* 临时保持结束,状态清零 */
173 get_hal_device_btcoex_s2m_wait_bitmap(hal_device) = 0;
174
175 /* 2.如果bitmap为空,说明不存在业务需要保持在siso,可以申请切换回mimo */
176 if (get_hal_device_btcoex_s2m_mode_bitmap(hal_device) == 0) {
177 /* 如果是ap模式需要切换 */
178 if (hmac_m2s_custom_switch_check(hal_device) == OSAL_TRUE) {
179 /* 清btcoex mode业务状态 */
180 get_hal_m2s_mode_tpye(hal_device) &= (~WLAN_M2S_TRIGGER_MODE_BTCOEX);
181
182 hmac_m2s_handle_event(hal_device, HAL_M2S_EVENT_CUSTOM_SISO_C1_TO_SISO_C0, 0, OSAL_NULL);
183 } else {
184 hmac_m2s_handle_event(hal_device, HAL_M2S_EVENT_BT_SISO_TO_MIMO, 0, OSAL_NULL);
185 }
186
187 /* 回到mimo/c0 siso的话,需要恢复ps机制 */
188 hmac_btcoex_ps_stop_check_and_notify(hal_device);
189
190 oam_warning_log2(0, OAM_SF_COEX,
191 "{hmac_btcoex_s2m_resume_callback::succ to mimo, m2s_bitmap[%d] m2s_mode[%d]!}",
192 get_hal_device_btcoex_m2s_mode_bitmap(hal_device), get_hal_m2s_mode_tpye(hal_device));
193
194 /* 此时可能多个业务同时结束,定时器清除,造成可能某个业务m2s标记一直在,切回mimo,需要清所有业务标记 */
195 get_hal_device_btcoex_m2s_mode_bitmap(hal_device) = 0;
196 } else {
197 /* 3. 需要sco = 0 a2dp = 0 ldac = 0 都做切回mimo申请,才能接口做得简单 */
198 oam_warning_log2(0, OAM_SF_COEX,
199 "{hmac_btcoex_s2m_resume_callback::cannot to mimo, need all is ready s2m_bitmap[%d]m2s_bitmap[%d]!}",
200 get_hal_device_btcoex_s2m_mode_bitmap(hal_device), get_hal_device_btcoex_m2s_mode_bitmap(hal_device));
201 }
202
203 return OAL_SUCC;
204 }
205
206 /*****************************************************************************
207 函 数 名 : hmac_btcoex_m2s_allow_check
208 功能描述 : 当前业务场景,是否执行m2s切换
209 (1)方案上考虑2g vap
210 (2)sta和ap处于不同的接口时
211 *****************************************************************************/
hmac_btcoex_m2s_allow_check(hal_to_dmac_device_stru * hal_device,const hmac_vap_stru * hmac_vap)212 osal_void hmac_btcoex_m2s_allow_check(hal_to_dmac_device_stru *hal_device, const hmac_vap_stru *hmac_vap)
213 {
214 hal_chip_stru *hal_chip = hal_get_chip_stru();
215 bt_status_stru *bt_status = OSAL_NULL;
216 oal_bool_enum_uint8 m2s_need = OSAL_FALSE;
217 hal_btcoex_btble_status_stru *status = OSAL_NULL;
218
219 if (hal_device == OSAL_NULL) {
220 return;
221 }
222
223 /* 2.如果不支持切换直接返回 */
224 if (hal_device->device_btcoex_mgr.m2s_6slot == OSAL_FALSE &&
225 hal_device->device_btcoex_mgr.m2s_ldac == OSAL_FALSE) {
226 return;
227 }
228
229 /* 3. sta已经关联上,尽量不要在siso时候关联此ap,可能有风险,ap在黑名单需要保持在miso,不能切换 */
230 if (get_hal_device_m2s_del_swi_miso_hold(hal_device) == OSAL_TRUE) {
231 oam_warning_log0(0, OAM_SF_COEX,
232 "{hmac_btcoex_m2s_allow_check::MISO AP not support change to siso!}");
233 return;
234 }
235
236 /* 4.已经是c1 siso的话,新入网的设备直接入网就是 */
237 if (hal_device->hal_m2s_fsm.oal_fsm.cur_state == HAL_M2S_STATE_SISO &&
238 hal_device->cfg_cap_info->phy_chain == WLAN_PHY_CHAIN_ONE) {
239 oam_warning_log0(0, OAM_SF_COEX, "{hmac_btcoex_m2s_allow_check::already c1 siso!}");
240 return;
241 }
242
243 /* 4.1 后续所有切siso业务都要判断,当前spec是不是支持,支持的话可以切换,不支持的话,不能切换;
244 主要是2G不支持c1 siso的话 */
245 if (hal_get_chip_stru()->rf_custom_mgr.support_rf_chain_2g == WLAN_RF_CHAIN_ZERO) {
246 oam_warning_log1(0, OAM_SF_COEX,
247 "{hmac_btcoex_m2s_allow_check::spec 2G chain[%d] restrain, not support c1 SISO.}",
248 hal_get_chip_stru()->rf_custom_mgr.support_rf_chain_2g);
249 return;
250 }
251
252 /* 5.当前hal device上另一个vap设备状态无所谓,只要当前入网vap是2G 就考虑切siso */
253 /* 当前vap一定是在入网和ap up,find 找不到,此时直接判断入网的vap在2g的话,也需要申请切siso */
254 if (hmac_vap->channel.band == WLAN_BAND_2G) {
255 m2s_need = OSAL_TRUE;
256 }
257 status = hal_btcoex_btble_status();
258 hal_update_btcoex_btble_status(status);
259 bt_status = &(status->bt_status.bt_status);
260
261 /* 5.存在2g vap,开始判断是否存在切siso的蓝牙业务 */
262 if (m2s_need == OSAL_TRUE) {
263 if (bt_status->bt_6slot == 2 && hal_device->device_btcoex_mgr.m2s_6slot == OSAL_TRUE) { /* 六时隙若为2 */
264 hmac_btcoex_m2s_switch_apply(hal_device, BT_M2S_6SLOT_MASK);
265 } else if (bt_status->bt_ldac == 1 && hal_device->device_btcoex_mgr.m2s_ldac == OSAL_TRUE) {
266 hmac_btcoex_m2s_switch_apply(hal_device, BT_M2S_LDAC_MASK);
267 }
268 }
269 oam_warning_log3(0, OAM_SF_COEX, "{hmac_btcoex_m2s_allow_check::m2s_need[%d]m2s_state[%d]m2s_mode[%d]!}",
270 m2s_need, hal_device->hal_m2s_fsm.oal_fsm.cur_state, get_hal_m2s_mode_tpye(hal_device));
271 oam_warning_log4(0, OAM_SF_COEX, "{hmac_btcoex_m2s_allow_check::6slot[%d]ldac[%d]vap_band[%d]vap_mode[%d]!}",
272 bt_status->bt_6slot, bt_status->bt_ldac, hmac_vap->channel.band, hmac_vap->vap_mode);
273 }
274
hmac_btcoex_m2s_switch_other(const hal_to_dmac_device_stru * hal_device,hal_m2s_event_tpye_uint16 * m2s_event)275 osal_u32 hmac_btcoex_m2s_switch_other(const hal_to_dmac_device_stru *hal_device,
276 hal_m2s_event_tpye_uint16 *m2s_event)
277 {
278 /* 3.有其他业务已经申请切换,不包括自身模块,不支持切换,这里要变厚 */
279 if ((get_hal_m2s_mode_tpye(hal_device) & (~WLAN_M2S_TRIGGER_MODE_BTCOEX)) != 0) {
280 /* 2.0 如果此时是spec切换到了siso 蓝牙业务期望切换到siso的话,就保持不变;等spec退出时判断要不要切c1
281 * siso;暂时不采用共存mode方式 */
282 if (hal_m2s_check_spec_on(hal_device) == OSAL_TRUE) {
283 } else if (hal_m2s_check_fast_scan_on(hal_device) == OSAL_TRUE) {
284 /* 2.1 按照优先级,如果DBDC在运行,在最外层已经判断主路没有2g而返回,dbdc退出时候要单独判断bt业务状态 */
285 /* 3.2 虽然scan abort了,但是此处会有并发扫描伴随dbdc,扫描结束不会回mimo,因为dbdc在,并发扫描标记还在 */
286 *m2s_event = HAL_M2S_EVENT_BT_SISO_C0_TO_SISO_C1;
287
288 get_hal_m2s_mode_tpye(hal_device) &= (~WLAN_M2S_TRIGGER_MODE_FAST_SCAN);
289 } else if (hal_m2s_check_command_on(hal_device) == OSAL_TRUE) {
290 /* 3.3 如果只有低优先级的MSS,默认是c0 siso,直接清mss标记,然后切c1 siso即可 */
291 /* 如果处于miso探测态,需要停止切换保护,并切c1 siso */
292 if (hal_device->hal_m2s_fsm.oal_fsm.cur_state == HAL_M2S_STATE_MISO) {
293 *m2s_event = HAL_M2S_EVENT_BT_MISO_TO_SISO_C1;
294 } else {
295 *m2s_event = HAL_M2S_EVENT_BT_SISO_C0_TO_SISO_C1;
296 }
297
298 /* 切换保护功能关闭 */
299 get_hal_device_m2s_switch_prot(hal_device) = OSAL_FALSE;
300
301 /* 清业务标志 */
302 get_hal_m2s_mode_tpye(hal_device) &= (~WLAN_M2S_TRIGGER_MODE_COMMAND);
303 } else if (hal_m2s_check_rssi_on(hal_device) == OSAL_TRUE) {
304 /* 3.4 如果只有低优先级的rssi,要判断是c0 miso 还是c1 miso */
305 *m2s_event = HAL_M2S_EVENT_BT_MISO_TO_SISO_C1;
306
307 /* 清业务标志 */
308 get_hal_m2s_mode_tpye(hal_device) &= (~WLAN_M2S_TRIGGER_MODE_RSSI);
309 } else if (hal_m2s_check_custom_on(hal_device) == OSAL_TRUE) {
310 /* 3.5 如果custom, 需要切换到c1 siso,而且需要用蓝牙状态,否则后续无法回去 */
311 *m2s_event = HAL_M2S_EVENT_BT_SISO_C0_TO_SISO_C1;
312
313 /* 清业务标志,btcoex和custom相互打断,会相互恢复 刚打开热点,蓝牙中断就更新好了 */
314 get_hal_m2s_mode_tpye(hal_device) &= (~WLAN_M2S_TRIGGER_MODE_CUSTOM);
315 } else {
316 oam_error_log1(0, OAM_SF_COEX,
317 "{hmac_btcoex_m2s_switch_other::cannot to siso, mode[%d]!}", get_hal_m2s_mode_tpye(hal_device));
318 return OAL_FAIL;
319 }
320 } else {
321 /* 4.如果有业务mode bitmap已经是1,说明已经在申请siso过程中,保持siso不处理即可 */
322 if (get_hal_device_btcoex_m2s_mode_bitmap(hal_device) != 0) {
323 oam_warning_log1(0, OAM_SF_COEX,
324 "{hmac_btcoex_m2s_switch_other::keep siso. m2s_bitmap[%d]!}",
325 get_hal_device_btcoex_m2s_mode_bitmap(hal_device));
326 } else { /* */
327 if (hal_device->hal_m2s_fsm.oal_fsm.cur_state == HAL_M2S_STATE_MIMO) {
328 *m2s_event = HAL_M2S_EVENT_BT_MIMO_TO_SISO_C1;
329 } else if (hal_device->hal_m2s_fsm.oal_fsm.cur_state == HAL_M2S_STATE_SISO) {
330 *m2s_event = HAL_M2S_EVENT_BT_SISO_C0_TO_SISO_C1;
331 } else if (hal_device->hal_m2s_fsm.oal_fsm.cur_state == HAL_M2S_STATE_IDLE &&
332 hal_device->cfg_cap_info->phy2dscr_chain == WLAN_PHY_CHAIN_DOUBLE &&
333 hal_device->cfg_cap_info->phy_chain == WLAN_PHY_CHAIN_DOUBLE) {
334 /* 这里希望做到c1 siso入网,默认idle时候要是mimo,不是的话 */
335 *m2s_event = HAL_M2S_EVENT_BT_MIMO_TO_SISO_C1;
336 } else {
337 oam_error_log3(0, OAM_SF_COEX,
338 "{hmac_btcoex_m2s_switch_other::error. m2s_state[%d]phy_chain[%d]phy2dscr_chain[%d]!}",
339 hal_device->hal_m2s_fsm.oal_fsm.cur_state, hal_device->cfg_cap_info->phy_chain,
340 hal_device->cfg_cap_info->phy2dscr_chain);
341 }
342 }
343 }
344 return OAL_CONTINUE;
345 }
346
347 /*****************************************************************************
348 函 数 名 : hmac_btcoex_m2s_switch_apply
349 功能描述 : btcoex下特性业务申请切到siso
350 (1)业务进入,申请切siso
351 (2)业务退出,申请切mimo,ldac和sco同时在,一个退出,也保持siso
352 (3)这里需要对业务做集中管理,比如ldac来的太频繁,要保护到切换完成
353 (4)保护标志可以在m2s完成里面清
354 (5)要保证中断是1和0 否则可能出现先切mimo的操作,不过应该没关系
355 *****************************************************************************/
hmac_btcoex_m2s_switch_apply(hal_to_dmac_device_stru * hal_device,osal_u8 m2s_mode_mask)356 osal_u32 hmac_btcoex_m2s_switch_apply(hal_to_dmac_device_stru *hal_device, osal_u8 m2s_mode_mask)
357 {
358 hal_m2s_event_tpye_uint16 m2s_event = HAL_M2S_EVENT_BUTT;
359 hmac_device_stru *hmac_device = hmac_res_get_mac_dev_etc(0);
360 osal_u32 ret;
361
362 /* 0.存在2G设备时候才切siso,最外层已经判断,这里肯定是存在,另外防止mss
363 * 回miso扫描,bt申请切siso时先abort当次扫描,避免冲突 */
364 hmac_scan_abort(hmac_device);
365
366 oam_warning_log2(0, OAM_SF_COEX, "{hmac_btcoex_m2s_switch_apply:: m2s_stru[%d]m2s_state[%d]!}",
367 get_hal_m2s_mode_tpye(hal_device), hal_device->hal_m2s_fsm.oal_fsm.cur_state);
368
369 /* 1. ap在黑名单需要保持在miso,不能切换 */
370 if (get_hal_device_m2s_del_swi_miso_hold(hal_device) == OSAL_TRUE) {
371 oam_warning_log0(0, OAM_SF_COEX,
372 "{hmac_btcoex_m2s_switch_apply:: AP not support change to siso!}");
373 return OAL_FAIL;
374 }
375
376 /* 2. 异频dbac场景,2g期望工作在c1 siso,5g时工作在c0 siso,之间切换,此时要支持切换,2G
377 默认支持mimo,此时不处理往下走, 暂时该情况就不支持 */
378 if (hmac_m2s_spec_support_siso_switch_check(hal_device, hmac_device, WLAN_M2S_TRIGGER_MODE_BTCOEX) == OSAL_FALSE) {
379 oam_warning_log0(0, OAM_SF_COEX,
380 "{hmac_btcoex_m2s_switch_apply::2g5g dbac not support change to siso!}");
381 return OAL_FAIL;
382 }
383
384 ret = hmac_btcoex_m2s_switch_other(hal_device, &m2s_event);
385 if (ret != OAL_CONTINUE) {
386 return ret;
387 }
388
389 if (m2s_event != HAL_M2S_EVENT_BUTT) {
390 oam_warning_log2(0, OAM_SF_COEX,
391 "{hmac_btcoex_m2s_switch_apply:: excute c1 siso, m2s_event[%d]m2s_state[%d]!}", m2s_event,
392 hal_device->hal_m2s_fsm.oal_fsm.cur_state);
393
394 hmac_m2s_handle_event(hal_device, m2s_event, 0, OSAL_NULL);
395
396 hmac_btcoex_ps_stop_check_and_notify(hal_device);
397 }
398
399 /* 5.置m2s bitmap标记 */
400 get_hal_device_btcoex_m2s_mode_bitmap(hal_device) |= m2s_mode_mask;
401
402 return OAL_SUCC;
403 }
404
405 /*****************************************************************************
406 函 数 名 : hmac_btcoex_s2m_switch_apply
407 功能描述 : btcoex下特性业务申请切回mimo
408 (1)业务进入,申请切siso
409 (2)业务退出,申请切mimo,ldac和sco同时在,一个退出,也保持siso
410 (3)这里需要对业务做集中管理,比如ldac来的太频繁,要保护到切换完成
411 (4)保护标志可以在m2s完成里面清
412 (5)要保证中断是1和0 否则可能出现先切mimo的操作,不过应该没关系
413 *****************************************************************************/
hmac_btcoex_s2m_switch_apply(hal_to_dmac_device_stru * hal_device,osal_u8 m2s_mode_mask)414 osal_u32 hmac_btcoex_s2m_switch_apply(hal_to_dmac_device_stru *hal_device, osal_u8 m2s_mode_mask)
415 {
416 /* 申请回mimo,需要考虑复杂度,一方面要等待3s,另一方面需要判断当前所有a2dp和6slot标记都是0时,才回mimo */
417 hal_device_btcoex_mgr_stru *device_btcoex_mgr;
418
419 device_btcoex_mgr = &(hal_device->device_btcoex_mgr);
420
421 /* 0.可能此时已经是mimo状态,比如wifi切换到5g,此时直接返回即可,各业务清自己的s2m业务状态即可 */
422 /* 1.要申请回mimo,wait业务标记 bitmap */
423 get_hal_device_btcoex_s2m_wait_bitmap(hal_device) |= m2s_mode_mask;
424
425 /* 2.启动定时器 */
426 if (device_btcoex_mgr->s2m_resume_timer.is_registerd == OSAL_TRUE) {
427 frw_destroy_timer_entry(&(device_btcoex_mgr->s2m_resume_timer));
428 }
429 frw_create_timer_entry(&(device_btcoex_mgr->s2m_resume_timer), hmac_btcoex_s2m_resume_callback,
430 BTCOEX_S2M_RESUME_TIMEOUT, (osal_void *)hal_device, OSAL_FALSE);
431
432 oam_warning_log3(0, OAM_SF_COEX,
433 "{hmac_btcoex_s2m_switch_apply::m2s_mode_bitmap[%d]s2m_mode_bitmap[%d]wait_bitmap[%d]!}",
434 get_hal_device_btcoex_m2s_mode_bitmap(hal_device), get_hal_device_btcoex_s2m_mode_bitmap(hal_device),
435 get_hal_device_btcoex_s2m_wait_bitmap(hal_device));
436
437 return OAL_SUCC;
438 }
439 #endif
440
441 #ifdef _PRE_WLAN_FEATURE_BT_SUPPORT
442 /*****************************************************************************
443 函 数 名 : hmac_btcoex_s2m_siso_ap_resume_callback
444 功能描述 : siso ap申请回mimo定时器超时处理函数,只是为了音乐等切歌,或者电话等切换太快,尽量业务保持
445 *****************************************************************************/
hmac_btcoex_s2m_siso_ap_resume_callback(osal_void * arg)446 osal_u32 hmac_btcoex_s2m_siso_ap_resume_callback(osal_void *arg)
447 {
448 hal_btcoex_btble_status_stru *btble_status = OSAL_NULL;
449 hal_to_dmac_device_stru *hal_device = (hal_to_dmac_device_stru *)arg;
450
451 btble_status = hal_btcoex_btble_status();
452 /* 中断上半部会刷新状态值,状态值还是1就不处理,等下一个上半部0再次触发 */
453 if (btble_status->bt_status.bt_status.bt_ba == 0) {
454 #ifdef _PRE_WLAN_FEATURE_M2S
455 if (hmac_m2s_custom_switch_check(hal_device) == OSAL_TRUE) {
456 /* 清btcoex mode业务状态 */
457 get_hal_m2s_mode_tpye(hal_device) &= (~WLAN_M2S_TRIGGER_MODE_BTCOEX);
458
459 hmac_m2s_handle_event(hal_device, HAL_M2S_EVENT_CUSTOM_SISO_C1_TO_SISO_C0, 0, OSAL_NULL);
460 } else {
461 hmac_m2s_handle_event(hal_device, HAL_M2S_EVENT_BT_SISO_TO_MIMO, 0, OSAL_NULL);
462 }
463 #endif
464 /* 回到mimo/c0 siso的话,需要恢复ps机制 */
465 hmac_btcoex_ps_stop_check_and_notify(hal_device);
466
467 hal_device->device_btcoex_mgr.siso_ap_excute_on = OSAL_FALSE;
468
469 oam_warning_log2(0, OAM_SF_COEX,
470 "{hmac_btcoex_s2m_siso_ap_resume_callback::succ to mimo, m2s_bitmap[%d] m2s_mode[%d]!}",
471 get_hal_device_btcoex_m2s_mode_bitmap(hal_device), get_hal_m2s_mode_tpye(hal_device));
472 } else {
473 oam_warning_log3(0, OAM_SF_COEX,
474 "{hmac_btcoex_s2m_siso_ap_resume_callback::a2dp[%d]sco[%d]transfer[%d]delay to mimo wait for next time!}",
475 btble_status->bt_status.bt_status.bt_a2dp, btble_status->bt_status.bt_status.bt_sco,
476 btble_status->bt_status.bt_status.bt_transfer);
477 }
478
479 return OAL_SUCC;
480 }
481
hmac_ap_switch_siso(hal_to_dmac_device_stru * hal_device,hmac_device_stru * hmac_device)482 OSAL_STATIC osal_void hmac_ap_switch_siso(hal_to_dmac_device_stru *hal_device, hmac_device_stru *hmac_device)
483 {
484 hal_m2s_event_tpye_uint16 m2s_event = HAL_M2S_EVENT_BUTT;
485
486 /* 存在2G设备时候才切siso,最外层已经判断,这里肯定是存在,另外防止mss 回miso扫描,
487 bt申请切siso时先abort当次扫描,避免冲突 */
488 hmac_scan_abort(hmac_device);
489
490 /* 前面for循环过滤了dbdc 并发扫描 custom(当前是只有ap模式才会),此时只可能存在mss和rssi */
491 if (hal_m2s_check_command_on(hal_device) == OSAL_TRUE) {
492 /* 如果处于miso探测态,需要停止切换保护,并切c1 siso */
493 if (hal_device->hal_m2s_fsm.oal_fsm.cur_state == HAL_M2S_STATE_MISO) {
494 m2s_event = HAL_M2S_EVENT_BT_MISO_TO_SISO_C1;
495 } else {
496 m2s_event = HAL_M2S_EVENT_BT_SISO_C0_TO_SISO_C1;
497 }
498 #ifdef _PRE_WLAN_FEATURE_M2S
499 /* 切换保护功能关闭 */
500 get_hal_device_m2s_switch_prot(hal_device) = OSAL_FALSE;
501 #endif
502 /* 清业务标志 */
503 get_hal_m2s_mode_tpye(hal_device) &= (~WLAN_M2S_TRIGGER_MODE_COMMAND);
504 } else if (hal_m2s_check_rssi_on(hal_device) == OSAL_TRUE) { /* 如果只有低优先级的rssi,要判断是c0 miso 还是c1 miso */
505 m2s_event = HAL_M2S_EVENT_BT_MISO_TO_SISO_C1;
506
507 /* 清业务标志 */
508 get_hal_m2s_mode_tpye(hal_device) &= (~WLAN_M2S_TRIGGER_MODE_RSSI);
509 } else if (hal_m2s_check_btcoex_on(hal_device) == OSAL_TRUE) { /* 如果已经处于bt c1 siso状态的话,直接返回不处理即可 */
510 oam_warning_log1(0, OAM_SF_COEX,
511 "{hmac_btcoex_assoc_ap_check_process:: already c1 siso mode_stru[%d].}", get_hal_m2s_mode_tpye(hal_device));
512 } else {
513 m2s_event = HAL_M2S_EVENT_BT_MIMO_TO_SISO_C1;
514 }
515
516 if (m2s_event != HAL_M2S_EVENT_BUTT) {
517 hal_device->device_btcoex_mgr.siso_ap_excute_on = OSAL_TRUE;
518 #ifdef _PRE_WLAN_FEATURE_M2S
519 hmac_m2s_handle_event(hal_device, m2s_event, 0, OSAL_NULL);
520 #endif
521 hmac_btcoex_ps_stop_check_and_notify(hal_device);
522
523 oam_warning_log2(0, OAM_SF_COEX,
524 "{hmac_btcoex_assoc_ap_check_process:: need to switch c1 siso of siso ap event[%d]mode_stru[%d].}",
525 m2s_event, get_hal_m2s_mode_tpye(hal_device));
526 }
527 return;
528 }
529
530 /*****************************************************************************
531 函 数 名 : hmac_btcoex_assoc_ap_check_process
532 功能描述 : siso ap切换检查
533 *****************************************************************************/
hmac_btcoex_assoc_ap_check_process(hal_to_dmac_device_stru * hal_device)534 osal_void hmac_btcoex_assoc_ap_check_process(hal_to_dmac_device_stru *hal_device)
535 {
536 osal_u8 vap_idx, valid_vap_num;
537 osal_u8 mac_vap_id[WLAN_SERVICE_VAP_MAX_NUM_PER_DEVICE] = {0};
538 hmac_vap_stru *hmac_vap = OSAL_NULL;
539 oal_bool_enum_uint8 siso_need = OSAL_FALSE;
540 hmac_user_stru *hmac_user = OSAL_NULL;
541 hmac_device_stru *hmac_device = hmac_res_get_mac_dev_etc(0);
542
543 /* siso ap已经切换到了siso,不处理即可,一定要保证siso ap切换在之前完成 */
544 if (hal_device->device_btcoex_mgr.siso_ap_excute_on == OSAL_TRUE) {
545 return;
546 }
547
548 /* 找到满足要求的vap个数 */
549 valid_vap_num = hmac_btcoex_find_all_valid_sta_per_device(hal_device, mac_vap_id,
550 WLAN_SERVICE_VAP_MAX_NUM_PER_DEVICE);
551 /* 1.只考虑单sta模式 */
552 if (valid_vap_num != 1) {
553 return;
554 }
555
556 for (vap_idx = 0; vap_idx < valid_vap_num; vap_idx++) {
557 hmac_vap = (hmac_vap_stru *)mac_res_get_hmac_vap(mac_vap_id[vap_idx]);
558 if (hmac_vap == OSAL_NULL) {
559 oam_error_log1(0, OAM_SF_COEX, "{hmac_btcoex_assoc_ap_check_process::hmac_vap[%d] IS NULL.}",
560 mac_vap_id[vap_idx]);
561 return;
562 }
563
564 /* 不符合要求 */
565 if (mac_btcoex_check_valid_sta(hmac_vap) == OSAL_FALSE) {
566 continue;
567 }
568
569 /* STA模式获取user */
570 hmac_user = (hmac_user_stru *)mac_res_get_hmac_user_etc(hmac_vap->assoc_vap_id);
571 if (osal_unlikely(hmac_user == OSAL_NULL)) {
572 oam_warning_log1(0, OAM_SF_COEX,
573 "vap_id[%d] {hmac_btcoex_assoc_ap_check_process::hmac_user null.}", hmac_vap->vap_id);
574 continue;
575 }
576
577 /* 关联的是siso ap,需要申请到siso; 可能是dbdc入网,此时仍然不需要处理 */
578 if (hmac_user->user_num_spatial_stream == WLAN_SINGLE_NSS) {
579 siso_need = OSAL_TRUE;
580 }
581 }
582
583 /* 该切换方式可以要求苛刻一点;后续多vap之后,能切回来就可以 */
584 /* mimo状态下申请切换siso; dbdc会在前面返回; miso等暂时不考虑; 单独优先级,
585 无法直接调用hmac_btcoex_m2s_switch_apply接口 */
586 if (siso_need == OSAL_TRUE) {
587 hmac_ap_switch_siso(hal_device, hmac_device);
588 }
589 return;
590 }
591 #endif
592
593 #ifdef _PRE_WLAN_FEATURE_M2S
hmac_btcoex_m2s_back_to_mimo_check(hal_to_dmac_device_stru * hal_device)594 osal_bool hmac_btcoex_m2s_back_to_mimo_check(hal_to_dmac_device_stru *hal_device)
595 {
596 if (hal_m2s_check_btcoex_on(hal_device) == OSAL_TRUE) {
597 hmac_btcoex_s2m_allow_check(hal_device);
598 return OSAL_TRUE;
599 }
600 return OSAL_FALSE;
601 }
602
hmac_btcoex_m2s_back_to_mimo(hal_to_dmac_device_stru * hal_device,osal_u8 * m2s_mode_mask)603 osal_bool hmac_btcoex_m2s_back_to_mimo(hal_to_dmac_device_stru *hal_device, osal_u8 *m2s_mode_mask)
604 {
605 if (hmac_m2s_btcoex_need_switch_check(hal_device, m2s_mode_mask) != OSAL_TRUE) {
606 /* 1.c0 siso */
607 if (hal_device->cfg_cap_info->phy_chain == WLAN_PHY_CHAIN_ZERO) {
608 oam_warning_log0(0, OAM_SF_M2S,
609 "{hmac_btcoex_m2s_back_to_mimo:: need to switch siso c1 because of btcoex!}");
610 /* dbdc和spec都可能在此退出 */
611 get_hal_m2s_mode_tpye(hal_device) &= (~trigger_mode);
612 hmac_btcoex_m2s_switch_apply(hal_device, m2s_mode_mask);
613 } else {
614 /* 保持在c1 siso即可,清对应业务标记,增加维测,当前业务管理下出现此种情况属于异常,需要展开定位 */
615 oam_error_log1(0, OAM_SF_M2S,
616 "{hmac_btcoex_m2s_back_to_mimo:: btcoex apply but is already c1 siso, mode[%d]!}",
617 get_hal_m2s_mode_tpye(hal_device));
618 }
619 return OSAL_TRUE;
620 }
621 return OSAL_FALSE;
622 }
623
hmac_btcoex_m2s_update_hal_device(const hal_to_dmac_device_stru * hal_device,osal_u8 * m2s_mode_mask)624 osal_bool hmac_btcoex_m2s_update_hal_device(const hal_to_dmac_device_stru *hal_device, osal_u8 *m2s_mode_mask)
625 {
626 if (hmac_m2s_btcoex_need_switch_check(hal_device, &m2s_mode_mask) == OSAL_TRUE) {
627 /* btcoex业务在,直接切c1 siso即可 */
628 get_hal_m2s_mode_tpye(hal_device) &= (~WLAN_M2S_TRIGGER_MODE_SPEC);
629 /* 1.c0 siso */
630 if (hal_device->cfg_cap_info->phy_chain == WLAN_PHY_CHAIN_ZERO) {
631 oam_warning_log0(0, OAM_SF_M2S,
632 "{hmac_m2s_spec_update_hal_device_proc:: need to switch siso c1 because of btcoex!}");
633
634 hmac_btcoex_m2s_switch_apply(hal_device, m2s_mode_mask);
635 } else {
636 get_hal_m2s_mode_tpye(hal_device) |= WLAN_M2S_TRIGGER_MODE_BTCOEX;
637
638 /* 保持在c1 siso即可,清对应业务标记,增加维测,当前业务管理下出现此种情况属于异常,需要展开定位 */
639 oam_error_log1(0, OAM_SF_M2S,
640 "{hmac_m2s_spec_update_hal_device_proc:: btcoex apply but is already c1 siso, mode[%d]!}",
641 get_hal_m2s_mode_tpye(hal_device));
642 }
643 return OSAL_TRUE;
644 }
645 return OSAL_FALSE;
646 }
647
hmac_btcoex_m2s_choose_mimo_siso(hal_to_dmac_device_stru * hal_device)648 osal_void hmac_btcoex_m2s_choose_mimo_siso(hal_to_dmac_device_stru *hal_device)
649 {
650 if (hal_m2s_check_btcoex_on(hal_device) == OSAL_TRUE) {
651 hmac_btcoex_s2m_allow_check(hal_device);
652 }
653 /* sta入网,非dbdc场景下mimo是否需要切到c1 siso */
654 hmac_btcoex_m2s_allow_check(hal_device, hmac_vap);
655 }
656 #endif
657
hmac_btcoex_m2s_init(osal_void)658 osal_u32 hmac_btcoex_m2s_init(osal_void)
659 {
660 #ifdef _PRE_WLAN_FEATURE_M2S
661 hmac_feature_hook_register(HMAC_FHOOK_BTCOEX_M2S_M2S_ALLOW_CHECK, hmac_btcoex_m2s_allow_check);
662 hmac_feature_hook_register(HMAC_FHOOK_BTCOEX_M2S_BACK_MIMO_CHECK, hmac_btcoex_m2s_back_to_mimo_check);
663 hmac_feature_hook_register(HMAC_FHOOK_BTCOEX_M2S_BACK_MIMO, hmac_btcoex_m2s_back_to_mimo);
664 hmac_feature_hook_register(HMAC_FHOOK_BTCOEX_M2S_UPDATE_HAL_DEVICE, hmac_btcoex_m2s_update_hal_device);
665 hmac_feature_hook_register(HMAC_FHOOK_BTCOEX_M2S_CHOOSE_MIMO_SISO, hmac_btcoex_m2s_choose_mimo_siso);
666 #endif
667 return OAL_SUCC;
668 }
669
hmac_btcoex_m2s_deinit(osal_void)670 osal_void hmac_btcoex_m2s_deinit(osal_void)
671 {
672 #ifdef _PRE_WLAN_FEATURE_M2S
673 hmac_feature_hook_unregister(HMAC_FHOOK_BTCOEX_M2S_M2S_ALLOW_CHECK);
674 hmac_feature_hook_unregister(HMAC_FHOOK_BTCOEX_M2S_BACK_MIMO_CHECK);
675 hmac_feature_hook_unregister(HMAC_FHOOK_BTCOEX_M2S_BACK_MIMO);
676 hmac_feature_hook_unregister(HMAC_FHOOK_BTCOEX_M2S_UPDATE_HAL_DEVICE);
677 hmac_feature_hook_unregister(HMAC_FHOOK_BTCOEX_M2S_CHOOSE_MIMO_SISO);
678 hmac_feature_hook_unregister(HMAC_FHOOK_BTCOEX_M2S_S2M_ALLOW_CHECK);
679 #endif
680 return;
681 }
682
683 #ifdef __cplusplus
684 #if __cplusplus
685 }
686 #endif
687 #endif
688
689 #endif
690