Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

crypto: octeontx2 - add apis for custom engine groups

Octeon TX2 CPT has three type of engines to handle symmetric, asymmetric
and ipsec specific workload. For better utilization, these engines can
be grouped to custom groups at runtime.

This patch adds APIs to create and delete custom CPT engine groups.

Signed-off-by: Srujana Challa <schalla@marvell.com>
Signed-off-by: Shijith Thotton <sthotton@marvell.com>
Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>

authored by

Srujana Challa and committed by
Herbert Xu
d9d77497 3d6b6613

+322 -7
+316 -6
drivers/crypto/marvell/octeontx2/otx2_cptpf_ucode.c
··· 1110 1110 struct otx2_cpt_engines engs[OTX2_CPT_MAX_ETYPES_PER_GRP] = { {0} }; 1111 1111 struct pci_dev *pdev = cptpf->pdev; 1112 1112 struct fw_info_t fw_info; 1113 - int ret; 1113 + int ret = 0; 1114 1114 1115 + mutex_lock(&eng_grps->lock); 1115 1116 /* 1116 1117 * We don't create engine groups if it was already 1117 1118 * made (when user enabled VFs for the first time) 1118 1119 */ 1119 1120 if (eng_grps->is_grps_created) 1120 - return 0; 1121 + goto unlock; 1121 1122 1122 1123 ret = cpt_ucode_load_fw(pdev, &fw_info); 1123 1124 if (ret) 1124 - return ret; 1125 + goto unlock; 1125 1126 1126 1127 /* 1127 1128 * Create engine group with SE engines for kernel ··· 1187 1186 cpt_ucode_release_fw(&fw_info); 1188 1187 1189 1188 if (is_dev_otx2(pdev)) 1190 - return 0; 1189 + goto unlock; 1191 1190 /* 1192 1191 * Configure engine group mask to allow context prefetching 1193 1192 * for the groups. ··· 1202 1201 */ 1203 1202 otx2_cpt_write_af_reg(&cptpf->afpf_mbox, pdev, CPT_AF_CTX_FLUSH_TIMER, 1204 1203 CTX_FLUSH_TIMER_CNT, BLKADDR_CPT0); 1204 + mutex_unlock(&eng_grps->lock); 1205 1205 return 0; 1206 1206 1207 1207 delete_eng_grp: 1208 1208 delete_engine_grps(pdev, eng_grps); 1209 1209 release_fw: 1210 1210 cpt_ucode_release_fw(&fw_info); 1211 + unlock: 1212 + mutex_unlock(&eng_grps->lock); 1211 1213 return ret; 1212 1214 } 1213 1215 ··· 1290 1286 struct otx2_cpt_eng_grp_info *grp; 1291 1287 int i, j; 1292 1288 1289 + mutex_lock(&eng_grps->lock); 1293 1290 delete_engine_grps(pdev, eng_grps); 1294 1291 /* Release memory */ 1295 1292 for (i = 0; i < OTX2_CPT_MAX_ENGINE_GROUPS; i++) { ··· 1300 1295 grp->engs[j].bmap = NULL; 1301 1296 } 1302 1297 } 1298 + mutex_unlock(&eng_grps->lock); 1303 1299 } 1304 1300 1305 1301 int otx2_cpt_init_eng_grps(struct pci_dev *pdev, ··· 1309 1303 struct otx2_cpt_eng_grp_info *grp; 1310 1304 int i, j, ret; 1311 1305 1306 + mutex_init(&eng_grps->lock); 1312 1307 eng_grps->obj = pci_get_drvdata(pdev); 1313 1308 eng_grps->avail.se_cnt = eng_grps->avail.max_se_cnt; 1314 1309 eng_grps->avail.ie_cnt = eng_grps->avail.max_ie_cnt; ··· 1356 1349 struct fw_info_t fw_info; 1357 1350 int ret; 1358 1351 1352 + mutex_lock(&eng_grps->lock); 1359 1353 ret = cpt_ucode_load_fw(pdev, &fw_info); 1360 - if (ret) 1354 + if (ret) { 1355 + mutex_unlock(&eng_grps->lock); 1361 1356 return ret; 1357 + } 1362 1358 1363 - uc_info[0] = get_ucode(&fw_info, OTX2_CPT_SE_TYPES); 1359 + uc_info[0] = get_ucode(&fw_info, OTX2_CPT_AE_TYPES); 1364 1360 if (uc_info[0] == NULL) { 1365 1361 dev_err(&pdev->dev, "Unable to find firmware for AE\n"); 1366 1362 ret = -EINVAL; ··· 1406 1396 goto delete_eng_grp; 1407 1397 1408 1398 cpt_ucode_release_fw(&fw_info); 1399 + mutex_unlock(&eng_grps->lock); 1409 1400 return 0; 1410 1401 1411 1402 delete_eng_grp: 1412 1403 delete_engine_grps(pdev, eng_grps); 1413 1404 release_fw: 1414 1405 cpt_ucode_release_fw(&fw_info); 1406 + mutex_unlock(&eng_grps->lock); 1415 1407 return ret; 1416 1408 } 1417 1409 ··· 1512 1500 delete_engine_grps(pdev, &cptpf->eng_grps); 1513 1501 1514 1502 return ret; 1503 + } 1504 + 1505 + static void swap_engines(struct otx2_cpt_engines *engsl, 1506 + struct otx2_cpt_engines *engsr) 1507 + { 1508 + struct otx2_cpt_engines engs; 1509 + 1510 + engs = *engsl; 1511 + *engsl = *engsr; 1512 + *engsr = engs; 1513 + } 1514 + 1515 + int otx2_cpt_dl_custom_egrp_create(struct otx2_cptpf_dev *cptpf, 1516 + struct devlink_param_gset_ctx *ctx) 1517 + { 1518 + struct otx2_cpt_engines engs[OTX2_CPT_MAX_ETYPES_PER_GRP] = { { 0 } }; 1519 + struct otx2_cpt_uc_info_t *uc_info[OTX2_CPT_MAX_ETYPES_PER_GRP] = {}; 1520 + struct otx2_cpt_eng_grps *eng_grps = &cptpf->eng_grps; 1521 + char *ucode_filename[OTX2_CPT_MAX_ETYPES_PER_GRP]; 1522 + char tmp_buf[OTX2_CPT_NAME_LENGTH] = { 0 }; 1523 + struct device *dev = &cptpf->pdev->dev; 1524 + char *start, *val, *err_msg, *tmp; 1525 + int grp_idx = 0, ret = -EINVAL; 1526 + bool has_se, has_ie, has_ae; 1527 + struct fw_info_t fw_info; 1528 + int ucode_idx = 0; 1529 + 1530 + if (!eng_grps->is_grps_created) { 1531 + dev_err(dev, "Not allowed before creating the default groups\n"); 1532 + return -EINVAL; 1533 + } 1534 + err_msg = "Invalid engine group format"; 1535 + strscpy(tmp_buf, ctx->val.vstr, strlen(ctx->val.vstr) + 1); 1536 + start = tmp_buf; 1537 + 1538 + has_se = has_ie = has_ae = false; 1539 + 1540 + for (;;) { 1541 + val = strsep(&start, ";"); 1542 + if (!val) 1543 + break; 1544 + val = strim(val); 1545 + if (!*val) 1546 + continue; 1547 + 1548 + if (!strncasecmp(val, "se", 2) && strchr(val, ':')) { 1549 + if (has_se || ucode_idx) 1550 + goto err_print; 1551 + tmp = strim(strsep(&val, ":")); 1552 + if (!val) 1553 + goto err_print; 1554 + if (strlen(tmp) != 2) 1555 + goto err_print; 1556 + if (kstrtoint(strim(val), 10, &engs[grp_idx].count)) 1557 + goto err_print; 1558 + engs[grp_idx++].type = OTX2_CPT_SE_TYPES; 1559 + has_se = true; 1560 + } else if (!strncasecmp(val, "ae", 2) && strchr(val, ':')) { 1561 + if (has_ae || ucode_idx) 1562 + goto err_print; 1563 + tmp = strim(strsep(&val, ":")); 1564 + if (!val) 1565 + goto err_print; 1566 + if (strlen(tmp) != 2) 1567 + goto err_print; 1568 + if (kstrtoint(strim(val), 10, &engs[grp_idx].count)) 1569 + goto err_print; 1570 + engs[grp_idx++].type = OTX2_CPT_AE_TYPES; 1571 + has_ae = true; 1572 + } else if (!strncasecmp(val, "ie", 2) && strchr(val, ':')) { 1573 + if (has_ie || ucode_idx) 1574 + goto err_print; 1575 + tmp = strim(strsep(&val, ":")); 1576 + if (!val) 1577 + goto err_print; 1578 + if (strlen(tmp) != 2) 1579 + goto err_print; 1580 + if (kstrtoint(strim(val), 10, &engs[grp_idx].count)) 1581 + goto err_print; 1582 + engs[grp_idx++].type = OTX2_CPT_IE_TYPES; 1583 + has_ie = true; 1584 + } else { 1585 + if (ucode_idx > 1) 1586 + goto err_print; 1587 + if (!strlen(val)) 1588 + goto err_print; 1589 + if (strnstr(val, " ", strlen(val))) 1590 + goto err_print; 1591 + ucode_filename[ucode_idx++] = val; 1592 + } 1593 + } 1594 + 1595 + /* Validate input parameters */ 1596 + if (!(grp_idx && ucode_idx)) 1597 + goto err_print; 1598 + 1599 + if (ucode_idx > 1 && grp_idx < 2) 1600 + goto err_print; 1601 + 1602 + if (grp_idx > OTX2_CPT_MAX_ETYPES_PER_GRP) { 1603 + err_msg = "Error max 2 engine types can be attached"; 1604 + goto err_print; 1605 + } 1606 + 1607 + if (grp_idx > 1) { 1608 + if ((engs[0].type + engs[1].type) != 1609 + (OTX2_CPT_SE_TYPES + OTX2_CPT_IE_TYPES)) { 1610 + err_msg = "Only combination of SE+IE engines is allowed"; 1611 + goto err_print; 1612 + } 1613 + /* Keep SE engines at zero index */ 1614 + if (engs[1].type == OTX2_CPT_SE_TYPES) 1615 + swap_engines(&engs[0], &engs[1]); 1616 + } 1617 + mutex_lock(&eng_grps->lock); 1618 + 1619 + if (cptpf->enabled_vfs) { 1620 + dev_err(dev, "Disable VFs before modifying engine groups\n"); 1621 + ret = -EACCES; 1622 + goto err_unlock; 1623 + } 1624 + INIT_LIST_HEAD(&fw_info.ucodes); 1625 + ret = load_fw(dev, &fw_info, ucode_filename[0]); 1626 + if (ret) { 1627 + dev_err(dev, "Unable to load firmware %s\n", ucode_filename[0]); 1628 + goto err_unlock; 1629 + } 1630 + if (ucode_idx > 1) { 1631 + ret = load_fw(dev, &fw_info, ucode_filename[1]); 1632 + if (ret) { 1633 + dev_err(dev, "Unable to load firmware %s\n", 1634 + ucode_filename[1]); 1635 + goto release_fw; 1636 + } 1637 + } 1638 + uc_info[0] = get_ucode(&fw_info, engs[0].type); 1639 + if (uc_info[0] == NULL) { 1640 + dev_err(dev, "Unable to find firmware for %s\n", 1641 + get_eng_type_str(engs[0].type)); 1642 + ret = -EINVAL; 1643 + goto release_fw; 1644 + } 1645 + if (ucode_idx > 1) { 1646 + uc_info[1] = get_ucode(&fw_info, engs[1].type); 1647 + if (uc_info[1] == NULL) { 1648 + dev_err(dev, "Unable to find firmware for %s\n", 1649 + get_eng_type_str(engs[1].type)); 1650 + ret = -EINVAL; 1651 + goto release_fw; 1652 + } 1653 + } 1654 + ret = create_engine_group(dev, eng_grps, engs, grp_idx, 1655 + (void **)uc_info, 1); 1656 + 1657 + release_fw: 1658 + cpt_ucode_release_fw(&fw_info); 1659 + err_unlock: 1660 + mutex_unlock(&eng_grps->lock); 1661 + return ret; 1662 + err_print: 1663 + dev_err(dev, "%s\n", err_msg); 1664 + return ret; 1665 + } 1666 + 1667 + int otx2_cpt_dl_custom_egrp_delete(struct otx2_cptpf_dev *cptpf, 1668 + struct devlink_param_gset_ctx *ctx) 1669 + { 1670 + struct otx2_cpt_eng_grps *eng_grps = &cptpf->eng_grps; 1671 + struct device *dev = &cptpf->pdev->dev; 1672 + char *tmp, *err_msg; 1673 + int egrp; 1674 + int ret; 1675 + 1676 + err_msg = "Invalid input string format(ex: egrp:0)"; 1677 + if (strncasecmp(ctx->val.vstr, "egrp", 4)) 1678 + goto err_print; 1679 + tmp = ctx->val.vstr; 1680 + strsep(&tmp, ":"); 1681 + if (!tmp) 1682 + goto err_print; 1683 + if (kstrtoint(tmp, 10, &egrp)) 1684 + goto err_print; 1685 + 1686 + if (egrp >= OTX2_CPT_MAX_ENGINE_GROUPS) { 1687 + dev_err(dev, "Invalid engine group %d", egrp); 1688 + return -EINVAL; 1689 + } 1690 + if (!eng_grps->grp[egrp].is_enabled) { 1691 + dev_err(dev, "Error engine_group%d is not configured", egrp); 1692 + return -EINVAL; 1693 + } 1694 + mutex_lock(&eng_grps->lock); 1695 + ret = delete_engine_group(dev, &eng_grps->grp[egrp]); 1696 + mutex_unlock(&eng_grps->lock); 1697 + 1698 + return ret; 1699 + 1700 + err_print: 1701 + dev_err(dev, "%s\n", err_msg); 1702 + return -EINVAL; 1703 + } 1704 + 1705 + static void get_engs_info(struct otx2_cpt_eng_grp_info *eng_grp, char *buf, 1706 + int size, int idx) 1707 + { 1708 + struct otx2_cpt_engs_rsvd *mirrored_engs = NULL; 1709 + struct otx2_cpt_engs_rsvd *engs; 1710 + int len, i; 1711 + 1712 + buf[0] = '\0'; 1713 + for (i = 0; i < OTX2_CPT_MAX_ETYPES_PER_GRP; i++) { 1714 + engs = &eng_grp->engs[i]; 1715 + if (!engs->type) 1716 + continue; 1717 + if (idx != -1 && idx != i) 1718 + continue; 1719 + 1720 + if (eng_grp->mirror.is_ena) 1721 + mirrored_engs = find_engines_by_type( 1722 + &eng_grp->g->grp[eng_grp->mirror.idx], 1723 + engs->type); 1724 + if (i > 0 && idx == -1) { 1725 + len = strlen(buf); 1726 + scnprintf(buf + len, size - len, ", "); 1727 + } 1728 + 1729 + len = strlen(buf); 1730 + scnprintf(buf + len, size - len, "%d %s ", 1731 + mirrored_engs ? engs->count + mirrored_engs->count : 1732 + engs->count, 1733 + get_eng_type_str(engs->type)); 1734 + if (mirrored_engs) { 1735 + len = strlen(buf); 1736 + scnprintf(buf + len, size - len, 1737 + "(%d shared with engine_group%d) ", 1738 + engs->count <= 0 ? 1739 + engs->count + mirrored_engs->count : 1740 + mirrored_engs->count, 1741 + eng_grp->mirror.idx); 1742 + } 1743 + } 1744 + } 1745 + 1746 + void otx2_cpt_print_uc_dbg_info(struct otx2_cptpf_dev *cptpf) 1747 + { 1748 + struct otx2_cpt_eng_grps *eng_grps = &cptpf->eng_grps; 1749 + struct otx2_cpt_eng_grp_info *mirrored_grp; 1750 + char engs_info[2 * OTX2_CPT_NAME_LENGTH]; 1751 + struct otx2_cpt_eng_grp_info *grp; 1752 + struct otx2_cpt_engs_rsvd *engs; 1753 + u32 mask[4]; 1754 + int i, j; 1755 + 1756 + pr_debug("Engine groups global info"); 1757 + pr_debug("max SE %d, max IE %d, max AE %d", eng_grps->avail.max_se_cnt, 1758 + eng_grps->avail.max_ie_cnt, eng_grps->avail.max_ae_cnt); 1759 + pr_debug("free SE %d", eng_grps->avail.se_cnt); 1760 + pr_debug("free IE %d", eng_grps->avail.ie_cnt); 1761 + pr_debug("free AE %d", eng_grps->avail.ae_cnt); 1762 + 1763 + for (i = 0; i < OTX2_CPT_MAX_ENGINE_GROUPS; i++) { 1764 + grp = &eng_grps->grp[i]; 1765 + pr_debug("engine_group%d, state %s", i, 1766 + grp->is_enabled ? "enabled" : "disabled"); 1767 + if (grp->is_enabled) { 1768 + mirrored_grp = &eng_grps->grp[grp->mirror.idx]; 1769 + pr_debug("Ucode0 filename %s, version %s", 1770 + grp->mirror.is_ena ? 1771 + mirrored_grp->ucode[0].filename : 1772 + grp->ucode[0].filename, 1773 + grp->mirror.is_ena ? 1774 + mirrored_grp->ucode[0].ver_str : 1775 + grp->ucode[0].ver_str); 1776 + if (is_2nd_ucode_used(grp)) 1777 + pr_debug("Ucode1 filename %s, version %s", 1778 + grp->ucode[1].filename, 1779 + grp->ucode[1].ver_str); 1780 + } 1781 + 1782 + for (j = 0; j < OTX2_CPT_MAX_ETYPES_PER_GRP; j++) { 1783 + engs = &grp->engs[j]; 1784 + if (engs->type) { 1785 + get_engs_info(grp, engs_info, 1786 + 2 * OTX2_CPT_NAME_LENGTH, j); 1787 + pr_debug("Slot%d: %s", j, engs_info); 1788 + bitmap_to_arr32(mask, engs->bmap, 1789 + eng_grps->engs_num); 1790 + if (is_dev_otx2(cptpf->pdev)) 1791 + pr_debug("Mask: %8.8x %8.8x %8.8x %8.8x", 1792 + mask[3], mask[2], mask[1], 1793 + mask[0]); 1794 + else 1795 + pr_debug("Mask: %8.8x %8.8x %8.8x %8.8x %8.8x", 1796 + mask[4], mask[3], mask[2], mask[1], 1797 + mask[0]); 1798 + } 1799 + } 1800 + } 1515 1801 }
+6 -1
drivers/crypto/marvell/octeontx2/otx2_cptpf_ucode.h
··· 143 143 }; 144 144 145 145 struct otx2_cpt_eng_grps { 146 + struct mutex lock; 146 147 struct otx2_cpt_eng_grp_info grp[OTX2_CPT_MAX_ENGINE_GROUPS]; 147 148 struct otx2_cpt_engs_available avail; 148 149 void *obj; /* device specific data */ ··· 161 160 int otx2_cpt_disable_all_cores(struct otx2_cptpf_dev *cptpf); 162 161 int otx2_cpt_get_eng_grp(struct otx2_cpt_eng_grps *eng_grps, int eng_type); 163 162 int otx2_cpt_discover_eng_capabilities(struct otx2_cptpf_dev *cptpf); 164 - 163 + int otx2_cpt_dl_custom_egrp_create(struct otx2_cptpf_dev *cptpf, 164 + struct devlink_param_gset_ctx *ctx); 165 + int otx2_cpt_dl_custom_egrp_delete(struct otx2_cptpf_dev *cptpf, 166 + struct devlink_param_gset_ctx *ctx); 167 + void otx2_cpt_print_uc_dbg_info(struct otx2_cptpf_dev *cptpf); 165 168 #endif /* __OTX2_CPTPF_UCODE_H */