1 /*
2 * Copyright (c) 2020 HiSilicon (Shanghai) Technologies CO., LIMITED.
3 * Licensed under the Apache License, Version 2.0 (the "License");
4 * you may not use this file except in compliance with the License.
5 * You may obtain a copy of the License at
6 *
7 * http://www.apache.org/licenses/LICENSE-2.0
8 *
9 * Unless required by applicable law or agreed to in writing, software
10 * distributed under the License is distributed on an "AS IS" BASIS,
11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 * See the License for the specific language governing permissions and
13 * limitations under the License.
14 * Description: hmac_csi
15 * Author:
16 * Create: 2022-09-20
17 */
18
19 #ifdef _PRE_WLAN_SUPPORT_CCPRIV_CMD
20 /*****************************************************************************
21 1 头文件包含
22 *****************************************************************************/
23 #include "hmac_csi.h"
24 #include "hmac_ccpriv.h"
25
26 #ifdef __cplusplus
27 #if __cplusplus
28 extern "C" {
29 #endif
30 #endif
31
32 #undef THIS_FILE_ID
33 #define THIS_FILE_ID DIAG_FILE_ID_WIFI_HOST_HMAC_CSI_C
34
35 #undef THIS_MOD_ID
36 #define THIS_MOD_ID DIAG_MOD_ID_WIFI_HOST
37
38 /*****************************************************************************
39 2 全局变量定义
40 *****************************************************************************/
41 osal_u32 g_vap_id = INT_MAX;
42
43 /*****************************************************************************
44 3 函数实现
45 *****************************************************************************/
hmac_config_rx_csi(hmac_vap_stru * hmac_vap,frw_msg * msg)46 OAL_STATIC osal_s32 hmac_config_rx_csi(hmac_vap_stru *hmac_vap, frw_msg *msg)
47 {
48 osal_s32 ret;
49
50 if ((hmac_vap->init_flag == MAC_VAP_INVAILD) || (msg->data == OAL_PTR_NULL)) {
51 oam_warning_log2(0, OAM_SF_M2S,
52 "{hmac_config_rx_csi::hmac_vap->init_flag[%d], param[%p]!}", hmac_vap->init_flag, (uintptr_t)msg->data);
53 return OAL_ERR_CODE_PTR_NULL;
54 }
55 ret = frw_asyn_host_post_msg(WLAN_MSG_H2W_RX_CSI, FRW_POST_PRI_LOW, hmac_vap->vap_id, msg);
56 if (ret != OAL_SUCC) {
57 oam_warning_log2(0, OAM_SF_M2S,
58 "{hmac_config_rx_csi::hmac_vap->vap_id[%d], param[%p]!}", hmac_vap->vap_id, (uintptr_t)msg->data);
59 return ret;
60 }
61
62 return OAL_SUCC;
63 }
64
hmac_csi_set_reg_config(hmac_vap_stru * hmac_vap)65 OAL_STATIC osal_s32 hmac_csi_set_reg_config(hmac_vap_stru *hmac_vap)
66 {
67 hal_csi_set_tsf(hmac_vap->hal_vap->vap_id);
68
69 /* 关闭csi ack帧默认上报通道 */
70 hal_csi_set_ack_resp_flt();
71
72 /* 使能csi时,打开mac和phy的PA */
73 hal_enable_machw_phy_and_pa(hmac_vap->hal_device);
74
75 return OAL_SUCC;
76 }
77
hmac_config_csi_set_config(hmac_vap_stru * hmac_vap,frw_msg * msg)78 OAL_STATIC osal_s32 hmac_config_csi_set_config(hmac_vap_stru *hmac_vap, frw_msg *msg)
79 {
80 hal_csi_usr_attr user_attr;
81 mac_csi_usr_config_stru *csi_config = OAL_PTR_NULL;
82 osal_s32 ret;
83
84 /* 不允许在多个vap_id下发csi相关配置,只能用同一个vap */
85 if (g_vap_id != INT_MAX && hmac_vap->vap_id != g_vap_id) {
86 oam_error_log1(0, OAM_SF_CFG, "vap_id[%d] {hmac_config_csi_set_config:VAPs cannot coexist.}",
87 hmac_vap->vap_id);
88 return OAL_ERR_CODE_CONFIG_UNSUPPORT;
89 }
90 g_vap_id = hmac_vap->vap_id;
91
92 csi_config = (mac_csi_usr_config_stru *)msg->data;
93 hal_csi_get_usr_attr(csi_config->user_idx, &user_attr);
94 /* enable为0表示关闭对应user idx的csi信息上报,user全关闭,重置g_vap_id */
95 if (csi_config->enable == 0) {
96 user_attr.cfg_csi_en = 0;
97 hal_csi_set_usr_attr(csi_config->user_idx, &user_attr);
98 if (hal_csi_vap_is_close() == OAL_TRUE) {
99 g_vap_id = INT_MAX;
100 }
101 return OAL_SUCC;
102 }
103
104 /* 剩下处理修改user idx的配置的情况,如果现在就是开启状态,则不允许修改 */
105 if (user_attr.cfg_csi_en == 1) {
106 oam_error_log1(0, OAM_SF_CFG, "user_idx[%d] {hmac_config_csi_set_config:user exists.}",
107 csi_config->user_idx);
108 return OAL_ERR_CODE_CONFIG_UNSUPPORT;
109 }
110
111 /* 寄存器相关配置设置 */
112 ret = hmac_csi_set_reg_config(hmac_vap);
113 if (ret != OAL_SUCC) {
114 oam_warning_log1(0, OAM_SF_CFG, "{hmac_config_csi_set_config::hmac_vap->vap_id[%d]!}", hmac_vap->vap_id);
115 return ret;
116 }
117
118 /* 白名单总开关 */
119 user_attr.cfg_csi_en = 1;
120 /* MAC地址方向, 0 RA,1 TA */
121 user_attr.cfg_match_ta_ra_sel = csi_config->cfg_match_ta_ra_sel;
122
123 /* 帧类型过滤,管理 控制 数据 */
124 memcpy_s(user_attr.usr_addr, WLAN_MAC_ADDR_LEN, csi_config->mac_addr, WLAN_MAC_ADDR_LEN);
125 user_attr.cfg_mgmt_frame_en = ((csi_config->frame_type_filter_bitmap >> WLAN_MANAGEMENT) & 0x1);
126 user_attr.cfg_ctrl_frame_en = ((csi_config->frame_type_filter_bitmap >> WLAN_CONTROL) & 0x1);
127 user_attr.cfg_data_frame_en = ((csi_config->frame_type_filter_bitmap >> WLAN_DATA_BASICTYPE) & 0x1);
128 /* 帧子类型过滤开关 */
129 user_attr.frm_subtype_match_en = csi_config->sub_type_filter_enable;
130 /* 帧子类型过滤类型 */
131 user_attr.match_frame_subtype = csi_config->sub_type_filter;
132 /* ppdu format类型 */
133 user_attr.ppdu_non_ht_en = ((csi_config->ppdu_filter_bitmap >> HAL_CSI_PPDU_NONE_HT) & 0x1);
134 user_attr.ppdu_he_er_su_en = ((csi_config->ppdu_filter_bitmap >> HAL_CSI_PPDU_HE_ER_SU) & 0x1);
135 user_attr.ppdu_he_mu_mimo_en = ((csi_config->ppdu_filter_bitmap >> HAL_CSI_PPDU_HE_MU_MIMO) & 0x1);
136 user_attr.ppdu_he_mu_ofdma_en = ((csi_config->ppdu_filter_bitmap >> HAL_CSI_PPDU_HE_MU_OFDMA) & 0x1);
137 user_attr.ppdu_ht_en = ((csi_config->ppdu_filter_bitmap >> HAL_CSI_PPDU_HT) & 0x1);
138 user_attr.ppdu_vht_en = ((csi_config->ppdu_filter_bitmap >> HAL_CSI_PPDU_VHT) & 0x1);
139 /* period间隔时间 */
140 user_attr.sample_period_ms = csi_config->period;
141
142 wifi_printf("csi_set_config:frame type[%d %d %d] \r\n",
143 user_attr.cfg_mgmt_frame_en, user_attr.cfg_ctrl_frame_en, user_attr.cfg_data_frame_en);
144
145 hal_csi_set_usr_attr(csi_config->user_idx, &user_attr);
146 return OAL_SUCC;
147 }
148
hmac_csi_set_param(const osal_s8 * param,mac_csi_usr_config_stru * csi_config)149 OAL_STATIC osal_s32 hmac_csi_set_param(const osal_s8 *param, mac_csi_usr_config_stru *csi_config)
150 {
151 osal_u32 val;
152 osal_s32 ret;
153
154 /* 获取参数 白名单地址过滤类型 0 RA 1 TA */
155 ret = hmac_ccpriv_get_digit_with_check_max(¶m, 1, &val);
156 if (ret != OAL_SUCC) {
157 oam_warning_log1(0, OAM_SF_ANY, "{hmac_ccpriv_csi_set_config::get addr_filter_type err[%d]!}", ret);
158 return ret;
159 }
160 csi_config->cfg_match_ta_ra_sel = (osal_u8)val;
161
162 /* 获取参数 user mac地址 */
163 ret = (osal_s32)hmac_ccpriv_get_mac_addr_etc(¶m, csi_config->mac_addr);
164 if (ret != OAL_SUCC) {
165 oam_warning_log1(0, OAM_SF_ANY, "{hmac_ccpriv_csi_set_config::get mac err[%d]!}", ret);
166 return ret;
167 }
168
169 /* 获取参数 user frame type,取值范围0~7,bit0管理帧 bit1控制帧 bit2数据帧 */
170 ret = hmac_ccpriv_get_digit_with_check_max(¶m, 7, &val);
171 if (ret != OAL_SUCC) {
172 oam_warning_log1(0, OAM_SF_ANY, "{hmac_ccpriv_csi_set_config::get frame_type err[%d]!}", ret);
173 return ret;
174 }
175 csi_config->frame_type_filter_bitmap = (osal_u8)val;
176
177 /* 获取参数子帧过滤开关,取值0关闭,1打开 */
178 ret = hmac_ccpriv_get_digit_with_check_max(¶m, 1, &val);
179 if (ret != OAL_SUCC) {
180 oam_warning_log1(0, OAM_SF_ANY, "{hmac_ccpriv_csi_set_config::get frame sub type enable err[%d]!}", ret);
181 return ret;
182 }
183 csi_config->sub_type_filter_enable = (osal_u8)val;
184
185 /* 获取参数 user frame sub type,取值范围0~15,由4个bit组成的子帧类型对应的十进制数,1111对应15 */
186 ret = hmac_ccpriv_get_digit_with_check_max(¶m, 15, &val);
187 if (ret != OAL_SUCC) {
188 oam_warning_log1(0, OAM_SF_ANY, "{hmac_ccpriv_csi_set_config::get frame sub type filter err[%d]!}", ret);
189 return ret;
190 }
191 csi_config->sub_type_filter = (osal_u8)val;
192
193 /* 获取ppdu format过滤具体参数,取值范围0~63,共6位bit,详见结构体定义 */
194 ret = hmac_ccpriv_get_digit_with_check_max(¶m, 63, &val);
195 if (ret != OAL_SUCC) {
196 oam_warning_log1(0, OAM_SF_ANY, "{hmac_ccpriv_csi_set_config::frame ppdu_filter_bitmap err[%d]!}", ret);
197 return ret;
198 }
199 csi_config->ppdu_filter_bitmap = (osal_u8)val;
200
201 /* 获取csi 上报时间间隔,取值范围0~4095(单位ms),共12位bit */
202 ret = hmac_ccpriv_get_digit_with_check_max(¶m, 4095, &val);
203 if (ret != OAL_SUCC) {
204 oam_warning_log1(0, OAM_SF_ANY, "{hmac_ccpriv_csi_set_config::get period err[%d]!}", ret);
205 return ret;
206 }
207 csi_config->period = (osal_u16)val;
208
209 return OAL_SUCC;
210 }
211
hmac_ccpriv_csi_set_config(hmac_vap_stru * hmac_vap,const osal_s8 * param)212 OAL_STATIC osal_s32 hmac_ccpriv_csi_set_config(hmac_vap_stru *hmac_vap, const osal_s8 *param)
213 {
214 mac_csi_usr_config_stru csi_config;
215 osal_u32 val;
216 osal_s32 ret;
217 frw_msg msg;
218
219 (osal_void)memset_s(&csi_config, OAL_SIZEOF(csi_config), 0, OAL_SIZEOF(csi_config));
220 (osal_void)memset_s(&msg, OAL_SIZEOF(msg), 0, OAL_SIZEOF(msg));
221
222 /* 获取参数 user_idx,取值范围0~3,共4个用户 */
223 ret = hmac_ccpriv_get_digit_with_check_max(¶m, 3, &val);
224 if (ret != OAL_SUCC) {
225 oam_warning_log1(0, OAM_SF_ANY, "{hmac_ccpriv_csi_set_config::get user_idx err[%d]!}", ret);
226 return ret;
227 }
228 csi_config.user_idx = (osal_u8)val;
229
230 /* 获取参数 user开关 0表示删除,1表示添加 */
231 ret = hmac_ccpriv_get_digit_with_check_max(¶m, 1, &val);
232 if (ret != OAL_SUCC) {
233 oam_warning_log1(0, OAM_SF_ANY, "{hmac_ccpriv_csi_set_config::get enable err[%d]!}", ret);
234 return ret;
235 }
236 csi_config.enable = (osal_u8)val;
237
238 /* 只有当获取的enable参数为1时,才接着获取接下来的其他参数 */
239 if (csi_config.enable == 1) {
240 ret = hmac_csi_set_param(param, &csi_config);
241 if (ret != OAL_SUCC) {
242 oam_warning_log1(0, OAM_SF_ANY, "{hmac_ccpriv_csi_set_config::hmac_csi_set_param err[%d]!}", ret);
243 return ret;
244 }
245 }
246
247 msg.data = (osal_u8 *)&csi_config;
248 ret = hmac_config_csi_set_config(hmac_vap, &msg);
249 if (OAL_UNLIKELY(ret != OAL_SUCC)) {
250 oam_warning_log1(0, OAM_SF_ANY, "{hmac_ccpriv_csi_set_config::return err code [%d]!}", ret);
251 }
252 return ret;
253 }
254
255 /* 获取用户0配置信息 echo "wlan0 csi_get_config 0" > /sys/hisys/ccpriv */
hmac_ccpriv_csi_get_config(hmac_vap_stru * hmac_vap,const osal_s8 * param)256 OAL_STATIC osal_s32 hmac_ccpriv_csi_get_config(hmac_vap_stru *hmac_vap, const osal_s8 *param)
257 {
258 hal_csi_usr_attr user_attr;
259 osal_s32 ret;
260 osal_u8 user_id;
261
262 unref_param(hmac_vap);
263
264 (osal_void)memset_s(&user_attr, OAL_SIZEOF(user_attr), 0, OAL_SIZEOF(user_attr));
265
266 /* 获取参数 user_idx,取值范围0~3,共4个用户 */
267 ret = hmac_ccpriv_get_u8_with_check_max(¶m, 3, &user_id);
268 if (ret != OAL_SUCC) {
269 oam_warning_log1(0, OAM_SF_ANY, "{hmac_ccpriv_csi_get_config::get user_idx err[%d]!}", ret);
270 return ret;
271 }
272
273 hal_csi_get_usr_attr(user_id, &user_attr);
274 /* 如果该用户现在是关闭状态,则不进行打印 */
275 if (user_attr.cfg_csi_en == 0) {
276 return OAL_ERR_CODE_CONFIG_UNSUPPORT;
277 }
278
279 /* 打印所获取的用户配置信息 */
280 wifi_printf("hmac_ccpriv_csi_get_config:usr_id: %d addr_filter_type: %d mac_addr[%02X:%02X:**:**:**:**] \r\n",
281 user_id, user_attr.cfg_match_ta_ra_sel, user_attr.usr_addr[0], user_attr.usr_addr[1]);
282 wifi_printf("hmac_ccpriv_csi_get_config:frame type[%d %d %d] sub_frame_enable[%d] sub_frame[%d]\r\n",
283 user_attr.cfg_mgmt_frame_en, user_attr.cfg_ctrl_frame_en, user_attr.cfg_data_frame_en,
284 user_attr.frm_subtype_match_en, user_attr.match_frame_subtype);
285 wifi_printf("hmac_ccpriv_csi_get_config:ppdu[%d %d %d %d %d %d] period[%d]\r\n",
286 user_attr.ppdu_non_ht_en, user_attr.ppdu_he_er_su_en, user_attr.ppdu_he_mu_mimo_en,
287 user_attr.ppdu_he_mu_ofdma_en, user_attr.ppdu_ht_en, user_attr.ppdu_vht_en, user_attr.sample_period_ms);
288
289 return OAL_SUCC;
290 }
291
292 /* 设置buffer个数和大小,默认值为2,762 */
hmac_ccpriv_csi_set_buffer(hmac_vap_stru * hmac_vap,const osal_s8 * param)293 OAL_STATIC osal_s32 hmac_ccpriv_csi_set_buffer(hmac_vap_stru *hmac_vap, const osal_s8 *param)
294 {
295 hal_csi_buffer_stru csi_buffer;
296 osal_s32 ret;
297 osal_u32 val;
298 osal_u32 buflen = 762; /* 762 默认buffer长度 */
299
300 unref_param(hmac_vap);
301
302 (osal_void)memset_s(&csi_buffer, OAL_SIZEOF(csi_buffer), 0, OAL_SIZEOF(csi_buffer));
303
304 /* 获取参数 csi_data_blk_num,取值范围1~4,buffer个数 */
305 ret = hmac_ccpriv_get_digit_with_check_max(¶m, 4, &val);
306 if (ret != OAL_SUCC) {
307 oam_warning_log1(0, OAM_SF_ANY, "{hmac_ccpriv_csi_set_buffer::get csi_data_blk_num err[%d]!}", ret);
308 return ret;
309 }
310 csi_buffer.csi_data_blk_num = (osal_u8)val;
311
312 /* 获取参数 csi_data_max_len,取值范围378~762,单个buffer长度 */
313 ret = hmac_ccpriv_get_digit_with_check_max(¶m, buflen, &val);
314 if (ret != OAL_SUCC) {
315 oam_warning_log1(0, OAM_SF_ANY, "{hmac_ccpriv_csi_set_buffer::get csi_data_max_len err[%d]!}", ret);
316 return ret;
317 }
318 csi_buffer.csi_data_max_len = (osal_u16)val;
319
320 /* 判断buffer总长度是否超限,因为申请的是netbuf内存池,所以乘积不能超过netbuf最大的size */
321 if (csi_buffer.csi_data_blk_num > WLAN_LARGE_NETBUF_SIZE / csi_buffer.csi_data_max_len) {
322 oam_warning_log0(0, OAM_SF_ANY, "{hmac_ccpriv_csi_set_buffer::buffer exceeds the threshold!}");
323 return OAL_ERR_CODE_CONFIG_EXCEED_SPEC;
324 }
325
326 ret = (osal_s32)hal_csi_set_buffer_config(&csi_buffer);
327 if (ret != OAL_SUCC) {
328 oam_error_log1(0, OAM_SF_CFG, "hmac_ccpriv_csi_set_buffer:set buffer failed! buffer len[%u] user is null.",
329 csi_buffer.csi_data_max_len);
330 return OAL_ERR_CODE_INVALID_CONFIG;
331 }
332 return OAL_SUCC;
333 }
334
hmac_csi_exit(osal_void)335 OAL_STATIC osal_void hmac_csi_exit(osal_void)
336 {
337 osal_u8 index;
338
339 /* 禁用所有用户,退出CSI,重置g_vap_id */
340 for (index = 0; index < HAL_CSI_MAX_USER_NUM; index++) {
341 hal_csi_disable(index);
342 }
343 g_vap_id = INT_MAX;
344 }
345
hmac_config_csi_switch(hmac_vap_stru * hmac_vap,frw_msg * msg)346 OAL_STATIC osal_s32 hmac_config_csi_switch(hmac_vap_stru *hmac_vap, frw_msg *msg)
347 {
348 oal_bool_enum_uint8 csi_switch_on;
349
350 unref_param(hmac_vap);
351
352 csi_switch_on = (oal_bool_enum_uint8)*msg->data;
353 if (csi_switch_on == OAL_TRUE) {
354 hh503_csi_phy_open_channel();
355 } else if (csi_switch_on == OAL_FALSE) {
356 hmac_csi_exit();
357 } else {
358 return OAL_ERR_CODE_INVALID_CONFIG;
359 }
360
361 return OAL_SUCC;
362 }
363
hmac_ccpriv_csi_switch(hmac_vap_stru * hmac_vap,const osal_s8 * param)364 OAL_STATIC osal_s32 hmac_ccpriv_csi_switch(hmac_vap_stru *hmac_vap, const osal_s8 *param)
365 {
366 osal_u8 val;
367 osal_s32 ret;
368 oal_bool_enum_uint8 csi_switch_on;
369 frw_msg msg;
370
371 (osal_void)memset_s(&msg, OAL_SIZEOF(msg), 0, OAL_SIZEOF(msg));
372
373 ret = hmac_ccpriv_get_u8_with_check_max(¶m, 1, &val);
374 if (ret != OAL_SUCC) {
375 oam_warning_log1(0, OAM_SF_ANY, "{hmac_ccpriv_csi_switch::get csi_data_blk_num err[%d]!}", ret);
376 return ret;
377 }
378 csi_switch_on = val;
379
380 msg.data = (osal_u8 *)&csi_switch_on;
381 ret = hmac_config_csi_switch(hmac_vap, &msg);
382 if (OAL_UNLIKELY(ret != OAL_SUCC)) {
383 oam_warning_log1(0, OAM_SF_ANY, "{hmac_ccpriv_csi_switch::return err code [%d]!}", ret);
384 }
385 return ret;
386 }
387
hmac_csi_init(osal_void)388 osal_u32 hmac_csi_init(osal_void)
389 {
390 /* ccpriv命令注册 */
391 hmac_ccpriv_register((const osal_s8 *)"csi_set_config", hmac_ccpriv_csi_set_config);
392 hmac_ccpriv_register((const osal_s8 *)"csi_get_config", hmac_ccpriv_csi_get_config);
393 hmac_ccpriv_register((const osal_s8 *)"csi_set_buffer", hmac_ccpriv_csi_set_buffer);
394 hmac_ccpriv_register((const osal_s8 *)"csi_switch", hmac_ccpriv_csi_switch);
395
396 /* 消息注册 */
397 frw_msg_hook_register(WLAN_MSG_W2H_C_CFG_SET_CSI_PARAM, hmac_config_csi_set_config);
398 frw_msg_hook_register(WLAN_MSG_W2H_C_CFG_CSI_SWITCH, hmac_config_csi_switch);
399 frw_msg_hook_register(WLAN_MSG_D2H_C_CFG_RX_CSI, hmac_config_rx_csi);
400
401 /* 对外接口注册 */
402 hmac_feature_hook_register(HMAC_FHOOK_CSI_EXIT, hmac_csi_exit);
403 return OAL_SUCC;
404 }
405
hmac_csi_deinit(osal_void)406 osal_void hmac_csi_deinit(osal_void)
407 {
408 /* ccpriv命令去注册 */
409 hmac_ccpriv_unregister((const osal_s8 *)"csi_set_config");
410 hmac_ccpriv_unregister((const osal_s8 *)"csi_get_config");
411 hmac_ccpriv_unregister((const osal_s8 *)"csi_set_buffer");
412 hmac_ccpriv_unregister((const osal_s8 *)"csi_switch");
413
414 /* 消息去注册 */
415 frw_msg_hook_unregister(WLAN_MSG_W2H_C_CFG_SET_CSI_PARAM);
416 frw_msg_hook_unregister(WLAN_MSG_W2H_C_CFG_CSI_SWITCH);
417 frw_msg_hook_unregister(WLAN_MSG_D2H_C_CFG_RX_CSI);
418
419 /* 对外接口去注册 */
420 hmac_feature_hook_unregister(HMAC_FHOOK_CSI_EXIT);
421 return;
422 }
423
424 #ifdef __cplusplus
425 #if __cplusplus
426 }
427 #endif
428 #endif
429 #endif /* #ifdef _PRE_WLAN_SUPPORT_CCPRIV_CMD */