• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2020 HiSilicon (Shanghai) Technologies CO., LIMITED.
3  * Licensed under the Apache License, Version 2.0 (the "License");
4  * you may not use this file except in compliance with the License.
5  * You may obtain a copy of the License at
6  *
7  *     http://www.apache.org/licenses/LICENSE-2.0
8  *
9  * Unless required by applicable law or agreed to in writing, software
10  * distributed under the License is distributed on an "AS IS" BASIS,
11  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12  * See the License for the specific language governing permissions and
13  * limitations under the License.
14  * Description: 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(&param, 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(&param, 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(&param, 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(&param, 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(&param, 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(&param, 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(&param, 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(&param, 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(&param, 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(&param, 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(&param, 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(&param, 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(&param, 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 */