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: BA相关操作
15 * Date: 2023-02-09 09:51
16 */
17 #ifndef __HMAC_BTCOEX_BA_C__
18 #define __HMAC_BTCOEX_BA_C__
19
20 #include "hmac_roam_if.h"
21 #include "oal_netbuf_data.h"
22 #include "hmac_tx_data.h"
23 #include "hmac_mgmt_bss_comm.h"
24 #include "hmac_hook.h"
25 #include "hmac_feature_interface.h"
26 #include "hmac_btcoex.h"
27 #include "hmac_btcoex_ba.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_BA_C
36
37 #undef THIS_MOD_ID
38 #define THIS_MOD_ID DIAG_MOD_ID_WIFI_HOST
39
40 #define WLAN_AMPDU_TX_MAX_NUM_BTOCEX 4 // 共存场景下聚合度
41
42 /*****************************************************************************
43 函数声明
44 *****************************************************************************/
45 static osal_s32 hmac_btcoex_rx_delba_trigger_etc(hmac_vap_stru *hmac_vap,
46 hmac_to_hmac_btcoex_rx_delba_trigger_event_stru *btcoex_rx_delba);
47 /*****************************************************************************
48 函数实现
49 *****************************************************************************/
hmac_btcoex_update_ba_size(const hmac_vap_stru * hmac_vap,hmac_user_btcoex_delba_stru * btcoex_delba,const hal_btcoex_btble_status_stru * btble_status)50 osal_void hmac_btcoex_update_ba_size(const hmac_vap_stru *hmac_vap, hmac_user_btcoex_delba_stru *btcoex_delba,
51 const hal_btcoex_btble_status_stru *btble_status)
52 {
53 const bt_status_stru *bt_status;
54 wlan_channel_band_enum_uint8 band;
55 wlan_bw_cap_enum_uint8 bandwidth;
56 btcoex_active_mode_enum_uint8 bt_active_mode;
57 btcoex_rx_window_size_grade_enum_uint8 bt_rx_win_size_grade;
58
59 bt_status = &(btble_status->bt_status.bt_status);
60
61 band = hmac_vap->channel.band;
62 hmac_vap_get_bandwidth_cap_etc(hmac_vap, &bandwidth);
63 if ((band >= WLAN_BAND_BUTT) || (bandwidth >= WLAN_BW_CAP_BUTT)) {
64 oam_error_log3(0, OAM_SF_COEX, "vap_id[%d] {hmac_btcoex_update_ba_size::band %d, bandwidth %d exceed scope!}",
65 hmac_vap->vap_id, band, bandwidth);
66 return;
67 }
68
69 if (btcoex_delba == OSAL_NULL) {
70 return;
71 }
72
73 if (btcoex_delba->ba_size_expect_index >= BTCOEX_RX_WINDOW_SIZE_INDEX_BUTT) {
74 oam_error_log2(0, OAM_SF_COEX,
75 "vap_id[%d] {hmac_btcoex_update_ba_size::ba_size_expect_index %d exceed scope!}", hmac_vap->vap_id,
76 btcoex_delba->ba_size_expect_index);
77 return;
78 }
79
80 if (bt_status->bt_6slot != 0) {
81 bt_active_mode = BTCOEX_ACTIVE_MODE_SCO;
82
83 /* 6slot 设备 */
84 if (bt_status->bt_6slot == 2) { /* 6slot为2时才将ba_size设为1 */
85 btcoex_delba->ba_size = 1;
86 return;
87 }
88 } else if (bt_status->bt_a2dp != 0) {
89 bt_active_mode = BTCOEX_ACTIVE_MODE_A2DP;
90 } else if (bt_status->bt_transfer != 0) {
91 bt_active_mode = BTCOEX_ACTIVE_MODE_TRANSFER;
92 } else {
93 bt_active_mode = BTCOEX_ACTIVE_MODE_BUTT;
94 }
95
96 /* BT没有业务, 聚合64 */
97 if (bt_active_mode >= BTCOEX_ACTIVE_MODE_BUTT) {
98 bt_active_mode = BTCOEX_ACTIVE_MODE_A2DP;
99 btcoex_delba->ba_size_expect_index = BTCOEX_RX_WINDOW_SIZE_INDEX_3;
100 }
101 if (btcoex_delba->user_nss_num >= WLAN_DOUBLE_NSS) {
102 #if defined(WLAN_MAX_NSS_NUM) && defined(WLAN_SINGLE_NSS) && (WLAN_MAX_NSS_NUM != WLAN_SINGLE_NSS)
103 bt_rx_win_size_grade = hmac_get_g_rx_win_size_grage_mimo(band, bandwidth, bt_active_mode);
104 btcoex_delba->ba_size = hmac_get_g_rx_win_size_mimo(bt_rx_win_size_grade, btcoex_delba->ba_size_expect_index);
105 #endif
106 } else {
107 bt_rx_win_size_grade = hmac_get_g_rx_win_size_grage_siso(band, bandwidth, bt_active_mode);
108 btcoex_delba->ba_size = hmac_get_g_rx_win_size_siso(bt_rx_win_size_grade, btcoex_delba->ba_size_expect_index);
109 }
110 }
111
112 /*****************************************************************************
113 函 数 名 : hmac_btcoex_delba_trigger
114 功能描述 : Change ba size
115 *****************************************************************************/
hmac_btcoex_delba_trigger(hmac_vap_stru * hmac_vap,oal_bool_enum_uint8 need_delba,hmac_user_btcoex_delba_stru * btcoex_delba)116 osal_void hmac_btcoex_delba_trigger(hmac_vap_stru *hmac_vap, oal_bool_enum_uint8 need_delba,
117 hmac_user_btcoex_delba_stru *btcoex_delba)
118 {
119 hmac_to_hmac_btcoex_rx_delba_trigger_event_stru d2h_btcoex_rx_delba;
120
121 if (hmac_vap == OSAL_NULL) {
122 return;
123 }
124
125 /* 触发了一次主动删建BA,删建标记使能,后续单wifi自己删建BA需要采用共存配置的门限 */
126 if (need_delba == OSAL_TRUE) {
127 btcoex_delba->delba_trigger = OSAL_TRUE;
128
129 /* 6slot立即删聚合了,需要标记状态,用于后续双链路不要频繁删聚合;删到64时恢复标记 */
130 if (btcoex_delba->ba_size == 1) {
131 hmac_btcoex_get_vap_info(hmac_vap)->delba_on_6slot = OSAL_TRUE;
132 } else if (btcoex_delba->ba_size == 64) { /* when buffer size is 64 */
133 hmac_btcoex_get_vap_info(hmac_vap)->delba_on_6slot = OSAL_FALSE;
134 }
135 }
136
137 d2h_btcoex_rx_delba.need_delba = need_delba;
138 d2h_btcoex_rx_delba.ba_size = btcoex_delba->ba_size;
139 d2h_btcoex_rx_delba.user_id = hmac_vap->assoc_vap_id;
140
141 (osal_void)hmac_btcoex_rx_delba_trigger_etc(hmac_vap, &d2h_btcoex_rx_delba);
142 }
143
144 /*****************************************************************************
145 函 数 名 : hmac_btcoex_delba_event_process
146 功能描述 : BT音乐和数传下,针对聚合聚合个数调整, 配置聚合个数,在接收速率逻辑进行删除BA操作
147 (1)02和03方式处理不一致, 02是主场景,03只是存在兼容性时,删到第二档
148 (2)02下音乐和数传处理不同,03下处理一致,都需要延迟删除
149 (3)sta gc vap级别定时器处理
150 *****************************************************************************/
hmac_btcoex_delba_event_process(const hal_btcoex_btble_status_stru * btble_status,hmac_vap_stru * hmac_vap)151 osal_u32 hmac_btcoex_delba_event_process(const hal_btcoex_btble_status_stru *btble_status,
152 hmac_vap_stru *hmac_vap)
153 {
154 hmac_vap_btcoex_rx_statistics_stru *btcoex_rx_stat = OSAL_NULL;
155 hmac_user_btcoex_delba_stru *btcoex_delba = OSAL_NULL;
156 hmac_user_stru *hmac_user = OSAL_NULL;
157 oal_bool_enum_uint8 need_delba = OSAL_FALSE;
158
159 /* 如果不开启删聚合 直接返回 */
160 if (hal_btcoex_check_sw_preempt_delba_on(hmac_vap->hal_device) == OSAL_FALSE) {
161 return OAL_SUCC;
162 }
163
164 /* c1 siso不需要执行 */
165 if (hmac_vap->hal_device->hal_m2s_fsm.oal_fsm.cur_state == HAL_M2S_STATE_SISO &&
166 hmac_vap->hal_device->cfg_cap_info->phy_chain == WLAN_PHY_CHAIN_ONE) {
167 return OAL_SUCC;
168 }
169
170 hmac_user = (hmac_user_stru *)mac_res_get_hmac_user_etc(hmac_vap->assoc_vap_id);
171 if (osal_unlikely(hmac_user == OSAL_NULL)) {
172 oam_error_log1(0, 0, "vap_id[%d] hmac_btcoex_delba_event_process::user IS NULL.", hmac_vap->vap_id);
173 return OAL_ERR_CODE_PTR_NULL;
174 }
175
176 btcoex_rx_stat = &(hmac_btcoex_get_vap_info(hmac_vap)->hmac_vap_btcoex_rx_statistics);
177 btcoex_delba = &(hmac_btcoex_get_user_info(hmac_user)->hmac_user_btcoex_delba);
178
179 /* 音乐和数传暂时处理方式一致 */
180 /* 正常bt音乐和数传打开和关闭场景下,对聚合进行处理 */
181 if ((btble_status->bt_status.bt_status.bt_a2dp != 0) || (btble_status->bt_status.bt_status.bt_transfer != 0)) {
182 if (btcoex_delba->ba_size_real_index == BTCOEX_RX_WINDOW_SIZE_INDEX_3) {
183 btcoex_delba->ba_size_expect_index = BTCOEX_RX_WINDOW_SIZE_INDEX_2;
184 } else {
185 btcoex_delba->ba_size_expect_index = btcoex_delba->ba_size_real_index;
186 }
187
188 /* RX速率统计开关 */
189 btcoex_rx_stat->rx_rate_statistics_flag = OSAL_TRUE;
190 } else {
191 /* 只有电话, 音乐和数传都没有的情况才进行恢复成64的聚合 */
192 if (btble_status->bt_status.bt_status.bt_6slot == OSAL_FALSE) {
193 btcoex_delba->ba_size_expect_index = BTCOEX_RX_WINDOW_SIZE_INDEX_3;
194 btcoex_rx_stat->rx_rate_statistics_flag = OSAL_FALSE;
195 } else {
196 /* 音乐结束的时候还有电话的场景,在这里不进行BA删建处理,由电话的流程控制 */
197 return OAL_SUCC;
198 }
199 }
200
201 hmac_btcoex_update_ba_size(hmac_vap, btcoex_delba, btble_status);
202
203 oam_warning_log4(0, OAM_SF_COEX,
204 "{hmac_btcoex_delba_event_process:: a2dp status:%d, transfer status changed:%d, need_delba:%d,ba_size:%d.}",
205 btble_status->bt_status.bt_status.bt_a2dp, btble_status->bt_status.bt_status.bt_transfer, need_delba,
206 btcoex_delba->ba_size);
207
208 /* 默认都不立即删除BA, 接收速率统计逻辑中来处理删除BA操作 */
209 hmac_btcoex_delba_trigger(hmac_vap, need_delba, btcoex_delba);
210
211 btcoex_rx_stat->rx_rate_statistics_timeout = OSAL_FALSE;
212
213 if (btcoex_rx_stat->bt_coex_statistics_timer.is_registerd == OSAL_TRUE) {
214 frw_destroy_timer_entry(&(btcoex_rx_stat->bt_coex_statistics_timer));
215 }
216 frw_create_timer_entry(&(btcoex_rx_stat->bt_coex_statistics_timer), hmac_btcoex_rx_rate_statistics_flag_callback,
217 BTCOEX_RX_STATISTICS_TIME, (osal_void *)hmac_vap, OSAL_TRUE);
218
219 return OAL_SUCC;
220 }
221
hmac_btcoex_config_tx_aggr_num(osal_u8 aggt_num)222 osal_u32 hmac_btcoex_config_tx_aggr_num(osal_u8 aggt_num)
223 {
224 osal_u32 ret = OAL_FAIL;
225 frw_msg msg = {0};
226 msg.data = &aggt_num;
227 msg.data_len = (osal_u16)sizeof(osal_u8);
228 ret = (osal_u32)frw_send_msg_to_device(0, WLAN_MSG_H2D_C_CFG_BTCOEX_SET_AGGR_NUM, &msg, OSAL_FALSE);
229 if (osal_unlikely(ret != OAL_SUCC)) {
230 oam_error_log1(0, OAM_SF_ANY, "{hmac_btcoex_config_tx_aggr_num:: frw_send_msg [%d].}", ret);
231 }
232 return ret;
233 }
234
hmac_btcoex_get_expect_ba_size(hmac_vap_stru * hmac_vap,hmac_user_btcoex_delba_stru * btcoex_delba,const hal_btcoex_btble_status_stru * btble_status)235 OSAL_STATIC osal_void hmac_btcoex_get_expect_ba_size(hmac_vap_stru *hmac_vap, hmac_user_btcoex_delba_stru *btcoex_delba,
236 const hal_btcoex_btble_status_stru *btble_status)
237 {
238 wlan_bw_cap_enum_uint8 bandwidth;
239 osal_u8 btcoex_max_aggr_num = WLAN_AMPDU_TX_MAX_NUM;
240 hmac_vap_get_bandwidth_cap_etc(hmac_vap, &bandwidth);
241 btcoex_delba->ba_size_expect_index = BTCOEX_RX_WINDOW_SIZE_INDEX_3;
242
243 if (btble_status->ble_status.ble_status.ble_con_num >= BTCOEX_BLE_CONN_NUM_THOLD ||
244 (btble_status->ble_status.ble_status.ble_hid == OSAL_TRUE)) {
245 btcoex_delba->ba_size_expect_index = BTCOEX_RX_WINDOW_SIZE_INDEX_1;
246 btcoex_max_aggr_num = WLAN_AMPDU_TX_MAX_NUM_BTOCEX;
247 }
248
249 btcoex_delba->ba_size = hmac_get_g_rx_ba_win_size(bandwidth, btcoex_delba->ba_size_expect_index);
250 hmac_btcoex_config_tx_aggr_num(btcoex_max_aggr_num); /* 发消息到device侧修改tx最大聚合度 */
251 }
252
hmac_btcoex_action_dela_ba_handler(hmac_vap_stru * hmac_vap)253 osal_s32 hmac_btcoex_action_dela_ba_handler(hmac_vap_stru *hmac_vap)
254 {
255 osal_u8 mac_vap_id[WLAN_SERVICE_VAP_MAX_NUM_PER_DEVICE] = {0};
256 hmac_vap_stru *hmac_valid_vap = OSAL_NULL;
257 hal_btcoex_btble_status_stru *btble_status = OSAL_NULL;
258 osal_u8 vap_idx;
259 osal_u8 valid_vap_num;
260 hmac_user_btcoex_delba_stru btcoex_delba = {0};
261 hal_to_dmac_device_stru *hal_device;
262
263 unref_param(hmac_vap);
264 hal_device = &hal_get_chip_stru()->device.hal_device_base;
265 btble_status = hal_btcoex_btble_status();
266 valid_vap_num = hmac_btcoex_find_all_valid_sta_per_device(hal_device, mac_vap_id,
267 WLAN_SERVICE_VAP_MAX_NUM_PER_DEVICE);
268 for (vap_idx = 0; vap_idx < valid_vap_num; vap_idx++) {
269 hmac_valid_vap = (hmac_vap_stru *)mac_res_get_hmac_vap(mac_vap_id[vap_idx]);
270 if (hmac_valid_vap == OSAL_NULL) {
271 oam_error_log1(0, OAM_SF_COEX, "{hmac_btcoex_mul_conn_status_handler::hmac_vap[%d] is NULL.}",
272 mac_vap_id[vap_idx]);
273 return OAL_ERR_CODE_PTR_NULL;
274 }
275 hmac_btcoex_get_expect_ba_size(hmac_valid_vap, &btcoex_delba, btble_status);
276 hmac_btcoex_delba_trigger(hmac_valid_vap, OSAL_TRUE, &btcoex_delba);
277 }
278
279 return OAL_SUCC;
280 }
281
282 /*****************************************************************************
283 函 数 名 : hmac_btcoex_delba_foreach_tid
284 功能描述 : 共存删除BA会话
285 输入参数 : 无
286 输出参数 : 无
287 *****************************************************************************/
hmac_btcoex_delba_foreach_tid(hmac_vap_stru * hmac_vap,hmac_user_stru * hmac_user,mac_cfg_delba_req_param_stru * mac_cfg_delba_param)288 OAL_STATIC osal_u32 hmac_btcoex_delba_foreach_tid(hmac_vap_stru *hmac_vap, hmac_user_stru *hmac_user,
289 mac_cfg_delba_req_param_stru *mac_cfg_delba_param)
290 {
291 osal_u32 ul_ret;
292 frw_msg msg_info;
293 (osal_void)memset_s(&msg_info, OAL_SIZEOF(msg_info), 0, OAL_SIZEOF(msg_info));
294
295 oal_set_mac_addr(mac_cfg_delba_param->mac_addr, hmac_user->user_mac_addr);
296 mac_cfg_delba_param->trigger = MAC_DELBA_TRIGGER_BTCOEX;
297
298 for (mac_cfg_delba_param->tidno = 0; mac_cfg_delba_param->tidno < WLAN_TID_MAX_NUM;
299 mac_cfg_delba_param->tidno++) {
300 msg_info.data = (osal_u8 *)mac_cfg_delba_param;
301 msg_info.data_len = 0;
302 ul_ret = (osal_u32)hmac_config_delba_req_etc(hmac_vap, &msg_info);
303 if (ul_ret != OAL_SUCC) {
304 oam_warning_log3(0, OAM_SF_COEX, "vap_id[%d] {hmac_btcoex_delba_foreach_tid::ul_ret: %d, tid: %d}",
305 hmac_vap->vap_id, ul_ret, mac_cfg_delba_param->tidno);
306 return ul_ret;
307 }
308 }
309
310 return ul_ret;
311 }
312
313 /*****************************************************************************
314 函 数 名 : hmac_btcoex_delba_foreach_user
315 功能描述 : hmac删除BA
316 输入参数 : 无
317 输出参数 : 无
318 *****************************************************************************/
hmac_btcoex_delba_from_user(hmac_vap_stru * hmac_vap,hmac_user_stru * hmac_user)319 OAL_STATIC osal_u32 hmac_btcoex_delba_from_user(hmac_vap_stru *hmac_vap, hmac_user_stru *hmac_user)
320 {
321 mac_cfg_delba_req_param_stru mac_cfg_delba_param;
322 osal_void *fhook;
323
324 memset_s((osal_u8 *)&mac_cfg_delba_param, OAL_SIZEOF(mac_cfg_delba_param), 0, OAL_SIZEOF(mac_cfg_delba_param));
325
326 mac_cfg_delba_param.direction = MAC_RECIPIENT_DELBA;
327
328 /* 属于黑名单AP,并且已经处于电话业务时,不进行删BA逻辑 */
329 if (hmac_btcoex_get_user_info(hmac_user)->hmac_btcoex_addba_req.ba_handle_allow == OAL_FALSE) {
330 if (hmac_btcoex_get_blacklist_type(hmac_user) == BTCOEX_BLACKLIST_TPYE_FIX_BASIZE) {
331 oam_warning_log0(0, OAM_SF_COEX, "{hmac_btcoex_delba_from_user::DO NOT DELBA.}");
332 } else {
333 oam_warning_log0(0, OAM_SF_COEX, "{hmac_btcoex_delba_from_user::need to reassoc to READDBA.}");
334 fhook = hmac_get_feature_fhook(HMAC_FHOOK_ROAM_START);
335 if (fhook != OSAL_NULL) {
336 ((hmac_roam_start_etc_cb)fhook)(hmac_vap, ROAM_SCAN_CHANNEL_ORG_0, OAL_TRUE, ROAM_TRIGGER_COEX);
337 }
338 /* 重关联之后,刷新为允许建立聚合 */
339 hmac_btcoex_get_user_info(hmac_user)->hmac_btcoex_addba_req.ba_handle_allow = OAL_TRUE;
340
341 /* 保证wifi恢复聚合64 */
342 hmac_btcoex_get_user_info(hmac_user)->ba_size = 0;
343 }
344
345 return OAL_FAIL;
346 }
347
348 /* 开始arp探测统计 */
349 hmac_btcoex_get_user_info(hmac_user)->arp_probe_on = OAL_TRUE;
350
351 return hmac_btcoex_delba_foreach_tid(hmac_vap, hmac_user, &mac_cfg_delba_param);
352 }
353
354 /*****************************************************************************
355 函 数 名 : hmac_btcoex_rx_delba_trigger_etc
356 功能描述 : hmac删除BA
357 输入参数 : 无
358 输出参数 : 无
359 *****************************************************************************/
hmac_btcoex_rx_delba_trigger_etc(hmac_vap_stru * hmac_vap,hmac_to_hmac_btcoex_rx_delba_trigger_event_stru * btcoex_rx_delba)360 osal_s32 hmac_btcoex_rx_delba_trigger_etc(hmac_vap_stru *hmac_vap,
361 hmac_to_hmac_btcoex_rx_delba_trigger_event_stru *btcoex_rx_delba)
362 {
363 hmac_user_stru *hmac_user = OAL_PTR_NULL;
364 osal_s32 ul_ret;
365
366 hmac_user = mac_res_get_hmac_user_etc(btcoex_rx_delba->user_id);
367 if (OAL_UNLIKELY(hmac_user == OAL_PTR_NULL)) {
368 oam_warning_log2(0, OAM_SF_COEX,
369 "vap_id[%d] {hmac_btcoex_rx_delba_trigger_etc::hmac_user is null! user_id is %d.}",
370 hmac_vap->vap_id, btcoex_rx_delba->user_id);
371 return OAL_ERR_CODE_PTR_NULL;
372 }
373
374 hmac_btcoex_get_user_info(hmac_user)->ba_size = (osal_u16)btcoex_rx_delba->ba_size;
375
376 if (btcoex_rx_delba->need_delba == OAL_TRUE) {
377 /* 刷新共存触发删建BA标记 */
378 hmac_btcoex_get_user_info(hmac_user)->delba_btcoex_trigger = OAL_TRUE;
379 }
380
381 oam_warning_log4(0, OAM_SF_COEX,
382 "vap_id[%d] {hmac_btcoex_rx_delba_trigger_etc:delba size:%d, need_delba:%d, delba_trigger:%d.}",
383 hmac_vap->vap_id, btcoex_rx_delba->ba_size,
384 btcoex_rx_delba->need_delba, hmac_btcoex_get_user_info(hmac_user)->delba_btcoex_trigger);
385
386 if (btcoex_rx_delba->need_delba) {
387 ul_ret = (osal_s32)hmac_btcoex_delba_from_user(hmac_vap, hmac_user);
388 if (ul_ret != OAL_SUCC) {
389 oam_warning_log2(0, OAM_SF_COEX,
390 "vap_id[%d] {hmac_btcoex_rx_delba_trigger_etc:delba send failed:ul_ret: %d.}",
391 hmac_vap->vap_id, ul_ret);
392 return ul_ret;
393 }
394 }
395
396 return OAL_SUCC;
397 }
398
399 /*****************************************************************************
400 函 数 名 : hmac_btcoex_delba_send_timeout
401 输出参数 : 无
402 返 回 值 : OAL_SUCC 或 失败错误码
403 *****************************************************************************/
hmac_btcoex_delba_send_timeout(osal_void * p_arg)404 OAL_STATIC osal_u32 hmac_btcoex_delba_send_timeout(osal_void *p_arg)
405 {
406 hmac_btcoex_arp_req_process_stru *arp_req_process;
407 hmac_user_btcoex_stru *hmac_user_btcoex;
408 hmac_user_stru *hmac_user;
409 osal_s32 val;
410 osal_void *fhook;
411
412 hmac_user = (hmac_user_stru *)p_arg;
413 if (hmac_user == OAL_PTR_NULL) {
414 oam_error_log0(0, OAM_SF_COEX, "{hmac_btcoex_delba_send_timeout::hmac_user is null.}");
415 return OAL_ERR_CODE_PTR_NULL;
416 }
417
418 hmac_user_btcoex = hmac_btcoex_get_user_info(hmac_user);
419
420 arp_req_process = &(hmac_user_btcoex->hmac_btcoex_arp_req_process);
421
422 val = osal_adapt_atomic_read(&(arp_req_process->rx_unicast_pkt_to_lan));
423 if (val == 0) {
424 hmac_vap_stru *hmac_vap;
425
426 hmac_vap = (hmac_vap_stru *)mac_res_get_hmac_vap(hmac_user->vap_id);
427 if (OAL_UNLIKELY(hmac_vap == OAL_PTR_NULL)) {
428 oam_error_log1(0, OAM_SF_COEX, "vap_id[%d] {hmac_btcoex_delba_send_timeout::hmac_vap is null!}",
429 hmac_user->vap_id);
430 return OAL_ERR_CODE_PTR_NULL;
431 }
432
433 hmac_user_btcoex->rx_no_pkt_count++;
434
435 oam_warning_log2(0, OAM_SF_COEX, "vap_id[%d] {hmac_btcoex_delba_send_timeout::rx_pkt[%d]!}",
436 hmac_user->vap_id, hmac_user_btcoex->rx_no_pkt_count);
437
438 if (hmac_user_btcoex->rx_no_pkt_count > BTCOEX_ARP_FAIL_REASSOC_NUM) {
439 /* 重关联逻辑暂时关闭,等统计出现哪些场景出现不通,才限制场景放开 */
440 oam_warning_log1(0, OAM_SF_COEX, "vap_id[%d] {hmac_btcoex_delba_send_timeout::need to reassoc to resume.}",
441 hmac_user->vap_id);
442
443 /* 停止arp探测 */
444 hmac_user_btcoex->arp_probe_on = OAL_FALSE;
445 /* 发起reassoc req */
446 fhook = hmac_get_feature_fhook(HMAC_FHOOK_ROAM_START);
447 if (fhook != OSAL_NULL) {
448 ((hmac_roam_start_etc_cb)fhook)(hmac_vap, ROAM_SCAN_CHANNEL_ORG_0, OAL_TRUE, ROAM_TRIGGER_COEX);
449 }
450 /* 保证wifi恢复聚合64 */
451 hmac_btcoex_get_user_info(hmac_user)->ba_size = 0;
452 } else if (hmac_user_btcoex->rx_no_pkt_count > BTCOEX_ARP_FAIL_DELBA_NUM) {
453 hmac_btcoex_delba_from_user(hmac_vap, hmac_user);
454 }
455 } else {
456 /* 停止arp探测 */
457 hmac_user_btcoex->arp_probe_on = OAL_FALSE;
458
459 hmac_user_btcoex->rx_no_pkt_count = 0;
460 }
461
462 osal_adapt_atomic_set(&arp_req_process->rx_unicast_pkt_to_lan, 0);
463
464 return OAL_SUCC;
465 }
466
467 /*****************************************************************************
468 函 数 名 : hmac_btcoex_arp_fail_delba_process_etc
469 功能描述 : 发送方向arp帧成功率统计(发送arp req之后进行rx方向单播数据帧统计,一直收不到,触发删聚合逻辑)
470 输出参数 : 无
471 返 回 值 : OAL_SUCC 或 失败错误码
472 *****************************************************************************/
hmac_btcoex_arp_fail_delba_process_etc(oal_netbuf_stru ** pst_netbuf,hmac_vap_stru * hmac_vap)473 OSAL_STATIC osal_u32 hmac_btcoex_arp_fail_delba_process_etc(oal_netbuf_stru **pst_netbuf, hmac_vap_stru *hmac_vap)
474 {
475 hmac_btcoex_arp_req_process_stru *arp_req_process;
476 hmac_user_btcoex_stru *hmac_user_btcoex;
477 mac_ether_header_stru *mac_ether_hdr;
478 hmac_user_stru *hmac_user;
479 osal_u8 data_type;
480
481 /* 若该STA不存在,则直接返回,不处理,不影响该函数原调用处的流程 */
482 if (mac_btcoex_check_valid_sta(hmac_vap) != OAL_TRUE) {
483 return OAL_CONTINUE;
484 }
485
486 mac_ether_hdr = (mac_ether_header_stru *)oal_netbuf_data(*pst_netbuf);
487
488 /* 若该USER不存在,则直接返回,不处理,不影响该函数原调用处的流程 */
489 hmac_user = mac_res_get_hmac_user_etc(hmac_vap->assoc_vap_id);
490 if (OAL_UNLIKELY(hmac_user == OAL_PTR_NULL)) {
491 oam_warning_log2(0, OAM_SF_COEX,
492 "vap_id[%d] {hmac_btcoex_arp_fail_delba_process_etc::hmac_user is null!assoc_vap is %d.}",
493 hmac_vap->vap_id, hmac_vap->assoc_vap_id);
494 return OAL_CONTINUE;
495 }
496
497 /* 只要统计功能打开,就需要做一次探测 */
498 hmac_user_btcoex = hmac_btcoex_get_user_info(hmac_user);
499 if ((hmac_user_btcoex->ba_size > 0) && (hmac_user_btcoex->arp_probe_on == OAL_TRUE)) {
500 /* 参数外面已经做检查,里面没必要再做检查了 */
501 data_type = hmac_get_data_type_from_8023_etc((osal_u8 *)mac_ether_hdr, MAC_NETBUFF_PAYLOAD_ETH,
502 OAL_NETBUF_LEN(*pst_netbuf));
503
504 arp_req_process = &(hmac_user_btcoex->hmac_btcoex_arp_req_process);
505
506 /* 发送方向创建定时器,多次创建定时器 */
507 if ((data_type == MAC_DATA_ARP_REQ) &&
508 (arp_req_process->delba_opt_timer.is_registerd == OAL_FALSE)) {
509 /* 每次重启定时器之前清零,保证统计的时间 */
510 osal_adapt_atomic_set(&(arp_req_process->rx_unicast_pkt_to_lan), 0);
511
512 frw_create_timer_entry(&(arp_req_process->delba_opt_timer),
513 hmac_btcoex_delba_send_timeout,
514 BTCOEX_ARP_PROBE_TIMEOUT,
515 hmac_user,
516 OAL_FALSE);
517 }
518 }
519 return OAL_CONTINUE;
520 }
521
522 /*****************************************************************************
523 函 数 名 : hmac_btcoex_arp_fail_delba_process
524 功能描述 : 判断bsle是否开启,选择是否执行
525 输入参数 : 无
526 输出参数 : hmac_btcoex_arp_fail_delba_process_etc返回值
527 *****************************************************************************/
hmac_btcoex_arp_fail_delba_process(oal_netbuf_stru ** pst_netbuf,hmac_vap_stru * hmac_vap)528 WIFI_HMAC_TCM_TEXT WIFI_TCM_TEXT OSAL_STATIC osal_u32 hmac_btcoex_arp_fail_delba_process(oal_netbuf_stru **pst_netbuf,
529 hmac_vap_stru *hmac_vap)
530 {
531 hal_btcoex_btble_status_stru *status = hal_btcoex_btble_status();
532 if (status->bt_status.bt_status.bt_on == 0) {
533 return OAL_CONTINUE;
534 }
535 return hmac_btcoex_arp_fail_delba_process_etc(pst_netbuf, hmac_vap);
536 }
537
538 /*****************************************************************************
539 函 数 名 : hmac_config_print_btcoex_status_etc
540 功能描述 : 打印共存维测信息
541 输入参数 : 无
542 输出参数 : 无
543 *****************************************************************************/
hmac_btcoex_check_by_ba_size_etc(hmac_user_stru * hmac_user)544 OSAL_STATIC osal_u32 hmac_btcoex_check_by_ba_size_etc(hmac_user_stru *hmac_user)
545 {
546 hmac_user_btcoex_stru *hmac_user_btcoex = hmac_btcoex_get_user_info(hmac_user);
547 if ((hmac_user_btcoex->ba_size > 0) && (hmac_user_btcoex->ba_size < WLAN_AMPDU_RX_BA_LUT_WSIZE)) {
548 return OAL_TRUE;
549 }
550 return OAL_FALSE;
551 }
552
553 /*****************************************************************************
554 函 数 名 : hmac_btcoex_tx_addba_rsp_check
555 功能描述 : 判断一个帧是否是addba_rsp
556 *****************************************************************************/
hmac_btcoex_tx_addba_rsp_check(const oal_netbuf_stru * netbuf,hmac_user_stru * hmac_user)557 osal_void hmac_btcoex_tx_addba_rsp_check(const oal_netbuf_stru *netbuf, hmac_user_stru *hmac_user)
558 {
559 hmac_user_btcoex_delba_stru *btcoex_delba = OSAL_NULL;
560 const osal_u8 *mac_header = oal_netbuf_header_const(netbuf);
561 const osal_u8 *mac_payload = oal_netbuf_tx_data_const(netbuf);
562
563 if (mac_payload == OSAL_NULL) {
564 oam_error_log0(0, OAM_SF_COEX, "{hmac_btcoex_tx_addba_rsp_check::mac_payload is null!}");
565 return;
566 }
567
568 /* Management frame */
569 if (mac_get_frame_type_and_subtype(mac_header) == (WLAN_FC0_SUBTYPE_ACTION | WLAN_FC0_TYPE_MGT)) {
570 if ((mac_payload[0] == MAC_ACTION_CATEGORY_BA) && (mac_payload[1] == MAC_BA_ACTION_ADDBA_RSP)) {
571 btcoex_delba = &(hmac_btcoex_get_user_info(hmac_user)->hmac_user_btcoex_delba);
572 btcoex_delba->get_addba_req_flag = OSAL_TRUE;
573
574 if (btcoex_delba->delba_trigger == OSAL_TRUE) {
575 btcoex_delba->ba_size_real_index = btcoex_delba->ba_size_expect_index;
576 } else {
577 btcoex_delba->ba_size_real_index = BTCOEX_RX_WINDOW_SIZE_INDEX_3;
578 }
579 }
580 }
581 }
582
hmac_btcoex_adjust_addba_rsp_basize(hmac_vap_stru * hmac_vap,hmac_ba_rx_stru * addba_rsp)583 OSAL_STATIC osal_void hmac_btcoex_adjust_addba_rsp_basize(hmac_vap_stru *hmac_vap, hmac_ba_rx_stru *addba_rsp)
584 {
585 hmac_user_stru *hmac_user = OAL_PTR_NULL;
586 hmac_user_btcoex_stru *hmac_user_btcoex;
587
588 hmac_user = mac_vap_get_hmac_user_by_addr_etc(hmac_vap, addba_rsp->transmit_addr);
589 if ((hmac_user == OAL_PTR_NULL) || (mac_btcoex_check_valid_sta(hmac_vap) != OAL_TRUE)) {
590 return;
591 }
592
593 hmac_user_btcoex = hmac_btcoex_get_user_info(hmac_user);
594 /* 1.黑名单用户 */
595 if (hmac_user_btcoex->hmac_btcoex_addba_req.ba_handle_allow == OAL_FALSE) {
596 if (hmac_btcoex_get_blacklist_type(hmac_user) == BTCOEX_BLACKLIST_TPYE_FIX_BASIZE) {
597 addba_rsp->ba_resp_buf_size = (osal_u16)BTCOEX_BLACKLIST_BA_SIZE_LIMIT;
598 }
599 } else if ((hmac_user_btcoex->delba_btcoex_trigger == OAL_TRUE) && (hmac_user_btcoex->ba_size != 0)) {
600 addba_rsp->ba_resp_buf_size = (osal_u8)hmac_user_btcoex->ba_size;
601 }
602 }
603
604 hmac_netbuf_hook_stru g_btcoex_netbuf_hook = {
605 .hooknum = HMAC_FRAME_DATA_TX_BRIDGE_IN,
606 .priority = HMAC_HOOK_PRI_LOW,
607 .hook_func = hmac_btcoex_arp_fail_delba_process,
608 };
609
hmac_btcoex_ba_init(osal_void)610 osal_u32 hmac_btcoex_ba_init(osal_void)
611 {
612 osal_u32 ret;
613 /* 转发接口注册 */
614 ret = hmac_register_netbuf_hook(&g_btcoex_netbuf_hook);
615 if (ret != OAL_SUCC) {
616 oam_error_log0(0, OAM_SF_RX,
617 "{hmac_btcoex_arp_fail_delba_process:: MGMT RX IN register_netbuf_hooks error!");
618 return ret;
619 }
620 /* 对外接口注册 */
621 hmac_feature_hook_register(HMAC_FHOOK_BTCOEX_BA_ADDBA, hmac_btcoex_adjust_addba_rsp_basize);
622 hmac_feature_hook_register(HMAC_FHOOK_BTCOEX_BA_CHECK, hmac_btcoex_check_by_ba_size_etc);
623 return OAL_SUCC;
624 }
625
hmac_btcoex_ba_deinit(osal_void)626 osal_void hmac_btcoex_ba_deinit(osal_void)
627 {
628 /* 转发接口去注册 */
629 hmac_unregister_netbuf_hook(&g_btcoex_netbuf_hook);
630 /* 对外接口去注册 */
631 hmac_feature_hook_unregister(HMAC_FHOOK_BTCOEX_BA_ADDBA);
632 hmac_feature_hook_unregister(HMAC_FHOOK_BTCOEX_BA_CHECK);
633 return;
634 }
635
636 #ifdef __cplusplus
637 #if __cplusplus
638 }
639 #endif
640 #endif
641
642 #endif
643