• 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 #include "mac_ie.h"
20 #include "mac_frame.h"
21 #include "mac_device.h"
22 #include "dmac_ext_if.h"
23 
24 #ifdef __cplusplus
25 #if __cplusplus
26 extern "C" {
27 #endif
28 #endif
29 
30 /* ****************************************************************************
31   函数实现
32 **************************************************************************** */
33 #define __WIFI_ROM_SECTION__ /* 代码ROM段起始位置 */
34 
35 /* ****************************************************************************
36  功能描述  : 设置VAP mib值
37  输入参数  : [1]mac_vap
38              [2]us_len
39              [3]puc_param
40  返 回 值  : 无
41 **************************************************************************** */
mac_config_set_mib(const mac_vap_stru * mac_vap,hi_u16 us_len,const hi_u8 * puc_param)42 WIFI_ROM_TEXT hi_u32 mac_config_set_mib(const mac_vap_stru *mac_vap, hi_u16 us_len, const hi_u8 *puc_param)
43 {
44     mac_cfg_set_mib_stru *set_mib = (mac_cfg_set_mib_stru *)puc_param;
45 
46     hi_unref_param(us_len);
47 
48     if (set_mib->mib_idx == WLAN_MIB_INDEX_SPEC_MGMT_IMPLEMENT) {
49         mac_mib_set_spectrum_management_implemented(mac_vap, (hi_u8)(set_mib->mib_value));
50     } else if (set_mib->mib_idx == WLAN_MIB_INDEX_FORTY_MHZ_OPERN_IMPLEMENT) {
51         mac_mib_set_forty_mhz_operation_implemented(mac_vap, (hi_u8)(set_mib->mib_value));
52     } else if (set_mib->mib_idx == WLAN_MIB_INDEX_2040_COEXT_MGMT_SUPPORT) {
53         mac_mib_set_2040bss_coexistence_management_support(mac_vap, (hi_u8)(set_mib->mib_value));
54     } else if (set_mib->mib_idx == WLAN_MIB_INDEX_FORTY_MHZ_INTOL) {
55         mac_mib_set_forty_mhz_intolerant(mac_vap, (hi_u8)(set_mib->mib_value));
56     } else if (set_mib->mib_idx == WLAN_MIB_INDEX_OBSSSCAN_TRIGGER_INTERVAL) {
57         mac_mib_set_bsswidth_trigger_scan_interval(mac_vap, set_mib->mib_value);
58     } else if (set_mib->mib_idx == WLAN_MIB_INDEX_OBSSSCAN_TRANSITION_DELAY_FACTOR) {
59         mac_mib_set_bsswidth_channel_transition_delay_factor(mac_vap, set_mib->mib_value);
60     } else if (set_mib->mib_idx == WLAN_MIB_INDEX_OBSSSCAN_PASSIVE_DWELL) {
61         mac_mib_set_obssscan_passive_dwell(mac_vap, set_mib->mib_value);
62     } else if (set_mib->mib_idx == WLAN_MIB_INDEX_OBSSSCAN_ACTIVE_DWELL) {
63         mac_mib_set_obssscan_active_dwell(mac_vap, set_mib->mib_value);
64     } else if (set_mib->mib_idx == WLAN_MIB_INDEX_OBSSSCAN_PASSIVE_TOTAL_PER_CHANNEL) {
65         mac_mib_set_obssscan_passive_total_per_channel(mac_vap, set_mib->mib_value);
66     } else if (set_mib->mib_idx == WLAN_MIB_INDEX_OBSSSCAN_ACTIVE_TOTAL_PER_CHANNEL) {
67         mac_mib_set_obssscan_active_total_per_channel(mac_vap, set_mib->mib_value);
68     } else if (set_mib->mib_idx == WLAN_MIB_INDEX_OBSSSCAN_ACTIVITY_THRESHOLD) {
69         mac_mib_set_obssscan_activity_threshold(mac_vap, set_mib->mib_value);
70 #ifdef _PRE_WLAN_FEATURE_MESH_ROM
71     } else if (set_mib->mib_idx == WLAN_MIB_INDEX_MESH_ACCEPTING_PEER) {
72         mac_mib_set_accepting_peer(mac_vap, (hi_u8)set_mib->mib_value);
73     } else if (set_mib->mib_idx == WLAN_MIB_INDEX_MESH_SECURITY_ACTIVATED) {
74         mac_mib_set_mesh_security(mac_vap, (hi_u8)set_mib->mib_value);
75 #endif
76     } else {
77         oam_error_log1(mac_vap->vap_id, OAM_SF_CFG, "{hmac_config_set_mib::invalid ul_mib_idx[%d].}",
78             set_mib->mib_idx);
79     }
80 
81     return HI_SUCCESS;
82 }
83 
84 /* ****************************************************************************
85  功能描述  : 处理HT Operation IE
86  输入参数  : pst_mac_vap : MAC VAP结构体指针,指向STA
87              puc_payload : 指向HT Operation IE的指针
88              pst_mac_user: MAC VAP结构体指针,指向AP
89  修改历史      :
90   1.日    期   : 2014年3月3日
91     作    者   : HiSilicon
92     修改内容   : 新生成函数
93 **************************************************************************** */
mac_proc_ht_opern_ie(mac_vap_stru * mac_vap,const hi_u8 * puc_payload,mac_user_stru * mac_user)94 WIFI_ROM_TEXT hi_u32 mac_proc_ht_opern_ie(mac_vap_stru *mac_vap, const hi_u8 *puc_payload, mac_user_stru *mac_user)
95 {
96     mac_ht_opern_stru *ht_opern = HI_NULL;
97     mac_user_ht_hdl_stru ht_hdl;
98     wlan_bw_cap_enum_uint8 bwcap_vap;
99     const hi_u32 change = MAC_NO_CHANGE;
100 
101     if (oal_unlikely((mac_vap == HI_NULL) || (puc_payload == HI_NULL) || (mac_user == HI_NULL))) {
102         oam_error_log0(0, OAM_SF_ANY, "{hmac_ie_proc_ht_opern_ie::param null.}");
103         return change;
104     }
105 
106     if (puc_payload[1] < 6) { /* 长度校验,此处仅用到前6字节,后面Basic MCS Set未涉及 */
107         oam_warning_log1(0, OAM_SF_ANY, "{mac_proc_ht_opern_ie::invalid ht opern ie len[%d].}", puc_payload[1]);
108         return change;
109     }
110     mac_user_get_ht_hdl(mac_user, &ht_hdl);
111 
112     /* *********************** HT Operation Element *************************************
113       ----------------------------------------------------------------------
114       |EID |Length |PrimaryChannel |HT Operation Information |Basic MCS Set|
115       ----------------------------------------------------------------------
116       |1   |1      |1              |5                        |16           |
117       ----------------------------------------------------------------------
118     ************************************************************************** */
119     /* *********************** HT Information Field ****************************
120      |--------------------------------------------------------------------|
121      | Primary | Seconday  | STA Ch | RIFS |           reserved           |
122      | Channel | Ch Offset | Width  | Mode |                              |
123      |--------------------------------------------------------------------|
124      |    1    | B0     B1 |   B2   |  B3  |    B4                     B7 |
125      |--------------------------------------------------------------------|
126 
127      |----------------------------------------------------------------|
128      |     HT     | Non-GF STAs | resv      | OBSS Non-HT  | Reserved |
129      | Protection |   Present   |           | STAs Present |          |
130      |----------------------------------------------------------------|
131      | B0     B1  |     B2      |    B3     |     B4       | B5   B15 |
132      |----------------------------------------------------------------|
133 
134      |-------------------------------------------------------------|
135      | Reserved |  Dual  |  Dual CTS  | Seconday | LSIG TXOP Protn |
136      |          | Beacon | Protection |  Beacon  | Full Support    |
137      |-------------------------------------------------------------|
138      | B0    B5 |   B6   |     B7     |     B8   |       B9        |
139      |-------------------------------------------------------------|
140 
141      |---------------------------------------|
142      |  PCO   |  PCO  | Reserved | Basic MCS |
143      | Active | Phase |          |    Set    |
144      |---------------------------------------|
145      |  B10   |  B11  | B12  B15 |    16     |
146      |---------------------------------------|
147     ************************************************************************* */
148     ht_opern = (mac_ht_opern_stru *)(&puc_payload[MAC_IE_HDR_LEN]);
149 
150     /* 提取HT Operation IE中的"STA Channel Width" */
151     mac_user_set_bandwidth_info(mac_user, ht_opern->sta_chan_width, mac_user->cur_bandwidth);
152 
153     /* 提取HT Operation IE中的"Secondary Channel Offset" */
154     ht_hdl.secondary_chan_offset = ht_opern->secondary_chan_offset;
155 
156     /* 为了防止5G下用户声称20M,但发送80M数据的情况,在5G情况下该变量不切换 */
157     if ((mac_user->avail_bandwidth == 0) && (mac_vap->channel.band == WLAN_BAND_2G)) {
158         ht_hdl.secondary_chan_offset = MAC_SCN;
159     }
160 
161     /* 用户与VAP带宽能力取交集 */
162     mac_vap_get_bandwidth_cap(mac_vap, &bwcap_vap);
163     bwcap_vap = oal_min(mac_user->bandwidth_cap, bwcap_vap);
164     bwcap_vap = oal_min(mac_user->avail_bandwidth, bwcap_vap);
165     mac_user_set_bandwidth_info(mac_user, bwcap_vap, bwcap_vap);
166 
167     /* 保护相关 */
168     ht_hdl.rifs_mode = ht_opern->rifs_mode; /* 发送描述符填写时候需要此值 */
169     ht_hdl.ht_protection = ht_opern->ht_protection;
170     ht_hdl.nongf_sta_present = ht_opern->nongf_sta_present;
171     ht_hdl.obss_nonht_sta_present = ht_opern->obss_nonht_sta_present;
172     ht_hdl.lsig_txop_protection_full_support = ht_opern->lsig_txop_protection_full_support;
173 
174     mac_user_set_ht_hdl(mac_user, &ht_hdl);
175 
176     return change;
177 }
178 
179 /* ****************************************************************************
180  功能描述  : 构建从20M信道偏移IE
181  修改历史      :
182   1.日    期   : 2013年12月5日
183     作    者   : HiSilicon
184     修改内容   : 新生成函数
185 **************************************************************************** */
mac_set_second_channel_offset_ie(wlan_channel_bandwidth_enum_uint8 bw,hi_u8 * pauc_buffer,hi_u8 * puc_output_len)186 WIFI_ROM_TEXT hi_u32 mac_set_second_channel_offset_ie(wlan_channel_bandwidth_enum_uint8 bw, hi_u8 *pauc_buffer,
187     hi_u8 *puc_output_len)
188 {
189     /* 默认输出为空 */
190     *pauc_buffer    = '\0';
191     *puc_output_len = 0;
192 
193     /* 11n 设置Secondary Channel Offset Element */
194     /* **************************************************************** */
195     /* -------------------------------------------------------------- */
196     /* |Ele. ID |Length |Secondary channel offset |                   */
197     /* -------------------------------------------------------------- */
198     /* |1       |1      |1                        |                   */
199     /*                                                                */
200     /* **************************************************************** */
201     pauc_buffer[0] = 62; /* 固定设置为62 */
202     pauc_buffer[1] = 1;
203     switch (bw) {
204         case WLAN_BAND_WIDTH_20M:
205             pauc_buffer[2] = 0; /* no secondary channel(pauc_buffer[2]) */
206             break;
207         case WLAN_BAND_WIDTH_5M:
208             pauc_buffer[2] = MAC_BW_5M; /* pauc_buffer[2] : 自定义,窄带5M */
209             break;
210         case WLAN_BAND_WIDTH_10M:
211             pauc_buffer[2] = MAC_BW_10M; /* pauc_buffer[2] : 自定义,窄带10M */
212             break;
213         default:
214             oam_error_log1(0, OAM_SF_SCAN, "{mac_set_second_channel_offset_ie::invalid bandwidth[%d].}", bw);
215             return HI_FAIL;
216     }
217     *puc_output_len = 3; /* output_len固定赋值为3 */
218     return HI_SUCCESS;
219 }
220 
221 /* 代码ROM段结束位置 新增ROM代码请放在SECTION中 */
222 #undef __WIFI_ROM_SECTION__
223 
224 /* ****************************************************************************
225  功能描述  : 处理ht cap ie中的 supported channel width
226  输入参数  : pst_mac_user_sta           : user结构体指针
227              pst_mac_vap                : vap结构体指针
228              uc_supported_channel_width : 是否支持40Mhz带宽  0: 不支持, 1: 支持
229              en_prev_asoc_ht            : user之前是否已ht站点身份关联到ap  0: 之前未关联, 1: 之前关联过
230  返 回 值  :用户中共享区域的st_ht_hdl.bit_supported_channel_width信息
231  修改历史      :
232   1.日    期   : 2014年1月18日
233     作    者   : HiSilicon
234     修改内容   : 新生成函数
235 **************************************************************************** */
mac_ie_proc_ht_supported_channel_width(const mac_user_stru * mac_user_sta,mac_vap_stru * mac_vap,hi_u8 supported_channel_width,hi_bool prev_asoc_ht)236 hi_u8 mac_ie_proc_ht_supported_channel_width(const mac_user_stru *mac_user_sta, mac_vap_stru *mac_vap,
237     hi_u8 supported_channel_width, hi_bool prev_asoc_ht)
238 {
239     /* 不支持20/40Mhz频宽 */
240     if (supported_channel_width == 0) {
241         /*  如果STA之前没有作为HT站点与AP关联, 或者STA之前已经作为支持20/40Mhz频宽的HT站点与AP关联 */
242         if ((prev_asoc_ht == HI_FALSE) || (mac_user_sta->ht_hdl.ht_capinfo.supported_channel_width == HI_TRUE)) {
243             mac_vap->protection.sta_20_m_only_num++;
244         }
245         return HI_FALSE;
246     } else { /* 支持20/40Mhz频宽 */
247         /*  如果STA之前已经作为不支持20/40Mhz频宽的HT站点与AP关联 */
248         if ((prev_asoc_ht == HI_TRUE) && (mac_user_sta->ht_hdl.ht_capinfo.supported_channel_width == HI_FALSE)) {
249             mac_vap->protection.sta_20_m_only_num--;
250         }
251         return HI_TRUE;
252     }
253 }
254 
255 /* ****************************************************************************
256  功能描述  : 处理ht cap ie中的 ht green field  BIT4
257  输入参数  : pst_mac_user_sta  : user结构体指针
258              pst_mac_vap       : vap结构体指针
259              uc_ht_green_field : 是否支持gf, 0: 不支持, 1: 支持
260              en_prev_asoc_ht   : user之前是否已ht站点身份关联到ap  0: 之前未关联, 1: 之前关联过
261  返 回 值  :用户公共区域的st_ht_hdl.bit_ht_green_field信息
262  修改历史      :
263   1.日    期   : 2013年12月12日
264     作    者   : HiSilicon
265     修改内容   : 新生成函数
266 **************************************************************************** */
mac_ie_proc_ht_green_field(const mac_user_stru * mac_user_sta,mac_vap_stru * mac_vap,hi_u8 ht_green_field,hi_bool prev_asoc_ht)267 hi_u8 mac_ie_proc_ht_green_field(const mac_user_stru *mac_user_sta, mac_vap_stru *mac_vap, hi_u8 ht_green_field,
268     hi_bool prev_asoc_ht)
269 {
270     /* 不支持Greenfield */
271     if (ht_green_field == 0) {
272         /*  如果STA之前没有作为HT站点与AP关联, 或者STA之前已经作为支持GF的HT站点与AP关联 */
273         if ((prev_asoc_ht == HI_FALSE) || (mac_user_sta->ht_hdl.ht_capinfo.ht_green_field == HI_TRUE)) {
274             mac_vap->protection.sta_non_gf_num++;
275         }
276         return HI_FALSE;
277     } else { /* 支持Greenfield */
278         /*  如果STA之前已经作为不支持GF的HT站点与AP关联 */
279         if ((prev_asoc_ht == HI_TRUE) && (mac_user_sta->ht_hdl.ht_capinfo.ht_green_field == HI_FALSE)) {
280             mac_vap->protection.sta_non_gf_num--;
281         }
282         return HI_TRUE;
283     }
284 }
285 
286 /* ****************************************************************************
287  函 数 名  : mac_ie_proc_lsig_txop_protection_support
288  功能描述  : 处理ht cap ie中的 lsig_txop_protection_support
289  输入参数  : pst_mac_user_sta                : user结构体指针
290              pst_mac_vap                     : vap结构体指针
291              uc_lsig_txop_protection_support : 是否支持lsig txop保护, 0: 不支持, 1: 支持
292              en_prev_asoc_ht                 : user之前是否已ht站点身份关联到ap  0: 之前未关联, 1: 之前关联过
293  返 回 值  :用户公共区域的st_ht_hdl.bit_lsig_txop_protection信息
294  修改历史      :
295   1.日    期   : 2014年1月18日
296     作    者   : HiSilicon
297     修改内容   : 新生成函数
298 **************************************************************************** */
mac_ie_proc_lsig_txop_protection_support(const mac_user_stru * mac_user_sta,mac_vap_stru * mac_vap,hi_u8 lsig_txop_protection_support,hi_bool prev_asoc_ht)299 hi_u8 mac_ie_proc_lsig_txop_protection_support(const mac_user_stru *mac_user_sta, mac_vap_stru *mac_vap,
300     hi_u8 lsig_txop_protection_support, hi_bool prev_asoc_ht)
301 {
302     /* 不支持L-sig txop protection */
303     if (lsig_txop_protection_support == 0) {
304         /*  如果STA之前没有作为HT站点与AP关联, 或者STA之前已经作为支持Lsig txop protection的HT站点与AP关联 */
305         if ((prev_asoc_ht == HI_FALSE) || (mac_user_sta->ht_hdl.ht_capinfo.lsig_txop_protection == HI_TRUE)) {
306             mac_vap->protection.sta_no_lsig_txop_num++;
307         }
308         return HI_FALSE;
309     } else { /* 支持L-sig txop protection */
310         /*  如果STA之前已经作为不支持Lsig txop protection的HT站点与AP关联 */
311         if ((prev_asoc_ht == HI_TRUE) && (mac_user_sta->ht_hdl.ht_capinfo.lsig_txop_protection == HI_FALSE)) {
312             mac_vap->protection.sta_no_lsig_txop_num--;
313         }
314         return HI_TRUE;
315     }
316 }
317 
318 /* ****************************************************************************
319  * 函 数 名  :   mac_ie_txbf_set_ht_hdl
320  * 功能描述  : 设置txbf feild结构体
321  * 输入参数  :
322  * 输出参数  :
323  * 返 回 值  : hi_void
324  * *************************************************************************** */
mac_ie_txbf_set_ht_hdl(mac_user_ht_hdl_stru * ht_hdl,hi_u32 info_elem)325 hi_void mac_ie_txbf_set_ht_hdl(mac_user_ht_hdl_stru *ht_hdl, hi_u32 info_elem)
326 {
327     hi_u32 tmp_txbf_elem = info_elem;
328 
329     ht_hdl->imbf_receive_cap                = (tmp_txbf_elem & BIT0);
330     ht_hdl->receive_staggered_sounding_cap  = ((tmp_txbf_elem & BIT1) >> 1);
331     ht_hdl->transmit_staggered_sounding_cap = ((tmp_txbf_elem & BIT2) >> 2); /* 右移2 bit获取transmit sounding_cap */
332     ht_hdl->receive_ndp_cap                 = ((tmp_txbf_elem & BIT3) >> 3); /* 右移3 bit获取receive_ndp_cap */
333     ht_hdl->transmit_ndp_cap                = ((tmp_txbf_elem & BIT4) >> 4); /* 右移4 bit获取transmit_ndp_cap */
334     ht_hdl->imbf_cap                        = ((tmp_txbf_elem & BIT5) >> 5); /* 右移5 bit获取imbf_cap */
335     ht_hdl->calibration                     = ((tmp_txbf_elem & 0x000000C0) >> 6);  /* 右移6 bit获取calibration */
336     ht_hdl->exp_csi_txbf_cap                = ((tmp_txbf_elem & BIT8) >> 8);   /* 右移8 bit获取exp_csi_txbf_cap */
337     ht_hdl->exp_noncomp_txbf_cap            = ((tmp_txbf_elem & BIT9) >> 9);   /* 右移9 bit获取exp_noncomp_txbf_cap */
338     ht_hdl->exp_comp_txbf_cap               = ((tmp_txbf_elem & BIT10) >> 10); /* 右移10 bit获取exp_comp_txbf_cap */
339     ht_hdl->exp_csi_feedback                = ((tmp_txbf_elem & 0x00001800) >> 11); /* 右移11 bit获取exp_csi_feedback */
340     ht_hdl->exp_noncomp_feedback            = ((tmp_txbf_elem & 0x00006000) >> 13); /* 右移13 bit获取noncomp_feedback */
341 
342     ht_hdl->exp_comp_feedback               = ((tmp_txbf_elem & 0x0001C000) >> 15); /* 右移15 bit获取comp_feedback */
343     ht_hdl->min_grouping                    = ((tmp_txbf_elem & 0x00060000) >> 17); /* 右移17 bit获取min_grouping */
344     ht_hdl->csi_bfer_ant_number             = ((tmp_txbf_elem & 0x001C0000) >> 19); /* 右移19 bit获取bfer_ant_number */
345     ht_hdl->noncomp_bfer_ant_number         = ((tmp_txbf_elem & 0x00600000) >> 21); /* 右移21 bit获取bfer_ant_number */
346     ht_hdl->comp_bfer_ant_number            = ((tmp_txbf_elem & 0x01C00000) >> 23); /* 右移23 bit获取bfer_ant_number */
347     ht_hdl->csi_bfee_max_rows               = ((tmp_txbf_elem & 0x06000000) >> 25); /* 右移25 bit获取bfee_max_rows */
348     ht_hdl->channel_est_cap                 = ((tmp_txbf_elem & 0x18000000) >> 27); /* 右移27 bit获取channel_est_cap */
349 }
350 
351 /* ****************************************************************************
352  功能描述  : 搜索asoc rsp frame帧中的HT cap IE
353  修改历史      :
354   1.日    期   : 2013年7月10日
355     作    者   : HiSilicon
356     修改内容   : 新生成函数
357 **************************************************************************** */
mac_ie_proc_ht_sta(const mac_vap_stru * mac_vap,const hi_u8 * puc_payload,const hi_u16 * pus_index,mac_user_stru * mac_user_ap,hi_u16 * pus_ht_cap_info,hi_u16 * pus_amsdu_max)358 hi_void mac_ie_proc_ht_sta(const mac_vap_stru *mac_vap, const hi_u8 *puc_payload, const hi_u16 *pus_index,
359     mac_user_stru *mac_user_ap, hi_u16 *pus_ht_cap_info, hi_u16 *pus_amsdu_max)
360 {
361     hi_u16                us_offset = *pus_index;
362     mac_user_stru        *mac_user = mac_user_ap;
363     mac_user_ht_hdl_stru  ht_hdl_value;
364     mac_user_ht_hdl_stru *ht_hdl = &ht_hdl_value;
365     hi_u8 mcs_bmp_index;
366 
367     mac_user_get_ht_hdl(mac_user, ht_hdl);
368     /* 带有 HT Capability Element 的 AP,标示它具有HT capable. */
369     ht_hdl->ht_capable = HI_TRUE;
370     us_offset += MAC_IE_HDR_LEN;
371     /* ****************************************** */
372     /*     解析 HT Capabilities Info Field      */
373     /* ****************************************** */
374     *pus_ht_cap_info = hi_makeu16(puc_payload[us_offset], puc_payload[us_offset + 1]);
375     /* 检查STA所支持的LDPC编码能力 B0,0:不支持,1:支持 */
376     ht_hdl->ht_capinfo.ldpc_coding_cap = (*pus_ht_cap_info & BIT0);
377     /* 提取AP所支持的带宽能力  */
378     ht_hdl->ht_capinfo.supported_channel_width = ((*pus_ht_cap_info & BIT1) >> 1);
379     /* 检查空间复用节能模式 B2~B3 */
380     hi_u8 smps = (*pus_ht_cap_info & (BIT2 | BIT3));
381     ht_hdl->ht_capinfo.sm_power_save = mac_ie_proc_sm_power_save_field(smps);
382 
383     ht_hdl->ht_capinfo.ht_green_field = ((*pus_ht_cap_info & BIT4) >> 4); /* 提取AP支持Greenfield情况,右移4bit */
384 
385     ht_hdl->ht_capinfo.short_gi_20mhz = ((*pus_ht_cap_info & BIT5) >> 5); /* 提取AP支持20MHz Short-GI情况,右移5bit */
386 
387     ht_hdl->ht_capinfo.short_gi_40mhz = ((*pus_ht_cap_info & BIT6) >> 6); /* 提取AP支持40MHz Short-GI情况,右移6bit */
388 
389     ht_hdl->ht_capinfo.rx_stbc = (hi_u8)((*pus_ht_cap_info & 0x30) >> 4); /* 提取AP支持STBC PPDU情况,右移4bit */
390     /* 提取AP支持最大A-MSDU长度情况 */
391     *pus_amsdu_max =
392         ((*pus_ht_cap_info & BIT11) == 0) ? WLAN_MIB_MAX_AMSDU_LENGTH_SHORT : WLAN_MIB_MAX_AMSDU_LENGTH_LONG;
393 
394     ht_hdl->ht_capinfo.dsss_cck_mode_40mhz = ((*pus_ht_cap_info & BIT12) >> 12); /* 12:提取40M上DSSS/CCK的支持情况 */
395 
396     ht_hdl->ht_capinfo.lsig_txop_protection = ((*pus_ht_cap_info & BIT15) >> 15); /* 15:提取L-SIG TXOP 保护的支持情况 */
397     us_offset += MAC_HT_CAPINFO_LEN;
398 
399     /* ****************************************** */
400     /*     解析 A-MPDU Parameters Field         */
401     /* ****************************************** */
402     /* 提取 Maximum Rx A-MPDU factor (B1 - B0) */
403     ht_hdl->max_rx_ampdu_factor = (puc_payload[us_offset] & 0x03);
404 
405     ht_hdl->min_mpdu_start_spacing = (puc_payload[us_offset] >> 2) & 0x07; /* 提取 Minmum Rx A-MPDU factor (B3 - B2) */
406     us_offset += MAC_HT_AMPDU_PARAMS_LEN;
407 
408     /* ****************************************** */
409     /*     解析 Supported MCS Set Field         */
410     /* ****************************************** */
411     for (mcs_bmp_index = 0; mcs_bmp_index < WLAN_HT_MCS_BITMASK_LEN; mcs_bmp_index++) {
412         ht_hdl->rx_mcs_bitmask[mcs_bmp_index] =
413             (mac_vap->mib_info->supported_mcstx.auc_dot11_supported_mcs_tx_value[mcs_bmp_index]) &
414             (*(hi_u8 *)(puc_payload + us_offset + mcs_bmp_index));
415     }
416     ht_hdl->rx_mcs_bitmask[WLAN_HT_MCS_BITMASK_LEN - 1] &= 0x1F;
417     us_offset += MAC_HT_SUP_MCS_SET_LEN;
418 
419     /* ****************************************** */
420     /* 解析 HT Extended Capabilities Info Field */
421     /* ****************************************** */
422     *pus_ht_cap_info = hi_makeu16(puc_payload[us_offset], puc_payload[us_offset + 1]);
423     /* 提取 HTC support Information */
424     if ((*pus_ht_cap_info & BIT10) != 0) {
425         ht_hdl->htc_support = 1;
426     }
427     us_offset += MAC_HT_EXT_CAP_LEN;
428 
429     /* ****************************************** */
430     /*  解析 Tx Beamforming Field               */
431     /* ****************************************** */
432     hi_u16 us_tmp_info_elem = hi_makeu16(puc_payload[us_offset], puc_payload[us_offset + 1]);
433     hi_u16 us_tmp_txbf_low  = hi_makeu16(puc_payload[us_offset + 2], puc_payload[us_offset + 3]); /* 2/3:偏移 */
434     hi_u32 tmp_txbf_elem    = hi_makeu32(us_tmp_info_elem, us_tmp_txbf_low);
435 
436     mac_ie_txbf_set_ht_hdl(ht_hdl, tmp_txbf_elem);
437 
438     mac_user_set_ht_hdl(mac_user, ht_hdl);
439 }
440 
441 /* ****************************************************************************
442  功能描述  : 检查action帧是不是p2p帧
443  修改历史      :
444   1.日    期   : 2014年12月30日
445     作    者   : HiSilicon
446     修改内容   : 新生成函数
447 **************************************************************************** */
mac_ie_check_p2p_action(const hi_u8 * puc_payload)448 hi_u8 mac_ie_check_p2p_action(const hi_u8 *puc_payload)
449 {
450     /* 找到WFA OUI */
451     hi_u8 auc_oui[MAC_OUI_LEN] = {(hi_u8)MAC_WLAN_OUI_P2P0, (hi_u8)MAC_WLAN_OUI_P2P1, (hi_u8)MAC_WLAN_OUI_P2P2};
452 
453     if ((memcmp(puc_payload, auc_oui, MAC_OUI_LEN) == 0) && (puc_payload[MAC_OUI_LEN] == MAC_OUITYPE_P2P)) {
454         return HI_TRUE;
455     }
456     return HI_FALSE;
457 }
458 
459 /* ****************************************************************************
460  功能描述  : 更新ht cap ie中的 sm power save field B2~B3
461  输入参数  : pst_mac_user_sta --用户结构体指针,uc_smps--用户smps模式
462  返 回 值  : 用户信息中st_ht_hdl.bit_sm_power_save的信息
463  修改历史      :
464   1.日    期   : 2013年12月12日
465     作    者   : HiSilicon
466     修改内容   : 新生成函数
467 **************************************************************************** */
mac_ie_proc_sm_power_save_field(hi_u8 smps)468 wlan_mib_mimo_power_save_enum_uint8 mac_ie_proc_sm_power_save_field(hi_u8 smps)
469 {
470     if (smps == MAC_SMPS_STATIC_MODE) {
471         return WLAN_MIB_MIMO_POWER_SAVE_STATIC;
472     } else if (smps == MAC_SMPS_DYNAMIC_MODE) {
473         return WLAN_MIB_MIMO_POWER_SAVE_DYNAMIC;
474     } else {
475         return WLAN_MIB_MIMO_POWER_SAVE_MIMO;
476     }
477 }
478 
479 /* ****************************************************************************
480  功能描述  : 从帧体中解析ie中的chan信息,先在HT operation IE中找chan信息,如果找到就返回,如找不到,
481              再在DSSS Param set ie中寻找
482  修改历史      :
483   1.日    期   : 2014年2月19日
484     作    者   : HiSilicon
485     修改内容   : 新生成函数
486 **************************************************************************** */
mac_ie_get_chan_num(hi_u8 * puc_frame_body,hi_u16 us_frame_len,hi_u16 us_offset,hi_u8 curr_chan)487 hi_u8 mac_ie_get_chan_num(hi_u8 *puc_frame_body, hi_u16 us_frame_len, hi_u16 us_offset, hi_u8 curr_chan)
488 {
489     hi_u8 chan_num;
490     hi_u8 *puc_ie_start_addr = HI_NULL;
491 
492     if (us_frame_len > us_offset) {
493         /* 在DSSS Param set ie中解析chan num */
494         puc_ie_start_addr = mac_find_ie(MAC_EID_DSPARMS, puc_frame_body + us_offset, us_frame_len - us_offset);
495         if ((puc_ie_start_addr != HI_NULL) && (puc_ie_start_addr[1] == MAC_DSPARMS_LEN)) {
496             chan_num = puc_ie_start_addr[2]; /* 从ie_start_addr第2 byte获取信道数 */
497             if (mac_is_channel_num_valid(mac_get_band_by_channel_num(chan_num), chan_num) == HI_SUCCESS) {
498                 return chan_num;
499             }
500         }
501         /* 在HT operation ie中解析 chan num */
502         puc_ie_start_addr = mac_find_ie(MAC_EID_HT_OPERATION, puc_frame_body + us_offset, us_frame_len - us_offset);
503         if ((puc_ie_start_addr != HI_NULL) && (puc_ie_start_addr[1] >= 1)) {
504             chan_num = puc_ie_start_addr[2]; /* 从ie_start_addr第2 byte获取信道数 */
505             if (mac_is_channel_num_valid(mac_get_band_by_channel_num(chan_num), chan_num) == HI_SUCCESS) {
506                 return chan_num;
507             }
508         }
509     }
510     chan_num = curr_chan;
511     return chan_num;
512 }
513 
514 /* ****************************************************************************
515  功能描述  : 根据"带宽模式"获取对应的"次信道偏移量"
516  输入参数  : en_bandwidth: 带宽模式
517  返 回 值  : 次信道偏移量
518 **************************************************************************** */
mac_get_sco_from_bandwidth(wlan_channel_bandwidth_enum_uint8 bandwidth)519 WIFI_ROM_TEXT mac_sec_ch_off_enum_uint8 mac_get_sco_from_bandwidth(wlan_channel_bandwidth_enum_uint8 bandwidth)
520 {
521     switch (bandwidth) {
522         case WLAN_BAND_WIDTH_40PLUS:
523         case WLAN_BAND_WIDTH_80PLUSPLUS:
524         case WLAN_BAND_WIDTH_80PLUSMINUS:
525             return MAC_SCA;
526         case WLAN_BAND_WIDTH_40MINUS:
527         case WLAN_BAND_WIDTH_80MINUSPLUS:
528         case WLAN_BAND_WIDTH_80MINUSMINUS:
529             return MAC_SCB;
530         default:
531             return MAC_SCN;
532     }
533 }
534 
535 /* ****************************************************************************
536  功能描述  : 根据信道中心频点获取对应的"带宽模式"
537  输入参数  : uc_channel         : 信道号
538              uc_chan_center_freq: 信道中心频点
539  修改历史      :
540   1.日    期   : 2014年2月27日
541     作    者   : HiSilicon
542     修改内容   : 新生成函数
543 **************************************************************************** */
mac_get_bandwith_from_center_freq_seg0(hi_u8 channel,hi_u8 chan_center_freq)544 wlan_channel_bandwidth_enum_uint8 mac_get_bandwith_from_center_freq_seg0(hi_u8 channel, hi_u8 chan_center_freq)
545 {
546     switch (chan_center_freq - channel) {
547         case 6: /* 6: 从20信道+1, 从40信道+1 场景 */
548             /* **********************************************************************
549             | 主20 | 从20 | 从40       |
550                           |
551                           |中心频率相对于主20偏6个信道
552             *********************************************************************** */
553             return WLAN_BAND_WIDTH_80PLUSPLUS;
554         case -2: /* -2: 从20信道+1, 从40信道-1 场景 */
555             /* **********************************************************************
556             | 从40        | 主20 | 从20 |
557                           |
558                           |中心频率相对于主20偏-2个信道
559             *********************************************************************** */
560             return WLAN_BAND_WIDTH_80PLUSMINUS;
561         case 2: /* 2: 从20信道-1, 从40信道+1 场景 */
562             /* **********************************************************************
563             | 从20 | 主20 | 从40       |
564                           |
565                           |中心频率相对于主20偏2个信道
566             *********************************************************************** */
567             return WLAN_BAND_WIDTH_80MINUSPLUS;
568         case -6: /* -6: 从20信道-1, 从40信道-1 场景 */
569             /* **********************************************************************
570             | 从40        | 从20 | 主20 |
571                           |
572                           |中心频率相对于主20偏-6个信道
573             *********************************************************************** */
574             return WLAN_BAND_WIDTH_80MINUSMINUS;
575         default:
576             return 0;
577     }
578 }
579 
580 /* ****************************************************************************
581  功能描述  : 根据"次信道偏移量"获取对应的带宽模式
582  输入参数  : en_sec_chan_offset: 次信道偏移量
583  返 回 值  : 带宽模式
584 **************************************************************************** */
mac_get_bandwidth_from_sco(mac_sec_ch_off_enum_uint8 sec_chan_offset)585 wlan_channel_bandwidth_enum_uint8 mac_get_bandwidth_from_sco(mac_sec_ch_off_enum_uint8 sec_chan_offset)
586 {
587     switch (sec_chan_offset) {
588         case MAC_SCA: /* Secondary Channel Above */
589             return WLAN_BAND_WIDTH_40PLUS;
590         case MAC_SCB: /* Secondary Channel Below */
591             return WLAN_BAND_WIDTH_40MINUS;
592         case MAC_BW_5M:
593             return WLAN_BAND_WIDTH_5M;
594         case MAC_BW_10M:
595             return WLAN_BAND_WIDTH_10M;
596         default: /* No Secondary Channel    */
597             return WLAN_BAND_WIDTH_20M;
598     }
599 }
600 
601 #ifdef __cplusplus
602 #if __cplusplus
603 }
604 #endif
605 #endif
606