Commit 78506c2a1eac97504ff56de1c587bac403ca8dca

Authored by Srujana Challa
Committed by Herbert Xu
1 parent 6450601703

crypto: octeontx2 - add support to get engine capabilities

Adds support to get engine capabilities and adds a new mailbox
to share capabilities with VF driver.

Signed-off-by: Suheil Chandran <schandran@marvell.com>
Signed-off-by: Srujana Challa <schalla@marvell.com>
Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>

Showing 8 changed files with 350 additions and 0 deletions Side-by-side Diff

drivers/crypto/marvell/octeontx2/otx2_cpt_common.h
... ... @@ -20,6 +20,7 @@
20 20  
21 21 #define OTX2_CPT_INVALID_CRYPTO_ENG_GRP 0xFF
22 22 #define OTX2_CPT_NAME_LENGTH 64
  23 +#define OTX2_CPT_DMA_MINALIGN 128
23 24  
24 25 #define BAD_OTX2_CPT_ENG_TYPE OTX2_CPT_MAX_ENG_TYPES
25 26  
... ... @@ -32,6 +33,7 @@
32 33  
33 34 /* Take mbox id from end of CPT mbox range in AF (range 0xA00 - 0xBFF) */
34 35 #define MBOX_MSG_GET_ENG_GRP_NUM 0xBFF
  36 +#define MBOX_MSG_GET_CAPS 0xBFD
35 37  
36 38 /*
37 39 * Message request and response to get engine group number
... ... @@ -47,6 +49,40 @@
47 49 struct mbox_msghdr hdr;
48 50 u8 eng_type;
49 51 u8 eng_grp_num;
  52 +};
  53 +
  54 +/* CPT HW capabilities */
  55 +union otx2_cpt_eng_caps {
  56 + u64 u;
  57 + struct {
  58 + u64 reserved_0_4:5;
  59 + u64 mul:1;
  60 + u64 sha1_sha2:1;
  61 + u64 chacha20:1;
  62 + u64 zuc_snow3g:1;
  63 + u64 sha3:1;
  64 + u64 aes:1;
  65 + u64 kasumi:1;
  66 + u64 des:1;
  67 + u64 crc:1;
  68 + u64 reserved_14_63:50;
  69 + };
  70 +};
  71 +
  72 +/*
  73 + * Message request and response to get HW capabilities for each
  74 + * engine type (SE, IE, AE).
  75 + * This messages are only used between CPT PF <=> CPT VF
  76 + */
  77 +struct otx2_cpt_caps_msg {
  78 + struct mbox_msghdr hdr;
  79 +};
  80 +
  81 +struct otx2_cpt_caps_rsp {
  82 + struct mbox_msghdr hdr;
  83 + u16 cpt_pf_drv_version;
  84 + u8 cpt_revision;
  85 + union otx2_cpt_eng_caps eng_caps[OTX2_CPT_MAX_ENG_TYPES];
50 86 };
51 87  
52 88 static inline void otx2_cpt_write64(void __iomem *reg_base, u64 blk, u64 slot,
drivers/crypto/marvell/octeontx2/otx2_cpt_reqmgr.h
  1 +/* SPDX-License-Identifier: GPL-2.0-only
  2 + * Copyright (C) 2020 Marvell.
  3 + */
  4 +
  5 +#ifndef __OTX2_CPT_REQMGR_H
  6 +#define __OTX2_CPT_REQMGR_H
  7 +
  8 +#include "otx2_cpt_common.h"
  9 +
  10 +/* Completion code size and initial value */
  11 +#define OTX2_CPT_COMPLETION_CODE_SIZE 8
  12 +#define OTX2_CPT_COMPLETION_CODE_INIT OTX2_CPT_COMP_E_NOTDONE
  13 +
  14 +union otx2_cpt_opcode {
  15 + u16 flags;
  16 + struct {
  17 + u8 major;
  18 + u8 minor;
  19 + } s;
  20 +};
  21 +
  22 +/*
  23 + * CPT_INST_S software command definitions
  24 + * Words EI (0-3)
  25 + */
  26 +union otx2_cpt_iq_cmd_word0 {
  27 + u64 u;
  28 + struct {
  29 + __be16 opcode;
  30 + __be16 param1;
  31 + __be16 param2;
  32 + __be16 dlen;
  33 + } s;
  34 +};
  35 +
  36 +union otx2_cpt_iq_cmd_word3 {
  37 + u64 u;
  38 + struct {
  39 + u64 cptr:61;
  40 + u64 grp:3;
  41 + } s;
  42 +};
  43 +
  44 +struct otx2_cpt_iq_command {
  45 + union otx2_cpt_iq_cmd_word0 cmd;
  46 + u64 dptr;
  47 + u64 rptr;
  48 + union otx2_cpt_iq_cmd_word3 cptr;
  49 +};
  50 +
  51 +#endif /* __OTX2_CPT_REQMGR_H */
drivers/crypto/marvell/octeontx2/otx2_cptlf.h
... ... @@ -4,9 +4,11 @@
4 4 #ifndef __OTX2_CPTLF_H
5 5 #define __OTX2_CPTLF_H
6 6  
  7 +#include <linux/soc/marvell/octeontx2/asm.h>
7 8 #include <mbox.h>
8 9 #include <rvu.h>
9 10 #include "otx2_cpt_common.h"
  11 +#include "otx2_cpt_reqmgr.h"
10 12  
11 13 /*
12 14 * CPT instruction and pending queues user requested length in CPT_INST_S msgs
... ... @@ -270,6 +272,66 @@
270 272 otx2_cptlf_enable_iqueue_exec(&lfs->lf[slot]);
271 273 otx2_cptlf_enable_iqueue_enq(&lfs->lf[slot]);
272 274 }
  275 +}
  276 +
  277 +static inline void otx2_cpt_fill_inst(union otx2_cpt_inst_s *cptinst,
  278 + struct otx2_cpt_iq_command *iq_cmd,
  279 + u64 comp_baddr)
  280 +{
  281 + cptinst->u[0] = 0x0;
  282 + cptinst->s.doneint = true;
  283 + cptinst->s.res_addr = comp_baddr;
  284 + cptinst->u[2] = 0x0;
  285 + cptinst->u[3] = 0x0;
  286 + cptinst->s.ei0 = iq_cmd->cmd.u;
  287 + cptinst->s.ei1 = iq_cmd->dptr;
  288 + cptinst->s.ei2 = iq_cmd->rptr;
  289 + cptinst->s.ei3 = iq_cmd->cptr.u;
  290 +}
  291 +
  292 +/*
  293 + * On OcteonTX2 platform the parameter insts_num is used as a count of
  294 + * instructions to be enqueued. The valid values for insts_num are:
  295 + * 1 - 1 CPT instruction will be enqueued during LMTST operation
  296 + * 2 - 2 CPT instructions will be enqueued during LMTST operation
  297 + */
  298 +static inline void otx2_cpt_send_cmd(union otx2_cpt_inst_s *cptinst,
  299 + u32 insts_num, struct otx2_cptlf_info *lf)
  300 +{
  301 + void __iomem *lmtline = lf->lmtline;
  302 + long ret;
  303 +
  304 + /*
  305 + * Make sure memory areas pointed in CPT_INST_S
  306 + * are flushed before the instruction is sent to CPT
  307 + */
  308 + dma_wmb();
  309 +
  310 + do {
  311 + /* Copy CPT command to LMTLINE */
  312 + memcpy_toio(lmtline, cptinst, insts_num * OTX2_CPT_INST_SIZE);
  313 +
  314 + /*
  315 + * LDEOR initiates atomic transfer to I/O device
  316 + * The following will cause the LMTST to fail (the LDEOR
  317 + * returns zero):
  318 + * - No stores have been performed to the LMTLINE since it was
  319 + * last invalidated.
  320 + * - The bytes which have been stored to LMTLINE since it was
  321 + * last invalidated form a pattern that is non-contiguous, does
  322 + * not start at byte 0, or does not end on a 8-byte boundary.
  323 + * (i.e.comprises a formation of other than 1โ€“16 8-byte
  324 + * words.)
  325 + *
  326 + * These rules are designed such that an operating system
  327 + * context switch or hypervisor guest switch need have no
  328 + * knowledge of the LMTST operations; the switch code does not
  329 + * need to store to LMTCANCEL. Also note as LMTLINE data cannot
  330 + * be read, there is no information leakage between processes.
  331 + */
  332 + ret = otx2_lmt_flush(lf->ioreg);
  333 +
  334 + } while (!ret);
273 335 }
274 336  
275 337 int otx2_cptlf_init(struct otx2_cptlfs_info *lfs, u8 eng_grp_msk, int pri,
drivers/crypto/marvell/octeontx2/otx2_cptpf.h
... ... @@ -31,6 +31,9 @@
31 31 struct otx2_cptvf_info vf[OTX2_CPT_MAX_VFS_NUM];
32 32 struct otx2_cpt_eng_grps eng_grps;/* Engine groups information */
33 33 struct otx2_cptlfs_info lfs; /* CPT LFs attached to this PF */
  34 + /* HW capabilities for each engine type */
  35 + union otx2_cpt_eng_caps eng_caps[OTX2_CPT_MAX_ENG_TYPES];
  36 + bool is_eng_caps_discovered;
34 37  
35 38 /* AF <=> PF mbox */
36 39 struct otx2_mbox afpf_mbox;
drivers/crypto/marvell/octeontx2/otx2_cptpf_main.c
... ... @@ -500,6 +500,11 @@
500 500 if (ret)
501 501 goto destroy_flr;
502 502  
  503 + /* Get CPT HW capabilities using LOAD_FVC operation. */
  504 + ret = otx2_cpt_discover_eng_capabilities(cptpf);
  505 + if (ret)
  506 + goto disable_intr;
  507 +
503 508 ret = otx2_cpt_create_eng_grps(cptpf->pdev, &cptpf->eng_grps);
504 509 if (ret)
505 510 goto disable_intr;
drivers/crypto/marvell/octeontx2/otx2_cptpf_mbox.c
... ... @@ -5,6 +5,12 @@
5 5 #include "otx2_cptpf.h"
6 6 #include "rvu_reg.h"
7 7  
  8 +/*
  9 + * CPT PF driver version, It will be incremented by 1 for every feature
  10 + * addition in CPT mailbox messages.
  11 + */
  12 +#define OTX2_CPT_PF_DRV_VERSION 0x1
  13 +
8 14 static int forward_to_af(struct otx2_cptpf_dev *cptpf,
9 15 struct otx2_cptvf_info *vf,
10 16 struct mbox_msghdr *req, int size)
... ... @@ -35,6 +41,28 @@
35 41 return 0;
36 42 }
37 43  
  44 +static int handle_msg_get_caps(struct otx2_cptpf_dev *cptpf,
  45 + struct otx2_cptvf_info *vf,
  46 + struct mbox_msghdr *req)
  47 +{
  48 + struct otx2_cpt_caps_rsp *rsp;
  49 +
  50 + rsp = (struct otx2_cpt_caps_rsp *)
  51 + otx2_mbox_alloc_msg(&cptpf->vfpf_mbox, vf->vf_id,
  52 + sizeof(*rsp));
  53 + if (!rsp)
  54 + return -ENOMEM;
  55 +
  56 + rsp->hdr.id = MBOX_MSG_GET_CAPS;
  57 + rsp->hdr.sig = OTX2_MBOX_RSP_SIG;
  58 + rsp->hdr.pcifunc = req->pcifunc;
  59 + rsp->cpt_pf_drv_version = OTX2_CPT_PF_DRV_VERSION;
  60 + rsp->cpt_revision = cptpf->pdev->revision;
  61 + memcpy(&rsp->eng_caps, &cptpf->eng_caps, sizeof(rsp->eng_caps));
  62 +
  63 + return 0;
  64 +}
  65 +
38 66 static int handle_msg_get_eng_grp_num(struct otx2_cptpf_dev *cptpf,
39 67 struct otx2_cptvf_info *vf,
40 68 struct mbox_msghdr *req)
... ... @@ -71,6 +99,9 @@
71 99 switch (req->id) {
72 100 case MBOX_MSG_GET_ENG_GRP_NUM:
73 101 err = handle_msg_get_eng_grp_num(cptpf, vf, req);
  102 + break;
  103 + case MBOX_MSG_GET_CAPS:
  104 + err = handle_msg_get_caps(cptpf, vf, req);
74 105 break;
75 106 default:
76 107 err = forward_to_af(cptpf, vf, req, size);
drivers/crypto/marvell/octeontx2/otx2_cptpf_ucode.c
... ... @@ -6,6 +6,8 @@
6 6 #include "otx2_cptpf_ucode.h"
7 7 #include "otx2_cpt_common.h"
8 8 #include "otx2_cptpf.h"
  9 +#include "otx2_cptlf.h"
  10 +#include "otx2_cpt_reqmgr.h"
9 11 #include "rvu_reg.h"
10 12  
11 13 #define CSR_DELAY 30
... ... @@ -1250,6 +1252,165 @@
1250 1252  
1251 1253 cleanup_eng_grps:
1252 1254 otx2_cpt_cleanup_eng_grps(pdev, eng_grps);
  1255 + return ret;
  1256 +}
  1257 +
  1258 +static int create_eng_caps_discovery_grps(struct pci_dev *pdev,
  1259 + struct otx2_cpt_eng_grps *eng_grps)
  1260 +{
  1261 + struct otx2_cpt_uc_info_t *uc_info[OTX2_CPT_MAX_ETYPES_PER_GRP] = { };
  1262 + struct otx2_cpt_engines engs[OTX2_CPT_MAX_ETYPES_PER_GRP] = { {0} };
  1263 + struct fw_info_t fw_info;
  1264 + int ret;
  1265 +
  1266 + ret = cpt_ucode_load_fw(pdev, &fw_info);
  1267 + if (ret)
  1268 + return ret;
  1269 +
  1270 + uc_info[0] = get_ucode(&fw_info, OTX2_CPT_SE_TYPES);
  1271 + if (uc_info[0] == NULL) {
  1272 + dev_err(&pdev->dev, "Unable to find firmware for AE\n");
  1273 + ret = -EINVAL;
  1274 + goto release_fw;
  1275 + }
  1276 + engs[0].type = OTX2_CPT_AE_TYPES;
  1277 + engs[0].count = 2;
  1278 +
  1279 + ret = create_engine_group(&pdev->dev, eng_grps, engs, 1,
  1280 + (void **) uc_info, 0);
  1281 + if (ret)
  1282 + goto release_fw;
  1283 +
  1284 + uc_info[0] = get_ucode(&fw_info, OTX2_CPT_SE_TYPES);
  1285 + if (uc_info[0] == NULL) {
  1286 + dev_err(&pdev->dev, "Unable to find firmware for SE\n");
  1287 + ret = -EINVAL;
  1288 + goto delete_eng_grp;
  1289 + }
  1290 + engs[0].type = OTX2_CPT_SE_TYPES;
  1291 + engs[0].count = 2;
  1292 +
  1293 + ret = create_engine_group(&pdev->dev, eng_grps, engs, 1,
  1294 + (void **) uc_info, 0);
  1295 + if (ret)
  1296 + goto delete_eng_grp;
  1297 +
  1298 + uc_info[0] = get_ucode(&fw_info, OTX2_CPT_IE_TYPES);
  1299 + if (uc_info[0] == NULL) {
  1300 + dev_err(&pdev->dev, "Unable to find firmware for IE\n");
  1301 + ret = -EINVAL;
  1302 + goto delete_eng_grp;
  1303 + }
  1304 + engs[0].type = OTX2_CPT_IE_TYPES;
  1305 + engs[0].count = 2;
  1306 +
  1307 + ret = create_engine_group(&pdev->dev, eng_grps, engs, 1,
  1308 + (void **) uc_info, 0);
  1309 + if (ret)
  1310 + goto delete_eng_grp;
  1311 +
  1312 + cpt_ucode_release_fw(&fw_info);
  1313 + return 0;
  1314 +
  1315 +delete_eng_grp:
  1316 + delete_engine_grps(pdev, eng_grps);
  1317 +release_fw:
  1318 + cpt_ucode_release_fw(&fw_info);
  1319 + return ret;
  1320 +}
  1321 +
  1322 +/*
  1323 + * Get CPT HW capabilities using LOAD_FVC operation.
  1324 + */
  1325 +int otx2_cpt_discover_eng_capabilities(struct otx2_cptpf_dev *cptpf)
  1326 +{
  1327 + struct otx2_cptlfs_info *lfs = &cptpf->lfs;
  1328 + struct otx2_cpt_iq_command iq_cmd;
  1329 + union otx2_cpt_opcode opcode;
  1330 + union otx2_cpt_res_s *result;
  1331 + union otx2_cpt_inst_s inst;
  1332 + dma_addr_t rptr_baddr;
  1333 + struct pci_dev *pdev;
  1334 + u32 len, compl_rlen;
  1335 + int ret, etype;
  1336 + void *rptr;
  1337 +
  1338 + /*
  1339 + * We don't get capabilities if it was already done
  1340 + * (when user enabled VFs for the first time)
  1341 + */
  1342 + if (cptpf->is_eng_caps_discovered)
  1343 + return 0;
  1344 +
  1345 + pdev = cptpf->pdev;
  1346 + /*
  1347 + * Create engine groups for each type to submit LOAD_FVC op and
  1348 + * get engine's capabilities.
  1349 + */
  1350 + ret = create_eng_caps_discovery_grps(pdev, &cptpf->eng_grps);
  1351 + if (ret)
  1352 + goto delete_grps;
  1353 +
  1354 + lfs->pdev = pdev;
  1355 + lfs->reg_base = cptpf->reg_base;
  1356 + lfs->mbox = &cptpf->afpf_mbox;
  1357 + ret = otx2_cptlf_init(&cptpf->lfs, OTX2_CPT_ALL_ENG_GRPS_MASK,
  1358 + OTX2_CPT_QUEUE_HI_PRIO, 1);
  1359 + if (ret)
  1360 + goto delete_grps;
  1361 +
  1362 + compl_rlen = ALIGN(sizeof(union otx2_cpt_res_s), OTX2_CPT_DMA_MINALIGN);
  1363 + len = compl_rlen + LOADFVC_RLEN;
  1364 +
  1365 + result = kzalloc(len, GFP_KERNEL);
  1366 + if (!result) {
  1367 + ret = -ENOMEM;
  1368 + goto lf_cleanup;
  1369 + }
  1370 + rptr_baddr = dma_map_single(&pdev->dev, (void *)result, len,
  1371 + DMA_BIDIRECTIONAL);
  1372 + if (dma_mapping_error(&pdev->dev, rptr_baddr)) {
  1373 + dev_err(&pdev->dev, "DMA mapping failed\n");
  1374 + ret = -EFAULT;
  1375 + goto free_result;
  1376 + }
  1377 + rptr = (u8 *)result + compl_rlen;
  1378 +
  1379 + /* Fill in the command */
  1380 + opcode.s.major = LOADFVC_MAJOR_OP;
  1381 + opcode.s.minor = LOADFVC_MINOR_OP;
  1382 +
  1383 + iq_cmd.cmd.u = 0;
  1384 + iq_cmd.cmd.s.opcode = cpu_to_be16(opcode.flags);
  1385 +
  1386 + /* 64-bit swap for microcode data reads, not needed for addresses */
  1387 + cpu_to_be64s(&iq_cmd.cmd.u);
  1388 + iq_cmd.dptr = 0;
  1389 + iq_cmd.rptr = rptr_baddr + compl_rlen;
  1390 + iq_cmd.cptr.u = 0;
  1391 +
  1392 + for (etype = 1; etype < OTX2_CPT_MAX_ENG_TYPES; etype++) {
  1393 + result->s.compcode = OTX2_CPT_COMPLETION_CODE_INIT;
  1394 + iq_cmd.cptr.s.grp = otx2_cpt_get_eng_grp(&cptpf->eng_grps,
  1395 + etype);
  1396 + otx2_cpt_fill_inst(&inst, &iq_cmd, rptr_baddr);
  1397 + otx2_cpt_send_cmd(&inst, 1, &cptpf->lfs.lf[0]);
  1398 +
  1399 + while (result->s.compcode == OTX2_CPT_COMPLETION_CODE_INIT)
  1400 + cpu_relax();
  1401 +
  1402 + cptpf->eng_caps[etype].u = be64_to_cpup(rptr);
  1403 + }
  1404 + dma_unmap_single(&pdev->dev, rptr_baddr, len, DMA_BIDIRECTIONAL);
  1405 + cptpf->is_eng_caps_discovered = true;
  1406 +
  1407 +free_result:
  1408 + kfree(result);
  1409 +lf_cleanup:
  1410 + otx2_cptlf_shutdown(&cptpf->lfs);
  1411 +delete_grps:
  1412 + delete_engine_grps(pdev, &cptpf->eng_grps);
  1413 +
1253 1414 return ret;
1254 1415 }
drivers/crypto/marvell/octeontx2/otx2_cptpf_ucode.h
... ... @@ -157,6 +157,7 @@
157 157 struct otx2_cpt_eng_grps *eng_grps);
158 158 int otx2_cpt_disable_all_cores(struct otx2_cptpf_dev *cptpf);
159 159 int otx2_cpt_get_eng_grp(struct otx2_cpt_eng_grps *eng_grps, int eng_type);
  160 +int otx2_cpt_discover_eng_capabilities(struct otx2_cptpf_dev *cptpf);
160 161  
161 162 #endif /* __OTX2_CPTPF_UCODE_H */