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: PS处理
15 * Date: 2023-01-28 15:24
16 */
17
18 #ifndef __HMAC_BTCOEX_PS_C__
19 #define __HMAC_BTCOEX_PS_C__
20
21 #include "hmac_scan.h"
22 #include "hmac_fcs.h"
23 #include "msg_btcoex_rom.h"
24 #include "hmac_btcoex.h"
25 #include "frw_util_notifier.h"
26 #include "hmac_feature_interface.h"
27 #include "hmac_btcoex_ps.h"
28
29 #ifdef __cplusplus
30 #if __cplusplus
31 extern "C" {
32 #endif
33 #endif
34 #undef THIS_FILE_ID
35 #define THIS_FILE_ID DIAG_FILE_ID_WIFI_HOST_HMAC_BTCOEX_PS_C
36
37 #undef THIS_MOD_ID
38 #define THIS_MOD_ID DIAG_MOD_ID_WIFI_HOST
39 /*****************************************************************************
40 函 数 名 : hmac_btcoex_encap_preempt_frame
41 功能描述 : 根据指定的PS位封null data帧
42 *****************************************************************************/
hmac_btcoex_encap_preempt_frame(hmac_vap_stru * hmac_vap,const hmac_user_stru * hmac_user)43 OSAL_STATIC osal_void hmac_btcoex_encap_preempt_frame(hmac_vap_stru *hmac_vap, const hmac_user_stru *hmac_user)
44 {
45 hal_to_dmac_device_stru *hal_device = hmac_vap->hal_device;
46 osal_u32 qosnull_seq_num = 0;
47
48 if (hal_device == OSAL_NULL) {
49 oam_warning_log1(0, 0, "vap_id[%d] {hmac_btcoex_encap_preempt_frame:: HAL_DEVICE null}", hmac_vap->vap_id);
50 return;
51 }
52
53 /* 初始化dmac vap对应的preempt字段,包括写给硬件的premmpt帧地址和premmpt帧的参数 */
54 (osal_void)memset_s(&(hmac_btcoex_get_vap_info(hmac_vap)->null_preempt_param),
55 sizeof(hmac_vap_btcoex_null_preempt_stru), 0, sizeof(hmac_vap_btcoex_null_preempt_stru));
56
57 switch (hmac_btcoex_get_vap_info(hmac_vap)->all_abort_preempt_type) {
58 case HAL_BTCOEX_HW_POWSAVE_NOFRAME:
59 case HAL_BTCOEX_HW_POWSAVE_SELFCTS:
60 break;
61
62 case HAL_BTCOEX_HW_POWSAVE_NULLDATA: {
63 /* 填写帧头,其中from ds为1,to ds为0,ps=1 因此frame control的第二个字节为12 */
64 mac_ieee80211_frame_stru *mac_header = (mac_ieee80211_frame_stru *) \
65 hmac_btcoex_get_vap_info(hmac_vap)->null_preempt_param.null_qosnull_frame;
66 mac_null_data_encap(hmac_btcoex_get_vap_info(hmac_vap)->null_preempt_param.null_qosnull_frame,
67 WLAN_PROTOCOL_VERSION | WLAN_FC0_TYPE_DATA | WLAN_FC0_SUBTYPE_NODATA | 0x1100,
68 hmac_user->user_mac_addr,
69 mac_mib_get_station_id(hmac_vap));
70
71 /* 22表示seq num位 */
72 hmac_btcoex_get_vap_info(hmac_vap)->null_preempt_param.null_qosnull_frame[22] = 0;
73 /* 23表示frag位 */
74 hmac_btcoex_get_vap_info(hmac_vap)->null_preempt_param.null_qosnull_frame[23] = 0;
75 mac_header->frame_control.power_mgmt = 1;
76 break;
77 }
78
79 case HAL_BTCOEX_HW_POWSAVE_QOSNULL: {
80 hmac_btcoex_qosnull_frame_stru *mac_header = (hmac_btcoex_qosnull_frame_stru *) \
81 hmac_btcoex_get_vap_info(hmac_vap)->null_preempt_param.null_qosnull_frame;
82 mac_null_data_encap(hmac_btcoex_get_vap_info(hmac_vap)->null_preempt_param.null_qosnull_frame,
83 WLAN_PROTOCOL_VERSION | WLAN_FC0_TYPE_DATA | WLAN_FC0_SUBTYPE_QOS_NULL |
84 0x1100, hmac_user->user_mac_addr,
85 mac_mib_get_station_id(hmac_vap));
86
87 mac_header->frame_control.power_mgmt = 1;
88 mac_header->qc_tid = WLAN_TIDNO_COEX_QOSNULL;
89 mac_header->qc_eosp = 0;
90
91 /* 设置seq的序列号 */
92 hal_get_btcoex_abort_qos_null_seq_num(hal_device, &qosnull_seq_num);
93 mac_header->sc_seq_num = (osal_u16)(qosnull_seq_num + 1);
94 hal_set_btcoex_abort_qos_null_seq_num(hal_device, mac_header->sc_seq_num);
95
96 /* 协议规定单播的QOS NULL DATA只允许normal ack 共存里面要设置0是对方会回ack */
97 mac_header->qc_ack_polocy = WLAN_TX_NORMAL_ACK;
98 break;
99 }
100
101 default:
102 oam_error_log2(0, OAM_SF_COEX, "vap_id[%d] {hmac_btcoex_encap_preempt_frame::sw_preempt_type[%d] error}",
103 hmac_vap->vap_id, hmac_btcoex_get_vap_info(hmac_vap)->all_abort_preempt_type);
104 return;
105 }
106
107 oam_warning_log2(0, OAM_SF_COEX, "vap_id[%d] {hmac_btcoex_encap_preempt_frame::sw_preempt_type[%d]!}",
108 hmac_vap->vap_id, hmac_btcoex_get_vap_info(hmac_vap)->all_abort_preempt_type);
109 }
110
111 /*****************************************************************************
112 函 数 名 : hmac_btcoex_set_preempt_frame_param
113 功能描述 : 配置preempt帧的参数类型,注意pst_mac_user要保证不为空
114 *****************************************************************************/
hmac_btcoex_set_preempt_frame_param(hmac_vap_stru * hmac_vap,const hmac_user_stru * hmac_user)115 OSAL_STATIC osal_void hmac_btcoex_set_preempt_frame_param(hmac_vap_stru *hmac_vap, const hmac_user_stru *hmac_user)
116 {
117 osal_u16 preempt_param_val = 0;
118
119 switch (hmac_btcoex_get_vap_info(hmac_vap)->all_abort_preempt_type) {
120 case HAL_BTCOEX_HW_POWSAVE_NOFRAME:
121 /* 增加接口通用性,NOFRAME直接返回,写对应寄存器类型为0即可 */
122 return;
123
124 case HAL_BTCOEX_HW_POWSAVE_SELFCTS:
125 break;
126
127 case HAL_BTCOEX_HW_POWSAVE_NULLDATA:
128 hmac_btcoex_get_vap_info(hmac_vap)->null_preempt_param.cfg_coex_tx_peer_index = hmac_user->lut_index;
129
130 /* null配置peer idx */
131 preempt_param_val = preempt_param_val |
132 hmac_btcoex_get_vap_info(hmac_vap)->null_preempt_param.cfg_coex_tx_peer_index;
133 break;
134
135 case HAL_BTCOEX_HW_POWSAVE_QOSNULL:
136 hmac_btcoex_get_vap_info(hmac_vap)->null_preempt_param.cfg_coex_tx_peer_index = hmac_user->lut_index;
137 hmac_btcoex_get_vap_info(hmac_vap)->null_preempt_param.cfg_coex_tx_qos_null_tid =
138 WLAN_TIDNO_COEX_QOSNULL;
139
140 /* qos null需要配置tid */
141 preempt_param_val = preempt_param_val | /* 8表示左移8位以取cfg_coex_tx_qos_null_tidde的低8位 */
142 (hmac_btcoex_get_vap_info(hmac_vap)->null_preempt_param.cfg_coex_tx_qos_null_tid << 8);
143 /* qos null配置peer idx */
144 preempt_param_val = preempt_param_val |
145 hmac_btcoex_get_vap_info(hmac_vap)->null_preempt_param.cfg_coex_tx_peer_index;
146 break;
147
148 default:
149 oam_error_log2(0, OAM_SF_COEX,
150 "vap_id[%d] {hmac_btcoex_set_preempt_frame_param::sw_preempt_type[%d] error}", hmac_vap->vap_id,
151 hmac_btcoex_get_vap_info(hmac_vap)->all_abort_preempt_type);
152 return;
153 }
154
155 /* 03的self cts的时候也需要vap index; 02看软件开哪些vap里从0~4找,最先找到的vap的mac地址作为self cts的地址 */
156 hmac_btcoex_get_vap_info(hmac_vap)->null_preempt_param.cfg_coex_tx_vap_index = hmac_vap->hal_vap->vap_id;
157
158 /* 三类帧都需要配置vap index, self cts的时候也需要vap index(pilot才会做,软件先写好,后续注意验证) */
159 preempt_param_val = preempt_param_val |
160 (hmac_btcoex_get_vap_info(hmac_vap)->null_preempt_param.cfg_coex_tx_vap_index << 12); /* 12表示左移12位 */
161
162 hal_set_btcoex_abort_preempt_frame_param(preempt_param_val);
163
164 oam_warning_log3(0, OAM_SF_COEX,
165 "vap_id[%d] {hmac_btcoex_set_preempt_frame_param::SUCC sw_preempt_type[%d] preempt_param_val[%d]!}",
166 hmac_vap->vap_id, hmac_btcoex_get_vap_info(hmac_vap)->all_abort_preempt_type, preempt_param_val);
167 }
168
169 /*****************************************************************************
170 函 数 名 : hmac_btcoex_init_preempt
171 功能描述 : preempt机制初始化
172 1.单VAP的话, AP和STA三种帧都可以发送,ap和sta都默认self-cts, 后续根据调试情况来调整
173 2.只要多个vap的都用self cts,sta和p2p gc同存也要用self cts,
174 因为发null帧只能让一个ap不给我们发帧;
175 *****************************************************************************/
hmac_btcoex_init_preempt(hmac_vap_stru * hmac_vap,const hmac_user_stru * hmac_user,osal_u8 preempt_enable)176 osal_void hmac_btcoex_init_preempt(hmac_vap_stru *hmac_vap, const hmac_user_stru *hmac_user, osal_u8 preempt_enable)
177 {
178 hmac_vap_btcoex_stru *hmac_vap_btcoex = hmac_btcoex_get_vap_info(hmac_vap);
179 osal_s32 ret;
180
181 if (hmac_vap_btcoex == OSAL_NULL) {
182 oam_error_log0(0, OAM_SF_CFG, "hmac_btcoex_init_preempt::hmac_vap_btcoex is null.");
183 return;
184 }
185
186 /* 初始化为不发preempt帧 */
187 if (preempt_enable == OSAL_FALSE) {
188 hmac_vap_btcoex->all_abort_preempt_type = HAL_BTCOEX_HW_POWSAVE_NOFRAME;
189 } else {
190 hmac_vap_btcoex->all_abort_preempt_type = HAL_BTCOEX_HW_POWSAVE_NULLDATA;
191 }
192
193 /* encap preempt帧 */
194 hmac_btcoex_encap_preempt_frame(hmac_vap, hmac_user);
195 /* 配置premmpt帧的参数 */
196 hmac_btcoex_set_preempt_frame_param(hmac_vap, hmac_user);
197 /* 写入null qos null帧地址 */
198 if ((hmac_vap_btcoex->all_abort_preempt_type == HAL_BTCOEX_HW_POWSAVE_NULLDATA) ||
199 (hmac_vap_btcoex->all_abort_preempt_type == HAL_BTCOEX_HW_POWSAVE_QOSNULL)) {
200 frw_msg msg_info = {0};
201 btcoex_null_preempt_stru btcoex_null_preempt;
202
203 (osal_void)memcpy_s(btcoex_null_preempt.null_qosnull_frame, WLAN_COEX_PKT_LEN,
204 hmac_vap_btcoex->null_preempt_param.null_qosnull_frame, WLAN_COEX_PKT_LEN);
205 btcoex_null_preempt.cfg_coex_tx_vap_index = hmac_vap_btcoex->null_preempt_param.cfg_coex_tx_vap_index;
206 btcoex_null_preempt.cfg_coex_tx_qos_null_tid = hmac_vap_btcoex->null_preempt_param.cfg_coex_tx_qos_null_tid;
207 btcoex_null_preempt.cfg_coex_tx_peer_index = hmac_vap_btcoex->null_preempt_param.cfg_coex_tx_peer_index;
208
209 frw_msg_init((osal_u8 *)&btcoex_null_preempt, sizeof(btcoex_null_preempt_stru), OSAL_NULL, 0, &msg_info);
210 ret = frw_send_msg_to_device(0, WLAN_MSG_H2D_C_CFG_SET_BTCOEX_ABORT_NULL, &msg_info, OSAL_TRUE);
211 if (ret != OAL_SUCC) {
212 oam_warning_log1(0, OAM_SF_CFG, "hmac_btcoex_init_preempt:send btcoex abort null to device fail[%d]", ret);
213 }
214 }
215
216 /* 6. 配置芯片premmpt类型 */
217 hal_set_btcoex_tx_abort_preempt_type(hmac_vap_btcoex->all_abort_preempt_type);
218 }
219
220 /*****************************************************************************
221 函 数 名 : hmac_btcoex_update_ps_frame_param
222 功能描述 : 更新ps相关参数
223 *****************************************************************************/
hmac_btcoex_update_ps_frame_param(hal_to_dmac_device_stru * hal_device,hal_chip_stru * hal_chip,mac_btcoex_ps_frame_info_stru * ps_param)224 static osal_void hmac_btcoex_update_ps_frame_param(hal_to_dmac_device_stru *hal_device,
225 hal_chip_stru *hal_chip, mac_btcoex_ps_frame_info_stru *ps_param)
226 {
227 unref_param(hal_chip);
228
229 if (hal_device->btcoex_sw_preempt.coex_pri_forbit == OSAL_FALSE) {
230 ps_param->protect_coex_pri = hal_device->btcoex_sw_preempt.protect_coex_pri;
231 } else {
232 ps_param->protect_coex_pri = HAL_FCS_PROTECT_COEX_PRI_NORMAL;
233 }
234
235 /* 这里等效fcs_service_type条件判断,这个变量耦合太多,建议删除 */
236 /* 非self-CTS duration参数也会统一设置但实际不会使用 */
237 if (hal_btcoex_btble_status()->bt_status.bt_status.bt_ldac == OSAL_TRUE) {
238 ps_param->duration = MAC_FCS_CTS_MAX_BTCOEX_LDAC_DURATION;
239 ps_param->timeout = MAC_FCS_DEFAULT_PROTECT_TIME_OUT;
240 ps_param->wait_timeout = MAC_ONE_PACKET_TIME_OUT;
241 } else {
242 ps_param->duration = MAC_FCS_CTS_MAX_BTCOEX_NOR_DURATION;
243 ps_param->timeout = MAC_FCS_DEFAULT_PROTECT_TIME_OUT3;
244 ps_param->wait_timeout = MAC_ONE_PACKET_TIME_OUT3;
245 }
246 }
247
248 /*****************************************************************************
249 函 数 名 : hmac_btcoex_set_ps_flag
250 功能描述 : BTCOEX同步ps状态标志给device侧
251 *****************************************************************************/
hmac_btcoex_set_ps_flag(hal_to_dmac_device_stru * hal_device)252 osal_void hmac_btcoex_set_ps_flag(hal_to_dmac_device_stru *hal_device)
253 {
254 osal_s32 ret;
255 mac_btcoex_ps_flag_info_stru ps_flags = {0};
256 frw_msg msg = {0};
257
258 if (hal_device == OSAL_NULL) {
259 return;
260 }
261
262 if ((hal_device->btcoex_sw_preempt.ps_stop == OSAL_TRUE) ||
263 (hal_device->btcoex_sw_preempt.sw_preempt_mode.ps_on == OSAL_FALSE) ||
264 (hal_device->btcoex_sw_preempt.ps_pause == OSAL_TRUE)) {
265 ps_flags.one_pkt_en = OSAL_FALSE;
266 } else {
267 ps_flags.one_pkt_en = OSAL_TRUE;
268 }
269
270 ps_flags.dis_abort = OSAL_TRUE;
271 ps_flags.reply_cts = hal_device->btcoex_sw_preempt.sw_preempt_mode.reply_cts;
272 ps_flags.rsp_frame_ps = hal_device->btcoex_sw_preempt.sw_preempt_mode.rsp_frame_ps;
273
274 oam_info_log3(0, OAM_SF_COEX, "{hmac_btcoex_set_ps_flag:: enable=%d, cts=%d, rsp_ps=%d}",
275 ps_flags.one_pkt_en, ps_flags.reply_cts, ps_flags.rsp_frame_ps);
276
277 frw_msg_init((osal_u8 *)&ps_flags, sizeof(ps_flags), OSAL_NULL, 0, &msg);
278 ret = frw_send_msg_to_device(0, WLAN_MSG_H2D_C_CFG_SET_BTCOEX_PS_FLAG, &msg, OSAL_TRUE);
279 if (ret != OAL_SUCC) {
280 oam_error_log1(0, OAM_SF_COEX, "{hmac_btcoex_set_ps_flag send msg fail, ret=%d}", ret);
281 }
282 return;
283 }
284
285 /*****************************************************************************
286 函 数 名 : hmac_btcoex_et_vap_ps_frame
287 功能描述 : BTCOEX同步ps frame内容给device侧
288 *****************************************************************************/
hmac_btcoex_set_vap_ps_frame(hmac_vap_stru * hmac_vap,osal_u32 enable)289 osal_void hmac_btcoex_set_vap_ps_frame(hmac_vap_stru *hmac_vap, osal_u32 enable)
290 {
291 osal_s32 ret;
292 mac_btcoex_ps_frame_info_stru ps_frame = {0};
293 frw_msg msg = {0};
294 hal_one_packet_cfg_stru one_packet_cfg_tmp = {0};
295 hmac_user_stru *hmac_user = OSAL_NULL;
296 hal_chip_stru *hal_chip = hal_get_chip_stru();
297 hal_to_dmac_device_stru *hal_device = OSAL_NULL;
298
299 unref_param(enable);
300 if ((hmac_vap == OSAL_NULL) || (hmac_vap->hal_vap == OSAL_NULL) ||
301 (hal_chip == OSAL_NULL) || (hmac_vap->hal_device == OSAL_NULL)) {
302 oam_error_log0(0, OAM_SF_COEX, "{hmac_btcoex_set_vap_ps_frame:: null pointer}");
303 return;
304 }
305
306 hal_device = hmac_vap->hal_device;
307
308 /* user_nums只能表示接入。最好判断设备已经接入并完成认证 */
309 ps_frame.is_vap_param = OAL_TRUE;
310 ps_frame.is_valid = OAL_TRUE;
311 if (!is_sta(hmac_vap) || (hmac_vap->user_nums == 0)) {
312 ps_frame.is_valid = OAL_FALSE;
313 }
314
315 hmac_user = (hmac_user_stru *)mac_res_get_hmac_user_etc(hmac_vap->assoc_vap_id);
316 if (hmac_user == OSAL_NULL) {
317 ps_frame.is_valid = OAL_FALSE;
318 }
319
320 if (ps_frame.is_valid == OAL_TRUE) {
321 ps_frame.protect_cnt = mac_fcs_get_protect_cnt(hmac_vap);
322 ps_frame.cfg_one_pkt_tx_vap_index = hmac_vap->hal_vap->vap_id;
323 ps_frame.cfg_one_pkt_tx_peer_index = hmac_user->lut_index;
324
325 /* data_rate和tx_mode信息最终方案需要由算法模块提供 */
326 ps_frame.tx_data_rate = hmac_fcs_set_prot_datarate(hmac_vap);
327 one_packet_cfg_tmp.tx_data_rate = ps_frame.tx_data_rate;
328 ps_frame.tx_mode = hmac_fcs_get_prot_mode(hmac_vap, &one_packet_cfg_tmp);
329
330 if (hmac_btcoex_get_vap_info(hmac_vap)->ps_type == HAL_FCS_PROTECT_TYPE_SELF_CTS) {
331 ps_frame.protect_type = HAL_FCS_PROTECT_TYPE_SELF_CTS;
332 } else {
333 ps_frame.protect_type = HAL_FCS_PROTECT_TYPE_NULL_DATA;
334 }
335 }
336
337 // device相关的ps frame参数
338 ps_frame.is_dev_param = OAL_TRUE;
339 hmac_btcoex_update_ps_frame_param(hal_device, hal_chip, &ps_frame);
340
341 oam_info_log3(0, OAM_SF_COEX, "{hmac_btcoex_set_vap_ps_frame:: valid=%d, vap_id=%d, lut_index=%d}",
342 ps_frame.is_valid, ps_frame.cfg_one_pkt_tx_vap_index, ps_frame.cfg_one_pkt_tx_peer_index);
343
344 frw_msg_init((osal_u8 *)&ps_frame, sizeof(ps_frame), OSAL_NULL, 0, &msg);
345 ret = frw_send_msg_to_device(hmac_vap->vap_id, WLAN_MSG_H2D_C_CFG_SET_BTCOEX_PS_FRAME, &msg, OSAL_TRUE);
346 if (ret != OAL_SUCC) {
347 oam_error_log1(0, OAM_SF_COEX, "{hmac_btcoex_set_vap_ps_frame send msg fail, ret=%d}", ret);
348 }
349 }
350
351 /*****************************************************************************
352 函 数 名 : hmac_btcoex_set_dev_ps_frame
353 功能描述 : BTCOEX同步ps frame内容给device侧
354 *****************************************************************************/
hmac_btcoex_set_dev_ps_frame(hal_to_dmac_device_stru * hal_device)355 osal_void hmac_btcoex_set_dev_ps_frame(hal_to_dmac_device_stru *hal_device)
356 {
357 osal_s32 ret;
358 hal_chip_stru *hal_chip = hal_get_chip_stru();
359 mac_btcoex_ps_frame_info_stru ps_frame = {0};
360 frw_msg msg = {0};
361
362 // device相关的ps frame参数
363 ps_frame.is_dev_param = OAL_TRUE;
364 hmac_btcoex_update_ps_frame_param(hal_device, hal_chip, &ps_frame);
365
366 oam_info_log2(0, OAM_SF_COEX, "{hmac_btcoex_set_dev_ps_frame:: coex_pri=%d duration=%d}",
367 ps_frame.protect_coex_pri, ps_frame.duration);
368
369 frw_msg_init((osal_u8 *)&ps_frame, sizeof(ps_frame), OSAL_NULL, 0, &msg);
370 ret = frw_send_msg_to_device(0, WLAN_MSG_H2D_C_CFG_SET_BTCOEX_PS_FRAME, &msg, OSAL_TRUE);
371 if (ret != OAL_SUCC) {
372 oam_error_log1(0, OAM_SF_COEX, "{hmac_btcoex_set_dev_ps_frame send msg fail, ret=%d}",
373 ret);
374 }
375 }
376
377 /*****************************************************************************
378 函 数 名 : hmac_btcoex_switch_ps
379 功能描述 : BTCOEX通知device进行ps状态切换
380 *****************************************************************************/
hmac_btcoex_switch_ps(hal_to_dmac_device_stru * hal_device,hmac_btcoex_ps_switch_enum_uint8 status)381 OSAL_STATIC osal_void hmac_btcoex_switch_ps(hal_to_dmac_device_stru *hal_device,
382 hmac_btcoex_ps_switch_enum_uint8 status)
383 {
384 osal_s32 ret;
385 frw_msg msg = {0};
386
387 unref_param(hal_device);
388 frw_msg_init((osal_u8 *)&status, sizeof(status), OSAL_NULL, 0, &msg);
389 ret = frw_send_msg_to_device(0, WLAN_MSG_H2D_C_CFG_BTCOEX_SIWTCH_PS, &msg, OSAL_TRUE);
390 if (ret != OAL_SUCC) {
391 oam_error_log2(0, OAM_SF_COEX, "{hmac_btcoex_switch_ps send msg fail, status=%u ret=%d}",
392 status, ret);
393 }
394
395 return;
396 }
397
398 /*****************************************************************************
399 函 数 名 : hmac_btcoex_preempt_sub_type_notify
400 功能描述 : 外部触发,切换sw preempt sub type
401 *****************************************************************************/
hmac_btcoex_set_sw_preempt_type(hal_to_dmac_device_stru * hal_device,hal_coex_sw_preempt_subtype_uint8 type)402 OSAL_STATIC osal_u32 hmac_btcoex_set_sw_preempt_type(hal_to_dmac_device_stru *hal_device,
403 hal_coex_sw_preempt_subtype_uint8 type)
404 {
405 hal_device->btcoex_sw_preempt.sw_preempt_type = type;
406
407 if ((type == HAL_BTCOEX_SW_POWSAVE_SCAN_BEGIN) ||
408 (type == HAL_BTCOEX_SW_POWSAVE_SCAN_WAIT) ||
409 (type == HAL_BTCOEX_SW_POWSAVE_SCAN_ABORT) ||
410 (type == HAL_BTCOEX_SW_POWSAVE_SCAN_END)) {
411 /* 通知device侧ps状态被打断 */
412 hmac_btcoex_switch_ps(hal_device, HMAC_BTCOEX_PS_ABORT);
413 }
414
415 return OSAL_SUCCESS;
416 }
417
418 /*****************************************************************************
419 函 数 名 : hmac_btcoex_ps_timeout_update_time
420 功能描述 : ps机制更新timeout超时时间,音乐数传,page inquiry下超时时间配置需要不同
421 *****************************************************************************/
hmac_btcoex_ps_timeout_update_time(hal_to_dmac_device_stru * hal_device)422 osal_void hmac_btcoex_ps_timeout_update_time(hal_to_dmac_device_stru *hal_device)
423 {
424 hal_btcoex_ps_status_enum_uint8 ps_status = HAL_BTCOEX_PS_STATUE_BUTT;
425
426 /* 获取当前ps业务状态 */
427 hal_btcoex_get_ps_service_status(hal_device, &ps_status);
428
429 switch (ps_status) {
430 case HAL_BTCOEX_PS_STATUE_ACL:
431 hal_device->btcoex_sw_preempt.timeout_ms = BTCOEX_POWSAVE_TIMEOUT_LEVEL0;
432 break;
433
434 case HAL_BTCOEX_PS_STATUE_LDAC:
435 case HAL_BTCOEX_PS_STATUE_LDAC_ACL:
436 case HAL_BTCOEX_PS_STATUE_PAGE_INQ:
437 hal_device->btcoex_sw_preempt.timeout_ms = BTCOEX_POWSAVE_TIMEOUT_LEVEL1;
438 break;
439
440 case HAL_BTCOEX_PS_STATUE_PAGE_ACL:
441 case HAL_BTCOEX_PS_STATUE_LDAC_PAGE:
442 case HAL_BTCOEX_PS_STATUE_TRIPLE:
443 hal_device->btcoex_sw_preempt.timeout_ms = BTCOEX_POWSAVE_TIMEOUT_LEVEL2;
444 break;
445
446 default:
447 oam_warning_log1(0, OAM_SF_COEX, "{hmac_btcoex_ps_timeout_update_time::ps_status[%d] error.}",
448 ps_status);
449 }
450 }
451
452 /*****************************************************************************
453 函 数 名 : hmac_btcoex_ps_stop_check_and_notify
454 功能描述 : 获取ps是否禁止标记
455 (1)dbac启动和停止 (2)单ap模式 (3)sco电话启动和结束 (4)5G工作
456 其中单ap模式,5g工作逻辑在关联和去关联时候也要单独判断
457 *****************************************************************************/
hmac_btcoex_ps_stop_check_and_notify(hal_to_dmac_device_stru * hal_device)458 osal_void hmac_btcoex_ps_stop_check_and_notify(hal_to_dmac_device_stru *hal_device)
459 {
460 hmac_device_stru *hmac_device = hmac_res_get_mac_dev_etc(0);
461 hmac_vap_stru *hmac_vap = OSAL_NULL;
462 oal_bool_enum_uint8 sco_status = OSAL_FALSE;
463 oal_bool_enum_uint8 ps_stop = OSAL_FALSE; /* 初始是打开ps */
464 osal_u8 vap_idx, up_vap_num, up_ap_num, up_sta_num, up_2g_num, up_5g_num;
465 osal_u8 mac_vap_id[WLAN_SERVICE_VAP_MAX_NUM_PER_DEVICE] = {0};
466
467 up_ap_num = up_sta_num = up_2g_num = up_5g_num = 0;
468
469 if (hal_device == OSAL_NULL) {
470 oam_warning_log0(0, OAM_SF_COEX, "{hmac_btcoex_ps_stop_check_and_notify: hal_device is null ptr.}");
471 return;
472 }
473
474 /* 1.电话场景 */
475 hal_btcoex_get_bt_sco_status(hal_device, &sco_status);
476 if ((sco_status == OSAL_TRUE) || (mac_is_dbac_running(hmac_device) == OSAL_TRUE)) {
477 ps_stop = OSAL_TRUE;
478 }
479
480 /* Hal Device处于work状态vap个数 */
481 up_vap_num = hal_device_find_all_up_vap(hal_device, mac_vap_id, WLAN_SERVICE_VAP_MAX_NUM_PER_DEVICE);
482 for (vap_idx = 0; vap_idx < up_vap_num; vap_idx++) {
483 hmac_vap = (hmac_vap_stru *)mac_res_get_hmac_vap(mac_vap_id[vap_idx]);
484 if (hmac_vap == OSAL_NULL) {
485 continue;
486 }
487
488 /* 关联用户数不为0 */
489 if (hmac_vap->user_nums != 0) {
490 (is_ap(hmac_vap)) ? (up_ap_num++) : (up_sta_num++);
491 (mac_btcoex_check_valid_vap(hmac_vap) == OSAL_TRUE) ? (up_2g_num++) : (up_5g_num++);
492 }
493 }
494
495 /* 3.单ap模式 4.5g模式 5.siso c1 */
496 if ((up_ap_num != 0 && up_sta_num == 0) || (up_5g_num != 0 && up_2g_num == 0) ||
497 ((hal_device->cfg_cap_info->phy_chain == WLAN_PHY_CHAIN_ONE) &&
498 (hal_device->hal_m2s_fsm.oal_fsm.cur_state == HAL_M2S_STATE_SISO))) {
499 ps_stop = OSAL_TRUE;
500 }
501
502 /* 刷新ps能力 */
503 hal_device->btcoex_sw_preempt.ps_stop = ps_stop;
504 hmac_btcoex_set_ps_flag(hal_device);
505
506 hal_set_btcoex_wifi_status_notify(HAL_BTCOEX_WIFI_STATE_PS_STOP, (osal_u32)ps_stop);
507
508 hal_coex_sw_irq_set(HAL_COEX_SW_IRQ_BT);
509
510 oam_warning_log_alter(0, OAM_SF_COEX,
511 "{hmac_btcoex_ps_stop_check_and_notify::ap[%d]sta[%d]5g[%d]2g[%d]sco[%d]dbac[%d]chain[%d]m2s[%d] ps_stop[%d]!}",
512 /* 9代表9后面有9个待打印参数 */
513 9, up_ap_num, up_sta_num, up_5g_num, up_2g_num, sco_status,
514 mac_is_dbac_running(hmac_device), hal_device->cfg_cap_info->phy_chain,
515 hal_device->hal_m2s_fsm.oal_fsm.cur_state,
516 hal_device->btcoex_sw_preempt.ps_stop);
517 }
518
519 /*****************************************************************************
520 函 数 名 : hmac_btcoex_ps_pause_check_and_notify
521 功能描述 : 获取ps是否暂停标记,单wifi侧
522 (1)漫游过程中需要暂停
523 *****************************************************************************/
hmac_btcoex_ps_pause_check_and_notify(osal_void * notify_data)524 OSAL_STATIC osal_bool hmac_btcoex_ps_pause_check_and_notify(osal_void *notify_data)
525 {
526 hmac_vap_stru *hmac_vap = OSAL_NULL;
527 oal_bool_enum_uint8 ps_pause = OSAL_FALSE; /* 初始是不暂停ps */
528 hal_to_dmac_device_stru *hal_device = ((hmac_vap_stru *)notify_data)->hal_device;
529 osal_u8 vap_idx;
530 osal_u8 up_vap_num;
531 osal_u8 mac_vap_id[WLAN_SERVICE_VAP_MAX_NUM_PER_DEVICE] = {0};
532
533 /* Hal Device处于work状态vap个数 */
534 up_vap_num = hal_device_find_all_up_vap(hal_device, mac_vap_id, WLAN_SERVICE_VAP_MAX_NUM_PER_DEVICE);
535 for (vap_idx = 0; vap_idx < up_vap_num; vap_idx++) {
536 hmac_vap = (hmac_vap_stru *)mac_res_get_hmac_vap(mac_vap_id[vap_idx]);
537 if (hmac_vap == OSAL_NULL) {
538 continue;
539 }
540
541 /* 1.处于漫游过程中需要暂停ps */
542 if (hmac_vap->vap_state == MAC_VAP_STATE_ROAMING) {
543 ps_pause = OSAL_TRUE;
544 }
545 }
546
547 /* 刷新ps能力 */
548 hal_device->btcoex_sw_preempt.ps_pause = ps_pause;
549 hmac_btcoex_set_ps_flag(hal_device);
550
551 oam_warning_log2(0, OAM_SF_COEX,
552 "{hmac_btcoex_ps_pause_check_and_notify::ps_pause[%d]up_vap_num[%d]!}",
553 hal_device->btcoex_sw_preempt.ps_pause, up_vap_num);
554 return OSAL_TRUE;
555 }
556
hmac_btcoex_pow_save_scan_state(hmac_device_stru * hmac_device,hal_to_dmac_device_stru * h2d_device)557 OSAL_STATIC osal_void hmac_btcoex_pow_save_scan_state(hmac_device_stru *hmac_device,
558 hal_to_dmac_device_stru *h2d_device)
559 {
560 switch (h2d_device->btcoex_sw_preempt.sw_preempt_type) {
561 case HAL_BTCOEX_SW_POWSAVE_SCAN_BEGIN:
562 /* 如果扫描一开始被ps打断,此时ps来恢复继续扫描 */
563 hmac_scan_begin(hmac_device, h2d_device);
564 break;
565
566 case HAL_BTCOEX_SW_POWSAVE_SCAN_WAIT:
567 /* 如果扫描临时回home channel继续工作被打断,此时ps来恢复继续回home channel工作 */
568 hmac_scan_switch_home_channel_work(hmac_device, h2d_device);
569 oam_warning_log0(0, OAM_SF_COEX,
570 "{hmac_btcoex_pow_save_scan_state::hmac_scan_switch_home_channel_work start.}");
571 break;
572
573 case HAL_BTCOEX_SW_POWSAVE_SCAN_END:
574 /* 如果扫描结束被打断,此时ps来恢复继续扫描 */
575 oam_warning_log0(0, OAM_SF_COEX,
576 "{hmac_btcoex_pow_save_scan_state::hmac_scan_handle_switch_channel_back start.}");
577 hmac_scan_prepare_end(hmac_device, h2d_device);
578 break;
579
580 case HAL_BTCOEX_SW_POWSAVE_SCAN_ABORT:
581 /* abort状态一定是,在save状态时候scan baort,类似于ps=0要恢复ps=1的配置,因为scan
582 * abort提前resume了,此处不需要处理 */
583 oam_warning_log0(0, OAM_SF_COEX, "{hmac_btcoex_pow_save_scan_state::scan is already abort and resume.}");
584 break;
585
586 case HAL_BTCOEX_SW_POWSAVE_IDLE:
587 /* 可能是状态1事件没有及时处理下半部,又来了状态0,此时处于扫描,恢复交给扫描来做即可 */
588 oam_warning_log0(0, OAM_SF_COEX, "{hmac_btcoex_pow_save_scan_state::HAL_BTCOEX_SW_POWSAVE_IDLE.}");
589 break;
590
591 case HAL_BTCOEX_SW_POWSAVE_WORK:
592 /* 如果扫描期间来了1又来了0,此时恢复交给扫描自己恢复,ps=0不做处理 */
593 break;
594
595 default:
596 oam_warning_log1(0, OAM_SF_COEX, "{hmac_btcoex_pow_save_scan_state::sw_preempt_type[%d] error.}",
597 h2d_device->btcoex_sw_preempt.sw_preempt_type);
598 }
599
600 return;
601 }
602
hmac_btcoex_pow_save_other_state(hal_to_dmac_device_stru * h2d_device)603 OSAL_STATIC osal_void hmac_btcoex_pow_save_other_state(hal_to_dmac_device_stru *h2d_device)
604 {
605 switch (h2d_device->btcoex_sw_preempt.sw_preempt_type) {
606 case HAL_BTCOEX_SW_POWSAVE_PSM_END:
607 /* 先执行了低功耗恢复,不要做操作 */
608 oam_warning_log0(0, OAM_SF_COEX, "{hmac_btcoex_pow_save_other_state:: powerdown already resume.}");
609 break;
610
611 case HAL_BTCOEX_SW_POWSAVE_IDLE:
612 /* 可能是低功耗ps=1事件才开始执行,此时读取寄存器状态=0,当前是0状态,就按照0来处理即可,
613 * 会连续来两个0的事件处理
614 */
615 oam_warning_log0(0, OAM_SF_COEX, "{hmac_btcoex_pow_save_other_state:: current is normal!.}");
616 break;
617
618 case HAL_BTCOEX_SW_POWSAVE_SCAN_ABORT:
619 /* 强制scan abort恢复了,此处不需要恢复 */
620 oam_warning_log0(0, OAM_SF_COEX,
621 "{hmac_btcoex_pow_save_other_state:: work state scan abort already resume.}");
622 break;
623
624 case HAL_BTCOEX_SW_POWSAVE_WORK:
625 /* 恢复发送和接收 */
626 if (h2d_device->btcoex_sw_preempt.sw_preempt_subtype == HAL_BTCOEX_SW_POWSAVE_SUB_IDLE) {
627 h2d_device->btcoex_sw_preempt.sw_preempt_subtype = HAL_BTCOEX_SW_POWSAVE_SUB_ACTIVE;
628 oam_warning_log0(0, OAM_SF_COEX,
629 "{hmac_btcoex_pow_save_other_state:: work HAL_BTCOEX_SW_POWSAVE_SUB_IDLE.}");
630 } else if (h2d_device->btcoex_sw_preempt.sw_preempt_subtype == HAL_BTCOEX_SW_POWSAVE_SUB_SCAN) {
631 h2d_device->btcoex_sw_preempt.sw_preempt_subtype = HAL_BTCOEX_SW_POWSAVE_SUB_ACTIVE;
632 oam_warning_log0(0, OAM_SF_COEX,
633 "{hmac_btcoex_pow_save_other_state:: work HAL_BTCOEX_SW_POWSAVE_SUB_SCAN.}");
634 }
635 break;
636
637 default:
638 oam_warning_log1(0, OAM_SF_COEX, "{hmac_btcoex_pow_save_other_state::sw_preempt_type[%d] error.}",
639 h2d_device->btcoex_sw_preempt.sw_preempt_type);
640 }
641
642 return;
643 }
644
645 /*****************************************************************************
646 函 数 名 : hmac_btcoex_pow_save_callback
647 功能描述 : 软件preempt机制下恢复节能定时处理函数
648 *****************************************************************************/
hmac_btcoex_pow_save_callback(osal_void * arg)649 osal_u32 hmac_btcoex_pow_save_callback(osal_void *arg)
650 {
651 hal_to_dmac_device_stru *h2d_device = (hal_to_dmac_device_stru *)arg;
652 hmac_device_stru *hmac_device = hmac_res_get_mac_dev_etc(0);
653
654 if (h2d_device == OSAL_NULL) {
655 oam_warning_log0(0, OAM_SF_COEX, "{hmac_btcoex_pow_save_callback::h2d_device is null.}");
656 return OAL_FAIL;
657 }
658 /* 在scan状态时候,扫描不进入低功耗,此时不用担心低功耗,如果扫描来时 */
659 if (h2d_device->hal_dev_fsm.oal_fsm.cur_state == HAL_DEVICE_SCAN_STATE) {
660 hmac_btcoex_pow_save_scan_state(hmac_device, h2d_device);
661 } else {
662 hmac_btcoex_pow_save_other_state(h2d_device);
663 }
664 hmac_btcoex_switch_ps(h2d_device, HMAC_BTCOEX_PS_TIMOUT); /* 通知device侧处理ps超时 */
665 /* preempt机制置为NONE形式 */
666 h2d_device->btcoex_sw_preempt.sw_preempt_type = HAL_BTCOEX_SW_POWSAVE_TIMEOUT;
667 h2d_device->btcoex_sw_preempt.ps_timeout_cnt++;
668
669 oam_warning_log0(0, OAM_SF_COEX, "{hmac_btcoex_pow_save_callback::time is up.}");
670
671 return OAL_SUCC;
672 }
673
hmac_btcoex_ps_on_proc(hmac_device_stru * hmac_device,hal_to_dmac_device_stru * h2d_device,hal_chip_stru * hal_chip)674 osal_void hmac_btcoex_ps_on_proc(hmac_device_stru *hmac_device,
675 hal_to_dmac_device_stru *h2d_device, hal_chip_stru *hal_chip)
676 {
677 unref_param(hmac_device);
678 unref_param(hal_chip);
679
680 /* preempt机制置为软件形式 */
681 h2d_device->btcoex_sw_preempt.sw_preempt_type = HAL_BTCOEX_SW_POWSAVE_WORK;
682
683 /* 在scan状态时候 */
684 if (h2d_device->hal_dev_fsm.oal_fsm.cur_state == HAL_DEVICE_SCAN_STATE) {
685 /* 在扫描执行过程中,不需要处理,扫描时对端已经处于节能状态并在tx
686 pause状态,扫描结束时需要考虑是不是由ps来恢复,低功耗是200ms,
687 即使扫描由ps来恢复,也来得及,ps等于0肯定在低功耗前来到或者恢复之后,不会被低功耗打断
688 */
689 h2d_device->btcoex_sw_preempt.sw_preempt_subtype = HAL_BTCOEX_SW_POWSAVE_SUB_SCAN;
690 } else {
691 /* sta模式可能一开始还没关联上,处于非up状态,后续启动成up状态,ps=0时候恢复不生效,
692 * 直接判断不处理即可,如果处于低功耗状态(主要是work状态下的awake子状态,
693 * 收到ps中断, 仍然对端在睡眠状态),wifi不需要特殊处理,执行pause不需要发ps帧,
694 * 等低功耗自己来处理ps状态.sta vap进行发送pause,并通知对端缓存数据暂停发送数据,
695 * 处于idle状态,空发一帧也没关系 */
696 /* 1.先默认为active状态,能保证低功耗饿死时,中断ps=1也能唤醒 */
697 h2d_device->btcoex_sw_preempt.sw_preempt_subtype = HAL_BTCOEX_SW_POWSAVE_SUB_ACTIVE;
698 }
699
700 /* 状态变迁,启动定时器完成ps操作,防止扫描置状态之后,出现wifi不醒来 */
701 if (h2d_device->btcoex_powersave_timer.is_registerd == OSAL_TRUE) {
702 frw_destroy_timer_entry(&(h2d_device->btcoex_powersave_timer));
703 }
704
705 /* ps机制启动时,需要根据当前状态,刷新超时定时器时间 */
706 hmac_btcoex_ps_timeout_update_time(h2d_device);
707 frw_create_timer_entry(&(h2d_device->btcoex_powersave_timer), hmac_btcoex_pow_save_callback,
708 h2d_device->btcoex_sw_preempt.timeout_ms, (osal_void *)h2d_device, OSAL_FALSE);
709 }
710
hmac_btcoex_ps_off_scan_state_proc(hmac_device_stru * hmac_device,hal_to_dmac_device_stru * h2d_device)711 osal_void hmac_btcoex_ps_off_scan_state_proc(hmac_device_stru *hmac_device, hal_to_dmac_device_stru *h2d_device)
712 {
713 switch (h2d_device->btcoex_sw_preempt.sw_preempt_type) {
714 case HAL_BTCOEX_SW_POWSAVE_SCAN_BEGIN:
715 /* 如果扫描一开始被ps打断,此时ps来恢复继续扫描 */
716 hmac_scan_begin(hmac_device, h2d_device);
717 break;
718
719 case HAL_BTCOEX_SW_POWSAVE_SCAN_WAIT:
720 /* 如果扫描临时回home channel继续工作被打断,此时ps来恢复继续回home channel工作 */
721 hmac_scan_switch_home_channel_work(hmac_device, h2d_device);
722 oam_warning_log0(0, OAM_SF_COEX,
723 "{hmac_btcoex_ps_off_scan_state_proc::hmac_scan_switch_home_channel_work start.}");
724 break;
725
726 case HAL_BTCOEX_SW_POWSAVE_SCAN_END:
727 /* 如果扫描结束被打断,此时ps来恢复继续扫描 */
728 oam_warning_log0(0, OAM_SF_COEX,
729 "{hmac_btcoex_ps_off_scan_state_proc::hmac_scan_handle_switch_channel_back start.}");
730 hmac_scan_prepare_end(hmac_device, h2d_device);
731 break;
732
733 case HAL_BTCOEX_SW_POWSAVE_SCAN_ABORT:
734 /* abort状态一定是,在save状态时候scan baort,类似于ps=0要恢复ps=1的配置,因为scan
735 * abort提前resume了,此处不需要处理 */
736 oam_warning_log0(0, OAM_SF_COEX,
737 "{hmac_btcoex_ps_off_scan_state_proc::scan is already abort and resume.}");
738
739 /* abort已经强制置为恢复,此次不保护,vap已经vap了不需要做操作 */
740 /* 恢复发送和接收 */
741 break;
742
743 case HAL_BTCOEX_SW_POWSAVE_IDLE:
744 /* 可能是状态1事件没有及时处理下半部,又来了状态0,此时处于扫描,恢复交给扫描来做即可 */
745 oam_warning_log0(0, OAM_SF_COEX,
746 "{hmac_btcoex_ps_off_scan_state_proc::HAL_BTCOEX_SW_POWSAVE_IDLE.}");
747 break;
748
749 case HAL_BTCOEX_SW_POWSAVE_WORK:
750 /* 如果扫描期间来了1又来了0,此时恢复交给扫描自己恢复,ps=0不做处理 */
751 break;
752
753 case HAL_BTCOEX_SW_POWSAVE_TIMEOUT:
754 /* time is up, 或者低功耗已经提前恢复,属于正常 */
755 break;
756
757 default:
758 oam_warning_log1(0, OAM_SF_COEX, "{hmac_btcoex_ps_off_scan_state_proc::sw_preempt_type[%d] error.}",
759 h2d_device->btcoex_sw_preempt.sw_preempt_type);
760 }
761 }
762
hmac_btcoex_ps_off_no_scan_state_proc(hal_to_dmac_device_stru * h2d_device)763 osal_void hmac_btcoex_ps_off_no_scan_state_proc(hal_to_dmac_device_stru *h2d_device)
764 {
765 switch (h2d_device->btcoex_sw_preempt.sw_preempt_type) {
766 case HAL_BTCOEX_SW_POWSAVE_PSM_END:
767 /* 先执行了低功耗恢复,不要做操作 */
768 oam_warning_log0(0, OAM_SF_COEX,
769 "{hmac_btcoex_ps_off_no_scan_state_proc:: powerdown has already resume.}");
770 break;
771
772 case HAL_BTCOEX_SW_POWSAVE_IDLE:
773 /* 可能是低功耗ps=1事件才开始执行,此时读取寄存器状态=0,
774 当前是0状态,就按照0来处理即可,会连续来两个0的事件处理 */
775 oam_warning_log0(0, OAM_SF_COEX, "{hmac_btcoex_ps_off_no_scan_state_proc:: current is normal!.}");
776 break;
777
778 case HAL_BTCOEX_SW_POWSAVE_SCAN_ABORT:
779 /* 强制scan abort恢复了,此处不需要恢复 */
780 oam_warning_log0(0, OAM_SF_COEX,
781 "{hmac_btcoex_ps_off_no_scan_state_proc:: work state scan abort already resume.}");
782 break;
783
784 case HAL_BTCOEX_SW_POWSAVE_WORK:
785 /* 恢复发送和接收 */
786 if (h2d_device->btcoex_sw_preempt.sw_preempt_subtype == HAL_BTCOEX_SW_POWSAVE_SUB_IDLE) {
787 h2d_device->btcoex_sw_preempt.sw_preempt_subtype = HAL_BTCOEX_SW_POWSAVE_SUB_ACTIVE;
788 oam_warning_log0(0, OAM_SF_COEX,
789 "{hmac_btcoex_ps_off_no_scan_state_proc:: work HAL_BTCOEX_SW_POWSAVE_SUB_IDLE.}");
790 } else if (h2d_device->btcoex_sw_preempt.sw_preempt_subtype == HAL_BTCOEX_SW_POWSAVE_SUB_SCAN) {
791 h2d_device->btcoex_sw_preempt.sw_preempt_subtype = HAL_BTCOEX_SW_POWSAVE_SUB_ACTIVE;
792 oam_warning_log0(0, OAM_SF_COEX,
793 "{hmac_btcoex_ps_off_no_scan_state_proc:: work HAL_BTCOEX_SW_POWSAVE_SUB_SCAN.}");
794 }
795 break;
796
797 case HAL_BTCOEX_SW_POWSAVE_TIMEOUT:
798 /* time is up, 或者低功耗已经提前恢复,属于正常 */
799 break;
800
801 default:
802 oam_warning_log1(0, OAM_SF_COEX,
803 "{hmac_btcoex_ps_off_no_scan_state_proc::sw_preempt_type[%d] error.}",
804 h2d_device->btcoex_sw_preempt.sw_preempt_type);
805 }
806 }
807
808 /*****************************************************************************
809 函 数 名 : hmac_btcoex_one_pkt_type_and_duration_update
810 功能描述 : one pkt帧类型刷新,兼容性设备只能识别self-cts帧
811 *****************************************************************************/
hmac_btcoex_one_pkt_type_and_duration_update(const mac_fcs_mgr_stru * fcs_mgr,hal_one_packet_cfg_stru * one_packet_cfg,hmac_vap_stru * hmac_vap)812 OSAL_STATIC osal_void hmac_btcoex_one_pkt_type_and_duration_update(const mac_fcs_mgr_stru *fcs_mgr,
813 hal_one_packet_cfg_stru *one_packet_cfg, hmac_vap_stru *hmac_vap)
814 {
815 /* 针对sta模式下才刷新帧类型 */
816 if (!is_sta(hmac_vap)) {
817 return;
818 }
819
820 /* 如果是非null帧类型,也即是self-cts类型,需要刷新duration */
821 if (hmac_btcoex_get_vap_info(hmac_vap)->ps_type == HAL_FCS_PROTECT_TYPE_SELF_CTS) {
822 /* 刷新帧类型和duration时间 */
823 one_packet_cfg->protect_type = HAL_FCS_PROTECT_TYPE_SELF_CTS;
824
825 if (fcs_mgr->fcs_service_type == HAL_FCS_SERVICE_TYPE_BTCOEX_LDAC) {
826 one_packet_cfg->duration = MAC_FCS_CTS_MAX_BTCOEX_LDAC_DURATION;
827 } else {
828 one_packet_cfg->duration = MAC_FCS_CTS_MAX_BTCOEX_NOR_DURATION;
829 }
830 }
831 }
832
hmac_btcoex_ps_init(osal_void)833 osal_u32 hmac_btcoex_ps_init(osal_void)
834 {
835 /* notify注册 */
836 frw_util_notifier_register_with_priority(WLAN_UTIL_NOTIFIER_EVENT_ROAM_ACTIVE,
837 hmac_btcoex_ps_pause_check_and_notify, WLAN_UTIL_NOTIFIER_PRIORITY_MAX);
838 frw_util_notifier_register_with_priority(WLAN_UTIL_NOTIFIER_EVENT_ROAM_DEACTIVE,
839 hmac_btcoex_ps_pause_check_and_notify, WLAN_UTIL_NOTIFIER_PRIORITY_MAX);
840 /* 对外接口注册 */
841 hmac_feature_hook_register(HMAC_FHOOK_BTCOEX_PS_SET_SW_PREEMPT_TYPE, hmac_btcoex_set_sw_preempt_type);
842 hmac_feature_hook_register(HMAC_FHOOK_BTCOEX_PS_ONE_PKT_TYPE_UPDATE, hmac_btcoex_one_pkt_type_and_duration_update);
843 hmac_feature_hook_register(HMAC_FHOOK_BTCOEX_PS_STOP_CHECK, hmac_btcoex_ps_stop_check_and_notify);
844 return OAL_SUCC;
845 }
846
hmac_btcoex_ps_deinit(osal_void)847 osal_void hmac_btcoex_ps_deinit(osal_void)
848 {
849 /* notify去注册 */
850 frw_util_notifier_unregister_with_priority(WLAN_UTIL_NOTIFIER_EVENT_ROAM_ACTIVE,
851 hmac_btcoex_ps_pause_check_and_notify, WLAN_UTIL_NOTIFIER_PRIORITY_MAX);
852 frw_util_notifier_unregister_with_priority(WLAN_UTIL_NOTIFIER_EVENT_ROAM_DEACTIVE,
853 hmac_btcoex_ps_pause_check_and_notify, WLAN_UTIL_NOTIFIER_PRIORITY_MAX);
854 /* 对外接口去注册 */
855 hmac_feature_hook_unregister(HMAC_FHOOK_BTCOEX_PS_SET_SW_PREEMPT_TYPE);
856 hmac_feature_hook_unregister(HMAC_FHOOK_BTCOEX_PS_ONE_PKT_TYPE_UPDATE);
857 hmac_feature_hook_unregister(HMAC_FHOOK_BTCOEX_PS_STOP_CHECK);
858 return;
859 }
860
861 #ifdef __cplusplus
862 #if __cplusplus
863 }
864 #endif
865 #endif
866
867 #endif
868