• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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