Back to home page

OSCL-LXR

 
 

    


0001 /* SPDX-License-Identifier: GPL-2.0
0002  * Marvell OcteonTX CPT driver
0003  *
0004  * Copyright (C) 2019 Marvell International Ltd.
0005  *
0006  * This program is free software; you can redistribute it and/or modify
0007  * it under the terms of the GNU General Public License version 2 as
0008  * published by the Free Software Foundation.
0009  */
0010 
0011 #ifndef __OTX_CPTVF_REQUEST_MANAGER_H
0012 #define __OTX_CPTVF_REQUEST_MANAGER_H
0013 
0014 #include <linux/types.h>
0015 #include <linux/crypto.h>
0016 #include <linux/pci.h>
0017 #include "otx_cpt_hw_types.h"
0018 
0019 /*
0020  * Maximum total number of SG buffers is 100, we divide it equally
0021  * between input and output
0022  */
0023 #define OTX_CPT_MAX_SG_IN_CNT       50
0024 #define OTX_CPT_MAX_SG_OUT_CNT      50
0025 
0026 /* DMA mode direct or SG */
0027 #define OTX_CPT_DMA_DIRECT_DIRECT   0
0028 #define OTX_CPT_DMA_GATHER_SCATTER  1
0029 
0030 /* Context source CPTR or DPTR */
0031 #define OTX_CPT_FROM_CPTR       0
0032 #define OTX_CPT_FROM_DPTR       1
0033 
0034 /* CPT instruction queue alignment */
0035 #define OTX_CPT_INST_Q_ALIGNMENT    128
0036 #define OTX_CPT_MAX_REQ_SIZE        65535
0037 
0038 /* Default command timeout in seconds */
0039 #define OTX_CPT_COMMAND_TIMEOUT     4
0040 #define OTX_CPT_TIMER_HOLD      0x03F
0041 #define OTX_CPT_COUNT_HOLD      32
0042 #define OTX_CPT_TIME_IN_RESET_COUNT     5
0043 
0044 /* Minimum and maximum values for interrupt coalescing */
0045 #define OTX_CPT_COALESC_MIN_TIME_WAIT   0x0
0046 #define OTX_CPT_COALESC_MAX_TIME_WAIT   ((1<<16)-1)
0047 #define OTX_CPT_COALESC_MIN_NUM_WAIT    0x0
0048 #define OTX_CPT_COALESC_MAX_NUM_WAIT    ((1<<20)-1)
0049 
0050 union otx_cpt_opcode_info {
0051     u16 flags;
0052     struct {
0053         u8 major;
0054         u8 minor;
0055     } s;
0056 };
0057 
0058 struct otx_cptvf_request {
0059     u32 param1;
0060     u32 param2;
0061     u16 dlen;
0062     union otx_cpt_opcode_info opcode;
0063 };
0064 
0065 struct otx_cpt_buf_ptr {
0066     u8 *vptr;
0067     dma_addr_t dma_addr;
0068     u16 size;
0069 };
0070 
0071 union otx_cpt_ctrl_info {
0072     u32 flags;
0073     struct {
0074 #if defined(__BIG_ENDIAN_BITFIELD)
0075         u32 reserved0:26;
0076         u32 grp:3;  /* Group bits */
0077         u32 dma_mode:2; /* DMA mode */
0078         u32 se_req:1;   /* To SE core */
0079 #else
0080         u32 se_req:1;   /* To SE core */
0081         u32 dma_mode:2; /* DMA mode */
0082         u32 grp:3;  /* Group bits */
0083         u32 reserved0:26;
0084 #endif
0085     } s;
0086 };
0087 
0088 /*
0089  * CPT_INST_S software command definitions
0090  * Words EI (0-3)
0091  */
0092 union otx_cpt_iq_cmd_word0 {
0093     u64 u64;
0094     struct {
0095         __be16 opcode;
0096         __be16 param1;
0097         __be16 param2;
0098         __be16 dlen;
0099     } s;
0100 };
0101 
0102 union otx_cpt_iq_cmd_word3 {
0103     u64 u64;
0104     struct {
0105 #if defined(__BIG_ENDIAN_BITFIELD)
0106         u64 grp:3;
0107         u64 cptr:61;
0108 #else
0109         u64 cptr:61;
0110         u64 grp:3;
0111 #endif
0112     } s;
0113 };
0114 
0115 struct otx_cpt_iq_cmd {
0116     union otx_cpt_iq_cmd_word0 cmd;
0117     u64 dptr;
0118     u64 rptr;
0119     union otx_cpt_iq_cmd_word3 cptr;
0120 };
0121 
0122 struct otx_cpt_sglist_component {
0123     union {
0124         u64 len;
0125         struct {
0126             __be16 len0;
0127             __be16 len1;
0128             __be16 len2;
0129             __be16 len3;
0130         } s;
0131     } u;
0132     __be64 ptr0;
0133     __be64 ptr1;
0134     __be64 ptr2;
0135     __be64 ptr3;
0136 };
0137 
0138 struct otx_cpt_pending_entry {
0139     u64 *completion_addr;   /* Completion address */
0140     struct otx_cpt_info_buffer *info;
0141     /* Kernel async request callback */
0142     void (*callback)(int status, void *arg1, void *arg2);
0143     struct crypto_async_request *areq; /* Async request callback arg */
0144     u8 resume_sender;   /* Notify sender to resume sending requests */
0145     u8 busy;        /* Entry status (free/busy) */
0146 };
0147 
0148 struct otx_cpt_pending_queue {
0149     struct otx_cpt_pending_entry *head; /* Head of the queue */
0150     u32 front;          /* Process work from here */
0151     u32 rear;           /* Append new work here */
0152     u32 pending_count;      /* Pending requests count */
0153     u32 qlen;           /* Queue length */
0154     spinlock_t lock;        /* Queue lock */
0155 };
0156 
0157 struct otx_cpt_req_info {
0158     /* Kernel async request callback */
0159     void (*callback)(int status, void *arg1, void *arg2);
0160     struct crypto_async_request *areq; /* Async request callback arg */
0161     struct otx_cptvf_request req;/* Request information (core specific) */
0162     union otx_cpt_ctrl_info ctrl;/* User control information */
0163     struct otx_cpt_buf_ptr in[OTX_CPT_MAX_SG_IN_CNT];
0164     struct otx_cpt_buf_ptr out[OTX_CPT_MAX_SG_OUT_CNT];
0165     u8 *iv_out;     /* IV to send back */
0166     u16 rlen;   /* Output length */
0167     u8 incnt;   /* Number of input buffers */
0168     u8 outcnt;  /* Number of output buffers */
0169     u8 req_type;    /* Type of request */
0170     u8 is_enc;  /* Is a request an encryption request */
0171     u8 is_trunc_hmac;/* Is truncated hmac used */
0172 };
0173 
0174 struct otx_cpt_info_buffer {
0175     struct otx_cpt_pending_entry *pentry;
0176     struct otx_cpt_req_info *req;
0177     struct pci_dev *pdev;
0178     u64 *completion_addr;
0179     u8 *out_buffer;
0180     u8 *in_buffer;
0181     dma_addr_t dptr_baddr;
0182     dma_addr_t rptr_baddr;
0183     dma_addr_t comp_baddr;
0184     unsigned long time_in;
0185     u32 dlen;
0186     u32 dma_len;
0187     u8 extra_time;
0188 };
0189 
0190 static inline void do_request_cleanup(struct pci_dev *pdev,
0191                       struct otx_cpt_info_buffer *info)
0192 {
0193     struct otx_cpt_req_info *req;
0194     int i;
0195 
0196     if (info->dptr_baddr)
0197         dma_unmap_single(&pdev->dev, info->dptr_baddr,
0198                  info->dma_len, DMA_BIDIRECTIONAL);
0199 
0200     if (info->req) {
0201         req = info->req;
0202         for (i = 0; i < req->outcnt; i++) {
0203             if (req->out[i].dma_addr)
0204                 dma_unmap_single(&pdev->dev,
0205                          req->out[i].dma_addr,
0206                          req->out[i].size,
0207                          DMA_BIDIRECTIONAL);
0208         }
0209 
0210         for (i = 0; i < req->incnt; i++) {
0211             if (req->in[i].dma_addr)
0212                 dma_unmap_single(&pdev->dev,
0213                          req->in[i].dma_addr,
0214                          req->in[i].size,
0215                          DMA_BIDIRECTIONAL);
0216         }
0217     }
0218     kfree_sensitive(info);
0219 }
0220 
0221 struct otx_cptvf_wqe;
0222 void otx_cpt_dump_sg_list(struct pci_dev *pdev, struct otx_cpt_req_info *req);
0223 void otx_cpt_post_process(struct otx_cptvf_wqe *wqe);
0224 int otx_cpt_do_request(struct pci_dev *pdev, struct otx_cpt_req_info *req,
0225                int cpu_num);
0226 
0227 #endif /* __OTX_CPTVF_REQUEST_MANAGER_H */