• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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