blob: 9dfa7adbeea54a91cda9a5d9cfa18145a6309510 [file] [log] [blame]
developer94c513e2023-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>
developerebe38fd2024-03-22 14:36:06 +080014#include <linux/crypto.h>
developer94c513e2023-08-21 17:33:25 +080015#include <linux/platform_device.h>
developerebe38fd2024-03-22 14:36:06 +080016#include <crypto/internal/skcipher.h>
17#include <crypto/internal/aead.h>
18#include <crypto/internal/hash.h>
developer94c513e2023-08-21 17:33:25 +080019
20#include <mtk_eth_soc.h>
21#include <mtk_hnat/hnat.h>
22
developer94c513e2023-08-21 17:33:25 +080023#include "crypto-eip/crypto-eip.h"
24#include "crypto-eip/ddk-wrapper.h"
developerebe38fd2024-03-22 14:36:06 +080025#include "crypto-eip/lookaside.h"
developer94c513e2023-08-21 17:33:25 +080026#include "crypto-eip/internal.h"
developer1baf13c2024-07-05 15:43:05 +080027#include "crypto-eip/debugfs.h"
developer94c513e2023-08-21 17:33:25 +080028
29#define DRIVER_AUTHOR "Ren-Ting Wang <ren-ting.wang@mediatek.com, " \
30 "Chris.Chou <chris.chou@mediatek.com"
31
32struct mtk_crypto mcrypto;
33struct device *crypto_dev;
developerebe38fd2024-03-22 14:36:06 +080034struct mtk_crypto_priv *priv;
developerebe38fd2024-03-22 14:36:06 +080035
36static struct mtk_crypto_alg_template *mtk_crypto_algs[] = {
37 &mtk_crypto_cbc_aes,
38 &mtk_crypto_ecb_aes,
39 &mtk_crypto_cfb_aes,
40 &mtk_crypto_ofb_aes,
41 &mtk_crypto_ctr_aes,
42 &mtk_crypto_cbc_des,
43 &mtk_crypto_ecb_des,
44 &mtk_crypto_cbc_des3_ede,
45 &mtk_crypto_ecb_des3_ede,
46 &mtk_crypto_sha1,
47 &mtk_crypto_hmac_sha1,
48 &mtk_crypto_sha224,
49 &mtk_crypto_hmac_sha224,
50 &mtk_crypto_sha256,
51 &mtk_crypto_hmac_sha256,
52 &mtk_crypto_sha384,
53 &mtk_crypto_hmac_sha384,
54 &mtk_crypto_sha512,
55 &mtk_crypto_hmac_sha512,
56 &mtk_crypto_md5,
57 &mtk_crypto_hmac_md5,
58 &mtk_crypto_xcbcmac,
59 &mtk_crypto_cmac,
60 &mtk_crypto_hmac_sha1_cbc_aes,
61 &mtk_crypto_hmac_sha224_cbc_aes,
62 &mtk_crypto_hmac_sha256_cbc_aes,
63 &mtk_crypto_hmac_sha384_cbc_aes,
64 &mtk_crypto_hmac_sha512_cbc_aes,
65 &mtk_crypto_hmac_md5_cbc_aes,
66 &mtk_crypto_hmac_sha1_cbc_des3_ede,
67 &mtk_crypto_hmac_sha224_cbc_des3_ede,
68 &mtk_crypto_hmac_sha256_cbc_des3_ede,
69 &mtk_crypto_hmac_sha384_cbc_des3_ede,
70 &mtk_crypto_hmac_sha512_cbc_des3_ede,
71 &mtk_crypto_hmac_md5_cbc_des3_ede,
72 &mtk_crypto_hmac_sha1_cbc_des,
73 &mtk_crypto_hmac_sha224_cbc_des,
74 &mtk_crypto_hmac_sha256_cbc_des,
75 &mtk_crypto_hmac_sha384_cbc_des,
76 &mtk_crypto_hmac_sha512_cbc_des,
77 //&mtk_crypto_hmac_sha1_ctr_aes, /* no testcase, todo */
78 //&mtk_crypto_hmac_sha256_ctr_aes, /* no testcase, todo */
79 &mtk_crypto_gcm,
80 &mtk_crypto_rfc4106_gcm,
81 &mtk_crypto_rfc4543_gcm,
82 &mtk_crypto_rfc4309_ccm,
83};
developer94c513e2023-08-21 17:33:25 +080084
85inline void crypto_eth_write(u32 reg, u32 val)
86{
87 writel(val, mcrypto.eth_base + reg);
88}
89
90static inline void crypto_eip_write(u32 reg, u32 val)
91{
92 writel(val, mcrypto.crypto_base + reg);
93}
94
95static inline void crypto_eip_set(u32 reg, u32 mask)
96{
97 setbits(mcrypto.crypto_base + reg, mask);
98}
99
100static inline void crypto_eip_clr(u32 reg, u32 mask)
101{
102 clrbits(mcrypto.crypto_base + reg, mask);
103}
104
105static inline void crypto_eip_rmw(u32 reg, u32 mask, u32 val)
106{
107 clrsetbits(mcrypto.crypto_base + reg, mask, val);
108}
109
110static inline u32 crypto_eip_read(u32 reg)
111{
112 return readl(mcrypto.crypto_base + reg);
113}
114
developer49489b82024-03-28 15:18:08 +0800115#if IS_ENABLED(CONFIG_NET_MEDIATEK_HNAT)
developer94c513e2023-08-21 17:33:25 +0800116static bool mtk_crypto_eip_offloadable(struct sk_buff *skb)
117{
118 /* TODO: check is esp */
119 return true;
120}
developer49489b82024-03-28 15:18:08 +0800121#endif // HNAT
developer94c513e2023-08-21 17:33:25 +0800122
developer5922d4d2024-02-26 19:01:58 +0800123u32 mtk_crypto_ppe_get_num(void)
124{
125 return mcrypto.ppe_num;
126}
127
developer94c513e2023-08-21 17:33:25 +0800128static const struct xfrmdev_ops mtk_xfrmdev_ops = {
129 .xdo_dev_state_add = mtk_xfrm_offload_state_add,
130 .xdo_dev_state_delete = mtk_xfrm_offload_state_delete,
131 .xdo_dev_state_free = mtk_xfrm_offload_state_free,
132 .xdo_dev_offload_ok = mtk_xfrm_offload_ok,
133
134 /* Not support at v5.4*/
135 .xdo_dev_policy_add = mtk_xfrm_offload_policy_add,
136};
137
developerebe38fd2024-03-22 14:36:06 +0800138static int mtk_crypto_register_algorithms(struct mtk_crypto_priv *priv)
139{
140 int i;
141 int j;
142 int ret;
143
144 for (i = 0; i < ARRAY_SIZE(mtk_crypto_algs); i++) {
145 mtk_crypto_algs[i]->priv = priv;
146
147 if (mtk_crypto_algs[i]->type == MTK_CRYPTO_ALG_TYPE_SKCIPHER)
148 ret = crypto_register_skcipher(&mtk_crypto_algs[i]->alg.skcipher);
149 else if (mtk_crypto_algs[i]->type == MTK_CRYPTO_ALG_TYPE_AEAD)
150 ret = crypto_register_aead(&mtk_crypto_algs[i]->alg.aead);
151 else
152 ret = crypto_register_ahash(&mtk_crypto_algs[i]->alg.ahash);
153
154 if (ret)
155 goto fail;
156 }
157
158 return 0;
159
160fail:
161 for (j = 0; j < i; j++) {
162 if (mtk_crypto_algs[j]->type == MTK_CRYPTO_ALG_TYPE_SKCIPHER)
163 crypto_unregister_skcipher(&mtk_crypto_algs[j]->alg.skcipher);
164 else if (mtk_crypto_algs[j]->type == MTK_CRYPTO_ALG_TYPE_AEAD)
165 crypto_unregister_aead(&mtk_crypto_algs[j]->alg.aead);
166 else
167 crypto_unregister_ahash(&mtk_crypto_algs[j]->alg.ahash);
168 }
169
170 return ret;
171}
172
173static void mtk_crypto_unregister_algorithms(void)
174{
175 int i;
176
177 for (i = 0; i < ARRAY_SIZE(mtk_crypto_algs); i++) {
178 if (mtk_crypto_algs[i]->type == MTK_CRYPTO_ALG_TYPE_SKCIPHER)
179 crypto_unregister_skcipher(&mtk_crypto_algs[i]->alg.skcipher);
180 else if (mtk_crypto_algs[i]->type == MTK_CRYPTO_ALG_TYPE_AEAD)
181 crypto_unregister_aead(&mtk_crypto_algs[i]->alg.aead);
182 else
183 crypto_unregister_ahash(&mtk_crypto_algs[i]->alg.ahash);
184 }
185}
186
developer94c513e2023-08-21 17:33:25 +0800187static void mtk_crypto_xfrm_offload_deinit(struct mtk_eth *eth)
188{
189 int i;
190
developer49489b82024-03-28 15:18:08 +0800191#if IS_ENABLED(CONFIG_NET_MEDIATEK_HNAT)
developer94c513e2023-08-21 17:33:25 +0800192 mtk_crypto_offloadable = NULL;
developer49489b82024-03-28 15:18:08 +0800193#endif // HNAT
developer94c513e2023-08-21 17:33:25 +0800194
195 for (i = 0; i < MTK_MAC_COUNT; i++) {
196 eth->netdev[i]->xfrmdev_ops = NULL;
197 eth->netdev[i]->features &= (~NETIF_F_HW_ESP);
198 eth->netdev[i]->hw_enc_features &= (~NETIF_F_HW_ESP);
199 rtnl_lock();
200 netdev_change_features(eth->netdev[i]);
201 rtnl_unlock();
202 }
203}
204
205static void mtk_crypto_xfrm_offload_init(struct mtk_eth *eth)
206{
207 int i;
208
209 for (i = 0; i < MTK_MAC_COUNT; i++) {
210 eth->netdev[i]->xfrmdev_ops = &mtk_xfrmdev_ops;
211 eth->netdev[i]->features |= NETIF_F_HW_ESP;
212 eth->netdev[i]->hw_enc_features |= NETIF_F_HW_ESP;
213 rtnl_lock();
214 netdev_change_features(eth->netdev[i]);
215 rtnl_unlock();
216 }
217
developer49489b82024-03-28 15:18:08 +0800218#if IS_ENABLED(CONFIG_NET_MEDIATEK_HNAT)
developer94c513e2023-08-21 17:33:25 +0800219 mtk_crypto_offloadable = mtk_crypto_eip_offloadable;
developer49489b82024-03-28 15:18:08 +0800220#endif // HNAT
developer94c513e2023-08-21 17:33:25 +0800221}
222
223static int __init mtk_crypto_eth_dts_init(struct platform_device *pdev)
224{
225 struct platform_device *eth_pdev;
226 struct device_node *crypto_node;
227 struct device_node *eth_node;
228 struct resource res;
229 int ret = 0;
230
231 crypto_node = pdev->dev.of_node;
232
233 eth_node = of_parse_phandle(crypto_node, "eth", 0);
234 if (!eth_node)
235 return -ENODEV;
236
237 eth_pdev = of_find_device_by_node(eth_node);
238 if (!eth_pdev) {
239 ret = -ENODEV;
240 goto out;
241 }
242
243 if (!eth_pdev->dev.driver) {
244 ret = -EFAULT;
245 goto out;
246 }
247
248 if (of_address_to_resource(eth_node, 0, &res)) {
249 ret = -ENXIO;
250 goto out;
251 }
252
253 mcrypto.eth_base = devm_ioremap(&pdev->dev,
254 res.start, resource_size(&res));
255 if (!mcrypto.eth_base) {
256 ret = -ENOMEM;
257 goto out;
258 }
259
260 mcrypto.eth = platform_get_drvdata(eth_pdev);
261
262out:
263 of_node_put(eth_node);
264
265 return ret;
266}
267
developer5922d4d2024-02-26 19:01:58 +0800268static int __init mtk_crypto_ppe_num_dts_init(struct platform_device *pdev)
269{
270 struct device_node *hnat = NULL;
271 u32 val = 0;
272 int ret = 0;
273
274 hnat = of_parse_phandle(pdev->dev.of_node, "hnat", 0);
275 if (!hnat) {
276 CRYPTO_ERR("can not find hnat node\n");
277 return -ENODEV;
278 }
279
280 ret = of_property_read_u32(hnat, "mtketh-ppe-num", &val);
281 if (ret)
282 mcrypto.ppe_num = 1;
283 else
284 mcrypto.ppe_num = val;
285
286 of_node_put(hnat);
287
288 return 0;
289}
290
developerebe38fd2024-03-22 14:36:06 +0800291static int __init mtk_crypto_lookaside_data_init(struct platform_device *pdev)
292{
293 struct device *dev = &pdev->dev;
developerb3c41cd2024-06-04 17:52:08 +0800294 int i;
developerebe38fd2024-03-22 14:36:06 +0800295
296 priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL);
297 if (!priv)
298 return -ENOMEM;
299
300 platform_set_drvdata(pdev, priv);
301
developerb3c41cd2024-06-04 17:52:08 +0800302 priv->mtk_eip_ring = devm_kcalloc(dev, PEC_MAX_INTERFACE_NUM,
303 sizeof(*priv->mtk_eip_ring), GFP_KERNEL);
304 if (!priv->mtk_eip_ring)
developerebe38fd2024-03-22 14:36:06 +0800305 return -ENOMEM;
306
developerb3c41cd2024-06-04 17:52:08 +0800307 for (i = 0; i < PEC_MAX_INTERFACE_NUM; i++) {
308 char wq_name[17] = {0};
309 char irq_name[6] = {0};
310 int irq, cpu;
311
312 // init workqueue for all rings
313 priv->mtk_eip_ring[i].work_data.priv = priv;
314 priv->mtk_eip_ring[i].work_data.ring = i;
315 INIT_WORK(&priv->mtk_eip_ring[i].work_data.work, mtk_crypto_dequeue_work);
316
317 snprintf(wq_name, 17, "mtk_crypto_work%d", i);
318 priv->mtk_eip_ring[i].workqueue = create_singlethread_workqueue(wq_name);
319 if (!priv->mtk_eip_ring[i].workqueue)
320 return -ENOMEM;
developerebe38fd2024-03-22 14:36:06 +0800321
developerb3c41cd2024-06-04 17:52:08 +0800322 crypto_init_queue(&priv->mtk_eip_ring[i].queue, EIP197_DEFAULT_RING_SIZE);
323
324 spin_lock_init(&priv->mtk_eip_ring[i].ring_lock);
325 spin_lock_init(&priv->mtk_eip_ring[i].queue_lock);
326 INIT_LIST_HEAD(&priv->mtk_eip_ring[i].list);
327
328 // setup irq affinity
329 snprintf(irq_name, 6, "ring%d", i);
330 irq = platform_get_irq_byname(pdev, irq_name);
331 if (irq < 0)
332 return irq;
333
334 cpu = cpumask_local_spread(i, NUMA_NO_NODE);
335 irq_set_affinity_hint(irq, get_cpu_mask(cpu));
336 }
developerebe38fd2024-03-22 14:36:06 +0800337
338 return 0;
339};
340
developer94c513e2023-08-21 17:33:25 +0800341static int __init mtk_crypto_eip_dts_init(void)
342{
343 struct platform_device *crypto_pdev;
344 struct device_node *crypto_node;
345 struct resource res;
346 int ret;
347
348 crypto_node = of_find_compatible_node(NULL, NULL, HWPAL_PLATFORM_DEVICE_NAME);
349 if (!crypto_node)
350 return -ENODEV;
351
352 crypto_pdev = of_find_device_by_node(crypto_node);
353 if (!crypto_pdev) {
354 ret = -ENODEV;
355 goto out;
356 }
357
358 /* check crypto platform device is ready */
359 if (!crypto_pdev->dev.driver) {
360 ret = -EFAULT;
361 goto out;
362 }
363
364 if (of_address_to_resource(crypto_node, 0, &res)) {
365 ret = -ENXIO;
366 goto out;
367 }
368
369 mcrypto.crypto_base = devm_ioremap(&crypto_pdev->dev,
370 res.start, resource_size(&res));
371 if (!mcrypto.crypto_base) {
372 ret = -ENOMEM;
373 goto out;
374 }
375
376 ret = mtk_crypto_eth_dts_init(crypto_pdev);
377 if (ret)
378 goto out;
379
developer5922d4d2024-02-26 19:01:58 +0800380 ret = mtk_crypto_ppe_num_dts_init(crypto_pdev);
381 if (ret)
382 goto out;
383
developer94c513e2023-08-21 17:33:25 +0800384 crypto_dev = &crypto_pdev->dev;
385
developerebe38fd2024-03-22 14:36:06 +0800386 ret = mtk_crypto_lookaside_data_init(crypto_pdev);
387 if (ret)
388 goto out;
389
developer94c513e2023-08-21 17:33:25 +0800390out:
391 of_node_put(crypto_node);
392
393 return ret;
394}
395
396static int __init mtk_crypto_eip_hw_init(void)
397{
398 crypto_eip_write(EIP197_FORCE_CLK_ON, 0xffffffff);
399
400 crypto_eip_write(EIP197_FORCE_CLK_ON2, 0xffffffff);
401
402 /* TODO: adjust AXI burst? */
403
404 mtk_ddk_pec_init();
405
406 return 0;
407}
408
409static void __exit mtk_crypto_eip_hw_deinit(void)
410{
411 mtk_ddk_pec_deinit();
412
413 crypto_eip_write(EIP197_FORCE_CLK_ON, 0);
414
415 crypto_eip_write(EIP197_FORCE_CLK_ON2, 0);
416}
417
418static int __init mtk_crypto_eip_init(void)
419{
420 int ret;
421
422 ret = mtk_crypto_eip_dts_init();
423 if (ret) {
424 CRYPTO_ERR("crypto-eip dts init failed: %d\n", ret);
425 return ret;
426 }
427
428 ret = mtk_crypto_eip_hw_init();
429 if (ret) {
430 CRYPTO_ERR("crypto-eip hw init failed: %d\n", ret);
431 return ret;
432 }
433
434 mtk_crypto_xfrm_offload_init(mcrypto.eth);
developer1baf13c2024-07-05 15:43:05 +0800435 mtk_crypto_debugfs_init();
developerebe38fd2024-03-22 14:36:06 +0800436 mtk_crypto_register_algorithms(priv);
developer49489b82024-03-28 15:18:08 +0800437#if defined(CONFIG_MTK_TOPS_CAPWAP_DTLS)
438 mtk_dtls_capwap_init();
439#endif
developer94c513e2023-08-21 17:33:25 +0800440
441 CRYPTO_INFO("crypto-eip init done\n");
442
443 return ret;
444}
445
446static void __exit mtk_crypto_eip_exit(void)
447{
448 /* TODO: deactivate all tunnel */
developer49489b82024-03-28 15:18:08 +0800449#if defined(CONFIG_MTK_TOPS_CAPWAP_DTLS)
450 mtk_dtls_capwap_deinit();
451#endif
developerebe38fd2024-03-22 14:36:06 +0800452 mtk_crypto_unregister_algorithms();
developer94c513e2023-08-21 17:33:25 +0800453 mtk_crypto_xfrm_offload_deinit(mcrypto.eth);
454
455 mtk_crypto_eip_hw_deinit();
developerebe38fd2024-03-22 14:36:06 +0800456
developer94c513e2023-08-21 17:33:25 +0800457}
458
459module_init(mtk_crypto_eip_init);
460module_exit(mtk_crypto_eip_exit);
461
462MODULE_LICENSE("GPL");
463MODULE_DESCRIPTION("MediaTek Crypto EIP Control Driver");
464MODULE_AUTHOR(DRIVER_AUTHOR);