[PATCH 4/5] crypto/nx: Add P9 NX support for 842 compression engine.
Michael Ellerman
mpe at ellerman.id.au
Tue Apr 4 20:55:30 AEST 2017
Hi Haren,
A few comments ...
Haren Myneni <haren at linux.vnet.ibm.com> writes:
> diff --git a/arch/powerpc/include/asm/vas.h b/arch/powerpc/include/asm/vas.h
> index 4e5a470..7315621 100644
> --- a/arch/powerpc/include/asm/vas.h
> +++ b/arch/powerpc/include/asm/vas.h
> @@ -19,6 +19,8 @@
> #define VAS_RX_FIFO_SIZE_MIN (1 << 10) /* 1KB */
> #define VAS_RX_FIFO_SIZE_MAX (8 << 20) /* 8MB */
>
> +#define is_vas_available() (cpu_has_feature(CPU_FTR_ARCH_300))
You shouldn't need that, it should all come from the device tree.
> diff --git a/drivers/crypto/nx/Kconfig b/drivers/crypto/nx/Kconfig
> index ad7552a..4ad7fdb 100644
> --- a/drivers/crypto/nx/Kconfig
> +++ b/drivers/crypto/nx/Kconfig
> @@ -38,6 +38,7 @@ config CRYPTO_DEV_NX_COMPRESS_PSERIES
> config CRYPTO_DEV_NX_COMPRESS_POWERNV
> tristate "Compression acceleration support on PowerNV platform"
> depends on PPC_POWERNV
> + select VAS
Don't select symbols that are user visible.
I'm not sure we actually want CONFIG_VAS to be user visible, but
currently it is so this should be 'depends on VAS'.
> diff --git a/drivers/crypto/nx/nx-842-powernv.c b/drivers/crypto/nx/nx-842-powernv.c
> index 8737e90..66efd39 100644
> --- a/drivers/crypto/nx/nx-842-powernv.c
> +++ b/drivers/crypto/nx/nx-842-powernv.c
> @@ -554,6 +662,164 @@ static int nx842_powernv_decompress(const unsigned char *in, unsigned int inlen,
> wmem, CCW_FC_842_DECOMP_CRC);
> }
>
> +
> +static int __init vas_cfg_coproc_info(struct device_node *dn, int chip_id,
> + int vasid, int ct)
> +{
> + struct vas_window *rxwin, *txwin = NULL;
> + struct vas_rx_win_attr rxattr;
> + struct vas_tx_win_attr txattr;
> + struct nx842_coproc *coproc;
> + u32 lpid, pid, tid;
> + u64 rx_fifo;
> + int ret;
> +#define RX_FIFO_SIZE 0x8000
Where's that come from?
> + if (of_property_read_u64(dn, "rx-fifo-address", (void *)&rx_fifo)) {
> + pr_err("ibm,nx-842: Missing rx-fifo-address property\n");
The driver already declares pr_fmt(), so do you need the prefixes on
these pr_err()s ?
> + return -EINVAL;
> + }
> +
> + if (of_property_read_u32(dn, "lpid", &lpid)) {
> + pr_err("ibm,nx-842: Missing lpid property\n");
> + return -EINVAL;
> + }
> +
> + if (of_property_read_u32(dn, "pid", &pid)) {
> + pr_err("ibm,nx-842: Missing pid property\n");
> + return -EINVAL;
> + }
> +
> + if (of_property_read_u32(dn, "tid", &tid)) {
> + pr_err("ibm,nx-842: Missing tid property\n");
> + return -EINVAL;
> + }
> +
> + vas_init_rx_win_attr(&rxattr, ct);
> + rxattr.rx_fifo = (void *)rx_fifo;
> + rxattr.rx_fifo_size = RX_FIFO_SIZE;
> + rxattr.lnotify_lpid = lpid;
> + rxattr.lnotify_pid = pid;
> + rxattr.lnotify_tid = tid;
> + rxattr.wcreds_max = 64;
> +
> + /*
> + * Open a VAS receice window which is used to configure RxFIFO
> + * for NX.
> + */
> + rxwin = vas_rx_win_open(vasid, ct, &rxattr);
> + if (IS_ERR(rxwin)) {
> + pr_err("ibm,nx-842: setting RxFIFO with VAS failed: %ld\n",
> + PTR_ERR(rxwin));
> + return PTR_ERR(rxwin);
> + }
> +
> + /*
> + * Kernel requests will be high priority. So open send
> + * windows only for high priority RxFIFO entries.
> + */
> + if (ct == VAS_COP_TYPE_842_HIPRI) {
This if body looks like it should be a separate function to me.
> + vas_init_tx_win_attr(&txattr, ct);
> + txattr.lpid = 0; /* lpid is 0 for kernel requests */
> + txattr.pid = mfspr(SPRN_PID);
> +
> + /*
> + * Open a VAS send window which is used to send request to NX.
> + */
> + txwin = vas_tx_win_open(vasid, ct, &txattr);
> + if (IS_ERR(txwin)) {
> + pr_err("ibm,nx-842: Can not open TX window: %ld\n",
> + PTR_ERR(txwin));
> + ret = PTR_ERR(txwin);
> + goto err_out;
> + }
> + }
> +
> + coproc = kmalloc(sizeof(*coproc), GFP_KERNEL);
> + if (!coproc) {
> + ret = -ENOMEM;
> + goto err_out;
> + }
The error handling would be simpler if you did that earlier, before you
open the RX/TX windows.
> + coproc->chip_id = chip_id;
> + coproc->vas.rxwin = rxwin;
> + coproc->vas.txwin = txwin;
> +
> + INIT_LIST_HEAD(&coproc->list);
> + list_add(&coproc->list, &nx842_coprocs);
That duplicates logic in the non-vas probe, so ideally would be shared
or in a helper.
> +
> + return 0;
> +
> +err_out:
> + if (txwin)
> + vas_win_close(txwin);
> +
> + vas_win_close(rxwin);
> +
> + return ret;
> +}
> +
> +
> +static int __init nx842_powernv_probe_vas(struct device_node *dn)
> +{
> + struct device_node *nxdn, *np;
There's too many device nodes in this function.
> + int chip_id, vasid, rc;
> +
> + chip_id = of_get_ibm_chip_id(dn);
> + if (chip_id < 0) {
> + pr_err("ibm,chip-id missing\n");
> + return -EINVAL;
> + }
> +
> + np = of_find_node_by_name(dn, "vas");
You should always search by compatible when possible. I don't see why
you wouldn't here.
> + if (!np) {
> + pr_err("ibm,xscom: Missing VAS device node\n");
> + return -EINVAL;
> + }
> +
> + if (of_property_read_u32(np, "vas-id", &vasid)) {
> + pr_err("ibm,vas: Missing vas-id device property\n");
> + of_node_put(np);
> + return -EINVAL;
> + }
> +
> + of_node_put(np);
> +
> + nxdn = of_find_compatible_node(dn, NULL, "ibm,power-nx");
What are you trying to do here?
This will find any node in the device tree that is compatible with
"ibm,power-nx". It will start searching after dn in the device tree. But
it doesn't search the children of dn necessarily, is that what you're
trying to do?
> + if (!nxdn) {
> + pr_err("ibm,xscom: Missing NX device node\n");
> + return -EINVAL;
> + }
> +
> + np = of_find_node_by_name(nxdn, "ibm,nx-842-high");
Search by name again.
> + if (!np) {
> + pr_err("ibm,nx-842-high device node is missing\n");
> + rc = -EINVAL;
> + goto out_nd_put;
> + }
> +
> + rc = vas_cfg_coproc_info(np, chip_id, vasid, VAS_COP_TYPE_842_HIPRI);
> + of_node_put(np);
> + if (rc)
> + goto out_nd_put;
> +
> + np = of_find_node_by_name(nxdn, "ibm,nx-842-normal");
Search by name again.
Normal vs high should not be encoded in the name, it should be a
property of the node.
> + if (!np) {
> + pr_err("ibm,nx-842-normal device node is missing\n");
> + rc = -EINVAL;
> + goto out_nd_put;
> + }
> +
> + rc = vas_cfg_coproc_info(np, chip_id, vasid, VAS_COP_TYPE_842);
> + of_node_put(np);
> + if (!rc)
> + return 0;
> +
> +out_nd_put:
> + of_node_put(nxdn);
> + return rc;
> +}
> +
> static int __init nx842_powernv_probe(struct device_node *dn)
> {
> struct nx842_coproc *coproc;
> @@ -602,11 +868,42 @@ static void nx842_delete_coproc(void)
> struct nx842_coproc *coproc, *n;
>
> list_for_each_entry_safe(coproc, n, &nx842_coprocs, list) {
> + if (is_vas_available()) {
That should just be a check of coproc->vas.rxwin != NULL or similar.
> + vas_win_close(coproc->vas.rxwin);
> + /*
> + * txwin opened only for high priority RxFIFOs
> + */
> + if (coproc->vas.txwin)
> + vas_win_close(coproc->vas.txwin);
> + }
That should be pulled out into a helper, not in the middle of the loop
here.
> list_del(&coproc->list);
> kfree(coproc);
> }
> }
cheers
More information about the Linuxppc-dev
mailing list