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