xref: /OK3568_Linux_fs/external/rkwifibt/drivers/rtl8852be/phl/phl_sec.c (revision 4882a59341e53eb6f0b4789bf948001014eff981)
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