• 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  * 文 件 名   : 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(&param, (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(&param, (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(&param, 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(&param, 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(&param, (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(&param, (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