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