• 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: 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