1 /*
2 * Copyright (C) 2021 HiSilicon (Shanghai) Technologies CO., LIMITED.
3 *
4 * This program is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU General Public License
6 * as published by the Free Software Foundation; either version 2
7 * of the License, or (at your option) any later version.
8 *
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License
15 * along with this program; if not, write to the Free Software
16 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
17 */
18
19 /* ****************************************************************************
20 1 头文件包含
21 **************************************************************************** */
22 #include "mac_regdomain.h"
23 #include "mac_device.h"
24 #include "hmac_mgmt_sta.h"
25 #include "hmac_sme_sta.h"
26 #include "hmac_fsm.h"
27 #include "hmac_chan_mgmt.h"
28 #include "hcc_hmac_if.h"
29
30 #ifdef __cplusplus
31 #if __cplusplus
32 extern "C" {
33 #endif
34 #endif
35
36 /* ****************************************************************************
37 2 全局变量定义
38 **************************************************************************** */
39 /* 2.4G频段 信道与中心频率映射 */
40 const mac_freq_channel_map_stru g_ast_freq_map_2g[MAC_CHANNEL_FREQ_2_BUTT] = {
41 {2412, 1, 0},
42 {2417, 2, 1},
43 {2422, 3, 2},
44 {2427, 4, 3},
45 {2432, 5, 4},
46 {2437, 6, 5},
47 {2442, 7, 6},
48 {2447, 8, 7},
49 {2452, 9, 8},
50 {2457, 10, 9},
51 {2462, 11, 10},
52 {2467, 12, 11},
53 {2472, 13, 12},
54 {2484, 14, 13},
55 };
56
57 /* ****************************************************************************
58 3 函数实现
59 **************************************************************************** */
get_ast_freq_map_2g_elem(hi_u32 index)60 mac_freq_channel_map_stru get_ast_freq_map_2g_elem(hi_u32 index)
61 {
62 return g_ast_freq_map_2g[index];
63 }
64
65 /* ****************************************************************************
66 功能描述 : 设置VAP信道参数,准备切换至新信道运行
67 输入参数 : pst_mac_vap : MAC VAP结构体指针
68 uc_channel : 新信道号(准备切换到的20MHz主信道号)
69 en_bandwidth: 新带宽模式
70 修改历史 :
71 1.日 期 : 2014年2月22日
72 作 者 : HiSilicon
73 修改内容 : 新生成函数
74 **************************************************************************** */
hmac_chan_initiate_switch_to_new_channel(mac_vap_stru * mac_vap,hi_u8 channel,wlan_channel_bandwidth_enum_uint8 bandwidth)75 static hi_void hmac_chan_initiate_switch_to_new_channel(mac_vap_stru *mac_vap, hi_u8 channel,
76 wlan_channel_bandwidth_enum_uint8 bandwidth)
77 {
78 frw_event_mem_stru *event_mem = HI_NULL;
79 frw_event_stru *event = HI_NULL;
80 hi_u32 ret;
81 dmac_set_ch_switch_info_stru *ch_switch_info = HI_NULL;
82
83 /* AP准备切换信道 */
84 mac_vap->ch_switch_info.ch_switch_status = WLAN_CH_SWITCH_STATUS_1;
85 mac_vap->ch_switch_info.announced_channel = channel;
86 mac_vap->ch_switch_info.announced_bandwidth = bandwidth;
87
88 /* 在Beacon帧中添加Channel Switch Announcement IE */
89 mac_vap->ch_switch_info.csa_present_in_bcn = HI_TRUE;
90
91 oam_info_log2(mac_vap->vap_id, OAM_SF_2040,
92 "{hmac_chan_initiate_switch_to_new_channel::uc_announced_channel=%d,en_announced_bandwidth=%d}",
93 channel, bandwidth);
94
95 /* 申请事件内存 */
96 event_mem = frw_event_alloc(sizeof(dmac_set_ch_switch_info_stru));
97 if (oal_unlikely(event_mem == HI_NULL)) {
98 oam_error_log0(mac_vap->vap_id, OAM_SF_SCAN, "{hmac_chan_initiate_switch_to_new_channel::event_mem null.}");
99 return;
100 }
101
102 event = (frw_event_stru *)event_mem->puc_data;
103
104 /* 填写事件头 */
105 frw_event_hdr_init(&(event->event_hdr), FRW_EVENT_TYPE_WLAN_CTX, DMAC_WLAN_CTX_EVENT_SUB_TYPE_SWITCH_TO_NEW_CHAN,
106 sizeof(dmac_set_ch_switch_info_stru), FRW_EVENT_PIPELINE_STAGE_1, mac_vap->vap_id);
107
108 /* 填写事件payload */
109 ch_switch_info = (dmac_set_ch_switch_info_stru *)event->auc_event_data;
110 ch_switch_info->ch_switch_status = WLAN_CH_SWITCH_STATUS_1;
111 ch_switch_info->announced_channel = channel;
112 ch_switch_info->announced_bandwidth = bandwidth;
113 ch_switch_info->ch_switch_cnt = mac_vap->ch_switch_info.ch_switch_cnt;
114 ch_switch_info->csa_present_in_bcn = HI_TRUE;
115
116 /* 分发事件 */
117 ret = hcc_hmac_tx_control_event(event_mem, sizeof(dmac_set_ch_switch_info_stru));
118 if (ret != HI_SUCCESS) {
119 oam_error_log1(mac_vap->vap_id, OAM_SF_SCAN,
120 "{hmac_chan_initiate_switch_to_new_channel::frw_event_dispatch_event failed[%d].}", ret);
121 frw_event_free(event_mem);
122 return;
123 }
124
125 /* 释放事件 */
126 frw_event_free(event_mem);
127 }
128
129 /* ****************************************************************************
130 功能描述 : 遍历device下所有ap,设置VAP信道参数,准备切换至新信道运行
131 输入参数 : pst_mac_vap : MAC VAP结构体指针
132 uc_channel : 新信道号(准备切换到的20MHz主信道号)
133 en_bandwidth: 新带宽模式
134 修改历史 :
135 1.日 期 : 2014年4月3日
136 作 者 : HiSilicon
137 修改内容 : 新生成函数
138 **************************************************************************** */
hmac_chan_multi_switch_to_new_channel(hi_u8 channel,wlan_channel_bandwidth_enum_uint8 bandwidth)139 hi_void hmac_chan_multi_switch_to_new_channel(hi_u8 channel, wlan_channel_bandwidth_enum_uint8 bandwidth)
140 {
141 hi_u8 vap_idx;
142 mac_device_stru *mac_dev = HI_NULL;
143 mac_vap_stru *ap = HI_NULL;
144
145 oam_info_log2(0, OAM_SF_2040, "{hmac_chan_multi_switch_to_new_channel::uc_channel=%d,en_bandwidth=%d}",
146 channel, bandwidth);
147
148 mac_dev = mac_res_get_dev();
149 if (mac_dev->vap_num == 0) {
150 oam_error_log0(0, OAM_SF_SCAN, "{hmac_chan_multi_switch_to_new_channel::none vap.}");
151 return;
152 }
153
154 /* 遍历device下所有ap,设置ap信道参数,准备切换至新信道运行 */
155 for (vap_idx = 0; vap_idx < mac_dev->vap_num; vap_idx++) {
156 ap = mac_vap_get_vap_stru(mac_dev->auc_vap_id[vap_idx]);
157 if (ap == HI_NULL) {
158 oam_error_log1(0, OAM_SF_SCAN, "{hmac_chan_multi_switch_to_new_channel::pst_ap null.}",
159 mac_dev->auc_vap_id[vap_idx]);
160 continue;
161 }
162
163 /* 只更新AP侧的信道切换信息 */
164 if (ap->vap_mode != WLAN_VAP_MODE_BSS_AP) {
165 continue;
166 }
167
168 hmac_chan_initiate_switch_to_new_channel(ap, channel, bandwidth);
169 }
170 }
171
hmac_chan_sync_init(const mac_vap_stru * mac_vap,dmac_set_chan_stru * set_chan)172 hi_void hmac_chan_sync_init(const mac_vap_stru *mac_vap, dmac_set_chan_stru *set_chan)
173 {
174 if (memset_s(set_chan, sizeof(dmac_set_chan_stru), 0, sizeof(dmac_set_chan_stru)) != EOK) {
175 return;
176 }
177 if (memcpy_s(&set_chan->channel, sizeof(mac_channel_stru), &mac_vap->channel, sizeof(mac_channel_stru)) != EOK) {
178 oam_error_log0(0, OAM_SF_CFG, "hmac_chan_sync_init::hmac_chan_sync_init memcpy_s fail.");
179 return;
180 }
181 if (memcpy_s(&set_chan->ch_switch_info, sizeof(mac_ch_switch_info_stru), &mac_vap->ch_switch_info,
182 sizeof(mac_ch_switch_info_stru)) != EOK) {
183 oam_error_log0(0, OAM_SF_CFG, "hmac_chan_sync_init::hmac_chan_sync_init memcpy_s fail.");
184 return;
185 }
186 }
187
188 /* ****************************************************************************
189 功能描述 : HMAC模块抛事件到DMAC模块,设置SW/MAC/PHY/RF中的信道和带宽,
190 使VAP工作在新信道上
191 修改历史 :
192 1.日 期 : 2014年2月26日
193 作 者 : HiSilicon
194 修改内容 : 新生成函数
195 **************************************************************************** */
hmac_chan_do_sync(mac_vap_stru * mac_vap,dmac_set_chan_stru * set_chan)196 hi_void hmac_chan_do_sync(mac_vap_stru *mac_vap, dmac_set_chan_stru *set_chan)
197 {
198 frw_event_mem_stru *event_mem = HI_NULL;
199 frw_event_stru *event = HI_NULL;
200 hi_u32 ret;
201 hi_u8 idx;
202
203 if (mac_vap == HI_NULL || set_chan == HI_NULL) {
204 oam_error_log2(0, OAM_SF_ANY, "{hmac_chan_do_sync::pst_mac_vap[%p] or pst_set_chan[%p] null!}",
205 (uintptr_t)mac_vap, (uintptr_t)set_chan);
206 return;
207 }
208
209 /* 更新VAP下的主20MHz信道号、带宽模式、信道索引 */
210 ret = mac_get_channel_idx_from_num(mac_vap->channel.band, set_chan->channel.chan_number, &idx);
211 if (ret != HI_SUCCESS) {
212 oam_warning_log1(mac_vap->vap_id, OAM_SF_ANY,
213 "{hmac_chan_sync::mac_get_channel_idx_from_num failed[%d].}", ret);
214 return;
215 }
216
217 mac_vap->channel.chan_number = set_chan->channel.chan_number;
218 mac_vap->channel.en_bandwidth = set_chan->channel.en_bandwidth;
219 mac_vap->channel.idx = idx;
220
221 /* 申请事件内存 */
222 event_mem = frw_event_alloc(sizeof(dmac_set_chan_stru));
223 if (oal_unlikely(event_mem == HI_NULL)) {
224 oam_error_log0(mac_vap->vap_id, OAM_SF_SCAN, "{hmac_chan_sync::event_mem null.}");
225 return;
226 }
227
228 event = (frw_event_stru *)event_mem->puc_data;
229
230 /* 填写事件头 */
231 frw_event_hdr_init(&(event->event_hdr), FRW_EVENT_TYPE_WLAN_CTX, DMAC_WALN_CTX_EVENT_SUB_TYPR_SELECT_CHAN,
232 sizeof(dmac_set_chan_stru), FRW_EVENT_PIPELINE_STAGE_1, mac_vap->vap_id);
233 /* event->auc_event_data, 可变数组 */
234 if (memcpy_s(frw_get_event_payload(event_mem), sizeof(dmac_set_chan_stru), (hi_u8 *)set_chan,
235 sizeof(dmac_set_chan_stru)) != EOK) {
236 oam_error_log0(0, OAM_SF_CFG, "hmac_chan_do_sync::pst_set_chan memcpy_s fail.");
237 frw_event_free(event_mem);
238 return;
239 }
240
241 /* 分发事件 */
242 ret = hcc_hmac_tx_control_event(event_mem, sizeof(dmac_set_chan_stru));
243 if (ret != HI_SUCCESS) {
244 oam_warning_log1(mac_vap->vap_id, OAM_SF_SCAN, "{hmac_chan_sync::frw_event_dispatch_event failed[%d].}", ret);
245 frw_event_free(event_mem);
246 return;
247 }
248
249 /* 释放事件 */
250 frw_event_free(event_mem);
251 }
252
253 /* ****************************************************************************
254 功能描述 : HMAC将信道/带宽信息同步到DMAC
255 输入参数 : pst_mac_vap : MAC VAP结构体指针
256 uc_channel : 将要被设置的信道号
257 en_bandwidth: 将要被设置的带宽模式
258 en_switch_immediately: DMAC侧收到同步事件之后是否立即切换
259 修改历史 :
260 1.日 期 : 2014年2月26日
261 作 者 : HiSilicon
262 修改内容 : 新生成函数
263 **************************************************************************** */
hmac_chan_sync(mac_vap_stru * mac_vap,hi_u8 channel,wlan_channel_bandwidth_enum_uint8 bandwidth,hi_u8 switch_immediately)264 hi_void hmac_chan_sync(mac_vap_stru *mac_vap, hi_u8 channel, wlan_channel_bandwidth_enum_uint8 bandwidth,
265 hi_u8 switch_immediately)
266 {
267 dmac_set_chan_stru set_chan;
268
269 hmac_chan_sync_init(mac_vap, &set_chan);
270 set_chan.channel.chan_number = channel;
271 set_chan.channel.en_bandwidth = bandwidth;
272 set_chan.switch_immediately = switch_immediately;
273 hmac_chan_do_sync(mac_vap, &set_chan);
274 }
275
276 /* ****************************************************************************
277 功能描述 : 遍历device下所有VAP,设置SW/MAC/PHY/RF中的信道和带宽,使VAP工作在新信道上
278 输入参数 : pst_mac_vap : MAC VAP结构体指针
279 uc_channel : 将要被设置的信道号
280 en_bandwidth: 将要被设置的带宽模式
281 修改历史 :
282 1.日 期 : 2014年4月3日
283 作 者 : HiSilicon
284 修改内容 : 新生成函数
285 **************************************************************************** */
hmac_chan_multi_select_channel_mac(mac_vap_stru * mac_vap,hi_u8 channel,wlan_channel_bandwidth_enum_uint8 bandwidth)286 hi_void hmac_chan_multi_select_channel_mac(mac_vap_stru *mac_vap, hi_u8 channel,
287 wlan_channel_bandwidth_enum_uint8 bandwidth)
288 {
289 hi_u8 vap_idx;
290 mac_device_stru *mac_dev = HI_NULL;
291 mac_vap_stru *mac_vap_value = HI_NULL;
292
293 oam_warning_log2(mac_vap->vap_id, OAM_SF_2040,
294 "{hmac_chan_multi_select_channel_mac::uc_channel=%d,en_bandwidth=%d}", channel, bandwidth);
295
296 mac_dev = mac_res_get_dev();
297 if (mac_dev->vap_num == 0) {
298 oam_error_log0(mac_vap->vap_id, OAM_SF_2040, "{hmac_chan_multi_select_channel_mac::none vap.}");
299 return;
300 }
301
302 if (mac_is_dbac_running(mac_dev)) {
303 hmac_chan_sync(mac_vap, channel, bandwidth, HI_TRUE);
304 return;
305 }
306
307 /* 遍历device下所有vap, */
308 for (vap_idx = 0; vap_idx < mac_dev->vap_num; vap_idx++) {
309 mac_vap_value = mac_vap_get_vap_stru(mac_dev->auc_vap_id[vap_idx]);
310 if (mac_vap_value == HI_NULL) {
311 oam_error_log1(mac_vap->vap_id, OAM_SF_SCAN,
312 "{hmac_chan_multi_select_channel_mac::mac_vap_value null,vap_id=%d.}", mac_dev->auc_vap_id[vap_idx]);
313 continue;
314 }
315
316 hmac_chan_sync(mac_vap_value, channel, bandwidth, HI_TRUE);
317 }
318 }
319
320 /* ****************************************************************************
321 功能描述 : 控制硬件是否发送(数据帧、ACK、RTS)
322 输入参数 : pst_mac_vap: MAC VAP结构体指针
323 uc_sub_type: 事件子类型
324 修改历史 :
325 1.日 期 : 2014年7月17日
326 作 者 : HiSilicon
327 修改内容 : 新生成函数
328 **************************************************************************** */
hmac_chan_ctrl_machw_tx(const mac_vap_stru * mac_vap,hi_u8 sub_type)329 static hi_void hmac_chan_ctrl_machw_tx(const mac_vap_stru *mac_vap, hi_u8 sub_type)
330 {
331 frw_event_mem_stru *event_mem = HI_NULL;
332 frw_event_stru *event = HI_NULL;
333 hi_u32 ret;
334
335 /* 申请事件内存 */
336 event_mem = frw_event_alloc(0);
337 if (oal_unlikely(event_mem == HI_NULL)) {
338 oam_error_log0(mac_vap->vap_id, OAM_SF_SCAN, "{hmac_chan_ctrl_machw_tx::event_mem null.}");
339 return;
340 }
341
342 event = (frw_event_stru *)event_mem->puc_data;
343
344 /* 填写事件头 */
345 frw_event_hdr_init(&(event->event_hdr), FRW_EVENT_TYPE_WLAN_CTX, sub_type, 0, FRW_EVENT_PIPELINE_STAGE_1,
346 mac_vap->vap_id);
347
348 /* 分发事件 */
349 ret = hcc_hmac_tx_control_event(event_mem, 0);
350 if (ret != HI_SUCCESS) {
351 oam_warning_log1(mac_vap->vap_id, OAM_SF_SCAN,
352 "{hmac_chan_ctrl_machw_tx::frw_event_dispatch_event failed[%d].}", ret);
353 frw_event_free(event_mem);
354 return;
355 }
356
357 /* 释放事件 */
358 frw_event_free(event_mem);
359 }
360
361 /* ****************************************************************************
362 功能描述 : 禁止硬件发送(数据帧、ACK、RTS)
363 输入参数 : pst_mac_vap: MAC VAP结构体指针
364 修改历史 :
365 1.日 期 : 2014年3月13日
366 作 者 : HiSilicon
367 修改内容 : 新生成函数
368 **************************************************************************** */
hmac_chan_disable_machw_tx(const mac_vap_stru * mac_vap)369 hi_void hmac_chan_disable_machw_tx(const mac_vap_stru *mac_vap)
370 {
371 hmac_chan_ctrl_machw_tx(mac_vap, DMAC_WALN_CTX_EVENT_SUB_TYPR_DISABLE_TX);
372 }
373
374 /* ****************************************************************************
375 功能描述 : 在指定(可用)信道上启动BSS
376 输入参数 : pst_hmac_vap: HMAC VAP指针
377 返 回 值 : HI_SUCCESS或其它错误码
378 修改历史 :
379 1.日 期 : 2014年10月20日
380 作 者 : HiSilicon
381 修改内容 : 新生成函数
382 **************************************************************************** */
hmac_start_bss_in_available_channel(hmac_vap_stru * hmac_vap)383 hi_u32 hmac_start_bss_in_available_channel(hmac_vap_stru *hmac_vap)
384 {
385 hi_u32 ret;
386
387 /* 调用hmac_config_start_vap_event,启动BSS */
388 ret = hmac_config_start_vap_event(hmac_vap->base_vap, HI_TRUE);
389 if (oal_unlikely(ret != HI_SUCCESS)) {
390 hmac_fsm_change_state(hmac_vap, MAC_VAP_STATE_INIT);
391 oam_warning_log1(0, OAM_SF_SCAN,
392 "{hmac_start_bss_in_available_channel::hmac_config_send_event failed[%d].}", ret);
393 return ret;
394 }
395
396 /* 设置bssid */
397 mac_vap_set_bssid(hmac_vap->base_vap, hmac_vap->base_vap->mib_info->wlan_mib_sta_config.auc_dot11_station_id,
398 WLAN_MAC_ADDR_LEN);
399
400 /* 入网优化,不同频段下的能力不一样 */
401 if (hmac_vap->base_vap->channel.band == WLAN_BAND_2G) {
402 mac_mib_set_short_preamble_option_implemented(hmac_vap->base_vap, WLAN_LEGACY_11B_MIB_SHORT_PREAMBLE);
403 mac_mib_set_spectrum_management_required(hmac_vap->base_vap, HI_FALSE);
404 } else {
405 mac_mib_set_short_preamble_option_implemented(hmac_vap->base_vap, WLAN_LEGACY_11B_MIB_LONG_PREAMBLE);
406 mac_mib_set_spectrum_management_required(hmac_vap->base_vap, HI_TRUE);
407 }
408
409 /* 设置AP侧状态机为 UP */
410 hmac_fsm_change_state(hmac_vap, MAC_VAP_STATE_UP);
411 return HI_SUCCESS;
412 }
413
414 /* ****************************************************************************
415 功能描述 : 挑选一条信道(对),并启动BSS
416 输入参数 : pst_mac_vap: MAC VAP结构体指针
417 返 回 值 : HI_SUCCESS或其它错误码
418 修改历史 :
419 1.日 期 : 2014年6月3日
420 作 者 : HiSilicon
421 修改内容 : 新生成函数
422 **************************************************************************** */
hmac_chan_start_bss(hmac_vap_stru * hmac_vap)423 hi_u32 hmac_chan_start_bss(hmac_vap_stru *hmac_vap)
424 {
425 mac_device_stru *mac_dev = HI_NULL;
426 mac_vap_stru *mac_vap = hmac_vap->base_vap;
427 hi_u8 channel = 0;
428 wlan_channel_bandwidth_enum_uint8 bandwidth = WLAN_BAND_WIDTH_BUTT;
429 hi_u32 ret;
430
431 /* 设置bssid */
432 mac_vap_set_bssid(mac_vap, mac_vap->mib_info->wlan_mib_sta_config.auc_dot11_station_id, WLAN_MAC_ADDR_LEN);
433
434 /* 初始化AP速率集 */
435 mac_vap_init_rates(mac_vap);
436
437 /* 获取mac device指针 */
438 mac_dev = mac_res_get_dev();
439 /* 挑选一条信道(对) */
440 ret = mac_is_channel_num_valid(mac_vap->channel.band, channel);
441 if (ret != HI_SUCCESS) {
442 hmac_fsm_change_state(hmac_vap, MAC_VAP_STATE_INIT);
443 oam_warning_log1(mac_vap->vap_id, OAM_SF_SCAN, "{hmac_chan_start_bss::mac_is_channel_num_valid failed[%d].}", ret);
444 return ret;
445 }
446
447 oam_info_log2(mac_vap->vap_id, OAM_SF_SCAN,
448 "{hmac_chan_start_bss::AP: Starting network in Channel: %d, bandwidth: %d.}", channel, bandwidth);
449
450 /* 更新带宽模式 */
451 mac_vap->channel.en_bandwidth = bandwidth;
452
453 /* 设置信道号 */
454 #ifdef _PRE_WLAN_FEATURE_DBAC
455 /* 同时更改多个VAP的信道,此时需要强制清除记录 */
456 /* 若启动了DBAC,则按照原始流程进行 */
457 if (!mac_dev->dbac_enabled) {
458 mac_dev->max_channel = 0;
459 }
460 #else
461 mac_dev->max_channel = 0;
462 #endif
463
464 ret = hmac_config_set_freq(mac_vap, sizeof(hi_u32), &channel);
465 if (ret != HI_SUCCESS) {
466 oam_warning_log1(mac_vap->vap_id, OAM_SF_SCAN, "{hmac_chan_start_bss::hmac_config_set_freq failed[%d].}", ret);
467 return ret;
468 }
469
470 /* 设置带宽模式,直接抛事件到DMAC配置寄存器 */
471 ret = hmac_set_mode_event(mac_vap);
472 if (oal_unlikely(ret != HI_SUCCESS)) {
473 oam_warning_log1(mac_vap->vap_id, OAM_SF_CFG, "{hmac_chan_start_bss::hmac_config_send_event failed[%d].}", ret);
474 return ret;
475 }
476 /* 否则,直接启动BSS */
477 return hmac_start_bss_in_available_channel(hmac_vap);
478 }
479
480 /* ****************************************************************************
481 功能描述 : 切换信道后重启BSS
482 修改历史 :
483 1.日 期 : 2014年11月7日
484 作 者 : HiSilicon
485 修改内容 : 新生成函数
486 **************************************************************************** */
hmac_chan_restart_network_after_switch(const mac_vap_stru * mac_vap)487 hi_u32 hmac_chan_restart_network_after_switch(const mac_vap_stru *mac_vap)
488 {
489 frw_event_mem_stru *event_mem = HI_NULL;
490 frw_event_stru *event = HI_NULL;
491 hi_u32 ret;
492
493 /* 申请事件内存 */
494 event_mem = frw_event_alloc(0);
495 if (oal_unlikely(event_mem == HI_NULL)) {
496 oam_error_log0(mac_vap->vap_id, OAM_SF_SCAN, "{hmac_chan_restart_network_after_switch::event_mem null.}");
497
498 return HI_ERR_CODE_ALLOC_MEM_FAIL;
499 }
500
501 event = (frw_event_stru *)event_mem->puc_data;
502
503 /* 填写事件头 */
504 frw_event_hdr_init(&(event->event_hdr), FRW_EVENT_TYPE_WLAN_CTX, DMAC_WLAN_CTX_EVENT_SUB_TYPR_RESTART_NETWORK, 0,
505 FRW_EVENT_PIPELINE_STAGE_1, mac_vap->vap_id);
506
507 /* 分发事件 */
508 ret = hcc_hmac_tx_control_event(event_mem, 0);
509 if (ret != HI_SUCCESS) {
510 oam_error_log1(mac_vap->vap_id, OAM_SF_SCAN,
511 "{hmac_chan_restart_network_after_switch::frw_event_dispatch_event failed[%d].}", ret);
512 frw_event_free(event_mem);
513
514 return ret;
515 }
516 frw_event_free(event_mem);
517
518 return HI_SUCCESS;
519 }
520
521 /* ****************************************************************************
522 功能描述 : 处理信道/带宽切换完成事件
523 输入参数 :
524 修改历史 :
525 1.日 期 : 2014年5月8日
526 作 者 : HiSilicon
527 修改内容 : 新生成函数
528 **************************************************************************** */
hmac_chan_switch_to_new_chan_complete(frw_event_mem_stru * event_mem)529 hi_u32 hmac_chan_switch_to_new_chan_complete(frw_event_mem_stru *event_mem)
530 {
531 frw_event_stru *event = HI_NULL;
532 hmac_vap_stru *hmac_vap = HI_NULL;
533 mac_vap_stru *mac_vap = HI_NULL;
534 dmac_set_chan_stru *set_chan = HI_NULL;
535 hi_u32 ret;
536 hi_u8 idx;
537 hi_s32 l_freq = 0;
538 hi_unref_param(l_freq);
539
540 if (oal_unlikely(event_mem == HI_NULL)) {
541 oam_error_log0(0, OAM_SF_2040, "{hmac_switch_to_new_chan_complete::event_mem null.}");
542 return HI_ERR_CODE_PTR_NULL;
543 }
544
545 event = (frw_event_stru *)event_mem->puc_data;
546 set_chan = (dmac_set_chan_stru *)event->auc_event_data;
547 hmac_vap = hmac_vap_get_vap_stru(event->event_hdr.vap_id);
548 if (oal_unlikely(hmac_vap == HI_NULL)) {
549 oam_error_log0(event->event_hdr.vap_id, OAM_SF_2040, "{hmac_switch_to_new_chan_complete::pst_hmac_vap null.}");
550 return HI_ERR_CODE_PTR_NULL;
551 }
552
553 mac_vap = hmac_vap->base_vap;
554 ret = mac_get_channel_idx_from_num(mac_vap->channel.band, set_chan->channel.chan_number, &idx);
555 if (ret != HI_SUCCESS) {
556 oam_warning_log1(mac_vap->vap_id, OAM_SF_2040,
557 "{hmac_switch_to_new_chan_complete::mac_get_channel_idx_from_num failed[%d].}", ret);
558 return HI_FAIL;
559 }
560
561 mac_vap->channel.chan_number = set_chan->channel.chan_number;
562 mac_vap->channel.en_bandwidth = set_chan->channel.en_bandwidth;
563 mac_vap->channel.idx = idx;
564
565 mac_vap->ch_switch_info.waiting_to_shift_channel = set_chan->ch_switch_info.waiting_to_shift_channel;
566
567 mac_vap->ch_switch_info.ch_switch_status = set_chan->ch_switch_info.ch_switch_status;
568 mac_vap->ch_switch_info.bw_switch_status = set_chan->ch_switch_info.bw_switch_status;
569
570 l_freq = oal_ieee80211_channel_to_frequency(mac_vap->channel.chan_number, mac_vap->channel.band);
571 hi_unref_param(l_freq);
572
573 #if (_PRE_MULTI_CORE_MODE != _PRE_MULTI_CORE_MODE_OFFLOAD_DMAC)
574 /* 将信道切换信息上报到wpa_supplicant */
575 hmac_channel_switch_report_event(hmac_vap, l_freq);
576 #endif
577 return HI_SUCCESS;
578 }
579
580 /* ****************************************************************************
581 功能描述 : 处理dbac status event
582 输入参数 :
583 修改历史 :
584 1.日 期 : 2014年5月8日
585 作 者 : HiSilicon
586 修改内容 : 新生成函数
587 **************************************************************************** */
hmac_dbac_status_notify(frw_event_mem_stru * event_mem)588 hi_u32 hmac_dbac_status_notify(frw_event_mem_stru *event_mem)
589 {
590 #if (_PRE_MULTI_CORE_MODE_OFFLOAD_DMAC == _PRE_MULTI_CORE_MODE)
591 frw_event_stru *event = HI_NULL;
592 mac_device_stru *mac_dev = HI_NULL;
593 mac_vap_stru *mac_vap = HI_NULL;
594 hi_u8 vap_index = 0;
595
596 if (oal_unlikely(event_mem == HI_NULL)) {
597 oam_error_log0(0, OAM_SF_DBAC, "{hmac_dbac_status_notify::event_mem null.}");
598 return HI_ERR_CODE_PTR_NULL;
599 }
600
601 event = (frw_event_stru *)event_mem->puc_data;
602 mac_dev = mac_res_get_dev();
603 mac_dev->dbac_running = event->auc_event_data[0];
604 mac_dev->dbac_same_ch = event->auc_event_data[1];
605 oam_warning_log2(0, OAM_SF_DBAC, "{hmac_dbac_status_notify::sync dbac status, running[%d], same ch[%d].}",
606 mac_dev->dbac_running, mac_dev->dbac_same_ch);
607 /* 设置device下所有STA的KEEPALIVE */
608 for (; vap_index < mac_dev->vap_num; vap_index++) {
609 mac_vap = mac_vap_get_vap_stru(mac_dev->auc_vap_id[vap_index]);
610 if ((mac_vap != HI_NULL) && (is_sta(mac_vap))) {
611 /* 开启时关闭 keepalive,关闭时开启 */
612 mac_vap->cap_flag.keepalive = (mac_dev->dbac_running == HI_TRUE) ? HI_FALSE : HI_TRUE;
613 }
614 }
615 #else
616 hi_unref_param(event_mem);
617 #endif
618 return HI_SUCCESS;
619 }
620
621 /* ****************************************************************************
622 功能描述 : 处理(Extended) Channel Switch Announcement IE
623 输入参数 : pst_mac_vap: MAC VAP结构体指针
624 puc_payload: 指向(Extended) Channel Switch Announcement IE的指针
625 en_eid_type: Element ID
626 返 回 值 : HI_SUCCESS或其它错误码
627 修改历史 :
628 1.日 期 : 2014年3月12日
629 作 者 : HiSilicon
630 修改内容 : 新生成函数
631 2.日 期 : 2015年1月20日
632 作 者 : HiSilicon
633 修改内容 : 上移HMAC
634 **************************************************************************** */
hmac_ie_proc_ch_switch_ie(mac_vap_stru * mac_vap,const hi_u8 * puc_payload,mac_eid_enum_uint8 eid_type)635 hi_u32 hmac_ie_proc_ch_switch_ie(mac_vap_stru *mac_vap, const hi_u8 *puc_payload, mac_eid_enum_uint8 eid_type)
636 {
637 if (oal_unlikely((mac_vap == HI_NULL) || (puc_payload == HI_NULL))) {
638 oam_error_log0(0, OAM_SF_ANY, "{hmac_ie_proc_ch_switch_ie::param null.}");
639
640 return HI_ERR_CODE_PTR_NULL;
641 }
642
643 /* *********************************************************************** */
644 /* Channel Switch Announcement element */
645 /* --------------------------------------------------------------------- */
646 /* |Element ID|Length |Channel switch Mode|New Channel| Ch switch count| */
647 /* --------------------------------------------------------------------- */
648 /* |1 |1 |1 |1 |1 | */
649 /* --------------------------------------------------------------------- */
650 /* */
651 /* Extended Channel Switch Announcement element */
652 /* --------------------------------------------------------------------- */
653 /* |Elem ID|Length|Ch Switch Mode|New Reg Class|New Ch| Ch switch count| */
654 /* --------------------------------------------------------------------- */
655 /* |1 |1 |1 |1 |1 |1 | */
656 /* --------------------------------------------------------------------- */
657 /* */
658 /* *********************************************************************** */
659 /* Extended Channel Switch Announcement element */
660 hi_u8 ch_sw_mode = puc_payload[MAC_IE_HDR_LEN];
661 hi_u8 new_chan = puc_payload[MAC_IE_HDR_LEN + 1];
662 hi_u8 sw_cnt = puc_payload[MAC_IE_HDR_LEN + 2]; /* 2:偏移2 */
663
664 if (eid_type == MAC_EID_CHANSWITCHANN) {
665 if (puc_payload[1] < MAC_CHANSWITCHANN_IE_LEN) {
666 oam_warning_log1(0, 0, "{hmac_ie_proc_ch_switch_ie::invalid chan switch ann ie len[%d]}", puc_payload[1]);
667 return HI_FAIL;
668 }
669 } else if (eid_type == MAC_EID_EXTCHANSWITCHANN) {
670 if (puc_payload[1] < MAC_EXT_CHANSWITCHANN_IE_LEN) {
671 oam_warning_log1(0, 0, "{hmac_ie_proc_ch_switch_ie::invalid ExtChan switch ann ie len=%d}", puc_payload[1]);
672 return HI_FAIL;
673 }
674
675 /* Skip New Operating Class = puc_payload[MAC_IE_HDR_LEN + 1] */
676 new_chan = puc_payload[MAC_IE_HDR_LEN + 2]; /* 2:偏移2 */
677 sw_cnt = puc_payload[MAC_IE_HDR_LEN + 3]; /* 3:偏移3 */
678 } else {
679 return HI_FAIL;
680 }
681
682 /* 检查当前管制域是否支持该信道,如果不支持,则直接返回 */
683 hi_u32 check = mac_is_channel_num_valid(mac_vap->channel.band, new_chan);
684 if (check != HI_SUCCESS) {
685 oam_warning_log2(mac_vap->vap_id, OAM_SF_ANY,
686 "{hmac_ie_proc_ch_switch_ie::mac_is_channel_num_valid failed[%d], uc_new_chan=%d.}", check, new_chan);
687 return check;
688 }
689
690 /* 如果STA已经准备进行信道切换,则不做任何事情,直接返回 */
691 if (mac_vap->ch_switch_info.waiting_to_shift_channel == HI_TRUE) {
692 if (sw_cnt < mac_vap->ch_switch_info.ch_swt_cnt) {
693 return HI_SUCCESS;
694 }
695 } else if (ch_sw_mode == 1) { /* STA在信道切换完成前应该停止传输 */
696 hmac_chan_disable_machw_tx(mac_vap);
697 } /* 后无else */
698
699 mac_vap->ch_switch_info.new_channel = new_chan;
700 mac_vap->ch_switch_info.new_ch_swt_cnt = sw_cnt;
701 mac_vap->ch_switch_info.ch_swt_cnt = sw_cnt;
702 mac_vap->ch_switch_info.waiting_to_shift_channel = (hi_u8)HI_TRUE;
703
704 /* 如果"信道切换计数"等于0,则立即切换信道 */
705 if (mac_vap->ch_switch_info.new_ch_swt_cnt == 0) {
706 mac_vap->ch_switch_info.channel_swt_cnt_zero = (hi_u8)HI_TRUE;
707 }
708
709 #if (_PRE_MULTI_CORE_MODE_OFFLOAD_DMAC == _PRE_MULTI_CORE_MODE)
710 hmac_chan_sync(mac_vap, mac_vap->channel.chan_number, mac_vap->channel.en_bandwidth, HI_FALSE);
711 #endif
712
713 return HI_SUCCESS;
714 }
715
716 #if (_PRE_MULTI_CORE_MODE != _PRE_MULTI_CORE_MODE_OFFLOAD_DMAC)
717 /* ****************************************************************************
718 功能描述 : 将CSA切换信道的结果上报到WPA
719 **************************************************************************** */
hmac_channel_switch_report_event(const hmac_vap_stru * hmac_vap,hi_s32 l_freq)720 hi_void hmac_channel_switch_report_event(const hmac_vap_stru *hmac_vap, hi_s32 l_freq)
721 {
722 hmac_send_event_to_host(hmac_vap->base_vap, (const hi_u8 *)(&l_freq), sizeof(hi_s32),
723 HMAC_HOST_CTX_EVENT_SUB_TYPE_CHANNEL_SWITCH);
724 return;
725 }
726 #endif
727
728 #ifdef __cplusplus
729 #if __cplusplus
730 }
731 #endif
732 #endif
733