Path: blob/master/drivers/crypto/cavium/nitrox/nitrox_lib.c
26285 views
// SPDX-License-Identifier: GPL-2.01#include <linux/cpumask.h>2#include <linux/dma-mapping.h>3#include <linux/dmapool.h>4#include <linux/delay.h>5#include <linux/gfp.h>6#include <linux/kernel.h>7#include <linux/module.h>8#include <linux/pci_regs.h>9#include <linux/vmalloc.h>10#include <linux/pci.h>1112#include "nitrox_dev.h"13#include "nitrox_common.h"14#include "nitrox_req.h"15#include "nitrox_csr.h"1617#define CRYPTO_CTX_SIZE 2561819/* packet input ring alignments */20#define PKTIN_Q_ALIGN_BYTES 1621/* AQM Queue input alignments */22#define AQM_Q_ALIGN_BYTES 322324static int nitrox_cmdq_init(struct nitrox_cmdq *cmdq, int align_bytes)25{26struct nitrox_device *ndev = cmdq->ndev;2728cmdq->qsize = (ndev->qlen * cmdq->instr_size) + align_bytes;29cmdq->unalign_base = dma_alloc_coherent(DEV(ndev), cmdq->qsize,30&cmdq->unalign_dma,31GFP_KERNEL);32if (!cmdq->unalign_base)33return -ENOMEM;3435cmdq->dma = PTR_ALIGN(cmdq->unalign_dma, align_bytes);36cmdq->base = cmdq->unalign_base + (cmdq->dma - cmdq->unalign_dma);37cmdq->write_idx = 0;3839spin_lock_init(&cmdq->cmd_qlock);40spin_lock_init(&cmdq->resp_qlock);41spin_lock_init(&cmdq->backlog_qlock);4243INIT_LIST_HEAD(&cmdq->response_head);44INIT_LIST_HEAD(&cmdq->backlog_head);45INIT_WORK(&cmdq->backlog_qflush, backlog_qflush_work);4647atomic_set(&cmdq->pending_count, 0);48atomic_set(&cmdq->backlog_count, 0);49return 0;50}5152static void nitrox_cmdq_reset(struct nitrox_cmdq *cmdq)53{54cmdq->write_idx = 0;55atomic_set(&cmdq->pending_count, 0);56atomic_set(&cmdq->backlog_count, 0);57}5859static void nitrox_cmdq_cleanup(struct nitrox_cmdq *cmdq)60{61struct nitrox_device *ndev;6263if (!cmdq)64return;6566if (!cmdq->unalign_base)67return;6869ndev = cmdq->ndev;70cancel_work_sync(&cmdq->backlog_qflush);7172dma_free_coherent(DEV(ndev), cmdq->qsize,73cmdq->unalign_base, cmdq->unalign_dma);74nitrox_cmdq_reset(cmdq);7576cmdq->dbell_csr_addr = NULL;77cmdq->compl_cnt_csr_addr = NULL;78cmdq->unalign_base = NULL;79cmdq->base = NULL;80cmdq->unalign_dma = 0;81cmdq->dma = 0;82cmdq->qsize = 0;83cmdq->instr_size = 0;84}8586static void nitrox_free_aqm_queues(struct nitrox_device *ndev)87{88int i;8990for (i = 0; i < ndev->nr_queues; i++) {91nitrox_cmdq_cleanup(ndev->aqmq[i]);92kfree_sensitive(ndev->aqmq[i]);93ndev->aqmq[i] = NULL;94}95}9697static int nitrox_alloc_aqm_queues(struct nitrox_device *ndev)98{99int i, err;100101for (i = 0; i < ndev->nr_queues; i++) {102struct nitrox_cmdq *cmdq;103u64 offset;104105cmdq = kzalloc_node(sizeof(*cmdq), GFP_KERNEL, ndev->node);106if (!cmdq) {107err = -ENOMEM;108goto aqmq_fail;109}110111cmdq->ndev = ndev;112cmdq->qno = i;113cmdq->instr_size = sizeof(struct aqmq_command_s);114115/* AQM Queue Doorbell Counter Register Address */116offset = AQMQ_DRBLX(i);117cmdq->dbell_csr_addr = NITROX_CSR_ADDR(ndev, offset);118/* AQM Queue Commands Completed Count Register Address */119offset = AQMQ_CMD_CNTX(i);120cmdq->compl_cnt_csr_addr = NITROX_CSR_ADDR(ndev, offset);121122err = nitrox_cmdq_init(cmdq, AQM_Q_ALIGN_BYTES);123if (err) {124kfree_sensitive(cmdq);125goto aqmq_fail;126}127ndev->aqmq[i] = cmdq;128}129130return 0;131132aqmq_fail:133nitrox_free_aqm_queues(ndev);134return err;135}136137static void nitrox_free_pktin_queues(struct nitrox_device *ndev)138{139int i;140141for (i = 0; i < ndev->nr_queues; i++) {142struct nitrox_cmdq *cmdq = &ndev->pkt_inq[i];143144nitrox_cmdq_cleanup(cmdq);145}146kfree(ndev->pkt_inq);147ndev->pkt_inq = NULL;148}149150static int nitrox_alloc_pktin_queues(struct nitrox_device *ndev)151{152int i, err;153154ndev->pkt_inq = kcalloc_node(ndev->nr_queues,155sizeof(struct nitrox_cmdq),156GFP_KERNEL, ndev->node);157if (!ndev->pkt_inq)158return -ENOMEM;159160for (i = 0; i < ndev->nr_queues; i++) {161struct nitrox_cmdq *cmdq;162u64 offset;163164cmdq = &ndev->pkt_inq[i];165cmdq->ndev = ndev;166cmdq->qno = i;167cmdq->instr_size = sizeof(struct nps_pkt_instr);168169/* packet input ring doorbell address */170offset = NPS_PKT_IN_INSTR_BAOFF_DBELLX(i);171cmdq->dbell_csr_addr = NITROX_CSR_ADDR(ndev, offset);172/* packet solicit port completion count address */173offset = NPS_PKT_SLC_CNTSX(i);174cmdq->compl_cnt_csr_addr = NITROX_CSR_ADDR(ndev, offset);175176err = nitrox_cmdq_init(cmdq, PKTIN_Q_ALIGN_BYTES);177if (err)178goto pktq_fail;179}180return 0;181182pktq_fail:183nitrox_free_pktin_queues(ndev);184return err;185}186187static int create_crypto_dma_pool(struct nitrox_device *ndev)188{189size_t size;190191/* Crypto context pool, 16 byte aligned */192size = CRYPTO_CTX_SIZE + sizeof(struct ctx_hdr);193ndev->ctx_pool = dma_pool_create("nitrox-context",194DEV(ndev), size, 16, 0);195if (!ndev->ctx_pool)196return -ENOMEM;197198return 0;199}200201static void destroy_crypto_dma_pool(struct nitrox_device *ndev)202{203if (!ndev->ctx_pool)204return;205206dma_pool_destroy(ndev->ctx_pool);207ndev->ctx_pool = NULL;208}209210/*211* crypto_alloc_context - Allocate crypto context from pool212* @ndev: NITROX Device213*/214void *crypto_alloc_context(struct nitrox_device *ndev)215{216struct ctx_hdr *ctx;217struct crypto_ctx_hdr *chdr;218void *vaddr;219dma_addr_t dma;220221chdr = kmalloc(sizeof(*chdr), GFP_KERNEL);222if (!chdr)223return NULL;224225vaddr = dma_pool_zalloc(ndev->ctx_pool, GFP_KERNEL, &dma);226if (!vaddr) {227kfree(chdr);228return NULL;229}230231/* fill meta data */232ctx = vaddr;233ctx->pool = ndev->ctx_pool;234ctx->dma = dma;235ctx->ctx_dma = dma + sizeof(struct ctx_hdr);236237chdr->pool = ndev->ctx_pool;238chdr->dma = dma;239chdr->vaddr = vaddr;240241return chdr;242}243244/**245* crypto_free_context - Free crypto context to pool246* @ctx: context to free247*/248void crypto_free_context(void *ctx)249{250struct crypto_ctx_hdr *ctxp;251252if (!ctx)253return;254255ctxp = ctx;256dma_pool_free(ctxp->pool, ctxp->vaddr, ctxp->dma);257kfree(ctxp);258}259260/**261* nitrox_common_sw_init - allocate software resources.262* @ndev: NITROX device263*264* Allocates crypto context pools and command queues etc.265*266* Return: 0 on success, or a negative error code on error.267*/268int nitrox_common_sw_init(struct nitrox_device *ndev)269{270int err = 0;271272/* per device crypto context pool */273err = create_crypto_dma_pool(ndev);274if (err)275return err;276277err = nitrox_alloc_pktin_queues(ndev);278if (err)279destroy_crypto_dma_pool(ndev);280281err = nitrox_alloc_aqm_queues(ndev);282if (err) {283nitrox_free_pktin_queues(ndev);284destroy_crypto_dma_pool(ndev);285}286287return err;288}289290/**291* nitrox_common_sw_cleanup - free software resources.292* @ndev: NITROX device293*/294void nitrox_common_sw_cleanup(struct nitrox_device *ndev)295{296nitrox_free_aqm_queues(ndev);297nitrox_free_pktin_queues(ndev);298destroy_crypto_dma_pool(ndev);299}300301302