1/*************************************************************************
2 *
3 * This file is provided under a dual BSD/GPLv2 license.  When using or
4 *   redistributing this file, you may do so under either license.
5 *
6 *   GPL LICENSE SUMMARY
7 *
8 *   Copyright(c) 2007,2008,2009 Intel Corporation. All rights reserved.
9 *
10 *   This program is free software; you can redistribute it and/or modify
11 *   it under the terms of version 2 of the GNU General Public License as
12 *   published by the Free Software Foundation.
13 *
14 *   This program is distributed in the hope that it will be useful, but
15 *   WITHOUT ANY WARRANTY; without even the implied warranty of
16 *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
17 *   General Public License for more details.
18 *
19 *   You should have received a copy of the GNU General Public License
20 *   along with this program; if not, write to the Free Software
21 *   Foundation, Inc., 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
22 *   The full GNU General Public License is included in this distribution
23 *   in the file called LICENSE.GPL.
24 *
25 *   Contact Information:
26 *   Intel Corporation
27 *
28 *   BSD LICENSE
29 *
30 *   Copyright(c) 2007,2008,2009 Intel Corporation. All rights reserved.
31 *   All rights reserved.
32 *
33 *   Redistribution and use in source and binary forms, with or without
34 *   modification, are permitted provided that the following conditions
35 *   are met:
36 *
37 *     * Redistributions of source code must retain the above copyright
38 *       notice, this list of conditions and the following disclaimer.
39 *     * Redistributions in binary form must reproduce the above copyright
40 *       notice, this list of conditions and the following disclaimer in
41 *       the documentation and/or other materials provided with the
42 *       distribution.
43 *     * Neither the name of Intel Corporation nor the names of its
44 *       contributors may be used to endorse or promote products derived
45 *       from this software without specific prior written permission.
46 *
47 *   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
48 *   "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
49 *   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
50 *   A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
51 *   OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
52 *   SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
53 *   LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
54 *   DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
55 *   THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
56 *   (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
57 *   OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
58 *
59 *
60 *  version: Security.L.1.0.2-229
61 *
62 ***************************************************************************/
63
64/*
65 * An OCF module that uses Intel�� QuickAssist Integrated Accelerator to do the
66 * crypto.
67 *
68 * This driver requires the ICP Access Library that is available from Intel in
69 * order to operate.
70 */
71
72#include "icp_ocf.h"
73
74#define ICP_OCF_COMP_NAME                       "ICP_OCF"
75#define ICP_OCF_VER_MAIN                        (2)
76#define ICP_OCF_VER_MJR                         (1)
77#define ICP_OCF_VER_MNR                         (0)
78
79#define MAX_DEREG_RETRIES                       (100)
80#define DEFAULT_DEREG_RETRIES 			(10)
81#define DEFAULT_DEREG_DELAY_IN_JIFFIES		(10)
82
83/* This defines the maximum number of sessions possible between OCF
84   and the OCF EP80579 Driver. If set to zero, there is no limit. */
85#define DEFAULT_OCF_TO_DRV_MAX_SESSION_COUNT    (0)
86#define NUM_SUPPORTED_CAPABILITIES              (21)
87
88/*Slab zone names*/
89#define ICP_SESSION_DATA_NAME   "icp_ocf.SesDat"
90#define ICP_OP_DATA_NAME        "icp_ocf.OpDat"
91#define ICP_DH_NAME             "icp_ocf.DH"
92#define ICP_MODEXP_NAME         "icp_ocf.ModExp"
93#define ICP_RSA_DECRYPT_NAME    "icp_ocf.RSAdec"
94#define ICP_RSA_PKEY_NAME       "icp_ocf.RSApk"
95#define ICP_DSA_SIGN_NAME       "icp_ocf.DSAsg"
96#define ICP_DSA_VER_NAME        "icp_ocf.DSAver"
97#define ICP_RAND_VAL_NAME       "icp_ocf.DSArnd"
98#define ICP_FLAT_BUFF_NAME      "icp_ocf.FB"
99
100/*Slabs zones*/
101icp_kmem_cache drvSessionData_zone = NULL;
102icp_kmem_cache drvOpData_zone = NULL;
103icp_kmem_cache drvDH_zone = NULL;
104icp_kmem_cache drvLnModExp_zone = NULL;
105icp_kmem_cache drvRSADecrypt_zone = NULL;
106icp_kmem_cache drvRSAPrivateKey_zone = NULL;
107icp_kmem_cache drvDSARSSign_zone = NULL;
108icp_kmem_cache drvDSARSSignKValue_zone = NULL;
109icp_kmem_cache drvDSAVerify_zone = NULL;
110
111/*Slab zones for flatbuffers and bufferlist*/
112icp_kmem_cache drvFlatBuffer_zone = NULL;
113
114static inline int icp_cache_null_check(void)
115{
116	return (drvSessionData_zone && drvOpData_zone
117		&& drvDH_zone && drvLnModExp_zone && drvRSADecrypt_zone
118		&& drvRSAPrivateKey_zone && drvDSARSSign_zone
119		&& drvDSARSSign_zone && drvDSARSSignKValue_zone
120		&& drvDSAVerify_zone && drvFlatBuffer_zone);
121}
122
123/*Function to free all allocated slab caches before exiting the module*/
124static void icp_ocfDrvFreeCaches(void);
125
126int32_t icp_ocfDrvDriverId = INVALID_DRIVER_ID;
127
128/* Module parameter - gives the number of times LAC deregistration shall be
129   re-tried */
130int num_dereg_retries = DEFAULT_DEREG_RETRIES;
131
132/* Module parameter - gives the delay time in jiffies before a LAC session
133   shall be attempted to be deregistered again */
134int dereg_retry_delay_in_jiffies = DEFAULT_DEREG_DELAY_IN_JIFFIES;
135
136/* Module parameter - gives the maximum number of sessions possible between
137   OCF and the OCF EP80579 Driver. If set to zero, there is no limit.*/
138int max_sessions = DEFAULT_OCF_TO_DRV_MAX_SESSION_COUNT;
139
140/* This is set when the module is removed from the system, no further
141   processing can take place if this is set */
142icp_atomic_t icp_ocfDrvIsExiting = ICP_ATOMIC_INIT(0);
143
144/* This is used to show how many lac sessions were not deregistered*/
145icp_atomic_t lac_session_failed_dereg_count = ICP_ATOMIC_INIT(0);
146
147/* This is used to track the number of registered sessions between OCF and
148 * and the OCF EP80579 driver, when max_session is set to value other than
149 * zero. This ensures that the max_session set for the OCF and the driver
150 * is equal to the LAC registered sessions */
151icp_atomic_t num_ocf_to_drv_registered_sessions = ICP_ATOMIC_INIT(0);
152
153/* Head of linked list used to store session data */
154icp_drvSessionListHead_t icp_ocfDrvGlobalSymListHead;
155icp_drvSessionListHead_t icp_ocfDrvGlobalSymListHead_FreeMemList;
156
157icp_spinlock_t icp_ocfDrvSymSessInfoListSpinlock;
158
159/*Below pointer is only used in linux, FreeBSD uses the name to
160create its own variable name*/
161icp_workqueue *icp_ocfDrvFreeLacSessionWorkQ = NULL;
162ICP_WORKQUEUE_DEFINE_THREAD(icp_ocfDrvFreeLacSessionWorkQ);
163
164struct icp_drvBuffListInfo defBuffListInfo;
165
166/* Name        : icp_ocfDrvInit
167 *
168 * Description : This function will register all the symmetric and asymmetric
169 * functionality that will be accelerated by the hardware. It will also
170 * get a unique driver ID from the OCF and initialise all slab caches
171 */
172ICP_MODULE_INIT_FUNC(icp_ocfDrvInit)
173{
174	int ocfStatus = 0;
175
176	IPRINTK("=== %s ver %d.%d.%d ===\n", ICP_OCF_COMP_NAME,
177		ICP_OCF_VER_MAIN, ICP_OCF_VER_MJR, ICP_OCF_VER_MNR);
178
179	if (MAX_DEREG_RETRIES < num_dereg_retries) {
180		EPRINTK("Session deregistration retry count set to greater "
181			"than %d", MAX_DEREG_RETRIES);
182		icp_module_return_code(EINVAL);
183	}
184
185	/* Initialize and Start the Cryptographic component */
186	if (CPA_STATUS_SUCCESS !=
187	    cpaCyStartInstance(CPA_INSTANCE_HANDLE_SINGLE)) {
188		EPRINTK("Failed to initialize and start the instance "
189			"of the Cryptographic component.\n");
190		return icp_module_return_code(EINVAL);
191	}
192
193	icp_spin_lock_init(&icp_ocfDrvSymSessInfoListSpinlock);
194
195	/* Set the default size of BufferList to allocate */
196	memset(&defBuffListInfo, 0, sizeof(struct icp_drvBuffListInfo));
197	if (ICP_OCF_DRV_STATUS_SUCCESS !=
198	    icp_ocfDrvBufferListMemInfo(ICP_OCF_DRV_DEFAULT_BUFFLIST_ARRAYS,
199					&defBuffListInfo)) {
200		EPRINTK("Failed to get bufferlist memory info.\n");
201		return icp_module_return_code(ENOMEM);
202	}
203
204	/*Register OCF EP80579 Driver with OCF */
205	icp_ocfDrvDriverId = ICP_CRYPTO_GET_DRIVERID();
206
207	if (icp_ocfDrvDriverId < 0) {
208		EPRINTK("%s : ICP driver failed to register with OCF!\n",
209			__FUNCTION__);
210		return icp_module_return_code(ENODEV);
211	}
212
213	/*Create all the slab caches used by the OCF EP80579 Driver */
214	drvSessionData_zone =
215	    ICP_CACHE_CREATE(ICP_SESSION_DATA_NAME, struct icp_drvSessionData);
216
217	/*
218	 * Allocation of the OpData includes the allocation space for meta data.
219	 * The memory after the opData structure is reserved for this meta data.
220	 */
221	drvOpData_zone =
222	    icp_kmem_cache_create(ICP_OP_DATA_NAME,
223				  sizeof(struct icp_drvOpData) +
224				  defBuffListInfo.metaSize,
225				  ICP_KERNEL_CACHE_ALIGN,
226				  ICP_KERNEL_CACHE_NOINIT);
227
228	drvDH_zone = ICP_CACHE_CREATE(ICP_DH_NAME, CpaCyDhPhase1KeyGenOpData);
229
230	drvLnModExp_zone =
231	    ICP_CACHE_CREATE(ICP_MODEXP_NAME, CpaCyLnModExpOpData);
232
233	drvRSADecrypt_zone =
234	    ICP_CACHE_CREATE(ICP_RSA_DECRYPT_NAME, CpaCyRsaDecryptOpData);
235
236	drvRSAPrivateKey_zone =
237	    ICP_CACHE_CREATE(ICP_RSA_PKEY_NAME, CpaCyRsaPrivateKey);
238
239	drvDSARSSign_zone =
240	    ICP_CACHE_CREATE(ICP_DSA_SIGN_NAME, CpaCyDsaRSSignOpData);
241
242	/*too awkward to use a macro here */
243	drvDSARSSignKValue_zone =
244	    ICP_CACHE_CREATE(ICP_RAND_VAL_NAME,
245			     DSA_RS_SIGN_PRIMEQ_SIZE_IN_BYTES);
246
247	drvDSAVerify_zone =
248	    ICP_CACHE_CREATE(ICP_DSA_VER_NAME, CpaCyDsaVerifyOpData);
249
250	drvFlatBuffer_zone =
251	    ICP_CACHE_CREATE(ICP_FLAT_BUFF_NAME, CpaFlatBuffer);
252
253	if (0 == icp_cache_null_check()) {
254		icp_ocfDrvFreeCaches();
255		EPRINTK("%s() line %d: Not enough memory!\n",
256			__FUNCTION__, __LINE__);
257		return ENOMEM;
258	}
259
260	/* Register the ICP symmetric crypto support. */
261	ICP_REG_SYM_WITH_OCF(icp_ocfDrvDriverId, CRYPTO_NULL_CBC, ocfStatus);
262	ICP_REG_SYM_WITH_OCF(icp_ocfDrvDriverId, CRYPTO_DES_CBC, ocfStatus);
263	ICP_REG_SYM_WITH_OCF(icp_ocfDrvDriverId, CRYPTO_3DES_CBC, ocfStatus);
264	ICP_REG_SYM_WITH_OCF(icp_ocfDrvDriverId, CRYPTO_AES_CBC, ocfStatus);
265	ICP_REG_SYM_WITH_OCF(icp_ocfDrvDriverId, CRYPTO_ARC4, ocfStatus);
266	ICP_REG_SYM_WITH_OCF(icp_ocfDrvDriverId, CRYPTO_MD5, ocfStatus);
267	ICP_REG_SYM_WITH_OCF(icp_ocfDrvDriverId, CRYPTO_MD5_HMAC, ocfStatus);
268	ICP_REG_SYM_WITH_OCF(icp_ocfDrvDriverId, CRYPTO_SHA1, ocfStatus);
269	ICP_REG_SYM_WITH_OCF(icp_ocfDrvDriverId, CRYPTO_SHA1_HMAC, ocfStatus);
270	ICP_REG_SYM_WITH_OCF(icp_ocfDrvDriverId, CRYPTO_SHA2_256, ocfStatus);
271	ICP_REG_SYM_WITH_OCF(icp_ocfDrvDriverId, CRYPTO_SHA2_256_HMAC,
272			     ocfStatus);
273	ICP_REG_SYM_WITH_OCF(icp_ocfDrvDriverId, CRYPTO_SHA2_384, ocfStatus);
274	ICP_REG_SYM_WITH_OCF(icp_ocfDrvDriverId, CRYPTO_SHA2_384_HMAC,
275			     ocfStatus);
276	ICP_REG_SYM_WITH_OCF(icp_ocfDrvDriverId, CRYPTO_SHA2_512, ocfStatus);
277	ICP_REG_SYM_WITH_OCF(icp_ocfDrvDriverId, CRYPTO_SHA2_512_HMAC,
278			     ocfStatus);
279
280	/* Register the ICP asymmetric algorithm support */
281	ICP_REG_ASYM_WITH_OCF(icp_ocfDrvDriverId, CRK_DH_COMPUTE_KEY,
282			      ocfStatus);
283	ICP_REG_ASYM_WITH_OCF(icp_ocfDrvDriverId, CRK_MOD_EXP, ocfStatus);
284	ICP_REG_ASYM_WITH_OCF(icp_ocfDrvDriverId, CRK_MOD_EXP_CRT, ocfStatus);
285	ICP_REG_ASYM_WITH_OCF(icp_ocfDrvDriverId, CRK_DSA_SIGN, ocfStatus);
286	ICP_REG_ASYM_WITH_OCF(icp_ocfDrvDriverId, CRK_DSA_VERIFY, ocfStatus);
287
288	/* Register the ICP random number generator support */
289	ICP_REG_RAND_WITH_OCF(icp_ocfDrvDriverId,
290			      icp_ocfDrvReadRandom, NULL, ocfStatus);
291
292	if (OCF_ZERO_FUNCTIONALITY_REGISTERED == ocfStatus) {
293		DPRINTK("%s: Failed to register any device capabilities\n",
294			__FUNCTION__);
295		icp_ocfDrvFreeCaches();
296		icp_ocfDrvDriverId = INVALID_DRIVER_ID;
297		return icp_module_return_code(ECANCELED);
298	}
299
300	DPRINTK("%s: Registered %d of %d device capabilities\n",
301		__FUNCTION__, ocfStatus, NUM_SUPPORTED_CAPABILITIES);
302
303	/*Session data linked list used during module exit */
304	ICP_INIT_LIST_HEAD(&icp_ocfDrvGlobalSymListHead);
305	ICP_INIT_LIST_HEAD(&icp_ocfDrvGlobalSymListHead_FreeMemList);
306
307	ICP_WORKQUEUE_CREATE(icp_ocfDrvFreeLacSessionWorkQ, "icpwq");
308	if (ICP_WORKQUEUE_NULL_CHECK(icp_ocfDrvFreeLacSessionWorkQ)) {
309		EPRINTK("%s: Failed to create single "
310			"thread workqueue\n", __FUNCTION__);
311		icp_ocfDrvFreeCaches();
312		icp_ocfDrvDriverId = INVALID_DRIVER_ID;
313		return icp_module_return_code(ENOMEM);
314	}
315
316	return icp_module_return_code(0);
317}
318
319/* Name        : icp_ocfDrvExit
320 *
321 * Description : This function will deregister all the symmetric sessions
322 * registered with the LAC component. It will also deregister all symmetric
323 * and asymmetric functionality that can be accelerated by the hardware via OCF
324 * and random number generation if it is enabled.
325 */
326ICP_MODULE_EXIT_FUNC(icp_ocfDrvExit)
327{
328	CpaStatus lacStatus = CPA_STATUS_SUCCESS;
329	struct icp_drvSessionData *sessionData = NULL;
330	struct icp_drvSessionData *tempSessionData = NULL;
331	int i, remaining_delay_time_in_jiffies = 0;
332
333	/* For FreeBSD the invariant macro below makes function to return     */
334	/* with EBUSY value in the case of any session which has been regi-   */
335	/* stered with LAC not being deregistered.                            */
336	/* The Linux implementation is empty since it is purely to compensate */
337	/* for a limitation of the FreeBSD 7.1 Opencrypto framework.          */
338
339    ICP_MODULE_EXIT_INV();
340
341	/* There is a possibility of a process or new session command being   */
342	/* sent before this variable is incremented. The aim of this variable */
343	/* is to stop a loop of calls creating a deadlock situation which     */
344	/* would prevent the driver from exiting.                             */
345	icp_atomic_set(&icp_ocfDrvIsExiting, 1);
346
347	/*Existing sessions will be routed to another driver after these calls */
348	crypto_unregister_all(icp_ocfDrvDriverId);
349	crypto_runregister_all(icp_ocfDrvDriverId);
350
351	if (ICP_WORKQUEUE_NULL_CHECK(icp_ocfDrvFreeLacSessionWorkQ)) {
352		DPRINTK("%s: workqueue already "
353			"destroyed, therefore module exit "
354			" function already called. Exiting.\n", __FUNCTION__);
355		return ICP_MODULE_EXIT_FUNC_RETURN_VAL;
356	}
357	/*If any sessions are waiting to be deregistered, do that. This also
358	   flushes the work queue */
359	ICP_WORKQUEUE_DESTROY(icp_ocfDrvFreeLacSessionWorkQ);
360
361	/*ENTER CRITICAL SECTION */
362	icp_spin_lockbh_lock(&icp_ocfDrvSymSessInfoListSpinlock);
363
364	ICP_LIST_FOR_EACH_ENTRY_SAFE(tempSessionData, sessionData,
365				     &icp_ocfDrvGlobalSymListHead, listNode) {
366		for (i = 0; i < num_dereg_retries; i++) {
367			/*No harm if bad input - LAC will handle error cases */
368			if (ICP_SESSION_RUNNING == tempSessionData->inUse) {
369				lacStatus =
370				    cpaCySymRemoveSession
371				    (CPA_INSTANCE_HANDLE_SINGLE,
372				     tempSessionData->sessHandle);
373				if (CPA_STATUS_SUCCESS == lacStatus) {
374					/* Succesfully deregistered */
375					break;
376				} else if (CPA_STATUS_RETRY != lacStatus) {
377					icp_atomic_inc
378					    (&lac_session_failed_dereg_count);
379					break;
380				}
381
382				/*schedule_timout returns the time left for completion if
383				 * this task is set to TASK_INTERRUPTIBLE */
384				remaining_delay_time_in_jiffies =
385				    dereg_retry_delay_in_jiffies;
386				while (0 > remaining_delay_time_in_jiffies) {
387					remaining_delay_time_in_jiffies =
388					    icp_schedule_timeout
389					    (&icp_ocfDrvSymSessInfoListSpinlock,
390					     remaining_delay_time_in_jiffies);
391				}
392
393				DPRINTK
394				    ("%s(): Retry %d to deregistrate the session\n",
395				     __FUNCTION__, i);
396			}
397		}
398
399		/*remove from current list */
400		ICP_LIST_DEL(tempSessionData, listNode);
401		/*add to free mem linked list */
402		ICP_LIST_ADD(tempSessionData,
403			     &icp_ocfDrvGlobalSymListHead_FreeMemList,
404			     listNode);
405
406	}
407
408	/*EXIT CRITICAL SECTION */
409	icp_spin_lockbh_unlock(&icp_ocfDrvSymSessInfoListSpinlock);
410
411	/*set back to initial values */
412	sessionData = NULL;
413	/*still have a reference in our list! */
414	tempSessionData = NULL;
415	/*free memory */
416
417	ICP_LIST_FOR_EACH_ENTRY_SAFE(tempSessionData, sessionData,
418				     &icp_ocfDrvGlobalSymListHead_FreeMemList,
419				     listNode) {
420
421		ICP_LIST_DEL(tempSessionData, listNode);
422		/* Free allocated CpaCySymSessionCtx */
423		if (NULL != tempSessionData->sessHandle) {
424			icp_kfree(tempSessionData->sessHandle);
425		}
426		memset(tempSessionData, 0, sizeof(struct icp_drvSessionData));
427		ICP_CACHE_FREE(drvSessionData_zone, tempSessionData);
428	}
429
430	if (0 != icp_atomic_read(&lac_session_failed_dereg_count)) {
431		DPRINTK("%s(): %d LAC sessions were not deregistered "
432			"correctly. This is not a clean exit! \n",
433			__FUNCTION__,
434			icp_atomic_read(&lac_session_failed_dereg_count));
435	}
436
437	icp_ocfDrvFreeCaches();
438	icp_ocfDrvDriverId = INVALID_DRIVER_ID;
439
440	icp_spin_lock_destroy(&icp_ocfDrvSymSessInfoListSpinlock);
441
442	/* Shutdown the Cryptographic component */
443	lacStatus = cpaCyStopInstance(CPA_INSTANCE_HANDLE_SINGLE);
444	if (CPA_STATUS_SUCCESS != lacStatus) {
445		DPRINTK("%s(): Failed to stop instance of the "
446			"Cryptographic component.(status == %d)\n",
447			__FUNCTION__, lacStatus);
448	}
449
450	return ICP_MODULE_EXIT_FUNC_RETURN_VAL;
451}
452
453/* Name        : icp_ocfDrvFreeCaches
454 *
455 * Description : This function deregisters all slab caches
456 */
457static void icp_ocfDrvFreeCaches(void)
458{
459	icp_atomic_set(&icp_ocfDrvIsExiting, 1);
460
461	/*Sym Zones */
462	ICP_CACHE_DESTROY(drvSessionData_zone);
463	ICP_CACHE_DESTROY(drvOpData_zone);
464
465	/*Asym zones */
466	ICP_CACHE_DESTROY(drvDH_zone);
467	ICP_CACHE_DESTROY(drvLnModExp_zone);
468	ICP_CACHE_DESTROY(drvRSADecrypt_zone);
469	ICP_CACHE_DESTROY(drvRSAPrivateKey_zone);
470	ICP_CACHE_DESTROY(drvDSARSSignKValue_zone);
471	ICP_CACHE_DESTROY(drvDSARSSign_zone);
472	ICP_CACHE_DESTROY(drvDSAVerify_zone);
473
474	/*FlatBuffer and BufferList Zones */
475	ICP_CACHE_DESTROY(drvFlatBuffer_zone);
476
477}
478
479/* Name        : icp_ocfDrvDeregRetry
480 *
481 * Description : This function will try to farm the session deregistration
482 * off to a work queue. If it fails, nothing more can be done and it
483 * returns an error
484 */
485int icp_ocfDrvDeregRetry(CpaCySymSessionCtx sessionToDeregister)
486{
487	struct icp_ocfDrvFreeLacSession *workstore = NULL;
488
489	DPRINTK("%s(): Retry - Deregistering session (%p)\n",
490		__FUNCTION__, sessionToDeregister);
491
492	/*make sure the session is not available to be allocated during this
493	   process */
494	icp_atomic_inc(&lac_session_failed_dereg_count);
495
496	/*Farm off to work queue */
497	workstore =
498	    icp_kmalloc(sizeof(struct icp_ocfDrvFreeLacSession), ICP_M_NOWAIT);
499	if (NULL == workstore) {
500		DPRINTK("%s(): unable to free session - no memory available "
501			"for work queue\n", __FUNCTION__);
502		return ENOMEM;
503	}
504
505	workstore->sessionToDeregister = sessionToDeregister;
506
507	icp_init_work(&(workstore->work),
508		      icp_ocfDrvDeferedFreeLacSessionTaskFn, workstore);
509
510	ICP_WORKQUEUE_ENQUEUE(icp_ocfDrvFreeLacSessionWorkQ,
511			      &(workstore->work));
512
513	return ICP_OCF_DRV_STATUS_SUCCESS;
514
515}
516
517/* Name        : icp_ocfDrvDeferedFreeLacSessionProcess
518 *
519 * Description : This function will retry (module input parameter)
520 * 'num_dereg_retries' times to deregister any symmetric session that recieves a
521 * CPA_STATUS_RETRY message from the LAC component. This function is run in
522 * Thread context because it is called from a worker thread
523 */
524void icp_ocfDrvDeferedFreeLacSessionProcess(void *arg)
525{
526	struct icp_ocfDrvFreeLacSession *workstore = NULL;
527	CpaCySymSessionCtx sessionToDeregister = NULL;
528	int i = 0;
529	int remaining_delay_time_in_jiffies = 0;
530	CpaStatus lacStatus = CPA_STATUS_SUCCESS;
531
532	workstore = (struct icp_ocfDrvFreeLacSession *)arg;
533	if (NULL == workstore) {
534		DPRINTK("%s() function called with null parameter \n",
535			__FUNCTION__);
536		return;
537	}
538
539	sessionToDeregister = workstore->sessionToDeregister;
540	icp_kfree(workstore);
541
542	/*if exiting, give deregistration one more blast only */
543	if (icp_atomic_read(&icp_ocfDrvIsExiting) == CPA_TRUE) {
544		lacStatus = cpaCySymRemoveSession(CPA_INSTANCE_HANDLE_SINGLE,
545						  sessionToDeregister);
546
547		if (lacStatus != CPA_STATUS_SUCCESS) {
548			DPRINTK("%s() Failed to Dereg LAC session %p "
549				"during module exit\n", __FUNCTION__,
550				sessionToDeregister);
551			return;
552		}
553
554		icp_atomic_dec(&lac_session_failed_dereg_count);
555		return;
556	}
557
558	for (i = 0; i <= num_dereg_retries; i++) {
559		lacStatus = cpaCySymRemoveSession(CPA_INSTANCE_HANDLE_SINGLE,
560						  sessionToDeregister);
561
562		if (lacStatus == CPA_STATUS_SUCCESS) {
563			icp_atomic_dec(&lac_session_failed_dereg_count);
564			return;
565		}
566		if (lacStatus != CPA_STATUS_RETRY) {
567			DPRINTK("%s() Failed to deregister session - lacStatus "
568				" = %d", __FUNCTION__, lacStatus);
569			break;
570		}
571
572		/*schedule_timout returns the time left for completion if this
573		   task is set to TASK_INTERRUPTIBLE */
574		remaining_delay_time_in_jiffies = dereg_retry_delay_in_jiffies;
575		while (0 < remaining_delay_time_in_jiffies) {
576			remaining_delay_time_in_jiffies =
577			    icp_schedule_timeout(NULL,
578						 remaining_delay_time_in_jiffies);
579		}
580
581	}
582
583	DPRINTK("%s(): Unable to deregister session\n", __FUNCTION__);
584	DPRINTK("%s(): Number of unavailable LAC sessions = %d\n", __FUNCTION__,
585		icp_atomic_read(&lac_session_failed_dereg_count));
586}
587
588/* Name        : icp_ocfDrvPtrAndLenToFlatBuffer
589 *
590 * Description : This function converts a "pointer and length" buffer
591 * structure to Fredericksburg Flat Buffer (CpaFlatBuffer) format.
592 *
593 * This function assumes that the data passed in are valid.
594 */
595inline void
596icp_ocfDrvPtrAndLenToFlatBuffer(void *pData, uint32_t len,
597				CpaFlatBuffer * pFlatBuffer)
598{
599	pFlatBuffer->pData = pData;
600	pFlatBuffer->dataLenInBytes = len;
601}
602
603/* Name        : icp_ocfDrvPtrAndLenToBufferList
604 *
605 * Description : This function converts a "pointer and length" buffer
606 * structure to Fredericksburg Scatter/Gather Buffer (CpaBufferList) format.
607 *
608 * This function assumes that the data passed in are valid.
609 */
610inline void
611icp_ocfDrvPtrAndLenToBufferList(void *pDataIn, uint32_t length,
612				CpaBufferList * pBufferList)
613{
614	pBufferList->numBuffers = 1;
615	pBufferList->pBuffers->pData = pDataIn;
616	pBufferList->pBuffers->dataLenInBytes = length;
617}
618
619/* Name        : icp_ocfDrvBufferListToPtrAndLen
620 *
621 * Description : This function converts Fredericksburg Scatter/Gather Buffer
622 * (CpaBufferList) format to a "pointer and length" buffer structure.
623 *
624 * This function assumes that the data passed in are valid.
625 */
626inline void
627icp_ocfDrvBufferListToPtrAndLen(CpaBufferList * pBufferList,
628				void **ppDataOut, uint32_t * pLength)
629{
630	*ppDataOut = pBufferList->pBuffers->pData;
631	*pLength = pBufferList->pBuffers->dataLenInBytes;
632}
633
634/* Name        : icp_ocfDrvBufferListMemInfo
635 *
636 * Description : This function will set the number of flat buffers in
637 * bufferlist, the size of memory to allocate for the pPrivateMetaData
638 * member of the CpaBufferList.
639 */
640int
641icp_ocfDrvBufferListMemInfo(uint16_t numBuffers,
642			    struct icp_drvBuffListInfo *buffListInfo)
643{
644	buffListInfo->numBuffers = numBuffers;
645
646	if (CPA_STATUS_SUCCESS !=
647	    cpaCyBufferListGetMetaSize(CPA_INSTANCE_HANDLE_SINGLE,
648				       buffListInfo->numBuffers,
649				       &(buffListInfo->metaSize))) {
650		EPRINTK("%s() Failed to get buffer list meta size.\n",
651			__FUNCTION__);
652		return ICP_OCF_DRV_STATUS_FAIL;
653	}
654
655	return ICP_OCF_DRV_STATUS_SUCCESS;
656}
657
658/* Name        : icp_ocfDrvFreeFlatBuffer
659 *
660 * Description : This function will deallocate flat buffer.
661 */
662inline void icp_ocfDrvFreeFlatBuffer(CpaFlatBuffer * pFlatBuffer)
663{
664	if (pFlatBuffer != NULL) {
665		memset(pFlatBuffer, 0, sizeof(CpaFlatBuffer));
666		ICP_CACHE_FREE(drvFlatBuffer_zone, pFlatBuffer);
667	}
668}
669
670/* Name        : icp_ocfDrvAllocMetaData
671 *
672 * Description : This function will allocate memory for the
673 * pPrivateMetaData member of CpaBufferList.
674 */
675inline int
676icp_ocfDrvAllocMetaData(CpaBufferList * pBufferList,
677			struct icp_drvOpData *pOpData)
678{
679	Cpa32U metaSize = 0;
680
681	if (pBufferList->numBuffers <= ICP_OCF_DRV_DEFAULT_BUFFLIST_ARRAYS) {
682		uint8_t *pOpDataStartAddr = (uint8_t *) pOpData;
683
684		if (0 == defBuffListInfo.metaSize) {
685			pBufferList->pPrivateMetaData = NULL;
686			return ICP_OCF_DRV_STATUS_SUCCESS;
687		}
688		/*
689		 * The meta data allocation has been included as part of the
690		 * op data.  It has been pre-allocated in memory just after the
691		 * icp_drvOpData structure.
692		 */
693		pBufferList->pPrivateMetaData = (void *)(pOpDataStartAddr +
694							 sizeof(struct
695								icp_drvOpData));
696	} else {
697		if (CPA_STATUS_SUCCESS !=
698		    cpaCyBufferListGetMetaSize(CPA_INSTANCE_HANDLE_SINGLE,
699					       pBufferList->numBuffers,
700					       &metaSize)) {
701			EPRINTK("%s() Failed to get buffer list meta size.\n",
702				__FUNCTION__);
703			return ICP_OCF_DRV_STATUS_FAIL;
704		}
705
706		if (0 == metaSize) {
707			pBufferList->pPrivateMetaData = NULL;
708			return ICP_OCF_DRV_STATUS_SUCCESS;
709		}
710
711		pBufferList->pPrivateMetaData =
712		    icp_kmalloc(metaSize, ICP_M_NOWAIT);
713	}
714	if (NULL == pBufferList->pPrivateMetaData) {
715		EPRINTK("%s() Failed to allocate pPrivateMetaData.\n",
716			__FUNCTION__);
717		return ICP_OCF_DRV_STATUS_FAIL;
718	}
719
720	return ICP_OCF_DRV_STATUS_SUCCESS;
721}
722
723/* Name        : icp_ocfDrvFreeMetaData
724 *
725 * Description : This function will deallocate pPrivateMetaData memory.
726 */
727inline void icp_ocfDrvFreeMetaData(CpaBufferList * pBufferList)
728{
729	if (NULL == pBufferList->pPrivateMetaData) {
730		return;
731	}
732
733	/*
734	 * Only free the meta data if the BufferList has more than
735	 * ICP_OCF_DRV_DEFAULT_BUFFLIST_ARRAYS number of buffers.
736	 * Otherwise, the meta data shall be freed when the icp_drvOpData is
737	 * freed.
738	 */
739	if (ICP_OCF_DRV_DEFAULT_BUFFLIST_ARRAYS < pBufferList->numBuffers) {
740		icp_kfree(pBufferList->pPrivateMetaData);
741	}
742}
743
744/* Module declaration, init and exit functions */
745ICP_DECLARE_MODULE(icp_ocf, icp_ocfDrvInit, icp_ocfDrvExit);
746ICP_MODULE_DESCRIPTION("OCF Driver for Intel Quick Assist crypto acceleration");
747ICP_MODULE_VERSION(icp_ocf, ICP_OCF_VER_MJR);
748ICP_MODULE_LICENSE("Dual BSD/GPL");
749ICP_MODULE_AUTHOR("Intel");
750
751/* Module parameters */
752ICP_MODULE_PARAM_INT(icp_ocf, num_dereg_retries,
753		     "Number of times to retry LAC Sym Session Deregistration. "
754		     "Default 10, Max 100");
755ICP_MODULE_PARAM_INT(icp_ocf, dereg_retry_delay_in_jiffies, "Delay in jiffies "
756		     "(added to a schedule() function call) before a LAC Sym "
757		     "Session Dereg is retried. Default 10");
758ICP_MODULE_PARAM_INT(icp_ocf, max_sessions,
759		     "This sets the maximum number of sessions "
760		     "between OCF and this driver. If this value is set to zero,"
761		     "max session count checking is disabled. Default is zero(0)");
762
763/* Module dependencies */
764#define MODULE_MIN_VER	1
765#define CRYPTO_MAX_VER	3
766#define LAC_MAX_VER	2
767
768ICP_MODULE_DEPEND(icp_ocf, crypto, MODULE_MIN_VER, MODULE_MIN_VER,
769		  CRYPTO_MAX_VER);
770ICP_MODULE_DEPEND(icp_ocf, cryptodev, MODULE_MIN_VER, MODULE_MIN_VER,
771		  CRYPTO_MAX_VER);
772ICP_MODULE_DEPEND(icp_ocf, icp_crypto, MODULE_MIN_VER, MODULE_MIN_VER,
773		  LAC_MAX_VER);
774