• 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_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