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_vap.h"
23 #include "mac_frame.h"
24 #include "hmac_mgmt_ap.h"
25 #include "hmac_encap_frame_ap.h"
26 #include "hmac_rx_data.h"
27 #include "hmac_uapsd.h"
28
29 #ifdef __cplusplus
30 #if __cplusplus
31 extern "C" {
32 #endif
33 #endif
34
35 /* ****************************************************************************
36 3 函数实现
37 **************************************************************************** */
38 /* ****************************************************************************
39 功能描述 : 设置UAPSD使能
40 输入参数 : [1]mac_vap
41 [2]us_len
42 [3]puc_param
43 返 回 值 : hi_u32
44 **************************************************************************** */
hmac_config_set_uapsden(mac_vap_stru * mac_vap,hi_u16 us_len,const hi_u8 * puc_param)45 hi_u32 hmac_config_set_uapsden(mac_vap_stru *mac_vap, hi_u16 us_len, const hi_u8 *puc_param)
46 {
47 hi_u32 ret;
48 mac_device_stru *mac_dev = HI_NULL;
49
50 /* wmm */
51 mac_dev = mac_res_get_dev();
52 if (mac_dev->wmm == HI_FALSE) {
53 oam_warning_log0(0, OAM_SF_UM, "{hmac_config_set_uapsden::wmm is off, not support uapsd mode}");
54 return HI_FAIL;
55 }
56
57 /* mesh */
58 if (mac_vap->vap_mode == WLAN_VAP_MODE_MESH) {
59 oam_warning_log0(mac_vap->vap_id, OAM_SF_PWR, "{hmac_config_set_uapsden::vap mode mesh,not support uapsd!}");
60 return HI_FAIL;
61 }
62
63 /* 窄带 */
64 if ((mac_vap->channel.en_bandwidth == WLAN_BAND_WIDTH_5M) ||
65 (mac_vap->channel.en_bandwidth == WLAN_BAND_WIDTH_10M)) {
66 oam_warning_log1(mac_vap->vap_id, OAM_SF_PWR,
67 "{hmac_config_set_uapsden::narrow band[%dM] mode,not support uapsd!}", mac_vap->channel.en_bandwidth);
68 return HI_FAIL;
69 }
70
71 /* 设置mib值 */
72 mac_vap_set_uapsd_en(mac_vap, *puc_param);
73 /* **************************************************************************
74 抛事件到DMAC层, 同步DMAC数据
75 ************************************************************************** */
76 ret = hmac_config_send_event(mac_vap, WLAN_CFGID_UAPSD_EN, us_len, puc_param);
77 if (oal_unlikely(ret != HI_SUCCESS)) {
78 oam_warning_log1(mac_vap->vap_id, OAM_SF_CFG, "{hmac_config_set_uapsden::hmac_config_send_event failed[%d].}",
79 ret);
80 }
81
82 return ret;
83 }
84
hmac_uapsd_set_info(const hi_u8 * puc_mac_hdr,const hmac_user_stru * hmac_user,hi_u8 uapsd_flag,hi_u32 idx,mac_user_uapsd_status_stru * uapsd_status)85 hi_void hmac_uapsd_set_info(const hi_u8 *puc_mac_hdr, const hmac_user_stru *hmac_user, hi_u8 uapsd_flag, hi_u32 idx,
86 mac_user_uapsd_status_stru *uapsd_status)
87 {
88 /* 设置max SP长度 */
89 hi_u8 max_sp = (puc_mac_hdr[idx + HMAC_UAPSD_WME_LEN] >> 5) & 0x3; /* 右移5位 */
90 switch (max_sp) {
91 case 1: /* 1 case 标志 */
92 uapsd_status->max_sp_len = 2; /* 赋值为2 */
93 break;
94 case 2: /* 2 case 标志 */
95 uapsd_status->max_sp_len = 4; /* 赋值为4 */
96 break;
97 case 3: /* 3 case 标志 */
98 uapsd_status->max_sp_len = 6; /* 赋值为6 */
99 break;
100 default:
101 uapsd_status->max_sp_len = HMAC_UAPSD_SEND_ALL;
102 break;
103 }
104 /* Send uapsd_flag & uapsd_status syn to dmac */
105 mac_vap_stru *mac_vap = mac_vap_get_vap_stru(hmac_user->base_user->vap_id);
106 if (oal_unlikely(mac_vap == HI_NULL)) {
107 oam_error_log1(0, OAM_SF_CFG, "{hmac_uapsd_update_user_para::vap %d null}", hmac_user->base_user->vap_id);
108 return;
109 }
110 hi_u16 us_len = sizeof(hi_u8);
111 hi_u16 us_len_total = sizeof(hi_u8) + sizeof(hi_u8) + sizeof(mac_user_uapsd_status_stru);
112 hi_u8 *puc_param = (hi_u8 *)oal_mem_alloc(OAL_MEM_POOL_ID_LOCAL, us_len_total);
113 if (oal_unlikely(puc_param == HI_NULL)) {
114 oam_error_log0(mac_vap->vap_id, OAM_SF_CFG, "{hmac_uapsd_update_user_para::puc_param null.}");
115 return;
116 }
117 // uc_user_index
118 puc_param[0] = (hi_u8)hmac_user->base_user->us_assoc_id;
119 // uc_uapsd_flag
120 puc_param[us_len] = uapsd_flag;
121 us_len++;
122 // st_uapsd_status
123 if (memcpy_s(puc_param + us_len, sizeof(mac_user_uapsd_status_stru), uapsd_status,
124 sizeof(mac_user_uapsd_status_stru)) != EOK) {
125 oal_mem_free(puc_param);
126 oam_error_log0(0, OAM_SF_CFG, "hmac_uapsd_update_user_para:: st_uapsd_status memcpy_s fail.");
127 return;
128 }
129 us_len += sizeof(mac_user_uapsd_status_stru);
130
131 hi_u32 ret = hmac_config_send_event(mac_vap, WLAN_CFGID_UAPSD_UPDATE, us_len, puc_param);
132 if (oal_unlikely(ret != HI_SUCCESS)) {
133 oam_warning_log1(mac_vap->vap_id, OAM_SF_CFG, "{hmac_uapsd_update_user_para:hmac_config_send_event er%u}", ret);
134 }
135 oal_mem_free(puc_param);
136 }
137
138 /* ****************************************************************************
139 功能描述 : uapsd处理关联请求中的WMM IE
140 修改历史 :
141 1.日 期 : 2013年9月18日
142 作 者 : zourong
143 修改内容 : 新生成函数
144 **************************************************************************** */
hmac_uapsd_update_user_para(const hi_u8 * puc_mac_hdr,hi_u8 sub_type,hi_u32 msg_len,const hmac_user_stru * hmac_user)145 hi_void hmac_uapsd_update_user_para(const hi_u8 *puc_mac_hdr, hi_u8 sub_type, hi_u32 msg_len,
146 const hmac_user_stru *hmac_user)
147 {
148 hi_u8 found_wmm = HI_FALSE;
149 hi_u8 en = HI_FALSE;
150 hi_u8 uapsd_flag = 0;
151 mac_user_uapsd_status_stru uapsd_status = { 0 };
152
153 hi_u32 idx = MAC_CAP_INFO_LEN + MAC_LIS_INTERVAL_IE_LEN;
154 if (WLAN_FC0_SUBTYPE_REASSOC_REQ == sub_type) {
155 idx += WLAN_MAC_ADDR_LEN;
156 }
157 while (idx < msg_len) {
158 if (HI_TRUE != mac_is_wmm_ie((puc_mac_hdr + idx))) {
159 idx += (MAC_IE_HDR_LEN + puc_mac_hdr[(idx + 1)]);
160 continue;
161 }
162 found_wmm = HI_TRUE;
163 break;
164 }
165 /* 不存在WMM IE,直接返回 */
166 if (found_wmm == HI_FALSE) {
167 oam_warning_log1(hmac_user->base_user->vap_id, OAM_SF_PWR, "Could not find WMM IE in assoc req,user_id[%d]\n",
168 hmac_user->base_user->us_assoc_id);
169 return;
170 }
171
172 uapsd_status.qos_info = puc_mac_hdr[idx + HMAC_UAPSD_WME_LEN];
173
174 /* 8为WMM IE长度 */
175 if (BIT0 == (puc_mac_hdr[idx + HMAC_UAPSD_WME_LEN] & BIT0)) {
176 uapsd_status.ac_trigger_ena[WLAN_WME_AC_VO] = 1;
177 uapsd_status.ac_delievy_ena[WLAN_WME_AC_VO] = 1;
178 en = HI_TRUE;
179 }
180
181 if (BIT1 == (puc_mac_hdr[idx + HMAC_UAPSD_WME_LEN] & BIT1)) {
182 uapsd_status.ac_trigger_ena[WLAN_WME_AC_VI] = 1;
183 uapsd_status.ac_delievy_ena[WLAN_WME_AC_VI] = 1;
184 en = HI_TRUE;
185 }
186
187 if (BIT2 == (puc_mac_hdr[idx + HMAC_UAPSD_WME_LEN] & BIT2)) {
188 uapsd_status.ac_trigger_ena[WLAN_WME_AC_BK] = 1;
189 uapsd_status.ac_delievy_ena[WLAN_WME_AC_BK] = 1;
190 en = HI_TRUE;
191 }
192
193 if (BIT3 == (puc_mac_hdr[idx + HMAC_UAPSD_WME_LEN] & BIT3)) {
194 uapsd_status.ac_trigger_ena[WLAN_WME_AC_BE] = 1;
195 uapsd_status.ac_delievy_ena[WLAN_WME_AC_BE] = 1;
196 en = HI_TRUE;
197 }
198
199 if (en == HI_TRUE) {
200 uapsd_flag |= MAC_USR_UAPSD_EN;
201 }
202
203 hmac_uapsd_set_info(puc_mac_hdr, hmac_user, uapsd_flag, idx, &uapsd_status);
204 }
205
206 #ifdef __cplusplus
207 #if __cplusplus
208 }
209 #endif
210 #endif
211