1 /******************************************************************************
2 *
3 * Copyright(c) 2019 Realtek Corporation.
4 *
5 * This program is free software; you can redistribute it and/or modify it
6 * under the terms of version 2 of the GNU General Public License as
7 * published by the Free Software Foundation.
8 *
9 * This program is distributed in the hope that it will be useful, but WITHOUT
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
12 * more details.
13 *
14 *****************************************************************************/
15 #define _PHL_SEC_C_
16 #include "phl_headers.h"
17
18 #define RTW_PHL_EXT_KEY_LEN 32
19 #define RTW_SEC_KEY_TYPE_NUM 3
20
21 static enum rtw_phl_status
_phl_set_key(struct phl_info_t * phl_info,struct rtw_phl_stainfo_t * sta,struct phl_sec_param_h * crypt,u8 * keybuf)22 _phl_set_key(struct phl_info_t *phl_info,
23 struct rtw_phl_stainfo_t *sta,
24 struct phl_sec_param_h *crypt,
25 u8 *keybuf)
26 {
27 enum rtw_hal_status hal_status = RTW_HAL_STATUS_FAILURE;
28 enum rtw_phl_status phl_status = RTW_PHL_STATUS_FAILURE;
29
30 if(keybuf)
31 PHL_INFO("Add_key:: enc_type(%d) key_id(%d) key_type(%d)\n",
32 crypt->enc_type, crypt->keyid, crypt->key_type);
33 hal_status = rtw_hal_set_key(phl_info->hal,
34 sta,
35 crypt->enc_type,
36 (crypt->key_len==RTW_PHL_EXT_KEY_LEN)?1:0,
37 crypt->spp,
38 crypt->keyid,
39 crypt->key_type,
40 keybuf);
41 if (hal_status == RTW_HAL_STATUS_SUCCESS)
42 phl_status = RTW_PHL_STATUS_SUCCESS;
43
44 return phl_status;
45 }
46
47 #ifdef CONFIG_CMD_DISP
48 struct cmd_sec_param {
49 struct rtw_phl_stainfo_t *sta;
50 struct phl_sec_param_h *crypt;
51 u8 *keybuf;
52 };
53
54 static void
_phl_cmd_set_key_done(void * drv_priv,u8 * cmd,u32 cmd_len,enum rtw_phl_status status)55 _phl_cmd_set_key_done(void *drv_priv,
56 u8 *cmd,
57 u32 cmd_len,
58 enum rtw_phl_status status)
59 {
60 struct cmd_sec_param *param = (struct cmd_sec_param *)cmd;
61
62 if (param) {
63 if (param->keybuf)
64 _os_kmem_free(drv_priv,
65 param->keybuf,
66 param->crypt->key_len);
67
68 if (param->crypt)
69 _os_kmem_free(drv_priv,
70 param->crypt,
71 sizeof(struct phl_sec_param_h));
72
73 _os_kmem_free(drv_priv, param, cmd_len);
74 }
75 }
76
77 enum rtw_phl_status
_phl_cmd_set_key(void * phl,struct rtw_phl_stainfo_t * sta,struct phl_sec_param_h * crypt,u8 * keybuf,enum phl_cmd_type cmd_type,u32 cmd_timeout)78 _phl_cmd_set_key(void *phl,
79 struct rtw_phl_stainfo_t *sta,
80 struct phl_sec_param_h *crypt,
81 u8 *keybuf,
82 enum phl_cmd_type cmd_type,
83 u32 cmd_timeout)
84 {
85 struct phl_info_t *phl_info = (struct phl_info_t *)phl;
86 void *drv = phl_to_drvpriv(phl_info);
87 enum rtw_phl_status psts = RTW_PHL_STATUS_FAILURE;
88
89 struct cmd_sec_param *param = NULL;
90 u32 param_len = 0, crypt_len = 0;
91
92 if (cmd_type == PHL_CMD_DIRECTLY) {
93 psts = _phl_set_key(phl_info, sta, crypt, keybuf);
94 goto _exit;
95 }
96
97 param_len = sizeof(struct cmd_sec_param);
98 param = _os_kmem_alloc(drv, param_len);
99 if (param == NULL) {
100 PHL_ERR("%s: alloc param failed!\n", __func__);
101 psts = RTW_PHL_STATUS_RESOURCE;
102 goto error_param;
103 }
104 _os_mem_set(drv, param, 0, param_len);
105 param->sta = sta;
106
107 crypt_len = sizeof(struct phl_sec_param_h);
108 param->crypt = _os_kmem_alloc(drv, crypt_len);
109 if (param->crypt == NULL) {
110 PHL_ERR("%s: alloc param->crypt failed!\n", __func__);
111 psts = RTW_PHL_STATUS_RESOURCE;
112 goto error_crypt;
113 }
114 _os_mem_set(drv, param->crypt, 0, crypt_len);
115 _os_mem_cpy(drv, param->crypt, crypt, crypt_len);
116
117 if (keybuf) { /* set key */
118 param->keybuf = _os_kmem_alloc(drv, param->crypt->key_len);
119 if (param->keybuf == NULL) {
120 PHL_ERR("%s: alloc param->keybuf failed!\n", __func__);
121 psts = RTW_PHL_STATUS_RESOURCE;
122 goto error_key_buf;
123 }
124 _os_mem_cpy(drv, param->keybuf, keybuf, param->crypt->key_len);
125 }
126
127 psts = phl_cmd_enqueue(phl_info,
128 sta->wrole->hw_band,
129 MSG_EVT_SEC_KEY,
130 (u8 *)param,
131 param_len,
132 _phl_cmd_set_key_done,
133 cmd_type,
134 cmd_timeout);
135
136 if (is_cmd_failure(psts)) {
137 /* Send cmd success, but wait cmd fail*/
138 psts = RTW_PHL_STATUS_FAILURE;
139 } else if (psts != RTW_PHL_STATUS_SUCCESS) {
140 /* Send cmd fail */
141 psts = RTW_PHL_STATUS_FAILURE;
142 goto error_cmd;
143 }
144
145 return psts;
146
147 error_cmd:
148 if (param->keybuf)
149 _os_kmem_free(drv, param->keybuf, param->crypt->key_len);
150 error_key_buf:
151 if (param->crypt)
152 _os_kmem_free(drv, param->crypt, crypt_len);
153
154 error_crypt:
155 if (param)
156 _os_kmem_free(drv, param, param_len);
157
158 error_param:
159 _exit:
160 return psts;
161 }
162
163 enum rtw_phl_status
phl_cmd_set_key_hdl(struct phl_info_t * phl_info,u8 * param)164 phl_cmd_set_key_hdl(struct phl_info_t *phl_info, u8 *param)
165 {
166 struct cmd_sec_param *cmd_sec_param = (struct cmd_sec_param *)param;
167
168 return _phl_set_key(phl_info,
169 cmd_sec_param->sta,
170 cmd_sec_param->crypt,
171 cmd_sec_param->keybuf);
172 }
173 #endif /* CONFIG_CMD_DISP */
174
175 enum rtw_phl_status
rtw_phl_cmd_add_key(void * phl,struct rtw_phl_stainfo_t * sta,struct phl_sec_param_h * crypt,u8 * keybuf,enum phl_cmd_type cmd_type,u32 cmd_timeout)176 rtw_phl_cmd_add_key(void *phl,
177 struct rtw_phl_stainfo_t *sta,
178 struct phl_sec_param_h *crypt,
179 u8 *keybuf,
180 enum phl_cmd_type cmd_type,
181 u32 cmd_timeout)
182 {
183 #ifdef CONFIG_CMD_DISP
184 return _phl_cmd_set_key(phl, sta, crypt, keybuf, cmd_type, cmd_timeout);
185 #else
186 PHL_TRACE(COMP_PHL_DBG, _PHL_INFO_, "%s: not support add key cmd\n",
187 __func__);
188
189 return _phl_set_key((struct phl_info_t *)phl, sta, crypt, keybuf);
190 #endif /* CONFIG_CMD_DISP */
191 }
192
193 enum rtw_phl_status
rtw_phl_cmd_del_key(void * phl,struct rtw_phl_stainfo_t * sta,struct phl_sec_param_h * crypt,enum phl_cmd_type cmd_type,u32 cmd_timeout)194 rtw_phl_cmd_del_key(void *phl,
195 struct rtw_phl_stainfo_t *sta,
196 struct phl_sec_param_h *crypt,
197 enum phl_cmd_type cmd_type,
198 u32 cmd_timeout)
199 {
200 #ifdef CONFIG_CMD_DISP
201 return _phl_cmd_set_key(phl, sta, crypt, NULL, cmd_type, cmd_timeout);
202 #else
203 PHL_TRACE(COMP_PHL_DBG, _PHL_INFO_, "%s: not support del key cmd\n",
204 __func__);
205
206 return _phl_set_key((struct phl_info_t *)phl, sta, crypt, NULL);
207 #endif /* CONFIG_CMD_DISP */
208 }
209
rtw_phl_trans_sec_mode(u8 unicast,u8 multicast)210 u8 rtw_phl_trans_sec_mode(u8 unicast, u8 multicast)
211 {
212 u8 ret = RTW_SEC_ENT_MODE_0;
213
214 if (RTW_ENC_NONE == unicast && RTW_ENC_NONE == multicast) {
215 ret = RTW_SEC_ENT_MODE_0;
216 } else if ((RTW_ENC_WEP40 == unicast && RTW_ENC_WEP40 == multicast) ||
217 (RTW_ENC_WEP104 == unicast && RTW_ENC_WEP104 == multicast)) {
218 ret = RTW_SEC_ENT_MODE_1;
219 } else if (RTW_ENC_WEP40 == multicast || RTW_ENC_WEP104 == multicast) {
220 ret = RTW_SEC_ENT_MODE_3;
221 } else {
222 ret = RTW_SEC_ENT_MODE_2;
223 }
224
225 return ret;
226 }
227
rtw_phl_get_sec_cam_idx(void * phl,struct rtw_phl_stainfo_t * sta,u8 keyid,u8 key_type)228 u8 rtw_phl_get_sec_cam_idx(void *phl,
229 struct rtw_phl_stainfo_t *sta,
230 u8 keyid,
231 u8 key_type)
232 {
233 u8 ret = 0;
234 struct phl_info_t *phl_info = (struct phl_info_t *)phl;
235
236 ret = (u8) rtw_hal_search_key_idx(phl_info->hal, sta, keyid, key_type);
237
238 return ret;
239 }
240