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: APF hmac function.
15 * Create: 2022-10-14
16 */
17
18 /*****************************************************************************
19 1 头文件包含
20 *****************************************************************************/
21 #include "hmac_apf.h"
22 #include "msg_apf_rom.h"
23 #include "frw_util_notifier.h"
24 #include "hmac_feature_interface.h"
25 #ifdef _PRE_PLAT_FEATURE_CUSTOMIZE
26 #include "soc_customize_wifi.h"
27 #endif
28
29 #ifdef __cplusplus
30 #if __cplusplus
31 extern "C" {
32 #endif
33 #endif
34
35 #undef THIS_FILE_ID
36 #define THIS_FILE_ID DIAG_FILE_ID_WIFI_HOST_HMAC_APF_C
37
38 #undef THIS_MOD_ID
39 #define THIS_MOD_ID DIAG_MOD_ID_WIFI_HOST
40
41 /*****************************************************************************
42 2 全局变量定义
43 *****************************************************************************/
44 /* APF规则信息全局结构体 */
45 mac_apf_stru g_hmac_st_apf = {0};
46 osal_u8 g_hmac_st_apf_ip[0x4] = {0};
47
48 /*****************************************************************************
49 3 函数实现
50 *****************************************************************************/
51
52 /*****************************************************************************
53 功能描述 : 更新APF过滤规则中自己的IP地址
54 *****************************************************************************/
hmac_apf_update_st_apf(osal_void)55 OSAL_STATIC osal_void hmac_apf_update_st_apf(osal_void)
56 {
57 frw_msg msg2device = {0};
58 osal_s32 ret;
59 osal_u32 j;
60 osal_u32 i;
61
62 if (g_hmac_st_apf.program_len < APF_PROGRAM_IPV4_BROADCAST_END) {
63 return;
64 }
65 /* 从第76 - 79字符是IPV4地址 */
66 for (j = APF_PROGRAM_IPV4_BEGIN, i = 0; j <= APF_PROGRAM_IPV4_END; j++, i++) {
67 g_hmac_st_apf.program[j] = ((osal_u8 *)(g_hmac_st_apf_ip))[i];
68 }
69
70 /* 替换网段广播地址,从第143 - 145字符是IPV4段广播地址 */
71 for (j = APF_PROGRAM_IPV4_BROADCAST_BEGIN, i = 0; j <= APF_PROGRAM_IPV4_BROADCAST_END; j++, i++) {
72 g_hmac_st_apf.program[j] = ((osal_u8 *)(g_hmac_st_apf_ip))[i];
73 }
74
75 if (g_hmac_st_apf.is_enabled == OAL_TRUE) {
76 // 下发事件更新apf规则
77 frw_msg_init((osal_u8 *)&g_hmac_st_apf, sizeof(mac_apf_stru), OSAL_NULL, 0, &msg2device);
78 ret = send_cfg_to_device(0, WLAN_MSG_H2D_C_CFG_APF_EXEC, &msg2device, OSAL_TRUE);
79 if (ret != OAL_SUCC) {
80 oam_error_log1(0, OAM_SF_APF, "{hmac_apf_update_st_apf:: send apf on to device fail [%d]!}", ret);
81 }
82 }
83 }
84
hmac_apf_set_ip_addr_etc(osal_void * notify_data)85 OSAL_STATIC osal_bool hmac_apf_set_ip_addr_etc(osal_void *notify_data)
86 {
87 if (notify_data == OAL_PTR_NULL) {
88 oam_error_log0(0, OAM_SF_PWR, "{hmac_apf_set_ip_addr_etc::The ip_addr is NULL. }");
89 return OSAL_FALSE;
90 }
91 (osal_void)memcpy_s(g_hmac_st_apf_ip, sizeof(g_hmac_st_apf_ip), notify_data, sizeof(g_hmac_st_apf_ip));
92 hmac_apf_update_st_apf();
93 return OSAL_TRUE;
94 }
95
96 /*****************************************************************************
97 功能描述 : APF功能开关
98 *****************************************************************************/
hmac_apf_filter_switch(osal_void * notify_data)99 OSAL_STATIC osal_bool hmac_apf_filter_switch(osal_void *notify_data)
100 {
101 frw_msg msg2device = {0};
102 oal_bool_enum_uint8 device_apf_msg;
103 osal_s32 ret;
104 oal_bool_enum_uint8 apf_switch = *(oal_bool_enum_uint8 *)notify_data;
105 osal_u32 pps_rate = 0;
106 osal_void *fhook = hmac_get_feature_fhook(HMAC_FHOOK_AUTO_FREQ_PPS);
107
108 if (apf_switch >= OAL_BUTT) {
109 return OSAL_FALSE;
110 }
111
112 if (fhook != OSAL_NULL) {
113 ((hmac_get_pps_handle_pps_rate_cb)fhook)(&pps_rate);
114 }
115
116 /* 如果apf已处状态和设置状态一致 则直接返回 */
117 if (g_hmac_st_apf.is_enabled == apf_switch) {
118 return OSAL_TRUE;
119 }
120
121 /* 开关状态置为关 */
122 if (apf_switch == OAL_FALSE) {
123 oam_warning_log0(0, OAM_SF_APF, "hmac_apf_filter_switch::disable");
124 device_apf_msg = OAL_FALSE;
125 g_hmac_st_apf.is_enabled = OAL_FALSE;
126
127 // 下发事件将device的apf功能给关了
128 frw_msg_init((osal_u8 *)&device_apf_msg, sizeof(oal_bool_enum_uint8), OSAL_NULL, 0, &msg2device);
129 /* snyc ps config to device */
130 ret = send_cfg_to_device(0, WLAN_MSG_H2D_C_CFG_APF_EXEC, &msg2device, OSAL_TRUE);
131 if (ret != OAL_SUCC) {
132 oam_error_log1(0, OAM_SF_APF, "{hmac_apf_filter_switch:: send apf off to device fail [%d]!}", ret);
133 return OSAL_FALSE;
134 }
135 return OSAL_TRUE;
136 }
137
138 if ((g_hmac_st_apf.program_len != 0) && (pps_rate <= PPS_VALUE_1)) {
139 g_hmac_st_apf.is_enabled = OAL_TRUE;
140
141 oam_warning_log3(0, OAM_SF_APF, "hmac_apf_filter_switch:enable[%hhu] program len[%hu], over[%u]",
142 g_hmac_st_apf.is_enabled, g_hmac_st_apf.program_len, PPS_VALUE_1);
143
144 // 下发事件开apf功能
145 frw_msg_init((osal_u8 *)&g_hmac_st_apf, sizeof(mac_apf_stru), OSAL_NULL, 0, &msg2device);
146 ret = send_cfg_to_device(0, WLAN_MSG_H2D_C_CFG_APF_EXEC, &msg2device, OSAL_TRUE);
147 if (ret != OAL_SUCC) {
148 oam_error_log1(0, OAM_SF_APF, "{hmac_apf_filter_switch:: send apf on to device fail [%d]!}", ret);
149 return OSAL_FALSE;
150 }
151 } else {
152 oam_warning_log0(0, OAM_SF_APF, "hmac_apf_filter_switch::can't enable apf.");
153 }
154 return OSAL_TRUE;
155 }
156
157 /*****************************************************************************
158 功能描述 : 强制停止APF
159 *****************************************************************************/
hmac_config_force_stop_filter(hmac_vap_stru * hmac_vap,frw_msg * msg)160 OSAL_STATIC osal_s32 hmac_config_force_stop_filter(hmac_vap_stru *hmac_vap, frw_msg *msg)
161 {
162 oal_bool_enum_uint8 uc_switch = OAL_FALSE;
163 hmac_device_stru *hmac_device;
164 osal_u8 force_stop_filter;
165
166 if (hmac_vap == OAL_PTR_NULL || msg == OAL_PTR_NULL) {
167 oam_warning_log0(0, OAM_SF_APF, "hmac_config_force_stop_filter:: NULL ptr error.");
168 return OAL_ERR_CODE_PTR_NULL;
169 }
170
171 if (hwifi_get_apf_enable() == OSAL_FALSE) {
172 oam_warning_log0(0, OAM_SF_APF, "{hmac_config_force_stop_filter: apf isn't supported.}");
173 return OAL_SUCC;
174 }
175
176 hmac_device = hmac_res_get_mac_dev_etc(hmac_vap->device_id);
177 if (hmac_device == OAL_PTR_NULL) {
178 oam_warning_log0(0, OAM_SF_APF, "hmac_config_force_stop_filter::hmac_device NULL error");
179 return OAL_ERR_CODE_PTR_NULL;
180 }
181
182 force_stop_filter = (*((osal_s32 *)msg->data) == OSAL_SWITCH_ON);
183 /* 在暗屏情况下, force_stop_filter不使能时,开启apf过滤; 使能时,强制关闭apf */
184 if ((hmac_device->in_suspend == OSAL_TRUE) && (force_stop_filter == OAL_FALSE)) {
185 // 打开apf
186 uc_switch = OAL_TRUE;
187 }
188 hmac_apf_filter_switch(&uc_switch);
189 return OAL_SUCC;
190 }
191
192 /*****************************************************************************
193 功能描述 : 配置APF过滤条件
194 *****************************************************************************/
hmac_apf_filter_install(const mac_apf_filter_cmd_stru * apf_filter_cmd)195 OSAL_STATIC osal_void hmac_apf_filter_install(const mac_apf_filter_cmd_stru *apf_filter_cmd)
196 {
197 osal_u8 *program = apf_filter_cmd->program;
198 osal_u16 program_len = apf_filter_cmd->program_len;
199
200 if (program_len > APF_PROGRAM_MAX_LEN) {
201 oam_error_log2(0, OAM_SF_APF, "{hmac_apf_filter_install::program_len [%hu] > APF_PROGRAM_MAX_LEN[%d]!.}",
202 program_len, APF_PROGRAM_MAX_LEN);
203 return;
204 }
205
206 if (memcpy_s(g_hmac_st_apf.program, APF_PROGRAM_MAX_LEN, program, program_len) != EOK) {
207 oam_error_log0(0, OAM_SF_APF, "hmac_apf_filter_install::memcpy fail.");
208 return;
209 }
210 g_hmac_st_apf.program_len = program_len;
211 hmac_apf_update_st_apf();
212 g_hmac_st_apf.install_timestamp = (osal_u32)(osal_get_time_stamp_ms() >> BIT_OFFSET_10); /* 秒级时间戳 */
213
214 oam_warning_log1(0, OAM_SF_APF, "{hmac_apf_filter_install::set_apf_filter succ, program_len[%hu].}",
215 g_hmac_st_apf.program_len);
216 return;
217 }
218
219 /*****************************************************************************
220 功能描述 : 删除APF过滤条件
221 *****************************************************************************/
hmac_apf_filter_del_user(osal_void * notify_data)222 OSAL_STATIC osal_bool hmac_apf_filter_del_user(osal_void *notify_data)
223 {
224 frw_msg msg2device = {0};
225 oal_bool_enum_uint8 device_apf_msg;
226 osal_s32 ret;
227 hmac_vap_stru *hmac_vap = OSAL_NULL;
228 hmac_user_stru *hmac_user = (hmac_user_stru *)notify_data;
229
230 hmac_vap = mac_res_get_hmac_vap(hmac_user->vap_id);
231 if (hmac_vap == OSAL_NULL) {
232 oam_warning_log1(0, 0, "{hmac_apf_filter_del_user:vap[%d] is null.}", hmac_user->vap_id);
233 return OSAL_FALSE;
234 }
235
236 if (!is_legacy_sta(hmac_vap)) {
237 return OSAL_TRUE;
238 }
239
240 /* 如果apf正打开,则发事件关闭 */
241 if (g_hmac_st_apf.is_enabled == OSAL_TRUE) {
242 device_apf_msg = OSAL_FALSE;
243 frw_msg_init((osal_u8 *)&device_apf_msg, sizeof(oal_bool_enum_uint8), OSAL_NULL, 0, &msg2device);
244 /* snyc ps config to device */
245 ret = send_cfg_to_device(hmac_vap->vap_id, WLAN_MSG_H2D_C_CFG_APF_EXEC, &msg2device, OSAL_TRUE);
246 if (ret != OAL_SUCC) {
247 oam_error_log1(0, OAM_SF_APF, "{hmac_apf_filter_uninstall:: send apf off to device fail [%d]!}", ret);
248 }
249 }
250 oam_warning_log1(0, OAM_SF_APF, "dmac_apf_filter_uninstall::program_len[%hu].", g_hmac_st_apf.program_len);
251 g_hmac_st_apf.is_enabled = OAL_FALSE;
252 g_hmac_st_apf.program_len = 0;
253 return OSAL_TRUE;
254 }
255
256 /*****************************************************************************
257 功能描述:
258 1.当apf_filter_cmd->cmd_type == APF_SET_FILTER_CMD时,
259 下发APF过滤规则到dmac
260 2.当apf_filter_cmd->cmd_type != APF_SET_FILTER_CMD时,
261 上报HMAC侧当前APF过滤规则
262 *****************************************************************************/
hmac_config_apf_filter_cmd(hmac_vap_stru * hmac_vap,frw_msg * msg)263 OSAL_STATIC osal_s32 hmac_config_apf_filter_cmd(hmac_vap_stru *hmac_vap, frw_msg *msg)
264 {
265 mac_apf_filter_cmd_stru *apf_filter_cmd = OSAL_NULL;
266 frw_msg msg2device;
267 osal_s32 ret;
268 osal_u32 i;
269
270 if (hmac_vap == OSAL_NULL || msg == OSAL_NULL || msg->data == OSAL_NULL) {
271 oam_error_log0(0, OAM_SF_APF, "{hmac_config_apf_filter_cmd::mac_vap or param or msg->data is null.}");
272 return OAL_ERR_CODE_PTR_NULL;
273 }
274
275 apf_filter_cmd = (mac_apf_filter_cmd_stru *)msg->data;
276 if (apf_filter_cmd->cmd_type == APF_SET_FILTER_CMD) {
277 hmac_apf_filter_install(apf_filter_cmd);
278 /* 规则发生变动需要看目前是否开启apf,如果开启则需要重新下发规则给device */
279 if (g_hmac_st_apf.is_enabled == OAL_TRUE) {
280 frw_msg_init((osal_u8 *)&g_hmac_st_apf, sizeof(mac_apf_stru), OSAL_NULL, 0, &msg2device);
281 ret = send_cfg_to_device(hmac_vap->vap_id, WLAN_MSG_H2D_C_CFG_APF_EXEC, &msg2device, OSAL_TRUE);
282 if (ret != OAL_SUCC) {
283 oam_error_log1(0, OAM_SF_APF, "{hmac_config_apf_filter_cmd:: send apf on to device fail [%d]!}", ret);
284 return ret;
285 }
286 }
287 } else if (apf_filter_cmd->cmd_type == APF_GET_FILTER_CMD) {
288 for (i = 0; i < g_hmac_st_apf.program_len; ++i) {
289 wifi_printf("%02x", g_hmac_st_apf.program[i]);
290 }
291 }
292
293 return OAL_SUCC;
294 }
295
hmac_apf_init(osal_void)296 osal_u32 hmac_apf_init(osal_void)
297 {
298 /* 注册监听 */
299 frw_util_notifier_register(WLAN_UTIL_NOTIFIER_EVENT_DEL_USER, hmac_apf_filter_del_user);
300 frw_util_notifier_register(WLAN_UTIL_NOTIFIER_EVENT_INETADDR_NOTIFIER_UP, hmac_apf_set_ip_addr_etc);
301 frw_util_notifier_register(WLAN_UTIL_NOTIFIER_EVENT_SUSPEND_CHANGE, hmac_apf_filter_switch);
302 /* 注册消息 */
303 frw_msg_hook_register(WLAN_MSG_W2H_CFG_SET_FILTER_LIST, hmac_config_apf_filter_cmd);
304 frw_msg_hook_register(WLAN_MSG_W2H_CFG_FORCE_STOP_FILTER, hmac_config_force_stop_filter);
305 return OAL_SUCC;
306 }
307
hmac_apf_deinit(osal_void)308 osal_void hmac_apf_deinit(osal_void)
309 {
310 /* 去注册监听 */
311 frw_util_notifier_unregister(WLAN_UTIL_NOTIFIER_EVENT_DEL_USER, hmac_apf_filter_del_user);
312 frw_util_notifier_unregister(WLAN_UTIL_NOTIFIER_EVENT_INETADDR_NOTIFIER_UP, hmac_apf_set_ip_addr_etc);
313 frw_util_notifier_unregister(WLAN_UTIL_NOTIFIER_EVENT_SUSPEND_CHANGE, hmac_apf_filter_switch);
314 /* 去注册消息 */
315 frw_msg_hook_unregister(WLAN_MSG_W2H_CFG_SET_FILTER_LIST);
316 frw_msg_hook_unregister(WLAN_MSG_W2H_CFG_FORCE_STOP_FILTER);
317 return;
318 }
319
320 #ifdef __cplusplus
321 #if __cplusplus
322 }
323 #endif
324 #endif
325