blob: 42976eea684d0d53bf2180743f3f88cbc670f98f [file] [log] [blame]
developer4f0d2ba2023-08-21 17:33:25 +08001// SPDX-License-Identifier: GPL-2.0-or-later
2/*
3 * Copyright (C) 2023 MediaTek Inc.
4 *
5 * Author: Chris.Chou <chris.chou@mediatek.com>
6 * Ren-Ting Wang <ren-ting.wang@mediatek.com>
7 */
8
9#include <linux/module.h>
10#include <linux/netdevice.h>
11#include <linux/of.h>
12#include <linux/of_address.h>
13#include <linux/of_platform.h>
developer2df22aa2024-03-22 14:36:06 +080014#include <linux/crypto.h>
developer4f0d2ba2023-08-21 17:33:25 +080015#include <linux/platform_device.h>
developer2df22aa2024-03-22 14:36:06 +080016#include <crypto/internal/skcipher.h>
17#include <crypto/internal/aead.h>
18#include <crypto/internal/hash.h>
developer4f0d2ba2023-08-21 17:33:25 +080019
20#include <mtk_eth_soc.h>
21#include <mtk_hnat/hnat.h>
22
23#include <crypto-eip/ddk/configs/cs_hwpal_ext.h>
24
25#include "crypto-eip/crypto-eip.h"
26#include "crypto-eip/ddk-wrapper.h"
developer2df22aa2024-03-22 14:36:06 +080027#include "crypto-eip/lookaside.h"
developer4f0d2ba2023-08-21 17:33:25 +080028#include "crypto-eip/internal.h"
29
30#define DRIVER_AUTHOR "Ren-Ting Wang <ren-ting.wang@mediatek.com, " \
31 "Chris.Chou <chris.chou@mediatek.com"
32
33struct mtk_crypto mcrypto;
34struct device *crypto_dev;
developer2df22aa2024-03-22 14:36:06 +080035struct mtk_crypto_priv *priv;
36spinlock_t add_lock;
37
38static struct mtk_crypto_alg_template *mtk_crypto_algs[] = {
39 &mtk_crypto_cbc_aes,
40 &mtk_crypto_ecb_aes,
41 &mtk_crypto_cfb_aes,
42 &mtk_crypto_ofb_aes,
43 &mtk_crypto_ctr_aes,
44 &mtk_crypto_cbc_des,
45 &mtk_crypto_ecb_des,
46 &mtk_crypto_cbc_des3_ede,
47 &mtk_crypto_ecb_des3_ede,
48 &mtk_crypto_sha1,
49 &mtk_crypto_hmac_sha1,
50 &mtk_crypto_sha224,
51 &mtk_crypto_hmac_sha224,
52 &mtk_crypto_sha256,
53 &mtk_crypto_hmac_sha256,
54 &mtk_crypto_sha384,
55 &mtk_crypto_hmac_sha384,
56 &mtk_crypto_sha512,
57 &mtk_crypto_hmac_sha512,
58 &mtk_crypto_md5,
59 &mtk_crypto_hmac_md5,
60 &mtk_crypto_xcbcmac,
61 &mtk_crypto_cmac,
62 &mtk_crypto_hmac_sha1_cbc_aes,
63 &mtk_crypto_hmac_sha224_cbc_aes,
64 &mtk_crypto_hmac_sha256_cbc_aes,
65 &mtk_crypto_hmac_sha384_cbc_aes,
66 &mtk_crypto_hmac_sha512_cbc_aes,
67 &mtk_crypto_hmac_md5_cbc_aes,
68 &mtk_crypto_hmac_sha1_cbc_des3_ede,
69 &mtk_crypto_hmac_sha224_cbc_des3_ede,
70 &mtk_crypto_hmac_sha256_cbc_des3_ede,
71 &mtk_crypto_hmac_sha384_cbc_des3_ede,
72 &mtk_crypto_hmac_sha512_cbc_des3_ede,
73 &mtk_crypto_hmac_md5_cbc_des3_ede,
74 &mtk_crypto_hmac_sha1_cbc_des,
75 &mtk_crypto_hmac_sha224_cbc_des,
76 &mtk_crypto_hmac_sha256_cbc_des,
77 &mtk_crypto_hmac_sha384_cbc_des,
78 &mtk_crypto_hmac_sha512_cbc_des,
79 //&mtk_crypto_hmac_sha1_ctr_aes, /* no testcase, todo */
80 //&mtk_crypto_hmac_sha256_ctr_aes, /* no testcase, todo */
81 &mtk_crypto_gcm,
82 &mtk_crypto_rfc4106_gcm,
83 &mtk_crypto_rfc4543_gcm,
84 &mtk_crypto_rfc4309_ccm,
85};
developer4f0d2ba2023-08-21 17:33:25 +080086
87inline void crypto_eth_write(u32 reg, u32 val)
88{
89 writel(val, mcrypto.eth_base + reg);
90}
91
92static inline void crypto_eip_write(u32 reg, u32 val)
93{
94 writel(val, mcrypto.crypto_base + reg);
95}
96
97static inline void crypto_eip_set(u32 reg, u32 mask)
98{
99 setbits(mcrypto.crypto_base + reg, mask);
100}
101
102static inline void crypto_eip_clr(u32 reg, u32 mask)
103{
104 clrbits(mcrypto.crypto_base + reg, mask);
105}
106
107static inline void crypto_eip_rmw(u32 reg, u32 mask, u32 val)
108{
109 clrsetbits(mcrypto.crypto_base + reg, mask, val);
110}
111
112static inline u32 crypto_eip_read(u32 reg)
113{
114 return readl(mcrypto.crypto_base + reg);
115}
116
developer12ea7142024-03-28 15:18:08 +0800117#if IS_ENABLED(CONFIG_NET_MEDIATEK_HNAT)
developer4f0d2ba2023-08-21 17:33:25 +0800118static bool mtk_crypto_eip_offloadable(struct sk_buff *skb)
119{
120 /* TODO: check is esp */
121 return true;
122}
developer12ea7142024-03-28 15:18:08 +0800123#endif // HNAT
developer4f0d2ba2023-08-21 17:33:25 +0800124
developerddc0d842024-02-26 19:01:58 +0800125u32 mtk_crypto_ppe_get_num(void)
126{
127 return mcrypto.ppe_num;
128}
129
developer4f0d2ba2023-08-21 17:33:25 +0800130static const struct xfrmdev_ops mtk_xfrmdev_ops = {
131 .xdo_dev_state_add = mtk_xfrm_offload_state_add,
132 .xdo_dev_state_delete = mtk_xfrm_offload_state_delete,
133 .xdo_dev_state_free = mtk_xfrm_offload_state_free,
134 .xdo_dev_offload_ok = mtk_xfrm_offload_ok,
135
136 /* Not support at v5.4*/
137 .xdo_dev_policy_add = mtk_xfrm_offload_policy_add,
138};
139
developer2df22aa2024-03-22 14:36:06 +0800140static int mtk_crypto_register_algorithms(struct mtk_crypto_priv *priv)
141{
142 int i;
143 int j;
144 int ret;
145
146 for (i = 0; i < ARRAY_SIZE(mtk_crypto_algs); i++) {
147 mtk_crypto_algs[i]->priv = priv;
148
149 if (mtk_crypto_algs[i]->type == MTK_CRYPTO_ALG_TYPE_SKCIPHER)
150 ret = crypto_register_skcipher(&mtk_crypto_algs[i]->alg.skcipher);
151 else if (mtk_crypto_algs[i]->type == MTK_CRYPTO_ALG_TYPE_AEAD)
152 ret = crypto_register_aead(&mtk_crypto_algs[i]->alg.aead);
153 else
154 ret = crypto_register_ahash(&mtk_crypto_algs[i]->alg.ahash);
155
156 if (ret)
157 goto fail;
158 }
159
160 return 0;
161
162fail:
163 for (j = 0; j < i; j++) {
164 if (mtk_crypto_algs[j]->type == MTK_CRYPTO_ALG_TYPE_SKCIPHER)
165 crypto_unregister_skcipher(&mtk_crypto_algs[j]->alg.skcipher);
166 else if (mtk_crypto_algs[j]->type == MTK_CRYPTO_ALG_TYPE_AEAD)
167 crypto_unregister_aead(&mtk_crypto_algs[j]->alg.aead);
168 else
169 crypto_unregister_ahash(&mtk_crypto_algs[j]->alg.ahash);
170 }
171
172 return ret;
173}
174
175static void mtk_crypto_unregister_algorithms(void)
176{
177 int i;
178
179 for (i = 0; i < ARRAY_SIZE(mtk_crypto_algs); i++) {
180 if (mtk_crypto_algs[i]->type == MTK_CRYPTO_ALG_TYPE_SKCIPHER)
181 crypto_unregister_skcipher(&mtk_crypto_algs[i]->alg.skcipher);
182 else if (mtk_crypto_algs[i]->type == MTK_CRYPTO_ALG_TYPE_AEAD)
183 crypto_unregister_aead(&mtk_crypto_algs[i]->alg.aead);
184 else
185 crypto_unregister_ahash(&mtk_crypto_algs[i]->alg.ahash);
186 }
187}
188
developer4f0d2ba2023-08-21 17:33:25 +0800189static void mtk_crypto_xfrm_offload_deinit(struct mtk_eth *eth)
190{
191 int i;
192
developer12ea7142024-03-28 15:18:08 +0800193#if IS_ENABLED(CONFIG_NET_MEDIATEK_HNAT)
developer4f0d2ba2023-08-21 17:33:25 +0800194 mtk_crypto_offloadable = NULL;
developer12ea7142024-03-28 15:18:08 +0800195#endif // HNAT
developer4f0d2ba2023-08-21 17:33:25 +0800196
197 for (i = 0; i < MTK_MAC_COUNT; i++) {
198 eth->netdev[i]->xfrmdev_ops = NULL;
199 eth->netdev[i]->features &= (~NETIF_F_HW_ESP);
200 eth->netdev[i]->hw_enc_features &= (~NETIF_F_HW_ESP);
201 rtnl_lock();
202 netdev_change_features(eth->netdev[i]);
203 rtnl_unlock();
204 }
205}
206
207static void mtk_crypto_xfrm_offload_init(struct mtk_eth *eth)
208{
209 int i;
210
211 for (i = 0; i < MTK_MAC_COUNT; i++) {
212 eth->netdev[i]->xfrmdev_ops = &mtk_xfrmdev_ops;
213 eth->netdev[i]->features |= NETIF_F_HW_ESP;
214 eth->netdev[i]->hw_enc_features |= NETIF_F_HW_ESP;
215 rtnl_lock();
216 netdev_change_features(eth->netdev[i]);
217 rtnl_unlock();
218 }
219
developer12ea7142024-03-28 15:18:08 +0800220#if IS_ENABLED(CONFIG_NET_MEDIATEK_HNAT)
developer4f0d2ba2023-08-21 17:33:25 +0800221 mtk_crypto_offloadable = mtk_crypto_eip_offloadable;
developer12ea7142024-03-28 15:18:08 +0800222#endif // HNAT
developer4f0d2ba2023-08-21 17:33:25 +0800223}
224
225static int __init mtk_crypto_eth_dts_init(struct platform_device *pdev)
226{
227 struct platform_device *eth_pdev;
228 struct device_node *crypto_node;
229 struct device_node *eth_node;
230 struct resource res;
231 int ret = 0;
232
233 crypto_node = pdev->dev.of_node;
234
235 eth_node = of_parse_phandle(crypto_node, "eth", 0);
236 if (!eth_node)
237 return -ENODEV;
238
239 eth_pdev = of_find_device_by_node(eth_node);
240 if (!eth_pdev) {
241 ret = -ENODEV;
242 goto out;
243 }
244
245 if (!eth_pdev->dev.driver) {
246 ret = -EFAULT;
247 goto out;
248 }
249
250 if (of_address_to_resource(eth_node, 0, &res)) {
251 ret = -ENXIO;
252 goto out;
253 }
254
255 mcrypto.eth_base = devm_ioremap(&pdev->dev,
256 res.start, resource_size(&res));
257 if (!mcrypto.eth_base) {
258 ret = -ENOMEM;
259 goto out;
260 }
261
262 mcrypto.eth = platform_get_drvdata(eth_pdev);
263
264out:
265 of_node_put(eth_node);
266
267 return ret;
268}
269
developerddc0d842024-02-26 19:01:58 +0800270static int __init mtk_crypto_ppe_num_dts_init(struct platform_device *pdev)
271{
272 struct device_node *hnat = NULL;
273 u32 val = 0;
274 int ret = 0;
275
276 hnat = of_parse_phandle(pdev->dev.of_node, "hnat", 0);
277 if (!hnat) {
278 CRYPTO_ERR("can not find hnat node\n");
279 return -ENODEV;
280 }
281
282 ret = of_property_read_u32(hnat, "mtketh-ppe-num", &val);
283 if (ret)
284 mcrypto.ppe_num = 1;
285 else
286 mcrypto.ppe_num = val;
287
288 of_node_put(hnat);
289
290 return 0;
291}
292
developer2df22aa2024-03-22 14:36:06 +0800293static int __init mtk_crypto_lookaside_data_init(struct platform_device *pdev)
294{
295 struct device *dev = &pdev->dev;
296
297 priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL);
298 if (!priv)
299 return -ENOMEM;
300
301 platform_set_drvdata(pdev, priv);
302
303 priv->mtk_eip_queue.work_data.priv = priv;
304 INIT_WORK(&priv->mtk_eip_queue.work_data.work, mtk_crypto_dequeue_work);
305
306 priv->mtk_eip_queue.workqueue = create_singlethread_workqueue("mtk_crypto_work");
307 if (!priv->mtk_eip_queue.workqueue)
308 return -ENOMEM;
309
310 crypto_init_queue(&priv->mtk_eip_queue.queue, EIP197_DEFAULT_RING_SIZE);
311
312 spin_lock_init(&priv->mtk_eip_queue.lock);
313 spin_lock_init(&priv->mtk_eip_queue.queue_lock);
314 spin_lock_init(&add_lock);
315
316 return 0;
317};
318
developer4f0d2ba2023-08-21 17:33:25 +0800319static int __init mtk_crypto_eip_dts_init(void)
320{
321 struct platform_device *crypto_pdev;
322 struct device_node *crypto_node;
323 struct resource res;
324 int ret;
325
326 crypto_node = of_find_compatible_node(NULL, NULL, HWPAL_PLATFORM_DEVICE_NAME);
327 if (!crypto_node)
328 return -ENODEV;
329
330 crypto_pdev = of_find_device_by_node(crypto_node);
331 if (!crypto_pdev) {
332 ret = -ENODEV;
333 goto out;
334 }
335
336 /* check crypto platform device is ready */
337 if (!crypto_pdev->dev.driver) {
338 ret = -EFAULT;
339 goto out;
340 }
341
342 if (of_address_to_resource(crypto_node, 0, &res)) {
343 ret = -ENXIO;
344 goto out;
345 }
346
347 mcrypto.crypto_base = devm_ioremap(&crypto_pdev->dev,
348 res.start, resource_size(&res));
349 if (!mcrypto.crypto_base) {
350 ret = -ENOMEM;
351 goto out;
352 }
353
354 ret = mtk_crypto_eth_dts_init(crypto_pdev);
355 if (ret)
356 goto out;
357
developerddc0d842024-02-26 19:01:58 +0800358 ret = mtk_crypto_ppe_num_dts_init(crypto_pdev);
359 if (ret)
360 goto out;
361
developer4f0d2ba2023-08-21 17:33:25 +0800362 crypto_dev = &crypto_pdev->dev;
363
developer2df22aa2024-03-22 14:36:06 +0800364 ret = mtk_crypto_lookaside_data_init(crypto_pdev);
365 if (ret)
366 goto out;
367
developer4f0d2ba2023-08-21 17:33:25 +0800368out:
369 of_node_put(crypto_node);
370
371 return ret;
372}
373
374static int __init mtk_crypto_eip_hw_init(void)
375{
376 crypto_eip_write(EIP197_FORCE_CLK_ON, 0xffffffff);
377
378 crypto_eip_write(EIP197_FORCE_CLK_ON2, 0xffffffff);
379
380 /* TODO: adjust AXI burst? */
381
382 mtk_ddk_pec_init();
383
384 return 0;
385}
386
387static void __exit mtk_crypto_eip_hw_deinit(void)
388{
389 mtk_ddk_pec_deinit();
390
391 crypto_eip_write(EIP197_FORCE_CLK_ON, 0);
392
393 crypto_eip_write(EIP197_FORCE_CLK_ON2, 0);
394}
395
396static int __init mtk_crypto_eip_init(void)
397{
398 int ret;
399
400 ret = mtk_crypto_eip_dts_init();
401 if (ret) {
402 CRYPTO_ERR("crypto-eip dts init failed: %d\n", ret);
403 return ret;
404 }
405
406 ret = mtk_crypto_eip_hw_init();
407 if (ret) {
408 CRYPTO_ERR("crypto-eip hw init failed: %d\n", ret);
409 return ret;
410 }
411
412 mtk_crypto_xfrm_offload_init(mcrypto.eth);
developer2df22aa2024-03-22 14:36:06 +0800413 mtk_crypto_register_algorithms(priv);
developer12ea7142024-03-28 15:18:08 +0800414#if defined(CONFIG_MTK_TOPS_CAPWAP_DTLS)
415 mtk_dtls_capwap_init();
416#endif
developer4f0d2ba2023-08-21 17:33:25 +0800417
418 CRYPTO_INFO("crypto-eip init done\n");
419
420 return ret;
421}
422
423static void __exit mtk_crypto_eip_exit(void)
424{
425 /* TODO: deactivate all tunnel */
developer12ea7142024-03-28 15:18:08 +0800426#if defined(CONFIG_MTK_TOPS_CAPWAP_DTLS)
427 mtk_dtls_capwap_deinit();
428#endif
developer2df22aa2024-03-22 14:36:06 +0800429 mtk_crypto_unregister_algorithms();
developer4f0d2ba2023-08-21 17:33:25 +0800430 mtk_crypto_xfrm_offload_deinit(mcrypto.eth);
431
432 mtk_crypto_eip_hw_deinit();
developer2df22aa2024-03-22 14:36:06 +0800433
developer4f0d2ba2023-08-21 17:33:25 +0800434}
435
436module_init(mtk_crypto_eip_init);
437module_exit(mtk_crypto_eip_exit);
438
439MODULE_LICENSE("GPL");
440MODULE_DESCRIPTION("MediaTek Crypto EIP Control Driver");
441MODULE_AUTHOR(DRIVER_AUTHOR);