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