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 * 文 件 名 : hmac_twt.c
15 * 生成日期 : 2023年7月29日
16 * 功能描述 : twt
17 */
18
19 /* 1 头文件包含 */
20 #include "hmac_twt.h"
21 #include "oal_util.h"
22 #include "hmac_ext_if.h"
23 #include "hmac_resource.h"
24 #include "hmac_device.h"
25 #include "hmac_vap.h"
26 #include "hmac_mgmt_bss_comm.h"
27 #include "hmac_tx_mgmt.h"
28 #include "hmac_psm_ap.h"
29 #include "hmac_feature_dft.h"
30
31 #include "hal_device.h"
32
33 #include "mac_frame.h"
34 #ifdef _PRE_WLAN_FEATURE_P2P
35 #include "hmac_p2p.h"
36 #endif
37 #include "hmac_user.h"
38 #include "hmac_mgmt_ap.h"
39 #include "hmac_config.h"
40 #include "msg_twt_rom.h"
41 #include "hmac_ccpriv.h"
42 #include "frw_util_notifier.h"
43 #include "hmac_feature_interface.h"
44 #include "hmac_hook.h"
45 #include "oal_netbuf_data.h"
46 #include "wal_utils.h"
47
48 #ifdef __cplusplus
49 #if __cplusplus
50 extern "C" {
51 #endif
52 #endif
53
54 #undef THIS_FILE_ID
55 #define THIS_FILE_ID DIAG_FILE_ID_WIFI_HOST_HMAC_TWT_C
56
57 #undef THIS_MOD_ID
58 #define THIS_MOD_ID DIAG_MOD_ID_WIFI_HOST
59
60 /* 2 全局变量定义 */
61 sta_twt_para_stru *g_sta_twt_info[WLAN_VAP_MAX_NUM_PER_DEVICE_LIMIT] = {OSAL_NULL, OSAL_NULL, OSAL_NULL, OSAL_NULL};
62
63 /* 函数声明 */
64
65 /* 3 函数实现 */
hmac_get_sta_twt_info(osal_u8 vap_id)66 WIFI_HMAC_TCM_TEXT WIFI_TCM_TEXT OSAL_STATIC sta_twt_para_stru *hmac_get_sta_twt_info(osal_u8 vap_id)
67 {
68 if (hmac_vap_id_param_check(vap_id) != OSAL_TRUE) {
69 return OSAL_NULL;
70 }
71 return g_sta_twt_info[vap_id];
72 }
73
hmac_device_twt_custom_is_open(osal_u8 vap_id)74 WIFI_HMAC_TCM_TEXT WIFI_TCM_TEXT OSAL_STATIC osal_u8 hmac_device_twt_custom_is_open(osal_u8 vap_id)
75 {
76 if (hmac_get_sta_twt_info(vap_id) == OSAL_NULL) {
77 return OSAL_FALSE;
78 }
79 return ((g_sta_twt_info[vap_id]->sta_twt_custom_para.twt_responder_support == OSAL_TRUE) ||
80 (g_sta_twt_info[vap_id]->sta_twt_custom_para.twt_requester_support == OSAL_TRUE));
81 }
82
hmac_twt_set_resp_bit(osal_u8 vap_id,osal_u8 value)83 OSAL_STATIC osal_void hmac_twt_set_resp_bit(osal_u8 vap_id, osal_u8 value)
84 {
85 if (hmac_get_sta_twt_info(vap_id) == OSAL_NULL) {
86 return;
87 }
88 g_sta_twt_info[vap_id]->sta_twt_custom_para.twt_responder_support = value;
89 }
90
hmac_twt_set_req_bit(osal_u8 vap_id,osal_u8 value)91 OSAL_STATIC osal_void hmac_twt_set_req_bit(osal_u8 vap_id, osal_u8 value)
92 {
93 if (hmac_get_sta_twt_info(vap_id) == OSAL_NULL) {
94 return;
95 }
96 g_sta_twt_info[vap_id]->sta_twt_custom_para.twt_requester_support = value;
97 }
98
hmac_twt_get_req_bit(osal_u8 vap_id)99 OSAL_STATIC osal_u8 hmac_twt_get_req_bit(osal_u8 vap_id)
100 {
101 if (hmac_get_sta_twt_info(vap_id) == OSAL_NULL) {
102 return OSAL_FALSE;
103 }
104 return g_sta_twt_info[vap_id]->sta_twt_custom_para.twt_requester_support;
105 }
106
107 /*****************************************************************************
108 函 数 名 : hmac_twt_handle_ps
109 功能描述 : handle twt start/end interrupt
110 *****************************************************************************/
hmac_twt_handle_ps(hmac_vap_stru * hmac_vap,osal_u8 pause)111 OSAL_STATIC osal_void hmac_twt_handle_ps(hmac_vap_stru *hmac_vap, osal_u8 pause)
112 {
113 hmac_device_stru *hmac_device = hmac_res_get_mac_dev_etc(0);
114 hmac_user_stru *hmac_user = OSAL_NULL;
115 osal_u8 mac_vap_id_old = hmac_device->mac_vap_id;
116 sta_twt_para_stru *twt_info = hmac_get_sta_twt_info(hmac_vap->vap_id);
117
118 if (twt_info->sta_cfg_twt_para.twt_ps_pause == pause) {
119 oam_error_log1(0, OAM_SF_11AX, "{hmac_twt_handle_ps::hmac_vap->twt_cfg.twt_ps_pause == pause[%d].}", pause);
120 return;
121 }
122
123 hmac_user = (hmac_user_stru *)mac_res_get_hmac_user_etc(hmac_vap->assoc_vap_id);
124 if (hmac_user == OSAL_NULL) {
125 oam_error_log1(0, OAM_SF_11AX, "{hmac_twt_handle_ps::hmac_user[%d] null.}", hmac_vap->assoc_vap_id);
126 return;
127 }
128
129 /* TWT SP之外,关闭收发 */
130 if (pause == OSAL_TRUE) {
131 /* 记录当前twt节能状态 */
132 twt_info->sta_cfg_twt_para.twt_ps_pause = OSAL_TRUE;
133 hmac_user_pause(hmac_user);
134
135 /* 告知MAC用户进入节能模式, 记录睡眠时vap id */
136 hmac_device->mac_vap_id = hmac_vap->vap_id;
137 } else {
138 hmac_user_resume(hmac_user); /* 恢复该用户的硬件队列的发送 */
139 /* 记录当前twt节能状态 */
140 twt_info->sta_cfg_twt_para.twt_ps_pause = OSAL_FALSE;
141 /* 将缓存队列的数据发送 */
142 hmac_psm_queue_flush(hmac_vap, hmac_user);
143 }
144 if (mac_vap_id_old != hmac_device->mac_vap_id) {
145 /* 如果休眠vap_id发生变化,则同步 */
146 hmac_device_sync(hmac_device);
147 }
148 }
149
hmac_twt_status_d2h_sync(hmac_vap_stru * hmac_vap,mac_d2hd_twt_cfg_stru * twt_cfg)150 OSAL_STATIC osal_void hmac_twt_status_d2h_sync(hmac_vap_stru *hmac_vap, mac_d2hd_twt_cfg_stru *twt_cfg)
151 {
152 hal_to_dmac_device_stru *hal_device = hmac_vap->hal_device;
153 hmac_user_stru *hmac_user = OSAL_NULL;
154 sta_twt_para_stru *sta_twt_info = OSAL_NULL;
155
156 if (hmac_device_twt_custom_is_open(hmac_vap->vap_id) != OSAL_TRUE) {
157 return;
158 }
159
160 sta_twt_info = hmac_get_sta_twt_info(hmac_vap->vap_id);
161 sta_twt_info->sta_cfg_twt_para.twt_session_status = twt_cfg->twt_session_status;
162 sta_twt_info->sta_cfg_twt_para.twt_ps_pause = OSAL_FALSE;
163 hal_device->twt_session_enable =
164 (sta_twt_info->sta_cfg_twt_para.twt_session_status == TWT_SESSION_ON) ? OSAL_TRUE : OSAL_FALSE;
165
166 hmac_user = (hmac_user_stru *)mac_res_get_hmac_user_etc(twt_cfg->user_idx);
167 if (hmac_user != OSAL_NULL) {
168 /* 恢复tid队列 */
169 hmac_user_resume(hmac_user);
170
171 /* 释放节能队列 */
172 hmac_psm_queue_flush(hmac_vap, hmac_user);
173 } else {
174 oam_error_log0(0, OAM_SF_11AX, "{hmac_twt_status_d2hd_sync:: find dmac user fail!.}");
175 }
176 }
177
hmac_twt_update_d2h_sync(hmac_vap_stru * hmac_vap,mac_d2hd_twt_sync_info_stru * twt_cfg)178 OSAL_STATIC osal_s32 hmac_twt_update_d2h_sync(hmac_vap_stru *hmac_vap, mac_d2hd_twt_sync_info_stru *twt_cfg)
179 {
180 switch (twt_cfg->cfg_type) {
181 case TWT_UPDATE_SESSION_CFG:
182 hmac_twt_status_d2h_sync(hmac_vap, &(twt_cfg->twt_cfg));
183 break;
184 case TWT_UPDATE_PS_PAUSE_CFG:
185 hmac_get_sta_twt_info(hmac_vap->vap_id)->sta_cfg_twt_para.twt_ps_pause = OSAL_TRUE;
186 break;
187 case TWT_PS_HANDLE_CFG:
188 hmac_twt_handle_ps(hmac_vap, twt_cfg->twt_cfg.twt_ps_pause);
189 break;
190 default:
191 break;
192 }
193 return OAL_SUCC;
194 }
195
196 /*****************************************************************************
197 函 数 名 : hmac_twt_is_ps_pause
198 功能描述 : 判断TWT是否处于省电发送暂停状态
199 *****************************************************************************/
hmac_twt_is_ps_pause(const hmac_vap_stru * hmac_vap)200 WIFI_TCM_TEXT OSAL_STATIC osal_u8 hmac_twt_is_ps_pause(const hmac_vap_stru *hmac_vap)
201 {
202 return (hmac_get_sta_twt_info(hmac_vap->vap_id))->sta_cfg_twt_para.twt_ps_pause;
203 }
204
205 /*****************************************************************************
206 函 数 名 : hmac_mgmt_tx_twt_setup_req
207 功能描述 : TWT SETUP函数,需要将HMAC模块的生成的信息, 在DMAC稍作修改
208 *****************************************************************************/
hmac_mgmt_tx_twt_setup_req(hmac_vap_stru * hmac_vap,const hmac_user_stru * hmac_user,const hmac_ctx_action_event_stru * ctx_action_event,oal_netbuf_stru * netbuf)209 OSAL_STATIC osal_u32 hmac_mgmt_tx_twt_setup_req(hmac_vap_stru *hmac_vap, const hmac_user_stru *hmac_user,
210 const hmac_ctx_action_event_stru *ctx_action_event, oal_netbuf_stru *netbuf)
211 {
212 mac_individual_twt_setup_frame_stru *setup_frame = OSAL_NULL;
213 mac_tx_ctl_stru *tx_ctl = OSAL_NULL;
214 osal_u8 *data = OSAL_NULL;
215 osal_u32 ret;
216
217 /* 如果dbac或同频同信道启动P2P,则不建立twt会话 */
218 if (hal_device_calc_up_vap_num(hmac_vap->hal_device) >= 2) { /* 2: TWT和P2P不能共存 */
219 oam_warning_log0(0, OAM_SF_11AX, "{hmac_mgmt_tx_twt_setup_req:: p2p is running, do not setup twt session.}");
220 hmac_dft_print_drop_frame_info(THIS_FILE_ID, __LINE__, 1, netbuf);
221 return OAL_FAIL;
222 }
223
224 /* 将索引指向frame body起始位置 */
225 data = oal_netbuf_data_offset(netbuf, MAC_80211_FRAME_LEN);
226 setup_frame = (mac_individual_twt_setup_frame_stru *)(data);
227 setup_frame->twt_element.twt = 0;
228
229 /* 填写netbuf的cb字段,共发送管理帧和发送完成接口使用 */
230 tx_ctl = (mac_tx_ctl_stru *)oal_netbuf_cb(netbuf);
231 tx_ctl->tx_user_idx = (osal_u8)hmac_user->assoc_id;
232 tx_ctl->mpdu_num = 1; /* 管理帧只有一个 */
233 tx_ctl->ac = WLAN_WME_AC_MGMT;
234
235 /* 调用发送管理帧接口 */
236 ret = hmac_tx_mgmt(hmac_vap, netbuf, ctx_action_event->frame_len, OSAL_TRUE);
237 if (ret != OAL_SUCC) {
238 oam_error_log1(0, OAM_SF_11AX, "{hmac_mgmt_tx_twt_setup_req::hmac_tx_mgmt return Err=%d.}", ret);
239 }
240
241 return ret;
242 }
243
244 /*****************************************************************************
245 功能描述 : TWT information函数,需要将HMAC模块的生成的next-twt信息, 在DMAC作修改
246 *****************************************************************************/
hmac_mgmt_tx_twt_information_req(hmac_vap_stru * hmac_vap,const hmac_user_stru * hmac_user,const hmac_ctx_action_event_stru * ctx_action_event,oal_netbuf_stru * netbuf)247 OSAL_STATIC osal_u32 hmac_mgmt_tx_twt_information_req(hmac_vap_stru *hmac_vap, const hmac_user_stru *hmac_user,
248 const hmac_ctx_action_event_stru *ctx_action_event, oal_netbuf_stru *netbuf)
249 {
250 mac_tx_ctl_stru *tx_ctl = OSAL_NULL;
251 osal_u32 ret;
252
253 /* 填写netbuf的cb字段,共发送管理帧和发送完成接口使用 */
254 tx_ctl = (mac_tx_ctl_stru *)oal_netbuf_cb(netbuf);
255 tx_ctl->tx_user_idx = (osal_u8)hmac_user->assoc_id;
256 tx_ctl->mpdu_num = 1;
257 tx_ctl->ac = WLAN_WME_AC_MGMT;
258
259 /* 调用发送管理帧接口 */
260 ret = hmac_tx_mgmt(hmac_vap, netbuf, ctx_action_event->frame_len, OSAL_TRUE);
261 if (ret != OAL_SUCC) {
262 oam_error_log1(0, OAM_SF_11AX, "{hmac_mgmt_tx_twt_information_req::hmac_tx_mgmt return Err=%d.}", ret);
263 }
264
265 return ret;
266 }
267
268 /*****************************************************************************
269 功能描述 : send TWT teardown frame
270 *****************************************************************************/
hmac_mgmt_tx_twt_teardown_req(hmac_vap_stru * hmac_vap,const hmac_user_stru * hmac_user,const hmac_ctx_action_event_stru * ctx_action_event,oal_netbuf_stru * netbuf)271 OSAL_STATIC osal_u32 hmac_mgmt_tx_twt_teardown_req(hmac_vap_stru *hmac_vap, const hmac_user_stru *hmac_user,
272 const hmac_ctx_action_event_stru *ctx_action_event, oal_netbuf_stru *netbuf)
273 {
274 mac_tx_ctl_stru *tx_ctl = OSAL_NULL;
275 osal_u8 *data = OSAL_NULL;
276
277 osal_u32 ret;
278
279 /* 将索引指向frame body起始位置 */
280 data = oal_netbuf_data_offset(netbuf, MAC_80211_FRAME_LEN);
281 oam_warning_log3(0, OAM_SF_11AX, "{tx teardown frame:CATEGORY[%02x] ACTION[%02x] FLOW ID[%02x]!.}",
282 data[HMAC_TWT_CATEGORY], data[HMAC_TWT_ACTION], data[HMAC_TWT_FLOW_ID]);
283
284 /* 填写netbuf的cb字段,共发送管理帧和发送完成接口使用 */
285 tx_ctl = (mac_tx_ctl_stru *)oal_netbuf_cb(netbuf);
286 tx_ctl->tx_user_idx = (osal_u8)hmac_user->assoc_id;
287 tx_ctl->mpdu_num = 1; /* 管理帧只有一个 */
288 tx_ctl->ac = WLAN_WME_AC_MGMT;
289
290 /* 调用发送管理帧接口 */
291 ret = hmac_tx_mgmt(hmac_vap, netbuf, ctx_action_event->frame_len, OSAL_TRUE);
292 if (ret != OAL_SUCC) {
293 oam_error_log1(0, OAM_SF_11AX, "{hmac_mgmt_tx_twt_teardown_req::hmac_tx_mgmt return Err=%d.}", ret);
294 }
295
296 return ret;
297 }
298
299 /*****************************************************************************
300 函 数 名 : hmac_sta_twt_update_event_etc
301 功能描述 : 将twt更新事件抛向dmac层,teardown,setup,information,association处理的最终汇合
302 输入参数 : hmac_vap_stru *hmac_vap, hmac_user_stru *hmac_user, mac_ctx_update_twt_stru *update_twt_cfg
303 输出参数 : 无
304 *****************************************************************************/
hmac_sta_twt_update_event_etc(hmac_vap_stru * hmac_vap,hmac_user_stru * hmac_user,mac_twt_update_source_enum_uint8 twt_update_source)305 OSAL_STATIC osal_u32 hmac_sta_twt_update_event_etc(hmac_vap_stru *hmac_vap, hmac_user_stru *hmac_user,
306 mac_twt_update_source_enum_uint8 twt_update_source)
307 {
308 mac_ctx_update_twt_stru update_twt_cfg_event;
309 osal_s32 ret;
310 frw_msg msg_info = {0};
311
312 update_twt_cfg_event.update_source = twt_update_source;
313 update_twt_cfg_event.user_idx = hmac_user->assoc_id;
314 update_twt_cfg_event.twt_cfg = (hmac_get_sta_twt_info(hmac_vap->vap_id))->sta_cfg_twt_para;
315
316 /* 只有twt information帧才有next_twt_size */
317 if (update_twt_cfg_event.update_source != MAC_TWT_UPDATE_SOURCE_INFORMATION) {
318 update_twt_cfg_event.twt_cfg.next_twt_size = 0;
319 }
320 msg_info.data = (osal_u8 *)&update_twt_cfg_event;
321 msg_info.data_len = sizeof(mac_ctx_update_twt_stru);
322
323 ret = frw_send_msg_to_device(hmac_vap->vap_id, WLAN_MSG_H2D_C_UPDATE_TWT, &msg_info, OSAL_TRUE);
324 if (ret != OAL_SUCC) {
325 oam_warning_log1(0, OAM_SF_ANY, "{hmac_sta_twt_update_event_etc::frw_send_msg_to_device failed[%d]!.}", ret);
326 }
327
328 return (osal_u32)ret;
329 }
330 #ifdef _PRE_WLAN_SUPPORT_CCPRIV_CMD
331 /*****************************************************************************
332 函 数 名 : mac_set_twt_element_field_etc
333 功能描述 : 用于设置TWT 信息元素位,TWT_SETUP与ASSOCIATION均会调用
334 输入参数 : mac_twt_ie_individual * twt_element,mac_cfg_twt_basic_param_stru *twt_basic_param
335 *****************************************************************************/
mac_set_twt_element_field_etc(mac_twt_ie_individual_stru * twt_element,mac_cfg_twt_basic_param_stru * twt_basic_param)336 OSAL_STATIC osal_void mac_set_twt_element_field_etc(mac_twt_ie_individual_stru *twt_element,
337 mac_cfg_twt_basic_param_stru *twt_basic_param)
338 {
339 twt_element->element_id = MAC_EID_TWT;
340 twt_element->len = sizeof(mac_twt_ie_individual_stru) - 2; /* control之前有2 byte数据 */
341
342 twt_element->control.ndp_paging_indicator = 0;
343 twt_element->control.responder_pm_mode = 0;
344 twt_element->control.negotiation = 0; /* 默认支持单播TWT */
345 twt_element->control.twt_info_frame_disable = 0; /* 默认支持twt information帧 */
346 twt_element->control.wake_duration_unit = twt_basic_param->wake_duration_unit; /* min_duration的单位 */
347 twt_element->control.resv = 0;
348
349 twt_element->request_type.request = 1;
350 twt_element->request_type.setup_command = twt_basic_param->setup_command; /* 由user决定 */
351 twt_element->request_type.trigger = twt_basic_param->trigger;
352 twt_element->request_type.implicit = 1; /* 默认隐式TWT */
353 twt_element->request_type.flow_type = twt_basic_param->flow_type;
354 twt_element->request_type.flow_id = twt_basic_param->flow_id; /* 由user决定 */
355 twt_element->request_type.intrval_exponent = twt_basic_param->intrval_exponent; /* unit:us */
356 twt_element->request_type.protection = 0;
357
358 twt_element->twt = twt_basic_param->twt;
359 twt_element->min_duration = twt_basic_param->min_duration; /* user decide, unit: 256us */
360 twt_element->intrval_mantissa = twt_basic_param->intrval_mantissa; /* user decide, unit:us */
361 twt_element->channel = 0;
362
363 /* 输出维测信息 */
364 oam_warning_log4(0, OAM_SF_11AX, "{mac_set_twt_element_field_etc::command=%d,flowType=%d,flowId=%d,trigger=%d}",
365 twt_element->request_type.setup_command, twt_element->request_type.flow_type,
366 twt_element->request_type.flow_id, twt_element->request_type.trigger);
367
368 oam_warning_log4(0, OAM_SF_11AX, "{mac_set_twt_element_field_etc::twt=%d,duration=%d,exponent=%d,mantissa=%d}",
369 twt_element->twt, twt_element->min_duration,
370 twt_element->request_type.intrval_exponent, twt_element->intrval_mantissa);
371 }
372
373 /*****************************************************************************
374 函 数 名 : hmac_mgmt_encap_twt_setup_req
375 功能描述 : 组twt_setup帧
376 输入参数 : hmac_vap_stru *hmac_vap, hmac_user_stru *hmac_user,
377 osal_u8 *data, mac_cfg_twt_basic_param_stru *twt_basic_param
378 输出参数 : twt setup帧不包含FCS字段的MAC帧长度
379 *****************************************************************************/
hmac_mgmt_encap_twt_setup_req(hmac_vap_stru * hmac_vap,hmac_user_stru * hmac_user,osal_u8 * data,mac_cfg_twt_basic_param_stru * twt_basic_param,osal_u16 * frame_len)380 OSAL_STATIC osal_u32 hmac_mgmt_encap_twt_setup_req(hmac_vap_stru *hmac_vap, hmac_user_stru *hmac_user,
381 osal_u8 *data, mac_cfg_twt_basic_param_stru *twt_basic_param, osal_u16 *frame_len)
382 {
383 mac_individual_twt_setup_frame_stru setup_frame;
384 errno_t ret;
385
386 if ((data == OSAL_NULL) || (twt_basic_param == OSAL_NULL)) {
387 oam_error_log0(0, OAM_SF_11AX, "{hmac_mgmt_encap_twt_setup_req null param}");
388 return OAL_ERR_CODE_PTR_NULL;
389 }
390
391 (hmac_get_sta_twt_info(hmac_vap->vap_id))->sta_cfg_twt_para.dialog_token++;
392 oam_warning_log1(0, OAM_SF_11AX, "{hmac_mgmt_encap_twt_setup_req: sta_cfg_twt_para.dialog=%d}",
393 (hmac_get_sta_twt_info(hmac_vap->vap_id))->sta_cfg_twt_para.dialog_token);
394
395 /* 规则6.6:禁止使用内存操作类危险函数 例外(1)对固定长度的数组进行初始化,或对固定长度的结构体进行内存初始化 */
396 (void)memset_s((osal_u8 *)&setup_frame, sizeof(mac_individual_twt_setup_frame_stru),
397 0, sizeof(mac_individual_twt_setup_frame_stru));
398
399 oam_warning_log3(0, OAM_SF_11AX, "{hmac_mgmt_encap_twt_setup_req:: mac_addr[%02x XX XX XX %02x %02x]!.}",
400 hmac_user->user_mac_addr[0], hmac_user->user_mac_addr[4], /* 4 */
401 hmac_user->user_mac_addr[5]); /* 5 */
402
403 /******************************************************************************************************************/
404 /* TWT element */
405 /* -------------------------------------------------------------------------------------------------------------- */
406 /* |Element ID |Length |Control |TWT Parameter Information| */
407 /* -------------------------------------------------------------------------------------------------------------- */
408 /* |1 |1 |1 |variable | */
409 /* -------------------------------------------------------------------------------------------------------------- */
410 /* */
411 /******************************************************************************************************************/
412 /*************************************************************************/
413 /* Set the fields in the frame header */
414 /*************************************************************************/
415 /* Frame Control Field 中只需要设置Type/Subtype值,其他设置为0 */
416 mac_hdr_set_frame_control(data, WLAN_PROTOCOL_VERSION | WLAN_FC0_TYPE_MGT | WLAN_FC0_SUBTYPE_ACTION);
417
418 /* 设置 DA address1: AP MAC地址 (BSSID) */
419 oal_set_mac_addr(data + WLAN_HDR_ADDR1_OFFSET, hmac_vap->bssid);
420
421 /* 设置 SA address2: dot11MACAddress */
422 oal_set_mac_addr(data + WLAN_HDR_ADDR2_OFFSET, mac_mib_get_station_id(hmac_vap));
423
424 /* 设置 DA address3: AP MAC地址 (BSSID) */
425 oal_set_mac_addr(data + WLAN_HDR_ADDR3_OFFSET, hmac_vap->bssid);
426 /* 设置分片序号为0 */
427 mac_hdr_set_fragment_number(data, 0);
428
429 /******************************************************************************************************************/
430 /* TWT argument */
431 /* -------------------------------------------------------------------------------------------------------------- */
432 /* |setup_cmd |flow_type |flow_ID |Reserve | */
433 /* -------------------------------------------------------------------------------------------------------------- */
434 /* |1 |1 |1 |1 | */
435 /* -------------------------------------------------------------------------------------------------------------- */
436 /* */
437 /******************************************************************************************************************/
438 setup_frame.category = MAC_ACTION_CATEGORY_S1G;
439 setup_frame.action = MAC_S1G_ACTION_TWT_SETUP;
440 setup_frame.dialog_token = (hmac_get_sta_twt_info(hmac_vap->vap_id))->sta_cfg_twt_para.dialog_token;
441
442 /* 传入信息元素 */
443 mac_set_twt_element_field_etc(&(setup_frame.twt_element), twt_basic_param);
444
445 ret = memcpy_s((osal_u8 *)(data + MAC_80211_FRAME_LEN), sizeof(mac_individual_twt_setup_frame_stru),
446 (osal_u8 *)&setup_frame, sizeof(mac_individual_twt_setup_frame_stru));
447 if (ret == EOK) {
448 *frame_len = (MAC_80211_FRAME_LEN + sizeof(mac_individual_twt_setup_frame_stru)); /* 长度不包括FCS,安全校验 */
449 return OAL_SUCC;
450 } else {
451 oam_error_log0(0, OAM_SF_11AX, "{hmac_mgmt_encap_twt_setup_req::memcpy error}");
452 return OAL_FAIL;
453 }
454 }
455
456 /*****************************************************************************
457 功能描述 : 组装twt_information_req帧
458 *****************************************************************************/
hmac_mgmt_encap_twt_information_req(hmac_vap_stru * hmac_vap,osal_u8 * data,mac_twt_information_field_stru * information_filed,osal_u16 * frame_len)459 OSAL_STATIC osal_void hmac_mgmt_encap_twt_information_req(hmac_vap_stru *hmac_vap, osal_u8 *data,
460 mac_twt_information_field_stru *information_filed, osal_u16 *frame_len)
461 {
462 mac_twt_information_frame_stru *information_frame = OSAL_NULL;
463 osal_u16 information_size;
464
465 if (data == OSAL_NULL) {
466 oam_error_log0(0, OAM_SF_11AX, "{hmac_mgmt_encap_twt_information_req_etc::null data}");
467 *frame_len = 0;
468 return;
469 }
470
471 /*************************************************************************/
472 /* Set the fields in the frame header */
473 /*************************************************************************/
474 /* Frame Control Field 中只需要设置Type/Subtype值,其他设置为0 */
475 mac_hdr_set_frame_control(data, WLAN_PROTOCOL_VERSION | WLAN_FC0_TYPE_MGT | WLAN_FC0_SUBTYPE_ACTION);
476
477 /* 设置 DA address1: AP MAC地址 (BSSID) */
478 oal_set_mac_addr(data + WLAN_HDR_ADDR1_OFFSET, hmac_vap->bssid);
479
480 /* 设置 SA address2: dot11MACAddress */
481 oal_set_mac_addr(data + WLAN_HDR_ADDR2_OFFSET, mac_mib_get_station_id(hmac_vap));
482
483 /* 设置 DA address3: AP MAC地址 (BSSID) */
484 oal_set_mac_addr(data + WLAN_HDR_ADDR3_OFFSET, hmac_vap->bssid);
485 /* 设置分片序号为0 */
486 mac_hdr_set_fragment_number(data, 0);
487
488 /*************************************************************************/
489 /* Set the contents of the frame body */
490 /*************************************************************************/
491 information_frame = (mac_twt_information_frame_stru *)(data + MAC_80211_FRAME_LEN);
492 information_frame->category = MAC_ACTION_CATEGORY_S1G;
493 information_frame->action = MAC_S1G_ACTION_TWT_INFORMATION;
494
495 information_frame->twt_information_filed.flow_id = information_filed->flow_id;
496 information_frame->twt_information_filed.next_twt_subfield_size = information_filed->next_twt_subfield_size;
497 information_frame->twt_information_filed.response_requested = 0; /* 暂停/重启都无需对端回复information */
498 information_frame->twt_information_filed.next_twt_request = 0; /* 暂停/重启都无需对端提供next_twt */
499 information_frame->twt_information_filed.all_twt = 0; /* 只有一套参数 */
500
501 /* next-size有0(暂停,不带twt)和3(恢复,带64bit的twt参数两种情况 */
502 if (information_filed->next_twt_subfield_size == 0) {
503 information_size = sizeof(mac_twt_information_frame_stru) - 8; /* 8表示减去next-twt的8字节 */
504 } else {
505 information_size = sizeof(mac_twt_information_frame_stru);
506 }
507
508 *frame_len = (MAC_80211_FRAME_LEN + information_size); /* 返回的帧长度中不包括FCS */
509 }
510 #endif
511
hmac_twt_fill_ctx_and_cb(hmac_vap_stru * hmac_vap,oal_netbuf_stru * twt_frame,osal_u16 length,osal_u32 sub_type,osal_u32 action_sub_type)512 OSAL_STATIC osal_u32 hmac_twt_fill_ctx_and_cb(hmac_vap_stru *hmac_vap, oal_netbuf_stru *twt_frame,
513 osal_u16 length, osal_u32 sub_type, osal_u32 action_sub_type)
514 {
515 mac_tx_ctl_stru *tx_ctl = OSAL_NULL;
516 hmac_ctx_action_event_stru wlan_ctx_action = {0};
517 hmac_user_stru *hmac_user = (hmac_user_stru *)mac_res_get_hmac_user_etc(hmac_vap->assoc_vap_id);
518 errno_t ret;
519
520 if (hmac_user == OSAL_NULL) {
521 return OAL_ERR_CODE_PTR_NULL;
522 }
523
524 /* 赋值要传入Dmac的信息 */
525 wlan_ctx_action.frame_len = length;
526 wlan_ctx_action.hdr_len = MAC_80211_FRAME_LEN;
527 wlan_ctx_action.action_category = MAC_ACTION_CATEGORY_S1G;
528 wlan_ctx_action.action = (osal_u8)action_sub_type;
529 wlan_ctx_action.user_idx = hmac_user->assoc_id;
530
531 ret = memcpy_s((osal_u8 *)(oal_netbuf_data(twt_frame) + length), sizeof(hmac_ctx_action_event_stru),
532 (osal_u8 *)&wlan_ctx_action, sizeof(hmac_ctx_action_event_stru));
533 if (ret != EOK) {
534 hmac_dft_print_drop_frame_info(THIS_FILE_ID, __LINE__, 1, twt_frame);
535 oam_error_log2(0, OAM_SF_11AX,
536 "vap_id[%d] {hmac_twt_fill_ctx_and_cb::memcpy err=%d}", hmac_vap->vap_id, ret);
537 oal_netbuf_free(twt_frame);
538 return OAL_FAIL;
539 }
540
541 oal_netbuf_put(twt_frame, (length + sizeof(hmac_ctx_action_event_stru)));
542
543 /* 初始化CB */
544 (void)memset_s(oal_netbuf_cb(twt_frame), OAL_NETBUF_CB_SIZE(), 0, OAL_NETBUF_CB_SIZE());
545
546 tx_ctl = (mac_tx_ctl_stru *)oal_netbuf_cb(twt_frame);
547 tx_ctl->mpdu_payload_len = length + sizeof(hmac_ctx_action_event_stru);
548 tx_ctl->frame_type = WLAN_CB_FRAME_TYPE_ACTION;
549 tx_ctl->frame_subtype = (wlan_cb_frame_subtype_enum_uint8)sub_type;
550
551 return OAL_SUCC;
552 }
553 #ifdef _PRE_WLAN_SUPPORT_CCPRIV_CMD
554 /*****************************************************************************
555 功能描述 : 组装twt_information_req帧发送
556 *****************************************************************************/
hmac_mgmt_tx_twt_information(hmac_vap_stru * hmac_vap,hmac_user_stru * hmac_user,mac_twt_information_field_stru * information_filed)557 OSAL_STATIC osal_u32 hmac_mgmt_tx_twt_information(hmac_vap_stru *hmac_vap, hmac_user_stru *hmac_user,
558 mac_twt_information_field_stru *information_filed)
559 {
560 oal_netbuf_stru *twt_information_req = OSAL_NULL;
561 osal_u16 length; /* 帧长度 */
562 osal_u32 ret;
563
564 unref_param(hmac_user);
565
566 /* 申请TWT INFORMATION管理帧内存 */
567 twt_information_req = OAL_MEM_NETBUF_ALLOC(OAL_NORMAL_NETBUF, WLAN_MEM_NETBUF_SIZE2, OAL_NETBUF_PRIORITY_MID);
568 if (twt_information_req == OSAL_NULL) {
569 oam_error_log1(0, OAM_SF_11AX,
570 "vap_id[%d] {hmac_mgmt_tx_twt_information::information_req null.}", hmac_vap->vap_id);
571 return OAL_ERR_CODE_PTR_NULL;
572 }
573
574 twt_information_req->prev = OSAL_NULL;
575 twt_information_req->next = OSAL_NULL;
576
577 /* 调用封装管理帧接口 */
578 hmac_mgmt_encap_twt_information_req(hmac_vap, oal_netbuf_data(twt_information_req), information_filed, &length);
579 if (length == 0) {
580 hmac_dft_print_drop_frame_info(THIS_FILE_ID, __LINE__, 1, OAL_PTR_NULL);
581 oam_error_log1(0, OAM_SF_11AX, "vap_id[%d] {hmac_mgmt_tx_twt_information::encap err=%d}", hmac_vap->vap_id);
582 oal_netbuf_free(twt_information_req);
583 return OAL_FAIL;
584 }
585
586 ret = hmac_twt_fill_ctx_and_cb(hmac_vap, twt_information_req, length,
587 WLAN_ACTION_TWT_INFORMATION_REQ, MAC_S1G_ACTION_TWT_INFORMATION);
588 if (ret != OAL_SUCC) {
589 return ret;
590 }
591
592 ret = hmac_tx_mgmt_send_event_etc(hmac_vap, twt_information_req, length); /* 执行失败再函数内释放内存 */
593 if (ret != OAL_SUCC) {
594 oam_error_log2(0, OAM_SF_11AX,
595 "vap_id[%d] {hmac_mgmt_tx_twt_information::event send err=%d}", hmac_vap->vap_id, ret);
596 }
597
598 return ret;
599 }
600
601 /*****************************************************************************
602 功能描述 : 组twt_setup帧发送
603 *****************************************************************************/
hmac_mgmt_tx_twt_setup(hmac_vap_stru * hmac_vap,hmac_user_stru * hmac_user,mac_cfg_twt_basic_param_stru * twt_basic_param)604 OSAL_STATIC osal_u32 hmac_mgmt_tx_twt_setup(hmac_vap_stru *hmac_vap, hmac_user_stru *hmac_user,
605 mac_cfg_twt_basic_param_stru *twt_basic_param)
606 {
607 oal_netbuf_stru *twt_setup_req = OSAL_NULL;
608 osal_u32 ret;
609 osal_u16 frame_len; /* 帧的长度 */
610
611 /* 申请TWT SETUP管理帧内存 */
612 twt_setup_req = OAL_MEM_NETBUF_ALLOC(OAL_NORMAL_NETBUF, WLAN_MEM_NETBUF_SIZE2, OAL_NETBUF_PRIORITY_MID);
613 if (twt_setup_req == OSAL_NULL) {
614 return OAL_ERR_CODE_PTR_NULL;
615 }
616
617 twt_setup_req->prev = OSAL_NULL;
618 twt_setup_req->next = OSAL_NULL;
619
620 /* 调用封装管理帧接口 */
621 ret = hmac_mgmt_encap_twt_setup_req(hmac_vap, hmac_user, oal_netbuf_data(twt_setup_req),
622 twt_basic_param, &frame_len);
623 if (ret != OAL_SUCC) {
624 hmac_dft_print_drop_frame_info(THIS_FILE_ID, __LINE__, 1, OAL_PTR_NULL);
625 oam_error_log2(0, OAM_SF_11AX, "vap_id[%d] {hmac_mgmt_tx_twt_setup::encap err=%d}", hmac_vap->vap_id, ret);
626 oal_netbuf_free(twt_setup_req);
627 return ret;
628 }
629
630 ret = hmac_twt_fill_ctx_and_cb(hmac_vap, twt_setup_req, frame_len,
631 WLAN_ACTION_TWT_SETUP_REQ, MAC_S1G_ACTION_TWT_SETUP);
632 if (ret != OAL_SUCC) {
633 return ret;
634 }
635
636 return hmac_tx_mgmt_send_event_etc(hmac_vap, twt_setup_req, frame_len);
637 }
638 #endif
639
640 /*****************************************************************************
641 功能描述 : 组装twt_teardown_req帧
642 *****************************************************************************/
hmac_mgmt_encap_twt_teardown_req(hmac_vap_stru * hmac_vap,hmac_user_stru * hmac_user,osal_u8 * data,osal_u8 flow_id,osal_u16 * frame_len)643 OSAL_STATIC osal_u32 hmac_mgmt_encap_twt_teardown_req(hmac_vap_stru *hmac_vap, hmac_user_stru *hmac_user,
644 osal_u8 *data, osal_u8 flow_id, osal_u16 *frame_len)
645 {
646 mac_twt_teardown_stru twt_teardown;
647 errno_t ret;
648
649 if (data == OSAL_NULL) {
650 oam_error_log0(0, OAM_SF_11AX, "{hmac_mgmt_encap_twt_teardown_req::null data}");
651 return OAL_ERR_CODE_PTR_NULL;
652 }
653
654 ret = memset_s((osal_u8 *)&twt_teardown, OAL_SIZEOF(mac_twt_teardown_stru), 0, OAL_SIZEOF(mac_twt_teardown_stru));
655 if (ret != EOK) {
656 oam_error_log0(0, OAM_SF_11AX, "{hmac_mgmt_encap_twt_teardown_req::MEMSET Teardown Frame ERROR}");
657 return OAL_FAIL;
658 }
659
660 oam_warning_log3(0, OAM_SF_11AX, "{hmac_mgmt_encap_twt_setup_req:: mac_addr[%02x XX XX XX %02x %02x]!.}",
661 hmac_user->user_mac_addr[0], hmac_user->user_mac_addr[4], /* 4 */
662 hmac_user->user_mac_addr[5]); /* 5 */
663
664 /*************************************************************************/
665 /* Set the fields in the frame header */
666 /*************************************************************************/
667 /* Frame Control Field 中只需要设置Type/Subtype值,其他设置为0 */
668 mac_hdr_set_frame_control(data, WLAN_PROTOCOL_VERSION | WLAN_FC0_TYPE_MGT | WLAN_FC0_SUBTYPE_ACTION);
669
670 /* 设置 DA address1: AP MAC地址 (BSSID) */
671 oal_set_mac_addr(data + WLAN_HDR_ADDR1_OFFSET, hmac_vap->bssid);
672
673 /* 设置 SA address2: dot11MACAddress */
674 oal_set_mac_addr(data + WLAN_HDR_ADDR2_OFFSET, mac_mib_get_station_id(hmac_vap));
675
676 /* 设置 DA address3: AP MAC地址 (BSSID) */
677 oal_set_mac_addr(data + WLAN_HDR_ADDR3_OFFSET, hmac_vap->bssid);
678 /* 设置分片序号为0 */
679 mac_hdr_set_fragment_number(data, 0);
680
681 /*************************************************************************/
682 /* Set the contents of the frame body */
683 /*************************************************************************/
684 twt_teardown.category = MAC_ACTION_CATEGORY_S1G;
685 twt_teardown.action = MAC_S1G_ACTION_TWT_TEARDOWN;
686
687 twt_teardown.flow_id = flow_id; /* 由user决定 */
688 twt_teardown.resv1 = 0;
689 twt_teardown.nego_type = 0; /* 默认设置为单播TWT的teardown */
690 twt_teardown.teardown_all_twt = 0;
691
692 ret = memcpy_s((osal_u8 *)(data + MAC_80211_FRAME_LEN), sizeof(mac_twt_teardown_stru),
693 (osal_u8 *)&twt_teardown, sizeof(mac_twt_teardown_stru));
694 if (ret != EOK) {
695 oam_error_log0(0, OAM_SF_11AX, "{hmac_mgmt_encap_twt_teardown_req::memcpy error}");
696 return OAL_FAIL;
697 }
698
699 *frame_len = (MAC_80211_FRAME_LEN + sizeof(mac_twt_teardown_stru)); /* 返回的帧长度中不包括FCS */
700 return OAL_SUCC;
701 }
702
703 /*****************************************************************************
704 功能描述 : 组装twt_teardown_req帧发送
705 *****************************************************************************/
hmac_mgmt_tx_twt_teardown(hmac_vap_stru * hmac_vap,hmac_user_stru * hmac_user,osal_u8 flow_id)706 OSAL_STATIC osal_u32 hmac_mgmt_tx_twt_teardown(hmac_vap_stru *hmac_vap, hmac_user_stru *hmac_user, osal_u8 flow_id)
707 {
708 oal_netbuf_stru *twt_teardown_req = OSAL_NULL;
709 osal_u16 length; /* 帧长度 */
710 osal_u32 ret;
711
712 /* 申请TWT TEARDOWN管理帧内存 */
713 twt_teardown_req = OAL_MEM_NETBUF_ALLOC(OAL_NORMAL_NETBUF, WLAN_MEM_NETBUF_SIZE2, OAL_NETBUF_PRIORITY_MID);
714 if (twt_teardown_req == OSAL_NULL) {
715 oam_error_log1(0, OAM_SF_11AX, "vap_id[%d] hmac_mgmt_tx_twt_teardown::malloc null.", hmac_vap->vap_id);
716 return OAL_ERR_CODE_PTR_NULL;
717 }
718
719 twt_teardown_req->prev = OSAL_NULL;
720 twt_teardown_req->next = OSAL_NULL;
721
722 /* 调用封装管理帧接口 */
723 ret = hmac_mgmt_encap_twt_teardown_req(hmac_vap, hmac_user, oal_netbuf_data(twt_teardown_req), flow_id, &length);
724 if (ret != OAL_SUCC) {
725 hmac_dft_print_drop_frame_info(THIS_FILE_ID, __LINE__, 1, OAL_PTR_NULL);
726 oam_error_log2(0, OAM_SF_11AX, "vap_id[%d] {hmac_mgmt_tx_twt_teardown::encap err=%d}", hmac_vap->vap_id, ret);
727 oal_netbuf_free(twt_teardown_req);
728 return ret;
729 }
730
731 ret = hmac_twt_fill_ctx_and_cb(hmac_vap, twt_teardown_req, length,
732 WLAN_ACTION_TWT_TEARDOWN_REQ, MAC_S1G_ACTION_TWT_TEARDOWN);
733 if (ret != OAL_SUCC) {
734 return ret;
735 }
736
737 ret = hmac_tx_mgmt_send_event_etc(hmac_vap, twt_teardown_req, length);
738 if (ret != OAL_SUCC) {
739 oam_error_log2(0, OAM_SF_11AX, "vap[%d] hmac_mgmt_tx_twt_teardown::event send err=%d", hmac_vap->vap_id, ret);
740 }
741
742 return ret;
743 }
744
745 /*****************************************************************************
746 功能描述 : 寻找处在UP状态的 wlan sta
747 *****************************************************************************/
mac_device_find_up_sta_wlan_etc(hmac_device_stru * hmac_device,hmac_vap_stru ** hmac_vap)748 OSAL_STATIC osal_u32 mac_device_find_up_sta_wlan_etc(hmac_device_stru *hmac_device, hmac_vap_stru **hmac_vap)
749 {
750 osal_u8 vap_idx;
751 hmac_vap_stru *mac_vap_tmp = OSAL_NULL;
752
753 for (vap_idx = 0; vap_idx < hmac_device->vap_num; vap_idx++) {
754 mac_vap_tmp = mac_res_get_hmac_vap(hmac_device->vap_id[vap_idx]);
755 if (mac_vap_tmp == OSAL_NULL) {
756 oam_warning_log1(0, OAM_SF_SCAN, "mac_device_find_up_sta_wlan_etc::vap is null! vap id is %d",
757 hmac_device->vap_id[vap_idx]);
758 continue;
759 }
760
761 if (((mac_vap_tmp->vap_state == MAC_VAP_STATE_UP) || (mac_vap_tmp->vap_state == MAC_VAP_STATE_PAUSE)) &&
762 (mac_vap_tmp->p2p_mode == WLAN_LEGACY_VAP_MODE)) {
763 *hmac_vap = mac_vap_tmp;
764 return OAL_SUCC;
765 }
766 }
767
768 *hmac_vap = OSAL_NULL;
769 return OAL_FAIL;
770 }
771
772 /*****************************************************************************
773 功能描述 : 从twt element中提取twt参数,存储到hmac vap中
774 *****************************************************************************/
hmac_sta_twt_save_parameters(hmac_vap_stru * hmac_vap,mac_twt_ie_individual_stru * twt_element)775 OSAL_STATIC osal_void hmac_sta_twt_save_parameters(hmac_vap_stru *hmac_vap,
776 mac_twt_ie_individual_stru *twt_element)
777 {
778 osal_u32 wake_unit[2] = {WAKE_DURATION_UNIT0, WAKE_DURATION_UNIT1}; /* 2:数组表示时间单位,0与1分别表示256与1024us */
779 sta_twt_para_stru *twt_info = hmac_get_sta_twt_info(hmac_vap->vap_id);
780 /*************************************************************************/
781 /* TWT Element Format */
782 /* --------------------------------------------------------------------- */
783 /* |Element ID | Length | Control | TWT parameter Information */
784 /* --------------------------------------------------------------------- */
785 /* | 1 | 1 | 1 | Variable | */
786 /* --------------------------------------------------------------------- */
787 /*************************************************************************/
788 twt_info->sta_cfg_twt_para.twt_basic_param.setup_command = twt_element->request_type.setup_command;
789 twt_info->sta_cfg_twt_para.twt_basic_param.flow_type = twt_element->request_type.flow_type;
790 twt_info->sta_cfg_twt_para.twt_basic_param.flow_id = twt_element->request_type.flow_id;
791 twt_info->sta_cfg_twt_para.twt_basic_param.trigger = twt_element->request_type.trigger;
792
793 twt_info->sta_cfg_twt_para.twt_basic_param.min_duration = twt_element->min_duration;
794 twt_info->sta_cfg_twt_para.twt_basic_param.intrval_exponent = twt_element->request_type.intrval_exponent;
795 twt_info->sta_cfg_twt_para.twt_basic_param.intrval_mantissa = twt_element->intrval_mantissa;
796 twt_info->sta_cfg_twt_para.twt_basic_param.twt = twt_element->twt;
797
798 twt_info->sta_cfg_twt_para.twt_interval = (osal_u32)twt_element->intrval_mantissa <<
799 twt_element->request_type.intrval_exponent;
800
801 /* wake_duration_unit为1时单位为1024us,为0时为256us */
802 twt_info->sta_cfg_twt_para.twt_duration = ((osal_u32)twt_element->min_duration) *
803 wake_unit[twt_element->control.wake_duration_unit];
804 twt_info->sta_cfg_twt_para.twt_basic_param.information_disable = twt_element->control.twt_info_frame_disable;
805
806 twt_info->sta_cfg_twt_para.twt_session_status = TWT_SESSION_ON;
807 }
808
809 /*****************************************************************************
810 函 数 名 : hmac_sta_rx_twt_negotiate
811 功能描述 : 根据协商命令字段进一步处理,来源有twt_setup以及association
812 修改 : 传入的参数为mac_twt_ie_individual_stru类型,同时要告知来源是association还是twt_setup
813 *****************************************************************************/
hmac_sta_rx_twt_negotiate(hmac_vap_stru * hmac_vap,hmac_user_stru * hmac_user,mac_twt_ie_individual_stru * twt_element,mac_twt_update_source_enum_uint8 twt_update_source)814 OSAL_STATIC osal_u32 hmac_sta_rx_twt_negotiate(hmac_vap_stru *hmac_vap, hmac_user_stru *hmac_user,
815 mac_twt_ie_individual_stru *twt_element, mac_twt_update_source_enum_uint8 twt_update_source)
816 {
817 mac_twt_command_enum_uint8 command = (mac_twt_command_enum_uint8)twt_element->request_type.setup_command;
818 osal_u32 ret;
819
820 /* 协商开始 */
821 switch (command) {
822 case MAC_TWT_COMMAND_ACCEPT:
823 case MAC_TWT_COMMAND_ALTERNATE:
824 /* 保存参数并发事件 */
825 hmac_sta_twt_save_parameters(hmac_vap, twt_element);
826 ret = hmac_sta_twt_update_event_etc(hmac_vap, hmac_user, twt_update_source);
827 if (ret != OAL_SUCC) {
828 oam_error_log1(0, OAM_SF_11AX,
829 "{hmac_sta_rx_twt_negotiate::hmac_sta_twt_update_event_etc return err=[%d]}", ret);
830 return ret;
831 }
832 break;
833
834 /* 以下内容待补充 */
835 case MAC_TWT_COMMAND_DICTATE:
836 case MAC_TWT_COMMAND_REJECT:
837 oam_info_log1(0, OAM_SF_11AX, "{hmac_sta_rx_twt_negotiate:: command=%d}", command);
838 break;
839
840 default:
841 oam_error_log1(0, OAM_SF_11AX, "{hmac_sta_rx_twt_negotiate:: invalid command =[%d]}", command);
842 return OAL_FAIL;
843 }
844 return OAL_SUCC;
845 }
846
847 /*****************************************************************************
848 功能描述 : 在association response中处理twt元素
849 *****************************************************************************/
hmac_sta_rx_twt_association_frame_etc(hmac_vap_stru * hmac_vap,hmac_user_stru * hmac_user,osal_u8 * payload)850 OSAL_STATIC osal_void hmac_sta_rx_twt_association_frame_etc(hmac_vap_stru *hmac_vap, hmac_user_stru *hmac_user,
851 osal_u8 *payload)
852 {
853 mac_twt_ie_individual_stru *twt_element = (mac_twt_ie_individual_stru *)payload;
854 osal_u64 twt_interval;
855 osal_u32 twt_wake_duration, ret;
856 osal_u32 wake_unit[2] = {WAKE_DURATION_UNIT0, WAKE_DURATION_UNIT1}; /* 2:数组表示时间单位,0与1分别表示256与1024us */
857
858 oam_warning_log4(0, OAM_SF_11AX,
859 "{hmac_sta_rx_twt_accociation_frame_etc:: flow_id:%d, flow_type:%d, trigger:%d, setup_command:%d}",
860 twt_element->request_type.flow_id, twt_element->request_type.flow_type, twt_element->request_type.trigger,
861 twt_element->request_type.setup_command);
862
863 /* 长度校验! */
864 if (twt_element->len != (sizeof(mac_twt_ie_individual_stru) - 2)) { /* 控制位之前有2个byte */
865 oam_error_log1(0, OAM_SF_11AX, "{hmac_sta_rx_twt_association_frame_etc::error len:%d}", twt_element->len);
866 return;
867 }
868
869 /* 检测TWT命令字段,MAC_TWT_ACCEPT以内错误 */
870 if (twt_element->request_type.setup_command < MAC_TWT_COMMAND_ACCEPT) {
871 oam_error_log1(0, OAM_SF_11AX, "{hmac_sta_rx_twt_association_frame_etc::error command=%d}",
872 twt_element->request_type.setup_command);
873 return;
874 }
875
876 /* interval及min_duration获取,min_duration单位需要判断 */
877 twt_interval = (osal_u64)twt_element->intrval_mantissa << twt_element->request_type.intrval_exponent;
878 twt_wake_duration = ((osal_u32)twt_element->min_duration) * wake_unit[twt_element->control.wake_duration_unit];
879
880 /* twt_interval与twt_min_duration校验 */
881 if ((twt_interval > 0xffffffff) || (twt_interval < (osal_u64)twt_wake_duration)) { /* 0xffffffff: 寄存器最大位数 */
882 oam_error_log3(0, OAM_SF_11AX,
883 "vap_id[%d] {hmac_sta_rx_twt_association_frame_etc::interval[%d], duration[%d]!}",
884 hmac_vap->vap_id, twt_interval, twt_wake_duration);
885 return;
886 }
887
888 /* 进行协商,参数传入了twt更新来源 */
889 ret = hmac_sta_rx_twt_negotiate(hmac_vap, hmac_user, twt_element, MAC_TWT_UPDATE_SOURCE_ASSOCIATION);
890 if (ret != OAL_SUCC) {
891 /* 输出错误 */
892 oam_error_log1(0, OAM_SF_11AX, "{hmac_sta_rx_twt_association_frame_etc:: negotiate error = [%d]}", ret);
893 }
894 }
895
896 /*****************************************************************************
897 函 数 名 : hmac_sta_rx_twt_para_verify_etc
898 功能描述 : STA从空口接收TWT setup帧的参数校验函数
899 输入参数 : hmac_vap_stru *hmac_vap, hmac_user_stru *hmac_user, mac_individual_twt_setup_frame_stru *setup_frame
900 输出参数 : 无
901 *****************************************************************************/
hmac_sta_rx_twt_para_verify_etc(hmac_vap_stru * hmac_vap,hmac_user_stru * hmac_user,mac_individual_twt_setup_frame_stru * setup_frame)902 OSAL_STATIC osal_u32 hmac_sta_rx_twt_para_verify_etc(hmac_vap_stru *hmac_vap, hmac_user_stru *hmac_user,
903 mac_individual_twt_setup_frame_stru *setup_frame)
904 {
905 osal_u64 twt_interval;
906 osal_u32 twt_wake_duration, ret;
907 osal_u32 wake_unit[2] = {WAKE_DURATION_UNIT0, WAKE_DURATION_UNIT1}; /* 2:数组表示时间单位,0与1分别表示256与1024us */
908 osal_u8 command = (osal_u8)setup_frame->twt_element.request_type.setup_command;
909 sta_twt_para_stru *twt_info = hmac_get_sta_twt_info(hmac_vap->vap_id);
910
911 /* 非TWT element */
912 if (setup_frame->twt_element.element_id != MAC_EID_TWT) {
913 oam_error_log1(0, OAM_SF_11AX, "{hmac_sta_rx_twt_setup_frame:id=%d}", setup_frame->twt_element.element_id);
914 return OAL_FAIL;
915 }
916
917 /* 若TWT已存在,且收到的TWT与当前TWT的id不匹配时错误 */
918 if ((twt_info->sta_cfg_twt_para.twt_session_status != TWT_SESSION_OFF) &&
919 (twt_info->sta_cfg_twt_para.twt_basic_param.flow_id != setup_frame->twt_element.request_type.flow_id)) {
920 oam_error_log2(0, OAM_SF_11AX, "{hmac_sta_rx_twt_setup_frame::unmatched id1=%d,id2=%d}",
921 twt_info->sta_cfg_twt_para.twt_basic_param.flow_id, setup_frame->twt_element.request_type.flow_id);
922 return OAL_FAIL;
923 }
924
925 /* 检测TWT命令字段,MAC_TWT_COMMAND_DEMAND以内错误 */
926 if (command < MAC_TWT_COMMAND_ACCEPT) {
927 oam_error_log1(0, OAM_SF_11AX, "{hmac_sta_rx_twt_setup_frame::command ERR=%d}", command);
928 return OAL_FAIL;
929 }
930
931 /* 检查dialog token */
932 if ((setup_frame->dialog_token != 0) && (setup_frame->dialog_token != twt_info->sta_cfg_twt_para.dialog_token)) {
933 oam_error_log2(0, OAM_SF_11AX, "{hmac_sta_rx_twt_setup_frame::dialog token diff.rx=%d,tx=%d}",
934 setup_frame->dialog_token, twt_info->sta_cfg_twt_para.dialog_token);
935 return OAL_FAIL;
936 }
937
938 /* interval及min_duration获取,min_duration单位需要判断 */
939 twt_interval = ((osal_u64)setup_frame->twt_element.intrval_mantissa) <<
940 setup_frame->twt_element.request_type.intrval_exponent;
941
942 twt_wake_duration = ((osal_u32)setup_frame->twt_element.min_duration) *
943 wake_unit[setup_frame->twt_element.control.wake_duration_unit];
944
945 /* twt_interval与twt_min_duration校验 */
946 if (twt_interval < (osal_u64)twt_wake_duration) {
947 oam_error_log2(0, OAM_SF_11AX, "{hmac_sta_rx_twt_setup_frame:i=%d<d=%d}", twt_interval, twt_wake_duration);
948 return OAL_FAIL;
949 }
950
951 /* 0xffffffff: 收到AP发来的Accept且interval参数不合理,发送teardown撤销AP侧的TWT协商 */
952 if (twt_interval > 0xffffffff) {
953 if (command == MAC_TWT_COMMAND_ACCEPT) {
954 oam_error_log1(0, OAM_SF_11AX, "{hmac_sta_rx_twt_setup_frame::twt interval[%d]}", twt_interval);
955 ret = hmac_mgmt_tx_twt_teardown(hmac_vap, hmac_user,
956 (osal_u8)setup_frame->twt_element.request_type.flow_id);
957 if (ret != OAL_SUCC) {
958 oam_error_log1(0, OAM_SF_11AX, "{hmac_sta_rx_twt_setup_frame::teardown err[%d]}", ret);
959 return ret;
960 }
961 }
962 return OAL_FAIL;
963 }
964 return OAL_SUCC;
965 }
966
967 /*****************************************************************************
968 功能描述 : STA从空口接收TWT setup帧的处理函数
969 *****************************************************************************/
hmac_sta_rx_twt_setup_frame(hmac_vap_stru * hmac_vap,hmac_user_stru * hmac_user,mac_individual_twt_setup_frame_stru * setup_frame)970 OSAL_STATIC osal_u32 hmac_sta_rx_twt_setup_frame(hmac_vap_stru *hmac_vap, hmac_user_stru *hmac_user,
971 mac_individual_twt_setup_frame_stru *setup_frame)
972 {
973 osal_u32 ret;
974
975 /******************************************************************/
976 /* TWT setup Frame - Frame Body */
977 /* --------------------------------------------------------------- */
978 /* | Category | Action | Dialog | TWT element | */
979 /* --------------------------------------------------------------- */
980 /* | 1 | 1 | 1 | Variable | */
981 /* --------------------------------------------------------------- */
982 /* */
983 /******************************************************************/
984 /*************************************************************************/
985 /* TWT Element Format */
986 /* --------------------------------------------------------------------- */
987 /* |Element ID | Length | Control | TWT parameter Information */
988 /* --------------------------------------------------------------------- */
989 /* | 1 | 1 | 1 | Variable | */
990 /* --------------------------------------------------------------------- */
991 /*************************************************************************/
992 oam_warning_log3(0, OAM_SF_11AX, "{hmac_sta_rx_twt_setup_frame:: flow_id:%d, flow_type:%d, setup_command:%d}",
993 setup_frame->twt_element.request_type.flow_id, setup_frame->twt_element.request_type.flow_type,
994 setup_frame->twt_element.request_type.setup_command);
995
996 /* 判断twt开关是否打开 */
997 if (hmac_twt_get_req_bit(hmac_vap->vap_id) == OSAL_FALSE) {
998 oam_error_log0(0, OAM_SF_11AX, "{hmac_sta_rx_twt_setup_frame::twt requester support off}");
999 return OAL_FAIL;
1000 }
1001
1002 /* 进行TWT参数校验 */
1003 ret = hmac_sta_rx_twt_para_verify_etc(hmac_vap, hmac_user, setup_frame);
1004 if (ret != OAL_SUCC) {
1005 oam_error_log1(0, OAM_SF_11AX, "{hmac_sta_rx_twt_setup_frame:: in valid para=[%d]}", ret);
1006 return ret;
1007 }
1008
1009 /* 进行TWT协商 */
1010 ret = hmac_sta_rx_twt_negotiate(hmac_vap, hmac_user, &(setup_frame->twt_element), MAC_TWT_UPDATE_SOURCE_SETUP);
1011 if (ret != OAL_SUCC) {
1012 oam_error_log1(0, OAM_SF_11AX, "{hmac_sta_rx_twt_setup_frame:: negotiation failed error=[%d]}", ret);
1013 }
1014
1015 return ret;
1016 }
1017
1018 /*****************************************************************************
1019 功能描述 : 从空口接收到TWT teardown帧的处理函数
1020 *****************************************************************************/
hmac_sta_rx_twt_teardown_frame(hmac_vap_stru * hmac_vap,hmac_user_stru * hmac_user,osal_u8 * payload)1021 OSAL_STATIC osal_u32 hmac_sta_rx_twt_teardown_frame(hmac_vap_stru *hmac_vap,
1022 hmac_user_stru *hmac_user, osal_u8 *payload)
1023 {
1024 mac_twt_teardown_stru *twt_teardown = (mac_twt_teardown_stru *)payload;
1025 osal_u32 ret;
1026 osal_u8 dialog_token;
1027 sta_twt_para_stru *twt_info = hmac_get_sta_twt_info(hmac_vap->vap_id);
1028
1029 /******************************************************************/
1030 /* TWT teardown Frame - Frame Body */
1031 /* --------------------------------------------------------------- */
1032 /* | Category | Action | TWT Flow | */
1033 /* --------------------------------------------------------------- */
1034 /* | 1 | 1 | 1 | */
1035 /* --------------------------------------------------------------- */
1036 /* */
1037 /******************************************************************/
1038 oam_warning_log3(0, OAM_SF_11AX, "vap_id[%d] {hmac_sta_rx_twt_teardown_frame::flow_id:%d, nego_type:%d}",
1039 hmac_vap->vap_id,
1040 twt_teardown->flow_id, twt_teardown->nego_type);
1041
1042 /* 只支持删除单播TWT会话 */
1043 if (twt_teardown->nego_type != 0) {
1044 oam_warning_log2(0, OAM_SF_11AX,
1045 "vap_id[%d] {hmac_sta_rx_twt_teardown_frame::nego_type[%d] Error}", hmac_vap->vap_id,
1046 twt_teardown->nego_type);
1047 return OAL_FAIL;
1048 }
1049
1050 /* 检查TWT是否在运行 */
1051 if (twt_info->sta_cfg_twt_para.twt_session_status == TWT_SESSION_OFF) {
1052 oam_warning_log1(0, OAM_SF_11AX, "vap_id[%d] {hmac_sta_rx_twt_teardown_frame::twt already disable}",
1053 hmac_vap->vap_id);
1054 return OAL_FAIL;
1055 }
1056
1057 /* 检查flow id */
1058 if (twt_info->sta_cfg_twt_para.twt_basic_param.flow_id != twt_teardown->flow_id) {
1059 oam_error_log3(0, OAM_SF_11AX,
1060 "vap_id[%d] {hmac_sta_rx_twt_teardown_frame:: the flow id [%d] is invalid,our flow id is [%d]}",
1061 hmac_vap->vap_id, twt_teardown->flow_id, twt_info->sta_cfg_twt_para.twt_basic_param.flow_id);
1062 return OAL_FAIL;
1063 }
1064
1065 /* 暂存,为下面清零后恢复 */
1066 dialog_token = twt_info->sta_cfg_twt_para.dialog_token;
1067
1068 (void)memset_s((osal_u8 *)&(twt_info->sta_cfg_twt_para), sizeof(mac_cfg_twt_stru), 0, sizeof(mac_cfg_twt_stru));
1069
1070 twt_info->sta_cfg_twt_para.twt_basic_param.flow_id = twt_teardown->flow_id;
1071 twt_info->sta_cfg_twt_para.dialog_token = dialog_token;
1072
1073 /* 调用发事件函数,事件分发至dmac */
1074 ret = hmac_sta_twt_update_event_etc(hmac_vap, hmac_user, MAC_TWT_UPDATE_SOURCE_TEARDOWN);
1075 if (ret != OAL_SUCC) {
1076 oam_error_log1(0, OAM_SF_11AX, "{hmac_sta_rx_twt_teardown_frame:: teardown failed error=[%d]}", ret);
1077 }
1078 return ret;
1079 }
1080
1081 /*****************************************************************************
1082 函 数 名 : hmac_get_next_twt
1083 功能描述 : 从twt information帧中获取next twt
1084 输入参数 : hmac_vap_stru *hmac_vap, osal_u8 *payload, osal_u8 next_twt_subfd_size
1085 输出参数 : 无
1086 *****************************************************************************/
hmac_get_next_twt(hmac_vap_stru * hmac_vap,osal_u8 * payload,osal_u8 next_twt_subfd_size)1087 OSAL_STATIC osal_u64 hmac_get_next_twt(hmac_vap_stru *hmac_vap, osal_u8 *payload, osal_u8 next_twt_subfd_size)
1088 {
1089 osal_u32 next_twt_low;
1090 osal_u64 next_twt_high;
1091 osal_u64 next_twt;
1092
1093 switch (next_twt_subfd_size) {
1094 case HMAC_NEXT_TWT_SUBFIELD_SIZE_BITS_0:
1095 next_twt = 0;
1096 break;
1097
1098 case HMAC_NEXT_TWT_SUBFIELD_SIZE_BITS_32: /* 32 bits */
1099 next_twt_low = payload[0];
1100 next_twt_low |= (payload[1] << 8); /* 填充bit8~15 */
1101 next_twt_low |= (payload[2] << 16); /* payload[2]填充bit16~23 */
1102 next_twt_low |= (payload[3] << 24); /* payload[3]填充bit24~31 */
1103 next_twt = next_twt_low;
1104 break;
1105
1106 case HMAC_NEXT_TWT_SUBFIELD_SIZE_BITS_48: /* 48 bits */
1107 next_twt_low = payload[0];
1108 next_twt_low |= (payload[1] << 8); /* 填充bit8~15 */
1109 next_twt_low |= (payload[2] << 16); /* payload[2]填充bit16~23 */
1110 next_twt_low |= (payload[3] << 24); /* payload[3]填充bit24~31 */
1111
1112 next_twt_high = payload[4]; /* payload[4]填充bit0~7 */
1113 next_twt_high |= (payload[5] << 8); /* payload[5]填充bit8~15 */
1114
1115 next_twt = next_twt_low;
1116 next_twt |= (next_twt_high << 32); /* next_twt_high放入高32bit */
1117 break;
1118
1119 case HMAC_NEXT_TWT_SUBFIELD_SIZE_BITS_64: /* 64 bits */
1120 next_twt_low = payload[0];
1121 next_twt_low |= (payload[1] << 8); /* payload[1]填充bit8~15 */
1122 next_twt_low |= (payload[2] << 16); /* payload[2]填充bit16~23 */
1123 next_twt_low |= (payload[3] << 24); /* payload[3]填充bit24~31 */
1124
1125 next_twt_high = payload[4]; /* payload[4]填充bit0~7 */
1126 next_twt_high |= (payload[5] << 8); /* payload[5]填充bit8~15 */
1127 next_twt_high |= (payload[6] << 16); /* payload[6]填充bit16~23 */
1128 next_twt_high |= ((osal_u32)payload[7] << 24); /* payload[7]填充bit24~31 */
1129
1130 next_twt = next_twt_low;
1131 next_twt |= (next_twt_high << 32); /* next_twt_high放入高32bit */
1132 break;
1133
1134 default:
1135 next_twt = 0;
1136 oam_error_log2(0, OAM_SF_11AX,
1137 "vap_id[%d] {hmac_get_next_twt:: invalid next twt size [%d]!}", hmac_vap->vap_id,
1138 next_twt_subfd_size);
1139 break;
1140 }
1141
1142 return next_twt;
1143 }
1144
1145 /*****************************************************************************
1146 功能描述 : 从空口接收TWT information帧的处理函数
1147 *****************************************************************************/
hmac_sta_rx_twt_information_frame(hmac_vap_stru * hmac_vap,hmac_user_stru * hmac_user,osal_u8 * payload_len)1148 OSAL_STATIC osal_u32 hmac_sta_rx_twt_information_frame(hmac_vap_stru *hmac_vap,
1149 hmac_user_stru *hmac_user, osal_u8 *payload_len)
1150 {
1151 osal_u8 *payload = payload_len;
1152 /* 2表示information field前有2byte(category and action) */
1153 mac_twt_information_field_stru *information_field = (mac_twt_information_field_stru *)(payload + 2);
1154 osal_u32 ret;
1155 osal_u8 next_twt_subfd_size;
1156 osal_u64 next_twt;
1157 sta_twt_para_stru *twt_info = hmac_get_sta_twt_info(hmac_vap->vap_id);
1158
1159 /******************************************************************/
1160 /* TWT information Frame - Frame Body */
1161 /* --------------------------------------------------------------- */
1162 /* | Category | Action | TWT information_field | Next TWT */
1163 /* --------------------------------------------------------------- */
1164 /* | 1 | 1 | 1 | Variable */
1165 /* --------------------------------------------------------------- */
1166 /* */
1167 /******************************************************************/
1168
1169 /* 检查TWT是否在运行 */
1170 if (twt_info->sta_cfg_twt_para.twt_session_status == TWT_SESSION_OFF) {
1171 oam_warning_log1(0, OAM_SF_11AX, "vap_id[%d] {hmac_sta_rx_twt_information_frame::twt is disable!}",
1172 hmac_vap->vap_id);
1173 return OAL_FAIL;
1174 }
1175
1176 /* 检查flow id */
1177 if (twt_info->sta_cfg_twt_para.twt_basic_param.flow_id != information_field->flow_id) {
1178 oam_warning_log3(0, OAM_SF_11AX,
1179 "vap_id[%d] {hmac_sta_rx_twt_information_frame:: the flow id [%d] is invalid,our flow id is [%d]}",
1180 hmac_vap->vap_id, information_field->flow_id, twt_info->sta_cfg_twt_para.twt_basic_param.flow_id);
1181 return OAL_FAIL;
1182 }
1183
1184 next_twt_subfd_size = information_field->next_twt_subfield_size;
1185 payload += sizeof(mac_twt_information_field_stru) + 2; /* 2表示information field前有两个byte */
1186
1187 next_twt = hmac_get_next_twt(hmac_vap, payload, next_twt_subfd_size);
1188
1189 /* 这里只更新twt start time和next twt size */
1190 twt_info->sta_cfg_twt_para.twt_basic_param.twt = next_twt;
1191 twt_info->sta_cfg_twt_para.next_twt_size = next_twt_subfd_size;
1192 oam_warning_log3(0, OAM_SF_11AX,
1193 "vap_id[%d] {hmac_sta_rx_twt_information_frame:: next_twt=%ld,next_twt_size=[%d]}",
1194 hmac_vap->vap_id, next_twt, next_twt_subfd_size);
1195
1196 /* 事件分发至dmac */
1197 ret = hmac_sta_twt_update_event_etc(hmac_vap, hmac_user, MAC_TWT_UPDATE_SOURCE_INFORMATION);
1198 if (ret != OAL_SUCC) {
1199 oam_error_log1(0, OAM_SF_11AX,
1200 "{hmac_sta_rx_twt_information_frame::information update failed error=[%d]}", ret);
1201 }
1202 return ret;
1203 }
1204 #ifdef _PRE_WLAN_SUPPORT_CCPRIV_CMD
1205 /*****************************************************************************
1206 功能描述 : 建立TWT SETUP会话的配置命令
1207 *****************************************************************************/
hmac_config_twt_setup_req(hmac_vap_stru * hmac_vap,mac_cfg_twt_setup_req_param_stru * twt_setup_req)1208 OSAL_STATIC osal_s32 hmac_config_twt_setup_req(hmac_vap_stru *hmac_vap, mac_cfg_twt_setup_req_param_stru *twt_setup_req)
1209 {
1210 osal_u32 twt_wake_duration, ret;
1211 osal_u64 twt_interval;
1212 osal_u8 vap_num;
1213 /* 2:~{J}Wi1mJ>J1<d5%N;#,~}0~{Sk~}1~{7V1p1mJ>~}256~{Sk~}1024us */
1214 osal_u32 wake_unit[2] = {WAKE_DURATION_UNIT0, WAKE_DURATION_UNIT1};
1215
1216 hmac_device_stru *hmac_device = OSAL_NULL;
1217 hmac_user_stru *hmac_user = mac_vap_get_hmac_user_by_addr_etc(hmac_vap, twt_setup_req->mac_addr);
1218 mac_chip_stru *mac_chip = OSAL_NULL;
1219
1220 if (hmac_vap == OSAL_NULL) {
1221 return OAL_ERR_CODE_PTR_NULL;
1222 }
1223
1224 if (hmac_twt_get_req_bit(hmac_vap->vap_id) == OSAL_FALSE) {
1225 oam_error_log1(0, OAM_SF_11AX, "vap_id[%d] {hmac_config_twt_setup_req::not support}", hmac_vap->vap_id);
1226 return OAL_FAIL;
1227 }
1228
1229 hmac_device = hmac_res_get_mac_dev_etc(hmac_vap->device_id);
1230 if ((hmac_device == OSAL_NULL) || (hmac_user == OSAL_NULL)) {
1231 oam_error_log0(0, OAM_SF_11AX, "{hmac_config_twt_setup_req null param.}");
1232 return OAL_ERR_CODE_PTR_NULL;
1233 }
1234
1235 mac_chip = hmac_res_get_mac_chip(hmac_device->chip_id);
1236 if (mac_chip == OSAL_NULL) {
1237 oam_error_log1(0, OAM_SF_11AX, "vap_id[%d] {hmac_config_twt_setup_req::mac_chip is NULL}", hmac_vap->vap_id);
1238 return OAL_FAIL;
1239 }
1240
1241 /* 如果是已经启动多vap的情况下,不能建立TWT会话:
1242 非DBDC场景,如果启动了3个及以上的vap,说明是wlan0/p2p共存,此时不能建立TWT会话 */
1243 vap_num = (osal_u8)hmac_get_chip_vap_num(mac_chip);
1244 if (vap_num >= HMAC_TWT_P2P_RUNNING_VAP_NUM) {
1245 oam_error_log2(0, OAM_SF_11AX, "vap_id[%d] {hmac_config_twt_setup_req::vap_num[%d]}",
1246 hmac_vap->vap_id, vap_num);
1247 return OAL_FAIL;
1248 }
1249
1250 /* 对于STA而言MAC_TWT_COMMAND_DEMAND以内的command参数是合法的 */
1251 if (twt_setup_req->twt_basic_param.setup_command > MAC_TWT_COMMAND_DEMAND) {
1252 oam_error_log0(0, OAM_SF_11AX, "{hmac_config_twt_setup_req::err_command!}");
1253 return OAL_FAIL;
1254 }
1255
1256 /* 获取twt_interval与min_duration并校验 */
1257 twt_interval = ((osal_u64)twt_setup_req->twt_basic_param.intrval_mantissa) <<
1258 twt_setup_req->twt_basic_param.intrval_exponent;
1259 twt_wake_duration = ((osal_u32)twt_setup_req->twt_basic_param.min_duration) *
1260 wake_unit[twt_setup_req->twt_basic_param.wake_duration_unit];
1261
1262 /* 0xffffffff: twt interval不超过32bit */
1263 if ((twt_interval > 0xffffffff) || (twt_interval < (osal_u64)twt_wake_duration)) {
1264 oam_error_log2(0, OAM_SF_11AX, "{hmac_config_twt_setup_req:In=%d,du=%d}", twt_interval, twt_wake_duration);
1265 return OAL_ERR_CODE_INVALID_CONFIG;
1266 }
1267
1268 ret = hmac_mgmt_tx_twt_setup(hmac_vap, hmac_user, &(twt_setup_req->twt_basic_param));
1269 if (ret != OAL_SUCC) {
1270 oam_error_log2(0, OAM_SF_11AX, "vap_id[%d] {hmac_config_twt_setup_req::twt setup error=%d}",
1271 hmac_vap->vap_id, ret);
1272 }
1273 return (osal_s32)ret;
1274 }
1275
1276 /*****************************************************************************
1277 函 数 名 : hmac_config_twt_teardown_req_etc
1278 功能描述 : delete TWT SETUP会话的配置命令
1279 输入参数 : hmac_vap_stru *mac_vap, osal_u16 len, osal_u8 *param
1280 输出参数 : 无
1281 *****************************************************************************/
hmac_config_twt_teardown_req_etc(hmac_vap_stru * hmac_vap,mac_cfg_twt_teardown_req_param_stru * twt_teardown_req)1282 OSAL_STATIC osal_s32 hmac_config_twt_teardown_req_etc(hmac_vap_stru *hmac_vap,
1283 mac_cfg_twt_teardown_req_param_stru *twt_teardown_req)
1284 {
1285 hmac_user_stru *hmac_user = mac_vap_get_hmac_user_by_addr_etc(hmac_vap, twt_teardown_req->mac_addr);
1286 mac_cfg_twt_basic_param_stru twt_basic_param;
1287 osal_u32 ret;
1288 sta_twt_para_stru *twt_info = OSAL_NULL;
1289
1290 if (hmac_vap == OSAL_NULL || hmac_user == OSAL_NULL) {
1291 return OAL_ERR_CODE_PTR_NULL;
1292 }
1293
1294 twt_info = hmac_get_sta_twt_info(hmac_vap->vap_id);
1295 if (twt_info == OSAL_NULL) {
1296 oam_error_log1(0, OAM_SF_11AX,
1297 "vap_id[%d] {hmac_config_twt_teardown_req_etc::twt_info null.}", hmac_vap->vap_id);
1298 return OAL_ERR_CODE_PTR_NULL;
1299 }
1300
1301 if (twt_info->sta_cfg_twt_para.twt_session_status == TWT_SESSION_OFF) {
1302 oam_error_log4(0, OAM_SF_11AX,
1303 "{hmac_config_twt_teardown_req_etc::the twt session of the ap[%x:%x:%x:%x:xx:xx] hasn't seted up yet!.}",
1304 twt_teardown_req->mac_addr[0], twt_teardown_req->mac_addr[1], twt_teardown_req->mac_addr[2], /* 2 */
1305 twt_teardown_req->mac_addr[3]); /* 3 */
1306 return OAL_ERR_CODE_INVALID_CONFIG;
1307 }
1308
1309 if (twt_teardown_req->twt_flow_id != twt_info->sta_cfg_twt_para.twt_basic_param.flow_id) {
1310 oam_error_log3(0, OAM_SF_11AX,
1311 "vap_id[%d] {hmac_config_twt_teardown_req_etc::flow id diff:seted up id[%d],request teardown id[%d]!.}",
1312 hmac_vap->vap_id, twt_info->sta_cfg_twt_para.twt_basic_param.flow_id, twt_teardown_req->twt_flow_id);
1313 return OAL_ERR_CODE_INVALID_CONFIG;
1314 }
1315 twt_basic_param.flow_id = twt_teardown_req->twt_flow_id;
1316
1317 ret = hmac_mgmt_tx_twt_teardown(hmac_vap, hmac_user, (osal_u8)twt_basic_param.flow_id);
1318 if (ret != OAL_SUCC) {
1319 oam_error_log2(0, OAM_SF_11AX, "vap_id[%d] {hmac_config_twt_teardown_req_etc::twt teardown err=%d}",
1320 hmac_vap->vap_id, ret);
1321 }
1322 return (osal_s32)ret;
1323 }
1324
1325 /*****************************************************************************
1326 函 数 名 : hmac_config_twt_receive_setup_etc
1327 功能描述 : STA接收twt setup帧处理
1328 输入参数 : hmac_vap_stru *mac_vap, osal_u16 len, osal_u8 *param
1329 输出参数 : 无
1330 *****************************************************************************/
hmac_config_twt_receive_setup_etc(hmac_vap_stru * hmac_vap,mac_individual_twt_setup_frame_stru * setup_frame)1331 OSAL_STATIC osal_s32 hmac_config_twt_receive_setup_etc(hmac_vap_stru *hmac_vap,
1332 mac_individual_twt_setup_frame_stru *setup_frame)
1333 {
1334 hmac_user_stru *hmac_user = OSAL_NULL;
1335 osal_u8 mac_addr[] = {0x34, 0x46, 0xEC, 0x6B, 0x95, 0x20};
1336
1337 if (hmac_vap == OSAL_NULL || setup_frame == OSAL_NULL) {
1338 oam_error_log0(0, OAM_SF_11AX, "{hmac_config_twt_teardown_req_etc:: hmac_vap null.}");
1339 return OAL_ERR_CODE_PTR_NULL;
1340 }
1341
1342 oam_warning_log1(0, OAM_SF_11AX, "vap_id[%d] {hmac_config_twt_receive_setup_etc.}", hmac_vap->vap_id);
1343
1344 /* ~{;qH!SC;'6TS&5DKwR}~} */
1345 hmac_user = mac_vap_get_hmac_user_by_addr_etc(hmac_vap, mac_addr);
1346 if (hmac_user == OSAL_NULL) {
1347 oam_error_log1(0, OAM_SF_11AX, "vap_id[%d] {hmac_config_twt_teardown_req_etc::hmac_user null.}",
1348 hmac_vap->vap_id);
1349 return OAL_ERR_CODE_PTR_NULL;
1350 }
1351
1352 hmac_sta_rx_twt_setup_frame(hmac_vap, hmac_user, setup_frame);
1353
1354 return OAL_SUCC;
1355 }
1356
1357 /*****************************************************************************
1358 功能描述 : STA发送twt informaiuton帧处理
1359 *****************************************************************************/
hmac_config_twt_information_req(hmac_vap_stru * hmac_vap,mac_cfg_twt_information_req_param_stru * twt_information_req)1360 OSAL_STATIC osal_s32 hmac_config_twt_information_req(hmac_vap_stru *hmac_vap,
1361 mac_cfg_twt_information_req_param_stru *twt_information_req)
1362 {
1363 hmac_user_stru *hmac_user = mac_vap_get_hmac_user_by_addr_etc(hmac_vap, twt_information_req->mac_addr);
1364 sta_twt_para_stru *twt_info = OSAL_NULL;
1365 osal_u32 ret;
1366
1367 if (hmac_vap == OSAL_NULL || hmac_user == OSAL_NULL) {
1368 return OAL_ERR_CODE_PTR_NULL;
1369 }
1370
1371 twt_info = hmac_get_sta_twt_info(hmac_vap->vap_id);
1372 if (twt_info == OSAL_NULL) {
1373 return OAL_ERR_CODE_PTR_NULL;
1374 }
1375
1376 /* TWT会话不存在 */
1377 if (twt_info->sta_cfg_twt_para.twt_session_status == TWT_SESSION_OFF) {
1378 oam_error_log1(0, OAM_SF_11AX, "vap_id[%d] {hmac_config_twt_information_req::twt session not exit}",
1379 hmac_vap->vap_id);
1380 return OAL_ERR_CODE_INVALID_CONFIG;
1381 }
1382 /* TWT-information使能 */
1383 if (twt_info->sta_cfg_twt_para.twt_basic_param.information_disable == OSAL_TRUE) {
1384 oam_error_log1(0, OAM_SF_11AX, "vap_id[%d] {hmac_config_twt_information_req::twt information disable}",
1385 hmac_vap->vap_id);
1386 return OAL_ERR_CODE_INVALID_CONFIG;
1387 }
1388 /* TWT-flow-id一致 */
1389 if (twt_information_req->twt_information_filed.flow_id != twt_info->sta_cfg_twt_para.twt_basic_param.flow_id) {
1390 oam_error_log3(0, OAM_SF_11AX,
1391 "vap_id[%d] {hmac_config_twt_information_req::twt flow id isn't same:seted up id[%d],request id[%d]!.}",
1392 hmac_vap->vap_id,
1393 twt_info->sta_cfg_twt_para.twt_basic_param.flow_id, twt_information_req->twt_information_filed.flow_id);
1394 return OAL_ERR_CODE_INVALID_CONFIG;
1395 }
1396
1397 ret = hmac_mgmt_tx_twt_information(hmac_vap, hmac_user, &(twt_information_req->twt_information_filed));
1398 if (ret != OAL_SUCC) {
1399 oam_error_log2(0, OAM_SF_11AX, "vap_id[%d] {hmac_config_twt_information_req::twt setup error=%d}",
1400 hmac_vap->vap_id, ret);
1401 }
1402 return (osal_s32)ret;
1403 }
1404
1405 /*****************************************************************************
1406 函 数 名 : uapi_ccpriv_twt_setup_req
1407 功能描述 : 建立TWT SETUP会话的调测命令
1408 输入参数 : oal_net_device_stru *net_dev, osal_s8 *param
1409 输出参数 : 无
1410 *****************************************************************************/
hmac_ccpriv_twt_setup_req(hmac_vap_stru * hmac_vap,const osal_s8 * param)1411 OSAL_STATIC osal_s32 hmac_ccpriv_twt_setup_req(hmac_vap_stru *hmac_vap, const osal_s8 *param)
1412 {
1413 osal_char arg[WAL_CCPRIV_CMD_NAME_MAX_LEN] = {0};
1414 osal_u32 index, value;
1415 osal_s32 ret;
1416 osal_u64 value_set[9]; /* 9:用来暂存从命令中读取的twt参数,共有9个 */
1417 /* 本命令总计10个参数,新增wake duration unit */
1418 osal_u32 compare[10] = {0, 0x7, 0x1, 0x7, 0x1, 0, 0x1f, 0xff, 0xffff, 0x1};
1419 mac_cfg_twt_setup_req_param_stru twt_setup_req_param;
1420
1421 (osal_void)memset_s(&twt_setup_req_param, OAL_SIZEOF(mac_cfg_twt_setup_req_param_stru), 0,
1422 OAL_SIZEOF(mac_cfg_twt_setup_req_param_stru));
1423
1424 /*
1425 * 设置AMPDU关闭的配置命令
1426 * ccpriv "wlan0 twt_setup_req xx xx xx xx xx xx(mac地址)
1427 * setup_cmd flow_type flow_ID trigger twt interval_exponent min_duration interval_mantissa duration_unit"
1428 */
1429 for (index = 0; index < 10; index++) { /* 本命令总计10个参数 */
1430 ret = hmac_ccpriv_get_one_arg(¶m, (osal_s8 *)arg, OAL_SIZEOF(arg));
1431 if (ret != OAL_SUCC) {
1432 oam_warning_log1(0, OAM_SF_ANY, "{hmac_ccpriv_twt_setup_req::parse arg failed [%d]!}", ret);
1433 return ret;
1434 }
1435
1436 if (index == 0) { /* 0: mac addr */
1437 oal_strtoaddr((const osal_char *)arg, twt_setup_req_param.mac_addr);
1438 continue;
1439 }
1440
1441 value = (osal_u32)oal_atoi((const osal_s8 *)arg);
1442 if ((index != 5) && (value > compare[index])) { /* 5指twt,其最大支持64bit, 不做参数校验 */
1443 oam_error_log2(0, OAM_SF_11AX, "{hmac_ccpriv_twt_setup_req::index[%d] is not correct[%d]!", index, value);
1444 return OAL_ERR_CODE_INVALID_CONFIG;
1445 }
1446
1447 value_set[index - 1] = value; /* index >= 1使用数组暂存参数,循环结束后一并读取 */
1448 }
1449 twt_setup_req_param.twt_basic_param.setup_command = (osal_u16)value_set[0]; /* 0:value_set[0]含setup-command */
1450 twt_setup_req_param.twt_basic_param.flow_type = (osal_u16)value_set[1]; /* 1:value_set[1]含flow type */
1451 twt_setup_req_param.twt_basic_param.flow_id = (osal_u16)value_set[2]; /* 2:value_set[2]含flow id */
1452 twt_setup_req_param.twt_basic_param.trigger = (osal_u16)value_set[3]; /* 3:value_set[3]含trigger */
1453 twt_setup_req_param.twt_basic_param.twt = value_set[4]; /* 4:value_set[4]含twt */
1454 twt_setup_req_param.twt_basic_param.intrval_exponent = (osal_u16)value_set[5]; /* 5:value_set[5]含exponent */
1455 twt_setup_req_param.twt_basic_param.min_duration = (osal_u8)value_set[6]; /* 6:value_set[6]含min duration */
1456 twt_setup_req_param.twt_basic_param.intrval_mantissa = (osal_u16)value_set[7]; /* 7:value_set[7]含mantissa */
1457 twt_setup_req_param.twt_basic_param.wake_duration_unit = (osal_u16)value_set[8]; /* 8:value_set[8]含duration unit */
1458
1459 ret = hmac_config_twt_setup_req(hmac_vap, &twt_setup_req_param);
1460 if (ret != OAL_SUCC) {
1461 oam_warning_log1(0, OAM_SF_ANY, "{hmac_ccpriv_twt_setup_req::config failed [%d]!}", ret);
1462 }
1463
1464 return ret;
1465 }
1466
1467 /*****************************************************************************
1468 函 数 名 : uapi_ccpriv_twt_teardown_req
1469 功能描述 : 建立TWT TEARDOWN会话的调测命令
1470 输入参数 : oal_net_device_stru *net_dev, osal_s8 *param
1471 输出参数 : 无
1472 *****************************************************************************/
hmac_ccpriv_twt_teardown_req(hmac_vap_stru * hmac_vap,const osal_s8 * param)1473 OSAL_STATIC osal_s32 hmac_ccpriv_twt_teardown_req(hmac_vap_stru *hmac_vap, const osal_s8 *param)
1474 {
1475 osal_char arg[WAL_CCPRIV_CMD_NAME_MAX_LEN] = {0};
1476 osal_s32 ret;
1477 mac_cfg_twt_teardown_req_param_stru teardown_req_param;
1478
1479 (osal_void)memset_s(&teardown_req_param, OAL_SIZEOF(mac_cfg_twt_teardown_req_param_stru), 0,
1480 OAL_SIZEOF(mac_cfg_twt_teardown_req_param_stru));
1481
1482 /*
1483 * 设置AMPDU关闭的配置命令:
1484 * ccpriv "wlan0 twt_teardown_req xx xx xx xx xx xx(mac地址) flow_id"
1485 */
1486 oam_warning_log0(0, OAM_SF_11AX, "{hmac_ccpriv_twt_teardown_req!}");
1487
1488 /* 获取mac地址 */
1489 ret = hmac_ccpriv_get_one_arg(¶m, (osal_s8 *)arg, OAL_SIZEOF(arg));
1490 if (ret != OAL_SUCC) {
1491 oam_warning_log1(0, OAM_SF_11AX, "{hmac_ccpriv_twt_teardown_req::wal_get_cmd_one_arg err=%d!}", ret);
1492 return (osal_s32)ret;
1493 }
1494 oal_strtoaddr(arg, teardown_req_param.mac_addr);
1495
1496 /* 获取twt_flow_id */
1497 ret = hmac_ccpriv_get_u8_with_check_max(¶m, 0x07, &teardown_req_param.twt_flow_id);
1498 if (ret != OAL_SUCC) {
1499 oam_warning_log1(0, OAM_SF_11AX,
1500 "{hmac_ccpriv_twt_teardown_req::wal_cmd_get_u8_with_check_max return err=%d!}", ret);
1501 return (osal_s32)ret;
1502 }
1503
1504 /* 抛事件到wal层处理 */
1505 ret = hmac_config_twt_teardown_req_etc(hmac_vap, &teardown_req_param);
1506 if (ret != OAL_SUCC) {
1507 oam_warning_log1(0, OAM_SF_11AX, "{hmac_ccpriv_twt_teardown_req::return err code[%d]!}", ret);
1508 }
1509
1510 return ret;
1511 }
1512
1513 /*****************************************************************************
1514 函 数 名 : uapi_ccpriv_twt_receive_setup
1515 功能描述 : STA接收TWT Setup帧的调测命令
1516 输入参数 : oal_net_device_stru *net_dev, osal_s8 *param
1517 输出参数 : 无
1518 *****************************************************************************/
hmac_ccpriv_twt_receive_setup(hmac_vap_stru * hmac_vap,const osal_s8 * param)1519 OSAL_STATIC osal_s32 hmac_ccpriv_twt_receive_setup(hmac_vap_stru *hmac_vap, const osal_s8 *param)
1520 {
1521 osal_u32 index;
1522 osal_s32 ret;
1523 osal_s8 arg[WAL_CCPRIV_CMD_NAME_MAX_LEN] = {0};
1524 osal_u64 value_set[TWT_RX_PARA_NUM]; /* 11:用来暂存从命令中读取的twt参数,共有11个 */
1525 /* 本命令总计11个参数 */
1526 osal_u32 compare[TWT_RX_PARA_NUM] = {0xff, 0xff, 0x7, 0x1, 0x7, 0x1, 0, 0x1f, 0xff, 0xffff, 0x1};
1527 mac_individual_twt_setup_frame_stru setup_frame;
1528
1529 (osal_void)memset_s(&setup_frame, OAL_SIZEOF(mac_individual_twt_setup_frame_stru), 0,
1530 OAL_SIZEOF(mac_individual_twt_setup_frame_stru));
1531
1532 /*
1533 * 设置收到TWT Setup帧的配置命令:
1534 * 1.dialog_token 2.EID 3.setup_cmd 4.flow_type 5.flow_ID 6.trigger 7.twt 8.interval_exponent
1535 * 9.min_duration 10.interval_mantissa 11.duration_unit"
1536 */
1537 oam_warning_log0(0, OAM_SF_11AX, "{hmac_ccpriv_twt_receive_setup!}");
1538 /* 11: 本命令总计11个参数 */
1539 for (index = 0; index < TWT_RX_PARA_NUM; index++) {
1540 ret = hmac_ccpriv_get_one_arg(¶m, arg, OAL_SIZEOF(arg));
1541 if (ret != OAL_SUCC) {
1542 oam_warning_log1(0, OAM_SF_11AX, "{hmac_ccpriv_twt_teardown_req::wal_get_cmd_one_arg err=%d!}", ret);
1543 return ret;
1544 }
1545
1546 value_set[index] = (osal_u64)oal_atoi((const osal_s8 *)arg);
1547 /* 6:6号参数twt不检验 */
1548 if ((index != 6) && (value_set[index] > compare[index])) {
1549 oam_error_log2(0, OAM_SF_11AX, "{hmac_ccpriv_twt_receive_setup::indx[%d] err[%d]!",
1550 index, value_set[index]);
1551 return OAL_ERR_CODE_INVALID_CONFIG;
1552 }
1553 }
1554 setup_frame.dialog_token = 0; /* 0:dialogtoken赋值 */
1555 setup_frame.twt_element.element_id = MAC_EID_TWT;
1556 setup_frame.twt_element.request_type.setup_command = (osal_u16)value_set[2]; /* 2:setupcmd */
1557 setup_frame.twt_element.request_type.flow_type = (osal_u16)value_set[3]; /* 3:flow type */
1558 setup_frame.twt_element.request_type.flow_id = (osal_u16)value_set[4]; /* 4:flow id */
1559 setup_frame.twt_element.request_type.trigger = (osal_u16)value_set[5]; /* 5:trigger初始化1 */
1560 setup_frame.twt_element.twt = value_set[6]; /* 6:初始化twt为100000 */
1561 setup_frame.twt_element.request_type.intrval_exponent = (osal_u16)value_set[7]; /* 7:初始化intrval_exponent为5 */
1562 setup_frame.twt_element.min_duration = (osal_u8)value_set[8]; /* 8:初始化min_duration为10 */
1563 setup_frame.twt_element.intrval_mantissa = (osal_u16)value_set[9]; /* 9:初始化intrval_mantissa为100 */
1564 setup_frame.twt_element.control.wake_duration_unit = (osal_u8)value_set[10]; /* 10:初始化unit为0,256us */
1565
1566 /* 抛事件到wal层处理 */
1567 ret = hmac_config_twt_receive_setup_etc(hmac_vap, &setup_frame);
1568 if (ret != OAL_SUCC) {
1569 oam_warning_log1(0, OAM_SF_11AX, "{hmac_ccpriv_twt_receive_setup::return err code[%d]!}", ret);
1570 }
1571
1572 return ret;
1573 }
1574
1575 /*****************************************************************************
1576 功能描述 : 发送TWT information调测,共输入mac地址,flow-id,pause三个参数
1577 *****************************************************************************/
hmac_ccpriv_twt_information_req(hmac_vap_stru * hmac_vap,const osal_s8 * param)1578 OSAL_STATIC osal_s32 hmac_ccpriv_twt_information_req(hmac_vap_stru *hmac_vap, const osal_s8 *param)
1579 {
1580 osal_char arg[WAL_CCPRIV_CMD_NAME_MAX_LEN] = {0};
1581 osal_s32 ret;
1582 osal_s32 index;
1583 osal_u64 value_set[2]; /* 6:用来暂存从命令中读取的twt参数,flow id, pause */
1584 osal_u32 compare[2] = {0x7, 0x1}; /* 本命令总计2个参数 */
1585 mac_cfg_twt_information_req_param_stru information_req;
1586
1587 (osal_void)memset_s(&information_req, OAL_SIZEOF(mac_cfg_twt_information_req_param_stru), 0,
1588 OAL_SIZEOF(mac_cfg_twt_information_req_param_stru));
1589
1590 /*
1591 * echo "wlan0 twt_information_req xx xx xx xx xx xx(mac地址)
1592 * 0:flow_ID 1:pause(TRUE for pause, FAlSE for resume)"
1593 */
1594 oam_warning_log0(0, OAM_SF_11AX, "{hmac_ccpriv_twt_information_req!}");
1595 /* 获取mac地址 */
1596 ret = hmac_ccpriv_get_one_arg(¶m, (osal_s8 *)arg, OAL_SIZEOF(arg));
1597 if (ret != OAL_SUCC) {
1598 oam_warning_log1(0, OAM_SF_11AX, "{hmac_ccpriv_twt_teardown_req::wal_get_cmd_one_arg err=%d!}", ret);
1599 return ret;
1600 }
1601 oal_strtoaddr(arg, information_req.mac_addr);
1602
1603 /* 2表示一共有两个参数 */
1604 for (index = 0; index < 2; index++) {
1605 if (hmac_ccpriv_get_one_arg(¶m, (osal_s8 *)arg, OAL_SIZEOF(arg)) != OAL_SUCC) {
1606 oam_error_log1(0, OAM_SF_11AX, "{hmac_ccpriv_twt_information_req::get param err, index=[%d].}", index);
1607 return OAL_ERR_CODE_INVALID_CONFIG;
1608 }
1609
1610 value_set[index] = (osal_u64)oal_atoi((const osal_s8 *)arg) & compare[index];
1611 }
1612
1613 information_req.twt_information_filed.flow_id = (osal_u8)value_set[0]; /* 第一个参数flow-id */
1614 /* 0x3表示next-twt都按64位发送 */
1615 information_req.twt_information_filed.next_twt_subfield_size = (value_set[1] == OSAL_TRUE) ? 0 : 0x3;
1616
1617 /* 抛事件到wal层处理 */
1618 ret = hmac_config_twt_information_req(hmac_vap, &information_req);
1619 if (ret != OAL_SUCC) {
1620 oam_error_log1(0, OAM_SF_11AX, "{hmac_ccpriv_twt_information_req::return err code[%d]!}", ret);
1621 }
1622
1623 return ret;
1624 }
1625 #endif
1626 /*****************************************************************************
1627 功能描述 : 去关联时清除TWT寄存器,清除标志位
1628 *****************************************************************************/
hmac_twt_deinit(osal_void * notify_data)1629 OSAL_STATIC osal_bool hmac_twt_deinit(osal_void *notify_data)
1630 {
1631 hmac_user_stru *hmac_user = (hmac_user_stru *)notify_data;
1632 hmac_vap_stru *hmac_vap;
1633 sta_twt_para_stru *sta_twt_info = OSAL_NULL;
1634
1635 if (hmac_user == OSAL_NULL) {
1636 return OSAL_FALSE;
1637 }
1638
1639 hmac_vap = mac_res_get_hmac_vap(hmac_user->vap_id);
1640 if (hmac_vap == OSAL_NULL) {
1641 return OSAL_FALSE;
1642 }
1643
1644 if (is_legacy_sta(hmac_vap) != OSAL_TRUE) {
1645 return OSAL_TRUE;
1646 }
1647
1648 if (hmac_device_twt_custom_is_open(hmac_vap->vap_id) != OSAL_TRUE) {
1649 return OSAL_TRUE;
1650 }
1651
1652 sta_twt_info = hmac_get_sta_twt_info(hmac_vap->vap_id);
1653 if (sta_twt_info->sta_cfg_twt_para.twt_session_status != TWT_SESSION_OFF) {
1654 (osal_void)memset_s(&(sta_twt_info->sta_cfg_twt_para), sizeof(mac_cfg_twt_stru), 0, sizeof(mac_cfg_twt_stru));
1655 }
1656 return OSAL_TRUE;
1657 }
1658
1659 /*****************************************************************************
1660 函 数 名 : hmac_twt_is_session_enable
1661 功能描述 : twt会话是否开启
1662 *****************************************************************************/
hmac_twt_is_session_enable(const hmac_vap_stru * hmac_vap)1663 WIFI_TCM_TEXT OSAL_STATIC osal_u8 hmac_twt_is_session_enable(const hmac_vap_stru *hmac_vap)
1664 {
1665 if (hmac_vap == OSAL_NULL) {
1666 return OSAL_FALSE;
1667 }
1668
1669 if (hmac_device_twt_custom_is_open(hmac_vap->vap_id) != OSAL_TRUE) {
1670 return OSAL_FALSE;
1671 }
1672
1673 return ((hmac_get_sta_twt_info(hmac_vap->vap_id))->sta_cfg_twt_para.twt_session_status == TWT_SESSION_ON) ?
1674 OSAL_TRUE : OSAL_FALSE;
1675 }
1676
hmac_is_twt_processed_not_need_buff(const hmac_vap_stru * hmac_vap)1677 WIFI_TCM_TEXT OSAL_STATIC osal_bool hmac_is_twt_processed_not_need_buff(const hmac_vap_stru *hmac_vap)
1678 {
1679 if (hmac_vap == OSAL_NULL) {
1680 return OSAL_FALSE;
1681 }
1682
1683 if (!is_legacy_sta(hmac_vap)) {
1684 return OSAL_FALSE;
1685 }
1686
1687 if (hmac_get_sta_twt_info(hmac_vap->vap_id) == OSAL_NULL) {
1688 return OSAL_TRUE;
1689 }
1690
1691 if ((hmac_twt_is_session_enable(hmac_vap) == OSAL_TRUE) && (hmac_twt_is_ps_pause(hmac_vap) == OSAL_FALSE)) {
1692 return OSAL_TRUE;
1693 }
1694
1695 return OSAL_FALSE;
1696 }
1697
hmac_is_twt_need_buff(hmac_vap_stru * hmac_vap)1698 WIFI_TCM_TEXT OSAL_STATIC osal_bool hmac_is_twt_need_buff(hmac_vap_stru *hmac_vap)
1699 {
1700 if (hmac_vap == OSAL_NULL) {
1701 return OSAL_FALSE;
1702 }
1703
1704 if (hmac_get_sta_twt_info(hmac_vap->vap_id) == OSAL_NULL) {
1705 return OSAL_FALSE;
1706 }
1707
1708 if ((hmac_twt_is_session_enable(hmac_vap) == OSAL_TRUE) && (hmac_twt_is_ps_pause(hmac_vap) == OSAL_TRUE)) {
1709 return OSAL_TRUE;
1710 }
1711
1712 return OSAL_FALSE;
1713 }
1714
hmac_twt_tx_action(hmac_vap_stru * hmac_vap,const hmac_user_stru * hmac_user,const hmac_ctx_action_event_stru * ctx_action_event,oal_netbuf_stru * netbuf,mac_tx_ctl_stru * tx_ctl)1715 OSAL_STATIC osal_u32 hmac_twt_tx_action(hmac_vap_stru *hmac_vap, const hmac_user_stru *hmac_user,
1716 const hmac_ctx_action_event_stru *ctx_action_event, oal_netbuf_stru *netbuf, mac_tx_ctl_stru *tx_ctl)
1717 {
1718 if (hmac_vap == OSAL_NULL || hmac_user == OSAL_NULL || ctx_action_event == OSAL_NULL ||
1719 netbuf == OSAL_NULL || tx_ctl == OSAL_NULL) {
1720 return OAL_ERR_CODE_PTR_NULL;
1721 }
1722
1723 if (tx_ctl->frame_subtype == WLAN_ACTION_TWT_SETUP_REQ) {
1724 return hmac_mgmt_tx_twt_setup_req(hmac_vap, hmac_user, ctx_action_event, netbuf);
1725 } else if (tx_ctl->frame_subtype == WLAN_ACTION_TWT_TEARDOWN_REQ) {
1726 return hmac_mgmt_tx_twt_information_req(hmac_vap, hmac_user, ctx_action_event, netbuf);
1727 } else if (tx_ctl->frame_subtype == WLAN_ACTION_TWT_INFORMATION_REQ) {
1728 return hmac_mgmt_tx_twt_teardown_req(hmac_vap, hmac_user, ctx_action_event, netbuf);
1729 }
1730
1731 return OAL_SUCC;
1732 }
1733
1734 /*****************************************************************************
1735 功能描述 : P2P与TWT共存场景下,自动终止twt会话
1736 *****************************************************************************/
hmac_p2p_teardown_twt_session(hmac_device_stru * hmac_device)1737 OSAL_STATIC osal_u32 hmac_p2p_teardown_twt_session(hmac_device_stru *hmac_device)
1738 {
1739 mac_chip_stru *mac_chip = OSAL_NULL;
1740 hmac_vap_stru *hmac_vap = OSAL_NULL;
1741 hmac_user_stru *hmac_user = OSAL_NULL;
1742 osal_u32 ret = OAL_SUCC;
1743 osal_u8 vap_num;
1744 sta_twt_para_stru *twt_info = OSAL_NULL;
1745
1746 mac_chip = hmac_res_get_mac_chip(hmac_device->chip_id);
1747 if (mac_chip == OSAL_NULL) {
1748 oam_error_log1(0, OAM_SF_ANY, "hmac_p2p_teardown_twt_session::mac_chip id[%d] NULL", hmac_device->chip_id);
1749 return ret;
1750 }
1751
1752 vap_num = (osal_u8)hmac_get_chip_vap_num(mac_chip);
1753 /* 非DBDC场景,如果启动了3个及以上的vap,说明是wlan0/p2p共存,此时如果已经建立twt会则需要删除 */
1754 if (vap_num >= 2) {
1755 /* 先找到wlan vap */
1756 mac_device_find_up_sta_wlan_etc(hmac_device, &hmac_vap);
1757 if (hmac_vap == OSAL_NULL) {
1758 oam_warning_log0(0, OAM_SF_CFG, "{hmac_p2p_teardown_twt_session::hmac_vap null.}");
1759 return ret;
1760 }
1761
1762 if (hmac_vap->vap_mode != WLAN_VAP_MODE_BSS_STA) {
1763 return OAL_SUCC;
1764 }
1765
1766 /* 获取用户对应的索引 */
1767 hmac_user = mac_res_get_hmac_user_etc(hmac_vap->assoc_vap_id);
1768 if (hmac_user == OSAL_NULL) {
1769 /* 已经删除了的话,属于正常 */
1770 oam_warning_log2(0, OAM_SF_ASSOC,
1771 "vap_id[%d] {hmac_p2p_teardown_twt_session::hmac_user[%d] null.}", hmac_vap->vap_id,
1772 hmac_vap->assoc_vap_id);
1773 return ret;
1774 }
1775
1776 twt_info = hmac_get_sta_twt_info(hmac_vap->vap_id);
1777 if (twt_info == OSAL_NULL) {
1778 return OAL_ERR_CODE_PTR_NULL;
1779 }
1780
1781 /* 如果该vap的twt会话已经开启,则删除twt会话 */
1782 if (twt_info->sta_cfg_twt_para.twt_session_status != TWT_SESSION_OFF) {
1783 ret = hmac_mgmt_tx_twt_teardown(hmac_vap, hmac_user, twt_info->sta_cfg_twt_para.twt_basic_param.flow_id);
1784 }
1785 }
1786 return ret;
1787 }
1788
hmac_process_update_twt(hmac_vap_stru * hmac_vap,hmac_user_stru * hmac_user,osal_u8 * payload,osal_u16 msg_len)1789 OSAL_STATIC osal_void hmac_process_update_twt(hmac_vap_stru *hmac_vap, hmac_user_stru *hmac_user, osal_u8 *payload,
1790 osal_u16 msg_len)
1791 {
1792 osal_u8 *tmp_ie = OAL_PTR_NULL;
1793
1794 if (hmac_vap == OSAL_NULL) {
1795 return;
1796 }
1797
1798 /* 寻找是否有TWT信息元素, tmp_ie指向信息元素 */
1799 tmp_ie = mac_find_ie_etc(MAC_EID_TWT, payload, msg_len);
1800 if (tmp_ie != OSAL_NULL) {
1801 /* 判断TWT能力位是否满足 */
1802 if (hmac_twt_get_req_bit(hmac_vap->vap_id) == OSAL_TRUE) {
1803 hmac_sta_rx_twt_association_frame_etc(hmac_vap, hmac_user, tmp_ie);
1804 }
1805 }
1806 }
1807
hmac_sta_up_rx_action_s1g(oal_netbuf_stru ** netbuf,hmac_vap_stru * hmac_vap)1808 OSAL_STATIC osal_u32 hmac_sta_up_rx_action_s1g(oal_netbuf_stru **netbuf, hmac_vap_stru *hmac_vap)
1809 {
1810 dmac_rx_ctl_stru *rx_ctl = (dmac_rx_ctl_stru *)oal_netbuf_cb(*netbuf); /* 获取帧头信息 */
1811 mac_ieee80211_frame_stru *frame_hdr = (mac_ieee80211_frame_stru *)mac_get_rx_cb_mac_hdr(&(rx_ctl->rx_info));
1812 osal_u8 *data = OSAL_NULL;
1813 hmac_user_stru *hmac_user;
1814 sta_twt_para_stru *twt_info;
1815
1816 if (hmac_vap == OSAL_NULL) {
1817 return OAL_CONTINUE;
1818 }
1819
1820 if (!is_legacy_sta(hmac_vap)) {
1821 return OAL_CONTINUE;
1822 }
1823
1824 if (frame_hdr->frame_control.type != WLAN_MANAGEMENT || frame_hdr->frame_control.sub_type != WLAN_ACTION) {
1825 return OAL_CONTINUE;
1826 }
1827
1828 data = oal_netbuf_rx_data(*netbuf);
1829 if ((data[MAC_ACTION_OFFSET_CATEGORY] != MAC_ACTION_CATEGORY_S1G) ||
1830 ((data[MAC_ACTION_OFFSET_ACTION] != MAC_S1G_ACTION_TWT_SETUP) &&
1831 (data[MAC_ACTION_OFFSET_ACTION] != MAC_S1G_ACTION_TWT_TEARDOWN) &&
1832 (data[MAC_ACTION_OFFSET_ACTION] != MAC_S1G_ACTION_TWT_INFORMATION))) {
1833 return OAL_CONTINUE;
1834 }
1835
1836 /* 获取发送端的用户指针 */
1837 hmac_user = mac_vap_get_hmac_user_by_addr_etc(hmac_vap, frame_hdr->address2);
1838 if (hmac_user == OAL_PTR_NULL) {
1839 oam_warning_log1(0, OAM_SF_RX, "vap_id[%d] {hmac_sta_up_rx_action_s1g::find_user_by_macaddr_etc failed.}",
1840 hmac_vap->vap_id);
1841 return OAL_CONTINUE;
1842 }
1843
1844 twt_info = hmac_get_sta_twt_info(hmac_vap->vap_id);
1845 if (twt_info == OSAL_NULL) {
1846 return OAL_FAIL;
1847 }
1848
1849 switch (data[MAC_ACTION_OFFSET_ACTION]) {
1850 case MAC_S1G_ACTION_TWT_SETUP:
1851 hmac_sta_rx_twt_setup_frame(hmac_vap, hmac_user, (mac_individual_twt_setup_frame_stru *)data);
1852 break;
1853
1854 case MAC_S1G_ACTION_TWT_TEARDOWN:
1855 hmac_sta_rx_twt_teardown_frame(hmac_vap, hmac_user, data);
1856 break;
1857
1858 case MAC_S1G_ACTION_TWT_INFORMATION:
1859 hmac_sta_rx_twt_information_frame(hmac_vap, hmac_user, data);
1860 break;
1861 default:
1862 break;
1863 }
1864
1865 return OAL_SUCC;
1866 }
1867
hmac_config_twt_status_sync(hmac_vap_stru * hmac_vap,frw_msg * msg)1868 OSAL_STATIC osal_s32 hmac_config_twt_status_sync(hmac_vap_stru *hmac_vap, frw_msg *msg)
1869 {
1870 mac_d2hd_twt_sync_info_stru *cfg = OSAL_NULL;
1871
1872 if (hmac_vap == OSAL_NULL || msg == OSAL_NULL) {
1873 oam_warning_log0(0, OAM_SF_ANY, "{hmac_config_twt_status_sync:: param is null!}");
1874 return OAL_ERR_CODE_PTR_NULL;
1875 }
1876
1877 if (hmac_get_sta_twt_info(hmac_vap->vap_id) == OSAL_NULL) {
1878 return OAL_ERR_CODE_PTR_NULL;
1879 }
1880
1881 cfg = (mac_d2hd_twt_sync_info_stru *)msg->data;
1882 return hmac_twt_update_d2h_sync(hmac_vap, cfg);
1883 }
1884
hmac_set_ext_cap_twt_req(hmac_vap_stru * hmac_vap,mac_ext_cap_ie_stru * ext_cap_ie,osal_u8 * ie_len)1885 OSAL_STATIC osal_void hmac_set_ext_cap_twt_req(hmac_vap_stru *hmac_vap, mac_ext_cap_ie_stru *ext_cap_ie,
1886 osal_u8 *ie_len)
1887 {
1888 if (mac_mib_get_he_twt_option_activated(hmac_vap) == OSAL_FALSE) {
1889 return;
1890 }
1891
1892 ext_cap_ie->twt_requester_support = 1;
1893 (*ie_len) = MAC_XCAPS_EX_TWT_LEN;
1894 }
1895
hmac_twt_sta_vap_add(osal_void * notify_data)1896 OSAL_STATIC osal_bool hmac_twt_sta_vap_add(osal_void *notify_data)
1897 {
1898 hmac_vap_stru *hmac_vap = (hmac_vap_stru *)notify_data;
1899 osal_void *mem_ptr = OSAL_NULL;
1900 osal_u8 vap_id;
1901
1902 if (hmac_vap == OSAL_NULL) {
1903 return OSAL_FALSE;
1904 }
1905 vap_id = hmac_vap->vap_id;
1906 if (hmac_vap_id_param_check(vap_id) != OSAL_TRUE) {
1907 return OSAL_TRUE;
1908 }
1909
1910 if (!is_legacy_sta(hmac_vap)) {
1911 return OSAL_TRUE;
1912 }
1913
1914 if (g_sta_twt_info[vap_id] != OSAL_NULL) {
1915 oam_warning_log1(0, OAM_SF_PWR, "vap_id[%d] hmac_twt_sta_vap_add mem already malloc!", vap_id);
1916 return OSAL_TRUE;
1917 }
1918
1919 mem_ptr = oal_mem_alloc(OAL_MEM_POOL_ID_LOCAL, sizeof(sta_twt_para_stru), OAL_TRUE);
1920 if (mem_ptr == OSAL_NULL) {
1921 oam_error_log1(0, OAM_SF_PWR, "vap_id[%d] hmac_twt_sta_vap_add malloc null!", vap_id);
1922 return OSAL_FALSE;
1923 }
1924
1925 (osal_void)memset_s(mem_ptr, sizeof(sta_twt_para_stru), 0, sizeof(sta_twt_para_stru));
1926 g_sta_twt_info[vap_id] = (sta_twt_para_stru *)mem_ptr;
1927
1928 hmac_twt_set_resp_bit(vap_id, OSAL_TRUE);
1929 hmac_twt_set_req_bit(vap_id, OSAL_TRUE);
1930 mac_mib_set_he_twt_option_activated(hmac_vap, OSAL_TRUE);
1931
1932 return OSAL_TRUE;
1933 }
1934
1935 /*****************************************************************************
1936 函 数 名 : hmac_roam_exit_etc
1937 功能描述 : roam模块控制信息卸载
1938 输入参数 : hmac_vap 需要卸载roam模块的vap
1939 返 回 值 : OAL_SUCC 或 失败错误码
1940 *****************************************************************************/
hmac_twt_sta_vap_del(osal_void * notify_data)1941 OSAL_STATIC osal_bool hmac_twt_sta_vap_del(osal_void *notify_data)
1942 {
1943 hmac_vap_stru *hmac_vap = (hmac_vap_stru *)notify_data;
1944 osal_u8 vap_id;
1945
1946 if (hmac_vap == OSAL_NULL) {
1947 return OSAL_FALSE;
1948 }
1949
1950 vap_id = hmac_vap->vap_id;
1951 if (hmac_vap_id_param_check(vap_id) != OSAL_TRUE) {
1952 return OSAL_TRUE;
1953 }
1954
1955 if (g_sta_twt_info[vap_id] == OAL_PTR_NULL) {
1956 oam_warning_log1(0, OAM_SF_PWR, "vap_id[%d] {hmac_twt_sta_vap_del::sta_uapsd_info is NULL.}",
1957 hmac_vap->vap_id);
1958 return OSAL_TRUE;
1959 }
1960
1961 oal_mem_free(g_sta_twt_info[vap_id], OAL_TRUE);
1962 g_sta_twt_info[vap_id] = OAL_PTR_NULL;
1963
1964 return OSAL_TRUE;
1965 }
1966
1967 hmac_netbuf_hook_stru twt_netbuf_hook = {
1968 .hooknum = HMAC_FRAME_MGMT_RX_EVENT_FEATURE,
1969 .priority = HMAC_HOOK_PRI_LOW,
1970 .hook_func = hmac_sta_up_rx_action_s1g,
1971 };
1972
hmac_twt_sta_init(osal_void)1973 osal_u32 hmac_twt_sta_init(osal_void)
1974 {
1975 osal_u32 ret;
1976 #ifdef _PRE_WLAN_SUPPORT_CCPRIV_CMD
1977 hmac_ccpriv_register((const osal_s8 *)"twt_setup_req", hmac_ccpriv_twt_setup_req);
1978 hmac_ccpriv_register((const osal_s8 *)"twt_teardown_req", hmac_ccpriv_twt_teardown_req);
1979 hmac_ccpriv_register((const osal_s8 *)"twt_receive_setup", hmac_ccpriv_twt_receive_setup);
1980 hmac_ccpriv_register((const osal_s8 *)"twt_information_req", hmac_ccpriv_twt_information_req);
1981 #endif
1982 frw_util_notifier_register(WLAN_UTIL_NOTIFIER_EVENT_DEL_USER, hmac_twt_deinit);
1983 frw_util_notifier_register(WLAN_UTIL_NOTIFIER_EVENT_ADD_VAP, hmac_twt_sta_vap_add);
1984 frw_util_notifier_register(WLAN_UTIL_NOTIFIER_EVENT_DEL_VAP, hmac_twt_sta_vap_del);
1985
1986 frw_msg_hook_register(WLAN_MSG_D2H_C_CFG_SYNC_TWT_STATUS, hmac_config_twt_status_sync);
1987
1988 hmac_feature_hook_register(HMAC_FHOOK_TWT_IS_SESSION_ENABLE, hmac_twt_is_session_enable);
1989 hmac_feature_hook_register(HMAC_FHOOK_TWT_NOT_NEED_BUFF, hmac_is_twt_processed_not_need_buff);
1990 hmac_feature_hook_register(HMAC_FHOOK_TWT_NEED_BUFF, hmac_is_twt_need_buff);
1991 hmac_feature_hook_register(HMAC_FHOOK_TWT_TX_ACTION, hmac_twt_tx_action);
1992 hmac_feature_hook_register(HMAC_FHOOK_TWT_P2P_TEARDOWN_SESSION, hmac_p2p_teardown_twt_session);
1993 hmac_feature_hook_register(HMAC_FHOOK_TWT_PROCESS_UPDATE_INFO, hmac_process_update_twt);
1994 hmac_feature_hook_register(HMAC_FHOOK_TWT_GET_REQ_BIT, hmac_twt_get_req_bit);
1995 hmac_feature_hook_register(HMAC_FHOOK_TWT_SET_EXT_CAP_TWT_REQ, hmac_set_ext_cap_twt_req);
1996
1997 ret = hmac_register_netbuf_hook(&twt_netbuf_hook);
1998 if (ret != OAL_SUCC) {
1999 oam_error_log0(0, OAM_SF_RX, "{hmac_roam_sta_init:: MGMT RX IN register_netbuf_hooks error!");
2000 return ret;
2001 }
2002
2003 return OAL_SUCC;
2004 }
2005
hmac_twt_sta_deinit(osal_void)2006 osal_void hmac_twt_sta_deinit(osal_void)
2007 {
2008 #ifdef _PRE_WLAN_SUPPORT_CCPRIV_CMD
2009 hmac_ccpriv_unregister((const osal_s8 *)"twt_setup_req");
2010 hmac_ccpriv_unregister((const osal_s8 *)"twt_teardown_req");
2011 hmac_ccpriv_unregister((const osal_s8 *)"twt_receive_setup");
2012 hmac_ccpriv_unregister((const osal_s8 *)"twt_information_req");
2013 #endif
2014 frw_util_notifier_unregister(WLAN_UTIL_NOTIFIER_EVENT_DEL_USER, hmac_twt_deinit);
2015 frw_util_notifier_unregister(WLAN_UTIL_NOTIFIER_EVENT_ADD_VAP, hmac_twt_sta_vap_add);
2016 frw_util_notifier_unregister(WLAN_UTIL_NOTIFIER_EVENT_DEL_VAP, hmac_twt_sta_vap_del);
2017
2018 frw_msg_hook_unregister(WLAN_MSG_D2H_C_CFG_SYNC_TWT_STATUS);
2019
2020 hmac_feature_hook_unregister(HMAC_FHOOK_TWT_IS_SESSION_ENABLE);
2021 hmac_feature_hook_unregister(HMAC_FHOOK_TWT_NOT_NEED_BUFF);
2022 hmac_feature_hook_unregister(HMAC_FHOOK_TWT_NEED_BUFF);
2023 hmac_feature_hook_unregister(HMAC_FHOOK_TWT_TX_ACTION);
2024 hmac_feature_hook_unregister(HMAC_FHOOK_TWT_P2P_TEARDOWN_SESSION);
2025 hmac_feature_hook_unregister(HMAC_FHOOK_TWT_PROCESS_UPDATE_INFO);
2026 hmac_feature_hook_unregister(HMAC_FHOOK_TWT_GET_REQ_BIT);
2027 hmac_feature_hook_unregister(HMAC_FHOOK_TWT_SET_EXT_CAP_TWT_REQ);
2028
2029 hmac_unregister_netbuf_hook(&twt_netbuf_hook);
2030
2031 return;
2032 }
2033
2034 #ifdef __cplusplus
2035 #if __cplusplus
2036 }
2037 #endif
2038 #endif
2039